diff --git a/CHANGELOG.md b/CHANGELOG.md index f6d4c16c4273de715e457505b0c3fda443452f44..e996c6d6b343f71ff7f4034e2ab450b7faf06ed7 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 afa71850aebe762bf08469556236789d502d49dc..5dbe185060ebd9ea9572600777be8a4b5f151f7a 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 6ddc27c2b91aeecff25544a07c0e924a8fba0260..f0b721b9177a547cc361c8be53fcdc55287d2a7c 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 184d523f0314ef55cf88c68e4932929696272ada..a4de6bfbb62474cfda8063fb7f03ffd7a3f9a7eb 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 dbb4aff1f278c442a7b9a9998cb491cd3f421526..58fecc09063a3db525c81982a86086cf5a4f0d30 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 377927511e9f3a51aae22c568ae818598da7105e..66b54f7e03d2fbf23d02fe466b3609c491fce13e 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 afcdf4db5b36a8e5aec6a98ac78093b878bf4ec9..e41008167770efce7d9218b0879d3d2c79ae51f8 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 31715d0c50dcd12dea19cf6f7da9421d3109910a..4eaee5b27ed6b9cfb0075473be447852183fbc7c 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 c6e34f4eb3ac92cd2d68db3b3bf0c67748a3344c..1fc81415874b023d96dd32af7a4b8ee4b2f6b4a9 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 5718bf99d06ea3d3648fcccab8999d9e2bbdecbc..418b813c284f0a38f76b4d4075488b1ee930a25d 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 d3fde55038393f90806d6f4e1b8d28da1ea2e8eb..13ce51331319696f073f8f3c5d5e9aeccd218bff 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 0e599ed4b8091e0c00b661854409398e17f1df4c..4d39b68504ce31a32e5eced1a1dcfa5909884346 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 c6c133164c7ed98caa7e3789d84f272bf535a495..ed7bab2f34225cbbc671f4f2a94b03074dda7dee 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 572e7db25caddfab8cac105576cc2f31feb033a8..24a5ae511809fbf46cd73925928ac98c3669d662 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 95a5d685f4a7a42a50821c44bff41cbc5538ffad..fd580f157ba75d51ed93974c50c66f1e71d16c0b 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 926c1487508d43eb536feb0b17d6e09b71979637..1d395bad928c23f11739862a6914f9d8ba4b97d5 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 3dae4cf8e8ea0f4fd8fe6a653f4a596e765f22be..b3fee4640c8d03acc5a4739e4298d3e22e4cda9c 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 57fc64cba924ff927d8f1f72be5711807763b994..3bef872469bc45eff44c06d4d5ce07b7b1dbe6aa 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 21ccebc1d9c1f26c2ddb6f31fd7eb4e22110af75..602d0a2ce5dc38704a59a1d5a5ad8c80a77287af 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 79cf17452441b3409e75d5485d99529282bc1675..90644891245a07e94eda0c7b06ac22dffccd8f34 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 ef21edcbb9c4740a2e13ee68ca9344aa7c57f97e..7e6f88afe1a39af92ee8e6452be929ceebbccdd5 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 0000000000000000000000000000000000000000..a2088116fc2b3e8c3dc7346e0cc867c420b926ad --- /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 1f52aaf2593c086b1d22571b004a98406ae309b5..35a6be2e382e63661fe9643ca294a9913adddc25 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 b5252b355143ec07b91a89bd3cb2d67ce8b5be50..710e662ca661a510aa48a5624b448314c557d992 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 60c1c94237d5d98e362c4ebdde992045a7a5ad31..351bba1ae051440e0c6d77deafce45be4f5d6fff 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 ab98d61d96fb53dea1cbaa241425108a5c8a81c9..4d9669b01ee031b6e7893f9044bc6a19dc4894e5 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 f6ec82a16a94443cc52f876602bfaab93859ad61..4355bd9d6a35da04f53d0d0d81cca8201cb98baa 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 e4a225be29f918b93a139966800c3bdd158874fe..de530aae1acff219158d05855b33d22ce9b2b63c 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 59c9b5f5fb8ef4264e77d7ce250f3be4a93e4cb8..d84e25414ba6db4ca44ae1598757a6fe2bd7602c 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 3db44392e6d3d3ed9c26476544fcc195dad2f9f8..9d7a3bafa73abf065b8f3ae384c1dc85b8699973 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 4a8b607cd346203e8df8a904db6a957491c8cd0f..81e8e543a06c231141f63cdef7fdeb4afa0f27ad 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 b7f7023538d6706f6d709c48bb785b613ce71f24..1975aaf8fd7112c624eacbc3226e3a025b1ed694 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