SF.net SVN: docutils:[9930] trunk/docutils

milde--- via Docutils-checkins <[email protected]>
Newsgroups gmane.text.docutils.cvs
Message-ID <[email protected]>
Revision: 9930
          http://sourceforge.net/p/docutils/code/9930
Author:   milde
Date:     2024-09-13 08:13:03 +0000 (Fri, 13 Sep 2024)
Log Message:
-----------
Use "unknown_reference_resolver" for LaTeX writer option "use-bibtex".

The "latex" writer provides the (provisional) setting "use_bibtex" to defer
the resolution of citation references to the backend (LaTeX/BibTeX/LaTeX).

Use the `unknown_reference_resolvers` hook of the `TransformSpec` to
mark citation references as resolved if BibTeX is used.

Advantages:

* replaces hard-coded special-case in
  `transforms.references.DanglingReferencesVisitor` introduced in [r9312],
* provides a usage example,
* tests the hook with the Docutils test suite without additional overhead.

Update docstrings and comments.

Modified Paths:
--------------
    trunk/docutils/HISTORY.rst
    trunk/docutils/docutils/__init__.py
    trunk/docutils/docutils/transforms/__init__.py
    trunk/docutils/docutils/transforms/references.py
    trunk/docutils/docutils/writers/latex2e/__init__.py

Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst	2024-09-12 12:57:48 UTC (rev 9929)
+++ trunk/docutils/HISTORY.rst	2024-09-13 08:13:03 UTC (rev 9930)
@@ -158,6 +158,8 @@
     (ignored since at least 2012).
   - Don't wrap references with custom reference-label_ in
     a ``\hyperref`` command.
+  - Provide an "unknown_references_resolver" (cf. `docutils/TransformSpec`)
+    for citation references resolved with BibTeX (cf. `use_bibtex`_ setting).
 
   .. _reference-label: docs/user/config.html#reference-label
 
@@ -3856,9 +3858,9 @@
 * docutils/transforms/__init__.py:
 
   - Added ``Transformer`` class and completed transform reform.
-  - Added unknown_reference_resolvers list for each transformer. This list holds
-    the list of functions provided by each component of the transformer that
-    help resolve references.
+  - Added unknown_reference_resolvers list for each transformer.
+    This list holds the list of functions provided by each component
+    of the transformer that help resolve references.
 
 * docutils/transforms/frontmatter.py:
 

Modified: trunk/docutils/docutils/__init__.py
===================================================================
--- trunk/docutils/docutils/__init__.py	2024-09-12 12:57:48 UTC (rev 9929)
+++ trunk/docutils/docutils/__init__.py	2024-09-13 08:13:03 UTC (rev 9930)
@@ -282,8 +282,11 @@
     default_transforms: ClassVar[tuple[()]] = ()
 
     unknown_reference_resolvers: Sequence[_UnknownReferenceResolver] = ()
-    """List of functions to try to resolve unknown references.
+    """List of hook functions which assist in resolving references.
 
+    Override in subclasses to implement component-specific resolving of
+    unknown references.
+
     Unknown references have a 'refname' attribute which doesn't correspond
     to any target in the document.  Called when the transforms in
     `docutils.transforms.references` are unable to find a correct target.
@@ -291,7 +294,7 @@
     The list should contain functions which will try to resolve unknown
     references, with the following signature::
 
-        def reference_resolver(node):
+        def reference_resolver(node: nodes.Element) -> bool:
             '''Returns boolean: true if resolved, false if not.'''
 
     If the function is able to resolve the reference, it should also remove
@@ -301,13 +304,20 @@
         node.resolved = True
 
     Each function must have a "priority" attribute which will affect the order
-    the unknown_reference_resolvers are run::
+    the unknown_reference_resolvers are run
+    cf. ../docs/api/transforms.html#transform-priority-range-categories ::
 
-        reference_resolver.priority = 100
+        reference_resolver.priority = 500
 
-    This hook is provided for 3rd party extensions.
-    Example use case: the `MoinMoin - ReStructured Text Parser`
-    https://github.com/moinwiki/moin
+    Examples:
+      `writers.latex2e.Writer` defines a resolver to mark citation references
+      as resolved by BibTeX if the "use_bibtex" configuration setting is set.
+
+      The `MoinMoin ReStructured Text Parser`__ provides a resolver for
+      "WikiWiki links" (currently only in the outdated 1.9 version).
+
+      __ https://github.com/moinwiki/moin-1.9/blob/1.9.11/MoinMoin/parser/
+         text_rst.py
     """
 
 

Modified: trunk/docutils/docutils/transforms/__init__.py
===================================================================
--- trunk/docutils/docutils/transforms/__init__.py	2024-09-12 12:57:48 UTC (rev 9929)
+++ trunk/docutils/docutils/transforms/__init__.py	2024-09-13 08:13:03 UTC (rev 9930)
@@ -144,7 +144,7 @@
 
     def populate_from_components(self, components) -> None:
         """
