Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ NEW: Add myst_extensions configuration option #9

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 31 additions & 1 deletion mdformat_myst/plugin.py
@@ -1,7 +1,9 @@
from __future__ import annotations

import argparse
import re
from textwrap import indent
from typing import Set

from markdown_it import MarkdownIt
import mdformat.plugins
Expand All @@ -16,8 +18,35 @@
_TARGET_PATTERN = re.compile(r"^\s*\(([a-zA-Z0-9|@<>*./_\-+:]{1,100})\)=\s*$")
_ROLE_NAME_PATTERN = re.compile(r"({[a-zA-Z0-9_\-+:]{1,36}})")

# TODO eventually support all in:
# https://myst-parser.readthedocs.io/en/latest/syntax/optional.html
SUPPORTED_EXTENSIONS = {"dollarmath"}


def _extension_arg_type(arg: str) -> Set[str]:
"""Convert extension list to set and validate."""
extensions = set(arg.split(","))
unallowed_extensions = extensions.difference(SUPPORTED_EXTENSIONS)
if unallowed_extensions:
raise ValueError(f"Unsupported myst extensions: {unallowed_extensions!r}")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be made a warning instead of a hard error?

return extensions


def add_cli_options(parser: argparse.ArgumentParser) -> None:
"""Add options to the mdformat CLI, to be stored in
``mdit.options["mdformat"]``"""
parser.add_argument(
"--myst-extensions",
dest="myst_extensions",
type=_extension_arg_type,
default="dollarmath",
help="Comma-delimited list of MyST syntax extensions",
metavar="|".join(SUPPORTED_EXTENSIONS),
)


def update_mdit(mdit: MarkdownIt) -> None:
myst_extensions = mdit.options.get("mdformat", {}).get("myst_extensions", set())
# Enable mdformat-tables plugin
tables_plugin = mdformat.plugins.PARSER_EXTENSIONS["tables"]
if tables_plugin not in mdit.options["parser_extension"]:
Expand All @@ -38,7 +67,8 @@ def update_mdit(mdit: MarkdownIt) -> None:
mdit.use(myst_block_plugin)

# Enable dollarmath markdown-it extension
mdit.use(dollarmath_plugin)
if "dollarmath" in myst_extensions:
mdit.use(dollarmath_plugin)

# Enable footnote markdown-it extension
mdit.use(footnote_plugin)
Expand Down
14 changes: 12 additions & 2 deletions tests/test_mdformat_myst.py
Expand Up @@ -13,21 +13,31 @@
)
def test_fixtures__api(line, title, text, expected):
"""Test fixtures in tests/data/fixtures.md."""
md_new = mdformat.text(text, extensions={"myst"})
md_new = mdformat.text(
text, extensions={"myst"}, options={"myst_extensions": {"dollarmath"}}
)
try:
assert md_new == expected
except Exception:
print(md_new)
raise


def test_cli_unsupported_extension(tmp_path):
file_path = tmp_path / "test_markdown.md"
file_path.write_text("a")

with pytest.raises(SystemExit):
mdformat._cli.run([str(file_path), "--myst-extensions", "a"])


@pytest.mark.parametrize(
"line,title,text,expected", TEST_CASES, ids=[f[1] for f in TEST_CASES]
)
def test_fixtures__cli(line, title, text, expected, tmp_path):
"""Test fixtures in tests/data/fixtures.md."""
file_path = tmp_path / "test_markdown.md"
file_path.write_text(text)
assert mdformat._cli.run([str(file_path)]) == 0
assert mdformat._cli.run([str(file_path), "--myst-extensions", "dollarmath"]) == 0
md_new = file_path.read_text()
assert md_new == expected