Skip to content

Commit

Permalink
Merge branch 'main' into patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
krassowski authored Jan 2, 2025
2 parents 4f8eb61 + 18e10f6 commit 6e28114
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 13 deletions.
22 changes: 22 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,28 @@ jobs:
PIP_CONSTRAINT= hatch env run -e test -- pip install 'pip>=24.2'
xvfb-run --auto-servernum hatch run test:nowarn || xvfb-run --auto-servernum hatch run test:nowarn --lf
test_mistune_30:
name: Test Mistune 3.0
timeout-minutes: 20
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Base Setup
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install texlive-plain-generic inkscape texlive-xetex latexmk
sudo apt-get install xvfb x11-utils libxkbcommon-x11-0 libxcb-xinerama0 python3-pyqt5
# pandoc is not up to date in the ubuntu repos, so we install directly
wget https://github.com/jgm/pandoc/releases/download/2.9.2.1/pandoc-2.9.2.1-1-amd64.deb && sudo dpkg -i pandoc-2.9.2.1-1-amd64.deb
- name: Run tests
run: |
hatch env run -e test -- pip install 'mistune~=3.0.0'
xvfb-run --auto-servernum hatch run test:nowarn || xvfb-run --auto-servernum hatch run test:nowarn --lf
test_prereleases:
name: Test Prereleases
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion docs/source/nbconvert_library.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"@damianavila wrote the Nikola Plugin to [write blog post as Notebooks](http://damianavila.github.io/blog/posts/one-line-deployment-of-your-site-to-gh-pages.html) and is developing a js-extension to publish notebooks via one click from the web app."
"@damianavila wrote the Nikola Plugin to [write blog post as Notebooks](https://damianavila.github.io/blog/posts/one-line-deployment-of-your-site-to-gh-pages) and is developing a js-extension to publish notebooks via one click from the web app."
]
}
],
Expand Down
39 changes: 27 additions & 12 deletions nbconvert/filters/markdown_mistune.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import mimetypes
import os
from html import escape
from typing import Any, Callable, Dict, Iterable, Match, Optional, Tuple
from typing import TYPE_CHECKING, Any, ClassVar, Dict, Iterable, Match, Optional, Protocol, Tuple

import bs4
from pygments import highlight
Expand All @@ -20,6 +20,19 @@

from nbconvert.filters.strings import add_anchor

if TYPE_CHECKING:
try:
from mistune.plugins import Plugin
except ImportError:

class Plugin(Protocol): # type: ignore[no-redef]
"""Mistune plugin interface."""

def __call__(self, markdown: "Markdown") -> None:
"""Apply the plugin on the markdown document."""
...


try: # for Mistune >= 3.0
from mistune import ( # type:ignore[attr-defined]
BlockParser,
Expand All @@ -32,6 +45,7 @@
)

MISTUNE_V3 = True
MISTUNE_V3_ATX = "atx_heading" in BlockParser.SPECIFICATION

except ImportError: # for Mistune >= 2.0
import re
Expand All @@ -45,8 +59,9 @@
)

MISTUNE_V3 = False
MISTUNE_V3_ATX = False

def import_plugin(name: str) -> "MarkdownPlugin": # type: ignore[misc]
def import_plugin(name: str) -> "Plugin": # type: ignore[misc]
"""Simple implementation of Mistune V3's import_plugin for V2."""
return PLUGINS[name] # type: ignore[no-any-return]

Expand Down Expand Up @@ -75,8 +90,10 @@ class MathBlockParser(BlockParser):
is ignored here.
"""

AXT_HEADING_WITHOUT_LEADING_SPACES = (
r"^ {0,3}(?P<axt_1>#{1,6})(?!#+)(?P<axt_2>[ \t]*(.*?)?)$"
ATX_HEADING_WITHOUT_LEADING_SPACES = (
r"^ {0,3}(?P<atx_1>#{1,6})(?!#+)(?P<atx_2>[ \t]*(.*?)?)$"
if MISTUNE_V3_ATX
else r"^ {0,3}(?P<axt_1>#{1,6})(?!#+)(?P<axt_2>[ \t]*(.*?)?)$"
)

MULTILINE_MATH = _dotall(
Expand All @@ -92,12 +109,14 @@ class MathBlockParser(BlockParser):

SPECIFICATION = {
**BlockParser.SPECIFICATION,
"axt_heading": AXT_HEADING_WITHOUT_LEADING_SPACES,
(
"atx_heading" if MISTUNE_V3_ATX else "axt_heading"
): ATX_HEADING_WITHOUT_LEADING_SPACES,
"multiline_math": MULTILINE_MATH,
}

# Multiline math must be searched before other rules
DEFAULT_RULES: Tuple[str, ...] = ("multiline_math", *BlockParser.DEFAULT_RULES) # type: ignore[assignment]
DEFAULT_RULES: ClassVar[Iterable[str]] = ("multiline_math", *BlockParser.DEFAULT_RULES) # type: ignore[assignment]

def parse_multiline_math(self, m: Match[str], state: BlockState) -> int:
"""Send mutiline math as a single paragraph to MathInlineParser."""
Expand Down Expand Up @@ -139,7 +158,7 @@ class MathInlineParser(InlineParser):
}

# Block math must be matched first, and all math must come before text
DEFAULT_RULES: Tuple[str, ...] = (
DEFAULT_RULES: ClassVar[Iterable[str]] = (
"block_math_tex",
"block_math_latex",
"inline_math_tex",
Expand Down Expand Up @@ -442,10 +461,6 @@ def _html_embed_images(self, html: str) -> str:
return str(parsed_html)


# Represents an already imported plugin for Mistune
MarkdownPlugin = Callable[[Markdown], None]


class MarkdownWithMath(Markdown):
"""Markdown text with math enabled."""

Expand All @@ -464,7 +479,7 @@ def __init__(
renderer: HTMLRenderer,
block: Optional[BlockParser] = None,
inline: Optional[InlineParser] = None,
plugins: Optional[Iterable[MarkdownPlugin]] = None,
plugins: Optional[Iterable["Plugin"]] = None,
):
"""Initialize the parser."""
if block is None:
Expand Down

0 comments on commit 6e28114

Please sign in to comment.