diff --git a/CHANGES b/CHANGES index 3518cb03c..9823bb988 100644 --- a/CHANGES +++ b/CHANGES @@ -44,6 +44,9 @@ New features added - #10: Added HTML section numbers, enabled by giving a ``:numbered:`` flag to the ``toctree`` directive. + - #114: Added an ``abbr`` role to markup abbreviations and + acronyms. + - The ``literalinclude`` directive now supports several more options, to include only parts of a file. diff --git a/doc/concepts.rst b/doc/concepts.rst index e6d5fa026..d3c8cf7c2 100644 --- a/doc/concepts.rst +++ b/doc/concepts.rst @@ -19,6 +19,8 @@ such a document name. Examples for document names are ``index``, ``library/zipfile``, or ``reference/datamodel/types``. Note that there is no leading slash. +This is a :abbr:`LIFO (last-in, first-out)` and a :abbr:`LIFO (last-in, first-out)`. + The TOC tree ------------ diff --git a/doc/markup/inline.rst b/doc/markup/inline.rst index 97b20da79..69721b321 100644 --- a/doc/markup/inline.rst +++ b/doc/markup/inline.rst @@ -278,6 +278,16 @@ Other semantic markup The following roles don't do anything special except formatting the text in a different style: +.. role:: abbr + + An abbreviation. If the role content contains a parenthesized explanation, + it will be treated specially: it will be shown in a tool-tip in HTML, and + output only once in LaTeX. + + Example: ``:abbr:`LIFO (last-in, first-out)```. + + .. versionadded:: 0.6 + .. role:: command The name of an OS-level command, such as ``rm``. diff --git a/sphinx/addnodes.py b/sphinx/addnodes.py index f0b0b0632..63907a0e6 100644 --- a/sphinx/addnodes.py +++ b/sphinx/addnodes.py @@ -84,6 +84,9 @@ class highlightlang(nodes.Element): pass # like emphasis, but doesn't apply further text processors, e.g. smartypants class literal_emphasis(nodes.emphasis): pass +# for abbreviations (with explanations) +class abbreviation(nodes.Inline, nodes.TextElement): pass + # glossary class glossary(nodes.Element): pass @@ -109,4 +112,5 @@ nodes._add_node_class_names("""index desc desc_content desc_signature desc_parameter desc_optional download_reference hlist hlistcol centered versionmodified seealso productionlist production toctree pending_xref compact_paragraph highlightlang literal_emphasis - glossary acks module start_of_file tabular_col_spec meta""".split()) + abbreviation glossary acks module start_of_file tabular_col_spec + meta""".split()) diff --git a/sphinx/roles.py b/sphinx/roles.py index 9cc7fcd24..550deb3ee 100644 --- a/sphinx/roles.py +++ b/sphinx/roles.py @@ -226,6 +226,18 @@ def emph_literal_role(typ, rawtext, text, lineno, inliner, return [retnode], [] +_abbr_re = re.compile('\((.*)\)$') + +def abbr_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): + text = utils.unescape(text) + m = _abbr_re.search(text) + if m is None: + return [addnodes.abbreviation(text, text)], [] + abbr = text[:m.start()].strip() + expl = m.group(1) + return [addnodes.abbreviation(abbr, abbr, explanation=expl)], [] + + specific_docroles = { 'data': xfileref_role, 'exc': xfileref_role, @@ -254,6 +266,7 @@ specific_docroles = { 'menuselection': menusel_role, 'file': emph_literal_role, 'samp': emph_literal_role, + 'abbr': abbr_role, } for rolename, func in specific_docroles.iteritems(): diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py index e2f754a81..f600e8bd2 100644 --- a/sphinx/writers/html.py +++ b/sphinx/writers/html.py @@ -453,6 +453,14 @@ class HTMLTranslator(BaseTranslator): def depart_literal_emphasis(self, node): return self.depart_emphasis(node) + 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('') + def depart_title(self, node): close_tag = self.context[-1] if self.add_permalinks and self.builder.add_permalinks and \ diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 9ec3b00d4..fddc0a79c 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -216,6 +216,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.written_ids = set() self.footnotestack = [] self.curfilestack = [] + self.handled_abbrs = set() if self.elements['docclass'] == 'manual': if builder.config.latex_use_parts: self.top_sectionlevel = 0 @@ -1043,6 +1044,18 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_strong(self, node): self.body.append('}') + def visit_abbreviation(self, node): + abbr = node.astext() + self.body.append(r'\textsc{') + # spell out the explanation once + if node.hasattr('explanation') and abbr not in self.handled_abbrs: + self.context.append('} (%s)' % self.encode(node['explanation'])) + self.handled_abbrs.add(abbr) + else: + self.context.append('}') + def depart_abbreviation(self, node): + self.body.append(self.context.pop()) + def visit_title_reference(self, node): self.body.append(r'\emph{') def depart_title_reference(self, node): diff --git a/sphinx/writers/text.py b/sphinx/writers/text.py index 787e70207..b3b565c51 100644 --- a/sphinx/writers/text.py +++ b/sphinx/writers/text.py @@ -645,6 +645,12 @@ class TextTranslator(nodes.NodeVisitor): def depart_strong(self, node): self.add_text('**') + def visit_abbreviation(self, node): + self.add_text('') + def depart_abbreviation(self, node): + if node.hasattr('explanation'): + self.add_text(' (%s)' % node['explanation']) + def visit_title_reference(self, node): self.add_text('*') def depart_title_reference(self, node): diff --git a/tests/root/markup.txt b/tests/root/markup.txt index d799c80dd..52d407e22 100644 --- a/tests/root/markup.txt +++ b/tests/root/markup.txt @@ -152,6 +152,7 @@ Option list: try2_stmt: "try" ":" `suite` : "finally" ":" `suite` +Test :abbr:`abbr (abbreviation)` and another :abbr:`abbr (abbreviation)`. Index markup ------------