Skip to content

Commit

Permalink
[ENH] add support for definition lists to myst (#94)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmcky committed Nov 2, 2020
1 parent dbec1fd commit e16f278
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 84 deletions.
6 changes: 6 additions & 0 deletions sphinx_tomyst/writers/myst.py
Expand Up @@ -26,6 +26,12 @@ def visit_bullet_list_item(self, listobj):
marker = listobj["marker"]
return "{}{} ".format(indent, marker)

def visit_definition(self, text):
# Adjust \n and \n\n with indentation
text = text.replace("\n", "\n ")
text = text.replace("\n \n ", "\n\n ")
return ": " + text

def visit_epigraph(self):
return "```{{epigraph}}"

Expand Down
92 changes: 57 additions & 35 deletions sphinx_tomyst/writers/translator.py
Expand Up @@ -67,6 +67,9 @@ class MystTranslator(SphinxTranslator):
block_quote["in"] = False
block_quote["type"] = None
block_quote["collect"] = []
# Definition
definition = dict()
definition["in"] = False
# Figure
figure = dict()
figure["in"] = False
Expand Down Expand Up @@ -114,6 +117,7 @@ def __init__(self, document, builder):
self.language_synonyms = self.builder.config["tomyst_language_synonyms"]
self.language_synonyms.append(self.default_language)
self.debug = self.builder.config["tomyst_debug"]
self.messages = set()
# Document Settings
self.syntax = MystSyntax()
self.images = []
Expand All @@ -134,6 +138,9 @@ def visit_document(self, node):

def depart_document(self, node):
self.body = "".join(self.output)
if self.messages:
for msg in self.messages:
logger.info(msg)

def unknown_visit(self, node):
raise NotImplementedError("Unknown node: " + node.__class__.__name__)
Expand Down Expand Up @@ -165,6 +172,9 @@ def visit_Text(self, node):

def depart_Text(self, node):
# Accumulators
if self.definition["in"]:
self.definition["text"] += self.text
return
if self.List:
self.List.addto_list_item(self.text)
return
Expand Down Expand Up @@ -493,37 +503,28 @@ def depart_danger(self, node):
# https://docutils.sourceforge.io/docs/ref/doctree.html#definition

def visit_definition(self, node):
pass
# Current Syntax consists of HTML markers
# self.output.append(self.syntax.visit_definition()) #html markers!
# self.add_newline()
self.definition["in"] = True
self.definition["text"] = ""

def depart_definition(self, node):
pass
# Current Syntax consists of HTML markers
# self.output.append(self.syntax.depart_definition())
# self.add_newline()
syntax = self.syntax.visit_definition(self.definition["text"].rstrip())
self.output.append(syntax)
self.definition["text"] = ""
self.definition["in"] = False

# docutils.elements.definition_list
# https://docutils.sourceforge.io/docs/ref/doctree.html#definition-list

def visit_definition_list(self, node):
msg = """
SKIP [definition_list] objects are not supported in commonmark
CONFIG [definition_list] support for definition list in myst requires:
myst_deflist_enable = True
to be specified in the conf.py
""".strip()
logger.warning(msg)
raise nodes.SkipNode
# Current Syntax consists of HTML markers
# self.add_newline()
# self.output.append(self.syntax.visit_definition_list())
# self.add_newline()
self.messages.add(msg)

def depart_definition_list(self, node):
pass
# Current Syntax consists of HTML markers
# self.add_newline()
# self.output.append(self.syntax.depart_definition_list())
# self.add_newparagraph()

# docutils.elements.definition_list_item
# https://docutils.sourceforge.io/docs/ref/doctree.html#definition-list-item
Expand All @@ -532,7 +533,7 @@ def visit_definition_list_item(self, node):
pass

def depart_definition_list_item(self, node):
pass
self.add_newparagraph()

# docutils.elements.description
# https://docutils.sourceforge.io/docs/ref/doctree.html#description
Expand Down Expand Up @@ -570,6 +571,8 @@ def visit_emphasis(self, node):
self.Table.add_item(syntax)
elif self.block_quote["in"] and self.block_quote["type"] == "block_quote":
self.block_quote["collect"].append(syntax)
elif self.definition["in"]:
self.definition["text"] += syntax
else:
self.output.append(syntax)

Expand All @@ -581,6 +584,8 @@ def depart_emphasis(self, node):
self.Table.add_item(syntax)
elif self.block_quote["in"] and self.block_quote["type"] == "block_quote":
self.block_quote["collect"].append(syntax)
elif self.definition["in"]:
self.definition["text"] += syntax
else:
self.output.append(syntax)

Expand Down Expand Up @@ -639,40 +644,42 @@ def depart_error(self, node):
# docutils.elements.field
# https://docutils.sourceforge.io/docs/ref/doctree.html#field

# TODO: Implement Support for Fields

def visit_field(self, node):
# for child in node.children:
# if type(child) is nodes.field_name:
# field_name = child.astext()
# elif type(child) is nodes.field_body:
# field_body = child.astext()
raise NotImplementedError
raise nodes.SkipChildren

# docutils.elements.field_body
# https://docutils.sourceforge.io/docs/ref/doctree.html#field-body

def visit_field_body(self, node):
self.visit_definition(node) # TODO: review if wrapper of definition
pass

def depart_field_body(self, node):
self.depart_definition(node)
pass

# docutils.elements.field_list
# https://docutils.sourceforge.io/docs/ref/doctree.html#field-list

def visit_field_list(self, node):
self.visit_definition_list(node)
pass

def depart_field_list(self, node):
self.depart_definition_list(node)
pass

# docutils.element.field_name
# https://docutils.sourceforge.io/docs/ref/doctree.html#field-name

def visit_field_name(self, node):
self.visit_term(node)
pass

def depart_field_name(self, node):
self.depart_term(node)
pass

# docutils.figure
# https://docutils.sourceforge.io/docs/ref/rst/directives.html#figure
Expand Down Expand Up @@ -978,6 +985,8 @@ def visit_literal(self, node):
self.Table.add_item(syntax)
elif self.block_quote["in"] and self.block_quote["type"] == "block_quote":
self.block_quote["collect"].append(syntax)
elif self.definition["in"]:
self.definition["text"] += syntax
else:
self.output.append(syntax)

Expand All @@ -991,6 +1000,8 @@ def depart_literal(self, node):
self.Table.add_item(syntax)
elif self.block_quote["in"] and self.block_quote["type"] == "block_quote":
self.block_quote["collect"].append(syntax)
elif self.definition["in"]:
self.definition["text"] += syntax
else:
self.output.append(syntax)
self.literal = False
Expand Down Expand Up @@ -1110,12 +1121,6 @@ def depart_literal_block(self, node):
self.add_newparagraph()
self.literal_block = False

# sphinx.literalinclude
def visit_literalinclude(self, node):
import pdb

pdb.set_trace()

# docutils.element.math
# https://docutils.sourceforge.io/docs/ref/doctree.html#math

Expand All @@ -1129,6 +1134,8 @@ def visit_math(self, node):
self.Table.add_item(syntax)
elif self.block_quote["in"] and self.block_quote["type"] == "block_quote":
self.block_quote["collect"].append(syntax)
elif self.definition["in"]:
self.definition["text"] += syntax
else:
self.output.append(syntax)

Expand All @@ -1140,6 +1147,8 @@ def depart_math(self, node):
self.Table.add_item(syntax)
elif self.block_quote["in"] and self.block_quote["type"] == "block_quote":
self.block_quote["collect"].append(syntax)
elif self.definition["in"]:
self.definition["text"] += syntax
else:
self.output.append(syntax)
self.math = False
Expand All @@ -1163,6 +1172,8 @@ def visit_math_block(self, node):
self.Table.add_item(syntax)
elif self.block_quote["in"] and self.block_quote["type"] == "block_quote":
self.block_quote["collect"].append(syntax)
elif self.definition["in"]:
self.definition["text"] += syntax
else:
self.output.append(syntax)

Expand All @@ -1188,6 +1199,8 @@ def depart_math_block(self, node):
self.Table.add_item(syntax + "\n\n")
elif self.block_quote["in"] and self.block_quote["type"] == "block_quote":
self.block_quote["collect"].append(syntax + "\n\n")
elif self.definition["in"]:
self.definition["text"] += syntax + "\n\n"
else:
self.output.append(syntax + "\n\n")
self.math_block["in"] = False
Expand Down Expand Up @@ -1251,6 +1264,9 @@ def depart_paragraph(self, node):
if self.block_quote["in"] and self.block_quote["type"] == "block_quote":
self.block_quote["collect"].append("\n\n")
return
if self.definition["in"]:
self.definition["text"] += "\n\n"
return
self.add_newparagraph()

# docutils.elements.pending
Expand Down Expand Up @@ -1454,6 +1470,8 @@ def visit_strong(self, node):
self.Table.add_item(syntax)
elif self.block_quote["in"] and self.block_quote["type"] == "block_quote":
self.block_quote["collect"].append(syntax)
elif self.definition["in"]:
self.definition["text"] += syntax
else:
self.output.append(syntax)

Expand All @@ -1465,6 +1483,8 @@ def depart_strong(self, node):
self.Table.add_item(syntax)
elif self.block_quote["in"] and self.block_quote["type"] == "block_quote":
self.block_quote["collect"].append(syntax)
elif self.definition["in"]:
self.definition["text"] += syntax
else:
self.output.append(syntax)

Expand Down Expand Up @@ -1539,10 +1559,12 @@ def depart_tbody(self, node):
# https://docutils.sourceforge.io/docs/ref/doctree.html#term

def visit_term(self, node):
self.output.append("<dt>")
self.output.append(node.astext())
self.add_newline()
raise nodes.SkipChildren

def depart_term(self, node):
self.output.append("</dt>\n")
pass

# docutils.element.tgroup
# uses: table
Expand Down
31 changes: 17 additions & 14 deletions tests/snippet/test_snippet.myst
Expand Up @@ -15,26 +15,29 @@ kernelspec:

# Snippet

Add a footnote
## definition_list

Lorem ipsum [^f1] dolor sit amet ... [^f2]
This tests `definition`, `definition_list` and
`definition_list_item`

[^f1]: Text of the first footnote.
Term1
: Definition 1a
with **another part** of the paragraphs

[^f2]: Text of the second footnote.
Definition 1b

Lorem ipsum [^autoid_0] dolor sit amet ... [^autoid_1]
Term2
: Definition 2 with $f_x$

[^autoid_0]: Text of the first footnote.
$$
f_x
$$

[^autoid_1]: Text of the second footnote.
Can `term` have formatting:

and example from lectures
Term3
: Definition 3

Just as [NumPy](http://www.numpy.org/) provides the basic array data type plus core array operations, pandas

1. endows them with methods that facilitate operations such as
* sorting, grouping, re-ordering and general data munging [^mung]

[^mung]: Wikipedia defines munging as cleaning data from one raw form into a structured, purged one.
Currently this is **not** supported and only `term3` as text
will be transferred

4 changes: 2 additions & 2 deletions tests/source/docutils/directives.rst
Expand Up @@ -125,10 +125,10 @@ hint
images
------

.. image:: qs.png
.. image:: img/qs.png
:scale: 50 %

.. image:: qs.png
.. image:: img/qs.png
:height: 100px

important
Expand Down
24 changes: 19 additions & 5 deletions tests/source/docutils/elements.rst
Expand Up @@ -107,12 +107,26 @@ definition_list
This tests ``definition``, ``definition_list`` and
``definition_list_item``

Term
Definition.
Term1
Definition 1a
with **another part** of the paragraphs

Term : classifier
The ' : ' indicates a classifier in
definition list item terms only.
Definition 1b

Term2
Definition 2 with :math:`f_x`

.. math::
f_x
Can ``term`` have formatting:

**Term3**
Definition 3

Currently this is **not** supported and only ``term3`` as text
will be transferred

docinfo
-------
Expand Down

0 comments on commit e16f278

Please sign in to comment.