pkgsrc-WIP-changes archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
py-docutils: update to 0.22.1.
Module Name: pkgsrc-wip
Committed By: Thomas Klausner <wiz%NetBSD.org@localhost>
Pushed By: wiz
Date: Thu Sep 18 10:30:31 2025 +0200
Changeset: 37e2a0861a3aecc71fc306d38135cefbfc1f7a3a
Modified Files:
py-docutils/Makefile
py-docutils/distinfo
Removed Files:
py-docutils/patches/patch-docutils_____init____.py
py-docutils/patches/patch-docutils_frontend.py
py-docutils/patches/patch-docutils_nodes.py
py-docutils/patches/patch-docutils_parsers_rst_directives_body.py
py-docutils/patches/patch-docutils_parsers_rst_directives_misc.py
py-docutils/patches/patch-docutils_parsers_rst_directives_parts.py
py-docutils/patches/patch-docutils_parsers_rst_states.py
py-docutils/patches/patch-docutils_statemachine.py
py-docutils/patches/patch-docutils_transforms_references.py
py-docutils/patches/patch-docutils_writers___html__base.py
py-docutils/patches/patch-docutils_writers_html4css1_____init____.py
py-docutils/patches/patch-docutils_writers_html5__polyglot_____init____.py
py-docutils/patches/patch-docutils_writers_latex2e_____init____.py
py-docutils/patches/patch-docutils_writers_latex2e_docutils.sty
py-docutils/patches/patch-docutils_writers_odf__odt_____init____.py
py-docutils/patches/patch-docutils_writers_xetex_____init____.py
Log Message:
py-docutils: update to 0.22.1.
To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=37e2a0861a3aecc71fc306d38135cefbfc1f7a3a
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
diffstat:
py-docutils/Makefile | 6 +-
py-docutils/distinfo | 22 +-
py-docutils/patches/patch-docutils_____init____.py | 0
py-docutils/patches/patch-docutils_frontend.py | 45 --
py-docutils/patches/patch-docutils_nodes.py | 32 --
.../patch-docutils_parsers_rst_directives_body.py | 44 --
.../patch-docutils_parsers_rst_directives_misc.py | 13 -
.../patch-docutils_parsers_rst_directives_parts.py | 15 -
.../patches/patch-docutils_parsers_rst_states.py | 562 ---------------------
py-docutils/patches/patch-docutils_statemachine.py | 30 --
.../patch-docutils_transforms_references.py | 53 --
.../patches/patch-docutils_writers___html__base.py | 24 -
...atch-docutils_writers_html4css1_____init____.py | 13 -
...ocutils_writers_html5__polyglot_____init____.py | 13 -
.../patch-docutils_writers_latex2e_____init____.py | 504 ------------------
.../patch-docutils_writers_latex2e_docutils.sty | 32 --
...patch-docutils_writers_odf__odt_____init____.py | 18 -
.../patch-docutils_writers_xetex_____init____.py | 14 -
18 files changed, 6 insertions(+), 1434 deletions(-)
diffs:
diff --git a/py-docutils/Makefile b/py-docutils/Makefile
index 8aa2175a18..19fdaf3c50 100644
--- a/py-docutils/Makefile
+++ b/py-docutils/Makefile
@@ -1,6 +1,6 @@
# $NetBSD: Makefile,v 1.67 2025/08/03 10:06:37 wiz Exp $
-DISTNAME= docutils-0.22
+DISTNAME= docutils-0.22.1
PKGNAME= ${PYPKGPREFIX}-${DISTNAME}
CATEGORIES= textproc python
MASTER_SITES= ${MASTER_SITE_PYPI:=d/docutils/}
@@ -29,8 +29,8 @@ post-install:
cd ${DESTDIR}${PREFIX}/bin && \
${MV} ${bin} ${bin}-${PYVERSSUFFIX} || ${TRUE}
.endfor
-# due to patches
- find ${DESTDIR}${PREFIX}/${PYSITELIB} -name *.orig -delete
+ # bug in 0.22.1 distfile
+ ${RM} ${DESTDIR}${PREFIX}/${PYSITELIB}/docutils/.__init__.py.swp
do-test:
cd ${WRKSRC} && ${PYTHONBIN} test/alltests.py
diff --git a/py-docutils/distinfo b/py-docutils/distinfo
index 542f85d5b9..40c1409e0b 100644
--- a/py-docutils/distinfo
+++ b/py-docutils/distinfo
@@ -1,21 +1,5 @@
$NetBSD: distinfo,v 1.33 2025/08/03 10:06:37 wiz Exp $
-BLAKE2s (docutils-0.22.tar.gz) = 20d7b105f2af0a2417ab1e3800120565ef7c3fc77da8dd4ebef852624b7b3eaa
-SHA512 (docutils-0.22.tar.gz) = 09082eb3bdd5f9b3e977d356740efee47725a50fbaca7bf35c7fddff06003c2b2177a38d160a9956f9e96261f881c0d870c0aa9fef84f90d0cac079ccc73669d
-Size (docutils-0.22.tar.gz) = 2277984 bytes
-SHA1 (patch-docutils_____init____.py) = da39a3ee5e6b4b0d3255bfef95601890afd80709
-SHA1 (patch-docutils_frontend.py) = e36ef1bbc98c2b01ae45341636a93a93e712b757
-SHA1 (patch-docutils_nodes.py) = 77d1ef24f35ac59abef0a12ab4d6e2097d2bd248
-SHA1 (patch-docutils_parsers_rst_directives_body.py) = 6b596cfe394299cce7609b2c1c5b8833b97dd18f
-SHA1 (patch-docutils_parsers_rst_directives_misc.py) = 86ba1bdcb00309e7bcde5980fee15ad4036e0c99
-SHA1 (patch-docutils_parsers_rst_directives_parts.py) = 709edad294ecfefd1013eaee886c3382a46699ea
-SHA1 (patch-docutils_parsers_rst_states.py) = 0e3c1925ffc2f38c3dc8d63c1215bdf51d8edc13
-SHA1 (patch-docutils_statemachine.py) = fb3e42652d16de8d9c26e8b77e83aef0ff6d6bc4
-SHA1 (patch-docutils_transforms_references.py) = e2cf86dfb87930def33b8371a7851efeb96a12cb
-SHA1 (patch-docutils_writers___html__base.py) = f432c8222ea1ef1f7181439e39caf130f014fa03
-SHA1 (patch-docutils_writers_html4css1_____init____.py) = b1a13109b56f1ba6922b1a67a2a52b3b34ace689
-SHA1 (patch-docutils_writers_html5__polyglot_____init____.py) = 5324c969d44395627942e9036770e7174313e30a
-SHA1 (patch-docutils_writers_latex2e_____init____.py) = fe531918331bbacbe37d29503c43234fcfa2c30f
-SHA1 (patch-docutils_writers_latex2e_docutils.sty) = c1d1204f9e141dfb48f93dc8efa7649c80f4c514
-SHA1 (patch-docutils_writers_odf__odt_____init____.py) = 6244cfd4b2fa431afeb896116dd0a335d262df84
-SHA1 (patch-docutils_writers_xetex_____init____.py) = 4164cd7c8d9d8f1c501ba2d560a58ace6923abc1
+BLAKE2s (docutils-0.22.1.tar.gz) = 7217a7166d29c48320a798f7484228ae0e9a9d7e2b2f17a7d384e787e3ff3a3b
+SHA512 (docutils-0.22.1.tar.gz) = 9cf82e12e5b63bed33dd334a9282a565d6a65edd7b8ad0b62ffe2a05ce039f7947a935de8743acc4846a6334fd894d90533dd0bf931166dcdbab56bc93c92619
+Size (docutils-0.22.1.tar.gz) = 2291655 bytes
diff --git a/py-docutils/patches/patch-docutils_____init____.py b/py-docutils/patches/patch-docutils_____init____.py
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/py-docutils/patches/patch-docutils_frontend.py b/py-docutils/patches/patch-docutils_frontend.py
deleted file mode 100644
index ae48cf9d93..0000000000
--- a/py-docutils/patches/patch-docutils_frontend.py
+++ /dev/null
@@ -1,45 +0,0 @@
-$NetBSD$
-
---- docutils/frontend.py.orig 2025-07-29 14:37:38.634775200 +0000
-+++ docutils/frontend.py
-@@ -808,34 +808,26 @@ class OptionParser(optparse.OptionParser
- ['--input-encoding'],
- {'metavar': '<name[:handler]>', 'default': 'utf-8',
- 'validator': validate_encoding_and_error_handler}),
-- ('Specify the error handler for undecodable characters. '
-- 'Choices: "strict" (default), "ignore", and "replace".',
-- ['--input-encoding-error-handler'],
-+ (SUPPRESS_HELP, ['--input-encoding-error-handler'],
- {'default': 'strict', 'validator': validate_encoding_error_handler}),
- ('Specify the text encoding and optionally the error handler for '
- 'output. Default: utf-8.',
- ['--output-encoding'],
- {'metavar': '<name[:handler]>', 'default': 'utf-8',
- 'validator': validate_encoding_and_error_handler}),
-- ('Specify error handler for unencodable output characters; '
-- '"strict" (default), "ignore", "replace", '
-- '"xmlcharrefreplace", "backslashreplace".',
-- ['--output-encoding-error-handler'],
-+ (SUPPRESS_HELP, ['--output-encoding-error-handler'],
- {'default': 'strict', 'validator': validate_encoding_error_handler}),
-- ('Specify text encoding and optionally error handler '
-- 'for error output. Default: %s.' % default_error_encoding,
-+ ('Specify text encoding and optionally the error handler'
-+ f' for error output. Default: {default_error_encoding}.',
- ['--error-encoding', '-e'],
- {'metavar': '<name[:handler]>', 'default': default_error_encoding,
- 'validator': validate_encoding_and_error_handler}),
-- ('Specify the error handler for unencodable characters in '
-- 'error output. Default: %s.'
-- % default_error_encoding_error_handler,
-- ['--error-encoding-error-handler'],
-+ (SUPPRESS_HELP, ['--error-encoding-error-handler'],
- {'default': default_error_encoding_error_handler,
- 'validator': validate_encoding_error_handler}),
- ('Specify the language (as BCP 47 language tag). Default: en.',
- ['--language', '-l'], {'dest': 'language_code', 'default': 'en',
-- 'metavar': '<name>'}),
-+ 'metavar': '<tag>'}),
- ('Write output file dependencies to <file>.',
- ['--record-dependencies'],
- {'metavar': '<file>', 'validator': validate_dependency_file,
diff --git a/py-docutils/patches/patch-docutils_nodes.py b/py-docutils/patches/patch-docutils_nodes.py
deleted file mode 100644
index e1ce675896..0000000000
--- a/py-docutils/patches/patch-docutils_nodes.py
+++ /dev/null
@@ -1,32 +0,0 @@
-$NetBSD$
-
---- docutils/nodes.py.orig 2025-07-29 14:37:37.467805600 +0000
-+++ docutils/nodes.py
-@@ -818,20 +818,23 @@ class Element(Node):
- return self.parent[i-1] if i > 0 else None
-
- def section_hierarchy(self) -> list[section]:
-- """Return the element's section hierarchy.
-+ """Return the element's section anchestors.
-
-- Return a list of all <section> elements containing `self`
-- (including `self` if it is a <section>).
-+ Return a list of all <section> elements that contain `self`
-+ (including `self` if it is a <section>) and have a parent node.
-
- List item ``[i]`` is the parent <section> of level i+1
- (1: section, 2: subsection, 3: subsubsection, ...).
- The length of the list is the element's section level.
-
-+ See `docutils.parsers.rst.states.RSTState.check_subsection()`
-+ for a usage example.
-+
- Provisional. May be changed or removed without warning.
- """
- sections = []
- node = self
-- while node is not None:
-+ while node.parent is not None:
- if isinstance(node, section):
- sections.append(node)
- node = node.parent
diff --git a/py-docutils/patches/patch-docutils_parsers_rst_directives_body.py b/py-docutils/patches/patch-docutils_parsers_rst_directives_body.py
deleted file mode 100644
index 95dc2b2f1b..0000000000
--- a/py-docutils/patches/patch-docutils_parsers_rst_directives_body.py
+++ /dev/null
@@ -1,44 +0,0 @@
-$NetBSD$
-
---- docutils/parsers/rst/directives/body.py.orig 2025-07-29 14:37:38.097654300 +0000
-+++ docutils/parsers/rst/directives/body.py
-@@ -19,9 +19,8 @@ from docutils.utils.code_analyzer import
-
-
- class BasePseudoSection(Directive):
-+ """Base class for Topic and Sidebar."""
-
-- required_arguments = 1
-- optional_arguments = 0
- final_argument_whitespace = True
- option_spec = {'class': directives.class_option,
- 'name': directives.unchanged}
-@@ -31,8 +30,8 @@ class BasePseudoSection(Directive):
- """Node class to be used (must be set in subclasses)."""
-
- def run(self):
-- if not (self.state_machine.match_titles
-- or isinstance(self.state_machine.node, nodes.sidebar)):
-+ if not isinstance(self.state_machine.node,
-+ (nodes.document, nodes.section, nodes.sidebar)):
- raise self.error('The "%s" directive may not be used within '
- 'topics or body elements.' % self.name)
- self.assert_has_content()
-@@ -64,15 +63,14 @@ class BasePseudoSection(Directive):
-
- class Topic(BasePseudoSection):
-
-+ required_arguments = 1
- node_class = nodes.topic
-
-
- class Sidebar(BasePseudoSection):
-
-- node_class = nodes.sidebar
--
-- required_arguments = 0
- optional_arguments = 1
-+ node_class = nodes.sidebar
- option_spec = BasePseudoSection.option_spec | {
- 'subtitle': directives.unchanged_required}
-
diff --git a/py-docutils/patches/patch-docutils_parsers_rst_directives_misc.py b/py-docutils/patches/patch-docutils_parsers_rst_directives_misc.py
deleted file mode 100644
index c4783e5a32..0000000000
--- a/py-docutils/patches/patch-docutils_parsers_rst_directives_misc.py
+++ /dev/null
@@ -1,13 +0,0 @@
-$NetBSD$
-
---- docutils/parsers/rst/directives/misc.py.orig 2025-07-29 14:37:38.096681000 +0000
-+++ docutils/parsers/rst/directives/misc.py
-@@ -236,8 +236,6 @@ class Include(Directive):
- def insert_into_input_lines(self, text: str) -> None:
- """Insert file content into the rST input of the calling parser.
-
-- Returns an empty list to comply with the API of `Directive.run()`.
--
- Provisional.
- """
- source = self.options['source']
diff --git a/py-docutils/patches/patch-docutils_parsers_rst_directives_parts.py b/py-docutils/patches/patch-docutils_parsers_rst_directives_parts.py
deleted file mode 100644
index 6be7140786..0000000000
--- a/py-docutils/patches/patch-docutils_parsers_rst_directives_parts.py
+++ /dev/null
@@ -1,15 +0,0 @@
-$NetBSD$
-
---- docutils/parsers/rst/directives/parts.py.orig 2025-07-29 14:37:38.160271400 +0000
-+++ docutils/parsers/rst/directives/parts.py
-@@ -43,8 +43,8 @@ class Contents(Directive):
- 'class': directives.class_option}
-
- def run(self):
-- if not (self.state_machine.match_titles
-- or isinstance(self.state_machine.node, nodes.sidebar)):
-+ if not isinstance(self.state_machine.node,
-+ (nodes.document, nodes.section, nodes.sidebar)):
- raise self.error('The "%s" directive may not be used within '
- 'topics or body elements.' % self.name)
- document = self.state_machine.document
diff --git a/py-docutils/patches/patch-docutils_parsers_rst_states.py b/py-docutils/patches/patch-docutils_parsers_rst_states.py
deleted file mode 100644
index 6ef9871d3f..0000000000
--- a/py-docutils/patches/patch-docutils_parsers_rst_states.py
+++ /dev/null
@@ -1,562 +0,0 @@
-$NetBSD$
-
---- docutils/parsers/rst/states.py.orig 2025-07-29 14:37:37.894344600 +0000
-+++ docutils/parsers/rst/states.py
-@@ -107,6 +107,7 @@ __docformat__ = 'reStructuredText'
- import re
- from types import FunctionType, MethodType
- from types import SimpleNamespace as Struct
-+import warnings
-
- from docutils import nodes, statemachine, utils
- from docutils import ApplicationError, DataError
-@@ -121,6 +122,10 @@ from docutils.utils import split_escaped
- from docutils.utils._roman_numerals import (InvalidRomanNumeralError,
- RomanNumeral)
-
-+TYPE_CHECKING = False
-+if TYPE_CHECKING:
-+ from docutils.statemachine import StringList
-+
-
- class MarkupError(DataError): pass
- class UnknownInterpretedRoleError(DataError): pass
-@@ -136,6 +141,15 @@ class RSTStateMachine(StateMachineWS):
-
- The entry point to reStructuredText parsing is the `run()` method.
- """
-+ section_level_offset: int = 0
-+ """Correction term for section level determination in nested parsing.
-+
-+ Updated by `RSTState.nested_parse()` and used in
-+ `RSTState.check_subsection()` to compensate differences when
-+ nested parsing uses a detached base node with a document-wide
-+ section title style hierarchy or the current node with a new,
-+ independent title style hierarchy.
-+ """
-
- def run(self, input_lines, document, input_offset=0, match_titles=True,
- inliner=None) -> None:
-@@ -151,16 +165,19 @@ class RSTStateMachine(StateMachineWS):
- if inliner is None:
- inliner = Inliner()
- inliner.init_customizations(document.settings)
-+ # A collection of objects to share with nested parsers.
-+ # The attributes `reporter`, `section_level`, and
-+ # `section_bubble_up_kludge` will be removed in Docutils 2.0
- self.memo = Struct(document=document,
-- reporter=document.reporter,
-+ reporter=document.reporter, # ignored
- language=self.language,
- title_styles=[],
-- section_level=0, # ignored, to be removed in 2.0
-- section_bubble_up_kludge=False, # ignored, ""
-+ section_level=0, # ignored
-+ section_bubble_up_kludge=False, # ignored
- inliner=inliner)
- self.document = document
- self.attach_observer(document.note_source)
-- self.reporter = self.memo.reporter
-+ self.reporter = self.document.reporter
- self.node = document
- results = StateMachineWS.run(self, input_lines, input_offset,
- input_source=document['source'])
-@@ -168,16 +185,23 @@ class RSTStateMachine(StateMachineWS):
- self.node = self.memo = None # remove unneeded references
-
-
--class NestedStateMachine(StateMachineWS):
--
-+class NestedStateMachine(RSTStateMachine):
- """
- StateMachine run from within other StateMachine runs, to parse nested
- document structures.
- """
-
-+ def __init__(self, state_classes, initial_state,
-+ debug=False, parent_state_machine=None) -> None:
-+
-+ self.parent_state_machine = parent_state_machine
-+ """The instance of the parent state machine."""
-+
-+ super().__init__(state_classes, initial_state, debug)
-+
- def run(self, input_lines, input_offset, memo, node, match_titles=True):
- """
-- Parse `input_lines` and populate a `docutils.nodes.document` instance.
-+ Parse `input_lines` and populate `node`.
-
- Extend `StateMachineWS.run()`: set up document-wide data.
- """
-@@ -185,8 +209,8 @@ class NestedStateMachine(StateMachineWS)
- self.memo = memo
- self.document = memo.document
- self.attach_observer(self.document.note_source)
-- self.reporter = memo.reporter
- self.language = memo.language
-+ self.reporter = self.document.reporter
- self.node = node
- results = StateMachineWS.run(self, input_lines, input_offset)
- assert results == [], ('NestedStateMachine.run() results should be '
-@@ -205,7 +229,7 @@ class RSTState(StateWS):
- nested_sm = NestedStateMachine
- nested_sm_cache = []
-
-- def __init__(self, state_machine, debug=False) -> None:
-+ def __init__(self, state_machine: RSTStateMachine, debug=False) -> None:
- self.nested_sm_kwargs = {'state_classes': state_classes,
- 'initial_state': 'Body'}
- StateWS.__init__(self, state_machine, debug)
-@@ -214,14 +238,21 @@ class RSTState(StateWS):
- StateWS.runtime_init(self)
- memo = self.state_machine.memo
- self.memo = memo
-- self.reporter = memo.reporter
-- self.inliner = memo.inliner
- self.document = memo.document
-- self.parent = self.state_machine.node
-+ self.inliner = memo.inliner
-+ self.reporter = self.document.reporter
- # enable the reporter to determine source and source-line
- if not hasattr(self.reporter, 'get_source_and_line'):
- self.reporter.get_source_and_line = self.state_machine.get_source_and_line # noqa:E501
-
-+ @property
-+ def parent(self) -> nodes.Element | None:
-+ return self.state_machine.node
-+
-+ @parent.setter
-+ def parent(self, value: nodes.Element):
-+ self.state_machine.node = value
-+
- def goto_line(self, abs_line_offset) -> None:
- """
- Jump to input line `abs_line_offset`, ignoring jumps past the end.
-@@ -248,12 +279,45 @@ class RSTState(StateWS):
- """Called at beginning of file."""
- return [], []
-
-- def nested_parse(self, block, input_offset, node, match_titles=False,
-- state_machine_class=None, state_machine_kwargs=None):
-- """
-- Create a new StateMachine rooted at `node` and run it over the input
-- `block`.
-+ def nested_parse(self,
-+ block: StringList,
-+ input_offset: int,
-+ node: nodes.Element|None = None,
-+ match_titles: bool = False,
-+ state_machine_class: StateMachineWS|None = None,
-+ state_machine_kwargs: dict|None = None
-+ ) -> int:
-+ """
-+ Parse the input `block` with a nested state-machine rooted at `node`.
-+
-+ :block:
-+ reStructuredText source extract.
-+ :input_offset:
-+ Line number at start of the block.
-+ :node:
-+ Base node. Generated nodes will be appended to this node.
-+ Default: the "current node" (`self.state_machine.node`).
-+ :match_titles:
-+ Allow section titles?
-+ Caution: With a custom base node, this may lead to an invalid
-+ or mixed up document tree. [#]_
-+ :state_machine_class:
-+ Default: `NestedStateMachine`.
-+ :state_machine_kwargs:
-+ Keyword arguments for the state-machine instantiation.
-+ Default: `self.nested_sm_kwargs`.
-+
-+ Create a new state-machine instance if required.
-+ Return new offset.
-+
-+ .. [#] See also ``test_parsers/test_rst/test_nested_parsing.py``
-+ and Sphinx's `nested_parse_to_nodes()`__.
-+
-+ __ https://www.sphinx-doc.org/en/master/extdev/utils.html
-+ #sphinx.util.parsing.nested_parse_to_nodes
- """
-+ if node is None:
-+ node = self.state_machine.node
- use_default = 0
- if state_machine_class is None:
- state_machine_class = self.nested_sm
-@@ -261,24 +325,54 @@ class RSTState(StateWS):
- if state_machine_kwargs is None:
- state_machine_kwargs = self.nested_sm_kwargs
- use_default += 1
-- block_length = len(block)
--
-- state_machine = None
-+ my_state_machine = None
- if use_default == 2:
- try:
-- state_machine = self.nested_sm_cache.pop()
-+ # get cached state machine, prevent others from using it
-+ my_state_machine = self.nested_sm_cache.pop()
- except IndexError:
- pass
-- if not state_machine:
-- state_machine = state_machine_class(debug=self.debug,
-- **state_machine_kwargs)
-- state_machine.run(block, input_offset, memo=self.memo,
-- node=node, match_titles=match_titles)
-+ if not my_state_machine:
-+ my_state_machine = state_machine_class(
-+ debug=self.debug,
-+ parent_state_machine=self.state_machine,
-+ **state_machine_kwargs)
-+ # Check if we may use sections (with a caveat for custom nodes
-+ # that may be dummies to collect children):
-+ if (node == self.state_machine.node
-+ and not isinstance(node, (nodes.document, nodes.section))):
-+ match_titles = False # avoid invalid sections
-+ if match_titles:
-+ # Compensate mismatch of known title styles and number of
-+ # parent sections of the base node if the document wide
-+ # title styles are used with a detached base node or
-+ # a new list of title styles with the current parent node:
-+ l_node = len(node.section_hierarchy())
-+ l_start = min(len(self.parent.section_hierarchy()),
-+ len(self.memo.title_styles))
-+ my_state_machine.section_level_offset = l_start - l_node
-+
-+ # run the state machine and populate `node`:
-+ block_length = len(block)
-+ my_state_machine.run(block, input_offset, self.memo,
-+ node, match_titles)
-+
-+ if match_titles:
-+ if node == self.state_machine.node:
-+ # Pass on the new "current node" to parent state machines:
-+ sm = self.state_machine
-+ try:
-+ while True:
-+ sm.node = my_state_machine.node
-+ sm = sm.parent_state_machine
-+ except AttributeError:
-+ pass
-+ # clean up
-+ new_offset = my_state_machine.abs_line_offset()
- if use_default == 2:
-- self.nested_sm_cache.append(state_machine)
-+ self.nested_sm_cache.append(my_state_machine)
- else:
-- state_machine.unlink()
-- new_offset = state_machine.abs_line_offset()
-+ my_state_machine.unlink()
- # No `block.parent` implies disconnected -- lines aren't in sync:
- if block.parent and (len(block) - block_length) != 0:
- # Adjustment for block if modified in nested parse:
-@@ -289,31 +383,45 @@ class RSTState(StateWS):
- blank_finish,
- blank_finish_state=None,
- extra_settings={},
-- match_titles=False,
-+ match_titles=False, # deprecated, will be removed
- state_machine_class=None,
- state_machine_kwargs=None):
- """
-- Create a new StateMachine rooted at `node` and run it over the input
-- `block`. Also keep track of optional intermediate blank lines and the
-+ Parse the input `block` with a nested state-machine rooted at `node`.
-+
-+ Create a new StateMachine rooted at `node` and run it over the
-+ input `block` (see also `nested_parse()`).
-+ Also keep track of optional intermediate blank lines and the
- required final one.
-+
-+ Return new offset and a boolean indicating whether there was a
-+ blank final line.
- """
-+ if match_titles:
-+ warnings.warn('The "match_titles" argument of '
-+ 'parsers.rst.states.RSTState.nested_list_parse() '
-+ 'will be ignored in Docutils 1.0 '
-+ 'and removed in Docutils 2.0.',
-+ PendingDeprecationWarning, stacklevel=2)
- if state_machine_class is None:
- state_machine_class = self.nested_sm
- if state_machine_kwargs is None:
- state_machine_kwargs = self.nested_sm_kwargs.copy()
- state_machine_kwargs['initial_state'] = initial_state
-- state_machine = state_machine_class(debug=self.debug,
-- **state_machine_kwargs)
-+ my_state_machine = state_machine_class(
-+ debug=self.debug,
-+ parent_state_machine=self.state_machine,
-+ **state_machine_kwargs)
- if blank_finish_state is None:
- blank_finish_state = initial_state
-- state_machine.states[blank_finish_state].blank_finish = blank_finish
-+ my_state_machine.states[blank_finish_state].blank_finish = blank_finish
- for key, value in extra_settings.items():
-- setattr(state_machine.states[initial_state], key, value)
-- state_machine.run(block, input_offset, memo=self.memo,
-- node=node, match_titles=match_titles)
-- blank_finish = state_machine.states[blank_finish_state].blank_finish
-- state_machine.unlink()
-- return state_machine.abs_line_offset(), blank_finish
-+ setattr(my_state_machine.states[initial_state], key, value)
-+ my_state_machine.run(block, input_offset, memo=self.memo,
-+ node=node, match_titles=match_titles)
-+ blank_finish = my_state_machine.states[blank_finish_state].blank_finish
-+ my_state_machine.unlink()
-+ return my_state_machine.abs_line_offset(), blank_finish
-
- def section(self, title, source, style, lineno, messages) -> None:
- """Check for a valid subsection and create one if it checks out."""
-@@ -326,40 +434,60 @@ class RSTState(StateWS):
-
- When a new section is reached that isn't a subsection of the current
- section, set `self.parent` to the new section's parent section
-- (or the document if the new section is a top-level section).
-+ (or the root node if the new section is a top-level section).
- """
- title_styles = self.memo.title_styles
- parent_sections = self.parent.section_hierarchy()
-- # current section level: (0 document, 1 section, 2 subsection, ...)
-- mylevel = len(parent_sections)
-- # Determine the level of the new section:
-+ # current section level: (0 root, 1 section, 2 subsection, ...)
-+ oldlevel = (len(parent_sections)
-+ + self.state_machine.section_level_offset)
-+ # new section level:
- try: # check for existing title style
-- level = title_styles.index(style) + 1
-+ newlevel = title_styles.index(style) + 1
- except ValueError: # new title style
-- title_styles.append(style)
-- level = len(title_styles)
-+ newlevel = len(title_styles) + 1
- # The new level must not be deeper than an immediate child
- # of the current level:
-- if level > mylevel + 1:
-- styles = " ".join("/".join(s for s in style)
-- for style in title_styles)
-- self.parent += self.reporter.severe(
-+ if newlevel > oldlevel + 1:
-+ styles = ' '.join('/'.join(style) for style in title_styles)
-+ self.parent += self.reporter.error(
- 'Inconsistent title style:'
-- f' skip from level {mylevel} to {level}.',
-+ f' skip from level {oldlevel} to {newlevel}.',
- nodes.literal_block('', source),
- nodes.paragraph('', f'Established title styles: {styles}'),
- line=lineno)
- return False
-- # Update parent state:
-- self.memo.section_level = level
-- if level <= mylevel:
-+ if newlevel <= oldlevel:
- # new section is sibling or higher up in the section hierarchy
-- self.parent = parent_sections[level-1].parent
-+ try:
-+ new_parent = parent_sections[newlevel-oldlevel-1].parent
-+ except IndexError:
-+ styles = ' '.join('/'.join(style) for style in title_styles)
-+ details = (f'The parent of level {newlevel} sections cannot'
-+ ' be reached. The parser is at section level'
-+ f' {oldlevel} but the current node has only'
-+ f' {len(parent_sections)} parent section(s).'
-+ '\nOne reason may be a high level'
-+ ' section used in a directive that parses its'
-+ ' content into a base node not attached to'
-+ ' the document\n(up to Docutils 0.21,'
-+ ' these sections were silently dropped).')
-+ self.parent += self.reporter.error(
-+ f'A level {newlevel} section cannot be used here.',
-+ nodes.literal_block('', source),
-+ nodes.paragraph('', f'Established title styles: {styles}'),
-+ nodes.paragraph('', details),
-+ line=lineno)
-+ return False
-+ self.parent = new_parent
-+ self.memo.section_level = newlevel - 1
-+ if newlevel > len(title_styles):
-+ title_styles.append(style)
- return True
-
- def title_inconsistent(self, sourcetext, lineno):
- # Ignored. Will be removed in Docutils 2.0.
-- error = self.reporter.severe(
-+ error = self.reporter.error(
- 'Title level inconsistent:', nodes.literal_block('', sourcetext),
- line=lineno)
- return error
-@@ -377,15 +505,8 @@ class RSTState(StateWS):
- section_node += title_messages
- self.document.note_implicit_target(section_node, section_node)
- # Update state:
-- self.state_machine.node = section_node
-- # Also update the ".parent" attribute in all states.
-- # This is a bit violent, but the state classes copy their .parent from
-- # state_machine.node on creation, so we need to update them. We could
-- # also remove RSTState.parent entirely and replace references to it
-- # with statemachine.node, but that might break code downstream of
-- # docutils.
-- for s in self.state_machine.states.values():
-- s.parent = section_node
-+ self.parent = section_node
-+ self.memo.section_level += 1
-
- def paragraph(self, lines, lineno):
- """
-@@ -620,9 +741,9 @@ class Inliner:
- :text: source string
- :lineno: absolute line number, cf. `statemachine.get_source_and_line()`
- """
-- self.reporter = memo.reporter
- self.document = memo.document
- self.language = memo.language
-+ self.reporter = self.document.reporter
- self.parent = parent
- pattern_search = self.patterns.initial.search
- dispatch = self.dispatch
-@@ -1600,7 +1721,7 @@ class Body(RSTState):
- self.state_machine.input_lines[offset:],
- input_offset=self.state_machine.abs_line_offset() + 1,
- node=block, initial_state='LineBlock',
-- blank_finish=0)
-+ blank_finish=False)
- self.goto_line(new_line_offset)
- if not blank_finish:
- self.parent += self.reporter.warning(
-@@ -1695,14 +1816,14 @@ class Body(RSTState):
-
- def isolate_grid_table(self):
- messages = []
-- blank_finish = 1
-+ blank_finish = True
- try:
- block = self.state_machine.get_text_block(flush_left=True)
- except statemachine.UnexpectedIndentationError as err:
- block, src, srcline = err.args
- messages.append(self.reporter.error('Unexpected indentation.',
- source=src, line=srcline))
-- blank_finish = 0
-+ blank_finish = False
- block.disconnect()
- # for East Asian chars:
- block.pad_double_width(self.double_width_pad_char)
-@@ -1710,24 +1831,26 @@ class Body(RSTState):
- for i in range(len(block)):
- block[i] = block[i].strip()
- if block[i][0] not in '+|': # check left edge
-- blank_finish = 0
-+ blank_finish = False
- self.state_machine.previous_line(len(block) - i)
- del block[i:]
- break
- if not self.grid_table_top_pat.match(block[-1]): # find bottom
-- blank_finish = 0
- # from second-last to third line of table:
- for i in range(len(block) - 2, 1, -1):
- if self.grid_table_top_pat.match(block[i]):
- self.state_machine.previous_line(len(block) - i + 1)
- del block[i+1:]
-+ blank_finish = False
- break
- else:
-- messages.extend(self.malformed_table(block))
-+ detail = 'Bottom border missing or corrupt.'
-+ messages.extend(self.malformed_table(block, detail, i))
- return [], messages, blank_finish
- for i in range(len(block)): # check right edge
- if len(block[i]) != width or block[i][-1] not in '+|':
-- messages.extend(self.malformed_table(block))
-+ detail = 'Right border not aligned or missing.'
-+ messages.extend(self.malformed_table(block, detail, i))
- return [], messages, blank_finish
- return block, messages, blank_finish
-
-@@ -1747,8 +1870,8 @@ class Body(RSTState):
- if len(line.strip()) != toplen:
- self.state_machine.next_line(i - start)
- messages = self.malformed_table(
-- lines[start:i+1], 'Bottom/header table border does '
-- 'not match top border.')
-+ lines[start:i+1], 'Bottom border or header rule does '
-+ 'not match top border.', i-start)
- return [], messages, i == limit or not lines[i+1].strip()
- found += 1
- found_at = i
-@@ -1757,17 +1880,16 @@ class Body(RSTState):
- break
- i += 1
- else: # reached end of input_lines
-+ details = 'No bottom table border found'
- if found:
-- extra = ' or no blank line after table bottom'
-+ details += ' or no blank line after table bottom'
- self.state_machine.next_line(found_at - start)
- block = lines[start:found_at+1]
- else:
-- extra = ''
- self.state_machine.next_line(i - start - 1)
- block = lines[start:]
-- messages = self.malformed_table(
-- block, 'No bottom table border found%s.' % extra)
-- return [], messages, not extra
-+ messages = self.malformed_table(block, details + '.')
-+ return [], messages, not found
- self.state_machine.next_line(end - start)
- block = lines[start:end+1]
- # for East Asian chars:
-@@ -2382,8 +2504,7 @@ class Body(RSTState):
- self.state_machine.input_lines[offset:],
- input_offset=self.state_machine.abs_line_offset() + 1,
- node=self.parent, initial_state='Explicit',
-- blank_finish=blank_finish,
-- match_titles=self.state_machine.match_titles)
-+ blank_finish=blank_finish)
- self.goto_line(newline_offset)
- if not blank_finish:
- self.parent += self.unindent_warning('Explicit markup')
-@@ -2420,7 +2541,7 @@ class Body(RSTState):
- raise statemachine.TransitionCorrection('text')
- else:
- blocktext = self.state_machine.line
-- msg = self.reporter.severe(
-+ msg = self.reporter.error(
- 'Unexpected section title or transition.',
- nodes.literal_block(blocktext, blocktext),
- line=self.state_machine.abs_line_number())
-@@ -2775,7 +2896,7 @@ class Text(RSTState):
- # if the error is in a table (try with test_tables.py)?
- # print("get_source_and_line", srcline)
- # print("abs_line_number", self.state_machine.abs_line_number())
-- msg = self.reporter.severe(
-+ msg = self.reporter.error(
- 'Unexpected section title.',
- nodes.literal_block(blocktext, blocktext),
- source=src, line=srcline)
-@@ -2977,7 +3098,7 @@ class Line(SpecializedText):
- if len(overline.rstrip()) < 4:
- self.short_overline(context, blocktext, lineno, 2)
- else:
-- msg = self.reporter.severe(
-+ msg = self.reporter.error(
- 'Incomplete section title.',
- nodes.literal_block(blocktext, blocktext),
- line=lineno)
-@@ -2991,7 +3112,7 @@ class Line(SpecializedText):
- if len(overline.rstrip()) < 4:
- self.short_overline(context, blocktext, lineno, 2)
- else:
-- msg = self.reporter.severe(
-+ msg = self.reporter.error(
- 'Missing matching underline for section title overline.',
- nodes.literal_block(source, source),
- line=lineno)
-@@ -3002,7 +3123,7 @@ class Line(SpecializedText):
- if len(overline.rstrip()) < 4:
- self.short_overline(context, blocktext, lineno, 2)
- else:
-- msg = self.reporter.severe(
-+ msg = self.reporter.error(
- 'Title overline & underline mismatch.',
- nodes.literal_block(source, source),
- line=lineno)
diff --git a/py-docutils/patches/patch-docutils_statemachine.py b/py-docutils/patches/patch-docutils_statemachine.py
deleted file mode 100644
index 4fab9d76d9..0000000000
--- a/py-docutils/patches/patch-docutils_statemachine.py
+++ /dev/null
@@ -1,30 +0,0 @@
-$NetBSD$
-
---- docutils/statemachine.py.orig 2025-07-29 14:37:38.508729200 +0000
-+++ docutils/statemachine.py
-@@ -140,7 +140,6 @@ class StateMachine:
- - `initial_state`: a string, the class name of the initial state.
- - `debug`: a boolean; produce verbose output if true (nonzero).
- """
--
- self.input_lines = None
- """`StringList` of input lines (without newlines).
- Filled by `self.run()`."""
-@@ -1406,7 +1405,7 @@ class StringList(ViewList):
- stripped = line.lstrip()
- if not stripped: # blank line
- if until_blank:
-- blank_finish = 1
-+ blank_finish = True
- break
- elif block_indent is None:
- line_indent = len(line) - len(stripped)
-@@ -1416,7 +1415,7 @@ class StringList(ViewList):
- indent = min(indent, line_indent)
- end += 1
- else:
-- blank_finish = 1 # block ends at end of lines
-+ blank_finish = True # block ends at end of lines
- block = self[start:end]
- if first_indent is not None and block:
- block.data[0] = block.data[0][first_indent:]
diff --git a/py-docutils/patches/patch-docutils_transforms_references.py b/py-docutils/patches/patch-docutils_transforms_references.py
deleted file mode 100644
index 3c6113f79d..0000000000
--- a/py-docutils/patches/patch-docutils_transforms_references.py
+++ /dev/null
@@ -1,53 +0,0 @@
-$NetBSD$
-
---- docutils/transforms/references.py.orig 2025-07-29 14:37:38.409054500 +0000
-+++ docutils/transforms/references.py
-@@ -542,10 +542,12 @@ class Footnotes(Transform):
- try:
- label = self.autofootnote_labels[i]
- except IndexError:
-+ n = len(self.autofootnote_labels)
-+ s = 's' if n > 1 else ''
- msg = self.document.reporter.error(
-- 'Too many autonumbered footnote references: only %s '
-- 'corresponding footnotes available.'
-- % len(self.autofootnote_labels), base_node=ref)
-+ 'Too many autonumbered footnote references: '
-+ f'only {n} corresponding footnote{s} available.',
-+ base_node=ref)
- msgid = self.document.set_id(msg)
- for ref in self.document.autofootnote_refs[i:]:
- if ref.resolved or ref.hasattr('refname'):
-@@ -953,11 +955,29 @@ class DanglingReferencesVisitor(nodes.Sp
- if refname in self.document.nameids:
- msg = self.document.reporter.error(
- 'Duplicate target name, cannot be used as a unique '
-- 'reference: "%s".' % (node['refname']), base_node=node)
-+ f'reference: "{refname}".', base_node=node)
- else:
-+ if '<' in refname or '>' in refname:
-+ hint = 'Did you want to embed a URI or alias?'
-+ if '<' not in refname:
-+ hint += '\nOpening bracket missing.'
-+ elif ' <' not in refname:
-+ hint += ('\nThe embedded reference must be preceded'
-+ ' by whitespace.')
-+ if '>' not in refname:
-+ hint += '\nClosing bracket missing.'
-+ elif not refname.endswith('>'):
-+ hint += ('\nThe embedded reference must be the last text'
-+ ' before the end string.')
-+ if '< ' in refname or ' >' in refname:
-+ hint += ('\nWhitespace around the embedded reference'
-+ ' is not allowed.')
-+ details = [nodes.paragraph('', hint)]
-+ else:
-+ details = []
- msg = self.document.reporter.error(
-- f'Unknown target name: "{node["refname"]}".',
-- base_node=node)
-+ f'Unknown target name: "{refname}".',
-+ *details, base_node=node)
- msgid = self.document.set_id(msg)
- prb = nodes.problematic(node.rawsource, node.rawsource, refid=msgid)
- try:
diff --git a/py-docutils/patches/patch-docutils_writers___html__base.py b/py-docutils/patches/patch-docutils_writers___html__base.py
deleted file mode 100644
index f7e56c892f..0000000000
--- a/py-docutils/patches/patch-docutils_writers___html__base.py
+++ /dev/null
@@ -1,24 +0,0 @@
-$NetBSD$
-
---- docutils/writers/_html_base.py.orig 2025-07-29 14:37:37.539381000 +0000
-+++ docutils/writers/_html_base.py
-@@ -115,16 +115,16 @@ class Writer(writers.Writer):
- ('Disable compact simple field lists.',
- ['--no-compact-field-lists'],
- {'dest': 'compact_field_lists', 'action': 'store_false'}),
-- ('Added to standard table classes. '
-+ ('Class value(s) assigned to all tables. '
- 'Defined styles: borderless, booktabs, '
- 'align-left, align-center, align-right, '
- 'colwidths-auto, colwidths-grid.',
- ['--table-style'],
-- {'default': ''}),
-+ {'metavar': '<style>', 'default': ''}),
- ('Math output format (one of "MathML", "HTML", "MathJax", '
- 'or "LaTeX") and option(s). (default: "MathML")',
- ['--math-output'],
-- {'default': 'MathML',
-+ {'metavar': '<format [option(s)]>', 'default': 'MathML',
- 'validator': frontend.validate_math_output}),
- ('Prepend an XML declaration. ',
- ['--xml-declaration'],
diff --git a/py-docutils/patches/patch-docutils_writers_html4css1_____init____.py b/py-docutils/patches/patch-docutils_writers_html4css1_____init____.py
deleted file mode 100644
index 34e1550774..0000000000
--- a/py-docutils/patches/patch-docutils_writers_html4css1_____init____.py
+++ /dev/null
@@ -1,13 +0,0 @@
-$NetBSD$
-
---- docutils/writers/html4css1/__init__.py.orig 2025-07-29 14:37:37.693212000 +0000
-+++ docutils/writers/html4css1/__init__.py
-@@ -74,7 +74,7 @@ class Writer(writers._html_base.Writer):
- 'Math output format (one of "MathML", "HTML", "MathJax", or '
- '"LaTeX") and option(s). (default: "HTML math.css")',
- ['--math-output'],
-- {'default': 'HTML math.css',
-+ {'metavar': '<format [option(s)]>', 'default': 'HTML math.css',
- 'validator': frontend.validate_math_output}),
- xml_declaration=(
- 'Prepend an XML declaration (default). ',
diff --git a/py-docutils/patches/patch-docutils_writers_html5__polyglot_____init____.py b/py-docutils/patches/patch-docutils_writers_html5__polyglot_____init____.py
deleted file mode 100644
index 10973367a9..0000000000
--- a/py-docutils/patches/patch-docutils_writers_html5__polyglot_____init____.py
+++ /dev/null
@@ -1,13 +0,0 @@
-$NetBSD$
-
---- docutils/writers/html5_polyglot/__init__.py.orig 2025-07-29 14:37:37.693464500 +0000
-+++ docutils/writers/html5_polyglot/__init__.py
-@@ -93,7 +93,7 @@ class Writer(_html_base.Writer):
- ('Suggest at which point images should be loaded: '
- '"embed", "link" (default), or "lazy".',
- ['--image-loading'],
-- {'choices': ('embed', 'link', 'lazy'),
-+ {'metavar': '<strategy>', 'choices': ('embed', 'link', 'lazy'),
- # 'default': 'link' # default set in _html_base.py
- }),
- ('Append a self-link to section headings.',
diff --git a/py-docutils/patches/patch-docutils_writers_latex2e_____init____.py b/py-docutils/patches/patch-docutils_writers_latex2e_____init____.py
deleted file mode 100644
index d8c16a03e8..0000000000
--- a/py-docutils/patches/patch-docutils_writers_latex2e_____init____.py
+++ /dev/null
@@ -1,504 +0,0 @@
-$NetBSD$
-
---- docutils/writers/latex2e/__init__.py.orig 2025-07-29 14:37:37.736252500 +0000
-+++ docutils/writers/latex2e/__init__.py
-@@ -47,11 +47,11 @@ class Writer(writers.Writer):
- None,
- (('Specify LaTeX documentclass. Default: "article".',
- ['--documentclass'],
-- {'default': 'article', }),
-+ {'metavar': '<documentclass>', 'default': 'article'}),
- ('Specify document options. Multiple options can be given, '
- 'separated by commas. Default: "a4paper".',
- ['--documentoptions'],
-- {'default': 'a4paper', }),
-+ {'metavar': '<options>', 'default': 'a4paper'}),
- ('Format for footnote references: one of "superscript" or '
- '"brackets". Default: "superscript".',
- ['--footnote-references'],
-@@ -105,7 +105,7 @@ class Writer(writers.Writer):
- ('Customization by LaTeX code in the preamble. '
- 'Default: select PDF standard fonts (Times, Helvetica, Courier).',
- ['--latex-preamble'],
-- {'default': default_preamble}),
-+ {'metavar': '<preamble>', 'default': default_preamble}),
- ('Specify the template file. Default: "%s".' % default_template,
- ['--template'],
- {'default': default_template, 'metavar': '<file>'}),
-@@ -139,9 +139,11 @@ class Writer(writers.Writer):
- 'validator': frontend.validate_boolean}),
- ('Color of any hyperlinks embedded in text. '
- 'Default: "blue" (use "false" to disable).',
-- ['--hyperlink-color'], {'default': 'blue'}),
-+ ['--hyperlink-color'],
-+ {'metavar': '<color>', 'default': 'blue'}),
- ('Additional options to the "hyperref" package.',
-- ['--hyperref-options'], {'default': ''}),
-+ ['--hyperref-options'],
-+ {'metavar': '<options>', 'default': ''}),
- ('Enable compound enumerators for nested enumerated lists '
- '(e.g. "1.2.a.ii").',
- ['--compound-enumerators'],
-@@ -166,8 +168,8 @@ class Writer(writers.Writer):
- ('When possible, use the specified environment for literal-blocks. '
- 'Default: "" (fall back to "alltt").',
- ['--literal-block-env'],
-- {'default': ''}),
-- ('Deprecated alias for "--literal-block-env=verbatim".',
-+ {'metavar': '<environment>', 'default': ''}),
-+ (frontend.SUPPRESS_HELP, # deprecated legacy option
- ['--use-verbatim-when-possible'],
- {'action': 'store_true',
- 'validator': frontend.validate_boolean}),
-@@ -181,22 +183,19 @@ class Writer(writers.Writer):
- 'action': 'append',
- 'validator': frontend.validate_comma_separated_list,
- 'choices': table_style_values}),
-- ('LaTeX graphicx package option. '
-- 'Possible values are "dvipdfmx", "dvips", "dvisvgm", '
-- '"luatex", "pdftex", and "xetex".'
-- 'Default: "".',
-+ ('LaTeX graphicx package option. Default: "".',
- ['--graphicx-option'],
-- {'default': ''}),
-+ {'metavar': '<option>', 'default': ''}),
- ('LaTeX font encoding. '
- 'Possible values are "", "T1" (default), "OT1", "LGR,T1" or '
- 'any other combination of options to the `fontenc` package. ',
- ['--font-encoding'],
-- {'default': 'T1'}),
-+ {'metavar': '<encoding>', 'default': 'T1'}),
- ('Per default the latex-writer puts the reference title into '
-- 'hyperreferences. Specify "ref*" or "pageref*" to get the section '
-+ 'hyperreferences. Specify "ref" or "pageref" to get the section '
- 'number or the page number.',
- ['--reference-label'],
-- {'default': ''}),
-+ {'metavar': '<command name>', 'default': ''}),
- ('Specify style and database(s) for bibtex, for example '
- '"--use-bibtex=unsrt,mydb1,mydb2". Provisional!',
- ['--use-bibtex'],
-@@ -938,24 +937,25 @@ class Table:
- return ''
-
- def get_opening(self, width=r'\linewidth'):
-+ opening = []
-+ nr_of_cols = len(self._col_specs)
- align_map = {'left': '[l]',
- 'center': '[c]',
- 'right': '[r]',
- None: ''}
- align = align_map.get(self.get('align'))
- latex_type = self.get_latex_type()
-- if align and latex_type not in ("longtable", "longtable*"):
-- opening = [r'\noindent\makebox[\linewidth]%s{%%' % (align,),
-- r'\begin{%s}' % (latex_type,)]
-- else:
-- opening = [r'\begin{%s}%s' % (latex_type, align)]
-+ if align and not latex_type.startswith("longtable"):
-+ opening.append(r'\noindent\makebox[\linewidth]%s{%%' % align)
-+ align = ''
- if not self.colwidths_auto:
- if self.borders == 'standard' and not self.legacy_column_widths:
-- opening.insert(-1, r'\setlength{\DUtablewidth}'
-+ opening.append(r'\setlength{\DUtablewidth}'
- r'{\dimexpr%s-%i\arrayrulewidth\relax}%%'
-- % (width, len(self._col_specs)+1))
-+ % (width, nr_of_cols+1))
- else:
-- opening.insert(-1, r'\setlength{\DUtablewidth}{%s}%%' % width)
-+ opening.append(r'\setlength{\DUtablewidth}{%s}%%' % width)
-+ opening.append(r'\begin{%s}%s' % (latex_type, align))
- return '\n'.join(opening)
-
- def get_closing(self):
-@@ -966,7 +966,7 @@ class Table:
- # closing.append(r'\hline')
- closing.append(r'\end{%s}' % self.get_latex_type())
- if (self.get('align')
-- and self.get_latex_type() not in ("longtable", "longtable*")):
-+ and not self.get_latex_type().startswith("longtable")):
- closing.append('}')
- return '\n'.join(closing)
-
-@@ -1359,7 +1359,7 @@ class LaTeXTranslator(writers.DoctreeTra
- else:
- # require a minimal version:
- self.fallbacks['_docutils.sty'] = (
-- r'\usepackage{docutils}[2024-09-24]')
-+ r'\usepackage{docutils}[2025-08-06]')
-
- self.stylesheet = [self.stylesheet_call(path)
- for path in stylesheet_list]
-@@ -1381,7 +1381,8 @@ class LaTeXTranslator(writers.DoctreeTra
- # -----------------
-
- def stylesheet_call(self, path):
-- """Return code to reference or embed stylesheet file `path`"""
-+ """Return code to reference or embed stylesheet file `path`."""
-+
- path = Path(path)
- # is it a package (no extension or *.sty) or "normal" tex code:
- is_package = path.suffix in ('.sty', '')
-@@ -1560,19 +1561,25 @@ class LaTeXTranslator(writers.DoctreeTra
- id for id in node['ids']))
-
- def ids_to_labels(self, node, set_anchor=True, protect=False,
-- newline=False) -> list[str]:
-+ newline=False, pre_nl=False) -> list[str]:
- """Return label definitions for all ids of `node`.
-
- If `set_anchor` is True, an anchor is set with \\phantomsection.
- If `protect` is True, the \\label cmd is made robust.
- If `newline` is True, a newline is added if there are labels.
-+ If `pre_nl` is True, a newline is prepended if there are labels.
-+
-+ Provisional.
- """
- prefix = '\\protect' if protect else ''
-- labels = [prefix + '\\label{%s}' % id for id in node['ids']]
-- if set_anchor and labels:
-- labels.insert(0, '\\phantomsection')
-- if newline and labels:
-- labels.append('\n')
-+ labels = [f'{prefix}\\label{{{id}}}' for id in node['ids']]
-+ if labels:
-+ if set_anchor:
-+ labels.insert(0, '\\phantomsection')
-+ if newline:
-+ labels.append('\n')
-+ if pre_nl:
-+ labels.insert(0, '\n')
- return labels
-
- def set_align_from_classes(self, node) -> None:
-@@ -1707,6 +1714,8 @@ class LaTeXTranslator(writers.DoctreeTra
- self.provide_fallback('admonition')
- if 'error' in node['classes']:
- self.provide_fallback('error')
-+ if not isinstance(node, nodes.system_message):
-+ self.out += self.ids_to_labels(node, pre_nl=True)
- self.duclass_open(node)
- self.out.append('\\begin{DUadmonition}')
-
-@@ -1739,6 +1748,7 @@ class LaTeXTranslator(writers.DoctreeTra
- self.depart_docinfo_item(node)
-
- def visit_block_quote(self, node) -> None:
-+ self.out += self.ids_to_labels(node, pre_nl=True)
- self.duclass_open(node)
- self.out.append('\\begin{quote}')
-
-@@ -1747,6 +1757,7 @@ class LaTeXTranslator(writers.DoctreeTra
- self.duclass_close(node)
-
- def visit_bullet_list(self, node) -> None:
-+ self.out += self.ids_to_labels(node, pre_nl=True)
- self.duclass_open(node)
- self.out.append('\\begin{itemize}')
-
-@@ -1771,7 +1782,7 @@ class LaTeXTranslator(writers.DoctreeTra
- self.out.append('}')
-
- def visit_caption(self, node) -> None:
-- self.out.append('\n\\caption{')
-+ self.out.append('\\caption{')
- self.visit_inline(node)
-
- def depart_caption(self, node) -> None:
-@@ -1869,6 +1880,7 @@ class LaTeXTranslator(writers.DoctreeTra
- def visit_compound(self, node) -> None:
- if isinstance(node.parent, nodes.compound):
- self.out.append('\n')
-+ self.out += self.ids_to_labels(node, pre_nl=True)
- node['classes'].insert(0, 'compound')
- self.duclass_open(node)
-
-@@ -1882,6 +1894,7 @@ class LaTeXTranslator(writers.DoctreeTra
- self.depart_docinfo_item(node)
-
- def visit_container(self, node) -> None:
-+ self.out += self.ids_to_labels(node, pre_nl=True)
- self.duclass_open(node)
-
- def depart_container(self, node) -> None:
-@@ -1913,6 +1926,7 @@ class LaTeXTranslator(writers.DoctreeTra
- pass
-
- def visit_definition_list(self, node) -> None:
-+ self.out += self.ids_to_labels(node, pre_nl=True)
- self.duclass_open(node)
- self.out.append('\\begin{description}\n')
-
-@@ -1921,7 +1935,7 @@ class LaTeXTranslator(writers.DoctreeTra
- self.duclass_close(node)
-
- def visit_definition_list_item(self, node) -> None:
-- pass
-+ self.out += self.ids_to_labels(node, newline=True)
-
- def depart_definition_list_item(self, node) -> None:
- if node.next_node(descend=False, siblings=True) is not None:
-@@ -2232,6 +2246,7 @@ class LaTeXTranslator(writers.DoctreeTra
- label = r'%s\%s{%s}%s' % (prefix, enumtype, counter_name, suffix)
- self._enumeration_counters.append(label)
-
-+ self.out += self.ids_to_labels(node, pre_nl=True)
- self.duclass_open(node)
- if enum_level <= 4:
- self.out.append('\\begin{enumerate}')
-@@ -2256,8 +2271,8 @@ class LaTeXTranslator(writers.DoctreeTra
- self._enumeration_counters.pop()
-
- def visit_field(self, node) -> None:
-+ self.out += self.ids_to_labels(node, pre_nl=True)
- # output is done in field_body, field_name
-- pass
-
- def depart_field(self, node) -> None:
- pass
-@@ -2271,6 +2286,7 @@ class LaTeXTranslator(writers.DoctreeTra
- self.out.append(r'\\'+'\n')
-
- def visit_field_list(self, node) -> None:
-+ self.out += self.ids_to_labels(node, pre_nl=True)
- self.duclass_open(node)
- if self.out is not self.docinfo:
- self.provide_fallback('fieldlist')
-@@ -2297,6 +2313,7 @@ class LaTeXTranslator(writers.DoctreeTra
-
- def visit_figure(self, node) -> None:
- self.requirements['float'] = PreambleCmds.float
-+ self.out += self.ids_to_labels(node, pre_nl=True)
- self.duclass_open(node)
- # The 'align' attribute sets the "outer alignment",
- # for "inner alignment" use LaTeX default alignment (similar to HTML)
-@@ -2305,10 +2322,9 @@ class LaTeXTranslator(writers.DoctreeTra
- # The LaTeX "figure" environment always uses the full linewidth,
- # so "outer alignment" is ignored. Just write a comment.
- # TODO: use the wrapfigure environment?
-- self.out.append('\\begin{figure} %% align = "%s"\n' % alignment)
-+ self.out.append('\\begin{figure} %% align = "%s"' % alignment)
- else:
-- self.out.append('\\begin{figure}\n')
-- self.out += self.ids_to_labels(node, newline=True)
-+ self.out.append('\\begin{figure}')
-
- def depart_figure(self, node) -> None:
- self.out.append('\\end{figure}\n')
-@@ -2335,9 +2351,6 @@ class LaTeXTranslator(writers.DoctreeTra
- num = '[%s]' % num
- self.out.append('%%\n\\DUfootnotetext{%s}{%s}{%s}{' %
- (node['ids'][0], backref, self.encode(num)))
-- if node['ids'] == [nodes.make_id(n) for n in node['names']]:
-- # autonumber-label: create anchor
-- self.out += self.ids_to_labels(node)
- # prevent spurious whitespace if footnote starts with paragraph:
- if len(node) > 1 and isinstance(node[1], nodes.paragraph):
- self.out.append('%')
-@@ -2441,6 +2454,9 @@ class LaTeXTranslator(writers.DoctreeTra
- return f'{value}\\DU{unit}dimen'
-
- def visit_image(self, node) -> None:
-+ # <image> can be inline element, body element, or nested in a <figure>
-+ # in all three cases the <image> may also be nested in a <reference>
-+ # TODO: "classes" attribute currently ignored!
- self.requirements['graphicx'] = self.graphicx_package
- attrs = node.attributes
- # convert image URI to filesystem path, do not adjust relative path:
-@@ -2485,13 +2501,14 @@ class LaTeXTranslator(writers.DoctreeTra
- if 'width' in attrs:
- include_graphics_options.append(
- f"width={self.to_latex_length(attrs['width'], node)}")
-+ pre.append(''.join(self.ids_to_labels(node, newline=True)))
- if not (self.is_inline(node)
-- or isinstance(node.parent, (nodes.figure, nodes.compound))):
-+ or isinstance(node.parent, nodes.compound)):
- pre.append('\n')
-- if not (self.is_inline(node)
-- or isinstance(node.parent, nodes.figure)):
-+ if not self.is_inline(node):
- post.append('\n')
- pre.reverse()
-+ # now insert image code
- self.out.extend(pre)
- if imagepath.suffix == '.svg' and 'svg' in self.settings.stylesheet:
- cmd = 'includesvg'
-@@ -2504,7 +2521,7 @@ class LaTeXTranslator(writers.DoctreeTra
- self.out.extend(post)
-
- def depart_image(self, node) -> None:
-- self.out += self.ids_to_labels(node, newline=True)
-+ pass
-
- def visit_inline(self, node) -> None:
- # This function is also called by the visiting functions for
-@@ -2512,8 +2529,9 @@ class LaTeXTranslator(writers.DoctreeTra
-
- # Handle "ids" attribute:
- # do we need a \phantomsection?
-- set_anchor = not (isinstance(node.parent, (nodes.caption, nodes.title))
-- or isinstance(node, nodes.caption))
-+ anchor_nodes = (nodes.caption, nodes.subtitle, nodes.title)
-+ set_anchor = not (isinstance(node.parent, anchor_nodes)
-+ or isinstance(node, anchor_nodes))
- add_newline = isinstance(node, nodes.paragraph)
- self.out += self.ids_to_labels(node, set_anchor, newline=add_newline)
- # Handle "classes" attribute:
-@@ -2552,6 +2570,7 @@ class LaTeXTranslator(writers.DoctreeTra
- '\\begin{DUlineblock}{\\DUlineblockindent}\n')
- # In rST, nested line-blocks cannot be given class arguments
- else:
-+ self.out += self.ids_to_labels(node, pre_nl=True)
- self.duclass_open(node)
- self.out.append('\\begin{DUlineblock}{0em}\n')
- self.insert_align_declaration(node)
-@@ -2561,6 +2580,7 @@ class LaTeXTranslator(writers.DoctreeTra
- self.duclass_close(node)
-
- def visit_list_item(self, node) -> None:
-+ self.out += self.ids_to_labels(node, pre_nl=True)
- self.out.append('\n\\item ')
-
- def depart_list_item(self, node) -> None:
-@@ -2626,8 +2646,8 @@ class LaTeXTranslator(writers.DoctreeTra
- _use_listings = (literal_env == 'lstlisting') and _use_env
-
- # Labels and classes:
-+ self.out += self.ids_to_labels(node, pre_nl=True)
- self.duclass_open(node)
-- self.out += self.ids_to_labels(node, newline=True)
- # Highlight code?
- if (not _plaintext
- and 'code' in node['classes']
-@@ -2728,16 +2748,20 @@ class LaTeXTranslator(writers.DoctreeTra
-
- def visit_math_block(self, node) -> None:
- self.requirements['amsmath'] = r'\usepackage{amsmath}'
-+ math_env = pick_math_environment(node.astext())
-+ self.out.append('%\n')
-+ if node['ids'] and math_env.endswith('*'): # non-numbered equation
-+ self.out.append('\\phantomsection\n')
- for cls in node['classes']:
- self.provide_fallback('inline')
-- self.out.append(r'\DUrole{%s}{' % cls)
-- math_env = pick_math_environment(node.astext())
-- self.out += [f'%\n\\begin{{{math_env}}}\n',
-+ self.out.append(f'\\DUrole{{{cls}}}{{%\n')
-+ self.out += [f'\\begin{{{math_env}}}\n',
- node.astext().translate(unichar2tex.uni2tex_table),
- '\n',
- *self.ids_to_labels(node, set_anchor=False, newline=True),
- f'\\end{{{math_env}}}']
-- self.out.append('}' * len(node['classes']))
-+ if node['classes']:
-+ self.out.append('\n' + '}' * len(node['classes']))
- raise nodes.SkipNode # content already processed
-
- def depart_math_block(self, node) -> None:
-@@ -2771,6 +2795,7 @@ class LaTeXTranslator(writers.DoctreeTra
- def visit_option_list(self, node) -> None:
- self.provide_fallback('providelength', '_providelength')
- self.provide_fallback('optionlist')
-+ self.out += self.ids_to_labels(node, pre_nl=True)
- self.duclass_open(node)
- self.out.append('\\begin{DUoptionlist}\n')
-
-@@ -2779,7 +2804,7 @@ class LaTeXTranslator(writers.DoctreeTra
- self.duclass_close(node)
-
- def visit_option_list_item(self, node) -> None:
-- pass
-+ self.out += self.ids_to_labels(node, newline=True)
-
- def depart_option_list_item(self, node) -> None:
- pass
-@@ -2871,7 +2896,7 @@ class LaTeXTranslator(writers.DoctreeTra
- ord('%'): '\\%',
- ord('\\'): '\\\\',
- }
-- if not (self.is_inline(node) or isinstance(node.parent, nodes.figure)):
-+ if not self.is_inline(node):
- self.out.append('\n')
- # external reference (URL)
- if 'refuri' in node:
-@@ -2901,7 +2926,7 @@ class LaTeXTranslator(writers.DoctreeTra
-
- def depart_reference(self, node) -> None:
- self.out.append('}')
-- if not (self.is_inline(node) or isinstance(node.parent, nodes.figure)):
-+ if not self.is_inline(node):
- self.out.append('\n')
-
- def visit_revision(self, node) -> None:
-@@ -2914,10 +2939,13 @@ class LaTeXTranslator(writers.DoctreeTra
- self.provide_fallback('rubric')
- # class wrapper would interfere with ``\section*"`` type commands
- # (spacing/indent of first paragraph)
-- self.out.append('\n\\DUrubric{')
-+ self.out += self.ids_to_labels(node, pre_nl=True)
-+ self.duclass_open(node)
-+ self.out.append('\\DUrubric{')
-
- def depart_rubric(self, node) -> None:
- self.out.append('}\n')
-+ self.duclass_close(node)
-
- def visit_section(self, node) -> None:
- # Update counter-prefix for compound enumerators
-@@ -2959,6 +2987,7 @@ class LaTeXTranslator(writers.DoctreeTra
- self.section_level -= 1
-
- def visit_sidebar(self, node) -> None:
-+ self.out += self.ids_to_labels(node, pre_nl=True)
- self.duclass_open(node)
- self.requirements['color'] = PreambleCmds.color
- self.provide_fallback('sidebar')
-@@ -2975,12 +3004,15 @@ class LaTeXTranslator(writers.DoctreeTra
-
- def visit_attribution(self, node) -> None:
- prefix, suffix = self.attribution_formats[self.settings.attribution]
-- self.out.append('\\nopagebreak\n\n\\raggedleft ')
-- self.out.append(prefix)
-+ self.out.append('\\nopagebreak\n')
-+ self.out += self.ids_to_labels(node, pre_nl=True)
-+ self.duclass_open(node)
-+ self.out.append(f'\\raggedleft {prefix}')
- self.context.append(suffix)
-
- def depart_attribution(self, node) -> None:
- self.out.append(self.context.pop() + '\n')
-+ self.duclass_close(node)
-
- def visit_status(self, node) -> None:
- self.visit_docinfo_item(node)
-@@ -3056,7 +3088,6 @@ class LaTeXTranslator(writers.DoctreeTra
- self.depart_admonition(node)
-
- def visit_table(self, node) -> None:
-- self.duclass_open(node)
- self.requirements['table'] = PreambleCmds.table
- if not self.settings.legacy_column_widths:
- self.requirements['table1'] = PreambleCmds.table_columnwidth
-@@ -3088,9 +3119,9 @@ class LaTeXTranslator(writers.DoctreeTra
- # if it has no caption/title.
- # See visit_thead() for tables with caption.
- if not self.active_table.caption:
-- self.out.extend(self.ids_to_labels(
-- node, set_anchor=len(self.table_stack) != 1,
-- newline=True))
-+ set_anchor = (len(self.table_stack) != 1)
-+ self.out += self.ids_to_labels(node, set_anchor, pre_nl=True)
-+ self.duclass_open(node)
- # TODO: Don't use a longtable or add \noindent before
- # the next paragraph, when in a "compound paragraph".
- # Start a new line or a new paragraph?
-@@ -3269,7 +3300,7 @@ class LaTeXTranslator(writers.DoctreeTra
-
- # labels and PDF bookmark (sidebar entry)
- self.out.append('\n') # start new paragraph
-- if node['names']: # don't add labels just for auto-ids
-+ if len(node['names']) > 1: # don't add labels just for the auto-id
- self.out += self.ids_to_labels(node, newline=True)
- if (isinstance(node.next_node(), nodes.title)
- and 'local' not in node['classes']
diff --git a/py-docutils/patches/patch-docutils_writers_latex2e_docutils.sty b/py-docutils/patches/patch-docutils_writers_latex2e_docutils.sty
deleted file mode 100644
index a08394b8be..0000000000
--- a/py-docutils/patches/patch-docutils_writers_latex2e_docutils.sty
+++ /dev/null
@@ -1,32 +0,0 @@
-$NetBSD$
-
---- docutils/writers/latex2e/docutils.sty.orig 2025-07-29 14:37:37.623939000 +0000
-+++ docutils/writers/latex2e/docutils.sty
-@@ -22,7 +22,7 @@
-
- \NeedsTeXFormat{LaTeX2e}
- \ProvidesPackage{docutils}
-- [2024-09-24 macros for Docutils LaTeX output]
-+ [2025-08-06 macros for Docutils LaTeX output]
-
- % Helpers
- % -------
-@@ -124,15 +124,15 @@
-
- % footnotes::
-
--% numerical or symbol footnotes with hyperlinks and backlinks
-+% numbered or symbol footnotes with hyperlinks and backlinks
- \providecommand*{\DUfootnotemark}[3]{%
- \raisebox{1em}{\hypertarget{#1}{}}%
-- \hyperlink{#2}{\textsuperscript{#3}}%
-+ \hyperref[#2]{\textsuperscript{#3}}%
- }
- \providecommand{\DUfootnotetext}[4]{%
- \begingroup%
- \renewcommand{\thefootnote}{%
-- \protect\raisebox{1em}{\protect\hypertarget{#1}{}}%
-+ \protect\phantomsection\protect\label{#1}
- \protect\hyperlink{#2}{#3}}%
- \footnotetext{#4}%
- \endgroup%
diff --git a/py-docutils/patches/patch-docutils_writers_odf__odt_____init____.py b/py-docutils/patches/patch-docutils_writers_odf__odt_____init____.py
deleted file mode 100644
index 703a3d015c..0000000000
--- a/py-docutils/patches/patch-docutils_writers_odf__odt_____init____.py
+++ /dev/null
@@ -1,18 +0,0 @@
-$NetBSD$
-
---- docutils/writers/odf_odt/__init__.py.orig 2025-07-29 14:37:37.693677400 +0000
-+++ docutils/writers/odf_odt/__init__.py
-@@ -386,10 +386,9 @@ class Writer(writers.Writer):
- ('Specify a stylesheet. '
- 'Default: "%s"' % default_stylesheet_path,
- ['--stylesheet'],
-- {
-- 'default': default_stylesheet_path,
-- 'dest': 'stylesheet'
-- }),
-+ {'default': default_stylesheet_path,
-+ 'dest': 'stylesheet',
-+ 'metavar': '<filename>'}),
- ('Specify an ODF-specific configuration/mapping file '
- 'relative to the current working directory.',
- ['--odf-config-file'],
diff --git a/py-docutils/patches/patch-docutils_writers_xetex_____init____.py b/py-docutils/patches/patch-docutils_writers_xetex_____init____.py
deleted file mode 100644
index e4ae2def9e..0000000000
--- a/py-docutils/patches/patch-docutils_writers_xetex_____init____.py
+++ /dev/null
@@ -1,14 +0,0 @@
-$NetBSD$
-
---- docutils/writers/xetex/__init__.py.orig 2025-07-29 14:37:37.839053600 +0000
-+++ docutils/writers/xetex/__init__.py
-@@ -57,7 +57,8 @@ class Writer(latex2e.Writer):
- latex_preamble=('Customization by LaTeX code in the preamble. '
- 'Default: select "Linux Libertine" fonts.',
- ['--latex-preamble'],
-- {'default': default_preamble}),
-+ {'metavar': '<preamble>',
-+ 'default': default_preamble}),
- )
-
- def __init__(self) -> None:
Home |
Main Index |
Thread Index |
Old Index