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

dollarmath: Add allow_blank_lines option #46

Merged
merged 11 commits into from
Mar 6, 2023
15 changes: 11 additions & 4 deletions mdit_py_plugins/dollarmath/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ def dollarmath_plugin(
allow_labels: bool = True,
allow_space: bool = True,
allow_digits: bool = True,
allow_blank_lines: bool = True,
double_inline: bool = False,
label_normalizer: Optional[Callable[[str], str]] = None,
renderer: Optional[Callable[[str, Dict[str, Any]], str]] = None,
Expand All @@ -30,6 +31,10 @@ def dollarmath_plugin(
:param allow_digits: Parse inline math when there is a digit
before/after the opening/closing ``$``, e.g. ``1$`` or ``$2``.
This is useful when also using currency.
:param allow_blank_lines: Allow blank lines inside ``$$``. Note that blank lines are
not allowed in LaTeX, executablebooks/markdown-it-dollarmath, or the Github or
StackExchange markdown dialects. Hoever, they have special semantics if used
within Sphinx `..math` admonitions, so are allowed for backwards-compatibility.
:param double_inline: Search for double-dollar math within inline contexts
:param label_normalizer: Function to normalize the label,
by default replaces whitespace with `-`
Expand All @@ -47,7 +52,9 @@ def dollarmath_plugin(
math_inline_dollar(allow_space, allow_digits, double_inline),
)
md.block.ruler.before(
"fence", "math_block", math_block_dollar(allow_labels, label_normalizer)
"fence",
"math_block",
math_block_dollar(allow_labels, label_normalizer, allow_blank_lines),
)

# TODO the current render rules are really just for testing
Expand Down Expand Up @@ -246,6 +253,7 @@ def _math_inline_dollar(state: StateInline, silent: bool) -> bool:
def math_block_dollar(
allow_labels: bool = True,
label_normalizer: Optional[Callable[[str], str]] = None,
allow_blank_lines: bool = False,
) -> Callable[[StateBlock, int, int, bool], bool]:
"""Generate block dollar rule."""

Expand Down Expand Up @@ -299,15 +307,14 @@ def _math_block_dollar(
start = state.bMarks[nextLine] + state.tShift[nextLine]
end = state.eMarks[nextLine]

if end - start < 2:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should stay (but break not continue) to safeguard against any index errors

Copy link
Contributor Author

@eric-wieser eric-wieser Jun 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line doesn't exist any more in the javascript version, why would you want to keep it in the Python version?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because JavaScript does not act the same as Python; if you index a JavaScript array with "bad indexes" it will simply return null, whereas in python it will raise an indexerror.
There has been multiple bug fixed for this in markdown-it-py

Copy link
Contributor Author

@eric-wieser eric-wieser Jun 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only indexing that takes place is state.src[start:end], and that will never give an IndexError. If start=end then it will return "", but that's absolutely fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rowanc1: what can we do to progress here?

continue

lineText = state.src[start:end]

if lineText.strip().endswith("$$"):
haveEndMarker = True
end = end - 2 - (len(lineText) - len(lineText.strip()))
break
if lineText.strip() == "" and not allow_blank_lines:
break # blank lines are not allowed within $$

# reverse the line and match
if allow_labels:
Expand Down
12 changes: 12 additions & 0 deletions tests/fixtures/dollar_math.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,18 @@ b = 2
</div>
.

display equation with blank lines. (valid=False)
.
$$
1+1=2

$$
.
<p>$$
1+1=2</p>
<p>$$</p>
.

equation followed by a labelled equation (valid=True)
.
$$
Expand Down
6 changes: 5 additions & 1 deletion tests/test_dollarmath.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,11 @@ def test_custom_renderer(data_regression):
)
def test_dollarmath_fixtures(line, title, input, expected):
md = MarkdownIt("commonmark").use(
dollarmath_plugin, allow_space=False, allow_digits=False, double_inline=True
dollarmath_plugin,
allow_space=False,
allow_digits=False,
double_inline=True,
allow_blank_lines=False,
)
md.options.xhtmlOut = False
text = md.render(input)
Expand Down