From: <mi...@us...> - 2011-12-14 23:53:45
|
Revision: 7256 http://docutils.svn.sourceforge.net/docutils/?rev=7256&view=rev Author: milde Date: 2011-12-14 23:53:38 +0000 (Wed, 14 Dec 2011) Log Message: ----------- Clean up record_dependencies feature. Use utf8 encoding for the record file: simple, failsave and reproducible way for portable storage of non-ASCII filenames (cf. http://www.dwheeler.com/essays/fixing-unix-linux-filenames.html). Drop latex2e exception: Record only files required to generate the LaTeX source. Modified Paths: -------------- trunk/docutils/HISTORY.txt trunk/docutils/docs/user/config.txt trunk/docutils/docutils/parsers/rst/directives/images.py trunk/docutils/docutils/parsers/rst/directives/misc.py trunk/docutils/docutils/utils.py trunk/docutils/docutils/writers/html4css1/__init__.py trunk/docutils/docutils/writers/latex2e/__init__.py trunk/docutils/test/data/dependencies.txt trunk/docutils/test/test_dependencies.py Modified: trunk/docutils/HISTORY.txt =================================================================== --- trunk/docutils/HISTORY.txt 2011-12-14 19:14:33 UTC (rev 7255) +++ trunk/docutils/HISTORY.txt 2011-12-14 23:53:38 UTC (rev 7256) @@ -32,8 +32,8 @@ * docutils/utils.py - - DependencyList uses io.FileOutput to prevent errors recording - non-ASCII filenames (fixes [ 3434355 ]. + - DependencyList uses io.FileOutput and 'utf8' encoding to prevent + errors recording non-ASCII filenames (fixes [ 3434355 ]. * docutils/parsers/rst/states.py @@ -48,6 +48,7 @@ * docutils/writers/latex2e/__init__.py - Support the `abbreviation` and `acronym` standard roles. + - Record only files required to generate the LaTeX source as dependencies. * docutils/writers/html4css1/__init__.py Modified: trunk/docutils/docs/user/config.txt =================================================================== --- trunk/docutils/docs/user/config.txt 2011-12-14 19:14:33 UTC (rev 7255) +++ trunk/docutils/docs/user/config.txt 2011-12-14 23:53:38 UTC (rev 7256) @@ -387,14 +387,24 @@ --output-encoding, -o``. _`record_dependencies` - Path to a file where Docutils will write a list of files that the - input and output depend on [#dependencies]_, e.g. due to file - inclusion. [#pwd]_ The format is one filename per line. This - option is particularly useful in conjunction with programs like - ``make``. + Path to a file where Docutils will write a list of files that were + required to generate the output, e.g. included files or embedded + stylesheets [#dependencies]_. [#pwd]_ The format is one path per + line with forward slashes as separator, the encoding is ``utf8``. Set to ``-`` in order to write dependencies to stdout. + This option is particularly useful in conjunction with programs like + ``make`` using ``Makefile`` rules like:: + + ham.html: ham.txt $(shell cat hamdeps.txt) + rst2html.py --record-dependencies=hamdeps.txt ham.txt ham.html + + If the filesystem encoding differs from utf8, replace the ``cat`` + command with a call to a converter, e.g.:: + + $(shell iconv -f utf8 -t latin1 hamdeps.txt) + Default: None. Option: ``--record-dependencies``. _`report_level` @@ -1436,20 +1446,9 @@ do the overriding explicitly, by assigning ``None`` to the other settings. -.. [#dependencies] Some notes on the dependency recorder: +.. [#dependencies] Images are only added to the dependency list if the + reStructuredText parser extracted image dimensions from the file. - * Images are only added to the dependency list if the - reStructuredText parser extracted image dimensions from the file. - - * Stylesheets are only added if they are embedded. - - * For practical reasons, the output of the LaTeX writer is - considered merely an *intermediate* processing stage. The - dependency recorder records all files the *rendered* file - (e.g. in PDF or DVI format) depends on. Thus, images and - stylesheets are both unconditionally recorded as dependencies - when using the LaTeX writer. - .. [#footnote_space] The footnote space is trimmed if the reference style is "superscript", and it is left if the reference style is "brackets". Modified: trunk/docutils/docutils/parsers/rst/directives/images.py =================================================================== --- trunk/docutils/docutils/parsers/rst/directives/images.py 2011-12-14 19:14:33 UTC (rev 7255) +++ trunk/docutils/docutils/parsers/rst/directives/images.py 2011-12-14 23:53:38 UTC (rev 7256) @@ -10,18 +10,22 @@ import sys +import urllib from docutils import nodes, utils from docutils.parsers.rst import Directive from docutils.parsers.rst import directives, states from docutils.nodes import fully_normalize_name, whitespace_normalize_name from docutils.parsers.rst.roles import set_classes - -try: - import Image as PIL # PIL +try: # check for the Python Imaging Library + import PIL except ImportError: - PIL = None + try: # sometimes PIL modules are put in PYTHONPATH's root + import Image + class PIL(object): pass # dummy wrapper + PIL.Image = Image + except ImportError: + PIL = None - class Image(Directive): align_h_values = ('left', 'center', 'right') @@ -121,15 +125,17 @@ figure_node = nodes.figure('', image_node) if figwidth == 'image': if PIL and self.state.document.settings.file_insertion_enabled: - # PIL doesn't like Unicode paths: + imagepath = urllib.url2pathname(image_node['uri']) try: - i = PIL.open(str(image_node['uri'])) - except (IOError, UnicodeError): - pass + img = PIL.Image.open( + imagepath.encode(sys.getfilesystemencoding())) + except (IOError, UnicodeEncodeError): + pass # TODO: warn? else: self.state.document.settings.record_dependencies.add( - image_node['uri']) - figure_node['width'] = i.size[0] + imagepath.replace('\\', '/')) + figure_node['width'] = img.size[0] + del img elif figwidth is not None: figure_node['width'] = figwidth if figclasses: Modified: trunk/docutils/docutils/parsers/rst/directives/misc.py =================================================================== --- trunk/docutils/docutils/parsers/rst/directives/misc.py 2011-12-14 19:14:33 UTC (rev 7255) +++ trunk/docutils/docutils/parsers/rst/directives/misc.py 2011-12-14 23:53:38 UTC (rev 7256) @@ -198,12 +198,14 @@ self.options['file'])) path = utils.relative_path(None, path) try: - self.state.document.settings.record_dependencies.add(path) raw_file = io.FileInput( source_path=path, encoding=encoding, error_handler=(self.state.document.settings.\ input_encoding_error_handler), handle_io_errors=None) + # TODO: currently, raw input files are recorded as + # dependencies even if not used for the chosen output format. + self.state.document.settings.record_dependencies.add(path) except IOError, error: raise self.severe(u'Problems with "%s" directive path:\n%s.' % (self.name, ErrorString(error))) Modified: trunk/docutils/docutils/utils.py =================================================================== --- trunk/docutils/docutils/utils.py 2011-12-14 19:14:33 UTC (rev 7255) +++ trunk/docutils/docutils/utils.py 2011-12-14 23:53:38 UTC (rev 7256) @@ -662,7 +662,7 @@ return taglist -class DependencyList: +class DependencyList(object): """ List of dependencies, with file recording support. @@ -699,9 +699,7 @@ else: of = output_file self.file = FileOutput(destination_path=of, - encoding=sys.getfilesystemencoding(), - error_handler='xmlcharrefreplace', - autoclose=False) + encoding='utf8', autoclose=False) else: self.file = None @@ -725,8 +723,8 @@ self.file = None def __repr__(self): - if self.file: + try: output_file = self.file.name - else: + except AttributeError: output_file = None return '%s(%r, %s)' % (self.__class__.__name__, output_file, self.list) Modified: trunk/docutils/docutils/writers/html4css1/__init__.py =================================================================== --- trunk/docutils/docutils/writers/html4css1/__init__.py 2011-12-14 19:14:33 UTC (rev 7255) +++ trunk/docutils/docutils/writers/html4css1/__init__.py 2011-12-14 23:53:38 UTC (rev 7256) @@ -19,10 +19,16 @@ import os.path import time import re -try: - import Image # check for the Python Imaging Library +import urllib +try: # check for the Python Imaging Library + import PIL except ImportError: - Image = None + try: # sometimes PIL modules are put in PYTHONPATH's root + import Image + class PIL(object): pass # dummy wrapper + PIL.Image = Image + except ImportError: + PIL = None import docutils from docutils import frontend, nodes, utils, writers, languages, io from docutils.transforms import writer_aux @@ -286,10 +292,10 @@ styles = [utils.relative_path(settings._destination, sheet) for sheet in styles] if settings.embed_stylesheet: - settings.record_dependencies.add(*styles) self.stylesheet = [self.embedded_stylesheet % io.FileInput(source_path=sheet, encoding='utf-8').read() for sheet in styles] + settings.record_dependencies.add(*styles) else: # link to stylesheets self.stylesheet = [self.stylesheet_link % self.encode(stylesheet) for stylesheet in styles] @@ -1006,18 +1012,22 @@ if 'height' in node: atts['height'] = node['height'] if 'scale' in node: - if Image and not ('width' in node and 'height' in node): + if (PIL and not ('width' in node and 'height' in node) + and self.settings.file_insertion_enabled): + imagepath = urllib.url2pathname(uri) try: - im = Image.open(str(uri)) - except (IOError, # Source image can't be found or opened - UnicodeError): # PIL doesn't like Unicode paths. - pass + img = PIL.Image.open( + imagepath.encode(sys.getfilesystemencoding())) + except (IOError, UnicodeEncodeError): + pass # TODO: warn? else: + self.settings.record_dependencies.add( + imagepath.replace('\\', '/')) if 'width' not in atts: - atts['width'] = str(im.size[0]) + atts['width'] = str(img.size[0]) if 'height' not in atts: - atts['height'] = str(im.size[1]) - del im + atts['height'] = str(img.size[1]) + del img for att_name in 'width', 'height': if att_name in atts: match = re.match(r'([0-9.]+)(\S*)$', atts[att_name]) Modified: trunk/docutils/docutils/writers/latex2e/__init__.py =================================================================== --- trunk/docutils/docutils/writers/latex2e/__init__.py 2011-12-14 19:14:33 UTC (rev 7255) +++ trunk/docutils/docutils/writers/latex2e/__init__.py 2011-12-14 23:53:38 UTC (rev 7256) @@ -1284,6 +1284,8 @@ # Unicode chars that are not recognized by LaTeX's utf8 encoding unsupported_unicode_chars = { 0x00A0: ur'~', # NO-BREAK SPACE + # TODO: ensure white space also at the beginning of a line? + # 0x00A0: ur'\leavevmode\nobreak\vadjust{}~' 0x00AD: ur'\-', # SOFT HYPHEN # 0x2008: ur'\,', # PUNCTUATION SPACE @@ -2225,9 +2227,8 @@ def visit_image(self, node): self.requirements['graphicx'] = self.graphicx_package attrs = node.attributes - # Convert image URI to a local file path and add to dependency list + # Convert image URI to a local file path imagepath = urllib.url2pathname(attrs['uri']).replace('\\', '/') - self.settings.record_dependencies.add(imagepath) # alignment defaults: if not 'align' in attrs: # Set default align of image in a figure to 'center' Modified: trunk/docutils/test/data/dependencies.txt =================================================================== --- trunk/docutils/test/data/dependencies.txt 2011-12-14 19:14:33 UTC (rev 7255) +++ trunk/docutils/test/data/dependencies.txt 2011-12-14 23:53:38 UTC (rev 7256) @@ -1,10 +1,29 @@ -.. image:: some_image.png +Test input for test_dependencies. +Docutils can write a list of files required to generate the output like +included files or embedded stylesheets. This is particularly useful in +conjunction with programs like ``make``. + +Included files are recorded: + .. include:: include.txt .. raw:: HTML :file: raw.txt +Dependencies are recorded only once: + .. include:: include.txt -.. image:: картина.jpg +Image files are only recorded, if actually accessed +(to extract the size or if embedded in the output document): + +.. image:: test.jpg + +.. figure:: ../docs/user/rst/images/title.png + :figwidth: image + +Scaled images without given size are recorded by the html writer: + +.. image:: ../docs/user/rst/images/biohazard.png + :scale: 50 % Modified: trunk/docutils/test/test_dependencies.py =================================================================== --- trunk/docutils/test/test_dependencies.py 2011-12-14 19:14:33 UTC (rev 7255) +++ trunk/docutils/test/test_dependencies.py 2011-12-14 23:53:38 UTC (rev 7256) @@ -15,79 +15,108 @@ import docutils.core import docutils.utils import docutils.io +from docutils.parsers.rst.directives.images import PIL +# docutils.utils.DependencyList records POSIX paths, +# i.e. "/" as a path separator even on Windows (not os.path.join). +paths = {'include': u'data/include.txt', # included rst file + 'raw': u'data/raw.txt', # included raw "HTML file" + 'scaled-image': u'../docs/user/rst/images/biohazard.png', + 'figure-image': u'../docs/user/rst/images/title.png', + 'stylesheet': u'data/stylesheet.txt', + 'default-stylesheet': u'../docutils/writers/html4css1/html4css1.css', + } + class RecordDependenciesTests(unittest.TestCase): - # docutils.utils.DependencyList records relative URLs, not platform paths, - # so use "/" as a path separator even on Windows (not os.path.join). - def get_record(self, **settings): recordfile = 'record.txt' + recorder = docutils.utils.DependencyList(recordfile) + # (Re) create the record file by running a conversion: settings.setdefault('source_path', os.path.join('data', 'dependencies.txt')) settings.setdefault('settings_overrides', {}) - settings['settings_overrides'] = settings['settings_overrides'].copy() - settings['settings_overrides']['_disable_config'] = 1 - if 'record_dependencies' not in settings['settings_overrides']: - settings['settings_overrides']['record_dependencies'] = \ - docutils.utils.DependencyList(recordfile) - docutils.core.publish_file( - destination=DocutilsTestSupport.DevNull(), **settings) - settings['settings_overrides']['record_dependencies'].close() + settings['settings_overrides'].update(_disable_config=True, + record_dependencies=recorder) + docutils.core.publish_file(destination=DocutilsTestSupport.DevNull(), + **settings) + recorder.close() + # Read the record file: record = docutils.io.FileInput(source_path=recordfile, encoding='utf8') return record.read().splitlines() def test_dependencies(self): - self.assertEqual(self.get_record(), - ['data/include.txt', 'data/raw.txt']) - self.assertEqual(self.get_record(writer_name='latex'), - ['data/include.txt', - 'data/raw.txt', - # this is a URL, not a path: - 'some_image.png', - # cyrillic filename (testing with an image, because - # this does not abort if the file does not exist): - u'\u043a\u0430\u0440\u0442\u0438\u043d\u0430.jpg']) + # Note: currently, raw input files are read (and hence recorded) while + # parsing even if not used in the chosen output format. + # This should change (see parsers/rst/directives/misc.py). + keys = ['include', 'raw'] + if PIL: + keys += ['figure-image'] + expected = [paths[key] for key in keys] + record = self.get_record(writer_name='xml') + # the order of the files is arbitrary + record.sort() + expected.sort() + self.assertEqual(record, expected) + def test_dependencies_html(self): + keys = ['include', 'raw', 'default-stylesheet'] + if PIL: + keys += ['figure-image', 'scaled-image'] + expected = [paths[key] for key in keys] + record = self.get_record(writer_name='html') + # the order of the files is arbitrary + record.sort() + expected.sort() + self.assertEqual(record, expected) + + def test_dependencies_latex(self): + # since 0.9, the latex writer records only really accessed files, too + # Note: currently, raw input files are read (and hence recorded) while + # parsing even if not used in the chosen output format. + # This should change (see parsers/rst/directives/misc.py). + keys = ['include', 'raw'] + if PIL: + keys += ['figure-image'] + expected = [paths[key] for key in keys] + record = self.get_record(writer_name='latex') + # the order of the files is arbitrary + record.sort() + expected.sort() + self.assertEqual(record, expected) + def test_csv_dependencies(self): try: import csv - self.assertEqual( - self.get_record(source_path=os.path.join('data', - 'csv_dep.txt')), - ['data/csv_data.txt']) + csvsource = os.path.join('data', 'csv_dep.txt') + self.assertEqual(self.get_record(source_path=csvsource), + ['data/csv_data.txt']) except ImportError: pass def test_stylesheet_dependencies(self): - # Parameters to publish_file. - s = {'settings_overrides': {}} - so = s['settings_overrides'] - so['embed_stylesheet'] = 0 - # must use '/', not os.sep or os.path.join, because of URL handling - # (see docutils.utils.relative_path): - stylesheet_path = 'data/stylesheet.txt' - so['stylesheet_path'] = stylesheet_path - so['stylesheet'] = None - s['writer_name'] = 'html' - record = self.get_record(**s) - self.assert_(stylesheet_path not in record, - '%r should not be in %r' % (stylesheet_path, record)) - so['embed_stylesheet'] = 1 - record = self.get_record(**s) - self.assert_(stylesheet_path in record, - '%r should be in %r' % (stylesheet_path, record)) - s['writer_name'] = 'latex' - record = self.get_record(**s) - self.assert_(stylesheet_path in record, - '%r should be in %r' % (stylesheet_path, record)) - del so['embed_stylesheet'] - record = self.get_record(**s) - self.assert_(stylesheet_path not in record, - '%r should not be in %r' % (stylesheet_path, record)) + stylesheet = paths['stylesheet'] + so = {'stylesheet_path': paths['stylesheet'], + 'stylesheet': None} + so['embed_stylesheet'] = False + record = self.get_record(writer_name='html', settings_overrides=so) + self.assert_(stylesheet not in record, + '%r should not be in %r' % (stylesheet, record)) + record = self.get_record(writer_name='latex', settings_overrides=so) + self.assert_(stylesheet not in record, + '%r should not be in %r' % (stylesheet, record)) + so['embed_stylesheet'] = True + record = self.get_record(writer_name='html', settings_overrides=so) + self.assert_(stylesheet in record, + '%r should be in %r' % (stylesheet, record)) + record = self.get_record(writer_name='latex', settings_overrides=so) + self.assert_(stylesheet in record, + '%r should be in %r' % (stylesheet, record)) + + if __name__ == '__main__': unittest.main() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mi...@us...> - 2011-12-20 14:14:33
|
Revision: 7267 http://docutils.svn.sourceforge.net/docutils/?rev=7267&view=rev Author: milde Date: 2011-12-20 14:14:21 +0000 (Tue, 20 Dec 2011) Log Message: ----------- docutils.utils is now a package (providing a place for sub-modules) important:: docutils/math, docutils/error_reporting.py, and docutils/urischemes.py will move to the utils package in the next release, too. Code importing these modules needs to adapt. Modified Paths: -------------- trunk/docutils/HISTORY.txt trunk/docutils/RELEASE-NOTES.txt trunk/docutils/docutils/__init__.py trunk/docutils/docutils/parsers/rst/directives/body.py trunk/docutils/docutils/parsers/rst/roles.py trunk/docutils/docutils/parsers/rst/states.py trunk/docutils/setup.py trunk/docutils/test/test_parsers/test_rst/test_directives/test_code.py trunk/docutils/test/test_parsers/test_rst/test_directives/test_code_long.py trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py trunk/docutils/test/test_parsers/test_rst/test_interpreted.py trunk/docutils/test/test_utils.py Added Paths: ----------- trunk/docutils/docutils/utils/ trunk/docutils/docutils/utils/__init__.py trunk/docutils/docutils/utils/code_analyzer.py trunk/docutils/docutils/utils/punctuation_chars.py Removed Paths: ------------- trunk/docutils/docutils/parsers/code_analyzer.py trunk/docutils/docutils/parsers/rst/punctuation_chars.py trunk/docutils/docutils/utils.py Modified: trunk/docutils/HISTORY.txt =================================================================== --- trunk/docutils/HISTORY.txt 2011-12-20 09:36:10 UTC (rev 7266) +++ trunk/docutils/HISTORY.txt 2011-12-20 14:14:21 UTC (rev 7267) @@ -30,8 +30,15 @@ - Fix [ 3395948 ] (Work around encoding problems in Py3k). -* docutils/utils.py +* docutils/utils.py -> docutils/utils/__init__.py + - docutils.utils is now a package (providing a place for sub-modules) + + .. important:: docutils/math, docutils/error_reporting.py, and + docutils/urischemes.py will move to the utils package in the next + release, too. Code importing these modules needs to adapt + (``import docutils.math`` -> ``import docutils.utils.math``, etc.). + - DependencyList uses io.FileOutput and 'utf8' encoding to prevent errors recording non-ASCII filenames (fixes [ 3434355 ]. @@ -60,11 +67,11 @@ * General: - Fix [ 3364658 ] (Change last file with Apache license to BSD-2-Clause) - and [ 3395920 ] (correct copyright info for rst.el). - + and [ 3395920 ] (correct copyright info for rst.el). + * docutils/test/ - - Apply [ 3303733 ] and [ 3365041 ] to fix tests under py3k. + - Apply [ 3303733 ] and [ 3365041 ] to fix tests under py3k. * docutils/writers/latex2e/__init__.py @@ -95,7 +102,7 @@ - Most directives now support a "name" option that attaches a reference name. - + - Directive content may start on the first line also when the directive type accepts options. Modified: trunk/docutils/RELEASE-NOTES.txt =================================================================== --- trunk/docutils/RELEASE-NOTES.txt 2011-12-20 09:36:10 UTC (rev 7266) +++ trunk/docutils/RELEASE-NOTES.txt 2011-12-20 14:14:21 UTC (rev 7267) @@ -28,11 +28,24 @@ .. _Pygments: http://pygments.org/ +* docutils/utils.py -> docutils/utils/__init__.py + + - docutils.utils is now a package (providing a place for sub-modules) + + .. important:: docutils/math, docutils/error_reporting.py, and + docutils/urischemes.py will move to the utils package in the next + release, too. Code importing these modules needs to adapt + (``import docutils.math`` -> ``import docutils.utils.math``, etc.). + * docutils/writers/html4css1/__init__.py - change default for `math-output` setting to MathJax +* docutils/writers/latex2e/__init__.py + - Record only files required to generate the LaTeX source as dependencies. + + Release 0.8.1 (2011-08-30) ========================== Modified: trunk/docutils/docutils/__init__.py =================================================================== --- trunk/docutils/docutils/__init__.py 2011-12-20 09:36:10 UTC (rev 7266) +++ trunk/docutils/docutils/__init__.py 2011-12-20 14:14:21 UTC (rev 7267) @@ -29,9 +29,6 @@ - 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. @@ -44,6 +41,9 @@ - transforms: Modules used by readers and writers to modify DPS doctrees. +- utils: Contains the ``Reporter`` system warning class and miscellaneous + utilities used by readers, writers, and transforms. + - writers: Format-specific output translators. """ Deleted: trunk/docutils/docutils/parsers/code_analyzer.py =================================================================== --- trunk/docutils/docutils/parsers/code_analyzer.py 2011-12-20 09:36:10 UTC (rev 7266) +++ trunk/docutils/docutils/parsers/code_analyzer.py 2011-12-20 14:14:21 UTC (rev 7267) @@ -1,134 +0,0 @@ -#!/usr/bin/python -# coding: utf-8 - -"""Lexical analysis of formal languages (i.e. code) using Pygments.""" - -# :Author: Georg Brandl; Felix Wiemann; Günter Milde -# :Date: $Date$ -# :Copyright: This module has been placed in the public domain. - -from docutils import ApplicationError -try: - import pygments - from pygments.lexers import get_lexer_by_name - from pygments.formatters.html import _get_ttype_class - with_pygments = True -except ImportError: - with_pygments = False - -# Filter the following token types from the list of class arguments: -unstyled_tokens = ['token', # Token (base token type) - 'text', # Token.Text - ''] # short name for Token and Text -# (Add, e.g., Token.Punctuation with ``unstyled_tokens += 'punctuation'``.) - -class LexerError(ApplicationError): - pass - -class Lexer(object): - """Parse `code` lines and yield "classified" tokens. - - Arguments - - code -- string of source code to parse, - language -- formal language the code is written in, - tokennames -- either 'long', 'short', or '' (see below). - - Merge subsequent tokens of the same token-type. - - Iterating over an instance yields the tokens as ``(tokentype, value)`` - tuples. The value of `tokennames` configures the naming of the tokentype: - - 'long': downcased full token type name, - 'short': short name defined by pygments.token.STANDARD_TYPES - (= class argument used in pygments html output), - 'none': skip lexical analysis. - """ - - def __init__(self, code, language, tokennames='short'): - """ - Set up a lexical analyzer for `code` in `language`. - """ - self.code = code - self.language = language - self.tokennames = tokennames - self.lexer = None - # get lexical analyzer for `language`: - if language in ('', 'text') or tokennames == 'none': - return - if not with_pygments: - raise LexerError('Cannot analyze code. ' - 'Pygments package not found.') - try: - self.lexer = get_lexer_by_name(self.language) - except pygments.util.ClassNotFound: - raise LexerError('Cannot analyze code. ' - 'No Pygments lexer found for "%s".' % language) - - # Since version 1.2. (released Jan 01, 2010) Pygments has a - # TokenMergeFilter. However, this requires Python >= 2.4. When Docutils - # requires same minimal version, ``self.merge(tokens)`` in __iter__ can - # be replaced by ``self.lexer.add_filter('tokenmerge')`` in __init__. - def merge(self, tokens): - """Merge subsequent tokens of same token-type. - - Also strip the final newline (added by pygments). - """ - tokens = iter(tokens) - (lasttype, lastval) = tokens.next() - for ttype, value in tokens: - if ttype is lasttype: - lastval += value - else: - yield(lasttype, lastval) - (lasttype, lastval) = (ttype, value) - if lastval.endswith('\n'): - lastval = lastval[:-1] - if lastval: - yield(lasttype, lastval) - - def __iter__(self): - """Parse self.code and yield "classified" tokens. - """ - if self.lexer is None: - yield ([], self.code) - return - tokens = pygments.lex(self.code, self.lexer) - for tokentype, value in self.merge(tokens): - if self.tokennames == 'long': # long CSS class args - classes = str(tokentype).lower().split('.') - else: # short CSS class args - classes = [_get_ttype_class(tokentype)] - classes = [cls for cls in classes if cls not in unstyled_tokens] - yield (classes, value) - - -class NumberLines(object): - """Insert linenumber-tokens at the start of every code line. - - Arguments - - tokens -- iterable of ``(classes, value)`` tuples - startline -- first line number - endline -- last line number - - Iterating over an instance yields the tokens with a - ``(['ln'], '<the line number>')`` token added for every code line. - Multi-line tokens are splitted.""" - - def __init__(self, tokens, startline, endline): - self.tokens = tokens - self.startline = startline - # pad linenumbers, e.g. endline == 100 -> fmt_str = '%3d ' - self.fmt_str = '%%%dd ' % len(str(endline)) - - def __iter__(self): - lineno = self.startline - yield (['ln'], self.fmt_str % lineno) - for ttype, value in self.tokens: - lines = value.split('\n') - for line in lines[:-1]: - yield (ttype, line + '\n') - lineno += 1 - yield (['ln'], self.fmt_str % lineno) - yield (ttype, lines[-1]) Modified: trunk/docutils/docutils/parsers/rst/directives/body.py =================================================================== --- trunk/docutils/docutils/parsers/rst/directives/body.py 2011-12-20 09:36:10 UTC (rev 7266) +++ trunk/docutils/docutils/parsers/rst/directives/body.py 2011-12-20 14:14:21 UTC (rev 7267) @@ -16,7 +16,7 @@ from docutils.parsers.rst import Directive from docutils.parsers.rst import directives from docutils.parsers.rst.roles import set_classes -from docutils.parsers.code_analyzer import Lexer, LexerError, NumberLines +from docutils.utils.code_analyzer import Lexer, LexerError, NumberLines class BasePseudoSection(Directive): Deleted: trunk/docutils/docutils/parsers/rst/punctuation_chars.py =================================================================== --- trunk/docutils/docutils/parsers/rst/punctuation_chars.py 2011-12-20 09:36:10 UTC (rev 7266) +++ trunk/docutils/docutils/parsers/rst/punctuation_chars.py 2011-12-20 14:14:21 UTC (rev 7267) @@ -1,211 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf8 -*- -# :Copyright: © 2011 Günter Milde. -# :License: Released under the terms of the `2-Clause BSD license`_, in short: -# -# Copying and distribution of this file, with or without modification, -# are permitted in any medium without royalty provided the copyright -# notice and this notice are preserved. -# This file is offered as-is, without any warranty. -# -# .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause - -# :Id: $Id$ - -import sys, re -import unicodedata - -# punctuation characters around inline markup -# =========================================== -# -# This module provides the lists of characters for the implementation of -# the `inline markup recognition rules`_ in the reStructuredText parser -# (states.py) -# -# .. _inline markup recognition rules: -# ../../../docs/ref/rst/restructuredtext.html#inline-markup - -# Docutils punctuation category sample strings -# -------------------------------------------- -# -# The sample strings are generated by punctuation_samples() and put here -# literal to avoid the time-consuming generation with every Docutils -# run. Running this file as a standalone module checks the definitions below -# against a re-calculation. - -openers = ur"""\"\'\(\<\[\{༺༼᚛⁅⁽₍〈❨❪❬❮❰❲❴⟅⟦⟨⟪⟬⟮⦃⦅⦇⦉⦋⦍⦏⦑⦓⦕⦗⧘⧚⧼⸢⸤⸦⸨〈《「『【〔〖〘〚〝〝﴾︗︵︷︹︻︽︿﹁﹃﹇﹙﹛﹝([{⦅「«‘“‹⸂⸄⸉⸌⸜⸠‚„»’”›⸃⸅⸊⸍⸝⸡‛‟""" -closers = ur"""\"\'\)\>\]\}༻༽᚜⁆⁾₎〉❩❫❭❯❱❳❵⟆⟧⟩⟫⟭⟯⦄⦆⦈⦊⦌⦎⦐⦒⦔⦖⦘⧙⧛⧽⸣⸥⸧⸩〉》」』】〕〗〙〛〞〟﴿︘︶︸︺︼︾﹀﹂﹄﹈﹚﹜﹞)]}⦆」»’”›⸃⸅⸊⸍⸝⸡‛‟«‘“‹⸂⸄⸉⸌⸜⸠‚„""" -delimiters = ur"\-\/\:֊־᐀᠆‐‑‒–—―⸗⸚〜〰゠︱︲﹘﹣-¡·¿;·՚՛՜՝՞՟։׀׃׆׳״؉؊،؍؛؞؟٪٫٬٭۔܀܁܂܃܄܅܆܇܈܉܊܋܌܍߷߸߹࠰࠱࠲࠳࠴࠵࠶࠷࠸࠹࠺࠻࠼࠽࠾।॥॰෴๏๚๛༄༅༆༇༈༉༊་༌།༎༏༐༑༒྅࿐࿑࿒࿓࿔၊။၌၍၎၏჻፡።፣፤፥፦፧፨᙭᙮᛫᛬᛭᜵᜶។៕៖៘៙៚᠀᠁᠂᠃᠄᠅᠇᠈᠉᠊᥄᥅᧞᧟᨞᨟᪠᪡᪢᪣᪤᪥᪦᪨᪩᪪᪫᪬᪭᭚᭛᭜᭝᭞᭟᭠᰻᰼᰽᰾᰿᱾᱿᳓‖‗†‡•‣․‥…‧‰‱′″‴‵‶‷‸※‼‽‾⁁⁂⁃⁇⁈⁉⁊⁋⁌⁍⁎⁏⁐⁑⁓⁕⁖⁗⁘⁙⁚⁛⁜⁝⁞⳹⳺⳻⳼⳾⳿⸀⸁⸆⸇⸈⸋⸎⸏⸐⸑⸒⸓⸔⸕⸖⸘⸙⸛⸞⸟⸪⸫⸬⸭⸮⸰⸱、。〃〽・꓾꓿꘍꘎꘏꙳꙾꛲꛳꛴꛵꛶꛷꡴꡵꡶꡷꣎꣏꣸꣹꣺꤮꤯꥟꧁꧂꧃꧄꧅꧆꧇꧈꧉꧊꧋꧌꧍꧞꧟꩜꩝꩞꩟꫞꫟꯫︐︑︒︓︔︕︖︙︰﹅﹆﹉﹊﹋﹌﹐﹑﹒﹔﹕﹖﹗﹟﹠﹡﹨﹪﹫!"#%&'*,./:;?@\。、・𐄀𐄁𐎟𐏐𐡗𐤟𐤿𐩐𐩑𐩒𐩓𐩔𐩕𐩖𐩗𐩘𐩿𐬹𐬺𐬻𐬼𐬽𐬾𐬿𑂻𑂼𑂾𑂿𑃀𑃁𒑰𒑱𒑲𒑳" -closing_delimiters = ur"\.\,\;\!\?" - - -# Unicode punctuation character categories -# ---------------------------------------- - -unicode_punctuation_categories = { - # 'Pc': 'Connector', # not used in Docutils inline markup recognition - 'Pd': 'Dash', - 'Ps': 'Open', - 'Pe': 'Close', - 'Pi': 'Initial quote', # may behave like Ps or Pe depending on usage - 'Pf': 'Final quote', # may behave like Ps or Pe depending on usage - 'Po': 'Other' - } -"""Unicode character categories for punctuation""" - - -# generate character pattern strings -# ================================== - -def unicode_charlists(categories, cp_min=0, cp_max=None): - """Return dictionary of Unicode character lists. - - For each of the `catagories`, an item contains a list with all Unicode - characters with `cp_min` <= code-point <= `cp_max` that belong to the - category. (The default values check every code-point supported by Python.) - """ - # Determine highest code point with one of the given categories - # (may shorten the search time considerably if there are many - # categories with not too high characters): - if cp_max is None: - cp_max = max(x for x in xrange(sys.maxunicode + 1) - if unicodedata.category(unichr(x)) in categories) - # print cp_max # => 74867 for unicode_punctuation_categories - charlists = {} - for cat in categories: - charlists[cat] = [unichr(x) for x in xrange(cp_min, cp_max+1) - if unicodedata.category(unichr(x)) == cat] - return charlists - - -# Character categories in Docutils -# -------------------------------- - -def punctuation_samples(): - - """Docutils punctuation category sample strings. - - Return list of sample strings for the categories "Open", "Close", - "Delimiters" and "Closing-Delimiters" used in the `inline markup - recognition rules`_. - """ - - # Lists with characters in Unicode punctuation character categories - cp_min = 160 # ASCII chars have special rules for backwards compatibility - ucharlists = unicode_charlists(unicode_punctuation_categories, cp_min) - - # match opening/closing characters - # -------------------------------- - # Rearange the lists to ensure matching characters at the same - # index position. - - # low quotation marks are also used as closers (e.g. in Greek) - # move them to category Pi: - ucharlists['Ps'].remove(u'‚') # 201A SINGLE LOW-9 QUOTATION MARK - ucharlists['Ps'].remove(u'„') # 201E DOUBLE LOW-9 QUOTATION MARK - ucharlists['Pi'] += [u'‚', u'„'] - - ucharlists['Pi'].remove(u'‛') # 201B SINGLE HIGH-REVERSED-9 QUOTATION MARK - ucharlists['Pi'].remove(u'‟') # 201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK - ucharlists['Pf'] += [u'‛', u'‟'] - - # 301F LOW DOUBLE PRIME QUOTATION MARK misses the opening pendant: - ucharlists['Ps'].insert(ucharlists['Pe'].index(u'\u301f'), u'\u301d') - - # print u''.join(ucharlists['Ps']).encode('utf8') - # print u''.join(ucharlists['Pe']).encode('utf8') - # print u''.join(ucharlists['Pi']).encode('utf8') - # print u''.join(ucharlists['Pf']).encode('utf8') - - # The Docutils character categories - # --------------------------------- - # - # The categorization of ASCII chars is non-standard to reduce both - # false positives and need for escaping. (see `inline markup recognition - # rules`_) - - # matching, allowed before markup - openers = [re.escape('"\'(<[{')] - for cat in ('Ps', 'Pi', 'Pf'): - openers.extend(ucharlists[cat]) - - # matching, allowed after markup - closers = [re.escape('"\')>]}')] - for cat in ('Pe', 'Pf', 'Pi'): - closers.extend(ucharlists[cat]) - - # non-matching, allowed on both sides - delimiters = [re.escape('-/:')] - for cat in ('Pd', 'Po'): - delimiters.extend(ucharlists[cat]) - - # non-matching, after markup - closing_delimiters = [re.escape('.,;!?')] - - # # Test open/close matching: - # for i in range(min(len(openers),len(closers))): - # print '%4d %s %s' % (i, openers[i].encode('utf8'), - # closers[i].encode('utf8')) - - return [u''.join(chars) - for chars in (openers, closers, delimiters, closing_delimiters)] - - -# Matching open/close quotes -# -------------------------- - -# Rule (5) requires determination of matching open/close pairs. However, -# the pairing of open/close quotes is ambigue due to different typographic -# conventions in different languages. - -quote_pairs = {u'\xbb': u'\xbb', # Swedish - u'\u2018': u'\u201a', # Greek - u'\u2019': u'\u2019', # Swedish - u'\u201a': u'\u2018\u2019', # German, Polish - u'\u201c': u'\u201e', # German - u'\u201e': u'\u201c\u201d', - u'\u201d': u'\u201d', # Swedish - u'\u203a': u'\u203a', # Swedish - } - -def match_chars(c1, c2): - try: - i = openers.index(c1) - except ValueError: # c1 not in openers - return False - return c2 == closers[i] or c2 in quote_pairs.get(c1, '') - - - - -# print results -# ============= - -if __name__ == '__main__': - - # (re) create and compare the samples: - (o, c, d, cd) = punctuation_samples() - if o != openers: - print '- openers = ur"""%s"""' % openers.encode('utf8') - print '+ openers = ur"""%s"""' % o.encode('utf8') - if c != closers: - print '- closers = ur"""%s"""' % closers.encode('utf8') - print '+ closers = ur"""%s"""' % c.encode('utf8') - if d != delimiters: - print '- delimiters = ur"%s"' % delimiters.encode('utf8') - print '+ delimiters = ur"%s"' % d.encode('utf8') - if cd != closing_delimiters: - print '- closing_delimiters = ur"%s"' % closing_delimiters.encode('utf8') - print '+ closing_delimiters = ur"%s"' % cd.encode('utf8') - - # # test prints - # print 'openers = ', repr(openers) - # print 'closers = ', repr(closers) - # print 'delimiters = ', repr(delimiters) - # print 'closing_delimiters = ', repr(closing_delimiters) - - # ucharlists = unicode_charlists(unicode_punctuation_categories) - # for cat, chars in ucharlists.items(): - # # print cat, chars - # # compact output (visible with a comprehensive font): - # print (u":%s: %s" % (cat, u''.join(chars))).encode('utf8') Modified: trunk/docutils/docutils/parsers/rst/roles.py =================================================================== --- trunk/docutils/docutils/parsers/rst/roles.py 2011-12-20 09:36:10 UTC (rev 7266) +++ trunk/docutils/docutils/parsers/rst/roles.py 2011-12-20 14:14:21 UTC (rev 7267) @@ -75,7 +75,7 @@ from docutils import nodes, utils from docutils.parsers.rst import directives from docutils.parsers.rst.languages import en as _fallback_language_module -from docutils.parsers.code_analyzer import Lexer, LexerError +from docutils.utils.code_analyzer import Lexer, LexerError DEFAULT_INTERPRETED_ROLE = 'title-reference' """ Modified: trunk/docutils/docutils/parsers/rst/states.py =================================================================== --- trunk/docutils/docutils/parsers/rst/states.py 2011-12-20 09:36:10 UTC (rev 7266) +++ trunk/docutils/docutils/parsers/rst/states.py 2011-12-20 14:14:21 UTC (rev 7267) @@ -107,16 +107,17 @@ import re import roman from types import FunctionType, MethodType + 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.utils import escape2null, unescape, column_width import docutils.parsers.rst from docutils.parsers.rst import directives, languages, tableparser, roles from docutils.parsers.rst.languages import en as _fallback_language_module -from docutils.parsers.rst import punctuation_chars +from docutils.utils import escape2null, unescape, column_width +from docutils.utils import punctuation_chars class MarkupError(DataError): pass class UnknownInterpretedRoleError(DataError): pass Copied: trunk/docutils/docutils/utils/__init__.py (from rev 7266, trunk/docutils/docutils/utils.py) =================================================================== --- trunk/docutils/docutils/utils/__init__.py (rev 0) +++ trunk/docutils/docutils/utils/__init__.py 2011-12-20 14:14:21 UTC (rev 7267) @@ -0,0 +1,730 @@ +# coding: utf8 +# $Id$ +# Author: David Goodger <go...@py...> +# Copyright: This module has been placed in the public domain. + +""" +Miscellaneous utilities for the documentation utilities. +""" + +__docformat__ = 'reStructuredText' + +import sys +import os +import os.path +import warnings +import unicodedata +from docutils import ApplicationError, DataError +from docutils import nodes +from docutils.io import FileOutput +from docutils.error_reporting import ErrorOutput, SafeString + + +class SystemMessage(ApplicationError): + + def __init__(self, system_message, level): + Exception.__init__(self, system_message.astext()) + self.level = level + + +class SystemMessagePropagation(ApplicationError): pass + + +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 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 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 if 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 + 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. + + .. [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() + """List of names for system message levels, indexed by level.""" + + # system message level constants: + (DEBUG_LEVEL, + INFO_LEVEL, + WARNING_LEVEL, + ERROR_LEVEL, + SEVERE_LEVEL) = range(5) + + def __init__(self, source, report_level, halt_level, stream=None, + debug=0, encoding=None, error_handler='backslashreplace'): + """ + :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` + 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), + '' (empty string) or `False` (for discarding all stream messages) + or `None` (implies `sys.stderr`; default). + - `encoding`: The output encoding. + - `error_handler`: The error handler for stderr output encoding. + """ + + self.source = source + """The path to or description of the source data.""" + + 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 not isinstance(stream, ErrorOutput): + stream = ErrorOutput(stream, encoding, error_handler) + + self.stream = stream + """Where warning output is sent.""" + + self.encoding = encoding or getattr(stream, 'encoding', 'ascii') + """The output character encoding.""" + + self.observers = [] + """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): + warnings.warn('docutils.utils.Reporter.set_conditions deprecated; ' + 'set attributes via configuration settings or directly', + DeprecationWarning, stacklevel=2) + self.report_level = report_level + self.halt_level = halt_level + if not isinstance(stream, ErrorOutput): + stream = ErrorOutput(stream, self.encoding, self.error_handler) + self.stream = stream + self.debug_flag = debug + + 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, message, *children, **kwargs): + """ + Return a system_message object. + + Raise an exception or generate a warning if appropriate. + """ + # `message` can be a `string`, `unicode`, or `Exception` instance. + if isinstance(message, Exception): + message = SafeString(message) + + attributes = kwargs.copy() + if 'base_node' in kwargs: + 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) + # assert source is not None, "node has line- but no source-argument" + if not 'source' in attributes: # 'line' is absolute line number + try: # look up (source, line-in-source) + source, line = self.locator(attributes.get('line')) + # print "locator lookup", kwargs.get('line'), "->", source, line + except AttributeError: + source, line = None, None + if source is not None: + attributes['source'] = source + if line is not None: + attributes['line'] = line + # assert attributes['line'] is not None, (message, kwargs) + # assert attributes['source'] is not None, (message, kwargs) + attributes.setdefault('source', self.source) + + msg = nodes.system_message(message, level=level, + type=self.levels[level], + *children, **attributes) + if self.stream and (level >= self.report_level + or self.debug_flag and level == self.DEBUG_LEVEL + or level >= self.halt_level): + self.stream.write(msg.astext() + '\n') + if level >= self.halt_level: + raise SystemMessage(msg, level) + if level > self.DEBUG_LEVEL or self.debug_flag: + self.notify_observers(msg) + self.max_level = max(level, self.max_level) + return msg + + 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. + """ + if self.debug_flag: + return self.system_message(self.DEBUG_LEVEL, *args, **kwargs) + + 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(self.INFO_LEVEL, *args, **kwargs) + + 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(self.WARNING_LEVEL, *args, **kwargs) + + 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(self.ERROR_LEVEL, *args, **kwargs) + + 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(self.SEVERE_LEVEL, *args, **kwargs) + + +class ExtensionOptionError(DataError): pass +class BadOptionError(ExtensionOptionError): pass +class BadOptionDataError(ExtensionOptionError): pass +class DuplicateOptionError(ExtensionOptionError): pass + + +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. + - `options_spec`: Dictionary mapping known option names to a + conversion function such as `int` or `float`. + + :Exceptions: + - `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, + missing data, bad quotes, etc.). + """ + option_list = extract_options(field_list) + option_dict = assemble_option_dict(option_list, options_spec) + return option_dict + +def extract_options(field_list): + """ + Return a list of option (name, value) pairs from field names & bodies. + + :Parameter: + `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. + - `BadOptionDataError` for invalid option data (missing name, + missing data, bad quotes, etc.). + """ + option_list = [] + for field in field_list: + if len(field[0].astext().split()) != 1: + raise BadOptionError( + 'extension option field name may not contain multiple words') + 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 BadOptionDataError( + 'extension option field body may contain\n' + 'a single paragraph only (option "%s")' % name) + else: + data = body[0][0].astext() + option_list.append((name, data)) + return option_list + +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()`). + - `options_spec`: Dictionary mapping known option names to a + conversion function such as `int` or `float`. + + :Exceptions: + - `KeyError` for unknown option names. + - `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: + convertor = options_spec[name] # raises KeyError if unknown + if convertor is None: + raise KeyError(name) # or if explicitly disabled + if name in options: + raise DuplicateOptionError('duplicate option "%s"' % name) + try: + options[name] = convertor(value) + except (ValueError, TypeError), detail: + raise detail.__class__('(option: "%s"; value: %r)\n%s' + % (name, value, ' '.join(detail.args))) + return options + + +class NameValueError(DataError): pass + + +def decode_path(path): + """ + Ensure `path` is Unicode. Return `nodes.reprunicode` object. + + Decode file/path string in a failsave manner if not already done. + """ + # see also http://article.gmane.org/gmane.text.docutils.user/2905 + if isinstance(path, unicode): + return path + try: + path = path.decode(sys.getfilesystemencoding(), 'strict') + except AttributeError: # default value None has no decode method + return nodes.reprunicode(path) + except UnicodeDecodeError: + try: + path = path.decode('utf-8', 'strict') + except UnicodeDecodeError: + path = path.decode('ascii', 'replace') + return nodes.reprunicode(path) + + +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 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. + """ + 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. + + :Parameters: + `source_path` : string + The path to or description of the source text of the document. + `settings` : optparse.Values object + Runtime settings. If none are provided, a default core set will + be used. If you will use the document object with any Docutils + components, you must provide their default settings as well. For + example, if parsing, at least provide the parser settings, + obtainable as follows:: + + settings = docutils.frontend.OptionParser( + components=(docutils.parsers.rst.Parser,) + ).get_default_values() + """ + from docutils import frontend + if settings is None: + settings = frontend.OptionParser().get_default_values() + source_path = decode_path(source_path) + 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): + if len(paragraph) == 1 and isinstance(paragraph[0], nodes.Text): + textnode = paragraph[0] + for pattern, substitution in keyword_substitutions: + match = pattern.search(textnode) + if match: + paragraph[0] = nodes.Text(pattern.sub(substitution, textnode)) + return + +def relative_path(source, target): + """ + Build and return a path to `target`, relative to `source` (both files). + + If there is no common prefix, return the absolute path to `target`. + """ + 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]: + # Nothing in common between paths. + # Return absolute path, using '/' for URLs: + return '/'.join(target_parts) + source_parts.reverse() + target_parts.reverse() + while (source_parts and target_parts + and 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) + +def get_stylesheet_reference(settings, relative_to=None): + """ + Retrieve a stylesheet reference from the settings object. + + Deprecated. Use get_stylesheet_list() instead to + enable specification of multiple stylesheets as a comma-separated + list. + """ + 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 + +# Return 'stylesheet' or 'stylesheet_path' arguments as list. +# +# The original settings arguments are kept unchanged: you can test +# with e.g. ``if settings.stylesheet_path:`` +# +# Differences to ``get_stylesheet_reference``: +# * return value is a list +# * no re-writing of the path (and therefore no optional argument) +# (if required, use ``utils.relative_path(source, target)`` +# in the calling script) +def get_stylesheet_list(settings): + """ + Retrieve list of stylesheet references from the settings object. + """ + assert not (settings.stylesheet and settings.stylesheet_path), ( + 'stylesheet and stylesheet_path are mutually exclusive.') + if settings.stylesheet_path: + sheets = settings.stylesheet_path.split(",") + elif settings.stylesheet: + sheets = settings.stylesheet.split(",") + else: + sheets = [] + # strip whitespace (frequently occuring in config files) + return [sheet.strip(u' \t\n') for sheet in sheets] + +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 + its closest ancestor. + """ + while node: + if node.source or node.line: + return node.source, node.line + 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 + +def strip_combining_chars(text): + if isinstance(text, str) and sys.version_info < (3,0): + return text + return u''.join([c for c in text if not unicodedata.combining(c)]) + +def find_combining_chars(text): + """Return indices of all combining chars in Unicode string `text`. + + >>> find_combining_chars(u'A t̆ab̆lĕ') + [3, 6, 9] + """ + if isinstance(text, str) and sys.version_info < (3,0): + return [] + return [i for i,c in enumerate(text) if unicodedata.combining(c)] + +def column_indices(text): + """Indices of Unicode string `text` when skipping combining characters. + + >>> column_indices(u'A t̆ab̆lĕ') + [0, 1, 2, 4, 5, 7, 8] + """ + # TODO: account for asian wide chars here instead of using dummy + # replacements in the tableparser? + string_indices = range(len(text)) + for index in find_combining_chars(text): + string_indices[index] = None + return [i for i in string_indices if i is not None] + +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_widt()` to character +column widths.""" + +def column_width(text): + """Return the column width of text. + + Correct ``len(text)`` for wide East Asian and combining Unicode chars. + """ + if isinstance(text, str) and sys.version_info < (3,0): + return len(text) + try: + width = sum([east_asian_widths[unicodedata.east_asian_width(c)] + for c in text]) + except AttributeError: # east_asian_width() New in version 2.4. + width = len(text) + # correction for combining chars: + width -= len(find_combining_chars(text)) + return width + +def uniq(L): + r = [] + for item in L: + if not item in r: + r.append(item) + return r + +# by Li Daobing http://code.activestate.com/recipes/190465/ +# since Python 2.6 there is also itertools.combinations() +def unique_combinations(items, n): + """Return n-length tuples, in sorted order, no repeated elements""" + if n==0: yield [] + else: + for i in xrange(len(items)-n+1): + for cc in unique_combinations(items[i+1:],n-1): + yield [items[i]]+cc + +def normalize_language_tag(tag): + """Return a list of normalized combinations for a `BCP 47` language tag. + + Example: + + >>> normalize_language_tag('de-AT-1901') + ['de_at_1901', 'de_at', 'de_1901', 'de'] + """ + # normalize: + tag = tag.lower().replace('-','_') + # find all combinations of subtags + taglist = [] + base_tag= tag.split('_')[:1] + subtags = tag.split('_')[1:] + # print base_tag, subtags + for n in range(len(subtags), 0, -1): + for tags in unique_combinations(subtags, n): + # print tags + taglist.append('_'.join(base_tag + tags)) + taglist += base_tag + return taglist + + +class DependencyList(object): + + """ + 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 + 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: + if output_file == '-': + of = None + else: + of = output_file + self.file = FileOutput(destination_path=of, + encoding='utf8', autoclose=False) + else: + self.file = None + + def add(self, *filenames): + """ + 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. + """ + for filename in filenames: + if not filename in self.list: + self.list.append(filename) + if self.file is not None: + self.file.write(filename+'\n') + + def close(self): + """ + Close the output file. + """ + self.file.close() + self.file = None + + def __repr__(self): + try: + output_file = self.file.name + except AttributeError: + output_file = None + return '%s(%r, %s)' % (self.__class__.__name__, output_file, self.list) Copied: trunk/docutils/docutils/utils/code_analyzer.py (from rev 7266, trunk/docutils/docutils/parsers/code_analyzer.py) =================================================================== --- trunk/docutils/docutils/utils/code_analyzer.py (rev 0) +++ trunk/docutils/docutils/utils/code_analyzer.py 2011-12-20 14:14:21 UTC (rev 7267) @@ -0,0 +1,134 @@ +#!/usr/bin/python +# coding: utf-8 + +"""Lexical analysis of formal languages (i.e. code) using Pygments.""" + +# :Author: Georg Brandl; Felix Wiemann; Günter Milde +# :Date: $Date$ +# :Copyright: This module has been placed in the public domain. + +from docutils import ApplicationError +try: + import pygments + from pygments.lexers import get_lexer_by_name + from pygments.formatters.html import _get_ttype_class + with_pygments = True +except ImportError: + with_pygments = False + +# Filter the following token types from the list of class arguments: +unstyled_tokens = ['token', # Token (base token type) + 'text', # Token.Text + ''] # short name for Token and Text +# (Add, e.g., Token.Punctuation with ``unstyled_tokens += 'punctuation'``.) + +class LexerError(ApplicationError): + pass + +class Lexer(object): + """Parse `code` lines and yield "classified" tokens. + + Arguments + + code -- string of source code to parse, + language -- formal language the code is written in, + tokennames -- either 'long', 'short', or '' (see below). + + Merge subsequent tokens of the same token-type. + + Iterating over an instance yields the tokens as ``(tokentype, value)`` + tuples. The value of `tokennames` configures the naming of the tokentype: + + 'long': downcased full token type name, + 'short': short name defined by pygments.token.STANDARD_TYPES + (= class argument used in pygments html output), + 'none': skip lexical analysis. + """ + + def __init__(self, code, language, tokennames='short'): + """ + Set up a lexical analyzer for `code` in `language`. + """ + self.code = code + self.language = language + self.tokennames = tokennames + self.lexer = None + # get lexical analyzer for `language`: + if language in ('', 'text') or tokennames == 'none': + return + if not with_pygments: + raise LexerError('Cannot analyze code. ' + 'Pygments package not found.') + try: + self.lexer = get_lexer_by_name(self.language) + except pygments.util.ClassNotFound: + raise LexerError('Cannot analyze code. ' + 'No Pygments lexer found for "%s".' % language) + + # Since version 1.2. (released Jan 01, 2010) Pygments has a + # TokenMergeFilter. However, this requires Python >= 2.4. When Docutils + # requires same minimal version, ``self.merge(tokens)`` in __iter__ can + # be replaced by ``self.lexer.add_filter('tokenmerge')`` in __init__. + def merge(self, tokens): + """Merge subsequent tokens of same token-type. + + Also strip the final newline (added by pygments). + """ + tokens = iter(tokens) + (lasttype, lastval) = tokens.next() + for ttype, value in tokens: + if ttype is lasttype: + lastval += value + else: + yield(lasttype, lastval) + (lasttype, lastval) = (ttype, value) + if lastval.endswith('\n'): + lastval = lastval[:-1] + if lastval: + yield(lasttype, lastval) + + def __iter__(self): + """Parse self.code and yield "classified" tokens. + """ + if self.lexer is None: + yield ([], self.code) + return + tokens = pygments.lex(self.code, self.lexer) + for tokentype, value in self.merge(tokens): + if self.tokennames == 'long': # long CSS class args + classes = str(tokentype).lower().split('.') + else: # short CSS class args + classes = [_get_ttype_class(tokentype)] + classes = [cls for cls in classes if cls not in unstyled_tokens] + yield (classes, value) + + +class NumberLines(object): + """Insert linenumber-tokens at the start of every code line. + + Arguments + + tokens -- iterable of ``(classes, value)`` tuples + startline -- first line number + endline -- last line number + + Iterating over an instance yields the tokens with a + ``(['ln'], '<the line number>')`` token added for every code line. + Multi-line tokens are splitted.""" + + def __init__(self, tokens, startline, endline): + self.tokens = tokens + self.startline = startline + # pad linenumbers, e.g. endline == 100 -> fmt_str = '%3d ' + self.fmt_str = '%%%dd ' % len(str(endline)) + + def __iter__(self): + lineno = self.startline + yield (['ln'], self.fmt_str % lineno) + for ttype, value in self.tokens: + lines = value.split('\n') + for line in lines[:-1]: + yield (ttype, line + '\n') + lineno += 1 + yield (['ln'], self.fmt_str % lineno) + yield (ttype, lines[-1]) Copied: trunk/docutils/docutils/utils/punctuation_chars.py (from rev 7266, trunk/docutils/docutils/parsers/rst/punctuation_chars.py) =================================================================== --- trunk/docutils/docutils/utils/punctuation_chars.py (rev 0) +++ trunk/docutils/docutils/utils/punctuation_chars.py 2011-12-20 14:14:21 UTC (rev 7267) @@ -0,0 +1,211 @@ +#!/usr/bin/env python +# -*- coding: utf8 -*- +# :Copyright: © 2011 Günter Milde. +# :License: Released under the terms of the `2-Clause BSD license`_, in short: +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +# This file is offered as-is, without any warranty. +# +# .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause + +# :Id: $Id$ + +import sys, re +import unicodedata + +# punctuation characters around inline markup +# =========================================== +# +# This module provides the lists of characters for the implementation of +# the `inline markup recognition rules`_ in the reStructuredText parser +# (states.py) +# +# .. _inline markup recognition rules: +# ../../../docs/ref/rst/restructuredtext.html#inline-markup + +# Docutils punctuation category sample strings +# -------------------------------------------- +# +# The sample strings are generated by punctuation_samples() and put here +# literal to avoid the time-consuming generation with every Docutils +# run. Running this file as a standalone module checks the definitions below +# against a re-calculation. + +openers = ur"""\"\'\(\<\[\{༺༼᚛⁅⁽₍〈❨❪❬❮❰❲❴⟅⟦⟨⟪⟬⟮⦃⦅⦇⦉⦋⦍⦏⦑⦓⦕⦗⧘⧚⧼⸢⸤⸦⸨〈《「『【〔〖〘〚〝〝﴾︗︵︷︹︻︽︿﹁﹃﹇﹙﹛﹝([{⦅「«‘“‹⸂⸄⸉⸌⸜⸠‚„»’”›⸃⸅⸊⸍⸝⸡‛‟""" +closers = ur"""\"\'\)\>\]\}༻༽᚜⁆⁾₎〉❩❫❭❯❱❳❵⟆⟧⟩⟫⟭⟯⦄⦆⦈⦊⦌⦎⦐⦒⦔⦖⦘⧙⧛⧽⸣⸥⸧⸩〉》」』】〕〗〙〛〞〟﴿︘︶︸︺︼︾﹀﹂﹄﹈﹚﹜﹞)]}⦆」»’”›⸃⸅⸊⸍⸝⸡‛‟«‘“‹⸂⸄⸉⸌⸜⸠‚„""" +delimiters = ur"\-\/\:֊־᐀᠆‐‑‒–—―⸗⸚〜〰゠︱︲﹘﹣-¡·¿;·՚՛՜՝՞՟։׀׃׆׳״؉؊،؍؛؞؟٪٫٬٭۔܀܁܂܃܄܅܆܇܈܉܊܋܌܍߷߸߹࠰࠱࠲࠳࠴࠵࠶࠷࠸࠹࠺࠻࠼࠽࠾।॥॰෴๏๚๛༄༅༆༇༈༉༊་༌།༎༏༐༑༒྅࿐࿑࿒࿓࿔၊။၌၍၎၏჻፡።፣፤፥፦፧፨᙭᙮᛫᛬᛭᜵᜶។៕៖៘៙៚᠀᠁᠂᠃᠄᠅᠇᠈᠉᠊᥄᥅᧞᧟᨞᨟᪠᪡᪢᪣᪤᪥᪦᪨᪩᪪᪫᪬᪭᭚᭛᭜᭝᭞᭟᭠᰻᰼᰽᰾᰿᱾᱿᳓‖‗†‡•‣․‥…‧‰‱′″‴‵‶‷‸※‼‽‾⁁⁂⁃⁇⁈⁉⁊⁋⁌⁍⁎⁏⁐⁑⁓⁕⁖⁗⁘⁙⁚⁛⁜⁝⁞⳹⳺⳻⳼⳾⳿⸀⸁⸆⸇⸈⸋⸎⸏⸐⸑⸒⸓⸔⸕⸖⸘⸙⸛⸞⸟⸪⸫⸬⸭⸮⸰⸱、。〃〽・꓾꓿꘍꘎꘏꙳꙾꛲꛳꛴꛵꛶꛷꡴꡵꡶꡷꣎꣏꣸꣹꣺꤮꤯꥟꧁꧂꧃꧄꧅꧆꧇꧈꧉꧊꧋꧌꧍꧞꧟꩜꩝꩞꩟꫞꫟꯫︐︑︒︓︔︕︖︙︰﹅﹆﹉﹊﹋﹌﹐﹑﹒﹔﹕﹖﹗﹟﹠﹡﹨﹪﹫!"#%&'*,./:;?@\。、・𐄀𐄁𐎟𐏐𐡗𐤟𐤿𐩐𐩑𐩒𐩓𐩔𐩕𐩖𐩗𐩘𐩿𐬹𐬺𐬻𐬼𐬽𐬾𐬿𑂻𑂼𑂾𑂿𑃀𑃁𒑰𒑱𒑲𒑳" +closing_delimiters = ur"\.\,\;\!\?" + + +# Unicode punctuation character categories +# ---------------------------------------- + +unicode_punctuation_categories = { + # 'Pc': 'Connector', # not used in Docutils inline markup recognition + 'Pd': 'Dash', + 'Ps': 'Open', + 'Pe': 'Close', + 'Pi': 'Initial quote', # may behave like Ps or Pe depending on usage + 'Pf': 'Final quote', # may behave like Ps or Pe depending on usage + 'Po': 'Other' + } +"""Unicode character categories for punctuation""" + + +# generate character pattern strings +# ================================== + +def unicode_charlists(categories, cp_min=0, cp_max=None): + """Return dictionary of Unicode character lists. + + For each of the `catagories`, an item contains a list with all Unicode + characters with `cp_min` <= code-point <= `cp_max` that belong to the + category. (The default values check every code-point supported by Python.) + """ + # Determine highest code point with one of the given categories + # (may shorten the search time considerably if there are many + # categories with not too high characters): + if cp_max is None: + cp_max = max(x for x in xrange(sys.maxunicode + 1) + if unicodedata.category(unichr(x)) in categories) + # print cp_max # => 74867 for unicode_punctuation_categories + charlists = {} + for cat in categories: + charlists[cat] = [unichr(x) for x in xrange(cp_min, cp_max+1) + if unicodedata.category(unichr(x)) == cat] + return charlists + + +# Character categories in Docutils +# -------------------------------- + +def punctuation_samples(): + + """Docutils punctuation category sample strings. + + Return list of sample strings for the categories "Open", "Close", + "Delimiters" and "Closing-Delimiters" used in the `inline markup + recognition rules`_. + """ + + # Lists with characters in Unicode punctuation character categories + cp_min = 160 # ASCII chars have special rules for backwards compatibility + ucharlists = unicode_charlists(unicode_punctuation_categories, cp_min) + + # match opening/closing characters + # -------------------------------- + # Rearange the lists to ensure matching characters at the same + # index position. + + # low quotation marks are also used as closers (e.g. in Greek) + # move them to category Pi: + ucharlists['Ps'].remove(u'‚') # 201A SINGLE LOW-9 QUOTATION MARK + ucharlists['Ps'].remove(u'„') # 201E DOUBLE LOW-9 QUOTATION MARK + ucharlists['Pi'] += [u'‚', u'„'] + + ucharlists['Pi'].remove(u'‛') # 201B SINGLE HIGH-REVERSED-9 QUOTATION MARK + ucharlists['Pi'].remove(u'‟') # 201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK + ucharlists['Pf'] += [u'‛', u'‟'] + + # 301F LOW DOUBLE PRIME QUOTATION MARK misses the opening pendant: + ucharlists['Ps'].insert(ucharlists['Pe'].index(u'\u301f'), u'\u301d') + + # print u''.join(ucharlists['Ps']).encode('utf8') + # print u''.join(ucharlists['Pe']).encode('utf8') + # print u''.join(ucharlists['Pi']).encode('utf8') + # print u''.join(ucharlists['Pf']).encode('utf8') + + # The Docutils character categories + # --------------------------------- + # + # The categorization of ASCII chars is non-standard to reduce both + # false positives and need for escaping. (see `inline markup recognition + # rules`_) + + # matching, allowed before markup + openers = [re.escape('"\'(<[{')] + for cat in ('Ps', 'Pi', 'Pf'): + openers.extend(ucharlists[cat]) + + # matching, allowed after markup + closers = [re.escape('"\')>]}')] + for cat in ('Pe', 'Pf', 'Pi'): + closers.extend(ucharlists[cat]) + + # non-matching, allowed on both sides + delimiters = [re.escape('-/:')] + for cat in ('Pd', 'Po'): + delimiters.extend(ucharlists[cat]) + + # non-matching, after markup + closing_delimiters = ... [truncated message content] |
From: <mi...@us...> - 2011-12-20 16:39:16
|
Revision: 7268 http://docutils.svn.sourceforge.net/docutils/?rev=7268&view=rev Author: milde Date: 2011-12-20 16:39:10 +0000 (Tue, 20 Dec 2011) Log Message: ----------- Fix [ 2971827 ] and [ 3442827 ] extras/roman.py moved to docutils/utils/roman.py Modified Paths: -------------- trunk/docutils/HISTORY.txt trunk/docutils/docutils/parsers/rst/states.py trunk/docutils/docutils/writers/manpage.py trunk/docutils/setup.py Added Paths: ----------- trunk/docutils/docutils/utils/roman.py Removed Paths: ------------- trunk/docutils/extras/ Modified: trunk/docutils/HISTORY.txt =================================================================== --- trunk/docutils/HISTORY.txt 2011-12-20 14:14:21 UTC (rev 7267) +++ trunk/docutils/HISTORY.txt 2011-12-20 16:39:10 UTC (rev 7268) @@ -26,6 +26,11 @@ .. _Pygments: http://pygments.org/ +* setup.py + + - Fix [ 2971827 ] and [ 3442827 ] + extras/roman.py moved to docutils/utils/roman.py + * docutils/io.py - Fix [ 3395948 ] (Work around encoding problems in Py3k). Modified: trunk/docutils/docutils/parsers/rst/states.py =================================================================== --- trunk/docutils/docutils/parsers/rst/states.py 2011-12-20 14:14:21 UTC (rev 7267) +++ trunk/docutils/docutils/parsers/rst/states.py 2011-12-20 16:39:10 UTC (rev 7268) @@ -105,7 +105,10 @@ import sys import re -import roman +try: + import roman +except ImportError: + import docutils.utils.roman as roman from types import FunctionType, MethodType from docutils import nodes, statemachine, utils, urischemes Copied: trunk/docutils/docutils/utils/roman.py (from rev 7266, trunk/docutils/extras/roman.py) =================================================================== --- trunk/docutils/docutils/utils/roman.py (rev 0) +++ trunk/docutils/docutils/utils/roman.py 2011-12-20 16:39:10 UTC (rev 7268) @@ -0,0 +1,81 @@ +"""Convert to and from Roman numerals""" + +__author__ = "Mark Pilgrim (f8...@di...)" +__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 + Modified: trunk/docutils/docutils/writers/manpage.py =================================================================== --- trunk/docutils/docutils/writers/manpage.py 2011-12-20 14:14:21 UTC (rev 7267) +++ trunk/docutils/docutils/writers/manpage.py 2011-12-20 16:39:10 UTC (rev 7268) @@ -48,7 +48,10 @@ import docutils from docutils import nodes, writers, languages -import roman +try: + import roman +except ImportError: + import docutils.utils.roman as roman FIELD_LIST_INDENT = 7 DEFINITION_LIST_INDENT = 7 Modified: trunk/docutils/setup.py =================================================================== --- trunk/docutils/setup.py 2011-12-20 14:14:21 UTC (rev 7267) +++ trunk/docutils/setup.py 2011-12-20 16:39:10 UTC (rev 7268) @@ -88,9 +88,6 @@ def do_setup(): kwargs = package_data.copy() - extras = get_extras() - if extras: - kwargs['py_modules'] = extras kwargs['classifiers'] = classifiers # Install data files properly. kwargs['cmdclass'] = {'build_data': build_data, @@ -124,7 +121,6 @@ 'license': 'public domain, Python, 2-Clause BSD, GPL 3 (see COPYING.txt)', 'platforms': 'OS-independent', 'package_dir': {'docutils': 'docutils', - '': 'extras', 'docutils.tools': 'tools'}, 'packages': ['docutils', 'docutils.languages', @@ -156,8 +152,6 @@ ['docutils/writers/latex2e/default.tex', 'docutils/writers/latex2e/titlepage.tex', 'docutils/writers/latex2e/xelatex.tex',]), - # ('docutils/writers/newlatex2e', - # ['docutils/writers/newlatex2e/base.tex']), ('docutils/writers/pep_html', ['docutils/writers/pep_html/pep.css', 'docutils/writers/pep_html/template.txt']), @@ -170,7 +164,6 @@ 'scripts' : ['tools/rst2html.py', 'tools/rst2s5.py', 'tools/rst2latex.py', - # 'tools/rst2newlatex.py', 'tools/rst2xetex.py', 'tools/rst2man.py', 'tools/rst2xml.py', @@ -222,26 +215,5 @@ """Trove classifiers for the Distutils "register" command; Python 2.3 and up.""" -extra_modules = [('roman', '1.4', ['toRoman', 'fromRoman', - 'InvalidRomanNumeralError'])] -"""Third-party modules to install if they're not already present. -List of (module name, minimum __version__ string, [attribute names]).""" - -def get_extras(): - extras = [] - for module_name, version, attributes in extra_modules: - try: - module = __import__(module_name) - if version and module.__version__ < version: - raise ValueError - for attribute in attributes or []: - getattr(module, attribute) - print ('"%s" module already present; ignoring extras/%s.py.' - % (module_name, module_name)) - except (ImportError, AttributeError, ValueError): - extras.append(module_name) - return extras - - if __name__ == '__main__' : do_setup() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mi...@us...> - 2012-01-11 20:29:03
|
Revision: 7313 http://docutils.svn.sourceforge.net/docutils/?rev=7313&view=rev Author: milde Date: 2012-01-11 20:28:57 +0000 (Wed, 11 Jan 2012) Log Message: ----------- Report table parsing errors with correct line number. Modified Paths: -------------- trunk/docutils/docutils/parsers/rst/states.py trunk/docutils/docutils/parsers/rst/tableparser.py trunk/docutils/test/test_parsers/test_rst/test_SimpleTableParser.py trunk/docutils/test/test_parsers/test_rst/test_TableParser.py trunk/docutils/test/test_parsers/test_rst/test_east_asian_text.py trunk/docutils/test/test_parsers/test_rst/test_tables.py Modified: trunk/docutils/docutils/parsers/rst/states.py =================================================================== --- trunk/docutils/docutils/parsers/rst/states.py 2012-01-10 02:36:13 UTC (rev 7312) +++ trunk/docutils/docutils/parsers/rst/states.py 2012-01-11 20:28:57 UTC (rev 7313) @@ -1627,9 +1627,9 @@ + 1) table = self.build_table(tabledata, tableline) nodelist = [table] + messages - except tableparser.TableMarkupError, detail: - nodelist = self.malformed_table( - block, ' '.join(detail.args)) + messages + except tableparser.TableMarkupError, err: + nodelist = self.malformed_table(block, ' '.join(err.args), + offset=err.offset) + messages else: nodelist = messages return nodelist, blank_finish @@ -1715,7 +1715,7 @@ 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=''): + def malformed_table(self, block, detail='', offset=0): block.replace(self.double_width_pad_char, '') data = '\n'.join(block) message = 'Malformed table.' @@ -1723,7 +1723,7 @@ if detail: message += '\n' + detail error = self.reporter.error(message, nodes.literal_block(data, data), - line=startline) + line=startline+offset) return [error] def build_table(self, tabledata, tableline, stub_columns=0): Modified: trunk/docutils/docutils/parsers/rst/tableparser.py =================================================================== --- trunk/docutils/docutils/parsers/rst/tableparser.py 2012-01-10 02:36:13 UTC (rev 7312) +++ trunk/docutils/docutils/parsers/rst/tableparser.py 2012-01-11 20:28:57 UTC (rev 7313) @@ -26,9 +26,20 @@ from docutils.utils import strip_combining_chars -class TableMarkupError(DataError): pass +class TableMarkupError(DataError): + """ + Raise if there is any problem with table markup. + The keyword argument `offset` denotes the offset of the problem + from the table's start line. + """ + + def __init__(self, *args, **kwargs): + self.offset = kwargs.pop('offset', 0) + DataError.__init__(self, *args) + + class TableParser: """ @@ -64,16 +75,17 @@ 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)) + 'Multiple head/body row separators ' + '(table lines %s and %s); only one allowed.' + % (self.head_body_sep+1, i+1), offset=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.') + 'the first or last line of the table.', + offset=i) class GridTableParser(TableParser): @@ -425,8 +437,9 @@ cols.append((begin, end)) if self.columns: if cols[-1][1] != self.border_end: - raise TableMarkupError('Column span incomplete at line ' - 'offset %s.' % offset) + raise TableMarkupError('Column span incomplete in table ' + 'line %s.' % (offset+1), + offset=offset) # Allow for an unbounded rightmost column: cols[-1] = (cols[-1][0], self.columns[-1][1]) return cols @@ -442,8 +455,9 @@ i += 1 morecols += 1 except (AssertionError, IndexError): - raise TableMarkupError('Column span alignment problem at ' - 'line offset %s.' % (offset + 1)) + raise TableMarkupError('Column span alignment problem ' + 'in table line %s.' % (offset+2), + offset=offset+1) cells.append([0, morecols, offset, []]) i += 1 return cells @@ -502,8 +516,9 @@ 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.' % (first_line + offset)) + raise TableMarkupError('Text in column margin ' + 'in table line %s.' % (first_line+offset+1), + offset=first_line+offset) offset += 1 columns.pop() Modified: trunk/docutils/test/test_parsers/test_rst/test_SimpleTableParser.py =================================================================== --- trunk/docutils/test/test_parsers/test_rst/test_SimpleTableParser.py 2012-01-10 02:36:13 UTC (rev 7312) +++ trunk/docutils/test/test_parsers/test_rst/test_SimpleTableParser.py 2012-01-11 20:28:57 UTC (rev 7313) @@ -82,14 +82,14 @@ cell 3 cell 4 ============ ====== """, -'TableMarkupError: Text in column margin at line offset 1.'], +'TableMarkupError: Text in column margin in table line 2.'], ["""\ ====== ===== ====== row one Another bad table ====== ===== ====== """, -'TableMarkupError: Text in column margin at line offset 2.'], +'TableMarkupError: Text in column margin in table line 3.'], ["""\ =========== ================ A table with two header rows, @@ -116,8 +116,8 @@ That's bad. ============ ============= """, -'TableMarkupError: Multiple head/body row separators in table ' -'(at line offset 2 and 4); only one allowed.'], +'TableMarkupError: Multiple head/body row separators ' +'(table lines 3 and 5); only one allowed.'], ["""\ ============ ============ ============ ============ Modified: trunk/docutils/test/test_parsers/test_rst/test_TableParser.py =================================================================== --- trunk/docutils/test/test_parsers/test_rst/test_TableParser.py 2012-01-10 02:36:13 UTC (rev 7312) +++ trunk/docutils/test/test_parsers/test_rst/test_TableParser.py 2012-01-11 20:28:57 UTC (rev 7313) @@ -197,10 +197,10 @@ | That's bad. | | +-------------+-----------------+ """, -'TableMarkupError: Multiple head/body row separators in table ' -'(at line offset 2 and 4); only one allowed.', -'TableMarkupError: Multiple head/body row separators in table ' -'(at line offset 2 and 4); only one allowed.'], +'TableMarkupError: Multiple head/body row separators ' +'(table lines 3 and 5); only one allowed.', +'TableMarkupError: Multiple head/body row separators ' +'(table lines 3 and 5); only one allowed.'], ["""\ +-------------------------------------+ | | Modified: trunk/docutils/test/test_parsers/test_rst/test_east_asian_text.py =================================================================== --- trunk/docutils/test/test_parsers/test_rst/test_east_asian_text.py 2012-01-10 02:36:13 UTC (rev 7312) +++ trunk/docutils/test/test_parsers/test_rst/test_east_asian_text.py 2012-01-11 20:28:57 UTC (rev 7313) @@ -149,10 +149,10 @@ <entry> <paragraph> ダイ2ラン - <system_message level="3" line="5" source="test data" type="ERROR"> + <system_message level="3" line="6" source="test data" type="ERROR"> <paragraph> Malformed table. - Text in column margin at line offset 1. + Text in column margin in table line 2. <literal_block xml:space="preserve"> ======== ========= ダイ1ラン ダイ2ラン Modified: trunk/docutils/test/test_parsers/test_rst/test_tables.py =================================================================== --- trunk/docutils/test/test_parsers/test_rst/test_tables.py 2012-01-10 02:36:13 UTC (rev 7312) +++ trunk/docutils/test/test_parsers/test_rst/test_tables.py 2012-01-11 20:28:57 UTC (rev 7313) @@ -896,10 +896,10 @@ """, """\ <document source="test data"> - <system_message level="3" line="1" source="test data" type="ERROR"> + <system_message level="3" line="4" source="test data" type="ERROR"> <paragraph> Malformed table. - Column span alignment problem at line offset 3. + Column span alignment problem in table line 4. <literal_block xml:space="preserve"> ============== ====== A bad table cell 2 @@ -914,10 +914,10 @@ """, """\ <document source="test data"> - <system_message level="3" line="1" source="test data" type="ERROR"> + <system_message level="3" line="2" source="test data" type="ERROR"> <paragraph> Malformed table. - Text in column margin at line offset 1. + Text in column margin in table line 2. <literal_block xml:space="preserve"> ======== ========= A bad table cell 2 @@ -1158,10 +1158,10 @@ """, """\ <document source="test data"> - <system_message level="3" line="1" source="test data" type="ERROR"> + <system_message level="3" line="4" source="test data" type="ERROR"> <paragraph> Malformed table. - Text in column margin at line offset 3. + Text in column margin in table line 4. <literal_block xml:space="preserve"> == =========== =========== 1 Span columns 2 & 3 @@ -1170,10 +1170,10 @@ ------------------------ 3 == =========== =========== - <system_message level="3" line="9" source="test data" type="ERROR"> + <system_message level="3" line="13" source="test data" type="ERROR"> <paragraph> Malformed table. - Column span incomplete at line offset 4. + Column span incomplete in table line 5. <literal_block xml:space="preserve"> == =========== =========== 1 Span cols 1&2 but not 3 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mi...@us...> - 2012-01-18 10:16:32
|
Revision: 7315 http://docutils.svn.sourceforge.net/docutils/?rev=7315&view=rev Author: milde Date: 2012-01-18 10:16:20 +0000 (Wed, 18 Jan 2012) Log Message: ----------- XML writer overhaul (use visitor pattern, raw XML pass through). Modified Paths: -------------- trunk/docutils/HISTORY.txt trunk/docutils/docutils/nodes.py trunk/docutils/docutils/writers/docutils_xml.py trunk/docutils/test/test_writers/test_docutils_xml.py Modified: trunk/docutils/HISTORY.txt =================================================================== --- trunk/docutils/HISTORY.txt 2012-01-12 10:14:43 UTC (rev 7314) +++ trunk/docutils/HISTORY.txt 2012-01-18 10:16:20 UTC (rev 7315) @@ -64,8 +64,15 @@ * docutils/writers/html4css1/__init__.py - - change default for `math-output` setting to MathJax + - Change default for `math-output` setting to MathJax. +* docutils/writers/docutils_xml.py + + - Use the visitor pattern with default methods instead of minidom + to facilitate special handling of selected nodes. + + - Support raw XML (inserted as-is inside a <raw></raw> node). + Release 0.8.1 (2011-08-30) ========================== Modified: trunk/docutils/docutils/nodes.py =================================================================== --- trunk/docutils/docutils/nodes.py 2012-01-12 10:14:43 UTC (rev 7314) +++ trunk/docutils/docutils/nodes.py 2012-01-18 10:16:20 UTC (rev 7315) @@ -499,23 +499,29 @@ # 2to3 doesn't convert __unicode__ to __str__ __str__ = __unicode__ - def starttag(self): + def starttag(self, quoteattr=None): + # the optional arg is used by the docutils_xml writer + if quoteattr is None: + quoteattr = pseudo_quoteattr parts = [self.tagname] for name, value in self.attlist(): if value is None: # boolean attribute parts.append(name) - elif isinstance(value, list): + continue + if isinstance(value, list): values = [serial_escape('%s' % (v,)) for v in value] - parts.append('%s="%s"' % (name, ' '.join(values))) + value = ' '.join(values) else: - parts.append('%s="%s"' % (name, value)) - return '<%s>' % ' '.join(parts) + value = unicode(value) + value = quoteattr(value) + parts.append(u'%s=%s' % (name, value)) + return u'<%s>' % u' '.join(parts) def endtag(self): return '</%s>' % self.tagname def emptytag(self): - return u'<%s/>' % ' '.join([self.tagname] + + return u'<%s/>' % u' '.join([self.tagname] + ['%s="%s"' % (n, v) for n, v in self.attlist()]) @@ -1913,6 +1919,10 @@ """Escape string values that are elements of a list, for serialization.""" return value.replace('\\', r'\\').replace(' ', r'\ ') +def pseudo_quoteattr(value): + """Quote attributes for pseudo-xml""" + return '"%s"' % value + # # # Local Variables: Modified: trunk/docutils/docutils/writers/docutils_xml.py =================================================================== --- trunk/docutils/docutils/writers/docutils_xml.py 2012-01-12 10:14:43 UTC (rev 7314) +++ trunk/docutils/docutils/writers/docutils_xml.py 2012-01-18 10:16:20 UTC (rev 7315) @@ -1,18 +1,26 @@ # $Id$ -# Author: David Goodger <go...@py...> +# Author: David Goodger, Paul Tremblay, Guenter Milde +# Maintainer: doc...@li... # Copyright: This module has been placed in the public domain. """ -Simple internal document tree Writer, writes Docutils XML. +Simple document tree Writer, writes Docutils XML according to +http://docutils.sourceforge.net/docs/ref/docutils.dtd. """ __docformat__ = 'reStructuredText' +import sys +import xml.sax.saxutils +from StringIO import StringIO import docutils -from docutils import frontend, writers +from docutils import frontend, writers, nodes +class RawXmlError(docutils.ApplicationError): pass + + class Writer(writers.Writer): supported = ('xml',) @@ -20,9 +28,7 @@ settings_spec = ( '"Docutils XML" Writer Options', - 'Warning: In versions older than 2.7.3 and 3.2.3, the --newlines and ' - '--indents options may adversely affect whitespace; use them only ' - 'for reading convenience (see http://bugs.python.org/issue4147).', + None, (('Generate XML with newlines before and after tags.', ['--newlines'], {'action': 'store_true', 'validator': frontend.validate_boolean}), @@ -46,7 +52,20 @@ output = None """Final translated form of `document`.""" + def __init__(self): + writers.Writer.__init__(self) + self.translator_class = XMLTranslator + + def translate(self): + self.visitor = visitor = self.translator_class(self.document) + self.document.walkabout(visitor) + self.output = ''.join(visitor.output) + + +class XMLTranslator(nodes.GenericNodeVisitor): + xml_declaration = '<?xml version="1.0" encoding="%s"?>\n' + # TODO: add stylesheet options similar to HTML and LaTeX writers? #xml_stylesheet = '<?xml-stylesheet type="text/xsl" href="%s"?>\n' doctype = ( '<!DOCTYPE document PUBLIC' @@ -54,21 +73,107 @@ ' "http://docutils.sourceforge.net/docs/ref/docutils.dtd">\n') generator = '<!-- Generated by Docutils %s -->\n' - def translate(self): - settings = self.document.settings - indent = newline = '' + xmlparser = xml.sax.make_parser() + """SAX parser instance to check/exctract raw XML.""" + xmlparser.setFeature( + "http://xml.org/sax/features/external-general-entities", True) + + def __init__(self, document): + nodes.NodeVisitor.__init__(self, document) + + # Reporter + self.warn = self.document.reporter.warning + self.error = self.document.reporter.error + + # Settings + self.settings = settings = document.settings + self.indent = self.newline = '' if settings.newlines: - newline = '\n' + self.newline = '\n' if settings.indents: - newline = '\n' - indent = ' ' - output_prefix = [] + self.newline = '\n' + self.indent = ' ' + self.level = 0 # indentation level + self.in_simple = 0 # level of nesting inside mixed-content elements + + # Output + self.output = [] if settings.xml_declaration: - output_prefix.append( + self.output.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)) + self.output.append(self.doctype) + self.output.append(self.generator % docutils.__version__) + + # initialize XML parser + self.the_handle=TestXml() + self.xmlparser.setContentHandler(self.the_handle) + + # generic visit and depart methods + # -------------------------------- + + def default_visit(self, node): + """Default node visit method.""" + if not self.in_simple: + self.output.append(self.indent*self.level) + self.output.append(node.starttag(xml.sax.saxutils.quoteattr)) + self.level += 1 + if isinstance(node, nodes.TextElement): + self.in_simple += 1 + if not self.in_simple: + self.output.append(self.newline) + + def default_departure(self, node): + """Default node depart method.""" + self.level -= 1 + if not self.in_simple: + self.output.append(self.indent*self.level) + self.output.append(node.endtag()) + if isinstance(node, nodes.TextElement): + self.in_simple -= 1 + if not self.in_simple: + self.output.append(self.newline) + + + # specific visit and depart methods + # --------------------------------- + + def visit_Text(self, node): + text = xml.sax.saxutils.escape(node.astext()) + self.output.append(text) + + def depart_Text(self, node): + pass + + def visit_raw(self, node): + if 'xml' not in node.get('format', '').split(): + # skip other raw content? + # raise nodes.SkipNode + self.default_visit(node) + return + # wrap in <raw> element + self.default_visit(node) # or not? + xml_string = node.astext() + self.output.append(xml_string) + self.default_departure(node) # or not? + # Check validity of raw XML: + if isinstance(xml_string, unicode) and sys.version_info < (3,): + xml_string = xml_string.encode('utf8') + try: + self.xmlparser.parse(StringIO(xml_string)) + except xml.sax._exceptions.SAXParseException, error: + col_num = self.the_handle.locator.getColumnNumber() + line_num = self.the_handle.locator.getLineNumber() + srcline = node.line + if not isinstance(node.parent, nodes.TextElement): + srcline += 2 # directive content start line + msg = 'Invalid raw XML in column %d, line offset %d:\n%s' % ( + col_num, line_num, node.astext()) + self.warn(msg, source=node.source, line=srcline+line_num-1) + raise nodes.SkipNode # content already processed + + +class TestXml(xml.sax.ContentHandler): + + def setDocumentLocator(self, locator): + self.locator = locator Modified: trunk/docutils/test/test_writers/test_docutils_xml.py =================================================================== --- trunk/docutils/test/test_writers/test_docutils_xml.py 2012-01-12 10:14:43 UTC (rev 7314) +++ trunk/docutils/test/test_writers/test_docutils_xml.py 2012-01-18 10:16:20 UTC (rev 7315) @@ -6,15 +6,22 @@ """ Test for docutils XML writer. + +.. Attention:: + While the tests compare the output on the string-level, no guarantee + is given against changes to identical XML representations like + ``<empty></empty>`` vs. ``<empty/>``. The sample strings in this test + module mirrors the current behaviour of the docutils_xml writer. """ -from __init__ import DocutilsTestSupport +from StringIO import StringIO -import sys +from __init__ import DocutilsTestSupport # must be imported before docutils import docutils import docutils.core -# sample strings: +# sample strings +# -------------- source = u"""\ Test @@ -36,119 +43,160 @@ bodynormal = u"""\ <document source="<string>"><paragraph>Test</paragraph>\ -<transition/><paragraph>Test. \xe4\xf6\xfc€</paragraph>\ +<transition></transition><paragraph>Test. \xe4\xf6\xfc€</paragraph>\ </document>""" bodynewlines = u"""\ <document source="<string>"> <paragraph>Test</paragraph> -<transition/> +<transition> +</transition> <paragraph>Test. \xe4\xf6\xfc€</paragraph> </document> """ -bodynewlines_old = u"""\ +bodyindents = u"""\ <document source="<string>"> -<paragraph> -Test -</paragraph> -<transition/> -<paragraph> -Test. \xe4\xf6\xfc€ -</paragraph> + <paragraph>Test</paragraph> + <transition> + </transition> + <paragraph>Test. \xe4\xf6\xfc€</paragraph> </document> """ -bodyindents = u"""\ +# raw XML +# """"""" + +raw_xml_source = u"""\ +.. raw:: xml + + <root> + <child>Test \xe4\xf6\xfc\u20ac</child> + > + < + + </root> + +.. role:: xml(raw) + :format: xml + +:xml:`<test>inline raw XML</test>`. +""" + +raw_xml = u"""\ <document source="<string>"> - <paragraph>Test</paragraph> - <transition/> - <paragraph>Test. \xe4\xf6\xfc€</paragraph> +<raw format="xml" xml:space="preserve"><root> + <child>Test \xe4\xf6\xfc€</child> + > + < + +</root></raw> +<paragraph><raw classes="xml" format="xml" xml:space="preserve">\ +<test>inline raw XML</test></raw>.</paragraph> </document> """ -bodyindents_old = u"""\ +invalid_raw_xml_source = u"""\ +.. raw:: xml + + <root> + <child>Test \xe4\xf6\xfc\u20ac</child> + </mismatch> + +.. role:: xml(raw) + :format: xml + +:xml:`<test>inline raw XML</test>`. +""" + +invalid_raw_xml = u"""\ <document source="<string>"> - <paragraph> - Test - </paragraph> - <transition/> - <paragraph> - Test. \xe4\xf6\xfc€ - </paragraph> +<raw format="xml" xml:space="preserve"><root> + <child>Test \xe4\xf6\xfc\u20ac</child> +</mismatch></raw> +<paragraph><raw classes="xml" format="xml" xml:space="preserve">\ +<test>inline raw XML</test></raw>.</paragraph> </document> """ -# New formatting introduced in versions 2.7.3 and 3.2.3 on 2011-11-18 -# to fix http://bugs.python.org/issue4147 -# (Some distributions ship also earlier versions with this patch.) -if (sys.version_info < (2, 7, 3) or - sys.version_info[0] == 3 and sys.version_info < (3, 2, 3)): - whitespace_fix = False -else: - whitespace_fix = True -def publish_xml(settings): +def publish_xml(settings, source): return docutils.core.publish_string(source=source.encode('utf8'), reader_name='standalone', writer_name='docutils_xml', settings_overrides=settings) +# XML Test Case +# ------------- class DocutilsXMLTestCase(DocutilsTestSupport.StandardTestCase): settings = {'input_encoding': 'utf8', 'output_encoding': 'iso-8859-1', - '_disable_config': 1} + '_disable_config': True, + 'indents': False, + 'newlines': True, + 'xml_declaration': False, + 'doctype_declaration': False, + } def test_publish(self): - for self.settings['xml_declaration'] in True, False: - for self.settings['doctype_declaration'] in True, False: + settings = self.settings.copy() + settings['newlines'] = False + for settings['xml_declaration'] in True, False: + for settings['doctype_declaration'] in True, False: expected = u'' - if self.settings['xml_declaration']: + if settings['xml_declaration']: expected += xmldecl - if self.settings['doctype_declaration']: + if settings['doctype_declaration']: expected += doctypedecl expected += generatedby expected += bodynormal - result = publish_xml(self.settings) + result = publish_xml(settings, source) self.assertEqual(result, expected.encode('latin1')) def test_publish_indents(self): - self.settings['indents'] = True - self.settings['newlines'] = False - self.settings['xml_declaration'] = False - self.settings['doctype_declaration'] = False - result = publish_xml(self.settings) - - # New formatting introduced in versions 2.7.3 and 3.2.3 - if whitespace_fix: - expected = (generatedby + bodyindents).encode('latin1') - else: - expected = (generatedby + bodyindents_old).encode('latin1') - # Some distributions patch also earlier versions: - if (result != expected and not whitespace_fix): - expected = (generatedby + bodyindents).encode('latin1') - + settings = self.settings.copy() + settings['indents'] = True + result = publish_xml(settings, source) + expected = (generatedby + bodyindents).encode('latin1') self.assertEqual(result, expected) def test_publish_newlines(self): - self.settings['newlines'] = True - self.settings['indents'] = False - self.settings['xml_declaration'] = False - self.settings['doctype_declaration'] = False - result = publish_xml(self.settings) + settings = self.settings.copy() + result = publish_xml(settings, source) + expected = (generatedby + bodynewlines).encode('latin1') + self.assertEqual(result, expected) - # New formatting introduced in versions 2.7.3 and 3.2.3 - if whitespace_fix: - expected = (generatedby + bodynewlines).encode('latin1') - else: - expected = (generatedby + bodynewlines_old).encode('latin1') - # Some distributions patch also earlier versions: - if (result != expected and not whitespace_fix): - expected = (generatedby + bodynewlines).encode('latin1') + def test_raw_xml(self): + result = publish_xml(self.settings, raw_xml_source) + expected = (generatedby + + raw_xml).encode('latin1', 'xmlcharrefreplace') + self.assertEqual(result, expected) + def test_invalid_raw_xml(self): + warnings = StringIO() + settings = self.settings.copy() + settings['warning_stream'] = warnings + result = publish_xml(settings, invalid_raw_xml_source) + expected = (generatedby + + invalid_raw_xml).encode('latin1', 'xmlcharrefreplace') self.assertEqual(result, expected) + warnings.seek(0) + self.assertEqual(warnings.readlines(), + [u'<string>:5: ' + u'(WARNING/2) Invalid raw XML in column 2, line offset 3:\n', + u'<root>\n', + u' <child>Test \xe4\xf6\xfc\u20ac</child>\n', + u'</mismatch>\n', + u'<string>:10: ' + u'(WARNING/2) Invalid raw XML in column 30, line offset 1:\n', + u'<test>inline raw XML</test>\n']) + # abort with SystemMessage if halt_level is "info": + settings['halt_level'] = 2 + settings['warning_stream'] = '' + self.assertRaises(docutils.utils.SystemMessage, + publish_xml, settings, invalid_raw_xml_source) if __name__ == '__main__': This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mi...@us...> - 2012-01-19 11:32:05
|
Revision: 7316 http://docutils.svn.sourceforge.net/docutils/?rev=7316&view=rev Author: milde Date: 2012-01-19 11:31:58 +0000 (Thu, 19 Jan 2012) Log Message: ----------- SafeString: normalize filename quoting for EnvironmentError exceptions. Modified Paths: -------------- trunk/docutils/docutils/_compat.py trunk/docutils/docutils/error_reporting.py trunk/docutils/test/test_parsers/test_rst/test_directives/test_raw.py trunk/docutils/test/test_parsers/test_rst/test_directives/test_tables.py Modified: trunk/docutils/docutils/_compat.py =================================================================== --- trunk/docutils/docutils/_compat.py 2012-01-18 10:16:20 UTC (rev 7315) +++ trunk/docutils/docutils/_compat.py 2012-01-19 11:31:58 UTC (rev 7316) @@ -10,7 +10,8 @@ * bytes (name of byte string type; str in 2.x, bytes in 3.x) * b (function converting a string literal to an ASCII byte string; can be also used to convert a Unicode string into a byte string) -* u_prefix (unicode repr prefix, 'u' in 2.x, nothing in 3.x) +* u_prefix (unicode repr prefix: 'u' in 2.x, '' in 3.x) + (Required in docutils/test/test_publisher.py) * BytesIO (a StringIO class that works with bytestrings) """ Modified: trunk/docutils/docutils/error_reporting.py =================================================================== --- trunk/docutils/docutils/error_reporting.py 2012-01-18 10:16:20 UTC (rev 7315) +++ trunk/docutils/docutils/error_reporting.py 2012-01-19 11:31:58 UTC (rev 7316) @@ -95,14 +95,17 @@ * else decode with `self.encoding` and `self.decoding_errors`. """ try: - return unicode(self.data) + u = unicode(self.data) + if isinstance(self.data, EnvironmentError): + u = u.replace(": u'", ": '") # normalize filename quoting + return u except UnicodeError, error: # catch ..Encode.. and ..Decode.. errors if isinstance(self.data, EnvironmentError): return u"[Errno %s] %s: '%s'" % (self.data.errno, SafeString(self.data.strerror, self.encoding, - self.decoding_errors), + self.decoding_errors), SafeString(self.data.filename, self.encoding, - self.decoding_errors)) + self.decoding_errors)) if isinstance(self.data, Exception): args = [unicode(SafeString(arg, self.encoding, decoding_errors=self.decoding_errors)) Modified: trunk/docutils/test/test_parsers/test_rst/test_directives/test_raw.py =================================================================== --- trunk/docutils/test/test_parsers/test_rst/test_directives/test_raw.py 2012-01-18 10:16:20 UTC (rev 7315) +++ trunk/docutils/test/test_parsers/test_rst/test_directives/test_raw.py 2012-01-19 11:31:58 UTC (rev 7316) @@ -11,7 +11,7 @@ import os.path import sys from __init__ import DocutilsTestSupport -from docutils._compat import u_prefix, b +from docutils._compat import b def suite(): s = DocutilsTestSupport.ParserTestSuite() @@ -158,25 +158,14 @@ <system_message level="4" line="1" source="test data" type="SEVERE"> <paragraph> Problems with "raw" directive path: - IOError: [Errno 2] No such file or directory: %s'non-existent.file'. + IOError: [Errno 2] No such file or directory: 'non-existent.file'. <literal_block xml:space="preserve"> .. raw:: html :file: non-existent.file -""" % u_prefix], +"""], # note that this output is rewritten below for certain python versions ] -# Rewrite tests that depend on the output of IOError as it is -# platform-dependent before python 2.4 for a unicode path. -if sys.version_info < (2, 4): - # remove the unicode repr u except for py2.3 on windows: - if not sys.platform.startswith('win') or sys.version_info < (2, 3): - for i in range(len(totest['raw'])): - if totest['raw'][i][1].find("u'non-existent.file'") != -1: - totest['raw'][i][1] = totest['raw'][i][1].replace( - "u'non-existent.file'", "'non-existent.file'") - - if __name__ == '__main__': import unittest unittest.main(defaultTest='suite') Modified: trunk/docutils/test/test_parsers/test_rst/test_directives/test_tables.py =================================================================== --- trunk/docutils/test/test_parsers/test_rst/test_directives/test_tables.py 2012-01-18 10:16:20 UTC (rev 7315) +++ trunk/docutils/test/test_parsers/test_rst/test_directives/test_tables.py 2012-01-19 11:31:58 UTC (rev 7316) @@ -12,7 +12,6 @@ import os import csv -from docutils._compat import u_prefix from docutils.parsers.rst.directives import tables @@ -558,11 +557,11 @@ <system_message level="4" line="1" source="test data" type="SEVERE"> <paragraph> Problems with "csv-table" directive path: - [Errno 2] No such file or directory: %s'bogus.csv'. + [Errno 2] No such file or directory: 'bogus.csv'. <literal_block xml:space="preserve"> .. csv-table:: no such file :file: bogus.csv -""" % u_prefix], +"""], # note that this output is rewritten below for certain python versions ["""\ .. csv-table:: bad URL This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mi...@us...> - 2012-01-19 11:55:33
|
Revision: 7317 http://docutils.svn.sourceforge.net/docutils/?rev=7317&view=rev Author: milde Date: 2012-01-19 11:55:26 +0000 (Thu, 19 Jan 2012) Log Message: ----------- Fix handling of missing stylesheets. Updated and simplied tests. Missing stylesheets are no reason to abort conversion: Report as error and insert a comment in the output doc. Modified Paths: -------------- trunk/docutils/HISTORY.txt trunk/docutils/docutils/writers/__init__.py trunk/docutils/docutils/writers/html4css1/__init__.py trunk/docutils/docutils/writers/latex2e/__init__.py trunk/docutils/test/test_writers/test_latex2e.py Added Paths: ----------- trunk/docutils/test/functional/expected/stylesheet_path_html4css1.html trunk/docutils/test/functional/tests/stylesheet_path_html4css1.py Removed Paths: ------------- trunk/docutils/test/data/hidden.css trunk/docutils/test/data/spam.sty trunk/docutils/test/functional/expected/multistyle_path_embed_rst_html4css1.html trunk/docutils/test/functional/expected/multistyle_path_rst_html4css1.html trunk/docutils/test/functional/expected/multistyle_rst_html4css1.html trunk/docutils/test/functional/tests/multistyle_path_embedd_rst_html4css1.py trunk/docutils/test/functional/tests/multistyle_path_rst_html4css1.py trunk/docutils/test/functional/tests/multistyle_rst_html4css1.py Modified: trunk/docutils/HISTORY.txt =================================================================== --- trunk/docutils/HISTORY.txt 2012-01-19 11:31:58 UTC (rev 7316) +++ trunk/docutils/HISTORY.txt 2012-01-19 11:55:26 UTC (rev 7317) @@ -13,17 +13,15 @@ .. contents:: - Changes Since 0.8.1 =================== * General: - - reStructuredText "code" role and directive with syntax highlighting - by Pygments_. - - "code" option of the "include" directive. + - New reStructuredText "code" role and directive and "code" option + of the "include" directive with syntax highlighting by Pygments_. - Fix parse_option_marker for option arguments containing ``=``. - + .. _Pygments: http://pygments.org/ * setup.py @@ -61,16 +59,17 @@ - Support the `abbreviation` and `acronym` standard roles. - Record only files required to generate the LaTeX source as dependencies. + - Fix handling of missing stylesheets. * docutils/writers/html4css1/__init__.py - Change default for `math-output` setting to MathJax. + - Fix handling of missing stylesheets. * docutils/writers/docutils_xml.py - - Use the visitor pattern with default methods instead of minidom - to facilitate special handling of selected nodes. - + - Use the visitor pattern with default_visit()/default_depart() methods + instead of minidom to facilitate special handling of selected nodes. - Support raw XML (inserted as-is inside a <raw></raw> node). Release 0.8.1 (2011-08-30) Modified: trunk/docutils/docutils/writers/__init__.py =================================================================== --- trunk/docutils/docutils/writers/__init__.py 2012-01-19 11:31:58 UTC (rev 7316) +++ trunk/docutils/docutils/writers/__init__.py 2012-01-19 11:55:26 UTC (rev 7317) @@ -52,7 +52,7 @@ def __init__(self): - # Used by HTML and LaTex writer for output fragments: + # Used by HTML and LaTeX writer for output fragments: self.parts = {} """Mapping of document part names to fragments of `self.output`. Values are Unicode strings; encoding is up to the client. The 'whole' Modified: trunk/docutils/docutils/writers/html4css1/__init__.py =================================================================== --- trunk/docutils/docutils/writers/html4css1/__init__.py 2012-01-19 11:31:58 UTC (rev 7316) +++ trunk/docutils/docutils/writers/html4css1/__init__.py 2012-01-19 11:55:26 UTC (rev 7317) @@ -1,5 +1,6 @@ # $Id$ -# Author: David Goodger <go...@py...> +# Author: David Goodger +# Maintainer: doc...@li... # Copyright: This module has been placed in the public domain. """ @@ -31,6 +32,7 @@ PIL = None import docutils from docutils import frontend, nodes, utils, writers, languages, io +from docutils.error_reporting import SafeString from docutils.transforms import writer_aux from docutils.math import unichar2tex, pick_math_environment from docutils.math.latex2mathml import parse_latex_math @@ -286,19 +288,8 @@ # encoding not interpolated: self.html_prolog.append(self.xml_declaration) self.head = self.meta[:] - # stylesheets - styles = utils.get_stylesheet_list(settings) - if settings.stylesheet_path and not(settings.embed_stylesheet): - styles = [utils.relative_path(settings._destination, sheet) - for sheet in styles] - if settings.embed_stylesheet: - self.stylesheet = [self.embedded_stylesheet % - io.FileInput(source_path=sheet, encoding='utf-8').read() - for sheet in styles] - settings.record_dependencies.add(*styles) - else: # link to stylesheets - self.stylesheet = [self.stylesheet_link % self.encode(stylesheet) - for stylesheet in styles] + self.stylesheet = [self.stylesheet_call(path) + for path in utils.get_stylesheet_list(settings)] self.body_prefix = ['</head>\n<body>\n'] # document title, subtitle display self.body_pre_docinfo = [] @@ -377,6 +368,26 @@ encoded = encoded.replace('.', '.') return encoded + def stylesheet_call(self, path): + """Return code to reference or embed stylesheet file `path`""" + if self.settings.embed_stylesheet: + try: + content = io.FileInput(source_path=path, + encoding='utf-8', + handle_io_errors=False).read() + self.settings.record_dependencies.add(path) + except IOError, err: + msg = u"Cannot embed stylesheet '%s': %s." % ( + path, SafeString(err.strerror)) + self.document.reporter.error(msg) + return '<--- %s --->\n' % msg + return self.embedded_stylesheet % content + # else link to style file: + if self.settings.stylesheet_path: + # adapt path relative to output (cf. config.html#stylesheet-path) + path = utils.relative_path(self.settings._destination, path) + return self.stylesheet_link % self.encode(path) + def starttag(self, node, tagname, suffix='\n', empty=0, **attributes): """ Construct and return a start tag given a node (id & class attributes Modified: trunk/docutils/docutils/writers/latex2e/__init__.py =================================================================== --- trunk/docutils/docutils/writers/latex2e/__init__.py 2012-01-19 11:31:58 UTC (rev 7316) +++ trunk/docutils/docutils/writers/latex2e/__init__.py 2012-01-19 11:55:26 UTC (rev 7317) @@ -1,6 +1,7 @@ # .. coding: utf8 # $Id$ -# Author: Engelbert Gruber <gr...@us...> +# Author: Engelbert Gruber, Günter Milde +# Maintainer: doc...@li... # Copyright: This module has been placed in the public domain. """LaTeX2e document tree Writer.""" @@ -19,6 +20,7 @@ import string import urllib from docutils import frontend, nodes, languages, writers, utils, io +from docutils.error_reporting import SafeString from docutils.transforms import writer_aux from docutils.math import pick_math_environment, unichar2tex @@ -492,11 +494,6 @@ \DUprovidelength{\DUdocinfowidth}{0.9\textwidth}""" # PreambleCmds.docinfo._depends = 'providelength' -PreambleCmds.embedded_package_wrapper = r"""\makeatletter -%% embedded stylesheet: %s -%s -\makeatother""" - PreambleCmds.dedication = r""" % dedication topic \providecommand{\DUtopicdedication}[1]{\begin{center}#1\end{center}}""" @@ -970,7 +967,6 @@ self.use_latex_toc = settings.use_latex_toc self.use_latex_docinfo = settings.use_latex_docinfo self._use_latex_citations = settings.use_latex_citations - self.embed_stylesheet = settings.embed_stylesheet self._reference_label = settings.reference_label self.hyperlink_color = settings.hyperlink_color self.compound_enumerators = settings.compound_enumerators @@ -1037,7 +1033,6 @@ self.requirements = SortableDict() # made a list in depart_document() self.requirements['__static'] = r'\usepackage{ifthen}' self.latex_preamble = [settings.latex_preamble] - self.stylesheet = [] self.fallbacks = SortableDict() # made a list in depart_document() self.pdfsetup = [] # PDF properties (hyperref package) self.title = [] @@ -1109,30 +1104,10 @@ self.requirements['typearea'] = r'\usepackage{typearea}' # Stylesheets - # get list of style sheets from settings - styles = utils.get_stylesheet_list(settings) - # adapt path if --stylesheet_path is used - if settings.stylesheet_path and not(self.embed_stylesheet): - styles = [utils.relative_path(settings._destination, sheet) - for sheet in styles] - for sheet in styles: - (base, ext) = os.path.splitext(sheet) - is_package = ext in ['.sty', ''] - if self.embed_stylesheet: - if is_package: - sheet = base + '.sty' # adapt package name - # wrap in \makeatletter, \makeatother - wrapper = PreambleCmds.embedded_package_wrapper - else: - wrapper = '%% embedded stylesheet: %s\n%s' - settings.record_dependencies.add(sheet) - self.stylesheet.append(wrapper % - (sheet, io.FileInput(source_path=sheet, encoding='utf-8').read())) - else: # link to style sheet - if is_package: - self.stylesheet.append(r'\usepackage{%s}' % base) - else: - self.stylesheet.append(r'\input{%s}' % sheet) + # (the name `self.stylesheet` is singular because only one + # stylesheet was supported before Docutils 0.6). + self.stylesheet = [self.stylesheet_call(path) + for path in utils.get_stylesheet_list(settings)] # PDF setup if self.hyperlink_color in ('0', 'false', 'False', ''): @@ -1150,7 +1125,11 @@ ## self.requirements['tocdepth'] = (r'\setcounter{tocdepth}{%d}' % ## len(self.d_class.sections)) - # LaTeX section numbering + # Section numbering + # TODO: use \secnumdepth instead of starred commands + ## if self.settings.sectnum_xform: # section numbering by Docutils + ## sectnum_depth = 0 + ## else: if not self.settings.sectnum_xform: # section numbering by LaTeX: # sectnum_depth: # None "sectnum" directive without depth arg -> LaTeX default @@ -1180,7 +1159,7 @@ self.requirements['sectnum_start'] = ( r'\setcounter{%s}{%d}' % (self.d_class.sections[0], settings.sectnum_start-1)) - # currently ignored (configure in a stylesheet): + # TODO: currently ignored (configure in a stylesheet): ## settings.sectnum_prefix ## settings.sectnum_suffix @@ -1188,6 +1167,41 @@ # Auxiliary Methods # ----------------- + def stylesheet_call(self, path): + """Return code to reference or embed stylesheet file `path`""" + # is it a package (no extension or *.sty) or "normal" tex code: + (base, ext) = os.path.splitext(path) + is_package = ext in ['.sty', ''] + # Embed content of style file: + if self.settings.embed_stylesheet: + if is_package: + path = base + '.sty' # ensure extension + try: + content = io.FileInput(source_path=path, + encoding='utf-8', + handle_io_errors=False).read() + self.settings.record_dependencies.add(path) + except IOError, err: + msg = u"Cannot embed stylesheet '%s':\n %s." % ( + path, SafeString(err.strerror)) + self.document.reporter.error(msg) + return '% ' + msg.replace('\n', '\n% ') + if is_package: + content = '\n'.join([r'\makeatletter', + content, + r'\makeatother']) + return '%% embedded stylesheet: %s\n%s' % (path, content) + # Link to style file: + if is_package: + path = base # drop extension + cmd = r'\usepackage{%s}' + else: + cmd = r'\input{%s}' + if self.settings.stylesheet_path: + # adapt path relative to output (cf. config.html#stylesheet-path) + path = utils.relative_path(self.settings._destination, path) + return cmd % path + def to_latex_encoding(self,docutils_encoding): """Translate docutils encoding name into LaTeX's. Deleted: trunk/docutils/test/data/hidden.css =================================================================== --- trunk/docutils/test/data/hidden.css 2012-01-19 11:31:58 UTC (rev 7316) +++ trunk/docutils/test/data/hidden.css 2012-01-19 11:55:26 UTC (rev 7317) @@ -1,2 +0,0 @@ -.hidden { - display: none } Deleted: trunk/docutils/test/data/spam.sty =================================================================== --- trunk/docutils/test/data/spam.sty 2012-01-19 11:31:58 UTC (rev 7316) +++ trunk/docutils/test/data/spam.sty 2012-01-19 11:55:26 UTC (rev 7317) @@ -1,3 +0,0 @@ -\ProvidesPackage{spam} -[2008/12/09 v0.2 simple silly test package] -\newcommand{\spam}{\@percentchar\ wonderfull spam} Deleted: trunk/docutils/test/functional/expected/multistyle_path_embed_rst_html4css1.html =================================================================== --- trunk/docutils/test/functional/expected/multistyle_path_embed_rst_html4css1.html 2012-01-19 11:31:58 UTC (rev 7316) +++ trunk/docutils/test/functional/expected/multistyle_path_embed_rst_html4css1.html 2012-01-19 11:55:26 UTC (rev 7317) @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head> -<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="generator" content="Docutils 0.9: http://docutils.sourceforge.net/" /> -<title></title> -<style type="text/css"> - -.hidden { - display: none } - -</style> -<style type="text/css"> - -dl.docutils dd { - margin-bottom: 0.5em } - -</style> -</head> -<body> -<div class="document"> - - -<p>simple input</p> -</div> -</body> -</html> Deleted: trunk/docutils/test/functional/expected/multistyle_path_rst_html4css1.html =================================================================== --- trunk/docutils/test/functional/expected/multistyle_path_rst_html4css1.html 2012-01-19 11:31:58 UTC (rev 7316) +++ trunk/docutils/test/functional/expected/multistyle_path_rst_html4css1.html 2012-01-19 11:55:26 UTC (rev 7317) @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head> -<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="generator" content="Docutils 0.9: http://docutils.sourceforge.net/" /> -<title></title> -<link rel="stylesheet" href="../../ham.css" type="text/css" /> -<link rel="stylesheet" href="../../path/to/spam.css" type="text/css" /> -</head> -<body> -<div class="document"> - - -<p>simple input</p> -</div> -</body> -</html> Deleted: trunk/docutils/test/functional/expected/multistyle_rst_html4css1.html =================================================================== --- trunk/docutils/test/functional/expected/multistyle_rst_html4css1.html 2012-01-19 11:31:58 UTC (rev 7316) +++ trunk/docutils/test/functional/expected/multistyle_rst_html4css1.html 2012-01-19 11:55:26 UTC (rev 7317) @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head> -<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="generator" content="Docutils 0.9: http://docutils.sourceforge.net/" /> -<title></title> -<link rel="stylesheet" href="ham.css" type="text/css" /> -<link rel="stylesheet" href="/spam.css" type="text/css" /> -</head> -<body> -<div class="document"> - - -<p>simple input</p> -</div> -</body> -</html> Copied: trunk/docutils/test/functional/expected/stylesheet_path_html4css1.html (from rev 7307, trunk/docutils/test/functional/expected/multistyle_path_rst_html4css1.html) =================================================================== --- trunk/docutils/test/functional/expected/stylesheet_path_html4css1.html (rev 0) +++ trunk/docutils/test/functional/expected/stylesheet_path_html4css1.html 2012-01-19 11:55:26 UTC (rev 7317) @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<meta name="generator" content="Docutils 0.9: http://docutils.sourceforge.net/" /> +<title></title> +<link rel="stylesheet" href="../../data/ham.css" type="text/css" /> +<link rel="stylesheet" href="/missing.css" type="text/css" /> +</head> +<body> +<div class="document"> + + +<p>simple input</p> +</div> +</body> +</html> Deleted: trunk/docutils/test/functional/tests/multistyle_path_embedd_rst_html4css1.py =================================================================== --- trunk/docutils/test/functional/tests/multistyle_path_embedd_rst_html4css1.py 2012-01-19 11:31:58 UTC (rev 7316) +++ trunk/docutils/test/functional/tests/multistyle_path_embedd_rst_html4css1.py 2012-01-19 11:55:26 UTC (rev 7317) @@ -1,14 +0,0 @@ -# Source and destination file names. -test_source = "simple.txt" -test_destination = "multistyle_path_embed_rst_html4css1.html" - -# Keyword parameters passed to publish_file. -reader_name = "standalone" -parser_name = "rst" -writer_name = "html4css1" - -# Settings -# test for encoded attribute value: -settings_overrides['stylesheet'] = '' -settings_overrides['stylesheet_path'] = 'data/hidden.css,data/ham.css' -settings_overrides['embed_stylesheet'] = 1 Deleted: trunk/docutils/test/functional/tests/multistyle_path_rst_html4css1.py =================================================================== --- trunk/docutils/test/functional/tests/multistyle_path_rst_html4css1.py 2012-01-19 11:31:58 UTC (rev 7316) +++ trunk/docutils/test/functional/tests/multistyle_path_rst_html4css1.py 2012-01-19 11:55:26 UTC (rev 7317) @@ -1,14 +0,0 @@ -# Source and destination file names. -test_source = "simple.txt" -test_destination = "multistyle_path_rst_html4css1.html" - -# Keyword parameters passed to publish_file. -reader_name = "standalone" -parser_name = "rst" -writer_name = "html4css1" - -# Settings -# test for encoded attribute value: -settings_overrides['stylesheet'] = '' -settings_overrides['stylesheet_path'] = 'ham.css,path/to/spam.css' -settings_overrides['embed_stylesheet'] = 0 Deleted: trunk/docutils/test/functional/tests/multistyle_rst_html4css1.py =================================================================== --- trunk/docutils/test/functional/tests/multistyle_rst_html4css1.py 2012-01-19 11:31:58 UTC (rev 7316) +++ trunk/docutils/test/functional/tests/multistyle_rst_html4css1.py 2012-01-19 11:55:26 UTC (rev 7317) @@ -1,14 +0,0 @@ -# Source and destination file names. -test_source = "simple.txt" -test_destination = "multistyle_rst_html4css1.html" - -# Keyword parameters passed to publish_file. -reader_name = "standalone" -parser_name = "rst" -writer_name = "html4css1" - -# Settings -# test for encoded attribute value: -settings_overrides['stylesheet'] = 'ham.css,/spam.css' -settings_overrides['stylesheet_path'] = '' -settings_overrides['embed_stylesheet'] = 0 Copied: trunk/docutils/test/functional/tests/stylesheet_path_html4css1.py (from rev 7307, trunk/docutils/test/functional/tests/multistyle_path_embedd_rst_html4css1.py) =================================================================== --- trunk/docutils/test/functional/tests/stylesheet_path_html4css1.py (rev 0) +++ trunk/docutils/test/functional/tests/stylesheet_path_html4css1.py 2012-01-19 11:55:26 UTC (rev 7317) @@ -0,0 +1,15 @@ +# Test re-writing of stylesheet paths relative to output directory + +# Source and destination file names. +test_source = "simple.txt" +test_destination = "stylesheet_path_html4css1.html" + +# Keyword parameters passed to publish_file. +reader_name = "standalone" +parser_name = "rst" +writer_name = "html4css1" + +# Settings +settings_overrides['stylesheet'] = '' +settings_overrides['stylesheet_path'] = 'data/ham.css,/missing.css' +settings_overrides['embed_stylesheet'] = False Modified: trunk/docutils/test/test_writers/test_latex2e.py =================================================================== --- trunk/docutils/test/test_writers/test_latex2e.py 2012-01-19 11:31:58 UTC (rev 7316) +++ trunk/docutils/test/test_writers/test_latex2e.py 2012-01-19 11:55:26 UTC (rev 7317) @@ -17,23 +17,22 @@ from __init__ import DocutilsTestSupport -from docutils._compat import b - def suite(): - settings = {'use_latex_toc': 0} + settings = {'use_latex_toc': False} s = DocutilsTestSupport.PublishTestSuite('latex', suite_settings=settings) s.generateTests(totest) - settings['use_latex_toc'] = 1 + settings['use_latex_toc'] = True s.generateTests(totest_latex_toc) - settings['use_latex_toc'] = 0 - settings['sectnum_xform'] = 0 + settings['use_latex_toc'] = False + settings['sectnum_xform'] = False s.generateTests(totest_latex_sectnum) - settings['sectnum_xform'] = 1 - settings['use_latex_citations'] = 1 + settings['sectnum_xform'] = True + settings['use_latex_citations'] = True s.generateTests(totest_latex_citations) settings['stylesheet_path'] = 'data/spam,data/ham.tex' s.generateTests(totest_stylesheet) - settings['embed_stylesheet'] = 1 + settings['embed_stylesheet'] = True + settings['warning_stream'] = '' s.generateTests(totest_stylesheet_embed) return s @@ -659,13 +658,8 @@ # input ["""two stylesheets embedded in the header""", head_template.substitute(dict(parts, stylesheet = -r"""\makeatletter -% embedded stylesheet: data/spam.sty -\ProvidesPackage{spam} -[2008/12/09 v0.2 simple silly test package] -\newcommand{\spam}{\@percentchar\ wonderfull spam} - -\makeatother +r"""% Cannot embed stylesheet 'data/spam.sty': +% No such file or directory. % embedded stylesheet: data/ham.tex \newcommand{\ham}{wonderful ham} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mi...@us...> - 2012-01-19 22:33:10
|
Revision: 7320 http://docutils.svn.sourceforge.net/docutils/?rev=7320&view=rev Author: milde Date: 2012-01-19 22:33:02 +0000 (Thu, 19 Jan 2012) Log Message: ----------- Cleanup: Use True/False for boolean values Modified Paths: -------------- trunk/docutils/docutils/core.py trunk/docutils/docutils/examples.py trunk/docutils/docutils/nodes.py trunk/docutils/docutils/parsers/rst/__init__.py trunk/docutils/docutils/parsers/rst/directives/html.py trunk/docutils/docutils/parsers/rst/directives/misc.py trunk/docutils/docutils/parsers/rst/states.py trunk/docutils/docutils/parsers/rst/tableparser.py trunk/docutils/docutils/readers/pep.py trunk/docutils/docutils/statemachine.py trunk/docutils/docutils/transforms/references.py trunk/docutils/docutils/transforms/writer_aux.py trunk/docutils/docutils/utils/__init__.py trunk/docutils/docutils/writers/html4css1/__init__.py trunk/docutils/docutils/writers/latex2e/__init__.py trunk/docutils/docutils/writers/pseudoxml.py trunk/docutils/docutils/writers/s5_html/__init__.py trunk/docutils/test/DocutilsTestSupport.py trunk/docutils/test/functional/tests/_default.py trunk/docutils/test/functional/tests/dangerous.py trunk/docutils/test/functional/tests/field_name_limit.py trunk/docutils/test/functional/tests/misc_rst_html4css1.py trunk/docutils/test/package_unittest.py trunk/docutils/test/test_nodes.py trunk/docutils/test/test_statemachine.py trunk/docutils/test/test_writers/test_html4css1_misc.py Modified: trunk/docutils/docutils/core.py =================================================================== --- trunk/docutils/docutils/core.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/docutils/core.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -111,7 +111,7 @@ #@@@ Add self.source & self.destination to components in future? option_parser = OptionParser( components=(self.parser, self.reader, self.writer, settings_spec), - defaults=defaults, read_config_files=1, + defaults=defaults, read_config_files=True, usage=usage, description=description) return option_parser @@ -193,7 +193,7 @@ 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=False): """ Process command line options and arguments (if `self.settings` not already set), run `self.reader` and then `self.writer`. Return @@ -316,7 +316,7 @@ writer=None, writer_name='pseudoxml', settings=None, settings_spec=None, settings_overrides=None, config_section=None, - enable_exit_status=1, argv=None, + enable_exit_status=True, argv=None, usage=default_usage, description=default_description): """ Set up & run a `Publisher` for command-line-based file I/O (input and @@ -344,7 +344,7 @@ parser=None, parser_name='restructuredtext', writer=None, writer_name='pseudoxml', settings=None, settings_spec=None, settings_overrides=None, - config_section=None, enable_exit_status=None): + config_section=None, enable_exit_status=False): """ Set up & run a `Publisher` for programmatic use with file-like I/O. Return the encoded string output also. @@ -370,7 +370,7 @@ writer=None, writer_name='pseudoxml', settings=None, settings_spec=None, settings_overrides=None, config_section=None, - enable_exit_status=None): + enable_exit_status=False): """ Set up & run a `Publisher` for programmatic use with string I/O. Return the encoded string or Unicode string output. @@ -407,7 +407,7 @@ writer=None, writer_name='pseudoxml', settings=None, settings_spec=None, settings_overrides=None, config_section=None, - enable_exit_status=None): + enable_exit_status=False): """ Set up & run a `Publisher`, and return a dictionary of document parts. Dictionary keys are the names of parts, and values are Unicode strings; @@ -440,7 +440,7 @@ parser=None, parser_name='restructuredtext', settings=None, settings_spec=None, settings_overrides=None, config_section=None, - enable_exit_status=None): + enable_exit_status=False): """ Set up & run a `Publisher` for programmatic use with string I/O. Return the document tree. @@ -469,7 +469,7 @@ writer=None, writer_name='pseudoxml', settings=None, settings_spec=None, settings_overrides=None, config_section=None, - enable_exit_status=None): + enable_exit_status=False): """ Set up & run a `Publisher` to render from an existing document tree data structure, for programmatic use with string I/O. Return @@ -509,7 +509,7 @@ writer=None, writer_name='pseudoxml', settings=None, settings_spec=None, settings_overrides=None, config_section=None, - enable_exit_status=1, argv=None, + enable_exit_status=True, argv=None, usage=default_usage, description=default_description, destination=None, destination_class=io.BinaryFileOutput ): Modified: trunk/docutils/docutils/examples.py =================================================================== --- trunk/docutils/docutils/examples.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/docutils/examples.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -15,7 +15,8 @@ def html_parts(input_string, source_path=None, destination_path=None, - input_encoding='unicode', doctitle=1, initial_header_level=1): + input_encoding='unicode', doctitle=True, + initial_header_level=1): """ Given an input string, returns a dictionary of HTML document parts. @@ -50,7 +51,7 @@ def html_body(input_string, source_path=None, destination_path=None, input_encoding='unicode', output_encoding='unicode', - doctitle=1, initial_header_level=1): + doctitle=True, initial_header_level=1): """ Given an input string, returns an HTML fragment as a string. Modified: trunk/docutils/docutils/nodes.py =================================================================== --- trunk/docutils/docutils/nodes.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/docutils/nodes.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -120,7 +120,7 @@ Return true if we should stop the traversal. """ - stop = 0 + stop = False visitor.document.reporter.debug( 'docutils.nodes.Node.walk calling dispatch_visit for %s' % self.__class__.__name__) @@ -135,12 +135,12 @@ try: for child in children[:]: if child.walk(visitor): - stop = 1 + stop = True break except SkipSiblings: pass except StopTraversal: - stop = 1 + stop = True return stop def walkabout(self, visitor): @@ -155,8 +155,8 @@ Return true if we should stop the traversal. """ - call_depart = 1 - stop = 0 + call_depart = True + stop = False visitor.document.reporter.debug( 'docutils.nodes.Node.walkabout calling dispatch_visit for %s' % self.__class__.__name__) @@ -166,19 +166,19 @@ except SkipNode: return stop except SkipDeparture: - call_depart = 0 + call_depart = False children = self.children try: for child in children[:]: if child.walkabout(visitor): - stop = 1 + stop = True break except SkipSiblings: pass except SkipChildren: pass except StopTraversal: - stop = 1 + stop = True if call_depart: visitor.document.reporter.debug( 'docutils.nodes.Node.walkabout calling dispatch_departure ' @@ -203,8 +203,8 @@ result.extend(child._all_traverse()) return result - def traverse(self, condition=None, - include_self=1, descend=1, siblings=0, ascend=0): + def traverse(self, condition=None, include_self=True, descend=True, + siblings=False, ascend=False): """ Return an iterable containing @@ -236,12 +236,12 @@ [<emphasis>, <strong>, <#text: Foo>, <#text: Bar>] - and list(strong.traverse(ascend=1)) equals :: + and list(strong.traverse(ascend=True)) equals :: [<strong>, <#text: Foo>, <#text: Bar>, <reference>, <#text: Baz>] """ if ascend: - siblings=1 + siblings=True # Check for special argument combinations that allow using an # optimized version of traverse() if include_self and descend and not siblings: @@ -260,16 +260,17 @@ r.append(self) if descend and len(self.children): for child in self: - r.extend(child.traverse( - include_self=1, descend=1, siblings=0, ascend=0, - condition=condition)) + r.extend(child.traverse(include_self=True, descend=True, + siblings=False, ascend=False, + condition=condition)) if siblings or ascend: node = self while node.parent: index = node.parent.index(node) for sibling in node.parent[index+1:]: - r.extend(sibling.traverse(include_self=1, descend=descend, - siblings=0, ascend=0, + r.extend(sibling.traverse(include_self=True, + descend=descend, + siblings=False, ascend=False, condition=condition)) if not ascend: break @@ -277,8 +278,8 @@ node = node.parent return r - def next_node(self, condition=None, - include_self=0, descend=1, siblings=0, ascend=0): + def next_node(self, condition=None, include_self=False, descend=True, + siblings=False, ascend=False): """ Return the first node in the iterable returned by traverse(), or None if the iterable is empty. @@ -1112,7 +1113,7 @@ def note_explicit_target(self, target, msgnode=None): id = self.set_id(target, msgnode) - self.set_name_id_map(target, id, msgnode, explicit=1) + self.set_name_id_map(target, id, msgnode, explicit=True) def note_refname(self, node): self.refnames.setdefault(node['refname'], []).append(node) Modified: trunk/docutils/docutils/parsers/rst/__init__.py =================================================================== --- trunk/docutils/docutils/parsers/rst/__init__.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/docutils/parsers/rst/__init__.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -49,12 +49,12 @@ 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.) +passed: ``rfc2822`` and ``inliner``. Pass ``rfc2822=True`` 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 @@ -141,7 +141,7 @@ config_section = 'restructuredtext parser' config_section_dependencies = ('parsers',) - def __init__(self, rfc2822=None, inliner=None): + def __init__(self, rfc2822=False, inliner=None): if rfc2822: self.initial_state = 'RFC2822Body' else: @@ -158,7 +158,7 @@ debug=document.reporter.debug_flag) inputlines = docutils.statemachine.string2lines( inputstring, tab_width=document.settings.tab_width, - convert_whitespace=1) + convert_whitespace=True) self.statemachine.run(inputlines, document, inliner=self.inliner) self.finish_parse() Modified: trunk/docutils/docutils/parsers/rst/directives/html.py =================================================================== --- trunk/docutils/docutils/parsers/rst/directives/html.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/docutils/parsers/rst/directives/html.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -74,7 +74,7 @@ node = nodes.Element() new_line_offset, blank_finish = self.state.nested_list_parse( self.content, self.content_offset, node, - initial_state='MetaBody', blank_finish=1, + initial_state='MetaBody', blank_finish=True, state_machine_kwargs=self.SMkwargs) if (new_line_offset - self.content_offset) != len(self.content): # incomplete parse of block? Modified: trunk/docutils/docutils/parsers/rst/directives/misc.py =================================================================== --- trunk/docutils/docutils/parsers/rst/directives/misc.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/docutils/parsers/rst/directives/misc.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -105,16 +105,16 @@ raise self.severe('Problem with "end-before" option of "%s" ' 'directive:\nText not found.' % self.name) rawtext = rawtext[:before_index] - - include_lines = statemachine.string2lines(rawtext, tab_width, - convert_whitespace=1) + + include_lines = statemachine.string2lines(rawtext, tab_width, + convert_whitespace=True) if 'literal' in self.options: # Convert tabs to spaces, if `tab_width` is positive. if tab_width >= 0: text = rawtext.expandtabs(tab_width) else: text = rawtext - literal_block = nodes.literal_block(rawtext, source=path, + literal_block = nodes.literal_block(rawtext, source=path, classes=self.options.get('class', [])) literal_block.line = 1 self.add_name(literal_block) @@ -130,7 +130,7 @@ tokens = NumberLines([([], text)], startline, endline) for classes, value in tokens: if classes: - literal_block += nodes.inline(value, value, + literal_block += nodes.inline(value, value, classes=classes) else: literal_block += nodes.Text(value, value) @@ -139,7 +139,7 @@ return [literal_block] if 'code' in self.options: self.options['source'] = path - codeblock = CodeBlock(self.name, + codeblock = CodeBlock(self.name, [self.options.pop('code')], # arguments self.options, include_lines, # content @@ -240,7 +240,7 @@ # This will always fail because there is no content. self.assert_has_content() raw_node = nodes.raw('', text, **attributes) - (raw_node.source, + (raw_node.source, raw_node.line) = self.state_machine.get_source_and_line(self.lineno) return [raw_node] Modified: trunk/docutils/docutils/parsers/rst/states.py =================================================================== --- trunk/docutils/docutils/parsers/rst/states.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/docutils/parsers/rst/states.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -145,7 +145,7 @@ The entry point to reStructuredText parsing is the `run()` method. """ - def run(self, input_lines, document, input_offset=0, match_titles=1, + def run(self, input_lines, document, input_offset=0, match_titles=True, inliner=None): """ Parse `input_lines` and modify the `document` node in place. @@ -164,7 +164,7 @@ language=self.language, title_styles=[], section_level=0, - section_bubble_up_kludge=0, + section_bubble_up_kludge=False, inliner=inliner) self.document = document self.attach_observer(document.note_source) @@ -183,7 +183,7 @@ document structures. """ - def run(self, input_lines, input_offset, memo, node, match_titles=1): + def run(self, input_lines, input_offset, memo, node, match_titles=True): """ Parse `input_lines` and populate a `docutils.nodes.document` instance. @@ -213,7 +213,7 @@ nested_sm = NestedStateMachine nested_sm_cache = [] - def __init__(self, state_machine, debug=0): + def __init__(self, state_machine, debug=False): self.nested_sm_kwargs = {'state_classes': state_classes, 'initial_state': 'Body'} StateWS.__init__(self, state_machine, debug) @@ -258,7 +258,7 @@ """Called at beginning of file.""" return [], [] - def nested_parse(self, block, input_offset, node, match_titles=0, + def nested_parse(self, block, input_offset, node, match_titles=False, state_machine_class=None, state_machine_kwargs=None): """ Create a new StateMachine rooted at `node` and run it over the input @@ -299,7 +299,7 @@ blank_finish, blank_finish_state=None, extra_settings={}, - match_titles=0, + match_titles=False, state_machine_class=None, state_machine_kwargs=None): """ @@ -361,7 +361,7 @@ 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 + memo.section_bubble_up_kludge = True # 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 @@ -396,7 +396,7 @@ absoffset = self.state_machine.abs_line_offset() + 1 newabsoffset = self.nested_parse( self.state_machine.input_lines[offset:], input_offset=absoffset, - node=section_node, match_titles=1) + node=section_node, match_titles=True) self.goto_line(newabsoffset) if memo.section_level <= mylevel: # can't handle next section? raise EOFError # bubble up to supersection @@ -438,7 +438,7 @@ line=lineno) -def build_regexp(definition, compile=1): +def build_regexp(definition, compile=True): """ Build, compile and return a regular expression based on `definition`. @@ -695,7 +695,7 @@ return punctuation_chars.match_chars(prestart, poststart) def inline_obj(self, match, lineno, end_pattern, nodeclass, - restore_backslashes=0): + restore_backslashes=False): string = match.string matchstart = match.start('start') matchend = match.end('start') @@ -844,7 +844,7 @@ def literal(self, match, lineno): before, inlines, remaining, sysmessages, endstring = self.inline_obj( match, lineno, self.patterns.literal, nodes.literal, - restore_backslashes=1) + restore_backslashes=True) return before, inlines, remaining, sysmessages def inline_internal_target(self, match, lineno): @@ -914,7 +914,7 @@ before = before.rstrip() return (before, [refnode], remaining, []) - def reference(self, match, lineno, anonymous=None): + def reference(self, match, lineno, anonymous=False): referencename = match.group('refname') refname = normalize_name(referencename) referencenode = nodes.reference( @@ -1558,8 +1558,8 @@ 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) + self.state_machine.get_first_known_indented(match.end(), + until_blank=True) text = u'\n'.join(indented) text_nodes, messages = self.inline_text(text, lineno) line = nodes.line(text, '', *text_nodes) @@ -1638,7 +1638,7 @@ messages = [] blank_finish = 1 try: - block = self.state_machine.get_text_block(flush_left=1) + block = self.state_machine.get_text_block(flush_left=True) except statemachine.UnexpectedIndentationError, err: block, src, srcline = err.args messages.append(self.reporter.error('Unexpected indentation.', @@ -1868,12 +1868,12 @@ 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) + match.end(), until_blank=True, strip_indent=False) blocktext = match.string[:match.end()] + '\n'.join(block) block = [escape2null(line) for line in block] escaped = block[0] blockindex = 0 - while 1: + while True: targetmatch = pattern.match(escaped) if targetmatch: break @@ -1951,12 +1951,12 @@ src, srcline = self.state_machine.get_source_and_line() block, indent, offset, blank_finish = \ self.state_machine.get_first_known_indented(match.end(), - strip_indent=0) + strip_indent=False) blocktext = (match.string[:match.end()] + '\n'.join(block)) block.disconnect() escaped = escape2null(block[0].rstrip()) blockindex = 0 - while 1: + while True: subdefmatch = pattern.match(escaped) if subdefmatch: break @@ -2192,7 +2192,7 @@ node = nodes.field_list() newline_offset, blank_finish = self.nested_list_parse( datalines, 0, node, initial_state='ExtensionOptions', - blank_finish=1) + blank_finish=True) if newline_offset != len(datalines): # incomplete parse of block return 0, 'invalid option block' try: @@ -2211,7 +2211,7 @@ 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) + self.state_machine.get_first_known_indented(0, strip_indent=False) text = '\n'.join(indented) error = self.reporter.error( 'Unknown directive type "%s".' % type_name, @@ -2322,8 +2322,8 @@ 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) + = self.state_machine.get_first_known_indented(match.end(), + until_blank=True) blocktext = match.string[:match.end()] + '\n'.join(block) block = [escape2null(line) for line in block] target = self.make_target(block, blocktext, lineno, '') @@ -2391,7 +2391,7 @@ name = match.string[:match.string.find(':')] indented, indent, line_offset, blank_finish = \ self.state_machine.get_first_known_indented(match.end(), - until_blank=1) + until_blank=True) fieldnode = nodes.field() fieldnode += nodes.field_name(name, name) fieldbody = nodes.field_body('\n'.join(indented)) @@ -2710,7 +2710,7 @@ startline = self.state_machine.abs_line_number() - 1 msg = None try: - block = self.state_machine.get_text_block(flush_left=1) + block = self.state_machine.get_text_block(flush_left=True) except statemachine.UnexpectedIndentationError, err: block, src, srcline = err.args msg = self.reporter.error('Unexpected indentation.', @@ -2749,7 +2749,7 @@ 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, + input_offset=abs_line_offset, node=parent_node, match_titles=False, state_machine_kwargs={'state_classes': (QuotedLiteralBlock,), 'initial_state': 'QuotedLiteralBlock'}) self.goto_line(new_abs_offset) @@ -2853,7 +2853,7 @@ """Transition marker at end of section or document.""" marker = context[0].strip() if self.memo.section_bubble_up_kludge: - self.memo.section_bubble_up_kludge = 0 + self.memo.section_bubble_up_kludge = False elif len(marker) < 4: self.state_correction(context) if self.eofcheck: # ignore EOFError with sections @@ -2979,7 +2979,7 @@ 'text': r''} initial_transitions = ('initial_quoted', 'text') - def __init__(self, state_machine, debug=0): + def __init__(self, state_machine, debug=False): RSTState.__init__(self, state_machine, debug) self.messages = [] self.initial_lineno = None Modified: trunk/docutils/docutils/parsers/rst/tableparser.py =================================================================== --- trunk/docutils/docutils/parsers/rst/tableparser.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/docutils/parsers/rst/tableparser.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -427,7 +427,7 @@ """ cols = [] end = 0 - while 1: + while True: begin = line.find('-', end) end = line.find(' ', begin) if begin < 0: Modified: trunk/docutils/docutils/readers/pep.py =================================================================== --- trunk/docutils/docutils/readers/pep.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/docutils/readers/pep.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -44,5 +44,5 @@ def __init__(self, parser=None, parser_name=None): """`parser` should be ``None``.""" if parser is None: - parser = rst.Parser(rfc2822=1, inliner=self.inliner_class()) + parser = rst.Parser(rfc2822=True, inliner=self.inliner_class()) standalone.Reader.__init__(self, parser, '') Modified: trunk/docutils/docutils/statemachine.py =================================================================== --- trunk/docutils/docutils/statemachine.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/docutils/statemachine.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -128,7 +128,7 @@ results of processing in a list. """ - def __init__(self, state_classes, initial_state, debug=0): + def __init__(self, state_classes, initial_state, debug=False): """ Initialize a `StateMachine` object; add state objects. @@ -224,7 +224,7 @@ print >>self._stderr, '\nStateMachine.run: bof transition' context, result = state.bof(context) results.extend(result) - while 1: + while True: try: try: self.next_line() @@ -403,7 +403,7 @@ self.input_lines.insert(self.line_offset + 2, StringList(input_lines, source)) - def get_text_block(self, flush_left=0): + def get_text_block(self, flush_left=False): """ Return a contiguous block of text. @@ -595,14 +595,14 @@ defaults. """ - def __init__(self, state_machine, debug=0): + def __init__(self, state_machine, debug=False): """ Initialize a `State` object; make & add initial transitions. Parameters: - `statemachine`: the controlling `StateMachine` object. - - `debug`: a boolean; produce verbose output if true (nonzero). + - `debug`: a boolean; produce verbose output if true. """ self.transition_order = [] @@ -803,17 +803,15 @@ known. """ - def get_indented(self, until_blank=0, strip_indent=1): + def get_indented(self, until_blank=False, strip_indent=True): """ Return a block of indented lines of text, and info. Extract an indented block where the indent is unknown for all lines. :Parameters: - - `until_blank`: Stop collecting at the first blank line if true - (1). - - `strip_indent`: Strip common leading indent if true (1, - default). + - `until_blank`: Stop collecting at the first blank line if true. + - `strip_indent`: Strip common leading indent if true (default). :Return: - the indented block (a list of lines of text), @@ -831,7 +829,7 @@ offset += 1 return indented, indent, offset, blank_finish - def get_known_indented(self, indent, until_blank=0, strip_indent=1): + def get_known_indented(self, indent, until_blank=False, strip_indent=True): """ Return an indented block and info. @@ -842,10 +840,9 @@ :Parameters: - `indent`: The number of indent columns/characters. - - `until_blank`: Stop collecting at the first blank line if true - (1). + - `until_blank`: Stop collecting at the first blank line if true. - `strip_indent`: Strip `indent` characters of indentation if true - (1, default). + (default). :Return: - the indented block, @@ -862,8 +859,8 @@ offset += 1 return indented, offset, blank_finish - def get_first_known_indented(self, indent, until_blank=0, strip_indent=1, - strip_top=1): + def get_first_known_indented(self, indent, until_blank=False, + strip_indent=True, strip_top=True): """ Return an indented block and info. @@ -957,7 +954,7 @@ """Default initial whitespace transitions, added before those listed in `State.initial_transitions`. May be overridden in subclasses.""" - def __init__(self, state_machine, debug=0): + def __init__(self, state_machine, debug=False): """ Initialize a `StateSM` object; extends `State.__init__()`. @@ -1348,7 +1345,7 @@ self.data[start:end] = [line[length:] for line in self.data[start:end]] - def get_text_block(self, start, flush_left=0): + def get_text_block(self, start, flush_left=False): """ Return a contiguous block of text. @@ -1369,7 +1366,7 @@ end += 1 return self[start:end] - def get_indented(self, start=0, until_blank=0, strip_indent=1, + def get_indented(self, start=0, until_blank=False, strip_indent=True, block_indent=None, first_indent=None): """ Extract and return a StringList of indented lines of text. @@ -1429,7 +1426,7 @@ 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): + def get_2D_block(self, top, left, bottom, right, strip_indent=True): block = self[top:bottom] indent = right for i in range(len(block.data)): @@ -1504,7 +1501,7 @@ """ -def string2lines(astring, tab_width=8, convert_whitespace=0, +def string2lines(astring, tab_width=8, convert_whitespace=False, whitespace=re.compile('[\v\f]')): """ Return a list of one-line strings with tabs expanded, no newlines, and Modified: trunk/docutils/docutils/transforms/references.py =================================================================== --- trunk/docutils/docutils/transforms/references.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/docutils/transforms/references.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -47,7 +47,7 @@ target.hasattr('refname'))): continue assert len(target) == 0, 'error: block-level target has children' - next_node = target.next_node(ascend=1) + next_node = target.next_node(ascend=True) # Do not move names and ids into Invisibles (we'd lose the # attributes) or different Targetables (e.g. footnotes). if (next_node is not None and @@ -136,7 +136,7 @@ return for ref, target in zip(anonymous_refs, anonymous_targets): target.referenced = 1 - while 1: + while True: if target.hasattr('refuri'): ref['refuri'] = target['refuri'] ref.resolved = 1 @@ -502,7 +502,7 @@ corresponding footnote references. """ for footnote in self.document.autofootnotes: - while 1: + while True: label = str(startnum) startnum += 1 if label not in self.document.nameids: @@ -808,8 +808,7 @@ for ref in refs: if isinstance(ref, nodes.target): continue - refnode = nodes.footnote_reference( - refname=footnote_name, auto=1) + 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) Modified: trunk/docutils/docutils/transforms/writer_aux.py =================================================================== --- trunk/docutils/docutils/transforms/writer_aux.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/docutils/transforms/writer_aux.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -39,11 +39,11 @@ def apply(self): for compound in self.document.traverse(nodes.compound): - first_child = 1 + first_child = True for child in compound: if first_child: if not isinstance(child, nodes.Invisible): - first_child = 0 + first_child = False else: child['classes'].append('continued') # Substitute children for compound. Modified: trunk/docutils/docutils/utils/__init__.py =================================================================== --- trunk/docutils/docutils/utils/__init__.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/docutils/utils/__init__.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -72,7 +72,7 @@ SEVERE_LEVEL) = range(5) def __init__(self, source, report_level, halt_level, stream=None, - debug=0, encoding=None, error_handler='backslashreplace'): + debug=False, encoding=None, error_handler='backslashreplace'): """ :Parameters: - `source`: The path to or description of the source data. @@ -123,7 +123,7 @@ """The highest level system message generated so far.""" def set_conditions(self, category, report_level, halt_level, - stream=None, debug=0): + stream=None, debug=False): warnings.warn('docutils.utils.Reporter.set_conditions deprecated; ' 'set attributes via configuration settings or directly', DeprecationWarning, stacklevel=2) @@ -547,7 +547,7 @@ """Return a string with escape-backslashes converted to nulls.""" parts = [] start = 0 - while 1: + while True: found = text.find('\\', start) if found == -1: parts.append(text[start:]) @@ -556,7 +556,7 @@ parts.append('\x00' + text[found+1:found+2]) start = found + 2 # skip character after escape -def unescape(text, restore_backslashes=0): +def unescape(text, restore_backslashes=False): """ Return a string with nulls removed or restored to backslashes. Backslash-escaped spaces are also removed. Modified: trunk/docutils/docutils/writers/html4css1/__init__.py =================================================================== --- trunk/docutils/docutils/writers/html4css1/__init__.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/docutils/writers/html4css1/__init__.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -307,10 +307,10 @@ self.topic_classes = [] self.colspecs = [] self.compact_p = 1 - self.compact_simple = None - self.compact_field_list = None - self.in_docinfo = None - self.in_sidebar = None + self.compact_simple = False + self.compact_field_list = False + self.in_docinfo = False + self.in_sidebar = False self.title = [] self.subtitle = [] self.header = [] @@ -319,9 +319,9 @@ self.html_title = [] self.html_subtitle = [] self.html_body = [] - self.in_document_title = 0 - self.in_mailto = 0 - self.author_in_authors = None + self.in_document_title = 0 # len(self.body) or 0 + self.in_mailto = False + self.author_in_authors = False self.math_header = '' def astext(self): @@ -388,7 +388,7 @@ path = utils.relative_path(self.settings._destination, path) return self.stylesheet_link % self.encode(path) - def starttag(self, node, tagname, suffix='\n', empty=0, **attributes): + def starttag(self, node, tagname, suffix='\n', empty=False, **attributes): """ Construct and return a start tag given a node (id & class attributes are extracted), tag name, and optional attributes. @@ -454,7 +454,7 @@ def emptytag(self, node, tagname, suffix='\n', **attributes): """Construct and return an XML-compatible empty tag.""" - return self.starttag(node, tagname, suffix, empty=1, **attributes) + return self.starttag(node, tagname, suffix, empty=True, **attributes) def set_class_on_child(self, node, class_, index=0): """ @@ -497,7 +497,7 @@ self.body.append('</acronym>') def visit_address(self, node): - self.visit_docinfo_item(node, 'address', meta=None) + self.visit_docinfo_item(node, 'address', meta=False) self.body.append(self.starttag(node, 'pre', CLASS='address')) def depart_address(self, node): @@ -534,17 +534,16 @@ def depart_author(self, node): if isinstance(node.parent, nodes.authors): - self.author_in_authors += 1 + self.author_in_authors = True else: self.depart_docinfo_item() def visit_authors(self, node): self.visit_docinfo_item(node, 'authors') - self.author_in_authors = 0 # initialize counter + self.author_in_authors = False # initialize def depart_authors(self, node): self.depart_docinfo_item() - self.author_in_authors = None def visit_block_quote(self, node): self.body.append(self.starttag(node, 'blockquote')) @@ -661,7 +660,7 @@ self.body.append('</div>\n') def visit_contact(self, node): - self.visit_docinfo_item(node, 'contact', meta=None) + self.visit_docinfo_item(node, 'contact', meta=False) def depart_contact(self, node): self.depart_docinfo_item() @@ -719,16 +718,16 @@ self.body.append('<col class="docinfo-name" />\n' '<col class="docinfo-content" />\n' '<tbody valign="top">\n') - self.in_docinfo = 1 + self.in_docinfo = True def depart_docinfo(self, node): self.body.append('</tbody>\n</table>\n') - self.in_docinfo = None + self.in_docinfo = False start = self.context.pop() self.docinfo = self.body[start:] self.body = [] - def visit_docinfo_item(self, node, name, meta=1): + def visit_docinfo_item(self, node, name, meta=True): if meta: meta_tag = '<meta name="%s" content="%s" />\n' \ % (name, self.attval(node.astext())) @@ -858,10 +857,10 @@ self.context.append((self.compact_field_list, self.compact_p)) self.compact_p = None if 'compact' in node['classes']: - self.compact_field_list = 1 + self.compact_field_list = True elif (self.settings.compact_field_lists and 'open' not in node['classes']): - self.compact_field_list = 1 + self.compact_field_list = True if self.compact_field_list: for field in node: field_body = field[-1] @@ -872,7 +871,7 @@ len(children) == 1 and isinstance(children[0], (nodes.paragraph, nodes.line_block))): - self.compact_field_list = 0 + self.compact_field_list = False break self.body.append(self.starttag(node, 'table', frame='void', rules='none', @@ -1369,7 +1368,7 @@ if ( self.settings.cloak_email_addresses and atts['href'].startswith('mailto:')): atts['href'] = self.cloak_mailto(atts['href']) - self.in_mailto = 1 + self.in_mailto = True atts['class'] += ' external' else: assert 'refid' in node, \ @@ -1385,10 +1384,10 @@ self.body.append('</a>') if not isinstance(node.parent, nodes.TextElement): self.body.append('\n') - self.in_mailto = 0 + self.in_mailto = False def visit_revision(self, node): - self.visit_docinfo_item(node, 'revision', meta=None) + self.visit_docinfo_item(node, 'revision', meta=False) def depart_revision(self, node): self.depart_docinfo_item() @@ -1419,14 +1418,14 @@ self.body.append( self.starttag(node, 'div', CLASS='sidebar')) self.set_first_last(node) - self.in_sidebar = 1 + self.in_sidebar = True def depart_sidebar(self, node): self.body.append('</div>\n') - self.in_sidebar = None + self.in_sidebar = False def visit_status(self, node): - self.visit_docinfo_item(node, 'status', meta=None) + self.visit_docinfo_item(node, 'status', meta=False) def depart_status(self, node): self.depart_docinfo_item() @@ -1569,7 +1568,7 @@ def visit_title(self, node): """Only 6 section levels are supported by HTML.""" - check_id = 0 + check_id = 0 # TODO: is this a bool (False) or a counter? close_tag = '</p>\n' if isinstance(node.parent, nodes.topic): self.body.append( @@ -1638,7 +1637,7 @@ pass def visit_version(self, node): - self.visit_docinfo_item(node, 'version', meta=None) + self.visit_docinfo_item(node, 'version', meta=False) def depart_version(self, node): self.depart_docinfo_item() Modified: trunk/docutils/docutils/writers/latex2e/__init__.py =================================================================== --- trunk/docutils/docutils/writers/latex2e/__init__.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/docutils/writers/latex2e/__init__.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -720,7 +720,7 @@ self._translator = translator self._latex_type = latex_type self._table_style = table_style - self._open = 0 + self._open = False # miscellaneous attributes self._attrs = {} self._col_width = [] @@ -850,6 +850,7 @@ elif self._table_style == 'booktabs': return ['\\toprule\n'] return [] + def depart_thead(self): a = [] #if self._table_style == 'standard': @@ -885,7 +886,7 @@ cline = '' rowspans.reverse() # TODO merge clines - while 1: + while True: try: c_start = rowspans.pop() except: @@ -928,10 +929,10 @@ ## use_optionlist_for_docinfo = False # TODO: NOT YET IN USE # Use compound enumerations (1.A.1.) - compound_enumerators = 0 + compound_enumerators = False # If using compound enumerations, include section information. - section_prefix_for_enumerators = 0 + section_prefix_for_enumerators = False # This is the character that separates the section ("." subsection ...) # prefix from the regular list enumerator. @@ -1106,7 +1107,7 @@ # Stylesheets # (the name `self.stylesheet` is singular because only one # stylesheet was supported before Docutils 0.6). - self.stylesheet = [self.stylesheet_call(path) + self.stylesheet = [self.stylesheet_call(path) for path in utils.get_stylesheet_list(settings)] # PDF setup @@ -1678,8 +1679,8 @@ if self._use_latex_citations: followup_citation = False # check for a following citation separated by a space or newline - next_siblings = node.traverse(descend=0, siblings=1, - include_self=0) + next_siblings = node.traverse(descend=False, siblings=True, + include_self=False) if len(next_siblings) > 1: next = next_siblings[0] if (isinstance(next, nodes.Text) and Modified: trunk/docutils/docutils/writers/pseudoxml.py =================================================================== --- trunk/docutils/docutils/writers/pseudoxml.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/docutils/writers/pseudoxml.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -28,4 +28,4 @@ def supports(self, format): """This writer supports all format-specific elements.""" - return 1 + return True Modified: trunk/docutils/docutils/writers/s5_html/__init__.py =================================================================== --- trunk/docutils/docutils/writers/s5_html/__init__.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/docutils/writers/s5_html/__init__.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -202,7 +202,7 @@ else: # no destination, so we can't copy the theme return - default = 0 + default = False while path: for f in os.listdir(path): # copy all files from each theme if f == self.base_theme_file: @@ -233,7 +233,7 @@ if not path: path = find_theme(self.default_theme) theme_paths.append(path) - default = 1 + default = True if len(required_files_copied) != len(self.required_theme_files): # Some required files weren't found & couldn't be copied. required = list(self.required_theme_files) Modified: trunk/docutils/test/DocutilsTestSupport.py =================================================================== --- trunk/docutils/test/DocutilsTestSupport.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/test/DocutilsTestSupport.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -143,8 +143,8 @@ compare = difflib.Differ().compare """Comparison method shared by all subclasses.""" - def __init__(self, method_name, input, expected, id, run_in_debugger=0, - suite_settings=None): + def __init__(self, method_name, input, expected, id, + run_in_debugger=True, suite_settings=None): """ Initialise the CustomTestCase. @@ -274,7 +274,7 @@ self.id = id def addTestCase(self, test_case_class, method_name, input, expected, - id=None, run_in_debugger=0, **kwargs): + id=None, run_in_debugger=False, **kwargs): """ Create a CustomTestCase in the CustomTestSuite. Also return it, just in case. @@ -405,7 +405,7 @@ for name, (transforms, cases) in dict.items(): for casenum in range(len(cases)): case = cases[casenum] - run_in_debugger = 0 + run_in_debugger = False if len(case)==3: # TODO: (maybe) change the 3rd argument to a dict, so it # can handle more cases by keyword ('disable', 'debug', @@ -413,7 +413,7 @@ # But there's also the method that # HtmlPublishPartsTestSuite uses <DJG> if case[2]: - run_in_debugger = 1 + run_in_debugger = True else: continue self.addTestCase( @@ -479,10 +479,10 @@ for name, cases in dict.items(): for casenum in range(len(cases)): case = cases[casenum] - run_in_debugger = 0 + run_in_debugger = False if len(case)==3: if case[2]: - run_in_debugger = 1 + run_in_debugger = True else: continue self.addTestCase( @@ -496,7 +496,7 @@ """PEP-specific parser test case.""" - parser = rst.Parser(rfc2822=1, inliner=rst.states.Inliner()) + parser = rst.Parser(rfc2822=True, inliner=rst.states.Inliner()) """Parser shared by all PEPParserTestCases.""" option_parser = frontend.OptionParser(components=(rst.Parser, pep.Reader)) @@ -564,10 +564,10 @@ for name, cases in dict.items(): for casenum in range(len(cases)): case = cases[casenum] - run_in_debugger = 0 + run_in_debugger = False if len(case) == 4: if case[-1]: - run_in_debugger = 1 + run_in_debugger = True else: continue self.addTestCase(self.test_case_class, 'test_parse_table', @@ -607,10 +607,10 @@ for name, cases in dict.items(): for casenum in range(len(cases)): case = cases[casenum] - run_in_debugger = 0 + run_in_debugger = False if len(case) == 3: if case[-1]: - run_in_debugger = 1 + run_in_debugger = True else: continue self.addTestCase(self.test_case_class, 'test_parse', @@ -668,10 +668,10 @@ for name, cases in dict.items(): for casenum in range(len(cases)): case = cases[casenum] - run_in_debugger = 0 + run_in_debugger = False if len(case)==3: if case[2]: - run_in_debugger = 1 + run_in_debugger = True else: continue self.addTestCase( @@ -724,10 +724,10 @@ for name, cases in dict.items(): for casenum in range(len(cases)): case = cases[casenum] - run_in_debugger = 0 + run_in_debugger = False if len(case)==3: if case[2]: - run_in_debugger = 1 + run_in_debugger = True else: continue self.addTestCase( @@ -747,10 +747,10 @@ settings.update(settings_overrides) for casenum in range(len(cases)): case = cases[casenum] - run_in_debugger = 0 + run_in_debugger = False if len(case)==3: if case[2]: - run_in_debugger = 1 + run_in_debugger = True else: continue self.addTestCase( Modified: trunk/docutils/test/functional/tests/_default.py =================================================================== --- trunk/docutils/test/functional/tests/_default.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/test/functional/tests/_default.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -4,4 +4,4 @@ settings_overrides['halt_level'] = 5 settings_overrides['warning_stream'] = '' settings_overrides['input_encoding'] = 'utf-8' -settings_overrides['embed_stylesheet'] = 0 +settings_overrides['embed_stylesheet'] = False Modified: trunk/docutils/test/functional/tests/dangerous.py =================================================================== --- trunk/docutils/test/functional/tests/dangerous.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/test/functional/tests/dangerous.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -8,5 +8,5 @@ writer_name = "html" # Settings -settings_overrides['file_insertion_enabled'] = 0 -settings_overrides['raw_enabled'] = 0 +settings_overrides['file_insertion_enabled'] = False +settings_overrides['raw_enabled'] = False Modified: trunk/docutils/test/functional/tests/field_name_limit.py =================================================================== --- trunk/docutils/test/functional/tests/field_name_limit.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/test/functional/tests/field_name_limit.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -9,4 +9,4 @@ # Settings settings_overrides['field_name_limit'] = 0 # no limit -settings_overrides['docinfo_xform'] = 0 +settings_overrides['docinfo_xform'] = False Modified: trunk/docutils/test/functional/tests/misc_rst_html4css1.py =================================================================== --- trunk/docutils/test/functional/tests/misc_rst_html4css1.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/test/functional/tests/misc_rst_html4css1.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -11,4 +11,4 @@ # test for encoded attribute value: settings_overrides['stylesheet'] = 'foo&bar.css' settings_overrides['stylesheet_path'] = '' -settings_overrides['embed_stylesheet'] = 0 +settings_overrides['embed_stylesheet'] = False Modified: trunk/docutils/test/package_unittest.py =================================================================== --- trunk/docutils/test/package_unittest.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/test/package_unittest.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -21,7 +21,7 @@ # So that individual test modules can share a bit of state, # `package_unittest` acts as an intermediary for the following # variables: -debug = 0 +debug = False verbosity = 1 USAGE = """\ Modified: trunk/docutils/test/test_nodes.py =================================================================== --- trunk/docutils/test/test_nodes.py 2012-01-19 21:00:21 UTC (rev 7319) +++ trunk/docutils/test/test_nodes.py 2012-01-19 22:33:02 UTC (rev 7320) @@ -16,7 +16,7 @@ from DocutilsTestSupport import nodes, utils from docutils._compat import b -debug = 0 +debug = False class TextTests(unittest.TestCase): @@ -399,21 +399,21 @@ e += nodes.Element() self.assertEquals(list(e.traverse()), [e, e[0], e[0][0], e[0][1], e[0][1][0], e[1], e[2]]) - self.assertEquals(list(e.traverse(include_self=0)), + self.assertEquals(list(e.traverse(include_self=False)), [e[0], e[0][0], e[0][1], e[0][1][0], e[1], e[2]]) - self.assertEquals(list(e.traverse(descend=0)), + self.assertEquals(list(e.traverse(descend=False)), [e]) - self.assertEquals(list(e[0].traverse(descend=0, ascend=1)), + self.assertEquals(list(e[0].traverse(descend=False, ascend=True)), [e[0], e[1], e[2]]) - self.assertEquals(list(e[0][0].traverse(descend=0, ascend=1)), + self.assertEquals(list(e[0][0].traverse(descend=False, ascend=True)), [e[0][0], e[0][1], e[1], e[2]]) - self.assertEquals(list(e[0][0].traverse(descend=0, siblings=1)), + self.assertEquals(list(e[0][0].traverse(descend=False, siblings=True)), [e[0][0], e[0][1]]) self.testlist = e[0:2] self.assertEquals(list(e.traverse(condition=self.not_in_testlist)), [e, e[0][0], e[0][1], e[0][1][0], e[2]]) - # Return siblings despite siblings=0 because ascend is true. - self.assertEquals(list(e[1].traverse(ascend=1, siblings=0)), + # Return siblings despite siblings=False because ascend is true. + self.assertEquals(list(e[1].traverse(ascend=True, siblings=False)), [e[1], e[2]]) self.assertEquals(list(e[0].traverse()), [e[0], e[0][0], e[0][1], e[0][1][0]]) @@ -442,9 +442,9 @@ (e[1], e[2]), (e[2], None)] for node, next_node in compare: - self.assertEquals(node.next_node(self.not_in_testlist, ascend=1), + self.assertEquals(node.next_node(self.not_in_testlist, ascend=True), next_node) - self.assertEquals(e[0][0].next_node(ascend=1)... [truncated message content] |
From: <go...@us...> - 2012-01-23 20:57:35
|
Revision: 7323 http://docutils.svn.sourceforge.net/docutils/?rev=7323&view=rev Author: goodger Date: 2012-01-23 20:57:29 +0000 (Mon, 23 Jan 2012) Log Message: ----------- fixed the --prune & --ignore options of buildhtml.py Modified Paths: -------------- trunk/docutils/docs/user/config.txt trunk/docutils/tools/buildhtml.py Modified: trunk/docutils/docs/user/config.txt =================================================================== --- trunk/docutils/docs/user/config.txt 2012-01-20 08:48:09 UTC (rev 7322) +++ trunk/docutils/docs/user/config.txt 2012-01-23 20:57:29 UTC (rev 7323) @@ -1341,19 +1341,22 @@ ``````````````````````` _`ignore` - List of wildcard (shell globing) patterns to silently ignore. To - specify multiple patterns in configuration files, use - colon-separated patterns; on the command line, the option may be - used more than once. + List of wildcard (shell globing) patterns, specifying files to + silently ignore. To specify multiple patterns, use + colon-separated patterns (in configuration files or on the command + line); on the command line, the option may also be used more than + once. - Default: ['.svn', 'CVS']. Options: ``--ignore``. + Default: none ([]). Options: ``--ignore``. _`prune` List of directories not to process. To specify multiple - directories in configuration files, use colon-separated paths; on - the command line, the option may be used more than once. + directories, use colon-separated paths (in configuration files or + on the command line); on the command line, the option may also be + used more than once. - Default: none ([]). Options: ``--prune``. + Default: ['.hg', '.bzr', '.git', '.svn', 'CVS']. Options: + ``--prune``. _`recurse` Recursively scan subdirectories, or ignore subdirectories. Modified: trunk/docutils/tools/buildhtml.py =================================================================== --- trunk/docutils/tools/buildhtml.py 2012-01-20 08:48:09 UTC (rev 7322) +++ trunk/docutils/tools/buildhtml.py 2012-01-23 20:57:29 UTC (rev 7323) @@ -47,6 +47,8 @@ Runtime settings & command-line options for the front end. """ + prune_default = ['.hg', '.bzr', '.git', '.svn', 'CVS'] + # Can't be included in OptionParser below because we don't want to # override the base class. settings_spec = ( @@ -59,17 +61,19 @@ 'validator': frontend.validate_boolean}), ('Do not scan subdirectories for files to process.', ['--local'], {'dest': 'recurse', 'action': 'store_false'}), - ('BROKEN Do not process files in <directory>. This option may be used ' - 'more than once to specify multiple directories.', + ('Do not process files in <directory> (shell globbing patterns, ' + 'separated by colons). This option may be used ' + 'more than once to specify multiple directories. Default: "%s".' + % ':'.join(prune_default), ['--prune'], {'metavar': '<directory>', 'action': 'append', - 'validator': frontend.validate_colon_separated_string_list}), - ('BROKEN Recursively ignore files or directories matching any of the given ' - 'wildcard (shell globbing) patterns (separated by colons). ' - 'Default: ".svn:CVS"', + 'validator': frontend.validate_colon_separated_string_list, + 'default': prune_default,}), + ('Recursively ignore files matching any of the given ' + 'wildcard (shell globbing) patterns (separated by colons).', ['--ignore'], {'metavar': '<patterns>', 'action': 'append', - 'default': ['.svn', 'CVS'], + 'default': [], 'validator': frontend.validate_colon_separated_string_list}), ('Work silently (no progress messages). Independent of "--quiet".', ['--silent'], @@ -190,17 +194,16 @@ # influence by modifying dirs. if not recurse: del dirs[:] - self.visit(root, files) + self.visit(root, files, dirs) - def visit(self, directory, names): - # BUG prune and ignore do not work + def visit(self, directory, names, subdirectories): settings = self.get_settings('', directory) errout = ErrorOutput(encoding=settings.error_encoding) if settings.prune and (os.path.abspath(directory) in settings.prune): print >>errout, ('/// ...Skipping directory (pruned): %s' % directory) sys.stderr.flush() - names[:] = [] + del subdirectories[:] return if not self.initial_settings.silent: print >>errout, '/// Processing directory: %s' % directory @@ -212,12 +215,9 @@ if fnmatch(names[i], pattern): # Modify in place! del names[i] - prune = 0 for name in names: if name.endswith('.txt'): - prune = self.process_txt(directory, name) - if prune: - break + self.process_txt(directory, name) def process_txt(self, directory, name): if name.startswith('pep-'): @@ -227,8 +227,6 @@ settings = self.get_settings(publisher, directory) errout = ErrorOutput(encoding=settings.error_encoding) pub_struct = self.publishers[publisher] - if settings.prune and (directory in settings.prune): - return 1 settings._source = os.path.normpath(os.path.join(directory, name)) settings._destination = settings._source[:-4]+'.html' if not self.initial_settings.silent: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mi...@us...> - 2012-01-26 13:08:16
|
Revision: 7325 http://docutils.svn.sourceforge.net/docutils/?rev=7325&view=rev Author: milde Date: 2012-01-26 13:08:04 +0000 (Thu, 26 Jan 2012) Log Message: ----------- Do not use ``\\\\section*``-macros to suppress LaTeX section numbering. Use ``\\\\DUtitle`` for section levels not supported by LaTeX. Modified Paths: -------------- trunk/docutils/HISTORY.txt trunk/docutils/docutils/writers/latex2e/__init__.py trunk/docutils/test/functional/expected/cyrillic.tex trunk/docutils/test/functional/expected/standalone_rst_latex.tex trunk/docutils/test/functional/expected/standalone_rst_xetex.tex trunk/docutils/test/functional/expected/xetex-cyrillic.tex trunk/docutils/test/functional/input/data/urls.txt trunk/docutils/test/functional/input/standalone_rst_latex.txt trunk/docutils/test/functional/input/standalone_rst_xetex.txt trunk/docutils/test/test_writers/test_latex2e.py Modified: trunk/docutils/HISTORY.txt =================================================================== --- trunk/docutils/HISTORY.txt 2012-01-26 09:57:04 UTC (rev 7324) +++ trunk/docutils/HISTORY.txt 2012-01-26 13:08:04 UTC (rev 7325) @@ -21,7 +21,7 @@ - New reStructuredText "code" role and directive and "code" option of the "include" directive with syntax highlighting by Pygments_. - Fix parse_option_marker for option arguments containing ``=``. - + .. _Pygments: http://pygments.org/ * setup.py @@ -60,6 +60,9 @@ - Support the `abbreviation` and `acronym` standard roles. - Record only files required to generate the LaTeX source as dependencies. - Fix handling of missing stylesheets. + - Use ``\setcounter{secnumdepth}{0}`` instead of ``*``-versions + when suppressing LaTeX section numbering. + - Use ``\DUtitle`` for unsupported section levels * docutils/writers/html4css1/__init__.py Modified: trunk/docutils/docutils/writers/latex2e/__init__.py =================================================================== --- trunk/docutils/docutils/writers/latex2e/__init__.py 2012-01-26 09:57:04 UTC (rev 7324) +++ trunk/docutils/docutils/writers/latex2e/__init__.py 2012-01-26 13:08:04 UTC (rev 7325) @@ -19,6 +19,10 @@ import re import string import urllib +try: + import roman +except ImportError: + import docutils.utils.roman as roman from docutils import frontend, nodes, languages, writers, utils, io from docutils.error_reporting import SafeString from docutils.transforms import writer_aux @@ -648,7 +652,7 @@ \providecommand*{\DUroletitlereference}[1]{\textsl{#1}}""" PreambleCmds.title = r""" -% title for topics, admonitions and sidebar +% title for topics, admonitions, unsupported section levels, and sidebar \providecommand*{\DUtitle}[2][class-arg]{% % call \DUtitle#1{#2} if it exists: \ifcsname DUtitle#1\endcsname% @@ -696,13 +700,11 @@ The name depends on the specific document class. Level is 1,2,3..., as level 0 is the title. """ - if level <= len(self.sections): return self.sections[level-1] - else: - return self.sections[-1] + else: # unsupported levels + return 'DUtitle[section%s]' % roman.toRoman(level) - class Table(object): """Manage a table while traversing. @@ -1127,33 +1129,32 @@ ## len(self.d_class.sections)) # Section numbering - # TODO: use \secnumdepth instead of starred commands - ## if self.settings.sectnum_xform: # section numbering by Docutils - ## sectnum_depth = 0 - ## else: - if not self.settings.sectnum_xform: # section numbering by LaTeX: - # sectnum_depth: - # None "sectnum" directive without depth arg -> LaTeX default - # 0 no "sectnum" directive -> no section numbers - # else value of the "depth" argument: translate to LaTeX level - # -1 part (0 with "article" document class) - # 0 chapter (missing in "article" document class) - # 1 section - # 2 subsection - # 3 subsubsection - # 4 paragraph - # 5 subparagraph - if settings.sectnum_depth is not None: + if not self.settings.sectnum_xform: # section numbering by Docutils + PreambleCmds.secnumdepth = r'\setcounter{secnumdepth}{0}' + else: # section numbering by LaTeX: + secnumdepth = settings.sectnum_depth + # Possible values of settings.sectnum_depth: + # None "sectnum" directive without depth arg -> LaTeX default + # 0 no "sectnum" directive -> no section numbers + # >0 value of "depth" argument -> translate to LaTeX levels: + # -1 part (0 with "article" document class) + # 0 chapter (missing in "article" document class) + # 1 section + # 2 subsection + # 3 subsubsection + # 4 paragraph + # 5 subparagraph + if secnumdepth is not None: # limit to supported levels - sectnum_depth = min(settings.sectnum_depth, - len(self.d_class.sections)) + secnumdepth = min(secnumdepth, len(self.d_class.sections)) # adjust to document class and use_part_section settings if 'chapter' in self.d_class.sections: - sectnum_depth -= 1 + secnumdepth -= 1 if self.d_class.sections[0] == 'part': - sectnum_depth -= 1 - self.requirements['sectnum_depth'] = ( - r'\setcounter{secnumdepth}{%d}' % sectnum_depth) + secnumdepth -= 1 + PreambleCmds.secnumdepth = \ + r'\setcounter{secnumdepth}{%d}' % secnumdepth + # start with specified number: if (hasattr(settings, 'sectnum_start') and settings.sectnum_start != 1): @@ -1164,7 +1165,6 @@ ## settings.sectnum_prefix ## settings.sectnum_suffix - # Auxiliary Methods # ----------------- @@ -2850,18 +2850,6 @@ node.walkabout(self) self._thead_depth -= 1 - def bookmark(self, node): - """Return label and pdfbookmark string for titles.""" - result = [''] - if self.settings.sectnum_xform: # "starred" section cmd - # add to the toc and pdfbookmarks - section_name = self.d_class.section(max(self.section_level, 1)) - section_title = self.encode(node.astext()) - result.append(r'\addcontentsline{toc}{%s}{%s}' % - (section_name, section_title)) - result += self.ids_to_labels(node.parent, set_anchor=False) - return '%\n '.join(result) + '%\n' - def visit_title(self, node): """Append section and other titles.""" # Document title @@ -2886,26 +2874,31 @@ self.context.append('') # Section title else: - self.out.append('\n\n') - self.out.append('%' + '_' * 75) - self.out.append('\n\n') - # + self.requirements['secnumdepth'] = PreambleCmds.secnumdepth section_name = self.d_class.section(self.section_level) - section_star = '' - pdfanchor = '' - # number sections? - if (self.settings.sectnum_xform # numbering by Docutils - or (self.section_level > len(self.d_class.sections))): - section_star = '*' - pdfanchor = '\\phantomsection%\n ' - self.out.append(r'\%s%s{%s' % - (section_name, section_star, pdfanchor)) + self.out.append('\n\n') # System messages heading in red: if ('system-messages' in node.parent['classes']): self.requirements['color'] = PreambleCmds.color - self.out.append('\color{red}') + section_title = self.encode(node.astext()) + self.out.append(r'\%s[%s]{\color{red}' % ( + section_name,section_title)) + else: + self.out.append(r'\%s{' % section_name) + if self.section_level > len(self.d_class.sections): + # section level not supported by LaTeX + self.fallbacks['title'] = PreambleCmds.title + # self.out.append('\\phantomsection%\n ') # label and ToC entry: - self.context.append(self.bookmark(node) + '}\n') + bookmark = [''] + # add sections with unsupported level to toc and pdfbookmarks? + ## if self.section_level > len(self.d_class.sections): + ## section_title = self.encode(node.astext()) + ## bookmark.append(r'\addcontentsline{toc}{%s}{%s}' % + ## (section_name, section_title)) + bookmark += self.ids_to_labels(node.parent, set_anchor=False) + self.context.append('%\n '.join(bookmark) + '%\n}\n') + # MAYBE postfix paragraph and subparagraph with \leavemode to # ensure floats stay in the section and text starts on a new line. Modified: trunk/docutils/test/functional/expected/cyrillic.tex =================================================================== --- trunk/docutils/test/functional/expected/cyrillic.tex 2012-01-26 09:57:04 UTC (rev 7324) +++ trunk/docutils/test/functional/expected/cyrillic.tex 2012-01-26 13:08:04 UTC (rev 7325) @@ -6,6 +6,7 @@ \usepackage[T1,T2A]{fontenc} \usepackage[utf8]{inputenc} \usepackage[english,russian]{babel} +\setcounter{secnumdepth}{0} %%% Custom LaTeX preamble % PDF Standard Fonts @@ -32,33 +33,21 @@ \begin{document} -%___________________________________________________________________________ - -\section*{\phantomsection% - Заголовок% - \addcontentsline{toc}{section}{Заголовок}% +\section{Заголовок% \label{id1}% } первый пример: \glqq{}Здравствуй, мир!\grqq{} -%___________________________________________________________________________ - -\section*{\phantomsection% - Title% - \addcontentsline{toc}{section}{Title}% +\section{Title% \label{title}% } \otherlanguage{english}{first example: \glqq{}Hello world\grqq{}.} -%___________________________________________________________________________ - -\section*{\phantomsection% - Notes% - \addcontentsline{toc}{section}{Notes}% +\section{Notes% \label{notes}% } Modified: trunk/docutils/test/functional/expected/standalone_rst_latex.tex =================================================================== --- trunk/docutils/test/functional/expected/standalone_rst_latex.tex 2012-01-26 09:57:04 UTC (rev 7324) +++ trunk/docutils/test/functional/expected/standalone_rst_latex.tex 2012-01-26 13:08:04 UTC (rev 7325) @@ -16,6 +16,7 @@ \usepackage{graphicx} \usepackage{multirow} \usepackage{pifont} +\setcounter{secnumdepth}{0} \usepackage{longtable,ltcaption,array} \setlength{\extrarowheight}{2pt} \newlength{\DUtablewidth} % internal use in tables @@ -149,7 +150,7 @@ % subtitle (for topic/sidebar) \providecommand*{\DUsubtitle}[2][class-arg]{\par\emph{#2}\smallskip} -% title for topics, admonitions and sidebar +% title for topics, admonitions, unsupported section levels, and sidebar \providecommand*{\DUtitle}[2][class-arg]{% % call \DUtitle#1{#2} if it exists: \ifcsname DUtitle#1\endcsname% @@ -280,20 +281,12 @@ -%___________________________________________________________________________ - -\section*{\phantomsection% - 1~~~Structural Elements% - \addcontentsline{toc}{section}{1~~~Structural Elements}% +\section{1~~~Structural Elements% \label{structural-elements}% } -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 1.1~~~Section Title% - \addcontentsline{toc}{subsection}{1.1~~~Section Title}% +\subsection{1.1~~~Section Title% \label{section-title}% } \subsubsection*{Section Subtitle} @@ -303,20 +296,12 @@ \texttt{sectsubtitle-xform} configuration value. -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 1.2~~~Empty Section% - \addcontentsline{toc}{subsection}{1.2~~~Empty Section}% +\subsection{1.2~~~Empty Section% \label{empty-section}% } -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 1.3~~~Transitions% - \addcontentsline{toc}{subsection}{1.3~~~Transitions}% +\subsection{1.3~~~Transitions% \label{transitions}% } @@ -335,31 +320,19 @@ -%___________________________________________________________________________ - -\section*{\phantomsection% - 2~~~Body Elements% - \addcontentsline{toc}{section}{2~~~Body Elements}% +\section{2~~~Body Elements% \label{body-elements}% } -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.1~~~Paragraphs% - \addcontentsline{toc}{subsection}{2.1~~~Paragraphs}% +\subsection{2.1~~~Paragraphs% \label{paragraphs}% } A paragraph. -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.1.1~~~Inline Markup% - \addcontentsline{toc}{subsubsection}{2.1.1~~~Inline Markup}% +\subsubsection{2.1.1~~~Inline Markup% \label{inline-markup}% } @@ -398,11 +371,7 @@ live link to PEP 258 here. -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.2~~~Bullet Lists% - \addcontentsline{toc}{subsection}{2.2~~~Bullet Lists}% +\subsection{2.2~~~Bullet Lists% \label{bullet-lists}% } % @@ -448,11 +417,7 @@ \end{itemize} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.3~~~Enumerated Lists% - \addcontentsline{toc}{subsection}{2.3~~~Enumerated Lists}% +\subsection{2.3~~~Enumerated Lists% \label{enumerated-lists}% } \newcounter{listcnt0} @@ -540,11 +505,7 @@ \end{list} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.4~~~Definition Lists% - \addcontentsline{toc}{subsection}{2.4~~~Definition Lists}% +\subsection{2.4~~~Definition Lists% \label{definition-lists}% } % @@ -569,11 +530,7 @@ \end{description} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.5~~~Field Lists% - \addcontentsline{toc}{subsection}{2.5~~~Field Lists}% +\subsection{2.5~~~Field Lists% \label{field-lists}% } % @@ -597,11 +554,7 @@ \end{DUfieldlist} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.6~~~Option Lists% - \addcontentsline{toc}{subsection}{2.6~~~Option Lists}% +\subsection{2.6~~~Option Lists% \label{option-lists}% } @@ -638,11 +591,7 @@ description. -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.7~~~Literal Blocks% - \addcontentsline{toc}{subsection}{2.7~~~Literal Blocks}% +\subsection{2.7~~~Literal Blocks% \label{literal-blocks}% } @@ -667,11 +616,7 @@ \end{quote} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.8~~~Line Blocks% - \addcontentsline{toc}{subsection}{2.8~~~Line Blocks}% +\subsection{2.8~~~Line Blocks% \label{line-blocks}% } @@ -767,11 +712,7 @@ \end{DUlineblock} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.9~~~Block Quotes% - \addcontentsline{toc}{subsection}{2.9~~~Block Quotes}% +\subsection{2.9~~~Block Quotes% \label{block-quotes}% } @@ -803,11 +744,7 @@ \end{quote} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.10~~~Doctest Blocks% - \addcontentsline{toc}{subsection}{2.10~~~Doctest Blocks}% +\subsection{2.10~~~Doctest Blocks% \label{doctest-blocks}% } % @@ -820,11 +757,7 @@ \end{quote} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.11~~~Footnotes% - \addcontentsline{toc}{subsection}{2.11~~~Footnotes}% +\subsection{2.11~~~Footnotes% \label{footnotes}% } % @@ -868,11 +801,7 @@ } -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.12~~~Citations% - \addcontentsline{toc}{subsection}{2.12~~~Citations}% +\subsection{2.12~~~Citations% \label{citations}% } \begin{figure}[b]\raisebox{1em}{\hypertarget{cit2002}{}}[CIT2002] @@ -886,11 +815,7 @@ citation. -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.13~~~Targets% - \addcontentsline{toc}{subsection}{2.13~~~Targets}% +\subsection{2.13~~~Targets% \label{targets}% \label{another-target}% } @@ -914,11 +839,7 @@ error. -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.13.1~~~Duplicate Target Names% - \addcontentsline{toc}{subsubsection}{2.13.1~~~Duplicate Target Names}% +\subsubsection{2.13.1~~~Duplicate Target Names% \label{duplicate-target-names}% } @@ -927,11 +848,7 @@ explicit targets will generate ``warning'' (level-2) system messages. -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.13.2~~~Duplicate Target Names% - \addcontentsline{toc}{subsubsection}{2.13.2~~~Duplicate Target Names}% +\subsubsection{2.13.2~~~Duplicate Target Names% \label{id21}% } @@ -941,11 +858,7 @@ \raisebox{1em}{\hypertarget{id52}{}}\hyperlink{id51}{\textbf{\color{red}`Duplicate Target Names`\_}}), an error is generated. -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.14~~~Directives% - \addcontentsline{toc}{subsection}{2.14~~~Directives}% +\subsection{2.14~~~Directives% \label{directives}% } @@ -955,11 +868,7 @@ \url{http://docutils.sourceforge.net/docs/ref/rst/directives.html}. -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.14.1~~~Document Parts% - \addcontentsline{toc}{subsubsection}{2.14.1~~~Document Parts}% +\subsubsection{2.14.1~~~Document Parts% \label{document-parts}% } @@ -968,11 +877,7 @@ document (a document-wide \hyperref[table-of-contents]{table of contents}). -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.14.2~~~Images and Figures% - \addcontentsline{toc}{subsubsection}{2.14.2~~~Images and Figures}% +\subsubsection{2.14.2~~~Images and Figures% \label{images-and-figures}% } @@ -1106,11 +1011,7 @@ upon the style sheet and the browser or rendering software used. -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.14.3~~~Admonitions% - \addcontentsline{toc}{subsubsection}{2.14.3~~~Admonitions}% +\subsubsection{2.14.3~~~Admonitions% \label{admonitions}% } @@ -1186,11 +1087,7 @@ } -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.14.4~~~Topics, Sidebars, and Rubrics% - \addcontentsline{toc}{subsubsection}{2.14.4~~~Topics, Sidebars, and Rubrics}% +\subsubsection{2.14.4~~~Topics, Sidebars, and Rubrics% \label{topics-sidebars-and-rubrics}% } @@ -1228,11 +1125,7 @@ allowed (e.g. inside a directive). -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.14.5~~~Target Footnotes% - \addcontentsline{toc}{subsubsection}{2.14.5~~~Target Footnotes}% +\subsubsection{2.14.5~~~Target Footnotes% \label{target-footnotes}% } % @@ -1257,22 +1150,14 @@ } -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.14.6~~~Replacement Text% - \addcontentsline{toc}{subsubsection}{2.14.6~~~Replacement Text}% +\subsubsection{2.14.6~~~Replacement Text% \label{replacement-text}% } I recommend you try \href{http://www.python.org/}{Python, \emph{the} best language around}\DUfootnotemark{id32}{id29}{5}. -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.14.7~~~Compound Paragraph% - \addcontentsline{toc}{subsubsection}{2.14.7~~~Compound Paragraph}% +\subsubsection{2.14.7~~~Compound Paragraph% \label{compound-paragraph}% } @@ -1349,11 +1234,7 @@ Compound 7, another paragraph. -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.14.8~~~Parsed Literal Blocks% - \addcontentsline{toc}{subsubsection}{2.14.8~~~Parsed Literal Blocks}% +\subsubsection{2.14.8~~~Parsed Literal Blocks% \label{parsed-literal-blocks}% } % @@ -1368,11 +1249,7 @@ \end{quote} -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.14.9~~~Code% - \addcontentsline{toc}{subsubsection}{2.14.9~~~Code}% +\subsubsection{2.14.9~~~Code% \label{code}% } @@ -1421,11 +1298,7 @@ \end{quote} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.15~~~Substitution Definitions% - \addcontentsline{toc}{subsection}{2.15~~~Substitution Definitions}% +\subsection{2.15~~~Substitution Definitions% \label{substitution-definitions}% } @@ -1434,11 +1307,7 @@ (Substitution definitions are not visible in the HTML source.) -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.16~~~Comments% - \addcontentsline{toc}{subsection}{2.16~~~Comments}% +\subsection{2.16~~~Comments% \label{comments}% } @@ -1455,11 +1324,7 @@ (View the HTML source to see the comment.) -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.17~~~Raw text% - \addcontentsline{toc}{subsection}{2.17~~~Raw text}% +\subsection{2.17~~~Raw text% \label{raw-text}% } @@ -1478,11 +1343,7 @@ Fifth test in LaTeX.\\Line two. -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.18~~~Container% - \addcontentsline{toc}{subsection}{2.18~~~Container}% +\subsection{2.18~~~Container% \label{container}% } @@ -1494,11 +1355,7 @@ % .. include:: data/header_footer.txt -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.19~~~Colspanning tables% - \addcontentsline{toc}{subsection}{2.19~~~Colspanning tables}% +\subsection{2.19~~~Colspanning tables% \label{colspanning-tables}% } @@ -1576,11 +1433,7 @@ \end{longtable*} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.20~~~Rowspanning tables% - \addcontentsline{toc}{subsection}{2.20~~~Rowspanning tables}% +\subsection{2.20~~~Rowspanning tables% \label{rowspanning-tables}% } @@ -1639,11 +1492,7 @@ \end{longtable*} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.21~~~Custom Roles% - \addcontentsline{toc}{subsection}{2.21~~~Custom Roles}% +\subsection{2.21~~~Custom Roles% \label{custom-roles}% } % @@ -1688,11 +1537,7 @@ \end{itemize} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.22~~~Mathematics% - \addcontentsline{toc}{subsection}{2.22~~~Mathematics}% +\subsection{2.22~~~Mathematics% \label{mathematics}% } @@ -1818,11 +1663,7 @@ \end{cases} \end{equation*} -%___________________________________________________________________________ - -\section*{\phantomsection% - 3~~~Tests for the LaTeX writer% - \addcontentsline{toc}{section}{3~~~Tests for the LaTeX writer}% +\section{3~~~Tests for the LaTeX writer% \label{tests-for-the-latex-writer}% } @@ -1830,11 +1671,7 @@ not need to be tested with other writers (e.g. the HTML writer). -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 3.1~~~Custom Roles in LaTeX% - \addcontentsline{toc}{subsection}{3.1~~~Custom Roles in LaTeX}% +\subsection{3.1~~~Custom Roles in LaTeX% \label{custom-roles-in-latex}% } % @@ -1878,11 +1715,7 @@ \end{itemize} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 3.2~~~More Tables% - \addcontentsline{toc}{subsection}{3.2~~~More Tables}% +\subsection{3.2~~~More Tables% \label{more-tables}% } @@ -1946,11 +1779,7 @@ % This file is used by the standalone_rst_latex test. -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 3.3~~~Option lists% - \addcontentsline{toc}{subsection}{3.3~~~Option lists}% +\subsection{3.3~~~Option lists% \label{id23}% } @@ -1986,11 +1815,7 @@ \end{description} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 3.4~~~Monospaced non-alphanumeric characters% - \addcontentsline{toc}{subsection}{3.4~~~Monospaced non-alphanumeric characters}% +\subsection{3.4~~~Monospaced non-alphanumeric characters% \label{monospaced-non-alphanumeric-characters}% } @@ -2006,11 +1831,7 @@ width as the third line. -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 3.5~~~Non-ASCII characters% - \addcontentsline{toc}{subsection}{3.5~~~Non-ASCII characters}% +\subsection{3.5~~~Non-ASCII characters% \label{non-ascii-characters}% } @@ -2424,11 +2245,7 @@ \end{itemize} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 3.6~~~Encoding special chars% - \addcontentsline{toc}{subsection}{3.6~~~Encoding special chars}% +\subsection{3.6~~~Encoding special chars% \label{encoding-special-chars}% } @@ -2497,11 +2314,7 @@ \end{quote} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 3.7~~~Hyperlinks and -targets% - \addcontentsline{toc}{subsection}{3.7~~~Hyperlinks and -targets}% +\subsection{3.7~~~Hyperlinks and -targets% \label{hyperlinks-and-targets}% } @@ -2546,17 +2359,13 @@ \hyperref[image-label]{image label}. -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 3.8~~~External references% - \addcontentsline{toc}{subsection}{3.8~~~External references}% +\subsection{3.8~~~External references% \label{external-references}% } Long URLs should be wrapped in the PDF. This can be achieved with the url command which is used by the LaTeX writer -wheneve the content (name) of a reference node equals the link URL. +whenever the content (name) of a reference node equals the link URL. % \begin{description} \item[{Example:}] \leavevmode @@ -2634,17 +2443,63 @@ \end{itemize} + +\subsection{3.9~~~Section titles with \hyperref[inline-markup]{inline markup}% + \label{section-titles-with-inline-markup}% +} + + +\subsubsection{3.9.1~~~\emph{emphasized}, H\textsubscript{2}O and $x^2$% + \label{emphasized-h2o-and-x-2}% +} + + +\subsubsection{3.9.2~~~Substitutions work% + \label{substitutions-fail}% +} + + +\subsection{3.10~~~Deeply nested sections% + \label{deeply-nested-sections}% +} + +In LaTeX and HTML, + + +\subsubsection{3.10.1~~~Level 3% + \label{level-3}% +} + +nested sections + + +\paragraph{3.10.1.1~~~level 4% + \label{level-4}% +} + +reach at some level + + +\subparagraph{3.10.1.1.1~~~level 5% + \label{level-5}% +} + +(depending on the document class) + + +\DUtitle[sectionVI]{3.10.1.1.1.1~~~level 6% + \label{level-6}% +} + +an unsupported level. + % unusual combinations (from newlatex, for interactive testing) % .. include:: data/latex.txt % Preface for System Messages: -%___________________________________________________________________________ - -\section*{\phantomsection% - 4~~~Error Handling% - \addcontentsline{toc}{section}{4~~~Error Handling}% +\section{4~~~Error Handling% \label{error-handling}% } @@ -2656,11 +2511,7 @@ % section should be added by Docutils automatically -%___________________________________________________________________________ - -\section*{\phantomsection% - \color{red}Docutils System Messages% - \addcontentsline{toc}{section}{Docutils System Messages}% +\section[Docutils System Messages]{\color{red}Docutils System Messages% } \DUadmonition[system-message]{ Modified: trunk/docutils/test/functional/expected/standalone_rst_xetex.tex =================================================================== --- trunk/docutils/test/functional/expected/standalone_rst_xetex.tex 2012-01-26 09:57:04 UTC (rev 7324) +++ trunk/docutils/test/functional/expected/standalone_rst_xetex.tex 2012-01-26 13:08:04 UTC (rev 7325) @@ -13,6 +13,7 @@ \floatplacement{figure}{H} % place figures here definitely \usepackage{graphicx} \usepackage{multirow} +\setcounter{secnumdepth}{0} \usepackage{longtable,ltcaption,array} \setlength{\extrarowheight}{2pt} \newlength{\DUtablewidth} % internal use in tables @@ -148,7 +149,7 @@ % subtitle (for topic/sidebar) \providecommand*{\DUsubtitle}[2][class-arg]{\par\emph{#2}\smallskip} -% title for topics, admonitions and sidebar +% title for topics, admonitions, unsupported section levels, and sidebar \providecommand*{\DUtitle}[2][class-arg]{% % call \DUtitle#1{#2} if it exists: \ifcsname DUtitle#1\endcsname% @@ -279,20 +280,12 @@ -%___________________________________________________________________________ - -\section*{\phantomsection% - 1 Structural Elements% - \addcontentsline{toc}{section}{1 Structural Elements}% +\section{1 Structural Elements% \label{structural-elements}% } -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 1.1 Section Title% - \addcontentsline{toc}{subsection}{1.1 Section Title}% +\subsection{1.1 Section Title% \label{section-title}% } \subsubsection*{Section Subtitle} @@ -302,20 +295,12 @@ \texttt{sectsubtitle-xform} configuration value. -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 1.2 Empty Section% - \addcontentsline{toc}{subsection}{1.2 Empty Section}% +\subsection{1.2 Empty Section% \label{empty-section}% } -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 1.3 Transitions% - \addcontentsline{toc}{subsection}{1.3 Transitions}% +\subsection{1.3 Transitions% \label{transitions}% } @@ -334,31 +319,19 @@ -%___________________________________________________________________________ - -\section*{\phantomsection% - 2 Body Elements% - \addcontentsline{toc}{section}{2 Body Elements}% +\section{2 Body Elements% \label{body-elements}% } -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.1 Paragraphs% - \addcontentsline{toc}{subsection}{2.1 Paragraphs}% +\subsection{2.1 Paragraphs% \label{paragraphs}% } A paragraph. -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.1.1 Inline Markup% - \addcontentsline{toc}{subsubsection}{2.1.1 Inline Markup}% +\subsubsection{2.1.1 Inline Markup% \label{inline-markup}% } @@ -397,11 +370,7 @@ live link to PEP 258 here. -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.2 Bullet Lists% - \addcontentsline{toc}{subsection}{2.2 Bullet Lists}% +\subsection{2.2 Bullet Lists% \label{bullet-lists}% } % @@ -447,11 +416,7 @@ \end{itemize} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.3 Enumerated Lists% - \addcontentsline{toc}{subsection}{2.3 Enumerated Lists}% +\subsection{2.3 Enumerated Lists% \label{enumerated-lists}% } \newcounter{listcnt0} @@ -539,11 +504,7 @@ \end{list} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.4 Definition Lists% - \addcontentsline{toc}{subsection}{2.4 Definition Lists}% +\subsection{2.4 Definition Lists% \label{definition-lists}% } % @@ -568,11 +529,7 @@ \end{description} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.5 Field Lists% - \addcontentsline{toc}{subsection}{2.5 Field Lists}% +\subsection{2.5 Field Lists% \label{field-lists}% } % @@ -596,11 +553,7 @@ \end{DUfieldlist} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.6 Option Lists% - \addcontentsline{toc}{subsection}{2.6 Option Lists}% +\subsection{2.6 Option Lists% \label{option-lists}% } @@ -637,11 +590,7 @@ description. -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.7 Literal Blocks% - \addcontentsline{toc}{subsection}{2.7 Literal Blocks}% +\subsection{2.7 Literal Blocks% \label{literal-blocks}% } @@ -666,11 +615,7 @@ \end{quote} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.8 Line Blocks% - \addcontentsline{toc}{subsection}{2.8 Line Blocks}% +\subsection{2.8 Line Blocks% \label{line-blocks}% } @@ -766,11 +711,7 @@ \end{DUlineblock} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.9 Block Quotes% - \addcontentsline{toc}{subsection}{2.9 Block Quotes}% +\subsection{2.9 Block Quotes% \label{block-quotes}% } @@ -802,11 +743,7 @@ \end{quote} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.10 Doctest Blocks% - \addcontentsline{toc}{subsection}{2.10 Doctest Blocks}% +\subsection{2.10 Doctest Blocks% \label{doctest-blocks}% } % @@ -819,11 +756,7 @@ \end{quote} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.11 Footnotes% - \addcontentsline{toc}{subsection}{2.11 Footnotes}% +\subsection{2.11 Footnotes% \label{footnotes}% } % @@ -867,11 +800,7 @@ } -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.12 Citations% - \addcontentsline{toc}{subsection}{2.12 Citations}% +\subsection{2.12 Citations% \label{citations}% } \begin{figure}[b]\raisebox{1em}{\hypertarget{cit2002}{}}[CIT2002] @@ -885,11 +814,7 @@ citation. -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.13 Targets% - \addcontentsline{toc}{subsection}{2.13 Targets}% +\subsection{2.13 Targets% \label{targets}% \label{another-target}% } @@ -913,11 +838,7 @@ error. -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.13.1 Duplicate Target Names% - \addcontentsline{toc}{subsubsection}{2.13.1 Duplicate Target Names}% +\subsubsection{2.13.1 Duplicate Target Names% \label{duplicate-target-names}% } @@ -926,11 +847,7 @@ explicit targets will generate "warning" (level-2) system messages. -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.13.2 Duplicate Target Names% - \addcontentsline{toc}{subsubsection}{2.13.2 Duplicate Target Names}% +\subsubsection{2.13.2 Duplicate Target Names% \label{id21}% } @@ -940,11 +857,7 @@ \raisebox{1em}{\hypertarget{id51}{}}\hyperlink{id50}{\textbf{\color{red}`Duplicate Target Names`\_}}), an error is generated. -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.14 Directives% - \addcontentsline{toc}{subsection}{2.14 Directives}% +\subsection{2.14 Directives% \label{directives}% } @@ -954,11 +867,7 @@ \url{http://docutils.sourceforge.net/docs/ref/rst/directives.html}. -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.14.1 Document Parts% - \addcontentsline{toc}{subsubsection}{2.14.1 Document Parts}% +\subsubsection{2.14.1 Document Parts% \label{document-parts}% } @@ -967,11 +876,7 @@ document (a document-wide \hyperref[table-of-contents]{table of contents}). -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.14.2 Images and Figures% - \addcontentsline{toc}{subsubsection}{2.14.2 Images and Figures}% +\subsubsection{2.14.2 Images and Figures% \label{images-and-figures}% } @@ -1105,11 +1010,7 @@ upon the style sheet and the browser or rendering software used. -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.14.3 Admonitions% - \addcontentsline{toc}{subsubsection}{2.14.3 Admonitions}% +\subsubsection{2.14.3 Admonitions% \label{admonitions}% } @@ -1185,11 +1086,7 @@ } -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.14.4 Topics, Sidebars, and Rubrics% - \addcontentsline{toc}{subsubsection}{2.14.4 Topics, Sidebars, and Rubrics}% +\subsubsection{2.14.4 Topics, Sidebars, and Rubrics% \label{topics-sidebars-and-rubrics}% } @@ -1227,11 +1124,7 @@ allowed (e.g. inside a directive). -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.14.5 Target Footnotes% - \addcontentsline{toc}{subsubsection}{2.14.5 Target Footnotes}% +\subsubsection{2.14.5 Target Footnotes% \label{target-footnotes}% } % @@ -1244,7 +1137,7 @@ } % \DUfootnotetext{id35}{id36}{7}{% -\url{http://tug.ctan.org/cgi-bin/ctanPackageInformation.py?id=polyglossia} +\url{http://ctan.org/pkg/polyglossia} } % \DUfootnotetext{id38}{id39}{8}{% @@ -1256,22 +1149,14 @@ } -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.14.6 Replacement Text% - \addcontentsline{toc}{subsubsection}{2.14.6 Replacement Text}% +\subsubsection{2.14.6 Replacement Text% \label{replacement-text}% } I recommend you try \href{http://www.python.org/}{Python, \emph{the} best language around}\DUfootnotemark{id32}{id29}{5}. -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.14.7 Compound Paragraph% - \addcontentsline{toc}{subsubsection}{2.14.7 Compound Paragraph}% +\subsubsection{2.14.7 Compound Paragraph% \label{compound-paragraph}% } @@ -1348,11 +1233,7 @@ Compound 7, another paragraph. -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.14.8 Parsed Literal Blocks% - \addcontentsline{toc}{subsubsection}{2.14.8 Parsed Literal Blocks}% +\subsubsection{2.14.8 Parsed Literal Blocks% \label{parsed-literal-blocks}% } % @@ -1367,11 +1248,7 @@ \end{quote} -%___________________________________________________________________________ - -\subsubsection*{\phantomsection% - 2.14.9 Code% - \addcontentsline{toc}{subsubsection}{2.14.9 Code}% +\subsubsection{2.14.9 Code% \label{code}% } @@ -1420,11 +1297,7 @@ \end{quote} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.15 Substitution Definitions% - \addcontentsline{toc}{subsection}{2.15 Substitution Definitions}% +\subsection{2.15 Substitution Definitions% \label{substitution-definitions}% } @@ -1433,11 +1306,7 @@ (Substitution definitions are not visible in the HTML source.) -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.16 Comments% - \addcontentsline{toc}{subsection}{2.16 Comments}% +\subsection{2.16 Comments% \label{comments}% } @@ -1454,11 +1323,7 @@ (View the HTML source to see the comment.) -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.17 Raw text% - \addcontentsline{toc}{subsection}{2.17 Raw text}% +\subsection{2.17 Raw text% \label{raw-text}% } @@ -1477,11 +1342,7 @@ Fifth test in LaTeX.\\Line two. -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.18 Container% - \addcontentsline{toc}{subsection}{2.18 Container}% +\subsection{2.18 Container% \label{container}% } @@ -1493,11 +1354,7 @@ % .. include:: data/header_footer.txt -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.19 Colspanning tables% - \addcontentsline{toc}{subsection}{2.19 Colspanning tables}% +\subsection{2.19 Colspanning tables% \label{colspanning-tables}% } @@ -1575,11 +1432,7 @@ \end{longtable*} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.20 Rowspanning tables% - \addcontentsline{toc}{subsection}{2.20 Rowspanning tables}% +\subsection{2.20 Rowspanning tables% \label{rowspanning-tables}% } @@ -1638,11 +1491,7 @@ \end{longtable*} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 2.21 Custom Roles% - \addcontentsline{toc}{subsection}{2.21 Custom Roles}% +\subsection{2.21 Custom Roles% \label{custom-roles}% } % @@ -1687,11 +1536,7 @@ \end{itemize} -%___________________________________________________________________________ - -\section*{\phantomsection% - 3 Tests for the LaTeX writer% - \addcontentsline{toc}{section}{3 Tests for the LaTeX writer}% +\section{3 Tests for the LaTeX writer% \label{tests-for-the-latex-writer}% } @@ -1699,11 +1544,7 @@ not need to be tested with other writers (e.g. the HTML writer). -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 3.1 Custom Roles in LaTeX% - \addcontentsline{toc}{subsection}{3.1 Custom Roles in LaTeX}% +\subsection{3.1 Custom Roles in LaTeX% \label{custom-roles-in-latex}% } % @@ -1749,11 +1590,7 @@ % This file is used by the standalone_rst_latex test. -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 3.2 Option lists% - \addcontentsline{toc}{subsection}{3.2 Option lists}% +\subsection{3.2 Option lists% \label{id23}% } @@ -1789,11 +1626,7 @@ \end{description} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 3.3 Monospaced non-alphanumeric characters% - \addcontentsline{toc}{subsection}{3.3 Monospaced non-alphanumeric characters}% +\subsection{3.3 Monospaced non-alphanumeric characters% \label{monospaced-non-alphanumeric-characters}% } @@ -1809,11 +1642,7 @@ width as the third line. -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 3.4 Non-ASCII characters% - \addcontentsline{toc}{subsection}{3.4 Non-ASCII characters}% +\subsection{3.4 Non-ASCII characters% \label{non-ascii-characters}% } @@ -2227,11 +2056,7 @@ \end{itemize} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 3.5 Encoding special chars% - \addcontentsline{toc}{subsection}{3.5 Encoding special chars}% +\subsection{3.5 Encoding special chars% \label{encoding-special-chars}% } @@ -2300,11 +2125,7 @@ \end{quote} -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 3.6 Hyperlinks and -targets% - \addcontentsline{toc}{subsection}{3.6 Hyperlinks and -targets}% +\subsection{3.6 Hyperlinks and -targets% \label{hyperlinks-and-targets}% } @@ -2349,17 +2170,13 @@ \hyperref[image-label]{image label}. -%___________________________________________________________________________ - -\subsection*{\phantomsection% - 3.7 External references% - \addcontentsline{toc}{subsection}{3.7 External references}% +\subsection{3.7 External references% \label{external-references}% } Long URLs should be wrapped in the PDF. This can be achieved with the url command which is used by the LaTeX writer -wheneve the content (name) of a reference node equals the link URL. +whenever the content (name) of a reference node equals the link URL. % \begin{description} \item[{Example:}] \leavevmode @@ -2438,11 +2255,57 @@ \end{itemize} -%___________________________________________________________________________ +\subsection{3.8 Section titles with \hyperref[inline-markup]{inline markup}% + \label{section-titles-with-inline-markup}% +} -\section*{\phantomsection% - 4 Tests for the XeTeX writer% - \addcontentsline{toc}{section}{4 Tests for the XeTeX writer}% + +\subsubsection{3.8.1 \emph{emphasized}, H\textsubscript{2}O and $x^2$% + \label{emphasized-h2o-and-x-2}% +} + + +\subsubsection{3.8.2 Substitutions work% + \label{substitutions-fail}% +} + + +\subsection{3.9 Deeply nested sections% + \label{deeply-nested-sections}% +} + +In LaTeX and HTML, + + +\subsubsection{3.9.1 Level 3% + \label{level-3}% +} + +nested sections + + +\paragraph{3.9.1.1 level 4% + \label{level-4}% +} + +reach at some level + + +\subparagraph{3.9.1.1.1 level 5% + \label{level-5}% +} + +(depending on the document class) + + +\DUtitle[sectionVI]{3.9.1.1.1.1 level 6% + \label{level-6}% +} + +an unsupported level. + + +\section{4 Tests for the XeTeX writer% \label{tests-for-the-xetex-writer}% } @@ -2454,16 +2317,12 @@ Русский, Slovenščina, Српски, Türkçe, Українська, Tiếng Việt, Volapük, Võro, ייִדיש , Žemaitėška. Currently, there is extended support for 28 languages in the -\href{http://tug.ctan.org/cgi-bin/ctanPackageInformation.py?id=polyglossia}{polyglossia}\DUfootnotemark{id36}{id35}{7} package. +\href{http://ctan.org/pkg/polyglossia}{polyglossia}\DUfootnotemark{id36}{id35}{7} package. % System Messages: -%___________________________________________________________________________ - -\section*{\phantomsection% - 5 Error Handling% - \addcontentsline{toc}{section}{5 Error Handling}% +\section{5 Error Handling% \label{error-handling}% } @@ -2475,11 +2334,7 @@ % section should be added by Docutils automatically -%___________________________________________________________________________ - -\section*{\phantomsection% - \color{red}Docutils System Messages% - \addcontentsline{toc}{section}{Docutils System Messages}% +\section[Docutils System Messages]{\color{red}Docutils System Messages% } \DUadmonition[system-message]{ Modified: trunk/docutils/test/functional/expected/xetex-cyrillic.tex =================================================================== --- trunk/docutils/test/functional/expected/xetex-cyrillic.tex 2012-01-26 09:57:04 UTC (rev 7324) +++ trunk/docutils/test/functional/expected/xetex-cyrillic.tex 2012-01-26 13:08:04 UTC (rev 7325) @@ -7,6 +7,7 @@ \usepackage{polyglossia} \setdefaultlanguage{russian} \setotherlanguages{english} +\setcounter{secnumdepth}{0} %%% Custom LaTeX preamble % Linux Libertine (free, wide coverage, not only for Linux) @@ -32,33 +33,21 @@ \begin{document} -%___________________________________________________________________________ - -\section*{\phantomsection% - Заголовок% - \addcontentsline{toc}{section}{Заголовок}% +\section{Заголовок% \label{id1}% } первый пример: "Здравствуй, мир!" -%___________________________________________________________________________ - -\section*{\phantomsection% - Title% - \addcontentsline{toc}{section}{Title}% +\section{Title% \label{title}% } \otherlanguage{english}{first example: "Hello world".} -%___________________________________________________________________________ - -\section*{\phantomsection% - Notes% - \addcontentsline{toc}{section}{Notes}% +\section{Notes% \label{notes}% } Modified: trunk/docutils/test/functional/input/data/urls.txt =================================================================== --- trunk/docutils/test/functional/input/data/urls.txt 2012-01-26 09:57:04 UTC (rev 7324) +++ trunk/docutils/test/functional/input/data/urls.txt 2012-01-26 13:08:04 UTC (rev 7325) @@ -3,7 +3,7 @@ Long URLs should be wrapped in the PDF. This can be achieved with the \url command which is used by the LaTeX writer -wheneve the content (name) of a reference node equals the link URL. +whenever the content (name) of a reference node equals the link URL. Example: a long URL that should wrap in the output Modified: trunk/docutils/test/functional/input/standalone_rst_latex.txt =================================================================== --- trunk/docutils/test/functional/input/standalone_rst_latex.txt 2012-01-26 09:57:04 UTC (rev 7324) +++ trunk/docutils/test/functional/input/standalone_rst_latex.txt 2012-01-26 13:08:04 UTC (rev 7325) @@ -20,6 +20,7 @@ .. include:: data/latex_encoding.txt .. include:: data/hyperlinking.txt .. include:: data/urls.txt +.. include:: data/section_titles.txt .. unusual combinations (from newlatex, for interactive testing) .. include:: data/latex.txt Modified: trunk/docutils/test/functional/input/standalone_rst_xetex.txt =================================================================== --- trunk/docutils/test/functional/input/standalone_rst_xetex.txt 2012-01-26 09:57:04 UTC (rev 7324) +++ trunk/docutils/test/functional/input/standalone_rst_xetex.txt 2012-01-26 13:08:04 UTC (rev 7325) @@ -18,6 +18,7 @@ .. include:: data/latex_encoding.txt .. include:: data/hyperlinking.txt .. include:: data/urls.txt +.. include:: data/section_titles.txt Tests for the XeTeX writer ========================== @@ -32,8 +33,7 @@ Currently, there is extended support for 28 languages in the polyglossia_ package. -.. _polyglossia: - http://tug.ctan.org/cgi-bin/ctanPackageInformation.py?id=polyglossia +.. _polyglossia: http://ctan.org/pkg/polyglossia .. System Messages: .. include:: data/errors.txt Modified: trunk/docutils/test/test_writers/test_latex2e.py =================================================================== --- trunk/docutils/test/test_writers/test_latex2e.py 2012-01-26 09:57:04 UTC (rev 7324) +++ trunk/docutils/test/test_writers/test_latex2e.py 2012-01-26 13:08:04 UTC (rev 7325) @@ -143,8 +143,10 @@ Paragraph 2. """, ## # expected output -head_template.substitute(dict(parts, fallbacks = r""" -% title for topics, admonitions and sidebar +head_template.substitute(dict(parts, + requirements=parts['requirements'] + '\\setcounter{secnumdepth}{0}\n', + fallbacks=r""" +% title for topics, admonitions, unsupported section levels, and sidebar \providecommand*{\DUtitle}[2][class-arg]{% % call \DUtitle#1{#2} if it exists: \ifcsname DUtitle#1\endcsname% @@ -171,22 +173,14 @@ \end{list} -%___________________________________________________________________________ - -\section*{\phantomsection% - Title 1% - \addcontentsline{toc}{section}{Title 1}% +\section{Title 1% \label{title-1}% } Paragraph 1. -%___________________________________________________________________________ - -\subsection*{\phantomsection% - Title 2% - \addcontentsline{toc}{subsection}{Title 2}% +\subsection{Title 2% \label{title-2}% } @@ -206,18 +200,16 @@ ------------- """, ## # expected output -head + r""" +head_template.substitute(dict(parts, + requirements=parts['requirements'] + '\\setcounter{secnumdepth}{0}\n' +)) + r""" \phantomsection\label{contents} \pdfbookmark[1]{Contents}{contents} \tableofcontents -%___________________________________________________________________________ - -\section*{\phantomsection% - first section% - \addcontentsline{toc}{section}{first section}% +\section{first section% \label{first-section}% } @@ -235,18 +227,16 @@ ------------- """, ## # expected output -head + r""" +head_template.substitute(dict(parts, + requirements=parts['requirements'] + '\\setcounter{secnumdepth}{0}\n' +)) + r""" \phantomsection\label{contents} \pdfbookmark[1]{Contents}{contents} \tableofcontents -%___________________________________________________________________________ - -\section*{\phantomsection% - 1~~~first section% - \addcontentsline{toc}{section}{1~~~first section}% +\section{1~~~first section% \label{first-section}% } @@ -270,8 +260,6 @@ some text -%___________________________________________________________________________ - \section{first section% \label{first-section}% } @@ -291,12 +279,12 @@ ------------- """, ## # expected output -head + r""" +head_template.substitute(dict(parts, + requirements=parts['requirements'] + '\\setcounter{secnumdepth}{0}\n' +)) + r""" some text -%___________________________________________________________________________ - \section{first section% \label{first-section}% } @@ -611,8 +599,9 @@ This is the *document*. """, -head_template.substitute( - dict(parts, pdfsetup=parts['pdfsetup'] + r"""\hypersetup{ +head_template.substitute(dict(parts, + requirements=parts['requirements'] + '\\setcounter{secnumdepth}{0}\n', + pdfsetup=parts['pdfsetup'] + r"""\hypersetup{ pdftitle={This is the Title}, } """, titledata=r"""%%% Title Data @@ -627,11 +616,7 @@ """)) + r"""\maketitle -%___________________________________________________________________________ - -\section*{\phantomsection% - This is a \emph{section title}% - \addcontentsline{toc}{section}{This is a section title}% +\section{This is a \emph{section title}% \label{this-is-a-section-title}% } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mi...@us...> - 2012-01-26 13:39:03
|
Revision: 7326 http://docutils.svn.sourceforge.net/docutils/?rev=7326&view=rev Author: milde Date: 2012-01-26 13:38:54 +0000 (Thu, 26 Jan 2012) Log Message: ----------- io.FileInput/io.FileOutput: No system-exit on IOError. Allows handling by core.Publisher or a calling application. Modified Paths: -------------- trunk/docutils/HISTORY.txt trunk/docutils/docutils/core.py trunk/docutils/docutils/io.py trunk/docutils/docutils/parsers/rst/directives/misc.py trunk/docutils/docutils/parsers/rst/directives/tables.py trunk/docutils/docutils/writers/html4css1/__init__.py trunk/docutils/docutils/writers/latex2e/__init__.py trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py trunk/docutils/test/test_parsers/test_rst/test_directives/test_raw.py Modified: trunk/docutils/HISTORY.txt =================================================================== --- trunk/docutils/HISTORY.txt 2012-01-26 13:08:04 UTC (rev 7325) +++ trunk/docutils/HISTORY.txt 2012-01-26 13:38:54 UTC (rev 7326) @@ -29,9 +29,18 @@ - Fix [ 2971827 ] and [ 3442827 ] extras/roman.py moved to docutils/utils/roman.py +* docutils/core.py: + + - Catch and report InputError/OutputError + (unless the configuration setting "traceback" is true). + * docutils/io.py - Fix [ 3395948 ] (Work around encoding problems in Py3k). + - FileInput/FileOutput: No system-exit on IOError. + Instead, the custom exceptions InputError/OutputError are raised + to allow handling by core.Publisher or a calling application. + The optional argument `handle_io_errors` (to be removed later) is ignored. * docutils/utils.py -> docutils/utils/__init__.py Modified: trunk/docutils/docutils/core.py =================================================================== --- trunk/docutils/docutils/core.py 2012-01-26 13:08:04 UTC (rev 7325) +++ trunk/docutils/docutils/core.py 2012-01-26 13:38:54 UTC (rev 7326) @@ -135,7 +135,7 @@ if self.settings is None: defaults = (settings_overrides or {}).copy() # Propagate exceptions by default when used programmatically: - defaults.setdefault('traceback', 1) + defaults.setdefault('traceback', True) self.get_settings(settings_spec=settings_spec, config_section=config_section, **defaults) @@ -221,7 +221,7 @@ self.debugging_dumps() raise self.report_Exception(error) - exit = 1 + exit = True exit_status = 1 self.debugging_dumps() if (enable_exit_status and self.document @@ -260,6 +260,10 @@ self.report_SystemMessage(error) elif isinstance(error, UnicodeEncodeError): self.report_UnicodeError(error) + elif isinstance(error, io.InputError): + self.report_InputError(error) + elif isinstance(error, io.OutputError): + self.report_OutputError(error) else: print >>self._stderr, u'%s' % ErrorString(error) print >>self._stderr, ("""\ @@ -275,6 +279,14 @@ % (error.level, utils.Reporter.levels[error.level])) + def report_InputError(self, error): + self._stderr.write(u'Unable to open source file for reading:\n' + u' %s\n' % ErrorString(error)) + + def report_OutputError(self, error): + self._stderr.write(u'Unable to open destination file for writing:\n' + u' %s\n' % ErrorString(error)) + def report_UnicodeError(self, error): data = error.object[error.start:error.end] self._stderr.write( Modified: trunk/docutils/docutils/io.py =================================================================== --- trunk/docutils/docutils/io.py 2012-01-26 13:08:04 UTC (rev 7325) +++ trunk/docutils/docutils/io.py 2012-01-26 13:38:54 UTC (rev 7326) @@ -17,6 +17,11 @@ from docutils._compat import b from docutils.error_reporting import locale_encoding, ErrorString, ErrorOutput + +class InputError(IOError): pass +class OutputError(IOError): pass + + class Input(TransformSpec): """ @@ -184,7 +189,7 @@ """ def __init__(self, source=None, source_path=None, encoding=None, error_handler='strict', - autoclose=True, handle_io_errors=True, mode='rU'): + autoclose=True, handle_io_errors=False, mode='rU'): """ :Parameters: - `source`: either a file-like object (which is read directly), or @@ -194,7 +199,7 @@ - `error_handler`: the encoding error handler to use. - `autoclose`: close automatically after read (except when `sys.stdin` is the source). - - `handle_io_errors`: summarize I/O errors here, and exit? + - `handle_io_errors`: ignored. - `mode`: how the file is to be opened (see standard function `open`). The default 'rU' provides universal newline support for text files. @@ -216,12 +221,7 @@ try: self.source = open(source_path, mode, **kwargs) except IOError, error: - if not handle_io_errors: - raise - print >>self._stderr, ErrorString(error) - print >>self._stderr, (u'Unable to open source' - u" file for reading ('%s'). Exiting." % source_path) - sys.exit(1) + raise InputError(error.errno, error.strerror, source_path) else: self.source = sys.stdin elif (sys.version_info >= (3,0) and @@ -286,7 +286,7 @@ def __init__(self, destination=None, destination_path=None, encoding=None, error_handler='strict', autoclose=True, - handle_io_errors=True): + handle_io_errors=False): """ :Parameters: - `destination`: either a file-like object (which is written @@ -294,8 +294,11 @@ `destination_path` given). - `destination_path`: a path to a file, which is opened and then written. + - `encoding`: the text encoding of the output file. + - `error_handler`: the encoding error handler to use. - `autoclose`: close automatically after write (except when `sys.stdout` or `sys.stderr` is the destination). + - `handle_io_errors`: ignored. """ Output.__init__(self, destination, destination_path, encoding, error_handler) @@ -326,12 +329,8 @@ try: self.destination = open(self.destination_path, 'w', **kwargs) except IOError, error: - if not self.handle_io_errors: - raise - print >>self._stderr, ErrorString(error) - print >>self._stderr, (u'Unable to open destination file' - u" for writing ('%s'). Exiting." % self.destination_path) - sys.exit(1) + raise OutputError(error.errno, error.strerror, + self.destination_path) self.opened = True def write(self, data): Modified: trunk/docutils/docutils/parsers/rst/directives/misc.py =================================================================== --- trunk/docutils/docutils/parsers/rst/directives/misc.py 2012-01-26 13:08:04 UTC (rev 7325) +++ trunk/docutils/docutils/parsers/rst/directives/misc.py 2012-01-26 13:38:54 UTC (rev 7326) @@ -69,10 +69,10 @@ try: self.state.document.settings.record_dependencies.add(path) include_file = io.FileInput( - source_path=path, encoding=encoding, - error_handler=(self.state.document.settings.\ - input_encoding_error_handler), - handle_io_errors=None) + source_path=path, + encoding=encoding, + error_handler= + self.state.document.settings.input_encoding_error_handler) except IOError, error: raise self.severe(u'Problems with "%s" directive path:\n%s.' % (self.name, ErrorString(error))) @@ -198,11 +198,10 @@ self.options['file'])) path = utils.relative_path(None, path) try: - raw_file = io.FileInput( - source_path=path, encoding=encoding, - error_handler=(self.state.document.settings.\ - input_encoding_error_handler), - handle_io_errors=None) + eh = self.state.document.settings.input_encoding_error_handler + raw_file = io.FileInput(source_path=path, + encoding=encoding, + error_handler=eh) # TODO: currently, raw input files are recorded as # dependencies even if not used for the chosen output format. self.state.document.settings.record_dependencies.add(path) Modified: trunk/docutils/docutils/parsers/rst/directives/tables.py =================================================================== --- trunk/docutils/docutils/parsers/rst/directives/tables.py 2012-01-26 13:08:04 UTC (rev 7325) +++ trunk/docutils/docutils/parsers/rst/directives/tables.py 2012-01-26 13:38:54 UTC (rev 7326) @@ -271,10 +271,10 @@ try: self.state.document.settings.record_dependencies.add(source) csv_file = io.FileInput( - source_path=source, encoding=encoding, - error_handler=(self.state.document.settings.\ - input_encoding_error_handler), - handle_io_errors=None) + source_path=source, + encoding=encoding, + error_handler= + self.state.document.settings.input_encoding_error_handler) csv_data = csv_file.read().splitlines() except IOError, error: severe = self.state_machine.reporter.severe( Modified: trunk/docutils/docutils/writers/html4css1/__init__.py =================================================================== --- trunk/docutils/docutils/writers/html4css1/__init__.py 2012-01-26 13:08:04 UTC (rev 7325) +++ trunk/docutils/docutils/writers/html4css1/__init__.py 2012-01-26 13:38:54 UTC (rev 7326) @@ -373,8 +373,7 @@ if self.settings.embed_stylesheet: try: content = io.FileInput(source_path=path, - encoding='utf-8', - handle_io_errors=False).read() + encoding='utf-8').read() self.settings.record_dependencies.add(path) except IOError, err: msg = u"Cannot embed stylesheet '%s': %s." % ( Modified: trunk/docutils/docutils/writers/latex2e/__init__.py =================================================================== --- trunk/docutils/docutils/writers/latex2e/__init__.py 2012-01-26 13:08:04 UTC (rev 7325) +++ trunk/docutils/docutils/writers/latex2e/__init__.py 2012-01-26 13:38:54 UTC (rev 7326) @@ -1179,8 +1179,7 @@ path = base + '.sty' # ensure extension try: content = io.FileInput(source_path=path, - encoding='utf-8', - handle_io_errors=False).read() + encoding='utf-8').read() self.settings.record_dependencies.add(path) except IOError, err: msg = u"Cannot embed stylesheet '%s':\n %s." % ( Modified: trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py =================================================================== --- trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py 2012-01-26 13:08:04 UTC (rev 7325) +++ trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py 2012-01-26 13:38:54 UTC (rev 7326) @@ -212,7 +212,7 @@ <system_message level="4" line="4" source="test data" type="SEVERE"> <paragraph> Problems with "include" directive path: - IOError: [Errno 2] No such file or directory: 'nonexistent.txt'. + InputError: [Errno 2] No such file or directory: 'nonexistent.txt'. <literal_block xml:space="preserve"> .. include:: nonexistent.txt <paragraph> @@ -414,7 +414,7 @@ <system_message level="4" line="3" source="test data" type="SEVERE"> <paragraph> Problems with "include" directive path: - IOError: [Errno 2] No such file or directory: '\u043c\u0438\u0440.txt'. + InputError: [Errno 2] No such file or directory: '\u043c\u0438\u0440.txt'. <literal_block xml:space="preserve"> .. include:: \u043c\u0438\u0440.txt """], @@ -458,7 +458,7 @@ <system_message level="4" line="12" source="%(source)s" type="SEVERE"> <paragraph> Problems with "include" directive path: - IOError: [Errno 2] No such file or directory: '%(nonexistent)s'. + InputError: [Errno 2] No such file or directory: '%(nonexistent)s'. <literal_block xml:space="preserve"> .. include:: <nonexistent> <system_message level="3" line="14" source="%(source)s" type="ERROR"> @@ -697,7 +697,7 @@ <system_message level="4" line="3" source="test data" type="SEVERE"> <paragraph> Problems with "include" directive path: - IOError: [Errno 2] No such file or directory: '%s'. + InputError: [Errno 2] No such file or directory: '%s'. <literal_block xml:space="preserve"> .. include:: <nonexistent> """ % nonexistent_rel], Modified: trunk/docutils/test/test_parsers/test_rst/test_directives/test_raw.py =================================================================== --- trunk/docutils/test/test_parsers/test_rst/test_directives/test_raw.py 2012-01-26 13:08:04 UTC (rev 7325) +++ trunk/docutils/test/test_parsers/test_rst/test_directives/test_raw.py 2012-01-26 13:38:54 UTC (rev 7326) @@ -158,7 +158,7 @@ <system_message level="4" line="1" source="test data" type="SEVERE"> <paragraph> Problems with "raw" directive path: - IOError: [Errno 2] No such file or directory: 'non-existent.file'. + InputError: [Errno 2] No such file or directory: 'non-existent.file'. <literal_block xml:space="preserve"> .. raw:: html :file: non-existent.file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mi...@us...> - 2012-01-27 08:41:43
|
Revision: 7328 http://docutils.svn.sourceforge.net/docutils/?rev=7328&view=rev Author: milde Date: 2012-01-27 08:41:35 +0000 (Fri, 27 Jan 2012) Log Message: ----------- Revert "io.FileInput/io.FileOutput: No system-exit on IOError." This reverts commit 7326 on Davids order. Modified Paths: -------------- trunk/docutils/HISTORY.txt trunk/docutils/docutils/core.py trunk/docutils/docutils/io.py trunk/docutils/docutils/parsers/rst/directives/misc.py trunk/docutils/docutils/parsers/rst/directives/tables.py trunk/docutils/docutils/writers/html4css1/__init__.py trunk/docutils/docutils/writers/latex2e/__init__.py trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py trunk/docutils/test/test_parsers/test_rst/test_directives/test_raw.py Modified: trunk/docutils/HISTORY.txt =================================================================== --- trunk/docutils/HISTORY.txt 2012-01-27 03:59:49 UTC (rev 7327) +++ trunk/docutils/HISTORY.txt 2012-01-27 08:41:35 UTC (rev 7328) @@ -29,18 +29,9 @@ - Fix [ 2971827 ] and [ 3442827 ] extras/roman.py moved to docutils/utils/roman.py -* docutils/core.py: - - - Catch and report InputError/OutputError - (unless the configuration setting "traceback" is true). - * docutils/io.py - Fix [ 3395948 ] (Work around encoding problems in Py3k). - - FileInput/FileOutput: No system-exit on IOError. - Instead, the custom exceptions InputError/OutputError are raised - to allow handling by core.Publisher or a calling application. - The optional argument `handle_io_errors` (to be removed later) is ignored. * docutils/utils.py -> docutils/utils/__init__.py Modified: trunk/docutils/docutils/core.py =================================================================== --- trunk/docutils/docutils/core.py 2012-01-27 03:59:49 UTC (rev 7327) +++ trunk/docutils/docutils/core.py 2012-01-27 08:41:35 UTC (rev 7328) @@ -135,7 +135,7 @@ if self.settings is None: defaults = (settings_overrides or {}).copy() # Propagate exceptions by default when used programmatically: - defaults.setdefault('traceback', True) + defaults.setdefault('traceback', 1) self.get_settings(settings_spec=settings_spec, config_section=config_section, **defaults) @@ -221,7 +221,7 @@ self.debugging_dumps() raise self.report_Exception(error) - exit = True + exit = 1 exit_status = 1 self.debugging_dumps() if (enable_exit_status and self.document @@ -260,10 +260,6 @@ self.report_SystemMessage(error) elif isinstance(error, UnicodeEncodeError): self.report_UnicodeError(error) - elif isinstance(error, io.InputError): - self.report_InputError(error) - elif isinstance(error, io.OutputError): - self.report_OutputError(error) else: print >>self._stderr, u'%s' % ErrorString(error) print >>self._stderr, ("""\ @@ -279,14 +275,6 @@ % (error.level, utils.Reporter.levels[error.level])) - def report_InputError(self, error): - self._stderr.write(u'Unable to open source file for reading:\n' - u' %s\n' % ErrorString(error)) - - def report_OutputError(self, error): - self._stderr.write(u'Unable to open destination file for writing:\n' - u' %s\n' % ErrorString(error)) - def report_UnicodeError(self, error): data = error.object[error.start:error.end] self._stderr.write( Modified: trunk/docutils/docutils/io.py =================================================================== --- trunk/docutils/docutils/io.py 2012-01-27 03:59:49 UTC (rev 7327) +++ trunk/docutils/docutils/io.py 2012-01-27 08:41:35 UTC (rev 7328) @@ -17,11 +17,6 @@ from docutils._compat import b from docutils.error_reporting import locale_encoding, ErrorString, ErrorOutput - -class InputError(IOError): pass -class OutputError(IOError): pass - - class Input(TransformSpec): """ @@ -189,7 +184,7 @@ """ def __init__(self, source=None, source_path=None, encoding=None, error_handler='strict', - autoclose=True, handle_io_errors=False, mode='rU'): + autoclose=True, handle_io_errors=True, mode='rU'): """ :Parameters: - `source`: either a file-like object (which is read directly), or @@ -199,7 +194,7 @@ - `error_handler`: the encoding error handler to use. - `autoclose`: close automatically after read (except when `sys.stdin` is the source). - - `handle_io_errors`: ignored. + - `handle_io_errors`: summarize I/O errors here, and exit? - `mode`: how the file is to be opened (see standard function `open`). The default 'rU' provides universal newline support for text files. @@ -221,7 +216,12 @@ try: self.source = open(source_path, mode, **kwargs) except IOError, error: - raise InputError(error.errno, error.strerror, source_path) + if not handle_io_errors: + raise + print >>self._stderr, ErrorString(error) + print >>self._stderr, (u'Unable to open source' + u" file for reading ('%s'). Exiting." % source_path) + sys.exit(1) else: self.source = sys.stdin elif (sys.version_info >= (3,0) and @@ -286,7 +286,7 @@ def __init__(self, destination=None, destination_path=None, encoding=None, error_handler='strict', autoclose=True, - handle_io_errors=False): + handle_io_errors=True): """ :Parameters: - `destination`: either a file-like object (which is written @@ -294,11 +294,8 @@ `destination_path` given). - `destination_path`: a path to a file, which is opened and then written. - - `encoding`: the text encoding of the output file. - - `error_handler`: the encoding error handler to use. - `autoclose`: close automatically after write (except when `sys.stdout` or `sys.stderr` is the destination). - - `handle_io_errors`: ignored. """ Output.__init__(self, destination, destination_path, encoding, error_handler) @@ -329,8 +326,12 @@ try: self.destination = open(self.destination_path, 'w', **kwargs) except IOError, error: - raise OutputError(error.errno, error.strerror, - self.destination_path) + if not self.handle_io_errors: + raise + print >>self._stderr, ErrorString(error) + print >>self._stderr, (u'Unable to open destination file' + u" for writing ('%s'). Exiting." % self.destination_path) + sys.exit(1) self.opened = True def write(self, data): Modified: trunk/docutils/docutils/parsers/rst/directives/misc.py =================================================================== --- trunk/docutils/docutils/parsers/rst/directives/misc.py 2012-01-27 03:59:49 UTC (rev 7327) +++ trunk/docutils/docutils/parsers/rst/directives/misc.py 2012-01-27 08:41:35 UTC (rev 7328) @@ -69,10 +69,10 @@ try: self.state.document.settings.record_dependencies.add(path) include_file = io.FileInput( - source_path=path, - encoding=encoding, - error_handler= - self.state.document.settings.input_encoding_error_handler) + source_path=path, encoding=encoding, + error_handler=(self.state.document.settings.\ + input_encoding_error_handler), + handle_io_errors=None) except IOError, error: raise self.severe(u'Problems with "%s" directive path:\n%s.' % (self.name, ErrorString(error))) @@ -198,10 +198,11 @@ self.options['file'])) path = utils.relative_path(None, path) try: - eh = self.state.document.settings.input_encoding_error_handler - raw_file = io.FileInput(source_path=path, - encoding=encoding, - error_handler=eh) + raw_file = io.FileInput( + source_path=path, encoding=encoding, + error_handler=(self.state.document.settings.\ + input_encoding_error_handler), + handle_io_errors=None) # TODO: currently, raw input files are recorded as # dependencies even if not used for the chosen output format. self.state.document.settings.record_dependencies.add(path) Modified: trunk/docutils/docutils/parsers/rst/directives/tables.py =================================================================== --- trunk/docutils/docutils/parsers/rst/directives/tables.py 2012-01-27 03:59:49 UTC (rev 7327) +++ trunk/docutils/docutils/parsers/rst/directives/tables.py 2012-01-27 08:41:35 UTC (rev 7328) @@ -271,10 +271,10 @@ try: self.state.document.settings.record_dependencies.add(source) csv_file = io.FileInput( - source_path=source, - encoding=encoding, - error_handler= - self.state.document.settings.input_encoding_error_handler) + source_path=source, encoding=encoding, + error_handler=(self.state.document.settings.\ + input_encoding_error_handler), + handle_io_errors=None) csv_data = csv_file.read().splitlines() except IOError, error: severe = self.state_machine.reporter.severe( Modified: trunk/docutils/docutils/writers/html4css1/__init__.py =================================================================== --- trunk/docutils/docutils/writers/html4css1/__init__.py 2012-01-27 03:59:49 UTC (rev 7327) +++ trunk/docutils/docutils/writers/html4css1/__init__.py 2012-01-27 08:41:35 UTC (rev 7328) @@ -373,7 +373,8 @@ if self.settings.embed_stylesheet: try: content = io.FileInput(source_path=path, - encoding='utf-8').read() + encoding='utf-8', + handle_io_errors=False).read() self.settings.record_dependencies.add(path) except IOError, err: msg = u"Cannot embed stylesheet '%s': %s." % ( Modified: trunk/docutils/docutils/writers/latex2e/__init__.py =================================================================== --- trunk/docutils/docutils/writers/latex2e/__init__.py 2012-01-27 03:59:49 UTC (rev 7327) +++ trunk/docutils/docutils/writers/latex2e/__init__.py 2012-01-27 08:41:35 UTC (rev 7328) @@ -1179,7 +1179,8 @@ path = base + '.sty' # ensure extension try: content = io.FileInput(source_path=path, - encoding='utf-8').read() + encoding='utf-8', + handle_io_errors=False).read() self.settings.record_dependencies.add(path) except IOError, err: msg = u"Cannot embed stylesheet '%s':\n %s." % ( Modified: trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py =================================================================== --- trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py 2012-01-27 03:59:49 UTC (rev 7327) +++ trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py 2012-01-27 08:41:35 UTC (rev 7328) @@ -212,7 +212,7 @@ <system_message level="4" line="4" source="test data" type="SEVERE"> <paragraph> Problems with "include" directive path: - InputError: [Errno 2] No such file or directory: 'nonexistent.txt'. + IOError: [Errno 2] No such file or directory: 'nonexistent.txt'. <literal_block xml:space="preserve"> .. include:: nonexistent.txt <paragraph> @@ -414,7 +414,7 @@ <system_message level="4" line="3" source="test data" type="SEVERE"> <paragraph> Problems with "include" directive path: - InputError: [Errno 2] No such file or directory: '\u043c\u0438\u0440.txt'. + IOError: [Errno 2] No such file or directory: '\u043c\u0438\u0440.txt'. <literal_block xml:space="preserve"> .. include:: \u043c\u0438\u0440.txt """], @@ -458,7 +458,7 @@ <system_message level="4" line="12" source="%(source)s" type="SEVERE"> <paragraph> Problems with "include" directive path: - InputError: [Errno 2] No such file or directory: '%(nonexistent)s'. + IOError: [Errno 2] No such file or directory: '%(nonexistent)s'. <literal_block xml:space="preserve"> .. include:: <nonexistent> <system_message level="3" line="14" source="%(source)s" type="ERROR"> @@ -697,7 +697,7 @@ <system_message level="4" line="3" source="test data" type="SEVERE"> <paragraph> Problems with "include" directive path: - InputError: [Errno 2] No such file or directory: '%s'. + IOError: [Errno 2] No such file or directory: '%s'. <literal_block xml:space="preserve"> .. include:: <nonexistent> """ % nonexistent_rel], Modified: trunk/docutils/test/test_parsers/test_rst/test_directives/test_raw.py =================================================================== --- trunk/docutils/test/test_parsers/test_rst/test_directives/test_raw.py 2012-01-27 03:59:49 UTC (rev 7327) +++ trunk/docutils/test/test_parsers/test_rst/test_directives/test_raw.py 2012-01-27 08:41:35 UTC (rev 7328) @@ -158,7 +158,7 @@ <system_message level="4" line="1" source="test data" type="SEVERE"> <paragraph> Problems with "raw" directive path: - InputError: [Errno 2] No such file or directory: 'non-existent.file'. + IOError: [Errno 2] No such file or directory: 'non-existent.file'. <literal_block xml:space="preserve"> .. raw:: html :file: non-existent.file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mi...@us...> - 2012-02-03 12:22:21
|
Revision: 7338 http://docutils.svn.sourceforge.net/docutils/?rev=7338&view=rev Author: milde Date: 2012-02-03 12:22:14 +0000 (Fri, 03 Feb 2012) Log Message: ----------- Fix relative_path() with source=None and `unicode` target. Modified Paths: -------------- trunk/docutils/docutils/utils/__init__.py trunk/docutils/test/test_utils.py Modified: trunk/docutils/docutils/utils/__init__.py =================================================================== --- trunk/docutils/docutils/utils/__init__.py 2012-02-03 08:16:53 UTC (rev 7337) +++ trunk/docutils/docutils/utils/__init__.py 2012-02-03 12:22:14 UTC (rev 7338) @@ -457,7 +457,8 @@ If there is no common prefix, return the absolute path to `target`. """ - source_parts = os.path.abspath(source or 'dummy_file').split(os.sep) + source_parts = os.path.abspath(source or type(target)('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]: Modified: trunk/docutils/test/test_utils.py =================================================================== --- trunk/docutils/test/test_utils.py 2012-02-03 08:16:53 UTC (rev 7337) +++ trunk/docutils/test/test_utils.py 2012-02-03 12:22:14 UTC (rev 7338) @@ -253,5 +253,37 @@ self.assertEqual(utils.column_width(u'dâ'), 2) # combining + def test_relative_path(self): + # Build and return a path to `target`, relative to `source`: + # Use '/' as path sep in result. + self.assertEqual(utils.relative_path('spam', 'spam'), '') + source = os.path.join('h\xE4m', 'spam', 'fileA') + target = os.path.join('h\xE4m', 'spam', 'fileB') + self.assertEqual(utils.relative_path(source, target), 'fileB') + source = os.path.join('h\xE4m', 'spam', 'fileA') + target = os.path.join('h\xE4m', 'fileB') + self.assertEqual(utils.relative_path(source, target), '../fileB') + # if source is None, default to the cwd: + target = os.path.join('eggs', 'fileB') + self.assertEqual(utils.relative_path(None, target), 'eggs/fileB') + # If there is no common prefix, return the absolute path to `target`: + # source = '/foo/bar/fileA' # POSIX + # TODO: how to specify an absolute path independent of the OS? + # target = os.path.join('eggs', 'fileB') + # self.assertEqual(utils.relative_path(source, target), + # os.path.abspath('fileB')) + # Correctly process unicode instances: + self.assertEqual(utils.relative_path(u'spam', u'spam'), u'') + source = os.path.join(u'h\xE4m', u'spam', u'fileA') + target = os.path.join(u'h\xE4m', u'spam', u'fileB') + self.assertEqual(utils.relative_path(source, target), u'fileB') + source = os.path.join(u'h\xE4m', u'spam', u'fileA') + target = os.path.join(u'h\xE4m', u'fileB') + self.assertEqual(utils.relative_path(source, target), u'../fileB') + # if source is None, default to the cwd: + target = os.path.join(u'eggs', u'fileB') + self.assertEqual(utils.relative_path(None, target), u'eggs/fileB') + + if __name__ == '__main__': unittest.main() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mi...@us...> - 2012-02-03 12:23:38
|
Revision: 7339 http://docutils.svn.sourceforge.net/docutils/?rev=7339&view=rev Author: milde Date: 2012-02-03 12:23:27 +0000 (Fri, 03 Feb 2012) Log Message: ----------- Fix [ 3481980 ] Use os.getcwdu() in make_paths_absolute(). Modified Paths: -------------- trunk/docutils/HISTORY.txt trunk/docutils/RELEASE-NOTES.txt trunk/docutils/docutils/frontend.py trunk/docutils/test/test_settings.py Modified: trunk/docutils/HISTORY.txt =================================================================== --- trunk/docutils/HISTORY.txt 2012-02-03 12:22:14 UTC (rev 7338) +++ trunk/docutils/HISTORY.txt 2012-02-03 12:23:27 UTC (rev 7339) @@ -29,6 +29,10 @@ - Fix [ 2971827 ] and [ 3442827 ] extras/roman.py moved to docutils/utils/roman.py +* docutils/frontend.py + + - Fix [ 3481980 ] Use os.getcwdu() in make_paths_absolute(). + * docutils/io.py - Fix [ 3395948 ] (Work around encoding problems in Py3k). @@ -37,14 +41,17 @@ - docutils.utils is now a package (providing a place for sub-modules) - .. important:: docutils/math, docutils/error_reporting.py, and + .. note:: docutils/math, docutils/error_reporting.py, and docutils/urischemes.py will move to the utils package in the next - release, too. Code importing these modules needs to adapt - (``import docutils.math`` -> ``import docutils.utils.math``, etc.). + release, too. See RELEASE-NOTES__ + __ RELEASE-NOTES.html + - DependencyList uses io.FileOutput and 'utf8' encoding to prevent - errors recording non-ASCII filenames (fixes [ 3434355 ]. + errors recording non-ASCII filenames (fixes [ 3434355 ]). + - Fix relative_path() with source=None and `unicode` target. + * docutils/parsers/rst/states.py - Fix [ 3402314 ] allow non-ASCII whitespace, punctuation Modified: trunk/docutils/RELEASE-NOTES.txt =================================================================== --- trunk/docutils/RELEASE-NOTES.txt 2012-02-03 12:22:14 UTC (rev 7338) +++ trunk/docutils/RELEASE-NOTES.txt 2012-02-03 12:23:27 UTC (rev 7339) @@ -16,6 +16,19 @@ .. contents:: +Future changes +============== + +* docutils/math, docutils/error_reporting.py, and + docutils/urischemes.py will move to the utils package + Code importing these modules needs to adapt, e.g.:: + + try: + import docutils.math as math + except ImportError: + import docutils.utils.math as math + + Release 0.9 (unpublished) ========================= @@ -31,11 +44,6 @@ - docutils.utils is now a package (providing a place for sub-modules) - .. important:: docutils/math, docutils/error_reporting.py, and - docutils/urischemes.py will move to the utils package in the next - release, too. Code importing these modules needs to adapt - (``import docutils.math`` -> ``import docutils.utils.math``, etc.). - * docutils/writers/html4css1/__init__.py - change default for `math-output` setting to MathJax Modified: trunk/docutils/docutils/frontend.py =================================================================== --- trunk/docutils/docutils/frontend.py 2012-02-03 12:22:14 UTC (rev 7338) +++ trunk/docutils/docutils/frontend.py 2012-02-03 12:23:27 UTC (rev 7339) @@ -184,7 +184,8 @@ `OptionParser.relative_path_settings`. """ if base_path is None: - base_path = os.getcwd() + base_path = os.getcwdu() # type(base_path) == unicode + # to allow combining non-ASCII cwd with unicode values in `pathdict` for key in keys: if key in pathdict: value = pathdict[key] @@ -618,8 +619,7 @@ def check_values(self, values, args): """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()) + make_paths_absolute(values.__dict__, self.relative_path_settings) values._config_files = self.config_files return values Modified: trunk/docutils/test/test_settings.py =================================================================== --- trunk/docutils/test/test_settings.py 2012-02-03 12:22:14 UTC (rev 7338) +++ trunk/docutils/test/test_settings.py 2012-02-03 12:23:27 UTC (rev 7339) @@ -169,5 +169,29 @@ os.environ = self.orig_environ +class HelperFunctionsTests(unittest.TestCase): + + pathdict = {'foo': 'hallo', 'ham': u'h\xE4m', 'spam': u'spam'} + keys = ['foo', 'ham'] + + def test_make_paths_absolute(self): + pathdict = self.pathdict.copy() + frontend.make_paths_absolute(pathdict, self.keys, base_path='base') + self.assertEqual(pathdict['foo'], os.path.abspath('base/hallo')) + self.assertEqual(pathdict['ham'], os.path.abspath(u'base/h\xE4m')) + # not touched, because key not in keys: + self.assertEqual(pathdict['spam'], u'spam') + + def test_make_paths_absolute_cwd(self): + # With base_path None, the cwd is used as base path. + # Settings values may-be `unicode` instances, therefore + # os.getcwdu() is used and the converted path is a unicode instance: + pathdict = self.pathdict.copy() + frontend.make_paths_absolute(pathdict, self.keys) + self.assertEqual(pathdict['foo'], os.path.abspath(u'hallo')) + self.assertEqual(pathdict['ham'], os.path.abspath(u'h\xE4m')) + # not touched, because key not in keys: + self.assertEqual(pathdict['spam'], u'spam') + if __name__ == '__main__': unittest.main() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mi...@us...> - 2012-02-08 19:46:20
|
Revision: 7348 http://docutils.svn.sourceforge.net/docutils/?rev=7348&view=rev Author: milde Date: 2012-02-08 19:46:11 +0000 (Wed, 08 Feb 2012) Log Message: ----------- Use `field_marker` pattern to look for start of a directive option block (fixes [ 3484857 ]). Modified Paths: -------------- trunk/docutils/HISTORY.txt trunk/docutils/docutils/parsers/rst/states.py trunk/docutils/test/test_parsers/test_rst/test_directives/test_admonitions.py trunk/docutils/test/test_parsers/test_rst/test_directives/test_images.py Modified: trunk/docutils/HISTORY.txt =================================================================== --- trunk/docutils/HISTORY.txt 2012-02-06 21:03:50 UTC (rev 7347) +++ trunk/docutils/HISTORY.txt 2012-02-08 19:46:11 UTC (rev 7348) @@ -56,6 +56,8 @@ - Fix [ 3402314 ] allow non-ASCII whitespace, punctuation characters and "international" quotes around inline markup. + - Use `field_marker` pattern to look for start of a + directive option block (fixes [ 3484857 ]). * docutils/parsers/rst/tableparser.py Modified: trunk/docutils/docutils/parsers/rst/states.py =================================================================== --- trunk/docutils/docutils/parsers/rst/states.py 2012-02-06 21:03:50 UTC (rev 7347) +++ trunk/docutils/docutils/parsers/rst/states.py 2012-02-08 19:46:11 UTC (rev 7348) @@ -2142,8 +2142,8 @@ 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] == ':': + for i, line in enumerate(arg_block): + if re.match(Body.patterns['field_marker'], line): opt_block = arg_block[i:] arg_block = arg_block[:i] break Modified: trunk/docutils/test/test_parsers/test_rst/test_directives/test_admonitions.py =================================================================== --- trunk/docutils/test/test_parsers/test_rst/test_directives/test_admonitions.py 2012-02-06 21:03:50 UTC (rev 7347) +++ trunk/docutils/test/test_parsers/test_rst/test_directives/test_admonitions.py 2012-02-08 19:46:11 UTC (rev 7348) @@ -111,6 +111,35 @@ No blank lines in-between. """], ["""\ +.. note:: Content before options + is possible too. + :class: mynote + +.. note:: :strong:`a role is not an option`. + :name: role not option + +.. note:: a role is + :strong:`not an option`, even if its starts a line. +""", +"""\ +<document source="test data"> + <note classes="mynote"> + <paragraph> + Content before options + is possible too. + <note ids="role-not-option" names="role\ not\ option"> + <paragraph> + <strong> + a role is not an option + . + <note> + <paragraph> + a role is + <strong> + not an option + , even if its starts a line. +"""], +["""\ .. note:: """, """\ Modified: trunk/docutils/test/test_parsers/test_rst/test_directives/test_images.py =================================================================== --- trunk/docutils/test/test_parsers/test_rst/test_directives/test_images.py 2012-02-06 21:03:50 UTC (rev 7347) +++ trunk/docutils/test/test_parsers/test_rst/test_directives/test_images.py 2012-02-08 19:46:11 UTC (rev 7348) @@ -85,6 +85,8 @@ :width: 200 :scale: 50 """], +# If there are multiple lines in the link block, they are stripped of +# leading and trailing whitespace and joined together: ["""\ .. image:: a/very/long/path/to/ picture.png @@ -96,8 +98,36 @@ <document source="test data"> <image height="100" scale="50" uri="a/very/long/path/to/picture.png" width="200"> """], +# The following two misspellings were detected in Docutils <= 0.8 +# (the option block was started by any line starting with a colon +# which led to problems with named roles in other directives): ["""\ .. image:: picture.png + :scale 50 +""", +"""\ +<document source="test data"> + <image uri="picture.png:scale50"> +"""], +["""\ +.. image:: picture.png + :: 50 +""", +"""\ +<document source="test data"> + <image uri="picture.png::50"> +"""], +# a missing leading colon went undetected also in Docutils <= 0.8: +["""\ +.. image:: picture.png + scale: 50 +""", +"""\ +<document source="test data"> + <image uri="picture.pngscale:50"> +"""], +["""\ +.. image:: picture.png :width: 200px :height: 100 em """, @@ -175,6 +205,7 @@ """ % DocutilsTestSupport.exception_data(int, None)[1][0]], ["""\ .. image:: picture.png + :height: 100 :scale 50 """, """\ @@ -185,32 +216,11 @@ invalid option block. <literal_block xml:space="preserve"> .. image:: picture.png + :height: 100 :scale 50 """], ["""\ .. image:: picture.png - scale: 50 -""", -"""\ -<document source="test data"> - <image uri="picture.pngscale:50"> -"""], -["""\ -.. image:: picture.png - :: 50 -""", -"""\ -<document source="test data"> - <system_message level="3" line="1" source="test data" type="ERROR"> - <paragraph> - Error in "image" directive: - invalid option block. - <literal_block xml:space="preserve"> - .. image:: picture.png - :: 50 -"""], -["""\ -.. image:: picture.png :sale: 50 """, """\ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <go...@us...> - 2012-02-20 21:31:55
|
Revision: 7363 http://docutils.svn.sourceforge.net/docutils/?rev=7363&view=rev Author: goodger Date: 2012-02-20 21:31:48 +0000 (Mon, 20 Feb 2012) Log Message: ----------- note that references with embedded target URIs have been referenced (implicitly); enable INFO-level system messages in pseudo-XML functional test Modified Paths: -------------- trunk/docutils/docutils/parsers/rst/states.py trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt trunk/docutils/test/functional/tests/standalone_rst_pseudoxml.py Modified: trunk/docutils/docutils/parsers/rst/states.py =================================================================== --- trunk/docutils/docutils/parsers/rst/states.py 2012-02-16 21:24:09 UTC (rev 7362) +++ trunk/docutils/docutils/parsers/rst/states.py 2012-02-20 21:31:48 UTC (rev 7363) @@ -795,6 +795,7 @@ uri = self.adjust_uri(uri) if uri: target = nodes.target(match.group(1), refuri=uri) + target.referenced = 1 else: raise ApplicationError('problem with URI: %r' % uri_text) if not text: Modified: trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt =================================================================== --- trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt 2012-02-16 21:24:09 UTC (rev 7362) +++ trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt 2012-02-20 21:31:48 UTC (rev 7363) @@ -616,6 +616,9 @@ <list_item> <paragraph> Four + <system_message level="1" line="8" source="functional/input/data/standard.txt" type="INFO"> + <paragraph> + Enumerated list start value not ordinal-1: "3" (ordinal 3) <enumerated_list enumtype="upperalpha" prefix="" start="3" suffix="."> <list_item> <paragraph> @@ -623,6 +626,9 @@ <list_item> <paragraph> D + <system_message level="1" line="8" source="functional/input/data/standard.txt" type="INFO"> + <paragraph> + Enumerated list start value not ordinal-1: "C" (ordinal 3) <enumerated_list enumtype="lowerroman" prefix="" start="3" suffix="."> <list_item> <paragraph> @@ -630,6 +636,9 @@ <list_item> <paragraph> iv + <system_message level="1" line="8" source="functional/input/data/standard.txt" type="INFO"> + <paragraph> + Enumerated list start value not ordinal-1: "iii" (ordinal 3) <section ids="definition-lists" names="definition\ lists"> <title auto="1" refid="id43"> <generated classes="sectnum"> @@ -1123,6 +1132,9 @@ <generated classes="sectnum"> 2.13.2 Duplicate Target Names + <system_message backrefs="id21" level="1" line="438" source="functional/input/data/standard.txt" type="INFO"> + <paragraph> + Duplicate implicit target name: "duplicate target names". <paragraph> Since there are two "Duplicate Target Names" section headers, we cannot uniquely refer to either of them by name. If we try to (like @@ -2044,3 +2056,24 @@ <system_message backrefs="id90" ids="id89" level="3" line="440" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Duplicate target name, cannot be used as a unique reference: "duplicate target names". + <system_message level="1" line="163" source="functional/input/data/standard.txt" type="INFO"> + <paragraph> + Hyperlink target "target" is not referenced. + <system_message level="1" line="405" source="functional/input/data/standard.txt" type="INFO"> + <paragraph> + Hyperlink target "another-target" is not referenced. + <system_message level="1" line="473" source="functional/input/data/standard.txt" type="INFO"> + <paragraph> + Hyperlink target "image-target-1" is not referenced. + <system_message level="1" line="474" source="functional/input/data/standard.txt" type="INFO"> + <paragraph> + Hyperlink target "image-target-2" is not referenced. + <system_message level="1" line="475" source="functional/input/data/standard.txt" type="INFO"> + <paragraph> + Hyperlink target "image-target-3" is not referenced. + <system_message level="1" line="632" source="functional/input/data/standard.txt" type="INFO"> + <paragraph> + Hyperlink target "docutils" is not referenced. + <system_message level="1" line="753" source="functional/input/data/standard.txt" type="INFO"> + <paragraph> + Hyperlink target "hyperlink targets" is not referenced. Modified: trunk/docutils/test/functional/tests/standalone_rst_pseudoxml.py =================================================================== --- trunk/docutils/test/functional/tests/standalone_rst_pseudoxml.py 2012-02-16 21:24:09 UTC (rev 7362) +++ trunk/docutils/test/functional/tests/standalone_rst_pseudoxml.py 2012-02-20 21:31:48 UTC (rev 7363) @@ -6,3 +6,7 @@ # Keyword parameters passed to publish_file. writer_name = "pseudoxml" + +# Settings +# enable INFO-level system messages in this test: +settings_overrides['report_level'] = 1 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mi...@us...> - 2012-03-19 16:24:21
|
Revision: 7382 http://docutils.svn.sourceforge.net/docutils/?rev=7382&view=rev Author: milde Date: 2012-03-19 16:24:10 +0000 (Mon, 19 Mar 2012) Log Message: ----------- `mode` argument for FileOutput avoids code replication in BinaryFileOutput. Modified Paths: -------------- trunk/docutils/HISTORY.txt trunk/docutils/docutils/io.py Modified: trunk/docutils/HISTORY.txt =================================================================== --- trunk/docutils/HISTORY.txt 2012-03-16 19:49:39 UTC (rev 7381) +++ trunk/docutils/HISTORY.txt 2012-03-19 16:24:10 UTC (rev 7382) @@ -36,6 +36,8 @@ * docutils/io.py - Fix [ 3395948 ] (Work around encoding problems in Py3k). + - `mode` argument for FileOutput avoids code replication in + BinaryFileOutput. * docutils/utils.py -> docutils/utils/__init__.py Modified: trunk/docutils/docutils/io.py =================================================================== --- trunk/docutils/docutils/io.py 2012-03-16 19:49:39 UTC (rev 7381) +++ trunk/docutils/docutils/io.py 2012-03-19 16:24:10 UTC (rev 7382) @@ -284,9 +284,15 @@ Output for single, simple file-like objects. """ + mode = 'w' + """The mode argument for `open()`.""" + # 'wb' for binary (e.g. OpenOffice) files. + # (Do not use binary mode ('wb') for text files, as this prevents the + # conversion of newlines to the system specific default.) + def __init__(self, destination=None, destination_path=None, encoding=None, error_handler='strict', autoclose=True, - handle_io_errors=True): + handle_io_errors=None, mode=None): """ :Parameters: - `destination`: either a file-like object (which is written @@ -294,14 +300,22 @@ `destination_path` given). - `destination_path`: a path to a file, which is opened and then written. + - `encoding`: the text encoding of the output file. + - `error_handler`: the encoding error handler to use. - `autoclose`: close automatically after write (except when `sys.stdout` or `sys.stderr` is the destination). + - `handle_io_errors`: summarize I/O errors here, and exit? + - `mode`: how the file is to be opened (see standard function + `open`). The default is 'w', providing universal newline + support for text files. """ Output.__init__(self, destination, destination_path, encoding, error_handler) self.opened = True self.autoclose = autoclose self.handle_io_errors = handle_io_errors + if mode is not None: + self.mode = mode self._stderr = ErrorOutput() if destination is None: if destination_path: @@ -316,15 +330,13 @@ def open(self): # Specify encoding in Python 3. - # (Do not use binary mode ('wb') as this prevents the - # conversion of newlines to the system specific default.) if sys.version_info >= (3,0): kwargs = {'encoding': self.encoding, 'errors': self.error_handler} else: kwargs = {} try: - self.destination = open(self.destination_path, 'w', **kwargs) + self.destination = open(self.destination_path, self.mode, **kwargs) except IOError, error: if not self.handle_io_errors: raise @@ -376,17 +388,9 @@ """ A version of docutils.io.FileOutput which writes to a binary file. """ - def open(self): - try: - self.destination = open(self.destination_path, 'wb') - except IOError, error: - if not self.handle_io_errors: - raise - print >>self._stderr, ErrorString(error) - print >>self._stderr, (u'Unable to open destination file' - u" for writing ('%s'). Exiting." % self.destination_path) - sys.exit(1) - self.opened = True + # Used by core.publish_cmdline_to_binary() which in turn is used by + # rst2odt (OpenOffice writer) + mode = 'wb' class StringInput(Input): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mi...@us...> - 2012-03-19 22:59:16
|
Revision: 7384 http://docutils.svn.sourceforge.net/docutils/?rev=7384&view=rev Author: milde Date: 2012-03-19 22:59:09 +0000 (Mon, 19 Mar 2012) Log Message: ----------- Backwards-compatible fix for system-exit on IOError. Modified Paths: -------------- trunk/docutils/HISTORY.txt trunk/docutils/docutils/core.py trunk/docutils/docutils/io.py trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py trunk/docutils/test/test_parsers/test_rst/test_directives/test_raw.py trunk/docutils/test/test_publisher.py Modified: trunk/docutils/HISTORY.txt =================================================================== --- trunk/docutils/HISTORY.txt 2012-03-19 17:04:49 UTC (rev 7383) +++ trunk/docutils/HISTORY.txt 2012-03-19 22:59:09 UTC (rev 7384) @@ -38,7 +38,15 @@ - Fix [ 3395948 ] (Work around encoding problems in Py3k). - `mode` argument for FileOutput avoids code replication in BinaryFileOutput. + - New exceptions InputError and OutputError for IO errors in + FileInput/FileOutput. + +* docutils/core.py: + - No "hard" system exit on file IO errors: catch and report them in + `Publisher.reportException` instead. Allows handling by a calling + application if the configuration setting `traceback` is True. + * docutils/utils.py -> docutils/utils/__init__.py - docutils.utils is now a package (providing a place for sub-modules) Modified: trunk/docutils/docutils/core.py =================================================================== --- trunk/docutils/docutils/core.py 2012-03-19 17:04:49 UTC (rev 7383) +++ trunk/docutils/docutils/core.py 2012-03-19 22:59:09 UTC (rev 7384) @@ -135,7 +135,7 @@ if self.settings is None: defaults = (settings_overrides or {}).copy() # Propagate exceptions by default when used programmatically: - defaults.setdefault('traceback', 1) + defaults.setdefault('traceback', True) self.get_settings(settings_spec=settings_spec, config_section=config_section, **defaults) @@ -171,9 +171,17 @@ source_path = self.settings._source else: self.settings._source = source_path - self.source = self.source_class( - source=source, source_path=source_path, - encoding=self.settings.input_encoding) + # Raise IOError instead of system exit with `tracback == True` + # TODO: change io.FileInput's default behaviour and remove this hack + try: + self.source = self.source_class( + source=source, source_path=source_path, + encoding=self.settings.input_encoding, + handle_io_errors=False) + except TypeError: + 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: @@ -184,6 +192,9 @@ destination=destination, destination_path=destination_path, encoding=self.settings.output_encoding, error_handler=self.settings.output_encoding_error_handler) + # Raise IOError instead of system exit with `tracback == True` + # TODO: change io.FileInput's default behaviour and remove this hack + self.destination.handle_io_errors=False def apply_transforms(self): self.document.transformer.populate_from_components( @@ -221,7 +232,7 @@ self.debugging_dumps() raise self.report_Exception(error) - exit = 1 + exit = True exit_status = 1 self.debugging_dumps() if (enable_exit_status and self.document @@ -260,6 +271,13 @@ self.report_SystemMessage(error) elif isinstance(error, UnicodeEncodeError): self.report_UnicodeError(error) + elif isinstance(error, io.InputError): + self._stderr.write(u'Unable to open source file for reading:\n' + u' %s\n' % ErrorString(error)) + elif isinstance(error, io.OutputError): + self._stderr.write( + u'Unable to open destination file for writing:\n' + u' %s\n' % ErrorString(error)) else: print >>self._stderr, u'%s' % ErrorString(error) print >>self._stderr, ("""\ Modified: trunk/docutils/docutils/io.py =================================================================== --- trunk/docutils/docutils/io.py 2012-03-19 17:04:49 UTC (rev 7383) +++ trunk/docutils/docutils/io.py 2012-03-19 22:59:09 UTC (rev 7384) @@ -17,6 +17,11 @@ from docutils._compat import b from docutils.error_reporting import locale_encoding, ErrorString, ErrorOutput + +class InputError(IOError): pass +class OutputError(IOError): pass + + class Input(TransformSpec): """ @@ -216,12 +221,13 @@ try: self.source = open(source_path, mode, **kwargs) except IOError, error: - if not handle_io_errors: - raise - print >>self._stderr, ErrorString(error) - print >>self._stderr, (u'Unable to open source' - u" file for reading ('%s'). Exiting." % source_path) - sys.exit(1) + if handle_io_errors: + print >>self._stderr, ErrorString(error) + print >>self._stderr, ( + u'Unable to open source file for reading ("%s").' + u'Exiting.' % source_path) + sys.exit(1) + raise InputError(error.errno, error.strerror, source_path) else: self.source = sys.stdin elif (sys.version_info >= (3,0) and @@ -292,7 +298,7 @@ def __init__(self, destination=None, destination_path=None, encoding=None, error_handler='strict', autoclose=True, - handle_io_errors=None, mode=None): + handle_io_errors=True, mode=None): """ :Parameters: - `destination`: either a file-like object (which is written @@ -338,12 +344,13 @@ try: self.destination = open(self.destination_path, self.mode, **kwargs) except IOError, error: - if not self.handle_io_errors: - raise - print >>self._stderr, ErrorString(error) - print >>self._stderr, (u'Unable to open destination file' - u" for writing ('%s'). Exiting." % self.destination_path) - sys.exit(1) + if self.handle_io_errors: + print >>self._stderr, ErrorString(error) + print >>self._stderr, (u'Unable to open destination file' + u" for writing ('%s'). Exiting." % self.destination_path) + sys.exit(1) + raise OutputError(error.errno, error.strerror, + self.destination_path) self.opened = True def write(self, data): Modified: trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py =================================================================== --- trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py 2012-03-19 17:04:49 UTC (rev 7383) +++ trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py 2012-03-19 22:59:09 UTC (rev 7384) @@ -212,7 +212,7 @@ <system_message level="4" line="4" source="test data" type="SEVERE"> <paragraph> Problems with "include" directive path: - IOError: [Errno 2] No such file or directory: 'nonexistent.txt'. + InputError: [Errno 2] No such file or directory: 'nonexistent.txt'. <literal_block xml:space="preserve"> .. include:: nonexistent.txt <paragraph> @@ -414,7 +414,7 @@ <system_message level="4" line="3" source="test data" type="SEVERE"> <paragraph> Problems with "include" directive path: - IOError: [Errno 2] No such file or directory: '\u043c\u0438\u0440.txt'. + InputError: [Errno 2] No such file or directory: '\u043c\u0438\u0440.txt'. <literal_block xml:space="preserve"> .. include:: \u043c\u0438\u0440.txt """], @@ -458,7 +458,7 @@ <system_message level="4" line="12" source="%(source)s" type="SEVERE"> <paragraph> Problems with "include" directive path: - IOError: [Errno 2] No such file or directory: '%(nonexistent)s'. + InputError: [Errno 2] No such file or directory: '%(nonexistent)s'. <literal_block xml:space="preserve"> .. include:: <nonexistent> <system_message level="3" line="14" source="%(source)s" type="ERROR"> @@ -697,7 +697,7 @@ <system_message level="4" line="3" source="test data" type="SEVERE"> <paragraph> Problems with "include" directive path: - IOError: [Errno 2] No such file or directory: '%s'. + InputError: [Errno 2] No such file or directory: '%s'. <literal_block xml:space="preserve"> .. include:: <nonexistent> """ % nonexistent_rel], Modified: trunk/docutils/test/test_parsers/test_rst/test_directives/test_raw.py =================================================================== --- trunk/docutils/test/test_parsers/test_rst/test_directives/test_raw.py 2012-03-19 17:04:49 UTC (rev 7383) +++ trunk/docutils/test/test_parsers/test_rst/test_directives/test_raw.py 2012-03-19 22:59:09 UTC (rev 7384) @@ -158,7 +158,7 @@ <system_message level="4" line="1" source="test data" type="SEVERE"> <paragraph> Problems with "raw" directive path: - IOError: [Errno 2] No such file or directory: 'non-existent.file'. + InputError: [Errno 2] No such file or directory: 'non-existent.file'. <literal_block xml:space="preserve"> .. raw:: html :file: non-existent.file Modified: trunk/docutils/test/test_publisher.py =================================================================== --- trunk/docutils/test/test_publisher.py 2012-03-19 17:04:49 UTC (rev 7383) +++ trunk/docutils/test/test_publisher.py 2012-03-19 22:59:09 UTC (rev 7384) @@ -53,6 +53,29 @@ """ % u_prefix) +class PublisherTests(DocutilsTestSupport.StandardTestCase): + + def test_input_error_handling(self): + # core.publish_cmdline(argv=['nonexisting/path']) + # exits with a short message, if `traceback` is False, + + # pass IOErrors to calling application if `traceback` is True + try: + core.publish_cmdline(argv=['nonexisting/path'], + settings_overrides={'traceback': True}) + except IOError, e: + self.assertTrue(isinstance(e, io.InputError)) + + + def test_output_error_handling(self): + # pass IOErrors to calling application if `traceback` is True + try: + core.publish_cmdline(argv=['data/include.txt', 'nonexisting/path'], + settings_overrides={'traceback': True}) + except IOError, e: + self.assertTrue(isinstance(e, io.OutputError)) + + class PublishDoctreeTestCase(DocutilsTestSupport.StandardTestCase, docutils.SettingsSpec): settings_default_overrides = { @@ -100,7 +123,7 @@ def test_publish_pickle(self): # Test publishing a document tree with pickling and unpickling. - + # Produce the document tree. doctree = core.publish_doctree( source=test_document, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mi...@us...> - 2012-03-30 07:11:48
|
Revision: 7388 http://docutils.svn.sourceforge.net/docutils/?rev=7388&view=rev Author: milde Date: 2012-03-30 07:11:39 +0000 (Fri, 30 Mar 2012) Log Message: ----------- Apply [ 3512791 ] do not compare string literals with "is". Modified Paths: -------------- trunk/docutils/HISTORY.txt trunk/docutils/docutils/writers/latex2e/__init__.py Modified: trunk/docutils/HISTORY.txt =================================================================== --- trunk/docutils/HISTORY.txt 2012-03-23 02:29:27 UTC (rev 7387) +++ trunk/docutils/HISTORY.txt 2012-03-30 07:11:39 UTC (rev 7388) @@ -82,6 +82,7 @@ - Use ``\setcounter{secnumdepth}{0}`` instead of ``*``-versions when suppressing LaTeX section numbering. - Use ``\DUtitle`` for unsupported section levels + - Apply [ 3512791 ] do not compare string literals with "is" * docutils/writers/html4css1/__init__.py Modified: trunk/docutils/docutils/writers/latex2e/__init__.py =================================================================== --- trunk/docutils/docutils/writers/latex2e/__init__.py 2012-03-23 02:29:27 UTC (rev 7387) +++ trunk/docutils/docutils/writers/latex2e/__init__.py 2012-03-30 07:11:39 UTC (rev 7388) @@ -392,7 +392,7 @@ self.setup.append( r'\addto\shorthandsspanish{\spanishdeactivate{."~<>}}') # or prepend r'\def\spanishoptions{es-noshorthands}' - if (languages[-1] is 'english' and + if (languages[-1] == 'english' and 'french' in self.otherlanguages.keys()): self.setup += ['% Prevent side-effects if French hyphenation ' 'patterns are not loaded:', This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mi...@us...> - 2012-03-30 11:58:29
|
Revision: 7389 http://docutils.svn.sourceforge.net/docutils/?rev=7389&view=rev Author: milde Date: 2012-03-30 11:58:21 +0000 (Fri, 30 Mar 2012) Log Message: ----------- Avoid code duplication between xetex and latex2e writer (solves [ 3512728 ]). Modified Paths: -------------- trunk/docutils/HISTORY.txt trunk/docutils/docutils/writers/latex2e/__init__.py trunk/docutils/docutils/writers/xetex/__init__.py trunk/docutils/test/functional/expected/standalone_rst_xetex.tex Modified: trunk/docutils/HISTORY.txt =================================================================== --- trunk/docutils/HISTORY.txt 2012-03-30 07:11:39 UTC (rev 7388) +++ trunk/docutils/HISTORY.txt 2012-03-30 11:58:21 UTC (rev 7389) @@ -40,12 +40,12 @@ BinaryFileOutput. - New exceptions InputError and OutputError for IO errors in FileInput/FileOutput. - + * docutils/core.py: - No "hard" system exit on file IO errors: catch and report them in `Publisher.reportException` instead. Allows handling by a calling - application if the configuration setting `traceback` is True. + application if the configuration setting `traceback` is True. * docutils/utils.py -> docutils/utils/__init__.py @@ -84,6 +84,10 @@ - Use ``\DUtitle`` for unsupported section levels - Apply [ 3512791 ] do not compare string literals with "is" +* docutils/writers/xetex/__init__.py + + - Avoid code duplication with latex2e writer (solves [ 3512728 ]). + * docutils/writers/html4css1/__init__.py - Change default for `math-output` setting to MathJax. Modified: trunk/docutils/docutils/writers/latex2e/__init__.py =================================================================== --- trunk/docutils/docutils/writers/latex2e/__init__.py 2012-03-30 07:11:39 UTC (rev 7388) +++ trunk/docutils/docutils/writers/latex2e/__init__.py 2012-03-30 11:58:21 UTC (rev 7389) @@ -680,6 +680,161 @@ }""" +# LaTeX encoding maps +# ------------------- +# :: + +class CharMaps(object): + """LaTeX representations for active and Unicode characters.""" + + # characters that always need escaping: + special = { + ord('#'): ur'\#', + ord('$'): ur'\$', + ord('%'): ur'\%', + ord('&'): ur'\&', + ord('~'): ur'\textasciitilde{}', + ord('_'): ur'\_', + ord('^'): ur'\textasciicircum{}', + ord('\\'): ur'\textbackslash{}', + ord('{'): ur'\{', + ord('}'): ur'\}', + # Square brackets are ordinary chars and cannot be escaped with '\', + # so we put them in a group '{[}'. (Alternative: ensure that all + # macros with optional arguments are terminated with {} and text + # inside any optional argument is put in a group ``[{text}]``). + # Commands with optional args inside an optional arg must be put in a + # group, e.g. ``\item[{\hyperref[label]{text}}]``. + ord('['): ur'{[}', + ord(']'): ur'{]}', + # the soft hyphen is unknown in 8-bit text and not properly handled by XeTeX + 0x00AD: ur'\-', # SOFT HYPHEN + } + # Unicode chars that are not recognized by LaTeX's utf8 encoding + unsupported_unicode = { + 0x00A0: ur'~', # NO-BREAK SPACE + # TODO: ensure white space also at the beginning of a line? + # 0x00A0: ur'\leavevmode\nobreak\vadjust{}~' + 0x2008: ur'\,', # PUNCTUATION SPACE + 0x2011: ur'\hbox{-}', # NON-BREAKING HYPHEN + 0x202F: ur'\,', # NARROW NO-BREAK SPACE + 0x21d4: ur'$\Leftrightarrow$', + # Docutils footnote symbols: + 0x2660: ur'$\spadesuit$', + 0x2663: ur'$\clubsuit$', + } + # Unicode chars that are recognized by LaTeX's utf8 encoding + utf8_supported_unicode = { + 0x200C: ur'\textcompwordmark', # ZERO WIDTH NON-JOINER + 0x2013: ur'\textendash{}', + 0x2014: ur'\textemdash{}', + 0x2018: ur'\textquoteleft{}', + 0x2019: ur'\textquoteright{}', + 0x201A: ur'\quotesinglbase{}', # SINGLE LOW-9 QUOTATION MARK + 0x201C: ur'\textquotedblleft{}', + 0x201D: ur'\textquotedblright{}', + 0x201E: ur'\quotedblbase{}', # DOUBLE LOW-9 QUOTATION MARK + 0x2030: ur'\textperthousand{}', # PER MILLE SIGN + 0x2031: ur'\textpertenthousand{}', # PER TEN THOUSAND SIGN + 0x2039: ur'\guilsinglleft{}', + 0x203A: ur'\guilsinglright{}', + 0x2423: ur'\textvisiblespace{}', # OPEN BOX + 0x2020: ur'\dag{}', + 0x2021: ur'\ddag{}', + 0x2026: ur'\dots{}', + 0x2122: ur'\texttrademark{}', + } + # recognized with 'utf8', if textcomp is loaded + textcomp = { + # Latin-1 Supplement + 0x00a2: ur'\textcent{}', # ¢ CENT SIGN + 0x00a4: ur'\textcurrency{}', # ¤ CURRENCY SYMBOL + 0x00a5: ur'\textyen{}', # ¥ YEN SIGN + 0x00a6: ur'\textbrokenbar{}', # ¦ BROKEN BAR + 0x00a7: ur'\textsection{}', # § SECTION SIGN + 0x00a8: ur'\textasciidieresis{}', # ¨ DIAERESIS + 0x00a9: ur'\textcopyright{}', # © COPYRIGHT SIGN + 0x00aa: ur'\textordfeminine{}', # ª FEMININE ORDINAL INDICATOR + 0x00ac: ur'\textlnot{}', # ¬ NOT SIGN + 0x00ae: ur'\textregistered{}', # ® REGISTERED SIGN + 0x00af: ur'\textasciimacron{}', # ¯ MACRON + 0x00b0: ur'\textdegree{}', # ° DEGREE SIGN + 0x00b1: ur'\textpm{}', # ± PLUS-MINUS SIGN + 0x00b2: ur'\texttwosuperior{}', # ² SUPERSCRIPT TWO + 0x00b3: ur'\textthreesuperior{}', # ³ SUPERSCRIPT THREE + 0x00b4: ur'\textasciiacute{}', # ´ ACUTE ACCENT + 0x00b5: ur'\textmu{}', # µ MICRO SIGN + 0x00b6: ur'\textparagraph{}', # ¶ PILCROW SIGN # not equal to \textpilcrow + 0x00b9: ur'\textonesuperior{}', # ¹ SUPERSCRIPT ONE + 0x00ba: ur'\textordmasculine{}', # º MASCULINE ORDINAL INDICATOR + 0x00bc: ur'\textonequarter{}', # 1/4 FRACTION + 0x00bd: ur'\textonehalf{}', # 1/2 FRACTION + 0x00be: ur'\textthreequarters{}', # 3/4 FRACTION + 0x00d7: ur'\texttimes{}', # × MULTIPLICATION SIGN + 0x00f7: ur'\textdiv{}', # ÷ DIVISION SIGN + # + 0x0192: ur'\textflorin{}', # LATIN SMALL LETTER F WITH HOOK + 0x02b9: ur'\textasciiacute{}', # MODIFIER LETTER PRIME + 0x02ba: ur'\textacutedbl{}', # MODIFIER LETTER DOUBLE PRIME + 0x2016: ur'\textbardbl{}', # DOUBLE VERTICAL LINE + 0x2022: ur'\textbullet{}', # BULLET + 0x2032: ur'\textasciiacute{}', # PRIME + 0x2033: ur'\textacutedbl{}', # DOUBLE PRIME + 0x2035: ur'\textasciigrave{}', # REVERSED PRIME + 0x2036: ur'\textgravedbl{}', # REVERSED DOUBLE PRIME + 0x203b: ur'\textreferencemark{}', # REFERENCE MARK + 0x203d: ur'\textinterrobang{}', # INTERROBANG + 0x2044: ur'\textfractionsolidus{}', # FRACTION SLASH + 0x2045: ur'\textlquill{}', # LEFT SQUARE BRACKET WITH QUILL + 0x2046: ur'\textrquill{}', # RIGHT SQUARE BRACKET WITH QUILL + 0x2052: ur'\textdiscount{}', # COMMERCIAL MINUS SIGN + 0x20a1: ur'\textcolonmonetary{}', # COLON SIGN + 0x20a3: ur'\textfrenchfranc{}', # FRENCH FRANC SIGN + 0x20a4: ur'\textlira{}', # LIRA SIGN + 0x20a6: ur'\textnaira{}', # NAIRA SIGN + 0x20a9: ur'\textwon{}', # WON SIGN + 0x20ab: ur'\textdong{}', # DONG SIGN + 0x20ac: ur'\texteuro{}', # EURO SIGN + 0x20b1: ur'\textpeso{}', # PESO SIGN + 0x20b2: ur'\textguarani{}', # GUARANI SIGN + 0x2103: ur'\textcelsius{}', # DEGREE CELSIUS + 0x2116: ur'\textnumero{}', # NUMERO SIGN + 0x2117: ur'\textcircledP{}', # SOUND RECORDING COYRIGHT + 0x211e: ur'\textrecipe{}', # PRESCRIPTION TAKE + 0x2120: ur'\textservicemark{}', # SERVICE MARK + 0x2122: ur'\texttrademark{}', # TRADE MARK SIGN + 0x2126: ur'\textohm{}', # OHM SIGN + 0x2127: ur'\textmho{}', # INVERTED OHM SIGN + 0x212e: ur'\textestimated{}', # ESTIMATED SYMBOL + 0x2190: ur'\textleftarrow{}', # LEFTWARDS ARROW + 0x2191: ur'\textuparrow{}', # UPWARDS ARROW + 0x2192: ur'\textrightarrow{}', # RIGHTWARDS ARROW + 0x2193: ur'\textdownarrow{}', # DOWNWARDS ARROW + 0x2212: ur'\textminus{}', # MINUS SIGN + 0x2217: ur'\textasteriskcentered{}', # ASTERISK OPERATOR + 0x221a: ur'\textsurd{}', # SQUARE ROOT + 0x2422: ur'\textblank{}', # BLANK SYMBOL + 0x25e6: ur'\textopenbullet{}', # WHITE BULLET + 0x25ef: ur'\textbigcircle{}', # LARGE CIRCLE + 0x266a: ur'\textmusicalnote{}', # EIGHTH NOTE + 0x26ad: ur'\textmarried{}', # MARRIAGE SYMBOL + 0x26ae: ur'\textdivorced{}', # DIVORCE SYMBOL + 0x27e8: ur'\textlangle{}', # MATHEMATICAL LEFT ANGLE BRACKET + 0x27e9: ur'\textrangle{}', # MATHEMATICAL RIGHT ANGLE BRACKET + } + # Unicode chars that require a feature/package to render + pifont = { + 0x2665: ur'\ding{170}', # black heartsuit + 0x2666: ur'\ding{169}', # black diamondsuit + 0x2713: ur'\ding{51}', # check mark + 0x2717: ur'\ding{55}', # check mark + } + # TODO: greek alphabet ... ? + # see also LaTeX codec + # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252124 + # and unimap.py from TeXML + + class DocumentClass(object): """Details of a LaTeX document class.""" @@ -923,6 +1078,10 @@ # to other packages, as done with babel. # Dummy settings might be taken from document settings + # Write code for typesetting with 8-bit tex/pdftex (vs. xetex/luatex) engine + # overwritten by the XeTeX writer + is_xetex = False + # Config setting defaults # ----------------------- @@ -1097,7 +1256,7 @@ self.requirements['_inputenc'] = (r'\usepackage[%s]{inputenc}' % self.latex_encoding) # TeX font encoding - if self.font_encoding: + if self.font_encoding and not self.is_xetex: self.requirements['_fontenc'] = (r'\usepackage[%s]{fontenc}' % self.font_encoding) # page layout with typearea (if there are relevant document options) @@ -1239,7 +1398,7 @@ encoding = docutils_encoding.lower() if encoding in tr: return tr[encoding] - # convert: latin-1, latin_1, utf-8 and similar things + # drop hyphen or low-line from "latin-1", "latin_1", "utf-8" and similar encoding = encoding.replace('_', '').replace('-', '') # strip the error handler return encoding.split(':')[0] @@ -1247,188 +1406,24 @@ def language_label(self, docutil_label): return self.language_module.labels[docutil_label] - def ensure_math(self, text): - if not hasattr(self, 'ensure_math_re'): - chars = { # lnot,pm,twosuperior,threesuperior,mu,onesuperior,times,div - 'latin1' : '\xac\xb1\xb2\xb3\xb5\xb9\xd7\xf7' , # ¬±²³µ¹×÷ - # TODO?: use texcomp instead. - } - self.ensure_math_re = re.compile('([%s])' % chars['latin1']) - text = self.ensure_math_re.sub(r'\\ensuremath{\1}', text) - return text - def encode(self, text): """Return text with 'problematic' characters escaped. - Escape the ten special printing characters ``# $ % & ~ _ ^ \ { }``, - square brackets ``[ ]``, double quotes and (in OT1) ``< | >``. - - Separate ``-`` (and more in literal text) to prevent input ligatures. - - Translate non-supported Unicode characters. + * Escape the ten special printing characters ``# $ % & ~ _ ^ \ { }``, + square brackets ``[ ]``, double quotes and (in OT1) ``< | >``. + * Translate non-supported Unicode characters. + * Separate ``-`` (and more in literal text) to prevent input ligatures. """ if self.verbatim: return text - # Separate compound characters, e.g. '--' to '-{}-'. - separate_chars = '-' - # In monospace-font, we also separate ',,', '``' and "''" and some - # other characters which can't occur in non-literal text. - if self.literal: - separate_chars += ',`\'"<>' - # LaTeX encoding maps: - special_chars = { - ord('#'): ur'\#', - ord('$'): ur'\$', - ord('%'): ur'\%', - ord('&'): ur'\&', - ord('~'): ur'\textasciitilde{}', - ord('_'): ur'\_', - ord('^'): ur'\textasciicircum{}', - ord('\\'): ur'\textbackslash{}', - ord('{'): ur'\{', - ord('}'): ur'\}', - # Square brackets are ordinary chars and cannot be escaped with '\', - # so we put them in a group '{[}'. (Alternative: ensure that all - # macros with optional arguments are terminated with {} and text - # inside any optional argument is put in a group ``[{text}]``). - # Commands with optional args inside an optional arg must be put - # in a group, e.g. ``\item[{\hyperref[label]{text}}]``. - ord('['): ur'{[}', - ord(']'): ur'{]}' - } - # Unicode chars that are not recognized by LaTeX's utf8 encoding - unsupported_unicode_chars = { - 0x00A0: ur'~', # NO-BREAK SPACE - # TODO: ensure white space also at the beginning of a line? - # 0x00A0: ur'\leavevmode\nobreak\vadjust{}~' - 0x00AD: ur'\-', # SOFT HYPHEN - # - 0x2008: ur'\,', # PUNCTUATION SPACE - 0x2011: ur'\hbox{-}', # NON-BREAKING HYPHEN - 0x202F: ur'\,', # NARROW NO-BREAK SPACE - 0x21d4: ur'$\Leftrightarrow$', - # Docutils footnote symbols: - 0x2660: ur'$\spadesuit$', - 0x2663: ur'$\clubsuit$', - } - # Unicode chars that are recognized by LaTeX's utf8 encoding - unicode_chars = { - 0x200C: ur'\textcompwordmark', # ZERO WIDTH NON-JOINER - 0x2013: ur'\textendash{}', - 0x2014: ur'\textemdash{}', - 0x2018: ur'\textquoteleft{}', - 0x2019: ur'\textquoteright{}', - 0x201A: ur'\quotesinglbase{}', # SINGLE LOW-9 QUOTATION MARK - 0x201C: ur'\textquotedblleft{}', - 0x201D: ur'\textquotedblright{}', - 0x201E: ur'\quotedblbase{}', # DOUBLE LOW-9 QUOTATION MARK - 0x2030: ur'\textperthousand{}', # PER MILLE SIGN - 0x2031: ur'\textpertenthousand{}', # PER TEN THOUSAND SIGN - 0x2039: ur'\guilsinglleft{}', - 0x203A: ur'\guilsinglright{}', - 0x2423: ur'\textvisiblespace{}', # OPEN BOX - 0x2020: ur'\dag{}', - 0x2021: ur'\ddag{}', - 0x2026: ur'\dots{}', - 0x2122: ur'\texttrademark{}', - } - # Unicode chars that require a feature/package to render - pifont_chars = { - 0x2665: ur'\ding{170}', # black heartsuit - 0x2666: ur'\ding{169}', # black diamondsuit - 0x2713: ur'\ding{51}', # check mark - 0x2717: ur'\ding{55}', # check mark - } - # recognized with 'utf8', if textcomp is loaded - textcomp_chars = { - # Latin-1 Supplement - 0x00a2: ur'\textcent{}', # ¢ CENT SIGN - 0x00a4: ur'\textcurrency{}', # ¤ CURRENCY SYMBOL - 0x00a5: ur'\textyen{}', # ¥ YEN SIGN - 0x00a6: ur'\textbrokenbar{}', # ¦ BROKEN BAR - 0x00a7: ur'\textsection{}', # § SECTION SIGN - 0x00a8: ur'\textasciidieresis{}', # ¨ DIAERESIS - 0x00a9: ur'\textcopyright{}', # © COPYRIGHT SIGN - 0x00aa: ur'\textordfeminine{}', # ª FEMININE ORDINAL INDICATOR - 0x00ac: ur'\textlnot{}', # ¬ NOT SIGN - 0x00ae: ur'\textregistered{}', # ® REGISTERED SIGN - 0x00af: ur'\textasciimacron{}', # ¯ MACRON - 0x00b0: ur'\textdegree{}', # ° DEGREE SIGN - 0x00b1: ur'\textpm{}', # ± PLUS-MINUS SIGN - 0x00b2: ur'\texttwosuperior{}', # ² SUPERSCRIPT TWO - 0x00b3: ur'\textthreesuperior{}', # ³ SUPERSCRIPT THREE - 0x00b4: ur'\textasciiacute{}', # ´ ACUTE ACCENT - 0x00b5: ur'\textmu{}', # µ MICRO SIGN - 0x00b6: ur'\textparagraph{}', # ¶ PILCROW SIGN # not equal to \textpilcrow - 0x00b9: ur'\textonesuperior{}', # ¹ SUPERSCRIPT ONE - 0x00ba: ur'\textordmasculine{}', # º MASCULINE ORDINAL INDICATOR - 0x00bc: ur'\textonequarter{}', # 1/4 FRACTION - 0x00bd: ur'\textonehalf{}', # 1/2 FRACTION - 0x00be: ur'\textthreequarters{}', # 3/4 FRACTION - 0x00d7: ur'\texttimes{}', # × MULTIPLICATION SIGN - 0x00f7: ur'\textdiv{}', # ÷ DIVISION SIGN - # - 0x0192: ur'\textflorin{}', # LATIN SMALL LETTER F WITH HOOK - 0x02b9: ur'\textasciiacute{}', # MODIFIER LETTER PRIME - 0x02ba: ur'\textacutedbl{}', # MODIFIER LETTER DOUBLE PRIME - 0x2016: ur'\textbardbl{}', # DOUBLE VERTICAL LINE - 0x2022: ur'\textbullet{}', # BULLET - 0x2032: ur'\textasciiacute{}', # PRIME - 0x2033: ur'\textacutedbl{}', # DOUBLE PRIME - 0x2035: ur'\textasciigrave{}', # REVERSED PRIME - 0x2036: ur'\textgravedbl{}', # REVERSED DOUBLE PRIME - 0x203b: ur'\textreferencemark{}', # REFERENCE MARK - 0x203d: ur'\textinterrobang{}', # INTERROBANG - 0x2044: ur'\textfractionsolidus{}', # FRACTION SLASH - 0x2045: ur'\textlquill{}', # LEFT SQUARE BRACKET WITH QUILL - 0x2046: ur'\textrquill{}', # RIGHT SQUARE BRACKET WITH QUILL - 0x2052: ur'\textdiscount{}', # COMMERCIAL MINUS SIGN - 0x20a1: ur'\textcolonmonetary{}', # COLON SIGN - 0x20a3: ur'\textfrenchfranc{}', # FRENCH FRANC SIGN - 0x20a4: ur'\textlira{}', # LIRA SIGN - 0x20a6: ur'\textnaira{}', # NAIRA SIGN - 0x20a9: ur'\textwon{}', # WON SIGN - 0x20ab: ur'\textdong{}', # DONG SIGN - 0x20ac: ur'\texteuro{}', # EURO SIGN - 0x20b1: ur'\textpeso{}', # PESO SIGN - 0x20b2: ur'\textguarani{}', # GUARANI SIGN - 0x2103: ur'\textcelsius{}', # DEGREE CELSIUS - 0x2116: ur'\textnumero{}', # NUMERO SIGN - 0x2117: ur'\textcircledP{}', # SOUND RECORDING COYRIGHT - 0x211e: ur'\textrecipe{}', # PRESCRIPTION TAKE - 0x2120: ur'\textservicemark{}', # SERVICE MARK - 0x2122: ur'\texttrademark{}', # TRADE MARK SIGN - 0x2126: ur'\textohm{}', # OHM SIGN - 0x2127: ur'\textmho{}', # INVERTED OHM SIGN - 0x212e: ur'\textestimated{}', # ESTIMATED SYMBOL - 0x2190: ur'\textleftarrow{}', # LEFTWARDS ARROW - 0x2191: ur'\textuparrow{}', # UPWARDS ARROW - 0x2192: ur'\textrightarrow{}', # RIGHTWARDS ARROW - 0x2193: ur'\textdownarrow{}', # DOWNWARDS ARROW - 0x2212: ur'\textminus{}', # MINUS SIGN - 0x2217: ur'\textasteriskcentered{}', # ASTERISK OPERATOR - 0x221a: ur'\textsurd{}', # SQUARE ROOT - 0x2422: ur'\textblank{}', # BLANK SYMBOL - 0x25e6: ur'\textopenbullet{}', # WHITE BULLET - 0x25ef: ur'\textbigcircle{}', # LARGE CIRCLE - 0x266a: ur'\textmusicalnote{}', # EIGHTH NOTE - 0x26ad: ur'\textmarried{}', # MARRIAGE SYMBOL - 0x26ae: ur'\textdivorced{}', # DIVORCE SYMBOL - 0x27e8: ur'\textlangle{}', # MATHEMATICAL LEFT ANGLE BRACKET - 0x27e9: ur'\textrangle{}', # MATHEMATICAL RIGHT ANGLE BRACKET - } - # TODO: greek alphabet ... ? - # see also LaTeX codec - # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252124 - # and unimap.py from TeXML - # set up the translation table: - table = special_chars + # Set up the translation table: + table = CharMaps.special.copy() # keep the underscore in citation references if self.inside_citation_reference_label: del(table[ord('_')]) # Workarounds for OT1 font-encoding - if self.font_encoding in ['OT1', '']: + if self.font_encoding in ['OT1', ''] and not self.is_xetex: # * out-of-order characters in cmtt if self.literal: # replace underscore by underlined blank, @@ -1449,41 +1444,47 @@ # double quotes are 'active' in some languages # TODO: use \textquotedbl if font encoding starts with T? table[ord('"')] = self.babel.literal_double_quote - # Unicode chars: - table.update(unsupported_unicode_chars) - table.update(pifont_chars) - if not self.latex_encoding.startswith('utf8'): - table.update(unicode_chars) - table.update(textcomp_chars) - # Characters that require a feature/package to render - for ch in text: - if ord(ch) in pifont_chars: - self.requirements['pifont'] = '\\usepackage{pifont}' - if ord(ch) in textcomp_chars: + # Unicode replacements for 8-bit tex engines (not required with XeTeX/LuaTeX): + if not self.is_xetex: + table.update(CharMaps.unsupported_unicode) + if not self.latex_encoding.startswith('utf8'): + table.update(CharMaps.utf8_supported_unicode) + table.update(CharMaps.textcomp) + table.update(CharMaps.pifont) + # Characters that require a feature/package to render + if [True for ch in text if ord(ch) in CharMaps.textcomp]: self.requirements['textcomp'] = PreambleCmds.textcomp + if [True for ch in text if ord(ch) in CharMaps.pifont]: + self.requirements['pifont'] = '\\usepackage{pifont}' text = text.translate(table) - # Break up input ligatures - for char in separate_chars * 2: - # Do it twice ("* 2") because otherwise we would replace - # '---' by '-{}--'. - text = text.replace(char + char, char + '{}' + char) + # Break up input ligatures e.g. '--' to '-{}-'. + if not self.is_xetex: # Not required with xetex/luatex + separate_chars = '-' + # In monospace-font, we also separate ',,', '``' and "''" and some + # other characters which can't occur in non-literal text. + if self.literal: + separate_chars += ',`\'"<>' + for char in separate_chars * 2: + # Do it twice ("* 2") because otherwise we would replace + # '---' by '-{}--'. + text = text.replace(char + char, char + '{}' + char) + # Literal line breaks (in address or literal blocks): if self.insert_newline: lines = text.split('\n') - # for blank lines, insert a protected space, to avoid - # ! LaTeX Error: There's no line here to end. - lines = [line + '~'*(not line.lstrip()) - for line in lines[:-1]] + lines[-1:] - text = '\\\\\n'.join(lines) + # Add a protected space to blank lines (except the last) + # to avoid ``! LaTeX Error: There's no line here to end.`` + for i, line in enumerate(lines[:-1]): + if not line.lstrip(): + lines[i] += '~' + text = (r'\\' + '\n').join(lines) if not self.literal: text = self.babel.quote_quotes(text) if self.literal and not self.insert_non_breaking_blanks: # preserve runs of spaces but allow wrapping text = text.replace(' ', ' ~') - if not self.latex_encoding.startswith('utf8'): - text = self.ensure_math(text) return text def attval(self, text, @@ -2218,9 +2219,12 @@ self.requirements['~header'] = ''.join(self.out) self.pop_output_collector() - def to_latex_length(self, length_str, pxunit='px'): + def to_latex_length(self, length_str, pxunit=None): """Convert `length_str` with rst lenght to LaTeX length """ + if pxunit is not None: + sys.stderr.write('deprecation warning: LaTeXTranslator.to_latex_length()' + ' option `pxunit` will be removed.') match = re.match('(\d*\.?\d*)\s*(\S*)', length_str) if not match: return length_str @@ -2231,12 +2235,13 @@ # percentage: relate to current line width elif unit == '%': length_str = '%.3f\\linewidth' % (float(value)/100.0) - elif (unit == 'px') and (pxunit != 'px'): - # length unit px not defined in some tex variants (e.g. XeTeX) + elif self.is_xetex and unit == 'px': + # XeTeX does not know the length unit px. + # Use \pdfpxdimen, the macro to set the value of 1 px in pdftex. + # This way, configuring works the same for pdftex and xetex. self.fallbacks['_providelength'] = PreambleCmds.providelength - self.fallbacks['px'] = '\n\\DUprovidelength{%s}{1bp}\n' % pxunit - length_str = '%s%s' % (value, pxunit) - + self.fallbacks['px'] = '\n\\DUprovidelength{\\pdfpxdimen}{1bp}\n' + length_str = r'%s\pdfpxdimen' % value return length_str def visit_image(self, node): Modified: trunk/docutils/docutils/writers/xetex/__init__.py =================================================================== --- trunk/docutils/docutils/writers/xetex/__init__.py 2012-03-30 07:11:39 UTC (rev 7388) +++ trunk/docutils/docutils/writers/xetex/__init__.py 2012-03-30 11:58:21 UTC (rev 7389) @@ -61,7 +61,7 @@ def __init__(self): latex2e.Writer.__init__(self) - self.settings_defaults.update({'fontencoding': ''}) # use default (EU1) + self.settings_defaults.update({'fontencoding': ''}) # use default (EU1 or EU2) self.translator_class = XeLaTeXTranslator @@ -125,79 +125,10 @@ class XeLaTeXTranslator(latex2e.LaTeXTranslator): def __init__(self, document): + self.is_xetex = True # typeset with XeTeX or LuaTeX engine latex2e.LaTeXTranslator.__init__(self, document, Babel) if self.latex_encoding == 'utf8': self.requirements.pop('_inputenc', None) else: self.requirements['_inputenc'] = (r'\XeTeXinputencoding %s ' % self.latex_encoding) - - # XeTeX does not know the length unit px. - # Use \pdfpxdimen, the macro to set the value of 1 px in pdftex. - # This way, configuring works the same for pdftex and xetex. - def to_latex_length(self, length_str, px=r'\pdfpxdimen'): - """Convert string with rst lenght to LaTeX length""" - return latex2e.LaTeXTranslator.to_latex_length(self, length_str, px) - - # Simpler variant of encode, as XeTeX understands utf8 Unicode: - def encode(self, text): - """Return text with 'problematic' characters escaped. - - Escape the ten special printing characters ``# $ % & ~ _ ^ \ { }``, - square brackets ``[ ]``, double quotes and (in OT1) ``< | >``. - """ - if self.verbatim: - return text - # LaTeX encoding maps: - special_chars = { - ord('#'): ur'\#', - ord('$'): ur'\$', - ord('%'): ur'\%', - ord('&'): ur'\&', - ord('~'): ur'\textasciitilde{}', - ord('_'): ur'\_', - ord('^'): ur'\textasciicircum{}', - ord('\\'): ur'\textbackslash{}', - ord('{'): ur'\{', - ord('}'): ur'\}', - # Square brackets are ordinary chars and cannot be escaped with '\', - # so we put them in a group '{[}'. (Alternative: ensure that all - # macros with optional arguments are terminated with {} and text - # inside any optional argument is put in a group ``[{text}]``). - # Commands with optional args inside an optional arg must be put - # in a group, e.g. ``\item[{\hyperref[label]{text}}]``. - ord('['): ur'{[}', - ord(']'): ur'{]}' - } - # Unicode chars that are not properly handled by XeTeX - unsupported_unicode_chars = { - 0x00AD: ur'\-', # SOFT HYPHEN - } - # set up the translation table: - table = special_chars - # keep the underscore in citation references - if self.inside_citation_reference_label: - del(table[ord('_')]) - if self.insert_non_breaking_blanks: - table[ord(' ')] = ur'~' - if self.literal: - # double quotes are 'active' in some languages - table[ord('"')] = self.babel.literal_double_quote - else: - text = self.babel.quote_quotes(text) - # Unicode chars: - table.update(unsupported_unicode_chars) - - text = text.translate(table) - - # Literal line breaks (in address or literal blocks): - if self.insert_newline: - # for blank lines, insert a protected space, to avoid - # ! LaTeX Error: There's no line here to end. - textlines = [line + '~'*(not line.lstrip()) - for line in text.split('\n')] - text = '\\\\\n'.join(textlines) - if self.literal and not self.insert_non_breaking_blanks: - # preserve runs of spaces but allow wrapping - text = text.replace(' ', ' ~') - return text Modified: trunk/docutils/test/functional/expected/standalone_rst_xetex.tex =================================================================== --- trunk/docutils/test/functional/expected/standalone_rst_xetex.tex 2012-03-30 07:11:39 UTC (rev 7388) +++ trunk/docutils/test/functional/expected/standalone_rst_xetex.tex 2012-03-30 11:58:21 UTC (rev 7389) @@ -1269,8 +1269,8 @@ % \begin{quote}{\ttfamily \raggedright \noindent \DUrole{ln}{~8~}\#~print~integers~from~0~to~9:\\ -~\DUrole{ln}{~9~}for~i~in~range(10):\\ -~\DUrole{ln}{10~}~~~~print~i +\DUrole{ln}{~9~}for~i~in~range(10):\\ +\DUrole{ln}{10~}~~~~print~i } \end{quote} @@ -1292,7 +1292,7 @@ % \begin{quote}{\ttfamily \raggedright \noindent \DUrole{ln}{1~}..~header::~Document~header\\ -~\DUrole{ln}{2~}..~footer::~Document~footer +\DUrole{ln}{2~}..~footer::~Document~footer } \end{quote} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gr...@us...> - 2012-05-02 17:13:50
|
Revision: 7410 http://docutils.svn.sourceforge.net/docutils/?rev=7410&view=rev Author: grubert Date: 2012-05-02 17:13:41 +0000 (Wed, 02 May 2012) Log Message: ----------- Release 0.9: closed "Changes Since ..." section Modified Paths: -------------- trunk/docutils/HISTORY.txt trunk/docutils/RELEASE-NOTES.txt Modified: trunk/docutils/HISTORY.txt =================================================================== --- trunk/docutils/HISTORY.txt 2012-05-02 17:06:37 UTC (rev 7409) +++ trunk/docutils/HISTORY.txt 2012-05-02 17:13:41 UTC (rev 7410) @@ -13,8 +13,8 @@ .. contents:: -Changes Since 0.8.1 -=================== +Release 0.9 (2012-05-02) +======================== * General: Modified: trunk/docutils/RELEASE-NOTES.txt =================================================================== --- trunk/docutils/RELEASE-NOTES.txt 2012-05-02 17:06:37 UTC (rev 7409) +++ trunk/docutils/RELEASE-NOTES.txt 2012-05-02 17:13:41 UTC (rev 7410) @@ -42,7 +42,7 @@ :0.13: remove the `handle_io_errors` option. -Release 0.9 (unpublished) +Release 0.9 (2012-05-02) ========================= * General: @@ -53,6 +53,16 @@ .. _Pygments: http://pygments.org/ + - Fix [ 3402314 ] allow non-ASCII whitespace, punctuation + characters and "international" quotes around inline markup. + + - Fix handling of missing stylesheets. + +* setup.py + + - Fix [ 2971827 ] and [ 3442827 ] + extras/roman.py moved to docutils/utils/roman.py + * docutils/utils.py -> docutils/utils/__init__.py - docutils.utils is now a package (providing a place for sub-modules) @@ -63,7 +73,10 @@ * docutils/writers/latex2e/__init__.py + - Support the `abbreviation` and `acronym` standard roles. - Record only files required to generate the LaTeX source as dependencies. + - Use ``\setcounter{secnumdepth}{0}`` instead of ``*``-versions + when suppressing LaTeX section numbering. Release 0.8.1 (2011-08-30) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gr...@us...> - 2012-05-02 19:19:47
|
Revision: 7417 http://docutils.svn.sourceforge.net/docutils/?rev=7417&view=rev Author: grubert Date: 2012-05-02 19:19:41 +0000 (Wed, 02 May 2012) Log Message: ----------- Release 0.9: added empty "Changes Since 0.9" section Modified Paths: -------------- trunk/docutils/HISTORY.txt trunk/docutils/RELEASE-NOTES.txt Modified: trunk/docutils/HISTORY.txt =================================================================== --- trunk/docutils/HISTORY.txt 2012-05-02 19:19:12 UTC (rev 7416) +++ trunk/docutils/HISTORY.txt 2012-05-02 19:19:41 UTC (rev 7417) @@ -13,6 +13,10 @@ .. contents:: +Changes Since 0.9 +================= + + Release 0.9 (2012-05-02) ======================== Modified: trunk/docutils/RELEASE-NOTES.txt =================================================================== --- trunk/docutils/RELEASE-NOTES.txt 2012-05-02 19:19:12 UTC (rev 7416) +++ trunk/docutils/RELEASE-NOTES.txt 2012-05-02 19:19:41 UTC (rev 7417) @@ -42,6 +42,10 @@ :0.13: remove the `handle_io_errors` option. +Changes Since 0.9 +================= + + Release 0.9 (2012-05-02) ========================= This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gr...@us...> - 2012-05-02 19:24:00
|
Revision: 7418 http://docutils.svn.sourceforge.net/docutils/?rev=7418&view=rev Author: grubert Date: 2012-05-02 19:23:53 +0000 (Wed, 02 May 2012) Log Message: ----------- Release 0.9: set version number to 0.10 Modified Paths: -------------- trunk/docutils/docutils/__init__.py trunk/docutils/setup.py trunk/docutils/test/functional/expected/compact_lists.html trunk/docutils/test/functional/expected/dangerous.html trunk/docutils/test/functional/expected/field_name_limit.html trunk/docutils/test/functional/expected/math_output_html.html trunk/docutils/test/functional/expected/math_output_latex.html trunk/docutils/test/functional/expected/math_output_mathjax.html trunk/docutils/test/functional/expected/math_output_mathml.xhtml trunk/docutils/test/functional/expected/misc_rst_html4css1.html trunk/docutils/test/functional/expected/pep_html.html trunk/docutils/test/functional/expected/standalone_rst_html4css1.html trunk/docutils/test/functional/expected/standalone_rst_s5_html_1.html trunk/docutils/test/functional/expected/standalone_rst_s5_html_2.html trunk/docutils/test/functional/expected/stylesheet_path_html4css1.html Modified: trunk/docutils/docutils/__init__.py =================================================================== --- trunk/docutils/docutils/__init__.py 2012-05-02 19:19:41 UTC (rev 7417) +++ trunk/docutils/docutils/__init__.py 2012-05-02 19:23:53 UTC (rev 7418) @@ -49,7 +49,7 @@ __docformat__ = 'reStructuredText' -__version__ = '0.9' +__version__ = '0.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 Modified: trunk/docutils/setup.py =================================================================== --- trunk/docutils/setup.py 2012-05-02 19:19:41 UTC (rev 7417) +++ trunk/docutils/setup.py 2012-05-02 19:23:53 UTC (rev 7418) @@ -115,7 +115,7 @@ input Docutils supports reStructuredText, an easy-to-read, what-you-see-is-what-you-get plaintext markup syntax.""", # wrap at col 60 'url': 'http://docutils.sourceforge.net/', - 'version': '0.9', + 'version': '0.10', 'author': 'David Goodger', 'author_email': 'go...@py...', 'license': 'public domain, Python, 2-Clause BSD, GPL 3 (see COPYING.txt)', Modified: trunk/docutils/test/functional/expected/compact_lists.html =================================================================== --- trunk/docutils/test/functional/expected/compact_lists.html 2012-05-02 19:19:41 UTC (rev 7417) +++ trunk/docutils/test/functional/expected/compact_lists.html 2012-05-02 19:23:53 UTC (rev 7418) @@ -3,7 +3,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="generator" content="Docutils 0.9: http://docutils.sourceforge.net/" /> +<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" /> <title></title> <link rel="stylesheet" href="../../../docutils/writers/html4css1/html4css1.css" type="text/css" /> </head> Modified: trunk/docutils/test/functional/expected/dangerous.html =================================================================== --- trunk/docutils/test/functional/expected/dangerous.html 2012-05-02 19:19:41 UTC (rev 7417) +++ trunk/docutils/test/functional/expected/dangerous.html 2012-05-02 19:23:53 UTC (rev 7418) @@ -3,7 +3,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="generator" content="Docutils 0.9: http://docutils.sourceforge.net/" /> +<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" /> <title></title> <link rel="stylesheet" href="../../../docutils/writers/html4css1/html4css1.css" type="text/css" /> </head> Modified: trunk/docutils/test/functional/expected/field_name_limit.html =================================================================== --- trunk/docutils/test/functional/expected/field_name_limit.html 2012-05-02 19:19:41 UTC (rev 7417) +++ trunk/docutils/test/functional/expected/field_name_limit.html 2012-05-02 19:23:53 UTC (rev 7418) @@ -3,7 +3,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="generator" content="Docutils 0.9: http://docutils.sourceforge.net/" /> +<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" /> <title></title> <link rel="stylesheet" href="../../../docutils/writers/html4css1/html4css1.css" type="text/css" /> </head> Modified: trunk/docutils/test/functional/expected/math_output_html.html =================================================================== --- trunk/docutils/test/functional/expected/math_output_html.html 2012-05-02 19:19:41 UTC (rev 7417) +++ trunk/docutils/test/functional/expected/math_output_html.html 2012-05-02 19:23:53 UTC (rev 7418) @@ -3,7 +3,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="generator" content="Docutils 0.9: http://docutils.sourceforge.net/" /> +<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" /> <title>Mathematics</title> <link rel="stylesheet" href="../../../docutils/writers/html4css1/html4css1.css" type="text/css" /> <link rel="stylesheet" href="../../../docutils/writers/html4css1/math.css" type="text/css" /> Modified: trunk/docutils/test/functional/expected/math_output_latex.html =================================================================== --- trunk/docutils/test/functional/expected/math_output_latex.html 2012-05-02 19:19:41 UTC (rev 7417) +++ trunk/docutils/test/functional/expected/math_output_latex.html 2012-05-02 19:23:53 UTC (rev 7418) @@ -3,7 +3,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="generator" content="Docutils 0.9: http://docutils.sourceforge.net/" /> +<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" /> <title>Mathematics</title> <link rel="stylesheet" href="../../../docutils/writers/html4css1/html4css1.css" type="text/css" /> </head> Modified: trunk/docutils/test/functional/expected/math_output_mathjax.html =================================================================== --- trunk/docutils/test/functional/expected/math_output_mathjax.html 2012-05-02 19:19:41 UTC (rev 7417) +++ trunk/docutils/test/functional/expected/math_output_mathjax.html 2012-05-02 19:23:53 UTC (rev 7418) @@ -3,7 +3,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="generator" content="Docutils 0.9: http://docutils.sourceforge.net/" /> +<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" /> <title>Mathematics</title> <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script> <link rel="stylesheet" href="../../../docutils/writers/html4css1/html4css1.css" type="text/css" /> Modified: trunk/docutils/test/functional/expected/math_output_mathml.xhtml =================================================================== --- trunk/docutils/test/functional/expected/math_output_mathml.xhtml 2012-05-02 19:19:41 UTC (rev 7417) +++ trunk/docutils/test/functional/expected/math_output_mathml.xhtml 2012-05-02 19:23:53 UTC (rev 7418) @@ -3,7 +3,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" /> -<meta name="generator" content="Docutils 0.9: http://docutils.sourceforge.net/" /> +<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" /> <title>Mathematics</title> <link rel="stylesheet" href="../../../docutils/writers/html4css1/html4css1.css" type="text/css" /> </head> Modified: trunk/docutils/test/functional/expected/misc_rst_html4css1.html =================================================================== --- trunk/docutils/test/functional/expected/misc_rst_html4css1.html 2012-05-02 19:19:41 UTC (rev 7417) +++ trunk/docutils/test/functional/expected/misc_rst_html4css1.html 2012-05-02 19:23:53 UTC (rev 7418) @@ -3,7 +3,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="generator" content="Docutils 0.9: http://docutils.sourceforge.net/" /> +<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" /> <title></title> <link rel="stylesheet" href="foo&bar.css" type="text/css" /> </head> Modified: trunk/docutils/test/functional/expected/pep_html.html =================================================================== --- trunk/docutils/test/functional/expected/pep_html.html 2012-05-02 19:19:41 UTC (rev 7417) +++ trunk/docutils/test/functional/expected/pep_html.html 2012-05-02 19:23:53 UTC (rev 7418) @@ -8,7 +8,7 @@ --> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <meta name="generator" content="Docutils 0.9: http://docutils.sourceforge.net/" /> + <meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" /> <title>PEP 100 -- Test PEP</title> <link rel="stylesheet" href="../../../docutils/writers/pep_html/pep.css" type="text/css" /> </head> Modified: trunk/docutils/test/functional/expected/standalone_rst_html4css1.html =================================================================== --- trunk/docutils/test/functional/expected/standalone_rst_html4css1.html 2012-05-02 19:19:41 UTC (rev 7417) +++ trunk/docutils/test/functional/expected/standalone_rst_html4css1.html 2012-05-02 19:23:53 UTC (rev 7418) @@ -3,7 +3,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="generator" content="Docutils 0.9: http://docutils.sourceforge.net/" /> +<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" /> <title>reStructuredText Test Document</title> <meta name="author" content="David Goodger" /> <meta name="authors" content="Me Myself I" /> Modified: trunk/docutils/test/functional/expected/standalone_rst_s5_html_1.html =================================================================== --- trunk/docutils/test/functional/expected/standalone_rst_s5_html_1.html 2012-05-02 19:19:41 UTC (rev 7417) +++ trunk/docutils/test/functional/expected/standalone_rst_s5_html_1.html 2012-05-02 19:23:53 UTC (rev 7418) @@ -3,7 +3,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="generator" content="Docutils 0.9: http://docutils.sourceforge.net/" /> +<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" /> <meta name="version" content="S5 1.1" /> <title>Slide Shows</title> <meta name="author" content="David Goodger" /> Modified: trunk/docutils/test/functional/expected/standalone_rst_s5_html_2.html =================================================================== --- trunk/docutils/test/functional/expected/standalone_rst_s5_html_2.html 2012-05-02 19:19:41 UTC (rev 7417) +++ trunk/docutils/test/functional/expected/standalone_rst_s5_html_2.html 2012-05-02 19:23:53 UTC (rev 7418) @@ -3,7 +3,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="generator" content="Docutils 0.9: http://docutils.sourceforge.net/" /> +<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" /> <meta name="version" content="S5 1.1" /> <title>Slide Shows</title> <meta name="author" content="David Goodger" /> Modified: trunk/docutils/test/functional/expected/stylesheet_path_html4css1.html =================================================================== --- trunk/docutils/test/functional/expected/stylesheet_path_html4css1.html 2012-05-02 19:19:41 UTC (rev 7417) +++ trunk/docutils/test/functional/expected/stylesheet_path_html4css1.html 2012-05-02 19:23:53 UTC (rev 7418) @@ -3,7 +3,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="generator" content="Docutils 0.9: http://docutils.sourceforge.net/" /> +<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" /> <title></title> <link rel="stylesheet" href="../../data/ham.css" type="text/css" /> <link rel="stylesheet" href="missing.css" type="text/css" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mi...@us...> - 2012-05-03 10:55:40
|
Revision: 7422 http://docutils.svn.sourceforge.net/docutils/?rev=7422&view=rev Author: milde Date: 2012-05-03 10:55:30 +0000 (Thu, 03 May 2012) Log Message: ----------- odtwriter: import the PIL Image module via ``import PIL``. * Unify the PIL.Image import (images.py and the HTML writer changed already in Dec 2011, Pygments in May 2010). * starting with PIL 1.2, "PIL lives in the PIL namespace only" (http://mail.python.org/pipermail/image-sig/2011-January/006650.html) Modified Paths: -------------- trunk/docutils/HISTORY.txt trunk/docutils/docutils/writers/odf_odt/__init__.py Modified: trunk/docutils/HISTORY.txt =================================================================== --- trunk/docutils/HISTORY.txt 2012-05-03 06:37:16 UTC (rev 7421) +++ trunk/docutils/HISTORY.txt 2012-05-03 10:55:30 UTC (rev 7422) @@ -25,8 +25,12 @@ - New reStructuredText "code" role and directive and "code" option of the "include" directive with syntax highlighting by Pygments_. - Fix parse_option_marker for option arguments containing ``=``. + - Fix [ 2993756 ]: import Python Imaging Library's Image module + via ``import PIL`` as starting with PIL 1.2, + "PIL lives in the PIL namespace only" (announcement__). .. _Pygments: http://pygments.org/ +__ http://mail.python.org/pipermail/image-sig/2011-January/006650.html * setup.py Modified: trunk/docutils/docutils/writers/odf_odt/__init__.py =================================================================== --- trunk/docutils/docutils/writers/odf_odt/__init__.py 2012-05-03 06:37:16 UTC (rev 7421) +++ trunk/docutils/docutils/writers/odf_odt/__init__.py 2012-05-03 10:55:30 UTC (rev 7422) @@ -64,12 +64,15 @@ except ImportError, exp: pygments = None -# -# Is the PIL imaging library installed? -try: - import Image -except ImportError, exp: - Image = None +try: # check for the Python Imaging Library + import PIL +except ImportError: + try: # sometimes PIL modules are put in PYTHONPATH's root + import Image + class PIL(object): pass # dummy wrapper + PIL.Image = Image + except ImportError: + PIL = None ## import warnings ## warnings.warn('importing IPShellEmbed', UserWarning) @@ -2123,9 +2126,9 @@ height = self.get_image_width_height(node, 'height') dpi = (72, 72) - if Image is not None and source in self.image_dict: + if PIL is not None and source in self.image_dict: filename, destination = self.image_dict[source] - imageobj = Image.open(filename, 'r') + imageobj = PIL.Image.open(filename, 'r') dpi = imageobj.info.get('dpi', dpi) # dpi information can be (xdpi, ydpi) or xydpi try: iter(dpi) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mi...@us...> - 2012-05-03 11:02:00
|
Revision: 7423 http://docutils.svn.sourceforge.net/docutils/?rev=7423&view=rev Author: milde Date: 2012-05-03 11:01:54 +0000 (Thu, 03 May 2012) Log Message: ----------- Documentation update. Modified Paths: -------------- trunk/docutils/RELEASE-NOTES.txt trunk/docutils/docutils/error_reporting.py Modified: trunk/docutils/RELEASE-NOTES.txt =================================================================== --- trunk/docutils/RELEASE-NOTES.txt 2012-05-03 10:55:30 UTC (rev 7422) +++ trunk/docutils/RELEASE-NOTES.txt 2012-05-03 11:01:54 UTC (rev 7423) @@ -34,12 +34,13 @@ Roadmap: :0.10: change of default behaviour to the equivalent of - ``handle_io_errors=False`` and deprecation of the - `handle_io_errors` option, - :0.11: deprecation warning to stderr if FileInput/FileOutput - is called with `handle_io_errors`, - :0.12: ignore ``handle_io_errors=True``, - :0.13: remove the `handle_io_errors` option. + ``handle_io_errors=False``, + ignore and deprecate the `handle_io_errors` option. + (allows us to clean up Docutils code and remove the error handling + code from the FileInput/FileOutput classes) + :0.10 + n: deprecation warning to stderr if FileInput/FileOutput + is called with `handle_io_errors`, + :0.10 + n+1: remove the `handle_io_errors` option. Changes Since 0.9 Modified: trunk/docutils/docutils/error_reporting.py =================================================================== --- trunk/docutils/docutils/error_reporting.py 2012-05-03 10:55:30 UTC (rev 7422) +++ trunk/docutils/docutils/error_reporting.py 2012-05-03 11:01:54 UTC (rev 7423) @@ -140,11 +140,10 @@ decoding_errors='replace'): """ :Parameters: - - `stream`: a file-like object (which is written to), - a string (opended as a file), - `None` (bind to `sys.stderr`; default). - If evaluating to `False` (but not `None`), - write() requests are ignored. + - `stream`: a file-like object, + a string (path to a file), + `None` (write to `sys.stderr`, default), or + evaluating to `False` (write() requests are ignored). - `encoding`: `stream` text encoding. Guessed if None. - `encoding_errors`: how to treat encoding errors. """ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |