Author: milde Date: 2009-08-28 20:43:52 +0200 (Fri, 28 Aug 2009) New Revision: 6105 Added: trunk/docutils/docutils/_string_template_compat.py trunk/docutils/docutils/writers/latex2e/template.tex Modified: trunk/docutils/HISTORY.txt trunk/docutils/RELEASE-NOTES.txt trunk/docutils/docs/dev/todo.txt trunk/docutils/docutils/writers/latex2e/__init__.py Log: latex2e writer: Use template (file and configuration option). Modified: trunk/docutils/HISTORY.txt =================================================================== --- trunk/docutils/HISTORY.txt 2009-08-28 18:29:11 UTC (rev 6104) +++ trunk/docutils/HISTORY.txt 2009-08-28 18:43:52 UTC (rev 6105) @@ -114,6 +114,7 @@ - Float placement made configurable, default changed to "here definitely". - Typeset generic topic as "quote block with title". - More stable implementation of ``--use-titlepage-env``. + - Use template (file and configuration option). * docutils/writers/manpage.py Modified: trunk/docutils/RELEASE-NOTES.txt =================================================================== --- trunk/docutils/RELEASE-NOTES.txt 2009-08-28 18:29:11 UTC (rev 6104) +++ trunk/docutils/RELEASE-NOTES.txt 2009-08-28 18:43:52 UTC (rev 6105) @@ -58,6 +58,7 @@ - Use class defaults for page margins ('typearea' now optional). - Float placement made configurable, default changed to "here definitely". - Typeset generic topic as "quote with title". + - Use template (file and configuration option). * ODT writer: Modified: trunk/docutils/docs/dev/todo.txt =================================================================== --- trunk/docutils/docs/dev/todo.txt 2009-08-28 18:29:11 UTC (rev 6104) +++ trunk/docutils/docs/dev/todo.txt 2009-08-28 18:43:52 UTC (rev 6105) @@ -1060,7 +1060,8 @@ * Add _`math markup`. We should try for a general solution, that's applicable to any output format. Using a standard, such as MathML_, would be best. TeX (or itex_) would be acceptable as a *front-end* - to MathML. See `the culmination of a relevant discussion + to MathML. An simpler, alternative input format is defined by + ASCIIMathML_. See `the culmination of a relevant discussion <http://article.gmane.org/gmane.text.docutils.user/118>`__. Both a directive and an interpreted text role will be necessary (for @@ -1076,6 +1077,7 @@ .. _MathML: http://www.w3.org/TR/MathML2/ .. _itex: http://pear.math.pitt.edu/mathzilla/itex2mmlItex.html + .. _ASCIIMathML: http://www1.chapman.edu/~jipsen/mathml/asciimath.html * How about a syntax for alternative hyperlink behavior, such as "open in a new window" (as in HTML's ``<a target="_blank">``)? Double @@ -1909,22 +1911,20 @@ See `<../../test/functional/input/data/latex.txt>`__ -* Too deeply nested lists fail: generate an error, a warning or provide - a workaround? +* Too deeply nested lists fail: generate a warning and provide + a workaround. * Symbol footnotes fail with "use_latex_footnotes". + For a possible fix see + http://help-csli.stanford.edu/tex/latex-footnotes.shtml + Generate clean and configurable LaTeX source ---------------------------------------------- * Check the generated source with package `nag`. -LaTeX macros for Docutils-specific objects -`````````````````````````````````````````` - -:subtitle: Is there a package or native construct? - Configurable placement of figure and table floats ````````````````````````````````````````````````` @@ -1960,10 +1960,6 @@ + No "fancy" or "exotic" requirements. - Or provide fallback solutions in case the required packages do not exist - on the target system? (Can be done with ``\@ifpackageloaded{}`` or - ``\IfPackageExists{}``.) - + pointers to advanced packages and their use in the `latex writer documentation`_. @@ -1998,14 +1994,51 @@ happen when using configuration files), the spaces in front of footnote references aren't trimmed. - .. Footnote related packages (found with ``locate *foot*sty``):: + .. Footnote packages: + + :footmisc: texlive-latex-extra + :manyfoot: texlive-latex-extra + :bigfoot: texlive-latex-extra + :footnote: texlive-latex-recommended + :perpage: texlive-latex-extra - bigfoot.sty, eskdfootnote.sty, fixfoot.sty, footbib.sty, - footmisc.sty, footnpag.sty, mdwtools/footnote.sty, - ncctools/manyfoot.sty, ncctools/nccfoots.sty, pdfcolfoot.sty, - titlefoot.sty, yafoot/dblfnote.sty, yafoot/fnpos.sty, - yafoot/pfnote.sty + .. Footnote FAQs: + `Footnotes whose texts are identical + <http://www.tex.ac.uk/cgi-bin/texfaq2html?label=repfootnote>`__ + + * label per hand or use footmisc + + `More than one sequence of footnotes + <http://www.tex.ac.uk/cgi-bin/texfaq2html?label=multfoot>`__ + (manyfoot, bigfoot) + + `Footnotes in tables + <http://www.tex.ac.uk/cgi-bin/texfaq2html?label=footintab>`__ + + * `tabularx` and longtable allow footnotes. + * `footnote` provides an savenotes which collects all + footnotes and emits them at the end of the environment + + `Footnotes in LaTeX section headings + <http://www.tex.ac.uk/cgi-bin/texfaq2html?label=ftnsect>`__ + + * Take advantage of the fact that the mandatory argument doesn\u2019t + \u2018move\u2019 if the optional argument is present:: + + \section[title] {title\footnote{title ftnt}} + + * Use the footmisc package, with package option stable - this modifies + footnotes so that they softly and silently vanish away if used in a + moving argument. + + `Footnotes numbered \u201cper page\u201d + <http://www.tex.ac.uk/cgi-bin/texfaq2html?label=footnpp>`__ + + * perpage provides a general mechanism for resetting counters per page + * footmisc provides a package option perpage + + * enumeration environment, field list use `mdwlist` from texlive-latex-recommended? @@ -2067,6 +2100,11 @@ * Configurable `classifier` in description list? \emph instead of bold as default? +* More space between title and subtitle? :: + + - \\ % subtitle% + + \\[0.5em] % subtitle% + __ ../../../sandbox/latex-variants/README.html#default-font .. _PSNFSS documentation: @@ -2147,8 +2185,8 @@ Missing features ---------------- -* test and document selection of LaTeX fontsize. - +* test and document selection of LaTeX fontsize. + Add font size in points to the document options, e.g. ``--documentoptions=12``, use extsize or some other package for values other than [10,11,12]. @@ -2180,33 +2218,6 @@ Put in place of the to-be-implemented "citations" directive (see `Footnote & Citation Gathering`_). -* Provide a ``--default-dpi`` (or better named) option to set the size of a - pixel (lenght unit px)? - - You can do this already with:: - - \pdfpxdimen=1in % 1 DPI - \divide\pdfpxdimen by 92 % 92 DPI - - in a style sheet. So which should take precedence (or just leave it)? - -template file -````````````` - -Using a template file instead of hard-coded string literals for the -skeleton of the exported LaTeX file would provide improved configurability. -A power user could replace the template with a custom version, -e.g. to overcome issues with order of package loading or suppressing some -parts. - -* Template Strings, ``from string import Template``, provide a suitable - syntax (shell-like $something substitution) but are new in version 2.4. - - For 2.3 compatibility, %-substitution is needed, which is less readable - (and LaTeX' comment sign '%' must be escaped). - - -> provide a 2.3 compatibility implementation? - Unicode to LaTeX with ``unicodesymbols`` file from LyX `````````````````````````````````````````````````````` Added: trunk/docutils/docutils/_string_template_compat.py =================================================================== --- trunk/docutils/docutils/_string_template_compat.py 2009-08-28 18:29:11 UTC (rev 6104) +++ trunk/docutils/docutils/_string_template_compat.py 2009-08-28 18:43:52 UTC (rev 6105) @@ -0,0 +1,133 @@ +#!/usr/bin/env python +# -*- coding: utf8 -*- + +# string_template_compat.py: string.Template for Python <= 2.4 +# ===================================================== + +# This is just an excerpt of the standard string module to provide backwards +# compatibility. + +import re as _re + +class _multimap: + """Helper class for combining multiple mappings. + + Used by .{safe_,}substitute() to combine the mapping and keyword + arguments. + """ + def __init__(self, primary, secondary): + self._primary = primary + self._secondary = secondary + + def __getitem__(self, key): + try: + return self._primary[key] + except KeyError: + return self._secondary[key] + + +class _TemplateMetaclass(type): + pattern = r""" + %(delim)s(?: + (?P<escaped>%(delim)s) | # Escape sequence of two delimiters + (?P<named>%(id)s) | # delimiter and a Python identifier + {(?P<braced>%(id)s)} | # delimiter and a braced identifier + (?P<invalid>) # Other ill-formed delimiter exprs + ) + """ + + def __init__(cls, name, bases, dct): + super(_TemplateMetaclass, cls).__init__(name, bases, dct) + if 'pattern' in dct: + pattern = cls.pattern + else: + pattern = _TemplateMetaclass.pattern % { + 'delim' : _re.escape(cls.delimiter), + 'id' : cls.idpattern, + } + cls.pattern = _re.compile(pattern, _re.IGNORECASE | _re.VERBOSE) + + +class Template: + """A string class for supporting $-substitutions.""" + __metaclass__ = _TemplateMetaclass + + delimiter = '$' + idpattern = r'[_a-z][_a-z0-9]*' + + def __init__(self, template): + self.template = template + + # Search for $$, $identifier, ${identifier}, and any bare $'s + + def _invalid(self, mo): + i = mo.start('invalid') + lines = self.template[:i].splitlines(True) + if not lines: + colno = 1 + lineno = 1 + else: + colno = i - len(''.join(lines[:-1])) + lineno = len(lines) + raise ValueError('Invalid placeholder in string: line %d, col %d' % + (lineno, colno)) + + def substitute(self, *args, **kws): + if len(args) > 1: + raise TypeError('Too many positional arguments') + if not args: + mapping = kws + elif kws: + mapping = _multimap(kws, args[0]) + else: + mapping = args[0] + # Helper function for .sub() + def convert(mo): + # Check the most common path first. + named = mo.group('named') or mo.group('braced') + if named is not None: + val = mapping[named] + # We use this idiom instead of str() because the latter will + # fail if val is a Unicode containing non-ASCII characters. + return '%s' % (val,) + if mo.group('escaped') is not None: + return self.delimiter + if mo.group('invalid') is not None: + self._invalid(mo) + raise ValueError('Unrecognized named group in pattern', + self.pattern) + return self.pattern.sub(convert, self.template) + + def safe_substitute(self, *args, **kws): + if len(args) > 1: + raise TypeError('Too many positional arguments') + if not args: + mapping = kws + elif kws: + mapping = _multimap(kws, args[0]) + else: + mapping = args[0] + # Helper function for .sub() + def convert(mo): + named = mo.group('named') + if named is not None: + try: + # We use this idiom instead of str() because the latter + # will fail if val is a Unicode containing non-ASCII + return '%s' % (mapping[named],) + except KeyError: + return self.delimiter + named + braced = mo.group('braced') + if braced is not None: + try: + return '%s' % (mapping[braced],) + except KeyError: + return self.delimiter + '{' + braced + '}' + if mo.group('escaped') is not None: + return self.delimiter + if mo.group('invalid') is not None: + return self.delimiter + raise ValueError('Unrecognized named group in pattern', + self.pattern) + return self.pattern.sub(convert, self.template) + Property changes on: trunk/docutils/docutils/_string_template_compat.py ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native Modified: trunk/docutils/docutils/writers/latex2e/__init__.py =================================================================== --- trunk/docutils/docutils/writers/latex2e/__init__.py 2009-08-28 18:29:11 UTC (rev 6104) +++ trunk/docutils/docutils/writers/latex2e/__init__.py 2009-08-28 18:43:52 UTC (rev 6105) @@ -16,14 +16,23 @@ import time import re import string +import docutils from docutils import frontend, nodes, languages, writers, utils, transforms from docutils.writers.newlatex2e import unicode_map +# compatibility module for Python <= 2.4 +if not hasattr(string, 'Template'): + import docutils._string_template_compat + string.Template = docutils._string_template_compat.Template + class Writer(writers.Writer): supported = ('latex','latex2e') """Formats this writer supports.""" + default_template = 'template.tex' + default_template_path = os.path.dirname(__file__) + settings_spec = ( 'LaTeX-Specific Options', 'The LaTeX "--output-encoding" default is "latin-1:strict".', @@ -55,7 +64,7 @@ ['--attribution'], {'choices': ['dash', 'parentheses', 'parens', 'none'], 'default': 'dash', 'metavar': '<format>'}), - ('Specify LaTeX packages/stylesheets. ' + ('Specify LaTeX packages/stylesheets. ' ' A style is referenced with \\usepackage if extension is ' '".sty" or omitted and with \\input else. ' ' Overrides previous --stylesheet and --stylesheet-path settings.', @@ -68,7 +77,7 @@ {'metavar': '<file>', 'overrides': 'stylesheet'}), ('Embed the stylesheet in the output LaTeX file. The stylesheet ' 'file must be accessible during processing. ' - ' Default: link to stylesheets', + 'Default: link to stylesheets', ['--embed-stylesheet'], {'default': 0, 'action': 'store_true', 'validator': frontend.validate_boolean}), @@ -76,6 +85,9 @@ ' This is the default (if not changed in a config file).', ['--link-stylesheet'], {'dest': 'embed_stylesheet', 'action': 'store_false'}), + ('Specify the template file. Default: "%s".' % default_template, + ['--template'], + {'default': default_template, 'metavar': '<file>'}), ('Table of contents by Docutils (default) or LaTeX. ' '(Docutils does not know of pagenumbers.) ', ['--use-latex-toc'], @@ -196,11 +208,26 @@ def translate(self): visitor = self.translator_class(self.document) self.document.walkabout(visitor) - self.output = visitor.astext() # copy parts - for attr in self.visitor_attributes: - setattr(self, attr, getattr(visitor, attr)) + for part in visitor_attributes: + setattr(self, part, getattr(visitor, part)) + self.output = self.apply_template() + def apply_template(self): + # Get template string from file + try: + file = open(self.document.settings.template, 'rb') + except IOError: + file = open(os.path.join(os.path.dirname(__file__), + self.document.settings.template), 'rb') + template = string.Template(file.read()) + file.close() + # create dictionary of substitutions + subs = self.assemble_parts() + subs['encoding'] = self.document.settings.output_encoding + subs['version'] = docutils.__version__ + return template.substitute(subs) + def assemble_parts(self): writers.Writer.assemble_parts(self) for part in self.visitor_attributes: @@ -209,6 +236,7 @@ self.parts[part] = ''.join(getattr(self, part)) else: self.parts[part] = '\n'.join(getattr(self, part)) + return self.parts class Babel(object): @@ -773,8 +801,6 @@ linking = PreambleCmds.linking # if false, hyperref is not loaded # TODO: use a config value? - generator = '% generated by Docutils <http://docutils.sourceforge.net/>' - # Config setting defaults # ----------------------- @@ -923,7 +949,7 @@ # packages and/or stylesheets # --------------------------- - self.stylesheet = ['\n%%% User specified packages and stylesheets'] + self.stylesheet = [] # get list of style sheets from settings styles = utils.get_stylesheet_list(settings) # adapt path if --stylesheet_path is used @@ -947,10 +973,11 @@ self.stylesheet.append(r'\usepackage{%s}' % base) else: self.stylesheet.append(r'\input{%s}' % sheet) + if self.stylesheet: + self.stylesheet.append('') # trailing blank line # Part of LaTeX preamble before style sheet(s) self.head_prefix = [ - self.generator, self.latex_head % (self.d_options,self.settings.documentclass), ## '%%% Requirements', # multi-language support (language is in document settings) @@ -980,9 +1007,9 @@ # an empty string supresses the "auto-date" feature of \maketitle self.date = '' - self.body_prefix = ['\n%%% Body\n\\begin{document}\n'] + self.body_prefix = ['\\begin{document}\n'] self.body = [] - self.body_suffix = ['\n\\end{document}\n'] + self.body_suffix = ['\\end{document}'] self.context = [] # Where to collect the output of visitor methods @@ -1477,20 +1504,19 @@ def visit_docinfo(self, node): self.out = self.docinfo - self.out.append('\n% Docinfo\n' - '\\begin{center}\n' - '\\begin{tabularx}{\\DUdocinfowidth}{lX}\n') def depart_docinfo(self, node): self.out = self.body # Some itmes (e.g. author) end up at other places - if len(self.docinfo) == 1: - self.docinfo = [] - else: + if self.docinfo: # tabularx: automatic width of columns, no page breaks allowed. self.requirements['tabularx'] = r'\usepackage{tabularx}' self.fallbacks['_providelength'] = PreambleCmds.providelength self.fallbacks['docinfo'] = PreambleCmds.docinfo + # + self.docinfo.insert(0, '\n% Docinfo\n' + '\\begin{center}\n' + '\\begin{tabularx}{\\DUdocinfowidth}{lX}\n') self.docinfo.append('\\end{tabularx}\n' '\\end{center}\n') @@ -1548,8 +1574,6 @@ # a) conditional requirements (before style sheet) self.head_prefix += self.requirements.sortedvalues() # b) coditional fallback definitions (after style sheet) - self.head.append( - '\n%%% Fallback definitions for Docutils-specific commands') self.head += self.fallbacks.sortedvalues() # c) hyperlink setup and PDF metadata self.head.append(self.linking % (self.colorlinks, @@ -1576,7 +1600,7 @@ self.date)) # docinfo might alse be given for a document without title self.body_prefix += self.docinfo - if ((self.title or self.author_stack) and + if ((self.title or self.author_stack) and self.settings.use_titlepage_env): self.body_prefix.append('\\thispagestyle{empty}\n' '\\end{titlepage}') @@ -1844,6 +1868,15 @@ def visit_footnote_reference(self, node): if self.use_latex_footnotes: + # TODO: insert footnote content at (or near) this place + # print "footnote-ref to", node['refid'] + # footnotes = (self.document.footnotes + + # self.document.autofootnotes + + # self.document.symbol_footnotes) + # for footnote in footnotes: + # # print footnote['ids'] + # if node.get('refid', '') in footnote['ids']: + # print 'matches', footnote['ids'] self.out.append('\\footnotemark['+self.encode(node.astext())+']') raise nodes.SkipNode href = '' Added: trunk/docutils/docutils/writers/latex2e/template.tex =================================================================== --- trunk/docutils/docutils/writers/latex2e/template.tex 2009-08-28 18:29:11 UTC (rev 6104) +++ trunk/docutils/docutils/writers/latex2e/template.tex 2009-08-28 18:43:52 UTC (rev 6105) @@ -0,0 +1,11 @@ +% generated by Docutils <http://docutils.sourceforge.net/> +$head_prefix + +%%% User specified packages and stylesheets +$stylesheet +%%% Fallback definitions for Docutils-specific commands +$head + +%%% Body +$body_prefix$body +$body_suffix Property changes on: trunk/docutils/docutils/writers/latex2e/template.tex ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native |