Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

👌 IMPROVE: MathJax compatibility with nbsphinx #395

Merged
merged 4 commits into from
Jun 17, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 1 addition & 20 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -48,31 +48,12 @@ jobs:
python -m pip install --upgrade pip
pip install -e .[linkify,testing]
pip install --upgrade-strategy "only-if-needed" "sphinx${{ matrix.sphinx }}"
- name: Run pytest
run: pytest

coverage:

name: Run test coverage and upload to Codecov
if: github.repository == 'executablebooks/MyST-Parser'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: 3.8
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .[linkify,testing]

- name: Run pytest
run: |
pytest --cov=myst_parser --cov-report=xml --cov-report=term-missing
coverage xml

- name: Upload to Codecov
if: github.repository == 'executablebooks/MyST-Parser' && matrix.python-version == 3.8
uses: codecov/codecov-action@v1
with:
name: myst-parser-pytests
10 changes: 4 additions & 6 deletions docs/syntax/optional.md
Original file line number Diff line number Diff line change
@@ -72,9 +72,6 @@ text | converted
``--`` | --
``---`` | ---

(syntax/linkify)=


(syntax/math)=
## Math shortcuts

@@ -225,19 +222,20 @@ Myst-Parser injects the `tex2jax_ignore` (MathJax v2) and `mathjax_ignore` (Mat
MathJax version 2 (see [the tex2jax preprocessor](https://docs.mathjax.org/en/v2.7-latest/options/preprocessors/tex2jax.html#configure-tex2jax):

```javascript
MathJax.Hub.Config({"tex2jax": {"processClass": "tex2jax_process|mathjax_process|math"}})
MathJax.Hub.Config({"tex2jax": {"processClass": "tex2jax_process|mathjax_process|math|output_area"}})
```

MathJax version 3 (see [the document options](https://docs.mathjax.org/en/latest/options/document.html?highlight=ignoreHtmlClass#the-configuration-block)):

```javascript
window.MathJax = {"options": {"processHtmlClass": "tex2jax_process|mathjax_process|math"}}
window.MathJax = {"options": {"processHtmlClass": "tex2jax_process|mathjax_process|math|output_area"}}
```

This ensurea that MathJax processes only math, identified by the `dollarmath` and `amsmath` extensions, or specified in `math` directives.

To change this behaviour, set a custom regex, for identifying HTML classes to process, like `myst_mathjax_classes="math|myclass"`, or set `update_mathjax=False` to inhibit this override and process all HTML elements.
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.

(syntax/linkify)=
## Linkify

Adding `"linkify"` to `myst_enable_extensions` (in the sphinx `conf.py` [configuration file](https://www.sphinx-doc.org/en/master/usage/configuration.html)) will automatically identify "bare" web URLs and add hyperlinks:
2 changes: 1 addition & 1 deletion myst_parser/main.py
Original file line number Diff line number Diff line change
@@ -48,7 +48,7 @@ class MdParserConfig:
update_mathjax: bool = attr.ib(default=True, validator=instance_of(bool))

mathjax_classes: str = attr.ib(
default="tex2jax_process|mathjax_process|math",
default="tex2jax_process|mathjax_process|math|output_area",
validator=instance_of(str),
)

45 changes: 35 additions & 10 deletions myst_parser/mathjax.py
Original file line number Diff line number Diff line change
@@ -19,6 +19,22 @@
logger = logging.getLogger(__name__)


def log_override_warning(app: Sphinx, version: int, current: str, new: str) -> None:
"""Log a warning if MathJax configuration being overriden."""
if logging.is_suppressed_warning("myst", "mathjax", app.config.suppress_warnings):
return
config_name = (
"mathjax3_config['options']['processHtmlClass']"
if version == 3
else "mathjax_config['tex2jax']['processClass']"
)
logger.warning(
f"`{config_name}` is being overridden by myst-parser: '{current}' -> '{new}'. "
"Set `suppress_warnings=['myst.mathjax']` to ignore this warning, or "
"`myst_update_mathjax=False` if this is undesirable."
)


def override_mathjax(app: Sphinx):
"""Override aspects of the mathjax extension.

@@ -44,22 +60,31 @@ def override_mathjax(app: Sphinx):
# sphinx 4 + mathjax 3
app.config.mathjax3_config = app.config.mathjax3_config or {} # type: ignore[attr-defined]
app.config.mathjax3_config.setdefault("options", {})
if "processHtmlClass" in app.config.mathjax3_config["options"]:
logger.warning(
"`mathjax3_config['options']['processHtmlClass']` is being overridden "
f"by myst-parser to {mjax_classes}. "
"Set `myst_mathjax_classes = None` if this is undesirable."
if (
"processHtmlClass" in app.config.mathjax3_config["options"]
and app.config.mathjax3_config["options"]["processHtmlClass"]
!= mjax_classes
):
log_override_warning(
app,
3,
app.config.mathjax3_config["options"]["processHtmlClass"],
mjax_classes,
)
app.config.mathjax3_config["options"]["processHtmlClass"] = mjax_classes
elif "mathjax_config" in app.config:
# sphinx 3 + mathjax 2
app.config.mathjax_config = app.config.mathjax_config or {} # type: ignore[attr-defined]
app.config.mathjax_config.setdefault("tex2jax", {})
if "processClass" in app.config.mathjax_config["tex2jax"]:
logger.warning(
"`mathjax_config['tex2jax']['processClass']` is being overridden by "
f"myst-parser to {mjax_classes}. "
"Set `myst_mathjax_classes = None` if this is undesirable."
if (
"processClass" in app.config.mathjax_config["tex2jax"]
and app.config.mathjax_config["tex2jax"]["processClass"] != mjax_classes
):
log_override_warning(
app,
2,
app.config.mathjax_config["tex2jax"]["processClass"],
mjax_classes,
)
app.config.mathjax_config["tex2jax"]["processClass"] = mjax_classes

12 changes: 12 additions & 0 deletions tests/test_sphinx/sourcedirs/mathjax/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import sphinx

extensions = ["myst_parser"]
exclude_patterns = ["_build"]

if sphinx.version_info[0] <= 3:
mathjax_config = {"tex2jax": {"processClass": "other"}}
else:
mathjax3_config = {"options": {"processHtmlClass": "other"}}

# this should remove the warning
# suppress_warnings = ["myst.mathjax"]
5 changes: 5 additions & 0 deletions tests/test_sphinx/sourcedirs/mathjax/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Test

```{math}
a = 1
```
19 changes: 19 additions & 0 deletions tests/test_sphinx/test_sphinx_builds.py
Original file line number Diff line number Diff line change
@@ -380,3 +380,22 @@ def test_gettext(
output = re.sub(r"Copyright \(C\) [0-9]{4}", "Copyright (C) XXXX", output)

file_regression.check(output, extension=".pot")


@pytest.mark.sphinx(
buildername="html", srcdir=os.path.join(SOURCE_DIR, "mathjax"), freshenv=True
)
def test_mathjax_warning(
app,
status,
warning,
remove_sphinx_builds,
):
"""Test mathjax config override warning."""
app.build()
assert "build succeeded" in status.getvalue() # Build succeeded
warnings = warning.getvalue().strip()
assert (
"overridden by myst-parser: 'other' -> 'tex2jax_process|mathjax_process|math|output_area'"
in warnings
)