mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
This reverts commit 5d13215b58
.
This commit is contained in:
parent
aee3c0ab75
commit
59de8d5202
9
CHANGES
9
CHANGES
@ -23,11 +23,6 @@ Deprecated
|
|||||||
----------
|
----------
|
||||||
|
|
||||||
* #11247: Deprecate the legacy ``intersphinx_mapping`` format
|
* #11247: Deprecate the legacy ``intersphinx_mapping`` format
|
||||||
* #11165: Warn when the ``_t`` suffix is used for template files. The formal
|
|
||||||
deprecation process will begin no earlier than 31 December 2024.
|
|
||||||
Templates should change to use the ``.jinja`` filename suffix instead.
|
|
||||||
For more information, see :ref:`theming-static-templates`.
|
|
||||||
Patch by James Addison and Adam Turner
|
|
||||||
|
|
||||||
Features added
|
Features added
|
||||||
--------------
|
--------------
|
||||||
@ -65,10 +60,6 @@ Features added
|
|||||||
``= 'xelatex'``. Patch by Dimitar Dimitrov
|
``= 'xelatex'``. Patch by Dimitar Dimitrov
|
||||||
* #11109, #9643: Add :confval:`python_display_short_literal_types` option for
|
* #11109, #9643: Add :confval:`python_display_short_literal_types` option for
|
||||||
condensed rendering of ``Literal`` types.
|
condensed rendering of ``Literal`` types.
|
||||||
* #11165: Support the `officially recommended`_ ``.jinja`` suffix for template
|
|
||||||
files. Patch by James Addison
|
|
||||||
|
|
||||||
.. _officially recommended: https://jinja.palletsprojects.com/en/latest/templates/#template-file-extension
|
|
||||||
|
|
||||||
Bugs fixed
|
Bugs fixed
|
||||||
----------
|
----------
|
||||||
|
@ -156,51 +156,13 @@ template static files as well as HTML files. Therefore, Sphinx supports
|
|||||||
so-called "static templates", like this:
|
so-called "static templates", like this:
|
||||||
|
|
||||||
If the name of a file in the ``static/`` directory of a theme (or in the user's
|
If the name of a file in the ``static/`` directory of a theme (or in the user's
|
||||||
static path, for that matter) ends with ``.jinja``, it will be processed by the
|
static path, for that matter) ends with ``_t``, it will be processed by the
|
||||||
template engine. The ``.jinja`` will be removed from the final file name. For
|
template engine. The ``_t`` will be left from the final file name. For
|
||||||
example, the *classic* theme has a file ``static/classic.css.jinja`` which uses
|
example, the *classic* theme has a file ``static/classic.css_t`` which uses
|
||||||
templating to put the colour options into the stylesheet. When a documentation
|
templating to put the color options into the stylesheet. When a documentation
|
||||||
project is built with the classic theme, the output directory will contain a
|
project is built with the classic theme, the output directory will contain a
|
||||||
``_static/classic.css`` file where all template tags have been processed.
|
``_static/classic.css`` file where all template tags have been processed.
|
||||||
|
|
||||||
.. versionchanged:: 6.2
|
|
||||||
|
|
||||||
The preferred suffix for static templates is now ``.jinja``, in line with
|
|
||||||
the Jinja project's `recommended file extension`_.
|
|
||||||
|
|
||||||
The ``_t`` file suffix for static templates is now considered 'legacy', and
|
|
||||||
support will eventually be removed. The standard deprecation process will
|
|
||||||
begin no earlier than 31 December 2024, at which point using ``_t`` suffixes
|
|
||||||
will emit ``RemovedInSphinx__Warning`` warnings.
|
|
||||||
|
|
||||||
If a static template with a ``_t`` suffix is detected, it will be processed
|
|
||||||
by the template engine, with the ``_t`` suffix removed from the final file
|
|
||||||
name.
|
|
||||||
|
|
||||||
To silence the warning for ``_t`` suffixes, the new
|
|
||||||
``sphinx.deprecation.OldJinjaSuffixWarning`` class has been added for use
|
|
||||||
with Python's standard `warning control`_ mechanisms. This class will be
|
|
||||||
removed no earlier than 31 December 2024, so guard any imports with a
|
|
||||||
try/except block.
|
|
||||||
For example, in a ``setup()`` function:
|
|
||||||
|
|
||||||
.. code:: python
|
|
||||||
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
def setup(app):
|
|
||||||
try:
|
|
||||||
from sphinx.deprecation import OldJinjaSuffixWarning
|
|
||||||
except ImportError:
|
|
||||||
pass # Only silence the warning if it exists!
|
|
||||||
else:
|
|
||||||
warnings.filterwarnings('ignore', category=OldJinjaSuffixWarning)
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
||||||
.. _recommended file extension: https://jinja.palletsprojects.com/en/latest/templates/#template-file-extension
|
|
||||||
.. _warning control: https://docs.python.org/3/library/warnings.html#the-warnings-filter
|
|
||||||
|
|
||||||
|
|
||||||
Use custom page metadata in HTML templates
|
Use custom page metadata in HTML templates
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -1813,12 +1813,12 @@ Miscellany
|
|||||||
.. hint::
|
.. hint::
|
||||||
|
|
||||||
As an experimental feature, Sphinx can use user-defined template file for
|
As an experimental feature, Sphinx can use user-defined template file for
|
||||||
LaTeX source if you have a file named ``_templates/latex.tex.jinja`` in your
|
LaTeX source if you have a file named ``_templates/latex.tex_t`` in your
|
||||||
project.
|
project.
|
||||||
|
|
||||||
Additional files ``longtable.tex.jinja``, ``tabulary.tex.jinja`` and
|
Additional files ``longtable.tex_t``, ``tabulary.tex_t`` and
|
||||||
``tabular.tex.jinja`` can be added to ``_templates/`` to configure some
|
``tabular.tex_t`` can be added to ``_templates/`` to configure some aspects
|
||||||
aspects of table rendering (such as the caption position).
|
of table rendering (such as the caption position).
|
||||||
|
|
||||||
.. versionadded:: 1.6
|
.. versionadded:: 1.6
|
||||||
currently all template variables are unstable and undocumented.
|
currently all template variables are unstable and undocumented.
|
||||||
|
@ -603,8 +603,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
html.escape(self.refnodes[0]['refuri'])))
|
html.escape(self.refnodes[0]['refuri'])))
|
||||||
|
|
||||||
# write the project file
|
# write the project file
|
||||||
content_t = path.join(self.template_dir, 'content.opf.jinja')
|
copy_asset_file(path.join(self.template_dir, 'content.opf_t'), self.outdir, metadata)
|
||||||
copy_asset_file(content_t, self.outdir, metadata)
|
|
||||||
|
|
||||||
def new_navpoint(self, node: dict[str, Any], level: int, incr: bool = True) -> NavPoint:
|
def new_navpoint(self, node: dict[str, Any], level: int, incr: bool = True) -> NavPoint:
|
||||||
"""Create a new entry in the toc from the node at given level."""
|
"""Create a new entry in the toc from the node at given level."""
|
||||||
@ -687,7 +686,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
navpoints = self.build_navpoints(refnodes)
|
navpoints = self.build_navpoints(refnodes)
|
||||||
level = max(item['level'] for item in self.refnodes)
|
level = max(item['level'] for item in self.refnodes)
|
||||||
level = min(level, self.config.epub_tocdepth)
|
level = min(level, self.config.epub_tocdepth)
|
||||||
copy_asset_file(path.join(self.template_dir, 'toc.ncx.jinja'), self.outdir,
|
copy_asset_file(path.join(self.template_dir, 'toc.ncx_t'), self.outdir,
|
||||||
self.toc_metadata(level, navpoints))
|
self.toc_metadata(level, navpoints))
|
||||||
|
|
||||||
def build_epub(self) -> None:
|
def build_epub(self) -> None:
|
||||||
|
@ -133,10 +133,10 @@ class ChangesBuilder(Builder):
|
|||||||
f.write(self.templates.render('changes/rstsource.html', ctx))
|
f.write(self.templates.render('changes/rstsource.html', ctx))
|
||||||
themectx = {'theme_' + key: val for (key, val) in
|
themectx = {'theme_' + key: val for (key, val) in
|
||||||
self.theme.get_options({}).items()}
|
self.theme.get_options({}).items()}
|
||||||
default_t = path.join(package_dir, 'themes', 'default', 'static', 'default.css.jinja')
|
copy_asset_file(path.join(package_dir, 'themes', 'default', 'static', 'default.css_t'),
|
||||||
copy_asset_file(default_t, self.outdir, context=themectx, renderer=self.templates)
|
self.outdir, context=themectx, renderer=self.templates)
|
||||||
basic = path.join(package_dir, 'themes', 'basic', 'static', 'basic.css')
|
copy_asset_file(path.join(package_dir, 'themes', 'basic', 'static', 'basic.css'),
|
||||||
copy_asset_file(basic, self.outdir)
|
self.outdir)
|
||||||
|
|
||||||
def hl(self, text: str, version: str) -> str:
|
def hl(self, text: str, version: str) -> str:
|
||||||
text = html.escape(text)
|
text = html.escape(text)
|
||||||
|
@ -184,7 +184,7 @@ class Epub3Builder(_epub_base.EpubBuilder):
|
|||||||
# 'includehidden'
|
# 'includehidden'
|
||||||
refnodes = self.refnodes
|
refnodes = self.refnodes
|
||||||
navlist = self.build_navlist(refnodes)
|
navlist = self.build_navlist(refnodes)
|
||||||
copy_asset_file(path.join(self.template_dir, 'nav.xhtml.jinja'), self.outdir,
|
copy_asset_file(path.join(self.template_dir, 'nav.xhtml_t'), self.outdir,
|
||||||
self.navigation_doc_metadata(navlist))
|
self.navigation_doc_metadata(navlist))
|
||||||
|
|
||||||
# Add nav.xhtml to epub file
|
# Add nav.xhtml to epub file
|
||||||
|
@ -283,7 +283,7 @@ class MessageCatalogBuilder(I18nBuilder):
|
|||||||
ensuredir(path.join(self.outdir, path.dirname(textdomain)))
|
ensuredir(path.join(self.outdir, path.dirname(textdomain)))
|
||||||
|
|
||||||
context['messages'] = list(catalog)
|
context['messages'] = list(catalog)
|
||||||
content = GettextRenderer(outdir=self.outdir).render('message.pot.jinja', context)
|
content = GettextRenderer(outdir=self.outdir).render('message.pot_t', context)
|
||||||
|
|
||||||
pofn = path.join(self.outdir, textdomain + '.pot')
|
pofn = path.join(self.outdir, textdomain + '.pot')
|
||||||
if should_write(pofn, content):
|
if should_write(pofn, content):
|
||||||
|
@ -402,7 +402,7 @@ class LaTeXBuilder(Builder):
|
|||||||
# use pre-1.6.x Makefile for make latexpdf on Windows
|
# use pre-1.6.x Makefile for make latexpdf on Windows
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
staticdirname = path.join(package_dir, 'texinputs_win')
|
staticdirname = path.join(package_dir, 'texinputs_win')
|
||||||
copy_asset_file(path.join(staticdirname, 'Makefile.jinja'),
|
copy_asset_file(path.join(staticdirname, 'Makefile_t'),
|
||||||
self.outdir, context=context)
|
self.outdir, context=context)
|
||||||
|
|
||||||
@progress_message(__('copying additional files'))
|
@progress_message(__('copying additional files'))
|
||||||
@ -441,7 +441,7 @@ class LaTeXBuilder(Builder):
|
|||||||
if self.context['babel'] or self.context['polyglossia']:
|
if self.context['babel'] or self.context['polyglossia']:
|
||||||
context['addtocaptions'] = r'\addto\captions%s' % self.babel.get_language()
|
context['addtocaptions'] = r'\addto\captions%s' % self.babel.get_language()
|
||||||
|
|
||||||
filename = path.join(package_dir, 'templates', 'latex', 'sphinxmessages.sty.jinja')
|
filename = path.join(package_dir, 'templates', 'latex', 'sphinxmessages.sty_t')
|
||||||
copy_asset_file(filename, self.outdir, context=context, renderer=LaTeXRenderer())
|
copy_asset_file(filename, self.outdir, context=context, renderer=LaTeXRenderer())
|
||||||
|
|
||||||
|
|
||||||
|
@ -370,29 +370,29 @@ def generate(
|
|||||||
if 'quiet' not in d:
|
if 'quiet' not in d:
|
||||||
print(__('File %s already exists, skipping.') % fpath)
|
print(__('File %s already exists, skipping.') % fpath)
|
||||||
|
|
||||||
conf_path = os.path.join(templatedir, 'conf.py.jinja') if templatedir else None
|
conf_path = os.path.join(templatedir, 'conf.py_t') if templatedir else None
|
||||||
if not conf_path or not path.isfile(conf_path):
|
if not conf_path or not path.isfile(conf_path):
|
||||||
conf_path = os.path.join(package_dir, 'templates', 'quickstart', 'conf.py.jinja')
|
conf_path = os.path.join(package_dir, 'templates', 'quickstart', 'conf.py_t')
|
||||||
with open(conf_path, encoding="utf-8") as f:
|
with open(conf_path, encoding="utf-8") as f:
|
||||||
conf_text = f.read()
|
conf_text = f.read()
|
||||||
|
|
||||||
write_file(path.join(srcdir, 'conf.py'), template.render_string(conf_text, d))
|
write_file(path.join(srcdir, 'conf.py'), template.render_string(conf_text, d))
|
||||||
|
|
||||||
masterfile = path.join(srcdir, d['master'] + d['suffix'])
|
masterfile = path.join(srcdir, d['master'] + d['suffix'])
|
||||||
if template._has_custom_template('quickstart/master_doc.rst.jinja'):
|
if template._has_custom_template('quickstart/master_doc.rst_t'):
|
||||||
msg = ('A custom template `master_doc.rst_t` found. It has been renamed to '
|
msg = ('A custom template `master_doc.rst_t` found. It has been renamed to '
|
||||||
'`root_doc.rst_t`. Please rename it on your project too.')
|
'`root_doc.rst_t`. Please rename it on your project too.')
|
||||||
print(colorize('red', msg))
|
print(colorize('red', msg))
|
||||||
write_file(masterfile, template.render('quickstart/master_doc.rst.jinja', d))
|
write_file(masterfile, template.render('quickstart/master_doc.rst_t', d))
|
||||||
else:
|
else:
|
||||||
write_file(masterfile, template.render('quickstart/root_doc.rst.jinja', d))
|
write_file(masterfile, template.render('quickstart/root_doc.rst_t', d))
|
||||||
|
|
||||||
if d.get('make_mode') is True:
|
if d.get('make_mode') is True:
|
||||||
makefile_template = 'quickstart/Makefile.new.jinja'
|
makefile_template = 'quickstart/Makefile.new_t'
|
||||||
batchfile_template = 'quickstart/make.bat.new.jinja'
|
batchfile_template = 'quickstart/make.bat.new_t'
|
||||||
else:
|
else:
|
||||||
makefile_template = 'quickstart/Makefile.jinja'
|
makefile_template = 'quickstart/Makefile_t'
|
||||||
batchfile_template = 'quickstart/make.bat.jinja'
|
batchfile_template = 'quickstart/make.bat_t'
|
||||||
|
|
||||||
if d['makefile'] is True:
|
if d['makefile'] is True:
|
||||||
d['rsrcdir'] = 'source' if d['sep'] else '.'
|
d['rsrcdir'] = 'source' if d['sep'] else '.'
|
||||||
|
@ -62,31 +62,3 @@ def _deprecation_warning(
|
|||||||
|
|
||||||
warnings.warn(message + " Check CHANGES for Sphinx API modifications.",
|
warnings.warn(message + " Check CHANGES for Sphinx API modifications.",
|
||||||
warning_class, stacklevel=3)
|
warning_class, stacklevel=3)
|
||||||
|
|
||||||
|
|
||||||
class OldJinjaSuffixWarning(PendingDeprecationWarning):
|
|
||||||
"""Warning class for ``_old_jinja_template_suffix_warning``.
|
|
||||||
|
|
||||||
This class exists only so that extensions and themes can silence the legacy
|
|
||||||
filename warning via Python's `warning control`_ mechanisms. See
|
|
||||||
:ref:`theming-static-templates` for an example.
|
|
||||||
|
|
||||||
This warning class will be removed, and the warning class changed to the
|
|
||||||
appropriate RemovedInSphinx_0Warning no earlier than 31 December 2024, at
|
|
||||||
which point the standard deprecation process for ``_t`` template suffixes
|
|
||||||
will start.
|
|
||||||
|
|
||||||
.. _warning control: https://docs.python.org/3/library/warnings.html#the-warnings-filter
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def _old_jinja_template_suffix_warning(filename: str) -> None:
|
|
||||||
if filename.endswith('_t'):
|
|
||||||
warnings.warn(
|
|
||||||
f"{filename!r}: the '_t' suffix for Jinja templates is deprecated. "
|
|
||||||
"If the file is a template, use the suffix '.jinja' instead. "
|
|
||||||
'For more information, see '
|
|
||||||
'https://www.sphinx-doc.org/en/master/development/theming.html#static-templates',
|
|
||||||
OldJinjaSuffixWarning,
|
|
||||||
stacklevel=3,
|
|
||||||
)
|
|
||||||
|
@ -102,7 +102,7 @@ def create_module_file(package: str, basename: str, opts: Any,
|
|||||||
'qualname': qualname,
|
'qualname': qualname,
|
||||||
'automodule_options': options,
|
'automodule_options': options,
|
||||||
}
|
}
|
||||||
text = ReSTRenderer([user_template_dir, template_dir]).render('module.rst.jinja', context)
|
text = ReSTRenderer([user_template_dir, template_dir]).render('module.rst_t', context)
|
||||||
write_file(qualname, text, opts)
|
write_file(qualname, text, opts)
|
||||||
|
|
||||||
|
|
||||||
@ -138,8 +138,7 @@ def create_package_file(root: str, master_package: str, subroot: str, py_files:
|
|||||||
'show_headings': not opts.noheadings,
|
'show_headings': not opts.noheadings,
|
||||||
'maxdepth': opts.maxdepth,
|
'maxdepth': opts.maxdepth,
|
||||||
}
|
}
|
||||||
engine = ReSTRenderer([user_template_dir, template_dir])
|
text = ReSTRenderer([user_template_dir, template_dir]).render('package.rst_t', context)
|
||||||
text = engine.render('package.rst.jinja', context)
|
|
||||||
write_file(pkgname, text, opts)
|
write_file(pkgname, text, opts)
|
||||||
|
|
||||||
if submodules and opts.separatemodules:
|
if submodules and opts.separatemodules:
|
||||||
@ -164,7 +163,7 @@ def create_modules_toc_file(modules: list[str], opts: Any, name: str = 'modules'
|
|||||||
'maxdepth': opts.maxdepth,
|
'maxdepth': opts.maxdepth,
|
||||||
'docnames': modules,
|
'docnames': modules,
|
||||||
}
|
}
|
||||||
text = ReSTRenderer([user_template_dir, template_dir]).render('toc.rst.jinja', context)
|
text = ReSTRenderer([user_template_dir, template_dir]).render('toc.rst_t', context)
|
||||||
write_file(name, text, opts)
|
write_file(name, text, opts)
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@ from sphinx import package_dir
|
|||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.config import Config
|
from sphinx.config import Config
|
||||||
from sphinx.deprecation import _old_jinja_template_suffix_warning
|
|
||||||
from sphinx.errors import SphinxError
|
from sphinx.errors import SphinxError
|
||||||
from sphinx.locale import _, __
|
from sphinx.locale import _, __
|
||||||
from sphinx.util import logging, sha1
|
from sphinx.util import logging, sha1
|
||||||
@ -96,20 +95,16 @@ def generate_latex_macro(image_format: str,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if config.imgmath_use_preview:
|
if config.imgmath_use_preview:
|
||||||
template_name = 'preview.tex'
|
template_name = 'preview.tex_t'
|
||||||
else:
|
else:
|
||||||
template_name = 'template.tex'
|
template_name = 'template.tex_t'
|
||||||
|
|
||||||
for template_dir in config.templates_path:
|
for template_dir in config.templates_path:
|
||||||
# TODO: deprecate '_t' template suffix support after 2024-12-31
|
template = path.join(confdir, template_dir, template_name)
|
||||||
for template_suffix in ('_t', '.jinja'):
|
if path.exists(template):
|
||||||
template = path.join(confdir, template_dir, template_name + template_suffix)
|
return LaTeXRenderer().render(template, variables)
|
||||||
if path.exists(template):
|
|
||||||
_old_jinja_template_suffix_warning(template)
|
|
||||||
return LaTeXRenderer().render(template, variables)
|
|
||||||
|
|
||||||
# Default: fallback to a pathless in-library jinja template
|
return LaTeXRenderer(templates_path).render(template_name, variables)
|
||||||
return LaTeXRenderer(templates_path).render(f"{template_name}.jinja", variables)
|
|
||||||
|
|
||||||
|
|
||||||
def ensure_tempdir(builder: Builder) -> str:
|
def ensure_tempdir(builder: Builder) -> str:
|
||||||
|
@ -8,7 +8,6 @@ from typing import TYPE_CHECKING, Callable
|
|||||||
|
|
||||||
from docutils.utils import relative_path
|
from docutils.utils import relative_path
|
||||||
|
|
||||||
from sphinx.deprecation import _old_jinja_template_suffix_warning
|
|
||||||
from sphinx.util.osutil import copyfile, ensuredir
|
from sphinx.util.osutil import copyfile, ensuredir
|
||||||
from sphinx.util.typing import PathMatcher
|
from sphinx.util.typing import PathMatcher
|
||||||
|
|
||||||
@ -16,19 +15,6 @@ if TYPE_CHECKING:
|
|||||||
from sphinx.util.template import BaseRenderer
|
from sphinx.util.template import BaseRenderer
|
||||||
|
|
||||||
|
|
||||||
def _template_basename(filename: str) -> str | None:
|
|
||||||
"""Given an input filename:
|
|
||||||
If the input looks like a template, then return the filename output should
|
|
||||||
be written to. Otherwise, return no result (None)."""
|
|
||||||
# TODO: deprecate '_t' template suffix support after 2024-12-31
|
|
||||||
if filename.lower().endswith('_t'):
|
|
||||||
_old_jinja_template_suffix_warning(filename)
|
|
||||||
return filename[:-2]
|
|
||||||
elif filename.lower().endswith(".jinja"):
|
|
||||||
return filename[:-6]
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def copy_asset_file(source: str, destination: str,
|
def copy_asset_file(source: str, destination: str,
|
||||||
context: dict | None = None,
|
context: dict | None = None,
|
||||||
renderer: BaseRenderer | None = None) -> None:
|
renderer: BaseRenderer | None = None) -> None:
|
||||||
@ -49,13 +35,14 @@ def copy_asset_file(source: str, destination: str,
|
|||||||
# Use source filename if destination points a directory
|
# Use source filename if destination points a directory
|
||||||
destination = os.path.join(destination, os.path.basename(source))
|
destination = os.path.join(destination, os.path.basename(source))
|
||||||
|
|
||||||
if _template_basename(source) and context is not None:
|
if source.lower().endswith('_t') and context is not None:
|
||||||
if renderer is None:
|
if renderer is None:
|
||||||
from sphinx.util.template import SphinxRenderer
|
from sphinx.util.template import SphinxRenderer
|
||||||
renderer = SphinxRenderer()
|
renderer = SphinxRenderer()
|
||||||
|
|
||||||
with open(source, encoding='utf-8') as fsrc:
|
with open(source, encoding='utf-8') as fsrc:
|
||||||
destination = _template_basename(destination) or destination
|
if destination.lower().endswith('_t'):
|
||||||
|
destination = destination[:-2]
|
||||||
with open(destination, 'w', encoding='utf-8') as fdst:
|
with open(destination, 'w', encoding='utf-8') as fdst:
|
||||||
fdst.write(renderer.render_string(fsrc.read(), context))
|
fdst.write(renderer.render_string(fsrc.read(), context))
|
||||||
else:
|
else:
|
||||||
|
@ -16,7 +16,7 @@ from docutils import nodes, writers
|
|||||||
from docutils.nodes import Element, Node, Text
|
from docutils.nodes import Element, Node, Text
|
||||||
|
|
||||||
from sphinx import addnodes, highlighting
|
from sphinx import addnodes, highlighting
|
||||||
from sphinx.deprecation import RemovedInSphinx70Warning, _old_jinja_template_suffix_warning
|
from sphinx.deprecation import RemovedInSphinx70Warning
|
||||||
from sphinx.domains import IndexEntry
|
from sphinx.domains import IndexEntry
|
||||||
from sphinx.domains.std import StandardDomain
|
from sphinx.domains.std import StandardDomain
|
||||||
from sphinx.errors import SphinxError
|
from sphinx.errors import SphinxError
|
||||||
@ -435,8 +435,7 @@ class LaTeXTranslator(SphinxTranslator):
|
|||||||
'body': ''.join(self.body),
|
'body': ''.join(self.body),
|
||||||
'indices': self.generate_indices(),
|
'indices': self.generate_indices(),
|
||||||
})
|
})
|
||||||
template = self._find_template('latex.tex')
|
return self.render('latex.tex_t', self.elements)
|
||||||
return self.render(template, self.elements)
|
|
||||||
|
|
||||||
def hypertarget(self, id: str, withdoc: bool = True, anchor: bool = True) -> str:
|
def hypertarget(self, id: str, withdoc: bool = True, anchor: bool = True) -> str:
|
||||||
if withdoc:
|
if withdoc:
|
||||||
@ -513,21 +512,14 @@ class LaTeXTranslator(SphinxTranslator):
|
|||||||
|
|
||||||
return ''.join(ret)
|
return ''.join(ret)
|
||||||
|
|
||||||
def _find_template(self, template_name: str) -> str:
|
|
||||||
for template_dir in self.config.templates_path:
|
|
||||||
# TODO: deprecate '_t' template suffix support after 2024-12-31
|
|
||||||
for template_suffix in ('_t', '.jinja'):
|
|
||||||
template = path.join(self.builder.confdir, template_dir,
|
|
||||||
template_name + template_suffix)
|
|
||||||
if path.exists(template):
|
|
||||||
_old_jinja_template_suffix_warning(template)
|
|
||||||
return template
|
|
||||||
|
|
||||||
# Default: fallback to a pathless in-library jinja template
|
|
||||||
return f"{template_name}.jinja"
|
|
||||||
|
|
||||||
def render(self, template_name: str, variables: dict[str, Any]) -> str:
|
def render(self, template_name: str, variables: dict[str, Any]) -> str:
|
||||||
renderer = LaTeXRenderer(latex_engine=self.config.latex_engine)
|
renderer = LaTeXRenderer(latex_engine=self.config.latex_engine)
|
||||||
|
for template_dir in self.config.templates_path:
|
||||||
|
template = path.join(self.builder.confdir, template_dir,
|
||||||
|
template_name)
|
||||||
|
if path.exists(template):
|
||||||
|
return renderer.render(template, variables)
|
||||||
|
|
||||||
return renderer.render(template_name, variables)
|
return renderer.render(template_name, variables)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -910,8 +902,8 @@ class LaTeXTranslator(SphinxTranslator):
|
|||||||
def depart_table(self, node: Element) -> None:
|
def depart_table(self, node: Element) -> None:
|
||||||
labels = self.hypertarget_to(node)
|
labels = self.hypertarget_to(node)
|
||||||
table_type = self.table.get_table_type()
|
table_type = self.table.get_table_type()
|
||||||
template = self._find_template(f"{table_type}.tex")
|
table = self.render(table_type + '.tex_t',
|
||||||
table = self.render(template, {'table': self.table, 'labels': labels})
|
{'table': self.table, 'labels': labels})
|
||||||
self.body.append(BLANKLINE)
|
self.body.append(BLANKLINE)
|
||||||
self.body.append(table)
|
self.body.append(table)
|
||||||
self.body.append(CR)
|
self.body.append(CR)
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
<# TODO: deprecate '_t' template suffix support after 2024-12-31 #>
|
|
||||||
AU REVOIR, KANIGGETS
|
|
@ -1153,7 +1153,7 @@ def test_html_assets(app):
|
|||||||
# html_extra_path
|
# html_extra_path
|
||||||
assert (app.outdir / '.htaccess').exists()
|
assert (app.outdir / '.htaccess').exists()
|
||||||
assert not (app.outdir / '.htpasswd').exists()
|
assert not (app.outdir / '.htpasswd').exists()
|
||||||
assert (app.outdir / 'API.html.jinja').exists()
|
assert (app.outdir / 'API.html_t').exists()
|
||||||
assert (app.outdir / 'css/style.css').exists()
|
assert (app.outdir / 'css/style.css').exists()
|
||||||
assert (app.outdir / 'rimg.png').exists()
|
assert (app.outdir / 'rimg.png').exists()
|
||||||
assert not (app.outdir / '_build' / 'index.html').exists()
|
assert not (app.outdir / '_build' / 'index.html').exists()
|
||||||
|
@ -1382,10 +1382,6 @@ def test_latex_table_custom_template_caseA(app, status, warning):
|
|||||||
result = (app.outdir / 'python.tex').read_text(encoding='utf8')
|
result = (app.outdir / 'python.tex').read_text(encoding='utf8')
|
||||||
assert 'SALUT LES COPAINS' in result
|
assert 'SALUT LES COPAINS' in result
|
||||||
|
|
||||||
# # TODO: deprecate '_t' template suffix support after 2024-12-31
|
|
||||||
assert 'TODO' not in result
|
|
||||||
assert 'AU REVOIR, KANIGGETS' in result
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.sphinx('latex', testroot='latex-table',
|
@pytest.mark.sphinx('latex', testroot='latex-table',
|
||||||
confoverrides={'templates_path': ['_mytemplates']})
|
confoverrides={'templates_path': ['_mytemplates']})
|
||||||
|
@ -1,114 +0,0 @@
|
|||||||
import warnings
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
from sphinx import deprecation
|
|
||||||
|
|
||||||
|
|
||||||
def test_old_jinja_suffix_warning_is_warning():
|
|
||||||
assert isinstance(deprecation.OldJinjaSuffixWarning, type)
|
|
||||||
assert issubclass(deprecation.OldJinjaSuffixWarning, Warning)
|
|
||||||
assert issubclass(deprecation.OldJinjaSuffixWarning, PendingDeprecationWarning)
|
|
||||||
|
|
||||||
with pytest.warns(deprecation.OldJinjaSuffixWarning):
|
|
||||||
warnings.warn('test_1', category=deprecation.OldJinjaSuffixWarning)
|
|
||||||
|
|
||||||
with pytest.warns(PendingDeprecationWarning):
|
|
||||||
warnings.warn('test_2', category=deprecation.OldJinjaSuffixWarning)
|
|
||||||
|
|
||||||
with pytest.warns(Warning):
|
|
||||||
warnings.warn('test_3', category=deprecation.OldJinjaSuffixWarning)
|
|
||||||
|
|
||||||
|
|
||||||
def test_old_jinja_suffix_warning_simplefilter_always(recwarn):
|
|
||||||
assert len(recwarn) == 0
|
|
||||||
warnings.resetwarnings()
|
|
||||||
|
|
||||||
warnings.simplefilter('always', category=deprecation.OldJinjaSuffixWarning)
|
|
||||||
warnings.warn('test_simplefilter_always', category=deprecation.OldJinjaSuffixWarning)
|
|
||||||
|
|
||||||
assert len(recwarn) == 1
|
|
||||||
caught_warning = recwarn[0]
|
|
||||||
assert caught_warning.category is deprecation.OldJinjaSuffixWarning
|
|
||||||
assert str(caught_warning.message) == 'test_simplefilter_always'
|
|
||||||
|
|
||||||
|
|
||||||
def test_old_jinja_suffix_warning_filterwarnings_always(recwarn):
|
|
||||||
assert len(recwarn) == 0
|
|
||||||
warnings.resetwarnings()
|
|
||||||
|
|
||||||
warnings.filterwarnings('always', category=deprecation.OldJinjaSuffixWarning)
|
|
||||||
warnings.warn('test_filterwarnings_always', category=deprecation.OldJinjaSuffixWarning)
|
|
||||||
|
|
||||||
assert len(recwarn) == 1
|
|
||||||
caught_warning = recwarn[0]
|
|
||||||
assert caught_warning.category is deprecation.OldJinjaSuffixWarning
|
|
||||||
assert str(caught_warning.message) == 'test_filterwarnings_always'
|
|
||||||
|
|
||||||
|
|
||||||
def test_old_jinja_suffix_warning_simplefilter_ignore(recwarn):
|
|
||||||
assert len(recwarn) == 0
|
|
||||||
warnings.resetwarnings()
|
|
||||||
|
|
||||||
warnings.simplefilter('ignore', deprecation.OldJinjaSuffixWarning)
|
|
||||||
warnings.warn('test_simplefilter_ignore', category=deprecation.OldJinjaSuffixWarning)
|
|
||||||
|
|
||||||
assert len(recwarn) == 0
|
|
||||||
|
|
||||||
|
|
||||||
def test_old_jinja_suffix_warning_filterwarnings_ignore(recwarn):
|
|
||||||
assert len(recwarn) == 0
|
|
||||||
warnings.resetwarnings()
|
|
||||||
|
|
||||||
warnings.filterwarnings('ignore', category=deprecation.OldJinjaSuffixWarning)
|
|
||||||
warnings.warn('test_filterwarnings_ignore', category=deprecation.OldJinjaSuffixWarning)
|
|
||||||
|
|
||||||
assert len(recwarn) == 0
|
|
||||||
|
|
||||||
|
|
||||||
def test__old_jinja_template_suffix_no_warning_css(recwarn):
|
|
||||||
assert len(recwarn) == 0
|
|
||||||
warnings.resetwarnings()
|
|
||||||
warnings.simplefilter('always', category=deprecation.OldJinjaSuffixWarning)
|
|
||||||
|
|
||||||
deprecation._old_jinja_template_suffix_warning('template.css')
|
|
||||||
|
|
||||||
assert len(recwarn) == 0
|
|
||||||
|
|
||||||
|
|
||||||
def test__old_jinja_template_suffix_no_warning_jinja(recwarn):
|
|
||||||
assert len(recwarn) == 0
|
|
||||||
warnings.resetwarnings()
|
|
||||||
warnings.simplefilter('always', category=deprecation.OldJinjaSuffixWarning)
|
|
||||||
|
|
||||||
deprecation._old_jinja_template_suffix_warning('template.css.jinja')
|
|
||||||
|
|
||||||
assert len(recwarn) == 0
|
|
||||||
|
|
||||||
|
|
||||||
def test__old_jinja_template_suffix_warning__t():
|
|
||||||
with pytest.warns(deprecation.OldJinjaSuffixWarning,
|
|
||||||
match=r"the '_t' suffix for Jinja templates is deprecated"):
|
|
||||||
deprecation._old_jinja_template_suffix_warning('template.css_t')
|
|
||||||
|
|
||||||
|
|
||||||
def test__old_jinja_template_suffix_warning_stacklevel():
|
|
||||||
# _old_jinja_template_suffix_warning is only called within functions that
|
|
||||||
# use template files.
|
|
||||||
def do_something_with_templates(filename):
|
|
||||||
deprecation._old_jinja_template_suffix_warning(filename)
|
|
||||||
|
|
||||||
# TOJTSWS line number marker
|
|
||||||
with pytest.warns(deprecation.OldJinjaSuffixWarning) as caught:
|
|
||||||
do_something_with_templates('template.css_t')
|
|
||||||
|
|
||||||
lines = [b''] + Path(__file__).read_bytes().splitlines()
|
|
||||||
line_number = lines.index(b' # TOJTSWS line number marker') + 2
|
|
||||||
|
|
||||||
assert len(caught) == 1
|
|
||||||
caught_warning = caught[0]
|
|
||||||
assert caught_warning.category is deprecation.OldJinjaSuffixWarning
|
|
||||||
assert "the '_t' suffix for Jinja templates is deprecated" in str(caught_warning.message)
|
|
||||||
assert caught_warning.filename == __file__
|
|
||||||
assert caught_warning.lineno == line_number
|
|
@ -3,7 +3,7 @@
|
|||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
from sphinx.jinja2glue import BuiltinTemplateLoader
|
from sphinx.jinja2glue import BuiltinTemplateLoader
|
||||||
from sphinx.util.fileutil import _template_basename, copy_asset, copy_asset_file
|
from sphinx.util.fileutil import copy_asset, copy_asset_file
|
||||||
|
|
||||||
|
|
||||||
class DummyTemplateLoader(BuiltinTemplateLoader):
|
class DummyTemplateLoader(BuiltinTemplateLoader):
|
||||||
@ -28,9 +28,9 @@ def test_copy_asset_file(tempdir):
|
|||||||
assert src.read_text(encoding='utf8') == dest.read_text(encoding='utf8')
|
assert src.read_text(encoding='utf8') == dest.read_text(encoding='utf8')
|
||||||
|
|
||||||
# copy template file
|
# copy template file
|
||||||
src = (tempdir / 'asset.txt.jinja')
|
src = (tempdir / 'asset.txt_t')
|
||||||
src.write_text('# {{var1}} data')
|
src.write_text('# {{var1}} data')
|
||||||
dest = (tempdir / 'output.txt.jinja')
|
dest = (tempdir / 'output.txt_t')
|
||||||
|
|
||||||
copy_asset_file(src, dest, {'var1': 'template'}, renderer)
|
copy_asset_file(src, dest, {'var1': 'template'}, renderer)
|
||||||
assert not dest.exists()
|
assert not dest.exists()
|
||||||
@ -38,7 +38,7 @@ def test_copy_asset_file(tempdir):
|
|||||||
assert (tempdir / 'output.txt').read_text(encoding='utf8') == '# template data'
|
assert (tempdir / 'output.txt').read_text(encoding='utf8') == '# template data'
|
||||||
|
|
||||||
# copy template file to subdir
|
# copy template file to subdir
|
||||||
src = (tempdir / 'asset.txt.jinja')
|
src = (tempdir / 'asset.txt_t')
|
||||||
src.write_text('# {{var1}} data')
|
src.write_text('# {{var1}} data')
|
||||||
subdir1 = (tempdir / 'subdir')
|
subdir1 = (tempdir / 'subdir')
|
||||||
subdir1.makedirs()
|
subdir1.makedirs()
|
||||||
@ -48,14 +48,14 @@ def test_copy_asset_file(tempdir):
|
|||||||
assert (subdir1 / 'asset.txt').read_text(encoding='utf8') == '# template data'
|
assert (subdir1 / 'asset.txt').read_text(encoding='utf8') == '# template data'
|
||||||
|
|
||||||
# copy template file without context
|
# copy template file without context
|
||||||
src = (tempdir / 'asset.txt.jinja')
|
src = (tempdir / 'asset.txt_t')
|
||||||
subdir2 = (tempdir / 'subdir2')
|
subdir2 = (tempdir / 'subdir2')
|
||||||
subdir2.makedirs()
|
subdir2.makedirs()
|
||||||
|
|
||||||
copy_asset_file(src, subdir2)
|
copy_asset_file(src, subdir2)
|
||||||
assert not (subdir2 / 'asset.txt').exists()
|
assert not (subdir2 / 'asset.txt').exists()
|
||||||
assert (subdir2 / 'asset.txt.jinja').exists()
|
assert (subdir2 / 'asset.txt_t').exists()
|
||||||
assert (subdir2 / 'asset.txt.jinja').read_text(encoding='utf8') == '# {{var1}} data'
|
assert (subdir2 / 'asset.txt_t').read_text(encoding='utf8') == '# {{var1}} data'
|
||||||
|
|
||||||
|
|
||||||
def test_copy_asset(tempdir):
|
def test_copy_asset(tempdir):
|
||||||
@ -65,12 +65,12 @@ def test_copy_asset(tempdir):
|
|||||||
source = (tempdir / 'source')
|
source = (tempdir / 'source')
|
||||||
source.makedirs()
|
source.makedirs()
|
||||||
(source / 'index.rst').write_text('index.rst', encoding='utf8')
|
(source / 'index.rst').write_text('index.rst', encoding='utf8')
|
||||||
(source / 'foo.rst.jinja').write_text('{{var1}}.rst', encoding='utf8')
|
(source / 'foo.rst_t').write_text('{{var1}}.rst', encoding='utf8')
|
||||||
(source / '_static').makedirs()
|
(source / '_static').makedirs()
|
||||||
(source / '_static' / 'basic.css').write_text('basic.css', encoding='utf8')
|
(source / '_static' / 'basic.css').write_text('basic.css', encoding='utf8')
|
||||||
(source / '_templates').makedirs()
|
(source / '_templates').makedirs()
|
||||||
(source / '_templates' / 'layout.html').write_text('layout.html', encoding='utf8')
|
(source / '_templates' / 'layout.html').write_text('layout.html', encoding='utf8')
|
||||||
(source / '_templates' / 'sidebar.html.jinja').write_text('sidebar: {{var2}}', encoding='utf8')
|
(source / '_templates' / 'sidebar.html_t').write_text('sidebar: {{var2}}', encoding='utf8')
|
||||||
|
|
||||||
# copy a single file
|
# copy a single file
|
||||||
assert not (tempdir / 'test1').exists()
|
assert not (tempdir / 'test1').exists()
|
||||||
@ -101,14 +101,3 @@ def test_copy_asset(tempdir):
|
|||||||
assert not (destdir / '_static' / 'basic.css').exists()
|
assert not (destdir / '_static' / 'basic.css').exists()
|
||||||
assert (destdir / '_templates' / 'layout.html').exists()
|
assert (destdir / '_templates' / 'layout.html').exists()
|
||||||
assert not (destdir / '_templates' / 'sidebar.html').exists()
|
assert not (destdir / '_templates' / 'sidebar.html').exists()
|
||||||
|
|
||||||
|
|
||||||
def test_template_basename():
|
|
||||||
assert not _template_basename("asset.txt")
|
|
||||||
assert _template_basename("asset.txt.jinja") == "asset.txt"
|
|
||||||
assert _template_basename("sidebar.html.jinja") == "sidebar.html"
|
|
||||||
|
|
||||||
|
|
||||||
def test_legacy_template_basename():
|
|
||||||
# TODO: deprecate '_t' template suffix support after 2024-12-31
|
|
||||||
assert _template_basename("asset.txt_t") == "asset.txt"
|
|
||||||
|
@ -42,9 +42,7 @@ METHOD_MAP = [
|
|||||||
# Extraction from Python source files
|
# Extraction from Python source files
|
||||||
('**.py', extract_python),
|
('**.py', extract_python),
|
||||||
# Extraction from Jinja2 template files
|
# Extraction from Jinja2 template files
|
||||||
('**/templates/latex/**.tex.jinja', extract_jinja2),
|
|
||||||
('**/templates/latex/**.tex_t', extract_jinja2),
|
('**/templates/latex/**.tex_t', extract_jinja2),
|
||||||
('**/templates/latex/**.sty.jinja', extract_jinja2),
|
|
||||||
('**/templates/latex/**.sty_t', extract_jinja2),
|
('**/templates/latex/**.sty_t', extract_jinja2),
|
||||||
# Extraction from Jinja2 HTML templates
|
# Extraction from Jinja2 HTML templates
|
||||||
('**/themes/**.html', extract_jinja2),
|
('**/themes/**.html', extract_jinja2),
|
||||||
@ -52,7 +50,6 @@ METHOD_MAP = [
|
|||||||
('**/themes/**.xml', extract_jinja2),
|
('**/themes/**.xml', extract_jinja2),
|
||||||
# Extraction from JavaScript files
|
# Extraction from JavaScript files
|
||||||
('**.js', extract_javascript),
|
('**.js', extract_javascript),
|
||||||
('**.js.jinja', extract_javascript),
|
|
||||||
('**.js_t', extract_javascript),
|
('**.js_t', extract_javascript),
|
||||||
]
|
]
|
||||||
OPTIONS_MAP = {
|
OPTIONS_MAP = {
|
||||||
@ -61,9 +58,7 @@ OPTIONS_MAP = {
|
|||||||
'encoding': 'utf-8',
|
'encoding': 'utf-8',
|
||||||
},
|
},
|
||||||
# Extraction from Jinja2 template files
|
# Extraction from Jinja2 template files
|
||||||
'**/templates/latex/**.tex.jinja': TEX_DELIMITERS.copy(),
|
|
||||||
'**/templates/latex/**.tex_t': TEX_DELIMITERS.copy(),
|
'**/templates/latex/**.tex_t': TEX_DELIMITERS.copy(),
|
||||||
'**/templates/latex/**.sty.jinja': TEX_DELIMITERS.copy(),
|
|
||||||
'**/templates/latex/**.sty_t': TEX_DELIMITERS.copy(),
|
'**/templates/latex/**.sty_t': TEX_DELIMITERS.copy(),
|
||||||
# Extraction from Jinja2 HTML templates
|
# Extraction from Jinja2 HTML templates
|
||||||
'**/themes/**.html': {
|
'**/themes/**.html': {
|
||||||
|
Loading…
Reference in New Issue
Block a user