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 Docutils MyST config and CLI #426

Merged
merged 17 commits into from
Dec 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions docs/api/parsers.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,34 @@

The MyST Parser comes bundled with some helper functions to quickly parse MyST Markdown and render its output.

:::{important}
These APIs are primarily intended for testing and development purposes.
For proper parsing see {ref}`myst-sphinx` and {ref}`myst-docutils`.
:::

### Parse MyST Markdown to HTML

For example, the following code parses markdown and renders as HTML:
The following code parses markdown and renders as HTML using only the markdown-it parser
(i.e. no sphinx or docutils specific processing is done):

```python
from myst_parser.main import to_html
to_html("some *text*")
to_html("some *text* {literal}`a`")
```

<!-- #region -->
```html
'<p>some <em>text</em></p>\n'
'<p>some <em>text</em> <code class="myst role">{literal}[a]</code></p>\n'
```
<!-- #endregion -->

### Parse MyST Markdown to docutils

The following function renders your text as **docutils objects** (for example, for use with the Sphinx ecosystem):
The following function renders your text as **docutils AST objects** (for example, for use with the Sphinx ecosystem):

```python
from myst_parser.main import to_docutils
print(to_docutils("some *text*").pformat())
print(to_docutils("some *text* {literal}`a`").pformat())
```

```xml
Expand All @@ -39,8 +45,17 @@ print(to_docutils("some *text*").pformat())
some
<emphasis>
text

<literal>
a
```

:::{note}
This function only performs the initial parse of the AST,
without applying any transforms or post-processing.
See for example the [Sphinx core events](https://www.sphinx-doc.org/en/master/extdev/appapi.html?highlight=config-inited#sphinx-core-events).
:::

### Parse MyST Markdown as `markdown-it` tokens

The MyST Parser uses `markdown-it-py` tokens as an intermediate representation of your text.
Expand Down
10 changes: 10 additions & 0 deletions docs/api/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ Additional Methods
.. autofunction:: myst_parser.sphinx_renderer.mock_sphinx_env


.. _api/docutils_parser:

Docutils Parser Reference
-------------------------

.. autoclass:: myst_parser.docutils_.Parser
:members: parse
:undoc-members:
:member-order: bysource
:show-inheritance:

.. _api/sphinx_parser:

Expand Down
32 changes: 31 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

from sphinx.application import Sphinx
from sphinx.util.docutils import SphinxDirective

from myst_parser import __version__

# -- Project information -----------------------------------------------------
Expand Down Expand Up @@ -167,7 +170,34 @@ def run_apidoc(app):
]


def setup(app):
def setup(app: Sphinx):
"""Add functions to the Sphinx setup."""

class DocutilsCliHelpDirective(SphinxDirective):
"""Directive to print the docutils CLI help."""

has_content = False
required_arguments = 0
optional_arguments = 0
final_argument_whitespace = False
option_spec = {}

def run(self):
"""Run the directive."""
import io

from docutils import nodes
from docutils.frontend import OptionParser

from myst_parser.docutils_ import Parser as DocutilsParser

stream = io.StringIO()
OptionParser(
components=(DocutilsParser,),
usage="myst-docutils-<writer> [options] [<source> [<destination>]]",
).print_help(stream)
return [nodes.literal_block("", stream.getvalue())]

# app.connect("builder-inited", run_apidoc)
app.add_css_file("custom.css")
app.add_directive("docutils-cli-help", DocutilsCliHelpDirective)
79 changes: 79 additions & 0 deletions docs/docutils.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
(myst-docutils)=

# MyST with Docutils

Sphinx, and thus MyST-Parser, is built on top of the [Docutils](https://docutils.sourceforge.io/docs/) package.
MyST-Parser offers a renderer, parser and CLI-interface for working directly with Docutils, independent of Sphinx, as described below.

:::{note}
Since these tools are independent of Sphinx, this means they cannot parse any Sphinx or Sphinx extensions specific roles or directives.
:::

On installing MyST-Parser, the following CLI-commands are made available:

- `myst-docutils-html`: converts MyST to HTML
- `myst-docutils-html5`: converts MyST to HTML5
- `myst-docutils-latex`: converts MyST to LaTeX
- `myst-docutils-xml`: converts MyST to docutils-native XML
- `myst-docutils-pseudoxml`: converts MyST to pseudo-XML (to visualise the AST structure)

Each command can be piped stdin or take a file path as an argument:

```console
$ myst-docutils-html --help
$ echo "Hello World" | myst-docutils-html
$ myst-docutils-html hello-world.md
```

The commands are based on the [Docutils Front-End Tools](https://docutils.sourceforge.io/docs/user/tools.html), and so follow the same argument and options structure, included many of the MyST specific options detailed in [](sphinx/config-options).

:::{dropdown} Shared Docutils CLI Options
```{docutils-cli-help}
```
:::

The CLI commands can also utilise the [`docutils.conf` configuration file](https://docutils.sourceforge.io/docs/user/config.html) to configure the behaviour of the CLI commands. For example:

```
# These entries affect all processing:
[general]
myst-enable-extensions: deflist,linkify
myst-footnote-transition: no

# These entries affect specific HTML output:
[html writers]
embed-stylesheet: no

[html5 writer]
stylesheet-dirs: path/to/html5_polyglot/
stylesheet-path: minimal.css, responsive.css
```

You can also use the {py:class}`myst_parser.docutils_.Parser` class programmatically with the [Docutils publisher API](https://docutils.sourceforge.io/docs/api/publisher.html):

```python
from docutils.core import publish_string
from myst_parser.docutils_ import Parser

source = "hallo world\n: Definition"
output = publish_string(
source=source,
writer_name="html5",
settings_overrides={
"myst_enable_extensions": ["deflist"],
"embed_stylesheet": False,
},
parser=Parser(),
)
```

Finally, you can include MyST Markdown files within a RestructuredText file, using the [`include` directive](https://docutils.sourceforge.io/docs/ref/rst/directives.html#include):

```rst
.. include:: include.md
:parser: myst_parser.docutils_
```

```{important}
The `parser` option requires `docutils>=0.17`
```
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ syntax/reference
:caption: Topic Guides
explain/index.md
sphinx/index.md
docutils.md
api/index.md
develop/index.md
```
Expand Down
2 changes: 2 additions & 0 deletions docs/sphinx/index.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
(myst-sphinx)=

# MyST with Sphinx

The MyST Parser comes bundled with a Sphinx extension that allows you to use write Sphinx documentation entirely in MyST (or, in a combination of rST and MyST).
Expand Down
14 changes: 14 additions & 0 deletions docs/sphinx/use.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@ To include rST, we must first "wrap" the directive in the [eval-rst directive](s
.. include:: snippets/include-rst.rst
```

(howto/include-md)=
## Include Markdown files into an rST file

To include a MyST file within a ReStructuredText file, we can use the `parser` option of the `include` directive:

```rst
.. include:: include.md
:parser: myst_parser.sphinx_
```

```{important}
The `parser` option requires `docutils>=0.17`
```

## Use MyST in Jupyter Notebooks

The [MyST-NB](https://myst-nb.readthedocs.io) tool provides a Sphinx extension for parsing **Jupyter Notebooks written with MyST Markdown**. It includes features like automatically executing notebooks during documentation builds, storing notebook cell outputs in order to insert them elsewhere in your documentation, and more. See the [MyST-NB documentation](https://myst-nb.readthedocs.io) for more information.
Expand Down
Loading