summaryrefslogtreecommitdiff
path: root/docutils/transforms/universal.py
diff options
context:
space:
mode:
Diffstat (limited to 'docutils/transforms/universal.py')
-rw-r--r--docutils/transforms/universal.py47
1 files changed, 35 insertions, 12 deletions
diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py
index 443b186fb..4f5626c1d 100644
--- a/docutils/transforms/universal.py
+++ b/docutils/transforms/universal.py
@@ -207,23 +207,46 @@ class SmartQuotes(Transform):
"""
Replace ASCII quotation marks with typographic form.
- Also replace multiple dashes with em-dashes and en-dashes.
+ Also replace multiple dashes with em-dash/en-dash characters.
"""
default_priority = 850
+ texttype = {True: 'literal',
+ False: 'plain'}
+
def apply(self):
if self.document.settings.smart_quotes is False:
return
- for node in self.document.traverse(nodes.Text):
- if isinstance(node.parent,
- (nodes.FixedTextElement,
- nodes.literal,
- nodes.Special,
- nodes.option_string
- )):
- # print "literal", node
+
+ # "Educate" quotes in normal text. Handle each block of text
+ # (TextElement node) as a unit to keep context around inline nodes:
+ for node in self.document.traverse(nodes.TextElement):
+ # skip preformatted text blocks and special elements:
+ if isinstance(node, (nodes.FixedTextElement, nodes.Special)):
+ continue
+ # nested TextElements are not "block-level" elements:
+ if isinstance(node.parent, nodes.TextElement):
continue
- newtext = smartquotes.smartyPants(node.astext(), attr='2')
- node.parent.replace(node, nodes.Text(newtext))
- # print "smartquote",
+
+ # list of text nodes in the "text block":
+ txtnodes = [txtnode for txtnode in node.traverse(nodes.Text)
+ if not isinstance(txtnode.parent,
+ nodes.option_string)]
+ # smartquotes.educate_tokens() iterates over
+ # ``(texttype, nodetext)`` tuples. `texttype` is "literal"
+ # or "plain" where "literal" text is not changed:
+ tokens = [(self.texttype[isinstance(txtnode.parent,
+ (nodes.literal,
+ nodes.math,
+ nodes.image,
+ nodes.raw,
+ nodes.problematic))],
+ txtnode.astext()) for txtnode in txtnodes]
+
+ # Iterator educating quotes in plain text
+ # 2 : set all, using old school en- and em- dash shortcuts
+ teacher = smartquotes.educate_tokens(tokens, attr='2')
+
+ for txtnode, newtext in zip(txtnodes, teacher):
+ txtnode.parent.replace(txtnode, nodes.Text(newtext))