Skip to content

Commit

Permalink
♻️ REFACTOR: default_parser -> create_md_parser (#474)
Browse files Browse the repository at this point in the history
The `renderer` option has been removed from `MdParserConfig`,
since it is not a configuration for the parser.
Then the `default_parser` function has been replaced with `create_md_parser`,
which directly takes the renderer class as a 2nd argument.
  • Loading branch information
chrisjsewell committed Dec 28, 2021
1 parent 90c98aa commit fb67af6
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 43 deletions.
9 changes: 5 additions & 4 deletions docs/api/parsers.md
Expand Up @@ -96,13 +96,14 @@ See the documentation of these tools for more information.

### Load a parser

To load one of these parsers for your own use, use the `default_parser` function.
To load one of these parsers for your own use, use the `create_md_parser` function.
Below we'll create such a parser and show that it is an instance of a `markdown-it-py` parser:

```python
from myst_parser.main import default_parser, MdParserConfig
config = MdParserConfig(renderer="html")
parser = default_parser(config)
from markdown_it.renderer import RendererHTML
from myst_parser.main import create_md_parser, MdParserConfig
config = MdParserConfig()
parser = create_md_parser(config, RendererHTML)
parser
```

Expand Down
5 changes: 2 additions & 3 deletions myst_parser/__init__.py
Expand Up @@ -34,9 +34,8 @@ def setup_sphinx(app: "Sphinx"):
app.add_post_transform(MystReferenceResolver)

for name, default in MdParserConfig().as_dict().items():
if not name == "renderer":
# TODO add types?
app.add_config_value(f"myst_{name}", default, "env")
# TODO add types?
app.add_config_value(f"myst_{name}", default, "env")

app.connect("builder-inited", create_myst_config)
app.connect("builder-inited", override_mathjax)
Expand Down
6 changes: 4 additions & 2 deletions myst_parser/cli.py
@@ -1,7 +1,9 @@
import argparse
import sys

from myst_parser.main import MdParserConfig, default_parser
from markdown_it.renderer import RendererHTML

from myst_parser.main import MdParserConfig, create_md_parser


def print_anchors(args=None):
Expand All @@ -25,7 +27,7 @@ def print_anchors(args=None):
"-l", "--level", type=int, default=2, help="Maximum heading level."
)
args = arg_parser.parse_args(args)
parser = default_parser(MdParserConfig(renderer="html", heading_anchors=args.level))
parser = create_md_parser(MdParserConfig(heading_anchors=args.level), RendererHTML)

