From 636fd6cc380f2537924532a587c70e96a386e25c Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Tue, 17 Jul 2012 13:30:06 +0200 Subject: [PATCH] Add support for abbreviations to reST translator (fixes #395). --- pelican/readers.py | 13 +++++++++++++ pelican/rstdirectives.py | 20 ++++++++++++++++++-- tests/content/article.rst | 2 ++ tests/test_readers.py | 8 ++++++-- 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/pelican/readers.py b/pelican/readers.py index 83565918..3591c1b8 100644 --- a/pelican/readers.py +++ b/pelican/readers.py @@ -63,6 +63,18 @@ def render_node_to_html(document, node): return visitor.astext() +class PelicanHTMLTranslator(HTMLTranslator): + + def visit_abbreviation(self, node): + attrs = {} + if node.hasattr('explanation'): + attrs['title'] = node['explanation'] + self.body.append(self.starttag(node, 'abbr', '', **attrs)) + + def depart_abbreviation(self, node): + self.body.append('') + + class RstReader(Reader): enabled = bool(docutils) file_extensions = ['rst'] @@ -92,6 +104,7 @@ class RstReader(Reader): pub = docutils.core.Publisher( destination_class=docutils.io.StringOutput) pub.set_components('standalone', 'restructuredtext', 'html') + pub.writer.translator_class = PelicanHTMLTranslator pub.process_programmatic_settings(None, extra_params, None) pub.set_source(source_path=filename) pub.publish() diff --git a/pelican/rstdirectives.py b/pelican/rstdirectives.py index 9c821310..b1f1242c 100644 --- a/pelican/rstdirectives.py +++ b/pelican/rstdirectives.py @@ -1,9 +1,10 @@ # -*- coding: utf-8 -*- -from docutils import nodes -from docutils.parsers.rst import directives, Directive +from docutils import nodes, utils +from docutils.parsers.rst import directives, roles, Directive from pygments.formatters import HtmlFormatter from pygments import highlight from pygments.lexers import get_lexer_by_name, TextLexer +import re INLINESTYLES = False DEFAULT = HtmlFormatter(noclasses=INLINESTYLES) @@ -94,3 +95,18 @@ class YouTube(Directive): nodes.raw('', '', format='html')] directives.register_directive('youtube', YouTube) + +_abbr_re = re.compile('\((.*)\)$') + +class abbreviation(nodes.Inline, nodes.TextElement): pass + +def abbr_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): + text = utils.unescape(text) + m = _abbr_re.search(text) + if m is None: + return [abbreviation(text, text)], [] + abbr = text[:m.start()].strip() + expl = m.group(1) + return [abbreviation(abbr, abbr, explanation=expl)], [] + +roles.register_local_role('abbr', abbr_role) diff --git a/tests/content/article.rst b/tests/content/article.rst index 1707ab03..7109c29b 100644 --- a/tests/content/article.rst +++ b/tests/content/article.rst @@ -2,3 +2,5 @@ Article title ############# This is some content. With some stuff to "typogrify". + +Now with added support for :abbr:`TLA (three letter acronym)`. diff --git a/tests/test_readers.py b/tests/test_readers.py index a921cfc2..02d6c122 100644 --- a/tests/test_readers.py +++ b/tests/test_readers.py @@ -47,7 +47,9 @@ class RstReaderTest(unittest.TestCase): # unmodified content, _ = readers.read_file(_filename('article.rst')) expected = "

This is some content. With some stuff to "\ - ""typogrify".

\n" + ""typogrify".

\n

Now with added "\ + 'support for '\ + 'TLA.

\n' self.assertEqual(content, expected) @@ -56,7 +58,9 @@ class RstReaderTest(unittest.TestCase): content, _ = readers.read_file(_filename('article.rst'), settings={'TYPOGRIFY': True}) expected = "

This is some content. With some stuff to "\ - "“typogrify”.

\n" + "“typogrify”.

\n

Now with added "\ + 'support for '\ + 'TLA.

\n' self.assertEqual(content, expected) except ImportError: