From cc3e4fba75c20196bfb687190eb1f784b09222e0 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Wed, 6 Jul 2016 21:00:49 +0900 Subject: [PATCH] Jinja2-ize latex writer --- sphinx/templates/latex/content.tex_t | 42 ++++++++++++++++++++ sphinx/util/template.py | 57 ++++++++++++++++++++++++++++ sphinx/writers/latex.py | 54 ++++---------------------- 3 files changed, 106 insertions(+), 47 deletions(-) create mode 100644 sphinx/templates/latex/content.tex_t create mode 100644 sphinx/util/template.py diff --git a/sphinx/templates/latex/content.tex_t b/sphinx/templates/latex/content.tex_t new file mode 100644 index 000000000..fb5b1decd --- /dev/null +++ b/sphinx/templates/latex/content.tex_t @@ -0,0 +1,42 @@ +%% Generated by Sphinx. +\def\sphinxdocclass{<%= docclass %>} +\newif\ifsphinxKeepOldNames <%= keepoldnames %> +\documentclass[<%= papersize %>,<%= pointsize %><%= classoptions %>]{<%= wrapperclass %>} +\ifdefined\pdfpxdimen + \let\sphinxpxdimen\pdfpxdimen\else\newdimen\sphinxpxdimen +\fi \sphinxpxdimen=<%= pxunit %>\relax +\usepackage{iftex} +<%= passoptionstopackages %> +<%= inputenc %> +<%= utf8extra %> +<%= cmappkg %> +<%= fontenc %> +<%= amsmath %> +<%= babel %> +<%= fontpkg %> +<%= fncychap %> +<%= longtable %> +\usepackage{sphinx} +\usepackage{multirow} +\usepackage{eqparbox} +<%= usepackages %> +<%= contentsname %> +<%= numfig_format %> +<%= pageautorefname %> +<%= tocdepth %> +<%= secnumdepth %> +<%= preamble %> + +\title{<%= title %>} +\date{<%= date %>} +\release{<%= release %>} +\author{<%= author %>} +\newcommand{\sphinxlogo}{<%= logo %>} +\renewcommand{\releasename}{<%= releasename %>} +<%= makeindex %> +<%= body %> +<%= footer %> +<%= indices %> +\renewcommand{\indexname}{<%= indexname %>} +<%= printindex %> +\end{document} diff --git a/sphinx/util/template.py b/sphinx/util/template.py new file mode 100644 index 000000000..b89a4c960 --- /dev/null +++ b/sphinx/util/template.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +""" + sphinx.util.template + ~~~~~~~~~~~~~~~~~~~~ + + Templates utility functions for Sphinx. + + :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import os +from jinja2.sandbox import SandboxedEnvironment + +from sphinx import package_dir +from sphinx.jinja2glue import SphinxFileSystemLoader + + +class BaseRenderer(object): + def __init__(self, loader=None): + self.env = SandboxedEnvironment(loader=loader) + self.env.filters['repr'] = repr + + def render(self, template_name, context): + return self.env.get_template(template_name).render(context) + + def render_string(self, source, context): + return self.env.from_string(source).render(context) + + +class FileRenderer(BaseRenderer): + def __init__(self, search_path): + loader = SphinxFileSystemLoader(search_path) + super(FileRenderer, self).__init__(loader) + + @classmethod + def render_from_file(cls, filename, context): + dirname = os.path.dirname(filename) + basename = os.path.basename(filename) + return cls(dirname).render(basename, context) + + +class SphinxRenderer(FileRenderer): + def __init__(self): + super(SphinxRenderer, self).__init__(os.path.join(package_dir, 'templates')) + + +class LaTeXRenderer(SphinxRenderer): + def __init__(self): + super(LaTeXRenderer, self).__init__() + + # use JSP/eRuby like tagging instead because curly bracket; the default + # tagging of jinja2 is not good for LaTeX sources. + self.env.variable_start_string = '<%=' + self.env.variable_end_string = '%>' + self.env.block_start_string = '<%' + self.env.block_end_string = '%>' diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 528aca192..72050ad89 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -28,46 +28,10 @@ from sphinx.locale import admonitionlabels, _ from sphinx.util import split_into from sphinx.util.i18n import format_date from sphinx.util.nodes import clean_astext, traverse_parent +from sphinx.util.template import LaTeXRenderer from sphinx.util.texescape import tex_escape_map, tex_replace_map from sphinx.util.smartypants import educate_quotes_latex -HEADER = r'''%% Generated by Sphinx. -\def\sphinxdocclass{%(docclass)s} -\newif\ifsphinxKeepOldNames %(keepoldnames)s -\documentclass[%(papersize)s,%(pointsize)s%(classoptions)s]{%(wrapperclass)s} -\ifdefined\pdfpxdimen - \let\sphinxpxdimen\pdfpxdimen\else\newdimen\sphinxpxdimen -\fi \sphinxpxdimen=%(pxunit)s\relax -\usepackage{iftex} -%(passoptionstopackages)s -%(inputenc)s -%(utf8extra)s -%(cmappkg)s -%(fontenc)s -%(amsmath)s -%(babel)s -%(fontpkg)s -%(fncychap)s -%(longtable)s -\usepackage{sphinx} -\usepackage{multirow} -\usepackage{eqparbox} -%(usepackages)s -%(contentsname)s -%(numfig_format)s -%(pageautorefname)s -%(tocdepth)s -%(secnumdepth)s -%(preamble)s - -\title{%(title)s} -\date{%(date)s} -\release{%(release)s} -\author{%(author)s} -\newcommand{\sphinxlogo}{%(logo)s} -\renewcommand{\releasename}{%(releasename)s} -%(makeindex)s -''' BEGIN_DOC = r''' \begin{document} @@ -76,12 +40,8 @@ BEGIN_DOC = r''' %(tableofcontents)s ''' -FOOTER = r''' -\renewcommand{\indexname}{%(indexname)s} -%(printindex)s -\end{document} -''' +DEFAULT_TEMPLATE = 'latex/content.tex_t' URI_SCHEMES = ('mailto:', 'http:', 'https:', 'ftp:') SECNUMDEPTH = 3 @@ -543,11 +503,11 @@ class LaTeXTranslator(nodes.NodeVisitor): return docclass def astext(self): - return (HEADER % self.elements + - u''.join(self.body) + - '\n' + self.elements['footer'] + '\n' + - self.generate_indices() + - FOOTER % self.elements) + self.elements.update({ + 'body': u''.join(self.body), + 'indices': self.generate_indices() + }) + return LaTeXRenderer().render(DEFAULT_TEMPLATE, self.elements) def hypertarget(self, id, withdoc=True, anchor=True): if withdoc: