Skip to content

Commit

Permalink
Merge branch '3.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
tk0miya committed Jan 7, 2021
2 parents 5ba5602 + d9569a8 commit 5460ea1
Show file tree
Hide file tree
Showing 22 changed files with 131 additions and 53 deletions.
29 changes: 25 additions & 4 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ Features added
* #8619: html: kbd role generates customizable HTML tags for compound keys
* #8634: html: Allow to change the order of JS/CSS via ``priority`` parameter
for :meth:`Sphinx.add_js_file()` and :meth:`Sphinx.add_css_file()`
* #6241: html: Allow to add JS/CSS files to the specific page when an extension
calls ``app.add_js_file()`` or ``app.add_css_file()`` on
:event:`html-page-context` event
* #8649: imgconverter: Skip availability check if builder supports the image
type
* #6241: mathjax: Include mathjax.js only on the document using equations
* #8132: Add :confval:`project_copyright` as an alias of :confval:`copyright`

Bugs fixed
Expand All @@ -102,7 +108,7 @@ Bugs fixed
Testing
--------

Release 3.4.2 (in development)
Release 3.4.4 (in development)
==============================

Dependencies
Expand All @@ -120,15 +126,30 @@ Features added
Bugs fixed
----------

Testing
--------

Release 3.4.3 (released Jan 08, 2021)
=====================================

Bugs fixed
----------

* #8655: autodoc: Failed to generate document if target module contains an
object that raises an exception on ``hasattr()``

Release 3.4.2 (released Jan 04, 2021)
=====================================

Bugs fixed
----------

* #8164: autodoc: Classes that inherit mocked class are not documented
* #8602: autodoc: The ``autodoc-process-docstring`` event is emitted to the
non-datadescriptors unexpectedly
* #8616: autodoc: AttributeError is raised on non-class object is passed to
autoclass directive

Testing
--------

Release 3.4.1 (released Dec 25, 2020)
=====================================

Expand Down
3 changes: 3 additions & 0 deletions doc/extdev/appapi.rst
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,9 @@ Here is a more detailed list of these events.
You can return a string from the handler, it will then replace
``'page.html'`` as the HTML template for this page.

.. note:: You can install JS/CSS files for the specific page via
:meth:`Sphinx.add_js_file` and :meth:`Sphinx.add_css_file` since v3.5.0.

.. versionadded:: 0.4

.. versionchanged:: 1.3
Expand Down
14 changes: 14 additions & 0 deletions doc/usage/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1003,7 +1003,14 @@ that use Sphinx's HTMLWriter class.
'https://example.com/css/custom.css',
('print.css', {'media': 'print'})]

As a special attribute, *priority* can be set as an integer to load the CSS
file earlier or lazier step. For more information, refer
:meth:`Sphinx.add_css_files()`.

.. versionadded:: 1.8
.. versionchanged:: 3.5

Support priority attribute

.. confval:: html_js_files

Expand All @@ -1019,7 +1026,14 @@ that use Sphinx's HTMLWriter class.
'https://example.com/scripts/custom.js',
('custom.js', {'async': 'async'})]

As a special attribute, *priority* can be set as an integer to load the CSS
file earlier or lazier step. For more information, refer
:meth:`Sphinx.add_css_files()`.

.. versionadded:: 1.8
.. versionchanged:: 3.5

Support priority attribute

.. confval:: html_static_path

Expand Down
24 changes: 17 additions & 7 deletions sphinx/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -917,9 +917,11 @@ def add_js_file(self, filename: str, priority: int = 500, **kwargs: Any) -> None
Add *filename* to the list of JavaScript files that the default HTML
template will include in order of *priority* (ascending). The filename
must be relative to the HTML static path , or a full URI with scheme.
If the keyword argument ``body`` is given, its value will be added
between the ``<script>`` tags. Extra keyword arguments are included as
attributes of the ``<script>`` tag.
If the priority of JavaScript file is the same as others, the JavaScript
files will be included in order of the registration. If the keyword
argument ``body`` is given, its value will be added between the
``<script>`` tags. Extra keyword arguments are included as attributes of
the ``<script>`` tag.
Example::
Expand All @@ -944,14 +946,17 @@ def add_js_file(self, filename: str, priority: int = 500, **kwargs: Any) -> None
* - 800
- default priority for :confval:`html_js_files`
A JavaScript file can be added to the specific HTML page when on extension
calls this method on :event:`html-page-context` event.
.. versionadded:: 0.5
.. versionchanged:: 1.8
Renamed from ``app.add_javascript()``.
And it allows keyword arguments as attributes of script tag.
.. versionchanged:: 3.5
Take priority argument.
Take priority argument. Allow to add a JavaScript file to the specific page.
"""
self.registry.add_js_file(filename, priority=priority, **kwargs)
if hasattr(self.builder, 'add_js_file'):
Expand All @@ -962,8 +967,10 @@ def add_css_file(self, filename: str, priority: int = 500, **kwargs: Any) -> Non
Add *filename* to the list of CSS files that the default HTML template
will include in order of *priority* (ascending). The filename must be
relative to the HTML static path, or a full URI with scheme. The
eyword arguments are also accepted for attributes of ``<link>`` tag.
relative to the HTML static path, or a full URI with scheme. If the
priority of CSS file is the same as others, the CSS files will be
included in order of the registration. The keyword arguments are also
accepted for attributes of ``<link>`` tag.
Example::
Expand All @@ -990,6 +997,9 @@ def add_css_file(self, filename: str, priority: int = 500, **kwargs: Any) -> Non
* - 800
- default priority for :confval:`html_css_files`
A CSS file can be added to the specific HTML page when on extension calls
this method on :event:`html-page-context` event.
.. versionadded:: 1.0
.. versionchanged:: 1.6
Expand All @@ -1004,7 +1014,7 @@ def add_css_file(self, filename: str, priority: int = 500, **kwargs: Any) -> Non
And it allows keyword arguments as attributes of link tag.
.. versionchanged:: 3.5
Take priority argument.
Take priority argument. Allow to add a CSS file to the specific page.
"""
logger.debug('[app] adding stylesheet: %r', filename)
self.registry.add_css_files(filename, priority=priority, **kwargs)
Expand Down
8 changes: 8 additions & 0 deletions sphinx/builders/html/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,10 @@ def prepare_writing(self, docnames: Set[str]) -> None:
rellinks.append((indexname, indexcls.localname,
'', indexcls.shortname))

# back up script_files and css_files to allow adding JS/CSS files to a specific page.
self._script_files = list(self.script_files)
self._css_files = list(self.css_files)

