Got module working with FreeCAD 0.17 running Python 3+
This commit is contained in:
parent
ceb37b47c0
commit
05289f504d
|
@ -1,7 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""Adds all of the commands that are used for the menus of the CadQuery module"""
|
"""Adds all of the commands that are used for the menus of the CadQuery module"""
|
||||||
# (c) 2014-2016 Jeremy Wright Apache 2.0 License
|
# (c) 2014-2018 Jeremy Wright Apache 2.0 License
|
||||||
|
|
||||||
import imp, os, sys, tempfile
|
import imp, os, sys, tempfile
|
||||||
import FreeCAD, FreeCADGui
|
import FreeCAD, FreeCADGui
|
||||||
from PySide import QtGui, QtCore
|
from PySide import QtGui, QtCore
|
||||||
|
@ -160,7 +159,7 @@ class CadQueryExecuteScript:
|
||||||
scriptText = cqCodePane.toPlainText().encode('utf-8')
|
scriptText = cqCodePane.toPlainText().encode('utf-8')
|
||||||
|
|
||||||
# Check to see if we are executig a CQGI compliant script
|
# Check to see if we are executig a CQGI compliant script
|
||||||
if "show_object(" in scriptText or "debug(" in scriptText:
|
if b"show_object(" in scriptText or b"debug(" in scriptText:
|
||||||
FreeCAD.Console.PrintMessage("Executing CQGI-compliant script.\r\n")
|
FreeCAD.Console.PrintMessage("Executing CQGI-compliant script.\r\n")
|
||||||
|
|
||||||
# A repreentation of the CQ script with all the metadata attached
|
# A repreentation of the CQ script with all the metadata attached
|
||||||
|
@ -451,7 +450,7 @@ class CadQueryValidateScript:
|
||||||
|
|
||||||
scriptText = cqCodePane.toPlainText().encode('utf-8')
|
scriptText = cqCodePane.toPlainText().encode('utf-8')
|
||||||
|
|
||||||
if ("show_object(" not in scriptText and "# show_object(" in scriptText and "#show_boject(" in scriptText) or ("debug(" not in scriptText and "# debug(" in scriptText and "#debug(" in scriptText):
|
if (b"show_object(" not in scriptText) and (b"debug(" not in scriptText):
|
||||||
FreeCAD.Console.PrintError("Script did not call show_object or debug, no output available. Script must be CQGI compliant to get build output, variable editing and validation.\r\n")
|
FreeCAD.Console.PrintError("Script did not call show_object or debug, no output available. Script must be CQGI compliant to get build output, variable editing and validation.\r\n")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: __init__.py 7756 2014-07-06 11:48:05Z grubert $
|
# $Id: __init__.py 8147 2017-08-03 09:01:16Z grubert $
|
||||||
# Author: David Goodger <goodger@python.org>
|
# Author: David Goodger <goodger@python.org>
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
@ -50,22 +50,66 @@ Subpackages:
|
||||||
- writers: Format-specific output translators.
|
- writers: Format-specific output translators.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__docformat__ = 'reStructuredText'
|
|
||||||
|
|
||||||
__version__ = '0.12'
|
|
||||||
"""``major.minor.micro`` version number. The micro number is bumped for API
|
|
||||||
changes, for new functionality, and for interim project releases. The minor
|
|
||||||
number is bumped whenever there is a significant project release. The major
|
|
||||||
number will be bumped when the project is feature-complete, and perhaps if
|
|
||||||
there is a major change in the design."""
|
|
||||||
|
|
||||||
__version_details__ = 'release'
|
|
||||||
"""Extra version details (e.g. 'snapshot 2005-05-29, r3410', 'repository',
|
|
||||||
'release'), modified automatically & manually."""
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
class ApplicationError(StandardError):
|
|
||||||
|
__docformat__ = 'reStructuredText'
|
||||||
|
|
||||||
|
__version__ = '0.14'
|
||||||
|
"""Docutils version identifier (complies with PEP 440)::
|
||||||
|
|
||||||
|
major.minor[.micro][releaselevel[serial]][.dev]
|
||||||
|
|
||||||
|
* The major number will be bumped when the project is feature-complete, and
|
||||||
|
later if there is a major change in the design or API.
|
||||||
|
* The minor number is bumped whenever there are new features.
|
||||||
|
* The micro number is bumped for bug-fix releases. Omitted if micro=0.
|
||||||
|
* The releaselevel identifier is used for pre-releases, one of 'a' (alpha),
|
||||||
|
'b' (beta), or 'rc' (release candidate). Omitted for final releases.
|
||||||
|
* The serial release number identifies prereleases; omitted if 0.
|
||||||
|
* The '.dev' suffix indicates active development, not a release, before the
|
||||||
|
version indicated.
|
||||||
|
|
||||||
|
For version comparison operations, use `__version_info__`
|
||||||
|
rather than parsing the text of `__version__`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# workaround for Python < 2.6:
|
||||||
|
__version_info__ = (0, 14, 0, 'final', 0, True)
|
||||||
|
# To add in Docutils 0.15, replacing the line above:
|
||||||
|
"""
|
||||||
|
from collections import namedtuple
|
||||||
|
VersionInfo = namedtuple(
|
||||||
|
'VersionInfo', 'major minor micro releaselevel serial release')
|
||||||
|
__version_info__ = VersionInfo(
|
||||||
|
major=0,
|
||||||
|
minor=15,
|
||||||
|
micro=0,
|
||||||
|
releaselevel='alpha', # development status:
|
||||||
|
# one of 'alpha', 'beta', 'candidate', 'final'
|
||||||
|
serial=0, # pre-release number (0 for final releases)
|
||||||
|
release=False # True for official releases and pre-releases
|
||||||
|
)
|
||||||
|
|
||||||
|
Comprehensive version information tuple. Can be used to test for a
|
||||||
|
minimally required version, e.g. ::
|
||||||
|
|
||||||
|
if __version_info__ >= (0, 13, 0, 'candidate', 2, True)
|
||||||
|
|
||||||
|
or in a self-documenting way like ::
|
||||||
|
|
||||||
|
if __version_info__ >= docutils.VersionInfo(
|
||||||
|
major=0, minor=13, micro=0,
|
||||||
|
releaselevel='candidate', serial=2, release=True)
|
||||||
|
"""
|
||||||
|
|
||||||
|
__version_details__ = ''
|
||||||
|
"""Optional extra version details (e.g. 'snapshot 2005-05-29, r3410').
|
||||||
|
(For development and release status see `__version_info__`.)
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class ApplicationError(Exception):
|
||||||
# Workaround:
|
# Workaround:
|
||||||
# In Python < 2.6, unicode(<exception instance>) calls `str` on the
|
# In Python < 2.6, unicode(<exception instance>) calls `str` on the
|
||||||
# arg and therefore, e.g., unicode(StandardError(u'\u234')) fails
|
# arg and therefore, e.g., unicode(StandardError(u'\u234')) fails
|
||||||
|
@ -74,6 +118,7 @@ class ApplicationError(StandardError):
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u', '.join(self.args)
|
return u', '.join(self.args)
|
||||||
|
|
||||||
|
|
||||||
class DataError(ApplicationError): pass
|
class DataError(ApplicationError): pass
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: core.py 7466 2012-06-25 14:56:51Z milde $
|
# $Id: core.py 8126 2017-06-23 09:34:28Z milde $
|
||||||
# Author: David Goodger <goodger@python.org>
|
# Author: David Goodger <goodger@python.org>
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
@ -218,10 +218,10 @@ class Publisher:
|
||||||
self.apply_transforms()
|
self.apply_transforms()
|
||||||
output = self.writer.write(self.document, self.destination)
|
output = self.writer.write(self.document, self.destination)
|
||||||
self.writer.assemble_parts()
|
self.writer.assemble_parts()
|
||||||
except SystemExit, error:
|
except SystemExit as error:
|
||||||
exit = 1
|
exit = 1
|
||||||
exit_status = error.code
|
exit_status = error.code
|
||||||
except Exception, error:
|
except Exception as error:
|
||||||
if not self.settings: # exception too early to report nicely
|
if not self.settings: # exception too early to report nicely
|
||||||
raise
|
raise
|
||||||
if self.settings.traceback: # Propagate exceptions?
|
if self.settings.traceback: # Propagate exceptions?
|
||||||
|
@ -279,9 +279,11 @@ class Publisher:
|
||||||
print >>self._stderr, ("""\
|
print >>self._stderr, ("""\
|
||||||
Exiting due to error. Use "--traceback" to diagnose.
|
Exiting due to error. Use "--traceback" to diagnose.
|
||||||
Please report errors to <docutils-users@lists.sf.net>.
|
Please report errors to <docutils-users@lists.sf.net>.
|
||||||
Include "--traceback" output, Docutils version (%s [%s]),
|
Include "--traceback" output, Docutils version (%s%s),
|
||||||
Python version (%s), your OS type & version, and the
|
Python version (%s), your OS type & version, and the
|
||||||
command line used.""" % (__version__, __version_details__,
|
command line used.""" % (__version__,
|
||||||
|
docutils.__version_details__ and
|
||||||
|
' [%s]'%docutils.__version_details__ or '',
|
||||||
sys.version.split()[0]))
|
sys.version.split()[0]))
|
||||||
|
|
||||||
def report_SystemMessage(self, error):
|
def report_SystemMessage(self, error):
|
||||||
|
|
5
Libs/docutils/docutils.conf
Normal file
5
Libs/docutils/docutils.conf
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# This configuration file is to prevent tools/buildhtml.py from
|
||||||
|
# processing text files in and below this directory.
|
||||||
|
|
||||||
|
[buildhtml application]
|
||||||
|
prune: .
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: frontend.py 7584 2013-01-01 20:00:21Z milde $
|
# $Id: frontend.py 8126 2017-06-23 09:34:28Z milde $
|
||||||
# Author: David Goodger <goodger@python.org>
|
# Author: David Goodger <goodger@python.org>
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
@ -33,14 +33,18 @@ import os
|
||||||
import os.path
|
import os.path
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
import ConfigParser as CP
|
try:
|
||||||
|
import ConfigParser as CP
|
||||||
|
except:
|
||||||
|
import configparser as CP
|
||||||
import codecs
|
import codecs
|
||||||
import optparse
|
import optparse
|
||||||
from optparse import SUPPRESS_HELP
|
from optparse import SUPPRESS_HELP
|
||||||
import docutils
|
import docutils
|
||||||
import docutils.utils
|
import docutils.utils
|
||||||
import docutils.nodes
|
import docutils.nodes
|
||||||
from docutils.utils.error_reporting import locale_encoding, ErrorOutput, ErrorString
|
from docutils.utils.error_reporting import (locale_encoding, SafeString,
|
||||||
|
ErrorOutput, ErrorString)
|
||||||
|
|
||||||
|
|
||||||
def store_multiple(option, opt, value, parser, *args, **kwargs):
|
def store_multiple(option, opt, value, parser, *args, **kwargs):
|
||||||
|
@ -61,7 +65,7 @@ def read_config_file(option, opt, value, parser):
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
new_settings = parser.get_config_file_settings(value)
|
new_settings = parser.get_config_file_settings(value)
|
||||||
except ValueError, error:
|
except ValueError as error:
|
||||||
parser.error(error)
|
parser.error(error)
|
||||||
parser.values.update(new_settings, parser)
|
parser.values.update(new_settings, parser)
|
||||||
|
|
||||||
|
@ -205,10 +209,45 @@ def validate_strip_class(setting, value, option_parser,
|
||||||
for cls in value:
|
for cls in value:
|
||||||
normalized = docutils.nodes.make_id(cls)
|
normalized = docutils.nodes.make_id(cls)
|
||||||
if cls != normalized:
|
if cls != normalized:
|
||||||
raise ValueError('invalid class value %r (perhaps %r?)'
|
raise ValueError('Invalid class value %r (perhaps %r?)'
|
||||||
% (cls, normalized))
|
% (cls, normalized))
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
def validate_smartquotes_locales(setting, value, option_parser,
|
||||||
|
config_parser=None, config_section=None):
|
||||||
|
"""Check/normalize a comma separated list of smart quote definitions.
|
||||||
|
|
||||||
|
Return a list of (language-tag, quotes) string tuples."""
|
||||||
|
|
||||||
|
# value is a comma separated string list:
|
||||||
|
value = validate_comma_separated_list(setting, value, option_parser,
|
||||||
|
config_parser, config_section)
|
||||||
|
# validate list elements
|
||||||
|
lc_quotes = []
|
||||||
|
for item in value:
|
||||||
|
try:
|
||||||
|
lang, quotes = item.split(':', 1)
|
||||||
|
except AttributeError:
|
||||||
|
# this function is called for every option added to `value`
|
||||||
|
# -> ignore if already a tuple:
|
||||||
|
lc_quotes.append(item)
|
||||||
|
continue
|
||||||
|
except ValueError:
|
||||||
|
raise ValueError(u'Invalid value "%s".'
|
||||||
|
' Format is "<language>:<quotes>".'
|
||||||
|
% item.encode('ascii', 'backslashreplace'))
|
||||||
|
# parse colon separated string list:
|
||||||
|
quotes = quotes.strip()
|
||||||
|
multichar_quotes = quotes.split(':')
|
||||||
|
if len(multichar_quotes) == 4:
|
||||||
|
quotes = multichar_quotes
|
||||||
|
elif len(quotes) != 4:
|
||||||
|
raise ValueError('Invalid value "%s". Please specify 4 quotes\n'
|
||||||
|
' (primary open/close; secondary open/close).'
|
||||||
|
% item.encode('ascii', 'backslashreplace'))
|
||||||
|
lc_quotes.append((lang,quotes))
|
||||||
|
return lc_quotes
|
||||||
|
|
||||||
def make_paths_absolute(pathdict, keys, base_path=None):
|
def make_paths_absolute(pathdict, keys, base_path=None):
|
||||||
"""
|
"""
|
||||||
Interpret filesystem path settings relative to the `base_path` given.
|
Interpret filesystem path settings relative to the `base_path` given.
|
||||||
|
@ -310,7 +349,7 @@ class Option(optparse.Option):
|
||||||
value = getattr(values, setting)
|
value = getattr(values, setting)
|
||||||
try:
|
try:
|
||||||
new_value = self.validator(setting, value, parser)
|
new_value = self.validator(setting, value, parser)
|
||||||
except Exception, error:
|
except Exception as error:
|
||||||
raise (optparse.OptionValueError(
|
raise (optparse.OptionValueError(
|
||||||
'Error in option "%s":\n %s'
|
'Error in option "%s":\n %s'
|
||||||
% (opt, ErrorString(error))),
|
% (opt, ErrorString(error))),
|
||||||
|
@ -534,8 +573,10 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec):
|
||||||
|
|
||||||
config_section = 'general'
|
config_section = 'general'
|
||||||
|
|
||||||
version_template = ('%%prog (Docutils %s [%s], Python %s, on %s)'
|
version_template = ('%%prog (Docutils %s%s, Python %s, on %s)'
|
||||||
% (docutils.__version__, docutils.__version_details__,
|
% (docutils.__version__,
|
||||||
|
docutils.__version_details__ and
|
||||||
|
' [%s]'%docutils.__version_details__ or '',
|
||||||
sys.version.split()[0], sys.platform))
|
sys.version.split()[0], sys.platform))
|
||||||
"""Default version message."""
|
"""Default version message."""
|
||||||
|
|
||||||
|
@ -567,8 +608,8 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec):
|
||||||
if read_config_files and not self.defaults['_disable_config']:
|
if read_config_files and not self.defaults['_disable_config']:
|
||||||
try:
|
try:
|
||||||
config_settings = self.get_standard_config_settings()
|
config_settings = self.get_standard_config_settings()
|
||||||
except ValueError, error:
|
except ValueError as error:
|
||||||
self.error(error)
|
self.error(SafeString(error))
|
||||||
self.set_defaults_from_dict(config_settings.__dict__)
|
self.set_defaults_from_dict(config_settings.__dict__)
|
||||||
|
|
||||||
def populate_from_components(self, components):
|
def populate_from_components(self, components):
|
||||||
|
@ -788,7 +829,7 @@ Skipping "%s" configuration file.
|
||||||
new_value = option.validator(
|
new_value = option.validator(
|
||||||
setting, value, option_parser,
|
setting, value, option_parser,
|
||||||
config_parser=self, config_section=section)
|
config_parser=self, config_section=section)
|
||||||
except Exception, error:
|
except Exception as error:
|
||||||
raise (ValueError(
|
raise (ValueError(
|
||||||
'Error in config file "%s", section "[%s]":\n'
|
'Error in config file "%s", section "[%s]":\n'
|
||||||
' %s\n'
|
' %s\n'
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: io.py 7596 2013-01-25 13:42:17Z milde $
|
# $Id: io.py 8129 2017-06-27 14:55:22Z grubert $
|
||||||
# Author: David Goodger <goodger@python.org>
|
# Author: David Goodger <goodger@python.org>
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ class Input(TransformSpec):
|
||||||
self.successful_encoding = enc
|
self.successful_encoding = enc
|
||||||
# Return decoded, removing BOMs.
|
# Return decoded, removing BOMs.
|
||||||
return decoded.replace(u'\ufeff', u'')
|
return decoded.replace(u'\ufeff', u'')
|
||||||
except (UnicodeError, LookupError), err:
|
except (UnicodeError, LookupError) as err:
|
||||||
error = err # in Python 3, the <exception instance> is
|
error = err # in Python 3, the <exception instance> is
|
||||||
# local to the except clause
|
# local to the except clause
|
||||||
raise UnicodeError(
|
raise UnicodeError(
|
||||||
|
@ -122,7 +122,7 @@ class Input(TransformSpec):
|
||||||
'%s.\n(%s)' % (', '.join([repr(enc) for enc in encodings]),
|
'%s.\n(%s)' % (', '.join([repr(enc) for enc in encodings]),
|
||||||
ErrorString(error)))
|
ErrorString(error)))
|
||||||
|
|
||||||
coding_slug = re.compile(b("coding[:=]\s*([-\w.]+)"))
|
coding_slug = re.compile(b(r"coding[:=]\s*([-\w.]+)"))
|
||||||
"""Encoding declaration pattern."""
|
"""Encoding declaration pattern."""
|
||||||
|
|
||||||
byte_order_marks = ((codecs.BOM_UTF8, 'utf-8'), # 'utf-8-sig' new in v2.5
|
byte_order_marks = ((codecs.BOM_UTF8, 'utf-8'), # 'utf-8-sig' new in v2.5
|
||||||
|
@ -204,7 +204,7 @@ class FileInput(Input):
|
||||||
"""
|
"""
|
||||||
def __init__(self, source=None, source_path=None,
|
def __init__(self, source=None, source_path=None,
|
||||||
encoding=None, error_handler='strict',
|
encoding=None, error_handler='strict',
|
||||||
autoclose=True, handle_io_errors=None, mode='rU'):
|
autoclose=True, mode='rU', **kwargs):
|
||||||
"""
|
"""
|
||||||
:Parameters:
|
:Parameters:
|
||||||
- `source`: either a file-like object (which is read directly), or
|
- `source`: either a file-like object (which is read directly), or
|
||||||
|
@ -214,7 +214,6 @@ class FileInput(Input):
|
||||||
- `error_handler`: the encoding error handler to use.
|
- `error_handler`: the encoding error handler to use.
|
||||||
- `autoclose`: close automatically after read (except when
|
- `autoclose`: close automatically after read (except when
|
||||||
`sys.stdin` is the source).
|
`sys.stdin` is the source).
|
||||||
- `handle_io_errors`: ignored, deprecated, will be removed.
|
|
||||||
- `mode`: how the file is to be opened (see standard function
|
- `mode`: how the file is to be opened (see standard function
|
||||||
`open`). The default 'rU' provides universal newline support
|
`open`). The default 'rU' provides universal newline support
|
||||||
for text files.
|
for text files.
|
||||||
|
@ -222,6 +221,16 @@ class FileInput(Input):
|
||||||
Input.__init__(self, source, source_path, encoding, error_handler)
|
Input.__init__(self, source, source_path, encoding, error_handler)
|
||||||
self.autoclose = autoclose
|
self.autoclose = autoclose
|
||||||
self._stderr = ErrorOutput()
|
self._stderr = ErrorOutput()
|
||||||
|
# deprecation warning
|
||||||
|
for key in kwargs:
|
||||||
|
if key == 'handle_io_errors':
|
||||||
|
sys.stderr.write('deprecation warning: '
|
||||||
|
'io.FileInput() argument `handle_io_errors` '
|
||||||
|
'is ignored since "Docutils 0.10 (2012-12-16)" '
|
||||||
|
'and will soon be removed.')
|
||||||
|
else:
|
||||||
|
raise TypeError('__init__() got an unexpected keyword '
|
||||||
|
"argument '%s'" % key)
|
||||||
|
|
||||||
if source is None:
|
if source is None:
|
||||||
if source_path:
|
if source_path:
|
||||||
|
@ -234,7 +243,7 @@ class FileInput(Input):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.source = open(source_path, mode, **kwargs)
|
self.source = open(source_path, mode, **kwargs)
|
||||||
except IOError, error:
|
except IOError as error:
|
||||||
raise InputError(error.errno, error.strerror, source_path)
|
raise InputError(error.errno, error.strerror, source_path)
|
||||||
else:
|
else:
|
||||||
self.source = sys.stdin
|
self.source = sys.stdin
|
||||||
|
@ -263,7 +272,7 @@ class FileInput(Input):
|
||||||
data = b('\n').join(data.splitlines()) + b('\n')
|
data = b('\n').join(data.splitlines()) + b('\n')
|
||||||
else:
|
else:
|
||||||
data = self.source.read()
|
data = self.source.read()
|
||||||
except (UnicodeError, LookupError), err: # (in Py3k read() decodes)
|
except (UnicodeError, LookupError) as err: # (in Py3k read() decodes)
|
||||||
if not self.encoding and self.source_path:
|
if not self.encoding and self.source_path:
|
||||||
# re-read in binary mode and decode with heuristics
|
# re-read in binary mode and decode with heuristics
|
||||||
b_source = open(self.source_path, 'rb')
|
b_source = open(self.source_path, 'rb')
|
||||||
|
@ -353,7 +362,7 @@ class FileOutput(Output):
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
try:
|
try:
|
||||||
self.destination = open(self.destination_path, self.mode, **kwargs)
|
self.destination = open(self.destination_path, self.mode, **kwargs)
|
||||||
except IOError, error:
|
except IOError as error:
|
||||||
raise OutputError(error.errno, error.strerror,
|
raise OutputError(error.errno, error.strerror,
|
||||||
self.destination_path)
|
self.destination_path)
|
||||||
self.opened = True
|
self.opened = True
|
||||||
|
@ -369,19 +378,19 @@ class FileOutput(Output):
|
||||||
if ('b' not in self.mode and sys.version_info < (3,0)
|
if ('b' not in self.mode and sys.version_info < (3,0)
|
||||||
or check_encoding(self.destination, self.encoding) is False
|
or check_encoding(self.destination, self.encoding) is False
|
||||||
):
|
):
|
||||||
if sys.version_info >= (3,0) and os.linesep != '\n':
|
|
||||||
data = data.replace('\n', os.linesep) # fix endings
|
|
||||||
data = self.encode(data)
|
data = self.encode(data)
|
||||||
|
if sys.version_info >= (3,0) and os.linesep != '\n':
|
||||||
|
data = data.replace(b('\n'), b(os.linesep)) # fix endings
|
||||||
|
|
||||||
try: # In Python < 2.5, try...except has to be nested in try...finally.
|
try: # In Python < 2.5, try...except has to be nested in try...finally.
|
||||||
try:
|
try:
|
||||||
self.destination.write(data)
|
self.destination.write(data)
|
||||||
except TypeError, e:
|
except TypeError as e:
|
||||||
if sys.version_info >= (3,0) and isinstance(data, bytes):
|
if sys.version_info >= (3,0) and isinstance(data, bytes):
|
||||||
try:
|
try:
|
||||||
self.destination.buffer.write(data)
|
self.destination.buffer.write(data)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
if check_encoding(self.destination,
|
if check_encoding(self.destination,
|
||||||
self.encoding) is False:
|
self.encoding) is False:
|
||||||
raise ValueError('Encoding of %s (%s) differs \n'
|
raise ValueError('Encoding of %s (%s) differs \n'
|
||||||
' from specified encoding (%s)' %
|
' from specified encoding (%s)' %
|
||||||
|
@ -389,7 +398,7 @@ class FileOutput(Output):
|
||||||
self.destination.encoding, self.encoding))
|
self.destination.encoding, self.encoding))
|
||||||
else:
|
else:
|
||||||
raise e
|
raise e
|
||||||
except (UnicodeError, LookupError), err:
|
except (UnicodeError, LookupError) as err:
|
||||||
raise UnicodeError(
|
raise UnicodeError(
|
||||||
'Unable to encode output data. output-encoding is: '
|
'Unable to encode output data. output-encoding is: '
|
||||||
'%s.\n(%s)' % (self.encoding, ErrorString(err)))
|
'%s.\n(%s)' % (self.encoding, ErrorString(err)))
|
||||||
|
|
61
Libs/docutils/languages/fa.py
Normal file
61
Libs/docutils/languages/fa.py
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# $Id: fa.py 4564 2016-08-10 11:48:42Z
|
||||||
|
# Author: Shahin <me@5hah.in>
|
||||||
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
# New language mappings are welcome. Before doing a new translation, please
|
||||||
|
# read <http://docutils.sf.net/docs/howto/i18n.html>. Two files must be
|
||||||
|
# translated for each language: one in docutils/languages, the other in
|
||||||
|
# docutils/parsers/rst/languages.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Persian-language mappings for language-dependent features of Docutils.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__docformat__ = 'reStructuredText'
|
||||||
|
|
||||||
|
labels = {
|
||||||
|
# fixed: language-dependent
|
||||||
|
u'author': u'نویسنده',
|
||||||
|
u'authors': u'نویسندگان',
|
||||||
|
u'organization': u'سازمان',
|
||||||
|
u'address': u'آدرس',
|
||||||
|
u'contact': u'تماس',
|
||||||
|
u'version': u'نسخه',
|
||||||
|
u'revision': u'بازبینی',
|
||||||
|
u'status': u'وضعیت',
|
||||||
|
u'date': u'تاریخ',
|
||||||
|
u'copyright': u'کپیرایت',
|
||||||
|
u'dedication': u'تخصیص',
|
||||||
|
u'abstract': u'چکیده',
|
||||||
|
u'attention': u'توجه!',
|
||||||
|
u'caution': u'احتیاط!',
|
||||||
|
u'danger': u'خطر!',
|
||||||
|
u'error': u'خطا',
|
||||||
|
u'hint': u'راهنما',
|
||||||
|
u'important': u'مهم',
|
||||||
|
u'note': u'یادداشت',
|
||||||
|
u'tip': u'نکته',
|
||||||
|
u'warning': u'اخطار',
|
||||||
|
u'contents': u'محتوا'}
|
||||||
|
"""Mapping of node class name to label text."""
|
||||||
|
|
||||||
|
bibliographic_fields = {
|
||||||
|
# language-dependent: fixed
|
||||||
|
u'نویسنده': u'author',
|
||||||
|
u'نویسندگان': u'authors',
|
||||||
|
u'سازمان': u'organization',
|
||||||
|
u'آدرس': u'address',
|
||||||
|
u'تماس': u'contact',
|
||||||
|
u'نسخه': u'version',
|
||||||
|
u'بازبینی': u'revision',
|
||||||
|
u'وضعیت': u'status',
|
||||||
|
u'تاریخ': u'date',
|
||||||
|
u'کپیرایت': u'copyright',
|
||||||
|
u'تخصیص': u'dedication',
|
||||||
|
u'چکیده': u'abstract'}
|
||||||
|
"""Persian (lowcased) to canonical name mapping for bibliographic fields."""
|
||||||
|
|
||||||
|
author_separators = [u'؛', u'،']
|
||||||
|
"""List of separator strings for the 'Authors' bibliographic field. Tried in
|
||||||
|
order."""
|
|
@ -1,5 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# $Id: lt.py 7668 2013-06-04 12:46:30Z milde $
|
# $Id: lt.py 7911 2015-08-31 08:23:06Z milde $
|
||||||
# Author: Dalius Dobravolskas <dalius.do...@gmail.com>
|
# Author: Dalius Dobravolskas <dalius.do...@gmail.com>
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
# docutils/parsers/rst/languages.
|
# docutils/parsers/rst/languages.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
English-language mappings for language-dependent features of Docutils.
|
Lithuanian language mappings for language-dependent features of Docutils.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__docformat__ = 'reStructuredText'
|
__docformat__ = 'reStructuredText'
|
||||||
|
@ -54,68 +54,7 @@ bibliographic_fields = {
|
||||||
'autoriaus teisės': 'copyright',
|
'autoriaus teisės': 'copyright',
|
||||||
'dedikacija': 'dedication',
|
'dedikacija': 'dedication',
|
||||||
'santrauka': 'abstract'}
|
'santrauka': 'abstract'}
|
||||||
"""English (lowcased) to canonical name mapping for bibliographic fields."""
|
"""Lithuanian (lowcased) to canonical name mapping for bibliographic fields."""
|
||||||
|
|
||||||
author_separators = [';', ',']
|
|
||||||
"""List of separator strings for the 'Authors' bibliographic field. Tried in
|
|
||||||
order."""
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# $Id: lt.py 7668 2013-06-04 12:46:30Z milde $
|
|
||||||
# Author: David Goodger <goodger@python.org>
|
|
||||||
# Copyright: This module has been placed in the public domain.
|
|
||||||
|
|
||||||
# New language mappings are welcome. Before doing a new translation, please
|
|
||||||
# read <http://docutils.sf.net/docs/howto/i18n.html>. Two files must be
|
|
||||||
# translated for each language: one in docutils/languages, the other in
|
|
||||||
# docutils/parsers/rst/languages.
|
|
||||||
|
|
||||||
"""
|
|
||||||
English-language mappings for language-dependent features of Docutils.
|
|
||||||
"""
|
|
||||||
|
|
||||||
__docformat__ = 'reStructuredText'
|
|
||||||
|
|
||||||
labels = {
|
|
||||||
# fixed: language-dependent
|
|
||||||
'author': 'Autorius',
|
|
||||||
'authors': 'Autoriai',
|
|
||||||
'organization': 'Organizacija',
|
|
||||||
'address': 'Adresas',
|
|
||||||
'contact': 'Kontaktas',
|
|
||||||
'version': 'Versija',
|
|
||||||
'revision': 'Revizija',
|
|
||||||
'status': u'Būsena',
|
|
||||||
'date': 'Data',
|
|
||||||
'copyright': u'Autoriaus teisės',
|
|
||||||
'dedication': 'Dedikacija',
|
|
||||||
'abstract': 'Santrauka',
|
|
||||||
'attention': u'Dėmesio!',
|
|
||||||
'caution': 'Atsargiai!',
|
|
||||||
'danger': '!PAVOJINGA!',
|
|
||||||
'error': 'Klaida',
|
|
||||||
'hint': u'Užuomina',
|
|
||||||
'important': 'Svarbu',
|
|
||||||
'note': 'Pastaba',
|
|
||||||
'tip': 'Patarimas',
|
|
||||||
'warning': u'Įspėjimas',
|
|
||||||
'contents': 'Turinys'}
|
|
||||||
"""Mapping of node class name to label text."""
|
|
||||||
|
|
||||||
bibliographic_fields = {
|
|
||||||
# language-dependent: fixed
|
|
||||||
'autorius': 'author',
|
|
||||||
'autoriai': 'authors',
|
|
||||||
'organizacija': 'organization',
|
|
||||||
'adresas': 'address',
|
|
||||||
'kontaktas': 'contact',
|
|
||||||
'versija': 'version',
|
|
||||||
'revizija': 'revision',
|
|
||||||
'būsena': 'status',
|
|
||||||
'data': 'date',
|
|
||||||
'autoriaus teisės': 'copyright',
|
|
||||||
'dedikacija': 'dedication',
|
|
||||||
'santrauka': 'abstract'}
|
|
||||||
"""English (lowcased) to canonical name mapping for bibliographic fields."""
|
|
||||||
|
|
||||||
author_separators = [';', ',']
|
author_separators = [';', ',']
|
||||||
"""List of separator strings for the 'Authors' bibliographic field. Tried in
|
"""List of separator strings for the 'Authors' bibliographic field. Tried in
|
||||||
|
|
60
Libs/docutils/languages/lv.py
Normal file
60
Libs/docutils/languages/lv.py
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# $Id: lv.py 7975 2016-10-20 20:00:19Z milde $
|
||||||
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
# New language mappings are welcome. Before doing a new translation, please
|
||||||
|
# read <http://docutils.sf.net/docs/howto/i18n.html>. Two files must be
|
||||||
|
# translated for each language: one in docutils/languages, the other in
|
||||||
|
# docutils/parsers/rst/languages.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Latvian-language mappings for language-dependent features of Docutils.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__docformat__ = 'reStructuredText'
|
||||||
|
|
||||||
|
labels = {
|
||||||
|
# fixed: language-dependent
|
||||||
|
'author': 'Autors',
|
||||||
|
'authors': 'Autori',
|
||||||
|
'organization': 'Organizācija',
|
||||||
|
'address': 'Adrese',
|
||||||
|
'contact': 'Kontakti',
|
||||||
|
'version': 'Versija',
|
||||||
|
'revision': 'Revīzija',
|
||||||
|
'status': 'Statuss',
|
||||||
|
'date': 'Datums',
|
||||||
|
'copyright': 'Copyright',
|
||||||
|
'dedication': 'Veltījums',
|
||||||
|
'abstract': 'Atreferējums',
|
||||||
|
'attention': 'Uzmanību!',
|
||||||
|
'caution': 'Piesardzību!',
|
||||||
|
'danger': '!BĪSTAMI!',
|
||||||
|
'error': 'Kļūda',
|
||||||
|
'hint': 'Ieteikums',
|
||||||
|
'important': 'Svarīgi',
|
||||||
|
'note': 'Piezīme',
|
||||||
|
'tip': 'Padoms',
|
||||||
|
'warning': 'Brīdinājums',
|
||||||
|
'contents': 'Saturs'}
|
||||||
|
"""Mapping of node class name to label text."""
|
||||||
|
|
||||||
|
bibliographic_fields = {
|
||||||
|
# language-dependent: fixed
|
||||||
|
'autors': 'author',
|
||||||
|
'autori': 'authors',
|
||||||
|
'organizācija': 'organization',
|
||||||
|
'adrese': 'address',
|
||||||
|
'kontakti': 'contact',
|
||||||
|
'versija': 'version',
|
||||||
|
'revīzija': 'revision',
|
||||||
|
'statuss': 'status',
|
||||||
|
'datums': 'date',
|
||||||
|
'copyright': 'copyright',
|
||||||
|
'veltījums': 'dedication',
|
||||||
|
'atreferējums': 'abstract'}
|
||||||
|
"""English (lowcased) to canonical name mapping for bibliographic fields."""
|
||||||
|
|
||||||
|
author_separators = [';', ',']
|
||||||
|
"""List of separator strings for the 'Authors' bibliographic field. Tried in
|
||||||
|
order."""
|
|
@ -1,4 +1,5 @@
|
||||||
# $Id: sv.py 4564 2006-05-21 20:44:42Z wiemann $
|
# -*- coding: utf-8 -*-
|
||||||
|
# $Id: sv.py 8006 2016-12-22 23:02:44Z milde $
|
||||||
# Author: Adam Chodorowski <chodorowski@users.sourceforge.net>
|
# Author: Adam Chodorowski <chodorowski@users.sourceforge.net>
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
@ -14,8 +15,8 @@ Swedish language mappings for language-dependent features of Docutils.
|
||||||
__docformat__ = 'reStructuredText'
|
__docformat__ = 'reStructuredText'
|
||||||
|
|
||||||
labels = {
|
labels = {
|
||||||
'author': u'F\u00f6rfattare',
|
'author': u'Författare',
|
||||||
'authors': u'F\u00f6rfattare',
|
'authors': u'Författare',
|
||||||
'organization': u'Organisation',
|
'organization': u'Organisation',
|
||||||
'address': u'Adress',
|
'address': u'Adress',
|
||||||
'contact': u'Kontakt',
|
'contact': u'Kontakt',
|
||||||
|
@ -27,20 +28,20 @@ labels = {
|
||||||
'dedication': u'Dedikation',
|
'dedication': u'Dedikation',
|
||||||
'abstract': u'Sammanfattning',
|
'abstract': u'Sammanfattning',
|
||||||
'attention': u'Observera!',
|
'attention': u'Observera!',
|
||||||
'caution': u'Varning!',
|
'caution': u'Akta!', # 'Varning' already used for 'warning'
|
||||||
'danger': u'FARA!',
|
'danger': u'FARA!',
|
||||||
'error': u'Fel',
|
'error': u'Fel',
|
||||||
'hint': u'V\u00e4gledning',
|
'hint': u'Vink',
|
||||||
'important': u'Viktigt',
|
'important': u'Viktigt',
|
||||||
'note': u'Notera',
|
'note': u'Notera',
|
||||||
'tip': u'Tips',
|
'tip': u'Tips',
|
||||||
'warning': u'Varning',
|
'warning': u'Varning',
|
||||||
'contents': u'Inneh\u00e5ll' }
|
'contents': u'Innehåll' }
|
||||||
"""Mapping of node class name to label text."""
|
"""Mapping of node class name to label text."""
|
||||||
|
|
||||||
bibliographic_fields = {
|
bibliographic_fields = {
|
||||||
# 'Author' and 'Authors' identical in Swedish; assume the plural:
|
# 'Author' and 'Authors' identical in Swedish; assume the plural:
|
||||||
u'f\u00f6rfattare': 'authors',
|
u'författare': 'authors',
|
||||||
u' n/a': 'author',
|
u' n/a': 'author',
|
||||||
u'organisation': 'organization',
|
u'organisation': 'organization',
|
||||||
u'adress': 'address',
|
u'adress': 'address',
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: nodes.py 7595 2013-01-21 17:33:56Z milde $
|
# $Id: nodes.py 7788 2015-02-16 22:10:52Z milde $
|
||||||
# Author: David Goodger <goodger@python.org>
|
# Author: David Goodger <goodger@python.org>
|
||||||
# Maintainer: docutils-develop@lists.sourceforge.net
|
# Maintainer: docutils-develop@lists.sourceforge.net
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
@ -304,10 +304,8 @@ if sys.version_info < (3,):
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return unicode.__repr__(self)[1:]
|
return unicode.__repr__(self)[1:]
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
reprunicode = unicode
|
reprunicode = str
|
||||||
|
|
||||||
|
|
||||||
def ensure_str(s):
|
def ensure_str(s):
|
||||||
|
@ -533,7 +531,7 @@ class Element(Node):
|
||||||
parts = [self.tagname]
|
parts = [self.tagname]
|
||||||
for name, value in self.attlist():
|
for name, value in self.attlist():
|
||||||
if value is None: # boolean attribute
|
if value is None: # boolean attribute
|
||||||
parts.append(name)
|
parts.append('%s="True"' % name)
|
||||||
continue
|
continue
|
||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
values = [serial_escape('%s' % (v,)) for v in value]
|
values = [serial_escape('%s' % (v,)) for v in value]
|
||||||
|
@ -571,7 +569,7 @@ class Element(Node):
|
||||||
assert key.step in (None, 1), 'cannot handle slice with stride'
|
assert key.step in (None, 1), 'cannot handle slice with stride'
|
||||||
return self.children[key.start:key.stop]
|
return self.children[key.start:key.stop]
|
||||||
else:
|
else:
|
||||||
raise TypeError, ('element index must be an integer, a slice, or '
|
raise TypeError('element index must be an integer, a slice, or '
|
||||||
'an attribute name string')
|
'an attribute name string')
|
||||||
|
|
||||||
def __setitem__(self, key, item):
|
def __setitem__(self, key, item):
|
||||||
|
@ -586,7 +584,7 @@ class Element(Node):
|
||||||
self.setup_child(node)
|
self.setup_child(node)
|
||||||
self.children[key.start:key.stop] = item
|
self.children[key.start:key.stop] = item
|
||||||
else:
|
else:
|
||||||
raise TypeError, ('element index must be an integer, a slice, or '
|
raise TypeError('element index must be an integer, a slice, or '
|
||||||
'an attribute name string')
|
'an attribute name string')
|
||||||
|
|
||||||
def __delitem__(self, key):
|
def __delitem__(self, key):
|
||||||
|
@ -598,7 +596,7 @@ class Element(Node):
|
||||||
assert key.step in (None, 1), 'cannot handle slice with stride'
|
assert key.step in (None, 1), 'cannot handle slice with stride'
|
||||||
del self.children[key.start:key.stop]
|
del self.children[key.start:key.stop]
|
||||||
else:
|
else:
|
||||||
raise TypeError, ('element index must be an integer, a simple '
|
raise TypeError('element index must be an integer, a simple '
|
||||||
'slice, or an attribute name string')
|
'slice, or an attribute name string')
|
||||||
|
|
||||||
def __add__(self, other):
|
def __add__(self, other):
|
||||||
|
@ -954,7 +952,7 @@ class Element(Node):
|
||||||
'Losing "%s" attribute: %s' % (att, self[att])
|
'Losing "%s" attribute: %s' % (att, self[att])
|
||||||
self.parent.replace(self, new)
|
self.parent.replace(self, new)
|
||||||
|
|
||||||
def first_child_matching_class(self, childclass, start=0, end=sys.maxint):
|
def first_child_matching_class(self, childclass, start=0, end=sys.maxsize):
|
||||||
"""
|
"""
|
||||||
Return the index of the first child whose class exactly matches.
|
Return the index of the first child whose class exactly matches.
|
||||||
|
|
||||||
|
@ -974,7 +972,7 @@ class Element(Node):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def first_child_not_matching_class(self, childclass, start=0,
|
def first_child_not_matching_class(self, childclass, start=0,
|
||||||
end=sys.maxint):
|
end=sys.maxsize):
|
||||||
"""
|
"""
|
||||||
Return the index of the first child whose class does *not* match.
|
Return the index of the first child whose class does *not* match.
|
||||||
|
|
||||||
|
@ -1674,7 +1672,7 @@ class system_message(Special, BackLinkable, PreBibliographic, Element):
|
||||||
try:
|
try:
|
||||||
Element.__init__(self, '', *children, **attributes)
|
Element.__init__(self, '', *children, **attributes)
|
||||||
except:
|
except:
|
||||||
print 'system_message: children=%r' % (children,)
|
print('system_message: children=%r' % (children,))
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def astext(self):
|
def astext(self):
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: __init__.py 7598 2013-01-30 12:39:24Z milde $
|
# $Id: __init__.py 8068 2017-05-08 22:10:39Z milde $
|
||||||
# Author: David Goodger <goodger@python.org>
|
# Author: David Goodger <goodger@python.org>
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
@ -101,9 +101,9 @@ class Parser(docutils.parsers.Parser):
|
||||||
('Recognize and link to standalone RFC references (like "RFC 822").',
|
('Recognize and link to standalone RFC references (like "RFC 822").',
|
||||||
['--rfc-references'],
|
['--rfc-references'],
|
||||||
{'action': 'store_true', 'validator': frontend.validate_boolean}),
|
{'action': 'store_true', 'validator': frontend.validate_boolean}),
|
||||||
('Base URL for RFC references (default "http://www.faqs.org/rfcs/").',
|
('Base URL for RFC references (default "http://tools.ietf.org/html/").',
|
||||||
['--rfc-base-url'],
|
['--rfc-base-url'],
|
||||||
{'metavar': '<URL>', 'default': 'http://www.faqs.org/rfcs/',
|
{'metavar': '<URL>', 'default': 'http://tools.ietf.org/html/',
|
||||||
'validator': frontend.validate_url_trailing_slash}),
|
'validator': frontend.validate_url_trailing_slash}),
|
||||||
('Set number of spaces for tab expansion (default 8).',
|
('Set number of spaces for tab expansion (default 8).',
|
||||||
['--tab-width'],
|
['--tab-width'],
|
||||||
|
@ -141,7 +141,26 @@ class Parser(docutils.parsers.Parser):
|
||||||
('Change straight quotation marks to typographic form: '
|
('Change straight quotation marks to typographic form: '
|
||||||
'one of "yes", "no", "alt[ernative]" (default "no").',
|
'one of "yes", "no", "alt[ernative]" (default "no").',
|
||||||
['--smart-quotes'],
|
['--smart-quotes'],
|
||||||
{'default': False, 'validator': frontend.validate_ternary}),
|
{'default': False, 'metavar': '<yes/no/alt>',
|
||||||
|
'validator': frontend.validate_ternary}),
|
||||||
|
('Characters to use as "smart quotes" for <language>. ',
|
||||||
|
['--smartquotes-locales'],
|
||||||
|
{'metavar': '<language:quotes[,language:quotes,...]>',
|
||||||
|
'action': 'append',
|
||||||
|
'validator': frontend.validate_smartquotes_locales}),
|
||||||
|
('Inline markup recognized at word boundaries only '
|
||||||
|
'(adjacent to punctuation or whitespace). '
|
||||||
|
'Force character-level inline markup recognition with '
|
||||||
|
'"\\ " (backslash + space). Default.',
|
||||||
|
['--word-level-inline-markup'],
|
||||||
|
{'action': 'store_false', 'dest': 'character_level_inline_markup'}),
|
||||||
|
('Inline markup recognized anywhere, regardless of surrounding '
|
||||||
|
'characters. Backslash-escapes must be used to avoid unwanted '
|
||||||
|
'markup recognition. Useful for East Asian languages. '
|
||||||
|
'Experimental.',
|
||||||
|
['--character-level-inline-markup'],
|
||||||
|
{'action': 'store_true', 'default': False,
|
||||||
|
'dest': 'character_level_inline_markup'}),
|
||||||
))
|
))
|
||||||
|
|
||||||
config_section = 'restructuredtext parser'
|
config_section = 'restructuredtext parser'
|
||||||
|
@ -249,12 +268,6 @@ class Directive(object):
|
||||||
- ``lineno`` is the absolute line number of the first line
|
- ``lineno`` is the absolute line number of the first line
|
||||||
of the directive.
|
of the directive.
|
||||||
|
|
||||||
- ``src`` is the name (or path) of the rst source of the directive.
|
|
||||||
|
|
||||||
- ``srcline`` is the line number of the first line of the directive
|
|
||||||
in its source. It may differ from ``lineno``, if the main source
|
|
||||||
includes other sources with the ``.. include::`` directive.
|
|
||||||
|
|
||||||
- ``content_offset`` is the line offset of the first line of the content from
|
- ``content_offset`` is the line offset of the first line of the content from
|
||||||
the beginning of the current input. Used when initiating a nested parse.
|
the beginning of the current input. Used when initiating a nested parse.
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: __init__.py 7621 2013-03-04 13:20:49Z milde $
|
# $Id: __init__.py 8024 2017-02-06 00:41:48Z goodger $
|
||||||
# Author: David Goodger <goodger@python.org>
|
# Author: David Goodger <goodger@python.org>
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import codecs
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
from docutils.utils import split_escaped_whitespace, escape2null, unescape
|
||||||
from docutils.parsers.rst.languages import en as _fallback_language_module
|
from docutils.parsers.rst.languages import en as _fallback_language_module
|
||||||
if sys.version_info < (2,5):
|
if sys.version_info < (2,5):
|
||||||
from docutils._compat import __import__
|
from docutils._compat import __import__
|
||||||
|
@ -189,7 +190,7 @@ def path(argument):
|
||||||
|
|
||||||
def uri(argument):
|
def uri(argument):
|
||||||
"""
|
"""
|
||||||
Return the URI argument with whitespace removed.
|
Return the URI argument with unescaped whitespace removed.
|
||||||
(Directive option conversion function.)
|
(Directive option conversion function.)
|
||||||
|
|
||||||
Raise ``ValueError`` if no argument is found.
|
Raise ``ValueError`` if no argument is found.
|
||||||
|
@ -197,7 +198,8 @@ def uri(argument):
|
||||||
if argument is None:
|
if argument is None:
|
||||||
raise ValueError('argument required but none supplied')
|
raise ValueError('argument required but none supplied')
|
||||||
else:
|
else:
|
||||||
uri = ''.join(argument.split())
|
parts = split_escaped_whitespace(escape2null(argument))
|
||||||
|
uri = ' '.join(''.join(unescape(part).split()) for part in parts)
|
||||||
return uri
|
return uri
|
||||||
|
|
||||||
def nonnegative_int(argument):
|
def nonnegative_int(argument):
|
||||||
|
@ -402,3 +404,15 @@ def choice(argument, values):
|
||||||
def format_values(values):
|
def format_values(values):
|
||||||
return '%s, or "%s"' % (', '.join(['"%s"' % s for s in values[:-1]]),
|
return '%s, or "%s"' % (', '.join(['"%s"' % s for s in values[:-1]]),
|
||||||
values[-1])
|
values[-1])
|
||||||
|
|
||||||
|
def value_or(values, other):
|
||||||
|
"""
|
||||||
|
The argument can be any of `values` or `argument_type`.
|
||||||
|
"""
|
||||||
|
def auto_or_other(argument):
|
||||||
|
if argument in values:
|
||||||
|
return argument
|
||||||
|
else:
|
||||||
|
return other(argument)
|
||||||
|
return auto_or_other
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: misc.py 7487 2012-07-22 21:20:28Z milde $
|
# $Id: misc.py 7961 2016-07-28 22:02:47Z milde $
|
||||||
# Authors: David Goodger <goodger@python.org>; Dethe Elza
|
# Authors: David Goodger <goodger@python.org>; Dethe Elza
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
@ -231,7 +231,7 @@ class Raw(Directive):
|
||||||
raise self.severe(u'Problems with "%s" directive URL "%s":\n%s.'
|
raise self.severe(u'Problems with "%s" directive URL "%s":\n%s.'
|
||||||
% (self.name, self.options['url'], ErrorString(error)))
|
% (self.name, self.options['url'], ErrorString(error)))
|
||||||
raw_file = io.StringInput(source=raw_text, source_path=source,
|
raw_file = io.StringInput(source=raw_text, source_path=source,
|
||||||
encoding=encoding,
|
encoding=encoding,
|
||||||
error_handler=e_handler)
|
error_handler=e_handler)
|
||||||
try:
|
try:
|
||||||
text = raw_file.read()
|
text = raw_file.read()
|
||||||
|
@ -477,6 +477,24 @@ class Date(Directive):
|
||||||
except UnicodeEncodeError:
|
except UnicodeEncodeError:
|
||||||
raise self.warning(u'Cannot encode date format string '
|
raise self.warning(u'Cannot encode date format string '
|
||||||
u'with locale encoding "%s".' % locale_encoding)
|
u'with locale encoding "%s".' % locale_encoding)
|
||||||
|
# @@@
|
||||||
|
# Use timestamp from the `SOURCE_DATE_EPOCH`_ environment variable?
|
||||||
|
# Pro: Docutils-generated documentation
|
||||||
|
# can easily be part of `reproducible software builds`__
|
||||||
|
#
|
||||||
|
# __ https://reproducible-builds.org/
|
||||||
|
#
|
||||||
|
# Con: Changes the specs, hard to predict behaviour,
|
||||||
|
# no actual use case!
|
||||||
|
#
|
||||||
|
# See also the discussion about \date \time \year in TeX
|
||||||
|
# http://tug.org/pipermail/tex-k/2016-May/002704.html
|
||||||
|
# source_date_epoch = os.environ.get('SOURCE_DATE_EPOCH')
|
||||||
|
# if (source_date_epoch
|
||||||
|
# and self.state.document.settings.use_source_date_epoch):
|
||||||
|
# text = time.strftime(format_str,
|
||||||
|
# time.gmtime(int(source_date_epoch)))
|
||||||
|
# else:
|
||||||
text = time.strftime(format_str)
|
text = time.strftime(format_str)
|
||||||
if sys.version_info< (3, 0):
|
if sys.version_info< (3, 0):
|
||||||
# `text` is a byte string that may contain non-ASCII characters:
|
# `text` is a byte string that may contain non-ASCII characters:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: tables.py 7747 2014-03-20 10:51:10Z milde $
|
# $Id: tables.py 8039 2017-02-28 12:19:20Z milde $
|
||||||
# Authors: David Goodger <goodger@python.org>; David Priest
|
# Authors: David Goodger <goodger@python.org>; David Priest
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
@ -20,6 +20,10 @@ from docutils.parsers.rst import Directive
|
||||||
from docutils.parsers.rst import directives
|
from docutils.parsers.rst import directives
|
||||||
|
|
||||||
|
|
||||||
|
def align(argument):
|
||||||
|
return directives.choice(argument, ('left', 'center', 'right'))
|
||||||
|
|
||||||
|
|
||||||
class Table(Directive):
|
class Table(Directive):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -29,7 +33,10 @@ class Table(Directive):
|
||||||
optional_arguments = 1
|
optional_arguments = 1
|
||||||
final_argument_whitespace = True
|
final_argument_whitespace = True
|
||||||
option_spec = {'class': directives.class_option,
|
option_spec = {'class': directives.class_option,
|
||||||
'name': directives.unchanged}
|
'name': directives.unchanged,
|
||||||
|
'align': align,
|
||||||
|
'widths': directives.value_or(('auto', 'grid'),
|
||||||
|
directives.positive_int_list)}
|
||||||
has_content = True
|
has_content = True
|
||||||
|
|
||||||
def make_title(self):
|
def make_title(self):
|
||||||
|
@ -38,6 +45,8 @@ class Table(Directive):
|
||||||
text_nodes, messages = self.state.inline_text(title_text,
|
text_nodes, messages = self.state.inline_text(title_text,
|
||||||
self.lineno)
|
self.lineno)
|
||||||
title = nodes.title(title_text, '', *text_nodes)
|
title = nodes.title(title_text, '', *text_nodes)
|
||||||
|
(title.source,
|
||||||
|
title.line) = self.state_machine.get_source_and_line(self.lineno)
|
||||||
else:
|
else:
|
||||||
title = None
|
title = None
|
||||||
messages = []
|
messages = []
|
||||||
|
@ -85,15 +94,19 @@ class Table(Directive):
|
||||||
self.block_text, self.block_text), line=self.lineno)
|
self.block_text, self.block_text), line=self.lineno)
|
||||||
raise SystemMessagePropagation(error)
|
raise SystemMessagePropagation(error)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def widths(self):
|
||||||
|
return self.options.get('widths', '')
|
||||||
|
|
||||||
def get_column_widths(self, max_cols):
|
def get_column_widths(self, max_cols):
|
||||||
if 'widths' in self.options:
|
if type(self.widths) == list:
|
||||||
col_widths = self.options['widths']
|
if len(self.widths) != max_cols:
|
||||||
if len(col_widths) != max_cols:
|
|
||||||
error = self.state_machine.reporter.error(
|
error = self.state_machine.reporter.error(
|
||||||
'"%s" widths do not match the number of columns in table '
|
'"%s" widths do not match the number of columns in table '
|
||||||
'(%s).' % (self.name, max_cols), nodes.literal_block(
|
'(%s).' % (self.name, max_cols), nodes.literal_block(
|
||||||
self.block_text, self.block_text), line=self.lineno)
|
self.block_text, self.block_text), line=self.lineno)
|
||||||
raise SystemMessagePropagation(error)
|
raise SystemMessagePropagation(error)
|
||||||
|
col_widths = self.widths
|
||||||
elif max_cols:
|
elif max_cols:
|
||||||
col_widths = [100 // max_cols] * max_cols
|
col_widths = [100 // max_cols] * max_cols
|
||||||
else:
|
else:
|
||||||
|
@ -130,6 +143,21 @@ class RSTTable(Table):
|
||||||
return [error]
|
return [error]
|
||||||
table_node = node[0]
|
table_node = node[0]
|
||||||
table_node['classes'] += self.options.get('class', [])
|
table_node['classes'] += self.options.get('class', [])
|
||||||
|
if 'align' in self.options:
|
||||||
|
table_node['align'] = self.options.get('align')
|
||||||
|
tgroup = table_node[0]
|
||||||
|
if type(self.widths) == list:
|
||||||
|
colspecs = [child for child in tgroup.children
|
||||||
|
if child.tagname == 'colspec']
|
||||||
|
for colspec, col_width in zip(colspecs, self.widths):
|
||||||
|
colspec['colwidth'] = col_width
|
||||||
|
# @@@ the colwidths argument for <tgroup> is not part of the
|
||||||
|
# XML Exchange Table spec (https://www.oasis-open.org/specs/tm9901.htm)
|
||||||
|
# and hence violates the docutils.dtd.
|
||||||
|
if self.widths == 'auto':
|
||||||
|
table_node['classes'] += ['colwidths-auto']
|
||||||
|
elif self.widths: # "grid" or list of integers
|
||||||
|
table_node['classes'] += ['colwidths-given']
|
||||||
self.add_name(table_node)
|
self.add_name(table_node)
|
||||||
if title:
|
if title:
|
||||||
table_node.insert(0, title)
|
table_node.insert(0, title)
|
||||||
|
@ -141,12 +169,14 @@ class CSVTable(Table):
|
||||||
option_spec = {'header-rows': directives.nonnegative_int,
|
option_spec = {'header-rows': directives.nonnegative_int,
|
||||||
'stub-columns': directives.nonnegative_int,
|
'stub-columns': directives.nonnegative_int,
|
||||||
'header': directives.unchanged,
|
'header': directives.unchanged,
|
||||||
'widths': directives.positive_int_list,
|
'widths': directives.value_or(('auto', ),
|
||||||
|
directives.positive_int_list),
|
||||||
'file': directives.path,
|
'file': directives.path,
|
||||||
'url': directives.uri,
|
'url': directives.uri,
|
||||||
'encoding': directives.encoding,
|
'encoding': directives.encoding,
|
||||||
'class': directives.class_option,
|
'class': directives.class_option,
|
||||||
'name': directives.unchanged,
|
'name': directives.unchanged,
|
||||||
|
'align': align,
|
||||||
# field delimiter char
|
# field delimiter char
|
||||||
'delim': directives.single_char_or_whitespace_or_unicode,
|
'delim': directives.single_char_or_whitespace_or_unicode,
|
||||||
# treat whitespace after delimiter as significant
|
# treat whitespace after delimiter as significant
|
||||||
|
@ -235,8 +265,10 @@ class CSVTable(Table):
|
||||||
return [error]
|
return [error]
|
||||||
table = (col_widths, table_head, table_body)
|
table = (col_widths, table_head, table_body)
|
||||||
table_node = self.state.build_table(table, self.content_offset,
|
table_node = self.state.build_table(table, self.content_offset,
|
||||||
stub_columns)
|
stub_columns, widths=self.widths)
|
||||||
table_node['classes'] += self.options.get('class', [])
|
table_node['classes'] += self.options.get('class', [])
|
||||||
|
if 'align' in self.options:
|
||||||
|
table_node['align'] = self.options.get('align')
|
||||||
self.add_name(table_node)
|
self.add_name(table_node)
|
||||||
if title:
|
if title:
|
||||||
table_node.insert(0, title)
|
table_node.insert(0, title)
|
||||||
|
@ -356,13 +388,15 @@ class ListTable(Table):
|
||||||
Implement tables whose data is encoded as a uniform two-level bullet list.
|
Implement tables whose data is encoded as a uniform two-level bullet list.
|
||||||
For further ideas, see
|
For further ideas, see
|
||||||
http://docutils.sf.net/docs/dev/rst/alternatives.html#list-driven-tables
|
http://docutils.sf.net/docs/dev/rst/alternatives.html#list-driven-tables
|
||||||
"""
|
"""
|
||||||
|
|
||||||
option_spec = {'header-rows': directives.nonnegative_int,
|
option_spec = {'header-rows': directives.nonnegative_int,
|
||||||
'stub-columns': directives.nonnegative_int,
|
'stub-columns': directives.nonnegative_int,
|
||||||
'widths': directives.positive_int_list,
|
'widths': directives.value_or(('auto', ),
|
||||||
|
directives.positive_int_list),
|
||||||
'class': directives.class_option,
|
'class': directives.class_option,
|
||||||
'name': directives.unchanged}
|
'name': directives.unchanged,
|
||||||
|
'align': align}
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
if not self.content:
|
if not self.content:
|
||||||
|
@ -385,6 +419,8 @@ class ListTable(Table):
|
||||||
return [detail.args[0]]
|
return [detail.args[0]]
|
||||||
table_node = self.build_table_from_list(table_data, col_widths,
|
table_node = self.build_table_from_list(table_data, col_widths,
|
||||||
header_rows, stub_columns)
|
header_rows, stub_columns)
|
||||||
|
if 'align' in self.options:
|
||||||
|
table_node['align'] = self.options.get('align')
|
||||||
table_node['classes'] += self.options.get('class', [])
|
table_node['classes'] += self.options.get('class', [])
|
||||||
self.add_name(table_node)
|
self.add_name(table_node)
|
||||||
if title:
|
if title:
|
||||||
|
@ -432,10 +468,16 @@ class ListTable(Table):
|
||||||
|
|
||||||
def build_table_from_list(self, table_data, col_widths, header_rows, stub_columns):
|
def build_table_from_list(self, table_data, col_widths, header_rows, stub_columns):
|
||||||
table = nodes.table()
|
table = nodes.table()
|
||||||
|
if self.widths == 'auto':
|
||||||
|
table['classes'] += ['colwidths-auto']
|
||||||
|
elif self.widths: # "grid" or list of integers
|
||||||
|
table['classes'] += ['colwidths-given']
|
||||||
tgroup = nodes.tgroup(cols=len(col_widths))
|
tgroup = nodes.tgroup(cols=len(col_widths))
|
||||||
table += tgroup
|
table += tgroup
|
||||||
for col_width in col_widths:
|
for col_width in col_widths:
|
||||||
colspec = nodes.colspec(colwidth=col_width)
|
colspec = nodes.colspec()
|
||||||
|
if col_width is not None:
|
||||||
|
colspec.attributes['colwidth'] = col_width
|
||||||
if stub_columns:
|
if stub_columns:
|
||||||
colspec.attributes['stub'] = 1
|
colspec.attributes['stub'] = 1
|
||||||
stub_columns -= 1
|
stub_columns -= 1
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# $Id: de.py 7223 2011-11-21 16:43:06Z milde $
|
# $Id: de.py 8006 2016-12-22 23:02:44Z milde $
|
||||||
# Authors: Engelbert Gruber <grubert@users.sourceforge.net>;
|
# Authors: Engelbert Gruber <grubert@users.sourceforge.net>;
|
||||||
# Lea Wiemann <LeWiemann@gmail.com>
|
# Lea Wiemann <LeWiemann@gmail.com>
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
@ -30,13 +30,14 @@ directives = {
|
||||||
'warnung': 'warning',
|
'warnung': 'warning',
|
||||||
'ermahnung': 'admonition',
|
'ermahnung': 'admonition',
|
||||||
'kasten': 'sidebar',
|
'kasten': 'sidebar',
|
||||||
'seitenkasten': 'sidebar',
|
'seitenkasten': 'sidebar', # kept for backwards compatibiltity
|
||||||
|
'seitenleiste': 'sidebar',
|
||||||
'thema': 'topic',
|
'thema': 'topic',
|
||||||
'zeilen-block': 'line-block',
|
'zeilenblock': 'line-block',
|
||||||
'parsed-literal (translation required)': 'parsed-literal',
|
'parsed-literal (translation required)': 'parsed-literal',
|
||||||
'rubrik': 'rubric',
|
'rubrik': 'rubric',
|
||||||
'epigraph': 'epigraph',
|
'epigraph': 'epigraph',
|
||||||
'highlights (translation required)': 'highlights',
|
'highlights': 'highlights',
|
||||||
u'pull-quote': 'pull-quote', # commonly used in German too
|
u'pull-quote': 'pull-quote', # commonly used in German too
|
||||||
u'seitenansprache': 'pull-quote', # cf. http://www.typografie.info/2/wiki.php?title=Seitenansprache
|
u'seitenansprache': 'pull-quote', # cf. http://www.typografie.info/2/wiki.php?title=Seitenansprache
|
||||||
'zusammengesetzt': 'compound',
|
'zusammengesetzt': 'compound',
|
||||||
|
@ -45,7 +46,7 @@ directives = {
|
||||||
#'fragen': 'questions',
|
#'fragen': 'questions',
|
||||||
'tabelle': 'table',
|
'tabelle': 'table',
|
||||||
'csv-tabelle': 'csv-table',
|
'csv-tabelle': 'csv-table',
|
||||||
'list-table (translation required)': 'list-table',
|
'listentabelle': 'list-table',
|
||||||
u'mathe': 'math',
|
u'mathe': 'math',
|
||||||
u'formel': 'math',
|
u'formel': 'math',
|
||||||
'meta': 'meta',
|
'meta': 'meta',
|
||||||
|
@ -62,14 +63,14 @@ directives = {
|
||||||
'datum': 'date',
|
'datum': 'date',
|
||||||
'klasse': 'class',
|
'klasse': 'class',
|
||||||
'rolle': 'role',
|
'rolle': 'role',
|
||||||
u'default-role (translation required)': 'default-role',
|
u'standardrolle': 'default-role',
|
||||||
u'title (translation required)': 'title',
|
u'titel': 'title',
|
||||||
'inhalt': 'contents',
|
'inhalt': 'contents',
|
||||||
'kapitel-nummerierung': 'sectnum',
|
u'kapitelnummerierung': 'sectnum',
|
||||||
'abschnitts-nummerierung': 'sectnum',
|
u'abschnittsnummerierung': 'sectnum',
|
||||||
u'linkziel-fußfnoten': 'target-notes',
|
u'linkziel-fußnoten': 'target-notes',
|
||||||
u'header (translation required)': 'header',
|
u'kopfzeilen': 'header',
|
||||||
u'footer (translation required)': 'footer',
|
u'fußzeilen': 'footer',
|
||||||
#u'fußfnoten': 'footnotes',
|
#u'fußfnoten': 'footnotes',
|
||||||
#'zitate': 'citations',
|
#'zitate': 'citations',
|
||||||
}
|
}
|
||||||
|
@ -86,7 +87,8 @@ roles = {
|
||||||
'titel-referenz': 'title-reference',
|
'titel-referenz': 'title-reference',
|
||||||
'pep-referenz': 'pep-reference',
|
'pep-referenz': 'pep-reference',
|
||||||
'rfc-referenz': 'rfc-reference',
|
'rfc-referenz': 'rfc-reference',
|
||||||
'betonung': 'emphasis',
|
'betonung': 'emphasis', # for backwards compatibility
|
||||||
|
'betont': 'emphasis',
|
||||||
'fett': 'strong',
|
'fett': 'strong',
|
||||||
u'wörtlich': 'literal',
|
u'wörtlich': 'literal',
|
||||||
u'mathe': 'math',
|
u'mathe': 'math',
|
||||||
|
|
102
Libs/docutils/parsers/rst/languages/fa.py
Normal file
102
Libs/docutils/parsers/rst/languages/fa.py
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# $Id: fa.py 4564 2016-08-10 11:48:42Z
|
||||||
|
# Author: Shahin <me@5hah.in>
|
||||||
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
# New language mappings are welcome. Before doing a new translation, please
|
||||||
|
# read <http://docutils.sf.net/docs/howto/i18n.html>. Two files must be
|
||||||
|
# translated for each language: one in docutils/languages, the other in
|
||||||
|
# docutils/parsers/rst/languages.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Persian-language mappings for language-dependent features of
|
||||||
|
reStructuredText.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__docformat__ = 'reStructuredText'
|
||||||
|
|
||||||
|
|
||||||
|
directives = {
|
||||||
|
# language-dependent: fixed
|
||||||
|
u'توجه': u'attention',
|
||||||
|
u'احتیاط': u'caution',
|
||||||
|
u'کد': u'code',
|
||||||
|
u'بلوک-کد': u'code',
|
||||||
|
u'کد-منبع': u'code',
|
||||||
|
u'خطر': u'danger',
|
||||||
|
u'خطا': u'error',
|
||||||
|
u'راهنما': u'hint',
|
||||||
|
u'مهم': u'important',
|
||||||
|
u'یادداشت': u'note',
|
||||||
|
u'نکته': u'tip',
|
||||||
|
u'اخطار': u'warning',
|
||||||
|
u'تذکر': u'admonition',
|
||||||
|
u'نوار-کناری': u'sidebar',
|
||||||
|
u'موضوع': u'topic',
|
||||||
|
u'بلوک-خط': u'line-block',
|
||||||
|
u'تلفظ-پردازش-شده': u'parsed-literal',
|
||||||
|
u'سر-فصل': u'rubric',
|
||||||
|
u'کتیبه': u'epigraph',
|
||||||
|
u'نکات-برجسته': u'highlights',
|
||||||
|
u'نقل-قول': u'pull-quote',
|
||||||
|
u'ترکیب': u'compound',
|
||||||
|
u'ظرف': u'container',
|
||||||
|
#'questions': u'questions',
|
||||||
|
u'جدول': u'table',
|
||||||
|
u'جدول-csv': u'csv-table',
|
||||||
|
u'جدول-لیست': u'list-table',
|
||||||
|
#'qa': u'questions',
|
||||||
|
#'faq': u'questions',
|
||||||
|
u'متا': u'meta',
|
||||||
|
u'ریاضی': u'math',
|
||||||
|
#'imagemap': u'imagemap',
|
||||||
|
u'تصویر': u'image',
|
||||||
|
u'شکل': u'figure',
|
||||||
|
u'شامل': u'include',
|
||||||
|
u'خام': u'raw',
|
||||||
|
u'جایگزین': u'replace',
|
||||||
|
u'یونیکد': u'unicode',
|
||||||
|
u'تاریخ': u'date',
|
||||||
|
u'کلاس': u'class',
|
||||||
|
u'قانون': u'role',
|
||||||
|
u'قانون-پیشفرض': u'default-role',
|
||||||
|
u'عنوان': u'title',
|
||||||
|
u'محتوا': u'contents',
|
||||||
|
u'شماره-فصل': u'sectnum',
|
||||||
|
u'شمارهگذاری-فصل': u'sectnum',
|
||||||
|
u'سرآیند': u'header',
|
||||||
|
u'پاصفحه': u'footer',
|
||||||
|
#'footnotes': u'footnotes',
|
||||||
|
#'citations': u'citations',
|
||||||
|
u'یادداشت-هدف': u'target-notes',
|
||||||
|
}
|
||||||
|
"""Persian name to registered (in directives/__init__.py) directive name
|
||||||
|
mapping."""
|
||||||
|
|
||||||
|
roles = {
|
||||||
|
# language-dependent: fixed
|
||||||
|
u'مخفف': u'abbreviation',
|
||||||
|
u'سرنام': u'acronym',
|
||||||
|
u'کد': u'code',
|
||||||
|
u'شاخص': u'index',
|
||||||
|
u'زیرنویس': u'subscript',
|
||||||
|
u'بالانویس': u'superscript',
|
||||||
|
u'عنوان': u'title-reference',
|
||||||
|
u'نیرو': u'pep-reference',
|
||||||
|
u'rfc-reference (translation required)': u'rfc-reference',
|
||||||
|
u'تاکید': u'emphasis',
|
||||||
|
u'قوی': u'strong',
|
||||||
|
u'لفظی': u'literal',
|
||||||
|
u'ریاضی': u'math',
|
||||||
|
u'منبع-نامگذاری': u'named-reference',
|
||||||
|
u'منبع-ناشناس': u'anonymous-reference',
|
||||||
|
u'منبع-پانویس': u'footnote-reference',
|
||||||
|
u'منبع-نقلفول': u'citation-reference',
|
||||||
|
u'منبع-جایگزینی': u'substitution-reference',
|
||||||
|
u'هدف': u'target',
|
||||||
|
u'منبع-uri': u'uri-reference',
|
||||||
|
u'uri': u'uri-reference',
|
||||||
|
u'url': u'uri-reference',
|
||||||
|
u'خام': u'raw',}
|
||||||
|
"""Mapping of Persian role names to canonical role names for interpreted text.
|
||||||
|
"""
|
108
Libs/docutils/parsers/rst/languages/lv.py
Normal file
108
Libs/docutils/parsers/rst/languages/lv.py
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# $Id: lv.py 7975 2016-10-20 20:00:19Z milde $
|
||||||
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
# New language mappings are welcome. Before doing a new translation, please
|
||||||
|
# read <http://docutils.sf.net/docs/howto/i18n.html>. Two files must be
|
||||||
|
# translated for each language: one in docutils/languages, the other in
|
||||||
|
# docutils/parsers/rst/languages.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Latvian-language mappings for language-dependent features of
|
||||||
|
reStructuredText.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__docformat__ = 'reStructuredText'
|
||||||
|
|
||||||
|
|
||||||
|
directives = {
|
||||||
|
# language-dependent: fixed
|
||||||
|
'uzmanību': 'attention',
|
||||||
|
'piesardzību': 'caution',
|
||||||
|
'kods': 'code',
|
||||||
|
'koda-bloks': 'code',
|
||||||
|
'pirmkods': 'code',
|
||||||
|
'bīstami': 'danger',
|
||||||
|
'kļūda': 'error',
|
||||||
|
'ieteikums': 'hint',
|
||||||
|
'svarīgi': 'important',
|
||||||
|
'piezīme': 'note',
|
||||||
|
'padoms': 'tip',
|
||||||
|
'brīdinājums': 'warning',
|
||||||
|
'aizrādījums': 'admonition',
|
||||||
|
'sānjosla': 'sidebar',
|
||||||
|
'tēma': 'topic',
|
||||||
|
'rindu-bloks': 'line-block',
|
||||||
|
'parsēts-literālis': 'parsed-literal',
|
||||||
|
'rubrika': 'rubric',
|
||||||
|
'epigrāfs': 'epigraph',
|
||||||
|
'apskats': 'highlights',
|
||||||
|
'izvilkuma-citāts': 'pull-quote',
|
||||||
|
'savienojums': 'compound',
|
||||||
|
'konteiners': 'container',
|
||||||
|
#'questions': 'questions',
|
||||||
|
'tabula': 'table',
|
||||||
|
'csv-tabula': 'csv-table',
|
||||||
|
'sarakstveida-tabula': 'list-table',
|
||||||
|
#'qa': 'questions',
|
||||||
|
#'faq': 'questions',
|
||||||
|
'meta': 'meta',
|
||||||
|
'matemātika': 'math',
|
||||||
|
#'imagemap': 'imagemap',
|
||||||
|
'attēls': 'image',
|
||||||
|
'figūra': 'figure',
|
||||||
|
'ietvert': 'include',
|
||||||
|
'burtiski': 'raw',
|
||||||
|
'aizvieto': 'replace',
|
||||||
|
'unicode': 'unicode',
|
||||||
|
'datums': 'date',
|
||||||
|
'klase': 'class',
|
||||||
|
'role': 'role',
|
||||||
|
'noklusējuma-role': 'default-role',
|
||||||
|
'virsraksts': 'title',
|
||||||
|
'saturs': 'contents',
|
||||||
|
'numurēt-sekcijas': 'sectnum',
|
||||||
|
'galvene': 'header',
|
||||||
|
'kājene': 'footer',
|
||||||
|
#'footnotes': 'footnotes',
|
||||||
|
#'citations': 'citations',
|
||||||
|
'atsauces-apakšā': 'target-notes',
|
||||||
|
'restructuredtext-testa-direktīva': 'restructuredtext-test-directive'}
|
||||||
|
"""English name to registered (in directives/__init__.py) directive name
|
||||||
|
mapping."""
|
||||||
|
|
||||||
|
roles = {
|
||||||
|
# language-dependent: fixed
|
||||||
|
'saīsinājums': 'abbreviation',
|
||||||
|
'īsi': 'abbreviation',
|
||||||
|
'akronīms': 'acronym',
|
||||||
|
'kods': 'code',
|
||||||
|
'indekss': 'index',
|
||||||
|
'i': 'index',
|
||||||
|
'apakšraksts': 'subscript',
|
||||||
|
'apakšā': 'subscript',
|
||||||
|
'augšraksts': 'superscript',
|
||||||
|
'augšā': 'superscript',
|
||||||
|
'virsraksta-atsauce': 'title-reference',
|
||||||
|
'virsraksts': 'title-reference',
|
||||||
|
'v': 'title-reference',
|
||||||
|
'atsauce-uz-pep': 'pep-reference',
|
||||||
|
'pep': 'pep-reference',
|
||||||
|
'atsauce-uz-rfc': 'rfc-reference',
|
||||||
|
'rfc': 'rfc-reference',
|
||||||
|
'izcēlums': 'emphasis',
|
||||||
|
'blīvs': 'strong',
|
||||||
|
'literālis': 'literal',
|
||||||
|
'matemātika': 'math',
|
||||||
|
'nosaukta-atsauce': 'named-reference',
|
||||||
|
'nenosaukta-atsauce': 'anonymous-reference',
|
||||||
|
'kājenes-atsauce': 'footnote-reference',
|
||||||
|
'citātā-atsauce': 'citation-reference',
|
||||||
|
'aizvietojuma-atsauce': 'substitution-reference',
|
||||||
|
'mēr''kis': 'target',
|
||||||
|
'atsauce-uz-uri': 'uri-reference',
|
||||||
|
'uri': 'uri-reference',
|
||||||
|
'url': 'uri-reference',
|
||||||
|
'burtiski': 'raw',}
|
||||||
|
"""Mapping of English role names to canonical role names for interpreted text.
|
||||||
|
"""
|
|
@ -1,4 +1,5 @@
|
||||||
# $Id: sv.py 7119 2011-09-02 13:00:23Z milde $
|
# -*- coding: utf-8 -*-
|
||||||
|
# $Id: sv.py 8012 2017-01-03 23:08:19Z milde $
|
||||||
# Author: Adam Chodorowski <chodorowski@users.sourceforge.net>
|
# Author: Adam Chodorowski <chodorowski@users.sourceforge.net>
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
@ -13,55 +14,55 @@ Swedish language mappings for language-dependent features of reStructuredText.
|
||||||
|
|
||||||
__docformat__ = 'reStructuredText'
|
__docformat__ = 'reStructuredText'
|
||||||
|
|
||||||
|
|
||||||
directives = {
|
directives = {
|
||||||
u'observera': 'attention',
|
u'observera': 'attention',
|
||||||
u'caution (translation required)': 'caution',
|
u'akta': 'caution', # also 'försiktigt'
|
||||||
u'code (translation required)': 'code',
|
u'kod': 'code',
|
||||||
u'fara': 'danger',
|
u'fara': 'danger',
|
||||||
u'fel': 'error',
|
u'fel': 'error',
|
||||||
u'v\u00e4gledning': 'hint',
|
u'vink': 'hint', # also 'hint'
|
||||||
u'viktigt': 'important',
|
u'viktigt': 'important',
|
||||||
u'notera': 'note',
|
u'notera': 'note',
|
||||||
u'tips': 'tip',
|
u'tips': 'tip',
|
||||||
u'varning': 'warning',
|
u'varning': 'warning',
|
||||||
u'admonition (translation required)': 'admonition',
|
u'anmärkning': 'admonition', # literal 'tillrättavisning', 'förmaning'
|
||||||
u'sidebar (translation required)': 'sidebar',
|
u'sidorad': 'sidebar',
|
||||||
u'\u00e4mne': 'topic',
|
u'ämne': 'topic',
|
||||||
u'line-block (translation required)': 'line-block',
|
u'tema': 'topic',
|
||||||
u'parsed-literal (translation required)': 'parsed-literal',
|
u'rad-block': 'line-block',
|
||||||
u'mellanrubrik': 'rubric',
|
u'parsed-literal (translation required)': 'parsed-literal', # 'tolkad-bokstavlig'?
|
||||||
u'epigraph (translation required)': 'epigraph',
|
u'rubrik': 'rubric',
|
||||||
u'highlights (translation required)': 'highlights',
|
u'epigraf': 'epigraph',
|
||||||
|
u'höjdpunkter': 'highlights',
|
||||||
u'pull-quote (translation required)': 'pull-quote',
|
u'pull-quote (translation required)': 'pull-quote',
|
||||||
u'compound (translation required)': 'compound',
|
u'sammansatt': 'compound',
|
||||||
u'container (translation required)': 'container',
|
u'container': 'container',
|
||||||
# u'fr\u00e5gor': 'questions',
|
# u'frågor': 'questions',
|
||||||
# NOTE: A bit long, but recommended by http://www.nada.kth.se/dataterm/:
|
# NOTE: A bit long, but recommended by http://www.nada.kth.se/dataterm/:
|
||||||
# u'fr\u00e5gor-och-svar': 'questions',
|
# u'frågor-och-svar': 'questions',
|
||||||
# u'vanliga-fr\u00e5gor': 'questions',
|
# u'vanliga-frågor': 'questions',
|
||||||
u'table (translation required)': 'table',
|
u'tabell': 'table',
|
||||||
u'csv-table (translation required)': 'csv-table',
|
u'csv-tabell': 'csv-table',
|
||||||
u'list-table (translation required)': 'list-table',
|
u'list-tabell': 'list-table',
|
||||||
u'meta': 'meta',
|
u'meta': 'meta',
|
||||||
'math (translation required)': 'math',
|
u'matematik': 'math',
|
||||||
# u'bildkarta': 'imagemap', # FIXME: Translation might be too literal.
|
# u'bildkarta': 'imagemap', # FIXME: Translation might be too literal.
|
||||||
u'bild': 'image',
|
u'bild': 'image',
|
||||||
u'figur': 'figure',
|
u'figur': 'figure',
|
||||||
u'inkludera': 'include',
|
u'inkludera': 'include',
|
||||||
u'r\u00e5': 'raw', # FIXME: Translation might be too literal.
|
u'rå': 'raw',
|
||||||
u'ers\u00e4tt': 'replace',
|
u'ersätta': 'replace',
|
||||||
u'unicode': 'unicode',
|
u'unicode': 'unicode',
|
||||||
u'datum': 'date',
|
u'datum': 'date',
|
||||||
u'class (translation required)': 'class',
|
u'klass': 'class',
|
||||||
u'role (translation required)': 'role',
|
u'roll': 'role',
|
||||||
u'default-role (translation required)': 'default-role',
|
u'standardroll': 'default-role',
|
||||||
u'title (translation required)': 'title',
|
u'titel': 'title',
|
||||||
u'inneh\u00e5ll': 'contents',
|
u'innehåll': 'contents',
|
||||||
u'sektionsnumrering': 'sectnum',
|
u'sektionsnumrering': 'sectnum',
|
||||||
u'target-notes (translation required)': 'target-notes',
|
u'target-notes (translation required)': 'target-notes',
|
||||||
u'header (translation required)': 'header',
|
u'sidhuvud': 'header',
|
||||||
u'footer (translation required)': 'footer',
|
u'sidfot': 'footer',
|
||||||
# u'fotnoter': 'footnotes',
|
# u'fotnoter': 'footnotes',
|
||||||
# u'citeringar': 'citations',
|
# u'citeringar': 'citations',
|
||||||
}
|
}
|
||||||
|
@ -69,26 +70,26 @@ directives = {
|
||||||
mapping."""
|
mapping."""
|
||||||
|
|
||||||
roles = {
|
roles = {
|
||||||
u'abbreviation (translation required)': 'abbreviation',
|
u'förkortning': 'abbreviation',
|
||||||
u'acronym (translation required)': 'acronym',
|
u'akronym': 'acronym',
|
||||||
u'code (translation required)': 'code',
|
u'kod': 'code',
|
||||||
u'index (translation required)': 'index',
|
u'index': 'index',
|
||||||
u'subscript (translation required)': 'subscript',
|
u'nedsänkt': 'subscript',
|
||||||
u'superscript (translation required)': 'superscript',
|
u'upphöjd': 'superscript',
|
||||||
u'title-reference (translation required)': 'title-reference',
|
u'titel-referens': 'title-reference',
|
||||||
u'pep-reference (translation required)': 'pep-reference',
|
u'pep-referens': 'pep-reference',
|
||||||
u'rfc-reference (translation required)': 'rfc-reference',
|
u'rfc-referens': 'rfc-reference',
|
||||||
u'emphasis (translation required)': 'emphasis',
|
u'betoning': 'emphasis',
|
||||||
u'strong (translation required)': 'strong',
|
u'stark': 'strong',
|
||||||
u'literal (translation required)': 'literal',
|
u'bokstavlig': 'literal', # also 'ordagranna'
|
||||||
'math (translation required)': 'math',
|
u'matematik': 'math',
|
||||||
u'named-reference (translation required)': 'named-reference',
|
u'namngiven-referens': 'named-reference',
|
||||||
u'anonymous-reference (translation required)': 'anonymous-reference',
|
u'anonym-referens': 'anonymous-reference',
|
||||||
u'footnote-reference (translation required)': 'footnote-reference',
|
u'fotnot-referens': 'footnote-reference',
|
||||||
u'citation-reference (translation required)': 'citation-reference',
|
u'citat-referens': 'citation-reference',
|
||||||
u'substitution-reference (translation required)': 'substitution-reference',
|
u'ersättnings-referens': 'substitution-reference',
|
||||||
u'target (translation required)': 'target',
|
u'mål': 'target',
|
||||||
u'uri-reference (translation required)': 'uri-reference',
|
u'uri-referens': 'uri-reference',
|
||||||
u'r\u00e5': 'raw',}
|
u'rå': 'raw',}
|
||||||
"""Mapping of Swedish role names to canonical role names for interpreted text.
|
"""Mapping of Swedish role names to canonical role names for interpreted text.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: roles.py 7514 2012-09-14 14:27:12Z milde $
|
# $Id: roles.py 7937 2016-05-24 10:48:48Z milde $
|
||||||
# Author: Edward Loper <edloper@gradient.cis.upenn.edu>
|
# Author: Edward Loper <edloper@gradient.cis.upenn.edu>
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
@ -334,7 +334,7 @@ def code_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||||
|
|
||||||
node = nodes.literal(rawtext, '', classes=classes)
|
node = nodes.literal(rawtext, '', classes=classes)
|
||||||
|
|
||||||
# analyze content and add nodes for every token
|
# analyse content and add nodes for every token
|
||||||
for classes, value in tokens:
|
for classes, value in tokens:
|
||||||
# print (classes, value)
|
# print (classes, value)
|
||||||
if classes:
|
if classes:
|
||||||
|
@ -351,9 +351,10 @@ code_role.options = {'class': directives.class_option,
|
||||||
register_canonical_role('code', code_role)
|
register_canonical_role('code', code_role)
|
||||||
|
|
||||||
def math_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
|
def math_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||||
|
set_classes(options)
|
||||||
i = rawtext.find('`')
|
i = rawtext.find('`')
|
||||||
text = rawtext.split('`')[1]
|
text = rawtext.split('`')[1]
|
||||||
node = nodes.math(rawtext, text)
|
node = nodes.math(rawtext, text, **options)
|
||||||
return [node], []
|
return [node], []
|
||||||
|
|
||||||
register_canonical_role('math', math_role)
|
register_canonical_role('math', math_role)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: states.py 7640 2013-03-25 20:57:52Z milde $
|
# $Id: states.py 8060 2017-04-19 20:00:04Z milde $
|
||||||
# Author: David Goodger <goodger@python.org>
|
# Author: David Goodger <goodger@python.org>
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
@ -117,6 +117,7 @@ from docutils.parsers.rst import directives, languages, tableparser, roles
|
||||||
from docutils.parsers.rst.languages import en as _fallback_language_module
|
from docutils.parsers.rst.languages import en as _fallback_language_module
|
||||||
from docutils.utils import escape2null, unescape, column_width
|
from docutils.utils import escape2null, unescape, column_width
|
||||||
from docutils.utils import punctuation_chars, roman, urischemes
|
from docutils.utils import punctuation_chars, roman, urischemes
|
||||||
|
from docutils.utils import split_escaped_whitespace
|
||||||
|
|
||||||
class MarkupError(DataError): pass
|
class MarkupError(DataError): pass
|
||||||
class UnknownInterpretedRoleError(DataError): pass
|
class UnknownInterpretedRoleError(DataError): pass
|
||||||
|
@ -225,7 +226,6 @@ class RSTState(StateWS):
|
||||||
# enable the reporter to determine source and source-line
|
# enable the reporter to determine source and source-line
|
||||||
if not hasattr(self.reporter, 'get_source_and_line'):
|
if not hasattr(self.reporter, 'get_source_and_line'):
|
||||||
self.reporter.get_source_and_line = self.state_machine.get_source_and_line
|
self.reporter.get_source_and_line = self.state_machine.get_source_and_line
|
||||||
# print "adding get_source_and_line to reporter", self.state_machine.input_offset
|
|
||||||
|
|
||||||
|
|
||||||
def goto_line(self, abs_line_offset):
|
def goto_line(self, abs_line_offset):
|
||||||
|
@ -464,12 +464,144 @@ class Inliner:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.implicit_dispatch = [(self.patterns.uri, self.standalone_uri),]
|
self.implicit_dispatch = []
|
||||||
"""List of (pattern, bound method) tuples, used by
|
"""List of (pattern, bound method) tuples, used by
|
||||||
`self.implicit_inline`."""
|
`self.implicit_inline`."""
|
||||||
|
|
||||||
def init_customizations(self, settings):
|
def init_customizations(self, settings):
|
||||||
"""Setting-based customizations; run when parsing begins."""
|
# lookahead and look-behind expressions for inline markup rules
|
||||||
|
if getattr(settings, 'character_level_inline_markup', False):
|
||||||
|
start_string_prefix = u'(^|(?<!\x00))'
|
||||||
|
end_string_suffix = u''
|
||||||
|
else:
|
||||||
|
start_string_prefix = (u'(^|(?<=\\s|[%s%s]))' %
|
||||||
|
(punctuation_chars.openers,
|
||||||
|
punctuation_chars.delimiters))
|
||||||
|
end_string_suffix = (u'($|(?=\\s|[\x00%s%s%s]))' %
|
||||||
|
(punctuation_chars.closing_delimiters,
|
||||||
|
punctuation_chars.delimiters,
|
||||||
|
punctuation_chars.closers))
|
||||||
|
args = locals().copy()
|
||||||
|
args.update(vars(self.__class__))
|
||||||
|
|
||||||
|
parts = ('initial_inline', start_string_prefix, '',
|
||||||
|
[('start', '', self.non_whitespace_after, # simple start-strings
|
||||||
|
[r'\*\*', # strong
|
||||||
|
r'\*(?!\*)', # emphasis but not strong
|
||||||
|
r'``', # literal
|
||||||
|
r'_`', # inline internal target
|
||||||
|
r'\|(?!\|)'] # substitution reference
|
||||||
|
),
|
||||||
|
('whole', '', end_string_suffix, # whole constructs
|
||||||
|
[# reference name & end-string
|
||||||
|
r'(?P<refname>%s)(?P<refend>__?)' % self.simplename,
|
||||||
|
('footnotelabel', r'\[', r'(?P<fnend>\]_)',
|
||||||
|
[r'[0-9]+', # manually numbered
|
||||||
|
r'\#(%s)?' % self.simplename, # auto-numbered (w/ label?)
|
||||||
|
r'\*', # auto-symbol
|
||||||
|
r'(?P<citationlabel>%s)' % self.simplename] # citation reference
|
||||||
|
)
|
||||||
|
]
|
||||||
|
),
|
||||||
|
('backquote', # interpreted text or phrase reference
|
||||||
|
'(?P<role>(:%s:)?)' % self.simplename, # optional role
|
||||||
|
self.non_whitespace_after,
|
||||||
|
['`(?!`)'] # but not literal
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
self.start_string_prefix = start_string_prefix
|
||||||
|
self.end_string_suffix = end_string_suffix
|
||||||
|
self.parts = parts
|
||||||
|
|
||||||
|
self.patterns = Struct(
|
||||||
|
initial=build_regexp(parts),
|
||||||
|
emphasis=re.compile(self.non_whitespace_escape_before
|
||||||
|
+ r'(\*)' + end_string_suffix, re.UNICODE),
|
||||||
|
strong=re.compile(self.non_whitespace_escape_before
|
||||||
|
+ r'(\*\*)' + end_string_suffix, re.UNICODE),
|
||||||
|
interpreted_or_phrase_ref=re.compile(
|
||||||
|
r"""
|
||||||
|
%(non_unescaped_whitespace_escape_before)s
|
||||||
|
(
|
||||||
|
`
|
||||||
|
(?P<suffix>
|
||||||
|
(?P<role>:%(simplename)s:)?
|
||||||
|
(?P<refend>__?)?
|
||||||
|
)
|
||||||
|
)
|
||||||
|
%(end_string_suffix)s
|
||||||
|
""" % args, re.VERBOSE | re.UNICODE),
|
||||||
|
embedded_link=re.compile(
|
||||||
|
r"""
|
||||||
|
(
|
||||||
|
(?:[ \n]+|^) # spaces or beginning of line/string
|
||||||
|
< # open bracket
|
||||||
|
%(non_whitespace_after)s
|
||||||
|
(([^<>]|\x00[<>])+) # anything but unescaped angle brackets
|
||||||
|
%(non_whitespace_escape_before)s
|
||||||
|
> # close bracket
|
||||||
|
)
|
||||||
|
$ # end of string
|
||||||
|
""" % args, re.VERBOSE | re.UNICODE),
|
||||||
|
literal=re.compile(self.non_whitespace_before + '(``)'
|
||||||
|
+ end_string_suffix, re.UNICODE),
|
||||||
|
target=re.compile(self.non_whitespace_escape_before
|
||||||
|
+ r'(`)' + end_string_suffix, re.UNICODE),
|
||||||
|
substitution_ref=re.compile(self.non_whitespace_escape_before
|
||||||
|
+ r'(\|_{0,2})'
|
||||||
|
+ end_string_suffix, re.UNICODE),
|
||||||
|
email=re.compile(self.email_pattern % args + '$',
|
||||||
|
re.VERBOSE | re.UNICODE),
|
||||||
|
uri=re.compile(
|
||||||
|
(r"""
|
||||||
|
%(start_string_prefix)s
|
||||||
|
(?P<whole>
|
||||||
|
(?P<absolute> # absolute URI
|
||||||
|
(?P<scheme> # scheme (http, ftp, mailto)
|
||||||
|
[a-zA-Z][a-zA-Z0-9.+-]*
|
||||||
|
)
|
||||||
|
:
|
||||||
|
(
|
||||||
|
( # either:
|
||||||
|
(//?)? # hierarchical URI
|
||||||
|
%(uric)s* # URI characters
|
||||||
|
%(uri_end)s # final URI char
|
||||||
|
)
|
||||||
|
( # optional query
|
||||||
|
\?%(uric)s*
|
||||||
|
%(uri_end)s
|
||||||
|
)?
|
||||||
|
( # optional fragment
|
||||||
|
\#%(uric)s*
|
||||||
|
%(uri_end)s
|
||||||
|
)?
|
||||||
|
)
|
||||||
|
)
|
||||||
|
| # *OR*
|
||||||
|
(?P<email> # email address
|
||||||
|
""" + self.email_pattern + r"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
%(end_string_suffix)s
|
||||||
|
""") % args, re.VERBOSE | re.UNICODE),
|
||||||
|
pep=re.compile(
|
||||||
|
r"""
|
||||||
|
%(start_string_prefix)s
|
||||||
|
(
|
||||||
|
(pep-(?P<pepnum1>\d+)(.txt)?) # reference to source file
|
||||||
|
|
|
||||||
|
(PEP\s+(?P<pepnum2>\d+)) # reference by name
|
||||||
|
)
|
||||||
|
%(end_string_suffix)s""" % args, re.VERBOSE | re.UNICODE),
|
||||||
|
rfc=re.compile(
|
||||||
|
r"""
|
||||||
|
%(start_string_prefix)s
|
||||||
|
(RFC(-|\s+)?(?P<rfcnum>\d+))
|
||||||
|
%(end_string_suffix)s""" % args, re.VERBOSE | re.UNICODE))
|
||||||
|
|
||||||
|
self.implicit_dispatch.append((self.patterns.uri,
|
||||||
|
self.standalone_uri))
|
||||||
if settings.pep_references:
|
if settings.pep_references:
|
||||||
self.implicit_dispatch.append((self.patterns.pep,
|
self.implicit_dispatch.append((self.patterns.pep,
|
||||||
self.pep_reference))
|
self.pep_reference))
|
||||||
|
@ -527,20 +659,11 @@ class Inliner:
|
||||||
|
|
||||||
# Inline object recognition
|
# Inline object recognition
|
||||||
# -------------------------
|
# -------------------------
|
||||||
# lookahead and look-behind expressions for inline markup rules
|
# See also init_customizations().
|
||||||
start_string_prefix = (u'(^|(?<=\\s|[%s%s]))' %
|
non_whitespace_before = r'(?<!\s)'
|
||||||
(punctuation_chars.openers,
|
non_whitespace_escape_before = r'(?<![\s\x00])'
|
||||||
punctuation_chars.delimiters))
|
non_unescaped_whitespace_escape_before = r'(?<!(?<!\x00)[\s\x00])'
|
||||||
end_string_suffix = (u'($|(?=\\s|[\x00%s%s%s]))' %
|
non_whitespace_after = r'(?!\s)'
|
||||||
(punctuation_chars.closing_delimiters,
|
|
||||||
punctuation_chars.delimiters,
|
|
||||||
punctuation_chars.closers))
|
|
||||||
# print start_string_prefix.encode('utf8')
|
|
||||||
# TODO: support non-ASCII whitespace in the following 4 patterns?
|
|
||||||
non_whitespace_before = r'(?<![ \n])'
|
|
||||||
non_whitespace_escape_before = r'(?<![ \n\x00])'
|
|
||||||
non_unescaped_whitespace_escape_before = r'(?<!(?<!\x00)[ \n\x00])'
|
|
||||||
non_whitespace_after = r'(?![ \n])'
|
|
||||||
# Alphanumerics with isolated internal [-._+:] chars (i.e. not 2 together):
|
# Alphanumerics with isolated internal [-._+:] chars (i.e. not 2 together):
|
||||||
simplename = r'(?:(?!_)\w)+(?:[-._+:](?:(?!_)\w)+)*'
|
simplename = r'(?:(?!_)\w)+(?:[-._+:](?:(?!_)\w)+)*'
|
||||||
# Valid URI characters (see RFC 2396 & RFC 2732);
|
# Valid URI characters (see RFC 2396 & RFC 2732);
|
||||||
|
@ -560,118 +683,6 @@ class Inliner:
|
||||||
%(emailc)s+(?:\.%(emailc)s*)* # host
|
%(emailc)s+(?:\.%(emailc)s*)* # host
|
||||||
%(uri_end)s # final URI char
|
%(uri_end)s # final URI char
|
||||||
"""
|
"""
|
||||||
parts = ('initial_inline', start_string_prefix, '',
|
|
||||||
[('start', '', non_whitespace_after, # simple start-strings
|
|
||||||
[r'\*\*', # strong
|
|
||||||
r'\*(?!\*)', # emphasis but not strong
|
|
||||||
r'``', # literal
|
|
||||||
r'_`', # inline internal target
|
|
||||||
r'\|(?!\|)'] # substitution reference
|
|
||||||
),
|
|
||||||
('whole', '', end_string_suffix, # whole constructs
|
|
||||||
[# reference name & end-string
|
|
||||||
r'(?P<refname>%s)(?P<refend>__?)' % simplename,
|
|
||||||
('footnotelabel', r'\[', r'(?P<fnend>\]_)',
|
|
||||||
[r'[0-9]+', # manually numbered
|
|
||||||
r'\#(%s)?' % simplename, # auto-numbered (w/ label?)
|
|
||||||
r'\*', # auto-symbol
|
|
||||||
r'(?P<citationlabel>%s)' % simplename] # citation reference
|
|
||||||
)
|
|
||||||
]
|
|
||||||
),
|
|
||||||
('backquote', # interpreted text or phrase reference
|
|
||||||
'(?P<role>(:%s:)?)' % simplename, # optional role
|
|
||||||
non_whitespace_after,
|
|
||||||
['`(?!`)'] # but not literal
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
patterns = Struct(
|
|
||||||
initial=build_regexp(parts),
|
|
||||||
emphasis=re.compile(non_whitespace_escape_before
|
|
||||||
+ r'(\*)' + end_string_suffix, re.UNICODE),
|
|
||||||
strong=re.compile(non_whitespace_escape_before
|
|
||||||
+ r'(\*\*)' + end_string_suffix, re.UNICODE),
|
|
||||||
interpreted_or_phrase_ref=re.compile(
|
|
||||||
r"""
|
|
||||||
%(non_unescaped_whitespace_escape_before)s
|
|
||||||
(
|
|
||||||
`
|
|
||||||
(?P<suffix>
|
|
||||||
(?P<role>:%(simplename)s:)?
|
|
||||||
(?P<refend>__?)?
|
|
||||||
)
|
|
||||||
)
|
|
||||||
%(end_string_suffix)s
|
|
||||||
""" % locals(), re.VERBOSE | re.UNICODE),
|
|
||||||
embedded_link=re.compile(
|
|
||||||
r"""
|
|
||||||
(
|
|
||||||
(?:[ \n]+|^) # spaces or beginning of line/string
|
|
||||||
< # open bracket
|
|
||||||
%(non_whitespace_after)s
|
|
||||||
([^<>\x00]+(\x00_)?) # anything but angle brackets & nulls
|
|
||||||
# except escaped trailing low line
|
|
||||||
%(non_whitespace_before)s
|
|
||||||
> # close bracket w/o whitespace before
|
|
||||||
)
|
|
||||||
$ # end of string
|
|
||||||
""" % locals(), re.VERBOSE | re.UNICODE),
|
|
||||||
literal=re.compile(non_whitespace_before + '(``)'
|
|
||||||
+ end_string_suffix),
|
|
||||||
target=re.compile(non_whitespace_escape_before
|
|
||||||
+ r'(`)' + end_string_suffix),
|
|
||||||
substitution_ref=re.compile(non_whitespace_escape_before
|
|
||||||
+ r'(\|_{0,2})'
|
|
||||||
+ end_string_suffix),
|
|
||||||
email=re.compile(email_pattern % locals() + '$',
|
|
||||||
re.VERBOSE | re.UNICODE),
|
|
||||||
uri=re.compile(
|
|
||||||
(r"""
|
|
||||||
%(start_string_prefix)s
|
|
||||||
(?P<whole>
|
|
||||||
(?P<absolute> # absolute URI
|
|
||||||
(?P<scheme> # scheme (http, ftp, mailto)
|
|
||||||
[a-zA-Z][a-zA-Z0-9.+-]*
|
|
||||||
)
|
|
||||||
:
|
|
||||||
(
|
|
||||||
( # either:
|
|
||||||
(//?)? # hierarchical URI
|
|
||||||
%(uric)s* # URI characters
|
|
||||||
%(uri_end)s # final URI char
|
|
||||||
)
|
|
||||||
( # optional query
|
|
||||||
\?%(uric)s*
|
|
||||||
%(uri_end)s
|
|
||||||
)?
|
|
||||||
( # optional fragment
|
|
||||||
\#%(uric)s*
|
|
||||||
%(uri_end)s
|
|
||||||
)?
|
|
||||||
)
|
|
||||||
)
|
|
||||||
| # *OR*
|
|
||||||
(?P<email> # email address
|
|
||||||
""" + email_pattern + r"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
%(end_string_suffix)s
|
|
||||||
""") % locals(), re.VERBOSE | re.UNICODE),
|
|
||||||
pep=re.compile(
|
|
||||||
r"""
|
|
||||||
%(start_string_prefix)s
|
|
||||||
(
|
|
||||||
(pep-(?P<pepnum1>\d+)(.txt)?) # reference to source file
|
|
||||||
|
|
|
||||||
(PEP\s+(?P<pepnum2>\d+)) # reference by name
|
|
||||||
)
|
|
||||||
%(end_string_suffix)s""" % locals(), re.VERBOSE | re.UNICODE),
|
|
||||||
rfc=re.compile(
|
|
||||||
r"""
|
|
||||||
%(start_string_prefix)s
|
|
||||||
(RFC(-|\s+)?(?P<rfcnum>\d+))
|
|
||||||
%(end_string_suffix)s""" % locals(), re.VERBOSE | re.UNICODE))
|
|
||||||
|
|
||||||
def quoted_start(self, match):
|
def quoted_start(self, match):
|
||||||
"""Test if inline markup start-string is 'quoted'.
|
"""Test if inline markup start-string is 'quoted'.
|
||||||
|
@ -787,8 +798,10 @@ class Inliner:
|
||||||
match = self.patterns.embedded_link.search(escaped)
|
match = self.patterns.embedded_link.search(escaped)
|
||||||
if match: # embedded <URI> or <alias_>
|
if match: # embedded <URI> or <alias_>
|
||||||
text = unescape(escaped[:match.start(0)])
|
text = unescape(escaped[:match.start(0)])
|
||||||
aliastext = unescape(match.group(2), restore_backslashes=True)
|
aliastext = match.group(2)
|
||||||
if aliastext.endswith('_') and not (aliastext.endswith(r'\_')
|
underscore_escaped = aliastext.endswith('\x00_')
|
||||||
|
aliastext = unescape(aliastext)
|
||||||
|
if aliastext.endswith('_') and not (underscore_escaped
|
||||||
or self.patterns.uri.match(aliastext)):
|
or self.patterns.uri.match(aliastext)):
|
||||||
aliastype = 'name'
|
aliastype = 'name'
|
||||||
alias = normalize_name(aliastext[:-1])
|
alias = normalize_name(aliastext[:-1])
|
||||||
|
@ -796,7 +809,9 @@ class Inliner:
|
||||||
target.indirect_reference_name = aliastext[:-1]
|
target.indirect_reference_name = aliastext[:-1]
|
||||||
else:
|
else:
|
||||||
aliastype = 'uri'
|
aliastype = 'uri'
|
||||||
alias = ''.join(aliastext.split())
|
alias_parts = split_escaped_whitespace(match.group(2))
|
||||||
|
alias = ' '.join(''.join(unescape(part).split())
|
||||||
|
for part in alias_parts)
|
||||||
alias = self.adjust_uri(alias)
|
alias = self.adjust_uri(alias)
|
||||||
if alias.endswith(r'\_'):
|
if alias.endswith(r'\_'):
|
||||||
alias = alias[:-2] + '_'
|
alias = alias[:-2] + '_'
|
||||||
|
@ -1230,6 +1245,8 @@ class Body(RSTState):
|
||||||
def bullet(self, match, context, next_state):
|
def bullet(self, match, context, next_state):
|
||||||
"""Bullet list item."""
|
"""Bullet list item."""
|
||||||
bulletlist = nodes.bullet_list()
|
bulletlist = nodes.bullet_list()
|
||||||
|
(bulletlist.source,
|
||||||
|
bulletlist.line) = self.state_machine.get_source_and_line()
|
||||||
self.parent += bulletlist
|
self.parent += bulletlist
|
||||||
bulletlist['bullet'] = match.string[0]
|
bulletlist['bullet'] = match.string[0]
|
||||||
i, blank_finish = self.list_item(match.end())
|
i, blank_finish = self.list_item(match.end())
|
||||||
|
@ -1460,6 +1477,7 @@ class Body(RSTState):
|
||||||
def option_marker(self, match, context, next_state):
|
def option_marker(self, match, context, next_state):
|
||||||
"""Option list item."""
|
"""Option list item."""
|
||||||
optionlist = nodes.option_list()
|
optionlist = nodes.option_list()
|
||||||
|
(optionlist.source, optionlist.line) = self.state_machine.get_source_and_line()
|
||||||
try:
|
try:
|
||||||
listitem, blank_finish = self.option_list_item(match)
|
listitem, blank_finish = self.option_list_item(match)
|
||||||
except MarkupError, error:
|
except MarkupError, error:
|
||||||
|
@ -1547,6 +1565,9 @@ class Body(RSTState):
|
||||||
|
|
||||||
def doctest(self, match, context, next_state):
|
def doctest(self, match, context, next_state):
|
||||||
data = '\n'.join(self.state_machine.get_text_block())
|
data = '\n'.join(self.state_machine.get_text_block())
|
||||||
|
# TODO: prepend class value ['pycon'] (Python Console)
|
||||||
|
# parse with `directives.body.CodeBlock` (returns literal-block
|
||||||
|
# with class "code" and syntax highlight markup).
|
||||||
self.parent += nodes.doctest_block(data, data)
|
self.parent += nodes.doctest_block(data, data)
|
||||||
return [], next_state, []
|
return [], next_state, []
|
||||||
|
|
||||||
|
@ -1747,9 +1768,13 @@ class Body(RSTState):
|
||||||
line=startline+offset)
|
line=startline+offset)
|
||||||
return [error]
|
return [error]
|
||||||
|
|
||||||
def build_table(self, tabledata, tableline, stub_columns=0):
|
def build_table(self, tabledata, tableline, stub_columns=0, widths=None):
|
||||||
colwidths, headrows, bodyrows = tabledata
|
colwidths, headrows, bodyrows = tabledata
|
||||||
table = nodes.table()
|
table = nodes.table()
|
||||||
|
if widths == 'auto':
|
||||||
|
table['classes'] += ['colwidths-auto']
|
||||||
|
elif widths: # "grid" or list of integers
|
||||||
|
table['classes'] += ['colwidths-given']
|
||||||
tgroup = nodes.tgroup(cols=len(colwidths))
|
tgroup = nodes.tgroup(cols=len(colwidths))
|
||||||
table += tgroup
|
table += tgroup
|
||||||
for colwidth in colwidths:
|
for colwidth in colwidths:
|
||||||
|
@ -1939,8 +1964,10 @@ class Body(RSTState):
|
||||||
refname = self.is_reference(reference)
|
refname = self.is_reference(reference)
|
||||||
if refname:
|
if refname:
|
||||||
return 'refname', refname
|
return 'refname', refname
|
||||||
reference = ''.join([''.join(line.split()) for line in block])
|
ref_parts = split_escaped_whitespace(' '.join(block))
|
||||||
return 'refuri', unescape(reference)
|
reference = ' '.join(''.join(unescape(part).split())
|
||||||
|
for part in ref_parts)
|
||||||
|
return 'refuri', reference
|
||||||
|
|
||||||
def is_reference(self, reference):
|
def is_reference(self, reference):
|
||||||
match = self.explicit.patterns.reference.match(
|
match = self.explicit.patterns.reference.match(
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: tableparser.py 7320 2012-01-19 22:33:02Z milde $
|
# $Id: tableparser.py 7898 2015-05-29 20:49:28Z milde $
|
||||||
# Author: David Goodger <goodger@python.org>
|
# Author: David Goodger <goodger@python.org>
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
@ -511,8 +511,8 @@ class SimpleTableParser(TableParser):
|
||||||
if i == lastcol and line[end:].strip():
|
if i == lastcol and line[end:].strip():
|
||||||
text = line[start:].rstrip()
|
text = line[start:].rstrip()
|
||||||
new_end = start + len(text)
|
new_end = start + len(text)
|
||||||
columns[i] = (start, new_end)
|
|
||||||
main_start, main_end = self.columns[-1]
|
main_start, main_end = self.columns[-1]
|
||||||
|
columns[i] = (start, max(main_end, new_end))
|
||||||
if new_end > main_end:
|
if new_end > main_end:
|
||||||
self.columns[-1] = (main_start, new_end)
|
self.columns[-1] = (main_start, new_end)
|
||||||
elif line[end:nextstart].strip():
|
elif line[end:nextstart].strip():
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: frontmatter.py 7595 2013-01-21 17:33:56Z milde $
|
# $Id: frontmatter.py 8117 2017-06-18 23:38:18Z milde $
|
||||||
# Author: David Goodger, Ueli Schlaepfer <goodger@python.org>
|
# Author: David Goodger, Ueli Schlaepfer <goodger@python.org>
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
@ -433,6 +433,10 @@ class DocInfo(Transform):
|
||||||
and isinstance(field[-1][0], nodes.paragraph):
|
and isinstance(field[-1][0], nodes.paragraph):
|
||||||
utils.clean_rcs_keywords(
|
utils.clean_rcs_keywords(
|
||||||
field[-1][0], self.rcs_keyword_substitutions)
|
field[-1][0], self.rcs_keyword_substitutions)
|
||||||
|
if normedname not in bibliofields:
|
||||||
|
classvalue = nodes.make_id(normedname)
|
||||||
|
if classvalue:
|
||||||
|
field['classes'].append(classvalue)
|
||||||
docinfo.append(field)
|
docinfo.append(field)
|
||||||
nodelist = []
|
nodelist = []
|
||||||
if len(docinfo) != 0:
|
if len(docinfo) != 0:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: peps.py 6433 2010-09-28 08:21:25Z milde $
|
# $Id: peps.py 7995 2016-12-10 17:50:59Z milde $
|
||||||
# Author: David Goodger <goodger@python.org>
|
# Author: David Goodger <goodger@python.org>
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
@ -32,8 +32,8 @@ class Headers(Transform):
|
||||||
default_priority = 360
|
default_priority = 360
|
||||||
|
|
||||||
pep_url = 'pep-%04d'
|
pep_url = 'pep-%04d'
|
||||||
pep_cvs_url = ('http://svn.python.org/view/*checkout*'
|
pep_cvs_url = ('http://hg.python.org'
|
||||||
'/peps/trunk/pep-%04d.txt')
|
'/peps/file/default/pep-%04d.txt')
|
||||||
rcs_keyword_substitutions = (
|
rcs_keyword_substitutions = (
|
||||||
(re.compile(r'\$' r'RCSfile: (.+),v \$$', re.IGNORECASE), r'\1'),
|
(re.compile(r'\$' r'RCSfile: (.+),v \$$', re.IGNORECASE), r'\1'),
|
||||||
(re.compile(r'\$[a-zA-Z]+: (.+) \$$'), r'\1'),)
|
(re.compile(r'\$[a-zA-Z]+: (.+) \$$'), r'\1'),)
|
||||||
|
@ -113,7 +113,7 @@ class Headers(Transform):
|
||||||
elif name in ('replaces', 'replaced-by', 'requires'):
|
elif name in ('replaces', 'replaced-by', 'requires'):
|
||||||
newbody = []
|
newbody = []
|
||||||
space = nodes.Text(' ')
|
space = nodes.Text(' ')
|
||||||
for refpep in re.split(',?\s+', body.astext()):
|
for refpep in re.split(r',?\s+', body.astext()):
|
||||||
pepno = int(refpep)
|
pepno = int(refpep)
|
||||||
newbody.append(nodes.reference(
|
newbody.append(nodes.reference(
|
||||||
refpep, refpep,
|
refpep, refpep,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: references.py 7624 2013-03-07 14:10:26Z milde $
|
# $Id: references.py 8067 2017-05-04 20:10:03Z milde $
|
||||||
# Author: David Goodger <goodger@python.org>
|
# Author: David Goodger <goodger@python.org>
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
@ -710,6 +710,7 @@ class Substitutions(Transform):
|
||||||
raise CircularSubstitutionDefinitionError
|
raise CircularSubstitutionDefinitionError
|
||||||
else:
|
else:
|
||||||
nested[nested_name].append(key)
|
nested[nested_name].append(key)
|
||||||
|
nested_ref['ref-origin'] = ref
|
||||||
subreflist.append(nested_ref)
|
subreflist.append(nested_ref)
|
||||||
except CircularSubstitutionDefinitionError:
|
except CircularSubstitutionDefinitionError:
|
||||||
parent = ref.parent
|
parent = ref.parent
|
||||||
|
@ -721,9 +722,13 @@ class Substitutions(Transform):
|
||||||
line=parent.line, base_node=parent)
|
line=parent.line, base_node=parent)
|
||||||
parent.replace_self(msg)
|
parent.replace_self(msg)
|
||||||
else:
|
else:
|
||||||
|
# find original ref substitution which cased this error
|
||||||
|
ref_origin = ref
|
||||||
|
while ref_origin.hasattr('ref-origin'):
|
||||||
|
ref_origin = ref_origin['ref-origin']
|
||||||
msg = self.document.reporter.error(
|
msg = self.document.reporter.error(
|
||||||
'Circular substitution definition referenced: "%s".'
|
'Circular substitution definition referenced: '
|
||||||
% refname, base_node=ref)
|
'"%s".' % refname, base_node=ref_origin)
|
||||||
msgid = self.document.set_id(msg)
|
msgid = self.document.set_id(msg)
|
||||||
prb = nodes.problematic(
|
prb = nodes.problematic(
|
||||||
ref.rawsource, ref.rawsource, refid=msgid)
|
ref.rawsource, ref.rawsource, refid=msgid)
|
||||||
|
@ -893,7 +898,10 @@ class DanglingReferencesVisitor(nodes.SparseNodeVisitor):
|
||||||
msgid = self.document.set_id(msg)
|
msgid = self.document.set_id(msg)
|
||||||
prb = nodes.problematic(
|
prb = nodes.problematic(
|
||||||
node.rawsource, node.rawsource, refid=msgid)
|
node.rawsource, node.rawsource, refid=msgid)
|
||||||
prbid = self.document.set_id(prb)
|
try:
|
||||||
|
prbid = node['ids'][0]
|
||||||
|
except IndexError:
|
||||||
|
prbid = self.document.set_id(prb)
|
||||||
msg.add_backref(prbid)
|
msg.add_backref(prbid)
|
||||||
node.replace_self(prb)
|
node.replace_self(prb)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: universal.py 7668 2013-06-04 12:46:30Z milde $
|
# $Id: universal.py 8144 2017-07-26 21:25:08Z milde $
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Authors: David Goodger <goodger@python.org>; Ueli Schlaepfer; Günter Milde
|
# Authors: David Goodger <goodger@python.org>; Ueli Schlaepfer; Günter Milde
|
||||||
# Maintainer: docutils-develop@lists.sourceforge.net
|
# Maintainer: docutils-develop@lists.sourceforge.net
|
||||||
|
@ -49,6 +49,10 @@ class Decorations(Transform):
|
||||||
def generate_footer(self):
|
def generate_footer(self):
|
||||||
# @@@ Text is hard-coded for now.
|
# @@@ Text is hard-coded for now.
|
||||||
# Should be made dynamic (language-dependent).
|
# Should be made dynamic (language-dependent).
|
||||||
|
# @@@ Use timestamp from the `SOURCE_DATE_EPOCH`_ environment variable
|
||||||
|
# for the datestamp?
|
||||||
|
# See https://sourceforge.net/p/docutils/patches/132/
|
||||||
|
# and https://reproducible-builds.org/specs/source-date-epoch/
|
||||||
settings = self.document.settings
|
settings = self.document.settings
|
||||||
if settings.generator or settings.datestamp or settings.source_link \
|
if settings.generator or settings.datestamp or settings.source_link \
|
||||||
or settings.source_url:
|
or settings.source_url:
|
||||||
|
@ -204,6 +208,7 @@ class StripClassesAndElements(Transform):
|
||||||
if class_value in self.strip_elements:
|
if class_value in self.strip_elements:
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
class SmartQuotes(Transform):
|
class SmartQuotes(Transform):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -214,6 +219,20 @@ class SmartQuotes(Transform):
|
||||||
|
|
||||||
default_priority = 850
|
default_priority = 850
|
||||||
|
|
||||||
|
nodes_to_skip = (nodes.FixedTextElement, nodes.Special)
|
||||||
|
"""Do not apply "smartquotes" to instances of these block-level nodes."""
|
||||||
|
|
||||||
|
literal_nodes = (nodes.image, nodes.literal, nodes.math,
|
||||||
|
nodes.raw, nodes.problematic)
|
||||||
|
"""Do not change quotes in instances of these inline nodes."""
|
||||||
|
|
||||||
|
smartquotes_action = 'qDe'
|
||||||
|
"""Setting to select smartquote transformations.
|
||||||
|
|
||||||
|
The default 'qDe' educates normal quote characters: (", '),
|
||||||
|
em- and en-dashes (---, --) and ellipses (...).
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, document, startnode):
|
def __init__(self, document, startnode):
|
||||||
Transform.__init__(self, document, startnode=startnode)
|
Transform.__init__(self, document, startnode=startnode)
|
||||||
self.unsupported_languages = set()
|
self.unsupported_languages = set()
|
||||||
|
@ -226,11 +245,7 @@ class SmartQuotes(Transform):
|
||||||
False: 'plain'}
|
False: 'plain'}
|
||||||
for txtnode in txtnodes:
|
for txtnode in txtnodes:
|
||||||
nodetype = texttype[isinstance(txtnode.parent,
|
nodetype = texttype[isinstance(txtnode.parent,
|
||||||
(nodes.literal,
|
self.literal_nodes)]
|
||||||
nodes.math,
|
|
||||||
nodes.image,
|
|
||||||
nodes.raw,
|
|
||||||
nodes.problematic))]
|
|
||||||
yield (nodetype, txtnode.astext())
|
yield (nodetype, txtnode.astext())
|
||||||
|
|
||||||
|
|
||||||
|
@ -245,12 +260,15 @@ class SmartQuotes(Transform):
|
||||||
# print repr(alternative)
|
# print repr(alternative)
|
||||||
|
|
||||||
document_language = self.document.settings.language_code
|
document_language = self.document.settings.language_code
|
||||||
|
lc_smartquotes = self.document.settings.smartquotes_locales
|
||||||
|
if lc_smartquotes:
|
||||||
|
smartquotes.smartchars.quotes.update(dict(lc_smartquotes))
|
||||||
|
|
||||||
# "Educate" quotes in normal text. Handle each block of text
|
# "Educate" quotes in normal text. Handle each block of text
|
||||||
# (TextElement node) as a unit to keep context around inline nodes:
|
# (TextElement node) as a unit to keep context around inline nodes:
|
||||||
for node in self.document.traverse(nodes.TextElement):
|
for node in self.document.traverse(nodes.TextElement):
|
||||||
# skip preformatted text blocks and special elements:
|
# skip preformatted text blocks and special elements:
|
||||||
if isinstance(node, (nodes.FixedTextElement, nodes.Special)):
|
if isinstance(node, self.nodes_to_skip):
|
||||||
continue
|
continue
|
||||||
# nested TextElements are not "block-level" elements:
|
# nested TextElements are not "block-level" elements:
|
||||||
if isinstance(node.parent, nodes.TextElement):
|
if isinstance(node.parent, nodes.TextElement):
|
||||||
|
@ -269,7 +287,7 @@ class SmartQuotes(Transform):
|
||||||
lang = lang.replace('-x-altquot', '')
|
lang = lang.replace('-x-altquot', '')
|
||||||
else:
|
else:
|
||||||
lang += '-x-altquot'
|
lang += '-x-altquot'
|
||||||
# drop subtags missing in quotes:
|
# drop unsupported subtags:
|
||||||
for tag in utils.normalize_language_tag(lang):
|
for tag in utils.normalize_language_tag(lang):
|
||||||
if tag in smartquotes.smartchars.quotes:
|
if tag in smartquotes.smartchars.quotes:
|
||||||
lang = tag
|
lang = tag
|
||||||
|
@ -282,11 +300,12 @@ class SmartQuotes(Transform):
|
||||||
lang = ''
|
lang = ''
|
||||||
|
|
||||||
# Iterator educating quotes in plain text:
|
# Iterator educating quotes in plain text:
|
||||||
# '2': set all, using old school en- and em- dash shortcuts
|
# (see "utils/smartquotes.py" for the attribute setting)
|
||||||
teacher = smartquotes.educate_tokens(self.get_tokens(txtnodes),
|
teacher = smartquotes.educate_tokens(self.get_tokens(txtnodes),
|
||||||
attr='2', language=lang)
|
attr=self.smartquotes_action, language=lang)
|
||||||
|
|
||||||
for txtnode, newtext in zip(txtnodes, teacher):
|
for txtnode, newtext in zip(txtnodes, teacher):
|
||||||
txtnode.parent.replace(txtnode, nodes.Text(newtext))
|
txtnode.parent.replace(txtnode, nodes.Text(newtext,
|
||||||
|
rawsource=txtnode.rawsource))
|
||||||
|
|
||||||
self.unsupported_languages = set() # reset
|
self.unsupported_languages = set() # reset
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: writer_aux.py 7320 2012-01-19 22:33:02Z milde $
|
# $Id: writer_aux.py 7808 2015-02-27 17:03:32Z milde $
|
||||||
# Author: Lea Wiemann <LeWiemann@gmail.com>
|
# Author: Lea Wiemann <LeWiemann@gmail.com>
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
# $Id: __init__.py 7668 2013-06-04 12:46:30Z milde $
|
# $Id: __init__.py 8141 2017-07-08 17:05:18Z goodger $
|
||||||
# Author: David Goodger <goodger@python.org>
|
# Author: David Goodger <goodger@python.org>
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
@ -13,9 +13,10 @@ import sys
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import re
|
import re
|
||||||
|
import itertools
|
||||||
import warnings
|
import warnings
|
||||||
import unicodedata
|
import unicodedata
|
||||||
from docutils import ApplicationError, DataError
|
from docutils import ApplicationError, DataError, __version_info__
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
import docutils.io
|
import docutils.io
|
||||||
from docutils.utils.error_reporting import ErrorOutput, SafeString
|
from docutils.utils.error_reporting import ErrorOutput, SafeString
|
||||||
|
@ -325,7 +326,7 @@ def assemble_option_dict(option_list, options_spec):
|
||||||
raise DuplicateOptionError('duplicate option "%s"' % name)
|
raise DuplicateOptionError('duplicate option "%s"' % name)
|
||||||
try:
|
try:
|
||||||
options[name] = convertor(value)
|
options[name] = convertor(value)
|
||||||
except (ValueError, TypeError), detail:
|
except (ValueError, TypeError) as detail:
|
||||||
raise detail.__class__('(option: "%s"; value: %r)\n%s'
|
raise detail.__class__('(option: "%s"; value: %r)\n%s'
|
||||||
% (name, value, ' '.join(detail.args)))
|
% (name, value, ' '.join(detail.args)))
|
||||||
return options
|
return options
|
||||||
|
@ -575,7 +576,7 @@ def escape2null(text):
|
||||||
parts.append('\x00' + text[found+1:found+2])
|
parts.append('\x00' + text[found+1:found+2])
|
||||||
start = found + 2 # skip character after escape
|
start = found + 2 # skip character after escape
|
||||||
|
|
||||||
def unescape(text, restore_backslashes=False):
|
def unescape(text, restore_backslashes=False, respect_whitespace=False):
|
||||||
"""
|
"""
|
||||||
Return a string with nulls removed or restored to backslashes.
|
Return a string with nulls removed or restored to backslashes.
|
||||||
Backslash-escaped spaces are also removed.
|
Backslash-escaped spaces are also removed.
|
||||||
|
@ -587,6 +588,16 @@ def unescape(text, restore_backslashes=False):
|
||||||
text = ''.join(text.split(sep))
|
text = ''.join(text.split(sep))
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
def split_escaped_whitespace(text):
|
||||||
|
"""
|
||||||
|
Split `text` on escaped whitespace (null+space or null+newline).
|
||||||
|
Return a list of strings.
|
||||||
|
"""
|
||||||
|
strings = text.split('\x00 ')
|
||||||
|
strings = [string.split('\x00\n') for string in strings]
|
||||||
|
# flatten list of lists of strings to list of strings:
|
||||||
|
return list(itertools.chain(*strings))
|
||||||
|
|
||||||
def strip_combining_chars(text):
|
def strip_combining_chars(text):
|
||||||
if isinstance(text, str) and sys.version_info < (3,0):
|
if isinstance(text, str) and sys.version_info < (3,0):
|
||||||
return text
|
return text
|
||||||
|
@ -595,8 +606,10 @@ def strip_combining_chars(text):
|
||||||
def find_combining_chars(text):
|
def find_combining_chars(text):
|
||||||
"""Return indices of all combining chars in Unicode string `text`.
|
"""Return indices of all combining chars in Unicode string `text`.
|
||||||
|
|
||||||
|
>>> from docutils.utils import find_combining_chars
|
||||||
>>> find_combining_chars(u'A t̆ab̆lĕ')
|
>>> find_combining_chars(u'A t̆ab̆lĕ')
|
||||||
[3, 6, 9]
|
[3, 6, 9]
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if isinstance(text, str) and sys.version_info < (3,0):
|
if isinstance(text, str) and sys.version_info < (3,0):
|
||||||
return []
|
return []
|
||||||
|
@ -605,8 +618,10 @@ def find_combining_chars(text):
|
||||||
def column_indices(text):
|
def column_indices(text):
|
||||||
"""Indices of Unicode string `text` when skipping combining characters.
|
"""Indices of Unicode string `text` when skipping combining characters.
|
||||||
|
|
||||||
|
>>> from docutils.utils import column_indices
|
||||||
>>> column_indices(u'A t̆ab̆lĕ')
|
>>> column_indices(u'A t̆ab̆lĕ')
|
||||||
[0, 1, 2, 4, 5, 7, 8]
|
[0, 1, 2, 4, 5, 7, 8]
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# TODO: account for asian wide chars here instead of using dummy
|
# TODO: account for asian wide chars here instead of using dummy
|
||||||
# replacements in the tableparser?
|
# replacements in the tableparser?
|
||||||
|
@ -663,17 +678,21 @@ def normalize_language_tag(tag):
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
>>> from docutils.utils import normalize_language_tag
|
||||||
>>> normalize_language_tag('de_AT-1901')
|
>>> normalize_language_tag('de_AT-1901')
|
||||||
['de-at-1901', 'de-at', 'de-1901', 'de']
|
['de-at-1901', 'de-at', 'de-1901', 'de']
|
||||||
|
>>> normalize_language_tag('de-CH-x_altquot')
|
||||||
|
['de-ch-x-altquot', 'de-ch', 'de-x-altquot', 'de']
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# normalize:
|
# normalize:
|
||||||
tag = tag.lower().replace('_','-')
|
tag = tag.lower().replace('-','_')
|
||||||
# split (except singletons, which mark the following tag as non-standard):
|
# split (except singletons, which mark the following tag as non-standard):
|
||||||
tag = re.sub(r'-([a-zA-Z0-9])-', r'-\1_', tag)
|
tag = re.sub(r'_([a-zA-Z0-9])_', r'_\1-', tag)
|
||||||
taglist = []
|
subtags = [subtag for subtag in tag.split('_')]
|
||||||
subtags = [subtag.replace('_', '-') for subtag in tag.split('-')]
|
|
||||||
base_tag = [subtags.pop(0)]
|
base_tag = [subtags.pop(0)]
|
||||||
# find all combinations of subtags
|
# find all combinations of subtags
|
||||||
|
taglist = []
|
||||||
for n in range(len(subtags), 0, -1):
|
for n in range(len(subtags), 0, -1):
|
||||||
for tags in unique_combinations(subtags, n):
|
for tags in unique_combinations(subtags, n):
|
||||||
taglist.append('-'.join(base_tag+tags))
|
taglist.append('-'.join(base_tag+tags))
|
||||||
|
@ -747,3 +766,42 @@ class DependencyList(object):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
output_file = None
|
output_file = None
|
||||||
return '%s(%r, %s)' % (self.__class__.__name__, output_file, self.list)
|
return '%s(%r, %s)' % (self.__class__.__name__, output_file, self.list)
|
||||||
|
|
||||||
|
|
||||||
|
release_level_abbreviations = {
|
||||||
|
'alpha': 'a',
|
||||||
|
'beta': 'b',
|
||||||
|
'candidate': 'rc',
|
||||||
|
'final': '',}
|
||||||
|
|
||||||
|
def version_identifier(version_info=None):
|
||||||
|
# to add in Docutils 0.15:
|
||||||
|
# version_info is a namedtuple, an instance of Docutils.VersionInfo.
|
||||||
|
"""
|
||||||
|
Given a `version_info` tuple (default is docutils.__version_info__),
|
||||||
|
build & return a version identifier string.
|
||||||
|
"""
|
||||||
|
if version_info is None:
|
||||||
|
version_info = __version_info__
|
||||||
|
if version_info[2]: # version_info.micro
|
||||||
|
micro = '.%s' % version_info[2]
|
||||||
|
else:
|
||||||
|
micro = ''
|
||||||
|
releaselevel = release_level_abbreviations[
|
||||||
|
version_info[3]] # version_info.releaselevel
|
||||||
|
if version_info[4]: # version_info.serial
|
||||||
|
serial = version_info[4]
|
||||||
|
else:
|
||||||
|
serial = ''
|
||||||
|
if version_info[5]: # version_info.release
|
||||||
|
dev = ''
|
||||||
|
else:
|
||||||
|
dev = '.dev'
|
||||||
|
version = '%s.%s%s%s%s%s' % (
|
||||||
|
version_info[0], # version_info.major
|
||||||
|
version_info[1], # version_info.minor
|
||||||
|
micro,
|
||||||
|
releaselevel,
|
||||||
|
serial,
|
||||||
|
dev)
|
||||||
|
return version
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
"""Lexical analysis of formal languages (i.e. code) using Pygments."""
|
"""Lexical analysis of formal languages (i.e. code) using Pygments."""
|
||||||
|
|
||||||
# :Author: Georg Brandl; Felix Wiemann; Günter Milde
|
# :Author: Georg Brandl; Felix Wiemann; Günter Milde
|
||||||
# :Date: $Date: 2011-12-20 15:14:21 +0100 (Die, 20. Dez 2011) $
|
# :Date: $Date: 2015-04-20 16:05:27 +0200 (Mo, 20 Apr 2015) $
|
||||||
# :Copyright: This module has been placed in the public domain.
|
# :Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
from docutils import ApplicationError
|
from docutils import ApplicationError
|
||||||
|
@ -13,7 +13,7 @@ try:
|
||||||
from pygments.lexers import get_lexer_by_name
|
from pygments.lexers import get_lexer_by_name
|
||||||
from pygments.formatters.html import _get_ttype_class
|
from pygments.formatters.html import _get_ttype_class
|
||||||
with_pygments = True
|
with_pygments = True
|
||||||
except ImportError:
|
except (ImportError, SyntaxError): # pygments 2.0.1 fails with Py 3.1 and 3.2
|
||||||
with_pygments = False
|
with_pygments = False
|
||||||
|
|
||||||
# Filter the following token types from the list of class arguments:
|
# Filter the following token types from the list of class arguments:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# :Id: $Id: error_reporting.py 7668 2013-06-04 12:46:30Z milde $
|
# :Id: $Id: error_reporting.py 8119 2017-06-22 20:59:19Z milde $
|
||||||
# :Copyright: © 2011 Günter Milde.
|
# :Copyright: © 2011 Günter Milde.
|
||||||
# :License: Released under the terms of the `2-Clause BSD license`_, in short:
|
# :License: Released under the terms of the `2-Clause BSD license`_, in short:
|
||||||
#
|
#
|
||||||
|
@ -44,10 +44,20 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
locale_encoding = None
|
locale_encoding = None
|
||||||
else:
|
else:
|
||||||
locale_encoding = locale.getlocale()[1] or locale.getdefaultlocale()[1]
|
try:
|
||||||
# locale.getpreferredencoding([do_setlocale=True|False])
|
locale_encoding = locale.getlocale()[1] or locale.getdefaultlocale()[1]
|
||||||
# has side-effects | might return a wrong guess.
|
# locale.getpreferredencoding([do_setlocale=True|False])
|
||||||
# (cf. Update 1 in http://stackoverflow.com/questions/4082645/using-python-2-xs-locale-module-to-format-numbers-and-currency)
|
# has side-effects | might return a wrong guess.
|
||||||
|
# (cf. Update 1 in http://stackoverflow.com/questions/4082645/using-python-2-xs-locale-module-to-format-numbers-and-currency)
|
||||||
|
except ValueError as error: # OS X may set UTF-8 without language code
|
||||||
|
# see http://bugs.python.org/issue18378
|
||||||
|
# and https://sourceforge.net/p/docutils/bugs/298/
|
||||||
|
if "unknown locale: UTF-8" in error.args:
|
||||||
|
locale_encoding = "UTF-8"
|
||||||
|
else:
|
||||||
|
locale_encoding = None
|
||||||
|
except: # any other problems determining the locale -> use None
|
||||||
|
locale_encoding = None
|
||||||
try:
|
try:
|
||||||
codecs.lookup(locale_encoding or '') # None -> ''
|
codecs.lookup(locale_encoding or '') # None -> ''
|
||||||
except LookupError:
|
except LookupError:
|
||||||
|
@ -72,7 +82,7 @@ class SafeString(object):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
try:
|
try:
|
||||||
return str(self.data)
|
return str(self.data)
|
||||||
except UnicodeEncodeError, err:
|
except UnicodeEncodeError:
|
||||||
if isinstance(self.data, Exception):
|
if isinstance(self.data, Exception):
|
||||||
args = [str(SafeString(arg, self.encoding,
|
args = [str(SafeString(arg, self.encoding,
|
||||||
self.encoding_errors))
|
self.encoding_errors))
|
||||||
|
@ -103,7 +113,7 @@ class SafeString(object):
|
||||||
if isinstance(self.data, EnvironmentError):
|
if isinstance(self.data, EnvironmentError):
|
||||||
u = u.replace(": u'", ": '") # normalize filename quoting
|
u = u.replace(": u'", ": '") # normalize filename quoting
|
||||||
return u
|
return u
|
||||||
except UnicodeError, error: # catch ..Encode.. and ..Decode.. errors
|
except UnicodeError as error: # catch ..Encode.. and ..Decode.. errors
|
||||||
if isinstance(self.data, EnvironmentError):
|
if isinstance(self.data, EnvironmentError):
|
||||||
return u"[Errno %s] %s: '%s'" % (self.data.errno,
|
return u"[Errno %s] %s: '%s'" % (self.data.errno,
|
||||||
SafeString(self.data.strerror, self.encoding,
|
SafeString(self.data.strerror, self.encoding,
|
||||||
|
@ -189,7 +199,11 @@ class ErrorOutput(object):
|
||||||
self.stream.write(data)
|
self.stream.write(data)
|
||||||
except UnicodeEncodeError:
|
except UnicodeEncodeError:
|
||||||
self.stream.write(data.encode(self.encoding, self.encoding_errors))
|
self.stream.write(data.encode(self.encoding, self.encoding_errors))
|
||||||
except TypeError: # in Python 3, stderr expects unicode
|
except TypeError:
|
||||||
|
if isinstance(data, unicode): # passed stream may expect bytes
|
||||||
|
self.stream.write(data.encode(self.encoding,
|
||||||
|
self.encoding_errors))
|
||||||
|
return
|
||||||
if self.stream in (sys.stderr, sys.stdout):
|
if self.stream in (sys.stderr, sys.stdout):
|
||||||
self.stream.buffer.write(data) # write bytes to raw stream
|
self.stream.buffer.write(data) # write bytes to raw stream
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# :Id: $Id: __init__.py 7218 2011-11-08 17:42:40Z milde $
|
# :Id: $Id: __init__.py 7865 2015-04-12 10:06:43Z milde $
|
||||||
# :Author: Guenter Milde.
|
# :Author: Guenter Milde.
|
||||||
# :License: Released under the terms of the `2-Clause BSD license`_, in short:
|
# :License: Released under the terms of the `2-Clause BSD license`_, in short:
|
||||||
#
|
#
|
||||||
|
@ -17,8 +17,9 @@ It contains various modules for conversion between different math formats
|
||||||
|
|
||||||
:math2html: LaTeX math -> HTML conversion from eLyXer
|
:math2html: LaTeX math -> HTML conversion from eLyXer
|
||||||
:latex2mathml: LaTeX math -> presentational MathML
|
:latex2mathml: LaTeX math -> presentational MathML
|
||||||
:unichar2tex: Unicode character to LaTeX math translation table
|
:unichar2tex: Unicode character to LaTeX math translation table
|
||||||
:tex2unichar: LaTeX math to Unicode character translation dictionaries
|
:tex2unichar: LaTeX math to Unicode character translation dictionaries
|
||||||
|
:tex2mathml_extern: Wrapper for TeX -> MathML command line converters
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# helpers for Docutils math support
|
# helpers for Docutils math support
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# :Id: $Id: latex2mathml.py 7668 2013-06-04 12:46:30Z milde $
|
# :Id: $Id: latex2mathml.py 7995 2016-12-10 17:50:59Z milde $
|
||||||
# :Copyright: © 2010 Günter Milde.
|
# :Copyright: © 2010 Günter Milde.
|
||||||
# Based on rst2mathml.py from the latex_math sandbox project
|
# Based on rst2mathml.py from the latex_math sandbox project
|
||||||
# © 2005 Jens Jørgen Mortensen
|
# © 2005 Jens Jørgen Mortensen
|
||||||
|
@ -151,8 +151,8 @@ mathscr = {
|
||||||
}
|
}
|
||||||
|
|
||||||
negatables = {'=': u'\u2260',
|
negatables = {'=': u'\u2260',
|
||||||
'\in': u'\u2209',
|
r'\in': u'\u2209',
|
||||||
'\equiv': u'\u2262'}
|
r'\equiv': u'\u2262'}
|
||||||
|
|
||||||
# LaTeX to MathML translation stuff:
|
# LaTeX to MathML translation stuff:
|
||||||
class math:
|
class math:
|
||||||
|
@ -558,3 +558,14 @@ def handle_keyword(name, node, string):
|
||||||
raise SyntaxError(u'Unknown LaTeX command: ' + name)
|
raise SyntaxError(u'Unknown LaTeX command: ' + name)
|
||||||
|
|
||||||
return node, skip
|
return node, skip
|
||||||
|
|
||||||
|
def tex2mathml(tex_math, inline=True):
|
||||||
|
"""Return string with MathML code corresponding to `tex_math`.
|
||||||
|
|
||||||
|
`inline`=True is for inline math and `inline`=False for displayed math.
|
||||||
|
"""
|
||||||
|
|
||||||
|
mathml_tree = parse_latex_math(tex_math, inline=inline)
|
||||||
|
return ''.join(mathml_tree.xml())
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
# .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause
|
# .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause
|
||||||
|
|
||||||
# Based on eLyXer: convert LyX source files to HTML output.
|
# Based on eLyXer: convert LyX source files to HTML output.
|
||||||
# http://elyxer.nongnu.org/
|
# http://alexfernandez.github.io/elyxer/
|
||||||
|
|
||||||
# --end--
|
# --end--
|
||||||
# Alex 20101110
|
# Alex 20101110
|
||||||
|
@ -112,7 +112,7 @@ class BibStylesConfig(object):
|
||||||
u'@conference':u'$authors: “$title”, <i>$journal</i>,{ pp. $pages,} $year.{ URL <a href="$url">$url</a>.}{ $note.}',
|
u'@conference':u'$authors: “$title”, <i>$journal</i>,{ pp. $pages,} $year.{ URL <a href="$url">$url</a>.}{ $note.}',
|
||||||
u'@inbook':u'$authors: <i>$title</i>.{{ $publisher,} $year.}{ URL <a href="$url">$url</a>.}{ $note.}',
|
u'@inbook':u'$authors: <i>$title</i>.{{ $publisher,} $year.}{ URL <a href="$url">$url</a>.}{ $note.}',
|
||||||
u'@incollection':u'$authors: <i>$title</i>{ in <i>$booktitle</i>{ ($editor, ed.)}}.{{ $publisher,} $year.}{ URL <a href="$url">$url</a>.}{ $note.}',
|
u'@incollection':u'$authors: <i>$title</i>{ in <i>$booktitle</i>{ ($editor, ed.)}}.{{ $publisher,} $year.}{ URL <a href="$url">$url</a>.}{ $note.}',
|
||||||
u'@inproceedings':u'$authors: “$title”, <i>$journal</i>,{ pp. $pages,} $year.{ URL <a href="$url">$url</a>.}{ $note.}',
|
u'@inproceedings':u'$authors: “$title”, <i>$booktitle</i>,{ pp. $pages,} $year.{ URL <a href="$url">$url</a>.}{ $note.}',
|
||||||
u'@manual':u'$authors: <i>$title</i>.{{ $publisher,} $year.}{ URL <a href="$url">$url</a>.}{ $note.}',
|
u'@manual':u'$authors: <i>$title</i>.{{ $publisher,} $year.}{ URL <a href="$url">$url</a>.}{ $note.}',
|
||||||
u'@mastersthesis':u'$authors: <i>$title</i>.{{ $publisher,} $year.}{ URL <a href="$url">$url</a>.}{ $note.}',
|
u'@mastersthesis':u'$authors: <i>$title</i>.{{ $publisher,} $year.}{ URL <a href="$url">$url</a>.}{ $note.}',
|
||||||
u'@misc':u'$authors: <i>$title</i>.{{ $publisher,}{ $howpublished,} $year.}{ URL <a href="$url">$url</a>.}{ $note.}',
|
u'@misc':u'$authors: <i>$title</i>.{{ $publisher,}{ $howpublished,} $year.}{ URL <a href="$url">$url</a>.}{ $note.}',
|
||||||
|
@ -245,7 +245,8 @@ class ContainerConfig(object):
|
||||||
u'\\begin_inset Quotes':u'QuoteContainer',
|
u'\\begin_inset Quotes':u'QuoteContainer',
|
||||||
u'\\begin_inset Tabular':u'Table', u'\\begin_inset Text':u'InsetText',
|
u'\\begin_inset Tabular':u'Table', u'\\begin_inset Text':u'InsetText',
|
||||||
u'\\begin_inset VSpace':u'VerticalSpace', u'\\begin_inset Wrap':u'Wrap',
|
u'\\begin_inset VSpace':u'VerticalSpace', u'\\begin_inset Wrap':u'Wrap',
|
||||||
u'\\begin_inset listings':u'Listing', u'\\begin_inset space':u'Space',
|
u'\\begin_inset listings':u'Listing',
|
||||||
|
u'\\begin_inset script':u'ScriptInset', u'\\begin_inset space':u'Space',
|
||||||
u'\\begin_layout':u'Layout', u'\\begin_layout Abstract':u'Abstract',
|
u'\\begin_layout':u'Layout', u'\\begin_layout Abstract':u'Abstract',
|
||||||
u'\\begin_layout Author':u'Author',
|
u'\\begin_layout Author':u'Author',
|
||||||
u'\\begin_layout Bibliography':u'Bibliography',
|
u'\\begin_layout Bibliography':u'Bibliography',
|
||||||
|
@ -291,7 +292,7 @@ class EscapeConfig(object):
|
||||||
"Configuration class from elyxer.config file"
|
"Configuration class from elyxer.config file"
|
||||||
|
|
||||||
chars = {
|
chars = {
|
||||||
u'\n':u'', u' -- ':u' — ', u'\'':u'’', u'---':u'—', u'`':u'‘',
|
u'\n':u'', u' -- ':u' — ', u' --- ':u' — ', u'\'':u'’', u'`':u'‘',
|
||||||
}
|
}
|
||||||
|
|
||||||
commands = {
|
commands = {
|
||||||
|
@ -324,21 +325,24 @@ class FormulaConfig(object):
|
||||||
|
|
||||||
alphacommands = {
|
alphacommands = {
|
||||||
u'\\AA':u'Å', u'\\AE':u'Æ',
|
u'\\AA':u'Å', u'\\AE':u'Æ',
|
||||||
u'\\AmS':u'<span class="versalitas">AmS</span>', u'\\DH':u'Ð',
|
u'\\AmS':u'<span class="versalitas">AmS</span>', u'\\Angstroem':u'Å',
|
||||||
u'\\L':u'Ł', u'\\O':u'Ø', u'\\OE':u'Œ', u'\\TH':u'Þ', u'\\aa':u'å',
|
u'\\DH':u'Ð', u'\\Koppa':u'Ϟ', u'\\L':u'Ł', u'\\Micro':u'µ', u'\\O':u'Ø',
|
||||||
u'\\ae':u'æ', u'\\alpha':u'α', u'\\beta':u'β', u'\\delta':u'δ',
|
u'\\OE':u'Œ', u'\\Sampi':u'Ϡ', u'\\Stigma':u'Ϛ', u'\\TH':u'Þ',
|
||||||
u'\\dh':u'ð', u'\\epsilon':u'ϵ', u'\\eta':u'η', u'\\gamma':u'γ',
|
u'\\aa':u'å', u'\\ae':u'æ', u'\\alpha':u'α', u'\\beta':u'β',
|
||||||
u'\\i':u'ı', u'\\imath':u'ı', u'\\iota':u'ι', u'\\j':u'ȷ',
|
u'\\delta':u'δ', u'\\dh':u'ð', u'\\digamma':u'ϝ', u'\\epsilon':u'ϵ',
|
||||||
u'\\jmath':u'ȷ', u'\\kappa':u'κ', u'\\l':u'ł', u'\\lambda':u'λ',
|
u'\\eta':u'η', u'\\eth':u'ð', u'\\gamma':u'γ', u'\\i':u'ı',
|
||||||
|
u'\\imath':u'ı', u'\\iota':u'ι', u'\\j':u'ȷ', u'\\jmath':u'ȷ',
|
||||||
|
u'\\kappa':u'κ', u'\\koppa':u'ϟ', u'\\l':u'ł', u'\\lambda':u'λ',
|
||||||
u'\\mu':u'μ', u'\\nu':u'ν', u'\\o':u'ø', u'\\oe':u'œ', u'\\omega':u'ω',
|
u'\\mu':u'μ', u'\\nu':u'ν', u'\\o':u'ø', u'\\oe':u'œ', u'\\omega':u'ω',
|
||||||
u'\\phi':u'φ', u'\\pi':u'π', u'\\psi':u'ψ', u'\\rho':u'ρ',
|
u'\\phi':u'φ', u'\\pi':u'π', u'\\psi':u'ψ', u'\\rho':u'ρ',
|
||||||
u'\\sigma':u'σ', u'\\ss':u'ß', u'\\tau':u'τ', u'\\textcrh':u'ħ',
|
u'\\sampi':u'ϡ', u'\\sigma':u'σ', u'\\ss':u'ß', u'\\stigma':u'ϛ',
|
||||||
u'\\th':u'þ', u'\\theta':u'θ', u'\\upsilon':u'υ', u'\\varDelta':u'∆',
|
u'\\tau':u'τ', u'\\tcohm':u'Ω', u'\\textcrh':u'ħ', u'\\th':u'þ',
|
||||||
|
u'\\theta':u'θ', u'\\upsilon':u'υ', u'\\varDelta':u'∆',
|
||||||
u'\\varGamma':u'Γ', u'\\varLambda':u'Λ', u'\\varOmega':u'Ω',
|
u'\\varGamma':u'Γ', u'\\varLambda':u'Λ', u'\\varOmega':u'Ω',
|
||||||
u'\\varPhi':u'Φ', u'\\varPi':u'Π', u'\\varPsi':u'Ψ', u'\\varSigma':u'Σ',
|
u'\\varPhi':u'Φ', u'\\varPi':u'Π', u'\\varPsi':u'Ψ', u'\\varSigma':u'Σ',
|
||||||
u'\\varTheta':u'Θ', u'\\varUpsilon':u'Υ', u'\\varXi':u'Ξ',
|
u'\\varTheta':u'Θ', u'\\varUpsilon':u'Υ', u'\\varXi':u'Ξ',
|
||||||
u'\\varepsilon':u'ε', u'\\varkappa':u'ϰ', u'\\varphi':u'φ',
|
u'\\varbeta':u'ϐ', u'\\varepsilon':u'ε', u'\\varkappa':u'ϰ',
|
||||||
u'\\varpi':u'ϖ', u'\\varrho':u'ϱ', u'\\varsigma':u'ς',
|
u'\\varphi':u'φ', u'\\varpi':u'ϖ', u'\\varrho':u'ϱ', u'\\varsigma':u'ς',
|
||||||
u'\\vartheta':u'ϑ', u'\\xi':u'ξ', u'\\zeta':u'ζ',
|
u'\\vartheta':u'ϑ', u'\\xi':u'ξ', u'\\zeta':u'ζ',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,59 +380,75 @@ class FormulaConfig(object):
|
||||||
|
|
||||||
commands = {
|
commands = {
|
||||||
u'\\ ':u' ', u'\\!':u'', u'\\#':u'#', u'\\$':u'$', u'\\%':u'%',
|
u'\\ ':u' ', u'\\!':u'', u'\\#':u'#', u'\\$':u'$', u'\\%':u'%',
|
||||||
u'\\&':u'&', u'\\,':u' ', u'\\:':u' ', u'\\;':u' ',
|
u'\\&':u'&', u'\\,':u' ', u'\\:':u' ', u'\\;':u' ', u'\\AC':u'∿',
|
||||||
u'\\APLdownarrowbox':u'⍗', u'\\APLleftarrowbox':u'⍇',
|
u'\\APLcomment':u'⍝', u'\\APLdownarrowbox':u'⍗', u'\\APLinput':u'⍞',
|
||||||
|
u'\\APLinv':u'⌹', u'\\APLleftarrowbox':u'⍇', u'\\APLlog':u'⍟',
|
||||||
u'\\APLrightarrowbox':u'⍈', u'\\APLuparrowbox':u'⍐', u'\\Box':u'□',
|
u'\\APLrightarrowbox':u'⍈', u'\\APLuparrowbox':u'⍐', u'\\Box':u'□',
|
||||||
u'\\Bumpeq':u'≎', u'\\CIRCLE':u'●', u'\\Cap':u'⋒', u'\\CheckedBox':u'☑',
|
u'\\Bumpeq':u'≎', u'\\CIRCLE':u'●', u'\\Cap':u'⋒',
|
||||||
u'\\Circle':u'○', u'\\Coloneqq':u'⩴', u'\\Corresponds':u'≙',
|
u'\\CapitalDifferentialD':u'ⅅ', u'\\CheckedBox':u'☑', u'\\Circle':u'○',
|
||||||
u'\\Cup':u'⋓', u'\\Delta':u'Δ', u'\\Diamond':u'◇', u'\\Downarrow':u'⇓',
|
u'\\Coloneqq':u'⩴', u'\\ComplexI':u'ⅈ', u'\\ComplexJ':u'ⅉ',
|
||||||
u'\\EUR':u'€', u'\\Game':u'⅁', u'\\Gamma':u'Γ', u'\\Im':u'ℑ',
|
u'\\Corresponds':u'≙', u'\\Cup':u'⋓', u'\\Delta':u'Δ', u'\\Diamond':u'◇',
|
||||||
u'\\Join':u'⨝', u'\\LEFTCIRCLE':u'◖', u'\\LEFTcircle':u'◐',
|
u'\\Diamondblack':u'◆', u'\\Diamonddot':u'⟐', u'\\DifferentialD':u'ⅆ',
|
||||||
u'\\Lambda':u'Λ', u'\\Leftarrow':u'⇐', u'\\Lleftarrow':u'⇚',
|
u'\\Downarrow':u'⇓', u'\\EUR':u'€', u'\\Euler':u'ℇ',
|
||||||
u'\\Longleftarrow':u'⟸', u'\\Longleftrightarrow':u'⟺',
|
u'\\ExponetialE':u'ⅇ', u'\\Finv':u'Ⅎ', u'\\Game':u'⅁', u'\\Gamma':u'Γ',
|
||||||
u'\\Longrightarrow':u'⟹', u'\\Lsh':u'↰', u'\\Mapsfrom':u'⇐|',
|
u'\\Im':u'ℑ', u'\\Join':u'⨝', u'\\LEFTCIRCLE':u'◖', u'\\LEFTcircle':u'◐',
|
||||||
u'\\Mapsto':u'|⇒', u'\\Omega':u'Ω', u'\\P':u'¶', u'\\Phi':u'Φ',
|
u'\\LHD':u'◀', u'\\Lambda':u'Λ', u'\\Lbag':u'⟅', u'\\Leftarrow':u'⇐',
|
||||||
u'\\Pi':u'Π', u'\\Pr':u'Pr', u'\\Psi':u'Ψ', u'\\RIGHTCIRCLE':u'◗',
|
u'\\Lleftarrow':u'⇚', u'\\Longleftarrow':u'⟸',
|
||||||
u'\\RIGHTcircle':u'◑', u'\\Re':u'ℜ', u'\\Rrightarrow':u'⇛',
|
u'\\Longleftrightarrow':u'⟺', u'\\Longrightarrow':u'⟹', u'\\Lparen':u'⦅',
|
||||||
u'\\Rsh':u'↱', u'\\S':u'§', u'\\Sigma':u'Σ', u'\\Square':u'☐',
|
u'\\Lsh':u'↰', u'\\Mapsfrom':u'⇐|', u'\\Mapsto':u'|⇒', u'\\Omega':u'Ω',
|
||||||
u'\\Subset':u'⋐', u'\\Supset':u'⋑', u'\\Theta':u'Θ', u'\\Uparrow':u'⇑',
|
u'\\P':u'¶', u'\\Phi':u'Φ', u'\\Pi':u'Π', u'\\Pr':u'Pr', u'\\Psi':u'Ψ',
|
||||||
u'\\Updownarrow':u'⇕', u'\\Upsilon':u'Υ', u'\\Vdash':u'⊩',
|
u'\\Qoppa':u'Ϙ', u'\\RHD':u'▶', u'\\RIGHTCIRCLE':u'◗',
|
||||||
u'\\Vert':u'∥', u'\\Vvdash':u'⊪', u'\\XBox':u'☒', u'\\Xi':u'Ξ',
|
u'\\RIGHTcircle':u'◑', u'\\Rbag':u'⟆', u'\\Re':u'ℜ', u'\\Rparen':u'⦆',
|
||||||
u'\\Yup':u'⅄', u'\\\\':u'<br/>', u'\\_':u'_', u'\\aleph':u'ℵ',
|
u'\\Rrightarrow':u'⇛', u'\\Rsh':u'↱', u'\\S':u'§', u'\\Sigma':u'Σ',
|
||||||
u'\\amalg':u'∐', u'\\angle':u'∠', u'\\aquarius':u'♒',
|
u'\\Square':u'☐', u'\\Subset':u'⋐', u'\\Sun':u'☉', u'\\Supset':u'⋑',
|
||||||
u'\\arccos':u'arccos', u'\\arcsin':u'arcsin', u'\\arctan':u'arctan',
|
u'\\Theta':u'Θ', u'\\Uparrow':u'⇑', u'\\Updownarrow':u'⇕',
|
||||||
u'\\arg':u'arg', u'\\aries':u'♈', u'\\ast':u'∗', u'\\asymp':u'≍',
|
u'\\Upsilon':u'Υ', u'\\Vdash':u'⊩', u'\\Vert':u'∥', u'\\Vvdash':u'⊪',
|
||||||
|
u'\\XBox':u'☒', u'\\Xi':u'Ξ', u'\\Yup':u'⅄', u'\\\\':u'<br/>',
|
||||||
|
u'\\_':u'_', u'\\aleph':u'ℵ', u'\\amalg':u'∐', u'\\anchor':u'⚓',
|
||||||
|
u'\\angle':u'∠', u'\\aquarius':u'♒', u'\\arccos':u'arccos',
|
||||||
|
u'\\arcsin':u'arcsin', u'\\arctan':u'arctan', u'\\arg':u'arg',
|
||||||
|
u'\\aries':u'♈', u'\\arrowbullet':u'➢', u'\\ast':u'∗', u'\\asymp':u'≍',
|
||||||
u'\\backepsilon':u'∍', u'\\backprime':u'‵', u'\\backsimeq':u'⋍',
|
u'\\backepsilon':u'∍', u'\\backprime':u'‵', u'\\backsimeq':u'⋍',
|
||||||
u'\\backslash':u'\\', u'\\barwedge':u'⊼', u'\\because':u'∵',
|
u'\\backslash':u'\\', u'\\ballotx':u'✗', u'\\barwedge':u'⊼',
|
||||||
u'\\beth':u'ℶ', u'\\between':u'≬', u'\\bigcap':u'∩', u'\\bigcirc':u'○',
|
u'\\because':u'∵', u'\\beth':u'ℶ', u'\\between':u'≬', u'\\bigcap':u'∩',
|
||||||
u'\\bigcup':u'∪', u'\\bigodot':u'⊙', u'\\bigoplus':u'⊕',
|
u'\\bigcirc':u'○', u'\\bigcup':u'∪', u'\\bigodot':u'⊙',
|
||||||
u'\\bigotimes':u'⊗', u'\\bigsqcup':u'⊔', u'\\bigstar':u'★',
|
u'\\bigoplus':u'⊕', u'\\bigotimes':u'⊗', u'\\bigsqcup':u'⊔',
|
||||||
u'\\bigtriangledown':u'▽', u'\\bigtriangleup':u'△', u'\\biguplus':u'⊎',
|
u'\\bigstar':u'★', u'\\bigtriangledown':u'▽', u'\\bigtriangleup':u'△',
|
||||||
u'\\bigvee':u'∨', u'\\bigwedge':u'∧', u'\\blacklozenge':u'⧫',
|
u'\\biguplus':u'⊎', u'\\bigvee':u'∨', u'\\bigwedge':u'∧',
|
||||||
u'\\blacksmiley':u'☻', u'\\blacksquare':u'■', u'\\blacktriangle':u'▲',
|
u'\\biohazard':u'☣', u'\\blacklozenge':u'⧫', u'\\blacksmiley':u'☻',
|
||||||
u'\\blacktriangledown':u'▼', u'\\blacktriangleright':u'▶', u'\\bot':u'⊥',
|
u'\\blacksquare':u'■', u'\\blacktriangle':u'▲',
|
||||||
u'\\bowtie':u'⋈', u'\\box':u'▫', u'\\boxdot':u'⊡', u'\\bullet':u'•',
|
u'\\blacktriangledown':u'▼', u'\\blacktriangleleft':u'◂',
|
||||||
|
u'\\blacktriangleright':u'▶', u'\\blacktriangleup':u'▴', u'\\bot':u'⊥',
|
||||||
|
u'\\bowtie':u'⋈', u'\\box':u'▫', u'\\boxast':u'⧆', u'\\boxbar':u'◫',
|
||||||
|
u'\\boxbox':u'⧈', u'\\boxbslash':u'⧅', u'\\boxcircle':u'⧇',
|
||||||
|
u'\\boxdot':u'⊡', u'\\boxminus':u'⊟', u'\\boxplus':u'⊞',
|
||||||
|
u'\\boxslash':u'⧄', u'\\boxtimes':u'⊠', u'\\bullet':u'•',
|
||||||
u'\\bumpeq':u'≏', u'\\cancer':u'♋', u'\\cap':u'∩', u'\\capricornus':u'♑',
|
u'\\bumpeq':u'≏', u'\\cancer':u'♋', u'\\cap':u'∩', u'\\capricornus':u'♑',
|
||||||
u'\\cdot':u'⋅', u'\\cdots':u'⋯', u'\\centerdot':u'∙',
|
u'\\cat':u'⁀', u'\\cdot':u'⋅', u'\\cdots':u'⋯', u'\\cent':u'¢',
|
||||||
u'\\checkmark':u'✓', u'\\chi':u'χ', u'\\circ':u'○', u'\\circeq':u'≗',
|
u'\\centerdot':u'∙', u'\\checkmark':u'✓', u'\\chi':u'χ', u'\\circ':u'∘',
|
||||||
u'\\circledR':u'®', u'\\circledast':u'⊛', u'\\circledcirc':u'⊚',
|
u'\\circeq':u'≗', u'\\circlearrowleft':u'↺', u'\\circlearrowright':u'↻',
|
||||||
u'\\circleddash':u'⊝', u'\\clubsuit':u'♣', u'\\coloneqq':u'≔',
|
u'\\circledR':u'®', u'\\circledast':u'⊛', u'\\circledbslash':u'⦸',
|
||||||
|
u'\\circledcirc':u'⊚', u'\\circleddash':u'⊝', u'\\circledgtr':u'⧁',
|
||||||
|
u'\\circledless':u'⧀', u'\\clubsuit':u'♣', u'\\colon':u': ', u'\\coloneqq':u'≔',
|
||||||
u'\\complement':u'∁', u'\\cong':u'≅', u'\\coprod':u'∐',
|
u'\\complement':u'∁', u'\\cong':u'≅', u'\\coprod':u'∐',
|
||||||
u'\\copyright':u'©', u'\\cos':u'cos', u'\\cosh':u'cosh', u'\\cot':u'cot',
|
u'\\copyright':u'©', u'\\cos':u'cos', u'\\cosh':u'cosh', u'\\cot':u'cot',
|
||||||
u'\\coth':u'coth', u'\\csc':u'csc', u'\\cup':u'∪',
|
u'\\coth':u'coth', u'\\csc':u'csc', u'\\cup':u'∪', u'\\curlyvee':u'⋎',
|
||||||
u'\\curvearrowleft':u'↶', u'\\curvearrowright':u'↷', u'\\dag':u'†',
|
u'\\curlywedge':u'⋏', u'\\curvearrowleft':u'↶',
|
||||||
u'\\dagger':u'†', u'\\daleth':u'ℸ', u'\\dashleftarrow':u'⇠',
|
u'\\curvearrowright':u'↷', u'\\dag':u'†', u'\\dagger':u'†',
|
||||||
u'\\dashv':u'⊣', u'\\ddag':u'‡', u'\\ddagger':u'‡', u'\\ddots':u'⋱',
|
u'\\daleth':u'ℸ', u'\\dashleftarrow':u'⇠', u'\\dashv':u'⊣',
|
||||||
u'\\deg':u'deg', u'\\det':u'det', u'\\diagdown':u'╲', u'\\diagup':u'╱',
|
u'\\ddag':u'‡', u'\\ddagger':u'‡', u'\\ddots':u'⋱', u'\\deg':u'deg',
|
||||||
u'\\diamond':u'◇', u'\\diamondsuit':u'♦', u'\\dim':u'dim', u'\\div':u'÷',
|
u'\\det':u'det', u'\\diagdown':u'╲', u'\\diagup':u'╱',
|
||||||
u'\\divideontimes':u'⋇', u'\\dotdiv':u'∸', u'\\doteq':u'≐',
|
u'\\diameter':u'⌀', u'\\diamond':u'◇', u'\\diamondsuit':u'♦',
|
||||||
u'\\doteqdot':u'≑', u'\\dotplus':u'∔', u'\\dots':u'…',
|
u'\\dim':u'dim', u'\\div':u'÷', u'\\divideontimes':u'⋇',
|
||||||
u'\\doublebarwedge':u'⌆', u'\\downarrow':u'↓', u'\\downdownarrows':u'⇊',
|
u'\\dotdiv':u'∸', u'\\doteq':u'≐', u'\\doteqdot':u'≑', u'\\dotplus':u'∔',
|
||||||
u'\\downharpoonleft':u'⇃', u'\\downharpoonright':u'⇂', u'\\earth':u'♁',
|
u'\\dots':u'…', u'\\doublebarwedge':u'⌆', u'\\downarrow':u'↓',
|
||||||
u'\\ell':u'ℓ', u'\\emptyset':u'∅', u'\\eqcirc':u'≖', u'\\eqcolon':u'≕',
|
u'\\downdownarrows':u'⇊', u'\\downharpoonleft':u'⇃',
|
||||||
u'\\eqsim':u'≂', u'\\euro':u'€', u'\\exists':u'∃', u'\\exp':u'exp',
|
u'\\downharpoonright':u'⇂', u'\\dsub':u'⩤', u'\\earth':u'♁',
|
||||||
u'\\fallingdotseq':u'≒', u'\\female':u'♀', u'\\flat':u'♭',
|
u'\\eighthnote':u'♪', u'\\ell':u'ℓ', u'\\emptyset':u'∅',
|
||||||
u'\\forall':u'∀', u'\\frown':u'⌢', u'\\frownie':u'☹', u'\\gcd':u'gcd',
|
u'\\eqcirc':u'≖', u'\\eqcolon':u'≕', u'\\eqsim':u'≂', u'\\euro':u'€',
|
||||||
|
u'\\exists':u'∃', u'\\exp':u'exp', u'\\fallingdotseq':u'≒',
|
||||||
|
u'\\fcmp':u'⨾', u'\\female':u'♀', u'\\flat':u'♭', u'\\forall':u'∀',
|
||||||
|
u'\\fourth':u'⁗', u'\\frown':u'⌢', u'\\frownie':u'☹', u'\\gcd':u'gcd',
|
||||||
u'\\gemini':u'♊', u'\\geq)':u'≥', u'\\geqq':u'≧', u'\\geqslant':u'≥',
|
u'\\gemini':u'♊', u'\\geq)':u'≥', u'\\geqq':u'≧', u'\\geqslant':u'≥',
|
||||||
u'\\gets':u'←', u'\\gg':u'≫', u'\\ggg':u'⋙', u'\\gimel':u'ℷ',
|
u'\\gets':u'←', u'\\gg':u'≫', u'\\ggg':u'⋙', u'\\gimel':u'ℷ',
|
||||||
u'\\gneqq':u'≩', u'\\gnsim':u'⋧', u'\\gtrdot':u'⋗', u'\\gtreqless':u'⋚',
|
u'\\gneqq':u'≩', u'\\gnsim':u'⋧', u'\\gtrdot':u'⋗', u'\\gtreqless':u'⋚',
|
||||||
|
@ -439,41 +459,44 @@ class FormulaConfig(object):
|
||||||
u'\\hslash':u'ℏ', u'\\idotsint':u'<span class="bigsymbol">∫⋯∫</span>',
|
u'\\hslash':u'ℏ', u'\\idotsint':u'<span class="bigsymbol">∫⋯∫</span>',
|
||||||
u'\\iiint':u'<span class="bigsymbol">∭</span>',
|
u'\\iiint':u'<span class="bigsymbol">∭</span>',
|
||||||
u'\\iint':u'<span class="bigsymbol">∬</span>', u'\\imath':u'ı',
|
u'\\iint':u'<span class="bigsymbol">∬</span>', u'\\imath':u'ı',
|
||||||
u'\\inf':u'inf', u'\\infty':u'∞', u'\\invneg':u'⌐', u'\\jmath':u'ȷ',
|
u'\\inf':u'inf', u'\\infty':u'∞', u'\\intercal':u'⊺',
|
||||||
u'\\jupiter':u'♃', u'\\ker':u'ker', u'\\land':u'∧',
|
u'\\interleave':u'⫴', u'\\invamp':u'⅋', u'\\invneg':u'⌐',
|
||||||
u'\\landupint':u'<span class="bigsymbol">∱</span>', u'\\langle':u'⟨',
|
u'\\jmath':u'ȷ', u'\\jupiter':u'♃', u'\\ker':u'ker', u'\\land':u'∧',
|
||||||
u'\\lbrace':u'{', u'\\lbrace)':u'{', u'\\lbrack':u'[', u'\\lceil':u'⌈',
|
u'\\landupint':u'<span class="bigsymbol">∱</span>', u'\\lang':u'⟪',
|
||||||
u'\\ldots':u'…', u'\\leadsto':u'⇝', u'\\leftarrow)':u'←',
|
u'\\langle':u'⟨', u'\\lblot':u'⦉', u'\\lbrace':u'{', u'\\lbrace)':u'{',
|
||||||
u'\\leftarrowtail':u'↢', u'\\leftarrowtobar':u'⇤',
|
u'\\lbrack':u'[', u'\\lceil':u'⌈', u'\\ldots':u'…', u'\\leadsto':u'⇝',
|
||||||
|
u'\\leftarrow)':u'←', u'\\leftarrowtail':u'↢', u'\\leftarrowtobar':u'⇤',
|
||||||
u'\\leftharpoondown':u'↽', u'\\leftharpoonup':u'↼',
|
u'\\leftharpoondown':u'↽', u'\\leftharpoonup':u'↼',
|
||||||
u'\\leftleftarrows':u'⇇', u'\\leftleftharpoons':u'⥢', u'\\leftmoon':u'☾',
|
u'\\leftleftarrows':u'⇇', u'\\leftleftharpoons':u'⥢', u'\\leftmoon':u'☾',
|
||||||
u'\\leftrightarrow':u'↔', u'\\leftrightarrows':u'⇆',
|
u'\\leftrightarrow':u'↔', u'\\leftrightarrows':u'⇆',
|
||||||
u'\\leftrightharpoons':u'⇋', u'\\leftthreetimes':u'⋋', u'\\leo':u'♌',
|
u'\\leftrightharpoons':u'⇋', u'\\leftthreetimes':u'⋋', u'\\leo':u'♌',
|
||||||
u'\\leq)':u'≤', u'\\leqq':u'≦', u'\\leqslant':u'≤', u'\\lessdot':u'⋖',
|
u'\\leq)':u'≤', u'\\leqq':u'≦', u'\\leqslant':u'≤', u'\\lessdot':u'⋖',
|
||||||
u'\\lesseqgtr':u'⋛', u'\\lesseqqgtr':u'⪋', u'\\lessgtr':u'≶',
|
u'\\lesseqgtr':u'⋛', u'\\lesseqqgtr':u'⪋', u'\\lessgtr':u'≶',
|
||||||
u'\\lesssim':u'≲', u'\\lfloor':u'⌊', u'\\lg':u'lg', u'\\lhd':u'⊲',
|
u'\\lesssim':u'≲', u'\\lfloor':u'⌊', u'\\lg':u'lg', u'\\lgroup':u'⟮',
|
||||||
u'\\libra':u'♎', u'\\lightning':u'↯', u'\\liminf':u'liminf',
|
u'\\lhd':u'⊲', u'\\libra':u'♎', u'\\lightning':u'↯', u'\\limg':u'⦇',
|
||||||
u'\\limsup':u'limsup', u'\\ll':u'≪', u'\\lll':u'⋘', u'\\ln':u'ln',
|
u'\\liminf':u'liminf', u'\\limsup':u'limsup', u'\\ll':u'≪',
|
||||||
|
u'\\llbracket':u'⟦', u'\\llcorner':u'⌞', u'\\lll':u'⋘', u'\\ln':u'ln',
|
||||||
u'\\lneqq':u'≨', u'\\lnot':u'¬', u'\\lnsim':u'⋦', u'\\log':u'log',
|
u'\\lneqq':u'≨', u'\\lnot':u'¬', u'\\lnsim':u'⋦', u'\\log':u'log',
|
||||||
u'\\longleftarrow':u'⟵', u'\\longleftrightarrow':u'⟷',
|
u'\\longleftarrow':u'⟵', u'\\longleftrightarrow':u'⟷',
|
||||||
u'\\longmapsto':u'⟼', u'\\longrightarrow':u'⟶', u'\\looparrowleft':u'↫',
|
u'\\longmapsto':u'⟼', u'\\longrightarrow':u'⟶', u'\\looparrowleft':u'↫',
|
||||||
u'\\looparrowright':u'↬', u'\\lor':u'∨', u'\\lozenge':u'◊',
|
u'\\looparrowright':u'↬', u'\\lor':u'∨', u'\\lozenge':u'◊',
|
||||||
u'\\ltimes':u'⋉', u'\\lyxlock':u'', u'\\male':u'♂', u'\\maltese':u'✠',
|
u'\\lrcorner':u'⌟', u'\\ltimes':u'⋉', u'\\lyxlock':u'', u'\\male':u'♂',
|
||||||
u'\\mapsfrom':u'↤', u'\\mapsto':u'↦', u'\\mathcircumflex':u'^',
|
u'\\maltese':u'✠', u'\\mapsfrom':u'↤', u'\\mapsto':u'↦',
|
||||||
u'\\max':u'max', u'\\measuredangle':u'∡', u'\\mercury':u'☿',
|
u'\\mathcircumflex':u'^', u'\\max':u'max', u'\\measuredangle':u'∡',
|
||||||
u'\\mho':u'℧', u'\\mid':u'∣', u'\\min':u'min', u'\\models':u'⊨',
|
u'\\medbullet':u'⚫', u'\\medcirc':u'⚪', u'\\mercury':u'☿', u'\\mho':u'℧',
|
||||||
u'\\mp':u'∓', u'\\multimap':u'⊸', u'\\nLeftarrow':u'⇍',
|
u'\\mid':u'∣', u'\\min':u'min', u'\\models':u'⊨', u'\\mp':u'∓',
|
||||||
u'\\nLeftrightarrow':u'⇎', u'\\nRightarrow':u'⇏', u'\\nVDash':u'⊯',
|
u'\\multimap':u'⊸', u'\\nLeftarrow':u'⇍', u'\\nLeftrightarrow':u'⇎',
|
||||||
u'\\nabla':u'∇', u'\\napprox':u'≉', u'\\natural':u'♮', u'\\ncong':u'≇',
|
u'\\nRightarrow':u'⇏', u'\\nVDash':u'⊯', u'\\nabla':u'∇',
|
||||||
u'\\nearrow':u'↗', u'\\neg':u'¬', u'\\neg)':u'¬', u'\\neptune':u'♆',
|
u'\\napprox':u'≉', u'\\natural':u'♮', u'\\ncong':u'≇', u'\\nearrow':u'↗',
|
||||||
u'\\nequiv':u'≢', u'\\newline':u'<br/>', u'\\nexists':u'∄',
|
u'\\neg':u'¬', u'\\neg)':u'¬', u'\\neptune':u'♆', u'\\nequiv':u'≢',
|
||||||
u'\\ngeqslant':u'≱', u'\\ngtr':u'≯', u'\\ngtrless':u'≹', u'\\ni':u'∋',
|
u'\\newline':u'<br/>', u'\\nexists':u'∄', u'\\ngeqslant':u'≱',
|
||||||
u'\\ni)':u'∋', u'\\nleftarrow':u'↚', u'\\nleftrightarrow':u'↮',
|
u'\\ngtr':u'≯', u'\\ngtrless':u'≹', u'\\ni':u'∋', u'\\ni)':u'∋',
|
||||||
u'\\nleqslant':u'≰', u'\\nless':u'≮', u'\\nlessgtr':u'≸', u'\\nmid':u'∤',
|
u'\\nleftarrow':u'↚', u'\\nleftrightarrow':u'↮', u'\\nleqslant':u'≰',
|
||||||
u'\\nolimits':u'', u'\\nonumber':u'', u'\\not':u'¬', u'\\not<':u'≮',
|
u'\\nless':u'≮', u'\\nlessgtr':u'≸', u'\\nmid':u'∤', u'\\nolimits':u'',
|
||||||
u'\\not=':u'≠', u'\\not>':u'≯', u'\\notbackslash':u'⍀', u'\\notin':u'∉',
|
u'\\nonumber':u'', u'\\not':u'¬', u'\\not<':u'≮', u'\\not=':u'≠',
|
||||||
u'\\notni':u'∌', u'\\notslash':u'⌿', u'\\nparallel':u'∦',
|
u'\\not>':u'≯', u'\\notbackslash':u'⍀', u'\\notin':u'∉', u'\\notni':u'∌',
|
||||||
u'\\nprec':u'⊀', u'\\nrightarrow':u'↛', u'\\nsim':u'≁', u'\\nsimeq':u'≄',
|
u'\\notslash':u'⌿', u'\\nparallel':u'∦', u'\\nprec':u'⊀',
|
||||||
|
u'\\nrightarrow':u'↛', u'\\nsim':u'≁', u'\\nsimeq':u'≄',
|
||||||
u'\\nsqsubset':u'⊏̸', u'\\nsubseteq':u'⊈', u'\\nsucc':u'⊁',
|
u'\\nsqsubset':u'⊏̸', u'\\nsubseteq':u'⊈', u'\\nsucc':u'⊁',
|
||||||
u'\\nsucccurlyeq':u'⋡', u'\\nsupset':u'⊅', u'\\nsupseteq':u'⊉',
|
u'\\nsucccurlyeq':u'⋡', u'\\nsupset':u'⊅', u'\\nsupseteq':u'⊉',
|
||||||
u'\\ntriangleleft':u'⋪', u'\\ntrianglelefteq':u'⋬',
|
u'\\ntriangleleft':u'⋪', u'\\ntrianglelefteq':u'⋬',
|
||||||
|
@ -485,31 +508,40 @@ class FormulaConfig(object):
|
||||||
u'\\ointclockwise':u'<span class="bigsymbol">∲</span>',
|
u'\\ointclockwise':u'<span class="bigsymbol">∲</span>',
|
||||||
u'\\ointctrclockwise':u'<span class="bigsymbol">∳</span>',
|
u'\\ointctrclockwise':u'<span class="bigsymbol">∳</span>',
|
||||||
u'\\ominus':u'⊖', u'\\oplus':u'⊕', u'\\oslash':u'⊘', u'\\otimes':u'⊗',
|
u'\\ominus':u'⊖', u'\\oplus':u'⊕', u'\\oslash':u'⊘', u'\\otimes':u'⊗',
|
||||||
u'\\owns':u'∋', u'\\parallel':u'∥', u'\\partial':u'∂', u'\\perp':u'⊥',
|
u'\\owns':u'∋', u'\\parallel':u'∥', u'\\partial':u'∂', u'\\pencil':u'✎',
|
||||||
u'\\pisces':u'♓', u'\\pitchfork':u'⋔', u'\\pluto':u'♇', u'\\pm':u'±',
|
u'\\perp':u'⊥', u'\\pisces':u'♓', u'\\pitchfork':u'⋔', u'\\pluto':u'♇',
|
||||||
u'\\pointer':u'➪', u'\\pounds':u'£', u'\\prec':u'≺',
|
u'\\pm':u'±', u'\\pointer':u'➪', u'\\pointright':u'☞', u'\\pounds':u'£',
|
||||||
u'\\preccurlyeq':u'≼', u'\\preceq':u'≼', u'\\precsim':u'≾',
|
u'\\prec':u'≺', u'\\preccurlyeq':u'≼', u'\\preceq':u'≼',
|
||||||
u'\\prime':u'′', u'\\prompto':u'∝', u'\\qquad':u' ', u'\\quad':u' ',
|
u'\\precsim':u'≾', u'\\prime':u'′', u'\\prompto':u'∝', u'\\qoppa':u'ϙ',
|
||||||
u'\\quarternote':u'♩', u'\\rangle':u'⟩', u'\\rbrace':u'}',
|
u'\\qquad':u' ', u'\\quad':u' ', u'\\quarternote':u'♩',
|
||||||
u'\\rbrace)':u'}', u'\\rbrack':u']', u'\\rceil':u'⌉', u'\\rfloor':u'⌋',
|
u'\\radiation':u'☢', u'\\rang':u'⟫', u'\\rangle':u'⟩', u'\\rblot':u'⦊',
|
||||||
u'\\rhd':u'⊳', u'\\rightarrow)':u'→', u'\\rightarrowtail':u'↣',
|
u'\\rbrace':u'}', u'\\rbrace)':u'}', u'\\rbrack':u']', u'\\rceil':u'⌉',
|
||||||
|
u'\\recycle':u'♻', u'\\rfloor':u'⌋', u'\\rgroup':u'⟯', u'\\rhd':u'⊳',
|
||||||
|
u'\\rightangle':u'∟', u'\\rightarrow)':u'→', u'\\rightarrowtail':u'↣',
|
||||||
u'\\rightarrowtobar':u'⇥', u'\\rightharpoondown':u'⇁',
|
u'\\rightarrowtobar':u'⇥', u'\\rightharpoondown':u'⇁',
|
||||||
u'\\rightharpoonup':u'⇀', u'\\rightharpooondown':u'⇁',
|
u'\\rightharpoonup':u'⇀', u'\\rightharpooondown':u'⇁',
|
||||||
u'\\rightharpooonup':u'⇀', u'\\rightleftarrows':u'⇄',
|
u'\\rightharpooonup':u'⇀', u'\\rightleftarrows':u'⇄',
|
||||||
u'\\rightleftharpoons':u'⇌', u'\\rightmoon':u'☽',
|
u'\\rightleftharpoons':u'⇌', u'\\rightmoon':u'☽',
|
||||||
u'\\rightrightarrows':u'⇉', u'\\rightrightharpoons':u'⥤',
|
u'\\rightrightarrows':u'⇉', u'\\rightrightharpoons':u'⥤',
|
||||||
u'\\rightthreetimes':u'⋌', u'\\risingdotseq':u'≓', u'\\rtimes':u'⋊',
|
u'\\rightthreetimes':u'⋌', u'\\rimg':u'⦈', u'\\risingdotseq':u'≓',
|
||||||
|
u'\\rrbracket':u'⟧', u'\\rsub':u'⩥', u'\\rtimes':u'⋊',
|
||||||
u'\\sagittarius':u'♐', u'\\saturn':u'♄', u'\\scorpio':u'♏',
|
u'\\sagittarius':u'♐', u'\\saturn':u'♄', u'\\scorpio':u'♏',
|
||||||
u'\\searrow':u'↘', u'\\sec':u'sec', u'\\setminus':u'∖', u'\\sharp':u'♯',
|
u'\\searrow':u'↘', u'\\sec':u'sec', u'\\second':u'″', u'\\setminus':u'∖',
|
||||||
u'\\simeq':u'≃', u'\\sin':u'sin', u'\\sinh':u'sinh', u'\\slash':u'∕',
|
u'\\sharp':u'♯', u'\\simeq':u'≃', u'\\sin':u'sin', u'\\sinh':u'sinh',
|
||||||
u'\\smile':u'⌣', u'\\smiley':u'☺', u'\\spadesuit':u'♠',
|
u'\\sixteenthnote':u'♬', u'\\skull':u'☠', u'\\slash':u'∕',
|
||||||
u'\\sphericalangle':u'∢', u'\\sqcap':u'⊓', u'\\sqcup':u'⊔',
|
u'\\smallsetminus':u'∖', u'\\smalltriangledown':u'▿',
|
||||||
u'\\sqsubset':u'⊏', u'\\sqsubseteq':u'⊑', u'\\sqsupset':u'⊐',
|
u'\\smalltriangleleft':u'◃', u'\\smalltriangleright':u'▹',
|
||||||
u'\\sqsupseteq':u'⊒', u'\\square':u'□', u'\\star':u'⋆',
|
u'\\smalltriangleup':u'▵', u'\\smile':u'⌣', u'\\smiley':u'☺',
|
||||||
|
u'\\spadesuit':u'♠', u'\\spddot':u'¨', u'\\sphat':u'',
|
||||||
|
u'\\sphericalangle':u'∢', u'\\spot':u'⦁', u'\\sptilde':u'~',
|
||||||
|
u'\\sqcap':u'⊓', u'\\sqcup':u'⊔', u'\\sqsubset':u'⊏',
|
||||||
|
u'\\sqsubseteq':u'⊑', u'\\sqsupset':u'⊐', u'\\sqsupseteq':u'⊒',
|
||||||
|
u'\\square':u'□', u'\\sslash':u'⫽', u'\\star':u'⋆', u'\\steaming':u'☕',
|
||||||
u'\\subseteqq':u'⫅', u'\\subsetneqq':u'⫋', u'\\succ':u'≻',
|
u'\\subseteqq':u'⫅', u'\\subsetneqq':u'⫋', u'\\succ':u'≻',
|
||||||
u'\\succcurlyeq':u'≽', u'\\succeq':u'≽', u'\\succnsim':u'⋩',
|
u'\\succcurlyeq':u'≽', u'\\succeq':u'≽', u'\\succnsim':u'⋩',
|
||||||
u'\\succsim':u'≿', u'\\sun':u'☼', u'\\sup':u'sup', u'\\supseteqq':u'⫆',
|
u'\\succsim':u'≿', u'\\sun':u'☼', u'\\sup':u'sup', u'\\supseteqq':u'⫆',
|
||||||
u'\\supsetneqq':u'⫌', u'\\surd':u'√', u'\\swarrow':u'↙', u'\\tan':u'tan',
|
u'\\supsetneqq':u'⫌', u'\\surd':u'√', u'\\swarrow':u'↙',
|
||||||
|
u'\\swords':u'⚔', u'\\talloblong':u'⫾', u'\\tan':u'tan',
|
||||||
u'\\tanh':u'tanh', u'\\taurus':u'♉', u'\\textasciicircum':u'^',
|
u'\\tanh':u'tanh', u'\\taurus':u'♉', u'\\textasciicircum':u'^',
|
||||||
u'\\textasciitilde':u'~', u'\\textbackslash':u'\\',
|
u'\\textasciitilde':u'~', u'\\textbackslash':u'\\',
|
||||||
u'\\textcopyright':u'©\'', u'\\textdegree':u'°', u'\\textellipsis':u'…',
|
u'\\textcopyright':u'©\'', u'\\textdegree':u'°', u'\\textellipsis':u'…',
|
||||||
|
@ -520,20 +552,21 @@ class FormulaConfig(object):
|
||||||
u'\\textregistered':u'®', u'\\textrightarrow':u'→',
|
u'\\textregistered':u'®', u'\\textrightarrow':u'→',
|
||||||
u'\\textsection':u'§', u'\\texttrademark':u'™',
|
u'\\textsection':u'§', u'\\texttrademark':u'™',
|
||||||
u'\\texttwosuperior':u'²', u'\\textvisiblespace':u' ',
|
u'\\texttwosuperior':u'²', u'\\textvisiblespace':u' ',
|
||||||
u'\\therefore':u'∴', u'\\top':u'⊤', u'\\triangle':u'△',
|
u'\\therefore':u'∴', u'\\third':u'‴', u'\\top':u'⊤', u'\\triangle':u'△',
|
||||||
u'\\triangleleft':u'⊲', u'\\trianglelefteq':u'⊴', u'\\triangleq':u'≜',
|
u'\\triangleleft':u'⊲', u'\\trianglelefteq':u'⊴', u'\\triangleq':u'≜',
|
||||||
u'\\triangleright':u'▷', u'\\trianglerighteq':u'⊵',
|
u'\\triangleright':u'▷', u'\\trianglerighteq':u'⊵',
|
||||||
u'\\twoheadleftarrow':u'↞', u'\\twoheadrightarrow':u'↠',
|
u'\\twoheadleftarrow':u'↞', u'\\twoheadrightarrow':u'↠',
|
||||||
u'\\twonotes':u'♫', u'\\udot':u'⊍', u'\\unlhd':u'⊴', u'\\unrhd':u'⊵',
|
u'\\twonotes':u'♫', u'\\udot':u'⊍', u'\\ulcorner':u'⌜', u'\\unlhd':u'⊴',
|
||||||
u'\\unrhl':u'⊵', u'\\uparrow':u'↑', u'\\updownarrow':u'↕',
|
u'\\unrhd':u'⊵', u'\\unrhl':u'⊵', u'\\uparrow':u'↑',
|
||||||
u'\\upharpoonleft':u'↿', u'\\upharpoonright':u'↾', u'\\uplus':u'⊎',
|
u'\\updownarrow':u'↕', u'\\upharpoonleft':u'↿', u'\\upharpoonright':u'↾',
|
||||||
u'\\upuparrows':u'⇈', u'\\uranus':u'♅', u'\\vDash':u'⊨',
|
u'\\uplus':u'⊎', u'\\upuparrows':u'⇈', u'\\uranus':u'♅',
|
||||||
u'\\varclubsuit':u'♧', u'\\vardiamondsuit':u'♦', u'\\varheartsuit':u'♥',
|
u'\\urcorner':u'⌝', u'\\vDash':u'⊨', u'\\varclubsuit':u'♧',
|
||||||
u'\\varnothing':u'∅', u'\\varspadesuit':u'♤', u'\\vdash':u'⊢',
|
u'\\vardiamondsuit':u'♦', u'\\varheartsuit':u'♥', u'\\varnothing':u'∅',
|
||||||
u'\\vdots':u'⋮', u'\\vee':u'∨', u'\\vee)':u'∨', u'\\veebar':u'⊻',
|
u'\\varspadesuit':u'♤', u'\\vdash':u'⊢', u'\\vdots':u'⋮', u'\\vee':u'∨',
|
||||||
u'\\vert':u'∣', u'\\virgo':u'♍', u'\\wedge':u'∧', u'\\wedge)':u'∧',
|
u'\\vee)':u'∨', u'\\veebar':u'⊻', u'\\vert':u'∣', u'\\virgo':u'♍',
|
||||||
u'\\wp':u'℘', u'\\wr':u'≀', u'\\yen':u'¥', u'\\{':u'{', u'\\|':u'∥',
|
u'\\warning':u'⚠', u'\\wasylozenge':u'⌑', u'\\wedge':u'∧',
|
||||||
u'\\}':u'}',
|
u'\\wedge)':u'∧', u'\\wp':u'℘', u'\\wr':u'≀', u'\\yen':u'¥',
|
||||||
|
u'\\yinyang':u'☯', u'\\{':u'{', u'\\|':u'∥', u'\\}':u'}',
|
||||||
}
|
}
|
||||||
|
|
||||||
decoratedcommand = {
|
decoratedcommand = {
|
||||||
|
@ -580,7 +613,9 @@ class FormulaConfig(object):
|
||||||
}
|
}
|
||||||
|
|
||||||
hybridfunctions = {
|
hybridfunctions = {
|
||||||
|
u'\\addcontentsline':[u'{$p!}{$q!}{$r!}',u'f0{}',u'ignored',],
|
||||||
|
u'\\addtocontents':[u'{$p!}{$q!}',u'f0{}',u'ignored',],
|
||||||
|
u'\\backmatter':[u'',u'f0{}',u'ignored',],
|
||||||
u'\\binom':[u'{$1}{$2}',u'f2{(}f0{f1{$1}f1{$2}}f2{)}',u'span class="binom"',u'span class="binomstack"',u'span class="bigsymbol"',],
|
u'\\binom':[u'{$1}{$2}',u'f2{(}f0{f1{$1}f1{$2}}f2{)}',u'span class="binom"',u'span class="binomstack"',u'span class="bigsymbol"',],
|
||||||
u'\\boxed':[u'{$1}',u'f0{$1}',u'span class="boxed"',],
|
u'\\boxed':[u'{$1}',u'f0{$1}',u'span class="boxed"',],
|
||||||
u'\\cfrac':[u'[$p!]{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fullfraction"',u'span class="numerator align-$p"',u'span class="denominator"',u'span class="ignored"',],
|
u'\\cfrac':[u'[$p!]{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fullfraction"',u'span class="numerator align-$p"',u'span class="denominator"',u'span class="ignored"',],
|
||||||
|
@ -589,15 +624,21 @@ class FormulaConfig(object):
|
||||||
u'\\dbinom':[u'{$1}{$2}',u'(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}})',u'span class="binomial"',u'span class="binomrow"',u'span class="binomcell"',],
|
u'\\dbinom':[u'{$1}{$2}',u'(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}})',u'span class="binomial"',u'span class="binomrow"',u'span class="binomcell"',],
|
||||||
u'\\dfrac':[u'{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fullfraction"',u'span class="numerator"',u'span class="denominator"',u'span class="ignored"',],
|
u'\\dfrac':[u'{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fullfraction"',u'span class="numerator"',u'span class="denominator"',u'span class="ignored"',],
|
||||||
u'\\displaystyle':[u'{$1}',u'f0{$1}',u'span class="displaystyle"',],
|
u'\\displaystyle':[u'{$1}',u'f0{$1}',u'span class="displaystyle"',],
|
||||||
|
u'\\fancyfoot':[u'[$p!]{$q!}',u'f0{}',u'ignored',],
|
||||||
|
u'\\fancyhead':[u'[$p!]{$q!}',u'f0{}',u'ignored',],
|
||||||
u'\\fbox':[u'{$1}',u'f0{$1}',u'span class="fbox"',],
|
u'\\fbox':[u'{$1}',u'f0{$1}',u'span class="fbox"',],
|
||||||
u'\\fboxrule':[u'{$p!}',u'f0{}',u'ignored',],
|
u'\\fboxrule':[u'{$p!}',u'f0{}',u'ignored',],
|
||||||
u'\\fboxsep':[u'{$p!}',u'f0{}',u'ignored',],
|
u'\\fboxsep':[u'{$p!}',u'f0{}',u'ignored',],
|
||||||
u'\\fcolorbox':[u'{$p!}{$q!}{$1}',u'f0{$1}',u'span class="boxed" style="border-color: $p; background: $q;"',],
|
u'\\fcolorbox':[u'{$p!}{$q!}{$1}',u'f0{$1}',u'span class="boxed" style="border-color: $p; background: $q;"',],
|
||||||
u'\\frac':[u'{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fraction"',u'span class="numerator"',u'span class="denominator"',u'span class="ignored"',],
|
u'\\frac':[u'{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fraction"',u'span class="numerator"',u'span class="denominator"',u'span class="ignored"',],
|
||||||
u'\\framebox':[u'[$p!][$q!]{$1}',u'f0{$1}',u'span class="framebox align-$q" style="width: $p;"',],
|
u'\\framebox':[u'[$p!][$q!]{$1}',u'f0{$1}',u'span class="framebox align-$q" style="width: $p;"',],
|
||||||
|
u'\\frontmatter':[u'',u'f0{}',u'ignored',],
|
||||||
u'\\href':[u'[$o]{$u!}{$t!}',u'f0{$t}',u'a href="$u"',],
|
u'\\href':[u'[$o]{$u!}{$t!}',u'f0{$t}',u'a href="$u"',],
|
||||||
u'\\hspace':[u'{$p!}',u'f0{ }',u'span class="hspace" style="width: $p;"',],
|
u'\\hspace':[u'{$p!}',u'f0{ }',u'span class="hspace" style="width: $p;"',],
|
||||||
u'\\leftroot':[u'{$p!}',u'f0{ }',u'span class="leftroot" style="width: $p;px"',],
|
u'\\leftroot':[u'{$p!}',u'f0{ }',u'span class="leftroot" style="width: $p;px"',],
|
||||||
|
u'\\mainmatter':[u'',u'f0{}',u'ignored',],
|
||||||
|
u'\\markboth':[u'{$p!}{$q!}',u'f0{}',u'ignored',],
|
||||||
|
u'\\markright':[u'{$p!}',u'f0{}',u'ignored',],
|
||||||
u'\\nicefrac':[u'{$1}{$2}',u'f0{f1{$1}⁄f2{$2}}',u'span class="fraction"',u'sup class="numerator"',u'sub class="denominator"',u'span class="ignored"',],
|
u'\\nicefrac':[u'{$1}{$2}',u'f0{f1{$1}⁄f2{$2}}',u'span class="fraction"',u'sup class="numerator"',u'sub class="denominator"',u'span class="ignored"',],
|
||||||
u'\\parbox':[u'[$p!]{$w!}{$1}',u'f0{1}',u'div class="Boxed" style="width: $w;"',],
|
u'\\parbox':[u'[$p!]{$w!}{$1}',u'f0{1}',u'div class="Boxed" style="width: $w;"',],
|
||||||
u'\\raisebox':[u'{$p!}{$1}',u'f0{$1.font}',u'span class="raisebox" style="vertical-align: $p;"',],
|
u'\\raisebox':[u'{$p!}{$1}',u'f0{$1.font}',u'span class="raisebox" style="vertical-align: $p;"',],
|
||||||
|
@ -610,6 +651,7 @@ class FormulaConfig(object):
|
||||||
u'\\tbinom':[u'{$1}{$2}',u'(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}})',u'span class="binomial"',u'span class="binomrow"',u'span class="binomcell"',],
|
u'\\tbinom':[u'{$1}{$2}',u'(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}})',u'span class="binomial"',u'span class="binomrow"',u'span class="binomcell"',],
|
||||||
u'\\textcolor':[u'{$p!}{$1}',u'f0{$1}',u'span style="color: $p;"',],
|
u'\\textcolor':[u'{$p!}{$1}',u'f0{$1}',u'span style="color: $p;"',],
|
||||||
u'\\textstyle':[u'{$1}',u'f0{$1}',u'span class="textstyle"',],
|
u'\\textstyle':[u'{$1}',u'f0{$1}',u'span class="textstyle"',],
|
||||||
|
u'\\thispagestyle':[u'{$p!}',u'f0{}',u'ignored',],
|
||||||
u'\\unit':[u'[$0]{$1}',u'$0f0{$1.font}',u'span class="unit"',],
|
u'\\unit':[u'[$0]{$1}',u'$0f0{$1.font}',u'span class="unit"',],
|
||||||
u'\\unitfrac':[u'[$0]{$1}{$2}',u'$0f0{f1{$1.font}⁄f2{$2.font}}',u'span class="fraction"',u'sup class="unit"',u'sub class="unit"',],
|
u'\\unitfrac':[u'[$0]{$1}{$2}',u'$0f0{f1{$1.font}⁄f2{$2.font}}',u'span class="fraction"',u'sup class="unit"',u'sub class="unit"',],
|
||||||
u'\\uproot':[u'{$p!}',u'f0{ }',u'span class="uproot" style="width: $p;px"',],
|
u'\\uproot':[u'{$p!}',u'f0{ }',u'span class="uproot" style="width: $p;px"',],
|
||||||
|
@ -627,24 +669,24 @@ class FormulaConfig(object):
|
||||||
}
|
}
|
||||||
|
|
||||||
limitcommands = {
|
limitcommands = {
|
||||||
u'\\int':u'∫', u'\\intop':u'∫', u'\\lim':u'lim', u'\\prod':u'∏',
|
u'\\biginterleave':u'⫼', u'\\bigsqcap':u'⨅', u'\\fint':u'⨏',
|
||||||
u'\\smallint':u'∫', u'\\sum':u'∑',
|
u'\\iiiint':u'⨌', u'\\int':u'∫', u'\\intop':u'∫', u'\\lim':u'lim',
|
||||||
|
u'\\prod':u'∏', u'\\smallint':u'∫', u'\\sqint':u'⨖', u'\\sum':u'∑',
|
||||||
|
u'\\varointclockwise':u'∲', u'\\varprod':u'⨉', u'\\zcmp':u'⨟',
|
||||||
|
u'\\zhide':u'⧹', u'\\zpipe':u'⨠', u'\\zproject':u'⨡',
|
||||||
}
|
}
|
||||||
# TODO: setting for simple enlarged vs. piecewise symbols
|
|
||||||
for key in (u'\\int', u'\\intop', u'\\prod', u'\\sum'):
|
|
||||||
limitcommands[key] = '<span class="symbol">%s</span>' % limitcommands[key]
|
|
||||||
|
|
||||||
misccommands = {
|
misccommands = {
|
||||||
u'\\limits':u'LimitPreviousCommand', u'\\newcommand':u'MacroDefinition',
|
u'\\limits':u'LimitPreviousCommand', u'\\newcommand':u'MacroDefinition',
|
||||||
u'\\renewcommand':u'MacroDefinition',
|
u'\\renewcommand':u'MacroDefinition',
|
||||||
u'\\setcounter':u'SetCounterFunction', u'\\tag':u'FormulaTag',
|
u'\\setcounter':u'SetCounterFunction', u'\\tag':u'FormulaTag',
|
||||||
u'\\tag*':u'FormulaTag',
|
u'\\tag*':u'FormulaTag', u'\\today':u'TodayCommand',
|
||||||
}
|
}
|
||||||
|
|
||||||
modified = {
|
modified = {
|
||||||
u'\n':u'', u' ':u'', u'$':u'', u'&':u' ', u'\'':u'’', u'+':u' + ',
|
u'\n':u'', u' ':u'', u'$':u'', u'&':u' ', u'\'':u'’', u'+':u' + ',
|
||||||
u',':u', ', u'-':u' − ', u'/':u' ⁄ ', u'<':u' < ', u'=':u' = ',
|
u',':u', ', u'-':u' − ', u'/':u' ⁄ ', u':':u' : ', u'<':u' < ',
|
||||||
u'>':u' > ', u'@':u'', u'~':u'',
|
u'=':u' = ', u'>':u' > ', u'@':u'', u'~':u'',
|
||||||
}
|
}
|
||||||
|
|
||||||
onefunctions = {
|
onefunctions = {
|
||||||
|
@ -664,13 +706,58 @@ class FormulaConfig(object):
|
||||||
}
|
}
|
||||||
|
|
||||||
spacedcommands = {
|
spacedcommands = {
|
||||||
u'\\Leftrightarrow':u'⇔', u'\\Rightarrow':u'⇒', u'\\approx':u'≈',
|
u'\\Bot':u'⫫', u'\\Doteq':u'≑', u'\\DownArrowBar':u'⤓',
|
||||||
u'\\dashrightarrow':u'⇢', u'\\equiv':u'≡', u'\\ge':u'≥', u'\\geq':u'≥',
|
u'\\DownLeftTeeVector':u'⥞', u'\\DownLeftVectorBar':u'⥖',
|
||||||
|
u'\\DownRightTeeVector':u'⥟', u'\\DownRightVectorBar':u'⥗',
|
||||||
|
u'\\Equal':u'⩵', u'\\LeftArrowBar':u'⇤', u'\\LeftDownTeeVector':u'⥡',
|
||||||
|
u'\\LeftDownVectorBar':u'⥙', u'\\LeftTeeVector':u'⥚',
|
||||||
|
u'\\LeftTriangleBar':u'⧏', u'\\LeftUpTeeVector':u'⥠',
|
||||||
|
u'\\LeftUpVectorBar':u'⥘', u'\\LeftVectorBar':u'⥒',
|
||||||
|
u'\\Leftrightarrow':u'⇔', u'\\Longmapsfrom':u'⟽', u'\\Longmapsto':u'⟾',
|
||||||
|
u'\\MapsDown':u'↧', u'\\MapsUp':u'↥', u'\\Nearrow':u'⇗',
|
||||||
|
u'\\NestedGreaterGreater':u'⪢', u'\\NestedLessLess':u'⪡',
|
||||||
|
u'\\NotGreaterLess':u'≹', u'\\NotGreaterTilde':u'≵',
|
||||||
|
u'\\NotLessTilde':u'≴', u'\\Nwarrow':u'⇖', u'\\Proportion':u'∷',
|
||||||
|
u'\\RightArrowBar':u'⇥', u'\\RightDownTeeVector':u'⥝',
|
||||||
|
u'\\RightDownVectorBar':u'⥕', u'\\RightTeeVector':u'⥛',
|
||||||
|
u'\\RightTriangleBar':u'⧐', u'\\RightUpTeeVector':u'⥜',
|
||||||
|
u'\\RightUpVectorBar':u'⥔', u'\\RightVectorBar':u'⥓',
|
||||||
|
u'\\Rightarrow':u'⇒', u'\\Same':u'⩶', u'\\Searrow':u'⇘',
|
||||||
|
u'\\Swarrow':u'⇙', u'\\Top':u'⫪', u'\\UpArrowBar':u'⤒', u'\\VDash':u'⊫',
|
||||||
|
u'\\approx':u'≈', u'\\approxeq':u'≊', u'\\backsim':u'∽', u'\\barin':u'⋶',
|
||||||
|
u'\\barleftharpoon':u'⥫', u'\\barrightharpoon':u'⥭', u'\\bij':u'⤖',
|
||||||
|
u'\\coloneq':u'≔', u'\\corresponds':u'≙', u'\\curlyeqprec':u'⋞',
|
||||||
|
u'\\curlyeqsucc':u'⋟', u'\\dashrightarrow':u'⇢', u'\\dlsh':u'↲',
|
||||||
|
u'\\downdownharpoons':u'⥥', u'\\downuparrows':u'⇵',
|
||||||
|
u'\\downupharpoons':u'⥯', u'\\drsh':u'↳', u'\\eqslantgtr':u'⪖',
|
||||||
|
u'\\eqslantless':u'⪕', u'\\equiv':u'≡', u'\\ffun':u'⇻', u'\\finj':u'⤕',
|
||||||
|
u'\\ge':u'≥', u'\\geq':u'≥', u'\\ggcurly':u'⪼', u'\\gnapprox':u'⪊',
|
||||||
|
u'\\gneq':u'⪈', u'\\gtrapprox':u'⪆', u'\\hash':u'⋕', u'\\iddots':u'⋰',
|
||||||
u'\\implies':u' ⇒ ', u'\\in':u'∈', u'\\le':u'≤', u'\\leftarrow':u'←',
|
u'\\implies':u' ⇒ ', u'\\in':u'∈', u'\\le':u'≤', u'\\leftarrow':u'←',
|
||||||
u'\\leq':u'≤', u'\\ne':u'≠', u'\\neq':u'≠', u'\\not\\in':u'∉',
|
u'\\leftarrowtriangle':u'⇽', u'\\leftbarharpoon':u'⥪',
|
||||||
u'\\propto':u'∝', u'\\rightarrow':u'→', u'\\rightsquigarrow':u'⇝',
|
u'\\leftrightarrowtriangle':u'⇿', u'\\leftrightharpoon':u'⥊',
|
||||||
u'\\sim':u'~', u'\\subset':u'⊂', u'\\subseteq':u'⊆', u'\\supset':u'⊃',
|
u'\\leftrightharpoondown':u'⥐', u'\\leftrightharpoonup':u'⥎',
|
||||||
u'\\supseteq':u'⊇', u'\\times':u'×', u'\\to':u'→',
|
u'\\leftrightsquigarrow':u'↭', u'\\leftslice':u'⪦',
|
||||||
|
u'\\leftsquigarrow':u'⇜', u'\\leftupdownharpoon':u'⥑', u'\\leq':u'≤',
|
||||||
|
u'\\lessapprox':u'⪅', u'\\llcurly':u'⪻', u'\\lnapprox':u'⪉',
|
||||||
|
u'\\lneq':u'⪇', u'\\longmapsfrom':u'⟻', u'\\multimapboth':u'⧟',
|
||||||
|
u'\\multimapdotbothA':u'⊶', u'\\multimapdotbothB':u'⊷',
|
||||||
|
u'\\multimapinv':u'⟜', u'\\nVdash':u'⊮', u'\\ne':u'≠', u'\\neq':u'≠',
|
||||||
|
u'\\ngeq':u'≱', u'\\nleq':u'≰', u'\\nni':u'∌', u'\\not\\in':u'∉',
|
||||||
|
u'\\notasymp':u'≭', u'\\npreceq':u'⋠', u'\\nsqsubseteq':u'⋢',
|
||||||
|
u'\\nsqsupseteq':u'⋣', u'\\nsubset':u'⊄', u'\\nsucceq':u'⋡',
|
||||||
|
u'\\pfun':u'⇸', u'\\pinj':u'⤔', u'\\precapprox':u'⪷', u'\\preceqq':u'⪳',
|
||||||
|
u'\\precnapprox':u'⪹', u'\\precnsim':u'⋨', u'\\propto':u'∝',
|
||||||
|
u'\\psur':u'⤀', u'\\rightarrow':u'→', u'\\rightarrowtriangle':u'⇾',
|
||||||
|
u'\\rightbarharpoon':u'⥬', u'\\rightleftharpoon':u'⥋',
|
||||||
|
u'\\rightslice':u'⪧', u'\\rightsquigarrow':u'⇝',
|
||||||
|
u'\\rightupdownharpoon':u'⥏', u'\\sim':u'~', u'\\strictfi':u'⥼',
|
||||||
|
u'\\strictif':u'⥽', u'\\subset':u'⊂', u'\\subseteq':u'⊆',
|
||||||
|
u'\\subsetneq':u'⊊', u'\\succapprox':u'⪸', u'\\succeqq':u'⪴',
|
||||||
|
u'\\succnapprox':u'⪺', u'\\supset':u'⊃', u'\\supseteq':u'⊇',
|
||||||
|
u'\\supsetneq':u'⊋', u'\\times':u'×', u'\\to':u'→',
|
||||||
|
u'\\updownarrows':u'⇅', u'\\updownharpoons':u'⥮', u'\\upupharpoons':u'⥣',
|
||||||
|
u'\\vartriangleleft':u'⊲', u'\\vartriangleright':u'⊳',
|
||||||
}
|
}
|
||||||
|
|
||||||
starts = {
|
starts = {
|
||||||
|
@ -695,7 +782,7 @@ class FormulaConfig(object):
|
||||||
|
|
||||||
unmodified = {
|
unmodified = {
|
||||||
|
|
||||||
u'characters':[u'.',u'*',u'€',u'(',u')',u'[',u']',u':',u'·',u'!',u';',u'|',u'§',u'"',],
|
u'characters':[u'.',u'*',u'€',u'(',u')',u'[',u']',u'·',u'!',u';',u'|',u'§',u'"',],
|
||||||
}
|
}
|
||||||
|
|
||||||
urls = {
|
urls = {
|
||||||
|
@ -706,7 +793,7 @@ class GeneralConfig(object):
|
||||||
"Configuration class from elyxer.config file"
|
"Configuration class from elyxer.config file"
|
||||||
|
|
||||||
version = {
|
version = {
|
||||||
u'date':u'2011-06-27', u'lyxformat':u'413', u'number':u'1.2.3',
|
u'date':u'2015-02-26', u'lyxformat':u'413', u'number':u'1.2.5',
|
||||||
}
|
}
|
||||||
|
|
||||||
class HeaderConfig(object):
|
class HeaderConfig(object):
|
||||||
|
@ -735,6 +822,7 @@ class ImageConfig(object):
|
||||||
|
|
||||||
u'imagemagick':u'convert[ -density $scale][ -define $format:use-cropbox=true] "$input" "$output"',
|
u'imagemagick':u'convert[ -density $scale][ -define $format:use-cropbox=true] "$input" "$output"',
|
||||||
u'inkscape':u'inkscape "$input" --export-png="$output"',
|
u'inkscape':u'inkscape "$input" --export-png="$output"',
|
||||||
|
u'lyx':u'lyx -C "$input" "$output"',
|
||||||
}
|
}
|
||||||
|
|
||||||
cropboxformats = {
|
cropboxformats = {
|
||||||
|
@ -860,6 +948,10 @@ class TagConfig(object):
|
||||||
u'Comment':u'', u'Greyedout':u'span class="greyedout"', u'Note':u'',
|
u'Comment':u'', u'Greyedout':u'span class="greyedout"', u'Note':u'',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
script = {
|
||||||
|
u'subscript':u'sub', u'superscript':u'sup',
|
||||||
|
}
|
||||||
|
|
||||||
shaped = {
|
shaped = {
|
||||||
u'italic':u'i', u'slanted':u'i', u'smallcaps':u'span class="versalitas"',
|
u'italic':u'i', u'slanted':u'i', u'smallcaps':u'span class="versalitas"',
|
||||||
}
|
}
|
||||||
|
@ -889,7 +981,8 @@ class TranslationConfig(object):
|
||||||
|
|
||||||
languages = {
|
languages = {
|
||||||
u'american':u'en', u'british':u'en', u'deutsch':u'de', u'dutch':u'nl',
|
u'american':u'en', u'british':u'en', u'deutsch':u'de', u'dutch':u'nl',
|
||||||
u'english':u'en', u'french':u'fr', u'ngerman':u'de', u'spanish':u'es',
|
u'english':u'en', u'french':u'fr', u'ngerman':u'de', u'russian':u'ru',
|
||||||
|
u'spanish':u'es',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -936,7 +1029,7 @@ class CommandLineParser(object):
|
||||||
initial = args[0]
|
initial = args[0]
|
||||||
del args[0]
|
del args[0]
|
||||||
return key, self.readquoted(args, initial)
|
return key, self.readquoted(args, initial)
|
||||||
value = args[0]
|
value = args[0].decode('utf-8')
|
||||||
del args[0]
|
del args[0]
|
||||||
if isinstance(current, list):
|
if isinstance(current, list):
|
||||||
current.append(value)
|
current.append(value)
|
||||||
|
@ -945,8 +1038,10 @@ class CommandLineParser(object):
|
||||||
|
|
||||||
def readquoted(self, args, initial):
|
def readquoted(self, args, initial):
|
||||||
"Read a value between quotes"
|
"Read a value between quotes"
|
||||||
|
Trace.error('Oops')
|
||||||
value = initial[1:]
|
value = initial[1:]
|
||||||
while len(args) > 0 and not args[0].endswith('"') and not args[0].startswith('--'):
|
while len(args) > 0 and not args[0].endswith('"') and not args[0].startswith('--'):
|
||||||
|
Trace.error('Appending ' + args[0])
|
||||||
value += ' ' + args[0]
|
value += ' ' + args[0]
|
||||||
del args[0]
|
del args[0]
|
||||||
if len(args) == 0 or args[0].startswith('--'):
|
if len(args) == 0 or args[0].startswith('--'):
|
||||||
|
@ -983,6 +1078,7 @@ class Options(object):
|
||||||
unicode = False
|
unicode = False
|
||||||
iso885915 = False
|
iso885915 = False
|
||||||
css = []
|
css = []
|
||||||
|
favicon = ''
|
||||||
title = None
|
title = None
|
||||||
directory = None
|
directory = None
|
||||||
destdirectory = None
|
destdirectory = None
|
||||||
|
@ -1062,6 +1158,8 @@ class Options(object):
|
||||||
Options.copyimages = True
|
Options.copyimages = True
|
||||||
if Options.css == []:
|
if Options.css == []:
|
||||||
Options.css = ['http://elyxer.nongnu.org/lyx.css']
|
Options.css = ['http://elyxer.nongnu.org/lyx.css']
|
||||||
|
if Options.favicon == '':
|
||||||
|
pass # no default favicon
|
||||||
if Options.html:
|
if Options.html:
|
||||||
Options.simplemath = True
|
Options.simplemath = True
|
||||||
if Options.toc and not Options.tocfor:
|
if Options.toc and not Options.tocfor:
|
||||||
|
@ -1069,6 +1167,8 @@ class Options(object):
|
||||||
Options.tocfor = Options.toctarget
|
Options.tocfor = Options.toctarget
|
||||||
if Options.nocopy:
|
if Options.nocopy:
|
||||||
Trace.error('Option --nocopy is deprecated; it is no longer needed')
|
Trace.error('Option --nocopy is deprecated; it is no longer needed')
|
||||||
|
if Options.jsmath:
|
||||||
|
Trace.error('Option --jsmath is deprecated; use --mathjax instead')
|
||||||
# set in Trace if necessary
|
# set in Trace if necessary
|
||||||
for param in dir(Trace):
|
for param in dir(Trace):
|
||||||
if param.endswith('mode'):
|
if param.endswith('mode'):
|
||||||
|
@ -1088,6 +1188,7 @@ class Options(object):
|
||||||
return
|
return
|
||||||
Options.marginfoot = False
|
Options.marginfoot = False
|
||||||
Options.letterfoot = False
|
Options.letterfoot = False
|
||||||
|
Options.hoverfoot = False
|
||||||
options = Options.footnotes.split(',')
|
options = Options.footnotes.split(',')
|
||||||
for option in options:
|
for option in options:
|
||||||
footoption = option + 'foot'
|
footoption = option + 'foot'
|
||||||
|
@ -1113,7 +1214,8 @@ class Options(object):
|
||||||
Trace.error(' Options for HTML output:')
|
Trace.error(' Options for HTML output:')
|
||||||
Trace.error(' --title "title": set the generated page title')
|
Trace.error(' --title "title": set the generated page title')
|
||||||
Trace.error(' --css "file.css": use a custom CSS file')
|
Trace.error(' --css "file.css": use a custom CSS file')
|
||||||
Trace.error(' --embedcss "file.css": embed styles from elyxer.a CSS file into the output')
|
Trace.error(' --embedcss "file.css": embed styles from a CSS file into the output')
|
||||||
|
Trace.error(' --favicon "icon.ico": insert the specified favicon in the header.')
|
||||||
Trace.error(' --html: output HTML 4.0 instead of the default XHTML')
|
Trace.error(' --html: output HTML 4.0 instead of the default XHTML')
|
||||||
Trace.error(' --unicode: full Unicode output')
|
Trace.error(' --unicode: full Unicode output')
|
||||||
Trace.error(' --iso885915: output a document with ISO-8859-15 encoding')
|
Trace.error(' --iso885915: output a document with ISO-8859-15 encoding')
|
||||||
|
@ -1143,8 +1245,8 @@ class Options(object):
|
||||||
Trace.error(' --notoclabels: omit the part labels in the TOC, such as Chapter')
|
Trace.error(' --notoclabels: omit the part labels in the TOC, such as Chapter')
|
||||||
Trace.error(' --lowmem: do the conversion on the fly (conserve memory)')
|
Trace.error(' --lowmem: do the conversion on the fly (conserve memory)')
|
||||||
Trace.error(' --raw: generate HTML without header or footer.')
|
Trace.error(' --raw: generate HTML without header or footer.')
|
||||||
Trace.error(' --jsmath "URL": use jsMath from elyxer.the given URL to display equations')
|
Trace.error(' --mathjax remote: use MathJax remotely to display equations')
|
||||||
Trace.error(' --mathjax "URL": use MathJax from elyxer.the given URL to display equations')
|
Trace.error(' --mathjax "URL": use MathJax from the given URL to display equations')
|
||||||
Trace.error(' --googlecharts: use Google Charts to generate formula images')
|
Trace.error(' --googlecharts: use Google Charts to generate formula images')
|
||||||
Trace.error(' --template "file": use a template, put everything in <!--$content-->')
|
Trace.error(' --template "file": use a template, put everything in <!--$content-->')
|
||||||
Trace.error(' --copyright: add a copyright notice at the bottom')
|
Trace.error(' --copyright: add a copyright notice at the bottom')
|
||||||
|
@ -1152,6 +1254,7 @@ class Options(object):
|
||||||
Trace.error(' --toc: (deprecated) create a table of contents')
|
Trace.error(' --toc: (deprecated) create a table of contents')
|
||||||
Trace.error(' --toctarget "page": (deprecated) generate a TOC for the given page')
|
Trace.error(' --toctarget "page": (deprecated) generate a TOC for the given page')
|
||||||
Trace.error(' --nocopy: (deprecated) maintained for backwards compatibility')
|
Trace.error(' --nocopy: (deprecated) maintained for backwards compatibility')
|
||||||
|
Trace.error(' --jsmath "URL": use jsMath from the given URL to display equations')
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
def showversion(self):
|
def showversion(self):
|
||||||
|
@ -3536,11 +3639,17 @@ class BarredText(TaggedText):
|
||||||
return
|
return
|
||||||
self.output.tag = TagConfig.barred[self.type]
|
self.output.tag = TagConfig.barred[self.type]
|
||||||
|
|
||||||
class LangLine(BlackBox):
|
class LangLine(TaggedText):
|
||||||
"A line with language information"
|
"A line with language information"
|
||||||
|
|
||||||
def process(self):
|
def process(self):
|
||||||
self.lang = self.header[1]
|
"Only generate a span with lang info when the language is recognized."
|
||||||
|
lang = self.header[1]
|
||||||
|
if not lang in TranslationConfig.languages:
|
||||||
|
self.output = ContentsOutput()
|
||||||
|
return
|
||||||
|
isolang = TranslationConfig.languages[lang]
|
||||||
|
self.output = TaggedOutput().settag('span lang="' + isolang + '"', False)
|
||||||
|
|
||||||
class InsetLength(BlackBox):
|
class InsetLength(BlackBox):
|
||||||
"A length measure inside an inset."
|
"A length measure inside an inset."
|
||||||
|
@ -3908,8 +4017,7 @@ class Reference(Link):
|
||||||
self.replace('@', partkey and partkey.number)
|
self.replace('@', partkey and partkey.number)
|
||||||
self.replace(u'¶', partkey and partkey.tocentry)
|
self.replace(u'¶', partkey and partkey.tocentry)
|
||||||
if not '$' in self.formatted or not partkey or not partkey.titlecontents:
|
if not '$' in self.formatted or not partkey or not partkey.titlecontents:
|
||||||
if '$' in self.formatted:
|
# there is a $ left, but it should go away on preprocessing
|
||||||
Trace.error('No title in ' + unicode(partkey))
|
|
||||||
self.contents = [Constant(self.formatted)]
|
self.contents = [Constant(self.formatted)]
|
||||||
return
|
return
|
||||||
pieces = self.formatted.split('$')
|
pieces = self.formatted.split('$')
|
||||||
|
@ -3993,7 +4101,7 @@ class FormulaCommand(FormulaBit):
|
||||||
|
|
||||||
def emptycommand(self, pos):
|
def emptycommand(self, pos):
|
||||||
"""Check for an empty command: look for command disguised as ending.
|
"""Check for an empty command: look for command disguised as ending.
|
||||||
Special case against '{ \{ \} }' situation."""
|
Special case against '{ \\{ \\} }' situation."""
|
||||||
command = ''
|
command = ''
|
||||||
if not pos.isout():
|
if not pos.isout():
|
||||||
ending = pos.nextending()
|
ending = pos.nextending()
|
||||||
|
@ -4452,7 +4560,7 @@ class EquationEnvironment(MultiRowFormula):
|
||||||
self.parserows(pos)
|
self.parserows(pos)
|
||||||
|
|
||||||
class BeginCommand(CommandBit):
|
class BeginCommand(CommandBit):
|
||||||
"A \\begin{}...\end command and what it entails (array, cases, aligned)"
|
"A \\begin{}...\\end command and what it entails (array, cases, aligned)"
|
||||||
|
|
||||||
commandmap = {FormulaConfig.array['begin']:''}
|
commandmap = {FormulaConfig.array['begin']:''}
|
||||||
|
|
||||||
|
@ -4481,6 +4589,8 @@ class BeginCommand(CommandBit):
|
||||||
FormulaCommand.types += [BeginCommand]
|
FormulaCommand.types += [BeginCommand]
|
||||||
|
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
class CombiningFunction(OneParamFunction):
|
class CombiningFunction(OneParamFunction):
|
||||||
|
|
||||||
|
@ -4697,6 +4807,16 @@ class BracketProcessor(MathsProcessor):
|
||||||
command.output = ContentsOutput()
|
command.output = ContentsOutput()
|
||||||
command.contents = bracket.getcontents()
|
command.contents = bracket.getcontents()
|
||||||
|
|
||||||
|
class TodayCommand(EmptyCommand):
|
||||||
|
"Shows today's date."
|
||||||
|
|
||||||
|
commandmap = None
|
||||||
|
|
||||||
|
def parsebit(self, pos):
|
||||||
|
"Parse a command without parameters"
|
||||||
|
self.output = FixedOutput()
|
||||||
|
self.html = [datetime.date.today().strftime('%b %d, %Y')]
|
||||||
|
|
||||||
|
|
||||||
FormulaCommand.types += [
|
FormulaCommand.types += [
|
||||||
DecoratingFunction, CombiningFunction, LimitCommand, BracketCommand,
|
DecoratingFunction, CombiningFunction, LimitCommand, BracketCommand,
|
||||||
|
|
147
Libs/docutils/utils/math/tex2mathml_extern.py
Normal file
147
Libs/docutils/utils/math/tex2mathml_extern.py
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# :Id: $Id: tex2mathml_extern.py 7861 2015-04-10 23:48:51Z milde $
|
||||||
|
# :Copyright: © 2015 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
|
||||||
|
|
||||||
|
# Wrappers for TeX->MathML conversion by external tools
|
||||||
|
# =====================================================
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
document_template = r"""\documentclass{article}
|
||||||
|
\usepackage{amsmath}
|
||||||
|
\begin{document}
|
||||||
|
%s
|
||||||
|
\end{document}
|
||||||
|
"""
|
||||||
|
|
||||||
|
def latexml(math_code, reporter=None):
|
||||||
|
"""Convert LaTeX math code to MathML with LaTeXML_
|
||||||
|
|
||||||
|
.. _LaTeXML: http://dlmf.nist.gov/LaTeXML/
|
||||||
|
"""
|
||||||
|
p = subprocess.Popen(['latexml',
|
||||||
|
'-', # read from stdin
|
||||||
|
# '--preload=amsmath',
|
||||||
|
'--inputencoding=utf8',
|
||||||
|
],
|
||||||
|
stdin=subprocess.PIPE,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
close_fds=True)
|
||||||
|
p.stdin.write((document_template % math_code).encode('utf8'))
|
||||||
|
p.stdin.close()
|
||||||
|
latexml_code = p.stdout.read()
|
||||||
|
latexml_err = p.stderr.read().decode('utf8')
|
||||||
|
if reporter and latexml_err.find('Error') >= 0 or not latexml_code:
|
||||||
|
reporter.error(latexml_err)
|
||||||
|
|
||||||
|
post_p = subprocess.Popen(['latexmlpost',
|
||||||
|
'-',
|
||||||
|
'--nonumbersections',
|
||||||
|
'--format=xhtml',
|
||||||
|
# '--linelength=78', # experimental
|
||||||
|
'--'
|
||||||
|
],
|
||||||
|
stdin=subprocess.PIPE,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
close_fds=True)
|
||||||
|
post_p.stdin.write(latexml_code)
|
||||||
|
post_p.stdin.close()
|
||||||
|
result = post_p.stdout.read().decode('utf8')
|
||||||
|
post_p_err = post_p.stderr.read().decode('utf8')
|
||||||
|
if reporter and post_p_err.find('Error') >= 0 or not result:
|
||||||
|
reporter.error(post_p_err)
|
||||||
|
|
||||||
|
# extract MathML code:
|
||||||
|
start,end = result.find('<math'), result.find('</math>')+7
|
||||||
|
result = result[start:end]
|
||||||
|
if 'class="ltx_ERROR' in result:
|
||||||
|
raise SyntaxError(result)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def ttm(math_code, reporter=None):
|
||||||
|
"""Convert LaTeX math code to MathML with TtM_
|
||||||
|
|
||||||
|
.. _TtM: http://hutchinson.belmont.ma.us/tth/mml/
|
||||||
|
"""
|
||||||
|
p = subprocess.Popen(['ttm',
|
||||||
|
# '-i', # italic font for equations. Default roman.
|
||||||
|
'-u', # unicode character encoding. (Default iso-8859-1).
|
||||||
|
'-r', # output raw MathML (no preamble or postlude)
|
||||||
|
],
|
||||||
|
stdin=subprocess.PIPE,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
close_fds=True)
|
||||||
|
p.stdin.write((document_template % math_code).encode('utf8'))
|
||||||
|
p.stdin.close()
|
||||||
|
result = p.stdout.read()
|
||||||
|
err = p.stderr.read().decode('utf8')
|
||||||
|
if err.find('**** Unknown') >= 0:
|
||||||
|
msg = '\n'.join([line for line in err.splitlines()
|
||||||
|
if line.startswith('****')])
|
||||||
|
raise SyntaxError('\nMessage from external converter TtM:\n'+ msg)
|
||||||
|
if reporter and err.find('**** Error') >= 0 or not result:
|
||||||
|
reporter.error(err)
|
||||||
|
start,end = result.find('<math'), result.find('</math>')+7
|
||||||
|
result = result[start:end]
|
||||||
|
return result
|
||||||
|
|
||||||
|
def blahtexml(math_code, inline=True, reporter=None):
|
||||||
|
"""Convert LaTeX math code to MathML with blahtexml_
|
||||||
|
|
||||||
|
.. _blahtexml: http://gva.noekeon.org/blahtexml/
|
||||||
|
"""
|
||||||
|
options = ['--mathml',
|
||||||
|
'--indented',
|
||||||
|
'--spacing', 'moderate',
|
||||||
|
'--mathml-encoding', 'raw',
|
||||||
|
'--other-encoding', 'raw',
|
||||||
|
'--doctype-xhtml+mathml',
|
||||||
|
'--annotate-TeX',
|
||||||
|
]
|
||||||
|
if inline:
|
||||||
|
mathmode_arg = ''
|
||||||
|
else:
|
||||||
|
mathmode_arg = 'mode="display"'
|
||||||
|
options.append('--displaymath')
|
||||||
|
|
||||||
|
p = subprocess.Popen(['blahtexml']+options,
|
||||||
|
stdin=subprocess.PIPE,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
close_fds=True)
|
||||||
|
p.stdin.write(math_code.encode('utf8'))
|
||||||
|
p.stdin.close()
|
||||||
|
result = p.stdout.read().decode('utf8')
|
||||||
|
err = p.stderr.read().decode('utf8')
|
||||||
|
|
||||||
|
print err
|
||||||
|
if result.find('<error>') >= 0:
|
||||||
|
raise SyntaxError('\nMessage from external converter blahtexml:\n'
|
||||||
|
+result[result.find('<message>')+9:result.find('</message>')])
|
||||||
|
if reporter and (err.find('**** Error') >= 0 or not result):
|
||||||
|
reporter.error(err)
|
||||||
|
start,end = result.find('<markup>')+9, result.find('</markup>')
|
||||||
|
result = ('<math xmlns="http://www.w3.org/1998/Math/MathML"%s>\n'
|
||||||
|
'%s</math>\n') % (mathmode_arg, result[start:end])
|
||||||
|
return result
|
||||||
|
|
||||||
|
# self-test
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
example = ur'\frac{\partial \sin^2(\alpha)}{\partial \vec r} \varpi \, \text{Grüße}'
|
||||||
|
# print latexml(example).encode('utf8')
|
||||||
|
# print ttm(example)#.encode('utf8')
|
||||||
|
print blahtexml(example).encode('utf8')
|
|
@ -1,6 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# :Copyright: © 2011 Günter Milde.
|
# :Id: $Id: punctuation_chars.py 8016 2017-01-17 15:06:17Z milde $
|
||||||
|
# :Copyright: © 2011, 2017 Günter Milde.
|
||||||
# :License: Released under the terms of the `2-Clause BSD license`_, in short:
|
# :License: Released under the terms of the `2-Clause BSD license`_, in short:
|
||||||
#
|
#
|
||||||
# Copying and distribution of this file, with or without modification,
|
# Copying and distribution of this file, with or without modification,
|
||||||
|
@ -9,29 +10,38 @@
|
||||||
# This file is offered as-is, without any warranty.
|
# This file is offered as-is, without any warranty.
|
||||||
#
|
#
|
||||||
# .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause
|
# .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause
|
||||||
|
#
|
||||||
# :Id: $Id: punctuation_chars.py 7668 2013-06-04 12:46:30Z milde $
|
# This file is generated by
|
||||||
|
# ``docutils/tools/dev/generate_punctuation_chars.py``.
|
||||||
|
# ::
|
||||||
|
|
||||||
import sys, re
|
import sys, re
|
||||||
import unicodedata
|
import unicodedata
|
||||||
|
|
||||||
# punctuation characters around inline markup
|
"""Docutils character category patterns.
|
||||||
# ===========================================
|
|
||||||
#
|
|
||||||
# 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
|
Patterns for the implementation of the `inline markup recognition rules`_
|
||||||
# --------------------------------------------
|
in the reStructuredText parser `docutils.parsers.rst.states.py` based
|
||||||
#
|
on Unicode character categories.
|
||||||
# The sample strings are generated by punctuation_samples() and put here
|
The patterns are used inside ``[ ]`` in regular expressions.
|
||||||
# literal to avoid the time-consuming generation with every Docutils run.
|
|
||||||
# As the samples are used inside ``[ ]`` in regular expressions, hyphen and
|
Rule (5) requires determination of matching open/close pairs. However, the
|
||||||
# square brackets are escaped. ::
|
pairing of open/close quotes is ambiguous due to different typographic
|
||||||
|
conventions in different languages. The ``quote_pairs`` function tests
|
||||||
|
whether two characters form an open/close pair.
|
||||||
|
|
||||||
|
The patterns are generated by
|
||||||
|
``docutils/tools/dev/generate_punctuation_chars.py`` to prevent dependence
|
||||||
|
on the Python version and avoid the time-consuming generation with every
|
||||||
|
Docutils run. See there for motives and implementation details.
|
||||||
|
|
||||||
|
The category of some characters changed with the development of the
|
||||||
|
Unicode standard. The current lists are generated with the help of the
|
||||||
|
"unicodedata" module of Python 2.7.13 (based on Unicode version 5.2.0).
|
||||||
|
|
||||||
|
.. _inline markup recognition rules:
|
||||||
|
http://docutils.sf.net/docs/ref/rst/restructuredtext.html#inline-markup-recognition-rules
|
||||||
|
"""
|
||||||
|
|
||||||
openers = (u'"\'(<\\[{\u0f3a\u0f3c\u169b\u2045\u207d\u208d\u2329\u2768'
|
openers = (u'"\'(<\\[{\u0f3a\u0f3c\u169b\u2045\u207d\u208d\u2329\u2768'
|
||||||
u'\u276a\u276c\u276e\u2770\u2772\u2774\u27c5\u27e6\u27e8\u27ea'
|
u'\u276a\u276c\u276e\u2770\u2772\u2774\u27c5\u27e6\u27e8\u27ea'
|
||||||
|
@ -84,272 +94,29 @@ closing_delimiters = u'\\\\.,;!?'
|
||||||
# Matching open/close quotes
|
# Matching open/close quotes
|
||||||
# --------------------------
|
# --------------------------
|
||||||
|
|
||||||
# Rule (5) requires determination of matching open/close pairs. However,
|
quote_pairs = {# open char: matching closing characters # usage example
|
||||||
# the pairing of open/close quotes is ambigue due to different typographic
|
u'\xbb': u'\xbb', # » » Swedish
|
||||||
# conventions in different languages.
|
u'\u2018': u'\u201a', # ‘ ‚ Albanian/Greek/Turkish
|
||||||
|
u'\u2019': u'\u2019', # ’ ’ Swedish
|
||||||
quote_pairs = {u'\xbb': u'\xbb', # Swedish
|
u'\u201a': u'\u2018\u2019', # ‚ ‘ German ‚ ’ Polish
|
||||||
u'\u2018': u'\u201a', # Greek
|
u'\u201c': u'\u201e', # “ „ Albanian/Greek/Turkish
|
||||||
u'\u2019': u'\u2019', # Swedish
|
u'\u201e': u'\u201c\u201d', # „ “ German „ ” Polish
|
||||||
u'\u201a': u'\u2018\u2019', # German, Polish
|
u'\u201d': u'\u201d', # ” ” Swedish
|
||||||
u'\u201c': u'\u201e', # German
|
u'\u203a': u'\u203a', # › › Swedish
|
||||||
u'\u201e': u'\u201c\u201d',
|
}
|
||||||
u'\u201d': u'\u201d', # Swedish
|
"""Additional open/close quote pairs."""
|
||||||
u'\u203a': u'\u203a', # Swedish
|
|
||||||
}
|
|
||||||
|
|
||||||
def match_chars(c1, c2):
|
def match_chars(c1, c2):
|
||||||
|
"""Test whether `c1` and `c2` are a matching open/close character pair.
|
||||||
|
|
||||||
|
Matching open/close pairs are at the same position in
|
||||||
|
`punctuation_chars.openers` and `punctuation_chars.closers`.
|
||||||
|
The pairing of open/close quotes is ambiguous due to different
|
||||||
|
typographic conventions in different languages,
|
||||||
|
so we test for additional matches stored in `quote_pairs`.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
i = openers.index(c1)
|
i = openers.index(c1)
|
||||||
except ValueError: # c1 not in openers
|
except ValueError: # c1 not in openers
|
||||||
return False
|
return False
|
||||||
return c2 == closers[i] or c2 in quote_pairs.get(c1, '')
|
return c2 == closers[i] or c2 in quote_pairs.get(c1, u'')
|
||||||
|
|
||||||
|
|
||||||
# Running this file as a standalone module checks the definitions against a
|
|
||||||
# re-calculation::
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
|
||||||
|
|
||||||
# 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
|
|
||||||
(`sys.maxint` is 0x10FFFF in a "wide" build and 0xFFFF in a "narrow"
|
|
||||||
build, i.e. ucs4 and ucs2 respectively).
|
|
||||||
"""
|
|
||||||
# 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`_)
|
|
||||||
|
|
||||||
# allowed before markup if there is a matching closer
|
|
||||||
openers = [u'"\'(<\\[{']
|
|
||||||
for cat in ('Ps', 'Pi', 'Pf'):
|
|
||||||
openers.extend(ucharlists[cat])
|
|
||||||
|
|
||||||
# allowed after markup if there is a matching opener
|
|
||||||
closers = [u'"\')>\\]}']
|
|
||||||
for cat in ('Pe', 'Pf', 'Pi'):
|
|
||||||
closers.extend(ucharlists[cat])
|
|
||||||
|
|
||||||
# non-matching, allowed on both sides
|
|
||||||
delimiters = [u'\\-/:']
|
|
||||||
for cat in ('Pd', 'Po'):
|
|
||||||
delimiters.extend(ucharlists[cat])
|
|
||||||
|
|
||||||
# non-matching, after markup
|
|
||||||
closing_delimiters = [r'\\.,;!?']
|
|
||||||
|
|
||||||
# # 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)]
|
|
||||||
|
|
||||||
def separate_wide_chars(s):
|
|
||||||
"""Return (s1,s2) with characters above 0xFFFF in s2"""
|
|
||||||
maxunicode_narrow = 0xFFFF
|
|
||||||
l1 = [ch for ch in s if ord(ch) <= maxunicode_narrow]
|
|
||||||
l2 = [ch for ch in s if ord(ch) > maxunicode_narrow]
|
|
||||||
return ''.join(l1), ''.join(l2)
|
|
||||||
|
|
||||||
def mark_intervals(s):
|
|
||||||
"""Return s with shortcut notation for runs of consecutive characters
|
|
||||||
|
|
||||||
Sort string and replace 'cdef' by 'c-f' and similar.
|
|
||||||
"""
|
|
||||||
l =[]
|
|
||||||
s = [ord(ch) for ch in s]
|
|
||||||
s.sort()
|
|
||||||
for n in s:
|
|
||||||
try:
|
|
||||||
if l[-1][-1]+1 == n:
|
|
||||||
l[-1].append(n)
|
|
||||||
else:
|
|
||||||
l.append([n])
|
|
||||||
except IndexError:
|
|
||||||
l.append([n])
|
|
||||||
|
|
||||||
l2 = []
|
|
||||||
for i in l:
|
|
||||||
i = [unichr(n) for n in i]
|
|
||||||
if len(i) > 2:
|
|
||||||
i = i[0], u'-', i[-1]
|
|
||||||
l2.extend(i)
|
|
||||||
|
|
||||||
return ''.join(l2)
|
|
||||||
|
|
||||||
def wrap_string(s, startstring= "(",
|
|
||||||
endstring = ")", wrap=65):
|
|
||||||
"""Line-wrap a unicode string literal definition."""
|
|
||||||
c = len(startstring)
|
|
||||||
contstring = "'\n" + ' ' * len(startstring) + "u'"
|
|
||||||
l = [startstring]
|
|
||||||
for ch in s:
|
|
||||||
c += 1
|
|
||||||
if ch == '\\' and c > wrap:
|
|
||||||
c = len(startstring)
|
|
||||||
ch = contstring + ch
|
|
||||||
l.append(ch)
|
|
||||||
l.append(endstring)
|
|
||||||
return ''.join(l)
|
|
||||||
|
|
||||||
|
|
||||||
# print results
|
|
||||||
# =============
|
|
||||||
|
|
||||||
# (re) create and compare the samples:
|
|
||||||
|
|
||||||
(o, c, d, cd) = punctuation_samples()
|
|
||||||
o, o_wide = separate_wide_chars(o)
|
|
||||||
c, c_wide = separate_wide_chars(c)
|
|
||||||
d, d_wide = separate_wide_chars(d)
|
|
||||||
d = d[:5] + mark_intervals(d[5:])
|
|
||||||
d_wide = mark_intervals(d_wide)
|
|
||||||
if sys.maxunicode >= 0x10FFFF: # "wide" build
|
|
||||||
d += d_wide
|
|
||||||
if o != openers:
|
|
||||||
print '- openers = ur"""%s"""' % openers.encode('utf8')
|
|
||||||
print '+ openers = ur"""%s"""' % o.encode('utf8')
|
|
||||||
if o_wide:
|
|
||||||
print '+ openers-wide = ur"""%s"""' % o_wide.encode('utf8')
|
|
||||||
if c != closers:
|
|
||||||
print '- closers = ur"""%s"""' % closers.encode('utf8')
|
|
||||||
print '+ closers = ur"""%s"""' % c.encode('utf8')
|
|
||||||
if c_wide:
|
|
||||||
print '+ closers-wide = ur"""%s"""' % c_wide.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')
|
|
||||||
# closing_delimiters are all ASCII characters
|
|
||||||
|
|
||||||
# Print literal code to define the character sets:
|
|
||||||
|
|
||||||
# `openers` and `closers` must be verbose and keep order because they are
|
|
||||||
# also used in `match_chars()`.
|
|
||||||
print wrap_string(repr(o), startstring='openers = (')
|
|
||||||
print wrap_string(repr(c), startstring='closers = (')
|
|
||||||
# delimiters: sort and use shortcut for intervals (saves ~150 characters):
|
|
||||||
print wrap_string(repr(d), startstring='delimiters = (')
|
|
||||||
# add characters in the upper plane only in a "wide" build:
|
|
||||||
print 'if sys.maxunicode >= 0x10FFFF: # "wide" build'
|
|
||||||
print wrap_string(repr(d_wide), startstring=' delimiters += (')
|
|
||||||
print 'closing_delimiters =', repr(cd)
|
|
||||||
|
|
||||||
# test prints
|
|
||||||
|
|
||||||
# print "wide" Unicode characters:
|
|
||||||
# ucharlists = unicode_charlists(unicode_punctuation_categories)
|
|
||||||
# for key in ucharlists:
|
|
||||||
# if key.endswith('wide'):
|
|
||||||
# print key, ucharlists[key]
|
|
||||||
|
|
||||||
# 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')
|
|
||||||
|
|
||||||
# verbose print
|
|
||||||
|
|
||||||
# print 'openers:'
|
|
||||||
# for ch in openers:
|
|
||||||
# print ch.encode('utf8'), unicodedata.name(ch)
|
|
||||||
# print 'closers:'
|
|
||||||
# for ch in closers:
|
|
||||||
# print ch.encode('utf8'), unicodedata.name(ch)
|
|
||||||
# print 'delimiters:'
|
|
||||||
# for ch in delimiters:
|
|
||||||
# print ch.encode('utf8'), unicodedata.name(ch)
|
|
||||||
# print 'closing_delimiters:'
|
|
||||||
# for ch in closing_delimiters:
|
|
||||||
# print ch.encode('utf8'), unicodedata.name(ch)
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# :Id: $Id: smartquotes.py 7716 2013-08-21 21:54:57Z milde $
|
# :Id: $Id: smartquotes.py 8095 2017-05-30 21:04:18Z milde $
|
||||||
# :Copyright: © 2010 Günter Milde,
|
# :Copyright: © 2010 Günter Milde,
|
||||||
# original `SmartyPants`_: © 2003 John Gruber
|
# original `SmartyPants`_: © 2003 John Gruber
|
||||||
# smartypants.py: © 2004, 2007 Chad Miller
|
# smartypants.py: © 2004, 2007 Chad Miller
|
||||||
|
@ -17,25 +17,25 @@
|
||||||
|
|
||||||
|
|
||||||
r"""
|
r"""
|
||||||
========================
|
=========================
|
||||||
SmartyPants for Docutils
|
Smart Quotes for Docutils
|
||||||
========================
|
=========================
|
||||||
|
|
||||||
Synopsis
|
Synopsis
|
||||||
========
|
========
|
||||||
|
|
||||||
Smart-quotes for Docutils.
|
"SmartyPants" is a free web publishing plug-in for Movable Type, Blosxom, and
|
||||||
|
BBEdit that easily translates plain ASCII punctuation characters into "smart"
|
||||||
|
typographic punctuation characters.
|
||||||
|
|
||||||
The original "SmartyPants" is a free web publishing plug-in for Movable Type,
|
``smartquotes.py`` is an adaption of "SmartyPants" to Docutils_.
|
||||||
Blosxom, and BBEdit that easily translates plain ASCII punctuation characters
|
|
||||||
into "smart" typographic punctuation characters.
|
|
||||||
|
|
||||||
`smartypants.py`, endeavours to be a functional port of
|
* Using Unicode instead of HTML entities for typographic punctuation
|
||||||
SmartyPants to Python, for use with Pyblosxom_.
|
characters, it works for any output format that supports Unicode.
|
||||||
|
* Supports `language specific quote characters`__.
|
||||||
|
|
||||||
|
__ http://en.wikipedia.org/wiki/Non-English_usage_of_quotation_marks
|
||||||
|
|
||||||
`smartquotes.py` is an adaption of Smartypants to Docutils_. By using Unicode
|
|
||||||
characters instead of HTML entities for typographic quotes, it works for any
|
|
||||||
output format that supports Unicode.
|
|
||||||
|
|
||||||
Authors
|
Authors
|
||||||
=======
|
=======
|
||||||
|
@ -43,7 +43,7 @@ Authors
|
||||||
`John Gruber`_ did all of the hard work of writing this software in Perl for
|
`John Gruber`_ did all of the hard work of writing this software in Perl for
|
||||||
`Movable Type`_ and almost all of this useful documentation. `Chad Miller`_
|
`Movable Type`_ and almost all of this useful documentation. `Chad Miller`_
|
||||||
ported it to Python to use with Pyblosxom_.
|
ported it to Python to use with Pyblosxom_.
|
||||||
Adapted to Docutils_ by Günter Milde
|
Adapted to Docutils_ by Günter Milde.
|
||||||
|
|
||||||
Additional Credits
|
Additional Credits
|
||||||
==================
|
==================
|
||||||
|
@ -160,102 +160,25 @@ appropriate, such as source code or example markup.
|
||||||
Backslash Escapes
|
Backslash Escapes
|
||||||
=================
|
=================
|
||||||
|
|
||||||
If you need to use literal straight quotes (or plain hyphens and
|
If you need to use literal straight quotes (or plain hyphens and periods),
|
||||||
periods), SmartyPants accepts the following backslash escape sequences
|
`smartquotes` accepts the following backslash escape sequences to force
|
||||||
to force non-smart punctuation. It does so by transforming the escape
|
ASCII-punctuation. Mind, that you need two backslashes as Docutils expands it,
|
||||||
sequence into a character:
|
too.
|
||||||
|
|
||||||
======== ===== =========
|
======== =========
|
||||||
Escape Value Character
|
Escape Character
|
||||||
======== ===== =========
|
======== =========
|
||||||
``\\\\`` \ \\
|
``\\`` \\
|
||||||
\\" " "
|
``\\"`` \\"
|
||||||
\\' ' '
|
``\\'`` \\'
|
||||||
\\. . .
|
``\\.`` \\.
|
||||||
\\- - \-
|
``\\-`` \\-
|
||||||
\\` ` \`
|
``\\``` \\`
|
||||||
======== ===== =========
|
======== =========
|
||||||
|
|
||||||
This is useful, for example, when you want to use straight quotes as
|
This is useful, for example, when you want to use straight quotes as
|
||||||
foot and inch marks: 6\\'2\\" tall; a 17\\" iMac.
|
foot and inch marks: 6\\'2\\" tall; a 17\\" iMac.
|
||||||
|
|
||||||
Options
|
|
||||||
=======
|
|
||||||
|
|
||||||
For Pyblosxom users, the ``smartypants_attributes`` attribute is where you
|
|
||||||
specify configuration options.
|
|
||||||
|
|
||||||
Numeric values are the easiest way to configure SmartyPants' behavior:
|
|
||||||
|
|
||||||
"0"
|
|
||||||
Suppress all transformations. (Do nothing.)
|
|
||||||
"1"
|
|
||||||
Performs default SmartyPants transformations: quotes (including
|
|
||||||
\`\`backticks'' -style), em-dashes, and ellipses. "``--``" (dash dash)
|
|
||||||
is used to signify an em-dash; there is no support for en-dashes.
|
|
||||||
|
|
||||||
"2"
|
|
||||||
Same as smarty_pants="1", except that it uses the old-school typewriter
|
|
||||||
shorthand for dashes: "``--``" (dash dash) for en-dashes, "``---``"
|
|
||||||
(dash dash dash)
|
|
||||||
for em-dashes.
|
|
||||||
|
|
||||||
"3"
|
|
||||||
Same as smarty_pants="2", but inverts the shorthand for dashes:
|
|
||||||
"``--``" (dash dash) for em-dashes, and "``---``" (dash dash dash) for
|
|
||||||
en-dashes.
|
|
||||||
|
|
||||||
"-1"
|
|
||||||
Stupefy mode. Reverses the SmartyPants transformation process, turning
|
|
||||||
the characters produced by SmartyPants into their ASCII equivalents.
|
|
||||||
E.g. "“" is turned into a simple double-quote (\"), "—" is
|
|
||||||
turned into two dashes, etc.
|
|
||||||
|
|
||||||
|
|
||||||
The following single-character attribute values can be combined to toggle
|
|
||||||
individual transformations from within the smarty_pants attribute. For
|
|
||||||
example, to educate normal quotes and em-dashes, but not ellipses or
|
|
||||||
\`\`backticks'' -style quotes:
|
|
||||||
|
|
||||||
``py['smartypants_attributes'] = "1"``
|
|
||||||
|
|
||||||
"q"
|
|
||||||
Educates normal quote characters: (") and (').
|
|
||||||
|
|
||||||
"b"
|
|
||||||
Educates \`\`backticks'' -style double quotes.
|
|
||||||
|
|
||||||
"B"
|
|
||||||
Educates \`\`backticks'' -style double quotes and \`single' quotes.
|
|
||||||
|
|
||||||
"d"
|
|
||||||
Educates em-dashes.
|
|
||||||
|
|
||||||
"D"
|
|
||||||
Educates em-dashes and en-dashes, using old-school typewriter shorthand:
|
|
||||||
(dash dash) for en-dashes, (dash dash dash) for em-dashes.
|
|
||||||
|
|
||||||
"i"
|
|
||||||
Educates em-dashes and en-dashes, using inverted old-school typewriter
|
|
||||||
shorthand: (dash dash) for em-dashes, (dash dash dash) for en-dashes.
|
|
||||||
|
|
||||||
"e"
|
|
||||||
Educates ellipses.
|
|
||||||
|
|
||||||
"w"
|
|
||||||
Translates any instance of ``"`` into a normal double-quote character.
|
|
||||||
This should be of no interest to most people, but of particular interest
|
|
||||||
to anyone who writes their posts using Dreamweaver, as Dreamweaver
|
|
||||||
inexplicably uses this entity to represent a literal double-quote
|
|
||||||
character. SmartyPants only educates normal quotes, not entities (because
|
|
||||||
ordinarily, entities are used for the explicit purpose of representing the
|
|
||||||
specific character they represent). The "w" option must be used in
|
|
||||||
conjunction with one (or both) of the other quote options ("q" or "b").
|
|
||||||
Thus, if you wish to apply all SmartyPants transformations (quotes, en-
|
|
||||||
and em-dashes, and ellipses) and also translate ``"`` entities into
|
|
||||||
regular quotes so SmartyPants can educate them, you should pass the
|
|
||||||
following to the smarty_pants attribute:
|
|
||||||
|
|
||||||
|
|
||||||
Caveats
|
Caveats
|
||||||
=======
|
=======
|
||||||
|
@ -274,7 +197,7 @@ If you're the sort of person who just doesn't care, you might well want to
|
||||||
continue not caring. Using straight quotes -- and sticking to the 7-bit
|
continue not caring. Using straight quotes -- and sticking to the 7-bit
|
||||||
ASCII character set in general -- is certainly a simpler way to live.
|
ASCII character set in general -- is certainly a simpler way to live.
|
||||||
|
|
||||||
Even if you I *do* care about accurate typography, you still might want to
|
Even if you *do* care about accurate typography, you still might want to
|
||||||
think twice before educating the quote characters in your weblog. One side
|
think twice before educating the quote characters in your weblog. One side
|
||||||
effect of publishing curly quote characters is that it makes your
|
effect of publishing curly quote characters is that it makes your
|
||||||
weblog a bit harder for others to quote from using copy-and-paste. What
|
weblog a bit harder for others to quote from using copy-and-paste. What
|
||||||
|
@ -300,21 +223,52 @@ Algorithmic Shortcomings
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
One situation in which quotes will get curled the wrong way is when
|
One situation in which quotes will get curled the wrong way is when
|
||||||
apostrophes are used at the start of leading contractions. For example:
|
apostrophes are used at the start of leading contractions. For example::
|
||||||
|
|
||||||
``'Twas the night before Christmas.``
|
'Twas the night before Christmas.
|
||||||
|
|
||||||
In the case above, SmartyPants will turn the apostrophe into an opening
|
In the case above, SmartyPants will turn the apostrophe into an opening
|
||||||
single-quote, when in fact it should be a closing one. I don't think
|
single-quote, when in fact it should be the `right single quotation mark`
|
||||||
this problem can be solved in the general case -- every word processor
|
character which is also "the preferred character to use for apostrophe"
|
||||||
I've tried gets this wrong as well. In such cases, it's best to use the
|
(Unicode). I don't think this problem can be solved in the general case --
|
||||||
proper character for closing single-quotes (``’``) by hand.
|
every word processor I've tried gets this wrong as well. In such cases, it's
|
||||||
|
best to use the proper character for closing single-quotes (’) by hand.
|
||||||
|
|
||||||
|
In English, the same character is used for apostrophe and closing single
|
||||||
|
quote (both plain and "smart" ones). For other locales (French, Italean,
|
||||||
|
Swiss, ...) "smart" single closing quotes differ from the curly apostrophe.
|
||||||
|
|
||||||
|
.. class:: language-fr
|
||||||
|
|
||||||
|
Il dit : "C'est 'super' !"
|
||||||
|
|
||||||
|
If the apostrophe is used at the end of a word, it cannot be distinguished
|
||||||
|
from a single quote by the algorithm. Therefore, a text like::
|
||||||
|
|
||||||
|
.. class:: language-de-CH
|
||||||
|
|
||||||
|
"Er sagt: 'Ich fass' es nicht.'"
|
||||||
|
|
||||||
|
will get a single closing guillemet instead of an apostrophe.
|
||||||
|
|
||||||
|
This can be prevented by use use of the curly apostrophe character (’) in
|
||||||
|
the source::
|
||||||
|
|
||||||
|
- "Er sagt: 'Ich fass' es nicht.'"
|
||||||
|
+ "Er sagt: 'Ich fass’ es nicht.'"
|
||||||
|
|
||||||
|
|
||||||
Version History
|
Version History
|
||||||
===============
|
===============
|
||||||
|
|
||||||
1.7 2012-11-19
|
1.8: 2017-04-24
|
||||||
|
- Command line front-end.
|
||||||
|
|
||||||
|
1.7.1: 2017-03-19
|
||||||
|
- Update and extend language-dependent quotes.
|
||||||
|
- Differentiate apostrophe from single quote.
|
||||||
|
|
||||||
|
1.7: 2012-11-19
|
||||||
- Internationalization: language-dependent quotes.
|
- Internationalization: language-dependent quotes.
|
||||||
|
|
||||||
1.6.1: 2012-11-06
|
1.6.1: 2012-11-06
|
||||||
|
@ -358,10 +312,72 @@ Version History
|
||||||
- Initial release
|
- Initial release
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
options = r"""
|
||||||
|
Options
|
||||||
|
=======
|
||||||
|
|
||||||
|
Numeric values are the easiest way to configure SmartyPants' behavior:
|
||||||
|
|
||||||
|
:0: Suppress all transformations. (Do nothing.)
|
||||||
|
|
||||||
|
:1: Performs default SmartyPants transformations: quotes (including
|
||||||
|
\`\`backticks'' -style), em-dashes, and ellipses. "``--``" (dash dash)
|
||||||
|
is used to signify an em-dash; there is no support for en-dashes
|
||||||
|
|
||||||
|
:2: Same as smarty_pants="1", except that it uses the old-school typewriter
|
||||||
|
shorthand for dashes: "``--``" (dash dash) for en-dashes, "``---``"
|
||||||
|
(dash dash dash)
|
||||||
|
for em-dashes.
|
||||||
|
|
||||||
|
:3: Same as smarty_pants="2", but inverts the shorthand for dashes:
|
||||||
|
"``--``" (dash dash) for em-dashes, and "``---``" (dash dash dash) for
|
||||||
|
en-dashes.
|
||||||
|
|
||||||
|
:-1: Stupefy mode. Reverses the SmartyPants transformation process, turning
|
||||||
|
the characters produced by SmartyPants into their ASCII equivalents.
|
||||||
|
E.g. the LEFT DOUBLE QUOTATION MARK (“) is turned into a simple
|
||||||
|
double-quote (\"), "—" is turned into two dashes, etc.
|
||||||
|
|
||||||
|
|
||||||
|
The following single-character attribute values can be combined to toggle
|
||||||
|
individual transformations from within the smarty_pants attribute. For
|
||||||
|
example, ``"1"`` is equivalent to ``"qBde"``.
|
||||||
|
|
||||||
|
:q: Educates normal quote characters: (") and (').
|
||||||
|
|
||||||
|
:b: Educates \`\`backticks'' -style double quotes.
|
||||||
|
|
||||||
|
:B: Educates \`\`backticks'' -style double quotes and \`single' quotes.
|
||||||
|
|
||||||
|
:d: Educates em-dashes.
|
||||||
|
|
||||||
|
:D: Educates em-dashes and en-dashes, using old-school typewriter shorthand:
|
||||||
|
(dash dash) for en-dashes, (dash dash dash) for em-dashes.
|
||||||
|
|
||||||
|
:i: Educates em-dashes and en-dashes, using inverted old-school typewriter
|
||||||
|
shorthand: (dash dash) for em-dashes, (dash dash dash) for en-dashes.
|
||||||
|
|
||||||
|
:e: Educates ellipses.
|
||||||
|
|
||||||
|
:w: Translates any instance of ``"`` into a normal double-quote character.
|
||||||
|
This should be of no interest to most people, but of particular interest
|
||||||
|
to anyone who writes their posts using Dreamweaver, as Dreamweaver
|
||||||
|
inexplicably uses this entity to represent a literal double-quote
|
||||||
|
character. SmartyPants only educates normal quotes, not entities (because
|
||||||
|
ordinarily, entities are used for the explicit purpose of representing the
|
||||||
|
specific character they represent). The "w" option must be used in
|
||||||
|
conjunction with one (or both) of the other quote options ("q" or "b").
|
||||||
|
Thus, if you wish to apply all SmartyPants transformations (quotes, en-
|
||||||
|
and em-dashes, and ellipses) and also translate ``"`` entities into
|
||||||
|
regular quotes so SmartyPants can educate them, you should pass the
|
||||||
|
following to the smarty_pants attribute:
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
default_smartypants_attr = "1"
|
default_smartypants_attr = "1"
|
||||||
|
|
||||||
|
|
||||||
import re
|
import re, sys
|
||||||
|
|
||||||
class smartchars(object):
|
class smartchars(object):
|
||||||
"""Smart quotes and dashes
|
"""Smart quotes and dashes
|
||||||
|
@ -370,75 +386,116 @@ class smartchars(object):
|
||||||
endash = u'–' # "–" EN DASH
|
endash = u'–' # "–" EN DASH
|
||||||
emdash = u'—' # "—" EM DASH
|
emdash = u'—' # "—" EM DASH
|
||||||
ellipsis = u'…' # "…" HORIZONTAL ELLIPSIS
|
ellipsis = u'…' # "…" HORIZONTAL ELLIPSIS
|
||||||
|
apostrophe = u'’' # "’" RIGHT SINGLE QUOTATION MARK
|
||||||
|
|
||||||
# quote characters (language-specific, set in __init__())
|
# quote characters (language-specific, set in __init__())
|
||||||
|
# [1] http://en.wikipedia.org/wiki/Non-English_usage_of_quotation_marks
|
||||||
|
# [2] http://de.wikipedia.org/wiki/Anf%C3%BChrungszeichen#Andere_Sprachen
|
||||||
|
# [3] https://fr.wikipedia.org/wiki/Guillemet
|
||||||
|
# [4] http://typographisme.net/post/Les-espaces-typographiques-et-le-web
|
||||||
|
# [5] http://www.btb.termiumplus.gc.ca/tpv2guides/guides/redac/index-fra.html
|
||||||
|
# [6] https://en.wikipedia.org/wiki/Hebrew_punctuation#Quotation_marks
|
||||||
|
# [7] http://www.tustep.uni-tuebingen.de/bi/bi00/bi001t1-anfuehrung.pdf
|
||||||
|
# [8] http://www.korrekturavdelingen.no/anforselstegn.htm
|
||||||
|
# [9] Typografisk håndbok. Oslo: Spartacus. 2000. s. 67. ISBN 8243001530.
|
||||||
|
# [10] http://www.typografi.org/sitat/sitatart.html
|
||||||
#
|
#
|
||||||
# English smart quotes (open primary, close primary, open secondary, close
|
# TODO: configuration option, e.g.::
|
||||||
# secondary) are:
|
#
|
||||||
# opquote = u'“' # "“" LEFT DOUBLE QUOTATION MARK
|
# smartquote-locales: nl: „“’’, # apostrophe for ``'s Gravenhage``
|
||||||
# cpquote = u'”' # "”" RIGHT DOUBLE QUOTATION MARK
|
# nr: se, # alias
|
||||||
# osquote = u'‘' # "‘" LEFT SINGLE QUOTATION MARK
|
# fr: « : »:‹ : ›, # :-separated list with NBSPs
|
||||||
# csquote = u'’' # "’" RIGHT SINGLE QUOTATION MARK
|
|
||||||
# For other languages see:
|
|
||||||
# http://en.wikipedia.org/wiki/Non-English_usage_of_quotation_marks
|
|
||||||
# http://de.wikipedia.org/wiki/Anf%C3%BChrungszeichen#Andere_Sprachen
|
|
||||||
quotes = {'af': u'“”‘’',
|
quotes = {'af': u'“”‘’',
|
||||||
'af-x-altquot': u'„”‚’',
|
'af-x-altquot': u'„”‚’',
|
||||||
|
'bg': u'„“‚‘', # Bulgarian, https://bg.wikipedia.org/wiki/Кавички
|
||||||
'ca': u'«»“”',
|
'ca': u'«»“”',
|
||||||
'ca-x-altquot': u'“”‘’',
|
'ca-x-altquot': u'“”‘’',
|
||||||
'cs': u'„“‚‘',
|
'cs': u'„“‚‘',
|
||||||
'cs-x-altquot': u'»«›‹',
|
'cs-x-altquot': u'»«›‹',
|
||||||
'da': u'»«‘’',
|
'da': u'»«›‹',
|
||||||
'da-x-altquot': u'„“‚‘',
|
'da-x-altquot': u'„“‚‘',
|
||||||
|
# 'da-x-altquot2': u'””’’',
|
||||||
'de': u'„“‚‘',
|
'de': u'„“‚‘',
|
||||||
'de-x-altquot': u'»«›‹',
|
'de-x-altquot': u'»«›‹',
|
||||||
'de-CH': u'«»‹›',
|
'de-ch': u'«»‹›',
|
||||||
'el': u'«»“”',
|
'el': u'«»“”',
|
||||||
'en': u'“”‘’',
|
'en': u'“”‘’',
|
||||||
'en-UK': u'‘’“”',
|
'en-uk-x-altquot': u'‘’“”', # Attention: " → ‘ and ' → “ !
|
||||||
'eo': u'“”‘’',
|
'eo': u'“”‘’',
|
||||||
'es': u'«»“”',
|
'es': u'«»“”',
|
||||||
'et': u'„“‚‘', # no secondary quote listed in
|
|
||||||
'et-x-altquot': u'»«›‹', # the sources above (wikipedia.org)
|
|
||||||
'eu': u'«»‹›',
|
|
||||||
'es-x-altquot': u'“”‘’',
|
'es-x-altquot': u'“”‘’',
|
||||||
|
'et': u'„“‚‘', # no secondary quote listed in
|
||||||
|
'et-x-altquot': u'«»‹›', # the sources above (wikipedia.org)
|
||||||
|
'eu': u'«»‹›',
|
||||||
'fi': u'””’’',
|
'fi': u'””’’',
|
||||||
'fi-x-altquot': u'»»’’',
|
'fi-x-altquot': u'»»››',
|
||||||
'fr': (u'« ', u' »', u'‹ ', u' ›'), # with narrow no-break space
|
'fr': (u'« ', u' »', u'“', u'”'), # full no-break space
|
||||||
'fr-x-altquot': u'«»‹›', # for use with manually set spaces
|
'fr-x-altquot': (u'« ', u' »', u'“', u'”'), # narrow no-break space
|
||||||
# 'fr-x-altquot': (u'“ ', u' ”', u'‘ ', u' ’'), # rarely used
|
'fr-ch': u'«»‹›',
|
||||||
'fr-CH': u'«»‹›',
|
'fr-ch-x-altquot': (u'« ', u' »', u'‹ ', u' ›'), # narrow no-break space, http://typoguide.ch/
|
||||||
'gl': u'«»“”',
|
'gl': u'«»“”',
|
||||||
'he': u'”“»«',
|
'he': u'”“»«', # Hebrew is RTL, test position:
|
||||||
'he-x-altquot': u'„”‚’',
|
'he-x-altquot': u'„”‚’', # low quotation marks are opening.
|
||||||
|
# 'he-x-altquot': u'“„‘‚', # RTL: low quotation marks opening
|
||||||
|
'hr': u'„”‘’', # http://hrvatska-tipografija.com/polunavodnici/
|
||||||
|
'hr-x-altquot': u'»«›‹',
|
||||||
|
'hsb': u'„“‚‘',
|
||||||
|
'hsb-x-altquot':u'»«›‹',
|
||||||
|
'hu': u'„”«»',
|
||||||
|
'is': u'„“‚‘',
|
||||||
'it': u'«»“”',
|
'it': u'«»“”',
|
||||||
'it-CH': u'«»‹›',
|
'it-ch': u'«»‹›',
|
||||||
'it-x-altquot': u'“”‘’',
|
'it-x-altquot': u'“”‘’',
|
||||||
|
# 'it-x-altquot2': u'“„‘‚', # [7] in headlines
|
||||||
'ja': u'「」『』',
|
'ja': u'「」『』',
|
||||||
'lt': u'„“‚‘',
|
'lt': u'„“‚‘',
|
||||||
|
'lv': u'„“‚‘',
|
||||||
|
'mk': u'„“‚‘', # Macedonian, https://mk.wikipedia.org/wiki/Правопис_и_правоговор_на_македонскиот_јазик
|
||||||
'nl': u'“”‘’',
|
'nl': u'“”‘’',
|
||||||
'nl-x-altquot': u'„”‚’',
|
'nl-x-altquot': u'„”‚’',
|
||||||
|
# 'nl-x-altquot2': u'””’’',
|
||||||
|
'nb': u'«»’’', # Norsk bokmål (canonical form 'no')
|
||||||
|
'nn': u'«»’’', # Nynorsk [10]
|
||||||
|
'nn-x-altquot': u'«»‘’', # [8], [10]
|
||||||
|
# 'nn-x-altquot2': u'«»«»', # [9], [10
|
||||||
|
# 'nn-x-altquot3': u'„“‚‘', # [10]
|
||||||
|
'no': u'«»’’', # Norsk bokmål [10]
|
||||||
|
'no-x-altquot': u'«»‘’', # [8], [10]
|
||||||
|
# 'no-x-altquot2': u'«»«»', # [9], [10
|
||||||
|
# 'no-x-altquot3': u'„“‚‘', # [10]
|
||||||
'pl': u'„”«»',
|
'pl': u'„”«»',
|
||||||
'pl-x-altquot': u'«»“”',
|
'pl-x-altquot': u'«»‚’',
|
||||||
|
# 'pl-x-altquot2': u'„”‚’', # https://pl.wikipedia.org/wiki/Cudzys%C5%82%C3%B3w
|
||||||
'pt': u'«»“”',
|
'pt': u'«»“”',
|
||||||
'pt-BR': u'“”‘’',
|
'pt-br': u'“”‘’',
|
||||||
'ro': u'„”«»',
|
'ro': u'„”«»',
|
||||||
'ro-x-altquot': u'«»„”',
|
|
||||||
'ru': u'«»„“',
|
'ru': u'«»„“',
|
||||||
'sk': u'„“‚‘',
|
'sh': u'„”‚’', # Serbo-Croatian
|
||||||
|
'sh-x-altquot': u'»«›‹',
|
||||||
|
'sk': u'„“‚‘', # Slovak
|
||||||
'sk-x-altquot': u'»«›‹',
|
'sk-x-altquot': u'»«›‹',
|
||||||
'sv': u'„“‚‘',
|
'sl': u'„“‚‘', # Slovenian
|
||||||
'sv-x-altquot': u'»«›‹',
|
'sl-x-altquot': u'»«›‹',
|
||||||
'zh-CN': u'“”‘’',
|
'sq': u'«»‹›', # Albanian
|
||||||
'it': u'«»“”',
|
'sq-x-altquot': u'“„‘‚',
|
||||||
'zh-TW': u'「」『』',
|
'sr': u'„”’’',
|
||||||
|
'sr-x-altquot': u'»«›‹',
|
||||||
|
'sv': u'””’’',
|
||||||
|
'sv-x-altquot': u'»»››',
|
||||||
|
'tr': u'“”‘’',
|
||||||
|
'tr-x-altquot': u'«»‹›',
|
||||||
|
# 'tr-x-altquot2': u'“„‘‚', # [7] antiquated?
|
||||||
|
'uk': u'«»„“',
|
||||||
|
'uk-x-altquot': u'„“‚‘',
|
||||||
|
'zh-cn': u'“”‘’',
|
||||||
|
'zh-tw': u'「」『』',
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, language='en'):
|
def __init__(self, language='en'):
|
||||||
self.language = language
|
self.language = language
|
||||||
try:
|
try:
|
||||||
(self.opquote, self.cpquote,
|
(self.opquote, self.cpquote,
|
||||||
self.osquote, self.csquote) = self.quotes[language]
|
self.osquote, self.csquote) = self.quotes[language.lower()]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
self.opquote, self.cpquote, self.osquote, self.csquote = u'""\'\''
|
self.opquote, self.cpquote, self.osquote, self.csquote = u'""\'\''
|
||||||
|
|
||||||
|
@ -476,9 +533,8 @@ def educate_tokens(text_tokens, attr=default_smartypants_attr, language='en'):
|
||||||
do_ellipses = False
|
do_ellipses = False
|
||||||
do_stupefy = False
|
do_stupefy = False
|
||||||
|
|
||||||
if attr == "0": # Do nothing.
|
# if attr == "0": # pass tokens unchanged (see below).
|
||||||
yield text
|
if attr == "1": # Do everything, turn all options on.
|
||||||
elif attr == "1": # Do everything, turn all options on.
|
|
||||||
do_quotes = True
|
do_quotes = True
|
||||||
do_backticks = True
|
do_backticks = True
|
||||||
do_dashes = 1
|
do_dashes = 1
|
||||||
|
@ -550,7 +606,10 @@ def educate_tokens(text_tokens, attr=default_smartypants_attr, language='en'):
|
||||||
text = educateSingleBackticks(text, language)
|
text = educateSingleBackticks(text, language)
|
||||||
|
|
||||||
if do_quotes:
|
if do_quotes:
|
||||||
text = educateQuotes(prev_token_last_char+text, language)[1:]
|
# Replace plain quotes in context to prevent converstion to
|
||||||
|
# 2-character sequence in French.
|
||||||
|
context = prev_token_last_char.replace('"',';').replace("'",';')
|
||||||
|
text = educateQuotes(context+text, language)[1:]
|
||||||
|
|
||||||
if do_stupefy:
|
if do_stupefy:
|
||||||
text = stupefyEntities(text, language)
|
text = stupefyEntities(text, language)
|
||||||
|
@ -591,7 +650,8 @@ def educateQuotes(text, language='en'):
|
||||||
text = re.sub(r"""'"(?=\w)""", smart.osquote+smart.opquote, text)
|
text = re.sub(r"""'"(?=\w)""", smart.osquote+smart.opquote, text)
|
||||||
|
|
||||||
# Special case for decade abbreviations (the '80s):
|
# Special case for decade abbreviations (the '80s):
|
||||||
text = re.sub(r"""\b'(?=\d{2}s)""", smart.csquote, text)
|
if language.startswith('en'): # TODO similar cases in other languages?
|
||||||
|
text = re.sub(r"""'(?=\d{2}s)""", smart.apostrophe, text, re.UNICODE)
|
||||||
|
|
||||||
close_class = r"""[^\ \t\r\n\[\{\(\-]"""
|
close_class = r"""[^\ \t\r\n\[\{\(\-]"""
|
||||||
dec_dashes = r"""–|—"""
|
dec_dashes = r"""–|—"""
|
||||||
|
@ -608,21 +668,31 @@ def educateQuotes(text, language='en'):
|
||||||
)
|
)
|
||||||
' # the quote
|
' # the quote
|
||||||
(?=\w) # followed by a word character
|
(?=\w) # followed by a word character
|
||||||
""" % (dec_dashes,), re.VERBOSE)
|
""" % (dec_dashes,), re.VERBOSE | re.UNICODE)
|
||||||
text = opening_single_quotes_regex.sub(r'\1'+smart.osquote, text)
|
text = opening_single_quotes_regex.sub(r'\1'+smart.osquote, text)
|
||||||
|
|
||||||
|
# In many locales, single closing quotes are different from apostrophe:
|
||||||
|
if smart.csquote != smart.apostrophe:
|
||||||
|
apostrophe_regex = re.compile(r"(?<=(\w|\d))'(?=\w)", re.UNICODE)
|
||||||
|
text = apostrophe_regex.sub(smart.apostrophe, text)
|
||||||
|
# TODO: keep track of quoting level to recognize apostrophe in, e.g.,
|
||||||
|
# "Ich fass' es nicht."
|
||||||
|
|
||||||
closing_single_quotes_regex = re.compile(r"""
|
closing_single_quotes_regex = re.compile(r"""
|
||||||
(%s)
|
(%s)
|
||||||
'
|
'
|
||||||
(?!\s | s\b | \d)
|
(?!\s | # whitespace
|
||||||
""" % (close_class,), re.VERBOSE)
|
s\b |
|
||||||
|
\d # digits ('80s)
|
||||||
|
)
|
||||||
|
""" % (close_class,), re.VERBOSE | re.UNICODE)
|
||||||
text = closing_single_quotes_regex.sub(r'\1'+smart.csquote, text)
|
text = closing_single_quotes_regex.sub(r'\1'+smart.csquote, text)
|
||||||
|
|
||||||
closing_single_quotes_regex = re.compile(r"""
|
closing_single_quotes_regex = re.compile(r"""
|
||||||
(%s)
|
(%s)
|
||||||
'
|
'
|
||||||
(\s | s\b)
|
(\s | s\b)
|
||||||
""" % (close_class,), re.VERBOSE)
|
""" % (close_class,), re.VERBOSE | re.UNICODE)
|
||||||
text = closing_single_quotes_regex.sub(r'\1%s\2' % smart.csquote, text)
|
text = closing_single_quotes_regex.sub(r'\1%s\2' % smart.csquote, text)
|
||||||
|
|
||||||
# Any remaining single quotes should be opening ones:
|
# Any remaining single quotes should be opening ones:
|
||||||
|
@ -855,52 +925,98 @@ def tokenize(text):
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
import locale
|
import itertools
|
||||||
|
|
||||||
try:
|
try:
|
||||||
locale.setlocale(locale.LC_ALL, '')
|
import locale # module missing in Jython
|
||||||
|
locale.setlocale(locale.LC_ALL, '') # set to user defaults
|
||||||
|
defaultlanguage = locale.getdefaultlocale()[0]
|
||||||
except:
|
except:
|
||||||
pass
|
defaultlanguage = 'en'
|
||||||
|
|
||||||
from docutils.core import publish_string
|
# Normalize and drop unsupported subtags:
|
||||||
docstring_html = publish_string(__doc__, writer_name='html')
|
defaultlanguage = defaultlanguage.lower().replace('-','_')
|
||||||
|
# split (except singletons, which mark the following tag as non-standard):
|
||||||
print docstring_html
|
defaultlanguage = re.sub(r'_([a-zA-Z0-9])_', r'_\1-', defaultlanguage)
|
||||||
|
_subtags = [subtag for subtag in defaultlanguage.split('_')]
|
||||||
|
_basetag = _subtags.pop(0)
|
||||||
|
# find all combinations of subtags
|
||||||
|
for n in range(len(_subtags), 0, -1):
|
||||||
|
for tags in itertools.combinations(_subtags, n):
|
||||||
|
_tag = '-'.join((_basetag,)+tags)
|
||||||
|
if _tag in smartchars.quotes:
|
||||||
|
defaultlanguage = _tag
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if _basetag in smartchars.quotes:
|
||||||
|
defaultlanguage = _basetag
|
||||||
|
else:
|
||||||
|
defaultlanguage = 'en'
|
||||||
|
|
||||||
|
|
||||||
# Unit test output goes out stderr.
|
import argparse
|
||||||
import unittest
|
parser = argparse.ArgumentParser(
|
||||||
sp = smartyPants
|
description='Filter stdin making ASCII punctuation "smart".')
|
||||||
|
# parser.add_argument("text", help="text to be acted on")
|
||||||
|
parser.add_argument("-a", "--action", default="1",
|
||||||
|
help="what to do with the input (see --actionhelp)")
|
||||||
|
parser.add_argument("-e", "--encoding", default="utf8",
|
||||||
|
help="text encoding")
|
||||||
|
parser.add_argument("-l", "--language", default=defaultlanguage,
|
||||||
|
help="text language (BCP47 tag), Default: %s"%defaultlanguage)
|
||||||
|
parser.add_argument("-q", "--alternative-quotes", action="store_true",
|
||||||
|
help="use alternative quote style")
|
||||||
|
parser.add_argument("--doc", action="store_true",
|
||||||
|
help="print documentation")
|
||||||
|
parser.add_argument("--actionhelp", action="store_true",
|
||||||
|
help="list available actions")
|
||||||
|
parser.add_argument("--stylehelp", action="store_true",
|
||||||
|
help="list available quote styles")
|
||||||
|
parser.add_argument("--test", action="store_true",
|
||||||
|
help="perform short self-test")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
class TestSmartypantsAllAttributes(unittest.TestCase):
|
if args.doc:
|
||||||
# the default attribute is "1", which means "all".
|
print (__doc__)
|
||||||
|
elif args.actionhelp:
|
||||||
|
print(options)
|
||||||
|
elif args.stylehelp:
|
||||||
|
print()
|
||||||
|
print("Available styles (primary open/close, secondary open/close)")
|
||||||
|
print("language tag quotes")
|
||||||
|
print("============ ======")
|
||||||
|
for key in sorted(smartchars.quotes.keys()):
|
||||||
|
print("%-14s %s" % (key, smartchars.quotes[key]))
|
||||||
|
elif args.test:
|
||||||
|
# Unit test output goes to stderr.
|
||||||
|
import unittest
|
||||||
|
|
||||||
def test_dates(self):
|
class TestSmartypantsAllAttributes(unittest.TestCase):
|
||||||
self.assertEqual(sp("1440-80's"), u"1440-80’s")
|
# the default attribute is "1", which means "all".
|
||||||
self.assertEqual(sp("1440-'80s"), u"1440-‘80s")
|
def test_dates(self):
|
||||||
self.assertEqual(sp("1440---'80s"), u"1440–‘80s")
|
self.assertEqual(smartyPants("1440-80's"), u"1440-80’s")
|
||||||
self.assertEqual(sp("1960s"), "1960s") # no effect.
|
self.assertEqual(smartyPants("1440-'80s"), u"1440-’80s")
|
||||||
self.assertEqual(sp("1960's"), u"1960’s")
|
self.assertEqual(smartyPants("1440---'80s"), u"1440–’80s")
|
||||||
self.assertEqual(sp("one two '60s"), u"one two ‘60s")
|
self.assertEqual(smartyPants("1960's"), u"1960’s")
|
||||||
self.assertEqual(sp("'60s"), u"‘60s")
|
self.assertEqual(smartyPants("one two '60s"), u"one two ’60s")
|
||||||
|
self.assertEqual(smartyPants("'60s"), u"’60s")
|
||||||
|
|
||||||
def test_ordinal_numbers(self):
|
def test_educated_quotes(self):
|
||||||
self.assertEqual(sp("21st century"), "21st century") # no effect.
|
self.assertEqual(smartyPants('"Isn\'t this fun?"'), u'“Isn’t this fun?”')
|
||||||
self.assertEqual(sp("3rd"), "3rd") # no effect.
|
|
||||||
|
|
||||||
def test_educated_quotes(self):
|
def test_html_tags(self):
|
||||||
self.assertEqual(sp('''"Isn't this fun?"'''), u'“Isn’t this fun?”')
|
text = '<a src="foo">more</a>'
|
||||||
|
self.assertEqual(smartyPants(text), text)
|
||||||
|
|
||||||
def test_html_tags(self):
|
suite = unittest.TestLoader().loadTestsFromTestCase(
|
||||||
text = '<a src="foo">more</a>'
|
TestSmartypantsAllAttributes)
|
||||||
self.assertEqual(sp(text), text)
|
unittest.TextTestRunner().run(suite)
|
||||||
|
|
||||||
unittest.main()
|
else:
|
||||||
|
if args.alternative_quotes:
|
||||||
|
if '-x-altquot' in args.language:
|
||||||
|
args.language = args.language.replace('-x-altquot', '')
|
||||||
|
else:
|
||||||
__author__ = "Chad Miller <smartypantspy@chad.org>"
|
args.language += '-x-altquot'
|
||||||
__version__ = "1.5_1.6: Fri, 27 Jul 2007 07:06:40 -0400"
|
text = sys.stdin.read().decode(args.encoding)
|
||||||
__url__ = "http://wiki.chad.org/SmartyPantsPy"
|
print(smartyPants(text, attr=args.action,
|
||||||
__description__ = "Smart-quotes, smart-ellipses, and smart-dashes for weblog entries in pyblosxom"
|
language=args.language).encode(args.encoding))
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: urischemes.py 7464 2012-06-25 13:16:03Z milde $
|
# $Id: urischemes.py 7922 2015-09-22 15:28:09Z milde $
|
||||||
# Author: David Goodger <goodger@python.org>
|
# Author: David Goodger <goodger@python.org>
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ schemes = {
|
||||||
'tel': ('a connection to a terminal that handles normal voice '
|
'tel': ('a connection to a terminal that handles normal voice '
|
||||||
'telephone calls, a voice mailbox or another voice messaging '
|
'telephone calls, a voice mailbox or another voice messaging '
|
||||||
'system or a service that can be operated using DTMF tones; '
|
'system or a service that can be operated using DTMF tones; '
|
||||||
'RFC 2806.'),
|
'RFC 3966.'),
|
||||||
'telephone': 'telephone',
|
'telephone': 'telephone',
|
||||||
'telnet': 'Reference to interactive sessions; RFC 4248',
|
'telnet': 'Reference to interactive sessions; RFC 4248',
|
||||||
'tftp': 'Trivial File Transfer Protocol; RFC 3617',
|
'tftp': 'Trivial File Transfer Protocol; RFC 3617',
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: __init__.py 7648 2013-04-18 07:36:22Z milde $
|
# $Id: __init__.py 7969 2016-08-18 21:40:00Z milde $
|
||||||
# Author: David Goodger <goodger@python.org>
|
# Author: David Goodger <goodger@python.org>
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
@ -120,13 +120,18 @@ class UnfilteredWriter(Writer):
|
||||||
|
|
||||||
|
|
||||||
_writer_aliases = {
|
_writer_aliases = {
|
||||||
'html': 'html4css1',
|
'html': 'html4css1', # may change to html5 some day
|
||||||
|
'html4': 'html4css1',
|
||||||
|
'html5': 'html5_polyglot',
|
||||||
'latex': 'latex2e',
|
'latex': 'latex2e',
|
||||||
'pprint': 'pseudoxml',
|
'pprint': 'pseudoxml',
|
||||||
'pformat': 'pseudoxml',
|
'pformat': 'pseudoxml',
|
||||||
'pdf': 'rlpdf',
|
'pdf': 'rlpdf',
|
||||||
'xml': 'docutils_xml',
|
's5': 's5_html',
|
||||||
's5': 's5_html'}
|
'xelatex': 'xetex',
|
||||||
|
'xhtml': 'html5_polyglot',
|
||||||
|
'xhtml10': 'html4css1',
|
||||||
|
'xml': 'docutils_xml'}
|
||||||
|
|
||||||
def get_writer_class(writer_name):
|
def get_writer_class(writer_name):
|
||||||
"""Return the Writer class from the `writer_name` module."""
|
"""Return the Writer class from the `writer_name` module."""
|
||||||
|
|
1670
Libs/docutils/writers/_html_base.py
Normal file
1670
Libs/docutils/writers/_html_base.py
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
||||||
# $Id: docutils_xml.py 7497 2012-08-16 15:17:29Z milde $
|
# $Id: docutils_xml.py 7966 2016-08-18 13:06:09Z milde $
|
||||||
# Author: David Goodger, Paul Tremblay, Guenter Milde
|
# Author: David Goodger, Paul Tremblay, Guenter Milde
|
||||||
# Maintainer: docutils-develop@lists.sourceforge.net
|
# Maintainer: docutils-develop@lists.sourceforge.net
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
@ -46,7 +46,7 @@ class Writer(writers.Writer):
|
||||||
['--newlines'],
|
['--newlines'],
|
||||||
{'action': 'store_true', 'validator': frontend.validate_boolean}),
|
{'action': 'store_true', 'validator': frontend.validate_boolean}),
|
||||||
('Generate XML with indents and newlines.',
|
('Generate XML with indents and newlines.',
|
||||||
['--indents'],
|
['--indents'], #@ TODO use integer value for number of spaces?
|
||||||
{'action': 'store_true', 'validator': frontend.validate_boolean}),
|
{'action': 'store_true', 'validator': frontend.validate_boolean}),
|
||||||
('Omit the XML declaration. Use with caution.',
|
('Omit the XML declaration. Use with caution.',
|
||||||
['--no-xml-declaration'],
|
['--no-xml-declaration'],
|
||||||
|
@ -105,9 +105,10 @@ class XMLTranslator(nodes.GenericNodeVisitor):
|
||||||
self.newline = '\n'
|
self.newline = '\n'
|
||||||
if settings.indents:
|
if settings.indents:
|
||||||
self.newline = '\n'
|
self.newline = '\n'
|
||||||
self.indent = ' '
|
self.indent = ' ' #@ TODO make this configurable?
|
||||||
self.level = 0 # indentation level
|
self.level = 0 # indentation level
|
||||||
self.in_simple = 0 # level of nesting inside mixed-content elements
|
self.in_simple = 0 # level of nesting inside mixed-content elements
|
||||||
|
self.fixed_text = 0 # level of nesting inside FixedText elements
|
||||||
|
|
||||||
# Output
|
# Output
|
||||||
self.output = []
|
self.output = []
|
||||||
|
@ -125,13 +126,19 @@ class XMLTranslator(nodes.GenericNodeVisitor):
|
||||||
# generic visit and depart methods
|
# generic visit and depart methods
|
||||||
# --------------------------------
|
# --------------------------------
|
||||||
|
|
||||||
|
simple_nodes = (nodes.TextElement,
|
||||||
|
nodes.image, nodes.colspec, nodes.transition) # empty elements
|
||||||
|
|
||||||
def default_visit(self, node):
|
def default_visit(self, node):
|
||||||
"""Default node visit method."""
|
"""Default node visit method."""
|
||||||
if not self.in_simple:
|
if not self.in_simple:
|
||||||
self.output.append(self.indent*self.level)
|
self.output.append(self.indent*self.level)
|
||||||
self.output.append(node.starttag(xml.sax.saxutils.quoteattr))
|
self.output.append(node.starttag(xml.sax.saxutils.quoteattr))
|
||||||
self.level += 1
|
self.level += 1
|
||||||
if isinstance(node, nodes.TextElement):
|
# @@ make nodes.literal an instance of FixedTextElement?
|
||||||
|
if isinstance(node, (nodes.FixedTextElement, nodes.literal)):
|
||||||
|
self.fixed_text += 1
|
||||||
|
if isinstance(node, self.simple_nodes):
|
||||||
self.in_simple += 1
|
self.in_simple += 1
|
||||||
if not self.in_simple:
|
if not self.in_simple:
|
||||||
self.output.append(self.newline)
|
self.output.append(self.newline)
|
||||||
|
@ -142,7 +149,9 @@ class XMLTranslator(nodes.GenericNodeVisitor):
|
||||||
if not self.in_simple:
|
if not self.in_simple:
|
||||||
self.output.append(self.indent*self.level)
|
self.output.append(self.indent*self.level)
|
||||||
self.output.append(node.endtag())
|
self.output.append(node.endtag())
|
||||||
if isinstance(node, nodes.TextElement):
|
if isinstance(node, (nodes.FixedTextElement, nodes.literal)):
|
||||||
|
self.fixed_text -= 1
|
||||||
|
if isinstance(node, self.simple_nodes):
|
||||||
self.in_simple -= 1
|
self.in_simple -= 1
|
||||||
if not self.in_simple:
|
if not self.in_simple:
|
||||||
self.output.append(self.newline)
|
self.output.append(self.newline)
|
||||||
|
@ -153,6 +162,9 @@ class XMLTranslator(nodes.GenericNodeVisitor):
|
||||||
|
|
||||||
def visit_Text(self, node):
|
def visit_Text(self, node):
|
||||||
text = xml.sax.saxutils.escape(node.astext())
|
text = xml.sax.saxutils.escape(node.astext())
|
||||||
|
# indent text if we are not in a FixedText element:
|
||||||
|
if not self.fixed_text:
|
||||||
|
text = text.replace('\n', '\n'+self.indent*self.level)
|
||||||
self.output.append(text)
|
self.output.append(text)
|
||||||
|
|
||||||
def depart_Text(self, node):
|
def depart_Text(self, node):
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
:Author: David Goodger (goodger@python.org)
|
:Author: David Goodger (goodger@python.org)
|
||||||
:Id: $Id: html4css1.css 7614 2013-02-21 15:55:51Z milde $
|
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
|
||||||
:Copyright: This stylesheet has been placed in the public domain.
|
:Copyright: This stylesheet has been placed in the public domain.
|
||||||
|
|
||||||
Default cascading style sheet for the HTML output of Docutils.
|
Default cascading style sheet for the HTML output of Docutils.
|
||||||
|
@ -28,6 +28,14 @@ table.borderless td, table.borderless th {
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none }
|
display: none }
|
||||||
|
|
||||||
|
.subscript {
|
||||||
|
vertical-align: sub;
|
||||||
|
font-size: smaller }
|
||||||
|
|
||||||
|
.superscript {
|
||||||
|
vertical-align: super;
|
||||||
|
font-size: smaller }
|
||||||
|
|
||||||
a.toc-backref {
|
a.toc-backref {
|
||||||
text-decoration: none ;
|
text-decoration: none ;
|
||||||
color: black }
|
color: black }
|
||||||
|
@ -152,12 +160,12 @@ h2.subtitle {
|
||||||
hr.docutils {
|
hr.docutils {
|
||||||
width: 75% }
|
width: 75% }
|
||||||
|
|
||||||
img.align-left, .figure.align-left, object.align-left {
|
img.align-left, .figure.align-left, object.align-left, table.align-left {
|
||||||
clear: left ;
|
clear: left ;
|
||||||
float: left ;
|
float: left ;
|
||||||
margin-right: 1em }
|
margin-right: 1em }
|
||||||
|
|
||||||
img.align-right, .figure.align-right, object.align-right {
|
img.align-right, .figure.align-right, object.align-right, table.align-right {
|
||||||
clear: right ;
|
clear: right ;
|
||||||
float: right ;
|
float: right ;
|
||||||
margin-left: 1em }
|
margin-left: 1em }
|
||||||
|
@ -168,6 +176,11 @@ img.align-center, .figure.align-center, object.align-center {
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table.align-center {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.align-left {
|
.align-left {
|
||||||
text-align: left }
|
text-align: left }
|
||||||
|
|
||||||
|
@ -185,6 +198,15 @@ div.align-right {
|
||||||
/* div.align-center * { */
|
/* div.align-center * { */
|
||||||
/* text-align: left } */
|
/* text-align: left } */
|
||||||
|
|
||||||
|
.align-top {
|
||||||
|
vertical-align: top }
|
||||||
|
|
||||||
|
.align-middle {
|
||||||
|
vertical-align: middle }
|
||||||
|
|
||||||
|
.align-bottom {
|
||||||
|
vertical-align: bottom }
|
||||||
|
|
||||||
ol.simple, ul.simple {
|
ol.simple, ul.simple {
|
||||||
margin-bottom: 1em }
|
margin-bottom: 1em }
|
||||||
|
|
||||||
|
|
214
Libs/docutils/writers/html5_polyglot/__init__.py
Normal file
214
Libs/docutils/writers/html5_polyglot/__init__.py
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
# .. coding: utf8
|
||||||
|
# $Id: __init__.py 8041 2017-03-01 11:02:33Z milde $
|
||||||
|
# :Author: Günter Milde <milde@users.sf.net>
|
||||||
|
# Based on the html4css1 writer by David Goodger.
|
||||||
|
# :Maintainer: docutils-develop@lists.sourceforge.net
|
||||||
|
# :Copyright: © 2005, 2009, 2015 Günter Milde,
|
||||||
|
# portions from html4css1 © David Goodger.
|
||||||
|
# :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
|
||||||
|
|
||||||
|
# Use "best practice" as recommended by the W3C:
|
||||||
|
# http://www.w3.org/2009/cheatsheet/
|
||||||
|
|
||||||
|
"""
|
||||||
|
Plain HyperText Markup Language document tree Writer.
|
||||||
|
|
||||||
|
The output conforms to the `HTML5` specification.
|
||||||
|
|
||||||
|
The cascading style sheet "minimal.css" is required for proper viewing,
|
||||||
|
the style sheet "plain.css" improves reading experience.
|
||||||
|
"""
|
||||||
|
__docformat__ = 'reStructuredText'
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
import docutils
|
||||||
|
from docutils import frontend, nodes, writers, io
|
||||||
|
from docutils.transforms import writer_aux
|
||||||
|
from docutils.writers import _html_base
|
||||||
|
|
||||||
|
class Writer(writers._html_base.Writer):
|
||||||
|
|
||||||
|
supported = ('html', 'html5', 'html4', 'xhtml', 'xhtml10')
|
||||||
|
"""Formats this writer supports."""
|
||||||
|
|
||||||
|
default_stylesheets = ['minimal.css','plain.css']
|
||||||
|
default_stylesheet_dirs = ['.', os.path.abspath(os.path.dirname(__file__))]
|
||||||
|
|
||||||
|
default_template = 'template.txt'
|
||||||
|
default_template_path = os.path.join(
|
||||||
|
os.path.dirname(os.path.abspath(__file__)), default_template)
|
||||||
|
|
||||||
|
settings_spec = (
|
||||||
|
'HTML-Specific Options',
|
||||||
|
None,
|
||||||
|
(('Specify the template file (UTF-8 encoded). Default is "%s".'
|
||||||
|
% default_template_path,
|
||||||
|
['--template'],
|
||||||
|
{'default': default_template_path, 'metavar': '<file>'}),
|
||||||
|
('Comma separated list of stylesheet URLs. '
|
||||||
|
'Overrides previous --stylesheet and --stylesheet-path settings.',
|
||||||
|
['--stylesheet'],
|
||||||
|
{'metavar': '<URL[,URL,...]>', 'overrides': 'stylesheet_path',
|
||||||
|
'validator': frontend.validate_comma_separated_list}),
|
||||||
|
('Comma separated list of stylesheet paths. '
|
||||||
|
'Relative paths are expanded if a matching file is found in '
|
||||||
|
'the --stylesheet-dirs. With --link-stylesheet, '
|
||||||
|
'the path is rewritten relative to the output HTML file. '
|
||||||
|
'Default: "%s"' % ','.join(default_stylesheets),
|
||||||
|
['--stylesheet-path'],
|
||||||
|
{'metavar': '<file[,file,...]>', 'overrides': 'stylesheet',
|
||||||
|
'validator': frontend.validate_comma_separated_list,
|
||||||
|
'default': default_stylesheets}),
|
||||||
|
('Embed the stylesheet(s) in the output HTML file. The stylesheet '
|
||||||
|
'files must be accessible during processing. This is the default.',
|
||||||
|
['--embed-stylesheet'],
|
||||||
|
{'default': 1, 'action': 'store_true',
|
||||||
|
'validator': frontend.validate_boolean}),
|
||||||
|
('Link to the stylesheet(s) in the output HTML file. '
|
||||||
|
'Default: embed stylesheets.',
|
||||||
|
['--link-stylesheet'],
|
||||||
|
{'dest': 'embed_stylesheet', 'action': 'store_false'}),
|
||||||
|
('Comma-separated list of directories where stylesheets are found. '
|
||||||
|
'Used by --stylesheet-path when expanding relative path arguments. '
|
||||||
|
'Default: "%s"' % default_stylesheet_dirs,
|
||||||
|
['--stylesheet-dirs'],
|
||||||
|
{'metavar': '<dir[,dir,...]>',
|
||||||
|
'validator': frontend.validate_comma_separated_list,
|
||||||
|
'default': default_stylesheet_dirs}),
|
||||||
|
('Specify the initial header level. Default is 1 for "<h1>". '
|
||||||
|
'Does not affect document title & subtitle (see --no-doc-title).',
|
||||||
|
['--initial-header-level'],
|
||||||
|
{'choices': '1 2 3 4 5 6'.split(), 'default': '1',
|
||||||
|
'metavar': '<level>'}),
|
||||||
|
('Format for footnote references: one of "superscript" or '
|
||||||
|
'"brackets". Default is "brackets".',
|
||||||
|
['--footnote-references'],
|
||||||
|
{'choices': ['superscript', 'brackets'], 'default': 'brackets',
|
||||||
|
'metavar': '<format>',
|
||||||
|
'overrides': 'trim_footnote_reference_space'}),
|
||||||
|
('Format for block quote attributions: one of "dash" (em-dash '
|
||||||
|
'prefix), "parentheses"/"parens", or "none". Default is "dash".',
|
||||||
|
['--attribution'],
|
||||||
|
{'choices': ['dash', 'parentheses', 'parens', 'none'],
|
||||||
|
'default': 'dash', 'metavar': '<format>'}),
|
||||||
|
('Remove extra vertical whitespace between items of "simple" bullet '
|
||||||
|
'lists and enumerated lists. Default: enabled.',
|
||||||
|
['--compact-lists'],
|
||||||
|
{'default': True, 'action': 'store_true',
|
||||||
|
'validator': frontend.validate_boolean}),
|
||||||
|
('Disable compact simple bullet and enumerated lists.',
|
||||||
|
['--no-compact-lists'],
|
||||||
|
{'dest': 'compact_lists', 'action': 'store_false'}),
|
||||||
|
('Remove extra vertical whitespace between items of simple field '
|
||||||
|
'lists. Default: enabled.',
|
||||||
|
['--compact-field-lists'],
|
||||||
|
{'default': True, 'action': 'store_true',
|
||||||
|
'validator': frontend.validate_boolean}),
|
||||||
|
('Disable compact simple field lists.',
|
||||||
|
['--no-compact-field-lists'],
|
||||||
|
{'dest': 'compact_field_lists', 'action': 'store_false'}),
|
||||||
|
('Added to standard table classes. '
|
||||||
|
'Defined styles: borderless, booktabs, '
|
||||||
|
'align-left, align-center, align-right, colwidths-auto. '
|
||||||
|
'Default: ""',
|
||||||
|
['--table-style'],
|
||||||
|
{'default': ''}),
|
||||||
|
('Math output format (one of "MathML", "HTML", "MathJax", '
|
||||||
|
'or "LaTeX") and option(s). '
|
||||||
|
'Default: "HTML math.css"',
|
||||||
|
['--math-output'],
|
||||||
|
{'default': 'HTML math.css'}),
|
||||||
|
('Prepend an XML declaration. (Thwarts HTML5 conformance.) '
|
||||||
|
'Default: False',
|
||||||
|
['--xml-declaration'],
|
||||||
|
{'default': False, 'action': 'store_true',
|
||||||
|
'validator': frontend.validate_boolean}),
|
||||||
|
('Omit the XML declaration.',
|
||||||
|
['--no-xml-declaration'],
|
||||||
|
{'dest': 'xml_declaration', 'action': 'store_false'}),
|
||||||
|
('Obfuscate email addresses to confuse harvesters while still '
|
||||||
|
'keeping email links usable with standards-compliant browsers.',
|
||||||
|
['--cloak-email-addresses'],
|
||||||
|
{'action': 'store_true', 'validator': frontend.validate_boolean}),))
|
||||||
|
|
||||||
|
config_section = 'html5 writer'
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.parts = {}
|
||||||
|
self.translator_class = HTMLTranslator
|
||||||
|
|
||||||
|
|
||||||
|
class HTMLTranslator(writers._html_base.HTMLTranslator):
|
||||||
|
"""
|
||||||
|
This writer generates `polyglot markup`: HTML5 that is also valid XML.
|
||||||
|
|
||||||
|
Safe subclassing: when overriding, treat ``visit_*`` and ``depart_*``
|
||||||
|
methods as a unit to prevent breaks due to internal changes. See the
|
||||||
|
docstring of docutils.writers._html_base.HTMLTranslator for details
|
||||||
|
and examples.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# <acronym> tag not supported in HTML5. Use the <abbr> tag instead.
|
||||||
|
def visit_acronym(self, node):
|
||||||
|
# @@@ implementation incomplete ("title" attribute)
|
||||||
|
self.body.append(self.starttag(node, 'abbr', ''))
|
||||||
|
def depart_acronym(self, node):
|
||||||
|
self.body.append('</abbr>')
|
||||||
|
|
||||||
|
# no meta tag in HTML5
|
||||||
|
def visit_authors(self, node):
|
||||||
|
self.visit_docinfo_item(node, 'authors', meta=False)
|
||||||
|
def depart_authors(self, node):
|
||||||
|
self.depart_docinfo_item()
|
||||||
|
|
||||||
|
# no meta tag in HTML5
|
||||||
|
def visit_copyright(self, node):
|
||||||
|
self.visit_docinfo_item(node, 'copyright', meta=False)
|
||||||
|
def depart_copyright(self, node):
|
||||||
|
self.depart_docinfo_item()
|
||||||
|
|
||||||
|
# no meta tag in HTML5
|
||||||
|
def visit_date(self, node):
|
||||||
|
self.visit_docinfo_item(node, 'date', meta=False)
|
||||||
|
def depart_date(self, node):
|
||||||
|
self.depart_docinfo_item()
|
||||||
|
|
||||||
|
# TODO: use HTML5 <footer> element?
|
||||||
|
# def visit_footer(self, node):
|
||||||
|
# def depart_footer(self, node):
|
||||||
|
|
||||||
|
# TODO: use the new HTML5 element <aside>? (Also for footnote text)
|
||||||
|
# def visit_footnote(self, node):
|
||||||
|
# def depart_footnote(self, node):
|
||||||
|
|
||||||
|
# Meta tags: 'lang' attribute replaced by 'xml:lang' in XHTML 1.1
|
||||||
|
# HTML5/polyglot recommends using both
|
||||||
|
def visit_meta(self, node):
|
||||||
|
if node.hasattr('lang'):
|
||||||
|
node['xml:lang'] = node['lang']
|
||||||
|
# del(node['lang'])
|
||||||
|
meta = self.emptytag(node, 'meta', **node.non_default_attributes())
|
||||||
|
self.add_meta(meta)
|
||||||
|
def depart_meta(self, node):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# no meta tag in HTML5
|
||||||
|
def visit_organization(self, node):
|
||||||
|
self.visit_docinfo_item(node, 'organization', meta=False)
|
||||||
|
def depart_organization(self, node):
|
||||||
|
self.depart_docinfo_item()
|
||||||
|
|
||||||
|
# TODO: use the new HTML5 element <section>?
|
||||||
|
# def visit_section(self, node):
|
||||||
|
# def depart_section(self, node):
|
||||||
|
|
||||||
|
# TODO: use the new HTML5 element <aside>?
|
||||||
|
# def visit_topic(self, node):
|
||||||
|
# def depart_topic(self, node):
|
260
Libs/docutils/writers/html5_polyglot/minimal.css
Normal file
260
Libs/docutils/writers/html5_polyglot/minimal.css
Normal file
|
@ -0,0 +1,260 @@
|
||||||
|
/* Minimal style sheet for the HTML output of Docutils. */
|
||||||
|
/* */
|
||||||
|
/* :Author: Günter Milde, based on html4css1.css by David Goodger */
|
||||||
|
/* :Id: $Id: minimal.css 8036 2017-02-14 13:05:46Z milde $ */
|
||||||
|
/* :Copyright: © 2015 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 */
|
||||||
|
|
||||||
|
/* This CSS2.1_ stylesheet defines rules for Docutils elements without */
|
||||||
|
/* HTML equivalent. It is required to make the document semantic visible. */
|
||||||
|
/* */
|
||||||
|
/* .. _CSS2.1: http://www.w3.org/TR/CSS2 */
|
||||||
|
/* .. _validates: http://jigsaw.w3.org/css-validator/validator$link */
|
||||||
|
|
||||||
|
/* alignment of text and inline objects inside block objects*/
|
||||||
|
.align-left { text-align: left; }
|
||||||
|
.align-right { text-align: right; }
|
||||||
|
.align-center { clear: both; text-align: center; }
|
||||||
|
.align-top { vertical-align: top; }
|
||||||
|
.align-middle { vertical-align: middle; }
|
||||||
|
.align-bottom { vertical-align: bottom; }
|
||||||
|
|
||||||
|
/* titles */
|
||||||
|
h1.title, p.subtitle {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
p.admonition-title,
|
||||||
|
p.topic-title,
|
||||||
|
p.sidebar-title,
|
||||||
|
p.rubric,
|
||||||
|
p.system-message-title {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
h1 + p.subtitle,
|
||||||
|
h1 + p.section-subtitle {
|
||||||
|
font-size: 1.6em;
|
||||||
|
}
|
||||||
|
h2 + p.section-subtitle { font-size: 1.28em; }
|
||||||
|
p.subtitle,
|
||||||
|
p.section-subtitle,
|
||||||
|
p.sidebar-subtitle {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: -0.5em;
|
||||||
|
}
|
||||||
|
p.sidebar-title,
|
||||||
|
p.rubric {
|
||||||
|
font-size: larger;
|
||||||
|
}
|
||||||
|
p.rubric { color: maroon; }
|
||||||
|
a.toc-backref {
|
||||||
|
color: black;
|
||||||
|
text-decoration: none; }
|
||||||
|
|
||||||
|
/* Warnings, Errors */
|
||||||
|
div.caution p.admonition-title,
|
||||||
|
div.attention p.admonition-title,
|
||||||
|
div.danger p.admonition-title,
|
||||||
|
div.error p.admonition-title,
|
||||||
|
div.warning p.admonition-title,
|
||||||
|
div.system-messages h1,
|
||||||
|
div.error,
|
||||||
|
span.problematic,
|
||||||
|
p.system-message-title {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* inline literals */
|
||||||
|
span.docutils.literal {
|
||||||
|
font-family: monospace;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
/* do not wraph at hyphens and similar: */
|
||||||
|
.literal > span.pre { white-space: nowrap; }
|
||||||
|
|
||||||
|
/* Lists */
|
||||||
|
|
||||||
|
/* compact and simple lists: no margin between items */
|
||||||
|
.simple li, .compact li,
|
||||||
|
.simple ul, .compact ul,
|
||||||
|
.simple ol, .compact ol,
|
||||||
|
.simple > li p, .compact > li p,
|
||||||
|
dl.simple > dd, dl.compact > dd {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Table of Contents */
|
||||||
|
div.topic.contents { margin: 0; }
|
||||||
|
ul.auto-toc {
|
||||||
|
list-style-type: none;
|
||||||
|
padding-left: 1.5em; }
|
||||||
|
|
||||||
|
/* Enumerated Lists */
|
||||||
|
ol.arabic { list-style: decimal }
|
||||||
|
ol.loweralpha { list-style: lower-alpha }
|
||||||
|
ol.upperalpha { list-style: upper-alpha }
|
||||||
|
ol.lowerroman { list-style: lower-roman }
|
||||||
|
ol.upperroman { list-style: upper-roman }
|
||||||
|
|
||||||
|
dt span.classifier { font-style: italic }
|
||||||
|
dt span.classifier:before {
|
||||||
|
font-style: normal;
|
||||||
|
margin: 0.5em;
|
||||||
|
content: ":";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Field Lists and drivatives */
|
||||||
|
/* bold field name, content starts on the same line */
|
||||||
|
dl.field-list > dt,
|
||||||
|
dl.option-list > dt,
|
||||||
|
dl.docinfo > dt,
|
||||||
|
dl.footnote > dt,
|
||||||
|
dl.citation > dt {
|
||||||
|
font-weight: bold;
|
||||||
|
clear: left;
|
||||||
|
float: left;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
padding-right: 0.5em;
|
||||||
|
}
|
||||||
|
/* Offset for field content (corresponds to the --field-name-limit option) */
|
||||||
|
dl.field-list > dd,
|
||||||
|
dl.option-list > dd,
|
||||||
|
dl.docinfo > dd {
|
||||||
|
margin-left: 9em; /* ca. 14 chars in the test examples */
|
||||||
|
}
|
||||||
|
/* start field-body on a new line after long field names */
|
||||||
|
dl.field-list > dd > *:first-child,
|
||||||
|
dl.option-list > dd > *:first-child
|
||||||
|
{
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
/* field names followed by a colon */
|
||||||
|
dl.field-list > dt:after,
|
||||||
|
dl.docinfo > dt:after {
|
||||||
|
content: ":";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bibliographic Fields (docinfo) */
|
||||||
|
pre.address { font: inherit; }
|
||||||
|
dd.authors > p { margin: 0; }
|
||||||
|
|
||||||
|
/* Option Lists */
|
||||||
|
dl.option-list { margin-left: 40px; }
|
||||||
|
dl.option-list > dt { font-weight: normal; }
|
||||||
|
span.option { white-space: nowrap; }
|
||||||
|
|
||||||
|
/* Footnotes and Citations */
|
||||||
|
dl.footnote.superscript > dd {margin-left: 1em; }
|
||||||
|
dl.footnote.brackets > dd {margin-left: 2em; }
|
||||||
|
dl > dt.label { font-weight: normal; }
|
||||||
|
a.footnote-reference.brackets:before,
|
||||||
|
dt.label > span.brackets:before { content: "["; }
|
||||||
|
a.footnote-reference.brackets:after,
|
||||||
|
dt.label > span.brackets:after { content: "]"; }
|
||||||
|
a.footnote-reference.superscript,
|
||||||
|
dl.footnote.superscript > dt.label {
|
||||||
|
vertical-align: super;
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
||||||
|
dt.label > span.fn-backref { margin-left: 0.2em; }
|
||||||
|
dt.label > span.fn-backref > a { font-style: italic; }
|
||||||
|
|
||||||
|
/* Line Blocks */
|
||||||
|
div.line-block { display: block; }
|
||||||
|
div.line-block div.line-block {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-left: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Figures, Images, and Tables */
|
||||||
|
.figure.align-left,
|
||||||
|
img.align-left,
|
||||||
|
object.align-left,
|
||||||
|
table.align-left {
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
.figure.align-center,
|
||||||
|
img.align-center,
|
||||||
|
object.align-center {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
table.align-center {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
.figure.align-right,
|
||||||
|
img.align-right,
|
||||||
|
object.align-right,
|
||||||
|
table.align-right {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
/* reset inner alignment in figures and tables */
|
||||||
|
/* div.align-left, div.align-center, div.align-right, */
|
||||||
|
table.align-left, table.align-center, table.align-right
|
||||||
|
{ text-align: inherit }
|
||||||
|
|
||||||
|
/* Admonitions and System Messages */
|
||||||
|
div.admonition,
|
||||||
|
div.system-message,
|
||||||
|
div.sidebar{
|
||||||
|
margin: 40px;
|
||||||
|
border: medium outset;
|
||||||
|
padding-right: 1em;
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sidebar */
|
||||||
|
div.sidebar {
|
||||||
|
width: 30%;
|
||||||
|
max-width: 26em;
|
||||||
|
float: right;
|
||||||
|
clear: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text Blocks */
|
||||||
|
div.topic,
|
||||||
|
pre.literal-block,
|
||||||
|
pre.doctest-block,
|
||||||
|
pre.math,
|
||||||
|
pre.code {
|
||||||
|
margin-right: 40px;
|
||||||
|
margin-left: 40px;
|
||||||
|
}
|
||||||
|
pre.code .ln { color: gray; } /* line numbers */
|
||||||
|
|
||||||
|
/* Tables */
|
||||||
|
table { border-collapse: collapse; }
|
||||||
|
td, th {
|
||||||
|
border-style: solid;
|
||||||
|
border-color: silver;
|
||||||
|
padding: 0 1ex;
|
||||||
|
border-width: thin;
|
||||||
|
}
|
||||||
|
td > p:first-child, th > p:first-child { margin-top: 0; }
|
||||||
|
td > p, th > p { margin-bottom: 0; }
|
||||||
|
|
||||||
|
table > caption {
|
||||||
|
text-align: left;
|
||||||
|
margin-bottom: 0.25em
|
||||||
|
}
|
||||||
|
|
||||||
|
table.borderless td, table.borderless th {
|
||||||
|
border: 0;
|
||||||
|
padding: 0;
|
||||||
|
padding-right: 0.5em /* separate table cells */
|
||||||
|
}
|
288
Libs/docutils/writers/html5_polyglot/plain.css
Normal file
288
Libs/docutils/writers/html5_polyglot/plain.css
Normal file
|
@ -0,0 +1,288 @@
|
||||||
|
/* CSS31_ style sheet for the output of Docutils HTML writers. */
|
||||||
|
/* Rules for easy reading and pre-defined style variants. */
|
||||||
|
/* */
|
||||||
|
/* :Author: Günter Milde, based on html4css1.css by David Goodger */
|
||||||
|
/* :Id: $Id: plain.css 8120 2017-06-22 21:02:40Z milde $ */
|
||||||
|
/* :Copyright: © 2015 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 */
|
||||||
|
/* .. _CSS3: http://www.w3.org/TR/CSS3 */
|
||||||
|
|
||||||
|
|
||||||
|
/* Document Structure */
|
||||||
|
/* ****************** */
|
||||||
|
|
||||||
|
/* "page layout" */
|
||||||
|
body {
|
||||||
|
padding: 0 5%;
|
||||||
|
margin: 8px 0;
|
||||||
|
}
|
||||||
|
div.document {
|
||||||
|
line-height:1.3;
|
||||||
|
counter-reset: table;
|
||||||
|
/* counter-reset: figure; */
|
||||||
|
/* avoid long lines --> better reading */
|
||||||
|
/* OTOH: lines should not be too short because of missing hyphenation, */
|
||||||
|
max-width: 50em;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sections */
|
||||||
|
|
||||||
|
/* Transitions */
|
||||||
|
|
||||||
|
hr.docutils {
|
||||||
|
width: 80%;
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Paragraphs */
|
||||||
|
/* ========== */
|
||||||
|
|
||||||
|
/* vertical space (parskip) */
|
||||||
|
p, ol, ul, dl,
|
||||||
|
div.line-block,
|
||||||
|
table{
|
||||||
|
margin-top: 0.5em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
h1, h2, h3, h4, h5, h6,
|
||||||
|
dl > dd {
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lists */
|
||||||
|
/* ========== */
|
||||||
|
|
||||||
|
/* Definition Lists */
|
||||||
|
|
||||||
|
dl > dd > p:first-child { margin-top: 0; }
|
||||||
|
/* :last-child is not part of CSS 2.1 (introduced in CSS 3) */
|
||||||
|
dl > dd > p:last-child { margin-bottom: 0; }
|
||||||
|
|
||||||
|
/* lists nested in definition lists */
|
||||||
|
/* :only-child is not part of CSS 2.1 (introduced in CSS 3) */
|
||||||
|
dd > ul:only-child, dd > ol:only-child { padding-left: 1em; }
|
||||||
|
|
||||||
|
/* Description Lists */
|
||||||
|
/* styled like in most dictionaries, encyclopedias etc. */
|
||||||
|
dl.description > dt {
|
||||||
|
font-weight: bold;
|
||||||
|
clear: left;
|
||||||
|
float: left;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
padding-right: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Field Lists */
|
||||||
|
|
||||||
|
/* example for custom field-name width */
|
||||||
|
dl.field-list.narrow > dd {
|
||||||
|
margin-left: 5em;
|
||||||
|
}
|
||||||
|
/* run-in: start field-body on same line after long field names */
|
||||||
|
dl.field-list.run-in > dd p {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bibliographic Fields */
|
||||||
|
|
||||||
|
/* generally, bibliographic fields use special definition list dl.docinfo */
|
||||||
|
/* but dedication and abstract are placed into "topic" divs */
|
||||||
|
div.abstract p.topic-title {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
div.dedication {
|
||||||
|
margin: 2em 5em;
|
||||||
|
text-align: center;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
div.dedication p.topic-title {
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Citations */
|
||||||
|
dl.citation dt.label {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
span.fn-backref {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text Blocks */
|
||||||
|
/* ============ */
|
||||||
|
|
||||||
|
/* Literal Blocks */
|
||||||
|
pre.literal-block, pre.doctest-block,
|
||||||
|
pre.math, pre.code {
|
||||||
|
margin-left: 1.5em;
|
||||||
|
margin-right: 1.5em
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Block Quotes */
|
||||||
|
|
||||||
|
blockquote,
|
||||||
|
div.topic {
|
||||||
|
margin-left: 1.5em;
|
||||||
|
margin-right: 1.5em
|
||||||
|
}
|
||||||
|
blockquote > table,
|
||||||
|
div.topic > table {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
blockquote p.attribution,
|
||||||
|
div.topic p.attribution {
|
||||||
|
text-align: right;
|
||||||
|
margin-left: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tables */
|
||||||
|
/* ====== */
|
||||||
|
|
||||||
|
/* th { vertical-align: bottom; } */
|
||||||
|
|
||||||
|
table tr { text-align: left; }
|
||||||
|
|
||||||
|
/* "booktabs" style (no vertical lines) */
|
||||||
|
table.booktabs {
|
||||||
|
border: 0;
|
||||||
|
border-top: 2px solid;
|
||||||
|
border-bottom: 2px solid;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
table.booktabs * {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
table.booktabs th {
|
||||||
|
border-bottom: thin solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* numbered tables (counter defined in div.document) */
|
||||||
|
table.numbered > caption:before {
|
||||||
|
counter-increment: table;
|
||||||
|
content: "Table " counter(table) ": ";
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Explicit Markup Blocks */
|
||||||
|
/* ====================== */
|
||||||
|
|
||||||
|
/* Footnotes and Citations */
|
||||||
|
/* ----------------------- */
|
||||||
|
|
||||||
|
/* line on the left */
|
||||||
|
dl.footnote {
|
||||||
|
padding-left: 1ex;
|
||||||
|
border-left: solid;
|
||||||
|
border-left-width: thin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Directives */
|
||||||
|
/* ---------- */
|
||||||
|
|
||||||
|
/* Body Elements */
|
||||||
|
/* ~~~~~~~~~~~~~ */
|
||||||
|
|
||||||
|
/* Images and Figures */
|
||||||
|
|
||||||
|
/* let content flow to the side of aligned images and figures */
|
||||||
|
.figure.align-left,
|
||||||
|
img.align-left,
|
||||||
|
object.align-left {
|
||||||
|
display: block;
|
||||||
|
clear: left;
|
||||||
|
float: left;
|
||||||
|
margin-right: 1em
|
||||||
|
}
|
||||||
|
.figure.align-right,
|
||||||
|
img.align-right,
|
||||||
|
object.align-right {
|
||||||
|
display: block;
|
||||||
|
clear: right;
|
||||||
|
float: right;
|
||||||
|
margin-left: 1em
|
||||||
|
}
|
||||||
|
/* Stop floating sidebars, images and figures at section level 1,2,3 */
|
||||||
|
h1, h2, h3 { clear: both; }
|
||||||
|
|
||||||
|
/* Sidebar */
|
||||||
|
|
||||||
|
/* Move into the margin. In a layout with fixed margins, */
|
||||||
|
/* it can be moved into the margin completely. */
|
||||||
|
div.sidebar {
|
||||||
|
width: 30%;
|
||||||
|
max-width: 26em;
|
||||||
|
margin-left: 1em;
|
||||||
|
margin-right: -5.5%;
|
||||||
|
background-color: #ffffee ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Code */
|
||||||
|
|
||||||
|
pre.code, code { background-color: #eeeeee }
|
||||||
|
pre.code .ln { color: gray; } /* line numbers */
|
||||||
|
/* basic highlighting: for a complete scheme, see */
|
||||||
|
/* http://docutils.sourceforge.net/sandbox/stylesheets/ */
|
||||||
|
pre.code .comment, code .comment { color: #5C6576 }
|
||||||
|
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
|
||||||
|
pre.code .literal.string, code .literal.string { color: #0C5404 }
|
||||||
|
pre.code .name.builtin, code .name.builtin { color: #352B84 }
|
||||||
|
pre.code .deleted, code .deleted { background-color: #DEB0A1}
|
||||||
|
pre.code .inserted, code .inserted { background-color: #A3D289}
|
||||||
|
|
||||||
|
/* Math */
|
||||||
|
/* styled separately (see math.css for math-output=HTML) */
|
||||||
|
|
||||||
|
/* Epigraph */
|
||||||
|
/* Highlights */
|
||||||
|
/* Pull-Quote */
|
||||||
|
/* Compound Paragraph */
|
||||||
|
/* Container */
|
||||||
|
|
||||||
|
/* can be styled in a custom stylesheet */
|
||||||
|
|
||||||
|
/* Document Header and Footer */
|
||||||
|
|
||||||
|
div.footer, div.header {
|
||||||
|
clear: both;
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inline Markup */
|
||||||
|
/* ============= */
|
||||||
|
|
||||||
|
/* Emphasis */
|
||||||
|
/* em */
|
||||||
|
/* Strong Emphasis */
|
||||||
|
/* strong */
|
||||||
|
/* Interpreted Text */
|
||||||
|
/* span.interpreted */
|
||||||
|
/* Title Reference */
|
||||||
|
/* cite */
|
||||||
|
/* Inline Literals */
|
||||||
|
/* possible values: normal, nowrap, pre, pre-wrap, pre-line */
|
||||||
|
/* span.docutils.literal { white-space: pre-wrap; } */
|
||||||
|
|
||||||
|
/* Hyperlink References */
|
||||||
|
a { text-decoration: none; }
|
||||||
|
|
||||||
|
/* External Targets */
|
||||||
|
/* span.target.external */
|
||||||
|
/* Internal Targets */
|
||||||
|
/* span.target.internal */
|
||||||
|
/* Footnote References */
|
||||||
|
/* a.footnote-reference */
|
||||||
|
/* Citation References */
|
||||||
|
/* a.citation-reference */
|
8
Libs/docutils/writers/html5_polyglot/template.txt
Normal file
8
Libs/docutils/writers/html5_polyglot/template.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
%(head_prefix)s
|
||||||
|
%(head)s
|
||||||
|
%(stylesheet)s
|
||||||
|
%(body_prefix)s
|
||||||
|
%(body_pre_docinfo)s
|
||||||
|
%(docinfo)s
|
||||||
|
%(body)s
|
||||||
|
%(body_suffix)s
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,4 @@
|
||||||
$head_prefix% generated by Docutils <http://docutils.sourceforge.net/>
|
$head_prefix% generated by Docutils <http://docutils.sourceforge.net/>
|
||||||
\usepackage{fixltx2e} % LaTeX patches, \textsubscript
|
|
||||||
\usepackage{cmap} % fix search and cut-and-paste in Acrobat
|
\usepackage{cmap} % fix search and cut-and-paste in Acrobat
|
||||||
$requirements
|
$requirements
|
||||||
%%% Custom LaTeX preamble
|
%%% Custom LaTeX preamble
|
||||||
|
|
738
Libs/docutils/writers/latex2e/docutils-05-compat.sty
Normal file
738
Libs/docutils/writers/latex2e/docutils-05-compat.sty
Normal file
|
@ -0,0 +1,738 @@
|
||||||
|
% ==================================================================
|
||||||
|
% Changes to the Docutils latex2e writer since version 0.5
|
||||||
|
% ==================================================================
|
||||||
|
%
|
||||||
|
% A backwards compatibility style sheet
|
||||||
|
% *************************************
|
||||||
|
%
|
||||||
|
% :Author: Guenter Milde
|
||||||
|
% :Contact: milde@users.sourceforge.net
|
||||||
|
% :Revision: $Revision: 6156 $
|
||||||
|
% :Date: $Date: 2009-02-24 $
|
||||||
|
% :Copyright: © 2009 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.
|
||||||
|
%
|
||||||
|
% :Abstract: This file documents changes and provides a style for best
|
||||||
|
% possible compatibility to the behaviour of the `latex2e`
|
||||||
|
% writer of Doctutils release 0.5.
|
||||||
|
%
|
||||||
|
% .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause
|
||||||
|
%
|
||||||
|
% ::
|
||||||
|
|
||||||
|
\NeedsTeXFormat{LaTeX2e}
|
||||||
|
\ProvidesPackage{docutils-05-compat}
|
||||||
|
[2009/03/26 v0.1 compatibility with rst2latex from Docutils 0.5]
|
||||||
|
|
||||||
|
% .. contents::
|
||||||
|
% :depth: 3
|
||||||
|
%
|
||||||
|
% Usage
|
||||||
|
% =====
|
||||||
|
%
|
||||||
|
% * To get an (almost) identic look for your old documents,
|
||||||
|
% place ``docutils-05-compat.sty`` in the TEXINPUT path (e.g.
|
||||||
|
% the current work directory) and pass the
|
||||||
|
% ``--stylesheet=docutils-05-compat`` option to ``rst2latex.py``.
|
||||||
|
%
|
||||||
|
% * To use your custom stylesheets without change, add them to the
|
||||||
|
% compatibility style, e.g.
|
||||||
|
% ``--stylesheet="docutils-05-compat,mystyle.tex``.
|
||||||
|
%
|
||||||
|
% .. tip:: As the changes include bug fixes that are partly reverted by this
|
||||||
|
% style, it is recommended to adapt the stylesheets to the new version or
|
||||||
|
% copy just the relevant parts of this style into them.
|
||||||
|
%
|
||||||
|
% Changes since 0.5
|
||||||
|
% =================
|
||||||
|
%
|
||||||
|
% Bugfixes
|
||||||
|
% --------
|
||||||
|
%
|
||||||
|
% * Newlines around comments, targets and references prevent run-together
|
||||||
|
% paragraphs.
|
||||||
|
%
|
||||||
|
% + An image directive with hyperlink reference or target did not start a
|
||||||
|
% new paragraph (e.g. the first two image examples in
|
||||||
|
% standalone_rst_latex.tex).
|
||||||
|
%
|
||||||
|
% + Paragraphs were not separated if there was a (hyper) target definition
|
||||||
|
% inbetween.
|
||||||
|
%
|
||||||
|
% + Paragraphs did run together, if separated by a comment-paragraph in the
|
||||||
|
% rst source.
|
||||||
|
%
|
||||||
|
% * Fixed missing and spurious internal links/targets.
|
||||||
|
% Internal links now take you to the correct place.
|
||||||
|
%
|
||||||
|
% * Verbose and linked system messages.
|
||||||
|
%
|
||||||
|
% * `Figure and image alignment`_ now conforms to the rst definition.
|
||||||
|
%
|
||||||
|
% * Put `header and footer directive`__ content in \DUheader respective
|
||||||
|
% \DUfooter macros (ignored by the default style/template).
|
||||||
|
%
|
||||||
|
% (They were put inside hard-coded markup at the top/bottom of the document
|
||||||
|
% without an option to get them on every page.)
|
||||||
|
%
|
||||||
|
% __ ../ref/rst/directives.html#document-header-footer
|
||||||
|
%
|
||||||
|
% * Render doctest blocks as literal blocks (fixes bug [1586058] doctest block
|
||||||
|
% nested in admonition). I.e.
|
||||||
|
%
|
||||||
|
% + indent doctest blocks by nesting in a quote environment. This is also
|
||||||
|
% the rendering by the HTML writer (html4css2.css).
|
||||||
|
% + apply the ``--literal-block-env`` setting also to doctest blocks.
|
||||||
|
%
|
||||||
|
% .. warning::
|
||||||
|
% (``--literal-block-env=verbatim`` and
|
||||||
|
% ``--literal-block-env=lstlistings`` fail with literal or doctest
|
||||||
|
% blocks nested in an admonition.
|
||||||
|
%
|
||||||
|
% * Two-way hyperlinked footnotes and support for symbol footnotes and
|
||||||
|
% ``--footnote-references=brackets`` with ``--use-latex-footnotes``.
|
||||||
|
%
|
||||||
|
% * The packages `fixltx2e` (providing LaTeX patches and the \textsubscript
|
||||||
|
% command) and `cmap` (including character maps in the generated PDF for
|
||||||
|
% better search and copy-and-paste operations) are now always loaded
|
||||||
|
% (configurable with custom templates_).
|
||||||
|
%
|
||||||
|
% Backwards compatibility:
|
||||||
|
% "Bug for bug compatibility" is not provided.
|
||||||
|
%
|
||||||
|
%
|
||||||
|
% New configuration setting defaults
|
||||||
|
% ----------------------------------
|
||||||
|
%
|
||||||
|
% - font-encoding: "T1" (formerly implicitely set by 'ae').
|
||||||
|
% - use-latex-toc: true (ToC with page numbers).
|
||||||
|
% - use-latex-footnotes: true (no mixup with figures).
|
||||||
|
%
|
||||||
|
% Backwards compatibility:
|
||||||
|
% Reset to the former defaults with:
|
||||||
|
%
|
||||||
|
% | font-encoding: ''
|
||||||
|
% | use-latex-toc: False
|
||||||
|
% | use-latex-footnotes: False
|
||||||
|
%
|
||||||
|
% (in the config file) or the command line options:
|
||||||
|
%
|
||||||
|
% ``--figure-footnotes --use-docutils-toc --font-encoding=''``
|
||||||
|
%
|
||||||
|
%
|
||||||
|
% Cleaner LaTeX source
|
||||||
|
% --------------------
|
||||||
|
%
|
||||||
|
% New features:
|
||||||
|
% * Remove redundant "double protection" from the encoding of the "special
|
||||||
|
% printing characters" and square brackets, e.g. ``\%`` instead of
|
||||||
|
% ``{\%}``.
|
||||||
|
% * Remove some spurious whitespace, e.g. ``\item [what:] -> \item[what:]``.
|
||||||
|
% * Use conventional style for "named" macros, e.g. ``\dots{}`` instead of
|
||||||
|
% ``{\dots}``
|
||||||
|
%
|
||||||
|
% Backwards compatibility:
|
||||||
|
% Changes do not affect the output.
|
||||||
|
%
|
||||||
|
%
|
||||||
|
% LaTeX style sheets
|
||||||
|
% ------------------
|
||||||
|
%
|
||||||
|
% New Feature:
|
||||||
|
% LaTeX packages can be used as ``--stylesheet`` argument without
|
||||||
|
% restriction.
|
||||||
|
%
|
||||||
|
% Implementation:
|
||||||
|
% Use ``\usepackage`` if style sheet ends with ``.sty`` or has no
|
||||||
|
% extension and ``\input`` else.
|
||||||
|
%
|
||||||
|
% Rationale:
|
||||||
|
% while ``\input`` works with extension as well as without extension,
|
||||||
|
% ``\usepackage`` expects the package name without extension. (The latex2e
|
||||||
|
% writer will strip a ``.sty`` extension.)
|
||||||
|
%
|
||||||
|
%
|
||||||
|
% Backwards compatibility:
|
||||||
|
% Up to Docutils 0.5, if no filename extension is given in the
|
||||||
|
% ``stylesheet`` argument, ``.tex`` is assumed (by latex).
|
||||||
|
%
|
||||||
|
% Since Docutils 0.6, a stylesheet without filename extension is assumed to
|
||||||
|
% be a LaTeX package (``*.sty``) and referenced with the ``\usepackage``
|
||||||
|
% command.
|
||||||
|
%
|
||||||
|
% .. important::
|
||||||
|
% Always specify the extension if you want the style sheet to be
|
||||||
|
% ``\input`` by LaTeX.
|
||||||
|
%
|
||||||
|
%
|
||||||
|
% Templates
|
||||||
|
% ---------
|
||||||
|
%
|
||||||
|
% New Feature:
|
||||||
|
% Advanced configuration via custom templates.
|
||||||
|
%
|
||||||
|
% Implementation:
|
||||||
|
% A ``--template`` option and config setting allows specification of a
|
||||||
|
% template file.
|
||||||
|
%
|
||||||
|
% See the `LaTeX writer documentation`__ for details.
|
||||||
|
%
|
||||||
|
% __ latex.html#templates
|
||||||
|
%
|
||||||
|
%
|
||||||
|
% Custom roles
|
||||||
|
% ------------
|
||||||
|
%
|
||||||
|
% New Feature: failsave implementation
|
||||||
|
% As with classes to HTML objects, class arguments are silently ignored if
|
||||||
|
% there is no styling rule for this class in a custom style sheet.
|
||||||
|
%
|
||||||
|
% New Feature: custom roles based on standard roles
|
||||||
|
% As class support needs to be handled by the LaTeX writer, this feature was
|
||||||
|
% not present "automatically" (as in HTML). Modified visit/depart_*()
|
||||||
|
% methods for the standard roles now call visit/depart_inline() if there are
|
||||||
|
% class arguments to the node.
|
||||||
|
%
|
||||||
|
% Backwards compatibility:
|
||||||
|
% The implementation is fully backwards compatible. (SVN versions 5742 to
|
||||||
|
% 5861 contained an implementation that did not work with commands expecting
|
||||||
|
% an argument.)
|
||||||
|
%
|
||||||
|
% Length units
|
||||||
|
% ------------
|
||||||
|
%
|
||||||
|
% New Features:
|
||||||
|
% 1. Add default unit if none given.
|
||||||
|
% A poll on docutils-users favoured ``bp`` (Big Point: 1 bp = 1/72 in).
|
||||||
|
%
|
||||||
|
% 2. Do not change ``px`` to ``pt``.
|
||||||
|
%
|
||||||
|
% 3. Lengths specified in the document with unit "pt" will be written with
|
||||||
|
% unit "bp" to the LaTeX source.
|
||||||
|
%
|
||||||
|
% Rationale:
|
||||||
|
% 1. prevent LaTeX error "missing unit".
|
||||||
|
%
|
||||||
|
% 2. ``px`` is a valid unit in pdftex since version 1.3.0 released on
|
||||||
|
% 2005-02-04:
|
||||||
|
%
|
||||||
|
% 1px defaults to 1bp (or 72dpi), but can be changed with the
|
||||||
|
% ``\pdfpxdimen`` primitive.::
|
||||||
|
|
||||||
|
\pdfpxdimen=1in % 1 dpi
|
||||||
|
\divide\pdfpxdimen by 96 % 96 dpi
|
||||||
|
|
||||||
|
% -- http://www.tug.org/applications/pdftex/NEWS
|
||||||
|
%
|
||||||
|
% Modern TeX distributions use pdftex also for dvi generation (i.e.
|
||||||
|
% ``latex`` actually calls ``pdftex`` with some options).
|
||||||
|
%
|
||||||
|
% 3. In Docutils (as well as CSS) the unit symbol "pt" denotes the
|
||||||
|
% `Postscript point` or `DTP point` while LaTeX uses "pt" for the `LaTeX
|
||||||
|
% point`, which is unknown to Docutils and 0.3 % smaller.
|
||||||
|
%
|
||||||
|
% The `DTP point` is available in LaTeX as "bp" (big point):
|
||||||
|
%
|
||||||
|
% 1 pt = 1/72.25 in < 1 bp = 1/72 in
|
||||||
|
%
|
||||||
|
%
|
||||||
|
% Backwards compatibility:
|
||||||
|
% Images with width specification in ``px`` come out slightly (0.3 %) larger:
|
||||||
|
%
|
||||||
|
% 1 px = 1 bp = 1/72 in > 1 pt = 1/72.25 in
|
||||||
|
%
|
||||||
|
% This can be reset with ::
|
||||||
|
|
||||||
|
\pdfpxdimen=1pt
|
||||||
|
|
||||||
|
% .. caution:: It is impossible to revert the change of lengths specified with
|
||||||
|
% "pt" or without unit in a style sheet, however the 0.3 % change will be
|
||||||
|
% imperceptible in most cases.
|
||||||
|
%
|
||||||
|
% .. admonition:: Error ``illegal unit px``
|
||||||
|
%
|
||||||
|
% The unit ``px`` is not defined in "pure" LaTeX, but introduced by the
|
||||||
|
% `pdfTeX` converter on 2005-02-04. `pdfTeX` is used in all modern LaTeX
|
||||||
|
% distributions (since ca. 2006) also for conversion into DVI.
|
||||||
|
%
|
||||||
|
% If you convert the LaTeX source with a legacy program, you might get the
|
||||||
|
% error ``illegal unit px``.
|
||||||
|
%
|
||||||
|
% If updating LaTeX is not an option, just remove the ``px`` from the length
|
||||||
|
% specification. HTML/CSS will default to ``px`` while the `latexe2` writer
|
||||||
|
% will add the fallback unit ``bp``.
|
||||||
|
%
|
||||||
|
%
|
||||||
|
% Font encoding
|
||||||
|
% -------------
|
||||||
|
%
|
||||||
|
% New feature:
|
||||||
|
% Do not mix font-encoding and font settings: do not load the obsolete
|
||||||
|
% `ae` and `aeguill` packages unless explicitely required via the
|
||||||
|
% ``--stylesheet`` option.
|
||||||
|
%
|
||||||
|
% :font-encoding = "": do not load `ae` and `aeguill`, i.e.
|
||||||
|
%
|
||||||
|
% * do not change font settings,
|
||||||
|
% * do not use the fontenc package
|
||||||
|
% (implicitely loaded via `ae`),
|
||||||
|
% * use LaTeX default font encoding (OT1)
|
||||||
|
%
|
||||||
|
% :font-encoding = "OT1": load `fontenc` with ``\usepackage[OT1]{fontenc}``
|
||||||
|
%
|
||||||
|
% Example:
|
||||||
|
% ``--font-encoding=LGR,T1`` becomes ``\usepackage[LGR,T1]{fontenc}``
|
||||||
|
% (Latin, Latin-1 Supplement, and Greek)
|
||||||
|
%
|
||||||
|
%
|
||||||
|
% Backwards compatibility:
|
||||||
|
% Load the ae and aeguill packages if fontenc is not used.
|
||||||
|
%
|
||||||
|
% .. tip:: Using `ae` is not recommended. A similar look (but better
|
||||||
|
% implementation) can be achieved with the packages `lmodern`, `cmsuper`,
|
||||||
|
% or `cmlgr` all providing Computer Modern look-alikes in vector format and
|
||||||
|
% T1 encoding, e.g. ``--font-encoding=T1 --stylesheet=lmodern``.
|
||||||
|
%
|
||||||
|
% Sub- and superscript as text
|
||||||
|
% ----------------------------
|
||||||
|
%
|
||||||
|
% New feature:
|
||||||
|
% Set sub- and superscript role argument in text mode not as math.
|
||||||
|
%
|
||||||
|
% Pass the role content to ``\textsubscript`` or ``\textsuperscript``.
|
||||||
|
%
|
||||||
|
% Backwards compatibility:
|
||||||
|
% The old implementation set the role content in Math mode, where
|
||||||
|
%
|
||||||
|
% * whitespace is ignored,
|
||||||
|
% * a different command set and font setting scheme is active,
|
||||||
|
% * Latin letters are typeset italic but numbers upright.
|
||||||
|
%
|
||||||
|
% Although it is possible to redefine ``\textsubscript`` and
|
||||||
|
% ``\textsuperscript`` to typeset the content in math-mode, this can lead to
|
||||||
|
% errors with certain input and is therefore not done in this style sheet.
|
||||||
|
%
|
||||||
|
% .. tip:: To get italic subscripts, define and use in your document
|
||||||
|
% `custom roles`_ like ``.. role:: sub(subscript)`` and
|
||||||
|
% ``.. role:: super(superscript)`` and define the "role commands"::
|
||||||
|
|
||||||
|
\newcommand{\DUrolesub}{\itshape}
|
||||||
|
\newcommand{\DUrolesuper}{\itshape}
|
||||||
|
|
||||||
|
% Alternatively, if you want all sub- and superscripts in italic, redefine
|
||||||
|
% the macros::
|
||||||
|
|
||||||
|
%% \let\DUsup\textsubscript
|
||||||
|
%% \let\DUsuper\textsuperscript
|
||||||
|
%% \renewcommand*{\textsubscript}{\DUsub\itshape}
|
||||||
|
%% \renewcommand*{\textsuperscript}{\DUsuper\itshape}
|
||||||
|
|
||||||
|
% This is not fully backwards compatible, as it will also set numbers in
|
||||||
|
% italic shape and not ignore whitespace.
|
||||||
|
%
|
||||||
|
% Page layout
|
||||||
|
% -----------
|
||||||
|
%
|
||||||
|
% New features:
|
||||||
|
% * Margins are configurable via the ``DIV=...`` document option.
|
||||||
|
%
|
||||||
|
% * The ``\raggedbottom`` setting is no longer inserted into the document. It
|
||||||
|
% is the default for article and report classes. If requested in combination
|
||||||
|
% with a book class, it can be given in a custom style sheet.
|
||||||
|
%
|
||||||
|
% Backwards compatibility:
|
||||||
|
% Up to version 0.5, use of `typearea` and a DIV setting of 12 were
|
||||||
|
% hard-coded into the latex2e writer ::
|
||||||
|
|
||||||
|
\usepackage{typearea}
|
||||||
|
\typearea{12}
|
||||||
|
|
||||||
|
% and the vertical alignment of lower boundary of the text area in book
|
||||||
|
% classes disabled via ::
|
||||||
|
|
||||||
|
\raggedbottom
|
||||||
|
|
||||||
|
|
||||||
|
% ToC and section numbers
|
||||||
|
% -----------------------
|
||||||
|
%
|
||||||
|
% Better conformance to Docutils specifications.
|
||||||
|
%
|
||||||
|
% New feature:
|
||||||
|
% * The "depth" argument of the "contents" and "sectnum" directives is
|
||||||
|
% respected.
|
||||||
|
%
|
||||||
|
% * section numbering independent of 'use-latex-toc':
|
||||||
|
%
|
||||||
|
% + sections are only numbered if there is a "sectnum" directive in the
|
||||||
|
% document
|
||||||
|
%
|
||||||
|
% + section numbering by LaTeX if the "sectnum_xforms" config setting is
|
||||||
|
% False.
|
||||||
|
%
|
||||||
|
% Backwards compatibility:
|
||||||
|
%
|
||||||
|
% The previous behaviour was to always number sections if 'use-latex-toc' is
|
||||||
|
% true, using the document class defaults. It cannot be restored
|
||||||
|
% universally, the following code sets the default values of the "article"
|
||||||
|
% document class::
|
||||||
|
|
||||||
|
\setcounter{secnumdepth}{3}
|
||||||
|
\setcounter{tocdepth}{3}
|
||||||
|
|
||||||
|
% .. TODO or not to do? (Back-compatibility problems)
|
||||||
|
% * The default "depth" of the LaTeX-created ToC and the LaTeX section
|
||||||
|
% numbering is increased to the number of supported section levels.
|
||||||
|
%
|
||||||
|
% New feature:
|
||||||
|
% If 'use-latex-toc' is set, local tables of content are typeset using the
|
||||||
|
% 'minitoc' package (instead of being ignored).
|
||||||
|
%
|
||||||
|
% Backwards compatibility:
|
||||||
|
% Disable the creation of local ToCs (ignoring all special commands) by
|
||||||
|
% replacing ``\usepackage{minitoc} with ``\usepackage{mtcoff}``.
|
||||||
|
%
|
||||||
|
%
|
||||||
|
% Default font in admonitions and sidebar
|
||||||
|
% ---------------------------------------
|
||||||
|
%
|
||||||
|
% New feature:
|
||||||
|
% Use default font in admonitions and sidebar.
|
||||||
|
%
|
||||||
|
% Backward compatibility:
|
||||||
|
% See the fallback definitions for admonitions_, `topic title`_ and
|
||||||
|
% `sidebar`_.
|
||||||
|
%
|
||||||
|
%
|
||||||
|
% Figure placement
|
||||||
|
% ----------------
|
||||||
|
%
|
||||||
|
% New feature:
|
||||||
|
% Use ``\floatplacement`` from the `float` package instead of
|
||||||
|
% "hard-coded" optional argument for the global setting.
|
||||||
|
%
|
||||||
|
% Default to ``\floatplacement{figure}{H}`` (here definitely). This
|
||||||
|
% corresponds most closely to the source and HTML placement (principle of
|
||||||
|
% least surprise).
|
||||||
|
%
|
||||||
|
% Backwards compatibility:
|
||||||
|
% Set the global default back to the previous used value::
|
||||||
|
|
||||||
|
\usepackage{float}
|
||||||
|
\floatplacement{figure}{htbp} % here, top, bottom, extra-page
|
||||||
|
|
||||||
|
|
||||||
|
% Figure and image alignment
|
||||||
|
% --------------------------
|
||||||
|
%
|
||||||
|
% New features:
|
||||||
|
%
|
||||||
|
% a) Fix behaviour of 'align' argument to a figure (do not align figure
|
||||||
|
% contents).
|
||||||
|
%
|
||||||
|
% As the 'figwidth' argument is still ignored and the "natural width" of a
|
||||||
|
% figure in LaTeX is 100% \textwidth, setting the 'align' argument of a
|
||||||
|
% figure has currently no effect on the LaTeX output.
|
||||||
|
%
|
||||||
|
% b) Set default align of image in a figure to 'center'.
|
||||||
|
%
|
||||||
|
% c) Also center images that are wider than textwidth.
|
||||||
|
%
|
||||||
|
% d) Align images with class "align-[right|center|left]" (allows setting the
|
||||||
|
% alignment of an image in a figure).
|
||||||
|
%
|
||||||
|
% Backwards compatibility:
|
||||||
|
% There is no "automatic" way to reverse these changes via a style sheet.
|
||||||
|
%
|
||||||
|
% a) The alignment of the image can be set with the "align-left",
|
||||||
|
% "align-center" and "align-right" class arguments.
|
||||||
|
%
|
||||||
|
% As previously, the caption of a figure is aligned according to the
|
||||||
|
% document class -- configurable with a style sheet using the "caption"
|
||||||
|
% package.
|
||||||
|
%
|
||||||
|
% b) See a)
|
||||||
|
%
|
||||||
|
% c) Set the alignment of "oversized" images to "left" to get back the
|
||||||
|
% old placement.
|
||||||
|
%
|
||||||
|
% Shorter preamble
|
||||||
|
% ----------------
|
||||||
|
%
|
||||||
|
% New feature:
|
||||||
|
% The document preamble is pruned to contain only relevant commands and
|
||||||
|
% settings.
|
||||||
|
%
|
||||||
|
% Packages that are no longer required
|
||||||
|
% ````````````````````````````````````
|
||||||
|
%
|
||||||
|
% The following packages where required in pre-0.5 versions and still loaded
|
||||||
|
% with version 0.5::
|
||||||
|
|
||||||
|
\usepackage{shortvrb}
|
||||||
|
\usepackage{amsmath}
|
||||||
|
|
||||||
|
|
||||||
|
% Packages that are conditionally loaded
|
||||||
|
% ``````````````````````````````````````
|
||||||
|
%
|
||||||
|
% Additional to the `typearea` for `page layout`_, the following packages are
|
||||||
|
% only loaded if actually required by doctree elements:
|
||||||
|
%
|
||||||
|
% Tables
|
||||||
|
% ^^^^^^
|
||||||
|
%
|
||||||
|
% Standard package for tables across several pages::
|
||||||
|
|
||||||
|
\usepackage{longtable}
|
||||||
|
|
||||||
|
% Extra space between text in tables and the line above them
|
||||||
|
% ('array' is implicitely loaded by 'tabularx', see below)::
|
||||||
|
|
||||||
|
\usepackage{array}
|
||||||
|
\setlength{\extrarowheight}{2pt}
|
||||||
|
|
||||||
|
% Table cells spanning multiple rows::
|
||||||
|
|
||||||
|
\usepackage{multirow}
|
||||||
|
|
||||||
|
% Docinfo
|
||||||
|
% ^^^^^^^
|
||||||
|
%
|
||||||
|
% One-page tables with auto-width columns::
|
||||||
|
|
||||||
|
\usepackage{tabularx}
|
||||||
|
|
||||||
|
% Images
|
||||||
|
% ^^^^^^
|
||||||
|
% Include graphic files::
|
||||||
|
|
||||||
|
\usepackage{graphicx}
|
||||||
|
|
||||||
|
% Problematic, Sidebar
|
||||||
|
% ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
% Set text and/or background colour, coloured boxes with ``\colorbox``::
|
||||||
|
|
||||||
|
\usepackage{color}
|
||||||
|
|
||||||
|
% Floats for footnotes settings
|
||||||
|
% `````````````````````````````
|
||||||
|
%
|
||||||
|
% Settings for the use of floats for footnotes are only included if
|
||||||
|
%
|
||||||
|
% * the option "use-latex-footnotes" is False, and
|
||||||
|
% * there is at least one footnote in the document.
|
||||||
|
%
|
||||||
|
% ::
|
||||||
|
|
||||||
|
% begin: floats for footnotes tweaking.
|
||||||
|
\setlength{\floatsep}{0.5em}
|
||||||
|
\setlength{\textfloatsep}{\fill}
|
||||||
|
\addtolength{\textfloatsep}{3em}
|
||||||
|
\renewcommand{\textfraction}{0.5}
|
||||||
|
\renewcommand{\topfraction}{0.5}
|
||||||
|
\renewcommand{\bottomfraction}{0.5}
|
||||||
|
\setcounter{totalnumber}{50}
|
||||||
|
\setcounter{topnumber}{50}
|
||||||
|
\setcounter{bottomnumber}{50}
|
||||||
|
% end floats for footnotes
|
||||||
|
|
||||||
|
|
||||||
|
% Special lengths, commands, and environments
|
||||||
|
% -------------------------------------------
|
||||||
|
%
|
||||||
|
% Removed definitions
|
||||||
|
% ```````````````````
|
||||||
|
%
|
||||||
|
% admonition width
|
||||||
|
% ^^^^^^^^^^^^^^^^
|
||||||
|
% The ``admonitionwith`` lenght is replaced by the more powerful
|
||||||
|
% ``\DUadmonition`` command (see admonitions_).
|
||||||
|
%
|
||||||
|
% Backwards compatibility:
|
||||||
|
% The default value (90 % of the textwidth) is unchanged.
|
||||||
|
%
|
||||||
|
% To configure the admonition width, you must redefine the ``DUadmonition``
|
||||||
|
% command instead of changing the ``admonitionwith`` length value.
|
||||||
|
%
|
||||||
|
%
|
||||||
|
% Renamed definitions (now conditional)
|
||||||
|
% `````````````````````````````````````
|
||||||
|
%
|
||||||
|
% The names for special doctree elements are now prefixed with ``DU``.
|
||||||
|
%
|
||||||
|
% Up to version 0.5, all definitions were included in the preamble (before the
|
||||||
|
% style sheet) of every document -- even if not used in the body. Since
|
||||||
|
% version 0.6, fallback definitions are included after the style sheet and
|
||||||
|
% only if required.
|
||||||
|
%
|
||||||
|
% Customization is done by an alternative definition in a style sheet with
|
||||||
|
% ``\newcommand`` instead of the former ``\renewcommand``.
|
||||||
|
%
|
||||||
|
% The following code provides the old definitions and maps them (or their
|
||||||
|
% custom variants) to the new interface.
|
||||||
|
%
|
||||||
|
% docinfo width
|
||||||
|
% ^^^^^^^^^^^^^
|
||||||
|
% ::
|
||||||
|
|
||||||
|
\newlength{\docinfowidth}
|
||||||
|
\setlength{\docinfowidth}{0.9\textwidth}
|
||||||
|
|
||||||
|
\newlength{\DUdocinfowidth}
|
||||||
|
\AtBeginDocument{\setlength{\DUdocinfowidth}{\docinfowidth}}
|
||||||
|
|
||||||
|
% line block
|
||||||
|
% ^^^^^^^^^^
|
||||||
|
% ::
|
||||||
|
|
||||||
|
\newlength{\lineblockindentation}
|
||||||
|
\setlength{\lineblockindentation}{2.5em}
|
||||||
|
\newenvironment{lineblock}[1]
|
||||||
|
{\begin{list}{}
|
||||||
|
{\setlength{\partopsep}{\parskip}
|
||||||
|
\addtolength{\partopsep}{\baselineskip}
|
||||||
|
\topsep0pt\itemsep0.15\baselineskip\parsep0pt
|
||||||
|
\leftmargin#1}
|
||||||
|
\raggedright}
|
||||||
|
{\end{list}}
|
||||||
|
|
||||||
|
\newlength{\DUlineblockindent}
|
||||||
|
\AtBeginDocument{\setlength{\DUlineblockindent}{\lineblockindentation}}
|
||||||
|
\newenvironment{DUlineblock}[1]
|
||||||
|
{\begin{lineblock}{#1}}
|
||||||
|
{\end{lineblock}}
|
||||||
|
|
||||||
|
% local line width
|
||||||
|
% ^^^^^^^^^^^^^^^^
|
||||||
|
%
|
||||||
|
% The ``\locallinewidth`` length for internal use in tables is replaced
|
||||||
|
% by ``\DUtablewidth``. It was never intended for customization::
|
||||||
|
|
||||||
|
\newlength{\locallinewidth}
|
||||||
|
|
||||||
|
% option lists
|
||||||
|
% ^^^^^^^^^^^^
|
||||||
|
% ::
|
||||||
|
|
||||||
|
\newcommand{\optionlistlabel}[1]{\bf #1 \hfill}
|
||||||
|
\newenvironment{optionlist}[1]
|
||||||
|
{\begin{list}{}
|
||||||
|
{\setlength{\labelwidth}{#1}
|
||||||
|
\setlength{\rightmargin}{1cm}
|
||||||
|
\setlength{\leftmargin}{\rightmargin}
|
||||||
|
\addtolength{\leftmargin}{\labelwidth}
|
||||||
|
\addtolength{\leftmargin}{\labelsep}
|
||||||
|
\renewcommand{\makelabel}{\optionlistlabel}}
|
||||||
|
}{\end{list}}
|
||||||
|
|
||||||
|
\newcommand{\DUoptionlistlabel}{\optionlistlabel}
|
||||||
|
\newenvironment{DUoptionlist}
|
||||||
|
{\begin{optionlist}{3cm}}
|
||||||
|
{\end{optionlist}}
|
||||||
|
|
||||||
|
% rubric
|
||||||
|
% ^^^^^^
|
||||||
|
% Now less prominent (not bold, normal size) restore with::
|
||||||
|
|
||||||
|
\newcommand{\rubric}[1]{\subsection*{~\hfill {\it #1} \hfill ~}}
|
||||||
|
\newcommand{\DUrubric}[2][class-arg]{\rubric{#2}}
|
||||||
|
|
||||||
|
% title reference role
|
||||||
|
% ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
% ::
|
||||||
|
|
||||||
|
\newcommand{\titlereference}[1]{\textsl{#1}}
|
||||||
|
\newcommand{\DUroletitlereference}[1]{\titlereference{#1}}
|
||||||
|
|
||||||
|
|
||||||
|
% New definitions
|
||||||
|
% ```````````````
|
||||||
|
%
|
||||||
|
% New Feature:
|
||||||
|
% Enable customization of some more Docutils elements with special commands
|
||||||
|
%
|
||||||
|
% :admonition: ``DUadmonition`` command (replacing ``\admonitionwidth``),
|
||||||
|
% :field list: ``DUfieldlist`` environment,
|
||||||
|
% :legend: ``DUlegend`` environment,
|
||||||
|
% :sidebar: ``\DUsidebar``, ``\DUtitle``, and
|
||||||
|
% ``DUsubtitle`` commands,
|
||||||
|
% :topic: ``\DUtopic`` and ``\DUtitle`` commands,
|
||||||
|
% :transition: ``\DUtransition`` command.
|
||||||
|
% :footnotes: ``\DUfootnotemark`` and ``\DUfootnotetext`` commands with
|
||||||
|
% hyperlink support using the Docutils-provided footnote label.
|
||||||
|
%
|
||||||
|
% Backwards compatibility:
|
||||||
|
% In most cases, the default definition corresponds to the previously used
|
||||||
|
% construct. The following definitions restore the old behaviour in case of
|
||||||
|
% changes.
|
||||||
|
%
|
||||||
|
% admonitions
|
||||||
|
% ^^^^^^^^^^^
|
||||||
|
% Use sans-serif fonts::
|
||||||
|
|
||||||
|
\newcommand{\DUadmonition}[2][class-arg]{%
|
||||||
|
\begin{center}
|
||||||
|
\fbox{\parbox{0.9\textwidth}{\sffamily #2}}
|
||||||
|
\end{center}
|
||||||
|
}
|
||||||
|
|
||||||
|
% dedication
|
||||||
|
% ^^^^^^^^^^
|
||||||
|
% Do not center::
|
||||||
|
|
||||||
|
\newcommand{\DUtopicdedication}[1]{#1}
|
||||||
|
|
||||||
|
% But center the title::
|
||||||
|
|
||||||
|
\newcommand*{\DUtitlededication}[1]{\centerline{\textbf{#1}}}
|
||||||
|
|
||||||
|
% sidebar
|
||||||
|
% ^^^^^^^
|
||||||
|
% Use sans-serif fonts, a frame, and a darker shade of grey::
|
||||||
|
|
||||||
|
\providecommand{\DUsidebar}[2][class-arg]{%
|
||||||
|
\begin{center}
|
||||||
|
\sffamily
|
||||||
|
\fbox{\colorbox[gray]{0.80}{\parbox{0.9\textwidth}{#2}}}
|
||||||
|
\end{center}
|
||||||
|
}
|
||||||
|
|
||||||
|
% sidebar sub-title
|
||||||
|
% ^^^^^^^^^^^^^^^^^
|
||||||
|
% Bold instead of emphasized::
|
||||||
|
|
||||||
|
\providecommand*{\DUsubtitlesidebar}[1]{\hspace*{\fill}\\
|
||||||
|
\textbf{#1}\smallskip}
|
||||||
|
|
||||||
|
% topic
|
||||||
|
% ^^^^^
|
||||||
|
% No quote but normal text::
|
||||||
|
|
||||||
|
\newcommand{\DUtopic}[2][class-arg]{%
|
||||||
|
\ifcsname DUtopic#1\endcsname%
|
||||||
|
\csname DUtopic#1\endcsname{#2}%
|
||||||
|
\else
|
||||||
|
#2
|
||||||
|
\fi
|
||||||
|
}
|
||||||
|
|
||||||
|
% topic title
|
||||||
|
% ^^^^^^^^^^^
|
||||||
|
% Title for "topics" (admonitions, sidebar).
|
||||||
|
%
|
||||||
|
% Larger font size::
|
||||||
|
|
||||||
|
\providecommand*{\DUtitletopic}[1]{\textbf{\large #1}\smallskip}
|
||||||
|
|
||||||
|
% transition
|
||||||
|
% ^^^^^^^^^^
|
||||||
|
% Do not add vertical space after the transition. ::
|
||||||
|
|
||||||
|
\providecommand*{\DUtransition}[1][class-arg]{%
|
||||||
|
\hspace*{\fill}\hrulefill\hspace*{\fill}}
|
|
@ -1,7 +1,12 @@
|
||||||
$head_prefix% generated by Docutils <http://docutils.sourceforge.net/>
|
$head_prefix% generated by Docutils <http://docutils.sourceforge.net/>
|
||||||
% rubber: set program xelatex
|
% rubber: set program xelatex
|
||||||
\usepackage[no-sscript]{xltxtra} % loads fixltx2e, metalogo, xunicode, fontspec
|
\usepackage{fontspec}
|
||||||
% \defaultfontfeatures{Scale=MatchLowercase}
|
% \defaultfontfeatures{Scale=MatchLowercase}
|
||||||
|
% straight double quotes (defined T1 but missing in TU):
|
||||||
|
\ifdefined \UnicodeEncodingName
|
||||||
|
\DeclareTextCommand{\textquotedbl}{\UnicodeEncodingName}{%
|
||||||
|
{\addfontfeatures{RawFeature=-tlig,Mapping=}\char34}}%
|
||||||
|
\fi
|
||||||
$requirements
|
$requirements
|
||||||
%%% Custom LaTeX preamble
|
%%% Custom LaTeX preamble
|
||||||
$latex_preamble
|
$latex_preamble
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# $Id: manpage.py 7628 2013-03-09 10:19:35Z grubert $
|
# $Id: manpage.py 8116 2017-06-18 19:09:40Z milde $
|
||||||
# Author: Engelbert Gruber <grubert@users.sourceforge.net>
|
# Author: Engelbert Gruber <grubert@users.sourceforge.net>
|
||||||
# Copyright: This module is put into the public domain.
|
# Copyright: This module is put into the public domain.
|
||||||
|
|
||||||
|
@ -368,7 +368,7 @@ class Translator(nodes.NodeVisitor):
|
||||||
tmpl = (".TH %(title_upper)s %(manual_section)s"
|
tmpl = (".TH %(title_upper)s %(manual_section)s"
|
||||||
" \"%(date)s\" \"%(version)s\" \"%(manual_group)s\"\n"
|
" \"%(date)s\" \"%(version)s\" \"%(manual_group)s\"\n"
|
||||||
".SH NAME\n"
|
".SH NAME\n"
|
||||||
"%(title)s \- %(subtitle)s\n")
|
"%(title)s \\- %(subtitle)s\n")
|
||||||
return tmpl % self._docinfo
|
return tmpl % self._docinfo
|
||||||
|
|
||||||
def append_header(self):
|
def append_header(self):
|
||||||
|
@ -403,7 +403,7 @@ class Translator(nodes.NodeVisitor):
|
||||||
self.defs['strong'][0],
|
self.defs['strong'][0],
|
||||||
self.language.labels.get(name, name).upper(),
|
self.language.labels.get(name, name).upper(),
|
||||||
self.defs['strong'][1],
|
self.defs['strong'][1],
|
||||||
)
|
)
|
||||||
self.body.append(name)
|
self.body.append(name)
|
||||||
self.visit_block_quote(node)
|
self.visit_block_quote(node)
|
||||||
|
|
||||||
|
@ -755,6 +755,12 @@ class Translator(nodes.NodeVisitor):
|
||||||
|
|
||||||
depart_important = depart_admonition
|
depart_important = depart_admonition
|
||||||
|
|
||||||
|
def visit_inline(self, node):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def depart_inline(self, node):
|
||||||
|
pass
|
||||||
|
|
||||||
def visit_label(self, node):
|
def visit_label(self, node):
|
||||||
# footnote and citation
|
# footnote and citation
|
||||||
if (isinstance(node.parent, nodes.footnote)
|
if (isinstance(node.parent, nodes.footnote)
|
||||||
|
@ -818,7 +824,7 @@ class Translator(nodes.NodeVisitor):
|
||||||
# BUG/HACK: indent alway uses the _last_ indention,
|
# BUG/HACK: indent alway uses the _last_ indention,
|
||||||
# thus we need two of them.
|
# thus we need two of them.
|
||||||
self.indent(LITERAL_BLOCK_INDENT)
|
self.indent(LITERAL_BLOCK_INDENT)
|
||||||
self.indent(0)
|
self.indent(0)
|
||||||
self.body.append(self.defs['literal_block'][0])
|
self.body.append(self.defs['literal_block'][0])
|
||||||
self._in_literal = True
|
self._in_literal = True
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: __init__.py 7717 2013-08-21 22:01:21Z milde $
|
# $Id: __init__.py 8131 2017-07-03 22:06:53Z dkuhlman $
|
||||||
# Author: Dave Kuhlman <dkuhlman@rexx.com>
|
# Author: Dave Kuhlman <dkuhlman@rexx.com>
|
||||||
# Copyright: This module has been placed in the public domain.
|
# Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
@ -23,12 +23,18 @@ import re
|
||||||
import StringIO
|
import StringIO
|
||||||
import copy
|
import copy
|
||||||
import urllib2
|
import urllib2
|
||||||
|
import itertools
|
||||||
import docutils
|
import docutils
|
||||||
|
try:
|
||||||
|
import locale # module missing in Jython
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
from docutils import frontend, nodes, utils, writers, languages
|
from docutils import frontend, nodes, utils, writers, languages
|
||||||
from docutils.readers import standalone
|
from docutils.readers import standalone
|
||||||
from docutils.transforms import references
|
from docutils.transforms import references
|
||||||
|
|
||||||
|
|
||||||
|
IMAGE_NAME_COUNTER = itertools.count()
|
||||||
WhichElementTree = ''
|
WhichElementTree = ''
|
||||||
try:
|
try:
|
||||||
# 1. Try to use lxml.
|
# 1. Try to use lxml.
|
||||||
|
@ -58,7 +64,7 @@ try:
|
||||||
import pygments.lexers
|
import pygments.lexers
|
||||||
from pygmentsformatter import OdtPygmentsProgFormatter, \
|
from pygmentsformatter import OdtPygmentsProgFormatter, \
|
||||||
OdtPygmentsLaTeXFormatter
|
OdtPygmentsLaTeXFormatter
|
||||||
except ImportError, exp:
|
except (ImportError, SyntaxError), exp:
|
||||||
pygments = None
|
pygments = None
|
||||||
|
|
||||||
# check for the Python Imaging Library
|
# check for the Python Imaging Library
|
||||||
|
@ -569,6 +575,48 @@ class Writer(writers.Writer):
|
||||||
s1 = self.create_meta()
|
s1 = self.create_meta()
|
||||||
self.write_zip_str(zfile, 'meta.xml', s1)
|
self.write_zip_str(zfile, 'meta.xml', s1)
|
||||||
s1 = self.get_stylesheet()
|
s1 = self.get_stylesheet()
|
||||||
|
# Set default language in document to be generated.
|
||||||
|
# Language is specified by the -l/--language command line option.
|
||||||
|
# The format is described in BCP 47. If region is omitted, we use
|
||||||
|
# local.normalize(ll) to obtain a region.
|
||||||
|
language_code = None
|
||||||
|
region_code = None
|
||||||
|
if self.visitor.language_code:
|
||||||
|
language_ids = self.visitor.language_code.replace('_', '-')
|
||||||
|
language_ids = language_ids.split('-')
|
||||||
|
# first tag is primary language tag
|
||||||
|
language_code = language_ids[0].lower()
|
||||||
|
# 2-letter region subtag may follow in 2nd or 3rd position
|
||||||
|
for subtag in language_ids[1:]:
|
||||||
|
if len(subtag) == 2 and subtag.isalpha():
|
||||||
|
region_code = subtag.upper()
|
||||||
|
break
|
||||||
|
elif len(subtag) == 1:
|
||||||
|
break # 1-letter tag is never before valid region tag
|
||||||
|
if region_code is None:
|
||||||
|
try:
|
||||||
|
rcode = locale.normalize(language_code)
|
||||||
|
except NameError:
|
||||||
|
rcode = language_code
|
||||||
|
rcode = rcode.split('_')
|
||||||
|
if len(rcode) > 1:
|
||||||
|
rcode = rcode[1].split('.')
|
||||||
|
region_code = rcode[0]
|
||||||
|
if region_code is None:
|
||||||
|
self.document.reporter.warning(
|
||||||
|
'invalid language-region.\n'
|
||||||
|
' Could not find region with locale.normalize().\n'
|
||||||
|
' Please specify both language and region (ll-RR).\n'
|
||||||
|
' Examples: es-MX (Spanish, Mexico),\n'
|
||||||
|
' en-AU (English, Australia).')
|
||||||
|
# Update the style ElementTree with the language and region.
|
||||||
|
# Note that we keep a reference to the modified node because
|
||||||
|
# it is possible that ElementTree will throw away the Python
|
||||||
|
# representation of the updated node if we do not.
|
||||||
|
updated, new_dom_styles, updated_node = self.update_stylesheet(
|
||||||
|
self.visitor.get_dom_stylesheet(), language_code, region_code)
|
||||||
|
if updated:
|
||||||
|
s1 = etree.tostring(new_dom_styles)
|
||||||
self.write_zip_str(zfile, 'styles.xml', s1)
|
self.write_zip_str(zfile, 'styles.xml', s1)
|
||||||
self.store_embedded_files(zfile)
|
self.store_embedded_files(zfile)
|
||||||
self.copy_from_stylesheet(zfile)
|
self.copy_from_stylesheet(zfile)
|
||||||
|
@ -580,7 +628,58 @@ class Writer(writers.Writer):
|
||||||
self.parts['encoding'] = self.document.settings.output_encoding
|
self.parts['encoding'] = self.document.settings.output_encoding
|
||||||
self.parts['version'] = docutils.__version__
|
self.parts['version'] = docutils.__version__
|
||||||
|
|
||||||
def write_zip_str(self, zfile, name, bytes, compress_type=zipfile.ZIP_DEFLATED):
|
def update_stylesheet(self, stylesheet_root, language_code, region_code):
|
||||||
|
"""Update xml style sheet element with language and region/country."""
|
||||||
|
updated = False
|
||||||
|
modified_nodes = set()
|
||||||
|
if language_code is not None or region_code is not None:
|
||||||
|
n1 = stylesheet_root.find(
|
||||||
|
'{urn:oasis:names:tc:opendocument:xmlns:office:1.0}'
|
||||||
|
'styles')
|
||||||
|
if n1 is None:
|
||||||
|
raise RuntimeError(
|
||||||
|
"Cannot find 'styles' element in styles.odt/styles.xml")
|
||||||
|
n2_nodes = n1.findall(
|
||||||
|
'{urn:oasis:names:tc:opendocument:xmlns:style:1.0}'
|
||||||
|
'default-style')
|
||||||
|
if not n2_nodes:
|
||||||
|
raise RuntimeError(
|
||||||
|
"Cannot find 'default-style' "
|
||||||
|
"element in styles.xml")
|
||||||
|
for node in n2_nodes:
|
||||||
|
family = node.attrib.get(
|
||||||
|
'{urn:oasis:names:tc:opendocument:xmlns:style:1.0}'
|
||||||
|
'family')
|
||||||
|
if family == 'paragraph' or family == 'graphic':
|
||||||
|
n3 = node.find(
|
||||||
|
'{urn:oasis:names:tc:opendocument:xmlns:style:1.0}'
|
||||||
|
'text-properties')
|
||||||
|
if n3 is None:
|
||||||
|
raise RuntimeError(
|
||||||
|
"Cannot find 'text-properties' "
|
||||||
|
"element in styles.xml")
|
||||||
|
if language_code is not None:
|
||||||
|
n3.attrib[
|
||||||
|
'{urn:oasis:names:tc:opendocument:xmlns:'
|
||||||
|
'xsl-fo-compatible:1.0}language'] = language_code
|
||||||
|
n3.attrib[
|
||||||
|
'{urn:oasis:names:tc:opendocument:xmlns:'
|
||||||
|
'style:1.0}language-complex'] = language_code
|
||||||
|
updated = True
|
||||||
|
modified_nodes.add(n3)
|
||||||
|
if region_code is not None:
|
||||||
|
n3.attrib[
|
||||||
|
'{urn:oasis:names:tc:opendocument:xmlns:'
|
||||||
|
'xsl-fo-compatible:1.0}country'] = region_code
|
||||||
|
n3.attrib[
|
||||||
|
'{urn:oasis:names:tc:opendocument:xmlns:'
|
||||||
|
'style:1.0}country-complex'] = region_code
|
||||||
|
updated = True
|
||||||
|
modified_nodes.add(n3)
|
||||||
|
return updated, stylesheet_root, modified_nodes
|
||||||
|
|
||||||
|
def write_zip_str(
|
||||||
|
self, zfile, name, bytes, compress_type=zipfile.ZIP_DEFLATED):
|
||||||
localtime = time.localtime(time.time())
|
localtime = time.localtime(time.time())
|
||||||
zinfo = zipfile.ZipInfo(name, localtime)
|
zinfo = zipfile.ZipInfo(name, localtime)
|
||||||
# Add some standard UNIX file access permissions (-rw-r--r--).
|
# Add some standard UNIX file access permissions (-rw-r--r--).
|
||||||
|
@ -594,9 +693,7 @@ class Writer(writers.Writer):
|
||||||
if source is None:
|
if source is None:
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
# encode/decode
|
zfile.write(source, destination)
|
||||||
destination1 = destination.decode('latin-1').encode('utf-8')
|
|
||||||
zfile.write(source, destination1)
|
|
||||||
except OSError, e:
|
except OSError, e:
|
||||||
self.document.reporter.warning(
|
self.document.reporter.warning(
|
||||||
"Can't open file %s." % (source, ))
|
"Can't open file %s." % (source, ))
|
||||||
|
@ -727,8 +824,8 @@ class Writer(writers.Writer):
|
||||||
#s1 = doc.toprettyxml(' ')
|
#s1 = doc.toprettyxml(' ')
|
||||||
return s1
|
return s1
|
||||||
|
|
||||||
# class ODFTranslator(nodes.SparseNodeVisitor):
|
|
||||||
|
|
||||||
|
# class ODFTranslator(nodes.SparseNodeVisitor):
|
||||||
class ODFTranslator(nodes.GenericNodeVisitor):
|
class ODFTranslator(nodes.GenericNodeVisitor):
|
||||||
|
|
||||||
used_styles = (
|
used_styles = (
|
||||||
|
@ -786,15 +883,17 @@ class ODFTranslator(nodes.GenericNodeVisitor):
|
||||||
'lineblock5',
|
'lineblock5',
|
||||||
'lineblock6',
|
'lineblock6',
|
||||||
'image', 'figureframe',
|
'image', 'figureframe',
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, document):
|
def __init__(self, document):
|
||||||
#nodes.SparseNodeVisitor.__init__(self, document)
|
#nodes.SparseNodeVisitor.__init__(self, document)
|
||||||
nodes.GenericNodeVisitor.__init__(self, document)
|
nodes.GenericNodeVisitor.__init__(self, document)
|
||||||
self.settings = document.settings
|
self.settings = document.settings
|
||||||
lcode = self.settings.language_code
|
self.language_code = self.settings.language_code
|
||||||
self.language = languages.get_language(lcode, document.reporter)
|
self.language = languages.get_language(
|
||||||
self.format_map = { }
|
self.language_code,
|
||||||
|
document.reporter)
|
||||||
|
self.format_map = {}
|
||||||
if self.settings.odf_config_file:
|
if self.settings.odf_config_file:
|
||||||
from ConfigParser import ConfigParser
|
from ConfigParser import ConfigParser
|
||||||
|
|
||||||
|
@ -804,8 +903,9 @@ class ODFTranslator(nodes.GenericNodeVisitor):
|
||||||
if rststyle not in self.used_styles:
|
if rststyle not in self.used_styles:
|
||||||
self.document.reporter.warning(
|
self.document.reporter.warning(
|
||||||
'Style "%s" is not a style used by odtwriter.' % (
|
'Style "%s" is not a style used by odtwriter.' % (
|
||||||
rststyle, ))
|
rststyle, ))
|
||||||
self.format_map[rststyle] = format.decode('utf-8')
|
if sys.version_info.major == 2:
|
||||||
|
self.format_map[rststyle] = format.decode('utf-8')
|
||||||
self.section_level = 0
|
self.section_level = 0
|
||||||
self.section_count = 0
|
self.section_count = 0
|
||||||
# Create ElementTree content and styles documents.
|
# Create ElementTree content and styles documents.
|
||||||
|
@ -872,6 +972,8 @@ class ODFTranslator(nodes.GenericNodeVisitor):
|
||||||
self.table_styles = None
|
self.table_styles = None
|
||||||
self.in_citation = False
|
self.in_citation = False
|
||||||
|
|
||||||
|
# Keep track of nested styling classes
|
||||||
|
self.inline_style_count_stack = []
|
||||||
|
|
||||||
def get_str_stylesheet(self):
|
def get_str_stylesheet(self):
|
||||||
return self.str_stylesheet
|
return self.str_stylesheet
|
||||||
|
@ -982,18 +1084,18 @@ class ODFTranslator(nodes.GenericNodeVisitor):
|
||||||
'style:name': style_name,
|
'style:name': style_name,
|
||||||
'style:master-page-name': "rststyle-pagedefault",
|
'style:master-page-name': "rststyle-pagedefault",
|
||||||
'style:family': "paragraph",
|
'style:family': "paragraph",
|
||||||
}, nsdict=SNSD)
|
}, nsdict=SNSD)
|
||||||
if current_style:
|
if current_style:
|
||||||
el1.set('style:parent-style-name', current_style)
|
el1.set('style:parent-style-name', current_style)
|
||||||
el.set('text:style-name', style_name)
|
el.set('text:style-name', style_name)
|
||||||
|
|
||||||
|
def rststyle(self, name, parameters=()):
|
||||||
def rststyle(self, name, parameters=( )):
|
|
||||||
"""
|
"""
|
||||||
Returns the style name to use for the given style.
|
Returns the style name to use for the given style.
|
||||||
|
|
||||||
If `parameters` is given `name` must contain a matching number of ``%`` and
|
If `parameters` is given `name` must contain a matching number of
|
||||||
is used as a format expression with `parameters` as the value.
|
``%`` and is used as a format expression with `parameters` as
|
||||||
|
the value.
|
||||||
"""
|
"""
|
||||||
name1 = name % parameters
|
name1 = name % parameters
|
||||||
stylename = self.format_map.get(name1, 'rststyle-%s' % name1)
|
stylename = self.format_map.get(name1, 'rststyle-%s' % name1)
|
||||||
|
@ -1010,6 +1112,9 @@ class ODFTranslator(nodes.GenericNodeVisitor):
|
||||||
new_content = etree.tostring(self.dom_stylesheet)
|
new_content = etree.tostring(self.dom_stylesheet)
|
||||||
return new_content
|
return new_content
|
||||||
|
|
||||||
|
def get_dom_stylesheet(self):
|
||||||
|
return self.dom_stylesheet
|
||||||
|
|
||||||
def setup_paper(self, root_el):
|
def setup_paper(self, root_el):
|
||||||
try:
|
try:
|
||||||
fin = os.popen("paperconf -s 2> /dev/null")
|
fin = os.popen("paperconf -s 2> /dev/null")
|
||||||
|
@ -2058,7 +2163,7 @@ class ODFTranslator(nodes.GenericNodeVisitor):
|
||||||
# Capture the image file.
|
# Capture the image file.
|
||||||
if 'uri' in node.attributes:
|
if 'uri' in node.attributes:
|
||||||
source = node.attributes['uri']
|
source = node.attributes['uri']
|
||||||
if not source.startswith('http:'):
|
if not (source.startswith('http:') or source.startswith('https:')):
|
||||||
if not source.startswith(os.sep):
|
if not source.startswith(os.sep):
|
||||||
docsource, line = utils.get_source_line(node)
|
docsource, line = utils.get_source_line(node)
|
||||||
if docsource:
|
if docsource:
|
||||||
|
@ -2077,7 +2182,7 @@ class ODFTranslator(nodes.GenericNodeVisitor):
|
||||||
self.image_count += 1
|
self.image_count += 1
|
||||||
filename = os.path.split(source)[1]
|
filename = os.path.split(source)[1]
|
||||||
destination = 'Pictures/1%08x%s' % (self.image_count, filename, )
|
destination = 'Pictures/1%08x%s' % (self.image_count, filename, )
|
||||||
if source.startswith('http:'):
|
if source.startswith('http:') or source.startswith('https:'):
|
||||||
try:
|
try:
|
||||||
imgfile = urllib2.urlopen(source)
|
imgfile = urllib2.urlopen(source)
|
||||||
content = imgfile.read()
|
content = imgfile.read()
|
||||||
|
@ -2118,70 +2223,151 @@ class ODFTranslator(nodes.GenericNodeVisitor):
|
||||||
|
|
||||||
def get_image_width_height(self, node, attr):
|
def get_image_width_height(self, node, attr):
|
||||||
size = None
|
size = None
|
||||||
|
unit = None
|
||||||
if attr in node.attributes:
|
if attr in node.attributes:
|
||||||
size = node.attributes[attr]
|
size = node.attributes[attr]
|
||||||
unit = size[-2:]
|
size = size.strip()
|
||||||
if unit.isalpha():
|
# For conversion factors, see:
|
||||||
size = size[:-2]
|
# http://www.unitconversion.org/unit_converter/typography-ex.html
|
||||||
else:
|
|
||||||
unit = 'px'
|
|
||||||
try:
|
try:
|
||||||
size = float(size)
|
if size.endswith('%'):
|
||||||
except ValueError, e:
|
if attr == 'height':
|
||||||
|
# Percentage allowed for width but not height.
|
||||||
|
raise ValueError('percentage not allowed for height')
|
||||||
|
size = size.rstrip(' %')
|
||||||
|
size = float(size) / 100.0
|
||||||
|
unit = '%'
|
||||||
|
else:
|
||||||
|
size, unit = convert_to_cm(size)
|
||||||
|
except ValueError, exp:
|
||||||
self.document.reporter.warning(
|
self.document.reporter.warning(
|
||||||
'Invalid %s for image: "%s"' % (
|
'Invalid %s for image: "%s". '
|
||||||
attr, node.attributes[attr]))
|
'Error: "%s".' % (
|
||||||
size = [size, unit]
|
attr, node.attributes[attr], exp))
|
||||||
return size
|
return size, unit
|
||||||
|
|
||||||
|
def convert_to_cm(self, size):
|
||||||
|
"""Convert various units to centimeters.
|
||||||
|
|
||||||
|
Note that a call to this method should be wrapped in:
|
||||||
|
try: except ValueError:
|
||||||
|
"""
|
||||||
|
size = size.strip()
|
||||||
|
if size.endswith('px'):
|
||||||
|
size = float(size[:-2]) * 0.026 # convert px to cm
|
||||||
|
elif size.endswith('in'):
|
||||||
|
size = float(size[:-2]) * 2.54 # convert in to cm
|
||||||
|
elif size.endswith('pt'):
|
||||||
|
size = float(size[:-2]) * 0.035 # convert pt to cm
|
||||||
|
elif size.endswith('pc'):
|
||||||
|
size = float(size[:-2]) * 2.371 # convert pc to cm
|
||||||
|
elif size.endswith('mm'):
|
||||||
|
size = float(size[:-2]) * 10.0 # convert mm to cm
|
||||||
|
elif size.endswith('cm'):
|
||||||
|
size = float(size[:-2])
|
||||||
|
else:
|
||||||
|
raise ValueError('unknown unit type')
|
||||||
|
unit = 'cm'
|
||||||
|
return size, unit
|
||||||
|
|
||||||
def get_image_scale(self, node):
|
def get_image_scale(self, node):
|
||||||
if 'scale' in node.attributes:
|
if 'scale' in node.attributes:
|
||||||
|
scale = node.attributes['scale']
|
||||||
try:
|
try:
|
||||||
scale = int(node.attributes['scale'])
|
scale = int(scale)
|
||||||
if scale < 1: # or scale > 100:
|
except ValueError:
|
||||||
self.document.reporter.warning(
|
|
||||||
'scale out of range (%s), using 1.' % (scale, ))
|
|
||||||
scale = 1
|
|
||||||
scale = scale * 0.01
|
|
||||||
except ValueError, e:
|
|
||||||
self.document.reporter.warning(
|
self.document.reporter.warning(
|
||||||
'Invalid scale for image: "%s"' % (
|
'Invalid scale for image: "%s"' % (
|
||||||
node.attributes['scale'], ))
|
node.attributes['scale'], ))
|
||||||
|
if scale < 1: # or scale > 100:
|
||||||
|
self.document.reporter.warning(
|
||||||
|
'scale out of range (%s), using 1.' % (scale, ))
|
||||||
|
scale = 1
|
||||||
|
scale = scale * 0.01
|
||||||
else:
|
else:
|
||||||
scale = 1.0
|
scale = 1.0
|
||||||
return scale
|
return scale
|
||||||
|
|
||||||
def get_image_scaled_width_height(self, node, source):
|
def get_image_scaled_width_height(self, node, source):
|
||||||
|
"""Return the image size in centimeters adjusted by image attrs."""
|
||||||
scale = self.get_image_scale(node)
|
scale = self.get_image_scale(node)
|
||||||
width = self.get_image_width_height(node, 'width')
|
width, width_unit = self.get_image_width_height(node, 'width')
|
||||||
height = self.get_image_width_height(node, 'height')
|
height, _ = self.get_image_width_height(node, 'height')
|
||||||
|
|
||||||
dpi = (72, 72)
|
dpi = (72, 72)
|
||||||
if PIL 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]
|
filename, destination = self.image_dict[source]
|
||||||
imageobj = PIL.Image.open(filename, 'r')
|
imageobj = PIL.Image.open(filename, 'r')
|
||||||
dpi = imageobj.info.get('dpi', dpi)
|
dpi = imageobj.info.get('dpi', dpi)
|
||||||
# dpi information can be (xdpi, ydpi) or xydpi
|
# dpi information can be (xdpi, ydpi) or xydpi
|
||||||
try: iter(dpi)
|
try:
|
||||||
except: dpi = (dpi, dpi)
|
iter(dpi)
|
||||||
|
except:
|
||||||
|
dpi = (dpi, dpi)
|
||||||
else:
|
else:
|
||||||
imageobj = None
|
imageobj = None
|
||||||
|
|
||||||
if width is None or height is None:
|
if width is None or height is None:
|
||||||
if imageobj is None:
|
if imageobj is None:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
'image size not fully specified and PIL not installed')
|
'image size not fully specified and PIL not installed')
|
||||||
if width is None: width = [imageobj.size[0], 'px']
|
if width is None:
|
||||||
if height is None: height = [imageobj.size[1], 'px']
|
width = imageobj.size[0]
|
||||||
|
width = float(width) * 0.026 # convert px to cm
|
||||||
|
if height is None:
|
||||||
|
height = imageobj.size[1]
|
||||||
|
height = float(height) * 0.026 # convert px to cm
|
||||||
|
if width_unit == '%':
|
||||||
|
factor = width
|
||||||
|
image_width = imageobj.size[0]
|
||||||
|
image_width = float(image_width) * 0.026 # convert px to cm
|
||||||
|
image_height = imageobj.size[1]
|
||||||
|
image_height = float(image_height) * 0.026 # convert px to cm
|
||||||
|
line_width = self.get_page_width()
|
||||||
|
width = factor * line_width
|
||||||
|
factor = (factor * line_width) / image_width
|
||||||
|
height = factor * image_height
|
||||||
|
width *= scale
|
||||||
|
height *= scale
|
||||||
|
width = '%.2fcm' % width
|
||||||
|
height = '%.2fcm' % height
|
||||||
|
return width, height
|
||||||
|
|
||||||
width[0] *= scale
|
def get_page_width(self):
|
||||||
height[0] *= scale
|
"""Return the document's page width in centimeters."""
|
||||||
if width[1] == 'px': width = [width[0] / dpi[0], 'in']
|
root = self.get_dom_stylesheet()
|
||||||
if height[1] == 'px': height = [height[0] / dpi[1], 'in']
|
nodes = root.iterfind(
|
||||||
|
'.//{urn:oasis:names:tc:opendocument:xmlns:style:1.0}'
|
||||||
width[0] = str(width[0])
|
'page-layout/'
|
||||||
height[0] = str(height[0])
|
'{urn:oasis:names:tc:opendocument:xmlns:style:1.0}'
|
||||||
return ''.join(width), ''.join(height)
|
'page-layout-properties')
|
||||||
|
width = None
|
||||||
|
for node in nodes:
|
||||||
|
page_width = node.get(
|
||||||
|
'{urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0}'
|
||||||
|
'page-width')
|
||||||
|
margin_left = node.get(
|
||||||
|
'{urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0}'
|
||||||
|
'margin-left')
|
||||||
|
margin_right = node.get(
|
||||||
|
'{urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0}'
|
||||||
|
'margin-right')
|
||||||
|
if (page_width is None or
|
||||||
|
margin_left is None or
|
||||||
|
margin_right is None):
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
page_width, _ = self.convert_to_cm(page_width)
|
||||||
|
margin_left, _ = self.convert_to_cm(margin_left)
|
||||||
|
margin_right, _ = self.convert_to_cm(margin_right)
|
||||||
|
except ValueError, exp:
|
||||||
|
self.document.reporter.warning(
|
||||||
|
'Stylesheet file contains invalid page width '
|
||||||
|
'or margin size.')
|
||||||
|
width = page_width - margin_left - margin_right
|
||||||
|
if width is None:
|
||||||
|
# We can't find the width in styles, so we make a guess.
|
||||||
|
# Use a width of 6 in = 15.24 cm.
|
||||||
|
width = 15.24
|
||||||
|
return width
|
||||||
|
|
||||||
def generate_figure(self, node, source, destination, current_element):
|
def generate_figure(self, node, source, destination, current_element):
|
||||||
caption = None
|
caption = None
|
||||||
|
@ -2222,6 +2408,7 @@ class ODFTranslator(nodes.GenericNodeVisitor):
|
||||||
el2 = SubElement(el1, 'style:text-properties',
|
el2 = SubElement(el1, 'style:text-properties',
|
||||||
attrib=attrib, nsdict=SNSD)
|
attrib=attrib, nsdict=SNSD)
|
||||||
style_name = 'rstframestyle%d' % self.image_style_count
|
style_name = 'rstframestyle%d' % self.image_style_count
|
||||||
|
draw_name = 'graphics%d' % IMAGE_NAME_COUNTER.next()
|
||||||
# Add the styles
|
# Add the styles
|
||||||
attrib = {
|
attrib = {
|
||||||
'style:name': style_name,
|
'style:name': style_name,
|
||||||
|
@ -2252,7 +2439,7 @@ class ODFTranslator(nodes.GenericNodeVisitor):
|
||||||
'style:graphic-properties', attrib=attrib, nsdict=SNSD)
|
'style:graphic-properties', attrib=attrib, nsdict=SNSD)
|
||||||
attrib = {
|
attrib = {
|
||||||
'draw:style-name': style_name,
|
'draw:style-name': style_name,
|
||||||
'draw:name': 'Frame1',
|
'draw:name': draw_name,
|
||||||
'text:anchor-type': 'paragraph',
|
'text:anchor-type': 'paragraph',
|
||||||
'draw:z-index': '0',
|
'draw:z-index': '0',
|
||||||
}
|
}
|
||||||
|
@ -2326,12 +2513,13 @@ class ODFTranslator(nodes.GenericNodeVisitor):
|
||||||
attrib['style:wrap'] = 'none'
|
attrib['style:wrap'] = 'none'
|
||||||
el2 = SubElement(el1,
|
el2 = SubElement(el1,
|
||||||
'style:graphic-properties', attrib=attrib, nsdict=SNSD)
|
'style:graphic-properties', attrib=attrib, nsdict=SNSD)
|
||||||
|
draw_name = 'graphics%d' % IMAGE_NAME_COUNTER.next()
|
||||||
# Add the content.
|
# Add the content.
|
||||||
#el = SubElement(current_element, 'text:p',
|
#el = SubElement(current_element, 'text:p',
|
||||||
# attrib={'text:style-name': self.rststyle('textbody')})
|
# attrib={'text:style-name': self.rststyle('textbody')})
|
||||||
attrib={
|
attrib={
|
||||||
'draw:style-name': style_name,
|
'draw:style-name': style_name,
|
||||||
'draw:name': 'graphics2',
|
'draw:name': draw_name,
|
||||||
'draw:z-index': '1',
|
'draw:z-index': '1',
|
||||||
}
|
}
|
||||||
if isinstance(node.parent, nodes.TextElement):
|
if isinstance(node.parent, nodes.TextElement):
|
||||||
|
@ -2399,14 +2587,26 @@ class ODFTranslator(nodes.GenericNodeVisitor):
|
||||||
|
|
||||||
def visit_inline(self, node):
|
def visit_inline(self, node):
|
||||||
styles = node.attributes.get('classes', ())
|
styles = node.attributes.get('classes', ())
|
||||||
if len(styles) > 0:
|
if styles:
|
||||||
inline_style = styles[0]
|
el = self.current_element
|
||||||
el = SubElement(self.current_element, 'text:span',
|
for inline_style in styles:
|
||||||
attrib={'text:style-name': self.rststyle(inline_style)})
|
el = SubElement(el, 'text:span',
|
||||||
|
attrib={'text:style-name':
|
||||||
|
self.rststyle(inline_style)})
|
||||||
|
count = len(styles)
|
||||||
|
else:
|
||||||
|
# No style was specified so use a default style (old code
|
||||||
|
# crashed if no style was given)
|
||||||
|
el = SubElement(self.current_element, 'text:span')
|
||||||
|
count = 1
|
||||||
|
|
||||||
self.set_current_element(el)
|
self.set_current_element(el)
|
||||||
|
self.inline_style_count_stack.append(count)
|
||||||
|
|
||||||
def depart_inline(self, node):
|
def depart_inline(self, node):
|
||||||
self.set_to_parent()
|
count = self.inline_style_count_stack.pop()
|
||||||
|
for x in range(count):
|
||||||
|
self.set_to_parent()
|
||||||
|
|
||||||
def _calculate_code_block_padding(self, line):
|
def _calculate_code_block_padding(self, line):
|
||||||
count = 0
|
count = 0
|
||||||
|
@ -3251,14 +3451,19 @@ class ODFTranslator(nodes.GenericNodeVisitor):
|
||||||
depart_admonition = depart_warning
|
depart_admonition = depart_warning
|
||||||
|
|
||||||
def generate_admonition(self, node, label, title=None):
|
def generate_admonition(self, node, label, title=None):
|
||||||
el1 = SubElement(self.current_element, 'text:p', attrib = {
|
if hasattr(self.language, 'labels'):
|
||||||
'text:style-name': self.rststyle('admon-%s-hdr', ( label, )),
|
translated_label = self.language.labels[label]
|
||||||
})
|
else:
|
||||||
|
translated_label = label
|
||||||
|
el1 = SubElement(self.current_element, 'text:p', attrib={
|
||||||
|
'text:style-name': self.rststyle(
|
||||||
|
'admon-%s-hdr', (label, )),
|
||||||
|
})
|
||||||
if title:
|
if title:
|
||||||
el1.text = title
|
el1.text = title
|
||||||
else:
|
else:
|
||||||
el1.text = '%s!' % (label.capitalize(), )
|
el1.text = '%s!' % (translated_label.capitalize(), )
|
||||||
s1 = self.rststyle('admon-%s-body', ( label, ))
|
s1 = self.rststyle('admon-%s-body', (label, ))
|
||||||
self.paragraph_style_stack.append(s1)
|
self.paragraph_style_stack.append(s1)
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
:Author: David Goodger
|
:Author: David Goodger
|
||||||
:Contact: goodger@python.org
|
:Contact: goodger@python.org
|
||||||
:date: $Date: 2006-05-21 22:44:42 +0200 (Son, 21. Mai 2006) $
|
:date: $Date: 2006-05-21 22:44:42 +0200 (So, 21 Mai 2006) $
|
||||||
:version: $Revision: 4564 $
|
:version: $Revision: 4564 $
|
||||||
:copyright: This stylesheet has been placed in the public domain.
|
:copyright: This stylesheet has been placed in the public domain.
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# :Author: Günter Milde <milde@users.sourceforge.net>
|
# :Author: Günter Milde <milde@users.sourceforge.net>
|
||||||
# :Revision: $Revision: 7668 $
|
# :Revision: $Revision: 8046 $
|
||||||
# :Date: $Date: 2013-06-04 14:46:30 +0200 (Die, 04. Jun 2013) $
|
# :Date: $Date: 2017-03-11 13:09:36 +0100 (Sa, 11 Mär 2017) $
|
||||||
# :Copyright: © 2010 Günter Milde.
|
# :Copyright: © 2010 Günter Milde.
|
||||||
# :License: Released under the terms of the `2-Clause BSD license`_, in short:
|
# :License: Released under the terms of the `2-Clause BSD license`_, in short:
|
||||||
#
|
#
|
||||||
|
@ -17,8 +17,9 @@
|
||||||
"""
|
"""
|
||||||
XeLaTeX document tree Writer.
|
XeLaTeX document tree Writer.
|
||||||
|
|
||||||
A variant of Docutils' standard 'latex2e' writer producing output
|
A variant of Docutils' standard 'latex2e' writer producing LaTeX output
|
||||||
suited for processing with XeLaTeX (http://tug.org/xetex/).
|
suited for processing with the Unicode-aware TeX engines
|
||||||
|
LuaTeX and XeTeX.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__docformat__ = 'reStructuredText'
|
__docformat__ = 'reStructuredText'
|
||||||
|
@ -32,9 +33,9 @@ from docutils import frontend, nodes, utils, writers, languages
|
||||||
from docutils.writers import latex2e
|
from docutils.writers import latex2e
|
||||||
|
|
||||||
class Writer(latex2e.Writer):
|
class Writer(latex2e.Writer):
|
||||||
"""A writer for Unicode-based LaTeX variants (XeTeX, LuaTeX)"""
|
"""A writer for Unicode-aware LaTeX variants (XeTeX, LuaTeX)"""
|
||||||
|
|
||||||
supported = ('xetex','xelatex','luatex')
|
supported = ('lxtex', 'xetex','xelatex','luatex', 'lualatex')
|
||||||
"""Formats this writer supports."""
|
"""Formats this writer supports."""
|
||||||
|
|
||||||
default_template = 'xelatex.tex'
|
default_template = 'xelatex.tex'
|
||||||
|
@ -54,7 +55,7 @@ class Writer(latex2e.Writer):
|
||||||
template=('Template file. Default: "%s".' % default_template,
|
template=('Template file. Default: "%s".' % default_template,
|
||||||
['--template'], {'default': default_template, 'metavar': '<file>'}),
|
['--template'], {'default': default_template, 'metavar': '<file>'}),
|
||||||
latex_preamble=('Customization by LaTeX code in the preamble. '
|
latex_preamble=('Customization by LaTeX code in the preamble. '
|
||||||
'Default: select PDF standard fonts (Times, Helvetica, Courier).',
|
'Default: select "Linux Libertine" fonts.',
|
||||||
['--latex-preamble'],
|
['--latex-preamble'],
|
||||||
{'default': default_preamble}),
|
{'default': default_preamble}),
|
||||||
)
|
)
|
||||||
|
@ -98,6 +99,11 @@ class Babel(latex2e.Babel):
|
||||||
for key in ('af', # 'afrikaans',
|
for key in ('af', # 'afrikaans',
|
||||||
'de-AT', # 'naustrian',
|
'de-AT', # 'naustrian',
|
||||||
'de-AT-1901', # 'austrian',
|
'de-AT-1901', # 'austrian',
|
||||||
|
# TODO: use variant=... for English variants
|
||||||
|
'en-CA', # 'canadian',
|
||||||
|
'en-GB', # 'british',
|
||||||
|
'en-NZ', # 'newzealand',
|
||||||
|
'en-US', # 'american',
|
||||||
'fr-CA', # 'canadien',
|
'fr-CA', # 'canadien',
|
||||||
'grc-ibycus', # 'ibycus', (Greek Ibycus encoding)
|
'grc-ibycus', # 'ibycus', (Greek Ibycus encoding)
|
||||||
'sr-Latn', # 'serbian script=latin'
|
'sr-Latn', # 'serbian script=latin'
|
||||||
|
@ -109,12 +115,12 @@ class Babel(latex2e.Babel):
|
||||||
self.reporter = reporter
|
self.reporter = reporter
|
||||||
self.language = self.language_name(language_code)
|
self.language = self.language_name(language_code)
|
||||||
self.otherlanguages = {}
|
self.otherlanguages = {}
|
||||||
self.warn_msg = 'Language "%s" not supported by XeTeX (polyglossia).'
|
self.warn_msg = 'Language "%s" not supported by Polyglossia.'
|
||||||
self.quote_index = 0
|
self.quote_index = 0
|
||||||
self.quotes = ('"', '"')
|
self.quotes = ('"', '"')
|
||||||
# language dependent configuration:
|
# language dependent configuration:
|
||||||
# double quotes are "active" in some languages (e.g. German).
|
# double quotes are "active" in some languages (e.g. German).
|
||||||
self.literal_double_quote = u'"' # TODO: use \textquotedbl
|
self.literal_double_quote = u'"' # TODO: use \textquotedbl ?
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
setup = [r'\usepackage{polyglossia}',
|
setup = [r'\usepackage{polyglossia}',
|
||||||
|
@ -126,6 +132,12 @@ class Babel(latex2e.Babel):
|
||||||
|
|
||||||
|
|
||||||
class XeLaTeXTranslator(latex2e.LaTeXTranslator):
|
class XeLaTeXTranslator(latex2e.LaTeXTranslator):
|
||||||
|
"""
|
||||||
|
Generate code for LaTeX using Unicode fonts (XeLaTex or LuaLaTeX).
|
||||||
|
|
||||||
|
See the docstring of docutils.writers._html_base.HTMLTranslator for
|
||||||
|
notes on and examples of safe subclassing.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, document):
|
def __init__(self, document):
|
||||||
self.is_xetex = True # typeset with XeTeX or LuaTeX engine
|
self.is_xetex = True # typeset with XeTeX or LuaTeX engine
|
||||||
|
|
|
@ -358,7 +358,10 @@ class FoldingPanel(Panel):
|
||||||
self.sizeHint().height())
|
self.sizeHint().height())
|
||||||
if self._native:
|
if self._native:
|
||||||
if os.environ['QT_API'].lower() not in PYQT5_API:
|
if os.environ['QT_API'].lower() not in PYQT5_API:
|
||||||
opt = QtGui.QStyleOptionViewItemV2()
|
try:
|
||||||
|
opt = QtGui.QStyleOptionViewItemV2()
|
||||||
|
except:
|
||||||
|
opt = QtWidgets.QStyleOptionViewItem()
|
||||||
else:
|
else:
|
||||||
opt = QtWidgets.QStyleOptionViewItem()
|
opt = QtWidgets.QStyleOptionViewItem()
|
||||||
opt.rect = rect
|
opt.rect = rect
|
||||||
|
|
|
@ -58,7 +58,7 @@ __version__ = '2.10.0'
|
||||||
#: Qt API environment variable name
|
#: Qt API environment variable name
|
||||||
QT_API = 'QT_API'
|
QT_API = 'QT_API'
|
||||||
#: names of the expected PyQt5 api
|
#: names of the expected PyQt5 api
|
||||||
PYQT5_API = ['pyqt5']
|
PYQT5_API = ['pyqt5','pyside2']
|
||||||
#: names of the expected PyQt4 api
|
#: names of the expected PyQt4 api
|
||||||
PYQT4_API = [
|
PYQT4_API = [
|
||||||
'pyqt', # name used in IPython.qt
|
'pyqt', # name used in IPython.qt
|
||||||
|
|
Loading…
Reference in New Issue
Block a user