-        Store each component's default transforms and reference resolvers
+        Store each component's default transforms and reference resolvers.
 
         Transforms are stored with default priorities for later sorting.
         "Unknown reference resolvers" are sorted and stored.
@@ -161,7 +161,7 @@
             resolvers.extend(component.unknown_reference_resolvers)
         self.sorted = False  # sort transform list in self.apply_transforms()
 
-        # Sort and add helper functions to help resolve unknown references.
+        # Sort and add hook functions helping to resolve unknown references.
         def keyfun(f):
             return f.priority
         resolvers.sort(key=keyfun)

Modified: trunk/docutils/docutils/transforms/references.py
===================================================================
--- trunk/docutils/docutils/transforms/references.py	2024-09-12 12:57:48 UTC (rev 9929)
+++ trunk/docutils/docutils/transforms/references.py	2024-09-13 08:13:03 UTC (rev 9930)
@@ -888,37 +888,33 @@
             return
         refname = node['refname']
         id = self.document.nameids.get(refname)
-        if id is None:
-            for resolver_function in self.unknown_reference_resolvers:
-                if resolver_function(node):
-                    break
-            else:
-                if (getattr(self.document.settings, 'use_bibtex', False)
-                    and isinstance(node, nodes.citation_reference)):
-                    # targets added from BibTeX database by LaTeX
-                    node.resolved = True
-                    return
-                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)
-                else:
-                    msg = self.document.reporter.error(
-                        f'Unknown target name: "{node["refname"]}".',
-                        base_node=node)
-                msgid = self.document.set_id(msg)
-                prb = nodes.problematic(
-                      node.rawsource, node.rawsource, refid=msgid)
-                try:
-                    prbid = node['ids'][0]
-                except IndexError:
-                    prbid = self.document.set_id(prb)
-                msg.add_backref(prbid)
-                node.replace_self(prb)
-        else:
+        if id is not None:
+            # target found, set refid
             del node['refname']
             node['refid'] = id
             self.document.ids[id].note_referenced_by(id=id)
             node.resolved = True
+            return
+        # Apply component-specific resolving functions (cf. TransformSpec):
+        for resolver_function in self.unknown_reference_resolvers:
+            if resolver_function(node):
+                return
+        # Report unresolved references:
+        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)
+        else:
+            msg = self.document.reporter.error(
+                f'Unknown target name: "{node["refname"]}".',
+                base_node=node)
+        msgid = self.document.set_id(msg)
+        prb = nodes.problematic(node.rawsource, node.rawsource, refid=msgid)
+        try:
+            prbid = node['ids'][0]
+        except IndexError:
+            prbid = self.document.set_id(prb)
+        msg.add_backref(prbid)
+        node.replace_self(prb)
 
     visit_footnote_reference = visit_citation_reference = visit_reference

Modified: trunk/docutils/docutils/writers/latex2e/__init__.py
===================================================================
--- trunk/docutils/docutils/writers/latex2e/__init__.py	2024-09-12 12:57:48 UTC (rev 9929)
+++ trunk/docutils/docutils/writers/latex2e/__init__.py	2024-09-13 08:13:03 UTC (rev 9930)
@@ -253,7 +253,23 @@
     def __init__(self) -> None:
         writers.Writer.__init__(self)
         self.translator_class = LaTeXTranslator
+        self.unknown_reference_resolvers = [self.bibtex_reference_resolver]
+        self.bibtex_reference_resolver.priority = 400
 
+    @staticmethod
+    def bibtex_reference_resolver(node: nodes.Element) -> bool:
+        """Mark citation references as resolved if BibTeX is used.
+
+        Cf. `TransformSpec.unknown_reference_resolvers`.
+        """
+        if (isinstance(node, nodes.citation_reference)
+            and node.document.settings.use_bibtex):
+            del node['refname']
+            node.resolved = True
+            return True
+        else:
+            return False
+
     def get_transforms(self):
         # Override parent method to add latex-specific transforms
         return super().get_transforms() + [

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.