Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Implemented :eq: role and 🏷️ option in math blocks for sphinx compati…
…bility
  • Loading branch information
Roberto Alsina committed Jun 13, 2018
1 parent c2ec991 commit 84ecbad
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 12 deletions.
3 changes: 2 additions & 1 deletion v7/sphinx_roles/README.md
Expand Up @@ -6,7 +6,8 @@ Currently supported:
* **ref:** Cross references for arbitrary locations (see [the sphinx docs](http://sphinx-doc.org/markup/inline.html#role-ref)). Limited to links inside a single document.
* **rfc:** An enhanced `:rfc:` role with support for anchors, like Sphinx's
* **term:** Reference to a term in the glossary
* **term:** Reference to a option defined using the option directive
* **option:** Reference to a option defined using the option directive
* **eq:** Reference to a equation defined in a math directive's label option.

The following are "semantic markup", they produce a HTML element with an extra
CSS class for styling. The description is from the Sphinx docs.
Expand Down
2 changes: 1 addition & 1 deletion v7/sphinx_roles/sphinx_roles.plugin
Expand Up @@ -9,7 +9,7 @@ MinVersion = 7.4.0

[Documentation]
Author = Roberto Alsina
Version = 0.3
Version = 0.4
Website = http://plugins.getnikola.com/#sphinx_roles
Description = A set of reStructuredText roles for Sphinx compatibility

52 changes: 42 additions & 10 deletions v7/sphinx_roles/sphinx_roles.py
Expand Up @@ -27,11 +27,11 @@
import datetime
import re

from docutils import nodes, utils
from docutils import languages, nodes, utils
from docutils.parsers.rst import Directive, directives, roles
from docutils.parsers.rst.directives.admonitions import BaseAdmonition
from docutils.parsers.rst.directives.body import MathBlock
from docutils.transforms import Transform
from docutils import languages

from nikola.plugin_categories import RestExtension
from nikola.plugins.compile.rest import add_node
Expand All @@ -48,6 +48,7 @@ def set_site(self, site):
roles.register_local_role('term', term_role)
roles.register_local_role('option', option_role)
roles.register_local_role('ref', ref_role)
roles.register_local_role('eq', eq_role)

# This is copied almost verbatim from Sphinx
generic_docroles = {
Expand Down Expand Up @@ -94,6 +95,7 @@ def set_site(self, site):
directives.register_directive('seealso', SeeAlso)
directives.register_directive('glossary', Glossary)
directives.register_directive('option', Option)
directives.register_directive('math', Math)

site.rst_transforms.append(Today)

Expand All @@ -112,7 +114,8 @@ def pep_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
try:
pepnum = int(text)
except ValueError:
msg = inliner.reporter.error('invalid PEP number %s' % text, line=lineno)
msg = inliner.reporter.error(
'invalid PEP number %s' % text, line=lineno)
prb = inliner.problematic(rawtext, rawtext, msg)
return [prb], [msg]
ref = inliner.document.settings.pep_base_url + 'pep-%04d' % pepnum
Expand Down Expand Up @@ -143,7 +146,8 @@ def rfc_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
try:
rfcnum = int(text)
except ValueError:
msg = inliner.reporter.error('invalid PEP number %s' % text, line=lineno)
msg = inliner.reporter.error(
'invalid PEP number %s' % text, line=lineno)
prb = inliner.problematic(rawtext, rawtext, msg)
return [prb], [msg]
ref = inliner.document.settings.rfc_base_url + inliner.rfc_url % rfcnum
Expand Down Expand Up @@ -265,6 +269,19 @@ def set_source_info(directive, node):
'deprecated': 'Deprecated since version %s',
}

math_option_spec = MathBlock.option_spec
math_option_spec['label'] = str


class Math(MathBlock):
option_spec = math_option_spec

def run(self):
output = super(Math, self).run()
if 'label' in self.options and output:
new_id = 'eq-' + self.options['label']
output[0]['ids'].append(new_id)
return output

class VersionChange(Directive):
"""
Expand Down Expand Up @@ -304,7 +321,8 @@ def run(self):
node[0].insert(0, nodes.inline('', '%s: ' % text,
classes=['versionmodified']))
else:
para = nodes.paragraph('', '', nodes.inline('', '%s.' % text, classes=['versionmodified']))
para = nodes.paragraph('', '', nodes.inline(
'', '%s.' % text, classes=['versionmodified']))
node.append(para)
language = languages.get_language(self.state.document.settings.language_code,
self.state.document.reporter)
Expand Down Expand Up @@ -425,6 +443,15 @@ def term_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
return [pnode], []


def eq_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
# FIXME add stylable span inside link
text = utils.unescape(text)
target = '#eq-' + nodes.make_id(text)
pnode = nodes.reference(text, text, internal=True, refuri=target)
pnode['classes'] = ['reference']
return [pnode], []


class Option(Directive):
has_content = True
required_arguments = 1
Expand All @@ -435,7 +462,8 @@ def run(self):
dl = nodes.definition_list()
dt = nodes.definition_list_item()
term = nodes.term()
term += nodes.literal(self.arguments[0], self.arguments[0], classes=["descname"])
term += nodes.literal(self.arguments[0],
self.arguments[0], classes=["descname"])
dt += term
definition = nodes.definition()
dt += definition
Expand Down Expand Up @@ -481,8 +509,10 @@ def visit_target(self, node):
else:
sibs = node.parent.children
next_sib = sibs[sibs.index(node) + 1]
if isinstance(next_sib, nodes.figure): # text has to be the figure caption
self.text = [x for x in next_sib.children if isinstance(x, nodes.caption)][0].astext()
# text has to be the figure caption
if isinstance(next_sib, nodes.figure):
self.text = [x for x in next_sib.children if isinstance(
x, nodes.caption)][0].astext()
elif isinstance(next_sib, nodes.section): # text has to be the title
self.text = next_sib.attributes['names'][0].title()

Expand All @@ -492,9 +522,11 @@ def unknown_visit(self, node):
visitor = RefVisitor(inliner.document, text)
inliner.document.walk(visitor)
if visitor.text is None:
msg_list.append(inliner.reporter.error("ref label {} is missing or not immediately before figure or section.".format(text)))
msg_list.append(inliner.reporter.error(
"ref label {} is missing or not immediately before figure or section.".format(text)))
target = '#' + text
pnode = nodes.reference(text, visitor.text, internal=True, refuri=target)
pnode = nodes.reference(
text, visitor.text, internal=True, refuri=target)
pnode['classes'] = ['reference']
return [pnode], msg_list

Expand Down

0 comments on commit 84ecbad

Please sign in to comment.