From 5d40570da9d94e4d1fccca8bb724f590ccc4dcde Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 5 Mar 2005 16:52:14 +0000 Subject: relocate internal targets only in front of sections, doctitles and subtitles git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk@3008 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/docs/ref/transforms.txt | 2 + docutils/docutils/readers/pep.py | 1 + docutils/docutils/readers/standalone.py | 1 + docutils/docutils/transforms/references.py | 76 ++++++----------- .../expected/standalone_rst_html4css1.html | 24 +++--- .../functional/expected/standalone_rst_latex.tex | 12 +-- docutils/test/functional/input/data/standard.txt | 6 +- docutils/test/test_transforms/test_hyperlinks.py | 97 +++++++++++----------- 8 files changed, 104 insertions(+), 115 deletions(-) (limited to 'docutils') diff --git a/docutils/docs/ref/transforms.txt b/docutils/docs/ref/transforms.txt index f5c045bb7..db4d3c426 100644 --- a/docutils/docs/ref/transforms.txt +++ b/docutils/docs/ref/transforms.txt @@ -28,6 +28,8 @@ misc.class "class" (d/p) 210 references.Substitutions standalone (r), pep (r) 220 +references.SectionTargets standalone (r), pep (r) 260 + frontmatter.DocTitle standalone (r) 320 frontmatter.DocInfo standalone (r) 340 diff --git a/docutils/docutils/readers/pep.py b/docutils/docutils/readers/pep.py index b615ba4db..b7774a949 100644 --- a/docutils/docutils/readers/pep.py +++ b/docutils/docutils/readers/pep.py @@ -31,6 +31,7 @@ class Reader(standalone.Reader): config_section_dependencies = ('readers', 'standalone reader') default_transforms = (references.Substitutions, + references.SectionTargets, peps.Headers, peps.Contents, references.ChainedTargets, diff --git a/docutils/docutils/readers/standalone.py b/docutils/docutils/readers/standalone.py index 29aec35dc..82541c297 100644 --- a/docutils/docutils/readers/standalone.py +++ b/docutils/docutils/readers/standalone.py @@ -43,6 +43,7 @@ class Reader(readers.Reader): config_section_dependencies = ('readers',) default_transforms = (references.Substitutions, + references.SectionTargets, frontmatter.DocTitle, frontmatter.DocInfo, references.ChainedTargets, diff --git a/docutils/docutils/transforms/references.py b/docutils/docutils/transforms/references.py index 5ea2f1b00..2ffbfc9be 100644 --- a/docutils/docutils/transforms/references.py +++ b/docutils/docutils/transforms/references.py @@ -19,6 +19,33 @@ from docutils.transforms import TransformError, Transform indices = xrange(sys.maxint) +class SectionTargets(Transform): + + default_priority = 260 + + def apply(self): + for target in self.document.internal_targets: + if not (target.attributes.has_key('refid') + or target.attributes.has_key('refuri') + or target.attributes.has_key('refname')): + self.relocate(target) + + def relocate(self, target): + """ + Move "target" elements into the next title element if + necessary. + """ + assert isinstance(target, nodes.target) + # Find next node which is not a target. + n = target.next_node(cond=lambda x: not isinstance(x, nodes.target)) + if isinstance(n, nodes.section): + assert isinstance(n[0], nodes.title) + target.parent.remove(target) + target += n[0].get_children() + n[0].clear() + n[0] += target + + class ChainedTargets(Transform): """ @@ -387,10 +414,6 @@ class InternalTargets(Transform): def apply(self): for target in self.document.internal_targets: self.resolve_reference_ids(target) - if not (target.attributes.has_key('refid') - or target.attributes.has_key('refuri') - or target.attributes.has_key('refname')): - self.relocate(target) def resolve_reference_ids(self, target): """ @@ -432,51 +455,6 @@ class InternalTargets(Transform): ref.resolved = 1 target.referenced = 1 - def relocate(self, target): - """ - Move "target" elements into the next text element - (in tree traversal order). - """ - parent = target.parent - child = target - while parent: - # Check all following siblings: - for index in range(parent.index(child) + 1, len(parent)): - element = parent[index] - visitor = InternalTargetRelocationPointLocator(self.document) - try: - element.walk(visitor) - except nodes.NodeFound: - target.parent.remove(target) - for child in visitor.found: - target += child - visitor.found.clear() - visitor.found += target - return - else: - # At end of section or container; try parent's sibling - child = parent - parent = parent.parent - error = self.document.reporter.error( - 'No element suitable for hosting target, following internal ' - 'target "%s".' % target['name'], line=target.line) - target.parent.replace(target, error) - - -class InternalTargetRelocationPointLocator(nodes.GenericNodeVisitor): - - """ - Find the first text-containing node that can host an internal target. - """ - - found = None - - def default_visit(self, node): - if (isinstance(node, nodes.TextElement) - and not isinstance(node, nodes.Special)): - self.found = node - raise nodes.NodeFound - class Footnotes(Transform): diff --git a/docutils/test/functional/expected/standalone_rst_html4css1.html b/docutils/test/functional/expected/standalone_rst_html4css1.html index c54bf046d..899b86324 100644 --- a/docutils/test/functional/expected/standalone_rst_html4css1.html +++ b/docutils/test/functional/expected/standalone_rst_html4css1.html @@ -18,8 +18,8 @@
-

reStructuredText Test Document

-

Examples of Syntax Constructs

+

reStructuredText Test Document

+

Examples of Syntax Constructs

@@ -168,7 +168,7 @@ hyperlink targets (see Targets b Character-level inline markup is also possible (although exceedingly ugly!) in reStructuredText. Problems are indicated by |problematic| text (generated by processing errors; this one is -intentional).

+intentional). Here is a reference to the doctitle and the subtitle.

The default role for interpreted text is Title Reference. Here are some explicit interpreted text roles: a PEP reference (PEP 287); an RFC reference (RFC 2822); a subscript; a superscript; @@ -204,14 +204,14 @@ live link to PEP 258 here.

  • Nested item 3.
  • -
  • This nested list should be compacted by the HTML writer. +
  • This nested list should be compacted by the HTML writer.
  • -

    2.3   Enumerated Lists

    +

    2.3   Enumerated Lists

    1. Arabic numerals.

        @@ -490,9 +490,9 @@ citation.

    2.13   Targets

    -

    This paragraph is pointed to by the explicit "example" target. A +

    This paragraph is pointed to by the explicit "example" target. A reference can be found under Inline Markup, above. Inline -hyperlink targets are also possible.

    +hyperlink targets are also possible.

    Section headers are implicit targets, referred to by name. See Targets, which is a subsection of Body Elements.

    Explicit external targets are interpolated into references such as @@ -868,19 +868,19 @@ section, "Docutils System Messages":

    Docutils System Messages

    -

    System Message: ERROR/3 (functional/input/data/standard.txt, line 94); backlink

    +

    System Message: ERROR/3 (functional/input/data/standard.txt, line 98); backlink

    Undefined substitution referenced: "problematic".
    -

    System Message: ERROR/3 (functional/input/standalone_rst_html4css1.txt, line 348); backlink

    +

    System Message: ERROR/3 (functional/input/standalone_rst_html4css1.txt, line 352); backlink

    Unknown target name: "5".
    -

    System Message: ERROR/3 (functional/input/data/standard.txt, line 357); backlink

    +

    System Message: ERROR/3 (functional/input/data/standard.txt, line 361); backlink

    Unknown target name: "nonexistent".
    -

    System Message: ERROR/3 (functional/input/data/standard.txt, line 382); backlink

    +

    System Message: ERROR/3 (functional/input/data/standard.txt, line 386); backlink

    Unknown target name: "hyperlink reference without a target".
    -

    System Message: ERROR/3 (functional/input/data/standard.txt, line 395); backlink

    +

    System Message: ERROR/3 (functional/input/data/standard.txt, line 399); backlink

    Duplicate target name, cannot be used as a unique reference: "duplicate target names".
    diff --git a/docutils/test/functional/expected/standalone_rst_latex.tex b/docutils/test/functional/expected/standalone_rst_latex.tex index a65919472..9f57af6ea 100644 --- a/docutils/test/functional/expected/standalone_rst_latex.tex +++ b/docutils/test/functional/expected/standalone_rst_latex.tex @@ -302,7 +302,7 @@ hyperlink targets} (see \href{\#targets}{Targets} below for a reference back to Character-level inline markup is also possible (although exceedingly ugly!) in \emph{re}\texttt{Structured}\emph{Text}. Problems are indicated by {\color{red}\bfseries{}{\textbar}problematic{\textbar}} text (generated by processing errors; this one is -intentional). +intentional). Here is a reference to the \href{\#doctitle}{doctitle} and the \href{\#subtitle}{subtitle}. The default role for interpreted text is \titlereference{Title Reference}. Here are some explicit interpreted text roles: a PEP reference (\href{http://www.python.org/peps/pep-0287.html}{PEP 287}); an @@ -363,7 +363,7 @@ Nested item 3. \item {} This nested list should be compacted by the HTML writer. -% Even if this item contains a target and a comment. +\hypertarget{target}{}% Even if this item contains a target and a comment. \end{itemize} @@ -374,7 +374,7 @@ This nested list should be compacted by the HTML writer. \hypertarget{enumerated-lists}{} \pdfbookmark[1]{2.3~~~Enumerated Lists}{enumerated-lists} -\subsection*{2.3~~~\hypertarget{target}{Enumerated Lists}} +\subsection*{2.3~~~Enumerated Lists} \newcounter{listcnt1} \begin{list}{\arabic{listcnt1}.} { @@ -772,10 +772,10 @@ citation. \hypertarget{targets}{} \pdfbookmark[1]{2.13~~~Targets}{targets} \subsection*{2.13~~~Targets} - -\hypertarget{example}{This paragraph is pointed to by the explicit ``example'' target. A +\hypertarget{example}{} +This paragraph is pointed to by the explicit ``example'' target. A reference can be found under \href{\#inline-markup}{Inline Markup}, above. \href{\#inline-hyperlink-targets}{Inline -hyperlink targets} are also possible.} +hyperlink targets} are also possible. Section headers are implicit targets, referred to by name. See \href{\#targets}{Targets}, which is a subsection of \href{\#body-elements}{Body Elements}. diff --git a/docutils/test/functional/input/data/standard.txt b/docutils/test/functional/input/data/standard.txt index 69afbbc67..95f74820c 100644 --- a/docutils/test/functional/input/data/standard.txt +++ b/docutils/test/functional/input/data/standard.txt @@ -1,6 +1,8 @@ .. This is a comment. Note how any initial comments are moved by transforms to after the document title, subtitle, and docinfo. +.. _doctitle: + ================================ reStructuredText Test Document ================================ @@ -8,6 +10,8 @@ .. Above is the document title, and below is the subtitle. They are transformed from section titles after parsing. +.. _subtitle: + -------------------------------- Examples of Syntax Constructs -------------------------------- @@ -101,7 +105,7 @@ hyperlink targets` (see Targets_ below for a reference back to here). Character-level inline markup is also possible (although exceedingly ugly!) in *re*\ ``Structured``\ *Text*. Problems are indicated by |problematic| text (generated by processing errors; this one is -intentional). +intentional). Here is a reference to the doctitle_ and the subtitle_. The default role for interpreted text is `Title Reference`. Here are some explicit interpreted text roles: a PEP reference (:PEP:`287`); an diff --git a/docutils/test/test_transforms/test_hyperlinks.py b/docutils/test/test_transforms/test_hyperlinks.py index e82a3580d..2fd9eb831 100755 --- a/docutils/test/test_transforms/test_hyperlinks.py +++ b/docutils/test/test_transforms/test_hyperlinks.py @@ -11,8 +11,10 @@ Tests for docutils.transforms.references.Hyperlinks. """ from __init__ import DocutilsTestSupport -from docutils.transforms.references import ChainedTargets, \ - AnonymousHyperlinks, IndirectHyperlinks, ExternalTargets, InternalTargets +from docutils.transforms.references import SectionTargets, ChainedTargets, \ + AnonymousHyperlinks, IndirectHyperlinks, ExternalTargets, \ + InternalTargets + from docutils.transforms.universal import FinalChecks from docutils.parsers.rst import Parser @@ -28,9 +30,10 @@ totest = {} # Exhaustive listing of hyperlink variations: every combination of # target/reference, direct/indirect, internal/external, and named/anonymous, # plus embedded URIs. -totest['exhaustive_hyperlinks'] = ((ChainedTargets, AnonymousHyperlinks, - IndirectHyperlinks, ExternalTargets, - InternalTargets, FinalChecks), [ +totest['exhaustive_hyperlinks'] = ((SectionTargets, ChainedTargets, + AnonymousHyperlinks, IndirectHyperlinks, + ExternalTargets, InternalTargets, + FinalChecks), [ ["""\ direct_ external @@ -66,11 +69,11 @@ direct_ internal """, """\ + - - - direct - internal + + direct + internal """], ["""\ .. _ztarget: @@ -82,11 +85,11 @@ indirect_ internal """, """\ + - - - indirect - internal + + indirect + internal """], @@ -226,10 +229,10 @@ __ """, """\ + - - - direct internal + + direct internal """], ["""\ .. _ztarget: @@ -240,10 +243,10 @@ __ ztarget_ """, """\ + - - - indirect internal + + indirect internal """], ["""\ @@ -261,15 +264,15 @@ __ ztarget_ """, """\ + - - First + First Duplicate explicit target name: "ztarget". + - - Second + Second `indirect internal`__ @@ -310,7 +313,7 @@ An `anonymous embedded uri `__. """], ]) -totest['hyperlinks'] = ((ChainedTargets, AnonymousHyperlinks, +totest['hyperlinks'] = ((SectionTargets, ChainedTargets, AnonymousHyperlinks, IndirectHyperlinks, ExternalTargets, InternalTargets,), [ ["""\ @@ -322,9 +325,9 @@ By this `internal hyperlink`_ referemce. """, """\ + - - This paragraph referenced. + This paragraph referenced. By this \n\ @@ -344,10 +347,10 @@ The results of the transform are not visible at the XML level. """, """\ + + - - - This paragraph referenced. + This paragraph referenced. By this \n\ @@ -461,23 +464,23 @@ __ + - - - Full syntax anonymous external hyperlink reference - , - - chained anonymous external reference - , - - simplified syntax anonymous external hyperlink reference - , - - indirect anonymous hyperlink reference - , - - internal anonymous hyperlink reference - . + + Full syntax anonymous external hyperlink reference + , + + chained anonymous external reference + , + + simplified syntax anonymous external hyperlink reference + , + + indirect anonymous hyperlink reference + , + + internal anonymous hyperlink reference + . """], ["""\ Duplicate external target_'s (different URIs): @@ -540,9 +543,9 @@ __ http://example.org + - - + -- cgit v1.2.1