def _filter_plugin(state):
state.tokens = [
Expand Down
2 changes: 0 additions & 2 deletions myst_parser/directives.py
Expand Up @@ -61,8 +61,6 @@ def run(self) -> List[nodes.Node]:
figclasses = self.options.pop("class", None)
align = self.options.pop("align", None)

# parser = default_parser(self.env.myst_config)

node = nodes.Element()
# TODO test that we are using myst parser
# ensure html image enabled
Expand Down
10 changes: 4 additions & 6 deletions myst_parser/docutils_.py
Expand Up @@ -11,7 +11,8 @@
from docutils.parsers.rst import Parser as RstParser
from markdown_it.token import Token

from myst_parser.main import MdParserConfig, default_parser
from myst_parser.docutils_renderer import DocutilsRenderer
from myst_parser.main import MdParserConfig, create_md_parser


def _validate_int(
Expand Down Expand Up @@ -63,8 +64,6 @@ def __repr__(self):
"ref_domains",
"update_mathjax",
"mathjax_classes",
# We don't want to set the renderer from docutils.conf
"renderer",
)
"""Names of settings that cannot be set in docutils.conf."""

Expand Down Expand Up @@ -139,7 +138,6 @@ def create_myst_config(settings: frontend.Values):
val = getattr(settings, setting, DOCUTILS_UNSET)
if val is not DOCUTILS_UNSET:
values[attribute.name] = val
values["renderer"] = "docutils"
return MdParserConfig(**values)


Expand Down Expand Up @@ -171,8 +169,8 @@ def parse(self, inputstring: str, document: nodes.document) -> None:
config = create_myst_config(document.settings)
except (TypeError, ValueError) as error:
document.reporter.error(f"myst configuration invalid: {error.args[0]}")
config = MdParserConfig(renderer="docutils")
parser = default_parser(config)
config = MdParserConfig()
parser = create_md_parser(config, DocutilsRenderer)
parser.options["document"] = document
env: dict = {}
tokens = parser.parse(inputstring, env)
Expand Down
40 changes: 16 additions & 24 deletions myst_parser/main.py
Expand Up @@ -35,9 +35,6 @@ class MdParserConfig:
Note in the sphinx configuration these option names are prepended with ``myst_``
"""

renderer: str = attr.ib(
default="sphinx", validator=in_(["sphinx", "html", "docutils"])
)
commonmark_only: bool = attr.ib(
default=False,
validator=instance_of(bool),
Expand Down Expand Up @@ -196,32 +193,27 @@ def as_dict(self, dict_factory=dict) -> dict:
return attr.asdict(self, dict_factory=dict_factory)


def default_parser(config: MdParserConfig) -> MarkdownIt:
"""Return the default parser configuration for MyST"""
renderer_cls: Callable[[MarkdownIt], RendererProtocol]

if config.renderer == "sphinx":
from myst_parser.sphinx_renderer import SphinxRenderer
def default_parser(config: MdParserConfig):
raise NotImplementedError(
"default_parser has been deprecated and replaced by create_md_parser."
"You must also supply the renderer class directly to create_md_parser."
)

renderer_cls = SphinxRenderer
elif config.renderer == "html":
renderer_cls = RendererHTML
elif config.renderer == "docutils":
from myst_parser.docutils_renderer import DocutilsRenderer

renderer_cls = DocutilsRenderer
else:
raise ValueError("unknown renderer type: {0}".format(config.renderer))
def create_md_parser(
config: MdParserConfig, renderer: Callable[[MarkdownIt], RendererProtocol]
) -> MarkdownIt:
"""Return a Markdown parser with the required MyST configuration."""

if config.commonmark_only:
md = MarkdownIt("commonmark", renderer_cls=renderer_cls).use(
md = MarkdownIt("commonmark", renderer_cls=renderer).use(
wordcount_plugin, per_minute=config.words_per_minute
)
md.options.update({"commonmark_only": True})
return md

md = (
MarkdownIt("commonmark", renderer_cls=renderer_cls)
MarkdownIt("commonmark", renderer_cls=renderer)
.enable("table")
.use(front_matter_plugin)
.use(myst_block_plugin)
Expand Down Expand Up @@ -299,6 +291,7 @@ def default_parser(config: MdParserConfig) -> MarkdownIt:
def to_docutils(
text: str,
parser_config: Optional[MdParserConfig] = None,
*,
options=None,
env=None,
document=None,
Expand All @@ -320,8 +313,9 @@ def to_docutils(
:returns: docutils document
"""
from myst_parser.docutils_renderer import make_document
from myst_parser.sphinx_renderer import SphinxRenderer

md = default_parser(parser_config or MdParserConfig())
md = create_md_parser(parser_config or MdParserConfig(), SphinxRenderer)
if options:
md.options.update(options)
md.options["document"] = document or make_document()
Expand All @@ -340,13 +334,11 @@ def to_html(text: str, env=None, config: Optional[MdParserConfig] = None):
This is mainly for test purposes only.
"""
config = config or MdParserConfig()
config.renderer = "html"
md = default_parser(config)
md = create_md_parser(config, RendererHTML)
return md.render(text, env)


def to_tokens(text: str, env=None, config: Optional[MdParserConfig] = None):
config = config or MdParserConfig()
config.renderer = "html"
md = default_parser(config)
md = create_md_parser(config, RendererHTML)
return md.parse(text, env)
5 changes: 3 additions & 2 deletions myst_parser/sphinx_parser.py
Expand Up @@ -12,7 +12,8 @@
from sphinx.util import logging
from sphinx.util.docutils import sphinx_domains

from myst_parser.main import default_parser
from myst_parser.main import create_md_parser
from myst_parser.sphinx_renderer import SphinxRenderer

SPHINX_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -49,7 +50,7 @@ def parse(self, inputstring: str, document: nodes.document) -> None:
"""
config = document.settings.env.myst_config
parser = default_parser(config)
parser = create_md_parser(config, SphinxRenderer)
parser.options["document"] = document
env: dict = {}
tokens = parser.parse(inputstring, env)
Expand Down

0 comments on commit fb67af6

Please sign in to comment.