huggingface / huggingface/doc-builder

Inline `\(...\)` math swallows the preceding whitespace; the custom delimiter regexes also diverge from standard KaTeX

Open
#809 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
144
Forks
59
Avg merge
2d 5h
Merged PRs (30d)
13

Description

The Markdown preprocessor renders math by extracting it with hand-written regexes (`markKatex` in `kit/preprocessors/mdsvex/index.js`) before Markdown runs, then rendering the stashed TeX with `katex.renderToString`. There is a concrete bug in that extraction, plus a broader issue: the custom delimiter rules diverge from standard KaTeX in ways that silently bite contributors.

## 1. Bug: inline `\(...\)` eats the whitespace before it

```js
const REGEX_LATEX_INLINE = /\s\\\\\(([\s\S]+?)\\\\\)/g;
// ...
.replace(REGEX_LATEX_INLINE, (_, tex) => {
const marker = `KATEXPARSE${counter++}MARKER`;
markedKatex[marker] = { tex, displayMode: false };
return marker; // the leading \s that was matched is never restored
});
```

The regex matches a leading `\s`, but the replacement returns only `marker`, so that whitespace character is consumed and dropped. Two visible effects:

- **A space between text and an inline formula disappears:** `... one step \(S_{t+1}\)` renders as `one stepS_{t+1}` (glued).
- **Standalone equations run together:** when the eaten character is the newline separating two `\(...\)` lines, the blank-line paragraph break collapses and consecutive equations jam onto one line.

The `$...$` branch a few lines below handles this correctly — it captures the surrounding whitespace and re-emits it (`return spaceBefore + marker + spaceAfter`). The `\(` branch (and the `$$` branch, which eats a leading `\n`) do not.

**Fix** — assert the boundary without consuming it, or capture-and-restore:

```js
const REGEX_LATEX_INLINE = /(?<=\s)\\\\\(([\s\S]+?)\\\\\)/g; // lookbehind
// or: /(\s)\\\\\(([\s\S]+?)\\\\\)/g -> return spaceBefore + marker;
```

## 2. The delimiter rules are inconsistent

| Syntax | Rule in `markKatex` |
|---|---|
| `\(...\)` inline | requires (and eats) one leading whitespace |
| `$...$` inline | requires whitespace on **both** sides |
| `$$...$$` display | requires (and eats) a leading newline |
| `\[...\]` display | **not handled at all** |

There is no consistent mental model, and the natural display counterpart of `\(...\)` — `\[...\]` — is not supported (you must use `$$`).

## 3. The real cost: standard KaTeX syntax silently fails

Contributors will reach for standard KaTeX syntax, but much of it does not render here — it silently becomes literal text instead of math. Examples that fail:

- `$x$` right before punctuation or markup, e.g. `$x$.` or `**$x$**`
- `\[ ... \]` display math — not handled at all
- `\(...\)` at the start of a line — no leading space for the regex to match

We hit this while fixing one page in the Deep RL course: using standard `$...$` and `\[...\]` silently broke ~20 formulas, and it took reading this file to find out why.

**Suggestion:** handle math with the standard toolchain — `remark-math` + `rehype-katex`, or KaTeX's `auto-render` — instead of hand-written regexes, so standard syntax just works and the issues above go away together.

## Where it shows

Live example on the Deep RL course: https://huggingface.co/learn/deep-rl-course/unit2/mc-vs-td (source `units/en/unit2/mc-vs-td.mdx`). Before/after below:

Image

Contributor guide

No contributing guide indexed for this repository

Research direction

Read kit/preprocessors/mdsvex/index.js, focusing on markKatex and its delimiter branches. Reproduce the whitespace cases and standard-syntax examples from the issue, then verify that inline and display math—including \(...\), $...$, $$...$$, and \[...\]—renders without lost whitespace or literal-text fallbacks.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
documentation, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.