jlevy / jlevy/flowmark

Inline `$…$` math is not protected from wrapping, and the rewrap escapes characters inside it (corrupts the LaTeX)

Open Beginner friendly
#70 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
81
Forks
11
Avg merge
10h 53m
Merged PRs (30d)
6

Description

## Summary

When a wrap boundary falls inside an inline `$…$` math span, flowmark breaks the line inside the span **and** applies Markdown escaping to the fragment that lands at the start of the new line. The escape character ends up inside the math, changing the LaTeX rather than only its layout.

Inline code spans are correctly treated as atomic in the same position. Inline math is not.

This contradicts a stated assumption in #62, which lists **"the interior of `$…$` inline math"** under *"Already robustly safe (no action needed)"*. The interior is safe from *reflow of its contents*, but the span itself is not protected from being **split**, and the split introduces an escape.

## Minimal reproduction

`repro.md`:

```markdown
# Repro

Filler words to push the formula across the wrap column boundary here now ok $a + b + c + d$ tail.

Filler words to push the formula across the wrap column boundary here now ok `a + b + c + d` tail.
```

Run:

```bash
flowmark --auto --nobackup repro.md
```

## Actual

```markdown
# Repro

Filler words to push the formula across the wrap column boundary here now ok $a + b + c
\+ d$ tail.

Filler words to push the formula across the wrap column boundary here now ok
`a + b + c + d` tail.
```

Two distinct problems in the math line:

1. The span is **split across lines** — `$a + b + c` / `\+ d$`.
2. The `+` beginning the continuation line is **escaped to `\+`**. The math span now contains a literal backslash that was not in the input, so this is content corruption, not just reflow.

The code-span line shows the correct behaviour by contrast: the whole span is moved to the next line intact.

## Expected

Inline `$…$` should be atomic for wrapping purposes, exactly like `` `…` ``: move the whole span to the next line rather than splitting it, and never apply Markdown escaping inside it.

## Scope

- Reproduced on **`flowmark 0.3.2` (Rust)** and **`flowmark 0.7.0` (Python)**. Both emit byte-identical output, so this is shared behaviour rather than a port regression.
- The escaping is **idempotent** — re-running does not accumulate further backslashes. It is a one-time corruption, not runaway.
- Only triggers when the wrap column lands inside the span, which is why it is easy to miss on short formulas.

## Why it matters in practice

I hit this archiving a mathematics literature corpus as Markdown for local search. Formatting the corpus broke a substantial fraction of its inline math:

| File | `$…$` spans | Split across lines |
|---|---|---|
| Stromquist 2003 transcription | 339 | 31 |
| Caoduro–Sebő transcription | 1236 | 101 |
| A web capture | 433 | 5 |

Beyond the escaping bug, a newline inside a formula defeats `grep`, which for a searchable archive is the whole point. Some Markdown math renderers also require inline math to stay on one line. The practical consequence is that math-bearing Markdown currently has to be excluded from flowmark entirely, which is what I have had to do.

## Suggested fix

Add `$…$` to the inline atomic-span tokenizer alongside code spans, links, autolinks and HTML/Jinja tags (`src/wrapping/atomic_patterns.rs` in the Rust port, per the file map in #62). That is the mechanism already protecting code spans in the contrasting line above, so this looks like extending an existing list rather than new infrastructure.

Worth pairing with the `\(…\)` item already listed as P2 in #62, since both are the inline case of the same problem.

A conservative delimiter rule would help avoid false positives on currency (`$5 and $10`): require the closing `$` to be non-whitespace-preceded and the opening `$` non-whitespace-followed, as CommonMark math extensions generally do.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by running `flowmark --auto --nobackup repro.md` from the minimal reproduction, then read `src/wrapping/atomic_patterns.rs` and the inline atomic-span tokenizer described in the issue. Extend the existing atomic-span handling for `$…$`, considering the stated currency-delimiter rule and the related `\(…\)` case. Done means inline math moves intact to the next line without Markdown escaping inside it.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, rust
Domain
cli, tooling
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.