Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,12 @@ jobs:
- "3.12"
- "3.13-dev"
docutils:
- "0.18"
- "0.20"
- "0.21"
include:
# test every supported Docutils version for the latest supported Python
- python: "3.12"
docutils: "0.19"
- python: "3.12"
docutils: "0.20"
# include:
# # test every supported Docutils version for the latest supported Python
# - python: "3.12"
# docutils: "0.20"

steps:
- uses: actions/checkout@v4
Expand Down
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ Release 7.4.0 (in development)
Dependencies
------------

* #12555: Drop Docutils 0.18.1 and Docutils 0.19 support.
Patch by Adam Turner

Incompatible changes
--------------------

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ dependencies = [
"sphinxcontrib-qthelp",
"Jinja2>=3.0",
"Pygments>=2.14",
"docutils>=0.18.1,<0.22",
"docutils>=0.20,<0.22",
"snowballstemmer>=2.0",
"babel>=2.9",
"alabaster~=0.7.14",
Expand Down
6 changes: 1 addition & 5 deletions sphinx/builders/html/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,7 @@ def __init__(self, app: Sphinx, env: BuildEnvironment) -> None:
source_class=DocTreeInput,
destination=StringOutput(encoding='unicode'),
)
if docutils.__version_info__[:2] >= (0, 19):
pub.get_settings(output_encoding='unicode', traceback=True)
else:
op = pub.setup_option_parser(output_encoding='unicode', traceback=True)
pub.settings = op.get_default_values()
pub.get_settings(output_encoding='unicode', traceback=True)
self._publisher = pub

def init(self) -> None:
Expand Down
8 changes: 2 additions & 6 deletions sphinx/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

from typing import TYPE_CHECKING, Any

import docutils
from docutils import nodes
from docutils.core import Publisher
from docutils.io import FileInput, Input, NullOutput
from docutils.readers import standalone
Expand All @@ -25,6 +23,7 @@
from sphinx.versioning import UIDTransform

if TYPE_CHECKING:
from docutils import nodes
from docutils.frontend import Values
from docutils.parsers import Parser
from docutils.transforms import Transform
Expand Down Expand Up @@ -191,8 +190,5 @@ def create_publisher(app: Sphinx, filetype: str) -> Publisher:
# Propagate exceptions by default when used programmatically:
defaults = {'traceback': True, **app.env.settings}
# Set default settings
if docutils.__version_info__[:2] >= (0, 19):
pub.get_settings(**defaults)
else:
pub.settings = pub.setup_option_parser(**defaults).get_default_values()
pub.get_settings(**defaults)
return pub
37 changes: 1 addition & 36 deletions sphinx/util/docutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
from docutils.parsers.rst.states import Inliner # NoQA: TCH002
from docutils.statemachine import State, StateMachine, StringList
from docutils.utils import Reporter, unescape
from docutils.writers._html_base import HTMLTranslator

from sphinx.errors import SphinxError
from sphinx.locale import _, __
Expand Down Expand Up @@ -181,46 +180,12 @@ def using_user_docutils_conf(confdir: str | None) -> Iterator[None]:
os.environ['DOCUTILSCONFIG'] = docutilsconfig


@contextmanager
def du19_footnotes() -> Iterator[None]:
def visit_footnote(self: HTMLTranslator, node: Element) -> None:
label_style = self.settings.footnote_references
if not isinstance(node.previous_sibling(), type(node)):
self.body.append(f'<aside class="footnote-list {label_style}">\n')
self.body.append(self.starttag(node, 'aside',
classes=[node.tagname, label_style],
role="note"))

def depart_footnote(self: HTMLTranslator, node: Element) -> None:
self.body.append('</aside>\n')
if not isinstance(node.next_node(descend=False, siblings=True),
type(node)):
self.body.append('</aside>\n')

old_visit_footnote = HTMLTranslator.visit_footnote
old_depart_footnote = HTMLTranslator.depart_footnote

# Only apply on Docutils 0.18 or 0.18.1, as 0.17 and earlier used a <dl> based
# approach, and 0.19 and later use the fixed approach by default.
if docutils.__version_info__[:2] == (0, 18):
HTMLTranslator.visit_footnote = visit_footnote # type: ignore[method-assign]
HTMLTranslator.depart_footnote = depart_footnote # type: ignore[method-assign]

try:
yield
finally:
if docutils.__version_info__[:2] == (0, 18):
HTMLTranslator.visit_footnote = old_visit_footnote # type: ignore[method-assign]
HTMLTranslator.depart_footnote = old_depart_footnote # type: ignore[method-assign]


@contextmanager
def patch_docutils(confdir: str | None = None) -> Iterator[None]:
"""Patch to docutils temporarily."""
with patched_get_language(), \
patched_rst_get_language(), \
using_user_docutils_conf(confdir), \
du19_footnotes():
using_user_docutils_conf(confdir):
yield


Expand Down