|
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,
+ t...
[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(s...
[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{...
[truncated message content] |
|
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...
[truncated message content] |
|
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.
|