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 --- 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 + 31 files changed, 8357 insertions(+) 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 (limited to 'docutils') 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) -- cgit v1.2.1 From 6381b74ce6924bc0f14b7f377ee57496e2ebb2d9 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 20 Apr 2002 16:36:24 +0000 Subject: - Improved diagnostic system messages for missing blank lines. - Fixed substitution_reference bug. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@29 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 68 ++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 32 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index b2dbf9b3e..706ed6106 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -626,24 +626,27 @@ class RSTState(StateWS): before, inlines, remaining, sysmessages, endstring = self.inlineobj( match, lineno, self.inline.patterns.substitution_ref, nodes.substitution_reference) - if inlines: - assert len(inlines) == 1 + if len(inlines) == 1: subrefnode = inlines[0] - assert isinstance(subrefnode, nodes.substitution_reference) - subreftext = subrefnode.astext() - refname = normname(subreftext) - subrefnode['refname'] = refname - self.statemachine.memo.document.note_substitution_ref(subrefnode) - if endstring[-1:] == '_': - referencenode = nodes.reference('|%s%s' % (subreftext, endstring), '') - if endstring[-2:] == '__': - referencenode['anonymous'] = 1 - self.statemachine.memo.document.note_anonymous_ref(referencenode) - else: - referencenode['refname'] = refname - self.statemachine.memo.document.note_refname(referencenode) - referencenode += subrefnode - inlines = [referencenode] + if isinstance(subrefnode, nodes.substitution_reference): + subreftext = subrefnode.astext() + refname = normname(subreftext) + subrefnode['refname'] = refname + self.statemachine.memo.document.note_substitution_ref( + subrefnode) + if endstring[-1:] == '_': + referencenode = nodes.reference( + '|%s%s' % (subreftext, endstring), '') + if endstring[-2:] == '__': + referencenode['anonymous'] = 1 + self.statemachine.memo.document.note_anonymous_ref( + referencenode) + else: + referencenode['refname'] = refname + self.statemachine.memo.document.note_refname( + referencenode) + referencenode += subrefnode + inlines = [referencenode] return before, inlines, remaining, sysmessages def footnote_reference(self, match, lineno): @@ -788,10 +791,10 @@ class RSTState(StateWS): processed += self.standalone_uri(remaining, lineno) return processed, messages - def unindentwarning(self): + def unindent_warning(self, node_name): return self.statemachine.memo.reporter.warning( - ('Unindent without blank line at line %s.' - % (self.statemachine.abslineno() + 1))) + ('%s ends without a blank line; unexpected unindent at line %s.' + % (node_name, self.statemachine.abslineno() + 1))) class Body(RSTState): @@ -882,7 +885,7 @@ class Body(RSTState): blockquote = self.block_quote(indented, lineoffset) self.statemachine.node += blockquote if not blankfinish: - self.statemachine.node += self.unindentwarning() + self.statemachine.node += self.unindent_warning('Block quote') return context, nextstate, [] def block_quote(self, indented, lineoffset): @@ -904,7 +907,7 @@ class Body(RSTState): node=bulletlist, initialstate='BulletList', blankfinish=blankfinish) if not blankfinish: - self.statemachine.node += self.unindentwarning() + self.statemachine.node += self.unindent_warning('Bullet list') self.gotoline(newlineoffset) return [], nextstate, [] @@ -930,7 +933,8 @@ class Body(RSTState): bq = self.block_quote(indented, lineoffset) self.statemachine.node += bq if not blankfinish: - self.statemachine.node += self.unindentwarning() + self.statemachine.node += self.unindent_warning( + 'Enumerated list') return [], nextstate, [] if ordinal != 1: msg = self.statemachine.memo.reporter.info( @@ -955,7 +959,7 @@ class Body(RSTState): blankfinish=blankfinish, extrasettings={'lastordinal': ordinal, 'format': format}) if not blankfinish: - self.statemachine.node += self.unindentwarning() + self.statemachine.node += self.unindent_warning('Enumerated list') self.gotoline(newlineoffset) return [], nextstate, [] @@ -1022,7 +1026,7 @@ class Body(RSTState): node=fieldlist, initialstate='FieldList', blankfinish=blankfinish) if not blankfinish: - self.statemachine.node += self.unindentwarning() + self.statemachine.node += self.unindent_warning('Field list') self.gotoline(newlineoffset) return [], nextstate, [] @@ -1062,7 +1066,7 @@ class Body(RSTState): blockquote = self.block_quote(indented, lineoffset) self.statemachine.node += blockquote if not blankfinish: - self.statemachine.node += self.unindentwarning() + self.statemachine.node += self.unindent_warning('Option list') return [], nextstate, [] self.statemachine.node += optionlist optionlist += listitem @@ -1073,7 +1077,7 @@ class Body(RSTState): node=optionlist, initialstate='OptionList', blankfinish=blankfinish) if not blankfinish: - self.statemachine.node += self.unindentwarning() + self.statemachine.node += self.unindent_warning('Option list') self.gotoline(newlineoffset) return [], nextstate, [] @@ -1592,8 +1596,8 @@ class Body(RSTState): def explicitlist(self, blankfinish): """ - Create a nested state machine for a series of explicit markup constructs - (including anonymous hyperlink targets). + 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( @@ -1603,7 +1607,7 @@ class Body(RSTState): blankfinish=blankfinish) self.gotoline(newlineoffset) if not blankfinish: - self.statemachine.node += self.unindentwarning() + self.statemachine.node += self.unindent_warning('Explicit markup') def anonymous(self, match, context, nextstate): """Anonymous hyperlink targets.""" @@ -1857,7 +1861,7 @@ class Text(RSTState): node=definitionlist, initialstate='DefinitionList', blankfinish=blankfinish, blankfinishstate='Definition') if not blankfinish: - self.statemachine.node += self.unindentwarning() + self.statemachine.node += self.unindent_warning('Definition list') self.gotoline(newlineoffset) return [], 'Body', [] @@ -1918,7 +1922,7 @@ class Text(RSTState): data = '\n'.join(indented) nodelist.append(nodes.literal_block(data, data)) if not blankfinish: - nodelist.append(self.unindentwarning()) + nodelist.append(self.unindent_warning('Literal block')) else: nodelist.append(self.statemachine.memo.reporter.warning( 'Literal block expected at line %s; none found.' -- cgit v1.2.1 From 630e79abef4ea3263ee70235cd85e1d8159e0321 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 25 Apr 2002 03:25:44 +0000 Subject: - Added RFC-2822 header support. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@36 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/__init__.py | 9 +++- docutils/parsers/rst/states.py | 105 +++++++++++++++++++++++++++++---------- 2 files changed, 87 insertions(+), 27 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/__init__.py b/docutils/parsers/rst/__init__.py index 06589513b..bbe7dfee6 100644 --- a/docutils/parsers/rst/__init__.py +++ b/docutils/parsers/rst/__init__.py @@ -56,12 +56,19 @@ class Parser(docutils.parsers.Parser): """The reStructuredText parser.""" + def __init__(self, rfc2822=None): + if rfc2822: + self.initialstate = '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.statemachine = states.RSTStateMachine( - stateclasses=states.stateclasses, initialstate='Body', + stateclasses=states.stateclasses, + initialstate=self.initialstate, debug=debug) inputlines = docutils.statemachine.string2lines( inputstring, convertwhitespace=1) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 706ed6106..efce3b4f1 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -6,21 +6,24 @@ :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: +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. + - `SpecializedBody`: Superclass for compound element members. - `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. + - `DefinitionList`: Second+ definition_list_items. + - `EnumeratedList`: Second+ enumerated_list list_items. + - `FieldList`: Second+ fields. + - `OptionList`: Second+ option_list_items. + - `RFC2822List`: Second+ RFC2822-style fields. + - `Explicit`: Second+ explicit markup constructs. - `SubstitutionDef`: For embedded directives in substitution definitions. - `Text`: Classifier of second line of a text block. + - `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. @@ -28,12 +31,10 @@ the reStructuredText parser. It defines the following: :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`. @@ -42,22 +43,22 @@ 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 +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). + 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 + 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. @@ -71,11 +72,11 @@ Parsing proceeds as follows: - 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 + '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` + 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 + 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, @@ -83,7 +84,7 @@ Parsing proceeds as follows: 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: + 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. @@ -93,8 +94,8 @@ Parsing proceeds as follows: 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. + inline markup and appended to the parent element. Processing + continues with step 1. """ __docformat__ = 'reStructuredText' @@ -865,7 +866,6 @@ class Body(RSTState): 'explicit_markup': r'\.\.( +|$)', 'anonymous': r'__( +|$)', 'line': r'(%(nonalphanum7bit)s)\1\1\1+ *$' % pats, - #'rfc822': r'[!-9;-~]+:( +|$)', 'text': r''} initialtransitions = ['bullet', 'enumerator', @@ -1666,6 +1666,49 @@ class Body(RSTState): return [match.string], 'Text', [] +class RFC2822Body(Body): + + """ + RFC2822 headers are only valid as the first constructs in documents. As + soon as anything else appears, the `Body` state should take over. + """ + + 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' + + def rfc2822(self, match, context, nextstate): + """RFC2822-style field list item.""" + fieldlist = nodes.field_list() + self.statemachine.node += fieldlist + field, blankfinish = 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( + 'RFC2822-style field list') + self.gotoline(newlineoffset) + return [], nextstate, [] + + def rfc2822_field(self, match): + name = match.string[:match.string.find(':')] + indented, indent, lineoffset, blankfinish = \ + self.statemachine.getfirstknownindented(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 + + class SpecializedBody(Body): """ @@ -1764,11 +1807,21 @@ class OptionList(SpecializedBody): return [], 'OptionList', [] -class RFC822List(SpecializedBody): +class RFC2822List(SpecializedBody, RFC2822Body): - """Second and subsequent RFC822 field_list fields.""" + """Second and subsequent RFC2822-style field_list fields.""" + + patterns = RFC2822Body.patterns + initialtransitions = RFC2822Body.initialtransitions + + def rfc2822(self, match, context, nextstate): + """RFC2822-style field list item.""" + field, blankfinish = self.rfc2822_field(match) + self.statemachine.node += field + self.blankfinish = blankfinish + return [], 'RFC2822List', [] - pass + blank = SpecializedBody.invalid_input class Explicit(SpecializedBody): @@ -2093,8 +2146,8 @@ class Line(SpecializedText): stateclasses = [Body, BulletList, DefinitionList, EnumeratedList, FieldList, - OptionList, RFC822List, Explicit, Text, Definition, Line, - SubstitutionDef] + OptionList, Explicit, Text, Definition, Line, SubstitutionDef, + RFC2822Body, RFC2822List] """Standard set of State classes used to start `RSTStateMachine`.""" -- cgit v1.2.1 From 3085fc5c7d0053692b09642c62c409f50c42806b Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 4 May 2002 03:21:59 +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@67 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 301 ++++++++++++++++++++++-------------------- 1 file changed, 161 insertions(+), 140 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index dde26f7d0..a911719ab 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -17,13 +17,16 @@ contains a minimum of formatting information. A cascading style sheet __docformat__ = 'reStructuredText' -import time +import time, string, re from types import ListType from docutils import writers, nodes, languages class Writer(writers.Writer): + names = ('html', 'html4css1', 'xhtml') + """Names this writer answers to.""" + output = None """Final translated form of `document`.""" @@ -41,14 +44,14 @@ class HTMLTranslator(nodes.NodeVisitor): def __init__(self, doctree): nodes.NodeVisitor.__init__(self, doctree) self.language = languages.getlanguage(doctree.languagecode) - self.head = ['\n', - '\n\n' % doctree.languagecode, - '\n'] - self.body = ['\n\n'] - self.foot = ['\n\n'] + '\n\n' % doctree.languagecode, + '\n'] + self.body = ['\n\n'] + self.foot = ['\n\n'] self.sectionlevel = 0 self.context = [] self.topic_class = '' @@ -64,31 +67,49 @@ class HTMLTranslator(nodes.NodeVisitor): text = text.replace(">", ">") return text - def starttag(self, node, tagname, suffix='\n', **attributes): + 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)) + + def starttag(self, node, tagname, suffix='\n', infix='', **attributes): + """ + Construct and return a start tag given a node (id & class attributes + are extracted), tag name, and optional 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] + if node.has_key(att) or atts.has_key(att): + atts[att] = \ + (node.get(att, '') + ' ' + atts.get(att, '')).strip() for att in ('id',): # node attribute overrides if node.has_key(att): atts[att] = node[att] + if atts.has_key('id'): + atts['name'] = atts['id'] # for compatibility with old browsers attlist = atts.items() attlist.sort() - parts = [tagname.upper()] + parts = [tagname.lower()] for name, value in attlist: if value is None: # boolean attribute - parts.append(name.upper()) + # According to the HTML spec, ```` is good, + # ```` is bad. + # (But the XHTML (XML) spec says the opposite. ) + parts.append(name.lower()) elif isinstance(value, ListType): values = [str(v) for v in value] - parts.append('%s="%s"' % (name.upper(), - self.encode(' '.join(values)))) + parts.append('%s="%s"' % (name.lower(), + self.attval(' '.join(values)))) else: - parts.append('%s="%s"' % (name.upper(), - self.encode(str(value)))) - return '<%s>%s' % (' '.join(parts), suffix) + parts.append('%s="%s"' % (name.lower(), + self.attval(str(value)))) + return '<%s%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) def visit_Text(self, node): self.body.append(self.encode(node.astext())) @@ -98,10 +119,11 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_admonition(self, node, name): self.body.append(self.starttag(node, 'div', CLASS=name)) - self.body.append('

' + self.language.labels[name] + '

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

' + + self.language.labels[name] + '

\n') def depart_admonition(self): - self.body.append('\n') + self.body.append('\n') def visit_attention(self, node): self.visit_admonition(node, 'attention') @@ -125,7 +147,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.starttag(node, 'blockquote')) def depart_block_quote(self, node): - self.body.append('\n') + self.body.append('\n') def visit_bullet_list(self, node): if self.topic_class == 'contents': @@ -134,13 +156,13 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.starttag(node, 'ul')) def depart_bullet_list(self, node): - self.body.append('\n') + 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') + self.body.append('

\n') def visit_caution(self, node): self.visit_admonition(node, 'caution') @@ -151,14 +173,14 @@ 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' - '\n' - '\n' - '\n') + self.body.append('\n' + '\n' + '\n' + '\n') def depart_citation(self, node): - self.body.append('\n' - '\n\n') + self.body.append('\n' + '\n\n') def visit_citation_reference(self, node): href = '' @@ -166,33 +188,34 @@ class HTMLTranslator(nodes.NodeVisitor): 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'], + self.body.append(self.starttag(node, 'a', '[', href=href, CLASS='citation-reference')) def depart_citation_reference(self, node): - self.body.append(']') + self.body.append(']') def visit_classifier(self, node): - self.body.append(' : ') + self.body.append(' : ') self.body.append(self.starttag(node, 'span', '', CLASS='classifier')) def depart_classifier(self, node): - self.body.append('') + 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.starttag(node, 'col', **atts)) + self.body.append(self.emptytag(node, 'col', **atts)) def depart_colspec(self, node): pass - def visit_comment(self, node): - self.body.append('\n') + def visit_comment(self, node, + sub=re.compile('-(?=-)').sub): + """Escape double-dashes in comment text.""" + self.body.append('\n' % sub('- ', node.astext())) + raise nodes.SkipNode def visit_contact(self, node): self.visit_docinfo_item(node, 'contact') @@ -219,17 +242,17 @@ class HTMLTranslator(nodes.NodeVisitor): self.depart_docinfo_item() def visit_definition(self, node): - self.body.append('\n') + self.body.append('\n') self.body.append(self.starttag(node, 'dd')) def depart_definition(self, node): - self.body.append('\n') + self.body.append('\n') def visit_definition_list(self, node): self.body.append(self.starttag(node, 'dl')) def depart_definition_list(self, node): - self.body.append('\n') + self.body.append('\n') def visit_definition_list_item(self, node): pass @@ -238,54 +261,54 @@ class HTMLTranslator(nodes.NodeVisitor): pass def visit_description(self, node): - self.body.append('\n') + self.body.append('\n') def depart_description(self, node): - self.body.append('') + self.body.append('') def visit_docinfo(self, node): self.body.append(self.starttag(node, 'table', CLASS='docinfo', frame="void", rules="none")) - self.body.append('\n' - '\n' - '\n') + self.body.append('\n' + '\n' + '\n') def depart_docinfo(self, node): - self.body.append('\n\n') + self.body.append('\n\n') def visit_docinfo_item(self, node, name): - self.head.append('\n' - % (name, self.encode(node.astext()))) + self.head.append('\n' + % (name, self.attval(node.astext()))) self.body.append(self.starttag(node, 'tr', '')) - self.body.append('\n' - '

%s:

\n' - '\n' - '

' % self.language.labels[name]) + self.body.append('\n' + '

%s:

\n' + '\n' + '

' % self.language.labels[name]) def depart_docinfo_item(self): - self.body.append('

\n') + 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') + self.body.append('\n') def visit_document(self, node): self.body.append(self.starttag(node, 'div', CLASS='document')) def depart_document(self, node): - self.body.append('\n') + self.body.append('\n') #self.body.append( - # '

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

\n' % (node['source'], time.strftime('%Y-%m-%d'))) + # '

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

\n' % (node['source'], time.strftime('%Y-%m-%d'))) def visit_emphasis(self, node): - self.body.append('') + self.body.append('') def depart_emphasis(self, node): - self.body.append('') + self.body.append('') def visit_entry(self, node): if isinstance(node.parent.parent, nodes.thead): @@ -298,7 +321,7 @@ class HTMLTranslator(nodes.NodeVisitor): if node.has_key('morecols'): atts['colspan'] = node['morecols'] + 1 self.body.append(self.starttag(node, tagname, **atts)) - self.context.append('' % tagname.upper()) + self.context.append('' % tagname.lower()) if len(node) == 0: # empty cell self.body.append(' ') @@ -321,7 +344,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.starttag(node, 'ol', **atts)) def depart_enumerated_list(self, node): - self.body.append('\n') + self.body.append('\n') def visit_error(self, node): self.visit_admonition(node, 'error') @@ -333,7 +356,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.starttag(node, 'tr', CLASS='field')) def depart_field(self, node): - self.body.append('\n') + self.body.append('\n') def visit_field_argument(self, node): self.body.append(' ') @@ -341,27 +364,27 @@ class HTMLTranslator(nodes.NodeVisitor): CLASS='field-argument')) def depart_field_argument(self, node): - self.body.append('') + self.body.append('') def visit_field_body(self, node): - self.body.append(':

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

\n') self.body.append(self.starttag(node, 'div', 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')) - self.body.append('\n' - '\n' - '\n') + self.body.append('\n' + '\n' + '\n') def depart_field_list(self, node): - self.body.append('\n\n') + self.body.append('\n\n') def visit_field_name(self, node): - self.body.append('\n') + self.body.append('\n') self.body.append(self.starttag(node, 'p', '', CLASS='field-name')) def depart_field_name(self, node): @@ -375,19 +398,19 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.starttag(node, 'div', CLASS='figure')) def depart_figure(self, node): - self.body.append('\n') + self.body.append('\n') def visit_footnote(self, node): self.body.append(self.starttag(node, 'table', CLASS='footnote', frame="void", rules="none")) - self.body.append('\n' - '\n' - '\n' - '\n') + self.body.append('\n' + '\n' + '\n' + '\n') def depart_footnote(self, node): - self.body.append('\n' - '\n\n') + self.body.append('\n' + '\n\n') def visit_footnote_reference(self, node): href = '' @@ -395,11 +418,11 @@ class HTMLTranslator(nodes.NodeVisitor): 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'], + self.body.append(self.starttag(node, 'a', '', href=href, CLASS='footnote-reference')) def depart_footnote_reference(self, node): - self.body.append('') + self.body.append('') def visit_hint(self, node): self.visit_admonition(node, 'hint') @@ -413,7 +436,7 @@ class HTMLTranslator(nodes.NodeVisitor): del atts['uri'] if not atts.has_key('alt'): atts['alt'] = atts['src'] - self.body.append(self.starttag(node, 'img', '', **atts)) + self.body.append(self.emptytag(node, 'img', '', **atts)) def depart_image(self, node): pass @@ -425,41 +448,41 @@ class HTMLTranslator(nodes.NodeVisitor): self.depart_admonition() def visit_interpreted(self, node): - self.body.append('') + self.body.append('') def depart_interpreted(self, node): - self.body.append('') + self.body.append('') def visit_label(self, node): self.body.append(self.starttag(node, 'p', '[', CLASS='label')) def depart_label(self, node): - self.body.append(']

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

\n' + '\n') def visit_legend(self, node): self.body.append(self.starttag(node, 'div', CLASS='legend')) def depart_legend(self, node): - self.body.append('\n') + self.body.append('\n') def visit_list_item(self, node): self.body.append(self.starttag(node, 'li')) def depart_list_item(self, node): - self.body.append('\n') + self.body.append('\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', CLASS='literal-block')) def depart_literal_block(self, node): - self.body.append('\n') + self.body.append('\n') def visit_meta(self, node): self.head.append(self.starttag(node, 'meta', **node.attributes)) @@ -486,46 +509,46 @@ class HTMLTranslator(nodes.NodeVisitor): CLASS='option-argument')) def depart_option_argument(self, node): - self.body.append('') + self.body.append('') def visit_option_group(self, node): atts = {} if len(node.astext()) > 14: atts['colspan'] = 2 - self.context.append('\n ') + self.context.append('\n ') 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): self.body.append( self.starttag(node, 'table', CLASS='option-list', frame="void", rules="none", cellspacing=12)) - self.body.append('\n' - '\n' - '\n') + self.body.append('\n' + '\n' + '\n') def depart_option_list(self, node): - self.body.append('\n\n') + 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') + self.body.append('\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('') + self.body.append('') def visit_organization(self, node): self.visit_docinfo_item(node, 'organization') @@ -541,18 +564,18 @@ class HTMLTranslator(nodes.NodeVisitor): if self.topic_class == 'contents': self.body.append('\n') else: - self.body.append('

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

\n') def visit_problematic(self, node): if node.hasattr('refid'): - self.body.append('' % node['refid']) - self.context.append('') + self.body.append('' % node['refid']) + 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.body.append(self.context.pop()) def visit_raw(self, node): @@ -564,16 +587,14 @@ class HTMLTranslator(nodes.NodeVisitor): 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('') + self.body.append('') def visit_revision(self, node): self.visit_docinfo_item(node, 'revision') @@ -585,7 +606,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.starttag(node, 'tr', '')) def depart_row(self, node): - self.body.append('\n') + self.body.append('\n') def visit_section(self, node): self.sectionlevel += 1 @@ -593,7 +614,7 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_section(self, node): self.sectionlevel -= 1 - self.body.append('\n') + self.body.append('\n') def visit_status(self, node): self.visit_docinfo_item(node, 'status') @@ -602,10 +623,10 @@ class HTMLTranslator(nodes.NodeVisitor): self.depart_docinfo_item() def visit_strong(self, node): - self.body.append('') + self.body.append('') def depart_strong(self, node): - self.body.append('') + self.body.append('') def visit_substitution_definition(self, node): raise nodes.SkipChildren @@ -617,50 +638,50 @@ class HTMLTranslator(nodes.NodeVisitor): self.unimplemented_visit(node) def visit_subtitle(self, node): - self.body.append(self.starttag(node, 'H2', '', CLASS='subtitle')) + self.body.append(self.starttag(node, 'h2', '', CLASS='subtitle')) def depart_subtitle(self, node): - self.body.append('\n') + self.body.append('\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('

') + self.body.append('

') if node.hasattr('backrefs'): backrefs = node['backrefs'] if len(backrefs) == 1: - self.body.append('%s ' - '(level %s system message)

\n' + self.body.append('%s ' + '(level %s system message)

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

\n' + 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' + self.body.append('%s (level %s system message)

\n' % (node['type'], node['level'])) def depart_system_message(self, node): - self.body.append('\n') + self.body.append('\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('\n') + 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, 'a', '', CLASS='target')) - self.context.append('') + self.context.append('') else: self.context.append('') @@ -668,11 +689,11 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.context.pop()) def visit_tbody(self, node): - 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): - self.body.append('\n') + self.body.append('\n') def visit_term(self, node): self.body.append(self.starttag(node, 'dt', '')) @@ -686,18 +707,18 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_tgroup(self, node): self.body.append(self.starttag(node, 'colgroup')) - self.context.append('\n') + self.context.append('\n') def depart_tgroup(self, node): pass def visit_thead(self, node): - self.body.append(self.context.pop()) # '\n' + self.body.append(self.context.pop()) # '\n' self.context.append('') self.body.append(self.starttag(node, 'thead', valign='bottom')) def depart_thead(self, node): - self.body.append('\n') + self.body.append('\n') def visit_tip(self, node): self.visit_admonition(node, 'tip') @@ -709,21 +730,21 @@ class HTMLTranslator(nodes.NodeVisitor): """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('

\n') + self.starttag(node, 'p', '', CLASS='topic-title')) + self.context.append('

\n') elif self.sectionlevel == 0: - self.head.append('%s\n' + self.head.append('%s\n' % self.encode(node.astext())) - self.body.append(self.starttag(node, 'H1', '', CLASS='title')) - self.context.append('\n') + 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.sectionlevel, '')) context = '' if node.hasattr('refid'): - self.body.append('' % node['refid']) - context = '' - self.context.append('%s\n' % (context, self.sectionlevel)) + 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()) @@ -733,11 +754,11 @@ class HTMLTranslator(nodes.NodeVisitor): self.topic_class = node.get('class') def depart_topic(self, node): - self.body.append('\n') + self.body.append('\n') self.topic_class = '' def visit_transition(self, node): - self.body.append(self.starttag(node, 'hr')) + self.body.append(self.emptytag(node, 'hr')) def depart_transition(self, node): pass -- 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(+) (limited to 'docutils') 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(-) (limited to 'docutils') 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 (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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 (limited to 'docutils') 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 (limited to 'docutils') 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 (limited to 'docutils') 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(-) (limited to 'docutils') 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 (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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 (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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 f6d1d682215cee2501c938cf8389d720ef6118df Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 c0405e481cc67c4aae4feb3de44696bc13760acd Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 bb7d59f401c5548c607574294c3ae4e23d4f6a22 Mon Sep 17 00:00:00 2001 From: richard 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(-) (limited to 'docutils') 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('') 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('\n') -- cgit v1.2.1 From 7cd21ab928fcae9a597ae04c69ae74b41b919ec4 Mon Sep 17 00:00:00 2001 From: richard 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(-) (limited to 'docutils') 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('

\n') 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('\n') -- cgit v1.2.1 From d44e62eb34941a552ee243fef90b529064eda265 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 = '\n' + doctype = '\n' + html_head = '\n\n' + content_type = '\n', + stylesheet_link = '\n'] + def __init__(self, document): nodes.NodeVisitor.__init__(self, document) - self.language = languages.getlanguage(document.language_code) - self.head = ['\n', - '\n\n' % document.language_code, - '\n'] - self.body = ['\n\n'] - self.foot = ['\n\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 = ['\n\n'] + self.body = [] + self.body_suffix = ['\n\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('\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('\n') -- cgit v1.2.1 From 5acb5943d2383d82e4e180a49905f6d7f7eb7337 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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 --- 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 ++-- 9 files changed, 27 insertions(+), 22 deletions(-) (limited to 'docutils') 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): - 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):: @@ -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 bd058e6fbfa94584b9026f705cd5cbe73dfa9827 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 = '\n\n' content_type = '\n', + 'charset=UTF-8">\n' stylesheet_link = '\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 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(-) (limited to 'docutils') 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 3510bd954117ba2d0179a2419887fd61cb3a2c7c Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 18 May 2002 02:53:47 +0000 Subject: - Added a "generator" meta tag to . 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(-) (limited to 'docutils') 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 = '\n\n' - content_type = '\n' + generator = '\n' stylesheet_link = '\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 = ['\n\n'] -- cgit v1.2.1 From 9e311d21148b1320c59bc46990f073939bec7826 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 05e4910c4b36bdcc1534594160644f2bb2fec9c4 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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 --- docutils/transforms/references.py | 2 +- docutils/transforms/universal.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') 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 b9a42c808f2d269e277d5c937e78ca1401563aff Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 060ae1cc18c6362cbfc28c6ee525ff32616ad1fb Mon Sep 17 00:00:00 2001 From: goodger 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 +- 4 files changed, 43 insertions(+), 41 deletions(-) (limited to 'docutils') 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('\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('

') -- cgit v1.2.1 From 6f467ee322d74ec5c68592a4c9b97a96488d79b8 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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 (limited to 'docutils') 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 ' + ' (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': ''}), + ('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 () 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': ''}), + ('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 .', + ['--warnings'], {'dest': 'warning_stream', 'metavar': ''}), + # @@@ Take default encoding & language from locale? + #('Specify the encoding of input text. Default is "utf-8".', + # ['--encoding', '-e'], {'default': 'utf-8', 'metavar': ''}), + ('Specify the language of input text (ISO 639 2-letter identifier. ' + 'Default is "en" (English).', + ['--language', '-l'], {'dest': 'language_code', 'default': 'en', + 'metavar': ''}), + ('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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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'(? 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(-) (limited to 'docutils') 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': ''}),) + output = None """Final translated form of `document`.""" @@ -51,19 +58,18 @@ class HTMLTranslator(nodes.NodeVisitor): 'charset=UTF-8">\n' generator = '\n' - stylesheet_link = '\n' + stylesheet_link = '\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 = ['\n\n'] self.body = [] -- cgit v1.2.1 From 1be17ead1d6e210c5a8d76cd44a283879f932d69 Mon Sep 17 00:00:00 2001 From: goodger 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 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') 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() -- cgit v1.2.1 From 1934c6cf5d19f763d01e03aa4babd681eea3b399 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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 ++- 6 files changed, 20 insertions(+), 8 deletions(-) (limited to 'docutils') 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 -- cgit v1.2.1 From f58fb865a3aea6a7b87ca716fd16a0ba2cdd9ac6 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 8610e9c1dfa7383679ef821aac3e95185feadae4 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 ' ' (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 .', ['--warnings'], {'dest': 'warning_stream', 'metavar': ''}), # @@@ Take default encoding & language from locale? -- cgit v1.2.1 From 4c89d002f8f9017caa9ff690e0a82d1ec7556f5d Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(+) (limited to 'docutils') 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('\n') self.body.append(self.starttag(node, 'dd')) @@ -425,6 +431,16 @@ class HTMLTranslator(nodes.NodeVisitor): 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'] + + self.body[start:] + ['\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('') + 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('
\n\n') + del self.body[start:] + def visit_hint(self, node): self.visit_admonition(node, 'hint') -- cgit v1.2.1 From 7ce7476c958ae579fbd64bbbb00ebcee127d88ac Mon Sep 17 00:00:00 2001 From: goodger 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(+) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 ' - ' (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': ''}), - ('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 () 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': ''}), - ('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 .', - ['--warnings'], {'dest': 'warning_stream', 'metavar': ''}), - # @@@ Take default encoding & language from locale? - #('Specify the encoding of input text. Default is "utf-8".', - # ['--encoding', '-e'], {'default': 'utf-8', 'metavar': ''}), - ('Specify the language of input text (ISO 639 2-letter identifier. ' - 'Default is "en" (English).', - ['--language', '-l'], {'dest': 'language_code', 'default': 'en', - 'metavar': ''}), - ('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 ' + ' (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': ''}), + ('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 () 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': ''}), + ('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 .', + ['--warnings'], {'dest': 'warning_stream', 'metavar': ''}), + # @@@ Take default encoding & language from locale? + #('Specify the encoding of input text. Default is "utf-8".', + # ['--encoding', '-e'], {'default': 'utf-8', 'metavar': ''}), + ('Specify the language of input text (ISO 639 2-letter identifier. ' + 'Default is "en" (English).', + ['--language', '-l'], {'dest': 'language_code', 'default': 'en', + 'metavar': ''}), + ("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 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 (limited to 'docutils') 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 + +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 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 (limited to 'docutils') 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 + +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 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(-) (limited to 'docutils') 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': ''}),) + 'HTML-Specific Options', + None, + (('Specify a stylesheet file. Default is "default.css".', + ['--stylesheet'], + {'default': 'default.css', 'metavar': ''}),),) output = None """Final translated form of `document`.""" -- cgit v1.2.1 From 13da103589ae4085005670489808aaff76d54145 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 ae57b4ceca35d1f06037284f4089684604a48e26 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 7f675ec43766d8805ba70f87064e330912f90ec3 Mon Sep 17 00:00:00 2001 From: goodger 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 --- docutils/writers/html4css1.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'docutils') 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('') def depart_interpreted(self, node): @@ -684,10 +686,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('') 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 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 (limited to 'docutils') 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 - -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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 373cca31645a6460611519ee0ae27e02076d2495 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 .', ['--warnings'], {'dest': 'warning_stream', 'metavar': ''}), - # @@@ Take default encoding & language from locale? - #('Specify the encoding of input text. Default is "utf-8".', - # ['--encoding', '-e'], {'default': 'utf-8', 'metavar': ''}), + ('Specify the encoding of input text. Default is locale-dependent.', + ['--encoding', '-e'], {'metavar': ''}), ('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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 9c38addab1cab5a5e7e5b763984ef67e06881440 Mon Sep 17 00:00:00 2001 From: goodger 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 (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 .', ['--warnings'], {'dest': 'warning_stream', 'metavar': ''}), ('Specify the encoding of input text. Default is locale-dependent.', - ['--encoding', '-e'], {'metavar': ''}), - ('Specify the language of input text (ISO 639 2-letter identifier. ' - 'Default is "en" (English).', + ['--input-encoding', '-i'], {'metavar': ''}), + ('Specify the encoding for output. Default is UTF-8.', + ['--output-encoding', '-o'], + {'metavar': '', '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': ''}), ("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 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(-) (limited to 'docutils') 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 = '\n' + xml_declaration = '\n' doctype = '\n' html_head = '\n\n' content_type = '\n' + 'charset=%s">\n' generator = '\n' stylesheet_link = '\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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 ce2f906d0b60ee6836aacc32bf2922e338b8a314 Mon Sep 17 00:00:00 2001 From: goodger 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(+) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 c06d0f016cf4f539db28a4ea6142855cc7bb92aa Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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'(? # 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 constructs: + (?P%s) # reference name + (?P__?) # end-string | \[ # footnote_reference or # citation_reference start - ( # label (group 6): + (?P # 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%s) # citation reference ) - (\]_) # end-string (group 8) + (?P\]_) # end-string ) %s # end-string suffix | # *OR* - ((?::%s:)?) # optional role (group 9) - ( # start-string (group 10) + (?P(:%s:)?) # optional role + (?P # 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:%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 + (?P # absolute URI + (?P # 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 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`?) # optional open quote + (?![ `]) # first char. not space or + # backquote + (?P # 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%s)_ # simple reference name + | # *OR* + ` # open backquote + (?![ ]) # not space + (?P.+?) # 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.+?) # 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 15717892479e478467487d48f4e2e5f43eb66d10 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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-strings only: \*\* # strong @@ -456,52 +456,53 @@ class Inliner: | \| # substitution_reference start ) - %s # no whitespace after + %(non_whitespace_after)s | # *OR* (?P # whole constructs: - (?P%s) # reference name - (?P__?) # end-string + (?P%(simplename)s) # reference name + (?P__?) # end-string | \[ # footnote_reference or # citation_reference start (?P # label: [0-9]+ # manually numbered | # *OR* - \#(%s)? # auto-numbered (w/ label?) + \#(%(simplename)s)? # auto-numbered (w/ label?) | # *OR* \* # auto-symbol | # *OR* - (?P%s) # citation reference + (?P + %(simplename)s) # citation reference ) (?P\]_) # end-string ) - %s # end-string suffix + %(end_string_suffix)s | # *OR* - (?P(:%s:)?) # optional role + (?P(:%(simplename)s:)?) # optional role (?P # 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:%s:|__?)?)%s' % (non_whitespace_escape_before, - simplename, - end_string_suffix)), + r""" + %(non_whitespace_escape_before)s + ( + ` + (?P + (?P:%(simplename)s:)? + (?P__?)? + ) + ) + %(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 (?P # absolute URI (?P # 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 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 # 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%s)_ # simple reference name + (?P%(simplename)s)_ | # *OR* ` # open backquote (?![ ]) # not space (?P.+?) # 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.+?) # 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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 (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 be8b2373908f3c5f02b983b0f65016a0911ad921 Mon Sep 17 00:00:00 2001 From: goodger 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 --- docutils/core.py | 6 +++--- docutils/statemachine.py | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'docutils') 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: -- cgit v1.2.1 From 5c1d1c93ddd584c9e2217a122f6650bc86de2543 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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': ''}),),) + {'default': 'default.css', 'metavar': ''}),)) output = None """Final translated form of `document`.""" @@ -78,7 +78,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body_prefix = ['\n\n'] self.body = [] self.body_suffix = ['\n\n'] - self.sectionlevel = 0 + self.section_level = 0 self.context = [] self.topic_class = '' @@ -667,11 +667,11 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('\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('\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('

\n') - elif self.sectionlevel == 0: + elif self.section_level == 0: + # document title self.head.append('%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(+) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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 0cd6e450ebc86185487cadf3a91fbffcbfa0fd1e Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(+) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(+) (limited to 'docutils') 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 88804d77d0b560dbc7b80893770b052dfc765c37 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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%s)(?P__?)' % simplename, + ('footnotelabel', r'\[', r'(?P\]_)', + [r'[0-9]+', # manually numbered + r'\#(%s)?' % simplename, # auto-numbered (w/ label?) + r'\*', # auto-symbol + r'(?P%s)' % simplename] # citation reference + ) + ] + ), + ('backquote', # interpreted text or phrase reference + '(?P(:%s:)?)' % simplename, # optional role + non_whitespace_after, + ['`(?!`)'] # but not literal + ) + ] + ) patterns = Stuff( - initial=re.compile( - r""" - %(start_string_prefix)s - ( - (?P # start-strings only: - \*\* # strong - | - \* # emphasis - (?!\*) # but not strong - | - `` # literal - | - _` # inline hyperlink target - | - \| # substitution_reference start - ) - %(non_whitespace_after)s - | # *OR* - (?P # whole constructs: - (?P%(simplename)s) # reference name - (?P__?) # end-string - | - \[ # footnote_reference or - # citation_reference start - (?P # label: - [0-9]+ # manually numbered - | # *OR* - \#(%(simplename)s)? # auto-numbered (w/ label?) - | # *OR* - \* # auto-symbol - | # *OR* - (?P - %(simplename)s) # citation reference - ) - (?P\]_) # end-string - ) - %(end_string_suffix)s - | # *OR* - (?P(:%(simplename)s:)?) # optional role - (?P # 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 c21a148798856797bbf693ff1f5c8ba9c604cce1 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(+) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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('
') def visit_field_body(self, node): - self.body.append(':

\n') - self.body.append(self.starttag(node, 'div', CLASS='field-body')) + self.body.append(':

\n\n') + #self.body.append(self.starttag(node, 'div', CLASS='field-body')) def depart_field_body(self, node): - self.body.append('\n') + #self.body.append('\n') + self.body.append('\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 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 (limited to 'docutils') 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': ''}), + ('Specify a template file. Default is "peptemplate.html".', + ['--template'], + {'default': 'peptemplate.html', 'metavar': ''}), + ('Python\'s home URL. Default is "http://www.python.org".', + ['--python-home'], + {'default': 'http://www.python.org', 'metavar': ''}), + ('Home URL for this PEP. Default is "." (current directory).', + ['--pep-home'], + {'default': '.', 'metavar': ''}),)) + + 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('
\n') -- cgit v1.2.1 From 0f70ab017321ae0f80a4aeaa2adcafb12dd26cb3 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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': ''}), - ('Specify a template file. Default is "peptemplate.html".', + {'default': 'pep.css', 'metavar': ''}), + ('Specify a template file. Default is "pep-template.html".', ['--template'], - {'default': 'peptemplate.html', 'metavar': ''}), + {'default': 'pep-template.html', 'metavar': ''}), ('Python\'s home URL. Default is "http://www.python.org".', ['--python-home'], {'default': 'http://www.python.org', 'metavar': ''}), -- cgit v1.2.1 From acb21b5d5622d284a3ed98236bf15ee70bb03069 Mon Sep 17 00:00:00 2001 From: goodger 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 + 1 file changed, 1 insertion(+) (limited to 'docutils') 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) -- cgit v1.2.1 From 79edab7ca03b79aae0397b2c449f0df1a5fe7920 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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') + self.footnote_backrefs(node) def depart_citation(self, node): self.body.append('\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('\n' - '

%s:

\n' - '\n' - '

' % self.language.labels[name]) + self.body.append('%s:\n' + % self.language.labels[name]) def depart_docinfo_item(self): - self.body.append('

\n') + 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\n') - #self.body.append(self.starttag(node, 'div', CLASS='field-body')) + self.body.append(': ') + 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' '\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(('', '')) + 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' @@ -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' - '\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 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(-) (limited to 'docutils') 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(+) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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('\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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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 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 (limited to 'docutils') 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 (limited to 'docutils') 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 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(+) (limited to 'docutils') 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(-) (limited to 'docutils') 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(+) (limited to 'docutils') 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 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 ++++++++++++++++++++++++++++++++---------- 1 file changed, 98 insertions(+), 28 deletions(-) (limited to 'docutils') 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 -- 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(-) (limited to 'docutils') 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(+) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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(+) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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 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 (limited to 'docutils') 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 15f41ca47d032c33376f939059faf9eb82ac3f51 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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] [ []]' +default_description = ('Reads from (default is stdin) and writes to ' + ' (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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(+) (limited to 'docutils') 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 a1713e3ba0b936004190f616c62f2189e0953b59 Mon Sep 17 00:00:00 2001 From: goodger 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(+) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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 --- docutils/writers/html4css1.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'docutils') 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('\n' '\n' '\n') + self.in_docinfo = 1 def depart_docinfo(self, node): self.body.append('\n\n') + self.in_docinfo = None def visit_docinfo_item(self, node, name): 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): @@ -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('\n') @@ -460,7 +463,11 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('\n\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 2a12c4edb207059ea690a10f90be2aa1d5b09f32 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 f9911cad64b1b288d54f2b021baef80d0b07c5f6 Mon Sep 17 00:00:00 2001 From: goodger 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(+) (limited to 'docutils') 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 "
  • 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"' if it is a paragraph. The stylesheet + sets the top margin to 0 for these paragraphs. + """ + xml_declaration = '\n' doctype = ' 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(-) (limited to 'docutils') 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(('', '')) - self.context.append(('' % backrefs[0],)) + self.context.append(('' + % backrefs[0],)) else: i = 1 backlinks = [] for backref in backrefs: - backlinks.append('%s' % (backref, i)) + backlinks.append('%s' + % (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('' % node['refid']) + self.body.append('' + % node['refid']) context = '' self.context.append('%s\n' % (context, self.section_level)) -- cgit v1.2.1 From 61d204ba2bacd28ca39307302970bda873e053d8 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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'), '


    \n'] + footer = (['\n', + self.starttag(node, 'div', CLASS='footer')] + self.body[start:] + ['\n']) self.body_suffix[:0] = footer del self.body[start:] -- cgit v1.2.1 From 087383956c0c5aba2337ab961e66b3ef18e2445f Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 fe66cb1cd619d5abd815be4b235b116cd3c43807 Mon Sep 17 00:00:00 2001 From: goodger 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(+) (limited to 'docutils') 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 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 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docutils') 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): -- cgit v1.2.1 From 00721f31c013181f753ed200b3fa0414f143f780 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 for a "View document source" link; ' + 'implies --source-link.', + ['--source-url'], {'metavar': ''}), ('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 efd006184800e755c1baef8b7fc5790bf301bb96 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 ef63f320763f423632642e4b2aeb2b9570d4eedf Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 = ['\n\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 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(-) (limited to 'docutils') 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 0e1aadf8cc6ace83cb42ca97d89fa9d1649ad396 Mon Sep 17 00:00:00 2001 From: goodger 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(+) (limited to 'docutils') 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': ''}), + ('Read this configuration .', + ['--config'], {'metavar': '', '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 fad349b8d9dac2aea4e20397ff4ff74143247622 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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': ''}), ('Read this configuration .', ['--config'], {'metavar': '', '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 542dc656827c94acf719e1d942053787b5752b0a Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 () 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': ''}), - ('Read this configuration .', + ('Read configuration options from , if it exists.', ['--config'], {'metavar': '', '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 c3dd163385425e7e2df847faef58c3bdb22d19a4 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 60e5c1371c60c00dc4c76d684f263021a703c3a7 Mon Sep 17 00:00:00 2001 From: goodger 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 --- docutils/transforms/universal.py | 6 +++--- docutils/writers/html4css1.py | 2 +- docutils/writers/pep_html.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'docutils') 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 = ['\n\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 e07795fb06abccd594d7553cc8d7c6daf7f199c4 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 () at or above which system messages are ' -- cgit v1.2.1 From a0f7c8dbee178f8426ad60a251134cff94f2b99b Mon Sep 17 00:00:00 2001 From: goodger 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(+) (limited to 'docutils') 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 2a5a926315c1ef3dfe6c0a62329da715f0ba4a01 Mon Sep 17 00:00:00 2001 From: chodorowski 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(+) (limited to 'docutils') 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 415ea7d3b8d5217275984c80b475d4cf2da5b00d Mon Sep 17 00:00:00 2001 From: goodger 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 --- docutils/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') 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 -- cgit v1.2.1 From a411812a5ace3c65515654456a2cf329b4119e44 Mon Sep 17 00:00:00 2001 From: goodger 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 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(-) (limited to 'docutils') 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 = '\n' stylesheet_link = '\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, ```` 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('' - % node['refid']) - context = '' - self.context.append('%s\n' % (context, self.section_level)) + atts['class'] = 'toc-backref' + atts['href'] = '#' + node['refid'] + self.body.append(self.starttag({}, 'a', '', **atts) + self.context.append('\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 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(-) (limited to 'docutils') 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('\n' % (self.section_level)) def depart_title(self, node): -- cgit v1.2.1 From 90b5fbc2436e55d24b306af0f63239513ca01700 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 3 Aug 2002 15:52:34 +0000 Subject: Sometimes a
    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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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(('', '')) - self.context.append(('' - % backrefs[0],)) + self.context.append('') + self.context.append('' % (backrefs[0], node['id'])) else: i = 1 backlinks = [] @@ -559,11 +559,11 @@ class HTMLTranslator(nodes.NodeVisitor): backlinks.append('%s' % (backref, i)) i += 1 - self.context.append(('', '(%s) ' % ', '.join(backlinks))) - self.context.append(('',)) + self.context.append('(%s) ' % ', '.join(backlinks)) + self.context.append('' % node['id']) else: - self.context.append(('', '')) - self.context.append(('',)) + self.context.append('') + self.context.append('' % node['id']) def depart_footnote(self, node): self.body.append('\n' @@ -627,7 +627,7 @@ class HTMLTranslator(nodes.NodeVisitor): CLASS='label')) def depart_label(self, node): - self.body.append(']%s%s' % self.context.pop()) + self.body.append(']%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('

    \n') + if node.parent.hasattr('id'): + self.body.append( + self.starttag({}, 'a', '', name=node.parent['id'])) + self.context.append('

    \n') + else: + self.context.append('

    \n') elif self.section_level == 0: # document title self.head.append('%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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(+) (limited to 'docutils') 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(-) (limited to 'docutils') 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(+) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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 1981123ec5a63f9d98ee3b8d8433e7d1cab3b021 Mon Sep 17 00:00:00 2001 From: goodger 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 --- docutils/parsers/rst/directives/__init__.py | 4 ++-- docutils/parsers/rst/languages/en.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'docutils') 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.""" -- cgit v1.2.1 From a83aaa90155115647d0bb2728003e61a7dc8248c Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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('%s' % token) + self.body.append('%s' + % self.encode(token)) else: self.body.append(' ' * (len(token) - 1) + ' ') self.body.append('') -- 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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 f3c5decc4be60d2dd06c9dfbfef0f55788657c59 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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('%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('') raise nodes.SkipNode -- cgit v1.2.1 From d5f026e798598f57d02ab02ffa4b20efb818473f Mon Sep 17 00:00:00 2001 From: goodger 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 --- docutils/core.py | 8 ++++---- docutils/writers/pep_html.py | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'docutils') 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 -- cgit v1.2.1 From 403cb20d5dc1c872855031ed1ea90dc2fa948281 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 940de581fe90267e7d5b9b1acbfa878db8e7961c Mon Sep 17 00:00:00 2001 From: yole Date: Sun, 11 Aug 2002 19:41:37 +0000 Subject: Second version of the .. sectnum:: directive implementation. Also, the really working fix of the empty path problem in package_unittest.py. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@500 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 1 + docutils/parsers/rst/directives/parts.py | 35 ++++++++++++++- docutils/transforms/parts.py | 66 +++++++++++++++++++++++++---- 3 files changed, 93 insertions(+), 9 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index ada409a79..0a9721c9f 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -55,6 +55,7 @@ _directive_registry = { 'image': ('images', 'image'), 'figure': ('images', 'figure'), 'contents': ('parts', 'contents'), + 'sectnum': ('parts', 'sectnum'), #'footnotes': ('parts', 'footnotes'), #'citations': ('parts', 'citations'), 'meta': ('html', 'meta'), diff --git a/docutils/parsers/rst/directives/parts.py b/docutils/parsers/rst/directives/parts.py index d3bba86c5..aefea341d 100644 --- a/docutils/parsers/rst/directives/parts.py +++ b/docutils/parsers/rst/directives/parts.py @@ -1,7 +1,7 @@ #! /usr/bin/env python """ -:Author: David Goodger +:Author: David Goodger, Dmitry Jemerov :Contact: goodger@users.sourceforge.net :Revision: $Revision$ :Date: $Date$ @@ -75,3 +75,36 @@ def contents(match, type_name, data, state, state_machine, attributes): return [error] + messages, blank_finish state_machine.document.note_pending(pending) return [pending] + messages, blank_finish + +sectnum_attribute_spec = {'depth': int} + +def sectnum(match, type_name, data, state, state_machine, attributes): + """ + Parse the `.. sectnum::` directive. + + The following attributes are supported: + + - :depth: + + The attributes can be specified in the lines following the directive, + or it is possible to specify one attribute in the same line as the + directive itself. + """ + 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_attributes( + sectnum_attribute_spec, datablock, 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), '') + return [error], blank_finish + + state_machine.document.note_pending(pending) + return [pending], blank_finish diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index 8b835f276..48b7588e3 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -1,6 +1,6 @@ #! /usr/bin/env python """ -:Authors: David Goodger, Ueli Schlaepfer +:Authors: David Goodger, Ueli Schlaepfer, Dmitry Jemerov :Contact: goodger@users.sourceforge.net :Revision: $Revision$ :Date: $Date$ @@ -9,6 +9,7 @@ Transforms related to document parts. - `Contents`: Used to build a table of contents. +- `SectNum`: Used to automatically number the section titles. """ __docformat__ = 'reStructuredText' @@ -19,6 +20,38 @@ import sys from docutils import nodes, utils 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. + """ + + def transform(self): + self.maxdepth = self.startnode.details.get('depth', sys.maxint) + self.startnode.parent.remove(self.startnode) + self.update_section_numbers(self.document, "", 1) + + def update_section_numbers(self, node, prefix, depth): + cur_index = 1 + for child in node: + if isinstance(child, nodes.section): + number_str = "%s%d." % (prefix, cur_index) + title = child[0] + child['autonum_origtitle'] = copy_and_filter(self.document, + title) + child['autonum_prefix'] = prefix + if isinstance(title[0], nodes.Text): + title[0].data = number_str + " " + title[0].data + else: + title.insert(0, nodes.Text(number_str + " ")) + if depth < self.maxdepth: + self.update_section_numbers(child, number_str, depth+1) + cur_index += 1 class Contents(Transform): @@ -79,10 +112,20 @@ class Contents(Transform): i -= 1 sections.reverse() entries = [] + autonum = 0 depth = self.startnode.details.get('depth', sys.maxint) for section in sections: title = section[0] - entrytext = self.copy_and_filter(title) + + # If the title has been modified by the sectnum transform, + # take the title before modification saved in the + # `autonum_origtitle` attribute. + entrytext = section.get('autonum_origtitle', '') + if entrytext: + autonum = 1 + autonum_prefix = section.get('autonum_prefix') + else: + entrytext = copy_and_filter(self.document, title) reference = nodes.reference('', '', refid=section['id'], *entrytext) ref_id = self.document.set_id(reference) @@ -97,14 +140,21 @@ class Contents(Transform): item += subsects entries.append(item) if entries: - entries = nodes.bullet_list('', *entries) + if autonum: + entries = nodes.enumerated_list('', + enumtype='arabic', + prefix=autonum_prefix, + suffix='.', + *entries) + else: + 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() +def copy_and_filter(document, node): + """Return a copy of a title, with references, images, etc. removed.""" + visitor = ContentsFilter(document) + node.walkabout(visitor) + return visitor.get_entry_text() class ContentsFilter(nodes.TreeCopyVisitor): -- cgit v1.2.1 From ed133b3ce34d61dabf89a02ad8b3f37745692f3f Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 13 Aug 2002 00:51:34 +0000 Subject: Added "generated" element. Improved "pending" docstrings. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@503 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 0924658a7..c03cc63d7 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1003,10 +1003,10 @@ class pending(Special, Invisible, 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. + 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. 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 @@ -1021,8 +1021,15 @@ class pending(Special, Invisible, PreBibliographic, Element): + internal attributes - The "pending" node is also appended to `document.pending`, so that a later - stage of processing can easily run all pending transforms. + 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()``. """ def __init__(self, transform, stage, details, @@ -1100,6 +1107,7 @@ class image(General, Inline, TextElement): class problematic(Inline, TextElement): pass +class generated(Inline, TextElement): pass # ======================================== @@ -1117,6 +1125,7 @@ node_class_names = """ emphasis entry enumerated_list error field field_argument field_body field_list field_name figure footer footnote footnote_reference + generated header hint image important interpreted label legend list_item literal literal_block -- cgit v1.2.1 From 7a7a49ec21fec9c14621992cbfcee53337a424f4 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 13 Aug 2002 00:53:05 +0000 Subject: Changed the "Contents" transform's order. Docstrings. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@504 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/parts.py | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/parts.py b/docutils/parsers/rst/directives/parts.py index aefea341d..eeff6fc29 100644 --- a/docutils/parsers/rst/directives/parts.py +++ b/docutils/parsers/rst/directives/parts.py @@ -39,6 +39,7 @@ contents_attribute_spec = {'depth': int, 'qa': unchanged} def contents(match, type_name, data, state, state_machine, attributes): + """Table of contents.""" lineno = state_machine.abs_line_number() line_offset = state_machine.line_offset datablock, indent, offset, blank_finish = \ @@ -60,7 +61,7 @@ def contents(match, type_name, data, state, state_machine, attributes): else: messages = [] title = None - pending = nodes.pending(parts.Contents, 'last reader', {'title': title}, + pending = nodes.pending(parts.Contents, 'first writer', {'title': title}, blocktext) if attlines: success, data, blank_finish = state.parse_extension_attributes( @@ -79,22 +80,11 @@ def contents(match, type_name, data, state, state_machine, attributes): sectnum_attribute_spec = {'depth': int} def sectnum(match, type_name, data, state, state_machine, attributes): - """ - Parse the `.. sectnum::` directive. - - The following attributes are supported: - - - :depth: - - The attributes can be specified in the lines following the directive, - or it is possible to specify one attribute in the same line as the - directive itself. - """ + """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_attributes( sectnum_attribute_spec, datablock, blank_finish) @@ -105,6 +95,5 @@ def sectnum(match, type_name, data, state, state_machine, attributes): 'Error in "%s" directive attributes at line %s:\n%s.' % (match.group(1), lineno, data), '') return [error], blank_finish - state_machine.document.note_pending(pending) return [pending], blank_finish -- cgit v1.2.1 From 3cfa7ce4f723086105232c55166fec4b7bc935bc Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 13 Aug 2002 00:53:40 +0000 Subject: Added "sectnum" directive. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@505 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/en.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index 0ccba3952..3e95e1972 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -34,6 +34,8 @@ directives = { 'figure': 'figure', #'raw': 'raw', 'contents': 'contents', + 'sectnum': 'sectnum', + 'section-numbering': 'sectnum', #'footnotes': 'footnotes', #'citations': 'citations', 'restructuredtext-test-directive': 'restructuredtext-test-directive'} -- cgit v1.2.1 From 077121b3b8eada56010fc661595ab47f7c350638 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 13 Aug 2002 00:56:09 +0000 Subject: * Reworked the ``docutils.transforms.parts.SectNum`` transform's ``update_section_numbers()`` method: - Simplified calling the method (default parameter values). - Removed the "autonum_origtitle" and "autonum_prefix" attributes from "section" elements: unnecessarily redundant. Instead, the "title" elements get an "auto" attribute. - The section number text is inserted into the title, wrapped in a ```` element. We don't actually use this yet, but it could be used this to remove the generated text if we need to. * Reworked the ``docutils.transforms.parts.Contents`` transform's ``build_contents()`` method: - It turns out that we don't need to build enumerated lists; we continue to build bullet lists as before. - If an "auto" attribute is detected in a title, we add a ``class="auto-toc"`` attribute to the bullet list. - The generated text is left alone; there's no need to remove it. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@506 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/parts.py | 70 +++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 40 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index 48b7588e3..78a99b121 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -20,12 +20,13 @@ import sys from docutils import nodes, utils 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 + 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. @@ -34,24 +35,24 @@ class SectNum(Transform): def transform(self): self.maxdepth = self.startnode.details.get('depth', sys.maxint) self.startnode.parent.remove(self.startnode) - self.update_section_numbers(self.document, "", 1) + self.update_section_numbers(self.document) - def update_section_numbers(self, node, prefix, depth): - cur_index = 1 + def update_section_numbers(self, node, prefix=(), depth=0): + depth += 1 + sectnum = 1 for child in node: if isinstance(child, nodes.section): - number_str = "%s%d." % (prefix, cur_index) + numbers = prefix + (str(sectnum),) title = child[0] - child['autonum_origtitle'] = copy_and_filter(self.document, - title) - child['autonum_prefix'] = prefix - if isinstance(title[0], nodes.Text): - title[0].data = number_str + " " + title[0].data - else: - title.insert(0, nodes.Text(number_str + " ")) + # Use   for spacing: + generated = nodes.generated( + '', '.'.join(numbers) + u'\u00a0' * 3, CLASS='sectnum') + title.insert(0, generated) + title['auto'] = 1 if depth < self.maxdepth: - self.update_section_numbers(child, number_str, depth+1) - cur_index += 1 + self.update_section_numbers(child, numbers, depth) + sectnum += 1 + class Contents(Transform): @@ -116,16 +117,8 @@ class Contents(Transform): depth = self.startnode.details.get('depth', sys.maxint) for section in sections: title = section[0] - - # If the title has been modified by the sectnum transform, - # take the title before modification saved in the - # `autonum_origtitle` attribute. - entrytext = section.get('autonum_origtitle', '') - if entrytext: - autonum = 1 - autonum_prefix = section.get('autonum_prefix') - else: - entrytext = copy_and_filter(self.document, title) + auto = title.get('auto') # May be set by SectNum. + entrytext = self.copy_and_filter(title) reference = nodes.reference('', '', refid=section['id'], *entrytext) ref_id = self.document.set_id(reference) @@ -140,21 +133,18 @@ class Contents(Transform): item += subsects entries.append(item) if entries: - if autonum: - entries = nodes.enumerated_list('', - enumtype='arabic', - prefix=autonum_prefix, - suffix='.', - *entries) - else: - entries = nodes.bullet_list('', *entries) - return entries - -def copy_and_filter(document, node): - """Return a copy of a title, with references, images, etc. removed.""" - visitor = ContentsFilter(document) - node.walkabout(visitor) - return visitor.get_entry_text() + contents = nodes.bullet_list('', *entries) + if auto: + contents.set_class('auto-toc') + return contents + else: + return [] + + def copy_and_filter(self, node): + """Return a copy of a title, with references, images, etc. removed.""" + visitor = ContentsFilter(self.document) + node.walkabout(visitor) + return visitor.get_entry_text() class ContentsFilter(nodes.TreeCopyVisitor): -- cgit v1.2.1 From b0d73b9dfd712717d3f56e71b8e99f2ee081cbb7 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 13 Aug 2002 00:57:37 +0000 Subject: Improved modularity of output; added ``self.body_pre_docinfo`` and ``self.docinfo`` segments. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@507 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index f8a58d736..cd7402fcd 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -50,6 +50,8 @@ class Writer(writers.Writer): self.head_prefix = visitor.head_prefix self.head = visitor.head self.body_prefix = visitor.body_prefix + self.body_pre_docinfo = visitor.body_pre_docinfo + self.docinfo = visitor.docinfo self.body = visitor.body self.body_suffix = visitor.body_suffix @@ -123,6 +125,8 @@ class HTMLTranslator(nodes.NodeVisitor): options.stylesheet)] self.head = [] self.body_prefix = ['\n\n'] + self.body_pre_docinfo = [] + self.docinfo = [] self.body = [] self.body_suffix = ['\n\n'] self.section_level = 0 @@ -134,8 +138,9 @@ class HTMLTranslator(nodes.NodeVisitor): self.in_docinfo = None def astext(self): - return ''.join(self.head_prefix + self.head - + self.body_prefix + self.body + self.body_suffix) + return ''.join(self.head_prefix + self.head + self.body_prefix + + self.body_pre_docinfo + self.docinfo + self.body + + self.body_suffix) def encode(self, text): """Encode special characters in `text` & return.""" @@ -382,6 +387,7 @@ class HTMLTranslator(nodes.NodeVisitor): 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' @@ -392,6 +398,10 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_docinfo(self, node): self.body.append('\n\n') self.in_docinfo = None + start = self.context.pop() + self.body_pre_docinfo = self.body[:start] + self.docinfo = self.body[start:] + self.body = [] def visit_docinfo_item(self, node, name): self.head.append('\n' @@ -584,6 +594,12 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_footnote_reference(self, node): self.body.append('') + def visit_generated(self, node): + pass + + def depart_generated(self, node): + pass + def visit_header(self, node): self.context.append(len(self.body)) @@ -900,8 +916,8 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_tgroup(self, node): # Mozilla needs : self.body.append(self.starttag(node, 'colgroup')) + # Appended by thead or tbody: self.context.append('\n') - pass def depart_tgroup(self, node): pass -- cgit v1.2.1 From 07dc5b490583921a0cc62654ed4a0e37c1bea9d9 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 13 Aug 2002 01:06:07 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@514 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/pep_html.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index b591f9230..6e1750537 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -78,7 +78,8 @@ class Writer(html4css1.Writer): except: subs['pepnum'] = pepnum subs['title'] = header[1][1].astext() - subs['body'] = ''.join(self.body) + subs['body'] = ''.join( + self.body_pre_docinfo + self.docinfo + self.body) subs['body_suffix'] = ''.join(self.body_suffix) self.output = template % subs -- cgit v1.2.1 From 9fe2dbf1beb29ef9380782bf15f6176c07759fff Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 13 Aug 2002 03:39:27 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@516 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/peps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index edc9ed382..bf04d5868 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -120,7 +120,7 @@ class Contents(Transform): def transform(self): - pending = nodes.pending(parts.Contents, 'last reader', + pending = nodes.pending(parts.Contents, 'first writer', {'title': None}) self.document.insert(1, pending) self.document.note_pending(pending) -- cgit v1.2.1 From c2ea4b4b6c19ef8823c2ed2c6ccdf2e45b369d46 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 14 Aug 2002 02:38:32 +0000 Subject: - Added support for lists of nodes to ``Element.insert()``. - Fixed parent linking in ``Element.replace()``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@517 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index c03cc63d7..51baf54b5 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -396,10 +396,12 @@ class Element(Node): 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 insert(self, index, item): + if isinstance(item, Node): + item.parent = self + self.children.insert(index, item) + elif item is not None: + self[index:index] = item def pop(self, i=-1): return self.children.pop(i) @@ -414,6 +416,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[index] = new elif new is not None: self[index:index+1] = new -- cgit v1.2.1 From 9d58b7001284d065e4d04254c1ac50d097858dc9 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 14 Aug 2002 02:39:34 +0000 Subject: Added to project. Contains the "target-notes" directive. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@518 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/references.py | 29 +++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 docutils/parsers/rst/directives/references.py (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/references.py b/docutils/parsers/rst/directives/references.py new file mode 100644 index 000000000..98f06f778 --- /dev/null +++ b/docutils/parsers/rst/directives/references.py @@ -0,0 +1,29 @@ +#! /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. + +Directives for references and targets. +""" + +__docformat__ = 'reStructuredText' + +from docutils import nodes +from docutils.transforms import references + + +def target_notes(match, type_name, data, state, state_machine, attributes): + """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 (at line %s).' + % (match.group(1), data, state_machine.abs_line_number())) + nodelist.append(warning) + return nodelist, state_machine.is_next_line_blank() -- cgit v1.2.1 From afc01457d52d9e450abdf34f7f92a3ceb5c79e12 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 14 Aug 2002 02:41:29 +0000 Subject: Added the ``TargetNotes`` PEP-specific transform. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@519 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/peps.py | 52 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 8 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index bf04d5868..8c188b443 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -23,7 +23,7 @@ import time from docutils import nodes, utils from docutils import ApplicationError, DataError from docutils.transforms import Transform, TransformError -from docutils.transforms import parts +from docutils.transforms import parts, references class Headers(Transform): @@ -50,8 +50,14 @@ class Headers(Transform): pep = title = None for field in header: if field[0].astext().lower() == 'pep': # should be the first field - pep = int(field[1].astext()) - break + value = field[1].astext() + try: + pep = int(value) + except ValueError: + raise DataError('"PEP" header must contain an integer; ' + '"%s" is an invalid value.' % value) + else: + break if pep is None: raise DataError('Document does not contain an RFC-2822 "PEP" ' 'header.') @@ -76,7 +82,7 @@ class Headers(Transform): '%d-%b-%Y', time.localtime(os.stat(self.document['source'])[8])) body += nodes.paragraph() - uri = self.pep_cvs_url % int(pep) + uri = self.pep_cvs_url % pep body[0][:] = [nodes.reference('', date, refuri=uri)] else: # empty @@ -102,7 +108,7 @@ class Headers(Transform): elif name == 'last-modified': utils.clean_rcs_keywords(para, self.rcs_keyword_substitutions) date = para.astext() - uri = self.pep_cvs_url % int(pep) + uri = self.pep_cvs_url % pep para[:] = [nodes.reference('', date, refuri=uri)] elif name == 'content-type': pep_type = para.astext() @@ -115,10 +121,10 @@ class Headers(Transform): class Contents(Transform): """ - Insert a table of contents into the document after the RFC 2822 header. + Insert a table of contents transform placeholder into the document after + the RFC 2822 header. """ - def transform(self): pending = nodes.pending(parts.Contents, 'first writer', {'title': None}) @@ -126,6 +132,36 @@ class Contents(Transform): self.document.note_pending(pending) +class TargetNotes(Transform): + + """ + Locate the "References" section, insert a placeholder for an external + target footnote insertion transform at the end, and run the transform. + """ + + def transform(self): + doc = self.document + 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(): + refsect = doc[i] + break + if 'copyright' in doc[i][0].astext().lower().split(): + copyright = i + i -= 1 + if not refsect: + refsect = nodes.section() + refsect += nodes.title('', 'References') + if copyright: + doc.insert(copyright, refsect) + else: + doc.append(refsect) + pending = nodes.pending(references.TargetNotes, 'immediate', {}) + refsect.append(pending) + pending.transform(doc, self, pending).transform() + + class PEPZero(Transform): """ @@ -142,7 +178,7 @@ class PEPZeroSpecial(nodes.SparseNodeVisitor): """ Perform the special processing needed by PEP 0: - + - Mask email addresses. - Link PEP numbers in the second column of 4-column tables to the PEPs -- cgit v1.2.1 From 1d5845785ad08f7e2c7a76668af4572739cb44cb Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 14 Aug 2002 02:43:28 +0000 Subject: Added the ``TargetNotes`` generic transform. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@520 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 58 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 20cdcd525..ff3cfb081 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -11,15 +11,20 @@ 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. """ __docformat__ = 'reStructuredText' +import sys import re from docutils import nodes, utils from docutils.transforms import TransformError, Transform +indices = xrange(sys.maxint) + + class Hyperlinks(Transform): """Resolve the various types of hyperlink targets and references.""" @@ -78,9 +83,8 @@ class Hyperlinks(Transform): msg.add_backref(prbid) ref.parent.replace(ref, prb) return - for i in range(len(self.document.anonymous_refs)): - ref = self.document.anonymous_refs[i] - target = self.document.anonymous_targets[i] + for ref, target in zip(self.document.anonymous_refs, + self.document.anonymous_targets): if target.hasattr('refuri'): ref['refuri'] = target['refuri'] ref.resolved = 1 @@ -655,3 +659,51 @@ class Substitutions(Transform): msg.add_backref(prbid) ref.parent.replace(ref, prb) self.document.substitution_refs = None # release replaced references + + +class TargetNotes(Transform): + + """ + Creates a footnote for each external target in the text, and corresponding + footnote references after each reference. + """ + + def transform(self): + nodelist = [] + for target in self.document.external_targets: + name = target.get('name') + if not name: + print >>sys.stderr, 'no name on target: %r' % target + continue + refs = self.document.refnames.get(name, []) + if not refs: + continue + nodelist.append(self.make_target_footnote(target, refs)) + 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'): + nodelist.append(self.make_target_footnote(target, [ref])) + self.startnode.parent.replace(self.startnode, nodelist) + # @@@ what about indirect links to external targets? + + def make_target_footnote(self, target, refs): + footnote = nodes.footnote() + footnote_id = self.document.set_id(footnote) + footnote_name = '_targetnote ' + footnote_id + footnote['auto'] = 1 + footnote['name'] = footnote_name + footnote += nodes.reference('', target['refuri'], + refuri=target['refuri']) + self.document.note_autofootnote(footnote) + self.document.note_explicit_target(footnote, footnote) + for ref in refs: + refnode = nodes.footnote_reference( + refname=footnote_name, auto=1) + self.document.note_autofootnote_ref(refnode) + self.document.note_footnote_ref(refnode) + index = ref.parent.index(ref) + 1 + reflist = [nodes.Text(' '), refnode] + ref.parent.insert(index, reflist) + return footnote -- cgit v1.2.1 From 2fe84555dacb42e1d3ead2e7a81d1aa71abe72f1 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 14 Aug 2002 02:43:57 +0000 Subject: Added the ``peps.TargetNotes`` transform to the Reader. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@521 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/pep.py | 1 + 1 file changed, 1 insertion(+) (limited to 'docutils') diff --git a/docutils/readers/pep.py b/docutils/readers/pep.py index c926723b8..a4571bbc9 100644 --- a/docutils/readers/pep.py +++ b/docutils/readers/pep.py @@ -30,6 +30,7 @@ class Reader(standalone.Reader): transforms = (references.Substitutions, peps.Headers, peps.Contents, + peps.TargetNotes, references.Footnotes, references.Hyperlinks,) -- cgit v1.2.1 From 096e020774b4f3681762f86fb2baeff90957feb5 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 14 Aug 2002 02:45:02 +0000 Subject: Added the "target-notes" directive. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@523 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 1 + docutils/parsers/rst/languages/en.py | 1 + 2 files changed, 2 insertions(+) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 0a9721c9f..03ebf262d 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -58,6 +58,7 @@ _directive_registry = { 'sectnum': ('parts', 'sectnum'), #'footnotes': ('parts', 'footnotes'), #'citations': ('parts', 'citations'), + 'target-notes': ('references', 'target_notes'), '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 3e95e1972..8c198ccef 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -36,6 +36,7 @@ directives = { 'contents': 'contents', 'sectnum': 'sectnum', 'section-numbering': 'sectnum', + 'target-notes': 'target-notes', #'footnotes': 'footnotes', #'citations': 'citations', 'restructuredtext-test-directive': 'restructuredtext-test-directive'} -- cgit v1.2.1 From c4a00cfc467df8194d21a819070dc14e0e31ddfe Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 15 Aug 2002 01:45:14 +0000 Subject: ``FileOutput.write()`` now returns the encoded output string. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@529 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index 9b126c502..07337672a 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -171,13 +171,14 @@ class FileOutput(Output): self.opened = 1 def write(self, data): - """Encode and write `data` to a single file.""" + """Encode `data`, write it to a single file, and return it.""" output = data.encode(self.options.output_encoding) if not self.opened: self.open() self.destination.write(output) if self.autoclose: self.close() + return output def close(self): self.destination.close() @@ -202,7 +203,7 @@ class StringOutput(Output): """ def write(self, data): - """Encode and return `data`.""" + """Encode `data`, store it in `self.destination`, and return it.""" self.destination = data.encode(self.options.output_encoding) return self.destination -- cgit v1.2.1 From 9bc776e2c61bbd39cbe94c7e7f78fa1de63c7f86 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 16 Aug 2002 00:29:46 +0000 Subject: Added ``line_block`` element class. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@536 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 51baf54b5..8f613a573 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -960,8 +960,9 @@ class option_list_item(Part, Element): 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 +class line_block(General, TextElement): pass +class block_quote(General, Element): pass class attention(Admonition, Element): pass class caution(Admonition, Element): pass class danger(Admonition, Element): pass @@ -1131,7 +1132,7 @@ node_class_names = """ generated header hint image important interpreted - label legend list_item literal literal_block + label legend line_block list_item literal literal_block note option option_argument option_group option_list option_list_item option_string organization -- cgit v1.2.1 From 0e0945034dac85d840bcf15384b533a41ece4d49 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 16 Aug 2002 00:32:36 +0000 Subject: Added the "line-block" and "parsed-literal" directives. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@537 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 2 ++ docutils/parsers/rst/directives/body.py | 36 +++++++++++++++++++++++++++++ docutils/parsers/rst/languages/en.py | 2 ++ 3 files changed, 40 insertions(+) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 03ebf262d..d6345562a 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -51,6 +51,8 @@ _directive_registry = { 'hint': ('admonitions', 'hint'), 'warning': ('admonitions', 'warning'), 'topic': ('body', 'topic'), + 'line-block': ('body', 'line_block'), + 'parsed-literal': ('body', 'parsed_literal'), #'questions': ('body', 'question_list'), 'image': ('images', 'image'), 'figure': ('images', 'figure'), diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index 3cdc1d382..98f04d237 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -12,6 +12,8 @@ Directives for additional body elements. __docformat__ = 'reStructuredText' + +import sys from docutils import nodes @@ -45,3 +47,37 @@ def topic(match, type_name, data, state, state_machine, attributes): if text: state.nested_parse(indented, line_offset, topic_node) return [topic_node], blank_finish + + +def parsed_literal(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()) + while indented and not indented[-1].strip(): + indented.pop() + blocktext = '\n'.join(state_machine.input_lines[ + initial_offset : line_offset + len(indented)]) + if not indented: + return [], blank_finish + text = '\n'.join(indented) + textnodes, messages = state.inline_text(text, lineno) + literal = nodes.literal_block(text, '', *textnodes) + return [literal] + messages, blank_finish + + +def line_block(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()) + while indented and not indented[-1].strip(): + indented.pop() + blocktext = '\n'.join(state_machine.input_lines[ + initial_offset : line_offset + len(indented)]) + if not indented: + return [], blank_finish + text = '\n'.join(indented) + textnodes, messages = state.inline_text(text, lineno) + line_block_node = nodes.line_block(text, '', *textnodes) + return [line_block_node] + messages, blank_finish diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index 8c198ccef..34c4c101a 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -25,6 +25,8 @@ directives = { 'tip': 'tip', 'warning': 'warning', 'topic': 'topic', + 'line-block': 'line-block', + 'parsed-literal': 'parsed-literal', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', -- cgit v1.2.1 From a7cbc5c1f096f980f20efceb9ca8dd3b7cff1ee0 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 16 Aug 2002 00:34:32 +0000 Subject: Fixed enumerated list item parsing to allow paragraphs & section titles to begin with enumerators. Plus some cleanup. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@538 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 102 +++++++++++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 29 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index fec37d1c9..eb545a1f2 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -957,20 +957,8 @@ class Body(RSTState): def enumerator(self, match, context, next_state): """Enumerated List Item""" format, sequence, text, ordinal = self.parse_enumerator(match) - if ordinal is None: - msg = self.reporter.error( - ('Enumerated list start value invalid at line %s: ' - '"%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()) - bq = self.block_quote(indented, line_offset) - self.parent += bq - if not blank_finish: - self.parent += self.unindent_warning( - 'Enumerated list') - return [], next_state, [] + if not self.is_enumerated_list_item(ordinal, sequence, format): + raise statemachine.TransitionCorrection('text') if ordinal != 1: msg = self.reporter.info( ('Enumerated list start value not ordinal-1 at line %s: ' @@ -1022,7 +1010,7 @@ class Body(RSTState): if groupdict[format]: # was this the format matched? break # yes; keep `format` else: # shouldn't happen - raise ParserError, 'enumerator format not matched' + raise ParserError('enumerator format not matched') text = groupdict[format][self.enum.formatinfo[format].start :self.enum.formatinfo[format].end] if expected_sequence: @@ -1030,24 +1018,81 @@ class Body(RSTState): if self.enum.sequenceregexps[expected_sequence].match(text): sequence = expected_sequence except KeyError: # shouldn't happen - raise ParserError, 'unknown sequence: %s' % sequence - else: - if text == 'i': - sequence = 'lowerroman' - elif text == 'I': - sequence = 'upperroman' + raise ParserError('unknown enumerator sequence: %s' + % sequence) + elif 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' + raise ParserError('enumerator sequence not matched') try: ordinal = self.enum.converters[sequence](text) except roman.InvalidRomanNumeralError: ordinal = None return format, sequence, text, ordinal + def is_enumerated_list_item(self, ordinal, sequence, format): + """ + Check validity based on the ordinal value and the second line. + + Return true iff the ordinal is valid and the second line is blank, + indented, or starts with the next enumerator. + """ + if ordinal is None: + return None + try: + next_line = self.state_machine.next_line() + except IndexError: # end of input lines + self.state_machine.previous_line() + return 1 + else: + self.state_machine.previous_line() + if not next_line[:1].strip(): # blank or indented + return 1 + next_enumerator = self.make_enumerator(ordinal + 1, sequence, format) + try: + if next_line.startswith(next_enumerator): + return 1 + except TypeError: + pass + return None + + def make_enumerator(self, ordinal, sequence, format): + """ + Construct and return an enumerated list item marker. + + Return ``None`` for invalid (out of range) ordinals. + """ + if sequence == 'arabic': + enumerator = str(ordinal) + else: + if sequence.endswith('alpha'): + if ordinal > 26: + return None + enumerator = chr(ordinal + ord('a') - 1) + elif sequence.endswith('roman'): + try: + enumerator = roman.toRoman(ordinal) + except roman.RomanError: + return None + else: # shouldn't happen + raise ParserError('unknown enumerator sequence: "%s"' + % sequence) + if sequence.startswith('lower'): + enumerator = enumerator.lower() + elif sequence.startswith('upper'): + enumerator = enumerator.upper() + else: # shouldn't happen + raise ParserError('unknown enumerator sequence: "%s"' + % sequence) + formatinfo = self.enum.formatinfo[format] + return formatinfo.prefix + enumerator + formatinfo.suffix + ' ' + def field_marker(self, match, context, next_state): """Field list item.""" fieldlist = nodes.field_list() @@ -1874,7 +1919,8 @@ class EnumeratedList(SpecializedBody): match, self.parent['enumtype']) if (sequence != self.parent['enumtype'] or format != self.format or - ordinal != self.lastordinal + 1): + ordinal != (self.lastordinal + 1) or + not self.is_enumerated_list_item(ordinal, sequence, format)): # different enumeration: new list self.invalid_input() listitem, blank_finish = self.list_item(match.end()) @@ -1999,11 +2045,7 @@ class Text(RSTState): def eof(self, context): if context: - paragraph, literalnext = self.paragraph( - context, self.state_machine.abs_line_number() - 1) - self.parent += paragraph - if literalnext: - self.parent += self.literal_block() + self.blank(None, context, None) return [] def indent(self, match, context, next_state): @@ -2163,7 +2205,9 @@ class Definition(SpecializedText): class Line(SpecializedText): - """Second line of over- & underlined section title or transition marker.""" + """ + 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.""" -- cgit v1.2.1 From edef2e799880bb096510ccc1881dc37fb89c413d Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 16 Aug 2002 00:35:47 +0000 Subject: Added support for "line_block" elements. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@539 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index cd7402fcd..2fd517d1c 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -654,6 +654,13 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_legend(self, node): self.body.append('\n') + def visit_line_block(self, node): + self.body.append(self.starttag(node, 'pre', suffix='', + 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) and isinstance(node[0], nodes.paragraph): -- cgit v1.2.1 From 09f7c959981a2e5f51ab2c28b1388cb4d91c2bff Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 16 Aug 2002 01:49:44 +0000 Subject: simplified git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@547 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/body.py | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index 98f04d237..d60bb98e9 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -49,35 +49,22 @@ def topic(match, type_name, data, state, state_machine, attributes): return [topic_node], blank_finish -def parsed_literal(match, type_name, data, state, state_machine, attributes): +def parsed_literal(match, type_name, data, state, state_machine, attributes, + node_class=nodes.literal_block): 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()) while indented and not indented[-1].strip(): indented.pop() - blocktext = '\n'.join(state_machine.input_lines[ - initial_offset : line_offset + len(indented)]) if not indented: return [], blank_finish text = '\n'.join(indented) textnodes, messages = state.inline_text(text, lineno) - literal = nodes.literal_block(text, '', *textnodes) - return [literal] + messages, blank_finish + node = node_class(text, '', *textnodes) + return [node] + messages, blank_finish def line_block(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()) - while indented and not indented[-1].strip(): - indented.pop() - blocktext = '\n'.join(state_machine.input_lines[ - initial_offset : line_offset + len(indented)]) - if not indented: - return [], blank_finish - text = '\n'.join(indented) - textnodes, messages = state.inline_text(text, lineno) - line_block_node = nodes.line_block(text, '', *textnodes) - return [line_block_node] + messages, blank_finish + return parsed_literal(match, type_name, data, state, state_machine, + attributes, node_class=nodes.line_block) -- cgit v1.2.1 From f0b8b4564b132e5d6622d98c56b93deeabffc1cc Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 17 Aug 2002 01:22:29 +0000 Subject: Simplified and improved the "line-block" and "parsed-literal" code. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@548 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/body.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index d60bb98e9..ad603dae6 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -49,22 +49,24 @@ def topic(match, type_name, data, state, state_machine, attributes): return [topic_node], blank_finish -def parsed_literal(match, type_name, data, state, state_machine, attributes, - node_class=nodes.literal_block): +def line_block(match, type_name, data, state, state_machine, attributes, + node_class=nodes.line_block): 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()) while indented and not indented[-1].strip(): indented.pop() if not indented: - return [], blank_finish + warning = state_machine.reporter.warning( + 'Text block expected for the "%s" directive after line %s; none ' + 'found.' % (type_name, 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 -def line_block(match, type_name, data, state, state_machine, attributes): - return parsed_literal(match, type_name, data, state, state_machine, - attributes, node_class=nodes.line_block) +def parsed_literal(match, type_name, data, state, state_machine, attributes): + return line_block(match, type_name, data, state, state_machine, + attributes, node_class=nodes.literal_block) -- cgit v1.2.1 From 74799c8befaa980bd5b42a9027bf2420bf0cfc08 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 17 Aug 2002 01:24:05 +0000 Subject: Improved the ``TargetNotes`` name handling. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@549 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index ff3cfb081..662547ea6 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -691,7 +691,8 @@ class TargetNotes(Transform): def make_target_footnote(self, target, refs): footnote = nodes.footnote() footnote_id = self.document.set_id(footnote) - footnote_name = '_targetnote ' + footnote_id + # Use a colon; they can't be produced inside names by the parser: + footnote_name = 'target_note: ' + footnote_id footnote['auto'] = 1 footnote['name'] = footnote_name footnote += nodes.reference('', target['refuri'], -- cgit v1.2.1 From b24a391ecebe5f31ba0129fdecf2aadbef595f5b Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 17 Aug 2002 01:31:15 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@553 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index d6345562a..002270bc6 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -24,9 +24,9 @@ Where: - ``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 - by substitution definitions (value: the substitution name), which may by - used by an embedded image directive. + element the directive produces. Currently, only an "alt" attribute 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: -- cgit v1.2.1 From 29d91209909f3ef393cc04d0c20db22db7069c8b Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 21 Aug 2002 02:31:32 +0000 Subject: Try to get path/stream name automatically in ``FileInput`` & ``FileOutput``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@565 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index 07337672a..6fa62af55 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -126,6 +126,11 @@ class FileInput(Input): else: self.source = sys.stdin self.autoclose = None + if not source_path: + try: + self.source_path = self.source.name + except AttributeError: + pass def read(self, reader): """Read and decode a single file and return the data.""" @@ -165,6 +170,11 @@ class FileOutput(Output): else: self.destination = sys.stdout self.autoclose = None + if not destination_path: + try: + self.destination_path = self.destination.name + except AttributeError: + pass def open(self): self.destination = open(self.destination_path, 'w') -- cgit v1.2.1 From f14a4a77a3317b106627cb417e13579734768854 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 21 Aug 2002 02:33:45 +0000 Subject: Added new abstract superclass ``FixedTextElement``; adds "xml:space" attribute. Added ``address`` node class. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@566 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 8f613a573..877dcd047 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -502,6 +502,15 @@ class TextElement(Element): Element.__init__(self, rawsource, *children, **attributes) +class FixedTextElement(TextElement): + + """An element which directly contains preformatted text.""" + + def __init__(self, rawsource='', text='', *children, **attributes): + TextElement.__init__(self, rawsource, text, *children, **attributes) + self.attributes['xml:space'] = 1 + + # ======== # Mixins # ======== @@ -872,6 +881,7 @@ class docinfo(Bibliographic, Element): pass class author(Bibliographic, TextElement): pass class authors(Bibliographic, Element): pass class organization(Bibliographic, TextElement): pass +class address(Bibliographic, FixedTextElement): pass class contact(Bibliographic, TextElement): pass class version(Bibliographic, TextElement): pass class revision(Bibliographic, TextElement): pass @@ -959,9 +969,9 @@ class option_list_item(Part, Element): class option_string(Part, TextElement): pass class description(Part, Element): pass -class literal_block(General, TextElement): pass -class doctest_block(General, TextElement): pass -class line_block(General, TextElement): pass +class literal_block(General, FixedTextElement): pass +class doctest_block(General, FixedTextElement): pass +class line_block(General, FixedTextElement): pass class block_quote(General, Element): pass class attention(Admonition, Element): pass class caution(Admonition, Element): pass @@ -972,7 +982,7 @@ class note(Admonition, Element): pass class tip(Admonition, Element): pass class hint(Admonition, Element): pass class warning(Admonition, Element): pass -class comment(Special, Invisible, PreBibliographic, TextElement): pass +class comment(Special, Invisible, PreBibliographic, FixedTextElement): pass class substitution_definition(Special, Invisible, TextElement): pass class target(Special, Invisible, Inline, TextElement, Targetable): pass class footnote(General, Element, Labeled, BackLinkable): pass @@ -999,8 +1009,8 @@ class system_message(Special, PreBibliographic, Element, BackLinkable): Element.__init__(self, '', *children, **attributes) def astext(self): - return '%s (%s) %s' % (self['type'], self['level'], - Element.astext(self)) + return '%s/%s (%s) %s' % (self['type'], self['level'], self['source'], + Element.astext(self)) class pending(Special, Invisible, PreBibliographic, Element): @@ -1081,7 +1091,7 @@ class pending(Special, Invisible, PreBibliographic, Element): **self.attributes) -class raw(Special, Inline, PreBibliographic, TextElement): +class raw(Special, Inline, PreBibliographic, FixedTextElement): """ Raw data that is to be passed untouched to the Writer. @@ -1120,7 +1130,7 @@ class generated(Inline, TextElement): pass node_class_names = """ Text - attention author authors + address attention author authors block_quote bullet_list caption caution citation citation_reference classifier colspec comment contact copyright -- cgit v1.2.1 From 08c643062389b23a4c72004b417eb8104c2afbce Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 21 Aug 2002 02:42:19 +0000 Subject: Improved support for generic fields. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@567 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/frontmatter.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index 3a3cc6e5f..fbe281075 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -274,6 +274,10 @@ class DocInfo(Transform): else: docinfo.append(biblioclass('', *field[1].children)) except TransformError: + if len(field[-1]) == 1 \ + and isinstance(field[-1][0], nodes.paragraph): + utils.clean_rcs_keywords( + field[-1][0], self.rcs_keyword_substitutions) docinfo.append(field) continue nodelist = [] @@ -285,18 +289,18 @@ class DocInfo(Transform): return nodelist def check_empty_biblio_field(self, field, name): - if len(field[1]) < 1: + if len(field[-1]) < 1: 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: + if len(field[-1]) > 1: field[-1] += self.document.reporter.warning( 'Cannot extract compound bibliographic field "%s".' % name) return None - if not isinstance(field[1][0], nodes.paragraph): + 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) -- cgit v1.2.1 From 4223ee697fe8de32b95b79d996eaf805424d6737 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 21 Aug 2002 02:43:46 +0000 Subject: Added a ``source`` attribute to Reporter instances and ``system_message`` elements. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@568 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/utils.py b/docutils/utils.py index c8a0be2ba..84133f650 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -66,12 +66,14 @@ class Reporter: levels = 'DEBUG INFO WARNING ERROR SEVERE'.split() """List of names for system message levels, indexed by level.""" - def __init__(self, report_level, halt_level, stream=None, debug=0): + def __init__(self, source, report_level, halt_level, stream=None, + debug=0): """ 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`. - `halt_level`: The level at or above which `SystemMessage` @@ -81,6 +83,9 @@ class Reporter: ``.write`` method), a string (file name, opened for writing), or `None` (implies `sys.stderr`; default). """ + self.source = source + """The path to or description of the source data.""" + if stream is None: stream = sys.stderr elif type(stream) in (StringType, UnicodeType): @@ -120,6 +125,7 @@ class Reporter: msg = nodes.system_message(comment, 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: @@ -333,12 +339,12 @@ def normalize_name(name): """Return a case- and whitespace-normalized name.""" return ' '.join(name.lower().split()) -def new_document(options=None): +def new_document(source, options=None): if options is None: options = frontend.OptionParser().get_default_values() - reporter = Reporter(options.report_level, options.halt_level, + reporter = Reporter(source, options.report_level, options.halt_level, options.warning_stream, options.debug) - document = nodes.document(options=options, reporter=reporter) + document = nodes.document(options, reporter, source=source) return document def clean_rcs_keywords(paragraph, keyword_substitutions): -- cgit v1.2.1 From 5af5a5f0d33cac7735bf61c521a04b6f24871079 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 21 Aug 2002 02:46:33 +0000 Subject: - Added support for "address" element. - Improved backlinks (footnotes & system_messages). - Improved system_message output. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@569 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 2fd517d1c..410fae11f 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -203,6 +203,15 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_Text(self, node): pass + def visit_address(self, node): + self.visit_docinfo_item(node, 'address', meta=None) + self.body.append(self.starttag(node, 'pre', suffix='', + CLASS='line-block')) + + def depart_address(self, node): + self.body.append('\n') + self.depart_docinfo_item() + def visit_admonition(self, node, name): self.body.append(self.starttag(node, 'div', CLASS=name)) self.body.append('

    ' @@ -328,7 +337,7 @@ class HTMLTranslator(nodes.NodeVisitor): raise nodes.SkipNode def visit_contact(self, node): - self.visit_docinfo_item(node, 'contact') + self.visit_docinfo_item(node, 'contact', meta=None) def depart_contact(self, node): self.depart_docinfo_item() @@ -403,9 +412,10 @@ class HTMLTranslator(nodes.NodeVisitor): self.docinfo = self.body[start:] self.body = [] - def visit_docinfo_item(self, node, name): - self.head.append('\n' - % (name, self.attval(node.astext()))) + def visit_docinfo_item(self, node, name, meta=1): + if meta: + self.head.append('\n' + % (name, self.attval(node.astext()))) self.body.append(self.starttag(node, 'tr', '')) self.body.append('%s: \n' % self.language.labels[name]) @@ -572,7 +582,7 @@ class HTMLTranslator(nodes.NodeVisitor): backlinks.append('%s' % (backref, i)) i += 1 - self.context.append('(%s) ' % ', '.join(backlinks)) + self.context.append('(%s) ' % ', '.join(backlinks)) self.context.append('' % node['id']) else: self.context.append('') @@ -810,7 +820,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('') def visit_revision(self, node): - self.visit_docinfo_item(node, 'revision') + self.visit_docinfo_item(node, 'revision', meta=None) def depart_revision(self, node): self.depart_docinfo_item() @@ -830,7 +840,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('\n') def visit_status(self, node): - self.visit_docinfo_item(node, 'status') + self.visit_docinfo_item(node, 'status', meta=None) def depart_status(self, node): self.depart_docinfo_item() @@ -859,7 +869,6 @@ class HTMLTranslator(nodes.NodeVisitor): 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'] @@ -873,13 +882,15 @@ class HTMLTranslator(nodes.NodeVisitor): for backref in backrefs: backlinks.append('%s' % (backref, i)) i += 1 - backref_text = '%s; ' % ', '.join(backlinks) + backref_text = '; %s' % ', '.join(backlinks) if attr: - self.body.append(self.starttag({}, 'a', '', **attr)) + a_start = self.starttag({}, 'a', '', **attr) a_end = '' - self.body.append('%s%s (%slevel %s system message)

    \n' - % (node['type'], a_end, backref_text, - node['level'])) + else: + a_start = a_end = '' + self.body.append('System Message: %s%s/%s%s (%s%s)

    \n' + % (a_start, node['type'], node['level'], a_end, + node['source'], backref_text)) def depart_system_message(self, node): self.body.append('\n') @@ -992,7 +1003,7 @@ class HTMLTranslator(nodes.NodeVisitor): pass def visit_version(self, node): - self.visit_docinfo_item(node, 'version') + self.visit_docinfo_item(node, 'version', meta=None) def depart_version(self, node): self.depart_docinfo_item() -- cgit v1.2.1 From 13ed20d392cc6c5e727344dad0c3aca8cea125f1 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 21 Aug 2002 03:00:07 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@572 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/en.py | 2 ++ docutils/parsers/rst/__init__.py | 2 +- docutils/readers/__init__.py | 9 ++++----- 3 files changed, 7 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/languages/en.py b/docutils/languages/en.py index 8488a902b..fb320511d 100644 --- a/docutils/languages/en.py +++ b/docutils/languages/en.py @@ -20,6 +20,7 @@ labels = { 'author': 'Author', 'authors': 'Authors', 'organization': 'Organization', + 'address': 'Address', 'contact': 'Contact', 'version': 'Version', 'revision': 'Revision', @@ -44,6 +45,7 @@ bibliographic_fields = { 'author': nodes.author, 'authors': nodes.authors, 'organization': nodes.organization, + 'address': nodes.address, 'contact': nodes.contact, 'version': nodes.version, 'revision': nodes.revision, diff --git a/docutils/parsers/rst/__init__.py b/docutils/parsers/rst/__init__.py index 66b594841..7894d8869 100644 --- a/docutils/parsers/rst/__init__.py +++ b/docutils/parsers/rst/__init__.py @@ -26,7 +26,7 @@ Usage 3. Create a new empty `docutils.nodes.document` tree:: - document = docutils.utils.new_document() + document = docutils.utils.new_document(source) See `docutils.utils.new_document()` for parameter details. diff --git a/docutils/readers/__init__.py b/docutils/readers/__init__.py index fbd0ee8fc..95f03c461 100644 --- a/docutils/readers/__init__.py +++ b/docutils/readers/__init__.py @@ -30,8 +30,9 @@ class Reader(Component): """ transforms = () - """Ordered tuple of transform classes (each with a ``transform()`` method). - Populated by subclasses. `Reader.transform()` instantiates & runs them.""" + """Ordered tuple of transform classes (each with a ``transform()`` + method). Populated by subclasses. `Reader.transform()` + instantiates & runs them.""" def __init__(self, parser, parser_name): """ @@ -85,9 +86,7 @@ class Reader(Component): def new_document(self): """Create and return a new empty document tree (root node).""" - document = utils.new_document(self.options) - if self.source.source_path: - document['source'] = self.source.source_path + document = utils.new_document(self.source.source_path, self.options) return document -- cgit v1.2.1 From dc60acc162c0031fabdcfb261ff4e2defda9f782 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 23 Aug 2002 01:47:19 +0000 Subject: Made ``publish()`` a bit more convenient. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@573 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index 6dcc93d8a..8c291ea3c 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -147,12 +147,12 @@ 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): + option_spec=None, options=None): """ A convenience function for file I/O front ends; set up & run a `Publisher`. """ - pub = Publisher(reader, parser, writer) + pub = Publisher(reader, parser, writer, options=options) if reader is None: pub.set_reader(reader_name, parser, parser_name) if writer is None: -- cgit v1.2.1 From 743a75b6e6aa77e6d595e722f373264079ea1ca6 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 23 Aug 2002 01:48:35 +0000 Subject: Added defaults for source & destination paths. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@574 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index 6fa62af55..db156b9a0 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -23,6 +23,8 @@ class Input: Abstract base class for input wrappers. """ + 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" @@ -34,6 +36,9 @@ class Input: self.source_path = source_path """A text reference to the source.""" + if not source_path: + self.source_path = self.default_source_path + def __repr__(self): return '%s: source=%r, source_path=%r' % (self.__class__, self.source, self.source_path) @@ -84,6 +89,8 @@ class Output: Abstract base class for output wrappers. """ + 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" @@ -95,6 +102,9 @@ class Output: self.destination_path = destination_path """A text reference to the destination.""" + if not destination_path: + self.destination_path = self.default_destination_path + def __repr__(self): return ('%s: destination=%r, destination_path=%r' % (self.__class__, self.destination, self.destination_path)) @@ -201,6 +211,8 @@ class StringInput(Input): Direct string input. """ + default_source_path = 'string input' + def read(self, reader): """Decode and return the source string.""" return self.decode(self.source) @@ -212,6 +224,8 @@ class StringOutput(Output): Direct string output. """ + default_destination_path = 'string output' + def write(self, data): """Encode `data`, store it in `self.destination`, and return it.""" self.destination = data.encode(self.options.output_encoding) @@ -224,6 +238,8 @@ class NullInput(Input): Degenerate input: read nothing. """ + default_source_path = 'null input' + def read(self, reader): """Return a null string.""" return u'' @@ -235,6 +251,8 @@ class NullOutput(Output): Degenerate output: write nothing. """ + default_destination_path = 'null output' + def write(self, data): """Do nothing ([don't even] send data to the bit bucket).""" pass -- cgit v1.2.1 From 323e641db71eb83083577685200302a739d84e71 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 23 Aug 2002 01:51:15 +0000 Subject: Renamed ``relative_uri`` to ``relative_path``, & fixed logic (thanks to Kenichi Sato). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@575 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/utils.py b/docutils/utils.py index 84133f650..293f3d61c 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -356,15 +356,15 @@ def clean_rcs_keywords(paragraph, keyword_substitutions): textnode.data = pattern.sub(substitution, textnode.data) return -def relative_uri(source, target): +def relative_path(source, target): """ - Build and return a URI to `target`, relative to `source`. + Build and return a path 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]: + if source_parts[:1] != target_parts[:1]: # Nothing in common between paths. Return absolute path. return '/'.join(target_parts) source_parts.reverse() -- cgit v1.2.1 From 4b0b6768c0574040113150e3742ae09087d56191 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 23 Aug 2002 01:52:04 +0000 Subject: Improved "address" & updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@576 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 410fae11f..2f31ec05b 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -121,8 +121,8 @@ 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, - options.stylesheet)] + self.stylesheet_link % utils.relative_path(options._destination, + options.stylesheet)] self.head = [] self.body_prefix = ['\n\n'] self.body_pre_docinfo = [] @@ -206,7 +206,7 @@ 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='line-block')) + CLASS='address')) def depart_address(self, node): self.body.append('\n') -- cgit v1.2.1 From da1ed9c59bcc92e21b45ed894c8850d669b508d0 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 23 Aug 2002 02:03:08 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@585 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/universal.py | 4 ++-- docutils/writers/pep_html.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index dc4a97fb1..1ce2c7dc5 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -62,8 +62,8 @@ class Decorations(Transform): if options.source_url: source = options.source_url else: - source = utils.relative_uri(options._destination, - options._source) + source = utils.relative_path(options._destination, + options._source) text.extend([ nodes.reference('', 'View document source', refuri=source), diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index 6e1750537..374ccf8ef 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -55,8 +55,8 @@ class Writer(html4css1.Writer): stylesheet = options.pep_stylesheet if stylesheet is None: stylesheet = options.stylesheet - subs['stylesheet'] = utils.relative_uri(options._destination, - stylesheet) + subs['stylesheet'] = utils.relative_path(options._destination, + stylesheet) pyhome = options.python_home subs['pyhome'] = pyhome subs['pephome'] = options.pep_home -- cgit v1.2.1 From 3070c1c1a7f59b584446a7bc33c8c1169ade4a33 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 24 Aug 2002 01:18:09 +0000 Subject: - Bumped version to 0.2.2 to reflect changes to stylesheet options. - Factored ``OptionSpec`` out of ``Component``; separately useful. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@587 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index 9e3df1414..097aa3944 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -57,7 +57,7 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.2.1' +__version__ = '0.2.2' """``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.""" @@ -66,19 +66,34 @@ class ApplicationError(StandardError): pass class DataError(ApplicationError): pass -class Component: +class OptionSpec: - """ - Base class for Docutils components. - """ + """Runtime option specification base class.""" + + cmdline_options = () + """Command-line option specification. Override in subclasses. + Used by `docutils.frontend.OptionParser`. + + 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.""" + + relative_path_options = () + """Options containing filesystem paths. Override in subclasses. + Used by `docutils.frontend.OptionParser`. + + Options listed here are to be interpreted relative to the current working + directory.""" + + +class Component(OptionSpec): + + """Base class for Docutils components.""" supported = () """Names for this component. Override in subclasses.""" - cmdline_options = () - """Command-line option specification. - See `docutils.frontend.OptionParser`.""" - def supports(self, format): """ Is `format` supported by this component? -- cgit v1.2.1 From 80ac56e2e5e8dda1b76a70b68f1ab63969cb88a3 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 24 Aug 2002 01:20:30 +0000 Subject: - Set non-command-line defaults in ``OptionParser.__init__()``: ``_source`` & ``_destination``. - Distributed ``relative_path_options`` 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``). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@588 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 86 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 36 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index c03634634..1e4003b9e 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -45,25 +45,26 @@ 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, os.path.dirname(value)) + make_paths_absolute(settings, parser.relative_path_options, + 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): +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`. """ 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.abspath(os.path.join(base_path, dictionary[option]))) + for key in keys: + if pathdict.has_key(key) and pathdict[key]: + pathdict[key] = os.path.normpath( + os.path.abspath(os.path.join(base_path, pathdict[key]))) -class OptionParser(optik.OptionParser): +class OptionParser(optik.OptionParser, docutils.OptionSpec): """ Parser for command-line and library use. The `cmdline_options` @@ -101,9 +102,9 @@ class OptionParser(optik.OptionParser): 'dest': 'datestamp'}), ('Include a "View document source" link (relative to destination).', ['--source-link', '-s'], {'action': 'store_true'}), - ('Use the supplied for a "View document source" link; ' - 'implies --source-link.', - ['--source-url'], {'metavar': ''}), + ('Use the supplied verbatim for a "View document source" ' + 'link; implies --source-link.', + ['--source-url'], {'metavar': ''}), ('Do not include a "View document source" link.', ['--no-source-link'], {'action': 'callback', 'callback': store_multiple, @@ -173,14 +174,14 @@ class OptionParser(optik.OptionParser): (optik.SUPPRESS_HELP, ['--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 options common to all Docutils front ends. Option specs + specific to individual Docutils components are also used (see + `populate_from_components()`).""" + + relative_path_options = ('warning_stream',) version_template = '%%prog (Docutils %s)' % docutils.__version__ + """Default version message.""" def __init__(self, components=(), *args, **kwargs): """ @@ -188,28 +189,40 @@ class OptionParser(optik.OptionParser): ``.cmdline_options`` attribute. `defaults` is a mapping of option default overrides. """ - optik.OptionParser.__init__(self, help=None, format=optik.Titled(), - *args, **kwargs) + optik.OptionParser.__init__( + self, help=None, + format=optik.Titled(), + # Needed when Optik is updated (replaces above 2 lines): + #self, add_help=None, + #formatter=optik.TitledHelpFormatter(width=78), + *args, **kwargs) if not self.version: self.version = self.version_template + # Internal settings with no defaults from option 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.populate_from_components(tuple(components) + (self,)) def populate_from_components(self, components): for component in components: - 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 + 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] + 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): if hasattr(values, 'report_level'): @@ -217,7 +230,8 @@ class OptionParser(optik.OptionParser): 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()) + make_paths_absolute(values.__dict__, self.relative_path_options, + os.getcwd()) return values def check_threshold(self, level): -- cgit v1.2.1 From 51068afd344b3f65920292e5510d836c8061d556 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 24 Aug 2002 01:21:45 +0000 Subject: Redefined "--stylesheet" as containing an invariant URL, used verbatim. Added "--stylesheet-path", interpreted w.r.t. the working directory. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@589 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 2f31ec05b..a1e63e0c5 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -9,9 +9,10 @@ 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. +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. """ __docformat__ = 'reStructuredText' @@ -32,9 +33,16 @@ class Writer(writers.Writer): cmdline_options = ( 'HTML-Specific Options', None, - (('Specify a stylesheet file. Default is "default.css".', + (('Specify a stylesheet URL, used verbatim. Default is ' + '"default.css".', ['--stylesheet'], - {'default': 'default.css', 'metavar': ''}),)) + {'default': 'default.css', 'metavar': ''}), + ('Specify a stylesheet file. The path is interpreted relative ' + 'to the output HTML file. Overrides --stylesheet.', + ['--stylesheet-path'], + {'metavar': ''}),)) + + relative_path_options = ('stylesheet_path',) output = None """Final translated form of `document`.""" @@ -115,14 +123,18 @@ class HTMLTranslator(nodes.NodeVisitor): nodes.NodeVisitor.__init__(self, document) options = document.options self.language = languages.get_language(options.language_code) + if options.stylesheet_path: + stylesheet = utils.relative_path(options._destination, + options.stylesheet_path) + else: + stylesheet = options.stylesheet self.head_prefix = [ self.xml_declaration % options.output_encoding, self.doctype, self.html_head % options.language_code, self.content_type % options.output_encoding, self.generator, - self.stylesheet_link % utils.relative_path(options._destination, - options.stylesheet)] + self.stylesheet_link % stylesheet] self.head = [] self.body_prefix = ['\n\n'] self.body_pre_docinfo = [] @@ -582,7 +594,7 @@ class HTMLTranslator(nodes.NodeVisitor): backlinks.append('%s' % (backref, i)) i += 1 - self.context.append('(%s) ' % ', '.join(backlinks)) + self.context.append('(%s) ' % ', '.join(backlinks)) self.context.append('' % node['id']) else: self.context.append('') @@ -875,20 +887,22 @@ class HTMLTranslator(nodes.NodeVisitor): if node.hasattr('backrefs'): backrefs = node['backrefs'] if len(backrefs) == 1: - attr['href'] = '#' + backrefs[0] + backref_text = ('; backlink' + % backrefs[0]) else: i = 1 backlinks = [] for backref in backrefs: backlinks.append('%s' % (backref, i)) i += 1 - backref_text = '; %s' % ', '.join(backlinks) + backref_text = ('; backlinks: %s' + % ', '.join(backlinks)) 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)

    \n' + self.body.append('System Message: %s%s/%s%s (%s)%s

    \n' % (a_start, node['type'], node['level'], a_end, node['source'], backref_text)) -- cgit v1.2.1 From 080e0e58f01027a91fce06ff0c1917b569878815 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 24 Aug 2002 01:22:47 +0000 Subject: Redefined "--pep-stylesheet" as containing an invariant URL, used verbatim. Added "--pep-stylesheet-path", interpreted w.r.t. the working directory. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@590 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/pep_html.py | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index 374ccf8ef..300805245 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -23,10 +23,15 @@ class Writer(html4css1.Writer): cmdline_options = html4css1.Writer.cmdline_options + ( 'PEP/HTML-Specific Options', None, - (("Specify a PEP stylesheet file. Default is --stylesheet's value. " - 'If given, --pep-stylesheet overrides --stylesheet.', + (('Specify a PEP stylesheet URL, used verbatim. Default is ' + '--stylesheet\'s value. If given, --pep-stylesheet overrides ' + '--stylesheet.', ['--pep-stylesheet'], - {'metavar': ''}), + {'metavar': ''}), + ('Specify a PEP stylesheet file. The path is interpreted relative ' + 'to the output HTML file. Overrides --pep-stylesheet.', + ['--pep-stylesheet-path'], + {'metavar': ''}), ('Specify a template file. Default is "pep-html-template".', ['--pep-template'], {'default': 'pep-html-template', 'metavar': ''}), @@ -41,6 +46,8 @@ class Writer(html4css1.Writer): (optik.SUPPRESS_HELP, ['--no-random'], {'action': 'store_true'}),)) + relative_path_options = ('pep_stylesheet_path', 'pep_template') + def __init__(self): html4css1.Writer.__init__(self) self.translator_class = HTMLTranslator @@ -52,11 +59,17 @@ class Writer(html4css1.Writer): # Substitutions dict for template: subs = {} subs['encoding'] = options.output_encoding - stylesheet = options.pep_stylesheet - if stylesheet is None: + if options.pep_stylesheet_path: + stylesheet = utils.relative_path(options._destination, + options.pep_stylesheet_path) + elif options.pep_stylesheet: + stylesheet = options.pep_stylesheet + elif options._stylesheet_path: + stylesheet = utils.relative_path(options._destination, + options.stylesheet_path) + else: stylesheet = options.stylesheet - subs['stylesheet'] = utils.relative_path(options._destination, - stylesheet) + subs['stylesheet'] = stylesheet pyhome = options.python_home subs['pyhome'] = pyhome subs['pephome'] = options.pep_home -- cgit v1.2.1 From 473739633ba059db86d233b2b383bc0108d65083 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 24 Aug 2002 01:27:18 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@592 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index 8c291ea3c..9aa33467b 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -76,14 +76,15 @@ class Publisher: def setup_option_parser(self, usage=None, description=None, option_spec=None, **defaults): + option_parser = OptionParser( + components=(option_spec, self.reader, self.parser, self.writer), + usage=usage, description=description) config = ConfigParser() config.read_standard_files() config_options = config.get_section('options') - frontend.make_paths_absolute(config_options) + frontend.make_paths_absolute(config_options, + option_parser.relative_path_options) defaults.update(config_options) - option_parser = OptionParser( - components=(option_spec, self.reader, self.parser, self.writer), - usage=usage, description=description) option_parser.set_defaults(**defaults) return option_parser -- cgit v1.2.1 From 236ccf11c2d82f9003ebcab79785981dfaf653d6 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 24 Aug 2002 14:09:15 +0000 Subject: Added literal block to system_message ("sectnum" directive). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@593 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/parts.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/parts.py b/docutils/parsers/rst/directives/parts.py index eeff6fc29..8c36b3cc7 100644 --- a/docutils/parsers/rst/directives/parts.py +++ b/docutils/parsers/rst/directives/parts.py @@ -91,9 +91,12 @@ def sectnum(match, type_name, data, state, state_machine, attributes): if success: # data is a dict of attributes 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 attributes at line %s:\n%s.' - % (match.group(1), lineno, data), '') + % (match.group(1), lineno, data), '', + nodes.literal_block(blocktext, blocktext)) return [error], blank_finish state_machine.document.note_pending(pending) return [pending], blank_finish -- cgit v1.2.1 From f14be8cb9b05636ef65e921923ecd74a7cd8304d Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 27 Aug 2002 00:40:51 +0000 Subject: Changed "attribute" to "option" for directives/extensions. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@597 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 7 +-- docutils/parsers/rst/directives/admonitions.py | 2 +- docutils/parsers/rst/directives/body.py | 9 ++-- docutils/parsers/rst/directives/html.py | 4 +- docutils/parsers/rst/directives/images.py | 32 ++++++------ docutils/parsers/rst/directives/misc.py | 4 +- docutils/parsers/rst/directives/parts.py | 30 +++++------ docutils/parsers/rst/directives/references.py | 3 +- docutils/parsers/rst/states.py | 36 ++++++------- docutils/utils.py | 72 +++++++++++++------------- 10 files changed, 100 insertions(+), 99 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 002270bc6..419350110 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -11,7 +11,8 @@ This package contains directive implementation modules. The interface for directive functions is as follows:: - def directivefn(match, type_name, data, state, state_machine, attributes) + def directivefn(match, type_name, data, state, state_machine, + option_presets): Where: @@ -23,8 +24,8 @@ Where: - ``state`` is the state which called the directive function. - ``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 +- ``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. diff --git a/docutils/parsers/rst/directives/admonitions.py b/docutils/parsers/rst/directives/admonitions.py index 9e6b0ebf7..e1506610f 100644 --- a/docutils/parsers/rst/directives/admonitions.py +++ b/docutils/parsers/rst/directives/admonitions.py @@ -18,7 +18,7 @@ from docutils import nodes def admonition(node_class, match, type_name, data, state, state_machine, - attributes): + option_presets): indented, indent, line_offset, blank_finish \ = state_machine.get_first_known_indented(match.end()) text = '\n'.join(indented) diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index ad603dae6..9ba25844e 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -17,7 +17,7 @@ import sys from docutils import nodes -def topic(match, type_name, data, state, state_machine, attributes): +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 \ @@ -49,7 +49,7 @@ def topic(match, type_name, data, state, state_machine, attributes): return [topic_node], blank_finish -def line_block(match, type_name, data, state, state_machine, attributes, +def line_block(match, type_name, data, state, state_machine, option_presets, node_class=nodes.line_block): lineno = state_machine.abs_line_number() indented, indent, line_offset, blank_finish \ @@ -67,6 +67,7 @@ def line_block(match, type_name, data, state, state_machine, attributes, return [node] + messages, blank_finish -def parsed_literal(match, type_name, data, state, state_machine, attributes): +def parsed_literal(match, type_name, data, state, state_machine, + option_presets): return line_block(match, type_name, data, state, state_machine, - attributes, node_class=nodes.literal_block) + option_presets, node_class=nodes.literal_block) diff --git a/docutils/parsers/rst/directives/html.py b/docutils/parsers/rst/directives/html.py index d21ff0505..e7315bd76 100644 --- a/docutils/parsers/rst/directives/html.py +++ b/docutils/parsers/rst/directives/html.py @@ -18,7 +18,7 @@ from docutils.parsers.rst import states from docutils.transforms import components -def meta(match, type_name, data, state, state_machine, attributes): +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) @@ -41,7 +41,7 @@ def meta(match, type_name, data, state, state_machine, attributes): node += msg return node.get_children(), blank_finish -def imagemap(match, type_name, data, state, state_machine, attributes): +def imagemap(match, type_name, data, state, state_machine, option_presets): return [], 0 diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index 76e5d6f47..94599b933 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -20,12 +20,12 @@ from docutils import nodes, utils def unchanged(arg): return arg # unchanged! -image_attribute_spec = {'alt': unchanged, - 'height': int, - 'width': int, - 'scale': int} +image_option_spec = {'alt': unchanged, + 'height': int, + 'width': int, + 'scale': int} -def image(match, type_name, data, state, state_machine, attributes): +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 = \ @@ -52,28 +52,28 @@ def image(match, type_name, data, state, state_machine, attributes): nodes.literal_block(blocktext, blocktext)) return [error], blank_finish if attlines: - 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) + 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 attributes at line %s:\n%s.' + 'Error in "%s" directive options at line %s:\n%s.' % (match.group(1), lineno, data), '', nodes.literal_block(blocktext, blocktext)) return [error], blank_finish - attributes['uri'] = reference - imagenode = nodes.image(blocktext, **attributes) + option_presets['uri'] = reference + imagenode = nodes.image(blocktext, **option_presets) return [imagenode], blank_finish -def figure(match, type_name, data, state, state_machine, attributes): +def figure(match, type_name, data, state, state_machine, option_presets): line_offset = state_machine.line_offset (imagenode,), blank_finish = image(match, type_name, data, state, - state_machine, attributes) + 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]) + 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) diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 3a23f9226..ee0a56b99 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -16,11 +16,11 @@ __docformat__ = 'reStructuredText' from docutils import nodes -def raw(match, type_name, data, state, state_machine, attributes): +def raw(match, type_name, data, state, state_machine, option_presets): return [], 1 def directive_test_function(match, type_name, data, state, state_machine, - attributes): + option_presets): try: state_machine.next_line() indented, indent, offset, blank_finish = state_machine.get_indented() diff --git a/docutils/parsers/rst/directives/parts.py b/docutils/parsers/rst/directives/parts.py index 8c36b3cc7..a5a5c70f7 100644 --- a/docutils/parsers/rst/directives/parts.py +++ b/docutils/parsers/rst/directives/parts.py @@ -33,12 +33,12 @@ def backlinks(arg): raise ValueError( '"%s" unknown; choose from "top", "entry", or "none"' % arg) -contents_attribute_spec = {'depth': int, - 'local': unchanged, - 'backlinks': backlinks, - 'qa': unchanged} +contents_option_spec = {'depth': int, + 'local': unchanged, + 'backlinks': backlinks} + #'qa': unchanged} -def contents(match, type_name, data, state, state_machine, attributes): +def contents(match, type_name, data, state, state_machine, option_presets): """Table of contents.""" lineno = state_machine.abs_line_number() line_offset = state_machine.line_offset @@ -64,37 +64,37 @@ def contents(match, type_name, data, state, state_machine, attributes): pending = nodes.pending(parts.Contents, 'first writer', {'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 + 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 attributes at line %s:\n%s.' + 'Error in "%s" directive options 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 -sectnum_attribute_spec = {'depth': int} +sectnum_option_spec = {'depth': int} -def sectnum(match, type_name, data, state, state_machine, attributes): +def sectnum(match, type_name, data, state, state_machine, option_presets): """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_attributes( - sectnum_attribute_spec, datablock, blank_finish) - if success: # data is a dict of attributes + 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 attributes at line %s:\n%s.' + 'Error in "%s" directive options at line %s:\n%s.' % (match.group(1), lineno, data), '', nodes.literal_block(blocktext, blocktext)) return [error], blank_finish diff --git a/docutils/parsers/rst/directives/references.py b/docutils/parsers/rst/directives/references.py index 98f06f778..12416d5cb 100644 --- a/docutils/parsers/rst/directives/references.py +++ b/docutils/parsers/rst/directives/references.py @@ -16,7 +16,8 @@ from docutils import nodes from docutils.transforms import references -def target_notes(match, type_name, data, state, state_machine, attributes): +def target_notes(match, type_name, data, state, state_machine, + option_presets): """Target footnote generation.""" pending = nodes.pending(references.TargetNotes, 'first reader', {}) state_machine.document.note_pending(pending) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index eb545a1f2..ed56875cd 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1594,14 +1594,14 @@ class Body(RSTState): self.parent += msg return [], blank_finish - def directive(self, match, **attributes): + 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, attributes) + self.state_machine, option_presets) else: return self.unknown_directive(type_name, data) @@ -1615,21 +1615,20 @@ class Body(RSTState): '', nodes.literal_block(text, text)) return [error], blank_finish - def parse_extension_attributes(self, attribute_spec, datalines, - blank_finish): + def parse_extension_options(self, option_spec, datalines, blank_finish): """ - Parse `datalines` for a field list containing extension attributes - matching `attribute_spec`. + Parse `datalines` for a field list containing extension options + matching `option_spec`. :Parameters: - - `attribute_spec`: a mapping of attribute name to conversion + - `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 attribute dictionary on success, an error string on failure. + - An option dictionary on success, an error string on failure. - Updated `blank_finish` flag. """ node = nodes.field_list() @@ -1637,17 +1636,16 @@ class Body(RSTState): 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 + return 0, 'invalid option block', blank_finish try: - attributes = utils.extract_extension_attributes(node, - attribute_spec) + options = utils.extract_extension_options(node, option_spec) except KeyError, detail: - return 0, ('unknown attribute: "%s"' % detail), blank_finish + return 0, ('unknown option: "%s"' % detail), blank_finish except (ValueError, TypeError), detail: - 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 + return 0, ('invalid option value: %s' % detail), blank_finish + except utils.ExtensionOptionError, detail: + return 0, ('invalid option data: %s' % detail), blank_finish + return 1, options, blank_finish def comment(self, match): if not match.string[match.end():].strip() \ @@ -2007,10 +2005,10 @@ class SubstitutionDef(Body): def embedded_directive(self, match, context, next_state): if self.parent.has_key('alt'): - attributes = {'alt': self.parent['alt']} + option_presets = {'alt': self.parent['alt']} else: - attributes = {} - nodelist, blank_finish = self.directive(match, **attributes) + option_presets = {} + nodelist, blank_finish = self.directive(match, **option_presets) self.parent += nodelist if not self.state_machine.at_eof(): self.blank_finish = blank_finish diff --git a/docutils/utils.py b/docutils/utils.py index 293f3d61c..98ede8ac8 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -198,94 +198,94 @@ class ConditionSet: self.stream) -class ExtensionAttributeError(DataError): pass -class BadAttributeError(ExtensionAttributeError): pass -class BadAttributeDataError(ExtensionAttributeError): pass -class DuplicateAttributeError(ExtensionAttributeError): pass +class ExtensionOptionError(DataError): pass +class BadOptionError(ExtensionOptionError): pass +class BadOptionDataError(ExtensionOptionError): pass +class DuplicateOptionError(ExtensionOptionError): pass -def extract_extension_attributes(field_list, attribute_spec): +def extract_extension_options(field_list, option_spec): """ - Return a dictionary mapping extension attribute names to converted values. + 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. - - `attribute_spec`: Dictionary mapping known attribute names to a + - `option_spec`: Dictionary mapping known option 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 + - `KeyError` for unknown option names. + - `ValueError` for invalid option values (raised by the conversion function). - - `DuplicateAttributeError` for duplicate attributes. - - `BadAttributeError` for invalid fields. - - `BadAttributeDataError` for invalid attribute data (missing name, + - `DuplicateOptionError` for duplicate options. + - `BadOptionError` for invalid fields. + - `BadOptionDataError` for invalid option data (missing name, missing data, bad quotes, etc.). """ - attlist = extract_attributes(field_list) - attdict = assemble_attribute_dict(attlist, attribute_spec) + attlist = extract_options(field_list) + attdict = assemble_option_dict(attlist, option_spec) return attdict -def extract_attributes(field_list): +def extract_options(field_list): """ - Return a list of attribute (name, value) pairs from field names & bodies. + Return a list of option (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, + - `BadOptionError` for invalid fields. + - `BadOptionDataError` for invalid option 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') + raise BadOptionError( + 'extension option field may not contain field arguments') name = str(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) + raise BadOptionDataError( + 'extension option field body may contain\n' + 'a single paragraph only (option "%s")' % name) else: data = body[0][0].astext() attlist.append((name, data)) return attlist -def assemble_attribute_dict(attlist, attspec): +def assemble_option_dict(attlist, attspec): """ - Return a mapping of attribute names to values. + Return a mapping of option names to values. :Parameters: - `attlist`: A list of (name, value) pairs (the output of - `extract_attributes()`). - - `attspec`: Dictionary mapping known attribute names to a + `extract_options()`). + - `attspec`: Dictionary mapping known option 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 + - `KeyError` for unknown option names. + - `DuplicateOptionError` for duplicate options. + - `ValueError` for invalid option values (raised by conversion function). """ - attributes = {} + options = {} for name, value in attlist: convertor = attspec[name] # raises KeyError if unknown - if attributes.has_key(name): - raise DuplicateAttributeError('duplicate attribute "%s"' % name) + if options.has_key(name): + raise DuplicateOptionError('duplicate option "%s"' % name) try: - attributes[name] = convertor(value) + options[name] = convertor(value) except (ValueError, TypeError), detail: - raise detail.__class__('(attribute: "%s"; value: %r)\n%s' + raise detail.__class__('(option: "%s"; value: %r)\n%s' % (name, value, detail)) - return attributes + return options class NameValueError(DataError): pass -- cgit v1.2.1 From 721328bfaa518d9a511a43d78ad422a58308fad3 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 28 Aug 2002 00:22:19 +0000 Subject: Finished changing "attribute" (or "attr") to "option" for directives/extensions. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@600 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'docutils') diff --git a/docutils/utils.py b/docutils/utils.py index 98ede8ac8..1f33f2908 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -223,9 +223,9 @@ def extract_extension_options(field_list, option_spec): - `BadOptionDataError` for invalid option data (missing name, missing data, bad quotes, etc.). """ - attlist = extract_options(field_list) - attdict = assemble_option_dict(attlist, option_spec) - return attdict + option_list = extract_options(field_list) + option_dict = assemble_option_dict(option_list, option_spec) + return option_dict def extract_options(field_list): """ @@ -240,7 +240,7 @@ def extract_options(field_list): - `BadOptionDataError` for invalid option data (missing name, missing data, bad quotes, etc.). """ - attlist = [] + option_list = [] for field in field_list: if len(field) != 2: raise BadOptionError( @@ -256,17 +256,17 @@ def extract_options(field_list): 'a single paragraph only (option "%s")' % name) else: data = body[0][0].astext() - attlist.append((name, data)) - return attlist + option_list.append((name, data)) + return option_list -def assemble_option_dict(attlist, attspec): +def assemble_option_dict(option_list, option_spec): """ Return a mapping of option names to values. :Parameters: - - `attlist`: A list of (name, value) pairs (the output of + - `option_list`: A list of (name, value) pairs (the output of `extract_options()`). - - `attspec`: Dictionary mapping known option names to a + - `option_spec`: Dictionary mapping known option names to a conversion function such as `int` or `float`. :Exceptions: @@ -276,8 +276,8 @@ def assemble_option_dict(attlist, attspec): function). """ options = {} - for name, value in attlist: - convertor = attspec[name] # raises KeyError if unknown + for name, value in option_list: + convertor = option_spec[name] # raises KeyError if unknown if options.has_key(name): raise DuplicateOptionError('duplicate option "%s"' % name) try: -- cgit v1.2.1 From 63cc2ce9e8e918f00f1ae0d383f0fb073a72585b Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 28 Aug 2002 00:35:53 +0000 Subject: whitespace git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@602 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 877dcd047..6ffcb1348 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1064,7 +1064,7 @@ class pending(Special, Invisible, PreBibliographic, Element): internals = [ '.. internal attributes:', ' .transform: %s.%s' % (self.transform.__module__, - self.transform.__name__), + self.transform.__name__), ' .stage: %r' % self.stage, ' .details:'] details = self.details.items() -- cgit v1.2.1 From 537691e2e0b359558a1aba0acda9c2a6f9e31cc3 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 29 Aug 2002 01:44:20 +0000 Subject: Added "--footnote-references" option (superscript or brackets). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@606 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index a1e63e0c5..ef64e7309 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -40,7 +40,12 @@ class Writer(writers.Writer): ('Specify a stylesheet file. The path is interpreted relative ' 'to the output HTML file. Overrides --stylesheet.', ['--stylesheet-path'], - {'metavar': ''}),)) + {'metavar': ''}), + ('Format for footnote references: one of "superscript" or ' + '"brackets". Default is "superscript".', + ['--footnote-references'], + {'choices': ['superscript', 'brackets'], 'default': 'superscript', + 'metavar': ''}),)) relative_path_options = ('stylesheet_path',) @@ -610,11 +615,21 @@ class HTMLTranslator(nodes.NodeVisitor): href = '#' + node['refid'] elif node.has_key('refname'): href = '#' + self.document.nameids[node['refname']] - self.body.append(self.starttag(node, 'a', '', href=href, + format = self.document.options.footnote_references + if format == 'brackets': + suffix = '[' + self.context.append(']') + elif format == 'superscript': + suffix = '' + self.context.append('') + else: # shouldn't happen + suffix = '???' + self.content.append('???') + self.body.append(self.starttag(node, 'a', suffix, href=href, CLASS='footnote-reference')) def depart_footnote_reference(self, node): - self.body.append('') + self.body.append(self.context.pop() + '') def visit_generated(self, node): pass -- cgit v1.2.1 From 9d78dcb9f6dab76a9985e6159a90bc9de11913ee Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 29 Aug 2002 01:45:29 +0000 Subject: Eliminate duplicate URLs in ``TargetNotes``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@607 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 662547ea6..7830004a8 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -668,6 +668,10 @@ class TargetNotes(Transform): footnote references after each reference. """ + def __init__(self, document, component, startnode=None): + Transform.__init__(self, document, component, startnode) + self.notes = {} + def transform(self): nodelist = [] for target in self.document.external_targets: @@ -678,27 +682,37 @@ class TargetNotes(Transform): refs = self.document.refnames.get(name, []) if not refs: continue - nodelist.append(self.make_target_footnote(target, refs)) + footnote = self.make_target_footnote(target, refs) + if not self.notes.has_key(target['refuri']): + self.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'): - nodelist.append(self.make_target_footnote(target, [ref])) + footnote = self.make_target_footnote(target, [ref]) + if not self.notes.has_key(target['refuri']): + self.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): - footnote = nodes.footnote() - footnote_id = self.document.set_id(footnote) - # Use a colon; they can't be produced inside names by the parser: - footnote_name = 'target_note: ' + footnote_id - footnote['auto'] = 1 - footnote['name'] = footnote_name - footnote += nodes.reference('', target['refuri'], - refuri=target['refuri']) - self.document.note_autofootnote(footnote) - self.document.note_explicit_target(footnote, footnote) + refuri = target['refuri'] + if self.notes.has_key(refuri): # duplicate? + footnote = self.notes[refuri] + footnote_name = footnote['name'] + else: # original + footnote = nodes.footnote() + footnote_id = self.document.set_id(footnote) + # Use a colon; they can't be produced inside names by the parser: + footnote_name = 'target_note: ' + footnote_id + footnote['auto'] = 1 + footnote['name'] = footnote_name + footnote += nodes.reference('', refuri, refuri=refuri) + self.document.note_autofootnote(footnote) + self.document.note_explicit_target(footnote, footnote) for ref in refs: refnode = nodes.footnote_reference( refname=footnote_name, auto=1) -- cgit v1.2.1 From 2b57d30609bb5efa7031d6aa3fdaaa9143c8041e Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 29 Aug 2002 02:49:34 +0000 Subject: Added ``option_default_overrides`` to ``docutils.OptionSpec``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@609 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 12 +++++++++--- docutils/frontend.py | 3 +++ docutils/writers/pep_html.py | 2 ++ 3 files changed, 14 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index 097aa3944..c50574045 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -68,20 +68,26 @@ class DataError(ApplicationError): pass class OptionSpec: - """Runtime option specification base class.""" + """ + Runtime option specification base class. + + OptionSpec subclass objects used by `docutils.frontend.OptionParser`. + """ cmdline_options = () """Command-line option specification. Override in subclasses. - Used by `docutils.frontend.OptionParser`. 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_default_overrides = None + """A dictionary of auxiliary defaults, to override defaults for options + defined in other components. Override in subclasses.""" + relative_path_options = () """Options containing filesystem paths. Override in subclasses. - Used by `docutils.frontend.OptionParser`. Options listed here are to be interpreted relative to the current working directory.""" diff --git a/docutils/frontend.py b/docutils/frontend.py index 1e4003b9e..36a20cb07 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -223,6 +223,9 @@ class OptionParser(optik.OptionParser, docutils.OptionSpec): group.add_option(help=help_text, *option_strings, **kwargs) i += 3 + for component in components: + if component and component.option_default_overrides: + self.set_defaults(component.option_default_overrides) def check_values(self, values, args): if hasattr(values, 'report_level'): diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index 300805245..ee4c01187 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -46,6 +46,8 @@ class Writer(html4css1.Writer): (optik.SUPPRESS_HELP, ['--no-random'], {'action': 'store_true'}),)) + option_default_overrides = {'footnote_references': 'brackets'} + relative_path_options = ('pep_stylesheet_path', 'pep_template') def __init__(self): -- cgit v1.2.1 From dc42b55883bb75809e9edcec8e6cd8fdbb8480b1 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 29 Aug 2002 02:57:18 +0000 Subject: fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@611 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 36a20cb07..9e2088787 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -225,7 +225,7 @@ class OptionParser(optik.OptionParser, docutils.OptionSpec): i += 3 for component in components: if component and component.option_default_overrides: - self.set_defaults(component.option_default_overrides) + self.defaults.update(component.option_default_overrides) def check_values(self, values, args): if hasattr(values, 'report_level'): -- cgit v1.2.1 From 573c0a4a6e4d06733db75aa4226ad28296d14b46 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 4 Sep 2002 01:28:15 +0000 Subject: Added "line" attribute to ``system_message`` elements. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@620 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 6ffcb1348..6437ef62d 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1009,8 +1009,13 @@ class system_message(Special, PreBibliographic, Element, BackLinkable): Element.__init__(self, '', *children, **attributes) def astext(self): - return '%s/%s (%s) %s' % (self['type'], self['level'], self['source'], - Element.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)) class pending(Special, Invisible, PreBibliographic, Element): -- cgit v1.2.1 From 520f573499ee93fd4953686d5a71c30f9ec04ce1 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 4 Sep 2002 01:30:12 +0000 Subject: Added support for "line" attribute of ``system_message`` nodes. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@621 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index ef64e7309..d2fc50064 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -912,14 +912,18 @@ class HTMLTranslator(nodes.NodeVisitor): 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

    \n' + self.body.append('System Message: %s%s/%s%s (%s%s)%s

    \n' % (a_start, node['type'], node['level'], a_end, - node['source'], backref_text)) + node['source'], line, backref_text)) def depart_system_message(self, node): self.body.append('\n') -- cgit v1.2.1 From a024b2b067ec8a092d783c9baed4b43dd5898d56 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 4 Sep 2002 01:33:22 +0000 Subject: Converted system messages to use the new "line" attribute. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@622 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/body.py | 16 +-- docutils/parsers/rst/directives/html.py | 22 ++-- docutils/parsers/rst/directives/images.py | 17 +-- docutils/parsers/rst/directives/misc.py | 6 +- docutils/parsers/rst/directives/parts.py | 12 +- docutils/parsers/rst/directives/references.py | 4 +- docutils/parsers/rst/states.py | 168 +++++++++++++------------- 7 files changed, 123 insertions(+), 122 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index 9ba25844e..7d74e7a2b 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -23,11 +23,11 @@ def topic(match, type_name, data, state, state_machine, option_presets): 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)]) + initial_offset : line_offset + len(indented) - 1]) 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)) + '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 @@ -37,15 +37,15 @@ def topic(match, type_name, data, state, state_machine, option_presets): 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), '') + '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 = '' topic_node = nodes.topic(text, title, *messages) if text: - state.nested_parse(indented, line_offset, topic_node) + state.nested_parse(indented, line_offset + 1, topic_node) return [topic_node], blank_finish @@ -58,8 +58,8 @@ def line_block(match, type_name, data, state, state_machine, option_presets, indented.pop() if not indented: warning = state_machine.reporter.warning( - 'Text block expected for the "%s" directive after line %s; none ' - 'found.' % (type_name, lineno)) + '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) diff --git a/docutils/parsers/rst/directives/html.py b/docutils/parsers/rst/directives/html.py index e7315bd76..0e7527592 100644 --- a/docutils/parsers/rst/directives/html.py +++ b/docutils/parsers/rst/directives/html.py @@ -31,13 +31,13 @@ def meta(match, type_name, data, state, state_machine, option_presets): 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.' - % state_machine.abs_line_number(), '', - nodes.literal_block(blocktext, blocktext)) + 'Invalid meta directive.', '', + nodes.literal_block(blocktext, blocktext), + line=state_machine.abs_line_number()) node += msg else: - msg = state_machine.reporter.error('Empty meta directive at line %s.' - % state_machine.abs_line_number()) + msg = state_machine.reporter.error( + 'Empty meta directive.', line=state_machine.abs_line_number()) node += msg return node.get_children(), blank_finish @@ -68,9 +68,9 @@ class MetaBody(states.SpecializedBody): if not indented: 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)) + 'No content for meta tag "%s".' % name, '', + nodes.literal_block(line, line), + line=self.state_machine.abs_line_number()) return msg, blank_finish try: attname, val = utils.extract_name_value(name)[0] @@ -84,9 +84,9 @@ class MetaBody(states.SpecializedBody): except utils.NameValueError, detail: 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)) + 'Error parsing meta tag attribute "%s": %s.' + % (arg, detail), '', nodes.literal_block(line, line), + line=self.state_machine.abs_line_number()) return msg, blank_finish self.document.note_pending(pending) return pending, blank_finish diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index 94599b933..e63105a12 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -41,15 +41,15 @@ def image(match, type_name, data, state, state_machine, option_presets): attlines = [] if not datablock: error = state_machine.reporter.error( - 'Missing image URI argument at line %s.' % lineno, '', - nodes.literal_block(blocktext, blocktext)) + '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]) if reference.find(' ') != -1: error = state_machine.reporter.error( - 'Image URI at line %s contains whitespace.' % lineno, '', - nodes.literal_block(blocktext, blocktext)) + '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( @@ -58,15 +58,16 @@ def image(match, type_name, data, state, state_machine, option_presets): option_presets.update(data) else: # data is an error string error = state_machine.reporter.error( - 'Error in "%s" directive options at line %s:\n%s.' - % (match.group(1), lineno, data), '', - nodes.literal_block(blocktext, blocktext)) + '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 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) @@ -90,7 +91,7 @@ def figure(match, type_name, data, state, state_machine, option_presets): elif not (isinstance(firstnode, nodes.comment) and len(firstnode) == 0): error = state_machine.reporter.error( 'Figure caption must be a paragraph or empty comment.', '', - nodes.literal_block(blocktext, blocktext)) + nodes.literal_block(blocktext, blocktext), line=lineno) return [figurenode, error], blank_finish if len(node) > 1: figurenode += nodes.legend('', *node[1:]) diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index ee0a56b99..663325ead 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -21,6 +21,7 @@ def raw(match, type_name, data, state, state_machine, option_presets): 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() @@ -31,9 +32,10 @@ def directive_test_function(match, type_name, data, state, state_machine, if text: info = state_machine.reporter.info( 'Directive processed. Type="%s", data="%s", directive block:' - % (type_name, data), '', nodes.literal_block(text, text)) + % (type_name, data), '', 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)) + 'None' % (type_name, data), line=lineno) return [info], blank_finish diff --git a/docutils/parsers/rst/directives/parts.py b/docutils/parsers/rst/directives/parts.py index a5a5c70f7..bb7527d05 100644 --- a/docutils/parsers/rst/directives/parts.py +++ b/docutils/parsers/rst/directives/parts.py @@ -70,9 +70,9 @@ def contents(match, type_name, data, state, state_machine, option_presets): pending.details.update(data) else: # data is an error string error = state_machine.reporter.error( - 'Error in "%s" directive options at line %s:\n%s.' - % (match.group(1), lineno, data), '', - nodes.literal_block(blocktext, blocktext)) + 'Error in "%s" directive options:\n%s.' + % (match.group(1), data), '', + nodes.literal_block(blocktext, blocktext), line=lineno) return [error] + messages, blank_finish state_machine.document.note_pending(pending) return [pending] + messages, blank_finish @@ -94,9 +94,9 @@ def sectnum(match, type_name, data, state, state_machine, option_presets): blocktext = '\n'.join(state_machine.input_lines[ line_offset : line_offset + len(datablock) + 1]) error = state_machine.reporter.error( - 'Error in "%s" directive options at line %s:\n%s.' - % (match.group(1), lineno, data), '', - nodes.literal_block(blocktext, blocktext)) + 'Error in "%s" directive options:\n%s.' + % (match.group(1), data), '', + nodes.literal_block(blocktext, blocktext), line=lineno) return [error], blank_finish state_machine.document.note_pending(pending) return [pending], blank_finish diff --git a/docutils/parsers/rst/directives/references.py b/docutils/parsers/rst/directives/references.py index 12416d5cb..0a8b2afd0 100644 --- a/docutils/parsers/rst/directives/references.py +++ b/docutils/parsers/rst/directives/references.py @@ -24,7 +24,7 @@ def target_notes(match, type_name, data, state, state_machine, nodelist = [pending] if data: warning = state_machine.reporter.warning( - 'The "%s" directive takes no data; "%s" ignored (at line %s).' - % (match.group(1), data, state_machine.abs_line_number())) + '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() diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index ed56875cd..88d4f3562 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -316,8 +316,8 @@ class RSTState(StateWS): def title_inconsistent(self, sourcetext, lineno): literalblock = nodes.literal_block('', sourcetext) - error = self.reporter.severe('Title level inconsistent at line %s:' - % lineno, '', literalblock) + error = self.reporter.severe('Title level inconsistent:', '', + literalblock, line=lineno) return error def new_subsection(self, title, lineno, messages): @@ -374,8 +374,8 @@ class RSTState(StateWS): def unindent_warning(self, node_name): return self.reporter.warning( - ('%s ends without a blank line; unexpected unindent at line %s.' - % (node_name, self.state_machine.abs_line_number() + 1))) + '%s ends without a blank line; unexpected unindent.' % node_name, + line=(self.state_machine.abs_line_number() + 1)) def build_regexp(definition, compile=1): @@ -585,8 +585,8 @@ class Inliner: return (string[:matchstart], [nodeclass(rawsource, text)], string[textend:], [], endmatch.group(1)) msg = self.reporter.warning( - 'Inline %s start-string without end-string ' - 'at line %s.' % (nodeclass.__name__, lineno)) + 'Inline %s start-string without end-string.' + % nodeclass.__name__, line=lineno) text = unescape(string[matchstart:matchend], 1) rawsource = unescape(string[matchstart:matchend], 1) prb = self.problematic(text, rawsource, msg) @@ -628,9 +628,9 @@ class Inliner: 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) + 'Multiple roles in interpreted text (both ' + 'prefix and suffix present; only one allowed).', + line=lineno) text = unescape(string[rolestart:textend], 1) prb = self.problematic(text, text, msg) return string[:rolestart], [prb], string[textend:], [msg] @@ -643,7 +643,7 @@ class Inliner: if role: msg = self.reporter.warning( 'Mismatch: both interpreted text role %s and ' - 'reference suffix at line %s.' % (position, lineno)) + 'reference suffix.' % position, line=lineno) text = unescape(string[rolestart:textend], 1) prb = self.problematic(text, text, msg) return string[:rolestart], [prb], string[textend:], [msg] @@ -654,7 +654,7 @@ class Inliner: rawsource, text, role, position) msg = self.reporter.warning( 'Inline interpreted text or phrase reference start-string ' - 'without end-string at line %s.' % lineno) + 'without end-string.', line=lineno) text = unescape(string[matchstart:matchend], 1) prb = self.problematic(text, text, msg) return string[:matchstart], [prb], string[matchend:], [msg] @@ -961,9 +961,8 @@ class Body(RSTState): raise statemachine.TransitionCorrection('text') if ordinal != 1: msg = self.reporter.info( - ('Enumerated list start value not ordinal-1 at line %s: ' - '"%s" (ordinal %s)' - % (self.state_machine.abs_line_number(), text, ordinal))) + 'Enumerated list start value not ordinal-1: "%s" (ordinal %s)' + % (text, ordinal), line=self.state_machine.abs_line_number()) self.parent += msg enumlist = nodes.enumerated_list() self.parent += enumlist @@ -1137,10 +1136,10 @@ class Body(RSTState): optionlist = nodes.option_list() try: listitem, blank_finish = self.option_list_item(match) - except MarkupError, detail: # shouldn't happen; won't match pattern + except MarkupError, (message, lineno): + # This shouldn't happen; pattern won't match. msg = self.reporter.error( - ('Invalid option list marker at line %s: %s' - % (self.state_machine.abs_line_number(), detail))) + 'Invalid option list marker: %s' % message, line=lineno) self.parent += msg indented, indent, line_offset, blank_finish = \ self.state_machine.get_first_known_indented(match.end()) @@ -1201,9 +1200,10 @@ class Body(RSTState): delimiter=delimiter) optlist.append(option) else: - raise MarkupError('wrong numer of option tokens (=%s), ' - 'should be 1 or 2: "%s"' % (len(tokens), - optionstring)) + raise MarkupError( + 'wrong numer of option tokens (=%s), should be 1 or 2: ' + '"%s"' % (len(tokens), optionstring), + self.state_machine.abs_line_number() + 1) return optlist def doctest(self, match, context, next_state): @@ -1230,8 +1230,8 @@ class Body(RSTState): self.parent += nodelist if not blank_finish: msg = self.reporter.warning( - 'Blank line required after table at line %s.' - % (self.state_machine.abs_line_number() + 1)) + 'Blank line required after table.', + line=self.state_machine.abs_line_number() + 1) self.parent += msg return [], next_state, [] @@ -1259,8 +1259,8 @@ class Body(RSTState): block = self.state_machine.get_text_block(flush_left=1) except statemachine.UnexpectedIndentationError, instance: block, lineno = instance.args - messages.append(self.reporter.error( - 'Unexpected indentation at line %s.' % lineno)) + messages.append(self.reporter.error('Unexpected indentation.', + line=lineno)) blank_finish = 0 width = len(block[0].strip()) for i in range(len(block)): @@ -1330,14 +1330,14 @@ class Body(RSTState): def malformed_table(self, block, detail=''): data = '\n'.join(block) - message = 'Malformed table at line %s; formatting as a ' \ - 'literal block.' % (self.state_machine.abs_line_number() - - len(block) + 1) + message = 'Malformed table.' + lineno = self.state_machine.abs_line_number() - len(block) + 1 if detail: message += '\n' + detail - nodelist = [self.reporter.error(message), - nodes.literal_block(data, data)] - return nodelist + error = self.reporter.error(message, '', + nodes.literal_block(data, data), + line=lineno) + return [error] def build_table(self, tabledata, tableline): colspecs, headrows, bodyrows = tabledata @@ -1479,9 +1479,8 @@ class Body(RSTState): blockindex += 1 try: escaped += block[blockindex] - except (IndexError, MarkupError): - raise MarkupError('malformed hyperlink target at line %s.' - % lineno) + except IndexError: + raise MarkupError('malformed hyperlink target.', lineno) del block[:blockindex] block[0] = (block[0] + ' ')[targetmatch.end()-len(escaped)-1:].strip() if block and block[-1].strip()[-1:] == '_': # possible indirect target @@ -1496,10 +1495,9 @@ class Body(RSTState): reference = ''.join([line.strip() for line in block]) if reference.find(' ') != -1: warning = self.reporter.warning( - '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)) + 'Hyperlink target contains whitespace. Perhaps a footnote ' + 'was intended?', '', + nodes.literal_block(blocktext, blocktext), line=lineno) nodelist.append(warning) else: unescaped = unescape(reference) @@ -1548,9 +1546,9 @@ class Body(RSTState): blockindex += 1 try: escaped = escaped + ' ' + block[blockindex].strip() - except (IndexError, MarkupError): - raise MarkupError('malformed substitution definition ' - 'at line %s.' % lineno) + except IndexError: + raise MarkupError('malformed substitution definition.', + lineno) del block[:blockindex] # strip out the substitution marker block[0] = (block[0] + ' ')[subdefmatch.end()-len(escaped)-1:].strip() if not block[0]: @@ -1577,9 +1575,9 @@ class Body(RSTState): i += 1 if len(substitutionnode) == 0: msg = self.reporter.warning( - 'Substitution definition "%s" empty or invalid at line ' - '%s.' % (subname, self.state_machine.abs_line_number()), - '', nodes.literal_block(blocktext, blocktext)) + 'Substitution definition "%s" empty or invalid.' + % subname, '', + nodes.literal_block(blocktext, blocktext), line=lineno) self.parent += msg else: del substitutionnode['alt'] @@ -1588,9 +1586,8 @@ class Body(RSTState): return [substitutionnode], blank_finish else: msg = self.reporter.warning( - 'Substitution definition "%s" missing contents at line %s.' - % (subname, self.state_machine.abs_line_number()), '', - nodes.literal_block(blocktext, blocktext)) + 'Substitution definition "%s" missing contents.' % subname, + '', nodes.literal_block(blocktext, blocktext), line=lineno) self.parent += msg return [], blank_finish @@ -1611,8 +1608,8 @@ 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" at line %s.' % (type_name, lineno), - '', nodes.literal_block(text, text)) + 'Unknown directive type "%s".' % type_name, '', + nodes.literal_block(text, text), line=lineno) return [error], blank_finish def parse_extension_options(self, option_spec, datalines, blank_finish): @@ -1714,10 +1711,11 @@ class Body(RSTState): if expmatch: try: return method(self, expmatch) - except MarkupError, detail: # never reached? + except MarkupError, (message, lineno): # never reached? errors.append( - self.reporter.warning('%s: %s' - % (detail.__class__.__name__, detail))) + self.reporter.warning( + '%s: %s' % (detail.__class__.__name__, message), + line=lineno)) break nodelist, blank_finish = self.comment(match) return nodelist + errors, blank_finish @@ -1762,11 +1760,12 @@ class Body(RSTState): nodelist = [] reference = escape2null(''.join([line.strip() for line in block])) if reference.find(' ') != -1: + lineno = self.state_machine.abs_line_number() - len(block) + 1 warning = self.reporter.warning( - 'Anonymous hyperlink target at line %s contains ' - 'whitespace. Perhaps a footnote was intended?' - % (self.state_machine.abs_line_number() - len(block) + 1), - '', nodes.literal_block(blocktext, blocktext)) + 'Anonymous hyperlink target contains whitespace. Perhaps a ' + 'footnote was intended?', '', + nodes.literal_block(blocktext, blocktext), + line=lineno) nodelist.append(warning) else: target = nodes.target(blocktext, '', anonymous=1) @@ -1784,9 +1783,9 @@ class Body(RSTState): else: blocktext = self.state_machine.line msg = self.reporter.severe( - 'Unexpected section title or transition at line %s.' - % self.state_machine.abs_line_number(), '', - nodes.literal_block(blocktext, blocktext)) + 'Unexpected section title or transition.', '', + nodes.literal_block(blocktext, blocktext), + line=self.state_machine.abs_line_number()) self.parent += msg return [], next_state, [] @@ -1948,7 +1947,7 @@ class OptionList(SpecializedBody): """Option list item.""" try: option_list_item, blank_finish = self.option_list_item(match) - except MarkupError, detail: + except MarkupError, (message, lineno): self.invalid_input() self.parent += option_list_item self.blank_finish = blank_finish @@ -2069,8 +2068,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 at line %s.' % lineno, '', - nodes.literal_block(blocktext, blocktext)) + 'Unexpected section title.', '', + nodes.literal_block(blocktext, blocktext), line=lineno) self.parent += msg return [], next_state, [] title = context[0].rstrip() @@ -2080,8 +2079,8 @@ class Text(RSTState): if len(title) > len(underline): blocktext = context[0] + '\n' + self.state_machine.line msg = self.reporter.warning( - 'Title underline too short at line %s.' % lineno, '', - nodes.literal_block(blocktext, blocktext)) + 'Title underline too short.', '', + nodes.literal_block(blocktext, blocktext), line=lineno) messages.append(msg) style = underline[0] context[:] = [] @@ -2096,8 +2095,7 @@ class Text(RSTState): block = self.state_machine.get_text_block(flush_left=1) except statemachine.UnexpectedIndentationError, instance: block, lineno = instance.args - msg = self.reporter.error( - 'Unexpected indentation at line %s.' % lineno) + msg = self.reporter.error('Unexpected indentation.', line=lineno) lines = context + block paragraph, literalnext = self.paragraph(lines, startline) self.parent += paragraph @@ -2124,8 +2122,8 @@ class Text(RSTState): nodelist.append(self.unindent_warning('Literal block')) else: nodelist.append(self.reporter.warning( - 'Literal block expected at line %s; none found.' - % self.state_machine.abs_line_number())) + 'Literal block expected; none found.', + line=self.state_machine.abs_line_number())) return nodelist def definition_list_item(self, termline): @@ -2141,7 +2139,7 @@ class Text(RSTState): if termline[0][-2:] == '::': definition += self.reporter.info( 'Blank line missing before literal block? Interpreted as a ' - 'definition list item. At line %s.' % (line_offset + 1)) + 'definition list item.', line=line_offset + 1) self.nested_parse(indented, input_offset=line_offset, node=definition) return definitionlistitem, blank_finish @@ -2216,8 +2214,8 @@ class Line(SpecializedText): transition = nodes.transition(context[0]) self.parent += transition msg = self.reporter.error( - 'Document or section may not end with a transition ' - '(line %s).' % (self.state_machine.abs_line_number() - 1)) + 'Document or section may not end with a transition.', + line=self.state_machine.abs_line_number() - 1) self.parent += msg self.eofcheck = 1 return [] @@ -2227,14 +2225,14 @@ class Line(SpecializedText): transition = nodes.transition(context[0]) if len(self.parent) == 0: msg = self.reporter.error( - 'Document or section may not begin with a transition ' - '(line %s).' % (self.state_machine.abs_line_number() - 1)) + 'Document or section may not begin with a transition.', + line=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.state_machine.abs_line_number() - 1)) + 'adjacent transitions not allowed.', + line=self.state_machine.abs_line_number() - 1) self.parent += msg self.parent += transition return [], 'Body', [] @@ -2250,8 +2248,8 @@ class Line(SpecializedText): except IndexError: blocktext = overline + '\n' + title msg = self.reporter.severe( - 'Incomplete section title at line %s.' % lineno, '', - nodes.literal_block(blocktext, blocktext)) + 'Incomplete section title.', '', + nodes.literal_block(blocktext, blocktext), line=lineno) self.parent += msg return [], 'Body', [] source = '%s\n%s\n%s' % (overline, title, underline) @@ -2259,22 +2257,22 @@ class Line(SpecializedText): underline = underline.rstrip() if not self.transitions['underline'][0].match(underline): msg = self.reporter.severe( - 'Missing underline for overline at line %s.' % lineno, '', - nodes.literal_block(source, source)) + 'Missing underline for overline.', '', + nodes.literal_block(source, source), line=lineno) self.parent += msg return [], 'Body', [] elif overline != underline: msg = self.reporter.severe( - 'Title overline & underline mismatch at ' 'line %s.' - % lineno, '', nodes.literal_block(source, source)) + 'Title overline & underline mismatch.', '', + nodes.literal_block(source, source), line=lineno) self.parent += msg return [], 'Body', [] title = title.rstrip() messages = [] if len(title) > len(overline): msg = self.reporter.warning( - 'Title overline too short at line %s.'% lineno, '', - nodes.literal_block(source, source)) + 'Title overline too short.', '', + nodes.literal_block(source, source), line=lineno) messages.append(msg) style = (overline[0], underline[0]) self.eofcheck = 0 # @@@ not sure this is correct @@ -2287,9 +2285,9 @@ class Line(SpecializedText): 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.state_machine.abs_line_number() - 1), '', - nodes.literal_block(blocktext, blocktext)) + 'Invalid section title or transition marker.', '', + nodes.literal_block(blocktext, blocktext), + line=self.state_machine.abs_line_number() - 1) self.parent += msg return [], 'Body', [] -- cgit v1.2.1 From e3a1d04f79d71326853537f702a0665952c5cf20 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 5 Sep 2002 03:04:47 +0000 Subject: - Added support for the observer pattern from ``utils.Reporter``. Added ``parse_messages`` and ``transform_messages`` attributes to ``document``, removed ``messages``. Added ``note_parse_message`` and ``note_transform_message`` methods. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@626 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 6437ef62d..56722347e 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -663,8 +663,11 @@ class document(Root, Structural, Element): self.id_start = 1 """Initial ID number.""" - self.messages = Element() - """System messages generated after parsing.""" + self.parse_messages = [] + """System messages generated while parsing.""" + + self.transform_messages = [] + """System messages generated while applying transforms.""" def asdom(self, dom=xml.dom.minidom): domroot = dom.Document() @@ -676,9 +679,8 @@ class document(Root, Structural, Element): 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 + if msgnode != None: + msgnode += msg else: if node.has_key('name'): id = make_id(node['name']) @@ -731,8 +733,6 @@ class document(Root, Structural, Element): self.nametypes[name] = explicit def set_duplicate_name_id(self, node, id, name, msgnode, explicit): - if msgnode == None: - msgnode = self.messages old_id = self.nameids[name] old_explicit = self.nametypes[name] self.nametypes[name] = old_explicit or explicit @@ -753,7 +753,8 @@ class document(Root, Structural, Element): msg = self.reporter.system_message( level, 'Duplicate explicit target name: "%s".' % name, backrefs=[id]) - msgnode += msg + if msgnode != None: + msgnode += msg dupname(node) else: self.nameids[name] = id @@ -770,7 +771,8 @@ class document(Root, Structural, Element): msg = self.reporter.info( 'Duplicate implicit target name: "%s".' % name, backrefs=[id]) - msgnode += msg + if msgnode != None: + msgnode += msg def has_name(self, name): return self.nameids.has_key(name) @@ -845,9 +847,8 @@ class document(Root, Structural, Element): 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 + if msgnode != None: + msgnode += msg oldnode = self.substitution_defs[name] dupname(oldnode) # keep only the last definition @@ -860,6 +861,12 @@ class document(Root, Structural, Element): def note_pending(self, pending): self.pending.append(pending) + def note_parse_message(self, message): + self.parse_messages.append(message) + + def note_transform_message(self, message): + self.transform_messages.append(message) + def copy(self): return self.__class__(self.options, self.reporter, **self.attributes) -- cgit v1.2.1 From 5ca04faff5c6d8589efc32de49092e12936e218c Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 5 Sep 2002 03:05:44 +0000 Subject: Added support for the observer pattern from ``utils.Reporter``, in ``Reader.parse`` and ``Reader.transform``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@627 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/__init__.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/readers/__init__.py b/docutils/readers/__init__.py index 95f03c461..9fb829b6e 100644 --- a/docutils/readers/__init__.py +++ b/docutils/readers/__init__.py @@ -74,11 +74,15 @@ class Reader(Component): def parse(self): """Parse `self.input` into a document tree.""" - self.document = self.new_document() - self.parser.parse(self.input, self.document) + 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) 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): -- cgit v1.2.1 From 9bd2d1956e361d262b8cbd2bf4e84daad6d16597 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 5 Sep 2002 03:07:45 +0000 Subject: - Added an observer pattern to ``utils.Reporter`` to keep track of system messages. - Fixed a bug in ``relative_path()``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@628 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/utils.py b/docutils/utils.py index 1f33f2908..395374e7d 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -59,8 +59,18 @@ class Reporter: retrieve reporting conditions from the 'writer' category (which, unless explicitly set, defaults to the conditions of the default category). + The Reporter class also employs a modified form of the "Observer" pattern + [GoF95]_ to track system messages generated. The `attach_observer` method + should be called before parsing, with a bound method or function which + 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. """ levels = 'DEBUG INFO WARNING ERROR SEVERE'.split() @@ -95,6 +105,10 @@ class Reporter: stream)} """Mapping of category names to conditions. Default category is ''.""" + self.observers = [] + """List of bound methods or functions to call with each system_message + created.""" + def set_conditions(self, category, report_level, halt_level, stream=None, debug=0): if stream is None: @@ -115,6 +129,20 @@ class Reporter: __getitem__ = get_conditions + def attach_observer(self, observer): + """ + The `observer` parameter is a function or bound method which takes one + argument, a `nodes.system_message` instance. + """ + self.observers.append(observer) + + def detach_observer(self, observer): + self.observers.remove(observer) + + def notify_observers(self, message): + for observer in self.observers: + observer(message) + def system_message(self, level, comment=None, category='', *children, **attributes): """ @@ -134,6 +162,8 @@ class Reporter: print >>stream, 'Reporter:', 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): @@ -362,7 +392,7 @@ def relative_path(source, target): If there is no common prefix, return the absolute path to `target`. """ - source_parts = os.path.abspath(source).split(os.sep) + 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. -- cgit v1.2.1 From c8db0efbe820766afdbeff6939de45a6dd640391 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 5 Sep 2002 03:10:05 +0000 Subject: tweak git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@630 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index d2fc50064..c264c8ef6 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -434,7 +434,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): -- cgit v1.2.1 From c1554e0cae13b502620d286b2d7519c7f4c53909 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 5 Sep 2002 03:15:16 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@631 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 9 --------- docutils/transforms/universal.py | 21 +++++++++++---------- 2 files changed, 11 insertions(+), 19 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 7830004a8..566b0cef3 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -74,7 +74,6 @@ class Hyperlinks(Transform): '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: prb = nodes.problematic( @@ -187,7 +186,6 @@ class Hyperlinks(Transform): msg = self.document.reporter.warning( 'Indirect hyperlink target %s refers to target "%s", ' 'which does not exist.' % (naming, target['refname'])) - self.document.messages += msg msgid = self.document.set_id(msg) for ref in reflist: prb = nodes.problematic( @@ -219,7 +217,6 @@ class Hyperlinks(Transform): msg = self.document.reporter.info( 'Indirect hyperlink target "%s" is not referenced.' % name) - self.document.messages += msg target.referenced = 1 return delatt = 'refname' @@ -233,7 +230,6 @@ class Hyperlinks(Transform): msg = self.document.reporter.info( 'Indirect hyperlink target id="%s" is not referenced.' % id) - self.document.messages += msg target.referenced = 1 return delatt = 'refid' @@ -277,7 +273,6 @@ class Hyperlinks(Transform): msg = self.document.reporter.info( 'External hyperlink target "%s" is not referenced.' % name) - self.document.messages += msg target.referenced = 1 continue for ref in reflist: @@ -319,7 +314,6 @@ class Hyperlinks(Transform): msg = self.document.reporter.info( 'Internal hyperlink target "%s" is not referenced.' % name) - self.document.messages += msg target.referenced = 1 continue for ref in reflist: @@ -530,7 +524,6 @@ class Footnotes(Transform): 'corresponding footnotes available.' % len(self.autofootnote_labels)) 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 @@ -569,7 +562,6 @@ class Footnotes(Transform): 'Too many symbol footnote references: only %s ' 'corresponding footnotes available.' % len(labels)) msgid = self.set_id(msg) - self.document.messages += msg for ref in self.document.symbol_footnote_refs[i:]: if ref.resolved or ref.hasattr('refid'): continue @@ -652,7 +644,6 @@ class Substitutions(Transform): 'Undefined substitution referenced: "%s".' % refname) msgid = self.document.set_id(msg) - self.document.messages += msg prb = nodes.problematic( ref.rawsource, ref.rawsource, refid=msgid) prbid = self.document.set_id(prb) diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 1ce2c7dc5..5e5498a8a 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -10,7 +10,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`. + `nodes.document.transform_messages`. - `TestMessages`: Like `Messages`, used on test runs. - `FinalReferences`: Resolve remaining references. - `Pending`: Execute pending transforms (abstract base class; @@ -67,10 +67,10 @@ class Decorations(Transform): text.extend([ nodes.reference('', 'View document source', refuri=source), - nodes.Text('. ')]) + nodes.Text('.\n')]) if options.datestamp: datestamp = time.strftime(options.datestamp, time.gmtime()) - text.append(nodes.Text('Generated on: ' + datestamp + '. ')) + text.append(nodes.Text('Generated on: ' + datestamp + '.\n')) if options.generator: text.extend([ nodes.Text('Generated by '), @@ -79,7 +79,7 @@ class Decorations(Transform): nodes.Text(' from '), nodes.reference('', 'reStructuredText', refuri='http://' 'docutils.sourceforge.net/rst.html'), - nodes.Text(' source. ')]) + nodes.Text(' source.\n')]) footer = nodes.footer() footer += nodes.paragraph('', '', *text) return footer @@ -95,29 +95,31 @@ class Messages(Transform): """ def transform(self): - unfiltered = self.document.messages.get_children() + unfiltered = self.document.transform_messages threshold = self.document.reporter['writer'].report_level messages = [] for msg in unfiltered: - if msg['level'] >= threshold: + if msg['level'] >= threshold and not msg.parent: 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 += messages - self.document.messages[:] = [] + self.document.transform_messages[:] = [] self.document += section class TestMessages(Transform): """ - Append all system messages to the end of the document. + Append all post-parse system messages to the end of the document. """ def transform(self): - self.document += self.document.messages.get_children() + for msg in self.document.transform_messages: + if not msg.parent: + self.document += msg class FinalChecks(Transform): @@ -146,7 +148,6 @@ class FinalCheckVisitor(nodes.SparseNodeVisitor): if id is None: msg = self.document.reporter.error( 'Unknown target name: "%s".' % (node['refname'])) - self.document.messages += msg msgid = self.document.set_id(msg) prb = nodes.problematic( node.rawsource, node.rawsource, refid=msgid) -- cgit v1.2.1 From 1368e12ba7bc99bbaab878786482331e3cee07ed Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 6 Sep 2002 02:12:54 +0000 Subject: Fixed a substitution reference edge case. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@636 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 88d4f3562..0d5b8ba20 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -469,7 +469,7 @@ class Inliner: r'\*(?!\*)', # emphasis but not strong r'``', # literal r'_`', # inline internal target - r'\|'] # substitution reference + r'\|(?!\|)'] # substitution reference ), ('whole', '', end_string_suffix, # whole constructs [# reference name & end-string -- cgit v1.2.1 From 8d99e24bdb9eeee509fb25513a0d88f7ac03dd57 Mon Sep 17 00:00:00 2001 From: chodorowski Date: Fri, 6 Sep 2002 16:04:40 +0000 Subject: Added support for 'align'. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@640 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/images.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index e63105a12..0e0c14277 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -23,7 +23,9 @@ def unchanged(arg): image_option_spec = {'alt': unchanged, 'height': int, 'width': int, - 'scale': int} + 'scale': int, + 'align': unchanged} + def image(match, type_name, data, state, state_machine, option_presets): lineno = state_machine.abs_line_number() -- cgit v1.2.1 From 4a16efd0a29ad89070e8bd19e16b141014935189 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 7 Sep 2002 02:31:14 +0000 Subject: Added the "--pep-references" and "--rfc-references" options. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@643 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/__init__.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'docutils') diff --git a/docutils/parsers/rst/__init__.py b/docutils/parsers/rst/__init__.py index 7894d8869..4bc8970c4 100644 --- a/docutils/parsers/rst/__init__.py +++ b/docutils/parsers/rst/__init__.py @@ -58,6 +58,16 @@ class Parser(docutils.parsers.Parser): supported = ('restructuredtext', 'rst', 'rest', 'restx', 'rtxt', 'rstx') """Aliases this parser supports.""" + cmdline_options = ( + 'reStructuredText Parser Options', + None, + (('Recognize and link to PEP references (like "PEP 258").', + ['--pep-references'], + {'action': 'store_true'}), + ('Recognize and link to RFC references (like "RFC 822").', + ['--rfc-references'], + {'action': 'store_true'}),)) + def __init__(self, rfc2822=None, inliner=None): if rfc2822: self.initial_state = 'RFC2822Body' -- cgit v1.2.1 From aba194af678474835e94a9c686d6e5a202706af0 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 7 Sep 2002 02:32:37 +0000 Subject: Added support for "--pep-references" and "--rfc-references" options; reworked ``Inliner`` code to make customization easier. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@644 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 77 +++++++++++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 12 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 0d5b8ba20..d66e52bbd 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -148,6 +148,7 @@ class RSTStateMachine(StateMachineWS): self.match_titles = match_titles if inliner is None: inliner = Inliner() + inliner.init_customizations(document.options) self.memo = Stuff(document=document, reporter=document.reporter, language=self.language, @@ -407,6 +408,20 @@ class Inliner: Parse inline markup; call the `parse()` method. """ + def __init__(self): + self.implicit_dispatch = [(self.patterns.uri, self.standalone_uri),] + """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: + self.implicit_dispatch.append((self.patterns.pep, + self.pep_reference)) + if options.rfc_references: + self.implicit_dispatch.append((self.patterns.rfc, + self.rfc_reference)) + def parse(self, text, lineno, memo, parent): """ Return 2 lists: nodes (text and inline elements), and system_messages. @@ -548,7 +563,21 @@ class Inliner: ) ) %(end_string_suffix)s - """ % locals(), re.VERBOSE)) + """ % locals(), re.VERBOSE), + pep=re.compile( + r""" + %(start_string_prefix)s + ( + (pep-(?P\d+)(.txt)?) # reference to source file + | + (PEP\s+(?P\d+)) # reference by name + ) + %(end_string_suffix)s""" % locals(), re.VERBOSE), + rfc=re.compile( + r""" + %(start_string_prefix)s + (RFC(-|\s+)?(?P\d+)) + %(end_string_suffix)s""" % locals(), re.VERBOSE)) def quoted_start(self, match): """Return 1 if inline markup start-string is 'quoted', 0 if not.""" @@ -787,31 +816,55 @@ class Inliner: else: # not a valid scheme raise MarkupMismatch - implicit = ((patterns.uri, standalone_uri),) - """List of (pattern, dispatch method) pairs.""" + pep_url_local = 'pep-%04d.html' + pep_url_absolute = 'http://www.python.org/peps/pep-%04d.html' + pep_url = pep_url_absolute + + def pep_reference(self, match, lineno): + text = match.group(0) + if text.startswith('pep-'): + pepnum = int(match.group('pepnum1')) + elif text.startswith('PEP'): + pepnum = int(match.group('pepnum2')) + else: + raise MarkupMismatch + ref = self.pep_url % pepnum + unescaped = unescape(text, 0) + return [nodes.reference(unescape(text, 1), unescaped, refuri=ref)] + + rfc_url = 'http://www.faqs.org/rfcs/rfc%d.html' + + def rfc_reference(self, match, lineno): + text = match.group(0) + if text.startswith('RFC'): + rfcnum = int(match.group('rfcnum')) + ref = self.rfc_url % rfcnum + else: + raise MarkupMismatch + unescaped = unescape(text, 0) + return [nodes.reference(unescape(text, 1), unescaped, refuri=ref)] def implicit_inline(self, text, lineno): """ - 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. Return a list of `nodes.Text` and - inline element nodes. + Check each of the patterns in `self.implicit_dispatch` for a match, + and dispatch to the stored method for the pattern. Recursively check + the text before and after the match. Return a list of `nodes.Text` + and inline element nodes. """ if not text: return [] - for pattern, dispatch in self.implicit: + for pattern, method in self.implicit_dispatch: match = pattern.search(text) if match: try: # 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) + + + method(match, lineno) + self.implicit_inline(text[match.end():], lineno)) except MarkupMismatch: pass return [nodes.Text(unescape(text))] - dispatch = {'*': emphasis, '**': strong, @@ -1047,10 +1100,10 @@ class Body(RSTState): try: next_line = self.state_machine.next_line() except IndexError: # end of input lines - self.state_machine.previous_line() + self.state_machine.previous_line() return 1 else: - self.state_machine.previous_line() + self.state_machine.previous_line() if not next_line[:1].strip(): # blank or indented return 1 next_enumerator = self.make_enumerator(ordinal + 1, sequence, format) -- cgit v1.2.1 From 71169a5256be234c8d8b72663c7dda9be2154386 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 7 Sep 2002 02:33:25 +0000 Subject: Removed PEP & RFC reference detection code; moved to parsers/rst/states.py as options (enabled here by default). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@645 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/pep.py | 42 ++++++++++-------------------------------- 1 file changed, 10 insertions(+), 32 deletions(-) (limited to 'docutils') diff --git a/docutils/readers/pep.py b/docutils/readers/pep.py index a4571bbc9..b051d63b9 100644 --- a/docutils/readers/pep.py +++ b/docutils/readers/pep.py @@ -27,6 +27,12 @@ class Reader(standalone.Reader): supported = ('pep',) """Contexts this reader supports.""" + cmdline_options = ( + 'PEP Reader Option Defaults', + 'The --pep-references and --rfc-references options (for the ' + 'reStructuredText parser) are on by default.', + ()) + transforms = (references.Substitutions, peps.Headers, peps.Contents, @@ -34,6 +40,8 @@ class Reader(standalone.Reader): references.Footnotes, references.Hyperlinks,) + option_default_overrides = {'pep_references': 1, 'rfc_references': 1} + def __init__(self, parser, parser_name): """`parser` should be ``None``.""" if parser is None: @@ -44,37 +52,7 @@ class Reader(standalone.Reader): class Inliner(rst.states.Inliner): """ - Extend `rst.Inliner` to also parse standalone PEP & RFC references. + Extend `rst.Inliner` to for local PEP 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 rst.states.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.""" + pep_url = rst.states.Inliner.pep_url_local -- cgit v1.2.1 From 8b4029d42a479e1f1da35b31ea250e36319d2d13 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 7 Sep 2002 02:34:15 +0000 Subject: Added "--compact-lists" and "--no-compact-lists" options. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@646 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index c264c8ef6..0c3323986 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -45,7 +45,16 @@ class Writer(writers.Writer): '"brackets". Default is "superscript".', ['--footnote-references'], {'choices': ['superscript', 'brackets'], 'default': 'superscript', - 'metavar': ''}),)) + '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.', + ['--compact-lists'], + {'default': 1, 'action': 'store_true'}), + ('Disable compact simple bullet and enumerated lists.', + ['--no-compact-lists'], + {'dest': 'compact_lists', 'action': 'store_false'}),)) relative_path_options = ('stylesheet_path',) @@ -126,7 +135,7 @@ class HTMLTranslator(nodes.NodeVisitor): def __init__(self, document): nodes.NodeVisitor.__init__(self, document) - options = document.options + self.options = options = document.options self.language = languages.get_language(options.language_code) if options.stylesheet_path: stylesheet = utils.relative_path(options._destination, @@ -276,9 +285,10 @@ 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.compact_simple - or self.topic_class == 'contents' - or self.check_simple_list(node)) + self.compact_simple = (self.options.compact_lists and + (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)) @@ -495,9 +505,10 @@ 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.compact_simple - or self.topic_class == 'contents' - or self.check_simple_list(node)) + self.compact_simple = (self.options.compact_lists and + (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)) @@ -585,8 +596,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.footnote_backrefs(node) def footnote_backrefs(self, node): - if self.document.options.footnote_backlinks \ - and node.hasattr('backrefs'): + if self.options.footnote_backlinks and node.hasattr('backrefs'): backrefs = node['backrefs'] if len(backrefs) == 1: self.context.append('') @@ -615,7 +625,7 @@ class HTMLTranslator(nodes.NodeVisitor): href = '#' + node['refid'] elif node.has_key('refname'): href = '#' + self.document.nameids[node['refname']] - format = self.document.options.footnote_references + format = self.options.footnote_references if format == 'brackets': suffix = '[' self.context.append(']') -- cgit v1.2.1 From 5d6d0b13b959ef217fe9d19dbb5a184446336453 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 7 Sep 2002 02:41:55 +0000 Subject: Removed tabs git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@652 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/images.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index 0e0c14277..b8198dd6a 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -24,8 +24,7 @@ image_option_spec = {'alt': unchanged, 'height': int, 'width': int, 'scale': int, - 'align': unchanged} - + 'align': unchanged} def image(match, type_name, data, state, state_machine, option_presets): lineno = state_machine.abs_line_number() -- cgit v1.2.1 From 49373e9eff9b650bd989452f2067cf2b78a5cebe Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 7 Sep 2002 02:42:09 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@653 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 4 ++-- docutils/core.py | 2 +- docutils/writers/pep_html.py | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index c50574045..8dfc2d3a5 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -69,7 +69,7 @@ class DataError(ApplicationError): pass class OptionSpec: """ - Runtime option specification base class. + Runtime option specification base class. OptionSpec subclass objects used by `docutils.frontend.OptionParser`. """ @@ -85,7 +85,7 @@ class OptionSpec: option_default_overrides = None """A dictionary of auxiliary defaults, to override defaults for options defined in other components. Override in subclasses.""" - + relative_path_options = () """Options containing filesystem paths. Override in subclasses. diff --git a/docutils/core.py b/docutils/core.py index 9aa33467b..8354d8393 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -77,7 +77,7 @@ class Publisher: def setup_option_parser(self, usage=None, description=None, option_spec=None, **defaults): option_parser = OptionParser( - components=(option_spec, self.reader, self.parser, self.writer), + components=(option_spec, self.parser, self.reader, self.writer), usage=usage, description=description) config = ConfigParser() config.read_standard_files() diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index ee4c01187..2ae16b24a 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -22,7 +22,8 @@ class Writer(html4css1.Writer): cmdline_options = html4css1.Writer.cmdline_options + ( 'PEP/HTML-Specific Options', - None, + 'The HTML --footnote-references option is set to "brackets" by ' + 'default.', (('Specify a PEP stylesheet URL, used verbatim. Default is ' '--stylesheet\'s value. If given, --pep-stylesheet overrides ' '--stylesheet.', -- cgit v1.2.1 From 5b8929c3291e2e0625c1336dcf6d12530bc00f36 Mon Sep 17 00:00:00 2001 From: chodorowski Date: Mon, 9 Sep 2002 17:21:43 +0000 Subject: Make sure that the keyword passed to the 'align' option is one of 'bottom', 'middle', 'top', 'left', 'center' or 'right'. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@655 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/images.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index b8198dd6a..439f24531 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -20,11 +20,31 @@ from docutils import nodes, utils def unchanged(arg): return arg # unchanged! +def format_allowed( allowed ): + qouted = map( lambda s: '"%s"' % s, allowed ) + return ' or '.join( [ ', '.join( qouted[:-1] ), qouted[-1] ] ) + +def align( argument ): + allowed = ( 'top', 'middle', 'bottom', 'left', 'center', 'right' ) + + try: + value = argument.lower().strip() + except AttributeError: + raise TypeError('must supply an argument; choose from %s', + format_allowed( allowed )) + + if value in allowed: + return value + else: + raise ValueError( + '"%s" unknown; choose from %s' % (argument, format_allowed( allowed )) ) + + image_option_spec = {'alt': unchanged, 'height': int, 'width': int, 'scale': int, - 'align': unchanged} + 'align': align} def image(match, type_name, data, state, state_machine, option_presets): lineno = state_machine.abs_line_number() -- cgit v1.2.1 From c84ea50f0fb04462de27076b70fc7297f5d71eaa Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 10 Sep 2002 03:28:03 +0000 Subject: Added ``flag()``, ``unchanged()``, and ``choice()`` directive option helper functions. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@658 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 419350110..3968d575e 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -109,3 +109,28 @@ def directive(directive_name, language_module): except AttributeError: return None return function + +def flag(argument): + if argument and argument.strip(): + raise ValueError('no argument is allowed; "%s" supplied' % argument) + else: + return None + +def unchanged(argument): + return argument # unchanged! + +def format_values(values): + return '%s, or "%s"' % (', '.join(['"%s"' % s for s in values[:-1]]), + values[-1]) + +def choice(argument, values): + try: + value = argument.lower().strip() + except AttributeError: + raise TypeError('must supply an argument; choose from %s', + format_values(values)) + if value in values: + return value + else: + raise ValueError('"%s" unknown; choose from %s' + % (argument, format_values(values))) -- cgit v1.2.1 From 4d9b2b3cd409effab2c8ee243e5aa69f38371099 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 10 Sep 2002 03:29:36 +0000 Subject: Moved ``unchanged()`` helper function and code from ``align()`` to __init__.py; updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@659 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/images.py | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index 439f24531..bb997bc58 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -14,33 +14,16 @@ __docformat__ = 'reStructuredText' import sys -from docutils.parsers.rst import states from docutils import nodes, utils +from docutils.parsers.rst import directives -def unchanged(arg): - return arg # unchanged! -def format_allowed( allowed ): - qouted = map( lambda s: '"%s"' % s, allowed ) - return ' or '.join( [ ', '.join( qouted[:-1] ), qouted[-1] ] ) - -def align( argument ): - allowed = ( 'top', 'middle', 'bottom', 'left', 'center', 'right' ) - - try: - value = argument.lower().strip() - except AttributeError: - raise TypeError('must supply an argument; choose from %s', - format_allowed( allowed )) - - if value in allowed: - return value - else: - raise ValueError( - '"%s" unknown; choose from %s' % (argument, format_allowed( allowed )) ) +align_values = ('top', 'middle', 'bottom', 'left', 'center', 'right') +def align(argument): + return directives.choice(argument, align_values) -image_option_spec = {'alt': unchanged, +image_option_spec = {'alt': directives.unchanged, 'height': int, 'width': int, 'scale': int, @@ -109,7 +92,8 @@ def figure(match, type_name, data, state, state_machine, option_presets): caption = nodes.caption(firstnode.rawsource, '', *firstnode.children) figurenode += caption - elif not (isinstance(firstnode, nodes.comment) and len(firstnode) == 0): + elif not (isinstance(firstnode, nodes.comment) + and len(firstnode) == 0): error = state_machine.reporter.error( 'Figure caption must be a paragraph or empty comment.', '', nodes.literal_block(blocktext, blocktext), line=lineno) -- cgit v1.2.1 From 0c5fd85359f37a4c3d25c5df8dfd6e0c4702d692 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 10 Sep 2002 03:31:21 +0000 Subject: Updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@660 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/parts.py | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/parts.py b/docutils/parsers/rst/directives/parts.py index bb7527d05..9a3e9e71c 100644 --- a/docutils/parsers/rst/directives/parts.py +++ b/docutils/parsers/rst/directives/parts.py @@ -14,27 +14,20 @@ __docformat__ = 'reStructuredText' from docutils import nodes from docutils.transforms import parts +from docutils.parsers.rst import directives -def unchanged(arg): - return arg # unchanged! +backlinks_values = ('top', 'entry', 'none') def backlinks(arg): - try: - value = arg.lower().strip() - except AttributeError: - raise TypeError('must supply an argument; choose from "top", ' - '"entry", or "none"') + value = directives.choice(arg, backlinks_values) 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) + return value contents_option_spec = {'depth': int, - 'local': unchanged, + 'local': directives.flag, 'backlinks': backlinks} #'qa': unchanged} -- cgit v1.2.1 From 6b549311b8e4d646cc2922743dd7544bee035b21 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 10 Sep 2002 03:35:17 +0000 Subject: fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@661 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 3968d575e..9cdde6d31 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -127,8 +127,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 TypeError('must supply an argument; choose from %s' + % format_values(values)) if value in values: return value else: -- cgit v1.2.1 From a07bc663d7654004db7594bb1601525b18d46f4a Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 11 Sep 2002 02:52:01 +0000 Subject: Removed "field_argument" element & support; "field_name" may contain multiple words and whitespace. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@664 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 3 +-- docutils/parsers/rst/states.py | 9 +++------ docutils/writers/html4css1.py | 15 +-------------- 3 files changed, 5 insertions(+), 22 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 56722347e..095868297 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -946,7 +946,6 @@ class definition(Part, Element): pass class field_list(Sequential, 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 @@ -1149,7 +1148,7 @@ node_class_names = """ 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 footer + field field_body field_list field_name figure footer footnote footnote_reference generated header hint diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index d66e52bbd..fa2d6260f 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1163,13 +1163,11 @@ class Body(RSTState): return [], next_state, [] def field(self, match): - name, args = self.parse_field_marker(match) + name = self.parse_field_marker(match) 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: - fieldnode += nodes.field_argument(arg, arg) fieldbody = nodes.field_body('\n'.join(indented)) fieldnode += fieldbody if indented: @@ -1178,11 +1176,10 @@ class Body(RSTState): return fieldnode, blank_finish def parse_field_marker(self, match): - """Extract & return name & argument list from a field marker 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. - tokens = field.split() - return tokens[0], tokens[1:] # first == name, others == args + return field def option_marker(self, match, context, next_state): """Option list item.""" diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 0c3323986..51c0fe768 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -529,16 +529,7 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_field(self, node): self.body.append('\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('') - 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') @@ -564,11 +555,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.starttag(node, 'th', '', CLASS=class_name)) def depart_field_name(self, node): - """ - Leave the end tag to `self.visit_field_body()`, in case there are any - field_arguments. - """ - pass + self.body.append(': ') def visit_figure(self, node): self.body.append(self.starttag(node, 'div', CLASS='figure')) -- cgit v1.2.1 From 2ba8fffc2b3bf0e74aedfd33533f10a54a5b77be Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 11 Sep 2002 02:54:23 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@665 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/html.py | 16 +++++++++------- docutils/utils.py | 8 ++++---- 2 files changed, 13 insertions(+), 11 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/html.py b/docutils/parsers/rst/directives/html.py index 0e7527592..732ef7b56 100644 --- a/docutils/parsers/rst/directives/html.py +++ b/docutils/parsers/rst/directives/html.py @@ -27,7 +27,8 @@ def meta(match, type_name, data, state, state_machine, option_presets): 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? + 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( @@ -58,7 +59,7 @@ class MetaBody(states.SpecializedBody): return [], next_state, [] def parsemeta(self, match): - name, args = self.parse_field_marker(match) + name = self.parse_field_marker(match) indented, indent, line_offset, blank_finish = \ self.state_machine.get_first_known_indented(match.end()) node = self.meta() @@ -72,20 +73,21 @@ class MetaBody(states.SpecializedBody): nodes.literal_block(line, line), line=self.state_machine.abs_line_number()) return msg, blank_finish + tokens = name.split() try: - attname, val = utils.extract_name_value(name)[0] + attname, val = utils.extract_name_value(tokens[0])[0] node[attname.lower()] = val except utils.NameValueError: - node['name'] = name - for arg in args: + node['name'] = tokens[0] + for token in tokens[1:]: try: - attname, val = utils.extract_name_value(arg)[0] + attname, val = utils.extract_name_value(token)[0] node[attname.lower()] = val except utils.NameValueError, detail: line = self.state_machine.line msg = self.reporter.error( 'Error parsing meta tag attribute "%s": %s.' - % (arg, 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/utils.py b/docutils/utils.py index 395374e7d..edeb26109 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -262,8 +262,8 @@ def extract_options(field_list): Return a list of option (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. + `field_list`: A flat field list, where each field name is a single + word and each field body consists of a single paragraph only. :Exceptions: - `BadOptionError` for invalid fields. @@ -272,9 +272,9 @@ def extract_options(field_list): """ option_list = [] for field in field_list: - if len(field) != 2: + if len(field[0].astext().split()) != 1: raise BadOptionError( - 'extension option field may not contain field arguments') + 'extension option field name may not contain multiple words') name = str(field[0].astext().lower()) body = field[1] if len(body) == 0: -- cgit v1.2.1 From 3d74553eded7a541d1dd38f29dffc1fcaec07768 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 12 Sep 2002 02:18:39 +0000 Subject: Bumped version to 0.2.3 because of the new ``--embed-stylesheet`` option and its effect on the PEP template & writer. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@668 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index 8dfc2d3a5..229e85dee 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -57,7 +57,7 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.2.2' +__version__ = '0.2.3' """``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 19a3b0b955f0ff97def175154e4226b8df1910ea Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 12 Sep 2002 02:19:42 +0000 Subject: Added "--embed-stylesheet" and "--link-stylesheet" options; factored out ``HTMLTranslator.get_stylesheet_reference()``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@669 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 50 ++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 13 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 51c0fe768..22a9247a2 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -37,10 +37,22 @@ class Writer(writers.Writer): '"default.css".', ['--stylesheet'], {'default': 'default.css', 'metavar': ''}), - ('Specify a stylesheet file. The path is interpreted relative ' - 'to the output HTML file. Overrides --stylesheet.', + ('Specify a stylesheet file, relative to the current working ' + 'directory. The path is adjusted relative to the output HTML ' + 'file. Overrides --stylesheet.', ['--stylesheet-path'], {'metavar': ''}), + ('Link to the stylesheet in the output HTML file. This is the ' + 'default.', + ['--link-stylesheet'], + {'dest': 'embed_stylesheet', 'action': 'store_false'}), + ('Embed the stylesheet in the output HTML file. The stylesheet ' + 'file must be accessible during processing (--stylesheet-path is ' + 'recommended). The stylesheet is embedded inside a comment, so it ' + 'must not contain the text "--" (two hyphens). Default: link the ' + 'stylesheet, do not embed it.', + ['--embed-stylesheet'], + {'action': 'store_true'}), ('Format for footnote references: one of "superscript" or ' '"brackets". Default is "superscript".', ['--footnote-references'], @@ -70,6 +82,7 @@ class Writer(writers.Writer): self.document.walkabout(visitor) self.output = visitor.astext() self.head_prefix = visitor.head_prefix + self.stylesheet = visitor.stylesheet self.head = visitor.head self.body_prefix = visitor.body_prefix self.body_pre_docinfo = visitor.body_pre_docinfo @@ -82,7 +95,7 @@ class HTMLTranslator(nodes.NodeVisitor): """ This HTML writer has been optimized to produce visually compact - HTML (less vertical whitespace). HTML's mixed content models + 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 @@ -116,6 +129,8 @@ class HTMLTranslator(nodes.NodeVisitor): 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. + + The ``--no-compact-lists`` option disables list whitespace optimization. """ xml_declaration = '\n' @@ -129,6 +144,7 @@ class HTMLTranslator(nodes.NodeVisitor): generator = '\n' stylesheet_link = '\n' + embedded_stylesheet = '\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') @@ -137,19 +153,19 @@ class HTMLTranslator(nodes.NodeVisitor): nodes.NodeVisitor.__init__(self, document) self.options = options = document.options self.language = languages.get_language(options.language_code) - if options.stylesheet_path: - stylesheet = utils.relative_path(options._destination, - options.stylesheet_path) - else: - stylesheet = options.stylesheet self.head_prefix = [ self.xml_declaration % options.output_encoding, self.doctype, self.html_head % options.language_code, self.content_type % options.output_encoding, - self.generator, - self.stylesheet_link % stylesheet] + self.generator] self.head = [] + stylesheet = self.get_stylesheet_reference() + if options.embed_stylesheet: + stylesheet_text = open(stylesheet).read() + self.stylesheet = [self.embedded_stylesheet % stylesheet_text] + else: + self.stylesheet = [self.stylesheet_link % stylesheet] self.body_prefix = ['\n\n'] self.body_pre_docinfo = [] self.docinfo = [] @@ -163,10 +179,18 @@ class HTMLTranslator(nodes.NodeVisitor): self.compact_simple = None self.in_docinfo = None + def get_stylesheet_reference(self): + options = self.options + if options.stylesheet_path: + return utils.relative_path(options._destination, + options.stylesheet_path) + else: + return options.stylesheet + def astext(self): - return ''.join(self.head_prefix + self.head + self.body_prefix - + self.body_pre_docinfo + self.docinfo + self.body - + self.body_suffix) + 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.""" -- cgit v1.2.1 From 30d30c80ffea45e7b02f50cb08db766a9e190120 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 12 Sep 2002 02:20:31 +0000 Subject: Factored out ``HTMLTranslator.get_stylesheet_reference()``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@670 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/pep_html.py | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index 2ae16b24a..1f1a432f2 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -29,8 +29,9 @@ class Writer(html4css1.Writer): '--stylesheet.', ['--pep-stylesheet'], {'metavar': ''}), - ('Specify a PEP stylesheet file. The path is interpreted relative ' - 'to the output HTML file. Overrides --pep-stylesheet.', + ('Specify a PEP stylesheet file, relative to the current working ' + 'directory. The path is adjusted relative to the output HTML ' + 'file. Overrides --pep-stylesheet and --stylesheet-path.', ['--pep-stylesheet-path'], {'metavar': ''}), ('Specify a template file. Default is "pep-html-template".', @@ -62,17 +63,7 @@ class Writer(html4css1.Writer): # Substitutions dict for template: subs = {} subs['encoding'] = options.output_encoding - if options.pep_stylesheet_path: - stylesheet = utils.relative_path(options._destination, - options.pep_stylesheet_path) - elif options.pep_stylesheet: - stylesheet = options.pep_stylesheet - elif options._stylesheet_path: - stylesheet = utils.relative_path(options._destination, - options.stylesheet_path) - else: - stylesheet = options.stylesheet - subs['stylesheet'] = stylesheet + subs['stylesheet'] = ''.join(self.stylesheet) pyhome = options.python_home subs['pyhome'] = pyhome subs['pephome'] = options.pep_home @@ -102,6 +93,19 @@ class Writer(html4css1.Writer): class HTMLTranslator(html4css1.HTMLTranslator): + def get_stylesheet_reference(self): + options = self.options + if options.pep_stylesheet_path: + return utils.relative_path(options._destination, + 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) + 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': -- cgit v1.2.1 From ad4b74e07d803a121815322820b360b6336535e9 Mon Sep 17 00:00:00 2001 From: richard Date: Thu, 12 Sep 2002 03:42:31 +0000 Subject: Add a class to "normal" tables so we can play with them specifically in CSS, and not affect other tables. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@674 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 22a9247a2..31454c4db 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -951,7 +951,8 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_table(self, node): self.body.append( - self.starttag(node, 'table', frame='border', rules='all')) + self.starttag(node, 'table', CLASS="table", + frame='border', rules='all')) def depart_table(self, node): self.body.append('\n') -- cgit v1.2.1 From 2eab694fe746f8a8f99f438220daebdecf9d7893 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 15 Sep 2002 16:31:55 +0000 Subject: Added -V (version) option git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@681 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 9e2088787..155893521 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -167,7 +167,7 @@ class OptionParser(optik.OptionParser, docutils.OptionSpec): ['--config'], {'metavar': '', 'type': 'string', 'action': 'callback', 'callback': read_config_file}), ("Show this program's version number and exit.", - ['--version'], {'action': 'version'}), + ['--version', '-V'], {'action': 'version'}), ('Show this help message and exit.', ['--help', '-h'], {'action': 'help'}), # Hidden options, for development use only: -- cgit v1.2.1 From 0b774599f04c5ff6c27b3c271019a949500ea002 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 19 Sep 2002 00:41:42 +0000 Subject: Added support for short section title over/underlines. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@689 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 145 +++++++++++++++++++++++++++++------------ 1 file changed, 105 insertions(+), 40 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index fa2d6260f..fa940c49a 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1,10 +1,10 @@ -""" -: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.parsers.restructuredtext.states`` module, the core of the reStructuredText parser. It defines the following: @@ -217,9 +217,23 @@ class RSTState(StateWS): """ try: self.state_machine.goto_line(abs_line_offset) - except IndexError: + except EOFError: pass + def no_match(self, context, transitions): + """ + Override `StateWS.no_match` to generate a system message. + + This code should never be run. + """ + self.reporter.severe( + 'Internal error: no transition pattern match. State: "%s"; ' + 'transitions: %s; context: %s; current line: %r.' + % (self.__class__.__name__, transitions, context, + self.state_machine.line), + line=self.state_machine.abs_line_number()) + return context, None, [] + def bof(self, context): """Called at beginning of file.""" return [], [] @@ -950,7 +964,7 @@ class Body(RSTState): 'simple_table_top': simple_table_top_pat, 'explicit_markup': r'\.\.( +|$)', 'anonymous': r'__( +|$)', - 'line': r'(%(nonalphanum7bit)s)\1\1\1+ *$' % pats, + 'line': r'(%(nonalphanum7bit)s)\1* *$' % pats, 'text': r''} initial_transitions = ( 'bullet', @@ -1099,7 +1113,7 @@ class Body(RSTState): return None try: next_line = self.state_machine.next_line() - except IndexError: # end of input lines + except EOFError: # end of input lines self.state_machine.previous_line() return 1 else: @@ -1830,6 +1844,13 @@ class Body(RSTState): """Section title overline or transition marker.""" if self.state_machine.match_titles: return [match.string], 'Line', [] + 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.", '', + line=self.state_machine.abs_line_number()) + self.parent += msg + raise statemachine.TransitionCorrection('text') else: blocktext = self.state_machine.line msg = self.reporter.severe( @@ -2127,11 +2148,19 @@ class Text(RSTState): source = title + '\n' + underline messages = [] if len(title) > len(underline): - blocktext = context[0] + '\n' + self.state_machine.line - msg = self.reporter.warning( - 'Title underline too short.', '', - nodes.literal_block(blocktext, blocktext), line=lineno) - messages.append(msg) + 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.", '', + 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.', '', + nodes.literal_block(blocktext, blocktext), line=lineno) + messages.append(msg) style = underline[0] context[:] = [] self.section(title, source, style, lineno - 1, messages) @@ -2153,7 +2182,7 @@ class Text(RSTState): if literalnext: try: self.state_machine.next_line() - except IndexError: + except EOFError: pass self.parent += self.literal_block() return [], next_state, [] @@ -2260,6 +2289,9 @@ class Line(SpecializedText): def eof(self, context): """Transition marker at end of section or document.""" + marker = context[0].strip() + if len(marker) < 4: + self.state_correction(context) if self.eofcheck: # ignore EOFError with sections transition = nodes.transition(context[0]) self.parent += transition @@ -2272,7 +2304,10 @@ class Line(SpecializedText): def blank(self, match, context, next_state): """Transition marker.""" - transition = nodes.transition(context[0]) + marker = context[0].strip() + if len(marker) < 4: + self.state_correction(context) + transition = nodes.transition(marker) if len(self.parent) == 0: msg = self.reporter.error( 'Document or section may not begin with a transition.', @@ -2295,35 +2330,50 @@ class Line(SpecializedText): underline = '' try: underline = self.state_machine.next_line() - except IndexError: + except EOFError: blocktext = overline + '\n' + title - msg = self.reporter.severe( - 'Incomplete section title.', '', - nodes.literal_block(blocktext, blocktext), line=lineno) - self.parent += msg - return [], 'Body', [] + if len(overline.rstrip()) < 4: + self.short_overline(context, blocktext, lineno, 2) + else: + msg = self.reporter.severe( + 'Incomplete section title.', '', + nodes.literal_block(blocktext, blocktext), line=lineno) + 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.reporter.severe( - 'Missing underline for overline.', '', - nodes.literal_block(source, source), line=lineno) - self.parent += msg - return [], 'Body', [] + blocktext = overline + '\n' + title + '\n' + underline + if len(overline.rstrip()) < 4: + self.short_overline(context, blocktext, lineno, 2) + else: + msg = self.reporter.severe( + 'Missing underline for overline.', '', + nodes.literal_block(source, source), line=lineno) + self.parent += msg + return [], 'Body', [] elif overline != underline: - msg = self.reporter.severe( - 'Title overline & underline mismatch.', '', - nodes.literal_block(source, source), line=lineno) - self.parent += msg - return [], 'Body', [] + blocktext = overline + '\n' + title + '\n' + underline + if len(overline.rstrip()) < 4: + self.short_overline(context, blocktext, lineno, 2) + else: + msg = self.reporter.severe( + 'Title overline & underline mismatch.', '', + nodes.literal_block(source, source), line=lineno) + self.parent += msg + return [], 'Body', [] title = title.rstrip() messages = [] if len(title) > len(overline): - msg = self.reporter.warning( - 'Title overline too short.', '', - nodes.literal_block(source, source), line=lineno) - messages.append(msg) + blocktext = overline + '\n' + title + '\n' + underline + if len(overline.rstrip()) < 4: + self.short_overline(context, blocktext, lineno, 2) + else: + msg = self.reporter.warning( + 'Title overline too short.', '', + nodes.literal_block(source, source), line=lineno) + messages.append(msg) style = (overline[0], underline[0]) self.eofcheck = 0 # @@@ not sure this is correct self.section(title.lstrip(), source, style, lineno + 1, messages) @@ -2332,15 +2382,30 @@ class Line(SpecializedText): indent = text # indented title - def underline(self, match=None, context=None, next_state=None): - blocktext = context[0] + '\n' + self.state_machine.line + def underline(self, match, context, next_state): + overline = context[0] + blocktext = overline + '\n' + self.state_machine.line + lineno = self.state_machine.abs_line_number() - 1 + if len(overline.rstrip()) < 4: + self.short_overline(context, blocktext, lineno, 1) msg = self.reporter.error( 'Invalid section title or transition marker.', '', - nodes.literal_block(blocktext, blocktext), - line=self.state_machine.abs_line_number() - 1) + nodes.literal_block(blocktext, blocktext), line=lineno) self.parent += msg return [], 'Body', [] + 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) + self.parent += msg + self.state_correction(context, lines) + + def state_correction(self, context, lines=1): + self.state_machine.previous_line(lines) + context[:] = [] + raise statemachine.StateCorrection('Body', 'text') + state_classes = (Body, BulletList, DefinitionList, EnumeratedList, FieldList, OptionList, Explicit, Text, Definition, Line, -- cgit v1.2.1 From ca21c540669d234443c007298437b7fc60ebc678 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 19 Sep 2002 00:42:39 +0000 Subject: Fixed a bug that was producing unwanted empty rows in "simple" tables. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@690 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/tableparser.py | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/tableparser.py b/docutils/parsers/rst/tableparser.py index d304445c8..3ef7e7d68 100644 --- a/docutils/parsers/rst/tableparser.py +++ b/docutils/parsers/rst/tableparser.py @@ -1,10 +1,10 @@ -""" -: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 module defines table parser classes,which parse plaintext-graphic tables and produce a well-formed data structure suitable for building a CALS table. @@ -401,16 +401,16 @@ class SimpleTableParser(TableParser): offset += 1 if self.span_pat.match(line): # Column span underline or border; row is complete. - self.parse_row(rowlines, line) + self.parse_row(rowlines, (line.rstrip(), offset)) 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)] + rowlines = [(line.rstrip(), offset)] else: # Accumulate lines of incomplete row. - rowlines.append((line, offset)) + rowlines.append((line.rstrip(), offset)) def parse_columns(self, line): """ @@ -458,10 +458,19 @@ class SimpleTableParser(TableParser): adjust for insigificant whitespace. """ if spanline: - columns = self.parse_columns(spanline) + columns = self.parse_columns(spanline[0]) else: columns = self.columns[:] - row = self.init_row(columns, lines[0][1]) + while lines and not lines[-1][0]: + lines.pop() # Remove blank trailing lines. + if lines: + offset = lines[0][1] + elif spanline: + offset = spanline[1] + else: + # No new row, just blank lines. + return + row = self.init_row(columns, offset) # "Infinite" value for a dummy last column's beginning, used to # check for text overflow: columns.append((sys.maxint, None)) -- cgit v1.2.1 From 3a83bc523b7d1164ae1c349f395eec2dc0e909a6 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 19 Sep 2002 00:44:29 +0000 Subject: - 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. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@691 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/statemachine.py | 327 ++++++++++++++++++++++++----------------------- 1 file changed, 169 insertions(+), 158 deletions(-) (limited to 'docutils') diff --git a/docutils/statemachine.py b/docutils/statemachine.py index b8496d3e0..ba1b98f2e 100644 --- a/docutils/statemachine.py +++ b/docutils/statemachine.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. - A finite state machine specialized for regular-expression-based text filters, this module defines the following classes: @@ -19,6 +17,7 @@ this module defines the following classes: Exception classes: +- `StateMachineError` - `UnknownStateError` - `DuplicateStateError` - `UnknownTransitionError` @@ -27,6 +26,7 @@ Exception classes: - `TransitionMethodNotFound` - `UnexpectedIndentationError` - `TransitionCorrection`: Raised to switch to another transition. +- `StateCorrection`: Raised to switch to another state & transition. Functions: @@ -76,8 +76,9 @@ How To Use This Module If you are using `StateWS` as a base class, in order to handle nested indented blocks, you may wish to: - - override the attributes `StateWS.indent_sm`, `StateWS.indent_sm_kwargs`, - `StateWS.known_indent_sm`, and/or `StateWS.known_indent_sm_kwargs`; + - 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.known_indent()`, and/or `StateWS.firstknown_indent()` methods. @@ -143,7 +144,7 @@ class StateMachine: self.line = None """Current input line.""" - self.line_offset = None + self.line_offset = -1 """Current input line offset from beginning of `self.input_lines`.""" self.debug = debug @@ -194,6 +195,7 @@ class StateMachine: print >>sys.stderr, ('\nStateMachine.run: input_lines:\n| %s' % '\n| '.join(self.input_lines)) context = None + transitions = None results = [] state = self.get_state() try: @@ -203,23 +205,47 @@ class StateMachine: results.extend(result) while 1: try: - self.next_line() + try: + self.next_line() + if self.debug: + print >>sys.stderr, ('\nStateMachine.run: line:\n' + '| %s' % self.line) + context, next_state, result = self.check_line( + context, state, transitions) + except EOFError: + if self.debug: + print >>sys.stderr, ( + '\nStateMachine.run: %s.eof transition' + % state.__class__.__name__) + result = state.eof(context) + results.extend(result) + break + else: + results.extend(result) + except TransitionCorrection, exception: + self.previous_line() # back up for another try + transitions = (exception.args[0],) if self.debug: - print >>sys.stderr, ('\nStateMachine.run: line:\n| %s' - % self.line) - except IndexError: - break - try: - context, next_state, result = self.check_line(context, - state) - except EOFError: - break + print >>sys.stderr, ( + '\nStateMachine.run: TransitionCorrection to ' + 'state "%s", transition %s.' + % (state.__class__.__name, transitions[0])) + continue + except StateCorrection, exception: + self.previous_line() # back up for another try + next_state = exception.args[0] + if len(exception.args) == 1: + transitions = None + else: + transitions = (exception.args[1],) + if self.debug: + print >>sys.stderr, ( + '\nStateMachine.run: StateCorrection to state ' + '"%s", transition %s.' + % (next_state, transitions[0])) + else: + transitions = None state = self.get_state(next_state) - results.extend(result) - if self.debug: - print >>sys.stderr, ('\nStateMachine.run: eof transition') - result = state.eof(context) - results.extend(result) except: self.error() raise @@ -249,7 +275,11 @@ class StateMachine: def next_line(self, n=1): """Load `self.line` with the `n`'th next line and return it.""" self.line_offset += n - self.line = self.input_lines[self.line_offset] + try: + self.line = self.input_lines[self.line_offset] + except IndexError: + self.line = None + raise EOFError return self.line def is_next_line_blank(self): @@ -270,13 +300,20 @@ class StateMachine: def previous_line(self, n=1): """Load `self.line` with the `n`'th previous line and return it.""" self.line_offset -= n - self.line = self.input_lines[self.line_offset] + if self.line_offset < 0: + self.line = None + else: + self.line = self.input_lines[self.line_offset] 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 - self.line = self.input_lines[self.line_offset] + try: + self.line = self.input_lines[self.line_offset] + except IndexError: + self.line = None + raise EOFError return self.line def abs_line_offset(self): @@ -307,71 +344,49 @@ class StateMachine: self.next_line(len(block) - 1) # advance to last line of block return block - def check_line(self, context, state): + def check_line(self, context, state, transitions=None): """ - Examine one line of input for a transition match. + Examine one line of input for a transition match & execute its method. Parameters: - `context`: application-dependent storage. - `state`: a `State` object, the current state. + - `transitions`: an optional ordered list of transition names to try, + instead of ``state.transition_order``. 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; + - next state name (`State` subclass name); - the result output of the transition, a list. - """ - if self.debug: - print >>sys.stdout, ('\nStateMachine.check_line: ' - 'context "%s", state "%s"' % - (context, state.__class__.__name__)) - context, next_state, result = self.match_transition(context, state) - return context, next_state, result - - def match_transition(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). + When there is no match, ``state.no_match()`` is called and its return + value is returned. """ + if transitions is None: + transitions = state.transition_order + state_correction = None if self.debug: print >>sys.stderr, ( - '\nStateMachine.match_transition: state="%s", transitions=' - '%r.' % (state.__class__.__name__, state.transition_order)) - for name in state.transition_order: - while 1: - pattern, method, next_state = state.transitions[name] + '\nStateMachine.check_line: state="%s", transitions=%r.' + % (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: print >>sys.stderr, ( - '\nStateMachine.match_transition: Trying ' - 'transition "%s" in state "%s".' + '\nStateMachine.check_line: Matched transition ' + '"%s" in state "%s".' % (name, state.__class__.__name__)) - match = self.match(pattern) - if match: - if self.debug: - print >>sys.stderr, ( - '\nStateMachine.match_transition: Matched ' - 'transition "%s" in state "%s".' - % (name, state.__class__.__name__)) - try: - return method(match, context, next_state) - except TransitionCorrection, detail: - name = str(detail) - continue # try again with new transition name - break + return method(match, context, next_state) else: - return context, None, [] # no match + return state.no_match(context, transitions) def match(self, pattern): """ @@ -515,10 +530,7 @@ class State: or other classes. """ - if self.initial_transitions: - names, transitions = self.make_transitions( - self.initial_transitions) - self.add_transitions(names, transitions) + self.add_initial_transitions() self.state_machine = state_machine """A reference to the controlling `StateMachine` object.""" @@ -543,6 +555,13 @@ class State: """Remove circular references to objects no longer required.""" self.state_machine = None + def add_initial_transitions(self): + """Make and add transitions listed in `self.initial_transitions`.""" + if self.initial_transitions: + names, transitions = self.make_transitions( + self.initial_transitions) + self.add_transitions(names, transitions) + def add_transitions(self, names, transitions): """ Add a list of transitions to the start of the transition list. @@ -624,9 +643,9 @@ class State: """ Return a list of transition names and a transition mapping. - 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). + 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 = [] @@ -640,6 +659,20 @@ class State: names.append(namestate[0]) return names, transitions + def no_match(self, context, transitions): + """ + Called when there is no match from `StateMachine.check_line()`. + + Return the same values returned by transition methods: + + - context: unchanged; + - next state name: ``None``; + - empty result list. + + Override in subclasses to catch this event. + """ + return context, None, [] + def bof(self, context): """ Handle beginning-of-file. Return unchanged `context`, empty result. @@ -675,73 +708,14 @@ 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: - + There are three methods provided for extracting indented text blocks: + - `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 check_line(self, context, state): - """ - Examine one line of input for whitespace first, then transitions. - - Extends `StateMachine.check_line()`. - """ - if self.debug: - print >>sys.stdout, ('\nStateMachineWS.check_line: ' - 'context "%s", state "%s"' % - (context, state.__class__.__name__)) - 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, next_state, result - - 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. - - 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.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.check_whitespace: ' - 'implicit transition "blank" matched') - return state.blank(match, context, self.current_state) - elif indent: - if self.debug: - print >>sys.stdout, ('\nStateMachineWS.check_whitespace: ' - 'implicit transition "indent" matched') - return state.indent(match, context, self.current_state) - else: - return context, '', [] # neither blank line nor indented - def get_indented(self, until_blank=0, strip_indent=1): """ Return a block of indented lines of text, and info. @@ -850,17 +824,18 @@ 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 `indent_sm`, - and the constructor keyword arguments are in the dictionary - `indent_sm_kwargs`. + Use this class with `StateMachineWS`. The transitions 'blank' (for blank + lines) and 'indent' (for indented text blocks) are added automatically, + before any other transitions. 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 `indent_sm`, and the + constructor keyword arguments are in the dictionary `indent_sm_kwargs`. 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 - `known_indent_sm` and `known_indent_sm_kwargs`. Neither transition method + `known_indent_sm` and `known_indent_sm_kwargs`. Neither transition method is triggered automatically. """ @@ -896,6 +871,15 @@ class StateWS(State): `indent_sm_kwargs`. Override it in subclasses to avoid the default. """ + ws_patterns = {'blank': ' *$', + 'indent': ' +'} + """Patterns for default whitespace transitions. May be overridden in + subclasses.""" + + ws_initial_transitions = ('blank', 'indent') + """Default initial whitespace transitions, added before those listed in + `State.initial_transitions`. May be overridden in subclasses.""" + def __init__(self, state_machine, debug=0): """ Initialize a `StateSM` object; extends `State.__init__()`. @@ -912,6 +896,20 @@ class StateWS(State): if self.known_indent_sm_kwargs is None: self.known_indent_sm_kwargs = self.indent_sm_kwargs + def add_initial_transitions(self): + """ + Add whitespace-specific transitions before those defined in subclass. + + Extends `State.add_initial_transitions()`. + """ + State.add_initial_transitions(self) + if self.patterns is None: + self.patterns = {} + self.patterns.update(self.ws_patterns) + names, transitions = self.make_transitions( + self.ws_initial_transitions) + self.add_transitions(names, transitions) + def blank(self, match, context, next_state): """Handle blank lines. Does nothing. Override in subclasses.""" return self.nop(match, context, next_state) @@ -934,8 +932,8 @@ class StateWS(State): Handle a known-indent text block. Extend or override in subclasses. Recursively run the registered state machine for known-indent indented - blocks (`self.known_indent_sm`). 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, line_offset, blank_finish = \ self.state_machine.get_known_indented(match.end()) @@ -995,19 +993,32 @@ class SearchStateMachineWS(_SearchOverride, StateMachineWS): 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 StateMachineError(Exception): pass +class UnknownStateError(StateMachineError): pass +class DuplicateStateError(StateMachineError): pass +class UnknownTransitionError(StateMachineError): pass +class DuplicateTransitionError(StateMachineError): pass +class TransitionPatternNotFound(StateMachineError): pass +class TransitionMethodNotFound(StateMachineError): pass +class UnexpectedIndentationError(StateMachineError): pass class TransitionCorrection(Exception): """ Raise from within a transition method to switch to another transition. + + Raise with one argument, the new transition name. + """ + + +class StateCorrection(Exception): + + """ + Raise from within a transition method to switch to another state. + + Raise with one or two arguments: new state name, and an optional new + transition name. """ -- cgit v1.2.1 From 9ac643158b26bf30d7493eac1e6a1acd6345914f Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 19 Sep 2002 00:46:05 +0000 Subject: Improved field list rendering. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@692 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 31454c4db..ff020d85c 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.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. - Simple HyperText Markup Language document tree Writer. The output conforms to the HTML 4.01 Transitional DTD and to the Extensible @@ -468,7 +466,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): @@ -572,14 +570,21 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('\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')) -- 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 --- docutils/parsers/rst/directives/misc.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'docutils') 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: -- cgit v1.2.1 From c42533ff80a5543fb3a207c102cf8655b9cb6ffc Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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'(? 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(+) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 1aa202a450e403c6451909598132d1bf4a2cb162 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 = '\n' + #xml_stylesheet = '\n' + doctype = ( + '\n') + generator = '\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 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 +++++++------- 2 files changed, 12 insertions(+), 11 deletions(-) (limited to 'docutils') 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 = '\n\n' content_type = '\n' - generator = '\n' + 'charset=%s" />\n' + generator = '\n' stylesheet_link = '\n' embedded_stylesheet = '\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 -- 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(-) (limited to 'docutils') 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 6e26d36491f9f2c7ac4790d64ccf28d9a3de92b7 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 ed28012e60a40b2a0774a987d0d25240e2f592a8 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 45d96016aabd12df32ac212fc5c5136d2b1f0dbb Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 58036bb54a184a823272be8ddf5f52c619d4f83c Mon Sep 17 00:00:00 2001 From: goodger 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 --- 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 +++++++++++++++++++----------------- 6 files changed, 59 insertions(+), 57 deletions(-) (limited to 'docutils') 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) -- cgit v1.2.1 From 8016246d7ce753e06932376eaed76ab26e6eeb22 Mon Sep 17 00:00:00 2001 From: goodger 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 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'docutils') 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 = '\n' - doctype = '\n' + doctype = ('\n') html_head = '\n\n' - content_type = '\n' - generator = '\n' + content_type = ('\n') + generator = ('\n') stylesheet_link = '\n' embedded_stylesheet = '\n' named_tags = {'a': 1, 'applet': 1, 'form': 1, 'frame': 1, 'iframe': 1, -- cgit v1.2.1 From efdd39867964b92520a58c6796658895e412c441 Mon Sep 17 00:00:00 2001 From: goodger 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 +++++------- 17 files changed, 88 insertions(+), 119 deletions(-) (limited to 'docutils') 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. """ -- cgit v1.2.1 From 0aae6532d69456b387c15261eba7e2f8e1adf146 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 = ['\n\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('
    \n') -- 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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 --- docutils/parsers/rst/__init__.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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 (limited to 'docutils') 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 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'docutils') 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') -- 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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 --- docutils/parsers/rst/languages/en.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docutils') 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', -- 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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 a47fca125f6ebfaefa64347df50173d08f5b7f0c Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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 --- 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 +++++++-------- 18 files changed, 199 insertions(+), 179 deletions(-) (limited to 'docutils') 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] [ []]' default_description = ('Reads from (default is stdin) and writes to ' ' (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': ''}), - ('Read configuration options from , if it exists.', + ('Read configuration settings from , if it exists.', ['--config'], {'metavar': '', '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): biohazard """ - 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 = '\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 = '\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) -- cgit v1.2.1 From 18c39f24ba6a4c6d170d750b2d8476d8e896adf1 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 (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 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(-) (limited to 'docutils') 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 = '' 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 = '' 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 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(-) (limited to 'docutils') 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 Date: Fri, 18 Oct 2002 23:45:29 +0000 Subject: Improved layout of
     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(-)
    
    (limited to 'docutils')
    
    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('
    \n') + self.body.append('\n\n') self.depart_docinfo_item() def visit_admonition(self, node, name): @@ -485,11 +484,10 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('\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('\n') + self.body.append('\n\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('\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('\n') + self.body.append('\n\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('\n') + self.body.append('\n\n') def visit_meta(self, node): self.head.append(self.starttag(node, 'meta', **node.attributes)) -- cgit v1.2.1 From 17c3ca36527dee68dfbe7076fb54866ff2b2be51 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 22 Oct 2002 01:02:55 +0000 Subject: Fixed attribute typo in . 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(-) (limited to 'docutils') 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 45517c8b55bcc6a6723576bfb620772ab471601a Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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('\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('\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('') + # 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('') 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('

    ') -- cgit v1.2.1 From 99fbfbba88293ef1c07f4b96cc0cf9a75dc28849 Mon Sep 17 00:00:00 2001 From: goodger 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 --- docutils/frontend.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(+) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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:: + 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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:: + + + + + + - - internal - - external - - + I'm known as "d". + + + - Corresponding references are linked via "refid" or resolved via - "refuri":: + ``ChainedTargetResolver(document).walk()`` will transform the above into:: + + + + + - - text - - external - - - """ + I'm known as "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:: + + + + internal + + external + + + + Corresponding references are linked via "refid" or resolved via "refuri":: + + + + text + + 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:: - - - - indirect 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):: - - - - indirect external - - - - Once the attribute is migrated, the preexisting "refname" attribute - is dropped. - - b) Indirect internal references:: - - - - - indirect internal - - - - 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:: - - - - - indirect internal - - - """ + +class IndirectHyperlinks(Transform): + + """ + a) Indirect external references:: + + + + indirect 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):: + + + + indirect external + + + + Once the attribute is migrated, the preexisting "refname" attribute + is dropped. + + b) Indirect internal references:: + + + + + indirect internal + + + + 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:: + + + + + indirect internal + + + """ + + 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:: - - - direct external - +class ExternalTargets(Transform): + + """ + Given:: - The "refname" attribute is replaced by the direct "refuri" attribute:: + + + direct external + - - - direct external - - """ + The "refname" attribute is replaced by the direct "refuri" attribute:: + + + + direct external + + """ + + 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:: - - - direct internal - +class InternalTargets(Transform): + + """ + Given:: - The "refname" attribute is replaced by "refid" linking to the target's - "id":: + + + direct internal + - - - direct internal - - """ + The "refname" attribute is replaced by "refid" linking to the target's + "id":: + + + + 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:: - - - - - - - - I'm known as "d". - - - - - ``ChainedTargetResolver(document).walk()`` will transform the above into:: - - - - - - - - I'm known as "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): biohazard """ + 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 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(-) (limited to 'docutils') 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 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 ++++-- 5 files changed, 113 insertions(+), 61 deletions(-) (limited to 'docutils') 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) -- cgit v1.2.1 From a714d9a65946eaec2c775e27e24159ce65ce10a1 Mon Sep 17 00:00:00 2001 From: goodger 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 --- 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 +- 5 files changed, 15 insertions(+), 8 deletions(-) (limited to 'docutils') 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 -- cgit v1.2.1 From 35a1beda765cd44715a9ea7c4064d71b1abbcf1e Mon Sep 17 00:00:00 2001 From: goodger 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 --- docutils/core.py | 4 ++-- docutils/transforms/peps.py | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'docutils') 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) -- cgit v1.2.1 From b35f28af244723b3fe955654857fcfb58e07d49b Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 b4f387efe3f819802be5bdbcecc3e420f244a0b2 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 cd4490bf85dd03ebe0e60f6cdd55d779cf111ffd Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 bbff5bae14890845feab785b384f2893ffcd18f9 Mon Sep 17 00:00:00 2001 From: grubert 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 (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(+) (limited to 'docutils') 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 3ac51a6c7a0d119945d87d3634d6fca261562a8e Mon Sep 17 00:00:00 2001 From: goodger 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(+) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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 (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 47e460c659b1e295d43604762eff2e9147d7df6c Mon Sep 17 00:00:00 2001 From: goodger 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 --- docutils/parsers/rst/tableparser.py | 4 ++-- docutils/utils.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'docutils') 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): -- 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 --- docutils/parsers/rst/directives/__init__.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'docutils') 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 d28804c48f1c32b5192a6c16e991d3cc3a8bcfb6 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 13 Nov 2002 01:20:10 +0000 Subject: Refined XML prologue. Support for no stylesheet. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@941 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 851df03e3..057fb5024 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -134,12 +134,13 @@ class HTMLTranslator(nodes.NodeVisitor): option) disables list whitespace optimization. """ - xml_declaration = '\n' + xml_declaration = '\n' doctype = ('\n') - html_head = '\n\n' + html_head = ('\n\n') content_type = ('\n') generator = (' Date: Thu, 14 Nov 2002 02:25:38 +0000 Subject: Return ``None`` for missing language modules. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@948 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/__init__.py b/docutils/parsers/rst/languages/__init__.py index 8f78fc481..86bfd03ba 100644 --- a/docutils/parsers/rst/languages/__init__.py +++ b/docutils/parsers/rst/languages/__init__.py @@ -16,6 +16,9 @@ _languages = {} def get_language(language_code): if _languages.has_key(language_code): return _languages[language_code] - module = __import__(language_code, globals(), locals()) + try: + module = __import__(language_code, globals(), locals()) + except ImportError: + return None _languages[language_code] = module return module -- cgit v1.2.1 From 77f2ee4872ec99a61ca1756c2dad1be556877a3a Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 14 Nov 2002 02:31:34 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@949 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/sv.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/sv.py b/docutils/parsers/rst/languages/sv.py index b68040cf3..36a576343 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -21,19 +21,18 @@ directives = { u'notera': 'note', u'tips': 'tip', u'varning': 'warning', - u'fr\u00e5gor': 'questions', + # u'fr\u00e5gor': 'questions', # 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'fr\u00e5gor-och-svar': 'questions', + # u'vanliga-fr\u00e5gor': 'questions', u'meta': 'meta', # u'bildkarta': 'imagemap', # FIXME: Translation might be too literal. u'bild': 'image', u'figur': 'figure', - # u'r\u00e5': 'raw', # FIXME: Translation might be too literal. + 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' } + u'\u00e4mne': 'topic'} """Swedish name to registered (in directives/__init__.py) directive name mapping.""" -- cgit v1.2.1 From c5ce75c3c1fb6a65e9f61b968238a7cbc79e2d35 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 14 Nov 2002 02:43:49 +0000 Subject: Slovak mappings, by Miroslav Vasko. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@950 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/sk.py | 45 ++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 docutils/parsers/rst/languages/sk.py (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/sk.py b/docutils/parsers/rst/languages/sk.py new file mode 100644 index 000000000..e23bc3988 --- /dev/null +++ b/docutils/parsers/rst/languages/sk.py @@ -0,0 +1,45 @@ +# 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 +reStructuredText. +""" + +__docformat__ = 'reStructuredText' + + +directives = { + u'pozor': 'attention', + u'opatrne': 'caution', + u'nebezpe\xe8enstvo': 'danger', + u'chyba': 'error', + u'rada': 'hint', + u'd\xf4le\x9eit\xe9': 'important', + u'pozn\xe1mka': 'note', + u'tip': 'tip', + u'varovanie': 'warning', + u't\xe9ma': 'topic', + u'blok-riadkov': 'line-block', + u'parsed-literal': 'parsed-literal', + #u'questions': 'questions', + #u'qa': 'questions', + #u'faq': 'questions', + u'meta': 'meta', + #u'imagemap': 'imagemap', + u'obr\xe1zok': 'image', + u'tvar': 'figure', + u'vlo\x9ei\x9d': 'include', + u'raw': 'raw', + u'nahradi\x9d': 'replace', + u'obsah': 'contents', + u'\xe8as\x9d': 'sectnum', + u'\xe8as\x9d-\xe8\xedslovanie': 'sectnum', + u'cie\xbeov\xe9-pozn\xe1mky': 'target-notes', + #u'footnotes': 'footnotes', + #u'citations': 'citations',} +"""Slovak name to registered (in directives/__init__.py) directive name +mapping.""" -- cgit v1.2.1 From dcd1c7643fe745cbd8dd0637bef9390c390d584b Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 14 Nov 2002 02:51:50 +0000 Subject: typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@952 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/sk.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/sk.py b/docutils/parsers/rst/languages/sk.py index e23bc3988..e88fda694 100644 --- a/docutils/parsers/rst/languages/sk.py +++ b/docutils/parsers/rst/languages/sk.py @@ -40,6 +40,7 @@ directives = { u'\xe8as\x9d-\xe8\xedslovanie': 'sectnum', u'cie\xbeov\xe9-pozn\xe1mky': 'target-notes', #u'footnotes': 'footnotes', - #u'citations': 'citations',} + #u'citations': 'citations', + } """Slovak name to registered (in directives/__init__.py) directive name mapping.""" -- cgit v1.2.1 From 3d389e7cded3fe068f30fab1546e87ff6e79ccc9 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 16 Nov 2002 02:27:00 +0000 Subject: Enabled recognition of schemeless email addresses in targets. Added support for embedded URIs in hyperlink references. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@954 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 84 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 16 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 9c4eeafab..3f49a9954 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -534,9 +534,17 @@ class Inliner: non_whitespace_after = r'(?![ \n])' # Alphanumerics with isolated internal [-._] chars (i.e. not 2 together): simplename = r'(?:(?!_)\w)+(?:[-._](?:(?!_)\w)+)*' + # Valid URI characters (see RFC 2396 & RFC 2732): uric = r"""[-_.!~*'()[\];/:@&=+$,%a-zA-Z0-9]""" - urilast = r"""[_~/\]a-zA-Z0-9]""" # no punctuation + # Last URI character; same as uric but no punctuation: + urilast = r"""[_~/a-zA-Z0-9]""" emailc = r"""[-_!~*'{|}/#?^`&=+$%a-zA-Z0-9]""" + email_pattern = r""" + %(emailc)s+(?:\.%(emailc)s+)* # name + @ # at + %(emailc)s+(?:\.%(emailc)s*)* # host + %(urilast)s # final URI char + """ parts = ('initial_inline', start_string_prefix, '', [('start', '', non_whitespace_after, # simple start-strings [r'\*\*', # strong @@ -581,6 +589,18 @@ class Inliner: ) %(end_string_suffix)s """ % locals(), re.VERBOSE | re.UNICODE), + embedded_uri=re.compile( + r""" + ( + [ \n]+ # spaces or beginning of line + < # open bracket + %(non_whitespace_after)s + ([^<>\0]+) # anything but angle brackets & nulls + %(non_whitespace_before)s + > # close bracket w/o whitespace before + ) + $ # end of string + """ % locals(), re.VERBOSE), literal=re.compile(non_whitespace_before + '(``)' + end_string_suffix), target=re.compile(non_whitespace_escape_before @@ -588,8 +608,9 @@ class Inliner: substitution_ref=re.compile(non_whitespace_escape_before + r'(\|_{0,2})' + end_string_suffix), + email=re.compile(email_pattern % locals() + '$', re.VERBOSE), uri=re.compile( - r""" + (r""" %(start_string_prefix)s (?P (?P # absolute URI @@ -615,14 +636,11 @@ class Inliner: ) | # *OR* (?P # email address - %(emailc)s+(\.%(emailc)s+)* # name - @ # at - %(emailc)s+(\.%(emailc)s*)* # host - %(urilast)s # final URI char + """ + email_pattern + r""" ) ) %(end_string_suffix)s - """ % locals(), re.VERBOSE), + """) % locals(), re.VERBOSE), pep=re.compile( r""" %(start_string_prefix)s @@ -736,7 +754,7 @@ class Inliner: prb = self.problematic(text, text, msg) return string[:rolestart], [prb], string[textend:], [msg] return self.phrase_ref(string[:matchstart], string[textend:], - rawsource, text) + rawsource, escaped, text) else: return self.interpreted(string[:rolestart], string[textend:], rawsource, text, role, position) @@ -747,16 +765,46 @@ class Inliner: prb = self.problematic(text, text, msg) return string[:matchstart], [prb], string[matchend:], [msg] - def phrase_ref(self, before, after, rawsource, text): + def phrase_ref(self, before, after, rawsource, escaped, text): + match = self.patterns.embedded_uri.search(escaped) + if match: + text = unescape(escaped[:match.start(0)]) + uri_text = match.group(2) + uri = ''.join(uri_text.split()) + uri = self.adjust_uri(uri) + if uri: + target = nodes.target(match.group(1), refuri=uri) + else: + raise ApplicationError('problem with URI: %r' % uri_text) + else: + target = None refname = normalize_name(text) reference = nodes.reference(rawsource, text) + node_list = [reference] if rawsource[-2:] == '__': - reference['anonymous'] = 1 - self.document.note_anonymous_ref(reference) + if target: + reference['refuri'] = uri + else: + reference['anonymous'] = 1 + self.document.note_anonymous_ref(reference) else: - reference['refname'] = refname - self.document.note_refname(reference) - return before, [reference], after, [] + if target: + reference['refuri'] = uri + target['name'] = refname + self.document.note_external_target(target) + self.document.note_explicit_target(target, self.parent) + node_list.append(target) + else: + reference['refname'] = refname + self.document.note_refname(reference) + return before, node_list, after, [] + + def adjust_uri(self, uri): + match = self.patterns.email.match(uri) + if match: + return 'mailto:' + uri + else: + return uri def interpreted(self, before, after, rawsource, text, role, position): if role: @@ -1639,8 +1687,12 @@ class Body(RSTState): name = normalize_name(unescape(targetname)) target['name'] = name if refuri: - target['refuri'] = refuri - self.document.note_external_target(target) + 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) -- cgit v1.2.1 From 67dfd81313b6286fc27502a78353ef445737e8a5 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 16 Nov 2002 02:27:32 +0000 Subject: Fixed TargetNotes transform. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@955 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/peps.py | 1 + 1 file changed, 1 insertion(+) (limited to 'docutils') diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index fe82175b8..67277a9cc 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -170,6 +170,7 @@ class TargetNotes(Transform): if not refsect: refsect = nodes.section() refsect += nodes.title('', 'References') + doc.set_id(refsect) if copyright: # Put the new "References" section before "Copyright": doc.insert(copyright, refsect) -- cgit v1.2.1 From 2a8ab9ccdf887cbc888e576a71616c29ee8dbd9e Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 19 Nov 2002 02:33:05 +0000 Subject: Removed unnecessary parameter from ``read()`` methods. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@964 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index de8af4582..b72935082 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -44,7 +44,7 @@ class Input(TransformSpec): return '%s: source=%r, source_path=%r' % (self.__class__, self.source, self.source_path) - def read(self, reader): + def read(self): raise NotImplementedError def decode(self, data): @@ -155,7 +155,7 @@ class FileInput(Input): except AttributeError: pass - def read(self, reader): + def read(self): """Read and decode a single file and return the data.""" data = self.source.read() if self.autoclose: @@ -226,7 +226,7 @@ class StringInput(Input): default_source_path = '' - def read(self, reader): + def read(self): """Decode and return the source string.""" return self.decode(self.source) @@ -253,7 +253,7 @@ class NullInput(Input): default_source_path = 'null input' - def read(self, reader): + def read(self): """Return a null string.""" return u'' -- cgit v1.2.1 From 872c2c52b9aac7313cdcb135cdd8da81fb256142 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 19 Nov 2002 02:34:42 +0000 Subject: Fixed "include" directive path manipulation & encoding bugs. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@965 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 3ff9eb93f..b9409aca8 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -11,15 +11,16 @@ __docformat__ = 'reStructuredText' import sys import os.path from urllib2 import urlopen, URLError -from docutils import nodes, statemachine, utils +from docutils import io, 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)) + source = state_machine.input_lines.source( + lineno - state_machine.input_offset - 1) + source_dir = os.path.dirname(os.path.abspath(source)) path = ''.join(arguments[0].splitlines()) if path.find(' ') != -1: error = state_machine.reporter.error( @@ -29,14 +30,13 @@ def include(name, arguments, options, content, lineno, path = os.path.normpath(os.path.join(source_dir, path)) path = utils.relative_path(None, path) try: - include_file = open(path) + include_file = io.FileInput(state.document.settings, source_path=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) -- cgit v1.2.1 From df0b272dc4cd35d6b1ab106ffd1285c7da2177ac Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 19 Nov 2002 02:37:08 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@966 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 1 - docutils/readers/__init__.py | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 3f49a9954..5ddcbb5bb 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1801,7 +1801,6 @@ class Body(RSTState): """ arguments = [] options = {} - content = [] argument_spec = getattr(directive_fn, 'arguments', None) if argument_spec and argument_spec[:2] == (0, 0): argument_spec = None diff --git a/docutils/readers/__init__.py b/docutils/readers/__init__.py index 70960b210..f12401ff0 100644 --- a/docutils/readers/__init__.py +++ b/docutils/readers/__init__.py @@ -61,8 +61,7 @@ class Reader(Component): if not self.parser: self.parser = parser self.settings = settings - # May modify self.parser, depending on input: - self.input = self.source.read(self) + self.input = self.source.read() self.parse() return self.document -- cgit v1.2.1 From 29b0b7275b12f306a4753590fb7012006745ad45 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 21 Nov 2002 02:23:46 +0000 Subject: expanded docstring git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@969 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/__init__.py | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/__init__.py b/docutils/parsers/rst/__init__.py index ad60a319d..b242ad9cb 100644 --- a/docutils/parsers/rst/__init__.py +++ b/docutils/parsers/rst/__init__.py @@ -8,15 +8,16 @@ This is ``docutils.parsers.rst`` package. It exports a single class, `Parser`, the reStructuredText parser. + Usage ===== 1. Create a parser:: - parser = docutils.parsers.restructuredtext.Parser() + parser = docutils.parsers.rst.Parser() Several optional arguments may be passed to modify the parser's behavior. - Please see `docutils.parsers.Parser` for details. + Please see `Customizing the Parser`_ below for details. 2. Gather input (a multi-line string), by reading a file or the standard input:: @@ -25,7 +26,7 @@ Usage 3. Create a new empty `docutils.nodes.document` tree:: - document = docutils.utils.new_document(source) + document = docutils.utils.new_document(source, settings) See `docutils.utils.new_document()` for parameter details. @@ -33,6 +34,7 @@ Usage parser.parse(input, document) + Parser Overview =============== @@ -40,6 +42,31 @@ 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. + + +Customizing the Parser +---------------------- + +Anything that isn't already customizable is that way simply because that type +of customizability hasn't been implemented yet. Patches welcome! + +When instantiating an object of the `Parser` class, two parameters may be +passed: ``rfc2822`` and ``inliner``. Pass ``rfc2822=1`` to enable an initial +RFC-2822 style header block, parsed as a "field_list" element (with "class" +attribute set to "rfc2822"). Currently this is the only body-level element +which is customizable without subclassing. (Tip: subclass `Parser` and change +its "state_classes" and "initial_state" attributes to refer to new classes. +Contact the author if you need more details.) + +The ``inliner`` parameter takes an instance of `states.Inliner` or a subclass. +It handles inline markup recognition. A common extension is the addition of +further implicit hyperlinks, like "RFC 2822". This can be done by subclassing +`states.Inliner`, adding a new method for the implicit markup, and adding a +``(pattern, method)`` pair to the "implicit_dispatch" attribute of the +subclass. See `states.Inliner.implicit_inline()` for details. Explicit +inline markup can be customized in a `states.Inliner` subclass via the +``patterns.initial`` and ``dispatch`` attributes (and new methods as +appropriate). """ __docformat__ = 'reStructuredText' -- cgit v1.2.1 From 81d959d8ec43bfb13eb65c8519803aff94f0fa8c Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 21 Nov 2002 02:25:53 +0000 Subject: Moved ``Inliner`` & made it a class attribute of ``Reader`` for easy subclassing. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@970 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/pep.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'docutils') diff --git a/docutils/readers/pep.py b/docutils/readers/pep.py index 38d09f8c7..7b75b94e8 100644 --- a/docutils/readers/pep.py +++ b/docutils/readers/pep.py @@ -20,6 +20,15 @@ from docutils.transforms import peps, references from docutils.parsers import rst +class Inliner(rst.states.Inliner): + + """ + Extend `rst.Inliner` to for local PEP references. + """ + + pep_url = rst.states.Inliner.pep_url_local + + class Reader(standalone.Reader): supported = ('pep',) @@ -44,17 +53,10 @@ class Reader(standalone.Reader): settings_default_overrides = {'pep_references': 1, 'rfc_references': 1} + inliner_class = Inliner + def __init__(self, parser=None, parser_name=None): """`parser` should be ``None``.""" if parser is None: - parser = rst.Parser(rfc2822=1, inliner=Inliner()) + parser = rst.Parser(rfc2822=1, inliner=self.inliner_class()) standalone.Reader.__init__(self, parser, '') - - -class Inliner(rst.states.Inliner): - - """ - Extend `rst.Inliner` to for local PEP references. - """ - - pep_url = rst.states.Inliner.pep_url_local -- cgit v1.2.1 From f5e7d4b1ce7cb79a5f2b987c9833d952a843bc41 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 21 Nov 2002 02:27:00 +0000 Subject: added docstring git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@971 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'docutils') diff --git a/docutils/utils.py b/docutils/utils.py index a216e114a..809511cba 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -373,6 +373,15 @@ def normalize_name(name): return ' '.join(name.lower().split()) def new_document(source, settings=None): + """ + Return a new empty document 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. + """ if settings is None: settings = frontend.OptionParser().get_default_values() reporter = Reporter(source, settings.report_level, settings.halt_level, -- cgit v1.2.1 From 4ea8903f17cf86452afef915296820e8c7d8225f Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 21 Nov 2002 02:31:16 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@973 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/peps.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index 67277a9cc..9df903e67 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -150,7 +150,8 @@ class TargetNotes(Transform): """ Locate the "References" section, insert a placeholder for an external - target footnote insertion transform at the end, and run the transform. + target footnote insertion transform at the end, and schedule the + transform to run immediately. """ default_priority = 520 -- cgit v1.2.1 From fe4f32cd84affa9cb4cef45cb96d50e899fa17fb Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 22 Nov 2002 04:33:02 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@978 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 057fb5024..f77fca758 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -125,10 +125,10 @@ class HTMLTranslator(nodes.NodeVisitor): 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. + - Regardless of the above, in definitions, table cells, field bodies, + option descriptions, and list items, mark the first child with + 'class="first"' and the last child with 'class="last"'. The stylesheet + sets the margins (top & bottom respecively) to 0 for these elements. The ``no_compact_lists`` setting (``--no-compact-lists`` command-line option) disables list whitespace optimization. -- cgit v1.2.1 From 61e1c94b8ec784fa597445dc16a0b9e49da23134 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 28 Nov 2002 03:30:19 +0000 Subject: Added "--no-doctype" and "--no-xml-declaration" options. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@979 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/docutils_xml.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/docutils_xml.py b/docutils/writers/docutils_xml.py index e5de9c48c..4ecbfb6c2 100644 --- a/docutils/writers/docutils_xml.py +++ b/docutils/writers/docutils_xml.py @@ -22,12 +22,18 @@ class Writer(writers.Writer): settings_spec = ( '"Docutils XML" Writer Options', - 'Warning: these options may adversely affect whitespace; use them ' - 'only for reading convenience.', + 'Warning: the --newlines and --indents 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'}),),) + ['--indents'], {'action': 'store_true'}), + ('Omit the XML declaration. Use with caution.', + ['--no-xml-declaration'], {'dest': 'xml_declaration', 'default': 1, + 'action': 'store_false'}), + ('Omit the DOCTYPE declaration.', + ['--no-doctype'], {'dest': 'doctype_declaration', 'default': 1, + 'action': 'store_false'}),)) output = None """Final translated form of `document`.""" @@ -48,9 +54,13 @@ class Writer(writers.Writer): if settings.indents: newline = '\n' indent = ' ' - output_prefix = [self.xml_declaration % settings.output_encoding, - self.doctype, - self.generator % docutils.__version__] + output_prefix = [] + if settings.xml_declaration: + output_prefix.append( + self.xml_declaration % settings.output_encoding) + if settings.doctype_declaration: + output_prefix.append(self.doctype) + output_prefix.append(self.generator % docutils.__version__) docnode = self.document.asdom().childNodes[0] self.output = (''.join(output_prefix) + docnode.toprettyxml(indent, newline)) -- cgit v1.2.1 From 849b081b357cc89d5af44ec49b48085de68d2e3e Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 28 Nov 2002 03:33:34 +0000 Subject: Deprecated reliance on runtime settings; pass encoding directly. "settings" parameters to be removed before next release. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@980 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 58 +++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 19 deletions(-) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index b72935082..ba624f1e7 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -26,10 +26,20 @@ class Input(TransformSpec): default_source_path = None - 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).""" + def __init__(self, settings=None, source=None, source_path=None, + encoding=None): + self.encoding = encoding + """The character encoding for the input source.""" + + if settings: + if not encoding: + self.encoding = settings.input_encoding + import warnings, traceback + warnings.warn( + 'Setting input encoding via a "settings" struct is ' + 'deprecated; send encoding directly instead.\n%s' + % ''.join(traceback.format_list(traceback.extract_stack() + [-3:-1]))) self.source = source """The source of input data.""" @@ -57,10 +67,9 @@ class Input(TransformSpec): locale.setlocale(locale.LC_ALL, '') """ - if self.settings.input_encoding \ - and self.settings.input_encoding.lower() == 'unicode': + if self.encoding and self.encoding.lower() == 'unicode': return unicode(data) - encodings = [self.settings.input_encoding, 'utf-8'] + encodings = [self.encoding, 'utf-8'] try: encodings.append(locale.nl_langinfo(locale.CODESET)) except: @@ -97,10 +106,20 @@ class Output(TransformSpec): default_destination_path = None - 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).""" + def __init__(self, settings=None, destination=None, destination_path=None, + encoding=None): + self.encoding = encoding + """The character encoding for the output destination.""" + + if settings: + if not encoding: + self.encoding = settings.output_encoding + import warnings, traceback + warnings.warn( + 'Setting output encoding via a "settings" struct is ' + 'deprecated; send encoding directly instead.\n%s' + % ''.join(traceback.format_list(traceback.extract_stack() + [-3:-1]))) self.destination = destination """The destination for output data.""" @@ -119,11 +138,10 @@ class Output(TransformSpec): raise NotImplementedError def encode(self, data): - if self.settings.output_encoding \ - and self.settings.output_encoding.lower() == 'unicode': + if self.encoding and self.encoding.lower() == 'unicode': return data else: - return data.encode(self.settings.output_encoding or '') + return data.encode(self.encoding or '') class FileInput(Input): @@ -132,7 +150,8 @@ class FileInput(Input): Input for single, simple file-like objects. """ - def __init__(self, settings, source=None, source_path=None, autoclose=1): + def __init__(self, settings=None, source=None, source_path=None, + encoding=None, autoclose=1): """ :Parameters: - `source`: either a file-like object (which is read directly), or @@ -141,7 +160,7 @@ class FileInput(Input): - `autoclose`: close automatically after read (boolean); always false if `sys.stdin` is the source. """ - Input.__init__(self, settings, source, source_path) + Input.__init__(self, settings, source, source_path, encoding) self.autoclose = autoclose if source is None: if source_path: @@ -172,8 +191,8 @@ class FileOutput(Output): Output for single, simple file-like objects. """ - def __init__(self, settings, destination=None, destination_path=None, - autoclose=1): + def __init__(self, settings=None, destination=None, destination_path=None, + encoding=None, autoclose=1): """ :Parameters: - `destination`: either a file-like object (which is written @@ -184,7 +203,8 @@ class FileOutput(Output): - `autoclose`: close automatically after write (boolean); always false if `sys.stdout` is the destination. """ - Output.__init__(self, settings, destination, destination_path) + Output.__init__(self, settings, destination, destination_path, + encoding) self.opened = 1 self.autoclose = autoclose if destination is None: -- cgit v1.2.1 From 673c882e62ff706d8706218bfe74c203c46c87f5 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 28 Nov 2002 03:45:11 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@983 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 9 +++++---- docutils/parsers/rst/directives/misc.py | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index fa99df483..f73ccf338 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -137,8 +137,9 @@ class Publisher: source_path = self.settings._source else: self.settings._source = source_path - self.source = self.source_class(self.settings, source=source, - source_path=source_path) + self.source = self.source_class( + source=source, source_path=source_path, + encoding=self.settings.input_encoding) def set_destination(self, destination=None, destination_path=None): if destination_path is None: @@ -146,8 +147,8 @@ class Publisher: else: self.settings._destination = destination_path self.destination = self.destination_class( - self.settings, destination=destination, - destination_path=destination_path) + destination=destination, destination_path=destination_path, + encoding=self.settings.output_encoding) def apply_transforms(self, document): document.transformer.populate_from_components( diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index b9409aca8..cc8019886 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -30,7 +30,8 @@ def include(name, arguments, options, content, lineno, path = os.path.normpath(os.path.join(source_dir, path)) path = utils.relative_path(None, path) try: - include_file = io.FileInput(state.document.settings, source_path=path) + include_file = io.FileInput( + source_path=path, encoding=state.document.settings.input_encoding) except IOError, error: severe = state_machine.reporter.severe( 'Problems with "%s" directive path:\n%s.' % (name, error), -- cgit v1.2.1 From a692660f038f4d089c877cc1d98d1654d72d0f3a Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 5 Dec 2002 02:25:35 +0000 Subject: Python Source Reader git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@989 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/python/__init__.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 docutils/readers/python/__init__.py (limited to 'docutils') diff --git a/docutils/readers/python/__init__.py b/docutils/readers/python/__init__.py new file mode 100644 index 000000000..a346ce32a --- /dev/null +++ b/docutils/readers/python/__init__.py @@ -0,0 +1,19 @@ +# 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 the Python Source Reader modules. +""" + +__docformat__ = 'reStructuredText' + + +import sys +import docutils.readers + + +class Reader(docutils.readers.Reader): + pass -- cgit v1.2.1 From 9635f4c1c9ba56761da76c853eaa53bde44655ca Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 5 Dec 2002 02:26:03 +0000 Subject: Parser for Python modules git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@990 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/python/moduleparser.py | 244 ++++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 docutils/readers/python/moduleparser.py (limited to 'docutils') diff --git a/docutils/readers/python/moduleparser.py b/docutils/readers/python/moduleparser.py new file mode 100644 index 000000000..a4ef25298 --- /dev/null +++ b/docutils/readers/python/moduleparser.py @@ -0,0 +1,244 @@ +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Parser for Python modules. + +Ideas: + +* Tokenize the module in parallel to extract initial values, comments, etc. + +* Merge the compiler & tokenize output such that the raw text hangs off of + nodes? Especially assignment expressions (RHS). + +""" + +__docformat__ = 'reStructuredText' + +import sys +import compiler +import compiler.ast +import compiler.visitor +from compiler.consts import OP_ASSIGN +from types import StringType, UnicodeType + + +def parse_module(module_text, filename): + ast = compiler.parse(module_text) + visitor = ModuleVisitor(filename) + compiler.walk(ast, visitor, walker=visitor) + return visitor.module + + +class ModuleVisitor(compiler.visitor.ASTVisitor): + + def __init__(self, filename): + compiler.visitor.ASTVisitor.__init__(self) + self.filename = filename + self.module = None + self.context = [] + self.documentable = None + + def default(self, node, *args): + self.documentable = None + #print 'in default (%s)' % node.__class__.__name__ + #compiler.visitor.ASTVisitor.default(self, node, *args) + + def default_ignore(self, node, *args): + #print 'in default_ignore (%s)' % node.__class__.__name__ + compiler.visitor.ASTVisitor.default(self, node, *args) + + def visitModule(self, node): + #print dir(node) + self.module = module = Module(node, self.filename) + if node.doc is not None: + module.append(Docstring(node, node.doc)) + self.context.append(module) + self.documentable = module + self.visit(node.node) + self.context.pop() + + def visitStmt(self, node): + self.default_ignore(node) + + def visitDiscard(self, node): + if self.documentable: + self.visit(node.expr) + + def visitConst(self, node): + if self.documentable: + if type(node.value) in (StringType, UnicodeType): + self.documentable.append(Docstring(node, node.value)) + else: + self.documentable = None + + def visitImport(self, node): + self.context[-1].append(Import(node, node.names)) + self.documentable = None + + def visitFrom(self, node): + self.context[-1].append( + Import(node, node.names, from_name=node.modname)) + self.documentable = None + + def visitAssign(self, node): + visitor = AssignmentVisitor() + compiler.walk(node, visitor, walker=visitor) + if visitor.attributes: + self.context[-1].extend(visitor.attributes) + if len(visitor.attributes) == 1: + self.documentable = visitor.attributes[0] + else: + self.documentable = None + + +class AssignmentVisitor(compiler.visitor.ASTVisitor): + + def __init__(self): + compiler.visitor.ASTVisitor.__init__(self) + self.attributes = [] + + def default(self, node, *args): + pass + + def visitAssign(self, node): + compiler.visitor.ASTVisitor.default(self, node) + + def visitAssName(self, node): + self.attributes.append(Attribute(node, node.name)) + + def get_rhs(self, node): + return "'TBD'" + + +class Node: # (compiler.ast.Node) + + def __init__(self, node): + self.children = [] + """List of child nodes.""" + + self.lineno = node.lineno + """Line number of this node (or ``None``).""" + + def __str__(self, indent=' ', level=0): + return ''.join(['%s%s\n' % (indent * level, repr(self))] + + [child.__str__(indent, level+1) + for child in self.children]) + + def __repr__(self): + parts = [self.__class__.__name__] + for name, value in self.attlist(): + parts.append('%s="%s"' % (name, value)) + return '<%s>' % ' '.join(parts) + + def attlist(self, **atts): + if self.lineno is not None: + atts['lineno'] = self.lineno + attlist = atts.items() + attlist.sort() + return attlist + + def append(self, node): + self.children.append(node) + + def extend(self, node_list): + self.children.extend(node_list) + + +class Module(Node): + + def __init__(self, node, filename): + Node.__init__(self, node) + self.filename = filename + + def attlist(self): + return Node.attlist(self, filename=self.filename) + + +class Docstring(Node): + + def __init__(self, node, text): + Node.__init__(self, node) + self.text = trim_docstring(text) + + def __str__(self, indent=' ', level=0): + prefix = indent * (level + 1) + text = '\n'.join([prefix + line for line in self.text.splitlines()]) + return Node.__str__(self, indent, level) + text + '\n' + + +class Import(Node): + + def __init__(self, node, names, from_name=None): + Node.__init__(self, node) + self.names = names + self.from_name = from_name + + def __str__(self, indent=' ', level=0): + prefix = indent * (level + 1) + lines = [] + for name, as in self.names: + if as: + lines.append('%s%s as %s' % (prefix, name, as)) + else: + lines.append('%s%s' % (prefix, name)) + text = '\n'.join(lines) + return Node.__str__(self, indent, level) + text + '\n' + + def attlist(self): + if self.from_name: + atts = {'from': self.from_name} + else: + atts = {} + return Node.attlist(self, **atts) + + +class Attribute(Node): + + def __init__(self, node, name): + Node.__init__(self, node) + self.name = name + + def attlist(self): + return Node.attlist(self, name=self.name) + + +class Expression(Node): + + def __init__(self, node, text): + Node.__init__(self, node) + self.text = text + + +def trim_docstring(text): + """ + Trim indentation and blank lines from docstring text & return it. + + See PEP 257. + """ + if not text: + return '' + # Convert tabs to spaces (following the normal Python rules) + # and split into a list of lines: + lines = text.expandtabs().splitlines() + # Determine minimum indentation (first line doesn't count): + indent = sys.maxint + for line in lines[1:]: + stripped = line.lstrip() + if stripped: + indent = min(indent, len(line) - len(stripped)) + # Remove indentation (first line is special): + trimmed = [lines[0].strip()] + if indent < sys.maxint: + for line in lines[1:]: + trimmed.append(line[indent:].rstrip()) + # Strip off trailing and leading blank lines: + while trimmed and not trimmed[-1]: + trimmed.pop() + while trimmed and not trimmed[0]: + trimmed.pop(0) + # Return a single string: + return '\n'.join(trimmed) -- cgit v1.2.1 From 3fad4eec8286426c2f81d7bbc79d4487ed04f047 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 7 Dec 2002 03:03:04 +0000 Subject: Fixed empty meta tags (thanks to David Abrahams). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1002 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index f77fca758..855d78895 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -780,7 +780,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('\n\n') def visit_meta(self, node): - self.head.append(self.starttag(node, 'meta', **node.attributes)) + self.head.append(self.emptytag(node, 'meta', **node.attributes)) def depart_meta(self, node): pass -- cgit v1.2.1 From 8fb2993c1845c8f2b68b150f14b99ca5035799e6 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 7 Dec 2002 03:05:29 +0000 Subject: Added ``TargetNotes.cleanup_callback``. Some improvements to ``Headers``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1003 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/peps.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index 9df903e67..9ae7fa80b 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -22,7 +22,7 @@ import time from docutils import nodes, utils from docutils import ApplicationError, DataError from docutils.transforms import Transform, TransformError -from docutils.transforms import parts, references +from docutils.transforms import parts, references, misc class Headers(Transform): @@ -42,13 +42,14 @@ class Headers(Transform): def apply(self): if not len(self.document): + # @@@ replace these DataErrors with proper system messages raise DataError('Document tree is empty.') header = self.document[0] if not isinstance(header, nodes.field_list) or \ header.get('class') != 'rfc2822': raise DataError('Document does not begin with an RFC-2822 ' 'header; it is not a PEP.') - pep = title = None + pep = None for field in header: if field[0].astext().lower() == 'pep': # should be the first field value = field[1].astext() @@ -79,6 +80,8 @@ class Headers(Transform): pending = nodes.pending(PEPZero) self.document.insert(1, pending) self.document.note_pending(pending) + if len(header) < 2 or header[1][0].astext().lower() != 'title': + raise DataError('No title!') for field in header: name = field[0].astext().lower() body = field[1] @@ -181,6 +184,19 @@ class TargetNotes(Transform): pending = nodes.pending(references.TargetNotes) refsect.append(pending) self.document.note_pending(pending, 0) + pending = nodes.pending(misc.CallBack, + details={'callback': self.cleanup_callback}) + refsect.append(pending) + self.document.note_pending(pending, 1) + + def cleanup_callback(self, pending): + """ + Remove an empty "References" section. + + Called after the `references.TargetNotes` transform is complete. + """ + if len(pending.parent) == 2: # and <pending> + pending.parent.parent.remove(pending.parent) class PEPZero(Transform): -- cgit v1.2.1 From 3d1457ba9864768febb04f75ea4a692e96aefd0a Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 7 Dec 2002 03:07:38 +0000 Subject: Miscellaneous transforms. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1004 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/misc.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 docutils/transforms/misc.py (limited to 'docutils') diff --git a/docutils/transforms/misc.py b/docutils/transforms/misc.py new file mode 100644 index 000000000..cf26f6c3b --- /dev/null +++ b/docutils/transforms/misc.py @@ -0,0 +1,33 @@ +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Miscellaneous transforms. +""" + +__docformat__ = 'reStructuredText' + +from docutils.transforms import Transform, TransformError + + +class CallBack(Transform): + + """ + Inserts a callback into a document. The callback is called when the + transform is applied, which is determined by its priority. + + For use with `nodes.pending` elements. Requires a ``details['callback']`` + entry, a bound method or function which takes one parameter: the pending + node. Other data can be stored in the ``details`` attribute or in the + object hosting the callback method. + """ + + default_priority = 990 + + def apply(self): + pending = self.startnode + pending.details['callback'](pending) + pending.parent.remove(pending) -- cgit v1.2.1 From 241b81278dfcb2caddefea8ce1ed648a48f720d4 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 7 Dec 2002 03:13:24 +0000 Subject: update git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1006 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/python/moduleparser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/readers/python/moduleparser.py b/docutils/readers/python/moduleparser.py index a4ef25298..5aab372b2 100644 --- a/docutils/readers/python/moduleparser.py +++ b/docutils/readers/python/moduleparser.py @@ -114,7 +114,7 @@ class AssignmentVisitor(compiler.visitor.ASTVisitor): return "'TBD'" -class Node: # (compiler.ast.Node) +class Node: def __init__(self, node): self.children = [] -- cgit v1.2.1 From a5017ad1128d5d901ce4c80c31cf4d06a43d5637 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 12 Dec 2002 02:44:44 +0000 Subject: fixed a bug with ellipsis etc. (<=3 char underline) on second line of a block quote paragraph git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1013 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 5ddcbb5bb..ab1266f9a 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -2382,24 +2382,18 @@ class Text(RSTState): def underline(self, match, context, next_state): """Section title.""" 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.', - nodes.literal_block(blocktext, blocktext), line=lineno) - self.parent += msg - return [], next_state, [] title = context[0].rstrip() underline = match.string.rstrip() source = title + '\n' + underline messages = [] if len(title) > len(underline): 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.", - line=lineno) - self.parent += msg + if self.state_machine.match_titles: + msg = self.reporter.info( + 'Possible title underline, too short for the title.\n' + "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 @@ -2407,6 +2401,14 @@ class Text(RSTState): 'Title underline too short.', nodes.literal_block(blocktext, blocktext), line=lineno) messages.append(msg) + 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) + self.parent += messages + self.parent += msg + return [], next_state, [] style = underline[0] context[:] = [] self.section(title, source, style, lineno - 1, messages) -- cgit v1.2.1 From b75e46e8a06dd8170c9fbabaee4c4aaa22050e67 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 12 Dec 2002 03:26:55 +0000 Subject: Updated. Dead-end with AssignmentVisitor reconstructing expressions. TokenReader seems to be the way to go. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1017 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/python/moduleparser.py | 250 ++++++++++++++++++++++++++++++-- 1 file changed, 238 insertions(+), 12 deletions(-) (limited to 'docutils') diff --git a/docutils/readers/python/moduleparser.py b/docutils/readers/python/moduleparser.py index 5aab372b2..9ab3eea79 100644 --- a/docutils/readers/python/moduleparser.py +++ b/docutils/readers/python/moduleparser.py @@ -14,6 +14,150 @@ Ideas: * Merge the compiler & tokenize output such that the raw text hangs off of nodes? Especially assignment expressions (RHS). +What I'd like to do is to take a module, read in the text, run it through the +module parser (using compiler.py and tokenize.py) and produce a high-level AST +full of nodes that are interesting from an auto-documentation standpoint. For +example, given this module (x.py):: + + # comment + + '''Docstring''' + + '''Additional docstring''' + + __docformat__ = 'reStructuredText' + + a = 1 + '''Attribute docstring''' + + class C(Super): + + '''C's docstring''' + + class_attribute = 1 + '''class_attribute's docstring''' + + def __init__(self, text=None): + '''__init__'s docstring''' + + self.instance_attribute = (text * 7 + + ' whaddyaknow') + '''instance_attribute's docstring''' + + + def f(x, # parameter x + y=a*5, # parameter y + *args): # parameter args + '''f's docstring''' + return [x + item for item in args] + + f.function_attribute = 1 + '''f.function_attribute's docstring''' + +The module parser should produce a high-level AST, something like this:: + + <Module filename="x.py"> + <Comment lineno=1> + comment + <Docstring lineno=3> + Docstring + <Docstring lineno=...> (I'll leave out the lineno's) + Additional docstring + <Attribute name="__docformat__"> + <Expression> + 'reStructuredText' + <Attribute name="a"> + <Expression> + 1 + <Docstring> + Attribute docstring + <Class name="C" inheritance="Super"> + <Docstring> + C's docstring + <Attribute name="class_attribute"> + <Expression> + 1 + <Docstring> + class_attribute's docstring + <Method name="__init__" argnames=['self', ('text', 'None')]> + <Docstring> + __init__'s docstring + <Attribute name="instance_attribute" instance=True> + <Expression> + (text * 7 + + ' whaddyaknow') + <Docstring> + class_attribute's docstring + <Function name="f"> + <Parameters> + <Parameter name="x"> + <Comment> + # parameter x + <Parameter name="y"> + <Expression> + a*5 + <Comment> + # parameter y + <Parameter name="args" varargs=True> + <Comment> + # parameter args + <Docstring> + f's docstring + <Attribute name="function_attribute"> + <Expression> + 1 + <Docstring> + f.function_attribute's docstring + +compiler.parse() provides most of what's needed for this AST. I think that +"tokenize" can be used to get the rest, and all that's left is to hunker down +and figure out how. We can determine the line number from the +compiler.parse() AST, and a get_rhs(lineno) method would provide the rest. + +The Docutils Python reader component will transform this AST into a +Python-specific doctree, and then a `stylist transform`_ would further +transform it into a generic doctree. Namespaces will have to be compiled for +each of the scopes, but I'm not certain at what stage of processing. + +It's very important to keep all docstring processing out of this, so that it's +a completely generic and not tool-specific. + +> Why perform all of those transformations? Why not go from the AST to a +> generic doctree? Or, even from the AST to the final output? + +I want the docutils.readers.python.moduleparser.parse_module() function to +produce a standard documentation-oriented AST that can be used by any tool. +We can develop it together without having to compromise on the rest of our +design (i.e., HappyDoc doesn't have to be made to work like Docutils, and +vice-versa). It would be a higher-level version of what compiler.py provides. + +The Python reader component transforms this generic AST into a Python-specific +doctree (it knows about modules, classes, functions, etc.), but this is +specific to Docutils and cannot be used by HappyDoc or others. The stylist +transform does the final layout, converting Python-specific structures +("class" sections, etc.) into a generic doctree using primitives (tables, +sections, lists, etc.). This generic doctree does *not* know about Python +structures any more. The advantage is that this doctree can be handed off to +any of the output writers to create any output format we like. + +The latter two transforms are separate because I want to be able to have +multiple independent layout styles (multiple runtime-selectable "stylist +transforms"). Each of the existing tools (HappyDoc, pydoc, epydoc, Crystal, +etc.) has its own fixed format. I personally don't like the tables-based +format produced by these tools, and I'd like to be able to customize the +format easily. That's the goal of stylist transforms, which are independent +from the Reader component itself. One stylist transform could produce +HappyDoc-like output, another could produce output similar to module docs in +the Python library reference manual, and so on. + +It's for exactly this reason: + +>> It's very important to keep all docstring processing out of this, so that +>> it's a completely generic and not tool-specific. + +... but it goes past docstring processing. It's also important to keep style +decisions and tool-specific data transforms out of this module parser. + """ __docformat__ = 'reStructuredText' @@ -21,8 +165,10 @@ __docformat__ = 'reStructuredText' import sys import compiler import compiler.ast -import compiler.visitor +import tokenize +import token from compiler.consts import OP_ASSIGN +from compiler.visitor import ASTVisitor from types import StringType, UnicodeType @@ -33,10 +179,10 @@ def parse_module(module_text, filename): return visitor.module -class ModuleVisitor(compiler.visitor.ASTVisitor): +class ModuleVisitor(ASTVisitor): def __init__(self, filename): - compiler.visitor.ASTVisitor.__init__(self) + ASTVisitor.__init__(self) self.filename = filename self.module = None self.context = [] @@ -45,11 +191,11 @@ class ModuleVisitor(compiler.visitor.ASTVisitor): def default(self, node, *args): self.documentable = None #print 'in default (%s)' % node.__class__.__name__ - #compiler.visitor.ASTVisitor.default(self, node, *args) + #ASTVisitor.default(self, node, *args) def default_ignore(self, node, *args): #print 'in default_ignore (%s)' % node.__class__.__name__ - compiler.visitor.ASTVisitor.default(self, node, *args) + ASTVisitor.default(self, node, *args) def visitModule(self, node): #print dir(node) @@ -95,23 +241,66 @@ class ModuleVisitor(compiler.visitor.ASTVisitor): self.documentable = None -class AssignmentVisitor(compiler.visitor.ASTVisitor): +class AssignmentVisitor(ASTVisitor): + + """ + Tried reconstructing expressions (the RHS of assignments) by + visiting the compiler.parse() tree, but a lot of information is + missing, like parenthesis-grouping of expressions. + + Gotta do it by parsing tokens. + """ def __init__(self): - compiler.visitor.ASTVisitor.__init__(self) + ASTVisitor.__init__(self) self.attributes = [] + self.parts = [] def default(self, node, *args): - pass + print >>sys.stderr, '%s not visited!' % node.__class__.__name__ + ASTVisitor.default(self, node) def visitAssign(self, node): - compiler.visitor.ASTVisitor.default(self, node) + ASTVisitor.default(self, node) + self.attributes[-1].append(Expression(node, ''.join(self.parts))) def visitAssName(self, node): self.attributes.append(Attribute(node, node.name)) - def get_rhs(self, node): - return "'TBD'" + def visitAdd(self, node): + ASTVisitor.default(self, node) + self.parts[-2:] = ' + '.join(self.parts[-2:]) + + def visitAnd(self, node): + ASTVisitor.default(self, node) + self.parts.insert(len(self.parts) - 1, ' and ') + + def visitBackquote(self, node): + self.parts.append('`') + ASTVisitor.default(self, node) + self.parts.append('`') + + def visitBitand(self, node): + ASTVisitor.default(self, node) + self.parts.insert(len(self.parts) - 1, ' & ') + + def visitBitor(self, node): + ASTVisitor.default(self, node) + self.parts.insert(len(self.parts) - 1, ' | ') + + def visitBitxor(self, node): + ASTVisitor.default(self, node) + self.parts.insert(len(self.parts) - 1, ' ^ ') + + def visitConst(self, node): + self.parts.append(repr(node.value)) + + def visitConst(self, node): + self.parts.append(repr(node.value)) + + def visitInvert(self, node): + self.parts.append('~ ') + ASTVisitor.default(self, node) class Node: @@ -211,7 +400,44 @@ class Expression(Node): def __init__(self, node, text): Node.__init__(self, node) self.text = text - + + def __str__(self, indent=' ', level=0): + prefix = indent * (level + 1) + return '%s%s%s\n' % (Node.__str__(self, indent, level), + prefix, self.text) + + +class TokenReader: + + def __init__(self, text): + self.text = text + self.lines = text.splitlines(1) + self.generator = tokenize.generate_tokens(iter(self.lines).next) + + def __iter__(self): + return self + + def next(self): + token = self.generator.next() + self.type, self.string, self.start, self.end, self.line = token + return token + + def goto_line(self, lineno): + for token in self: + if self.start[0] >= lineno: + return token + else: + raise IndexError + + def rhs(self, name, lineno): + self.goto_line(lineno) + while self.start[0] == lineno: + if self.type == token.OP and self.string == '=': + break + self.next() + else: + raise IndexError + def trim_docstring(text): """ -- cgit v1.2.1 From 47ff214eaec8f59ac08c78614811e12eb9b06fde Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 14 Dec 2002 01:38:31 +0000 Subject: making good progress git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1020 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/python/moduleparser.py | 293 ++++++++++++++++++++++---------- 1 file changed, 199 insertions(+), 94 deletions(-) (limited to 'docutils') diff --git a/docutils/readers/python/moduleparser.py b/docutils/readers/python/moduleparser.py index 9ab3eea79..cbca876a7 100644 --- a/docutils/readers/python/moduleparser.py +++ b/docutils/readers/python/moduleparser.py @@ -12,7 +12,7 @@ Ideas: * Tokenize the module in parallel to extract initial values, comments, etc. * Merge the compiler & tokenize output such that the raw text hangs off of - nodes? Especially assignment expressions (RHS). + nodes. Useful for assignment expressions (RHS). What I'd like to do is to take a module, read in the text, run it through the module parser (using compiler.py and tokenize.py) and produce a high-level AST @@ -79,7 +79,12 @@ The module parser should produce a high-level AST, something like this:: 1 <Docstring> class_attribute's docstring - <Method name="__init__" argnames=['self', ('text', 'None')]> + <Method name="__init__"> + <Parameters> + <Parameter name="self"> + <Parameter name="text"> + <Expression> + None <Docstring> __init__'s docstring <Attribute name="instance_attribute" instance=True> @@ -109,10 +114,10 @@ The module parser should produce a high-level AST, something like this:: <Docstring> f.function_attribute's docstring -compiler.parse() provides most of what's needed for this AST. I think that -"tokenize" can be used to get the rest, and all that's left is to hunker down -and figure out how. We can determine the line number from the -compiler.parse() AST, and a get_rhs(lineno) method would provide the rest. +compiler.parse() provides most of what's needed for this AST, and "tokenize" +can be used to get the rest. We can determine the line number from the +compiler.parse() AST, and the TokenParser.rhs(lineno) method provides the +rest. The Docutils Python reader component will transform this AST into a Python-specific doctree, and then a `stylist transform`_ would further @@ -174,17 +179,17 @@ from types import StringType, UnicodeType def parse_module(module_text, filename): ast = compiler.parse(module_text) - visitor = ModuleVisitor(filename) + token_parser = TokenParser(module_text) + visitor = ModuleVisitor(filename, token_parser) compiler.walk(ast, visitor, walker=visitor) return visitor.module -class ModuleVisitor(ASTVisitor): +class BaseVisitor(ASTVisitor): - def __init__(self, filename): + def __init__(self, token_parser): ASTVisitor.__init__(self) - self.filename = filename - self.module = None + self.token_parser = token_parser self.context = [] self.documentable = None @@ -193,22 +198,12 @@ class ModuleVisitor(ASTVisitor): #print 'in default (%s)' % node.__class__.__name__ #ASTVisitor.default(self, node, *args) - def default_ignore(self, node, *args): - #print 'in default_ignore (%s)' % node.__class__.__name__ + def default_visit(self, node, *args): + #print 'in default_visit (%s)' % node.__class__.__name__ ASTVisitor.default(self, node, *args) - def visitModule(self, node): - #print dir(node) - self.module = module = Module(node, self.filename) - if node.doc is not None: - module.append(Docstring(node, node.doc)) - self.context.append(module) - self.documentable = module - self.visit(node.node) - self.context.pop() - def visitStmt(self, node): - self.default_ignore(node) +class DocstringVisitor(BaseVisitor): def visitDiscard(self, node): if self.documentable: @@ -221,17 +216,14 @@ class ModuleVisitor(ASTVisitor): else: self.documentable = None - def visitImport(self, node): - self.context[-1].append(Import(node, node.names)) - self.documentable = None + def visitStmt(self, node): + self.default_visit(node) - def visitFrom(self, node): - self.context[-1].append( - Import(node, node.names, from_name=node.modname)) - self.documentable = None + +class AssignmentVisitor(DocstringVisitor): def visitAssign(self, node): - visitor = AssignmentVisitor() + visitor = AttributeVisitor(self.token_parser) compiler.walk(node, visitor, walker=visitor) if visitor.attributes: self.context[-1].extend(visitor.attributes) @@ -241,66 +233,111 @@ class ModuleVisitor(ASTVisitor): self.documentable = None -class AssignmentVisitor(ASTVisitor): +class ModuleVisitor(AssignmentVisitor): - """ - Tried reconstructing expressions (the RHS of assignments) by - visiting the compiler.parse() tree, but a lot of information is - missing, like parenthesis-grouping of expressions. + def __init__(self, filename, token_parser): + AssignmentVisitor.__init__(self, token_parser) + self.filename = filename + self.module = None - Gotta do it by parsing tokens. - """ + def visitModule(self, node): + self.module = module = Module(node, self.filename) + if node.doc is not None: + module.append(Docstring(node, node.doc)) + self.context.append(module) + self.documentable = module + self.visit(node.node) + self.context.pop() - def __init__(self): - ASTVisitor.__init__(self) - self.attributes = [] - self.parts = [] + def visitImport(self, node): + self.context[-1].append(Import(node, node.names)) + self.documentable = None - def default(self, node, *args): - print >>sys.stderr, '%s not visited!' % node.__class__.__name__ - ASTVisitor.default(self, node) + def visitFrom(self, node): + self.context[-1].append( + Import(node, node.names, from_name=node.modname)) + self.documentable = None + + def visitFunction(self, node): + visitor = FunctionVisitor(self.token_parser) + compiler.walk(node, visitor, walker=visitor) + self.context[-1].append(visitor.function) + + +class AttributeVisitor(BaseVisitor): + + def __init__(self, token_parser): + BaseVisitor.__init__(self, token_parser) + self.attributes = [] def visitAssign(self, node): - ASTVisitor.default(self, node) - self.attributes[-1].append(Expression(node, ''.join(self.parts))) + # Don't visit the expression itself, just the attribute nodes: + for child in node.nodes: + self.dispatch(child) + expression_text = self.token_parser.rhs(node.lineno) + expression = Expression(node, expression_text) + for attribute in self.attributes: + attribute.append(expression) def visitAssName(self, node): self.attributes.append(Attribute(node, node.name)) - def visitAdd(self, node): - ASTVisitor.default(self, node) - self.parts[-2:] = ' + '.join(self.parts[-2:]) - - def visitAnd(self, node): - ASTVisitor.default(self, node) - self.parts.insert(len(self.parts) - 1, ' and ') + def visitAssTuple(self, node): + attributes = self.attributes + self.attributes = [] + self.default_visit(node) + names = [attribute.name for attribute in self.attributes] + att_tuple = AttributeTuple(node, names) + att_tuple.lineno = self.attributes[0].lineno + self.attributes = attributes + self.attributes.append(att_tuple) - def visitBackquote(self, node): - self.parts.append('`') - ASTVisitor.default(self, node) - self.parts.append('`') + def visitAssAttr(self, node): + self.default_visit(node, node.attrname) - def visitBitand(self, node): - ASTVisitor.default(self, node) - self.parts.insert(len(self.parts) - 1, ' & ') + def visitGetattr(self, node, suffix): + self.default_visit(node, node.attrname + '.' + suffix) - def visitBitor(self, node): - ASTVisitor.default(self, node) - self.parts.insert(len(self.parts) - 1, ' | ') + def visitName(self, node, suffix): + self.attributes.append(Attribute(node, node.name + '.' + suffix)) - def visitBitxor(self, node): - ASTVisitor.default(self, node) - self.parts.insert(len(self.parts) - 1, ' ^ ') - def visitConst(self, node): - self.parts.append(repr(node.value)) +class FunctionVisitor(DocstringVisitor): - def visitConst(self, node): - self.parts.append(repr(node.value)) + def visitFunction(self, node): + self.function = function = Function(node, node.name) + if node.doc is not None: + function.append(Docstring(node, node.doc)) + self.context.append(function) + self.documentable = function + self.parse_parameter_list(node) + self.visit(node.code) + self.context.pop() - def visitInvert(self, node): - self.parts.append('~ ') - ASTVisitor.default(self, node) + def parse_parameter_list(self, node): + parameters = [] + special = [] + argnames = list(node.argnames) + if node.kwargs: + special.append(ExcessKeywordArguments(node, argnames[-1])) + argnames.pop() + if node.varargs: + special.append(ExcessPositionalArguments(node, argnames[-1])) + argnames.pop() + defaults = list(node.defaults) + defaults = [None] * (len(argnames) - len(defaults)) + defaults + for argname, default in zip(argnames, defaults): + parameter = Parameter(node, argname) + if default: + default_text = self.token_parser.default(node.lineno) + parameter.append(Default(node, default_text)) + parameters.append(parameter) + if parameters or special: + special.reverse() + parameters.extend(special) + parameter_list = ParameterList(node) + parameter_list.extend(parameters) + self.function.append(parameter_list) class Node: @@ -395,6 +432,16 @@ class Attribute(Node): return Node.attlist(self, name=self.name) +class AttributeTuple(Node): + + def __init__(self, node, names): + Node.__init__(self, node) + self.names = names + + def attlist(self): + return Node.attlist(self, names=' '.join(self.names)) + + class Expression(Node): def __init__(self, node, text): @@ -404,40 +451,98 @@ class Expression(Node): def __str__(self, indent=' ', level=0): prefix = indent * (level + 1) return '%s%s%s\n' % (Node.__str__(self, indent, level), - prefix, self.text) + prefix, self.text.encode('unicode-escape')) -class TokenReader: +class Function(Attribute): pass + + +class ParameterList(Node): pass + + +class Parameter(Attribute): pass + + +class ExcessPositionalArguments(Parameter): pass + + +class ExcessKeywordArguments(Parameter): pass + + +class Default(Expression): pass + + +class TokenParser: def __init__(self, text): - self.text = text - self.lines = text.splitlines(1) + self.text = text + '\n\n' + self.lines = self.text.splitlines(1) self.generator = tokenize.generate_tokens(iter(self.lines).next) + self.next() def __iter__(self): return self def next(self): - token = self.generator.next() - self.type, self.string, self.start, self.end, self.line = token - return token + self.token = self.generator.next() + self.type, self.string, self.start, self.end, self.line = self.token + return self.token def goto_line(self, lineno): - for token in self: - if self.start[0] >= lineno: - return token - else: - raise IndexError + while self.start[0] < lineno: + self.next() + return token - def rhs(self, name, lineno): + def rhs(self, lineno): + """ + Return a whitespace-normalized expression string from the right-hand + side of an assignment at line `lineno`. + """ self.goto_line(lineno) - while self.start[0] == lineno: - if self.type == token.OP and self.string == '=': - break + while self.string != '=': self.next() - else: - raise IndexError - + while self.type != token.NEWLINE and self.string != ';': + append = 1 + append_ws = 1 + del_ws = 0 + if self.string == '=': + start_row, start_col = self.end + tokens = [] + last_type = None + last_string = None + backquote = 0 + append = 0 + elif self.string == '.': + del_ws = 1 + append_ws = 0 + elif self.string in ('(', '[', '{'): + append_ws = 0 + if self.string in '([' and (last_type == token.NAME or + last_string in (')', ']', '}')): + del_ws = 1 + elif self.string in (')', ']', '}', ':', ','): + del_ws = 1 + elif self.string == '`': + if backquote: + del_ws = 1 + else: + append_ws = 0 + backquote = not backquote + elif self.type == tokenize.NL: + append = 0 + if append: + if del_ws and tokens and tokens[-1] == ' ': + del tokens[-1] + tokens.append(self.string) + last_type = self.type + last_string = self.string + if append_ws: + tokens.append(' ') + self.next() + self.next() + text = ''.join(tokens) + return text.strip() + def trim_docstring(text): """ -- cgit v1.2.1 From eb82300e688f6e452b1db58d5abadd76be56025d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 17 Dec 2002 02:25:19 +0000 Subject: Added support for backslash-escape after inline markup. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1023 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index ab1266f9a..fb95cdd6a 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -528,7 +528,7 @@ class Inliner: openers = '\'"([{<' closers = '\'")]}>' start_string_prefix = (r'((?<=^)|(?<=[-/: \n%s]))' % re.escape(openers)) - end_string_suffix = (r'((?=$)|(?=[-/:.,;!? \n%s]))' % re.escape(closers)) + end_string_suffix = (r'((?=$)|(?=[-/:.,;!? \n\x00%s]))' % re.escape(closers)) non_whitespace_before = r'(?<![ \n])' non_whitespace_escape_before = r'(?<![ \n\x00])' non_whitespace_after = r'(?![ \n])' -- cgit v1.2.1 From 173c7a539ca4e2b3a9f8c3a06f67d4a868fd850c Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 18 Dec 2002 01:44:49 +0000 Subject: More progress; functions done. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1027 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/python/moduleparser.py | 197 +++++++++++++++++++++++++------- 1 file changed, 157 insertions(+), 40 deletions(-) (limited to 'docutils') diff --git a/docutils/readers/python/moduleparser.py b/docutils/readers/python/moduleparser.py index cbca876a7..8dcf432b2 100644 --- a/docutils/readers/python/moduleparser.py +++ b/docutils/readers/python/moduleparser.py @@ -163,6 +163,14 @@ It's for exactly this reason: ... but it goes past docstring processing. It's also important to keep style decisions and tool-specific data transforms out of this module parser. + +Issues +====== + +* At what point should namespaces be computed? Should they be part of the + basic AST produced by the ASTVisitor walk, or generated by another tree + traversal? + """ __docformat__ = 'reStructuredText' @@ -174,7 +182,7 @@ import tokenize import token from compiler.consts import OP_ASSIGN from compiler.visitor import ASTVisitor -from types import StringType, UnicodeType +from types import StringType, UnicodeType, TupleType def parse_module(module_text, filename): @@ -304,7 +312,13 @@ class AttributeVisitor(BaseVisitor): class FunctionVisitor(DocstringVisitor): + in_function = 0 + def visitFunction(self, node): + if self.in_function: + # Don't bother with nested function definitions. + return + self.in_function = 1 self.function = function = Function(node, node.name) if node.doc is not None: function.append(Docstring(node, node.doc)) @@ -326,11 +340,17 @@ class FunctionVisitor(DocstringVisitor): argnames.pop() defaults = list(node.defaults) defaults = [None] * (len(argnames) - len(defaults)) + defaults + function_parameters = self.token_parser.function_parameters( + node.lineno) + #print >>sys.stderr, function_parameters for argname, default in zip(argnames, defaults): - parameter = Parameter(node, argname) + if type(argname) is TupleType: + parameter = ParameterTuple(node, argname) + argname = normalize_parameter_name(argname) + else: + parameter = Parameter(node, argname) if default: - default_text = self.token_parser.default(node.lineno) - parameter.append(Default(node, default_text)) + parameter.append(Default(node, function_parameters[argname])) parameters.append(parameter) if parameters or special: special.reverse() @@ -463,6 +483,12 @@ class ParameterList(Node): pass class Parameter(Attribute): pass +class ParameterTuple(AttributeTuple): + + def attlist(self): + return Node.attlist(self, names=normalize_parameter_name(self.names)) + + class ExcessPositionalArguments(Parameter): pass @@ -502,47 +528,129 @@ class TokenParser: while self.string != '=': self.next() while self.type != token.NEWLINE and self.string != ';': - append = 1 - append_ws = 1 - del_ws = 0 if self.string == '=': - start_row, start_col = self.end - tokens = [] - last_type = None - last_string = None - backquote = 0 - append = 0 - elif self.string == '.': - del_ws = 1 - append_ws = 0 - elif self.string in ('(', '[', '{'): - append_ws = 0 - if self.string in '([' and (last_type == token.NAME or - last_string in (')', ']', '}')): - del_ws = 1 - elif self.string in (')', ']', '}', ':', ','): - del_ws = 1 - elif self.string == '`': - if backquote: - del_ws = 1 - else: - append_ws = 0 - backquote = not backquote - elif self.type == tokenize.NL: - append = 0 - if append: - if del_ws and tokens and tokens[-1] == ' ': - del tokens[-1] - tokens.append(self.string) - last_type = self.type - last_string = self.string - if append_ws: - tokens.append(' ') + self.tokens = [] + self.stack = [] + self._type = None + self._string = None + self._backquote = 0 + else: + self.note_token() self.next() self.next() - text = ''.join(tokens) + text = ''.join(self.tokens) return text.strip() + openers = {')': '(', ']': '[', '}': '{'} + + def note_token(self): + append = 1 + append_ws = 1 + del_ws = 0 + if self.string == '.': + del_ws = 1 + append_ws = 0 + elif self.string in ('(', '[', '{'): + append_ws = 0 + if self.string in '([' and (self._type == token.NAME or + self._string in (')', ']', '}')): + del_ws = 1 + self.stack.append(self.string) + elif self.string in (')', ']', '}'): + del_ws = 1 + assert self.stack[-1] == self.openers[self.string] + self.stack.pop() + elif self.string in (':', ','): + del_ws = 1 + elif self.string == '`': + if self._backquote: + del_ws = 1 + assert self.stack[-1] == self.string + self.stack.pop() + else: + append_ws = 0 + self.stack.append(self.string) + self._backquote = not self._backquote + elif self.type == tokenize.NL: + append = 0 + if append: + if del_ws and self.tokens and self.tokens[-1] == ' ': + del self.tokens[-1] + self.tokens.append(self.string) + self._type = self.type + self._string = self.string + if append_ws: + self.tokens.append(' ') + + def function_parameters(self, lineno): + """ + Return a dictionary mapping parameters to defaults + (whitespace-normalized strings). + """ + self.goto_line(lineno) + while self.string != 'def': + self.next() + while self.string != '(': + self.next() + name = None + default = None + parameter_tuple = None + self.tokens = [] + parameters = {} + self.stack = [self.string] + self.next() + while 1: + if len(self.stack) == 1: + if parameter_tuple: + # Just encountered ")". + #print >>sys.stderr, 'parameter_tuple: %r' % self.tokens + name = ''.join(self.tokens).strip() + self.tokens = [] + parameter_tuple = None + if self.string in (')', ','): + if name: + if self.tokens: + default_text = ''.join(self.tokens).strip() + else: + default_text = None + parameters[name] = default_text + self.tokens = [] + name = None + default = None + if self.string == ')': + break + elif self.type == token.NAME: + if name and default: + self.note_token() + else: + assert name is None, ( + 'token=%r name=%r parameters=%r stack=%r' + % (self.token, name, parameters, self.stack)) + name = self.string + #print >>sys.stderr, 'name=%r' % name + elif self.string == '=': + assert name is not None, 'token=%r' % (self.token,) + assert default is None, 'token=%r' % (self.token,) + assert self.tokens == [], 'token=%r' % (self.token,) + default = 1 + self._type = None + self._string = None + self._backquote = 0 + elif name: + self.note_token() + elif self.string == '(': + parameter_tuple = 1 + self._type = None + self._string = None + self._backquote = 0 + self.note_token() + else: # ignore these tokens: + assert self.string in ('*', '**', '\n'), ( + 'token=%r' % (self.token,)) + else: + self.note_token() + self.next() + return parameters def trim_docstring(text): """ @@ -573,3 +681,12 @@ def trim_docstring(text): trimmed.pop(0) # Return a single string: return '\n'.join(trimmed) + +def normalize_parameter_name(name): + """ + Converts a tuple like ``('a', ('b', 'c'), 'd')`` into ``'(a, (b, c), d)'`` + """ + if type(name) is TupleType: + return '(%s)' % ', '.join([normalize_parameter_name(n) for n in name]) + else: + return name -- cgit v1.2.1 From 34762d707e5fbe502b302027e4318c8301d7a34d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 19 Dec 2002 01:08:01 +0000 Subject: Added classes & methods. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1032 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/python/moduleparser.py | 464 +++++++++++++++++++------------- 1 file changed, 277 insertions(+), 187 deletions(-) (limited to 'docutils') diff --git a/docutils/readers/python/moduleparser.py b/docutils/readers/python/moduleparser.py index 8dcf432b2..dee7810ad 100644 --- a/docutils/readers/python/moduleparser.py +++ b/docutils/readers/python/moduleparser.py @@ -7,17 +7,11 @@ """ Parser for Python modules. -Ideas: - -* Tokenize the module in parallel to extract initial values, comments, etc. - -* Merge the compiler & tokenize output such that the raw text hangs off of - nodes. Useful for assignment expressions (RHS). - -What I'd like to do is to take a module, read in the text, run it through the -module parser (using compiler.py and tokenize.py) and produce a high-level AST -full of nodes that are interesting from an auto-documentation standpoint. For -example, given this module (x.py):: +The `parse_module()` function takes a module's text and file name, runs it +through the module parser (using compiler.py and tokenize.py) and produces a +"module documentation tree": a high-level AST full of nodes that are +interesting from an auto-documentation standpoint. For example, given this +module (x.py):: # comment @@ -54,75 +48,77 @@ example, given this module (x.py):: f.function_attribute = 1 '''f.function_attribute's docstring''' -The module parser should produce a high-level AST, something like this:: +The module parser will produce this module documentation tree:: - <Module filename="x.py"> + <Module filename="test data"> <Comment lineno=1> comment - <Docstring lineno=3> + <Docstring> Docstring - <Docstring lineno=...> (I'll leave out the lineno's) + <Docstring lineno="5"> Additional docstring - <Attribute name="__docformat__"> - <Expression> + <Attribute lineno="7" name="__docformat__"> + <Expression lineno="7"> 'reStructuredText' - <Attribute name="a"> - <Expression> + <Attribute lineno="9" name="a"> + <Expression lineno="9"> 1 - <Docstring> + <Docstring lineno="10"> Attribute docstring - <Class name="C" inheritance="Super"> - <Docstring> + <Class bases="Super" lineno="12" name="C"> + <Docstring lineno="12"> C's docstring - <Attribute name="class_attribute"> - <Expression> + <Attribute lineno="16" name="class_attribute"> + <Expression lineno="16"> 1 - <Docstring> + <Docstring lineno="17"> class_attribute's docstring - <Method name="__init__"> - <Parameters> - <Parameter name="self"> - <Parameter name="text"> - <Expression> - None - <Docstring> + <Method lineno="19" name="__init__"> + <Docstring lineno="19"> __init__'s docstring - <Attribute name="instance_attribute" instance=True> - <Expression> - (text * 7 - + ' whaddyaknow') - <Docstring> - class_attribute's docstring - <Function name="f"> - <Parameters> - <Parameter name="x"> + <ParameterList lineno="19"> + <Parameter lineno="19" name="self"> + <Parameter lineno="19" name="text"> + <Default lineno="19"> + None + <Attribute lineno="22" name="self.instance_attribute"> + <Expression lineno="22"> + (text * 7 + ' whaddyaknow') + <Docstring lineno="24"> + instance_attribute's docstring + <Function lineno="27" name="f"> + <Docstring lineno="27"> + f's docstring + <ParameterList lineno="27"> + <Parameter lineno="27" name="x"> <Comment> # parameter x - <Parameter name="y"> - <Expression> - a*5 + <Parameter lineno="27" name="y"> + <Default lineno="27"> + a * 5 <Comment> # parameter y - <Parameter name="args" varargs=True> + <ExcessPositionalArguments lineno="27" name="args"> <Comment> # parameter args - <Docstring> - f's docstring - <Attribute name="function_attribute"> - <Expression> - 1 - <Docstring> - f.function_attribute's docstring + <Attribute lineno="33" name="f.function_attribute"> + <Expression lineno="33"> + 1 + <Docstring lineno="34"> + f.function_attribute's docstring + +(Comments are not implemented yet.) -compiler.parse() provides most of what's needed for this AST, and "tokenize" -can be used to get the rest. We can determine the line number from the -compiler.parse() AST, and the TokenParser.rhs(lineno) method provides the +compiler.parse() provides most of what's needed for this doctree, and +"tokenize" can be used to get the rest. We can determine the line number from +the compiler.parse() AST, and the TokenParser.rhs(lineno) method provides the rest. -The Docutils Python reader component will transform this AST into a -Python-specific doctree, and then a `stylist transform`_ would further -transform it into a generic doctree. Namespaces will have to be compiled for -each of the scopes, but I'm not certain at what stage of processing. +The Docutils Python reader component will transform this module doctree into a +Python-specific Docutils doctree, and then a `stylist transform`_ will +further transform it into a generic doctree. Namespaces will have to be +compiled for each of the scopes, but I'm not certain at what stage of +processing. It's very important to keep all docstring processing out of this, so that it's a completely generic and not tool-specific. @@ -131,7 +127,7 @@ a completely generic and not tool-specific. > generic doctree? Or, even from the AST to the final output? I want the docutils.readers.python.moduleparser.parse_module() function to -produce a standard documentation-oriented AST that can be used by any tool. +produce a standard documentation-oriented tree that can be used by any tool. We can develop it together without having to compromise on the rest of our design (i.e., HappyDoc doesn't have to be made to work like Docutils, and vice-versa). It would be a higher-level version of what compiler.py provides. @@ -171,6 +167,17 @@ Issues basic AST produced by the ASTVisitor walk, or generated by another tree traversal? +* At what point should a distinction be made between local variables & + instance attributes in __init__ methods? + +* Docstrings are getting their lineno from their parents. Should the + TokenParser find the real line no's? + +* Comments: include them? How and when? Only full-line comments, or + parameter comments too? (See function "f" above for an example.) + +* Module could use more docstrings & refactoring in places. + """ __docformat__ = 'reStructuredText' @@ -186,6 +193,7 @@ from types import StringType, UnicodeType, TupleType def parse_module(module_text, filename): + """Return a module documentation tree from `module_text`.""" ast = compiler.parse(module_text) token_parser = TokenParser(module_text) visitor = ModuleVisitor(filename, token_parser) @@ -193,6 +201,161 @@ def parse_module(module_text, filename): return visitor.module +class Node: + + def __init__(self, node): + self.children = [] + """List of child nodes.""" + + self.lineno = node.lineno + """Line number of this node (or ``None``).""" + + def __str__(self, indent=' ', level=0): + return ''.join(['%s%s\n' % (indent * level, repr(self))] + + [child.__str__(indent, level+1) + for child in self.children]) + + def __repr__(self): + parts = [self.__class__.__name__] + for name, value in self.attlist(): + parts.append('%s="%s"' % (name, value)) + return '<%s>' % ' '.join(parts) + + def attlist(self, **atts): + if self.lineno is not None: + atts['lineno'] = self.lineno + attlist = atts.items() + attlist.sort() + return attlist + + def append(self, node): + self.children.append(node) + + def extend(self, node_list): + self.children.extend(node_list) + + +class Module(Node): + + def __init__(self, node, filename): + Node.__init__(self, node) + self.filename = filename + + def attlist(self): + return Node.attlist(self, filename=self.filename) + + +class Docstring(Node): + + def __init__(self, node, text): + Node.__init__(self, node) + self.text = trim_docstring(text) + + def __str__(self, indent=' ', level=0): + prefix = indent * (level + 1) + text = '\n'.join([prefix + line for line in self.text.splitlines()]) + return Node.__str__(self, indent, level) + text + '\n' + + +class Import(Node): + + def __init__(self, node, names, from_name=None): + Node.__init__(self, node) + self.names = names + self.from_name = from_name + + def __str__(self, indent=' ', level=0): + prefix = indent * (level + 1) + lines = [] + for name, as in self.names: + if as: + lines.append('%s%s as %s' % (prefix, name, as)) + else: + lines.append('%s%s' % (prefix, name)) + text = '\n'.join(lines) + return Node.__str__(self, indent, level) + text + '\n' + + def attlist(self): + if self.from_name: + atts = {'from': self.from_name} + else: + atts = {} + return Node.attlist(self, **atts) + + +class Attribute(Node): + + def __init__(self, node, name): + Node.__init__(self, node) + self.name = name + + def attlist(self): + return Node.attlist(self, name=self.name) + + +class AttributeTuple(Node): + + def __init__(self, node, names): + Node.__init__(self, node) + self.names = names + + def attlist(self): + return Node.attlist(self, names=' '.join(self.names)) + + +class Expression(Node): + + def __init__(self, node, text): + Node.__init__(self, node) + self.text = text + + def __str__(self, indent=' ', level=0): + prefix = indent * (level + 1) + return '%s%s%s\n' % (Node.__str__(self, indent, level), + prefix, self.text.encode('unicode-escape')) + + +class Function(Attribute): pass + + +class ParameterList(Node): pass + + +class Parameter(Attribute): pass + + +class ParameterTuple(AttributeTuple): + + def attlist(self): + return Node.attlist(self, names=normalize_parameter_name(self.names)) + + +class ExcessPositionalArguments(Parameter): pass + + +class ExcessKeywordArguments(Parameter): pass + + +class Default(Expression): pass + + +class Class(Node): + + def __init__(self, node, name, bases=None): + Node.__init__(self, node) + self.name = name + self.bases = bases or [] + + def attlist(self): + atts = {'name': self.name} + if self.bases: + atts['bases'] = ' '.join(self.bases) + return Node.attlist(self, **atts) + + +class Method(Function): pass + + class BaseVisitor(ASTVisitor): def __init__(self, token_parser): @@ -271,6 +434,11 @@ class ModuleVisitor(AssignmentVisitor): compiler.walk(node, visitor, walker=visitor) self.context[-1].append(visitor.function) + def visitClass(self, node): + visitor = ClassVisitor(self.token_parser) + compiler.walk(node, visitor, walker=visitor) + self.context[-1].append(visitor.klass) + class AttributeVisitor(BaseVisitor): @@ -313,13 +481,15 @@ class AttributeVisitor(BaseVisitor): class FunctionVisitor(DocstringVisitor): in_function = 0 + function_class = Function def visitFunction(self, node): if self.in_function: + self.documentable = None # Don't bother with nested function definitions. return self.in_function = 1 - self.function = function = Function(node, node.name) + self.function = function = self.function_class(node, node.name) if node.doc is not None: function.append(Docstring(node, node.doc)) self.context.append(function) @@ -360,142 +530,61 @@ class FunctionVisitor(DocstringVisitor): self.function.append(parameter_list) -class Node: - - def __init__(self, node): - self.children = [] - """List of child nodes.""" - - self.lineno = node.lineno - """Line number of this node (or ``None``).""" - - def __str__(self, indent=' ', level=0): - return ''.join(['%s%s\n' % (indent * level, repr(self))] + - [child.__str__(indent, level+1) - for child in self.children]) +class ClassVisitor(AssignmentVisitor): - def __repr__(self): - parts = [self.__class__.__name__] - for name, value in self.attlist(): - parts.append('%s="%s"' % (name, value)) - return '<%s>' % ' '.join(parts) + in_class = 0 - def attlist(self, **atts): - if self.lineno is not None: - atts['lineno'] = self.lineno - attlist = atts.items() - attlist.sort() - return attlist - - def append(self, node): - self.children.append(node) - - def extend(self, node_list): - self.children.extend(node_list) - - -class Module(Node): - - def __init__(self, node, filename): - Node.__init__(self, node) - self.filename = filename - - def attlist(self): - return Node.attlist(self, filename=self.filename) - - -class Docstring(Node): - - def __init__(self, node, text): - Node.__init__(self, node) - self.text = trim_docstring(text) - - def __str__(self, indent=' ', level=0): - prefix = indent * (level + 1) - text = '\n'.join([prefix + line for line in self.text.splitlines()]) - return Node.__str__(self, indent, level) + text + '\n' - - -class Import(Node): - - def __init__(self, node, names, from_name=None): - Node.__init__(self, node) - self.names = names - self.from_name = from_name + def __init__(self, token_parser): + AssignmentVisitor.__init__(self, token_parser) + self.bases = [] - def __str__(self, indent=' ', level=0): - prefix = indent * (level + 1) - lines = [] - for name, as in self.names: - if as: - lines.append('%s%s as %s' % (prefix, name, as)) - else: - lines.append('%s%s' % (prefix, name)) - text = '\n'.join(lines) - return Node.__str__(self, indent, level) + text + '\n' + def visitClass(self, node): + if self.in_class: + self.documentable = None + # Don't bother with nested class definitions. + return + self.in_class = 1 + #import mypdb as pdb + #pdb.set_trace() + for base in node.bases: + self.visit(base) + self.klass = klass = Class(node, node.name, self.bases) + if node.doc is not None: + klass.append(Docstring(node, node.doc)) + self.context.append(klass) + self.documentable = klass + self.visit(node.code) + self.context.pop() - def attlist(self): - if self.from_name: - atts = {'from': self.from_name} + def visitGetattr(self, node, suffix=None): + if suffix: + name = node.attrname + '.' + suffix else: - atts = {} - return Node.attlist(self, **atts) - - -class Attribute(Node): - - def __init__(self, node, name): - Node.__init__(self, node) - self.name = name - - def attlist(self): - return Node.attlist(self, name=self.name) - - -class AttributeTuple(Node): - - def __init__(self, node, names): - Node.__init__(self, node) - self.names = names + name = node.attrname + self.default_visit(node, name) - def attlist(self): - return Node.attlist(self, names=' '.join(self.names)) - - -class Expression(Node): - - def __init__(self, node, text): - Node.__init__(self, node) - self.text = text - - def __str__(self, indent=' ', level=0): - prefix = indent * (level + 1) - return '%s%s%s\n' % (Node.__str__(self, indent, level), - prefix, self.text.encode('unicode-escape')) - - -class Function(Attribute): pass - - -class ParameterList(Node): pass - - -class Parameter(Attribute): pass - - -class ParameterTuple(AttributeTuple): - - def attlist(self): - return Node.attlist(self, names=normalize_parameter_name(self.names)) + def visitName(self, node, suffix=None): + if suffix: + name = node.name + '.' + suffix + else: + name = node.name + self.bases.append(name) + def visitFunction(self, node): + if node.name == '__init__': + visitor = InitMethodVisitor(self.token_parser) + else: + visitor = MethodVisitor(self.token_parser) + compiler.walk(node, visitor, walker=visitor) + self.context[-1].append(visitor.function) -class ExcessPositionalArguments(Parameter): pass +class MethodVisitor(FunctionVisitor): -class ExcessKeywordArguments(Parameter): pass + function_class = Method -class Default(Expression): pass +class InitMethodVisitor(MethodVisitor, AssignmentVisitor): pass class TokenParser: @@ -645,7 +734,8 @@ class TokenParser: self._backquote = 0 self.note_token() else: # ignore these tokens: - assert self.string in ('*', '**', '\n'), ( + assert (self.string in ('*', '**', '\n') + or self.type == tokenize.COMMENT), ( 'token=%r' % (self.token,)) else: self.note_token() @@ -659,7 +749,7 @@ def trim_docstring(text): See PEP 257. """ if not text: - return '' + return text # Convert tabs to spaces (following the normal Python rules) # and split into a list of lines: lines = text.expandtabs().splitlines() -- cgit v1.2.1 From 6c7003a050d919f5b10d85b28c0dcafc45f4686f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 19 Dec 2002 04:40:45 +0000 Subject: fixed RHS parse bug, found by Richard Jones git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1035 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/python/moduleparser.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/readers/python/moduleparser.py b/docutils/readers/python/moduleparser.py index dee7810ad..15f05a869 100644 --- a/docutils/readers/python/moduleparser.py +++ b/docutils/readers/python/moduleparser.py @@ -616,8 +616,9 @@ class TokenParser: self.goto_line(lineno) while self.string != '=': self.next() + self.stack = None while self.type != token.NEWLINE and self.string != ';': - if self.string == '=': + if self.string == '=' and not self.stack: self.tokens = [] self.stack = [] self._type = None -- cgit v1.2.1 From f611c402a80b5a839cd1db6d008c0e893c84606e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 29 Dec 2002 16:18:41 +0000 Subject: Italian language support by Nicola Larosa git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1044 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/it.py | 60 ++++++++++++++++++++++++++++++++++++ docutils/parsers/rst/languages/it.py | 46 +++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 docutils/languages/it.py create mode 100644 docutils/parsers/rst/languages/it.py (limited to 'docutils') diff --git a/docutils/languages/it.py b/docutils/languages/it.py new file mode 100644 index 000000000..101abeb96 --- /dev/null +++ b/docutils/languages/it.py @@ -0,0 +1,60 @@ +# Author: Nicola Larosa +# Contact: docutils@tekNico.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Italian-language mappings for language-dependent features of Docutils. +""" + +__docformat__ = 'reStructuredText' + + +from docutils import nodes + + +labels = { + 'author': 'Autore', + 'authors': 'Autori', + 'organization': 'Organizzazione', + 'address': 'Indirizzo', + 'contact': 'Contatti', + 'version': 'Versione', + 'revision': 'Revisione', + 'status': 'Status', + 'date': 'Data', + 'copyright': 'Copyright', + 'dedication': 'Dedica', + 'abstract': 'Riassunto', + 'attention': 'Attenzione!', + 'caution': 'Cautela!', + 'danger': '!PERICOLO!', + 'error': 'Errore', + 'hint': 'Suggerimento', + 'important': 'Importante', + 'note': 'Nota', + 'tip': 'Consiglio', + 'warning': 'Avvertenza', + 'contents': 'Indice'} +"""Mapping of node class name to label text.""" + +bibliographic_fields = { + 'autore': nodes.author, + 'autori': nodes.authors, + 'organizzazione': nodes.organization, + 'indirizzo': nodes.address, + 'contatti': nodes.contact, + 'versione': nodes.version, + 'revisione': nodes.revision, + 'status': nodes.status, + 'data': nodes.date, + 'copyright': nodes.copyright, + 'dedica': nodes.topic, + 'riassunto': 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/it.py b/docutils/parsers/rst/languages/it.py new file mode 100644 index 000000000..fe7610eb0 --- /dev/null +++ b/docutils/parsers/rst/languages/it.py @@ -0,0 +1,46 @@ +# Author: Nicola Larosa +# Contact: docutils@tekNico.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Italian-language mappings for language-dependent features of +reStructuredText. +""" + +__docformat__ = 'reStructuredText' + + +directives = { + 'attenzione': 'attention', + 'cautela': 'caution', + 'pericolo': 'danger', + 'errore': 'error', + 'suggerimento': 'hint', + 'importante': 'important', + 'nota': 'note', + 'consiglio': 'tip', + 'avvertenza': 'warning', + 'argomento': 'topic', + 'blocco di linee': 'line-block', + 'parsed-literal': 'parsed-literal', + #'questions': 'questions', + #'qa': 'questions', + #'faq': 'questions', + 'meta': 'meta', + #'imagemap': 'imagemap', + 'immagine': 'image', + 'figura': 'figure', + 'includi': 'include', + 'grezzo': 'raw', + 'sostituisci': 'replace', + 'indice': 'contents', + 'seznum': '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 acb0feec0ebec5110c719a661b253cd37bf9a721 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 29 Dec 2002 18:37:18 +0000 Subject: refactored a bit git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1045 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/python/moduleparser.py | 81 ++++++++++++++++----------------- 1 file changed, 39 insertions(+), 42 deletions(-) (limited to 'docutils') diff --git a/docutils/readers/python/moduleparser.py b/docutils/readers/python/moduleparser.py index 15f05a869..2262ddbd5 100644 --- a/docutils/readers/python/moduleparser.py +++ b/docutils/readers/python/moduleparser.py @@ -235,6 +235,18 @@ class Node: self.children.extend(node_list) +class TextNode(Node): + + def __init__(self, node, text): + Node.__init__(self, node) + self.text = trim_docstring(text) + + def __str__(self, indent=' ', level=0): + prefix = indent * (level + 1) + text = '\n'.join([prefix + line for line in self.text.splitlines()]) + return Node.__str__(self, indent, level) + text + '\n' + + class Module(Node): def __init__(self, node, filename): @@ -245,16 +257,10 @@ class Module(Node): return Node.attlist(self, filename=self.filename) -class Docstring(Node): +class Docstring(TextNode): pass - def __init__(self, node, text): - Node.__init__(self, node) - self.text = trim_docstring(text) - def __str__(self, indent=' ', level=0): - prefix = indent * (level + 1) - text = '\n'.join([prefix + line for line in self.text.splitlines()]) - return Node.__str__(self, indent, level) + text + '\n' +class Comment(TextNode): pass class Import(Node): @@ -303,11 +309,7 @@ class AttributeTuple(Node): return Node.attlist(self, names=' '.join(self.names)) -class Expression(Node): - - def __init__(self, node, text): - Node.__init__(self, node) - self.text = text +class Expression(TextNode): def __str__(self, indent=' ', level=0): prefix = indent * (level + 1) @@ -631,46 +633,40 @@ class TokenParser: text = ''.join(self.tokens) return text.strip() - openers = {')': '(', ']': '[', '}': '{'} + closers = {')': '(', ']': '[', '}': '{'} + openers = {'(': 1, '[': 1, '{': 1} + del_ws_prefix = {'.': 1, '=': 1, ')': 1, ']': 1, '}': 1, ':': 1, ',': 1} + no_ws_suffix = {'.': 1, '=': 1, '(': 1, '[': 1, '{': 1} def note_token(self): - append = 1 - append_ws = 1 - del_ws = 0 - if self.string == '.': - del_ws = 1 - append_ws = 0 - elif self.string in ('(', '[', '{'): - append_ws = 0 - if self.string in '([' and (self._type == token.NAME or - self._string in (')', ']', '}')): - del_ws = 1 + if self.type == tokenize.NL: + return + del_ws = self.del_ws_prefix.has_key(self.string) + append_ws = not self.no_ws_suffix.has_key(self.string) + if self.openers.has_key(self.string): self.stack.append(self.string) - elif self.string in (')', ']', '}'): - del_ws = 1 - assert self.stack[-1] == self.openers[self.string] + if (self._type == token.NAME + or self.closers.has_key(self._string)): + del_ws = 1 + elif self.closers.has_key(self.string): + assert self.stack[-1] == self.closers[self.string] self.stack.pop() - elif self.string in (':', ','): - del_ws = 1 elif self.string == '`': if self._backquote: del_ws = 1 - assert self.stack[-1] == self.string + assert self.stack[-1] == '`' self.stack.pop() else: append_ws = 0 - self.stack.append(self.string) + self.stack.append('`') self._backquote = not self._backquote - elif self.type == tokenize.NL: - append = 0 - if append: - if del_ws and self.tokens and self.tokens[-1] == ' ': - del self.tokens[-1] - self.tokens.append(self.string) - self._type = self.type - self._string = self.string - if append_ws: - self.tokens.append(' ') + if del_ws and self.tokens and self.tokens[-1] == ' ': + del self.tokens[-1] + self.tokens.append(self.string) + self._type = self.type + self._string = self.string + if append_ws: + self.tokens.append(' ') def function_parameters(self, lineno): """ @@ -743,6 +739,7 @@ class TokenParser: self.next() return parameters + def trim_docstring(text): """ Trim indentation and blank lines from docstring text & return it. -- cgit v1.2.1 From 0fd219662d78c3136a236ea2463b5ebdbbfb441e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 1 Jan 2003 02:12:14 +0000 Subject: removed nasty internals-fiddling ConfigParser.get_section code git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1047 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 35 +++++------------------------------ 1 file changed, 5 insertions(+), 30 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 3c13f094e..029f2763a 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -303,33 +303,8 @@ class ConfigParser(CP.ConfigParser): 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 + section_dict = {} + if self.has_section(section): + for option in self.options(section): + section_dict[option] = self.get(section, option, raw, vars) + return section_dict -- cgit v1.2.1 From f6d2823bed3483be7c3a126c2499d7e9018fae8d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 1 Jan 2003 02:41:16 +0000 Subject: redundant; CVSROOT/cvsignore is global git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1048 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 deletions(-) delete mode 100644 docutils/.cvsignore delete mode 100644 docutils/languages/.cvsignore delete mode 100644 docutils/parsers/.cvsignore delete mode 100644 docutils/parsers/rst/.cvsignore delete mode 100644 docutils/parsers/rst/directives/.cvsignore delete mode 100644 docutils/parsers/rst/languages/.cvsignore delete mode 100644 docutils/readers/.cvsignore delete mode 100644 docutils/transforms/.cvsignore delete mode 100644 docutils/writers/.cvsignore (limited to 'docutils') diff --git a/docutils/.cvsignore b/docutils/.cvsignore deleted file mode 100644 index 0d20b6487..000000000 --- a/docutils/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/docutils/languages/.cvsignore b/docutils/languages/.cvsignore deleted file mode 100644 index 0d20b6487..000000000 --- a/docutils/languages/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/docutils/parsers/.cvsignore b/docutils/parsers/.cvsignore deleted file mode 100644 index 0d20b6487..000000000 --- a/docutils/parsers/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/docutils/parsers/rst/.cvsignore b/docutils/parsers/rst/.cvsignore deleted file mode 100644 index 0d20b6487..000000000 --- a/docutils/parsers/rst/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/docutils/parsers/rst/directives/.cvsignore b/docutils/parsers/rst/directives/.cvsignore deleted file mode 100644 index 0d20b6487..000000000 --- a/docutils/parsers/rst/directives/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/docutils/parsers/rst/languages/.cvsignore b/docutils/parsers/rst/languages/.cvsignore deleted file mode 100644 index 0d20b6487..000000000 --- a/docutils/parsers/rst/languages/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/docutils/readers/.cvsignore b/docutils/readers/.cvsignore deleted file mode 100644 index 0d20b6487..000000000 --- a/docutils/readers/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/docutils/transforms/.cvsignore b/docutils/transforms/.cvsignore deleted file mode 100644 index 0d20b6487..000000000 --- a/docutils/transforms/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/docutils/writers/.cvsignore b/docutils/writers/.cvsignore deleted file mode 100644 index 0d20b6487..000000000 --- a/docutils/writers/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc -- cgit v1.2.1 From c9cc44e987ddc86c342b6b797e38e4836aedcd62 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 1 Jan 2003 15:50:23 +0000 Subject: Fixed slice handling for Python 2.3. Patch from (and thanks to) Fred Drake. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1049 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/statemachine.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'docutils') diff --git a/docutils/statemachine.py b/docutils/statemachine.py index 076a9df2f..d0ddb6330 100644 --- a/docutils/statemachine.py +++ b/docutils/statemachine.py @@ -110,6 +110,7 @@ __docformat__ = 'restructuredtext' import sys import re +from types import SliceType as _SliceType class StateMachine: @@ -1104,22 +1105,23 @@ class ViewList: def __contains__(self, item): return item in self.data def __len__(self): return len(self.data) + # The __getitem__()/__setitem__() methods check whether the index + # is a slice first, since native list objects start supporting + # them directly in Python 2.3 (no exception is raised when + # indexing a list with a slice object; they just work). + def __getitem__(self, i): - try: - return self.data[i] - except TypeError: - assert i.step is None, 'cannot handle slice with stride' + if isinstance(i, _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], parent=self, parent_offset=i.start) + else: + return self.data[i] 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 isinstance(i, _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') self.data[i.start:i.stop] = item.data @@ -1128,6 +1130,10 @@ class ViewList: if self.parent: self.parent[i.start + self.parent_offset : i.stop + self.parent_offset] = item + else: + self.data[i] = item + if self.parent: + self.parent[i + self.parent_offset] = item def __delitem__(self, i): try: -- cgit v1.2.1 From 56b72a68001ef0999d3447f566220bd3145556e8 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 3 Jan 2003 00:47:13 +0000 Subject: placeholder translations; awaiting the real thing git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1051 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/fr.py | 46 ++++++++++++++++++++++++++++++++++++ docutils/parsers/rst/languages/sv.py | 12 ++++++++-- 2 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 docutils/parsers/rst/languages/fr.py (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py new file mode 100644 index 000000000..19cdc5be8 --- /dev/null +++ b/docutils/parsers/rst/languages/fr.py @@ -0,0 +1,46 @@ +# Author: your name here! +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +French-language mappings for language-dependent features of +reStructuredText. +""" + +__docformat__ = 'reStructuredText' + + +directives = { + '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', + 'topic (translation required)': 'topic', + 'line-block (translation required)': 'line-block', + 'parsed-literal (translation required)': 'parsed-literal', + #'questions (translation required)': 'questions', + #'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', + 'contents (translation required)': 'contents', + 'sectnum (translation required)': 'sectnum', + 'section-numbering (translation required)': 'sectnum', + 'target-notes (translation required)': 'target-notes', + #'footnotes (translation required)': 'footnotes', + #'citations (translation required)': 'citations', + } +"""French name to registered (in directives/__init__.py) directive name +mapping.""" diff --git a/docutils/parsers/rst/languages/sv.py b/docutils/parsers/rst/languages/sv.py index 36a576343..9686194df 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -13,7 +13,7 @@ __docformat__ = 'reStructuredText' directives = { u'observera': 'attention', - u'varning': 'caution', + u'caution (translation required)': 'caution', u'fara': 'danger', u'fel': 'error', u'v\u00e4gledning': 'hint', @@ -21,6 +21,9 @@ directives = { u'notera': 'note', u'tips': 'tip', u'varning': 'warning', + u'\u00e4mne': 'topic', + 'line-block (translation required)': 'line-block', + 'parsed-literal (translation required)': 'parsed-literal', # u'fr\u00e5gor': 'questions', # NOTE: A bit long, but recommended by http://www.nada.kth.se/dataterm/: # u'fr\u00e5gor-och-svar': 'questions', @@ -29,10 +32,15 @@ directives = { # u'bildkarta': 'imagemap', # FIXME: Translation might be too literal. u'bild': 'image', u'figur': 'figure', + 'include (translation required)': 'include', u'r\u00e5': 'raw', # FIXME: Translation might be too literal. + 'replace (translation required)': 'replace', u'inneh\u00e5ll': 'contents', + 'sectnum (translation required)': 'sectnum', + 'section-numbering (translation required)': 'sectnum', + 'target-notes (translation required)': 'target-notes', # u'fotnoter': 'footnotes', # u'citeringar': 'citations', - u'\u00e4mne': 'topic'} + } """Swedish name to registered (in directives/__init__.py) directive name mapping.""" -- cgit v1.2.1 From fe8eef6403c40aa13b19cb1f9371aad9c180467f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 3 Jan 2003 00:48:54 +0000 Subject: Fixed XML DOM bug (SF #660611) and slice subtleties. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1052 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index c9670796e..25c06895a 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -57,8 +57,9 @@ class Node: return 1 def asdom(self, dom=xml.dom.minidom): - """Return a DOM representation of this Node.""" - return self._dom_node(dom) + """Return a DOM **fragment** representation of this Node.""" + domroot = dom.Document() + return self._dom_node(domroot) def pformat(self, indent=' ', level=0): """Return an indented pseudo-XML representation, for test purposes.""" @@ -180,10 +181,7 @@ class Text(Node, UserString): 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): + def _dom_node(self, domroot): return domroot.createTextNode(self.data) def astext(self): @@ -260,22 +258,14 @@ class Element(Node): 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): + def _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)) + element.appendChild(child._dom_node(domroot)) return element def __repr__(self): @@ -335,7 +325,7 @@ class Element(Node): elif isinstance(key, IntType): return self.children[key] elif isinstance(key, SliceType): - assert key.step is None, 'cannot handle slice with stride' + assert key.step in (None, 1), 'cannot handle slice with stride' return self.children[key.start:key.stop] else: raise TypeError, ('element index must be an integer, a slice, or ' @@ -348,7 +338,7 @@ class Element(Node): self.setup_child(item) self.children[key] = item elif isinstance(key, SliceType): - assert key.step is None, 'cannot handle slice with stride' + assert key.step in (None, 1), 'cannot handle slice with stride' for node in item: self.setup_child(node) self.children[key.start:key.stop] = item @@ -362,7 +352,7 @@ class Element(Node): elif isinstance(key, IntType): del self.children[key] elif isinstance(key, SliceType): - assert key.step is None, 'cannot handle slice with stride' + assert key.step in (None, 1), 'cannot handle slice with stride' del self.children[key.start:key.stop] else: raise TypeError, ('element index must be an integer, a simple ' @@ -701,8 +691,9 @@ class document(Root, Structural, Element): self.document = self def asdom(self, dom=xml.dom.minidom): + """Return a DOM representation of this document.""" domroot = dom.Document() - domroot.appendChild(self._rooted_dom_node(domroot)) + domroot.appendChild(self._dom_node(domroot)) return domroot def set_id(self, node, msgnode=None): -- cgit v1.2.1 From ac1c77d4c74b175a60843b9f628c1afe8aeb3da1 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 3 Jan 2003 00:49:44 +0000 Subject: Python 2.3 compatibility fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1053 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index fb95cdd6a..8c3f43a30 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1910,7 +1910,7 @@ class Body(RSTState): try: options = utils.extract_extension_options(node, option_spec) except KeyError, detail: - return 0, ('unknown option: "%s"' % detail) + return 0, ('unknown option: "%s"' % detail.args[0]) except (ValueError, TypeError), detail: return 0, ('invalid option value: %s' % detail) except utils.ExtensionOptionError, detail: -- cgit v1.2.1 From df2ba997c490308d849dfc5c67f3ed550dd8138c Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 4 Jan 2003 00:18:58 +0000 Subject: docstring git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1060 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/python/moduleparser.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'docutils') diff --git a/docutils/readers/python/moduleparser.py b/docutils/readers/python/moduleparser.py index 2262ddbd5..9fcd1ec07 100644 --- a/docutils/readers/python/moduleparser.py +++ b/docutils/readers/python/moduleparser.py @@ -203,6 +203,10 @@ def parse_module(module_text, filename): class Node: + """ + Base class for module documentation tree nodes. + """ + def __init__(self, node): self.children = [] """List of child nodes.""" -- cgit v1.2.1 From 7e2b2dab3c856bad1107fee7daf8e1f4e70a2dd0 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 10 Jan 2003 02:11:18 +0000 Subject: Removed the ``interpeted`` element class and added ``title_reference``, ``abbreviation``, ``acronym``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1076 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 25c06895a..f1548e6b0 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1138,12 +1138,14 @@ class raw(Special, Inline, PreBibliographic, FixedTextElement): 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 title_reference(Inline, TextElement): pass +class abbreviation(Inline, TextElement): pass +class acronym(Inline, TextElement): pass class image(General, Inline, TextElement): @@ -1162,7 +1164,7 @@ class generated(Inline, TextElement): pass node_class_names = """ Text - address attention author authors + abbreviation acronym address attention author authors block_quote bullet_list caption caution citation citation_reference classifier colspec comment contact copyright @@ -1173,7 +1175,7 @@ node_class_names = """ footnote footnote_reference generated header hint - image important interpreted + image important label legend line_block list_item literal literal_block note option option_argument option_group option_list option_list_item @@ -1182,7 +1184,8 @@ node_class_names = """ raw reference revision row section status strong substitution_definition substitution_reference subtitle system_message - table target tbody term tgroup thead tip title topic transition + table target tbody term tgroup thead tip title title_reference topic + transition version warning""".split() """A list of names of all concrete Node subclasses.""" -- cgit v1.2.1 From 5636e4d3f02f20e89be705d779a53d9bbd50cd31 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 10 Jan 2003 02:11:51 +0000 Subject: Fixed bug in ``relative_path()``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1077 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/utils.py b/docutils/utils.py index 809511cba..eb3dc4932 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -420,7 +420,7 @@ def relative_path(source, target): source_parts.pop() target_parts.pop() target_parts.reverse() - parts = ['..'] * (len(source_parts) - 1) + target_parts + parts = ['..'] * len(source_parts) + target_parts return '/'.join(parts) def get_source_line(node): -- cgit v1.2.1 From edaeb226e0a505faa5ca54f8bb473a534f3e7b81 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 10 Jan 2003 02:12:36 +0000 Subject: Added support for correct interpreted text processing. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1078 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 148 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 140 insertions(+), 8 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 8c3f43a30..2ddd50809 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -113,9 +113,12 @@ from docutils import ApplicationError, DataError from docutils.statemachine import StateMachineWS, StateWS from docutils.utils import normalize_name from docutils.parsers.rst import directives, languages, tableparser +from docutils.parsers.rst.languages import en as _fallback_language_module class MarkupError(DataError): pass +class UnknownInterpretedRoleError(DataError): pass +class InterpretedRoleNotImplementedError(DataError): pass class ParserError(ApplicationError): pass class MarkupMismatch(Exception): pass @@ -466,11 +469,53 @@ class Inliner: Parse inline markup; call the `parse()` method. """ - def __init__(self): + _interpreted_roles = { + # Values of ``None`` mean "not implemented yet": + 'title-reference': 'title_reference_role', + 'abbreviation': None, + 'acronym': None, + 'index': None, + 'emphasis': None, + 'strong': None, + 'literal': None, + 'named-reference': None, + 'anonymous-reference': None, + 'uri-reference': None, + 'pep-reference': 'pep_reference_role', + 'rfc-reference': 'rfc_reference_role', + 'footnote-reference': None, + 'citation-reference': None, + 'substitution-reference': None, + 'target': None, + } + """Mapping of canonical interpreted text role name to method name. + Initializes a name to bound-method mapping in `__init__`.""" + + default_interpreted_role = 'title-reference' + """The role to use when no explicit role is given. + Override in subclasses.""" + + def __init__(self, roles=None): + """ + `roles` is a mapping of canonical role name to role function or bound + method, which enables additional interpreted text roles. + """ + self.implicit_dispatch = [(self.patterns.uri, self.standalone_uri),] """List of (pattern, bound method) tuples, used by `self.implicit_inline`.""" + self.interpreted_roles = {} + """Mapping of canonical role name to role function or bound method. + Items removed from this mapping will be disabled.""" + + for canonical, method in self._interpreted_roles.items(): + if method: + self.interpreted_roles[canonical] = getattr(self, method) + else: + self.interpreted_roles[canonical] = None + self.interpreted_roles.update(roles or {}) + def init_customizations(self, settings): """Setting-based customizations; run when parsing begins.""" if settings.pep_references: @@ -496,6 +541,7 @@ class Inliner: """ self.reporter = memo.reporter self.document = memo.document + self.language = memo.language self.parent = parent pattern_search = self.patterns.initial.search dispatch = self.dispatch @@ -528,7 +574,8 @@ class Inliner: openers = '\'"([{<' closers = '\'")]}>' start_string_prefix = (r'((?<=^)|(?<=[-/: \n%s]))' % re.escape(openers)) - end_string_suffix = (r'((?=$)|(?=[-/:.,;!? \n\x00%s]))' % re.escape(closers)) + end_string_suffix = (r'((?=$)|(?=[-/:.,;!? \n\x00%s]))' + % re.escape(closers)) non_whitespace_before = r'(?<![ \n])' non_whitespace_escape_before = r'(?<![ \n\x00])' non_whitespace_after = r'(?![ \n])' @@ -756,8 +803,26 @@ class Inliner: return self.phrase_ref(string[:matchstart], string[textend:], rawsource, escaped, text) else: - return self.interpreted(string[:rolestart], string[textend:], - rawsource, text, role, position) + try: + return self.interpreted( + string[:rolestart], string[textend:], + rawsource, text, role, lineno) + except UnknownInterpretedRoleError, detail: + msg = self.reporter.error( + 'Unknown interpreted text role "%s".' % role, + line=lineno) + text = unescape(string[rolestart:textend], 1) + prb = self.problematic(text, text, msg) + return (string[:rolestart], [prb], string[textend:], + detail.args[0] + [msg]) + except InterpretedRoleNotImplementedError, detail: + msg = self.reporter.error( + 'Interpreted text role "%s" not implemented.' % role, + line=lineno) + text = unescape(string[rolestart:textend], 1) + prb = self.problematic(text, text, msg) + return (string[:rolestart], [prb], string[textend:], + detail.args[0] + [msg]) msg = self.reporter.warning( 'Inline interpreted text or phrase reference start-string ' 'without end-string.', line=lineno) @@ -806,12 +871,48 @@ class Inliner: else: return uri - def interpreted(self, before, after, rawsource, text, role, position): + def interpreted(self, before, after, rawsource, text, role, lineno): + role_function, messages = self.get_role_function(role, lineno) + if role_function: + nodelist, messages2 = role_function(role, rawsource, text, lineno) + messages.extend(messages2) + return before, nodelist, after, messages + else: + raise InterpretedRoleNotImplementedError(messages) + + def get_role_function(self, role, lineno): + messages = [] + msg_text = [] if role: - atts = {'role': role, 'position': position} + name = role.lower() + canonical = None + try: + canonical = self.language.roles[name] + except AttributeError, error: + msg_text.append('Problem retrieving role entry from language ' + 'module %r: %s.' % (self.language, error)) + except KeyError: + msg_text.append('No role entry for "%s" in module "%s".' + % (role, self.language.__name__)) + if not canonical: + try: + canonical = _fallback_language_module.roles[name] + msg_text.append('Using English fallback for role "%s".' + % role) + except KeyError: + msg_text.append('Trying "%s" as canonical role name.' + % role) + # Should be an English name, but just in case: + canonical = name + if msg_text: + message = self.reporter.info('\n'.join(msg_text), line=lineno) + messages.append(message) + try: + return self.interpreted_roles[canonical], messages + except KeyError: + raise UnknownInterpretedRoleError(messages) else: - atts = {} - return before, [nodes.interpreted(rawsource, text, **atts)], after, [] + return self.interpreted_roles[self.default_interpreted_role], [] def literal(self, match, lineno): before, inlines, remaining, sysmessages, endstring = self.inline_obj( @@ -983,6 +1084,37 @@ class Inliner: '_': reference, '__': anonymous_reference} + def title_reference_role(self, role, rawtext, text, lineno): + return [nodes.title_reference(rawtext, text)], [] + + def pep_reference_role(self, role, rawtext, text, lineno): + try: + pepnum = int(text) + if pepnum < 0 or pepnum > 9999: + raise ValueError + except ValueError: + msg = self.reporter.error( + 'PEP number must be a number from 0 to 9999; "%s" is invalid.' + % text, line=lineno) + prb = self.problematic(text, text, msg) + return [prb], [msg] + ref = self.pep_url % pepnum + return [nodes.reference(rawtext, 'PEP ' + text, refuri=ref)], [] + + def rfc_reference_role(self, role, rawtext, text, lineno): + try: + rfcnum = int(text) + if rfcnum <= 0: + raise ValueError + except ValueError: + msg = self.reporter.error( + 'RFC number must be a number greater than or equal to 1; ' + '"%s" is invalid.' % text, line=lineno) + prb = self.problematic(text, text, msg) + return [prb], [msg] + ref = self.rfc_url % rfcnum + return [nodes.reference(rawtext, 'RFC ' + text, refuri=ref)], [] + class Body(RSTState): -- cgit v1.2.1 From d95ba708da2b525259ed786ab17eeb1f5830a112 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 10 Jan 2003 02:13:10 +0000 Subject: Added interpreted text roles mapping. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1079 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/en.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index 0d5e0da34..60bd8b733 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -44,3 +44,33 @@ directives = { 'restructuredtext-test-directive': 'restructuredtext-test-directive'} """English name to registered (in directives/__init__.py) directive name mapping.""" + +roles = { + 'abbreviation': 'abbreviation', + 'ab': 'abbreviation', + 'acronym': 'acronym', + 'ac': 'acronym', + 'index': 'index', + 'i': 'index', + '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', + } +"""Mapping of English role names to canonical role names for interpreted text. +""" -- cgit v1.2.1 From ba91c4e02e64fad0bd15e8b93579674b25e2b9cd Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 10 Jan 2003 02:13:58 +0000 Subject: Removed "interpreted" element support. Added support for "title_reference" element. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1080 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 855d78895..cf7bacf23 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -719,14 +719,6 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_important(self, node): 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): - self.body.append('</span>') - def visit_label(self, node): self.body.append(self.starttag(node, 'td', '%s[' % self.context.pop(), CLASS='label')) @@ -1074,6 +1066,12 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_title(self, node): self.body.append(self.context.pop()) + def visit_title_reference(self, node): + self.body.append(self.starttag(node, 'cite', '')) + + def depart_title_reference(self, node): + self.body.append('</cite>') + def visit_topic(self, node): self.body.append(self.starttag(node, 'div', CLASS='topic')) self.topic_class = node.get('class') -- cgit v1.2.1 From d5a43d9bb3e0e052c1b83cb66e2360b23be520bd Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 10 Jan 2003 23:28:26 +0000 Subject: real fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1094 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/utils.py b/docutils/utils.py index eb3dc4932..0ab9f27e0 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -405,7 +405,7 @@ def relative_path(source, target): If there is no common prefix, return the absolute path to `target`. """ - source_parts = os.path.abspath(source or '').split(os.sep) + source_parts = os.path.abspath(source or 'dummy_file').split(os.sep) target_parts = os.path.abspath(target).split(os.sep) # Check first 2 parts because '/dir'.split('/') == ['', 'dir']: if source_parts[:2] != target_parts[:2]: @@ -420,7 +420,7 @@ def relative_path(source, target): source_parts.pop() target_parts.pop() target_parts.reverse() - parts = ['..'] * len(source_parts) + target_parts + parts = ['..'] * (len(source_parts) - 1) + target_parts return '/'.join(parts) def get_source_line(node): -- cgit v1.2.1 From b203fb8fd7596191d692918697927f91fe3afe16 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 11 Jan 2003 22:39:52 +0000 Subject: clarified git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1130 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index cf7bacf23..eceb6ea47 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -34,7 +34,7 @@ class Writer(writers.Writer): 'HTML-Specific Options', None, (('Specify a stylesheet URL, used verbatim. Default is ' - '"default.css".', + '"default.css". Overridden by --stylesheet-path.', ['--stylesheet'], {'default': 'default.css', 'metavar': '<URL>'}), ('Specify a stylesheet file, relative to the current working ' -- cgit v1.2.1 From 3c59885646e7a7416b0f9d2a51417dcfb22a13ba Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 17 Jan 2003 19:07:39 +0000 Subject: fixed multiply-indirect reference bug (bug report: Bruce Smith) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1139 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index c757f39d3..bdc56ccfc 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -221,7 +221,7 @@ class IndirectHyperlinks(Transform): 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 + self.resolve_indirect_target(reftarget) # multiply indirect if reftarget.hasattr('refuri'): target['refuri'] = reftarget['refuri'] if target.hasattr('name'): -- cgit v1.2.1 From ce023f176856687f0329c4d3fcc22e6e320bc753 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 17 Jan 2003 19:45:54 +0000 Subject: Added check for circular indirect references. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1140 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index bdc56ccfc..5b1243ed5 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -221,7 +221,14 @@ class IndirectHyperlinks(Transform): reftarget = self.document.ids[reftarget_id] if isinstance(reftarget, nodes.target) \ and not reftarget.resolved and reftarget.hasattr('refname'): + if hasattr(target, 'multiply_indirect'): + #and target.multiply_indirect): + #del target.multiply_indirect + self.circular_indirect_reference(target) + return + target.multiply_indirect = 1 self.resolve_indirect_target(reftarget) # multiply indirect + del target.multiply_indirect if reftarget.hasattr('refuri'): target['refuri'] = reftarget['refuri'] if target.hasattr('name'): @@ -241,6 +248,12 @@ class IndirectHyperlinks(Transform): reftarget.referenced = 1 def nonexistent_indirect_target(self, target): + self.indirect_target_error(target, 'which does not exist') + + def circular_indirect_reference(self, target): + self.indirect_target_error(target, 'forming a circular reference') + + def indirect_target_error(self, target, explanation): naming = '' if target.hasattr('name'): naming = '"%s" ' % target['name'] @@ -248,9 +261,9 @@ class IndirectHyperlinks(Transform): else: 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", ' - 'which does not exist.' % (naming, target['refname']), + msg = self.document.reporter.error( + 'Indirect hyperlink target %s refers to target "%s", %s.' + % (naming, target['refname'], explanation), base_node=target) msgid = self.document.set_id(msg) for ref in reflist: -- cgit v1.2.1 From c6a8b09215bf080177a35cbd1ad9154be6328970 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 21 Jan 2003 18:24:54 +0000 Subject: correction git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1151 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 2ddd50809..e7b5a91a7 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1974,7 +1974,7 @@ class Body(RSTState): arguments = self.parse_directive_arguments(argument_spec, arg_block) if content and not content_spec: - raise MarkupError('no content permitted.') + raise MarkupError('no content permitted') except MarkupError, detail: error = self.reporter.error( 'Error in "%s" directive:\n%s.' % (type_name, detail), -- cgit v1.2.1 From 22a29d348c7ca6a4d8f0d080f3edd07e7397eec5 Mon Sep 17 00:00:00 2001 From: chodorowski <chodorowski@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 28 Jan 2003 18:15:19 +0000 Subject: Translated some more terms. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1155 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/sv.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/sv.py b/docutils/parsers/rst/languages/sv.py index 9686194df..419ea4257 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -32,12 +32,11 @@ directives = { # u'bildkarta': 'imagemap', # FIXME: Translation might be too literal. u'bild': 'image', u'figur': 'figure', - 'include (translation required)': 'include', + u'inkludera': 'include', u'r\u00e5': 'raw', # FIXME: Translation might be too literal. - 'replace (translation required)': 'replace', + u'ers\u00e4tt': 'replace', u'inneh\u00e5ll': 'contents', - 'sectnum (translation required)': 'sectnum', - 'section-numbering (translation required)': 'sectnum', + u'sektionsnumrering': 'sectnum', 'target-notes (translation required)': 'target-notes', # u'fotnoter': 'footnotes', # u'citeringar': 'citations', -- cgit v1.2.1 From c20a5143b933667b65436e21e5e5a24ef927cc6e Mon Sep 17 00:00:00 2001 From: fdrake <fdrake@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 4 Feb 2003 16:58:40 +0000 Subject: Add a source encoding declaration for Python 2.3; this avoids a compile-time warning for this file. I *think* Latin-1 is the right encoding; hopefully someone more knowledgable can confirm. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1160 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/de.py | 1 + 1 file changed, 1 insertion(+) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index 25e6c4dd6..78cbc1b0e 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -1,3 +1,4 @@ +# -*- coding: iso-8859-1 -*- # Author: Engelbert Gruber # Contact: grubert@users.sourceforge.net # Revision: $Revision$ -- cgit v1.2.1 From 9d4fcb00e8f6023b8ab16b20679198ffbd1acf45 Mon Sep 17 00:00:00 2001 From: pobrien <pobrien@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 20 Feb 2003 14:19:55 +0000 Subject: Added sidebar directive. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1193 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 18 ++++++++++++++++-- docutils/parsers/rst/directives/__init__.py | 1 + docutils/parsers/rst/directives/body.py | 27 +++++++++++++++++++++++++++ docutils/parsers/rst/languages/de.py | 1 + docutils/parsers/rst/languages/en.py | 1 + docutils/parsers/rst/languages/fr.py | 1 + docutils/parsers/rst/languages/it.py | 1 + docutils/parsers/rst/languages/sk.py | 1 + docutils/parsers/rst/languages/sv.py | 1 + docutils/writers/html4css1.py | 9 +++++++++ 10 files changed, 59 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index f1548e6b0..1788a273a 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -943,6 +943,20 @@ class footer(Decorative, Element): pass class section(Structural, Element): pass +class sidebar(Structural, Element): + + """ + Sidebars are terminal, "leaf" mini-sections, like block quotes with titles, + or textual figures. A sidebar is just like a section, except that it has no + subsections, and it doesn't have to conform to section placement rules. + + Sidebars are allowed wherever body elements (list, table, etc.) are + allowed, but only at the top level of a section or document. Sidebars + cannot nest inside sidebars or body elements; you can't have a sidebar + inside a table, list, block quote, etc. + """ + + class topic(Structural, Element): """ @@ -1182,8 +1196,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 sidebar status strong substitution_definition + substitution_reference subtitle system_message table target tbody term tgroup thead tip title title_reference topic transition version diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 4593d8f23..93461c1ed 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -92,6 +92,7 @@ _directive_registry = { 'tip': ('admonitions', 'tip'), 'hint': ('admonitions', 'hint'), 'warning': ('admonitions', 'warning'), + 'sidebar': ('body', 'sidebar'), 'topic': ('body', 'topic'), 'line-block': ('body', 'line_block'), 'parsed-literal': ('body', 'parsed_literal'), diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index 8bc2d7a4f..9793e0bc3 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -13,6 +13,7 @@ __docformat__ = 'reStructuredText' import sys from docutils import nodes +from docutils.parsers.rst import directives def topic(name, arguments, options, content, lineno, @@ -40,6 +41,32 @@ def topic(name, arguments, options, content, lineno, topic.arguments = (1, 0, 1) topic.content = 1 +def sidebar(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + if not state_machine.match_titles: + error = state_machine.reporter.error( + 'Sidebars may not be nested within sidebars 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) + text = '\n'.join(content) + sidebar_node = nodes.sidebar(text, title, *messages, **options) + if text: + state.nested_parse(content, content_offset, sidebar_node) + return [sidebar_node] + +sidebar.arguments = (1, 0, 1) +sidebar.options = {'subtitle': directives.unchanged} +sidebar.content = 1 + def line_block(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine, node_class=nodes.line_block): diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index 78cbc1b0e..fafb6f4fa 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -23,6 +23,7 @@ directives = { 'notiz': 'note', 'tip': 'tip', 'warnung': 'warning', + 'sidebar (translation required)': 'sidebar', 'topic': 'topic', # berbegriff 'line-block': 'line-block', 'parsed-literal': 'parsed-literal', diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index 60bd8b733..7d0976471 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -22,6 +22,7 @@ directives = { 'note': 'note', 'tip': 'tip', 'warning': 'warning', + 'sidebar': 'sidebar', 'topic': 'topic', 'line-block': 'line-block', 'parsed-literal': 'parsed-literal', diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index 19cdc5be8..4a7d85176 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -22,6 +22,7 @@ directives = { 'note (translation required)': 'note', 'tip (translation required)': 'tip', 'warning (translation required)': 'warning', + 'sidebar (translation required)': 'sidebar', 'topic (translation required)': 'topic', 'line-block (translation required)': 'line-block', 'parsed-literal (translation required)': 'parsed-literal', diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index fe7610eb0..93cba7936 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -22,6 +22,7 @@ directives = { 'nota': 'note', 'consiglio': 'tip', 'avvertenza': 'warning', + 'sidebar (translation required)': 'sidebar', 'argomento': 'topic', 'blocco di linee': 'line-block', 'parsed-literal': 'parsed-literal', diff --git a/docutils/parsers/rst/languages/sk.py b/docutils/parsers/rst/languages/sk.py index e88fda694..585bf934d 100644 --- a/docutils/parsers/rst/languages/sk.py +++ b/docutils/parsers/rst/languages/sk.py @@ -22,6 +22,7 @@ directives = { u'pozn\xe1mka': 'note', u'tip': 'tip', u'varovanie': 'warning', + u'sidebar (translation required)': 'sidebar', u't\xe9ma': 'topic', u'blok-riadkov': 'line-block', u'parsed-literal': 'parsed-literal', diff --git a/docutils/parsers/rst/languages/sv.py b/docutils/parsers/rst/languages/sv.py index 419ea4257..c63922c5e 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -21,6 +21,7 @@ directives = { u'notera': 'note', u'tips': 'tip', u'varning': 'warning', + u'sidebar (translation required)': 'sidebar', u'\u00e4mne': 'topic', 'line-block (translation required)': 'line-block', 'parsed-literal (translation required)': 'parsed-literal', diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index eceb6ea47..ab369cf1c 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -185,6 +185,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.compact_p = 1 self.compact_simple = None self.in_docinfo = None + self.in_sidebar = None def get_stylesheet_reference(self, relative_to=None): settings = self.settings @@ -908,6 +909,14 @@ class HTMLTranslator(nodes.NodeVisitor): self.section_level -= 1 self.body.append('</div>\n') + def visit_sidebar(self, node): + self.body.append(self.starttag(node, 'div', CLASS='sidebar')) + self.in_sidebar = 1 + + def depart_sidebar(self, node): + self.body.append('</div>\n') + self.in_sidebar = None + def visit_status(self, node): self.visit_docinfo_item(node, 'status', meta=None) -- cgit v1.2.1 From 100cbbd0266915f6b8708799f2729adeb3b75a25 Mon Sep 17 00:00:00 2001 From: pobrien <pobrien@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 20 Feb 2003 14:33:31 +0000 Subject: Fixed sidebar title handling. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1194 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index ab369cf1c..e65398d04 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -1054,6 +1054,15 @@ class HTMLTranslator(nodes.NodeVisitor): self.context.append('</a></p>\n') else: self.context.append('</p>\n') + elif isinstance(node.parent, nodes.sidebar): + self.body.append( + self.starttag(node, 'p', '', CLASS='sidebar-title')) + 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 813c817e2696f9eba43e10cd147ba4a04244a1d1 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 20 Feb 2003 22:35:49 +0000 Subject: sidebar improvements git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1196 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 33 ++++++++++++++------------ docutils/parsers/rst/directives/body.py | 41 +++++++++++++-------------------- docutils/parsers/rst/states.py | 3 ++- docutils/writers/html4css1.py | 10 ++++++-- 4 files changed, 44 insertions(+), 43 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 1788a273a..db38ae1e9 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -943,31 +943,34 @@ class footer(Decorative, Element): pass class section(Structural, Element): pass -class sidebar(Structural, Element): +class topic(Structural, Element): """ - Sidebars are terminal, "leaf" mini-sections, like block quotes with titles, - or textual figures. A sidebar is just like a section, except that it has no + 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. - Sidebars are allowed wherever body elements (list, table, etc.) are - allowed, but only at the top level of a section or document. Sidebars - cannot nest inside sidebars or body elements; you can't have a sidebar - inside a table, list, block quote, etc. + 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, sidebars, or body elements; you can't have a topic inside a + table, list, block quote, etc. """ -class topic(Structural, Element): +class sidebar(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. + Sidebars are like miniature, parallel documents that occur inside other + documents, providing related or reference material. A sidebar is + typically offset by a border and "floats" to the side of the page; the + document's main text may flow around it. Sidebars can also be likened to + super-footnotes; their content is outside of the flow of the document's + main text. - 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. + Sidebars are allowed wherever body elements (list, table, etc.) are + allowed, but only at the top level of a section or document. Sidebars + cannot nest inside sidebars, topics, or body elements; you can't have a + sidebar inside a table, list, block quote, etc. """ diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index 9793e0bc3..f24edb325 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -17,10 +17,12 @@ from docutils.parsers.rst import directives def topic(name, arguments, options, content, lineno, - content_offset, block_text, state, state_machine): + content_offset, block_text, state, state_machine, + node_class=nodes.topic): if not state_machine.match_titles: error = state_machine.reporter.error( - 'Topics may not be nested within topics or body elements.', + 'The "%s" directive may not be used within topics, sidebars, ' + 'or body elements.' % name, nodes.literal_block(block_text, block_text), line=lineno) return [error] if not content: @@ -31,37 +33,26 @@ def topic(name, arguments, options, content, lineno, return [warning] title_text = arguments[0] textnodes, messages = state.inline_text(title_text, lineno) - title = nodes.title(title_text, '', *textnodes) + titles = [nodes.title(title_text, '', *textnodes)] + if options.has_key('subtitle'): + textnodes, more_messages = state.inline_text(options['subtitle'], + lineno) + titles.append(nodes.subtitle(options['subtitle'], '', *textnodes)) + messages.extend(more_messages) text = '\n'.join(content) - topic_node = nodes.topic(text, title, *messages) + node = node_class(text, *(titles + messages)) if text: - state.nested_parse(content, content_offset, topic_node) - return [topic_node] + state.nested_parse(content, content_offset, node) + return [node] topic.arguments = (1, 0, 1) topic.content = 1 def sidebar(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): - if not state_machine.match_titles: - error = state_machine.reporter.error( - 'Sidebars may not be nested within sidebars 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) - text = '\n'.join(content) - sidebar_node = nodes.sidebar(text, title, *messages, **options) - if text: - state.nested_parse(content, content_offset, sidebar_node) - return [sidebar_node] + return topic(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine, + node_class=nodes.sidebar) sidebar.arguments = (1, 0, 1) sidebar.options = {'subtitle': directives.unchanged} diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index e7b5a91a7..d10b07a68 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -2147,7 +2147,8 @@ class Body(RSTState): 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) + blank_finish=blank_finish, + match_titles=self.state_machine.match_titles) self.goto_line(newline_offset) if not blank_finish: self.parent += self.unindent_warning('Explicit markup') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index e65398d04..fd42a061c 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -937,10 +937,16 @@ class HTMLTranslator(nodes.NodeVisitor): self.unimplemented_visit(node) def visit_subtitle(self, node): - self.body.append(self.starttag(node, 'h2', '', CLASS='subtitle')) + if isinstance(node.parent, nodes.sidebar): + self.body.append(self.starttag(node, 'p', '', + CLASS='sidebar-subtitle')) + self.context.append('

    \n') + else: + self.body.append(self.starttag(node, 'h2', '', CLASS='subtitle')) + self.context.append('\n') def depart_subtitle(self, node): - self.body.append('\n') + self.body.append(self.context.pop()) def visit_system_message(self, node): if node['level'] < self.document.reporter['writer'].report_level: -- cgit v1.2.1 From cb00118e698eeebcb601543046d5023d33fa8046 Mon Sep 17 00:00:00 2001 From: grubert Date: Mon, 24 Feb 2003 14:20:02 +0000 Subject: + moved latex writer into main line. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1202 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/__init__.py | 1 + docutils/writers/latex2e.py | 1296 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1297 insertions(+) create mode 100644 docutils/writers/latex2e.py (limited to 'docutils') diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index 675c45f18..d8183dc37 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -68,6 +68,7 @@ class Writer(Component): _writer_aliases = { 'html': 'html4css1', + 'latex': 'latex2e', 'pprint': 'pseudoxml', 'pformat': 'pseudoxml', 'pdf': 'rlpdf', diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py new file mode 100644 index 000000000..f1930f27b --- /dev/null +++ b/docutils/writers/latex2e.py @@ -0,0 +1,1296 @@ +#! /usr/bin/env python + +""" +: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' + +# convention deactivate code by two # e.g. ##. + +import sys +import time +import re +import string +from types import ListType +from docutils import writers, nodes, languages + +# country code by a.schlock. +# partly manually converted from iso and babel stuff, dialects and some +# languages remain missing (austrian, UKEnglish, brazillian etc.) +_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', + + 'de': 'ngerman', #XXX rather than german + 'el': 'greek', + 'en': 'english', + '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' + } + +class Writer(writers.Writer): + + supported = ('latex','latex2e') + """Formats this writer supports.""" + + settings_spec = ( + 'LaTeX-Specific Options', + 'The LaTeX "--output-encoding" default is "latin-1".', + (('Specify documentclass. Default is "article".', + ['--documentclass'], + {'default': 'article', }), + ('Format for footnote references: one of "superscript" or ' + '"brackets". Default is "superscript".', + ['--footnote-references'], + {'choices': ['superscript', 'brackets'], 'default': 'brackets', + 'metavar': ''}), + ('Link to the stylesheet in the output LaTeX file. This is the ' + 'default.', + ['--link-stylesheet'], + {'dest': 'embed_stylesheet', 'action': 'store_false'}), + ('Embed the stylesheet in the output LaTeX file. The stylesheet ' + 'file must be accessible during processing (--stylesheet-path is ' + 'recommended).', + ['--embed-stylesheet'], + {'action': 'store_true'}), + ('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}), + )) + + settings_default_overrides = {'output_encoding': 'latin-1'} + + output = None + """Final translated form of `document`.""" + + def translate(self): + visitor = LaTeXTranslator(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 +-------------- + +* Put labels inside environments:: + \chapter[optional]{title} + \label{lab} % optional, for cross referencing + text for this unit ... +* unnumbered sections are not written to tableofcontents. + a. donot print numbers:: + \renewcommand{\thesection}{} + b. use:: + \addcontentsline{file}{sec_unit}{entry} + file toc,lof lot + sec_unit section, subsection , ... + entry the line:: + \numberline text pagenumber + X. latex does not support multiple tocs in one document. + (might be no limitation except for docutils documentation) + +* sectioning:: + \part + \chapter (report style only) + \section + \subsection + \subsubsection + \paragraph + \subparagraph + \subsubparagraph (milstd and book-form styles only) + \subsubsubparagraph (milstd and book-form styles only) + +* documentclass options + + all notitlepage. + + article: 11pt, 12pt, twoside, twocolumn, draft, fleqn, leqno, acm + + report: 11pt, 12pt, twoside, twocolumn, draft, fleqn, leqno, acm + + letter: 11pt, 12pt, fleqn, leqno, acm + + book: 11pt, 12pt, twoside,twocolumn, draft, fleqn, leqno + +* width + + * linewidth - width of a line in the local environment + * textwidth - the width of text on the page + + Maybe always use linewidth ? +""" + +class Babel: + """Language specifics for LaTeX.""" + def __init__(self,lang): + self.language = lang + if re.search('^de',self.language): + self.quotes = ("\"`", "\"'") + 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 + +latex_headings = { + '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', + ] + } + + +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 + + ## For narrower things (tables, docinfos use admwidth in latex construct). + d_class = 'article' # document.settings.stylesheet + d_options = '10pt' # papersize, fontsize + d_paper = 'a4paper' + d_margins = '2cm' + d_stylesheet_path = 'style.tex' + # for pdflatex some other package. pslatex + + latex_head = '\\documentclass[%s]{%s}\n' + encoding = '\\usepackage[latin1]{inputenc}\n' + linking = '\\usepackage[colorlinks,linkcolor=blue]{hyperref}\n' + geometry = '\\usepackage[%s,margin=%s,nohead]{geometry}\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 + # table kind: if 0 tabularx (single page), 1 longtable + # maybe should be decided on row count. + use_longtable = 1 + # 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 + + def __init__(self, document): + nodes.NodeVisitor.__init__(self, document) + self.settings = settings = document.settings + self.use_latex_toc = settings.use_latex_toc + # 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] + if _ISO639_TO_BABEL.has_key(settings.language_code): + self.d_options += ',%s' % \ + _ISO639_TO_BABEL[settings.language_code] + self.head_prefix = [ + self.latex_head % (self.d_options,self.d_class), + '\\usepackage{babel}\n', # language is in documents settings. + '\\usepackage{shortvrb}\n', # allows verb in footnotes. + self.encoding, + # * tabularx: for docinfo, automatic width of columns, always on one page. + '\\usepackage{tabularx}\n', + '\\usepackage{longtable}\n', + # 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. + '\\usepackage{graphicx}\n', + '\\usepackage{color}\n', + '\\usepackage{multirow}\n', + self.linking, + # geometry and fonts might go into style.tex. + self.geometry % (self.d_paper, self.d_margins), + # + self.generator, + # admonition width and docinfo tablewidth + '\\newlength{\\admwidth}\n\\addtolength{\\admwidth}{0.9\\textwidth}\n', + # 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', + ] + self.head_prefix.extend( latex_headings['footnote_floats'] ) + ## stylesheet is last: so it might be possible to overwrite defaults. + self.head_prefix.append( + self.stylesheet % (self.d_stylesheet_path) ) + + if self.linking: # and maybe check for pdf + self.pdfinfo = [ ] + self.pdfauthor = None + # pdftitle, pdfsubject, pdfauthor, pdfkeywords, pdfcreator, pdfproducer + else: + self.pdfinfo = None + self.head = [] + self.body_prefix = ['\\raggedbottom\n'] + # separate title, so we can appen subtitle. + self.title = "" + self.body = [] + self.body_suffix = ['\n'] + self.section_level = 0 + self.context = [] + self.topic_class = '' + # column specification for tables + self.colspecs = [] + # verbatim: to tell encode not to encode. + self.verbatim = 0 + # insert_newline: to tell encode to add 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 + + def language_label(self, docutil_label): + return self.language.labels[docutil_label] + + 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 (really ?) + $ starts math- mode. + AND quotes: + + """ + if self.verbatim: + return text + # first the backslash + text = text.replace("\\", '{\\textbackslash}') + # then dollar + text = text.replace("$", '{\\$}') + # then all that needs math mode + text = text.replace("<", '{$<$}') + text = text.replace(">", '{$>$}') + # then + text = text.replace("&", '{\\&}') + text = text.replace("_", '{\\_}') + text = text.replace("^", '{\\verb|^|}') # ugly + text = text.replace("%", '{\\%}') + text = text.replace("#", '{\\#}') + text = text.replace("~", '{\\~{ }}') + t = None + for part in text.split('"'): + if t == None: + t = part + else: + t += self.babel.next_quote() + part + text = t + if self.insert_newline: + text = text.replace("\n", '\\\\\n') + elif self.mbox_newline: + text = text.replace("\n", '}\\\\\n\\mbox{') + text = text.replace(' ', '~') + # unicode !!! + text = text.replace(u'\u2020', '{$\\dagger$}') + 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: + if self.pdfauthor: + self.pdfinfo.append('pdfauthor={%s}' % self.pdfauthor) + pdfinfo = '\\hypersetup{\n' + ',\n'.join(self.pdfinfo) + '\n}\n' + else: + pdfinfo = '' + title = '\\title{%s}\n' % self.title + return ''.join(self.head_prefix + [title] + 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}\n'); + # alternatives: parbox or minipage. + # minpage has footnotes on the minipage. + # BUG there is no border. + self.body.append('\\parbox{\\admwidth}{\\textbf{' + + self.language.labels[name] + '}\n') + + def depart_admonition(self): + self.body.append('}\n') + self.body.append('\\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): + # ignore. visit_author is called for each one + # self.visit_docinfo_item(node, 'author') + pass + + def depart_authors(self, node): + # self.depart_docinfo_item(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 not self.use_latex_toc and self.topic_class == 'contents': + self.body.append( '\\begin{list}{}{}\n' ) + else: + self.body.append( '\\begin{itemize}\n' ) + + def depart_bullet_list(self, node): + if not self.use_latex_toc and self.topic_class == 'contents': + self.body.append( '\\end{list}\n' ) + else: + self.body.append( '\\end{itemize}\n' ) + + 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_citation(self, node): + self.visit_footnote(node) + + def depart_citation(self, node): + self.depart_footnote(node) + + def visit_title_reference(self, node): + # BUG title-references are what? + pass + + def depart_title_reference(self, node): + pass + + 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('[\\hyperlink{%s}{' % href) + + def depart_citation_reference(self, node): + 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): + if self.use_longtable: + self.colspecs.append(node) + else: + self.context[-1] += 1 + + def depart_colspec(self, node): + pass + + def visit_comment(self, node, + sub=re.compile('\n').sub): + """Escape end of line by a ne comment start in comment text.""" + self.body.append('%% %s \n' % sub('\n% ', node.astext())) + raise nodes.SkipNode + + def visit_contact(self, node): + self.visit_docinfo_item(node, 'contact') + + def depart_contact(self, node): + self.depart_docinfo_item(node) + + 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}{\\admwidth}{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 + if self.use_latex_toc: + self.body.append('\\tableofcontents\n\n\\bigskip\n') + + def visit_docinfo_item(self, node, name): + # should we stick to latex or docutils. + # latex article has its own handling of date and author. + # If we use it we get latexs language handling. + latex_docinfo = 0 + + if name == 'abstract': + # NOTE tableofcontents before or after ? + # eg after: depart_docinfo + # NOTE this limits abstract to text. + self.body.append('\\begin{abstract}\n') + self.context.append('\\end{abstract}\n') + self.context.append(self.body) + self.context.append(len(self.body)) + else: + self.docinfo.append('\\textbf{%s}: &\n\t' % self.language_label(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 latex_docinfo: + self.head.append('\\author{%s}\n' % self.attval(node.astext())) + raise nodes.SkipNode + else: + # avoid latexs maketitle generating one for us. + self.head.append('\\author{}\n') + elif name == 'date': + if latex_docinfo: + self.head.append('\\date{%s}\n' % self.attval(node.astext())) + raise nodes.SkipNode + else: + # avoid latexs maketitle generating one for us. + self.head.append("\\date{}\n") + 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)) + # \thanks is a footnote to the title. + + 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}' ) + + def depart_doctest_block(self, node): + self.body.append( '\\end{verbatim}\n' ) + + def visit_document(self, node): + self.body_prefix.append('\\begin{document}\n') + self.body_prefix.append('\\maketitle\n\n') + # alternative use titlepage environment. + # \begin{titlepage} + + def depart_document(self, node): + self.body_suffix.append('\\end{document}\n') + + def visit_emphasis(self, node): + self.body.append('\\emph{') + + def depart_emphasis(self, node): + self.body.append('}') + + def visit_entry(self, node): + # cell separation + column_one = 1 + if self.context[-1] > 0: + column_one = 0 + if not column_one: + self.body.append(' & ') + + # multi{row,column} + if node.has_key('morerows') and node.has_key('morecols'): + raise NotImplementedError('LaTeX can\'t handle cells that' + 'span multiple rows *and* columns, sorry.') + atts = {} + if node.has_key('morerows'): + count = node['morerows'] + 1 + self.body.append('\\multirow{%d}*{' % count) + self.context.append('}') + elif node.has_key('morecols'): + # the vertical bar before column is missing if it is the first column. + # the one after always. + if column_one: + bar = '|' + else: + bar = '' + count = node['morecols'] + 1 + self.body.append('\\multicolumn{%d}{%sl|}{' % (count, bar)) + self.context.append('}') + else: + self.context.append('') + + # header / not header + if isinstance(node.parent.parent, nodes.thead): + self.body.append('\\textbf{') + self.context.append('}') + else: + self.context.append('') + + def depart_entry(self, node): + self.body.append(self.context.pop()) # header / not header + self.body.append(self.context.pop()) # multirow/column + self.context[-1] += 1 + + 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_cnt += 1 + + enum_style = {'arabic':'arabic', + 'loweralpha':'alph', + 'upperalpha':'Alph', + 'lowerroman':'roman', + 'upperroman':'Roman' }; + enumtype = "arabic" + if node.has_key('enumtype'): + enumtype = node['enumtype'] + if enum_style.has_key(enumtype): + enumtype = enum_style[enumtype] + counter_name = "listcnt%d" % self._enum_cnt; + self.body.append('\\newcounter{%s}\n' % counter_name) + self.body.append('\\begin{list}{\\%s{%s}}\n' % (enumtype,counter_name)) + self.body.append('{\n') + self.body.append('\\usecounter{%s}\n' % counter_name) + # set start after usecounter, because it initializes to zero. + if node.has_key('start'): + self.body.append('\\addtocounter{%s}{%d}\n' \ + % (counter_name,node['start']-1)) + ## set rightmargin equal to leftmargin + self.body.append('\\setlength{\\rightmargin}{\\leftmargin}\n') + self.body.append('}\n') + + def depart_enumerated_list(self, node): + self.body.append('\\end{list}\n') + + def visit_error(self, node): + self.visit_admonition(node, 'error') + + def depart_error(self, node): + self.depart_admonition() + + def visit_field(self, node): + # real output is done in siblings: _argument, _body, _name + pass + + def depart_field(self, node): + self.body.append('\n') + ##self.body.append('%[depart_field]\n') + + def visit_field_argument(self, node): + self.body.append('%[visit_field_argument]\n') + + def depart_field_argument(self, node): + self.body.append('%[depart_field_argument]\n') + + def visit_field_body(self, node): + # BUG by attach as text we loose references. + if self.docinfo: + self.docinfo.append('%s \\\\\n' % node.astext()) + raise nodes.SkipNode + # what happens if not docinfo + + def depart_field_body(self, node): + self.body.append( '\n' ) + + def visit_field_list(self, node): + if not self.docinfo: + self.body.append('\\begin{quote}\n') + self.body.append('\\begin{description}\n') + + def depart_field_list(self, node): + if not self.docinfo: + self.body.append('\\end{description}\n') + self.body.append('\\end{quote}\n') + + def visit_field_name(self, node): + # BUG this duplicates docinfo_item + if self.docinfo: + self.docinfo.append('\\textbf{%s}: &\n\t' % node.astext()) + raise nodes.SkipNode + else: + self.body.append('\\item [') + + def depart_field_name(self, node): + if not self.docinfo: + self.body.append(':]') + + def visit_figure(self, node): + self.body.append( '\\begin{figure}\n' ) + + def depart_figure(self, node): + self.body.append( '\\end{figure}\n' ) + + def visit_footer(self, node): + self.context.append(len(self.body)) + + def depart_footer(self, node): + start = self.context.pop() + footer = (['\n\\begin{center}\small\n'] + + self.body[start:] + ['\n\\end{center}\n']) + self.body_suffix[:0] = footer + del self.body[start:] + + def visit_footnote(self, node): + notename = node['id'] + self.body.append('\\begin{figure}[b]') + self.body.append('\\hypertarget{%s}' % notename) + + def depart_footnote(self, node): + self.body.append('\\end{figure}\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']] + format = self.settings.footnote_references + if format == 'brackets': + suffix = '[' + self.context.append(']') + elif format == 'superscript': + suffix = '\\raisebox{.5em}[0em]{\\scriptsize' + self.context.append('}') + else: # shouldn't happen + raise AssertionError('Illegal footnote reference format.') + self.body.append('%s\\hyperlink{%s}{' % (suffix,href)) + + def depart_footnote_reference(self, node): + self.body.append('}%s' % 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() + self.body_prefix.append('\n\\verb|begin_header|\n') + self.body_prefix.extend(self.body[start:]) + self.body_prefix.append('\n\\verb|end_header|\n') + 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 = node.attributes.copy() + href = atts['uri'] + ##self.body.append('\\begin{center}\n') + self.body.append('\\includegraphics{%s}\n' % href) + ##self.body.append('\\end{center}\n') + + 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): + # @@@ Incomplete, pending a proper implementation on the + # Parser/Reader end. + self.visit_literal(node) + + def depart_interpreted(self, node): + self.depart_literal(node) + + def visit_label(self, node): + # footnote/citation label + self.body.append('[') + + def depart_label(self, node): + self.body.append(']') + + def visit_legend(self, node): + self.body.append('{\\small ') + + def depart_legend(self, node): + self.body.append('}') + + def visit_line_block(self, node): + """line-block: + * whitespace (including linebreaks) is significant + * inline markup is supported. + * serif typeface""" + self.mbox_newline = 1 + self.body.append('\\begin{flushleft}\n\\mbox{') + + def depart_line_block(self, node): + self.body.append('}\n\\end{flushleft}\n') + self.mbox_newline = 0 + + def visit_list_item(self, node): + self.body.append('\\item ') + + def depart_list_item(self, node): + self.body.append('\n') + + def visit_literal(self, node): + self.body.append('\\texttt{') + + def depart_literal(self, node): + self.body.append('}') + + def visit_literal_block(self, node): + self.use_verbatim_for_literal = 1 + if (self.use_verbatim_for_literal): + self.verbatim = 1 + self.body.append('\\begin{quote}\n') + self.body.append('\\begin{verbatim}\n') + else: + self.body.append('{\\obeylines\\obeyspaces\\ttfamily\n') + + def depart_literal_block(self, node): + if self.use_verbatim_for_literal: + self.body.append('\n\\end{verbatim}\n') + self.body.append('\\end{quote}\n') + self.verbatim = 0 + else: + self.body.append('}\n') + + def visit_meta(self, node): + self.body.append('[visit_meta]\n') + # BUG maybe set keywords for pdf + ##self.head.append(self.starttag(node, 'meta', **node.attributes)) + + def depart_meta(self, node): + self.body.append('[depart_meta]\n') + + 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]: + # this is not the first option + self.body.append(', ') + + def depart_option(self, node): + # flag tha the first option is done. + self.context[-1] += 1 + + def visit_option_argument(self, node): + """The delimiter betweeen an option and its argument.""" + self.body.append(node.get('delimiter', ' ')) + + def depart_option_argument(self, node): + pass + + def visit_option_group(self, node): + if self.use_optionlist_for_option_list: + self.body.append('\\item [') + else: + atts = {} + if len(node.astext()) > 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): + if not self.topic_class == 'contents': + self.body.append('\n') + + def depart_paragraph(self, node): + if self.topic_class == 'contents': + self.body.append('\n') + else: + 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 node.has_key('format') and node['format'].lower() == 'latex': + self.body.append(node.astext()) + raise nodes.SkipNode + + def visit_reference(self, node): + # for pdflatex hyperrefs might be supported + if node.has_key('refuri'): + href = node['refuri'] + elif node.has_key('refid'): + href = '#' + node['refid'] + elif node.has_key('refname'): + href = '#' + self.document.nameids[node['refname']] + ##self.body.append('[visit_reference]') + self.body.append('\\href{%s}{' % href) + + def depart_reference(self, node): + self.body.append('}') + ##self.body.append('[depart_reference]') + + def visit_revision(self, node): + self.visit_docinfo_item(node, 'revision') + + def depart_revision(self, node): + self.depart_docinfo_item(node) + + def visit_row(self, node): + self.context.append(0) + + def depart_row(self, node): + self.context.pop() # remove cell counter + self.body.append(' \\\\ \\hline\n') + + def visit_section(self, node): + self.section_level += 1 + + def depart_section(self, node): + self.section_level -= 1 + + 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{') + + def depart_strong(self, node): + self.body.append('}') + + def visit_substitution_definition(self, node): + raise nodes.SkipNode + + def visit_substitution_reference(self, node): + self.unimplemented_visit(node) + + def visit_subtitle(self, node): + self.title = self.title + \ + '\\\\\n\\large{%s}\n' % self.encode(node.astext()) + raise nodes.SkipNode + + def depart_subtitle(self, node): + pass + + def visit_system_message(self, node): + if node['level'] < self.document.reporter['writer'].report_level: + raise nodes.SkipNode + + + def depart_system_message(self, node): + self.body.append('\n') + + def get_colspecs(self): + """ + Return column specification for longtable. + + The width is scaled down by 93%. We do it here + because the we can use linewidth which should be the local + width. + """ + width = 0 + for node in self.colspecs: + width += node['colwidth'] + s = "" + for node in self.colspecs: + colwidth = 0.93 * float(node['colwidth']) / width + s += "|p{%.2f\\linewidth}" % colwidth + self.colspecs = [] + return s+"|" + + def visit_table(self, node): + if self.use_longtable: + self.body.append('\n\\begin{longtable}[c]') + else: + self.body.append('\n\\begin{tabularx}{\\linewidth}') + self.context.append('table_sentinel') # sentinel + self.context.append(0) # column counter + + def depart_table(self, node): + if self.use_longtable: + self.body.append('\\end{longtable}\n') + else: + self.body.append('\\end{tabularx}\n') + sentinel = self.context.pop() + if sentinel != 'table_sentinel': + print 'context:', self.context + [sentinel] + raise AssertionError + + def table_preamble(self): + if self.use_longtable: + self.body.append('{%s}\n' % self.get_colspecs()) + else: + if self.context[-1] != 'table_sentinel': + self.body.append('{%s}' % ('|X' * self.context.pop() + '|')) + self.body.append('\n\\hline') + + def visit_target(self, node): + if not (node.has_key('refuri') or node.has_key('refid') + or node.has_key('refname')): + self.body.append('\\hypertarget{%s}{' % node['name']) + self.context.append('}') + 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 len(self.colspecs) > 0: + self.visit_thead(None) + self.depart_thead(None) + self.body.append('%[visit_tbody]\n') + + def depart_tbody(self, node): + self.body.append('%[depart_tbody]\n') + + def visit_term(self, node): + self.body.append('\\item[') + + def depart_term(self, node): + # definition list term. + self.body.append(':]\n') + + 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): + # number_of_columns will be zero after get_colspecs. + # BUG ! push onto context for depart to pop it. + number_of_columns = len(self.colspecs) + self.table_preamble() + #BUG longtable needs firstpage and lastfooter too. + self.body.append('\\hline\n') + + def depart_thead(self, node): + if self.use_longtable: + # the table header written should be on every page + # => \endhead + self.body.append('\\endhead\n') + # 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 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. + if node.parent.hasattr('id'): + self.body.append('\\hypertarget{%s}{}' % node.parent['id']) + self.body.append('\\begin{center}\n') + self.context.append('\\end{center}\n') + ## should this be section subsection or + self.body.append('\\subsection*{') + self.context.append('}\n') + 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') + if node.parent.hasattr('id'): + self.body.append('\\hypertarget{%s}{}\n' % node.parent['id']) + # section_level 0 is title and handled above. + # BUG: latex has no deeper sections (actually paragrah is no section either). + if self.use_latex_toc: + section_star = "" + else: + section_star = "*" + if (self.section_level<=3): # 1,2,3 + self.body.append('\\%ssection%s{' % ('sub'*(self.section_level-1),section_star)) + elif (self.section_level==4): + #self.body.append('\\paragraph*{') + self.body.append('\\subsubsection%s{' % (section_star)) + else: + #self.body.append('\\subparagraph*{') + self.body.append('\\subsubsection%s{' % (section_star)) + # BUG: self.body.append( '\\label{%s}\n' % name) + self.context.append('}\n') + + def depart_title(self, node): + self.body.append(self.context.pop()) + if isinstance(node.parent, nodes.topic): + self.body.append(self.context.pop()) + # BUG level depends on style. + if node.parent.hasattr('id') and not self.use_latex_toc: + # 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 + self.body.append('\\pdfbookmark[%d]{%s}{%s}\n' % \ + (l,node.astext(),node.parent['id'])) + + def visit_topic(self, node): + self.topic_class = node.get('class') + if self.use_latex_toc: + self.topic_class = '' + raise nodes.SkipNode + + def depart_topic(self, node): + self.topic_class = '' + self.body.append('\n') + + 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): + #self.body.append('[depart_transition]') + 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 : -- cgit v1.2.1 From 7d61997fa018d4c0bae1800bdc271ef0702a540a Mon Sep 17 00:00:00 2001 From: grubert Date: Sun, 2 Mar 2003 09:46:33 +0000 Subject: FIX: docinfo attribute does not exist when no document info is present. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1208 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index f1930f27b..4ef2b8969 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -306,6 +306,8 @@ class LaTeXTranslator(nodes.NodeVisitor): self.mbox_newline = 0 # enumeration is done by list environment. self._enum_cnt = 0 + # docinfo. + self.docinfo = None def language_label(self, docutil_label): return self.language.labels[docutil_label] @@ -737,7 +739,7 @@ class LaTeXTranslator(nodes.NodeVisitor): if self.docinfo: self.docinfo.append('%s \\\\\n' % node.astext()) raise nodes.SkipNode - # what happens if not docinfo + # BUG: what happens if not docinfo def depart_field_body(self, node): self.body.append( '\n' ) -- cgit v1.2.1 From 551651c2f7c60702651834c5a68595efbf945cdb Mon Sep 17 00:00:00 2001 From: grubert Date: Mon, 3 Mar 2003 11:00:31 +0000 Subject: Always emit empty date and author for latex. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1212 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 4ef2b8969..96c6b5808 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -287,7 +287,13 @@ class LaTeXTranslator(nodes.NodeVisitor): # pdftitle, pdfsubject, pdfauthor, pdfkeywords, pdfcreator, pdfproducer else: self.pdfinfo = None - self.head = [] + # 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. + self.latex_docinfo = 0 + self.head = [ ] + if not self.latex_docinfo: + self.head.extend( [ '\\author{}\n', '\\date{}\n' ] ) self.body_prefix = ['\\raggedbottom\n'] # separate title, so we can appen subtitle. self.title = "" @@ -367,9 +373,10 @@ class LaTeXTranslator(nodes.NodeVisitor): pdfinfo = '\\hypersetup{\n' + ',\n'.join(self.pdfinfo) + '\n}\n' else: pdfinfo = '' - title = '\\title{%s}\n' % self.title - return ''.join(self.head_prefix + [title] + self.head + [pdfinfo] - + self.body_prefix + self.body + self.body_suffix) + title = '\\title{%s}\n' % self.title + return ''.join(self.head_prefix + [title] + + self.head + [pdfinfo] + + self.body_prefix + self.body + self.body_suffix) def visit_Text(self, node): self.body.append(self.encode(node.astext())) @@ -566,9 +573,6 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_docinfo_item(self, node, name): # should we stick to latex or docutils. - # latex article has its own handling of date and author. - # If we use it we get latexs language handling. - latex_docinfo = 0 if name == 'abstract': # NOTE tableofcontents before or after ? @@ -579,26 +583,21 @@ class LaTeXTranslator(nodes.NodeVisitor): self.context.append(self.body) self.context.append(len(self.body)) else: - self.docinfo.append('\\textbf{%s}: &\n\t' % self.language_label(name)) + if not self.latex_docinfo: + self.docinfo.append('\\textbf{%s}: &\n\t' % self.language_label(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 latex_docinfo: + if self.latex_docinfo: self.head.append('\\author{%s}\n' % self.attval(node.astext())) raise nodes.SkipNode - else: - # avoid latexs maketitle generating one for us. - self.head.append('\\author{}\n') elif name == 'date': - if latex_docinfo: + if self.latex_docinfo: self.head.append('\\date{%s}\n' % self.attval(node.astext())) raise nodes.SkipNode - else: - # avoid latexs maketitle generating one for us. - self.head.append("\\date{}\n") if name == 'address': self.insert_newline = 1 self.docinfo.append('{\\raggedright\n') -- cgit v1.2.1 From 5724e79e9320f2a3fccfa5609e33395afed4fc23 Mon Sep 17 00:00:00 2001 From: grubert Date: Tue, 11 Mar 2003 08:17:35 +0000 Subject: Change literal_block: no more verbatim to allow inline makup. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1215 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 96c6b5808..893e68607 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -893,19 +893,32 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('}') def visit_literal_block(self, node): - self.use_verbatim_for_literal = 1 - if (self.use_verbatim_for_literal): + """ + .. parsed-literal:: + """ + # typically in a typewriter/monospaced typeface. + # care must be taken with the text, because inline markup is recognized. + # + # possibilities: + # * verbatim: is no possibility, as inline markup does not work. + # * obey..: is from julien and never worked for me (grubert). + self.use_for_literal_block = "mbox" + if (self.use_for_literal_block == "verbatim"): self.verbatim = 1 - self.body.append('\\begin{quote}\n') self.body.append('\\begin{verbatim}\n') + elif (self.use_for_literal_block == "mbox"): + self.mbox_newline = 1 + self.body.append('\\ttfamily{\\begin{flushleft}\n\\mbox{') else: self.body.append('{\\obeylines\\obeyspaces\\ttfamily\n') def depart_literal_block(self, node): - if self.use_verbatim_for_literal: + if self.use_for_literal_block == "verbatim": self.body.append('\n\\end{verbatim}\n') - self.body.append('\\end{quote}\n') self.verbatim = 0 + elif (self.use_for_literal_block == "mbox"): + self.body.append('}\n\\end{flushleft}}\n') + self.mbox_newline = 0 else: self.body.append('}\n') -- cgit v1.2.1 From 4001ff9fed940cf2aadbce3e72bc00503fad81eb Mon Sep 17 00:00:00 2001 From: grubert Date: Fri, 14 Mar 2003 14:58:19 +0000 Subject: FIX: brace protection for literal-blocks. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1217 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 893e68607..decd1a517 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -116,22 +116,30 @@ Notes on LaTeX -------------- * Put labels inside environments:: + \chapter[optional]{title} \label{lab} % optional, for cross referencing text for this unit ... + * unnumbered sections are not written to tableofcontents. a. donot print numbers:: + \renewcommand{\thesection}{} b. use:: + \addcontentsline{file}{sec_unit}{entry} + file toc,lof lot sec_unit section, subsection , ... entry the line:: + \numberline text pagenumber + X. latex does not support multiple tocs in one document. (might be no limitation except for docutils documentation) * sectioning:: + \part \chapter (report style only) \section @@ -331,8 +339,19 @@ class LaTeXTranslator(nodes.NodeVisitor): """ if self.verbatim: return text - # first the backslash - text = text.replace("\\", '{\\textbackslash}') + # 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'(? Date: Tue, 18 Mar 2003 12:13:27 +0000 Subject: borders for admonitions (thanks to g schwant). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1218 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index decd1a517..68f125157 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -410,16 +410,15 @@ class LaTeXTranslator(nodes.NodeVisitor): self.depart_docinfo_item(node) def visit_admonition(self, node, name): - self.body.append('\\begin{center}\n'); - # alternatives: parbox or minipage. - # minpage has footnotes on the minipage. - # BUG there is no border. - self.body.append('\\parbox{\\admwidth}{\\textbf{' - + self.language.labels[name] + '}\n') + self.body.append('\\begin{center}\\begin{sffamily}\n') + self.body.append('\\fbox{\\parbox{\\admwidth}{\n') + self.body.append('\\textbf{\\large '+ self.language.labels[name] + '}\n'); + self.body.append('\\vspace{2mm}\n') + def depart_admonition(self): - self.body.append('}\n') - self.body.append('\\end{center}\n'); + 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') -- cgit v1.2.1 From 4d86cd33b11fb73d3e7ed89d20e1e270ac67790e Mon Sep 17 00:00:00 2001 From: grubert Date: Tue, 18 Mar 2003 12:38:18 +0000 Subject: ^ by mathmode wedge (verb|^| did not work in mbox). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1219 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 68f125157..da43075c2 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -360,7 +360,10 @@ class LaTeXTranslator(nodes.NodeVisitor): # then text = text.replace("&", '{\\&}') text = text.replace("_", '{\\_}') - text = text.replace("^", '{\\verb|^|}') # ugly + # the ^: + # * verb|^| does not work in mbox. + # * mathmode has wedge. hat{~} would also work. + text = text.replace("^", '{\\ensuremath{^\\wedge}}') text = text.replace("%", '{\\%}') text = text.replace("#", '{\\#}') text = text.replace("~", '{\\~{ }}') -- cgit v1.2.1 From 79e76dc959555d012c0c66cd7084be0594f59c33 Mon Sep 17 00:00:00 2001 From: grubert Date: Thu, 20 Mar 2003 09:08:12 +0000 Subject: FIX: (hack) around latex choking on abstract. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1220 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index da43075c2..8e0d4a9a1 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1240,9 +1240,16 @@ class LaTeXTranslator(nodes.NodeVisitor): if node.parent.hasattr('id'): self.body.append('\\hypertarget{%s}{}' % node.parent['id']) self.body.append('\\begin{center}\n') - self.context.append('\\end{center}\n') + # BUG: latex chokes: perhaps a missing item. + self.context.append('% HACK: latex chokes: -- perhaps a missing item.\n' + '\\begin{list}{ }{' + '\\setlength{\\topsep}{0pt}' + '\\setlength{\\itemsep}{-1cm}}' + '\\item \\item \\end{list}\n' + '\\end{center}\n') ## should this be section subsection or self.body.append('\\subsection*{') + # the closing brace for subsection. self.context.append('}\n') elif self.section_level == 0: # document title -- cgit v1.2.1 From 07650c09dd37f9ed4e5e181462f76b51a5d8dc24 Mon Sep 17 00:00:00 2001 From: grubert Date: Fri, 21 Mar 2003 13:40:00 +0000 Subject: remove unused latex abstract construct. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1223 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 59 ++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 35 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 8e0d4a9a1..5f115dfe9 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -593,41 +593,30 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('\\tableofcontents\n\n\\bigskip\n') def visit_docinfo_item(self, node, name): - # should we stick to latex or docutils. - - if name == 'abstract': - # NOTE tableofcontents before or after ? - # eg after: depart_docinfo - # NOTE this limits abstract to text. - self.body.append('\\begin{abstract}\n') - self.context.append('\\end{abstract}\n') - self.context.append(self.body) - self.context.append(len(self.body)) - else: - if not self.latex_docinfo: - self.docinfo.append('\\textbf{%s}: &\n\t' % self.language_label(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.latex_docinfo: - self.head.append('\\author{%s}\n' % self.attval(node.astext())) - raise nodes.SkipNode - elif name == 'date': - if self.latex_docinfo: - self.head.append('\\date{%s}\n' % self.attval(node.astext())) - raise nodes.SkipNode - 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)) - # \thanks is a footnote to the title. + if not self.latex_docinfo: + self.docinfo.append('\\textbf{%s}: &\n\t' % self.language_label(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.latex_docinfo: + self.head.append('\\author{%s}\n' % self.attval(node.astext())) + raise nodes.SkipNode + elif name == 'date': + if self.latex_docinfo: + self.head.append('\\date{%s}\n' % self.attval(node.astext())) + raise nodes.SkipNode + if name == 'address': + # BUG will fail if latex_docinfo is set. + 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() -- cgit v1.2.1 From 639d46d0fb21b77cf936524ff5e917a36a1b37a8 Mon Sep 17 00:00:00 2001 From: grubert Date: Fri, 21 Mar 2003 14:00:15 +0000 Subject: exchange the empty list hack for centering titles with hfill. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1224 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 5f115dfe9..fbf259ee5 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1228,18 +1228,11 @@ class LaTeXTranslator(nodes.NodeVisitor): # section titles before the table of contents. if node.parent.hasattr('id'): self.body.append('\\hypertarget{%s}{}' % node.parent['id']) - self.body.append('\\begin{center}\n') - # BUG: latex chokes: perhaps a missing item. - self.context.append('% HACK: latex chokes: -- perhaps a missing item.\n' - '\\begin{list}{ }{' - '\\setlength{\\topsep}{0pt}' - '\\setlength{\\itemsep}{-1cm}}' - '\\item \\item \\end{list}\n' - '\\end{center}\n') - ## should this be section subsection or - self.body.append('\\subsection*{') + # BUG: latex chokes on center environment with "perhaps a missing item". + # so we use hfill. + self.body.append('\\subsection*{~\\hfill ') # the closing brace for subsection. - self.context.append('}\n') + self.context.append('\\hfill ~}\n') elif self.section_level == 0: # document title self.title = self.encode(node.astext()) @@ -1271,8 +1264,6 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_title(self, node): self.body.append(self.context.pop()) - if isinstance(node.parent, nodes.topic): - self.body.append(self.context.pop()) # BUG level depends on style. if node.parent.hasattr('id') and not self.use_latex_toc: # pdflatex allows level 0 to 3 -- cgit v1.2.1 From 14d71fdb718770f67d5ed764c5cb984f5a71c3dc Mon Sep 17 00:00:00 2001 From: grubert Date: Fri, 21 Mar 2003 14:11:15 +0000 Subject: dot after enumeration counters. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1225 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index fbf259ee5..e8d38ebf2 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -709,7 +709,7 @@ class LaTeXTranslator(nodes.NodeVisitor): enumtype = enum_style[enumtype] counter_name = "listcnt%d" % self._enum_cnt; self.body.append('\\newcounter{%s}\n' % counter_name) - self.body.append('\\begin{list}{\\%s{%s}}\n' % (enumtype,counter_name)) + self.body.append('\\begin{list}{\\%s{%s}.}\n' % (enumtype,counter_name)) self.body.append('{\n') self.body.append('\\usecounter{%s}\n' % counter_name) # set start after usecounter, because it initializes to zero. -- cgit v1.2.1 From 3cf105681c70001de69a7bc12e5d77dee6329e61 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 22 Mar 2003 06:02:17 +0000 Subject: support & docs for character-level inline markup git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1226 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index d10b07a68..68b3b6853 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -2820,8 +2820,13 @@ def escape2null(text): start = found + 2 # skip character after escape def unescape(text, restore_backslashes=0): - """Return a string with nulls removed or restored to backslashes.""" + """ + Return a string with nulls removed or restored to backslashes. + Backslash-escaped spaces are also removed. + """ if restore_backslashes: return text.replace('\x00', '\\') else: - return ''.join(text.split('\x00')) + for sep in ['\x00 ', '\x00\n', '\x00']: + text = ''.join(text.split(sep)) + return text -- cgit v1.2.1 From 7136258d4d66f37fbc63bb6d95b3a8369066ac7e Mon Sep 17 00:00:00 2001 From: grubert Date: Mon, 24 Mar 2003 09:29:54 +0000 Subject: support stylesheet and stylesheet-path. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1230 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index e8d38ebf2..c7812a85e 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -82,6 +82,17 @@ class Writer(writers.Writer): ['--footnote-references'], {'choices': ['superscript', 'brackets'], 'default': 'brackets', 'metavar': ''}), + ('Specify a stylesheet file. The file will be "input" by latex ' + 'in the document header. Default is "style.tex". ' + 'If this is set to "" disables input.' + 'Overridden by --stylesheet-path.', + ['--stylesheet'], + {'default': 'style.tex', 'metavar': ''}), + ('Specify a stylesheet file, relative to the current working ' + 'directory.' + 'Overrides --stylesheet.', + ['--stylesheet-path'], + {'metavar': ''}), ('Link to the stylesheet in the output LaTeX file. This is the ' 'default.', ['--link-stylesheet'], @@ -212,8 +223,6 @@ class LaTeXTranslator(nodes.NodeVisitor): d_options = '10pt' # papersize, fontsize d_paper = 'a4paper' d_margins = '2cm' - d_stylesheet_path = 'style.tex' - # for pdflatex some other package. pslatex latex_head = '\\documentclass[%s]{%s}\n' encoding = '\\usepackage[latin1]{inputenc}\n' @@ -286,8 +295,9 @@ class LaTeXTranslator(nodes.NodeVisitor): ] self.head_prefix.extend( latex_headings['footnote_floats'] ) ## stylesheet is last: so it might be possible to overwrite defaults. - self.head_prefix.append( - self.stylesheet % (self.d_stylesheet_path) ) + stylesheet = self.get_stylesheet_reference() + if stylesheet: + self.head_prefix.append(self.stylesheet % (stylesheet)) if self.linking: # and maybe check for pdf self.pdfinfo = [ ] @@ -323,6 +333,12 @@ class LaTeXTranslator(nodes.NodeVisitor): # docinfo. self.docinfo = None + def get_stylesheet_reference(self): + if self.settings.stylesheet_path: + return self.settings.stylesheet_path + else: + return self.settings.stylesheet + def language_label(self, docutil_label): return self.language.labels[docutil_label] -- cgit v1.2.1 From 7cbcaaf26a56bb809200414ef2c52f622605469e Mon Sep 17 00:00:00 2001 From: grubert Date: Tue, 25 Mar 2003 09:04:00 +0000 Subject: no treatment of quotes inside literal-blocks. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1232 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 78 ++++++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 33 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index c7812a85e..20c8a8ac7 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -196,7 +196,28 @@ class Babel: 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 + 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', + ], 'footnote_floats' : [ '% begin: floats for footnotes tweaking.\n', '\\setlength{\\floatsep}{0.5em}\n', @@ -281,18 +302,8 @@ class LaTeXTranslator(nodes.NodeVisitor): self.generator, # admonition width and docinfo tablewidth '\\newlength{\\admwidth}\n\\addtolength{\\admwidth}{0.9\\textwidth}\n', - # 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', ] + self.head_prefix.extend( latex_headings['optionlist_environment'] ) self.head_prefix.extend( latex_headings['footnote_floats'] ) ## stylesheet is last: so it might be possible to overwrite defaults. stylesheet = self.get_stylesheet_reference() @@ -332,6 +343,8 @@ class LaTeXTranslator(nodes.NodeVisitor): self._enum_cnt = 0 # docinfo. self.docinfo = None + # inside literal block: no quote mangling. + self.literal_block = 0 def get_stylesheet_reference(self): if self.settings.stylesheet_path: @@ -383,13 +396,8 @@ class LaTeXTranslator(nodes.NodeVisitor): text = text.replace("%", '{\\%}') text = text.replace("#", '{\\#}') text = text.replace("~", '{\\~{ }}') - t = None - for part in text.split('"'): - if t == None: - t = part - else: - t += self.babel.next_quote() + part - text = t + if not self.literal_block: + text = self.babel.quote_quotes(text) if self.insert_newline: text = text.replace("\n", '\\\\\n') elif self.mbox_newline: @@ -717,15 +725,23 @@ class LaTeXTranslator(nodes.NodeVisitor): 'loweralpha':'alph', 'upperalpha':'Alph', 'lowerroman':'roman', - 'upperroman':'Roman' }; - enumtype = "arabic" + 'upperroman':'Roman' } + enum_suffix = "" + if node.has_key('suffix'): + enum_suffix = node['suffix'] + enum_prefix = "" + if node.has_key('prefix'): + enum_prefix = node['prefix'] + + enum_type = "arabic" if node.has_key('enumtype'): - enumtype = node['enumtype'] - if enum_style.has_key(enumtype): - enumtype = enum_style[enumtype] + enum_type = node['enumtype'] + if enum_style.has_key(enum_type): + enum_type = enum_style[enum_type] counter_name = "listcnt%d" % self._enum_cnt; self.body.append('\\newcounter{%s}\n' % counter_name) - self.body.append('\\begin{list}{\\%s{%s}.}\n' % (enumtype,counter_name)) + self.body.append('\\begin{list}{%s\\%s{%s}%s}\n' % \ + (enum_prefix,enum_type,counter_name,enum_suffix)) self.body.append('{\n') self.body.append('\\usecounter{%s}\n' % counter_name) # set start after usecounter, because it initializes to zero. @@ -929,24 +945,20 @@ class LaTeXTranslator(nodes.NodeVisitor): # * verbatim: is no possibility, as inline markup does not work. # * obey..: is from julien and never worked for me (grubert). self.use_for_literal_block = "mbox" - if (self.use_for_literal_block == "verbatim"): - self.verbatim = 1 - self.body.append('\\begin{verbatim}\n') - elif (self.use_for_literal_block == "mbox"): + self.literal_block = 1 + if (self.use_for_literal_block == "mbox"): self.mbox_newline = 1 self.body.append('\\begin{ttfamily}\\begin{flushleft}\n\\mbox{') else: self.body.append('{\\obeylines\\obeyspaces\\ttfamily\n') def depart_literal_block(self, node): - if self.use_for_literal_block == "verbatim": - self.body.append('\n\\end{verbatim}\n') - self.verbatim = 0 - elif (self.use_for_literal_block == "mbox"): + if (self.use_for_literal_block == "mbox"): self.body.append('}\n\\end{flushleft}\\end{ttfamily}\n') self.mbox_newline = 0 else: self.body.append('}\n') + self.literal_block = 0 def visit_meta(self, node): self.body.append('[visit_meta]\n') @@ -1131,7 +1143,7 @@ class LaTeXTranslator(nodes.NodeVisitor): Return column specification for longtable. The width is scaled down by 93%. We do it here - because the we can use linewidth which should be the local + because then we can use linewidth which should be the local width. """ width = 0 -- cgit v1.2.1 From 3d98a8e8eea73278c7c72eb907a4d20d99e24ee8 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 27 Mar 2003 00:21:21 +0000 Subject: fixed bibliographic field language lookups git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1234 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/de.py | 30 ++++++++++------------- docutils/languages/en.py | 31 ++++++++++-------------- docutils/languages/fr.py | 31 ++++++++++-------------- docutils/languages/it.py | 31 ++++++++++-------------- docutils/languages/sk.py | 31 ++++++++++-------------- docutils/languages/sv.py | 29 ++++++++++------------ docutils/transforms/frontmatter.py | 49 +++++++++++++++++++++++++------------- 7 files changed, 109 insertions(+), 123 deletions(-) (limited to 'docutils') diff --git a/docutils/languages/de.py b/docutils/languages/de.py index e5968dae3..9da99b67a 100644 --- a/docutils/languages/de.py +++ b/docutils/languages/de.py @@ -10,9 +10,6 @@ German language mappings for language-dependent features of Docutils. __docformat__ = 'reStructuredText' -from docutils import nodes - - labels = { 'author': 'Autor', 'authors': 'Autoren', @@ -39,20 +36,19 @@ labels = { """Mapping of node class name to label text.""" 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).""" + 'autor': 'author', + 'autoren': 'authors', + 'organisation': 'organization', + 'adresse': 'address', + 'kontakt': 'contact', + 'version': 'version', + 'revision': 'revision', + 'status': 'status', + 'datum': 'date', + 'copyright': 'copyright', + 'widmung': 'dedication', + 'zusammenfassung': 'abstract'} +"""German (lowcased) to canonical name mapping for bibliographic fields.""" author_separators = [';', ','] """List of separator strings for the 'Authors' bibliographic field. Tried in diff --git a/docutils/languages/en.py b/docutils/languages/en.py index 4ca94d632..066c77286 100644 --- a/docutils/languages/en.py +++ b/docutils/languages/en.py @@ -10,10 +10,6 @@ English-language mappings for language-dependent features of Docutils. __docformat__ = 'reStructuredText' - -from docutils import nodes - - labels = { 'author': 'Author', 'authors': 'Authors', @@ -40,20 +36,19 @@ labels = { """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': 'author', + 'authors': 'authors', + 'organization': 'organization', + 'address': 'address', + 'contact': 'contact', + 'version': 'version', + 'revision': 'revision', + 'status': 'status', + 'date': 'date', + 'copyright': 'copyright', + 'dedication': 'dedication', + 'abstract': 'abstract'} +"""English (lowcased) to canonical name mapping for bibliographic fields.""" author_separators = [';', ','] """List of separator strings for the 'Authors' bibliographic field. Tried in diff --git a/docutils/languages/fr.py b/docutils/languages/fr.py index cd3f40bc5..0ff327bec 100644 --- a/docutils/languages/fr.py +++ b/docutils/languages/fr.py @@ -10,10 +10,6 @@ French-language mappings for language-dependent features of Docutils. __docformat__ = 'reStructuredText' - -from docutils import nodes - - labels = { 'author': 'Auteur', 'authors': 'Auteurs', @@ -40,20 +36,19 @@ labels = { """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).""" + 'auteur': 'author', + 'auteurs': 'authors', + 'organisation': 'organization', + 'adresse': 'address', + 'contact': 'contact', + 'version': 'version', + 'r\u00e9vision': 'revision', + 'status': 'status', + 'date': 'date', + 'copyright': 'copyright', + 'd\u00e9dicace': 'dedication', + 'r\u00e9sum\u00e9': 'abstract'} +"""French (lowcased) to canonical name mapping for bibliographic fields.""" author_separators = [';', ','] """List of separator strings for the 'Authors' bibliographic field. Tried in diff --git a/docutils/languages/it.py b/docutils/languages/it.py index 101abeb96..1a59b5c7d 100644 --- a/docutils/languages/it.py +++ b/docutils/languages/it.py @@ -10,10 +10,6 @@ Italian-language mappings for language-dependent features of Docutils. __docformat__ = 'reStructuredText' - -from docutils import nodes - - labels = { 'author': 'Autore', 'authors': 'Autori', @@ -40,20 +36,19 @@ labels = { """Mapping of node class name to label text.""" bibliographic_fields = { - 'autore': nodes.author, - 'autori': nodes.authors, - 'organizzazione': nodes.organization, - 'indirizzo': nodes.address, - 'contatti': nodes.contact, - 'versione': nodes.version, - 'revisione': nodes.revision, - 'status': nodes.status, - 'data': nodes.date, - 'copyright': nodes.copyright, - 'dedica': nodes.topic, - 'riassunto': nodes.topic} -"""Field name (lowcased) to node class name mapping for bibliographic fields -(field_list).""" + 'autore': 'author', + 'autori': 'authors', + 'organizzazione': 'organization', + 'indirizzo': 'address', + 'contatti': 'contact', + 'versione': 'version', + 'revisione': 'revision', + 'status': 'status', + 'data': 'date', + 'copyright': 'copyright', + 'dedica': 'dedication', + 'riassunto': 'abstract'} +"""Italian (lowcased) to canonical name mapping for bibliographic fields.""" author_separators = [';', ','] """List of separator strings for the 'Authors' bibliographic field. Tried in diff --git a/docutils/languages/sk.py b/docutils/languages/sk.py index 49372d7ad..e57e3c8cf 100644 --- a/docutils/languages/sk.py +++ b/docutils/languages/sk.py @@ -10,10 +10,6 @@ Slovak-language mappings for language-dependent features of Docutils. __docformat__ = 'reStructuredText' - -from docutils import nodes - - labels = { 'author': u'Autor', 'authors': u'Autori', @@ -40,20 +36,19 @@ labels = { """Mapping of node class name to label text.""" bibliographic_fields = { - 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).""" + u'autor': 'author', + u'autori': 'authors', + u'organiz\u00E1cia': 'organization', + u'adresa': 'address', + u'kontakt': 'contact', + u'verzia': 'version', + u'rev\u00EDzia': 'revision', + u'stav': 'status', + u'd\u00E1tum': 'date', + u'copyright': 'copyright', + u'venovanie': 'dedication', + u'abstraktne': 'abstract'} +"""Slovak (lowcased) to canonical name mapping for bibliographic fields.""" author_separators = [';', ','] """List of separator strings for the 'Authors' bibliographic field. Tried in diff --git a/docutils/languages/sv.py b/docutils/languages/sv.py index c96f2c99d..55f25192f 100644 --- a/docutils/languages/sv.py +++ b/docutils/languages/sv.py @@ -10,10 +10,6 @@ Swedish language mappings for language-dependent features of Docutils. __docformat__ = 'reStructuredText' - -from docutils import nodes - - labels = { 'author': u'F\u00f6rfattare', 'authors': u'F\u00f6rfattare', @@ -41,19 +37,18 @@ labels = { bibliographic_fields = { # 'Author' and 'Authors' identical in Swedish; assume the plural: - 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, - 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).""" + u'f\u00f6rfattare': 'authors', + u'organisation': 'organization', + u'adress': 'address', + u'kontakt': 'contact', + u'version': 'version', + u'revision': 'revision', + u'status': 'status', + u'datum': 'date', + u'copyright': 'copyright', + u'dedikation': 'dedication', + u'sammanfattning': 'abstract' } +"""Swedish (lowcased) to canonical name mapping for bibliographic fields.""" author_separators = [';', ','] """List of separator strings for the 'Authors' bibliographic field. Tried in diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index 86cae9854..d1272ab15 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -229,6 +229,22 @@ class DocInfo(Transform): default_priority = 340 + biblio_nodes = { + 'author': nodes.author, + 'authors': nodes.authors, + 'organization': nodes.organization, + 'address': nodes.address, + 'contact': nodes.contact, + 'version': nodes.version, + 'revision': nodes.revision, + 'status': nodes.status, + 'date': nodes.date, + 'copyright': nodes.copyright, + 'dedication': nodes.topic, + 'abstract': nodes.topic} + """Canonical field name (lowcased) to node class name mapping for + bibliographic fields (field_list).""" + def apply(self): document = self.document index = document.first_child_not_matching_class( @@ -252,38 +268,37 @@ class DocInfo(Transform): for field in field_list: try: name = field[0][0].astext() - normedname = utils.normalize_name(name) + normedname = nodes.fully_normalize_name(name) if not (len(field) == 2 and bibliofields.has_key(normedname) and self.check_empty_biblio_field(field, name)): raise TransformError - biblioclass = bibliofields[normedname] + canonical = bibliofields[normedname] + biblioclass = self.biblio_nodes[canonical] if issubclass(biblioclass, nodes.TextElement): if not self.check_compound_biblio_field(field, name): raise TransformError utils.clean_rcs_keywords( field[1][0], self.rcs_keyword_substitutions) docinfo.append(biblioclass('', '', *field[1][0])) - else: # multiple body elements possible - if issubclass(biblioclass, nodes.authors): - self.extract_authors(field, name, docinfo) - elif issubclass(biblioclass, nodes.topic): - if topics[normedname]: - field[-1] += self.document.reporter.warning( - 'There can only be one "%s" field.' % name, - base_node=field) - raise TransformError - title = nodes.title(name, labels[normedname]) - topics[normedname] = biblioclass( - '', title, CLASS=normedname, *field[1].children) - else: - docinfo.append(biblioclass('', *field[1].children)) + elif issubclass(biblioclass, nodes.authors): + self.extract_authors(field, name, docinfo) + elif issubclass(biblioclass, nodes.topic): + if topics[canonical]: + field[-1] += self.document.reporter.warning( + 'There can only be one "%s" field.' % name, + base_node=field) + raise TransformError + title = nodes.title(name, labels[canonical]) + topics[canonical] = biblioclass( + '', title, CLASS=canonical, *field[1].children) + else: + docinfo.append(biblioclass('', *field[1].children)) except TransformError: if len(field[-1]) == 1 \ and isinstance(field[-1][0], nodes.paragraph): utils.clean_rcs_keywords( field[-1][0], self.rcs_keyword_substitutions) docinfo.append(field) - continue nodelist = [] if len(docinfo) != 0: nodelist.append(docinfo) -- cgit v1.2.1 From adf281a00341eae13815afb97acf04ded5fa6f2d Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 27 Mar 2003 00:28:07 +0000 Subject: beginnings of substitution case-sensitizing git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1235 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 12 ++++++++++++ docutils/parsers/rst/states.py | 2 +- docutils/transforms/parts.py | 2 +- docutils/utils.py | 4 ---- 4 files changed, 14 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index db38ae1e9..c300c0711 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -619,6 +619,10 @@ class document(Root, Structural, Element): self.substitution_defs = {} """Mapping of substitution names to substitution_definition nodes.""" + self.substitution_names = {} + """Mapping of case-normalized substitution names to case-sensitive + names.""" + self.refnames = {} """Mapping of names to lists of referencing nodes.""" @@ -1442,3 +1446,11 @@ _non_id_at_ends = re.compile('^[-0-9]+|-+$') def dupname(node): node['dupname'] = node['name'] del node['name'] + +def fully_normalize_name(name): + """Return a case- and whitespace-normalized name.""" + return ' '.join(name.lower().split()) + +def whitespace_normalize_name(name): + """Return a whitespace-normalized name.""" + return ' '.join(name.split()) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 68b3b6853..d712cbea2 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -111,7 +111,7 @@ from types import TupleType 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.nodes import fully_normalize_name as normalize_name from docutils.parsers.rst import directives, languages, tableparser from docutils.parsers.rst.languages import en as _fallback_language_module diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index 05747183e..5d8a114ba 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -89,7 +89,7 @@ class Contents(Transform): topic += title else: name = self.language.labels['contents'] - name = utils.normalize_name(name) + name = nodes.fully_normalize_name(name) if not self.document.has_name(name): topic['name'] = name self.document.note_implicit_target(topic) diff --git a/docutils/utils.py b/docutils/utils.py index 0ab9f27e0..01c365cb9 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -368,10 +368,6 @@ 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 new_document(source, settings=None): """ Return a new empty document object. -- cgit v1.2.1 From 1c87d959eb6be73667ca61bbb48d69b075a846df Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 27 Mar 2003 03:56:37 +0000 Subject: substitutions made case-sensitive but forgiving (case-insensitive fallback) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1236 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 14 ++++++---- docutils/parsers/rst/states.py | 58 ++++++++++++++++----------------------- docutils/transforms/references.py | 10 ++++++- 3 files changed, 41 insertions(+), 41 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index c300c0711..e2c8ef9d8 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -868,8 +868,8 @@ class document(Root, Structural, Element): self.citation_refs.setdefault(ref['refname'], []).append(ref) self.note_refname(ref) - def note_substitution_def(self, subdef, msgnode=None): - name = subdef['name'] + def note_substitution_def(self, subdef, def_name, msgnode=None): + name = subdef['name'] = whitespace_normalize_name(def_name) if self.substitution_defs.has_key(name): msg = self.reporter.error( 'Duplicate substitution definition name: "%s".' % name, @@ -878,12 +878,14 @@ class document(Root, Structural, Element): msgnode += msg oldnode = self.substitution_defs[name] dupname(oldnode) - # keep only the last definition + # keep only the last definition: self.substitution_defs[name] = subdef + # case-insensitive mapping: + self.substitution_names[fully_normalize_name(name)] = name - def note_substitution_ref(self, subref): - self.substitution_refs.setdefault( - subref['refname'], []).append(subref) + def note_substitution_ref(self, subref, refname): + name = subref['refname'] = whitespace_normalize_name(refname) + self.substitution_refs.setdefault(name, []).append(subref) def note_pending(self, pending, priority=None): self.transformer.add_pending(pending, priority) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index d712cbea2..481ac1259 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -936,26 +936,22 @@ class Inliner: match, lineno, self.patterns.substitution_ref, nodes.substitution_reference) if len(inlines) == 1: - subrefnode = inlines[0] - if isinstance(subrefnode, nodes.substitution_reference): - subreftext = subrefnode.astext() - refname = normalize_name(subreftext) - subrefnode['refname'] = refname - self.document.note_substitution_ref( - subrefnode) + subref_node = inlines[0] + if isinstance(subref_node, nodes.substitution_reference): + subref_text = subref_node.astext() + self.document.note_substitution_ref(subref_node, subref_text) if endstring[-1:] == '_': - referencenode = nodes.reference( - '|%s%s' % (subreftext, endstring), '') + reference_node = nodes.reference( + '|%s%s' % (subref_text, endstring), '') if endstring[-2:] == '__': - referencenode['anonymous'] = 1 + reference_node['anonymous'] = 1 self.document.note_anonymous_ref( - referencenode) + reference_node) else: - referencenode['refname'] = refname - self.document.note_refname( - referencenode) - referencenode += subrefnode - inlines = [referencenode] + reference_node['refname'] = normalize_name(subref_text) + self.document.note_refname(reference_node) + reference_node += subref_node + inlines = [reference_node] return before, inlines, remaining, sysmessages def footnote_reference(self, match, lineno): @@ -1864,34 +1860,31 @@ class Body(RSTState): while block and not block[-1].strip(): block.pop() subname = subdefmatch.group('name') - name = normalize_name(subname) - substitutionnode = nodes.substitution_definition( - blocktext, name=name, alt=subname) - substitutionnode.line = lineno + 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=substitutionnode, + block, input_offset=offset, node=substitution_node, initial_state='SubstitutionDef', blank_finish=blank_finish) i = 0 - for node in substitutionnode[:]: + for node in substitution_node[:]: if not (isinstance(node, nodes.Inline) or isinstance(node, nodes.Text)): - self.parent += substitutionnode[i] - del substitutionnode[i] + self.parent += substitution_node[i] + del substitution_node[i] else: i += 1 - if len(substitutionnode) == 0: + if len(substitution_node) == 0: msg = self.reporter.warning( 'Substitution definition "%s" empty or invalid.' % subname, nodes.literal_block(blocktext, blocktext), line=lineno) return [msg], blank_finish else: - del substitutionnode['alt'] - self.document.note_substitution_def( - substitutionnode, self.parent) - return [substitutionnode], blank_finish + return [substitution_node], blank_finish else: msg = self.reporter.warning( 'Substitution definition "%s" missing contents.' % subname, @@ -2453,11 +2446,8 @@ class SubstitutionDef(Body): initial_transitions = ['embedded_directive', 'text'] def embedded_directive(self, match, context, next_state): - if self.parent.has_key('alt'): - option_presets = {'alt': self.parent['alt']} - else: - option_presets = {} - nodelist, blank_finish = self.directive(match, **option_presets) + nodelist, blank_finish = self.directive(match, + alt=self.parent['name']) self.parent += nodelist if not self.state_machine.at_eof(): self.blank_finish = blank_finish diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 5b1243ed5..fd52f00fc 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -668,11 +668,17 @@ class Substitutions(Transform): def apply(self): defs = self.document.substitution_defs + normed = self.document.substitution_names for refname, refs in self.document.substitution_refs.items(): for ref in refs: + key = None if defs.has_key(refname): - ref.parent.replace(ref, defs[refname].get_children()) + 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) @@ -682,6 +688,8 @@ class Substitutions(Transform): prbid = self.document.set_id(prb) msg.add_backref(prbid) ref.parent.replace(ref, prb) + else: + ref.parent.replace(ref, defs[key].get_children()) self.document.substitution_refs = None # release replaced references -- cgit v1.2.1 From 6878314cfc759787683a88efac4733aee3a9d94b Mon Sep 17 00:00:00 2001 From: grubert Date: Thu, 27 Mar 2003 08:21:34 +0000 Subject: bibliographic_fields: status in french is statut ? git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1238 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/fr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/languages/fr.py b/docutils/languages/fr.py index 0ff327bec..bba990855 100644 --- a/docutils/languages/fr.py +++ b/docutils/languages/fr.py @@ -43,7 +43,7 @@ bibliographic_fields = { 'contact': 'contact', 'version': 'version', 'r\u00e9vision': 'revision', - 'status': 'status', + 'statut': 'status', 'date': 'date', 'copyright': 'copyright', 'd\u00e9dicace': 'dedication', -- cgit v1.2.1 From 3171a1a73139979536cdb785dfd3795e7f40ac30 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 29 Mar 2003 14:58:40 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1243 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index f73ccf338..20a4c7f19 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -286,7 +286,13 @@ def publish_string(source, source_path=None, destination_path=None, 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. + output. Here's how:: + + publish_string(..., settings_overrides={'output_encoding': 'unicode'}) + + Similarly for Unicode string input (`source`):: + + publish_string(..., settings_overrides={'input_encoding': 'unicode'}) Parameters: -- cgit v1.2.1 From bfaeac7127423affe8914dfabaeeec24c5957f9e Mon Sep 17 00:00:00 2001 From: grubert Date: Mon, 31 Mar 2003 07:21:40 +0000 Subject: FIX quotehandling in inline literals (in work?). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1244 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 20c8a8ac7..cdc07ba11 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -345,6 +345,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.docinfo = None # inside literal block: no quote mangling. self.literal_block = 0 + self.literal = 0 def get_stylesheet_reference(self): if self.settings.stylesheet_path: @@ -396,7 +397,12 @@ class LaTeXTranslator(nodes.NodeVisitor): text = text.replace("%", '{\\%}') text = text.replace("#", '{\\#}') text = text.replace("~", '{\\~{ }}') - if not self.literal_block: + if self.literal_block or self.literal: + # a thinspace after every quote. + # requested by g.schwant but not yet verified. + #text = text.replace('"', '"\\,') + pass + else: text = self.babel.quote_quotes(text) if self.insert_newline: text = text.replace("\n", '\\\\\n') @@ -929,10 +935,12 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('\n') def visit_literal(self, node): + self.literal = 1 self.body.append('\\texttt{') def depart_literal(self, node): self.body.append('}') + self.literal = 0 def visit_literal_block(self, node): """ -- cgit v1.2.1 From dfaf49c690c1511b3c5d592c96a6b8e7b689f6f5 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 31 Mar 2003 19:45:42 +0000 Subject: recognize unicode strings don't need decoding git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1246 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index ba624f1e7..78aba7652 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -13,6 +13,7 @@ __docformat__ = 'reStructuredText' import sys import locale +from types import UnicodeType from docutils import TransformSpec @@ -67,7 +68,8 @@ class Input(TransformSpec): locale.setlocale(locale.LC_ALL, '') """ - if self.encoding and self.encoding.lower() == 'unicode': + if (self.encoding and self.encoding.lower() == 'unicode' + or isinstance(data, UnicodeType)): return unicode(data) encodings = [self.encoding, 'utf-8'] try: -- cgit v1.2.1 From 3e79d5f86dc7eef80d1f93b6ccdda353adbbb99d Mon Sep 17 00:00:00 2001 From: fdrake Date: Mon, 31 Mar 2003 20:37:43 +0000 Subject: Use isinstance() consistently. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1248 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index e2c8ef9d8..bbcb04329 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -261,7 +261,7 @@ class Element(Node): def _dom_node(self, domroot): element = domroot.createElement(self.tagname) for attribute, value in self.attributes.items(): - if type(value) is ListType: + if isinstance(value, ListType): value = ' '.join(value) element.setAttribute(attribute, str(value)) for child in self.children: @@ -1129,7 +1129,7 @@ class pending(Special, Invisible, PreBibliographic, Element): internals.append('%7s%s:' % ('', key)) internals.extend(['%9s%s' % ('', line) for line in value.pformat().splitlines()]) - elif value and type(value) == ListType \ + elif value and isinstance(value, ListType) \ and isinstance(value[0], Node): internals.append('%7s%s:' % ('', key)) for v in value: -- cgit v1.2.1 From ca5ab88ddebf471440cc7c8d334b37902dd8f299 Mon Sep 17 00:00:00 2001 From: fdrake Date: Mon, 31 Mar 2003 20:56:52 +0000 Subject: Remove unnecessary local variable. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1249 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index 78aba7652..6bd59210e 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -89,8 +89,7 @@ class Input(TransformSpec): if not enc: continue try: - decoded = unicode(data, enc) - return decoded + return unicode(data, enc) except (UnicodeError, LookupError): pass raise UnicodeError( -- cgit v1.2.1 From 4c7056f26293b3f87e1cf666bc6dd0882b06ce82 Mon Sep 17 00:00:00 2001 From: grubert Date: Tue, 1 Apr 2003 15:03:27 +0000 Subject: Double quotes for language de and language fr (recommit previous seams to get lost). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1250 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 122 ++++++++++++++++++++++++++------------------ 1 file changed, 71 insertions(+), 51 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index cdc07ba11..618b014a7 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -21,51 +21,6 @@ import string from types import ListType from docutils import writers, nodes, languages -# country code by a.schlock. -# partly manually converted from iso and babel stuff, dialects and some -# languages remain missing (austrian, UKEnglish, brazillian etc.) -_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', - - 'de': 'ngerman', #XXX rather than german - 'el': 'greek', - 'en': 'english', - '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' - } - class Writer(writers.Writer): supported = ('latex','latex2e') @@ -183,10 +138,61 @@ Notes on LaTeX 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): + # maybe use: {\glqq} {\grqq}. self.quotes = ("\"`", "\"'") + self.double_quote_replacment = "{\\dq}" else: self.quotes = ("``", "''") self.quote_index = 0 @@ -205,6 +211,22 @@ class Babel: 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' @@ -273,9 +295,9 @@ class LaTeXTranslator(nodes.NodeVisitor): self.language = languages.get_language(settings.language_code) self.babel = Babel(settings.language_code) self.author_separator = self.language.author_separators[0] - if _ISO639_TO_BABEL.has_key(settings.language_code): + if self.babel.get_language(): self.d_options += ',%s' % \ - _ISO639_TO_BABEL[settings.language_code] + self.babel.get_language() self.head_prefix = [ self.latex_head % (self.d_options,self.d_class), '\\usepackage{babel}\n', # language is in documents settings. @@ -398,10 +420,8 @@ class LaTeXTranslator(nodes.NodeVisitor): text = text.replace("#", '{\\#}') text = text.replace("~", '{\\~{ }}') if self.literal_block or self.literal: - # a thinspace after every quote. - # requested by g.schwant but not yet verified. - #text = text.replace('"', '"\\,') - pass + # pdflatex does not produce doublequotes for ngerman. + text = self.babel.double_quotes_in_tt(text) else: text = self.babel.quote_quotes(text) if self.insert_newline: -- cgit v1.2.1 From 9b9fd595cd4dc880c50f68c962f53767e2800043 Mon Sep 17 00:00:00 2001 From: bbum Date: Tue, 1 Apr 2003 15:57:41 +0000 Subject: Added '--hyperlink-color' flag to latex2e. It allows one to unify the color of links or to turn of link coloring entirely. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1251 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 618b014a7..ef1d6b2a3 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -60,7 +60,10 @@ class Writer(writers.Writer): ('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}), - )) + ('Color of any hyperlinks embedded in text (default: "blue", "0" to disable).', + ['--hyperlink-color'], {'default': 'blue'}), + ), + ) settings_default_overrides = {'output_encoding': 'latin-1'} @@ -269,7 +272,7 @@ class LaTeXTranslator(nodes.NodeVisitor): latex_head = '\\documentclass[%s]{%s}\n' encoding = '\\usepackage[latin1]{inputenc}\n' - linking = '\\usepackage[colorlinks,linkcolor=blue]{hyperref}\n' + linking = '\\usepackage[colorlinks=%s,linkcolor=%s,urlcolor=%s]{hyperref}\n' geometry = '\\usepackage[%s,margin=%s,nohead]{geometry}\n' stylesheet = '\\input{%s}\n' # add a generated on day , machine by user using docutils version. @@ -286,10 +289,20 @@ class LaTeXTranslator(nodes.NodeVisitor): # list environment for docinfo. else tabularx use_optionlist_for_docinfo = 0 # NOT YET IN USE + # default link color + hyperlink_color = "blue" + def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.settings = settings = document.settings self.use_latex_toc = settings.use_latex_toc + self.hyperlink_color = settings.hyperlink_color + 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) @@ -317,7 +330,7 @@ class LaTeXTranslator(nodes.NodeVisitor): '\\usepackage{graphicx}\n', '\\usepackage{color}\n', '\\usepackage{multirow}\n', - self.linking, + self.linking % (self.colorlinks, self.hyperlink_color, self.hyperlink_color), # geometry and fonts might go into style.tex. self.geometry % (self.d_paper, self.d_margins), # -- cgit v1.2.1 From 1583184ba811275b3bebca23fb278277bc625ee1 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 3 Apr 2003 01:11:40 +0000 Subject: added Unicode "u" prefix; thanks to Eric Bellot git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1253 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/fr.py | 68 ++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 34 deletions(-) (limited to 'docutils') diff --git a/docutils/languages/fr.py b/docutils/languages/fr.py index bba990855..3416b0c6f 100644 --- a/docutils/languages/fr.py +++ b/docutils/languages/fr.py @@ -11,43 +11,43 @@ French-language mappings for language-dependent features of Docutils. __docformat__ = 'reStructuredText' 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'} + u'author': u'Auteur', + u'authors': u'Auteurs', + u'organization': u'Organisation', + u'address': u'Adresse', + u'contact': u'Contact', + u'version': u'Version', + u'revision': u'R\u00e9vision', + u'status': u'Statut', + u'date': u'Date', + u'copyright': u'Copyright', + u'dedication': u'D\u00e9dicace', + u'abstract': u'R\u00e9sum\u00e9', + u'attention': u'Attention!', + u'caution': u'Avertissement!', + u'danger': u'!DANGER!', + u'error': u'Erreur', + u'hint': u'Indication', + u'important': u'Important', + u'note': u'Note', + u'tip': u'Astuce', + u'warning': u'Avis', + u'contents': u'Contenu'} """Mapping of node class name to label text.""" bibliographic_fields = { - 'auteur': 'author', - 'auteurs': 'authors', - 'organisation': 'organization', - 'adresse': 'address', - 'contact': 'contact', - 'version': 'version', - 'r\u00e9vision': 'revision', - 'statut': 'status', - 'date': 'date', - 'copyright': 'copyright', - 'd\u00e9dicace': 'dedication', - 'r\u00e9sum\u00e9': 'abstract'} + u'auteur': u'author', + u'auteurs': u'authors', + u'organisation': u'organization', + u'adresse': u'address', + u'contact': u'contact', + u'version': u'version', + u'r\u00e9vision': u'revision', + u'statut': u'status', + u'date': u'date', + u'copyright': u'copyright', + u'd\u00e9dicace': u'dedication', + u'r\u00e9sum\u00e9': u'abstract'} """French (lowcased) to canonical name mapping for bibliographic fields.""" author_separators = [';', ','] -- cgit v1.2.1 From 5e80a885d5886f2f8f071689143cd2f40f92f27f Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 3 Apr 2003 01:12:26 +0000 Subject: initial rough translations; awaiting native French speaker final translations git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1254 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/fr.py | 59 ++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 29 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index 4a7d85176..c4ff72716 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -13,35 +13,36 @@ __docformat__ = 'reStructuredText' directives = { - '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', - 'sidebar (translation required)': 'sidebar', - 'topic (translation required)': 'topic', - 'line-block (translation required)': 'line-block', - 'parsed-literal (translation required)': 'parsed-literal', - #'questions (translation required)': 'questions', - #'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', - 'contents (translation required)': 'contents', - 'sectnum (translation required)': 'sectnum', - 'section-numbering (translation required)': 'sectnum', - 'target-notes (translation required)': 'target-notes', - #'footnotes (translation required)': 'footnotes', - #'citations (translation required)': 'citations', + u'attention': u'attention', + u'avertissement': u'caution', + u'danger': u'danger', + u'erreur': u'error', + u'indication': u'hint', + u'important': u'important', + u'note': u'note', + u'astuce': u'tip', + u'avis': u'warning', + u'sidebar (translation required)': u'sidebar', + u'topic (translation required)': u'topic', + u'line-block (translation required)': u'line-block', + u'parsed-literal (translation required)': u'parsed-literal', + #u'questions (translation required)': u'questions', + #u'qa (translation required)': u'questions', + #u'faq (translation required)': u'questions', + u'meta (translation required)': u'meta', + #u'imagemap (translation required)': u'imagemap', + u'image': u'image', + u'figure (translation required)': u'figure', + u'inclure': u'include', + u'brut': u'raw', + u'remplacer': u'replace', + u'mati\u00E8res': u'contents', + u'table-des-mati\u00E8res': u'contents', + u'sectnum (translation required)': u'sectnum', + u'section-numbering (translation required)': u'sectnum', + u'target-notes (translation required)': u'target-notes', + #u'footnotes (translation required)': u'footnotes', + #u'citations (translation required)': u'citations', } """French name to registered (in directives/__init__.py) directive name mapping.""" -- cgit v1.2.1 From 6284806f895c09a82ebe4cf5847647726dc8ec55 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 3 Apr 2003 15:22:36 +0000 Subject: updated with translations from William Dode (& me) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1256 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/fr.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index c4ff72716..455c02b8e 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -1,4 +1,4 @@ -# Author: your name here! +# Authors: David Goodger; William Dode # Contact: goodger@users.sourceforge.net # Revision: $Revision$ # Date: $Date$ @@ -22,25 +22,25 @@ directives = { u'note': u'note', u'astuce': u'tip', u'avis': u'warning', - u'sidebar (translation required)': u'sidebar', - u'topic (translation required)': u'topic', - u'line-block (translation required)': u'line-block', - u'parsed-literal (translation required)': u'parsed-literal', + u'encart': u'sidebar', + u'sujet': u'topic', + u'bloc-ligne': u'line-block', + u'bloc-analys\u00E9': u'parsed-literal', #u'questions (translation required)': u'questions', #u'qa (translation required)': u'questions', #u'faq (translation required)': u'questions', - u'meta (translation required)': u'meta', + u'meta': u'meta', #u'imagemap (translation required)': u'imagemap', u'image': u'image', - u'figure (translation required)': u'figure', + u'figure': u'figure', u'inclure': u'include', u'brut': u'raw', u'remplacer': u'replace', u'mati\u00E8res': u'contents', u'table-des-mati\u00E8res': u'contents', - u'sectnum (translation required)': u'sectnum', - u'section-numbering (translation required)': u'sectnum', - u'target-notes (translation required)': u'target-notes', + u'sectnum': u'sectnum', + u'section-num\u00E9rot\u00E9e': u'sectnum', + u'liens': u'target-notes', #u'footnotes (translation required)': u'footnotes', #u'citations (translation required)': u'citations', } -- cgit v1.2.1 From 35e8cc0c270a59029dd1e5276894c4955eaf09c7 Mon Sep 17 00:00:00 2001 From: grubert Date: Wed, 9 Apr 2003 07:28:18 +0000 Subject: Add latex writer document. Table width is relative to an assumed reST linelength of 80 characters. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1264 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index ef1d6b2a3..4a4ed8708 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1183,13 +1183,9 @@ class LaTeXTranslator(nodes.NodeVisitor): """ Return column specification for longtable. - The width is scaled down by 93%. We do it here - because then we can use linewidth which should be the local - width. + Assumes reST line length being 80 characters. """ - width = 0 - for node in self.colspecs: - width += node['colwidth'] + width = 80 s = "" for node in self.colspecs: colwidth = 0.93 * float(node['colwidth']) / width -- cgit v1.2.1 From 1efe26688716c2186ca2077430da7a11d031121e Mon Sep 17 00:00:00 2001 From: grubert Date: Wed, 9 Apr 2003 07:34:29 +0000 Subject: Fix: Doctest blocks in real verbatim. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1265 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 4a4ed8708..2065e433a 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -693,9 +693,11 @@ class LaTeXTranslator(nodes.NodeVisitor): 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') -- cgit v1.2.1 From 3d412915a9f0b8906f8fe91e740a0605cdcb0a28 Mon Sep 17 00:00:00 2001 From: grubert Date: Wed, 9 Apr 2003 11:10:06 +0000 Subject: Documentation for stylesheet usage. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1268 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 2065e433a..3fa0dea3f 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -57,8 +57,9 @@ class Writer(writers.Writer): 'recommended).', ['--embed-stylesheet'], {'action': 'store_true'}), - ('Table of contents by docutils (default) or latex. Latex(writer) supports only ' - 'one ToC per document, but docutils does not write pagenumbers.', + ('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}), ('Color of any hyperlinks embedded in text (default: "blue", "0" to disable).', ['--hyperlink-color'], {'default': 'blue'}), -- cgit v1.2.1 From 108c7f999935ac472c17e7766392cfa82e04bc55 Mon Sep 17 00:00:00 2001 From: grubert Date: Thu, 10 Apr 2003 12:45:09 +0000 Subject: Add latex lengths: admonitionwidth and docinfowidth. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1272 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 61 ++++++++------------------------------------- 1 file changed, 10 insertions(+), 51 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 3fa0dea3f..db790ed60 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -85,53 +85,9 @@ class Writer(writers.Writer): Notes on LaTeX -------------- -* Put labels inside environments:: +* latex does not support multiple tocs in one document. + (might be no limitation except for docutils documentation) - \chapter[optional]{title} - \label{lab} % optional, for cross referencing - text for this unit ... - -* unnumbered sections are not written to tableofcontents. - a. donot print numbers:: - - \renewcommand{\thesection}{} - b. use:: - - \addcontentsline{file}{sec_unit}{entry} - - file toc,lof lot - sec_unit section, subsection , ... - entry the line:: - - \numberline text pagenumber - - X. latex does not support multiple tocs in one document. - (might be no limitation except for docutils documentation) - -* sectioning:: - - \part - \chapter (report style only) - \section - \subsection - \subsubsection - \paragraph - \subparagraph - \subsubparagraph (milstd and book-form styles only) - \subsubsubparagraph (milstd and book-form styles only) - -* documentclass options - - all notitlepage. - - article: 11pt, 12pt, twoside, twocolumn, draft, fleqn, leqno, acm - - report: 11pt, 12pt, twoside, twocolumn, draft, fleqn, leqno, acm - - letter: 11pt, 12pt, fleqn, leqno, acm - - book: 11pt, 12pt, twoside,twocolumn, draft, fleqn, leqno - * width * linewidth - width of a line in the local environment @@ -265,7 +221,6 @@ class LaTeXTranslator(nodes.NodeVisitor): # to other packages, as done with babel. # Dummy settings might be taken from document settings - ## For narrower things (tables, docinfos use admwidth in latex construct). d_class = 'article' # document.settings.stylesheet d_options = '10pt' # papersize, fontsize d_paper = 'a4paper' @@ -336,8 +291,12 @@ class LaTeXTranslator(nodes.NodeVisitor): self.geometry % (self.d_paper, self.d_margins), # self.generator, - # admonition width and docinfo tablewidth - '\\newlength{\\admwidth}\n\\addtolength{\\admwidth}{0.9\\textwidth}\n', + # latex lengths + '\\newlength{\\admonitionwidth}\n', + '\\setlength{\\admonitionwidth}{0.9\\textwidth}\n' + # width for docinfo tablewidth + '\\newlength{\\docinfowidth}\n', + '\\setlength{\\docinfowidth}{0.9\\textwidth}\n' ] self.head_prefix.extend( latex_headings['optionlist_environment'] ) self.head_prefix.extend( latex_headings['footnote_floats'] ) @@ -478,7 +437,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_admonition(self, node, name): self.body.append('\\begin{center}\\begin{sffamily}\n') - self.body.append('\\fbox{\\parbox{\\admwidth}{\n') + self.body.append('\\fbox{\\parbox{\\admonitionwidth}{\n') self.body.append('\\textbf{\\large '+ self.language.labels[name] + '}\n'); self.body.append('\\vspace{2mm}\n') @@ -645,7 +604,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.docinfo = [] self.docinfo.append('%' + '_'*75 + '\n') self.docinfo.append('\\begin{center}\n') - self.docinfo.append('\\begin{tabularx}{\\admwidth}{lX}\n') + self.docinfo.append('\\begin{tabularx}{\\docinfowidth}{lX}\n') def depart_docinfo(self, node): self.docinfo.append('\\end{tabularx}\n') -- cgit v1.2.1 From bd56a9bffcac75ad55ca38b9ba0c1d1aab7ff5f1 Mon Sep 17 00:00:00 2001 From: fdrake Date: Thu, 10 Apr 2003 15:21:25 +0000 Subject: When formatting system messages, the node source information needs to be encoded for HTML. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1273 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index fd42a061c..e736f8670 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -982,7 +982,7 @@ class HTMLTranslator(nodes.NodeVisitor): 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, - node['source'], line, backref_text)) + self.encode(node['source']), line, backref_text)) def depart_system_message(self, node): self.body.append('\n') -- cgit v1.2.1 From 9753cc15c75c5f7859e8fd526c5d3b9cbb0f4a7f Mon Sep 17 00:00:00 2001 From: fdrake Date: Thu, 10 Apr 2003 16:03:45 +0000 Subject: Don't use len(L) > 0 to test for non-emptiness of L; lists are true if non-empty and false if empty. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1274 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/universal.py | 2 +- docutils/writers/latex2e.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 65fc0cb4a..4523304f2 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -102,7 +102,7 @@ class Messages(Transform): for msg in unfiltered: if msg['level'] >= threshold and not msg.parent: messages.append(msg) - if len(messages) > 0: + if messages: section = nodes.section(CLASS='system-messages') # @@@ get this from the language module? section += nodes.title('', 'Docutils System Messages') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index db790ed60..a92362d8b 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1195,7 +1195,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_tbody(self, node): # BUG write preamble if not yet done (colspecs not []) # for tables without heads. - if len(self.colspecs) > 0: + if self.colspecs: self.visit_thead(None) self.depart_thead(None) self.body.append('%[visit_tbody]\n') -- cgit v1.2.1 From 86eaaba7d6c3649326a6b772a44c4fe38982809c Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 14 Apr 2003 20:00:39 +0000 Subject: Node.__nonzero__ clarification git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1276 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index bbcb04329..ee0f5bb48 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -53,7 +53,12 @@ class Node: """The line number (1-based) of the beginning of this Node in `source`.""" def __nonzero__(self): - """Node instances are always true.""" + """ + Node instances are always true, even if they're empty. + + Use `len()` to check node length. Use `None` to represent a boolean + false value. + """ return 1 def asdom(self, dom=xml.dom.minidom): @@ -175,6 +180,9 @@ class Text(Node, UserString): data = repr(self.data[:64] + ' ...') return '<%s: %s>' % (self.tagname, data) + def __len__(self): + return len(self.data) + def shortrepr(self): data = repr(self.data) if len(data) > 20: -- cgit v1.2.1 From 786cf85eaea56b646568f63af28b040de307903c Mon Sep 17 00:00:00 2001 From: bbum Date: Mon, 14 Apr 2003 20:21:39 +0000 Subject: added very basic sidebar support to latex2e. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1277 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index a92362d8b..abc78bc88 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1107,6 +1107,16 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_section(self, node): self.section_level -= 1 + def visit_sidebar(self, node): + # BUG: this is just a hack to make sidebars render something + 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'); + + def visit_status(self, node): self.visit_docinfo_item(node, 'status') -- cgit v1.2.1 From 593e45fb2edecff6652ee51363f8466bd38a5363 Mon Sep 17 00:00:00 2001 From: grubert Date: Wed, 16 Apr 2003 09:39:18 +0000 Subject: Actually use documentclass option. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1278 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index abc78bc88..8c35019d4 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -221,7 +221,6 @@ class LaTeXTranslator(nodes.NodeVisitor): # to other packages, as done with babel. # Dummy settings might be taken from document settings - d_class = 'article' # document.settings.stylesheet d_options = '10pt' # papersize, fontsize d_paper = 'a4paper' d_margins = '2cm' @@ -268,7 +267,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.d_options += ',%s' % \ self.babel.get_language() self.head_prefix = [ - self.latex_head % (self.d_options,self.d_class), + self.latex_head % (self.d_options,self.settings.documentclass), '\\usepackage{babel}\n', # language is in documents settings. '\\usepackage{shortvrb}\n', # allows verb in footnotes. self.encoding, -- cgit v1.2.1 From 85926fa8addd84c3d6411d73039a5bf1c6bc196d Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 18 Apr 2003 21:41:59 +0000 Subject: added "figwidth" option to "figure" directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1280 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/images.py | 26 +++++++++++++++++++++++++- docutils/writers/html4css1.py | 5 ++++- 2 files changed, 29 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index 8509bf7fc..8baa223e9 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -15,6 +15,10 @@ import sys from docutils import nodes, utils from docutils.parsers.rst import directives +try: + import Image # PIL +except ImportError: + Image = None align_values = ('top', 'middle', 'bottom', 'left', 'center', 'right') @@ -42,11 +46,24 @@ image.options = {'alt': directives.unchanged, def figure(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): + figwidth = options.setdefault('figwidth') + del options['figwidth'] (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 figwidth == 'image': + if Image: + # PIL doesn't like Unicode paths: + try: + i = Image.open(str(image_node['uri'])) + except (IOError, UnicodeError): + pass + else: + figure_node['width'] = i.size[0] + elif figwidth is not None: + figure_node['width'] = figwidth if content: node = nodes.Element() # anonymous container for parsing state.nested_parse(content, content_offset, node) @@ -65,6 +82,13 @@ def figure(name, arguments, options, content, lineno, figure_node += nodes.legend('', *node[1:]) return [figure_node] +def figwidth_value(argument): + if argument.lower() == 'image': + return 'image' + else: + return directives.nonnegative_int(argument) + figure.arguments = (1, 0, 1) -figure.options = image.options +figure.options = {'figwidth': figwidth_value} +figure.options.update(image.options) figure.content = 1 diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index e736f8670..a1c3997cd 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -606,7 +606,10 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.context.pop()) def visit_figure(self, node): - self.body.append(self.starttag(node, 'div', CLASS='figure')) + atts = {'class': 'figure'} + if node.get('width'): + atts['style'] = 'width: %spx' % node['width'] + self.body.append(self.starttag(node, 'div', **atts)) def depart_figure(self, node): self.body.append('\n') -- cgit v1.2.1 From 548c1f56bb8edfa4f7018c6e2673d6389a20bb36 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 18 Apr 2003 21:56:08 +0000 Subject: clarification git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1281 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index ee0f5bb48..76cdfd7bd 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -54,7 +54,9 @@ class Node: def __nonzero__(self): """ - Node instances are always true, even if they're empty. + Node instances are always true, even if they're empty. A node is more + than a simple container. Its boolean "truth" does not depend on + having one or more subnodes in the doctree. Use `len()` to check node length. Use `None` to represent a boolean false value. -- cgit v1.2.1 From 515aac3e6c6e46538147a0cc59d2d70476737a4f Mon Sep 17 00:00:00 2001 From: wilk Date: Sun, 20 Apr 2003 12:15:19 +0000 Subject: french translation git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1284 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/fr.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index 455c02b8e..e246ff0d7 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -14,21 +14,22 @@ __docformat__ = 'reStructuredText' directives = { u'attention': u'attention', - u'avertissement': u'caution', + u'pr\u00E9caution': u'caution', u'danger': u'danger', u'erreur': u'error', - u'indication': u'hint', + u'conseil': u'hint', u'important': u'important', u'note': u'note', u'astuce': u'tip', - u'avis': u'warning', - u'encart': u'sidebar', + u'avertissement': u'warning', + u'encadr\u00E9': u'sidebar', u'sujet': u'topic', - u'bloc-ligne': u'line-block', - u'bloc-analys\u00E9': u'parsed-literal', - #u'questions (translation required)': u'questions', - #u'qa (translation required)': u'questions', - #u'faq (translation required)': u'questions', + u'bloc-textuel': u'line-block', + u'bloc-interpr\u00E9t\u00E9': u'parsed-literal', + u'code-interpr\u00E9t\u00E9': u'parsed-literal', + #u'questions': u'questions', + #u'qr': u'questions', + #u'faq': u'questions', u'meta': u'meta', #u'imagemap (translation required)': u'imagemap', u'image': u'image', @@ -36,7 +37,7 @@ directives = { u'inclure': u'include', u'brut': u'raw', u'remplacer': u'replace', - u'mati\u00E8res': u'contents', + u'sommaire': u'contents', u'table-des-mati\u00E8res': u'contents', u'sectnum': u'sectnum', u'section-num\u00E9rot\u00E9e': u'sectnum', -- cgit v1.2.1 From 1a8014ec77441bbc1793ed60c2fd51494d5372f6 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 23 Apr 2003 23:41:05 +0000 Subject: Added ``register_directive()``, thanks to William Dode and Paul Moore git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1288 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 93461c1ed..d8a6c33bc 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -172,6 +172,10 @@ def directive(directive_name, language_module, document): return None, messages return function, messages +def register_directive(name, directive): + """Register a nonstandard application-defined directive function.""" + _directives[name] = directive + def flag(argument): """ Check for a valid flag option (no argument) and return ``None``. -- cgit v1.2.1 From 694eefebc0b181ae241e157fdffa4bb9424f0b14 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 28 Apr 2003 02:50:18 +0000 Subject: unicode handling fix; bug report and partial fix from William Dode git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1293 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 76cdfd7bd..e066b0431 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -272,8 +272,8 @@ class Element(Node): element = domroot.createElement(self.tagname) for attribute, value in self.attributes.items(): if isinstance(value, ListType): - value = ' '.join(value) - element.setAttribute(attribute, str(value)) + value = ' '.join(['%s' % v for v in value]) + element.setAttribute(attribute, '%s' % value) for child in self.children: element.appendChild(child._dom_node(domroot)) return element @@ -299,10 +299,13 @@ class Element(Node): return '<%s...>' % self.tagname def __str__(self): + return unicode(self).encode('raw_unicode_escape') + + def __unicode__(self): if self.children: - return '%s%s%s' % (self.starttag(), - ''.join([str(c) for c in self.children]), - self.endtag()) + return u'%s%s%s' % (self.starttag(), + ''.join([str(c) for c in self.children]), + self.endtag()) else: return self.emptytag() @@ -312,19 +315,19 @@ class Element(Node): if value is None: # boolean attribute parts.append(name) elif isinstance(value, ListType): - values = [str(v) for v in value] + values = ['%s' % v for v in value] parts.append('%s="%s"' % (name, ' '.join(values))) else: - parts.append('%s="%s"' % (name, str(value))) + parts.append('%s="%s"' % (name, 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()]) + return u'<%s/>' % ' '.join([self.tagname] + + ['%s="%s"' % (n, v) + for n, v in self.attlist()]) def __len__(self): return len(self.children) -- cgit v1.2.1 From 23ecbb5dfca3243d2bb0ff39608cf8def676648c Mon Sep 17 00:00:00 2001 From: pobrien Date: Thu, 1 May 2003 23:49:53 +0000 Subject: Added no-xml-declaration option. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1297 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index a1c3997cd..bb218e2ab 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -66,7 +66,10 @@ class Writer(writers.Writer): {'default': 1, 'action': 'store_true'}), ('Disable compact simple bullet and enumerated lists.', ['--no-compact-lists'], - {'dest': 'compact_lists', 'action': 'store_false'}),)) + {'dest': 'compact_lists', 'action': 'store_false'}), + ('Omit the XML declaration. Use with caution.', + ['--no-xml-declaration'], {'dest': 'xml_declaration', 'default': 1, + 'action': 'store_false'}),)) relative_path_settings = ('stylesheet_path',) @@ -157,7 +160,7 @@ class HTMLTranslator(nodes.NodeVisitor): lcode = settings.language_code self.language = languages.get_language(lcode) self.head_prefix = [ - self.xml_declaration % settings.output_encoding, +# self.xml_declaration % settings.output_encoding, self.doctype, self.html_head % (lcode, lcode), self.content_type % settings.output_encoding, @@ -197,9 +200,15 @@ class HTMLTranslator(nodes.NodeVisitor): return settings.stylesheet 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) + settings = self.settings + output_prefix = [] + if settings.xml_declaration: + output_prefix.append( + self.xml_declaration % settings.output_encoding) + return ''.join(output_prefix + 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.""" -- cgit v1.2.1 From 7c5f379bbc3a3b5a48a0f4a7aa0ec469c964fe5a Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 2 May 2003 00:49:46 +0000 Subject: moved xml_declaration back into HTMLTranslator.__init__; keeps related code together and the declaration in instance variables git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1298 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index bb218e2ab..7d5f8a3f4 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -160,11 +160,13 @@ class HTMLTranslator(nodes.NodeVisitor): lcode = settings.language_code self.language = languages.get_language(lcode) self.head_prefix = [ -# self.xml_declaration % settings.output_encoding, self.doctype, self.html_head % (lcode, lcode), self.content_type % settings.output_encoding, self.generator % docutils.__version__] + if settings.xml_declaration: + self.head_prefix.insert(0, self.xml_declaration + % settings.output_encoding) self.head = [] if settings.embed_stylesheet: stylesheet = self.get_stylesheet_reference(os.getcwd()) @@ -200,12 +202,7 @@ class HTMLTranslator(nodes.NodeVisitor): return settings.stylesheet def astext(self): - settings = self.settings - output_prefix = [] - if settings.xml_declaration: - output_prefix.append( - self.xml_declaration % settings.output_encoding) - return ''.join(output_prefix + self.head_prefix + self.head + return ''.join(self.head_prefix + self.head + self.stylesheet + self.body_prefix + self.body_pre_docinfo + self.docinfo + self.body + self.body_suffix) -- cgit v1.2.1 From 5ff4290ce25679a3dd409045b0173d53fd4bea2d Mon Sep 17 00:00:00 2001 From: grubert Date: Thu, 15 May 2003 06:40:39 +0000 Subject: Fix command line comment in the code and add the option to the documentation. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1313 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 8c35019d4..7e6048ee4 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -33,7 +33,7 @@ class Writer(writers.Writer): ['--documentclass'], {'default': 'article', }), ('Format for footnote references: one of "superscript" or ' - '"brackets". Default is "superscript".', + '"brackets". Default is "brackets".', ['--footnote-references'], {'choices': ['superscript', 'brackets'], 'default': 'brackets', 'metavar': ''}), -- cgit v1.2.1 From 03cf86d015ae45537eeb9da08862610708b7347b Mon Sep 17 00:00:00 2001 From: grubert Date: Thu, 15 May 2003 07:44:12 +0000 Subject: * add a LaTeX-nbsp (~) before a LaTeX-newline to avoid "LaTeX-Error no line to end here". * line_blocks without use of mbox, to allow markups span over line ends. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1314 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 7e6048ee4..a685828fa 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -327,12 +327,17 @@ class LaTeXTranslator(nodes.NodeVisitor): self.topic_class = '' # column specification for tables self.colspecs = [] + # Flags to encode + # --------------- # verbatim: to tell encode not to encode. self.verbatim = 0 - # insert_newline: to tell encode to add newline. + # 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 # docinfo. @@ -397,9 +402,12 @@ class LaTeXTranslator(nodes.NodeVisitor): else: text = self.babel.quote_quotes(text) if self.insert_newline: - text = text.replace("\n", '\\\\\n') + # HACK: 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: text = text.replace("\n", '}\\\\\n\\mbox{') + if self.insert_none_breaking_blanks: text = text.replace(' ', '~') # unicode !!! text = text.replace(u'\u2020', '{$\\dagger$}') @@ -914,13 +922,25 @@ class LaTeXTranslator(nodes.NodeVisitor): """line-block: * whitespace (including linebreaks) is significant * inline markup is supported. - * serif typeface""" - self.mbox_newline = 1 - self.body.append('\\begin{flushleft}\n\\mbox{') + * serif typeface + """ + self.body.append('\\begin{flushleft}\n') + self.insert_none_breaking_blanks = 1 + self.line_block_without_mbox = 1 + if self.line_block_without_mbox: + self.insert_newline = 1 + else: + self.mbox_newline = 1 + self.body.append('\\mbox{') def depart_line_block(self, node): - self.body.append('}\n\\end{flushleft}\n') - self.mbox_newline = 0 + if self.line_block_without_mbox: + self.insert_newline = 0 + else: + self.body.append('}') + self.mbox_newline = 0 + self.insert_none_breaking_blanks = 0 + self.body.append('\n\\end{flushleft}\n') def visit_list_item(self, node): self.body.append('\\item ') @@ -950,6 +970,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.literal_block = 1 if (self.use_for_literal_block == "mbox"): self.mbox_newline = 1 + self.insert_none_breaking_blanks = 1 self.body.append('\\begin{ttfamily}\\begin{flushleft}\n\\mbox{') else: self.body.append('{\\obeylines\\obeyspaces\\ttfamily\n') @@ -957,6 +978,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_literal_block(self, node): if (self.use_for_literal_block == "mbox"): self.body.append('}\n\\end{flushleft}\\end{ttfamily}\n') + self.insert_none_breaking_blanks = 0 self.mbox_newline = 0 else: self.body.append('}\n') -- cgit v1.2.1 From b0017b21c3adccdd613e21f092ed678ec25791ee Mon Sep 17 00:00:00 2001 From: grubert Date: Fri, 16 May 2003 14:38:51 +0000 Subject: HACK --snap-footnote-refs=1 to strip trailing blanks from item preceeding a footnote-ref. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1317 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index a685828fa..a3ee14a60 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -61,8 +61,12 @@ class Writer(writers.Writer): 'supports only one ToC per document, but docutils does not write ' 'pagenumbers.', ['--use-latex-toc'], {'default': 0}), - ('Color of any hyperlinks embedded in text (default: "blue", "0" to disable).', - ['--hyperlink-color'], {'default': 'blue'}), + ('Color of any hyperlinks embedded in text ' + '(default: "blue", "0" to disable).', + ['--hyperlink-color'], {'default': 'blue'}), + ('Remove trailing blanks and line ends from the element before a' + 'footnote_reference (default: off, "1" to enable).', + ['--snap-footnote-refs'], {'default': 0}), ), ) @@ -854,6 +858,8 @@ class LaTeXTranslator(nodes.NodeVisitor): self.context.append('}') else: # shouldn't happen raise AssertionError('Illegal footnote reference format.') + if self.settings.snap_footnote_refs and len(self.body)>0: + self.body.append(self.body.pop().rstrip()) self.body.append('%s\\hyperlink{%s}{' % (suffix,href)) def depart_footnote_reference(self, node): -- cgit v1.2.1 From 7c54992702b443ba1cdd10d3f068bb34575971c8 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 24 May 2003 20:46:17 +0000 Subject: Added element classes: ``rubric``, ``attribution``, ``admonition``, ``superscript``, ``subscript``, ``inline``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1326 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index e066b0431..f2618b9db 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -927,6 +927,7 @@ class document(Root, Structural, Element): class title(Titular, PreBibliographic, TextElement): pass class subtitle(Titular, PreBibliographic, TextElement): pass +class rubric(Titular, TextElement): pass # ======================== @@ -1045,6 +1046,7 @@ class literal_block(General, FixedTextElement): pass class doctest_block(General, FixedTextElement): pass class line_block(General, FixedTextElement): pass class block_quote(General, Element): pass +class attribution(Part, TextElement): pass class attention(Admonition, Element): pass class caution(Admonition, Element): pass class danger(Admonition, Element): pass @@ -1054,6 +1056,7 @@ class note(Admonition, Element): pass class tip(Admonition, Element): pass class hint(Admonition, Element): pass class warning(Admonition, Element): pass +class admonition(Admonition, Element): pass class comment(Special, Invisible, PreBibliographic, FixedTextElement): pass class substitution_definition(Special, Invisible, TextElement): pass class target(Special, Invisible, Inline, TextElement, Targetable): pass @@ -1182,6 +1185,8 @@ class substitution_reference(Inline, TextElement): pass class title_reference(Inline, TextElement): pass class abbreviation(Inline, TextElement): pass class acronym(Inline, TextElement): pass +class superscript(Inline, TextElement): pass +class subscript(Inline, TextElement): pass class image(General, Inline, TextElement): @@ -1190,6 +1195,7 @@ class image(General, Inline, TextElement): return self.get('alt', '') +class inline(Inline, TextElement): pass class problematic(Inline, TextElement): pass class generated(Inline, TextElement): pass @@ -1200,7 +1206,8 @@ class generated(Inline, TextElement): pass node_class_names = """ Text - abbreviation acronym address attention author authors + abbreviation acronym address admonition attention attribution author + authors block_quote bullet_list caption caution citation citation_reference classifier colspec comment contact copyright @@ -1211,15 +1218,15 @@ node_class_names = """ footnote footnote_reference generated header hint - image important + image important inline label legend line_block 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 sidebar status strong substitution_definition - substitution_reference subtitle system_message + raw reference revision row rubric + section sidebar status strong subscript substitution_definition + substitution_reference subtitle superscript system_message table target tbody term tgroup thead tip title title_reference topic transition version @@ -1421,9 +1428,9 @@ 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. + ``[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: @@ -1446,7 +1453,7 @@ def make_id(string): 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. + ``[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 -- cgit v1.2.1 From bd61a20c2fa1a7b09df66561eb26b5fc509806c2 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 24 May 2003 20:46:45 +0000 Subject: Added support for block quote attributions. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1327 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 70 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 481ac1259..838d495c4 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1204,16 +1204,72 @@ class Body(RSTState): """Block quote.""" indented, indent, line_offset, blank_finish = \ self.state_machine.get_indented() - blockquote = self.block_quote(indented, line_offset) + blockquote, messages = self.block_quote(indented, line_offset) self.parent += blockquote + self.parent += messages if not blank_finish: self.parent += self.unindent_warning('Block quote') return context, next_state, [] def block_quote(self, indented, line_offset): + blockquote_lines, attribution_lines, attribution_offset = \ + self.check_attribution(indented, line_offset) blockquote = nodes.block_quote() - self.nested_parse(indented, line_offset, blockquote) - return blockquote + self.nested_parse(blockquote_lines, line_offset, blockquote) + messages = [] + if attribution_lines: + attribution, messages = self.parse_attribution(attribution_lines, + attribution_offset) + blockquote += attribution + return blockquote, messages + + attribution_pattern = re.compile(r'--(?![-\n]) *(?=[^ \n])') + + def check_attribution(self, indented, line_offset): + """ + Check for an attribution in the last contiguous block of `indented`. + + * First line after last blank line must begin with "--" (etc.). + * Every line after that must have consistent indentation. + + Return a 3-tuple: (block quote lines, attribution lines, + attribution offset). + """ + blank = None + nonblank_seen = None + indent = 0 + for i in range(len(indented) - 1, 0, -1): # don't check first line + this_line_blank = not indented[i].strip() + if nonblank_seen and this_line_blank: + match = self.attribution_pattern.match(indented[i + 1]) + if match: + blank = i + break + elif not this_line_blank: + nonblank_seen = 1 + if blank and len(indented) - blank > 2: # multi-line attribution + 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 + blank = None + break + if blank: + a_lines = indented[blank + 1:] + a_lines.strip_indent(match.end(), end=1) + a_lines.strip_indent(indent, start=1) + return (indented[:blank], a_lines, line_offset + blank + 1) + else: + return (indented, None, None) + + def parse_attribution(self, indented, line_offset): + text = '\n'.join(indented).rstrip() + lineno = self.state_machine.abs_line_number() + line_offset + textnodes, messages = self.inline_text(text, lineno) + node = nodes.attribution(text, '', *textnodes) + node.line = lineno + return node, messages def bullet(self, match, context, next_state): """Bullet list item.""" @@ -1432,8 +1488,9 @@ class Body(RSTState): 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) + blockquote, messages = self.block_quote(indented, line_offset) self.parent += blockquote + self.parent += messages if not blank_finish: self.parent += self.unindent_warning('Option list') return [], next_state, [] @@ -2582,8 +2639,9 @@ class Text(RSTState): self.state_machine.get_indented() definitionlistitem = nodes.definition_list_item( '\n'.join(termline + list(indented))) - termlist, messages = self.term( - termline, self.state_machine.abs_line_number() - 1) + lineno = self.state_machine.abs_line_number() - 1 + definitionlistitem.line = lineno + termlist, messages = self.term(termline, lineno) definitionlistitem += termlist definition = nodes.definition('', *messages) definitionlistitem += definition -- cgit v1.2.1 From 4e571e82dee78fbe4773223e3ad3c3c6e8cd5012 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 24 May 2003 20:46:59 +0000 Subject: Added ``class_option()`` directive option helper function. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1328 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index d8a6c33bc..814197eab 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -92,10 +92,14 @@ _directive_registry = { 'tip': ('admonitions', 'tip'), 'hint': ('admonitions', 'hint'), 'warning': ('admonitions', 'warning'), + 'admonition': ('admonitions', 'admonition'), 'sidebar': ('body', 'sidebar'), 'topic': ('body', 'topic'), 'line-block': ('body', 'line_block'), 'parsed-literal': ('body', 'parsed_literal'), + 'rubric': ('body', 'rubric'), + 'epigraph': ('body', 'epigraph'), + 'highlights': ('body', 'highlights'), #'questions': ('body', 'question_list'), 'image': ('images', 'image'), 'figure': ('images', 'figure'), @@ -109,6 +113,8 @@ _directive_registry = { 'raw': ('misc', 'raw'), 'include': ('misc', 'include'), 'replace': ('misc', 'replace'), + 'unicode': ('misc', 'unicode_directive'), + 'class': ('misc', 'class_directive'), '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 @@ -238,3 +244,8 @@ def choice(argument, values): else: raise ValueError('"%s" unknown; choose from %s' % (argument, format_values(values))) + +def class_option(argument): + if argument is None: + raise ValueError('argument required but none supplied') + return nodes.make_id(argument) -- cgit v1.2.1 From fc72a15de8be988e497d9245029dd8ff2c01d333 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 24 May 2003 20:47:13 +0000 Subject: Added "admonition" directive. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1329 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/admonitions.py | 60 ++++++++++++++++---------- 1 file changed, 38 insertions(+), 22 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/admonitions.py b/docutils/parsers/rst/directives/admonitions.py index 7a349ad75..8e3a92895 100644 --- a/docutils/parsers/rst/directives/admonitions.py +++ b/docutils/parsers/rst/directives/admonitions.py @@ -11,64 +11,80 @@ Admonition directives. __docformat__ = 'reStructuredText' -from docutils.parsers.rst import states +from docutils.parsers.rst import states, directives from docutils import nodes -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: +def make_admonition(node_class, name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + if not content: error = state_machine.reporter.error( 'The "%s" admonition is empty; content required.' % (name), nodes.literal_block(block_text, block_text), line=lineno) return [error] + text = '\n'.join(content) + admonition_node = node_class(text) + if arguments: + title_text = arguments[0] + textnodes, messages = state.inline_text(title_text, lineno) + admonition_node += nodes.title(title_text, '', *textnodes) + admonition_node += messages + if options.has_key('class'): + class_value = options['class'] + else: + class_value = 'admonition-' + nodes.make_id(title_text) + admonition_node.set_class(class_value) + state.nested_parse(content, content_offset, admonition_node) + return [admonition_node] + +def admonition(*args): + return make_admonition(nodes.admonition, *args) + +admonition.arguments = (1, 0, 1) +admonition.options = {'class': directives.class_option} +admonition.content = 1 def attention(*args): - return admonition(nodes.attention, *args) + return make_admonition(nodes.attention, *args) attention.content = 1 def caution(*args): - return admonition(nodes.caution, *args) + return make_admonition(nodes.caution, *args) caution.content = 1 def danger(*args): - return admonition(nodes.danger, *args) + return make_admonition(nodes.danger, *args) danger.content = 1 def error(*args): - return admonition(nodes.error, *args) + return make_admonition(nodes.error, *args) error.content = 1 +def hint(*args): + return make_admonition(nodes.hint, *args) + +hint.content = 1 + def important(*args): - return admonition(nodes.important, *args) + return make_admonition(nodes.important, *args) important.content = 1 def note(*args): - return admonition(nodes.note, *args) + return make_admonition(nodes.note, *args) note.content = 1 def tip(*args): - return admonition(nodes.tip, *args) + return make_admonition(nodes.tip, *args) tip.content = 1 -def hint(*args): - return admonition(nodes.hint, *args) - -hint.content = 1 - def warning(*args): - return admonition(nodes.warning, *args) + return make_admonition(nodes.warning, *args) warning.content = 1 -- cgit v1.2.1 From 0e4f3603edbe99da05838c005078328d55fe4ec3 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 24 May 2003 20:47:32 +0000 Subject: Added "rubric", "epigraph", and "highlights" directives. Added "class" options to "topic", "sidebar", "line-block", and "parsed-literal". git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1330 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/body.py | 36 +++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index f24edb325..bc3f5b742 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -41,11 +41,14 @@ def topic(name, arguments, options, content, lineno, messages.extend(more_messages) text = '\n'.join(content) node = node_class(text, *(titles + messages)) + if options.has_key('class'): + node.set_class(options['class']) if text: state.nested_parse(content, content_offset, node) return [node] topic.arguments = (1, 0, 1) +topic.options = {'class': directives.class_option} topic.content = 1 def sidebar(name, arguments, options, content, lineno, @@ -55,7 +58,8 @@ def sidebar(name, arguments, options, content, lineno, node_class=nodes.sidebar) sidebar.arguments = (1, 0, 1) -sidebar.options = {'subtitle': directives.unchanged} +sidebar.options = {'subtitle': directives.unchanged, + 'class': directives.class_option} sidebar.content = 1 def line_block(name, arguments, options, content, lineno, @@ -68,9 +72,10 @@ def line_block(name, arguments, options, content, lineno, return [warning] text = '\n'.join(content) text_nodes, messages = state.inline_text(text, lineno) - node = node_class(text, '', *text_nodes) + node = node_class(text, '', *text_nodes, **options) return [node] + messages +line_block.options = {'class': directives.class_option} line_block.content = 1 def parsed_literal(name, arguments, options, content, lineno, @@ -79,4 +84,31 @@ def parsed_literal(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine, node_class=nodes.literal_block) +parsed_literal.options = {'class': directives.class_option} parsed_literal.content = 1 + +def rubric(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + rubric_text = arguments[0] + textnodes, messages = state.inline_text(rubric_text, lineno) + rubric = nodes.rubric(rubric_text, '', *textnodes, **options) + return [rubric] + messages + +rubric.arguments = (1, 0, 1) +rubric.options = {'class': directives.class_option} + +def epigraph(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + block_quote, messages = state.block_quote(content, content_offset) + block_quote.set_class('epigraph') + return [block_quote] + messages + +epigraph.content = 1 + +def highlights(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + block_quote, messages = state.block_quote(content, content_offset) + block_quote.set_class('highlights') + return [block_quote] + messages + +highlights.content = 1 -- cgit v1.2.1 From 8edecf9f21f56b524484fa27ede5d189b879a49e Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 24 May 2003 20:47:43 +0000 Subject: Added "class" option to "image", and "figclass" to "figure". git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1331 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/images.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index 8baa223e9..d193edffd 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -42,12 +42,15 @@ image.options = {'alt': directives.unchanged, 'height': directives.nonnegative_int, 'width': directives.nonnegative_int, 'scale': directives.nonnegative_int, - 'align': align} + 'align': align, + 'class': directives.class_option} def figure(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): figwidth = options.setdefault('figwidth') + figclass = options.setdefault('figclass') del options['figwidth'] + del options['figclass'] (image_node,) = image(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine) if isinstance(image_node, nodes.system_message): @@ -64,6 +67,8 @@ def figure(name, arguments, options, content, lineno, figure_node['width'] = i.size[0] elif figwidth is not None: figure_node['width'] = figwidth + if figclass: + figure_node.set_class(figclass) if content: node = nodes.Element() # anonymous container for parsing state.nested_parse(content, content_offset, node) @@ -89,6 +94,7 @@ def figwidth_value(argument): return directives.nonnegative_int(argument) figure.arguments = (1, 0, 1) -figure.options = {'figwidth': figwidth_value} +figure.options = {'figwidth': figwidth_value, + 'figclass': directives.class_option} figure.options.update(image.options) figure.content = 1 -- cgit v1.2.1 From 35ec6b12ea21441d7310c33cf6ae9db6301fe63f Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 24 May 2003 20:48:06 +0000 Subject: Added "unicode" and "class" directives. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1332 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 53 +++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index cc8019886..d1c993478 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -10,9 +10,11 @@ __docformat__ = 'reStructuredText' import sys import os.path +import re from urllib2 import urlopen, URLError from docutils import io, nodes, statemachine, utils from docutils.parsers.rst import directives, states +from docutils.transforms import misc def include(name, arguments, options, content, lineno, @@ -151,6 +153,57 @@ def replace(name, arguments, options, content, lineno, replace.content = 1 +def unicode_directive(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + r""" + Convert Unicode character codes (numbers) to characters. Codes may be + decimal numbers, hexadecimal numbers (prefixed by ``0x``, ``x``, ``\x``, + ``u``, or ``\u``), or XML-style numbered character entities (e.g. + ``ᨫ``). + """ + 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] + codes = arguments[0].split() + element = nodes.Element() + for code in codes: + if code.isdigit(): + element += nodes.Text(int(code)) + else: + match = unicode_pattern.match(code) + if match: + element += nodes.Text(unichr(int(match.group(2), 16))) + else: + element += nodes.Text(code) + return element.children + +unicode_directive.arguments = (1, 0, 1) +unicode_pattern = re.compile(r'(0x|x|\x00x|u|\x00u|&#x)([0-9a-f]+);?$', + re.IGNORECASE) + +def class_directive(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + """""" + class_value = nodes.make_id(arguments[0]) + if class_value: + pending = nodes.pending(misc.ClassAttribute, + {'class': class_value, 'directive': name}, + block_text) + state_machine.document.note_pending(pending) + return [pending] + else: + 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] + +class_directive.arguments = (1, 0, 0) +class_directive.content = 1 + def directive_test_function(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): if content: -- cgit v1.2.1 From 43b1e6fde04bd51b01ddc651dc18f2a103bc9ef1 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 24 May 2003 20:48:20 +0000 Subject: Added "class" option to "contents" directive. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1333 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/parts.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/parts.py b/docutils/parsers/rst/directives/parts.py index e4ca8d3df..2faaca44b 100644 --- a/docutils/parsers/rst/directives/parts.py +++ b/docutils/parsers/rst/directives/parts.py @@ -42,7 +42,8 @@ def contents(name, arguments, options, content, lineno, contents.arguments = (0, 1, 1) contents.options = {'depth': directives.nonnegative_int, 'local': directives.flag, - 'backlinks': backlinks} + 'backlinks': backlinks, + 'class': directives.class_option} def sectnum(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): -- cgit v1.2.1 From fc266b53464c3aee800b01e495ef6920a7af393e Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 24 May 2003 20:48:43 +0000 Subject: Added ``ClassAttribute`` to support the "class" directive. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1334 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/misc.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'docutils') diff --git a/docutils/transforms/misc.py b/docutils/transforms/misc.py index cf26f6c3b..4f6e2670b 100644 --- a/docutils/transforms/misc.py +++ b/docutils/transforms/misc.py @@ -10,6 +10,7 @@ Miscellaneous transforms. __docformat__ = 'reStructuredText' +from docutils import nodes from docutils.transforms import Transform, TransformError @@ -31,3 +32,31 @@ class CallBack(Transform): pending = self.startnode pending.details['callback'](pending) pending.parent.remove(pending) + + +class ClassAttribute(Transform): + + default_priority = 210 + + def apply(self): + pending = self.startnode + class_value = pending.details['class'] + parent = pending.parent + child = pending + while parent: + for index in range(parent.index(child) + 1, len(parent)): + element = parent[index] + if isinstance(element, nodes.comment): + continue + element.set_class(class_value) + pending.parent.remove(pending) + return + else: + child = parent + parent = parent.parent + error = self.document.reporter.error( + 'No suitable element following "%s" directive' + % pending.details['directive'], + nodes.literal_block(pending.rawsource, pending.rawsource), + line=pending.line) + pending.parent.replace(pending, error) -- cgit v1.2.1 From 76eca9ee047b2bf2442622191db83ba526f587a0 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 24 May 2003 20:48:58 +0000 Subject: Added "class" attribute support to ``Contents``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1335 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/parts.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index 5d8a114ba..016f4e1d8 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -73,8 +73,11 @@ class Contents(Transform): def apply(self): topic = nodes.topic(CLASS='contents') - title = self.startnode.details['title'] - if self.startnode.details.has_key('local'): + details = self.startnode.details + if details.has_key('class'): + topic.set_class(details['class']) + title = details['title'] + if details.has_key('local'): startnode = self.startnode.parent # @@@ generate an error if the startnode (directive) not at # section/document top-level? Drag it up until it is? @@ -94,8 +97,8 @@ class Contents(Transform): 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'] + if details.has_key('backlinks'): + self.backlinks = details['backlinks'] else: self.backlinks = self.document.settings.toc_backlinks contents = self.build_contents(startnode) -- cgit v1.2.1 From d7791c50f9707e1476c8155177f65199a321179c Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 24 May 2003 20:49:22 +0000 Subject: Added support for "attribution", "rubric", and generic "admonition" elements. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1336 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 53 ++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 18 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 7d5f8a3f4..decd6e18d 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -276,12 +276,14 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('\n\n') self.depart_docinfo_item() - def visit_admonition(self, node, name): - self.body.append(self.starttag(node, 'div', CLASS=name)) - self.body.append('

    ' - + self.language.labels[name] + '

    \n') - - def depart_admonition(self): + def visit_admonition(self, node, name=''): + self.body.append(self.starttag(node, 'div', + CLASS=(name or 'admonition'))) + if name: + self.body.append('

    ' + + self.language.labels[name] + '

    \n') + + def depart_admonition(self, node=None): self.body.append('\n') def visit_attention(self, node): @@ -290,6 +292,13 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_attention(self, node): self.depart_admonition() + def visit_attribution(self, node): + self.body.append( + self.starttag(node, 'p', u'\u2014', CLASS='attribution')) + + def depart_attribution(self, node): + self.body.append('

    \n') + def visit_author(self, node): self.visit_docinfo_item(node, 'author') @@ -910,6 +919,12 @@ class HTMLTranslator(nodes.NodeVisitor): 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.starttag(node, 'div', CLASS='section')) @@ -1060,24 +1075,19 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_title(self, node): """Only 6 section levels are supported by HTML.""" + check_id = 0 if isinstance(node.parent, nodes.topic): self.body.append( self.starttag(node, 'p', '', CLASS='topic-title')) - if node.parent.hasattr('id'): - self.body.append( - self.starttag({}, 'a', '', name=node.parent['id'])) - self.context.append('

    \n') - else: - self.context.append('

    \n') + check_id = 1 elif isinstance(node.parent, nodes.sidebar): self.body.append( self.starttag(node, 'p', '', CLASS='sidebar-title')) - if node.parent.hasattr('id'): - self.body.append( - self.starttag({}, 'a', '', name=node.parent['id'])) - self.context.append('

    \n') - else: - self.context.append('

    \n') + check_id = 1 + elif isinstance(node.parent, nodes.admonition): + self.body.append( + self.starttag(node, 'p', '', CLASS='admonition-title')) + check_id = 1 elif self.section_level == 0: # document title self.head.append('%s\n' @@ -1095,6 +1105,13 @@ class HTMLTranslator(nodes.NodeVisitor): atts['href'] = '#' + node['refid'] self.body.append(self.starttag({}, 'a', '', **atts)) self.context.append('\n' % (self.section_level)) + if check_id: + if node.parent.hasattr('id'): + self.body.append( + self.starttag({}, 'a', '', name=node.parent['id'])) + self.context.append('

    \n') + else: + self.context.append('

    \n') def depart_title(self, node): self.body.append(self.context.pop()) -- cgit v1.2.1 From e8c6ddb8ee857e0387997db70b0786243465b84b Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 24 May 2003 20:54:11 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1340 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/de.py | 6 ++++ docutils/parsers/rst/languages/en.py | 8 ++++- docutils/parsers/rst/languages/fr.py | 68 ++++++++++++++++++++---------------- docutils/parsers/rst/languages/it.py | 6 ++++ docutils/parsers/rst/languages/sk.py | 6 ++++ docutils/parsers/rst/languages/sv.py | 12 +++++-- 6 files changed, 71 insertions(+), 35 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index fafb6f4fa..03ec58530 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -23,10 +23,14 @@ directives = { 'notiz': 'note', 'tip': 'tip', 'warnung': 'warning', + 'admonition (translation required)': 'admonition', 'sidebar (translation required)': 'sidebar', 'topic': 'topic', # berbegriff 'line-block': 'line-block', 'parsed-literal': 'parsed-literal', + 'rubric (translation required)': 'rubric', + 'epigraph (translation required)': 'epigraph', + 'highlights (translation required)': 'highlights', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', @@ -38,6 +42,8 @@ directives = { 'include': 'include', # einfgen, "fge ein" would be more like a command. # einfgung would be the noun. 'replace': 'replace', # ersetzen, ersetze + 'unicode': 'unicode', + 'class (translation required)': 'class', 'inhalt': 'contents', 'sectnum': 'sectnum', 'section-numbering': 'sectnum', diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index 7d0976471..01d30e2b8 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -22,10 +22,14 @@ directives = { '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', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', @@ -36,12 +40,14 @@ directives = { 'include': 'include', 'raw': 'raw', 'replace': 'replace', + 'unicode': 'unicode', + 'class': 'class', 'contents': 'contents', 'sectnum': 'sectnum', 'section-numbering': 'sectnum', - 'target-notes': 'target-notes', #'footnotes': 'footnotes', #'citations': 'citations', + 'target-notes': 'target-notes', 'restructuredtext-test-directive': 'restructuredtext-test-directive'} """English name to registered (in directives/__init__.py) directive name mapping.""" diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index e246ff0d7..94ef05fcf 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -13,37 +13,43 @@ __docformat__ = 'reStructuredText' directives = { - u'attention': u'attention', - u'pr\u00E9caution': u'caution', - u'danger': u'danger', - u'erreur': u'error', - u'conseil': u'hint', - u'important': u'important', - u'note': u'note', - u'astuce': u'tip', - u'avertissement': u'warning', - u'encadr\u00E9': u'sidebar', - u'sujet': u'topic', - u'bloc-textuel': u'line-block', - u'bloc-interpr\u00E9t\u00E9': u'parsed-literal', - u'code-interpr\u00E9t\u00E9': u'parsed-literal', - #u'questions': u'questions', - #u'qr': u'questions', - #u'faq': u'questions', - u'meta': u'meta', - #u'imagemap (translation required)': u'imagemap', - u'image': u'image', - u'figure': u'figure', - u'inclure': u'include', - u'brut': u'raw', - u'remplacer': u'replace', - u'sommaire': u'contents', - u'table-des-mati\u00E8res': u'contents', - u'sectnum': u'sectnum', - u'section-num\u00E9rot\u00E9e': u'sectnum', - u'liens': u'target-notes', - #u'footnotes (translation required)': u'footnotes', - #u'citations (translation required)': u'citations', + u'attention': 'attention', + u'pr\u00E9caution': 'caution', + u'danger': 'danger', + u'erreur': 'error', + u'conseil': 'hint', + u'important': 'important', + u'note': 'note', + u'astuce': 'tip', + u'avertissement': 'warning', + u'admonestation': 'admonition', + u'encadr\u00E9': 'sidebar', + u'sujet': 'topic', + u'bloc-textuel': 'line-block', + u'bloc-interpr\u00E9t\u00E9': 'parsed-literal', + u'code-interpr\u00E9t\u00E9': 'parsed-literal', + u'inter-titre': 'rubric', + u'exergue': 'epigraph', + u'chapeau': 'highlights', + #u'questions': 'questions', + #u'qr': 'questions', + #u'faq': 'questions', + u'meta': 'meta', + #u'imagemap (translation required)': 'imagemap', + u'image': 'image', + u'figure': 'figure', + u'inclure': 'include', + u'brut': 'raw', + u'remplacer': 'replace', + u'unicode': 'unicode', + u'classe': 'class', + u'sommaire': 'contents', + u'table-des-mati\u00E8res': 'contents', + u'sectnum': 'sectnum', + u'section-num\u00E9rot\u00E9e': 'sectnum', + u'liens': 'target-notes', + #u'footnotes (translation required)': 'footnotes', + #u'citations (translation required)': 'citations', } """French name to registered (in directives/__init__.py) directive name mapping.""" diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index 93cba7936..fc93e3451 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -22,10 +22,14 @@ directives = { 'nota': 'note', 'consiglio': 'tip', 'avvertenza': 'warning', + 'admonition (translation required)': 'admonition', 'sidebar (translation required)': 'sidebar', 'argomento': 'topic', 'blocco di linee': 'line-block', 'parsed-literal': 'parsed-literal', + 'rubric (translation required)': 'rubric', + 'epigraph (translation required)': 'epigraph', + 'highlights (translation required)': 'highlights', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', @@ -36,6 +40,8 @@ directives = { 'includi': 'include', 'grezzo': 'raw', 'sostituisci': 'replace', + 'unicode': 'unicode', + 'class (translation required)': 'class', 'indice': 'contents', 'seznum': 'sectnum', 'section-numbering': 'sectnum', diff --git a/docutils/parsers/rst/languages/sk.py b/docutils/parsers/rst/languages/sk.py index 585bf934d..433f37f2f 100644 --- a/docutils/parsers/rst/languages/sk.py +++ b/docutils/parsers/rst/languages/sk.py @@ -22,10 +22,14 @@ directives = { u'pozn\xe1mka': 'note', u'tip': 'tip', u'varovanie': 'warning', + u'admonition (translation required)': 'admonition', u'sidebar (translation required)': 'sidebar', u't\xe9ma': 'topic', u'blok-riadkov': 'line-block', u'parsed-literal': 'parsed-literal', + u'rubric (translation required)': 'rubric', + u'epigraph (translation required)': 'epigraph', + u'highlights (translation required)': 'highlights', #u'questions': 'questions', #u'qa': 'questions', #u'faq': 'questions', @@ -36,6 +40,8 @@ directives = { u'vlo\x9ei\x9d': 'include', u'raw': 'raw', u'nahradi\x9d': 'replace', + u'unicode': 'unicode', + u'class (translation required)': 'class', 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 c63922c5e..fe31c9b7f 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -21,10 +21,14 @@ directives = { u'notera': 'note', u'tips': 'tip', u'varning': 'warning', + u'admonition (translation required)': 'admonition', u'sidebar (translation required)': 'sidebar', u'\u00e4mne': 'topic', - 'line-block (translation required)': 'line-block', - 'parsed-literal (translation required)': 'parsed-literal', + u'line-block (translation required)': 'line-block', + u'parsed-literal (translation required)': 'parsed-literal', + u'mellanrubrik': 'rubric', + u'epigraph (translation required)': 'epigraph', + u'highlights (translation required)': 'highlights', # u'fr\u00e5gor': 'questions', # NOTE: A bit long, but recommended by http://www.nada.kth.se/dataterm/: # u'fr\u00e5gor-och-svar': 'questions', @@ -36,9 +40,11 @@ directives = { u'inkludera': 'include', u'r\u00e5': 'raw', # FIXME: Translation might be too literal. u'ers\u00e4tt': 'replace', + u'unicode': 'unicode', + u'class (translation required)': 'class', u'inneh\u00e5ll': 'contents', u'sektionsnumrering': 'sectnum', - 'target-notes (translation required)': 'target-notes', + u'target-notes (translation required)': 'target-notes', # u'fotnoter': 'footnotes', # u'citeringar': 'citations', } -- cgit v1.2.1 From ea87be65128106e35aea589545f563f31e5c13bb Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 25 May 2003 14:59:30 +0000 Subject: Added a kludge to work-around a conflict between the bubble-up parser strategy and short titles (<= 3 char-long over- & underlines). Fixes SF bug #738803 "infinite loop with multiple titles" submitted by Jason Diamond. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1344 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 838d495c4..3901d6078 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -159,6 +159,7 @@ class RSTStateMachine(StateMachineWS): language=self.language, title_styles=[], section_level=0, + section_bubble_up_kludge=0, inliner=inliner) self.document = document self.attach_observer(document.note_source) @@ -340,6 +341,8 @@ class RSTState(StateWS): return None if level <= mylevel: # sibling or supersection memo.section_level = level # bubble up to parent section + if len(style) == 2: + memo.section_bubble_up_kludge = 1 # back up 2 lines for underline title, 3 for overline title self.state_machine.previous_line(len(style) + 1) raise EOFError # let parent section re-evaluate @@ -2727,7 +2730,9 @@ class Line(SpecializedText): def eof(self, context): """Transition marker at end of section or document.""" marker = context[0].strip() - if len(marker) < 4: + if self.memo.section_bubble_up_kludge: + self.memo.section_bubble_up_kludge = 0 + elif len(marker) < 4: self.state_correction(context) if self.eofcheck: # ignore EOFError with sections lineno = self.state_machine.abs_line_number() - 1 -- cgit v1.2.1 From 9e963da38dd474d0fb414a81dfbbd3877373348f Mon Sep 17 00:00:00 2001 From: wilk Date: Sun, 25 May 2003 15:34:05 +0000 Subject: =?UTF-8?q?admonition=20pour=20admonition=20intertitre=20au=20lieu?= =?UTF-8?q?=20de=20inter-titre=20=EF=BF=BDpigraphe=20pour=20epigraph?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1347 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/fr.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index 94ef05fcf..dbce1ab38 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -22,14 +22,15 @@ directives = { u'note': 'note', u'astuce': 'tip', u'avertissement': 'warning', - u'admonestation': 'admonition', + u'admonition': 'admonition', u'encadr\u00E9': 'sidebar', u'sujet': 'topic', u'bloc-textuel': 'line-block', u'bloc-interpr\u00E9t\u00E9': 'parsed-literal', u'code-interpr\u00E9t\u00E9': 'parsed-literal', - u'inter-titre': 'rubric', + u'intertitre': 'rubric', u'exergue': 'epigraph', + u'\u00E9pigraphe': 'epigraph', u'chapeau': 'highlights', #u'questions': 'questions', #u'qr': 'questions', -- cgit v1.2.1 From 65f2d2861a9afa088fda4744035e03404ae61d04 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 25 May 2003 17:35:28 +0000 Subject: use charent for better encoding compatibility git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1348 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index decd6e18d..3028cea5e 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -294,7 +294,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_attribution(self, node): self.body.append( - self.starttag(node, 'p', u'\u2014', CLASS='attribution')) + self.starttag(node, 'p', u'—', CLASS='attribution')) def depart_attribution(self, node): self.body.append('

    \n') -- cgit v1.2.1 From b5e3d8aec79987f22d63fa8466d192d719bd3e13 Mon Sep 17 00:00:00 2001 From: grubert Date: Mon, 26 May 2003 07:20:52 +0000 Subject: Attribution support. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1349 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index a3ee14a60..fcca145d5 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1144,6 +1144,13 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('\\end{sffamily}\n\\end{center}\n'); + def visit_attribution(self, node): + # latex: mdash is "---" + self.body.append('\n--- ') + + def depart_attribution(self, node): + self.body.append('\n') + def visit_status(self, node): self.visit_docinfo_item(node, 'status') -- cgit v1.2.1 From 2d2c70309a0a98df5dd4b397c1b2ba5f40369079 Mon Sep 17 00:00:00 2001 From: grubert Date: Tue, 27 May 2003 06:43:46 +0000 Subject: Option --no-doc-info and --no-doc-title to standalone reader. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1352 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 13 ++++++++++--- docutils/readers/standalone.py | 15 +++++++++++++++ docutils/transforms/frontmatter.py | 4 ++++ 3 files changed, 29 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 029f2763a..691c2b565 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -43,10 +43,17 @@ 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_settings, + + default_section = 'options' + for section_name in config_parser.sections: + if section_name == default_section: + prefix = '' + else: + prefix = section_name + '_' + settings = config_parser.get_section(section_name) + make_paths_absolute(settings, parser.relative_path_settings, os.path.dirname(value)) - parser.values.__dict__.update(settings) + parser.values.__dict__.update(settings) def make_paths_absolute(pathdict, keys, base_path=None): """ diff --git a/docutils/readers/standalone.py b/docutils/readers/standalone.py index d7c5c8828..4e391edb5 100644 --- a/docutils/readers/standalone.py +++ b/docutils/readers/standalone.py @@ -25,6 +25,21 @@ class Reader(readers.Reader): document = None """A single document tree.""" + settings_spec = ( + 'Standalone Reader', + 'The standalone reader defines a list of transforms.', + ( + ('Disable doctitle transform. By default the transform is enabled.', + ['--no-doc-title'], + {'default': 1, 'action': 'store_false' }, + ), + ('Disable docinfo transform. By default the transform is enabled.', + ['--no-doc-info'], + {'default': 1, 'action': 'store_false' }, + ), + ) + ) + default_transforms = (references.Substitutions, frontmatter.DocTitle, frontmatter.DocInfo, diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index d1272ab15..19616b14d 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -105,6 +105,8 @@ class DocTitle(Transform): default_priority = 320 def apply(self): + if not getattr(self.document.settings,'no_doc_title',1): + return if self.promote_document_title(): self.promote_document_subtitle() @@ -246,6 +248,8 @@ class DocInfo(Transform): bibliographic fields (field_list).""" def apply(self): + if not getattr(self.document.settings,'no_doc_info',1): + return document = self.document index = document.first_child_not_matching_class( nodes.PreBibliographic) -- cgit v1.2.1 From c79fb3e264380201a4ca3c49211abd7b1a002313 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 27 May 2003 13:40:10 +0000 Subject: Revert to 1.28 code. 1.29 had bugs, was incomplete, and was premature. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1354 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 691c2b565..029f2763a 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -43,17 +43,10 @@ def read_config_file(option, opt, value, parser): """ config_parser = ConfigParser() config_parser.read(value) - - default_section = 'options' - for section_name in config_parser.sections: - if section_name == default_section: - prefix = '' - else: - prefix = section_name + '_' - settings = config_parser.get_section(section_name) - make_paths_absolute(settings, parser.relative_path_settings, + settings = config_parser.get_section('options') + make_paths_absolute(settings, parser.relative_path_settings, os.path.dirname(value)) - parser.values.__dict__.update(settings) + parser.values.__dict__.update(settings) def make_paths_absolute(pathdict, keys, base_path=None): """ -- cgit v1.2.1 From 4b58b2fdd49004676d1785bcf043241d318cc3ba Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 29 May 2003 15:16:21 +0000 Subject: Spanish mappings by Marcelo Huerta San Martin git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1358 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/es.py | 55 +++++++++++++++++++++ docutils/parsers/rst/languages/es.py | 92 ++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 docutils/languages/es.py create mode 100644 docutils/parsers/rst/languages/es.py (limited to 'docutils') diff --git a/docutils/languages/es.py b/docutils/languages/es.py new file mode 100644 index 000000000..599345dd5 --- /dev/null +++ b/docutils/languages/es.py @@ -0,0 +1,55 @@ +# Author: Marcelo Huerta San Martn +# Contact: mghsm@uol.com.ar +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Spanish-language mappings for language-dependent features of Docutils. +""" + +__docformat__ = 'reStructuredText' + +labels = { + 'author': u'Autor', + 'authors': u'Autores', + 'organization': u'Organizaci\u00f3n', + 'address': u'Direcci\u00f3n', + 'contact': u'Contacto', + 'version': u'Versi\u00f3n', + 'revision': u'Revisi\u00f3n', + 'status': u'Estado', + 'date': u'Fecha', + 'copyright': u'Copyright', + 'dedication': u'Dedicatoria', + 'abstract': u'Resumen', + 'attention': u'\u00a1Atenci\u00f3n!', + 'caution': u'\u00a1Precauci\u00f3n!', + 'danger': u'\u00a1PELIGRO!', + 'error': u'Error', + 'hint': u'Sugerencia', + 'important': u'Importante', + 'note': u'Nota', + 'tip': u'Consejo', + 'warning': u'Advertencia', + 'contents': u'Contenido'} +"""Mapping of node class name to label text.""" + +bibliographic_fields = { + u'autor': 'author', + u'autores': 'authors', + u'organizaci\u00f3n': 'organization', + u'direcci\u00f3n': 'address', + u'contacto': 'contact', + u'versi\u00f3n': 'version', + u'revisi\u00f3n': 'revision', + u'estado': 'status', + u'fecha': 'date', + u'copyright': 'copyright', + u'dedicatoria': 'dedication', + u'resumen': 'abstract'} +"""Spanish (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/es.py b/docutils/parsers/rst/languages/es.py new file mode 100644 index 000000000..d92800187 --- /dev/null +++ b/docutils/parsers/rst/languages/es.py @@ -0,0 +1,92 @@ +# Author: Marcelo Huerta San Martn +# Contact: mghsm@uol.com.ar +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Spanish-language mappings for language-dependent features of +reStructuredText. +""" + +__docformat__ = 'reStructuredText' + + +directives = { + u'atenci\u00f3n': 'attention', + u'atencion': 'attention', + u'precauci\u00f3n': 'caution', + u'precaucion': 'caution', + u'peligro': 'danger', + u'error': 'error', + u'sugerencia': 'hint', + u'importante': 'important', + u'nota': 'note', + u'consejo': 'tip', + u'advertencia': 'warning', + u'admonition (translation required)': 'admonition', + u'nota-al-margen': 'sidebar', + u'tema': 'topic', + u'bloque-de-lineas': 'line-block', + u'bloque-de-l\u00edneas': 'line-block', + u'literal-evaluado': 'parsed-literal', + u'rubric (translation required)': 'rubric', + u'epigraph (translation required)': 'epigraph', + u'highlights (translation required)': 'highlights', + #'questions': 'questions', + #'qa': 'questions', + #'faq': 'questions', + u'meta': 'meta', + #'imagemap': 'imagemap', + u'imagen': 'image', + u'figura': 'figure', + u'incluir': 'include', + u'raw': 'raw', + u'reemplazar': 'replace', + u'unicode': 'unicode', + u'class (translation required)': 'class', + u'contenido': 'contents', + u'numseccion': 'sectnum', + u'numsecci\u00f3n': 'sectnum', + u'numeracion-seccion': 'sectnum', + u'numeraci\u00f3n-secci\u00f3n': 'sectnum', + u'notas-destino': 'target-notes', + #'footnotes': 'footnotes', + #'citations': 'citations', + u'restructuredtext-test-directive': 'restructuredtext-test-directive'} +"""English name to registered (in directives/__init__.py) directive name +mapping.""" + +roles = { + u'abreviatura': 'abbreviation', + u'ab': 'abbreviation', + u'acronimo': 'acronym', + u'acronimo': 'acronym', + u'ac': 'acronym', + u'indice': 'index', + u'i': 'index', + u'referencia-titulo': 'title-reference', + u'titulo': 'title-reference', + u't': 'title-reference', + u'referencia-pep': 'pep-reference', + u'pep': 'pep-reference', + u'referencia-rfc': 'rfc-reference', + u'rfc': 'rfc-reference', + u'enfasis': 'emphasis', + u'\u00e9nfasis': 'emphasis', + u'destacado': 'strong', + u'literal': 'literal', + u'referencia-con-nombre': 'named-reference', + u'referencia-anonima': 'anonymous-reference', + u'referencia-an\u00f3nima': 'anonymous-reference', + u'referencia-nota-al-pie': 'footnote-reference', + u'referencia-cita': 'citation-reference', + u'referencia-sustitucion': 'substitution-reference', + u'referencia-sustituci\u00f3n': 'substitution-reference', + u'destino': 'target', + u'referencia-uri': 'uri-reference', + u'uri': 'uri-reference', + u'url': 'uri-reference', + } +"""Mapping of Spanish role names to canonical role names for interpreted text. +""" -- cgit v1.2.1 From 796fb59a7f9cd5c32326aa70dd8b564576ef982e Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 29 May 2003 15:17:58 +0000 Subject: revised new --no-doc-title & --no-doc-info options git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1359 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/standalone.py | 24 +++++++++++------------- docutils/transforms/frontmatter.py | 4 ++-- 2 files changed, 13 insertions(+), 15 deletions(-) (limited to 'docutils') diff --git a/docutils/readers/standalone.py b/docutils/readers/standalone.py index 4e391edb5..14b75e3d7 100644 --- a/docutils/readers/standalone.py +++ b/docutils/readers/standalone.py @@ -27,19 +27,17 @@ class Reader(readers.Reader): settings_spec = ( 'Standalone Reader', - 'The standalone reader defines a list of transforms.', - ( - ('Disable doctitle transform. By default the transform is enabled.', - ['--no-doc-title'], - {'default': 1, 'action': 'store_false' }, - ), - ('Disable docinfo transform. By default the transform is enabled.', - ['--no-doc-info'], - {'default': 1, 'action': 'store_false' }, - ), - ) - ) - + None, + (('Disable the promotion of a lone top-level section title to ' + 'document title (and subsequent section title to document ' + 'subtitle promotion; enabled by default).', + ['--no-doc-title'], + {'dest': 'doctitle_xform', 'action': 'store_false', 'default': 1}), + ('Disable the bibliographic field list transform (enabled by ' + 'default).', + ['--no-doc-info'], + {'dest': 'docinfo_xform', 'action': 'store_false', 'default': 1}),)) + default_transforms = (references.Substitutions, frontmatter.DocTitle, frontmatter.DocInfo, diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index 19616b14d..00afc6fd2 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -105,7 +105,7 @@ class DocTitle(Transform): default_priority = 320 def apply(self): - if not getattr(self.document.settings,'no_doc_title',1): + if not getattr(self.document.settings, 'doctitle_xform', 1): return if self.promote_document_title(): self.promote_document_subtitle() @@ -248,7 +248,7 @@ class DocInfo(Transform): bibliographic fields (field_list).""" def apply(self): - if not getattr(self.document.settings,'no_doc_info',1): + if not getattr(self.document.settings, 'docinfo_xform', 1): return document = self.document index = document.first_child_not_matching_class( -- cgit v1.2.1 From 4635b386ba4ca833b623f3d22ac9456643d9e279 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 30 May 2003 18:13:07 +0000 Subject: added --attribution option git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1361 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 3028cea5e..6d9f170f4 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -57,7 +57,12 @@ class Writer(writers.Writer): '"brackets". Default is "superscript".', ['--footnote-references'], {'choices': ['superscript', 'brackets'], 'default': 'superscript', - 'metavar': ''}), + 'metavar': ''}), + ('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 ' @@ -292,12 +297,19 @@ class HTMLTranslator(nodes.NodeVisitor): 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', u'—', CLASS='attribution')) + self.starttag(node, 'p', prefix, CLASS='attribution')) def depart_attribution(self, node): - self.body.append('

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

    \n') def visit_author(self, node): self.visit_docinfo_item(node, 'author') -- cgit v1.2.1 From 9323acb9584c1a30e1fd6cf3a7c48c8adf6dfd1f Mon Sep 17 00:00:00 2001 From: richieadler Date: Sat, 31 May 2003 02:15:47 +0000 Subject: no message git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1363 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/es.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index d92800187..ee0ae5247 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -24,15 +24,17 @@ directives = { u'nota': 'note', u'consejo': 'tip', u'advertencia': 'warning', - u'admonition (translation required)': 'admonition', + u'exhortacion': 'admonition', + u'exhortaci\u00f3n': 'admonition', u'nota-al-margen': 'sidebar', u'tema': 'topic', u'bloque-de-lineas': 'line-block', u'bloque-de-l\u00edneas': 'line-block', u'literal-evaluado': 'parsed-literal', - u'rubric (translation required)': 'rubric', - u'epigraph (translation required)': 'epigraph', - u'highlights (translation required)': 'highlights', + u'firma': 'rubric', + u'ep\u00edgrafe': 'epigraph', + u'epigrafe': 'epigraph', + u'destacado': 'highlights', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', @@ -44,7 +46,7 @@ directives = { u'raw': 'raw', u'reemplazar': 'replace', u'unicode': 'unicode', - u'class (translation required)': 'class', + u'clase': 'class', u'contenido': 'contents', u'numseccion': 'sectnum', u'numsecci\u00f3n': 'sectnum', -- cgit v1.2.1 From 34af804b256cc97578f4bf9c16373d06e798029d Mon Sep 17 00:00:00 2001 From: grubert Date: Mon, 2 Jun 2003 08:56:36 +0000 Subject: Add attribution and align to the right. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1365 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index fcca145d5..29c150121 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -36,7 +36,12 @@ class Writer(writers.Writer): '"brackets". Default is "brackets".', ['--footnote-references'], {'choices': ['superscript', 'brackets'], 'default': 'brackets', - 'metavar': ''}), + 'metavar': ''}), + ('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 "style.tex". ' 'If this is set to "" disables input.' @@ -1144,12 +1149,20 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('\\end{sffamily}\n\\end{center}\n'); + attribution_formats = {'dash': ('---', ''), + 'parentheses': ('(', ')'), + 'parens': ('(', ')'), + 'none': ('', '')} + def visit_attribution(self, node): - # latex: mdash is "---" - self.body.append('\n--- ') + 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('\n') + self.body.append(self.context.pop() + '\n') + self.body.append('\\end{flushright}\n') def visit_status(self, node): self.visit_docinfo_item(node, 'status') -- cgit v1.2.1 From ee621bbedd53df1d330732f37c5df4cc1d9e0264 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 3 Jun 2003 02:12:18 +0000 Subject: Moved config file processing to docutils/frontend.py. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1368 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index 20a4c7f19..381c65711 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -87,14 +87,8 @@ class Publisher: #@@@ Add self.source & self.destination to components in future? option_parser = OptionParser( components=(settings_spec, self.parser, self.reader, self.writer), + defaults=defaults, read_config_files=1, usage=usage, description=description) - config = ConfigParser() - config.read_standard_files() - 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 get_settings(self, usage=None, description=None, -- cgit v1.2.1 From 14af1be64f8febc346e00f6e7ce696e0247f4beb Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 3 Jun 2003 02:13:27 +0000 Subject: Added validation functionality for config files. Added "--error-encoding" option/setting, "_disable_config" internal setting. Added encoding validation; updated "--input-encoding" and "--output-encoding". Moved config file processing from docutils/core.py. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1369 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 139 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 128 insertions(+), 11 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 029f2763a..f352f6254 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -19,7 +19,9 @@ __docformat__ = 'reStructuredText' import os import os.path +import types import ConfigParser as CP +import codecs import docutils from docutils import optik from docutils.optik import Values @@ -42,12 +44,62 @@ def read_config_file(option, opt, value, parser): Read a configuration file during option processing. (Option callback.) """ config_parser = ConfigParser() - config_parser.read(value) + config_parser.read(value, parser) settings = config_parser.get_section('options') make_paths_absolute(settings, parser.relative_path_settings, os.path.dirname(value)) parser.values.__dict__.update(settings) +def set_encoding(option, opt, value, parser): + """ + Validate & set the encoding specified. (Option callback.) + """ + try: + value = validate_encoding(value, option.default) + except LookupError, error: + raise optik.OptionValueError('option "%s": %s' % (opt, error)) + setattr(parser.values, option.dest, value) + +def validate_encoding(value, default): + try: + codecs.lookup(value) + except LookupError: + raise LookupError('unknown encoding: "%s"' % value) + return value + +def set_encoding_and_error_handler(option, opt, value, parser): + """ + Validate & set the encoding and error handlers specified. + (Option callback.) + """ + try: + value = validate_encoding_and_error_handler(value, option.default) + except LookupError, error: + raise optik.OptionValueError('option "%s": %s' % (opt, error)) + setattr(parser.values, option.dest, value) + +def validate_encoding_and_error_handler(value, default): + if ':' in value: + encoding, handler = value.split(':') + else: + encoding = value + handler = default.split(':')[1] + validate_encoding(encoding, default) + try: + codecs.lookup_error(handler) + except AttributeError: + if handler not in ('strict', 'ignore', 'replace'): + raise LookupError( + 'unknown encoding error handler: "%s" (choices: ' + '"strict", "ignore", or "replace")' % handler) + except LookupError: + raise LookupError( + 'unknown encoding error handler: "%s" (choices: ' + '"strict", "ignore", "replace", "backslashreplace", ' + '"xmlcharrefreplace", and possibly others; see documentation for ' + 'the Python ``codecs`` module)' % handler) + return encoding + ':' + handler + def make_paths_absolute(pathdict, keys, base_path=None): """ Interpret filesystem path settings relative to the `base_path` given. @@ -81,6 +133,11 @@ class OptionParser(optik.OptionParser, docutils.SettingsSpec): thresholds = {'info': 1, 'warning': 2, 'error': 3, 'severe': 4, 'none': 5} """Lookup table for --report and --halt threshold values.""" + if hasattr(codecs, 'backslashreplace_errors'): + default_error_encoding_error_handler = 'backslashreplace' + else: + default_error_encoding_error_handler = 'replace' + settings_spec = ( 'General Docutils Options', None, @@ -154,10 +211,26 @@ class OptionParser(optik.OptionParser, docutils.SettingsSpec): ('Send the output of system messages (warnings) to .', ['--warnings'], {'dest': 'warning_stream', 'metavar': ''}), ('Specify the encoding of input text. Default is locale-dependent.', - ['--input-encoding', '-i'], {'metavar': ''}), - ('Specify the encoding for output. Default is UTF-8.', + ['--input-encoding', '-i'], + {'action': 'callback', 'callback': set_encoding, + 'metavar': '', 'type': 'string', 'dest': 'input_encoding'}), + ('Specify the text encoding for output. Default is UTF-8. ' + 'Optionally also specify the encoding error handler for unencodable ' + 'characters (see "--error-encoding"); default is "strict".', ['--output-encoding', '-o'], - {'metavar': '', 'default': 'utf-8'}), + {'action': 'callback', 'callback': set_encoding_and_error_handler, + 'metavar': '', 'type': 'string', + 'dest': 'output_encoding', 'default': 'utf-8:strict'}), + ('Specify the text encoding for error output. Default is ASCII. ' + 'Optionally also specify the encoding error handler for unencodable ' + 'characters, after a colon (":"). Acceptable values are the same ' + 'as for the "error" parameter of Python\'s ``encode`` string ' + 'method. Default is "%s".' % default_error_encoding_error_handler, + ['--error-encoding', '-e'], + {'action': 'callback', 'callback': set_encoding_and_error_handler, + 'metavar': '', 'type': 'string', + 'dest': 'error_encoding', + 'default': 'ascii:%s' % default_error_encoding_error_handler}), ('Specify the language of input text (ISO 639 2-letter identifier).' ' Default is "en" (English).', ['--language', '-l'], {'dest': 'language_code', 'default': 'en', @@ -189,12 +262,15 @@ class OptionParser(optik.OptionParser, docutils.SettingsSpec): ends. Setting specs specific to individual Docutils components are also used (see `populate_from_components()`).""" + settings_default_overrides = {'_disable_config': None} + relative_path_settings = ('warning_stream',) version_template = '%%prog (Docutils %s)' % docutils.__version__ """Default version message.""" - def __init__(self, components=(), *args, **kwargs): + def __init__(self, components=(), defaults=None, read_config_files=None, + *args, **kwargs): """ `components` is a list of Docutils components each containing a ``.settings_spec`` attribute. `defaults` is a mapping of setting @@ -209,12 +285,19 @@ class OptionParser(optik.OptionParser, docutils.SettingsSpec): *args, **kwargs) if not self.version: self.version = self.version_template - # 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_settings = list(self.relative_path_settings) - self.populate_from_components(tuple(components) + (self,)) + self.populate_from_components((self,) + tuple(components)) + defaults = defaults or {} + if read_config_files and not self.defaults['_disable_config']: + config = ConfigParser() + config.read_standard_files(self) + config_settings = config.get_section('options') + make_paths_absolute(config_settings, self.relative_path_settings) + defaults.update(config_settings) + # Internal settings with no defaults from settings specifications; + # initialize manually: + self.set_defaults(_source=None, _destination=None, **defaults) def populate_from_components(self, components): for component in components: @@ -281,8 +364,42 @@ class ConfigParser(CP.ConfigParser): """Docutils configuration files, using ConfigParser syntax (section 'options'). Later files override earlier ones.""" - def read_standard_files(self): - self.read(self.standard_config_files) + validation = { + 'options': {'input_encoding': validate_encoding, + 'output_encoding': validate_encoding_and_error_handler, + 'error_encoding': validate_encoding_and_error_handler}} + """{section: {option: validation function}} mapping, used by + `validate_options`. Validation functions take two parameters: value and + default. They return a modified value, or raise an exception.""" + + def read_standard_files(self, option_parser): + self.read(self.standard_config_files, option_parser) + + def read(self, filenames, option_parser): + if type(filenames) in types.StringTypes: + filenames = [filenames] + for filename in filenames: + CP.ConfigParser.read(self, filename) + self.validate_options(filename, option_parser) + + def validate_options(self, filename, option_parser): + for section in self.validation.keys(): + if not self.has_section(section): + continue + for option in self.validation[section].keys(): + if self.has_option(section, option): + value = self.get(section, option) + validator = self.validation[section][option] + default = option_parser.defaults[option] + try: + new_value = validator(value, default) + except Exception, error: + raise ValueError( + 'Error in config file "%s", section "[%s]":\n' + ' %s: %s\n %s = %s' + % (filename, section, error.__class__.__name__, + error, option, value)) + self.set(section, option, new_value) def optionxform(self, optionstr): """ -- cgit v1.2.1 From c0c0b7b9afb2601cba0234d3fe52b3361f27e934 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 3 Jun 2003 02:13:43 +0000 Subject: Added support for output encoding error handlers. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1370 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index 6bd59210e..52d500dc7 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -30,7 +30,7 @@ class Input(TransformSpec): def __init__(self, settings=None, source=None, source_path=None, encoding=None): self.encoding = encoding - """The character encoding for the input source.""" + """Text encoding for the input source.""" if settings: if not encoding: @@ -109,8 +109,13 @@ class Output(TransformSpec): def __init__(self, settings=None, destination=None, destination_path=None, encoding=None): + encoding, error_handler = (encoding.split(':') + ['strict'])[:2] + self.encoding = encoding - """The character encoding for the output destination.""" + """Text encoding for the output destination.""" + + self.error_handler = error_handler + """Text encoding error handler.""" if settings: if not encoding: @@ -142,7 +147,7 @@ class Output(TransformSpec): if self.encoding and self.encoding.lower() == 'unicode': return data else: - return data.encode(self.encoding or '') + return data.encode(self.encoding, self.error_handler) class FileInput(Input): -- cgit v1.2.1 From 02e2060de0b8eb721746ea5a4815d29f3519390e Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 3 Jun 2003 02:14:05 +0000 Subject: Added support for encoding Reporter stderr output, and encoding error handlers. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1371 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/utils.py b/docutils/utils.py index 01c365cb9..152d5067c 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -75,7 +75,7 @@ class Reporter: """List of names for system message levels, indexed by level.""" def __init__(self, source, report_level, halt_level, stream=None, - debug=0): + debug=0, encoding='ascii:replace'): """ Initialize the `ConditionSet` forthe `Reporter`'s default category. @@ -90,6 +90,8 @@ class Reporter: - `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). + - `encoding`: The encoding and error handler (colon-separated) + for stderr output. """ self.source = source """The path to or description of the source data.""" @@ -99,6 +101,14 @@ class Reporter: elif type(stream) in (StringType, UnicodeType): raise NotImplementedError('This should open a file for writing.') + encoding, error_handler = (encoding.split(':') + ['replace'])[:2] + + 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 ''.""" @@ -164,10 +174,11 @@ class Reporter: *children, **attributes) debug, report_level, halt_level, stream = self[category].astuple() if level >= report_level or debug and level == 0: + msgtext = msg.astext().encode(self.encoding, self.error_handler) if category: - print >>stream, msg.astext(), '[%s]' % category + print >>stream, msgtext, '[%s]' % category else: - print >>stream, msg.astext() + print >>stream, msgtext if level >= halt_level: raise SystemMessage(msg) if level > 0 or debug: @@ -381,7 +392,8 @@ 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) + stream=settings.warning_stream, debug=settings.debug, + encoding=settings.error_encoding) document = nodes.document(settings, reporter, source=source) document.note_source(source, -1) return document @@ -422,7 +434,7 @@ def relative_path(source, target): def get_source_line(node): """ Return the "source" and "line" attributes from the `node` given or from - it's closest ancestor. + its closest ancestor. """ while node: if node.source or node.line: -- cgit v1.2.1 From f43900b985a1c3fae98d7a99847250750039b6b4 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 3 Jun 2003 02:16:59 +0000 Subject: Added "pull-quote" directive. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1373 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 1 + docutils/parsers/rst/directives/body.py | 8 ++++++++ docutils/parsers/rst/languages/de.py | 1 + docutils/parsers/rst/languages/en.py | 1 + docutils/parsers/rst/languages/es.py | 1 + docutils/parsers/rst/languages/fr.py | 1 + docutils/parsers/rst/languages/it.py | 1 + docutils/parsers/rst/languages/sk.py | 1 + docutils/parsers/rst/languages/sv.py | 1 + 9 files changed, 16 insertions(+) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 814197eab..1a113db2d 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -100,6 +100,7 @@ _directive_registry = { 'rubric': ('body', 'rubric'), 'epigraph': ('body', 'epigraph'), 'highlights': ('body', 'highlights'), + 'pull-quote': ('body', 'pull_quote'), #'questions': ('body', 'question_list'), 'image': ('images', 'image'), 'figure': ('images', 'figure'), diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index bc3f5b742..c2fd6b99d 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -112,3 +112,11 @@ def highlights(name, arguments, options, content, lineno, return [block_quote] + messages highlights.content = 1 + +def pull_quote(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + block_quote, messages = state.block_quote(content, content_offset) + block_quote.set_class('pull-quote') + return [block_quote] + messages + +pull_quote.content = 1 diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index 03ec58530..b91b16736 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -31,6 +31,7 @@ directives = { 'rubric (translation required)': 'rubric', 'epigraph (translation required)': 'epigraph', 'highlights (translation required)': 'highlights', + 'pull-quote (translation required)': 'pull-quote', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index 01d30e2b8..cb3ec000d 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -30,6 +30,7 @@ directives = { 'rubric': 'rubric', 'epigraph': 'epigraph', 'highlights': 'highlights', + 'pull-quote': 'pull-quote', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index ee0ae5247..2d51a793e 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -35,6 +35,7 @@ directives = { u'ep\u00edgrafe': 'epigraph', u'epigrafe': 'epigraph', u'destacado': 'highlights', + u'pull-quote (translation required)': 'pull-quote', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index dbce1ab38..0164fe0eb 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -32,6 +32,7 @@ directives = { u'exergue': 'epigraph', u'\u00E9pigraphe': 'epigraph', u'chapeau': 'highlights', + u'pull-quote (translation required)': 'pull-quote', #u'questions': 'questions', #u'qr': 'questions', #u'faq': 'questions', diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index fc93e3451..21ede5bce 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -30,6 +30,7 @@ directives = { 'rubric (translation required)': 'rubric', 'epigraph (translation required)': 'epigraph', 'highlights (translation required)': 'highlights', + 'pull-quote (translation required)': 'pull-quote', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/sk.py b/docutils/parsers/rst/languages/sk.py index 433f37f2f..772f0433f 100644 --- a/docutils/parsers/rst/languages/sk.py +++ b/docutils/parsers/rst/languages/sk.py @@ -30,6 +30,7 @@ directives = { u'rubric (translation required)': 'rubric', u'epigraph (translation required)': 'epigraph', u'highlights (translation required)': 'highlights', + u'pull-quote (translation required)': 'pull-quote', #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 fe31c9b7f..e126b9dd1 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -29,6 +29,7 @@ directives = { u'mellanrubrik': 'rubric', u'epigraph (translation required)': 'epigraph', u'highlights (translation required)': 'highlights', + u'pull-quote (translation required)': 'pull-quote', # u'fr\u00e5gor': 'questions', # NOTE: A bit long, but recommended by http://www.nada.kth.se/dataterm/: # u'fr\u00e5gor-och-svar': 'questions', -- cgit v1.2.1 From f4fc97209372be9399682ef969815a3557ceda88 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 3 Jun 2003 02:19:25 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1374 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 2 +- docutils/nodes.py | 4 ++-- docutils/readers/pep.py | 6 +----- 3 files changed, 4 insertions(+), 8 deletions(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index 9c1f2569f..4020133f9 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -55,7 +55,7 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.2.8' +__version__ = '0.2.9' """``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 diff --git a/docutils/nodes.py b/docutils/nodes.py index f2618b9db..b24f5f9fc 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1089,8 +1089,8 @@ class system_message(Special, PreBibliographic, Element, BackLinkable): def astext(self): line = self.get('line', '') - return '%s:%s: (%s/%s) %s' % (self['source'], line, self['type'], - self['level'], Element.astext(self)) + return u'%s:%s: (%s/%s) %s' % (self['source'], line, self['type'], + self['level'], Element.astext(self)) class pending(Special, Invisible, PreBibliographic, Element): diff --git a/docutils/readers/pep.py b/docutils/readers/pep.py index 7b75b94e8..e21d8f213 100644 --- a/docutils/readers/pep.py +++ b/docutils/readers/pep.py @@ -11,10 +11,6 @@ Python Enhancement Proposal (PEP) Reader. __docformat__ = 'reStructuredText' -import sys -import os -import re -from docutils import nodes from docutils.readers import standalone from docutils.transforms import peps, references from docutils.parsers import rst @@ -23,7 +19,7 @@ from docutils.parsers import rst class Inliner(rst.states.Inliner): """ - Extend `rst.Inliner` to for local PEP references. + Extend `rst.Inliner` for local PEP references. """ pep_url = rst.states.Inliner.pep_url_local -- cgit v1.2.1 From 200e86c1464ff1c86d01270ed45bfef065b21a52 Mon Sep 17 00:00:00 2001 From: wilk Date: Wed, 4 Jun 2003 21:55:55 +0000 Subject: accroche = pull-quote git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1377 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/fr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index 0164fe0eb..311c5db0f 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -32,7 +32,7 @@ directives = { u'exergue': 'epigraph', u'\u00E9pigraphe': 'epigraph', u'chapeau': 'highlights', - u'pull-quote (translation required)': 'pull-quote', + u'accroche': 'pull-quote', #u'questions': 'questions', #u'qr': 'questions', #u'faq': 'questions', -- cgit v1.2.1 From 26f053068c13c1b4fdcf5447a6f0ef8422b45d3a Mon Sep 17 00:00:00 2001 From: richieadler Date: Thu, 5 Jun 2003 00:33:38 +0000 Subject: "pull quote" translation git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1378 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/es.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index 2d51a793e..3b0a15b95 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -35,7 +35,7 @@ directives = { u'ep\u00edgrafe': 'epigraph', u'epigrafe': 'epigraph', u'destacado': 'highlights', - u'pull-quote (translation required)': 'pull-quote', + u'destacado': 'pull-quote', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', -- cgit v1.2.1 From 47edfa1d498f5bbecc83c26380cdce3c9990cf43 Mon Sep 17 00:00:00 2001 From: richieadler Date: Thu, 5 Jun 2003 00:42:44 +0000 Subject: no message git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1379 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/es.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index 3b0a15b95..5f3f964a6 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -35,7 +35,7 @@ directives = { u'ep\u00edgrafe': 'epigraph', u'epigrafe': 'epigraph', u'destacado': 'highlights', - u'destacado': 'pull-quote', + u'cita-destacada': 'pull-quote', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', -- cgit v1.2.1 From 389a395279a3fa0459a6ebe5dfa992b2973c4956 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 5 Jun 2003 15:14:36 +0000 Subject: Added explicit interpreted text roles for standard inline markup: "emphasis", "strong", "literal". Implemented "superscript" and "subscript" interpreted text roles. Added initial support for "abbreviation" and "acronym" roles; incomplete. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1383 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 97 ++++++++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 37 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 3901d6078..4a4da3478 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -474,13 +474,15 @@ class Inliner: _interpreted_roles = { # Values of ``None`` mean "not implemented yet": - 'title-reference': 'title_reference_role', - 'abbreviation': None, - 'acronym': None, + 'title-reference': 'generic_interpreted_role', + 'abbreviation': 'generic_interpreted_role', + 'acronym': 'generic_interpreted_role', 'index': None, - 'emphasis': None, - 'strong': None, - 'literal': None, + 'subscript': 'generic_interpreted_role', + 'superscript': 'generic_interpreted_role', + 'emphasis': 'generic_interpreted_role', + 'strong': 'generic_interpreted_role', + 'literal': 'generic_interpreted_role', 'named-reference': None, 'anonymous-reference': None, 'uri-reference': None, @@ -490,7 +492,7 @@ class Inliner: 'citation-reference': None, 'substitution-reference': None, 'target': None, - } + 'restructuredtext-unimplemented-role': None} """Mapping of canonical interpreted text role name to method name. Initializes a name to bound-method mapping in `__init__`.""" @@ -498,6 +500,18 @@ class Inliner: """The role to use when no explicit role is given. Override in subclasses.""" + generic_roles = {'abbreviation': nodes.abbreviation, + 'acronym': nodes.acronym, + 'emphasis': nodes.emphasis, + 'literal': nodes.literal, + 'strong': nodes.strong, + 'subscript': nodes.subscript, + 'superscript': nodes.superscript, + 'title-reference': nodes.title_reference,} + """Mapping of canonical interpreted text role name to node class. + Used by the `generic_interpreted_role` method for simple, straightforward + roles (simple wrapping; no extra processing).""" + def __init__(self, roles=None): """ `roles` is a mapping of canonical role name to role function or bound @@ -875,9 +889,11 @@ class Inliner: return uri def interpreted(self, before, after, rawsource, text, role, lineno): - role_function, messages = self.get_role_function(role, lineno) + role_function, canonical, messages = self.get_role_function(role, + lineno) if role_function: - nodelist, messages2 = role_function(role, rawsource, text, lineno) + nodelist, messages2 = role_function(canonical, rawsource, text, + lineno) messages.extend(messages2) return before, nodelist, after, messages else: @@ -888,34 +904,34 @@ class Inliner: msg_text = [] if role: name = role.lower() - canonical = None - try: - canonical = self.language.roles[name] - except AttributeError, error: - msg_text.append('Problem retrieving role entry from language ' - 'module %r: %s.' % (self.language, error)) - except KeyError: - msg_text.append('No role entry for "%s" in module "%s".' - % (role, self.language.__name__)) - if not canonical: - try: - canonical = _fallback_language_module.roles[name] - msg_text.append('Using English fallback for role "%s".' - % role) - except KeyError: - msg_text.append('Trying "%s" as canonical role name.' - % role) - # Should be an English name, but just in case: - canonical = name - if msg_text: - message = self.reporter.info('\n'.join(msg_text), line=lineno) - messages.append(message) + else: + name = self.default_interpreted_role + canonical = None + try: + canonical = self.language.roles[name] + except AttributeError, error: + msg_text.append('Problem retrieving role entry from language ' + 'module %r: %s.' % (self.language, error)) + except KeyError: + msg_text.append('No role entry for "%s" in module "%s".' + % (name, self.language.__name__)) + if not canonical: try: - return self.interpreted_roles[canonical], messages + canonical = _fallback_language_module.roles[name] + msg_text.append('Using English fallback for role "%s".' + % name) except KeyError: - raise UnknownInterpretedRoleError(messages) - else: - return self.interpreted_roles[self.default_interpreted_role], [] + msg_text.append('Trying "%s" as canonical role name.' + % name) + # Should be an English name, but just in case: + canonical = name + if msg_text: + message = self.reporter.info('\n'.join(msg_text), line=lineno) + messages.append(message) + try: + return self.interpreted_roles[canonical], canonical, messages + except KeyError: + raise UnknownInterpretedRoleError(messages) def literal(self, match, lineno): before, inlines, remaining, sysmessages, endstring = self.inline_obj( @@ -1083,8 +1099,15 @@ class Inliner: '_': reference, '__': anonymous_reference} - def title_reference_role(self, role, rawtext, text, lineno): - return [nodes.title_reference(rawtext, text)], [] + def generic_interpreted_role(self, role, rawtext, text, lineno): + try: + role_class = self.generic_roles[role] + except KeyError: + msg = self.reporter.error('Unknown interpreted text role: "%s".' + % role, line=lineno) + prb = self.problematic(text, text, msg) + return [prb], [msg] + return [role_class(rawtext, text)], [] def pep_reference_role(self, role, rawtext, text, lineno): try: -- cgit v1.2.1 From e1a069ecdbd5ff171d024fe5628e511d644a526f Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 5 Jun 2003 15:15:09 +0000 Subject: Added support for "inline", "subscript", "superscript". Added initial support for "abbreviation" and "acronym"; incomplete. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1384 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 6d9f170f4..788e2021e 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -273,6 +273,20 @@ class HTMLTranslator(nodes.NodeVisitor): 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')) @@ -750,6 +764,12 @@ class HTMLTranslator(nodes.NodeVisitor): 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')) @@ -965,6 +985,12 @@ class HTMLTranslator(nodes.NodeVisitor): 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 @@ -984,6 +1010,12 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_subtitle(self, node): self.body.append(self.context.pop()) + 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): if node['level'] < self.document.reporter['writer'].report_level: # Level is too low to display: -- cgit v1.2.1 From 6accfecf813ed11c110351c02d98e11b43f57c0a Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 5 Jun 2003 15:15:42 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1385 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/en.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index cb3ec000d..bc488a53e 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -60,6 +60,10 @@ roles = { 'ac': 'acronym', 'index': 'index', 'i': 'index', + 'subscript': 'subscript', + 'sub': 'subscript', + 'superscript': 'superscript', + 'sup': 'superscript', 'title-reference': 'title-reference', 'title': 'title-reference', 't': 'title-reference', @@ -78,7 +82,6 @@ roles = { 'target': 'target', 'uri-reference': 'uri-reference', 'uri': 'uri-reference', - 'url': 'uri-reference', - } + 'url': 'uri-reference',} """Mapping of English role names to canonical role names for interpreted text. """ -- cgit v1.2.1 From 2d01f588ef96fc5818aa5ab29c704278d83abbc4 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 7 Jun 2003 13:28:03 +0000 Subject: improved exception traceback handling git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1386 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index f352f6254..e3730a5a8 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -19,6 +19,7 @@ __docformat__ = 'reStructuredText' import os import os.path +import sys import types import ConfigParser as CP import codecs @@ -57,14 +58,16 @@ def set_encoding(option, opt, value, parser): try: value = validate_encoding(value, option.default) except LookupError, error: - raise optik.OptionValueError('option "%s": %s' % (opt, error)) + raise (optik.OptionValueError('option "%s": %s' % (opt, error)), + None, sys.exc_info[2]) setattr(parser.values, option.dest, value) def validate_encoding(value, default): try: codecs.lookup(value) except LookupError: - raise LookupError('unknown encoding: "%s"' % value) + raise (LookupError('unknown encoding: "%s"' % value), + None, sys.exc_info[2]) return value def set_encoding_and_error_handler(option, opt, value, parser): @@ -75,7 +78,8 @@ def set_encoding_and_error_handler(option, opt, value, parser): try: value = validate_encoding_and_error_handler(value, option.default) except LookupError, error: - raise optik.OptionValueError('option "%s": %s' % (opt, error)) + raise (optik.OptionValueError('option "%s": %s' % (opt, error)), + None, sys.exc_info[2]) setattr(parser.values, option.dest, value) def validate_encoding_and_error_handler(value, default): @@ -89,15 +93,17 @@ def validate_encoding_and_error_handler(value, default): codecs.lookup_error(handler) except AttributeError: if handler not in ('strict', 'ignore', 'replace'): - raise LookupError( + raise (LookupError( 'unknown encoding error handler: "%s" (choices: ' - '"strict", "ignore", or "replace")' % handler) + '"strict", "ignore", or "replace")' % handler), + None, sys.exc_info[2]) except LookupError: - raise LookupError( + raise (LookupError( 'unknown encoding error handler: "%s" (choices: ' '"strict", "ignore", "replace", "backslashreplace", ' '"xmlcharrefreplace", and possibly others; see documentation for ' - 'the Python ``codecs`` module)' % handler) + 'the Python ``codecs`` module)' % handler), + None, sys.exc_info[2]) return encoding + ':' + handler def make_paths_absolute(pathdict, keys, base_path=None): @@ -394,11 +400,11 @@ class ConfigParser(CP.ConfigParser): try: new_value = validator(value, default) except Exception, error: - raise ValueError( + raise (ValueError( 'Error in config file "%s", section "[%s]":\n' ' %s: %s\n %s = %s' % (filename, section, error.__class__.__name__, - error, option, value)) + error, option, value)), None, sys.exc_info()[2]) self.set(section, option, new_value) def optionxform(self, optionstr): -- cgit v1.2.1 From ca3e6f5192beff276e4d3a46b18969bc68d04e1b Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 7 Jun 2003 13:28:51 +0000 Subject: updated encoding git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1387 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 29c150121..5592145e3 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -28,7 +28,7 @@ class Writer(writers.Writer): settings_spec = ( 'LaTeX-Specific Options', - 'The LaTeX "--output-encoding" default is "latin-1".', + 'The LaTeX "--output-encoding" default is "latin-1:strict".', (('Specify documentclass. Default is "article".', ['--documentclass'], {'default': 'article', }), @@ -75,7 +75,7 @@ class Writer(writers.Writer): ), ) - settings_default_overrides = {'output_encoding': 'latin-1'} + settings_default_overrides = {'output_encoding': 'latin-1:strict'} output = None """Final translated form of `document`.""" -- cgit v1.2.1 From 67dba3f23a1da81334876b9ee9a429217da8df10 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 7 Jun 2003 13:33:42 +0000 Subject: fallback default encoding error handler git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1388 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index e3730a5a8..dc2169476 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -87,7 +87,9 @@ def validate_encoding_and_error_handler(value, default): encoding, handler = value.split(':') else: encoding = value - handler = default.split(':')[1] + # "strict" is a fallback default encoding error handler if none + # specified by the default value: + handler = (default.split(':') + ['strict'])[1] validate_encoding(encoding, default) try: codecs.lookup_error(handler) -- cgit v1.2.1 From c0da697b15b457a146dc3ea05be145ac1d211cdd Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 7 Jun 2003 13:57:03 +0000 Subject: use possibly updated option defaults from OptionParser, not Option git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1389 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index dc2169476..69d3152fd 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -56,7 +56,7 @@ def set_encoding(option, opt, value, parser): Validate & set the encoding specified. (Option callback.) """ try: - value = validate_encoding(value, option.default) + value = validate_encoding(value, parser.defaults[option.dest]) except LookupError, error: raise (optik.OptionValueError('option "%s": %s' % (opt, error)), None, sys.exc_info[2]) @@ -76,7 +76,8 @@ def set_encoding_and_error_handler(option, opt, value, parser): (Option callback.) """ try: - value = validate_encoding_and_error_handler(value, option.default) + value = validate_encoding_and_error_handler( + value, parser.defaults[option.dest]) except LookupError, error: raise (optik.OptionValueError('option "%s": %s' % (opt, error)), None, sys.exc_info[2]) -- cgit v1.2.1 From 30efea70114c19273c78bbdbb255a05ebb4ee177 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 7 Jun 2003 13:59:29 +0000 Subject: () added git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1390 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 69d3152fd..2597cc5d0 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -59,7 +59,7 @@ def set_encoding(option, opt, value, parser): value = validate_encoding(value, parser.defaults[option.dest]) except LookupError, error: raise (optik.OptionValueError('option "%s": %s' % (opt, error)), - None, sys.exc_info[2]) + None, sys.exc_info()[2]) setattr(parser.values, option.dest, value) def validate_encoding(value, default): @@ -67,7 +67,7 @@ def validate_encoding(value, default): codecs.lookup(value) except LookupError: raise (LookupError('unknown encoding: "%s"' % value), - None, sys.exc_info[2]) + None, sys.exc_info()[2]) return value def set_encoding_and_error_handler(option, opt, value, parser): @@ -80,7 +80,7 @@ def set_encoding_and_error_handler(option, opt, value, parser): value, parser.defaults[option.dest]) except LookupError, error: raise (optik.OptionValueError('option "%s": %s' % (opt, error)), - None, sys.exc_info[2]) + None, sys.exc_info()[2]) setattr(parser.values, option.dest, value) def validate_encoding_and_error_handler(value, default): @@ -99,14 +99,14 @@ def validate_encoding_and_error_handler(value, default): raise (LookupError( 'unknown encoding error handler: "%s" (choices: ' '"strict", "ignore", or "replace")' % handler), - None, sys.exc_info[2]) + None, sys.exc_info()[2]) except LookupError: raise (LookupError( 'unknown encoding error handler: "%s" (choices: ' '"strict", "ignore", "replace", "backslashreplace", ' '"xmlcharrefreplace", and possibly others; see documentation for ' 'the Python ``codecs`` module)' % handler), - None, sys.exc_info[2]) + None, sys.exc_info()[2]) return encoding + ':' + handler def make_paths_absolute(pathdict, keys, base_path=None): -- cgit v1.2.1 From ba5211d666e122eb662215bf4afc1148b614067d Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 8 Jun 2003 20:55:14 +0000 Subject: Added ``SettingsSpec.settings_defaults`` dict. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1398 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index 4020133f9..5de8a7db4 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -87,6 +87,10 @@ class SettingsSpec: from long option names ("--a-setting" becomes ``settings.a_setting``) or explicitly from the "destination" keyword argument.""" + settings_defaults = None + """A dictionary of defaults for internal or inaccessible (by command-line + or config file) settings. Override in subclasses.""" + settings_default_overrides = None """A dictionary of auxiliary defaults, to override defaults for settings defined in other components. Override in subclasses.""" -- cgit v1.2.1 From 9ade7d7ac8e96945d4d7c51cf3bb3b1f48e8f138 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 8 Jun 2003 20:56:38 +0000 Subject: Updated encoding handling and setting validation. Added "--error-encoding-error-handler" and "--output-encoding-error-handler". git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1400 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 101 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 68 insertions(+), 33 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 2597cc5d0..2acfbee93 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -56,13 +56,13 @@ def set_encoding(option, opt, value, parser): Validate & set the encoding specified. (Option callback.) """ try: - value = validate_encoding(value, parser.defaults[option.dest]) + value = validate_encoding(option.dest, value) except LookupError, error: raise (optik.OptionValueError('option "%s": %s' % (opt, error)), None, sys.exc_info()[2]) setattr(parser.values, option.dest, value) -def validate_encoding(value, default): +def validate_encoding(name, value): try: codecs.lookup(value) except LookupError: @@ -70,44 +70,59 @@ def validate_encoding(value, default): None, sys.exc_info()[2]) return value -def set_encoding_and_error_handler(option, opt, value, parser): +def set_encoding_error_handler(option, opt, value, parser): """ - Validate & set the encoding and error handlers specified. - (Option callback.) + Validate & set the encoding error handler specified. (Option callback.) """ try: - value = validate_encoding_and_error_handler( - value, parser.defaults[option.dest]) + value = validate_encoding_error_handler(option.dest, value) except LookupError, error: raise (optik.OptionValueError('option "%s": %s' % (opt, error)), None, sys.exc_info()[2]) setattr(parser.values, option.dest, value) -def validate_encoding_and_error_handler(value, default): - if ':' in value: - encoding, handler = value.split(':') - else: - encoding = value - # "strict" is a fallback default encoding error handler if none - # specified by the default value: - handler = (default.split(':') + ['strict'])[1] - validate_encoding(encoding, default) +def validate_encoding_error_handler(name, value): try: - codecs.lookup_error(handler) - except AttributeError: - if handler not in ('strict', 'ignore', 'replace'): + codecs.lookup_error(value) + except AttributeError: # prior to Python 2.3 + if value not in ('strict', 'ignore', 'replace'): raise (LookupError( 'unknown encoding error handler: "%s" (choices: ' - '"strict", "ignore", or "replace")' % handler), + '"strict", "ignore", or "replace")' % value), None, sys.exc_info()[2]) except LookupError: raise (LookupError( 'unknown encoding error handler: "%s" (choices: ' '"strict", "ignore", "replace", "backslashreplace", ' '"xmlcharrefreplace", and possibly others; see documentation for ' - 'the Python ``codecs`` module)' % handler), + 'the Python ``codecs`` module)' % value), + None, sys.exc_info()[2]) + return value + +def set_encoding_and_error_handler(option, opt, value, parser): + """ + Validate & set the encoding and error handler specified. (Option callback.) + """ + try: + value = validate_encoding_and_error_handler(option.dest, value) + except LookupError, error: + raise (optik.OptionValueError('option "%s": %s' % (opt, error)), None, sys.exc_info()[2]) - return encoding + ':' + handler + if ':' in value: + encoding, handler = value.split(':') + setattr(parser.values, option.dest + '_error_handler', handler) + else: + encoding = value + setattr(parser.values, option.dest, encoding) + +def validate_encoding_and_error_handler(name, value): + if ':' in value: + encoding, handler = value.split(':') + validate_encoding_error_handler(name + '_error_handler', handler) + else: + encoding = value + validate_encoding(name, encoding) + return value def make_paths_absolute(pathdict, keys, base_path=None): """ @@ -229,7 +244,12 @@ class OptionParser(optik.OptionParser, docutils.SettingsSpec): ['--output-encoding', '-o'], {'action': 'callback', 'callback': set_encoding_and_error_handler, 'metavar': '', 'type': 'string', - 'dest': 'output_encoding', 'default': 'utf-8:strict'}), + 'dest': 'output_encoding', 'default': 'utf-8'}), + (optik.SUPPRESS_HELP, # usually handled by --output-encoding + ['--output_encoding_error_handler'], + {'action': 'callback', 'callback': set_encoding_error_handler, + 'type': 'string', 'dest': 'output_encoding_error_handler', + 'default': 'strict'}), ('Specify the text encoding for error output. Default is ASCII. ' 'Optionally also specify the encoding error handler for unencodable ' 'characters, after a colon (":"). Acceptable values are the same ' @@ -238,8 +258,12 @@ class OptionParser(optik.OptionParser, docutils.SettingsSpec): ['--error-encoding', '-e'], {'action': 'callback', 'callback': set_encoding_and_error_handler, 'metavar': '', 'type': 'string', - 'dest': 'error_encoding', - 'default': 'ascii:%s' % default_error_encoding_error_handler}), + 'dest': 'error_encoding', 'default': 'ascii'}), + (optik.SUPPRESS_HELP, # usually handled by --error-encoding + ['--error_encoding_error_handler'], + {'action': 'callback', 'callback': set_encoding_error_handler, + 'type': 'string', 'dest': 'error_encoding_error_handler', + 'default': default_error_encoding_error_handler}), ('Specify the language of input text (ISO 639 2-letter identifier).' ' Default is "en" (English).', ['--language', '-l'], {'dest': 'language_code', 'default': 'en', @@ -271,7 +295,8 @@ class OptionParser(optik.OptionParser, docutils.SettingsSpec): ends. Setting specs specific to individual Docutils components are also used (see `populate_from_components()`).""" - settings_default_overrides = {'_disable_config': None} + settings_defaults = {'_disable_config': None} + """Defaults for settings that don't have command-line option equivalents.""" relative_path_settings = ('warning_stream',) @@ -309,6 +334,12 @@ class OptionParser(optik.OptionParser, docutils.SettingsSpec): self.set_defaults(_source=None, _destination=None, **defaults) def populate_from_components(self, components): + """ + For each component, first populate from the `SettingsSpec.settings_spec` + structure, then from the `SettingsSpec.settings_defaults` dictionary. + After all components have been processed, check for and populate from + each component's `SettingsSpec.settings_default_overrides` dictionary. + """ for component in components: if component is None: continue @@ -326,6 +357,8 @@ class OptionParser(optik.OptionParser, docutils.SettingsSpec): for (help_text, option_strings, kwargs) in option_spec: group.add_option(help=help_text, *option_strings, **kwargs) + if component.settings_defaults: + self.defaults.update(component.settings_defaults) i += 3 for component in components: if component and component.settings_default_overrides: @@ -374,12 +407,15 @@ class ConfigParser(CP.ConfigParser): 'options'). Later files override earlier ones.""" validation = { - 'options': {'input_encoding': validate_encoding, - 'output_encoding': validate_encoding_and_error_handler, - 'error_encoding': validate_encoding_and_error_handler}} + 'options': + {'input_encoding': validate_encoding, + 'output_encoding': validate_encoding, + 'output_encoding_error_handler': validate_encoding_error_handler, + 'error_encoding': validate_encoding, + 'error_encoding_error_handler': validate_encoding_error_handler}} """{section: {option: validation function}} mapping, used by - `validate_options`. Validation functions take two parameters: value and - default. They return a modified value, or raise an exception.""" + `validate_options`. Validation functions take two parameters: name and + value. They return a (possibly modified) value, or raise an exception.""" def read_standard_files(self, option_parser): self.read(self.standard_config_files, option_parser) @@ -399,9 +435,8 @@ class ConfigParser(CP.ConfigParser): if self.has_option(section, option): value = self.get(section, option) validator = self.validation[section][option] - default = option_parser.defaults[option] try: - new_value = validator(value, default) + new_value = validator(option, value) except Exception, error: raise (ValueError( 'Error in config file "%s", section "[%s]":\n' -- cgit v1.2.1 From bb2f2713e8cdf461d76b7354dc14525ae733545a Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 8 Jun 2003 20:58:58 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1401 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 3 ++- docutils/io.py | 8 +++----- docutils/utils.py | 11 +++++------ docutils/writers/latex2e.py | 2 +- 4 files changed, 11 insertions(+), 13 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index 381c65711..727d4e76a 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -142,7 +142,8 @@ class Publisher: self.settings._destination = destination_path self.destination = self.destination_class( destination=destination, destination_path=destination_path, - encoding=self.settings.output_encoding) + encoding=self.settings.output_encoding, + error_handler=self.settings.output_encoding_error_handler) def apply_transforms(self, document): document.transformer.populate_from_components( diff --git a/docutils/io.py b/docutils/io.py index 52d500dc7..5eac67f04 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -108,13 +108,11 @@ class Output(TransformSpec): default_destination_path = None def __init__(self, settings=None, destination=None, destination_path=None, - encoding=None): - encoding, error_handler = (encoding.split(':') + ['strict'])[:2] - + encoding=None, error_handler='strict'): self.encoding = encoding """Text encoding for the output destination.""" - self.error_handler = error_handler + self.error_handler = error_handler or 'strict' """Text encoding error handler.""" if settings: @@ -198,7 +196,7 @@ class FileOutput(Output): """ def __init__(self, settings=None, destination=None, destination_path=None, - encoding=None, autoclose=1): + encoding=None, error_handler='strict', autoclose=1): """ :Parameters: - `destination`: either a file-like object (which is written diff --git a/docutils/utils.py b/docutils/utils.py index 152d5067c..f8ca2c0af 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -75,7 +75,7 @@ class Reporter: """List of names for system message levels, indexed by level.""" def __init__(self, source, report_level, halt_level, stream=None, - debug=0, encoding='ascii:replace'): + debug=0, encoding='ascii', error_handler='replace'): """ Initialize the `ConditionSet` forthe `Reporter`'s default category. @@ -90,8 +90,8 @@ class Reporter: - `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). - - `encoding`: The encoding and error handler (colon-separated) - for stderr output. + - `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.""" @@ -101,8 +101,6 @@ class Reporter: elif type(stream) in (StringType, UnicodeType): raise NotImplementedError('This should open a file for writing.') - encoding, error_handler = (encoding.split(':') + ['replace'])[:2] - self.encoding = encoding """The character encoding for the stderr output.""" @@ -393,7 +391,8 @@ def new_document(source, settings=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) + encoding=settings.error_encoding, + error_handler=settings.error_encoding_error_handler) document = nodes.document(settings, reporter, source=source) document.note_source(source, -1) return document diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 5592145e3..0f7dea967 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -75,7 +75,7 @@ class Writer(writers.Writer): ), ) - settings_default_overrides = {'output_encoding': 'latin-1:strict'} + settings_defaults = {'output_encoding': 'latin-1'} output = None """Final translated form of `document`.""" -- cgit v1.2.1 From 1fc858bc8b0d46f289961e0c03ccabbede70d6fc Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 9 Jun 2003 15:06:07 +0000 Subject: Added "--trim-footnote-reference-space" option. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1403 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/__init__.py b/docutils/parsers/rst/__init__.py index b242ad9cb..899a49bc8 100644 --- a/docutils/parsers/rst/__init__.py +++ b/docutils/parsers/rst/__init__.py @@ -95,7 +95,10 @@ class Parser(docutils.parsers.Parser): {'action': 'store_true'}), ('Set number of spaces for tab expansion (default 8).', ['--tab-width'], - {'metavar': '', 'type': 'int', 'default': 8}),)) + {'metavar': '', 'type': 'int', 'default': 8}), + ('Remove spaces before footnote references.', + ['--trim-footnote-reference-space'], + {'action': 'store_true'}),)) def __init__(self, rfc2822=None, inliner=None): if rfc2822: -- cgit v1.2.1 From 0cf867bc975f087ce49b13340e925ff9311b4f8a Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 9 Jun 2003 15:06:34 +0000 Subject: Support for "--trim-footnote-reference-space" option. Optional space before colons in directives & hyperlink targets. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1404 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 4a4da3478..296bc57b4 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -980,6 +980,9 @@ class Inliner: """ label = match.group('footnotelabel') refname = normalize_name(label) + string = match.string + before = string[:match.start('whole')] + remaining = string[match.end('whole'):] if match.group('citationlabel'): refnode = nodes.citation_reference('[%s]_' % label, refname=refname) @@ -1001,10 +1004,9 @@ class Inliner: if refname: refnode['refname'] = refname self.document.note_footnote_ref(refnode) - string = match.string - matchstart = match.start('whole') - matchend = match.end('whole') - return (string[:matchstart], [refnode], string[matchend:], []) + if self.document.settings.trim_footnote_reference_space: + before = before.rstrip() + return (before, [refnode], remaining, []) def reference(self, match, lineno, anonymous=None): referencename = match.group('refname') @@ -1768,6 +1770,7 @@ class Body(RSTState): (?P=quote) # close quote if open quote used ) %(non_whitespace_escape_before)s + [ ]? # optional space : # end of reference name ([ ]+|$) # followed by whitespace """ % vars(Inliner), re.VERBOSE), @@ -2188,6 +2191,7 @@ class Body(RSTState): re.compile(r""" \.\.[ ]+ # explicit markup start (%s) # directive name + [ ]? # optional space :: # directive delimiter ([ ]+|$) # whitespace or end of line """ % Inliner.simplename, re.VERBOSE | re.UNICODE))] -- cgit v1.2.1 From 8dc63ea835280db6981eb79c10fec87436e54793 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 9 Jun 2003 15:06:54 +0000 Subject: Removed "--snap-footnote-refs" & support. Now handled in the parser by "--trim-footnote-reference-space". git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1405 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 0f7dea967..b2e860cac 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -68,12 +68,7 @@ class Writer(writers.Writer): ['--use-latex-toc'], {'default': 0}), ('Color of any hyperlinks embedded in text ' '(default: "blue", "0" to disable).', - ['--hyperlink-color'], {'default': 'blue'}), - ('Remove trailing blanks and line ends from the element before a' - 'footnote_reference (default: off, "1" to enable).', - ['--snap-footnote-refs'], {'default': 0}), - ), - ) + ['--hyperlink-color'], {'default': 'blue'}),)) settings_defaults = {'output_encoding': 'latin-1'} @@ -863,8 +858,6 @@ class LaTeXTranslator(nodes.NodeVisitor): self.context.append('}') else: # shouldn't happen raise AssertionError('Illegal footnote reference format.') - if self.settings.snap_footnote_refs and len(self.body)>0: - self.body.append(self.body.pop().rstrip()) self.body.append('%s\\hyperlink{%s}{' % (suffix,href)) def depart_footnote_reference(self, node): -- cgit v1.2.1 From 2671bd34f6c937267c01599005cc06bcb6168606 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 9 Jun 2003 15:07:47 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1406 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index fd52f00fc..c754ee05c 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -755,6 +755,8 @@ class TargetNotes(Transform): self.document.note_autofootnote_ref(refnode) self.document.note_footnote_ref(refnode) index = ref.parent.index(ref) + 1 - reflist = [nodes.Text(' '), refnode] + reflist = [refnode] + if not self.document.settings.trim_footnote_reference_space: + reflist.insert(0, nodes.Text(' ')) ref.parent.insert(index, reflist) return footnote -- cgit v1.2.1 From 8bb4bd55baaaeb14c3acf0a32adad690b603eaa3 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 11 Jun 2003 15:57:02 +0000 Subject: enabled "decoration" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1418 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index b2e860cac..3a33f9352 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -577,11 +577,11 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_date(self, node): self.depart_docinfo_item(node) -# def visit_decoration(self, node): -# pass + def visit_decoration(self, node): + pass -# def depart_decoration(self, node): -# pass + def depart_decoration(self, node): + pass def visit_definition(self, node): self.body.append('%[visit_definition]\n') -- cgit v1.2.1 From a1c52851ebebe162cd925f39b6221d1b09724a19 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 12 Jun 2003 19:35:34 +0000 Subject: "unicode": added support for "U+" notation, and catching wide-Unicode errors git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1433 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index d1c993478..c220c84cb 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -170,19 +170,26 @@ def unicode_directive(name, arguments, options, content, lineno, codes = arguments[0].split() element = nodes.Element() for code in codes: - if code.isdigit(): - element += nodes.Text(int(code)) - else: - match = unicode_pattern.match(code) - if match: - element += nodes.Text(unichr(int(match.group(2), 16))) + try: + if code.isdigit(): + element += nodes.Text(unichr(int(code))) else: - element += nodes.Text(code) + match = unicode_pattern.match(code) + if match: + value = match.group(1) or match.group(2) + element += nodes.Text(unichr(int(value, 16))) + else: + element += nodes.Text(code) + except ValueError, err: + error = state_machine.reporter.error( + 'Invalid character code: %s\n%s' % (code, err), + nodes.literal_block(block_text, block_text), line=lineno) + return [error] return element.children unicode_directive.arguments = (1, 0, 1) -unicode_pattern = re.compile(r'(0x|x|\x00x|u|\x00u|&#x)([0-9a-f]+);?$', - re.IGNORECASE) +unicode_pattern = re.compile( + r'(?:0x|x|\x00x|U\+?|\x00u)([0-9a-f]+)$|&#x([0-9a-f]+);$', re.IGNORECASE) def class_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): -- cgit v1.2.1 From 8d87788ce3afbd0e4274d14c85b897eb913739b6 Mon Sep 17 00:00:00 2001 From: grubert Date: Fri, 13 Jun 2003 16:55:42 +0000 Subject: Add rubric support. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1445 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 3a33f9352..ff4f63876 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -216,7 +216,12 @@ latex_headings = { '\\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]' + '{{\\hfill \\color{red}\\bfseries{}#1 \\hfill }}\n', + ] } @@ -303,6 +308,7 @@ class LaTeXTranslator(nodes.NodeVisitor): ] self.head_prefix.extend( latex_headings['optionlist_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 = self.get_stylesheet_reference() if stylesheet: @@ -1363,6 +1369,15 @@ class LaTeXTranslator(nodes.NodeVisitor): self.topic_class = '' self.body.append('\n') + def visit_rubric(self, node): +# self.body.append('\\hfill {\\color{red}\\bfseries{}') +# self.context.append('} \\hfill ~\n') + 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) -- cgit v1.2.1 From dfe2aa11eee34d0e4c433d5b80647ca58d850345 Mon Sep 17 00:00:00 2001 From: grubert Date: Fri, 13 Jun 2003 17:01:58 +0000 Subject: possible translations. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1446 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/de.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index b91b16736..9c6337b2d 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -24,14 +24,14 @@ directives = { 'tip': 'tip', 'warnung': 'warning', 'admonition (translation required)': 'admonition', - 'sidebar (translation required)': 'sidebar', - 'topic': 'topic', # berbegriff + 'sidebar (translation required)': 'sidebar', # kasten ? + 'topic': 'topic', # berbegriff, Thema ? 'line-block': 'line-block', 'parsed-literal': 'parsed-literal', - 'rubric (translation required)': 'rubric', + 'rubrik': 'rubric', 'epigraph (translation required)': 'epigraph', 'highlights (translation required)': 'highlights', - 'pull-quote (translation required)': 'pull-quote', + 'pull-quote (translation required)': 'pull-quote', # kasten too ? #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', -- cgit v1.2.1 From db1508b2d9f02abad41a84cea8b1172c435bbf84 Mon Sep 17 00:00:00 2001 From: grubert Date: Fri, 13 Jun 2003 17:40:06 +0000 Subject: Adapt test to rubric support. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1447 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index ff4f63876..319d1a486 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -220,7 +220,8 @@ latex_headings = { 'some_commands' : [ '% some commands, that could be overwritten in the style file.\n' '\\newcommand{\\rubric}[1]' - '{{\\hfill \\color{red}\\bfseries{}#1 \\hfill }}\n', + '{{\\hfill \\color{red}\\bfseries{}#1 \\hfill }}\n' + '% end of "some commands"\n', ] } -- cgit v1.2.1 From d8757edc730c6dd045521917b437a5b2fce66593 Mon Sep 17 00:00:00 2001 From: grubert Date: Sat, 14 Jun 2003 07:00:26 +0000 Subject: change rubric style to subsection italic. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1449 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 319d1a486..8fe755ac6 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -220,7 +220,7 @@ latex_headings = { 'some_commands' : [ '% some commands, that could be overwritten in the style file.\n' '\\newcommand{\\rubric}[1]' - '{{\\hfill \\color{red}\\bfseries{}#1 \\hfill }}\n' + '{\\subsection*{~\\hfill {\\it #1} \\hfill ~}}\n' '% end of "some commands"\n', ] } -- cgit v1.2.1 From 7f17738b76e7f641bf9f65d766f219ad8644f4ca Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 16 Jun 2003 03:13:56 +0000 Subject: Removed dependency on runtime settings; pass encoding directly. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1464 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 34 ++++++---------------------------- 1 file changed, 6 insertions(+), 28 deletions(-) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index 5eac67f04..4b14cef72 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -27,21 +27,10 @@ class Input(TransformSpec): default_source_path = None - def __init__(self, settings=None, source=None, source_path=None, - encoding=None): + def __init__(self, source=None, source_path=None, encoding=None): self.encoding = encoding """Text encoding for the input source.""" - if settings: - if not encoding: - self.encoding = settings.input_encoding - import warnings, traceback - warnings.warn( - 'Setting input encoding via a "settings" struct is ' - 'deprecated; send encoding directly instead.\n%s' - % ''.join(traceback.format_list(traceback.extract_stack() - [-3:-1]))) - self.source = source """The source of input data.""" @@ -107,7 +96,7 @@ class Output(TransformSpec): default_destination_path = None - def __init__(self, settings=None, destination=None, destination_path=None, + def __init__(self, destination=None, destination_path=None, encoding=None, error_handler='strict'): self.encoding = encoding """Text encoding for the output destination.""" @@ -115,16 +104,6 @@ class Output(TransformSpec): self.error_handler = error_handler or 'strict' """Text encoding error handler.""" - if settings: - if not encoding: - self.encoding = settings.output_encoding - import warnings, traceback - warnings.warn( - 'Setting output encoding via a "settings" struct is ' - 'deprecated; send encoding directly instead.\n%s' - % ''.join(traceback.format_list(traceback.extract_stack() - [-3:-1]))) - self.destination = destination """The destination for output data.""" @@ -154,7 +133,7 @@ class FileInput(Input): Input for single, simple file-like objects. """ - def __init__(self, settings=None, source=None, source_path=None, + def __init__(self, source=None, source_path=None, encoding=None, autoclose=1): """ :Parameters: @@ -164,7 +143,7 @@ class FileInput(Input): - `autoclose`: close automatically after read (boolean); always false if `sys.stdin` is the source. """ - Input.__init__(self, settings, source, source_path, encoding) + Input.__init__(self, source, source_path, encoding) self.autoclose = autoclose if source is None: if source_path: @@ -195,7 +174,7 @@ class FileOutput(Output): Output for single, simple file-like objects. """ - def __init__(self, settings=None, destination=None, destination_path=None, + def __init__(self, destination=None, destination_path=None, encoding=None, error_handler='strict', autoclose=1): """ :Parameters: @@ -207,8 +186,7 @@ class FileOutput(Output): - `autoclose`: close automatically after write (boolean); always false if `sys.stdout` is the destination. """ - Output.__init__(self, settings, destination, destination_path, - encoding) + Output.__init__(self, destination, destination_path, encoding) self.opened = 1 self.autoclose = autoclose if destination is None: -- cgit v1.2.1 From d940bafce847d3361f82cd279dfef0d7d8539627 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 16 Jun 2003 03:17:45 +0000 Subject: moved to "extras" directory git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1466 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/optik.py | 1354 ----------------------------------------------------- docutils/roman.py | 81 ---- 2 files changed, 1435 deletions(-) delete mode 100644 docutils/optik.py delete mode 100644 docutils/roman.py (limited to 'docutils') diff --git a/docutils/optik.py b/docutils/optik.py deleted file mode 100644 index a8652860c..000000000 --- a/docutils/optik.py +++ /dev/null @@ -1,1354 +0,0 @@ -# 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 - -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 -from types import TupleType, ListType, DictType, StringType -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)) - -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: - """ - Instance attributes: - _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 } - 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', - 'choices', - '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", "choice") - - # 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, - "choice" : check_choice, - } - - - # 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"): - 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) - if self.action not in self.TYPED_ACTIONS: - 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. - # 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_choice, - _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 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_option_help(self): - if not self.option_list: - return "" - 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_help(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_help() + "\n" - return result + self.get_option_help() - - -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 __repr__(self): - return "%s(%r)" % (self.__class__, self.__dict__) - - 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). - # - # 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: - # - # 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_help(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_help() - - def get_version_help(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_help() - - 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_option_help(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_help() + "\n") - if self.description: - result.append(self.get_description_help() + "\n") - result.append(self.get_option_help()) - 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 design pattern). - - Instance attributes: - indent_increment : int - 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. - 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, calculated. - """ - - def __init__(self, indent_increment, max_help_position, width, - short_first): - self.indent_increment = indent_increment - self.help_position = self.max_help_position = max_help_position - self.width = width - self.current_indent = 0 - self.level = 0 - self.help_width = width - max_help_position - if short_first: - self.format_option_strings = self.format_option_strings_short_first - else: - self.format_option_strings = self.format_option_strings_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): - # 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 = 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_position - 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_position, "", line) - for line in help_lines[1:]]) - elif opts[-1] != "\n": - result.append("\n") - return "".join(result) - - 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_strings_short_first or " - "format_option_strings_long_first instead.") - - def format_option_strings_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_strings_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): - - """Formats help with indented section bodies.""" - - def __init__(self, indent_increment=2, max_help_position=24, width=78, - short_first=1): - HelpFormat.__init__(self, indent_increment, max_help_position, 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): - - """Formats help with underlined section headers.""" - - def __init__(self, indent_increment=0, max_help_position=24, width=78, - short_first=None): - HelpFormat.__init__(self, indent_increment, max_help_position, 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 - - 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', raise 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]) diff --git a/docutils/roman.py b/docutils/roman.py deleted file mode 100644 index 5972c3cef..000000000 --- a/docutils/roman.py +++ /dev/null @@ -1,81 +0,0 @@ -"""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 - -- cgit v1.2.1 From 4d5856ed0b53ed121be993e520271fc0e4a1ce55 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 16 Jun 2003 03:26:53 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1470 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 10 ++------- docutils/frontend.py | 50 ++++++++++++++++++------------------------ docutils/parsers/rst/states.py | 3 ++- docutils/writers/pep_html.py | 4 ++-- 4 files changed, 27 insertions(+), 40 deletions(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index 5de8a7db4..a631b7f0b 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -23,12 +23,6 @@ Modules: - 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/). - - statemachine.py: A finite state machine specialized for regular-expression-based text filters. @@ -55,7 +49,7 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.2.9' +__version__ = '0.2.10' """``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 @@ -85,7 +79,7 @@ class SettingsSpec: 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.""" + explicitly from the "dest" keyword argument.""" settings_defaults = None """A dictionary of defaults for internal or inaccessible (by command-line diff --git a/docutils/frontend.py b/docutils/frontend.py index 2acfbee93..acf44e3b2 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -24,8 +24,8 @@ import types import ConfigParser as CP import codecs import docutils -from docutils import optik -from docutils.optik import Values +import optparse +from optparse import Values, SUPPRESS_HELP def store_multiple(option, opt, value, parser, *args, **kwargs): @@ -58,7 +58,7 @@ def set_encoding(option, opt, value, parser): try: value = validate_encoding(option.dest, value) except LookupError, error: - raise (optik.OptionValueError('option "%s": %s' % (opt, error)), + raise (optparse.OptionValueError('option "%s": %s' % (opt, error)), None, sys.exc_info()[2]) setattr(parser.values, option.dest, value) @@ -77,7 +77,7 @@ def set_encoding_error_handler(option, opt, value, parser): try: value = validate_encoding_error_handler(option.dest, value) except LookupError, error: - raise (optik.OptionValueError('option "%s": %s' % (opt, error)), + raise (optparse.OptionValueError('option "%s": %s' % (opt, error)), None, sys.exc_info()[2]) setattr(parser.values, option.dest, value) @@ -106,7 +106,7 @@ def set_encoding_and_error_handler(option, opt, value, parser): try: value = validate_encoding_and_error_handler(option.dest, value) except LookupError, error: - raise (optik.OptionValueError('option "%s": %s' % (opt, error)), + raise (optparse.OptionValueError('option "%s": %s' % (opt, error)), None, sys.exc_info()[2]) if ':' in value: encoding, handler = value.split(':') @@ -139,7 +139,7 @@ def make_paths_absolute(pathdict, keys, base_path=None): os.path.abspath(os.path.join(base_path, pathdict[key]))) -class OptionParser(optik.OptionParser, docutils.SettingsSpec): +class OptionParser(optparse.OptionParser, docutils.SettingsSpec): """ Parser for command-line and library use. The `settings_spec` @@ -245,7 +245,7 @@ class OptionParser(optik.OptionParser, docutils.SettingsSpec): {'action': 'callback', 'callback': set_encoding_and_error_handler, 'metavar': '', 'type': 'string', 'dest': 'output_encoding', 'default': 'utf-8'}), - (optik.SUPPRESS_HELP, # usually handled by --output-encoding + (SUPPRESS_HELP, # usually handled by --output-encoding ['--output_encoding_error_handler'], {'action': 'callback', 'callback': set_encoding_error_handler, 'type': 'string', 'dest': 'output_encoding_error_handler', @@ -259,7 +259,7 @@ class OptionParser(optik.OptionParser, docutils.SettingsSpec): {'action': 'callback', 'callback': set_encoding_and_error_handler, 'metavar': '', 'type': 'string', 'dest': 'error_encoding', 'default': 'ascii'}), - (optik.SUPPRESS_HELP, # usually handled by --error-encoding + (SUPPRESS_HELP, # usually handled by --error-encoding ['--error_encoding_error_handler'], {'action': 'callback', 'callback': set_encoding_error_handler, 'type': 'string', 'dest': 'error_encoding_error_handler', @@ -276,20 +276,11 @@ 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'], + (SUPPRESS_HELP, ['--dump-settings'], {'action': 'store_true'}), + (SUPPRESS_HELP, ['--dump-internals'], {'action': 'store_true'}), + (SUPPRESS_HELP, ['--dump-transforms'], {'action': 'store_true'}), + (SUPPRESS_HELP, ['--dump-pseudo-xml'], {'action': 'store_true'}), + (SUPPRESS_HELP, ['--expose-internal-attribute'], {'action': 'append', 'dest': 'expose_internals'}),)) """Runtime settings and command-line options common to all Docutils front ends. Setting specs specific to individual Docutils components are also @@ -310,12 +301,9 @@ class OptionParser(optik.OptionParser, docutils.SettingsSpec): ``.settings_spec`` attribute. `defaults` is a mapping of setting default overrides. """ - optik.OptionParser.__init__( - self, help=None, - format=optik.Titled(), - # Needed when Optik is updated (replaces above 2 lines): - #self, add_help=None, - #formatter=optik.TitledHelpFormatter(width=78), + optparse.OptionParser.__init__( + self, add_help_option=None, + formatter=optparse.TitledHelpFormatter(width=78), *args, **kwargs) if not self.version: self.version = self.version_template @@ -350,7 +338,7 @@ class OptionParser(optik.OptionParser, docutils.SettingsSpec): while i < len(settings_spec): title, description, option_spec = settings_spec[i:i+3] if title: - group = optik.OptionGroup(self, title, description) + group = optparse.OptionGroup(self, title, description) self.add_option_group(group) else: group = self # single options @@ -387,8 +375,12 @@ class OptionParser(optik.OptionParser, docutils.SettingsSpec): source = destination = None if args: source = args.pop(0) + if source == '-': # means stdin + source = None if args: destination = args.pop(0) + if destination == '-': # means stdout + destination = None if args: self.error('Maximum 2 arguments allowed.') if source and source == destination: diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 296bc57b4..2fc1f8866 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -107,8 +107,9 @@ __docformat__ = 'reStructuredText' import sys import re +import roman from types import TupleType -from docutils import nodes, statemachine, utils, roman, urischemes +from docutils import nodes, statemachine, utils, urischemes from docutils import ApplicationError, DataError from docutils.statemachine import StateMachineWS, StateWS from docutils.nodes import fully_normalize_name as normalize_name diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index c535f8c79..85c065c3d 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -13,7 +13,7 @@ __docformat__ = 'reStructuredText' import sys import docutils -from docutils import nodes, optik, utils +from docutils import nodes, frontend, utils from docutils.writers import html4css1 @@ -44,7 +44,7 @@ class Writer(html4css1.Writer): {'default': '.', 'metavar': ''}), # Workaround for SourceForge's broken Python # (``import random`` causes a segfault). - (optik.SUPPRESS_HELP, + (frontend.SUPPRESS_HELP, ['--no-random'], {'action': 'store_true'}),)) settings_default_overrides = {'footnote_references': 'brackets'} -- cgit v1.2.1 From 42355293ce630e6f8f8ab112286417dbfe796beb Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 16 Jun 2003 17:30:20 +0000 Subject: Added support for exit status ("exit_level" setting & ``enable_exit`` parameter for Publisher.publish() and convenience functions). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1477 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index 727d4e76a..5fe7e93cd 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -152,7 +152,8 @@ class Publisher: document.transformer.apply_transforms() def publish(self, argv=None, usage=None, description=None, - settings_spec=None, settings_overrides=None): + settings_spec=None, settings_overrides=None, + enable_exit=None): """ Process command line options and arguments (if `self.settings` not already set), run `self.reader` and then `self.writer`. Return @@ -183,6 +184,9 @@ class Publisher: print >>sys.stderr, '\n::: Pseudo-XML:' print >>sys.stderr, document.pformat().encode( 'raw_unicode_escape') + if enable_exit and (document.reporter.max_level + >= self.settings.exit_level): + sys.exit(document.reporter.max_level + 10) return output @@ -194,7 +198,7 @@ def publish_cmdline(reader=None, reader_name='standalone', parser=None, parser_name='restructuredtext', writer=None, writer_name='pseudoxml', settings=None, settings_spec=None, - settings_overrides=None, argv=None, + settings_overrides=None, enable_exit=1, argv=None, usage=default_usage, description=default_description): """ Set up & run a `Publisher`. For command-line front ends. @@ -215,6 +219,7 @@ def publish_cmdline(reader=None, reader_name='standalone', subclass. Used only if no `settings` specified. - `settings_overrides`: A dictionary containing program-specific overrides of component settings. + - `enable_exit`: Boolean; enable exit status at end of processing? - `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. @@ -223,14 +228,16 @@ def publish_cmdline(reader=None, reader_name='standalone', """ pub = Publisher(reader, parser, writer, settings=settings) pub.set_components(reader_name, parser_name, writer_name) - pub.publish(argv, usage, description, settings_spec, settings_overrides) + pub.publish(argv, usage, description, settings_spec, settings_overrides, + enable_exit=enable_exit) 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): + settings=None, settings_spec=None, settings_overrides=None, + enable_exit=None): """ Set up & run a `Publisher`. For programmatic use with file-like I/O. @@ -258,6 +265,7 @@ def publish_file(source=None, source_path=None, subclass. Used only if no `settings` specified. - `settings_overrides`: A dictionary containing program-specific overrides of component settings. + - `enable_exit`: Boolean; enable exit status at end of processing? """ pub = Publisher(reader, parser, writer, settings=settings) pub.set_components(reader_name, parser_name, writer_name) @@ -267,14 +275,14 @@ def publish_file(source=None, source_path=None, settings._update(settings_overrides, 'loose') pub.set_source(source, source_path) pub.set_destination(destination, destination_path) - pub.publish() + pub.publish(enable_exit=enable_exit) 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): + settings_overrides=None, enable_exit=None): """ Set up & run a `Publisher`, and return the string output. For programmatic use with string I/O. @@ -313,6 +321,7 @@ def publish_string(source, source_path=None, destination_path=None, subclass. Used only if no `settings` specified. - `settings_overrides`: A dictionary containing program-specific overrides of component settings. + - `enable_exit`: Boolean; enable exit status at end of processing? """ pub = Publisher(reader, parser, writer, settings=settings, source_class=io.StringInput, @@ -324,4 +333,4 @@ def publish_string(source, source_path=None, destination_path=None, settings._update(settings_overrides, 'loose') pub.set_source(source, source_path) pub.set_destination(destination_path=destination_path) - return pub.publish() + return pub.publish(enable_exit=enable_exit) -- cgit v1.2.1 From 94ffb6485491c20aed76aa9d4fe366cdf12aa17c Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 16 Jun 2003 17:31:18 +0000 Subject: Reporter keeps track of the highest level system message yet generated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1478 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'docutils') diff --git a/docutils/utils.py b/docutils/utils.py index f8ca2c0af..e50a3de07 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -115,6 +115,9 @@ class Reporter: """List of bound methods or functions to call with each system_message created.""" + 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: @@ -181,6 +184,7 @@ class Reporter: raise SystemMessage(msg) if level > 0 or debug: self.notify_observers(msg) + self.max_level = max(level, self.max_level) return msg def debug(self, *args, **kwargs): -- cgit v1.2.1 From a546d701795706cda0f378fb29f18fa5a45c1c9f Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 16 Jun 2003 17:31:37 +0000 Subject: Added "exit_level" setting ("--exit" option). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1479 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index acf44e3b2..d1393e003 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -228,6 +228,12 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): ('Same as "--halt=info": halt processing at the slightest problem.', ['--strict'], {'action': 'store_const', 'const': 'info', 'dest': 'halt_level'}), + ('Enable a non-zero exit status for normal exit if non-halting ' + 'system messages (at or above ) were generated. Levels as ' + 'in --report. Default is 5 (disabled). Exit status is the maximum ' + 'system message level plus 10 (11 for INFO, etc.).', + ['--exit'], {'choices': threshold_choices, 'dest': 'exit_level', + 'default': 5, 'metavar': ''}), ('Report debug-level system messages.', ['--debug'], {'action': 'store_true'}), ('Do not report debug-level system messages.', @@ -357,6 +363,8 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): values.report_level = self.check_threshold(values.report_level) if hasattr(values, 'halt_level'): values.halt_level = self.check_threshold(values.halt_level) + if hasattr(values, 'exit_level'): + values.exit_level = self.check_threshold(values.exit_level) values._source, values._destination = self.check_args(args) make_paths_absolute(values.__dict__, self.relative_path_settings, os.getcwd()) -- cgit v1.2.1 From 08bc4f8cf6dc274c7532d9cf7870bc98f5109c10 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 16 Jun 2003 21:29:24 +0000 Subject: fixed path bug with embedded stylesheets git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1483 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 788e2021e..f7cbe2e34 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -18,6 +18,7 @@ __docformat__ = 'reStructuredText' import sys import os +import os.path import time import re from types import ListType @@ -174,7 +175,8 @@ class HTMLTranslator(nodes.NodeVisitor): % settings.output_encoding) self.head = [] if settings.embed_stylesheet: - stylesheet = self.get_stylesheet_reference(os.getcwd()) + stylesheet = self.get_stylesheet_reference( + os.path.join(os.getcwd(), 'dummy')) stylesheet_text = open(stylesheet).read() self.stylesheet = [self.embedded_stylesheet % stylesheet_text] else: -- cgit v1.2.1 From 6d04c86a41e129af514fb6b670353e0229788259 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 16 Jun 2003 21:29:34 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1484 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/utils.py b/docutils/utils.py index e50a3de07..aa97e71c1 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -412,7 +412,7 @@ def clean_rcs_keywords(paragraph, keyword_substitutions): def relative_path(source, target): """ - Build and return a path to `target`, relative to `source`. + Build and return a path to `target`, relative to `source` (both files). If there is no common prefix, return the absolute path to `target`. """ -- cgit v1.2.1 From 79266acb6c5e3c2e4e152c811bcbb5601845cb42 Mon Sep 17 00:00:00 2001 From: grubert Date: Tue, 17 Jun 2003 06:15:50 +0000 Subject: add translations. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1485 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/de.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index 9c6337b2d..7f2a25e78 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -23,9 +23,9 @@ directives = { 'notiz': 'note', 'tip': 'tip', 'warnung': 'warning', - 'admonition (translation required)': 'admonition', - 'sidebar (translation required)': 'sidebar', # kasten ? - 'topic': 'topic', # berbegriff, Thema ? + 'ermahnung': 'admonition', + 'kasten': 'sidebar', # seitenkasten ? + 'thema': 'topic', 'line-block': 'line-block', 'parsed-literal': 'parsed-literal', 'rubrik': 'rubric', @@ -42,9 +42,9 @@ directives = { 'raw': 'raw', # unbearbeitet 'include': 'include', # einfgen, "fge ein" would be more like a command. # einfgung would be the noun. - 'replace': 'replace', # ersetzen, ersetze + 'ersetzung': 'replace', # ersetzen, ersetze 'unicode': 'unicode', - 'class (translation required)': 'class', + 'klasse': 'class', # offer class too ? 'inhalt': 'contents', 'sectnum': 'sectnum', 'section-numbering': 'sectnum', -- cgit v1.2.1 From 862563510270e6ee98f5ff554dd9929836d070ad Mon Sep 17 00:00:00 2001 From: grubert Date: Tue, 17 Jun 2003 06:44:32 +0000 Subject: FIX: sidebar title and subtitle overwrote documents title and subtitle. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1486 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 8fe755ac6..d2eec0a16 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1183,12 +1183,17 @@ class LaTeXTranslator(nodes.NodeVisitor): self.unimplemented_visit(node) def visit_subtitle(self, node): - self.title = self.title + \ + if isinstance(node.parent, nodes.sidebar): + self.body.append('~\\\\\n\\textbf{') + self.context.append('}\n\\smallskip\n') + else: + self.title = self.title + \ '\\\\\n\\large{%s}\n' % self.encode(node.astext()) - raise nodes.SkipNode + raise nodes.SkipNode def depart_subtitle(self, node): - pass + if isinstance(node.parent, nodes.sidebar): + self.body.append(self.context.pop()) def visit_system_message(self, node): if node['level'] < self.document.reporter['writer'].report_level: @@ -1317,6 +1322,9 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('\\subsection*{~\\hfill ') # the closing brace for subsection. self.context.append('\\hfill ~}\n') + elif isinstance(node.parent, nodes.sidebar): + self.body.append('\\textbf{\\large ') + self.context.append('}\n\\smallskip\n') elif self.section_level == 0: # document title self.title = self.encode(node.astext()) @@ -1348,8 +1356,10 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_title(self, node): self.body.append(self.context.pop()) + if isinstance(node.parent, nodes.sidebar): + return # BUG level depends on style. - if node.parent.hasattr('id') and not self.use_latex_toc: + elif node.parent.hasattr('id') and not self.use_latex_toc: # 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 -- cgit v1.2.1 From 0f05078f7a53809a3b63fb5732f19fdf6ca059db Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 17 Jun 2003 13:26:52 +0000 Subject: pass along error_handler parameter git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1488 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index 4b14cef72..9e6e75151 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -186,7 +186,8 @@ class FileOutput(Output): - `autoclose`: close automatically after write (boolean); always false if `sys.stdout` is the destination. """ - Output.__init__(self, destination, destination_path, encoding) + Output.__init__(self, destination, destination_path, + encoding, error_handler) self.opened = 1 self.autoclose = autoclose if destination is None: -- cgit v1.2.1 From 07e99283acdc2bc67dc0b75f596fbe468ab3ccd3 Mon Sep 17 00:00:00 2001 From: grubert Date: Sat, 21 Jun 2003 03:30:51 +0000 Subject: Take care of too wide tables (dave abrahams). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1492 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index d2eec0a16..e283347b9 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1,5 +1,3 @@ -#! /usr/bin/env python - """ :Author: Engelbert Gruber :Contact: grubert@users.sourceforge.net @@ -12,6 +10,9 @@ LaTeX2e document tree Writer. __docformat__ = 'reStructuredText' +# code contributions from several people included, thanks too all. +# some named: David Abrahams, Julien Letessier, who is missing. +# # convention deactivate code by two # e.g. ##. import sys @@ -1210,12 +1211,23 @@ class LaTeXTranslator(nodes.NodeVisitor): Assumes reST line length being 80 characters. """ width = 80 - s = "" + + total_width = 0.0 + # donot make it full linewidth + factor = 0.93 + # first see if we get too wide. + for node in self.colspecs: + colwidth = factor * float(node['colwidth']) / width + total_width += colwidth + if total_width > 1.0: + factor /= total_width + + latex_table_spec = "" for node in self.colspecs: - colwidth = 0.93 * float(node['colwidth']) / width - s += "|p{%.2f\\linewidth}" % colwidth + colwidth = factor * float(node['colwidth']) / width + latex_table_spec += "|p{%.2f\\linewidth}" % colwidth self.colspecs = [] - return s+"|" + return latex_table_spec+"|" def visit_table(self, node): if self.use_longtable: -- cgit v1.2.1 From 34e673460e676a67ed552c7c66e2381c6e0c2dbb Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 22 Jun 2003 22:21:28 +0000 Subject: added comments to "unicode" directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1494 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index c220c84cb..581c10269 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -158,8 +158,9 @@ def unicode_directive(name, arguments, options, content, lineno, r""" Convert Unicode character codes (numbers) to characters. Codes may be decimal numbers, hexadecimal numbers (prefixed by ``0x``, ``x``, ``\x``, - ``u``, or ``\u``), or XML-style numbered character entities (e.g. - ``ᨫ``). + ``U+``, ``u``, or ``\u``; e.g. ``U+262E``), or XML-style numeric character + entities (e.g. ``☮``). Text following ".." is a comment and is + ignored. Spaces are ignored, and any other text remains as-is. """ if not isinstance(state, states.SubstitutionDef): error = state_machine.reporter.error( @@ -167,7 +168,7 @@ def unicode_directive(name, arguments, options, content, lineno, 'substitution definition.' % (name), nodes.literal_block(block_text, block_text), line=lineno) return [error] - codes = arguments[0].split() + codes = arguments[0].split('.. ')[0].split() element = nodes.Element() for code in codes: try: -- cgit v1.2.1 From a1a86505970d935e0e0094f2470148366e996681 Mon Sep 17 00:00:00 2001 From: grubert Date: Mon, 23 Jun 2003 07:52:08 +0000 Subject: wide tables where set to 100% of linewidth, reduce to the 93%. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1499 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index e283347b9..e6b168422 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1213,12 +1213,12 @@ class LaTeXTranslator(nodes.NodeVisitor): width = 80 total_width = 0.0 - # donot make it full linewidth - factor = 0.93 # first see if we get too wide. for node in self.colspecs: - colwidth = factor * float(node['colwidth']) / width + colwidth = float(node['colwidth']) / width total_width += colwidth + # donot make it full linewidth + factor = 0.93 if total_width > 1.0: factor /= total_width -- cgit v1.2.1 From b48b803fa2457708113c059d539e9053abdaeb3f Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 25 Jun 2003 01:47:04 +0000 Subject: ready for release 0.3 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1504 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index a631b7f0b..188a3a711 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -49,12 +49,12 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.2.10' +__version__ = '0.3.0' """``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.""" +will be bumped when the project is feature-complete, and perhaps if there is a +major change in the design.""" class ApplicationError(StandardError): pass -- cgit v1.2.1 From 59bc3d5e94db984d4dac3f87b638416d88f3f755 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 26 Jun 2003 16:31:54 +0000 Subject: fix unicode handling of attribute values; part of bug 760673 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1509 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index f7cbe2e34..808bf2d00 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -257,12 +257,12 @@ class HTMLTranslator(nodes.NodeVisitor): # (But the XHTML (XML) spec says the opposite. ) parts.append(name.lower()) elif isinstance(value, ListType): - values = [str(v) for v in value] + values = [unicode(v) for v in value] parts.append('%s="%s"' % (name.lower(), self.attval(' '.join(values)))) else: parts.append('%s="%s"' % (name.lower(), - self.attval(str(value)))) + self.attval(unicode(value)))) return '<%s%s>%s' % (' '.join(parts), infix, suffix) def emptytag(self, node, tagname, suffix='\n', **attributes): -- cgit v1.2.1 From 19398b08d732989638849d03a7cdc21a366fb811 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 26 Jun 2003 18:32:02 +0000 Subject: added explanatory comments for language mappings git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1510 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/__init__.py | 3 +++ docutils/languages/de.py | 5 +++++ docutils/languages/en.py | 7 +++++++ docutils/languages/es.py | 5 +++++ docutils/languages/fr.py | 5 +++++ docutils/languages/it.py | 5 +++++ docutils/languages/sk.py | 5 +++++ docutils/languages/sv.py | 5 +++++ docutils/parsers/rst/languages/__init__.py | 3 +++ docutils/parsers/rst/languages/de.py | 5 +++++ docutils/parsers/rst/languages/en.py | 7 +++++++ docutils/parsers/rst/languages/es.py | 5 +++++ docutils/parsers/rst/languages/fr.py | 5 +++++ docutils/parsers/rst/languages/it.py | 5 +++++ docutils/parsers/rst/languages/sk.py | 5 +++++ docutils/parsers/rst/languages/sv.py | 5 +++++ 16 files changed, 80 insertions(+) (limited to 'docutils') diff --git a/docutils/languages/__init__.py b/docutils/languages/__init__.py index eb241a02e..a4d451156 100644 --- a/docutils/languages/__init__.py +++ b/docutils/languages/__init__.py @@ -4,6 +4,9 @@ # Date: $Date$ # Copyright: This module has been placed in the public domain. +# Internationalization details are documented in +# . + """ This package contains modules for language-dependent features of Docutils. """ diff --git a/docutils/languages/de.py b/docutils/languages/de.py index 9da99b67a..ddffbda74 100644 --- a/docutils/languages/de.py +++ b/docutils/languages/de.py @@ -4,6 +4,11 @@ # 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. + """ German language mappings for language-dependent features of Docutils. """ diff --git a/docutils/languages/en.py b/docutils/languages/en.py index 066c77286..db578810b 100644 --- a/docutils/languages/en.py +++ b/docutils/languages/en.py @@ -4,6 +4,11 @@ # 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. + """ English-language mappings for language-dependent features of Docutils. """ @@ -11,6 +16,7 @@ English-language mappings for language-dependent features of Docutils. __docformat__ = 'reStructuredText' labels = { + # fixed: language-dependent 'author': 'Author', 'authors': 'Authors', 'organization': 'Organization', @@ -36,6 +42,7 @@ labels = { """Mapping of node class name to label text.""" bibliographic_fields = { + # language-dependent: fixed 'author': 'author', 'authors': 'authors', 'organization': 'organization', diff --git a/docutils/languages/es.py b/docutils/languages/es.py index 599345dd5..7505de5da 100644 --- a/docutils/languages/es.py +++ b/docutils/languages/es.py @@ -4,6 +4,11 @@ # 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. + """ Spanish-language mappings for language-dependent features of Docutils. """ diff --git a/docutils/languages/fr.py b/docutils/languages/fr.py index 3416b0c6f..4a7f3ba4c 100644 --- a/docutils/languages/fr.py +++ b/docutils/languages/fr.py @@ -4,6 +4,11 @@ # 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. + """ French-language mappings for language-dependent features of Docutils. """ diff --git a/docutils/languages/it.py b/docutils/languages/it.py index 1a59b5c7d..d86a5b1ec 100644 --- a/docutils/languages/it.py +++ b/docutils/languages/it.py @@ -4,6 +4,11 @@ # 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. + """ Italian-language mappings for language-dependent features of Docutils. """ diff --git a/docutils/languages/sk.py b/docutils/languages/sk.py index e57e3c8cf..20fa645ad 100644 --- a/docutils/languages/sk.py +++ b/docutils/languages/sk.py @@ -4,6 +4,11 @@ # :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. + """ Slovak-language mappings for language-dependent features of Docutils. """ diff --git a/docutils/languages/sv.py b/docutils/languages/sv.py index 55f25192f..8e8d84f2d 100644 --- a/docutils/languages/sv.py +++ b/docutils/languages/sv.py @@ -4,6 +4,11 @@ # 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. + """ Swedish language mappings for language-dependent features of Docutils. """ diff --git a/docutils/parsers/rst/languages/__init__.py b/docutils/parsers/rst/languages/__init__.py index 86bfd03ba..ea4218657 100644 --- a/docutils/parsers/rst/languages/__init__.py +++ b/docutils/parsers/rst/languages/__init__.py @@ -4,6 +4,9 @@ # Date: $Date$ # Copyright: This module has been placed in the public domain. +# Internationalization details are documented in +# . + """ This package contains modules for language-dependent features of reStructuredText. diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index 7f2a25e78..001b7c3b9 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -5,6 +5,11 @@ # 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. + """ German-language mappings for language-dependent features of reStructuredText. diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index bc488a53e..a9b060f82 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -4,6 +4,11 @@ # 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. + """ English-language mappings for language-dependent features of reStructuredText. @@ -13,6 +18,7 @@ __docformat__ = 'reStructuredText' directives = { + # language-dependent: fixed 'attention': 'attention', 'caution': 'caution', 'danger': 'danger', @@ -54,6 +60,7 @@ directives = { mapping.""" roles = { + # language-dependent: fixed 'abbreviation': 'abbreviation', 'ab': 'abbreviation', 'acronym': 'acronym', diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index 5f3f964a6..d052d918c 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -4,6 +4,11 @@ # 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. + """ Spanish-language mappings for language-dependent features of reStructuredText. diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index 311c5db0f..f75cf6c78 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -4,6 +4,11 @@ # 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. + """ French-language mappings for language-dependent features of reStructuredText. diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index 21ede5bce..aed0f2be5 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -4,6 +4,11 @@ # 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. + """ Italian-language mappings for language-dependent features of reStructuredText. diff --git a/docutils/parsers/rst/languages/sk.py b/docutils/parsers/rst/languages/sk.py index 772f0433f..eb426ed47 100644 --- a/docutils/parsers/rst/languages/sk.py +++ b/docutils/parsers/rst/languages/sk.py @@ -4,6 +4,11 @@ # 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. + """ Slovak-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 e126b9dd1..a2f6b77cc 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -4,6 +4,11 @@ # 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. + """ Swedish language mappings for language-dependent features of reStructuredText. """ -- cgit v1.2.1 From 78994b64301991d92e7e0f610c940059e72ff095 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 27 Jun 2003 15:03:30 +0000 Subject: Afrikaans language mappings by Jannie Hofmeyr git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1513 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/af.py | 60 +++++++++++++++++++++++ docutils/parsers/rst/languages/af.py | 92 ++++++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 docutils/languages/af.py create mode 100644 docutils/parsers/rst/languages/af.py (limited to 'docutils') diff --git a/docutils/languages/af.py b/docutils/languages/af.py new file mode 100644 index 000000000..6bfe4f162 --- /dev/null +++ b/docutils/languages/af.py @@ -0,0 +1,60 @@ +# Author: Jannie Hofmeyr +# Contact: jhsh@sun.ac.za +# 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. + +""" +Afrikaans-language mappings for language-dependent features of Docutils. +""" + +__docformat__ = 'reStructuredText' + +labels = { + 'author': 'Auteur', + 'authors': 'Auteurs', + 'organization': 'Organisasie', + 'address': 'Adres', + 'contact': 'Kontak', + 'version': 'Weergawe', + 'revision': 'Revisie', + 'status': 'Status', + 'date': 'Datum', + 'copyright': 'Kopiereg', + 'dedication': 'Opdrag', + 'abstract': 'Opsomming', + 'attention': 'Aandag!', + 'caution': 'Wees versigtig!', + 'danger': '!GEVAAR!', + 'error': 'Fout', + 'hint': 'Wenk', + 'important': 'Belangrik', + 'note': 'Nota', + 'tip': 'Tip', # hint and tip both have the same translation: wenk + 'warning': 'Waarskuwing', + 'contents': 'Inhoud'} +"""Mapping of node class name to label text.""" + +bibliographic_fields = { + 'auteur': 'author', + 'auteurs': 'authors', + 'organisasie': 'organization', + 'adres': 'address', + 'kontak': 'contact', + 'weergawe': 'version', + 'revisie': 'revision', + 'status': 'status', + 'datum': 'date', + 'kopiereg': 'copyright', + 'opdrag': 'dedication', + 'opsomming': 'abstract'} +"""Afrikaans (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/af.py b/docutils/parsers/rst/languages/af.py new file mode 100644 index 000000000..8ad023ed1 --- /dev/null +++ b/docutils/parsers/rst/languages/af.py @@ -0,0 +1,92 @@ +# Author: Jannie Hofmeyr +# Contact: jhsh@sun.ac.za +# 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. + +""" +Afrikaans-language mappings for language-dependent features of +reStructuredText. +""" + +__docformat__ = 'reStructuredText' + + +directives = { + 'aandag': 'attention', + 'versigtig': 'caution', + 'gevaar': 'danger', + 'fout': 'error', + 'wenk': 'hint', + 'belangrik': 'important', + 'nota': 'note', + 'tip': 'tip', # hint and tip both have the same translation: wenk + 'waarskuwing': 'warning', + 'vermaning': 'admonition', + 'kantstreep': 'sidebar', + 'onderwerp': 'topic', + 'lynblok': 'line-block', + 'parsed-literal (translation required)': 'parsed-literal', + 'rubriek': 'rubric', + 'epigraaf': 'epigraph', + 'hoogtepunte': 'highlights', + 'pull-quote (translation required)': 'pull-quote', + #'vrae': 'questions', + #'qa': 'questions', + #'faq': 'questions', + 'meta': 'meta', + #'beeldkaart': 'imagemap', + 'beeld': 'image', + 'figuur': 'figure', + 'insluiting': 'include', + 'rou': 'raw', + 'vervang': 'replace', + 'unicode': 'unicode', # should this be translated? unikode + 'klas': 'class', + 'inhoud': 'contents', + 'sectnum': 'sectnum', + 'section-numbering': 'sectnum', + #'voetnote': 'footnotes', + #'aanhalings': 'citations', + 'teikennotas': 'target-notes', + 'restructuredtext-test-directive': 'restructuredtext-test-directive'} +"""Afrikaans name to registered (in directives/__init__.py) directive name +mapping.""" + +roles = { + 'afkorting': 'abbreviation', + 'ab': 'abbreviation', + 'akroniem': 'acronym', + 'ac': 'acronym', + 'indeks': 'index', + 'i': 'index', + 'voetskrif': 'subscript', + 'sub': 'subscript', + 'boskrif': 'superscript', + 'sup': 'superscript', + 'titelverwysing': 'title-reference', + 'titel': 'title-reference', + 't': 'title-reference', + 'pep-verwysing': 'pep-reference', + 'pep': 'pep-reference', + 'rfc-verwysing': 'rfc-reference', + 'rfc': 'rfc-reference', + 'nadruk': 'emphasis', + 'sterk': 'strong', + 'literal (translation required)': 'literal', + 'benoemde verwysing': 'named-reference', + 'anonieme verwysing': 'anonymous-reference', + 'voetnootverwysing': 'footnote-reference', + 'aanhalingverwysing': 'citation-reference', + 'vervangingsverwysing': 'substitution-reference', + 'teiken': 'target', + 'uri-verwysing': 'uri-reference', + 'uri': 'uri-reference', + 'url': 'uri-reference',} +"""Mapping of Afrikaans role names to canonical role names for interpreted text. +""" -- cgit v1.2.1 From 38b5d3c93e10b9be8d781f48d286871f3222f135 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 28 Jun 2003 04:26:35 +0000 Subject: Russian language mappings by Roman Suzi git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1515 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/ru.py | 68 +++++++++++++++++++++++++++++++ docutils/parsers/rst/languages/ru.py | 79 ++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 docutils/languages/ru.py create mode 100644 docutils/parsers/rst/languages/ru.py (limited to 'docutils') diff --git a/docutils/languages/ru.py b/docutils/languages/ru.py new file mode 100644 index 000000000..e3b24a0c6 --- /dev/null +++ b/docutils/languages/ru.py @@ -0,0 +1,68 @@ +# Author: Roman Suzi +# Contact: rnd@onego.ru +# 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. + +""" +Russian-language mappings for language-dependent features of Docutils. +""" + +__docformat__ = 'reStructuredText' + +labels = { + u'abstract': u'\u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f', + u'address': u'\u0410\u0434\u0440\u0435\u0441', + u'attention': u'\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435!', + u'author': u'\u0410\u0432\u0442\u043e\u0440', + u'authors': u'\u0410\u0432\u0442\u043e\u0440\u044b', + u'caution': u'\u041e\u0441\u0442\u043e\u0440\u043e\u0436\u043d\u043e!', + u'contact': u'\u041a\u043e\u043d\u0442\u0430\u043a\u0442', + u'contents': + u'\u0421\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435', + u'copyright': u'\u041f\u0440\u0430\u0432\u0430 ' + u'\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f', + u'danger': u'\u041e\u041f\u0410\u0421\u041d\u041e!', + u'date': u'\u0414\u0430\u0442\u0430', + u'dedication': + u'\u041f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u0438\u0435', + u'error': u'\u041e\u0448\u0438\u0431\u043a\u0430', + u'hint': u'\u0421\u043e\u0432\u0435\u0442', + u'important': u'\u0412\u0430\u0436\u043d\u043e', + u'note': u'\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435', + u'organization': + u'\u041e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044f', + u'revision': u'\u0420\u0435\u0434\u0430\u043a\u0446\u0438\u044f', + u'status': u'\u0421\u0442\u0430\u0442\u0443\u0441', + u'tip': u'\u041f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0430', + u'version': u'\u0412\u0435\u0440\u0441\u0438\u044f', + u'warning': u'\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436' + u'\u0434\u0435\u043d\u0438\u0435'} +"""Mapping of node class name to label text.""" + +bibliographic_fields = { + u'\u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f': u'abstract', + u'\u0410\u0434\u0440\u0435\u0441': u'address', + u'\u0410\u0432\u0442\u043e\u0440': u'author', + u'\u0410\u0432\u0442\u043e\u0440\u044b': u'authors', + u'\u041a\u043e\u043d\u0442\u0430\u043a\u0442': u'contact', + u'\u041f\u0440\u0430\u0432\u0430 \u043a\u043e\u043f\u0438\u0440\u043e' + u'\u0432\u0430\u043d\u0438\u044f': u'copyright', + u'\u0414\u0430\u0442\u0430': u'date', + u'\u041f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u0438\u0435': + u'dedication', + u'\u041e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044f': + u'organization', + u'\u0420\u0435\u0434\u0430\u043a\u0446\u0438\u044f': u'revision', + u'\u0421\u0442\u0430\u0442\u0443\u0441': u'status', + u'\u0412\u0435\u0440\u0441\u0438\u044f': u'version'} +"""Russian (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/ru.py b/docutils/parsers/rst/languages/ru.py new file mode 100644 index 000000000..d1bb1bc94 --- /dev/null +++ b/docutils/parsers/rst/languages/ru.py @@ -0,0 +1,79 @@ +# Author: Roman Suzi +# Contact: rnd@onego.ru +# 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. + +""" +Russian-language mappings for language-dependent features of +reStructuredText. +""" + +__docformat__ = 'reStructuredText' + +directives = { + u'line-block': u'line-block', + u'meta': u'meta', + u'parsed-literal': u'parsed-literal', + u'pull-quote': u'pull-quote', + u'raw': u'raw', + u'replace': u'replace', + u'restructuredtext-test-directive': u'restructuredtext-test-directive', + u'target-notes': u'target-notes', + u'unicode': u'unicode', + u'\u0431\u043e\u043a\u043e\u0432\u043e\u0435-\u043c\u0435\u043d\u044e': + u'sidebar', + u'\u0432\u0430\u0436\u043d\u043e': u'important', + u'\u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c': u'include', + u'\u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435': u'attention', + u'\u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435': u'highlights', + u'\u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435': u'admonition', + u'\u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435': + u'image', + u'\u043a\u043b\u0430\u0441\u0441': u'class', + 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' + u'\u0434\u0435\u043b\u043e\u0432': u'sectnum', + u'\u043e\u043f\u0430\u0441\u043d\u043e': u'danger', + u'\u043e\u0441\u0442\u043e\u0440\u043e\u0436\u043d\u043e': u'caution', + u'\u043e\u0448\u0438\u0431\u043a\u0430': u'error', + u'\u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0430': u'tip', + u'\u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d' + u'\u0438\u0435': u'warning', + u'\u043f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435': u'note', + u'\u0440\u0438\u0441\u0443\u043d\u043e\u043a': u'figure', + u'\u0440\u0443\u0431\u0440\u0438\u043a\u0430': u'rubric', + 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'} +"""Russian name to registered (in directives/__init__.py) directive name +mapping.""" + +roles = { + u'abbreviation (translation required)': 'abbreviation', + u'acronym (translation required)': 'acronym', + u'index (translation required)': 'index', + u'subscript (translation required)': 'subscript', + u'superscript (translation required)': 'superscript', + u'title-reference (translation required)': 'title-reference', + u'pep-reference (translation required)': 'pep-reference', + u'rfc-reference (translation required)': 'rfc-reference', + u'emphasis (translation required)': 'emphasis', + u'strong (translation required)': 'strong', + u'literal (translation required)': 'literal', + u'named-reference (translation required)': 'named-reference', + u'anonymous-reference (translation required)': 'anonymous-reference', + u'footnote-reference (translation required)': 'footnote-reference', + u'citation-reference (translation required)': 'citation-reference', + u'substitution-reference (translation required)': 'substitution-reference', + u'target (translation required)': 'target', + u'uri-reference (translation required)': 'uri-reference',} +"""Mapping of Russian role names to canonical role names for interpreted text. +""" -- cgit v1.2.1 From d3cfd957a5f0b80907bbb272a92e818b09556bf6 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 28 Jun 2003 04:27:51 +0000 Subject: cleaned up & added "roles" mapping to language modules git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1516 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/sv.py | 1 + docutils/parsers/rst/languages/de.py | 24 +++++++++++++++++++++++- docutils/parsers/rst/languages/es.py | 4 +++- docutils/parsers/rst/languages/fr.py | 22 ++++++++++++++++++++++ docutils/parsers/rst/languages/it.py | 24 +++++++++++++++++++++++- docutils/parsers/rst/languages/sk.py | 22 ++++++++++++++++++++++ docutils/parsers/rst/languages/sv.py | 22 ++++++++++++++++++++++ 7 files changed, 116 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/languages/sv.py b/docutils/languages/sv.py index 8e8d84f2d..3454ca6c1 100644 --- a/docutils/languages/sv.py +++ b/docutils/languages/sv.py @@ -43,6 +43,7 @@ labels = { bibliographic_fields = { # 'Author' and 'Authors' identical in Swedish; assume the plural: u'f\u00f6rfattare': 'authors', + u' n/a': 'author', u'organisation': 'organization', u'adress': 'address', u'kontakt': 'contact', diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index 001b7c3b9..017a2e851 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -57,5 +57,27 @@ directives = { #'footnotes': 'footnotes', #'citations': 'citations', 'restructuredtext-test-directive': 'restructuredtext-test-directive'} -"""English name to registered (in directives/__init__.py) directive name +"""German name to registered (in directives/__init__.py) directive name mapping.""" + +roles = { + 'abbreviation (translation required)': 'abbreviation', + 'acronym (translation required)': 'acronym', + 'index (translation required)': 'index', + 'subscript (translation required)': 'subscript', + 'superscript (translation required)': 'superscript', + 'title-reference (translation required)': 'title-reference', + 'pep-reference (translation required)': 'pep-reference', + 'rfc-reference (translation required)': 'rfc-reference', + 'emphasis (translation required)': 'emphasis', + 'strong (translation required)': 'strong', + 'literal (translation required)': 'literal', + 'named-reference (translation required)': 'named-reference', + 'anonymous-reference (translation required)': 'anonymous-reference', + 'footnote-reference (translation required)': 'footnote-reference', + 'citation-reference (translation required)': 'citation-reference', + 'substitution-reference (translation required)': 'substitution-reference', + 'target (translation required)': 'target', + 'uri-reference (translation required)': 'uri-reference',} +"""Mapping of German role names to canonical role names for interpreted text. +""" diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index d052d918c..53bb9ff77 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -62,7 +62,7 @@ directives = { #'footnotes': 'footnotes', #'citations': 'citations', u'restructuredtext-test-directive': 'restructuredtext-test-directive'} -"""English name to registered (in directives/__init__.py) directive name +"""Spanish name to registered (in directives/__init__.py) directive name mapping.""" roles = { @@ -73,6 +73,8 @@ roles = { u'ac': 'acronym', u'indice': 'index', u'i': 'index', + u'subscript (translation required)': 'subscript', + u'superscript (translation required)': 'superscript', u'referencia-titulo': 'title-reference', u'titulo': 'title-reference', u't': 'title-reference', diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index f75cf6c78..25f0586a2 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -60,3 +60,25 @@ directives = { } """French name to registered (in directives/__init__.py) directive name mapping.""" + +roles = { + u'abbreviation (translation required)': 'abbreviation', + u'acronym (translation required)': 'acronym', + u'index (translation required)': 'index', + u'subscript (translation required)': 'subscript', + u'superscript (translation required)': 'superscript', + u'title-reference (translation required)': 'title-reference', + u'pep-reference (translation required)': 'pep-reference', + u'rfc-reference (translation required)': 'rfc-reference', + u'emphasis (translation required)': 'emphasis', + u'strong (translation required)': 'strong', + u'literal (translation required)': 'literal', + u'named-reference (translation required)': 'named-reference', + u'anonymous-reference (translation required)': 'anonymous-reference', + u'footnote-reference (translation required)': 'footnote-reference', + u'citation-reference (translation required)': 'citation-reference', + u'substitution-reference (translation required)': 'substitution-reference', + u'target (translation required)': 'target', + u'uri-reference (translation required)': 'uri-reference',} +"""Mapping of French role names to canonical role names for interpreted text. +""" diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index aed0f2be5..911c69a66 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -55,5 +55,27 @@ directives = { #'footnotes': 'footnotes', #'citations': 'citations', 'restructuredtext-test-directive': 'restructuredtext-test-directive'} -"""English name to registered (in directives/__init__.py) directive name +"""Italian name to registered (in directives/__init__.py) directive name mapping.""" + +roles = { + 'abbreviation (translation required)': 'abbreviation', + 'acronym (translation required)': 'acronym', + 'index (translation required)': 'index', + 'subscript (translation required)': 'subscript', + 'superscript (translation required)': 'superscript', + 'title-reference (translation required)': 'title-reference', + 'pep-reference (translation required)': 'pep-reference', + 'rfc-reference (translation required)': 'rfc-reference', + 'emphasis (translation required)': 'emphasis', + 'strong (translation required)': 'strong', + 'literal (translation required)': 'literal', + 'named-reference (translation required)': 'named-reference', + 'anonymous-reference (translation required)': 'anonymous-reference', + 'footnote-reference (translation required)': 'footnote-reference', + 'citation-reference (translation required)': 'citation-reference', + 'substitution-reference (translation required)': 'substitution-reference', + 'target (translation required)': 'target', + 'uri-reference (translation required)': 'uri-reference',} +"""Mapping of Italian role names to canonical role names for interpreted text. +""" diff --git a/docutils/parsers/rst/languages/sk.py b/docutils/parsers/rst/languages/sk.py index eb426ed47..caf3ed5c4 100644 --- a/docutils/parsers/rst/languages/sk.py +++ b/docutils/parsers/rst/languages/sk.py @@ -57,3 +57,25 @@ directives = { } """Slovak name to registered (in directives/__init__.py) directive name mapping.""" + +roles = { + u'abbreviation (translation required)': 'abbreviation', + u'acronym (translation required)': 'acronym', + u'index (translation required)': 'index', + u'subscript (translation required)': 'subscript', + u'superscript (translation required)': 'superscript', + u'title-reference (translation required)': 'title-reference', + u'pep-reference (translation required)': 'pep-reference', + u'rfc-reference (translation required)': 'rfc-reference', + u'emphasis (translation required)': 'emphasis', + u'strong (translation required)': 'strong', + u'literal (translation required)': 'literal', + u'named-reference (translation required)': 'named-reference', + u'anonymous-reference (translation required)': 'anonymous-reference', + u'footnote-reference (translation required)': 'footnote-reference', + u'citation-reference (translation required)': 'citation-reference', + u'substitution-reference (translation required)': 'substitution-reference', + u'target (translation required)': 'target', + u'uri-reference (translation required)': 'uri-reference',} +"""Mapping of Slovak role names to canonical role names for interpreted text. +""" diff --git a/docutils/parsers/rst/languages/sv.py b/docutils/parsers/rst/languages/sv.py index a2f6b77cc..04d105f90 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -56,3 +56,25 @@ directives = { } """Swedish name to registered (in directives/__init__.py) directive name mapping.""" + +roles = { + u'abbreviation (translation required)': 'abbreviation', + u'acronym (translation required)': 'acronym', + u'index (translation required)': 'index', + u'subscript (translation required)': 'subscript', + u'superscript (translation required)': 'superscript', + u'title-reference (translation required)': 'title-reference', + u'pep-reference (translation required)': 'pep-reference', + u'rfc-reference (translation required)': 'rfc-reference', + u'emphasis (translation required)': 'emphasis', + u'strong (translation required)': 'strong', + u'literal (translation required)': 'literal', + u'named-reference (translation required)': 'named-reference', + u'anonymous-reference (translation required)': 'anonymous-reference', + u'footnote-reference (translation required)': 'footnote-reference', + u'citation-reference (translation required)': 'citation-reference', + u'substitution-reference (translation required)': 'substitution-reference', + u'target (translation required)': 'target', + u'uri-reference (translation required)': 'uri-reference',} +"""Mapping of Swedish role names to canonical role names for interpreted text. +""" -- cgit v1.2.1 From cdb8635afb5913cd53eed6fc5aae4b3fce782660 Mon Sep 17 00:00:00 2001 From: rnd0110 Date: Sat, 28 Jun 2003 11:35:58 +0000 Subject: roles translation added git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1520 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/ru.py | 46 ++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 18 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/ru.py b/docutils/parsers/rst/languages/ru.py index d1bb1bc94..df2ea0312 100644 --- a/docutils/parsers/rst/languages/ru.py +++ b/docutils/parsers/rst/languages/ru.py @@ -57,23 +57,33 @@ directives = { mapping.""" roles = { - u'abbreviation (translation required)': 'abbreviation', - u'acronym (translation required)': 'acronym', - u'index (translation required)': 'index', - u'subscript (translation required)': 'subscript', - u'superscript (translation required)': 'superscript', - u'title-reference (translation required)': 'title-reference', - u'pep-reference (translation required)': 'pep-reference', - u'rfc-reference (translation required)': 'rfc-reference', - u'emphasis (translation required)': 'emphasis', - u'strong (translation required)': 'strong', - u'literal (translation required)': 'literal', - u'named-reference (translation required)': 'named-reference', - u'anonymous-reference (translation required)': 'anonymous-reference', - u'footnote-reference (translation required)': 'footnote-reference', - u'citation-reference (translation required)': 'citation-reference', - u'substitution-reference (translation required)': 'substitution-reference', - u'target (translation required)': 'target', - u'uri-reference (translation required)': 'uri-reference',} + u'\u0430\u043a\u0440\u043e\u043d\u0438\u043c': 'acronym', + u'\u0430\u043d\u043e\u043d\u0438\u043c\u043d\u0430\u044f-\u0441\u0441\u044b\u043b\u043a\u0430': + 'anonymous-reference', + u'\u0431\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e': 'literal', + u'\u0432\u0435\u0440\u0445\u043d\u0438\u0439-\u0438\u043d\u0434\u0435\u043a\u0441': + 'superscript', + u'\u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435': 'emphasis', + u'\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u043d\u0430\u044f-\u0441\u0441\u044b\u043b\u043a\u0430': + 'named-reference', + u'\u0438\u043d\u0434\u0435\u043a\u0441': 'index', + u'\u043d\u0438\u0436\u043d\u0438\u0439-\u0438\u043d\u0434\u0435\u043a\u0441': + 'subscript', + u'\u0441\u0438\u043b\u044c\u043d\u043e\u0435-\u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435': + 'strong', + u'\u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0435': + 'abbreviation', + u'\u0441\u0441\u044b\u043b\u043a\u0430-\u0437\u0430\u043c\u0435\u043d\u0430': + 'substitution-reference', + u'\u0441\u0441\u044b\u043b\u043a\u0430-\u043d\u0430-pep': 'pep-reference', + u'\u0441\u0441\u044b\u043b\u043a\u0430-\u043d\u0430-rfc': 'rfc-reference', + u'\u0441\u0441\u044b\u043b\u043a\u0430-\u043d\u0430-uri': 'uri-reference', + u'\u0441\u0441\u044b\u043b\u043a\u0430-\u043d\u0430-\u0437\u0430\u0433\u043b\u0430\u0432\u0438\u0435': + 'title-reference', + u'\u0441\u0441\u044b\u043b\u043a\u0430-\u043d\u0430-\u0441\u043d\u043e\u0441\u043a\u0443': + 'footnote-reference', + u'\u0446\u0438\u0442\u0430\u0442\u043d\u0430\u044f-\u0441\u0441\u044b\u043b\u043a\u0430': + 'citation-reference', + u'\u044f\u043a\u043e\u0440\u044c': 'target'} """Mapping of Russian role names to canonical role names for interpreted text. """ -- cgit v1.2.1 From b21306e492669e1ef941794018d0347e2dbc31f9 Mon Sep 17 00:00:00 2001 From: rnd0110 Date: Sat, 28 Jun 2003 15:01:21 +0000 Subject: More and better translations git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1521 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/ru.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/ru.py b/docutils/parsers/rst/languages/ru.py index df2ea0312..366f4505f 100644 --- a/docutils/parsers/rst/languages/ru.py +++ b/docutils/parsers/rst/languages/ru.py @@ -17,16 +17,20 @@ reStructuredText. __docformat__ = 'reStructuredText' directives = { - u'line-block': u'line-block', + u'\u0431\u043b\u043e\u043a-\u0441\u0442\u0440\u043e\u043a': u'line-block', u'meta': u'meta', - u'parsed-literal': u'parsed-literal', - u'pull-quote': u'pull-quote', - u'raw': u'raw', - u'replace': u'replace', - u'restructuredtext-test-directive': u'restructuredtext-test-directive', - u'target-notes': u'target-notes', + u'\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0439-\u043b\u0438\u0442\u0435\u0440\u0430\u043b': + u'parsed-literal', + u'\u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f-\u0446\u0438\u0442\u0430\u0442\u0430': + u'pull-quote', + u'\u0441\u044b\u0440\u043e\u0439': u'raw', + u'\u0437\u0430\u043c\u0435\u043d\u0430': u'replace', + u'\u0442\u0435\u0441\u0442\u043e\u0432\u0430\u044f-\u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u0430-restructuredtext': + u'restructuredtext-test-directive', + u'\u0446\u0435\u043b\u0435\u0432\u044b\u0435-\u0441\u043d\u043e\u0441\u043a\u0438': + u'target-notes', u'unicode': u'unicode', - u'\u0431\u043e\u043a\u043e\u0432\u043e\u0435-\u043c\u0435\u043d\u044e': + u'\u0431\u043e\u043a\u043e\u0432\u0430\u044f-\u043f\u043e\u043b\u043e\u0441\u0430': u'sidebar', u'\u0432\u0430\u0436\u043d\u043e': u'important', u'\u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c': u'include', @@ -84,6 +88,6 @@ roles = { 'footnote-reference', u'\u0446\u0438\u0442\u0430\u0442\u043d\u0430\u044f-\u0441\u0441\u044b\u043b\u043a\u0430': 'citation-reference', - u'\u044f\u043a\u043e\u0440\u044c': 'target'} + u'\u0446\u0435\u043b\u044c': 'target'} """Mapping of Russian role names to canonical role names for interpreted text. """ -- cgit v1.2.1 From c3be2fe537769a1489e62dacf06e4a7192721949 Mon Sep 17 00:00:00 2001 From: grubert Date: Sat, 28 Jun 2003 17:36:51 +0000 Subject: respect specified output encoding, at least try. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1522 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index e6b168422..f41ca61aa 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -237,7 +237,7 @@ class LaTeXTranslator(nodes.NodeVisitor): d_margins = '2cm' latex_head = '\\documentclass[%s]{%s}\n' - encoding = '\\usepackage[latin1]{inputenc}\n' + encoding = '\\usepackage[%s]{inputenc}\n' linking = '\\usepackage[colorlinks=%s,linkcolor=%s,urlcolor=%s]{hyperref}\n' geometry = '\\usepackage[%s,margin=%s,nohead]{geometry}\n' stylesheet = '\\input{%s}\n' @@ -281,7 +281,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.latex_head % (self.d_options,self.settings.documentclass), '\\usepackage{babel}\n', # language is in documents settings. '\\usepackage{shortvrb}\n', # allows verb in footnotes. - self.encoding, + self.encoding % self.to_latex_encoding(settings.output_encoding), # * tabularx: for docinfo, automatic width of columns, always on one page. '\\usepackage{tabularx}\n', '\\usepackage{longtable}\n', @@ -364,6 +364,39 @@ class LaTeXTranslator(nodes.NodeVisitor): else: return self.settings.stylesheet + 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-8859-9": "latin5", # turkish + "iso-8859-15": "latin9", # latin9, update to latin1. + "mac_cyrillic": "maycyr", + # 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] -- cgit v1.2.1 From f971b5d387d6eda67c4b3e086dd40aea9e794f61 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 29 Jun 2003 04:52:52 +0000 Subject: catch system messages to stop tracebacks from parsing errors git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1523 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index 5fe7e93cd..61bf534b8 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -16,7 +16,7 @@ __docformat__ = 'reStructuredText' import sys from docutils import Component -from docutils import frontend, io, readers, parsers, writers +from docutils import frontend, io, utils, readers, parsers, writers from docutils.frontend import OptionParser, ConfigParser @@ -165,9 +165,16 @@ class Publisher: elif settings_overrides: 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) + try: + document = self.reader.read(self.source, self.parser, + self.settings) + self.apply_transforms(document) + output = self.writer.write(document, self.destination) + except utils.SystemMessage, error: + print >>sys.stderr, ('Exiting due to level-%s (%s) system message.' + % (error.level, + utils.Reporter.levels[error.level])) + sys.exit(1) if self.settings.dump_settings: from pprint import pformat print >>sys.stderr, '\n::: Runtime settings:' -- cgit v1.2.1 From d6cd2da9b49062e68524ceda90aca462600476de Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 29 Jun 2003 04:53:54 +0000 Subject: prevent duplicate detailed error reporting except when debugging git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1524 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/statemachine.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/statemachine.py b/docutils/statemachine.py index d0ddb6330..060347ade 100644 --- a/docutils/statemachine.py +++ b/docutils/statemachine.py @@ -266,7 +266,8 @@ class StateMachine: transitions = None state = self.get_state(next_state) except: - self.error() + if self.debug: + self.error() raise self.observers = [] return results -- cgit v1.2.1 From e84dbccb28c6fb0f1415fa0149c6f3e5d6abdf83 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 29 Jun 2003 04:54:42 +0000 Subject: add "level" attribute to SystemMessage exception git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1525 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/utils.py b/docutils/utils.py index aa97e71c1..2e60a6c6f 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -20,8 +20,9 @@ from docutils import frontend, nodes class SystemMessage(ApplicationError): - def __init__(self, system_message): + def __init__(self, system_message, level): Exception.__init__(self, system_message.astext()) + self.level = level class Reporter: @@ -181,7 +182,7 @@ class Reporter: else: print >>stream, msgtext if level >= halt_level: - raise SystemMessage(msg) + raise SystemMessage(msg, level) if level > 0 or debug: self.notify_observers(msg) self.max_level = max(level, self.max_level) -- cgit v1.2.1 From 5a8e95129e0a2603d6b711b5d22b060d071e2021 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 29 Jun 2003 15:39:51 +0000 Subject: improved error message; suggestion by Roman Suzi git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1527 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 2fc1f8866..c8d04325f 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -2823,7 +2823,7 @@ class Line(SpecializedText): self.short_overline(context, blocktext, lineno, 2) else: msg = self.reporter.severe( - 'Missing underline for overline.', + 'Missing matching underline for section title overline.', nodes.literal_block(source, source), line=lineno) self.parent += msg return [], 'Body', [] -- cgit v1.2.1 From ae3ee37139f01572fdb17a5e1b7ecdd0320cb757 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 29 Jun 2003 23:34:45 +0000 Subject: remove unused import git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1528 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index 61bf534b8..0b8a91726 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -17,7 +17,7 @@ __docformat__ = 'reStructuredText' import sys from docutils import Component from docutils import frontend, io, utils, readers, parsers, writers -from docutils.frontend import OptionParser, ConfigParser +from docutils.frontend import OptionParser class Publisher: -- cgit v1.2.1 From 6eab4e2fff15bc6538faaad087676a146e588b0a Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 30 Jun 2003 15:26:15 +0000 Subject: Catch IOErrors when opening source & destination files, report & exit without tracebacks. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1531 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index 9e6e75151..0ef4bdab6 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -147,7 +147,15 @@ class FileInput(Input): self.autoclose = autoclose if source is None: if source_path: - self.source = open(source_path) + try: + self.source = open(source_path) + except IOError, error: + print >>sys.stderr, '%s: %s' % (error.__class__.__name__, + error) + print >>sys.stderr, ( + 'Unable to open source file for reading (%s). Exiting.' + % source_path) + sys.exit(1) else: self.source = sys.stdin self.autoclose = None @@ -203,7 +211,14 @@ class FileOutput(Output): pass def open(self): - self.destination = open(self.destination_path, 'w') + try: + self.destination = open(self.destination_path, 'w') + except IOError, error: + print >>sys.stderr, '%s: %s' % (error.__class__.__name__, + error) + print >>sys.stderr, ('Unable to open destination file for writing ' + '(%s). Exiting.' % source_path) + sys.exit(1) self.opened = 1 def write(self, data): -- cgit v1.2.1 From 1a7567c0b74bd5b6f2e4725ddbb0a3c148569670 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 30 Jun 2003 15:26:41 +0000 Subject: Added "--traceback" & "--no-traceback" options ("traceback" setting). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1532 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index d1393e003..5952ec19e 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -234,12 +234,18 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): 'system message level plus 10 (11 for INFO, etc.).', ['--exit'], {'choices': threshold_choices, 'dest': 'exit_level', 'default': 5, 'metavar': ''}), - ('Report debug-level system messages.', + ('Report debug-level system messages and generate diagnostic output.', ['--debug'], {'action': 'store_true'}), - ('Do not report debug-level system messages.', + ('Do not report debug-level system messages or generate diagnostic ' + 'output.', ['--no-debug'], {'action': 'store_false', 'dest': 'debug'}), ('Send the output of system messages (warnings) to .', ['--warnings'], {'dest': 'warning_stream', 'metavar': ''}), + ('Enable Python tracebacks when an error occurs.', + ['--traceback'], {'action': 'store_true', 'default': None}), + ('Disable Python tracebacks when errors occur; report just the error ' + 'instead. This is the default.', + ['--no-traceback'], {'dest': 'traceback', 'action': 'store_false'}), ('Specify the encoding of input text. Default is locale-dependent.', ['--input-encoding', '-i'], {'action': 'callback', 'callback': set_encoding, -- cgit v1.2.1 From 67d42a2ee52e043a2fc401db7e8ffc4082a7aebc Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 30 Jun 2003 15:50:45 +0000 Subject: Catch exceptions during processing, report and exit without tracebacks, except when "--traceback" used. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1533 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index 0b8a91726..6d78ac57f 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -15,7 +15,7 @@ custom component objects first, and pass *them* to __docformat__ = 'reStructuredText' import sys -from docutils import Component +from docutils import Component, __version__ from docutils import frontend, io, utils, readers, parsers, writers from docutils.frontend import OptionParser @@ -165,35 +165,52 @@ class Publisher: elif settings_overrides: self.settings._update(settings_overrides, 'loose') 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) except utils.SystemMessage, error: + if self.settings.traceback: + raise print >>sys.stderr, ('Exiting due to level-%s (%s) system message.' % (error.level, utils.Reporter.levels[error.level])) - sys.exit(1) + exit = 1 + except Exception, error: + if self.settings.traceback: + raise + print >>sys.stderr, error + print >>sys.stderr, ("""\ +Exiting due to error. Use "--traceback" to diagnose. +Please report errors to . +Include "--traceback" output, Docutils version (%s), +Python version (%s), your OS type & version, and the +command line used.""" % (__version__, sys.version.split()[0])) + exit = 1 if self.settings.dump_settings: from pprint import pformat print >>sys.stderr, '\n::: Runtime settings:' print >>sys.stderr, pformat(self.settings.__dict__) - if self.settings.dump_internals: + if self.settings.dump_internals and document: from pprint import pformat print >>sys.stderr, '\n::: Document internals:' print >>sys.stderr, pformat(document.__dict__) - if self.settings.dump_transforms: + if self.settings.dump_transforms and document: from pprint import pformat print >>sys.stderr, '\n::: Transforms applied:' print >>sys.stderr, pformat(document.transformer.applied) - if self.settings.dump_pseudo_xml: + if self.settings.dump_pseudo_xml and document: print >>sys.stderr, '\n::: Pseudo-XML:' print >>sys.stderr, document.pformat().encode( 'raw_unicode_escape') - if enable_exit and (document.reporter.max_level - >= self.settings.exit_level): + if enable_exit and document and (document.reporter.max_level + >= self.settings.exit_level): sys.exit(document.reporter.max_level + 10) + elif exit: + sys.exit(1) return output -- cgit v1.2.1 From 45402ec3398e5e4dab0a3ce2b75c9c72c15cd695 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 1 Jul 2003 05:12:56 +0000 Subject: bugfix from Adrian van den Dries git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1538 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 808bf2d00..b73a622ad 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -527,7 +527,7 @@ class HTMLTranslator(nodes.NodeVisitor): if len(node): if isinstance(node[0], nodes.Element): node[0].set_class('first') - if isinstance(node[0], nodes.Element): + if isinstance(node[-1], nodes.Element): node[-1].set_class('last') def depart_docinfo_item(self): -- cgit v1.2.1 From ed5f23bfb8a76d37b7ae7504e821c4eaee9c8a91 Mon Sep 17 00:00:00 2001 From: wilk Date: Tue, 1 Jul 2003 09:44:23 +0000 Subject: contents = sommaire git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1540 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/fr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/languages/fr.py b/docutils/languages/fr.py index 4a7f3ba4c..52317c174 100644 --- a/docutils/languages/fr.py +++ b/docutils/languages/fr.py @@ -37,7 +37,7 @@ labels = { u'note': u'Note', u'tip': u'Astuce', u'warning': u'Avis', - u'contents': u'Contenu'} + u'contents': u'Sommaire'} """Mapping of node class name to label text.""" bibliographic_fields = { -- cgit v1.2.1 From ba89d44c4b8dc3f864afeb94a33aa871c749c727 Mon Sep 17 00:00:00 2001 From: wilk Date: Tue, 1 Jul 2003 09:45:46 +0000 Subject: =?UTF-8?q?m=EF=BF=BDta=20=3D=20meta=20remplace=20=3D=20replace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1541 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/fr.py | 43 ++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 19 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index 25f0586a2..7fa0004d3 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -41,13 +41,14 @@ directives = { #u'questions': 'questions', #u'qr': 'questions', #u'faq': 'questions', - u'meta': 'meta', + u'm\u00E9ta': 'meta', #u'imagemap (translation required)': 'imagemap', u'image': 'image', u'figure': 'figure', u'inclure': 'include', u'brut': 'raw', u'remplacer': 'replace', + u'remplace': 'replace', u'unicode': 'unicode', u'classe': 'class', u'sommaire': 'contents', @@ -62,23 +63,27 @@ directives = { mapping.""" roles = { - u'abbreviation (translation required)': 'abbreviation', - u'acronym (translation required)': 'acronym', - u'index (translation required)': 'index', - u'subscript (translation required)': 'subscript', - u'superscript (translation required)': 'superscript', - u'title-reference (translation required)': 'title-reference', - u'pep-reference (translation required)': 'pep-reference', - u'rfc-reference (translation required)': 'rfc-reference', - u'emphasis (translation required)': 'emphasis', - u'strong (translation required)': 'strong', - u'literal (translation required)': 'literal', - u'named-reference (translation required)': 'named-reference', - u'anonymous-reference (translation required)': 'anonymous-reference', - u'footnote-reference (translation required)': 'footnote-reference', - u'citation-reference (translation required)': 'citation-reference', - u'substitution-reference (translation required)': 'substitution-reference', - u'target (translation required)': 'target', - u'uri-reference (translation required)': 'uri-reference',} + u'abr\u00E9viation': 'abbreviation', + u'acronyme': 'acronym', + u'sigle': 'acronym', + u'index': 'index', + u'indice': 'subscript', + u'ind': 'subscript', + u'exposant': 'superscript', + u'exp': 'superscript', + u'titre-r\u00E9f\u00E9rence': 'title-reference', + u'titre': 'title-reference', + u'pep-r\u00E9f\u00E9rence': 'pep-reference', + u'rfc-r\u00E9f\u00E9rence': 'rfc-reference', + u'emphase': 'emphasis', + u'gras': 'strong', + u'litt\u00E9ral': 'literal', + u'nomm\u00E9e-r\u00E9f\u00E9rence': 'named-reference', + u'anonyme-r\u00E9f\u00E9rence': 'anonymous-reference', + u'note-r\u00E9f\u00E9rence': 'footnote-reference', + u'citation-r\u00E9f\u00E9rence': 'citation-reference', + u'substitution-r\u00E9f\u00E9rence': 'substitution-reference', + u'lien': 'target', + u'uri-r\u00E9f\u00E9rence': 'uri-reference',} """Mapping of French role names to canonical role names for interpreted text. """ -- cgit v1.2.1 From 2bab11599eb2b1c483cd583a7cac724782eb461a Mon Sep 17 00:00:00 2001 From: wilk Date: Tue, 1 Jul 2003 09:50:59 +0000 Subject: fort = strong git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1542 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/fr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index 7fa0004d3..ba0bcb014 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -76,7 +76,7 @@ roles = { u'pep-r\u00E9f\u00E9rence': 'pep-reference', u'rfc-r\u00E9f\u00E9rence': 'rfc-reference', u'emphase': 'emphasis', - u'gras': 'strong', + u'fort': 'strong', u'litt\u00E9ral': 'literal', u'nomm\u00E9e-r\u00E9f\u00E9rence': 'named-reference', u'anonyme-r\u00E9f\u00E9rence': 'anonymous-reference', -- cgit v1.2.1 From 09d084cc9ef1130ed1e0da9669746c2901c715cb Mon Sep 17 00:00:00 2001 From: rnd0110 Date: Tue, 1 Jul 2003 19:32:39 +0000 Subject: s/maycyr/maccyr/ git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1546 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index f41ca61aa..bca579027 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -378,7 +378,7 @@ class LaTeXTranslator(nodes.NodeVisitor): "iso-8859-5": "iso88595", # cyrillic "iso-8859-9": "latin5", # turkish "iso-8859-15": "latin9", # latin9, update to latin1. - "mac_cyrillic": "maycyr", + "mac_cyrillic": "maccyr", # unmatched encodings #"": "applemac", #"": "ansinew", # windows 3.1 ansi -- cgit v1.2.1 From c9d4867709d6431f2007f9ee4f1f0dd276a270ec Mon Sep 17 00:00:00 2001 From: rnd0110 Date: Tue, 1 Jul 2003 19:54:35 +0000 Subject: more LaTeX encodings added git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1547 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index bca579027..619d168b7 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -375,10 +375,16 @@ class LaTeXTranslator(nodes.NodeVisitor): "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-8859-5": "iso88595", # cyrillic (ISO) "iso-8859-9": "latin5", # turkish "iso-8859-15": "latin9", # latin9, update to latin1. - "mac_cyrillic": "maccyr", + "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 -- cgit v1.2.1 From 3a29321390896b511eecbb1327be76da51d8a809 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 4 Jul 2003 01:42:50 +0000 Subject: Added ``handle_io_errors`` parameter to ``FileInput`` & ``FileOutput`` to enable caller error handling. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1563 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 11 +++++++++-- docutils/parsers/rst/directives/misc.py | 6 ++++-- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index 0ef4bdab6..ab154b6e2 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -134,7 +134,7 @@ class FileInput(Input): """ def __init__(self, source=None, source_path=None, - encoding=None, autoclose=1): + encoding=None, autoclose=1, handle_io_errors=1): """ :Parameters: - `source`: either a file-like object (which is read directly), or @@ -145,11 +145,14 @@ class FileInput(Input): """ Input.__init__(self, source, source_path, encoding) self.autoclose = autoclose + self.handle_io_errors = handle_io_errors if source is None: if source_path: try: self.source = open(source_path) except IOError, error: + if not handle_io_errors: + raise print >>sys.stderr, '%s: %s' % (error.__class__.__name__, error) print >>sys.stderr, ( @@ -183,7 +186,8 @@ class FileOutput(Output): """ def __init__(self, destination=None, destination_path=None, - encoding=None, error_handler='strict', autoclose=1): + encoding=None, error_handler='strict', autoclose=1, + handle_io_errors=1): """ :Parameters: - `destination`: either a file-like object (which is written @@ -198,6 +202,7 @@ class FileOutput(Output): encoding, error_handler) self.opened = 1 self.autoclose = autoclose + self.handle_io_errors = handle_io_errors if destination is None: if destination_path: self.opened = None @@ -214,6 +219,8 @@ class FileOutput(Output): try: self.destination = open(self.destination_path, 'w') except IOError, error: + if not self.handle_io_errors: + raise print >>sys.stderr, '%s: %s' % (error.__class__.__name__, error) print >>sys.stderr, ('Unable to open destination file for writing ' diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 581c10269..c8af316a2 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -33,10 +33,12 @@ def include(name, arguments, options, content, lineno, path = utils.relative_path(None, path) try: include_file = io.FileInput( - source_path=path, encoding=state.document.settings.input_encoding) + source_path=path, encoding=state.document.settings.input_encoding, + handle_io_errors=None) except IOError, error: severe = state_machine.reporter.severe( - 'Problems with "%s" directive path:\n%s.' % (name, error), + 'Problems with "%s" directive path:\n%s: %s.' + % (name, error.__class__.__name__, error), nodes.literal_block(block_text, block_text), line=lineno) return [severe] include_text = include_file.read() -- cgit v1.2.1 From 0129fd5e094f2edc79ecd30036260ae6cc42264f Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 4 Jul 2003 01:44:41 +0000 Subject: Changed dynamic method definitions (via ``exec``) to dynamic assignments (via ``setattr``); thanks to Roman Suzi. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1564 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index b24f5f9fc..9217c7ef8 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1291,11 +1291,14 @@ class SparseNodeVisitor(NodeVisitor): subclasses), subclass `NodeVisitor` instead. """ - # 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 +def _nop(self, node): + pass + +# Save typing with dynamic assignments: +for _name in node_class_names: + setattr(SparseNodeVisitor, "visit_" + _name, _nop) + setattr(SparseNodeVisitor, "depart_" + _name, _nop) +del _name, _nop class GenericNodeVisitor(NodeVisitor): @@ -1324,13 +1327,17 @@ class GenericNodeVisitor(NodeVisitor): """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 +def _call_default_visit(self, node): + self.default_visit(node) + +def _call_default_departure(self, node): + self.default_departure(node) + +# Save typing with dynamic assignments: +for _name in node_class_names: + setattr(GenericNodeVisitor, "visit_" + _name, _call_default_visit) + setattr(GenericNodeVisitor, "depart_" + _name, _call_default_departure) +del _name, _call_default_visit, _call_default_departure class TreeCopyVisitor(GenericNodeVisitor): -- cgit v1.2.1 From 72a712e6d48c89b143a9da7e48525c657789b58a Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 5 Jul 2003 19:34:37 +0000 Subject: Renamed ``StringList.strip_indent`` to ``.trim_left``. Added ``StringList.get_2D_block``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1568 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/statemachine.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/statemachine.py b/docutils/statemachine.py index 060347ade..c6849d7d5 100644 --- a/docutils/statemachine.py +++ b/docutils/statemachine.py @@ -1295,11 +1295,11 @@ class StringList(ViewList): """A `ViewList` with string-specific methods.""" - def strip_indent(self, length, start=0, end=sys.maxint): + def trim_left(self, length, start=0, end=sys.maxint): """ - Strip `length` characters off the beginning of each item, in-place, + Trim `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. + trimmed text. Does not affect slice parent. """ self.data[start:end] = [line[length:] for line in self.data[start:end]] @@ -1382,9 +1382,20 @@ class StringList(ViewList): 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)) + block.trim_left(indent, start=(first_indent is not None)) return block, indent or 0, blank_finish + def get_2D_block(self, top, left, bottom, right, strip_indent=1): + block = self[top:bottom] + indent = right + for i in range(len(block.data)): + block.data[i] = line = block.data[i][left:right].rstrip() + if line: + indent = min(indent, len(line) - len(line.lstrip())) + if strip_indent and 0 < indent < right: + block.data = [line[indent:] for line in block.data] + return block + class StateMachineError(Exception): pass class UnknownStateError(StateMachineError): pass -- cgit v1.2.1 From 2313cb61ce61101b1d6bf7152b273b78196e4bcc Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 5 Jul 2003 19:38:11 +0000 Subject: updated ``RSTState.nested_parse`` for "include" in table cells, but not sure of correctness git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1569 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index c8d04325f..dce993f89 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -273,8 +273,13 @@ class RSTState(StateWS): node=node, match_titles=match_titles) state_machine.unlink() new_offset = state_machine.abs_line_offset() - # Adjustment for block if modified in nested parse: - self.state_machine.next_line(len(block) - block_length) + try: + # Adjustment for block if modified in nested parse: + self.state_machine.next_line(len(block) - block_length) + except EOFError: + # @@@ This accommodates "include" directives in table cells, + # but I'm not sure it's the correct solution. + pass return new_offset def nested_list_parse(self, block, input_offset, node, initial_state, @@ -1286,8 +1291,8 @@ class Body(RSTState): break if blank: a_lines = indented[blank + 1:] - a_lines.strip_indent(match.end(), end=1) - a_lines.strip_indent(indent, start=1) + a_lines.trim_left(match.end(), end=1) + a_lines.trim_left(indent, start=1) return (indented[:blank], a_lines, line_offset + blank + 1) else: return (indented, None, None) -- cgit v1.2.1 From 8056a097d274a6063ef5028200bd28c732697c1d Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 5 Jul 2003 19:40:57 +0000 Subject: reworked for ``StringList``, to support "include" directives in table cells git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1570 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/tableparser.py | 116 ++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 63 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/tableparser.py b/docutils/parsers/rst/tableparser.py index 35b52e578..0fb674eae 100644 --- a/docutils/parsers/rst/tableparser.py +++ b/docutils/parsers/rst/tableparser.py @@ -131,7 +131,8 @@ class GridTableParser(TableParser): head_body_separator_pat = re.compile(r'\+=[=+]+=\+ *$') def setup(self, block): - self.block = list(block) # make a copy; it may be modified + self.block = block[:] # make a copy; it may be modified + self.block.disconnect() self.bottom = len(block) - 1 self.right = len(block[0]) - 1 self.head_body_sep = None @@ -165,7 +166,8 @@ class GridTableParser(TableParser): 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) + cellblock = self.block.get_2D_block(top + 1, left + 1, + bottom, right) self.cells.append((top, left, bottom, right, cellblock)) corners.extend([(top, right), (bottom, left)]) corners.sort() @@ -188,19 +190,6 @@ class GridTableParser(TableParser): return None return 1 - def get_cell_block(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 = min(margin, len(line) - len(line.lstrip())) - if 0 < margin < right: - cellblock = [line[margin:] for line in cellblock] - return cellblock - def scan_cell(self, top, left): """Starting at the top-left corner, start tracing out a cell.""" assert self.block[top][left] == '+' @@ -278,7 +267,7 @@ class GridTableParser(TableParser): def structure_from_cells(self): """ - From the data colledted by `scan_cell()`, convert to the final data + From the data collected by `scan_cell()`, convert to the final data structure. """ rowseps = self.rowseps.keys() # list of row boundaries @@ -371,7 +360,8 @@ class SimpleTableParser(TableParser): span_pat = re.compile('-[ -]*$') def setup(self, block): - self.block = list(block) # make a copy; it will be modified + self.block = block[:] # make a copy; it will be modified + self.block.disconnect() # Convert top & bottom borders to column span underlines: self.block[0] = self.block[0].replace('=', '-') self.block[-1] = self.block[-1].replace('=', '-') @@ -394,25 +384,26 @@ class SimpleTableParser(TableParser): 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 - # Container for accumulating text lines until a row is complete: - rowlines = [] - while block: - line = block.pop(0) - offset += 1 + offset = 1 # skip top border + start = 1 + text_found = None + while offset < len(self.block): + line = self.block[offset] if self.span_pat.match(line): # Column span underline or border; row is complete. - self.parse_row(rowlines, (line.rstrip(), offset)) - rowlines = [] + self.parse_row(self.block[start:offset], start, + (line.rstrip(), offset)) + start = offset + 1 + text_found = None elif line[firststart:firstend].strip(): # First column not blank, therefore it's a new row. - if rowlines: - self.parse_row(rowlines) - rowlines = [(line.rstrip(), offset)] - else: - # Accumulate lines of incomplete row. - rowlines.append((line.rstrip(), offset)) + if text_found and offset != start: + self.parse_row(self.block[start:offset], start) + start = offset + text_found = 1 + elif not text_found: + start = offset + 1 + offset += 1 def parse_columns(self, line, offset): """ @@ -448,12 +439,12 @@ class SimpleTableParser(TableParser): morecols += 1 except (AssertionError, IndexError): raise TableMarkupError('Column span alignment problem at ' - 'line offset %s.' % offset) - cells.append((0, morecols, offset, [])) + 'line offset %s.' % (offset + 1)) + cells.append([0, morecols, offset, []]) i += 1 return cells - def parse_row(self, lines, spanline=None): + def parse_row(self, lines, start, spanline=None): """ Given the text `lines` of a row, parse it and append to `self.table`. @@ -462,20 +453,29 @@ class SimpleTableParser(TableParser): text from each line, and check for text in column margins. Finally, adjust for insigificant whitespace. """ - while lines and not lines[-1][0]: - lines.pop() # Remove blank trailing lines. - if lines: - offset = lines[0][1] - elif spanline: - offset = spanline[1] - else: + if not (lines or spanline): # No new row, just blank lines. return if spanline: columns = self.parse_columns(*spanline) + span_offset = spanline[1] else: columns = self.columns[:] - row = self.init_row(columns, offset) + span_offset = start + self.check_columns(lines, start, columns) + row = self.init_row(columns, start) + for i in range(len(columns)): + start, end = columns[i] + cellblock = lines.get_2D_block(0, start, len(lines), end) + row[i][3] = cellblock + self.table.append(row) + + def check_columns(self, lines, first_line, columns): + """ + Check for text in column margins and text overflow in the last column. + Raise TableMarkupError if anything but whitespace is in column margins. + Adjust the end value for the last column if there is text overflow. + """ # "Infinite" value for a dummy last column's beginning, used to # check for text overflow: columns.append((sys.maxint, None)) @@ -483,30 +483,20 @@ class SimpleTableParser(TableParser): 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: + offset = 0 + for line 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)) + new_end = start + len(text) + columns[i] = (start, new_end) + main_start, main_end = self.columns[-1] + if new_end > main_end: + self.columns[-1] = (main_start, new_end) 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) + 'offset %s.' % (first_line + offset)) + offset += 1 + columns.pop() def structure_from_cells(self): colspecs = [end - start for start, end in self.columns] -- cgit v1.2.1 From 02f76ed5085bdfdcf025e83117d59fa2f482d284 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 5 Jul 2003 19:43:13 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1572 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 5952ec19e..2aeb1049a 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -324,6 +324,8 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): self.populate_from_components((self,) + tuple(components)) defaults = defaults or {} if read_config_files and not self.defaults['_disable_config']: + # @@@ Extract this code into a method, which can be called from + # the read_config_file callback also. config = ConfigParser() config.read_standard_files(self) config_settings = config.get_section('options') -- cgit v1.2.1 From 58f7621cb2d8e18bfebf255eafc705c5a12c3fae Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 5 Jul 2003 22:38:28 +0000 Subject: fixed table cell line sync problem ("include" directive in cells) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1574 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 7 ++----- docutils/parsers/rst/tableparser.py | 6 ++++-- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index dce993f89..6c759367c 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -273,13 +273,10 @@ class RSTState(StateWS): node=node, match_titles=match_titles) state_machine.unlink() new_offset = state_machine.abs_line_offset() - try: + # No `block.parent` implies disconnected -- lines aren't in sync: + if block.parent: # Adjustment for block if modified in nested parse: self.state_machine.next_line(len(block) - block_length) - except EOFError: - # @@@ This accommodates "include" directives in table cells, - # but I'm not sure it's the correct solution. - pass return new_offset def nested_list_parse(self, block, input_offset, node, initial_state, diff --git a/docutils/parsers/rst/tableparser.py b/docutils/parsers/rst/tableparser.py index 0fb674eae..8529a65b0 100644 --- a/docutils/parsers/rst/tableparser.py +++ b/docutils/parsers/rst/tableparser.py @@ -132,7 +132,7 @@ class GridTableParser(TableParser): def setup(self, block): self.block = block[:] # make a copy; it may be modified - self.block.disconnect() + self.block.disconnect() # don't propagate changes to parent self.bottom = len(block) - 1 self.right = len(block[0]) - 1 self.head_body_sep = None @@ -168,6 +168,7 @@ class GridTableParser(TableParser): self.mark_done(top, left, bottom, right) cellblock = self.block.get_2D_block(top + 1, left + 1, bottom, right) + cellblock.disconnect() # lines in cell can't sync with parent self.cells.append((top, left, bottom, right, cellblock)) corners.extend([(top, right), (bottom, left)]) corners.sort() @@ -361,7 +362,7 @@ class SimpleTableParser(TableParser): def setup(self, block): self.block = block[:] # make a copy; it will be modified - self.block.disconnect() + self.block.disconnect() # don't propagate changes to parent # Convert top & bottom borders to column span underlines: self.block[0] = self.block[0].replace('=', '-') self.block[-1] = self.block[-1].replace('=', '-') @@ -467,6 +468,7 @@ class SimpleTableParser(TableParser): for i in range(len(columns)): start, end = columns[i] cellblock = lines.get_2D_block(0, start, len(lines), end) + cellblock.disconnect() # lines in cell can't sync with parent row[i][3] = cellblock self.table.append(row) -- cgit v1.2.1 From 8c126d1f6afe2e774adb545664ad7c5302e0d5de Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 9 Jul 2003 17:59:37 +0000 Subject: Renamed ``unchanged()`` directive option conversion function to ``unchanged_required``, and added a new ``unchanged``. Updated docstrings. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1577 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 54 ++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 8 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 1a113db2d..c63fee6a0 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -60,7 +60,8 @@ directive function): - ``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. + options to parse. Several directive option conversion functions are defined + in this module. - ``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 @@ -186,6 +187,7 @@ def register_directive(name, directive): def flag(argument): """ Check for a valid flag option (no argument) and return ``None``. + (Directive option conversion function.) Raise ``ValueError`` if an argument is found. """ @@ -194,9 +196,10 @@ def flag(argument): else: return None -def unchanged(argument): +def unchanged_required(argument): """ - Return the argument, unchanged. + Return the argument text, unchanged. + (Directive option conversion function.) Raise ``ValueError`` if no argument is found. """ @@ -205,9 +208,22 @@ def unchanged(argument): else: return argument # unchanged! +def unchanged(argument): + """ + Return the argument text, unchanged. + (Directive option conversion function.) + + No argument implies empty string (""). + """ + if argument is None: + return u'' + else: + return argument # unchanged! + def path(argument): """ Return the path argument unwrapped (with newlines removed). + (Directive option conversion function.) Raise ``ValueError`` if no argument is found or if the path contains internal whitespace. @@ -224,17 +240,44 @@ def path(argument): def nonnegative_int(argument): """ Check for a nonnegative integer argument; raise ``ValueError`` if not. + (Directive option conversion function.) """ value = int(argument) if value < 0: raise ValueError('negative value; must be positive or zero') return value + +def class_option(argument): + """ + Convert the argument into an ID-compatible string and return it. + (Directive option conversion function.) + + Raise ``ValueError`` if no argument is found. + """ + if argument is None: + raise ValueError('argument required but none supplied') + return nodes.make_id(argument) + def format_values(values): return '%s, or "%s"' % (', '.join(['"%s"' % s for s in values[:-1]]), values[-1]) def choice(argument, values): + """ + Directive option utility function, supplied to enable options whose + argument must be a member of a finite set of possible values (must be + lower case). 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')) + + Raise ``ValueError`` if no argument is found or if the argument's value is + not valid (not an entry in the supplied list). + """ try: value = argument.lower().strip() except AttributeError: @@ -245,8 +288,3 @@ def choice(argument, values): else: raise ValueError('"%s" unknown; choose from %s' % (argument, format_values(values))) - -def class_option(argument): - if argument is None: - raise ValueError('argument required but none supplied') - return nodes.make_id(argument) -- cgit v1.2.1 From 5fa4d3b2f10a3fb657a03e04733b4f0a346b6dcc Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 9 Jul 2003 18:00:50 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1578 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/body.py | 2 +- docutils/parsers/rst/directives/misc.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index c2fd6b99d..47e1423c8 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -58,7 +58,7 @@ def sidebar(name, arguments, options, content, lineno, node_class=nodes.sidebar) sidebar.arguments = (1, 0, 1) -sidebar.options = {'subtitle': directives.unchanged, +sidebar.options = {'subtitle': directives.unchanged_required, 'class': directives.class_option} sidebar.content = 1 diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index c8af316a2..8c5ff797d 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -229,5 +229,5 @@ def directive_test_function(name, arguments, options, content, lineno, return [info] directive_test_function.arguments = (0, 1, 1) -directive_test_function.options = {'option': directives.unchanged} +directive_test_function.options = {'option': directives.unchanged_required} directive_test_function.content = 1 -- cgit v1.2.1 From cfa326db4d50cbe1d99887039883a988eb8257d1 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 10 Jul 2003 05:22:18 +0000 Subject: Prevent duplication of "class" attribute values (bug report from Kirill Lapshin). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1579 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index b73a622ad..8df096fbd 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -746,6 +746,8 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_image(self, node): atts = node.attributes.copy() + if atts.has_key('class'): + del atts['class'] # prevent duplication with node attrs atts['src'] = atts['uri'] del atts['uri'] if not atts.has_key('alt'): -- cgit v1.2.1 From 335ac850858ac7eed71df75e491cddeb42da9f7e Mon Sep 17 00:00:00 2001 From: richieadler Date: Fri, 11 Jul 2003 01:30:52 +0000 Subject: Add Esperanto support git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1583 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/eo.py | 63 ++++++++++++++++++++++ docutils/parsers/rst/languages/eo.py | 100 +++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+) create mode 100644 docutils/languages/eo.py create mode 100644 docutils/parsers/rst/languages/eo.py (limited to 'docutils') diff --git a/docutils/languages/eo.py b/docutils/languages/eo.py new file mode 100644 index 000000000..af32aef52 --- /dev/null +++ b/docutils/languages/eo.py @@ -0,0 +1,63 @@ +# Author: Marcelo Huerta San Martin +# Contact: richieadler@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. + +""" +Esperanto-language mappings for language-dependent features of Docutils. +""" + +__docformat__ = 'reStructuredText' + +labels = { + # fixed: language-dependent + 'author': u'A\u016dtoro', + 'authors': u'A\u016dtoroj', + 'organization': u'Organizo', + 'address': u'Adreso', + 'contact': u'Kontakto', + 'version': u'Versio', + 'revision': u'Revido', + 'status': u'Stato', + 'date': u'Dato', + # 'copyright': u'Kopirajto', + 'copyright': u'A\u016dtorrajto', + 'dedication': u'Dedi\u0109o', + 'abstract': u'Resumo', + 'attention': u'Atentu!', + 'caution': u'Zorgu!', + 'danger': u'DAN\u011cERO!', + 'error': u'Eraro', + 'hint': u'Spuro', + 'important': u'Grava', + 'note': u'Noto', + 'tip': u'Helpeto', + 'warning': u'Averto', + 'contents': u'Enhavo'} +"""Mapping of node class name to label text.""" + +bibliographic_fields = { + # language-dependent: fixed + 'a\u016dtoro': 'author', + 'a\u016dtoroj': 'authors', + 'organizo': 'organization', + 'adreso': 'address', + 'kontakto': 'contact', + 'versio': 'version', + 'revido': 'revision', + 'stato': 'status', + 'dato': 'date', + 'a\u016dtorrajto': 'copyright', + 'dedi\u0109o': 'dedication', + 'resumo': 'abstract'} +"""Esperanto (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/eo.py b/docutils/parsers/rst/languages/eo.py new file mode 100644 index 000000000..35c3a6765 --- /dev/null +++ b/docutils/parsers/rst/languages/eo.py @@ -0,0 +1,100 @@ +# Author: Marcelo Huerta San Martin +# Contact: richieadler@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. + +""" +Esperanto-language mappings for language-dependent features of +reStructuredText. +""" + +__docformat__ = 'reStructuredText' + + +directives = { + # language-dependent: fixed + u'atentu': 'attention', + u'zorgu': 'caution', + u'dangxero': 'danger', + u'dan\u011dero': 'danger', + u'eraro': 'error', + u'spuro': 'hint', + u'grava': 'important', + u'noto': 'note', + u'helpeto': 'tip', + u'averto': 'warning', + u'admono': 'admonition', + u'flankteksto': 'sidebar', + u'temo': 'topic', + u'linea-bloko': 'line-block', + u'analizota-literalo': 'parsed-literal', + u'rubriko': 'rubric', + u'epigrafo': 'epigraph', + u'elstarajxoj': 'highlights', + u'elstara\u0135oj': 'highlights', + u'ekstera-citajxo': 'pull-quote', + u'ekstera-cita\u0135o': 'pull-quote', + #'questions': 'questions', + #'qa': 'questions', + #'faq': 'questions', + u'meta': 'meta', + #'imagemap': 'imagemap', + u'bildo': 'image', + u'figuro': 'figure', + u'inkludi': 'include', + u'senformata': 'raw', + u'anstatauxi': 'replace', + u'anstata\u016di': 'replace', + u'unicode': 'unicode', + u'klaso': 'class', + u'enhavo': 'contents', + u'seknum': 'sectnum', + u'sekcia-numerado': 'sectnum', + #'footnotes': 'footnotes', + #'citations': 'citations', + u'celaj-notoj': 'target-notes', + u'restructuredtext-test-directive': 'restructuredtext-test-directive'} +"""Esperanto name to registered (in directives/__init__.py) directive name +mapping.""" + +roles = { + # language-dependent: fixed + u'mallongigo': 'abbreviation', + u'mall': 'abbreviation', + u'komenclitero': 'acronym', + u'kl': 'acronym', + u'indekso': 'index', + u'i': 'index', + u'subskribo': 'subscript', + u'sub': 'subscript', + u'supraskribo': 'superscript', + u'sup': 'superscript', + u'titola-referenco': 'title-reference', + u'titolo': 'title-reference', + u't': 'title-reference', + u'pep-referenco': 'pep-reference', + u'pep': 'pep-reference', + u'rfc-referenco': 'rfc-reference', + u'rfc': 'rfc-reference', + u'emfazo': 'emphasis', + u'forta': 'strong', + u'litera': 'literal', + u'nomita-referenco': 'named-reference', + u'nenomita-referenco': 'anonymous-reference', + u'piednota-referenco': 'footnote-reference', + u'citajxo-referenco': 'citation-reference', + u'cita\u0135o-referenco': 'citation-reference', + u'anstatauxa-referenco': 'substitution-reference', + u'anstata\u016da-referenco': 'substitution-reference', + u'celo': 'target', + u'uri-referenco': 'uri-reference', + u'uri': 'uri-reference', + u'url': 'uri-reference',} +"""Mapping of Esperanto role names to canonical role names for interpreted text. +""" -- cgit v1.2.1 From 180fb329f6e70b36a04e3ae54238964eec9adf44 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 11 Jul 2003 02:05:37 +0000 Subject: Allowed true em-dash character as block quote attribution marker. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1584 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 6c759367c..216ea8da2 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1254,7 +1254,8 @@ class Body(RSTState): blockquote += attribution return blockquote, messages - attribution_pattern = re.compile(r'--(?![-\n]) *(?=[^ \n])') + # u'\u2014' is an em-dash: + attribution_pattern = re.compile(ur'(--|\u2014)(?![-\n]) *(?=[^ \n])') def check_attribution(self, indented, line_offset): """ -- cgit v1.2.1 From a3418f12380f5ca855453fa104445fcb52ed396c Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 12 Jul 2003 18:59:30 +0000 Subject: allow "---" for block quote attributions too git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1588 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 216ea8da2..6666366b6 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1255,7 +1255,7 @@ class Body(RSTState): return blockquote, messages # u'\u2014' is an em-dash: - attribution_pattern = re.compile(ur'(--|\u2014)(?![-\n]) *(?=[^ \n])') + attribution_pattern = re.compile(ur'(---?(?!-)|\u2014) *(?=[^ \n])') def check_attribution(self, indented, line_offset): """ -- cgit v1.2.1 From 1869c1f9c42fb5e9a97b1c24d0c50bf48156083f Mon Sep 17 00:00:00 2001 From: grubert Date: Tue, 15 Jul 2003 16:11:36 +0000 Subject: Fix: no latex tableofcontents was generated if no docinfo item was specified. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1593 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 619d168b7..2e233ae1f 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -532,14 +532,16 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append( '\\end{quote}\n') def visit_bullet_list(self, node): - if not self.use_latex_toc and self.topic_class == 'contents': - self.body.append( '\\begin{list}{}{}\n' ) + if self.topic_class == 'contents': + 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 not self.use_latex_toc and self.topic_class == 'contents': - self.body.append( '\\end{list}\n' ) + if self.topic_class == 'contents': + if not self.use_latex_toc: + self.body.append( '\\end{list}\n' ) else: self.body.append( '\\end{itemize}\n' ) @@ -670,8 +672,6 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body = self.docinfo + self.body # clear docinfo, so field names are no longer appended. self.docinfo = None - if self.use_latex_toc: - self.body.append('\\tableofcontents\n\n\\bigskip\n') def visit_docinfo_item(self, node, name): if not self.latex_docinfo: @@ -1129,10 +1129,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('\n') def depart_paragraph(self, node): - if self.topic_class == 'contents': - self.body.append('\n') - else: - self.body.append('\n') + self.body.append('\n') def visit_problematic(self, node): self.body.append('{\\color{red}\\bfseries{}') @@ -1424,6 +1421,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_topic(self, node): self.topic_class = node.get('class') if self.use_latex_toc: + self.body.append('\\tableofcontents\n\n\\bigskip\n') self.topic_class = '' raise nodes.SkipNode -- cgit v1.2.1 From efde7e0a233b846370c94c1dbd24a7fb144eff64 Mon Sep 17 00:00:00 2001 From: grubert Date: Tue, 15 Jul 2003 20:40:53 +0000 Subject: Donot put colons after terms. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1594 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 2e233ae1f..4e6c65c86 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1318,7 +1318,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_term(self, node): # definition list term. - self.body.append(':]\n') + self.body.append(']\n') def visit_tgroup(self, node): #self.body.append(self.starttag(node, 'colgroup')) -- cgit v1.2.1 From 20f29de2c82a9af27a18170ee88cfe521d4ad7f0 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 29 Jul 2003 03:45:22 +0000 Subject: Improved table grid/border handling (prompted by report from Bob Marshall). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1608 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 8df096fbd..562f8dfe3 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -1061,8 +1061,9 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_table(self, node): self.body.append( - self.starttag(node, 'table', CLASS="table", - frame='border', rules='all')) + # "border=None" is a boolean attribute; + # it means "standard border", not "no border": + self.starttag(node, 'table', CLASS="table", border=None)) def depart_table(self, node): self.body.append('\n') -- cgit v1.2.1 From 5d1d9fa2c05a0f513b5e575a2d768f4d4a594287 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 29 Jul 2003 18:01:38 +0000 Subject: minor XHTML fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1612 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 562f8dfe3..9793ce784 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -79,6 +79,9 @@ class Writer(writers.Writer): relative_path_settings = ('stylesheet_path',) + config_section = 'html4css1 writer' + config_section_predecessors = ('writers',) + output = None """Final translated form of `document`.""" @@ -662,7 +665,7 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_footer(self, node): start = self.context.pop() - footer = (['\n', + footer = (['\n', self.starttag(node, 'div', CLASS='footer')] + self.body[start:] + ['\n']) self.body_suffix[:0] = footer -- cgit v1.2.1 From 132725742c97909ad694f79467969c5f395a603c Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 1 Aug 2003 23:38:38 +0000 Subject: catch unicode value too high error; fixes bug 781766 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1618 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 8c5ff797d..dc4c09269 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -183,9 +183,10 @@ def unicode_directive(name, arguments, options, content, lineno, element += nodes.Text(unichr(int(value, 16))) else: element += nodes.Text(code) - except ValueError, err: + except (ValueError, OverflowError), err: error = state_machine.reporter.error( - 'Invalid character code: %s\n%s' % (code, err), + 'Invalid character code: %s\n%s: %s' + % (code, err.__class__.__name__, err), nodes.literal_block(block_text, block_text), line=lineno) return [error] return element.children -- cgit v1.2.1 From a13d6f62d9bd3d9ac04c40524b06578c37e2f58e Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 8 Aug 2003 15:21:09 +0000 Subject: encoding for comment git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1625 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/es.py | 1 + docutils/parsers/rst/languages/es.py | 1 + 2 files changed, 2 insertions(+) (limited to 'docutils') diff --git a/docutils/languages/es.py b/docutils/languages/es.py index 7505de5da..8a5111429 100644 --- a/docutils/languages/es.py +++ b/docutils/languages/es.py @@ -1,3 +1,4 @@ +# -*- coding: iso-8859-1 -*- # Author: Marcelo Huerta San Martn # Contact: mghsm@uol.com.ar # Revision: $Revision$ diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index 53bb9ff77..abe883741 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -1,3 +1,4 @@ +# -*- coding: iso-8859-1 -*- # Author: Marcelo Huerta San Martn # Contact: mghsm@uol.com.ar # Revision: $Revision$ -- cgit v1.2.1 From 0504917a3757ffc8ce858152d068669c64be010e Mon Sep 17 00:00:00 2001 From: grubert Date: Sat, 16 Aug 2003 19:13:46 +0000 Subject: Add option use-latex-footnotes. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1634 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 4e6c65c86..f2b2ce2a7 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -33,6 +33,10 @@ class Writer(writers.Writer): (('Specify documentclass. Default is "article".', ['--documentclass'], {'default': 'article', }), + ('Use LaTeX footnotes. ' + 'Default: no, uses figures.', + ['--use-latex-footnotes'], + {'default': 0, 'action': 'store_true'}), ('Format for footnote references: one of "superscript" or ' '"brackets". Default is "brackets".', ['--footnote-references'], @@ -262,6 +266,7 @@ class LaTeXTranslator(nodes.NodeVisitor): nodes.NodeVisitor.__init__(self, document) self.settings = settings = document.settings self.use_latex_toc = settings.use_latex_toc + self.use_latex_footnotes = settings.use_latex_footnotes self.hyperlink_color = settings.hyperlink_color if self.hyperlink_color == '0': self.hyperlink_color = 'black' @@ -883,14 +888,28 @@ class LaTeXTranslator(nodes.NodeVisitor): del self.body[start:] def visit_footnote(self, node): - notename = node['id'] - self.body.append('\\begin{figure}[b]') - self.body.append('\\hypertarget{%s}' % notename) + if self.use_latex_footnotes: + num,text = node.astext().split(None,1) + num = self.encode(num.strip()) + self.body.append('\\footnotetext['+num+']') + self.body.append('{'+self.encode(text)+'}') + raise nodes.SkipNode + else: + notename = node['id'] + self.body.append('\\begin{figure}[b]') + self.body.append('\\hypertarget{%s}' % notename) def depart_footnote(self, node): - self.body.append('\\end{figure}\n') + if self.use_latex_footnotes: + self.body.append('}') + else: + self.body.append('\\end{figure}\n') def visit_footnote_reference(self, node): + if self.use_latex_footnotes: + self.body.append("\\footnotemark["+self.encode(node.astext())+"]") + raise nodes.SkipNode + return href = '' if node.has_key('refid'): href = node['refid'] @@ -908,6 +927,8 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('%s\\hyperlink{%s}{' % (suffix,href)) def depart_footnote_reference(self, node): + if self.use_latex_footnotes: + return self.body.append('}%s' % self.context.pop()) def visit_generated(self, node): -- cgit v1.2.1 From 5745f8c2b09962cf2fb76bfc8b41af263363664c Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 27 Aug 2003 20:42:29 +0000 Subject: Bumped version to 0.3.1: Reorganized config file format (multiple sections); see docs/config.txt. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1641 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index 188a3a711..45ec3b2b0 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -12,12 +12,14 @@ Package Structure Modules: -- __init__.py: Contains the package docstring only (this text). +- __init__.py: Contains component base classes, exception classes, and + Docutils `__version__`. -- core.py: Contains the ``Publisher`` class and ``publish()`` convenience - function. +- core.py: Contains the ``Publisher`` class and ``publish_*()`` convenience + functions. -- frontend.py: Command-line and common processing for Docutils front-ends. +- frontend.py: Runtime settings (command-line interface, configuration files) + processing, for Docutils front-ends. - io.py: Provides a uniform API for low-level input and output. @@ -49,12 +51,12 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.3.0' +__version__ = '0.3.1' """``major.minor.micro`` version number. The micro number is bumped any time -there's a change in the API incompatible with one of the front ends. The -minor number is bumped whenever there is a 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.""" +there's a change in the API incompatible with one of the front ends or +significant new functionality. The minor number is bumped whenever there is a +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.""" class ApplicationError(StandardError): pass @@ -91,10 +93,20 @@ class SettingsSpec: relative_path_settings = () """Settings containing filesystem paths. Override in subclasses. - Settings listed here are to be interpreted relative to the current working directory.""" + config_section = None + """The name of the config file section specific to this component + (lowercase, no brackets). Override in subclasses.""" + + config_section_dependencies = None + """A list of names of config file sections that are to be applied before + `config_section`, in order (from general to specific). In other words, + the settings in `config_section` are to be overlaid on top of the settings + from these sections. The "general" section is assumed implicitly. + Override in subclasses.""" + class TransformSpec: -- cgit v1.2.1 From c0230af3f9a5e317c5d3f47e3187d305b87a2df0 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 27 Aug 2003 20:42:53 +0000 Subject: Reordered components for OptionParser; application comes last. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1642 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index 6d78ac57f..1049748e1 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -86,7 +86,7 @@ class Publisher: 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), + components=(self.parser, self.reader, self.writer, settings_spec), defaults=defaults, read_config_files=1, usage=usage, description=description) return option_parser @@ -94,8 +94,7 @@ class Publisher: def get_settings(self, usage=None, description=None, settings_spec=None, **defaults): """ - Set and return default settings (overrides in `defaults` keyword - argument). + Set and return default settings (overrides in `defaults` dict). Set components first (`self.set_reader` & `self.set_writer`). Explicitly setting `self.settings` disables command line option -- cgit v1.2.1 From d814bdb1076cb781bf9c3b0688ba9e7a6397cb03 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 27 Aug 2003 20:43:24 +0000 Subject: Implemented support for config file reorganization: ``standard_config_files`` moved from ``ConfigParser`` to ``OptionParser``; added ``OptionParser.get_config_file_settings()`` and ``.get_standard_config_settings()``; support for old "[options]" section (with deprecation warning) and mapping from old to new settings. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1643 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 96 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 75 insertions(+), 21 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 2aeb1049a..c1d10fe0c 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -21,6 +21,7 @@ import os import os.path import sys import types +import warnings import ConfigParser as CP import codecs import docutils @@ -44,11 +45,7 @@ def read_config_file(option, opt, value, parser): """ Read a configuration file during option processing. (Option callback.) """ - config_parser = ConfigParser() - config_parser.read(value, parser) - settings = config_parser.get_section('options') - make_paths_absolute(settings, parser.relative_path_settings, - os.path.dirname(value)) + settings = parser.get_config_file_settings(value) parser.values.__dict__.update(settings) def set_encoding(option, opt, value, parser): @@ -151,6 +148,13 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): are restrict to using long options. """ + standard_config_files = [ + '/etc/docutils.conf', # system-wide + './docutils.conf', # project-specific + os.path.expanduser('~/.docutils')] # user-specific + """Docutils configuration files, using ConfigParser syntax. + Later files override earlier ones.""" + threshold_choices = 'info 1 warning 2 error 3 severe 4 none 5'.split() """Possible inputs for for --report and --halt threshold values.""" @@ -303,6 +307,8 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): relative_path_settings = ('warning_stream',) + config_section = 'general' + version_template = '%%prog (Docutils %s)' % docutils.__version__ """Default version message.""" @@ -321,15 +327,11 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): self.version = self.version_template # Make an instance copy (it will be modified): self.relative_path_settings = list(self.relative_path_settings) - self.populate_from_components((self,) + tuple(components)) + self.components = (self,) + tuple(components) + self.populate_from_components(self.components) defaults = defaults or {} if read_config_files and not self.defaults['_disable_config']: - # @@@ Extract this code into a method, which can be called from - # the read_config_file callback also. - config = ConfigParser() - config.read_standard_files(self) - config_settings = config.get_section('options') - make_paths_absolute(config_settings, self.relative_path_settings) + config_settings = self.get_standard_config_settings() defaults.update(config_settings) # Internal settings with no defaults from settings specifications; # initialize manually: @@ -366,6 +368,31 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): if component and component.settings_default_overrides: self.defaults.update(component.settings_default_overrides) + def get_standard_config_settings(self): + settings = {} + for filename in self.standard_config_files: + settings.update(self.get_config_file_settings(filename)) + return settings + + def get_config_file_settings(self, config_file): + parser = ConfigParser() + parser.read(config_file, self) + base_path = os.path.dirname(config_file) + applied = {} + settings = {} + for component in self.components: + if not component: + continue + for section in (tuple(component.config_section_dependencies or ()) + + (component.config_section,)): + if applied.has_key(section): + continue + applied[section] = 1 + settings.update(parser.get_section(section)) + make_paths_absolute( + settings, self.relative_path_settings, base_path) + return settings + def check_values(self, values, args): if hasattr(values, 'report_level'): values.report_level = self.check_threshold(values.report_level) @@ -407,13 +434,6 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): 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.""" - validation = { 'options': {'input_encoding': validate_encoding, @@ -425,16 +445,46 @@ class ConfigParser(CP.ConfigParser): `validate_options`. Validation functions take two parameters: name and value. They return a (possibly modified) value, or raise an exception.""" - def read_standard_files(self, option_parser): - self.read(self.standard_config_files, option_parser) + old_settings = { + 'pep_stylesheet': ('pep_html writer', 'stylesheet'), + 'pep_stylesheet_path': ('pep_html writer', 'stylesheet_path'), + 'pep_template': ('pep_html writer', 'template')} + """{old setting: (new section, new setting)} mapping, used by + `handle_old_config`, to convert settings from the old [options] section.""" + + old_warning = """ +The "[option]" section is deprecated. Support for old-format configuration +files will be removed in a future Docutils release. Please revise your +configuration files. See . +""" def read(self, filenames, option_parser): if type(filenames) in types.StringTypes: filenames = [filenames] for filename in filenames: CP.ConfigParser.read(self, filename) + if self.has_section('options'): + self.handle_old_config(filename) self.validate_options(filename, option_parser) + def handle_old_config(self, filename): + warnings.warn_explicit(self.old_warning, ConfigDeprecationWarning, + filename, 0) + options = self.get_section('options') + if not self.has_section('general'): + self.add_section('general') + for key, value in options.items(): + if self.old_settings.has_key(key): + section, setting = self.old_settings[key] + if not self.has_section(section): + self.add_section(section) + else: + section = 'general' + setting = key + if not self.has_option(section, setting): + self.set(section, setting, value) + self.remove_section('options') + def validate_options(self, filename, option_parser): for section in self.validation.keys(): if not self.has_section(section): @@ -477,3 +527,7 @@ class ConfigParser(CP.ConfigParser): for option in self.options(section): section_dict[option] = self.get(section, option, raw, vars) return section_dict + + +class ConfigDeprecationWarning(DeprecationWarning): + """Warning for deprecated configuration file features.""" -- cgit v1.2.1 From ffa71e84747057982955e2bad3de2f8d3ed97c69 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 27 Aug 2003 20:50:43 +0000 Subject: Updated for configuration file reorganization. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1645 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/__init__.py | 1 + docutils/parsers/rst/__init__.py | 3 +++ docutils/readers/__init__.py | 1 + docutils/readers/pep.py | 3 +++ docutils/readers/python/__init__.py | 4 +++- docutils/readers/standalone.py | 3 +++ docutils/writers/__init__.py | 1 + docutils/writers/docutils_xml.py | 3 +++ docutils/writers/html4css1.py | 2 +- docutils/writers/latex2e.py | 13 +++++++------ docutils/writers/pep_html.py | 28 +++++++++++----------------- docutils/writers/pseudoxml.py | 3 +++ 12 files changed, 40 insertions(+), 25 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/__init__.py b/docutils/parsers/__init__.py index 5b1e964be..027c25a86 100644 --- a/docutils/parsers/__init__.py +++ b/docutils/parsers/__init__.py @@ -16,6 +16,7 @@ from docutils import Component class Parser(Component): component_type = 'parser' + config_section = 'parsers' def parse(self, inputstring, document): """Override to parse `inputstring` into document tree `document`.""" diff --git a/docutils/parsers/rst/__init__.py b/docutils/parsers/rst/__init__.py index 899a49bc8..0b46ad9e8 100644 --- a/docutils/parsers/rst/__init__.py +++ b/docutils/parsers/rst/__init__.py @@ -100,6 +100,9 @@ class Parser(docutils.parsers.Parser): ['--trim-footnote-reference-space'], {'action': 'store_true'}),)) + config_section = 'restructuredtext parser' + config_section_dependencies = ('parsers',) + def __init__(self, rfc2822=None, inliner=None): if rfc2822: self.initial_state = 'RFC2822Body' diff --git a/docutils/readers/__init__.py b/docutils/readers/__init__.py index f12401ff0..3ff069a28 100644 --- a/docutils/readers/__init__.py +++ b/docutils/readers/__init__.py @@ -28,6 +28,7 @@ class Reader(Component): """ component_type = 'reader' + config_section = 'readers' def __init__(self, parser=None, parser_name='restructuredtext'): """ diff --git a/docutils/readers/pep.py b/docutils/readers/pep.py index e21d8f213..f65fd2662 100644 --- a/docutils/readers/pep.py +++ b/docutils/readers/pep.py @@ -36,6 +36,9 @@ class Reader(standalone.Reader): 'reStructuredText parser) are on by default.', ()) + config_section = 'pep reader' + config_section_dependencies = ('readers', 'standalone reader') + default_transforms = (references.Substitutions, peps.Headers, peps.Contents, diff --git a/docutils/readers/python/__init__.py b/docutils/readers/python/__init__.py index a346ce32a..5bc832183 100644 --- a/docutils/readers/python/__init__.py +++ b/docutils/readers/python/__init__.py @@ -16,4 +16,6 @@ import docutils.readers class Reader(docutils.readers.Reader): - pass + + config_section = 'python reader' + config_section_dependencies = ('readers',) diff --git a/docutils/readers/standalone.py b/docutils/readers/standalone.py index 14b75e3d7..43ca4c40b 100644 --- a/docutils/readers/standalone.py +++ b/docutils/readers/standalone.py @@ -38,6 +38,9 @@ class Reader(readers.Reader): ['--no-doc-info'], {'dest': 'docinfo_xform', 'action': 'store_false', 'default': 1}),)) + config_section = 'standalone reader' + config_section_dependencies = ('readers',) + default_transforms = (references.Substitutions, frontmatter.DocTitle, frontmatter.DocInfo, diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index d8183dc37..7b37aa8a8 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -30,6 +30,7 @@ class Writer(Component): """ component_type = 'writer' + config_section = 'writers' document = None """The document to write.""" diff --git a/docutils/writers/docutils_xml.py b/docutils/writers/docutils_xml.py index 4ecbfb6c2..0eaa4ed3c 100644 --- a/docutils/writers/docutils_xml.py +++ b/docutils/writers/docutils_xml.py @@ -35,6 +35,9 @@ class Writer(writers.Writer): ['--no-doctype'], {'dest': 'doctype_declaration', 'default': 1, 'action': 'store_false'}),)) + config_section = 'docutils_xml writer' + config_section_dependencies = ('writers',) + output = None """Final translated form of `document`.""" diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 9793ce784..5bc33d5ea 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -80,7 +80,7 @@ class Writer(writers.Writer): relative_path_settings = ('stylesheet_path',) config_section = 'html4css1 writer' - config_section_predecessors = ('writers',) + config_section_dependencies = ('writers',) output = None """Final translated form of `document`.""" diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index f2b2ce2a7..8d14dbef7 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -47,15 +47,13 @@ class Writer(writers.Writer): ['--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 "style.tex". ' - 'If this is set to "" disables input.' - 'Overridden by --stylesheet-path.', + ('Specify a stylesheet file. The file will be "input" by latex in ' + 'the document header. Default is "style.tex". If this is set to ' + '"" disables input. Overridden by --stylesheet-path.', ['--stylesheet'], {'default': 'style.tex', 'metavar': ''}), ('Specify a stylesheet file, relative to the current working ' - 'directory.' - 'Overrides --stylesheet.', + 'directory. Overrides --stylesheet.', ['--stylesheet-path'], {'metavar': ''}), ('Link to the stylesheet in the output LaTeX file. This is the ' @@ -77,6 +75,9 @@ class Writer(writers.Writer): settings_defaults = {'output_encoding': 'latin-1'} + config_section = 'latex2e writer' + config_section_dependencies = ('writers',) + output = None """Final translated form of `document`.""" diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index 85c065c3d..be50e98ed 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -21,20 +21,10 @@ class Writer(html4css1.Writer): settings_spec = html4css1.Writer.settings_spec + ( 'PEP/HTML-Specific Options', - 'The HTML --footnote-references option is set to "brackets" by ' - 'default.', - (('Specify a PEP stylesheet URL, used verbatim. Default is ' - '--stylesheet\'s value. If given, --pep-stylesheet overrides ' - '--stylesheet.', - ['--pep-stylesheet'], - {'metavar': ''}), - ('Specify a PEP stylesheet file, relative to the current working ' - 'directory. The path is adjusted relative to the output HTML ' - 'file. Overrides --pep-stylesheet and --stylesheet-path.', - ['--pep-stylesheet-path'], - {'metavar': ''}), - ('Specify a template file. Default is "pep-html-template".', - ['--pep-template'], + """The HTML --footnote-references option's default is set to """ + '"brackets".', + (('Specify a template file. Default is "pep-html-template".', + ['--template'], {'default': 'pep-html-template', 'metavar': ''}), ('Python\'s home URL. Default is ".." (parent directory).', ['--python-home'], @@ -49,7 +39,11 @@ class Writer(html4css1.Writer): settings_default_overrides = {'footnote_references': 'brackets'} - relative_path_settings = ('pep_stylesheet_path', 'pep_template') + 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) @@ -58,7 +52,7 @@ class Writer(html4css1.Writer): def translate(self): html4css1.Writer.translate(self) settings = self.document.settings - template = open(settings.pep_template).read() + template = open(settings.template).read() # Substitutions dict for template: subs = {} subs['encoding'] = settings.output_encoding @@ -102,7 +96,7 @@ class HTMLTranslator(html4css1.HTMLTranslator): settings.pep_stylesheet_path) elif settings.pep_stylesheet: return settings.pep_stylesheet - elif settings._stylesheet_path: + elif settings.stylesheet_path: return utils.relative_path(relative_to, settings.stylesheet_path) else: return settings.stylesheet diff --git a/docutils/writers/pseudoxml.py b/docutils/writers/pseudoxml.py index 02dde58f3..c0e18bffb 100644 --- a/docutils/writers/pseudoxml.py +++ b/docutils/writers/pseudoxml.py @@ -19,6 +19,9 @@ class Writer(writers.Writer): supported = ('pprint', 'pformat', 'pseudoxml') """Formats this writer supports.""" + config_section = 'pseudoxml writer' + config_section_dependencies = ('writers',) + output = None """Final translated form of `document`.""" -- cgit v1.2.1 From 8109d33588c37eb4c8da451dbf579adacc57c384 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 27 Aug 2003 22:19:39 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1651 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/pep_html.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index be50e98ed..5fa14309b 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -91,12 +91,7 @@ class HTMLTranslator(html4css1.HTMLTranslator): settings = self.settings if relative_to == None: relative_to = settings._destination - if settings.pep_stylesheet_path: - return utils.relative_path(relative_to, - settings.pep_stylesheet_path) - elif settings.pep_stylesheet: - return settings.pep_stylesheet - elif settings.stylesheet_path: + if settings.stylesheet_path: return utils.relative_path(relative_to, settings.stylesheet_path) else: return settings.stylesheet -- cgit v1.2.1 From 4771aa9c9dc9dcdc4ba14125e3137f4cb8e5de03 Mon Sep 17 00:00:00 2001 From: grubert Date: Fri, 29 Aug 2003 15:45:18 +0000 Subject: LaTeX writer no longer has a default stylesheet. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1655 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 8d14dbef7..26b2bcca8 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -48,10 +48,10 @@ class Writer(writers.Writer): {'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 "style.tex". If this is set to ' + 'the document header. Default is "no stylesheet". If this is set to ' '"" disables input. Overridden by --stylesheet-path.', ['--stylesheet'], - {'default': 'style.tex', 'metavar': ''}), + {'default': '', 'metavar': ''}), ('Specify a stylesheet file, relative to the current working ' 'directory. Overrides --stylesheet.', ['--stylesheet-path'], -- cgit v1.2.1 From 55abea8d367801213b71637cd105e94a7efa21cd Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 1 Sep 2003 15:02:17 +0000 Subject: Reimplemented setting validation. Enabled flexible boolean values: yes/no, true/false, on/off. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1658 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 330 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 204 insertions(+), 126 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index c1d10fe0c..091992bde 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -9,10 +9,21 @@ Command-line and common processing for Docutils front-end tools. Exports the following classes: -- `OptionParser`: Standard Docutils command-line processing. -- `Values`: Runtime settings; objects are simple structs +* `OptionParser`: Standard Docutils command-line processing. +* `Option`: Customized version of `optparse.Option`; validation support. +* `Values`: Runtime settings; objects are simple structs (``object.attribute``). -- `ConfigParser`: Standard Docutils config file processing. +* `ConfigParser`: Standard Docutils config file processing. +* `DictUpdater`: Supports cumulative list settings (dict values). + +Also exports the following functions: + +* Option callbacks: `store_multiple`, `read_config_file`. +* Setting validators (see `OptionParser.validators`: `validate_encoding`, + `validate_encoding_error_handler`, `validate_encoding_and_error_handler`, + `validate_boolean`, `validate_threshold`, + `validate_colon_separated_string_list`. +* `make_paths_absolute`. """ __docformat__ = 'reStructuredText' @@ -21,6 +32,7 @@ import os import os.path import sys import types +import copy import warnings import ConfigParser as CP import codecs @@ -45,40 +57,26 @@ def read_config_file(option, opt, value, parser): """ Read a configuration file during option processing. (Option callback.) """ - settings = parser.get_config_file_settings(value) - parser.values.__dict__.update(settings) - -def set_encoding(option, opt, value, parser): - """ - Validate & set the encoding specified. (Option callback.) - """ try: - value = validate_encoding(option.dest, value) - except LookupError, error: - raise (optparse.OptionValueError('option "%s": %s' % (opt, error)), - None, sys.exc_info()[2]) - setattr(parser.values, option.dest, value) - -def validate_encoding(name, value): + new_settings = parser.get_config_file_settings(value) + except ValueError, error: + parser.error(error) + settings = DictUpdater(parser, parser.values.__dict__) + settings.update(new_settings) + parser.values._update_loose(settings.data) + +def validate_encoding(setting, value, option_parser, + config_parser=None, config_section=None): try: codecs.lookup(value) except LookupError: - raise (LookupError('unknown encoding: "%s"' % value), + raise (LookupError('setting "%s": unknown encoding: "%s"' + % (setting, value)), None, sys.exc_info()[2]) return value -def set_encoding_error_handler(option, opt, value, parser): - """ - Validate & set the encoding error handler specified. (Option callback.) - """ - try: - value = validate_encoding_error_handler(option.dest, value) - except LookupError, error: - raise (optparse.OptionValueError('option "%s": %s' % (opt, error)), - None, sys.exc_info()[2]) - setattr(parser.values, option.dest, value) - -def validate_encoding_error_handler(name, value): +def validate_encoding_error_handler(setting, value, option_parser, + config_parser=None, config_section=None): try: codecs.lookup_error(value) except AttributeError: # prior to Python 2.3 @@ -96,29 +94,57 @@ def validate_encoding_error_handler(name, value): None, sys.exc_info()[2]) return value -def set_encoding_and_error_handler(option, opt, value, parser): +def validate_encoding_and_error_handler( + setting, value, option_parser, config_parser=None, config_section=None): """ - Validate & set the encoding and error handler specified. (Option callback.) + Side-effect: if an error handler is included in the value, it is inserted + into the appropriate place as if it was a separate setting/option. """ - try: - value = validate_encoding_and_error_handler(option.dest, value) - except LookupError, error: - raise (optparse.OptionValueError('option "%s": %s' % (opt, error)), - None, sys.exc_info()[2]) if ':' in value: encoding, handler = value.split(':') - setattr(parser.values, option.dest + '_error_handler', handler) + validate_encoding_error_handler( + setting + '_error_handler', handler, option_parser, + config_parser, config_section) + if config_parser: + config_parser.set(config_section, setting + '_error_handler', + handler) + else: + setattr(option_parser.values, setting + '_error_handler', handler) else: encoding = value - setattr(parser.values, option.dest, encoding) + validate_encoding(setting, encoding, option_parser, + config_parser, config_section) + return encoding -def validate_encoding_and_error_handler(name, value): - if ':' in value: - encoding, handler = value.split(':') - validate_encoding_error_handler(name + '_error_handler', handler) +def validate_boolean(setting, value, option_parser, + config_parser=None, config_section=None): + if isinstance(value, types.StringType): + try: + return option_parser.booleans[value.strip().lower()] + except KeyError: + raise (LookupError('unknown boolean value: "%s"' % value), + None, sys.exc_info()[2]) + return value + +def validate_threshold(setting, value, option_parser, + config_parser=None, config_section=None): + try: + int(value) + return value + except ValueError: + try: + return option_parser.thresholds[value.lower()] + except (KeyError, AttributeError): + raise (LookupError('unknown threshold: %r.' % value), + None, sys.exc_info[2]) + +def validate_colon_separated_string_list( + setting, value, option_parser, config_parser=None, config_section=None): + if isinstance(value, types.StringType): + value = value.split(':') else: - encoding = value - validate_encoding(name, encoding) + last = value.pop() + value.extend(last.split(':')) return value def make_paths_absolute(pathdict, keys, base_path=None): @@ -131,9 +157,41 @@ def make_paths_absolute(pathdict, keys, base_path=None): if base_path is None: base_path = os.getcwd() for key in keys: - if pathdict.has_key(key) and pathdict[key]: - pathdict[key] = os.path.normpath( - os.path.abspath(os.path.join(base_path, pathdict[key]))) + if pathdict.has_key(key): + value = pathdict[key] + if isinstance(value, types.ListType): + value = [make_one_path_absolute(base_path, path) + for path in value] + elif value: + value = make_one_path_absolute(base_path, value) + pathdict[key] = value + +def make_one_path_absolute(base_path, path): + return os.path.abspath(os.path.join(base_path, path)) + + +class Option(optparse.Option): + + def process(self, opt, value, values, parser): + """ + Call the validator function on applicable settings. + Extends `optparse.Option.process`. + """ + result = optparse.Option.process(self, opt, value, values, parser) + setting = self.dest + if setting: + value = getattr(values, setting) + validator = parser.validators.get(setting) + if validator: + try: + new_value = validator(setting, value, parser) + except Exception, error: + raise (optparse.OptionValueError( + 'Error in option "%s":\n %s: %s' + % (opt, error.__class__.__name__, error)), + None, sys.exc_info()[2]) + setattr(values, setting, new_value) + return result class OptionParser(optparse.OptionParser, docutils.SettingsSpec): @@ -161,6 +219,10 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): thresholds = {'info': 1, 'warning': 2, 'error': 3, 'severe': 4, 'none': 5} """Lookup table for --report and --halt threshold values.""" + booleans={'1': 1, 'on': 1, 'yes': 1, 'true': 1, + '0': 0, 'off': 0, 'no': 0, 'false': 0, '': 0} + """Lookup table for boolean configuration file settings.""" + if hasattr(codecs, 'backslashreplace_errors'): default_error_encoding_error_handler = 'backslashreplace' else: @@ -171,7 +233,8 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): None, (('Include a "Generated by Docutils" credit and link at the end ' 'of the document.', - ['--generator', '-g'], {'action': 'store_true'}), + ['--generator', '-g'], {'action': 'store_true', + 'validator': validate_boolean}), ('Do not include a generator credit.', ['--no-generator'], {'action': 'store_false', 'dest': 'generator'}), ('Include the date at the end of the document (UTC).', @@ -185,7 +248,8 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): ['--no-datestamp'], {'action': 'store_const', 'const': None, 'dest': 'datestamp'}), ('Include a "View document source" link (relative to destination).', - ['--source-link', '-s'], {'action': 'store_true'}), + ['--source-link', '-s'], {'action': 'store_true', + 'validator': validate_boolean}), ('Use the supplied verbatim for a "View document source" ' 'link; implies --source-link.', ['--source-url'], {'metavar': ''}), @@ -208,7 +272,8 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): ('Enable backlinks from footnotes and citations to their ' 'references. This is the default.', ['--footnote-backlinks'], - {'action': 'store_true', 'default': 1}), + {'action': 'store_true', 'default': 1, + 'validator': validate_boolean}), ('Disable backlinks from footnotes and citations.', ['--no-footnote-backlinks'], {'dest': 'footnote_backlinks', 'action': 'store_false'}), @@ -216,7 +281,8 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): ' (by name or number: "info" or "1", warning/2, error/3, ' 'severe/4; also, "none" or "5"). Default is 2 (warning).', ['--report', '-r'], {'choices': threshold_choices, 'default': 2, - 'dest': 'report_level', 'metavar': ''}), + 'dest': 'report_level', 'metavar': '', + 'validator': validate_threshold}), ('Report all system messages, info-level and higher. (Same as ' '"--report=info".)', ['--verbose', '-v'], {'action': 'store_const', 'const': 'info', @@ -228,7 +294,8 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): 'converted to exceptions, halting execution immediately. Levels ' 'as in --report. Default is 4 (severe).', ['--halt'], {'choices': threshold_choices, 'dest': 'halt_level', - 'default': 4, 'metavar': ''}), + 'default': 4, 'metavar': '', + 'validator': validate_threshold}), ('Same as "--halt=info": halt processing at the slightest problem.', ['--strict'], {'action': 'store_const', 'const': 'info', 'dest': 'halt_level'}), @@ -237,49 +304,45 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): 'in --report. Default is 5 (disabled). Exit status is the maximum ' 'system message level plus 10 (11 for INFO, etc.).', ['--exit'], {'choices': threshold_choices, 'dest': 'exit_level', - 'default': 5, 'metavar': ''}), + 'default': 5, 'metavar': '', + 'validator': validate_threshold}), ('Report debug-level system messages and generate diagnostic output.', - ['--debug'], {'action': 'store_true'}), + ['--debug'], {'action': 'store_true', 'validator': validate_boolean}), ('Do not report debug-level system messages or generate diagnostic ' 'output.', ['--no-debug'], {'action': 'store_false', 'dest': 'debug'}), ('Send the output of system messages (warnings) to .', ['--warnings'], {'dest': 'warning_stream', 'metavar': ''}), ('Enable Python tracebacks when an error occurs.', - ['--traceback'], {'action': 'store_true', 'default': None}), + ['--traceback'], {'action': 'store_true', 'default': None, + 'validator': validate_boolean}), ('Disable Python tracebacks when errors occur; report just the error ' 'instead. This is the default.', ['--no-traceback'], {'dest': 'traceback', 'action': 'store_false'}), ('Specify the encoding of input text. Default is locale-dependent.', ['--input-encoding', '-i'], - {'action': 'callback', 'callback': set_encoding, - 'metavar': '', 'type': 'string', 'dest': 'input_encoding'}), + {'metavar': '', 'validator': validate_encoding}), ('Specify the text encoding for output. Default is UTF-8. ' 'Optionally also specify the encoding error handler for unencodable ' 'characters (see "--error-encoding"); default is "strict".', ['--output-encoding', '-o'], - {'action': 'callback', 'callback': set_encoding_and_error_handler, - 'metavar': '', 'type': 'string', - 'dest': 'output_encoding', 'default': 'utf-8'}), + {'metavar': '', 'default': 'utf-8', + 'validator': validate_encoding_and_error_handler}), (SUPPRESS_HELP, # usually handled by --output-encoding ['--output_encoding_error_handler'], - {'action': 'callback', 'callback': set_encoding_error_handler, - 'type': 'string', 'dest': 'output_encoding_error_handler', - 'default': 'strict'}), + {'default': 'strict', 'validator': validate_encoding_error_handler}), ('Specify the text encoding for error output. Default is ASCII. ' 'Optionally also specify the encoding error handler for unencodable ' 'characters, after a colon (":"). Acceptable values are the same ' 'as for the "error" parameter of Python\'s ``encode`` string ' 'method. Default is "%s".' % default_error_encoding_error_handler, ['--error-encoding', '-e'], - {'action': 'callback', 'callback': set_encoding_and_error_handler, - 'metavar': '', 'type': 'string', - 'dest': 'error_encoding', 'default': 'ascii'}), + {'metavar': '', 'default': 'ascii', + 'validator': validate_encoding_and_error_handler}), (SUPPRESS_HELP, # usually handled by --error-encoding ['--error_encoding_error_handler'], - {'action': 'callback', 'callback': set_encoding_error_handler, - 'type': 'string', 'dest': 'error_encoding_error_handler', - 'default': default_error_encoding_error_handler}), + {'default': default_error_encoding_error_handler, + 'validator': validate_encoding_error_handler}), ('Specify the language of input text (ISO 639 2-letter identifier).' ' Default is "en" (English).', ['--language', '-l'], {'dest': 'language_code', 'default': 'en', @@ -297,7 +360,8 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): (SUPPRESS_HELP, ['--dump-transforms'], {'action': 'store_true'}), (SUPPRESS_HELP, ['--dump-pseudo-xml'], {'action': 'store_true'}), (SUPPRESS_HELP, ['--expose-internal-attribute'], - {'action': 'append', 'dest': 'expose_internals'}),)) + {'action': 'append', 'dest': 'expose_internals', + 'validator': validate_colon_separated_string_list}),)) """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()`).""" @@ -319,8 +383,20 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): ``.settings_spec`` attribute. `defaults` is a mapping of setting default overrides. """ + self.validators = {} + """{setting: validation function} mapping, used by `validate_options`. + Validation functions take three or five parameters: setting name, + value, an `OptionParser` (``self``), and a `ConfigParser` and config + file section if activated from a config file. They return a (possibly + modified) value, or raise an exception. Populated from the "validator" + keyword argument dictionary entries of components' ``settings_spec`` + attribute.""" + + self.lists = {} + """Set of list-type settings.""" + optparse.OptionParser.__init__( - self, add_help_option=None, + self, option_class=Option, add_help_option=None, formatter=optparse.TitledHelpFormatter(width=78), *args, **kwargs) if not self.version: @@ -331,7 +407,10 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): self.populate_from_components(self.components) defaults = defaults or {} if read_config_files and not self.defaults['_disable_config']: - config_settings = self.get_standard_config_settings() + try: + config_settings = self.get_standard_config_settings() + except ValueError, error: + self.error(error) defaults.update(config_settings) # Internal settings with no defaults from settings specifications; # initialize manually: @@ -359,8 +438,18 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): else: group = self # single options for (help_text, option_strings, kwargs) in option_spec: - group.add_option(help=help_text, *option_strings, - **kwargs) + kwargs = kwargs.copy() # to be modified, locally only + if kwargs.has_key('validator'): + validator = kwargs['validator'] + del kwargs['validator'] + else: + validator = None + option = group.add_option(help=help_text, *option_strings, + **kwargs) + if validator: + self.validators[option.dest] = validator + if kwargs.get('action') == 'append': + self.lists[option.dest] = 1 if component.settings_defaults: self.defaults.update(component.settings_defaults) i += 3 @@ -379,7 +468,7 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): parser.read(config_file, self) base_path = os.path.dirname(config_file) applied = {} - settings = {} + settings = DictUpdater(self) for component in self.components: if not component: continue @@ -390,30 +479,16 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): applied[section] = 1 settings.update(parser.get_section(section)) make_paths_absolute( - settings, self.relative_path_settings, base_path) - return settings + settings.data, self.relative_path_settings, base_path) + return settings.data def check_values(self, values, 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) - if hasattr(values, 'exit_level'): - values.exit_level = self.check_threshold(values.exit_level) + """Store positional arguments as runtime settings.""" values._source, values._destination = self.check_args(args) make_paths_absolute(values.__dict__, self.relative_path_settings, os.getcwd()) return values - 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: @@ -434,17 +509,6 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): class ConfigParser(CP.ConfigParser): - validation = { - 'options': - {'input_encoding': validate_encoding, - 'output_encoding': validate_encoding, - 'output_encoding_error_handler': validate_encoding_error_handler, - 'error_encoding': validate_encoding, - 'error_encoding_error_handler': validate_encoding_error_handler}} - """{section: {option: validation function}} mapping, used by - `validate_options`. Validation functions take two parameters: name and - value. They return a (possibly modified) value, or raise an exception.""" - old_settings = { 'pep_stylesheet': ('pep_html writer', 'stylesheet'), 'pep_stylesheet_path': ('pep_html writer', 'stylesheet_path'), @@ -465,7 +529,7 @@ configuration files. See . CP.ConfigParser.read(self, filename) if self.has_section('options'): self.handle_old_config(filename) - self.validate_options(filename, option_parser) + self.validate_settings(filename, option_parser) def handle_old_config(self, filename): warnings.warn_explicit(self.old_warning, ConfigDeprecationWarning, @@ -485,23 +549,24 @@ configuration files. See . self.set(section, setting, value) self.remove_section('options') - def validate_options(self, filename, option_parser): - for section in self.validation.keys(): - if not self.has_section(section): - continue - for option in self.validation[section].keys(): - if self.has_option(section, option): - value = self.get(section, option) - validator = self.validation[section][option] + def validate_settings(self, filename, option_parser): + """Call the validator function on all applicable settings.""" + for section in self.sections(): + for setting in self.options(section): + validator = option_parser.validators.get(setting) + if validator: + value = self.get(section, setting, raw=1) try: - new_value = validator(option, value) + new_value = validator( + setting, value, option_parser, + config_parser=self, config_section=section) except Exception, error: raise (ValueError( 'Error in config file "%s", section "[%s]":\n' ' %s: %s\n %s = %s' % (filename, section, error.__class__.__name__, - error, option, value)), None, sys.exc_info()[2]) - self.set(section, option, new_value) + error, setting, value)), None, sys.exc_info()[2]) + self.set(section, setting, new_value) def optionxform(self, optionstr): """ @@ -509,25 +574,38 @@ configuration files. See . """ return optionstr.lower().replace('-', '_') - def get_section(self, section, raw=0, vars=None): + def get_section(self, section): """ 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. """ section_dict = {} if self.has_section(section): for option in self.options(section): - section_dict[option] = self.get(section, option, raw, vars) + section_dict[option] = self.get(section, option, raw=1) return section_dict class ConfigDeprecationWarning(DeprecationWarning): """Warning for deprecated configuration file features.""" + + +class DictUpdater: + + """ + Wraps a dict: updates list values by extension rather than by replacement. + Works in conjunction with the `OptionParser.lists` instance attribute. + """ + + def __init__(self, option_parser, data=None): + self.option_parser = option_parser + self.data = copy.deepcopy(data or {}) + + def update(self, other): + other = other.copy() + for setting in self.option_parser.lists: + if (self.data.has_key(setting) and self.data[setting] + and other.has_key(setting)): + self.data[setting] += other[setting] + del other[setting] + self.data.update(other) -- cgit v1.2.1 From 6bf1f3a52b24ff86ba93343d6a04e766601721de Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 1 Sep 2003 15:09:14 +0000 Subject: updated for setting validators git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1663 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 12 ++++++++---- docutils/parsers/rst/__init__.py | 7 ++++--- docutils/readers/standalone.py | 8 +++++--- docutils/writers/docutils_xml.py | 18 +++++++++++------- docutils/writers/html4css1.py | 15 +++++++++------ docutils/writers/latex2e.py | 21 ++++++++++++--------- docutils/writers/pep_html.py | 5 +++-- 7 files changed, 52 insertions(+), 34 deletions(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index 45ec3b2b0..2d2f012bc 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -78,10 +78,14 @@ class SettingsSpec: `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 "dest" keyword argument.""" + and/or description may be `None`; a group title of `None` implies no + group, just a list of single options. The "keyword arguments" dictionary + contains arguments to the OptionParser/OptionGroup ``add_option`` method, + with the addition of a "validator" keyword (see the + `docutils.frontend.OptionParser.validators` instance attribute). Runtime + settings names are derived implicitly from long option names + ("--a-setting" becomes ``settings.a_setting``) or explicitly from the + "dest" keyword argument.""" settings_defaults = None """A dictionary of defaults for internal or inaccessible (by command-line diff --git a/docutils/parsers/rst/__init__.py b/docutils/parsers/rst/__init__.py index 0b46ad9e8..679539fb9 100644 --- a/docutils/parsers/rst/__init__.py +++ b/docutils/parsers/rst/__init__.py @@ -75,6 +75,7 @@ __docformat__ = 'reStructuredText' import docutils.parsers import docutils.statemachine from docutils.parsers.rst import states +from docutils import frontend class Parser(docutils.parsers.Parser): @@ -89,16 +90,16 @@ class Parser(docutils.parsers.Parser): None, (('Recognize and link to PEP references (like "PEP 258").', ['--pep-references'], - {'action': 'store_true'}), + {'action': 'store_true', 'validator': frontend.validate_boolean}), ('Recognize and link to RFC references (like "RFC 822").', ['--rfc-references'], - {'action': 'store_true'}), + {'action': 'store_true', 'validator': frontend.validate_boolean}), ('Set number of spaces for tab expansion (default 8).', ['--tab-width'], {'metavar': '', 'type': 'int', 'default': 8}), ('Remove spaces before footnote references.', ['--trim-footnote-reference-space'], - {'action': 'store_true'}),)) + {'action': 'store_true', 'validator': frontend.validate_boolean}),)) config_section = 'restructuredtext parser' config_section_dependencies = ('parsers',) diff --git a/docutils/readers/standalone.py b/docutils/readers/standalone.py index 43ca4c40b..cd69504ac 100644 --- a/docutils/readers/standalone.py +++ b/docutils/readers/standalone.py @@ -12,7 +12,7 @@ __docformat__ = 'reStructuredText' import sys -from docutils import readers +from docutils import frontend, readers from docutils.transforms import frontmatter, references from docutils.parsers.rst import Parser @@ -32,11 +32,13 @@ class Reader(readers.Reader): 'document title (and subsequent section title to document ' 'subtitle promotion; enabled by default).', ['--no-doc-title'], - {'dest': 'doctitle_xform', 'action': 'store_false', 'default': 1}), + {'dest': 'doctitle_xform', 'action': 'store_false', 'default': 1, + 'validator': frontend.validate_boolean}), ('Disable the bibliographic field list transform (enabled by ' 'default).', ['--no-doc-info'], - {'dest': 'docinfo_xform', 'action': 'store_false', 'default': 1}),)) + {'dest': 'docinfo_xform', 'action': 'store_false', 'default': 1, + 'validator': frontend.validate_boolean}),)) config_section = 'standalone reader' config_section_dependencies = ('readers',) diff --git a/docutils/writers/docutils_xml.py b/docutils/writers/docutils_xml.py index 0eaa4ed3c..cc730d873 100644 --- a/docutils/writers/docutils_xml.py +++ b/docutils/writers/docutils_xml.py @@ -12,7 +12,7 @@ __docformat__ = 'reStructuredText' import docutils -from docutils import writers +from docutils import frontend, writers class Writer(writers.Writer): @@ -25,15 +25,19 @@ class Writer(writers.Writer): 'Warning: the --newlines and --indents options may adversely affect ' 'whitespace; use them only for reading convenience.', (('Generate XML with newlines before and after tags.', - ['--newlines'], {'action': 'store_true'}), + ['--newlines'], + {'action': 'store_true', 'validator': frontend.validate_boolean}), ('Generate XML with indents and newlines.', - ['--indents'], {'action': 'store_true'}), + ['--indents'], + {'action': 'store_true', 'validator': frontend.validate_boolean}), ('Omit the XML declaration. Use with caution.', - ['--no-xml-declaration'], {'dest': 'xml_declaration', 'default': 1, - 'action': 'store_false'}), + ['--no-xml-declaration'], + {'dest': 'xml_declaration', 'default': 1, 'action': 'store_false', + 'validator': frontend.validate_boolean}), ('Omit the DOCTYPE declaration.', - ['--no-doctype'], {'dest': 'doctype_declaration', 'default': 1, - 'action': 'store_false'}),)) + ['--no-doctype'], + {'dest': 'doctype_declaration', 'default': 1, + 'action': 'store_false', 'validator': frontend.validate_boolean}),)) config_section = 'docutils_xml writer' config_section_dependencies = ('writers',) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 5bc33d5ea..b50552c03 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -23,7 +23,7 @@ import time import re from types import ListType import docutils -from docutils import nodes, utils, writers, languages +from docutils import frontend, nodes, utils, writers, languages class Writer(writers.Writer): @@ -46,14 +46,15 @@ class Writer(writers.Writer): ('Link to the stylesheet in the output HTML file. This is the ' 'default.', ['--link-stylesheet'], - {'dest': 'embed_stylesheet', 'action': 'store_false'}), + {'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). The stylesheet is embedded inside a comment, so it ' 'must not contain the text "--" (two hyphens). Default: link the ' 'stylesheet, do not embed it.', ['--embed-stylesheet'], - {'action': 'store_true'}), + {'action': 'store_true', 'validator': frontend.validate_boolean}), ('Format for footnote references: one of "superscript" or ' '"brackets". Default is "superscript".', ['--footnote-references'], @@ -69,13 +70,15 @@ class Writer(writers.Writer): 'items each contain one paragraph and/or one "simple" sublist ' 'only). Default: enabled.', ['--compact-lists'], - {'default': 1, 'action': 'store_true'}), + {'default': 1, 'action': 'store_true', + 'validator': frontend.validate_boolean}), ('Disable compact simple bullet and enumerated lists.', ['--no-compact-lists'], {'dest': 'compact_lists', 'action': 'store_false'}), ('Omit the XML declaration. Use with caution.', - ['--no-xml-declaration'], {'dest': 'xml_declaration', 'default': 1, - 'action': 'store_false'}),)) + ['--no-xml-declaration'], + {'dest': 'xml_declaration', 'default': 1, 'action': 'store_false', + 'validator': frontend.validate_boolean}),)) relative_path_settings = ('stylesheet_path',) diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 26b2bcca8..2f763a56f 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -20,7 +20,7 @@ import time import re import string from types import ListType -from docutils import writers, nodes, languages +from docutils import frontend, nodes, languages, writers class Writer(writers.Writer): @@ -36,7 +36,8 @@ class Writer(writers.Writer): ('Use LaTeX footnotes. ' 'Default: no, uses figures.', ['--use-latex-footnotes'], - {'default': 0, 'action': 'store_true'}), + {'default': 0, 'action': 'store_true', + 'validator': frontend.validate_boolean}), ('Format for footnote references: one of "superscript" or ' '"brackets". Default is "brackets".', ['--footnote-references'], @@ -48,8 +49,8 @@ class Writer(writers.Writer): {'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". If this is set to ' - '"" disables input. Overridden by --stylesheet-path.', + 'the document header. Default is no stylesheet (""). ' + 'Overridden by --stylesheet-path.', ['--stylesheet'], {'default': '', 'metavar': ''}), ('Specify a stylesheet file, relative to the current working ' @@ -59,16 +60,18 @@ class Writer(writers.Writer): ('Link to the stylesheet in the output LaTeX file. This is the ' 'default.', ['--link-stylesheet'], - {'dest': 'embed_stylesheet', 'action': 'store_false'}), + {'dest': 'embed_stylesheet', 'action': 'store_false', + 'validator': frontend.validate_boolean}), ('Embed the stylesheet in the output LaTeX file. The stylesheet ' 'file must be accessible during processing (--stylesheet-path is ' 'recommended).', - ['--embed-stylesheet'], - {'action': 'store_true'}), - ('Table of contents by docutils (default) or latex. Latex(writer) ' + ['--embed-stylesheet'], {'action': 'store_true'}), + ('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}), + ['--use-latex-toc'], + {'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'}),)) diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index 5fa14309b..96c44cfb0 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -13,7 +13,7 @@ __docformat__ = 'reStructuredText' import sys import docutils -from docutils import nodes, frontend, utils +from docutils import frontend, nodes, utils from docutils.writers import html4css1 @@ -35,7 +35,8 @@ class Writer(html4css1.Writer): # Workaround for SourceForge's broken Python # (``import random`` causes a segfault). (frontend.SUPPRESS_HELP, - ['--no-random'], {'action': 'store_true'}),)) + ['--no-random'], + {'action': 'store_true', 'validator': frontend.validate_boolean}),)) settings_default_overrides = {'footnote_references': 'brackets'} -- cgit v1.2.1 From 39b4d4330f7fc49f90959865ea9ad6eb30075f55 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 1 Sep 2003 21:08:47 +0000 Subject: Added "config_section" parameter to several methods and functions, allowing front ends to easily specify their config file sections. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1666 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 53 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 17 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index 1049748e1..e2bb03074 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -15,7 +15,7 @@ custom component objects first, and pass *them* to __docformat__ = 'reStructuredText' import sys -from docutils import Component, __version__ +from docutils import __version__, Component, SettingsSpec from docutils import frontend, io, utils, readers, parsers, writers from docutils.frontend import OptionParser @@ -83,7 +83,14 @@ class Publisher: self.set_writer(writer_name) def setup_option_parser(self, usage=None, description=None, - settings_spec=None, **defaults): + settings_spec=None, config_section=None, + **defaults): + if config_section and not settings_spec: + settings_spec = SettingsSpec() + settings_spec.config_section = config_section + parts = config_section.split() + if len(parts) > 1 and parts[-1] == 'application': + settings_spec.config_section_dependencies = ['applications'] #@@@ Add self.source & self.destination to components in future? option_parser = OptionParser( components=(self.parser, self.reader, self.writer, settings_spec), @@ -92,7 +99,7 @@ class Publisher: return option_parser def get_settings(self, usage=None, description=None, - settings_spec=None, **defaults): + settings_spec=None, config_section=None, **defaults): """ Set and return default settings (overrides in `defaults` dict). @@ -100,21 +107,22 @@ class Publisher: Explicitly setting `self.settings` disables command line option processing from `self.publish()`. """ - option_parser = self.setup_option_parser(usage, description, - settings_spec, **defaults) + option_parser = self.setup_option_parser( + usage, description, settings_spec, config_section, **defaults) self.settings = option_parser.get_default_values() return self.settings def process_command_line(self, argv=None, usage=None, description=None, - settings_spec=None, **defaults): + settings_spec=None, config_section=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 = self.setup_option_parser(usage, description, - settings_spec, **defaults) + option_parser = self.setup_option_parser( + usage, description, settings_spec, config_section,**defaults) if argv is None: argv = sys.argv[1:] self.settings = option_parser.parse_args(argv) @@ -152,15 +160,16 @@ class Publisher: def publish(self, argv=None, usage=None, description=None, settings_spec=None, settings_overrides=None, - enable_exit=None): + config_section=None, enable_exit=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, - **(settings_overrides or {})) + self.process_command_line( + argv, usage, description, settings_spec, config_section, + **(settings_overrides or {})) elif settings_overrides: self.settings._update(settings_overrides, 'loose') self.set_io() @@ -221,7 +230,8 @@ def publish_cmdline(reader=None, reader_name='standalone', parser=None, parser_name='restructuredtext', writer=None, writer_name='pseudoxml', settings=None, settings_spec=None, - settings_overrides=None, enable_exit=1, argv=None, + settings_overrides=None, config_section=None, + enable_exit=1, argv=None, usage=default_usage, description=default_description): """ Set up & run a `Publisher`. For command-line front ends. @@ -242,6 +252,8 @@ def publish_cmdline(reader=None, reader_name='standalone', subclass. Used only if no `settings` specified. - `settings_overrides`: A dictionary containing program-specific overrides of component settings. + - `config_section`: Name of configuration file section for application. + Used only if no `settings` or `settings_spec` specified. - `enable_exit`: Boolean; enable exit status at end of processing? - `argv`: Command-line argument list to use instead of ``sys.argv[1:]``. - `usage`: Usage string, output if there's a problem parsing the command @@ -252,7 +264,7 @@ def publish_cmdline(reader=None, reader_name='standalone', pub = Publisher(reader, parser, writer, settings=settings) pub.set_components(reader_name, parser_name, writer_name) pub.publish(argv, usage, description, settings_spec, settings_overrides, - enable_exit=enable_exit) + config_section=config_section, enable_exit=enable_exit) def publish_file(source=None, source_path=None, destination=None, destination_path=None, @@ -260,7 +272,7 @@ def publish_file(source=None, source_path=None, parser=None, parser_name='restructuredtext', writer=None, writer_name='pseudoxml', settings=None, settings_spec=None, settings_overrides=None, - enable_exit=None): + config_section=None, enable_exit=None): """ Set up & run a `Publisher`. For programmatic use with file-like I/O. @@ -288,12 +300,15 @@ def publish_file(source=None, source_path=None, subclass. Used only if no `settings` specified. - `settings_overrides`: A dictionary containing program-specific overrides of component settings. + - `config_section`: Name of configuration file section for application. + Used only if no `settings` or `settings_spec` specified. - `enable_exit`: Boolean; enable exit status at end of processing? """ pub = Publisher(reader, parser, writer, settings=settings) pub.set_components(reader_name, parser_name, writer_name) if settings is None: - settings = pub.get_settings(settings_spec=settings_spec) + settings = pub.get_settings(settings_spec=settings_spec, + config_section=config_section) if settings_overrides: settings._update(settings_overrides, 'loose') pub.set_source(source, source_path) @@ -305,7 +320,8 @@ def publish_string(source, source_path=None, destination_path=None, parser=None, parser_name='restructuredtext', writer=None, writer_name='pseudoxml', settings=None, settings_spec=None, - settings_overrides=None, enable_exit=None): + settings_overrides=None, config_section=None, + enable_exit=None): """ Set up & run a `Publisher`, and return the string output. For programmatic use with string I/O. @@ -344,6 +360,8 @@ def publish_string(source, source_path=None, destination_path=None, subclass. Used only if no `settings` specified. - `settings_overrides`: A dictionary containing program-specific overrides of component settings. + - `config_section`: Name of configuration file section for application. + Used only if no `settings` or `settings_spec` specified. - `enable_exit`: Boolean; enable exit status at end of processing? """ pub = Publisher(reader, parser, writer, settings=settings, @@ -351,7 +369,8 @@ def publish_string(source, source_path=None, destination_path=None, destination_class=io.StringOutput) pub.set_components(reader_name, parser_name, writer_name) if settings is None: - settings = pub.get_settings(settings_spec=settings_spec) + settings = pub.get_settings(settings_spec=settings_spec, + config_section=config_section) if settings_overrides: settings._update(settings_overrides, 'loose') pub.set_source(source, source_path) -- cgit v1.2.1 From badbd5efb84ea0fcfa2f51804ab7bf28cf69a11e Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 1 Sep 2003 21:09:15 +0000 Subject: Merged ``DictUpdater`` functionality into ``Values``, a subclass of ``optparse.Values``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1667 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 59 ++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 30 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 091992bde..40c61c081 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -12,9 +12,8 @@ Exports the following classes: * `OptionParser`: Standard Docutils command-line processing. * `Option`: Customized version of `optparse.Option`; validation support. * `Values`: Runtime settings; objects are simple structs - (``object.attribute``). + (``object.attribute``). Supports cumulative list settings (attributes). * `ConfigParser`: Standard Docutils config file processing. -* `DictUpdater`: Supports cumulative list settings (dict values). Also exports the following functions: @@ -61,9 +60,7 @@ def read_config_file(option, opt, value, parser): new_settings = parser.get_config_file_settings(value) except ValueError, error: parser.error(error) - settings = DictUpdater(parser, parser.values.__dict__) - settings.update(new_settings) - parser.values._update_loose(settings.data) + parser.values.update(new_settings, parser) def validate_encoding(setting, value, option_parser, config_parser=None, config_section=None): @@ -170,6 +167,24 @@ def make_one_path_absolute(base_path, path): return os.path.abspath(os.path.join(base_path, path)) +class Values(optparse.Values): + + """ + Updates list attributes by extension rather than by replacement. + Works in conjunction with the `OptionParser.lists` instance attribute. + """ + + def update(self, other_dict, option_parser): + other_dict = other_dict.copy() + for setting in option_parser.lists: + if (hasattr(self, setting) and other_dict.has_key(setting)): + value = getattr(self, setting) + if value: + value += other_dict[setting] + del other_dict[setting] + self._update_loose(other_dict) + + class Option(optparse.Option): def process(self, opt, value, values, parser): @@ -464,11 +479,12 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): return settings def get_config_file_settings(self, config_file): + """Returns a dictionary containing appropriate config file settings.""" parser = ConfigParser() parser.read(config_file, self) base_path = os.path.dirname(config_file) applied = {} - settings = DictUpdater(self) + settings = Values() for component in self.components: if not component: continue @@ -477,10 +493,10 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): if applied.has_key(section): continue applied[section] = 1 - settings.update(parser.get_section(section)) + settings.update(parser.get_section(section), self) make_paths_absolute( - settings.data, self.relative_path_settings, base_path) - return settings.data + settings.__dict__, self.relative_path_settings, base_path) + return settings.__dict__ def check_values(self, values, args): """Store positional arguments as runtime settings.""" @@ -506,6 +522,10 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): 'destination. It will clobber the source file.') return source, destination + def get_default_values(self): + """Needed to get custom `Values` instances.""" + return Values(self.defaults) + class ConfigParser(CP.ConfigParser): @@ -588,24 +608,3 @@ configuration files. See . class ConfigDeprecationWarning(DeprecationWarning): """Warning for deprecated configuration file features.""" - - -class DictUpdater: - - """ - Wraps a dict: updates list values by extension rather than by replacement. - Works in conjunction with the `OptionParser.lists` instance attribute. - """ - - def __init__(self, option_parser, data=None): - self.option_parser = option_parser - self.data = copy.deepcopy(data or {}) - - def update(self, other): - other = other.copy() - for setting in self.option_parser.lists: - if (self.data.has_key(setting) and self.data[setting] - and other.has_key(setting)): - self.data[setting] += other[setting] - del other[setting] - self.data.update(other) -- cgit v1.2.1 From 88920f7db59954908fa82c9a39538f6c683666f9 Mon Sep 17 00:00:00 2001 From: cben Date: Thu, 11 Sep 2003 09:52:06 +0000 Subject: Added support for ``DOCUTILSCONFIG`` environment variable. Added method `OptionParser.get_config_files()` to allow overriding this behavior in a subclass. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1674 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 40c61c081..ef7dc5938 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -222,11 +222,11 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): """ standard_config_files = [ - '/etc/docutils.conf', # system-wide - './docutils.conf', # project-specific - os.path.expanduser('~/.docutils')] # user-specific - """Docutils configuration files, using ConfigParser syntax. - Later files override earlier ones.""" + '/etc/docutils.conf', # system-wide + './docutils.conf', # project-specific + '~/.docutils'] # user-specific + """Docutils configuration files, using ConfigParser syntax. Filenames + will be tilde-expanded later. Later files override earlier ones.""" threshold_choices = 'info 1 warning 2 error 3 severe 4 none 5'.split() """Possible inputs for for --report and --halt threshold values.""" @@ -472,7 +472,19 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): if component and component.settings_default_overrides: self.defaults.update(component.settings_default_overrides) + def get_config_files(self): + """Return list of config files, from environment or standard.""" + try: + config_files = os.environ['DOCUTILSCONFIG'] + if config_files == '': + return [] + else: + return config_files.split(os.pathsep) + except KeyError: + return self.standard_config_files + def get_standard_config_settings(self): + config_files = map(os.path.expanduser, self.get_config_files()) settings = {} for filename in self.standard_config_files: settings.update(self.get_config_file_settings(filename)) -- cgit v1.2.1 From 5261c45badb074fa23f7cad47808d96b572b717e Mon Sep 17 00:00:00 2001 From: cben Date: Thu, 11 Sep 2003 14:58:04 +0000 Subject: - Fixed stupid bug that made last change a no-op. - Explicitly made 'DOCUTILSCONFIG' ignore empty path items. - Refactored `test_settings.ConfigFileTests`: - Centralized reading of config files and combining of multiple setting dicts. - Subclassed with a class that runs the very same tests but sets `os.environ['DOCUTILSCONFIG']` instead of reading files directly. - Added test method that reads no files at all, for completeness. - Improved diff display in `compare_output` (order & trailing newlines). - Fixed bug in `test_old_and_new`: it used 'old' expected settings (which are surely the same as 'one') but read the 'one' config file. Assuming it's a cut-and-paste typo, changed to read 'one' file. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1675 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index ef7dc5938..e12449eaf 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -472,21 +472,19 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): if component and component.settings_default_overrides: self.defaults.update(component.settings_default_overrides) - def get_config_files(self): + def get_standard_config_files(self): """Return list of config files, from environment or standard.""" try: config_files = os.environ['DOCUTILSCONFIG'] - if config_files == '': - return [] - else: - return config_files.split(os.pathsep) + return [f for f in config_files.split(os.pathsep) if f != ''] except KeyError: return self.standard_config_files def get_standard_config_settings(self): - config_files = map(os.path.expanduser, self.get_config_files()) + config_files = map(os.path.expanduser, + self.get_standard_config_files()) settings = {} - for filename in self.standard_config_files: + for filename in config_files: settings.update(self.get_config_file_settings(filename)) return settings -- cgit v1.2.1 From ef69adb2f48763ddba3d0d6e6536ba16da78c04b Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 11 Sep 2003 22:42:59 +0000 Subject: simplified config file processing code git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1678 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index e12449eaf..f28333ce7 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -476,15 +476,14 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): """Return list of config files, from environment or standard.""" try: config_files = os.environ['DOCUTILSCONFIG'] - return [f for f in config_files.split(os.pathsep) if f != ''] except KeyError: - return self.standard_config_files + config_files = self.standard_config_files + return [os.path.expanduser(f) + for f in config_files.split(os.pathsep) if f.strip()] def get_standard_config_settings(self): - config_files = map(os.path.expanduser, - self.get_standard_config_files()) settings = {} - for filename in config_files: + for filename in self.get_standard_config_files(): settings.update(self.get_config_file_settings(filename)) return settings -- cgit v1.2.1 From 6d7dc5c949f7f42669203306a403d4d036d15362 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 11 Sep 2003 22:58:37 +0000 Subject: fixed bug git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1680 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index f28333ce7..fdfbacde7 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -475,11 +475,10 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): def get_standard_config_files(self): """Return list of config files, from environment or standard.""" try: - config_files = os.environ['DOCUTILSCONFIG'] + config_files = os.environ['DOCUTILSCONFIG'].split(os.pathsep) except KeyError: config_files = self.standard_config_files - return [os.path.expanduser(f) - for f in config_files.split(os.pathsep) if f.strip()] + return [os.path.expanduser(f) for f in config_files if f.strip()] def get_standard_config_settings(self): settings = {} -- cgit v1.2.1 From 277277b7cc17291c8149be895eb2d90524d304e9 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 12 Sep 2003 22:24:49 +0000 Subject: improved setting handling git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1682 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index fdfbacde7..1ab644531 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -175,6 +175,8 @@ class Values(optparse.Values): """ def update(self, other_dict, option_parser): + if isinstance(other_dict, Values): + other_dict = other_dict.__dict__ other_dict = other_dict.copy() for setting in option_parser.lists: if (hasattr(self, setting) and other_dict.has_key(setting)): @@ -426,7 +428,7 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): config_settings = self.get_standard_config_settings() except ValueError, error: self.error(error) - defaults.update(config_settings) + defaults.update(config_settings.__dict__) # Internal settings with no defaults from settings specifications; # initialize manually: self.set_defaults(_source=None, _destination=None, **defaults) @@ -481,9 +483,9 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): return [os.path.expanduser(f) for f in config_files if f.strip()] def get_standard_config_settings(self): - settings = {} + settings = Values() for filename in self.get_standard_config_files(): - settings.update(self.get_config_file_settings(filename)) + settings.update(self.get_config_file_settings(filename), self) return settings def get_config_file_settings(self, config_file): -- cgit v1.2.1 From e169be827f771c779b1cf97315af5f36c79482dc Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 13 Sep 2003 23:15:43 +0000 Subject: removed Python 2.2 feature git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1683 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 1ab644531..0a6fa8d84 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -553,7 +553,7 @@ configuration files. See . """ def read(self, filenames, option_parser): - if type(filenames) in types.StringTypes: + if type(filenames) in (types.StringType, types.UnicodeType): filenames = [filenames] for filename in filenames: CP.ConfigParser.read(self, filename) -- cgit v1.2.1 From a803d05c6c6121fe4ccdfa49068ef2971868503f Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 14 Sep 2003 00:01:38 +0000 Subject: removed another Python 2.2 feature git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1684 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 0a6fa8d84..5a52ff980 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -178,7 +178,7 @@ class Values(optparse.Values): if isinstance(other_dict, Values): other_dict = other_dict.__dict__ other_dict = other_dict.copy() - for setting in option_parser.lists: + for setting in option_parser.lists.keys(): if (hasattr(self, setting) and other_dict.has_key(setting)): value = getattr(self, setting) if value: -- cgit v1.2.1 From 143808332320692f761ef413867b05ae93440418 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 14 Sep 2003 19:17:37 +0000 Subject: Python 2.1 compatibility git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1687 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 9217c7ef8..d765c9abe 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -299,7 +299,7 @@ class Element(Node): return '<%s...>' % self.tagname def __str__(self): - return unicode(self).encode('raw_unicode_escape') + return self.__unicode__().encode('raw_unicode_escape') def __unicode__(self): if self.children: -- cgit v1.2.1 From da55c3e3fe4936d6531e9b594fca5b8fe53bb43c Mon Sep 17 00:00:00 2001 From: grubert Date: Sun, 14 Sep 2003 22:31:20 +0000 Subject: Apply beni's patch for documentoptions. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1688 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 2f763a56f..be33deae8 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -33,6 +33,10 @@ class Writer(writers.Writer): (('Specify documentclass. Default is "article".', ['--documentclass'], {'default': 'article', }), + ('Specify document options. Multiple options can be given, ' + 'separated by commas. Default is "10pt".', + ['--documentoptions'], + {'default': '10pt', }), ('Use LaTeX footnotes. ' 'Default: no, uses figures.', ['--use-latex-footnotes'], @@ -240,8 +244,7 @@ class LaTeXTranslator(nodes.NodeVisitor): # to other packages, as done with babel. # Dummy settings might be taken from document settings - d_options = '10pt' # papersize, fontsize - d_paper = 'a4paper' + d_paper = 'a4paper' # papersize d_margins = '2cm' latex_head = '\\documentclass[%s]{%s}\n' @@ -283,6 +286,7 @@ class LaTeXTranslator(nodes.NodeVisitor): 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() -- cgit v1.2.1 From 04f4937f776a56d8cd8f0b305ddd793af59b99dd Mon Sep 17 00:00:00 2001 From: cben Date: Wed, 17 Sep 2003 14:45:21 +0000 Subject: - Added some documentation about text-containing vs. compound elements. - Improved images in LaTeX writer: - Fixed inline images (used to always break the paragraph). - Implemented ``align`` and ``scale`` options. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1691 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 5 +- docutils/writers/latex2e.py | 118 +++++++++++++++++++++++++++----------------- 2 files changed, 76 insertions(+), 47 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index d765c9abe..f2a84088a 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -512,7 +512,10 @@ class TextElement(Element): """ An element which directly contains text. - Its children are all Text or TextElement nodes. + Its children are all `Text` or `TextElement` nodes. You can check whether + an element's context is inline simply by checking whether it's immediate + parent is a `TextElement`. This is handy for nodes like `image` that can + appear both inline and as standalone body elements. """ child_text_separator = '' diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index be33deae8..50f4f7265 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -105,13 +105,13 @@ Notes on LaTeX * latex does not support multiple tocs in one document. (might be no limitation except for docutils documentation) -* width +* width * linewidth - width of a line in the local environment * textwidth - the width of text on the page Maybe always use linewidth ? -""" +""" class Babel: """Language specifics for LaTeX.""" @@ -170,10 +170,10 @@ class Babel: # maybe use: {\glqq} {\grqq}. self.quotes = ("\"`", "\"'") self.double_quote_replacment = "{\\dq}" - else: + 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 @@ -241,7 +241,7 @@ latex_headings = { class LaTeXTranslator(nodes.NodeVisitor): # When options are given to the documentclass, latex will pass them - # to other packages, as done with babel. + # to other packages, as done with babel. # Dummy settings might be taken from document settings d_paper = 'a4paper' # papersize @@ -280,7 +280,7 @@ class LaTeXTranslator(nodes.NodeVisitor): 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) @@ -305,7 +305,7 @@ class LaTeXTranslator(nodes.NodeVisitor): # # extra space between text in tables and the line above them '\\setlength{\\extrarowheight}{2pt}\n', - '\\usepackage{amsmath}\n', # what fore amsmath. + '\\usepackage{amsmath}\n', # what fore amsmath. '\\usepackage{graphicx}\n', '\\usepackage{color}\n', '\\usepackage{multirow}\n', @@ -316,10 +316,10 @@ class LaTeXTranslator(nodes.NodeVisitor): self.generator, # latex lengths '\\newlength{\\admonitionwidth}\n', - '\\setlength{\\admonitionwidth}{0.9\\textwidth}\n' + '\\setlength{\\admonitionwidth}{0.9\\textwidth}\n' # width for docinfo tablewidth '\\newlength{\\docinfowidth}\n', - '\\setlength{\\docinfowidth}{0.9\\textwidth}\n' + '\\setlength{\\docinfowidth}{0.9\\textwidth}\n' ] self.head_prefix.extend( latex_headings['optionlist_environment'] ) self.head_prefix.extend( latex_headings['footnote_floats'] ) @@ -365,7 +365,7 @@ class LaTeXTranslator(nodes.NodeVisitor): # enumeration is done by list environment. self._enum_cnt = 0 - # docinfo. + # docinfo. self.docinfo = None # inside literal block: no quote mangling. self.literal_block = 0 @@ -395,9 +395,9 @@ class LaTeXTranslator(nodes.NodeVisitor): "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) + "windows-1250": "cp1250", # + "windows-1252": "cp1252", # + "us-ascii": "ascii", # ASCII (US) # unmatched encodings #"": "applemac", #"": "ansinew", # windows 3.1 ansi @@ -428,7 +428,7 @@ class LaTeXTranslator(nodes.NodeVisitor): < > are only available in math-mode (really ?) $ starts math- mode. AND quotes: - + """ if self.verbatim: return text @@ -466,14 +466,14 @@ class LaTeXTranslator(nodes.NodeVisitor): else: text = self.babel.quote_quotes(text) if self.insert_newline: - # HACK: insert a blank before the newline, to avoid + # HACK: 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: text = text.replace("\n", '}\\\\\n\\mbox{') if self.insert_none_breaking_blanks: text = text.replace(' ', '~') - # unicode !!! + # unicode !!! text = text.replace(u'\u2020', '{$\\dagger$}') return text @@ -490,7 +490,7 @@ class LaTeXTranslator(nodes.NodeVisitor): else: pdfinfo = '' title = '\\title{%s}\n' % self.title - return ''.join(self.head_prefix + [title] + return ''.join(self.head_prefix + [title] + self.head + [pdfinfo] + self.body_prefix + self.body + self.body_suffix) @@ -603,7 +603,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_colspec(self, node): if self.use_longtable: self.colspecs.append(node) - else: + else: self.context[-1] += 1 def depart_colspec(self, node): @@ -667,7 +667,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_description(self, node): if self.use_optionlist_for_option_list: self.body.append( ' ' ) - else: + else: self.body.append( ' & ' ) def depart_description(self, node): @@ -704,10 +704,10 @@ class LaTeXTranslator(nodes.NodeVisitor): raise nodes.SkipNode if name == 'address': # BUG will fail if latex_docinfo is set. - self.insert_newline = 1 + self.insert_newline = 1 self.docinfo.append('{\\raggedright\n') self.context.append(' } \\\\\n') - else: + else: self.context.append(' \\\\\n') self.context.append(self.docinfo) self.context.append(len(self.body)) @@ -795,7 +795,7 @@ class LaTeXTranslator(nodes.NodeVisitor): enum_style = {'arabic':'arabic', 'loweralpha':'alph', - 'upperalpha':'Alph', + 'upperalpha':'Alph', 'lowerroman':'roman', 'upperroman':'Roman' } enum_suffix = "" @@ -804,7 +804,7 @@ class LaTeXTranslator(nodes.NodeVisitor): enum_prefix = "" if node.has_key('prefix'): enum_prefix = node['prefix'] - + enum_type = "arabic" if node.has_key('enumtype'): enum_type = node['enumtype'] @@ -962,11 +962,37 @@ class LaTeXTranslator(nodes.NodeVisitor): self.depart_admonition() def visit_image(self, node): - atts = node.attributes.copy() - href = atts['uri'] - ##self.body.append('\\begin{center}\n') - self.body.append('\n\\includegraphics{%s}\n' % href) - ##self.body.append('\\end{center}\n') + attrs = node.attributes.copy() + pre = [] # in reverse order + post = ['\\includegraphics{%s}' % attrs['uri']] + def prepost(pre_append, post_append): + pre.append(pre_append) + post.append(post_append) + inline = isinstance(node.parent, nodes.TextElement) + if 'scale' in attrs: + # Could also be done with ``scale`` option to + # ``\includegraphics``; doing it this way for consistency. + prepost('\\scalebox{%f}{' % (attrs['scale'] / 100.0,), '}') + if 'align' in attrs: + align_prepost = { + # By default latex aligns the top of an image. + (1, 'top'): ('', ''), + (1, 'middle'): ('\\raisebox{-0.5\\height}{', '}'), + (1, 'bottom'): ('\\raisebox{-\\height}{', '}'), + (0, 'center'): ('{\\hfill', '\\hfill}'), + # These 2 don't exactly do the right thing. The image should + # be floated alongside the paragraph. See + # http://www.w3.org/TR/html4/struct/objects.html#adef-align-IMG + (0, 'left'): ('{', '\\hfill}'), + (0, 'right'): ('{\\hfill', '}'),} + try: + prepost(*align_prepost[inline, attrs['align']]) + except KeyError: + pass # complain here? + if not inline: + prepost('\n', '\n') + pre.reverse() + self.body.append(''.join(pre + post)) def depart_image(self, node): pass @@ -999,9 +1025,9 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('}') def visit_line_block(self, node): - """line-block: - * whitespace (including linebreaks) is significant - * inline markup is supported. + """line-block: + * whitespace (including linebreaks) is significant + * inline markup is supported. * serif typeface """ self.body.append('\\begin{flushleft}\n') @@ -1042,7 +1068,7 @@ class LaTeXTranslator(nodes.NodeVisitor): """ # typically in a typewriter/monospaced typeface. # care must be taken with the text, because inline markup is recognized. - # + # # possibilities: # * verbatim: is no possibility, as inline markup does not work. # * obey..: is from julien and never worked for me (grubert). @@ -1105,7 +1131,7 @@ class LaTeXTranslator(nodes.NodeVisitor): else: self.context.append('') self.body.append('\\texttt{') - # flag for first option + # flag for first option self.context.append(0) def depart_option_group(self, node): @@ -1206,7 +1232,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.section_level -= 1 def visit_sidebar(self, node): - # BUG: this is just a hack to make sidebars render something + # BUG: this is just a hack to make sidebars render something self.body.append('\\begin{center}\\begin{sffamily}\n') self.body.append('\\fbox{\\colorbox[gray]{0.80}{\\parbox{\\admonitionwidth}{\n') @@ -1254,7 +1280,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.context.append('}\n\\smallskip\n') else: self.title = self.title + \ - '\\\\\n\\large{%s}\n' % self.encode(node.astext()) + '\\\\\n\\large{%s}\n' % self.encode(node.astext()) raise nodes.SkipNode def depart_subtitle(self, node): @@ -1276,20 +1302,20 @@ class LaTeXTranslator(nodes.NodeVisitor): Assumes reST line length being 80 characters. """ width = 80 - + total_width = 0.0 # first see if we get too wide. for node in self.colspecs: - colwidth = float(node['colwidth']) / width + colwidth = float(node['colwidth']) / width total_width += colwidth # donot make it full linewidth factor = 0.93 if total_width > 1.0: factor /= total_width - + latex_table_spec = "" for node in self.colspecs: - colwidth = factor * float(node['colwidth']) / width + colwidth = factor * float(node['colwidth']) / width latex_table_spec += "|p{%.2f\\linewidth}" % colwidth self.colspecs = [] return latex_table_spec+"|" @@ -1305,7 +1331,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_table(self, node): if self.use_longtable: self.body.append('\\end{longtable}\n') - else: + else: self.body.append('\\end{tabularx}\n') sentinel = self.context.pop() if sentinel != 'table_sentinel': @@ -1375,12 +1401,12 @@ class LaTeXTranslator(nodes.NodeVisitor): # firsthead, but then we need the header twice. # # there is a \endfoot and \endlastfoot too. - # but we need the number of columns to + # 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') @@ -1414,15 +1440,15 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('\n\n') if node.parent.hasattr('id'): self.body.append('\\hypertarget{%s}{}\n' % node.parent['id']) - # section_level 0 is title and handled above. + # section_level 0 is title and handled above. # BUG: latex has no deeper sections (actually paragrah is no section either). if self.use_latex_toc: section_star = "" else: section_star = "*" - if (self.section_level<=3): # 1,2,3 + if (self.section_level<=3): # 1,2,3 self.body.append('\\%ssection%s{' % ('sub'*(self.section_level-1),section_star)) - elif (self.section_level==4): + elif (self.section_level==4): #self.body.append('\\paragraph*{') self.body.append('\\subsubsection%s{' % (section_star)) else: @@ -1495,5 +1521,5 @@ class LaTeXTranslator(nodes.NodeVisitor): # def unknown_visit(self, node): # def default_visit(self, node): - + # vim: set ts=4 et ai : -- cgit v1.2.1 From 1d2ec2557a016316cecf70a9aa88a5662949016e Mon Sep 17 00:00:00 2001 From: cben Date: Wed, 17 Sep 2003 17:41:36 +0000 Subject: Trivial code simplification. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1692 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 50f4f7265..1fbf55428 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -992,7 +992,7 @@ class LaTeXTranslator(nodes.NodeVisitor): if not inline: prepost('\n', '\n') pre.reverse() - self.body.append(''.join(pre + post)) + self.body.extend(pre + post) def depart_image(self, node): pass -- cgit v1.2.1 From ffa3cb13c661973bbc18f65636a73c72f1b73327 Mon Sep 17 00:00:00 2001 From: cben Date: Thu, 18 Sep 2003 18:43:40 +0000 Subject: Trivially worked around a bug in parsing ``raw::`` substitution definitions (backslashes are turned into null chars) because I don't have the expertise for the right fix (and I need it work now). When the proper fix is found this should be reverted. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1694 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 4 +++- docutils/writers/latex2e.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index b50552c03..0ed2f5a85 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -932,7 +932,9 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_raw(self, node): if node.get('format') == 'html': - self.body.append(node.astext()) + # @@@ Wrong fix! + from docutils.parsers.rst.states import unescape + self.body.append(unescape(node.astext(), restore_backslashes=1)) # Keep non-HTML raw text out of output: raise nodes.SkipNode diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 1fbf55428..a335af413 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1194,7 +1194,9 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_raw(self, node): if node.has_key('format') and node['format'].lower() == 'latex': - self.body.append(node.astext()) + # @@@ Wrong fix! + from docutils.parsers.rst.states import unescape + self.body.append(unescape(node.astext(), restore_backslashes=1)) raise nodes.SkipNode def visit_reference(self, node): -- cgit v1.2.1 From 296b45ebc25622c11469a55f08ecba9b0b3d8f5e Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 19 Sep 2003 03:01:44 +0000 Subject: Added support for complex option arguments (option lists). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1695 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 6666366b6..bb84261ae 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1198,8 +1198,10 @@ class Body(RSTState): '|%(upperroman)s)' % enum.sequencepats) pats['optname'] = '%(alphanum)s%(alphanumplus)s*' % pats # @@@ Loosen up the pattern? Allow Unicode? - pats['optarg'] = '%(alpha)s%(alphanumplus)s*' % pats - pats['option'] = r'(--?|\+|/)%(optname)s([ =]%(optarg)s)?' % pats + pats['optarg'] = '(%(alpha)s%(alphanumplus)s*|<%(alphanum)s[^ <>]+>)' % pats + pats['shortopt'] = r'(-|\+)%(alphanum)s( ?%(optarg)s)?' % pats + pats['longopt'] = r'(--|/)%(optname)s([ =]%(optarg)s)?' % pats + pats['option'] = r'(%(shortopt)s|%(longopt)s)' % pats for format in enum.formats: pats[format] = '(?P<%s>%s%s%s)' % ( @@ -1572,6 +1574,12 @@ class Body(RSTState): if len(firstopt) > 1: tokens[:1] = firstopt delimiter = '=' + elif (len(tokens[0]) > 2 + and ((tokens[0].startswith('-') + and not tokens[0].startswith('--')) + or tokens[0].startswith('+'))): + tokens[:1] = [tokens[0][:2], tokens[0][2:]] + delimiter = '' if 0 < len(tokens) <= 2: option = nodes.option(optionstring) option += nodes.option_string(tokens[0], tokens[0]) -- cgit v1.2.1 From db535a208f73d2fc6af3887c5cb8d0030558213d Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 20 Sep 2003 17:22:11 +0000 Subject: Fixed handling of backslashes in substitution definitions. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1696 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 6 ++++-- docutils/parsers/rst/states.py | 6 ++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index dc4c09269..a567ac9e2 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -170,7 +170,7 @@ def unicode_directive(name, arguments, options, content, lineno, 'substitution definition.' % (name), nodes.literal_block(block_text, block_text), line=lineno) return [error] - codes = arguments[0].split('.. ')[0].split() + codes = unicode_comment_pattern.split(arguments[0])[0].split() element = nodes.Element() for code in codes: try: @@ -193,7 +193,9 @@ def unicode_directive(name, arguments, options, content, lineno, unicode_directive.arguments = (1, 0, 1) unicode_pattern = re.compile( - r'(?:0x|x|\x00x|U\+?|\x00u)([0-9a-f]+)$|&#x([0-9a-f]+);$', re.IGNORECASE) + r'(?:0x|x|\\x|U\+?|\\u)([0-9a-f]+)$|&#x([0-9a-f]+);$', re.IGNORECASE) +unicode_comment_pattern = re.compile(r'( |\n|^).. ') + def class_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index bb84261ae..82ae15791 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1936,9 +1936,7 @@ class Body(RSTState): strip_indent=0) blocktext = (match.string[:match.end()] + '\n'.join(block)) block.disconnect() - for i in range(len(block)): - block[i] = escape2null(block[i]) - escaped = block[0].rstrip() + escaped = escape2null(block[0].rstrip()) blockindex = 0 while 1: subdefmatch = pattern.match(escaped) @@ -1946,7 +1944,7 @@ class Body(RSTState): break blockindex += 1 try: - escaped = escaped + ' ' + block[blockindex].strip() + escaped = escaped + ' ' + escape2null(block[blockindex].strip()) except IndexError: raise MarkupError('malformed substitution definition.', lineno) -- cgit v1.2.1 From 33d172b65e4273c82ffdc3bd46c470ebcf0e8f57 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 20 Sep 2003 17:30:24 +0000 Subject: reverted previous checkin; inappropriate fix in wrong place git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1698 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 4 +--- docutils/writers/latex2e.py | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 0ed2f5a85..b50552c03 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -932,9 +932,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_raw(self, node): if node.get('format') == 'html': - # @@@ Wrong fix! - from docutils.parsers.rst.states import unescape - self.body.append(unescape(node.astext(), restore_backslashes=1)) + self.body.append(node.astext()) # Keep non-HTML raw text out of output: raise nodes.SkipNode diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index a335af413..1fbf55428 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1194,9 +1194,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_raw(self, node): if node.has_key('format') and node['format'].lower() == 'latex': - # @@@ Wrong fix! - from docutils.parsers.rst.states import unescape - self.body.append(unescape(node.astext(), restore_backslashes=1)) + self.body.append(node.astext()) raise nodes.SkipNode def visit_reference(self, node): -- cgit v1.2.1 From f282f57ada8549b867097f45cdbb712fbc411126 Mon Sep 17 00:00:00 2001 From: grubert Date: Sun, 21 Sep 2003 17:26:55 +0000 Subject: Fix internal references in parsed literal (mbox does not like '#'). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1702 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 1fbf55428..65ecddb32 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1199,18 +1199,22 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_reference(self, node): # for pdflatex hyperrefs might be supported + if self.literal_block and (self.use_for_literal_block == "mbox"): + # mbox does not like the '#' + hash_char = '\\#' + else: + hash_char = '#' + if node.has_key('refuri'): href = node['refuri'] elif node.has_key('refid'): - href = '#' + node['refid'] + href = hash_char + node['refid'] elif node.has_key('refname'): - href = '#' + self.document.nameids[node['refname']] - ##self.body.append('[visit_reference]') + href = hash_char + self.document.nameids[node['refname']] self.body.append('\\href{%s}{' % href) def depart_reference(self, node): self.body.append('}') - ##self.body.append('[depart_reference]') def visit_revision(self, node): self.visit_docinfo_item(node, 'revision') -- cgit v1.2.1 From 03a77ce183aa801a45c01fd3cc91b2f97917b713 Mon Sep 17 00:00:00 2001 From: grubert Date: Mon, 22 Sep 2003 13:19:57 +0000 Subject: Fix: use node['id'] for hypertarget and href. Fix: pdfbookmarks firstparameter needs "_" escaped. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1703 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 65ecddb32..4cba3e139 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -903,9 +903,8 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('{'+self.encode(text)+'}') raise nodes.SkipNode else: - notename = node['id'] self.body.append('\\begin{figure}[b]') - self.body.append('\\hypertarget{%s}' % notename) + self.body.append('\\hypertarget{%s}' % node['id']) def depart_footnote(self, node): if self.use_latex_footnotes: @@ -1351,9 +1350,10 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('\n\\hline') 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')): - self.body.append('\\hypertarget{%s}{' % node['name']) + self.body.append('\\hypertarget{%s}{' % node['id']) self.context.append('}') else: self.context.append('') @@ -1474,8 +1474,10 @@ class LaTeXTranslator(nodes.NodeVisitor): l = self.section_level if l>0: l = l-1 + # pdftex does not like "_" subscripts in titles + text = node.astext().replace("_","\\_") self.body.append('\\pdfbookmark[%d]{%s}{%s}\n' % \ - (l,node.astext(),node.parent['id'])) + (l,text,node.parent['id'])) def visit_topic(self, node): self.topic_class = node.get('class') -- cgit v1.2.1 From 5c50446abb5353abd45e6255613defd9cbc70512 Mon Sep 17 00:00:00 2001 From: grubert Date: Tue, 23 Sep 2003 00:11:16 +0000 Subject: Move pdfbookmark before section. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1706 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 4cba3e139..6ee701e8a 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1418,12 +1418,30 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_tip(self, node): self.depart_admonition() + def bookmark(self, node): + """Append latex href and pdfbookmarks for titles. + """ + if node.parent.hasattr('id'): + self.body.append('\\hypertarget{%s}{}\n' % node.parent['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 = node.astext().replace("_","\\_") + self.body.append('\\pdfbookmark[%d]{%s}{%s}\n' % \ + (l,text,node.parent['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. - if node.parent.hasattr('id'): - self.body.append('\\hypertarget{%s}{}' % node.parent['id']) + self.bookmark(node) # BUG: latex chokes on center environment with "perhaps a missing item". # so we use hfill. self.body.append('\\subsection*{~\\hfill ') @@ -1442,8 +1460,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('\n\n') self.body.append('%' + '_' * 75) self.body.append('\n\n') - if node.parent.hasattr('id'): - self.body.append('\\hypertarget{%s}{}\n' % node.parent['id']) + self.bookmark(node) # section_level 0 is title and handled above. # BUG: latex has no deeper sections (actually paragrah is no section either). if self.use_latex_toc: @@ -1463,21 +1480,6 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_title(self, node): self.body.append(self.context.pop()) - if isinstance(node.parent, nodes.sidebar): - return - # BUG level depends on style. - elif node.parent.hasattr('id') and not self.use_latex_toc: - # 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 = node.astext().replace("_","\\_") - self.body.append('\\pdfbookmark[%d]{%s}{%s}\n' % \ - (l,text,node.parent['id'])) def visit_topic(self, node): self.topic_class = node.get('class') -- cgit v1.2.1 From 20ec49f0e786ce9c9089de64987ebf2a11af9fc5 Mon Sep 17 00:00:00 2001 From: grubert Date: Wed, 24 Sep 2003 10:48:13 +0000 Subject: Option use-LaTeX-docinfo. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1708 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 6ee701e8a..c6cb0f991 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -76,6 +76,10 @@ class Writer(writers.Writer): ['--use-latex-toc'], {'default': 0, 'action': 'store_true', 'validator': frontend.validate_boolean}), + ('Let LaTeX print author and date, donot show it in docutils document info.', + ['--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'}),)) @@ -273,6 +277,7 @@ class LaTeXTranslator(nodes.NodeVisitor): nodes.NodeVisitor.__init__(self, document) self.settings = settings = document.settings 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.hyperlink_color = settings.hyperlink_color if self.hyperlink_color == '0': @@ -338,9 +343,8 @@ class LaTeXTranslator(nodes.NodeVisitor): # 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. - self.latex_docinfo = 0 self.head = [ ] - if not self.latex_docinfo: + if not self.use_latex_docinfo: self.head.extend( [ '\\author{}\n', '\\date{}\n' ] ) self.body_prefix = ['\\raggedbottom\n'] # separate title, so we can appen subtitle. @@ -687,23 +691,21 @@ class LaTeXTranslator(nodes.NodeVisitor): self.docinfo = None def visit_docinfo_item(self, node, name): - if not self.latex_docinfo: - self.docinfo.append('\\textbf{%s}: &\n\t' % self.language_label(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.latex_docinfo: + if self.use_latex_docinfo: self.head.append('\\author{%s}\n' % self.attval(node.astext())) raise nodes.SkipNode elif name == 'date': - if self.latex_docinfo: + if self.use_latex_docinfo: self.head.append('\\date{%s}\n' % self.attval(node.astext())) raise nodes.SkipNode + self.docinfo.append('\\textbf{%s}: &\n\t' % self.language_label(name)) if name == 'address': - # BUG will fail if latex_docinfo is set. self.insert_newline = 1 self.docinfo.append('{\\raggedright\n') self.context.append(' } \\\\\n') @@ -1435,6 +1437,7 @@ class LaTeXTranslator(nodes.NodeVisitor): text = node.astext().replace("_","\\_") self.body.append('\\pdfbookmark[%d]{%s}{%s}\n' % \ (l,text,node.parent['id'])) + def visit_title(self, node): """Only 3 section levels are supported by LaTeX article (AFAIR).""" -- cgit v1.2.1 From 84dacb089c046314ea28057eff98d3c7658709a6 Mon Sep 17 00:00:00 2001 From: grubert Date: Thu, 25 Sep 2003 07:51:19 +0000 Subject: Inside literal < and > need no mathmode. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1709 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index c6cb0f991..5505458ab 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -429,7 +429,7 @@ class LaTeXTranslator(nodes.NodeVisitor): # $ % & ~ _ ^ \ { } Escaping with a backslash does not help with backslashes, ~ and ^. - < > are only available in math-mode (really ?) + < > are only available in math-mode or tt font. (really ?) $ starts math- mode. AND quotes: @@ -452,8 +452,9 @@ class LaTeXTranslator(nodes.NodeVisitor): # then dollar text = text.replace("$", '{\\$}') # then all that needs math mode - text = text.replace("<", '{$<$}') - text = text.replace(">", '{$>$}') + if not ( self.literal_block or self.literal ): + text = text.replace("<", '{$<$}') + text = text.replace(">", '{$>$}') # then text = text.replace("&", '{\\&}') text = text.replace("_", '{\\_}') -- cgit v1.2.1 From 95be53b5dbc78847320e898b0808008a920b38ba Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 26 Sep 2003 18:30:16 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1711 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index f2a84088a..d84b90461 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -512,10 +512,11 @@ class TextElement(Element): """ An element which directly contains text. - Its children are all `Text` or `TextElement` nodes. You can check whether - an element's context is inline simply by checking whether it's immediate - parent is a `TextElement`. This is handy for nodes like `image` that can - appear both inline and as standalone body elements. + Its children are all `Text` or `TextElement` subclass nodes. You can + check whether an element's context is inline simply by checking whether + its immediate parent is a `TextElement` instance (including subclasses). + This is handy for nodes like `image` that can appear both inline and as + standalone body elements. """ child_text_separator = '' -- cgit v1.2.1 From 808849ba73aed90854d1b367d16cca03c5bca266 Mon Sep 17 00:00:00 2001 From: grubert Date: Sun, 28 Sep 2003 09:10:18 +0000 Subject: Test for multiple authors and LaTeX docinfo. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1712 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 5505458ab..99d42ec63 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -356,6 +356,8 @@ class LaTeXTranslator(nodes.NodeVisitor): self.topic_class = '' # column specification for tables self.colspecs = [] + # do we have one or more authors + self.author_stack = None # Flags to encode # --------------- # verbatim: to tell encode not to encode. @@ -535,13 +537,15 @@ class LaTeXTranslator(nodes.NodeVisitor): self.depart_docinfo_item(node) def visit_authors(self, node): - # ignore. visit_author is called for each one - # self.visit_docinfo_item(node, 'author') - pass + # not used: visit_author is called anyway for each author. + if self.use_latex_docinfo: + self.author_stack = [] def depart_authors(self, node): - # self.depart_docinfo_item(node) - pass + if self.use_latex_docinfo: + self.head.append('\\author{%s}\n' % \ + ' \\and '.join(self.author_stack) ) + self.author_stack = None def visit_block_quote(self, node): self.body.append( '\\begin{quote}\n') @@ -699,7 +703,10 @@ class LaTeXTranslator(nodes.NodeVisitor): else: self.pdfauthor += self.author_separator + self.attval(node.astext()) if self.use_latex_docinfo: - self.head.append('\\author{%s}\n' % self.attval(node.astext())) + if self.author_stack == None: + self.head.append('\\author{%s}\n' % self.attval(node.astext())) + else: + self.author_stack.append( self.attval(node.astext()) ) raise nodes.SkipNode elif name == 'date': if self.use_latex_docinfo: -- cgit v1.2.1 From fba72f8cdf65b12513c1e6ec405d5f84e24c44b5 Mon Sep 17 00:00:00 2001 From: cben Date: Thu, 9 Oct 2003 22:37:50 +0000 Subject: Propogate align attribute of a non-inline image to the surrounding

    tag (otherwise the image's horizontal alignment has no effect). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1718 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index b50552c03..2bfe1b1ca 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -761,7 +761,11 @@ class HTMLTranslator(nodes.NodeVisitor): if isinstance(node.parent, nodes.TextElement): self.context.append('') else: - self.body.append('

    ') + if atts.has_key('align'): + self.body.append('

    ' % + (self.attval(atts['align'],))) + else: + self.body.append('

    ') self.context.append('

    \n') self.body.append(self.emptytag(node, 'img', '', **atts)) -- cgit v1.2.1 From 3d83e266cd60737fdaed517259b67eed77411ad2 Mon Sep 17 00:00:00 2001 From: grubert Date: Sat, 18 Oct 2003 21:42:39 +0000 Subject: Fix: having too wide tables in sidebars. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1720 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 99d42ec63..8e4c41de7 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -115,6 +115,13 @@ Notes on LaTeX * 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: @@ -325,6 +332,11 @@ class LaTeXTranslator(nodes.NodeVisitor): # 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 seams 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['footnote_floats'] ) @@ -745,6 +757,7 @@ class LaTeXTranslator(nodes.NodeVisitor): 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): self.body_suffix.append('\\end{document}\n') @@ -1246,12 +1259,14 @@ class LaTeXTranslator(nodes.NodeVisitor): 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': ('---', ''), @@ -1329,7 +1344,7 @@ class LaTeXTranslator(nodes.NodeVisitor): latex_table_spec = "" for node in self.colspecs: colwidth = factor * float(node['colwidth']) / width - latex_table_spec += "|p{%.2f\\linewidth}" % colwidth + latex_table_spec += "|p{%.2f\\locallinewidth}" % colwidth self.colspecs = [] return latex_table_spec+"|" -- cgit v1.2.1 From 6219365dc5686d1bdd18762eaeec07a3126c5323 Mon Sep 17 00:00:00 2001 From: grubert Date: Wed, 29 Oct 2003 08:51:13 +0000 Subject: Fix a typo in LaTeX.txt. Fix vertical bar: by using textbar Change <> by using textless/greater. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1729 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 8e4c41de7..731845b6e 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -465,20 +465,23 @@ class LaTeXTranslator(nodes.NodeVisitor): # then dollar text = text.replace("$", '{\\$}') - # then all that needs math mode if not ( self.literal_block or self.literal ): - text = text.replace("<", '{$<$}') - text = text.replace(">", '{$>$}') + # the vertical bar: in mathmode |,\vert or \mid + # in textmode \textbar + text = text.replace("|", '{\\textbar}') + text = text.replace("<", '{\\textless}') + text = text.replace(">", '{\\textgreater}') # then text = text.replace("&", '{\\&}') 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("^", '{\\ensuremath{^\\wedge}}') + text = text.replace("^", '{\\textasciicircum}') text = text.replace("%", '{\\%}') text = text.replace("#", '{\\#}') - text = text.replace("~", '{\\~{ }}') + text = text.replace("~", '{\\textasciitilde}') if self.literal_block or self.literal: # pdflatex does not produce doublequotes for ngerman. text = self.babel.double_quotes_in_tt(text) -- cgit v1.2.1 From 89a74143a6633baa06f44899f8ac406ba9cb0a24 Mon Sep 17 00:00:00 2001 From: grubert Date: Fri, 31 Oct 2003 14:10:58 +0000 Subject: Fix: "#" needs protection in LaTeX. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1732 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 731845b6e..529221029 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1223,12 +1223,9 @@ class LaTeXTranslator(nodes.NodeVisitor): raise nodes.SkipNode def visit_reference(self, node): - # for pdflatex hyperrefs might be supported - if self.literal_block and (self.use_for_literal_block == "mbox"): - # mbox does not like the '#' - hash_char = '\\#' - else: - hash_char = '#' + # 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'] -- cgit v1.2.1 From a64ff7ddc4a8637fd9dda75947e93c005ee4a2de Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 7 Nov 2003 14:48:26 +0000 Subject: fixed off-by-1 error with extra whitespace after substitution definition directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1733 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 82ae15791..d85ad8dae 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1949,7 +1949,7 @@ class Body(RSTState): raise MarkupError('malformed substitution definition.', lineno) del block[:blockindex] # strip out the substitution marker - block[0] = (block[0] + ' ')[subdefmatch.end()-len(escaped)-1:].strip() + block[0] = (block[0].strip() + ' ')[subdefmatch.end()-len(escaped)-1:-1] if not block[0]: del block[0] offset += 1 -- cgit v1.2.1 From 899263f55439c95856d51e861e7008d7bddfe2b0 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 14 Nov 2003 15:04:54 +0000 Subject: updated config warning git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1739 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 5a52ff980..5267bcf84 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -548,8 +548,9 @@ class ConfigParser(CP.ConfigParser): old_warning = """ The "[option]" section is deprecated. Support for old-format configuration -files will be removed in a future Docutils release. Please revise your -configuration files. See . +files may be removed in a future Docutils release. Please revise your +configuration files. See , section +"Old-Format Configuration Files". """ def read(self, filenames, option_parser): -- cgit v1.2.1 From 9810caa640eceab1a8c3f73c8c5ce5a7fd1f2bee Mon Sep 17 00:00:00 2001 From: lalo Date: Mon, 1 Dec 2003 03:48:50 +0000 Subject: adding pt-br language files git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1753 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/pt-br.py | 62 ++++++++++++++++++++++ docutils/parsers/rst/languages/pt-br.py | 94 +++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 docutils/languages/pt-br.py create mode 100644 docutils/parsers/rst/languages/pt-br.py (limited to 'docutils') diff --git a/docutils/languages/pt-br.py b/docutils/languages/pt-br.py new file mode 100644 index 000000000..5a1be4f8a --- /dev/null +++ b/docutils/languages/pt-br.py @@ -0,0 +1,62 @@ +# 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. + +""" +Brazilian Portuguese-language mappings for language-dependent features of Docutils. +""" + +__docformat__ = 'reStructuredText' + +labels = { + # fixed: language-dependent + 'author': u'Autor', + 'authors': u'Autores', + 'organization': unicode('Organizao', 'latin1'), + 'address': unicode('Endereo', 'latin1'), + 'contact': u'Contato', + 'version': unicode('Verso', 'latin1'), + 'revision': unicode('Reviso', 'latin1'), + 'status': u'Estado', + 'date': u'Data', + 'copyright': u'Copyright', + 'dedication': unicode('Dedicatria', 'latin1'), + 'abstract': u'Resumo', + 'attention': unicode('Atteno!', 'latin1'), + 'caution': u'Cuidado!', + 'danger': u'PERIGO!', + 'error': u'Erro', + 'hint': unicode('Sugesto', 'latin1'), + 'important': u'Importante', + 'note': u'Nota', + 'tip': u'Dica', + 'warning': u'Aviso', + 'contents': unicode('Sumrio', 'latin1')} +"""Mapping of node class name to label text.""" + +bibliographic_fields = { + # language-dependent: fixed + u'autor': 'author', + u'autores': 'authors', + unicode('organizao', 'latin1'): 'organization', + unicode('endereo', 'latin1'): 'address', + u'contato': 'contact', + unicode('verso', 'latin1'): 'version', + unicode('reviso', 'latin1'): 'revision', + u'estado': 'status', + u'data': 'date', + u'copyright': 'copyright', + unicode('dedicatria', 'latin1'): 'dedication', + u'resumo': 'abstract'} +"""English (lowcased) to canonical name mapping for bibliographic fields.""" + +author_separators = [';', ','] +"""List of separator strings for the 'Authors' bibliographic field. Tried in +order.""" diff --git a/docutils/parsers/rst/languages/pt-br.py b/docutils/parsers/rst/languages/pt-br.py new file mode 100644 index 000000000..5fc68218a --- /dev/null +++ b/docutils/parsers/rst/languages/pt-br.py @@ -0,0 +1,94 @@ +# 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. + +""" +Brazilian Portuguese-language mappings for language-dependent features of +reStructuredText. +""" + +__docformat__ = 'reStructuredText' + + +directives = { + # language-dependent: fixed + u'ateno': 'attention', + 'cuidado': 'caution', + 'perigo': 'danger', + 'erro': 'error', + u'sugesto': 'hint', + 'importante': 'important', + 'nota': 'note', + 'dica': 'tip', + 'aviso': 'warning', + u'exortao': 'admonition', + 'barra-lateral': 'sidebar', + u'tpico': 'topic', + 'bloco-de-linhas': 'line-block', + 'literal-interpretado': 'parsed-literal', + 'rubrica': 'rubric', + u'epgrafo': 'epigraph', + 'destaques': 'highlights', + u'citao-destacada': 'pull-quote', + #'perguntas': 'questions', + #'qa': 'questions', + #'faq': 'questions', + 'meta': 'meta', + #'imagemap': 'imagemap', + 'imagem': 'image', + 'figura': 'figure', + u'incluso': 'include', + 'cru': 'raw', + u'substituio': 'replace', + 'unicode': 'unicode', + 'classe': 'class', + u'ndice': 'contents', + 'numsec': 'sectnum', + u'numerao-de-sees': 'sectnum', + #u'notas-de-rorap': 'footnotes', + #u'citaes': 'citations', + u'links-no-rodap': 'target-notes', + 'restructuredtext-test-directive': 'restructuredtext-test-directive'} +"""English name to registered (in directives/__init__.py) directive name +mapping.""" + +roles = { + # language-dependent: fixed + u'abbreviao': 'abbreviation', + 'ab': 'abbreviation', + u'acrnimo': 'acronym', + 'ac': 'acronym', + u'ndice-remissivo': 'index', + 'i': 'index', + 'subscrito': 'subscript', + 'sub': 'subscript', + 'sobrescrito': 'superscript', + 'sob': 'superscript', + u'referncia-a-ttulo': 'title-reference', + u'ttulo': 'title-reference', + 't': 'title-reference', + u'referncia-a-pep': 'pep-reference', + 'pep': 'pep-reference', + u'referncia-a-rfc': 'rfc-reference', + 'rfc': 'rfc-reference', + u'nfase': 'emphasis', + 'forte': 'strong', + 'literal': 'literal', + u'referncia-por-nome': 'named-reference', + u'referncia-annima': 'anonymous-reference', + u'referncia-a-nota-de-rodap': 'footnote-reference', + u'referncia-a-citao': 'citation-reference', + u'referncia-a-substituio': 'substitution-reference', + 'alvo': 'target', + u'referncia-a-uri': 'uri-reference', + 'uri': 'uri-reference', + 'url': 'uri-reference',} +"""Mapping of English role names to canonical role names for interpreted text. +""" -- cgit v1.2.1 From 2e95c0e9f28c1d319a4497773d426804a36dd027 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 11 Dec 2003 19:49:10 +0000 Subject: bugfix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1765 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index ab154b6e2..0bdd3f517 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -156,7 +156,7 @@ class FileInput(Input): print >>sys.stderr, '%s: %s' % (error.__class__.__name__, error) print >>sys.stderr, ( - 'Unable to open source file for reading (%s). Exiting.' + 'Unable to open source file for reading (%r). Exiting.' % source_path) sys.exit(1) else: @@ -224,7 +224,7 @@ class FileOutput(Output): print >>sys.stderr, '%s: %s' % (error.__class__.__name__, error) print >>sys.stderr, ('Unable to open destination file for writing ' - '(%s). Exiting.' % source_path) + '(%r). Exiting.' % self.destination_path) sys.exit(1) self.opened = 1 -- cgit v1.2.1 From 1a045085cb46a990840be96ba284f850aaf8491d Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 15 Dec 2003 14:13:55 +0000 Subject: added Czech-language mappings by Marek Blaha git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1767 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/cs.py | 62 ++++++++++++++++++++++++ docutils/parsers/rst/languages/cs.py | 94 ++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 docutils/languages/cs.py create mode 100644 docutils/parsers/rst/languages/cs.py (limited to 'docutils') diff --git a/docutils/languages/cs.py b/docutils/languages/cs.py new file mode 100644 index 000000000..5e25800eb --- /dev/null +++ b/docutils/languages/cs.py @@ -0,0 +1,62 @@ +# Author: Marek Blaha +# Contact: mb@dat.cz +# 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. + +""" +Czech-language mappings for language-dependent features of Docutils. +""" + +__docformat__ = 'reStructuredText' + +labels = { + # fixed: language-dependent + 'author': u'Autor', + 'authors': u'Auto\u0159i', + 'organization': u'Organizace', + 'address': u'Adresa', + 'contact': u'Kontakt', + 'version': u'Verze', + 'revision': u'Revize', + 'status': u'Stav', + 'date': u'Datum', + 'copyright': u'Copyright', + 'dedication': u'V\u011Bnov\u00E1n\u00ED', + 'abstract': u'Abstrakt', + 'attention': u'Pozor!', + 'caution': u'Opatrn\u011B!', + 'danger': u'!NEBEZPE\u010C\u00CD!', + 'error': u'Chyba', + 'hint': u'Rada', + 'important': u'D\u016Fle\u017Eit\u00E9', + 'note': u'Pozn\u00E1mka', + 'tip': u'Tip', + 'warning': u'Varov\u00E1n\u00ED', + 'contents': u'Obsah'} +"""Mapping of node class name to label text.""" + +bibliographic_fields = { + # language-dependent: fixed + u'autor': 'author', + u'auto\u0159i': 'authors', + u'organizace': 'organization', + u'adresa': 'address', + u'kontakt': 'contact', + u'verze': 'version', + u'revize': 'revision', + u'stav': 'status', + u'datum': 'date', + u'copyright': 'copyright', + u'v\u011Bnov\u00E1n\u00ED': 'dedication', + u'abstrakt': 'abstract'} +"""Czech (lowcased) to canonical name mapping for bibliographic fields.""" + +author_separators = [';', ','] +"""List of separator strings for the 'Authors' bibliographic field. Tried in +order.""" diff --git a/docutils/parsers/rst/languages/cs.py b/docutils/parsers/rst/languages/cs.py new file mode 100644 index 000000000..45fb5e657 --- /dev/null +++ b/docutils/parsers/rst/languages/cs.py @@ -0,0 +1,94 @@ +# Author: Marek Blaha +# Contact: mb@dat.cz +# 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. + +""" +Czech-language mappings for language-dependent features of +reStructuredText. +""" + +__docformat__ = 'reStructuredText' + + +directives = { + # language-dependent: fixed + u'pozor': 'attention', + u'caution': 'caution', # jak rozlisit caution a warning? + u'nebezpe\u010D\u00ED': 'danger', + u'chyba': 'error', + u'rada': 'hint', + u'd\u016Fle\u017Eit\u00E9': 'important', + u'pozn\u00E1mka': 'note', + u'tip': 'tip', + u'varov\u00E1n\u00ED': 'warning', + u'admonition': 'admonition', + u'sidebar': 'sidebar', + u't\u00E9ma': 'topic', + u'line-block': 'line-block', + u'parsed-literal': 'parsed-literal', + u'odd\u00EDl': 'rubric', + u'moto': 'epigraph', + u'highlights': 'highlights', + u'pull-quote': 'pull-quote', + #'questions': 'questions', + #'qa': 'questions', + #'faq': 'questions', + u'meta': 'meta', + #'imagemap': 'imagemap', + u'image': 'image', # obrazek + u'figure': 'figure', # a tady? + u'include': 'include', + u'raw': 'raw', + u'replace': 'replace', + u'unicode': 'unicode', + u't\u0159\u00EDda': 'class', + u'obsah': 'contents', + u'sectnum': 'sectnum', + u'section-numbering': 'sectnum', + #'footnotes': 'footnotes', + #'citations': 'citations', + u'target-notes': 'target-notes', + u'restructuredtext-test-directive': 'restructuredtext-test-directive'} +"""Czech name to registered (in directives/__init__.py) directive name +mapping.""" + +roles = { + # language-dependent: fixed + u'abbreviation': 'abbreviation', + u'ab': 'abbreviation', + u'acronym': 'acronym', + u'ac': 'acronym', + u'index': 'index', + u'i': 'index', + u'subscript': 'subscript', + u'sub': 'subscript', + u'superscript': 'superscript', + u'sup': 'superscript', + u'title-reference': 'title-reference', + u'title': 'title-reference', + u't': 'title-reference', + u'pep-reference': 'pep-reference', + u'pep': 'pep-reference', + u'rfc-reference': 'rfc-reference', + u'rfc': 'rfc-reference', + u'emphasis': 'emphasis', + u'strong': 'strong', + u'literal': 'literal', + u'named-reference': 'named-reference', + u'anonymous-reference': 'anonymous-reference', + u'footnote-reference': 'footnote-reference', + u'citation-reference': 'citation-reference', + u'substitution-reference': 'substitution-reference', + u'target': 'target', + u'uri-reference': 'uri-reference', + u'uri': 'uri-reference', + u'url': 'uri-reference',} +"""Mapping of Czech role names to canonical role names for interpreted text. +""" -- cgit v1.2.1 From d23a3c4b16da560d3ecabd47f10caea757ddf532 Mon Sep 17 00:00:00 2001 From: grubert Date: Wed, 17 Dec 2003 06:46:51 +0000 Subject: Fix: Allow a list items text to start with a brackett "[" (needs "{}"). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1770 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 529221029..097bc7bf4 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1074,7 +1074,9 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('\n\\end{flushleft}\n') def visit_list_item(self, node): - self.body.append('\\item ') + # HACK append "{}" in case the next character is "[", which would break + # LaTeX's list environment (no numbering and the "[" is not printed). + self.body.append('\\item {} ') def depart_list_item(self, node): self.body.append('\n') -- cgit v1.2.1 From c5e249ae47c1c7b96367b911b7aa7817ba85c797 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 19 Dec 2003 14:30:13 +0000 Subject: Added inline markup parsing to field lists' field names git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1771 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index d85ad8dae..be0ab922d 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1494,8 +1494,9 @@ class Body(RSTState): 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)) + name_nodes, name_messages = self.inline_text(name, lineno) + fieldnode += nodes.field_name(name, '', *name_nodes) + fieldbody = nodes.field_body('\n'.join(indented), *name_messages) fieldnode += fieldbody if indented: self.parse_field_body(indented, line_offset, fieldbody) -- cgit v1.2.1 From 19c14c68f9ae90da3cc2595df2eb74a9f56a9115 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 19 Dec 2003 14:35:47 +0000 Subject: improved some naming git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1772 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index be0ab922d..0d4e6ab03 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1472,15 +1472,15 @@ class Body(RSTState): def field_marker(self, match, context, next_state): """Field list item.""" - fieldlist = nodes.field_list() - self.parent += fieldlist + field_list = nodes.field_list() + self.parent += field_list field, blank_finish = self.field(match) - fieldlist += field + field_list += field offset = self.state_machine.line_offset + 1 # next line newline_offset, blank_finish = self.nested_list_parse( self.state_machine.input_lines[offset:], input_offset=self.state_machine.abs_line_offset() + 1, - node=fieldlist, initial_state='FieldList', + node=field_list, initial_state='FieldList', blank_finish=blank_finish) self.goto_line(newline_offset) if not blank_finish: @@ -1492,15 +1492,15 @@ class Body(RSTState): 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 + field_node = nodes.field() + field_node.line = lineno name_nodes, name_messages = self.inline_text(name, lineno) - fieldnode += nodes.field_name(name, '', *name_nodes) - fieldbody = nodes.field_body('\n'.join(indented), *name_messages) - fieldnode += fieldbody + field_node += nodes.field_name(name, '', *name_nodes) + field_body = nodes.field_body('\n'.join(indented), *name_messages) + field_node += field_body if indented: - self.parse_field_body(indented, line_offset, fieldbody) - return fieldnode, blank_finish + self.parse_field_body(indented, line_offset, field_body) + return field_node, blank_finish def parse_field_marker(self, match): """Extract & return field name from a field marker match.""" -- cgit v1.2.1 From f74494c19b8a9de8a1bb4d6c2acce694b24d802b Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 20 Dec 2003 18:48:23 +0000 Subject: Added support for quoted (and unindented) literal blocks. Driven in part by a bribe from Frank Siebenlist (thanks!). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1773 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 102 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 91 insertions(+), 11 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 0d4e6ab03..571fe8f42 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -274,7 +274,7 @@ class RSTState(StateWS): state_machine.unlink() new_offset = state_machine.abs_line_offset() # No `block.parent` implies disconnected -- lines aren't in sync: - if block.parent: + if block.parent and (len(block) - block_length) != 0: # Adjustment for block if modified in nested parse: self.state_machine.next_line(len(block) - block_length) return new_offset @@ -2661,20 +2661,29 @@ class Text(RSTState): """Return a list of nodes.""" indented, indent, offset, blank_finish = \ self.state_machine.get_indented() - nodelist = [] while indented and not indented[-1].strip(): indented.trim_end() - if indented: - data = '\n'.join(indented) - nodelist.append(nodes.literal_block(data, data)) - if not blank_finish: - nodelist.append(self.unindent_warning('Literal block')) - else: - nodelist.append(self.reporter.warning( - 'Literal block expected; none found.', - line=self.state_machine.abs_line_number())) + if not indented: + return self.quoted_literal_block() + nodelist = [] + data = '\n'.join(indented) + nodelist.append(nodes.literal_block(data, data)) + if not blank_finish: + nodelist.append(self.unindent_warning('Literal block')) return nodelist + def quoted_literal_block(self): + abs_line_offset = self.state_machine.abs_line_offset() + offset = self.state_machine.line_offset + parent_node = nodes.Element() + new_abs_offset = self.nested_parse( + self.state_machine.input_lines[offset:], + input_offset=abs_line_offset, node=parent_node, match_titles=0, + state_machine_kwargs={'state_classes': (QuotedLiteralBlock,), + 'initial_state': 'QuotedLiteralBlock'}) + self.goto_line(new_abs_offset) + return parent_node.children + def definition_list_item(self, termline): indented, indent, line_offset, blank_finish = \ self.state_machine.get_indented() @@ -2891,6 +2900,77 @@ class Line(SpecializedText): raise statemachine.StateCorrection('Body', 'text') +class QuotedLiteralBlock(RSTState): + + """ + Nested parse handler for quoted (unindented) literal blocks. + + Special-purpose. Not for inclusion in `state_classes`. + """ + + patterns = {'initial_quoted': r'(%(nonalphanum7bit)s)' % Body.pats, + 'text': r''} + initial_transitions = ('initial_quoted', 'text') + + def __init__(self, state_machine, debug=0): + RSTState.__init__(self, state_machine, debug) + self.messages = [] + self.initial_lineno = None + + def blank(self, match, context, next_state): + if context: + raise EOFError + else: + return context, next_state, [] + + def eof(self, context): + if context: + text = '\n'.join(context) + literal_block = nodes.literal_block(text, text) + literal_block.line = self.initial_lineno + self.parent += literal_block + else: + self.parent += self.reporter.warning( + 'Literal block expected; none found.', + line=self.state_machine.abs_line_number()) + self.state_machine.previous_line() + self.parent += self.messages + return [] + + def indent(self, match, context, next_state): + assert context, ('QuotedLiteralBlock.indent: context should not ' + 'be empty!') + self.messages.append( + self.reporter.error('Unexpected indentation.', + line=self.state_machine.abs_line_number())) + self.state_machine.previous_line() + raise EOFError + + def initial_quoted(self, match, context, next_state): + """Match arbitrary quote character on the first line only.""" + self.remove_transition('initial_quoted') + quote = match.string[0] + pattern = re.compile(re.escape(quote)) + # New transition matches consistent quotes only: + self.add_transition('quoted', + (pattern, self.quoted, self.__class__.__name__)) + self.initial_lineno = self.state_machine.abs_line_number() + return [match.string], next_state, [] + + def quoted(self, match, context, next_state): + """Match consistent quotes on subsequent lines.""" + context.append(match.string) + return context, next_state, [] + + def text(self, match, context, next_state): + if context: + self.messages.append( + self.reporter.error('Inconsistent literal block quoting.', + line=self.state_machine.abs_line_number())) + self.state_machine.previous_line() + raise EOFError + + state_classes = (Body, BulletList, DefinitionList, EnumeratedList, FieldList, OptionList, ExtensionOptions, Explicit, Text, Definition, Line, SubstitutionDef, RFC2822Body, RFC2822List) -- cgit v1.2.1 From e4bb28bf3f6655e31095bf801d50c35566c6dc52 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 21 Dec 2003 02:32:02 +0000 Subject: beefed up directive error reporting git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1774 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index c63fee6a0..fdddb6c9d 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -165,18 +165,29 @@ 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)) return None, messages if _modules.has_key(modulename): module = _modules[modulename] else: try: module = __import__(modulename, globals(), locals()) - except ImportError: + except ImportError, detail: + messages.append(document.reporter.error( + 'Error importing directive module "%s" (directive "%s"):\n%s' + % (modulename, directive_name, detail), + line=document.current_line)) return None, messages try: function = getattr(module, functionname) _directives[normname] = function except AttributeError: + messages.append(document.reporter.error( + 'No function "%s" in module "%s" (directive "%s").' + % (functionname, modulename, directive_name), + line=document.current_line)) return None, messages return function, messages -- cgit v1.2.1 From 0029088b1ff3335c7beae49ca03f4ddd7d0e5381 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 21 Dec 2003 02:46:40 +0000 Subject: Isolated the import of the ``urllib2`` module; was causing problems on SourceForge (``libssl.so.2`` unavailable?). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1775 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index a567ac9e2..446935831 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -11,11 +11,15 @@ __docformat__ = 'reStructuredText' import sys import os.path import re -from urllib2 import urlopen, URLError from docutils import io, nodes, statemachine, utils from docutils.parsers.rst import directives, states from docutils.transforms import misc +try: + import urllib2 +except ImportError: + urllib2 = None + def include(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): @@ -97,9 +101,16 @@ def raw(name, arguments, options, content, lineno, raw_file.close() attributes['source'] = path elif options.has_key('url'): + if not urllib2: + severe = state_machine.reporter.severe( + 'Problems with the "%s" directive and its "url" option: ' + 'unable to access the required functionality (from the ' + '"urllib2" module).' % name, + nodes.literal_block(block_text, block_text), line=lineno) + return [severe] try: - raw_file = urlopen(options['url']) - except (URLError, IOError, OSError), error: + raw_file = urllib2.urlopen(options['url']) + except (urllib2.URLError, IOError, OSError), error: severe = state_machine.reporter.severe( 'Problems with "%s" directive URL "%s":\n%s.' % (name, options['url'], error), -- cgit v1.2.1 From 1a9d3d2ed89b62a7ed5126355e3f11b70ed1e5c1 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 24 Dec 2003 15:05:18 +0000 Subject: Upon reviewing RFC 2396, I see that asterisks are valid URL characters, sometimes actually used. There's a conflict with emphasis, but backslash escapes should overcome that (they didn't). This fixes a bug in the parser that escaped asterisks in URLs weren't recognized. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1778 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 571fe8f42..1c9b65f20 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -601,11 +601,12 @@ class Inliner: non_whitespace_after = r'(?![ \n])' # Alphanumerics with isolated internal [-._] chars (i.e. not 2 together): simplename = r'(?:(?!_)\w)+(?:[-._](?:(?!_)\w)+)*' - # Valid URI characters (see RFC 2396 & RFC 2732): - uric = r"""[-_.!~*'()[\];/:@&=+$,%a-zA-Z0-9]""" + # Valid URI characters (see RFC 2396 & RFC 2732); + # final \x00 allows backslash escapes in URIs: + uric = r"""[-_.!~*'()[\];/:@&=+$,%a-zA-Z0-9\x00]""" # Last URI character; same as uric but no punctuation: urilast = r"""[_~/a-zA-Z0-9]""" - emailc = r"""[-_!~*'{|}/#?^`&=+$%a-zA-Z0-9]""" + emailc = r"""[-_!~*'{|}/#?^`&=+$%a-zA-Z0-9\x00]""" email_pattern = r""" %(emailc)s+(?:\.%(emailc)s+)* # name @ # at -- cgit v1.2.1 From 37babfef0811bc5cfeaa92d5ec04d8c68904aafe Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 24 Dec 2003 15:18:55 +0000 Subject: updated URI schemes mapping & links git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1779 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/urischemes.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/urischemes.py b/docutils/urischemes.py index 6eb45820a..05ba20415 100644 --- a/docutils/urischemes.py +++ b/docutils/urischemes.py @@ -1,7 +1,8 @@ """ `schemes` is a dictionary with lowercase URI addressing schemes as keys and descriptions as values. It was compiled from the index at -http://www.w3.org/Addressing/schemes.html (revised 2001-08-20). +http://www.iana.org/assignments/uri-schemes (revised 2003-11-26) +and an older list at http://www.w3.org/Addressing/schemes.html. """ # Many values are blank and should be filled in with useful descriptions. @@ -30,6 +31,7 @@ schemes = { 'finger': '', 'freenet': '', 'ftp': 'File Transfer Protocol', + 'go': 'go; RFC3368', 'gopher': 'The Gopher Protocol', 'gsm-sms': ('Global System for Mobile Communications Short Message ' 'Service'), @@ -42,6 +44,7 @@ schemes = { 'https': 'HTTP over SSL', 'iioploc': 'Internet Inter-ORB Protocol Location?', 'ilu': 'Inter-Language Unification', + 'im': 'Instant Messaging', 'imap': 'Internet Message Access Protocol', 'ior': 'CORBA interoperable object reference', 'ipp': 'Internet Printing Protocol', @@ -62,6 +65,7 @@ schemes = { 'mocha': '', 'modem': ('a connection to a terminal that can handle incoming data ' 'calls; RFC 2806'), + 'mupdate': 'Mailbox Update (MUPDATE) Protocol', 'news': 'USENET news', 'nfs': 'Network File System protocol', 'nntp': 'USENET news using NNTP access', @@ -69,6 +73,7 @@ schemes = { 'phone': '', 'pop': 'Post Office Protocol', 'pop3': 'Post Office Protocol v3', + 'pres': 'Presence', 'printer': '', 'prospero': 'Prospero Directory Service', 'res': '', @@ -80,8 +85,11 @@ schemes = { 'service': 'service location', 'shttp': 'secure hypertext transfer protocol', 'sip': 'Session Initiation Protocol', + 'sips': 'secure session intitiaion protocol', 'smb': '', 'snews': 'For NNTP postings via SSL', + 'soap.beep': '', + 'soap.beeps': '', 't120': 'real time data conferencing (audiographics)', 'tcp': '', 'tel': ('a connection to a terminal that handles normal voice ' @@ -90,6 +98,7 @@ schemes = { 'RFC 2806.'), 'telephone': 'telephone', 'telnet': 'Reference to interactive sessions', + 'tftp': 'Trivial File Transfer Protocol', 'tip': 'Transaction Internet Protocol', 'tn3270': 'Interactive 3270 emulation sessions', 'tv': '', @@ -101,5 +110,7 @@ schemes = { 'wais': 'Wide Area Information Servers', 'whodp': '', 'whois++': 'Distributed directory service.', + 'xmlrpc.beep': '', + 'xmlrpc.beeps': '', 'z39.50r': 'Z39.50 Retrieval', 'z39.50s': 'Z39.50 Session',} -- cgit v1.2.1 From 4e174f882eb88ad4fd1e41e785a5c21e347e0c53 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 24 Dec 2003 15:51:38 +0000 Subject: Made embedded-URIs' reference text omittable. Idea from Beni Cherniavsky. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1781 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 1c9b65f20..9e048099d 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -660,10 +660,10 @@ class Inliner: embedded_uri=re.compile( r""" ( - [ \n]+ # spaces or beginning of line + (?:[ \n]+|^) # spaces or beginning of line/string < # open bracket %(non_whitespace_after)s - ([^<>\0]+) # anything but angle brackets & nulls + ([^<>\x00]+) # anything but angle brackets & nulls %(non_whitespace_before)s > # close bracket w/o whitespace before ) @@ -862,6 +862,8 @@ class Inliner: target = nodes.target(match.group(1), refuri=uri) else: raise ApplicationError('problem with URI: %r' % uri_text) + if not text: + text = uri else: target = None refname = normalize_name(text) -- cgit v1.2.1 From 101664a3673ff51de5ab0fe799e6c182ff25000f Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 30 Dec 2003 04:02:37 +0000 Subject: typos git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1784 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 5267bcf84..9066765d8 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -346,7 +346,7 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): {'metavar': '', 'default': 'utf-8', 'validator': validate_encoding_and_error_handler}), (SUPPRESS_HELP, # usually handled by --output-encoding - ['--output_encoding_error_handler'], + ['--output-encoding-error-handler'], {'default': 'strict', 'validator': validate_encoding_error_handler}), ('Specify the text encoding for error output. Default is ASCII. ' 'Optionally also specify the encoding error handler for unencodable ' @@ -357,7 +357,7 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): {'metavar': '', 'default': 'ascii', 'validator': validate_encoding_and_error_handler}), (SUPPRESS_HELP, # usually handled by --error-encoding - ['--error_encoding_error_handler'], + ['--error-encoding-error-handler'], {'default': default_error_encoding_error_handler, 'validator': validate_encoding_error_handler}), ('Specify the language of input text (ISO 639 2-letter identifier).' -- cgit v1.2.1 From 4f3cca455c06f867e63961e0425603713e74f09f Mon Sep 17 00:00:00 2001 From: david_abrahams Date: Thu, 1 Jan 2004 16:47:53 +0000 Subject: Improve diagnostic output by putting the name of the offending writer in the exception. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1786 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index d84b90461..9334834a8 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1273,8 +1273,8 @@ class NodeVisitor: Raise an exception unless overridden. """ - raise NotImplementedError('visiting unknown node type: %s' - % node.__class__.__name__) + raise NotImplementedError('%s visiting unknown node type: %s' + % (self.__class__, node.__class__.__name__)) def unknown_departure(self, node): """ @@ -1282,8 +1282,8 @@ class NodeVisitor: Raise exception unless overridden. """ - raise NotImplementedError('departing unknown node type: %s' - % node.__class__.__name__) + raise NotImplementedError('%s departing unknown node type: %s' + % (self.__class__, node.__class__.__name__)) class SparseNodeVisitor(NodeVisitor): -- cgit v1.2.1 From 039fed03ef0309339d55487713e24dbfec59a36b Mon Sep 17 00:00:00 2001 From: david_abrahams Date: Thu, 1 Jan 2004 17:42:52 +0000 Subject: Implemented super/subscript handling. Still problematic because it italicizes all letters, but not bad. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1787 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 097bc7bf4..07cce243d 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -388,7 +388,9 @@ class LaTeXTranslator(nodes.NodeVisitor): # inside literal block: no quote mangling. self.literal_block = 0 self.literal = 0 - + # true when encoding in math mode + self.mathmode = 0 + def get_stylesheet_reference(self): if self.settings.stylesheet_path: return self.settings.stylesheet_path @@ -465,7 +467,7 @@ class LaTeXTranslator(nodes.NodeVisitor): # then dollar text = text.replace("$", '{\\$}') - if not ( self.literal_block or self.literal ): + if not ( self.literal_block or self.literal or self.mathmode ): # the vertical bar: in mathmode |,\vert or \mid # in textmode \textbar text = text.replace("|", '{\\textbar}') @@ -582,6 +584,25 @@ class LaTeXTranslator(nodes.NodeVisitor): 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{' ) -- cgit v1.2.1 From 69e7ed1f66cc19205efaa870de5f76a30fdc09c4 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 4 Jan 2004 17:34:17 +0000 Subject: Refactored explicit target processing code git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1790 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 85 ++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 45 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 9e048099d..26f55c566 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1880,30 +1880,48 @@ class Body(RSTState): raise MarkupError('malformed hyperlink target.', lineno) del block[:blockindex] block[0] = (block[0] + ' ')[targetmatch.end()-len(escaped)-1:].strip() + target = self.make_target(block, blocktext, lineno, + targetmatch.group('name')) + return [target], blank_finish + + def make_target(self, block, block_text, lineno, target_name): + target_type, data = self.parse_target(block, block_text, lineno) + if target_type == 'refname': + target = nodes.target(block_text, '', refname=data) + self.add_target(target_name, '', target, lineno) + self.document.note_indirect_target(target) + return target + elif target_type == 'refuri': + target = nodes.target(block_text, '') + self.add_target(target_name, data, target, lineno) + return target + else: + return data + + def parse_target(self, block, block_text, lineno): + """ + Determine the type of reference of a target. + + :Return: A 2-tuple, one of: + + - 'refname' and the indirect reference name + - 'refuri' and the URI + - 'malformed' and a system_message node + """ if block and block[-1].strip()[-1:] == '_': # possible indirect target reference = ' '.join([line.strip() for line in block]) refname = self.is_reference(reference) if refname: - target = nodes.target(blocktext, '', refname=refname) - target.line = lineno - self.add_target(targetmatch.group('name'), '', target) - self.document.note_indirect_target(target) - return [target], blank_finish - nodelist = [] + return 'refname', refname reference = ''.join([line.strip() for line in block]) - if reference.find(' ') != -1: + if reference.find(' ') == -1: + return 'refuri', unescape(reference) + else: warning = self.reporter.warning( 'Hyperlink target contains whitespace. Perhaps a footnote ' 'was intended?', - nodes.literal_block(blocktext, blocktext), line=lineno) - nodelist.append(warning) - else: - unescaped = unescape(reference) - target = nodes.target(blocktext, '') - target.line = lineno - self.add_target(targetmatch.group('name'), unescaped, target) - nodelist.append(target) - return nodelist, blank_finish + nodes.literal_block(block_text, block_text), line=lineno) + return 'malformed', warning def is_reference(self, reference): match = self.explicit.patterns.reference.match( @@ -1912,7 +1930,8 @@ class Body(RSTState): return None return unescape(match.group('simple') or match.group('phrase')) - def add_target(self, targetname, refuri, target): + def add_target(self, targetname, refuri, target, lineno): + target.line = lineno if targetname: name = normalize_name(unescape(targetname)) target['name'] = name @@ -2255,38 +2274,14 @@ class Body(RSTState): return [], next_state, [] def anonymous_target(self, match): + lineno = self.state_machine.abs_line_number() block, indent, offset, blank_finish \ = self.state_machine.get_first_known_indented(match.end(), until_blank=1) blocktext = match.string[:match.end()] + '\n'.join(block) - if block and block[-1].strip()[-1:] == '_': # possible indirect target - reference = escape2null(' '.join([line.strip() - for line in block])) - refname = self.is_reference(reference) - if refname: - target = nodes.target(blocktext, '', refname=refname, - anonymous=1) - self.document.note_anonymous_target(target) - self.document.note_indirect_target(target) - return [target], blank_finish - nodelist = [] - reference = escape2null(''.join([line.strip() for line in block])) - if reference.find(' ') != -1: - lineno = self.state_machine.abs_line_number() - len(block) + 1 - warning = self.reporter.warning( - 'Anonymous hyperlink target contains whitespace. Perhaps a ' - 'footnote was intended?', - nodes.literal_block(blocktext, blocktext), - line=lineno) - nodelist.append(warning) - else: - target = nodes.target(blocktext, '', anonymous=1) - if reference: - unescaped = unescape(reference) - target['refuri'] = unescaped - self.document.note_anonymous_target(target) - nodelist.append(target) - return nodelist, blank_finish + block = [escape2null(line) for line in block] + target = self.make_target(block, blocktext, lineno, '') + return [target], blank_finish def line(self, match, context, next_state): """Section title overline or transition marker.""" -- cgit v1.2.1 From 10a6b744053a86b58f789caa23bfac62c1afa5fb Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 4 Jan 2004 17:35:33 +0000 Subject: Added "target" option to "image" directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1791 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/images.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index d193edffd..a835d3d74 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -13,7 +13,7 @@ __docformat__ = 'reStructuredText' import sys from docutils import nodes, utils -from docutils.parsers.rst import directives +from docutils.parsers.rst import directives, states try: import Image # PIL @@ -34,8 +34,22 @@ def image(name, arguments, options, content, lineno, nodes.literal_block(block_text, block_text), line=lineno) return [error] options['uri'] = reference - image_node = nodes.image(block_text, **options) - return [image_node] + if options.has_key('target'): + block = states.escape2null(options['target']).splitlines() + block = [line for line in block] + target_type, data = state.parse_target(block, block_text, lineno) + if target_type == 'refuri': + node_list = nodes.reference(refuri=data) + elif target_type == 'refname': + node_list = nodes.reference(refname=data) + state.document.note_refname(node_list) + else: # malformed target + node_list = [data] # data is a system message + del options['target'] + else: + node_list = [] + node_list.append(nodes.image(block_text, **options)) + return node_list image.arguments = (1, 0, 1) image.options = {'alt': directives.unchanged, @@ -43,6 +57,7 @@ image.options = {'alt': directives.unchanged, 'width': directives.nonnegative_int, 'scale': directives.nonnegative_int, 'align': align, + 'target': directives.unchanged_required, 'class': directives.class_option} def figure(name, arguments, options, content, lineno, -- cgit v1.2.1 From eaab763e93ebde4bba8e04f6bbfad9e570417ea8 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 4 Jan 2004 17:39:13 +0000 Subject: support for body-level reference nodes git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1792 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 2bfe1b1ca..1760f3f19 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -941,6 +941,11 @@ class HTMLTranslator(nodes.NodeVisitor): raise nodes.SkipNode def visit_reference(self, node): + if isinstance(node.parent, nodes.TextElement): + self.context.append('') + else: + self.body.append('

    ') + self.context.append('

    \n') if node.has_key('refuri'): href = node['refuri'] elif node.has_key('refid'): @@ -952,6 +957,7 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_reference(self, node): self.body.append('') + self.body.append(self.context.pop()) def visit_revision(self, node): self.visit_docinfo_item(node, 'revision', meta=None) -- cgit v1.2.1 From 1a01bf07144884a37d123823eb0dddcbb749b20b Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 4 Jan 2004 17:44:46 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1793 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 9334834a8..b304dbced 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1182,7 +1182,7 @@ class raw(Special, Inline, PreBibliographic, FixedTextElement): class emphasis(Inline, TextElement): pass class strong(Inline, TextElement): pass class literal(Inline, TextElement): pass -class reference(Inline, Referential, TextElement): pass +class reference(General, Inline, Referential, TextElement): pass class footnote_reference(Inline, Referential, TextElement): pass class citation_reference(Inline, Referential, TextElement): pass class substitution_reference(Inline, TextElement): pass -- cgit v1.2.1 From 4f2dc86710e382b1a3a35ae8e9ec0516ea4bbd09 Mon Sep 17 00:00:00 2001 From: grubert Date: Mon, 12 Jan 2004 07:52:53 +0000 Subject: Fix: Escape "#" in refuris, breaks inside LaTeX box envrionments. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1797 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 07cce243d..d7afe50ad 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1249,13 +1249,14 @@ class LaTeXTranslator(nodes.NodeVisitor): # BUG: hash_char "#" is trouble some in LaTeX. # mbox and other environment do not like the '#'. hash_char = '\\#' - if node.has_key('refuri'): - href = node['refuri'] + href = node['refuri'].replace('#',hash_char) elif node.has_key('refid'): href = hash_char + node['refid'] elif node.has_key('refname'): href = hash_char + self.document.nameids[node['refname']] + else: + raise AssertionError('Unknown reference.') self.body.append('\\href{%s}{' % href) def depart_reference(self, node): -- cgit v1.2.1 From 74bc7e3a7d5fe2ece9a48ffb4d368879e986b1bc Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 12 Jan 2004 16:27:25 +0000 Subject: added "table" directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1799 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 1 + docutils/parsers/rst/directives/body.py | 35 +++++++++++++++++++++++++++++ docutils/parsers/rst/languages/af.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/fr.py | 1 + docutils/parsers/rst/languages/it.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/writers/html4css1.py | 10 +++++++-- 15 files changed, 56 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index fdddb6c9d..23ef04188 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -102,6 +102,7 @@ _directive_registry = { 'epigraph': ('body', 'epigraph'), 'highlights': ('body', 'highlights'), 'pull-quote': ('body', 'pull_quote'), + 'table': ('body', 'table'), #'questions': ('body', 'question_list'), 'image': ('images', 'image'), 'figure': ('images', 'figure'), diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index 47e1423c8..122b2ccc4 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -120,3 +120,38 @@ def pull_quote(name, arguments, options, content, lineno, return [block_quote] + messages pull_quote.content = 1 + +def table(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + if not content: + warning = state_machine.reporter.warning( + 'Content block expected for the "%s" directive; none found.' + % name, nodes.literal_block(block_text, block_text), + line=lineno) + return [warning] + if arguments: + title_text = arguments[0] + text_nodes, messages = state.inline_text(title_text, lineno) + title = nodes.title(title_text, '', *text_nodes) + else: + title = None + node = nodes.Element() # anonymous container for parsing + text = '\n'.join(content) + state.nested_parse(content, content_offset, node) + if len(node) != 1 or not isinstance(node[0], nodes.table): + error = state_machine.reporter.error( + 'Error parsing content block for the "%s" directive: ' + 'exactly one table expected.' + % name, nodes.literal_block(block_text, block_text), + line=lineno) + return [error] + table_node = node[0] + if options.has_key('class'): + table_node.set_class(options['class']) + if title: + table_node.insert(0, title) + return [table_node] + +table.arguments = (0, 1, 1) +table.options = {'class': directives.class_option} +table.content = 1 diff --git a/docutils/parsers/rst/languages/af.py b/docutils/parsers/rst/languages/af.py index 8ad023ed1..f714ca9b1 100644 --- a/docutils/parsers/rst/languages/af.py +++ b/docutils/parsers/rst/languages/af.py @@ -36,6 +36,7 @@ directives = { 'epigraaf': 'epigraph', 'hoogtepunte': 'highlights', 'pull-quote (translation required)': 'pull-quote', + 'table (translation required)': 'table', #'vrae': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/cs.py b/docutils/parsers/rst/languages/cs.py index 45fb5e657..23c551140 100644 --- a/docutils/parsers/rst/languages/cs.py +++ b/docutils/parsers/rst/languages/cs.py @@ -37,6 +37,7 @@ directives = { u'moto': 'epigraph', u'highlights': 'highlights', u'pull-quote': 'pull-quote', + u'table (translation required)': 'table', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index 017a2e851..cc3b71138 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -37,6 +37,7 @@ directives = { 'epigraph (translation required)': 'epigraph', 'highlights (translation required)': 'highlights', 'pull-quote (translation required)': 'pull-quote', # kasten too ? + 'table (translation required)': 'table', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index a9b060f82..d9068ee8e 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -37,6 +37,7 @@ directives = { 'epigraph': 'epigraph', 'highlights': 'highlights', 'pull-quote': 'pull-quote', + 'table': 'table', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/eo.py b/docutils/parsers/rst/languages/eo.py index 35c3a6765..0682f875c 100644 --- a/docutils/parsers/rst/languages/eo.py +++ b/docutils/parsers/rst/languages/eo.py @@ -40,6 +40,7 @@ directives = { u'elstara\u0135oj': 'highlights', u'ekstera-citajxo': 'pull-quote', u'ekstera-cita\u0135o': 'pull-quote', + u'table (translation required)': 'table', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index abe883741..27cfb9301 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -42,6 +42,7 @@ directives = { u'epigrafe': 'epigraph', u'destacado': 'highlights', u'cita-destacada': 'pull-quote', + u'table (translation required)': 'table', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index ba0bcb014..6ed792430 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -38,6 +38,7 @@ directives = { u'\u00E9pigraphe': 'epigraph', u'chapeau': 'highlights', u'accroche': 'pull-quote', + u'tableau': 'table', #u'questions': 'questions', #u'qr': 'questions', #u'faq': 'questions', diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index 911c69a66..035fd60c9 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -36,6 +36,7 @@ directives = { 'epigraph (translation required)': 'epigraph', 'highlights (translation required)': 'highlights', 'pull-quote (translation required)': 'pull-quote', + u'table (translation required)': 'table', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/pt-br.py b/docutils/parsers/rst/languages/pt-br.py index 5fc68218a..309a4f39b 100644 --- a/docutils/parsers/rst/languages/pt-br.py +++ b/docutils/parsers/rst/languages/pt-br.py @@ -37,6 +37,7 @@ directives = { u'epgrafo': 'epigraph', 'destaques': 'highlights', u'citao-destacada': 'pull-quote', + u'table (translation required)': 'table', #'perguntas': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/ru.py b/docutils/parsers/rst/languages/ru.py index 366f4505f..40823dd81 100644 --- a/docutils/parsers/rst/languages/ru.py +++ b/docutils/parsers/rst/languages/ru.py @@ -23,6 +23,7 @@ directives = { u'parsed-literal', u'\u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f-\u0446\u0438\u0442\u0430\u0442\u0430': u'pull-quote', + u'table (translation required)': 'table', u'\u0441\u044b\u0440\u043e\u0439': u'raw', u'\u0437\u0430\u043c\u0435\u043d\u0430': u'replace', u'\u0442\u0435\u0441\u0442\u043e\u0432\u0430\u044f-\u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u0430-restructuredtext': diff --git a/docutils/parsers/rst/languages/sk.py b/docutils/parsers/rst/languages/sk.py index caf3ed5c4..83f101908 100644 --- a/docutils/parsers/rst/languages/sk.py +++ b/docutils/parsers/rst/languages/sk.py @@ -36,6 +36,7 @@ directives = { u'epigraph (translation required)': 'epigraph', u'highlights (translation required)': 'highlights', u'pull-quote (translation required)': 'pull-quote', + u'table (translation required)': 'table', #u'questions': 'questions', #u'qa': 'questions', #u'faq': 'questions', diff --git a/docutils/parsers/rst/languages/sv.py b/docutils/parsers/rst/languages/sv.py index 04d105f90..3409c30f2 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -35,6 +35,7 @@ directives = { u'epigraph (translation required)': 'epigraph', u'highlights (translation required)': 'highlights', u'pull-quote (translation required)': 'pull-quote', + u'table (translation required)': 'table', # u'fr\u00e5gor': 'questions', # NOTE: A bit long, but recommended by http://www.nada.kth.se/dataterm/: # u'fr\u00e5gor-och-svar': 'questions', diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 1760f3f19..566f5b67f 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -1141,6 +1141,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_title(self, node): """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')) @@ -1153,6 +1154,11 @@ class HTMLTranslator(nodes.NodeVisitor): 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 self.section_level == 0: # document title self.head.append('%s\n' @@ -1174,9 +1180,9 @@ class HTMLTranslator(nodes.NodeVisitor): if node.parent.hasattr('id'): self.body.append( self.starttag({}, 'a', '', name=node.parent['id'])) - self.context.append('

    \n') + self.context.append('' + close_tag) else: - self.context.append('

    \n') + self.context.append(close_tag) def depart_title(self, node): self.body.append(self.context.pop()) -- cgit v1.2.1 From 7aca2d56b7ae2bea193e91efd1531204d53e0195 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 14 Jan 2004 16:07:11 +0000 Subject: clarified system message git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1801 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 26f55c566..252a38f37 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -2695,8 +2695,8 @@ class Text(RSTState): definitionlistitem += definition if termline[0][-2:] == '::': definition += self.reporter.info( - 'Blank line missing before literal block? Interpreted as a ' - 'definition list item.', line=line_offset + 1) + 'Blank line missing before literal block (after the "::")? ' + 'Interpreted as a definition list item.', line=line_offset+1) self.nested_parse(indented, input_offset=line_offset, node=definition) return definitionlistitem, blank_finish -- cgit v1.2.1 From 14583868d63423cf7bb3154c1114659fc41d2a48 Mon Sep 17 00:00:00 2001 From: richieadler Date: Fri, 16 Jan 2004 02:27:32 +0000 Subject: New translated directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1802 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/eo.py | 2 +- docutils/parsers/rst/languages/es.py | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/eo.py b/docutils/parsers/rst/languages/eo.py index 0682f875c..dc9f59aa2 100644 --- a/docutils/parsers/rst/languages/eo.py +++ b/docutils/parsers/rst/languages/eo.py @@ -40,7 +40,7 @@ directives = { u'elstara\u0135oj': 'highlights', u'ekstera-citajxo': 'pull-quote', u'ekstera-cita\u0135o': 'pull-quote', - u'table (translation required)': 'table', + u'tabelo': 'table', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index 27cfb9301..f1354778b 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -42,7 +42,7 @@ directives = { u'epigrafe': 'epigraph', u'destacado': 'highlights', u'cita-destacada': 'pull-quote', - u'table (translation required)': 'table', + u'tabla': 'table', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', @@ -75,8 +75,10 @@ roles = { u'ac': 'acronym', u'indice': 'index', u'i': 'index', - u'subscript (translation required)': 'subscript', - u'superscript (translation required)': 'superscript', + u'subindice': 'subscript', + u'sub\u00edndice': 'subscript', + u'superindice': 'superscript', + u'super\u00edndice': 'superscript', u'referencia-titulo': 'title-reference', u'titulo': 'title-reference', u't': 'title-reference', -- cgit v1.2.1 From 7c33d0ab994dc21774f77b579d9642b8138557db Mon Sep 17 00:00:00 2001 From: david_abrahams Date: Fri, 16 Jan 2004 02:39:42 +0000 Subject: Admonition bug fixes git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1803 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index d7afe50ad..3d9aacdb0 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -530,14 +530,15 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_address(self, node): self.depart_docinfo_item(node) - def visit_admonition(self, node, name): + def visit_admonition(self, node, name=''): self.body.append('\\begin{center}\\begin{sffamily}\n') self.body.append('\\fbox{\\parbox{\\admonitionwidth}{\n') - self.body.append('\\textbf{\\large '+ self.language.labels[name] + '}\n'); + if name: + self.body.append('\\textbf{\\large '+ self.language.labels[name] + '}\n'); self.body.append('\\vspace{2mm}\n') - def depart_admonition(self): + def depart_admonition(self, node=None): self.body.append('}}\n') # end parbox fbox self.body.append('\\end{sffamily}\n\\end{center}\n'); -- cgit v1.2.1 From 7be3e33703c71319e161f9e233b687adb79cee58 Mon Sep 17 00:00:00 2001 From: lele Date: Wed, 21 Jan 2004 11:23:17 +0000 Subject: Translated several directive-aliases git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1807 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/it.py | 59 ++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 29 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index 035fd60c9..0dd5fbc30 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -1,7 +1,8 @@ -# Author: Nicola Larosa -# Contact: docutils@tekNico.net +# Author: Nicola Larosa, Lele Gaifax +# Contact: docutils@tekNico.net, lele@seldati.it # Revision: $Revision$ # Date: $Date$ +# Date: $Date$ # Copyright: This module has been placed in the public domain. # New language mappings are welcome. Before doing a new translation, please @@ -27,13 +28,13 @@ directives = { 'nota': 'note', 'consiglio': 'tip', 'avvertenza': 'warning', - 'admonition (translation required)': 'admonition', - 'sidebar (translation required)': 'sidebar', + 'ammonizione': 'admonition', + 'riquadro': 'sidebar', 'argomento': 'topic', - 'blocco di linee': 'line-block', - 'parsed-literal': 'parsed-literal', - 'rubric (translation required)': 'rubric', - 'epigraph (translation required)': 'epigraph', + 'blocco-di-righe': 'line-block', + 'blocco-interpretato': 'parsed-literal', + 'rubrica': 'rubric', + 'epigrafe': 'epigraph', 'highlights (translation required)': 'highlights', 'pull-quote (translation required)': 'pull-quote', u'table (translation required)': 'table', @@ -48,11 +49,11 @@ directives = { 'grezzo': 'raw', 'sostituisci': 'replace', 'unicode': 'unicode', - 'class (translation required)': 'class', + 'classe': 'class', 'indice': 'contents', 'seznum': 'sectnum', - 'section-numbering': 'sectnum', - 'target-notes': 'target-notes', + 'sezioni-autonumerate': 'sectnum', + 'annota-riferimenti-esterni': 'target-notes', #'footnotes': 'footnotes', #'citations': 'citations', 'restructuredtext-test-directive': 'restructuredtext-test-directive'} @@ -60,23 +61,23 @@ directives = { mapping.""" roles = { - 'abbreviation (translation required)': 'abbreviation', - 'acronym (translation required)': 'acronym', - 'index (translation required)': 'index', - 'subscript (translation required)': 'subscript', - 'superscript (translation required)': 'superscript', - 'title-reference (translation required)': 'title-reference', - 'pep-reference (translation required)': 'pep-reference', - 'rfc-reference (translation required)': 'rfc-reference', - 'emphasis (translation required)': 'emphasis', - 'strong (translation required)': 'strong', - 'literal (translation required)': 'literal', - 'named-reference (translation required)': 'named-reference', - 'anonymous-reference (translation required)': 'anonymous-reference', - 'footnote-reference (translation required)': 'footnote-reference', - 'citation-reference (translation required)': 'citation-reference', - 'substitution-reference (translation required)': 'substitution-reference', - 'target (translation required)': 'target', - 'uri-reference (translation required)': 'uri-reference',} + 'abbreviazione': 'abbreviation', + 'acronimo': 'acronym', + 'indice': 'index', + 'deponente': 'subscript', + 'esponente': 'superscript', + 'riferimento-titolo': 'title-reference', + 'riferimento-pep': 'pep-reference', + 'riferimento-rfc': 'rfc-reference', + 'enfasi': 'emphasis', + 'forte': 'strong', + 'letterale': 'literal', + 'riferimento-con-nome': 'named-reference', + 'riferimento-anonimo': 'anonymous-reference', + 'riferimento-nota': 'footnote-reference', + 'riferimento-citazione': 'citation-reference', + 'riferimento-sostituzione': 'substitution-reference', + 'destinazione': 'target', + 'riferimento-uri': 'uri-reference',} """Mapping of Italian role names to canonical role names for interpreted text. """ -- cgit v1.2.1 From a2fddea53b1590ce050a76573ff1840bd4fb55bc Mon Sep 17 00:00:00 2001 From: lele Date: Wed, 21 Jan 2004 11:28:26 +0000 Subject: Removed a double Date header that slipped in git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1808 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/it.py | 6 ------ 1 file changed, 6 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index 0dd5fbc30..fc08452e1 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -2,14 +2,8 @@ # Contact: docutils@tekNico.net, lele@seldati.it # Revision: $Revision$ # Date: $Date$ -# 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. - """ Italian-language mappings for language-dependent features of reStructuredText. -- cgit v1.2.1 From 9899cfe846c05ad7669126b4939a6881e7f028e8 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 22 Jan 2004 20:55:19 +0000 Subject: bugfix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1810 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 9066765d8..5523c947e 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -126,8 +126,7 @@ def validate_boolean(setting, value, option_parser, def validate_threshold(setting, value, option_parser, config_parser=None, config_section=None): try: - int(value) - return value + return int(value) except ValueError: try: return option_parser.thresholds[value.lower()] -- cgit v1.2.1 From b24dd9aaa77085ba010d3d2aaa2a42dac8f73e16 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 23 Jan 2004 02:35:13 +0000 Subject: Added FilterMessages transform (removes system messages below the verbosity threshold) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1811 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/__init__.py | 3 ++- docutils/transforms/universal.py | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py index 24cc4771f..aa3e1b525 100644 --- a/docutils/transforms/__init__.py +++ b/docutils/transforms/__init__.py @@ -76,7 +76,8 @@ class Transformer(TransformSpec): default_transforms = (universal.Decorations, universal.FinalChecks, - universal.Messages) + universal.Messages, + universal.FilterMessages) """These transforms are applied to all document trees.""" def __init__(self, document): diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 4523304f2..e7d1f150c 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -111,6 +111,29 @@ class Messages(Transform): self.document += section +class FilterMessages(Transform): + + """ + Remove system messages below verbosity threshold. + """ + + default_priority = 870 + + def apply(self): + visitor = SystemMessageFilterVisitor(self.document) + self.document.walk(visitor) + + +class SystemMessageFilterVisitor(nodes.SparseNodeVisitor): + + def unknown_visit(self, node): + pass + + def visit_system_message(self, node): + if node['level'] < self.document.reporter['writer'].report_level: + node.parent.remove(node) + + class TestMessages(Transform): """ -- cgit v1.2.1 From 7832bc8449c669bd5298ccc3cc291141180b6feb Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 30 Jan 2004 16:52:57 +0000 Subject: remove redundant method git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1823 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/pep_html.py | 9 --------- 1 file changed, 9 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index 96c44cfb0..54d269317 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -88,15 +88,6 @@ class Writer(html4css1.Writer): class HTMLTranslator(html4css1.HTMLTranslator): - def get_stylesheet_reference(self, relative_to=None): - settings = self.settings - if relative_to == None: - relative_to = settings._destination - if settings.stylesheet_path: - return utils.relative_path(relative_to, settings.stylesheet_path) - else: - return settings.stylesheet - def depart_field_list(self, node): html4css1.HTMLTranslator.depart_field_list(self, node) if node.get('class') == 'rfc2822': -- cgit v1.2.1 From 47c35375ec398f18f19be2fc69afbee82a27d677 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 2 Feb 2004 03:28:29 +0000 Subject: add "" for untitled docs, for XHTML conformance; thanks to Darek Suchojad git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1824 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 566f5b67f..79a583c25 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -547,6 +547,10 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_document(self, node): self.body.append(self.starttag(node, 'div', CLASS='document')) + # empty or untitled document? + if not len(node) or not isinstance(node[0], nodes.title): + # for XHTML conformance: + self.head.insert(0, '<title />\n') def depart_document(self, node): self.body.append('</div>\n') -- cgit v1.2.1 From 0516c805bd1d9de99ea553643af89a5bfba43659 Mon Sep 17 00:00:00 2001 From: grubert <grubert@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 16 Feb 2004 06:45:48 +0000 Subject: Add title_reference tag (italic). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1828 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 3d9aacdb0..4bd876436 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -245,6 +245,7 @@ latex_headings = { '% 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', ] } @@ -623,11 +624,10 @@ class LaTeXTranslator(nodes.NodeVisitor): self.depart_footnote(node) def visit_title_reference(self, node): - # BUG title-references are what? - pass + self.body.append( '\\titlereference{' ) def depart_title_reference(self, node): - pass + self.body.append( '}' ) def visit_citation_reference(self, node): href = '' -- cgit v1.2.1 From 320b8204b1fabbb443af0cb5894cbdc693a2668e Mon Sep 17 00:00:00 2001 From: bbum <bbum@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 19 Feb 2004 07:38:50 +0000 Subject: Added a bunch of URI schemes found on OS X (including third party apps). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1829 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/urischemes.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/urischemes.py b/docutils/urischemes.py index 05ba20415..2a29757f4 100644 --- a/docutils/urischemes.py +++ b/docutils/urischemes.py @@ -27,6 +27,7 @@ schemes = { 'specialized to justify their own schemes'), 'fax': ('a connection to a terminal that can handle telefaxes ' '(facsimiles); RFC 2806'), + 'feed' : 'NetNewsWire feed', 'file': 'Host-specific file names', 'finger': '', 'freenet': '', @@ -42,6 +43,7 @@ schemes = { 'hnews': 'an HTTP-tunneling variant of the NNTP news protocol', 'http': 'Hypertext Transfer Protocol', 'https': 'HTTP over SSL', + 'hydra': 'SubEthaEdit URI. See http://www.codingmonkeys.de/subethaedit.', 'iioploc': 'Internet Inter-ORB Protocol Location?', 'ilu': 'Inter-Language Unification', 'im': 'Instant Messaging', @@ -49,10 +51,11 @@ schemes = { 'ior': 'CORBA interoperable object reference', 'ipp': 'Internet Printing Protocol', 'irc': 'Internet Relay Chat', + 'iseek' : 'See www.ambrosiasw.com; a little util for OS X.', 'jar': 'Java archive', 'javascript': ('JavaScript code; evaluates the expression after the ' 'colon'), - 'jdbc': '', + 'jdbc': 'JDBC connection URI.', 'ldap': 'Lightweight Directory Access Protocol', 'lifn': '', 'livescript': '', @@ -76,6 +79,7 @@ schemes = { 'pres': 'Presence', 'printer': '', 'prospero': 'Prospero Directory Service', + 'rdar' : 'URLs found in Darwin source (http://www.opensource.apple.com/darwinsource/).', 'res': '', 'rtsp': 'real time streaming protocol', 'rvp': '', @@ -86,10 +90,11 @@ schemes = { 'shttp': 'secure hypertext transfer protocol', 'sip': 'Session Initiation Protocol', 'sips': 'secure session intitiaion protocol', - 'smb': '', + 'smb': 'SAMBA filesystems.', 'snews': 'For NNTP postings via SSL', 'soap.beep': '', 'soap.beeps': '', + 'ssh': 'Reference to interactive sessions via ssh.', 't120': 'real time data conferencing (audiographics)', 'tcp': '', 'tel': ('a connection to a terminal that handles normal voice ' @@ -110,6 +115,7 @@ schemes = { 'wais': 'Wide Area Information Servers', 'whodp': '', 'whois++': 'Distributed directory service.', + 'x-man-page': 'Opens man page in Terminal.app on OS X (see macosxhints.com)', 'xmlrpc.beep': '', 'xmlrpc.beeps': '', 'z39.50r': 'Z39.50 Retrieval', -- cgit v1.2.1 From f8c46fdf95cedd9ce6c63834af2f665a4b0c218e Mon Sep 17 00:00:00 2001 From: grubert <grubert@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 23 Feb 2004 07:19:03 +0000 Subject: Add: (Lele Gaifax) DocumentClass: encapsulating knowledge about LaTeX's section commands. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1830 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 48 +++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 4bd876436..4adf0e072 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -11,7 +11,7 @@ LaTeX2e document tree Writer. __docformat__ = 'reStructuredText' # code contributions from several people included, thanks too all. -# some named: David Abrahams, Julien Letessier, who is missing. +# some named: David Abrahams, Julien Letessier, Lele Gaifax, who is missing. # # convention deactivate code by two # e.g. ##. @@ -250,6 +250,33 @@ latex_headings = { ] } +class DocumentClass: + """Details of a LaTeX document class.""" + + # BUG: LaTeX has no deeper sections (actually paragrah is no + # section either). + _class_sections = { + 'book': ( 'chapter', 'section', 'subsection', 'subsubsection' ), + 'report': ( 'chapter', 'section', 'subsection', 'subsubsection' ), + 'article': ( 'section', 'subsection', 'subsubsection' ), + } + _deepest_section = 'subsubsection' + + def __init__(self, document_class): + self.document_class = document_class + + def section(self, level): + """ Return the section name at the given level for the specific + document class. + + Level is 1,2,3..., as level 0 is the title.""" + + sections = self._class_sections[self.document_class] + if level <= len(sections): + return sections[level-1] + else: + return self._deepest_section + class LaTeXTranslator(nodes.NodeVisitor): # When options are given to the documentclass, latex will pass them @@ -303,6 +330,9 @@ class LaTeXTranslator(nodes.NodeVisitor): if self.babel.get_language(): self.d_options += ',%s' % \ self.babel.get_language() + + self.d_class = DocumentClass(settings.documentclass) + self.head_prefix = [ self.latex_head % (self.d_options,self.settings.documentclass), '\\usepackage{babel}\n', # language is in documents settings. @@ -1512,21 +1542,15 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('%' + '_' * 75) self.body.append('\n\n') self.bookmark(node) - # section_level 0 is title and handled above. - # BUG: latex has no deeper sections (actually paragrah is no section either). + if self.use_latex_toc: section_star = "" else: section_star = "*" - if (self.section_level<=3): # 1,2,3 - self.body.append('\\%ssection%s{' % ('sub'*(self.section_level-1),section_star)) - elif (self.section_level==4): - #self.body.append('\\paragraph*{') - self.body.append('\\subsubsection%s{' % (section_star)) - else: - #self.body.append('\\subparagraph*{') - self.body.append('\\subsubsection%s{' % (section_star)) - # BUG: self.body.append( '\\label{%s}\n' % name) + + section_name = self.d_class.section(self.section_level) + self.body.append('\\%s%s{' % (section_name, section_star)) + self.context.append('}\n') def depart_title(self, node): -- cgit v1.2.1 From 6345ac8947d4d3b16eb06a70cf2ff11fed5d75f9 Mon Sep 17 00:00:00 2001 From: grubert <grubert@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 23 Feb 2004 19:10:00 +0000 Subject: Comments for picky ones. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1831 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 4adf0e072..b5d10cc48 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -11,7 +11,7 @@ LaTeX2e document tree Writer. __docformat__ = 'reStructuredText' # code contributions from several people included, thanks too all. -# some named: David Abrahams, Julien Letessier, Lele Gaifax, who is missing. +# some named: David Abrahams, Julien Letessier, Lele Gaifax, and others. # # convention deactivate code by two # e.g. ##. -- cgit v1.2.1 From f46f941bea713e73e4eb5d4c3f272944703a942e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 25 Feb 2004 02:54:22 +0000 Subject: removed unused import git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1834 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/standalone.py | 1 - 1 file changed, 1 deletion(-) (limited to 'docutils') diff --git a/docutils/readers/standalone.py b/docutils/readers/standalone.py index cd69504ac..29aec35dc 100644 --- a/docutils/readers/standalone.py +++ b/docutils/readers/standalone.py @@ -14,7 +14,6 @@ __docformat__ = 'reStructuredText' import sys from docutils import frontend, readers from docutils.transforms import frontmatter, references -from docutils.parsers.rst import Parser class Reader(readers.Reader): -- cgit v1.2.1 From ef4b9454f19c8a774c7c53430b15a8c59825ec09 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 25 Feb 2004 03:08:06 +0000 Subject: appease IE6 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1835 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 79a583c25..176f1850a 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -549,8 +549,8 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.starttag(node, 'div', CLASS='document')) # empty or untitled document? if not len(node) or not isinstance(node[0], nodes.title): - # for XHTML conformance: - self.head.insert(0, '<title />\n') + # for XHTML conformance, modulo IE6 appeasement: + self.head.insert(0, '<title>\n') def depart_document(self, node): self.body.append('\n') -- cgit v1.2.1 From 4fc059506945a34cf95ea1104d6e77ea01628470 Mon Sep 17 00:00:00 2001 From: fdrake Date: Sat, 20 Mar 2004 20:56:52 +0000 Subject: add some comments git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1840 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 176f1850a..1934ef118 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -192,7 +192,9 @@ class HTMLTranslator(nodes.NodeVisitor): else: self.stylesheet = [] self.body_prefix = ['\n\n'] + # document title, subtitle display self.body_pre_docinfo = [] + # author, date, etc. self.docinfo = [] self.body = [] self.body_suffix = ['\n\n'] -- cgit v1.2.1 From 20a4c2a870b5b91a23954fba80b5475ee7a47f0c Mon Sep 17 00:00:00 2001 From: aahz Date: Sun, 21 Mar 2004 15:45:44 +0000 Subject: Add ``info`` class to parallel ``docinfo`` for sections git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1843 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 1 + 1 file changed, 1 insertion(+) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index b304dbced..141f24bd1 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -939,6 +939,7 @@ class rubric(Titular, TextElement): pass # ======================== class docinfo(Bibliographic, Element): pass +class info(Bibliographic, Element): pass class author(Bibliographic, TextElement): pass class authors(Bibliographic, Element): pass class organization(Bibliographic, TextElement): pass -- cgit v1.2.1 From 0fcfd5fe8f7bd14d9ae8f60a82ffa01e6320d8fb Mon Sep 17 00:00:00 2001 From: orutherfurd Date: Sun, 21 Mar 2004 19:06:58 +0000 Subject: added 'info' to git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1846 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 141f24bd1..59ba34948 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1223,7 +1223,7 @@ node_class_names = """ footnote footnote_reference generated header hint - image important inline + image important info inline label legend line_block list_item literal literal_block note option option_argument option_group option_list option_list_item -- cgit v1.2.1 From 9f31157a98faacf4c2b8f2bbdf2bbbd5078d6093 Mon Sep 17 00:00:00 2001 From: ianbicking Date: Sun, 21 Mar 2004 20:18:22 +0000 Subject: Incomplete changes to the moduleparser python source reader git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1847 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 26 +++++++++++--------------- docutils/readers/python/moduleparser.py | 8 ++++++++ 2 files changed, 19 insertions(+), 15 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 59ba34948..ca585e888 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1296,16 +1296,6 @@ class SparseNodeVisitor(NodeVisitor): subclasses), subclass `NodeVisitor` instead. """ -def _nop(self, node): - pass - -# Save typing with dynamic assignments: -for _name in node_class_names: - setattr(SparseNodeVisitor, "visit_" + _name, _nop) - setattr(SparseNodeVisitor, "depart_" + _name, _nop) -del _name, _nop - - class GenericNodeVisitor(NodeVisitor): """ @@ -1338,12 +1328,18 @@ def _call_default_visit(self, node): def _call_default_departure(self, node): self.default_departure(node) -# Save typing with dynamic assignments: -for _name in node_class_names: - setattr(GenericNodeVisitor, "visit_" + _name, _call_default_visit) - setattr(GenericNodeVisitor, "depart_" + _name, _call_default_departure) -del _name, _call_default_visit, _call_default_departure +def _nop(self, node): + pass + +def _add_node_class_names(names): + """Save typing with dynamic assignments:""" + for _name in names: + setattr(GenericNodeVisitor, "visit_" + _name, _call_default_visit) + setattr(GenericNodeVisitor, "depart_" + _name, _call_default_departure) + setattr(SparseNodeVisitor, 'visit_' + _name, _nop) + setattr(SparseNodeVisitor, 'depart' + _name, _nop) +_add_node_class_names(node_class_names) class TreeCopyVisitor(GenericNodeVisitor): diff --git a/docutils/readers/python/moduleparser.py b/docutils/readers/python/moduleparser.py index 9fcd1ec07..a425d2738 100644 --- a/docutils/readers/python/moduleparser.py +++ b/docutils/readers/python/moduleparser.py @@ -190,6 +190,7 @@ import token from compiler.consts import OP_ASSIGN from compiler.visitor import ASTVisitor from types import StringType, UnicodeType, TupleType +from docutils.readers.python import pynodes def parse_module(module_text, filename): @@ -418,6 +419,7 @@ class ModuleVisitor(AssignmentVisitor): self.module = None def visitModule(self, node): + self.module = module = Module(node, self.filename) if node.doc is not None: module.append(Docstring(node, node.doc)) @@ -782,3 +784,9 @@ def normalize_parameter_name(name): return '(%s)' % ', '.join([normalize_parameter_name(n) for n in name]) else: return name + +if __name__ == '__main__': + import sys + filename = sys.argv[1] + content = open(filename).read() + print parse_module(content, filename) -- cgit v1.2.1 From 6126be3ca7e624ff208ac3b31de62116e6bc109a Mon Sep 17 00:00:00 2001 From: orutherfurd Date: Sun, 21 Mar 2004 22:33:36 +0000 Subject: added option to disable section numbering git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1849 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 4 ++++ docutils/transforms/parts.py | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 5523c947e..f98f1bb4c 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -293,6 +293,10 @@ 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', + ['--disable-section-numbering'], + {'action': 'store_false', 'default': 1, + 'dest': 'enable_section_numbering', 'validator': validate_boolean}), ('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).', diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index 016f4e1d8..68a2afed4 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -34,7 +34,8 @@ class SectNum(Transform): def apply(self): self.maxdepth = self.startnode.details.get('depth', sys.maxint) self.startnode.parent.remove(self.startnode) - self.update_section_numbers(self.document) + if self.document.settings.enable_section_numbering: + self.update_section_numbers(self.document) def update_section_numbers(self, node, prefix=(), depth=0): depth += 1 -- cgit v1.2.1 From 34833a0410b1bbe9d6880b0b7c7be85b8b09383e Mon Sep 17 00:00:00 2001 From: mmgilbe Date: Mon, 22 Mar 2004 01:07:40 +0000 Subject: Added unknown_reference_resolvers attribute to TransformSpec. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1853 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index 2d2f012bc..fe1c4c18e 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -122,6 +122,13 @@ class TransformSpec: default_transforms = () """Transforms required by this class. Override in subclasses.""" + + unknown_reference_resolvers = () + """List of functions to try to resolve unknown references. Called when + FinalCheckVisitor is unable to find a correct target. The list should + contain functions which will try to resolve unknown references. Each + function can have a default_priority attribute which will effect the order + the unknown_reference_resolvers are run. Override in subclass""" class Component(SettingsSpec, TransformSpec): @@ -133,7 +140,7 @@ class Component(SettingsSpec, TransformSpec): supported = () """Names for this component. Override in subclasses.""" - + def supports(self, format): """ Is `format` supported by this component? -- cgit v1.2.1 From 598ca90a5a7796f3344cff534f6912e1934d44b8 Mon Sep 17 00:00:00 2001 From: reggie Date: Mon, 22 Mar 2004 01:08:19 +0000 Subject: The "contents" directive does more work up-front, creating the "topic" and "title", and leaving the "pending" node for the transform. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1854 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/parts.py | 35 ++++++++++++++++++++++++----- docutils/transforms/parts.py | 38 +++++++++----------------------- 2 files changed, 41 insertions(+), 32 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/parts.py b/docutils/parsers/rst/directives/parts.py index 2faaca44b..5e6809142 100644 --- a/docutils/parsers/rst/directives/parts.py +++ b/docutils/parsers/rst/directives/parts.py @@ -10,7 +10,7 @@ Directives for document parts. __docformat__ = 'reStructuredText' -from docutils import nodes +from docutils import nodes, languages from docutils.transforms import parts from docutils.parsers.rst import directives @@ -27,17 +27,42 @@ def backlinks(arg): def contents(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """Table of contents.""" + document = state_machine.document + language = languages.get_language(document.settings.language_code) + if arguments: title_text = arguments[0] text_nodes, messages = state.inline_text(title_text, lineno) title = nodes.title(title_text, '', *text_nodes) else: messages = [] - title = None - pending = nodes.pending(parts.Contents, {'title': title}, block_text) + if options.has_key('local'): + title = None + else: + title = nodes.title('', language.labels['contents']) + + topic = nodes.topic(CLASS='contents') + + cls = options.get('class') + if cls: + topic.set_class(cls) + + if title: + name = title.astext() + topic += title + else: + name = language.labels['contents'] + + name = nodes.fully_normalize_name(name) + if not document.has_name(name): + topic['name'] = name + document.note_implicit_target(topic) + + pending = nodes.pending(parts.Contents, rawsource=block_text) pending.details.update(options) - state_machine.document.note_pending(pending) - return [pending] + messages + document.note_pending(pending) + topic += pending + return [topic] + messages contents.arguments = (0, 1, 1) contents.options = {'depth': directives.nonnegative_int, diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index 68a2afed4..b6da17f34 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -34,8 +34,7 @@ class SectNum(Transform): def apply(self): self.maxdepth = self.startnode.details.get('depth', sys.maxint) self.startnode.parent.remove(self.startnode) - if self.document.settings.enable_section_numbering: - self.update_section_numbers(self.document) + self.update_section_numbers(self.document) def update_section_numbers(self, node, prefix=(), depth=0): depth += 1 @@ -59,11 +58,11 @@ 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). + into a nested bullet list, which is placed within a "topic" created by the + contents directive. A title is either explicitly specified, taken from + the appropriate language module, or omitted (local table of contents). + The depth may be specified. Two-way references between the table of + contents and section titles are generated (requires Writer support). This transform requires a startnode, which which contains generation options and provides the location for the generated table of contents (the @@ -73,41 +72,26 @@ class Contents(Transform): default_priority = 720 def apply(self): - topic = nodes.topic(CLASS='contents') details = self.startnode.details - if details.has_key('class'): - topic.set_class(details['class']) - title = details['title'] if details.has_key('local'): - startnode = self.startnode.parent + startnode = self.startnode.parent.parent # @@@ generate an error if the startnode (directive) not at # section/document top-level? Drag it up until it is? while not isinstance(startnode, nodes.Structural): startnode = startnode.parent else: startnode = self.document - if not title: - title = nodes.title('', self.language.labels['contents']) - if title: - name = title.astext() - topic += title - else: - name = self.language.labels['contents'] - name = nodes.fully_normalize_name(name) - if not self.document.has_name(name): - topic['name'] = name - self.document.note_implicit_target(topic) - self.toc_id = topic['id'] + + self.toc_id = self.startnode.parent['id'] if details.has_key('backlinks'): self.backlinks = details['backlinks'] else: self.backlinks = self.document.settings.toc_backlinks contents = self.build_contents(startnode) if len(contents): - topic += contents - self.startnode.parent.replace(self.startnode, topic) + self.startnode.parent.replace(self.startnode, contents) else: - self.startnode.parent.remove(self.startnode) + self.startnode.parent.parent.remove(self.startnode.parent) def build_contents(self, node, level=0): level += 1 -- cgit v1.2.1 From 1f2f4eb5fe0d7347d89d5549d30a2d27f687a504 Mon Sep 17 00:00:00 2001 From: mmgilbe Date: Mon, 22 Mar 2004 01:08:37 +0000 Subject: Added hook (via docutils.TransformSpec.unknown_reference_resolvers) to FinalCheckVisitor for application-specific handling of unresolvable references. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1855 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/universal.py | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index e7d1f150c..a77437b95 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -159,7 +159,13 @@ class FinalChecks(Transform): default_priority = 840 def apply(self): - visitor = FinalCheckVisitor(self.document) + unknown_reference_resolvers = [] + for i in self.document.transformer.components.values(): + unknown_reference_resolvers.extend(i.unknown_reference_resolvers) + decorated_list = [(f.priority, f) for f in unknown_reference_resolvers] + decorated_list.sort() + unknown_reference_resolvers = [f[1] for f in decorated_list] + visitor = FinalCheckVisitor(self.document, unknown_reference_resolvers) self.document.walk(visitor) if self.document.settings.expose_internals: visitor = InternalAttributeExposer(self.document) @@ -167,6 +173,11 @@ class FinalChecks(Transform): 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 @@ -177,15 +188,21 @@ class FinalCheckVisitor(nodes.SparseNodeVisitor): refname = node['refname'] id = self.document.nameids.get(refname) if id is None: - msg = self.document.reporter.error( - 'Unknown target name: "%s".' % (node['refname']), - base_node=node) - msgid = self.document.set_id(msg) - prb = nodes.problematic( - node.rawsource, node.rawsource, refid=msgid) - prbid = self.document.set_id(prb) - msg.add_backref(prbid) - node.parent.replace(node, prb) + handled = None + for i in self.unknown_reference_resolvers: + if i(node): + handled = 1 + break + if not handled: + 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 -- cgit v1.2.1 From 2c868af6838d363ed0ca7fc5571b515622ecf3e2 Mon Sep 17 00:00:00 2001 From: reggie Date: Mon, 22 Mar 2004 01:12:45 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1857 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/body.py | 1 + 1 file changed, 1 insertion(+) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index 122b2ccc4..6c29d037e 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -34,6 +34,7 @@ def topic(name, arguments, options, content, lineno, title_text = arguments[0] textnodes, messages = state.inline_text(title_text, lineno) titles = [nodes.title(title_text, '', *textnodes)] + # sidebar uses this code if options.has_key('subtitle'): textnodes, more_messages = state.inline_text(options['subtitle'], lineno) -- cgit v1.2.1 From d1e833c256b95461a2d5af437c4ce16b71345c22 Mon Sep 17 00:00:00 2001 From: ianbicking Date: Mon, 22 Mar 2004 15:11:35 +0000 Subject: Added the pynodes file I missed yesterday. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1858 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/python/pynodes.py | 80 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 docutils/readers/python/pynodes.py (limited to 'docutils') diff --git a/docutils/readers/python/pynodes.py b/docutils/readers/python/pynodes.py new file mode 100644 index 000000000..f246a5dc6 --- /dev/null +++ b/docutils/readers/python/pynodes.py @@ -0,0 +1,80 @@ +#! /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. + +""" + +from docutils import nodes +from docutils.nodes import Element, TextElement, Structural, Inline, Part + + +# ===================== +# Structural Elements +# ===================== + +class package_section(Structural, Element): pass +class module_section(Structural, Element): pass +class class_section(Structural, Element): pass +class method_section(Structural, Element): pass +class function_section(Structural, Element): pass +class module_attribute_section(Structural, Element): pass +class class_attribute_section(Structural, Element): pass +class instance_attribute_section(Structural, Element): pass + +# Structural Support Elements +# --------------------------- + +class inheritance_list(Part, Element): pass +class parameter_list(Part, Element): pass +class parameter_item(Part, Element): pass +class optional_parameters(Part, Element): pass +class parameter_tuple(Part, Element): pass +class parameter_default(Part, TextElement): pass +class initial_value(Part, TextElement): pass +class import_item(Part, TextElement): pass + +# ================= +# Inline Elements +# ================= + +# These elements cannot become references until the second +# pass. Initially, we'll use "reference" or "name". + +class package(Part, Inline, TextElement): pass +class module(Part, Inline, TextElement): pass + + +class inline_class(Part, Inline, TextElement): + + tagname = 'class' + + +class method(Part, Inline, TextElement): pass +class function(Part, Inline, TextElement): pass +class variable(Inline, TextElement): pass +class parameter(Part, Inline, TextElement): pass +class inline_type(Inline, TextElement): + tagname = 'type' +class class_attribute(Part, Inline, TextElement): pass +class module_attribute(Part, Inline, TextElement): pass +class instance_attribute(Part, Inline, TextElement): pass +class exception_class(Inline, TextElement): pass +class warning_class(Inline, TextElement): pass + +# Collect all the classes we've written above +node_class_names = [] +def build_node_class_names(): + for name, var in globals().items(): + if type(var) is types.ClassType \ + and issubclass(var, nodes.Node) \ + and name.lower() == name: + node_class_names.append(var.tagname or name) + +# Register the new node names with GenericNodeVisitor and +# SpecificNodeVisitor: +nodes._add_node_class_names(node_class_names) -- cgit v1.2.1 From db10b42915077db1a6cbb936145d0d803142b12a Mon Sep 17 00:00:00 2001 From: ianbicking Date: Tue, 23 Mar 2004 19:57:14 +0000 Subject: * Bug fixes to python reader * Getting tests up-to-date * Trimming unused nodes from pynodes git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1876 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/python/__init__.py | 6 + docutils/readers/python/moduleparser.py | 343 +++++++++++++------------------- docutils/readers/python/pynodes.py | 81 ++++---- 3 files changed, 190 insertions(+), 240 deletions(-) (limited to 'docutils') diff --git a/docutils/readers/python/__init__.py b/docutils/readers/python/__init__.py index 5bc832183..3087f9147 100644 --- a/docutils/readers/python/__init__.py +++ b/docutils/readers/python/__init__.py @@ -13,9 +13,15 @@ __docformat__ = 'reStructuredText' import sys import docutils.readers +from docutils.readers.python import moduleparser class Reader(docutils.readers.Reader): config_section = 'python reader' config_section_dependencies = ('readers',) + + def parse(self): + """Parse `self.input` into a document tree.""" + self.document = document = moduleparser.parse_module(self.input) + document.current_source = document.current_line = None diff --git a/docutils/readers/python/moduleparser.py b/docutils/readers/python/moduleparser.py index a425d2738..c95d997c8 100644 --- a/docutils/readers/python/moduleparser.py +++ b/docutils/readers/python/moduleparser.py @@ -191,6 +191,7 @@ from compiler.consts import OP_ASSIGN from compiler.visitor import ASTVisitor from types import StringType, UnicodeType, TupleType from docutils.readers.python import pynodes +from docutils.nodes import Text def parse_module(module_text, filename): @@ -201,168 +202,6 @@ def parse_module(module_text, filename): compiler.walk(ast, visitor, walker=visitor) return visitor.module - -class Node: - - """ - Base class for module documentation tree nodes. - """ - - def __init__(self, node): - self.children = [] - """List of child nodes.""" - - self.lineno = node.lineno - """Line number of this node (or ``None``).""" - - def __str__(self, indent=' ', level=0): - return ''.join(['%s%s\n' % (indent * level, repr(self))] + - [child.__str__(indent, level+1) - for child in self.children]) - - def __repr__(self): - parts = [self.__class__.__name__] - for name, value in self.attlist(): - parts.append('%s="%s"' % (name, value)) - return '<%s>' % ' '.join(parts) - - def attlist(self, **atts): - if self.lineno is not None: - atts['lineno'] = self.lineno - attlist = atts.items() - attlist.sort() - return attlist - - def append(self, node): - self.children.append(node) - - def extend(self, node_list): - self.children.extend(node_list) - - -class TextNode(Node): - - def __init__(self, node, text): - Node.__init__(self, node) - self.text = trim_docstring(text) - - def __str__(self, indent=' ', level=0): - prefix = indent * (level + 1) - text = '\n'.join([prefix + line for line in self.text.splitlines()]) - return Node.__str__(self, indent, level) + text + '\n' - - -class Module(Node): - - def __init__(self, node, filename): - Node.__init__(self, node) - self.filename = filename - - def attlist(self): - return Node.attlist(self, filename=self.filename) - - -class Docstring(TextNode): pass - - -class Comment(TextNode): pass - - -class Import(Node): - - def __init__(self, node, names, from_name=None): - Node.__init__(self, node) - self.names = names - self.from_name = from_name - - def __str__(self, indent=' ', level=0): - prefix = indent * (level + 1) - lines = [] - for name, as in self.names: - if as: - lines.append('%s%s as %s' % (prefix, name, as)) - else: - lines.append('%s%s' % (prefix, name)) - text = '\n'.join(lines) - return Node.__str__(self, indent, level) + text + '\n' - - def attlist(self): - if self.from_name: - atts = {'from': self.from_name} - else: - atts = {} - return Node.attlist(self, **atts) - - -class Attribute(Node): - - def __init__(self, node, name): - Node.__init__(self, node) - self.name = name - - def attlist(self): - return Node.attlist(self, name=self.name) - - -class AttributeTuple(Node): - - def __init__(self, node, names): - Node.__init__(self, node) - self.names = names - - def attlist(self): - return Node.attlist(self, names=' '.join(self.names)) - - -class Expression(TextNode): - - def __str__(self, indent=' ', level=0): - prefix = indent * (level + 1) - return '%s%s%s\n' % (Node.__str__(self, indent, level), - prefix, self.text.encode('unicode-escape')) - - -class Function(Attribute): pass - - -class ParameterList(Node): pass - - -class Parameter(Attribute): pass - - -class ParameterTuple(AttributeTuple): - - def attlist(self): - return Node.attlist(self, names=normalize_parameter_name(self.names)) - - -class ExcessPositionalArguments(Parameter): pass - - -class ExcessKeywordArguments(Parameter): pass - - -class Default(Expression): pass - - -class Class(Node): - - def __init__(self, node, name, bases=None): - Node.__init__(self, node) - self.name = name - self.bases = bases or [] - - def attlist(self): - atts = {'name': self.name} - if self.bases: - atts['bases'] = ' '.join(self.bases) - return Node.attlist(self, **atts) - - -class Method(Function): pass - - class BaseVisitor(ASTVisitor): def __init__(self, token_parser): @@ -390,7 +229,7 @@ class DocstringVisitor(BaseVisitor): def visitConst(self, node): if self.documentable: if type(node.value) in (StringType, UnicodeType): - self.documentable.append(Docstring(node, node.value)) + self.documentable.append(make_docstring(node.value, node.lineno)) else: self.documentable = None @@ -419,26 +258,28 @@ class ModuleVisitor(AssignmentVisitor): self.module = None def visitModule(self, node): - - self.module = module = Module(node, self.filename) - if node.doc is not None: - module.append(Docstring(node, node.doc)) + self.module = module = pynodes.module_section() + module['filename'] = self.filename + append_docstring(module, node.doc, node.lineno) self.context.append(module) self.documentable = module self.visit(node.node) self.context.pop() def visitImport(self, node): - self.context[-1].append(Import(node, node.names)) + self.context[-1] += make_import_group(names=node.names, + lineno=node.lineno) self.documentable = None def visitFrom(self, node): self.context[-1].append( - Import(node, node.names, from_name=node.modname)) + make_import_group(names=node.names, from_name=node.modname, + lineno=node.lineno)) self.documentable = None def visitFunction(self, node): - visitor = FunctionVisitor(self.token_parser) + visitor = FunctionVisitor(self.token_parser, + function_class=pynodes.function_section) compiler.walk(node, visitor, walker=visitor) self.context[-1].append(visitor.function) @@ -452,29 +293,32 @@ class AttributeVisitor(BaseVisitor): def __init__(self, token_parser): BaseVisitor.__init__(self, token_parser) - self.attributes = [] + self.attributes = pynodes.class_attribute_section() def visitAssign(self, node): # Don't visit the expression itself, just the attribute nodes: for child in node.nodes: self.dispatch(child) expression_text = self.token_parser.rhs(node.lineno) - expression = Expression(node, expression_text) + expression = pynodes.expression_value() + expression.append(Text(expression_text)) for attribute in self.attributes: attribute.append(expression) def visitAssName(self, node): - self.attributes.append(Attribute(node, node.name)) + self.attributes.append(make_attribute(node.name, + lineno=node.lineno)) def visitAssTuple(self, node): attributes = self.attributes self.attributes = [] self.default_visit(node) - names = [attribute.name for attribute in self.attributes] - att_tuple = AttributeTuple(node, names) - att_tuple.lineno = self.attributes[0].lineno + n = pynodes.attribute_tuple() + n.extend(self.attributes) + n['lineno'] = self.attributes[0]['lineno'] + attributes.append(n) self.attributes = attributes - self.attributes.append(att_tuple) + #self.attributes.append(att_tuple) def visitAssAttr(self, node): self.default_visit(node, node.attrname) @@ -483,13 +327,17 @@ class AttributeVisitor(BaseVisitor): self.default_visit(node, node.attrname + '.' + suffix) def visitName(self, node, suffix): - self.attributes.append(Attribute(node, node.name + '.' + suffix)) + self.attributes.append(make_attribute(node.name + '.' + suffix, + lineno=node.lineno)) class FunctionVisitor(DocstringVisitor): in_function = 0 - function_class = Function + + def __init__(self, token_parser, function_class): + DocstringVisitor.__init__(self, token_parser) + self.function_class = function_class def visitFunction(self, node): if self.in_function: @@ -497,9 +345,11 @@ class FunctionVisitor(DocstringVisitor): # Don't bother with nested function definitions. return self.in_function = 1 - self.function = function = self.function_class(node, node.name) - if node.doc is not None: - function.append(Docstring(node, node.doc)) + self.function = function = make_function_like_section( + name=node.name, + lineno=node.lineno, + doc=node.doc, + function_class=self.function_class) self.context.append(function) self.documentable = function self.parse_parameter_list(node) @@ -511,10 +361,11 @@ class FunctionVisitor(DocstringVisitor): special = [] argnames = list(node.argnames) if node.kwargs: - special.append(ExcessKeywordArguments(node, argnames[-1])) + special.append(make_parameter(argnames[-1], excess_keyword=True)) argnames.pop() if node.varargs: - special.append(ExcessPositionalArguments(node, argnames[-1])) + special.append(make_parameter(argnames[-1], + excess_positional=True)) argnames.pop() defaults = list(node.defaults) defaults = [None] * (len(argnames) - len(defaults)) + defaults @@ -523,17 +374,21 @@ class FunctionVisitor(DocstringVisitor): #print >>sys.stderr, function_parameters for argname, default in zip(argnames, defaults): if type(argname) is TupleType: - parameter = ParameterTuple(node, argname) + parameter = pynodes.parameter_tuple() + for tuplearg in argname: + parameter.append(make_parameter(tuplearg)) argname = normalize_parameter_name(argname) else: - parameter = Parameter(node, argname) + parameter = make_parameter(argname) if default: - parameter.append(Default(node, function_parameters[argname])) + n_default = pynodes.parameter_default() + n_default.append(Text(function_parameters[argname])) + parameter.append(n_default) parameters.append(parameter) if parameters or special: special.reverse() parameters.extend(special) - parameter_list = ParameterList(node) + parameter_list = pynodes.parameter_list() parameter_list.extend(parameters) self.function.append(parameter_list) @@ -556,9 +411,9 @@ class ClassVisitor(AssignmentVisitor): #pdb.set_trace() for base in node.bases: self.visit(base) - self.klass = klass = Class(node, node.name, self.bases) - if node.doc is not None: - klass.append(Docstring(node, node.doc)) + self.klass = klass = make_class_section(node.name, self.bases, + doc=node.doc, + lineno=node.lineno) self.context.append(klass) self.documentable = klass self.visit(node.code) @@ -580,19 +435,17 @@ class ClassVisitor(AssignmentVisitor): def visitFunction(self, node): if node.name == '__init__': - visitor = InitMethodVisitor(self.token_parser) + visitor = InitMethodVisitor(self.token_parser, + function_class=pynodes.method_section) + compiler.walk(node, visitor, walker=visitor) else: - visitor = MethodVisitor(self.token_parser) - compiler.walk(node, visitor, walker=visitor) + visitor = FunctionVisitor(self.token_parser, + function_class=pynodes.method_section) + compiler.walk(node, visitor, walker=visitor) self.context[-1].append(visitor.function) -class MethodVisitor(FunctionVisitor): - - function_class = Method - - -class InitMethodVisitor(MethodVisitor, AssignmentVisitor): pass +class InitMethodVisitor(FunctionVisitor, AssignmentVisitor): pass class TokenParser: @@ -746,6 +599,81 @@ class TokenParser: return parameters +def make_docstring(doc, lineno): + n = pynodes.docstring() + if lineno: + # Really, only module docstrings don't have a line + # (@@: but maybe they should) + n['lineno'] = lineno + n.append(Text(doc)) + return n + +def append_docstring(node, doc, lineno): + if doc: + node.append(make_docstring(doc, lineno)) + +def make_class_section(name, bases, lineno, doc): + n = pynodes.class_section() + n['lineno'] = lineno + n.append(make_object_name(name)) + for base in bases: + b = pynodes.class_base() + b.append(make_object_name(base)) + n.append(b) + append_docstring(n, doc, lineno) + return n + +def make_object_name(name): + n = pynodes.object_name() + n.append(Text(name)) + return n + +def make_function_like_section(name, lineno, doc, function_class): + n = function_class() + n['lineno'] = lineno + n.append(make_object_name(name)) + append_docstring(n, doc, lineno) + return n + +def make_import_group(names, lineno, from_name=None): + n = pynodes.import_group() + n['lineno'] = lineno + if from_name: + n_from = pynodes.import_from() + n_from.append(Text(from_name)) + n.append(n_from) + for name, alias in names: + n_name = pynodes.import_name() + n_name.append(Text(name)) + if alias: + n_alias = pynodes.import_alias() + n_alias.append(Text(alias)) + n_name.append(n_alias) + n.append(n_name) + return n + +def make_class_attribute(name, lineno): + n = pynodes.class_attribute() + n['lineno'] = lineno + n.append(Text(name)) + return n + +def make_attribute(name, lineno): + n = pynodes.attribute() + n['lineno'] = lineno + n.append(make_object_name(name)) + return n + +def make_parameter(name, excess_keyword=False, excess_positional=False): + n = pynodes.parameter() + n.append(make_object_name(name)) + assert not excess_keyword or not excess_positional + if excess_keyword: + n['excess_keyword'] = 1 + if excess_positional: + n['excess_positional'] = 1 + return n + def trim_docstring(text): """ Trim indentation and blank lines from docstring text & return it. @@ -787,6 +715,15 @@ def normalize_parameter_name(name): if __name__ == '__main__': import sys - filename = sys.argv[1] - content = open(filename).read() - print parse_module(content, filename) + args = sys.argv[1:] + if args[0] == '-v': + filename = args[1] + module_text = open(filename).read() + ast = compiler.parse(module_text) + visitor = compiler.visitor.ExampleASTVisitor() + compiler.walk(ast, visitor, walker=visitor, verbose=1) + else: + filename = args[0] + content = open(filename).read() + print parse_module(content, filename).pformat() + diff --git a/docutils/readers/python/pynodes.py b/docutils/readers/python/pynodes.py index f246a5dc6..40db6975e 100644 --- a/docutils/readers/python/pynodes.py +++ b/docutils/readers/python/pynodes.py @@ -10,33 +10,39 @@ """ from docutils import nodes -from docutils.nodes import Element, TextElement, Structural, Inline, Part +from docutils.nodes import Element, TextElement, Structural, Inline, Part, \ + Text +import types +# This is the parent class of all the other pynode classes: +class PythonStructural(Structural): pass # ===================== # Structural Elements # ===================== -class package_section(Structural, Element): pass -class module_section(Structural, Element): pass -class class_section(Structural, Element): pass -class method_section(Structural, Element): pass -class function_section(Structural, Element): pass -class module_attribute_section(Structural, Element): pass -class class_attribute_section(Structural, Element): pass -class instance_attribute_section(Structural, Element): pass +class module_section(PythonStructural, Element): pass +class class_section(PythonStructural, Element): pass +class class_base(PythonStructural, Element): pass +class method_section(PythonStructural, Element): pass +class attribute(PythonStructural, Element): pass +class function_section(PythonStructural, Element): pass +class class_attribute_section(PythonStructural, Element): pass +class class_attribute(PythonStructural, Element): pass +class expression_value(PythonStructural, Element): pass +class attribute(PythonStructural, Element): pass # Structural Support Elements # --------------------------- -class inheritance_list(Part, Element): pass -class parameter_list(Part, Element): pass -class parameter_item(Part, Element): pass -class optional_parameters(Part, Element): pass -class parameter_tuple(Part, Element): pass -class parameter_default(Part, TextElement): pass -class initial_value(Part, TextElement): pass -class import_item(Part, TextElement): pass +class parameter_list(PythonStructural, Element): pass +class parameter_tuple(PythonStructural, Element): pass +class parameter_default(PythonStructural, TextElement): pass +class import_group(PythonStructural, TextElement): pass +class import_from(PythonStructural, TextElement): pass +class import_name(PythonStructural, TextElement): pass +class import_alias(PythonStructural, TextElement): pass +class docstring(PythonStructural, Element): pass # ================= # Inline Elements @@ -45,34 +51,35 @@ class import_item(Part, TextElement): pass # These elements cannot become references until the second # pass. Initially, we'll use "reference" or "name". -class package(Part, Inline, TextElement): pass -class module(Part, Inline, TextElement): pass +class object_name(PythonStructural, TextElement): pass +class parameter_list(PythonStructural, TextElement): pass +class parameter(PythonStructural, TextElement): pass +class parameter_default(PythonStructural, TextElement): pass +class class_attribute(PythonStructural, TextElement): pass +class attribute_tuple(PythonStructural, TextElement): pass +# ================= +# Unused Elements +# ================= -class inline_class(Part, Inline, TextElement): - - tagname = 'class' - +# These were part of the model, and maybe should be in the future, but +# aren't now. +#class package_section(PythonStructural, Element): pass +#class module_attribute_section(PythonStructural, Element): pass +#class instance_attribute_section(PythonStructural, Element): pass +#class module_attribute(PythonStructural, TextElement): pass +#class instance_attribute(PythonStructural, TextElement): pass +#class exception_class(PythonStructural, TextElement): pass +#class warning_class(PythonStructural, TextElement): pass -class method(Part, Inline, TextElement): pass -class function(Part, Inline, TextElement): pass -class variable(Inline, TextElement): pass -class parameter(Part, Inline, TextElement): pass -class inline_type(Inline, TextElement): - tagname = 'type' -class class_attribute(Part, Inline, TextElement): pass -class module_attribute(Part, Inline, TextElement): pass -class instance_attribute(Part, Inline, TextElement): pass -class exception_class(Inline, TextElement): pass -class warning_class(Inline, TextElement): pass # Collect all the classes we've written above node_class_names = [] def build_node_class_names(): for name, var in globals().items(): - if type(var) is types.ClassType \ - and issubclass(var, nodes.Node) \ - and name.lower() == name: + if (type(var) is types.ClassType + and issubclass(var, PythonStructural) \ + and name.lower() == name): node_class_names.append(var.tagname or name) # Register the new node names with GenericNodeVisitor and -- cgit v1.2.1 From 634a5d0622c6fbeb09face1622dc8b4d79878f00 Mon Sep 17 00:00:00 2001 From: reggie Date: Tue, 23 Mar 2004 22:29:44 +0000 Subject: Added funtionality to keep track of individual parts of a document and store them in a dictionary as the "parts" attribute of the writer. Added publish_parts convenience function to allow easy access to these parts. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1879 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 64 +++++++++++++++++++++++++++++++++++++++++ docutils/writers/__init__.py | 7 +++++ docutils/writers/html4css1.py | 67 ++++++++++++++++++++++++++++++------------- 3 files changed, 118 insertions(+), 20 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index e2bb03074..93defd38e 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -180,6 +180,7 @@ class Publisher: self.settings) self.apply_transforms(document) output = self.writer.write(document, self.destination) + self.writer.assemble_parts() except utils.SystemMessage, error: if self.settings.traceback: raise @@ -376,3 +377,66 @@ def publish_string(source, source_path=None, destination_path=None, pub.set_source(source, source_path) pub.set_destination(destination_path=destination_path) return pub.publish(enable_exit=enable_exit) + +def publish_parts(source, source_path=None, destination_path=None, + reader=None, reader_name='standalone', + parser=None, parser_name='restructuredtext', + writer=None, writer_name='pseudoxml', + settings=None, settings_spec=None, + settings_overrides=None, config_section=None, + enable_exit=None): + """ + Set up & run a `Publisher`, and return a dictionary of strings with the + names of parts as keys. 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 unencoded Unicode string + output. Here's how:: + + publish_string(..., settings_overrides={'output_encoding': 'unicode'}) + + Similarly for Unicode string input (`source`):: + + publish_string(..., settings_overrides={'input_encoding': 'unicode'}) + + Parameters: + + - `source`: An input string; required. This can be an encoded 8-bit + string (set the "input_encoding" setting to the correct encoding) or a + Unicode string (set the "input_encoding" setting to "unicode"). + - `source_path`: Path to the file or object that produced `source`; + optional. Only used for diagnostic output. + - `destination_path`: Path to the file or object which will receive the + output; optional. Used for determining relative paths (stylesheets, + source links, etc.). + - `reader`: A `docutils.readers.Reader` object. + - `reader_name`: Name or alias of the Reader class to be instantiated if + no `reader` supplied. + - `parser`: A `docutils.parsers.Parser` object. + - `parser_name`: Name or alias of the Parser class to be instantiated if + no `parser` supplied. + - `writer`: A `docutils.writers.Writer` object. + - `writer_name`: Name or alias of the Writer class to be instantiated if + no `writer` supplied. + - `settings`: Runtime settings object. + - `settings_spec`: Extra settings specification; a `docutils.SettingsSpec` + subclass. Used only if no `settings` specified. + - `settings_overrides`: A dictionary containing program-specific overrides + of component settings. + - `config_section`: Name of configuration file section for application. + Used only if no `settings` or `settings_spec` specified. + - `enable_exit`: Boolean; enable exit status at end of processing? + """ + pub = Publisher(reader, parser, writer, settings=settings, + source_class=io.StringInput, + destination_class=io.StringOutput) + pub.set_components(reader_name, parser_name, writer_name) + if settings is None: + settings = pub.get_settings(settings_spec=settings_spec, + config_section=config_section) + if settings_overrides: + settings._update(settings_overrides, 'loose') + pub.set_source(source, source_path) + pub.set_destination(destination_path=destination_path) + pub.publish(enable_exit=enable_exit) + return pub.writer.parts diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index 7b37aa8a8..778b50a68 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -44,6 +44,10 @@ class Writer(Component): def __init__(self): """Initialize the Writer instance.""" + self.parts = {} + """Collection of named parts of the document. 'whole' contains the + entire document.""" + def write(self, document, destination): self.document = document self.language = languages.get_language( @@ -66,6 +70,9 @@ class Writer(Component): """ raise NotImplementedError('subclass must override this method') + def assemble_parts(self): + self.parts['whole'] = self.output + _writer_aliases = { 'html': 'html4css1', diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 1934ef118..f77d4e368 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -96,15 +96,17 @@ class Writer(writers.Writer): visitor = self.translator_class(self.document) self.document.walkabout(visitor) self.output = visitor.astext() - self.head_prefix = visitor.head_prefix - self.stylesheet = visitor.stylesheet - self.head = visitor.head - self.body_prefix = visitor.body_prefix - self.body_pre_docinfo = visitor.body_pre_docinfo - self.docinfo = visitor.docinfo - self.body = visitor.body - self.body_suffix = visitor.body_suffix - + self.visitor = visitor + for attr in ('head_prefix', 'stylesheet', 'head', 'body_prefix', + 'body_pre_docinfo', 'docinfo', 'body', 'fragment', + 'body_suffix'): + setattr(self, attr, getattr(visitor, attr)) + + def assemble_parts(self): + writers.Writer.assemble_parts(self) + for part in ('title', 'subtitle', 'docinfo', 'body', 'header', + 'footer', 'meta', 'stylesheet', 'fragment'): + self.parts[part] = ''.join(getattr(self.visitor, part)) class HTMLTranslator(nodes.NodeVisitor): @@ -171,11 +173,12 @@ class HTMLTranslator(nodes.NodeVisitor): self.settings = settings = document.settings lcode = settings.language_code self.language = languages.get_language(lcode) + self.meta = [self.content_type % settings.output_encoding, + self.generator % docutils.__version__] self.head_prefix = [ self.doctype, - self.html_head % (lcode, lcode), - self.content_type % settings.output_encoding, - self.generator % docutils.__version__] + self.html_head % (lcode, lcode)] + self.head_prefix.extend(self.meta) if settings.xml_declaration: self.head_prefix.insert(0, self.xml_declaration % settings.output_encoding) @@ -197,6 +200,7 @@ class HTMLTranslator(nodes.NodeVisitor): # author, date, etc. self.docinfo = [] self.body = [] + self.fragment = [] self.body_suffix = ['\n\n'] self.section_level = 0 self.context = [] @@ -206,6 +210,11 @@ class HTMLTranslator(nodes.NodeVisitor): self.compact_simple = None self.in_docinfo = None self.in_sidebar = None + self.title = [] + self.subtitle = [] + self.header = [] + self.footer = [] + self.within_title = 0 def get_stylesheet_reference(self, relative_to=None): settings = self.settings @@ -527,8 +536,9 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_docinfo_item(self, node, name, meta=1): if meta: - self.head.append('\n' - % (name, self.attval(node.astext()))) + 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]) @@ -548,13 +558,14 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('\n\n') def visit_document(self, node): - self.body.append(self.starttag(node, 'div', CLASS='document')) # empty or untitled document? if not len(node) or not isinstance(node[0], nodes.title): # for XHTML conformance, modulo IE6 appeasement: self.head.insert(0, '\n') def depart_document(self, node): + self.fragment.extend(self.body) + self.body.insert(0, self.starttag(node, 'div', CLASS='document')) self.body.append('\n') def visit_emphasis(self, node): @@ -677,6 +688,7 @@ class HTMLTranslator(nodes.NodeVisitor): footer = (['\n', self.starttag(node, 'div', CLASS='footer')] + self.body[start:] + ['\n']) + self.footer.extend(footer) self.body_suffix[:0] = footer del self.body[start:] @@ -745,9 +757,11 @@ class HTMLTranslator(nodes.NodeVisitor): 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('
    \n\n') + header = [self.starttag(node, 'div', CLASS='header')] + header.extend(self.body[start:]) + header.append('
    \n\n') + self.body_prefix.extend(header) + self.header = header del self.body[start:] def visit_hint(self, node): @@ -843,11 +857,16 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('\n\n') def visit_meta(self, node): - self.head.append(self.emptytag(node, 'meta', **node.attributes)) + meta = self.emptytag(node, 'meta', **node.attributes) + self.add_meta(meta) def depart_meta(self, node): pass + def add_meta(self, tag): + self.meta.append(tag) + self.head.append(tag) + def visit_note(self, node): self.visit_admonition(node, 'note') @@ -1032,8 +1051,12 @@ class HTMLTranslator(nodes.NodeVisitor): else: self.body.append(self.starttag(node, 'h2', '', CLASS='subtitle')) self.context.append('\n') + self.within_title = len(self.body) def depart_subtitle(self, node): + if self.within_title: + self.subtitle = self.body[self.within_title:] + self.within_title = 0 self.body.append(self.context.pop()) def visit_superscript(self, node): @@ -1171,6 +1194,7 @@ class HTMLTranslator(nodes.NodeVisitor): % self.encode(node.astext())) self.body.append(self.starttag(node, 'h1', '', CLASS='title')) self.context.append('\n') + self.within_title = len(self.body) else: self.body.append( self.starttag(node, 'h%s' % self.section_level, '')) @@ -1189,8 +1213,11 @@ class HTMLTranslator(nodes.NodeVisitor): self.context.append('' + close_tag) else: self.context.append(close_tag) - + def depart_title(self, node): + if self.within_title: + self.title = self.body[self.within_title:] + self.within_title = 0 self.body.append(self.context.pop()) def visit_title_reference(self, node): -- cgit v1.2.1 From c75f5e75d567181ab0267cf4224a3cea59adc53f Mon Sep 17 00:00:00 2001 From: ianbicking Date: Tue, 23 Mar 2004 23:21:11 +0000 Subject: Reader parses docstrings (according to __docformat__) and produces full output. The reader should thus be "done". Run readers/python/__init__.py with a filename argument to get output in the DOM format. A transformer will be necessary to translate this into the standard docutils DOM. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1881 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/python/__init__.py | 105 ++++++++++++++++++++++++++++- docutils/readers/python/moduleparser.py | 115 +++++++++++++++++++------------- docutils/readers/python/pynodes.py | 12 ++-- 3 files changed, 178 insertions(+), 54 deletions(-) (limited to 'docutils') diff --git a/docutils/readers/python/__init__.py b/docutils/readers/python/__init__.py index 3087f9147..0da4ba938 100644 --- a/docutils/readers/python/__init__.py +++ b/docutils/readers/python/__init__.py @@ -14,14 +14,113 @@ __docformat__ = 'reStructuredText' import sys import docutils.readers from docutils.readers.python import moduleparser - +from docutils import parsers +from docutils import nodes +from docutils.readers.python import pynodes +from docutils import readers class Reader(docutils.readers.Reader): config_section = 'python reader' config_section_dependencies = ('readers',) + default_parser = 'restructuredtext' + def parse(self): """Parse `self.input` into a document tree.""" - self.document = document = moduleparser.parse_module(self.input) - document.current_source = document.current_line = None + self.document = document = self.new_document() + module_section = moduleparser.parse_module(self.input, + self.source.source_path) + module_section.walk(DocformatVisitor(self.document)) + visitor = DocstringFormattingVisitor( + document=document, + default_parser=self.default_parser) + module_section.walk(visitor) + self.document.append(module_section) + +class DocformatVisitor(nodes.SparseNodeVisitor): + + """ + This sets docformat attributes in a module. Wherever an assignment + to __docformat__ is found, we look for the enclosing scope -- a class, + a module, or a function -- and set the docformat attribute there. + + We can't do this during the DocstringFormattingVisitor walking, + because __docformat__ may appear below a docstring in that format + (typically below the module docstring). + """ + + def visit_attribute(self, node): + assert isinstance(node[0], pynodes.object_name) + name = node[0][0].data + if name != '__docformat__': + return + value = None + for child in children: + if isinstance(child, pynodes.expression_value): + value = child[0].data + break + assert value.startswith("'") or value.startswith('"'), "__docformat__ must be assigned a string literal (not %s); line: %s" % (value, node['lineno']) + name = name[1:-1] + looking_in = node.parent + while not isinstance(looking_in, (pynodes.module_section, + pynodes.function_section, + pynodes.class_section)): + looking_in = looking_in.parent + looking_in['docformat'] = name + +class DocstringFormattingVisitor(nodes.SparseNodeVisitor): + + def __init__(self, document, default_parser): + self.document = document + self.default_parser = default_parser + self.parsers = {} + + def visit_docstring(self, node): + text = node[0].data + docformat = self.find_docformat(node) + del node[0] + node['docformat'] = docformat + parser = self.get_parser(docformat) + parser.parse(text, self.document) + for child in self.document.get_children(): + node.append(child) + self.document.current_source = self.document.current_line = None + del self.document[:] + + def get_parser(self, parser_name): + """ + Get a parser based on its name. We reuse parsers during this + visitation, so parser instances are cached. + """ + parser_name = parsers._parser_aliases.get(parser_name, parser_name) + if not self.parsers.has_key(parser_name): + cls = parsers.get_parser_class(parser_name) + self.parsers[parser_name] = cls() + return self.parsers[parser_name] + + def find_docformat(self, node): + """ + Find the __docformat__ closest to this node (i.e., look in the + class or module) + """ + while node: + if node.get('docformat'): + return node['docformat'] + node = node.parent + return self.default_parser + +if __name__ == '__main__': + import locale + try: + locale.setlocale(locale.LC_ALL, '') + except: + pass + + from docutils.core import publish_cmdline, default_description + + description = ('Generates pseudo-XML from standalone reStructuredText ' + 'sources (for testing purposes). ' + default_description) + + publish_cmdline(description=description, + reader=Reader()) diff --git a/docutils/readers/python/moduleparser.py b/docutils/readers/python/moduleparser.py index c95d997c8..7f965e6e2 100644 --- a/docutils/readers/python/moduleparser.py +++ b/docutils/readers/python/moduleparser.py @@ -7,11 +7,10 @@ """ Parser for Python modules. -The `parse_module()` function takes a module's text and file name, runs it -through the module parser (using compiler.py and tokenize.py) and produces a -"module documentation tree": a high-level AST full of nodes that are -interesting from an auto-documentation standpoint. For example, given this -module (x.py):: +The `parse_module()` function takes a module's text and file name, +runs it through the module parser (using compiler.py and tokenize.py) +and produces a parse tree of the source code, using the nodes as found +in pynodes.py. For example, given this module (x.py):: # comment @@ -50,69 +49,95 @@ module (x.py):: The module parser will produce this module documentation tree:: - - - comment - + + Docstring - + Additional docstring - - + + + __docformat__ + 'reStructuredText' - - + + + a + 1 - + Attribute docstring - - + + + C + + Super + C's docstring - - + + + class_attribute + 1 - + class_attribute's docstring - - + + + __init__ + __init__'s docstring - - - - + + + + self + + + text + None - - + + + self.instance_attribute + (text * 7 + ' whaddyaknow') - + instance_attribute's docstring - - + + + f + f's docstring - - - + + + + x + # parameter x - - + + + y + a * 5 - + # parameter y - - + + + args + # parameter args - - + + + f.function_attribute + 1 - + f.function_attribute's docstring (Comments are not implemented yet.) compiler.parse() provides most of what's needed for this doctree, and -"tokenize" can be used to get the rest. We can determine the line number from -the compiler.parse() AST, and the TokenParser.rhs(lineno) method provides the -rest. +"tokenize" can be used to get the rest. We can determine the line +number from the compiler.parse() AST, and the TokenParser.rhs(lineno) +method provides the rest. The Docutils Python reader component will transform this module doctree into a Python-specific Docutils doctree, and then a `stylist transform`_ will diff --git a/docutils/readers/python/pynodes.py b/docutils/readers/python/pynodes.py index 40db6975e..61e21f10e 100644 --- a/docutils/readers/python/pynodes.py +++ b/docutils/readers/python/pynodes.py @@ -74,14 +74,14 @@ class attribute_tuple(PythonStructural, TextElement): pass # Collect all the classes we've written above -node_class_names = [] -def build_node_class_names(): +def install_node_class_names(): + node_class_names = [] for name, var in globals().items(): if (type(var) is types.ClassType and issubclass(var, PythonStructural) \ and name.lower() == name): node_class_names.append(var.tagname or name) - -# Register the new node names with GenericNodeVisitor and -# SpecificNodeVisitor: -nodes._add_node_class_names(node_class_names) + # Register the new node names with GenericNodeVisitor and + # SpecificNodeVisitor: + nodes._add_node_class_names(node_class_names) +install_node_class_names() -- cgit v1.2.1 From 00ee5f95c731a0e30a3a2504ce61561b9674dd7b Mon Sep 17 00:00:00 2001 From: mmgilbe Date: Tue, 23 Mar 2004 23:43:54 +0000 Subject: Verifying that external targets are truly targets and not indirect references. This is because we are now adding a "name" attribute to references in addition to targets. Note sure if this is correct! git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1882 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 1 + docutils/parsers/rst/directives/images.py | 4 +++- docutils/parsers/rst/states.py | 9 ++++++--- docutils/transforms/references.py | 3 ++- 4 files changed, 12 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index ca585e888..a13c9733d 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -820,6 +820,7 @@ class document(Root, Structural, Element): def has_name(self, name): return self.nameids.has_key(name) + # "note" here is an imperative verb: "take note of". def note_implicit_target(self, target, msgnode=None): id = self.set_id(target, msgnode) self.set_name_id_map(target, id, msgnode, explicit=None) diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index a835d3d74..ab96a0a4e 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -14,6 +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 try: import Image # PIL @@ -41,7 +42,8 @@ def image(name, arguments, options, content, lineno, if target_type == 'refuri': node_list = nodes.reference(refuri=data) elif target_type == 'refname': - node_list = nodes.reference(refname=data) + node_list = nodes.reference( + refname=data, name=whitespace_normalize_name(options['target'])) state.document.note_refname(node_list) else: # malformed target node_list = [data] # data is a system message diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 252a38f37..9b77d5d49 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -113,6 +113,7 @@ from docutils import nodes, statemachine, utils, urischemes from docutils import ApplicationError, DataError from docutils.statemachine import StateMachineWS, StateWS from docutils.nodes import fully_normalize_name as normalize_name +from docutils.nodes import whitespace_normalize_name from docutils.parsers.rst import directives, languages, tableparser from docutils.parsers.rst.languages import en as _fallback_language_module @@ -867,7 +868,8 @@ class Inliner: else: target = None refname = normalize_name(text) - reference = nodes.reference(rawsource, text) + reference = nodes.reference(rawsource, text, + name=whitespace_normalize_name(text)) node_list = [reference] if rawsource[-2:] == '__': if target: @@ -1017,8 +1019,9 @@ class Inliner: def reference(self, match, lineno, anonymous=None): referencename = match.group('refname') refname = normalize_name(referencename) - referencenode = nodes.reference(referencename + match.group('refend'), - referencename) + referencenode = nodes.reference( + referencename + match.group('refend'), referencename, + name=whitespace_normalize_name(referencename)) if anonymous: referencenode['anonymous'] = 1 self.document.note_anonymous_ref(referencenode) diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index c754ee05c..cd5b5163f 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -353,7 +353,8 @@ class ExternalTargets(Transform): try: reflist = self.document.refnames[name] except KeyError, instance: - if target.referenced: + # @@@ First clause correct??? + if not isinstance(target, nodes.target) or target.referenced: continue msg = self.document.reporter.info( 'External hyperlink target "%s" is not referenced.' -- cgit v1.2.1 From 06305ebeb5bb98b2be5f754084ac12cefc58719e Mon Sep 17 00:00:00 2001 From: mmgilbe Date: Wed, 24 Mar 2004 16:53:29 +0000 Subject: Added "origuri" attribute to references which contain an embedded uri. Some writers (maybe other transforms) are interested in the original (non normalized) uri text. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1888 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 9b77d5d49..9a52cafca 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -854,6 +854,7 @@ class Inliner: def phrase_ref(self, before, after, rawsource, escaped, text): match = self.patterns.embedded_uri.search(escaped) + uri_text = None if match: text = unescape(escaped[:match.start(0)]) uri_text = match.group(2) @@ -868,8 +869,15 @@ class Inliner: else: target = None refname = normalize_name(text) - reference = nodes.reference(rawsource, text, - name=whitespace_normalize_name(text)) + # Only add origuri attribute if the rawsource does contain an + # embedded_uri + if uri_text: + reference = nodes.reference(rawsource, text, + name=whitespace_normalize_name(text), + origuri=uri_text) + else: + reference = nodes.reference(rawsource, text, + name=whitespace_normalize_name(text)) node_list = [reference] if rawsource[-2:] == '__': if target: -- cgit v1.2.1 From f9ce4af77d798fd979eee78a8d31d05783f6f6f3 Mon Sep 17 00:00:00 2001 From: mmgilbe Date: Thu, 25 Mar 2004 23:01:11 +0000 Subject: Added unknown_reference_resolvers list for each transformer. This list holds the list of functions provided by each component of the transformer that help resolve references. Removed all refernces to the origuri code, which was broken. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1894 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 3 +++ docutils/parsers/rst/states.py | 17 +++++------------ docutils/transforms/__init__.py | 14 ++++++++++++++ docutils/transforms/references.py | 10 +++++++++- docutils/transforms/universal.py | 9 ++------- 5 files changed, 33 insertions(+), 20 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index a13c9733d..e9bf17f58 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -599,6 +599,9 @@ class Targetable(Resolvable): referenced = 0 + indirect_reference_name = None + """Holds the whitespace_normalized_name (contains mixed case) of a target""" + class Labeled: """Contains a `label` as its first element.""" diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 9a52cafca..d1c63f7f1 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -854,7 +854,6 @@ class Inliner: def phrase_ref(self, before, after, rawsource, escaped, text): match = self.patterns.embedded_uri.search(escaped) - uri_text = None if match: text = unescape(escaped[:match.start(0)]) uri_text = match.group(2) @@ -869,15 +868,8 @@ class Inliner: else: target = None refname = normalize_name(text) - # Only add origuri attribute if the rawsource does contain an - # embedded_uri - if uri_text: - reference = nodes.reference(rawsource, text, - name=whitespace_normalize_name(text), - origuri=uri_text) - else: - reference = nodes.reference(rawsource, text, - name=whitespace_normalize_name(text)) + reference = nodes.reference(rawsource, text, + name=whitespace_normalize_name(text)) node_list = [reference] if rawsource[-2:] == '__': if target: @@ -1898,7 +1890,8 @@ class Body(RSTState): def make_target(self, block, block_text, lineno, target_name): target_type, data = self.parse_target(block, block_text, lineno) if target_type == 'refname': - target = nodes.target(block_text, '', refname=data) + target = nodes.target(block_text, '', refname=normalize_name(data)) + target.indirect_reference_name = data self.add_target(target_name, '', target, lineno) self.document.note_indirect_target(target) return target @@ -1936,7 +1929,7 @@ class Body(RSTState): def is_reference(self, reference): match = self.explicit.patterns.reference.match( - normalize_name(reference)) + whitespace_normalize_name(reference)) if not match: return None return unescape(match.group('simple') or match.group('phrase')) diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py index aa3e1b525..94b06be5c 100644 --- a/docutils/transforms/__init__.py +++ b/docutils/transforms/__init__.py @@ -59,6 +59,7 @@ class Transform: self.language = languages.get_language( document.settings.language_code) """Language module local to this document.""" + def apply(self): """Override to apply the transform to the document tree.""" @@ -85,6 +86,9 @@ class Transformer(TransformSpec): """List of transforms to apply. Each item is a 3-tuple: ``(priority string, transform class, pending node or None)``.""" + self.unknown_reference_resolvers = [] + """List of hook functions which assist in resolving references""" + self.document = document """The `nodes.document` object this Transformer is attached to.""" @@ -150,6 +154,16 @@ 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 + # component of this transformer is able to register its own helper + # functions to help resolve references. + unknown_reference_resolvers = [] + for i in components: + unknown_reference_resolvers.extend(i.unknown_reference_resolvers) + decorated_list = [(f.priority, f) for f in unknown_reference_resolvers] + decorated_list.sort() + self.unknown_reference_resolvers.extend([f[1] for f in decorated_list]) + def apply_transforms(self): """Apply all of the stored transforms, in priority order.""" diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index cd5b5163f..0e41dae84 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -216,7 +216,15 @@ class IndirectHyperlinks(Transform): refname = target['refname'] reftarget_id = self.document.nameids.get(refname) if not reftarget_id: - self.nonexistent_indirect_target(target) + # Check the unknown_reference_resolvers + handled = 0 + for i in self.document.transformer.unknown_reference_resolvers: + print `target` + if i(target): + handled = 1 + break + if not handled: + self.nonexistent_indirect_target(target) return reftarget = self.document.ids[reftarget_id] if isinstance(reftarget, nodes.target) \ diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index a77437b95..8fbea62c4 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -159,13 +159,8 @@ class FinalChecks(Transform): default_priority = 840 def apply(self): - unknown_reference_resolvers = [] - for i in self.document.transformer.components.values(): - unknown_reference_resolvers.extend(i.unknown_reference_resolvers) - decorated_list = [(f.priority, f) for f in unknown_reference_resolvers] - decorated_list.sort() - unknown_reference_resolvers = [f[1] for f in decorated_list] - visitor = FinalCheckVisitor(self.document, unknown_reference_resolvers) + visitor = FinalCheckVisitor( + self.document, self.document.transformer.unknown_reference_resolvers) self.document.walk(visitor) if self.document.settings.expose_internals: visitor = InternalAttributeExposer(self.document) -- cgit v1.2.1 From f877afc0916de9f9177df646b34f4d6157808693 Mon Sep 17 00:00:00 2001 From: orutherfurd Date: Sun, 28 Mar 2004 15:39:27 +0000 Subject: moved locale imports into try blocks, for Jython compatibility git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1896 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 5 ++++- docutils/readers/python/__init__.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index 0bdd3f517..953418716 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -12,7 +12,10 @@ will exist for a variety of input/output mechanisms. __docformat__ = 'reStructuredText' import sys -import locale +try: + import locale +except: + pass from types import UnicodeType from docutils import TransformSpec diff --git a/docutils/readers/python/__init__.py b/docutils/readers/python/__init__.py index 0da4ba938..1bd9b151c 100644 --- a/docutils/readers/python/__init__.py +++ b/docutils/readers/python/__init__.py @@ -111,8 +111,8 @@ class DocstringFormattingVisitor(nodes.SparseNodeVisitor): return self.default_parser if __name__ == '__main__': - import locale try: + import locale locale.setlocale(locale.LC_ALL, '') except: pass -- cgit v1.2.1 From cac4685cb0442239fe73d2bd9b007ffb3a7317f4 Mon Sep 17 00:00:00 2001 From: fdrake Date: Tue, 30 Mar 2004 22:17:25 +0000 Subject: - allow RCS/CVS $keywords$ to be handled even if there is other text in the relevant docinfo fields (closes SF bug #926198) - make the tests of the RCS/CVS $keyword$ handling less fragile in the face of non-default -k options (closes SF bug #921085) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1898 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/frontmatter.py | 6 +++--- docutils/utils.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index 00afc6fd2..1a45c1336 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -334,10 +334,10 @@ 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) [\d:]+ \$', re.IGNORECASE), r'\1-\2-\3'), - (re.compile(r'\$' r'RCSfile: (.+),v \$$', re.IGNORECASE), r'\1'), - (re.compile(r'\$[a-zA-Z]+: (.+) \$$'), r'\1'),] + (re.compile(r'\$' r'RCSfile: (.+),v \$', re.IGNORECASE), r'\1'), + (re.compile(r'\$[a-zA-Z]+: (.+) \$'), r'\1'),] def extract_authors(self, field, name, docinfo): try: diff --git a/docutils/utils.py b/docutils/utils.py index 2e60a6c6f..148845330 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -406,7 +406,7 @@ 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) + match = pattern.search(textnode.data) if match: textnode.data = pattern.sub(substitution, textnode.data) return -- cgit v1.2.1 From 7fe82f75b0e6f9abd4f2f7a500af94fcd802ab17 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 2 Apr 2004 02:28:23 +0000 Subject: restored sectnum disabling code accidentally clobbered by another checkin; changed name of setting git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1901 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/parts.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index b6da17f34..80f5b0027 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -34,7 +34,8 @@ class SectNum(Transform): def apply(self): self.maxdepth = self.startnode.details.get('depth', sys.maxint) self.startnode.parent.remove(self.startnode) - self.update_section_numbers(self.document) + if self.document.settings.sectnum_xform: + self.update_section_numbers(self.document) def update_section_numbers(self, node, prefix=(), depth=0): depth += 1 -- cgit v1.2.1 From 95d52aaa548180ccedcb40193ac258b61edc5c47 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 2 Apr 2004 02:29:26 +0000 Subject: changed name of setting & cmdline option for sectnum disabling; now conforms to other settings/options git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1902 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index f98f1bb4c..8b74ab00c 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -294,9 +294,9 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): ['--no-footnote-backlinks'], {'dest': 'footnote_backlinks', 'action': 'store_false'}), ('Disable Docutils section numbering', - ['--disable-section-numbering'], - {'action': 'store_false', 'default': 1, - 'dest': 'enable_section_numbering', 'validator': validate_boolean}), + ['--no-section-numbering'], + {'action': 'store_false', 'dest': 'sectnum_xform', + 'default': 1, 'validator': validate_boolean}), ('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 b5ebdc72f8f412847de3fea77576b793372149f0 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 2 Apr 2004 02:54:36 +0000 Subject: updated docstring git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1904 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index fe1c4c18e..7921ab022 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -124,11 +124,18 @@ class TransformSpec: """Transforms required by this class. Override in subclasses.""" unknown_reference_resolvers = () - """List of functions to try to resolve unknown references. Called when - FinalCheckVisitor is unable to find a correct target. The list should - contain functions which will try to resolve unknown references. Each - function can have a default_priority attribute which will effect the order - the unknown_reference_resolvers are run. Override in subclass""" + """List of functions to try to resolve unknown references. Called when + FinalCheckVisitor is unable to find a correct target. The list should + contain functions which will try to resolve unknown references, with the + following signature:: + + def reference_resolver(node): + '''Returns boolean: true if resolved, false if not.''' + + Each function must have a "priority" attribute which will affect the order + the unknown_reference_resolvers are run. + + Override in subclasses.""" class Component(SettingsSpec, TransformSpec): -- cgit v1.2.1 From ed4e74f0c8c447034a3f79f7856ddaac878ab318 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 2 Apr 2004 02:56:04 +0000 Subject: simplified code git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1905 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/universal.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 8fbea62c4..4e7d0b457 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -160,7 +160,8 @@ class FinalChecks(Transform): def apply(self): visitor = FinalCheckVisitor( - self.document, self.document.transformer.unknown_reference_resolvers) + self.document, + self.document.transformer.unknown_reference_resolvers) self.document.walk(visitor) if self.document.settings.expose_internals: visitor = InternalAttributeExposer(self.document) @@ -183,12 +184,10 @@ class FinalCheckVisitor(nodes.SparseNodeVisitor): refname = node['refname'] id = self.document.nameids.get(refname) if id is None: - handled = None - for i in self.unknown_reference_resolvers: - if i(node): - handled = 1 + for resolver_function in self.unknown_reference_resolvers: + if resolver_function(node): break - if not handled: + else: msg = self.document.reporter.error( 'Unknown target name: "%s".' % (node['refname']), base_node=node) -- cgit v1.2.1 From 3a1f6be8832e3655f22cfd117fc321b2cde2c55a Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 3 Apr 2004 14:03:25 +0000 Subject: update publish_parts: docstring, and destination class (direct output is thrown away) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1911 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index 93defd38e..96ed69bcc 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -386,16 +386,13 @@ def publish_parts(source, source_path=None, destination_path=None, settings_overrides=None, config_section=None, enable_exit=None): """ - Set up & run a `Publisher`, and return a dictionary of strings with the - names of parts as keys. For programmatic use with string I/O. + Set up & run a `Publisher`, and return a dictionary of document parts. + Dictionary keys are the names of parts, and values are Unicode strings; + encoding is up to the client. For programmatic use with string I/O. - For encoded string 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 how:: - - publish_string(..., settings_overrides={'output_encoding': 'unicode'}) - - Similarly for Unicode string input (`source`):: + input. Here's how:: publish_string(..., settings_overrides={'input_encoding': 'unicode'}) @@ -429,7 +426,7 @@ def publish_parts(source, source_path=None, destination_path=None, """ pub = Publisher(reader, parser, writer, settings=settings, source_class=io.StringInput, - destination_class=io.StringOutput) + destination_class=io.NullOutput) pub.set_components(reader_name, parser_name, writer_name) if settings is None: settings = pub.get_settings(settings_spec=settings_spec, -- cgit v1.2.1 From bf9fda8fdfa4b1db2f73abc2ca018ca5f3a109b1 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 3 Apr 2004 14:04:20 +0000 Subject: docstrings git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1912 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/__init__.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index 778b50a68..fce06f82b 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -45,8 +45,7 @@ class Writer(Component): """Initialize the Writer instance.""" self.parts = {} - """Collection of named parts of the document. 'whole' contains the - entire document.""" + """Collection of named parts of the document.""" def write(self, document, destination): self.document = document @@ -71,6 +70,13 @@ class Writer(Component): raise NotImplementedError('subclass must override this method') def assemble_parts(self): + """ + Assemble the `self.parts` dictionary. Extend in subclasses. + + Dictionary keys are the names of parts, and values are Unicode + strings; encoding is up to the client. The 'whole' key contains the + entire document output. + """ self.parts['whole'] = self.output -- cgit v1.2.1 From 5bf6b589541554dae2df1edfbe61a3b12dfd4c2e Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 3 Apr 2004 14:04:54 +0000 Subject: whitespace git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1913 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index f77d4e368..d9d95bfbc 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -101,13 +101,14 @@ class Writer(writers.Writer): 'body_pre_docinfo', 'docinfo', 'body', 'fragment', 'body_suffix'): setattr(self, attr, getattr(visitor, attr)) - + def assemble_parts(self): writers.Writer.assemble_parts(self) for part in ('title', 'subtitle', 'docinfo', 'body', 'header', 'footer', 'meta', 'stylesheet', 'fragment'): self.parts[part] = ''.join(getattr(self.visitor, part)) + class HTMLTranslator(nodes.NodeVisitor): """ @@ -152,7 +153,7 @@ class HTMLTranslator(nodes.NodeVisitor): """ xml_declaration = '\n' - doctype = ('\n') @@ -866,7 +867,7 @@ class HTMLTranslator(nodes.NodeVisitor): def add_meta(self, tag): self.meta.append(tag) self.head.append(tag) - + def visit_note(self, node): self.visit_admonition(node, 'note') @@ -1213,7 +1214,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.context.append('' + close_tag) else: self.context.append(close_tag) - + def depart_title(self, node): if self.within_title: self.title = self.body[self.within_title:] -- cgit v1.2.1 From d8c8903dfb10818aad93e126a7541877a774b5cd Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 8 Apr 2004 01:58:27 +0000 Subject: Fixed bug relating to role-less interpreted text in non-English contexts. Reported by Lele Gaifax. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1916 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index d1c63f7f1..065eb6ef3 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -912,17 +912,17 @@ class Inliner: msg_text = [] if role: name = role.lower() + canonical = None + try: + canonical = self.language.roles[name] + except AttributeError, error: + msg_text.append('Problem retrieving role entry from language ' + 'module %r: %s.' % (self.language, error)) + except KeyError: + msg_text.append('No role entry for "%s" in module "%s".' + % (name, self.language.__name__)) else: - name = self.default_interpreted_role - canonical = None - try: - canonical = self.language.roles[name] - except AttributeError, error: - msg_text.append('Problem retrieving role entry from language ' - 'module %r: %s.' % (self.language, error)) - except KeyError: - msg_text.append('No role entry for "%s" in module "%s".' - % (name, self.language.__name__)) + canonical = self.default_interpreted_role if not canonical: try: canonical = _fallback_language_module.roles[name] -- cgit v1.2.1 From 482bb3c81f058e470ee5b0b42b545f41ec369521 Mon Sep 17 00:00:00 2001 From: aahz Date: Fri, 9 Apr 2004 22:49:02 +0000 Subject: Clarify use of TextElement.__init__() git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1919 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index e9bf17f58..c5ccbadf8 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -517,6 +517,9 @@ class TextElement(Element): its immediate parent is a `TextElement` instance (including subclasses). This is handy for nodes like `image` that can appear both inline and as standalone body elements. + + If passing children to `__init__()`, make sure to set `text` to + ``''`` or some other suitable value. """ child_text_separator = '' -- cgit v1.2.1 From 784ce2f5cc2587eaf50f671850c3385a81f4e574 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 11 Apr 2004 02:35:00 +0000 Subject: Python 2.1 compatibility git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1920 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index d9d95bfbc..d9f9e5130 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -279,8 +279,11 @@ class HTMLTranslator(nodes.NodeVisitor): parts.append('%s="%s"' % (name.lower(), self.attval(' '.join(values)))) else: - parts.append('%s="%s"' % (name.lower(), - self.attval(unicode(value)))) + try: + uval = unicode(value) + except TypeError: # for Python 2.1 compatibility: + uval = unicode(str(value)) + parts.append('%s="%s"' % (name.lower(), self.attval(uval))) return '<%s%s>%s' % (' '.join(parts), infix, suffix) def emptytag(self, node, tagname, suffix='\n', **attributes): -- cgit v1.2.1 From 49604925a37cfb2a041cfdd3caefda2a27720f59 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 12 Apr 2004 15:27:18 +0000 Subject: updated docstring git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1925 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index 7921ab022..304e90ca4 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -133,7 +133,9 @@ class TransformSpec: '''Returns boolean: true if resolved, false if not.''' Each function must have a "priority" attribute which will affect the order - the unknown_reference_resolvers are run. + the unknown_reference_resolvers are run:: + + reference_resolver.priority = 100 Override in subclasses.""" -- cgit v1.2.1 From 5eb179749c0ae6e8edd558c997e1814b6c53ddce Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 13 Apr 2004 20:24:04 +0000 Subject: Added options and support: ``--compound-enumerators``, ``--section-prefix-for-enumerators``, and ``--section-enumerator-separator``. By John F Meinel Jr (SF patch 934322). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1926 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 74 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index b5d10cc48..336b18606 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -76,13 +76,37 @@ class Writer(writers.Writer): ['--use-latex-toc'], {'default': 0, 'action': 'store_true', 'validator': frontend.validate_boolean}), - ('Let LaTeX print author and date, donot show it in docutils document info.', + ('Let LaTeX print author and date, do not show it in docutils ' + 'document info.', ['--use-latex-docinfo'], {'default': 0, 'action': 'store_true', 'validator': frontend.validate_boolean}), ('Color of any hyperlinks embedded in text ' '(default: "blue", "0" to disable).', - ['--hyperlink-color'], {'default': 'blue'}),)) + ['--hyperlink-color'], {'default': 'blue'}), + ('Enable compound enumerators for nested enumerated lists ' + '(e.g. "1.2.a.ii"). Default: disabled.', + ['--compound-enumerators'], + {'default': None, 'action': 'store_true', + 'validator': frontend.validate_boolean}), + ('Disable compound enumerators for nested enumerated lists. This is ' + 'the default.', + ['--no-compound-enumerators'], + {'action': 'store_false', 'dest': 'compound_enumerators'}), + ('Enable section ("." subsection ...) prefixes for compound ' + 'enumerators. This has no effect without --compound-enumerators. ' + 'Default: disabled.', + ['--section-prefix-for-enumerators'], + {'default': None, 'action': 'store_true', + 'validator': frontend.validate_boolean}), + ('Disable section prefixes for compound enumerators. ' + 'This is the default.', + ['--no-section-prefix-for-enumerators'], + {'action': 'store_false', 'dest': 'section_prefix_for_enumerators'}), + ('Set the separator between section number and enumerator ' + 'for compound enumerated lists. Default is "-".', + ['--section-enumerator-separator'], + {'default': '-', 'metavar': ''}),)) settings_defaults = {'output_encoding': 'latin-1'} @@ -305,6 +329,16 @@ class LaTeXTranslator(nodes.NodeVisitor): # 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" @@ -315,6 +349,11 @@ class LaTeXTranslator(nodes.NodeVisitor): self.use_latex_docinfo = settings.use_latex_docinfo self.use_latex_footnotes = settings.use_latex_footnotes self.hyperlink_color = settings.hyperlink_color + self.compound_enumerators = settings.compound_enumerators + self.section_prefix_for_enumerators = ( + settings.section_prefix_for_enumerators) + self.section_enumerator_separator = ( + settings.section_enumerator_separator.replace('_', '\\_')) if self.hyperlink_color == '0': self.hyperlink_color = 'black' self.colorlinks = 'false' @@ -414,6 +453,16 @@ class LaTeXTranslator(nodes.NodeVisitor): # enumeration is done by list environment. self._enum_cnt = 0 + + # Stack of section counters so that we don't have to use_latex_toc. + # This will grow and shrink as processing occurs. + # Initialized for potential first-level sections. + self._section_number = [0] + + # The current stack of enumerations so that we can expand + # them into a compound enumeration + self._enumeration_counters = [] + # docinfo. self.docinfo = None # inside literal block: no quote mangling. @@ -421,7 +470,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.literal = 0 # true when encoding in math mode self.mathmode = 0 - + def get_stylesheet_reference(self): if self.settings.stylesheet_path: return self.settings.stylesheet_path @@ -634,7 +683,6 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('}$') self.mathmode = 0 - def visit_caption(self, node): self.body.append( '\\caption{' ) @@ -882,13 +930,22 @@ class LaTeXTranslator(nodes.NodeVisitor): enum_prefix = "" if node.has_key('prefix'): enum_prefix = node['prefix'] - + if self.compound_enumerators: + pref = "" + if self.section_prefix_for_enumerators and self.section_level: + for i in range(self.section_level): + pref += '%d.' % self._section_number[i] + pref = pref[:-1] + self.section_enumerator_separator + enum_prefix += pref + for counter in self._enumeration_counters: + enum_prefix += counter + '.' enum_type = "arabic" if node.has_key('enumtype'): enum_type = node['enumtype'] if enum_style.has_key(enum_type): enum_type = enum_style[enum_type] counter_name = "listcnt%d" % self._enum_cnt; + self._enumeration_counters.append("\\%s{%s}" % (enum_type,counter_name)) self.body.append('\\newcounter{%s}\n' % counter_name) self.body.append('\\begin{list}{%s\\%s{%s}%s}\n' % \ (enum_prefix,enum_type,counter_name,enum_suffix)) @@ -904,6 +961,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_enumerated_list(self, node): self.body.append('\\end{list}\n') + self._enumeration_counters.pop() def visit_error(self, node): self.visit_admonition(node, 'error') @@ -1308,8 +1366,14 @@ class LaTeXTranslator(nodes.NodeVisitor): 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): -- cgit v1.2.1 From 5bcffd0b110a60188af43aadbc6aa40250bfb960 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 14 Apr 2004 02:38:44 +0000 Subject: Practical examples of Docutils client code; may be used as-is, or as models for variations. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1928 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/examples.py | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 docutils/examples.py (limited to 'docutils') diff --git a/docutils/examples.py b/docutils/examples.py new file mode 100644 index 000000000..c149bf9d5 --- /dev/null +++ b/docutils/examples.py @@ -0,0 +1,63 @@ +# Authors: David Goodger +# Contact: goodger@python.org +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +This module contains practical examples of Docutils client code. These +functions may be used as-is, or as models for variations. +""" + +from docutils import core + + +def html_parts(input_string, destination_path=None, + input_encoding='unicode', doctitle=1): + """ + Given an input string, returns a dictionary of HTML document parts. + + Dictionary keys are the names of parts, and values are Unicode strings; + encoding is up to the client. + + Parameters: + + - `input_string`: A multi-line text string; required. + - `destination_path`: Path to the file or object which will receive the + output; optional. Used for determining relative paths (stylesheets, + source links, etc.). + - `input_encoding`: The encoding of `input_string`. If it is an encoded + 8-bit string, provide the correct encoding. If it is a Unicode string, + use "unicode", the default. + - `doctitle`: Disable the promotion of a lone top-level section title to + document title (and subsequent section title to document subtitle + promotion); enabled by default. + """ + overrides = {'input_encoding': input_encoding, + 'doctitle_xform': doctitle} + parts = core.publish_parts( + source=input_string, destination_path=destination_path, + writer_name='html', settings_overrides=overrides) + return parts + +def html_fragment(input_string, destination_path=None, + input_encoding='unicode', output_encoding='unicode', + doctitle=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. + + Parameters (see `html_parts()` for the remainder): + + - `output_encoding`: The desired encoding of the output. If a Unicode + string is desired, use the default value of "unicode" . + """ + parts = html_parts( + input_string=input_string, destination_path=destination_path, + input_encoding=input_encoding, doctitle=doctitle) + fragment = parts['fragment'] + if output_endocing != 'unicode': + fragment = fragment.encode(output_encoding) + return fragment -- cgit v1.2.1 From 28a9ac517ee1816506d2aa8b1f54d734aed5547f Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 14 Apr 2004 22:16:36 +0000 Subject: Added proper support for the "scale" attribute of the "image" element. Contributed by Brent Cook. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1929 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index d9f9e5130..be1b2375e 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -22,6 +22,10 @@ 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 @@ -780,6 +784,23 @@ class HTMLTranslator(nodes.NodeVisitor): del atts['class'] # prevent duplication with node attrs atts['src'] = atts['uri'] del atts['uri'] + if atts.has_key('scale'): + if Image and not (atts.has_key('width') + and atts.has_key('height')): + try: + im = Image.open(str(atts['src'])) + except (IOError, # Source image can't be found or opened + UnicodeError): # PIL doesn't like Unicode paths. + pass + else: + if not atts.has_key('width'): + atts['width'] = int(im.size[0] + * (float(atts['scale']) / 100)) + if not atts.has_key('height'): + atts['height'] = int(im.size[1] + * (float(atts['scale']) / 100)) + del im + del atts['scale'] if not atts.has_key('alt'): atts['alt'] = atts['src'] if isinstance(node.parent, nodes.TextElement): -- cgit v1.2.1 From f7ab579e0cf0e85776826ddc0c2c572c8855e080 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 15 Apr 2004 19:13:56 +0000 Subject: Added coding comment. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1935 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/pt-br.py | 1 + 1 file changed, 1 insertion(+) (limited to 'docutils') diff --git a/docutils/languages/pt-br.py b/docutils/languages/pt-br.py index 5a1be4f8a..d9b9f3ca5 100644 --- a/docutils/languages/pt-br.py +++ b/docutils/languages/pt-br.py @@ -1,3 +1,4 @@ +# -*- coding: iso-8859-1 -*- # Author: David Goodger # Contact: goodger@users.sourceforge.net # Revision: $Revision$ -- cgit v1.2.1 From 3c42f072860137e69457165ae638ac884bdb23ec Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 15 Apr 2004 19:21:18 +0000 Subject: Added coding comment. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1936 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/pt-br.py | 1 + 1 file changed, 1 insertion(+) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/pt-br.py b/docutils/parsers/rst/languages/pt-br.py index 309a4f39b..6f8e3cf21 100644 --- a/docutils/parsers/rst/languages/pt-br.py +++ b/docutils/parsers/rst/languages/pt-br.py @@ -1,3 +1,4 @@ +# -*- coding: iso-8859-1 -*- # Author: David Goodger # Contact: goodger@users.sourceforge.net # Revision: $Revision$ -- cgit v1.2.1 From bee6561efe398179e59d465218a0aaefc9bf024b Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 16 Apr 2004 15:14:57 +0000 Subject: Reorganized interpreted text processing; moved code into the new roles.py module. roles.py contains interpreted text role functions, a registry for interpreted text roles, and an API for adding to and retrieving from the registry. Contributed by Edward Loper. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1943 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/roles.py | 187 +++++++++++++++++++++++++++++++++++++++++ docutils/parsers/rst/states.py | 169 ++++--------------------------------- 2 files changed, 205 insertions(+), 151 deletions(-) create mode 100644 docutils/parsers/rst/roles.py (limited to 'docutils') diff --git a/docutils/parsers/rst/roles.py b/docutils/parsers/rst/roles.py new file mode 100644 index 000000000..fd44c33e1 --- /dev/null +++ b/docutils/parsers/rst/roles.py @@ -0,0 +1,187 @@ +# Author: Edward Loper +# Contact: edloper@gradient.cis.upenn.edu +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +This module defines a registry for interpreted roles. + +The interface for interpreted role functions is as follows:: + + def role_fn(name, rawtext, text, lineno, inliner): + code... + +Parameters: + +- ``name`` is the interpreted role type or name. + +- ``rawtext`` is a string containing the entire interpreted text. + Include it as the content of a system message if there is a + problem. + +- ``text`` is the interpreted text content. + +- ``lineno`` is the line number where the interpreted text beings. + +- ``inliner`` is the Inliner object that called the role function. + It defines the following useful attributes: ``reporter``, + ``problematic``, ``memo``, ``parent``, ``document``. + +Interpreted role functions return a tuple of two values: + +- A list of nodes which will be inserted into the document tree at the + point where the interpreted role was encountered (can be an empty + list). + +- A list of messages, which will be inserted into the document tree + immediately after the end of the current inline block. +""" + +__docformat__ = 'reStructuredText' + +from docutils import nodes +from docutils.parsers.rst.languages import en as _fallback_language_module + +DEFAULT_INTERPRETED_ROLE = 'title-reference' +""" +The canonical name of the default interpreted role. This role is used +when no role is specified for a piece of interpreted text. +""" + +_roles = {} +""" +The interpreted role registry. This registry map canonical role names +to role functions. Language-dependent role names are defined in the +``language`` subpackage. +""" + +def role(role_name, language_module, lineno, inliner): + """ + Locate and return a role function from its language-dependent + name. If not found in the current language, check English. + Return None if the named role cannot be found. + """ + normname = role_name.lower() + messages = [] + msg_text = [] + + canonicalname = None + try: + canonicalname = language_module.roles[normname] + except AttributeError, error: + msg_text.append('Problem retrieving role entry from language ' + 'module %r: %s.' % (language_module, error)) + except KeyError: + msg_text.append('No role entry for "%s" in module "%s".' + % (role_name, language_module.__name__)) + + # If we didn't find it, try english as a fallback. + if not canonicalname: + try: + canonicalname = _fallback_language_module.roles[normname] + msg_text.append('Using English fallback for role "%s".' + % role_name) + except KeyError: + msg_text.append('Trying "%s" as canonical role name.' + % role_name) + # The canonical name should be an English name, but just in case: + canonicalname = normname + + # Collect any messages that we generated. + if msg_text: + message = inliner.reporter.info('\n'.join(msg_text), line=lineno) + messages.append(message) + + # Look the role up in the registry, and return it. + if _roles.has_key(canonicalname): + return _roles[canonicalname], messages + else: + return None, messages # Error message will be generated by caller. + +def register_role(name, role_fn): + """ + Register an interpreted role. + + :Parameters: + - `name`: The canonical name of the interpreted role. + - `role_fn`: The role function. See the module docstring for + `docutils.parsers.rst.roles` for a description of the + signature for `role_fn`. + """ + _roles[name] = role_fn + +###################################################################### +# Create and register the standard roles: +###################################################################### + +def make_generic_role(node_class, role, rawtext, text, lineno, inliner): + # If we wanted to, we could recursively call inliner.nested_parse + # to interpret the text contents here (after appropriately + # refactoring Inliner.parse). + return [node_class(rawtext, text)], [] + +# Helper function: +def register_generic_role(name, node_class): + def role_fn(role, rawtext, text, lineno, inliner, nc=node_class): + return make_generic_role(nc, role, rawtext, text, lineno, inliner) + register_role(name, role_fn) + +register_generic_role('abbreviation', nodes.abbreviation) +register_generic_role('acronym', nodes.acronym) +register_generic_role('emphasis', nodes.emphasis) +register_generic_role('literal', nodes.literal) +register_generic_role('strong', nodes.strong) +register_generic_role('subscript', nodes.subscript) +register_generic_role('superscript', nodes.superscript) +register_generic_role('title-reference', nodes.title_reference) + +def pep_reference_role(role, rawtext, text, lineno, inliner): + try: + pepnum = int(text) + if pepnum < 0 or pepnum > 9999: + raise ValueError + except ValueError: + msg = inliner.reporter.error( + 'PEP number must be a number from 0 to 9999; "%s" is invalid.' + % text, line=lineno) + prb = inliner.problematic(text, text, msg) + return [prb], [msg] + ref = inliner.pep_url % pepnum # [XX] + return [nodes.reference(rawtext, 'PEP ' + text, refuri=ref)], [] +register_role('pep-reference', pep_reference_role) + +def rfc_reference_role(role, rawtext, text, lineno, inliner): + try: + rfcnum = int(text) + if rfcnum <= 0: + raise ValueError + except ValueError: + msg = inliner.reporter.error( + 'RFC number must be a number greater than or equal to 1; ' + '"%s" is invalid.' % text, line=lineno) + prb = inliner.problematic(text, text, msg) + return [prb], [msg] + ref = inliner.rfc_url % rfcnum # [XX] + return [nodes.reference(rawtext, 'RFC ' + text, refuri=ref)], [] +register_role('rfc-reference', rfc_reference_role) + +###################################################################### +# Register roles that are currently unimplemented. +###################################################################### + +def unimplemented_role(role, rawtext, text, lineno, inliner): + msg = inliner.reporter.error( + 'Interpreted text role "%s" not implemented.' % role, line=lineno) + prb = inliner.problematic(rawtext, rawtext, msg) + return [prb], [msg] + +register_role('index', unimplemented_role) +register_role('named-reference', unimplemented_role) +register_role('anonymous-reference', unimplemented_role) +register_role('uri-reference', unimplemented_role) +register_role('footnote-reference', unimplemented_role) +register_role('citation-reference', unimplemented_role) +register_role('substitution-reference', unimplemented_role) +register_role('target', unimplemented_role) +register_role('restructuredtext-unimplemented-role', unimplemented_role) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 065eb6ef3..01075288f 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.parsers.rst import directives, languages, tableparser +from docutils.parsers.rst import directives, languages, tableparser, roles from docutils.parsers.rst.languages import en as _fallback_language_module @@ -475,47 +475,10 @@ class Inliner: """ Parse inline markup; call the `parse()` method. """ - - _interpreted_roles = { - # Values of ``None`` mean "not implemented yet": - 'title-reference': 'generic_interpreted_role', - 'abbreviation': 'generic_interpreted_role', - 'acronym': 'generic_interpreted_role', - 'index': None, - 'subscript': 'generic_interpreted_role', - 'superscript': 'generic_interpreted_role', - 'emphasis': 'generic_interpreted_role', - 'strong': 'generic_interpreted_role', - 'literal': 'generic_interpreted_role', - 'named-reference': None, - 'anonymous-reference': None, - 'uri-reference': None, - 'pep-reference': 'pep_reference_role', - 'rfc-reference': 'rfc_reference_role', - 'footnote-reference': None, - 'citation-reference': None, - 'substitution-reference': None, - 'target': None, - 'restructuredtext-unimplemented-role': None} - """Mapping of canonical interpreted text role name to method name. - Initializes a name to bound-method mapping in `__init__`.""" - default_interpreted_role = 'title-reference' """The role to use when no explicit role is given. Override in subclasses.""" - generic_roles = {'abbreviation': nodes.abbreviation, - 'acronym': nodes.acronym, - 'emphasis': nodes.emphasis, - 'literal': nodes.literal, - 'strong': nodes.strong, - 'subscript': nodes.subscript, - 'superscript': nodes.superscript, - 'title-reference': nodes.title_reference,} - """Mapping of canonical interpreted text role name to node class. - Used by the `generic_interpreted_role` method for simple, straightforward - roles (simple wrapping; no extra processing).""" - def __init__(self, roles=None): """ `roles` is a mapping of canonical role name to role function or bound @@ -526,17 +489,6 @@ class Inliner: """List of (pattern, bound method) tuples, used by `self.implicit_inline`.""" - self.interpreted_roles = {} - """Mapping of canonical role name to role function or bound method. - Items removed from this mapping will be disabled.""" - - for canonical, method in self._interpreted_roles.items(): - if method: - self.interpreted_roles[canonical] = getattr(self, method) - else: - self.interpreted_roles[canonical] = None - self.interpreted_roles.update(roles or {}) - def init_customizations(self, settings): """Setting-based customizations; run when parsing begins.""" if settings.pep_references: @@ -825,26 +777,11 @@ class Inliner: return self.phrase_ref(string[:matchstart], string[textend:], rawsource, escaped, text) else: - try: - return self.interpreted( - string[:rolestart], string[textend:], - rawsource, text, role, lineno) - except UnknownInterpretedRoleError, detail: - msg = self.reporter.error( - 'Unknown interpreted text role "%s".' % role, - line=lineno) - text = unescape(string[rolestart:textend], 1) - prb = self.problematic(text, text, msg) - return (string[:rolestart], [prb], string[textend:], - detail.args[0] + [msg]) - except InterpretedRoleNotImplementedError, detail: - msg = self.reporter.error( - 'Interpreted text role "%s" not implemented.' % role, - line=lineno) - text = unescape(string[rolestart:textend], 1) - prb = self.problematic(text, text, msg) - return (string[:rolestart], [prb], string[textend:], - detail.args[0] + [msg]) + rawsource = unescape(string[rolestart:textend], 1) + nodelist, messages = self.interpreted(rawsource, text, role, + lineno) + return (string[:rolestart], nodelist, + string[textend:], messages) msg = self.reporter.warning( 'Inline interpreted text or phrase reference start-string ' 'without end-string.', line=lineno) @@ -896,50 +833,19 @@ class Inliner: else: return uri - def interpreted(self, before, after, rawsource, text, role, lineno): - role_function, canonical, messages = self.get_role_function(role, - lineno) - if role_function: - nodelist, messages2 = role_function(canonical, rawsource, text, - lineno) - messages.extend(messages2) - return before, nodelist, after, messages + def interpreted(self, rawsource, text, role, lineno): + if not role: + role = roles.DEFAULT_INTERPRETED_ROLE + role_fn, messages = roles.role(role, self.language, lineno, self) + if role_fn: + nodes, messages2 = role_fn(role, rawsource, text, lineno, self) + return nodes, messages + messages2 else: - raise InterpretedRoleNotImplementedError(messages) - - def get_role_function(self, role, lineno): - messages = [] - msg_text = [] - if role: - name = role.lower() - canonical = None - try: - canonical = self.language.roles[name] - except AttributeError, error: - msg_text.append('Problem retrieving role entry from language ' - 'module %r: %s.' % (self.language, error)) - except KeyError: - msg_text.append('No role entry for "%s" in module "%s".' - % (name, self.language.__name__)) - else: - canonical = self.default_interpreted_role - if not canonical: - try: - canonical = _fallback_language_module.roles[name] - msg_text.append('Using English fallback for role "%s".' - % name) - except KeyError: - msg_text.append('Trying "%s" as canonical role name.' - % name) - # Should be an English name, but just in case: - canonical = name - if msg_text: - message = self.reporter.info('\n'.join(msg_text), line=lineno) - messages.append(message) - try: - return self.interpreted_roles[canonical], canonical, messages - except KeyError: - raise UnknownInterpretedRoleError(messages) + msg = self.reporter.error( + 'Unknown interpreted text role "%s".' % role, + line=lineno) + return ([self.problematic(rawsource, rawsource, msg)], + messages + [msg]) def literal(self, match, lineno): before, inlines, remaining, sysmessages, endstring = self.inline_obj( @@ -1110,45 +1016,6 @@ class Inliner: '_': reference, '__': anonymous_reference} - def generic_interpreted_role(self, role, rawtext, text, lineno): - try: - role_class = self.generic_roles[role] - except KeyError: - msg = self.reporter.error('Unknown interpreted text role: "%s".' - % role, line=lineno) - prb = self.problematic(text, text, msg) - return [prb], [msg] - return [role_class(rawtext, text)], [] - - def pep_reference_role(self, role, rawtext, text, lineno): - try: - pepnum = int(text) - if pepnum < 0 or pepnum > 9999: - raise ValueError - except ValueError: - msg = self.reporter.error( - 'PEP number must be a number from 0 to 9999; "%s" is invalid.' - % text, line=lineno) - prb = self.problematic(text, text, msg) - return [prb], [msg] - ref = self.pep_url % pepnum - return [nodes.reference(rawtext, 'PEP ' + text, refuri=ref)], [] - - def rfc_reference_role(self, role, rawtext, text, lineno): - try: - rfcnum = int(text) - if rfcnum <= 0: - raise ValueError - except ValueError: - msg = self.reporter.error( - 'RFC number must be a number greater than or equal to 1; ' - '"%s" is invalid.' % text, line=lineno) - prb = self.problematic(text, text, msg) - return [prb], [msg] - ref = self.rfc_url % rfcnum - return [nodes.reference(rawtext, 'RFC ' + text, refuri=ref)], [] - - class Body(RSTState): """ -- cgit v1.2.1 From e6e72312d4b0a56b625c7e40ed9ffbf265c1d33b Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 16 Apr 2004 15:16:24 +0000 Subject: bumped micro version due to API changes (interpreted text roles, and accumulated changes to date) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1944 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index 304e90ca4..dcf1fb8f9 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -51,7 +51,7 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.3.1' +__version__ = '0.3.2' """``major.minor.micro`` version number. The micro number is bumped any time there's a change in the API incompatible with one of the front ends or significant new functionality. The minor number is bumped whenever there is a -- cgit v1.2.1 From 3abac3279f845005f6313a8b0d16e14b6c8f8758 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 16 Apr 2004 15:38:21 +0000 Subject: Moved default interpreted text role processing to roles.py (canonical name, not language-dependent). Plus docstrings, whitespace. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1946 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/roles.py | 52 +++++++++++++++++++++++------------------- docutils/parsers/rst/states.py | 8 ++----- 2 files changed, 31 insertions(+), 29 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/roles.py b/docutils/parsers/rst/roles.py index fd44c33e1..03e4c934b 100644 --- a/docutils/parsers/rst/roles.py +++ b/docutils/parsers/rst/roles.py @@ -5,7 +5,9 @@ # Copyright: This module has been placed in the public domain. """ -This module defines a registry for interpreted roles. +This module defines standard interpreted text role functions, a registry for +interpreted text roles, and an API for adding to and retrieving from the +registry. The interface for interpreted role functions is as follows:: @@ -13,7 +15,7 @@ The interface for interpreted role functions is as follows:: code... Parameters: - + - ``name`` is the interpreted role type or name. - ``rawtext`` is a string containing the entire interpreted text. @@ -34,8 +36,8 @@ Interpreted role functions return a tuple of two values: point where the interpreted role was encountered (can be an empty list). -- A list of messages, which will be inserted into the document tree - immediately after the end of the current inline block. +- A list of system messages, which will be inserted into the document tree + immediately after the end of the current inline block (can also be empty). """ __docformat__ = 'reStructuredText' @@ -58,25 +60,28 @@ to role functions. Language-dependent role names are defined in the def role(role_name, language_module, lineno, inliner): """ - Locate and return a role function from its language-dependent - name. If not found in the current language, check English. - Return None if the named role cannot be found. + Locate and return a role function from its language-dependent name, along + with a list of system messages. If the role is not found in the current + language, check English. Return None if the named role cannot be found. """ normname = role_name.lower() messages = [] msg_text = [] - canonicalname = None - try: - canonicalname = language_module.roles[normname] - except AttributeError, error: - msg_text.append('Problem retrieving role entry from language ' - 'module %r: %s.' % (language_module, error)) - except KeyError: - msg_text.append('No role entry for "%s" in module "%s".' - % (role_name, language_module.__name__)) - - # If we didn't find it, try english as a fallback. + if role_name: + canonicalname = None + try: + canonicalname = language_module.roles[normname] + except AttributeError, error: + msg_text.append('Problem retrieving role entry from language ' + 'module %r: %s.' % (language_module, error)) + except KeyError: + msg_text.append('No role entry for "%s" in module "%s".' + % (role_name, language_module.__name__)) + else: + canonicalname = DEFAULT_INTERPRETED_ROLE + + # If we didn't find it, try English as a fallback. if not canonicalname: try: canonicalname = _fallback_language_module.roles[normname] @@ -92,17 +97,17 @@ def role(role_name, language_module, lineno, inliner): if msg_text: message = inliner.reporter.info('\n'.join(msg_text), line=lineno) messages.append(message) - + # Look the role up in the registry, and return it. if _roles.has_key(canonicalname): return _roles[canonicalname], messages else: return None, messages # Error message will be generated by caller. - + def register_role(name, role_fn): """ - Register an interpreted role. - + Register an interpreted text role. + :Parameters: - `name`: The canonical name of the interpreted role. - `role_fn`: The role function. See the module docstring for @@ -150,7 +155,7 @@ def pep_reference_role(role, rawtext, text, lineno, inliner): ref = inliner.pep_url % pepnum # [XX] return [nodes.reference(rawtext, 'PEP ' + text, refuri=ref)], [] register_role('pep-reference', pep_reference_role) - + def rfc_reference_role(role, rawtext, text, lineno, inliner): try: rfcnum = int(text) @@ -184,4 +189,5 @@ register_role('footnote-reference', unimplemented_role) register_role('citation-reference', unimplemented_role) register_role('substitution-reference', unimplemented_role) register_role('target', unimplemented_role) +# This one should remain unimplemented, for testing purposes: register_role('restructuredtext-unimplemented-role', unimplemented_role) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 01075288f..5d7c463dc 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -475,9 +475,6 @@ class Inliner: """ Parse inline markup; call the `parse()` method. """ - default_interpreted_role = 'title-reference' - """The role to use when no explicit role is given. - Override in subclasses.""" def __init__(self, roles=None): """ @@ -834,8 +831,6 @@ class Inliner: return uri def interpreted(self, rawsource, text, role, lineno): - if not role: - role = roles.DEFAULT_INTERPRETED_ROLE role_fn, messages = roles.role(role, self.language, lineno, self) if role_fn: nodes, messages2 = role_fn(role, rawsource, text, lineno, self) @@ -926,7 +921,7 @@ class Inliner: referencename = match.group('refname') refname = normalize_name(referencename) referencenode = nodes.reference( - referencename + match.group('refend'), referencename, + referencename + match.group('refend'), referencename, name=whitespace_normalize_name(referencename)) if anonymous: referencenode['anonymous'] = 1 @@ -1016,6 +1011,7 @@ class Inliner: '_': reference, '__': anonymous_reference} + class Body(RSTState): """ -- cgit v1.2.1 From 93c6daeb478ddb3486dc9b4283582e3d73dca23b Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 16 Apr 2004 15:39:27 +0000 Subject: docstring git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1948 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 23ef04188..a7e434b08 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -193,7 +193,10 @@ def directive(directive_name, language_module, document): return function, messages def register_directive(name, directive): - """Register a nonstandard application-defined directive function.""" + """ + Register a nonstandard application-defined directive function. + Language lookups are not needed for such functions. + """ _directives[name] = directive def flag(argument): -- cgit v1.2.1 From 55963837e360331f7c6f0ef94580e4c1f4f3027c Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 16 Apr 2004 16:41:35 +0000 Subject: implemented local registry git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1950 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/roles.py | 63 ++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 24 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/roles.py b/docutils/parsers/rst/roles.py index 03e4c934b..cd76b58d6 100644 --- a/docutils/parsers/rst/roles.py +++ b/docutils/parsers/rst/roles.py @@ -51,12 +51,14 @@ The canonical name of the default interpreted role. This role is used when no role is specified for a piece of interpreted text. """ +_role_registry = {} +"""Mapping of canonical role names to role functions. Language-dependent role +names are defined in the ``language`` subpackage. """ + _roles = {} -""" -The interpreted role registry. This registry map canonical role names -to role functions. Language-dependent role names are defined in the -``language`` subpackage. -""" +"""Mapping of language-dependent interpreted text role names to already +imported directive functions.""" + def role(role_name, language_module, lineno, inliner): """ @@ -68,6 +70,9 @@ def role(role_name, language_module, lineno, inliner): messages = [] msg_text = [] + if _roles.has_key(normname): + return _roles[normname], messages + if role_name: canonicalname = None try: @@ -99,20 +104,30 @@ def role(role_name, language_module, lineno, inliner): messages.append(message) # Look the role up in the registry, and return it. - if _roles.has_key(canonicalname): - return _roles[canonicalname], messages + if _role_registry.has_key(canonicalname): + role_fn = _role_registry[canonicalname] + register_local_role(normname, role_fn) + return role_fn, messages else: return None, messages # Error message will be generated by caller. -def register_role(name, role_fn): +def register_canonical_role(name, role_fn): """ - Register an interpreted text role. + Register an interpreted text role by its canonical name. :Parameters: - `name`: The canonical name of the interpreted role. - - `role_fn`: The role function. See the module docstring for - `docutils.parsers.rst.roles` for a description of the - signature for `role_fn`. + - `role_fn`: The role function. See the module docstring. + """ + _role_registry[name] = role_fn + +def register_local_role(name, role_fn): + """ + Register an interpreted text role by its local or language-dependent name. + + :Parameters: + - `name`: The local or language-dependent name of the interpreted role. + - `role_fn`: The role function. See the module docstring. """ _roles[name] = role_fn @@ -130,7 +145,7 @@ def make_generic_role(node_class, role, rawtext, text, lineno, inliner): def register_generic_role(name, node_class): def role_fn(role, rawtext, text, lineno, inliner, nc=node_class): return make_generic_role(nc, role, rawtext, text, lineno, inliner) - register_role(name, role_fn) + register_canonical_role(name, role_fn) register_generic_role('abbreviation', nodes.abbreviation) register_generic_role('acronym', nodes.acronym) @@ -154,7 +169,7 @@ def pep_reference_role(role, rawtext, text, lineno, inliner): return [prb], [msg] ref = inliner.pep_url % pepnum # [XX] return [nodes.reference(rawtext, 'PEP ' + text, refuri=ref)], [] -register_role('pep-reference', pep_reference_role) +register_canonical_role('pep-reference', pep_reference_role) def rfc_reference_role(role, rawtext, text, lineno, inliner): try: @@ -169,7 +184,7 @@ def rfc_reference_role(role, rawtext, text, lineno, inliner): return [prb], [msg] ref = inliner.rfc_url % rfcnum # [XX] return [nodes.reference(rawtext, 'RFC ' + text, refuri=ref)], [] -register_role('rfc-reference', rfc_reference_role) +register_canonical_role('rfc-reference', rfc_reference_role) ###################################################################### # Register roles that are currently unimplemented. @@ -181,13 +196,13 @@ def unimplemented_role(role, rawtext, text, lineno, inliner): prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] -register_role('index', unimplemented_role) -register_role('named-reference', unimplemented_role) -register_role('anonymous-reference', unimplemented_role) -register_role('uri-reference', unimplemented_role) -register_role('footnote-reference', unimplemented_role) -register_role('citation-reference', unimplemented_role) -register_role('substitution-reference', unimplemented_role) -register_role('target', unimplemented_role) +register_canonical_role('index', unimplemented_role) +register_canonical_role('named-reference', unimplemented_role) +register_canonical_role('anonymous-reference', unimplemented_role) +register_canonical_role('uri-reference', unimplemented_role) +register_canonical_role('footnote-reference', unimplemented_role) +register_canonical_role('citation-reference', unimplemented_role) +register_canonical_role('substitution-reference', unimplemented_role) +register_canonical_role('target', unimplemented_role) # This one should remain unimplemented, for testing purposes: -register_role('restructuredtext-unimplemented-role', unimplemented_role) +register_canonical_role('restructuredtext-unimplemented-role', unimplemented_role) -- cgit v1.2.1 From 0cf74910395c458d284ad0172097100427b9297e Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 16 Apr 2004 17:14:14 +0000 Subject: docstring fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1951 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/roles.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/roles.py b/docutils/parsers/rst/roles.py index cd76b58d6..262abf87a 100644 --- a/docutils/parsers/rst/roles.py +++ b/docutils/parsers/rst/roles.py @@ -53,12 +53,11 @@ when no role is specified for a piece of interpreted text. _role_registry = {} """Mapping of canonical role names to role functions. Language-dependent role -names are defined in the ``language`` subpackage. """ +names are defined in the ``language`` subpackage.""" _roles = {} -"""Mapping of language-dependent interpreted text role names to already -imported directive functions.""" - +"""Mapping of local or language-dependent interpreted text role names to role +functions.""" def role(role_name, language_module, lineno, inliner): """ -- cgit v1.2.1 From 85211ceb10f91f02f40ad54f6936621c8d57f929 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 17 Apr 2004 17:36:18 +0000 Subject: renamed pt-br.py to pt_br.py to conform with Python naming conventions and to allow normal imports git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1954 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/pt-br.py | 63 ---------------------- docutils/languages/pt_br.py | 63 ++++++++++++++++++++++ docutils/parsers/rst/languages/pt-br.py | 96 --------------------------------- docutils/parsers/rst/languages/pt_br.py | 96 +++++++++++++++++++++++++++++++++ 4 files changed, 159 insertions(+), 159 deletions(-) delete mode 100644 docutils/languages/pt-br.py create mode 100644 docutils/languages/pt_br.py delete mode 100644 docutils/parsers/rst/languages/pt-br.py create mode 100644 docutils/parsers/rst/languages/pt_br.py (limited to 'docutils') diff --git a/docutils/languages/pt-br.py b/docutils/languages/pt-br.py deleted file mode 100644 index d9b9f3ca5..000000000 --- a/docutils/languages/pt-br.py +++ /dev/null @@ -1,63 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# 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. - -""" -Brazilian Portuguese-language mappings for language-dependent features of Docutils. -""" - -__docformat__ = 'reStructuredText' - -labels = { - # fixed: language-dependent - 'author': u'Autor', - 'authors': u'Autores', - 'organization': unicode('Organizao', 'latin1'), - 'address': unicode('Endereo', 'latin1'), - 'contact': u'Contato', - 'version': unicode('Verso', 'latin1'), - 'revision': unicode('Reviso', 'latin1'), - 'status': u'Estado', - 'date': u'Data', - 'copyright': u'Copyright', - 'dedication': unicode('Dedicatria', 'latin1'), - 'abstract': u'Resumo', - 'attention': unicode('Atteno!', 'latin1'), - 'caution': u'Cuidado!', - 'danger': u'PERIGO!', - 'error': u'Erro', - 'hint': unicode('Sugesto', 'latin1'), - 'important': u'Importante', - 'note': u'Nota', - 'tip': u'Dica', - 'warning': u'Aviso', - 'contents': unicode('Sumrio', 'latin1')} -"""Mapping of node class name to label text.""" - -bibliographic_fields = { - # language-dependent: fixed - u'autor': 'author', - u'autores': 'authors', - unicode('organizao', 'latin1'): 'organization', - unicode('endereo', 'latin1'): 'address', - u'contato': 'contact', - unicode('verso', 'latin1'): 'version', - unicode('reviso', 'latin1'): 'revision', - u'estado': 'status', - u'data': 'date', - u'copyright': 'copyright', - unicode('dedicatria', 'latin1'): 'dedication', - u'resumo': 'abstract'} -"""English (lowcased) to canonical name mapping for bibliographic fields.""" - -author_separators = [';', ','] -"""List of separator strings for the 'Authors' bibliographic field. Tried in -order.""" diff --git a/docutils/languages/pt_br.py b/docutils/languages/pt_br.py new file mode 100644 index 000000000..d9b9f3ca5 --- /dev/null +++ b/docutils/languages/pt_br.py @@ -0,0 +1,63 @@ +# -*- coding: iso-8859-1 -*- +# 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. + +""" +Brazilian Portuguese-language mappings for language-dependent features of Docutils. +""" + +__docformat__ = 'reStructuredText' + +labels = { + # fixed: language-dependent + 'author': u'Autor', + 'authors': u'Autores', + 'organization': unicode('Organizao', 'latin1'), + 'address': unicode('Endereo', 'latin1'), + 'contact': u'Contato', + 'version': unicode('Verso', 'latin1'), + 'revision': unicode('Reviso', 'latin1'), + 'status': u'Estado', + 'date': u'Data', + 'copyright': u'Copyright', + 'dedication': unicode('Dedicatria', 'latin1'), + 'abstract': u'Resumo', + 'attention': unicode('Atteno!', 'latin1'), + 'caution': u'Cuidado!', + 'danger': u'PERIGO!', + 'error': u'Erro', + 'hint': unicode('Sugesto', 'latin1'), + 'important': u'Importante', + 'note': u'Nota', + 'tip': u'Dica', + 'warning': u'Aviso', + 'contents': unicode('Sumrio', 'latin1')} +"""Mapping of node class name to label text.""" + +bibliographic_fields = { + # language-dependent: fixed + u'autor': 'author', + u'autores': 'authors', + unicode('organizao', 'latin1'): 'organization', + unicode('endereo', 'latin1'): 'address', + u'contato': 'contact', + unicode('verso', 'latin1'): 'version', + unicode('reviso', 'latin1'): 'revision', + u'estado': 'status', + u'data': 'date', + u'copyright': 'copyright', + unicode('dedicatria', 'latin1'): 'dedication', + u'resumo': 'abstract'} +"""English (lowcased) to canonical name mapping for bibliographic fields.""" + +author_separators = [';', ','] +"""List of separator strings for the 'Authors' bibliographic field. Tried in +order.""" diff --git a/docutils/parsers/rst/languages/pt-br.py b/docutils/parsers/rst/languages/pt-br.py deleted file mode 100644 index 6f8e3cf21..000000000 --- a/docutils/parsers/rst/languages/pt-br.py +++ /dev/null @@ -1,96 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# 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. - -""" -Brazilian Portuguese-language mappings for language-dependent features of -reStructuredText. -""" - -__docformat__ = 'reStructuredText' - - -directives = { - # language-dependent: fixed - u'ateno': 'attention', - 'cuidado': 'caution', - 'perigo': 'danger', - 'erro': 'error', - u'sugesto': 'hint', - 'importante': 'important', - 'nota': 'note', - 'dica': 'tip', - 'aviso': 'warning', - u'exortao': 'admonition', - 'barra-lateral': 'sidebar', - u'tpico': 'topic', - 'bloco-de-linhas': 'line-block', - 'literal-interpretado': 'parsed-literal', - 'rubrica': 'rubric', - u'epgrafo': 'epigraph', - 'destaques': 'highlights', - u'citao-destacada': 'pull-quote', - u'table (translation required)': 'table', - #'perguntas': 'questions', - #'qa': 'questions', - #'faq': 'questions', - 'meta': 'meta', - #'imagemap': 'imagemap', - 'imagem': 'image', - 'figura': 'figure', - u'incluso': 'include', - 'cru': 'raw', - u'substituio': 'replace', - 'unicode': 'unicode', - 'classe': 'class', - u'ndice': 'contents', - 'numsec': 'sectnum', - u'numerao-de-sees': 'sectnum', - #u'notas-de-rorap': 'footnotes', - #u'citaes': 'citations', - u'links-no-rodap': 'target-notes', - 'restructuredtext-test-directive': 'restructuredtext-test-directive'} -"""English name to registered (in directives/__init__.py) directive name -mapping.""" - -roles = { - # language-dependent: fixed - u'abbreviao': 'abbreviation', - 'ab': 'abbreviation', - u'acrnimo': 'acronym', - 'ac': 'acronym', - u'ndice-remissivo': 'index', - 'i': 'index', - 'subscrito': 'subscript', - 'sub': 'subscript', - 'sobrescrito': 'superscript', - 'sob': 'superscript', - u'referncia-a-ttulo': 'title-reference', - u'ttulo': 'title-reference', - 't': 'title-reference', - u'referncia-a-pep': 'pep-reference', - 'pep': 'pep-reference', - u'referncia-a-rfc': 'rfc-reference', - 'rfc': 'rfc-reference', - u'nfase': 'emphasis', - 'forte': 'strong', - 'literal': 'literal', - u'referncia-por-nome': 'named-reference', - u'referncia-annima': 'anonymous-reference', - u'referncia-a-nota-de-rodap': 'footnote-reference', - u'referncia-a-citao': 'citation-reference', - u'referncia-a-substituio': 'substitution-reference', - 'alvo': 'target', - u'referncia-a-uri': 'uri-reference', - 'uri': 'uri-reference', - 'url': 'uri-reference',} -"""Mapping of English role names to canonical role names for interpreted text. -""" diff --git a/docutils/parsers/rst/languages/pt_br.py b/docutils/parsers/rst/languages/pt_br.py new file mode 100644 index 000000000..6f8e3cf21 --- /dev/null +++ b/docutils/parsers/rst/languages/pt_br.py @@ -0,0 +1,96 @@ +# -*- coding: iso-8859-1 -*- +# 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. + +""" +Brazilian Portuguese-language mappings for language-dependent features of +reStructuredText. +""" + +__docformat__ = 'reStructuredText' + + +directives = { + # language-dependent: fixed + u'ateno': 'attention', + 'cuidado': 'caution', + 'perigo': 'danger', + 'erro': 'error', + u'sugesto': 'hint', + 'importante': 'important', + 'nota': 'note', + 'dica': 'tip', + 'aviso': 'warning', + u'exortao': 'admonition', + 'barra-lateral': 'sidebar', + u'tpico': 'topic', + 'bloco-de-linhas': 'line-block', + 'literal-interpretado': 'parsed-literal', + 'rubrica': 'rubric', + u'epgrafo': 'epigraph', + 'destaques': 'highlights', + u'citao-destacada': 'pull-quote', + u'table (translation required)': 'table', + #'perguntas': 'questions', + #'qa': 'questions', + #'faq': 'questions', + 'meta': 'meta', + #'imagemap': 'imagemap', + 'imagem': 'image', + 'figura': 'figure', + u'incluso': 'include', + 'cru': 'raw', + u'substituio': 'replace', + 'unicode': 'unicode', + 'classe': 'class', + u'ndice': 'contents', + 'numsec': 'sectnum', + u'numerao-de-sees': 'sectnum', + #u'notas-de-rorap': 'footnotes', + #u'citaes': 'citations', + u'links-no-rodap': 'target-notes', + 'restructuredtext-test-directive': 'restructuredtext-test-directive'} +"""English name to registered (in directives/__init__.py) directive name +mapping.""" + +roles = { + # language-dependent: fixed + u'abbreviao': 'abbreviation', + 'ab': 'abbreviation', + u'acrnimo': 'acronym', + 'ac': 'acronym', + u'ndice-remissivo': 'index', + 'i': 'index', + 'subscrito': 'subscript', + 'sub': 'subscript', + 'sobrescrito': 'superscript', + 'sob': 'superscript', + u'referncia-a-ttulo': 'title-reference', + u'ttulo': 'title-reference', + 't': 'title-reference', + u'referncia-a-pep': 'pep-reference', + 'pep': 'pep-reference', + u'referncia-a-rfc': 'rfc-reference', + 'rfc': 'rfc-reference', + u'nfase': 'emphasis', + 'forte': 'strong', + 'literal': 'literal', + u'referncia-por-nome': 'named-reference', + u'referncia-annima': 'anonymous-reference', + u'referncia-a-nota-de-rodap': 'footnote-reference', + u'referncia-a-citao': 'citation-reference', + u'referncia-a-substituio': 'substitution-reference', + 'alvo': 'target', + u'referncia-a-uri': 'uri-reference', + 'uri': 'uri-reference', + 'url': 'uri-reference',} +"""Mapping of English role names to canonical role names for interpreted text. +""" -- cgit v1.2.1 From 917d7123f53aa0ba69c2ebcfed167acaac9c4931 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 17 Apr 2004 22:47:37 +0000 Subject: added support for custom interpreted text roles git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1958 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/roles.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/roles.py b/docutils/parsers/rst/roles.py index 262abf87a..a7d1333bc 100644 --- a/docutils/parsers/rst/roles.py +++ b/docutils/parsers/rst/roles.py @@ -134,16 +134,17 @@ def register_local_role(name, role_fn): # Create and register the standard roles: ###################################################################### -def make_generic_role(node_class, role, rawtext, text, lineno, inliner): +def generic_role(node_class, role, rawtext, text, lineno, inliner, + attributes={}): # If we wanted to, we could recursively call inliner.nested_parse # to interpret the text contents here (after appropriately # refactoring Inliner.parse). - return [node_class(rawtext, text)], [] + return [node_class(rawtext, text, **attributes)], [] # Helper function: def register_generic_role(name, node_class): def role_fn(role, rawtext, text, lineno, inliner, nc=node_class): - return make_generic_role(nc, role, rawtext, text, lineno, inliner) + return generic_role(nc, role, rawtext, text, lineno, inliner) register_canonical_role(name, role_fn) register_generic_role('abbreviation', nodes.abbreviation) @@ -155,6 +156,12 @@ register_generic_role('subscript', nodes.subscript) register_generic_role('superscript', nodes.superscript) register_generic_role('title-reference', nodes.title_reference) +def register_custom_role(name, attributes): + def role_fn(role, rawtext, text, lineno, inliner, atts=attributes): + return generic_role(nodes.inline, role, rawtext, text, lineno, inliner, + attributes=atts) + register_local_role(name, role_fn) + def pep_reference_role(role, rawtext, text, lineno, inliner): try: pepnum = int(text) -- cgit v1.2.1 From 5de4bec88b62acfa5cd0da03753f96b67603799c Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 17 Apr 2004 22:50:37 +0000 Subject: added "role" directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1959 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 6 +++++- docutils/parsers/rst/directives/misc.py | 23 +++++++++++++++++++++-- docutils/parsers/rst/languages/af.py | 1 + docutils/parsers/rst/languages/cs.py | 1 + docutils/parsers/rst/languages/de.py | 3 ++- 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/fr.py | 1 + docutils/parsers/rst/languages/it.py | 3 ++- 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 + 14 files changed, 40 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index a7e434b08..c2a1b5210 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -118,6 +118,7 @@ _directive_registry = { 'replace': ('misc', 'replace'), 'unicode': ('misc', 'unicode_directive'), 'class': ('misc', 'class_directive'), + 'role': ('misc', 'role'), 'restructuredtext-test-directive': ('misc', 'directive_test_function'),} """Mapping of directive name to (module name, function name). The directive name is canonical & must be lowercase. Language-dependent names are defined @@ -272,7 +273,10 @@ def class_option(argument): """ if argument is None: raise ValueError('argument required but none supplied') - return nodes.make_id(argument) + class_name = nodes.make_id(argument) + if not class_name: + raise ValueError('cannot make "%s" into a class name' % argument) + return class_name def format_values(values): return '%s, or "%s"' % (', '.join(['"%s"' % s for s in values[:-1]]), diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 446935831..762d42300 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -12,7 +12,7 @@ import sys import os.path import re from docutils import io, nodes, statemachine, utils -from docutils.parsers.rst import directives, states +from docutils.parsers.rst import directives, roles, states from docutils.transforms import misc try: @@ -220,7 +220,7 @@ def class_directive(name, arguments, options, content, lineno, return [pending] else: error = state_machine.reporter.error( - 'Invalid class attribute value for "%s" directive: %s' + 'Invalid class attribute value for "%s" directive: "%s".' % (name, arguments[0]), nodes.literal_block(block_text, block_text), line=lineno) return [error] @@ -245,3 +245,22 @@ def directive_test_function(name, arguments, options, content, lineno, directive_test_function.arguments = (0, 1, 1) directive_test_function.options = {'option': directives.unchanged_required} directive_test_function.content = 1 + +def role(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + """Dynamically create and register a custom interpreted text role.""" + role_name = arguments[0].lower() + if not options.has_key('class'): + try: + options['class'] = directives.class_option(role_name) + except ValueError, detail: + error = state_machine.reporter.error( + 'Invalid argument for "%s" directive:\n%s.' + % (name, detail), + nodes.literal_block(block_text, block_text), line=lineno) + return [error] + roles.register_custom_role(role_name, options) + return [] + +role.arguments = (1, 0, 0) +role.options = {'class': directives.class_option} diff --git a/docutils/parsers/rst/languages/af.py b/docutils/parsers/rst/languages/af.py index f714ca9b1..ed750a586 100644 --- a/docutils/parsers/rst/languages/af.py +++ b/docutils/parsers/rst/languages/af.py @@ -49,6 +49,7 @@ directives = { 'vervang': 'replace', 'unicode': 'unicode', # should this be translated? unikode 'klas': 'class', + 'role (translation required)': 'role', 'inhoud': 'contents', 'sectnum': 'sectnum', 'section-numbering': 'sectnum', diff --git a/docutils/parsers/rst/languages/cs.py b/docutils/parsers/rst/languages/cs.py index 23c551140..6e836c81b 100644 --- a/docutils/parsers/rst/languages/cs.py +++ b/docutils/parsers/rst/languages/cs.py @@ -50,6 +50,7 @@ directives = { u'replace': 'replace', u'unicode': 'unicode', u't\u0159\u00EDda': 'class', + u'role (translation required)': 'role', u'obsah': 'contents', u'sectnum': 'sectnum', u'section-numbering': 'sectnum', diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index cc3b71138..73ccd90d1 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -50,7 +50,8 @@ directives = { # einfgung would be the noun. 'ersetzung': 'replace', # ersetzen, ersetze 'unicode': 'unicode', - 'klasse': 'class', # offer class too ? + 'klasse': 'class', # offer "class" too ? + 'role (translation required)': 'role', 'inhalt': 'contents', 'sectnum': 'sectnum', 'section-numbering': 'sectnum', diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index d9068ee8e..291404372 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -50,6 +50,7 @@ directives = { 'replace': 'replace', 'unicode': 'unicode', 'class': 'class', + 'role': '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 dc9f59aa2..08855fa51 100644 --- a/docutils/parsers/rst/languages/eo.py +++ b/docutils/parsers/rst/languages/eo.py @@ -54,6 +54,7 @@ directives = { u'anstata\u016di': 'replace', u'unicode': 'unicode', u'klaso': 'class', + u'role (translation required)': '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 f1354778b..2e1da7cfc 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -55,6 +55,7 @@ directives = { u'reemplazar': 'replace', u'unicode': 'unicode', u'clase': 'class', + u'role (translation required)': 'role', u'contenido': 'contents', u'numseccion': 'sectnum', u'numsecci\u00f3n': 'sectnum', diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index 6ed792430..12ab694a0 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -52,6 +52,7 @@ directives = { u'remplace': 'replace', u'unicode': 'unicode', u'classe': 'class', + u'role (translation required)': 'role', u'sommaire': 'contents', u'table-des-mati\u00E8res': 'contents', u'sectnum': 'sectnum', diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index fc08452e1..c794528e0 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -31,7 +31,7 @@ directives = { 'epigrafe': 'epigraph', 'highlights (translation required)': 'highlights', 'pull-quote (translation required)': 'pull-quote', - u'table (translation required)': 'table', + 'table (translation required)': 'table', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', @@ -44,6 +44,7 @@ directives = { 'sostituisci': 'replace', 'unicode': 'unicode', 'classe': 'class', + 'role (translation required)': 'role', 'indice': 'contents', 'seznum': 'sectnum', 'sezioni-autonumerate': 'sectnum', diff --git a/docutils/parsers/rst/languages/pt_br.py b/docutils/parsers/rst/languages/pt_br.py index 6f8e3cf21..de06a74da 100644 --- a/docutils/parsers/rst/languages/pt_br.py +++ b/docutils/parsers/rst/languages/pt_br.py @@ -51,6 +51,7 @@ directives = { u'substituio': 'replace', 'unicode': 'unicode', 'classe': 'class', + 'role (translation required)': 'role', u'ndice': 'contents', 'numsec': 'sectnum', u'numerao-de-sees': 'sectnum', diff --git a/docutils/parsers/rst/languages/ru.py b/docutils/parsers/rst/languages/ru.py index 40823dd81..307c55a00 100644 --- a/docutils/parsers/rst/languages/ru.py +++ b/docutils/parsers/rst/languages/ru.py @@ -41,6 +41,7 @@ directives = { u'\u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435': u'image', u'\u043a\u043b\u0430\u0441\u0441': u'class', + u'role (translation required)': 'role', u'\u043d\u043e\u043c\u0435\u0440-\u0440\u0430\u0437\u0434\u0435\u043b\u0430': u'sectnum', u'\u043d\u0443\u043c\u0435\u0440\u0430\u0446\u0438\u044f-\u0440\u0430\u0437' diff --git a/docutils/parsers/rst/languages/sk.py b/docutils/parsers/rst/languages/sk.py index 83f101908..64af4ac1a 100644 --- a/docutils/parsers/rst/languages/sk.py +++ b/docutils/parsers/rst/languages/sk.py @@ -49,6 +49,7 @@ directives = { u'nahradi\x9d': 'replace', u'unicode': 'unicode', u'class (translation required)': 'class', + u'role (translation required)': 'role', u'obsah': 'contents', u'\xe8as\x9d': 'sectnum', u'\xe8as\x9d-\xe8\xedslovanie': 'sectnum', diff --git a/docutils/parsers/rst/languages/sv.py b/docutils/parsers/rst/languages/sv.py index 3409c30f2..9f6e8234c 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -49,6 +49,7 @@ directives = { u'ers\u00e4tt': 'replace', u'unicode': 'unicode', u'class (translation required)': 'class', + u'role (translation required)': 'role', u'inneh\u00e5ll': 'contents', u'sektionsnumrering': 'sectnum', u'target-notes (translation required)': 'target-notes', -- cgit v1.2.1 From 8c9bc8f14cd60ee09168be25c62cb2be4b646d3a Mon Sep 17 00:00:00 2001 From: richieadler Date: Sat, 17 Apr 2004 23:13:20 +0000 Subject: Translation to esperanto and spanish of the "role" directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1961 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/eo.py | 2 +- docutils/parsers/rst/languages/es.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/eo.py b/docutils/parsers/rst/languages/eo.py index 08855fa51..7101a082a 100644 --- a/docutils/parsers/rst/languages/eo.py +++ b/docutils/parsers/rst/languages/eo.py @@ -54,7 +54,7 @@ directives = { u'anstata\u016di': 'replace', u'unicode': 'unicode', u'klaso': 'class', - u'role (translation required)': 'role', + u'rolo': '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 2e1da7cfc..08d73e183 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -55,7 +55,7 @@ directives = { u'reemplazar': 'replace', u'unicode': 'unicode', u'clase': 'class', - u'role (translation required)': 'role', + u'rol': 'role', u'contenido': 'contents', u'numseccion': 'sectnum', u'numsecci\u00f3n': 'sectnum', -- cgit v1.2.1 From b4f3a6112f1915b50686c6512be6c491dfb9810f Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 18 Apr 2004 21:58:35 +0000 Subject: moved test directive last git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1966 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 37 +++++++++++++++++---------------- 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 762d42300..4352c846a 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -228,24 +228,6 @@ def class_directive(name, arguments, options, content, lineno, class_directive.arguments = (1, 0, 0) class_directive.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", 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", 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_required} -directive_test_function.content = 1 - def role(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """Dynamically create and register a custom interpreted text role.""" @@ -264,3 +246,22 @@ def role(name, arguments, options, content, lineno, role.arguments = (1, 0, 0) role.options = {'class': directives.class_option} + +def directive_test_function(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + """This directive is useful only for testing purposes.""" + if content: + text = '\n'.join(content) + info = state_machine.reporter.info( + '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", 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_required} +directive_test_function.content = 1 -- cgit v1.2.1 From 08958ecc17290adb1bc99df3bcfba29d9a30874d Mon Sep 17 00:00:00 2001 From: lele Date: Mon, 19 Apr 2004 00:44:47 +0000 Subject: Added 'role' translation git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1967 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/it.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index c794528e0..cdfd0492c 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -29,9 +29,9 @@ directives = { 'blocco-interpretato': 'parsed-literal', 'rubrica': 'rubric', 'epigrafe': 'epigraph', - 'highlights (translation required)': 'highlights', + 'evidenzia': 'highlights', 'pull-quote (translation required)': 'pull-quote', - 'table (translation required)': 'table', + 'tabella': 'table', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', @@ -44,7 +44,7 @@ directives = { 'sostituisci': 'replace', 'unicode': 'unicode', 'classe': 'class', - 'role (translation required)': 'role', + 'ruolo': 'role', 'indice': 'contents', 'seznum': 'sectnum', 'sezioni-autonumerate': 'sectnum', -- cgit v1.2.1 From 88c2b891564b4b5711743f7d42f96d24f8f23787 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 19 Apr 2004 01:23:20 +0000 Subject: code layout & docstrings git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1970 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/roles.py | 48 ++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 21 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/roles.py b/docutils/parsers/rst/roles.py index a7d1333bc..de5f106c6 100644 --- a/docutils/parsers/rst/roles.py +++ b/docutils/parsers/rst/roles.py @@ -11,16 +11,16 @@ registry. The interface for interpreted role functions is as follows:: - def role_fn(name, rawtext, text, lineno, inliner): + def role_fn(name, rawtext, text, lineno, inliner, attributes={}): code... Parameters: -- ``name`` is the interpreted role type or name. +- ``name`` is the local name of the interpreted text role, the role name + actually used in the document. -- ``rawtext`` is a string containing the entire interpreted text. - Include it as the content of a system message if there is a - problem. +- ``rawtext`` is a string containing the entire interpreted text construct. + Include it as a literal block in a system message if there is a problem. - ``text`` is the interpreted text content. @@ -30,6 +30,9 @@ Parameters: It defines the following useful attributes: ``reporter``, ``problematic``, ``memo``, ``parent``, ``document``. +- ``attributes``: A dictionary of additional attributes for the generated + elements, used for customization. + Interpreted role functions return a tuple of two values: - A list of nodes which will be inserted into the document tree at the @@ -130,22 +133,31 @@ def register_local_role(name, role_fn): """ _roles[name] = role_fn -###################################################################### -# Create and register the standard roles: -###################################################################### +def register_generic_role(canonical_name, node_class): + """For roles which simply wrap a given `node_class` around the text.""" + # Dynamically define a role function: + def role_fn(role, rawtext, text, lineno, inliner, nc=node_class): + return generic_role_helper(nc, role, rawtext, text, lineno, inliner) + # Register the role: + register_canonical_role(canonical_name, role_fn) -def generic_role(node_class, role, rawtext, text, lineno, inliner, - attributes={}): +def generic_role_helper(node_class, role, rawtext, text, lineno, inliner, + attributes={}): # If we wanted to, we could recursively call inliner.nested_parse # to interpret the text contents here (after appropriately # refactoring Inliner.parse). return [node_class(rawtext, text, **attributes)], [] -# Helper function: -def register_generic_role(name, node_class): - def role_fn(role, rawtext, text, lineno, inliner, nc=node_class): - return generic_role(nc, role, rawtext, text, lineno, inliner) - register_canonical_role(name, role_fn) +def register_custom_role(local_name, attributes): + """For roles defined in a document.""" + def role_fn(role, rawtext, text, lineno, inliner, atts=attributes): + return generic_role_helper( + nodes.inline, role, rawtext, text, lineno, inliner, attributes=atts) + register_local_role(local_name, role_fn) + +###################################################################### +# Define and register the standard roles: +###################################################################### register_generic_role('abbreviation', nodes.abbreviation) register_generic_role('acronym', nodes.acronym) @@ -156,12 +168,6 @@ register_generic_role('subscript', nodes.subscript) register_generic_role('superscript', nodes.superscript) register_generic_role('title-reference', nodes.title_reference) -def register_custom_role(name, attributes): - def role_fn(role, rawtext, text, lineno, inliner, atts=attributes): - return generic_role(nodes.inline, role, rawtext, text, lineno, inliner, - attributes=atts) - register_local_role(name, role_fn) - def pep_reference_role(role, rawtext, text, lineno, inliner): try: pepnum = int(text) -- cgit v1.2.1 From fa4714e71e65d48d849645f72a348402c4040334 Mon Sep 17 00:00:00 2001 From: grubert Date: Thu, 22 Apr 2004 13:22:37 +0000 Subject: Chg: table caption support. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1977 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 336b18606..8cb4ea73d 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -438,6 +438,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.topic_class = '' # column specification for tables self.colspecs = [] + self.table_caption = None # do we have one or more authors self.author_stack = None # Flags to encode @@ -1488,6 +1489,9 @@ class LaTeXTranslator(nodes.NodeVisitor): def table_preamble(self): if self.use_longtable: self.body.append('{%s}\n' % self.get_colspecs()) + if self.table_caption: + self.body.append('\\caption{%s}\\\\\n' % self.table_caption) + self.table_caption = None else: if self.context[-1] != 'table_sentinel': self.body.append('{%s}' % ('|X' * self.context.pop() + '|')) @@ -1595,6 +1599,10 @@ class LaTeXTranslator(nodes.NodeVisitor): elif isinstance(node.parent, nodes.sidebar): self.body.append('\\textbf{\\large ') self.context.append('}\n\\smallskip\n') + elif isinstance(node.parent, nodes.table): + # caption must be written after column spec + self.table_caption = node.astext() + raise nodes.SkipNode elif self.section_level == 0: # document title self.title = self.encode(node.astext()) -- cgit v1.2.1 From 080b9ef04d08c4de5c80fd5282bddf950692d546 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 22 Apr 2004 20:08:14 +0000 Subject: comments git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1981 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/roles.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/roles.py b/docutils/parsers/rst/roles.py index de5f106c6..7bf1f96a3 100644 --- a/docutils/parsers/rst/roles.py +++ b/docutils/parsers/rst/roles.py @@ -179,7 +179,8 @@ def pep_reference_role(role, rawtext, text, lineno, inliner): % text, line=lineno) prb = inliner.problematic(text, text, msg) return [prb], [msg] - ref = inliner.pep_url % pepnum # [XX] + # Base URL mainly used by inliner.pep_reference; so this is correct: + ref = inliner.pep_url % pepnum return [nodes.reference(rawtext, 'PEP ' + text, refuri=ref)], [] register_canonical_role('pep-reference', pep_reference_role) @@ -194,7 +195,8 @@ def rfc_reference_role(role, rawtext, text, lineno, inliner): '"%s" is invalid.' % text, line=lineno) prb = inliner.problematic(text, text, msg) return [prb], [msg] - ref = inliner.rfc_url % rfcnum # [XX] + # Base URL mainly used by inliner.rfc_reference, so this is correct: + ref = inliner.rfc_url % rfcnum return [nodes.reference(rawtext, 'RFC ' + text, refuri=ref)], [] register_canonical_role('rfc-reference', rfc_reference_role) -- cgit v1.2.1 From 78e2be643c2cee112989c1675005fd4d4396ce32 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 23 Apr 2004 13:48:24 +0000 Subject: Updated for ToC changes (topic now inserted by directive, so follow suit here). Fixes SF bug 928482. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1986 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/peps.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index 9ae7fa80b..fdd750d0c 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -19,7 +19,7 @@ import sys import os import re import time -from docutils import nodes, utils +from docutils import nodes, utils, languages from docutils import ApplicationError, DataError from docutils.transforms import Transform, TransformError from docutils.transforms import parts, references, misc @@ -137,15 +137,24 @@ class Headers(Transform): class Contents(Transform): """ - Insert a table of contents transform placeholder into the document after - the RFC 2822 header. + Insert an empty table of contents topic and a transform placeholder into + the document after the RFC 2822 header. """ default_priority = 380 def apply(self): - pending = nodes.pending(parts.Contents, {'title': None}) - self.document.insert(1, pending) + language = languages.get_language(self.document.settings.language_code) + name = language.labels['contents'] + title = nodes.title('', name) + topic = nodes.topic('', title, CLASS='contents') + name = nodes.fully_normalize_name(name) + if not self.document.has_name(name): + topic['name'] = name + self.document.note_implicit_target(topic) + pending = nodes.pending(parts.Contents) + topic += pending + self.document.insert(1, topic) self.document.note_pending(pending) -- cgit v1.2.1 From d83957271eed8042a24e0c63974cd3f1a2bbeee1 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 26 Apr 2004 22:09:57 +0000 Subject: fixed typo; found by Stephen Boulet git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1993 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/examples.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/examples.py b/docutils/examples.py index c149bf9d5..25c97b293 100644 --- a/docutils/examples.py +++ b/docutils/examples.py @@ -58,6 +58,6 @@ def html_fragment(input_string, destination_path=None, input_string=input_string, destination_path=destination_path, input_encoding=input_encoding, doctitle=doctitle) fragment = parts['fragment'] - if output_endocing != 'unicode': + if output_encoding != 'unicode': fragment = fragment.encode(output_encoding) return fragment -- cgit v1.2.1 From bbf8717a6f91e650f60c0dd380656562de9ed0a6 Mon Sep 17 00:00:00 2001 From: grubert Date: Tue, 27 Apr 2004 19:17:07 +0000 Subject: Chg: table width fiddling for narrow tables. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1998 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 8cb4ea73d..c05bd9bbe 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1448,13 +1448,20 @@ class LaTeXTranslator(nodes.NodeVisitor): Return column specification for longtable. Assumes reST line length being 80 characters. + Table width is hairy. + + === === + ABC DEF + === === + + usually gets to narrow, therefore we add 1 (fiddlefactor). """ width = 80 total_width = 0.0 # first see if we get too wide. for node in self.colspecs: - colwidth = float(node['colwidth']) / width + colwidth = float(node['colwidth']+1) / width total_width += colwidth # donot make it full linewidth factor = 0.93 @@ -1463,8 +1470,8 @@ class LaTeXTranslator(nodes.NodeVisitor): latex_table_spec = "" for node in self.colspecs: - colwidth = factor * float(node['colwidth']) / width - latex_table_spec += "|p{%.2f\\locallinewidth}" % colwidth + colwidth = factor * float(node['colwidth']+1) / width + latex_table_spec += "|p{%.2f\\locallinewidth}" % (colwidth+0.005) self.colspecs = [] return latex_table_spec+"|" -- cgit v1.2.1 From f47fbe4a9c8b4fade9beaee3a308ec2038af3098 Mon Sep 17 00:00:00 2001 From: fdrake Date: Tue, 27 Apr 2004 19:28:53 +0000 Subject: fix typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@1999 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index c05bd9bbe..c2b4e6139 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -403,7 +403,7 @@ class LaTeXTranslator(nodes.NodeVisitor): '\\newlength{\\docinfowidth}\n', '\\setlength{\\docinfowidth}{0.9\\textwidth}\n' # linewidth of current environment, so tables are not wider - # than the sidebar: using locallinewidth seams to defer evaluation + # than the sidebar: using locallinewidth seems to defer evaluation # of linewidth, this is fixing it. '\\newlength{\\locallinewidth}\n', # will be set later. -- cgit v1.2.1 From 5f4fc7c0e88fe3f9bdadc52d7ec2906bc02e4839 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 27 Apr 2004 19:47:28 +0000 Subject: Refactored ``Body.parse_directive`` into ``run_directive`` and ``parse_directive_block``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2000 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 68 +++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 28 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 5d7c463dc..219b8a790 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -496,6 +496,8 @@ class Inliner: self.rfc_reference)) def parse(self, text, lineno, memo, parent): + # Needs to be refactored for nested inline markup. + # Add nested_parse() method? """ Return 2 lists: nodes (text and inline elements), and system_messages. @@ -831,7 +833,8 @@ class Inliner: return uri def interpreted(self, rawsource, text, role, lineno): - role_fn, messages = roles.role(role, self.language, lineno, self) + role_fn, messages = roles.role(role, self.language, lineno, + self.reporter) if role_fn: nodes, messages2 = role_fn(role, rawsource, text, lineno, self) return nodes, messages + messages2 @@ -1878,17 +1881,18 @@ class Body(RSTState): return [msg], blank_finish def directive(self, match, **option_presets): + """Returns a 2-tuple: list of nodes, and a "blank finish" boolean.""" type_name = match.group(1) directive_function, messages = directives.directive( type_name, self.memo.language, self.document) self.parent += messages if directive_function: - return self.parse_directive( + return self.run_directive( directive_function, match, type_name, option_presets) else: return self.unknown_directive(type_name) - def parse_directive(self, directive_fn, match, type_name, option_presets): + def run_directive(self, directive_fn, match, type_name, option_presets): """ Parse a directive then run its directive function. @@ -1910,13 +1914,6 @@ class Body(RSTState): Returns a 2-tuple: list of nodes, and a "blank finish" boolean. """ - arguments = [] - options = {} - argument_spec = getattr(directive_fn, 'arguments', None) - if argument_spec and argument_spec[:2] == (0, 0): - argument_spec = None - option_spec = getattr(directive_fn, 'options', None) - content_spec = getattr(directive_fn, 'content', None) lineno = self.state_machine.abs_line_number() initial_line_offset = self.state_machine.line_offset indented, indent, line_offset, blank_finish \ @@ -1924,6 +1921,30 @@ class Body(RSTState): strip_top=0) block_text = '\n'.join(self.state_machine.input_lines[ initial_line_offset : self.state_machine.line_offset + 1]) + try: + arguments, options, content, content_offset = ( + self.parse_directive_block(indented, line_offset, + directive_fn, option_presets)) + except MarkupError, detail: + error = self.reporter.error( + 'Error in "%s" directive:\n%s.' % (type_name, detail), + nodes.literal_block(block_text, block_text), line=lineno) + return [error], blank_finish + result = directive_fn(type_name, arguments, options, content, lineno, + content_offset, block_text, self, + self.state_machine) + return (result, + blank_finish or self.state_machine.is_next_line_blank()) + + def parse_directive_block(self, indented, line_offset, directive_fn, + option_presets): + arguments = [] + options = {} + argument_spec = getattr(directive_fn, 'arguments', None) + if argument_spec and argument_spec[:2] == (0, 0): + argument_spec = None + option_spec = getattr(directive_fn, 'options', None) + content_spec = getattr(directive_fn, 'content', None) if indented and not indented[0].strip(): indented.trim_start() line_offset += 1 @@ -1945,24 +1966,15 @@ class Body(RSTState): while content and not content[0].strip(): content.trim_start() content_offset += 1 - try: - if option_spec: - options, arg_block = self.parse_directive_options( - option_presets, option_spec, arg_block) - if argument_spec: - arguments = self.parse_directive_arguments(argument_spec, - arg_block) - if content and not content_spec: - raise MarkupError('no content permitted') - except MarkupError, detail: - error = self.reporter.error( - 'Error in "%s" directive:\n%s.' % (type_name, detail), - nodes.literal_block(block_text, block_text), line=lineno) - return [error], blank_finish - result = directive_fn( - type_name, arguments, options, content, lineno, content_offset, - block_text, self, self.state_machine) - return result, blank_finish or self.state_machine.is_next_line_blank() + if option_spec: + options, arg_block = self.parse_directive_options( + option_presets, option_spec, arg_block) + if argument_spec: + arguments = self.parse_directive_arguments( + argument_spec, arg_block) + if content and not content_spec: + raise MarkupError('no content permitted') + return (arguments, options, content, content_offset) def parse_directive_options(self, option_presets, option_spec, arg_block): options = option_presets.copy() -- cgit v1.2.1 From 60d84454ac6baa935bb8492471cc9a428c0dbd52 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 27 Apr 2004 19:48:37 +0000 Subject: Reworked role API & "role" directive to allow customization. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2001 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 53 +++++++++-- docutils/parsers/rst/roles.py | 160 +++++++++++++++++++++++++------- 2 files changed, 171 insertions(+), 42 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 4352c846a..d2f65c990 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -228,24 +228,63 @@ def class_directive(name, arguments, options, content, lineno, class_directive.arguments = (1, 0, 0) class_directive.content = 1 +role_arg_pat = re.compile(r'(%s)\s*(\(\s*(%s)\s*\)\s*)?$' + % ((states.Inliner.simplename,) * 2)) def role(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """Dynamically create and register a custom interpreted text role.""" - role_name = arguments[0].lower() + if content_offset > lineno or not content: + error = state_machine.reporter.error( + '"%s" directive requires arguments on the first line.' + % name, nodes.literal_block(block_text, block_text), line=lineno) + return [error] + args = content[0] + match = role_arg_pat.match(args) + if not match: + error = state_machine.reporter.error( + '"%s" directive arguments not valid role names: "%s".' + % (name, args), nodes.literal_block(block_text, block_text), + line=lineno) + return [error] + new_role_name = match.group(1) + base_role_name = match.group(3) + messages = [] + if base_role_name: + base_role, messages = roles.role( + base_role_name, state_machine.language, lineno, state.reporter) + if base_role is None: + error = state.reporter.error( + 'Unknown interpreted text role "%s".' % base_role_name, + nodes.literal_block(block_text, block_text), line=lineno) + return messages + [error] + else: + base_role = roles.generic_custom_role + assert not hasattr(base_role, 'arguments'), ( + 'Supplemental directive arguments for "%s" directive not supported' + '(specified by "%r" role).' % (name, base_role)) + try: + (arguments, options, content, content_offset) = ( + state.parse_directive_block(content[1:], content_offset, base_role, + option_presets={})) + except states.MarkupError, detail: + error = state_machine.reporter.error( + 'Error in "%s" directive:\n%s.' % (name, detail), + nodes.literal_block(block_text, block_text), line=lineno) + return messages + [error] if not options.has_key('class'): try: - options['class'] = directives.class_option(role_name) + options['class'] = directives.class_option(new_role_name) except ValueError, detail: error = state_machine.reporter.error( 'Invalid argument for "%s" directive:\n%s.' % (name, detail), nodes.literal_block(block_text, block_text), line=lineno) - return [error] - roles.register_custom_role(role_name, options) - return [] + return messages + [error] + role = roles.CustomRole(new_role_name, base_role, options, content) + roles.register_local_role(new_role_name, role) + return messages -role.arguments = (1, 0, 0) -role.options = {'class': directives.class_option} +role.content = 1 def directive_test_function(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): diff --git a/docutils/parsers/rst/roles.py b/docutils/parsers/rst/roles.py index 7bf1f96a3..2af000d6c 100644 --- a/docutils/parsers/rst/roles.py +++ b/docutils/parsers/rst/roles.py @@ -11,16 +11,22 @@ registry. The interface for interpreted role functions is as follows:: - def role_fn(name, rawtext, text, lineno, inliner, attributes={}): + def role_fn(name, rawtext, text, lineno, inliner, + options={}, content=[]): code... + # Set function attributes for customization: + role_fn.options = ... + role_fn.content = ... + Parameters: - ``name`` is the local name of the interpreted text role, the role name actually used in the document. - ``rawtext`` is a string containing the entire interpreted text construct. - Include it as a literal block in a system message if there is a problem. + Return it as a ``problematic`` node linked to a system message if there is a + problem. - ``text`` is the interpreted text content. @@ -30,8 +36,30 @@ Parameters: It defines the following useful attributes: ``reporter``, ``problematic``, ``memo``, ``parent``, ``document``. -- ``attributes``: A dictionary of additional attributes for the generated - elements, used for customization. +- ``options``: A dictionary of directive options for customization, to be + interpreted by the role function. Used for additional attributes for the + generated elements and other functionality. + +- ``content``: A list of strings, the directive content for customization + ("role" directive). To be interpreted by the role function. + +Function attributes for customization, interpreted by the "role" directive: + +- ``options``: A dictionary, mapping known option names to conversion + functions such as `int` or `float`. ``None`` or an empty dict implies no + options to parse. Several directive option conversion functions are defined + in the `directives` module. + + All role functions implicitly support the "class" option, unless disabled + with an explicit ``{'class': None}``. + +- ``content``: A boolean; true if content is allowed. Client code must handle + the case where content is required but not supplied (an empty content list + will be supplied). + +Note that unlike directives, the "arguments" function attribute is not +supported for role customization. Directive arguments are handled by the +"role" directive itself. Interpreted role functions return a tuple of two values: @@ -46,6 +74,7 @@ Interpreted role functions return a tuple of two values: __docformat__ = 'reStructuredText' from docutils import nodes +from docutils.parsers.rst import directives from docutils.parsers.rst.languages import en as _fallback_language_module DEFAULT_INTERPRETED_ROLE = 'title-reference' @@ -62,11 +91,12 @@ _roles = {} """Mapping of local or language-dependent interpreted text role names to role functions.""" -def role(role_name, language_module, lineno, inliner): +def role(role_name, language_module, lineno, reporter): """ Locate and return a role function from its language-dependent name, along with a list of system messages. If the role is not found in the current - language, check English. Return None if the named role cannot be found. + language, check English. Return a 2-tuple: role function (``None`` if the + named role cannot be found) and a list of system messages. """ normname = role_name.lower() messages = [] @@ -102,7 +132,7 @@ def role(role_name, language_module, lineno, inliner): # Collect any messages that we generated. if msg_text: - message = inliner.reporter.info('\n'.join(msg_text), line=lineno) + message = reporter.info('\n'.join(msg_text), line=lineno) messages.append(message) # Look the role up in the registry, and return it. @@ -121,6 +151,7 @@ def register_canonical_role(name, role_fn): - `name`: The canonical name of the interpreted role. - `role_fn`: The role function. See the module docstring. """ + set_implicit_options(role_fn) _role_registry[name] = role_fn def register_local_role(name, role_fn): @@ -131,29 +162,80 @@ def register_local_role(name, role_fn): - `name`: The local or language-dependent name of the interpreted role. - `role_fn`: The role function. See the module docstring. """ + set_implicit_options(role_fn) _roles[name] = role_fn +def set_implicit_options(role_fn): + """ + Add customization options to role functions, unless explicitly set or + disabled. + """ + if not hasattr(role_fn, 'options') or role_fn.options is None: + role_fn.options = {'class': directives.class_option} + elif not role_fn.options.has_key('class'): + role_fn.options['class'] = directives.class_option + def register_generic_role(canonical_name, node_class): """For roles which simply wrap a given `node_class` around the text.""" - # Dynamically define a role function: - def role_fn(role, rawtext, text, lineno, inliner, nc=node_class): - return generic_role_helper(nc, role, rawtext, text, lineno, inliner) - # Register the role: - register_canonical_role(canonical_name, role_fn) - -def generic_role_helper(node_class, role, rawtext, text, lineno, inliner, - attributes={}): - # If we wanted to, we could recursively call inliner.nested_parse - # to interpret the text contents here (after appropriately - # refactoring Inliner.parse). - return [node_class(rawtext, text, **attributes)], [] - -def register_custom_role(local_name, attributes): - """For roles defined in a document.""" - def role_fn(role, rawtext, text, lineno, inliner, atts=attributes): - return generic_role_helper( - nodes.inline, role, rawtext, text, lineno, inliner, attributes=atts) - register_local_role(local_name, role_fn) + role = GenericRole(canonical_name, node_class) + register_canonical_role(canonical_name, role) + + +class GenericRole: + + """ + Generic interpreted text role, where the interpreted text is simply + wrapped with the provided node class. + """ + + def __init__(self, role_name, node_class): + self.name = role_name + self.node_class = node_class + + def __call__(self, role, rawtext, text, lineno, inliner, + options={}, content=[]): + return [self.node_class(rawtext, text, **options)], [] + + +class CustomRole: + + """ + Wrapper for custom interpreted text roles. + """ + + def __init__(self, role_name, base_role, options={}, content=[]): + self.name = role_name + self.base_role = base_role + self.options = None + if hasattr(base_role, 'options'): + self.options = base_role.options + self.content = None + if hasattr(base_role, 'content'): + self.content = base_role.content + self.supplied_options = options + self.supplied_content = content + + def __call__(self, role, rawtext, text, lineno, inliner, + options={}, content=[]): + opts = self.supplied_options.copy() + opts.update(options) + cont = list(self.supplied_content) + if cont and content: + cont += '\n' + cont.extend(content) + return self.base_role(role, rawtext, text, lineno, inliner, + options=opts, content=cont) + + +def generic_custom_role(role, rawtext, text, lineno, inliner, + options={}, content=[]): + """""" + # Once nested inline markup is implemented, this and other methods should + # recursively call inliner.nested_parse(). + return [nodes.inline(rawtext, text, **options)], [] + +generic_custom_role.options = {'class': directives.class_option} + ###################################################################### # Define and register the standard roles: @@ -168,7 +250,8 @@ register_generic_role('subscript', nodes.subscript) register_generic_role('superscript', nodes.superscript) register_generic_role('title-reference', nodes.title_reference) -def pep_reference_role(role, rawtext, text, lineno, inliner): +def pep_reference_role(role, rawtext, text, lineno, inliner, + options={}, content=[]): try: pepnum = int(text) if pepnum < 0 or pepnum > 9999: @@ -177,14 +260,16 @@ def pep_reference_role(role, rawtext, text, lineno, inliner): msg = inliner.reporter.error( 'PEP number must be a number from 0 to 9999; "%s" is invalid.' % text, line=lineno) - prb = inliner.problematic(text, text, msg) + prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] # Base URL mainly used by inliner.pep_reference; so this is correct: ref = inliner.pep_url % pepnum - return [nodes.reference(rawtext, 'PEP ' + text, refuri=ref)], [] + return [nodes.reference(rawtext, 'PEP ' + text, refuri=ref, **options)], [] + register_canonical_role('pep-reference', pep_reference_role) -def rfc_reference_role(role, rawtext, text, lineno, inliner): +def rfc_reference_role(role, rawtext, text, lineno, inliner, + options={}, content=[]): try: rfcnum = int(text) if rfcnum <= 0: @@ -193,18 +278,21 @@ def rfc_reference_role(role, rawtext, text, lineno, inliner): msg = inliner.reporter.error( 'RFC number must be a number greater than or equal to 1; ' '"%s" is invalid.' % text, line=lineno) - prb = inliner.problematic(text, text, msg) + 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 - return [nodes.reference(rawtext, 'RFC ' + text, refuri=ref)], [] + node = nodes.reference(rawtext, 'RFC ' + text, refuri=ref, **options) + return [node], [] + register_canonical_role('rfc-reference', rfc_reference_role) + ###################################################################### # Register roles that are currently unimplemented. ###################################################################### -def unimplemented_role(role, rawtext, text, lineno, inliner): +def unimplemented_role(role, rawtext, text, lineno, inliner, attributes={}): msg = inliner.reporter.error( 'Interpreted text role "%s" not implemented.' % role, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) @@ -218,5 +306,7 @@ register_canonical_role('footnote-reference', unimplemented_role) register_canonical_role('citation-reference', unimplemented_role) register_canonical_role('substitution-reference', unimplemented_role) register_canonical_role('target', unimplemented_role) -# This one should remain unimplemented, for testing purposes: -register_canonical_role('restructuredtext-unimplemented-role', unimplemented_role) + +# This should remain unimplemented, for testing purposes: +register_canonical_role('restructuredtext-unimplemented-role', + unimplemented_role) -- cgit v1.2.1 From 2e594eab0b980f2357c83ab560bc07c0d5779117 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 27 Apr 2004 19:53:19 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2002 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/utils.py b/docutils/utils.py index 148845330..70da14c7e 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -324,7 +324,9 @@ def assemble_option_dict(option_list, options_spec): """ options = {} for name, value in option_list: - convertor = options_spec[name] # raises KeyError if unknown + convertor = options_spec[name] # raises KeyError if unknown + if convertor is None: + raise KeyError(name) # or if explicitly disabled if options.has_key(name): raise DuplicateOptionError('duplicate option "%s"' % name) try: -- cgit v1.2.1 From b54987eb76da2804dc79906888d67d8b35da4755 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 28 Apr 2004 21:49:53 +0000 Subject: Added --initial-header-level option. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2010 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index be1b2375e..4327643e8 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -59,6 +59,11 @@ class Writer(writers.Writer): 'stylesheet, do not embed it.', ['--embed-stylesheet'], {'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'], + {'choices': '1 2 3 4 5 6'.split(), 'default': '1', + 'metavar': ''}), ('Format for footnote references: one of "superscript" or ' '"brackets". Default is "superscript".', ['--footnote-references'], @@ -208,6 +213,8 @@ class HTMLTranslator(nodes.NodeVisitor): self.fragment = [] self.body_suffix = ['\n\n'] self.section_level = 0 + print 'settings.initial_header_level:', settings.initial_header_level + self.initial_header_level = int(settings.initial_header_level) self.context = [] self.topic_class = '' self.colspecs = [] @@ -1221,8 +1228,10 @@ class HTMLTranslator(nodes.NodeVisitor): self.context.append('

    \n') self.within_title = len(self.body) else: + h_level = self.section_level + self.initial_header_level - 1 + print h_level self.body.append( - self.starttag(node, 'h%s' % self.section_level, '')) + self.starttag(node, 'h%s' % h_level, '')) atts = {} if node.parent.hasattr('id'): atts['name'] = node.parent['id'] @@ -1230,7 +1239,7 @@ class HTMLTranslator(nodes.NodeVisitor): atts['class'] = 'toc-backref' atts['href'] = '#' + node['refid'] self.body.append(self.starttag({}, 'a', '', **atts)) - self.context.append('\n' % (self.section_level)) + self.context.append('\n' % (h_level)) if check_id: if node.parent.hasattr('id'): self.body.append( -- cgit v1.2.1 From b7ba619ac48b53522d1bbc71c13e35c850c00aa1 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 28 Apr 2004 21:50:39 +0000 Subject: Added support for source_path and initial_header_level. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2011 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/examples.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'docutils') diff --git a/docutils/examples.py b/docutils/examples.py index 25c97b293..bef95ec63 100644 --- a/docutils/examples.py +++ b/docutils/examples.py @@ -12,8 +12,8 @@ functions may be used as-is, or as models for variations. from docutils import core -def html_parts(input_string, destination_path=None, - input_encoding='unicode', doctitle=1): +def html_parts(input_string, source_path=None, destination_path=None, + input_encoding='unicode', doctitle=1, initial_header_level=1): """ Given an input string, returns a dictionary of HTML document parts. @@ -23,6 +23,8 @@ def html_parts(input_string, destination_path=None, Parameters: - `input_string`: A multi-line text string; required. + - `source_path`: Path to the source file or object. Optional, but useful + for diagnostic output (system messages). - `destination_path`: Path to the file or object which will receive the output; optional. Used for determining relative paths (stylesheets, source links, etc.). @@ -32,17 +34,21 @@ def html_parts(input_string, destination_path=None, - `doctitle`: Disable the promotion of a lone top-level section title to document title (and subsequent section title to document subtitle promotion); enabled by default. + - `initial_header_level`: The initial level for header elements (e.g. 1 + for "

    "). """ overrides = {'input_encoding': input_encoding, - 'doctitle_xform': doctitle} + 'doctitle_xform': doctitle, + 'initial_header_level': initial_header_level} parts = core.publish_parts( - source=input_string, destination_path=destination_path, + source=input_string, source_path=source_path, + destination_path=destination_path, writer_name='html', settings_overrides=overrides) return parts -def html_fragment(input_string, destination_path=None, +def html_fragment(input_string, source_path=None, destination_path=None, input_encoding='unicode', output_encoding='unicode', - doctitle=1): + doctitle=1, initial_header_level=1): """ Given an input string, returns an HTML fragment as a string. @@ -55,8 +61,10 @@ def html_fragment(input_string, destination_path=None, string is desired, use the default value of "unicode" . """ parts = html_parts( - input_string=input_string, destination_path=destination_path, - input_encoding=input_encoding, doctitle=doctitle) + input_string=input_string, source_path=source_path, + destination_path=destination_path, + input_encoding=input_encoding, doctitle=doctitle, + initial_header_level=initial_header_level) fragment = parts['fragment'] if output_encoding != 'unicode': fragment = fragment.encode(output_encoding) -- cgit v1.2.1 From 7abc4ee4ae84c590d468d7ccfec2bb992d95204f Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 28 Apr 2004 21:54:39 +0000 Subject: remove print statements git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2013 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 4327643e8..f3289f58c 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -213,7 +213,6 @@ class HTMLTranslator(nodes.NodeVisitor): self.fragment = [] self.body_suffix = ['\n\n'] self.section_level = 0 - print 'settings.initial_header_level:', settings.initial_header_level self.initial_header_level = int(settings.initial_header_level) self.context = [] self.topic_class = '' @@ -1229,7 +1228,6 @@ class HTMLTranslator(nodes.NodeVisitor): self.within_title = len(self.body) else: h_level = self.section_level + self.initial_header_level - 1 - print h_level self.body.append( self.starttag(node, 'h%s' % h_level, '')) atts = {} -- cgit v1.2.1 From c1058eae2ee4d0292df20765c617e13b33421461 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 28 Apr 2004 23:41:26 +0000 Subject: added class="first" attributes to titles rendered with

    git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2014 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index f3289f58c..48e95eda2 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -155,7 +155,7 @@ class HTMLTranslator(nodes.NodeVisitor): - Regardless of the above, in definitions, table cells, field bodies, option descriptions, and list items, mark the first child with 'class="first"' and the last child with 'class="last"'. The stylesheet - sets the margins (top & bottom respecively) to 0 for these elements. + sets the margins (top & bottom respectively) to 0 for these elements. The ``no_compact_lists`` setting (``--no-compact-lists`` command-line option) disables list whitespace optimization. @@ -332,7 +332,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.starttag(node, 'div', CLASS=(name or 'admonition'))) if name: - self.body.append('

    ' + self.body.append('

    ' + self.language.labels[name] + '

    \n') def depart_admonition(self, node=None): @@ -1204,15 +1204,15 @@ class HTMLTranslator(nodes.NodeVisitor): close_tag = '

    \n' if isinstance(node.parent, nodes.topic): self.body.append( - self.starttag(node, 'p', '', CLASS='topic-title')) + self.starttag(node, 'p', '', CLASS='topic-title first')) check_id = 1 elif isinstance(node.parent, nodes.sidebar): self.body.append( - self.starttag(node, 'p', '', CLASS='sidebar-title')) + self.starttag(node, 'p', '', CLASS='sidebar-title first')) check_id = 1 elif isinstance(node.parent, nodes.admonition): self.body.append( - self.starttag(node, 'p', '', CLASS='admonition-title')) + self.starttag(node, 'p', '', CLASS='admonition-title first')) check_id = 1 elif isinstance(node.parent, nodes.table): self.body.append( -- cgit v1.2.1 From 00e17f6e2ad5d5ab863d00bb662dcf7e340b9275 Mon Sep 17 00:00:00 2001 From: grubert Date: Mon, 3 May 2004 21:34:23 +0000 Subject: Add --use-verbatim-when-possible. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2021 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 50 ++++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 16 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index c2b4e6139..b9f3b0825 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -106,7 +106,13 @@ class Writer(writers.Writer): ('Set the separator between section number and enumerator ' 'for compound enumerated lists. Default is "-".', ['--section-enumerator-separator'], - {'default': '-', 'metavar': ''}),)) + {'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}), + )) settings_defaults = {'output_encoding': 'latin-1'} @@ -1202,31 +1208,43 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_literal_block(self, node): """ - .. parsed-literal:: + Render a literal-block. + + Literal blocks are used for "::"-prefixed literal-indented + blocks of text, where the inline markup is not recognized, + but are also the product of the parsed-literal directive, + where the markup is respected. """ - # typically in a typewriter/monospaced typeface. - # care must be taken with the text, because inline markup is recognized. + # In both cases, we want to use a typewriter/monospaced typeface. + # For "real" literal-blocks, we can use \verbatim, while for all + # the others we must use \mbox. # - # possibilities: - # * verbatim: is no possibility, as inline markup does not work. - # * obey..: is from julien and never worked for me (grubert). - self.use_for_literal_block = "mbox" - self.literal_block = 1 - if (self.use_for_literal_block == "mbox"): + # We can distinguish between the two kinds by the number of + # siblings the compose this node: if it is composed by a + # single element, it's surely is either a real one, otherwise + # it's a parsed-literal that does not contain any markup. + # + if self.settings.use_verbatim_when_possible and (len(node) == 1): + self.verbatim = 1 + self.body.append('\\begin{verbatim}\n') + else: + self.literal_block = 1 self.mbox_newline = 1 self.insert_none_breaking_blanks = 1 self.body.append('\\begin{ttfamily}\\begin{flushleft}\n\\mbox{') - else: - self.body.append('{\\obeylines\\obeyspaces\\ttfamily\n') + # * obey..: is from julien and never worked for me (grubert). + # self.body.append('{\\obeylines\\obeyspaces\\ttfamily\n') def depart_literal_block(self, node): - if (self.use_for_literal_block == "mbox"): + if self.verbatim: + self.body.append('\n\\end{verbatim}\n') + self.verbatim = 0 + else: self.body.append('}\n\\end{flushleft}\\end{ttfamily}\n') self.insert_none_breaking_blanks = 0 self.mbox_newline = 0 - else: - self.body.append('}\n') - self.literal_block = 0 + # obey end: self.body.append('}\n') + self.literal_block = 0 def visit_meta(self, node): self.body.append('[visit_meta]\n') -- cgit v1.2.1 From 1edd0cd8fca10c572d723608dac92e30f8e42ce2 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 4 May 2004 00:38:15 +0000 Subject: Added specific error message for duplicate targets. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2022 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 16 +++++++++------- docutils/transforms/universal.py | 11 ++++++++--- 2 files changed, 17 insertions(+), 10 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 0e41dae84..2786cd562 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -217,13 +217,11 @@ class IndirectHyperlinks(Transform): reftarget_id = self.document.nameids.get(refname) if not reftarget_id: # Check the unknown_reference_resolvers - handled = 0 - for i in self.document.transformer.unknown_reference_resolvers: - print `target` - if i(target): - handled = 1 + for resolver_function in (self.document.transformer + .unknown_reference_resolvers): + if resolver_function(target): break - if not handled: + else: self.nonexistent_indirect_target(target) return reftarget = self.document.ids[reftarget_id] @@ -256,7 +254,11 @@ class IndirectHyperlinks(Transform): reftarget.referenced = 1 def nonexistent_indirect_target(self, target): - self.indirect_target_error(target, 'which does not exist') + if self.document.nameids.has_key(target['refname']): + self.indirect_target_error(target, 'which is a duplicate, and ' + 'cannot be used as a unique reference') + else: + self.indirect_target_error(target, 'which does not exist') def circular_indirect_reference(self, target): self.indirect_target_error(target, 'forming a circular reference') diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 4e7d0b457..45e74f3e3 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -188,9 +188,14 @@ class FinalCheckVisitor(nodes.SparseNodeVisitor): if resolver_function(node): break else: - msg = self.document.reporter.error( - 'Unknown target name: "%s".' % (node['refname']), - base_node=node) + 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) -- cgit v1.2.1 From f37cb747d33d646017801673edc1b91c668d6878 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 4 May 2004 22:54:40 +0000 Subject: Documented & set default for Writer.output attribute git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2025 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index fce06f82b..fab0c493f 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -35,6 +35,9 @@ class Writer(Component): document = None """The document to write.""" + output = None + """Final translated form of `document`.""" + language = None """Language module for the document.""" @@ -66,6 +69,9 @@ class Writer(Component): support all standard elements (listed in `docutils.nodes.node_class_names`) and possibly non-standard elements used by the current Reader as well. + + The final translated form of `self.document` should be assigned to + `self.output`. """ raise NotImplementedError('subclass must override this method') -- cgit v1.2.1 From 193166e722dceed37f94559c2547f9c8f86ff35f Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 4 May 2004 22:55:46 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2026 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 3 --- 1 file changed, 3 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 48e95eda2..2ebe9f4df 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -94,9 +94,6 @@ class Writer(writers.Writer): config_section = 'html4css1 writer' config_section_dependencies = ('writers',) - output = None - """Final translated form of `document`.""" - def __init__(self): writers.Writer.__init__(self) self.translator_class = HTMLTranslator -- cgit v1.2.1 From a77b2d0f6bad14d3297794bb61bc4e2b85ca0084 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 6 May 2004 16:15:29 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2028 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/examples.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/examples.py b/docutils/examples.py index bef95ec63..6936acd25 100644 --- a/docutils/examples.py +++ b/docutils/examples.py @@ -5,8 +5,11 @@ # Copyright: This module has been placed in the public domain. """ -This module contains practical examples of Docutils client code. These -functions may be used as-is, or as models for variations. +This module contains practical examples of Docutils client code. + +Importing this module is not recommended; its contents are subject to change +in future Docutils releases. Instead, it is recommended that you copy and +paste the parts you need into your own code, modifying as necessary. """ from docutils import core -- cgit v1.2.1 From de8c07d626555e33a0d6e28847e61efa439650ee Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 6 May 2004 18:22:37 +0000 Subject: docstrings git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2029 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 3 ++- docutils/writers/__init__.py | 20 ++++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index dcf1fb8f9..d47365229 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -145,7 +145,8 @@ class Component(SettingsSpec, TransformSpec): """Base class for Docutils components.""" component_type = None - """Override in subclasses.""" + """Name of the component type ('reader', 'parser', 'writer'). Override in + subclasses.""" supported = () """Names for this component. Override in subclasses.""" diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index fab0c493f..41b151407 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -26,31 +26,39 @@ class Writer(Component): Each writer must support all standard node types listed in `docutils.nodes.node_class_names`. - Call `write()` to process a document. + The `write()` method is the main entry point. """ component_type = 'writer' config_section = 'writers' document = None - """The document to write.""" + """The document to write (Docutils doctree); set by `write`.""" output = None - """Final translated form of `document`.""" + """Final translated form of `document`; set by `translate`.""" language = None - """Language module for the document.""" + """Language module for the document; set by `write`.""" destination = None - """`docutils.io` IO object; where to write the document.""" + """`docutils.io` IO object; where to write the document. Set by `write`.""" def __init__(self): - """Initialize the Writer instance.""" self.parts = {} """Collection of named parts of the document.""" def write(self, document, destination): + """ + Process a document into its final form. + + Translate `document` (a Docutils document tree) into the Writer's + native format, and write it out to its `destination` (a + `docutils.io.Output` subclass object). + + Normally not overridden or extended in subclasses. + """ self.document = document self.language = languages.get_language( document.settings.language_code) -- cgit v1.2.1 From 4b2b435a42cfd68cecea73646b470d9b8a9e7122 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 7 May 2004 01:46:51 +0000 Subject: docstrings git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2030 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/__init__.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index 41b151407..044884581 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -46,8 +46,12 @@ class Writer(Component): def __init__(self): + # Currently only used by HTML writer for output fragments: self.parts = {} - """Collection of named parts of the document.""" + """Mapping of document part names to fragments of `self.output`. + Values are Unicode strings; encoding is up to the client. The 'whole' + key should contain the entire document output. + """ def write(self, document, destination): """ @@ -69,28 +73,20 @@ class Writer(Component): def translate(self): """ - Override to do final document tree translation. + Do final translation of `self.document` into `self.output`. + Called from `write`. Override in subclasses. - This is usually done with a `docutils.nodes.NodeVisitor` subclass, in + Usually done with a `docutils.nodes.NodeVisitor` subclass, in combination with a call to `docutils.nodes.Node.walk()` or `docutils.nodes.Node.walkabout()`. The ``NodeVisitor`` subclass must support all standard elements (listed in `docutils.nodes.node_class_names`) and possibly non-standard elements used by the current Reader as well. - - The final translated form of `self.document` should be assigned to - `self.output`. """ raise NotImplementedError('subclass must override this method') def assemble_parts(self): - """ - Assemble the `self.parts` dictionary. Extend in subclasses. - - Dictionary keys are the names of parts, and values are Unicode - strings; encoding is up to the client. The 'whole' key contains the - entire document output. - """ + """Assemble the `self.parts` dictionary. Extend in subclasses.""" self.parts['whole'] = self.output -- cgit v1.2.1 From 00a18ecf4a86081753e27d394473a70dc287e9ed Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 7 May 2004 12:07:30 +0000 Subject: Python 2.1 compatibility fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2037 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/python/moduleparser.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/readers/python/moduleparser.py b/docutils/readers/python/moduleparser.py index 7f965e6e2..ddfe21ea7 100644 --- a/docutils/readers/python/moduleparser.py +++ b/docutils/readers/python/moduleparser.py @@ -386,11 +386,11 @@ class FunctionVisitor(DocstringVisitor): special = [] argnames = list(node.argnames) if node.kwargs: - special.append(make_parameter(argnames[-1], excess_keyword=True)) + special.append(make_parameter(argnames[-1], excess_keyword=1)) argnames.pop() if node.varargs: special.append(make_parameter(argnames[-1], - excess_positional=True)) + excess_positional=1)) argnames.pop() defaults = list(node.defaults) defaults = [None] * (len(argnames) - len(defaults)) + defaults @@ -689,7 +689,11 @@ def make_attribute(name, lineno): n.append(make_object_name(name)) return n -def make_parameter(name, excess_keyword=False, excess_positional=False): +def make_parameter(name, excess_keyword=0, excess_positional=0): + """ + excess_keyword and excess_positional must be either 1 or 0, and + not both of them can be 1. + """ n = pynodes.parameter() n.append(make_object_name(name)) assert not excess_keyword or not excess_positional -- cgit v1.2.1 From c30e1a407ebb25b22fa2690902bd3eea75511bfe Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 7 May 2004 13:52:04 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2038 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index b9f3b0825..b5a18280d 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1224,7 +1224,9 @@ class LaTeXTranslator(nodes.NodeVisitor): # single element, it's surely is either a real one, otherwise # it's a parsed-literal that does not contain any markup. # - if self.settings.use_verbatim_when_possible and (len(node) == 1): + if (self.settings.use_verbatim_when_possible and (len(node) == 1) + # in case of a parsed-literal containing just a "**bold**" word: + and isinstance(node[0], nodes.Text)): self.verbatim = 1 self.body.append('\\begin{verbatim}\n') else: -- cgit v1.2.1 From 4e2a0c51ca5e9a911b281a1547b4f258ee994061 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 7 May 2004 17:55:49 +0000 Subject: fixed image scaling git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2047 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 2ebe9f4df..d56598e89 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -797,12 +797,16 @@ class HTMLTranslator(nodes.NodeVisitor): pass else: if not atts.has_key('width'): - atts['width'] = int(im.size[0] - * (float(atts['scale']) / 100)) + atts['width'] = im.size[0] if not atts.has_key('height'): - atts['height'] = int(im.size[1] - * (float(atts['scale']) / 100)) + atts['height'] = im.size[1] del im + if atts.has_key('width'): + atts['width'] = int(round(atts['width'] + * (float(atts['scale']) / 100))) + if atts.has_key('height'): + atts['height'] = int(round(atts['height'] + * (float(atts['scale']) / 100))) del atts['scale'] if not atts.has_key('alt'): atts['alt'] = atts['src'] -- cgit v1.2.1 From 57a9c0577f41546be5adc5d0de742c0f4d487314 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 8 May 2004 18:56:43 +0000 Subject: corrected frontend script description git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2049 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/python/__init__.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/readers/python/__init__.py b/docutils/readers/python/__init__.py index 1bd9b151c..14d01c0c8 100644 --- a/docutils/readers/python/__init__.py +++ b/docutils/readers/python/__init__.py @@ -38,6 +38,7 @@ class Reader(docutils.readers.Reader): module_section.walk(visitor) self.document.append(module_section) + class DocformatVisitor(nodes.SparseNodeVisitor): """ @@ -69,6 +70,7 @@ class DocformatVisitor(nodes.SparseNodeVisitor): looking_in = looking_in.parent looking_in['docformat'] = name + class DocstringFormattingVisitor(nodes.SparseNodeVisitor): def __init__(self, document, default_parser): @@ -109,7 +111,8 @@ class DocstringFormattingVisitor(nodes.SparseNodeVisitor): return node['docformat'] node = node.parent return self.default_parser - + + if __name__ == '__main__': try: import locale @@ -119,8 +122,8 @@ if __name__ == '__main__': from docutils.core import publish_cmdline, default_description - description = ('Generates pseudo-XML from standalone reStructuredText ' - 'sources (for testing purposes). ' + default_description) + description = ('Generates pseudo-XML from Python modules ' + '(for testing purposes). ' + default_description) publish_cmdline(description=description, reader=Reader()) -- cgit v1.2.1 From 5e7a581a86980a8cd61e1a7369af4798b95e395b Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 8 May 2004 20:42:29 +0000 Subject: Py2.1 compatibility, typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2052 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index b5a18280d..d024cd971 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -888,7 +888,7 @@ class LaTeXTranslator(nodes.NodeVisitor): # multi{row,column} if node.has_key('morerows') and node.has_key('morecols'): - raise NotImplementedError('LaTeX can\'t handle cells that' + raise NotImplementedError('LaTeX can\'t handle cells that ' 'span multiple rows *and* columns, sorry.') atts = {} if node.has_key('morerows'): @@ -1107,14 +1107,12 @@ class LaTeXTranslator(nodes.NodeVisitor): attrs = node.attributes.copy() pre = [] # in reverse order post = ['\\includegraphics{%s}' % attrs['uri']] - def prepost(pre_append, post_append): - pre.append(pre_append) - post.append(post_append) inline = isinstance(node.parent, nodes.TextElement) if 'scale' in attrs: # Could also be done with ``scale`` option to # ``\includegraphics``; doing it this way for consistency. - prepost('\\scalebox{%f}{' % (attrs['scale'] / 100.0,), '}') + pre.append('\\scalebox{%f}{' % (attrs['scale'] / 100.0,)) + post.append('}') if 'align' in attrs: align_prepost = { # By default latex aligns the top of an image. @@ -1128,11 +1126,13 @@ class LaTeXTranslator(nodes.NodeVisitor): (0, 'left'): ('{', '\\hfill}'), (0, 'right'): ('{\\hfill', '}'),} try: - prepost(*align_prepost[inline, attrs['align']]) + pre.append(align_prepost[inline, attrs['align']][0]) + post.append(align_prepost[inline, attrs['align']][1]) except KeyError: - pass # complain here? + pass # XXX complain here? if not inline: - prepost('\n', '\n') + pre.append('\n') + post.append('\n') pre.reverse() self.body.extend(pre + post) -- cgit v1.2.1 From 1a6c4713d822d80c8656c27bde67e30a67d8bb24 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 8 May 2004 22:47:28 +0000 Subject: Fixed bug: the body_pre_docinfo segment depended on there being a docinfo; if no docinfo, the document title was incorporated into the body segment. Adversely affected the publish_parts interface. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2053 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index d56598e89..da2c7cac6 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -211,6 +211,8 @@ class HTMLTranslator(nodes.NodeVisitor): 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_class = '' self.colspecs = [] @@ -222,7 +224,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.subtitle = [] self.header = [] self.footer = [] - self.within_title = 0 + self.in_document_title = 0 def get_stylesheet_reference(self, relative_to=None): settings = self.settings @@ -541,7 +543,6 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('\n\n') self.in_docinfo = None start = self.context.pop() - self.body_pre_docinfo = self.body[:start] self.docinfo = self.body[start:] self.body = [] @@ -1080,16 +1081,18 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.starttag(node, 'p', '', CLASS='sidebar-subtitle')) self.context.append('

    \n') - else: + elif isinstance(node.parent, nodes.document): self.body.append(self.starttag(node, 'h2', '', CLASS='subtitle')) self.context.append('

    \n') - self.within_title = len(self.body) + self.in_document_title = len(self.body) def depart_subtitle(self, node): - if self.within_title: - self.subtitle = self.body[self.within_title:] - self.within_title = 0 self.body.append(self.context.pop()) + if self.in_document_title: + self.subtitle = self.body[self.in_document_title:-1] + self.in_document_title = 0 + self.body_pre_docinfo.extend(self.body) + del self.body[:] def visit_superscript(self, node): self.body.append(self.starttag(node, 'sup', '')) @@ -1226,7 +1229,7 @@ class HTMLTranslator(nodes.NodeVisitor): % self.encode(node.astext())) self.body.append(self.starttag(node, 'h1', '', CLASS='title')) self.context.append('\n') - self.within_title = len(self.body) + self.in_document_title = len(self.body) else: h_level = self.section_level + self.initial_header_level - 1 self.body.append( @@ -1248,10 +1251,12 @@ class HTMLTranslator(nodes.NodeVisitor): self.context.append(close_tag) def depart_title(self, node): - if self.within_title: - self.title = self.body[self.within_title:] - self.within_title = 0 self.body.append(self.context.pop()) + if self.in_document_title: + self.title = self.body[self.in_document_title:-1] + self.in_document_title = 0 + self.body_pre_docinfo.extend(self.body) + del self.body[:] def visit_title_reference(self, node): self.body.append(self.starttag(node, 'cite', '')) -- cgit v1.2.1 From 4be781bdfeba6e922e31c563956cf2bc277aff27 Mon Sep 17 00:00:00 2001 From: grubert Date: Sun, 9 May 2004 12:53:53 +0000 Subject: cosmetics ?! git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2061 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index d024cd971..65863eb68 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1104,7 +1104,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.depart_admonition() def visit_image(self, node): - attrs = node.attributes.copy() + attrs = node.attributes pre = [] # in reverse order post = ['\\includegraphics{%s}' % attrs['uri']] inline = isinstance(node.parent, nodes.TextElement) -- cgit v1.2.1 From 8a3e3c923e5bbcafb6021ae8883efca627765a39 Mon Sep 17 00:00:00 2001 From: grubert Date: Sun, 9 May 2004 14:10:11 +0000 Subject: Try to handle bold/emphasize spanning lines in parsed-literal blocks. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2063 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 65863eb68..9b773eae4 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -474,6 +474,7 @@ class LaTeXTranslator(nodes.NodeVisitor): 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 @@ -581,7 +582,13 @@ class LaTeXTranslator(nodes.NodeVisitor): # ! LaTeX Error: There's no line here to end. text = text.replace("\n", '~\\\\\n') elif self.mbox_newline: - text = text.replace("\n", '}\\\\\n\\mbox{') + if self.literal_block: + closings = "}" * len(self.literal_block_stack) + openings = "".join(self.literal_block_stack) + else: + closings = "" + openings = "" + text = text.replace("\n", "%s}\\\\\n\\mbox{%s" % (closings,openings)) if self.insert_none_breaking_blanks: text = text.replace(' ', '~') # unicode !!! @@ -874,9 +881,13 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_emphasis(self, node): self.body.append('\\emph{') + if self.literal_block: + self.literal_block_stack.append('\\emph{') def depart_emphasis(self, node): self.body.append('}') + if self.literal_block: + self.literal_block_stack.pop() def visit_entry(self, node): # cell separation @@ -1432,9 +1443,13 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_strong(self, node): self.body.append('\\textbf{') + if self.literal_block: + self.literal_block_stack.append('\\textbf{') def depart_strong(self, node): self.body.append('}') + if self.literal_block: + self.literal_block_stack.pop() def visit_substitution_definition(self, node): raise nodes.SkipNode -- cgit v1.2.1 From 443647725c11fe07696d5814a3bf6ddd5b7feb37 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 9 May 2004 16:23:54 +0000 Subject: bumped version to 0.3.3, changed versioning policy git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2067 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index d47365229..0a5442506 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -51,12 +51,14 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.3.2' -"""``major.minor.micro`` version number. The micro number is bumped any time -there's a change in the API incompatible with one of the front ends or -significant new functionality. The minor number is bumped whenever there is a +__version__ = '0.3.3' +"""``major.minor.micro`` version number. The micro number is bumped +any time there's a change in the API incompatible with one of the +front ends or significant new functionality, and at any alpha or beta +release. The minor number is bumped whenever there is a stable project release. The major number will be bumped when the project is -feature-complete, and perhaps if there is a major change in the design.""" +feature-complete, and perhaps if there is a major change in the +design.""" class ApplicationError(StandardError): pass -- cgit v1.2.1 From 633a241d40c5fe1eb9d3cb3c93954bcd9b7a0cc9 Mon Sep 17 00:00:00 2001 From: grubert Date: Sun, 9 May 2004 16:48:23 +0000 Subject: Add documentation on typewriter bold font. always push/pop in visit/depart_italic/strong onto literal_block_stack. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2068 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 9b773eae4..357f91006 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -881,13 +881,11 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_emphasis(self, node): self.body.append('\\emph{') - if self.literal_block: - self.literal_block_stack.append('\\emph{') + self.literal_block_stack.append('\\emph{') def depart_emphasis(self, node): self.body.append('}') - if self.literal_block: - self.literal_block_stack.pop() + self.literal_block_stack.pop() def visit_entry(self, node): # cell separation @@ -1242,9 +1240,11 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('\\begin{verbatim}\n') else: self.literal_block = 1 - self.mbox_newline = 1 self.insert_none_breaking_blanks = 1 - self.body.append('\\begin{ttfamily}\\begin{flushleft}\n\\mbox{') + self.body.append('\\begin{ttfamily}\\begin{flushleft}\n') + self.mbox_newline = 1 + if self.mbox_newline: + self.body.append('\\mbox{') # * obey..: is from julien and never worked for me (grubert). # self.body.append('{\\obeylines\\obeyspaces\\ttfamily\n') @@ -1253,7 +1253,9 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('\n\\end{verbatim}\n') self.verbatim = 0 else: - self.body.append('}\n\\end{flushleft}\\end{ttfamily}\n') + if self.mbox_newline: + self.body.append('}') + self.body.append('\n\\end{flushleft}\\end{ttfamily}\n') self.insert_none_breaking_blanks = 0 self.mbox_newline = 0 # obey end: self.body.append('}\n') @@ -1443,13 +1445,11 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_strong(self, node): self.body.append('\\textbf{') - if self.literal_block: - self.literal_block_stack.append('\\textbf{') + self.literal_block_stack.append('\\textbf{') def depart_strong(self, node): self.body.append('}') - if self.literal_block: - self.literal_block_stack.pop() + self.literal_block_stack.pop() def visit_substitution_definition(self, node): raise nodes.SkipNode -- cgit v1.2.1 From 888d604a64aae14fe0ea85e22da41cd9abfe4e5f Mon Sep 17 00:00:00 2001 From: grubert Date: Sun, 9 May 2004 16:54:22 +0000 Subject: Tell the reason for using mbox (not wrapping long lines). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2069 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 357f91006..6e44ac879 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1180,6 +1180,8 @@ class LaTeXTranslator(nodes.NodeVisitor): * whitespace (including linebreaks) is significant * inline markup is supported. * serif typeface + + mbox would stop LaTeX from wrapping long lines. """ self.body.append('\\begin{flushleft}\n') self.insert_none_breaking_blanks = 1 @@ -1223,6 +1225,8 @@ class LaTeXTranslator(nodes.NodeVisitor): blocks of text, where the inline markup is not recognized, but are also the product of the parsed-literal directive, where the markup is respected. + + mbox stops LaTeX from wrapping long lines. """ # In both cases, we want to use a typewriter/monospaced typeface. # For "real" literal-blocks, we can use \verbatim, while for all -- cgit v1.2.1 From 8d99e339fe3c08282cab199e9d6b032fd2577ffa Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 9 May 2004 17:19:11 +0000 Subject: bumped version to 0.3.4 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2070 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index 0a5442506..bcad2741c 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -51,7 +51,7 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.3.3' +__version__ = '0.3.4' """``major.minor.micro`` version number. The micro number is bumped any time there's a change in the API incompatible with one of the front ends or significant new functionality, and at any alpha or beta -- cgit v1.2.1 From 887947f5ad665679685e53076fa2b91748d4968b Mon Sep 17 00:00:00 2001 From: grubert Date: Mon, 10 May 2004 08:01:06 +0000 Subject: Comment on generated- functions. Another table test. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2076 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 1 + 1 file changed, 1 insertion(+) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 6e44ac879..d12d6e65f 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1090,6 +1090,7 @@ class LaTeXTranslator(nodes.NodeVisitor): return self.body.append('}%s' % self.context.pop()) + # elements generated by the framework e.g. section numbers. def visit_generated(self, node): pass -- cgit v1.2.1 From ac54bb531b3126f1e9573460a431980f9328fa6d Mon Sep 17 00:00:00 2001 From: grubert Date: Tue, 11 May 2004 07:00:39 +0000 Subject: Raise an error on multirows (never worked). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2080 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index d12d6e65f..7fb4e09d6 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -901,9 +901,11 @@ class LaTeXTranslator(nodes.NodeVisitor): 'span multiple rows *and* columns, sorry.') atts = {} if node.has_key('morerows'): + raise NotImplementedError('multiple rows are not working (yet), sorry.') count = node['morerows'] + 1 self.body.append('\\multirow{%d}*{' % count) self.context.append('}') + # BUG following rows must have empty cells. elif node.has_key('morecols'): # the vertical bar before column is missing if it is the first column. # the one after always. @@ -1402,6 +1404,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_row(self, node): self.context.pop() # remove cell counter self.body.append(' \\\\ \\hline\n') + # BUG if multirow cells \cline{x-y} def visit_section(self, node): self.section_level += 1 -- cgit v1.2.1 From 7368e7764782c50cbb58122dfa2ea59313393900 Mon Sep 17 00:00:00 2001 From: grubert Date: Wed, 12 May 2004 19:22:58 +0000 Subject: Add option --table-style=(standard|booktabs|nolines). Move most table handling into class Table. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2085 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 279 +++++++++++++++++++++++++++----------------- 1 file changed, 171 insertions(+), 108 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 7fb4e09d6..9d994f22e 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -112,6 +112,13 @@ class Writer(writers.Writer): ['--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': ''}), )) settings_defaults = {'output_encoding': 'latin-1'} @@ -307,7 +314,125 @@ class DocumentClass: 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 = {} + + 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 used_packages(self): + if self._table_style == 'booktabs': + return '\\usepackage{booktabs}\n' + return '' + def is_open(self): + return self._open + 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 + # 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 + latex_table_spec += "%sp{%.2f\\locallinewidth}" % (bar,colwidth+0.005) + return latex_table_spec+bar + + 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): + self._cell_in_row = None # remove cell counter + if self._table_style == 'standard': + return [' \\\\\n','\\hline\n'] + return [' \\\\\n'] + + 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. @@ -326,9 +451,7 @@ class LaTeXTranslator(nodes.NodeVisitor): # use latex tableofcontents or let docutils do it. use_latex_toc = 0 - # table kind: if 0 tabularx (single page), 1 longtable - # maybe should be decided on row count. - use_longtable = 1 + # TODO: use mixins for different implementations. # list environment for option-list. else tabularx use_optionlist_for_option_list = 1 @@ -378,6 +501,9 @@ class LaTeXTranslator(nodes.NodeVisitor): self.d_class = DocumentClass(settings.documentclass) + # object for a table while proccessing. + self.active_table = Table('longtable',settings.table_style) + self.head_prefix = [ self.latex_head % (self.d_options,self.settings.documentclass), '\\usepackage{babel}\n', # language is in documents settings. @@ -386,6 +512,7 @@ class LaTeXTranslator(nodes.NodeVisitor): # * 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). @@ -402,6 +529,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.geometry % (self.d_paper, self.d_margins), # self.generator, + # TODO active_table.definitions # latex lengths '\\newlength{\\admonitionwidth}\n', '\\setlength{\\admonitionwidth}{0.9\\textwidth}\n' @@ -443,7 +571,6 @@ class LaTeXTranslator(nodes.NodeVisitor): self.context = [] self.topic_class = '' # column specification for tables - self.colspecs = [] self.table_caption = None # do we have one or more authors self.author_stack = None @@ -739,10 +866,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append( '})\n' ) def visit_colspec(self, node): - if self.use_longtable: - self.colspecs.append(node) - else: - self.context[-1] += 1 + self.active_table.visit_colspec(node) def depart_colspec(self, node): pass @@ -888,11 +1012,9 @@ class LaTeXTranslator(nodes.NodeVisitor): self.literal_block_stack.pop() def visit_entry(self, node): + self.active_table.visit_entry() # cell separation - column_one = 1 - if self.context[-1] > 0: - column_one = 0 - if not column_one: + if self.active_table.get_entry_number() != 1: self.body.append(' & ') # multi{row,column} @@ -909,12 +1031,13 @@ class LaTeXTranslator(nodes.NodeVisitor): elif node.has_key('morecols'): # the vertical bar before column is missing if it is the first column. # the one after always. - if column_one: - bar = '|' + if self.active_table.get_entry_number() == 1: + bar1 = self.active_table.get_vertical_bar() else: - bar = '' + bar1 = '' count = node['morecols'] + 1 - self.body.append('\\multicolumn{%d}{%sl|}{' % (count, bar)) + self.body.append('\\multicolumn{%d}{%sl%s}{' % \ + (count, bar1, self.active_table.get_vertical_bar())) self.context.append('}') else: self.context.append('') @@ -929,7 +1052,6 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_entry(self, node): self.body.append(self.context.pop()) # header / not header self.body.append(self.context.pop()) # multirow/column - self.context[-1] += 1 def visit_enumerated_list(self, node): # We create our own enumeration list environment. @@ -1399,11 +1521,10 @@ class LaTeXTranslator(nodes.NodeVisitor): self.depart_docinfo_item(node) def visit_row(self, node): - self.context.append(0) + self.active_table.visit_row() def depart_row(self, node): - self.context.pop() # remove cell counter - self.body.append(' \\\\ \\hline\n') + self.body.extend(self.active_table.depart_row()) # BUG if multirow cells \cline{x-y} def visit_section(self, node): @@ -1482,70 +1603,19 @@ class LaTeXTranslator(nodes.NodeVisitor): if node['level'] < self.document.reporter['writer'].report_level: raise nodes.SkipNode - def depart_system_message(self, node): self.body.append('\n') - 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.colspecs: - colwidth = float(node['colwidth']+1) / width - total_width += colwidth - # donot make it full linewidth - factor = 0.93 - if total_width > 1.0: - factor /= total_width - - latex_table_spec = "" - for node in self.colspecs: - colwidth = factor * float(node['colwidth']+1) / width - latex_table_spec += "|p{%.2f\\locallinewidth}" % (colwidth+0.005) - self.colspecs = [] - return latex_table_spec+"|" - def visit_table(self, node): - if self.use_longtable: - self.body.append('\n\\begin{longtable}[c]') - else: - self.body.append('\n\\begin{tabularx}{\\linewidth}') - self.context.append('table_sentinel') # sentinel - self.context.append(0) # column counter + 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): - if self.use_longtable: - self.body.append('\\end{longtable}\n') - else: - self.body.append('\\end{tabularx}\n') - sentinel = self.context.pop() - if sentinel != 'table_sentinel': - print 'context:', self.context + [sentinel] - raise AssertionError - - def table_preamble(self): - if self.use_longtable: - self.body.append('{%s}\n' % self.get_colspecs()) - if self.table_caption: - self.body.append('\\caption{%s}\\\\\n' % self.table_caption) - self.table_caption = None - else: - if self.context[-1] != 'table_sentinel': - self.body.append('{%s}' % ('|X' * self.context.pop() + '|')) - self.body.append('\n\\hline') + 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 ? @@ -1562,13 +1632,12 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_tbody(self, node): # BUG write preamble if not yet done (colspecs not []) # for tables without heads. - if self.colspecs: + if not self.active_table.get('preamble written'): self.visit_thead(None) - self.depart_thead(None) - self.body.append('%[visit_tbody]\n') + # self.depart_thead(None) def depart_tbody(self, node): - self.body.append('%[depart_tbody]\n') + pass def visit_term(self, node): self.body.append('\\item[') @@ -1586,29 +1655,27 @@ class LaTeXTranslator(nodes.NodeVisitor): pass def visit_thead(self, node): - # number_of_columns will be zero after get_colspecs. - # BUG ! push onto context for depart to pop it. - number_of_columns = len(self.colspecs) - self.table_preamble() - #BUG longtable needs firstpage and lastfooter too. - self.body.append('\\hline\n') + 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): - if self.use_longtable: - # the table header written should be on every page - # => \endhead - self.body.append('\\endhead\n') - # 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') - + # 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') @@ -1637,7 +1704,6 @@ class LaTeXTranslator(nodes.NodeVisitor): 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) @@ -1651,7 +1717,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.context.append('}\n\\smallskip\n') elif isinstance(node.parent, nodes.table): # caption must be written after column spec - self.table_caption = node.astext() + self.active_table.caption = node.astext() raise nodes.SkipNode elif self.section_level == 0: # document title @@ -1690,8 +1756,6 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('\n') def visit_rubric(self, node): -# self.body.append('\\hfill {\\color{red}\\bfseries{}') -# self.context.append('} \\hfill ~\n') self.body.append('\\rubric{') self.context.append('}\n') @@ -1705,7 +1769,6 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('\n\n') def depart_transition(self, node): - #self.body.append('[depart_transition]') pass def visit_version(self, node): -- cgit v1.2.1 From 104d68ea45cc578d4aa06fcaedda795fbb093a1a Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 12 May 2004 23:58:49 +0000 Subject: Added special error handling & advice for UnicodeEncodeError. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2090 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 10 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index 96ed69bcc..37f9100f2 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -184,20 +184,17 @@ class Publisher: except utils.SystemMessage, error: if self.settings.traceback: raise - print >>sys.stderr, ('Exiting due to level-%s (%s) system message.' - % (error.level, - utils.Reporter.levels[error.level])) + self.report_SystemMessage(error) + exit = 1 + except UnicodeEncodeError, error: + if self.settings.traceback: + raise + self.report_UnicodeEncodeError(error) exit = 1 except Exception, error: if self.settings.traceback: raise - print >>sys.stderr, error - print >>sys.stderr, ("""\ -Exiting due to error. Use "--traceback" to diagnose. -Please report errors to . -Include "--traceback" output, Docutils version (%s), -Python version (%s), your OS type & version, and the -command line used.""" % (__version__, sys.version.split()[0])) + self.report_Exception(error) exit = 1 if self.settings.dump_settings: from pprint import pformat @@ -222,6 +219,51 @@ command line used.""" % (__version__, sys.version.split()[0])) sys.exit(1) return output + def report_SystemMessage(self, error): + print >>sys.stderr, ('Exiting due to level-%s (%s) system message.' + % (error.level, + utils.Reporter.levels[error.level])) + + def report_UnicodeEncodeError(self, error): + print >>sys.stderr, '%s: %s' % (error.__class__.__name__, error) + print >>sys.stderr, (""" +The specified output encoding (%s) cannot +handle all of the output. +Try setting "--output-encoding-error-handler" to +""" % (self.settings.output_encoding)), + if sys.hexversion >= 0x02030000: # Python 2.3 + print >>sys.stderr, (""" +* "xmlcharrefreplace" (for HTML & XML output, Python 2.3+); + the output will contain "%s" and should be usable. +* "backslashreplace" (for other output formats, Python 2.3+); + look for "%s" in the output. +*""" % (error.object[error.start:error.end].encode('ascii', + 'xmlcharrefreplace'), + error.object[error.start:error.end].encode('ascii', + 'backslashreplace'))), + print >>sys.stderr, ("""\ +"replace" (Python 2.1 or 2.2); look for "?" in the output. + +"--output-encoding-error-handler" is currently set to +"%s". + +Exiting due to error. Use "--traceback" to diagnose. +If the advice above doesn't eliminate the error, +please report it to . +Include "--traceback" output, Docutils version (%s), +Python version (%s), your OS type & version, and the +command line used.""" % (self.settings.output_encoding_error_handler, + __version__, sys.version.split()[0])) + + def report_Exception(self, error): + print >>sys.stderr, '%s: %s' % (error.__class__.__name__, error) + print >>sys.stderr, ("""\ +Exiting due to error. Use "--traceback" to diagnose. +Please report errors to . +Include "--traceback" output, Docutils version (%s), +Python version (%s), your OS type & version, and the +command line used.""" % (__version__, sys.version.split()[0])) + default_usage = '%prog [options] [ []]' default_description = ('Reads from (default is stdin) and writes to ' -- cgit v1.2.1 From 302da76e224a2fce05548bdebbd506d9d1a6bdad Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 12 May 2004 23:59:32 +0000 Subject: Added help text for --output-encoding-error-handler and --error-encoding-error-handler. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2091 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 8b74ab00c..48a58af69 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -344,22 +344,29 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): {'metavar': '', 'validator': validate_encoding}), ('Specify the text encoding for output. Default is UTF-8. ' 'Optionally also specify the encoding error handler for unencodable ' - 'characters (see "--error-encoding"); default is "strict".', + 'characters (see "--output-encoding-error-encoding"); ' + 'default is "strict".', ['--output-encoding', '-o'], {'metavar': '', 'default': 'utf-8', 'validator': validate_encoding_and_error_handler}), - (SUPPRESS_HELP, # usually handled by --output-encoding + ('Specify the encoding error handler for unencodable characters in ' + 'the output. Acceptable values include "strict", "ignore", ' + '"replace", "backslashreplace" (in Python 2.3+), and ' + '"xmlcharrefreplace" (in Python 2.3+). Default is "strict". ' + 'Usually specified as part of --output-encoding.', ['--output-encoding-error-handler'], {'default': 'strict', 'validator': validate_encoding_error_handler}), ('Specify the text encoding for error output. Default is ASCII. ' 'Optionally also specify the encoding error handler for unencodable ' - 'characters, after a colon (":"). Acceptable values are the same ' - 'as for the "error" parameter of Python\'s ``encode`` string ' - 'method. Default is "%s".' % default_error_encoding_error_handler, + 'characters, after a colon (":"). Default is "%s".' + % default_error_encoding_error_handler, ['--error-encoding', '-e'], {'metavar': '', 'default': 'ascii', 'validator': validate_encoding_and_error_handler}), - (SUPPRESS_HELP, # usually handled by --error-encoding + ('Specify the encoding error handler for unencodable characters in ' + 'error output. See --output-encoding-error-handler for acceptable ' + 'values. Default is "%s". Usually specified as part of ' + '--error-encoding.' % default_error_encoding_error_handler, ['--error-encoding-error-handler'], {'default': default_error_encoding_error_handler, 'validator': validate_encoding_error_handler}), -- cgit v1.2.1 From e63e9e1f758249afebcf545af3e4d73c208e8d29 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 13 May 2004 00:09:42 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2093 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 48a58af69..10716f568 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -343,13 +343,13 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): ['--input-encoding', '-i'], {'metavar': '', 'validator': validate_encoding}), ('Specify the text encoding for output. Default is UTF-8. ' - 'Optionally also specify the encoding error handler for unencodable ' - 'characters (see "--output-encoding-error-encoding"); ' - 'default is "strict".', + 'Optionally also specify the error handler for unencodable ' + 'characters, after a colon (":"); default is "strict". (See ' + '"--output-encoding-error-encoding".)', ['--output-encoding', '-o'], {'metavar': '', 'default': 'utf-8', 'validator': validate_encoding_and_error_handler}), - ('Specify the encoding error handler for unencodable characters in ' + ('Specify the error handler for unencodable characters in ' 'the output. Acceptable values include "strict", "ignore", ' '"replace", "backslashreplace" (in Python 2.3+), and ' '"xmlcharrefreplace" (in Python 2.3+). Default is "strict". ' @@ -357,13 +357,14 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): ['--output-encoding-error-handler'], {'default': 'strict', 'validator': validate_encoding_error_handler}), ('Specify the text encoding for error output. Default is ASCII. ' - 'Optionally also specify the encoding error handler for unencodable ' - 'characters, after a colon (":"). Default is "%s".' + 'Optionally also specify the error handler for unencodable ' + 'characters, after a colon (":"); default is "%s". (See ' + '"--output-encoding-error-encoding".' % default_error_encoding_error_handler, ['--error-encoding', '-e'], {'metavar': '', 'default': 'ascii', 'validator': validate_encoding_and_error_handler}), - ('Specify the encoding error handler for unencodable characters in ' + ('Specify the error handler for unencodable characters in ' 'error output. See --output-encoding-error-handler for acceptable ' 'values. Default is "%s". Usually specified as part of ' '--error-encoding.' % default_error_encoding_error_handler, -- cgit v1.2.1 From 7d04afaf75b5e41991029ba2babbd3ccfe3417e7 Mon Sep 17 00:00:00 2001 From: grubert Date: Fri, 14 May 2004 17:30:22 +0000 Subject: Remove unused variable atts. Change error message for multicell multirows. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2098 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 9d994f22e..73779f2a3 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -529,7 +529,6 @@ class LaTeXTranslator(nodes.NodeVisitor): self.geometry % (self.d_paper, self.d_margins), # self.generator, - # TODO active_table.definitions # latex lengths '\\newlength{\\admonitionwidth}\n', '\\setlength{\\admonitionwidth}{0.9\\textwidth}\n' @@ -1019,9 +1018,8 @@ class LaTeXTranslator(nodes.NodeVisitor): # multi{row,column} if node.has_key('morerows') and node.has_key('morecols'): - raise NotImplementedError('LaTeX can\'t handle cells that ' - 'span multiple rows *and* columns, sorry.') - atts = {} + raise NotImplementedError('Cells that ' + 'span multiple rows *and* columns are not supported, sorry.') if node.has_key('morerows'): raise NotImplementedError('multiple rows are not working (yet), sorry.') count = node['morerows'] + 1 @@ -1424,7 +1422,6 @@ class LaTeXTranslator(nodes.NodeVisitor): if self.use_optionlist_for_option_list: self.body.append('\\item [') else: - atts = {} if len(node.astext()) > 14: self.body.append('\\multicolumn{2}{l}{') self.context.append('} \\\\\n ') -- cgit v1.2.1 From 05550f4d93366798755e07b428c98e1b62a6838b Mon Sep 17 00:00:00 2001 From: grubert Date: Sun, 16 May 2004 16:32:07 +0000 Subject: Add column width array to class Table. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2111 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 73779f2a3..a0d0e2b3f 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -325,6 +325,7 @@ class Table: self._open = 0 # miscellaneous attributes self._attrs = {} + self._col_width = [] def open(self): self._open = 1 @@ -391,6 +392,7 @@ class Table: for node in self._col_specs: colwidth = float(node['colwidth']+1) / width total_width += colwidth + self._col_width = [] # donot make it full linewidth factor = 0.93 if total_width > 1.0: @@ -399,9 +401,15 @@ class Table: latex_table_spec = "" for node in self._col_specs: colwidth = factor * float(node['colwidth']+1) / width + self._col_width.append(colwidth+0.005) 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': @@ -1017,13 +1025,14 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append(' & ') # multi{row,column} + # IN WORK BUG TODO HACK continues here if node.has_key('morerows') and node.has_key('morecols'): raise NotImplementedError('Cells that ' 'span multiple rows *and* columns are not supported, sorry.') if node.has_key('morerows'): - raise NotImplementedError('multiple rows are not working (yet), sorry.') count = node['morerows'] + 1 - self.body.append('\\multirow{%d}*{' % count) + self.body.append('\\multirow{%d}{%s}{' % \ + (count,self.active_table.get_column_width())) self.context.append('}') # BUG following rows must have empty cells. elif node.has_key('morecols'): -- cgit v1.2.1 From a0e007f9eac57f0e6611d45aa8e5e73fa43110ae Mon Sep 17 00:00:00 2001 From: grubert Date: Sun, 16 May 2004 17:02:31 +0000 Subject: Figures have option "here" and content is centered. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2112 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index a0d0e2b3f..a3ee0a318 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1163,10 +1163,10 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append(':]') def visit_figure(self, node): - self.body.append( '\\begin{figure}\n' ) + self.body.append( '\\begin{figure}[h]\\begin{center}\n' ) def depart_figure(self, node): - self.body.append( '\\end{figure}\n' ) + self.body.append( '\\end{center}\\end{figure}\n' ) def visit_footer(self, node): self.context.append(len(self.body)) -- cgit v1.2.1 From 4f6306efaa650d80668f3f93d9e5dde7f0730789 Mon Sep 17 00:00:00 2001 From: grubert Date: Sun, 16 May 2004 20:31:11 +0000 Subject: Multirow support. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2115 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 68 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 11 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index a3ee0a318..3f3882457 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -326,6 +326,7 @@ class Table: # miscellaneous attributes self._attrs = {} self._col_width = [] + self._rowspan = [] def open(self): self._open = 1 @@ -393,6 +394,7 @@ class Table: 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: @@ -402,6 +404,7 @@ class Table: 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 @@ -430,11 +433,42 @@ class Table: 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': - return [' \\\\\n','\\hline\n'] - return [' \\\\\n'] - + 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): @@ -1021,16 +1055,25 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_entry(self, node): self.active_table.visit_entry() # cell separation - if self.active_table.get_entry_number() != 1: + if self.active_table.get_entry_number() == 1: + # 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(' & ') + self.active_table.visit_entry() # increment cell count + else: self.body.append(' & ') # multi{row,column} # IN WORK BUG TODO HACK continues here + # multirow in LaTeX simply will enlarge the cell over several rows + # (the following n if n is positive, the former if negative). if node.has_key('morerows') and node.has_key('morecols'): raise NotImplementedError('Cells that ' 'span multiple rows *and* columns are not supported, sorry.') if node.has_key('morerows'): count = node['morerows'] + 1 + self.active_table.set_rowspan(self.active_table.get_entry_number()-1,count) self.body.append('\\multirow{%d}{%s}{' % \ (count,self.active_table.get_column_width())) self.context.append('}') @@ -1059,6 +1102,16 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_entry(self, node): self.body.append(self.context.pop()) # header / not header self.body.append(self.context.pop()) # multirow/column + # if following row is spanned from above. + if self.active_table.get_rowspan(self.active_table.get_entry_number()): + self.body.append(' & ') + self.active_table.visit_entry() # increment cell count + + def visit_row(self, node): + self.active_table.visit_row() + + def depart_row(self, node): + self.body.extend(self.active_table.depart_row()) def visit_enumerated_list(self, node): # We create our own enumeration list environment. @@ -1526,13 +1579,6 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_revision(self, node): self.depart_docinfo_item(node) - def visit_row(self, node): - self.active_table.visit_row() - - def depart_row(self, node): - self.body.extend(self.active_table.depart_row()) - # BUG if multirow cells \cline{x-y} - def visit_section(self, node): self.section_level += 1 # Initialize counter for potential subsections: -- cgit v1.2.1 From 5eed847ca61d047d2f80c8b045a8ab69016ced0a Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 17 May 2004 17:11:53 +0000 Subject: changed [h] to [htbp] for placement of figures git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2117 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 3f3882457..e1305fc1a 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1216,7 +1216,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append(':]') def visit_figure(self, node): - self.body.append( '\\begin{figure}[h]\\begin{center}\n' ) + self.body.append( '\\begin{figure}[htbp]\\begin{center}\n' ) def depart_figure(self, node): self.body.append( '\\end{center}\\end{figure}\n' ) -- cgit v1.2.1 From 1a4e77baaf1faa8c191325baf19d53d9a15eb73e Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 17 May 2004 18:42:49 +0000 Subject: change to UnicodeError, which exists in Python 2.1 & 2.2 (UnicodeEncodeError is new in 2.3) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2118 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index 37f9100f2..0c7eba275 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -186,10 +186,10 @@ class Publisher: raise self.report_SystemMessage(error) exit = 1 - except UnicodeEncodeError, error: + except UnicodeError, error: if self.settings.traceback: raise - self.report_UnicodeEncodeError(error) + self.report_UnicodeError(error) exit = 1 except Exception, error: if self.settings.traceback: @@ -224,7 +224,7 @@ class Publisher: % (error.level, utils.Reporter.levels[error.level])) - def report_UnicodeEncodeError(self, error): + def report_UnicodeError(self, error): print >>sys.stderr, '%s: %s' % (error.__class__.__name__, error) print >>sys.stderr, (""" The specified output encoding (%s) cannot -- cgit v1.2.1 From 313f589dd000ca3f8fc956506186d22bada9ddc5 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 23 May 2004 16:09:12 +0000 Subject: XHTML validity fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2122 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index da2c7cac6..b661f831d 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -418,7 +418,6 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.starttag(node, 'table', CLASS='citation', frame="void", rules="none")) self.body.append('\n' - '\n' '\n' '') self.footnote_backrefs(node) @@ -1143,7 +1142,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append( # "border=None" is a boolean attribute; # it means "standard border", not "no border": - self.starttag(node, 'table', CLASS="table", border=None)) + self.starttag(node, 'table', CLASS="table", border="1")) def depart_table(self, node): self.body.append('\n') -- cgit v1.2.1 From e7e73998e0bb85cc2e98899cb59d85c83d90a128 Mon Sep 17 00:00:00 2001 From: grubert Date: Wed, 26 May 2004 16:19:16 +0000 Subject: Chg: use raggedright instead of flushleft for literal-blocks inside tables. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2127 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index e1305fc1a..ab3c06ce9 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -339,7 +339,8 @@ class Table: 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' @@ -1430,7 +1431,11 @@ class LaTeXTranslator(nodes.NodeVisitor): else: self.literal_block = 1 self.insert_none_breaking_blanks = 1 - self.body.append('\\begin{ttfamily}\\begin{flushleft}\n') + self.body.append('\\begin{ttfamily}') + if self.active_table.is_open(): + self.body.append('\\raggedright\n') + else: + self.body.append('\\begin{flushleft}\n') self.mbox_newline = 1 if self.mbox_newline: self.body.append('\\mbox{') @@ -1444,7 +1449,10 @@ class LaTeXTranslator(nodes.NodeVisitor): else: if self.mbox_newline: self.body.append('}') - self.body.append('\n\\end{flushleft}\\end{ttfamily}\n') + self.body.append('\n') + if not self.active_table.is_open(): + self.body.append('\\end{flushleft}') + self.body.append('\\end{ttfamily}\n') self.insert_none_breaking_blanks = 0 self.mbox_newline = 0 # obey end: self.body.append('}\n') -- cgit v1.2.1 From 88a664b00f6b686b36874c6168b4ef4e17a9f036 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 30 May 2004 14:13:47 +0000 Subject: simplified handling of literal blocks git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2138 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index ab3c06ce9..ebc7aa4d5 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -625,7 +625,9 @@ class LaTeXTranslator(nodes.NodeVisitor): # 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 + # XXX This is not needed anymore and will be deleted soon, + # if nobody complains. + self.mbox_newline = 0 # enumeration is done by list environment. self._enum_cnt = 0 @@ -758,6 +760,8 @@ class LaTeXTranslator(nodes.NodeVisitor): closings = "" openings = "" text = text.replace("\n", "%s}\\\\\n\\mbox{%s" % (closings,openings)) + else: + text = text.replace("\n", "\\\\\n") if self.insert_none_breaking_blanks: text = text.replace(' ', '~') # unicode !!! @@ -1411,8 +1415,6 @@ class LaTeXTranslator(nodes.NodeVisitor): blocks of text, where the inline markup is not recognized, but are also the product of the parsed-literal directive, where the markup is respected. - - mbox stops LaTeX from wrapping long lines. """ # In both cases, we want to use a typewriter/monospaced typeface. # For "real" literal-blocks, we can use \verbatim, while for all @@ -1422,7 +1424,7 @@ class LaTeXTranslator(nodes.NodeVisitor): # siblings the compose this node: if it is composed by a # single element, it's surely is either a real one, otherwise # it's a parsed-literal that does not contain any markup. - # + # if (self.settings.use_verbatim_when_possible and (len(node) == 1) # in case of a parsed-literal containing just a "**bold**" word: and isinstance(node[0], nodes.Text)): @@ -1431,12 +1433,8 @@ class LaTeXTranslator(nodes.NodeVisitor): else: self.literal_block = 1 self.insert_none_breaking_blanks = 1 - self.body.append('\\begin{ttfamily}') - if self.active_table.is_open(): - self.body.append('\\raggedright\n') - else: - self.body.append('\\begin{flushleft}\n') - self.mbox_newline = 1 + self.body.append('\n{\\ttfamily \\raggedright \\noindent\n') + self.mbox_newline = 0 if self.mbox_newline: self.body.append('\\mbox{') # * obey..: is from julien and never worked for me (grubert). @@ -1449,10 +1447,7 @@ class LaTeXTranslator(nodes.NodeVisitor): else: if self.mbox_newline: self.body.append('}') - self.body.append('\n') - if not self.active_table.is_open(): - self.body.append('\\end{flushleft}') - self.body.append('\\end{ttfamily}\n') + self.body.append('\n}\n') self.insert_none_breaking_blanks = 0 self.mbox_newline = 0 # obey end: self.body.append('}\n') -- cgit v1.2.1 From 64856e16043a6b36b6ab3ecc37ec98dc7ba69594 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 30 May 2004 14:22:22 +0000 Subject: fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2139 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index ebc7aa4d5..e607da79a 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -748,7 +748,7 @@ class LaTeXTranslator(nodes.NodeVisitor): text = self.babel.double_quotes_in_tt(text) else: text = self.babel.quote_quotes(text) - if self.insert_newline: + if self.insert_newline or self.literal_block: # HACK: insert a blank before the newline, to avoid # ! LaTeX Error: There's no line here to end. text = text.replace("\n", '~\\\\\n') @@ -760,8 +760,6 @@ class LaTeXTranslator(nodes.NodeVisitor): closings = "" openings = "" text = text.replace("\n", "%s}\\\\\n\\mbox{%s" % (closings,openings)) - else: - text = text.replace("\n", "\\\\\n") if self.insert_none_breaking_blanks: text = text.replace(' ', '~') # unicode !!! -- cgit v1.2.1 From 16cb718b14bbf360c87e14f5c46ed8f53a755faf Mon Sep 17 00:00:00 2001 From: grubert Date: Sun, 30 May 2004 17:09:02 +0000 Subject: Chg: literal_block with fluxhleft outside of tables. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2140 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index e607da79a..6b0a0e24c 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -625,9 +625,7 @@ class LaTeXTranslator(nodes.NodeVisitor): # insert_newline: to tell encode to add latex newline. self.insert_newline = 0 # mbox_newline: to tell encode to add mbox and newline. - # XXX This is not needed anymore and will be deleted soon, - # if nobody complains. - self.mbox_newline = 0 + self.mbox_newline = 0 # enumeration is done by list environment. self._enum_cnt = 0 @@ -1369,10 +1367,11 @@ class LaTeXTranslator(nodes.NodeVisitor): * inline markup is supported. * serif typeface - mbox would stop LaTeX from wrapping long lines. """ self.body.append('\\begin{flushleft}\n') self.insert_none_breaking_blanks = 1 + # mbox would stop LaTeX from wrapping long lines. + # but line_blocks are allowed to wrap. self.line_block_without_mbox = 1 if self.line_block_without_mbox: self.insert_newline = 1 @@ -1431,10 +1430,11 @@ class LaTeXTranslator(nodes.NodeVisitor): else: self.literal_block = 1 self.insert_none_breaking_blanks = 1 - self.body.append('\n{\\ttfamily \\raggedright \\noindent\n') - self.mbox_newline = 0 - if self.mbox_newline: - self.body.append('\\mbox{') + if self.active_table.is_open(): + self.body.append('\n{\\ttfamily \\raggedright \\noindent\n') + else: + self.body.append('\\begin{ttfamily}') + self.body.append('\\begin{flushleft}\n') # * obey..: is from julien and never worked for me (grubert). # self.body.append('{\\obeylines\\obeyspaces\\ttfamily\n') @@ -1442,12 +1442,13 @@ class LaTeXTranslator(nodes.NodeVisitor): if self.verbatim: self.body.append('\n\\end{verbatim}\n') self.verbatim = 0 - else: - if self.mbox_newline: - self.body.append('}') + elif self.active_table.is_open(): self.body.append('\n}\n') + else: + self.body.append('\n') + self.body.append('\\end{flushleft}') + self.body.append('\\end{ttfamily}\n') self.insert_none_breaking_blanks = 0 - self.mbox_newline = 0 # obey end: self.body.append('}\n') self.literal_block = 0 -- cgit v1.2.1 From 425f4e452ca17bc4e88f9b960309e98efe5d8692 Mon Sep 17 00:00:00 2001 From: grubert Date: Sun, 30 May 2004 18:59:53 +0000 Subject: Chg: citations cant be done with LaTeX footnotes. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2144 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 6b0a0e24c..0bd7ed831 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -37,7 +37,7 @@ class Writer(writers.Writer): 'separated by commas. Default is "10pt".', ['--documentoptions'], {'default': '10pt', }), - ('Use LaTeX footnotes. ' + ('Use LaTeX footnotes. LaTeX supports only numbered footnotes (does it?). ' 'Default: no, uses figures.', ['--use-latex-footnotes'], {'default': 0, 'action': 'store_true', @@ -750,6 +750,7 @@ class LaTeXTranslator(nodes.NodeVisitor): # HACK: insert a blank before the newline, to avoid # ! LaTeX Error: There's no line here to end. text = text.replace("\n", '~\\\\\n') + # HACK: lines starting with "[" or "]" give errors. elif self.mbox_newline: if self.literal_block: closings = "}" * len(self.literal_block_stack) @@ -879,10 +880,12 @@ class LaTeXTranslator(nodes.NodeVisitor): self.depart_admonition() def visit_citation(self, node): - self.visit_footnote(node) + # TODO maybe use cite bibitems + self.body.append('\\begin{figure}[b]') + self.body.append('\\hypertarget{%s}' % node['id']) def depart_citation(self, node): - self.depart_footnote(node) + self.body.append('\\end{figure}\n') def visit_title_reference(self, node): self.body.append( '\\titlereference{' ) @@ -1237,7 +1240,7 @@ class LaTeXTranslator(nodes.NodeVisitor): num,text = node.astext().split(None,1) num = self.encode(num.strip()) self.body.append('\\footnotetext['+num+']') - self.body.append('{'+self.encode(text)+'}') + self.body.append('{'+self.encode(text)+'}\n') raise nodes.SkipNode else: self.body.append('\\begin{figure}[b]') -- cgit v1.2.1 From c18ec002ea820f89aa7703980b4a3ca63686b61d Mon Sep 17 00:00:00 2001 From: grubert Date: Sun, 30 May 2004 21:07:13 +0000 Subject: Fix: bracketts at start of lines in literal blocks must be enclosed in braces. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2145 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 0bd7ed831..5b9b6a145 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -750,7 +750,6 @@ class LaTeXTranslator(nodes.NodeVisitor): # HACK: insert a blank before the newline, to avoid # ! LaTeX Error: There's no line here to end. text = text.replace("\n", '~\\\\\n') - # HACK: lines starting with "[" or "]" give errors. elif self.mbox_newline: if self.literal_block: closings = "}" * len(self.literal_block_stack) @@ -759,6 +758,11 @@ class LaTeXTranslator(nodes.NodeVisitor): closings = "" openings = "" text = text.replace("\n", "%s}\\\\\n\\mbox{%s" % (closings,openings)) + # HACK: lines starting with "[" or "]" give errors. + if not self.__dict__.has_key('encode_re_bracketts'): + self.encode_re_bracketts = re.compile(r'([\[\]])') + if self.literal_block and not self.mbox_newline: + text = self.encode_re_bracketts.sub(r'{\1}',text) if self.insert_none_breaking_blanks: text = text.replace(' ', '~') # unicode !!! -- cgit v1.2.1 From 00367ad5ed8785380bdb13b8242f79f4c3602809 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 31 May 2004 13:45:05 +0000 Subject: fix for square brackets git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2146 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 5b9b6a145..e61c131c5 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -741,6 +741,8 @@ class LaTeXTranslator(nodes.NodeVisitor): text = text.replace("%", '{\\%}') text = text.replace("#", '{\\#}') text = text.replace("~", '{\\textasciitilde}') + text = text.replace("[", '{}[') + text = text.replace("]", '{}]') if self.literal_block or self.literal: # pdflatex does not produce doublequotes for ngerman. text = self.babel.double_quotes_in_tt(text) -- cgit v1.2.1 From f31b416bab2ccf74f200241dce2a91162e0b98a9 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 31 May 2004 14:14:23 +0000 Subject: fix for square brackets git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2147 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index e61c131c5..ec251fd02 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -741,8 +741,6 @@ class LaTeXTranslator(nodes.NodeVisitor): text = text.replace("%", '{\\%}') text = text.replace("#", '{\\#}') text = text.replace("~", '{\\textasciitilde}') - text = text.replace("[", '{}[') - text = text.replace("]", '{}]') if self.literal_block or self.literal: # pdflatex does not produce doublequotes for ngerman. text = self.babel.double_quotes_in_tt(text) @@ -760,11 +758,9 @@ class LaTeXTranslator(nodes.NodeVisitor): closings = "" openings = "" text = text.replace("\n", "%s}\\\\\n\\mbox{%s" % (closings,openings)) - # HACK: lines starting with "[" or "]" give errors. - if not self.__dict__.has_key('encode_re_bracketts'): - self.encode_re_bracketts = re.compile(r'([\[\]])') - if self.literal_block and not self.mbox_newline: - text = self.encode_re_bracketts.sub(r'{\1}',text) + # lines starting with "[" or "]" give errors. + self.encode_re_bracketts = re.compile(r'([\[\]])') + text = self.encode_re_bracketts.sub(r'{\1}',text) if self.insert_none_breaking_blanks: text = text.replace(' ', '~') # unicode !!! -- cgit v1.2.1 From 79eef33c08e3c23042e76702ab41b51a4baf5f20 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 31 May 2004 16:54:59 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2149 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 10716f568..b440954fb 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -311,8 +311,9 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): ['--quiet', '-q'], {'action': 'store_const', 'const': 'none', 'dest': 'report_level'}), ('Set the threshold () at or above which system messages are ' - 'converted to exceptions, halting execution immediately. Levels ' - 'as in --report. Default is 4 (severe).', + 'converted to exceptions, halting execution immediately by ' + 'exiting (or propagating the exception if --traceback set). ' + 'Levels as in --report. Default is 4 (severe).', ['--halt'], {'choices': threshold_choices, 'dest': 'halt_level', 'default': 4, 'metavar': '', 'validator': validate_threshold}), @@ -333,7 +334,9 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): ['--no-debug'], {'action': 'store_false', 'dest': 'debug'}), ('Send the output of system messages (warnings) to .', ['--warnings'], {'dest': 'warning_stream', 'metavar': ''}), - ('Enable Python tracebacks when an error occurs.', + ('Enable Python tracebacks when halt-level system messages and ' + 'other exceptions occur. Useful for debugging, and essential for ' + 'issue reports.', ['--traceback'], {'action': 'store_true', 'default': None, 'validator': validate_boolean}), ('Disable Python tracebacks when errors occur; report just the error ' -- cgit v1.2.1 From c609122202af918a3175fe479b4e32052f011a28 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 31 May 2004 19:29:23 +0000 Subject: simply fix for square brackets git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2150 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index ec251fd02..cad87e8ca 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -758,9 +758,8 @@ class LaTeXTranslator(nodes.NodeVisitor): closings = "" openings = "" text = text.replace("\n", "%s}\\\\\n\\mbox{%s" % (closings,openings)) - # lines starting with "[" or "]" give errors. - self.encode_re_bracketts = re.compile(r'([\[\]])') - text = self.encode_re_bracketts.sub(r'{\1}',text) + # lines starting with "[" give errors. + text = text.replace('[', '{[}') if self.insert_none_breaking_blanks: text = text.replace(' ', '~') # unicode !!! -- cgit v1.2.1 From 8dde89834330d67af2ba384f5b72ea8aa11b8f3e Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 1 Jun 2004 03:58:09 +0000 Subject: refactored: simplified Publisher.publish (exception handling & debug dumps) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2154 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 58 ++++++++++++++++++++++++++------------------------------ 1 file changed, 27 insertions(+), 31 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index 0c7eba275..06a6fe2d3 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -15,6 +15,7 @@ custom component objects first, and pass *them* to __docformat__ = 'reStructuredText' import sys +import pprint from docutils import __version__, Component, SettingsSpec from docutils import frontend, io, utils, readers, parsers, writers from docutils.frontend import OptionParser @@ -181,43 +182,47 @@ class Publisher: self.apply_transforms(document) output = self.writer.write(document, self.destination) self.writer.assemble_parts() - except utils.SystemMessage, error: - if self.settings.traceback: - raise - self.report_SystemMessage(error) - exit = 1 - except UnicodeError, error: - if self.settings.traceback: - raise - self.report_UnicodeError(error) - exit = 1 except Exception, error: if self.settings.traceback: raise self.report_Exception(error) exit = 1 + self.debugging_dumps(document) + if enable_exit and document and (document.reporter.max_level + >= self.settings.exit_level): + sys.exit(document.reporter.max_level + 10) + elif exit: + sys.exit(1) + return output + + def debugging_dumps(self, document): if self.settings.dump_settings: - from pprint import pformat print >>sys.stderr, '\n::: Runtime settings:' - print >>sys.stderr, pformat(self.settings.__dict__) + print >>sys.stderr, pprint.pformat(self.settings.__dict__) if self.settings.dump_internals and document: - from pprint import pformat print >>sys.stderr, '\n::: Document internals:' - print >>sys.stderr, pformat(document.__dict__) + print >>sys.stderr, pprint.pformat(document.__dict__) if self.settings.dump_transforms and document: - from pprint import pformat print >>sys.stderr, '\n::: Transforms applied:' - print >>sys.stderr, pformat(document.transformer.applied) + print >>sys.stderr, pprint.pformat(document.transformer.applied) if self.settings.dump_pseudo_xml and document: print >>sys.stderr, '\n::: Pseudo-XML:' print >>sys.stderr, document.pformat().encode( 'raw_unicode_escape') - if enable_exit and document and (document.reporter.max_level - >= self.settings.exit_level): - sys.exit(document.reporter.max_level + 10) - elif exit: - sys.exit(1) - return output + + def report_Exception(self, error): + if isinstance(error, utils.SystemMessage): + self.report_SystemMessage(error) + elif isinstance(error, UnicodeError): + self.report_UnicodeError(error) + else: + print >>sys.stderr, '%s: %s' % (error.__class__.__name__, error) + print >>sys.stderr, ("""\ +Exiting due to error. Use "--traceback" to diagnose. +Please report errors to . +Include "--traceback" output, Docutils version (%s), +Python version (%s), your OS type & version, and the +command line used.""" % (__version__, sys.version.split()[0])) def report_SystemMessage(self, error): print >>sys.stderr, ('Exiting due to level-%s (%s) system message.' @@ -255,15 +260,6 @@ Python version (%s), your OS type & version, and the command line used.""" % (self.settings.output_encoding_error_handler, __version__, sys.version.split()[0])) - def report_Exception(self, error): - print >>sys.stderr, '%s: %s' % (error.__class__.__name__, error) - print >>sys.stderr, ("""\ -Exiting due to error. Use "--traceback" to diagnose. -Please report errors to . -Include "--traceback" output, Docutils version (%s), -Python version (%s), your OS type & version, and the -command line used.""" % (__version__, sys.version.split()[0])) - default_usage = '%prog [options] [ []]' default_description = ('Reads from (default is stdin) and writes to ' -- cgit v1.2.1 From b0f2e3492ad99d8c517ff9bc904c65696b2042d8 Mon Sep 17 00:00:00 2001 From: grubert Date: Tue, 1 Jun 2004 14:27:21 +0000 Subject: Change footnotes were taken as_text only, now with sructure too. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2159 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index cad87e8ca..dec05e2ae 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1241,8 +1241,7 @@ class LaTeXTranslator(nodes.NodeVisitor): num,text = node.astext().split(None,1) num = self.encode(num.strip()) self.body.append('\\footnotetext['+num+']') - self.body.append('{'+self.encode(text)+'}\n') - raise nodes.SkipNode + self.body.append('{') else: self.body.append('\\begin{figure}[b]') self.body.append('\\hypertarget{%s}' % node['id']) @@ -1257,7 +1256,6 @@ class LaTeXTranslator(nodes.NodeVisitor): if self.use_latex_footnotes: self.body.append("\\footnotemark["+self.encode(node.astext())+"]") raise nodes.SkipNode - return href = '' if node.has_key('refid'): href = node['refid'] @@ -1279,6 +1277,15 @@ class LaTeXTranslator(nodes.NodeVisitor): return self.body.append('}%s' % self.context.pop()) + # footnote/citation label + def visit_label(self, node): + if self.use_latex_footnotes: + raise nodes.SkipNode + self.body.append('[') + + def depart_label(self, node): + self.body.append(']') + # elements generated by the framework e.g. section numbers. def visit_generated(self, node): pass @@ -1352,13 +1359,6 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_interpreted(self, node): self.depart_literal(node) - def visit_label(self, node): - # footnote/citation label - self.body.append('[') - - def depart_label(self, node): - self.body.append(']') - def visit_legend(self, node): self.body.append('{\\small ') -- cgit v1.2.1 From 7f5c636bf4913667ee5b3a5aa55a33b175f5298f Mon Sep 17 00:00:00 2001 From: grubert Date: Tue, 1 Jun 2004 14:42:15 +0000 Subject: Fix: visit label must print labels for citations. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2160 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index dec05e2ae..b093f11e9 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1279,7 +1279,7 @@ class LaTeXTranslator(nodes.NodeVisitor): # footnote/citation label def visit_label(self, node): - if self.use_latex_footnotes: + if isinstance(node.parent, nodes.footnote) and self.use_latex_footnotes: raise nodes.SkipNode self.body.append('[') -- cgit v1.2.1 From 03b629b6eb4e58305b275baf30ebaea32cb701a5 Mon Sep 17 00:00:00 2001 From: grubert Date: Thu, 3 Jun 2004 08:26:42 +0000 Subject: Fix: admonitions before first section. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2177 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index b093f11e9..53988a5d1 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1762,6 +1762,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_title(self, node): """Only 3 section levels are supported by LaTeX article (AFAIR).""" + self.body.append(type(node.parent)) if isinstance(node.parent, nodes.topic): # section titles before the table of contents. self.bookmark(node) @@ -1770,7 +1771,10 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('\\subsection*{~\\hfill ') # the closing brace for subsection. self.context.append('\\hfill ~}\n') - elif isinstance(node.parent, nodes.sidebar): + # 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): -- cgit v1.2.1 From 6d548a2922ebb89dfc880cf20ecd00633a6a138d Mon Sep 17 00:00:00 2001 From: grubert Date: Thu, 3 Jun 2004 08:28:51 +0000 Subject: Remove test output. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2178 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 1 - 1 file changed, 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 53988a5d1..a98ac971b 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1762,7 +1762,6 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_title(self, node): """Only 3 section levels are supported by LaTeX article (AFAIR).""" - self.body.append(type(node.parent)) if isinstance(node.parent, nodes.topic): # section titles before the table of contents. self.bookmark(node) -- cgit v1.2.1 From d89f72d76b0683f92c0b16d86a16dcce54520643 Mon Sep 17 00:00:00 2001 From: grubert Date: Thu, 3 Jun 2004 09:31:23 +0000 Subject: Fix depart_literal_block when in a table. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2179 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index a98ac971b..600fbefd3 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1446,15 +1446,16 @@ class LaTeXTranslator(nodes.NodeVisitor): if self.verbatim: self.body.append('\n\\end{verbatim}\n') self.verbatim = 0 - elif self.active_table.is_open(): - self.body.append('\n}\n') else: - self.body.append('\n') - self.body.append('\\end{flushleft}') - self.body.append('\\end{ttfamily}\n') + if self.active_table.is_open(): + self.body.append('\n}\n') + else: + self.body.append('\n') + self.body.append('\\end{flushleft}') + self.body.append('\\end{ttfamily}\n') self.insert_none_breaking_blanks = 0 - # obey end: self.body.append('}\n') self.literal_block = 0 + # obey end: self.body.append('}\n') def visit_meta(self, node): self.body.append('[visit_meta]\n') -- cgit v1.2.1 From 89274bc3056c7c02f626fe5a126b55f62e6a08be Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 3 Jun 2004 20:44:34 +0000 Subject: Renamed "enable_exit" parameter of convenience functions to "enable_exit_status" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2208 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index 06a6fe2d3..9dd8f5760 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -161,7 +161,7 @@ class Publisher: def publish(self, argv=None, usage=None, description=None, settings_spec=None, settings_overrides=None, - config_section=None, enable_exit=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 @@ -188,8 +188,9 @@ class Publisher: self.report_Exception(error) exit = 1 self.debugging_dumps(document) - if enable_exit and document and (document.reporter.max_level - >= self.settings.exit_level): + if (enable_exit_status and document + and (document.reporter.max_level + >= self.settings.exit_status_level)): sys.exit(document.reporter.max_level + 10) elif exit: sys.exit(1) @@ -270,7 +271,7 @@ def publish_cmdline(reader=None, reader_name='standalone', writer=None, writer_name='pseudoxml', settings=None, settings_spec=None, settings_overrides=None, config_section=None, - enable_exit=1, argv=None, + enable_exit_status=1, argv=None, usage=default_usage, description=default_description): """ Set up & run a `Publisher`. For command-line front ends. @@ -293,7 +294,7 @@ def publish_cmdline(reader=None, reader_name='standalone', of component settings. - `config_section`: Name of configuration file section for application. Used only if no `settings` or `settings_spec` specified. - - `enable_exit`: Boolean; enable exit status at end of processing? + - `enable_exit_status`: Boolean; enable exit status at end of processing? - `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. @@ -303,7 +304,8 @@ def publish_cmdline(reader=None, reader_name='standalone', pub = Publisher(reader, parser, writer, settings=settings) pub.set_components(reader_name, parser_name, writer_name) pub.publish(argv, usage, description, settings_spec, settings_overrides, - config_section=config_section, enable_exit=enable_exit) + config_section=config_section, + enable_exit_status=enable_exit_status) def publish_file(source=None, source_path=None, destination=None, destination_path=None, @@ -311,7 +313,7 @@ def publish_file(source=None, source_path=None, parser=None, parser_name='restructuredtext', writer=None, writer_name='pseudoxml', settings=None, settings_spec=None, settings_overrides=None, - config_section=None, enable_exit=None): + config_section=None, enable_exit_status=None): """ Set up & run a `Publisher`. For programmatic use with file-like I/O. @@ -341,7 +343,7 @@ def publish_file(source=None, source_path=None, of component settings. - `config_section`: Name of configuration file section for application. Used only if no `settings` or `settings_spec` specified. - - `enable_exit`: Boolean; enable exit status at end of processing? + - `enable_exit_status`: Boolean; enable exit status at end of processing? """ pub = Publisher(reader, parser, writer, settings=settings) pub.set_components(reader_name, parser_name, writer_name) @@ -352,7 +354,7 @@ def publish_file(source=None, source_path=None, settings._update(settings_overrides, 'loose') pub.set_source(source, source_path) pub.set_destination(destination, destination_path) - pub.publish(enable_exit=enable_exit) + pub.publish(enable_exit_status=enable_exit_status) def publish_string(source, source_path=None, destination_path=None, reader=None, reader_name='standalone', @@ -360,7 +362,7 @@ def publish_string(source, source_path=None, destination_path=None, writer=None, writer_name='pseudoxml', settings=None, settings_spec=None, settings_overrides=None, config_section=None, - enable_exit=None): + enable_exit_status=None): """ Set up & run a `Publisher`, and return the string output. For programmatic use with string I/O. @@ -401,7 +403,7 @@ def publish_string(source, source_path=None, destination_path=None, of component settings. - `config_section`: Name of configuration file section for application. Used only if no `settings` or `settings_spec` specified. - - `enable_exit`: Boolean; enable exit status at end of processing? + - `enable_exit_status`: Boolean; enable exit status at end of processing? """ pub = Publisher(reader, parser, writer, settings=settings, source_class=io.StringInput, @@ -414,7 +416,7 @@ def publish_string(source, source_path=None, destination_path=None, settings._update(settings_overrides, 'loose') pub.set_source(source, source_path) pub.set_destination(destination_path=destination_path) - return pub.publish(enable_exit=enable_exit) + return pub.publish(enable_exit_status=enable_exit_status) def publish_parts(source, source_path=None, destination_path=None, reader=None, reader_name='standalone', @@ -422,7 +424,7 @@ def publish_parts(source, source_path=None, destination_path=None, writer=None, writer_name='pseudoxml', settings=None, settings_spec=None, settings_overrides=None, config_section=None, - enable_exit=None): + enable_exit_status=None): """ Set up & run a `Publisher`, and return a dictionary of document parts. Dictionary keys are the names of parts, and values are Unicode strings; @@ -460,7 +462,7 @@ def publish_parts(source, source_path=None, destination_path=None, of component settings. - `config_section`: Name of configuration file section for application. Used only if no `settings` or `settings_spec` specified. - - `enable_exit`: Boolean; enable exit status at end of processing? + - `enable_exit_status`: Boolean; enable exit status at end of processing? """ pub = Publisher(reader, parser, writer, settings=settings, source_class=io.StringInput, @@ -473,5 +475,5 @@ def publish_parts(source, source_path=None, destination_path=None, settings._update(settings_overrides, 'loose') pub.set_source(source, source_path) pub.set_destination(destination_path=destination_path) - pub.publish(enable_exit=enable_exit) + pub.publish(enable_exit_status=enable_exit_status) return pub.writer.parts -- cgit v1.2.1 From a9df7ccf4f6985faeee5f8f13b4f10a67381a761 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 3 Jun 2004 20:45:04 +0000 Subject: Renamed "--exit" to "--exit-status" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2209 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index b440954fb..ecf7db0de 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -324,9 +324,10 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): 'system messages (at or above ) were generated. Levels as ' 'in --report. Default is 5 (disabled). Exit status is the maximum ' 'system message level plus 10 (11 for INFO, etc.).', - ['--exit'], {'choices': threshold_choices, 'dest': 'exit_level', - 'default': 5, 'metavar': '', - 'validator': validate_threshold}), + ['--exit-status'], {'choices': threshold_choices, + 'dest': 'exit_status_level', + 'default': 5, 'metavar': '', + 'validator': validate_threshold}), ('Report debug-level system messages and generate diagnostic output.', ['--debug'], {'action': 'store_true', 'validator': validate_boolean}), ('Do not report debug-level system messages or generate diagnostic ' -- cgit v1.2.1 From 1a1a2081d9aa20f9ce80cbb3c85fe82c786266be Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 3 Jun 2004 21:17:16 +0000 Subject: Enabled traceback (exception propagation) by default in programmatic convenience functions. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2211 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index 9dd8f5760..4b060b6d0 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -183,7 +183,7 @@ class Publisher: output = self.writer.write(document, self.destination) self.writer.assemble_parts() except Exception, error: - if self.settings.traceback: + if self.settings.traceback: # propagate exceptions? raise self.report_Exception(error) exit = 1 @@ -350,6 +350,8 @@ def publish_file(source=None, source_path=None, if settings is None: settings = pub.get_settings(settings_spec=settings_spec, config_section=config_section) + # Set to propagate exceptions by default when used programmatically: + settings.traceback = 1 if settings_overrides: settings._update(settings_overrides, 'loose') pub.set_source(source, source_path) @@ -412,6 +414,8 @@ def publish_string(source, source_path=None, destination_path=None, if settings is None: settings = pub.get_settings(settings_spec=settings_spec, config_section=config_section) + # Set to propagate exceptions by default when used programmatically: + settings.traceback = 1 if settings_overrides: settings._update(settings_overrides, 'loose') pub.set_source(source, source_path) @@ -471,6 +475,8 @@ def publish_parts(source, source_path=None, destination_path=None, if settings is None: settings = pub.get_settings(settings_spec=settings_spec, config_section=config_section) + # Set to propagate exceptions by default when used programmatically: + settings.traceback = 1 if settings_overrides: settings._update(settings_overrides, 'loose') pub.set_source(source, source_path) -- cgit v1.2.1 From 6c18a0548558d3eefb532ef613a49533328dd357 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 5 Jun 2004 19:32:15 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2223 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 2 +- docutils/parsers/rst/directives/__init__.py | 2 +- docutils/writers/docutils_xml.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index c5ccbadf8..10c93eded 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -18,7 +18,7 @@ is represented by abstract base classes (`Root`, `Structural`, `Body`, ``isinstance(node, base_class)`` to determine the position of the node in the hierarchy. -.. _DTD: http://docutils.sourceforge.net/spec/docutils.dtd +.. _DTD: http://docutils.sourceforge.net/docs/ref/docutils.dtd """ __docformat__ = 'reStructuredText' diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index c2a1b5210..74ecc9984 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -74,7 +74,7 @@ empty list). See `Creating reStructuredText Directives`_ for more information. .. _Creating reStructuredText Directives: - http://docutils.sourceforge.net/spec/howto/rst-directives.html + http://docutils.sourceforge.net/docs/howto/rst-directives.html """ __docformat__ = 'reStructuredText' diff --git a/docutils/writers/docutils_xml.py b/docutils/writers/docutils_xml.py index cc730d873..1b1164977 100644 --- a/docutils/writers/docutils_xml.py +++ b/docutils/writers/docutils_xml.py @@ -50,7 +50,7 @@ class Writer(writers.Writer): doctype = ( '\n') + ' "http://docutils.sourceforge.net/docs/ref/docutils.dtd">\n') generator = '\n' def translate(self): -- cgit v1.2.1 From a3eedc4e04eea5aa5723ea42ebb293f87fc4c33c Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 5 Jun 2004 19:40:46 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2224 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/__init__.py | 2 +- docutils/languages/af.py | 2 +- docutils/languages/cs.py | 2 +- docutils/languages/de.py | 2 +- docutils/languages/en.py | 2 +- docutils/languages/eo.py | 2 +- docutils/languages/es.py | 2 +- docutils/languages/fr.py | 2 +- docutils/languages/it.py | 2 +- docutils/languages/pt_br.py | 2 +- docutils/languages/ru.py | 2 +- docutils/languages/sk.py | 2 +- docutils/languages/sv.py | 2 +- docutils/parsers/rst/languages/__init__.py | 2 +- 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/fr.py | 2 +- docutils/parsers/rst/languages/it.py | 5 +++++ docutils/parsers/rst/languages/pt_br.py | 2 +- docutils/parsers/rst/languages/ru.py | 2 +- docutils/parsers/rst/languages/sk.py | 2 +- docutils/parsers/rst/languages/sv.py | 2 +- 26 files changed, 30 insertions(+), 25 deletions(-) (limited to 'docutils') diff --git a/docutils/languages/__init__.py b/docutils/languages/__init__.py index a4d451156..018c880c4 100644 --- a/docutils/languages/__init__.py +++ b/docutils/languages/__init__.py @@ -5,7 +5,7 @@ # Copyright: This module has been placed in the public domain. # Internationalization details are documented in -# . +# . """ This package contains modules for language-dependent features of Docutils. diff --git a/docutils/languages/af.py b/docutils/languages/af.py index 6bfe4f162..1071b4469 100644 --- a/docutils/languages/af.py +++ b/docutils/languages/af.py @@ -5,7 +5,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/languages/cs.py b/docutils/languages/cs.py index 5e25800eb..94d4b70a1 100644 --- a/docutils/languages/cs.py +++ b/docutils/languages/cs.py @@ -5,7 +5,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/languages/de.py b/docutils/languages/de.py index ddffbda74..3a829dd34 100644 --- a/docutils/languages/de.py +++ b/docutils/languages/de.py @@ -5,7 +5,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/languages/en.py b/docutils/languages/en.py index db578810b..3b39c486f 100644 --- a/docutils/languages/en.py +++ b/docutils/languages/en.py @@ -5,7 +5,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/languages/eo.py b/docutils/languages/eo.py index af32aef52..32a1be4b1 100644 --- a/docutils/languages/eo.py +++ b/docutils/languages/eo.py @@ -5,7 +5,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/languages/es.py b/docutils/languages/es.py index 8a5111429..a1149b97e 100644 --- a/docutils/languages/es.py +++ b/docutils/languages/es.py @@ -6,7 +6,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/languages/fr.py b/docutils/languages/fr.py index 52317c174..33723befa 100644 --- a/docutils/languages/fr.py +++ b/docutils/languages/fr.py @@ -5,7 +5,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/languages/it.py b/docutils/languages/it.py index d86a5b1ec..08af6298a 100644 --- a/docutils/languages/it.py +++ b/docutils/languages/it.py @@ -5,7 +5,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/languages/pt_br.py b/docutils/languages/pt_br.py index d9b9f3ca5..78ce97025 100644 --- a/docutils/languages/pt_br.py +++ b/docutils/languages/pt_br.py @@ -6,7 +6,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/languages/ru.py b/docutils/languages/ru.py index e3b24a0c6..f1b7d1975 100644 --- a/docutils/languages/ru.py +++ b/docutils/languages/ru.py @@ -5,7 +5,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/languages/sk.py b/docutils/languages/sk.py index 20fa645ad..bb5cf089a 100644 --- a/docutils/languages/sk.py +++ b/docutils/languages/sk.py @@ -5,7 +5,7 @@ # :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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/languages/sv.py b/docutils/languages/sv.py index 3454ca6c1..275b3569a 100644 --- a/docutils/languages/sv.py +++ b/docutils/languages/sv.py @@ -5,7 +5,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/parsers/rst/languages/__init__.py b/docutils/parsers/rst/languages/__init__.py index ea4218657..be6feb644 100644 --- a/docutils/parsers/rst/languages/__init__.py +++ b/docutils/parsers/rst/languages/__init__.py @@ -5,7 +5,7 @@ # Copyright: This module has been placed in the public domain. # Internationalization details are documented in -# . +# . """ This package contains modules for language-dependent features of diff --git a/docutils/parsers/rst/languages/af.py b/docutils/parsers/rst/languages/af.py index ed750a586..3fc6c6a9a 100644 --- a/docutils/parsers/rst/languages/af.py +++ b/docutils/parsers/rst/languages/af.py @@ -5,7 +5,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/parsers/rst/languages/cs.py b/docutils/parsers/rst/languages/cs.py index 6e836c81b..7897b90a9 100644 --- a/docutils/parsers/rst/languages/cs.py +++ b/docutils/parsers/rst/languages/cs.py @@ -5,7 +5,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index 73ccd90d1..cc9465cb1 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -6,7 +6,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index 291404372..d6a70f564 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -5,7 +5,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/parsers/rst/languages/eo.py b/docutils/parsers/rst/languages/eo.py index 7101a082a..0abcc0390 100644 --- a/docutils/parsers/rst/languages/eo.py +++ b/docutils/parsers/rst/languages/eo.py @@ -5,7 +5,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index 08d73e183..1535b4a00 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -6,7 +6,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index 12ab694a0..3afdf942c 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -5,7 +5,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index cdfd0492c..db2c81d5f 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -4,6 +4,11 @@ # 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. + """ Italian-language mappings for language-dependent features of reStructuredText. diff --git a/docutils/parsers/rst/languages/pt_br.py b/docutils/parsers/rst/languages/pt_br.py index de06a74da..5424aa24c 100644 --- a/docutils/parsers/rst/languages/pt_br.py +++ b/docutils/parsers/rst/languages/pt_br.py @@ -6,7 +6,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/parsers/rst/languages/ru.py b/docutils/parsers/rst/languages/ru.py index 307c55a00..49420b3c3 100644 --- a/docutils/parsers/rst/languages/ru.py +++ b/docutils/parsers/rst/languages/ru.py @@ -5,7 +5,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/parsers/rst/languages/sk.py b/docutils/parsers/rst/languages/sk.py index 64af4ac1a..c4b8e635c 100644 --- a/docutils/parsers/rst/languages/sk.py +++ b/docutils/parsers/rst/languages/sk.py @@ -5,7 +5,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/parsers/rst/languages/sv.py b/docutils/parsers/rst/languages/sv.py index 9f6e8234c..a5579be25 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -5,7 +5,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. -- cgit v1.2.1 From ae82315c489d8015f1c902bfed4df47ddb3b35a3 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 5 Jun 2004 19:55:24 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2225 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index ecf7db0de..5899fa856 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -564,8 +564,8 @@ class ConfigParser(CP.ConfigParser): old_warning = """ The "[option]" section is deprecated. Support for old-format configuration files may be removed in a future Docutils release. Please revise your -configuration files. See , section -"Old-Format Configuration Files". +configuration files. See , +section "Old-Format Configuration Files". """ def read(self, filenames, option_parser): -- cgit v1.2.1 From dd8fab9aa5644ee3b5840721347b50fc13ec2e6b Mon Sep 17 00:00:00 2001 From: grubert Date: Mon, 7 Jun 2004 17:04:09 +0000 Subject: Add use-LaTeX-citations option. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2237 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 71 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 16 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 600fbefd3..1671448a3 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -47,6 +47,11 @@ class Writer(writers.Writer): ['--footnote-references'], {'choices': ['superscript', 'brackets'], 'default': 'brackets', 'metavar': ''}), + ('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'], @@ -520,6 +525,7 @@ class LaTeXTranslator(nodes.NodeVisitor): 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.section_prefix_for_enumerators = ( @@ -639,6 +645,8 @@ class LaTeXTranslator(nodes.NodeVisitor): # them into a compound enumeration self._enumeration_counters = [] + self._bibitems = [] + # docinfo. self.docinfo = None # inside literal block: no quote mangling. @@ -880,30 +888,46 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_caution(self, node): self.depart_admonition() - def visit_citation(self, node): - # TODO maybe use cite bibitems - self.body.append('\\begin{figure}[b]') - self.body.append('\\hypertarget{%s}' % node['id']) - - def depart_citation(self, node): - self.body.append('\\end{figure}\n') - 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]') + self.body.append('\\hypertarget{%s}' % node['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): - 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) + 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): - self.body.append('}]') + if self._use_latex_citations: + self.body.append('}') + else: + self.body.append('}]') def visit_classifier(self, node): self.body.append( '(\\textbf{' ) @@ -1047,6 +1071,16 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('\n\\setlength{\\locallinewidth}{\\linewidth}\n') def depart_document(self, node): + if self._use_latex_citations: + widest_label = "" + for bi in self._bibitems: + if len(widest_label) Date: Tue, 8 Jun 2004 07:23:36 +0000 Subject: Fix: dont insert bibliography if no bibitems were collected. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2239 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 1671448a3..1a4271496 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1071,7 +1071,8 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('\n\\setlength{\\locallinewidth}{\\linewidth}\n') def depart_document(self, node): - if self._use_latex_citations: + # 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) Date: Thu, 10 Jun 2004 13:30:31 +0000 Subject: News to T1. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2250 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 1a4271496..f8b0a23b7 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -555,6 +555,8 @@ class LaTeXTranslator(nodes.NodeVisitor): self.head_prefix = [ self.latex_head % (self.d_options,self.settings.documentclass), + # T1 should fix ~ in italian documents, but break "--" in ttfamily. + #'\\usepackage[T1]{fontenc}\n', '\\usepackage{babel}\n', # language is in documents settings. '\\usepackage{shortvrb}\n', # allows verb in footnotes. self.encoding % self.to_latex_encoding(settings.output_encoding), -- cgit v1.2.1 From 77bcf65467da3f71e40f8fd66a39bf5a268894b6 Mon Sep 17 00:00:00 2001 From: grubert Date: Sun, 13 Jun 2004 18:18:25 +0000 Subject: Remove "HACK" from comments. In literal and literal_block replace "--" by "-{}-", in case fontenc T1 is used. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2265 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index f8b0a23b7..131d292e4 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -754,10 +754,12 @@ class LaTeXTranslator(nodes.NodeVisitor): if self.literal_block or self.literal: # pdflatex does not produce doublequotes for ngerman. text = self.babel.double_quotes_in_tt(text) + # if fontenc == 'T1': make sure "--" does not become a "-". + text = text.replace("--","-{}-").replace("--","-{}-") else: text = self.babel.quote_quotes(text) if self.insert_newline or self.literal_block: - # HACK: insert a blank before the newline, to avoid + # 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: @@ -1435,7 +1437,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('\n\\end{flushleft}\n') def visit_list_item(self, node): - # HACK append "{}" in case the next character is "[", which would break + # Append "{}" in case the next character is "[", which would break # LaTeX's list environment (no numbering and the "[" is not printed). self.body.append('\\item {} ') -- cgit v1.2.1 From 0faaac9a361875c2a8c53ff8c3cc619d2b2284cb Mon Sep 17 00:00:00 2001 From: grubert Date: Sun, 13 Jun 2004 18:29:31 +0000 Subject: Replace underline in literal with underlined blank. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2266 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 131d292e4..f8459e7f7 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -742,7 +742,6 @@ class LaTeXTranslator(nodes.NodeVisitor): text = text.replace(">", '{\\textgreater}') # then text = text.replace("&", '{\\&}') - text = text.replace("_", '{\\_}') # the ^: # * verb|^| does not work in mbox. # * mathmode has wedge. hat{~} would also work. @@ -756,8 +755,11 @@ class LaTeXTranslator(nodes.NodeVisitor): text = self.babel.double_quotes_in_tt(text) # if fontenc == 'T1': make sure "--" does not become a "-". text = text.replace("--","-{}-").replace("--","-{}-") + # replace underline by underlined blank, because this has correct width. + text = text.replace("_", '{\\underline{ }}') else: text = self.babel.quote_quotes(text) + text = text.replace("_", '{\\_}') 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. -- cgit v1.2.1 From 98afa1038882feb752ce107d5f0a038598f245aa Mon Sep 17 00:00:00 2001 From: grubert Date: Mon, 14 Jun 2004 08:54:38 +0000 Subject: Comments to T1 encoding. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2270 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index f8459e7f7..db6fd9707 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -528,6 +528,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self._use_latex_citations = settings.use_latex_citations self.hyperlink_color = settings.hyperlink_color self.compound_enumerators = settings.compound_enumerators + self.fontenc = '' self.section_prefix_for_enumerators = ( settings.section_prefix_for_enumerators) self.section_enumerator_separator = ( @@ -552,12 +553,15 @@ class LaTeXTranslator(nodes.NodeVisitor): # object for a table while proccessing. self.active_table = Table('longtable',settings.table_style) + if self.fontenc == 'T1': + fontenc = '\\usepackage[T1]{fontenc}\n' + else: + fontenc = '' self.head_prefix = [ self.latex_head % (self.d_options,self.settings.documentclass), - # T1 should fix ~ in italian documents, but break "--" in ttfamily. - #'\\usepackage[T1]{fontenc}\n', '\\usepackage{babel}\n', # language is in documents settings. + fontenc, '\\usepackage{shortvrb}\n', # allows verb in footnotes. self.encoding % self.to_latex_encoding(settings.output_encoding), # * tabularx: for docinfo, automatic width of columns, always on one page. @@ -753,8 +757,12 @@ class LaTeXTranslator(nodes.NodeVisitor): if self.literal_block or self.literal: # pdflatex does not produce doublequotes for ngerman. text = self.babel.double_quotes_in_tt(text) - # if fontenc == 'T1': make sure "--" does not become a "-". - text = text.replace("--","-{}-").replace("--","-{}-") + if self.fontenc == 'T1': + # make sure "--" does not become a "-". + # the same for "<<" and ">>". + text = text.replace("--","-{}-").replace("--","-{}-") + text = text.replace(">>",">{}>").replace(">>",">{}>") + text = text.replace("<<","<{}<").replace("<<","<{}<") # replace underline by underlined blank, because this has correct width. text = text.replace("_", '{\\underline{ }}') else: -- cgit v1.2.1 From d50c0171dec967510512cda9aceaf1ff723c4920 Mon Sep 17 00:00:00 2001 From: grubert Date: Wed, 16 Jun 2004 07:37:55 +0000 Subject: Fix pdfbookmark text needs escaping for #. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2284 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index db6fd9707..38d13fd4c 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1810,7 +1810,7 @@ class LaTeXTranslator(nodes.NodeVisitor): if l>0: l = l-1 # pdftex does not like "_" subscripts in titles - text = node.astext().replace("_","\\_") + text = self.encode(node.astext()) self.body.append('\\pdfbookmark[%d]{%s}{%s}\n' % \ (l,text,node.parent['id'])) -- cgit v1.2.1 From 64dc5dafabac98fc4ef0dbcbaf054f8b0c741f7a Mon Sep 17 00:00:00 2001 From: david_abrahams Date: Wed, 16 Jun 2004 16:12:11 +0000 Subject: Fixed paragraph glomming around footnotes git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2286 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 38d13fd4c..b74f32240 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1297,7 +1297,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_footnote(self, node): if self.use_latex_footnotes: - self.body.append('}') + self.body.append('}\n') else: self.body.append('\\end{figure}\n') -- cgit v1.2.1 From c48260665ecf74131830f99949da7b99b7579348 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 16 Jun 2004 17:21:57 +0000 Subject: added pep_base_url & rfc_base_url settings & support git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2287 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 9 +++++++++ docutils/parsers/rst/__init__.py | 13 +++++++++++-- docutils/parsers/rst/roles.py | 4 ++-- docutils/parsers/rst/states.py | 10 ++++------ docutils/readers/pep.py | 11 +---------- 5 files changed, 27 insertions(+), 20 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 5899fa856..1be10e396 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -143,6 +143,15 @@ def validate_colon_separated_string_list( value.extend(last.split(':')) return value +def validate_url_trailing_slash( + setting, value, option_parser, config_parser=None, config_section=None): + if not value: + return './' + elif value.endswith('/'): + return value + else: + return value + '/' + def make_paths_absolute(pathdict, keys, base_path=None): """ Interpret filesystem path settings relative to the `base_path` given. diff --git a/docutils/parsers/rst/__init__.py b/docutils/parsers/rst/__init__.py index 679539fb9..33ad99829 100644 --- a/docutils/parsers/rst/__init__.py +++ b/docutils/parsers/rst/__init__.py @@ -88,12 +88,21 @@ class Parser(docutils.parsers.Parser): settings_spec = ( 'reStructuredText Parser Options', None, - (('Recognize and link to PEP references (like "PEP 258").', + (('Recognize and link to standalone PEP references (like "PEP 258").', ['--pep-references'], {'action': 'store_true', 'validator': frontend.validate_boolean}), - ('Recognize and link to RFC references (like "RFC 822").', + ('Base URL for PEP references ' + '(default "http://www.python.org/peps/").', + ['--pep-base-url'], + {'metavar': '', 'default': 'http://www.python.org/peps/', + 'validator': frontend.validate_url_trailing_slash}), + ('Recognize and link to standalone RFC references (like "RFC 822").', ['--rfc-references'], {'action': 'store_true', 'validator': frontend.validate_boolean}), + ('Base URL for RFC references (default "http://www.faqs.org/rfcs/").', + ['--rfc-base-url'], + {'metavar': '', 'default': 'http://www.faqs.org/rfcs/', + 'validator': frontend.validate_url_trailing_slash}), ('Set number of spaces for tab expansion (default 8).', ['--tab-width'], {'metavar': '', 'type': 'int', 'default': 8}), diff --git a/docutils/parsers/rst/roles.py b/docutils/parsers/rst/roles.py index 2af000d6c..aff19f30c 100644 --- a/docutils/parsers/rst/roles.py +++ b/docutils/parsers/rst/roles.py @@ -263,7 +263,7 @@ def pep_reference_role(role, rawtext, text, lineno, inliner, prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] # Base URL mainly used by inliner.pep_reference; so this is correct: - ref = inliner.pep_url % pepnum + ref = inliner.document.settings.pep_base_url + inliner.pep_url % pepnum return [nodes.reference(rawtext, 'PEP ' + text, refuri=ref, **options)], [] register_canonical_role('pep-reference', pep_reference_role) @@ -281,7 +281,7 @@ def rfc_reference_role(role, rawtext, text, lineno, inliner, 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 + ref = inliner.document.settings.rfc_base_url + inliner.rfc_url % rfcnum node = nodes.reference(rawtext, 'RFC ' + text, refuri=ref, **options) return [node], [] diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 219b8a790..4025c7e72 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -954,9 +954,7 @@ class Inliner: else: # not a valid scheme raise MarkupMismatch - pep_url_local = 'pep-%04d.html' - pep_url_absolute = 'http://www.python.org/peps/pep-%04d.html' - pep_url = pep_url_absolute + pep_url = 'pep-%04d.html' def pep_reference(self, match, lineno): text = match.group(0) @@ -966,17 +964,17 @@ class Inliner: pepnum = int(match.group('pepnum2')) else: raise MarkupMismatch - ref = self.pep_url % pepnum + ref = self.document.settings.pep_base_url + self.pep_url % pepnum unescaped = unescape(text, 0) return [nodes.reference(unescape(text, 1), unescaped, refuri=ref)] - rfc_url = 'http://www.faqs.org/rfcs/rfc%d.html' + rfc_url = 'rfc%d.html' def rfc_reference(self, match, lineno): text = match.group(0) if text.startswith('RFC'): rfcnum = int(match.group('rfcnum')) - ref = self.rfc_url % rfcnum + ref = self.document.settings.rfc_base_url + self.rfc_url % rfcnum else: raise MarkupMismatch unescaped = unescape(text, 0) diff --git a/docutils/readers/pep.py b/docutils/readers/pep.py index f65fd2662..b615ba4db 100644 --- a/docutils/readers/pep.py +++ b/docutils/readers/pep.py @@ -16,15 +16,6 @@ from docutils.transforms import peps, references from docutils.parsers import rst -class Inliner(rst.states.Inliner): - - """ - Extend `rst.Inliner` for local PEP references. - """ - - pep_url = rst.states.Inliner.pep_url_local - - class Reader(standalone.Reader): supported = ('pep',) @@ -52,7 +43,7 @@ class Reader(standalone.Reader): settings_default_overrides = {'pep_references': 1, 'rfc_references': 1} - inliner_class = Inliner + inliner_class = rst.states.Inliner def __init__(self, parser=None, parser_name=None): """`parser` should be ``None``.""" -- cgit v1.2.1 From d44851200e1a95811d32d00b9ff8e57e92d7fd26 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 16 Jun 2004 17:43:55 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2289 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/peps.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index fdd750d0c..16260367a 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -118,7 +118,9 @@ class Headers(Transform): for refpep in re.split(',?\s+', body.astext()): pepno = int(refpep) newbody.append(nodes.reference( - refpep, refpep, refuri=self.pep_url % pepno)) + refpep, refpep, + refuri=(self.document.settings.pep_base_url + + self.pep_url % pepno))) newbody.append(space) para[:] = newbody[:-1] # drop trailing space elif name == 'last-modified': @@ -128,7 +130,7 @@ class Headers(Transform): para[:] = [nodes.reference('', date, refuri=cvs_url)] elif name == 'content-type': pep_type = para.astext() - uri = self.pep_url % 12 + uri = self.document.settings.pep_base_url + self.pep_url % 12 para[:] = [nodes.reference('', pep_type, refuri=uri)] elif name == 'version' and len(body): utils.clean_rcs_keywords(para, self.rcs_keyword_substitutions) @@ -266,7 +268,8 @@ class PEPZeroSpecial(nodes.SparseNodeVisitor): text = p.astext() try: pep = int(text) - ref = self.pep_url % pep + ref = (self.document.settings.pep_base_url + + self.pep_url % pep) p[0] = nodes.reference(text, text, refuri=ref) except ValueError: pass -- cgit v1.2.1 From dea94526d6cba0d4538178fc7a8377697997dbe6 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 17 Jun 2004 02:08:48 +0000 Subject: docstrings git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2290 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 8 ++++++-- docutils/utils.py | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 74ecc9984..4eacafe9e 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -63,6 +63,10 @@ directive function): options to parse. Several directive option conversion functions are defined in this module. + Option conversion functions take a single parameter, the option argument (a + string or ``None``), validate it and/or convert it to the appropriate form. + Conversion functions may raise ``ValueError`` and ``TypeError`` exceptions. + - ``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). @@ -193,12 +197,12 @@ def directive(directive_name, language_module, document): return None, messages return function, messages -def register_directive(name, directive): +def register_directive(name, directive_function): """ Register a nonstandard application-defined directive function. Language lookups are not needed for such functions. """ - _directives[name] = directive + _directives[name] = directive_function def flag(argument): """ diff --git a/docutils/utils.py b/docutils/utils.py index 70da14c7e..e43c0dfaa 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -321,6 +321,8 @@ def assemble_option_dict(option_list, options_spec): - `DuplicateOptionError` for duplicate options. - `ValueError` for invalid option values (raised by conversion function). + - `TypeError` for invalid option value types (raised by conversion + function). """ options = {} for name, value in option_list: -- cgit v1.2.1 From a26033a9a9d2b2355ae1d3052663c73ee74b9b10 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 17 Jun 2004 02:51:31 +0000 Subject: docstrings git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2291 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docutils') diff --git a/docutils/utils.py b/docutils/utils.py index e43c0dfaa..d14f6342a 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -265,6 +265,8 @@ def extract_extension_options(field_list, options_spec): - `KeyError` for unknown option names. - `ValueError` for invalid option values (raised by the conversion function). + - `TypeError` for invalid option value types (raised by conversion + function). - `DuplicateOptionError` for duplicate options. - `BadOptionError` for invalid fields. - `BadOptionDataError` for invalid option data (missing name, -- cgit v1.2.1 From 461ca3f5083d8f4a86755b583797616460e34011 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 17 Jun 2004 02:52:54 +0000 Subject: extracted unicode code conversion git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2292 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 25 +++++++++++++++++++++++++ docutils/parsers/rst/directives/misc.py | 20 +++++--------------- 2 files changed, 30 insertions(+), 15 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 4eacafe9e..6f88e3638 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -83,6 +83,7 @@ See `Creating reStructuredText Directives`_ for more information. __docformat__ = 'reStructuredText' +import re from docutils import nodes from docutils.parsers.rst.languages import en as _fallback_language_module @@ -282,6 +283,30 @@ def class_option(argument): raise ValueError('cannot make "%s" into a class name' % argument) return class_name +unicode_pattern = re.compile( + r'(?:0x|x|\\x|U\+?|\\u)([0-9a-f]+)$|&#x([0-9a-f]+);$', re.IGNORECASE) + +def unicode_code(code): + r""" + Convert a Unicode character code to a Unicode character. + + Codes may be decimal numbers, hexadecimal numbers (prefixed by ``0x``, + ``x``, ``\x``, ``U+``, ``u``, or ``\u``; e.g. ``U+262E``), or XML-style + numeric character entities (e.g. ``☮``). Other text remains as-is. + """ + try: + if code.isdigit(): # decimal number + return unichr(int(code)) + else: + match = unicode_pattern.match(code) + if match: # hex number + value = match.group(1) or match.group(2) + return unichr(int(value, 16)) + else: # other text + return code + except OverflowError, detail: + raise ValueError('code too large (%s)' % detail) + def format_values(values): return '%s, or "%s"' % (', '.join(['"%s"' % s for s in values[:-1]]), values[-1]) diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index d2f65c990..a91719f6d 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -117,7 +117,7 @@ def raw(name, arguments, options, content, lineno, nodes.literal_block(block_text, block_text), line=lineno) return [severe] text = raw_file.read() - raw_file.close() + raw_file.close() attributes['source'] = options['file'] else: error = state_machine.reporter.warning( @@ -185,29 +185,19 @@ def unicode_directive(name, arguments, options, content, lineno, element = nodes.Element() for code in codes: try: - if code.isdigit(): - element += nodes.Text(unichr(int(code))) - else: - match = unicode_pattern.match(code) - if match: - value = match.group(1) or match.group(2) - element += nodes.Text(unichr(int(value, 16))) - else: - element += nodes.Text(code) - except (ValueError, OverflowError), err: + decoded = directives.unicode_code(code) + except ValueError, err: error = state_machine.reporter.error( 'Invalid character code: %s\n%s: %s' % (code, err.__class__.__name__, err), nodes.literal_block(block_text, block_text), line=lineno) return [error] + element += nodes.Text(decoded) return element.children unicode_directive.arguments = (1, 0, 1) -unicode_pattern = re.compile( - r'(?:0x|x|\\x|U\+?|\\u)([0-9a-f]+)$|&#x([0-9a-f]+);$', re.IGNORECASE) unicode_comment_pattern = re.compile(r'( |\n|^).. ') - def class_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """""" @@ -259,7 +249,7 @@ def role(name, arguments, options, content, lineno, return messages + [error] else: base_role = roles.generic_custom_role - assert not hasattr(base_role, 'arguments'), ( + assert not hasattr(base_role, 'arguments'), ( 'Supplemental directive arguments for "%s" directive not supported' '(specified by "%r" role).' % (name, base_role)) try: -- cgit v1.2.1 From 8db114eefd634b71c9176376b336fec9743f8324 Mon Sep 17 00:00:00 2001 From: grubert Date: Thu, 17 Jun 2004 08:31:50 +0000 Subject: A few unicode replacements. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2295 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index b74f32240..311fed732 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -784,8 +784,14 @@ class LaTeXTranslator(nodes.NodeVisitor): text = text.replace('[', '{[}') if self.insert_none_breaking_blanks: text = text.replace(' ', '~') - # unicode !!! - text = text.replace(u'\u2020', '{$\\dagger$}') + if self.settings.output_encoding != 'utf-8': + # see LaTeX codec http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252124 + text = text.replace(u'\u00A0', '~') + text = text.replace(u'\u00A9', '{\\copyright}') + text = text.replace(u'\u2013', '{--}') + text = text.replace(u'\u2014', '{---}') + text = text.replace(u'\u2020', '{\\dag}') + text = text.replace(u'\u2021', '{\\ddag}') return text def attval(self, text, -- cgit v1.2.1 From 16bbd9314c3d45a98742ce519ddd160516334c5a Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 17 Jun 2004 16:08:46 +0000 Subject: fixed omission git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2296 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/body.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index 6c29d037e..4fc015b21 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -136,6 +136,7 @@ def table(name, arguments, options, content, lineno, title = nodes.title(title_text, '', *text_nodes) else: title = None + messages = [] node = nodes.Element() # anonymous container for parsing text = '\n'.join(content) state.nested_parse(content, content_offset, node) @@ -151,7 +152,7 @@ def table(name, arguments, options, content, lineno, table_node.set_class(options['class']) if title: table_node.insert(0, title) - return [table_node] + return [table_node] + messages table.arguments = (0, 1, 1) table.options = {'class': directives.class_option} -- cgit v1.2.1 From eb06322ee79b43a063be327aa475db57d4089e2c Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 17 Jun 2004 21:46:50 +0000 Subject: support for CSV directive implementation git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2299 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/statemachine.py | 4 ++++ docutils/utils.py | 3 +++ 2 files changed, 7 insertions(+) (limited to 'docutils') diff --git a/docutils/statemachine.py b/docutils/statemachine.py index c6849d7d5..dfd49a777 100644 --- a/docutils/statemachine.py +++ b/docutils/statemachine.py @@ -344,6 +344,10 @@ class StateMachine: finally: self.notify_observers() + def get_source(self, line_offset): + """Return source of line at absolute line offset `line_offset`.""" + return self.input_lines.source(line_offset - self.input_offset) + def abs_line_offset(self): """Return line offset of current line, from beginning of file.""" return self.line_offset + self.input_offset diff --git a/docutils/utils.py b/docutils/utils.py index d14f6342a..4639e0e71 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -25,6 +25,9 @@ class SystemMessage(ApplicationError): self.level = level +class SystemMessagePropagation(ApplicationError): pass + + class Reporter: """ -- cgit v1.2.1 From c059e577bf3d4e3a261faee5d824f76a06a942a2 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 18 Jun 2004 21:35:35 +0000 Subject: moved "table" directive to tables.py git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2305 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/body.py | 38 +-------------------------------- 1 file changed, 1 insertion(+), 37 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index 4fc015b21..c63ac8aef 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -1,5 +1,5 @@ # Author: David Goodger -# Contact: goodger@users.sourceforge.net +# Contact: goodger@python.org # Revision: $Revision$ # Date: $Date$ # Copyright: This module has been placed in the public domain. @@ -121,39 +121,3 @@ def pull_quote(name, arguments, options, content, lineno, return [block_quote] + messages pull_quote.content = 1 - -def table(name, arguments, options, content, lineno, - content_offset, block_text, state, state_machine): - if not content: - warning = state_machine.reporter.warning( - 'Content block expected for the "%s" directive; none found.' - % name, nodes.literal_block(block_text, block_text), - line=lineno) - return [warning] - if arguments: - title_text = arguments[0] - text_nodes, messages = state.inline_text(title_text, lineno) - title = nodes.title(title_text, '', *text_nodes) - else: - title = None - messages = [] - node = nodes.Element() # anonymous container for parsing - text = '\n'.join(content) - state.nested_parse(content, content_offset, node) - if len(node) != 1 or not isinstance(node[0], nodes.table): - error = state_machine.reporter.error( - 'Error parsing content block for the "%s" directive: ' - 'exactly one table expected.' - % name, nodes.literal_block(block_text, block_text), - line=lineno) - return [error] - table_node = node[0] - if options.has_key('class'): - table_node.set_class(options['class']) - if title: - table_node.insert(0, title) - return [table_node] + messages - -table.arguments = (0, 1, 1) -table.options = {'class': directives.class_option} -table.content = 1 -- cgit v1.2.1 From 55d9840df5e7f33f12257081f425ef57f1374042 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 18 Jun 2004 21:36:30 +0000 Subject: added several directive option conversion functions git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2307 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 35 +++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 6f88e3638..6ef7c752f 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -1,5 +1,5 @@ # Author: David Goodger -# Contact: goodger@users.sourceforge.net +# Contact: goodger@python.org # Revision: $Revision$ # Date: $Date$ # Copyright: This module has been placed in the public domain. @@ -107,8 +107,9 @@ _directive_registry = { 'epigraph': ('body', 'epigraph'), 'highlights': ('body', 'highlights'), 'pull-quote': ('body', 'pull_quote'), - 'table': ('body', 'table'), #'questions': ('body', 'question_list'), + 'table': ('tables', 'table'), + 'csv-table': ('tables', 'csv_table'), 'image': ('images', 'image'), 'figure': ('images', 'figure'), 'contents': ('parts', 'contents'), @@ -307,6 +308,36 @@ def unicode_code(code): except OverflowError, detail: raise ValueError('code too large (%s)' % detail) + +def single_char_or_unicode(argument): + char = unicode_code(argument) + if len(char) > 1: + raise ValueError('%r invalid; must be a single character or ' + 'a Unicode code' % char) + return char + +def single_char_or_whitespace_or_unicode(argument): + if argument == 'tab': + char = '\t' + elif argument == 'space': + char = ' ' + else: + char = single_char_or_unicode(argument) + return char + +def positive_int(argument): + value = int(argument) + if value < 1: + raise ValueError('negative or zero value; must be positive') + return value + +def positive_int_list(argument): + if ',' in argument: + entries = argument.split(',') + else: + entries = argument.split() + return [positive_int(entry) for entry in entries] + def format_values(values): return '%s, or "%s"' % (', '.join(['"%s"' % s for s in values[:-1]]), values[-1]) -- cgit v1.2.1 From d2efa0442ee4ca7ecc5b6e68d209434eae946f74 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 18 Jun 2004 21:36:55 +0000 Subject: added "csv-table" directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2308 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/af.py | 3 ++- docutils/parsers/rst/languages/cs.py | 3 ++- docutils/parsers/rst/languages/de.py | 3 ++- docutils/parsers/rst/languages/en.py | 3 ++- docutils/parsers/rst/languages/eo.py | 3 ++- docutils/parsers/rst/languages/es.py | 3 ++- docutils/parsers/rst/languages/fr.py | 3 ++- docutils/parsers/rst/languages/it.py | 3 ++- docutils/parsers/rst/languages/pt_br.py | 3 ++- docutils/parsers/rst/languages/ru.py | 1 + docutils/parsers/rst/languages/sk.py | 3 ++- docutils/parsers/rst/languages/sv.py | 3 ++- 12 files changed, 23 insertions(+), 11 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/af.py b/docutils/parsers/rst/languages/af.py index 3fc6c6a9a..1c799127f 100644 --- a/docutils/parsers/rst/languages/af.py +++ b/docutils/parsers/rst/languages/af.py @@ -36,10 +36,11 @@ directives = { 'epigraaf': 'epigraph', 'hoogtepunte': 'highlights', 'pull-quote (translation required)': 'pull-quote', - 'table (translation required)': 'table', #'vrae': 'questions', #'qa': 'questions', #'faq': 'questions', + 'table (translation required)': 'table', + 'csv-table (translation required)': 'csv-table', 'meta': 'meta', #'beeldkaart': 'imagemap', 'beeld': 'image', diff --git a/docutils/parsers/rst/languages/cs.py b/docutils/parsers/rst/languages/cs.py index 7897b90a9..111a476eb 100644 --- a/docutils/parsers/rst/languages/cs.py +++ b/docutils/parsers/rst/languages/cs.py @@ -37,10 +37,11 @@ directives = { u'moto': 'epigraph', u'highlights': 'highlights', u'pull-quote': 'pull-quote', - u'table (translation required)': 'table', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', + u'table (translation required)': 'table', + u'csv-table (translation required)': 'csv-table', u'meta': 'meta', #'imagemap': 'imagemap', u'image': 'image', # obrazek diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index cc9465cb1..90eb77bdb 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -37,10 +37,11 @@ directives = { 'epigraph (translation required)': 'epigraph', 'highlights (translation required)': 'highlights', 'pull-quote (translation required)': 'pull-quote', # kasten too ? - 'table (translation required)': 'table', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', + 'table (translation required)': 'table', + 'csv-table (translation required)': 'csv-table', 'meta': 'meta', #'imagemap': 'imagemap', 'bild': 'image', diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index d6a70f564..f45e104f9 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -37,8 +37,9 @@ directives = { 'epigraph': 'epigraph', 'highlights': 'highlights', 'pull-quote': 'pull-quote', - 'table': 'table', #'questions': 'questions', + 'table': 'table', + 'csv-table': 'csv-table', #'qa': 'questions', #'faq': 'questions', 'meta': 'meta', diff --git a/docutils/parsers/rst/languages/eo.py b/docutils/parsers/rst/languages/eo.py index 0abcc0390..2e4f515e9 100644 --- a/docutils/parsers/rst/languages/eo.py +++ b/docutils/parsers/rst/languages/eo.py @@ -40,10 +40,11 @@ directives = { u'elstara\u0135oj': 'highlights', u'ekstera-citajxo': 'pull-quote', u'ekstera-cita\u0135o': 'pull-quote', - u'tabelo': 'table', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', + u'tabelo': 'table', + u'csv-tabelo (translation required)': 'csv-table', u'meta': 'meta', #'imagemap': 'imagemap', u'bildo': 'image', diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index 1535b4a00..537800961 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -42,10 +42,11 @@ directives = { u'epigrafe': 'epigraph', u'destacado': 'highlights', u'cita-destacada': 'pull-quote', - u'tabla': 'table', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', + u'tabla': 'table', + u'csv-table (translation required)': 'csv-table', u'meta': 'meta', #'imagemap': 'imagemap', u'imagen': 'image', diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index 3afdf942c..a104ae111 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -38,10 +38,11 @@ directives = { u'\u00E9pigraphe': 'epigraph', u'chapeau': 'highlights', u'accroche': 'pull-quote', - u'tableau': 'table', #u'questions': 'questions', #u'qr': 'questions', #u'faq': 'questions', + u'tableau': 'table', + u'csv-table (translation required)': 'csv-table', u'm\u00E9ta': 'meta', #u'imagemap (translation required)': 'imagemap', u'image': 'image', diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index db2c81d5f..1f80e3bc8 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -36,10 +36,11 @@ directives = { 'epigrafe': 'epigraph', 'evidenzia': 'highlights', 'pull-quote (translation required)': 'pull-quote', - 'tabella': 'table', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', + 'tabella': 'table', + 'csv-table (translation required)': 'csv-table', 'meta': 'meta', #'imagemap': 'imagemap', 'immagine': 'image', diff --git a/docutils/parsers/rst/languages/pt_br.py b/docutils/parsers/rst/languages/pt_br.py index 5424aa24c..4834e8f25 100644 --- a/docutils/parsers/rst/languages/pt_br.py +++ b/docutils/parsers/rst/languages/pt_br.py @@ -38,10 +38,11 @@ directives = { u'epgrafo': 'epigraph', 'destaques': 'highlights', u'citao-destacada': 'pull-quote', - u'table (translation required)': 'table', #'perguntas': 'questions', #'qa': 'questions', #'faq': 'questions', + u'table (translation required)': 'table', + u'csv-table (translation required)': 'csv-table', 'meta': 'meta', #'imagemap': 'imagemap', 'imagem': 'image', diff --git a/docutils/parsers/rst/languages/ru.py b/docutils/parsers/rst/languages/ru.py index 49420b3c3..ce0dc2b76 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'table (translation required)': 'table', + u'csv-table (translation required)': 'csv-table', u'\u0441\u044b\u0440\u043e\u0439': u'raw', u'\u0437\u0430\u043c\u0435\u043d\u0430': u'replace', u'\u0442\u0435\u0441\u0442\u043e\u0432\u0430\u044f-\u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u0430-restructuredtext': diff --git a/docutils/parsers/rst/languages/sk.py b/docutils/parsers/rst/languages/sk.py index c4b8e635c..1a508a851 100644 --- a/docutils/parsers/rst/languages/sk.py +++ b/docutils/parsers/rst/languages/sk.py @@ -36,10 +36,11 @@ directives = { u'epigraph (translation required)': 'epigraph', u'highlights (translation required)': 'highlights', u'pull-quote (translation required)': 'pull-quote', - u'table (translation required)': 'table', #u'questions': 'questions', #u'qa': 'questions', #u'faq': 'questions', + u'table (translation required)': 'table', + u'csv-table (translation required)': 'csv-table', u'meta': 'meta', #u'imagemap': 'imagemap', u'obr\xe1zok': 'image', diff --git a/docutils/parsers/rst/languages/sv.py b/docutils/parsers/rst/languages/sv.py index a5579be25..f4f8ee6a7 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -35,11 +35,12 @@ directives = { u'epigraph (translation required)': 'epigraph', u'highlights (translation required)': 'highlights', u'pull-quote (translation required)': 'pull-quote', - u'table (translation required)': 'table', # u'fr\u00e5gor': 'questions', # NOTE: A bit long, but recommended by http://www.nada.kth.se/dataterm/: # u'fr\u00e5gor-och-svar': 'questions', # u'vanliga-fr\u00e5gor': 'questions', + u'table (translation required)': 'table', + u'csv-table (translation required)': 'csv-table', u'meta': 'meta', # u'bildkarta': 'imagemap', # FIXME: Translation might be too literal. u'bild': 'image', -- cgit v1.2.1 From b514245823ade13164c47f8cdc769d5a358611c7 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 18 Jun 2004 21:41:31 +0000 Subject: table-related directives git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2309 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 269 ++++++++++++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 docutils/parsers/rst/directives/tables.py (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py new file mode 100644 index 000000000..90c392117 --- /dev/null +++ b/docutils/parsers/rst/directives/tables.py @@ -0,0 +1,269 @@ +# Authors: David Goodger, David Priest +# Contact: goodger@python.org +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Directives for table elements. +""" + +__docformat__ = 'reStructuredText' + + +import sys +import os.path +import csv +from docutils import nodes, statemachine, utils +from docutils.utils import SystemMessagePropagation +from docutils.parsers.rst import directives + +try: + import urllib2 +except ImportError: + urllib2 = None + +try: + True +except NameError: # Python 2.2 & 2.1 compatibility + True = not 0 + False = not 1 + + +def table(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + if not content: + warning = state_machine.reporter.warning( + 'Content block expected for the "%s" directive; none found.' + % name, nodes.literal_block(block_text, block_text), + line=lineno) + return [warning] + title, messages = make_title(arguments, state, lineno) + node = nodes.Element() # anonymous container for parsing + text = '\n'.join(content) + state.nested_parse(content, content_offset, node) + if len(node) != 1 or not isinstance(node[0], nodes.table): + error = state_machine.reporter.error( + 'Error parsing content block for the "%s" directive: ' + 'exactly one table expected.' + % name, nodes.literal_block(block_text, block_text), + line=lineno) + return [error] + table_node = node[0] + if options.has_key('class'): + table_node.set_class(options['class']) + if title: + table_node.insert(0, title) + return [table_node] + messages + +table.arguments = (0, 1, 1) +table.options = {'class': directives.class_option} +table.content = 1 + +def make_title(arguments, state, lineno): + if arguments: + title_text = arguments[0] + text_nodes, messages = state.inline_text(title_text, lineno) + title = nodes.title(title_text, '', *text_nodes) + else: + title = None + messages = [] + return title, messages + + +class DocutilsDialect(csv.Dialect): + + """CSV dialect for `csv_table` directive function.""" + + delimiter = ',' + quotechar = '"' + doublequote = True + skipinitialspace = True + lineterminator = '\n' + quoting = csv.QUOTE_MINIMAL + + def __init__(self, options): + if options.has_key('delim'): + self.delimiter = str(options['delim']) + if options.has_key('keepspace'): + self.skipinitialspace = False + if options.has_key('quote'): + self.quotechar = str(options['quote']) + if options.has_key('escape'): + self.doublequote = False + self.escapechar = str(options['escape']) + csv.Dialect.__init__(self) + + +class HeaderDialect(csv.Dialect): + + """CSV dialect to use for the "header" option data.""" + + delimiter = ',' + quotechar = '"' + escapechar = '\\' + doublequote = False + skipinitialspace = True + lineterminator = '\n' + quoting = csv.QUOTE_MINIMAL + + +def csv_table(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + + title, messages = make_title(arguments, state, lineno) + try: + csv_data, source = get_csv_data( + name, options, content, lineno, block_text, state, state_machine) + table_head, max_header_cols = process_header_option( + options, state_machine, lineno) + rows, max_cols = parse_csv_data_into_rows( + csv_data, DocutilsDialect(options), source, options) + max_cols = max(max_cols, max_header_cols) + header_rows = options.get('header-rows', 0) # default 0 + table_head.extend(rows[:header_rows]) + table_body = rows[header_rows:] + if not table_body: + error = state_machine.reporter.error( + '"%s" directive requires table body content.' % name, + nodes.literal_block(block_text, block_text), line=lineno) + return [error] + col_widths = get_column_widths( + max_cols, name, options, lineno, block_text, state_machine) + extend_short_rows_with_empty_cells(max_cols, (table_head, table_body)) + except SystemMessagePropagation, detail: + return [detail.args[0]] + except csv.Error, detail: + error = state_machine.reporter.error( + 'Error with CSV data in "%s" directive:\n%s' % (name, detail), + nodes.literal_block(block_text, block_text), line=lineno) + return [error] + table = (col_widths, table_head, table_body) + table_node = state.build_table(table, content_offset) + if options.has_key('class'): + table_node.set_class(options['class']) + if title: + table_node.insert(0, title) + return [table_node] + messages + +csv_table.arguments = (0, 1, 1) +csv_table.options = {'header-rows': directives.nonnegative_int, + 'header': directives.unchanged, + 'widths': directives.positive_int_list, + 'file': directives.path, + 'url': directives.path, + 'class': directives.class_option, + # field delimiter char + 'delim': directives.single_char_or_whitespace_or_unicode, + # treat whitespace after delimiter as significant + 'keepspace': directives.flag, + # text field quote/unquote char: + 'quote': directives.single_char_or_unicode, + # char used to escape delim & quote as-needed: + 'escape': directives.single_char_or_unicode,} +csv_table.content = 1 + +def get_csv_data(name, options, content, lineno, block_text, + state, state_machine): + """ + CSV data can come from the directive content, from an external file, or + from a URL reference. + """ + if content: # CSV data is from directive 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) + raise SystemMessagePropagation(error) + source = content.source(0) + csv_data = content + elif options.has_key('file'): # CSV data is from an external 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) + raise SystemMessagePropagation(error) + source_dir = os.path.dirname( + os.path.abspath(state.document.current_source)) + source = os.path.normpath(os.path.join(source_dir, options['file'])) + source = utils.relative_path(None, source) + try: + csv_file = open(source, 'rb') + try: + csv_data = csv_file.read().splitlines() + finally: + csv_file.close() + 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) + raise SystemMessagePropagation(severe) + elif options.has_key('url'): # CSV data is from a URL + if not urllib2: + severe = state_machine.reporter.severe( + 'Problems with the "%s" directive and its "url" option: ' + 'unable to access the required functionality (from the ' + '"urllib2" module).' % name, + nodes.literal_block(block_text, block_text), line=lineno) + raise SystemMessagePropagation(severe) + source = options['url'] + try: + csv_data = urllib2.urlopen(source).read().splitlines() + except (urllib2.URLError, IOError, OSError, ValueError), 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) + raise SystemMessagePropagation(severe) + else: + error = state_machine.reporter.warning( + 'The "%s" directive requires content; none supplied.' % (name), + nodes.literal_block(block_text, block_text), line=lineno) + raise SystemMessagePropagation(error) + return csv_data, source + +def process_header_option(options, state_machine, lineno): + source = state_machine.get_source(lineno - 1) + table_head = [] + max_header_cols = 0 + if options.has_key('header'): # separate table header in option + rows, max_header_cols = parse_csv_data_into_rows( + options['header'].split('\n'), HeaderDialect(), source, options) + table_head.extend(rows) + return table_head, max_header_cols + +def parse_csv_data_into_rows(csv_data, dialect, source, options): + csv_reader = csv.reader(csv_data, dialect=dialect) + rows = [] + max_cols = 0 + for row in csv_reader: + row_data = [] + for cell in row: + cell_data = (0, 0, 0, statemachine.StringList(cell.splitlines(), + source=source)) + row_data.append(cell_data) + rows.append(row_data) + max_cols = max(max_cols, len(row)) + return rows, max_cols + +def get_column_widths(max_cols, name, options, lineno, block_text, + state_machine): + if options.has_key('widths'): + col_widths = options['widths'] + if len(col_widths) != max_cols: + error = state_machine.reporter.error( + '"%s" widths do not match the number of columns in table (%s).' + % (name, max_cols), + nodes.literal_block(block_text, block_text), line=lineno) + raise SystemMessagePropagation(error) + else: + col_widths = [100 / max_cols] * max_cols + return col_widths + +def extend_short_rows_with_empty_cells(columns, parts): + for part in parts: + for row in part: + if len(row) < columns: + row.extend([(0, 0, 0, [])] * (columns - len(row))) -- cgit v1.2.1 From 536251810af32e0d1554cce5a674a88351aac9c8 Mon Sep 17 00:00:00 2001 From: grubert Date: Fri, 18 Jun 2004 22:56:36 +0000 Subject: Move unicode to LaTeX into a method. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2311 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 311fed732..54b2ee966 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -710,6 +710,23 @@ class LaTeXTranslator(nodes.NodeVisitor): def language_label(self, docutil_label): return self.language.labels[docutil_label] + def utf8_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. + latex_equivalents = { + u'\u00A0' : '~', + u'\u00A9' : '{\\copyright}', + u'\u2013' : '{--}', + u'\u2014' : '{---}', + u'\u2020' : '{\\dag}', + u'\u2021' : '{\\ddag}', + u'\u21d4' : '{$\\Leftrightarrow$}', + } + for uchar in latex_equivalents.keys(): + text = text.replace(uchar,latex_equivalents[uchar]) + return text + def encode(self, text): """ Encode special characters in `text` & return. @@ -785,13 +802,7 @@ class LaTeXTranslator(nodes.NodeVisitor): if self.insert_none_breaking_blanks: text = text.replace(' ', '~') if self.settings.output_encoding != 'utf-8': - # see LaTeX codec http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252124 - text = text.replace(u'\u00A0', '~') - text = text.replace(u'\u00A9', '{\\copyright}') - text = text.replace(u'\u2013', '{--}') - text = text.replace(u'\u2014', '{---}') - text = text.replace(u'\u2020', '{\\dag}') - text = text.replace(u'\u2021', '{\\ddag}') + text = self.utf8_to_latex(text) return text def attval(self, text, -- cgit v1.2.1 From 9afb2c5adc84beeabf5ec16e55200249a0dc1717 Mon Sep 17 00:00:00 2001 From: richieadler Date: Sat, 19 Jun 2004 01:44:07 +0000 Subject: Translation of new "csv-table" directive. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2312 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/eo.py | 3 ++- docutils/parsers/rst/languages/es.py | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/eo.py b/docutils/parsers/rst/languages/eo.py index 2e4f515e9..9f269decb 100644 --- a/docutils/parsers/rst/languages/eo.py +++ b/docutils/parsers/rst/languages/eo.py @@ -44,7 +44,8 @@ directives = { #'qa': 'questions', #'faq': 'questions', u'tabelo': 'table', - u'csv-tabelo (translation required)': 'csv-table', + u'tabelo-vdk': 'csv-table', # "valoroj disigitaj per komoj" + u'tabelo-csv': 'csv-table', u'meta': 'meta', #'imagemap': 'imagemap', u'bildo': 'image', diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index 537800961..ce5a92a28 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -1,6 +1,6 @@ # -*- coding: iso-8859-1 -*- # Author: Marcelo Huerta San Martn -# Contact: mghsm@uol.com.ar +# Contact: richieadler@users.sourceforge.net # Revision: $Revision$ # Date: $Date$ # Copyright: This module has been placed in the public domain. @@ -46,7 +46,8 @@ directives = { #'qa': 'questions', #'faq': 'questions', u'tabla': 'table', - u'csv-table (translation required)': 'csv-table', + u'tabla-vsc': 'csv-table', + u'tabla-csv': 'csv-table', u'meta': 'meta', #'imagemap': 'imagemap', u'imagen': 'image', -- cgit v1.2.1 From f2b64c0ff06f8682e71bc5bd12098b2f4a5d53b8 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 19 Jun 2004 22:53:32 +0000 Subject: added checks for cvs.py module (Python 2.3+), and table dimensions; added guarding for Python 2.1/2.2 (no CSV support) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2314 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 98 +++++++++++++++++++------------ 1 file changed, 62 insertions(+), 36 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 90c392117..e34e54b20 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -13,11 +13,15 @@ __docformat__ = 'reStructuredText' import sys import os.path -import csv from docutils import nodes, statemachine, utils from docutils.utils import SystemMessagePropagation from docutils.parsers.rst import directives +try: + import csv # new in Python 2.3 +except ImportError: + csv = None + try: import urllib2 except ImportError: @@ -71,48 +75,49 @@ def make_title(arguments, state, lineno): return title, messages -class DocutilsDialect(csv.Dialect): +if csv: + class DocutilsDialect(csv.Dialect): - """CSV dialect for `csv_table` directive function.""" + """CSV dialect for `csv_table` directive function.""" - delimiter = ',' - quotechar = '"' - doublequote = True - skipinitialspace = True - lineterminator = '\n' - quoting = csv.QUOTE_MINIMAL + delimiter = ',' + quotechar = '"' + doublequote = True + skipinitialspace = True + lineterminator = '\n' + quoting = csv.QUOTE_MINIMAL - def __init__(self, options): - if options.has_key('delim'): - self.delimiter = str(options['delim']) - if options.has_key('keepspace'): - self.skipinitialspace = False - if options.has_key('quote'): - self.quotechar = str(options['quote']) - if options.has_key('escape'): - self.doublequote = False - self.escapechar = str(options['escape']) - csv.Dialect.__init__(self) + def __init__(self, options): + if options.has_key('delim'): + self.delimiter = str(options['delim']) + if options.has_key('keepspace'): + self.skipinitialspace = False + if options.has_key('quote'): + self.quotechar = str(options['quote']) + if options.has_key('escape'): + self.doublequote = False + self.escapechar = str(options['escape']) + csv.Dialect.__init__(self) -class HeaderDialect(csv.Dialect): + class HeaderDialect(csv.Dialect): - """CSV dialect to use for the "header" option data.""" + """CSV dialect to use for the "header" option data.""" - delimiter = ',' - quotechar = '"' - escapechar = '\\' - doublequote = False - skipinitialspace = True - lineterminator = '\n' - quoting = csv.QUOTE_MINIMAL + delimiter = ',' + quotechar = '"' + escapechar = '\\' + doublequote = False + skipinitialspace = True + lineterminator = '\n' + quoting = csv.QUOTE_MINIMAL def csv_table(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): - - title, messages = make_title(arguments, state, lineno) try: + check_requirements(name, lineno, block_text, state_machine) + title, messages = make_title(arguments, state, lineno) csv_data, source = get_csv_data( name, options, content, lineno, block_text, state, state_machine) table_head, max_header_cols = process_header_option( @@ -121,13 +126,10 @@ def csv_table(name, arguments, options, content, lineno, csv_data, DocutilsDialect(options), source, options) max_cols = max(max_cols, max_header_cols) header_rows = options.get('header-rows', 0) # default 0 + check_table_dimensions( + rows, header_rows, name, lineno, block_text, state_machine) table_head.extend(rows[:header_rows]) table_body = rows[header_rows:] - if not table_body: - error = state_machine.reporter.error( - '"%s" directive requires table body content.' % name, - nodes.literal_block(block_text, block_text), line=lineno) - return [error] col_widths = get_column_widths( max_cols, name, options, lineno, block_text, state_machine) extend_short_rows_with_empty_cells(max_cols, (table_head, table_body)) @@ -163,6 +165,15 @@ csv_table.options = {'header-rows': directives.nonnegative_int, 'escape': directives.single_char_or_unicode,} csv_table.content = 1 +def check_requirements(name, lineno, block_text, state_machine): + if not csv: + error = state_machine.reporter.error( + 'The "%s" directive is not compatible with this version of ' + 'Python (%s). Requires the "csv" module, new in Python 2.3.' + % (name, sys.version.split()[0]), + nodes.literal_block(block_text, block_text), line=lineno) + raise SystemMessagePropagation(error) + def get_csv_data(name, options, content, lineno, block_text, state, state_machine): """ @@ -248,6 +259,21 @@ def parse_csv_data_into_rows(csv_data, dialect, source, options): max_cols = max(max_cols, len(row)) return rows, max_cols +def check_table_dimensions(rows, header_rows, name, lineno, block_text, + state_machine): + if len(rows) < header_rows: + error = state_machine.reporter.error( + '%s header row(s) specified but only %s row(s) of data supplied ' + '("%s" directive).' % (header_rows, len(rows), name), + nodes.literal_block(block_text, block_text), line=lineno) + raise SystemMessagePropagation(error) + elif len(rows) == header_rows > 0: + error = state_machine.reporter.error( + 'Insufficient data supplied (%s row(s)); no data remaining for ' + 'table body, required by "%s" directive.' % (len(rows), name), + nodes.literal_block(block_text, block_text), line=lineno) + raise SystemMessagePropagation(error) + def get_column_widths(max_cols, name, options, lineno, block_text, state_machine): if options.has_key('widths'): -- cgit v1.2.1 From 5b0a08da505813b51e174ad9034dee98b480816a Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 20 Jun 2004 12:28:08 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2321 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 5 ++++- docutils/writers/__init__.py | 10 ++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index 953418716..09119cef5 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -121,6 +121,7 @@ class Output(TransformSpec): % (self.__class__, self.destination, self.destination_path)) def write(self, data): + """`data` is a Unicode string, to be encoded by `self.encode`.""" raise NotImplementedError def encode(self, data): @@ -172,7 +173,9 @@ class FileInput(Input): pass def read(self): - """Read and decode a single file and return the data.""" + """ + Read and decode a single file and return the data (Unicode string). + """ data = self.source.read() if self.autoclose: self.close() diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index 044884581..d36cd1795 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -36,13 +36,15 @@ class Writer(Component): """The document to write (Docutils doctree); set by `write`.""" output = None - """Final translated form of `document`; set by `translate`.""" + """Final translated form of `document` (Unicode string); + set by `translate`.""" language = None """Language module for the document; set by `write`.""" destination = None - """`docutils.io` IO object; where to write the document. Set by `write`.""" + """`docutils.io` Output object; where to write the document. + Set by `write`.""" def __init__(self): @@ -73,8 +75,8 @@ class Writer(Component): def translate(self): """ - Do final translation of `self.document` into `self.output`. - Called from `write`. Override in subclasses. + Do final translation of `self.document` into `self.output` (Unicode + string). 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 3baae021442aeda1655134389c8573f9c4ed350f Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 20 Jun 2004 16:03:17 +0000 Subject: make warning_stream work git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2322 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/utils.py b/docutils/utils.py index 4639e0e71..87bcac9ba 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -55,7 +55,7 @@ class Reporter: 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. + stream if not set to ''. The default category is '' (empty string). By convention, Writers should retrieve reporting conditions from the 'writer' category (which, unless @@ -92,7 +92,8 @@ class Reporter: exceptions will be raised, halting execution. - `debug`: Show debug (level=0) system messages? - `stream`: Where warning output is sent. Can be file-like (has a - ``.write`` method), a string (file name, opened for writing), or + ``.write`` method), a string (file name, opened for writing), + '' (empty string, for discarding all stream messages) or `None` (implies `sys.stderr`; default). - `encoding`: The encoding for stderr output. - `error_handler`: The error handler for stderr output encoding. @@ -103,7 +104,12 @@ class Reporter: if stream is None: stream = sys.stderr elif type(stream) in (StringType, UnicodeType): - raise NotImplementedError('This should open a file for writing.') + # Leave stream untouched if it's ''. + if stream != '': + if type(stream) == StringType: + stream = open(stream, 'w') + elif type(stream) == UnicodeType: + stream = open(stream.encode(), 'w') self.encoding = encoding """The character encoding for the stderr output.""" @@ -178,7 +184,7 @@ class Reporter: type=self.levels[level], *children, **attributes) debug, report_level, halt_level, stream = self[category].astuple() - if level >= report_level or debug and level == 0: + if (level >= report_level or debug and level == 0) and stream: msgtext = msg.astext().encode(self.encoding, self.error_handler) if category: print >>stream, msgtext, '[%s]' % category -- cgit v1.2.1 From dfa3a35a0946731e59954fbfdd0ee72bf3abd25d Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 20 Jun 2004 20:46:21 +0000 Subject: encoding fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2332 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/pt_br.py | 27 +++++++------- docutils/parsers/rst/languages/pt_br.py | 63 ++++++++++++++++----------------- 2 files changed, 44 insertions(+), 46 deletions(-) (limited to 'docutils') diff --git a/docutils/languages/pt_br.py b/docutils/languages/pt_br.py index 78ce97025..ccd6d734b 100644 --- a/docutils/languages/pt_br.py +++ b/docutils/languages/pt_br.py @@ -1,4 +1,3 @@ -# -*- coding: iso-8859-1 -*- # Author: David Goodger # Contact: goodger@users.sourceforge.net # Revision: $Revision$ @@ -20,41 +19,41 @@ labels = { # fixed: language-dependent 'author': u'Autor', 'authors': u'Autores', - 'organization': unicode('Organizao', 'latin1'), - 'address': unicode('Endereo', 'latin1'), + 'organization': u'Organiza\u00E7\u00E3o', + 'address': u'Endere\u00E7o', 'contact': u'Contato', - 'version': unicode('Verso', 'latin1'), - 'revision': unicode('Reviso', 'latin1'), + 'version': u'Vers\u00E3o', + 'revision': u'Revis\u00E3o', 'status': u'Estado', 'date': u'Data', 'copyright': u'Copyright', - 'dedication': unicode('Dedicatria', 'latin1'), + 'dedication': u'Dedicat\u00F3ria', 'abstract': u'Resumo', - 'attention': unicode('Atteno!', 'latin1'), + 'attention': u'Atten\u00E7\u00E3o!', 'caution': u'Cuidado!', 'danger': u'PERIGO!', 'error': u'Erro', - 'hint': unicode('Sugesto', 'latin1'), + 'hint': u'Sugest\u00E3o', 'important': u'Importante', 'note': u'Nota', 'tip': u'Dica', 'warning': u'Aviso', - 'contents': unicode('Sumrio', 'latin1')} + 'contents': u'Sum\u00E1rio'} """Mapping of node class name to label text.""" bibliographic_fields = { # language-dependent: fixed u'autor': 'author', u'autores': 'authors', - unicode('organizao', 'latin1'): 'organization', - unicode('endereo', 'latin1'): 'address', + u'organiza\u00E7\u00E3o': 'organization', + u'endere\u00E7o': 'address', u'contato': 'contact', - unicode('verso', 'latin1'): 'version', - unicode('reviso', 'latin1'): 'revision', + u'vers\u00E3o': 'version', + u'revis\u00E3o': 'revision', u'estado': 'status', u'data': 'date', u'copyright': 'copyright', - unicode('dedicatria', 'latin1'): 'dedication', + u'dedicat\u00F3ria': 'dedication', u'resumo': 'abstract'} """English (lowcased) to canonical name mapping for bibliographic fields.""" diff --git a/docutils/parsers/rst/languages/pt_br.py b/docutils/parsers/rst/languages/pt_br.py index 4834e8f25..36005f344 100644 --- a/docutils/parsers/rst/languages/pt_br.py +++ b/docutils/parsers/rst/languages/pt_br.py @@ -1,4 +1,3 @@ -# -*- coding: iso-8859-1 -*- # Author: David Goodger # Contact: goodger@users.sourceforge.net # Revision: $Revision$ @@ -20,24 +19,24 @@ __docformat__ = 'reStructuredText' directives = { # language-dependent: fixed - u'ateno': 'attention', + u'aten\u00E7\u00E3o': 'attention', 'cuidado': 'caution', 'perigo': 'danger', 'erro': 'error', - u'sugesto': 'hint', + u'sugest\u00E3o': 'hint', 'importante': 'important', 'nota': 'note', 'dica': 'tip', 'aviso': 'warning', - u'exortao': 'admonition', + u'exorta\u00E7\u00E3o': 'admonition', 'barra-lateral': 'sidebar', - u'tpico': 'topic', + u't\u00F3pico': 'topic', 'bloco-de-linhas': 'line-block', 'literal-interpretado': 'parsed-literal', 'rubrica': 'rubric', - u'epgrafo': 'epigraph', + u'ep\u00EDgrafo': 'epigraph', 'destaques': 'highlights', - u'citao-destacada': 'pull-quote', + u'cita\u00E7\u00E3o-destacada': 'pull-quote', #'perguntas': 'questions', #'qa': 'questions', #'faq': 'questions', @@ -47,52 +46,52 @@ directives = { #'imagemap': 'imagemap', 'imagem': 'image', 'figura': 'figure', - u'incluso': 'include', + u'inclus\u00E3o': 'include', 'cru': 'raw', - u'substituio': 'replace', + u'substitui\u00E7\u00E3o': 'replace', 'unicode': 'unicode', 'classe': 'class', 'role (translation required)': 'role', - u'ndice': 'contents', + u'\u00EDndice': 'contents', 'numsec': 'sectnum', - u'numerao-de-sees': 'sectnum', - #u'notas-de-rorap': 'footnotes', - #u'citaes': 'citations', - u'links-no-rodap': 'target-notes', + u'numera\u00E7\u00E3o-de-se\u00E7\u00F5es': 'sectnum', + #u'notas-de-rorap\u00E9': 'footnotes', + #u'cita\u00E7\u00F5es': 'citations', + u'links-no-rodap\u00E9': 'target-notes', 'restructuredtext-test-directive': 'restructuredtext-test-directive'} -"""English name to registered (in directives/__init__.py) directive name -mapping.""" +"""Brazilian Portuguese name to registered (in directives/__init__.py) +directive name mapping.""" roles = { # language-dependent: fixed - u'abbreviao': 'abbreviation', + u'abbrevia\u00E7\u00E3o': 'abbreviation', 'ab': 'abbreviation', - u'acrnimo': 'acronym', + u'acr\u00F4nimo': 'acronym', 'ac': 'acronym', - u'ndice-remissivo': 'index', + u'\u00EDndice-remissivo': 'index', 'i': 'index', 'subscrito': 'subscript', 'sub': 'subscript', 'sobrescrito': 'superscript', 'sob': 'superscript', - u'referncia-a-ttulo': 'title-reference', - u'ttulo': 'title-reference', + u'refer\u00EAncia-a-t\u00EDtulo': 'title-reference', + u't\u00EDtulo': 'title-reference', 't': 'title-reference', - u'referncia-a-pep': 'pep-reference', + u'refer\u00EAncia-a-pep': 'pep-reference', 'pep': 'pep-reference', - u'referncia-a-rfc': 'rfc-reference', + u'refer\u00EAncia-a-rfc': 'rfc-reference', 'rfc': 'rfc-reference', - u'nfase': 'emphasis', + u'\u00EAnfase': 'emphasis', 'forte': 'strong', 'literal': 'literal', - u'referncia-por-nome': 'named-reference', - u'referncia-annima': 'anonymous-reference', - u'referncia-a-nota-de-rodap': 'footnote-reference', - u'referncia-a-citao': 'citation-reference', - u'referncia-a-substituio': 'substitution-reference', + u'refer\u00EAncia-por-nome': 'named-reference', + u'refer\u00EAncia-an\u00F4nima': 'anonymous-reference', + u'refer\u00EAncia-a-nota-de-rodap\u00E9': 'footnote-reference', + u'refer\u00EAncia-a-cita\u00E7\u00E3o': 'citation-reference', + u'refer\u00EAncia-a-substitui\u00E7\u00E3o': 'substitution-reference', 'alvo': 'target', - u'referncia-a-uri': 'uri-reference', + u'refer\u00EAncia-a-uri': 'uri-reference', 'uri': 'uri-reference', 'url': 'uri-reference',} -"""Mapping of English role names to canonical role names for interpreted text. -""" +"""Mapping of Brazilian Portuguese role names to canonical role names +for interpreted text.""" -- cgit v1.2.1 From f37924d3e8c8c8fa0281984a181a350df6f40261 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 20 Jun 2004 20:51:22 +0000 Subject: doc fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2333 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/pt_br.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/languages/pt_br.py b/docutils/languages/pt_br.py index ccd6d734b..5d2df0e82 100644 --- a/docutils/languages/pt_br.py +++ b/docutils/languages/pt_br.py @@ -55,7 +55,7 @@ bibliographic_fields = { u'copyright': 'copyright', u'dedicat\u00F3ria': 'dedication', u'resumo': 'abstract'} -"""English (lowcased) to canonical name mapping for bibliographic fields.""" +"""Brazilian Portuguese (lowcased) to canonical name mapping for bibliographic fields.""" author_separators = [';', ','] """List of separator strings for the 'Authors' bibliographic field. Tried in -- cgit v1.2.1 From 9d0496b115ec1e25eecd5a3d34fba4857d9f53bd Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 20 Jun 2004 21:31:56 +0000 Subject: fixed line number for literal blocks git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2334 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 4025c7e72..a786abbda 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -2540,9 +2540,10 @@ class Text(RSTState): indented.trim_end() if not indented: return self.quoted_literal_block() - nodelist = [] data = '\n'.join(indented) - nodelist.append(nodes.literal_block(data, data)) + literal_block = nodes.literal_block(data, data) + literal_block.line = offset + 1 + nodelist = [literal_block] if not blank_finish: nodelist.append(self.unindent_warning('Literal block')) return nodelist -- cgit v1.2.1 From 65e2e0206fa2d221870703a563471330d47d5b9d Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 20 Jun 2004 22:13:00 +0000 Subject: fixed "target" option for figure git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2336 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/images.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index ab96a0a4e..67cf6b4a6 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -40,18 +40,22 @@ def image(name, arguments, options, content, lineno, block = [line for line in block] target_type, data = state.parse_target(block, block_text, lineno) if target_type == 'refuri': - node_list = nodes.reference(refuri=data) + reference = nodes.reference(refuri=data) elif target_type == 'refname': - node_list = nodes.reference( + reference = nodes.reference( refname=data, name=whitespace_normalize_name(options['target'])) - state.document.note_refname(node_list) + state.document.note_refname(reference) else: # malformed target - node_list = [data] # data is a system message + reference = [data] # data is a system message del options['target'] else: - node_list = [] - node_list.append(nodes.image(block_text, **options)) - return node_list + reference = None + image_node = nodes.image(block_text, **options) + if reference: + reference += image_node + return [reference] + else: + return [image_node] image.arguments = (1, 0, 1) image.options = {'alt': directives.unchanged, -- cgit v1.2.1 From a3e0ea03f95fb7a40cca1defdc77b8a27964a0ca Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 21 Jun 2004 11:09:21 +0000 Subject: margins; KOMA-script support; ifthen git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2337 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 54b2ee966..1443f859c 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -34,9 +34,9 @@ class Writer(writers.Writer): ['--documentclass'], {'default': 'article', }), ('Specify document options. Multiple options can be given, ' - 'separated by commas. Default is "10pt".', + 'separated by commas. Default is "10pt,a4paper".', ['--documentoptions'], - {'default': '10pt', }), + {'default': '10pt,a4paper', }), ('Use LaTeX footnotes. LaTeX supports only numbered footnotes (does it?). ' 'Default: no, uses figures.', ['--use-latex-footnotes'], @@ -297,10 +297,15 @@ class DocumentClass: # 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' @@ -486,13 +491,9 @@ class LaTeXTranslator(nodes.NodeVisitor): # to other packages, as done with babel. # Dummy settings might be taken from document settings - d_paper = 'a4paper' # papersize - d_margins = '2cm' - latex_head = '\\documentclass[%s]{%s}\n' encoding = '\\usepackage[%s]{inputenc}\n' linking = '\\usepackage[colorlinks=%s,linkcolor=%s,urlcolor=%s]{hyperref}\n' - geometry = '\\usepackage[%s,margin=%s,nohead]{geometry}\n' stylesheet = '\\input{%s}\n' # add a generated on day , machine by user using docutils version. generator = '%% generator Docutils: http://docutils.sourceforge.net/\n' @@ -551,6 +552,15 @@ class LaTeXTranslator(nodes.NodeVisitor): self.d_class = DocumentClass(settings.documentclass) + # 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 = '' + # object for a table while proccessing. self.active_table = Table('longtable',settings.table_style) if self.fontenc == 'T1': @@ -579,10 +589,9 @@ class LaTeXTranslator(nodes.NodeVisitor): '\\usepackage{graphicx}\n', '\\usepackage{color}\n', '\\usepackage{multirow}\n', + '\\usepackage{ifthen}\n', # before hyperref! self.linking % (self.colorlinks, self.hyperlink_color, self.hyperlink_color), - # geometry and fonts might go into style.tex. - self.geometry % (self.d_paper, self.d_margins), - # + self.typearea, self.generator, # latex lengths '\\newlength{\\admonitionwidth}\n', @@ -1096,6 +1105,8 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_document(self, node): self.body_prefix.append('\\begin{document}\n') + # BUG: \maketitle without title (i.e. --no-doc-title) adds + # unnecessary vspace. self.body_prefix.append('\\maketitle\n\n') # alternative use titlepage environment. # \begin{titlepage} -- cgit v1.2.1 From e107070ca2dd791cde875463616d249d03eb8ada Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 21 Jun 2004 12:40:33 +0000 Subject: fixed bug introduced in last change git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2341 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/images.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index 67cf6b4a6..ddbdb96c6 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -28,6 +28,7 @@ def align(argument): def image(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): + messages = [] reference = ''.join(arguments[0].split('\n')) if reference.find(' ') != -1: error = state_machine.reporter.error( @@ -35,27 +36,26 @@ def image(name, arguments, options, content, lineno, nodes.literal_block(block_text, block_text), line=lineno) return [error] options['uri'] = reference + reference_node = None if options.has_key('target'): block = states.escape2null(options['target']).splitlines() block = [line for line in block] target_type, data = state.parse_target(block, block_text, lineno) if target_type == 'refuri': - reference = nodes.reference(refuri=data) + reference_node = nodes.reference(refuri=data) elif target_type == 'refname': - reference = nodes.reference( + reference_node = nodes.reference( refname=data, name=whitespace_normalize_name(options['target'])) - state.document.note_refname(reference) + state.document.note_refname(reference_node) else: # malformed target - reference = [data] # data is a system message + messages.append(data) # data is a system message del options['target'] - else: - reference = None image_node = nodes.image(block_text, **options) - if reference: - reference += image_node - return [reference] + if reference_node: + reference_node += image_node + return messages + [reference_node] else: - return [image_node] + return messages + [image_node] image.arguments = (1, 0, 1) image.options = {'alt': directives.unchanged, -- cgit v1.2.1 From a3b2fb13667da88606472ce64878b324b260dc23 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 21 Jun 2004 16:45:12 +0000 Subject: Py2.1 compatibility fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2344 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 1443f859c..df41e1d08 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1396,12 +1396,12 @@ class LaTeXTranslator(nodes.NodeVisitor): pre = [] # in reverse order post = ['\\includegraphics{%s}' % attrs['uri']] inline = isinstance(node.parent, nodes.TextElement) - if 'scale' in attrs: + 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 'align' in attrs: + if attrs.has_key('align'): align_prepost = { # By default latex aligns the top of an image. (1, 'top'): ('', ''), -- cgit v1.2.1 From 3023b038d9134115290f021ad0f65f1caee6e292 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 21 Jun 2004 22:21:25 +0000 Subject: return encoded string results from publish_* convenience functions git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2347 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index 4b060b6d0..f3ceed38c 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -274,7 +274,8 @@ def publish_cmdline(reader=None, reader_name='standalone', enable_exit_status=1, argv=None, usage=default_usage, description=default_description): """ - Set up & run a `Publisher`. For command-line front ends. + Set up & run a `Publisher` (and return the encoded string output). + For command-line front ends. Parameters: @@ -303,9 +304,10 @@ def publish_cmdline(reader=None, reader_name='standalone', """ pub = Publisher(reader, parser, writer, settings=settings) pub.set_components(reader_name, parser_name, writer_name) - pub.publish(argv, usage, description, settings_spec, settings_overrides, - config_section=config_section, - enable_exit_status=enable_exit_status) + output = pub.publish( + argv, usage, description, settings_spec, settings_overrides, + config_section=config_section, enable_exit_status=enable_exit_status) + return output def publish_file(source=None, source_path=None, destination=None, destination_path=None, @@ -315,7 +317,8 @@ def publish_file(source=None, source_path=None, settings=None, settings_spec=None, settings_overrides=None, config_section=None, enable_exit_status=None): """ - Set up & run a `Publisher`. For programmatic use with file-like I/O. + Set up & run a `Publisher` (and return the encoded string output). + For programmatic use with file-like I/O. Parameters: @@ -356,7 +359,8 @@ def publish_file(source=None, source_path=None, settings._update(settings_overrides, 'loose') pub.set_source(source, source_path) pub.set_destination(destination, destination_path) - pub.publish(enable_exit_status=enable_exit_status) + output = pub.publish(enable_exit_status=enable_exit_status) + return output def publish_string(source, source_path=None, destination_path=None, reader=None, reader_name='standalone', @@ -366,7 +370,7 @@ def publish_string(source, source_path=None, destination_path=None, settings_overrides=None, config_section=None, enable_exit_status=None): """ - Set up & run a `Publisher`, and return the string output. + Set up & run a `Publisher`, and return the encoded string output. For programmatic use with string I/O. For encoded string output, be sure to set the "output_encoding" setting to -- cgit v1.2.1 From e9392a97370514aa39851a14552563be3b5c8584 Mon Sep 17 00:00:00 2001 From: david_abrahams Date: Wed, 23 Jun 2004 02:17:11 +0000 Subject: Fix the line numbering of nodes produced by line_block directives. This is a total shot-in-the-dark, since it's unclear why lineno is 97 and content_offset is the right line number. Without some description of the protocol I can't really know, but it seems to be working... for now. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2361 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/body.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index c63ac8aef..bfe2e695f 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -15,7 +15,25 @@ import sys from docutils import nodes from docutils.parsers.rst import directives - +# Directive Handler Functions +# +# What they do is blah blah +# +# They are called by blah blah after being looked up blah blah +# +# Parameter Required Type Role +# ============== ============= ============================= +# name str ??? +# arguments ??? ??? +# options ??? ??? +# content ??? ??? +# lineno ??? ??? +# content_offset ??? ??? +# block_text ??? ??? +# state ??? ??? +# state_machine ??? ??? +# node_class ??? ??? + def topic(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine, node_class=nodes.topic): @@ -74,6 +92,7 @@ def line_block(name, arguments, options, content, lineno, text = '\n'.join(content) text_nodes, messages = state.inline_text(text, lineno) node = node_class(text, '', *text_nodes, **options) + node.line = content_offset return [node] + messages line_block.options = {'class': directives.class_option} -- cgit v1.2.1 From 5d0175645ac362a19bba5f479f8a24543e760cc1 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 23 Jun 2004 02:25:34 +0000 Subject: typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2362 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 10c93eded..aed0c2c28 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1123,8 +1123,8 @@ class pending(Special, Invisible, PreBibliographic, Element): 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:: + code leaves a placeholder behind that will trigger the second phase of its + processing, something like this:: + internal attributes -- cgit v1.2.1 From 5522058d7b68c055e68752ff4a5f3ff2138238af Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 23 Jun 2004 02:29:02 +0000 Subject: line number == (line offset + 1); check module docstring of directives/__init__.py for detailed instructions git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2363 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/body.py | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index bfe2e695f..9e93b3aff 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -15,24 +15,6 @@ import sys from docutils import nodes from docutils.parsers.rst import directives -# Directive Handler Functions -# -# What they do is blah blah -# -# They are called by blah blah after being looked up blah blah -# -# Parameter Required Type Role -# ============== ============= ============================= -# name str ??? -# arguments ??? ??? -# options ??? ??? -# content ??? ??? -# lineno ??? ??? -# content_offset ??? ??? -# block_text ??? ??? -# state ??? ??? -# state_machine ??? ??? -# node_class ??? ??? def topic(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine, @@ -92,7 +74,7 @@ def line_block(name, arguments, options, content, lineno, text = '\n'.join(content) text_nodes, messages = state.inline_text(text, lineno) node = node_class(text, '', *text_nodes, **options) - node.line = content_offset + node.line = content_offset + 1 return [node] + messages line_block.options = {'class': directives.class_option} -- cgit v1.2.1 From ea6bc82584ed1a16423aadc5d88af6baca1cda47 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 23 Jun 2004 02:35:59 +0000 Subject: docstrings git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2364 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/body.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index 9e93b3aff..85adda981 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -6,6 +6,8 @@ """ Directives for additional body elements. + +See `docutils.parsers.rst.directives` for API details. """ __docformat__ = 'reStructuredText' -- cgit v1.2.1 From 6809090a4197bff7bde6f08243383783e24fd43c Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 23 Jun 2004 03:44:06 +0000 Subject: docstrings git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2365 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 6ef7c752f..f10d42cec 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -20,11 +20,12 @@ The interface for directive functions is as follows:: Parameters: -- ``name`` is the directive type or name. +- ``name`` is the directive type or name (string). -- ``arguments`` is a list of positional arguments. +- ``arguments`` is a list of positional arguments (strings). -- ``options`` is a dictionary mapping option names to values. +- ``options`` is a dictionary mapping option names (strings) to values (type + depends on option conversion functions; see below). - ``content`` is a list of strings, the directive content. -- cgit v1.2.1 From ae7e43fcfd1be7b0415509b4d7329616f180a1f4 Mon Sep 17 00:00:00 2001 From: david_abrahams Date: Wed, 23 Jun 2004 11:51:50 +0000 Subject: Because Englebert said, "why not?" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2367 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index df41e1d08..8cf6650ef 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -586,7 +586,13 @@ class LaTeXTranslator(nodes.NodeVisitor): # extra space between text in tables and the line above them '\\setlength{\\extrarowheight}{2pt}\n', '\\usepackage{amsmath}\n', # what fore amsmath. - '\\usepackage{graphicx}\n', + r'''%Check if we are compiling under latex or pdflatex + \ifx\pdftexversion\undefined + \usepackage[dvips]{graphicx} + \else + \usepackage[pdftex]{graphicx} + \fi + ''', '\\usepackage{color}\n', '\\usepackage{multirow}\n', '\\usepackage{ifthen}\n', # before hyperref! -- cgit v1.2.1 From 973428782b288d7ff451f72faeb95d1854cc9477 Mon Sep 17 00:00:00 2001 From: grubert Date: Fri, 25 Jun 2004 19:09:25 +0000 Subject: Add option: graphicx-option. Default to no option. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2377 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 8cf6650ef..1f50472c9 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -120,11 +120,17 @@ class Writer(writers.Writer): ('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"', + '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': ''}), + ),) settings_defaults = {'output_encoding': 'latin-1'} @@ -551,6 +557,8 @@ class LaTeXTranslator(nodes.NodeVisitor): 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: @@ -561,13 +569,25 @@ class LaTeXTranslator(nodes.NodeVisitor): else: self.typearea = '' - # object for a table while proccessing. - self.active_table = Table('longtable',settings.table_style) if self.fontenc == 'T1': fontenc = '\\usepackage[T1]{fontenc}\n' else: fontenc = '' + def graphicx_package(): + if self.settings.graphicx_option == '': + return '\\usepackage{graphicx}\n' + if self.settings.graphicx_option.lower() == 'auto': + return '\n'.join(('%Check if we are compiling under latex or pdflatex', + '\\ifx\\pdftexversion\\undefined', + ' \\usepackage{graphicx}', + '\\else', + ' \\usepackage[pdftex]{graphicx}', + '\\fi\n')) + + return '\\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. @@ -586,13 +606,7 @@ class LaTeXTranslator(nodes.NodeVisitor): # extra space between text in tables and the line above them '\\setlength{\\extrarowheight}{2pt}\n', '\\usepackage{amsmath}\n', # what fore amsmath. - r'''%Check if we are compiling under latex or pdflatex - \ifx\pdftexversion\undefined - \usepackage[dvips]{graphicx} - \else - \usepackage[pdftex]{graphicx} - \fi - ''', + graphicx_package(), '\\usepackage{color}\n', '\\usepackage{multirow}\n', '\\usepackage{ifthen}\n', # before hyperref! -- cgit v1.2.1 From eea59a9c4db1abf46582542f241745d6957ed7e1 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 25 Jun 2004 21:34:20 +0000 Subject: Py2.1 compatibility fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2380 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 1f50472c9..740c6acee 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -574,19 +574,19 @@ class LaTeXTranslator(nodes.NodeVisitor): else: fontenc = '' - def graphicx_package(): - if self.settings.graphicx_option == '': - return '\\usepackage{graphicx}\n' - if self.settings.graphicx_option.lower() == 'auto': - return '\n'.join(('%Check if we are compiling under latex or pdflatex', - '\\ifx\\pdftexversion\\undefined', - ' \\usepackage{graphicx}', - '\\else', - ' \\usepackage[pdftex]{graphicx}', - '\\fi\n')) - - return '\\usepackage[%s]{graphicx}\n' % self.settings.graphicx_option - + 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), @@ -606,7 +606,7 @@ class LaTeXTranslator(nodes.NodeVisitor): # extra space between text in tables and the line above them '\\setlength{\\extrarowheight}{2pt}\n', '\\usepackage{amsmath}\n', # what fore amsmath. - graphicx_package(), + self.graphicx_package, '\\usepackage{color}\n', '\\usepackage{multirow}\n', '\\usepackage{ifthen}\n', # before hyperref! -- cgit v1.2.1 From 85038cc782dab0efabfb9cc8410d6e940cebe67d Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 25 Jun 2004 22:10:45 +0000 Subject: Simplified default-setting code git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2383 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 1be10e396..69a311d7b 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -407,7 +407,9 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): ends. Setting specs specific to individual Docutils components are also used (see `populate_from_components()`).""" - settings_defaults = {'_disable_config': None} + settings_defaults = {'_disable_config': None, + '_source': None, + '_destination': None} """Defaults for settings that don't have command-line option equivalents.""" relative_path_settings = ('warning_stream',) @@ -446,16 +448,13 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): self.relative_path_settings = list(self.relative_path_settings) self.components = (self,) + tuple(components) self.populate_from_components(self.components) - defaults = defaults or {} + self.set_defaults(**(defaults or {})) if read_config_files and not self.defaults['_disable_config']: try: config_settings = self.get_standard_config_settings() except ValueError, error: self.error(error) - defaults.update(config_settings.__dict__) - # Internal settings with no defaults from settings specifications; - # initialize manually: - self.set_defaults(_source=None, _destination=None, **defaults) + self.set_defaults(**config_settings.__dict__) def populate_from_components(self, components): """ -- cgit v1.2.1 From c08d3345ec4bf0ad19518fe87b7b91da61f72c64 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 25 Jun 2004 22:11:23 +0000 Subject: Extracted common code from publish_file, publish_string, and publish_parts, into new publish_programmatically. In Publisher.publish, disabled ``settings_overrides`` when ``settings`` is supplied; redundant. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2384 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 188 +++++++++++++++++++++---------------------------------- 1 file changed, 72 insertions(+), 116 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index f3ceed38c..da2333ceb 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -123,7 +123,7 @@ class Publisher: Set components first (`self.set_reader` & `self.set_writer`). """ option_parser = self.setup_option_parser( - usage, description, settings_spec, config_section,**defaults) + usage, description, settings_spec, config_section, **defaults) if argv is None: argv = sys.argv[1:] self.settings = option_parser.parse_args(argv) @@ -171,8 +171,6 @@ class Publisher: self.process_command_line( argv, usage, description, settings_spec, config_section, **(settings_overrides or {})) - elif settings_overrides: - self.settings._update(settings_overrides, 'loose') self.set_io() exit = None document = None @@ -189,7 +187,7 @@ class Publisher: exit = 1 self.debugging_dumps(document) if (enable_exit_status and document - and (document.reporter.max_level + and (document.reporter.max_level >= self.settings.exit_status_level)): sys.exit(document.reporter.max_level + 10) elif exit: @@ -277,25 +275,8 @@ def publish_cmdline(reader=None, reader_name='standalone', Set up & run a `Publisher` (and return the encoded string output). For command-line front ends. - Parameters: + Parameters: see `publish_programmatically` for the remainder. - - `reader`: A `docutils.readers.Reader` object. - - `reader_name`: Name or alias of the Reader class to be instantiated if - no `reader` supplied. - - `parser`: A `docutils.parsers.Parser` object. - - `parser_name`: Name or alias of the Parser class to be instantiated if - no `parser` supplied. - - `writer`: A `docutils.writers.Writer` object. - - `writer_name`: Name or alias of the Writer class to be instantiated if - no `writer` supplied. - - `settings`: Runtime settings object. - - `settings_spec`: Extra settings specification; a `docutils.SettingsSpec` - subclass. Used only if no `settings` specified. - - `settings_overrides`: A dictionary containing program-specific overrides - of component settings. - - `config_section`: Name of configuration file section for application. - Used only if no `settings` or `settings_spec` specified. - - `enable_exit_status`: Boolean; enable exit status at end of processing? - `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. @@ -320,49 +301,22 @@ def publish_file(source=None, source_path=None, Set up & run a `Publisher` (and return the encoded string output). 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. - - `config_section`: Name of configuration file section for application. - Used only if no `settings` or `settings_spec` specified. - - `enable_exit_status`: Boolean; enable exit status at end of processing? + Parameters: see `publish_programmatically`. """ - pub = Publisher(reader, parser, writer, settings=settings) - pub.set_components(reader_name, parser_name, writer_name) - if settings is None: - settings = pub.get_settings(settings_spec=settings_spec, - config_section=config_section) - # Set to propagate exceptions by default when used programmatically: - settings.traceback = 1 - if settings_overrides: - settings._update(settings_overrides, 'loose') - pub.set_source(source, source_path) - pub.set_destination(destination, destination_path) - output = pub.publish(enable_exit_status=enable_exit_status) + output, pub = publish_programmatically( + source=source, source_path=source_path, source_class=io.FileInput, + destination=destination, destination_path=destination_path, + destination_class=io.FileOutput, + reader=reader, reader_name=reader_name, + parser=parser, parser_name=parser_name, + 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 -def publish_string(source, source_path=None, destination_path=None, +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', @@ -375,7 +329,7 @@ def publish_string(source, source_path=None, destination_path=None, 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 how:: + output. Here's one way:: publish_string(..., settings_overrides={'output_encoding': 'unicode'}) @@ -383,50 +337,22 @@ def publish_string(source, source_path=None, destination_path=None, publish_string(..., settings_overrides={'input_encoding': 'unicode'}) - Parameters: - - - `source`: An input string; required. This can be an encoded 8-bit - string (set the "input_encoding" setting to the correct encoding) or a - Unicode string (set the "input_encoding" setting to "unicode"). - - `source_path`: Path to the file or object that produced `source`; - optional. Only used for diagnostic output. - - `destination_path`: Path to the file or object which will receive the - output; optional. Used for determining relative paths (stylesheets, - source links, etc.). - - `reader`: A `docutils.readers.Reader` object. - - `reader_name`: Name or alias of the Reader class to be instantiated if - no `reader` supplied. - - `parser`: A `docutils.parsers.Parser` object. - - `parser_name`: Name or alias of the Parser class to be instantiated if - no `parser` supplied. - - `writer`: A `docutils.writers.Writer` object. - - `writer_name`: Name or alias of the Writer class to be instantiated if - no `writer` supplied. - - `settings`: Runtime settings object. - - `settings_spec`: Extra settings specification; a `docutils.SettingsSpec` - subclass. Used only if no `settings` specified. - - `settings_overrides`: A dictionary containing program-specific overrides - of component settings. - - `config_section`: Name of configuration file section for application. - Used only if no `settings` or `settings_spec` specified. - - `enable_exit_status`: Boolean; enable exit status at end of processing? + Parameters: see `publish_programmatically`. """ - pub = Publisher(reader, parser, writer, settings=settings, - source_class=io.StringInput, - destination_class=io.StringOutput) - pub.set_components(reader_name, parser_name, writer_name) - if settings is None: - settings = pub.get_settings(settings_spec=settings_spec, - config_section=config_section) - # Set to propagate exceptions by default when used programmatically: - settings.traceback = 1 - if settings_overrides: - settings._update(settings_overrides, 'loose') - pub.set_source(source, source_path) - pub.set_destination(destination_path=destination_path) - return pub.publish(enable_exit_status=enable_exit_status) + output, pub = publish_programmatically( + source=source, source_path=source_path, source_class=io.StringInput, + destination=None, destination_path=destination_path, + destination_class=io.StringOutput, + reader=reader, reader_name=reader_name, + parser=parser, parser_name=parser_name, + 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 -def publish_parts(source, source_path=None, destination_path=None, +def publish_parts(source, source_path=None, destination_path=None, reader=None, reader_name='standalone', parser=None, parser_name='restructuredtext', writer=None, writer_name='pseudoxml', @@ -444,6 +370,33 @@ def publish_parts(source, source_path=None, destination_path=None, publish_string(..., settings_overrides={'input_encoding': 'unicode'}) + Parameters: see `publish_programmatically`. + """ + output, pub = publish_programmatically( + source=source, source_path=source_path, source_class=io.StringInput, + destination=None, destination_path=destination_path, + destination_class=io.StringOutput, + reader=reader, reader_name=reader_name, + parser=parser, parser_name=parser_name, + 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 pub.writer.parts + +def publish_programmatically(source, source_path, source_class, + destination, destination_path, destination_class, + 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 programmatic use. Return the encoded + string output and the Publisher object. + Parameters: - `source`: An input string; required. This can be an encoded 8-bit @@ -451,9 +404,12 @@ def publish_parts(source, source_path=None, destination_path=None, 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. + - `source_class`: The class for dynamically created source objects. - `destination_path`: Path to the file or object which will receive the output; optional. Used for determining relative paths (stylesheets, source links, etc.). + - `destination_class`: The class for dynamically created destination + objects. - `reader`: A `docutils.readers.Reader` object. - `reader_name`: Name or alias of the Reader class to be instantiated if no `reader` supplied. @@ -473,17 +429,17 @@ def publish_parts(source, source_path=None, destination_path=None, - `enable_exit_status`: Boolean; enable exit status at end of processing? """ pub = Publisher(reader, parser, writer, settings=settings, - source_class=io.StringInput, - destination_class=io.NullOutput) + source_class=source_class, + destination_class=destination_class) pub.set_components(reader_name, parser_name, writer_name) if settings is None: - settings = pub.get_settings(settings_spec=settings_spec, - config_section=config_section) - # Set to propagate exceptions by default when used programmatically: - settings.traceback = 1 - if settings_overrides: - settings._update(settings_overrides, 'loose') + pub.get_settings( + settings_spec=settings_spec, config_section=config_section, + # Propagate exceptions by default when used programmatically: + traceback=1, + # In case _disable_config is set: + **(settings_overrides or {})) pub.set_source(source, source_path) - pub.set_destination(destination_path=destination_path) - pub.publish(enable_exit_status=enable_exit_status) - return pub.writer.parts + pub.set_destination(destination, destination_path) + output = pub.publish(enable_exit_status=enable_exit_status) + return output, pub -- cgit v1.2.1 From f2d4d909f1921986d1ab52270f38ef61f3127a48 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 26 Jun 2004 11:07:45 +0000 Subject: fixed literal-block inside/outside table inconsistency; going to update the tests when Engelbert says it's OK. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2388 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 740c6acee..20de180aa 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1536,11 +1536,7 @@ class LaTeXTranslator(nodes.NodeVisitor): else: self.literal_block = 1 self.insert_none_breaking_blanks = 1 - if self.active_table.is_open(): - self.body.append('\n{\\ttfamily \\raggedright \\noindent\n') - else: - self.body.append('\\begin{ttfamily}') - self.body.append('\\begin{flushleft}\n') + self.body.append('\n{\\vspace{1ex}\\ttfamily \\raggedright \\noindent\n') # * obey..: is from julien and never worked for me (grubert). # self.body.append('{\\obeylines\\obeyspaces\\ttfamily\n') @@ -1549,12 +1545,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('\n\\end{verbatim}\n') self.verbatim = 0 else: - if self.active_table.is_open(): - self.body.append('\n}\n') - else: - self.body.append('\n') - self.body.append('\\end{flushleft}') - self.body.append('\\end{ttfamily}\n') + self.body.append('\n}\n') self.insert_none_breaking_blanks = 0 self.literal_block = 0 # obey end: self.body.append('}\n') -- cgit v1.2.1 From dfb3e6d20fc6095de34e913b8c2bfd371a5686dc Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 26 Jun 2004 15:12:58 +0000 Subject: reverted my changes; don't work git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2389 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 20de180aa..740c6acee 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1536,7 +1536,11 @@ class LaTeXTranslator(nodes.NodeVisitor): else: self.literal_block = 1 self.insert_none_breaking_blanks = 1 - self.body.append('\n{\\vspace{1ex}\\ttfamily \\raggedright \\noindent\n') + if self.active_table.is_open(): + self.body.append('\n{\\ttfamily \\raggedright \\noindent\n') + else: + self.body.append('\\begin{ttfamily}') + self.body.append('\\begin{flushleft}\n') # * obey..: is from julien and never worked for me (grubert). # self.body.append('{\\obeylines\\obeyspaces\\ttfamily\n') @@ -1545,7 +1549,12 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('\n\\end{verbatim}\n') self.verbatim = 0 else: - self.body.append('\n}\n') + if self.active_table.is_open(): + self.body.append('\n}\n') + else: + self.body.append('\n') + self.body.append('\\end{flushleft}') + self.body.append('\\end{ttfamily}\n') self.insert_none_breaking_blanks = 0 self.literal_block = 0 # obey end: self.body.append('}\n') -- cgit v1.2.1 From cee45a83ba3c6c983c5ca7a2166ca07886bc909f Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 27 Jun 2004 03:47:03 +0000 Subject: docstrings git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2392 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index bcad2741c..e3e15c4ec 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -1,5 +1,5 @@ # Author: David Goodger -# Contact: goodger@users.sourceforge.net +# Contact: goodger@python.org # Revision: $Revision$ # Date: $Date$ # Copyright: This module has been placed in the public domain. @@ -76,7 +76,7 @@ class SettingsSpec: settings_spec = () """Runtime settings specification. Override in subclasses. - Specifies runtime settings and associated command-line options, as used by + Defines 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 @@ -90,8 +90,9 @@ class SettingsSpec: "dest" keyword argument.""" settings_defaults = None - """A dictionary of defaults for internal or inaccessible (by command-line - or config file) settings. Override in subclasses.""" + """A dictionary of defaults for settings not in `settings_spec` (internal + settings, intended to be inaccessible by command-line and config file). + Override in subclasses.""" settings_default_overrides = None """A dictionary of auxiliary defaults, to override defaults for settings -- cgit v1.2.1 From 4e28d2a926aa3c43eebf821802f1424680a3d62a Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 27 Jun 2004 03:47:22 +0000 Subject: extracted ``publish_programmatically`` settings code to ``Publisher.process_programmatic_settings``; updated docstrings git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2393 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 192 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 129 insertions(+), 63 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index da2333ceb..846041f32 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -1,5 +1,5 @@ # Authors: David Goodger -# Contact: goodger@users.sourceforge.net +# Contact: goodger@python.org # Revision: $Revision$ # Date: $Date$ # Copyright: This module has been placed in the public domain. @@ -9,15 +9,17 @@ 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`. See `The Docutils Publisher`_. + +.. _The Docutils Publisher: http://docutils.sf.net/docs/api/publisher.html """ __docformat__ = 'reStructuredText' import sys import pprint -from docutils import __version__, Component, SettingsSpec -from docutils import frontend, io, utils, readers, parsers, writers +from docutils import __version__, SettingsSpec +from docutils import frontend, io, utils, readers, writers from docutils.frontend import OptionParser @@ -38,22 +40,23 @@ class Publisher: """ self.reader = reader - """A `readers.Reader` instance.""" + """A `docutils.readers.Reader` instance.""" self.parser = parser - """A `parsers.Parser` instance.""" + """A `docutils.parsers.Parser` instance.""" self.writer = writer - """A `writers.Writer` instance.""" + """A `docutils.writers.Writer` instance.""" self.source = source - """The source of input data, an `io.Input` instance.""" + """The source of input data, a `docutils.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.Output` instance.""" + """The destination for docutils output, a `docutils.io.Output` + instance.""" self.destination_class = destination_class """The class for dynamically created destination objects.""" @@ -86,8 +89,9 @@ class Publisher: def setup_option_parser(self, usage=None, description=None, settings_spec=None, config_section=None, **defaults): - if config_section and not settings_spec: - settings_spec = SettingsSpec() + if config_section: + if not settings_spec: + settings_spec = SettingsSpec() settings_spec.config_section = config_section parts = config_section.split() if len(parts) > 1 and parts[-1] == 'application': @@ -113,6 +117,17 @@ class Publisher: self.settings = option_parser.get_default_values() return self.settings + def process_programmatic_settings(self, settings_spec, + settings_overrides, + config_section): + if self.settings is None: + defaults = (settings_overrides or {}).copy() + # Propagate exceptions by default when used programmatically: + defaults.setdefault('traceback', 1) + self.get_settings(settings_spec=settings_spec, + config_section=config_section, + **defaults) + def process_command_line(self, argv=None, usage=None, description=None, settings_spec=None, config_section=None, **defaults): @@ -272,8 +287,9 @@ def publish_cmdline(reader=None, reader_name='standalone', enable_exit_status=1, argv=None, usage=default_usage, description=default_description): """ - Set up & run a `Publisher` (and return the encoded string output). - For command-line front ends. + Set up & run a `Publisher` for command-line-based file I/O (input and + output file paths taken automatically from the command line). Return the + encoded string output also. Parameters: see `publish_programmatically` for the remainder. @@ -298,15 +314,15 @@ def publish_file(source=None, source_path=None, settings=None, settings_spec=None, settings_overrides=None, config_section=None, enable_exit_status=None): """ - Set up & run a `Publisher` (and return the encoded string output). - For programmatic use with file-like I/O. + Set up & run a `Publisher` for programmatic use with file-like I/O. + Return the encoded string output also. Parameters: see `publish_programmatically`. """ output, pub = publish_programmatically( - source=source, source_path=source_path, source_class=io.FileInput, - destination=destination, destination_path=destination_path, + source_class=io.FileInput, source=source, source_path=source_path, destination_class=io.FileOutput, + destination=destination, destination_path=destination_path, reader=reader, reader_name=reader_name, parser=parser, parser_name=parser_name, writer=writer, writer_name=writer_name, @@ -324,11 +340,11 @@ def publish_string(source, source_path=None, destination_path=None, settings_overrides=None, config_section=None, enable_exit_status=None): """ - Set up & run a `Publisher`, and return the encoded string output. - For programmatic use with string I/O. + Set up & run a `Publisher` for programmatic use with string I/O. Return + the encoded string or Unicode string output. - For encoded string output, be sure to set the "output_encoding" setting to - the desired encoding. Set it to "unicode" for unencoded Unicode string + 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'}) @@ -340,9 +356,9 @@ def publish_string(source, source_path=None, destination_path=None, Parameters: see `publish_programmatically`. """ output, pub = publish_programmatically( - source=source, source_path=source_path, source_class=io.StringInput, - destination=None, destination_path=destination_path, + source_class=io.StringInput, source=source, source_path=source_path, destination_class=io.StringOutput, + destination=None, destination_path=destination_path, reader=reader, reader_name=reader_name, parser=parser, parser_name=parser_name, writer=writer, writer_name=writer_name, @@ -364,8 +380,8 @@ def publish_parts(source, source_path=None, destination_path=None, Dictionary keys are the names of parts, and values are Unicode strings; encoding is up to the client. For programmatic use with string I/O. - For encoded string input, be sure to set the "input_encoding" setting to - the desired encoding. Set it to "unicode" for unencoded Unicode string + For encoded string input, be sure to set the 'input_encoding' setting to + the desired encoding. Set it to 'unicode' for unencoded Unicode string input. Here's how:: publish_string(..., settings_overrides={'input_encoding': 'unicode'}) @@ -373,9 +389,9 @@ def publish_parts(source, source_path=None, destination_path=None, Parameters: see `publish_programmatically`. """ output, pub = publish_programmatically( - source=source, source_path=source_path, source_class=io.StringInput, - destination=None, destination_path=destination_path, + source_class=io.StringInput, source=source, source_path=source_path, destination_class=io.StringOutput, + destination=None, destination_path=destination_path, reader=reader, reader_name=reader_name, parser=parser, parser_name=parser_name, writer=writer, writer_name=writer_name, @@ -385,8 +401,8 @@ def publish_parts(source, source_path=None, destination_path=None, enable_exit_status=enable_exit_status) return pub.writer.parts -def publish_programmatically(source, source_path, source_class, - destination, destination_path, destination_class, +def publish_programmatically(source_class, source, source_path, + destination_class, destination, destination_path, reader, reader_name, parser, parser_name, writer, writer_name, @@ -394,51 +410,101 @@ def publish_programmatically(source, source_path, source_class, settings_overrides, config_section, enable_exit_status): """ - Set up & run a `Publisher` for programmatic use. Return the encoded - string output and the Publisher object. + Set up & run a `Publisher` for custom programmatic use. Return the + encoded string output and the Publisher object. + + 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. Parameters: - - `source`: An input string; required. This can be an encoded 8-bit - string (set the "input_encoding" setting to the correct encoding) or a - Unicode string (set the "input_encoding" setting to "unicode"). - - `source_path`: Path to the file or object that produced `source`; - optional. Only used for diagnostic output. - - `source_class`: The class for dynamically created source objects. - - `destination_path`: Path to the file or object which will receive the - output; optional. Used for determining relative paths (stylesheets, - source links, etc.). - - `destination_class`: The class for dynamically created destination - objects. - - `reader`: A `docutils.readers.Reader` object. - - `reader_name`: Name or alias of the Reader class to be instantiated if + * `source_class` **required**: The class for dynamically created source + objects. Typically `io.FileInput` or `io.StringInput`. + + * `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. + + - `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`: + + - `io.FileInput`: Path to the input file, opened if no `source` + supplied. + + - `io.StringInput`: Optional. Path to the file or object that produced + `source`. Only used for diagnostic output. + + * `destination_class` **required**: The class for dynamically created + destination objects. Typically `io.FileOutput` or `io.StringOutput`. + + * `destination`: Type depends on `destination_class`: + + - `io.FileOutput`: Either a file-like object (must have 'write' and + 'close' methods), or ``None`` (`destination_path` is opened). If + neither `destination` nor `destination_path` are supplied, + `sys.stdout` is used. + + - `io.StringOutput`: Not used; pass ``None``. + + * `destination_path`: Type depends on `destination_class`: + + - `io.FileOutput`: Path to the output file. Opened if no `destination` + supplied. + + - `io.StringOutput`: 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 + + * `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 + + * `writer`: A `docutils.writers.Writer` object. + + * `writer_name`: Name or alias of the Writer class to be instantiated if no `writer` supplied. - - `settings`: Runtime settings object. - - `settings_spec`: Extra settings specification; a `docutils.SettingsSpec` - subclass. Used only if no `settings` specified. - - `settings_overrides`: A dictionary containing program-specific overrides - of component settings. - - `config_section`: Name of configuration file section for application. - Used only if no `settings` or `settings_spec` specified. - - `enable_exit_status`: Boolean; enable exit status at end of processing? + + * `settings`: A runtime settings (`docutils.frontend.Values`) object, for + dotted-attribute access to runtime settings. It's the end result of the + `SettingsSpec`, config file, and option processing. If `settings` is + passed, it's assumed to be complete and no further setting/config/option + processing is done. + + * `settings_spec`: A `docutils.SettingsSpec` subclass or object. Provides + extra application-specific settings definitions independently of + components. In other words, the application becomes a component, and + its settings data is processed along with that of the other components. + Used only if no `settings` specified. + + * `settings_overrides`: A dictionary containing application-specific + settings defaults that override the defaults of other components. + Used only if no `settings` specified. + + * `config_section`: A string, the name of the configuration file section + for this application. Overrides the ``config_section`` attribute + defined by `settings_spec`. Used only if no `settings` specified. + + * `enable_exit_status`: Boolean; enable exit status at end of processing? """ pub = Publisher(reader, parser, writer, settings=settings, source_class=source_class, destination_class=destination_class) pub.set_components(reader_name, parser_name, writer_name) - if settings is None: - pub.get_settings( - settings_spec=settings_spec, config_section=config_section, - # Propagate exceptions by default when used programmatically: - traceback=1, - # In case _disable_config is set: - **(settings_overrides or {})) + pub.process_programmatic_settings( + settings_spec, settings_overrides, config_section) pub.set_source(source, source_path) pub.set_destination(destination, destination_path) output = pub.publish(enable_exit_status=enable_exit_status) -- cgit v1.2.1 From 80fce2bdf1c90e564c0f4b8d062d5349277e33b2 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 28 Jun 2004 19:06:02 +0000 Subject: made URI recognition slightly more aggressive and intelligent git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2407 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index a786abbda..43caa9711 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -556,14 +556,19 @@ class Inliner: # Valid URI characters (see RFC 2396 & RFC 2732); # final \x00 allows backslash escapes in URIs: uric = r"""[-_.!~*'()[\];/:@&=+$,%a-zA-Z0-9\x00]""" + # Delimiter indicating the end of a URI (not part of the URI): + uri_end_delim = r"""[>]""" # Last URI character; same as uric but no punctuation: - urilast = r"""[_~/a-zA-Z0-9]""" + urilast = r"""[_~*/=+a-zA-Z0-9]""" + # End of a URI (either 'urilast' or 'uric followed by a + # uri_end_delim'): + uri_end = r"""(?:%(urilast)s|%(uric)s(?=%(uri_end_delim)s))""" % locals() emailc = r"""[-_!~*'{|}/#?^`&=+$%a-zA-Z0-9\x00]""" email_pattern = r""" %(emailc)s+(?:\.%(emailc)s+)* # name @ # at %(emailc)s+(?:\.%(emailc)s*)* # host - %(urilast)s # final URI char + %(uri_end)s # final URI char """ parts = ('initial_inline', start_string_prefix, '', [('start', '', non_whitespace_after, # simple start-strings @@ -642,15 +647,15 @@ class Inliner: ( # either: (//?)? # hierarchical URI %(uric)s* # URI characters - %(urilast)s # final URI char + %(uri_end)s # final URI char ) ( # optional query \?%(uric)s* - %(urilast)s + %(uri_end)s )? ( # optional fragment \#%(uric)s* - %(urilast)s + %(uri_end)s )? ) ) -- cgit v1.2.1 From 071d1f5a99072ecac94a55c5a9b8800a1e46792a Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 2 Jul 2004 16:23:10 +0000 Subject: docstrings git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2418 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index e3e15c4ec..3b0ee40a3 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -127,14 +127,21 @@ class TransformSpec: """Transforms required by this class. Override in subclasses.""" unknown_reference_resolvers = () - """List of functions to try to resolve unknown references. Called when - FinalCheckVisitor is unable to find a correct target. The list should - contain functions which will try to resolve unknown references, with the - following signature:: + """List of functions to try to resolve unknown references. Unknown + references have a 'refname' attribute which doesn't correspond to any + target in the document. Called when FinalCheckVisitor is unable to find a + correct target. The list should contain functions which will try to + resolve unknown references, with the following signature:: def reference_resolver(node): '''Returns boolean: true if resolved, false if not.''' + If the function is able to resolve the reference, it should also remove + the 'refname' attribute and mark the node as resolved:: + + del node['refname'] + node.resolved = 1 + Each function must have a "priority" attribute which will affect the order the unknown_reference_resolvers are run:: -- cgit v1.2.1 From dd993980aaed320742b3d1b4ecc8a84c1dd10a79 Mon Sep 17 00:00:00 2001 From: grubert Date: Wed, 7 Jul 2004 07:56:26 +0000 Subject: Indent literal-blocks. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2423 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 740c6acee..a4952d692 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1532,29 +1532,31 @@ class LaTeXTranslator(nodes.NodeVisitor): # in case of a parsed-literal containing just a "**bold**" word: and isinstance(node[0], nodes.Text)): self.verbatim = 1 - self.body.append('\\begin{verbatim}\n') + self.body.append('\\begin{quote}\\begin{verbatim}\n') else: self.literal_block = 1 self.insert_none_breaking_blanks = 1 if self.active_table.is_open(): self.body.append('\n{\\ttfamily \\raggedright \\noindent\n') - else: - self.body.append('\\begin{ttfamily}') - self.body.append('\\begin{flushleft}\n') + else: + # no quote inside tables, to avoid vertical sppace between + # table border and literal block. + # BUG: fails if normal text preceeds the literal block. + self.body.append('\\begin{quote}') + self.body.append('{\\ttfamily \\raggedright \\noindent\n') # * obey..: is from julien and never worked for me (grubert). # self.body.append('{\\obeylines\\obeyspaces\\ttfamily\n') def depart_literal_block(self, node): if self.verbatim: - self.body.append('\n\\end{verbatim}\n') + self.body.append('\n\\end{verbatim}\\end{quote}\n') self.verbatim = 0 else: if self.active_table.is_open(): self.body.append('\n}\n') else: self.body.append('\n') - self.body.append('\\end{flushleft}') - self.body.append('\\end{ttfamily}\n') + self.body.append('}\\end{quote}\n') self.insert_none_breaking_blanks = 0 self.literal_block = 0 # obey end: self.body.append('}\n') -- cgit v1.2.1 From 0e3448f831e078189422b8587baf0b864bd74175 Mon Sep 17 00:00:00 2001 From: cben Date: Fri, 9 Jul 2004 15:17:31 +0000 Subject: Trivial loop refactoring git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2425 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 69a311d7b..1d4d25166 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -43,7 +43,7 @@ from optparse import Values, SUPPRESS_HELP 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`. """ @@ -466,11 +466,10 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): for component in components: if component is None: continue - i = 0 settings_spec = component.settings_spec self.relative_path_settings.extend( component.relative_path_settings) - while i < len(settings_spec): + for i in range(0, len(settings_spec), 3): title, description, option_spec = settings_spec[i:i+3] if title: group = optparse.OptionGroup(self, title, description) @@ -492,7 +491,6 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): self.lists[option.dest] = 1 if component.settings_defaults: self.defaults.update(component.settings_defaults) - i += 3 for component in components: if component and component.settings_default_overrides: self.defaults.update(component.settings_default_overrides) -- cgit v1.2.1 From 84d4b4eab68b4f10db2977c415dbef137c74e687 Mon Sep 17 00:00:00 2001 From: cben Date: Sat, 10 Jul 2004 21:20:15 +0000 Subject: Docstring improvement: structured data asks for structured description. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2427 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index 3b0ee40a3..606ad08aa 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -77,17 +77,30 @@ class SettingsSpec: """Runtime settings specification. Override in subclasses. Defines 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`; a group title of `None` implies no - group, just a list of single options. The "keyword arguments" dictionary - contains arguments to the OptionParser/OptionGroup ``add_option`` method, - with the addition of a "validator" keyword (see the - `docutils.frontend.OptionParser.validators` instance attribute). Runtime - settings names are derived implicitly from long option names - ("--a-setting" becomes ``settings.a_setting``) or explicitly from the - "dest" keyword argument.""" + `docutils.frontend.OptionParser`. This is a tuple of: + + - Option group title (string or `None` which implies no group, just a list + of single options). + + - Description (string or `None`). + + - A sequence of option tuples. Each consists of: + + - Help text (string) + + - List of option strings (e.g. ``['-Q', '--quux']``). + + - Dictionary of keyword arguments. It contains arguments to the + OptionParser/OptionGroup ``add_option`` method, possibly with the + addition of a 'validator' keyword (see the + `docutils.frontend.OptionParser.validators` instance attribute). Runtime + settings names are derived implicitly from long option names + ('--a-setting' becomes ``settings.a_setting``) or explicitly from the + 'dest' keyword argument. See optparse docs for more details. + + - More triples of group title, description, options, as many times as + needed. Thus, `settings_spec` tuples can be simply concatenated. + """ settings_defaults = None """A dictionary of defaults for settings not in `settings_spec` (internal -- cgit v1.2.1 From beef91589c2c8301e07524604122bbf1410f391e Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 16 Jul 2004 18:29:54 +0000 Subject: typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2433 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index a4952d692..aaa22d215 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -126,7 +126,7 @@ class Writer(writers.Writer): '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.' + 'to use "pdftex" if processing with pdf(la)tex and dvips otherwise. ' 'Default is no option.', ['--graphicx-option'], {'default': ''}), -- cgit v1.2.1 From e59980f818cc3a524de9ca7620fb8a3e4089e348 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 16 Jul 2004 23:17:40 +0000 Subject: corrected terminology git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2437 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index 606ad08aa..d3b4adbca 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -55,7 +55,7 @@ __version__ = '0.3.4' """``major.minor.micro`` version number. The micro number is bumped any time there's a change in the API incompatible with one of the front ends or significant new functionality, and at any alpha or beta -release. The minor number is bumped whenever there is a stable +release. The minor 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.""" -- cgit v1.2.1 From f7873d1a0c07f4a1ce311a93e4e011dc8c6a3111 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 24 Jul 2004 14:09:22 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2445 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index d3b4adbca..dd8945f11 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -52,13 +52,11 @@ Subpackages: __docformat__ = 'reStructuredText' __version__ = '0.3.4' -"""``major.minor.micro`` version number. The micro number is bumped -any time there's a change in the API incompatible with one of the -front ends or significant new functionality, and at any alpha or beta -release. The minor number is bumped whenever there is a 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.""" +"""``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 +number will be bumped when the project is feature-complete, and perhaps if +there is a major change in the design.""" class ApplicationError(StandardError): pass -- cgit v1.2.1 From 1941d0dc7b6120c34640c8d6e089a1eca21a434b Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 24 Jul 2004 14:13:38 +0000 Subject: xmlcharrefreplace backport git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2446 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 8 ++++---- docutils/io.py | 12 ++++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 1d4d25166..39678ba1d 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -77,10 +77,10 @@ def validate_encoding_error_handler(setting, value, option_parser, try: codecs.lookup_error(value) except AttributeError: # prior to Python 2.3 - if value not in ('strict', 'ignore', 'replace'): + if value not in ('strict', 'ignore', 'replace', 'xmlcharrefreplace'): raise (LookupError( 'unknown encoding error handler: "%s" (choices: ' - '"strict", "ignore", or "replace")' % value), + '"strict", "ignore", "replace", or "xmlcharrefreplace")' % value), None, sys.exc_info()[2]) except LookupError: raise (LookupError( @@ -364,8 +364,8 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): 'validator': validate_encoding_and_error_handler}), ('Specify the error handler for unencodable characters in ' 'the output. Acceptable values include "strict", "ignore", ' - '"replace", "backslashreplace" (in Python 2.3+), and ' - '"xmlcharrefreplace" (in Python 2.3+). Default is "strict". ' + '"replace", "xmlcharrefreplace", and ' + '"backslashreplace" (in Python 2.3+). Default is "strict". ' 'Usually specified as part of --output-encoding.', ['--output-encoding-error-handler'], {'default': 'strict', 'validator': validate_encoding_error_handler}), diff --git a/docutils/io.py b/docutils/io.py index 09119cef5..ad825bb12 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -9,6 +9,8 @@ I/O classes provide a uniform API for low-level input and output. Subclasses will exist for a variety of input/output mechanisms. """ +from __future__ import nested_scopes + __docformat__ = 'reStructuredText' import sys @@ -127,6 +129,16 @@ class Output(TransformSpec): def encode(self, data): if self.encoding and self.encoding.lower() == 'unicode': return data + elif (self.error_handler == 'xmlcharrefreplace' and + sys.hexversion < 0x02030000): + # We are using xmlcharrefreplace on a Python version which + # doesn't support it. + def enc(x): + try: + return x.encode(self.encoding, 'strict') + except UnicodeError: + return '&#%s;' % str(ord(x)) + return ''.join(map(enc, data)) else: return data.encode(self.encoding, self.error_handler) -- cgit v1.2.1 From 2bc818421e920944dce0b893e824c2ddb0430fea Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 24 Jul 2004 15:17:36 +0000 Subject: simplify xmlcharrefreplace emulation git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2447 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index ad825bb12..47a7dd3e4 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -9,8 +9,6 @@ I/O classes provide a uniform API for low-level input and output. Subclasses will exist for a variety of input/output mechanisms. """ -from __future__ import nested_scopes - __docformat__ = 'reStructuredText' import sys @@ -133,15 +131,17 @@ class Output(TransformSpec): sys.hexversion < 0x02030000): # We are using xmlcharrefreplace on a Python version which # doesn't support it. - def enc(x): - try: - return x.encode(self.encoding, 'strict') - except UnicodeError: - return '&#%s;' % str(ord(x)) - return ''.join(map(enc, data)) + return ''.join([self.xmlcharref_encode(char) for char in data]) else: return data.encode(self.encoding, self.error_handler) + def xmlcharref_encode(self, char): + """Emulate Python 2.3's 'xmlcharrefreplace' encoding error handler.""" + try: + return char.encode(self.encoding, 'strict') + except UnicodeError: + return '&#%i;' % ord(char) + class FileInput(Input): -- cgit v1.2.1 From 253d5324a1754ddda972807b0e2ff6303c3dbef4 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 24 Jul 2004 18:35:09 +0000 Subject: xmlcharrefreplace backport git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2448 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index 846041f32..17b8ddd7f 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -245,23 +245,23 @@ command line used.""" % (__version__, sys.version.split()[0])) def report_UnicodeError(self, error): print >>sys.stderr, '%s: %s' % (error.__class__.__name__, error) - print >>sys.stderr, (""" + print >>sys.stderr, """ The specified output encoding (%s) cannot handle all of the output. Try setting "--output-encoding-error-handler" to -""" % (self.settings.output_encoding)), + +* "xmlcharrefreplace" (for HTML & XML output);""" if sys.hexversion >= 0x02030000: # Python 2.3 - print >>sys.stderr, (""" -* "xmlcharrefreplace" (for HTML & XML output, Python 2.3+); + print >>sys.stderr, """\ the output will contain "%s" and should be usable. * "backslashreplace" (for other output formats, Python 2.3+); - look for "%s" in the output. -*""" % (error.object[error.start:error.end].encode('ascii', - 'xmlcharrefreplace'), - error.object[error.start:error.end].encode('ascii', - 'backslashreplace'))), + look for "%s" in the output.""" % ( + error.object[error.start:error.end].encode('ascii', 'xmlcharrefreplace'), + error.object[error.start:error.end].encode('ascii', 'backslashreplace')) + else: + print >>sys.stderr, ' the output should be usable as-is.' print >>sys.stderr, ("""\ -"replace" (Python 2.1 or 2.2); look for "?" in the output. +* "replace"; look for "?" in the output. "--output-encoding-error-handler" is currently set to "%s". -- cgit v1.2.1 From 2384d0cf6cd5f596511784ff8b54c8ae1e57e8fa Mon Sep 17 00:00:00 2001 From: cben Date: Sun, 25 Jul 2004 01:45:27 +0000 Subject: Allow the test suite to survive unimportable test modules. Notably, this fixes a crash on importing `moduleparser` under Python 2.1 from ``test/test_readers/test_python/test_functions.py``. (This shouldn't happen anyway, added to BUGS.txt) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2449 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/python/__init__.py | 3 +++ docutils/readers/python/moduleparser.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/readers/python/__init__.py b/docutils/readers/python/__init__.py index 14d01c0c8..6c027641d 100644 --- a/docutils/readers/python/__init__.py +++ b/docutils/readers/python/__init__.py @@ -6,6 +6,9 @@ """ This package contains the Python Source Reader modules. + +It requires Python 2.2 or higher (`moduleparser` depends on `compiler` and +`tokenizer` modules). """ __docformat__ = 'reStructuredText' diff --git a/docutils/readers/python/moduleparser.py b/docutils/readers/python/moduleparser.py index ddfe21ea7..8fd7ed67b 100644 --- a/docutils/readers/python/moduleparser.py +++ b/docutils/readers/python/moduleparser.py @@ -5,7 +5,7 @@ # Copyright: This module has been placed in the public domain. """ -Parser for Python modules. +Parser for Python modules. Requires Python 2.2 or higher. The `parse_module()` function takes a module's text and file name, runs it through the module parser (using compiler.py and tokenize.py) -- cgit v1.2.1 From 92cf1a41dfcfaecc618930fb85cf5fb5f775dc01 Mon Sep 17 00:00:00 2001 From: cben Date: Sun, 25 Jul 2004 02:14:23 +0000 Subject: Replace version number sniffing with specific features sniffing. Also fix 2 bugs in `report_UnicodeError`: * Print the current encoding (was a ``%s``). * Don't crash before Python 2.3 where `UnicodeError` objects had no ``object`` or ``encoding`` attributes. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2450 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index 17b8ddd7f..9794b95a6 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -245,21 +245,33 @@ command line used.""" % (__version__, sys.version.split()[0])) def report_UnicodeError(self, error): print >>sys.stderr, '%s: %s' % (error.__class__.__name__, error) - print >>sys.stderr, """ + + # A `UnicodeError` objected contained no useful args until Python 2.3 + try: + print >>sys.stderr, """ The specified output encoding (%s) cannot -handle all of the output. +handle all of the output.""" % error.encoding + except AttributeError: + print >>sys.stderr, """ +The specified output encoding cannot +handle all of the output.""" + + print """\ Try setting "--output-encoding-error-handler" to * "xmlcharrefreplace" (for HTML & XML output);""" - if sys.hexversion >= 0x02030000: # Python 2.3 + try: + data = error.object[error.start:error.end] print >>sys.stderr, """\ the output will contain "%s" and should be usable. * "backslashreplace" (for other output formats, Python 2.3+); look for "%s" in the output.""" % ( - error.object[error.start:error.end].encode('ascii', 'xmlcharrefreplace'), - error.object[error.start:error.end].encode('ascii', 'backslashreplace')) - else: - print >>sys.stderr, ' the output should be usable as-is.' + data.encode('ascii', 'xmlcharrefreplace'), + data.encode('ascii', 'backslashreplace')) + except AttributeError: + print >>sys.stderr, """\ + the output should be usable as-is.""" + print >>sys.stderr, ("""\ * "replace"; look for "?" in the output. -- cgit v1.2.1 From 00f1da6edfcac7e44bb561cff134ce408e9f5e2c Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 25 Jul 2004 13:36:33 +0000 Subject: re-re-fixed encoding error message, cleanup git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2455 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 69 ++++++++++++++++++++++++-------------------------------- 1 file changed, 30 insertions(+), 39 deletions(-) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index 9794b95a6..84136d5b2 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -244,48 +244,39 @@ command line used.""" % (__version__, sys.version.split()[0])) utils.Reporter.levels[error.level])) def report_UnicodeError(self, error): - print >>sys.stderr, '%s: %s' % (error.__class__.__name__, error) - - # A `UnicodeError` objected contained no useful args until Python 2.3 - try: - print >>sys.stderr, """ -The specified output encoding (%s) cannot -handle all of the output.""" % error.encoding - except AttributeError: - print >>sys.stderr, """ -The specified output encoding cannot -handle all of the output.""" - - print """\ -Try setting "--output-encoding-error-handler" to - -* "xmlcharrefreplace" (for HTML & XML output);""" + sys.stderr.write( + '%s: %s\n' + '\n' + 'The specified output encoding (%s) cannot\n' + 'handle all of the output.\n' + 'Try setting "--output-encoding-error-handler" to\n' + '\n' + '* "xmlcharrefreplace" (for HTML & XML output);\n' + % (error.__class__.__name__, error, + self.settings.output_encoding)) try: data = error.object[error.start:error.end] - print >>sys.stderr, """\ - the output will contain "%s" and should be usable. -* "backslashreplace" (for other output formats, Python 2.3+); - look for "%s" in the output.""" % ( - data.encode('ascii', 'xmlcharrefreplace'), - data.encode('ascii', 'backslashreplace')) + sys.stderr.write( + ' the output will contain "%s" and should be usable.\n' + '* "backslashreplace" (for other output formats, Python 2.3+);\n' + ' look for "%s" in the output.\n' + % (data.encode('ascii', 'xmlcharrefreplace'), + data.encode('ascii', 'backslashreplace'))) except AttributeError: - print >>sys.stderr, """\ - the output should be usable as-is.""" - - print >>sys.stderr, ("""\ -* "replace"; look for "?" in the output. - -"--output-encoding-error-handler" is currently set to -"%s". - -Exiting due to error. Use "--traceback" to diagnose. -If the advice above doesn't eliminate the error, -please report it to . -Include "--traceback" output, Docutils version (%s), -Python version (%s), your OS type & version, and the -command line used.""" % (self.settings.output_encoding_error_handler, - __version__, sys.version.split()[0])) - + sys.stderr.write(' the output should be usable as-is.\n') + sys.stderr.write( + '* "replace"; look for "?" in the output.\n' + '\n' + '"--output-encoding-error-handler" is currently set to "%s".\n' + '\n' + 'Exiting due to error. Use "--traceback" to diagnose.\n' + 'If the advice above doesn\'t eliminate the error,\n' + 'please report it to .\n' + 'Include "--traceback" output, Docutils version (%s),\n' + 'Python version (%s), your OS type & version, and the\n' + 'command line used.\n' + % (self.settings.output_encoding_error_handler, + __version__, sys.version.split()[0])) default_usage = '%prog [options] [ []]' default_description = ('Reads from (default is stdin) and writes to ' -- cgit v1.2.1 From c26c5afe71fd96435f6def0a9279a3ac52c3c01d Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 26 Jul 2004 09:55:00 +0000 Subject: Using feature sniffing instead of hexversion. Speedup when xmlcharrefreplace is used on Python < 2.3 but isn't needed git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2456 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index 47a7dd3e4..45cecdf08 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -127,13 +127,19 @@ class Output(TransformSpec): def encode(self, data): if self.encoding and self.encoding.lower() == 'unicode': return data - elif (self.error_handler == 'xmlcharrefreplace' and - sys.hexversion < 0x02030000): - # We are using xmlcharrefreplace on a Python version which - # doesn't support it. - return ''.join([self.xmlcharref_encode(char) for char in data]) else: - return data.encode(self.encoding, self.error_handler) + try: + return data.encode(self.encoding, self.error_handler) + except ValueError: + # ValueError is raised if there are unencodable chars + # in data and the error_handler isn't found. + if self.error_handler == 'xmlcharrefreplace': + # 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]) + else: + raise def xmlcharref_encode(self, char): """Emulate Python 2.3's 'xmlcharrefreplace' encoding error handler.""" -- cgit v1.2.1 From f7d89a66e61d93dc6f3b5f6813e7914b83a25369 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 26 Jul 2004 17:58:01 +0000 Subject: Removed comments around embedded stylesheets -- they're wrong in XHTML. See . git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2458 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index b661f831d..4be9e9074 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -170,7 +170,7 @@ class HTMLTranslator(nodes.NodeVisitor): generator = ('\n') stylesheet_link = '\n' - embedded_stylesheet = '\n' + embedded_stylesheet = '\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') -- cgit v1.2.1 From 96ef87cb0b150a32a4a318cb897c67cf51bcfcae Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 26 Jul 2004 22:32:24 +0000 Subject: fixed bug with ".." recognition in unicode directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2460 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index a91719f6d..882d6acd9 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -196,7 +196,7 @@ def unicode_directive(name, arguments, options, content, lineno, return element.children unicode_directive.arguments = (1, 0, 1) -unicode_comment_pattern = re.compile(r'( |\n|^).. ') +unicode_comment_pattern = re.compile(r'( |\n|^)\.\. ') def class_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): -- cgit v1.2.1 From d1d7913a9f7f3a589852c652ad167c64b60fbf99 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 27 Jul 2004 22:59:40 +0000 Subject: typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2487 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/python/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/readers/python/__init__.py b/docutils/readers/python/__init__.py index 6c027641d..22cfe3b8d 100644 --- a/docutils/readers/python/__init__.py +++ b/docutils/readers/python/__init__.py @@ -7,8 +7,8 @@ """ This package contains the Python Source Reader modules. -It requires Python 2.2 or higher (`moduleparser` depends on `compiler` and -`tokenizer` modules). +It requires Python 2.2 or higher (`moduleparser` depends on the +`compiler` and `tokenize` modules). """ __docformat__ = 'reStructuredText' -- cgit v1.2.1 From 248763249e49339854e070dda04541e8bdfe5e75 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 29 Jul 2004 00:24:32 +0000 Subject: fixed \maketitle bug git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2500 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index aaa22d215..fe897b82f 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1125,9 +1125,9 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_document(self, node): self.body_prefix.append('\\begin{document}\n') - # BUG: \maketitle without title (i.e. --no-doc-title) adds - # unnecessary vspace. - self.body_prefix.append('\\maketitle\n\n') + # titled document? + if 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') -- cgit v1.2.1 From 7e60d02af9cc77bf0c8620f0004df7c9b618abd1 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 29 Jul 2004 00:27:45 +0000 Subject: fixed indentation of comment git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2501 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index fe897b82f..b8d3d9c83 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1128,8 +1128,8 @@ class LaTeXTranslator(nodes.NodeVisitor): # titled document? if isinstance(node[0], nodes.title): self.body_prefix.append('\\maketitle\n\n') - # alternative use titlepage environment. - # \begin{titlepage} + # alternative use titlepage environment. + # \begin{titlepage} self.body.append('\n\\setlength{\\locallinewidth}{\\linewidth}\n') def depart_document(self, node): -- cgit v1.2.1 From d55cec685e1514c070b2eb77bc6015dfebbedc1f Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 29 Jul 2004 14:57:28 +0000 Subject: release 0.3.5 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2512 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index dd8945f11..2818a7dcf 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -51,7 +51,7 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.3.4' +__version__ = '0.3.5' """``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 -- cgit v1.2.1 From 24c3144d3600279ca16a90df8448436637b17048 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 29 Jul 2004 18:18:35 +0000 Subject: release 0.3.5 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2518 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index 2818a7dcf..94c7c7282 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -51,7 +51,7 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.3.5' +__version__ = '0.3.6' """``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 -- cgit v1.2.1 From 14d88a0e6bc1921b02952fc27b847121ea9ff2b1 Mon Sep 17 00:00:00 2001 From: lele Date: Fri, 20 Aug 2004 08:00:43 +0000 Subject: The directive now accepts a prefix option, a string that will be prepended to the generated section enumeration, and a start value, an integer used as the starting value for auto-numbering the sections. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2533 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/parts.py | 4 +++- docutils/transforms/parts.py | 18 ++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/parts.py b/docutils/parsers/rst/directives/parts.py index 5e6809142..98d2931f7 100644 --- a/docutils/parsers/rst/directives/parts.py +++ b/docutils/parsers/rst/directives/parts.py @@ -78,4 +78,6 @@ def sectnum(name, arguments, options, content, lineno, state_machine.document.note_pending(pending) return [pending] -sectnum.options = {'depth': int} +sectnum.options = {'depth': int, + 'start': int, + 'prefix': directives.unchanged_required} diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index 80f5b0027..fe2235cab 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -33,13 +33,27 @@ class SectNum(Transform): def apply(self): self.maxdepth = self.startnode.details.get('depth', sys.maxint) + self.startvalue = self.startnode.details.get('start', 1) + prefix = self.startnode.details.get('prefix', None) + if prefix is None: + self.prefix = () + else: + self.prefix = (prefix,) self.startnode.parent.remove(self.startnode) if self.document.settings.sectnum_xform: self.update_section_numbers(self.document) - def update_section_numbers(self, node, prefix=(), depth=0): + def update_section_numbers(self, node, prefix=None, depth=0): depth += 1 - sectnum = 1 + + if prefix: + sectnum = 1 + else: + sectnum = self.startvalue + + if prefix is None: + prefix = self.prefix + for child in node: if isinstance(child, nodes.section): numbers = prefix + (str(sectnum),) -- cgit v1.2.1 From ade51cc8b18dea1800f7a2481e81a1de2fe3d654 Mon Sep 17 00:00:00 2001 From: david_abrahams Date: Fri, 20 Aug 2004 13:02:50 +0000 Subject: Support for custom interpreted text roles git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2534 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index b8d3d9c83..21f679a20 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1872,7 +1872,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.bookmark(node) # BUG: latex chokes on center environment with "perhaps a missing item". # so we use hfill. - self.body.append('\\subsection*{~\\hfill ') + self.body.append('\\subsubsection*{~\\hfill ') # the closing brace for subsection. self.context.append('\\hfill ~}\n') # TODO: for admonition titles before the first section @@ -1917,6 +1917,12 @@ class LaTeXTranslator(nodes.NodeVisitor): self.topic_class = '' 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_class = '' self.body.append('\n') -- cgit v1.2.1 From 96cef63ca0e73f97052a3286d8480b7ea870313e Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 23 Aug 2004 17:35:50 +0000 Subject: added "suffix" option to "sectnum" directive; require separating punctuation git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2539 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/parts.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/parts.py b/docutils/parsers/rst/directives/parts.py index 98d2931f7..c182ad0fd 100644 --- a/docutils/parsers/rst/directives/parts.py +++ b/docutils/parsers/rst/directives/parts.py @@ -80,4 +80,5 @@ def sectnum(name, arguments, options, content, lineno, sectnum.options = {'depth': int, 'start': int, - 'prefix': directives.unchanged_required} + 'prefix': directives.unchanged_required, + 'suffix': directives.unchanged_required} -- cgit v1.2.1 From 332ab482eb042054553b3cd5380a13c80c23c00f Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 24 Aug 2004 01:12:24 +0000 Subject: added "suffix" option to "sectnum" directive; require separating punctuation git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2541 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/parts.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index fe2235cab..769cb8263 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -34,33 +34,27 @@ class SectNum(Transform): def apply(self): self.maxdepth = self.startnode.details.get('depth', sys.maxint) self.startvalue = self.startnode.details.get('start', 1) - prefix = self.startnode.details.get('prefix', None) - if prefix is None: - self.prefix = () - else: - self.prefix = (prefix,) + self.prefix = self.startnode.details.get('prefix', '') + self.suffix = self.startnode.details.get('suffix', '') self.startnode.parent.remove(self.startnode) if self.document.settings.sectnum_xform: self.update_section_numbers(self.document) - def update_section_numbers(self, node, prefix=None, depth=0): + def update_section_numbers(self, node, prefix=(), depth=0): depth += 1 - if prefix: sectnum = 1 else: sectnum = self.startvalue - - if prefix is None: - prefix = self.prefix - for child in node: if isinstance(child, nodes.section): numbers = prefix + (str(sectnum),) title = child[0] # Use   for spacing: generated = nodes.generated( - '', '.'.join(numbers) + u'\u00a0' * 3, CLASS='sectnum') + '', (self.prefix + '.'.join(numbers) + self.suffix + + u'\u00a0' * 3), + CLASS='sectnum') title.insert(0, generated) title['auto'] = 1 if depth < self.maxdepth: -- cgit v1.2.1 From 400a68c18030a642d4d9c1a45b4003ab468ccba9 Mon Sep 17 00:00:00 2001 From: grubert Date: Wed, 25 Aug 2004 08:04:18 +0000 Subject: Add ``\PreloadUnicodePage{n}`` to the header if in LaTeX code uses unicode. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2542 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 21f679a20..43395a588 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -573,7 +573,11 @@ class LaTeXTranslator(nodes.NodeVisitor): fontenc = '\\usepackage[T1]{fontenc}\n' else: fontenc = '' - + input_encoding = self.encoding % self.to_latex_encoding(settings.output_encoding) + if self.to_latex_encoding(settings.output_encoding) == 'utf8': + # preload unicode to avoid ``Please insert PrerenderUnicode`` message, + # when rendering the first ``\section``. + input_encoding += '\\PreloadUnicodePage{0}\n' if self.settings.graphicx_option == '': self.graphicx_package = '\\usepackage{graphicx}\n' elif self.settings.graphicx_option.lower() == 'auto': @@ -593,7 +597,7 @@ class LaTeXTranslator(nodes.NodeVisitor): '\\usepackage{babel}\n', # language is in documents settings. fontenc, '\\usepackage{shortvrb}\n', # allows verb in footnotes. - self.encoding % self.to_latex_encoding(settings.output_encoding), + input_encoding, # * tabularx: for docinfo, automatic width of columns, always on one page. '\\usepackage{tabularx}\n', '\\usepackage{longtable}\n', -- cgit v1.2.1 From 1183d087449b955125142f3280f4a64d355bd4ff Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 29 Aug 2004 12:23:35 +0000 Subject: added self.translator_class git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2545 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 43395a588..78cc0f9da 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -140,8 +140,12 @@ class Writer(writers.Writer): output = None """Final translated form of `document`.""" + def __init__(self): + writers.Writer.__init__(self) + self.translator_class = LaTeXTranslator + def translate(self): - visitor = LaTeXTranslator(self.document) + visitor = self.translator_class(self.document) self.document.walkabout(visitor) self.output = visitor.astext() self.head_prefix = visitor.head_prefix -- cgit v1.2.1 From fc90923c5bee3bc9d7520a320cf9b3c00eb8f85e Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 29 Aug 2004 13:01:18 +0000 Subject: Fixed bug which causes LaTeX writer to crash when called with an empty document tree. This happens e.g. when processing a reST document which only consists of a directive which is not supported by the LaTeX writer (like meta). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2546 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 78cc0f9da..b04e0f0a2 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1134,7 +1134,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_document(self, node): self.body_prefix.append('\\begin{document}\n') # titled document? - if isinstance(node[0], nodes.title): + if len(node) and isinstance(node[0], nodes.title): self.body_prefix.append('\\maketitle\n\n') # alternative use titlepage environment. # \begin{titlepage} -- cgit v1.2.1 From 0e4e4fc6de0df34ca437f7ed4d3a8b8db810a198 Mon Sep 17 00:00:00 2001 From: grubert Date: Sun, 5 Sep 2004 17:16:26 +0000 Subject: New option "font-encoding". git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2552 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index b04e0f0a2..d0e4adae4 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -130,6 +130,12 @@ class Writer(writers.Writer): '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". ', + ['--font-encoding'], + {'default': ''}), ),) settings_defaults = {'output_encoding': 'latin-1'} @@ -539,7 +545,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self._use_latex_citations = settings.use_latex_citations self.hyperlink_color = settings.hyperlink_color self.compound_enumerators = settings.compound_enumerators - self.fontenc = '' + self.font_encoding = settings.font_encoding self.section_prefix_for_enumerators = ( settings.section_prefix_for_enumerators) self.section_enumerator_separator = ( @@ -573,10 +579,12 @@ class LaTeXTranslator(nodes.NodeVisitor): else: self.typearea = '' - if self.fontenc == 'T1': - fontenc = '\\usepackage[T1]{fontenc}\n' + if self.font_encoding == 'OT1': + fontenc_header = '' + elif self.font_encoding == '': + fontenc_header = '\\usepackage{ae}\n' else: - fontenc = '' + fontenc_header = '\\usepackage[%s]{fontenc}\n' % (self.font_encoding,) input_encoding = self.encoding % self.to_latex_encoding(settings.output_encoding) if self.to_latex_encoding(settings.output_encoding) == 'utf8': # preload unicode to avoid ``Please insert PrerenderUnicode`` message, @@ -599,7 +607,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.head_prefix = [ self.latex_head % (self.d_options,self.settings.documentclass), '\\usepackage{babel}\n', # language is in documents settings. - fontenc, + fontenc_header, '\\usepackage{shortvrb}\n', # allows verb in footnotes. input_encoding, # * tabularx: for docinfo, automatic width of columns, always on one page. @@ -811,7 +819,7 @@ class LaTeXTranslator(nodes.NodeVisitor): if self.literal_block or self.literal: # pdflatex does not produce doublequotes for ngerman. text = self.babel.double_quotes_in_tt(text) - if self.fontenc == 'T1': + if self.font_encoding == 'T1' or self.font_encoding == '': # make sure "--" does not become a "-". # the same for "<<" and ">>". text = text.replace("--","-{}-").replace("--","-{}-") -- cgit v1.2.1 From b852fcf41a95ac4a0719bc92e6561392f2581212 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 7 Sep 2004 11:12:51 +0000 Subject: added escaping for some characters git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2556 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index d0e4adae4..127e3b604 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -819,14 +819,26 @@ class LaTeXTranslator(nodes.NodeVisitor): if self.literal_block or self.literal: # pdflatex does not produce doublequotes for ngerman. text = self.babel.double_quotes_in_tt(text) - if self.font_encoding == 'T1' or self.font_encoding == '': - # make sure "--" does not become a "-". - # the same for "<<" and ">>". - text = text.replace("--","-{}-").replace("--","-{}-") - text = text.replace(">>",">{}>").replace(">>",">{}>") - text = text.replace("<<","<{}<").replace("<<","<{}<") - # replace underline by underlined blank, because this has correct width. - text = text.replace("_", '{\\underline{ }}') + # Separate compound characters, e.g. ",,," to ",{},{},". + # This is usually only necessary when using T1 + # font-encoding, but in some languages (like russian) T1 + # is automatically activated, so we can't rely on + # font_encoding-guessing. Thus we separate the characters + # unconditionally, even if it is not necessary. Note that + # the separation must be done twice, because otherwise we + # would replace "---" by "-{}--". + for char in '"\',-<>`' * 2: + text = text.replace(char + char, char + '{}' + char) + 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("_", '{\\_}') -- cgit v1.2.1 From a2308056a0d1742e58f628cf7c361990ae94951a Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 7 Sep 2004 14:39:58 +0000 Subject: typos, font-encoding doc git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2559 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 127e3b604..aefe72b5a 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -112,7 +112,7 @@ class Writer(writers.Writer): 'for compound enumerated lists. Default is "-".', ['--section-enumerator-separator'], {'default': '-', 'metavar': ''}), - ('When possibile, use verbatim for literal-blocks.' + ('When possibile, use verbatim for literal-blocks. ' 'Default is to always use the mbox environment.', ['--use-verbatim-when-possible'], {'default': 0, 'action': 'store_true', @@ -124,16 +124,17 @@ class Writer(writers.Writer): ['--table-style'], {'choices': ['standard', 'booktabs','nolines'], 'default': 'standard', 'metavar': ''}), - ('LaTeX graphicx package option.' + ('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.' + '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". ', + 'character. Default is "" which leads to package "ae" (a T1 ' + 'emulation using CM fonts).', ['--font-encoding'], {'default': ''}), ),) -- cgit v1.2.1 From 151d9d61630c16ec0bf11441338413b2614a4a41 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 7 Sep 2004 17:53:23 +0000 Subject: added aeguill package git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2560 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index aefe72b5a..d848551ff 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -583,7 +583,7 @@ class LaTeXTranslator(nodes.NodeVisitor): if self.font_encoding == 'OT1': fontenc_header = '' elif self.font_encoding == '': - fontenc_header = '\\usepackage{ae}\n' + fontenc_header = '\\usepackage{ae}\n\\usepackage{aeguill}\n' else: fontenc_header = '\\usepackage[%s]{fontenc}\n' % (self.font_encoding,) input_encoding = self.encoding % self.to_latex_encoding(settings.output_encoding) -- cgit v1.2.1 From 39aebfa76a0130a96d3ba65fa973069bc1fe96f4 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 8 Sep 2004 19:48:26 +0000 Subject: fixed bug when multiple "class" directives are applied git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2561 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/misc.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/transforms/misc.py b/docutils/transforms/misc.py index 4f6e2670b..520a5febb 100644 --- a/docutils/transforms/misc.py +++ b/docutils/transforms/misc.py @@ -36,6 +36,11 @@ class CallBack(Transform): class ClassAttribute(Transform): + """ + Move the "class" attribute specified in the "pending" node into the + immediately following non-comment element. + """ + default_priority = 210 def apply(self): @@ -44,14 +49,16 @@ class ClassAttribute(Transform): parent = pending.parent child = pending while parent: + # Check for appropriate following siblings: for index in range(parent.index(child) + 1, len(parent)): element = parent[index] - if isinstance(element, nodes.comment): + if isinstance(element, nodes.Invisible): continue element.set_class(class_value) pending.parent.remove(pending) return else: + # At end of section or container; apply to sibling child = parent parent = parent.parent error = self.document.reporter.error( -- cgit v1.2.1 From f3aa787d95ca9355050f76b4a849610bbeeace5c Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 8 Sep 2004 19:49:33 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2562 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 882d6acd9..d6aa39ae7 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -200,7 +200,10 @@ 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. + """ class_value = nodes.make_id(arguments[0]) if class_value: pending = nodes.pending(misc.ClassAttribute, -- cgit v1.2.1 From 0ad035759fe1b762b46fc62b506cf04f000ea793 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 9 Sep 2004 21:20:09 +0000 Subject: typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2564 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 39678ba1d..4c6031c53 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -358,7 +358,7 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): ('Specify the text encoding for output. Default is UTF-8. ' 'Optionally also specify the error handler for unencodable ' 'characters, after a colon (":"); default is "strict". (See ' - '"--output-encoding-error-encoding".)', + '"--output-encoding-error-handler".)', ['--output-encoding', '-o'], {'metavar': '', 'default': 'utf-8', 'validator': validate_encoding_and_error_handler}), @@ -372,7 +372,7 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): ('Specify the text encoding for error output. Default is ASCII. ' 'Optionally also specify the error handler for unencodable ' 'characters, after a colon (":"); default is "%s". (See ' - '"--output-encoding-error-encoding".' + '"--output-encoding-error-handler".' % default_error_encoding_error_handler, ['--error-encoding', '-e'], {'metavar': '', 'default': 'ascii', @@ -637,6 +637,22 @@ section "Old-Format Configuration Files". section_dict[option] = self.get(section, option, raw=1) return section_dict + def set(self, section, option, value): + """ + Set an option. + + Overrides stdlib ConfigParser's set() method to allow non-string + values. Required for compatibility with Python 2.4. + """ + if not section or section == CP.DEFAULTSECT: + sectdict = self._defaults + else: + try: + sectdict = self._sections[section] + except KeyError: + raise CP.NoSectionError(section) + sectdict[self.optionxform(option)] = value + class ConfigDeprecationWarning(DeprecationWarning): """Warning for deprecated configuration file features.""" -- cgit v1.2.1 From eeef0a2eac14f4833500709dd31ab28b36558914 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 9 Sep 2004 21:32:36 +0000 Subject: oops, open issue; didn't meant to check that in yet git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2565 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 4c6031c53..412a1b5ad 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -637,22 +637,6 @@ section "Old-Format Configuration Files". section_dict[option] = self.get(section, option, raw=1) return section_dict - def set(self, section, option, value): - """ - Set an option. - - Overrides stdlib ConfigParser's set() method to allow non-string - values. Required for compatibility with Python 2.4. - """ - if not section or section == CP.DEFAULTSECT: - sectdict = self._defaults - else: - try: - sectdict = self._sections[section] - except KeyError: - raise CP.NoSectionError(section) - sectdict[self.optionxform(option)] = value - class ConfigDeprecationWarning(DeprecationWarning): """Warning for deprecated configuration file features.""" -- cgit v1.2.1 From 144f2976e1b8ac8619acfbb2bf333771b33d2e86 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 11 Sep 2004 13:27:03 +0000 Subject: fixed non-ASCII-character bug with csv-table directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2568 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index e34e54b20..787278b3e 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -13,6 +13,7 @@ __docformat__ = 'reStructuredText' import sys import os.path +from types import UnicodeType from docutils import nodes, statemachine, utils from docutils.utils import SystemMessagePropagation from docutils.parsers.rst import directives @@ -246,10 +247,18 @@ def process_header_option(options, state_machine, lineno): return table_head, max_header_cols def parse_csv_data_into_rows(csv_data, dialect, source, options): + isunicode = (csv_data and type(csv_data[0]) == UnicodeType) + if isunicode: + # Encode unicode in UTF-8, because the csv module doesn't + # support unicode strings. + csv_data = [item.encode('utf-8') for item in csv_data] csv_reader = csv.reader(csv_data, dialect=dialect) rows = [] max_cols = 0 for row in csv_reader: + if isunicode: + # Decode UTF-8 back to unicode + row = [item.decode('utf-8') for item in row] row_data = [] for cell in row: cell_data = (0, 0, 0, statemachine.StringList(cell.splitlines(), -- cgit v1.2.1 From 8f5b572efecb175fb4a07bd40f7bd6e3a275128d Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 11 Sep 2004 15:35:05 +0000 Subject: acceptet patch from http://sourceforge.net/tracker/index.php?func=detail&aid=1009676&group_id=38414&atid=422032 (finnish translation) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2570 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/fi.py | 62 ++++++++++++++++++++++++ docutils/parsers/rst/languages/fi.py | 91 ++++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 docutils/languages/fi.py create mode 100644 docutils/parsers/rst/languages/fi.py (limited to 'docutils') diff --git a/docutils/languages/fi.py b/docutils/languages/fi.py new file mode 100644 index 000000000..365172a38 --- /dev/null +++ b/docutils/languages/fi.py @@ -0,0 +1,62 @@ +# Author: Asko Soukka +# Contact: asko.soukka@iki.fi +# 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. + +""" +Finnish-language mappings for language-dependent features of Docutils. +""" + +__docformat__ = 'reStructuredText' + +labels = { + # fixed: language-dependent + u'author': u'Tekij\u00e4', + u'authors': u'Tekij\u00e4t', + u'organization': u'Yhteis\u00f6', + u'address': u'Osoite', + u'contact': u'Yhteystiedot', + u'version': u'Versio', + u'revision': u'Vedos', + u'status': u'Tila', + u'date': u'P\u00e4iv\u00e4ys', + u'copyright': u'Tekij\u00e4noikeudet', + u'dedication': u'Omistuskirjoitus', + u'abstract': u'Tiivistelm\u00e4', + u'attention': u'Huomio!', + u'caution': u'Varo!', + u'danger': u'!VAARA!', + u'error': u'Virhe', + u'hint': u'Vihje', + u'important': u'T\u00e4rke\u00e4\u00e4', + u'note': u'Huomautus', + u'tip': u'Neuvo', + u'warning': u'Varoitus', + u'contents': u'Sis\u00e4llys'} +"""Mapping of node class name to label text.""" + +bibliographic_fields = { + # language-dependent: fixed + u'tekij\u00e4': u'author', + u'tekij\u00e4t': u'authors', + u'yhteis\u00f6': u'organization', + u'osoite': u'address', + u'yhteystiedot': u'contact', + u'versio': u'version', + u'vedos': u'revision', + u'tila': u'status', + u'p\u00e4iv\u00e4ys': u'date', + u'tekij\u00e4noikeudet': u'copyright', + u'omistuskirjoitus': u'dedication', + u'tiivistelm\u00e4': u'abstract'} +"""Finnish (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/fi.py b/docutils/parsers/rst/languages/fi.py new file mode 100644 index 000000000..fda7b5af1 --- /dev/null +++ b/docutils/parsers/rst/languages/fi.py @@ -0,0 +1,91 @@ +# Author: Asko Soukka +# Contact: asko.soukka@iki.fi +# 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. + +""" +Finnish-language mappings for language-dependent features of +reStructuredText. +""" + +__docformat__ = 'reStructuredText' + + +directives = { + # language-dependent: fixed + u'huomio': u'attention', + u'varo': u'caution', + u'vaara': u'danger', + u'virhe': u'error', + u'vihje': u'hint', + u't\u00e4rke\u00e4\u00e4': u'important', + u'huomautus': u'note', + u'neuvo': u'tip', + u'varoitus': u'warning', + u'kehotus': u'admonition', + u'sivupalkki': u'sidebar', + u'aihe': u'topic', + u'rivi': u'line-block', + u'tasalevyinen': u'parsed-literal', + u'ohje': u'rubric', + u'epigraafi': u'epigraph', + u'kohokohdat': u'highlights', + u'lainaus': u'pull-quote', + u'taulukko': u'table', + u'csv-taulukko': u'csv-table', + #u'kysymykset': u'questions', + u'meta': u'meta', + #u'kuvakartta': u'imagemap', + u'kuva': u'image', + u'kaavio': u'figure', + u'sis\u00e4llyt\u00e4': u'include', + u'raaka': u'raw', + u'korvaa': u'replace', + u'unicode': u'unicode', + u'luokka': u'class', + u'rooli': u'role', + u'sis\u00e4llys': u'contents', + u'kappale': u'sectnum', + #u'alaviitteet': u'footnotes', + #u'viitaukset': u'citations', + u'target-notes': u'target-notes', + u'restructuredtext-test-directive': u'restructuredtext-test-directive'} +"""Finnish name to registered (in directives/__init__.py) directive name +mapping.""" + +roles = { + # language-dependent: fixed + u'lyhennys': u'abbreviation', + u'akronyymi': u'acronym', + u'kirjainsana': u'acronym', + u'hakemisto': u'index', + u'luettelo': u'index', + u'alaindeksi': u'subscript', + u'indeksi': u'subscript', + u'yl\u00e4indeksi': u'superscript', + u'title-reference': u'title-reference', + u'title': u'title-reference', + u'pep-reference': u'pep-reference', + u'pep': u'pep-reference', + u'rfc-reference': u'rfc-reference', + u'rfc': u'rfc-reference', + u'korostus': u'emphasis', + u'vahvistus': u'strong', + u'tasalevyinen': u'literal', + u'named-reference': u'named-reference', + u'anonymous-reference': u'anonymous-reference', + u'footnote-reference': u'footnote-reference', + u'citation-reference': u'citation-reference', + u'substitution-reference': u'substitution-reference', + u'kohde': u'target', + u'uri-reference': u'uri-reference', + u'uri': u'uri-reference', + u'url': u'uri-reference',} +"""Mapping of Finnish role names to canonical role names for interpreted text. +""" -- cgit v1.2.1 From 051f028f8d263ef3db69ffe83a689e92bf9408d1 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 11 Sep 2004 16:05:04 +0000 Subject: ripped out unnecessary stuff, added "(translation required)" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2571 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/fi.py | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/fi.py b/docutils/parsers/rst/languages/fi.py index fda7b5af1..0eeefff19 100644 --- a/docutils/parsers/rst/languages/fi.py +++ b/docutils/parsers/rst/languages/fi.py @@ -54,8 +54,7 @@ directives = { u'kappale': u'sectnum', #u'alaviitteet': u'footnotes', #u'viitaukset': u'citations', - u'target-notes': u'target-notes', - u'restructuredtext-test-directive': u'restructuredtext-test-directive'} + u'target-notes (translation required)': u'target-notes'} """Finnish name to registered (in directives/__init__.py) directive name mapping.""" @@ -69,23 +68,19 @@ roles = { u'alaindeksi': u'subscript', u'indeksi': u'subscript', u'yl\u00e4indeksi': u'superscript', - u'title-reference': u'title-reference', - u'title': u'title-reference', - u'pep-reference': u'pep-reference', - u'pep': u'pep-reference', - u'rfc-reference': u'rfc-reference', - u'rfc': u'rfc-reference', + u'title-reference (translation required)': u'title-reference', + u'title (translation required)': u'title-reference', + u'pep-reference (translation required)': u'pep-reference', + u'rfc-reference (translation required)': u'rfc-reference', u'korostus': u'emphasis', u'vahvistus': u'strong', u'tasalevyinen': u'literal', - u'named-reference': u'named-reference', - u'anonymous-reference': u'anonymous-reference', - u'footnote-reference': u'footnote-reference', - u'citation-reference': u'citation-reference', - u'substitution-reference': u'substitution-reference', + u'named-reference (translation required)': u'named-reference', + u'anonymous-reference (translation required)': u'anonymous-reference', + u'footnote-reference (translation required)': u'footnote-reference', + u'citation-reference (translation required)': u'citation-reference', + u'substitution-reference (translation required)': u'substitution-reference', u'kohde': u'target', - u'uri-reference': u'uri-reference', - u'uri': u'uri-reference', - u'url': u'uri-reference',} + u'uri-reference (translation required)': u'uri-reference', """Mapping of Finnish role names to canonical role names for interpreted text. """ -- cgit v1.2.1 From 74e3459ee5404626d2f5267d4d1e6da939df0dcb Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 11 Sep 2004 17:11:02 +0000 Subject: typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2572 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/de.py | 82 ++++++++++++++++++------------------ docutils/parsers/rst/languages/fi.py | 2 +- 2 files changed, 41 insertions(+), 43 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index 90eb77bdb..e6fcaaa1f 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -1,5 +1,4 @@ -# -*- coding: iso-8859-1 -*- -# Author: Engelbert Gruber +# Authors: Engelbert Gruber; Felix Wiemann # Contact: grubert@users.sourceforge.net # Revision: $Revision$ # Date: $Date$ @@ -26,61 +25,60 @@ directives = { 'hinweis': 'hint', 'wichtig': 'important', 'notiz': 'note', - 'tip': 'tip', + 'tipp': 'tip', 'warnung': 'warning', 'ermahnung': 'admonition', - 'kasten': 'sidebar', # seitenkasten ? - 'thema': 'topic', - 'line-block': 'line-block', - 'parsed-literal': 'parsed-literal', + 'kasten': 'sidebar', + 'seitenkasten': 'sidebar', + 'thema': 'topic', + 'zeilen-block': 'line-block', + 'parsed-literal (translation required)': 'parsed-literal', 'rubrik': 'rubric', - 'epigraph (translation required)': 'epigraph', + 'epigraph': 'epigraph', 'highlights (translation required)': 'highlights', 'pull-quote (translation required)': 'pull-quote', # kasten too ? - #'questions': 'questions', - #'qa': 'questions', - #'faq': 'questions', - 'table (translation required)': 'table', - 'csv-table (translation required)': 'csv-table', + #'fragen': 'questions', + 'tabelle': 'table', + 'csv-tabelle': 'csv-table', 'meta': 'meta', #'imagemap': 'imagemap', 'bild': 'image', 'abbildung': 'figure', - 'raw': 'raw', # unbearbeitet - 'include': 'include', # einfgen, "fge ein" would be more like a command. - # einfgung would be the noun. - 'ersetzung': 'replace', # ersetzen, ersetze + u'unver\xe4ndert': 'raw', + u'einf\xfcgen': 'include', + 'ersetzen': 'replace', + 'ersetze': 'replace', 'unicode': 'unicode', - 'klasse': 'class', # offer "class" too ? - 'role (translation required)': 'role', + 'klasse': 'class', + 'rolle': 'role', 'inhalt': 'contents', - 'sectnum': 'sectnum', - 'section-numbering': 'sectnum', - 'target-notes': 'target-notes', - #'footnotes': 'footnotes', - #'citations': 'citations', - 'restructuredtext-test-directive': 'restructuredtext-test-directive'} + 'kapitel-nummerierung': 'sectnum', + 'abschnitts-nummerierung': 'sectnum', + u'linkziel-fu\xdfnoten': 'target-notes', + #u'fu\xdfnoten': 'footnotes', + #'zitate': 'citations', + } """German name to registered (in directives/__init__.py) directive name mapping.""" roles = { - 'abbreviation (translation required)': 'abbreviation', - 'acronym (translation required)': 'acronym', - 'index (translation required)': 'index', - 'subscript (translation required)': 'subscript', - 'superscript (translation required)': 'superscript', - 'title-reference (translation required)': 'title-reference', - 'pep-reference (translation required)': 'pep-reference', - 'rfc-reference (translation required)': 'rfc-reference', - 'emphasis (translation required)': 'emphasis', - 'strong (translation required)': 'strong', + u'abk\xfcrzung': 'abbreviation', + 'akronym': 'acronym', + 'index': 'index', + 'tiefgestellt': 'subscript', + 'hochgestellt': 'superscript', + 'titel-referenz': 'title-reference', + 'pep-referenz': 'pep-reference', + 'rfc-referenz': 'rfc-reference', + 'betonung': 'emphasis', + 'fett': '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',} + 'benannte-referenz': 'named-reference', + 'unbenannte-referenz': 'anonymous-reference', + u'fu\xdfnoten-referenz': 'footnote-reference', + 'zitat-referenz': 'citation-reference', + 'ersetzungs-referenz': 'substitution-reference', + 'ziel': 'target', + 'uri-referenz': 'uri-reference',} """Mapping of German role names to canonical role names for interpreted text. """ diff --git a/docutils/parsers/rst/languages/fi.py b/docutils/parsers/rst/languages/fi.py index 0eeefff19..269a41d1e 100644 --- a/docutils/parsers/rst/languages/fi.py +++ b/docutils/parsers/rst/languages/fi.py @@ -81,6 +81,6 @@ roles = { u'citation-reference (translation required)': u'citation-reference', u'substitution-reference (translation required)': u'substitution-reference', u'kohde': u'target', - u'uri-reference (translation required)': u'uri-reference', + u'uri-reference (translation required)': u'uri-reference'} """Mapping of Finnish role names to canonical role names for interpreted text. """ -- cgit v1.2.1 From 2098f68d0d25262d21a2db2c7c91164052cdd004 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 11 Sep 2004 17:41:18 +0000 Subject: don't delete anything without a good reason git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2574 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/de.py | 1 + 1 file changed, 1 insertion(+) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index e6fcaaa1f..d8dedffd2 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -46,6 +46,7 @@ directives = { 'abbildung': 'figure', u'unver\xe4ndert': 'raw', u'einf\xfcgen': 'include', + 'ersetzung': 'replace', 'ersetzen': 'replace', 'ersetze': 'replace', 'unicode': 'unicode', -- cgit v1.2.1 From 2dc8803c87df3de126a36ef3b4aa76c9b65cac93 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 11 Sep 2004 21:25:53 +0000 Subject: added dispatcher git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2578 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index aed0c2c28..5cadb2c0b 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -107,11 +107,10 @@ class Node: 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.document.reporter.debug(name, category='nodes.Node.walk') + visitor.document.reporter.debug(self.__class__.__name__, + category='nodes.Node.walk') try: - method(self) + visitor.dispatch_visit(self, self.__class__.__name__) except (SkipChildren, SkipNode): return except SkipDeparture: # not applicable; ignore @@ -134,12 +133,11 @@ class Node: and ``depart_...`` methods for each `Node` subclass encountered. """ call_depart = 1 - name = 'visit_' + self.__class__.__name__ - method = getattr(visitor, name, visitor.unknown_visit) - visitor.document.reporter.debug(name, category='nodes.Node.walkabout') + visitor.document.reporter.debug(self.__class__.__name__, + category='nodes.Node.walkabout') try: try: - method(self) + visitor.dispatch_visit(self, self.__class__.__name__) except SkipNode: return except SkipDeparture: @@ -153,11 +151,9 @@ class Node: except SkipChildren: pass 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) + visitor.document.reporter.debug(self.__class__.__name__, + category='nodes.Node.walkabout') + visitor.dispatch_depart(self, self.__class__.__name__) class Text(Node, UserString): @@ -1275,6 +1271,14 @@ class NodeVisitor: def __init__(self, document): self.document = document + def dispatch_visit(self, node, method_name): + method = getattr(self, 'visit_' + method_name, self.unknown_visit) + return method(node) + + def dispatch_depart(self, node, method_name): + method = getattr(self, 'depart_' + method_name, self.unknown_departure) + return method(node) + def unknown_visit(self, node): """ Called when entering unknown `Node` types. -- cgit v1.2.1 From dfe81952acfa433c01bc66ad39bd4551d788698c Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 11 Sep 2004 22:21:55 +0000 Subject: reindented git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2579 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index d848551ff..f30f727cc 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -124,20 +124,20 @@ class Writer(writers.Writer): ['--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'], + ('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'} -- cgit v1.2.1 From 6169af74cff72a6fd0074fec9d1f5380e5952e00 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 11 Sep 2004 22:22:39 +0000 Subject: typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2580 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index f30f727cc..77ac60392 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -130,7 +130,7 @@ class Writer(writers.Writer): 'Default is no option.', ['--graphicx-option'], {'default': ''}), - ('LaTeX font encoding.' + ('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 ' -- cgit v1.2.1 From bc0fe1c8ff7aabfef06ac27413b8f131b5671be9 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 11 Sep 2004 22:23:32 +0000 Subject: added --call-class-command git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2581 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 77ac60392..6005ef892 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -137,7 +137,12 @@ class Writer(writers.Writer): 'emulation using CM fonts).', ['--font-encoding'], {'default': ''}), - ),) + ('Causes \\docutilsclass to be called for every node which has the ' + 'class attribute set. Default: disabled', + ['--call-class-command'], + {'default': 0, 'action': 'store_true', + 'validator': frontend.validate_boolean}), + ),) settings_defaults = {'output_encoding': 'latin-1'} @@ -504,6 +509,22 @@ class Table: class LaTeXTranslator(nodes.NodeVisitor): + + def dispatch_visit(self, node, method_name): + if self.call_class and \ + isinstance(node, nodes.Element) and \ + node.hasattr('class'): + self.body.append('\\docutilsclass{%s}{' % node.get('class')) + return nodes.NodeVisitor.dispatch_visit(self, node, method_name) + + def dispatch_depart(self, node, method_name): + r = nodes.NodeVisitor.dispatch_depart(self, node, method_name) + if self.call_class and \ + isinstance(node, nodes.Element) and \ + node.hasattr('class'): + self.body.append('}') + return r + # 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 @@ -556,6 +577,11 @@ class LaTeXTranslator(nodes.NodeVisitor): self.colorlinks = 'false' else: self.colorlinks = 'true' + self.call_class = settings.call_class_command + if self.call_class: + self.docutilsclass = '\\newcommand{\\docutilsclass}[2]{#2}\n' + else: + self.docutilsclass = '' # language: labels, bibliographic_fields, and author_separators. # to allow writing labes for specific languages. @@ -641,6 +667,7 @@ class LaTeXTranslator(nodes.NodeVisitor): # of linewidth, this is fixing it. '\\newlength{\\locallinewidth}\n', # will be set later. + self.docutilsclass, ] self.head_prefix.extend( latex_headings['optionlist_environment'] ) self.head_prefix.extend( latex_headings['footnote_floats'] ) -- cgit v1.2.1 From 6ccd5bb93592406d733a0a926e7a262fe81abcd5 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 12 Sep 2004 13:08:35 +0000 Subject: re-added visit_ and depart_ to debug output, changed method name to match the rest git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2583 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 5cadb2c0b..cbe24240d 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -107,7 +107,7 @@ class Node: Parameter `visitor`: A `NodeVisitor` object, containing a ``visit_...`` method for each `Node` subclass encountered. """ - visitor.document.reporter.debug(self.__class__.__name__, + visitor.document.reporter.debug('visit_' + self.__class__.__name__, category='nodes.Node.walk') try: visitor.dispatch_visit(self, self.__class__.__name__) @@ -133,7 +133,7 @@ class Node: and ``depart_...`` methods for each `Node` subclass encountered. """ call_depart = 1 - visitor.document.reporter.debug(self.__class__.__name__, + visitor.document.reporter.debug('visit_' + self.__class__.__name__, category='nodes.Node.walkabout') try: try: @@ -151,9 +151,10 @@ class Node: except SkipChildren: pass if call_depart: - visitor.document.reporter.debug(self.__class__.__name__, - category='nodes.Node.walkabout') - visitor.dispatch_depart(self, self.__class__.__name__) + visitor.document.reporter.debug( + 'depart_' + self.__class__.__name__, + category='nodes.Node.walkabout') + visitor.dispatch_departure(self, self.__class__.__name__) class Text(Node, UserString): @@ -1275,7 +1276,7 @@ class NodeVisitor: method = getattr(self, 'visit_' + method_name, self.unknown_visit) return method(node) - def dispatch_depart(self, node, method_name): + def dispatch_departure(self, node, method_name): method = getattr(self, 'depart_' + method_name, self.unknown_departure) return method(node) -- cgit v1.2.1 From 9a8200466f4f502f8cfc468c0b4f3c4f1227f247 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 12 Sep 2004 16:22:03 +0000 Subject: added some missing self.encode()s git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2585 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 6005ef892..95079fd04 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1057,10 +1057,9 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_colspec(self, node): pass - def visit_comment(self, node, - sub=re.compile('\n').sub): - """Escape end of line by a ne comment start in comment text.""" - self.body.append('%% %s \n' % sub('\n% ', node.astext())) + 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_contact(self, node): @@ -1344,7 +1343,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_field_body(self, node): # BUG by attach as text we loose references. if self.docinfo: - self.docinfo.append('%s \\\\\n' % node.astext()) + self.docinfo.append('%s \\\\\n' % self.encode(node.astext())) raise nodes.SkipNode # BUG: what happens if not docinfo @@ -1364,7 +1363,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_field_name(self, node): # BUG this duplicates docinfo_item if self.docinfo: - self.docinfo.append('\\textbf{%s}: &\n\t' % node.astext()) + self.docinfo.append('\\textbf{%s}: &\n\t' % self.encode(node.astext())) raise nodes.SkipNode else: self.body.append('\\item [') @@ -1939,7 +1938,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.context.append('}\n\\smallskip\n') elif isinstance(node.parent, nodes.table): # caption must be written after column spec - self.active_table.caption = node.astext() + self.active_table.caption = self.encode(node.astext()) raise nodes.SkipNode elif self.section_level == 0: # document title -- cgit v1.2.1 From dabc9aa76be60ffea41afc00b33103307d54d59a Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 12 Sep 2004 20:43:32 +0000 Subject: reverted rev1.3 (Unicode check for CSV table) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2587 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 9 --------- 1 file changed, 9 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 787278b3e..e34e54b20 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -13,7 +13,6 @@ __docformat__ = 'reStructuredText' import sys import os.path -from types import UnicodeType from docutils import nodes, statemachine, utils from docutils.utils import SystemMessagePropagation from docutils.parsers.rst import directives @@ -247,18 +246,10 @@ def process_header_option(options, state_machine, lineno): return table_head, max_header_cols def parse_csv_data_into_rows(csv_data, dialect, source, options): - isunicode = (csv_data and type(csv_data[0]) == UnicodeType) - if isunicode: - # Encode unicode in UTF-8, because the csv module doesn't - # support unicode strings. - csv_data = [item.encode('utf-8') for item in csv_data] csv_reader = csv.reader(csv_data, dialect=dialect) rows = [] max_cols = 0 for row in csv_reader: - if isunicode: - # Decode UTF-8 back to unicode - row = [item.decode('utf-8') for item in row] row_data = [] for cell in row: cell_data = (0, 0, 0, statemachine.StringList(cell.splitlines(), -- cgit v1.2.1 From 82924f762267c60ed71fd26c87e1fa533a2f1882 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 12 Sep 2004 21:13:54 +0000 Subject: Added "encoding" directive to "csv-table" directive. Added workaround for lack of Unicode support in csv.py, for non-ASCII CSV input. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2588 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index e34e54b20..1966d2ab2 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -13,7 +13,7 @@ __docformat__ = 'reStructuredText' import sys import os.path -from docutils import nodes, statemachine, utils +from docutils import io, nodes, statemachine, utils from docutils.utils import SystemMessagePropagation from docutils.parsers.rst import directives @@ -154,6 +154,7 @@ csv_table.options = {'header-rows': directives.nonnegative_int, 'widths': directives.positive_int_list, 'file': directives.path, 'url': directives.path, + 'encoding': directives.encoding, 'class': directives.class_option, # field delimiter char 'delim': directives.single_char_or_whitespace_or_unicode, @@ -180,6 +181,7 @@ def get_csv_data(name, options, content, lineno, block_text, CSV data can come from the directive content, from an external file, or from a URL reference. """ + encoding = options.get('encoding', state.document.settings.input_encoding) if content: # CSV data is from directive content if options.has_key('file') or options.has_key('url'): error = state_machine.reporter.error( @@ -201,11 +203,9 @@ def get_csv_data(name, options, content, lineno, block_text, source = os.path.normpath(os.path.join(source_dir, options['file'])) source = utils.relative_path(None, source) try: - csv_file = open(source, 'rb') - try: - csv_data = csv_file.read().splitlines() - finally: - csv_file.close() + csv_file = io.FileInput(source_path=source, encoding=encoding, + handle_io_errors=None) + csv_data = csv_file.read().splitlines() except IOError, error: severe = state_machine.reporter.severe( 'Problems with "%s" directive path:\n%s.' % (name, error), @@ -221,13 +221,16 @@ def get_csv_data(name, options, content, lineno, block_text, raise SystemMessagePropagation(severe) source = options['url'] try: - csv_data = urllib2.urlopen(source).read().splitlines() + csv_text = urllib2.urlopen(source).read() except (urllib2.URLError, IOError, OSError, ValueError), 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) raise SystemMessagePropagation(severe) + csv_file = io.StringInput(source=csv_text, source_path=source, + encoding=encoding) + csv_data = csv_file.read().splitlines() else: error = state_machine.reporter.warning( 'The "%s" directive requires content; none supplied.' % (name), @@ -246,14 +249,18 @@ def process_header_option(options, state_machine, lineno): return table_head, max_header_cols def parse_csv_data_into_rows(csv_data, dialect, source, options): - csv_reader = csv.reader(csv_data, dialect=dialect) + # csv.py doesn't do Unicode; encode temporarily as UTF-8 + csv_reader = csv.reader([line.encode('utf-8') for line in csv_data], + dialect=dialect) rows = [] max_cols = 0 for row in csv_reader: row_data = [] for cell in row: - cell_data = (0, 0, 0, statemachine.StringList(cell.splitlines(), - source=source)) + # decode UTF-8 back to Unicode + cell_text = unicode(cell, 'utf-8') + cell_data = (0, 0, 0, statemachine.StringList( + cell_text.splitlines(), source=source)) row_data.append(cell_data) rows.append(row_data) max_cols = max(max_cols, len(row)) -- cgit v1.2.1 From 2f3ac3cb4695c82cb36fc32bf88bfb9f22aca6ff Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 12 Sep 2004 21:14:54 +0000 Subject: Added --input-encoding-error-handler option & setting. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2589 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 412a1b5ad..87f3377fb 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -352,9 +352,19 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): ('Disable Python tracebacks when errors occur; report just the error ' 'instead. This is the default.', ['--no-traceback'], {'dest': 'traceback', 'action': 'store_false'}), - ('Specify the encoding of input text. Default is locale-dependent.', + ('Specify the encoding of input text. Default is locale-dependent. ' + 'Optionally also specify the error handler for undecodable ' + 'characters, after a colon (":"); default is "strict". (See ' + '"--intput-encoding-error-handler".)', ['--input-encoding', '-i'], - {'metavar': '', 'validator': validate_encoding}), + {'metavar': '', + 'validator': validate_encoding_and_error_handler}), + ('Specify the error handler for undecodable characters in ' + 'the input. Acceptable values include "strict", "ignore", and ' + '"replace". Default is "strict". ' + 'Usually specified as part of --input-encoding.', + ['--input-encoding-error-handler'], + {'default': 'strict', 'validator': validate_encoding_error_handler}), ('Specify the text encoding for output. Default is UTF-8. ' 'Optionally also specify the error handler for unencodable ' 'characters, after a colon (":"); default is "strict". (See ' -- cgit v1.2.1 From c0ad19fd7049a24b3f4a4ca8a1090fbc4a3834ed Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 12 Sep 2004 21:15:22 +0000 Subject: Added support for input encoding error handler. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2590 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index 45cecdf08..d1117d8a7 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -30,10 +30,14 @@ class Input(TransformSpec): default_source_path = None - def __init__(self, source=None, source_path=None, encoding=None): + def __init__(self, source=None, source_path=None, encoding=None, + error_handler='strict'): self.encoding = encoding """Text encoding for the input source.""" + self.error_handler = error_handler + """Text decoding error handler.""" + self.source = source """The source of input data.""" @@ -43,6 +47,9 @@ class Input(TransformSpec): if not source_path: self.source_path = self.default_source_path + self.successful_encoding = None + """The encoding that successfully decoded the source data.""" + def __repr__(self): return '%s: source=%r, source_path=%r' % (self.__class__, self.source, self.source_path) @@ -62,7 +69,7 @@ class Input(TransformSpec): """ if (self.encoding and self.encoding.lower() == 'unicode' or isinstance(data, UnicodeType)): - return unicode(data) + return data encodings = [self.encoding, 'utf-8'] try: encodings.append(locale.nl_langinfo(locale.CODESET)) @@ -81,7 +88,9 @@ class Input(TransformSpec): if not enc: continue try: - return unicode(data, enc) + decoded = unicode(data, enc, self.error_handler) + self.successful_encoding = enc + return decoded except (UnicodeError, LookupError): pass raise UnicodeError( @@ -156,16 +165,20 @@ class FileInput(Input): """ def __init__(self, source=None, source_path=None, - encoding=None, autoclose=1, handle_io_errors=1): + encoding=None, error_handler='strict', + autoclose=1, handle_io_errors=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. + - `encoding`: the expected text encoding of the input file. + - `error_handler`: the encoding error handler to use. - `autoclose`: close automatically after read (boolean); always false if `sys.stdin` is the source. + - `handle_io_errors`: summarize I/O errors here, and exit? """ - Input.__init__(self, source, source_path, encoding) + Input.__init__(self, source, source_path, encoding, error_handler) self.autoclose = autoclose self.handle_io_errors = handle_io_errors if source is None: @@ -194,9 +207,11 @@ class FileInput(Input): """ Read and decode a single file and return the data (Unicode string). """ - data = self.source.read() - if self.autoclose: - self.close() + try: + data = self.source.read() + finally: + if self.autoclose: + self.close() return self.decode(data) def close(self): @@ -257,9 +272,11 @@ class FileOutput(Output): output = self.encode(data) if not self.opened: self.open() - self.destination.write(output) - if self.autoclose: - self.close() + try: + self.destination.write(output) + finally: + if self.autoclose: + self.close() return output def close(self): -- cgit v1.2.1 From 486cd90ec8205d8dea974222199278edcaeb959c Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 12 Sep 2004 21:15:48 +0000 Subject: Added dispatch_visit and dispatch_departure methods to NodeVisitor; useful as a hook for Visitors. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2591 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index cbe24240d..ecc301300 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -107,8 +107,9 @@ class Node: Parameter `visitor`: A `NodeVisitor` object, containing a ``visit_...`` method for each `Node` subclass encountered. """ - visitor.document.reporter.debug('visit_' + self.__class__.__name__, - category='nodes.Node.walk') + visitor.document.reporter.debug( + 'calling dispatch_visit for %s' % self.__class__.__name__, + category='nodes.Node.walk') try: visitor.dispatch_visit(self, self.__class__.__name__) except (SkipChildren, SkipNode): @@ -133,11 +134,12 @@ class Node: and ``depart_...`` methods for each `Node` subclass encountered. """ call_depart = 1 - visitor.document.reporter.debug('visit_' + self.__class__.__name__, - category='nodes.Node.walkabout') + visitor.document.reporter.debug( + 'calling dispatch_visit for %s' % self.__class__.__name__, + category='nodes.Node.walkabout') try: try: - visitor.dispatch_visit(self, self.__class__.__name__) + visitor.dispatch_visit(self) except SkipNode: return except SkipDeparture: @@ -152,9 +154,9 @@ class Node: pass if call_depart: visitor.document.reporter.debug( - 'depart_' + self.__class__.__name__, + 'calling dispatch_departure for %s' % self.__class__.__name__, category='nodes.Node.walkabout') - visitor.dispatch_departure(self, self.__class__.__name__) + visitor.dispatch_departure(self) class Text(Node, UserString): @@ -1272,12 +1274,20 @@ class NodeVisitor: def __init__(self, document): self.document = document - def dispatch_visit(self, node, method_name): - method = getattr(self, 'visit_' + method_name, self.unknown_visit) + def dispatch_visit(self, node): + 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') return method(node) - def dispatch_departure(self, node, method_name): + def dispatch_departure(self, node): + node_name = node.__class__.__name__ method = getattr(self, 'depart_' + method_name, self.unknown_departure) + self.document.reporter.debug( + 'calling %s for %s' % (method.__name__, node_name), + category='nodes.NodeVisitor.dispatch_departure') return method(node) def unknown_visit(self, node): -- cgit v1.2.1 From 5cf52a0232f6f46fee60577e205a273082efea85 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 12 Sep 2004 21:16:37 +0000 Subject: Added ``encoding`` directive option conversion function. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2592 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index f10d42cec..bd8f84e8a 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -85,6 +85,7 @@ See `Creating reStructuredText Directives`_ for more information. __docformat__ = 'reStructuredText' import re +import codecs from docutils import nodes from docutils.parsers.rst.languages import en as _fallback_language_module @@ -339,9 +340,12 @@ def positive_int_list(argument): entries = argument.split() return [positive_int(entry) for entry in entries] -def format_values(values): - return '%s, or "%s"' % (', '.join(['"%s"' % s for s in values[:-1]]), - values[-1]) +def encoding(argument): + try: + codecs.lookup(argument) + except LookupError: + raise ValueError('unknown encoding: "%s"' % argument) + return argument def choice(argument, values): """ @@ -368,3 +372,7 @@ def choice(argument, values): else: raise ValueError('"%s" unknown; choose from %s' % (argument, format_values(values))) + +def format_values(values): + return '%s, or "%s"' % (', '.join(['"%s"' % s for s in values[:-1]]), + values[-1]) -- cgit v1.2.1 From 1a6a5138cc6fe3ede8e5ef7f6ff62cbb9e064128 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 12 Sep 2004 21:17:03 +0000 Subject: Added "encoding" option to "include" and "raw" directives. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2593 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index d6aa39ae7..8411f36c8 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -35,10 +35,10 @@ def include(name, arguments, options, content, lineno, return [error] 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) try: include_file = io.FileInput( - source_path=path, encoding=state.document.settings.input_encoding, - handle_io_errors=None) + source_path=path, encoding=encoding, handle_io_errors=None) except IOError, error: severe = state_machine.reporter.severe( 'Problems with "%s" directive path:\n%s: %s.' @@ -71,6 +71,7 @@ def raw(name, arguments, options, content, lineno, imported from a file or url. """ attributes = {'format': arguments[0]} + encoding = options.get('encoding', state.document.settings.input_encoding) if content: if options.has_key('file') or options.has_key('url'): error = state_machine.reporter.error( @@ -91,14 +92,13 @@ def raw(name, arguments, options, content, lineno, path = os.path.normpath(os.path.join(source_dir, options['file'])) path = utils.relative_path(None, path) try: - raw_file = open(path) + raw_file = io.FileInput(source_path=path, encoding=encoding) 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'] = path elif options.has_key('url'): if not urllib2: @@ -108,17 +108,19 @@ def raw(name, arguments, options, content, lineno, '"urllib2" module).' % name, nodes.literal_block(block_text, block_text), line=lineno) return [severe] + source = options['url'] try: - raw_file = urllib2.urlopen(options['url']) + raw_text = urllib2.urlopen(source).read() except (urllib2.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] + raw_file = io.StringInput(source=raw_text, source_path=source, + encoding=encoding) text = raw_file.read() - raw_file.close() - attributes['source'] = options['file'] + attributes['source'] = source else: error = state_machine.reporter.warning( 'The "%s" directive requires content; none supplied.' % (name), -- cgit v1.2.1 From 439e10c3dc34a84fe174a288bfbefd7491c9f070 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 12 Sep 2004 21:18:45 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2594 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 95079fd04..1aa8a5ce8 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -510,14 +510,14 @@ class Table: class LaTeXTranslator(nodes.NodeVisitor): - def dispatch_visit(self, node, method_name): + def dispatch_visit(self, node): if self.call_class and \ isinstance(node, nodes.Element) and \ node.hasattr('class'): self.body.append('\\docutilsclass{%s}{' % node.get('class')) return nodes.NodeVisitor.dispatch_visit(self, node, method_name) - def dispatch_depart(self, node, method_name): + def dispatch_depart(self, node): r = nodes.NodeVisitor.dispatch_depart(self, node, method_name) if self.call_class and \ isinstance(node, nodes.Element) and \ -- cgit v1.2.1 From 06c8efa5fb4532548d80dbbd29b2953ca6e62f52 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 12 Sep 2004 21:22:54 +0000 Subject: fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2596 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index ecc301300..d7784e1b1 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -111,7 +111,7 @@ class Node: 'calling dispatch_visit for %s' % self.__class__.__name__, category='nodes.Node.walk') try: - visitor.dispatch_visit(self, self.__class__.__name__) + visitor.dispatch_visit(self) except (SkipChildren, SkipNode): return except SkipDeparture: # not applicable; ignore -- cgit v1.2.1 From 095c3f83f75c45a712e7925b2b770b4f2e6c2452 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 12 Sep 2004 21:29:25 +0000 Subject: fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2597 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 2 +- docutils/writers/latex2e.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index d7784e1b1..8824f6e5f 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1284,7 +1284,7 @@ class NodeVisitor: def dispatch_departure(self, node): node_name = node.__class__.__name__ - method = getattr(self, 'depart_' + method_name, self.unknown_departure) + 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') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 1aa8a5ce8..39c8a9688 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -515,10 +515,10 @@ class LaTeXTranslator(nodes.NodeVisitor): isinstance(node, nodes.Element) and \ node.hasattr('class'): self.body.append('\\docutilsclass{%s}{' % node.get('class')) - return nodes.NodeVisitor.dispatch_visit(self, node, method_name) + return nodes.NodeVisitor.dispatch_visit(self, node) def dispatch_depart(self, node): - r = nodes.NodeVisitor.dispatch_depart(self, node, method_name) + r = nodes.NodeVisitor.dispatch_depart(self, node) if self.call_class and \ isinstance(node, nodes.Element) and \ node.hasattr('class'): -- cgit v1.2.1 From 09522775bb77029bc2a4cbfbbde5ebe5e43fabe1 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 13 Sep 2004 00:18:57 +0000 Subject: added input_encoding_error_handler to external file processing (include, raw, csv-table directives) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2598 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 15 +++++++++++---- docutils/parsers/rst/directives/tables.py | 11 +++++++---- 2 files changed, 18 insertions(+), 8 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 8411f36c8..599582acd 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -38,7 +38,9 @@ def include(name, arguments, options, content, lineno, encoding = options.get('encoding', state.document.settings.input_encoding) try: include_file = io.FileInput( - source_path=path, encoding=encoding, handle_io_errors=None) + source_path=path, encoding=encoding, + error_handler=state.document.settings.input_encoding_error_handler, + handle_io_errors=None) except IOError, error: severe = state_machine.reporter.severe( 'Problems with "%s" directive path:\n%s: %s.' @@ -72,6 +74,7 @@ def raw(name, arguments, options, content, lineno, """ attributes = {'format': arguments[0]} encoding = options.get('encoding', state.document.settings.input_encoding) + error_handler = state.document.settings.input_encoding_error_handler if content: if options.has_key('file') or options.has_key('url'): error = state_machine.reporter.error( @@ -92,7 +95,10 @@ def raw(name, arguments, options, content, lineno, path = os.path.normpath(os.path.join(source_dir, options['file'])) path = utils.relative_path(None, path) try: - raw_file = io.FileInput(source_path=path, encoding=encoding) + raw_file = io.FileInput( + source_path=path, encoding=encoding, + error_handler=state.document.settings.input_encoding_error_handler, + handle_io_errors=None) except IOError, error: severe = state_machine.reporter.severe( 'Problems with "%s" directive path:\n%s.' % (name, error), @@ -117,8 +123,9 @@ def raw(name, arguments, options, content, lineno, % (name, options['url'], error), nodes.literal_block(block_text, block_text), line=lineno) return [severe] - raw_file = io.StringInput(source=raw_text, source_path=source, - encoding=encoding) + raw_file = io.StringInput( + source=raw_text, source_path=source, encoding=encoding, + error_handler=state.document.settings.input_encoding_error_handler) text = raw_file.read() attributes['source'] = source else: diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 1966d2ab2..104a99480 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -203,8 +203,10 @@ def get_csv_data(name, options, content, lineno, block_text, source = os.path.normpath(os.path.join(source_dir, options['file'])) source = utils.relative_path(None, source) try: - csv_file = io.FileInput(source_path=source, encoding=encoding, - handle_io_errors=None) + csv_file = io.FileInput( + source_path=source, encoding=encoding, + error_handler=state.document.settings.input_encoding_error_handler, + handle_io_errors=None) csv_data = csv_file.read().splitlines() except IOError, error: severe = state_machine.reporter.severe( @@ -228,8 +230,9 @@ def get_csv_data(name, options, content, lineno, block_text, % (name, options['url'], error), nodes.literal_block(block_text, block_text), line=lineno) raise SystemMessagePropagation(severe) - csv_file = io.StringInput(source=csv_text, source_path=source, - encoding=encoding) + csv_file = io.StringInput( + source=csv_text, source_path=source, encoding=encoding, + error_handler=state.document.settings.input_encoding_error_handler) csv_data = csv_file.read().splitlines() else: error = state_machine.reporter.warning( -- cgit v1.2.1 From 7531dff9a666b4291d8707d37954b1768b49e607 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 13 Sep 2004 00:24:38 +0000 Subject: removed unnecessary line git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2599 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 1 - 1 file changed, 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 599582acd..243340ea9 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -74,7 +74,6 @@ def raw(name, arguments, options, content, lineno, """ attributes = {'format': arguments[0]} encoding = options.get('encoding', state.document.settings.input_encoding) - error_handler = state.document.settings.input_encoding_error_handler if content: if options.has_key('file') or options.has_key('url'): error = state_machine.reporter.error( -- cgit v1.2.1 From b5ad3c68e65f62a13d6ddf0ee44b62c8e7448a4c Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 13 Sep 2004 13:18:53 +0000 Subject: HTMLTranslator.encode now converts U+00A0 to " " (thanks to Dave Kuhlman) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2600 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 4be9e9074..022a1973a 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -249,6 +249,8 @@ class HTMLTranslator(nodes.NodeVisitor): 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 attval(self, text, -- cgit v1.2.1 From fc086c0355a08866685ee9a058d29e391e778425 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 13 Sep 2004 18:50:33 +0000 Subject: added Traditional Chinese language files; thanks to Joe YS Jaw git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2607 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/zh_tw.py | 64 ++++++++++++++++++++++ docutils/parsers/rst/languages/zh_tw.py | 97 +++++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 docutils/languages/zh_tw.py create mode 100644 docutils/parsers/rst/languages/zh_tw.py (limited to 'docutils') diff --git a/docutils/languages/zh_tw.py b/docutils/languages/zh_tw.py new file mode 100644 index 000000000..73a0762fb --- /dev/null +++ b/docutils/languages/zh_tw.py @@ -0,0 +1,64 @@ +# Author: Joe YS Jaw +# Contact: joeysj@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. + +""" +Traditional Chinese language mappings for language-dependent features of Docutils. +""" + +__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' +} +"""Mapping of node class name to label text.""" + +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'} +"""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.""" diff --git a/docutils/parsers/rst/languages/zh_tw.py b/docutils/parsers/rst/languages/zh_tw.py new file mode 100644 index 000000000..faeeac54d --- /dev/null +++ b/docutils/parsers/rst/languages/zh_tw.py @@ -0,0 +1,97 @@ +# 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. + +""" +Traditional Chinese language mappings for language-dependent features of +reStructuredText. +""" + +__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', + #'questions': 'questions', + 'table': 'table', + 'csv-table': 'csv-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', + 'contents': 'contents', + 'sectnum': 'sectnum', + 'section-numbering': 'sectnum', + #'footnotes': 'footnotes', + #'citations': 'citations', + 'target-notes': 'target-notes', + 'restructuredtext-test-directive': 'restructuredtext-test-directive'} +"""English 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',} +"""Mapping of Traditional Chinese role names to canonical role names for interpreted text. +""" -- cgit v1.2.1 From 4dc8a6ebadef2cb445d8518a545a9c1690d5a414 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 13 Sep 2004 19:09:56 +0000 Subject: fixed link git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2608 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/zh_tw.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/languages/zh_tw.py b/docutils/languages/zh_tw.py index 73a0762fb..2035725c0 100644 --- a/docutils/languages/zh_tw.py +++ b/docutils/languages/zh_tw.py @@ -5,7 +5,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. -- cgit v1.2.1 From e2477e304e4417a049215d78485c8c2e9627f884 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 13 Sep 2004 19:25:33 +0000 Subject: fixed links git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2609 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/fi.py | 2 +- docutils/parsers/rst/languages/fi.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/languages/fi.py b/docutils/languages/fi.py index 365172a38..340b33acb 100644 --- a/docutils/languages/fi.py +++ b/docutils/languages/fi.py @@ -5,7 +5,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. diff --git a/docutils/parsers/rst/languages/fi.py b/docutils/parsers/rst/languages/fi.py index 269a41d1e..4ccdee84a 100644 --- a/docutils/parsers/rst/languages/fi.py +++ b/docutils/parsers/rst/languages/fi.py @@ -5,7 +5,7 @@ # 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 +# read . Two files must be # translated for each language: one in docutils/languages, the other in # docutils/parsers/rst/languages. -- cgit v1.2.1 From 21bd3819d2a31f02a42d74b040792ee1a56be199 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 14 Sep 2004 10:23:50 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2613 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 022a1973a..36bd1185b 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -54,9 +54,7 @@ class Writer(writers.Writer): 'validator': frontend.validate_boolean}), ('Embed the stylesheet in the output HTML file. The stylesheet ' 'file must be accessible during processing (--stylesheet-path is ' - 'recommended). The stylesheet is embedded inside a comment, so it ' - 'must not contain the text "--" (two hyphens). Default: link the ' - 'stylesheet, do not embed it.', + 'recommended). Default: link the stylesheet, do not embed it.', ['--embed-stylesheet'], {'action': 'store_true', 'validator': frontend.validate_boolean}), ('Specify the initial header level. Default is 1 for "

    ". ' -- cgit v1.2.1 From 63d8c7c72483af0c247ee6ae1636989a3311b2f1 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 14 Sep 2004 10:38:38 +0000 Subject: removed support for boolean attributes without value git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2614 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 36bd1185b..9608c5f57 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -278,12 +278,10 @@ class HTMLTranslator(nodes.NodeVisitor): attlist.sort() parts = [tagname] for name, value in attlist: - if value is None: # boolean attribute - # According to the HTML spec, ```` is good, - # ```` is bad. - # (But the XHTML (XML) spec says the opposite. ) - parts.append(name.lower()) - elif isinstance(value, ListType): + # 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)))) -- cgit v1.2.1 From 5e9286d6b86022daafaf9a977af03c6011b49597 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 14 Sep 2004 15:36:50 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2615 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 9608c5f57..a44606e5d 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -1138,9 +1138,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_table(self, node): self.body.append( - # "border=None" is a boolean attribute; - # it means "standard border", not "no border": - self.starttag(node, 'table', CLASS="table", border="1")) + self.starttag(node, 'table', CLASS="table", border="1")) def depart_table(self, node): self.body.append('\n') -- cgit v1.2.1 From 3bbdc469d515dbb723ed5ecd4e57fc854671ec62 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 17 Sep 2004 19:27:30 +0000 Subject: removed misleading import git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2616 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 87f3377fb..38dafd49d 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -37,7 +37,7 @@ import ConfigParser as CP import codecs import docutils import optparse -from optparse import Values, SUPPRESS_HELP +from optparse import SUPPRESS_HELP def store_multiple(option, opt, value, parser, *args, **kwargs): -- cgit v1.2.1 From a61a365d55b4c0f5cf01d4cf04652038537c93a4 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 18 Sep 2004 23:00:20 +0000 Subject: typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2620 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 38dafd49d..4dc6e0522 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -382,7 +382,7 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): ('Specify the text encoding for error output. Default is ASCII. ' 'Optionally also specify the error handler for unencodable ' 'characters, after a colon (":"); default is "%s". (See ' - '"--output-encoding-error-handler".' + '"--output-encoding-error-handler".)' % default_error_encoding_error_handler, ['--error-encoding', '-e'], {'metavar': '', 'default': 'ascii', -- cgit v1.2.1 From 26e823e026f5b9be93d71437039d9b7eb3e0c76d Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 19 Sep 2004 00:34:03 +0000 Subject: added --dependency-file option git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2622 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 11 +++++++++++ docutils/io.py | 12 +++++++++++- docutils/parsers/rst/directives/images.py | 10 +++++++++- docutils/parsers/rst/directives/misc.py | 6 ++++-- docutils/parsers/rst/directives/tables.py | 3 ++- 5 files changed, 37 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 4dc6e0522..5f19453b6 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -152,6 +152,13 @@ def validate_url_trailing_slash( else: return value + '/' +def validate_dependency_file( + setting, value, option_parser, config_parser=None, config_section=None): + if value: + return open(value, 'w') + else: + return None + def make_paths_absolute(pathdict, keys, base_path=None): """ Interpret filesystem path settings relative to the `base_path` given. @@ -398,6 +405,10 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): ' Default is "en" (English).', ['--language', '-l'], {'dest': 'language_code', 'default': 'en', 'metavar': ''}), + ('Write dependencies (caused e.g. by the include directive) to ' + '. Useful in conjunction with programs like make.', + ['--dependency-file'], + {'metavar': '', 'validator': validate_dependency_file}), ('Read configuration settings from , if it exists.', ['--config'], {'metavar': '', 'type': 'string', 'action': 'callback', 'callback': read_config_file}), diff --git a/docutils/io.py b/docutils/io.py index d1117d8a7..88082c6b6 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -166,7 +166,7 @@ class FileInput(Input): def __init__(self, source=None, source_path=None, encoding=None, error_handler='strict', - autoclose=1, handle_io_errors=1): + autoclose=1, handle_io_errors=1, dep_file=None): """ :Parameters: - `source`: either a file-like object (which is read directly), or @@ -183,6 +183,7 @@ class FileInput(Input): self.handle_io_errors = handle_io_errors if source is None: if source_path: + add_dependency(source_path, dep_file) try: self.source = open(source_path) except IOError, error: @@ -335,3 +336,12 @@ class NullOutput(Output): def write(self, data): """Do nothing ([don't even] send data to the bit bucket).""" pass + + +def add_dependency(filename, dep_file): + """ + Add filename (string) to the list of dependencies in dep_file + (file object). + """ + if dep_file: + print >>dep_file, filename diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index ddbdb96c6..5c142d32d 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -12,7 +12,7 @@ __docformat__ = 'reStructuredText' import sys -from docutils import nodes, utils +from docutils import nodes, utils, io from docutils.parsers.rst import directives, states from docutils.nodes import whitespace_normalize_name @@ -35,6 +35,14 @@ def image(name, arguments, options, content, lineno, 'Image URI contains whitespace.', nodes.literal_block(block_text, block_text), line=lineno) return [error] + try: + open(reference) + # If this didn't cause an exception, the image URI is an + # existent file and can be added to the dependency list. + io.add_dependency(reference, + state.document.settings.dependency_file) + except (IOError, UnicodeError): + pass options['uri'] = reference reference_node = None if options.has_key('target'): diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 243340ea9..e04d9ac53 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -40,7 +40,8 @@ def include(name, arguments, options, content, lineno, include_file = io.FileInput( source_path=path, encoding=encoding, error_handler=state.document.settings.input_encoding_error_handler, - handle_io_errors=None) + handle_io_errors=None, + dep_file=state.document.settings.dependency_file) except IOError, error: severe = state_machine.reporter.severe( 'Problems with "%s" directive path:\n%s: %s.' @@ -97,7 +98,8 @@ def raw(name, arguments, options, content, lineno, raw_file = io.FileInput( source_path=path, encoding=encoding, error_handler=state.document.settings.input_encoding_error_handler, - handle_io_errors=None) + handle_io_errors=None, + dep_file=state.document.settings.dependency_file) except IOError, error: severe = state_machine.reporter.severe( 'Problems with "%s" directive path:\n%s.' % (name, error), diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 104a99480..5e90e7d3c 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -206,7 +206,8 @@ def get_csv_data(name, options, content, lineno, block_text, csv_file = io.FileInput( source_path=source, encoding=encoding, error_handler=state.document.settings.input_encoding_error_handler, - handle_io_errors=None) + handle_io_errors=None, + dep_file=state.document.settings.dependency_file) csv_data = csv_file.read().splitlines() except IOError, error: severe = state_machine.reporter.severe( -- cgit v1.2.1 From 62e3f92abe93a366c45dfdab02f109368467b82d Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 19 Sep 2004 01:57:52 +0000 Subject: removed \docutilsclass and --call-class-command git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2623 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 26 -------------------------- 1 file changed, 26 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 39c8a9688..e45170bf3 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -137,11 +137,6 @@ class Writer(writers.Writer): 'emulation using CM fonts).', ['--font-encoding'], {'default': ''}), - ('Causes \\docutilsclass to be called for every node which has the ' - 'class attribute set. Default: disabled', - ['--call-class-command'], - {'default': 0, 'action': 'store_true', - 'validator': frontend.validate_boolean}), ),) settings_defaults = {'output_encoding': 'latin-1'} @@ -510,21 +505,6 @@ class Table: class LaTeXTranslator(nodes.NodeVisitor): - def dispatch_visit(self, node): - if self.call_class and \ - isinstance(node, nodes.Element) and \ - node.hasattr('class'): - self.body.append('\\docutilsclass{%s}{' % node.get('class')) - return nodes.NodeVisitor.dispatch_visit(self, node) - - def dispatch_depart(self, node): - r = nodes.NodeVisitor.dispatch_depart(self, node) - if self.call_class and \ - isinstance(node, nodes.Element) and \ - node.hasattr('class'): - self.body.append('}') - return r - # 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 @@ -577,11 +557,6 @@ class LaTeXTranslator(nodes.NodeVisitor): self.colorlinks = 'false' else: self.colorlinks = 'true' - self.call_class = settings.call_class_command - if self.call_class: - self.docutilsclass = '\\newcommand{\\docutilsclass}[2]{#2}\n' - else: - self.docutilsclass = '' # language: labels, bibliographic_fields, and author_separators. # to allow writing labes for specific languages. @@ -667,7 +642,6 @@ class LaTeXTranslator(nodes.NodeVisitor): # of linewidth, this is fixing it. '\\newlength{\\locallinewidth}\n', # will be set later. - self.docutilsclass, ] self.head_prefix.extend( latex_headings['optionlist_environment'] ) self.head_prefix.extend( latex_headings['footnote_floats'] ) -- cgit v1.2.1 From 24f9bd8c8b48555bf5509c5d40c4b3fbf2caefbd Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 19 Sep 2004 14:54:42 +0000 Subject: added 'overrides' attribute for options git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2628 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 5f19453b6..f3551e04d 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -204,9 +204,12 @@ class Values(optparse.Values): class Option(optparse.Option): + ATTRS = optparse.Option.ATTRS + ['overrides'] + def process(self, opt, value, values, parser): """ - Call the validator function on applicable settings. + Call the validator function on applicable settings and + evaluate the 'overrides' option. Extends `optparse.Option.process`. """ result = optparse.Option.process(self, opt, value, values, parser) @@ -223,6 +226,8 @@ class Option(optparse.Option): % (opt, error.__class__.__name__, error)), None, sys.exc_info()[2]) setattr(values, setting, new_value) + if self.overrides is not None: + setattr(values, self.overrides, None) return result -- cgit v1.2.1 From 00ef5fdf969e2cfbf7f8b50375204c240da682cb Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 19 Sep 2004 14:55:23 +0000 Subject: made stylesheet override stylesheet_path and v.v. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2629 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index a44606e5d..b65978db5 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -39,14 +39,15 @@ class Writer(writers.Writer): 'HTML-Specific Options', None, (('Specify a stylesheet URL, used verbatim. Default is ' - '"default.css". Overridden by --stylesheet-path.', + '"default.css". Overrides --stylesheet-path.', ['--stylesheet'], - {'default': 'default.css', 'metavar': ''}), + {'default': 'default.css', '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.', ['--stylesheet-path'], - {'metavar': ''}), + {'metavar': '', 'overrides': 'stylesheet'}), ('Link to the stylesheet in the output HTML file. This is the ' 'default.', ['--link-stylesheet'], -- cgit v1.2.1 From f14f658ca8686deaff7167b47fc84b79515509bf Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 19 Sep 2004 18:11:09 +0000 Subject: made 'validator' a normal keyword for options (just a cosmetic change) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2632 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index f3551e04d..78cd638cb 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -18,10 +18,10 @@ Exports the following classes: Also exports the following functions: * Option callbacks: `store_multiple`, `read_config_file`. -* Setting validators (see `OptionParser.validators`: `validate_encoding`, - `validate_encoding_error_handler`, `validate_encoding_and_error_handler`, - `validate_boolean`, `validate_threshold`, - `validate_colon_separated_string_list`. +* Setting validators: `validate_encoding`, + `validate_encoding_error_handler`, + `validate_encoding_and_error_handler`, `validate_boolean`, + `validate_threshold`, `validate_colon_separated_string_list`. * `make_paths_absolute`. """ @@ -204,7 +204,7 @@ class Values(optparse.Values): class Option(optparse.Option): - ATTRS = optparse.Option.ATTRS + ['overrides'] + ATTRS = optparse.Option.ATTRS + ['validator', 'overrides'] def process(self, opt, value, values, parser): """ @@ -215,18 +215,17 @@ class Option(optparse.Option): result = optparse.Option.process(self, opt, value, values, parser) setting = self.dest if setting: - value = getattr(values, setting) - validator = parser.validators.get(setting) - if validator: + if self.validator: + value = getattr(values, setting) try: - new_value = validator(setting, value, parser) + new_value = self.validator(setting, value, parser) except Exception, error: raise (optparse.OptionValueError( 'Error in option "%s":\n %s: %s' % (opt, error.__class__.__name__, error)), None, sys.exc_info()[2]) setattr(values, setting, new_value) - if self.overrides is not None: + if self.overrides: setattr(values, self.overrides, None) return result @@ -503,16 +502,10 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): else: group = self # single options for (help_text, option_strings, kwargs) in option_spec: - kwargs = kwargs.copy() # to be modified, locally only - if kwargs.has_key('validator'): - validator = kwargs['validator'] - del kwargs['validator'] - else: - validator = None option = group.add_option(help=help_text, *option_strings, **kwargs) - if validator: - self.validators[option.dest] = validator + if kwargs.get('validator'): + self.validators[option.dest] = kwargs['validator'] if kwargs.get('action') == 'append': self.lists[option.dest] = 1 if component.settings_defaults: -- cgit v1.2.1 From 8a44ca3061c37a5ec1ceae4849b92b4aac4e3433 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 19 Sep 2004 18:27:03 +0000 Subject: made --stylesheet override --stylesheet-path and deleted useless options git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2633 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index e45170bf3..35788a913 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -59,22 +59,14 @@ class Writer(writers.Writer): 'default': 'dash', 'metavar': ''}), ('Specify a stylesheet file. The file will be "input" by latex in ' 'the document header. Default is no stylesheet (""). ' - 'Overridden by --stylesheet-path.', + 'Overrides --stylesheet-path.', ['--stylesheet'], - {'default': '', 'metavar': ''}), + {'default': '', 'metavar': '', + 'overrides': 'stylesheet_path'}), ('Specify a stylesheet file, relative to the current working ' 'directory. Overrides --stylesheet.', ['--stylesheet-path'], - {'metavar': ''}), - ('Link to the stylesheet in the output LaTeX file. This is the ' - 'default.', - ['--link-stylesheet'], - {'dest': 'embed_stylesheet', 'action': 'store_false', - 'validator': frontend.validate_boolean}), - ('Embed the stylesheet in the output LaTeX file. The stylesheet ' - 'file must be accessible during processing (--stylesheet-path is ' - 'recommended).', - ['--embed-stylesheet'], {'action': 'store_true'}), + {'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.', -- cgit v1.2.1 From 30f6867a3415f285e4e89e9d2bafd23ce3c3965a Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 19 Sep 2004 18:38:38 +0000 Subject: made stylesheet and stylesheet_path mutually exclusive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2635 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index b65978db5..5ec6e98d8 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -228,6 +228,8 @@ class HTMLTranslator(nodes.NodeVisitor): def get_stylesheet_reference(self, relative_to=None): settings = self.settings if settings.stylesheet_path: + assert not settings.stylesheet, \ + 'stylesheet and stylesheet_path are mutually exclusive.' if relative_to == None: relative_to = settings._destination return utils.relative_path(relative_to, settings.stylesheet_path) -- cgit v1.2.1 From 41883cf24b844898911cf4e9bcc35a3af4e13750 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 19 Sep 2004 18:39:39 +0000 Subject: made stylesheet and stylesheet_path mutually exclusive; made get_stylesheet_reference of latex writer match the documented behavior for stylesheet_path git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2637 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 35788a913..9aaa20ac7 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -20,7 +20,7 @@ import time import re import string from types import ListType -from docutils import frontend, nodes, languages, writers +from docutils import frontend, nodes, languages, writers, utils class Writer(writers.Writer): @@ -701,11 +701,16 @@ class LaTeXTranslator(nodes.NodeVisitor): # true when encoding in math mode self.mathmode = 0 - def get_stylesheet_reference(self): - if self.settings.stylesheet_path: - return self.settings.stylesheet_path + def get_stylesheet_reference(self, relative_to=None): + settings = self.settings + if settings.stylesheet_path: + assert not settings.stylesheet, \ + 'stylesheet and stylesheet_path are mutually exclusive.' + if relative_to == None: + relative_to = settings._destination + return utils.relative_path(relative_to, settings.stylesheet_path) else: - return self.settings.stylesheet + return settings.stylesheet def to_latex_encoding(self,docutils_encoding): """ -- cgit v1.2.1 From 74264bb4f6d8eea24294913e8f5ec00ca24d7931 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 19 Sep 2004 18:59:12 +0000 Subject: making stylesheet and stylesheet_path mutually exclusive was a bad idea; reverted git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2638 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 -- docutils/writers/latex2e.py | 2 -- 2 files changed, 4 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 5ec6e98d8..b65978db5 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -228,8 +228,6 @@ class HTMLTranslator(nodes.NodeVisitor): def get_stylesheet_reference(self, relative_to=None): settings = self.settings if settings.stylesheet_path: - assert not settings.stylesheet, \ - 'stylesheet and stylesheet_path are mutually exclusive.' if relative_to == None: relative_to = settings._destination return utils.relative_path(relative_to, settings.stylesheet_path) diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 9aaa20ac7..50fe506bc 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -704,8 +704,6 @@ class LaTeXTranslator(nodes.NodeVisitor): def get_stylesheet_reference(self, relative_to=None): settings = self.settings if settings.stylesheet_path: - assert not settings.stylesheet, \ - 'stylesheet and stylesheet_path are mutually exclusive.' if relative_to == None: relative_to = settings._destination return utils.relative_path(relative_to, settings.stylesheet_path) -- cgit v1.2.1 From 26efe6977a67b9a3c373fe826bd6a96ac12e5640 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 21 Sep 2004 16:49:04 +0000 Subject: Added config file support for "overrides" setting parameter. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2639 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 78cd638cb..0b1af5da8 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -460,6 +460,11 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): keyword argument dictionary entries of components' ``settings_spec`` attribute.""" + self.overrides = {} + """{setting: overridden setting} mapping, used by `validate_options`. + The overridden setting is set to `None` when the key setting is + encountered.""" + self.lists = {} """Set of list-type settings.""" @@ -508,6 +513,8 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): self.validators[option.dest] = kwargs['validator'] if kwargs.get('action') == 'append': self.lists[option.dest] = 1 + if kwargs.get('overrides'): + self.overrides[option.dest] = kwargs['overrides'] if component.settings_defaults: self.defaults.update(component.settings_defaults) for component in components: @@ -621,7 +628,10 @@ section "Old-Format Configuration Files". self.remove_section('options') def validate_settings(self, filename, option_parser): - """Call the validator function on all applicable settings.""" + """ + Call the validator function and implement overrides on all applicable + settings. + """ for section in self.sections(): for setting in self.options(section): validator = option_parser.validators.get(setting) @@ -638,6 +648,9 @@ section "Old-Format Configuration Files". % (filename, section, error.__class__.__name__, error, setting, value)), None, sys.exc_info()[2]) self.set(section, setting, new_value) + override = option_parser.overrides.get(setting) + if override: + self.set(section, override, None) def optionxform(self, optionstr): """ -- cgit v1.2.1 From 31d4088d020e507b0ce69e6da0876f795252cb9f Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 21 Sep 2004 16:50:04 +0000 Subject: restored check for mutually exclusive settings, now that settings may override others git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2640 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 ++ docutils/writers/latex2e.py | 2 ++ 2 files changed, 4 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index b65978db5..5ec6e98d8 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -228,6 +228,8 @@ class HTMLTranslator(nodes.NodeVisitor): def get_stylesheet_reference(self, relative_to=None): settings = self.settings if settings.stylesheet_path: + assert not settings.stylesheet, \ + 'stylesheet and stylesheet_path are mutually exclusive.' if relative_to == None: relative_to = settings._destination return utils.relative_path(relative_to, settings.stylesheet_path) diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 50fe506bc..9aaa20ac7 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -704,6 +704,8 @@ class LaTeXTranslator(nodes.NodeVisitor): def get_stylesheet_reference(self, relative_to=None): settings = self.settings if settings.stylesheet_path: + assert not settings.stylesheet, \ + 'stylesheet and stylesheet_path are mutually exclusive.' if relative_to == None: relative_to = settings._destination return utils.relative_path(relative_to, settings.stylesheet_path) -- cgit v1.2.1 From 8df004f7cc1e449df3b9e158c50e8536704c169d Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 25 Sep 2004 21:35:23 +0000 Subject: typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2642 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 9aaa20ac7..f987340d4 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -111,8 +111,8 @@ class Writer(writers.Writer): '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"', + 'above and below the table and below the header or "nolines". ' + 'Default: "standard"', ['--table-style'], {'choices': ['standard', 'booktabs','nolines'], 'default': 'standard', 'metavar': ''}), -- cgit v1.2.1 From 3964d77d7d15405e64ad2079356e6ba77628df0f Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 25 Sep 2004 23:33:58 +0000 Subject: added DependencyList class git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2644 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'docutils') diff --git a/docutils/utils.py b/docutils/utils.py index 87bcac9ba..e73f0f0ed 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -460,3 +460,32 @@ def get_source_line(node): return node.source, node.line node = node.parent return None, None + + +class DependencyList: + + def __init__(self, output_file=None, dependencies=[]): + self.list = [] + self.set_output(output_file) + for i in dependencies: + self.add(i) + + def set_output(self, output_file): + if output_file == '-': + self.file = sys.stdout + elif output_file: + self.file = open(output_file, 'w') + else: + self.file = None + + def add(self, filename): + if not filename in self.list: + self.list.append(filename) + if self.file is not None: + print >>self.file, filename + + def __repr__(self): + data = repr(self.list) + if len(data) > 60: + data = data[:56] + ' ...' + return '<%s: %s>' % (self.__class__.__name__, data) -- cgit v1.2.1 From 94cc169e7c0806612a49326d79cd266e0a479ac0 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 25 Sep 2004 23:35:26 +0000 Subject: changed --dependency-file to --record-dependencies git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2645 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 0b1af5da8..2b984f50e 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -21,7 +21,8 @@ Also exports the following functions: * Setting validators: `validate_encoding`, `validate_encoding_error_handler`, `validate_encoding_and_error_handler`, `validate_boolean`, - `validate_threshold`, `validate_colon_separated_string_list`. + `validate_threshold`, `validate_colon_separated_string_list`, + `validate_dependency_file`. * `make_paths_absolute`. """ @@ -154,10 +155,10 @@ def validate_url_trailing_slash( def validate_dependency_file( setting, value, option_parser, config_parser=None, config_section=None): - if value: - return open(value, 'w') - else: - return None + try: + return docutils.utils.DependencyList(value) + except IOError: + return docutils.utils.DependencyList(None) def make_paths_absolute(pathdict, keys, base_path=None): """ @@ -189,6 +190,11 @@ class Values(optparse.Values): Works in conjunction with the `OptionParser.lists` instance attribute. """ + def __init__(self, *args, **kwargs): + optparse.Values.__init__(self, *args, **kwargs) + # Set up dependency list, in case it is needed. + self.record_dependencies = docutils.utils.DependencyList() + def update(self, other_dict, option_parser): if isinstance(other_dict, Values): other_dict = other_dict.__dict__ @@ -409,10 +415,11 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): ' Default is "en" (English).', ['--language', '-l'], {'dest': 'language_code', 'default': 'en', 'metavar': ''}), - ('Write dependencies (caused e.g. by the include directive) to ' - '. Useful in conjunction with programs like make.', - ['--dependency-file'], - {'metavar': '', 'validator': validate_dependency_file}), + ('Write dependencies (caused e.g. by file inclusions) to ' + '. Useful in conjunction with programs like "make".', + ['--record-dependencies'], + {'dest': 'record_dependencies', 'metavar': '', + 'validator': validate_dependency_file}), ('Read configuration settings from , if it exists.', ['--config'], {'metavar': '', 'type': 'string', 'action': 'callback', 'callback': read_config_file}), -- cgit v1.2.1 From 43ad6eb70aa3e45d894253d74528f46d908f660d Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 25 Sep 2004 23:38:27 +0000 Subject: removed dependency magic in FileInput, removed add_dependency function (now in utils.DependencyList) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2646 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index 88082c6b6..d1117d8a7 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -166,7 +166,7 @@ class FileInput(Input): def __init__(self, source=None, source_path=None, encoding=None, error_handler='strict', - autoclose=1, handle_io_errors=1, dep_file=None): + autoclose=1, handle_io_errors=1): """ :Parameters: - `source`: either a file-like object (which is read directly), or @@ -183,7 +183,6 @@ class FileInput(Input): self.handle_io_errors = handle_io_errors if source is None: if source_path: - add_dependency(source_path, dep_file) try: self.source = open(source_path) except IOError, error: @@ -336,12 +335,3 @@ class NullOutput(Output): def write(self, data): """Do nothing ([don't even] send data to the bit bucket).""" pass - - -def add_dependency(filename, dep_file): - """ - Add filename (string) to the list of dependencies in dep_file - (file object). - """ - if dep_file: - print >>dep_file, filename -- cgit v1.2.1 From 965d763d192aabd0d71ed3a088b994170bc8219f Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 25 Sep 2004 23:44:06 +0000 Subject: use new DependencyList (in settings.record_dependencies) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2647 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/images.py | 11 ++--------- docutils/parsers/rst/directives/misc.py | 8 ++++---- docutils/parsers/rst/directives/tables.py | 4 ++-- 3 files changed, 8 insertions(+), 15 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index 5c142d32d..bf13b93e1 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -12,7 +12,7 @@ __docformat__ = 'reStructuredText' import sys -from docutils import nodes, utils, io +from docutils import nodes, utils from docutils.parsers.rst import directives, states from docutils.nodes import whitespace_normalize_name @@ -35,14 +35,6 @@ def image(name, arguments, options, content, lineno, 'Image URI contains whitespace.', nodes.literal_block(block_text, block_text), line=lineno) return [error] - try: - open(reference) - # If this didn't cause an exception, the image URI is an - # existent file and can be added to the dependency list. - io.add_dependency(reference, - state.document.settings.dependency_file) - except (IOError, UnicodeError): - pass options['uri'] = reference reference_node = None if options.has_key('target'): @@ -93,6 +85,7 @@ def figure(name, arguments, options, content, lineno, except (IOError, UnicodeError): pass else: + state.document.settings.record_dependencies.add(reference) figure_node['width'] = i.size[0] elif figwidth is not None: figure_node['width'] = figwidth diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index e04d9ac53..fc797e1eb 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -37,11 +37,11 @@ def include(name, arguments, options, content, lineno, path = utils.relative_path(None, path) encoding = options.get('encoding', state.document.settings.input_encoding) try: + state.document.settings.record_dependencies.add(path) include_file = io.FileInput( source_path=path, encoding=encoding, error_handler=state.document.settings.input_encoding_error_handler, - handle_io_errors=None, - dep_file=state.document.settings.dependency_file) + handle_io_errors=None) except IOError, error: severe = state_machine.reporter.severe( 'Problems with "%s" directive path:\n%s: %s.' @@ -95,11 +95,11 @@ def raw(name, arguments, options, content, lineno, path = os.path.normpath(os.path.join(source_dir, options['file'])) path = utils.relative_path(None, path) try: + state.document.settings.record_dependencies.add(path) raw_file = io.FileInput( source_path=path, encoding=encoding, error_handler=state.document.settings.input_encoding_error_handler, - handle_io_errors=None, - dep_file=state.document.settings.dependency_file) + handle_io_errors=None) except IOError, error: severe = state_machine.reporter.severe( 'Problems with "%s" directive path:\n%s.' % (name, error), diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 5e90e7d3c..5b4cf8313 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -203,11 +203,11 @@ def get_csv_data(name, options, content, lineno, block_text, source = os.path.normpath(os.path.join(source_dir, options['file'])) source = utils.relative_path(None, source) try: + state.document.settings.record_dependencies.add(source) csv_file = io.FileInput( source_path=source, encoding=encoding, error_handler=state.document.settings.input_encoding_error_handler, - handle_io_errors=None, - dep_file=state.document.settings.dependency_file) + handle_io_errors=None) csv_data = csv_file.read().splitlines() except IOError, error: severe = state_machine.reporter.severe( -- cgit v1.2.1 From 50c48a2270c9de3447dac18097d707238f73bd39 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 25 Sep 2004 23:44:51 +0000 Subject: made LaTeX writer record dependency on referenced images git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2648 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index f987340d4..6a78aa003 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1439,6 +1439,9 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_image(self, node): attrs = node.attributes + # Add image URI to dependency list, assuming that it's + # referring to a local file. + self.settings.record_dependencies.add(attrs['uri']) pre = [] # in reverse order post = ['\\includegraphics{%s}' % attrs['uri']] inline = isinstance(node.parent, nodes.TextElement) -- cgit v1.2.1 From 43d0eb9a47b5b2c490d692aeea7e005b6427dd7e Mon Sep 17 00:00:00 2001 From: grubert Date: Mon, 27 Sep 2004 06:12:45 +0000 Subject: Add unicode quotes u201C u201D. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2651 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 6a78aa003..0e9c01552 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -754,7 +754,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def language_label(self, docutil_label): return self.language.labels[docutil_label] - def utf8_to_latex(self,text): + 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. @@ -763,6 +763,8 @@ class LaTeXTranslator(nodes.NodeVisitor): u'\u00A9' : '{\\copyright}', u'\u2013' : '{--}', u'\u2014' : '{---}', + u'\u201C' : '``', + u'\u201D' : '\'\'', u'\u2020' : '{\\dag}', u'\u2021' : '{\\ddag}', u'\u21d4' : '{$\\Leftrightarrow$}', @@ -858,7 +860,7 @@ class LaTeXTranslator(nodes.NodeVisitor): if self.insert_none_breaking_blanks: text = text.replace(' ', '~') if self.settings.output_encoding != 'utf-8': - text = self.utf8_to_latex(text) + text = self.unicode_to_latex(text) return text def attval(self, text, -- cgit v1.2.1 From dfcc3c16fb6cc16ffc12824f734b3b8eb3a64ed4 Mon Sep 17 00:00:00 2001 From: grubert Date: Mon, 27 Sep 2004 06:16:42 +0000 Subject: No newline after depart_term. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2652 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 0e9c01552..10fde50f2 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1838,7 +1838,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_term(self, node): # definition list term. - self.body.append(']\n') + self.body.append('] ') def visit_tgroup(self, node): #self.body.append(self.starttag(node, 'colgroup')) -- cgit v1.2.1 From 7e01e55a123cbcb5ba89d7cc435ec97e2269f57e Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 27 Sep 2004 15:28:33 +0000 Subject: Fixed bug where a "role" directive in a nested parse would crash the parser; the "language" attribute was not being copied over to the new state machine. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2654 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 1 + 1 file changed, 1 insertion(+) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 43caa9711..f6a25465f 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -199,6 +199,7 @@ class NestedStateMachine(StateMachineWS): self.document = memo.document self.attach_observer(self.document.note_source) self.reporter = memo.reporter + self.language = memo.language self.node = node results = StateMachineWS.run(self, input_lines, input_offset) assert results == [], ('NestedStateMachine.run() results should be ' -- cgit v1.2.1 From 3004c8ccb54f33f7f8a23d39cd9dcfaa746e9f49 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Sep 2004 15:47:44 +0000 Subject: added function to get option by destination git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2657 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 2b984f50e..980838776 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -590,6 +590,19 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): """Needed to get custom `Values` instances.""" return Values(self.defaults) + def get_option_by_dest(self, dest): + """ + Get an option by its dest. + + If you're supplying a dest which is shared by several options, + the behavior is undefined. + """ + for group in self.option_groups + [self]: + for option in group.option_list: + if option.dest == dest: + return option + raise KeyError('No option with dest == %r.' % dest) + class ConfigParser(CP.ConfigParser): -- cgit v1.2.1 From acc174f64afebaf6b72d3f0b113d5f3bfca75dbf Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Sep 2004 16:26:05 +0000 Subject: removed OptionParser.validator and OptionParser.overrides dictionaries; use get_option_by_dest() instead; made documentation of get_option_by_dest() more precise git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2658 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 980838776..6e7d0e318 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -458,19 +458,6 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): ``.settings_spec`` attribute. `defaults` is a mapping of setting default overrides. """ - self.validators = {} - """{setting: validation function} mapping, used by `validate_options`. - Validation functions take three or five parameters: setting name, - value, an `OptionParser` (``self``), and a `ConfigParser` and config - file section if activated from a config file. They return a (possibly - modified) value, or raise an exception. Populated from the "validator" - keyword argument dictionary entries of components' ``settings_spec`` - attribute.""" - - self.overrides = {} - """{setting: overridden setting} mapping, used by `validate_options`. - The overridden setting is set to `None` when the key setting is - encountered.""" self.lists = {} """Set of list-type settings.""" @@ -516,12 +503,8 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): for (help_text, option_strings, kwargs) in option_spec: option = group.add_option(help=help_text, *option_strings, **kwargs) - if kwargs.get('validator'): - self.validators[option.dest] = kwargs['validator'] if kwargs.get('action') == 'append': self.lists[option.dest] = 1 - if kwargs.get('overrides'): - self.overrides[option.dest] = kwargs['overrides'] if component.settings_defaults: self.defaults.update(component.settings_defaults) for component in components: @@ -595,7 +578,10 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): Get an option by its dest. If you're supplying a dest which is shared by several options, - the behavior is undefined. + it is undefined which option of those is returned. + + A KeyError is raised if there is no option with the supplied + dest. """ for group in self.option_groups + [self]: for option in group.option_list: @@ -654,11 +640,14 @@ section "Old-Format Configuration Files". """ for section in self.sections(): for setting in self.options(section): - validator = option_parser.validators.get(setting) - if validator: + try: + option = option_parser.get_option_by_dest(setting) + except KeyError: + continue + if option.validator: value = self.get(section, setting, raw=1) try: - new_value = validator( + new_value = option.validator( setting, value, option_parser, config_parser=self, config_section=section) except Exception, error: @@ -668,9 +657,8 @@ section "Old-Format Configuration Files". % (filename, section, error.__class__.__name__, error, setting, value)), None, sys.exc_info()[2]) self.set(section, setting, new_value) - override = option_parser.overrides.get(setting) - if override: - self.set(section, override, None) + if option.overrides: + self.set(section, option.overrides, None) def optionxform(self, optionstr): """ -- cgit v1.2.1 From f5ff01e86632488da95a1cc7c11e208e976c8fb1 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Sep 2004 18:28:34 +0000 Subject: added some more unicode translations for the latex writer git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2659 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 10fde50f2..47f209e22 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -760,13 +760,18 @@ class LaTeXTranslator(nodes.NodeVisitor): # chars one should use the LaTeX unicode package. latex_equivalents = { u'\u00A0' : '~', - u'\u00A9' : '{\\copyright}', 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$}', } for uchar in latex_equivalents.keys(): -- cgit v1.2.1 From e3463783f6562867a2ad717a0c6653c6018a179a Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 28 Sep 2004 09:42:50 +0000 Subject: improved utf-8 recognition git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2661 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 47f209e22..ded6046fd 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -533,6 +533,7 @@ class LaTeXTranslator(nodes.NodeVisitor): 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 @@ -579,8 +580,8 @@ class LaTeXTranslator(nodes.NodeVisitor): fontenc_header = '\\usepackage{ae}\n\\usepackage{aeguill}\n' else: fontenc_header = '\\usepackage[%s]{fontenc}\n' % (self.font_encoding,) - input_encoding = self.encoding % self.to_latex_encoding(settings.output_encoding) - if self.to_latex_encoding(settings.output_encoding) == 'utf8': + input_encoding = self.encoding % self.latex_encoding + if self.latex_encoding == 'utf8': # preload unicode to avoid ``Please insert PrerenderUnicode`` message, # when rendering the first ``\section``. input_encoding += '\\PreloadUnicodePage{0}\n' @@ -864,7 +865,7 @@ class LaTeXTranslator(nodes.NodeVisitor): text = text.replace('[', '{[}') if self.insert_none_breaking_blanks: text = text.replace(' ', '~') - if self.settings.output_encoding != 'utf-8': + if self.latex_encoding != 'utf8': text = self.unicode_to_latex(text) return text -- cgit v1.2.1 From 465b9e552af2ecd5a1d5df8d042ebc9ca2258ff2 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 28 Sep 2004 11:53:41 +0000 Subject: added get_stylesheet_reference(); added documentation for DependencyList; made DependencyList.set_output() clear the list of already added dependencies git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2663 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/utils.py b/docutils/utils.py index e73f0f0ed..91b01f530 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -450,6 +450,19 @@ def relative_path(source, target): parts = ['..'] * (len(source_parts) - 1) + target_parts return '/'.join(parts) +def get_stylesheet_reference(settings, relative_to=None): + """ + Retrieve a stylesheet reference from the settings object. + """ + if settings.stylesheet_path: + assert not settings.stylesheet, \ + 'stylesheet and stylesheet_path are mutually exclusive.' + if relative_to == None: + relative_to = settings._destination + return relative_path(relative_to, settings.stylesheet_path) + else: + return settings.stylesheet + def get_source_line(node): """ Return the "source" and "line" attributes from the `node` given or from @@ -464,13 +477,32 @@ def get_source_line(node): class DependencyList: + """ + List of dependencies, with file recording support. + """ + def __init__(self, output_file=None, dependencies=[]): - self.list = [] + """ + Initialize the dependency list, automatically setting the + output file to `output_file` (see `set_output()`) and adding + all supplied dependencies. + """ self.set_output(output_file) for i in dependencies: self.add(i) def set_output(self, output_file): + """ + Set the output file and clear the list of already added + dependencies. + + `output_file` must be a string. The specified file is + immediately overwritten. + + If output_file is '-', the output will be written to stdout. + If it is None, no file output is done when calling add(). + """ + self.list = [] if output_file == '-': self.file = sys.stdout elif output_file: @@ -479,6 +511,11 @@ class DependencyList: self.file = None def add(self, filename): + """ + If the dependency `filename` has not already been added, + append it to self.list and print it to self.file if self.file + is not None. + """ if not filename in self.list: self.list.append(filename) if self.file is not None: -- cgit v1.2.1 From 9e0b1d48ebb74fe9a1e94bcabe72ab90fc237ae3 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 28 Sep 2004 11:56:01 +0000 Subject: use utils.get_stylesheet_reference(); record name of embedded stylesheet in dependencies git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2664 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 5ec6e98d8..435749798 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -190,12 +190,13 @@ class HTMLTranslator(nodes.NodeVisitor): % settings.output_encoding) self.head = [] if settings.embed_stylesheet: - stylesheet = self.get_stylesheet_reference( + 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 = self.get_stylesheet_reference() + stylesheet = utils.get_stylesheet_reference(settings) if stylesheet: self.stylesheet = [self.stylesheet_link % stylesheet] else: @@ -225,17 +226,6 @@ class HTMLTranslator(nodes.NodeVisitor): self.footer = [] self.in_document_title = 0 - def get_stylesheet_reference(self, relative_to=None): - settings = self.settings - if settings.stylesheet_path: - assert not settings.stylesheet, \ - 'stylesheet and stylesheet_path are mutually exclusive.' - if relative_to == None: - relative_to = settings._destination - return utils.relative_path(relative_to, settings.stylesheet_path) - else: - return settings.stylesheet - def astext(self): return ''.join(self.head_prefix + self.head + self.stylesheet + self.body_prefix -- cgit v1.2.1 From dbe05c29a398dd12da274c9b056b3b610a0ed802 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 28 Sep 2004 11:57:06 +0000 Subject: added relative_path_settings; use utils.get_stylesheet_reference() git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2665 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index ded6046fd..f09e59e05 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -133,6 +133,8 @@ class Writer(writers.Writer): settings_defaults = {'output_encoding': 'latin-1'} + relative_path_settings = ('stylesheet_path',) + config_section = 'latex2e writer' config_section_dependencies = ('writers',) @@ -640,7 +642,7 @@ class LaTeXTranslator(nodes.NodeVisitor): 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 = self.get_stylesheet_reference() + stylesheet = utils.get_stylesheet_reference(settings) if stylesheet: self.head_prefix.append(self.stylesheet % (stylesheet)) @@ -702,17 +704,6 @@ class LaTeXTranslator(nodes.NodeVisitor): # true when encoding in math mode self.mathmode = 0 - def get_stylesheet_reference(self, relative_to=None): - settings = self.settings - if settings.stylesheet_path: - assert not settings.stylesheet, \ - 'stylesheet and stylesheet_path are mutually exclusive.' - if relative_to == None: - relative_to = settings._destination - return utils.relative_path(relative_to, settings.stylesheet_path) - else: - return settings.stylesheet - def to_latex_encoding(self,docutils_encoding): """ Translate docutils encoding name into latex's. -- cgit v1.2.1 From b13cf9b7377a62aea3f89ebb2731fa59cbbac7c5 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 28 Sep 2004 12:37:29 +0000 Subject: latex writer now adds the stylesheet to the list of dependencies git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2666 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 1 + 1 file changed, 1 insertion(+) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index f09e59e05..c0584e691 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -644,6 +644,7 @@ class LaTeXTranslator(nodes.NodeVisitor): ## 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 -- cgit v1.2.1 From 545f59435541222a76907ab6c606bda6ac1dc40f Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 29 Sep 2004 15:33:19 +0000 Subject: removed \PreloadUnicodePage git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2668 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index c0584e691..b6f53197d 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -583,10 +583,6 @@ class LaTeXTranslator(nodes.NodeVisitor): else: fontenc_header = '\\usepackage[%s]{fontenc}\n' % (self.font_encoding,) input_encoding = self.encoding % self.latex_encoding - if self.latex_encoding == 'utf8': - # preload unicode to avoid ``Please insert PrerenderUnicode`` message, - # when rendering the first ``\section``. - input_encoding += '\\PreloadUnicodePage{0}\n' if self.settings.graphicx_option == '': self.graphicx_package = '\\usepackage{graphicx}\n' elif self.settings.graphicx_option.lower() == 'auto': -- cgit v1.2.1 From a642b1e99d0a3c417ef1422e3866ea450332bcc9 Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 29 Sep 2004 18:01:09 +0000 Subject: added close() method for DependencyList git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2670 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'docutils') diff --git a/docutils/utils.py b/docutils/utils.py index 91b01f530..4227b8d15 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -479,6 +479,9 @@ class DependencyList: """ List of dependencies, with file recording support. + + Note that the output file is not automatically closed. You have + to explicitly call the close() method. """ def __init__(self, output_file=None, dependencies=[]): @@ -521,6 +524,13 @@ class DependencyList: if self.file is not None: print >>self.file, filename + def close(self): + """ + Close the output file. + """ + self.file.close() + self.file = None + def __repr__(self): data = repr(self.list) if len(data) > 60: -- cgit v1.2.1 From 28b8294d62333bc4e217cdf430a42be0750211b8 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 30 Sep 2004 03:01:20 +0000 Subject: improved DependencyList.__repr__; whitespace git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2672 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'docutils') diff --git a/docutils/utils.py b/docutils/utils.py index 4227b8d15..7e515070f 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -92,7 +92,7 @@ class Reporter: exceptions will be raised, halting execution. - `debug`: Show debug (level=0) system messages? - `stream`: Where warning output is sent. Can be file-like (has a - ``.write`` method), a string (file name, opened for writing), + ``.write`` method), a string (file name, opened for writing), '' (empty string, for discarding all stream messages) or `None` (implies `sys.stderr`; default). - `encoding`: The encoding for stderr output. @@ -100,7 +100,7 @@ class Reporter: """ self.source = source """The path to or description of the source data.""" - + if stream is None: stream = sys.stderr elif type(stream) in (StringType, UnicodeType): @@ -476,14 +476,14 @@ def get_source_line(node): class DependencyList: - + """ List of dependencies, with file recording support. Note that the output file is not automatically closed. You have to explicitly call the close() method. """ - + def __init__(self, output_file=None, dependencies=[]): """ Initialize the dependency list, automatically setting the @@ -532,7 +532,8 @@ class DependencyList: self.file = None def __repr__(self): - data = repr(self.list) - if len(data) > 60: - data = data[:56] + ' ...' - return '<%s: %s>' % (self.__class__.__name__, data) + if self.file: + output_file = self.file.name + else: + output_file = None + return '%s(%r, %s)' % (self.__class__.__name__, output_file, self.list) -- cgit v1.2.1 From 71458320a74f312ed4f3eedf7314de7c064581fe Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 30 Sep 2004 03:32:48 +0000 Subject: fixed "record_dependencies" default git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2674 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 6e7d0e318..922098896 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -192,8 +192,9 @@ class Values(optparse.Values): def __init__(self, *args, **kwargs): optparse.Values.__init__(self, *args, **kwargs) - # Set up dependency list, in case it is needed. - self.record_dependencies = docutils.utils.DependencyList() + if self.record_dependencies is None: + # Set up dependency list, in case it is needed. + self.record_dependencies = docutils.utils.DependencyList() def update(self, other_dict, option_parser): if isinstance(other_dict, Values): @@ -418,8 +419,8 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): ('Write dependencies (caused e.g. by file inclusions) to ' '. Useful in conjunction with programs like "make".', ['--record-dependencies'], - {'dest': 'record_dependencies', 'metavar': '', - 'validator': validate_dependency_file}), + {'metavar': '', 'validator': validate_dependency_file, + 'default': None}), # default set in Values class ('Read configuration settings from , if it exists.', ['--config'], {'metavar': '', 'type': 'string', 'action': 'callback', 'callback': read_config_file}), -- cgit v1.2.1 From d1b246da31c77372e38ab3ece5275e07065be26b Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 30 Sep 2004 03:52:14 +0000 Subject: fixed last fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2675 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 922098896..ed20057d3 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -192,7 +192,8 @@ class Values(optparse.Values): def __init__(self, *args, **kwargs): optparse.Values.__init__(self, *args, **kwargs) - if self.record_dependencies is None: + if (not hasattr(self, 'record_dependencies') + or self.record_dependencies is None): # Set up dependency list, in case it is needed. self.record_dependencies = docutils.utils.DependencyList() -- cgit v1.2.1 From cae2ee1daa3debebadffe965580cd15af2712331 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 30 Sep 2004 13:43:40 +0000 Subject: added --leave-footnote-reference-space git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2680 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/__init__.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/__init__.py b/docutils/parsers/rst/__init__.py index 33ad99829..88795a830 100644 --- a/docutils/parsers/rst/__init__.py +++ b/docutils/parsers/rst/__init__.py @@ -108,7 +108,11 @@ class Parser(docutils.parsers.Parser): {'metavar': '', 'type': 'int', 'default': 8}), ('Remove spaces before footnote references.', ['--trim-footnote-reference-space'], - {'action': 'store_true', 'validator': frontend.validate_boolean}),)) + {'action': 'store_true', 'validator': frontend.validate_boolean}), + ('Leave spaces before footnote references.', + ['--leave-footnote-reference-space'], + {'action': 'store_false', 'dest': 'trim_footnote_reference_space', + 'validator': frontend.validate_boolean}),)) config_section = 'restructuredtext parser' config_section_dependencies = ('parsers',) -- cgit v1.2.1 From 124f37c038f86eb6c3b1344150840b5fd2a1cdbd Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 30 Sep 2004 13:47:59 +0000 Subject: setting footnote_references to "superscript" or "brackets" now causes footnote-reference-space to be trimmed or not, resp. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2681 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 2 +- docutils/transforms/references.py | 2 +- docutils/utils.py | 15 +++++++++++++++ docutils/writers/html4css1.py | 3 ++- docutils/writers/latex2e.py | 3 ++- 5 files changed, 21 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index f6a25465f..60e0bcafd 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -922,7 +922,7 @@ class Inliner: if refname: refnode['refname'] = refname self.document.note_footnote_ref(refnode) - if self.document.settings.trim_footnote_reference_space: + if utils.get_trim_footnote_ref_space(self.document.settings): before = before.rstrip() return (before, [refnode], remaining, []) diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 2786cd562..04b79a1cc 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -767,7 +767,7 @@ class TargetNotes(Transform): self.document.note_footnote_ref(refnode) index = ref.parent.index(ref) + 1 reflist = [refnode] - if not self.document.settings.trim_footnote_reference_space: + if not utils.get_trim_footnote_ref_space(self.document.settings): reflist.insert(0, nodes.Text(' ')) ref.parent.insert(index, reflist) return footnote diff --git a/docutils/utils.py b/docutils/utils.py index 7e515070f..ed0a36543 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -463,6 +463,21 @@ def get_stylesheet_reference(settings, relative_to=None): else: return settings.stylesheet +def get_trim_footnote_ref_space(settings): + """ + Return whether or not to trim footnote space. + + If trim_footnote_reference_space is not None, return it. + + If trim_footnote_reference_space is None, return False unless the + footnote reference style is 'superscript'. + """ + if settings.trim_footnote_reference_space is None: + return hasattr(settings, 'footnote_references') and \ + settings.footnote_references == 'superscript' + else: + return settings.trim_footnote_reference_space + def get_source_line(node): """ Return the "source" and "line" attributes from the `node` given or from diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 435749798..9fc6cfc69 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -67,7 +67,8 @@ class Writer(writers.Writer): '"brackets". Default is "superscript".', ['--footnote-references'], {'choices': ['superscript', 'brackets'], 'default': 'superscript', - 'metavar': ''}), + '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'], diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index b6f53197d..50c44c7b9 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -46,7 +46,8 @@ class Writer(writers.Writer): '"brackets". Default is "brackets".', ['--footnote-references'], {'choices': ['superscript', 'brackets'], 'default': 'brackets', - 'metavar': ''}), + 'metavar': '', + 'overrides': 'trim_footnote_reference_space'}), ('Use LaTeX citations. ' 'Default: no, uses figures which might get mixed with images.', ['--use-latex-citations'], -- cgit v1.2.1 From c5824048c8123eb5763ebf5d0be21e396c5897c4 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 1 Oct 2004 16:06:44 +0000 Subject: changed default footnote reference styles: brackets for HTML and superscript for LaTeX git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2684 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 4 ++-- docutils/writers/latex2e.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 9fc6cfc69..226708393 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -64,9 +64,9 @@ class Writer(writers.Writer): {'choices': '1 2 3 4 5 6'.split(), 'default': '1', 'metavar': ''}), ('Format for footnote references: one of "superscript" or ' - '"brackets". Default is "superscript".', + '"brackets". Default is "brackets".', ['--footnote-references'], - {'choices': ['superscript', 'brackets'], 'default': 'superscript', + {'choices': ['superscript', 'brackets'], 'default': 'brackets', 'metavar': '', 'overrides': 'trim_footnote_reference_space'}), ('Format for block quote attributions: one of "dash" (em-dash ' diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 50c44c7b9..9d468d8af 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -43,9 +43,9 @@ class Writer(writers.Writer): {'default': 0, 'action': 'store_true', 'validator': frontend.validate_boolean}), ('Format for footnote references: one of "superscript" or ' - '"brackets". Default is "brackets".', + '"brackets". Default is "superscript".', ['--footnote-references'], - {'choices': ['superscript', 'brackets'], 'default': 'brackets', + {'choices': ['superscript', 'brackets'], 'default': 'superscript', 'metavar': '', 'overrides': 'trim_footnote_reference_space'}), ('Use LaTeX citations. ' -- cgit v1.2.1 From 51aff67dab96dbe987b7b225d1d9dc8d3812a9f0 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 1 Oct 2004 18:48:23 +0000 Subject: updated documentation to match newly added ``dispatch`` methods git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2685 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 54 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 21 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 8824f6e5f..5e60d7a1b 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -87,12 +87,11 @@ class Node: 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. (The - `walkabout()` method is similar, except it also calls ``depart_...`` - methods before exiting each node.) + Traverse a tree of `Node` objects, calling the + `dispatch_visit()` method of `visitor` when entering each + node. (The `walkabout()` method is similar, except it also + calls the `dispatch_departure()` method before exiting each + node.) This tree traversal supports limited in-place tree modifications. Replacing one node with one or more nodes is @@ -100,12 +99,12 @@ 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`). Parameter `visitor`: A `NodeVisitor` object, containing a - ``visit_...`` method for each `Node` subclass encountered. + ``visit`` implementation for each `Node` subclass encountered. """ visitor.document.reporter.debug( 'calling dispatch_visit for %s' % self.__class__.__name__, @@ -125,13 +124,13 @@ class Node: def walkabout(self, visitor): """ - 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. + Perform a tree traversal similarly to `Node.walk()` (which + see), except also call the `dispatch_departure()` method + before exiting each node. - Parameter `visitor`: A `NodeVisitor` object, containing ``visit_...`` - and ``depart_...`` methods for each `Node` subclass encountered. + Parameter `visitor`: A `NodeVisitor` object, containing a + ``visit`` and ``depart`` implementation for each `Node` + subclass encountered. """ call_depart = 1 visitor.document.reporter.debug( @@ -1248,14 +1247,17 @@ node_class_names = """ class NodeVisitor: """ - "Visitor" pattern [GoF95]_ abstract superclass implementation for document - tree traversals. + "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 `dispatch_visit()` method is called by + `Node.walk()` upon entering a node. `Node.walkabout()` also calls + the `dispatch_departure()` method before exiting a node. - 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. + The dispatch methods call "``visit_`` + node class name" or + "``depart_`` + node class name", resp. This is a base class for visitors whose ``visit_...`` & ``depart_...`` methods should be implemented for *all* node types encountered (such as @@ -1275,6 +1277,11 @@ class NodeVisitor: self.document = document def dispatch_visit(self, node): + """ + Call self."``visit_`` + node class name" with `node` as + parameter. If the ``visit_...`` method does not exist, call + self.unknown_visit. + """ node_name = node.__class__.__name__ method = getattr(self, 'visit_' + node_name, self.unknown_visit) self.document.reporter.debug( @@ -1283,6 +1290,11 @@ class NodeVisitor: return method(node) def dispatch_departure(self, node): + """ + Call self."``depart_`` + node class name" with `node` as + parameter. If the ``depart_...`` method does not exist, call + self.unknown_departure. + """ node_name = node.__class__.__name__ method = getattr(self, 'depart_' + node_name, self.unknown_departure) self.document.reporter.debug( -- cgit v1.2.1 From 81cbe9fdf4f4d5b57902ddc6d7b764b1250b9c96 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 5 Oct 2004 01:21:26 +0000 Subject: Added support for line block syntax. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2686 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 90 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 60e0bcafd..cdc4258d1 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1090,6 +1090,7 @@ class Body(RSTState): 'field_marker': r':[^: ]([^:]*[^: ])?:( +|$)', 'option_marker': r'%(option)s(, %(option)s)*( +| ?$)' % pats, 'doctest': r'>>>( +|$)', + 'line_block': r'\|( +|$)', 'grid_table_top': grid_table_top_pat, 'simple_table_top': simple_table_top_pat, 'explicit_markup': r'\.\.( +|$)', @@ -1102,6 +1103,7 @@ class Body(RSTState): 'field_marker', 'option_marker', 'doctest', + 'line_block', 'grid_table_top', 'simple_table_top', 'explicit_markup', @@ -1189,12 +1191,12 @@ class Body(RSTState): i, blank_finish = self.list_item(match.end()) bulletlist += i offset = self.state_machine.line_offset + 1 # next line - newline_offset, blank_finish = self.nested_list_parse( + new_line_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) - self.goto_line(newline_offset) + self.goto_line(new_line_offset) if not blank_finish: self.parent += self.unindent_warning('Bullet list') return [], next_state, [] @@ -1476,6 +1478,69 @@ class Body(RSTState): self.parent += nodes.doctest_block(data, data) return [], next_state, [] + def line_block(self, match, context, next_state): + """First line of a line block.""" + block = nodes.line_block() + self.parent += block + lineno = self.state_machine.abs_line_number() + line, messages, blank_finish = self.line_block_line(match, lineno) + block += line + self.parent += messages + if not blank_finish: + offset = self.state_machine.line_offset + 1 # next line + new_line_offset, blank_finish = self.nested_list_parse( + self.state_machine.input_lines[offset:], + input_offset=self.state_machine.abs_line_offset() + 1, + node=block, initial_state='LineBlock', + blank_finish=0) + self.goto_line(new_line_offset) + if not blank_finish: + self.parent += self.reporter.warning( + 'Line block ends without a blank line.', + line=(self.state_machine.abs_line_number() + 1)) + if len(block): + if block[0].indent is None: + block[0].indent = 0 + self.nest_line_block_lines(block) + return [], next_state, [] + + def line_block_line(self, match, lineno): + """Return one line element of a line_block.""" + indented, indent, line_offset, blank_finish = \ + self.state_machine.get_first_known_indented(match.end(), + until_blank=1) + text = u'\n'.join(indented) + text_nodes, messages = self.inline_text(text, lineno) + line = nodes.line(text, '', *text_nodes) + if match.string.rstrip() != '|': # not empty + line.indent = len(match.group(1)) - 1 + return line, messages, blank_finish + + def nest_line_block_lines(self, block): + for index in range(1, len(block)): + if block[index].indent is None: + block[index].indent = block[index - 1].indent + self.nest_line_block_segment(block) + + def nest_line_block_segment(self, block): + indents = [item.indent for item in block] + least = min(indents) + new_items = [] + new_block = nodes.line_block() + for item in block: + if item.indent > least: + new_block.append(item) + else: + if len(new_block): + self.nest_line_block_segment(new_block) + new_items.append(new_block) + new_block = nodes.line_block() + new_items.append(item) + if len(new_block): + self.nest_line_block_segment(new_block) + new_items.append(new_block) + block[:] = new_items + def grid_table_top(self, match, context, next_state): """Top border of a full table.""" return self.table_top(match, context, next_state, @@ -2274,6 +2339,7 @@ class SpecializedBody(Body): field_marker = invalid_input option_marker = invalid_input doctest = invalid_input + line_block = invalid_input grid_table_top = invalid_input simple_table_top = invalid_input explicit_markup = invalid_input @@ -2391,6 +2457,22 @@ class ExtensionOptions(FieldList): lines = [] +class LineBlock(SpecializedBody): + + """Second and subsequent lines of a line_block.""" + + blank = SpecializedBody.invalid_input + + def line_block(self, match, context, next_state): + """New line of line block.""" + lineno = self.state_machine.abs_line_number() + line, messages, blank_finish = self.line_block_line(match, lineno) + self.parent += line + self.parent.parent += messages + self.blank_finish = blank_finish + return [], next_state, [] + + class Explicit(SpecializedBody): """Second and subsequent explicit markup construct.""" @@ -2854,8 +2936,8 @@ class QuotedLiteralBlock(RSTState): state_classes = (Body, BulletList, DefinitionList, EnumeratedList, FieldList, - OptionList, ExtensionOptions, Explicit, Text, Definition, - Line, SubstitutionDef, RFC2822Body, RFC2822List) + OptionList, LineBlock, ExtensionOptions, Explicit, Text, + Definition, Line, SubstitutionDef, RFC2822Body, RFC2822List) """Standard set of State classes used to start `RSTStateMachine`.""" -- cgit v1.2.1 From 0c7e50f7bffa72b34c0f760425c0d56009bafbe6 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 5 Oct 2004 01:21:33 +0000 Subject: Changed structure of ``line_block``; added ``line``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2687 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 5e60d7a1b..660d1f220 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1054,7 +1054,14 @@ class option_string(Part, TextElement): pass class description(Part, Element): pass class literal_block(General, FixedTextElement): pass class doctest_block(General, FixedTextElement): pass -class line_block(General, FixedTextElement): pass +class line_block(General, Element): pass + + +class line(General, TextElement): + + indent = None + + class block_quote(General, Element): pass class attribution(Part, TextElement): pass class attention(Admonition, Element): pass @@ -1229,7 +1236,7 @@ node_class_names = """ generated header hint image important info inline - label legend line_block list_item literal literal_block + label legend line line_block list_item literal literal_block note option option_argument option_group option_list option_list_item option_string organization -- cgit v1.2.1 From ef553a1fe8a6033a97e97a4c72d07632de6fbd7c Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 5 Oct 2004 01:21:47 +0000 Subject: Converted the line-block directive to use the new structure. Extracted the old line-block functionality to the ``block`` function (still used). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2689 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/body.py | 40 ++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 10 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index 85adda981..9d40331ca 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -66,31 +66,51 @@ sidebar.options = {'subtitle': directives.unchanged_required, sidebar.content = 1 def line_block(name, arguments, options, content, lineno, - content_offset, block_text, state, state_machine, - node_class=nodes.line_block): + content_offset, block_text, state, state_machine): if not content: warning = state_machine.reporter.warning( 'Content block expected for the "%s" directive; none found.' % name, nodes.literal_block(block_text, block_text), line=lineno) return [warning] - text = '\n'.join(content) - text_nodes, messages = state.inline_text(text, lineno) - node = node_class(text, '', *text_nodes, **options) - node.line = content_offset + 1 - return [node] + messages + block = nodes.line_block() + node_list = [block] + for line_text in content: + text_nodes, messages = state.inline_text(line_text.strip(), + lineno + content_offset) + line = nodes.line(line_text, '', *text_nodes) + if line_text.strip(): + line.indent = len(line_text) - len(line_text.lstrip()) + block += line + node_list.extend(messages) + content_offset += 1 + state.nest_line_block_lines(block) + return node_list line_block.options = {'class': directives.class_option} 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) + return block(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine, + node_class=nodes.literal_block) parsed_literal.options = {'class': directives.class_option} parsed_literal.content = 1 +def block(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine, node_class): + 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] + text = '\n'.join(content) + text_nodes, messages = state.inline_text(text, lineno) + node = node_class(text, '', *text_nodes, **options) + node.line = content_offset + 1 + return [node] + messages + def rubric(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): rubric_text = arguments[0] -- cgit v1.2.1 From 6bb61d96a0c98bbd68135a3a79284087c9f6e9b3 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 5 Oct 2004 01:22:09 +0000 Subject: Added support for the new line_block/line structure. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2692 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 226708393..18fef7be2 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -841,11 +841,19 @@ class HTMLTranslator(nodes.NodeVisitor): 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, 'pre', CLASS='line-block')) + self.body.append(self.starttag(node, 'div', CLASS='line-block')) def depart_line_block(self, node): - self.body.append('\n\n') + self.body.append('\n') def visit_list_item(self, node): self.body.append(self.starttag(node, 'li', '')) -- cgit v1.2.1 From 73c45ad649d5d414dbba3e7eca9432a1ba5841eb Mon Sep 17 00:00:00 2001 From: grubert Date: Tue, 5 Oct 2004 06:57:59 +0000 Subject: Chg: support new line block in some way. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2701 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 9d468d8af..39b3189b9 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -672,6 +672,8 @@ class LaTeXTranslator(nodes.NodeVisitor): # --------------- # verbatim: to tell encode not to encode. self.verbatim = 0 + # BUG hack to make new line blocks come out some way + self.line_block_depth = 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. @@ -1493,6 +1495,12 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_legend(self, node): self.body.append('}') + def visit_line(self, node): + self.body.append('~~'*self.line_block_depth) + + def depart_line(self, node): + self.body.append('\\\\ \n') + def visit_line_block(self, node): """line-block: * whitespace (including linebreaks) is significant @@ -1500,8 +1508,10 @@ class LaTeXTranslator(nodes.NodeVisitor): * serif typeface """ - self.body.append('\\begin{flushleft}\n') + if self.line_block_depth==0: + self.body.append('\\begin{flushleft}\n') self.insert_none_breaking_blanks = 1 + self.line_block_depth += 1 # mbox would stop LaTeX from wrapping long lines. # but line_blocks are allowed to wrap. self.line_block_without_mbox = 1 @@ -1517,8 +1527,10 @@ class LaTeXTranslator(nodes.NodeVisitor): else: self.body.append('}') self.mbox_newline = 0 + self.line_block_depth -= 1 self.insert_none_breaking_blanks = 0 - self.body.append('\n\\end{flushleft}\n') + if self.line_block_depth==0: + self.body.append('\n\\end{flushleft}\n') def visit_list_item(self, node): # Append "{}" in case the next character is "[", which would break -- cgit v1.2.1 From 4a0ca8481145ffe32962684f5f543ca730d68e98 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 7 Oct 2004 02:17:27 +0000 Subject: moved local dict (char translation) to class attribute git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2703 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 39b3189b9..b21d8aab4 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -746,27 +746,29 @@ class LaTeXTranslator(nodes.NodeVisitor): 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. - 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$}', - } - for uchar in latex_equivalents.keys(): + # 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,latex_equivalents[uchar]) return text -- cgit v1.2.1 From 820d23a9c9c52718760bac6c089c5ccc1b504928 Mon Sep 17 00:00:00 2001 From: cben Date: Sat, 9 Oct 2004 21:47:37 +0000 Subject: fixed a NameError git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2704 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index b21d8aab4..db690c3a0 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -769,7 +769,7 @@ class LaTeXTranslator(nodes.NodeVisitor): # 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,latex_equivalents[uchar]) + text = text.replace(uchar,self.latex_equivalents[uchar]) return text def encode(self, text): -- cgit v1.2.1 From ec1ff4de7d5175824a763277de41fa1d556b68d9 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 16 Oct 2004 15:00:35 +0000 Subject: only strip

    aragraphs in HTML if we don't lose relevant attributes git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2706 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 18fef7be2..847e390dd 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -966,10 +966,12 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_paragraph(self, node): # 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))): + if ((node.attributes in ({}, {'class': 'first'}, {'class': 'last'}, + {'class': 'first last'})) and + (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', '')) -- cgit v1.2.1 From 1c46e36e735eaa4c44d7bd0c5f0b209be515ec21 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 18 Oct 2004 14:21:45 +0000 Subject: made footnote label style match footnote reference style (superscript/brackets) for LaTeX writer git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2713 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index db690c3a0..93a8cf0a4 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1402,18 +1402,22 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('}%s' % self.context.pop()) # footnote/citation label + def label_delim(self, node, bracket, superscript): + if isinstance(node.parent, nodes.footnote) and \ + not self.use_latex_footnotes: + if self.settings.footnote_references == 'brackets': + self.body.append(bracket) + else: + self.body.append(superscript) + elif isinstance(node.parent, nodes.citation) and \ + not self._use_latex_citations: + self.body.append(bracket) + def visit_label(self, node): - if isinstance(node.parent, nodes.footnote) and self.use_latex_footnotes: - raise nodes.SkipNode - elif isinstance(node.parent, nodes.citation) and self._use_latex_citations: - pass - else: - self.body.append('[') + self.label_delim(node, '[', '$^{') def depart_label(self, node): - if isinstance(node.parent, nodes.citation) and self._use_latex_citations: - return - self.body.append(']') + self.label_delim(node, ']', '}$') # elements generated by the framework e.g. section numbers. def visit_generated(self, node): -- cgit v1.2.1 From 9937d8a5651ad5d90babc22cf6bb0d516839ccc6 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 18 Oct 2004 14:56:38 +0000 Subject: added "first" and "last" class attributes for footnotes to fix margins (cvs-up to rev. 1.11 to see the broken margins) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2716 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 847e390dd..d845d7505 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -704,6 +704,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.footnote_backrefs(node) def footnote_backrefs(self, node): + backlinks = [] if self.settings.footnote_backlinks and node.hasattr('backrefs'): backrefs = node['backrefs'] if len(backrefs) == 1: @@ -712,7 +713,6 @@ class HTMLTranslator(nodes.NodeVisitor): 'name="%s">' % (backrefs[0], node['id'])) else: i = 1 - backlinks = [] for backref in backrefs: backlinks.append('%s' % (backref, i)) @@ -722,6 +722,13 @@ class HTMLTranslator(nodes.NodeVisitor): else: self.context.append('') self.context.append('' % node['id']) + # 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].set_class('first') + node[-1].set_class('last') def depart_footnote(self, node): self.body.append('\n' -- cgit v1.2.1 From 2c70de7022257da3b6c9e2e9325cb08d14505b07 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 19 Oct 2004 23:29:44 +0000 Subject: added --strict-visitor option git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2723 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index ed20057d3..bf9b28303 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -436,7 +436,9 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): (SUPPRESS_HELP, ['--dump-pseudo-xml'], {'action': 'store_true'}), (SUPPRESS_HELP, ['--expose-internal-attribute'], {'action': 'append', 'dest': 'expose_internals', - 'validator': validate_colon_separated_string_list}),)) + 'validator': validate_colon_separated_string_list}), + (SUPPRESS_HELP, ['--strict-visitor'], {'action': 'store_true'}), + )) """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()`).""" -- cgit v1.2.1 From aa44e1902eb28a2ddabc3b9f54fe62e1eb164c52 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 19 Oct 2004 23:32:05 +0000 Subject: marked untranslated entries (all!) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2724 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/zh_tw.py | 137 ++++++++++++++++---------------- 1 file changed, 69 insertions(+), 68 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/zh_tw.py b/docutils/parsers/rst/languages/zh_tw.py index faeeac54d..acddae237 100644 --- a/docutils/parsers/rst/languages/zh_tw.py +++ b/docutils/parsers/rst/languages/zh_tw.py @@ -19,79 +19,80 @@ __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', - #'questions': 'questions', - 'table': 'table', - 'csv-table': 'csv-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', - 'contents': 'contents', - 'sectnum': 'sectnum', - 'section-numbering': 'sectnum', - #'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', + #'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', + 'contents (translation required)': 'contents', + 'sectnum (translation required)': 'sectnum', + 'section-numbering (translation required)': 'sectnum', + #'footnotes (translation required)': 'footnotes', + #'citations (translation required)': 'citations', + 'target-notes (translation required)': 'target-notes', 'restructuredtext-test-directive': 'restructuredtext-test-directive'} """English 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',} + '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',} """Mapping of Traditional Chinese role names to canonical role names for interpreted text. """ -- cgit v1.2.1 From 3060e6fbba970093521688e7f665a2ef8e9214d6 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 19 Oct 2004 23:36:31 +0000 Subject: Fixed directive parsing bug: argument-less directives didn't notice that arguments were present. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2725 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index cdc4258d1..0d6362b51 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -2038,6 +2038,9 @@ class Body(RSTState): if option_spec: options, arg_block = self.parse_directive_options( option_presets, option_spec, arg_block) + if arg_block and not argument_spec: + raise MarkupError('no arguments permitted; blank line ' + 'required before content block') if argument_spec: arguments = self.parse_directive_arguments( argument_spec, arg_block) -- cgit v1.2.1 From a5b30fef88ce1820207ff83afb790d71612573ca Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 19 Oct 2004 23:37:23 +0000 Subject: added "compound" directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2726 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/af.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/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 + 13 files changed, 13 insertions(+) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/af.py b/docutils/parsers/rst/languages/af.py index 1c799127f..fda16ccba 100644 --- a/docutils/parsers/rst/languages/af.py +++ b/docutils/parsers/rst/languages/af.py @@ -36,6 +36,7 @@ directives = { 'epigraaf': 'epigraph', 'hoogtepunte': 'highlights', 'pull-quote (translation required)': 'pull-quote', + u'compound (translation required)': 'compound', #'vrae': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/cs.py b/docutils/parsers/rst/languages/cs.py index 111a476eb..1dbd0ca2b 100644 --- a/docutils/parsers/rst/languages/cs.py +++ b/docutils/parsers/rst/languages/cs.py @@ -37,6 +37,7 @@ directives = { u'moto': 'epigraph', u'highlights': 'highlights', u'pull-quote': 'pull-quote', + u'compound (translation required)': 'compound', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index d8dedffd2..8e6df7e92 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -37,6 +37,7 @@ directives = { 'epigraph': 'epigraph', 'highlights (translation required)': 'highlights', 'pull-quote (translation required)': 'pull-quote', # kasten too ? + 'compound (translation required)': 'compound', #'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 f45e104f9..cd69becad 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -37,6 +37,7 @@ directives = { 'epigraph': 'epigraph', 'highlights': 'highlights', 'pull-quote': 'pull-quote', + 'compound': 'compound', #'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 9f269decb..8c0f65d6e 100644 --- a/docutils/parsers/rst/languages/eo.py +++ b/docutils/parsers/rst/languages/eo.py @@ -40,6 +40,7 @@ directives = { u'elstara\u0135oj': 'highlights', u'ekstera-citajxo': 'pull-quote', u'ekstera-cita\u0135o': 'pull-quote', + u'compound (translation required)': 'compound', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index ce5a92a28..076efaa01 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -42,6 +42,7 @@ directives = { u'epigrafe': 'epigraph', u'destacado': 'highlights', u'cita-destacada': 'pull-quote', + u'compound (translation required)': 'compound', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/fi.py b/docutils/parsers/rst/languages/fi.py index 4ccdee84a..72530600c 100644 --- a/docutils/parsers/rst/languages/fi.py +++ b/docutils/parsers/rst/languages/fi.py @@ -39,6 +39,7 @@ directives = { u'lainaus': u'pull-quote', u'taulukko': u'table', u'csv-taulukko': u'csv-table', + u'compound (translation required)': 'compound', #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 a104ae111..9518fb3d2 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -38,6 +38,7 @@ directives = { u'\u00E9pigraphe': 'epigraph', u'chapeau': 'highlights', u'accroche': 'pull-quote', + u'compound (translation required)': 'compound', #u'questions': 'questions', #u'qr': 'questions', #u'faq': 'questions', diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index 1f80e3bc8..e4aa04261 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -36,6 +36,7 @@ directives = { 'epigrafe': 'epigraph', 'evidenzia': 'highlights', 'pull-quote (translation required)': 'pull-quote', + 'compound (translation required)': 'compound', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/pt_br.py b/docutils/parsers/rst/languages/pt_br.py index 36005f344..66aa143c3 100644 --- a/docutils/parsers/rst/languages/pt_br.py +++ b/docutils/parsers/rst/languages/pt_br.py @@ -37,6 +37,7 @@ directives = { u'ep\u00EDgrafo': 'epigraph', 'destaques': 'highlights', u'cita\u00E7\u00E3o-destacada': 'pull-quote', + u'compound (translation required)': 'compound', #'perguntas': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/ru.py b/docutils/parsers/rst/languages/ru.py index ce0dc2b76..87deeebad 100644 --- a/docutils/parsers/rst/languages/ru.py +++ b/docutils/parsers/rst/languages/ru.py @@ -23,6 +23,7 @@ directives = { u'parsed-literal', 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'table (translation required)': 'table', u'csv-table (translation required)': 'csv-table', u'\u0441\u044b\u0440\u043e\u0439': u'raw', diff --git a/docutils/parsers/rst/languages/sk.py b/docutils/parsers/rst/languages/sk.py index 1a508a851..2d637d984 100644 --- a/docutils/parsers/rst/languages/sk.py +++ b/docutils/parsers/rst/languages/sk.py @@ -36,6 +36,7 @@ directives = { u'epigraph (translation required)': 'epigraph', u'highlights (translation required)': 'highlights', u'pull-quote (translation required)': 'pull-quote', + u'compound (translation required)': 'compound', #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 f4f8ee6a7..e014bc612 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -35,6 +35,7 @@ directives = { u'epigraph (translation required)': 'epigraph', u'highlights (translation required)': 'highlights', u'pull-quote (translation required)': 'pull-quote', + u'compound (translation required)': 'compound', # u'fr\u00e5gor': 'questions', # NOTE: A bit long, but recommended by http://www.nada.kth.se/dataterm/: # u'fr\u00e5gor-och-svar': 'questions', -- cgit v1.2.1 From 90c7498f0650fbbc5b375773a326e33e856d35cd Mon Sep 17 00:00:00 2001 From: richieadler Date: Wed, 20 Oct 2004 00:47:01 +0000 Subject: translation for the new "compound" directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2730 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/eo.py | 3 ++- docutils/parsers/rst/languages/es.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/eo.py b/docutils/parsers/rst/languages/eo.py index 8c0f65d6e..3e3c77c41 100644 --- a/docutils/parsers/rst/languages/eo.py +++ b/docutils/parsers/rst/languages/eo.py @@ -40,7 +40,8 @@ directives = { u'elstara\u0135oj': 'highlights', u'ekstera-citajxo': 'pull-quote', u'ekstera-cita\u0135o': 'pull-quote', - u'compound (translation required)': 'compound', + u'kombinajxo': 'compound', + u'kombina\u0135o': 'compound', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index 076efaa01..363e13516 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -42,7 +42,8 @@ directives = { u'epigrafe': 'epigraph', u'destacado': 'highlights', u'cita-destacada': 'pull-quote', - u'compound (translation required)': 'compound', + u'combinacion': 'compound', + u'combinaci\u00f3n': 'compound', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', -- cgit v1.2.1 From 4e92a1c8f5d8c9b33337526a3856ebe660b5679c Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 20 Oct 2004 13:45:44 +0000 Subject: Added ``compound`` node class. Added a mechanism for Visitors to transitionally ignore new node classes. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2731 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 660d1f220..f8043a960 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1012,6 +1012,7 @@ class transition(Structural, Element): pass # =============== class paragraph(General, TextElement): pass +class compound(General, Element): pass class bullet_list(Sequential, Element): pass class enumerated_list(Sequential, Element): pass class list_item(Part, Element): pass @@ -1227,7 +1228,7 @@ node_class_names = """ authors block_quote bullet_list caption caution citation citation_reference classifier colspec comment - contact copyright + compound contact copyright danger date decoration definition definition_list definition_list_item description docinfo doctest_block document emphasis entry enumerated_list error @@ -1280,6 +1281,14 @@ class NodeVisitor: 1995. """ + optional = ('compound',) + """ + No exception will be raised if writers do not implement visit + or departure functions for these node classes. + + Used to ensure transitional compatibility with existing 3rd-party writers. + """ + def __init__(self, document): self.document = document @@ -1315,8 +1324,11 @@ class NodeVisitor: Raise an exception unless overridden. """ - raise NotImplementedError('%s visiting unknown node type: %s' - % (self.__class__, node.__class__.__name__)) + if (node.document.settings.strict_visitor + or node.__class__.__name__ not in self.optional): + raise NotImplementedError( + '%s visiting unknown node type: %s' + % (self.__class__, node.__class__.__name__)) def unknown_departure(self, node): """ @@ -1324,8 +1336,11 @@ class NodeVisitor: Raise exception unless overridden. """ - raise NotImplementedError('%s departing unknown node type: %s' - % (self.__class__, node.__class__.__name__)) + if (node.document.settings.strict_visitor + or node.__class__.__name__ not in self.optional): + raise NotImplementedError( + '%s departing unknown node type: %s' + % (self.__class__, node.__class__.__name__)) class SparseNodeVisitor(NodeVisitor): -- cgit v1.2.1 From 54ce70ca93e577ba2bdddfb18bbae692cfdb57aa Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 20 Oct 2004 13:46:31 +0000 Subject: Added ``compound`` directive. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2732 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 1 + docutils/parsers/rst/directives/body.py | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index bd8f84e8a..828a830de 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -109,6 +109,7 @@ _directive_registry = { 'epigraph': ('body', 'epigraph'), 'highlights': ('body', 'highlights'), 'pull-quote': ('body', 'pull_quote'), + 'compound': ('body', 'compound'), #'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 9d40331ca..cfc3c04f4 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -144,3 +144,20 @@ def pull_quote(name, arguments, options, content, lineno, return [block_quote] + messages pull_quote.content = 1 + +def compound(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] + node = nodes.compound(text) + if options.has_key('class'): + node.set_class(options['class']) + state.nested_parse(content, content_offset, node) + return [node] + +compound.options = {'class': directives.class_option} +compound.content = 1 -- cgit v1.2.1 From b22ea3054a7f417e5d03e6a8ed39d43b47f46968 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 20 Oct 2004 13:47:25 +0000 Subject: Added support for ``compound`` elements. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2733 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 6 ++++++ docutils/writers/latex2e.py | 12 ++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index d845d7505..50772e814 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -460,6 +460,12 @@ class HTMLTranslator(nodes.NodeVisitor): # Content already processed: raise nodes.SkipNode + def visit_compound(self, node): + self.body.append(self.starttag(node, 'div', CLASS='compound')) + + def depart_compound(self, node): + self.body.append('\n') + def visit_contact(self, node): self.visit_docinfo_item(node, 'contact', meta=None) diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 93a8cf0a4..af2ae2a32 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -10,7 +10,7 @@ LaTeX2e document tree Writer. __docformat__ = 'reStructuredText' -# code contributions from several people included, thanks too all. +# 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. ##. @@ -1034,6 +1034,12 @@ class LaTeXTranslator(nodes.NodeVisitor): 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') @@ -1694,7 +1700,9 @@ class LaTeXTranslator(nodes.NodeVisitor): self.depart_docinfo_item(node) def visit_paragraph(self, node): - if not self.topic_class == 'contents': + if not (self.topic_class == 'contents' + or (isinstance(node.parent, nodes.compound) + and node.parent.index(node) > 0)): self.body.append('\n') def depart_paragraph(self, node): -- cgit v1.2.1 From 86949c4728d404a74dfdf0fedabde32ff9d751de Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 20 Oct 2004 16:19:33 +0000 Subject: added German translation for "compound" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2738 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/de.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index 8e6df7e92..5d7e6a006 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -37,7 +37,8 @@ directives = { 'epigraph': 'epigraph', 'highlights (translation required)': 'highlights', 'pull-quote (translation required)': 'pull-quote', # kasten too ? - 'compound (translation required)': 'compound', + 'zusammengesetzt': 'compound', + 'verbund': 'compound', #'fragen': 'questions', 'tabelle': 'table', 'csv-tabelle': 'csv-table', -- cgit v1.2.1 From 7a61fb0b3b0beea0aeb3d301295e7ec225cbf358 Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 20 Oct 2004 16:33:40 +0000 Subject: added logic to avoid merging of consecutive simple paragraphs in compound paragraphs in LaTeX git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2740 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index af2ae2a32..e8f3ae47e 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1700,9 +1700,11 @@ class LaTeXTranslator(nodes.NodeVisitor): self.depart_docinfo_item(node) def visit_paragraph(self, node): + index = node.parent.index(node) if not (self.topic_class == 'contents' or (isinstance(node.parent, nodes.compound) - and node.parent.index(node) > 0)): + and index > 0 and not isinstance(node.parent[index - 1], + nodes.paragraph))): self.body.append('\n') def depart_paragraph(self, node): -- cgit v1.2.1 From c96f2e5fac9e52f0d052744bef1a640adc7fa7bb Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 20 Oct 2004 17:34:36 +0000 Subject: added handling for nested compounds git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2741 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index e8f3ae47e..fc6153719 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1701,10 +1701,11 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_paragraph(self, node): index = node.parent.index(node) - if not (self.topic_class == 'contents' - or (isinstance(node.parent, nodes.compound) - and index > 0 and not isinstance(node.parent[index - 1], - nodes.paragraph))): + if not (self.topic_class == 'contents' 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): -- cgit v1.2.1 From 8e067440b8d610dfbd2b43e2a8a284d74e6eaa2d Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 20 Oct 2004 18:00:35 +0000 Subject: removed doubly declared method git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2743 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index fc6153719..0d5eda7c8 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -367,8 +367,6 @@ class Table: if self._table_style == 'booktabs': return '\\usepackage{booktabs}\n' return '' - def is_open(self): - return self._open def get_latex_type(self): return self._latex_type -- cgit v1.2.1 From 530600fba00013cf7ba8ca7ddaeceb5f52a0a1c9 Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 20 Oct 2004 19:19:25 +0000 Subject: improved line-block support for LaTeX writer git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2744 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 52 +++++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 33 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 0d5eda7c8..30497a3e2 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -282,6 +282,16 @@ latex_headings = { ' \\renewcommand{\\makelabel}{\\optionlistlabel}}\n' '}{\\end{list}}\n', ], + 'lineblock_environment' : [ + '\\newenvironment{lineblock}\n' + '{\\begin{list}{}\n' + ' {\\setlength{\\partopsep}{\\parskip}\n' + ' \\addtolength{\\partopsep}{\\baselineskip}\n' + ' \\topsep0pt\\itemsep0.15\\baselineskip\\parsep0pt\n' + ' \\leftmargin2em}\n' + ' \\raggedright}\n' + '{\\end{list}}\n' + ], 'footnote_floats' : [ '% begin: floats for footnotes tweaking.\n', '\\setlength{\\floatsep}{0.5em}\n', @@ -295,13 +305,13 @@ latex_headings = { '\\setcounter{bottomnumber}{50}\n', '% end floats for footnotes\n', ], - 'some_commands' : [ + '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: @@ -634,6 +644,7 @@ class LaTeXTranslator(nodes.NodeVisitor): # 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. @@ -670,8 +681,6 @@ class LaTeXTranslator(nodes.NodeVisitor): # --------------- # verbatim: to tell encode not to encode. self.verbatim = 0 - # BUG hack to make new line blocks come out some way - self.line_block_depth = 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. @@ -1506,41 +1515,18 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('}') def visit_line(self, node): - self.body.append('~~'*self.line_block_depth) + self.body.append('\item[] ') def depart_line(self, node): - self.body.append('\\\\ \n') + self.body.append('\n') def visit_line_block(self, node): - """line-block: - * whitespace (including linebreaks) is significant - * inline markup is supported. - * serif typeface - - """ - if self.line_block_depth==0: - self.body.append('\\begin{flushleft}\n') - self.insert_none_breaking_blanks = 1 - self.line_block_depth += 1 - # mbox would stop LaTeX from wrapping long lines. - # but line_blocks are allowed to wrap. - self.line_block_without_mbox = 1 - if self.line_block_without_mbox: - self.insert_newline = 1 - else: - self.mbox_newline = 1 - self.body.append('\\mbox{') + if isinstance(node.parent, nodes.line_block): + self.body.append('\\item[] ') + self.body.append('\n\\begin{lineblock}\n') def depart_line_block(self, node): - if self.line_block_without_mbox: - self.insert_newline = 0 - else: - self.body.append('}') - self.mbox_newline = 0 - self.line_block_depth -= 1 - self.insert_none_breaking_blanks = 0 - if self.line_block_depth==0: - self.body.append('\n\\end{flushleft}\n') + self.body.append('\\end{lineblock}\n') def visit_list_item(self, node): # Append "{}" in case the next character is "[", which would break -- cgit v1.2.1 From 22448f740617422662cb43a9025609f108559ce9 Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 20 Oct 2004 19:41:45 +0000 Subject: made outermost line block unindented for LaTeX writer git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2747 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 30497a3e2..95bf70bed 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -283,12 +283,12 @@ latex_headings = { '}{\\end{list}}\n', ], 'lineblock_environment' : [ - '\\newenvironment{lineblock}\n' + '\\newenvironment{lineblock}[1]\n' '{\\begin{list}{}\n' ' {\\setlength{\\partopsep}{\\parskip}\n' ' \\addtolength{\\partopsep}{\\baselineskip}\n' ' \\topsep0pt\\itemsep0.15\\baselineskip\\parsep0pt\n' - ' \\leftmargin2em}\n' + ' \\leftmargin#1}\n' ' \\raggedright}\n' '{\\end{list}}\n' ], @@ -1522,8 +1522,9 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_line_block(self, node): if isinstance(node.parent, nodes.line_block): - self.body.append('\\item[] ') - self.body.append('\n\\begin{lineblock}\n') + self.body.append('\\item[] \n\\begin{lineblock}{1.5em}\n') + else: + self.body.append('\n\\begin{lineblock}{0em}\n') def depart_line_block(self, node): self.body.append('\\end{lineblock}\n') -- cgit v1.2.1 From 25f02bab6e61674afc8b21ac6dca450257ad8fbf Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 20 Oct 2004 20:46:16 +0000 Subject: made line block indentation parametrizable; changed to 2.5em to avoid visual confusion with paragraph first-line indentation git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2748 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 95bf70bed..ee8821b6c 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -283,6 +283,8 @@ latex_headings = { '}{\\end{list}}\n', ], 'lineblock_environment' : [ + '\\newlength{\\lineblockindentation}\n' + '\\setlength{\\lineblockindentation}{2.5em}\n' '\\newenvironment{lineblock}[1]\n' '{\\begin{list}{}\n' ' {\\setlength{\\partopsep}{\\parskip}\n' @@ -1522,7 +1524,8 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_line_block(self, node): if isinstance(node.parent, nodes.line_block): - self.body.append('\\item[] \n\\begin{lineblock}{1.5em}\n') + self.body.append('\\item[] \n' + '\\begin{lineblock}{\\lineblockindentation}\n') else: self.body.append('\n\\begin{lineblock}{0em}\n') -- cgit v1.2.1 From 1f3e15ca9297a994be3113e08144d41178623f34 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 21 Oct 2004 01:27:56 +0000 Subject: moved first/last class-setting logic to method;

    tags aren't stripped in compound nodes anymore git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2750 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 50772e814..ae9880b57 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -291,6 +291,11 @@ class HTMLTranslator(nodes.NodeVisitor): """Construct and return an XML-compatible empty tag.""" return self.starttag(node, tagname, suffix, infix=' /', **attributes) + def set_first_last(self, node): + if len(node): + node[0].set_class('first') + node[-1].set_class('last') + def visit_Text(self, node): self.body.append(self.encode(node.astext())) @@ -499,9 +504,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_definition(self, node): self.body.append('\n') self.body.append(self.starttag(node, 'dd', '')) - if len(node): - node[0].set_class('first') - node[-1].set_class('last') + self.set_first_last(node) def depart_definition(self, node): self.body.append('\n') @@ -520,9 +523,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_description(self, node): self.body.append(self.starttag(node, 'td', '')) - if len(node): - node[0].set_class('first') - node[-1].set_class('last') + self.set_first_last(node) def depart_description(self, node): self.body.append('') @@ -597,9 +598,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.context.append('\n' % tagname.lower()) if len(node) == 0: # empty cell self.body.append(' ') - else: - node[0].set_class('first') - node[-1].set_class('last') + self.set_first_last(node) def depart_entry(self, node): self.body.append(self.context.pop()) @@ -646,9 +645,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_field_body(self, node): self.body.append(self.starttag(node, 'td', '', CLASS='field-body')) - if len(node): - node[0].set_class('first') - node[-1].set_class('last') + self.set_first_last(node) def depart_field_body(self, node): self.body.append('\n') @@ -979,7 +976,8 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_paragraph(self, node): # Omit

    tags if this is an only child and optimizable. - if ((node.attributes in ({}, {'class': 'first'}, {'class': 'last'}, + if (not isinstance(node.parent, nodes.compound) and + (node.attributes in ({}, {'class': 'first'}, {'class': 'last'}, {'class': 'first last'})) and (self.compact_simple or self.compact_p and (len(node.parent) == 1 or -- cgit v1.2.1 From 3d05eaa6ec0678f844f7638f5b018737dc67d757 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 21 Oct 2004 02:17:23 +0000 Subject: reduced vertical space in compound blocks in HTML by adding compound-{first,middle,last} classes git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2751 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index ae9880b57..3a3c06f9e 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -467,6 +467,11 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_compound(self, node): self.body.append(self.starttag(node, 'div', CLASS='compound')) + if len(node) > 1: + node[0].set_class('compound-first') + node[-1].set_class('compound-last') + for child in node[1:-1]: + child.set_class('compound-middle') def depart_compound(self, node): self.body.append('\n') -- cgit v1.2.1 From d2995e5fff30d16439cae71a4f6aa3d173a92b7b Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 22 Oct 2004 01:51:28 +0000 Subject: fixed unwanted interaction of "class" directive and enumerated lists (start != 1) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2761 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 0d6362b51..0f8bdcf83 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1215,13 +1215,13 @@ class Body(RSTState): format, sequence, text, ordinal = self.parse_enumerator(match) if not self.is_enumerated_list_item(ordinal, sequence, format): raise statemachine.TransitionCorrection('text') + enumlist = nodes.enumerated_list() + self.parent += enumlist if ordinal != 1: msg = self.reporter.info( 'Enumerated list start value not ordinal-1: "%s" (ordinal %s)' % (text, ordinal), line=self.state_machine.abs_line_number()) self.parent += msg - enumlist = nodes.enumerated_list() - self.parent += enumlist enumlist['enumtype'] = sequence if ordinal != 1: enumlist['start'] = ordinal -- cgit v1.2.1 From 51768bcfb012ab6819afb5f726043f29386e739f Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 22 Oct 2004 02:10:43 +0000 Subject: small simplification git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2762 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 0f8bdcf83..a1e34d5d1 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1217,16 +1217,15 @@ class Body(RSTState): raise statemachine.TransitionCorrection('text') enumlist = nodes.enumerated_list() self.parent += enumlist + enumlist['enumtype'] = sequence + enumlist['prefix'] = self.enum.formatinfo[format].prefix + enumlist['suffix'] = self.enum.formatinfo[format].suffix if ordinal != 1: + enumlist['start'] = ordinal msg = self.reporter.info( 'Enumerated list start value not ordinal-1: "%s" (ordinal %s)' % (text, ordinal), line=self.state_machine.abs_line_number()) self.parent += msg - enumlist['enumtype'] = sequence - if ordinal != 1: - enumlist['start'] = ordinal - enumlist['prefix'] = self.enum.formatinfo[format].prefix - enumlist['suffix'] = self.enum.formatinfo[format].suffix listitem, blank_finish = self.list_item(match.end()) enumlist += listitem offset = self.state_machine.line_offset + 1 # next line -- cgit v1.2.1 From c06ad6d8db73f5c13c2e42a89f9f11519c736b7d Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 23 Oct 2004 13:30:26 +0000 Subject: Do not create empty href's in HTML. Do not crash when encountering a reference node without any of refuri, refid or refname. Is this a valid fix for ? If yes, I'll add tests. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2764 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 3a3c06f9e..0372b75cc 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -429,8 +429,9 @@ class HTMLTranslator(nodes.NodeVisitor): href = '#' + node['refid'] elif node.has_key('refname'): href = '#' + self.document.nameids[node['refname']] - self.body.append(self.starttag(node, 'a', '[', href=href, - CLASS='citation-reference')) + self.body.append(self.starttag(node, 'a', '[', + CLASS='citation-reference', + **(href and {'href': href} or {}))) def depart_citation_reference(self, node): self.body.append(']') @@ -758,8 +759,9 @@ class HTMLTranslator(nodes.NodeVisitor): else: # shouldn't happen suffix = '???' self.content.append('???') - self.body.append(self.starttag(node, 'a', suffix, href=href, - CLASS='footnote-reference')) + self.body.append(self.starttag(node, 'a', suffix, + CLASS='footnote-reference', + **(href and {'href': href} or {}))) def depart_footnote_reference(self, node): self.body.append(self.context.pop() + '') @@ -1021,14 +1023,15 @@ class HTMLTranslator(nodes.NodeVisitor): else: self.body.append('

    ') self.context.append('

    \n') + href = '' if node.has_key('refuri'): href = node['refuri'] elif 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', '', href=href, - CLASS='reference')) + self.body.append(self.starttag(node, 'a', '', CLASS='reference', + **(href and {'href': href} or {}))) def depart_reference(self, node): self.body.append('') -- cgit v1.2.1 From 03ec9cf2b5bb45061f3b3205c27a26f27b673560 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 24 Oct 2004 14:50:33 +0000 Subject: class directive now skips system_messages git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2766 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/misc.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/transforms/misc.py b/docutils/transforms/misc.py index 520a5febb..b325f554b 100644 --- a/docutils/transforms/misc.py +++ b/docutils/transforms/misc.py @@ -52,7 +52,8 @@ class ClassAttribute(Transform): # Check for appropriate following siblings: for index in range(parent.index(child) + 1, len(parent)): element = parent[index] - if isinstance(element, nodes.Invisible): + if (isinstance(element, nodes.Invisible) or + isinstance(element, nodes.system_message)): continue element.set_class(class_value) pending.parent.remove(pending) -- cgit v1.2.1 From 4513833b27e558a8837877231abb4ce8b886b37b Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 25 Oct 2004 13:05:43 +0000 Subject: fixed documentation of RSTStateMachine.run() git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2768 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index a1e34d5d1..2c33cb081 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -144,11 +144,10 @@ class RSTStateMachine(StateMachineWS): def run(self, input_lines, document, input_offset=0, match_titles=1, inliner=None): """ - Parse `input_lines` and return a `docutils.nodes.document` instance. + Parse `input_lines` and modify the `document` node in place. - Extend `StateMachineWS.run()`: set up parse-global data, run the - StateMachine, and return the resulting - document. + Extend `StateMachineWS.run()`: set up parse-global data and + run the StateMachine. """ self.language = languages.get_language( document.settings.language_code) @@ -290,7 +289,7 @@ class RSTState(StateWS): 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 + `block`. Also keep track of optional intermediate blank lines and the required final one. """ if state_machine_class is None: -- cgit v1.2.1 From fe35db23f3879636016b8ec0a55f19aee5f7a29c Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 26 Oct 2004 21:48:47 +0000 Subject: typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2769 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index f8043a960..aff852322 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1177,7 +1177,7 @@ class pending(Special, Invisible, PreBibliographic, Element): def copy(self): return self.__class__(self.transform, self.details, self.rawsource, - **self.attribuates) + **self.attributes) class raw(Special, Inline, PreBibliographic, FixedTextElement): -- cgit v1.2.1 From 834bddc8060f2087a3b4feeabf6e1478721595f0 Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 27 Oct 2004 10:00:40 +0000 Subject: improved documentation of Node.pformat git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2770 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index aff852322..7d1d8adc2 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -69,7 +69,11 @@ class Node: return self._dom_node(domroot) def pformat(self, indent=' ', level=0): - """Return an indented pseudo-XML representation, for test purposes.""" + """ + Return an indented pseudo-XML representation, for test purposes. + + Override in subclasses. + """ raise NotImplementedError def copy(self): -- cgit v1.2.1 From 4fa1e4a87367088a71013e7f3a2f3ea6a56f582e Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 30 Oct 2004 13:51:52 +0000 Subject: added structural.py for structural transforms, with Transition transform git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2771 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/structural.py | 85 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 docutils/transforms/structural.py (limited to 'docutils') diff --git a/docutils/transforms/structural.py b/docutils/transforms/structural.py new file mode 100644 index 000000000..c293f83e7 --- /dev/null +++ b/docutils/transforms/structural.py @@ -0,0 +1,85 @@ +# Author: Felix Wiemann +# Contact: Felix_Wiemann@ososo.de +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Transforms for structural elements. +""" + +__docformat__ = 'reStructuredText' + +from docutils import nodes +from docutils.transforms import Transform + +class Transition(Transform): + + """ + Replace a pending transition by a real transition, moving + 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:: + +
    + ... + +
    + ... + + into this:: + +
    + ... + +
    + ... + """ + + default_priority = 810 + + def apply(self): + node = self.startnode + lineno = node.line + 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=lineno) + elif (isinstance(node.parent[index - 1], nodes.pending) and + isinstance(node.parent[index - 1].transform, self.__class__) or + 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=lineno) + if error: + # Insert before node and update index. + node.parent.insert(index, error) + index += 1 + # Create a real transition for later insertion. + transition = nodes.transition(node.rawsource) + while index == len(node.parent) - 1: + node = node.parent + if node.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=lineno) + self.startnode.parent.insert( + self.startnode.parent.index(self.startnode), + [transition, error]) + self.startnode.parent.remove(self.startnode) + return + index = node.parent.index(node) + node.parent.insert(index + 1, transition) + self.startnode.parent.remove(self.startnode) -- cgit v1.2.1 From 88a4789f802608b293da9f7be6af821103ab4222 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 30 Oct 2004 13:53:50 +0000 Subject: insert pending transition instead of real transition; removed error checking code git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2772 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 33 ++++++--------------------------- 1 file changed, 6 insertions(+), 27 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 2c33cb081..b99687505 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -116,6 +116,7 @@ from docutils.nodes import fully_normalize_name as normalize_name from docutils.nodes import whitespace_normalize_name from docutils.parsers.rst import directives, languages, tableparser, roles from docutils.parsers.rst.languages import en as _fallback_language_module +from docutils.transforms.structural import Transition as TransitionTransform class MarkupError(DataError): pass @@ -403,16 +404,6 @@ class RSTState(StateWS): 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): """ @@ -2748,13 +2739,11 @@ class Line(SpecializedText): 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 = nodes.pending(TransitionTransform, + rawsource=context[0]) transition.line = lineno + self.document.note_pending(transition) self.parent += transition - msg = self.reporter.error( - 'Document or section may not end with a transition.', - line=lineno) - self.parent += msg self.eofcheck = 1 return [] @@ -2764,19 +2753,9 @@ class Line(SpecializedText): marker = context[0].strip() if len(marker) < 4: self.state_correction(context) - transition = nodes.transition(marker) + transition = nodes.pending(TransitionTransform, rawsource=marker) transition.line = lineno - if len(self.parent) == 0: - msg = self.reporter.error( - 'Document or section may not begin with a transition.', - 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=lineno) - self.parent += msg + self.document.note_pending(transition) self.parent += transition return [], 'Body', [] -- cgit v1.2.1 From 54bea9c700c038c02df30a191545eb1e4c686ebe Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 30 Oct 2004 15:56:50 +0000 Subject: insert real transitions git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2780 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index b99687505..7d0b1bca2 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -116,7 +116,6 @@ from docutils.nodes import fully_normalize_name as normalize_name from docutils.nodes import whitespace_normalize_name from docutils.parsers.rst import directives, languages, tableparser, roles from docutils.parsers.rst.languages import en as _fallback_language_module -from docutils.transforms.structural import Transition as TransitionTransform class MarkupError(DataError): pass @@ -2739,10 +2738,8 @@ class Line(SpecializedText): self.state_correction(context) if self.eofcheck: # ignore EOFError with sections lineno = self.state_machine.abs_line_number() - 1 - transition = nodes.pending(TransitionTransform, - rawsource=context[0]) + transition = nodes.transition(rawsource=context[0]) transition.line = lineno - self.document.note_pending(transition) self.parent += transition self.eofcheck = 1 return [] @@ -2753,9 +2750,8 @@ class Line(SpecializedText): marker = context[0].strip() if len(marker) < 4: self.state_correction(context) - transition = nodes.pending(TransitionTransform, rawsource=marker) + transition = nodes.transition(rawsource=marker) transition.line = lineno - self.document.note_pending(transition) self.parent += transition return [], 'Body', [] -- cgit v1.2.1 From c684a39a8dd55bf49cff7bd02eceb12da06200f0 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 30 Oct 2004 16:00:40 +0000 Subject: moved transition transformation code to universal.FinalCheckVisitor git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2781 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/structural.py | 85 --------------------------------------- docutils/transforms/universal.py | 69 ++++++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 86 deletions(-) delete mode 100644 docutils/transforms/structural.py (limited to 'docutils') diff --git a/docutils/transforms/structural.py b/docutils/transforms/structural.py deleted file mode 100644 index c293f83e7..000000000 --- a/docutils/transforms/structural.py +++ /dev/null @@ -1,85 +0,0 @@ -# Author: Felix Wiemann -# Contact: Felix_Wiemann@ososo.de -# Revision: $Revision$ -# Date: $Date$ -# Copyright: This module has been placed in the public domain. - -""" -Transforms for structural elements. -""" - -__docformat__ = 'reStructuredText' - -from docutils import nodes -from docutils.transforms import Transform - -class Transition(Transform): - - """ - Replace a pending transition by a real transition, moving - 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:: - -
    - ... - -
    - ... - - into this:: - -
    - ... - -
    - ... - """ - - default_priority = 810 - - def apply(self): - node = self.startnode - lineno = node.line - 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=lineno) - elif (isinstance(node.parent[index - 1], nodes.pending) and - isinstance(node.parent[index - 1].transform, self.__class__) or - 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=lineno) - if error: - # Insert before node and update index. - node.parent.insert(index, error) - index += 1 - # Create a real transition for later insertion. - transition = nodes.transition(node.rawsource) - while index == len(node.parent) - 1: - node = node.parent - if node.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=lineno) - self.startnode.parent.insert( - self.startnode.parent.index(self.startnode), - [transition, error]) - self.startnode.parent.remove(self.startnode) - return - index = node.parent.index(node) - node.parent.insert(index + 1, transition) - self.startnode.parent.remove(self.startnode) diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 45e74f3e3..62304e2a8 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -151,9 +151,10 @@ class TestMessages(Transform): class FinalChecks(Transform): """ - Perform last-minute checks. + Perform last-minute checks and transforms. - Check for dangling references (incl. footnote & citation). + - Check for illegal transitions, move transitions. """ default_priority = 840 @@ -210,6 +211,72 @@ class FinalCheckVisitor(nodes.SparseNodeVisitor): 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:: + +
    + ... + +
    + ... + + into this:: + +
    + ... + +
    + ... + """ + 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): -- cgit v1.2.1 From 68914c72adf11349ce49f23d22ebb8a6c7be4c96 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 31 Oct 2004 21:24:04 +0000 Subject: made PreBibliographic nodes Invisible git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2789 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 7d1d8adc2..7a498e425 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -591,7 +591,7 @@ class Admonition(Body): pass class Special(Body): """Special internal body elements.""" -class Invisible: +class Invisible(PreBibliographic): """Internal elements that don't appear in output.""" class Part: pass @@ -1079,7 +1079,7 @@ class tip(Admonition, Element): pass class hint(Admonition, Element): pass class warning(Admonition, Element): pass class admonition(Admonition, Element): pass -class comment(Special, Invisible, PreBibliographic, FixedTextElement): pass +class comment(Special, Invisible, FixedTextElement): pass class substitution_definition(Special, Invisible, TextElement): pass class target(Special, Invisible, Inline, TextElement, Targetable): pass class footnote(General, Element, Labeled, BackLinkable): pass @@ -1115,7 +1115,7 @@ class system_message(Special, PreBibliographic, Element, BackLinkable): self['level'], Element.astext(self)) -class pending(Special, Invisible, PreBibliographic, Element): +class pending(Special, Invisible, Element): """ The "pending" element is used to encapsulate a pending operation: the -- cgit v1.2.1 From b3e9a23e50a601b58933870569c83a8aff859c5e Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 2 Nov 2004 22:14:14 +0000 Subject: Added "trim", "ltrim", and "rtrim" options to "unicode" directive. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2795 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index fc797e1eb..ee62f791b 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -177,7 +177,7 @@ def replace(name, arguments, options, content, lineno, replace.content = 1 def unicode_directive(name, arguments, options, content, lineno, - content_offset, block_text, state, state_machine): + content_offset, block_text, state, state_machine): r""" Convert Unicode character codes (numbers) to characters. Codes may be decimal numbers, hexadecimal numbers (prefixed by ``0x``, ``x``, ``\x``, @@ -191,6 +191,14 @@ def unicode_directive(name, arguments, options, content, lineno, 'substitution definition.' % (name), nodes.literal_block(block_text, block_text), line=lineno) return [error] + substitution_definition = state_machine.node + if options.has_key('trim'): + substitution_definition.attributes['ltrim'] = 1 + substitution_definition.attributes['rtrim'] = 1 + if options.has_key('ltrim'): + substitution_definition.attributes['ltrim'] = 1 + if options.has_key('rtrim'): + substitution_definition.attributes['rtrim'] = 1 codes = unicode_comment_pattern.split(arguments[0])[0].split() element = nodes.Element() for code in codes: @@ -206,6 +214,9 @@ def unicode_directive(name, arguments, options, content, lineno, return element.children unicode_directive.arguments = (1, 0, 1) +unicode_directive.options = {'trim': directives.flag, + 'ltrim': directives.flag, + 'rtrim': directives.flag} unicode_comment_pattern = re.compile(r'( |\n|^)\.\. ') def class_directive(name, arguments, options, content, lineno, -- cgit v1.2.1 From 9e41a6191aee10eedfa1df2d0d10a4700a194e55 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 2 Nov 2004 22:14:24 +0000 Subject: Added support for trimming whitespace from beside substitution references. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2796 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 04b79a1cc..254a0ee07 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -700,7 +700,22 @@ class Substitutions(Transform): msg.add_backref(prbid) ref.parent.replace(ref, prb) else: - ref.parent.replace(ref, defs[key].get_children()) + 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()) + parent.replace(ref, subdef.get_children()) self.document.substitution_refs = None # release replaced references -- cgit v1.2.1 From a6a2dd50bbaaea7412ef021329d7b3b518636583 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 3 Nov 2004 14:31:26 +0000 Subject: Enabled multiple format names for "raw" directive. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2799 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 4 ++-- docutils/writers/html4css1.py | 2 +- docutils/writers/latex2e.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index ee62f791b..49f3fb498 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -73,7 +73,7 @@ def raw(name, arguments, options, content, lineno, Content may be included inline (content section of directive) or imported from a file or url. """ - attributes = {'format': arguments[0]} + attributes = {'format': ' '.join(arguments[0].lower().split())} encoding = options.get('encoding', state.document.settings.input_encoding) if content: if options.has_key('file') or options.has_key('url'): @@ -82,7 +82,7 @@ def raw(name, arguments, options, content, lineno, 'have content.' % name, nodes.literal_block(block_text, block_text), line=lineno) return [error] - text = '\n'.join(content) + text = '\n'.join(content) + '\n' elif options.has_key('file'): if options.has_key('url'): error = state_machine.reporter.error( diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 0372b75cc..e03e042ce 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -1012,7 +1012,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.context.pop()) def visit_raw(self, node): - if node.get('format') == 'html': + if 'html' in node.get('format', '').split(): self.body.append(node.astext()) # Keep non-HTML raw text out of output: raise nodes.SkipNode diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index ee8821b6c..d3bce4128 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1706,7 +1706,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('}') def visit_raw(self, node): - if node.has_key('format') and node['format'].lower() == 'latex': + if 'latex' in node.get('format', '').split(): self.body.append(node.astext()) raise nodes.SkipNode -- cgit v1.2.1 From 097815228a511d2c7da47cf4c4d2141893556dcd Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 3 Nov 2004 20:11:11 +0000 Subject: Added support for multiple classifiers in definition list items. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2802 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 7d0b1bca2..874110a30 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -2657,8 +2657,10 @@ class Text(RSTState): self.nested_parse(indented, input_offset=line_offset, node=definition) return definitionlistitem, blank_finish + classifier_delimiter = re.compile(' +: +') + def term(self, lines, lineno): - """Return a definition_list's term and optional classifier.""" + """Return a definition_list's term and optional classifiers.""" assert len(lines) == 1 text_nodes, messages = self.inline_text(lines[0], lineno) term_node = nodes.term() @@ -2666,17 +2668,17 @@ class Text(RSTState): for i in range(len(text_nodes)): node = text_nodes[i] if isinstance(node, nodes.Text): - parts = node.rawsource.split(' : ', 1) + parts = self.classifier_delimiter.split(node.rawsource) if len(parts) == 1: - term_node += node + node_list[-1] += 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 + + node_list[-1] += nodes.Text(parts[0].rstrip()) + for part in parts[1:]: + classifier_node = nodes.classifier('', part) + node_list.append(classifier_node) else: - term_node += node + node_list[-1] += node return node_list, messages -- cgit v1.2.1 From ab11a3e961d6ddf8c4a975ce84de2b551ca9ee6f Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 5 Nov 2004 18:09:27 +0000 Subject: fixed label-printing function; behavior was incorrect on use-latex-footnotes/-citations. Hmm. We need more tests. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2807 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index d3bce4128..91a759ad6 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1418,15 +1418,17 @@ class LaTeXTranslator(nodes.NodeVisitor): # footnote/citation label def label_delim(self, node, bracket, superscript): - if isinstance(node.parent, nodes.footnote) and \ - not self.use_latex_footnotes: + if isinstance(node.parent, nodes.footnote): + if self.use_latex_footnotes: + raise nodes.SkipNode if self.settings.footnote_references == 'brackets': self.body.append(bracket) else: self.body.append(superscript) - elif isinstance(node.parent, nodes.citation) and \ - not self._use_latex_citations: - self.body.append(bracket) + else: + assert isinstance(node.parent, nodes.citation) + if not self._use_latex_citations: + self.body.append(bracket) def visit_label(self, node): self.label_delim(node, '[', '$^{') -- cgit v1.2.1 From ca40d84eba8e1ccfa232ea08c5d38d108d7238d9 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 6 Nov 2004 17:13:39 +0000 Subject: Allow multiple class names in the "class" directive. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2808 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 49f3fb498..ee718063c 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -225,21 +225,21 @@ def class_directive(name, arguments, options, content, lineno, Set a "class" attribute on the next element. A "pending" element is inserted, and a transform does the work later. """ - class_value = nodes.make_id(arguments[0]) - if class_value: - pending = nodes.pending(misc.ClassAttribute, - {'class': class_value, 'directive': name}, - block_text) - state_machine.document.note_pending(pending) - return [pending] - else: + try: + class_value = directives.class_option(arguments[0]) + 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] + pending = nodes.pending(misc.ClassAttribute, + {'class': class_value, 'directive': name}, + block_text) + state_machine.document.note_pending(pending) + return [pending] -class_directive.arguments = (1, 0, 0) +class_directive.arguments = (1, 0, 1) class_directive.content = 1 role_arg_pat = re.compile(r'(%s)\s*(\(\s*(%s)\s*\)\s*)?$' -- cgit v1.2.1 From b79ad0ee0ada6563707ed122aaea57c5e6a645d0 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 6 Nov 2004 17:13:58 +0000 Subject: Allow multiple class names in class_option conversion function git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2810 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 828a830de..7ef052053 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -272,7 +272,6 @@ def nonnegative_int(argument): raise ValueError('negative value; must be positive or zero') return value - def class_option(argument): """ Convert the argument into an ID-compatible string and return it. @@ -282,10 +281,14 @@ def class_option(argument): """ if argument is None: raise ValueError('argument required but none supplied') - class_name = nodes.make_id(argument) - if not class_name: - raise ValueError('cannot make "%s" into a class name' % argument) - return class_name + names = argument.split() + class_names = [] + for name in names: + class_name = nodes.make_id(name) + if not class_name: + raise ValueError('cannot make "%s" into a class name' % name) + class_names.append(class_name) + return ' '.join(class_names) unicode_pattern = re.compile( r'(?:0x|x|\\x|U\+?|\\u)([0-9a-f]+)$|&#x([0-9a-f]+);$', re.IGNORECASE) @@ -311,7 +314,6 @@ def unicode_code(code): except OverflowError, detail: raise ValueError('code too large (%s)' % detail) - def single_char_or_unicode(argument): char = unicode_code(argument) if len(char) > 1: -- cgit v1.2.1 From fe4b3dcec9139c2c9736b46e2b2c4e60a05867f4 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 6 Nov 2004 17:51:06 +0000 Subject: use \glqq and \grqq for German quotation marks to allow easy customization in stylesheet with \renewcommand{\glqq}... git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2812 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 91a759ad6..ece1fcad8 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -232,8 +232,8 @@ class Babel: # pdflatex does not produce double quotes for ngerman in tt. self.double_quote_replacment = None if re.search('^de',self.language): - # maybe use: {\glqq} {\grqq}. - self.quotes = ("\"`", "\"'") + #self.quotes = ("\"`", "\"'") + self.quotes = ('{\\glqq}', '{\\grqq}') self.double_quote_replacment = "{\\dq}" else: self.quotes = ("``", "''") -- cgit v1.2.1 From d74ca66c1c0d32c7447bfcd10c3c02ad9ea40123 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 6 Nov 2004 19:51:39 +0000 Subject: Added "raw" role git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2814 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/af.py | 3 +- docutils/parsers/rst/languages/cs.py | 59 +++++++++++++++++---------------- docutils/parsers/rst/languages/de.py | 3 +- docutils/parsers/rst/languages/en.py | 3 +- docutils/parsers/rst/languages/eo.py | 3 +- docutils/parsers/rst/languages/es.py | 4 +-- docutils/parsers/rst/languages/fi.py | 3 +- docutils/parsers/rst/languages/fr.py | 3 +- docutils/parsers/rst/languages/it.py | 3 +- docutils/parsers/rst/languages/pt_br.py | 5 +-- docutils/parsers/rst/languages/ru.py | 3 +- docutils/parsers/rst/languages/sk.py | 3 +- docutils/parsers/rst/languages/sv.py | 3 +- docutils/parsers/rst/languages/zh_tw.py | 3 +- 14 files changed, 57 insertions(+), 44 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/af.py b/docutils/parsers/rst/languages/af.py index fda16ccba..9c3b05633 100644 --- a/docutils/parsers/rst/languages/af.py +++ b/docutils/parsers/rst/languages/af.py @@ -91,6 +91,7 @@ roles = { 'teiken': 'target', 'uri-verwysing': 'uri-reference', 'uri': 'uri-reference', - 'url': 'uri-reference',} + 'url': 'uri-reference', + 'raw (translation required)': 'raw',} """Mapping of Afrikaans role names to canonical role names for interpreted text. """ diff --git a/docutils/parsers/rst/languages/cs.py b/docutils/parsers/rst/languages/cs.py index 1dbd0ca2b..61ab1a79a 100644 --- a/docutils/parsers/rst/languages/cs.py +++ b/docutils/parsers/rst/languages/cs.py @@ -65,34 +65,35 @@ mapping.""" roles = { # language-dependent: fixed - u'abbreviation': 'abbreviation', - u'ab': 'abbreviation', - u'acronym': 'acronym', - u'ac': 'acronym', - u'index': 'index', - u'i': 'index', - u'subscript': 'subscript', - u'sub': 'subscript', - u'superscript': 'superscript', - u'sup': 'superscript', - u'title-reference': 'title-reference', - u'title': 'title-reference', - u't': 'title-reference', - u'pep-reference': 'pep-reference', - u'pep': 'pep-reference', - u'rfc-reference': 'rfc-reference', - u'rfc': 'rfc-reference', - u'emphasis': 'emphasis', - u'strong': 'strong', - u'literal': 'literal', - u'named-reference': 'named-reference', - u'anonymous-reference': 'anonymous-reference', - u'footnote-reference': 'footnote-reference', - u'citation-reference': 'citation-reference', - u'substitution-reference': 'substitution-reference', - u'target': 'target', - u'uri-reference': 'uri-reference', - u'uri': 'uri-reference', - u'url': 'uri-reference',} + u'abbreviation (translation required)': 'abbreviation', + u'ab (translation required)': 'abbreviation', + u'acronym (translation required)': 'acronym', + u'ac (translation required)': 'acronym', + u'index (translation required)': 'index', + u'i (translation required)': 'index', + u'subscript (translation required)': 'subscript', + u'sub (translation required)': 'subscript', + u'superscript (translation required)': 'superscript', + u'sup (translation required)': 'superscript', + u'title-reference (translation required)': 'title-reference', + u'title (translation required)': 'title-reference', + u't (translation required)': 'title-reference', + u'pep-reference (translation required)': 'pep-reference', + u'pep (translation required)': 'pep-reference', + u'rfc-reference (translation required)': 'rfc-reference', + u'rfc (translation required)': 'rfc-reference', + u'emphasis (translation required)': 'emphasis', + u'strong (translation required)': 'strong', + u'literal (translation required)': 'literal', + u'named-reference (translation required)': 'named-reference', + u'anonymous-reference (translation required)': 'anonymous-reference', + u'footnote-reference (translation required)': 'footnote-reference', + u'citation-reference (translation required)': 'citation-reference', + u'substitution-reference (translation required)': 'substitution-reference', + u'target (translation required)': 'target', + u'uri-reference (translation required)': 'uri-reference', + u'uri (translation required)': 'uri-reference', + u'url (translation required)': 'uri-reference', + u'raw (translation required)': 'raw',} """Mapping of Czech role names to canonical role names for interpreted text. """ diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index 5d7e6a006..a8c215b3a 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -82,6 +82,7 @@ roles = { 'zitat-referenz': 'citation-reference', 'ersetzungs-referenz': 'substitution-reference', 'ziel': 'target', - 'uri-referenz': 'uri-reference',} + 'uri-referenz': 'uri-reference', + 'raw (translation required)': 'raw',} """Mapping of German role names to canonical role names for interpreted text. """ diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index cd69becad..5f83cd764 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -93,6 +93,7 @@ roles = { 'target': 'target', 'uri-reference': 'uri-reference', 'uri': 'uri-reference', - 'url': 'uri-reference',} + 'url': 'uri-reference', + 'raw': 'raw',} """Mapping of English role names to canonical role names for interpreted text. """ diff --git a/docutils/parsers/rst/languages/eo.py b/docutils/parsers/rst/languages/eo.py index 3e3c77c41..14a01d5f6 100644 --- a/docutils/parsers/rst/languages/eo.py +++ b/docutils/parsers/rst/languages/eo.py @@ -101,6 +101,7 @@ roles = { u'celo': 'target', u'uri-referenco': 'uri-reference', u'uri': 'uri-reference', - u'url': 'uri-reference',} + u'url': 'uri-reference', + u'raw (translation required)': 'raw',} """Mapping of Esperanto role names to canonical role names for interpreted text. """ diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index 363e13516..35fe17044 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -94,7 +94,7 @@ roles = { u'enfasis': 'emphasis', u'\u00e9nfasis': 'emphasis', u'destacado': 'strong', - u'literal': 'literal', + u'literal': 'literal', # translation required? u'referencia-con-nombre': 'named-reference', u'referencia-anonima': 'anonymous-reference', u'referencia-an\u00f3nima': 'anonymous-reference', @@ -106,6 +106,6 @@ roles = { u'referencia-uri': 'uri-reference', u'uri': 'uri-reference', u'url': 'uri-reference', - } + u'raw (translation required)': 'raw',} """Mapping of Spanish role names to canonical role names for interpreted text. """ diff --git a/docutils/parsers/rst/languages/fi.py b/docutils/parsers/rst/languages/fi.py index 72530600c..c03618fc3 100644 --- a/docutils/parsers/rst/languages/fi.py +++ b/docutils/parsers/rst/languages/fi.py @@ -82,6 +82,7 @@ roles = { u'citation-reference (translation required)': u'citation-reference', u'substitution-reference (translation required)': u'substitution-reference', u'kohde': u'target', - u'uri-reference (translation required)': u'uri-reference'} + u'uri-reference (translation required)': u'uri-reference', + u'raw (translation required)': 'raw',} """Mapping of Finnish role names to canonical role names for interpreted text. """ diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index 9518fb3d2..c43781179 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -88,6 +88,7 @@ roles = { u'citation-r\u00E9f\u00E9rence': 'citation-reference', u'substitution-r\u00E9f\u00E9rence': 'substitution-reference', u'lien': 'target', - u'uri-r\u00E9f\u00E9rence': 'uri-reference',} + u'uri-r\u00E9f\u00E9rence': 'uri-reference', + u'raw (translation required)': 'raw',} """Mapping of French role names to canonical role names for interpreted text. """ diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index e4aa04261..87a615e07 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -80,6 +80,7 @@ roles = { 'riferimento-citazione': 'citation-reference', 'riferimento-sostituzione': 'substitution-reference', 'destinazione': 'target', - 'riferimento-uri': 'uri-reference',} + 'riferimento-uri': 'uri-reference', + 'raw (translation required)': 'raw',} """Mapping of Italian role names to canonical role names for interpreted text. """ diff --git a/docutils/parsers/rst/languages/pt_br.py b/docutils/parsers/rst/languages/pt_br.py index 66aa143c3..ba60beb8e 100644 --- a/docutils/parsers/rst/languages/pt_br.py +++ b/docutils/parsers/rst/languages/pt_br.py @@ -84,7 +84,7 @@ roles = { 'rfc': 'rfc-reference', u'\u00EAnfase': 'emphasis', 'forte': 'strong', - 'literal': 'literal', + 'literal': 'literal', # translation required? u'refer\u00EAncia-por-nome': 'named-reference', u'refer\u00EAncia-an\u00F4nima': 'anonymous-reference', u'refer\u00EAncia-a-nota-de-rodap\u00E9': 'footnote-reference', @@ -93,6 +93,7 @@ roles = { 'alvo': 'target', u'refer\u00EAncia-a-uri': 'uri-reference', 'uri': 'uri-reference', - 'url': 'uri-reference',} + 'url': 'uri-reference', + 'raw (translation required)': 'raw',} """Mapping of Brazilian Portuguese role names to canonical role names for interpreted text.""" diff --git a/docutils/parsers/rst/languages/ru.py b/docutils/parsers/rst/languages/ru.py index 87deeebad..361565f62 100644 --- a/docutils/parsers/rst/languages/ru.py +++ b/docutils/parsers/rst/languages/ru.py @@ -92,6 +92,7 @@ roles = { 'footnote-reference', u'\u0446\u0438\u0442\u0430\u0442\u043d\u0430\u044f-\u0441\u0441\u044b\u043b\u043a\u0430': 'citation-reference', - u'\u0446\u0435\u043b\u044c': 'target'} + u'\u0446\u0435\u043b\u044c': 'target', + u'raw (translation required)': 'raw',} """Mapping of Russian role names to canonical role names for interpreted text. """ diff --git a/docutils/parsers/rst/languages/sk.py b/docutils/parsers/rst/languages/sk.py index 2d637d984..17d6b42d2 100644 --- a/docutils/parsers/rst/languages/sk.py +++ b/docutils/parsers/rst/languages/sk.py @@ -80,6 +80,7 @@ roles = { u'citation-reference (translation required)': 'citation-reference', u'substitution-reference (translation required)': 'substitution-reference', u'target (translation required)': 'target', - u'uri-reference (translation required)': 'uri-reference',} + u'uri-reference (translation required)': 'uri-reference', + u'raw (translation required)': 'raw',} """Mapping of Slovak role names to canonical role names for interpreted text. """ diff --git a/docutils/parsers/rst/languages/sv.py b/docutils/parsers/rst/languages/sv.py index e014bc612..404cac45a 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -79,6 +79,7 @@ roles = { u'citation-reference (translation required)': 'citation-reference', u'substitution-reference (translation required)': 'substitution-reference', u'target (translation required)': 'target', - u'uri-reference (translation required)': 'uri-reference',} + u'uri-reference (translation required)': 'uri-reference', + u'raw (translation required)': 'raw',} """Mapping of Swedish role names to canonical role names for interpreted text. """ diff --git a/docutils/parsers/rst/languages/zh_tw.py b/docutils/parsers/rst/languages/zh_tw.py index acddae237..b10a0a45a 100644 --- a/docutils/parsers/rst/languages/zh_tw.py +++ b/docutils/parsers/rst/languages/zh_tw.py @@ -93,6 +93,7 @@ roles = { 'target (translation required)': 'target', 'uri-reference (translation required)': 'uri-reference', 'uri (translation required)': 'uri-reference', - 'url (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 f12819e3506c1c414747b811d21ebfaaedd8893f Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 6 Nov 2004 19:51:58 +0000 Subject: moved ``escape2null`` and ``unescape`` functions from docutils/parsers/rst/states.py git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2815 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'docutils') diff --git a/docutils/utils.py b/docutils/utils.py index ed0a36543..ccc6a4f20 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -489,6 +489,31 @@ def get_source_line(node): node = node.parent return None, None +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, restore_backslashes=0): + """ + Return a string with nulls removed or restored to backslashes. + Backslash-escaped spaces are also removed. + """ + if restore_backslashes: + return text.replace('\x00', '\\') + else: + for sep in ['\x00 ', '\x00\n', '\x00']: + text = ''.join(text.split(sep)) + return text + class DependencyList: -- cgit v1.2.1 From a2458fbff98892912f8b2c1b0fb39ebe5cbcb646 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 6 Nov 2004 19:52:19 +0000 Subject: Changed role function API: the "text" parameter now takes null-escaped interpreted text content. Moved ``escape2null`` and ``unescape`` functions from to docutils/utils.py. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2816 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 32 +++----------------------------- 1 file changed, 3 insertions(+), 29 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 874110a30..7de9165a8 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -114,6 +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.parsers.rst import directives, languages, tableparser, roles from docutils.parsers.rst.languages import en as _fallback_language_module @@ -758,7 +759,6 @@ class Inliner: role = endmatch.group('suffix')[1:-1] position = 'suffix' escaped = endmatch.string[:endmatch.start(1)] - text = unescape(escaped, 0) rawsource = unescape(string[matchstart:textend], 1) if rawsource[-1:] == '_': if role: @@ -769,10 +769,10 @@ class Inliner: prb = self.problematic(text, text, msg) return string[:rolestart], [prb], string[textend:], [msg] return self.phrase_ref(string[:matchstart], string[textend:], - rawsource, escaped, text) + rawsource, escaped, unescape(escaped)) else: rawsource = unescape(string[rolestart:textend], 1) - nodelist, messages = self.interpreted(rawsource, text, role, + nodelist, messages = self.interpreted(rawsource, escaped, role, lineno) return (string[:rolestart], nodelist, string[textend:], messages) @@ -2917,29 +2917,3 @@ state_classes = (Body, BulletList, DefinitionList, EnumeratedList, FieldList, OptionList, LineBlock, ExtensionOptions, Explicit, Text, Definition, Line, SubstitutionDef, RFC2822Body, RFC2822List) """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, restore_backslashes=0): - """ - Return a string with nulls removed or restored to backslashes. - Backslash-escaped spaces are also removed. - """ - if restore_backslashes: - return text.replace('\x00', '\\') - else: - for sep in ['\x00 ', '\x00\n', '\x00']: - text = ''.join(text.split(sep)) - return text -- cgit v1.2.1 From 0a76dd265b7bdb27e65747a10a07d1a00259f857 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 6 Nov 2004 19:52:26 +0000 Subject: Added "raw" role. Changed role function API: the "text" parameter now takes null-escaped interpreted text content. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2817 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/roles.py | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/roles.py b/docutils/parsers/rst/roles.py index aff19f30c..2f3ab11a5 100644 --- a/docutils/parsers/rst/roles.py +++ b/docutils/parsers/rst/roles.py @@ -28,7 +28,8 @@ Parameters: Return it as a ``problematic`` node linked to a system message if there is a problem. -- ``text`` is the interpreted text content. +- ``text`` is the interpreted text content, with backslash escapes converted + to nulls (``\x00``). - ``lineno`` is the line number where the interpreted text beings. @@ -73,7 +74,7 @@ Interpreted role functions return a tuple of two values: __docformat__ = 'reStructuredText' -from docutils import nodes +from docutils import nodes, utils from docutils.parsers.rst import directives from docutils.parsers.rst.languages import en as _fallback_language_module @@ -194,7 +195,7 @@ class GenericRole: def __call__(self, role, rawtext, text, lineno, inliner, options={}, content=[]): - return [self.node_class(rawtext, text, **options)], [] + return [self.node_class(rawtext, utils.unescape(text), **options)], [] class CustomRole: @@ -232,7 +233,7 @@ def generic_custom_role(role, rawtext, text, lineno, inliner, """""" # Once nested inline markup is implemented, this and other methods should # recursively call inliner.nested_parse(). - return [nodes.inline(rawtext, text, **options)], [] + return [nodes.inline(rawtext, utils.unescape(text), **options)], [] generic_custom_role.options = {'class': directives.class_option} @@ -264,7 +265,8 @@ def pep_reference_role(role, rawtext, text, lineno, inliner, return [prb], [msg] # Base URL mainly used by inliner.pep_reference; so this is correct: ref = inliner.document.settings.pep_base_url + inliner.pep_url % pepnum - return [nodes.reference(rawtext, 'PEP ' + text, refuri=ref, **options)], [] + return [nodes.reference(rawtext, 'PEP ' + utils.unescape(text), refuri=ref, + **options)], [] register_canonical_role('pep-reference', pep_reference_role) @@ -282,11 +284,28 @@ def rfc_reference_role(role, rawtext, text, lineno, inliner, return [prb], [msg] # Base URL mainly used by inliner.rfc_reference, so this is correct: ref = inliner.document.settings.rfc_base_url + inliner.rfc_url % rfcnum - node = nodes.reference(rawtext, 'RFC ' + text, refuri=ref, **options) + node = nodes.reference(rawtext, 'RFC ' + utils.unescape(text), refuri=ref, + **options) return [node], [] register_canonical_role('rfc-reference', rfc_reference_role) +def raw_role(role, rawtext, text, lineno, inliner, options={}, content=[]): + if not options.has_key('format'): + msg = inliner.reporter.error( + 'No format (Writer name) is associated with this role: "%s".\n' + 'The "raw" role cannot be used directly.\n' + 'Instead, use the "role" directive to create a new role with ' + 'an associated format.' % role, line=lineno) + prb = inliner.problematic(rawtext, rawtext, msg) + return [prb], [msg] + node = nodes.raw(rawtext, utils.unescape(text, 1), **options) + return [node], [] + +raw_role.options = {'format': directives.class_option} + +register_canonical_role('raw', raw_role) + ###################################################################### # Register roles that are currently unimplemented. -- cgit v1.2.1 From a0bf43cf6055c71ebf22bf60e017ed72e0ce49ac Mon Sep 17 00:00:00 2001 From: richieadler Date: Sun, 7 Nov 2004 11:44:40 +0000 Subject: translation for the "raw" role git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2824 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/eo.py | 5 +++-- docutils/parsers/rst/languages/es.py | 9 ++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/eo.py b/docutils/parsers/rst/languages/eo.py index 14a01d5f6..0eada6bb5 100644 --- a/docutils/parsers/rst/languages/eo.py +++ b/docutils/parsers/rst/languages/eo.py @@ -53,7 +53,7 @@ directives = { u'bildo': 'image', u'figuro': 'figure', u'inkludi': 'include', - u'senformata': 'raw', + u'senanaliza': 'raw', u'anstatauxi': 'replace', u'anstata\u016di': 'replace', u'unicode': 'unicode', @@ -102,6 +102,7 @@ roles = { u'uri-referenco': 'uri-reference', u'uri': 'uri-reference', u'url': 'uri-reference', - u'raw (translation required)': 'raw',} + u'senanaliza': 'raw', +} """Mapping of Esperanto role names to canonical role names for interpreted text. """ diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index 35fe17044..e7a1cfd5c 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -55,7 +55,8 @@ directives = { u'imagen': 'image', u'figura': 'figure', u'incluir': 'include', - u'raw': 'raw', + u'sin-analisis': 'raw', + u'sin-an\u00e1lisis': 'raw', u'reemplazar': 'replace', u'unicode': 'unicode', u'clase': 'class', @@ -94,7 +95,7 @@ roles = { u'enfasis': 'emphasis', u'\u00e9nfasis': 'emphasis', u'destacado': 'strong', - u'literal': 'literal', # translation required? + u'literal': 'literal', # "literal" is also a word in Spanish :-) u'referencia-con-nombre': 'named-reference', u'referencia-anonima': 'anonymous-reference', u'referencia-an\u00f3nima': 'anonymous-reference', @@ -106,6 +107,8 @@ roles = { u'referencia-uri': 'uri-reference', u'uri': 'uri-reference', u'url': 'uri-reference', - u'raw (translation required)': 'raw',} + u'sin-analisis': 'raw', + u'sin-an\u00e1lisis': 'raw', +} """Mapping of Spanish role names to canonical role names for interpreted text. """ -- cgit v1.2.1 From 020a9519cd5b72b152ffe7a89d89b3040ee2451e Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 7 Nov 2004 19:31:00 +0000 Subject: removed newline at end of raw text, because sometimes (when there are two consecutive newlines) the newline creates a new paragraph in LaTeX; added test git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2825 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index ee718063c..6f50bfd31 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -82,7 +82,7 @@ def raw(name, arguments, options, content, lineno, 'have content.' % name, nodes.literal_block(block_text, block_text), line=lineno) return [error] - text = '\n'.join(content) + '\n' + text = '\n'.join(content) elif options.has_key('file'): if options.has_key('url'): error = state_machine.reporter.error( -- cgit v1.2.1 From 4f7958de234a5d9443ec3c423a85c1087eaba030 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 7 Nov 2004 20:06:11 +0000 Subject: added German translations for "raw" and "literal" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2826 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/de.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index a8c215b3a..31d012725 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -47,6 +47,7 @@ directives = { 'bild': 'image', 'abbildung': 'figure', u'unver\xe4ndert': 'raw', + u'roh': 'raw', u'einf\xfcgen': 'include', 'ersetzung': 'replace', 'ersetzen': 'replace', @@ -75,7 +76,7 @@ roles = { 'rfc-referenz': 'rfc-reference', 'betonung': 'emphasis', 'fett': 'strong', - 'literal (translation required)': 'literal', + u'w\xf6rtlich': 'literal', 'benannte-referenz': 'named-reference', 'unbenannte-referenz': 'anonymous-reference', u'fu\xdfnoten-referenz': 'footnote-reference', -- cgit v1.2.1 From 3cec404604dca055dd807bdb3ca65ff6b2f8b8d9 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 8 Nov 2004 14:51:49 +0000 Subject: added (translation required) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2827 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/cs.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/cs.py b/docutils/parsers/rst/languages/cs.py index 61ab1a79a..5d14b353e 100644 --- a/docutils/parsers/rst/languages/cs.py +++ b/docutils/parsers/rst/languages/cs.py @@ -20,45 +20,45 @@ __docformat__ = 'reStructuredText' directives = { # language-dependent: fixed u'pozor': 'attention', - u'caution': 'caution', # jak rozlisit caution a warning? + u'caution (translation required)': 'caution', # jak rozlisit caution a warning? u'nebezpe\u010D\u00ED': 'danger', u'chyba': 'error', u'rada': 'hint', u'd\u016Fle\u017Eit\u00E9': 'important', u'pozn\u00E1mka': 'note', - u'tip': 'tip', + u'tip (translation required)': 'tip', u'varov\u00E1n\u00ED': 'warning', - u'admonition': 'admonition', - u'sidebar': 'sidebar', + u'admonition (translation required)': 'admonition', + u'sidebar (translation required)': 'sidebar', u't\u00E9ma': 'topic', - u'line-block': 'line-block', - u'parsed-literal': 'parsed-literal', + u'line-block (translation required)': 'line-block', + u'parsed-literal (translation required)': 'parsed-literal', u'odd\u00EDl': 'rubric', u'moto': 'epigraph', - u'highlights': 'highlights', - u'pull-quote': 'pull-quote', + u'highlights (translation required)': 'highlights', + u'pull-quote (translation required)': 'pull-quote', u'compound (translation required)': 'compound', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', u'table (translation required)': 'table', u'csv-table (translation required)': 'csv-table', - u'meta': 'meta', + u'meta (translation required)': 'meta', #'imagemap': 'imagemap', - u'image': 'image', # obrazek - u'figure': 'figure', # a tady? - u'include': 'include', - u'raw': 'raw', - u'replace': 'replace', - u'unicode': 'unicode', + u'image (translation required)': 'image', # obrazek + u'figure (translation required)': 'figure', # a tady? + u'include (translation required)': 'include', + u'raw (translation required)': 'raw', + u'replace (translation required)': 'replace', + u'unicode (translation required)': 'unicode', u't\u0159\u00EDda': 'class', u'role (translation required)': 'role', u'obsah': 'contents', - u'sectnum': 'sectnum', - u'section-numbering': 'sectnum', + u'sectnum (translation required)': 'sectnum', + u'section-numbering (translation required)': 'sectnum', #'footnotes': 'footnotes', #'citations': 'citations', - u'target-notes': 'target-notes', + u'target-notes (translation required)': 'target-notes', u'restructuredtext-test-directive': 'restructuredtext-test-directive'} """Czech name to registered (in directives/__init__.py) directive name mapping.""" -- cgit v1.2.1 From f791c2296a457a1df4e0cadb5104cbe9a74817e5 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 8 Nov 2004 14:58:04 +0000 Subject: added (translation required) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2828 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/sk.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/sk.py b/docutils/parsers/rst/languages/sk.py index 17d6b42d2..13c72a1fd 100644 --- a/docutils/parsers/rst/languages/sk.py +++ b/docutils/parsers/rst/languages/sk.py @@ -25,7 +25,7 @@ directives = { u'rada': 'hint', u'd\xf4le\x9eit\xe9': 'important', u'pozn\xe1mka': 'note', - u'tip': 'tip', + u'tip (translation required)': 'tip', u'varovanie': 'warning', u'admonition (translation required)': 'admonition', u'sidebar (translation required)': 'sidebar', @@ -47,7 +47,7 @@ directives = { u'obr\xe1zok': 'image', u'tvar': 'figure', u'vlo\x9ei\x9d': 'include', - u'raw': 'raw', + u'raw (translation required)': 'raw', u'nahradi\x9d': 'replace', u'unicode': 'unicode', u'class (translation required)': 'class', -- cgit v1.2.1 From 1a3d835d5e2c9a5186f4769745508bc0fa062863 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 8 Nov 2004 14:59:32 +0000 Subject: inserted translation of raw directive as translation for raw role git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2829 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/af.py | 2 +- docutils/parsers/rst/languages/de.py | 3 ++- docutils/parsers/rst/languages/fr.py | 2 +- docutils/parsers/rst/languages/it.py | 2 +- docutils/parsers/rst/languages/pt_br.py | 2 +- docutils/parsers/rst/languages/sv.py | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/af.py b/docutils/parsers/rst/languages/af.py index 9c3b05633..26a9449bc 100644 --- a/docutils/parsers/rst/languages/af.py +++ b/docutils/parsers/rst/languages/af.py @@ -92,6 +92,6 @@ roles = { 'uri-verwysing': 'uri-reference', 'uri': 'uri-reference', 'url': 'uri-reference', - 'raw (translation required)': 'raw',} + 'rou': 'raw',} """Mapping of Afrikaans role names to canonical role names for interpreted text. """ diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index 31d012725..66ca1cb95 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -84,6 +84,7 @@ roles = { 'ersetzungs-referenz': 'substitution-reference', 'ziel': 'target', 'uri-referenz': 'uri-reference', - 'raw (translation required)': 'raw',} + u'unver\xe4ndert': 'raw', + u'roh': 'raw',} """Mapping of German role names to canonical role names for interpreted text. """ diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index c43781179..126abbf1e 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -89,6 +89,6 @@ roles = { u'substitution-r\u00E9f\u00E9rence': 'substitution-reference', u'lien': 'target', u'uri-r\u00E9f\u00E9rence': 'uri-reference', - u'raw (translation required)': 'raw',} + u'brut': 'raw',} """Mapping of French role names to canonical role names for interpreted text. """ diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index 87a615e07..365853fa2 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -81,6 +81,6 @@ roles = { 'riferimento-sostituzione': 'substitution-reference', 'destinazione': 'target', 'riferimento-uri': 'uri-reference', - 'raw (translation required)': 'raw',} + 'grezzo': 'raw',} """Mapping of Italian role names to canonical role names for interpreted text. """ diff --git a/docutils/parsers/rst/languages/pt_br.py b/docutils/parsers/rst/languages/pt_br.py index ba60beb8e..48abd5689 100644 --- a/docutils/parsers/rst/languages/pt_br.py +++ b/docutils/parsers/rst/languages/pt_br.py @@ -94,6 +94,6 @@ roles = { u'refer\u00EAncia-a-uri': 'uri-reference', 'uri': 'uri-reference', 'url': 'uri-reference', - 'raw (translation required)': 'raw',} + 'cru': 'raw',} """Mapping of Brazilian Portuguese role names to canonical role names for interpreted text.""" diff --git a/docutils/parsers/rst/languages/sv.py b/docutils/parsers/rst/languages/sv.py index 404cac45a..ba4407860 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -80,6 +80,6 @@ roles = { u'substitution-reference (translation required)': 'substitution-reference', u'target (translation required)': 'target', u'uri-reference (translation required)': 'uri-reference', - u'raw (translation required)': 'raw',} + u'r\u00e5': 'raw',} """Mapping of Swedish role names to canonical role names for interpreted text. """ -- cgit v1.2.1 From 3c9295317e8dc78cdf2de4e5ca4cd4da7ea39469 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 8 Nov 2004 15:01:40 +0000 Subject: typo; wrapped long lines git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2830 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/zh_tw.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/zh_tw.py b/docutils/parsers/rst/languages/zh_tw.py index b10a0a45a..c0f1632ff 100644 --- a/docutils/parsers/rst/languages/zh_tw.py +++ b/docutils/parsers/rst/languages/zh_tw.py @@ -60,8 +60,8 @@ directives = { #'citations (translation required)': 'citations', 'target-notes (translation required)': 'target-notes', 'restructuredtext-test-directive': 'restructuredtext-test-directive'} -"""English name to registered (in directives/__init__.py) directive name -mapping.""" +"""Traditional Chinese name to registered (in directives/__init__.py) +directive name mapping.""" roles = { # language-dependent: fixed @@ -95,5 +95,5 @@ 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 Traditional Chinese role names to canonical role names for +interpreted text.""" -- cgit v1.2.1 From 394204b9c7ea8b9c141a614f01c11d9839f6f8c5 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 8 Nov 2004 15:30:11 +0000 Subject: do not strip

    from a paragraph which is the only child of a document git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2831 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index e03e042ce..8ee66e1a0 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -983,7 +983,8 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_paragraph(self, node): # Omit

    tags if this is an only child and optimizable. - if (not isinstance(node.parent, nodes.compound) and + if (not isinstance(node.parent, nodes.document) and + not isinstance(node.parent, nodes.compound) and (node.attributes in ({}, {'class': 'first'}, {'class': 'last'}, {'class': 'first last'})) and (self.compact_simple or -- cgit v1.2.1 From 8f54002465522b7e6b10dfce83e16e4946fd4c6d Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 8 Nov 2004 16:33:26 +0000 Subject: moved paragraph-compacting logic to a separate method (thanks to Jason Diamond) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2832 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 8ee66e1a0..4375b889c 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -981,16 +981,25 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_organization(self, node): self.depart_docinfo_item() - def visit_paragraph(self, node): - # Omit

    tags if this is an only child and optimizable. - if (not isinstance(node.parent, nodes.document) and - not isinstance(node.parent, nodes.compound) and - (node.attributes in ({}, {'class': 'first'}, {'class': 'last'}, + 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 + if ((node.attributes in ({}, {'class': 'first'}, {'class': 'last'}, {'class': 'first last'})) and (self.compact_simple 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', '')) -- cgit v1.2.1 From 6108a767c19a1d7af03564d04c9449e618422bd1 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 8 Nov 2004 18:11:54 +0000 Subject: really disregard invisible nodes when checking for compactable lists git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2834 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 4375b889c..f57b775d4 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -1360,7 +1360,7 @@ class SimpleListChecker(nodes.GenericNodeVisitor): def invisible_visit(self, node): """Invisible nodes should be ignored.""" - pass + raise nodes.SkipNode visit_comment = invisible_visit visit_substitution_definition = invisible_visit -- cgit v1.2.1 From 99922cfb551859172d40a63f4d643a97cf38c2ef Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 9 Nov 2004 11:17:36 +0000 Subject: removed unused node class ``info`` git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2835 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 7a498e425..f0fd4abe3 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -948,7 +948,6 @@ class rubric(Titular, TextElement): pass # ======================== class docinfo(Bibliographic, Element): pass -class info(Bibliographic, Element): pass class author(Bibliographic, TextElement): pass class authors(Bibliographic, Element): pass class organization(Bibliographic, TextElement): pass @@ -1240,7 +1239,7 @@ node_class_names = """ footnote footnote_reference generated header hint - image important info inline + image important inline label legend line line_block list_item literal literal_block note option option_argument option_group option_list option_list_item -- cgit v1.2.1 From be8b55e1398a9905f07a8889890189bae1f7f007 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 9 Nov 2004 16:51:33 +0000 Subject: add tags for inline-level raw nodes in HTML to get the class of the raw node git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2836 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index f57b775d4..14da6ac8f 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -1023,7 +1023,17 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_raw(self, node): if 'html' in node.get('format', '').split(): + add_span = node.attributes.get('class') is not None + if add_span: + #if not isinstance(node.parent, nodes.TextElement): + # # I'd like to insert a system_message or + # # something like that, because block-level raw + # # elements may not have the class attribute set. + # # What shall we do in this case? + self.body.append(self.starttag(node, 'span', suffix='')) self.body.append(node.astext()) + if add_span: + self.body.append('') # Keep non-HTML raw text out of output: raise nodes.SkipNode -- cgit v1.2.1 From 3c7ecaccc7eff4e62e09e40756750126a18c358f Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 9 Nov 2004 17:13:02 +0000 Subject: removed error-handling comment for block-level raw nodes with class attribute; this case should be handled by the parser git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2837 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 5 ----- 1 file changed, 5 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 14da6ac8f..339610adb 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -1025,11 +1025,6 @@ class HTMLTranslator(nodes.NodeVisitor): if 'html' in node.get('format', '').split(): add_span = node.attributes.get('class') is not None if add_span: - #if not isinstance(node.parent, nodes.TextElement): - # # I'd like to insert a system_message or - # # something like that, because block-level raw - # # elements may not have the class attribute set. - # # What shall we do in this case? self.body.append(self.starttag(node, 'span', suffix='')) self.body.append(node.astext()) if add_span: -- cgit v1.2.1 From a01ce11ee2940f9ffb69a29fcd11deddb258203b Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 10 Nov 2004 04:17:57 +0000 Subject: corrected doc git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2840 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 339610adb..538fd7067 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -1331,7 +1331,7 @@ class HTMLTranslator(nodes.NodeVisitor): class SimpleListChecker(nodes.GenericNodeVisitor): """ - Raise `nodes.SkipNode` if non-simple list item is encountered. + 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. -- cgit v1.2.1 From b76c0637256c7c823dba009e145bffe7ca444783 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 13 Nov 2004 19:37:09 +0000 Subject: added class="docutils" to elements which need stylesheet tweaking and do not have their own class git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2849 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 538fd7067..a036c005c 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -412,7 +412,8 @@ class HTMLTranslator(nodes.NodeVisitor): self.depart_admonition() def visit_citation(self, node): - self.body.append(self.starttag(node, 'table', CLASS='citation', + self.body.append(self.starttag(node, 'table', + CLASS='docutils citation', frame="void", rules="none")) self.body.append('\n' '\n' @@ -516,7 +517,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('\n') def visit_definition_list(self, node): - self.body.append(self.starttag(node, 'dl')) + self.body.append(self.starttag(node, 'dl', CLASS='docutils')) def depart_definition_list(self, node): self.body.append('\n') @@ -536,7 +537,8 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_docinfo(self, node): self.context.append(len(self.body)) - self.body.append(self.starttag(node, 'table', CLASS='docinfo', + self.body.append(self.starttag(node, 'table', + CLASS='docinfo', frame="void", rules="none")) self.body.append('\n' '\n' @@ -658,7 +660,8 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_field_list(self, node): self.body.append(self.starttag(node, 'table', frame='void', - rules='none', CLASS='field-list')) + rules='none', + CLASS='docutils field-list')) self.body.append('\n' '\n' '\n') @@ -697,7 +700,7 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_footer(self, node): start = self.context.pop() - footer = (['

    \n', + footer = (['\n', self.starttag(node, 'div', CLASS='footer')] + self.body[start:] + ['\n']) self.footer.extend(footer) @@ -705,7 +708,8 @@ class HTMLTranslator(nodes.NodeVisitor): del self.body[start:] def visit_footnote(self, node): - self.body.append(self.starttag(node, 'table', CLASS='footnote', + self.body.append(self.starttag(node, 'table', + CLASS='docutils footnote', frame="void", rules="none")) self.body.append('\n' '\n' @@ -882,7 +886,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_literal(self, node): """Process text to prevent tokens from wrapping.""" - self.body.append(self.starttag(node, 'tt', '', CLASS='literal')) + 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(): @@ -954,7 +958,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_option_list(self, node): self.body.append( - self.starttag(node, 'table', CLASS='option-list', + self.starttag(node, 'table', CLASS='docutils option-list', frame="void", rules="none")) self.body.append('\n' '\n' @@ -1167,7 +1171,8 @@ class HTMLTranslator(nodes.NodeVisitor): a_end = '' else: a_start = a_end = '' - self.body.append('System Message: %s%s/%s%s (%s%s)%s

    \n' + 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)) @@ -1176,7 +1181,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_table(self, node): self.body.append( - self.starttag(node, 'table', CLASS="table", border="1")) + self.starttag(node, 'table', CLASS='docutils', border="1")) def depart_table(self, node): self.body.append('\n') @@ -1306,7 +1311,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.topic_class = '' def visit_transition(self, node): - self.body.append(self.emptytag(node, 'hr')) + self.body.append(self.emptytag(node, 'hr', CLASS='docutils')) def depart_transition(self, node): pass -- cgit v1.2.1 From 5646e5b5a5f7d0e29de74c557a829194f3619d89 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 13 Nov 2004 20:28:58 +0000 Subject: added "last" attribute to last element in admonition in HTML to avoid vertical space git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2853 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index a036c005c..8931733f3 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -330,6 +330,9 @@ class HTMLTranslator(nodes.NodeVisitor): if name: self.body.append('

    ' + self.language.labels[name] + '

    \n') + node[-1].set_class('last') + else: + self.set_first_last(node) def depart_admonition(self, node=None): self.body.append('\n') -- cgit v1.2.1 From d0d253b0becd518e4a387a42785ae872a19692f8 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 13 Nov 2004 20:51:59 +0000 Subject: Re-fixed rendering of admonitions in HTML to unify generated HTML of pre-defined and user-defined admonitions. This fix also avoids paragraph-compacting like this::

    Attention!

    Directives at large.
    (Note that the second paragraph has no

    tags.) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2854 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 8931733f3..5a2ab266a 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -328,11 +328,8 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.starttag(node, 'div', CLASS=(name or 'admonition'))) if name: - self.body.append('

    ' - + self.language.labels[name] + '

    \n') - node[-1].set_class('last') - else: - self.set_first_last(node) + 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') @@ -1255,9 +1252,9 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append( self.starttag(node, 'p', '', CLASS='sidebar-title first')) check_id = 1 - elif isinstance(node.parent, nodes.admonition): + elif isinstance(node.parent, nodes.Admonition): self.body.append( - self.starttag(node, 'p', '', CLASS='admonition-title first')) + self.starttag(node, 'p', '', CLASS='admonition-title')) check_id = 1 elif isinstance(node.parent, nodes.table): self.body.append( -- cgit v1.2.1 From dc6229375da8ddf286ff8fbf58e6cd9069b3ce4f Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 13 Nov 2004 21:03:57 +0000 Subject: add classes "first" and "last" to sidebar children git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2856 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 5a2ab266a..b3a0ebd2e 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -1084,6 +1084,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_sidebar(self, node): self.body.append(self.starttag(node, 'div', CLASS='sidebar')) + self.set_first_last(node) self.in_sidebar = 1 def depart_sidebar(self, node): @@ -1250,7 +1251,7 @@ class HTMLTranslator(nodes.NodeVisitor): check_id = 1 elif isinstance(node.parent, nodes.sidebar): self.body.append( - self.starttag(node, 'p', '', CLASS='sidebar-title first')) + self.starttag(node, 'p', '', CLASS='sidebar-title')) check_id = 1 elif isinstance(node.parent, nodes.Admonition): self.body.append( -- cgit v1.2.1 From 9fd461d2a73f79f09ae3170e4fe2f587326247ae Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 15 Nov 2004 16:31:46 +0000 Subject: Added class="docutils header" to horizontal-rules of headers. It didn't cause a single test to fail. :-/ David, are you still going to reply to my last "Remove nodes.header?" posting? git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2861 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index b3a0ebd2e..7a0342b0f 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -783,7 +783,7 @@ class HTMLTranslator(nodes.NodeVisitor): start = self.context.pop() header = [self.starttag(node, 'div', CLASS='header')] header.extend(self.body[start:]) - header.append('
    \n\n') + header.append('
    \n\n') self.body_prefix.extend(header) self.header = header del self.body[start:] -- cgit v1.2.1 From dbd944e80a6f67bea3f3b0e332a3b0c34ee618f5 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 25 Nov 2004 11:26:34 +0000 Subject: removed no_random option; SF's Python doesn't seem to be broken anymore git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2868 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/pep_html.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index 54d269317..9305e6062 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -11,6 +11,7 @@ PEP HTML Writer. __docformat__ = 'reStructuredText' +import random import sys import docutils from docutils import frontend, nodes, utils @@ -31,12 +32,7 @@ class Writer(html4css1.Writer): {'default': '..', 'metavar': ''}), ('Home URL prefix for PEPs. Default is "." (current directory).', ['--pep-home'], - {'default': '.', 'metavar': ''}), - # Workaround for SourceForge's broken Python - # (``import random`` causes a segfault). - (frontend.SUPPRESS_HELP, - ['--no-random'], - {'action': 'store_true', 'validator': frontend.validate_boolean}),)) + {'default': '.', 'metavar': ''}),)) settings_default_overrides = {'footnote_references': 'brackets'} @@ -70,14 +66,10 @@ class Writer(html4css1.Writer): 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) + subs['banner'] = random.randrange(64) try: subs['pepnum'] = '%04i' % int(pepnum) - except: + except ValueError: subs['pepnum'] = pepnum subs['title'] = header[1][1].astext() subs['body'] = ''.join( -- cgit v1.2.1 From 905976014be91324d50fa8e7d3d7a5ad05bfca63 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 25 Nov 2004 18:31:48 +0000 Subject: disable automatic dash-transformation ("--" to en-dash) in LaTeX git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2869 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index ece1fcad8..002e6f492 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -825,19 +825,16 @@ class LaTeXTranslator(nodes.NodeVisitor): 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) - # Separate compound characters, e.g. ",,," to ",{},{},". - # This is usually only necessary when using T1 - # font-encoding, but in some languages (like russian) T1 - # is automatically activated, so we can't rely on - # font_encoding-guessing. Thus we separate the characters - # unconditionally, even if it is not necessary. Note that - # the separation must be done twice, because otherwise we - # would replace "---" by "-{}--". - for char in '"\',-<>`' * 2: - text = text.replace(char + char, char + '{}' + char) if self.font_encoding == 'OT1': # We're using OT1 font-encoding and have to replace # underscore by underlined blank, because this has @@ -851,6 +848,10 @@ class LaTeXTranslator(nodes.NodeVisitor): 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. -- cgit v1.2.1 From a33879a926ba9d3beffcc35e5f8c45cb62e85ce4 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 26 Nov 2004 09:27:55 +0000 Subject: allow empty sections and documents git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2870 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 7de9165a8..b6954fe99 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -170,16 +170,8 @@ class RSTStateMachine(StateMachineWS): 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 - 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): @@ -384,27 +376,11 @@ class RSTState(StateWS): self.state_machine.input_lines[offset:], input_offset=absoffset, 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) - def paragraph(self, lines, lineno): """ Return a list (paragraph & messages) & a boolean: literal_block next? -- cgit v1.2.1 From 4e8fcbda06d8f16989e0ae6df3708a56de4d0ae7 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 26 Nov 2004 16:49:56 +0000 Subject: do not surround block-level `raw`s with tags; use
    instead git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2873 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 7a0342b0f..a7b00d6f4 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -1027,12 +1027,13 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_raw(self, node): if 'html' in node.get('format', '').split(): - add_span = node.attributes.get('class') is not None - if add_span: - self.body.append(self.starttag(node, 'span', suffix='')) + add_class = node.attributes.get('class') is not None + t = isinstance(node.parent, nodes.TextElement) and 'span' or 'div' + if add_class: + self.body.append(self.starttag(node, t, suffix='')) self.body.append(node.astext()) - if add_span: - self.body.append('') + if add_class: + self.body.append('' % t) # Keep non-HTML raw text out of output: raise nodes.SkipNode -- cgit v1.2.1 From 36036fa24780fe111ff0ab42bf8e712e79fcda7e Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 30 Nov 2004 19:58:52 +0000 Subject: fixed ("added") encoding support for raw and include directive (closes #1076183) thanks Julio Monteiro git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2876 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 6f50bfd31..d615f5540 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -61,7 +61,8 @@ def include(name, arguments, options, content, lineno, return [] include.arguments = (1, 0, 1) -include.options = {'literal': directives.flag} +include.options = {'literal': directives.flag, + 'encoding': directives.encoding} def raw(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): @@ -139,7 +140,8 @@ def raw(name, arguments, options, content, lineno, raw.arguments = (1, 0, 1) raw.options = {'file': directives.path, - 'url': directives.path} + 'url': directives.path, + 'encoding': directives.encoding} raw.content = 1 def replace(name, arguments, options, content, lineno, -- cgit v1.2.1 From f6253be6f54c20dbb4a65fa7c03d27c510299ebb Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 23 Dec 2004 16:34:24 +0000 Subject: added text about using the unicode directive for en and em dashes git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2888 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index 94c7c7282..20dd8e51f 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -51,7 +51,7 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.3.6' +__version__ = '0.3.7' """``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 -- cgit v1.2.1 From 58f039b55de17ed6b25baa7902b7ea1dcbb7b598 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 23 Dec 2004 16:40:35 +0000 Subject: reverted accidentally committed files; sorry git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2889 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index 20dd8e51f..94c7c7282 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -51,7 +51,7 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.3.7' +__version__ = '0.3.6' """``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 -- cgit v1.2.1 From 8be082796a90dddfb1aec2c4c2a4fcbc2a90b274 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 23 Dec 2004 16:49:43 +0000 Subject: removed compound node from list of optional nodes git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2890 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index f0fd4abe3..c18b4bc29 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1284,8 +1284,10 @@ class NodeVisitor: 1995. """ - optional = ('compound',) + optional = () """ + Tuple containing node class names (as strings). + No exception will be raised if writers do not implement visit or departure functions for these node classes. -- cgit v1.2.1 From 16285d9ba32a086ce2f12c1af08b844cba7339ca Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 23 Dec 2004 23:04:11 +0000 Subject: Release 0.4.0: set version number to 0.4.0 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2894 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index 94c7c7282..8b3ac2609 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -51,7 +51,7 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.3.6' +__version__ = '0.4.0' """``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 -- cgit v1.2.1 From 825684c2919c06fd9bc2208aa135f5d79fa6e948 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 23 Dec 2004 23:29:16 +0000 Subject: applied David Goodger's patch from http://article.gmane.org/gmane.text.docutils.devel/2487 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2896 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index a7b00d6f4..49a1ee903 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -583,8 +583,8 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_document(self, node): self.fragment.extend(self.body) - self.body.insert(0, self.starttag(node, 'div', CLASS='document')) - self.body.append('
    \n') + self.body_prefix.append(self.starttag(node, 'div', CLASS='document')) + self.body_suffix.insert(0, '\n') def visit_emphasis(self, node): self.body.append('') @@ -826,14 +826,20 @@ class HTMLTranslator(nodes.NodeVisitor): if isinstance(node.parent, nodes.TextElement): self.context.append('') else: - if atts.has_key('align'): - self.body.append('

    ' % - (self.attval(atts['align'],))) - else: - self.body.append('

    ') - self.context.append('

    \n') + div_atts = self.image_div_atts(node) + self.body.append(self.starttag({}, 'div', '', **div_atts)) + self.context.append('\n') self.body.append(self.emptytag(node, 'img', '', **atts)) + def image_div_atts(self, image_node): + div_atts = {'class': 'image'} + if image_node.attributes.has_key('class'): + div_atts['class'] += ' ' + image_node.attributes['class'] + 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 + def depart_image(self, node): self.body.append(self.context.pop()) @@ -1040,9 +1046,12 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_reference(self, node): if isinstance(node.parent, nodes.TextElement): self.context.append('') - else: - self.body.append('

    ') - self.context.append('

    \n') + 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('\n') href = '' if node.has_key('refuri'): href = node['refuri'] -- cgit v1.2.1 From 740682332c3a17b86db19fa219a99e44e74e24af Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 23 Dec 2004 23:39:15 +0000 Subject: Release 0.3.7: set version number to 0.3.7 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2897 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index 8b3ac2609..20dd8e51f 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -51,7 +51,7 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.4.0' +__version__ = '0.3.7' """``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 -- cgit v1.2.1 From 74ef0ca97d6a845eb24a2fa0546612d34474d043 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 24 Dec 2004 00:55:16 +0000 Subject: Release 0.3.7: set version number to 0.3.8 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2901 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/__init__.py b/docutils/__init__.py index 20dd8e51f..662f0a097 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -51,7 +51,7 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.3.7' +__version__ = '0.3.8' """``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 -- cgit v1.2.1 From 72b76553d951db5e70365a7333f3a12cea8033e7 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 25 Dec 2004 15:34:06 +0000 Subject: made --verbose do what it's supposed to do git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2911 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index bf9b28303..01731c478 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -333,10 +333,10 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): 'validator': validate_threshold}), ('Report all system messages, info-level and higher. (Same as ' '"--report=info".)', - ['--verbose', '-v'], {'action': 'store_const', 'const': 'info', + ['--verbose', '-v'], {'action': 'store_const', 'const': 1, 'dest': 'report_level'}), ('Do not report any system messages. (Same as "--report=none".)', - ['--quiet', '-q'], {'action': 'store_const', 'const': 'none', + ['--quiet', '-q'], {'action': 'store_const', 'const': 5, 'dest': 'report_level'}), ('Set the threshold () at or above which system messages are ' 'converted to exceptions, halting execution immediately by ' -- cgit v1.2.1 From 4c1c5cb59e1b6029193f5e4d4f06756f84d41fc5 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 25 Dec 2004 17:46:46 +0000 Subject: fixed documentation of TextElement node class git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2912 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index c18b4bc29..4a93790d4 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -514,7 +514,7 @@ class TextElement(Element): """ An element which directly contains text. - Its children are all `Text` or `TextElement` subclass nodes. You can + Its children are all `Text` or `Inline` subclass nodes. You can check whether an element's context is inline simply by checking whether its immediate parent is a `TextElement` instance (including subclasses). This is handy for nodes like `image` that can appear both inline and as -- cgit v1.2.1 From 54c920682fdf9362278109dc807acaaef8ef8e1e Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 5 Jan 2005 16:17:25 +0000 Subject: made HTMLTranslator.named_keys a list git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2925 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 49a1ee903..526886764 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -171,8 +171,7 @@ class HTMLTranslator(nodes.NodeVisitor): 'http://docutils.sourceforge.net/" />\n') stylesheet_link = '\n' embedded_stylesheet = '\n' - named_tags = {'a': 1, 'applet': 1, 'form': 1, 'frame': 1, 'iframe': 1, - 'img': 1, 'map': 1} + named_tags = ['a', 'applet', 'form', 'frame', 'iframe', 'img', 'map'] words_and_spaces = re.compile(r'\S+| +|\n') def __init__(self, document): @@ -266,7 +265,7 @@ 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') and self.named_tags.has_key(tagname): + 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() -- cgit v1.2.1 From 649a9fb4b37653a3085768358f7ab527a4ad7254 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 13 Jan 2005 14:29:12 +0000 Subject: added some more documentation for name and id attributes git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2934 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 4a93790d4..5926ae456 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -225,6 +225,12 @@ class Element(Node): element['att'] = 'value' + There are two special attributes: 'id' and 'name'. Both are + unique, and names serve as human interfaces to IDs. Names are + case- and whitespace-normalized (see the fully_normalize_name() + function), and IDs conform to the regular expression + ``[a-z](-?[a-z0-9]+)*`` (see the make_id() function). + Elements also emulate lists for child nodes (element nodes and/or text nodes), indexing by integer. To get the first child node, use:: -- cgit v1.2.1 From ae854fe9e05524b51690889ae99e1565507ddfda Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 13 Jan 2005 20:09:18 +0000 Subject: made email addresses escapable git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2935 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index b6954fe99..ddb2e5100 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -533,7 +533,7 @@ class Inliner: emailc = r"""[-_!~*'{|}/#?^`&=+$%a-zA-Z0-9\x00]""" email_pattern = r""" %(emailc)s+(?:\.%(emailc)s+)* # name - @ # at + (? Date: Fri, 14 Jan 2005 14:34:05 +0000 Subject: Implemented support for multiple author,organization,address,contact fields with use_latex_docinfo. Still has a bug: the document must have a title for \maketitle to be emitted. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2937 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 48 ++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 20 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 002e6f492..e90f2d1c2 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -349,7 +349,7 @@ class DocumentClass: return self._deepest_section class Table: - """ Manage a table while traversing. + """ Manage a table while traversing. Maybe change to a mixin defining the visit/departs, but then class Table internal variables are in the Translator. """ @@ -381,7 +381,7 @@ class Table: return '' def get_latex_type(self): return self._latex_type - + def set(self,attr,value): self._attrs[attr] = value def get(self,attr): @@ -442,7 +442,7 @@ class Table: return latex_table_spec+bar def get_column_width(self): - """ return columnwidth for current cell (not multicell) + """ return columnwidth for current cell (not multicell) """ return "%.2f\\locallinewidth" % self._col_width[self._cell_in_row-1] @@ -471,7 +471,7 @@ class Table: 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)): @@ -507,7 +507,7 @@ class Table: def visit_entry(self): self._cell_in_row += 1 - + class LaTeXTranslator(nodes.NodeVisitor): # When options are given to the documentclass, latex will pass them @@ -677,8 +677,8 @@ class LaTeXTranslator(nodes.NodeVisitor): self.topic_class = '' # column specification for tables self.table_caption = None - # do we have one or more authors - self.author_stack = None + # if use_latex_docinfo: collects lists of author/organization/contact/address lines + self.author_stack = [] # Flags to encode # --------------- # verbatim: to tell encode not to encode. @@ -927,14 +927,10 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_authors(self, node): # not used: visit_author is called anyway for each author. - if self.use_latex_docinfo: - self.author_stack = [] + pass def depart_authors(self, node): - if self.use_latex_docinfo: - self.head.append('\\author{%s}\n' % \ - ' \\and '.join(self.author_stack) ) - self.author_stack = None + pass def visit_block_quote(self, node): self.body.append( '\\begin{quote}\n') @@ -1115,6 +1111,10 @@ class LaTeXTranslator(nodes.NodeVisitor): self.docinfo.append('\\begin{tabularx}{\\docinfowidth}{lX}\n') def depart_docinfo(self, node): + if self.use_latex_docinfo and self.author_stack: + self.head.append('\\author{%s}\n' % \ + ' \\and\n'.join(['~\\\\\n'.join(author_lines) + for author_lines in self.author_stack]) ) self.docinfo.append('\\end{tabularx}\n') self.docinfo.append('\\end{center}\n') self.body = self.docinfo + self.body @@ -1128,14 +1128,22 @@ class LaTeXTranslator(nodes.NodeVisitor): self.pdfauthor = self.attval(node.astext()) else: self.pdfauthor += self.author_separator + self.attval(node.astext()) - if self.use_latex_docinfo: - if self.author_stack == None: - self.head.append('\\author{%s}\n' % 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: - self.author_stack.append( self.attval(node.astext()) ) + text = self.attval(node.astext()) + self.author_stack[-1].append(text) raise nodes.SkipNode - elif name == 'date': - if self.use_latex_docinfo: + elif name == 'date': self.head.append('\\date{%s}\n' % self.attval(node.astext())) raise nodes.SkipNode self.docinfo.append('\\textbf{%s}: &\n\t' % self.language_label(name)) @@ -1186,7 +1194,7 @@ class LaTeXTranslator(nodes.NodeVisitor): for bi in self._bibitems: self.body.append('\\bibitem[%s]{%s}{%s}\n' % (bi[0], bi[0], bi[1])) self.body.append('\\end{thebibliography}\n') - + self.body_suffix.append('\\end{document}\n') def visit_emphasis(self, node): -- cgit v1.2.1 From 8e61bea12a1e10ea035b823bd823c24cc030e35b Mon Sep 17 00:00:00 2001 From: cben Date: Sat, 15 Jan 2005 22:03:25 +0000 Subject: Fixed use_latex_docinfo to always show the titlepage. Forced \date{} and \author{} to be emitted at all times, to avoid latex's default (the date latex processed the file, which is never interesting for us; perhaps using the date *docutils* processed the file would make sense if --date is given?). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2938 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index e90f2d1c2..1ce091add 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -664,12 +664,16 @@ class LaTeXTranslator(nodes.NodeVisitor): # 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 = [ ] - if not self.use_latex_docinfo: - self.head.extend( [ '\\author{}\n', '\\date{}\n' ] ) - self.body_prefix = ['\\raggedbottom\n'] # separate title, so we can appen subtitle. - self.title = "" + 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 @@ -677,8 +681,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.topic_class = '' # column specification for tables self.table_caption = None - # if use_latex_docinfo: collects lists of author/organization/contact/address lines - self.author_stack = [] + # Flags to encode # --------------- # verbatim: to tell encode not to encode. @@ -878,15 +881,19 @@ class LaTeXTranslator(nodes.NodeVisitor): return self.encode(whitespace.sub(' ', text)) def astext(self): - if self.pdfinfo: + 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 = '' - title = '\\title{%s}\n' % self.title - return ''.join(self.head_prefix + [title] - + self.head + [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): @@ -1111,10 +1118,6 @@ class LaTeXTranslator(nodes.NodeVisitor): self.docinfo.append('\\begin{tabularx}{\\docinfowidth}{lX}\n') def depart_docinfo(self, node): - if self.use_latex_docinfo and self.author_stack: - self.head.append('\\author{%s}\n' % \ - ' \\and\n'.join(['~\\\\\n'.join(author_lines) - for author_lines in self.author_stack]) ) self.docinfo.append('\\end{tabularx}\n') self.docinfo.append('\\end{center}\n') self.body = self.docinfo + self.body @@ -1144,7 +1147,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.author_stack[-1].append(text) raise nodes.SkipNode elif name == 'date': - self.head.append('\\date{%s}\n' % self.attval(node.astext())) + self.date = self.attval(node.astext()) raise nodes.SkipNode self.docinfo.append('\\textbf{%s}: &\n\t' % self.language_label(name)) if name == 'address': @@ -1177,7 +1180,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_document(self, node): self.body_prefix.append('\\begin{document}\n') # titled document? - if len(node) and isinstance(node[0], nodes.title): + 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} -- cgit v1.2.1 From 15dc96b8717ef0854ce8fd11ea1791811ef6dc5e Mon Sep 17 00:00:00 2001 From: lele Date: Thu, 20 Jan 2005 12:10:39 +0000 Subject: Translated newest directives git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2943 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/it.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index 365853fa2..127318d0a 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -4,10 +4,10 @@ # 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. +# Beware: the italian translation of the reStructuredText documentation +# at http://docit.bice.dyndns.org/static/ReST, in particular +# http://docit.bice.dyndns.org/static/ReST/ref/rst/directives.html, needs +# to be synced with the content of this file. """ Italian-language mappings for language-dependent features of @@ -34,14 +34,14 @@ directives = { 'blocco-interpretato': 'parsed-literal', 'rubrica': 'rubric', 'epigrafe': 'epigraph', - 'evidenzia': 'highlights', - 'pull-quote (translation required)': 'pull-quote', - 'compound (translation required)': 'compound', + 'punti-salienti': 'highlights', + 'estratto-evidenziato': 'pull-quote', + 'composito': 'compound', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', 'tabella': 'table', - 'csv-table (translation required)': 'csv-table', + 'tabella-csv': 'csv-table', 'meta': 'meta', #'imagemap': 'imagemap', 'immagine': 'image', @@ -53,6 +53,7 @@ directives = { 'classe': 'class', 'ruolo': 'role', 'indice': 'contents', + 'contenuti': 'contents', 'seznum': 'sectnum', 'sezioni-autonumerate': 'sectnum', 'annota-riferimenti-esterni': 'target-notes', -- cgit v1.2.1 From 057a4b6284f51a7db8ccbe14c89eb2ce64f40f32 Mon Sep 17 00:00:00 2001 From: lele Date: Thu, 20 Jan 2005 12:11:50 +0000 Subject: Use the singular 'contatto' instead of 'contatti' git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2944 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/it.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/languages/it.py b/docutils/languages/it.py index 08af6298a..fa40afa83 100644 --- a/docutils/languages/it.py +++ b/docutils/languages/it.py @@ -45,7 +45,7 @@ bibliographic_fields = { 'autori': 'authors', 'organizzazione': 'organization', 'indirizzo': 'address', - 'contatti': 'contact', + 'contatto': 'contact', 'versione': 'version', 'revisione': 'revision', 'status': 'status', -- cgit v1.2.1 From cbd0e428395a177fb91276711ea76bb7efb842b8 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 11 Feb 2005 10:11:46 +0000 Subject: made span.option contain option variable as well git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2957 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 526886764..809ff53a0 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -934,8 +934,10 @@ class HTMLTranslator(nodes.NodeVisitor): 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): @@ -979,10 +981,10 @@ class HTMLTranslator(nodes.NodeVisitor): 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') -- cgit v1.2.1 From 9a8a8bc179c879ad1e498f65029dfc8c2d0cab39 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 11 Feb 2005 10:26:47 +0000 Subject: added class="option-group" to option_group s for better customizability with CSS git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2959 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 809ff53a0..6853a5d0b 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -954,7 +954,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.context.append('\n ') else: self.context.append('') - self.body.append(self.starttag(node, 'td', **atts)) + self.body.append(self.starttag(node, 'td', CLASS='option-group', **atts)) self.body.append('') self.context.append(0) # count number of options -- cgit v1.2.1 From dd317b4e446e8c3666bf6e30e13ebf3a39e168f3 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 11 Feb 2005 15:49:20 +0000 Subject: Added "list-table" directive. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2963 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 1 + docutils/parsers/rst/directives/tables.py | 103 +++++++++++++++++++++++++++- docutils/parsers/rst/languages/af.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/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 + 16 files changed, 117 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 7ef052053..adc43ffc2 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -113,6 +113,7 @@ _directive_registry = { #'questions': ('body', 'question_list'), 'table': ('tables', 'table'), 'csv-table': ('tables', 'csv_table'), + 'list-table': ('tables', 'list_table'), 'image': ('images', 'image'), 'figure': ('images', 'figure'), 'contents': ('parts', 'contents'), diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 5b4cf8313..b0d633079 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -44,7 +44,6 @@ def table(name, arguments, options, content, lineno, return [warning] title, messages = make_title(arguments, state, lineno) node = nodes.Element() # anonymous container for parsing - text = '\n'.join(content) state.nested_parse(content, content_offset, node) if len(node) != 1 or not isinstance(node[0], nodes.table): error = state_machine.reporter.error( @@ -304,3 +303,105 @@ def extend_short_rows_with_empty_cells(columns, parts): for row in part: if len(row) < columns: row.extend([(0, 0, 0, [])] * (columns - len(row))) + +def list_table(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + """ + Implement tables whose data is encoded as a uniform two-level bullet list. + For further ideas, see + http://docutils.sf.net/docs/dev/rst/alternatives.html#list-driven-tables + """ + if not content: + error = state_machine.reporter.error( + 'The "%s" directive is empty; content required.' % name, + nodes.literal_block(block_text, block_text), line=lineno) + return [error] + title, messages = make_title(arguments, state, lineno) + node = nodes.Element() # anonymous container for parsing + state.nested_parse(content, content_offset, node) + try: + num_cols, col_widths = check_list_content( + node, name, options, content, lineno, block_text, state_machine) + table_data = [[item.children for item in row_list[0]] + for row_list in node[0]] + header_rows = options.get('header-rows', 0) # default 0 + check_table_dimensions( + table_data, header_rows, name, lineno, block_text, state_machine) + except SystemMessagePropagation, detail: + return [detail.args[0]] + table_node = build_table_from_list(table_data, col_widths, header_rows) + if options.has_key('class'): + table_node.set_class(options['class']) + if title: + table_node.insert(0, title) + return [table_node] + messages + +list_table.arguments = (0, 1, 1) +list_table.options = {'header-rows': directives.nonnegative_int, + 'widths': directives.positive_int_list, + 'class': directives.class_option} +list_table.content = 1 + +def check_list_content(node, name, options, content, lineno, block_text, + state_machine): + if len(node) != 1 or not isinstance(node[0], nodes.bullet_list): + error = state_machine.reporter.error( + 'Error parsing content block for the "%s" directive: ' + 'exactly one bullet list expected.' % name, + nodes.literal_block(block_text, block_text), line=lineno) + raise SystemMessagePropagation(error) + list_node = node[0] + # Check for a uniform two-level bullet list: + for item_index in range(len(list_node)): + item = list_node[item_index] + if len(item) != 1 or not isinstance(item[0], nodes.bullet_list): + error = state_machine.reporter.error( + 'Error parsing content block for the "%s" directive: ' + 'two-level bullet list expected, but row %s does not contain ' + 'a second-level bullet list.' % (name, item_index + 1), + nodes.literal_block(block_text, block_text), line=lineno) + raise SystemMessagePropagation(error) + elif item_index: + if len(item[0]) != num_cols: + error = state_machine.reporter.error( + 'Error parsing content block for the "%s" directive: ' + 'uniform two-level bullet list expected, but row %s does ' + 'not contain the same number of items as row 1 (%s vs %s).' + % (name, item_index + 1, len(item[0]), num_cols), + nodes.literal_block(block_text, block_text), line=lineno) + raise SystemMessagePropagation(error) + else: + num_cols = len(item[0]) + col_widths = get_column_widths( + num_cols, name, options, lineno, block_text, state_machine) + if len(col_widths) != num_cols: + error = state_machine.reporter.error( + 'Error parsing "widths" option of the "%s" directive: ' + 'number of columns does not match the table data (%s vs %s).' + % (name, len(col_widths), num_cols), + nodes.literal_block(block_text, block_text), line=lineno) + raise SystemMessagePropagation(error) + return num_cols, col_widths + +def build_table_from_list(table_data, col_widths, header_rows): + table = nodes.table() + tgroup = nodes.tgroup(cols=len(col_widths)) + table += tgroup + for col_width in col_widths: + tgroup += nodes.colspec(colwidth=col_width) + rows = [] + for row in table_data: + row_node = nodes.row() + for cell in row: + entry = nodes.entry() + entry += cell + row_node += entry + rows.append(row_node) + if header_rows: + thead = nodes.thead() + thead.extend(rows[:header_rows]) + tgroup += thead + tbody = nodes.tbody() + tbody.extend(rows[header_rows:]) + tgroup += tbody + return table diff --git a/docutils/parsers/rst/languages/af.py b/docutils/parsers/rst/languages/af.py index 26a9449bc..e3664f717 100644 --- a/docutils/parsers/rst/languages/af.py +++ b/docutils/parsers/rst/languages/af.py @@ -42,6 +42,7 @@ directives = { #'faq': 'questions', 'table (translation required)': 'table', 'csv-table (translation required)': 'csv-table', + 'list-table (translation required)': 'list-table', 'meta': 'meta', #'beeldkaart': 'imagemap', 'beeld': 'image', diff --git a/docutils/parsers/rst/languages/cs.py b/docutils/parsers/rst/languages/cs.py index 5d14b353e..af32e69d6 100644 --- a/docutils/parsers/rst/languages/cs.py +++ b/docutils/parsers/rst/languages/cs.py @@ -43,6 +43,7 @@ directives = { #'faq': 'questions', u'table (translation required)': 'table', u'csv-table (translation required)': 'csv-table', + u'list-table (translation required)': 'list-table', u'meta (translation required)': 'meta', #'imagemap': 'imagemap', u'image (translation required)': 'image', # obrazek diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index 66ca1cb95..8ea77485b 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -42,6 +42,7 @@ directives = { #'fragen': 'questions', 'tabelle': 'table', 'csv-tabelle': 'csv-table', + 'list-table (translation required)': 'list-table', 'meta': 'meta', #'imagemap': 'imagemap', 'bild': 'image', diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index 5f83cd764..dcd5b9584 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -41,6 +41,7 @@ directives = { #'questions': 'questions', 'table': 'table', 'csv-table': 'csv-table', + 'list-table': 'list-table', #'qa': 'questions', #'faq': 'questions', 'meta': 'meta', diff --git a/docutils/parsers/rst/languages/eo.py b/docutils/parsers/rst/languages/eo.py index 0eada6bb5..4065f88d4 100644 --- a/docutils/parsers/rst/languages/eo.py +++ b/docutils/parsers/rst/languages/eo.py @@ -48,6 +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'meta': 'meta', #'imagemap': 'imagemap', u'bildo': 'image', diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index e7a1cfd5c..efd7ece08 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -50,6 +50,7 @@ directives = { u'tabla': 'table', u'tabla-vsc': 'csv-table', u'tabla-csv': 'csv-table', + u'list-table (translation required)': 'list-table', u'meta': 'meta', #'imagemap': 'imagemap', u'imagen': 'image', diff --git a/docutils/parsers/rst/languages/fi.py b/docutils/parsers/rst/languages/fi.py index c03618fc3..a718e7773 100644 --- a/docutils/parsers/rst/languages/fi.py +++ b/docutils/parsers/rst/languages/fi.py @@ -39,6 +39,7 @@ directives = { u'lainaus': u'pull-quote', u'taulukko': u'table', u'csv-taulukko': u'csv-table', + u'list-table (translation required)': 'list-table', u'compound (translation required)': 'compound', #u'kysymykset': u'questions', u'meta': u'meta', diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index 126abbf1e..26668ef09 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -44,6 +44,7 @@ directives = { #u'faq': 'questions', u'tableau': 'table', u'csv-table (translation required)': 'csv-table', + u'list-table (translation required)': 'list-table', u'm\u00E9ta': 'meta', #u'imagemap (translation required)': 'imagemap', u'image': 'image', diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index 127318d0a..4a7c15ad9 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -42,6 +42,7 @@ directives = { #'faq': 'questions', 'tabella': 'table', 'tabella-csv': 'csv-table', + 'list-table (translation required)': 'list-table', 'meta': 'meta', #'imagemap': 'imagemap', 'immagine': 'image', diff --git a/docutils/parsers/rst/languages/pt_br.py b/docutils/parsers/rst/languages/pt_br.py index 48abd5689..92801268b 100644 --- a/docutils/parsers/rst/languages/pt_br.py +++ b/docutils/parsers/rst/languages/pt_br.py @@ -43,6 +43,7 @@ directives = { #'faq': 'questions', u'table (translation required)': 'table', u'csv-table (translation required)': 'csv-table', + u'list-table (translation required)': 'list-table', 'meta': 'meta', #'imagemap': 'imagemap', 'imagem': 'image', diff --git a/docutils/parsers/rst/languages/ru.py b/docutils/parsers/rst/languages/ru.py index 361565f62..44363f5f1 100644 --- a/docutils/parsers/rst/languages/ru.py +++ b/docutils/parsers/rst/languages/ru.py @@ -26,6 +26,7 @@ directives = { u'compound (translation required)': 'compound', u'table (translation required)': 'table', u'csv-table (translation required)': 'csv-table', + u'list-table (translation required)': 'list-table', u'\u0441\u044b\u0440\u043e\u0439': u'raw', u'\u0437\u0430\u043c\u0435\u043d\u0430': u'replace', u'\u0442\u0435\u0441\u0442\u043e\u0432\u0430\u044f-\u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u0430-restructuredtext': diff --git a/docutils/parsers/rst/languages/sk.py b/docutils/parsers/rst/languages/sk.py index 13c72a1fd..fc1c54752 100644 --- a/docutils/parsers/rst/languages/sk.py +++ b/docutils/parsers/rst/languages/sk.py @@ -42,6 +42,7 @@ directives = { #u'faq': 'questions', u'table (translation required)': 'table', u'csv-table (translation required)': 'csv-table', + u'list-table (translation required)': 'list-table', u'meta': 'meta', #u'imagemap': 'imagemap', u'obr\xe1zok': 'image', diff --git a/docutils/parsers/rst/languages/sv.py b/docutils/parsers/rst/languages/sv.py index ba4407860..b64b7a57f 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -42,6 +42,7 @@ directives = { # u'vanliga-fr\u00e5gor': 'questions', u'table (translation required)': 'table', u'csv-table (translation required)': 'csv-table', + u'list-table (translation required)': 'list-table', u'meta': 'meta', # u'bildkarta': 'imagemap', # FIXME: Translation might be too literal. u'bild': 'image', diff --git a/docutils/parsers/rst/languages/zh_tw.py b/docutils/parsers/rst/languages/zh_tw.py index c0f1632ff..57c04eaaa 100644 --- a/docutils/parsers/rst/languages/zh_tw.py +++ b/docutils/parsers/rst/languages/zh_tw.py @@ -41,6 +41,7 @@ directives = { #'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', -- cgit v1.2.1 From 06ecc66a1e731e2d3cf4c0b4bedbd6353e3a8497 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 17 Feb 2005 14:39:07 +0000 Subject: typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2967 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index ddb2e5100..43a25b5ab 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1432,7 +1432,7 @@ class Body(RSTState): optlist.append(option) else: raise MarkupError( - 'wrong numer of option tokens (=%s), should be 1 or 2: ' + 'wrong number of option tokens (=%s), should be 1 or 2: ' '"%s"' % (len(tokens), optionstring), self.state_machine.abs_line_number() + 1) return optlist -- cgit v1.2.1 From 92b0917ae757987cc88daeefb777df3068c703f5 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 17 Feb 2005 14:50:10 +0000 Subject: allow option arguments in angle brackets to start with a non-alphanumeric character git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2969 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 43a25b5ab..b42d32a71 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1039,7 +1039,7 @@ class Body(RSTState): '|%(upperroman)s)' % enum.sequencepats) pats['optname'] = '%(alphanum)s%(alphanumplus)s*' % pats # @@@ Loosen up the pattern? Allow Unicode? - pats['optarg'] = '(%(alpha)s%(alphanumplus)s*|<%(alphanum)s[^ <>]+>)' % pats + pats['optarg'] = '(%(alpha)s%(alphanumplus)s*|<[^ <>]+>)' % pats pats['shortopt'] = r'(-|\+)%(alphanum)s( ?%(optarg)s)?' % pats pats['longopt'] = r'(--|/)%(optname)s([ =]%(optarg)s)?' % pats pats['option'] = r'(%(shortopt)s|%(longopt)s)' % pats -- cgit v1.2.1 From 247eacc6304c69815375f27fdc2747da523ccd90 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 17 Feb 2005 16:24:04 +0000 Subject: Fixed ``Input.decode`` method to apply heuristics only if no encoding is explicitly given. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2972 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index d1117d8a7..6365f2b8b 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -70,20 +70,23 @@ class Input(TransformSpec): if (self.encoding and self.encoding.lower() == 'unicode' or isinstance(data, UnicodeType)): return data - encodings = [self.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 - encodings.append('latin-1') + encodings = [self.encoding] + if not self.encoding: + # Apply heuristics only if no encoding is explicitly given. + encodings.append('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 + encodings.append('latin-1') for enc in encodings: if not enc: continue -- cgit v1.2.1 From dbcbf302d825c92cd21ae2b163ad443c0f22ebc4 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 17 Feb 2005 16:26:15 +0000 Subject: Fixed "include" and "raw" directives to catch text decoding errors. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2973 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index d615f5540..c774eeef0 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -48,7 +48,14 @@ def include(name, arguments, options, content, lineno, % (name, error.__class__.__name__, error), nodes.literal_block(block_text, block_text), line=lineno) return [severe] - include_text = include_file.read() + try: + include_text = include_file.read() + except UnicodeError, error: + severe = state_machine.reporter.severe( + 'Problem with "%s" directive:\n%s: %s' + % (name, error.__class__.__name__, error), + nodes.literal_block(block_text, block_text), line=lineno) + return [severe] if options.has_key('literal'): literal_block = nodes.literal_block(include_text, include_text, source=path) @@ -106,7 +113,14 @@ def raw(name, arguments, options, content, lineno, 'Problems with "%s" directive path:\n%s.' % (name, error), nodes.literal_block(block_text, block_text), line=lineno) return [severe] - text = raw_file.read() + try: + text = raw_file.read() + except UnicodeError, error: + severe = state_machine.reporter.severe( + 'Problem with "%s" directive:\n%s: %s' + % (name, error.__class__.__name__, error), + nodes.literal_block(block_text, block_text), line=lineno) + return [severe] attributes['source'] = path elif options.has_key('url'): if not urllib2: @@ -128,7 +142,14 @@ def raw(name, arguments, options, content, lineno, raw_file = io.StringInput( source=raw_text, source_path=source, encoding=encoding, error_handler=state.document.settings.input_encoding_error_handler) - text = raw_file.read() + try: + text = raw_file.read() + except UnicodeError, error: + severe = state_machine.reporter.severe( + 'Problem with "%s" directive:\n%s: %s' + % (name, error.__class__.__name__, error), + nodes.literal_block(block_text, block_text), line=lineno) + return [severe] attributes['source'] = source else: error = state_machine.reporter.warning( -- cgit v1.2.1 From 6e59df17d0c4a53e5d5ced08f5ef58852bc66ec8 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 19 Feb 2005 01:23:10 +0000 Subject: Fixed option lists to allow spaces inside ````. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2975 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index b42d32a71..3427c4694 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1039,7 +1039,7 @@ class Body(RSTState): '|%(upperroman)s)' % enum.sequencepats) pats['optname'] = '%(alphanum)s%(alphanumplus)s*' % pats # @@@ Loosen up the pattern? Allow Unicode? - pats['optarg'] = '(%(alpha)s%(alphanumplus)s*|<[^ <>]+>)' % pats + pats['optarg'] = '(%(alpha)s%(alphanumplus)s*|<[^<>]+>)' % pats pats['shortopt'] = r'(-|\+)%(alphanum)s( ?%(optarg)s)?' % pats pats['longopt'] = r'(--|/)%(optname)s([ =]%(optarg)s)?' % pats pats['option'] = r'(%(shortopt)s|%(longopt)s)' % pats @@ -1415,14 +1415,20 @@ class Body(RSTState): delimiter = ' ' firstopt = tokens[0].split('=') if len(firstopt) > 1: + # "--opt=value" form tokens[:1] = firstopt delimiter = '=' elif (len(tokens[0]) > 2 and ((tokens[0].startswith('-') and not tokens[0].startswith('--')) or tokens[0].startswith('+'))): + # "-ovalue" form tokens[:1] = [tokens[0][:2], tokens[0][2:]] delimiter = '' + if len(tokens) > 1 and (tokens[1].startswith('<') + and tokens[-1].endswith('>')): + # "-o " form; join all values into one token + tokens[1:] = [' '.join(tokens[1:])] if 0 < len(tokens) <= 2: option = nodes.option(optionstring) option += nodes.option_string(tokens[0], tokens[0]) -- cgit v1.2.1 From 7d3cee3b8d94922de7bfac09fd09a051b26176b9 Mon Sep 17 00:00:00 2001 From: lele Date: Sun, 20 Feb 2005 17:06:35 +0000 Subject: New translation for 'list-table' git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2978 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/it.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index 4a7c15ad9..a04f98fa4 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -42,7 +42,7 @@ directives = { #'faq': 'questions', 'tabella': 'table', 'tabella-csv': 'csv-table', - 'list-table (translation required)': 'list-table', + 'tabella-elenco': 'list-table', 'meta': 'meta', #'imagemap': 'imagemap', 'immagine': 'image', -- cgit v1.2.1 From a3e14f83bb27fe386e91b58604f7cf77810793cf Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 22 Feb 2005 01:29:17 +0000 Subject: Caught empty CSV table bug git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2980 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index b0d633079..6940bc72f 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -294,8 +294,13 @@ def get_column_widths(max_cols, name, options, lineno, block_text, % (name, max_cols), nodes.literal_block(block_text, block_text), line=lineno) raise SystemMessagePropagation(error) - else: + elif max_cols: col_widths = [100 / max_cols] * max_cols + else: + error = state_machine.reporter.error( + 'No table data detected in CSV file.', + nodes.literal_block(block_text, block_text), line=lineno) + raise SystemMessagePropagation(error) return col_widths def extend_short_rows_with_empty_cells(columns, parts): -- cgit v1.2.1 From 920206cc36d23d7bf159246f0d9e4c036559683d Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 25 Feb 2005 01:32:01 +0000 Subject: provide better reporting of decoding errors git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2981 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index 6365f2b8b..a5f0bd889 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -87,6 +87,8 @@ class Input(TransformSpec): except: pass encodings.append('latin-1') + error = None + error_details = '' for enc in encodings: if not enc: continue @@ -94,11 +96,15 @@ class Input(TransformSpec): decoded = unicode(data, enc, self.error_handler) self.successful_encoding = enc return decoded - except (UnicodeError, LookupError): + except (UnicodeError, LookupError), error: pass + if error is not None: + error_details = '\n(%s: %s)' % (error.__class__.__name__, error) raise UnicodeError( - 'Unable to decode input data. Tried the following encodings: %s.' - % ', '.join([repr(enc) for enc in encodings if enc])) + 'Unable to decode input data. Tried the following encodings: ' + '%s.%s' + % (', '.join([repr(enc) for enc in encodings if enc]), + error_details)) class Output(TransformSpec): -- cgit v1.2.1 From 69f0b1fb2cf475fdf9dd93f5e14b2a776ab33b63 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 25 Feb 2005 23:36:02 +0000 Subject: whitespace git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2983 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 5926ae456..9296c9126 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1363,6 +1363,7 @@ class SparseNodeVisitor(NodeVisitor): subclasses), subclass `NodeVisitor` instead. """ + class GenericNodeVisitor(NodeVisitor): """ @@ -1408,6 +1409,7 @@ def _add_node_class_names(names): _add_node_class_names(node_class_names) + class TreeCopyVisitor(GenericNodeVisitor): """ -- cgit v1.2.1 From 6702b7a9b8c842cf05719ef4c9c403495d28df04 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 25 Feb 2005 23:36:43 +0000 Subject: Fixed mislocated internal targets bug, by relocating targets into the next text element. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2984 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 122 ++++++++++++++++++++++++++------------ 1 file changed, 85 insertions(+), 37 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 254a0ee07..426d4c524 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -382,49 +382,97 @@ class ExternalTargets(Transform): class InternalTargets(Transform): - """ - Given:: + default_priority = 660 - - - direct internal - + def apply(self): + for target in self.document.internal_targets: + self.resolve_reference_ids(target) + if not (target.attributes.has_key('refid') + or target.attributes.has_key('refuri') + or target.attributes.has_key('refname')): + self.relocate(target) - The "refname" attribute is replaced by "refid" linking to the target's - "id":: + def resolve_reference_ids(self, target): + """ + Given:: - - - direct internal - - """ + + + direct internal + - default_priority = 660 + The "refname" attribute is replaced by "refid" linking to the target's + "id":: - def apply(self): - 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.document.refnames[name] - except KeyError, instance: - if target.referenced: - continue - msg = self.document.reporter.info( - 'Internal hyperlink target "%s" is not referenced.' - % name, base_node=target) - target.referenced = 1 - continue - for ref in reflist: - if ref.resolved: - continue - del ref['refname'] - ref['refid'] = refid - ref.resolved = 1 + + + direct internal + + """ + if target.hasattr('refuri') or target.hasattr('refid') \ + or not target.hasattr('name'): + return + name = target['name'] + refid = target['id'] + try: + reflist = self.document.refnames[name] + except KeyError, instance: + if target.referenced: + return + msg = self.document.reporter.info( + 'Internal hyperlink target "%s" is not referenced.' + % name, base_node=target) target.referenced = 1 + return + for ref in reflist: + if ref.resolved: + return + del ref['refname'] + ref['refid'] = refid + ref.resolved = 1 + target.referenced = 1 + + def relocate(self, target): + """ + Move "target" elements into the next text element + (in tree traversal order). + """ + parent = target.parent + child = target + while parent: + # Check all following siblings: + for index in range(parent.index(child) + 1, len(parent)): + element = parent[index] + visitor = InternalTargetRelocationPointLocator(self.document) + try: + element.walk(visitor) + except nodes.NodeFound: + target.parent.remove(target) + visitor.found.insert(0, target) + return + else: + # At end of section or container; try parent's sibling + child = parent + parent = parent.parent + error = self.document.reporter.error( + 'No element suitable for hosting target, following internal ' + 'target "%s".' % target['name'], line=target.line) + target.parent.replace(target, error) + + +class InternalTargetRelocationPointLocator(nodes.GenericNodeVisitor): + + """ + Find the first text-containing node that can host an internal target. + """ + + found = None + + def default_visit(self, node): + if (isinstance(node, nodes.TextElement) + and not isinstance(node, nodes.Special)): + self.found = node + raise nodes.NodeFound class Footnotes(Transform): -- cgit v1.2.1 From 999a66a7ae7196962673dc71b732a704d8275ed2 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 26 Feb 2005 18:17:59 +0000 Subject: enable --dump-* options when --traceback specified; allows for easier debugging git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2987 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'docutils') diff --git a/docutils/core.py b/docutils/core.py index 84136d5b2..4cb9d7ec3 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -197,6 +197,7 @@ class Publisher: self.writer.assemble_parts() except Exception, error: if self.settings.traceback: # propagate exceptions? + self.debugging_dumps(document) raise self.report_Exception(error) exit = 1 @@ -210,6 +211,8 @@ class Publisher: return output def debugging_dumps(self, document): + if not document: + return if self.settings.dump_settings: print >>sys.stderr, '\n::: Runtime settings:' print >>sys.stderr, pprint.pformat(self.settings.__dict__) -- cgit v1.2.1 From d097e1056d6223b6681dbc620c7a302f641c3f73 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 26 Feb 2005 18:20:45 +0000 Subject: Fixed duplicate footnote label bug. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2989 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 426d4c524..8fda16c77 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -671,15 +671,17 @@ class Footnotes(Transform): references. """ for footnote in self.document.footnotes: - label = footnote['name'] - if self.document.footnote_refs.has_key(label): - reflist = self.document.footnote_refs[label] - self.resolve_references(footnote, reflist) + if footnote.hasattr('name'): + label = footnote['name'] + if self.document.footnote_refs.has_key(label): + reflist = self.document.footnote_refs[label] + self.resolve_references(footnote, reflist) for citation in self.document.citations: - label = citation['name'] - if self.document.citation_refs.has_key(label): - reflist = self.document.citation_refs[label] - self.resolve_references(citation, reflist) + if citation.hasattr('name'): + label = citation['name'] + 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): id = note['id'] -- cgit v1.2.1 From abeb1862f5a6144e6e2ab4045375e615ae1a4f87 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 26 Feb 2005 18:49:47 +0000 Subject: Fixed unencoded stylesheet reference bug (characters like "&" in stylesheet reference). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2992 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 6853a5d0b..148790b58 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -198,7 +198,8 @@ class HTMLTranslator(nodes.NodeVisitor): else: stylesheet = utils.get_stylesheet_reference(settings) if stylesheet: - self.stylesheet = [self.stylesheet_link % stylesheet] + self.stylesheet = [self.stylesheet_link + % self.encode(stylesheet)] else: self.stylesheet = [] self.body_prefix = ['\n\n'] -- cgit v1.2.1 From d0042a179d7074b411890bdb80d17513dc43c335 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 27 Feb 2005 00:06:51 +0000 Subject: use "span" instead of "a" tags for targets, because otherwise we get invalid XHTML due to nested "a" elements git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2995 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 148790b58..cd28ffa15 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -1202,8 +1202,8 @@ class HTMLTranslator(nodes.NodeVisitor): 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('') + self.body.append(self.starttag(node, 'span', '', CLASS='target')) + self.context.append('') else: self.context.append('') -- cgit v1.2.1 From 6e194ab6b0f7b77f7c8edf53730f52bd8ce5f4a1 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 27 Feb 2005 01:00:59 +0000 Subject: when relocating a target, it now acquires the children of its new parent; fixed bug in recording internal targets so that anonymous targets are relocated as well git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2996 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 2 ++ docutils/transforms/references.py | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 3427c4694..f2c2d5144 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1857,6 +1857,8 @@ class Body(RSTState): 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 8fda16c77..c8989f2a6 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -448,7 +448,10 @@ class InternalTargets(Transform): element.walk(visitor) except nodes.NodeFound: target.parent.remove(target) - visitor.found.insert(0, target) + for child in visitor.found: + target += child + visitor.found.children = [] + visitor.found += target return else: # At end of section or container; try parent's sibling -- cgit v1.2.1 From 30f3a9b6afcf55afe190a28667a54a58c3d76c5f Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 3 Mar 2005 19:35:02 +0000 Subject: lowercased bibliographic fields; closing https://sourceforge.net/tracker/?func=detail&atid=422030&aid=1153237&group_id=38414; thanks Vjacheslav git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2999 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/ru.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'docutils') diff --git a/docutils/languages/ru.py b/docutils/languages/ru.py index f1b7d1975..369d2febd 100644 --- a/docutils/languages/ru.py +++ b/docutils/languages/ru.py @@ -46,21 +46,21 @@ labels = { """Mapping of node class name to label text.""" bibliographic_fields = { - u'\u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f': u'abstract', - u'\u0410\u0434\u0440\u0435\u0441': u'address', - u'\u0410\u0432\u0442\u043e\u0440': u'author', - u'\u0410\u0432\u0442\u043e\u0440\u044b': u'authors', - u'\u041a\u043e\u043d\u0442\u0430\u043a\u0442': u'contact', - u'\u041f\u0440\u0430\u0432\u0430 \u043a\u043e\u043f\u0438\u0440\u043e' + u'\u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f': u'abstract', + u'\u0430\u0434\u0440\u0435\u0441': u'address', + u'\u0430\u0432\u0442\u043e\u0440': u'author', + u'\u0430\u0432\u0442\u043e\u0440\u044b': u'authors', + u'\u043a\u043e\u043d\u0442\u0430\u043a\u0442': u'contact', + u'\u043f\u0440\u0430\u0432\u0430 \u043a\u043e\u043f\u0438\u0440\u043e' u'\u0432\u0430\u043d\u0438\u044f': u'copyright', - u'\u0414\u0430\u0442\u0430': u'date', - u'\u041f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u0438\u0435': + u'\u0434\u0430\u0442\u0430': u'date', + u'\u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u0438\u0435': u'dedication', - u'\u041e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044f': + u'\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044f': u'organization', - u'\u0420\u0435\u0434\u0430\u043a\u0446\u0438\u044f': u'revision', - u'\u0421\u0442\u0430\u0442\u0443\u0441': u'status', - u'\u0412\u0435\u0440\u0441\u0438\u044f': u'version'} + u'\u0440\u0435\u0434\u0430\u043a\u0446\u0438\u044f': u'revision', + u'\u0441\u0442\u0430\u0442\u0443\u0441': u'status', + u'\u0432\u0435\u0440\u0441\u0438\u044f': u'version'} """Russian (lowcased) to canonical name mapping for bibliographic fields.""" author_separators = [';', ','] -- cgit v1.2.1 From 2f8b9f01ba6bb14710507c987a99fc2a5ca95221 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 4 Mar 2005 22:20:43 +0000 Subject: removed code duplication git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3002 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 9296c9126..011b03e88 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -388,12 +388,9 @@ class Element(Node): def __iadd__(self, other): """Append a node or a list of nodes to `self.children`.""" if isinstance(other, Node): - self.setup_child(other) - self.children.append(other) + self.append(other) elif other is not None: - for node in other: - self.setup_child(node) - self.children.extend(other) + self.extend(other) return self def astext(self): @@ -426,8 +423,7 @@ class Element(Node): def extend(self, item): for node in item: - self.setup_child(node) - self.children.extend(item) + self.append(node) def insert(self, index, item): if isinstance(item, Node): -- cgit v1.2.1 From 24b6c2e1fce8d7cc7f9e3c482ed107cd63aa25ac Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 4 Mar 2005 22:50:47 +0000 Subject: added Element.clear() git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3003 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 011b03e88..2cb04300c 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -441,6 +441,9 @@ class Element(Node): def index(self, item): return self.children.index(item) + def clear(self): + self.children = [] + def replace(self, old, new): """Replace one child `Node` with another child or children.""" index = self.index(old) -- cgit v1.2.1 From aa76cea304f331ad416e6f4623c2e5f00f995c58 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 4 Mar 2005 22:52:04 +0000 Subject: removed direct references to Element.children attribute outside nodes.py git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3004 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/images.py | 2 +- docutils/parsers/rst/directives/misc.py | 4 ++-- docutils/parsers/rst/directives/tables.py | 2 +- docutils/parsers/rst/states.py | 2 +- docutils/transforms/frontmatter.py | 8 ++++---- docutils/transforms/references.py | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index bf13b93e1..eac3d174c 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -97,7 +97,7 @@ def figure(name, arguments, options, content, lineno, first_node = node[0] if isinstance(first_node, nodes.paragraph): caption = nodes.caption(first_node.rawsource, '', - *first_node.children) + *first_node.get_children()) figure_node += caption elif not (isinstance(first_node, nodes.comment) and len(first_node) == 0): diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index c774eeef0..127ec2d42 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -190,7 +190,7 @@ def replace(name, arguments, options, content, lineno, messages.append(error) return messages else: - return element[0].children + return element[0].get_children() else: error = state_machine.reporter.error( 'The "%s" directive is empty; content required.' % (name), @@ -234,7 +234,7 @@ def unicode_directive(name, arguments, options, content, lineno, nodes.literal_block(block_text, block_text), line=lineno) return [error] element += nodes.Text(decoded) - return element.children + return element.get_children() unicode_directive.arguments = (1, 0, 1) unicode_directive.options = {'trim': directives.flag, diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 6940bc72f..653499c20 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -327,7 +327,7 @@ def list_table(name, arguments, options, content, lineno, try: num_cols, col_widths = check_list_content( node, name, options, content, lineno, block_text, state_machine) - table_data = [[item.children for item in row_list[0]] + table_data = [[item.get_children() for item in row_list[0]] for row_list in node[0]] header_rows = options.get('header-rows', 0) # default 0 check_table_dimensions( diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index f2c2d5144..c4dff990a 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -2621,7 +2621,7 @@ class Text(RSTState): state_machine_kwargs={'state_classes': (QuotedLiteralBlock,), 'initial_state': 'QuotedLiteralBlock'}) self.goto_line(new_abs_offset) - return parent_node.children + return parent_node.get_children() def definition_list_item(self, termline): indented, indent, line_offset, blank_finish = \ diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index 1a45c1336..979ad1d65 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -294,9 +294,9 @@ class DocInfo(Transform): raise TransformError title = nodes.title(name, labels[canonical]) topics[canonical] = biblioclass( - '', title, CLASS=canonical, *field[1].children) + '', title, CLASS=canonical, *field[1].get_children()) else: - docinfo.append(biblioclass('', *field[1].children)) + docinfo.append(biblioclass('', *field[1].get_children())) except TransformError: if len(field[-1]) == 1 \ and isinstance(field[-1][0], nodes.paragraph): @@ -386,7 +386,7 @@ class DocInfo(Transform): for item in field[1][0]: if len(item) != 1 or not isinstance(item[0], nodes.paragraph): raise TransformError - authors.append(item[0].children) + authors.append(item[0].get_children()) if not authors: raise TransformError return authors @@ -395,5 +395,5 @@ class DocInfo(Transform): for item in field[1]: if not isinstance(item, nodes.paragraph): raise TransformError - authors = [item.children for item in field[1]] + authors = [item.get_children() for item in field[1]] return authors diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index c8989f2a6..5ea2f1b00 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -450,7 +450,7 @@ class InternalTargets(Transform): target.parent.remove(target) for child in visitor.found: target += child - visitor.found.children = [] + visitor.found.clear() visitor.found += target return else: -- cgit v1.2.1 From 272a0ee4d3814e7fafb1f9122ebf10ebc69a7511 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 4 Mar 2005 23:50:22 +0000 Subject: changed Element.get_children() so that it returns a copy git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3005 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 2cb04300c..78dd6f9a0 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -119,9 +119,8 @@ class Node: return except SkipDeparture: # not applicable; ignore pass - children = self.get_children() try: - for child in children[:]: + for child in self.get_children(): child.walk(visitor) except SkipSiblings: pass @@ -147,9 +146,8 @@ class Node: return except SkipDeparture: call_depart = 0 - children = self.get_children() try: - for child in children[:]: + for child in self.get_children(): child.walkabout(visitor) except SkipSiblings: pass @@ -502,8 +500,8 @@ class Element(Node): for child in self.children]) def get_children(self): - """Return this element's children.""" - return self.children + """Return a copy of this element's children as a list.""" + return list(self.children) def copy(self): return self.__class__(**self.attributes) -- cgit v1.2.1 From fb848ff48742947b27a9fc5f57058f9f9e28cba6 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 5 Mar 2005 14:09:48 +0000 Subject: reverted from 1.75 to 1.74; seemed like a bad idea git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3006 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 78dd6f9a0..2cb04300c 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -119,8 +119,9 @@ class Node: return except SkipDeparture: # not applicable; ignore pass + children = self.get_children() try: - for child in self.get_children(): + for child in children[:]: child.walk(visitor) except SkipSiblings: pass @@ -146,8 +147,9 @@ class Node: return except SkipDeparture: call_depart = 0 + children = self.get_children() try: - for child in self.get_children(): + for child in children[:]: child.walkabout(visitor) except SkipSiblings: pass @@ -500,8 +502,8 @@ class Element(Node): for child in self.children]) def get_children(self): - """Return a copy of this element's children as a list.""" - return list(self.children) + """Return this element's children.""" + return self.children def copy(self): return self.__class__(**self.attributes) -- cgit v1.2.1 From cb57e80d4b9d16aed07b08408f9e7ac527833bd1 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 5 Mar 2005 15:53:45 +0000 Subject: added Node.has_children() and Node.next_node() git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3007 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 2cb04300c..51bcb583d 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -161,6 +161,40 @@ class Node: category='nodes.Node.walkabout') visitor.dispatch_departure(self) + def has_children(self): + """Return true if this node has children.""" + return 0 + + def next_node(self, descend=1, ascend=1, cond=lambda e: 1): + """ + Return the next node in tree traversal order for which the + condition cond(node) is true. + + If descend is true, traverse children as well. If ascend is + true, go up in the tree if there is no direct next sibling. + Return None if there is no next node. + """ + node = self + while 1: + if descend and node.has_children(): + r = node[0] + elif node.parent is not None: + # Index of the next sibling. + index = node.parent.index(node) + 1 + if index < len(node.parent): + r = node.parent[index] + elif ascend: + r = node.parent.next_node(descend=0, ascend=1) + else: + return None + else: + return None + if cond(r): + return r + else: + # Get r.next_node(...), avoiding recursion. + node = r + class Text(Node, UserString): @@ -505,6 +539,10 @@ class Element(Node): """Return this element's children.""" return self.children + def has_children(self): + """Return true if this node has children.""" + return len(self.children) > 0 + def copy(self): return self.__class__(**self.attributes) -- cgit v1.2.1 From 26be35634ec3071982211cfe13e1c0b48d3aeb5f Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 5 Mar 2005 16:52:14 +0000 Subject: relocate internal targets only in front of sections, doctitles and subtitles git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3008 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/pep.py | 1 + docutils/readers/standalone.py | 1 + docutils/transforms/references.py | 76 ++++++++++++++------------------------- 3 files changed, 29 insertions(+), 49 deletions(-) (limited to 'docutils') diff --git a/docutils/readers/pep.py b/docutils/readers/pep.py index b615ba4db..b7774a949 100644 --- a/docutils/readers/pep.py +++ b/docutils/readers/pep.py @@ -31,6 +31,7 @@ class Reader(standalone.Reader): config_section_dependencies = ('readers', 'standalone reader') default_transforms = (references.Substitutions, + references.SectionTargets, peps.Headers, peps.Contents, references.ChainedTargets, diff --git a/docutils/readers/standalone.py b/docutils/readers/standalone.py index 29aec35dc..82541c297 100644 --- a/docutils/readers/standalone.py +++ b/docutils/readers/standalone.py @@ -43,6 +43,7 @@ class Reader(readers.Reader): config_section_dependencies = ('readers',) default_transforms = (references.Substitutions, + references.SectionTargets, frontmatter.DocTitle, frontmatter.DocInfo, references.ChainedTargets, diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 5ea2f1b00..2ffbfc9be 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -19,6 +19,33 @@ from docutils.transforms import TransformError, Transform indices = xrange(sys.maxint) +class SectionTargets(Transform): + + default_priority = 260 + + def apply(self): + for target in self.document.internal_targets: + if not (target.attributes.has_key('refid') + or target.attributes.has_key('refuri') + or target.attributes.has_key('refname')): + self.relocate(target) + + def relocate(self, target): + """ + Move "target" elements into the next title element if + necessary. + """ + assert isinstance(target, nodes.target) + # Find next node which is not a target. + n = target.next_node(cond=lambda x: not isinstance(x, nodes.target)) + if isinstance(n, nodes.section): + assert isinstance(n[0], nodes.title) + target.parent.remove(target) + target += n[0].get_children() + n[0].clear() + n[0] += target + + class ChainedTargets(Transform): """ @@ -387,10 +414,6 @@ class InternalTargets(Transform): def apply(self): for target in self.document.internal_targets: self.resolve_reference_ids(target) - if not (target.attributes.has_key('refid') - or target.attributes.has_key('refuri') - or target.attributes.has_key('refname')): - self.relocate(target) def resolve_reference_ids(self, target): """ @@ -432,51 +455,6 @@ class InternalTargets(Transform): ref.resolved = 1 target.referenced = 1 - def relocate(self, target): - """ - Move "target" elements into the next text element - (in tree traversal order). - """ - parent = target.parent - child = target - while parent: - # Check all following siblings: - for index in range(parent.index(child) + 1, len(parent)): - element = parent[index] - visitor = InternalTargetRelocationPointLocator(self.document) - try: - element.walk(visitor) - except nodes.NodeFound: - target.parent.remove(target) - for child in visitor.found: - target += child - visitor.found.clear() - visitor.found += target - return - else: - # At end of section or container; try parent's sibling - child = parent - parent = parent.parent - error = self.document.reporter.error( - 'No element suitable for hosting target, following internal ' - 'target "%s".' % target['name'], line=target.line) - target.parent.replace(target, error) - - -class InternalTargetRelocationPointLocator(nodes.GenericNodeVisitor): - - """ - Find the first text-containing node that can host an internal target. - """ - - found = None - - def default_visit(self, node): - if (isinstance(node, nodes.TextElement) - and not isinstance(node, nodes.Special)): - self.found = node - raise nodes.NodeFound - class Footnotes(Transform): -- cgit v1.2.1 From aebd1663dd94913d95761b230354731500a873cd Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 5 Mar 2005 17:40:15 +0000 Subject: added Node.tree() method git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3012 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 51bcb583d..d2b6c2f92 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -195,6 +195,13 @@ class Node: # Get r.next_node(...), avoiding recursion. node = r + def tree(self): + """Return the tree of this node.""" + r = [self] + for i in self.get_children(): + r.extend(i.tree()) + return r + class Text(Node, UserString): -- cgit v1.2.1 From 95bd4c152312d1b9a71ef107b8e3d8146b54b90d Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 5 Mar 2005 17:48:11 +0000 Subject: do not add a TOC-backlink if title contains a reference git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3014 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/parts.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index 769cb8263..496bcf92c 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -122,10 +122,13 @@ class Contents(Transform): ref_id = self.document.set_id(reference) entry = nodes.paragraph('', '', reference) item = nodes.list_item('', entry) - if self.backlinks == 'entry': - title['refid'] = ref_id - elif self.backlinks == 'top': - title['refid'] = self.toc_id + if (self.backlinks in ('entry', 'top') and + not filter(lambda x: isinstance(x, nodes.reference), + title.tree())): + if self.backlinks == 'entry': + title['refid'] = ref_id + elif self.backlinks == 'top': + title['refid'] = self.toc_id if level < depth: subsects = self.build_contents(section, level) item += subsects -- cgit v1.2.1 From eb61e1cc35eb16a7308e469e000a98f68d3ea896 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 5 Mar 2005 18:06:48 +0000 Subject: removed lambda, renamed cond to condition (explicit & self-documenting) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3016 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index d2b6c2f92..a4d74f561 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -165,10 +165,10 @@ class Node: """Return true if this node has children.""" return 0 - def next_node(self, descend=1, ascend=1, cond=lambda e: 1): + def next_node(self, descend=1, ascend=1, condition=None): """ - Return the next node in tree traversal order for which the - condition cond(node) is true. + Return the next node in tree traversal order for which + ``condition(node)`` is true. If descend is true, traverse children as well. If ascend is true, go up in the tree if there is no direct next sibling. @@ -189,7 +189,7 @@ class Node: return None else: return None - if cond(r): + if not condition or condition(r): return r else: # Get r.next_node(...), avoiding recursion. -- cgit v1.2.1 From b17334d09de7211955e834b0243695d6cb637d84 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 5 Mar 2005 18:32:47 +0000 Subject: Allowed whitespace in paths and URLs (targets; "image", "figure", & "include" directive args; ":file:" & ":url:" directive options). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3018 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 5 +---- docutils/parsers/rst/directives/images.py | 5 ----- docutils/parsers/rst/directives/misc.py | 5 ----- docutils/parsers/rst/states.py | 9 +-------- 4 files changed, 2 insertions(+), 22 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index adc43ffc2..4d45d72be 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -258,10 +258,7 @@ def path(argument): 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') + return path def nonnegative_int(argument): """ diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index eac3d174c..e47315576 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -30,11 +30,6 @@ def image(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): messages = [] 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 reference_node = None if options.has_key('target'): diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 127ec2d42..c88ed0922 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -28,11 +28,6 @@ def include(name, arguments, options, content, lineno, lineno - state_machine.input_offset - 1) source_dir = os.path.dirname(os.path.abspath(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) encoding = options.get('encoding', state.document.settings.input_encoding) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index c4dff990a..b9d257924 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1823,14 +1823,7 @@ class Body(RSTState): if refname: return 'refname', refname reference = ''.join([line.strip() for line in block]) - if reference.find(' ') == -1: - return 'refuri', unescape(reference) - else: - warning = self.reporter.warning( - 'Hyperlink target contains whitespace. Perhaps a footnote ' - 'was intended?', - nodes.literal_block(block_text, block_text), line=lineno) - return 'malformed', warning + return 'refuri', unescape(reference) def is_reference(self, reference): match = self.explicit.patterns.reference.match( -- cgit v1.2.1 From fd8dca3db3051aa4db1ba479e6ecf006c60c452e Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 5 Mar 2005 18:54:46 +0000 Subject: changed "cond" to "condition" in next_node call git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3020 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 2ffbfc9be..e42183634 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -37,7 +37,8 @@ class SectionTargets(Transform): """ assert isinstance(target, nodes.target) # Find next node which is not a target. - n = target.next_node(cond=lambda x: not isinstance(x, nodes.target)) + n = target.next_node( + condition=lambda x: not isinstance(x, nodes.target)) if isinstance(n, nodes.section): assert isinstance(n[0], nodes.title) target.parent.remove(target) -- cgit v1.2.1 From 696fdc7509435189525a9953fba48859e58ceab6 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 5 Mar 2005 21:29:16 +0000 Subject: made relocated targets before sections zero-length git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3021 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index e42183634..5677c5cf8 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -42,9 +42,7 @@ class SectionTargets(Transform): if isinstance(n, nodes.section): assert isinstance(n[0], nodes.title) target.parent.remove(target) - target += n[0].get_children() - n[0].clear() - n[0] += target + n[0].insert(0, target) class ChainedTargets(Transform): -- cgit v1.2.1 From de76fb4857800cda681e1c1bb83a2feaaa87a3a8 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 5 Mar 2005 22:07:49 +0000 Subject: fixed bug with chained targets in front of a section git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3022 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 5677c5cf8..9b7bb81a5 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -37,8 +37,11 @@ class SectionTargets(Transform): """ assert isinstance(target, nodes.target) # Find next node which is not a target. - n = target.next_node( - condition=lambda x: not isinstance(x, nodes.target)) + n = target.next_node(condition=lambda x: + not isinstance(x, nodes.target) or + x.has_key('refid') or + x.has_key('refuri') or + x.has_key('refname')) if isinstance(n, nodes.section): assert isinstance(n[0], nodes.title) target.parent.remove(target) -- cgit v1.2.1 From 0475344cde31dd90e93a188a572913ae6e7789f2 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 5 Mar 2005 22:32:07 +0000 Subject: "image" element class changed to subclass of Element, not TextElement (empty element; cannot contain text) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3023 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index a4d74f561..a84ad414d 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1260,7 +1260,7 @@ class superscript(Inline, TextElement): pass class subscript(Inline, TextElement): pass -class image(General, Inline, TextElement): +class image(General, Inline, Element): def astext(self): return self.get('alt', '') -- cgit v1.2.1 From 65d022b0038f1c38e7376740180107b056ca5227 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 6 Mar 2005 15:49:20 +0000 Subject: added more documentation to Node.tree() git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3025 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index a84ad414d..3eaecbce7 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -196,7 +196,24 @@ class Node: node = r def tree(self): - """Return the tree of this node.""" + """ + Return the tree of this node. + + Given the a paragraph node with the following tree:: + + + + + Foo + Bar + + Baz + + Then paragraph.tree() is:: + + [, , , , , + , ] + """ r = [self] for i in self.get_children(): r.extend(i.tree()) -- cgit v1.2.1 From ef0f3418f94c160ad02eb366a932a1dc9bb901d6 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 13 Mar 2005 02:41:36 +0000 Subject: renamed docutils.nodes.Node.tree to docutils.nodes.Node.flattened, and added to the docstring git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3029 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 9 +++++++-- docutils/transforms/parts.py | 4 ++-- docutils/transforms/references.py | 17 ++++++++--------- 3 files changed, 17 insertions(+), 13 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 3eaecbce7..727212b1a 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -195,9 +195,10 @@ class Node: # Get r.next_node(...), avoiding recursion. node = r - def tree(self): + def flattened(self): """ - Return the tree of this node. + Return a flattened representation of the (sub)tree rooted at this + node -- a list of nodes in tree traversal order. Given the a paragraph node with the following tree:: @@ -214,6 +215,10 @@ class Node: [, , , , , , ] """ + nodelist = [self] + for node in self.get_children(): + nodelist.extend(node.flattened()) + return nodelist r = [self] for i in self.get_children(): r.extend(i.tree()) diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index 496bcf92c..c9c0722ce 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -123,8 +123,8 @@ class Contents(Transform): entry = nodes.paragraph('', '', reference) item = nodes.list_item('', entry) if (self.backlinks in ('entry', 'top') and - not filter(lambda x: isinstance(x, nodes.reference), - title.tree())): + not [node for node in title.flattened() + if isinstance(node, nodes.reference)]): if self.backlinks == 'entry': title['refid'] = ref_id elif self.backlinks == 'top': diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 9b7bb81a5..fdebfb993 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -31,22 +31,21 @@ class SectionTargets(Transform): self.relocate(target) def relocate(self, target): - """ - Move "target" elements into the next title element if - necessary. - """ + """Move "target" elements into the next title element if necessary.""" assert isinstance(target, nodes.target) # Find next node which is not a target. - n = target.next_node(condition=lambda x: - not isinstance(x, nodes.target) or - x.has_key('refid') or - x.has_key('refuri') or - x.has_key('refname')) + n = target.next_node(condition=self.condition) if isinstance(n, nodes.section): assert isinstance(n[0], nodes.title) target.parent.remove(target) n[0].insert(0, target) + # This function needs a better name (and possibly a docstring), describing + # what it does and hopefully why: + def condition(self, node): + return (not isinstance(node, nodes.target) or node.has_key('refid') + or node.has_key('refuri') or node.has_key('refname')) + class ChainedTargets(Transform): -- cgit v1.2.1 From a73f41ba87e8d268e5eed1be73835ea6ddac9b7a Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 13 Mar 2005 02:49:51 +0000 Subject: simplified loop logic git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3030 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 727212b1a..f35872a6c 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -550,12 +550,10 @@ class Element(Node): 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 break - if not match: + else: return index return None -- cgit v1.2.1 From 42db2016c4b99839f278c8a72c34ba50eb890470 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 13 Mar 2005 11:04:44 +0000 Subject: renamed SectionTargets.condition() to possible_relocation_target(); added docs; if we add support for multiple ids and names, we might be able to merge ChainedTargets and SectionTargets; David, am I correct that the reST spec is missing chained external targets? git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3031 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index fdebfb993..6290c5153 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -34,15 +34,17 @@ class SectionTargets(Transform): """Move "target" elements into the next title element if necessary.""" assert isinstance(target, nodes.target) # Find next node which is not a target. - n = target.next_node(condition=self.condition) + n = target.next_node(condition=self.possible_relocation_target) if isinstance(n, nodes.section): assert isinstance(n[0], nodes.title) target.parent.remove(target) n[0].insert(0, target) - # This function needs a better name (and possibly a docstring), describing - # what it does and hopefully why: - def condition(self, node): + def possible_relocation_target(self, node): + """Return true if a preceding target could be relocated into node.""" + # True if node is not an internal target. (If it's an + # external target, we've just run into a not-yet resolved + # chained external target.) return (not isinstance(node, nodes.target) or node.has_key('refid') or node.has_key('refuri') or node.has_key('refname')) -- cgit v1.2.1 From 343e2407a1c49b31b9cc3863d58dc060b9c78bc2 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 13 Mar 2005 11:10:16 +0000 Subject: improved documentation of Element.flattened git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3032 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index f35872a6c..5f4ae11a6 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -198,7 +198,7 @@ class Node: def flattened(self): """ Return a flattened representation of the (sub)tree rooted at this - node -- a list of nodes in tree traversal order. + node -- an iterable of nodes in tree traversal order. Given the a paragraph node with the following tree:: @@ -210,10 +210,13 @@ class Node: Baz - Then paragraph.tree() is:: + Then paragraph.flattened() is:: [, , , , , , ] + + You should not rely on the return value to be a list; it could + be changed to an iterator later. """ nodelist = [self] for node in self.get_children(): -- cgit v1.2.1 From 692ebc31058c5a127244c2debbbfeaa286434945 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 13 Mar 2005 11:13:03 +0000 Subject: removed old implementation of Node.flattened() git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3033 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 5f4ae11a6..d4fb24d53 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -222,10 +222,6 @@ class Node: for node in self.get_children(): nodelist.extend(node.flattened()) return nodelist - r = [self] - for i in self.get_children(): - r.extend(i.tree()) - return r class Text(Node, UserString): -- cgit v1.2.1 From 4fe2b0fb8aa4609da22988bad7dd418c572386bf Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 14 Mar 2005 16:00:03 +0000 Subject: removed Node.has_children method git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3037 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index d4fb24d53..d384bfe92 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -161,10 +161,6 @@ class Node: category='nodes.Node.walkabout') visitor.dispatch_departure(self) - def has_children(self): - """Return true if this node has children.""" - return 0 - def next_node(self, descend=1, ascend=1, condition=None): """ Return the next node in tree traversal order for which @@ -176,7 +172,7 @@ class Node: """ node = self while 1: - if descend and node.has_children(): + if descend and node.get_children(): r = node[0] elif node.parent is not None: # Index of the next sibling. @@ -565,10 +561,6 @@ class Element(Node): """Return this element's children.""" return self.children - def has_children(self): - """Return true if this node has children.""" - return len(self.children) > 0 - def copy(self): return self.__class__(**self.attributes) -- cgit v1.2.1 From 43ca6a79125d28fce6c2ab2142f93733319382d4 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 14 Mar 2005 16:16:57 +0000 Subject: removed redundant get_children(); in case we want to change the behavior later, be can use __getattr__ or a descriptor; (the list is modified in place anyway, so there'd be not much to change about get_children) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3038 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 19 +++++++------------ docutils/parsers/rst/directives/html.py | 2 +- docutils/parsers/rst/directives/images.py | 2 +- docutils/parsers/rst/directives/misc.py | 4 ++-- docutils/parsers/rst/directives/tables.py | 2 +- docutils/parsers/rst/states.py | 2 +- docutils/readers/python/__init__.py | 2 +- docutils/transforms/frontmatter.py | 8 ++++---- docutils/transforms/parts.py | 2 +- docutils/transforms/references.py | 2 +- docutils/writers/html4css1.py | 2 +- 11 files changed, 21 insertions(+), 26 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index d384bfe92..5c8e7be50 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -119,7 +119,7 @@ class Node: return except SkipDeparture: # not applicable; ignore pass - children = self.get_children() + children = self.children try: for child in children[:]: child.walk(visitor) @@ -147,7 +147,7 @@ class Node: return except SkipDeparture: call_depart = 0 - children = self.get_children() + children = self.children try: for child in children[:]: child.walkabout(visitor) @@ -172,7 +172,7 @@ class Node: """ node = self while 1: - if descend and node.get_children(): + if descend and node.children: r = node[0] elif node.parent is not None: # Index of the next sibling. @@ -215,7 +215,7 @@ class Node: be changed to an iterator later. """ nodelist = [self] - for node in self.get_children(): + for node in self.children: nodelist.extend(node.flattened()) return nodelist @@ -230,6 +230,9 @@ class Text(Node, UserString): tagname = '#text' + children = [] + """Text nodes have no children.""" + def __init__(self, data, rawsource=''): UserString.__init__(self, data) @@ -267,10 +270,6 @@ class Text(Node, UserString): result.append(indent + line + '\n') return ''.join(result) - def get_children(self): - """Text nodes have no children. Return [].""" - return [] - class Element(Node): @@ -557,10 +556,6 @@ class Element(Node): [child.pformat(indent, level+1) for child in self.children]) - def get_children(self): - """Return this element's children.""" - return self.children - def copy(self): return self.__class__(**self.attributes) diff --git a/docutils/parsers/rst/directives/html.py b/docutils/parsers/rst/directives/html.py index a6e656994..86e19dcfc 100644 --- a/docutils/parsers/rst/directives/html.py +++ b/docutils/parsers/rst/directives/html.py @@ -34,7 +34,7 @@ def meta(name, arguments, options, content, lineno, 'Empty meta directive.', nodes.literal_block(block_text, block_text), line=lineno) node += error - return node.get_children() + return node.children meta.content = 1 diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index e47315576..32120cde8 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -92,7 +92,7 @@ def figure(name, arguments, options, content, lineno, first_node = node[0] if isinstance(first_node, nodes.paragraph): caption = nodes.caption(first_node.rawsource, '', - *first_node.get_children()) + *first_node.children) figure_node += caption elif not (isinstance(first_node, nodes.comment) and len(first_node) == 0): diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index c88ed0922..c5d26b3f1 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -185,7 +185,7 @@ def replace(name, arguments, options, content, lineno, messages.append(error) return messages else: - return element[0].get_children() + return element[0].children else: error = state_machine.reporter.error( 'The "%s" directive is empty; content required.' % (name), @@ -229,7 +229,7 @@ def unicode_directive(name, arguments, options, content, lineno, nodes.literal_block(block_text, block_text), line=lineno) return [error] element += nodes.Text(decoded) - return element.get_children() + return element.children unicode_directive.arguments = (1, 0, 1) unicode_directive.options = {'trim': directives.flag, diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 653499c20..6940bc72f 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -327,7 +327,7 @@ def list_table(name, arguments, options, content, lineno, try: num_cols, col_widths = check_list_content( node, name, options, content, lineno, block_text, state_machine) - table_data = [[item.get_children() for item in row_list[0]] + table_data = [[item.children for item in row_list[0]] for row_list in node[0]] header_rows = options.get('header-rows', 0) # default 0 check_table_dimensions( diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index b9d257924..04713fbdc 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -2614,7 +2614,7 @@ class Text(RSTState): state_machine_kwargs={'state_classes': (QuotedLiteralBlock,), 'initial_state': 'QuotedLiteralBlock'}) self.goto_line(new_abs_offset) - return parent_node.get_children() + return parent_node.children def definition_list_item(self, termline): indented, indent, line_offset, blank_finish = \ diff --git a/docutils/readers/python/__init__.py b/docutils/readers/python/__init__.py index 22cfe3b8d..ba147a3d5 100644 --- a/docutils/readers/python/__init__.py +++ b/docutils/readers/python/__init__.py @@ -88,7 +88,7 @@ class DocstringFormattingVisitor(nodes.SparseNodeVisitor): node['docformat'] = docformat parser = self.get_parser(docformat) parser.parse(text, self.document) - for child in self.document.get_children(): + for child in self.document.children: node.append(child) self.document.current_source = self.document.current_line = None del self.document[:] diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index 979ad1d65..1a45c1336 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -294,9 +294,9 @@ class DocInfo(Transform): raise TransformError title = nodes.title(name, labels[canonical]) topics[canonical] = biblioclass( - '', title, CLASS=canonical, *field[1].get_children()) + '', title, CLASS=canonical, *field[1].children) else: - docinfo.append(biblioclass('', *field[1].get_children())) + docinfo.append(biblioclass('', *field[1].children)) except TransformError: if len(field[-1]) == 1 \ and isinstance(field[-1][0], nodes.paragraph): @@ -386,7 +386,7 @@ class DocInfo(Transform): for item in field[1][0]: if len(item) != 1 or not isinstance(item[0], nodes.paragraph): raise TransformError - authors.append(item[0].get_children()) + authors.append(item[0].children) if not authors: raise TransformError return authors @@ -395,5 +395,5 @@ class DocInfo(Transform): for item in field[1]: if not isinstance(item, nodes.paragraph): raise TransformError - authors = [item.get_children() for item in field[1]] + authors = [item.children for item in field[1]] return authors diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index c9c0722ce..c26227664 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -151,7 +151,7 @@ class Contents(Transform): class ContentsFilter(nodes.TreeCopyVisitor): def get_entry_text(self): - return self.get_tree_copy().get_children() + return self.get_tree_copy().children def visit_citation_reference(self, node): raise nodes.SkipNode diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 6290c5153..2e3828910 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -749,7 +749,7 @@ class Substitutions(Transform): and isinstance(parent[index + 1], nodes.Text)): parent.replace(parent[index + 1], parent[index + 1].lstrip()) - parent.replace(ref, subdef.get_children()) + parent.replace(ref, subdef.children) self.document.substitution_refs = None # release replaced references diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index cd28ffa15..db3c15670 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -1366,7 +1366,7 @@ class SimpleListChecker(nodes.GenericNodeVisitor): def visit_list_item(self, node): children = [] - for child in node.get_children(): + for child in node.children: if not isinstance(child, nodes.Invisible): children.append(child) if (children and isinstance(children[0], nodes.paragraph) -- cgit v1.2.1 From 4c757af54eabf7f37b89dcc53813b2d9da223e15 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 14 Mar 2005 16:45:09 +0000 Subject: re-added --no-random option of PEP writer for testing git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3039 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/pep_html.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index 9305e6062..ebeef12e3 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -11,7 +11,6 @@ PEP HTML Writer. __docformat__ = 'reStructuredText' -import random import sys import docutils from docutils import frontend, nodes, utils @@ -32,7 +31,11 @@ class Writer(html4css1.Writer): {'default': '..', 'metavar': ''}), ('Home URL prefix for PEPs. Default is "." (current directory).', ['--pep-home'], - {'default': '.', 'metavar': ''}),)) + {'default': '.', 'metavar': ''}), + # For testing. + (frontend.SUPPRESS_HELP, + ['--no-random'], + {'action': 'store_true', 'validator': frontend.validate_boolean}),)) settings_default_overrides = {'footnote_references': 'brackets'} @@ -66,7 +69,11 @@ class Writer(html4css1.Writer): header = self.document[index] pepnum = header[0][1].astext() subs['pep'] = pepnum - subs['banner'] = random.randrange(64) + if settings.no_random: + subs['banner'] = 0 + else: + import random + subs['banner'] = random.randrange(64) try: subs['pepnum'] = '%04i' % int(pepnum) except ValueError: -- cgit v1.2.1 From 4bb19b11c8d5f0860a6b0409b41b6ca1d50031a4 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 14 Mar 2005 18:29:50 +0000 Subject: removed unnecessary "footnote-references: brackets" default git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3043 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/pep_html.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index ebeef12e3..a8c74bbc7 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -21,8 +21,7 @@ class Writer(html4css1.Writer): settings_spec = html4css1.Writer.settings_spec + ( 'PEP/HTML-Specific Options', - """The HTML --footnote-references option's default is set to """ - '"brackets".', + None, (('Specify a template file. Default is "pep-html-template".', ['--template'], {'default': 'pep-html-template', 'metavar': ''}), @@ -37,8 +36,6 @@ class Writer(html4css1.Writer): ['--no-random'], {'action': 'store_true', 'validator': frontend.validate_boolean}),)) - settings_default_overrides = {'footnote_references': 'brackets'} - relative_path_settings = (html4css1.Writer.relative_path_settings + ('template',)) -- cgit v1.2.1 From 2913454311795655ccd224ad249d5ff6a30301c6 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 15 Mar 2005 00:33:59 +0000 Subject: Added "uri" directive option conversion function. Added docstrings & documentation. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3045 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 44 +++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 4d45d72be..b8207599f 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -251,8 +251,7 @@ def path(argument): Return the path argument unwrapped (with newlines removed). (Directive option conversion function.) - Raise ``ValueError`` if no argument is found or if the path contains - internal whitespace. + Raise ``ValueError`` if no argument is found. """ if argument is None: raise ValueError('argument required but none supplied') @@ -260,6 +259,19 @@ def path(argument): path = ''.join([s.strip() for s in argument.splitlines()]) return path +def uri(argument): + """ + Return the URI argument with whitespace removed. + (Directive option conversion function.) + + Raise ``ValueError`` if no argument is found. + """ + if argument is None: + raise ValueError('argument required but none supplied') + else: + uri = ''.join(argument.split()) + return uri + def nonnegative_int(argument): """ Check for a nonnegative integer argument; raise ``ValueError`` if not. @@ -294,10 +306,13 @@ unicode_pattern = re.compile( def unicode_code(code): r""" Convert a Unicode character code to a Unicode character. + (Directive option conversion function.) Codes may be decimal numbers, hexadecimal numbers (prefixed by ``0x``, ``x``, ``\x``, ``U+``, ``u``, or ``\u``; e.g. ``U+262E``), or XML-style numeric character entities (e.g. ``☮``). Other text remains as-is. + + Raise ValueError for illegal Unicode code values. """ try: if code.isdigit(): # decimal number @@ -313,6 +328,10 @@ def unicode_code(code): raise ValueError('code too large (%s)' % detail) def single_char_or_unicode(argument): + """ + A single character is returned as-is. Unicode characters codes are + converted as in `unicode_code`. (Directive option conversion function.) + """ char = unicode_code(argument) if len(char) > 1: raise ValueError('%r invalid; must be a single character or ' @@ -320,6 +339,10 @@ def single_char_or_unicode(argument): return char def single_char_or_whitespace_or_unicode(argument): + """ + As with `single_char_or_unicode`, but "tab" and "space" are also supported. + (Directive option conversion function.) + """ if argument == 'tab': char = '\t' elif argument == 'space': @@ -329,12 +352,23 @@ def single_char_or_whitespace_or_unicode(argument): return char def positive_int(argument): + """ + Converts the argument into an integer. Raises ValueError for negative, + zero, or non-integer values. (Directive option conversion function.) + """ value = int(argument) if value < 1: raise ValueError('negative or zero value; must be positive') return value def positive_int_list(argument): + """ + Converts a space- or comma-separated list of values into a Python list + of integers. + (Directive option conversion function.) + + Raises ValueError for non-positive-integer values. + """ if ',' in argument: entries = argument.split(',') else: @@ -342,6 +376,12 @@ def positive_int_list(argument): return [positive_int(entry) for entry in entries] def encoding(argument): + """ + Verfies the encoding argument by lookup. + (Directive option conversion function.) + + Raises ValueError for unknown encodings. + """ try: codecs.lookup(argument) except LookupError: -- cgit v1.2.1 From 0a938a279683da492acd6512d0af6fa636c5a51c Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 15 Mar 2005 00:37:51 +0000 Subject: differentiate between paths and URIs git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3046 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/images.py | 2 +- docutils/parsers/rst/directives/misc.py | 4 ++-- docutils/parsers/rst/directives/tables.py | 2 +- docutils/parsers/rst/states.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index 32120cde8..765c14d61 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -29,7 +29,7 @@ def align(argument): def image(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): messages = [] - reference = ''.join(arguments[0].split('\n')) + reference = directives.uri(arguments[0]) options['uri'] = reference reference_node = None if options.has_key('target'): diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index c5d26b3f1..1ea4699f3 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -27,7 +27,7 @@ def include(name, arguments, options, content, lineno, source = state_machine.input_lines.source( lineno - state_machine.input_offset - 1) source_dir = os.path.dirname(os.path.abspath(source)) - path = ''.join(arguments[0].splitlines()) + path = directives.path(arguments[0]) 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) @@ -156,7 +156,7 @@ def raw(name, arguments, options, content, lineno, raw.arguments = (1, 0, 1) raw.options = {'file': directives.path, - 'url': directives.path, + 'url': directives.uri, 'encoding': directives.encoding} raw.content = 1 diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 6940bc72f..116a2759f 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -152,7 +152,7 @@ csv_table.options = {'header-rows': directives.nonnegative_int, 'header': directives.unchanged, 'widths': directives.positive_int_list, 'file': directives.path, - 'url': directives.path, + 'url': directives.uri, 'encoding': directives.encoding, 'class': directives.class_option, # field delimiter char diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 04713fbdc..628a1b02c 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1822,7 +1822,7 @@ class Body(RSTState): refname = self.is_reference(reference) if refname: return 'refname', refname - reference = ''.join([line.strip() for line in block]) + reference = ''.join([''.join(line.split()) for line in block]) return 'refuri', unescape(reference) def is_reference(self, reference): -- cgit v1.2.1 From 94ef88a19b8d2aae3b4c089d921b604c177f633c Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 15 Mar 2005 15:23:52 +0000 Subject: removed Node.flattened(); added Node.traverse(); implemented Node.next_node() using Node.traverse() git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3048 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 108 ++++++++++++++++++++++---------------- docutils/transforms/parts.py | 5 +- docutils/transforms/references.py | 2 +- 3 files changed, 67 insertions(+), 48 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 5c8e7be50..611857ee2 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -21,6 +21,8 @@ hierarchy. .. _DTD: http://docutils.sourceforge.net/docs/ref/docutils.dtd """ +from __future__ import generators + __docformat__ = 'reStructuredText' import sys @@ -161,65 +163,83 @@ class Node: category='nodes.Node.walkabout') visitor.dispatch_departure(self) - def next_node(self, descend=1, ascend=1, condition=None): - """ - Return the next node in tree traversal order for which - ``condition(node)`` is true. - - If descend is true, traverse children as well. If ascend is - true, go up in the tree if there is no direct next sibling. - Return None if there is no next 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). """ - node = self - while 1: - if descend and node.children: - r = node[0] - elif node.parent is not None: - # Index of the next sibling. - index = node.parent.index(node) + 1 - if index < len(node.parent): - r = node.parent[index] - elif ascend: - r = node.parent.next_node(descend=0, ascend=1) - else: - return None - else: - return None - if not condition or condition(r): - return r - else: - # Get r.next_node(...), avoiding recursion. - node = r + Return an iterator 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 + also descend is true) + * the siblings of the parent (if ascend is true) and their + descendants (if also descend is true), and so on - def flattened(self): - """ - Return a flattened representation of the (sub)tree rooted at this - node -- an iterable of nodes in tree traversal order. + If ascend is true, assume siblings to be true as well. - Given the a paragraph node with the following tree:: + For example, given the following tree:: - - + <--- emphasis.traverse() and + <--- strong.traverse() are called. Foo Bar Baz - Then paragraph.flattened() is:: + Then list(emphasis.traverse()) equals :: + + [, , <#text: Foo>, <#text: Bar>] - [, , , , , - , ] + and list(strong.traverse(ascend=1)) equals :: - You should not rely on the return value to be a list; it could - be changed to an iterator later. + [, <#text: Foo>, <#text: Bar>, , <#text: Baz>] """ - nodelist = [self] - for node in self.children: - nodelist.extend(node.flattened()) - return nodelist + if ascend: + siblings=1 + if include_self and (condition is None or condition(self)): + yield self + if descend and len(self.children): + for child in self: + for n in child.traverse( + include_self=1, descend=1, siblings=0, ascend=0, + condition=condition): + yield n + if siblings or ascend: + node = self + while node.parent: + index = node.parent.index(node) + for sibling in node.parent[index+1:]: + for n in sibling.traverse(include_self=1, descend=descend, + siblings=0, ascend=0, + condition=condition): + yield n + if not ascend: + break + else: + node = node.parent + def next_node(self, condition=None, + include_self=0, descend=1, siblings=0, ascend=0): + """ + Return the first node in the iterator returned by traverse(), + or None if the iterator is empty. + + Parameter list is the same as of traverse. Note that + include_self defaults to 0, though. + """ + iterator = self.traverse(condition=condition, + include_self=include_self, descend=descend, + siblings=siblings, ascend=ascend) + try: + return iterator.next() + except StopIteration: + return None + class Text(Node, UserString): """ diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index c26227664..d0537d5aa 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -122,9 +122,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 - not [node for node in title.flattened() - if isinstance(node, nodes.reference)]): + if (self.backlinks in ('entry', 'top') and title.next_node( + lambda n: isinstance(n, nodes.reference)) is None): if self.backlinks == 'entry': title['refid'] = ref_id elif self.backlinks == 'top': diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 2e3828910..428dad890 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -34,7 +34,7 @@ class SectionTargets(Transform): """Move "target" elements into the next title element if necessary.""" assert isinstance(target, nodes.target) # Find next node which is not a target. - n = target.next_node(condition=self.possible_relocation_target) + n = target.next_node(self.possible_relocation_target, ascend=1) if isinstance(n, nodes.section): assert isinstance(n[0], nodes.title) target.parent.remove(target) -- cgit v1.2.1 From cfa0e2ad0c742f615f6d7bbcb871525cccca0bfa Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 15 Mar 2005 15:30:36 +0000 Subject: made Node.traverse() and Node.next_node() Python 2.1 compatible git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3049 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 611857ee2..188c0d930 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -21,8 +21,6 @@ hierarchy. .. _DTD: http://docutils.sourceforge.net/docs/ref/docutils.dtd """ -from __future__ import generators - __docformat__ = 'reStructuredText' import sys @@ -169,7 +167,7 @@ class Node: # list for next_node (for which it's convenient to have # condition as first parameter). """ - Return an iterator containing + Return an iterable containing * self (if include_self is true) * all descendants in tree traversal order (if descend is true) @@ -198,46 +196,46 @@ class Node: [, <#text: Foo>, <#text: Bar>, , <#text: Baz>] """ + r = [] if ascend: siblings=1 if include_self and (condition is None or condition(self)): - yield self + r.append(self) if descend and len(self.children): for child in self: - for n in child.traverse( + r.extend(child.traverse( include_self=1, descend=1, siblings=0, ascend=0, - condition=condition): - yield n + condition=condition)) if siblings or ascend: node = self while node.parent: index = node.parent.index(node) for sibling in node.parent[index+1:]: - for n in sibling.traverse(include_self=1, descend=descend, + r.extend(sibling.traverse(include_self=1, descend=descend, siblings=0, ascend=0, - condition=condition): - yield n + condition=condition)) if not ascend: break else: node = node.parent + return r def next_node(self, condition=None, include_self=0, descend=1, siblings=0, ascend=0): """ - Return the first node in the iterator returned by traverse(), - or None if the iterator is empty. + Return the first node in the iterable returned by traverse(), + or None if the iterable is empty. Parameter list is the same as of traverse. Note that include_self defaults to 0, though. """ - iterator = self.traverse(condition=condition, + iterable = self.traverse(condition=condition, include_self=include_self, descend=descend, siblings=siblings, ascend=ascend) try: - return iterator.next() - except StopIteration: + return iterable[0] + except IndexError: return None class Text(Node, UserString): -- cgit v1.2.1 From abb20e7fa0f5cc85164b9cd97d00493aacae213b Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 18 Mar 2005 14:05:05 +0000 Subject: added Dutch translations; thanks to Martijn Pieters git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3056 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/nl.py | 62 +++++++++++++++++++++ docutils/parsers/rst/languages/nl.py | 105 +++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 docutils/languages/nl.py create mode 100644 docutils/parsers/rst/languages/nl.py (limited to 'docutils') diff --git a/docutils/languages/nl.py b/docutils/languages/nl.py new file mode 100644 index 000000000..d89d3f0c6 --- /dev/null +++ b/docutils/languages/nl.py @@ -0,0 +1,62 @@ +# Author: Martijn Pieters +# Contact: mjpieters@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. + +""" +Dutch-language mappings for language-dependent features of Docutils. +""" + +__docformat__ = 'reStructuredText' + +labels = { + # fixed: language-dependent + 'author': 'Auteur', + 'authors': 'Auteurs', + 'organization': 'Organisatie', + 'address': 'Adres', + 'contact': 'Contact', + 'version': 'Versie', + 'revision': 'Revisie', + 'status': 'Status', + 'date': 'Datum', + 'copyright': 'Copyright', + 'dedication': 'Toewijding', + 'abstract': 'Samenvatting', + 'attention': 'Attentie!', + 'caution': 'Waarschuwing!', + 'danger': '!GEVAAR!', + 'error': 'Fout', + 'hint': 'Hint', + 'important': 'Belangrijk', + 'note': 'Opmerking', + 'tip': 'Tip', + 'warning': 'Waarschuwing', + 'contents': 'Inhoud'} +"""Mapping of node class name to label text.""" + +bibliographic_fields = { + # language-dependent: fixed + 'auteur': 'author', + 'auteurs': 'authors', + 'organisatie': 'organization', + 'adres': 'address', + 'contact': 'contact', + 'versie': 'version', + 'revisie': 'revision', + 'status': 'status', + 'datum': 'date', + 'copyright': 'copyright', + 'toewijding': 'dedication', + 'samenvatting': 'abstract'} +"""Dutch (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/nl.py b/docutils/parsers/rst/languages/nl.py new file mode 100644 index 000000000..6840137df --- /dev/null +++ b/docutils/parsers/rst/languages/nl.py @@ -0,0 +1,105 @@ +# Author: Martijn Pieters +# Contact: mjpieters@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. + +""" +Dutch-language mappings for language-dependent features of +reStructuredText. +""" + +__docformat__ = 'reStructuredText' + + +directives = { + # language-dependent: fixed + 'attentie': 'attention', + 'waarschuwing': 'caution', + 'gevaar': 'danger', + 'fout': 'error', + 'hint': 'hint', + 'belangrijk': 'important', + 'opmerking': 'note', + 'tip': 'tip', + 'waarschuwing': 'warning', + 'aanmaning': 'admonition', + 'katern': 'sidebar', + 'onderwerp': 'topic', + 'lijn-blok': 'lijn-blok', + 'letterlijk-ontleed': 'parsed-literal', + 'rubriek': 'rubric', + 'opschrift': 'epigraph', + 'hoogtepunten': 'highlights', + 'pull-quote': 'pull-quote', # Dutch printers use the english term + 'samenstelling': 'compound', + 'verbinding': 'compound', + #'vragen': 'questions', + 'tabel': 'table', + 'csv-tabel': 'csv-table', + #'veelgestelde-vragen': 'questions', + 'meta': 'meta', + #'imagemap': 'imagemap', + 'beeld': 'image', + 'figuur': 'figure', + 'opnemen': 'include', + 'onbewerkt': 'raw', + 'letterlijk': 'raw', + 'vervang': 'replace', + 'vervanging': 'replace', + 'unicode': 'unicode', + 'klasse': 'class', + 'rol': 'role', + 'inhoud': 'contents', + 'sectnum': 'sectnum', + 'sectie-nummering': 'sectnum', + 'hoofdstuk-nummering': 'sectnum', + #'voetnoten': 'footnotes', + #'citaten': 'citations', + 'verwijzing-voetnoten': 'target-notes', + 'restructuredtext-test-instructie': 'restructuredtext-test-directive'} +"""Dutch name to registered (in directives/__init__.py) directive name +mapping.""" + +roles = { + # language-dependent: fixed + 'afkorting': 'abbreviation', + # 'ab': 'abbreviation', + 'acroniem': 'acronym', + 'ac': 'acronym', + 'index': 'index', + 'i': 'index', + 'inferieur': 'subscript', + 'inf': 'subscript', + 'superieur': 'superscript', + 'sup': 'superscript', + 'titel-referentie': 'title-reference', + 'titel': 'title-reference', + 't': 'title-reference', + 'pep-referentie': 'pep-reference', + 'pep': 'pep-reference', + 'rfc-referentie': 'rfc-reference', + 'rfc': 'rfc-reference', + 'nadruk': 'emphasis', + 'extra': 'strong', + 'extra-nadruk': 'strong', + 'vet': 'strong', + 'letterlijk': 'literal', + 'benoemde-referentie': 'named-reference', + 'anonieme-referentie': 'anonymous-reference', + 'voetnoot-referentie': 'footnote-reference', + 'citaat-referentie': 'citation-reference', + 'substitie-reference': 'substitution-reference', + 'verwijzing': 'target', + 'uri-referentie': 'uri-reference', + 'uri': 'uri-reference', + 'url': 'uri-reference', + 'letterlijk': 'raw', + 'onbewerkt': 'raw',} +"""Mapping of Dutch role names to canonical role names for interpreted text. +""" -- cgit v1.2.1 From c664df1b6f35351fb2d171c969b2ea433fe5e013 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 18 Mar 2005 20:09:22 +0000 Subject: applied some corrections for Dutch translations git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3058 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/nl.py | 2 +- docutils/parsers/rst/languages/nl.py | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/languages/nl.py b/docutils/languages/nl.py index d89d3f0c6..ca96d78d9 100644 --- a/docutils/languages/nl.py +++ b/docutils/languages/nl.py @@ -30,7 +30,7 @@ labels = { 'dedication': 'Toewijding', 'abstract': 'Samenvatting', 'attention': 'Attentie!', - 'caution': 'Waarschuwing!', + 'caution': 'Let op!', 'danger': '!GEVAAR!', 'error': 'Fout', 'hint': 'Hint', diff --git a/docutils/parsers/rst/languages/nl.py b/docutils/parsers/rst/languages/nl.py index 6840137df..fa6a1324a 100644 --- a/docutils/parsers/rst/languages/nl.py +++ b/docutils/parsers/rst/languages/nl.py @@ -20,7 +20,7 @@ __docformat__ = 'reStructuredText' directives = { # language-dependent: fixed 'attentie': 'attention', - 'waarschuwing': 'caution', + 'let-op': 'caution', 'gevaar': 'danger', 'fout': 'error', 'hint': 'hint', @@ -31,7 +31,7 @@ directives = { 'aanmaning': 'admonition', 'katern': 'sidebar', 'onderwerp': 'topic', - 'lijn-blok': 'lijn-blok', + 'lijn-blok': 'line-block', 'letterlijk-ontleed': 'parsed-literal', 'rubriek': 'rubric', 'opschrift': 'epigraph', @@ -42,6 +42,7 @@ directives = { #'vragen': 'questions', 'tabel': 'table', 'csv-tabel': 'csv-table', + 'lijst-tabel': 'list-table', #'veelgestelde-vragen': 'questions', 'meta': 'meta', #'imagemap': 'imagemap', @@ -49,7 +50,6 @@ directives = { 'figuur': 'figure', 'opnemen': 'include', 'onbewerkt': 'raw', - 'letterlijk': 'raw', 'vervang': 'replace', 'vervanging': 'replace', 'unicode': 'unicode', @@ -99,7 +99,6 @@ roles = { 'uri-referentie': 'uri-reference', 'uri': 'uri-reference', 'url': 'uri-reference', - 'letterlijk': 'raw', 'onbewerkt': 'raw',} """Mapping of Dutch role names to canonical role names for interpreted text. """ -- cgit v1.2.1 From f6786093e21666775cc85231c802ca3e80436560 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 20 Mar 2005 22:03:30 +0000 Subject: removed unneeded global variable git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3064 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 3 --- 1 file changed, 3 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 428dad890..e2196452c 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -16,9 +16,6 @@ from docutils import nodes, utils from docutils.transforms import TransformError, Transform -indices = xrange(sys.maxint) - - class SectionTargets(Transform): default_priority = 260 -- cgit v1.2.1 From b300c43b3d7ce16e8ce2a4caad57aa3ccebd9c53 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 20 Mar 2005 22:46:36 +0000 Subject: never discard messages git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3065 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 188c0d930..696363eef 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -803,9 +803,7 @@ class document(Root, Structural, Element): 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 += msg + msgnode += self.reporter.severe('Duplicate ID: "%s".' % id) else: if node.has_key('name'): id = make_id(node['name']) @@ -875,11 +873,9 @@ class document(Root, Structural, Element): if level > 1: dupname(old_node) self.nameids[name] = None - msg = self.reporter.system_message( + msgnode += self.reporter.system_message( level, 'Duplicate explicit target name: "%s".' % name, backrefs=[id], base_node=node) - if msgnode != None: - msgnode += msg dupname(node) else: self.nameids[name] = id @@ -893,11 +889,9 @@ class document(Root, Structural, Element): dupname(old_node) dupname(node) if not explicit or (not old_explicit and old_id is not None): - msg = self.reporter.info( + msgnode += self.reporter.info( 'Duplicate implicit target name: "%s".' % name, backrefs=[id], base_node=node) - if msgnode != None: - msgnode += msg def has_name(self, name): return self.nameids.has_key(name) @@ -971,11 +965,9 @@ class document(Root, Structural, Element): def note_substitution_def(self, subdef, def_name, msgnode=None): name = subdef['name'] = whitespace_normalize_name(def_name) if self.substitution_defs.has_key(name): - msg = self.reporter.error( + msgnode += self.reporter.error( 'Duplicate substitution definition name: "%s".' % name, base_node=subdef) - if msgnode != None: - msgnode += msg oldnode = self.substitution_defs[name] dupname(oldnode) # keep only the last definition: -- cgit v1.2.1 From 4549c639e71638c10f48ecf3dd547375d7235cac Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 21 Mar 2005 17:33:42 +0000 Subject: whitespace git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3066 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py index 94b06be5c..5a372f202 100644 --- a/docutils/transforms/__init__.py +++ b/docutils/transforms/__init__.py @@ -59,7 +59,7 @@ class Transform: self.language = languages.get_language( document.settings.language_code) """Language module local to this document.""" - + def apply(self): """Override to apply the transform to the document tree.""" @@ -164,7 +164,6 @@ class Transformer(TransformSpec): decorated_list.sort() self.unknown_reference_resolvers.extend([f[1] for f in decorated_list]) - def apply_transforms(self): """Apply all of the stored transforms, in priority order.""" self.document.reporter.attach_observer( -- cgit v1.2.1 From 535bdf0897686ed255e5ed8b26c3ad40a166036f Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 21 Mar 2005 19:29:04 +0000 Subject: I don't think nodes.Text should have a children attribute at all, but if it does, it shouldn't be mutable. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3068 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 696363eef..d68036f0a 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -248,8 +248,8 @@ class Text(Node, UserString): tagname = '#text' - children = [] - """Text nodes have no children.""" + children = () + """Text nodes have no children, and cannot have children.""" def __init__(self, data, rawsource=''): UserString.__init__(self, data) -- cgit v1.2.1 From 9532f3f6180c5da889812932d06d1ef3380d63a0 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 21 Mar 2005 20:34:17 +0000 Subject: reverted rev. 1.90; may have introduced bugs git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3069 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index d68036f0a..1ff84de1f 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -803,7 +803,9 @@ class document(Root, Structural, Element): if node.has_key('id'): id = node['id'] if self.ids.has_key(id) and self.ids[id] is not node: - msgnode += self.reporter.severe('Duplicate ID: "%s".' % id) + msg = self.reporter.severe('Duplicate ID: "%s".' % id) + if msgnode != None: + msgnode += msg else: if node.has_key('name'): id = make_id(node['name']) @@ -873,9 +875,11 @@ class document(Root, Structural, Element): if level > 1: dupname(old_node) self.nameids[name] = None - msgnode += self.reporter.system_message( + msg = self.reporter.system_message( level, 'Duplicate explicit target name: "%s".' % name, backrefs=[id], base_node=node) + if msgnode != None: + msgnode += msg dupname(node) else: self.nameids[name] = id @@ -889,9 +893,11 @@ class document(Root, Structural, Element): dupname(old_node) dupname(node) if not explicit or (not old_explicit and old_id is not None): - msgnode += self.reporter.info( + msg = self.reporter.info( 'Duplicate implicit target name: "%s".' % name, backrefs=[id], base_node=node) + if msgnode != None: + msgnode += msg def has_name(self, name): return self.nameids.has_key(name) @@ -965,9 +971,11 @@ class document(Root, Structural, Element): def note_substitution_def(self, subdef, def_name, msgnode=None): name = subdef['name'] = whitespace_normalize_name(def_name) if self.substitution_defs.has_key(name): - msgnode += self.reporter.error( + msg = self.reporter.error( 'Duplicate substitution definition name: "%s".' % name, base_node=subdef) + if msgnode != None: + msgnode += msg oldnode = self.substitution_defs[name] dupname(oldnode) # keep only the last definition: -- cgit v1.2.1 From 0da2794fd20b8ee19544b81a4deb0f0e8ef6ca8c Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 21 Mar 2005 21:19:34 +0000 Subject: line length git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3070 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index db3c15670..c0938c590 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -892,7 +892,8 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_literal(self, node): """Process text to prevent tokens from wrapping.""" - self.body.append(self.starttag(node, 'tt', '', CLASS='docutils literal')) + 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(): @@ -955,7 +956,8 @@ class HTMLTranslator(nodes.NodeVisitor): self.context.append('\n ') else: self.context.append('') - self.body.append(self.starttag(node, 'td', CLASS='option-group', **atts)) + self.body.append( + self.starttag(node, 'td', CLASS='option-group', **atts)) self.body.append('') self.context.append(0) # count number of options -- cgit v1.2.1 From d06b559d1082b9881e16d0278a65aca3b42ec5e2 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 21 Mar 2005 21:26:21 +0000 Subject: Added settings: ``file_insertion_enabled`` & ``raw_enabled``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3071 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/__init__.py | 18 +++++++++++++++++- docutils/parsers/rst/directives/misc.py | 12 ++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/__init__.py b/docutils/parsers/rst/__init__.py index 88795a830..8d7935be6 100644 --- a/docutils/parsers/rst/__init__.py +++ b/docutils/parsers/rst/__init__.py @@ -112,7 +112,23 @@ class Parser(docutils.parsers.Parser): ('Leave spaces before footnote references.', ['--leave-footnote-reference-space'], {'action': 'store_false', 'dest': 'trim_footnote_reference_space', - 'validator': frontend.validate_boolean}),)) + 'validator': frontend.validate_boolean}), + ('Disable directives that insert the contents of external file ' + '("include" & "raw"); replaced with a "warning" system message.', + ['--no-file-insertion'], + {'action': 'store_false', 'default': 1, + 'dest': 'file_insertion_enabled'}), + ('Enable directives that insert the contents of external file ' + '("include" & "raw"). Enabled by default.', + ['--file-insertion-enabled'], + {'action': 'store_true', 'dest': 'file_insertion_enabled'}), + ('Disable the "raw" directives; replaced with a "warning" ' + 'system message.', + ['--no-raw'], + {'action': 'store_false', 'default': 1, 'dest': 'raw_enabled'}), + ('Enable the "raw" directive. Enabled by default.', + ['--raw-enabled'], + {'action': 'store_true', 'dest': 'raw_enabled'}),)) config_section = 'restructuredtext parser' config_section_dependencies = ('parsers',) diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 1ea4699f3..1a6cbc17c 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -24,6 +24,11 @@ except ImportError: 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.""" + if not state.document.settings.file_insertion_enabled: + warning = state_machine.reporter.warning( + '"%s" directive disabled.' % name, + nodes.literal_block(block_text, block_text), line=lineno) + return [warning] source = state_machine.input_lines.source( lineno - state_machine.input_offset - 1) source_dir = os.path.dirname(os.path.abspath(source)) @@ -76,6 +81,13 @@ def raw(name, arguments, options, content, lineno, Content may be included inline (content section of directive) or imported from a file or url. """ + if ( not state.document.settings.raw_enabled + or (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) + return [warning] attributes = {'format': ' '.join(arguments[0].lower().split())} encoding = options.get('encoding', state.document.settings.input_encoding) if content: -- cgit v1.2.1 From b559771f98c67ca07b71c41dd947c2be6df75fee Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 22 Mar 2005 19:18:06 +0000 Subject: added csv-table directive support for the file_insertion_enabled setting git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3083 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 116a2759f..e47c9f9e4 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -115,6 +115,12 @@ if csv: def csv_table(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): try: + 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) + return [warning] check_requirements(name, lineno, block_text, state_machine) title, messages = make_title(arguments, state, lineno) csv_data, source = get_csv_data( @@ -205,7 +211,8 @@ def get_csv_data(name, options, content, lineno, block_text, state.document.settings.record_dependencies.add(source) csv_file = io.FileInput( source_path=source, encoding=encoding, - error_handler=state.document.settings.input_encoding_error_handler, + error_handler + =state.document.settings.input_encoding_error_handler, handle_io_errors=None) csv_data = csv_file.read().splitlines() except IOError, error: -- cgit v1.2.1 From 6adf9034472d079b9f0b9397a8c076e40b1f9ed9 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 24 Mar 2005 03:14:33 +0000 Subject: applied file_insertion_enabled setting to "figure" directive (disable "figwidth" option) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3106 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/images.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index 765c14d61..d6ac5a0c9 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -73,7 +73,7 @@ def figure(name, arguments, options, content, lineno, return [image_node] figure_node = nodes.figure('', image_node) if figwidth == 'image': - if Image: + if Image and state.document.settings.file_insertion_enabled: # PIL doesn't like Unicode paths: try: i = Image.open(str(image_node['uri'])) -- cgit v1.2.1 From 7d76b140ee974b59e35f1f044949dc032630e15f Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 25 Mar 2005 03:02:32 +0000 Subject: added auto-enumerated list items git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3113 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 59 ++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 19 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 628a1b02c..34c206ed2 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1036,7 +1036,7 @@ class Body(RSTState): 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) + '|%(upperroman)s|#)' % enum.sequencepats) pats['optname'] = '%(alphanum)s%(alphanumplus)s*' % pats # @@@ Loosen up the pattern? Allow Unicode? pats['optarg'] = '(%(alpha)s%(alphanumplus)s*|<[^<>]+>)' % pats @@ -1182,7 +1182,10 @@ class Body(RSTState): raise statemachine.TransitionCorrection('text') enumlist = nodes.enumerated_list() self.parent += enumlist - enumlist['enumtype'] = sequence + if sequence == '#': + enumlist['enumtype'] = 'arabic' + else: + enumlist['enumtype'] = sequence enumlist['prefix'] = self.enum.formatinfo[format].prefix enumlist['suffix'] = self.enum.formatinfo[format].suffix if ordinal != 1: @@ -1199,7 +1202,9 @@ class Body(RSTState): input_offset=self.state_machine.abs_line_offset() + 1, node=enumlist, initial_state='EnumeratedList', blank_finish=blank_finish, - extra_settings={'lastordinal': ordinal, 'format': format}) + extra_settings={'lastordinal': ordinal, + 'format': format, + 'auto': sequence == '#'}) self.goto_line(newline_offset) if not blank_finish: self.parent += self.unindent_warning('Enumerated list') @@ -1232,7 +1237,9 @@ class Body(RSTState): raise ParserError('enumerator format not matched') text = groupdict[format][self.enum.formatinfo[format].start :self.enum.formatinfo[format].end] - if expected_sequence: + if text == '#': + sequence = '#' + elif expected_sequence: try: if self.enum.sequenceregexps[expected_sequence].match(text): sequence = expected_sequence @@ -1249,10 +1256,13 @@ class Body(RSTState): break else: # shouldn't happen raise ParserError('enumerator sequence not matched') - try: - ordinal = self.enum.converters[sequence](text) - except roman.InvalidRomanNumeralError: - ordinal = None + if sequence == '#': + ordinal = 1 + else: + try: + ordinal = self.enum.converters[sequence](text) + except roman.InvalidRomanNumeralError: + ordinal = None return format, sequence, text, ordinal def is_enumerated_list_item(self, ordinal, sequence, format): @@ -1260,7 +1270,7 @@ class Body(RSTState): Check validity based on the ordinal value and the second line. Return true iff the ordinal is valid and the second line is blank, - indented, or starts with the next enumerator. + indented, or starts with the next enumerator or an auto-enumerator. """ if ordinal is None: return None @@ -1273,9 +1283,11 @@ class Body(RSTState): self.state_machine.previous_line() if not next_line[:1].strip(): # blank or indented return 1 - next_enumerator = self.make_enumerator(ordinal + 1, sequence, format) + next_enumerator, auto_enumerator = self.make_enumerator( + ordinal + 1, sequence, format) try: - if next_line.startswith(next_enumerator): + if ( next_line.startswith(next_enumerator) or + next_line.startswith(auto_enumerator) ): return 1 except TypeError: pass @@ -1283,11 +1295,14 @@ class Body(RSTState): def make_enumerator(self, ordinal, sequence, format): """ - Construct and return an enumerated list item marker. + Construct and return the next enumerated list item marker, and an + auto-enumerator ("#" instead of the regular enumerator). Return ``None`` for invalid (out of range) ordinals. - """ - if sequence == 'arabic': + """ #" + if sequence == '#': + enumerator = '#' + elif sequence == 'arabic': enumerator = str(ordinal) else: if sequence.endswith('alpha'): @@ -1310,7 +1325,10 @@ class Body(RSTState): raise ParserError('unknown enumerator sequence: "%s"' % sequence) formatinfo = self.enum.formatinfo[format] - return formatinfo.prefix + enumerator + formatinfo.suffix + ' ' + next_enumerator = (formatinfo.prefix + enumerator + formatinfo.suffix + + ' ') + auto_enumerator = formatinfo.prefix + '#' + formatinfo.suffix + ' ' + return next_enumerator, auto_enumerator def field_marker(self, match, context, next_state): """Field list item.""" @@ -2348,12 +2366,15 @@ class EnumeratedList(SpecializedBody): """Enumerated list item.""" format, sequence, text, ordinal = self.parse_enumerator( match, self.parent['enumtype']) - if (sequence != self.parent['enumtype'] or - format != self.format or - ordinal != (self.lastordinal + 1) or - not self.is_enumerated_list_item(ordinal, sequence, format)): + if ( format != self.format + or (sequence != '#' and (sequence != self.parent['enumtype'] + or self.auto + or ordinal != (self.lastordinal + 1))) + or not self.is_enumerated_list_item(ordinal, sequence, format)): # different enumeration: new list self.invalid_input() + if sequence == '#': + self.auto = 1 listitem, blank_finish = self.list_item(match.end()) self.parent += listitem self.blank_finish = blank_finish -- cgit v1.2.1 From 4df9fad485c1e12e850f9d7ff225d51c538af3dc Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 26 Mar 2005 01:04:09 +0000 Subject: fixed a bug that assumed text follows ".. _" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3119 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 34c206ed2..ddf47df7f 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -2146,13 +2146,13 @@ class Body(RSTState): re.compile(r""" \.\.[ ]+ # explicit markup start _ # target indicator - (?![ ]) # first char. not space + (?![ ]|$) # first char. not space or EOL """, re.VERBOSE)), (substitution_def, re.compile(r""" \.\.[ ]+ # explicit markup start \| # substitution indicator - (?![ ]) # first char. not space + (?![ ]|$) # first char. not space or EOL """, re.VERBOSE)), (directive, re.compile(r""" -- cgit v1.2.1 From 9dbc2adead008935245a396eab10bb7bcb11b226 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 26 Mar 2005 16:21:28 +0000 Subject: merged rev. 3094:3101 and 3102:HEAD from branches/multiple-ids to trunk git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3129 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 116 +++++--- docutils/parsers/rst/directives/images.py | 4 +- docutils/parsers/rst/directives/misc.py | 3 +- docutils/parsers/rst/directives/parts.py | 4 +- docutils/parsers/rst/roles.py | 18 +- docutils/parsers/rst/states.py | 19 +- docutils/readers/pep.py | 3 +- docutils/readers/standalone.py | 3 +- docutils/transforms/frontmatter.py | 10 +- docutils/transforms/parts.py | 6 +- docutils/transforms/peps.py | 12 +- docutils/transforms/references.py | 442 ++++++++++++++---------------- docutils/transforms/universal.py | 19 +- docutils/writers/html4css1.py | 89 +++--- docutils/writers/latex2e.py | 35 ++- docutils/writers/pep_html.py | 2 +- 16 files changed, 413 insertions(+), 372 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 1ff84de1f..2fb111427 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -27,6 +27,7 @@ import sys import os import re import xml.dom.minidom +from copy import deepcopy from types import IntType, SliceType, StringType, UnicodeType, \ TupleType, ListType from UserString import UserString @@ -326,6 +327,10 @@ class Element(Node): This is equivalent to ``element.extend([node1, node2])``. """ + attr_defaults = {'ids': [], 'classes': [], 'names': [], 'dupnames': []} + """Default attributes. ``attributes`` is initialized with a copy + of ``attr_defaults``.""" + tagname = None """The element generic identifier. If None, it is set as an instance attribute to the name of the class.""" @@ -342,7 +347,7 @@ class Element(Node): self.extend(children) # maintain parent info - self.attributes = {} + self.attributes = deepcopy(self.attr_defaults) """Dictionary of attribute {name: value}.""" for att, value in attributes.items(): @@ -353,7 +358,7 @@ class Element(Node): def _dom_node(self, domroot): element = domroot.createElement(self.tagname) - for attribute, value in self.attributes.items(): + for attribute, value in self.attlist(): if isinstance(value, ListType): value = ' '.join(['%s' % v for v in value]) element.setAttribute(attribute, '%s' % value) @@ -368,16 +373,16 @@ class Element(Node): if len(data) > 60: data = data[:56] + ' ...' break - if self.hasattr('name'): + if self['names']: return '<%s "%s": %s>' % (self.__class__.__name__, - self.attributes['name'], data) + '; '.join(self['names']), data) else: return '<%s: %s>' % (self.__class__.__name__, data) def shortrepr(self): - if self.hasattr('name'): + if self['names']: return '<%s "%s"...>' % (self.__class__.__name__, - self.attributes['name']) + '; '.join(self['names'])) else: return '<%s...>' % self.tagname @@ -472,8 +477,15 @@ class Element(Node): return self.child_text_separator.join( [child.astext() for child in self.children]) + def non_default_attributes(self): + atts = {} + for key, value in self.attributes.items(): + if self.is_not_default(key): + atts[key] = value + return atts + def attlist(self): - attlist = self.attributes.items() + attlist = self.non_default_attributes().items() attlist.sort() return attlist @@ -516,6 +528,12 @@ class Element(Node): def index(self, item): return self.children.index(item) + def is_not_default(self, key): + try: + return self[key] != self.attr_defaults[key] + except KeyError: + return 1 + def clear(self): self.children = [] @@ -579,8 +597,24 @@ class Element(Node): def set_class(self, name): """Add a new name to the "class" attribute.""" - self.attributes['class'] = (self.attributes.get('class', '') + ' ' - + name.lower()).strip() + 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`.""" + self.referenced = 1 + # Element.expect_referenced_by_* dictionaries map names or ids + # to nodes whose ``referenced`` attribute is set to true as + # soon as this node is referenced by the given name or id. + # Needed for target propagation. + by_name = getattr(self, 'expect_referenced_by_name', {}).get(name) + by_id = getattr(self, 'expect_referenced_by_id', {}).get(id) + if by_name: + assert name is not None + by_name.referenced = 1 + if by_id: + assert id is not None + by_id.referenced = 1 class TextElement(Element): @@ -630,8 +664,11 @@ class Resolvable: class BackLinkable: + attr_defaults = Element.attr_defaults.copy() + attr_defaults['backrefs'] = [] + def add_backref(self, refid): - self.setdefault('backrefs', []).append(refid) + self['backrefs'].append(refid) # ==================== @@ -678,9 +715,6 @@ class Targetable(Resolvable): referenced = 0 - indirect_reference_name = None - """Holds the whitespace_normalized_name (contains mixed case) of a target""" - class Labeled: """Contains a `label` as its first element.""" @@ -800,21 +834,22 @@ class document(Root, Structural, Element): return domroot def set_id(self, node, msgnode=None): - if node.has_key('id'): - id = node['id'] + for id in node['ids']: 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 += msg - else: - if node.has_key('name'): - id = make_id(node['name']) + if not node['ids']: + for name in node['names']: + id = 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 - self.id_start += 1 - node['id'] = id + while not id or self.ids.has_key(id): + id = 'id%s' % self.id_start + self.id_start += 1 + node['ids'].append(id) self.ids[id] = node return id @@ -849,8 +884,7 @@ class document(Root, Structural, Element): 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'] + for name in node['names']: if self.nameids.has_key(name): self.set_duplicate_name_id(node, id, name, msgnode, explicit) else: @@ -868,30 +902,30 @@ class document(Root, Structural, Element): old_node = self.ids[old_id] if node.has_key('refuri'): refuri = node['refuri'] - if old_node.has_key('name') \ + if old_node['names'] \ 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) + dupname(old_node, name) self.nameids[name] = None msg = self.reporter.system_message( level, 'Duplicate explicit target name: "%s".' % name, backrefs=[id], base_node=node) if msgnode != None: msgnode += msg - dupname(node) + dupname(node, name) else: self.nameids[name] = id if old_id is not None: old_node = self.ids[old_id] - dupname(old_node) + dupname(old_node, name) 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) + dupname(old_node, name) + dupname(node, name) if not explicit or (not old_explicit and old_id is not None): msg = self.reporter.info( 'Duplicate implicit target name: "%s".' % name, @@ -925,7 +959,7 @@ class document(Root, Structural, Element): def note_indirect_target(self, target): self.indirect_targets.append(target) - if target.has_key('name'): + if target['names']: self.note_refname(target) def note_anonymous_target(self, target): @@ -969,7 +1003,8 @@ class document(Root, Structural, Element): self.note_refname(ref) def note_substitution_def(self, subdef, def_name, msgnode=None): - name = subdef['name'] = whitespace_normalize_name(def_name) + 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, @@ -977,7 +1012,7 @@ class document(Root, Structural, Element): if msgnode != None: msgnode += msg oldnode = self.substitution_defs[name] - dupname(oldnode) + dupname(oldnode, name) # keep only the last definition: self.substitution_defs[name] = subdef # case-insensitive mapping: @@ -1155,8 +1190,8 @@ class admonition(Admonition, Element): pass class comment(Special, Invisible, FixedTextElement): 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 footnote(General, BackLinkable, Element, Labeled, Targetable): pass +class citation(General, BackLinkable, Element, Labeled, Targetable): pass class label(Part, TextElement): pass class figure(General, Element): pass class caption(Part, TextElement): pass @@ -1170,7 +1205,7 @@ class row(Part, Element): pass class entry(Part, Element): pass -class system_message(Special, PreBibliographic, Element, BackLinkable): +class system_message(Special, BackLinkable, PreBibliographic, Element): def __init__(self, message=None, *children, **attributes): if message: @@ -1610,9 +1645,12 @@ 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'] +def dupname(node, name): + node['dupnames'].append(name) + node['names'].remove(name) + # Assume that this method is referenced, even though it isn't; we + # don't want to throw unnecessary system_messages. + node.referenced = 1 def fully_normalize_name(name): """Return a case- and whitespace-normalized name.""" diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index d6ac5a0c9..76d0d75eb 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -39,8 +39,8 @@ 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=whitespace_normalize_name(options['target'])) + reference_node = nodes.reference(refname=data, + name=whitespace_normalize_name(options['target'])) state.document.note_refname(reference_node) else: # malformed target messages.append(data) # data is a system message diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 1a6cbc17c..7bae832d2 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -188,8 +188,7 @@ def replace(name, arguments, options, content, lineno, messages = [] for node in element: if isinstance(node, nodes.system_message): - if node.has_key('backrefs'): - del node['backrefs'] + node['backrefs'] = [] messages.append(node) error = state_machine.reporter.error( 'Error in "%s" directive: may contain a single paragraph ' diff --git a/docutils/parsers/rst/directives/parts.py b/docutils/parsers/rst/directives/parts.py index c182ad0fd..217def5b6 100644 --- a/docutils/parsers/rst/directives/parts.py +++ b/docutils/parsers/rst/directives/parts.py @@ -41,7 +41,7 @@ def contents(name, arguments, options, content, lineno, else: title = nodes.title('', language.labels['contents']) - topic = nodes.topic(CLASS='contents') + topic = nodes.topic(classes=['contents']) cls = options.get('class') if cls: @@ -55,7 +55,7 @@ def contents(name, arguments, options, content, lineno, name = nodes.fully_normalize_name(name) if not document.has_name(name): - topic['name'] = name + topic['names'].append(name) document.note_implicit_target(topic) pending = nodes.pending(parts.Contents, rawsource=block_text) diff --git a/docutils/parsers/rst/roles.py b/docutils/parsers/rst/roles.py index 2f3ab11a5..cf6d5a971 100644 --- a/docutils/parsers/rst/roles.py +++ b/docutils/parsers/rst/roles.py @@ -174,7 +174,7 @@ def set_implicit_options(role_fn): if not hasattr(role_fn, 'options') or role_fn.options is None: role_fn.options = {'class': directives.class_option} elif not role_fn.options.has_key('class'): - role_fn.options['class'] = directives.class_option + role_fn.options['class'] = directives.class_option def register_generic_role(canonical_name, node_class): """For roles which simply wrap a given `node_class` around the text.""" @@ -195,6 +195,7 @@ class GenericRole: def __call__(self, role, rawtext, text, lineno, inliner, options={}, content=[]): + set_classes(options) return [self.node_class(rawtext, utils.unescape(text), **options)], [] @@ -233,6 +234,7 @@ def generic_custom_role(role, rawtext, text, lineno, inliner, """""" # Once nested inline markup is implemented, this and other methods should # recursively call inliner.nested_parse(). + set_classes(options) return [nodes.inline(rawtext, utils.unescape(text), **options)], [] generic_custom_role.options = {'class': directives.class_option} @@ -265,6 +267,7 @@ def pep_reference_role(role, rawtext, text, lineno, inliner, return [prb], [msg] # Base URL mainly used by inliner.pep_reference; so this is correct: ref = inliner.document.settings.pep_base_url + inliner.pep_url % pepnum + set_classes(options) return [nodes.reference(rawtext, 'PEP ' + utils.unescape(text), refuri=ref, **options)], [] @@ -284,6 +287,7 @@ def rfc_reference_role(role, rawtext, text, lineno, inliner, return [prb], [msg] # Base URL mainly used by inliner.rfc_reference, so this is correct: 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], [] @@ -299,6 +303,7 @@ def raw_role(role, rawtext, text, lineno, inliner, options={}, content=[]): 'an associated format.' % role, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] + set_classes(options) node = nodes.raw(rawtext, utils.unescape(text, 1), **options) return [node], [] @@ -329,3 +334,14 @@ register_canonical_role('target', unimplemented_role) # This should remain unimplemented, for testing purposes: register_canonical_role('restructuredtext-unimplemented-role', unimplemented_role) + + +def set_classes(options): + """ + Auxiliary function to set options['classes'] and delete + options['class']. + """ + if options.has_key('class'): + assert not options.has_key('classes') + options['classes'] = options['class'].split() + del options['class'] diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index ddf47df7f..a44f47027 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -365,7 +365,7 @@ class RSTState(StateWS): textnodes, title_messages = self.inline_text(title, lineno) titlenode = nodes.title(title, '', *textnodes) name = normalize_name(titlenode.astext()) - section_node['name'] = name + section_node['names'].append(name) section_node += titlenode section_node += messages section_node += title_messages @@ -787,7 +787,7 @@ class Inliner: else: if target: reference['refuri'] = uri - target['name'] = refname + target['names'].append(refname) self.document.note_external_target(target) self.document.note_explicit_target(target, self.parent) node_list.append(target) @@ -829,7 +829,7 @@ class Inliner: assert len(inlines) == 1 target = inlines[0] name = normalize_name(target.astext()) - target['name'] = name + target['names'].append(name) self.document.note_explicit_target(target, self.parent) return before, inlines, remaining, sysmessages @@ -1751,7 +1751,7 @@ class Body(RSTState): name = name[1:] # autonumber label footnote['auto'] = 1 if name: - footnote['name'] = name + footnote['names'].append(name) self.document.note_autofootnote(footnote) elif name == '*': # auto-symbol name = '' @@ -1759,7 +1759,7 @@ class Body(RSTState): self.document.note_symbol_footnote(footnote) else: # manually numbered footnote += nodes.label('', label) - footnote['name'] = name + footnote['names'].append(name) self.document.note_footnote(footnote) if name: self.document.note_explicit_target(footnote, footnote) @@ -1778,7 +1778,7 @@ class Body(RSTState): citation = nodes.citation('\n'.join(indented)) citation.line = lineno citation += nodes.label('', label) - citation['name'] = name + citation['names'].append(name) self.document.note_citation(citation) self.document.note_explicit_target(citation, citation) if indented: @@ -1814,7 +1814,6 @@ class Body(RSTState): target_type, data = self.parse_target(block, block_text, lineno) if target_type == 'refname': target = nodes.target(block_text, '', refname=normalize_name(data)) - target.indirect_reference_name = data self.add_target(target_name, '', target, lineno) self.document.note_indirect_target(target) return target @@ -1854,7 +1853,7 @@ class Body(RSTState): target.line = lineno if targetname: name = normalize_name(unescape(targetname)) - target['name'] = name + target['names'].append(name) if refuri: uri = self.inliner.adjust_uri(refuri) if uri: @@ -2259,7 +2258,7 @@ class RFC2822Body(Body): def rfc2822(self, match, context, next_state): """RFC2822-style field list item.""" - fieldlist = nodes.field_list(CLASS='rfc2822') + fieldlist = nodes.field_list(classes=['rfc2822']) self.parent += fieldlist field, blank_finish = self.rfc2822_field(match) fieldlist += field @@ -2497,7 +2496,7 @@ class SubstitutionDef(Body): def embedded_directive(self, match, context, next_state): nodelist, blank_finish = self.directive(match, - alt=self.parent['name']) + alt=self.parent['names'][0]) self.parent += nodelist if not self.state_machine.at_eof(): self.blank_finish = blank_finish diff --git a/docutils/readers/pep.py b/docutils/readers/pep.py index b7774a949..b2326666f 100644 --- a/docutils/readers/pep.py +++ b/docutils/readers/pep.py @@ -31,10 +31,9 @@ class Reader(standalone.Reader): config_section_dependencies = ('readers', 'standalone reader') default_transforms = (references.Substitutions, - references.SectionTargets, + references.PropagateTargets, peps.Headers, peps.Contents, - references.ChainedTargets, references.AnonymousHyperlinks, references.IndirectHyperlinks, peps.TargetNotes, diff --git a/docutils/readers/standalone.py b/docutils/readers/standalone.py index 82541c297..63e618b51 100644 --- a/docutils/readers/standalone.py +++ b/docutils/readers/standalone.py @@ -43,10 +43,9 @@ class Reader(readers.Reader): config_section_dependencies = ('readers',) default_transforms = (references.Substitutions, - references.SectionTargets, + references.PropagateTargets, frontmatter.DocTitle, frontmatter.DocInfo, - references.ChainedTargets, references.AnonymousHyperlinks, references.IndirectHyperlinks, references.Footnotes, diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index 1a45c1336..8a5581313 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -50,7 +50,7 @@ class DocTitle(Transform): Once parsed, it looks like this:: -
    +
    Top-Level Title <paragraph> @@ -58,7 +58,7 @@ class DocTitle(Transform): After running the DocTitle transform, we have:: - <document name="top-level title"> + <document names="top-level title"> <title> Top-Level Title <paragraph> @@ -85,10 +85,10 @@ class DocTitle(Transform): After parsing and running the Section Promotion transform, the result is:: - <document name="top-level title"> + <document names="top-level title"> <title> Top-Level Title - <subtitle name="second-level title"> + <subtitle names="second-level title"> Second-Level Title <paragraph> A paragraph. @@ -294,7 +294,7 @@ class DocInfo(Transform): raise TransformError title = nodes.title(name, labels[canonical]) topics[canonical] = biblioclass( - '', title, CLASS=canonical, *field[1].children) + '', title, classes=[canonical], *field[1].children) else: docinfo.append(biblioclass('', *field[1].children)) except TransformError: diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index d0537d5aa..a1405f729 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -54,7 +54,7 @@ class SectNum(Transform): generated = nodes.generated( '', (self.prefix + '.'.join(numbers) + self.suffix + u'\u00a0' * 3), - CLASS='sectnum') + classes=['sectnum']) title.insert(0, generated) title['auto'] = 1 if depth < self.maxdepth: @@ -91,7 +91,7 @@ class Contents(Transform): else: startnode = self.document - self.toc_id = self.startnode.parent['id'] + self.toc_id = self.startnode.parent['ids'][0] if details.has_key('backlinks'): self.backlinks = details['backlinks'] else: @@ -117,7 +117,7 @@ class Contents(Transform): title = section[0] auto = title.get('auto') # May be set by SectNum. entrytext = self.copy_and_filter(title) - reference = nodes.reference('', '', refid=section['id'], + reference = nodes.reference('', '', refid=section['ids'][0], *entrytext) ref_id = self.document.set_id(reference) entry = nodes.paragraph('', '', reference) diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index 16260367a..201ce314b 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -46,7 +46,7 @@ class Headers(Transform): raise DataError('Document tree is empty.') header = self.document[0] if not isinstance(header, nodes.field_list) or \ - header.get('class') != 'rfc2822': + 'rfc2822' not in header['classes']: raise DataError('Document does not begin with an RFC-2822 ' 'header; it is not a PEP.') pep = None @@ -149,10 +149,10 @@ class Contents(Transform): language = languages.get_language(self.document.settings.language_code) name = language.labels['contents'] title = nodes.title('', name) - topic = nodes.topic('', title, CLASS='contents') + topic = nodes.topic('', title, classes=['contents']) name = nodes.fully_normalize_name(name) if not self.document.has_name(name): - topic['name'] = name + topic['names'].append(name) self.document.note_implicit_target(topic) pending = nodes.pending(parts.Contents) topic += pending @@ -244,7 +244,7 @@ class PEPZeroSpecial(nodes.SparseNodeVisitor): node.parent.replace(node, mask_email(node)) def visit_field_list(self, node): - if node.hasattr('class') and node['class'] == 'rfc2822': + if 'rfc2822' in node['classes']: raise nodes.SkipNode def visit_tgroup(self, node): @@ -254,7 +254,7 @@ class PEPZeroSpecial(nodes.SparseNodeVisitor): def visit_colspec(self, node): self.entry += 1 if self.pep_table and self.entry == 2: - node['class'] = 'num' + node['classes'].append('num') def visit_row(self, node): self.entry = 0 @@ -262,7 +262,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' + node['classes'].append('num') p = node[0] if isinstance(p, nodes.paragraph) and len(p) == 1: text = p.astext() diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index e2196452c..80bafbf2a 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -16,114 +16,75 @@ from docutils import nodes, utils from docutils.transforms import TransformError, Transform -class SectionTargets(Transform): +class PropagateTargets(Transform): - default_priority = 260 - - def apply(self): - for target in self.document.internal_targets: - if not (target.attributes.has_key('refid') - or target.attributes.has_key('refuri') - or target.attributes.has_key('refname')): - self.relocate(target) - - def relocate(self, target): - """Move "target" elements into the next title element if necessary.""" - assert isinstance(target, nodes.target) - # Find next node which is not a target. - n = target.next_node(self.possible_relocation_target, ascend=1) - if isinstance(n, nodes.section): - assert isinstance(n[0], nodes.title) - target.parent.remove(target) - n[0].insert(0, target) - - def possible_relocation_target(self, node): - """Return true if a preceding target could be relocated into node.""" - # True if node is not an internal target. (If it's an - # external target, we've just run into a not-yet resolved - # chained external target.) - return (not isinstance(node, nodes.target) or node.has_key('refid') - or node.has_key('refuri') or node.has_key('refname')) - - -class ChainedTargets(Transform): - - """ - Attributes "refuri" and "refname" are migrated from the final direct - target up the chain of contiguous adjacent internal targets, using - `ChainedTargetResolver`. """ + Propagate empty internal targets to the next element. - default_priority = 420 - - def apply(self): - visitor = ChainedTargetResolver(self.document) - self.document.walk(visitor) - - -class ChainedTargetResolver(nodes.SparseNodeVisitor): - - """ - Copy reference attributes up the length of a hyperlink target chain. + Given the following nodes:: - "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"> + <target ids="internal1" names="internal1"> + <target anonymous="1" ids="id1"> + <target ids="internal2" names="internal2"> + <paragraph> + This is a test. - ``ChainedTargetResolver(document).walk()`` will transform the above into:: + PropagateTargets propagates the ids and names of the internal + targets preceding the paragraph to the paragraph itself:: - <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"> + <target refid="internal1"> + <target anonymous="1" refid="id1"> + <target refid="internal2"> + <paragraph ids="internal2 id1 internal1" names="internal2 internal1"> + This is a test. """ - def unknown_visit(self, node): - pass + default_priority = 260 - 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) + 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'))): + continue + 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). + if (next_node is not None and + ((not isinstance(next_node, nodes.Invisible) and + not isinstance(next_node, nodes.Targetable)) or + isinstance(next_node, nodes.target))): + next_node['ids'].extend(target['ids']) + next_node['names'].extend(target['names']) + # Set defaults for next_node.expect_referenced_by_name/id. + if not hasattr(next_node, 'expect_referenced_by_name'): + next_node.expect_referenced_by_name = {} + if not hasattr(next_node, 'expect_referenced_by_id'): + next_node.expect_referenced_by_id = {} + for id in target['ids']: + # Update IDs to node mapping. + self.document.ids[id] = next_node + # If next_node is referenced by id ``id``, this + # target shall be marked as referenced. + next_node.expect_referenced_by_id[id] = target + for name in target['names']: + next_node.expect_referenced_by_name[name] = target + # If there are any expect_referenced_by_... attributes + # in target set, copy them to next_node. + next_node.expect_referenced_by_name.update( + getattr(target, 'expect_referenced_by_name', {})) + next_node.expect_referenced_by_id.update( + getattr(target, 'expect_referenced_by_id', {})) + # Set refid to point to the first former ID of target + # which is now an ID of next_node. + target['refid'] = target['ids'][0] + # Clear ids and names; they have been moved to + # next_node. + target['ids'] = [] + target['names'] = [] + self.document.note_refid(target) + self.document.note_internal_target(next_node) class AnonymousHyperlinks(Transform): @@ -136,8 +97,8 @@ class AnonymousHyperlinks(Transform): internal <reference anonymous="1"> external - <target anonymous="1" id="id1"> - <target anonymous="1" id="id2" refuri="http://external"> + <target anonymous="1" ids="id1"> + <target anonymous="1" ids="id2" refuri="http://external"> Corresponding references are linked via "refid" or resolved via "refuri":: @@ -146,8 +107,8 @@ class AnonymousHyperlinks(Transform): text <reference anonymous="1" refuri="http://external"> external - <target anonymous="1" id="id1"> - <target anonymous="1" id="id2" refuri="http://external"> + <target anonymous="1" ids="id1"> + <target anonymous="1" ids="id2" refuri="http://external"> """ default_priority = 440 @@ -167,16 +128,28 @@ 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): - if target.hasattr('refuri'): - ref['refuri'] = target['refuri'] - ref.resolved = 1 - else: - ref['refid'] = target['id'] - self.document.note_refid(ref) target.referenced = 1 + while 1: + if target.hasattr('refuri'): + ref['refuri'] = target['refuri'] + ref.resolved = 1 + break + else: + if not target['ids']: + # Propagated target. + target = self.document.ids[target['refid']] + continue + ref['refid'] = target['ids'][0] + self.document.note_refid(ref) + break class IndirectHyperlinks(Transform): @@ -240,20 +213,24 @@ class IndirectHyperlinks(Transform): self.resolve_indirect_references(target) def resolve_indirect_target(self, target): - refname = target['refname'] - reftarget_id = self.document.nameids.get(refname) - if not reftarget_id: - # Check the unknown_reference_resolvers - for resolver_function in (self.document.transformer - .unknown_reference_resolvers): - if resolver_function(target): - break - else: - self.nonexistent_indirect_target(target) - return + refname = target.get('refname') + if refname is None: + reftarget_id = target['refid'] + else: + reftarget_id = self.document.nameids.get(refname) + if not reftarget_id: + # Check the unknown_reference_resolvers + for resolver_function in \ + self.document.transformer.unknown_reference_resolvers: + if resolver_function(target): + break + else: + self.nonexistent_indirect_target(target) + return reftarget = self.document.ids[reftarget_id] + reftarget.note_referenced_by(id=reftarget_id) if isinstance(reftarget, nodes.target) \ - and not reftarget.resolved and reftarget.hasattr('refname'): + and not reftarget.resolved and reftarget.hasattr('refname'): if hasattr(target, 'multiply_indirect'): #and target.multiply_indirect): #del target.multiply_indirect @@ -264,21 +241,23 @@ class IndirectHyperlinks(Transform): del target.multiply_indirect if reftarget.hasattr('refuri'): target['refuri'] = reftarget['refuri'] - if target.hasattr('name'): + if target['names']: self.document.note_external_target(target) + if target.has_key('refid'): + del target['refid'] elif reftarget.hasattr('refid'): target['refid'] = reftarget['refid'] self.document.note_refid(target) else: - try: - target['refid'] = reftarget['id'] + if reftarget['ids']: + target['refid'] = reftarget_id self.document.note_refid(target) - except KeyError: + else: self.nonexistent_indirect_target(target) return - del target['refname'] + if refname is not None: + del target['refname'] target.resolved = 1 - reftarget.referenced = 1 def nonexistent_indirect_target(self, target): if self.document.nameids.has_key(target['refname']): @@ -292,18 +271,19 @@ class IndirectHyperlinks(Transform): def indirect_target_error(self, target, explanation): naming = '' - if target.hasattr('name'): - naming = '"%s" ' % target['name'] - reflist = self.document.refnames.get(target['name'], []) - else: - reflist = self.document.refids.get(target['id'], []) - naming += '(id="%s")' % target['id'] + reflist = [] + if target['names']: + naming = '"%s" ' % target['names'][0] + for name in target['names']: + reflist.extend(self.document.refnames.get(name, [])) + for id in target['ids']: + reflist.extend(self.document.refids.get(id, [])) + naming += '(id="%s")' % target['ids'][0] msg = self.document.reporter.error( 'Indirect hyperlink target %s refers to target "%s", %s.' - % (naming, target['refname'], explanation), - base_node=target) + % (naming, target['refname'], explanation), base_node=target) msgid = self.document.set_id(msg) - for ref in reflist: + for ref in uniq(reflist): prb = nodes.problematic( ref.rawsource, ref.rawsource, refid=msgid) prbid = self.document.set_id(prb) @@ -323,43 +303,34 @@ class IndirectHyperlinks(Transform): else: return attval = target[attname] - if target.hasattr('name'): - name = target['name'] - try: - reflist = self.document.refnames[name] - except KeyError, instance: - if target.referenced: - return - msg = self.document.reporter.info( - 'Indirect hyperlink target "%s" is not referenced.' - % name, base_node=target) - target.referenced = 1 - return - delatt = 'refname' - else: - id = target['id'] - try: - reflist = self.document.refids[id] - except KeyError, instance: - if target.referenced: - return - msg = self.document.reporter.info( - 'Indirect hyperlink target id="%s" is not referenced.' - % id, base_node=target) - 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 + for name in target['names']: + reflist = self.document.refnames.get(name, []) + if reflist: + target.note_referenced_by(name=name) + for ref in reflist: + if ref.resolved: + continue + del ref['refname'] + ref[attname] = attval + if not call_if_named or ref['names']: + call_method(ref) + ref.resolved = 1 + if isinstance(ref, nodes.target): + self.resolve_indirect_references(ref) + for id in target['ids']: + reflist = self.document.refids.get(id, []) + if reflist: + target.note_referenced_by(id=id) + for ref in reflist: + if ref.resolved: + continue + del ref['refid'] + ref[attname] = attval + if not call_if_named or ref['names']: + call_method(ref) + ref.resolved = 1 + if isinstance(ref, nodes.target): + self.resolve_indirect_references(ref) class ExternalTargets(Transform): @@ -384,27 +355,18 @@ class ExternalTargets(Transform): def apply(self): for target in self.document.external_targets: - if target.hasattr('refuri') and target.hasattr('name'): - name = target['name'] + if target.hasattr('refuri'): refuri = target['refuri'] - try: - reflist = self.document.refnames[name] - except KeyError, instance: - # @@@ First clause correct??? - if not isinstance(target, nodes.target) or target.referenced: - continue - msg = self.document.reporter.info( - 'External hyperlink target "%s" is not referenced.' - % name, base_node=target) - target.referenced = 1 - continue - for ref in reflist: - if ref.resolved: - continue - del ref['refname'] - ref['refuri'] = refuri - ref.resolved = 1 - target.referenced = 1 + for name in target['names']: + reflist = self.document.refnames.get(name, []) + if reflist: + target.note_referenced_by(name=name) + for ref in reflist: + if ref.resolved: + continue + del ref['refname'] + ref['refuri'] = refuri + ref.resolved = 1 class InternalTargets(Transform): @@ -433,27 +395,19 @@ class InternalTargets(Transform): <target id="id1" name="direct internal"> """ if target.hasattr('refuri') or target.hasattr('refid') \ - or not target.hasattr('name'): - return - name = target['name'] - refid = target['id'] - try: - reflist = self.document.refnames[name] - except KeyError, instance: - if target.referenced: - return - msg = self.document.reporter.info( - 'Internal hyperlink target "%s" is not referenced.' - % name, base_node=target) - target.referenced = 1 + or not target['names']: return - for ref in reflist: - if ref.resolved: - return - del ref['refname'] - ref['refid'] = refid - ref.resolved = 1 - target.referenced = 1 + for name in target['names']: + refid = self.document.nameids[name] + reflist = self.document.refnames.get(name, []) + if reflist: + target.note_referenced_by(name=name) + for ref in reflist: + if ref.resolved: + continue + del ref['refname'] + ref['refid'] = refid + ref.resolved = 1 class Footnotes(Transform): @@ -561,19 +515,17 @@ class Footnotes(Transform): if not self.document.nameids.has_key(label): break footnote.insert(0, nodes.label('', label)) - if footnote.hasattr('dupname'): - continue - if footnote.hasattr('name'): - name = footnote['name'] + for name in footnote['names']: 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']) + assert len(footnote['ids']) == len(ref['ids']) == 1 + ref['refid'] = footnote['ids'][0] + footnote.add_backref(ref['ids'][0]) self.document.note_refid(ref) ref.resolved = 1 - else: - footnote['name'] = label + if not footnote['names'] and not footnote['dupnames']: + footnote['names'].append(label) self.document.note_explicit_target(footnote, footnote) self.autofootnote_labels.append(label) return startnum @@ -606,7 +558,8 @@ class Footnotes(Transform): footnote = self.document.ids[id] ref['refid'] = id self.document.note_refid(ref) - footnote.add_backref(ref['id']) + assert len(ref['ids']) == 1 + footnote.add_backref(ref['ids'][0]) ref.resolved = 1 i += 1 @@ -641,9 +594,10 @@ class Footnotes(Transform): ref.parent.replace(ref, prb) break footnote = self.document.symbol_footnotes[i] - ref['refid'] = footnote['id'] + assert len(footnote['ids']) == 1 + ref['refid'] = footnote['ids'][0] self.document.note_refid(ref) - footnote.add_backref(ref['id']) + footnote.add_backref(ref['ids'][0]) i += 1 def resolve_footnotes_and_citations(self): @@ -652,26 +606,26 @@ class Footnotes(Transform): references. """ for footnote in self.document.footnotes: - if footnote.hasattr('name'): - label = footnote['name'] + for label in footnote['names']: if self.document.footnote_refs.has_key(label): reflist = self.document.footnote_refs[label] self.resolve_references(footnote, reflist) for citation in self.document.citations: - if citation.hasattr('name'): - label = citation['name'] + for label in citation['names']: 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): - id = note['id'] + assert len(note['ids']) == 1 + id = note['ids'][0] for ref in reflist: if ref.resolved: continue ref.delattr('refname') ref['refid'] = id - note.add_backref(ref['id']) + assert len(ref['ids']) == 1 + note.add_backref(ref['ids'][0]) ref.resolved = 1 note.resolved = 1 @@ -765,11 +719,12 @@ class TargetNotes(Transform): notes = {} nodelist = [] for target in self.document.external_targets: - name = target.get('name') - if not name: - print >>sys.stderr, 'no name on target: %r' % target - continue - refs = self.document.refnames.get(name, []) + names = target['names'] + # Only named targets. + assert names + refs = [] + for name in names: + refs.extend(self.document.refnames.get(name, [])) if not refs: continue footnote = self.make_target_footnote(target, refs, notes) @@ -791,14 +746,16 @@ class TargetNotes(Transform): refuri = target['refuri'] if notes.has_key(refuri): # duplicate? footnote = notes[refuri] - footnote_name = footnote['name'] + assert len(footnote['names']) == 1 + footnote_name = footnote['names'][0] else: # original footnote = nodes.footnote() footnote_id = self.document.set_id(footnote) - # Use a colon; they can't be produced inside names by the parser: - footnote_name = 'target_note: ' + footnote_id + # Use uppercase letters and a colon; they can't be + # produced inside names by the parser. + footnote_name = 'TARGET_NOTE: ' + footnote_id footnote['auto'] = 1 - footnote['name'] = footnote_name + footnote['names'] = [footnote_name] footnote_paragraph = nodes.paragraph() footnote_paragraph += nodes.reference('', refuri, refuri=refuri) footnote += footnote_paragraph @@ -817,3 +774,10 @@ class TargetNotes(Transform): reflist.insert(0, nodes.Text(' ')) ref.parent.insert(index, reflist) return footnote + + +def uniq(L): + d = {} + for x in L: + d[x] = None + return d.keys() diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 62304e2a8..7d8a796cc 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -103,7 +103,7 @@ class Messages(Transform): if msg['level'] >= threshold and not msg.parent: messages.append(msg) if messages: - section = nodes.section(CLASS='system-messages') + section = nodes.section(classes=['system-messages']) # @@@ get this from the language module? section += nodes.title('', 'Docutils System Messages') section += messages @@ -167,6 +167,21 @@ class FinalChecks(Transform): if self.document.settings.expose_internals: visitor = InternalAttributeExposer(self.document) 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: + 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): @@ -206,7 +221,7 @@ class FinalCheckVisitor(nodes.SparseNodeVisitor): else: del node['refname'] node['refid'] = id - self.document.ids[id].referenced = 1 + self.document.ids[id].note_referenced_by(id=id) node.resolved = 1 visit_footnote_reference = visit_citation_reference = visit_reference diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index c0938c590..a3b85f9a2 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -215,7 +215,7 @@ class HTMLTranslator(nodes.NodeVisitor): # A heterogenous stack used in conjunction with the tree traversal. # Make sure that the pops correspond to the pushes: self.context = [] - self.topic_class = '' + self.topic_class = [] self.colspecs = [] self.compact_p = 1 self.compact_simple = None @@ -256,16 +256,20 @@ class HTMLTranslator(nodes.NodeVisitor): are extracted), tag name, and optional attributes. """ tagname = tagname.lower() + prefix = [] atts = {} for (name, value) in attributes.items(): atts[name.lower()] = value - for att in ('class',): # append to node attribute - if node.has_key(att) or atts.has_key(att): - atts[att] = \ - (node.get(att, '') + ' ' + atts.get(att, '')).strip() - for att in ('id',): # node attribute overrides - if node.has_key(att): - atts[att] = node[att] + 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') + if node.get('ids'): + atts['id'] = node['ids'][0] + for id in node['ids'][1:]: + prefix.append('<span id="%s"></span>' % id) if atts.has_key('id') and tagname in self.named_tags: atts['name'] = atts['id'] # for compatibility with old browsers attlist = atts.items() @@ -285,7 +289,7 @@ class HTMLTranslator(nodes.NodeVisitor): except TypeError: # for Python 2.1 compatibility: uval = unicode(str(value)) parts.append('%s="%s"' % (name.lower(), self.attval(uval))) - return '<%s%s>%s' % (' '.join(parts), infix, suffix) + 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.""" @@ -389,7 +393,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.compact_p = None self.compact_simple = (self.settings.compact_lists and (self.compact_simple - or self.topic_class == 'contents' + or self.topic_classes == ['contents'] or self.check_simple_list(node))) if self.compact_simple and not old_compact_simple: atts['class'] = 'simple' @@ -629,7 +633,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.compact_p = None self.compact_simple = (self.settings.compact_lists and (self.compact_simple - or self.topic_class == 'contents' + 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() @@ -718,12 +722,13 @@ class HTMLTranslator(nodes.NodeVisitor): def footnote_backrefs(self, node): backlinks = [] - if self.settings.footnote_backlinks and node.hasattr('backrefs'): - backrefs = node['backrefs'] + backrefs = node['backrefs'] + if self.settings.footnote_backlinks and backrefs: if len(backrefs) == 1: self.context.append('') - self.context.append('<a class="fn-backref" href="#%s" ' - 'name="%s">' % (backrefs[0], node['id'])) + self.context.append( + '<a class="fn-backref" href="#%s" name="%s">' + % (backrefs[0], node['ids'][0])) else: i = 1 for backref in backrefs: @@ -731,10 +736,10 @@ class HTMLTranslator(nodes.NodeVisitor): % (backref, i)) i += 1 self.context.append('<em>(%s)</em> ' % ', '.join(backlinks)) - self.context.append('<a name="%s">' % node['id']) + self.context.append('<a name="%s">' % node['ids'][0]) else: self.context.append('') - self.context.append('<a name="%s">' % node['id']) + self.context.append('<a name="%s">' % 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 @@ -795,7 +800,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.depart_admonition() def visit_image(self, node): - atts = node.attributes.copy() + atts = node.non_default_attributes() if atts.has_key('class'): del atts['class'] # prevent duplication with node attrs atts['src'] = atts['uri'] @@ -832,9 +837,8 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.emptytag(node, 'img', '', **atts)) def image_div_atts(self, image_node): - div_atts = {'class': 'image'} - if image_node.attributes.has_key('class'): - div_atts['class'] += ' ' + image_node.attributes['class'] + 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'] @@ -917,7 +921,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('\n</pre>\n') def visit_meta(self, node): - meta = self.emptytag(node, 'meta', **node.attributes) + meta = self.emptytag(node, 'meta', **node.non_default_attributes()) self.add_meta(meta) def depart_meta(self, node): @@ -1003,12 +1007,16 @@ class HTMLTranslator(nodes.NodeVisitor): isinstance(node.parent, nodes.compound)): # Never compact paragraphs in document or compound. return 0 - if ((node.attributes in ({}, {'class': 'first'}, {'class': 'last'}, - {'class': 'first last'})) and - (self.compact_simple or - self.compact_p and (len(node.parent) == 1 or - len(node.parent) == 2 and - isinstance(node.parent[0], nodes.label)))): + 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_p and (len(node.parent) == 1 or + len(node.parent) == 2 and + isinstance(node.parent[0], nodes.label))): return 1 return 0 @@ -1025,7 +1033,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_problematic(self, node): if node.hasattr('refid'): self.body.append('<a href="#%s" name="%s">' % (node['refid'], - node['id'])) + node['ids'][0])) self.context.append('</a>') else: self.context.append('') @@ -1037,12 +1045,11 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_raw(self, node): if 'html' in node.get('format', '').split(): - add_class = node.attributes.get('class') is not None t = isinstance(node.parent, nodes.TextElement) and 'span' or 'div' - if add_class: + if node['classes']: self.body.append(self.starttag(node, t, suffix='')) self.body.append(node.astext()) - if add_class: + if node['classes']: self.body.append('</%s>' % t) # Keep non-HTML raw text out of output: raise nodes.SkipNode @@ -1162,9 +1169,9 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('<p class="system-message-title">') attr = {} backref_text = '' - if node.hasattr('id'): - attr['name'] = node['id'] - if node.hasattr('backrefs'): + if node['ids']: + attr['name'] = node['ids'][0] + if len(node['backrefs']): backrefs = node['backrefs'] if len(backrefs) == 1: backref_text = ('; <em><a href="#%s">backlink</a></em>' @@ -1288,17 +1295,17 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append( self.starttag(node, 'h%s' % h_level, '')) atts = {} - if node.parent.hasattr('id'): - atts['name'] = node.parent['id'] + if node.parent['ids']: + atts['name'] = node.parent['ids'][0] 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 check_id: - if node.parent.hasattr('id'): + if node.parent['ids']: self.body.append( - self.starttag({}, 'a', '', name=node.parent['id'])) + self.starttag({}, 'a', '', name=node.parent['ids'][0])) self.context.append('</a>' + close_tag) else: self.context.append(close_tag) @@ -1319,11 +1326,11 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_topic(self, node): self.body.append(self.starttag(node, 'div', CLASS='topic')) - self.topic_class = node.get('class') + self.topic_classes = node['classes'] def depart_topic(self, node): self.body.append('</div>\n') - self.topic_class = '' + self.topic_classes = [] def visit_transition(self, node): self.body.append(self.emptytag(node, 'hr', CLASS='docutils')) diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 1ce091add..7506c9f52 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -678,7 +678,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body_suffix = ['\n'] self.section_level = 0 self.context = [] - self.topic_class = '' + self.topic_classes = [] # column specification for tables self.table_caption = None @@ -946,14 +946,14 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append( '\\end{quote}\n') def visit_bullet_list(self, node): - if self.topic_class == 'contents': + if self.topic_classes == ['contents']: 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_class == 'contents': + if self.topic_classes == ['contents']: if not self.use_latex_toc: self.body.append( '\\end{list}\n' ) else: @@ -1001,7 +1001,8 @@ class LaTeXTranslator(nodes.NodeVisitor): self.context.append(len(self.body)) else: self.body.append('\\begin{figure}[b]') - self.body.append('\\hypertarget{%s}' % node['id']) + for id in node['ids']: + self.body.append('\\hypertarget{%s}' % id) def depart_citation(self, node): if self._use_latex_citations: @@ -1395,7 +1396,8 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('{') else: self.body.append('\\begin{figure}[b]') - self.body.append('\\hypertarget{%s}' % node['id']) + for id in node['ids']: + self.body.append('\\hypertarget{%s}' % id) def depart_footnote(self, node): if self.use_latex_footnotes: @@ -1703,7 +1705,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_paragraph(self, node): index = node.parent.index(node) - if not (self.topic_class == 'contents' or + if not (self.topic_classes == ['contents'] or (isinstance(node.parent, nodes.compound) and index > 0 and not isinstance(node.parent[index - 1], nodes.paragraph) and @@ -1841,8 +1843,9 @@ class LaTeXTranslator(nodes.NodeVisitor): # 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')): - self.body.append('\\hypertarget{%s}{' % node['id']) - self.context.append('}') + for id in node['ids']: + self.body.append('\\hypertarget{%s}{' % id) + self.context.append('}' * len(node['ids'])) else: self.context.append('') @@ -1906,8 +1909,9 @@ class LaTeXTranslator(nodes.NodeVisitor): def bookmark(self, node): """Append latex href and pdfbookmarks for titles. """ - if node.parent.hasattr('id'): - self.body.append('\\hypertarget{%s}{}\n' % node.parent['id']) + 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. @@ -1918,8 +1922,9 @@ class LaTeXTranslator(nodes.NodeVisitor): l = l-1 # pdftex does not like "_" subscripts in titles text = self.encode(node.astext()) - self.body.append('\\pdfbookmark[%d]{%s}{%s}\n' % \ - (l,text,node.parent['id'])) + 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).""" @@ -1968,10 +1973,10 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append(self.context.pop()) def visit_topic(self, node): - self.topic_class = node.get('class') + self.topic_classes = node['classes'] if self.use_latex_toc: self.body.append('\\tableofcontents\n\n\\bigskip\n') - self.topic_class = '' + self.topic_classes = [] raise nodes.SkipNode def visit_inline(self, node): # titlereference @@ -1981,7 +1986,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append( '}' ) def depart_topic(self, node): - self.topic_class = '' + self.topic_classes = [] self.body.append('\n') def visit_rubric(self, node): diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index a8c74bbc7..f6601120a 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -86,5 +86,5 @@ class HTMLTranslator(html4css1.HTMLTranslator): def depart_field_list(self, node): html4css1.HTMLTranslator.depart_field_list(self, node) - if node.get('class') == 'rfc2822': + if 'rfc2822' in node['classes']: self.body.append('<hr />\n') -- cgit v1.2.1 From 9fbd82b92c2f23dd8275ab2a5db022d652a7ca9b Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 26 Mar 2005 16:56:56 +0000 Subject: typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3131 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index a3b85f9a2..9a1a83873 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -215,7 +215,7 @@ class HTMLTranslator(nodes.NodeVisitor): # A heterogenous stack used in conjunction with the tree traversal. # Make sure that the pops correspond to the pushes: self.context = [] - self.topic_class = [] + self.topic_classes = [] self.colspecs = [] self.compact_p = 1 self.compact_simple = None -- cgit v1.2.1 From 40394acf8adb9b7f471ba35a2bd82dd19faa334b Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 26 Mar 2005 19:29:27 +0000 Subject: updated documentation to "ids" and "names" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3134 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 2fb111427..021c2dbf0 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -301,11 +301,11 @@ class Element(Node): element['att'] = 'value' - There are two special attributes: 'id' and 'name'. Both are - unique, and names serve as human interfaces to IDs. Names are - case- and whitespace-normalized (see the fully_normalize_name() - function), and IDs conform to the regular expression - ``[a-z](-?[a-z0-9]+)*`` (see the make_id() function). + There are two special attributes: 'ids' and 'names'. Both are + lists of unique identifiers, and names serve as human interfaces + to IDs. Names are case- and whitespace-normalized (see the + fully_normalize_name() function), and IDs conform to the regular + expression ``[a-z](-?[a-z0-9]+)*`` (see the make_id() function). Elements also emulate lists for child nodes (element nodes and/or text nodes), indexing by integer. To get the first child node, use:: -- cgit v1.2.1 From 713cd407a320d79424a2e59d5dfc50ccb31de930 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 26 Mar 2005 20:11:28 +0000 Subject: simplified creation of attributes; there is some redundancy now (the dictionary appears twice), and the backrefs attribute is set not only for BackLinkable nodes but for all Elements, but for simplicity that is OK, IMO; and after all, it provides quite a significant speedup git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3136 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 021c2dbf0..b6c34e359 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -27,7 +27,6 @@ import sys import os import re import xml.dom.minidom -from copy import deepcopy from types import IntType, SliceType, StringType, UnicodeType, \ TupleType, ListType from UserString import UserString @@ -327,9 +326,9 @@ class Element(Node): This is equivalent to ``element.extend([node1, node2])``. """ - attr_defaults = {'ids': [], 'classes': [], 'names': [], 'dupnames': []} - """Default attributes. ``attributes`` is initialized with a copy - of ``attr_defaults``.""" + attr_defaults = {'ids': [], 'classes': [], 'names': [], + 'dupnames': [], 'backrefs': []} + """Default attributes.""" tagname = None """The element generic identifier. If None, it is set as an instance @@ -347,7 +346,8 @@ class Element(Node): self.extend(children) # maintain parent info - self.attributes = deepcopy(self.attr_defaults) + self.attributes = {'ids': [], 'classes': [], 'names': [], + 'dupnames': [], 'backrefs': []} """Dictionary of attribute {name: value}.""" for att, value in attributes.items(): @@ -664,9 +664,6 @@ class Resolvable: class BackLinkable: - attr_defaults = Element.attr_defaults.copy() - attr_defaults['backrefs'] = [] - def add_backref(self, refid): self['backrefs'].append(refid) -- cgit v1.2.1 From 4cb54a62aaa4e04d01714fbcbc2cb93fbad74233 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 27 Mar 2005 15:05:34 +0000 Subject: remove BOMs from input streams git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3138 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/io.py b/docutils/io.py index a5f0bd889..665766605 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -95,7 +95,8 @@ class Input(TransformSpec): try: decoded = unicode(data, enc, self.error_handler) self.successful_encoding = enc - return decoded + # Return decoded, removing BOMs. + return decoded.replace(u'\ufeff', u'') except (UnicodeError, LookupError), error: pass if error is not None: -- cgit v1.2.1 From 5fab375714807b7b9c41f46bb3b33f5a953d14c1 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 27 Mar 2005 15:37:17 +0000 Subject: surround \items in LaTeX with curly brackets; closing https://sourceforge.net/tracker/index.php?func=detail&aid=1114337&group_id=38414&atid=422030 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3141 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 7506c9f52..1a488d88d 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1863,11 +1863,11 @@ class LaTeXTranslator(nodes.NodeVisitor): pass def visit_term(self, node): - self.body.append('\\item[') + self.body.append('\\item[{') def depart_term(self, node): # definition list term. - self.body.append('] ') + self.body.append('}] ') def visit_tgroup(self, node): #self.body.append(self.starttag(node, 'colgroup')) -- cgit v1.2.1 From 0dc19df0996b9fb471dfd9e9df25c8cad0723b44 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 27 Mar 2005 22:40:57 +0000 Subject: typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3142 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index b6c34e359..434a0d723 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1505,7 +1505,7 @@ def _add_node_class_names(names): setattr(GenericNodeVisitor, "visit_" + _name, _call_default_visit) setattr(GenericNodeVisitor, "depart_" + _name, _call_default_departure) setattr(SparseNodeVisitor, 'visit_' + _name, _nop) - setattr(SparseNodeVisitor, 'depart' + _name, _nop) + setattr(SparseNodeVisitor, 'depart_' + _name, _nop) _add_node_class_names(node_class_names) -- cgit v1.2.1 From 1e6c8b451a03a5f4dfc4662505a42ef230f0b13b Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 28 Mar 2005 12:40:55 +0000 Subject: made issuing debug-system_messages conditional git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3143 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/utils.py b/docutils/utils.py index ccc6a4f20..848e231fe 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -203,7 +203,8 @@ class Reporter: effect on the processing. Level-0 system messages are handled separately from the others. """ - return self.system_message(0, *args, **kwargs) + if self.categories[''].debug: + return self.system_message(0, *args, **kwargs) def info(self, *args, **kwargs): """ -- cgit v1.2.1 From d8a66c7cf9f0ca21a4b4eaa877a779731d3fce06 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 30 Mar 2005 20:51:06 +0000 Subject: removed non-deterministic behavior; thanks, David! git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3149 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'docutils') diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 80bafbf2a..7d1aa29e8 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -665,7 +665,9 @@ class Substitutions(Transform): def apply(self): defs = self.document.substitution_defs normed = self.document.substitution_names - for refname, refs in self.document.substitution_refs.items(): + subreflist = self.document.substitution_refs.items() + subreflist.sort() + for refname, refs in subreflist: for ref in refs: key = None if defs.has_key(refname): @@ -777,7 +779,8 @@ class TargetNotes(Transform): def uniq(L): - d = {} - for x in L: - d[x] = None - return d.keys() + r = [] + for item in L: + if not item in r: + r.append(item) + return r -- cgit v1.2.1 From f750d95ce28e8657f4e0c8952f55fc7adf2e9a9b Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 31 Mar 2005 21:36:09 +0000 Subject: added docstring for Sequential to make it more easily findable (when searching for "List") git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3151 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index 434a0d723..cbc01cba6 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -692,7 +692,8 @@ class Body: pass class General(Body): pass -class Sequential(Body): pass +class Sequential(Body): + """List-like elements.""" class Admonition(Body): pass -- cgit v1.2.1 From 232e7e218a2c4b14569bd11890ad26ab2d5cb76c Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 2 Apr 2005 21:57:06 +0000 Subject: removed nodes.Element.set_class() method; directives.class_option now returns a *list* of classes; added test for :figclass: option of figure directive; the raw role's :format: option is now "unchanged", not "class_option"; some fixes: the :class: option should now always be propagated correctly from directives git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3155 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 4 ---- docutils/parsers/rst/directives/__init__.py | 4 ++-- docutils/parsers/rst/directives/admonitions.py | 6 +++--- docutils/parsers/rst/directives/body.py | 16 ++++++++-------- docutils/parsers/rst/directives/images.py | 8 +++++--- docutils/parsers/rst/directives/parts.py | 4 +--- docutils/parsers/rst/directives/tables.py | 9 +++------ docutils/parsers/rst/roles.py | 4 ++-- docutils/transforms/misc.py | 3 +-- docutils/transforms/parts.py | 2 +- docutils/writers/html4css1.py | 24 ++++++++++++------------ 11 files changed, 38 insertions(+), 46 deletions(-) (limited to 'docutils') diff --git a/docutils/nodes.py b/docutils/nodes.py index cbc01cba6..d347d9dda 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -595,10 +595,6 @@ 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['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`.""" diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index b8207599f..05f552edd 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -284,7 +284,7 @@ def nonnegative_int(argument): def class_option(argument): """ - Convert the argument into an ID-compatible string and return it. + Convert the argument into a list of ID-compatible strings and return it. (Directive option conversion function.) Raise ``ValueError`` if no argument is found. @@ -298,7 +298,7 @@ def class_option(argument): if not class_name: raise ValueError('cannot make "%s" into a class name' % name) class_names.append(class_name) - return ' '.join(class_names) + return class_names unicode_pattern = re.compile( r'(?:0x|x|\\x|U\+?|\\u)([0-9a-f]+)$|&#x([0-9a-f]+);$', re.IGNORECASE) diff --git a/docutils/parsers/rst/directives/admonitions.py b/docutils/parsers/rst/directives/admonitions.py index 8e3a92895..73ca18161 100644 --- a/docutils/parsers/rst/directives/admonitions.py +++ b/docutils/parsers/rst/directives/admonitions.py @@ -30,10 +30,10 @@ def make_admonition(node_class, name, arguments, options, content, lineno, admonition_node += nodes.title(title_text, '', *textnodes) admonition_node += messages if options.has_key('class'): - class_value = options['class'] + classes = options['class'] else: - class_value = 'admonition-' + nodes.make_id(title_text) - admonition_node.set_class(class_value) + classes = ['admonition-' + nodes.make_id(title_text)] + admonition_node['classes'] += classes state.nested_parse(content, content_offset, admonition_node) return [admonition_node] diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index cfc3c04f4..117311720 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -16,6 +16,7 @@ __docformat__ = 'reStructuredText' import sys from docutils import nodes from docutils.parsers.rst import directives +from docutils.parsers.rst.roles import set_classes def topic(name, arguments, options, content, lineno, @@ -44,8 +45,7 @@ def topic(name, arguments, options, content, lineno, messages.extend(more_messages) text = '\n'.join(content) node = node_class(text, *(titles + messages)) - if options.has_key('class'): - node.set_class(options['class']) + node['classes'] += options.get('class', []) if text: state.nested_parse(content, content_offset, node) return [node] @@ -72,7 +72,7 @@ def line_block(name, arguments, options, content, lineno, 'Content block expected for the "%s" directive; none found.' % name, nodes.literal_block(block_text, block_text), line=lineno) return [warning] - block = nodes.line_block() + block = nodes.line_block(classes=options.get('class', [])) node_list = [block] for line_text in content: text_nodes, messages = state.inline_text(line_text.strip(), @@ -91,6 +91,7 @@ line_block.content = 1 def parsed_literal(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): + set_classes(options) return block(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine, node_class=nodes.literal_block) @@ -124,7 +125,7 @@ rubric.options = {'class': directives.class_option} def epigraph(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): block_quote, messages = state.block_quote(content, content_offset) - block_quote.set_class('epigraph') + block_quote['classes'].append('epigraph') return [block_quote] + messages epigraph.content = 1 @@ -132,7 +133,7 @@ epigraph.content = 1 def highlights(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): block_quote, messages = state.block_quote(content, content_offset) - block_quote.set_class('highlights') + block_quote['classes'].append('highlights') return [block_quote] + messages highlights.content = 1 @@ -140,7 +141,7 @@ highlights.content = 1 def pull_quote(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): block_quote, messages = state.block_quote(content, content_offset) - block_quote.set_class('pull-quote') + block_quote['classes'].append('pull-quote') return [block_quote] + messages pull_quote.content = 1 @@ -154,8 +155,7 @@ def compound(name, arguments, options, content, lineno, nodes.literal_block(block_text, block_text), line=lineno) return [error] node = nodes.compound(text) - if options.has_key('class'): - node.set_class(options['class']) + node['classes'] += options.get('class', []) state.nested_parse(content, content_offset, node) return [node] diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index 76d0d75eb..d4cd20a7f 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -15,6 +15,7 @@ import sys from docutils import nodes, utils from docutils.parsers.rst import directives, states from docutils.nodes import whitespace_normalize_name +from docutils.parsers.rst.roles import set_classes try: import Image # PIL @@ -45,6 +46,7 @@ def image(name, arguments, options, content, lineno, else: # malformed target messages.append(data) # data is a system message del options['target'] + set_classes(options) image_node = nodes.image(block_text, **options) if reference_node: reference_node += image_node @@ -64,7 +66,7 @@ image.options = {'alt': directives.unchanged, def figure(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): figwidth = options.setdefault('figwidth') - figclass = options.setdefault('figclass') + figclasses = options.setdefault('figclass') del options['figwidth'] del options['figclass'] (image_node,) = image(name, arguments, options, content, lineno, @@ -84,8 +86,8 @@ def figure(name, arguments, options, content, lineno, figure_node['width'] = i.size[0] elif figwidth is not None: figure_node['width'] = figwidth - if figclass: - figure_node.set_class(figclass) + if figclasses: + figure_node['classes'] += figclasses if content: node = nodes.Element() # anonymous container for parsing state.nested_parse(content, content_offset, node) diff --git a/docutils/parsers/rst/directives/parts.py b/docutils/parsers/rst/directives/parts.py index 217def5b6..c87c239ec 100644 --- a/docutils/parsers/rst/directives/parts.py +++ b/docutils/parsers/rst/directives/parts.py @@ -43,9 +43,7 @@ def contents(name, arguments, options, content, lineno, topic = nodes.topic(classes=['contents']) - cls = options.get('class') - if cls: - topic.set_class(cls) + topic['classes'] += options.get('class', []) if title: name = title.astext() diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index e47c9f9e4..8f16beda0 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -53,8 +53,7 @@ def table(name, arguments, options, content, lineno, line=lineno) return [error] table_node = node[0] - if options.has_key('class'): - table_node.set_class(options['class']) + table_node['classes'] += options.get('class', []) if title: table_node.insert(0, title) return [table_node] + messages @@ -147,8 +146,7 @@ def csv_table(name, arguments, options, content, lineno, return [error] table = (col_widths, table_head, table_body) table_node = state.build_table(table, content_offset) - if options.has_key('class'): - table_node.set_class(options['class']) + table_node['classes'] += options.get('class', []) if title: table_node.insert(0, title) return [table_node] + messages @@ -342,8 +340,7 @@ def list_table(name, arguments, options, content, lineno, except SystemMessagePropagation, detail: return [detail.args[0]] table_node = build_table_from_list(table_data, col_widths, header_rows) - if options.has_key('class'): - table_node.set_class(options['class']) + table_node['classes'] += options.get('class', []) if title: table_node.insert(0, title) return [table_node] + messages diff --git a/docutils/parsers/rst/roles.py b/docutils/parsers/rst/roles.py index cf6d5a971..554e1f441 100644 --- a/docutils/parsers/rst/roles.py +++ b/docutils/parsers/rst/roles.py @@ -307,7 +307,7 @@ def raw_role(role, rawtext, text, lineno, inliner, options={}, content=[]): node = nodes.raw(rawtext, utils.unescape(text, 1), **options) return [node], [] -raw_role.options = {'format': directives.class_option} +raw_role.options = {'format': directives.unchanged} register_canonical_role('raw', raw_role) @@ -343,5 +343,5 @@ def set_classes(options): """ if options.has_key('class'): assert not options.has_key('classes') - options['classes'] = options['class'].split() + options['classes'] = options['class'] del options['class'] diff --git a/docutils/transforms/misc.py b/docutils/transforms/misc.py index b325f554b..fb01c6c72 100644 --- a/docutils/transforms/misc.py +++ b/docutils/transforms/misc.py @@ -45,7 +45,6 @@ class ClassAttribute(Transform): def apply(self): pending = self.startnode - class_value = pending.details['class'] parent = pending.parent child = pending while parent: @@ -55,7 +54,7 @@ class ClassAttribute(Transform): if (isinstance(element, nodes.Invisible) or isinstance(element, nodes.system_message)): continue - element.set_class(class_value) + element['classes'] += pending.details['class'] pending.parent.remove(pending) return else: diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index a1405f729..20dbec880 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -135,7 +135,7 @@ class Contents(Transform): if entries: contents = nodes.bullet_list('', *entries) if auto: - contents.set_class('auto-toc') + contents['classes'].append('auto-toc') return contents else: return [] diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 9a1a83873..4736f54e0 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -297,8 +297,8 @@ class HTMLTranslator(nodes.NodeVisitor): def set_first_last(self, node): if len(node): - node[0].set_class('first') - node[-1].set_class('last') + node[0]['classes'].append('first') + node[-1]['classes'].append('last') def visit_Text(self, node): self.body.append(self.encode(node.astext())) @@ -474,10 +474,10 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_compound(self, node): self.body.append(self.starttag(node, 'div', CLASS='compound')) if len(node) > 1: - node[0].set_class('compound-first') - node[-1].set_class('compound-last') + node[0]['classes'].append('compound-first') + node[-1]['classes'].append('compound-last') for child in node[1:-1]: - child.set_class('compound-middle') + child['classes'].append('compound-middle') def depart_compound(self, node): self.body.append('</div>\n') @@ -566,9 +566,9 @@ class HTMLTranslator(nodes.NodeVisitor): % self.language.labels[name]) if len(node): if isinstance(node[0], nodes.Element): - node[0].set_class('first') + node[0]['classes'].append('first') if isinstance(node[-1], nodes.Element): - node[-1].set_class('last') + node[-1]['classes'].append('last') def depart_docinfo_item(self): self.body.append('</td></tr>\n') @@ -745,8 +745,8 @@ class HTMLTranslator(nodes.NodeVisitor): # If there are preceding backlinks, we do not set class # 'first', because we need to retain the top-margin. if not backlinks: - node[1].set_class('first') - node[-1].set_class('last') + node[1]['classes'].append('first') + node[-1]['classes'].append('last') def depart_footnote(self, node): self.body.append('</td></tr>\n' @@ -801,8 +801,8 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_image(self, node): atts = node.non_default_attributes() - if atts.has_key('class'): - del atts['class'] # prevent duplication with node attrs + 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'): @@ -889,7 +889,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_list_item(self, node): self.body.append(self.starttag(node, 'li', '')) if len(node): - node[0].set_class('first') + node[0]['classes'].append('first') def depart_list_item(self, node): self.body.append('</li>\n') -- cgit v1.2.1 From f1da7eb10858e31b6e69f96bf9c7f3e46801f50f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 4 Apr 2005 17:05:37 +0000 Subject: added the "field_name_limit" setting, test & docs git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3164 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 7 +++++++ docutils/writers/html4css1.py | 9 ++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'docutils') diff --git a/docutils/frontend.py b/docutils/frontend.py index 01731c478..d84aa55f3 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -124,6 +124,13 @@ def validate_boolean(setting, value, option_parser, None, sys.exc_info()[2]) return value +def validate_nonnegative_int(setting, value, option_parser, + config_parser=None, config_section=None): + value = int(value) + if value < 0: + raise ValueError('negative value; must be positive or zero') + return value + def validate_threshold(setting, value, option_parser, config_parser=None, config_section=None): try: diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 4736f54e0..af18e2745 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -63,6 +63,12 @@ class Writer(writers.Writer): ['--initial-header-level'], {'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".', + ['--field-name-limit'], + {'default': 14, 'metavar': '<level>', + 'validator': frontend.validate_nonnegative_int}), ('Format for footnote references: one of "superscript" or ' '"brackets". Default is "brackets".', ['--footnote-references'], @@ -679,7 +685,8 @@ class HTMLTranslator(nodes.NodeVisitor): atts['class'] = 'docinfo-name' else: atts['class'] = 'field-name' - if len(node.astext()) > 14: + if ( self.settings.field_name_limit + and len(node.astext()) > self.settings.field_name_limit): atts['colspan'] = 2 self.context.append('</tr>\n<tr><td> </td>') else: -- cgit v1.2.1 From dc3284ca85006e72f0e3b2c4ffbe078aa9148f76 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 5 Apr 2005 02:55:06 +0000 Subject: added "stub-columns" options to "csv-table" and "list-table" directives, plus support, docs, and tests git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3165 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 43 ++++++++++++++++++++++++------- docutils/parsers/rst/states.py | 14 ++++++---- docutils/writers/html4css1.py | 8 +++++- 3 files changed, 50 insertions(+), 15 deletions(-) (limited to 'docutils') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 8f16beda0..87131277d 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -130,8 +130,10 @@ def csv_table(name, arguments, options, content, lineno, csv_data, DocutilsDialect(options), source, options) max_cols = max(max_cols, max_header_cols) header_rows = options.get('header-rows', 0) # default 0 + stub_columns = options.get('stub-columns', 0) # default 0 check_table_dimensions( - rows, header_rows, name, lineno, block_text, state_machine) + rows, header_rows, stub_columns, name, lineno, + block_text, state_machine) table_head.extend(rows[:header_rows]) table_body = rows[header_rows:] col_widths = get_column_widths( @@ -145,7 +147,7 @@ def csv_table(name, arguments, options, content, lineno, nodes.literal_block(block_text, block_text), line=lineno) return [error] table = (col_widths, table_head, table_body) - table_node = state.build_table(table, content_offset) + table_node = state.build_table(table, content_offset, stub_columns) table_node['classes'] += options.get('class', []) if title: table_node.insert(0, title) @@ -153,6 +155,7 @@ def csv_table(name, arguments, options, content, lineno, csv_table.arguments = (0, 1, 1) csv_table.options = {'header-rows': directives.nonnegative_int, + 'stub-columns': directives.nonnegative_int, 'header': directives.unchanged, 'widths': directives.positive_int_list, 'file': directives.path, @@ -274,20 +277,34 @@ def parse_csv_data_into_rows(csv_data, dialect, source, options): max_cols = max(max_cols, len(row)) return rows, max_cols -def check_table_dimensions(rows, header_rows, name, lineno, block_text, - state_machine): +def check_table_dimensions(rows, header_rows, stub_columns, name, lineno, + block_text, state_machine): if len(rows) < header_rows: error = state_machine.reporter.error( '%s header row(s) specified but only %s row(s) of data supplied ' '("%s" directive).' % (header_rows, len(rows), name), nodes.literal_block(block_text, block_text), line=lineno) raise SystemMessagePropagation(error) - elif len(rows) == header_rows > 0: + if len(rows) == header_rows > 0: error = state_machine.reporter.error( 'Insufficient data supplied (%s row(s)); no data remaining for ' 'table body, required by "%s" directive.' % (len(rows), name), nodes.literal_block(block_text, block_text), line=lineno) raise SystemMessagePropagation(error) + for row in rows: + if len(row) < stub_columns: + error = state_machine.reporter.error( + '%s stub column(s) specified but only %s columns(s) of data ' + 'supplied ("%s" directive).' % (stub_columns, len(row), name), + nodes.literal_block(block_text, block_text), line=lineno) + raise SystemMessagePropagation(error) + if len(row) == stub_columns > 0: + error = state_machine.reporter.error( + 'Insufficient data supplied (%s columns(s)); no data remaining ' + 'for table body, required by "%s" directive.' + % (len(row), name), + nodes.literal_block(block_text, block_text), line=lineno) + raise SystemMessagePropagation(error) def get_column_widths(max_cols, name, options, lineno, block_text, state_machine): @@ -335,11 +352,14 @@ def list_table(name, arguments, options, content, lineno, table_data = [[item.children for item in row_list[0]] for row_list in node[0]] header_rows = options.get('header-rows', 0) # default 0 + stub_columns = options.get('stub-columns', 0) # default 0 check_table_dimensions( - table_data, header_rows, name, lineno, block_text, state_machine) + table_data, header_rows, stub_columns, name, lineno, + block_text, state_machine) except SystemMessagePropagation, detail: return [detail.args[0]] - table_node = build_table_from_list(table_data, col_widths, header_rows) + table_node = build_table_from_list(table_data, col_widths, + header_rows, stub_columns) table_node['classes'] += options.get('class', []) if title: table_node.insert(0, title) @@ -347,6 +367,7 @@ def list_table(name, arguments, options, content, lineno, list_table.arguments = (0, 1, 1) list_table.options = {'header-rows': directives.nonnegative_int, + 'stub-columns': directives.nonnegative_int, 'widths': directives.positive_int_list, 'class': directives.class_option} list_table.content = 1 @@ -392,12 +413,16 @@ def check_list_content(node, name, options, content, lineno, block_text, raise SystemMessagePropagation(error) return num_cols, col_widths -def build_table_from_list(table_data, col_widths, header_rows): +def build_table_from_list(table_data, col_widths, header_rows, stub_columns): table = nodes.table() tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup for col_width in col_widths: - tgroup += nodes.colspec(colwidth=col_width) + colspec = nodes.colspec(colwidth=col_width) + if stub_columns: + colspec.attributes['stub'] = 1 + stub_columns -= 1 + tgroup += colspec rows = [] for row in table_data: row_node = nodes.row() diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index a44f47027..f779df8b2 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1657,13 +1657,17 @@ class Body(RSTState): line=lineno) return [error] - def build_table(self, tabledata, tableline): - colspecs, headrows, bodyrows = tabledata + def build_table(self, tabledata, tableline, stub_columns=0): + colwidths, headrows, bodyrows = tabledata table = nodes.table() - tgroup = nodes.tgroup(cols=len(colspecs)) + tgroup = nodes.tgroup(cols=len(colwidths)) table += tgroup - for colspec in colspecs: - tgroup += nodes.colspec(colwidth=colspec) + for colwidth in colwidths: + colspec = nodes.colspec(colwidth=colwidth) + if stub_columns: + colspec.attributes['stub'] = 1 + stub_columns -= 1 + tgroup += colspec if headrows: thead = nodes.thead() tgroup += thead diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index af18e2745..27442e6ca 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) + node.parent.stubs.append(node.attributes.get('stub')) def depart_colspec(self, node): pass @@ -603,15 +604,18 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('</em>') def visit_entry(self, node): - if isinstance(node.parent.parent, nodes.thead): + if ( isinstance(node.parent.parent, nodes.thead) + or node.parent.parent.parent.stubs[node.parent.column]): tagname = 'th' else: tagname = 'td' + node.parent.column += 1 atts = {} 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('</%s>\n' % tagname.lower()) if len(node) == 0: # empty cell @@ -1092,6 +1096,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_row(self, node): self.body.append(self.starttag(node, 'tr', '')) + node.column = 0 def depart_row(self, node): self.body.append('</tr>\n') @@ -1249,6 +1254,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.starttag(node, 'colgroup')) # Appended by thead or tbody: self.context.append('</colgroup>\n') + node.stubs = [] def depart_tgroup(self, node): pass -- 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 +- 6 files changed, 48 insertions(+), 103 deletions(-) (limited to 'docutils') 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): -- 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 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'docutils') 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'): -- 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 --- docutils/writers/html4css1.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'docutils') 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 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 --- 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 +-- 21 files changed, 111 insertions(+), 30 deletions(-) (limited to 'docutils') 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:] -- 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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 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 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'docutils') 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): -- 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 --- docutils/parsers/rst/directives/parts.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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 --- docutils/parsers/rst/directives/body.py | 5 +++-- docutils/parsers/rst/directives/parts.py | 7 +++++++ docutils/transforms/parts.py | 4 +--- 3 files changed, 11 insertions(+), 5 deletions(-) (limited to 'docutils') 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'] -- 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 +++++ 1 file changed, 5 insertions(+) (limited to 'docutils') 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) -- 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(-) (limited to 'docutils') 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 --- docutils/nodes.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(+) (limited to 'docutils') 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 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(+) (limited to 'docutils') 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(+) (limited to 'docutils') 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(-) (limited to 'docutils') 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 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 --- docutils/parsers/rst/directives/images.py | 30 +++++++++++++++++++++++++++++- docutils/writers/html4css1.py | 2 ++ 2 files changed, 31 insertions(+), 1 deletion(-) (limited to 'docutils') 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): -- 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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 --- docutils/writers/html4css1.py | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'docutils') 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) -- 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 (limited to 'docutils') 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 --- docutils/examples.py | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'docutils') 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 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 --- docutils/writers/html4css1.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'docutils') 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): -- 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 +- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'docutils') 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 -- 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 --- docutils/writers/html4css1.py | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'docutils') 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]) -- 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 (limited to 'docutils') 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 ae9d340239b7bc97b08f3e0397a6c31ce0bc3919 Mon Sep 17 00:00:00 2001 From: wiemann 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 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docutils') 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() -- cgit v1.2.1 From fa387fdb69c9d4aa34cbcbabae2db046b329cd25 Mon Sep 17 00:00:00 2001 From: wiemann 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 +++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 20 deletions(-) (limited to 'docutils') 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 + # , + # 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') -- cgit v1.2.1 From ce727c88d8d89f9f86275c0d3fca3ae2be392cec Mon Sep 17 00:00:00 2001 From: goodger 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 --- docutils/writers/html4css1.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'docutils') 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 = ('\n\n') - content_type = ('\n') + content_type = ('\n') generator = ('\n') stylesheet_link = '\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, '\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]) -- cgit v1.2.1 From 0d367a20ddf73937c88f48eefe81a9de83649aa9 Mon Sep 17 00:00:00 2001 From: wiemann 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 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'docutils') 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': '', '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()) -- cgit v1.2.1 From 29686d0ea64c4790b23a689f7e1c67a93af6485b Mon Sep 17 00:00:00 2001 From: wiemann 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(-) (limited to 'docutils') 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': '', 'overrides': 'stylesheet'}), - ),) + ('Specify a uesr 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 = {'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 .\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 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 (limited to 'docutils') 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 . 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 . 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 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(-) (limited to 'docutils') 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 = '' self.context.append('') - 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() + '') -- 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(+) (limited to 'docutils') 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 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'docutils') 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) -- 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(+) (limited to 'docutils') 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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(+) (limited to 'docutils') 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 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docutils') 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. -- 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 --- docutils/parsers/rst/directives/images.py | 1 + 1 file changed, 1 insertion(+) (limited to 'docutils') 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, -- 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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 --- docutils/parsers/rst/directives/images.py | 1 - 1 file changed, 1 deletion(-) (limited to 'docutils') 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, -- 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') 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 -- 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 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') 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 -- 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 --- docutils/readers/standalone.py | 13 ++- docutils/transforms/frontmatter.py | 182 +++++++++++++++++++++++++++---------- 2 files changed, 147 insertions(+), 48 deletions(-) (limited to 'docutils') 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): -- 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 --- docutils/readers/standalone.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docutils') 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}), )) -- 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 --- docutils/frontend.py | 3 +++ docutils/nodes.py | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'docutils') 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 -- 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 --- docutils/writers/latex2e.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'docutils') 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 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 +++++--- 2 files changed, 17 insertions(+), 4 deletions(-) (limited to 'docutils') 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: -- 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') 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 -- cgit v1.2.1 From da24d3d9d27f18e38f4bb345f1f9965e985391a8 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> 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(+) (limited to 'docutils') 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 <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') 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 -- cgit v1.2.1 From b7b2f9f3ecf1b3877314db63d09242dfe71b41fc Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> 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 --- docutils/core.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') 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 + <http://docutils.sf.net/docs/user/mailing-lists.html#docutils-develop>. Parameters: -- cgit v1.2.1 From d412180dc51d316654dce051ff669022a07dabc7 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> 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(-) (limited to 'docutils') 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 <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 29 May 2005 12:42:43 +0000 Subject: moved aux. <span> 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 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'docutils') 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('<span id="%s"></span>' % id) + if infix: + # Empty tag. + prefix.append('<span id="%s"></span>' % id) + else: + # Non-empty tag. We place the auxiliary <span> + # tag *inside* the element. + suffix += '<span id="%s"></span>' % id if atts.has_key('id') and tagname in self.named_tags: atts['name'] = atts['id'] # for compatibility with old browsers attlist = atts.items() -- cgit v1.2.1 From c61ca0c471901af237277d5700c4c22b04e4d3d3 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> 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(-) (limited to 'docutils') 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 e10b9dee23a956499f61c0bd3d8a3c4233c754c3 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> 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 --- docutils/parsers/rst/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') 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': '<width>', 'type': 'int', 'default': 8}), + {'metavar': '<width>', '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}), -- cgit v1.2.1 From 78ed5de20eb3c06ef02efd5710145321fc40596f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> 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 --- docutils/__init__.py | 7 ++++--- docutils/core.py | 7 ++++--- docutils/frontend.py | 4 ++-- 3 files changed, 10 insertions(+), 8 deletions(-) (limited to 'docutils') 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 <docutils-users@lists.sf.net>. -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, -- cgit v1.2.1 From c1312b37ba8887cf092065cb09f3d09ee034ac31 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> 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 --- 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 + 18 files changed, 39 insertions(+) (limited to 'docutils') 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', -- cgit v1.2.1 From 19a93281192f747b7b9ebf20da4b779e4ec1c8e1 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> 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(+) (limited to 'docutils') 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 f3bb5b2325061a52c7de10c726defec34e1d893f Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 5 Jun 2005 21:30:29 +0000 Subject: fixed target bug <http://mid.gmane.org/200505291251.j4TCpZP0022378@sheep.berlios.de> git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3437 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') 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): -- cgit v1.2.1 From 94919da6a00f847aa507ec658f7edeb8676381f0 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> 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 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'docutils') 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): -- cgit v1.2.1 From 9061c56e4edac24c8e7adbe7aa6131578af9f040 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> 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 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'docutils') 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 -- 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 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'docutils') 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): -- 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 ++++++++++++++++++------------------------- 1 file changed, 18 insertions(+), 26 deletions(-) (limited to 'docutils') 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): -- 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 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'docutils') 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 -- 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 + 1 file changed, 1 insertion(+) (limited to 'docutils') 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 = '{ }' -- 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 - 1 file changed, 1 deletion(-) (limited to 'docutils') 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 = '{ }' -- 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(-) (limited to 'docutils') 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 --- 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 ++++++++++++------ 20 files changed, 40 insertions(+), 7 deletions(-) (limited to 'docutils') 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 d161fd862fb3bbec9472ee5f9e26e63ef5cac692 Mon Sep 17 00:00:00 2001 From: richieadler 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(-) (limited to 'docutils') 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 8854faf14796e27439bf730aef34b0c4e96546da Mon Sep 17 00:00:00 2001 From: wiemann 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(-) (limited to 'docutils') 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 + # , + # 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 - # , - # 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 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 (limited to 'docutils') 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 +# . +# 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 W3C Software Notice and License. + +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 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(-) (limited to 'docutils') 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 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') 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 -- cgit v1.2.1 From 2052f8691d2367a4280276aac3ea874c666eb23e Mon Sep 17 00:00:00 2001 From: wiemann 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(-) (limited to 'docutils') 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': '', '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 3b7a7200860068db23463a6a4246c19814012ee9 Mon Sep 17 00:00:00 2001 From: goodger 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 --- 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 ++++++ 35 files changed, 2805 insertions(+) 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 (limited to 'docutils') 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:: + +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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 + . + Processed by unicode2rstsubs.py, part of Docutils: + . + +.. |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 -- cgit v1.2.1 From cbc0c71cce99abae907d275148e80e1e8a201881 Mon Sep 17 00:00:00 2001 From: goodger 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 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') 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): -- cgit v1.2.1 From ed1b6c92164e41d468f87eae3cb4b0965431db77 Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 151676b3efb075a4f7524d2e5681e0ccefee8e2b Mon Sep 17 00:00:00 2001 From: wiemann 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(-) (limited to 'docutils') 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 c9bdf0b05fc639f4112d0dfd7538ff63a02c79b5 Mon Sep 17 00:00:00 2001 From: wiemann 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') 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'(? 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 --- docutils/parsers/rst/directives/__init__.py | 26 ++++++++++++++++++++++++++ docutils/parsers/rst/directives/images.py | 4 ++-- docutils/writers/html4css1.py | 10 ++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) (limited to 'docutils') 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 "" (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']) -- cgit v1.2.1 From 31021ff8ab8370d847c7f408bd89e5edff925959 Mon Sep 17 00:00:00 2001 From: wiemann 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(-) (limited to 'docutils') 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 # . # 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 W3C Software Notice and License. -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 70baa3875664998e598f5537ec067826c7143726 Mon Sep 17 00:00:00 2001 From: wiemann 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(-) (limited to 'docutils') 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 d90d048247c7f3012414659a52078b6c8a89765f Mon Sep 17 00:00:00 2001 From: wiemann 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 +++++ 1 file changed, 5 insertions(+) (limited to 'docutils') 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: -- 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 --- docutils/writers/docutils_xml.py | 2 ++ docutils/writers/html4css1.py | 2 ++ 2 files changed, 4 insertions(+) (limited to 'docutils') 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' -- 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') 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'' -- 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(-) (limited to 'docutils') 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 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docutils') 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() -- 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 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'docutils') 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}', -- 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(-) (limited to 'docutils') 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 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 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'docutils') 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: -- 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(-) (limited to 'docutils') 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 --- docutils/writers/html4css1.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docutils') 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 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 --- docutils/writers/html4css1.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'docutils') 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 = [] -- 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 ------- 1 file changed, 7 deletions(-) (limited to 'docutils') 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: -- 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 ++++++--- 3 files changed, 170 insertions(+), 15 deletions(-) (limited to 'docutils') 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): -- 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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 +++++++++----------------------------------------------- 1 file changed, 10 insertions(+), 54 deletions(-) (limited to 'docutils') 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 - -- 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 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 6 deletions(-) (limited to 'docutils') 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 -- 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 +++++++++++++++++++++++++++----------------------------- 1 file changed, 45 insertions(+), 49 deletions(-) (limited to 'docutils') 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 -- 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(-) (limited to 'docutils') 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(+) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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(+) (limited to 'docutils') 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 (limited to 'docutils') 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 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'docutils') 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)) -- 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(-) (limited to 'docutils') 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 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 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'docutils') 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)) -- 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(-) (limited to 'docutils') 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 ++++++ 1 file changed, 6 insertions(+) (limited to 'docutils') 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.""" -- 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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 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(+) (limited to 'docutils') 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 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 --- docutils/frontend.py | 3 ++- docutils/transforms/html.py | 30 ++++++++++++++++++++++++++++++ docutils/writers/html4css1.py | 27 +++++++++++---------------- 3 files changed, 43 insertions(+), 17 deletions(-) create mode 100644 docutils/transforms/html.py (limited to 'docutils') 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'] -- 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 +++------------ 3 files changed, 36 insertions(+), 23 deletions(-) (limited to 'docutils') 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) -- cgit v1.2.1 From 2e400f133f82a1419d816187770c546165d68eab Mon Sep 17 00:00:00 2001 From: blais 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(-) (limited to 'docutils') 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 f0bd13cec3b724e5b23f406d2d5c8bd081b3c2fc Mon Sep 17 00:00:00 2001 From: goodger 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(+) (limited to 'docutils') 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 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(+) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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 (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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 (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 94b4ee517017362ffc7b56ab5ba945c056da1d7a Mon Sep 17 00:00:00 2001 From: wiemann 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(-) (limited to 'docutils') 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 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 +++++++++++++++-------------------------- 1 file changed, 60 insertions(+), 106 deletions(-) (limited to 'docutils') 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))) -- cgit v1.2.1 From f5fe452d38fcd576e79684f83c9916ffaa62277b Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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 +++++++++++++++++---------------------- 3 files changed, 17 insertions(+), 41 deletions(-) (limited to 'docutils') 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 """ - 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, [])) -- cgit v1.2.1 From 992191ceb9e0efbfc0d3249f52966e1261c2bbe3 Mon Sep 17 00:00:00 2001 From: blais 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') 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 -- cgit v1.2.1 From 67bba794ba0290728c6cb0a9d184a2ebc3a278de Mon Sep 17 00:00:00 2001 From: blais 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(-) (limited to 'docutils') 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 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 --- docutils/core.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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 --- docutils/transforms/universal.py | 4 ++-- docutils/writers/html4css1.py | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'docutils') 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 ' - '``abc at example dot org``.', + '``abc@' + 'example.org``.', ['--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('@', '@') + addr = addr.replace('.', '.') + 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 -- cgit v1.2.1 From 4c9becf2db37c07284913497627b7c7a574ce30e Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') 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 -- cgit v1.2.1 From 601958dba675d1a3fc42e35b31782675cb108dce Mon Sep 17 00:00:00 2001 From: goodger 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 da694cfd8f275688b7b4bdac01c6b3691dbf3b41 Mon Sep 17 00:00:00 2001 From: wiemann 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 2703f7c25b10c10f59db93e0776cb81c1d181bca Mon Sep 17 00:00:00 2001 From: wiemann 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 --- docutils/readers/standalone.py | 6 ++- docutils/transforms/misc.py | 75 +++++++++++++++++++++++++++++++++++ docutils/transforms/universal.py | 86 +++------------------------------------- 3 files changed, 84 insertions(+), 83 deletions(-) (limited to 'docutils') 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:: + +
    + ... + +
    + ... + + into this:: + +
    + ... + +
    + ... + """ + 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:: - -
    - ... - -
    - ... - - into this:: - -
    - ... - -
    - ... - """ - 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 -- cgit v1.2.1 From e0a1eaac9d47da79a00c92c74ef7e789464421b7 Mon Sep 17 00:00:00 2001 From: wiemann 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 --- docutils/transforms/__init__.py | 1 + docutils/transforms/misc.py | 43 ++++++++++++++++++++-------------------- docutils/transforms/universal.py | 25 ++++++++++++++++------- 3 files changed, 41 insertions(+), 28 deletions(-) (limited to 'docutils') 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:: + +
    + ... + +
    + ... + + into this:: + +
    + ... + +
    + ... + """ + 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:: - -
    - ... - -
    - ... - - into this:: - -
    - ... - -
    - ... - """ 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): -- cgit v1.2.1 From 88b1bd28140150e41265cd8a84b5d0ee55f05138 Mon Sep 17 00:00:00 2001 From: wiemann 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 --- 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 --------------------------------------- 5 files changed, 81 insertions(+), 81 deletions(-) (limited to 'docutils') 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 -- cgit v1.2.1 From 5d0c3a22119855adddbf210fc607e3944bbad928 Mon Sep 17 00:00:00 2001 From: wiemann 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 c5aecf0e115ab835a4c79657245bcaed911ad41e Mon Sep 17 00:00:00 2001 From: wiemann 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 +++++++++------- 3 files changed, 46 insertions(+), 36 deletions(-) (limited to 'docutils') 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: -- cgit v1.2.1 From ec90f56d02442c7974aaf6177f51cfcf46c816d6 Mon Sep 17 00:00:00 2001 From: wiemann 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(-) (limited to 'docutils') 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('') 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('

    ') 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 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(-) (limited to 'docutils') 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 f7067269fdfeeb21fcd825051da7727a286be988 Mon Sep 17 00:00:00 2001 From: wiemann 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(+) (limited to 'docutils') 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 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(+) (limited to 'docutils') 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 From dbe5d1f505a545190a1ed1adfc7d97772c710e38 Mon Sep 17 00:00:00 2001 From: wiemann 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 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docutils') 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, -- cgit v1.2.1 From 019c9db1733295e6c56937d6a77005dba70b4fb9 Mon Sep 17 00:00:00 2001 From: wiemann 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(-) (limited to 'docutils') 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 dc98554c2fc0308774c70dcebc6fe45617f22e00 Mon Sep 17 00:00:00 2001 From: wiemann 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 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') 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) -- cgit v1.2.1 From 625b851763602bdb417647a4eac9cf2fb0365a2f Mon Sep 17 00:00:00 2001 From: wiemann 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 ++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 29 deletions(-) (limited to 'docutils') 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') -- cgit v1.2.1 From bd5d3204ec71f70e01164372d96230af029fd1c6 Mon Sep 17 00:00:00 2001 From: wiemann 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 --- docutils/writers/newlatex2e.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'docutils') 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 .\n' + 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) @@ -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. -- cgit v1.2.1 From d854c9bf42f3c21b876ad51e3c691def7e072840 Mon Sep 17 00:00:00 2001 From: goodger 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 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'docutils') 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): -- cgit v1.2.1 From 3752c889a0d0bff13b619d9e3c09024a5fd2dbf2 Mon Sep 17 00:00:00 2001 From: wiemann 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(-) (limited to 'docutils') 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 cf82ee9210cd535244ba63ecfad632fb32cad9c0 Mon Sep 17 00:00:00 2001 From: wiemann 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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': '', 'overrides': 'stylesheet'}), - ('Specify a uesr stylesheet file. See --stylesheet.', + ('Specify a user stylesheet file. See --stylesheet.', ['--user-stylesheet'], {'default': '', 'metavar': '', 'overrides': 'user_stylesheet_path'}), -- cgit v1.2.1 From ad22732219501fc1d846564dfd6cc01ddafc4d19 Mon Sep 17 00:00:00 2001 From: wiemann 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 67c57d6128cf805d676bd3ff38a3a8f8a7da274b Mon Sep 17 00:00:00 2001 From: wiemann 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 ++++ 1 file changed, 4 insertions(+) (limited to 'docutils') 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 -- cgit v1.2.1 From 12230a35702461fd90db1254371ad0050b74977e Mon Sep 17 00:00:00 2001 From: wiemann 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 ---- 1 file changed, 4 deletions(-) (limited to 'docutils') 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 -- cgit v1.2.1 From 03f113d5425662822ddb565d627b9c6b39e25aab Mon Sep 17 00:00:00 2001 From: wiemann 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 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'docutils') 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] -- cgit v1.2.1 From 090741b70591dc6209c48d4147167b6d88c578c7 Mon Sep 17 00:00:00 2001 From: goodger 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 --- docutils/parsers/rst/directives/images.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docutils') 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 -- cgit v1.2.1 From 5c90ddc006b36818e727b4a42196a708b2a78a25 Mon Sep 17 00:00:00 2001 From: wiemann 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 --- docutils/core.py | 6 ------ docutils/frontend.py | 3 +-- docutils/writers/html4css1.py | 3 ++- 3 files changed, 3 insertions(+), 9 deletions(-) (limited to 'docutils') 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',) -- cgit v1.2.1 From 166a3c55fa3628d3f16237bd4360b687f5d1cef4 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 25 Aug 2005 17:15:22 +0000 Subject: Moved "id" attribute from container (section etc.) to the 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 --- docutils/writers/html4css1.py | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'docutils') 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('' % id) @@ -328,6 +333,7 @@ class HTMLTranslator(nodes.NodeVisitor): # Non-empty tag. We place the auxiliary # tag *inside* the element. 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() @@ -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('\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('\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('' + close_tag) else: self.context.append(close_tag) @@ -1410,7 +1427,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('') 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): -- cgit v1.2.1 From b67ead9a20e534e7bb5fac07d62a8738ea8e5f46 Mon Sep 17 00:00:00 2001 From: goodger 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 + 1 file changed, 1 insertion(+) (limited to 'docutils') 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 ) + (? 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') 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 ) - (? 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 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docutils') 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': -- cgit v1.2.1 From 19aec1e70c4828d113ff64a12e24afe93df40b6c Mon Sep 17 00:00:00 2001 From: wiemann 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(-) (limited to 'docutils') 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 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 --- docutils/writers/html4css1.py | 52 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-) (limited to 'docutils') 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('\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('\n\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))): -- cgit v1.2.1 From a1b0314ca1358c6730e1795a4fff9746fbc096a4 Mon Sep 17 00:00:00 2001 From: wiemann 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 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils') 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 -- 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(-) (limited to 'docutils') 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(-) (limited to 'docutils') 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 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 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) (limited to 'docutils') 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 = [] -- 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 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'docutils') 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. -- 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 --- docutils/nodes.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'docutils') 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): -- 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 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'docutils') 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): -- 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 ++++++++-------- 5 files changed, 14 insertions(+), 14 deletions(-) (limited to 'docutils') 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 -- 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 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 docutils/transforms/writer_aux.py (limited to 'docutils') 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[:]) -- 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 --- docutils/writers/newlatex2e.py | 53 ++++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 17 deletions(-) (limited to 'docutils') 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') -- 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 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'docutils') 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')) -- 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 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'docutils') 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('}') -- 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 --- docutils/transforms/universal.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'docutils') 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 (limited to 'docutils') 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 ++++ 1 file changed, 4 insertions(+) (limited to 'docutils') 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): -- 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 --- docutils/writers/html4css1.py | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'docutils') 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): """ -- 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 --- 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 +- 12 files changed, 91 insertions(+), 70 deletions(-) (limited to 'docutils') 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 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 --- docutils/transforms/references.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') 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( -- cgit v1.2.1 From f80815602799ff058440771456e212325fd6d2f6 Mon Sep 17 00:00:00 2001 From: goodger 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 --- docutils/parsers/rst/directives/tables.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'docutils') 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 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 --- 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 -------------------- 14 files changed, 4254 insertions(+), 2422 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 (limited to 'docutils') 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': '', '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': '', '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': '', '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'], @@ -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': ''}), + {'default': default_template_path, 'metavar': ''}), ('Python\'s home URL. Default is "http://www.python.org".', ['--python-home'], {'default': 'http://www.python.org', 'metavar': ''}), @@ -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 +% +% 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 +# , 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/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 @@ + + + + + + + + PEP %(pep)s -- %(title)s + %(stylesheet)s + + + + +
    +%(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}$'} -- cgit v1.2.1 From 1515f34b2893338ee40861fbcb102d695db2cba4 Mon Sep 17 00:00:00 2001 From: wiemann 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 (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 +- 7 files changed, 17 insertions(+), 17 deletions(-) (limited to 'docutils') 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[:]) -- 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 --- docutils/parsers/rst/directives/misc.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'docutils') 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 -- 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 --- docutils/nodes.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'docutils') 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'\ ') -- 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 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'docutils') 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') -- cgit v1.2.1 From 5b8e4a4676301f3de183f5683c04e3ba3d4d5131 Mon Sep 17 00:00:00 2001 From: wiemann 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(+) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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': '', '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': '', 'overrides': 'stylesheet'}), + {'metavar': '', 'overrides': 'stylesheet', + 'default': default_stylesheet_path}), ('Specify a user stylesheet file. See --stylesheet.', ['--user-stylesheet'], {'default': '', 'metavar': '', -- cgit v1.2.1 From aebbc5cf69dddc4ccae38c8577ef2ae389a3447e Mon Sep 17 00:00:00 2001 From: grubert 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 --- docutils/writers/latex2e.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docutils') 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 8caecfa4637c4690054d994722b629f5dba32721 Mon Sep 17 00:00:00 2001 From: wiemann 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 --- docutils/nodes.py | 1 - docutils/parsers/rst/states.py | 53 ++++++++++++++++++++++++------------------ 2 files changed, 30 insertions(+), 24 deletions(-) (limited to 'docutils') 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.""" -- cgit v1.2.1 From 8ca484acd7f7fbc2990475a22fb1089b022e5571 Mon Sep 17 00:00:00 2001 From: wiemann 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 --- docutils/nodes.py | 19 +++++++--- docutils/transforms/references.py | 79 ++++++++++++++++++++------------------- 2 files changed, 53 insertions(+), 45 deletions(-) (limited to 'docutils') 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): -- cgit v1.2.1 From 7068fae26ee297f883adf5f884fd64b0892b2a70 Mon Sep 17 00:00:00 2001 From: wiemann 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 --- docutils/parsers/rst/states.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'docutils') 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) -- cgit v1.2.1 From c6e1fdb5efb32575f69e1c0c68cb6715ac896a85 Mon Sep 17 00:00:00 2001 From: wiemann 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 --- docutils/nodes.py | 10 --------- docutils/parsers/rst/states.py | 4 ---- docutils/transforms/references.py | 44 ++++++++++++++++++++++----------------- 3 files changed, 25 insertions(+), 33 deletions(-) (limited to 'docutils') 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 -- cgit v1.2.1 From 5da7532801abf44378d5422760ab68a84bc39fbc Mon Sep 17 00:00:00 2001 From: wiemann 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 --- docutils/writers/html4css1.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') 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' -- 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 --- 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 ++++++ 20 files changed, 53 insertions(+), 2 deletions(-) (limited to 'docutils') 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) -- cgit v1.2.1 From d92350b57c08a3f642a8a2e6147eb999769180f7 Mon Sep 17 00:00:00 2001 From: wiemann 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 --- docutils/languages/es.py | 4 ++-- docutils/languages/zh_tw.py | 2 +- docutils/parsers/rst/languages/es.py | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'docutils') 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$ -- cgit v1.2.1 From f50fd0893b3d46828d2acc46d8aa5c2bfcd9079f Mon Sep 17 00:00:00 2001 From: goodger 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 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'docutils') 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() + '

    \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
    ') + 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')) -- 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(+) (limited to 'docutils') 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(-) (limited to 'docutils') 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 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 --- docutils/transforms/frontmatter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils') 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 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils') 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'),] -- 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 --- docutils/writers/html4css1.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docutils') 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 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 --- docutils/languages/zh_cn.py | 76 ++++++++++++++++++++++ docutils/parsers/rst/languages/zh_cn.py | 108 ++++++++++++++++++++++++++++++++ 2 files changed, 184 insertions(+) create mode 100644 docutils/languages/zh_cn.py create mode 100644 docutils/parsers/rst/languages/zh_cn.py (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 --- docutils/languages/ja.py | 62 +++++++++++++++++++++ docutils/parsers/rst/languages/ja.py | 104 +++++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 docutils/languages/ja.py create mode 100644 docutils/parsers/rst/languages/ja.py (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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 ++++++ 1 file changed, 6 insertions(+) (limited to 'docutils') 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') -- cgit v1.2.1 From c3f2544cb53a69966f3e57aee2e15f51b4acd7f8 Mon Sep 17 00:00:00 2001 From: wiemann 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 ced6843a40a4b84b50b10c1106edfe80e088fbaa Mon Sep 17 00:00:00 2001 From: wiemann 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 --- docutils/parsers/rst/states.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docutils') 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':(?![: ])([^:\\]|\\.)*(?>>( +|$)', '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): -- cgit v1.2.1 From 184c20058d06fae93850e40a6d695b07b680a7cc Mon Sep 17 00:00:00 2001 From: wiemann 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'docutils') 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, -- 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(-) (limited to 'docutils') 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 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(-) (limited to 'docutils') 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 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 --- docutils/parsers/rst/states.py | 14 +++++++++++--- docutils/parsers/rst/tableparser.py | 5 +++++ docutils/statemachine.py | 31 ++++++++++++++++++++++++++++--- docutils/utils.py | 26 ++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 6 deletions(-) (limited to 'docutils') 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: -- cgit v1.2.1 From 118dd3d2aa36cf563590197e28830c1a905f9cd8 Mon Sep 17 00:00:00 2001 From: goodger 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 --- 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 +++++ 32 files changed, 2073 insertions(+), 24 deletions(-) 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 (limited to 'docutils') 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 ' ' (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 = '

    \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('\n' % (h_level)) + 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']: 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/" 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 = {} + 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('

    ', '

    ') + 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')) + 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/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 @@ + + + + + \ 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 = '' + 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' + + '