mathpix-markdown-it 2.0.35 → 2.0.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +146 -4
  2. package/doc/changelog.md +64 -0
  3. package/es5/browser/add-speech.js +1 -0
  4. package/es5/browser/auto-render.js +33 -0
  5. package/es5/bundle.js +5 -5
  6. package/es5/index.js +5 -5
  7. package/lib/browser/add-speech.d.ts +17 -0
  8. package/lib/browser/add-speech.js +97 -0
  9. package/lib/browser/add-speech.js.map +1 -0
  10. package/lib/browser/auto-render.d.ts +20 -0
  11. package/lib/browser/auto-render.js +319 -0
  12. package/lib/browser/auto-render.js.map +1 -0
  13. package/lib/browser/utils.d.ts +4 -0
  14. package/lib/browser/utils.js +11 -0
  15. package/lib/browser/utils.js.map +1 -0
  16. package/lib/contex-menu/styles.js +2 -1
  17. package/lib/contex-menu/styles.js.map +1 -1
  18. package/lib/copy-to-clipboard/clipboard-copy-styles.js +2 -1
  19. package/lib/copy-to-clipboard/clipboard-copy-styles.js.map +1 -1
  20. package/lib/markdown/common/convert-math-to-html.d.ts +4 -1
  21. package/lib/markdown/common/convert-math-to-html.js +174 -93
  22. package/lib/markdown/common/convert-math-to-html.js.map +1 -1
  23. package/lib/markdown/highlight/highlight-math-token.js +5 -3
  24. package/lib/markdown/highlight/highlight-math-token.js.map +1 -1
  25. package/lib/mathjax/index.d.ts +6 -0
  26. package/lib/mathjax/index.js +103 -33
  27. package/lib/mathjax/index.js.map +1 -1
  28. package/lib/mathpix-markdown-model/index.d.ts +35 -5
  29. package/lib/mathpix-markdown-model/index.js +106 -50
  30. package/lib/mathpix-markdown-model/index.js.map +1 -1
  31. package/lib/sre/index.d.ts +8 -0
  32. package/lib/sre/index.js +38 -20
  33. package/lib/sre/index.js.map +1 -1
  34. package/lib/sre/sre-browser.d.ts +16 -0
  35. package/lib/sre/sre-browser.js +26 -1
  36. package/lib/sre/sre-browser.js.map +1 -1
  37. package/lib/styles/colors.d.ts +63 -0
  38. package/lib/styles/colors.js +68 -0
  39. package/lib/styles/colors.js.map +1 -0
  40. package/lib/styles/helpers.js +22 -0
  41. package/lib/styles/helpers.js.map +1 -0
  42. package/lib/styles/index.d.ts +4 -3
  43. package/lib/styles/index.js +45 -7
  44. package/lib/styles/index.js.map +1 -1
  45. package/lib/styles/styles-code.d.ts +1 -1
  46. package/lib/styles/styles-code.js +6 -1
  47. package/lib/styles/styles-code.js.map +1 -1
  48. package/lib/styles/styles-container.js +2 -1
  49. package/lib/styles/styles-container.js.map +1 -1
  50. package/lib/styles/styles-lists.d.ts +1 -1
  51. package/lib/styles/styles-lists.js +1 -1
  52. package/lib/styles/styles-lists.js.map +1 -1
  53. package/lib/styles/styles-tabular.d.ts +1 -1
  54. package/lib/styles/styles-tabular.js +5 -2
  55. package/lib/styles/styles-tabular.js.map +1 -1
  56. package/package.json +2 -2
  57. package/pr-specs/2026-01-html-math-output-options.md +529 -0
  58. package/pr-specs/2026-03-mmd-css-scoping.md +267 -0
  59. package/lib/styles/halpers.js +0 -13
  60. package/lib/styles/halpers.js.map +0 -1
  61. /package/lib/styles/{halpers.d.ts → helpers.d.ts} +0 -0