self.globalcontext = {
'embedded': self.embedded,
'project': self.config.project,
Expand Down Expand Up @@ -1014,6 +1018,10 @@ def hasdoc(name: str) -> bool:
self.add_sidebars(pagename, ctx)
ctx.update(addctx)

# revert script_files and css_files
self.script_files[:] = self._script_files
self.css_files[:] = self.css_files

self.update_page_context(pagename, templatename, ctx, event_arg)
newtmpl = self.app.emit_firstresult('html-page-context', pagename,
templatename, ctx, event_arg)
Expand Down
12 changes: 7 additions & 5 deletions sphinx/directives/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"""

import re
from typing import TYPE_CHECKING, Any, Dict, List, Tuple, cast
from typing import TYPE_CHECKING, Any, Dict, Generic, List, Tuple, TypeVar, cast

from docutils import nodes
from docutils.nodes import Node
Expand All @@ -31,6 +31,8 @@
nl_escape_re = re.compile(r'\\\n')
strip_backslash_re = re.compile(r'\\(.)')

T = TypeVar('T')


def optional_int(argument: str) -> int:
"""
Expand All @@ -45,7 +47,7 @@ def optional_int(argument: str) -> int:
return value


class ObjectDescription(SphinxDirective):
class ObjectDescription(SphinxDirective, Generic[T]):
"""
Directive to describe a class, function or similar object. Not used
directly, but subclassed (in domain-specific directives) to add custom
Expand Down Expand Up @@ -95,7 +97,7 @@ def get_signatures(self) -> List[str]:
else:
return [line.strip() for line in lines]

def handle_signature(self, sig: str, signode: desc_signature) -> Any:
def handle_signature(self, sig: str, signode: desc_signature) -> T:
"""
Parse the signature *sig* into individual nodes and append them to
*signode*. If ValueError is raised, parsing is aborted and the whole
Expand All @@ -107,7 +109,7 @@ def handle_signature(self, sig: str, signode: desc_signature) -> Any:
"""
raise ValueError

def add_target_and_index(self, name: Any, sig: str, signode: desc_signature) -> None:
def add_target_and_index(self, name: T, sig: str, signode: desc_signature) -> None:
"""
Add cross-reference IDs and entries to self.indexnode, if applicable.
Expand Down Expand Up @@ -171,7 +173,7 @@ def run(self) -> List[Node]:
if self.domain:
node['classes'].append(self.domain)

self.names = [] # type: List[Any]
self.names = [] # type: List[T]
signatures = self.get_signatures()
for i, sig in enumerate(signatures):
# add a signature node for each signature in the current unit
Expand Down
2 changes: 1 addition & 1 deletion sphinx/domains/c.py
Original file line number Diff line number Diff line change
Expand Up @@ -3099,7 +3099,7 @@ def _make_phony_error_name() -> ASTNestedName:
return ASTNestedName([ASTIdentifier("PhonyNameDueToError")], rooted=False)


class CObject(ObjectDescription):
class CObject(ObjectDescription[ASTDeclaration]):
"""
Description of a C language object.
"""
Expand Down
2 changes: 1 addition & 1 deletion sphinx/domains/cpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -6670,7 +6670,7 @@ def _make_phony_error_name() -> ASTNestedName:
return ASTNestedName([nne], [False], rooted=False)


class CPPObject(ObjectDescription):
class CPPObject(ObjectDescription[ASTDeclaration]):
"""Description of a C++ language object."""

doc_field_types = [
Expand Down
2 changes: 1 addition & 1 deletion sphinx/domains/javascript.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
logger = logging.getLogger(__name__)


class JSObject(ObjectDescription):
class JSObject(ObjectDescription[Tuple[str, str]]):
"""
Description of a JavaScript object.
"""
Expand Down
7 changes: 5 additions & 2 deletions sphinx/domains/math.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,11 @@ def resolve_any_xref(self, env: BuildEnvironment, fromdocname: str, builder: "Bu
def get_objects(self) -> List:
return []

def has_equations(self) -> bool:
return any(self.data['has_equations'].values())
def has_equations(self, docname: str = None) -> bool:
if docname:
return self.data['has_equations'].get(docname, False)
else:
return any(self.data['has_equations'].values())


def setup(app: "Sphinx") -> Dict[str, Any]:
Expand Down
2 changes: 1 addition & 1 deletion sphinx/domains/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ def make_xref(self, rolename: str, domain: str, target: str,
return super().make_xref(rolename, domain, target, innernode, contnode, env)


class PyObject(ObjectDescription):
class PyObject(ObjectDescription[Tuple[str, str]]):
"""
Description of a general Python object.
Expand Down
2 changes: 1 addition & 1 deletion sphinx/domains/rst.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
dir_sig_re = re.compile(r'\.\. (.+?)::(.*)$')


class ReSTMarkup(ObjectDescription):
class ReSTMarkup(ObjectDescription[str]):
"""
Description of generic reST markup.
"""
Expand Down
4 changes: 2 additions & 2 deletions sphinx/domains/std.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
token_re = re.compile(r'`(\w+)`', re.U)


class GenericObject(ObjectDescription):
class GenericObject(ObjectDescription[str]):
"""
A generic x-ref directive registered with Sphinx.add_object_type().
"""
Expand Down Expand Up @@ -176,7 +176,7 @@ def make_old_id(self, name: str) -> str:
return self.name + '-' + name


class Cmdoption(ObjectDescription):
class Cmdoption(ObjectDescription[str]):
"""
Description of a command-line option (.. option).
"""
Expand Down
5 changes: 4 additions & 1 deletion sphinx/ext/autodoc/mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,10 @@ def mock(modnames: List[str]) -> Generator[None, None, None]:
def ismock(subject: Any) -> bool:
"""Check if the object is mocked."""
# check the object has '__sphinx_mock__' attribute
if not hasattr(subject, '__sphinx_mock__'):
try:
if safe_getattr(subject, '__sphinx_mock__', None) is None:
return False
except AttributeError:
return False

# check the object is mocked module
Expand Down
26 changes: 12 additions & 14 deletions sphinx/ext/mathjax.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@

import sphinx
from sphinx.application import Sphinx
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.domains.math import MathDomain
from sphinx.environment import BuildEnvironment
from sphinx.errors import ExtensionError
from sphinx.locale import _
from sphinx.util.math import get_node_equation_number
from sphinx.writers.html import HTMLTranslator

# more information for mathjax secure url is here:
# https://docs.mathjax.org/en/latest/start.html#secure-access-to-the-cdn
MATHJAX_URL = 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js'


def html_visit_math(self: HTMLTranslator, node: nodes.math) -> None:
self.body.append(self.starttag(node, 'span', '', CLASS='math notranslate nohighlight'))
Expand Down Expand Up @@ -66,41 +68,37 @@ def html_visit_displaymath(self: HTMLTranslator, node: nodes.math_block) -> None
raise nodes.SkipNode


def install_mathjax(app: Sphinx, env: BuildEnvironment) -> None:
def install_mathjax(app: Sphinx, pagename: str, templatename: str, context: Dict,
event_arg: Any) -> None:
if app.builder.format != 'html' or app.builder.math_renderer_name != 'mathjax': # type: ignore # NOQA
return
if not app.config.mathjax_path:
raise ExtensionError('mathjax_path config value must be set for the '
'mathjax extension to work')

builder = cast(StandaloneHTMLBuilder, app.builder)
domain = cast(MathDomain, env.get_domain('math'))
if domain.has_equations():
domain = cast(MathDomain, app.env.get_domain('math'))
if domain.has_equations(pagename):
# Enable mathjax only if equations exists
options = {'async': 'async'}
if app.config.mathjax_options:
options.update(app.config.mathjax_options)
builder.add_js_file(app.config.mathjax_path, **options)
app.add_js_file(app.config.mathjax_path, **options) # type: ignore

if app.config.mathjax_config:
body = "MathJax.Hub.Config(%s)" % json.dumps(app.config.mathjax_config)
builder.add_js_file(None, type="text/x-mathjax-config", body=body)
app.add_js_file(None, type="text/x-mathjax-config", body=body)


def setup(app: Sphinx) -> Dict[str, Any]:
app.add_html_math_renderer('mathjax',
(html_visit_math, None),
(html_visit_displaymath, None))

# more information for mathjax secure url is here:
# https://docs.mathjax.org/en/latest/start.html#secure-access-to-the-cdn
app.add_config_value('mathjax_path',
'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js',
'html')
app.add_config_value('mathjax_path', MATHJAX_URL, 'html')
app.add_config_value('mathjax_options', {}, 'html')
app.add_config_value('mathjax_inline', [r'\(', r'\)'], 'html')
app.add_config_value('mathjax_display', [r'\[', r'\]'], 'html')
app.add_config_value('mathjax_config', None, 'html')
app.connect('env-updated', install_mathjax)
app.connect('html-page-context', install_mathjax)

return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
Loading

0 comments on commit 5460ea1

Please sign in to comment.