Browse Source

switch to mistletoe (commonmark)

pull/67/head
adam j hartz 1 month ago
parent
commit
dfd5d8a2f9
Signed by: hz <hartz@mit.edu> GPG Key ID: 5FDD2840E179AD62
5 changed files with 70 additions and 78 deletions
  1. +6
    -0
      CHANGELOG.md
  2. +1
    -15
      catsoop/language.py
  3. +59
    -59
      catsoop/markdown_math.py
  4. +3
    -3
      catsoop/test/markdown_tests.py
  5. +1
    -1
      requirements.txt

+ 6
- 0
CHANGELOG.md View File

@@ -4,11 +4,17 @@ _Work toward next release. Currently under development._

**ADDED:**

* Added ability to conditionally show or hide HTML elements via the
`cs-show-if` and `cs-hide-if` attributes.

**CHANGED:**

* Auto-generated `csq_name` fields increment for every question, even those
that have names specified.

* Use [mistletoe](https://github.com/miyuchina/mistletoe) for handling Markdown
(CommonMark) instead of Python-Markdown.

**DEPRECATED:**

**REMOVED:**


+ 1
- 15
catsoop/language.py View File

@@ -45,10 +45,6 @@ from . import dispatch
from . import markdown_math
from .errors import html_format, clear_info

import markdown
from markdown.extensions import tables
from markdown.extensions import fenced_code
from markdown.extensions import sane_lists
from bs4 import BeautifulSoup
from unidecode import unidecode

@@ -196,17 +192,7 @@ def xml_pre_handle(context):


def _md(x):
o = markdown.markdown(
x,
extensions=[
"extra",
tables.TableExtension(),
fenced_code.FencedCodeExtension(),
sane_lists.SaneListExtension(),
markdown_math.MathExtension(),
],
)
return o
return markdown_math.markdown(x)


def md_pre_handle(context, xml=True):


+ 59
- 59
catsoop/markdown_math.py View File

@@ -13,62 +13,62 @@
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""CAT-SOOP Math Mode Extension for PyMarkdown"""
from markdown.extensions import Extension
from markdown.inlinepatterns import HtmlInlineProcessor, SimpleTextInlineProcessor
_nodoc = {
"Extension",
"HtmlInlineProcessor",
"SimpleTextInlineProcessor",
"absolute_import",
"unicode_literals",
}
_MATH_RE = r"(?:^|(?<!\\))\$(?P<body>(?:\\\$|[^$])*)\$"
_DMATH_RE = r"\$\$(?P<body>.*?)\$\$"
_DMATHENV_RE = r"\\begin\s*{(?P<env>(?:equation|eqnarray|align)\*?)}(?P<body>(?s).*?)\\end\s*{(?P=env)}"
_ESCAPED_DOLLAR_RE = r"(?<!\\)\\(\$)"
class RawHtmlInlineProcessor(HtmlInlineProcessor):
"""A subclass of `catsoop.thirdparty.markdown.inlinepattern.HtmlInlineProcessor`
used to store raw inline html and return a placeholder."""
def __init__(self, endtag, *args, **kwargs):
self._hz_tag = endtag
HtmlInlineProcessor.__init__(self, *args, **kwargs)
def handleMatch(self, m, data):
groups = m.groupdict()
body = self.unescape(groups["body"])
env = groups.get("env", "")
rawhtml = "<%(tag)s%(env)s>%(body)s</%(tag)s>" % {
"tag": self._hz_tag,
"body": body,
"env": ' env="%s"' % env if env else "",
}
place_holder = self.md.htmlStash.store(rawhtml)
return place_holder, m.start(0), m.end(0)
class MathExtension(Extension):
"""The CAT-SOOP math extension to Markdown."""
def extendMarkdown(self, md):
""" Modify inline patterns."""
md.inlinePatterns.register(
RawHtmlInlineProcessor("displaymath", _DMATHENV_RE, md),
"catsoop_denvmath",
203,
)
md.inlinePatterns.register(
RawHtmlInlineProcessor("displaymath", _DMATH_RE, md), "catsoop_dmath", 183
)
md.inlinePatterns.register(
RawHtmlInlineProcessor("math", _MATH_RE, md), "catsoop_math", 182
)
md.inlinePatterns.register(
SimpleTextInlineProcessor(_ESCAPED_DOLLAR_RE), "catsoop_emath", 181
)
"""CAT-SOOP Math Mode Extension for Mistletoe"""
import re
from mistletoe import Document
from mistletoe.span_token import SpanToken
from mistletoe.html_renderer import HTMLRenderer
class Math(SpanToken):
pattern = re.compile(r"(?:^|(?<!\\))\$(?P<body>(?:\\\$|[^$])*)\$")
parse_inner = False
def __init__(self, match):
self.body = match.group("body")
class DisplayMath(SpanToken):
pattern = re.compile(r"\$\$(?P<body>.*?)\$\$", re.MULTILINE | re.DOTALL)
parse_inner = False
precedence = SpanToken.precedence + 1
def __init__(self, match):
self.body = match.group("body")
class DisplayMathEnv(SpanToken):
pattern = re.compile(
r"\\begin\s*{(?P<env>(?:equation|eqnarray|align)\*?)}(?P<body>(?s).*?)\\end\s*{(?P=env)}",
re.MULTILINE | re.DOTALL,
)
parse_inner = False
def __init__(self, match):
self.body = match.group("body")
self.env = match.group("env")
class EscapedDollar(SpanToken):
pattern = re.compile(r"(?<!\\)\\(\$)")
class CatsoopRenderer(HTMLRenderer):
def __init__(self):
HTMLRenderer.__init__(self, DisplayMathEnv, DisplayMath, Math, EscapedDollar)
def render_math(self, token):
return f"<math>{token.body}</math>"
def render_display_math(self, token):
return f"<displaymath>{token.body}</displaymath>"
def render_display_math_env(self, token):
return f'<displaymath env="{token.env}">{token.body}</displaymath>'
def markdown(x):
with CatsoopRenderer() as renderer:
return renderer.render(Document(x))

+ 3
- 3
catsoop/test/markdown_tests.py View File

@@ -38,7 +38,7 @@ def dmath(x, env=""):


def _md(x):
out = language._md(x)
out = language._md(x).strip()
if out.startswith("<p>") and out.endswith("</p>"):
out = out[3:-4]
return out
@@ -88,11 +88,11 @@ class TestMarkdownMath(CATSOOPTest):
),
(
"\\begin{align}\n x & \\text{if $y$} \\\\\n y & \\text{else}\n\end{align}",
dmath("\n x & \\text{if $y$} \\\\\n y & \\text{else}\n", "align"),
dmath("\nx & \\text{if $y$} \\\\\ny & \\text{else}\n", "align"),
),
(
"\\begin{align*}\n x & \\text{if $y$} \\\\\n y & \\text{else}\n\end{align*}",
dmath("\n x & \\text{if $y$} \\\\\n y & \\text{else}\n", "align*"),
dmath("\nx & \\text{if $y$} \\\\\ny & \\text{else}\n", "align*"),
),
]



+ 1
- 1
requirements.txt View File

@@ -2,7 +2,7 @@ bs4
cheroot
filelock
python-jose
markdown>=3
mistletoe
mpmath
ply
pynacl


Loading…
Cancel
Save