├── .DS_Store ├── .gitignore ├── .idea ├── .gitignore ├── easypoi.iml ├── inspectionProfiles │ ├── Project_Default.xml │ └── profiles_settings.xml ├── misc.xml ├── modules.xml └── vcs.xml ├── README.md ├── docs ├── .DS_Store ├── Makefile ├── _static │ ├── local.css │ ├── logo-square.svg │ └── logo-wide.svg ├── api │ └── reference.rst ├── conf.py ├── configuration.md ├── develop │ ├── _changelog.md │ ├── architecture.md │ ├── background.md │ ├── contributing.md │ ├── index.md │ └── test_infrastructure.md ├── docutils.md ├── faq │ ├── index.md │ └── snippets │ │ ├── include-md.md │ │ └── include-rst.rst ├── index.md ├── intro.md ├── live-preview.md ├── live_preview.py └── syntax │ ├── example.txt │ ├── img │ └── fun-fish.png │ ├── optional.md │ ├── reference.md │ ├── roles-and-directives.md │ └── syntax.md ├── lumache.py ├── pyproject.toml └── requirements.txt /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soaringsoul/easypoi/b0b09047903d046dfd513ec7a0de533525b343d5/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | build/ 7 | dist/ 8 | venv/ 9 | 10 | *.pyc 11 | # C extensions 12 | *.exe 13 | *.so 14 | *.ui 15 | *.e4p 16 | *.qrc 17 | *.ipynb 18 | # Distribution / packaging 19 | .Python 20 | easy_location/ 21 | windows_exe/ 22 | build/ 23 | develop-eggs/ 24 | dist/ 25 | downloads/ 26 | eggs/ 27 | .eggs/ 28 | lib/ 29 | lib64/ 30 | parts/ 31 | sdist/ 32 | var/ 33 | wheels/ 34 | share/python-wheels/ 35 | *.egg-info/ 36 | .installed.cfg 37 | *.egg 38 | MANIFEST 39 | 40 | # PyInstaller 41 | # Usually these files are written by a python script from a template 42 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 43 | *.manifest 44 | 45 | 46 | # Installer logs 47 | pip-log.txt 48 | pip-delete-this-directory.txt 49 | 50 | # Unit test / coverage reports 51 | htmlcov/ 52 | .tox/ 53 | .nox/ 54 | .coverage 55 | .coverage.* 56 | .cache 57 | nosetests.xml 58 | coverage.xml 59 | *.cover 60 | .hypothesis/ 61 | .pytest_cache/ 62 | 63 | # Translations 64 | *.mo 65 | *.pot 66 | 67 | # Django stuff: 68 | *.log 69 | local_settings.py 70 | db.sqlite3 71 | 72 | # Flask stuff: 73 | instance/ 74 | .webassets-cache 75 | 76 | # Scrapy stuff: 77 | .scrapy 78 | 79 | # Sphinx documentation 80 | docs/_build/ 81 | 82 | # PyBuilder 83 | target/ 84 | 85 | # Jupyter Notebook 86 | .ipynb_checkpoints 87 | 88 | # IPython 89 | profile_default/ 90 | ipython_config.py 91 | 92 | # pyenv 93 | .python-version 94 | 95 | # celery beat schedule file 96 | celerybeat-schedule 97 | 98 | # SageMath parsed files 99 | *.sage.py 100 | 101 | # Environments 102 | .env 103 | .venv 104 | env/ 105 | venv/ 106 | ENV/ 107 | env.bak/ 108 | venv.bak/ 109 | 110 | # Spyder project settings 111 | .spyderproject 112 | .spyproject 113 | 114 | # Rope project settings 115 | .ropeproject 116 | 117 | # mkdocs documentation 118 | /site 119 | 120 | # mypy 121 | .mypy_cache/ 122 | .dmypy.json 123 | dmypy.json 124 | 125 | # Pyre type checker 126 | .pyre/ 127 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/easypoi.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 34 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 原理 2 | 3 | 知乎:[获取中国指定行政区域内所有POIS(兴趣点)的方法](https://zhuanlan.zhihu.com/p/48081408) 4 | 5 | # 核心功能 6 | 7 | 1 获取中国境内指定行政区域内(最小可精确到街道)的指定关键词的所有兴趣点; 例如可以获取一个城市内所有的便利店、商场、超市、咖啡店、大学等地理位置信息,包括经纬度、所在的省、市、区县、街道等等。 8 | 9 | 2 获取指定地点(地址或经纬度坐标)方圆N公里以内指定关键词的所有兴趣点。 10 | 11 | 3 可组合批量获取中国境内多个行政区域内多个关键词的所有兴趣点信息。例如你可以同时获取成都市、西安市、上海市三个指定的城市里所有超市、商场和大学的数据。 12 | 13 | # 下载地址 14 | 15 | > https://www.yuque.com/soaringsoul/geotools 16 | 17 | 如果发现下载地址失效,请在微信搜索人文互联网 公众号,关注后回复"poi"获取最新的下载链接; 18 | 19 | # 如何运行 20 | 21 | 非常简单,所见即所得,不做过多说明。 22 | 23 |
24 | 25 | # **采集结果示例** 26 | 27 | * csv 28 | 29 | ![result\_csv](https://pic3.zhimg.com/80/v2-f5f25aa2ad2c7fe1fd20f89069921aee\_720w.jpg) 30 | 31 | * excel 32 | 33 | ![result\_excel](https://pic3.zhimg.com/80/v2-03befe01d1f890ac48f12b42f513e13e\_720w.jpg) 34 | 35 | * mysql 36 | 37 | ![result\_excel](https://pic3.zhimg.com/80/v2-aacdf72a7f5611ef8bf8e9b45db6ff66\_720w.jpg) 38 | 39 | ### 联系我 40 | 41 | 如果在使用过程中遇到无法解决的问题,你可以通过关注我的个人公众号找到我。 42 | 43 | 另外,也可以通过提交issue的方式提交问题。 44 | 45 |
46 | 47 | # License 48 | 49 | [Apache 2.0 License](https://www.apache.org/licenses/LICENSE-2.0.html). 50 | -------------------------------------------------------------------------------- /docs/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soaringsoul/easypoi/b0b09047903d046dfd513ec7a0de533525b343d5/docs/.DS_Store -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | 22 | # raise warnings to errors 23 | html-strict: 24 | @$(SPHINXBUILD) -b html -nW --keep-going "$(SOURCEDIR)" "$(BUILDDIR)/html" $(SPHINXOPTS) $(O) 25 | 26 | clean: 27 | rm -r $(BUILDDIR) 28 | -------------------------------------------------------------------------------- /docs/_static/local.css: -------------------------------------------------------------------------------- 1 | /** Add a counter before subsections **/ 2 | h1:not(.tippy-header) { 3 | counter-reset: subsection; 4 | text-decoration: underline; 5 | } 6 | h2:not(.tippy-header) { 7 | counter-reset: subsubsection; 8 | } 9 | h2:not(.tippy-header)::before { 10 | counter-increment: subsection; 11 | content: counter(subsection) ". "; 12 | } 13 | h3:not(.tippy-header)::before { 14 | counter-increment: subsubsection; 15 | content: counter(subsection) "." counter(subsubsection) ". "; 16 | } 17 | 18 | /** No icon for admonitions with no-icon class */ 19 | .admonition > .admonition-title, div.admonition.no-icon > .admonition-title::before { 20 | content: ""; 21 | } 22 | .admonition > .admonition-title, div.admonition.no-icon > .admonition-title { 23 | padding-left: .6rem; 24 | } 25 | 26 | /* Live preview page */ 27 | iframe.pyscript, textarea.pyscript { 28 | width: 100%; 29 | height: 400px; 30 | } 31 | iframe.pyscript { 32 | padding: 4px; 33 | } 34 | textarea.pyscript { 35 | padding: 30px 20px 20px; 36 | border-radius: 8px; 37 | resize: vertical; 38 | font-size: 16px; 39 | font-family: monospace; 40 | } 41 | .display-flex { 42 | display: flex; 43 | } 44 | .display-inline-block { 45 | display: inline-block; 46 | margin-right: 1rem; 47 | margin-bottom: 0; 48 | } 49 | span.label { 50 | /* pyscript changes this and it messes up footnote labels */ 51 | all: unset; 52 | } 53 | 54 | .tippy-box { 55 | background-color:var(--pst-color-surface); 56 | color:var(--pst-color-text-base); 57 | border: 1px solid var(--pst-color-border); 58 | } 59 | -------------------------------------------------------------------------------- /docs/_static/logo-square.svg: -------------------------------------------------------------------------------- 1 | Artboard 4 2 | -------------------------------------------------------------------------------- /docs/_static/logo-wide.svg: -------------------------------------------------------------------------------- 1 | Artboard 1 2 | -------------------------------------------------------------------------------- /docs/api/reference.rst: -------------------------------------------------------------------------------- 1 | .. _api/main: 2 | 3 | ========== 4 | Python API 5 | ========== 6 | 7 | Source text parsers 8 | ------------------- 9 | 10 | .. _api/docutils_parser: 11 | 12 | Docutils 13 | ........ 14 | 15 | .. autoclass:: myst_parser.docutils_.Parser 16 | :members: parse 17 | :undoc-members: 18 | :member-order: bysource 19 | :show-inheritance: 20 | 21 | .. _api/sphinx_parser: 22 | 23 | Sphinx 24 | ...... 25 | 26 | .. autoclass:: myst_parser.parsers.sphinx_.MystParser 27 | :members: supported, parse 28 | :undoc-members: 29 | :member-order: bysource 30 | :show-inheritance: 31 | :exclude-members: __init__ 32 | 33 | .. _api/renderers: 34 | 35 | Markdown-it to docutils 36 | ----------------------- 37 | 38 | These renderers take the markdown-it parsed token stream and convert it to 39 | the docutils AST. The sphinx renderer is a subclass of the docutils one, 40 | with some additional methods only available *via* sphinx e.g. multi-document cross-referencing. 41 | 42 | 43 | Docutils 44 | ........ 45 | 46 | .. autoclass:: myst_parser.mdit_to_docutils.base.DocutilsRenderer 47 | :special-members: __output__, __init__ 48 | :members: render, nested_render_text, add_line_and_source_path, current_node_context 49 | :undoc-members: 50 | :member-order: bysource 51 | :show-inheritance: 52 | 53 | 54 | Sphinx 55 | ...... 56 | 57 | .. autoclass:: myst_parser.mdit_to_docutils.sphinx_.SphinxRenderer 58 | :special-members: __output__ 59 | :members: render_internal_link, render_math_block_label 60 | :undoc-members: 61 | :member-order: alphabetical 62 | :show-inheritance: 63 | 64 | .. _api/directive: 65 | 66 | Directive and role processing 67 | ----------------------------- 68 | 69 | This module processes the content of a directive: 70 | 71 | .. automodule:: myst_parser.parsers.directives 72 | :members: 73 | 74 | These classes are parsed to sphinx roles and directives, 75 | to mimic the original docutls rST specific parser elements, 76 | but instead run nested parsing with the markdown parser. 77 | 78 | .. autoclass:: myst_parser.mocking.MockInliner 79 | :members: 80 | :undoc-members: 81 | :show-inheritance: 82 | 83 | .. autoclass:: myst_parser.mocking.MockState 84 | :members: 85 | :undoc-members: 86 | :show-inheritance: 87 | 88 | .. autoclass:: myst_parser.mocking.MockStateMachine 89 | :members: 90 | :undoc-members: 91 | :show-inheritance: 92 | 93 | .. autoclass:: myst_parser.mocking.MockIncludeDirective 94 | :members: 95 | :undoc-members: 96 | :show-inheritance: 97 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 6 | 7 | from datetime import date 8 | 9 | from sphinx.application import Sphinx 10 | from sphinx.transforms.post_transforms import SphinxPostTransform 11 | 12 | from myst_parser import __version__ 13 | 14 | # -- Project information ----------------------------------------------------- 15 | 16 | project = "MyST Parser" 17 | copyright = f"{date.today().year}, Executable Book Project" 18 | author = "Executable Book Project" 19 | version = __version__ 20 | 21 | master_doc = "index" 22 | language = "en" 23 | 24 | # -- General configuration --------------------------------------------------- 25 | 26 | # Add any Sphinx extension module names here, as strings. They can be 27 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 28 | # ones. 29 | extensions = [ 30 | "myst_parser", 31 | "sphinx.ext.autodoc", 32 | "sphinx.ext.intersphinx", 33 | "sphinx.ext.viewcode", 34 | "sphinx_design", 35 | 36 | "sphinxcontrib.mermaid", 37 | 38 | "sphinx_pyscript", 39 | "sphinx_tippy", 40 | ] 41 | 42 | # Add any paths that contain templates here, relative to this directory. 43 | templates_path = ["_templates"] 44 | 45 | # List of patterns, relative to source directory, that match files and 46 | # directories to ignore when looking for source files. 47 | # This pattern also affects html_static_path and html_extra_path. 48 | exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] 49 | 50 | suppress_warnings = ["myst.strikethrough"] 51 | 52 | intersphinx_mapping = { 53 | "python": ("https://docs.python.org/3.7", None), 54 | "sphinx": ("https://www.sphinx-doc.org/en/master", None), 55 | "markdown_it": ("https://markdown-it-py.readthedocs.io/en/latest", None), 56 | } 57 | 58 | # -- Autodoc settings --------------------------------------------------- 59 | 60 | autodoc_member_order = "bysource" 61 | nitpicky = True 62 | nitpick_ignore = [ 63 | ("py:class", "docutils.nodes.document"), 64 | ("py:class", "docutils.nodes.docinfo"), 65 | ("py:class", "docutils.nodes.Element"), 66 | ("py:class", "docutils.nodes.Node"), 67 | ("py:class", "docutils.nodes.field_list"), 68 | ("py:class", "docutils.nodes.problematic"), 69 | ("py:class", "docutils.nodes.pending"), 70 | ("py:class", "docutils.nodes.system_message"), 71 | ("py:class", "docutils.statemachine.StringList"), 72 | ("py:class", "docutils.parsers.rst.directives.misc.Include"), 73 | ("py:class", "docutils.parsers.rst.Parser"), 74 | ("py:class", "docutils.utils.Reporter"), 75 | ("py:class", "nodes.Element"), 76 | ("py:class", "nodes.Node"), 77 | ("py:class", "nodes.system_message"), 78 | ("py:class", "Directive"), 79 | ("py:class", "Include"), 80 | ("py:class", "StringList"), 81 | ("py:class", "DocutilsRenderer"), 82 | ("py:class", "MockStateMachine"), 83 | ("py:exc", "MarkupError"), 84 | ] 85 | 86 | # -- MyST settings --------------------------------------------------- 87 | 88 | myst_enable_extensions = [ 89 | "dollarmath", 90 | "amsmath", 91 | "deflist", 92 | "fieldlist", 93 | "html_admonition", 94 | "html_image", 95 | "colon_fence", 96 | "smartquotes", 97 | "replacements", 98 | "linkify", 99 | "strikethrough", 100 | "substitution", 101 | "tasklist", 102 | "attrs_inline", 103 | "inv_link", 104 | ] 105 | myst_number_code_blocks = ["typescript"] 106 | myst_heading_anchors = 2 107 | myst_footnote_transition = True 108 | myst_dmath_double_inline = True 109 | myst_enable_checkboxes = True 110 | 111 | # -- HTML output ------------------------------------------------- 112 | 113 | html_theme = "sphinx_book_theme" 114 | html_logo = "_static/logo-wide.svg" 115 | html_favicon = "_static/logo-square.svg" 116 | html_title = "" 117 | html_theme_options = { 118 | "home_page_in_toc": True, 119 | "github_url": "https://github.com/executablebooks/MyST-Parser", 120 | "repository_url": "https://github.com/executablebooks/MyST-Parser", 121 | "repository_branch": "master", 122 | "path_to_docs": "docs", 123 | "use_repository_button": True, 124 | "use_edit_page_button": True, 125 | } 126 | # OpenGraph metadata 127 | ogp_site_url = "https://myst-parser.readthedocs.io/en/latest" 128 | # This is the image that GitHub stores for our social media previews 129 | ogp_image = "https://repository-images.githubusercontent.com/240151150/316bc480-cc23-11eb-96fc-4ab2f981a65d" # noqa: E501 130 | ogp_custom_meta_tags = [ 131 | '', 132 | ] 133 | 134 | # Add any paths that contain custom static files (such as style sheets) here, 135 | # relative to this directory. They are copied after the builtin static files, 136 | # so a file named "default.css" will overwrite the builtin "default.css". 137 | html_static_path = ["_static"] 138 | html_css_files = ["local.css"] 139 | 140 | rediraffe_redirects = { 141 | "using/intro.md": "sphinx/intro.md", 142 | "sphinx/intro.md": "intro.md", 143 | "using/use_api.md": "api/index.md", 144 | "api/index.md": "api/reference.rst", 145 | "using/syntax.md": "syntax/syntax.md", 146 | "using/syntax-optional.md": "syntax/optional.md", 147 | "using/reference.md": "syntax/reference.md", 148 | "sphinx/reference.md": "configuration.md", 149 | "sphinx/index.md": "faq/index.md", 150 | "sphinx/use.md": "faq/index.md", 151 | "sphinx/faq.md": "faq/index.md", 152 | "explain/index.md": "develop/background.md", 153 | } 154 | 155 | tippy_skip_anchor_classes = ("headerlink", "sd-stretched-link", "sd-rounded-pill") 156 | tippy_anchor_parent_selector = "article.bd-article" 157 | tippy_rtd_urls = [ 158 | "https://www.sphinx-doc.org/en/master", 159 | "https://markdown-it-py.readthedocs.io/en/latest", 160 | ] 161 | 162 | # -- LaTeX output ------------------------------------------------- 163 | 164 | latex_engine = "xelatex" 165 | 166 | # -- Local Sphinx extensions ------------------------------------------------- 167 | 168 | 169 | class StripUnsupportedLatex(SphinxPostTransform): 170 | """Remove unsupported nodes from the doctree.""" 171 | 172 | default_priority = 900 173 | 174 | def run(self): 175 | if self.app.builder.format != "latex": 176 | return 177 | from docutils import nodes 178 | 179 | for node in self.document.findall(): 180 | if node.tagname == "image" and node["uri"].endswith(".svg"): 181 | node.parent.replace(node, nodes.inline("", "Removed SVG image")) 182 | if node.tagname == "mermaid": 183 | node.parent.replace(node, nodes.inline("", "Removed Mermaid diagram")) 184 | 185 | 186 | def setup(app: Sphinx): 187 | """Add functions to the Sphinx setup.""" 188 | from myst_parser._docs import ( 189 | DirectiveDoc, 190 | DocutilsCliHelpDirective, 191 | MystConfigDirective, 192 | MystWarningsDirective, 193 | ) 194 | 195 | app.add_directive("myst-config", MystConfigDirective) 196 | app.add_directive("docutils-cli-help", DocutilsCliHelpDirective) 197 | app.add_directive("doc-directive", DirectiveDoc) 198 | app.add_directive("myst-warnings", MystWarningsDirective) 199 | app.add_post_transform(StripUnsupportedLatex) 200 | app.connect("html-page-context", add_version_to_css) 201 | 202 | 203 | def add_version_to_css(app, pagename, templatename, context, doctree): 204 | """Add the version number to the local.css file, to bust the cache for changes.""" 205 | if app.builder.name != "html": 206 | return 207 | if "_static/local.css" in context.get("css_files", {}): 208 | index = context["css_files"].index("_static/local.css") 209 | context["css_files"][index] = f"_static/local.css?v={__version__}" 210 | -------------------------------------------------------------------------------- /docs/configuration.md: -------------------------------------------------------------------------------- 1 | (sphinx/config-options)= 2 | # Configuration 3 | 4 | MyST parsing can be configured at both the global and individual document level, 5 | with the most specific configuration taking precedence. 6 | 7 | ## Global configuration 8 | 9 | Overriding the default configuration at the global level is achieved by specifying variables in the Sphinx `conf.py` file. 10 | All `myst_parser` global configuration variables are prefixed with `myst_`, e.g. 11 | 12 | ```python 13 | myst_enable_extensions = ["deflist"] 14 | ``` 15 | 16 | :::{seealso} 17 | Configuration in Docutils, in the [](docutils.md) section. 18 | ::: 19 | 20 | ```{myst-config} 21 | :sphinx: 22 | :scope: global 23 | ``` 24 | 25 | ### Extensions 26 | 27 | Configuration specific to syntax extensions: 28 | 29 | ```{myst-config} 30 | :sphinx: 31 | :extensions: 32 | :scope: global 33 | ``` 34 | 35 | ## Local configuration 36 | 37 | ```{versionadded} 0.18 38 | ``` 39 | 40 | The following configuration variables are available at the document level. 41 | These can be set in the document [front matter](syntax/frontmatter), under the `myst` key, e.g. 42 | 43 | ```yaml 44 | --- 45 | myst: 46 | enable_extensions: ["deflist"] 47 | --- 48 | ``` 49 | 50 | ```{myst-config} 51 | :sphinx: 52 | :scope: local 53 | ``` 54 | 55 | ### Extensions 56 | 57 | Configuration specific to syntax extensions: 58 | 59 | ```{myst-config} 60 | :sphinx: 61 | :extensions: 62 | :scope: local 63 | ``` 64 | 65 | ## List of syntax extensions 66 | 67 | Full details in the [](syntax/extensions) section. 68 | 69 | amsmath 70 | : enable direct parsing of [amsmath](https://ctan.org/pkg/amsmath) LaTeX equations 71 | 72 | attrs_inline 73 | : Enable inline attribute parsing, [see here](syntax/attributes) for details 74 | 75 | colon_fence 76 | : Enable code fences using `:::` delimiters, [see here](syntax/colon_fence) for details 77 | 78 | deflist 79 | : Enable definition lists, [see here](syntax/definition-lists) for details 80 | 81 | dollarmath 82 | : Enable parsing of dollar `$` and `$$` encapsulated math 83 | 84 | fieldlist 85 | : Enable field lists, [see here](syntax/fieldlists) for details 86 | 87 | html_admonition 88 | : Convert `
` elements to sphinx admonition nodes, see the [HTML admonition syntax](syntax/html-admonition) for details 89 | 90 | html_image 91 | : Convert HTML `` elements to sphinx image nodes, [see here](syntax/images) for details 92 | 93 | inv_link 94 | : Enable the `inv:` schema for Markdown link destinations, [see here](syntax/inv_links) for details 95 | 96 | linkify 97 | : Automatically identify "bare" web URLs and add hyperlinks 98 | 99 | replacements 100 | : Automatically convert some common typographic texts 101 | 102 | smartquotes 103 | : Automatically convert standard quotations to their opening/closing variants 104 | 105 | strikethrough 106 | : Enable strikethrough syntax, [see here](syntax/strikethrough) for details 107 | 108 | substitution 109 | : Substitute keys, [see here](syntax/substitutions) for details 110 | 111 | tasklist 112 | : Add check-boxes to the start of list items, [see here](syntax/tasklists) for details 113 | 114 | (howto/warnings)= 115 | (myst-warnings)= 116 | ## Build Warnings 117 | 118 | Below lists the MyST specific warnings that may be emitted during the build process. These will be prepended to the end of the warning message, e.g. 119 | 120 | ``` 121 | WARNING: Non-consecutive header level increase; H1 to H3 [myst.header] 122 | ``` 123 | 124 | **In general, if your build logs any warnings, you should either fix them or [raise an Issue](https://github.com/executablebooks/MyST-Parser/issues/new/choose) if you think the warning is erroneous.** 125 | 126 | However, in some circumstances if you wish to suppress the warning you can use the configuration option, e.g. 127 | 128 | ```python 129 | suppress_warnings = ["myst.header"] 130 | ``` 131 | 132 | Or use `--myst-suppress-warnings="myst.header"` for the [docutils CLI](myst-docutils). 133 | 134 | ```{myst-warnings} 135 | ``` 136 | -------------------------------------------------------------------------------- /docs/develop/_changelog.md: -------------------------------------------------------------------------------- 1 | ```{include} ../../CHANGELOG.md 2 | :relative-docs: docs/ 3 | :relative-images: 4 | ``` 5 | -------------------------------------------------------------------------------- /docs/develop/architecture.md: -------------------------------------------------------------------------------- 1 | # The MyST implementation architecture 2 | 3 | This page describes implementation details to help you understand the structure 4 | of the project. 5 | 6 | ## A Renderer for markdown-it tokens 7 | 8 | At a high level, the MyST parser is an extension of th project. Markdown-It-Py 9 | is a well-structured Python parser for CommonMark text. It also defines an extension 10 | point to include more syntax in parsed files. The MyST parser uses this extension 11 | point to define its own syntax options (e.g., for Sphinx roles and directives). 12 | 13 | The result of this parser is a markdown-it token stream. 14 | 15 | ## A docutils renderer 16 | 17 | The MyST parser also defines a docutils renderer for the markdown-it token stream. 18 | This allows us to convert parsed elements of a MyST markdown file into docutils. 19 | 20 | ## A Sphinx parser 21 | 22 | Finally, the MyST parser provides a parser for Sphinx, the documentation generation 23 | system. This parser does the following: 24 | 25 | * Parse markdown files with the markdown-it parser, including MyST specific plugins 26 | * Convert these files into docutils objects using the MyST docutils renderer 27 | * Provide these to Sphinx in order to use in building your site. 28 | -------------------------------------------------------------------------------- /docs/develop/background.md: -------------------------------------------------------------------------------- 1 | # Background 2 | 3 | These sections discuss high-level questions about the MyST ecosystem, and explain a few decisions made in the project. 4 | 5 | ## Why did we create MyST markdown? 6 | 7 | While markdown is ubiquitous, it is not powerful enough for writing modern, 8 | fully-featured documentation. Some flavors of markdown support features needed for this, 9 | but there is no community standard around various syntactic choices for these features. 10 | 11 | Sphinx is a documentation generation framework written in Python. It heavily-utilizes 12 | reStructuredText syntax, which is another markup language for writing documents. In 13 | particular, Sphinx defines two extension points that are extremely useful: 14 | **{ref}`in-line roles`** and **{ref}`block-level directives `**. 15 | 16 | **This project is an attempt at combining the simplicity and readability of Markdown 17 | with the power and flexibility of reStructuredText and the Sphinx platform.** It 18 | starts with the [CommonMark markdown specification][commonmark], and selectively adds a few extra 19 | syntax pieces to utilize the most powerful parts of reStructuredText. 20 | 21 | ```{note} 22 | The CommonMark community has been discussing an "official" extension syntax for many 23 | years now (for example, see 24 | [this seven-year-old thread about directives](https://talk.commonmark.org/t/generic-directives-plugins-syntax/444) as well as 25 | [this more recent converstaion](https://talk.commonmark.org/t/support-for-extension-token/2771), 26 | and [this comment listing several more threads on this topic](https://talk.commonmark.org/t/extension-terminology-and-rules/1233)). 27 | 28 | We have chosen a "roles and directives" syntax that seems reasonable and follows other 29 | common conventions in Markdown flavors. However, if the CommonMark community ever 30 | decides on an "official" extension syntax, we will likely utilize this syntax for 31 | MyST. 32 | ``` 33 | 34 | ## The relationship between MyST, reStructuredText, and Sphinx 35 | 36 | MyST markdown provides a markdown equivalent of the reStructuredText syntax, 37 | meaning that you can do anything in MyST that you can do with reStructuredText. 38 | 39 | The Sphinx documentation engine supports a number of different input types. By default, 40 | Sphinx reads **reStructuredText** (`.rst`) files. Sphinx uses a **parser** to parse input files 41 | into its own internal document model (which is provided by a core Python project, 42 | [docutils](https://docutils.sourceforge.io/)). 43 | 44 | Developers can *extend Sphinx* to support other kinds of input files. Any content file 45 | can be read into the Sphinx document structure, provided that somebody writes a 46 | **parser** for that file. Once a content file has been parsed into Sphinx, it behaves 47 | nearly the same way as any other content file, regardless of the language in which it 48 | was written. 49 | 50 | The MyST-parser is a Sphinx parser for the MyST markdown language. 51 | When you use it, Sphinx will know how to parse content files that contain MyST markdown (by default, Sphinx will assume any files ending in `.md` are written in MyST markdown). Once a document has been parsed into Sphinx, it behaves the same way regardless of whether it has been written in rST or MyST markdown. 52 | 53 | ``` 54 | myst markdown (.md) ------> myst parser ---+ 55 | | 56 | +-->Sphinx document (docutils) 57 | | 58 | reStructuredText (.rst) --> rst parser ----+ 59 | ``` 60 | 61 | For example, here's how you'd write a `toctree` directive in MyST markdown: 62 | 63 | ```` 64 | ```{toctree} 65 | My page name 66 | page2 67 | ``` 68 | ```` 69 | 70 | and here's the same in rST: 71 | 72 | ``` 73 | .. toctree:: 74 | 75 | My page name 76 | page2 77 | ``` 78 | 79 | They will both behave the same in Sphinx. 80 | 81 | 82 | [commonmark]: https://commonmark.org/ 83 | -------------------------------------------------------------------------------- /docs/develop/contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | [![Github-CI][github-ci]][github-link] 4 | [![Coverage Status][codecov-badge]][codecov-link] 5 | [![Documentation Status][rtd-badge]][rtd-link] 6 | [![Code style: black][black-badge]][black-link] 7 | 8 | We welcome all contributions! 9 | See the [EBP Contributing Guide](https://executablebooks.org/en/latest/contributing.html) for general details, and below for guidance specific to MyST-Parser. 10 | 11 | ## Install for development 12 | 13 | To install `myst-parser` for development, take the following steps: 14 | 15 | ```bash 16 | git clone https://github.com/executablebooks/MyST-Parser 17 | cd MyST-Parser 18 | git checkout master 19 | pip install -e .[code_style,testing,rtd] 20 | ``` 21 | 22 | ## Code Style 23 | 24 | Code style is tested using [flake8](http://flake8.pycqa.org), 25 | with the configuration set in `.flake8`, 26 | and code formatted with [black](https://github.com/ambv/black). 27 | 28 | Installing with `myst-parser[code_style]` makes the [pre-commit](https://pre-commit.com/) 29 | package available, which will ensure this style is met before commits are submitted, by reformatting the code 30 | and testing for lint errors. 31 | It can be setup by: 32 | 33 | ```shell 34 | >> cd MyST-Parser 35 | >> pre-commit install 36 | ``` 37 | 38 | Optionally you can run `black` and `flake8` separately: 39 | 40 | ```shell 41 | >> black . 42 | >> flake8 . 43 | ``` 44 | 45 | Editors like VS Code also have automatic code reformat utilities, which can adhere to this standard. 46 | 47 | All functions and class methods should be annotated with types and include a docstring. The preferred docstring format is outlined in `MyST-Parser/docstring.fmt.mustache` and can be used automatically with the 48 | [autodocstring](https://marketplace.visualstudio.com/items?itemName=njpwerner.autodocstring) VS Code extension. 49 | 50 | ## Testing 51 | 52 | For code tests, myst-parser uses [pytest](https://docs.pytest.org): 53 | 54 | ```shell 55 | >> cd MyST-Parser 56 | >> pytest 57 | ``` 58 | 59 | You can also use [tox](https://tox.readthedocs.io), to run the tests in multiple isolated environments (see the `tox.ini` file for available test environments): 60 | 61 | ```shell 62 | >> cd MyST-Parser 63 | >> tox 64 | ``` 65 | 66 | For documentation build tests: 67 | 68 | ```shell 69 | >> cd MyST-Parser/docs 70 | >> make clean 71 | >> make html-strict 72 | ``` 73 | 74 | ```{seealso} 75 | {ref}`develop/testing` 76 | ``` 77 | 78 | [github-ci]: https://github.com/executablebooks/MyST-Parser/workflows/continuous-integration/badge.svg?branch=master 79 | [github-link]: https://github.com/executablebooks/MyST-Parser 80 | [codecov-badge]: https://codecov.io/gh/executablebooks/MyST-Parser/branch/master/graph/badge.svg 81 | [codecov-link]: https://codecov.io/gh/executablebooks/MyST-Parser 82 | [rtd-badge]: https://readthedocs.org/projects/myst-parser/badge/?version=latest 83 | [rtd-link]: https://myst-parser.readthedocs.io/en/latest/?badge=latest 84 | [black-badge]: https://img.shields.io/badge/code%20style-black-000000.svg 85 | [black-link]: https://github.com/ambv/black 86 | -------------------------------------------------------------------------------- /docs/develop/index.md: -------------------------------------------------------------------------------- 1 | # Contribute 2 | 3 | This section covers documentation relevant to developing and maintaining the MyST 4 | codebase, and some guidelines for how you can contribute. 5 | 6 | ```{toctree} 7 | contributing.md 8 | architecture.md 9 | test_infrastructure.md 10 | ``` 11 | 12 | ## Code of Conduct 13 | 14 | The MyST-parser project follows the 15 | [Executable Book Project code of conduct](https://github.com/executablebooks/.github/blob/master/CODE_OF_CONDUCT.md). 16 | -------------------------------------------------------------------------------- /docs/develop/test_infrastructure.md: -------------------------------------------------------------------------------- 1 | (develop/testing)= 2 | 3 | # Testing Infrastructure 4 | 5 | Where possible, additions to the code should be carried out in a 6 | [test-driven development](https://en.wikipedia.org/wiki/Test-driven_development) 7 | manner: 8 | 9 | > **Write failing tests that the code should pass, then write code to pass the tests**. 10 | 11 | The tests are run using [pytest](https://docs.pytest.org)/[GitHub Actions](https://github.com/features/actions) for unit tests, and [readthedocs](https://readthedocs.org/) for documentation build tests. 12 | 13 | The tests are ordered in a hierarchical fashion: 14 | 15 | 1. In `tests/test_commonmark` the [CommonMark](https://github.com/commonmark/CommonMark.git) test set is run to check that the parser is complying with the CommonMark specification. 16 | 2. In `tests/test_renderers` are tests that check that the Markdown AST is being correctly converted to the docutils/sphinx AST. This includes testing that roles and directives are correctly parsed and run. 17 | 3. In `tests/test_sphinx` are tests that check that minimal sphinx project builds are running correctly, to convert MyST markdown files to HTML. 18 | 4. In `.circleci` the package documentation (written in MyST format) is built and tested for build errors/warnings. 19 | 20 | ## Test tools 21 | 22 | [**pytest-regressions**](https://pytest-regressions.readthedocs.io) is a pytest plugin 23 | that is used in the test suite, to maintain tests that generate lots of data. 24 | In particular, they are used in the syntax testing to generate tests for AST trees 25 | which may change in the future due to changes/additions to the data captured by the parser. 26 | For example, after writing: 27 | 28 | ```python 29 | def test_example_dict(data_regression): 30 | data_regression.check({ 31 | "key1": "value1", 32 | "key2": "value2", 33 | "more": "data...", 34 | }) 35 | def test_example_str(file_regression): 36 | file_regression.check("a very long string...") 37 | ``` 38 | 39 | Running the following will initially fail, 40 | but will also generate a file (per test) of expected output: 41 | 42 | ```console 43 | $ pytest -k test_example 44 | ``` 45 | 46 | Subsequent times the tests are run, the tests output will now be validated against these stored files. 47 | 48 | After a change to the syntax parser, all failing tests can then be 'regenerated' with the new 49 | expected output, by running: 50 | 51 | ```console 52 | $ pytest --force-regen 53 | ``` 54 | -------------------------------------------------------------------------------- /docs/docutils.md: -------------------------------------------------------------------------------- 1 | (myst-docutils)= 2 | 3 | # Single Page Builds 4 | 5 | ```{versionadded} 0.16.0 6 | ``` 7 | 8 | Sphinx, and thus MyST-Parser, is built on top of the [Docutils](https://docutils.sourceforge.io/docs/) package. 9 | MyST-Parser offers a renderer, parser and CLI-interface for working directly with Docutils, independent of Sphinx, as described below. 10 | 11 | :::{note} 12 | Since these tools are independent of Sphinx, this means they cannot parse any Sphinx or Sphinx extensions specific roles or directives. 13 | ::: 14 | 15 | On installing MyST-Parser, the following CLI-commands are made available: 16 | 17 | - `myst-docutils-html`: converts MyST to HTML 18 | - `myst-docutils-html5`: converts MyST to HTML5 19 | - `myst-docutils-latex`: converts MyST to LaTeX 20 | - `myst-docutils-xml`: converts MyST to docutils-native XML 21 | - `myst-docutils-pseudoxml`: converts MyST to pseudo-XML (to visualise the AST structure) 22 | 23 | Each command can be piped stdin or take a file path as an argument: 24 | 25 | ```console 26 | $ myst-docutils-html --help 27 | $ echo "Hello World" | myst-docutils-html 28 | $ myst-docutils-html hello-world.md 29 | ``` 30 | 31 | 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). 32 | 33 | :::{dropdown} Shared Docutils CLI Options 34 | ```{docutils-cli-help} 35 | ``` 36 | ::: 37 | 38 | :::{versionadded} 0.19.0 39 | `myst-suppress-warnings` replicates the functionality of sphinx's for `myst.` warnings in the `docutils` CLI. 40 | ::: 41 | 42 | 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: 43 | 44 | ``` 45 | # These entries affect all processing: 46 | [general] 47 | myst-enable-extensions: deflist,linkify 48 | myst-footnote-transition: no 49 | myst-substitutions: 50 | key1: value1 51 | key2: value2 52 | 53 | # These entries affect specific HTML output: 54 | [html writers] 55 | embed-stylesheet: no 56 | 57 | [html5 writer] 58 | stylesheet-dirs: path/to/html5_polyglot/ 59 | stylesheet-path: minimal.css, responsive.css 60 | ``` 61 | 62 | 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): 63 | 64 | ```python 65 | from docutils.core import publish_string 66 | from myst_parser.docutils_ import Parser 67 | 68 | source = "hallo world\n: Definition" 69 | output = publish_string( 70 | source=source, 71 | writer_name="html5", 72 | settings_overrides={ 73 | "myst_enable_extensions": ["deflist"], 74 | "embed_stylesheet": False, 75 | }, 76 | parser=Parser(), 77 | ) 78 | ``` 79 | 80 | 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): 81 | 82 | ```rst 83 | .. include:: include.md 84 | :parser: myst_parser.docutils_ 85 | ``` 86 | 87 | ```{important} 88 | The `parser` option requires `docutils>=0.17` 89 | ``` 90 | -------------------------------------------------------------------------------- /docs/faq/index.md: -------------------------------------------------------------------------------- 1 | (myst-sphinx)= 2 | 3 | # FAQ 4 | 5 | ## How-tos 6 | 7 | These sections describe some common scenarios and use-cases for writing MyST with Sphinx. 8 | 9 | (howto/include-rst)= 10 | ### Include rST files into a Markdown file 11 | 12 | As explained in [this section](syntax/directives/parsing), all MyST directives will parse their content as Markdown. 13 | Therefore, using the conventional `include` directive, will parse the file contents as Markdown: 14 | 15 | ````md 16 | ```{include} snippets/include-md.md 17 | ``` 18 | ```` 19 | 20 | ```{include} snippets/include-md.md 21 | ``` 22 | 23 | To include rST, we must first "wrap" the directive in the [eval-rst directive](syntax/directives/parsing): 24 | 25 | ````md 26 | ```{eval-rst} 27 | .. include:: snippets/include-rst.rst 28 | ``` 29 | ```` 30 | 31 | ```{eval-rst} 32 | .. include:: snippets/include-rst.rst 33 | ``` 34 | 35 | (howto/include-md)= 36 | ### Include Markdown files into an rST file 37 | 38 | To include a MyST file within a ReStructuredText file, we can use the `parser` option of the `include` directive: 39 | 40 | ```rst 41 | .. include:: include.md 42 | :parser: myst_parser.sphinx_ 43 | ``` 44 | 45 | ```{important} 46 | The `parser` option requires `docutils>=0.17` 47 | ``` 48 | 49 | ### Use MyST in Jupyter Notebooks 50 | 51 | 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. 52 | 53 | (howto/include-readme)= 54 | ### Include a file from outside the docs folder (like README.md) 55 | 56 | You can include a file, including one from outside the project using e.g.: 57 | 58 | ````md 59 | ```{include} ../README.md 60 | ``` 61 | ```` 62 | 63 | **However**, including a file will not usually resolve local links correctly, like `![](my-image.png)`, since it treats the text as if it originated from the "including file". 64 | 65 | As of myst-parser version 0.12.7, a new, experimental feature has been added to resolve such links. 66 | You can now use for example: 67 | 68 | ````md 69 | Source: 70 | ```{literalinclude} ../../example.md 71 | :language: md 72 | ``` 73 | Included: 74 | ```{include} ../../example.md 75 | :relative-docs: docs/ 76 | :relative-images: 77 | ``` 78 | ```` 79 | 80 | Source: 81 | 82 | ```{literalinclude} ../../example-include.md 83 | :language: md 84 | ``` 85 | 86 | Included: 87 | 88 | ```{include} ../../example-include.md 89 | :relative-docs: docs/ 90 | :relative-images: 91 | ``` 92 | 93 | The include here attempts to re-write local links, to reference them from the correct location! 94 | The `relative-docs` must be given the prefix of any links to re-write, to distinguish them from sphinx cross-references. 95 | 96 | :::{important} 97 | The current functionality only works for Markdown style images and links. 98 | 99 | If you encounter any issues with this feature, please don't hesitate to report it. 100 | ::: 101 | 102 | (howto/autodoc)= 103 | ### Use `sphinx.ext.autodoc` in Markdown files 104 | 105 | The [Sphinx extension `autodoc`](inv:sphinx#sphinx.ext.autodoc), which pulls in code documentation from docstrings, is currently hard-coded to parse reStructuredText. 106 | It is therefore incompatible with MyST's Markdown parser. 107 | However, the special [`eval-rst` directive](syntax/directives/parsing) can be used to "wrap" `autodoc` directives: 108 | 109 | ````md 110 | ```{eval-rst} 111 | .. autoclass:: myst_parser.mocking.MockRSTParser 112 | :show-inheritance: 113 | :members: parse 114 | ``` 115 | ```` 116 | 117 | ```{eval-rst} 118 | .. autoclass:: myst_parser.mocking.MockRSTParser 119 | :show-inheritance: 120 | :members: parse 121 | ``` 122 | 123 | As with other objects in MyST, this can then be referenced: 124 | 125 | - Using the role `` {py:class}`myst_parser.mocking.MockRSTParser` ``: {py:class}`myst_parser.mocking.MockRSTParser` 126 | - Using the Markdown syntax `[MockRSTParser](myst_parser.mocking.MockRSTParser)`: [MockRSTParser](myst_parser.mocking.MockRSTParser) 127 | 128 | ```{warning} 129 | This expects docstrings to be written in reStructuredText. 130 | We hope to support Markdown in the future, see [GitHub issue #228](https://github.com/executablebooks/MyST-Parser/issues/228). 131 | ``` 132 | 133 | (howto/autosectionlabel)= 134 | ### Automatically create targets for section headers 135 | 136 | :::{important} 137 | 138 | New in `v0.13.0` ✨, myst-parser now provides a separate implementation of `autosectionlabel`, which implements GitHub Markdown style bookmark anchors, like `[](file.md#header-anchor)`. 139 | 140 | See the [](syntax/header-anchors) section of extended syntaxes. 141 | 142 | ::: 143 | 144 | If you'd like to *automatically* generate targets for each of your section headers, 145 | check out the [autosectionlabel](inv:sphinx#usage/*/autosectionlabel) 146 | sphinx feature. You can activate it in your Sphinx site by adding the following to your 147 | `conf.py` file: 148 | 149 | ```python 150 | extensions = [ 151 | 'sphinx.ext.autosectionlabel', 152 | ] 153 | 154 | # Prefix document path to section labels, to use: 155 | # `path/to/file:heading` instead of just `heading` 156 | autosectionlabel_prefix_document = True 157 | ``` 158 | 159 | So, if you have a page at `myfolder/mypage.md` (relative to your documentation root) 160 | with the following structure: 161 | 162 | ```md 163 | # Title 164 | 165 | ## My Subtitle 166 | ``` 167 | 168 | Then the `autosectionlabel` feature will allow you to reference the section headers 169 | like so: 170 | 171 | ```md 172 | {ref}`path/to/file_1:My Subtitle` 173 | ``` 174 | 175 | ### Suppress warnings 176 | 177 | Moved to [](myst-warnings) 178 | 179 | ### Sphinx-specific page front matter 180 | 181 | Sphinx intercepts front matter and stores them within the global environment 182 | (as discussed in the [sphinx documentation](inv:sphinx#usage/*/field-lists)). 183 | There are certain front-matter keys (or their translations) that are also recognised specifically by docutils and parsed to inline Markdown: 184 | 185 | - `author` 186 | - `authors` 187 | - `organization` 188 | - `address` 189 | - `contact` 190 | - `version` 191 | - `revision` 192 | - `status` 193 | - `date` 194 | - `copyright` 195 | - `dedication` 196 | - `abstract` 197 | 198 | A classic use-case is to specify 'orphan' documents, that are not specified in any toctrees. 199 | For example, inserting the following syntax at the top of a page will cause Sphinx to treat it as an orphan page: 200 | 201 | ```md 202 | --- 203 | orphan: true 204 | --- 205 | 206 | This is an orphan document, not specified in any toctrees. 207 | ``` 208 | 209 | ### Migrate pre-existing rST into MyST 210 | 211 | If you've already got some reStructuredText files that you'd like to convert into MyST Markdown, try the [`rst-to-myst`](https://github.com/executablebooks/rst-to-myst) tool, which allows you to convert single rST files to MyST markdown documents. 212 | 213 | ## Disable Markdown syntax for the parser 214 | 215 | If you'd like to either enable or disable custom markdown syntax, use `myst_disable_syntax`. 216 | Anything in this list will no longer be parsed by the MyST parser. 217 | 218 | For example, to disable the `emphasis` in-line syntax, use this configuration: 219 | 220 | ```python 221 | myst_disable_syntax = ["emphasis"] 222 | ``` 223 | 224 | emphasis syntax will now be disabled. For example, the following will be rendered 225 | *without* any italics: 226 | 227 | ```md 228 | *emphasis is now disabled* 229 | ``` 230 | 231 | For a list of all the syntax elements you can disable, see the [markdown-it parser guide](inv:markdown_it#using). 232 | 233 | ## Common errors and questions 234 | 235 | These are common issues and gotchas that people may experience when using the MyST Sphinx extension. 236 | 237 | ### What markup language should I use inside directives? 238 | 239 | If you need to parse content *inside* of another block of content (for example, the 240 | content inside a **note directive**), note that the MyST parser will be used for this 241 | nested parsing as well. 242 | 243 | ### Why doesn't my role/directive recognize markdown link syntax? 244 | 245 | There are some roles/directives that _hard-code_ syntax into 246 | their behavior. For example, many roles allow you to supply titles for links like so: 247 | `` {role}`My title ` ``. While this looks like reStructuredText, the role may 248 | be explicitly expecting the `My title ` structure, and so MyST will behave the same way. 249 | -------------------------------------------------------------------------------- /docs/faq/snippets/include-md.md: -------------------------------------------------------------------------------- 1 | Hallo I'm from a Markdown file, [with a reference](howto/autodoc). 2 | -------------------------------------------------------------------------------- /docs/faq/snippets/include-rst.rst: -------------------------------------------------------------------------------- 1 | Hallo I'm from an rST file, :ref:`with a reference `. 2 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | sd_hide_title: true 3 | --- 4 | 5 | # Overview 6 | 7 | ::::{grid} 8 | :reverse: 9 | :gutter: 3 4 4 4 10 | :margin: 1 2 1 2 11 | 12 | :::{grid-item} 13 | :columns: 12 4 4 4 14 | 15 | ```{image} _static/logo-square.svg 16 | :width: 200px 17 | :class: sd-m-auto 18 | ``` 19 | 20 | ::: 21 | 22 | :::{grid-item} 23 | :columns: 12 8 8 8 24 | :child-align: justify 25 | :class: sd-fs-5 26 | 27 | ```{rubric} MyST - Markedly Structured Text - Parser 28 | ``` 29 | 30 | A Sphinx and Docutils extension to parse MyST, 31 | a rich and extensible flavour of Markdown for authoring technical and scientific documentation. 32 | 33 | ````{div} sd-d-flex-row 34 | ```{button-ref} intro 35 | :ref-type: doc 36 | :color: primary 37 | :class: sd-rounded-pill sd-mr-3 38 | 39 | Get Started 40 | ``` 41 | 42 | ```{button-ref} live-preview 43 | :ref-type: doc 44 | :color: secondary 45 | :class: sd-rounded-pill 46 | 47 | Live Demo 48 | ``` 49 | ```` 50 | 51 | ::: 52 | 53 | :::: 54 | 55 | --- 56 | 57 | ::::{grid} 1 2 2 3 58 | :gutter: 1 1 1 2 59 | 60 | :::{grid-item-card} {octicon}`markdown;1.5em;sd-mr-1` CommonMark-plus 61 | :link: syntax/core 62 | :link-type: ref 63 | 64 | MyST extends the CommonMark syntax specification, to support technical authoring features such as tables and footnotes. 65 | 66 | +++ 67 | [Learn more »](syntax/core) 68 | ::: 69 | 70 | :::{grid-item-card} {octicon}`plug;1.5em;sd-mr-1` Sphinx compatible 71 | :link: roles-directives 72 | :link-type: ref 73 | 74 | Use the MyST role and directive syntax to harness the full capability of Sphinx, such as admonitions and figures, and all existing Sphinx extensions. 75 | 76 | +++ 77 | [Learn more »](roles-directives) 78 | ::: 79 | 80 | :::{grid-item-card} {octicon}`tools;1.5em;sd-mr-1` Highly configurable 81 | :link: configuration 82 | :link-type: doc 83 | 84 | MyST-parser can be configured at both the global and individual document level, 85 | to modify parsing behaviour and access extended syntax features. 86 | 87 | +++ 88 | [Learn more »](configuration) 89 | ::: 90 | 91 | :::: 92 | 93 | --- 94 | 95 | ```{rubric} Additional resources 96 | ``` 97 | 98 | [MyST-Markdown VS Code extension](https://marketplace.visualstudio.com/items?itemName=ExecutableBookProject.myst-highlight) 99 | : For MyST extended syntax highlighting and authoring tools. 100 | 101 | [Convert existing ReStructuredText files to Markdown][rst-to-myst] 102 | : Use the [rst-to-myst] CLI or [the MySTyc interactive web interface](https://astrojuanlu.github.io/mystyc/). 103 | 104 | [MyST-NB](https://myst-nb.readthedocs.io) 105 | : A Sphinx and Docutils extension for compiling Jupyter Notebooks into high quality documentation formats, built on top of the MyST-Parser. 106 | 107 | [Jupyter Book](https://jupyterbook.org) 108 | : An open source project for building beautiful, publication-quality books and documents from computational material, built on top of the MyST-Parser and MyST-NB. 109 | 110 | [The Jupyter Book gallery](https://executablebooks.org/en/latest/gallery.html) 111 | : Examples of documents built with MyST. 112 | 113 | [Javascript MyST parser][mystjs] 114 | : The [mystjs] Javascript parser, allows you to parse MyST in websites. 115 | 116 | [markdown-it-py] 117 | : A CommonMark-compliant and extensible Markdown parser, used by MyST-Parser to parse source text to tokens. 118 | 119 | ```{rubric} Acknowledgements 120 | ``` 121 | 122 | The MyST markdown language and MyST parser are both supported by the open community, 123 | [The Executable Book Project](https://executablebooks.org). 124 | 125 | ```{toctree} 126 | :hidden: 127 | intro.md 128 | live-preview.md 129 | ``` 130 | 131 | ```{toctree} 132 | :hidden: 133 | :caption: Guides 134 | 135 | syntax/syntax 136 | syntax/optional 137 | syntax/roles-and-directives.md 138 | configuration.md 139 | docutils.md 140 | faq/index.md 141 | develop/index.md 142 | ``` 143 | 144 | ```{toctree} 145 | :hidden: 146 | :caption: Reference 147 | 148 | develop/_changelog.md 149 | syntax/reference 150 | develop/background.md 151 | api/reference.rst 152 | ``` 153 | 154 | [commonmark]: https://commonmark.org/ 155 | [github-ci]: https://github.com/executablebooks/MyST-Parser/workflows/continuous-integration/badge.svg?branch=master 156 | [github-link]: https://github.com/executablebooks/MyST-Parser 157 | [codecov-badge]: https://codecov.io/gh/executablebooks/MyST-Parser/branch/master/graph/badge.svg 158 | [codecov-link]: https://codecov.io/gh/executablebooks/MyST-Parser 159 | [rtd-badge]: https://readthedocs.org/projects/myst-parser/badge/?version=latest 160 | [rtd-link]: https://myst-parser.readthedocs.io/en/latest/?badge=latest 161 | [black-badge]: https://img.shields.io/badge/code%20style-black-000000.svg 162 | [pypi-badge]: https://img.shields.io/pypi/v/myst-parser.svg 163 | [pypi-link]: https://pypi.org/project/myst-parser 164 | [conda-badge]: https://anaconda.org/conda-forge/myst-parser/badges/version.svg 165 | [conda-link]: https://anaconda.org/conda-forge/myst-parser 166 | [black-link]: https://github.com/ambv/black 167 | [github-badge]: https://img.shields.io/github/stars/executablebooks/myst-parser?label=github 168 | [markdown-it-py]: https://markdown-it-py.readthedocs.io/ 169 | [markdown-it]: https://markdown-it.github.io/ 170 | [rst-to-myst]: https://rst-to-myst.readthedocs.io 171 | [mystjs]: https://github.com/executablebooks/mystjs 172 | -------------------------------------------------------------------------------- /docs/intro.md: -------------------------------------------------------------------------------- 1 | (intro/get-started)= 2 | # Get Started 3 | 4 | This page describes how to get started with the MyST parser, with a focus on enabling it in the Sphinx documentation engine. 5 | 6 | ## Installation 7 | 8 | [![PyPI][pypi-badge]][pypi-link] 9 | [![Conda][conda-badge]][conda-link] 10 | 11 | To install use [pip](https://pip.pypa.io): 12 | 13 | ```bash 14 | pip install myst-parser 15 | ``` 16 | 17 | or [Conda](https://docs.conda.io): 18 | 19 | ```bash 20 | conda install -c conda-forge myst-parser 21 | ``` 22 | 23 | [pypi-badge]: https://img.shields.io/pypi/v/myst-parser.svg 24 | [pypi-link]: https://pypi.org/project/myst-parser 25 | [conda-badge]: https://anaconda.org/conda-forge/myst-parser/badges/version.svg 26 | [conda-link]: https://anaconda.org/conda-forge/myst-parser 27 | 28 | (intro/sphinx)= 29 | ## Enable MyST in Sphinx 30 | 31 | To get started with Sphinx, see their [quick-start guide](inv:sphinx#usage/quickstart). 32 | 33 | To use the MyST parser in Sphinx, simply add the following to your `conf.py` file: 34 | 35 | ```python 36 | extensions = ["myst_parser"] 37 | ``` 38 | 39 | This will activate the MyST Parser extension, causing all documents with the `.md` extension to be parsed as MyST. 40 | 41 | :::{tip} 42 | To parse single documents, see the [](docutils.md) section 43 | ::: 44 | 45 | (intro/writing)= 46 | ## Write a CommonMark document 47 | 48 | MyST is an extension of [CommonMark Markdown](https://commonmark.org/), 49 | that includes [additional syntax](syntax/syntax.md) for technical authoring, 50 | which integrates with Docutils and Sphinx. 51 | 52 | To start off, create an empty file called `myfile.md` and give it a markdown title and text. 53 | 54 | ```md 55 | # My nifty title 56 | 57 | Some **text**! 58 | ``` 59 | 60 | To parse to HTML, try the CLI: 61 | 62 | ```html 63 | $ myst-docutils-html5 --stylesheet= myfile.md 64 | 65 | 66 | 67 | 68 | 69 | My nifty title 70 | 71 | 72 | 73 |
74 |

My nifty title

75 | 76 |

Some text!

77 |
78 | 79 | 80 | ``` 81 | 82 | To include this document within a Sphinx project, 83 | include `myfile.md` in a [`toctree` directive](inv:sphinx#toctree-directive) on an index page. 84 | 85 | ## Extend CommonMark with roles and directives 86 | 87 | MyST allows any Sphinx role or directive to be used in a document. 88 | These are extensions points allowing for richer features, such as admonitions and figures. 89 | 90 | For example, add an `admonition` directive and `sup` role to your Markdown page, like so: 91 | 92 | ````md 93 | # My nifty title 94 | 95 | Some **text**! 96 | 97 | ```{admonition} Here's my title 98 | :class: tip 99 | 100 | Here's my admonition content.{sup}`1` 101 | ``` 102 | ```` 103 | 104 | Then convert to HTML: 105 | 106 | ```html 107 | $ myst-docutils-html5 --stylesheet= myfile.md 108 | ... 109 |
110 |

Here's my title

111 |

Here's my admonition content.1

112 |
113 | ... 114 | ``` 115 | 116 | :::{seealso} 117 | The full [](syntax/roles-and-directives.md) section 118 | ::: 119 | 120 | (intro/reference)= 121 | ## Cross-referencing 122 | 123 | MyST-Parser offers powerful cross-referencing features, to link to documents, headers, figures and more. 124 | 125 | For example, to add a section *reference target*, and reference it: 126 | 127 | ```md 128 | (header-label)= 129 | # A header 130 | 131 | [My reference](header-label) 132 | ``` 133 | 134 | ```html 135 | $ myst-docutils-html5 --stylesheet= myfile.md 136 | ... 137 | 138 |

A header

139 | 140 |

My reference

141 | ... 142 | ``` 143 | 144 | :::{seealso} 145 | The [](syntax/referencing) section,\ 146 | and the [ReadTheDocs cross-referencing](https://docs.readthedocs.io/en/stable/guides/cross-referencing-with-sphinx.html) documentation 147 | ::: 148 | 149 | ## Configuring MyST-Parser 150 | 151 | The [](configuration.md) section contains a complete list of configuration options for the MyST-Parser. 152 | 153 | These can be applied globally, e.g. in the sphinx `conf.py`: 154 | 155 | ```python 156 | myst_enable_extensions = [ 157 | "colon_fence", 158 | ] 159 | ``` 160 | 161 | Or they can be applied to specific documents, at the top of the document: 162 | 163 | ```yaml 164 | --- 165 | myst: 166 | enable_extensions: ["colon_fence"] 167 | --- 168 | ``` 169 | 170 | ## Extending Sphinx 171 | 172 | The other way to extend MyST in Sphinx is to install Sphinx extensions that define new roles, directives, etc. 173 | 174 | For example, let's install the `sphinxcontrib.mermaid` extension, 175 | which will allow us to generate [Mermaid diagrams](https://mermaid-js.github.io/mermaid/#/) with MyST. 176 | 177 | First, install `sphinxcontrib.mermaid`: 178 | 179 | ```shell 180 | pip install sphinxcontrib-mermaid 181 | ``` 182 | 183 | Next, add it to your list of extensions in `conf.py`: 184 | 185 | ```python 186 | extensions = [ 187 | "myst_parser", 188 | "sphinxcontrib.mermaid", 189 | ] 190 | ``` 191 | 192 | Now, add a **mermaid directive** to your markdown file. 193 | For example: 194 | 195 | ````md 196 | # My nifty title 197 | 198 | Some **text**! 199 | 200 | ```{admonition} Here's my title 201 | :class: warning 202 | 203 | Here's my admonition content 204 | ``` 205 | 206 | (section-two)= 207 | ## Here's another section 208 | 209 | And some more content. 210 | 211 | % This comment won't make it into the outputs! 212 | And here's {ref}`a reference to this section `. 213 | I can also reference the section {ref}`section-two` without specifying my title. 214 | 215 | :::{note} 216 | And here's a note with a colon fence! 217 | ::: 218 | 219 | And finally, here's a cool mermaid diagram! 220 | 221 | ```{mermaid} 222 | sequenceDiagram 223 | participant Alice 224 | participant Bob 225 | Alice->John: Hello John, how are you? 226 | loop Healthcheck 227 | John->John: Fight against hypochondria 228 | end 229 | Note right of John: Rational thoughts
prevail... 230 | John-->Alice: Great! 231 | John->Bob: How about you? 232 | Bob-->John: Jolly good! 233 | ``` 234 | ```` 235 | 236 | When you build your documentation, you should see something like this: 237 | 238 | ```{mermaid} 239 | sequenceDiagram 240 | participant Alice 241 | participant Bob 242 | Alice->John: Hello John, how are you? 243 | loop Healthcheck 244 | John->John: Fight against hypochondria 245 | end 246 | Note right of John: Rational thoughts
prevail... 247 | John-->Alice: Great! 248 | John->Bob: How about you? 249 | Bob-->John: Jolly good! 250 | ``` 251 | -------------------------------------------------------------------------------- /docs/live-preview.md: -------------------------------------------------------------------------------- 1 | --- 2 | py-config: 3 | splashscreen: 4 | autoclose: true 5 | packages: 6 | - myst-docutils 7 | - docutils==0.19 8 | - pygments 9 | --- 10 | 11 | # Live Preview 12 | 13 | This is a live preview of the MyST Markdown [docutils renderer](docutils.md). 14 | You can edit the text/configuration below and see the live output.[^note] 15 | 16 | [^note]: Additional styling is usually provided by Sphinx themes. 17 | 18 | ```{py-script} 19 | :file: live_preview.py 20 | ``` 21 | 22 | ::::::::{grid} 1 1 1 2 23 | 24 | :::::::{grid-item} 25 | :child-align: end 26 | 27 | ```{raw} html 28 |
29 | ``` 30 | 31 | :::::{tab-set} 32 | ::::{tab-item} Input text 33 | ````{raw} html 34 | 65 | ```` 66 | 67 | :::: 68 | ::::{tab-item} Configuration (YAML) 69 | 80 | :::: 81 | ::::: 82 | 83 | ::::::: 84 | :::::::{grid-item} 85 | :child-align: end 86 | 87 | ```{raw} html 88 |
89 | 90 | 95 |
96 | ``` 97 | 98 | ::::{tab-set} 99 | :::{tab-item} HTML Render 100 | 101 | ::: 102 | :::{tab-item} Raw Output 103 | 104 | ::: 105 | :::{tab-item} Warnings 106 | 107 | ::: 108 | :::: 109 | ::::::: 110 | :::::::: 111 | -------------------------------------------------------------------------------- /docs/live_preview.py: -------------------------------------------------------------------------------- 1 | import traceback 2 | from io import StringIO 3 | 4 | import yaml 5 | from docutils.core import publish_string 6 | from js import document 7 | 8 | from myst_parser import __version__ 9 | from myst_parser.parsers.docutils_ import Parser 10 | 11 | 12 | def convert(input_config: str, input_myst: str, writer_name: str) -> dict: 13 | warning_stream = StringIO() 14 | try: 15 | settings = yaml.safe_load(input_config) if input_config else {} 16 | assert isinstance(settings, dict), "not a dictionary" 17 | except Exception as exc: 18 | warning_stream.write(f"ERROR: config load: {exc}\n") 19 | settings = {} 20 | settings.update( 21 | { 22 | "output_encoding": "unicode", 23 | "warning_stream": warning_stream, 24 | } 25 | ) 26 | try: 27 | output = publish_string( 28 | input_myst, 29 | parser=Parser(), 30 | writer_name=writer_name, 31 | settings_overrides=settings, 32 | ) 33 | except Exception as exc: 34 | output = f"ERROR: conversion:\n{exc}\n{traceback.format_exc()}" 35 | return {"output": output, "warnings": warning_stream.getvalue()} 36 | 37 | 38 | version_label = document.querySelector("span#myst-version") 39 | config_textarea = document.querySelector("textarea#input_config") 40 | input_textarea = document.querySelector("textarea#input_myst") 41 | output_iframe = document.querySelector("iframe#output_html") 42 | output_raw = document.querySelector("textarea#output_raw") 43 | warnings_textarea = document.querySelector("textarea#output_warnings") 44 | oformat_select = document.querySelector("select#output_format") 45 | 46 | 47 | def do_convert(event=None): 48 | result = convert(config_textarea.value, input_textarea.value, oformat_select.value) 49 | output_raw.value = result["output"] 50 | if "html" in oformat_select.value: 51 | output_iframe.contentDocument.body.innerHTML = result["output"] 52 | else: 53 | output_iframe.contentDocument.body.innerHTML = ( 54 | "Change output format to HTML to see output" 55 | ) 56 | warnings_textarea.value = result["warnings"] 57 | 58 | 59 | version_label.textContent = f"myst-parser v{__version__}" 60 | config_textarea.oninput = do_convert 61 | input_textarea.oninput = do_convert 62 | oformat_select.onchange = do_convert 63 | 64 | do_convert() 65 | -------------------------------------------------------------------------------- /docs/syntax/example.txt: -------------------------------------------------------------------------------- 1 | Hallo! 2 | -------------------------------------------------------------------------------- /docs/syntax/img/fun-fish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soaringsoul/easypoi/b0b09047903d046dfd513ec7a0de533525b343d5/docs/syntax/img/fun-fish.png -------------------------------------------------------------------------------- /docs/syntax/optional.md: -------------------------------------------------------------------------------- 1 | --- 2 | myst: 3 | substitutions: 4 | key1: I'm a **substitution** 5 | key2: | 6 | ```{note} 7 | {{ key1 }} 8 | ``` 9 | key3a: fishy 10 | key3: | 11 | ```{image} img/fun-fish.png 12 | :alt: fishy 13 | :width: 200px 14 | ``` 15 | key4: example 16 | confpy: sphinx `conf.py` [configuration file](inv:sphinx#usage/configuration) 17 | --- 18 | 19 | (syntax/extensions)= 20 | 21 | # Syntax Extensions 22 | 23 | MyST-Parser is highly configurable, utilising the inherent "plugability" of the [markdown-it-py](inv:markdown_it#index) parser. 24 | The following syntaxes are optional (disabled by default) and can be enabled *via* the {{ confpy }} (see also [](sphinx/config-options)). 25 | Their goal is generally to add more *Markdown friendly* syntaxes; often enabling and rendering [markdown-it-py plugins](inv:markdown_it#md/plugins) that extend the [CommonMark specification](https://commonmark.org/). 26 | 27 | To enable all the syntaxes explained below: 28 | 29 | ```python 30 | myst_enable_extensions = [ 31 | "amsmath", 32 | "attrs_inline", 33 | "colon_fence", 34 | "deflist", 35 | "dollarmath", 36 | "fieldlist", 37 | "html_admonition", 38 | "html_image", 39 | "inv_link", 40 | "linkify", 41 | "replacements", 42 | "smartquotes", 43 | "strikethrough", 44 | "substitution", 45 | "tasklist", 46 | ] 47 | ``` 48 | 49 | :::{versionchanged} 0.13.0 50 | `myst_enable_extensions` replaces previous configuration options: 51 | `admonition_enable`, `figure_enable`, `dmath_enable`, `amsmath_enable`, `deflist_enable`, `html_img_enable` 52 | ::: 53 | 54 | (syntax/typography)= 55 | 56 | ## Typography 57 | 58 | Adding `"smartquotes"` to `myst_enable_extensions` (in the {{ confpy }}) will automatically convert standard quotations to their opening/closing variants: 59 | 60 | - `'single quotes'`: 'single quotes' 61 | - `"double quotes"`: "double quotes" 62 | 63 | Adding `"replacements"` to `myst_enable_extensions` (in the {{ confpy }}) will automatically convert some common typographic texts 64 | 65 | text | converted 66 | ----- | ---------- 67 | ``(c)``, ``(C)`` | (c) 68 | ``(tm)``, ``(TM)`` | (tm) 69 | ``(r)``, ``(R)`` | (r) 70 | ``(p)``, ``(P)`` | (p) 71 | ``+-`` | +- 72 | ``...`` | ... 73 | ``?....`` | ?.... 74 | ``!....`` | !.... 75 | ``????????`` | ???????? 76 | ``!!!!!`` | !!!!! 77 | ``,,,`` | ,,, 78 | ``--`` | -- 79 | ``---`` | --- 80 | 81 | (syntax/strikethrough)= 82 | 83 | ## Strikethrough 84 | 85 | ```{versionadded} 0.17.0 86 | ``` 87 | 88 | The `strikethrough` extension allows text within `~~` delimiters to have a strikethrough (horizontal line) placed over it. 89 | For example, `~~strikethrough with *emphasis*~~` renders as: ~~strikethrough with *emphasis*~~. 90 | 91 | :::{warning} 92 | This extension is currently only supported for HTML output, 93 | and you will need to suppress the `myst.strikethrough` warning 94 | (see [](myst-warnings)) 95 | ::: 96 | 97 | (syntax/math)= 98 | ## Math shortcuts 99 | 100 | Math is parsed by adding to the `myst_enable_extensions` list option, in the {{ confpy }} one or both of: 101 | 102 | - `"dollarmath"` for parsing of dollar `$` and `$$` encapsulated math. 103 | - `"amsmath"` for direct parsing of [amsmath LaTeX environments](https://ctan.org/pkg/amsmath). 104 | 105 | These options enable their respective Markdown parser plugins, as detailed in the [markdown-it plugin guide](inv:markdown_it#md/plugins). 106 | 107 | :::{versionchanged} 0.13.0 108 | `myst_dmath_enable=True` and `myst_amsmath_enable=True` are deprecated, and replaced by `myst_enable_extensions = ["dollarmath", "amsmath"]` 109 | ::: 110 | 111 | ### Dollar delimited math 112 | 113 | Enabling `dollarmath` will parse the following syntax: 114 | 115 | - Inline math: `$...$` 116 | - Display (block) math: `$$...$$` 117 | 118 | Additionally if `myst_dmath_allow_labels=True` is set (the default): 119 | 120 | - Display (block) math with equation label: `$$...$$ (1)` 121 | 122 | For example, `$x_{hey}=it+is^{math}$` renders as $x_{hey}=it+is^{math}$. 123 | This is equivalent to writing: 124 | 125 | ```md 126 | {math}`x_{hey}=it+is^{math}` 127 | ``` 128 | 129 | :::{admonition} Escaping Dollars 130 | :class: tip 131 | 132 | Math can be escaped (negated) by adding a `\` before the first symbol, e.g. `\$a$` renders as \$a\$. 133 | Escaping can also be used inside math, e.g. `$a=\$3$` renders as $a=\$3$. 134 | 135 | Conversely `\\` will negate the escaping, so `\\$a$` renders as \\$a$. 136 | ::: 137 | 138 | Block-level math can be specified with `$$` signs that wrap the math block you'd like to parse. 139 | For example: 140 | 141 | ```latex 142 | $$ 143 | y & = ax^2 + bx + c \\ 144 | f(x) & = x^2 + 2xy + y^2 145 | $$ 146 | ``` 147 | 148 | becomes 149 | 150 | $$ 151 | y & = ax^2 + bx + c \\ 152 | f(x) & = x^2 + 2xy + y^2 153 | $$ 154 | 155 | This is equivalent to the following directive: 156 | 157 | ````md 158 | ```{math} 159 | y & = ax^2 + bx + c \\ 160 | f(x) & = x^2 + 2xy + y^2 161 | ``` 162 | ```` 163 | 164 | You can also add labels to block equations: 165 | 166 | ```latex 167 | $$ 168 | e = mc^2 169 | $$ (eqn:best) 170 | 171 | This is the best equation {eq}`eqn:best` 172 | ``` 173 | 174 | $$ 175 | e = mc^2 176 | $$ (eqn:best) 177 | 178 | This is the best equation {eq}`eqn:best` 179 | 180 | There are a few other options available to control dollar math parsing: 181 | 182 | `myst_dmath_allow_space=False`, will cause inline math to only be parsed if there are no initial / final spaces, e.g. `$a$` but not `$ a$` or `$a $`. 183 | 184 | `myst_dmath_allow_digits=False`, will cause inline math to only be parsed if there are no initial / final digits, e.g. `$a$` but not `1$a$` or `$a$2`. 185 | 186 | These options can both be useful if you also wish to use `$` as a unit of currency. 187 | 188 | ```{versionadded} 0.14.0 189 | `myst_dmath_double_inline` option 190 | ``` 191 | 192 | To allow display math (i.e. `$$`) within an inline context, set `myst_dmath_double_inline = True` (`False` by default). 193 | This allows for example: 194 | 195 | ```latex 196 | Hence, for $\alpha \in (0, 1)$, 197 | $$ 198 | \mathbb P (\alpha \bar{X} \ge \mu) \le \alpha; 199 | $$ 200 | i.e., $[\alpha \bar{X}, \infty)$ is a lower 1-sided $1-\alpha$ confidence bound for $\mu$. 201 | ``` 202 | 203 | Hence, for $\alpha \in (0, 1)$, 204 | $$ 205 | \mathbb P (\alpha \bar{X} \ge \mu) \le \alpha; 206 | $$ 207 | i.e., $[\alpha \bar{X}, \infty)$ is a lower 1-sided $1-\alpha$ confidence bound for $\mu$. 208 | 209 | ### Math in other block elements 210 | 211 | Math will also work when nested in other block elements, like lists or quotes: 212 | 213 | ```md 214 | - A list 215 | - $$ a = 1 $$ 216 | 217 | > A block quote 218 | > $$ a = 1 $$ 219 | ``` 220 | 221 | - A list 222 | - $$ a = 1 $$ 223 | 224 | > A block quote 225 | > $$ a = 1 $$ 226 | 227 | ### Direct LaTeX Math 228 | 229 | Want to use [amsmath](https://ctan.org/pkg/amsmath) LaTeX directly, with no dollars? 230 | See [the extended syntax option](syntax/amsmath). 231 | 232 | (syntax/mathjax)= 233 | ### Mathjax and math parsing 234 | 235 | When building HTML using the extension (enabled by default), 236 | If `dollarmath` is enabled, Myst-Parser injects the `tex2jax_ignore` (MathJax v2) and `mathjax_ignore` (MathJax v3) classes in to the top-level section of each MyST document, and adds the following default MathJax configuration: 237 | 238 | MathJax version 2 (see [the tex2jax preprocessor](https://docs.mathjax.org/en/v2.7-latest/options/preprocessors/tex2jax.html#configure-tex2jax): 239 | 240 | ```javascript 241 | MathJax.Hub.Config({"tex2jax": {"processClass": "tex2jax_process|mathjax_process|math|output_area"}}) 242 | ``` 243 | 244 | MathJax version 3 (see [the document options](https://docs.mathjax.org/en/latest/options/document.html?highlight=ignoreHtmlClass#the-configuration-block)): 245 | 246 | ```javascript 247 | window.MathJax = {"options": {"processHtmlClass": "tex2jax_process|mathjax_process|math|output_area"}} 248 | ``` 249 | 250 | This ensurea that MathJax processes only math, identified by the `dollarmath` and `amsmath` extensions, or specified in `math` directives. 251 | 252 | To change this behaviour, set a custom regex, for identifying HTML classes to process, like `myst_mathjax_classes="math|myclass"`, or set `myst_update_mathjax=False` to inhibit this override and process all HTML elements. 253 | 254 | (syntax/linkify)= 255 | ## Linkify 256 | 257 | Adding `"linkify"` to `myst_enable_extensions` (in the {{ confpy }}) will automatically identify "bare" web URLs and add hyperlinks: 258 | 259 | `www.example.com` -> www.example.com 260 | 261 | To only match URLs that start with schema, such as `http://example.com`, set `myst_linkify_fuzzy_links=False`. 262 | 263 | :::{important} 264 | This extension requires that [linkify-it-py](https://github.com/tsutsu3/linkify-it-py) is installed. 265 | Either directly; `pip install linkify-it-py` or *via* `pip install myst-parser[linkify]`. 266 | ::: 267 | 268 | (syntax/substitutions)= 269 | 270 | ## Substitutions (with Jinja2) 271 | 272 | Adding `"substitution"` to `myst_enable_extensions` (in the {{ confpy }}) will allow you to add substitutions, added in either the `conf.py` using `myst_substitutions`: 273 | 274 | ```python 275 | myst_substitutions = { 276 | "key1": "I'm a **substitution**" 277 | } 278 | ``` 279 | 280 | or at the top of the file, in the front-matter section (see [this section](syntax/frontmatter)): 281 | 282 | ````yaml 283 | --- 284 | myst: 285 | substitutions: 286 | key1: "I'm a **substitution**" 287 | key2: | 288 | ```{note} 289 | {{ key1 }} 290 | ``` 291 | key3: | 292 | ```{image} img/fun-fish.png 293 | :alt: fishy 294 | :width: 200px 295 | ``` 296 | key4: example 297 | --- 298 | ```` 299 | 300 | :::{important} 301 | Keys in the front-matter will override ones in the `conf.py`. 302 | ::: 303 | 304 | You can use these substitutions inline or as blocks, and you can even nest substitutions in other substitutions (but circular references are prohibited): 305 | 306 | ::::{tab-set} 307 | :::{tab-item} Markdown Input 308 | 309 | ```md 310 | Inline: {{ key1 }} 311 | 312 | Block level: 313 | 314 | {{ key2 }} 315 | 316 | | col1 | col2 | 317 | | -------- | -------- | 318 | | {{key2}} | {{key3}} | 319 | 320 | ``` 321 | 322 | ::: 323 | 324 | :::{tab-item} Rendered Output 325 | Inline: {{ key1 }} 326 | 327 | Block level: 328 | 329 | {{ key2 }} 330 | 331 | | col1 | col2 | 332 | | -------- | -------- | 333 | | {{key2}} | {{key3}} | 334 | 335 | ::: 336 | :::: 337 | 338 | :::{important} 339 | 340 | Substitutions will only be assessed where you would normally use Markdown, e.g. not in code blocks: 341 | 342 | ```` 343 | ``` 344 | {{ key1 }} 345 | ``` 346 | ```` 347 | 348 | ``` 349 | {{ key1 }} 350 | ``` 351 | 352 | One should also be wary of using unsuitable directives for inline substitutions. 353 | This may lead to unexpected outcomes. 354 | 355 | ::: 356 | 357 | Substitution references are assessed as [Jinja2 expressions](http://jinja.palletsprojects.com) which can use [filters](https://jinja.palletsprojects.com/en/2.11.x/templates/#list-of-builtin-filters), and also contains the [Sphinx Environment](inv:sphinx#extdev/envapi) in the context (as `env`). 358 | Therefore you can do things like: 359 | 360 | ```md 361 | - version: {{ env.config.version }} 362 | - docname: {{ env.docname | upper }} 363 | - {{ "a" + "b" }} 364 | ``` 365 | 366 | - version: {{ env.config.version }} 367 | - docname: {{ env.docname | upper }} 368 | - {{ "a" + "b" }} 369 | 370 | You can also change the delimiter if necessary, for example setting in the `conf.py`: 371 | 372 | ```python 373 | myst_sub_delimiters = ["|", "|"] 374 | ``` 375 | 376 | Will parse: `|| "a" + "b" ||`. 377 | This should be changed with care though, so as not to affect other syntaxes. 378 | 379 | The exact logic for handling substitutions is: 380 | 381 | 1. Combine global substitutions (specified in `conf.py`) with front-matter substitutions, to create a variable context (front-matter takes priority) 382 | 2. Add the sphinx `env` to the variable context 383 | 3. Create the string content to render using Jinja2 (passing it the variable context) 384 | 4. If the substitution is inline and not a directive, render ignoring block syntaxes (like lists or block-quotes), otherwise render with all syntax rules. 385 | 386 | ### Substitutions and URLs 387 | 388 | Substitutions cannot be directly used in URLs, such as `[a link](https://{{key4}}.com)` or ``. 389 | However, since Jinja2 substitutions allow for Python methods to be used, you can use string formatting or replacements: 390 | 391 | ```md 392 | {{ '[a link](https://{}.com)'.format(key4) }} 393 | 394 | {{ ''.replace('REPLACE', env.docname) }} 395 | ``` 396 | 397 | {{ '[a link](https://{}.com)'.format(key4) }} 398 | 399 | {{ ''.replace('REPLACE', env.docname) }} 400 | 401 | (syntax/colon_fence)= 402 | 403 | ## Code fences using colons 404 | 405 | By adding `"colon_fence"` to `myst_enable_extensions` (in the {{ confpy }}), 406 | you can also use `:::` delimiters to denote code fences, instead of ```` ``` ````. 407 | 408 | Using colons instead of back-ticks has the benefit of allowing the content to be rendered correctly, when you are working in any standard Markdown editor. 409 | It is ideal for admonition type directives (as documented in [Directives](syntax/directives)) or tables with titles, for example: 410 | 411 | ::::::{tab-set} 412 | :::::{tab-item} Markdown Input 413 | ```md 414 | :::{note} 415 | This text is **standard** _Markdown_ 416 | ::: 417 | 418 | :::{table} This is a **standard** _Markdown_ title 419 | :align: center 420 | :widths: grid 421 | 422 | abc | mnp | xyz 423 | --- | --- | --- 424 | 123 | 456 | 789 425 | ::: 426 | ``` 427 | 428 | ::::: 429 | 430 | :::::{tab-item} Rendered Output 431 | 432 | :::{note} 433 | This text is **standard** _Markdown_ 434 | ::: 435 | 436 | :::{table} This is a **standard** _Markdown_ title 437 | :align: center 438 | :widths: grid 439 | 440 | abc | mnp | xyz 441 | --- | --- | --- 442 | 123 | 456 | 789 443 | ::: 444 | 445 | ::::: 446 | :::::: 447 | 448 | Similar to normal directives, these directives can also be nested: 449 | 450 | ```md 451 | ::::{important} 452 | :::{note} 453 | This text is **standard** _Markdown_ 454 | ::: 455 | :::: 456 | ``` 457 | 458 | ::::{important} 459 | :::{note} 460 | This text is **standard** _Markdown_ 461 | ::: 462 | :::: 463 | 464 | and also parameter options can be used: 465 | 466 | ```md 467 | :::{admonition} This *is* also **Markdown** 468 | :class: warning 469 | 470 | This text is **standard** _Markdown_ 471 | ::: 472 | ``` 473 | 474 | :::{admonition} This *is* also **Markdown** 475 | :class: warning 476 | 477 | This text is **standard** _Markdown_ 478 | ::: 479 | 480 | (syntax/admonitions)= 481 | 482 | ## Admonition directives 483 | 484 | :::{versionchanged} 0.13.0 485 | `myst_admonition_enable` is deprecated and replaced by `myst_enable_extensions = ["colon_fence"]` (see above). 486 | Also, classes should now be set with the `:class: myclass` option. 487 | 488 | Also see [](syntax/html-admonition). 489 | ::: 490 | 491 | (syntax/header-anchors)= 492 | 493 | ## Auto-generated header anchors 494 | 495 | The MyST Parser can automatically generate label "slugs" for header anchors so that you can reference them from markdown links. 496 | For example, you can use header bookmark links, locally; `[](#header-anchor)`, or cross-file `[](path/to/file.md#header-anchor)`. 497 | To achieve this, use the `myst_heading_anchors = DEPTH` configuration option, where `DEPTH` is the depth of header levels for which you wish to generate links. 498 | 499 | For example, the following configuration in `conf.py` tells the `myst_parser` to generate labels for heading anchors for `h1`, `h2`, and `h3` level headings (corresponding to `#`, `##`, and `###` in markdown). 500 | 501 | ```python 502 | myst_heading_anchors = 3 503 | ``` 504 | 505 | You can then insert markdown links directly to anchors that are generated from your header titles in your documentation. 506 | For example `[](#auto-generated-header-anchors)`: [](#auto-generated-header-anchors). 507 | 508 | The paths to other files should be relative to the current file, for example 509 | `[**link text**](./syntax.md#core-syntax)`: [**link text**](./syntax.md#core-syntax). 510 | 511 | 512 | ### Anchor slug structure 513 | 514 | The anchor "slugs" created aim to follow the [GitHub implementation](https://github.com/Flet/github-slugger): 515 | 516 | - lower-case text 517 | - remove punctuation 518 | - replace spaces with `-` 519 | - enforce uniqueness *via* suffix enumeration `-1` 520 | 521 | To change the slug generation function, set `myst_heading_slug_func` in your `conf.py` to a function that accepts a string and returns a string. 522 | 523 | ### Inspect the links that will be created 524 | 525 | You can inspect the links that will be created using the command-line tool: 526 | 527 | ```console 528 | $ myst-anchors -l 2 docs/syntax/optional.md 529 |

530 |

531 |

532 |

533 |

534 |

535 |

536 | ``` 537 | 538 | (syntax/definition-lists)= 539 | 540 | ## Definition Lists 541 | 542 | By adding `"deflist"` to `myst_enable_extensions` (in the {{ confpy }}), 543 | you will be able to utilise definition lists. 544 | Definition lists utilise the [markdown-it-py deflist plugin](inv:markdown_it#md/plugins), which itself is based on the [Pandoc definition list specification](http://johnmacfarlane.net/pandoc/README.html#definition-lists). 545 | 546 | This syntax can be useful, for example, as an alternative to nested bullet-lists: 547 | 548 | - Term 1 549 | - Definition 550 | - Term 2 551 | - Definition 552 | 553 | Using instead: 554 | 555 | ```md 556 | Term 1 557 | : Definition 558 | 559 | Term 2 560 | : Definition 561 | ``` 562 | 563 | Term 1 564 | : Definition 565 | 566 | Term 2 567 | : Definition 568 | 569 | From the Pandoc documentation: 570 | 571 | > Each term must fit on one line, which may optionally be followed by a blank line, and must be followed by one or more definitions. 572 | > A definition begins with a colon or tilde, which may be indented one or two spaces. 573 | 574 | > A term may have multiple definitions, and each definition may consist of one or more block elements (paragraph, code block, list, etc.) 575 | 576 | Here is a more complex example, demonstrating some of these features: 577 | 578 | Term *with Markdown* 579 | : Definition [with reference](syntax/definition-lists) 580 | 581 | A second paragraph 582 | : A second definition 583 | 584 | Term 2 585 | ~ Definition 2a 586 | ~ Definition 2b 587 | 588 | Term 3 589 | : A code block 590 | : > A quote 591 | : A final definition, that can even include images: 592 | 593 | fishy 594 | 595 | This was created from: 596 | 597 | ```md 598 | Term *with Markdown* 599 | : Definition [with reference](syntax/definition-lists) 600 | 601 | A second paragraph 602 | : A second definition 603 | 604 | Term 2 605 | ~ Definition 2a 606 | ~ Definition 2b 607 | 608 | Term 3 609 | : A code block 610 | 611 | : > A quote 612 | 613 | : A final definition, that can even include images: 614 | 615 | fishy 616 | ``` 617 | 618 | (syntax/tasklists)= 619 | ## Task Lists 620 | 621 | By adding `"tasklist"` to `myst_enable_extensions` (in the {{ confpy }}), 622 | you will be able to utilise task lists. 623 | Task lists utilise the [markdown-it-py tasklists plugin](inv:markdown_it#md/plugins), 624 | and are applied to markdown list items starting with `[ ]` or `[x]`: 625 | 626 | ```markdown 627 | - [ ] An item that needs doing 628 | - [x] An item that is complete 629 | ``` 630 | 631 | - [ ] An item that needs doing 632 | - [x] An item that is complete 633 | 634 | (syntax/fieldlists)= 635 | ## Field Lists 636 | 637 | ```{versionadded} 0.16.0 638 | ``` 639 | 640 | Field lists are mappings from field names to field bodies, 641 | based on the [reStructureText syntax](https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#field-lists). 642 | 643 | ````md 644 | :name only: 645 | :name: body 646 | :*Nested syntax*: Both name and body may contain **nested syntax**. 647 | :Paragraphs: Since the field marker may be quite long, the second 648 | and subsequent lines of a paragraph do not have to line up 649 | with the first line. 650 | :Alignment 1: If the field body starts on the first line... 651 | 652 | Then the entire field body must be indented the same. 653 | :Alignment 2: 654 | If the field body starts on a subsequent line... 655 | 656 | Then the indentation is always two spaces. 657 | :Blocks: 658 | 659 | As well as paragraphs, any block syntaxes may be used in a field body: 660 | 661 | - Me 662 | - Myself 663 | - I 664 | 665 | ```python 666 | print("Hello, world!") 667 | ``` 668 | ```` 669 | 670 | :name only: 671 | :name: body 672 | :*Nested syntax*: Both name and body may contain **nested syntax**. 673 | :Paragraphs: Since the field marker may be quite long, the second 674 | and subsequent lines of a paragraph do not have to line up 675 | with the first line. 676 | :Alignment 1: If the field body starts on the first line... 677 | 678 | Then the entire field body must be indented the same. 679 | :Alignment 2: 680 | If the field body starts on a subsequent line... 681 | 682 | Then the indentation is always two spaces. 683 | :Blocks: 684 | 685 | As well as paragraphs, any block syntaxes may be used in a field body: 686 | 687 | - Me 688 | - Myself 689 | - I 690 | 691 | ```python 692 | print("Hello, world!") 693 | ``` 694 | 695 | A prominent use case of field lists is for use in API docstrings, as used in [Sphinx's docstring renderers](inv:sphinx#python-domain): 696 | 697 | ````md 698 | ```{py:function} send_message(sender, priority) 699 | 700 | Send a message to a recipient 701 | 702 | :param str sender: The person sending the message 703 | :param priority: The priority of the message, can be a number 1-5 704 | :type priority: int 705 | :return: the message id 706 | :rtype: int 707 | :raises ValueError: if the message_body exceeds 160 characters 708 | ``` 709 | ```` 710 | 711 | ```{py:function} send_message(sender, priority) 712 | 713 | Send a message to a recipient 714 | 715 | :param str sender: The person sending the message 716 | :param priority: The priority of the message, can be a number 1-5 717 | :type priority: int 718 | :return: the message id 719 | :rtype: int 720 | :raises ValueError: if the message_body exceeds 160 characters 721 | ``` 722 | 723 | :::{note} 724 | Currently `sphinx.ext.autodoc` does not support MyST, see [](howto/autodoc). 725 | ::: 726 | 727 | (syntax/attributes)= 728 | ## Inline attributes 729 | 730 | :::{versionadded} 0.19 731 | This feature is in *beta*, and may change in future versions. 732 | It replace the previous `attrs_image` extension, which is now deprecated. 733 | ::: 734 | 735 | By adding `"attrs_inline"` to `myst_enable_extensions` (in the {{ confpy }}), 736 | you can enable parsing of inline attributes after certain inline syntaxes. 737 | This is adapted from [djot inline attributes](https://htmlpreview.github.io/?https://github.com/jgm/djot/blob/master/doc/syntax.html#inline-attributes), 738 | and also related to [pandoc bracketed spans](https://pandoc.org/MANUAL.html#extension-bracketed_spans). 739 | 740 | Attributes are specified in curly braces after the inline syntax. 741 | Inside the curly braces, the following syntax is recognised: 742 | 743 | - `.foo` specifies `foo` as a class. 744 | Multiple classes may be given in this way; they will be combined. 745 | - `#foo` specifies `foo` as an identifier. 746 | An element may have only one identifier; 747 | if multiple identifiers are given, the last one is used. 748 | - `key="value"` or `key=value` specifies a key-value attribute. 749 | Quotes are not needed when the value consists entirely of 750 | ASCII alphanumeric characters or `_` or `:` or `-`. 751 | Backslash escapes may be used inside quoted values. 752 | **Note** only certain keys are supported, see below. 753 | - `%` begins a comment, which ends with the next `%` or the end of the attribute (`}`). 754 | 755 | For example, the following Markdown: 756 | 757 | ```md 758 | 759 | - [A span of text with attributes]{#spanid .bg-warning}, 760 | {ref}`a reference to the span ` 761 | 762 | - `A literal with attributes`{#literalid .bg-warning}, 763 | {ref}`a reference to the literal 764 | 765 | - An autolink with attributes: {.bg-warning title="a title"} 766 | 767 | - [A link with attributes](syntax/attributes){#linkid .bg-warning}, 768 | {ref}`a reference to the link ` 769 | 770 | - ![An image with attribute](img/fun-fish.png){#imgid .bg-warning w=100px align=center} 771 | {ref}`a reference to the image ` 772 | 773 | ``` 774 | 775 | will be parsed as: 776 | 777 | - [A span of text with attributes]{#spanid .bg-warning}, 778 | {ref}`a reference to the span ` 779 | 780 | - `A literal with attributes`{#literalid .bg-warning}, 781 | {ref}`a reference to the literal ` 782 | 783 | - An autolink with attributes: {.bg-warning title="a title"} 784 | 785 | - [A link with attributes](syntax/attributes){#linkid .bg-warning}, 786 | {ref}`a reference to the link ` 787 | 788 | - ![An image with attribute](img/fun-fish.png){#imgid .bg-warning w="100px" align=center} 789 | {ref}`a reference to the image ` 790 | 791 | ### key-value attributes 792 | 793 | `id` and `class` are supported for all inline syntaxes, 794 | but only certain key-value attributes are supported for each syntax. 795 | 796 | For **literals**, the following attributes are supported: 797 | 798 | - `language`/`lexer`/`l` defines the syntax lexer, 799 | e.g. `` `a = "b"`{l=python} `` is displayed as `a = "b"`{l=python}. 800 | Note, this is only supported in `sphinx >= 5`. 801 | 802 | For **images**, the following attributes are supported (equivalent to the `image` directive): 803 | 804 | - `width`/`w` defines the width of the image (in `%`, `px`, `em`, `cm`, etc) 805 | - `height`/`h` defines the height of the image (in `px`, `em`, `cm`, etc) 806 | - `align`/`a` defines the scale of the image (`left`, `center`, or `right`) 807 | 808 | (syntax/images)= 809 | 810 | ## HTML Images 811 | 812 | MyST provides a few different syntaxes for including images in your documentation, as explained below. 813 | 814 | The first is the standard Markdown syntax: 815 | 816 | ```md 817 | ![fishy](img/fun-fish.png) 818 | ``` 819 | 820 | ![fishy](img/fun-fish.png) 821 | 822 | This will correctly copy the image to the build folder and will render it in all output formats (HTML, TeX, etc). 823 | However, it is limited in the configuration that can be applied, for example setting a width. 824 | 825 | As discussed [above](syntax/directives), MyST allow for directives to be used such as `image` and `figure` (see {ref}`the sphinx documentation `): 826 | 827 | ````md 828 | ```{image} img/fun-fish.png 829 | :alt: fishy 830 | :class: bg-primary 831 | :width: 200px 832 | :align: center 833 | ``` 834 | ```` 835 | 836 | ```{image} img/fun-fish.png 837 | :alt: fishy 838 | :class: bg-primary mb-1 839 | :width: 200px 840 | ``` 841 | 842 | Additional options can now be set, however, in contrast to the Markdown syntax, this syntax will not show the image in common Markdown viewers (for example when the files are viewed on GitHub). 843 | 844 | The final option is directly using HTML, which is also parsed by MyST. 845 | This is usually a bad option, because the HTML is treated as raw text during the build process and so sphinx will not recognise that the image file is to be copied, and will not output the HTML into non-HTML output formats. 846 | 847 | HTML parsing to the rescue! 848 | 849 | By adding `"html_image"` to `myst_enable_extensions` (in the {{ confpy }}), 850 | MySt-Parser will attempt to convert any isolated `img` tags (i.e. not wrapped in any other HTML) to the internal representation used in sphinx. 851 | 852 | ```html 853 | fishy 854 | fishy 855 | ``` 856 | 857 | fishy 858 | fishy 859 | 860 | Allowed attributes are equivalent to the `image` directive: src, alt, class, width, height and name. 861 | Any other attributes will be dropped. 862 | 863 | HTML image can also be used inline! 864 | 865 | I'm an inline image: 866 | 867 | (syntax/figures)= 868 | 869 | ## Markdown Figures 870 | 871 | By adding `"colon_fence"` to `myst_enable_extensions` (in the {{ confpy }}), 872 | we can combine the above two extended syntaxes, 873 | to create a fully Markdown compliant version of the `figure` directive named `figure-md`. 874 | 875 | :::{versionchanged} 0.13.0 876 | `myst_figure_enable` with the `figure` directive is deprecated and replaced by `myst_enable_extensions = ["colon_fence"]` and `figure-md`. 877 | ::: 878 | 879 | The figure block must contain **only** two components; an image, in either Markdown or HTML syntax, and a single paragraph for the caption. 880 | 881 | The title is optional and taken as the reference target of the figure: 882 | 883 | ```md 884 | :::{figure-md} fig-target 885 | :class: myclass 886 | 887 | fishy 888 | 889 | This is a caption in **Markdown** 890 | ::: 891 | ``` 892 | 893 | :::{figure-md} fig-target 894 | :class: myclass 895 | 896 | fishy 897 | 898 | This is a caption in **Markdown** 899 | ::: 900 | 901 | As we see here, the target we set can be referenced: 902 | 903 | ```md 904 | [Go to the fish!](fig-target) 905 | ``` 906 | 907 | [Go to the fish!](fig-target) 908 | 909 | (syntax/html-admonition)= 910 | 911 | ## HTML Admonitions 912 | 913 | By adding `"html_admonition"` to `myst_enable_extensions` (in the {{ confpy }}), 914 | you can enable parsing of `
` HTML blocks. 915 | These blocks will be converted internally to Sphinx admonition directives, and so will work correctly for all output formats. 916 | This is helpful when you care about viewing the "source" Markdown, such as in Jupyter Notebooks. 917 | 918 | If the first element within the `div` is `
` or `

`, then this will be set as the admonition title. 919 | All internal text (and the title) will be parsed as MyST-Markdown and all classes and an optional name will be passed to the admonition: 920 | 921 | ```html 922 |

923 |

This is the **title**

924 | This is the *content* 925 |
926 | ``` 927 | 928 |
929 |
This is the **title**
930 | This is the *content* 931 |
932 | 933 | During the Sphinx render, both the `class` and `name` attributes will be used by Sphinx, but any other attributes like `style` will be discarded. 934 | 935 | :::{warning} 936 | There can be no empty lines in the block, otherwise they will be read as two separate blocks. 937 | If you want to use multiple paragraphs then they can be enclosed in `

`: 938 | 939 | ```html 940 |

941 |

Paragraph 1

942 |

Paragraph 2

943 |
944 | ``` 945 | 946 |
947 |

Paragraph 1

948 |

Paragraph 2

949 |
950 | 951 | ::: 952 | 953 | You can also nest HTML admonitions: 954 | 955 | ```html 956 |
957 |

Some **content**

958 |
959 |
A *title*
960 |

Paragraph 1

961 |

Paragraph 2

962 |
963 |
964 | ``` 965 | 966 |
967 |

Some **content**

968 |
969 |
A *title*
970 |

Paragraph 1

971 |

Paragraph 2

972 |
973 |
974 | 975 | (syntax/amsmath)= 976 | 977 | ## Direct LaTeX Math 978 | 979 | By adding `"amsmath"` to `myst_enable_extensions` (in the {{ confpy }}), 980 | you can enable direct parsing of [amsmath](https://ctan.org/pkg/amsmath) LaTeX equations. 981 | These top-level math environments will then be directly parsed: 982 | 983 | > equation, multline, gather, align, alignat, flalign, matrix, pmatrix, bmatrix, Bmatrix, vmatrix, Vmatrix, eqnarray. 984 | 985 | As expected, environments ending in `*` will not be numbered, for example: 986 | 987 | ```latex 988 | \begin{gather*} 989 | a_1=b_1+c_1\\ 990 | a_2=b_2+c_2-d_2+e_2 991 | \end{gather*} 992 | 993 | \begin{align} 994 | a_{11}& =b_{11}& 995 | a_{12}& =b_{12}\\ 996 | a_{21}& =b_{21}& 997 | a_{22}& =b_{22}+c_{22} 998 | \end{align} 999 | ``` 1000 | 1001 | \begin{gather*} 1002 | a_1=b_1+c_1\\ 1003 | a_2=b_2+c_2-d_2+e_2 1004 | \end{gather*} 1005 | 1006 | \begin{align} 1007 | a_{11}& =b_{11}& 1008 | a_{12}& =b_{12}\\ 1009 | a_{21}& =b_{21}& 1010 | a_{22}& =b_{22}+c_{22} 1011 | \end{align} 1012 | 1013 | :::{note} 1014 | `\labels` inside the environment are not currently identified, and so cannot be referenced. 1015 | We hope to implement this in a future update (see [executablebooks/MyST-Parser#202](https://github.com/executablebooks/MyST-Parser/issues/202))! 1016 | ::: 1017 | 1018 | :::{important} 1019 | See also [how Mathjax is configured with MyST-Parser](syntax/mathjax). 1020 | ::: 1021 | 1022 | This syntax will also work when nested in other block elements, like lists or quotes: 1023 | 1024 | ```md 1025 | - A list 1026 | - \begin{gather*} 1027 | a_1=b_1+c_1\\a_2=b_2+c_2-d_2+e_2 1028 | \end{gather*} 1029 | 1030 | > A block quote 1031 | > \begin{gather*} 1032 | a_1=b_1+c_1\\a_2=b_2+c_2-d_2+e_2 1033 | \end{gather*} 1034 | ``` 1035 | 1036 | - A list 1037 | - \begin{gather*} 1038 | a_1=b_1+c_1\\a_2=b_2+c_2-d_2+e_2 1039 | \end{gather*} 1040 | 1041 | > A block quote 1042 | > \begin{gather*} 1043 | a_1=b_1+c_1\\a_2=b_2+c_2-d_2+e_2 1044 | \end{gather*} 1045 | -------------------------------------------------------------------------------- /docs/syntax/reference.md: -------------------------------------------------------------------------------- 1 | (syntax-tokens)= 2 | # Syntax tokens 3 | 4 | This page serves as a reference for the syntax that makes of MyST Markdown. 5 | 6 | :::{seealso} 7 | For more description and explanation of MyST syntax, see the [syntax guide](syntax.md). 8 | ::: 9 | 10 | ## Block (Multi-line) Tokens 11 | 12 | Block tokens span multiple lines of content. They are broken down into two sections: 13 | 14 | - {ref}`extended-block-tokens` contains *extra* tokens that are not in CommonMark. 15 | - {ref}`commonmark-block-tokens` contains CommonMark tokens that also work, for reference. 16 | 17 | :::{note} 18 | Because MyST markdown was inspired by functionality that exists in reStructuredText, 19 | we have shown equivalent rST syntax for many MyST markdown features below. 20 | ::: 21 | 22 | (extended-block-tokens)= 23 | ### Extended block tokens 24 | 25 | `````{list-table} 26 | :header-rows: 1 27 | :widths: 10 20 20 28 | 29 | * - Token 30 | - Description 31 | - Example 32 | * - FrontMatter 33 | - A YAML block at the start of the document enclosed by `---` 34 | - ```yaml 35 | --- 36 | key: value 37 | --- 38 | ``` 39 | * - Directives 40 | - enclosed in 3 or more backticks followed by the directive name wrapped 41 | in curly brackets `{}`. See {ref}`syntax/directives` for more details. 42 | - ````md 43 | ```{directive} 44 | :option: value 45 | 46 | content 47 | ``` 48 | ```` 49 | * - Math 50 | - `$$` (default) or `\[`...`\]` characters wrapping multi-line math, or even direct [amsmath](https://ctan.org/pkg/amsmath) LaTeX equations (optional). 51 | See {ref}`syntax/math` for more information. 52 | - ```latex 53 | $$ 54 | a=1 55 | $$ 56 | ``` 57 | * - Table 58 | - Standard markdown table style, with pipe separation. 59 | - ```md 60 | | a | b | 61 | | :--- | ---: | 62 | | c | d | 63 | ``` 64 | * - LineComment 65 | - A commented line. See {ref}`syntax/comments` for more information. 66 | - ```latex 67 | % this is a comment 68 | ``` 69 | * - BlockBreak 70 | - Define blocks of text. See {ref}`syntax/blockbreaks` for more information. 71 | - ```md 72 | +++ {"meta": "data"} 73 | ``` 74 | * - Footnote 75 | - A definition for a referencing footnote, that is placed at the bottom of the document. 76 | See {ref}`syntax/footnotes` for more details. 77 | - ```md 78 | [^ref]: Some footnote text 79 | ``` 80 | * - Admonitions (optional) 81 | - An alternative approach for admonition style directives only, which has the benefit of allowing the content to be rendered in standard markdown editors. 82 | See [admonition directives](syntax/admonitions) for more details. 83 | - ````md 84 | :::{note} 85 | *content* 86 | ::: 87 | ```` 88 | ````` 89 | 90 | (commonmark-block-tokens)= 91 | ### CommonMark tokens 92 | 93 | `````{list-table} 94 | :header-rows: 1 95 | :widths: 10 20 20 96 | 97 | * - Token 98 | - Description 99 | - Example 100 | * - HTMLBlock 101 | - Any valid HTML (rendered in HTML output only) 102 | - ```html 103 |

some text

104 | ``` 105 | * - BlockCode 106 | - indented text (4 spaces or a tab) 107 | - ```md 108 | included as literal *text* 109 | ``` 110 | * - Heading 111 | - Level 1-6 headings, denoted by number of `#` 112 | - ```md 113 | ### Heading level 3 114 | ``` 115 | * - SetextHeading 116 | - Underlined header (using multiple `=` or `-`) 117 | - ```md 118 | Header 119 | ====== 120 | ``` 121 | * - Quote 122 | - Quoted text 123 | - ```md 124 | > this is a quote 125 | ``` 126 | * - CodeFence 127 | - Enclosed in 3 or more `` ` `` or `~` with an optional language name. 128 | See {ref}`syntax/code-blocks` for more information. 129 | - ````md 130 | ```python 131 | print('this is python') 132 | ``` 133 | ```` 134 | * - ThematicBreak 135 | - Creates a horizontal line in the output 136 | - ```md 137 | --- 138 | ``` 139 | * - List 140 | - bullet points or enumerated. 141 | - ```md 142 | - item 143 | - nested item 144 | 1. numbered item 145 | ``` 146 | * - LinkDefinition 147 | - A substitution for an inline link, which can have a reference target (no spaces), and an optional title (in `"`) 148 | - ```md 149 | [key]: https://www.google.com "a title" 150 | ``` 151 | * - Paragraph 152 | - General inline text 153 | - ```md 154 | any *text* 155 | ``` 156 | ````` 157 | 158 | ## Span (Inline) Tokens 159 | 160 | Span (or inline) tokens are defined on a single line of content. They are broken down into two 161 | sections below: 162 | 163 | - {ref}`extended-span-tokens` contains *extra* tokens that are not in CommonMark. 164 | - {ref}`commonmark-span-tokens` contains CommonMark tokens that also work, for reference. 165 | 166 | (extended-span-tokens)= 167 | ### Extended inline tokens 168 | 169 | `````{list-table} 170 | :header-rows: 1 171 | :widths: 10 20 20 172 | 173 | * - Token 174 | - Description 175 | - Example 176 | * - Role 177 | - See {ref}`syntax/roles` for more information. 178 | - ```md 179 | {rolename}`interpreted text` 180 | ``` 181 | * - Target 182 | - Precedes element to target, e.g. header. See 183 | {ref}`syntax/targets` for more information. 184 | - ```md 185 | (target)= 186 | ``` 187 | * - Math 188 | - `$` (default) or `\(`...`\)` enclosed math. See 189 | {ref}`syntax/math` for more information. 190 | - ```latex 191 | $a=1$ or $$a=1$$ 192 | ``` 193 | * - FootReference 194 | - Reference a footnote. See {ref}`syntax/footnotes` for more details. 195 | - ```md 196 | [^abc] 197 | ``` 198 | ````` 199 | 200 | (commonmark-span-tokens)= 201 | ### CommonMark inline tokens 202 | 203 | `````{list-table} 204 | :header-rows: 1 205 | :widths: 10 20 20 206 | 207 | * - Token 208 | - Description 209 | - Example 210 | * - HTMLSpan 211 | - Any valid HTML (rendered in HTML output only) 212 | - ```html 213 |

some text

214 | ``` 215 | * - EscapeSequence 216 | - Escaped symbols (to avoid them being interpreted as other syntax elements) 217 | - ```md 218 | \* 219 | ``` 220 | * - AutoLink 221 | - Link that is shown in final output 222 | - ```md 223 | 224 | ``` 225 | * - InlineCode 226 | - Literal text 227 | - ```md 228 | `a=1` 229 | ``` 230 | * - LineBreak 231 | - Soft or hard (ends with spaces or backslash) 232 | - ```md 233 | A hard break\ 234 | ``` 235 | * - Image 236 | - Link to an image. 237 | You can also use HTML syntax, to include image size etc, [see here](syntax/images) for details 238 | - ```md 239 | ![alt](src "title") 240 | ``` 241 | * - Link 242 | - Reference `LinkDefinitions`. See {ref}`syntax/referencing` for more details. 243 | - ```md 244 | [text](target "title") or [text][key] 245 | ``` 246 | * - Strong 247 | - Bold text 248 | - ```md 249 | **strong** 250 | ``` 251 | * - Emphasis 252 | - Italic text 253 | - ```md 254 | *emphasis* 255 | ``` 256 | * - RawText 257 | - Any text 258 | - ```md 259 | any text 260 | ``` 261 | ````` 262 | -------------------------------------------------------------------------------- /docs/syntax/roles-and-directives.md: -------------------------------------------------------------------------------- 1 | (roles-directives)= 2 | 3 | # Roles and Directives 4 | 5 | Roles and directives provide a way to extend the syntax of MyST in an unbound manner, 6 | by interpreting a chuck of text as a specific type of markup, according to its name. 7 | 8 | Mostly all 9 | [docutils roles](https://docutils.sourceforge.io/docs/ref/rst/roles.html), 10 | [docutils directives](https://docutils.sourceforge.io/docs/ref/rst/directives.html), 11 | [Sphinx roles](inv:sphinx#usage/*/roles), or 12 | [Sphinx directives](inv:sphinx#usage/*/directives) 13 | can be used in MyST. 14 | 15 | ## Syntax 16 | 17 | (syntax/directives)= 18 | 19 | ### Directives - a block-level extension point 20 | 21 | Directives syntax is defined with triple-backticks and curly-brackets. 22 | It is effectively a Markdown code fence with curly brackets around the language, and a directive name in place of a language name. 23 | Here is the basic structure: 24 | 25 | `````{list-table} 26 | --- 27 | header-rows: 1 28 | --- 29 | * - MyST 30 | - reStructuredText 31 | * - ````md 32 | ```{directivename} arguments 33 | --- 34 | key1: val1 35 | key2: val2 36 | --- 37 | This is 38 | directive content 39 | ``` 40 | ```` 41 | - ```rst 42 | .. directivename:: arguments 43 | :key1: val1 44 | :key2: val2 45 | 46 | This is 47 | directive content 48 | ``` 49 | ````` 50 | 51 | For example, the following code: 52 | 53 | ````md 54 | ```{admonition} This is my admonition 55 | This is my note 56 | ``` 57 | ```` 58 | 59 | Will generate this admonition: 60 | 61 | ```{admonition} This is my admonition 62 | This is my note 63 | ``` 64 | 65 | #### Parameterizing directives 66 | 67 | For directives that take parameters as input, there are two ways to parameterize them. 68 | In each case, the options themselves are given as `key: value` pairs. An example of 69 | each is shown below: 70 | 71 | **Using YAML frontmatter**. A block of YAML front-matter just after the 72 | first line of the directive will be parsed as options for the directive. This needs to be 73 | surrounded by `---` lines. Everything in between will be parsed by YAML and 74 | passed as keyword arguments to your directive. For example: 75 | 76 | ````md 77 | ```{code-block} python 78 | --- 79 | lineno-start: 10 80 | emphasize-lines: 1, 3 81 | caption: | 82 | This is my 83 | multi-line caption. It is *pretty nifty* ;-) 84 | --- 85 | a = 2 86 | print('my 1st line') 87 | print(f'my {a}nd line') 88 | ``` 89 | ```` 90 | 91 | ```{code-block} python 92 | --- 93 | lineno-start: 10 94 | emphasize-lines: 1, 3 95 | caption: | 96 | This is my 97 | multi-line caption. It is *pretty nifty* ;-) 98 | --- 99 | a = 2 100 | print('my 1st line') 101 | print(f'my {a}nd line') 102 | ``` 103 | 104 | **Short-hand options with `:` characters**. If you only need one or two options for your 105 | directive and wish to save lines, you may also specify directive options as a collection 106 | of lines just after the first line of the directive, each preceding with `:`. Then the 107 | leading `:` is removed from each line, and the rest is parsed as YAML. 108 | 109 | For example: 110 | 111 | ````md 112 | ```{code-block} python 113 | :lineno-start: 10 114 | :emphasize-lines: 1, 3 115 | 116 | a = 2 117 | print('my 1st line') 118 | print(f'my {a}nd line') 119 | ``` 120 | ```` 121 | 122 | (syntax/directives/parsing)= 123 | 124 | #### How directives parse content 125 | 126 | Some directives parse the content that is in their content block. 127 | MyST parses this content **as Markdown**. 128 | 129 | This means that MyST markdown can be written in the content areas of any directives written in MyST markdown. For example: 130 | 131 | ````md 132 | ```{admonition} My markdown link 133 | Here is [markdown link syntax](https://jupyter.org) 134 | ``` 135 | ```` 136 | 137 | ```{admonition} My markdown link 138 | Here is [markdown link syntax](https://jupyter.org) 139 | ``` 140 | 141 | As a short-hand for directives that require no arguments, and when no parameter options are used (see below), 142 | you may start the content directly after the directive name. 143 | 144 | ````md 145 | ```{note} Notes require **no** arguments, so content can start here. 146 | ``` 147 | ```` 148 | 149 | ```{note} Notes require **no** arguments, so content can start here. 150 | ``` 151 | 152 | For special cases, MySt also offers the `eval-rst` directive. 153 | This will parse the content **as ReStructuredText**: 154 | 155 | ````md 156 | ```{eval-rst} 157 | .. figure:: img/fun-fish.png 158 | :width: 100px 159 | :name: rst-fun-fish 160 | 161 | Party time! 162 | 163 | A reference from inside: :ref:`rst-fun-fish` 164 | 165 | A reference from outside: :ref:`syntax/directives/parsing` 166 | ``` 167 | ```` 168 | 169 | ```{eval-rst} 170 | .. figure:: img/fun-fish.png 171 | :width: 100px 172 | :name: rst-fun-fish 173 | 174 | Party time! 175 | 176 | A reference from inside: :ref:`rst-fun-fish` 177 | 178 | A reference from outside: :ref:`syntax/directives/parsing` 179 | ``` 180 | 181 | Note how the text is integrated into the rest of the document, so we can also reference [party fish](rst-fun-fish) anywhere else in the documentation. 182 | 183 | #### Nesting directives 184 | 185 | You can nest directives by ensuring that the tick-lines corresponding to the 186 | outermost directive are longer than the tick-lines for the inner directives. 187 | For example, nest a warning inside a note block like so: 188 | 189 | `````md 190 | ````{note} 191 | The next info should be nested 192 | ```{warning} 193 | Here's my warning 194 | ``` 195 | ```` 196 | ````` 197 | 198 | Here's how it looks rendered: 199 | 200 | ````{note} 201 | The next info should be nested 202 | ```{warning} 203 | Here's my warning 204 | ``` 205 | ```` 206 | 207 | You can indent inner-code fences, so long as they aren't indented by more than 3 spaces. 208 | Otherwise, they will be rendered as "raw code" blocks: 209 | 210 | `````md 211 | ````{note} 212 | The warning block will be properly-parsed 213 | 214 | ```{warning} 215 | Here's my warning 216 | ``` 217 | 218 | But the next block will be parsed as raw text 219 | 220 | ```{warning} 221 | Here's my raw text warning that isn't parsed... 222 | ``` 223 | ```` 224 | ````` 225 | 226 | ````{note} 227 | The warning block will be properly-parsed 228 | 229 | ```{warning} 230 | Here's my warning 231 | ``` 232 | 233 | But the next block will be parsed as raw text 234 | 235 | ```{warning} 236 | Here's my raw text warning that isn't parsed... 237 | ``` 238 | ```` 239 | 240 | This can really be abused if you'd like ;-) 241 | 242 | ``````{note} 243 | The next info should be nested 244 | `````{warning} 245 | Here's my warning 246 | ````{admonition} Yep another admonition 247 | ```python 248 | # All this fuss was about this boring python?! 249 | print('yep!') 250 | ``` 251 | ```` 252 | ````` 253 | `````` 254 | 255 | #### Markdown-friendly directives 256 | 257 | Want to use syntax that renders correctly in standard Markdown editors? 258 | See [the extended syntax option](syntax/colon_fence). 259 | 260 | ```md 261 | :::{note} 262 | This text is **standard** *Markdown* 263 | ::: 264 | ``` 265 | 266 | :::{note} 267 | This text is **standard** *Markdown* 268 | ::: 269 | 270 | (syntax/roles)= 271 | 272 | ### Roles - an in-line extension point 273 | 274 | Roles are similar to directives - they allow you to define arbitrary new functionality, but they are used *in-line*. 275 | To define an in-line role, use the following form: 276 | 277 | ````{list-table} 278 | --- 279 | header-rows: 1 280 | --- 281 | * - MyST 282 | - reStructuredText 283 | * - ````md 284 | {role-name}`role content` 285 | ```` 286 | - ```rst 287 | :role-name:`role content` 288 | ``` 289 | ```` 290 | 291 | For example, the following code: 292 | 293 | ```md 294 | Since Pythagoras, we know that {math}`a^2 + b^2 = c^2` 295 | ``` 296 | 297 | Becomes: 298 | 299 | Since Pythagoras, we know that {math}`a^2 + b^2 = c^2` 300 | 301 | You can use roles to do things like reference equations and other items in 302 | your book. For example: 303 | 304 | ````md 305 | ```{math} e^{i\pi} + 1 = 0 306 | --- 307 | label: euler 308 | --- 309 | ``` 310 | 311 | Euler's identity, equation {math:numref}`euler`, was elected one of the 312 | most beautiful mathematical formulas. 313 | ```` 314 | 315 | Becomes: 316 | 317 | ```{math} e^{i\pi} + 1 = 0 318 | --- 319 | label: euler 320 | --- 321 | ``` 322 | 323 | Euler's identity, equation {math:numref}`euler`, was elected one of the 324 | most beautiful mathematical formulas. 325 | 326 | #### How roles parse content 327 | 328 | The content of roles is parsed differently depending on the role that you've used. 329 | Some roles expect inputs that will be used to change functionality. For example, 330 | the `ref` role will assume that input content is a reference to some other part of the 331 | site. However, other roles may use the MyST parser to parse the input as content. 332 | 333 | Some roles also **extend their functionality** depending on the content that you pass. 334 | For example, following the `ref` example above, if you pass a string like this: 335 | `Content to display `, then the `ref` will display `Content to display` and use 336 | `myref` as the reference to look up. 337 | 338 | How roles parse this content depends on the author that created the role. 339 | 340 | ## Common roles and directives 341 | 342 | :::{admonition} {material-regular}`engineering;1.5rem;sd-mr-1` Currently Under Construction 343 | :class: no-icon 344 | Check back for more... 345 | ::: 346 | 347 | ### ToC Trees 348 | 349 | ```{doc-directive} contents 350 | Insert a table of contents tree of the documents headings. 351 | ``` 352 | 353 | ```{doc-directive} toctree 354 | Inserts a Sphinx "Table of Contents" tree, containing a list of (relative) child document paths. 355 | ``` 356 | 357 | ### Admonitions 358 | 359 | ```{doc-directive} admonition 360 | Create a generic "callout" box, containing the content. 361 | ``` 362 | 363 | ```{doc-directive} note 364 | Create a "callout" box, specific to notes, containing the content. 365 | ``` 366 | 367 | Other admonitions (same structure as `note`): `attention`, `caution`, `danger`, `error`, `hint`, `important`, `tip`, `warning`. 368 | 369 | Sphinx only: `deprecated`, `versionadded`, `versionchanged`. 370 | 371 | ### Images and Figures 372 | 373 | ```{doc-directive} image 374 | Insert an image, from a (relative) path or URL. 375 | ``` 376 | 377 | ```{doc-directive} figure 378 | Insert an image, from a (relative) path or URL, 379 | with a caption (first paragraph), and optional legend (subsequent content). 380 | ``` 381 | 382 | ```{doc-directive} table 383 | Insert a (MyST) table with a caption. 384 | ``` 385 | 386 | ### Tables 387 | 388 | ```{doc-directive} list-table 389 | Create a table from data in a uniform two-level bullet list. 390 | ``` 391 | 392 | ```{doc-directive} csv-table 393 | Create a table from CSV (comma-separated values) data. 394 | ``` 395 | 396 | ### Code 397 | 398 | ```{doc-directive} code-block 399 | Syntax highlight a block of code, according to the language. 400 | ``` 401 | 402 | (syntax/roles/special)= 403 | 404 | ### MyST only 405 | 406 | This section contains information about special roles and directives that come bundled with the MyST Parser Sphinx extension. 407 | 408 | #### Insert the date and reading time 409 | 410 | ```{versionadded} 0.14.0 411 | The `sub-ref` role and word counting. 412 | ``` 413 | 414 | You may insert the "last updated" date and estimated reading time into your document via substitution definitions, which can be accessed *via* the `sub-ref` role. 415 | 416 | For example: 417 | 418 | ```markdown 419 | > {sub-ref}`today` | {sub-ref}`wordcount-words` words | {sub-ref}`wordcount-minutes` min read 420 | ``` 421 | 422 | > {sub-ref}`today` | {sub-ref}`wordcount-words` words | {sub-ref}`wordcount-minutes` min read 423 | 424 | `today` is replaced by either the date on which the document is parsed, with the format set by , or the `today` variable if set in the configuration file. 425 | 426 | The reading speed is computed using the `myst_words_per_minute` configuration (see the [Sphinx configuration options](sphinx/config-options)). 427 | -------------------------------------------------------------------------------- /docs/syntax/syntax.md: -------------------------------------------------------------------------------- 1 | (syntax/core)= 2 | 3 | # Core Syntax 4 | 5 | ## Introduction 6 | 7 | MyST is a strict superset of the [CommonMark syntax specification](https://spec.commonmark.org/). 8 | It adds features focussed on scientific and technical documentation authoring, as detailed below. 9 | 10 | In addition, the roles and directives syntax provide inline/block-level extension points for plugins. 11 | This is detailed further in the [Roles and Directives](roles-directives) section. 12 | 13 | :::{seealso} 14 | The [syntax token reference tables](syntax-tokens) 15 | ::: 16 | 17 | (syntax/commonmark)= 18 | 19 | ## CommonMark 20 | 21 | The [CommonMark syntax specification](https://spec.commonmark.org/) details the full set of syntax rules. 22 | Here we provide a summary of most features: 23 | 24 | Element | Syntax 25 | --------------- | ------------------------------------------- 26 | Heading | `# H1` to `###### H6` 27 | Bold | `**bold**` 28 | Italic | `*italic*` 29 | Inline Code | `` `code` `` 30 | Autolink | `` 31 | URL Link | `[title](https://www.example.com)` 32 | Image | `![alt](https://www.example.com/image.png)` 33 | Reference Link | `[title][link]` 34 | Link Definition | `[link]: https://www.example.com` 35 | Thematic break | `---` 36 | Blockquote | `> quote` 37 | Ordered List | `1. item` 38 | Unordered List | `- item` 39 | Code Fence | opening ```` ```lang ```` to closing ```` ``` ```` 40 | 41 | (syntax/frontmatter)= 42 | 43 | ## Front Matter 44 | 45 | This is a [YAML](https://en.wikipedia.org/wiki/YAML) block at the start of the document, as used for example in [jekyll](https://jekyllrb.com/docs/front-matter/). 46 | The document should start with three or more `---` markers, and YAML is parsed until a closing `---` marker is found: 47 | 48 | ```yaml 49 | --- 50 | key1: value 51 | key2: [value1, value2] 52 | key3: 53 | subkey1: value 54 | --- 55 | ``` 56 | 57 | :::{seealso} 58 | Top-matter is also used for the [substitution syntax extension](syntax/substitutions), 59 | and can be used to store information for blog posting (see [ablog's myst-parser support](https://ablog.readthedocs.io/en/latest/manual/markdown/)). 60 | ::: 61 | 62 | ### Setting a title 63 | 64 | ```{versionadded} 0.17.0 65 | ``` 66 | 67 | If `myst_title_to_header` is set to `True`, and a `title` key is present in the front matter, 68 | then the title will be used as the document's header (parsed as Markdown). 69 | For example: 70 | 71 | ```md 72 | --- 73 | title: My Title with *emphasis* 74 | --- 75 | ``` 76 | 77 | would be equivalent to: 78 | 79 | ```md 80 | # My Title with *emphasis* 81 | ``` 82 | 83 | (syntax/html_meta)= 84 | 85 | ### Setting HTML Metadata 86 | 87 | The front-matter can contain the special key `html_meta`; a dict with data to add to the generated HTML as [`` elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta). 88 | This is equivalent to using the [meta directive](inv:sphinx#html-meta). 89 | 90 | HTML metadata can also be added globally in the `conf.py` *via* the `myst_html_meta` variable, in which case it will be added to all MyST documents. 91 | For each document, the `myst_html_meta` dict will be updated by the document level front-matter `html_meta`, with the front-matter taking precedence. 92 | 93 | ::::{tab-set} 94 | :::{tab-item} Sphinx Configuration 95 | 96 | ```python 97 | language = "en" 98 | myst_html_meta = { 99 | "description lang=en": "metadata description", 100 | "description lang=fr": "description des métadonnées", 101 | "keywords": "Sphinx, MyST", 102 | "property=og:locale": "en_US" 103 | } 104 | ``` 105 | 106 | ::: 107 | 108 | :::{tab-item} MyST Front-Matter 109 | 110 | ```yaml 111 | --- 112 | myst: 113 | html_meta: 114 | "description lang=en": "metadata description" 115 | "description lang=fr": "description des métadonnées" 116 | "keywords": "Sphinx, MyST" 117 | "property=og:locale": "en_US" 118 | --- 119 | ``` 120 | 121 | ::: 122 | 123 | :::{tab-item} RestructuredText 124 | 125 | ```restructuredtext 126 | .. meta:: 127 | :description lang=en: metadata description 128 | :description lang=fr: description des métadonnées 129 | :keywords: Sphinx, MyST 130 | :property=og:locale: en_US 131 | ``` 132 | 133 | ::: 134 | 135 | :::{tab-item} HTML Output 136 | 137 | ```html 138 | 139 | 140 | 141 | 142 | 143 | 144 | ``` 145 | 146 | ::: 147 | :::: 148 | 149 | (syntax/comments)= 150 | 151 | ## Comments 152 | 153 | You may add comments by putting the `%` character at the beginning of a line. This will 154 | prevent the line from being parsed into the output document. 155 | 156 | For example, this code: 157 | 158 | ```md 159 | % my comment 160 | ``` 161 | 162 | Is below, but it won't be parsed into the document. 163 | 164 | % my comment 165 | 166 | ````{important} 167 | Since comments are a block-level entity, they will terminate the previous block. 168 | In practical terms, this means that the following lines 169 | will be broken up into two paragraphs, resulting in a new line between them: 170 | 171 | ``` 172 | a line 173 | % a comment 174 | another line 175 | ``` 176 | 177 | a line 178 | % a comment 179 | another line 180 | ```` 181 | 182 | :::{tip} 183 | Comments are equivalent to the RST syntax: `.. my comment`. 184 | ::: 185 | 186 | (syntax/blockbreaks)= 187 | 188 | ## Block Breaks 189 | 190 | You may add a block break by putting `+++` at the beginning of a line. 191 | This constuct's intended use case is for mapping to cell based document formats, 192 | like [jupyter notebooks](https://jupyter.org/), 193 | to indicate a new text cell. It will not show up in the rendered text, 194 | but is stored in the internal document structure for use by developers. 195 | 196 | For example, this code: 197 | 198 | ```md 199 | +++ some text 200 | ``` 201 | 202 | Is below, but it won't be parsed into the document. 203 | 204 | +++ 205 | 206 | (syntax/referencing)= 207 | 208 | ## Markdown Links and Referencing 209 | 210 | ### CommonMark link format 211 | 212 | CommonMark links come in three forms ([see the spec](https://spec.commonmark.org/0.30/#links)): 213 | 214 | *Autolinks* are [URIs][uri] surrounded by `<` and `>`, which must always have a scheme: 215 | 216 | ```md 217 | 218 | ``` 219 | 220 | *Inline links* allow for optional explicit text and titles (in HTML titles are rendered as tooltips): 221 | 222 | ```md 223 | [Explicit *Markdown* text](destination "optional explicit title") 224 | ``` 225 | 226 | or, if the destination contains spaces, 227 | 228 | ```md 229 | [Explicit *Markdown* text]( "optional explicit title") 230 | ``` 231 | 232 | *Reference links* define the destination separately in the document, and can be used multiple times: 233 | 234 | ```md 235 | [Explicit *Markdown* text][label] 236 | [Another link][label] 237 | 238 | [label]: destination "optional explicit title" 239 | ``` 240 | 241 | [uri]: https://en.wikipedia.org/wiki/Uniform_Resource_Identifier 242 | [url]: https://en.wikipedia.org/wiki/URL 243 | 244 | ### Default destination resolution 245 | 246 | The destination of a link can resolve to either an **external** target, such as a [URL] to another website, 247 | or an **internal** target, such as a file, heading or figure within the same project. 248 | 249 | By default, MyST will resolve link destinations according to the following rules: 250 | 251 | 1. All autolinks will be treated as external [URL] links. 252 | 253 | 2. Destinations beginning with `http:`, `https:`, `ftp:`, or `mailto:` will be treated as external [URL] links. 254 | 255 | 3. Destinations which point to a local file path are treated as links to that file. 256 | - The path must be relative and in [POSIX format](https://en.wikipedia.org/wiki/Path_(computing)#POSIX_and_Unix_paths) (i.e. `/` separators). 257 | - If the path is to another source file in the project (e.g. a `.md` or `.rst` file), 258 | then the link will be to the initial heading in that file or, 259 | if the path is appended by a `#target`, to the heading "slug" in that file. 260 | - If the path is to a non-source file (e.g. a `.png` or `.pdf` file), 261 | then the link will be to the file itself, e.g. to download it. 262 | 263 | 4. Destinations beginning with `#` will be treated as a link to a heading "slug" in the same file. 264 | - This requires the `myst_heading_anchors` configuration be set. 265 | - For more details see [](syntax/header-anchors). 266 | 267 | 5. All other destinations are treated as internal references, which can link to any type of target within the project (see [](syntax/targets)). 268 | 269 | Here are some examples: 270 | 271 | :::{list-table} 272 | :header-rows: 1 273 | 274 | * - Type 275 | - Syntax 276 | - Rendered 277 | 278 | * - Autolink 279 | - `` 280 | - 281 | 282 | * - External URL 283 | - `[example.com](https://example.com)` 284 | - [example.com](https://example.com) 285 | 286 | * - Internal source file 287 | - `[Source file](syntax.md)` 288 | - [Source file](syntax.md) 289 | 290 | * - Internal non-source file 291 | - `[Non-source file](example.txt)` 292 | - [Non-source file](example.txt) 293 | 294 | * - Local heading 295 | - `[Heading](#markdown-links-and-referencing)` 296 | - [Heading](#markdown-links-and-referencing) 297 | 298 | * - Heading in another file 299 | - `[Heading](optional.md#auto-generated-header-anchors)` 300 | - [Heading](optional.md#auto-generated-header-anchors) 301 | 302 | ::: 303 | 304 | ### Customising destination resolution 305 | 306 | You can customise the default destination resolution rules by setting the following [configuration options](../configuration.md): 307 | 308 | `myst_all_links_external` (default: `False`) 309 | : If `True`, then all links will be treated as external links. 310 | 311 | `myst_url_schemes` (default: `["http", "https", "ftp", "mailto"]`) 312 | : A list of [URL] schemes which will be treated as external links. 313 | 314 | `myst_ref_domains` (default: `[]`) 315 | : A list of [sphinx domains](inv:sphinx#domain) which will be allowed for internal links. 316 | For example, `myst_ref_domains = ("std", "py")` will only allow cross-references to `std` and `py` domains. 317 | If the list is empty, then all domains will be allowed. 318 | 319 | (syntax/inv_links)= 320 | ### Cross-project (inventory) links 321 | 322 | :::{versionadded} 0.19 323 | This functionality is currently in *beta*. 324 | It is intended that eventually it will be part of the core syntax. 325 | ::: 326 | 327 | Each Sphinx HTML build creates a file named `objects.inv` that contains a mapping from referenceable objects to [URIs][uri] relative to the HTML set’s root. 328 | Each object is uniquely identified by a `domain`, `type`, and `name`. 329 | As well as the relative location, the object can also include implicit `text` for the reference (like the text for a heading). 330 | 331 | You can use the `myst-inv` command line tool (installed with `myst_parser`) to visualise and filter any remote URL or local file path to this inventory file (or its parent): 332 | 333 | ```yaml 334 | # $ myst-inv https://www.sphinx-doc.org/en/master -n index 335 | name: Sphinx 336 | version: 6.2.0 337 | base_url: https://www.sphinx-doc.org/en/master 338 | objects: 339 | rst: 340 | role: 341 | index: 342 | loc: usage/restructuredtext/directives.html#role-index 343 | text: null 344 | std: 345 | doc: 346 | index: 347 | loc: index.html 348 | text: Welcome 349 | ``` 350 | 351 | To load external inventories into your Sphinx project, you must load the [`sphinx.ext.intersphinx` extension](inv:sphinx#usage/*/intersphinx), and set the `intersphinx_mapping` configuration option. 352 | Then also enable the `inv_link` MyST extension e.g.: 353 | 354 | ```python 355 | extensions = ["myst_parser", "sphinx.ext.intersphinx"] 356 | intersphinx_mapping = { 357 | "sphinx": ("https://www.sphinx-doc.org/en/master", None), 358 | } 359 | myst_enable_extensions = ["inv_link"] 360 | ``` 361 | 362 | :::{dropdown} Docutils configuration 363 | 364 | Use the `docutils.conf` configuration file, for more details see [](myst-docutils). 365 | 366 | ```ini 367 | [general] 368 | myst-inventories: 369 | sphinx: ["https://www.sphinx-doc.org/en/master", null] 370 | myst-enable-extensions: inv_link 371 | ``` 372 | 373 | ::: 374 | 375 | you can then reference inventory objects by prefixing the `inv` schema to the destination [URI]: `inv:key:domain:type#name`. 376 | 377 | `key`, `domain` and `type` are optional, e.g. for `inv:#name`, all inventories, domains and types will be searched, with a [warning emitted](myst-warnings) if multiple matches are found. 378 | 379 | Additionally, `*` is a wildcard which matches zero or characters, e.g. `inv:*:std:doc#a*` will match all `std:doc` objects in all inventories, with a `name` beginning with `a`. 380 | Note, to match to a literal `*` use `\*`. 381 | 382 | Here are some examples: 383 | 384 | :::{list-table} 385 | :header-rows: 1 386 | 387 | * - Type 388 | - Syntax 389 | - Rendered 390 | 391 | * - Autolink, full 392 | - `` 393 | - 394 | 395 | * - Link, full 396 | - `[Sphinx](inv:sphinx:std:doc#index)` 397 | - [Sphinx](inv:sphinx:std:doc#index) 398 | 399 | * - Autolink, no type 400 | - `` 401 | - 402 | 403 | * - Autolink, no domain 404 | - `` 405 | - 406 | 407 | * - Autolink, only name 408 | - `` 409 | - 410 | 411 | ::: 412 | 413 | (syntax/targets)= 414 | 415 | ## Targets and Cross-Referencing 416 | 417 | Targets are used to define custom anchors that you can refer to elsewhere in your 418 | documentation. They generally go before section titles so that you can easily refer 419 | to them. 420 | 421 | :::{tip} 422 | 423 | If you'd like to *automatically* generate targets for each of your section headers, 424 | check out the [](syntax/header-anchors) section of extended syntaxes. 425 | 426 | ::: 427 | 428 | Target headers are defined with this syntax: 429 | 430 | ```md 431 | (header_target)= 432 | ``` 433 | 434 | They can then be referred to with the 435 | [`ref` inline role](inv:sphinx#ref-role): 436 | 437 | ```md 438 | {ref}`header_target` 439 | ``` 440 | 441 | By default, the reference will use the text of the target (such as the section title), but also you can directly specify the text: 442 | 443 | ```md 444 | {ref}`my text ` 445 | ``` 446 | 447 | For example, see this ref: {ref}`syntax/targets`, and here's a ref back to the top of this page: {ref}`my text `. 448 | 449 | Alternatively using the markdown syntax: 450 | 451 | ```md 452 | [my text](header_target) 453 | ``` 454 | 455 | is equivalent to using the [`any` inline role](inv:sphinx#any-role): 456 | 457 | ```md 458 | {any}`my text ` 459 | ``` 460 | 461 | but can also accept "nested" syntax (like bold text) and will recognise document paths that include extensions (e.g. `syntax/syntax` or `syntax/syntax.md`) 462 | 463 | Using the same example, see this ref: [](syntax/targets), here is a reference back to the top of 464 | this page: [my text with **nested** $\alpha$ syntax](syntax/core), and here is a reference to another page (`[](../intro.md)`): [](../intro.md). 465 | 466 | ```{note} 467 | If you wish to have the target's title inserted into your text, you can 468 | leave the "text" section of the markdown link empty. For example, this 469 | markdown: `[](syntax.md)` will result in: [](syntax.md). 470 | ``` 471 | 472 | (syntax/code-blocks)= 473 | ## Code syntax highlighting 474 | 475 | Code blocks contain a language identifier, which is used to determine the language of the code. 476 | This language is used to determine the syntax highlighting, using an available [pygments lexer](https://pygments.org/docs/lexers/). 477 | 478 | ````markdown 479 | ```python 480 | from a import b 481 | c = "string" 482 | ``` 483 | ```` 484 | 485 | ```python 486 | from a import b 487 | c = "string" 488 | ``` 489 | 490 | You can create and register your own lexer, using the [`pygments.lexers` entry point](https://pygments.org/docs/plugins/#register-plugins), 491 | or within a sphinx extension, with the [`app.add_lexer` method](inv:sphinx#*.Sphinx.add_lexer). 492 | 493 | Using the `myst_number_code_blocks` configuration option, you can also control whether code blocks are numbered by line. 494 | For example, using `myst_number_code_blocks = ["typescript"]`: 495 | 496 | ```typescript 497 | type MyBool = true | false; 498 | 499 | interface User { 500 | name: string; 501 | id: number; 502 | } 503 | ``` 504 | 505 | ### Show backticks inside raw markdown blocks 506 | 507 | If you'd like to show backticks inside of your markdown, you can do so by nesting them 508 | in backticks of a greater length. Markdown will treat the outer-most backticks as the 509 | edges of the "raw" block and everything inside will show up. For example: 510 | 511 | ``` `` `hi` `` ``` will be rendered as: `` `hi` `` 512 | 513 | and 514 | 515 | ````` 516 | ```` 517 | ``` 518 | hi 519 | ``` 520 | ```` 521 | ````` 522 | 523 | will be rendered as: 524 | 525 | ```` 526 | ``` 527 | hi 528 | ``` 529 | ```` 530 | 531 | ## Tables 532 | 533 | Tables can be written using the standard [Github Flavoured Markdown syntax](https://github.github.com/gfm/#tables-extension-): 534 | 535 | ```md 536 | | foo | bar | 537 | | --- | --- | 538 | | baz | bim | 539 | ``` 540 | 541 | | foo | bar | 542 | | --- | --- | 543 | | baz | bim | 544 | 545 | Cells in a column can be aligned using the `:` character: 546 | 547 | ```md 548 | | left | center | right | 549 | | :--- | :----: | ----: | 550 | | a | b | c | 551 | ``` 552 | 553 | | left | center | right | 554 | | :--- | :----: | ----: | 555 | | a | b | c | 556 | 557 | :::{note} 558 | 559 | Text is aligned by assigning `text-left`, `text-center`, or `text-right` to the cell. 560 | It is then necessary for the theme you are using to include the appropriate css styling. 561 | 562 | ```html 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 |

left

a

571 | ``` 572 | 573 | ::: 574 | 575 | ## Images 576 | 577 | MyST provides a few different syntaxes for including images in your documentation. 578 | 579 | The standard Markdown syntax is: 580 | 581 | ```md 582 | ![fishy](img/fun-fish.png) 583 | ``` 584 | 585 | ![fishy](img/fun-fish.png) 586 | 587 | But you can also enable extended image syntaxes, to control attributes like width and captions. 588 | See the [extended image syntax guide](syntax/images). 589 | 590 | (syntax/footnotes)= 591 | ## Footnotes 592 | 593 | Footnotes use the [pandoc specification](https://pandoc.org/MANUAL.html#footnotes). 594 | Their labels **start with `^`** and can then be any alphanumeric string (no spaces), which is case-insensitive. 595 | 596 | - If the label is an integer, then it will always use that integer for the rendered label (i.e. they are manually numbered). 597 | - For any other labels, they will be auto-numbered in the order which they are referenced, skipping any manually numbered labels. 598 | 599 | All footnote definitions are collected, and displayed at the bottom of the page (in the order they are referenced). 600 | Note that un-referenced footnote definitions will not be displayed. 601 | 602 | ```md 603 | - This is a manually-numbered footnote reference.[^3] 604 | - This is an auto-numbered footnote reference.[^myref] 605 | 606 | [^myref]: This is an auto-numbered footnote definition. 607 | [^3]: This is a manually-numbered footnote definition. 608 | ``` 609 | 610 | - This is a manually-numbered footnote reference.[^3] 611 | - This is an auto-numbered footnote reference.[^myref] 612 | 613 | [^myref]: This is an auto-numbered footnote definition. 614 | [^3]: This is a manually-numbered footnote definition. 615 | 616 | Any preceding text after a footnote definitions, which is 617 | indented by four or more spaces, will also be included in the footnote definition, and the text is rendered as MyST Markdown, e.g. 618 | 619 | ```md 620 | A longer footnote definition.[^mylongdef] 621 | 622 | [^mylongdef]: This is the _**footnote definition**_. 623 | 624 | That continues for all indented lines 625 | 626 | - even other block elements 627 | 628 | Plus any preceding unindented lines, 629 | that are not separated by a blank line 630 | 631 | This is not part of the footnote. 632 | ``` 633 | 634 | A longer footnote definition.[^mylongdef] 635 | 636 | [^mylongdef]: This is the _**footnote definition**_. 637 | 638 | That continues for all indented lines 639 | 640 | - even other block elements 641 | 642 | Plus any subsequent unindented lines, 643 | that are not separated by a blank line 644 | 645 | This is not part of the footnote. 646 | 647 | ````{important} 648 | Although footnote references can be used just fine within directives, e.g.[^myref], 649 | it is recommended that footnote definitions are not set within directives, 650 | unless they will only be referenced within that same directive: 651 | 652 | ```md 653 | [^other] 654 | 655 | [^other]: A definition within a directive 656 | ``` 657 | 658 | [^other] 659 | 660 | [^other]: A definition within a directive 661 | 662 | This is because, in the current implementation, they may not be available to reference in text above that particular directive. 663 | ```` 664 | 665 | By default, a transition line (with a `footnotes` class) will be placed before any footnotes. 666 | This can be turned off by adding `myst_footnote_transition = False` to the config file. 667 | -------------------------------------------------------------------------------- /lumache.py: -------------------------------------------------------------------------------- 1 | """ 2 | Lumache - Python library for cooks and food lovers. 3 | """ 4 | 5 | __version__ = "0.1.0" 6 | 7 | 8 | class InvalidKindError(Exception): 9 | """Raised if the kind is invalid.""" 10 | pass 11 | 12 | 13 | def get_random_ingredients(kind=None): 14 | """ 15 | Return a list of random ingredients as strings. 16 | 17 | :param kind: Optional "kind" of ingredients. 18 | :type kind: list[str] or None 19 | :raise lumache.InvalidKindError: If the kind is invalid. 20 | :return: The ingredients list. 21 | :rtype: list[str] 22 | """ 23 | return ["shells", "gorgonzola", "parsley"] 24 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["flit_core >=3.2,<4","myst-parser >=0.18.1"] 3 | build-backend = "flit_core.buildapi" 4 | 5 | [project] 6 | name = "EasyPoi " 7 | authors = [{name = "夜雨微寒", email = "951683309@qq.com"}] 8 | dynamic = ["version", "description"] 9 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | myst-parser 2 | sphinx_design 3 | sphinx_pyscript 4 | --------------------------------------------------------------------------------