@@ -0,0 +1,267 @@
1
+ # PR: CSS scoping — `#preview-content`/`#setText` specificity boost for all MMD selectors
2
+
3
+ Status: Implemented
4
+ Owner: @OlgaRedozubova
5
+
6
+ ---
7
+
8
+ ## Context
9
+
10
+ MMD styles use two scoping mechanisms:
11
+ 1. **ID selectors** (`#setText h1`, `#preview-content table`) for generic HTML elements — specificity (1,0,1), already beats any host class-based CSS.
12
+ 2. **Class selectors** (`.tabular`, `.figure_img`, `.itemize`, `.enumerate`, `.hljs-*`, `.proof`, `.author`, etc.) for MMD-specific elements — were bare, vulnerable to host CSS overrides with equal or higher specificity.
13
+
14
+ When MMD content is embedded on a host page (e.g., `.docs-content table { width: 100% }`), the host styles override MMD class-based rules. This caused tabular tables to stretch, figure alignment to break, list spacing to change, and syntax highlighting colors to be overridden.
15
+
16
+ ---
17
+
18
+ ## Goal
19
+
20
+ - Boost specificity of all MMD class selectors by adding `#preview-content`/`#setText` scoped variants.
21
+ - Keep bare selectors as fallback for `markdownToHTML()` which returns raw HTML without wrapper.
22
+ - Clean up dead code, fix bugs, restructure style modules for readability.
23
+ - No new wrapper elements, no breaking changes to HTML output or public API signatures.
24
+
25
+ ---
26
+
27
+ ## Scoping Strategy
28
+
29
+ ### Pattern: bare + scoped
30
+
31
+ Every MMD class selector now follows this pattern:
32
+
33
+ ```css
34
+ .selector,
35
+ #preview-content .selector, #setText .selector {
36
+ /* styles */
37
+ }
38
+ ```
39
+
40
+ - **Bare** (0,1,0) — fallback for `markdownToHTML()` consumers without `#setText`/`#preview-content` wrapper.
41
+ - **Scoped** (1,1,0) — beats host `.docs-content .selector` (0,1,x) when inside containers.
42
+
43
+ ### Exceptions (bare only, no scoped)
44
+
45
+ | Selector | Reason |
46
+ |---|---|
47
+ | `.math-block`, `.math-inline`, `.math-error` | `math-` prefix is distinctive enough; no known collisions |
48
+ | `mjx-container` | Custom element, cannot collide with host CSS |
49
+ | `*[data-has-dotfill]`, `*[data-has-dotfill] .dotfill` | `data-` attribute scoping is sufficient |
50
+ | `svg .math-inline`, `svg mjx-container`, etc. | SVG context selectors |
51
+
52
+ ### Exceptions (scoped only, no bare)
53
+
54
+ | Selector | Reason |
55
+ |---|---|
56
+ | `code`, `pre code`, `pre`, `table`, `blockquote`, `img`, `sup`, `h1`–`h6` | Generic HTML elements — bare selectors would affect all elements on host page |
57
+
58
+ ---
59
+
60
+ ## Non-Goals
61
+
62
+ - Adding a `.mmd` wrapper class (rejected: `#setText` already serves as wrapper).
63
+ - Renaming CSS classes `.tabular` → `.mmd-tabular` (rejected: breaking change with no real benefit).
64
+ - Shadow DOM encapsulation.
65
+
66
+ ---
67
+
68
+ ## Existing Protection (no changes needed)
69
+
70
+ | Element | Protection | Mechanism |
71
+ |---|---|---|
72
+ | Generic `<h1>`–`<h6>`, `<table>`, `<blockquote>`, `<pre>`, `<code>` | `#setText`, `#preview-content` | ID specificity (1,0,1) |
73
+ | `.tabular` display | `display: inline-table !important` | `!important` |
74
+ | `.tabular td` borders, padding | `border-style: none !important`, `padding !important` | `!important` |
75
+ | `.tabular tr` borders | `border-top/bottom: none !important` | `!important` |
76
+ | `<td>` text-align | `style="text-align: ..."` | Inline style |
77
+ | `<ul>/<ol>` list-style-type | `style="list-style-type: ..."` | Inline style |
78
+ | `<blockquote>` margins, padding | `style="margin: ...; padding: ..."` | Inline style (forDocx) |
79
+
80
+ ---
81
+
82
+ ## Changes by File
83
+
84
+ ### `src/styles/index.ts` — restructured into sub-functions
85
+
86
+ Monolithic `MathpixStyle` function split into 10 named sub-functions composed via array join:
87
+
88
+ ```typescript
89
+ export const MathpixStyle = (...) => [
90
+ layoutStyles({ setTextAlignJustify, maxWidth, isPptx }),
91
+ mathStyles(maxWidth),
92
+ imageStyles(),
93
+ blockquoteStyles(useColors),
94
+ codeBlockStyles(useColors),
95
+ tableStyles(useColors),
96
+ docStructureStyles(),
97
+ inlineTextStyles(useColors),
98
+ miscStyles(),
99
+ printStyles(),
100
+ ].join('');
101
+ ```
102
+
103
+ Scoped selectors added for: `.proof`, `.theorem`, `.main-title`, `.author`, `.section-title`, `.abstract`, `.text-url`, `mark`, `span[data-underline-type] mark`, `.smiles`, `div.svg-container`. Bare `h1, h2, ...` in `maxWidth` overflow block scoped as `#setText > h1, #setText > h2, ...`.
104
+
105
+ Dead code removed: `.empty` (never generated), `.preview-right` (used as id, not class), `scaleEquation` parameter (accepted but never used in CSS output).
106
+
107
+ Specificity side-effect fix: `.tabular` had `margin: 0` which at (0,1,0) was overridden by `#setText table { margin-bottom: 1em }` (1,0,1). After scoping, `#setText .tabular` (1,1,0) beats `#setText table` (1,0,1), dropping the margin. Fixed by replacing `margin: 0` with `margin: 0 0 1em` so `.tabular` explicitly declares its own bottom margin. Additionally, `font-size: inherit` and other defensive defaults now ensure `.tabular` renders consistently regardless of context (e.g., standalone vs nested inside a list) — previously, list context could affect table width and font size via cascade.
108
+
109
+ `useColors=false` color leaks fixed: blockquote `border-left`, table `border`, and `mark` `background-color` now gated behind `useColors`.
110
+
111
+ Bug fix: `div.svg-container` child combinator consistency (`>` for both `#preview-content` and `#setText`).
112
+
113
+ ### `src/styles/styles-tabular.ts` — replaced `.table_tabular .tabular` with ID scoping
114
+
115
+ Before (commit f0e068a): specificity boosted via `.table_tabular .tabular` compound selector.
116
+ Now: replaced with `#preview-content .tabular, #setText .tabular` — cleaner, consistent with other files.
117
+
118
+ ```css
119
+ .tabular,
120
+ #preview-content .tabular, #setText .tabular {
121
+ display: inline-table !important;
122
+ width: auto;
123
+ /* ... */
124
+ }
125
+ ```
126
+
127
+ Also scoped: `.table_tabular`, `.tabular th/tr/td/td>p`, `.tabular td._empty`, `.tabular td .f`, `.figure_img`, `div.figure_img img`, dark theme selectors.
128
+
129
+ Note: `.sub-table` rule moved here from `index.ts` (where it didn't belong).
130
+
131
+ ### `src/styles/styles-code.ts` — scoped hljs, normalized indentation
132
+
133
+ All 19 `.hljs-*` rule blocks now follow bare + scoped pattern. Indentation normalized to 0/2 (0 for selectors, 2 for properties).
134
+
135
+ ### `src/styles/styles-lists.ts` — scoped all selectors
136
+
137
+ All list selectors (`ol.enumerate`, `ul.itemize`, `.li_enumerate`, `.li_level`, `.not_number`) now have bare + scoped variants.
138
+
139
+ ### `src/styles/halpers.ts` → `src/styles/helpers.ts` — renamed, cleaned up
140
+
141
+ - Fixed typo in filename: `halpers` → `helpers`
142
+ - Fixed `max-width:` formatting (added space after colon)
143
+ - Added scoped variants for `.math-block`, `.smiles`, `.smiles-inline`, `.table_tabular`
144
+ - Combined h1-h6 `::-webkit-scrollbar` into single `hideScroll()` call
145
+ - Normalized indentation
146
+
147
+ ### `src/mathpix-markdown-model/index.ts`
148
+
149
+ - Import path updated: `halpers` → `helpers`
150
+ - Removed `scaleEquation` from `StyleBundleOpts` interface, `buildStyles()`, and all public method signatures
151
+
152
+ ### `tests/_styles.js`
153
+
154
+ - Updated `MathpixStyle` calls: removed `scaleEquation` argument
155
+ - Updated `max-width` assertion: `'max-width:800px;'` → `'max-width: 800px;'`
156
+ - Added `t()` trim helper for composition/buildStyles assertions (accounts for `parts.map(s => s.trim()).join('\n')` in `buildStyles`)
157
+ - Added `tabularStyles(isPptx=true)` snapshot test
158
+ - Added `codeStyles(false)` coverage in `getMathpixStyle(useColors=false)` test
159
+ - Added `tabularStyles(true, true)` assertion in `buildStyles isPptx` test
160
+ - All 79 tests pass
161
+
162
+ ### Snapshot files
163
+
164
+ All 17 `tests/_data/_styles/*.snap.css` files regenerated (including `tabularStyles-pptx`).
165
+
166
+ ---
167
+
168
+ ## Style system improvements (from prior commits)
169
+
170
+ ### `buildStyles(opts: StyleBundleOpts)` — single style builder
171
+
172
+ All 4 style assembly points (`loadMathJax`, `getMathpixStyleOnly`, `getMathpixStyle`, `getMathpixMarkdownStyles`) delegate to a single `buildStyles()` method.
173
+
174
+ ```typescript
175
+ interface StyleBundleOpts {
176
+ setTextAlignJustify?: boolean;
177
+ useColors?: boolean;
178
+ maxWidth?: string;
179
+ isPptx?: boolean;
180
+ resetBody?: boolean;
181
+ container?: boolean;
182
+ mathjax?: boolean;
183
+ code?: boolean; // default: true
184
+ preview?: boolean;
185
+ toc?: boolean;
186
+ tocContainerName?: string;
187
+ menu?: boolean;
188
+ }
189
+ ```
190
+
191
+ Module composition per caller:
192
+
193
+ | Module | loadMathJax | getMathpixStyleOnly | getMathpixStyle | getMathpixMarkdownStyles |
194
+ |---|:---:|:---:|:---:|:---:|
195
+ | resetBody | conditional | - | - | - |
196
+ | container | - | - | + | + |
197
+ | mathjax | - | + | + | + |
198
+ | MathpixStyle | + | + | + | + |
199
+ | code | + | + | + | - |
200
+ | tabular | + | + | + | + |
201
+ | lists | + | + | + | + |
202
+ | preview | - | - | if stylePreview | - |
203
+ | toc | + | - | if preview+toc | - |
204
+ | menu+clipboard | + | + | if stylePreview | - |
205
+
206
+ ### `loadMathJax` DOM re-injection fix
207
+
208
+ Previously, if `#Mathpix-styles` already existed in the DOM, `loadMathJax()` skipped style update entirely. Now it updates `innerHTML` of the existing element.
209
+
210
+ ### `useColors` propagation
211
+
212
+ Added `useColors` parameter to `loadMathJax`, `getMathpixStyleOnly`, `getMathpixStyle` — passed through to all style functions.
213
+
214
+ ### `codeStyles` conversion
215
+
216
+ Converted from static string to function accepting `useColors` parameter.
217
+
218
+ ### Pre-existing bug fixes
219
+
220
+ - Missing dot: `math-inline svg` → `.math-inline svg` in `@media print`
221
+ - Missing dot: `svg math-block` → `svg .math-block`
222
+ - Missing template interpolation: `#{containerName}` → `#${containerName}` in TocStyle
223
+ - Dead code: removed empty `if (showToc) {}`
224
+
225
+ ### CSS output cleanup
226
+
227
+ - All style files normalized to 0/2 indentation (0 spaces for selectors, 2 spaces for properties).
228
+ - `buildStyles` refactored from string concatenation to `parts.map(s => s.trim()).join('\n')` — eliminates blank lines between CSS modules.
229
+ - Removed duplicate `overflow-x: auto` in `mjx-container` rule (was emitted both unconditionally and conditionally when `maxWidth` is set).
230
+ - Color constants extracted into `src/styles/colors.ts` (link, text, border, background, hljs, toc, menu, clipboard colors).
231
+ - `src/contex-menu/styles.ts` and `src/copy-to-clipboard/clipboard-copy-styles.ts` refactored: colors moved to constants, formatting normalized, minor CSS optimizations (`0px` → `0`, padding shorthand).
232
+
233
+ ---
234
+
235
+ ## Downstream Impact
236
+
237
+ - Consumers that override MMD class selectors (e.g., `#preview-main .tabular { width: 100% }`) at specificity (1,1,0) — same as the new scoped selectors. Consumer styles that load after MMD styles win by cascade order. No breakage expected.
238
+ - Consumers with their own `.math-block`/`.math-inline` SCSS — bare selectors preserved, no breakage.
239
+ - `auto-render.ts` uses `querySelectorAll('.math-inline, .math-block')` — DOM query, not affected by CSS changes.
240
+
241
+ ---
242
+
243
+ ## Constraints / Invariants
244
+
245
+ - HTML output class names unchanged — no downstream breakage.
246
+ - Public API method signatures changed: `scaleEquation` parameter removed (was unused). Positional callers must shift arguments. `buildStyles(opts)` available as named-parameter alternative.
247
+ - Inherited CSS properties (`font-family`, `color`, `line-height`) intentionally cascade from host into MMD content.
248
+
249
+ ---
250
+
251
+ ## Done When
252
+
253
+ - [x] All MMD class selectors scoped via `#preview-content`/`#setText` (or justified exception)
254
+ - [x] Defensive defaults for tables, figures, lists
255
+ - [x] `.table_tabular .tabular` replaced with ID scoping
256
+ - [x] hljs selectors scoped in styles-code.ts
257
+ - [x] lists selectors scoped in styles-lists.ts
258
+ - [x] `halpers.ts` → `helpers.ts` rename + cleanup
259
+ - [x] `index.ts` restructured into sub-functions
260
+ - [x] Dead code removed (`scaleEquation`, `.empty`, `.preview-right`)
261
+ - [x] `buildStyles(opts)` single builder with `StyleBundleOpts`
262
+ - [x] `loadMathJax` DOM re-injection fix
263
+ - [x] `useColors` propagated through all style functions
264
+ - [x] Pre-existing bugs fixed
265
+ - [x] Snapshot + composition + buildStyles tests (79 tests)
266
+ - [x] All existing tests pass
267
+ - [x] PR reviewed and merged
@@ -1,13 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getMaxWidthStyle = void 0;
4
- var getMaxWidthStyle = function (maxWidth, isHideScroll) {
5
- if (maxWidth === void 0) { maxWidth = ''; }
6
- if (isHideScroll === void 0) { isHideScroll = false; }
7
- if (!maxWidth) {
8
- return '';
9
- }
10
- return "\n #setText {\n ".concat('max-width:' + maxWidth + ';', "\n }\n #setText > div {\n overflow-x: auto; \n -webkit-overflow-scrolling: touch;\n }\n \n .math-block {\n min-width: unset;\n overflow-x: auto; \n -webkit-overflow-scrolling: touch;\n }\n \n ").concat(isHideScroll ? '#setText > div::-webkit-scrollbar { display: none; }' : '', "\n \n ").concat(isHideScroll ? '#setText > blockquote::-webkit-scrollbar { display: none; }' : '', "\n ").concat(isHideScroll ? '#setText > h1::-webkit-scrollbar { display: none; }' : '', "\n ").concat(isHideScroll ? '#setText > h2::-webkit-scrollbar { display: none; }' : '', "\n ").concat(isHideScroll ? '#setText > h3::-webkit-scrollbar { display: none; }' : '', "\n ").concat(isHideScroll ? '#setText > h4::-webkit-scrollbar { display: none; }' : '', "\n ").concat(isHideScroll ? '#setText > h5::-webkit-scrollbar { display: none; }' : '', "\n ").concat(isHideScroll ? '#setText > h6::-webkit-scrollbar { display: none; }' : '', "\n \n ").concat(isHideScroll ? '.table_tabular::-webkit-scrollbar { display: none; }' : '', "\n \n ").concat(isHideScroll ? 'mjx-container::-webkit-scrollbar { display: none; }' : '', "\n \n mjx-container[jax=\"SVG\"] > svg { \n overflow-x: auto; \n }\n \n ").concat(isHideScroll ? 'mjx-container[jax="SVG"] > svg::-webkit-scrollbar { display: none; }' : '', "\n \n .smiles-inline, .smiles {\n ").concat('max-width:' + maxWidth + ';', "\n overflow-x: auto;\n }\n \n ").concat(isHideScroll ? '.smiles::-webkit-scrollbar { display: none; }' : '', "\n ").concat(isHideScroll ? '.smiles-inline::-webkit-scrollbar { display: none; }' : '', "\n ");
11
- };
12
- exports.getMaxWidthStyle = getMaxWidthStyle;
13
- //# sourceMappingURL=halpers.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"halpers.js","sourceRoot":"","sources":["../../src/styles/halpers.ts"],"names":[],"mappings":";;;AAAO,IAAM,gBAAgB,GAAG,UAAC,QAAqB,EAAE,YAAoB;IAA3C,yBAAA,EAAA,aAAqB;IAAE,6BAAA,EAAA,oBAAoB;IAC1E,IAAI,CAAC,QAAQ,EAAE;QACb,OAAO,EAAE,CAAA;KACV;IACD,OAAO,kCAED,YAAY,GAAG,QAAQ,GAAG,GAAG,8PAa/B,YAAY,CAAC,CAAC,CAAC,uDAAuD,CAAC,CAAC,CAAC,EAAE,yBAE3E,YAAY,CAAC,CAAC,CAAC,8DAA8D,CAAC,CAAC,CAAC,EAAE,mBAClF,YAAY,CAAC,CAAC,CAAC,sDAAsD,CAAC,CAAC,CAAC,EAAE,mBAC1E,YAAY,CAAC,CAAC,CAAC,sDAAsD,CAAC,CAAC,CAAC,EAAE,mBAC1E,YAAY,CAAC,CAAC,CAAC,sDAAsD,CAAC,CAAC,CAAC,EAAE,mBAC1E,YAAY,CAAC,CAAC,CAAC,sDAAsD,CAAC,CAAC,CAAC,EAAE,mBAC1E,YAAY,CAAC,CAAC,CAAC,sDAAsD,CAAC,CAAC,CAAC,EAAE,mBAC1E,YAAY,CAAC,CAAC,CAAC,sDAAsD,CAAC,CAAC,CAAC,EAAE,yBAE1E,YAAY,CAAC,CAAC,CAAC,uDAAuD,CAAC,CAAC,CAAC,EAAE,6BAE3E,YAAY,CAAC,CAAC,CAAC,sDAAsD,CAAC,CAAC,CAAC,EAAE,yGAM1E,YAAY,CAAC,CAAC,CAAC,uEAAuE,CAAC,CAAC,CAAC,EAAE,0DAGzF,YAAY,GAAG,QAAQ,GAAG,GAAG,yDAI/B,YAAY,CAAC,CAAC,CAAC,gDAAgD,CAAC,CAAC,CAAC,EAAE,mBACpE,YAAY,CAAC,CAAC,CAAC,uDAAuD,CAAC,CAAC,CAAC,EAAE,SAC9E,CAAA;AACH,CAAC,CAAC;AA/CW,QAAA,gBAAgB,oBA+C3B"}
File without changes