summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04>2005-05-18 22:27:52 +0000
committerwiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04>2005-05-18 22:27:52 +0000
commite699a07e2ed0da73245f131e5026011b0b4ac2a4 (patch)
tree5e04d7ee2db931833c745be92209c8713e87bbeb
parentf8e69145d50d9aba66e9a16a75c8fff0d162b5c4 (diff)
downloaddocutils-e699a07e2ed0da73245f131e5026011b0b4ac2a4.tar.gz
added SectSubTitle transform
git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk@3351 929543f6-e4f2-0310-98a6-ba3bd3dd1d04
-rw-r--r--docutils/HISTORY.txt10
-rw-r--r--docutils/docs/ref/transforms.txt2
-rw-r--r--docutils/docs/user/config.txt8
-rw-r--r--docutils/docutils/readers/standalone.py13
-rw-r--r--docutils/docutils/transforms/frontmatter.py182
-rwxr-xr-xdocutils/test/test_transforms/test_doctitle.py37
6 files changed, 202 insertions, 50 deletions
diff --git a/docutils/HISTORY.txt b/docutils/HISTORY.txt
index ba98ee2e2..ac312f6cb 100644
--- a/docutils/HISTORY.txt
+++ b/docutils/HISTORY.txt
@@ -121,6 +121,16 @@ Changes Since 0.3.7
* docutils/parsers/rst/languages/nl.py: Added to project; Dutch
mappings by Martijn Pieters.
+* docutils/readers/standalone.py:
+
+ - Added ``--section-subtitle`` and ``--no-section-subtitle`` options
+ to activate or deactivate the SectSubTitle transform.
+
+* docutils/transforms/frontmatter.py:
+
+ - Added SectSubTitle transform to promote titles of lone
+ subsections to subtitles.
+
* docutils/transforms/references.py:
- Fixed mislocated internal targets bug, by propagating internal
diff --git a/docutils/docs/ref/transforms.txt b/docutils/docs/ref/transforms.txt
index 9e4687a72..079bedaaa 100644
--- a/docutils/docs/ref/transforms.txt
+++ b/docutils/docs/ref/transforms.txt
@@ -34,6 +34,8 @@ frontmatter.DocTitle standalone (r) 320
frontmatter.DocInfo standalone (r) 340
+frontmatter.SectSubTitle standalone (r) 350
+
peps.Headers pep (r) 360
peps.Contents pep (r) 380
diff --git a/docutils/docs/user/config.txt b/docutils/docs/user/config.txt
index e3e052aaf..c00d82133 100644
--- a/docutils/docs/user/config.txt
+++ b/docutils/docs/user/config.txt
@@ -463,6 +463,14 @@ _`doctitle_xform`
Default: enabled (1). Options: ``--no-doc-title``.
+_`sectsubtitle_xform`
+
+ Enable or disable the promotion of the title of a lone subsection
+ to a subtitle (docutils.transforms.frontmatter.SectSubTitle).
+
+ Default: disabled (0). Options: ``--section-subtitle,
+ --no-section-subtitle``.
+
[pep reader]
````````````
diff --git a/docutils/docutils/readers/standalone.py b/docutils/docutils/readers/standalone.py
index 63e618b51..4cdea3df8 100644
--- a/docutils/docutils/readers/standalone.py
+++ b/docutils/docutils/readers/standalone.py
@@ -37,7 +37,17 @@ class Reader(readers.Reader):
'default).',
['--no-doc-info'],
{'dest': 'docinfo_xform', 'action': 'store_false', 'default': 1,
- 'validator': frontend.validate_boolean}),))
+ 'validator': frontend.validate_boolean}),
+ ('Activate the promotion of the title of a lone subsection to '
+ 'a section subtitle (disabled by default).',
+ ['--section-subtitle'],
+ {'dest': 'sectsubtitle_xform', 'action': 'store_true', 'default': 0,
+ 'validator': frontend.validate_boolean}),
+ ('Deactivate the promotion of lone subsection titles.',
+ ['--no-section-subtitle'],
+ {'dest': 'sectsubtitle_xform', 'action': 'store_false',
+ 'validator': frontend.validate_boolean}),
+ ))
config_section = 'standalone reader'
config_section_dependencies = ('readers',)
@@ -45,6 +55,7 @@ class Reader(readers.Reader):
default_transforms = (references.Substitutions,
references.PropagateTargets,
frontmatter.DocTitle,
+ frontmatter.SectionSubTitle,
frontmatter.DocInfo,
references.AnonymousHyperlinks,
references.IndirectHyperlinks,
diff --git a/docutils/docutils/transforms/frontmatter.py b/docutils/docutils/transforms/frontmatter.py
index 22ecbbf25..cd8fb0188 100644
--- a/docutils/docutils/transforms/frontmatter.py
+++ b/docutils/docutils/transforms/frontmatter.py
@@ -5,13 +5,15 @@
# Copyright: This module has been placed in the public domain.
"""
-Transforms related to the front matter of a document (information
-found before the main text):
+Transforms related to the front matter of a document or a section
+(information found before the main text):
- `DocTitle`: Used to transform a lone top level section's title to
the document title, and promote a remaining lone top-level section's
title to the document subtitle.
+- `SectionTitle`: Used to transform a lone subsection into a subtitle.
+
- `DocInfo`: Used to transform a bibliographic field list into docinfo
elements.
"""
@@ -23,7 +25,100 @@ from docutils import nodes, utils
from docutils.transforms import TransformError, Transform
-class DocTitle(Transform):
+class TitlePromoter(Transform):
+
+ """
+ Abstract base class for DocTitle and SectionSubTitle transforms.
+ """
+
+ def promote_title(self, node):
+ """
+ Transform the following tree::
+
+ <node>
+ <section>
+ <title>
+ ...
+
+ into ::
+
+ <node>
+ <title>
+ ...
+
+ `node` is normally a document.
+ """
+ # `node` must not have a title yet.
+ assert not (len(node) and isinstance(node[0], nodes.title))
+ section, index = self.candidate_index(node)
+ if index is None:
+ return None
+ # Transfer the section's attributes to the node:
+ node.attributes.update(section.attributes)
+ # setup_child is called automatically for all nodes.
+ node[:] = (section[:1] # section title
+ + node[:index] # everything that was in the
+ # node before the section
+ + section[1:]) # everything that was in the section
+ assert isinstance(node[0], nodes.title)
+ return 1
+
+ def promote_subtitle(self, node):
+ """
+ Transform the following node tree::
+
+ <node>
+ <title>
+ <section>
+ <title>
+ ...
+
+ into ::
+
+ <node>
+ <title>
+ <subtitle>
+ ...
+ """
+ subsection, index = self.candidate_index(node)
+ if index is None:
+ return None
+ subtitle = nodes.subtitle()
+ # Transfer the subsection's attributes to the new subtitle:
+ # This causes trouble with list attributes! To do: Write a
+ # test case which catches direct access to the `attributes`
+ # dictionary and/or write a test case which shows problems in
+ # this particular case.
+ subtitle.attributes.update(subsection.attributes)
+ # We're losing the subtitle's attributes here! To do: Write a
+ # test case which shows this behavior.
+ # Transfer the contents of the subsection's title to the
+ # subtitle:
+ subtitle[:] = subsection[0][:]
+ node[:] = (node[:1] # title
+ + [subtitle]
+ # everything that was before the section:
+ + node[1:index]
+ # everything that was in the subsection:
+ + subsection[1:])
+ return 1
+
+ def candidate_index(self, node):
+ """
+ Find and return the promotion candidate and its index.
+
+ Return (None, None) if no valid candidate was found.
+ """
+ index = node.first_child_not_matching_class(
+ nodes.PreBibliographic)
+ if index is None or len(node) > (index + 1) or \
+ not isinstance(node[index], nodes.section):
+ return None, None
+ else:
+ return node[index], index
+
+
+class DocTitle(TitlePromoter):
"""
In reStructuredText_, there is no way to specify a document title
@@ -107,54 +202,47 @@ class DocTitle(Transform):
def apply(self):
if not getattr(self.document.settings, 'doctitle_xform', 1):
return
- if self.promote_document_title():
- self.promote_document_subtitle()
+ if self.promote_title(self.document):
+ self.promote_subtitle(self.document)
- def promote_document_title(self):
- section, index = self.candidate_index()
- if index is None:
- return None
- document = self.document
- # Transfer the section's attributes to the document element (at root):
- document.attributes.update(section.attributes)
- document[:] = (section[:1] # section title
- + document[:index] # everything that was in the
- # document before the section
- + section[1:]) # everything that was in the section
- return 1
- def promote_document_subtitle(self):
- subsection, index = self.candidate_index()
- if index is None:
- return None
- subtitle = nodes.subtitle()
- # Transfer the subsection's attributes to the new subtitle:
- subtitle.attributes.update(subsection.attributes)
- # Transfer the contents of the subsection's title to the subtitle:
- subtitle[:] = subsection[0][:]
- document = self.document
- document[:] = (document[:1] # document title
- + [subtitle]
- # everything that was before the section:
- + document[1:index]
- # everything that was in the subsection:
- + subsection[1:])
- return 1
+class SectionSubTitle(TitlePromoter):
- def candidate_index(self):
- """
- Find and return the promotion candidate and its index.
+ """
+ This works like document subtitles, but for sections. For example, ::
- Return (None, None) if no valid candidate was found.
- """
- document = self.document
- index = document.first_child_not_matching_class(
- nodes.PreBibliographic)
- if index is None or len(document) > (index + 1) or \
- not isinstance(document[index], nodes.section):
- return None, None
- else:
- return document[index], index
+ <section>
+ <title>
+ Title
+ <section>
+ <title>
+ Subtitle
+ ...
+
+ is transformed into ::
+
+ <section>
+ <title>
+ Title
+ <subtitle>
+ Subtitle
+ ...
+
+ For details refer to the docstring of DocTitle.
+ """
+
+ default_priority = 350
+
+ def apply(self):
+ if not getattr(self.document.settings, 'sectsubtitle_xform', 1):
+ return
+ for section in self.document.traverse(lambda n:
+ isinstance(n, nodes.section)):
+ # On our way through the node tree, we are deleting
+ # sections, but we call self.promote_subtitle for those
+ # sections nonetheless. To do: Write a test case which
+ # shows the problem and discuss on Docutils-develop.
+ self.promote_subtitle(section)
class DocInfo(Transform):
diff --git a/docutils/test/test_transforms/test_doctitle.py b/docutils/test/test_transforms/test_doctitle.py
index c196c38ec..0e2050494 100755
--- a/docutils/test/test_transforms/test_doctitle.py
+++ b/docutils/test/test_transforms/test_doctitle.py
@@ -11,7 +11,7 @@ Tests for docutils.transforms.frontmatter.DocTitle.
"""
from __init__ import DocutilsTestSupport
-from docutils.transforms.frontmatter import DocTitle
+from docutils.transforms.frontmatter import DocTitle, SectionSubTitle
from docutils.parsers.rst import Parser
@@ -23,7 +23,7 @@ def suite():
totest = {}
-totest['section_headers'] = ((DocTitle,), [
+totest['section_headers'] = ((DocTitle, SectionSubTitle), [
["""\
.. test title promotion
@@ -188,6 +188,39 @@ substitution_definition.
This title should be the document title despite the
substitution_definition.
"""],
+["""\
+This is no doc title.
+
+===============
+ Section Title
+===============
+
+Subtitle
+========
+
+-----------------
+ Another Section
+-----------------
+
+Another Subtitle
+----------------
+
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ This is no doc title.
+ <section ids="section-title" names="section title">
+ <title>
+ Section Title
+ <subtitle ids="subtitle" names="subtitle">
+ Subtitle
+ <section ids="another-section" names="another section">
+ <title>
+ Another Section
+ <subtitle ids="another-subtitle" names="another subtitle">
+ Another Subtitle
+"""],
])