Skip to content

Select and copy math like text - #16

Merged
arpan404 merged 1 commit into
mainfrom
ace/math-selection
Nov 1, 2026
Merged

arpan404 merged 1 commit into
mainfrom
ace/math-selection

Conversation

@arpan404

@arpan404 arpan404 commented Nov 1, 2026 •

Copy link
Copy Markdown
Owner

Selecting across an answer with math highlighted only the words between formulas, in boxes as tall as the line, and never the formulas. This makes math select and copy like text.

Cause

  • Formulas are SVG paths. The browser has no text in them to select or paint, so they never highlight.
  • Chrome paints a native text selection as tall as the line box. A tall inline formula (a fraction, a \lim) makes the line box tall, so the words beside it get tall highlight boxes.
  • The copy handler already swapped formulas for data-tex, but it rebuilt the text with textContent, which drops list markers (1.) and table/line structure. It also wrote no text/html.

Change

  • web/math-selection.js: on selectionchange, formulas the selection touches get data-selected and are painted in --mk-selection (default Highlight, and #355274 in dark to match Chrome's native dark selection). Inline formulas highlight like a word; display formulas highlight as a block. The selection is mirrored into a markit-selection custom highlight (CSS Custom Highlight API). In lines that hold inline math, style.css shows that highlight instead of the native one, and it paints at text height. Double-clicking a formula selects all of it. One listener is shared per document.
  • web/copy-text.js: when the copied selection holds math, text/plain gets the TeX source (as written: $…$, $$…$$, \(…\)) interleaved with the words, list markers (1., -, nested indent), task boxes, table tabs and code. text/html gets the selected markup with every formula whole. Selections without math copy as the browser does.
  • Hosts with their own ::selection colour set --mk-selection to the same value. This is documented in docs/integration.md.

Tests

web/tests/math-selection.spec.js (Playwright, real mouse drag and real copy). All three tests fail on main:

  • Selecting across math paints every formula and keeps the area above "Recognize" (inside the tall line box) unpainted. Before: 0 % painted on the formulas, 100 % painted above the word.
  • Copying gives the exact TeX with words and list markers, and text/html has all 9 formulas. Before: the 1./2. markers were missing and there was no text/html.
  • Double-clicking a formula selects it whole and copies its TeX; double-clicking a word still selects the word.

Also ran renderer.spec.js, react.spec.js, inline.spec.js and tests/node (jsdom): all pass.

Copied text for the example:

Recognize $f'(a)=\lim_{h\to0}\frac{f(a+h)-f(a)}{h}$:

1. $f=\sin$ at $x$: $=\cos x$
2. $f=e^x$ at $0$: $=1$ since $e^0=1$

$$\int_0^1 x\,dx = \frac12$$

Done.

Formulas are SVG, so the browser had nothing to select or paint in them,
and a tall inline formula made Chrome paint the words beside it as tall
as the whole line. Selected formulas are now painted in the selection
colour, lines holding inline math draw the selection through a custom
highlight at text height, and double-clicking a formula selects it.

Copying a selection with math writes the TeX interleaved with the words,
list markers, table tabs and code to text/plain, and the drawn formulas
to text/html. Hosts match their ::selection colour with --mk-selection.

Co-Authored-By: spade <bot@acehq.dev>
@arpan404
arpan404 merged commit e2ae804 into main Nov 1, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant