From 0ffed2688a0ee8dcefb7aeddf317b927c94981fe Mon Sep 17 00:00:00 2001 From: Chris Holdgraf <choldgraf@berkeley.edu> Date: Wed, 3 Feb 2021 13:40:35 -0800 Subject: [PATCH] =?UTF-8?q?=E2=AC=86=20UPDATE:=20myst-nb=200.11=20(#1189)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 91 ++++++ docs/_config.yml | 18 +- docs/advanced/sphinx.md | 15 +- docs/content/citations.md | 6 +- docs/content/content-blocks.md | 265 +++++++++++++++--- docs/content/figures.md | 41 +-- docs/content/math.md | 12 +- docs/content/myst.md | 18 +- docs/customize/toc.md | 3 +- docs/file-types/markdown.md | 8 +- docs/intro.md | 3 +- docs/reference/glossary.md | 1 + docs/requirements.txt | 1 - docs/start/overview.md | 12 +- jupyter_book/__init__.py | 2 +- jupyter_book/config.py | 38 ++- jupyter_book/config_schema.json | 10 +- jupyter_book/default_config.yml | 13 +- setup.py | 5 +- tests/test_config.py | 13 +- .../test_config_sphinx_command.txt | 1 + ...et_final_config_custom_myst_extensions.yml | 75 +++++ .../test_get_final_config_empty_.yml | 5 + ...est_get_final_config_exclude_patterns_.yml | 5 + .../test_get_final_config_execute_method_.yml | 5 + ...test_get_final_config_extended_syntax_.yml | 11 +- ...st_get_final_config_html_extra_footer_.yml | 5 + .../test_get_final_config_latex_doc_.yml | 5 + .../test_get_final_config_launch_buttons_.yml | 5 + .../test_get_final_config_repository_.yml | 5 + .../test_get_final_config_sphinx_.yml | 5 + .../test_get_final_config_title_.yml | 5 + 32 files changed, 595 insertions(+), 112 deletions(-) create mode 100644 tests/test_config/test_get_final_config_custom_myst_extensions.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index f6d4c16c..e996c6d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,96 @@ # Change Log +## v0.10.0 2021-02-01 + +[full changelog](https://github.com/executablebooks/jupyter-book/compare/v0.9.1...d3c78097edda4fefb672e32344c3806c9cdc7a72) | [GitHub contributors page for this release](https://github.com/executablebooks/jupyter-book/graphs/contributors?from=2020-12-22&to=2021-01-30&type=c) + +This update focuses on new syntax features for MyST markdown, as well as a new configuration to enable MyST extensions. See below for more details. + +### New + +**MyST Parser version 0.13.x** +: The MyST-NB and MyST-parser have both been upgraded. + This comes with support for new syntax and a new configuration mechanism (see below for some examples). + + See [the myst-parser changelog](https://myst-parser.readthedocs.io/en/latest/develop/_changelog.html#id4) for more information about the syntax additions. + +**New `myst` extension configuration** +: The `myst_extended_syntax` configuration is **now deprecated**, in lieu of a more flexible extension mechanism. + You may now enable individual `myst` extensions by adding them to the following section of your `_config.yml` file: + ```yaml + parse: + myst_enable_extensions: + - <list-of-extensions> + ``` + See [](content-blocks:myst-extensions) for more information. + +**Citations and references configuration** +: This version comes with a version bump to `sphinxcontrib.bibtex v2.1.*`. This introduces new configuration for connecting your bibfiles (no longer using the bibliography directive), and makes the citation resolution process much more stable and dependable. + See [](content:citations) for more information, and the [`sphinxcontrib.bibtex` documentation](https://sphinxcontrib-bibtex.readthedocs.io/en/latest/) for more information about updates in the latest version. + +**TOC depth numbering**. +: You can now set the depth of numbering (e.g., 3.2 vs. 3.2.1) via the the `numbered` flag in your Table of Contents. + + +### New MyST syntax + +**MyST Markdown substitutions** +: Substitutions allow you to define **variables** in markdown, and insert them elsewhere in your document. + This lets you change the variable value and have it automatically update throughout your book. + This is **on by default**. + See [](content:substitutions) for more information. + +**Automatic HTML links** +: The `linkify` extension will automatically identify “bare†web URLs, like `www.example.com`, and add hyperlinks; www.example.com. + This extension is **on by default**. + +**Smart Quotes** +: The `smartquotes` extension will automatically convert standard quotations to their opening/closing variants: + + - `'single quotes'`: ‘single quotes’ + - `"double quotes"`: “double quotes†+ + This extension is **off by default**. + See [](myst-parser:syntax/typography) for more details. + +**Typography replacements for common characters** +: The `replacements` extension will automatically convert some common typographic texts, such as `+-` -> `±`. + This extension is **off by default**. + See [](myst-parser:syntax/typography) for more details. + +**HTML admonitions** +: By adding `"html_admonition"` to `myst_enable_extensions`, you can enable parsing of `<div class="admonition">` HTML blocks to sphinx admonitions. + This is helpful when you care about viewing the "source" Markdown, such as in Jupyter Notebooks. + For example: + ```html + <div class="admonition note" name="html-admonition"> + <p class="title">This is the **title**</p> + This is the *content* + </div> + ``` + See [](content-blocks:html-admonitions) for further information. + This extension is **off by default**. + +### Deprecations + +**Colon fences now behave like directives** +: The `colon_fence` extension (replacing `admonition_enable`) now works exactly the same as normal ```` ``` ```` code fences, but using `:::` delimiters. + This is helpful for directives that contain Markdown text, for example: + + ```md + :::{admonition} The title + :class: note + + This note contains *Markdown* + ::: + ``` + +**`myst_extended_syntax` is deprecated** +: See above for new configuration details. + +**Bibliographies no longer use a path to a bibtex file**. +: See above for new configuration details. + ## v0.9.1 2020-12-22 This is a minor release to issue `v0.9` to PyPI and updates a broken link that prohibited the `v0.9.0` PyPI release action. diff --git a/docs/_config.yml b/docs/_config.yml index afa71850..5dbe1850 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -15,9 +15,6 @@ bibtex_bibfiles: execute: execute_notebooks: cache -parse: - myst_extended_syntax: true - html: favicon: images/favicon.ico google_analytics_id: UA-52617120-7 @@ -38,6 +35,21 @@ launch_buttons: colab_url: "https://colab.research.google.com" thebe: true +parse: + myst_substitutions: + sub3: My _global_ value! + myst_enable_extensions: # default extensions to enable in the myst parser. See https://myst-parser.readthedocs.io/en/latest/using/syntax-optional.html + # - amsmath + - colon_fence + - deflist + - dollarmath + - html_admonition + # - html_image + - linkify + # - replacements + # - smartquotes + - substitution + latex: latex_engine: xelatex latex_documents: diff --git a/docs/advanced/sphinx.md b/docs/advanced/sphinx.md index 6ddc27c2..f0b721b9 100644 --- a/docs/advanced/sphinx.md +++ b/docs/advanced/sphinx.md @@ -271,19 +271,14 @@ and the section on [math and equations](myst-content/math). ::: :::{important} -To have "bare" LaTeX rendered in HTML, you must either set in your `_config.yml`: +To have "bare" LaTeX rendered in HTML, enable the `amsmath` extension in your `_config.yml`: ```yaml parse: - myst_extended_syntax: true -``` - -or more specifically: - -```yaml -sphinx: - config: - myst_amsmath_enable: true + myst_enable_extensions: + # don't forget to list any other extensions you want enabled, + # including those that are enabled by default! + - amsmath ``` Then you can include: diff --git a/docs/content/citations.md b/docs/content/citations.md index 184d523f..a4de6bfb 100644 --- a/docs/content/citations.md +++ b/docs/content/citations.md @@ -39,7 +39,8 @@ Here is a quick overview of some common roles for referencing: * `{doc}` is used to reference other files in your book * `{eq}` is used to reference equations that have been given a `label` value -:::{admonition,tip} Choosing your own link text +:::{admonition} Choosing your own link text +:class: tip You can reference a section label through ``{ref}`label` `` or ``{ref}`some text <label>` ``. Documents can be referenced through ``{doc}`path/to/document` `` or ``{doc}`some text <path/to/document>` `` ::: @@ -77,7 +78,8 @@ will link to a section and use its header text as the link text itself: [](./myst.md) -:::{admonition,tip} Internval vs. External URLs +:::{admonition} Internval vs. External URLs +:class: tip You can control how MyST Markdown distinguishes between internal references and external URLs in your `_config.yml`. For example, diff --git a/docs/content/content-blocks.md b/docs/content/content-blocks.md index dbb4aff1..58fecc09 100644 --- a/docs/content/content-blocks.md +++ b/docs/content/content-blocks.md @@ -1,9 +1,61 @@ +--- +substitutions: + key1: "I'm a **substitution**" + key2: | + ```{note} + {{ key1 }} + ``` + fishy: | + ```{image} /images/fun-fish.png + :alt: fishy + :width: 200px + ``` + jinja: "[Jinja templates](https://jinja.palletsprojects.com/en/2.11.x/)" + repo_name: "jupyter-book" + repo_url: "[my repo url](https://github.com/executablebooks/jupyter-book)" +--- + # Special content blocks A common use of directives and roles is to designate "special blocks" of your content. This allows your to include more complex information such as warnings and notes, citations, and figures. This section covers a few common ones. +(content-blocks:myst-extensions)= +## MyST syntax extensions + +{term}`MyST Markdown` has a base syntax that it supports, and additional syntax can be enabled to add extra functionality. +By default, Jupyter Book enables a few extra syntax pieces for MyST in order to more closely resemble the Markdown experience in Jupyter Notebooks and interfaces. +These extensions are: + +`dollarmath` +: To support `$$` and `$` syntax for math blocks. See [](math.md). + +`linkify` +: To auto-detect HTML-like links in your markdown and convert them to hyperlinks. + +`substitution` +: To allow you to define markdown "variables" and substitute text in using them. See [](content:substitutions). + +`colon_fence` +: To allow you to use `:::` fences for admonitions, in order to make them easier to render in interfaces that do not support MyST. See [](admonitions:colons). + +To enable your own syntax extensions, use the following configuration pattern: + +```yaml +parse: + myst_enable_extensions: + - extension-1 + - extension-2 +``` + +Note that this will **override** the default Jupyter Book extension list. +You should include all of the extensions that you want to be enabled. + +:::{seealso} +For a list of syntax extensions in MyST, see [the MyST documentation](https://myst-parser.readthedocs.io/en/latest/using/syntax-optional.html). +::: + (content:admonitions)= ## Notes, warnings, and other admonitions @@ -79,22 +131,12 @@ My content ````` (admonitions:colons)= -### New style admonitions +### Markdown-friendly directives with `:::` The admonition syntax above utilises the general [directives syntax](content:myst/directives). -This has the advantage of making it consistent with every other directive. -However, a big disadvantage is that, when working in any standard Markdown editor (or with the Jupyter Notebook interface), -the text they contain will not render nicely as standard Markdown (for Markdown previews). - -By enabling extended syntax in your `_config.yml`, you will gain access to an alternative syntax for admonitions: +However, if you're using an interface that does not support {term}`MyST Markdown`, it will render as a raw literal block. +Many directives contain markdown inside, and if you'd like this markdown to render "normally", you may also use `:::` fences rather than ` ``` ` fences to define the directive. As a result, the contents of the directive will be rendered as markdown. -```yaml -parse: - myst_extended_syntax: true -``` - -The key differences is that, instead of back-ticks (`` ` ``), colons (`:`) are used, -and thus **the content renders as regular Markdown**. For example: @@ -125,23 +167,7 @@ This text is **standard** _Markdown_ :::: :::{note} -This syntax only supports a selective subset of directives: - -> admonition, attention, caution, danger, error, important, hint, note, seealso, tip and warning. -::: - -These directives do **not** currently allow for parameters to be set, but you can add additional CSS classes to the admonition as comma-delimited arguments after the directive name. -Also, `admonition` can have a custom title. -For example: - -```md -:::{admonition,warning} This *is* also **Markdown** -This text is **standard** _Markdown_ -::: -``` - -:::{admonition,warning} This *is* also **Markdown** -This text is **standard** _Markdown_ +You can use this syntax for any kind of directive, though it is generally recommended to use only with directives that contain pure markdown in their content. ::: @@ -174,6 +200,39 @@ To hide code input and output that generated the variable you are inserting, use See [](../interactive/hiding.md) for more information and other tag options. ::: +(content-blocks:html-admonitions)= +### HTML admonitions + +A drawback of admonition syntax is that it will not render in interfaces that do not support this syntax (e.g., GitHub). If you'd like to use admonitions that are defined *purely with HTML*, MyST can parse them via the `html_admonitions` extension. To use it, first enable it with the following configuration: + +```yaml +parse: + myst_enable_extensions: + # don't forget to list any other extensions you want enabled, + # including those that are enabled by default! + - html_admonition +``` + +Then, you may define admonitions in your book like so: + +:::{tabbed} Markdown Input +```html +<div class="admonition note" name="html-admonition" style="background: lightgreen; padding: 10px"> +<p class="title">This is the **title**</p> +This is the *content* +</div> +``` +::: + +:::{tabbed} Rendered Output +<div class="admonition note" name="html-admonition" style="background: lightgreen; padding: 10px"> +<p class="title">This is the **title**</p> +This is the *content* +</div> +::: + +See [](myst-parser:syntax/html-admonition) for more information about HTML admonitions. + (content/panels)= ## Panels @@ -359,14 +418,16 @@ own titles and stylings. For example: source ^^^ ````md -:::{admonition,dropdown,tip} Click here! +:::{admonition} Click here! +:class: tip, dropdown Here's what's inside! ::: ```` --- result ^^^ -:::{admonition,dropdown,tip} Click here! +:::{admonition} Click here! +:class: tip, dropdown Here's what's inside! ::: ````` @@ -385,7 +446,10 @@ Definition lists are enabled by defining the following setting in your `_config. ```yaml parse: - myst_extended_syntax: true + myst_enable_extensions: + # don't forget to list any other extensions you want enabled, + # including those that are enabled by default! + - deflist ``` Definition lists utilise the [markdown-it-py deflist plugin](https://markdown-it-py.readthedocs.io/en/latest/plugins.html), which itself is based on the [Pandoc definition list specification](http://johnmacfarlane.net/pandoc/README.html#definition-lists). @@ -691,6 +755,141 @@ A caption for a pandas table. See the [`sphinx-panels` tabbed](sphinx-panels:components-tabbed) documentation for more information on how to use this. +(content:substitutions)= +## Substitutions and variables in markdown + +Substitutions allow you to define **variables** in the front-matter of your page, and then **insert** those variables into your content throughout. + +To use a substitution, first add front-matter content to the top of a page like so: + +````yaml +--- +substitutions: + key1: "I'm a **substitution**" + key2: | + ```{note} + {{ key1 }} + ``` + fishy: | + ```{image} img/fun-fish.png + :alt: fishy + :width: 200px + ``` +--- +```` + +You can use these substitutions inline or as blocks, and you can even nest substitutions in other substitutions (but circular references are prohibited): + +:::{tabbed} Markdown Input + +```md +Inline: {{ key1 }} + +Block level: + +{{ key2 }} + +``` +::: + +:::{tabbed} Rendered Output +Inline: {{ key1 }} + +Block level: + +{{ key2 }} +::: + +You can also insert substitutions inside of other markdown structures like tables: + +:::{tabbed} Markdown Input + +```md +| col1 | col2 | +| -------- | --------- | +| {{key2}} | {{fishy}} | +``` +::: + +:::{tabbed} Rendered Output +| col1 | col2 | +| -------- | --------- | +| {{key2}} | {{fishy}} | +::: + +:::{seealso} +For more information about Substitutions, see [](myst-parser:syntax/substitutions). +::: + +### Define substitutions for your whole book + +You can also define book-level substitution variables with the following configuration: + +```yaml +parse: + substitutions: + key: value +``` + +These substitutions will be available throughout your book. For example, the global substitution key `my-global-substitution` is defined in this book's `_config.yml` file, and it produces: {{ sub3 }}. + +### Formatting substitutions + +MyST substitutions use {{ jinja }} in order to substite in key / values. This means that you can apply any standard Jinja formatting to your substitutions. For example, you can **replace text in your substitutions** like so: + +:::{tabbed} Markdown Input + +```md +The original key1: {{ key1 }} + +{{ key1 | replace("a substitution", "the best substitution")}} +``` +::: + +:::{tabbed} Rendered Output +The original key1: {{ key1 }} + +{{ key1 | replace("a **substitution**", "**the best substitution**")}} +::: + +### Using substitutions in links + +If you'd like to use substitutions to insert and modify **links** in your book, here are two options to explore: + +1. **Define the entire markdown link as a variable**. For example: + + :::{tabbed} Markdown Input + + ```yaml + substitutions: + repo_url: [my repo url](https://github.com/executablebooks/jupyter-book) + ``` + ```md + Here's my link: {{ repo_url }} + ``` + ::: + + :::{tabbed} Rendered Output + Here's my link: {{ repo_url }} + ::: +2. Use Jinja features to insert the variable. + Because substitutions use {{ jinja }}, you also have access to **Python formatting** operations in your substitution. + For example: + + :::{tabbed} Markdown Input + + ```yaml + substitutions: + repo_name: jupyter-book + ``` + ```md + Here's my link: {{ '[my repo: `{repo}`](https://github.com/executablebooks/{repo})'.format(repo=repo_name) }} + ``` + ::: + + :::{tabbed} Rendered Output + Here's my link: {{ '[my repo: `{repo}`](https://github.com/executablebooks/{repo})'.format(repo=repo_name) }} + ::: ## Citations and cross-references diff --git a/docs/content/figures.md b/docs/content/figures.md index 37792751..66b54f7e 100644 --- a/docs/content/figures.md +++ b/docs/content/figures.md @@ -42,19 +42,29 @@ will include the following _customized_ figure: These directives allow you to control aspects of the image with [directive arguments](directive-arguments). -In one way, this is an improvement over the Markdown syntax. However, the drawback is that this syntax will not show the image in common Markdown viewers (for example when the files are viewed on GitHub). -A workaround is to use HTML directly, which can also be parsed as MyST Markdown. -Using raw HTML is usually a bad choice (see [this explanation](raw-html-in-markdown)), -but enabling extended syntax in your `_config` enables MySt-Parser to properly handle isolated `img` tags. -Setting +(figures:raw-html)= +### Raw HTML images + +The image syntax described above gives you more customizability, but note that this syntax will not show the image in common Markdown viewers (for example when the files are viewed on GitHub). + +A workaround is to use HTML directly, and MyST can parse HTML images directly via the `html_image` extension. + +:::{warning} +Using raw HTML is usually a bad choice (see [this explanation](raw-html-in-markdown)), so be careful before doing so! +::: + +To parse raw HTML image syntax, enable the `html_image` extension to your list of extensions in `_config.yml`: ```yaml parse: - myst_extended_syntax: true + myst_enable_extensions: + # don't forget to list any other extensions you want enabled, + # including those that are enabled by default! + - html_image ``` -in your `_config.yml` and writing +HTML images will be parsed like any other image. For example: ```html <img src="../images/fun-fish.png" alt="fishy" class="bg-primary" width="200px"> @@ -129,17 +139,14 @@ To do so, see [](content:code-outputs:glue). ## Markdown figures -Markdown figures combine [colon style admonitions](admonitions:colons) and [HTML image parsing](content-blocks-images), to produce a "Markdown friendly" syntax for figures, +Markdown figures combine [colon style admonitions](admonitions:colons) and [HTML image parsing](figures:raw-html), to produce a "Markdown friendly" syntax for figures, with equivalent behaviour to the `figure` directive above. -To enable them, add this to your `_config.yml` file: - -```yaml -parse: - myst_extended_syntax: true -``` +:::{note} +Using this feature requires that [HTML image parsing is enabled](figures:raw-html). +::: -The figure block must contain **only** two components; an image, in either Markdown or HTML syntax, and a single paragraph for the caption. +The figure block must contain **only** two components; an image, in either Markdown or HTML syntax, and a single paragraph for the caption. See below for an example. As with admonitions, the figure can have additional classes set. The "title" of the admonition is used as the label that can be targeted by your cross-references. @@ -147,7 +154,7 @@ The "title" of the admonition is used as the label that can be targeted by your For example, the code ```md -:::{figure,myclass} markdown-fig +:::{figure-md} markdown-fig <img src="../images/fun-fish.png" alt="fishy" class="bg-primary mb-1" width="200px"> This is a caption in **Markdown**! @@ -156,7 +163,7 @@ This is a caption in **Markdown**! generates this figure: -:::{figure,myclass} markdown-fig +:::{figure-md} markdown-fig <img src="../images/fun-fish.png" alt="fishy" class="bg-primary mb-1" width="200px"> This is a caption in **Markdown**! diff --git a/docs/content/math.md b/docs/content/math.md index afcdf4db..e4100816 100644 --- a/docs/content/math.md +++ b/docs/content/math.md @@ -65,14 +65,20 @@ $$ +++ -or, by adding to your `_config.yml`: +(math:latex)= +### Latex-style math + +You can enable parsing LaTeX-style math blocks with the `amsmath` MyST extension. Enable it by adding the following to `_config.yml` ```yaml parse: - myst_extended_syntax: true + myst_enable_extensions: + # don't forget to list any other extensions you want enabled, + # including those that are enabled by default! + - amsmath ``` -you can use: +Once enabled, you can define math blocks like so: ```latex \begin{gather*} diff --git a/docs/content/myst.md b/docs/content/myst.md index 31715d0c..4eaee5b2 100644 --- a/docs/content/myst.md +++ b/docs/content/myst.md @@ -18,7 +18,8 @@ This page contains a few pieces of information about MyST Markdown and how it re You can find much more information about this flavour of Markdown at [the Myst Parser documentation](myst-parser:example_syntax). -:::{admonition,tip} Want to use RMarkdown directly? +:::{admonition} Want to use RMarkdown directly? +:class: tip See [](../file-types/jupytext.md) ::: @@ -159,7 +160,9 @@ For a list of directives that are available to you, there are three places to ch has a list of directives in the Python "docutils" module. 3. This documentation has several additional directives that are specific to Jupyter Book. -In some unusual cases, MyST-Parser may be incompatible with a certain role or directive. +:::{admonition} What if it exists in rST but not MyST? +:class: tip +In some unusual cases, MyST may be incompatible with a certain role or directive. In this case, you can use the special `eval-rst` directive, to directly parse reStructuredText: ````md @@ -177,6 +180,7 @@ which produces A note written in reStructuredText. ``` +::: :::{seealso} The MyST-Parser documentation on [how directives parse content](myst-parser:syntax/directives/parsing), and its use for [including rST files into a Markdown file](myst-parser:howto/include-rst), and [using `sphinx.ext.autodoc` in Markdown files](myst-parser:howto/autodoc). @@ -240,12 +244,10 @@ Here are some links you can use as a reference: * [CommonMark in-line syntax](myst-parser:commonmark-span-tokens) * [Extended in-line syntax in MyST](myst-parser:extended-span-tokens) -As a shorthand, Jupyter Book offers a single configuration, to enable the MyST [extended syntaxes](myst-parser:syntax/optional): - -```yaml -parse: - myst_extended_syntax: true -``` +:::{seealso} +For information about enabling extended MyST syntax, see [](content-blocks:myst-extensions). +In addition, see other examples of this extended syntax (and how to enable each) throughout this documentation. +::: ## What can I create with MyST Markdown? diff --git a/docs/customize/toc.md b/docs/customize/toc.md index c6e34f4e..1fc81415 100644 --- a/docs/customize/toc.md +++ b/docs/customize/toc.md @@ -97,7 +97,8 @@ Below the first entry you have two options for defining the structure of your bo Note that **chapters do not continue between parts**. Think of each part as a self-contained collection of chapters (e.g., for the purposes of numbering). -:::{admonition,warning} Don't mix these two structures! +:::{admonition} Don't mix these two structures! +:class: warning When designing the top-level sections of your `_toc.yml` file, you must pick *either* a list of chapters via `- file:` entries, or a list of parts via `- part:` entries with chapters inside of them. You cannot intermix them both. diff --git a/docs/file-types/markdown.md b/docs/file-types/markdown.md index 5718bf99..418b813c 100644 --- a/docs/file-types/markdown.md +++ b/docs/file-types/markdown.md @@ -105,13 +105,7 @@ yep = its_{more}^{math} \end{align*} :::{important} -This requires the MyST extended syntax enabled in your `_config.yml`: - -```yaml -parse: - myst_extended_syntax: true -``` - +This requires the [`amsmath` MyST extension to be enabled](math:latex). ::: ## Extended Markdown with MyST Markdown diff --git a/docs/intro.md b/docs/intro.md index d3fde550..13ce5133 100644 --- a/docs/intro.md +++ b/docs/intro.md @@ -32,7 +32,8 @@ Here are some of the features of Jupyter Book: This website is built with Jupyter Book! You can browse its contents to the left to see what is possible. -:::{admonition,tip} Learn more and get involved +:::{admonition} Learn more and get involved +:class: tip Jupyter Book is an open community that welcomes your feedback, input, and contributions! diff --git a/docs/reference/glossary.md b/docs/reference/glossary.md index 0e599ed4..4d39b685 100644 --- a/docs/reference/glossary.md +++ b/docs/reference/glossary.md @@ -11,6 +11,7 @@ A glossary of common terms used throughout Jupyter Book. [ExecutableBookProject](https://executablebooks.org/en/latest/) The project that supports and develops many of the core tools used by Jupyter Book. +[MyST Markdown](https://myst-parser.readthedocs.io/en/latest/using/syntax.html) [MyST](https://myst-parser.readthedocs.io/en/latest/using/syntax.html) A flavour of Markdown that was designed for use with the {term}`Sphinx` project. It is a combination of {term}`CommonMark Markdown <CommonMark>` and a few extra diff --git a/docs/requirements.txt b/docs/requirements.txt index c6c13316..ed7bab2f 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -11,5 +11,4 @@ bokeh altair sphinx-click sphinx_inline_tabs -jupytext~=1.6.0 sphinxext-rediraffe~=0.2.3 diff --git a/docs/start/overview.md b/docs/start/overview.md index 572e7db2..24a5ae51 100644 --- a/docs/start/overview.md +++ b/docs/start/overview.md @@ -36,7 +36,8 @@ jupyter-book --help !jupyter-book --help ``` -:::{admonition,warning} A note for Windows users +:::{admonition} A note for Windows users +:class: warning Jupyter Book is now also tested against Windows OS 😀 @@ -108,7 +109,8 @@ execute: - `execute:` contains a collection of configuration options to control [execution and cacheing](../content/execute.md). - `execute_notebooks: "off"` tells Jupyter Book **not to execute** any computational content that it finds when building the book. By default, Jupyter Book executes and caches all book content. -:::{admonition,tip} More about `_config.yml` +:::{admonition} More about `_config.yml` +:class: tip There is much more that you can do with the `_config.yml` file. For example, you can [](source-repository-button) or add [](../interactive/interactive.ipynb). For a complete list of fields for `_config.yml`, see [](../customize/config.md). ::: @@ -151,7 +153,8 @@ For more information about how section structure maps onto book structure, see [](toc/structure). ``` -:::{admonition,tip} More about `_toc.yml` +:::{admonition} More about `_toc.yml` +:class: tip You can specify more complex book configurations with your `_toc.yml` file. For example, you can specify **parts**, **sections**, and control **custom titles**. For more information about your book's table of contents file, see [](../customize/toc.md). ::: @@ -201,7 +204,8 @@ Any outputs generated by the notebook will be inserted into your built book (tho There are many other interesting things that you can do with notebook content as a part of your book. We recommend checking out [](../content/code-outputs.md) as well as [](../interactive/interactive.md) to get started with Jupyter notebooks. ``` -:::{admonition,tip} More about writing content files +:::{admonition} More about writing content files +:class: tip This is only a simple example, and touches on just a couple of the many ways that you can configure and structure your book. For more information about this, see [](../file-types/index) as well as [](../content/content-blocks). ::: diff --git a/jupyter_book/__init__.py b/jupyter_book/__init__.py index 95a5d685..fd580f15 100644 --- a/jupyter_book/__init__.py +++ b/jupyter_book/__init__.py @@ -5,7 +5,7 @@ from .toc import add_toc_to_sphinx, add_toctree from .directive.toc import TableofContents, SwapTableOfContents -__version__ = "0.9.1" +__version__ = "0.10.0" def add_static_files(app, config): diff --git a/jupyter_book/config.py b/jupyter_book/config.py index 926c1487..1d395bad 100644 --- a/jupyter_book/config.py +++ b/jupyter_book/config.py @@ -254,15 +254,37 @@ def yaml_to_sphinx(yaml: dict): # Parse and Rendering parse = yaml.get("parse") if parse: + # Enable extra extensions + extensions = sphinx_config.get("myst_enable_extensions", []) + # TODO: deprecate this in v0.11.0 if parse.get("myst_extended_syntax") is True: - sphinx_config["myst_dmath_enable"] = True - sphinx_config["myst_amsmath_enable"] = True - sphinx_config["myst_deflist_enable"] = True - sphinx_config["myst_admonition_enable"] = True - sphinx_config["myst_html_img_enable"] = True - sphinx_config["myst_figure_enable"] = True - if "myst_url_schemes" in parse: - sphinx_config["myst_url_schemes"] = parse.get("myst_url_schemes") + extensions.append( + [ + "colon_fence", + "dollarmath", + "amsmath", + "deflist", + "html_image", + ] + ) + _message_box( + ( + "myst_extended_syntax is deprecated, instead specify extensions " + "you wish to be enabled. See https://myst-parser.readthedocs.io/en/latest/using/syntax-optional.html" # noqa: E501 + ), + color="orange", + print_func=print, + ) + for ext in parse.get("myst_enable_extensions", []): + if ext not in extensions: + extensions.append(ext) + if extensions: + sphinx_config["myst_enable_extensions"] = extensions + + # Configuration values we'll just pass-through + for ikey in ["myst_substitutions", "myst_url_schemes"]: + if ikey in parse: + sphinx_config[ikey] = parse.get(ikey) # Execution execute = yaml.get("execute") diff --git a/jupyter_book/config_schema.json b/jupyter_book/config_schema.json index 3dae4cf8..b3fee464 100644 --- a/jupyter_book/config_schema.json +++ b/jupyter_book/config_schema.json @@ -23,8 +23,14 @@ "parse": { "type": "object", "properties": { - "myst_extended_syntax": { - "type": "boolean" + "myst_enable_extensions": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + } }, "myst_url_schemes": { "type": [ diff --git a/jupyter_book/default_config.yml b/jupyter_book/default_config.yml index 57fc64cb..3bef8724 100644 --- a/jupyter_book/default_config.yml +++ b/jupyter_book/default_config.yml @@ -29,7 +29,18 @@ execute: ####################################################################################### # Parse and render settings parse: - myst_extended_syntax : false # enable MyST extended syntax support (see documents for details) + myst_enable_extensions: # default extensions to enable in the myst parser. See https://myst-parser.readthedocs.io/en/latest/using/syntax-optional.html + # - amsmath + - colon_fence + # - deflist + - dollarmath + # - html_admonition + # - html_image + - linkify + # - replacements + # - smartquotes + - substitution + myst_url_schemes : [mailto, http, https] # URI schemes that will be recognised as external URLs in Markdown links ####################################################################################### diff --git a/setup.py b/setup.py index 21ccebc1..602d0a2c 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,6 @@ test_reqs = [ "beautifulsoup4", "matplotlib", "pytest-regressions", - "jupytext~=1.6.0", "altair", "sphinx_click", "sphinx_tabs", @@ -67,7 +66,9 @@ setup( "pyyaml", "docutils>=0.15", "sphinx>=2,<4", - "myst-nb~=0.10.1", + "linkify-it-py~=1.0.1", + "myst-nb~=0.11.1", + "jupytext~=1.8.0", "click", "setuptools", "nbformat", diff --git a/tests/test_config.py b/tests/test_config.py index 79cf1745..90644891 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -16,7 +16,7 @@ pytest_plugins = "pytester" {"title": "hallo"}, {"html": {"extra_footer": ""}}, {"execute": {"execute_notebooks": "cache"}}, - {"parse": {"myst_extended_syntax": True}}, + {"parse": {"myst_enable_extensions": ["linkify"]}}, {"latex": {"latex_documents": {"targetname": "book.tex", "title": "other"}}}, {"launch_buttons": {"binderhub_url": "other"}}, {"repository": {"url": "other"}}, @@ -154,6 +154,17 @@ def test_only_build_toc_files_missing_toc(testdir): ) +def test_get_final_config_custom_myst_extensions(data_regression): + cli_config = {"latex_individualpages": False} + user_config = {"parse": {"myst_extra_extensions": ["linkify"]}} + final_config, metadata = get_final_config( + None, user_config, cli_config, validate=True, raise_on_invalid=True + ) + data_regression.check( + {"_user_config": user_config, "final": final_config, "metadata": metadata} + ) + + def test_get_final_config_bibtex(data_regression): cli_config = {"latex_individualpages": False} user_config = {"bibtex_bibfiles": ["tmp.bib"]} diff --git a/tests/test_config/test_config_sphinx_command.txt b/tests/test_config/test_config_sphinx_command.txt index ef21edcb..7e6f88af 100644 --- a/tests/test_config/test_config_sphinx_command.txt +++ b/tests/test_config/test_config_sphinx_command.txt @@ -19,6 +19,7 @@ jupyter_cache = '' jupyter_execute_notebooks = 'auto' language = None latex_engine = 'pdflatex' +myst_enable_extensions = ['colon_fence', 'dollarmath', 'linkify', 'substitution'] myst_url_schemes = ['mailto', 'http', 'https'] nb_output_stderr = 'show' numfig = True diff --git a/tests/test_config/test_get_final_config_custom_myst_extensions.yml b/tests/test_config/test_get_final_config_custom_myst_extensions.yml new file mode 100644 index 00000000..a2088116 --- /dev/null +++ b/tests/test_config/test_get_final_config_custom_myst_extensions.yml @@ -0,0 +1,75 @@ +_user_config: + parse: + myst_extra_extensions: + - linkify +final: + author: The Jupyter Book community + comments_config: + hypothesis: false + utterances: false + copyright: '2020' + exclude_patterns: + - '**.ipynb_checkpoints' + - .DS_Store + - Thumbs.db + - _build + execution_allow_errors: false + execution_excludepatterns: [] + execution_in_temp: false + execution_timeout: 30 + extensions: + - sphinx_togglebutton + - sphinx_copybutton + - myst_nb + - jupyter_book + - sphinx_thebe + - sphinx_comments + - sphinx.ext.intersphinx + - sphinx_panels + - sphinx_book_theme + html_add_permalinks: ¶ + html_baseurl: '' + html_favicon: '' + html_logo: '' + html_sourcelink_suffix: '' + html_theme: sphinx_book_theme + html_theme_options: + extra_footer: '' + extra_navbar: Powered by <a href="https://jupyterbook.org">Jupyter Book</a> + google_analytics_id: '' + home_page_in_toc: true + launch_buttons: + binderhub_url: https://mybinder.org + colab_url: '' + jupyterhub_url: '' + notebook_interface: classic + thebe: false + path_to_docs: '' + repository_branch: master + repository_url: https://github.com/executablebooks/jupyter-book + search_bar_text: Search this book... + use_edit_page_button: false + use_issues_button: false + use_repository_button: false + html_title: My Jupyter Book + jupyter_cache: '' + jupyter_execute_notebooks: auto + language: null + latex_engine: pdflatex + myst_enable_extensions: + - colon_fence + - dollarmath + - linkify + - substitution + myst_url_schemes: + - mailto + - http + - https + nb_output_stderr: show + numfig: true + panels_add_bootstrap_css: false + pygments_style: sphinx +metadata: + latex_doc_overrides: + title: My Jupyter Book + latex_individualpages: false diff --git a/tests/test_config/test_get_final_config_empty_.yml b/tests/test_config/test_get_final_config_empty_.yml index 1f52aaf2..35a6be2e 100644 --- a/tests/test_config/test_get_final_config_empty_.yml +++ b/tests/test_config/test_get_final_config_empty_.yml @@ -53,6 +53,11 @@ final: jupyter_execute_notebooks: auto language: null latex_engine: pdflatex + myst_enable_extensions: + - colon_fence + - dollarmath + - linkify + - substitution myst_url_schemes: - mailto - http diff --git a/tests/test_config/test_get_final_config_exclude_patterns_.yml b/tests/test_config/test_get_final_config_exclude_patterns_.yml index b5252b35..710e662c 100644 --- a/tests/test_config/test_get_final_config_exclude_patterns_.yml +++ b/tests/test_config/test_get_final_config_exclude_patterns_.yml @@ -56,6 +56,11 @@ final: jupyter_execute_notebooks: auto language: null latex_engine: pdflatex + myst_enable_extensions: + - colon_fence + - dollarmath + - linkify + - substitution myst_url_schemes: - mailto - http diff --git a/tests/test_config/test_get_final_config_execute_method_.yml b/tests/test_config/test_get_final_config_execute_method_.yml index 60c1c942..351bba1a 100644 --- a/tests/test_config/test_get_final_config_execute_method_.yml +++ b/tests/test_config/test_get_final_config_execute_method_.yml @@ -55,6 +55,11 @@ final: jupyter_execute_notebooks: cache language: null latex_engine: pdflatex + myst_enable_extensions: + - colon_fence + - dollarmath + - linkify + - substitution myst_url_schemes: - mailto - http diff --git a/tests/test_config/test_get_final_config_extended_syntax_.yml b/tests/test_config/test_get_final_config_extended_syntax_.yml index ab98d61d..4d9669b0 100644 --- a/tests/test_config/test_get_final_config_extended_syntax_.yml +++ b/tests/test_config/test_get_final_config_extended_syntax_.yml @@ -1,6 +1,7 @@ _user_config: parse: - myst_extended_syntax: true + myst_enable_extensions: + - linkify final: author: The Jupyter Book community comments_config: @@ -55,12 +56,8 @@ final: jupyter_execute_notebooks: auto language: null latex_engine: pdflatex - myst_admonition_enable: true - myst_amsmath_enable: true - myst_deflist_enable: true - myst_dmath_enable: true - myst_figure_enable: true - myst_html_img_enable: true + myst_enable_extensions: + - linkify myst_url_schemes: - mailto - http diff --git a/tests/test_config/test_get_final_config_html_extra_footer_.yml b/tests/test_config/test_get_final_config_html_extra_footer_.yml index f6ec82a1..4355bd9d 100644 --- a/tests/test_config/test_get_final_config_html_extra_footer_.yml +++ b/tests/test_config/test_get_final_config_html_extra_footer_.yml @@ -55,6 +55,11 @@ final: jupyter_execute_notebooks: auto language: null latex_engine: pdflatex + myst_enable_extensions: + - colon_fence + - dollarmath + - linkify + - substitution myst_url_schemes: - mailto - http diff --git a/tests/test_config/test_get_final_config_latex_doc_.yml b/tests/test_config/test_get_final_config_latex_doc_.yml index e4a225be..de530aae 100644 --- a/tests/test_config/test_get_final_config_latex_doc_.yml +++ b/tests/test_config/test_get_final_config_latex_doc_.yml @@ -57,6 +57,11 @@ final: jupyter_execute_notebooks: auto language: null latex_engine: pdflatex + myst_enable_extensions: + - colon_fence + - dollarmath + - linkify + - substitution myst_url_schemes: - mailto - http diff --git a/tests/test_config/test_get_final_config_launch_buttons_.yml b/tests/test_config/test_get_final_config_launch_buttons_.yml index 59c9b5f5..d84e2541 100644 --- a/tests/test_config/test_get_final_config_launch_buttons_.yml +++ b/tests/test_config/test_get_final_config_launch_buttons_.yml @@ -55,6 +55,11 @@ final: jupyter_execute_notebooks: auto language: null latex_engine: pdflatex + myst_enable_extensions: + - colon_fence + - dollarmath + - linkify + - substitution myst_url_schemes: - mailto - http diff --git a/tests/test_config/test_get_final_config_repository_.yml b/tests/test_config/test_get_final_config_repository_.yml index 3db44392..9d7a3baf 100644 --- a/tests/test_config/test_get_final_config_repository_.yml +++ b/tests/test_config/test_get_final_config_repository_.yml @@ -55,6 +55,11 @@ final: jupyter_execute_notebooks: auto language: null latex_engine: pdflatex + myst_enable_extensions: + - colon_fence + - dollarmath + - linkify + - substitution myst_url_schemes: - mailto - http diff --git a/tests/test_config/test_get_final_config_sphinx_.yml b/tests/test_config/test_get_final_config_sphinx_.yml index 4a8b607c..81e8e543 100644 --- a/tests/test_config/test_get_final_config_sphinx_.yml +++ b/tests/test_config/test_get_final_config_sphinx_.yml @@ -51,6 +51,11 @@ final: jupyter_execute_notebooks: auto language: null latex_engine: pdflatex + myst_enable_extensions: + - colon_fence + - dollarmath + - linkify + - substitution myst_url_schemes: - mailto - http diff --git a/tests/test_config/test_get_final_config_title_.yml b/tests/test_config/test_get_final_config_title_.yml index b7f70235..1975aaf8 100644 --- a/tests/test_config/test_get_final_config_title_.yml +++ b/tests/test_config/test_get_final_config_title_.yml @@ -54,6 +54,11 @@ final: jupyter_execute_notebooks: auto language: null latex_engine: pdflatex + myst_enable_extensions: + - colon_fence + - dollarmath + - linkify + - substitution myst_url_schemes: - mailto - http -- GitLab