mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #8599 from tk0miya/6550_html_permalinks_icon
Close #6550: html: Allow to use HTML permalink texts
This commit is contained in:
commit
becf8f43be
7
CHANGES
7
CHANGES
@ -8,6 +8,8 @@ Incompatible changes
|
|||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
* Update Underscore.js to 1.12.0
|
* Update Underscore.js to 1.12.0
|
||||||
|
* #6550: html: The config variable ``html_add_permalinks`` is replaced by
|
||||||
|
:confval:`html_permalinks` and :confval:`html_permalinks_icon`
|
||||||
|
|
||||||
Deprecated
|
Deprecated
|
||||||
----------
|
----------
|
||||||
@ -22,6 +24,8 @@ Deprecated
|
|||||||
* ``sphinx.ext.autodoc.importer.get_module_members()``
|
* ``sphinx.ext.autodoc.importer.get_module_members()``
|
||||||
* ``sphinx.ext.autosummary.generate._simple_info()``
|
* ``sphinx.ext.autosummary.generate._simple_info()``
|
||||||
* ``sphinx.ext.autosummary.generate._simple_warn()``
|
* ``sphinx.ext.autosummary.generate._simple_warn()``
|
||||||
|
* ``sphinx.writers.html.HTMLTranslator.permalink_text``
|
||||||
|
* ``sphinx.writers.html5.HTML5Translator.permalink_text``
|
||||||
|
|
||||||
Features added
|
Features added
|
||||||
--------------
|
--------------
|
||||||
@ -37,6 +41,8 @@ Features added
|
|||||||
* #6241: html: Allow to add JS/CSS files to the specific page when an extension
|
* #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
|
calls ``app.add_js_file()`` or ``app.add_css_file()`` on
|
||||||
:event:`html-page-context` event
|
:event:`html-page-context` event
|
||||||
|
* #6550: html: Allow to use HTML permalink texts via
|
||||||
|
:confval:`html_permalinks_icon`
|
||||||
* #8649: imgconverter: Skip availability check if builder supports the image
|
* #8649: imgconverter: Skip availability check if builder supports the image
|
||||||
type
|
type
|
||||||
* #8573: napoleon: Allow to change the style of custom sections using
|
* #8573: napoleon: Allow to change the style of custom sections using
|
||||||
@ -53,7 +59,6 @@ Features added
|
|||||||
* C++, also hyperlink operator overloads in expressions and alias declarations.
|
* C++, also hyperlink operator overloads in expressions and alias declarations.
|
||||||
* #8247: Allow production lists to refer to tokens from other production groups
|
* #8247: Allow production lists to refer to tokens from other production groups
|
||||||
|
|
||||||
|
|
||||||
Bugs fixed
|
Bugs fixed
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
@ -71,6 +71,16 @@ The following is a list of deprecated interfaces.
|
|||||||
- 5.0
|
- 5.0
|
||||||
- :ref:`logging-api`
|
- :ref:`logging-api`
|
||||||
|
|
||||||
|
* - ``sphinx.writers.html.HTMLTranslator.permalink_text``
|
||||||
|
- 3.5
|
||||||
|
- 5.0
|
||||||
|
- :confval:`html_permalinks_icon`
|
||||||
|
|
||||||
|
* - ``sphinx.writers.html5.HTML5Translator.permalink_text``
|
||||||
|
- 3.5
|
||||||
|
- 5.0
|
||||||
|
- :confval:`html_permalinks_icon`
|
||||||
|
|
||||||
* - The ``follow_wrapped`` argument of ``sphinx.util.inspect.signature()``
|
* - The ``follow_wrapped`` argument of ``sphinx.util.inspect.signature()``
|
||||||
- 3.4
|
- 3.4
|
||||||
- 5.0
|
- 5.0
|
||||||
|
@ -1133,6 +1133,23 @@ that use Sphinx's HTMLWriter class.
|
|||||||
This can now be a string to select the actual text of the link.
|
This can now be a string to select the actual text of the link.
|
||||||
Previously, only boolean values were accepted.
|
Previously, only boolean values were accepted.
|
||||||
|
|
||||||
|
.. deprecated:: 3.5
|
||||||
|
This has been replaced by :confval:`html_permalinks`
|
||||||
|
|
||||||
|
.. confval:: html_permalinks
|
||||||
|
|
||||||
|
If true, Sphinx will add "permalinks" for each heading and description
|
||||||
|
environment. Default: ``True``.
|
||||||
|
|
||||||
|
.. versionadded:: 3.5
|
||||||
|
|
||||||
|
.. confval:: html_permalinks_icon
|
||||||
|
|
||||||
|
A text for permalinks for each heading and description environment. HTML
|
||||||
|
tags are allowed. Default: a paragraph sign; ``¶``
|
||||||
|
|
||||||
|
.. versionadded:: 3.5
|
||||||
|
|
||||||
.. confval:: html_sidebars
|
.. confval:: html_sidebars
|
||||||
|
|
||||||
Custom sidebar templates, must be a dictionary that maps document names to
|
Custom sidebar templates, must be a dictionary that maps document names to
|
||||||
|
@ -1205,6 +1205,16 @@ def validate_html_favicon(app: Sphinx, config: Config) -> None:
|
|||||||
config.html_favicon = None # type: ignore
|
config.html_favicon = None # type: ignore
|
||||||
|
|
||||||
|
|
||||||
|
def migrate_html_add_permalinks(app: Sphinx, config: Config) -> None:
|
||||||
|
"""Migrate html_add_permalinks to html_permalinks*."""
|
||||||
|
if config.html_add_permalinks:
|
||||||
|
if (isinstance(config.html_add_permalinks, bool) and
|
||||||
|
config.html_add_permalinks is False):
|
||||||
|
config.html_permalinks = False # type: ignore
|
||||||
|
else:
|
||||||
|
config.html_permalinks_icon = html.escape(config.html_add_permalinks) # type: ignore # NOQA
|
||||||
|
|
||||||
|
|
||||||
# for compatibility
|
# for compatibility
|
||||||
import sphinxcontrib.serializinghtml # NOQA
|
import sphinxcontrib.serializinghtml # NOQA
|
||||||
|
|
||||||
@ -1235,7 +1245,9 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|||||||
app.add_config_value('html_sidebars', {}, 'html')
|
app.add_config_value('html_sidebars', {}, 'html')
|
||||||
app.add_config_value('html_additional_pages', {}, 'html')
|
app.add_config_value('html_additional_pages', {}, 'html')
|
||||||
app.add_config_value('html_domain_indices', True, 'html', [list])
|
app.add_config_value('html_domain_indices', True, 'html', [list])
|
||||||
app.add_config_value('html_add_permalinks', '¶', 'html')
|
app.add_config_value('html_add_permalinks', None, 'html')
|
||||||
|
app.add_config_value('html_permalinks', True, 'html')
|
||||||
|
app.add_config_value('html_permalinks_icon', '¶', 'html')
|
||||||
app.add_config_value('html_use_index', True, 'html')
|
app.add_config_value('html_use_index', True, 'html')
|
||||||
app.add_config_value('html_split_index', False, 'html')
|
app.add_config_value('html_split_index', False, 'html')
|
||||||
app.add_config_value('html_copy_source', True, 'html')
|
app.add_config_value('html_copy_source', True, 'html')
|
||||||
@ -1267,6 +1279,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|||||||
# event handlers
|
# event handlers
|
||||||
app.connect('config-inited', convert_html_css_files, priority=800)
|
app.connect('config-inited', convert_html_css_files, priority=800)
|
||||||
app.connect('config-inited', convert_html_js_files, priority=800)
|
app.connect('config-inited', convert_html_js_files, priority=800)
|
||||||
|
app.connect('config-inited', migrate_html_add_permalinks, priority=800)
|
||||||
app.connect('config-inited', validate_html_extra_path, priority=800)
|
app.connect('config-inited', validate_html_extra_path, priority=800)
|
||||||
app.connect('config-inited', validate_html_static_path, priority=800)
|
app.connect('config-inited', validate_html_static_path, priority=800)
|
||||||
app.connect('config-inited', validate_html_logo, priority=800)
|
app.connect('config-inited', validate_html_logo, priority=800)
|
||||||
|
@ -22,7 +22,7 @@ from docutils.writers.html4css1 import Writer
|
|||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx50Warning
|
||||||
from sphinx.locale import _, __, admonitionlabels
|
from sphinx.locale import _, __, admonitionlabels
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging
|
||||||
from sphinx.util.docutils import SphinxTranslator
|
from sphinx.util.docutils import SphinxTranslator
|
||||||
@ -100,11 +100,6 @@ class HTMLTranslator(SphinxTranslator, BaseTranslator):
|
|||||||
self.docnames = [self.builder.current_docname] # for singlehtml builder
|
self.docnames = [self.builder.current_docname] # for singlehtml builder
|
||||||
self.manpages_url = self.config.manpages_url
|
self.manpages_url = self.config.manpages_url
|
||||||
self.protect_literal_text = 0
|
self.protect_literal_text = 0
|
||||||
self.permalink_text = self.config.html_add_permalinks
|
|
||||||
# support backwards-compatible setting to a bool
|
|
||||||
if not isinstance(self.permalink_text, str):
|
|
||||||
self.permalink_text = '¶' if self.permalink_text else ''
|
|
||||||
self.permalink_text = self.encode(self.permalink_text)
|
|
||||||
self.secnumber_suffix = self.config.html_secnumber_suffix
|
self.secnumber_suffix = self.config.html_secnumber_suffix
|
||||||
self.param_separator = ''
|
self.param_separator = ''
|
||||||
self.optional_param_level = 0
|
self.optional_param_level = 0
|
||||||
@ -333,9 +328,10 @@ class HTMLTranslator(SphinxTranslator, BaseTranslator):
|
|||||||
append_fignumber(figtype, node['ids'][0])
|
append_fignumber(figtype, node['ids'][0])
|
||||||
|
|
||||||
def add_permalink_ref(self, node: Element, title: str) -> None:
|
def add_permalink_ref(self, node: Element, title: str) -> None:
|
||||||
if node['ids'] and self.permalink_text and self.builder.add_permalinks:
|
if node['ids'] and self.config.html_permalinks and self.builder.add_permalinks:
|
||||||
format = '<a class="headerlink" href="#%s" title="%s">%s</a>'
|
format = '<a class="headerlink" href="#%s" title="%s">%s</a>'
|
||||||
self.body.append(format % (node['ids'][0], title, self.permalink_text))
|
self.body.append(format % (node['ids'][0], title,
|
||||||
|
self.config.html_permalinks_icon))
|
||||||
|
|
||||||
def generate_targets_for_listing(self, node: Element) -> None:
|
def generate_targets_for_listing(self, node: Element) -> None:
|
||||||
"""Generate hyperlink targets for listings.
|
"""Generate hyperlink targets for listings.
|
||||||
@ -410,7 +406,7 @@ class HTMLTranslator(SphinxTranslator, BaseTranslator):
|
|||||||
|
|
||||||
def depart_title(self, node: Element) -> None:
|
def depart_title(self, node: Element) -> None:
|
||||||
close_tag = self.context[-1]
|
close_tag = self.context[-1]
|
||||||
if (self.permalink_text and self.builder.add_permalinks and
|
if (self.config.html_permalinks and self.builder.add_permalinks and
|
||||||
node.parent.hasattr('ids') and node.parent['ids']):
|
node.parent.hasattr('ids') and node.parent['ids']):
|
||||||
# add permalink anchor
|
# add permalink anchor
|
||||||
if close_tag.startswith('</h'):
|
if close_tag.startswith('</h'):
|
||||||
@ -420,7 +416,7 @@ class HTMLTranslator(SphinxTranslator, BaseTranslator):
|
|||||||
node.parent['ids'][0] +
|
node.parent['ids'][0] +
|
||||||
'title="%s">%s' % (
|
'title="%s">%s' % (
|
||||||
_('Permalink to this headline'),
|
_('Permalink to this headline'),
|
||||||
self.permalink_text))
|
self.config.html_permalinks_icon))
|
||||||
elif isinstance(node.parent, nodes.table):
|
elif isinstance(node.parent, nodes.table):
|
||||||
self.body.append('</span>')
|
self.body.append('</span>')
|
||||||
self.add_permalink_ref(node.parent, _('Permalink to this table'))
|
self.add_permalink_ref(node.parent, _('Permalink to this table'))
|
||||||
@ -838,3 +834,9 @@ class HTMLTranslator(SphinxTranslator, BaseTranslator):
|
|||||||
|
|
||||||
def unknown_visit(self, node: Node) -> None:
|
def unknown_visit(self, node: Node) -> None:
|
||||||
raise NotImplementedError('Unknown node: ' + node.__class__.__name__)
|
raise NotImplementedError('Unknown node: ' + node.__class__.__name__)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def permalink_text(self) -> str:
|
||||||
|
warnings.warn('HTMLTranslator.permalink_text is deprecated.',
|
||||||
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
|
return self.config.html_permalinks_icon
|
||||||
|
@ -20,7 +20,7 @@ from docutils.writers.html5_polyglot import HTMLTranslator as BaseTranslator
|
|||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx50Warning
|
||||||
from sphinx.locale import _, __, admonitionlabels
|
from sphinx.locale import _, __, admonitionlabels
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging
|
||||||
from sphinx.util.docutils import SphinxTranslator
|
from sphinx.util.docutils import SphinxTranslator
|
||||||
@ -71,11 +71,6 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
|
|||||||
self.docnames = [self.builder.current_docname] # for singlehtml builder
|
self.docnames = [self.builder.current_docname] # for singlehtml builder
|
||||||
self.manpages_url = self.config.manpages_url
|
self.manpages_url = self.config.manpages_url
|
||||||
self.protect_literal_text = 0
|
self.protect_literal_text = 0
|
||||||
self.permalink_text = self.config.html_add_permalinks
|
|
||||||
# support backwards-compatible setting to a bool
|
|
||||||
if not isinstance(self.permalink_text, str):
|
|
||||||
self.permalink_text = '¶' if self.permalink_text else ''
|
|
||||||
self.permalink_text = self.encode(self.permalink_text)
|
|
||||||
self.secnumber_suffix = self.config.html_secnumber_suffix
|
self.secnumber_suffix = self.config.html_secnumber_suffix
|
||||||
self.param_separator = ''
|
self.param_separator = ''
|
||||||
self.optional_param_level = 0
|
self.optional_param_level = 0
|
||||||
@ -304,9 +299,10 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
|
|||||||
append_fignumber(figtype, node['ids'][0])
|
append_fignumber(figtype, node['ids'][0])
|
||||||
|
|
||||||
def add_permalink_ref(self, node: Element, title: str) -> None:
|
def add_permalink_ref(self, node: Element, title: str) -> None:
|
||||||
if node['ids'] and self.permalink_text and self.builder.add_permalinks:
|
if node['ids'] and self.config.html_permalinks and self.builder.add_permalinks:
|
||||||
format = '<a class="headerlink" href="#%s" title="%s">%s</a>'
|
format = '<a class="headerlink" href="#%s" title="%s">%s</a>'
|
||||||
self.body.append(format % (node['ids'][0], title, self.permalink_text))
|
self.body.append(format % (node['ids'][0], title,
|
||||||
|
self.config.html_permalinks_icon))
|
||||||
|
|
||||||
# overwritten
|
# overwritten
|
||||||
def visit_bullet_list(self, node: Element) -> None:
|
def visit_bullet_list(self, node: Element) -> None:
|
||||||
@ -361,7 +357,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
|
|||||||
|
|
||||||
def depart_title(self, node: Element) -> None:
|
def depart_title(self, node: Element) -> None:
|
||||||
close_tag = self.context[-1]
|
close_tag = self.context[-1]
|
||||||
if (self.permalink_text and self.builder.add_permalinks and
|
if (self.config.html_permalinks and self.builder.add_permalinks and
|
||||||
node.parent.hasattr('ids') and node.parent['ids']):
|
node.parent.hasattr('ids') and node.parent['ids']):
|
||||||
# add permalink anchor
|
# add permalink anchor
|
||||||
if close_tag.startswith('</h'):
|
if close_tag.startswith('</h'):
|
||||||
@ -371,7 +367,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
|
|||||||
node.parent['ids'][0] +
|
node.parent['ids'][0] +
|
||||||
'title="%s">%s' % (
|
'title="%s">%s' % (
|
||||||
_('Permalink to this headline'),
|
_('Permalink to this headline'),
|
||||||
self.permalink_text))
|
self.config.html_permalinks_icon))
|
||||||
elif isinstance(node.parent, nodes.table):
|
elif isinstance(node.parent, nodes.table):
|
||||||
self.body.append('</span>')
|
self.body.append('</span>')
|
||||||
self.add_permalink_ref(node.parent, _('Permalink to this table'))
|
self.add_permalink_ref(node.parent, _('Permalink to this table'))
|
||||||
@ -786,3 +782,9 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
|
|||||||
|
|
||||||
def unknown_visit(self, node: Node) -> None:
|
def unknown_visit(self, node: Node) -> None:
|
||||||
raise NotImplementedError('Unknown node: ' + node.__class__.__name__)
|
raise NotImplementedError('Unknown node: ' + node.__class__.__name__)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def permalink_text(self) -> str:
|
||||||
|
warnings.warn('HTMLTranslator.permalink_text is deprecated.',
|
||||||
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
|
return self.config.html_permalinks_icon
|
||||||
|
@ -1665,3 +1665,23 @@ def test_highlight_options_old(app):
|
|||||||
location=ANY, opts={})
|
location=ANY, opts={})
|
||||||
assert call_args[2] == call(ANY, 'java', force=False, linenos=False,
|
assert call_args[2] == call(ANY, 'java', force=False, linenos=False,
|
||||||
location=ANY, opts={})
|
location=ANY, opts={})
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx('html', testroot='basic',
|
||||||
|
confoverrides={'html_permalinks': False})
|
||||||
|
def test_html_permalink_disable(app):
|
||||||
|
app.build()
|
||||||
|
content = (app.outdir / 'index.html').read_text()
|
||||||
|
|
||||||
|
assert '<h1>The basic Sphinx documentation for testing</h1>' in content
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx('html', testroot='basic',
|
||||||
|
confoverrides={'html_permalinks_icon': '<span>[PERMALINK]</span>'})
|
||||||
|
def test_html_permalink_icon(app):
|
||||||
|
app.build()
|
||||||
|
content = (app.outdir / 'index.html').read_text()
|
||||||
|
|
||||||
|
assert ('<h1>The basic Sphinx documentation for testing<a class="headerlink" '
|
||||||
|
'href="#the-basic-sphinx-documentation-for-testing" '
|
||||||
|
'title="Permalink to this headline"><span>[PERMALINK]</span></a></h1>' in content)
|
||||||
|
Loading…
Reference in New Issue
Block a user