@lapismd/mira 0.0.2 → 0.0.3

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @lapismd/mira
2
2
 
3
+ ## 0.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [#3](https://github.com/lapismd/mira-mde/pull/3) [`31e2502`](https://github.com/lapismd/mira-mde/commit/31e2502e185f883390165851e146a3823c6b9274) Thanks [@stevejuma](https://github.com/stevejuma)! - Relicense the public Mira packages to Apache 2.0.
8
+
9
+ - [#7](https://github.com/lapismd/mira-mde/pull/7) [`215a690`](https://github.com/lapismd/mira-mde/commit/215a6906130dbcf06f0a649e8a76074c6e24612f) Thanks [@stevejuma](https://github.com/stevejuma)! - Render list bullets, hanging indentation, and indentation guides when a consumer
10
+ mounts a Markdown editor directly on CodeMirror's root. Wrapped editors retain
11
+ the same marker geometry and caret behavior.
12
+
13
+ - [#7](https://github.com/lapismd/mira-mde/pull/7) [`215a690`](https://github.com/lapismd/mira-mde/commit/215a6906130dbcf06f0a649e8a76074c6e24612f) Thanks [@stevejuma](https://github.com/stevejuma)! - Preserve inline checkbox labels in live-preview editors embedded inside rendered
14
+ Markdown by excluding CodeMirror cursor-buffer images from Markdown image styles.
15
+
16
+ Refresh the repository's renderer and release-tool dependencies to patched
17
+ versions, retaining math rendering and trust restrictions in regression coverage.
18
+
19
+ - [#7](https://github.com/lapismd/mira-mde/pull/7) [`215a690`](https://github.com/lapismd/mira-mde/commit/215a6906130dbcf06f0a649e8a76074c6e24612f) Thanks [@stevejuma](https://github.com/stevejuma)! - Declare the reviewed KaTeX stylesheet package as a runtime dependency so public
20
+ Mira, editor, and React CSS resolves in isolated package-manager installations.
21
+
3
22
  ## 0.0.2
4
23
 
5
24
  ### Patch Changes
package/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- AGPL-3.0-or-later
1
+ Apache-2.0
2
2
 
3
- This project is licensed under the GNU Affero General Public License v3.0 or later.
4
- See <https://www.gnu.org/licenses/agpl-3.0.en.html>.
3
+ This project is licensed under the Apache License 2.0.
4
+ See <https://www.apache.org/licenses/LICENSE-2.0>.
@@ -4,6 +4,8 @@ import rehypeRaw from "rehype-raw";
4
4
  import rehypeSanitize, { defaultSchema } from "rehype-sanitize";
5
5
  import remarkEmoji from "remark-emoji";
6
6
  import remarkGfm from "remark-gfm";
7
+ import remarkMath from "remark-math";
8
+ import rehypeKatex from "rehype-katex";
7
9
  import { TYPE_TABLE, mdast2hastGridTablesHandler, } from "@adobe/mdast-util-gridtables";
8
10
  import { remarkHeadings, remarkWikiLinks } from "./remark";
9
11
  import { createParser } from "./renderer/utils";
@@ -13,6 +15,34 @@ describe("preview exports", () => {
13
15
  expect(typeof remarkWikiLinks).toBe("function");
14
16
  });
15
17
  });
18
+ describe("patched math renderer", () => {
19
+ it("renders inline and display math through the preview pipeline", () => {
20
+ const parser = createParser([remarkMath], [rehypeKatex]);
21
+ const ast = parser("Inline $x^2$.\n\n$$\nx^2 + y^2 = z^2\n$$");
22
+ const rendered = JSON.stringify(ast);
23
+ expect(rendered).toContain("katex-mathml");
24
+ expect(rendered).toContain("katex-display");
25
+ expect(findElement(ast, "math")).toBeDefined();
26
+ });
27
+ it("does not inherit polluted trust options when rendering authored math", () => {
28
+ const descriptor = Object.getOwnPropertyDescriptor(Object.prototype, "trust");
29
+ try {
30
+ Object.defineProperty(Object.prototype, "trust", {
31
+ value: true,
32
+ configurable: true,
33
+ });
34
+ const parser = createParser([remarkMath], [rehypeKatex]);
35
+ const ast = parser("$\\href{https://example.com}{untrusted}$");
36
+ expect(findElement(ast, "a")).toBeUndefined();
37
+ }
38
+ finally {
39
+ if (descriptor)
40
+ Object.defineProperty(Object.prototype, "trust", descriptor);
41
+ else
42
+ Reflect.deleteProperty(Object.prototype, "trust");
43
+ }
44
+ });
45
+ });
16
46
  describe("Carta markdown parity", () => {
17
47
  const dataPng = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==";
18
48
  it("renders reference-style base64 embedded images", () => {
@@ -2,13 +2,15 @@
2
2
  reading column, while preserving aspect ratio. Applies to both the
3
3
  dedicated image component and any raw <img> rendered through markdown
4
4
  (e.g. via rehype-raw HTML). Link-preview card thumbnails opt out since
5
- they already have their own, smaller sizing tuned for hover tooltips. */
5
+ they already have their own, smaller sizing tuned for hover tooltips.
6
+ CodeMirror cursor-buffer images must retain their zero-width inline layout
7
+ when an editor is nested inside rendered Markdown. */
6
8
  :is(
7
9
  .markdown-rendered,
8
10
  .markdown-preview-surface .markdown,
9
11
  .markdown-widget-shell
10
12
  )
11
- img:not(.mira-link-preview__asset),
13
+ img:not(.mira-link-preview__asset, .cm-widgetBuffer),
12
14
  .mira-markdown-image {
13
15
  border: 1px solid var(--mira-border);
14
16
  border-radius: var(--radius-s, 4px);
@@ -1,4 +1,4 @@
1
- .markdown-editor-surface .cm-editor {
1
+ :is(.markdown-editor-surface .cm-editor, .cm-editor.markdown-editor-surface) {
2
2
  cursor: text;
3
3
  font-family: var(--font-sans);
4
4
  font-size: var(--font-text-size);
@@ -37,25 +37,34 @@
37
37
  width: 0;
38
38
  }
39
39
 
40
- .markdown-editor-surface .cm-editor .cm-formatting-list-ul,
41
- .markdown-editor-surface .cm-editor .cm-formatting-list-ol {
40
+ :is(.markdown-editor-surface .cm-editor, .cm-editor.markdown-editor-surface)
41
+ .cm-formatting-list-ul,
42
+ :is(.markdown-editor-surface .cm-editor, .cm-editor.markdown-editor-surface)
43
+ .cm-formatting-list-ol {
42
44
  font-variant-numeric: tabular-nums;
43
45
  padding-inline-start: 0;
44
46
  }
45
47
 
46
- .markdown-editor-surface .cm-editor .cm-formatting-task {
48
+ :is(.markdown-editor-surface .cm-editor, .cm-editor.markdown-editor-surface)
49
+ .cm-formatting-task {
47
50
  color: var(--markdown-code-comment);
48
51
  }
49
52
 
50
- .markdown-live-preview-mode .cm-editor .cm-formatting-list-ul:not(.cm-line) {
53
+ :is(
54
+ .markdown-live-preview-mode .cm-editor,
55
+ .cm-editor.markdown-live-preview-mode
56
+ )
57
+ .cm-formatting-list-ul:not(.cm-line) {
51
58
  box-sizing: border-box;
52
59
  display: inline-block;
53
60
  inline-size: var(--hmd-unordered-list-marker-slot-width);
54
61
  padding-inline-start: var(--hmd-unordered-list-marker-padding-inline-start);
55
62
  }
56
63
 
57
- .markdown-live-preview-mode
58
- .cm-editor
64
+ :is(
65
+ .markdown-live-preview-mode .cm-editor,
66
+ .cm-editor.markdown-live-preview-mode
67
+ )
59
68
  .cm-formatting-list-bullet
60
69
  > span.cm-meta {
61
70
  color: transparent;
@@ -63,8 +72,10 @@
63
72
  position: relative;
64
73
  }
65
74
 
66
- .markdown-live-preview-mode
67
- .cm-editor
75
+ :is(
76
+ .markdown-live-preview-mode .cm-editor,
77
+ .cm-editor.markdown-live-preview-mode
78
+ )
68
79
  .cm-formatting-list-bullet
69
80
  > span.cm-meta::after {
70
81
  background-color: var(--list-marker-color);
@@ -82,13 +93,17 @@
82
93
  width: var(--list-bullet-size);
83
94
  }
84
95
 
85
- .markdown-live-preview-mode
86
- .cm-editor
96
+ :is(
97
+ .markdown-live-preview-mode .cm-editor,
98
+ .cm-editor.markdown-live-preview-mode
99
+ )
87
100
  .cm-line:hover
88
101
  .cm-formatting-list-bullet
89
102
  > span.cm-meta::after,
90
- .markdown-live-preview-mode
91
- .cm-editor
103
+ :is(
104
+ .markdown-live-preview-mode .cm-editor,
105
+ .cm-editor.markdown-live-preview-mode
106
+ )
92
107
  .cm-activeLine
93
108
  .cm-formatting-list-bullet
94
109
  > span.cm-meta::after {
@@ -96,11 +111,13 @@
96
111
  box-shadow: 0 0 0 4px var(--background-modifier-hover);
97
112
  }
98
113
 
99
- .markdown-editor-surface .cm-editor .HyperMD-list-line {
114
+ :is(.markdown-editor-surface .cm-editor, .cm-editor.markdown-editor-surface)
115
+ .HyperMD-list-line {
100
116
  white-space: pre-wrap;
101
117
  }
102
118
 
103
- .markdown-editor-surface .cm-editor .indented-wrapped-line {
119
+ :is(.markdown-editor-surface .cm-editor, .cm-editor.markdown-editor-surface)
120
+ .indented-wrapped-line {
104
121
  padding-inline-start: var(
105
122
  --hmd-indent-padding-measured,
106
123
  var(--hmd-indent-padding-fallback, 0px)
@@ -111,8 +128,7 @@
111
128
  );
112
129
  }
113
130
 
114
- .markdown-editor-surface
115
- .cm-editor
131
+ :is(.markdown-editor-surface .cm-editor, .cm-editor.markdown-editor-surface)
116
132
  .indented-wrapped-line:has(.cm-hmd-list-indent) {
117
133
  text-indent: calc(
118
134
  0px -
@@ -126,40 +142,54 @@
126
142
  );
127
143
  }
128
144
 
129
- .markdown-editor-surface .cm-editor .cm-line > * {
145
+ :is(.markdown-editor-surface .cm-editor, .cm-editor.markdown-editor-surface)
146
+ .cm-line
147
+ > * {
130
148
  text-indent: 0;
131
149
  }
132
150
 
133
- .markdown-editor-surface .cm-editor .cm-hmd-list-indent {
151
+ :is(.markdown-editor-surface .cm-editor, .cm-editor.markdown-editor-surface)
152
+ .cm-hmd-list-indent {
134
153
  display: inline-block;
135
154
  white-space: pre;
136
155
  }
137
156
 
138
- .markdown-editor-surface .cm-editor .cm-indent-guide {
157
+ :is(.markdown-editor-surface .cm-editor, .cm-editor.markdown-editor-surface)
158
+ .cm-indent-guide {
139
159
  min-width: var(--list-indent);
140
160
  }
141
161
 
142
- .markdown-editor-surface .cm-editor .cm-plain-indent-line,
143
- .markdown-editor-surface .cm-editor .cm-plain-indent-widget {
162
+ :is(.markdown-editor-surface .cm-editor, .cm-editor.markdown-editor-surface)
163
+ .cm-plain-indent-line,
164
+ :is(.markdown-editor-surface .cm-editor, .cm-editor.markdown-editor-surface)
165
+ .cm-plain-indent-widget {
144
166
  position: relative;
145
167
  }
146
168
 
147
- .markdown-editor-surface .cm-editor .cm-hmd-list-indent .cm-indent,
148
- .markdown-editor-surface .cm-editor .cm-plain-indent-widget .cm-indent {
169
+ :is(.markdown-editor-surface .cm-editor, .cm-editor.markdown-editor-surface)
170
+ .cm-hmd-list-indent
171
+ .cm-indent,
172
+ :is(.markdown-editor-surface .cm-editor, .cm-editor.markdown-editor-surface)
173
+ .cm-plain-indent-widget
174
+ .cm-indent {
149
175
  color: transparent;
150
176
  display: inline-block;
151
177
  position: relative;
152
178
  white-space: pre;
153
179
  }
154
180
 
155
- .markdown-editor-surface
156
- .cm-editor.cm-show-indentation-guides
181
+ :is(
182
+ .markdown-editor-surface .cm-editor.cm-show-indentation-guides,
183
+ .cm-editor.markdown-editor-surface.cm-show-indentation-guides
184
+ )
157
185
  .indented-wrapped-line {
158
186
  position: relative;
159
187
  }
160
188
 
161
- .markdown-editor-surface
162
- .cm-editor.cm-show-indentation-guides
189
+ :is(
190
+ .markdown-editor-surface .cm-editor.cm-show-indentation-guides,
191
+ .cm-editor.markdown-editor-surface.cm-show-indentation-guides
192
+ )
163
193
  .indented-wrapped-line::before {
164
194
  background-image: repeating-linear-gradient(
165
195
  to right,
@@ -181,8 +211,10 @@
181
211
  width: calc(var(--indent-guide-count, 0) * var(--indent-size, 4) * 1ch);
182
212
  }
183
213
 
184
- .markdown-editor-surface
185
- .cm-editor.cm-show-indentation-guides
214
+ :is(
215
+ .markdown-editor-surface .cm-editor.cm-show-indentation-guides,
216
+ .cm-editor.markdown-editor-surface.cm-show-indentation-guides
217
+ )
186
218
  .cm-activeLine.indented-wrapped-line::before {
187
219
  background-image: repeating-linear-gradient(
188
220
  to right,
@@ -208,12 +240,16 @@
208
240
  );
209
241
  }
210
242
 
211
- .markdown-editor-surface
212
- .cm-editor.cm-show-indentation-guides
243
+ :is(
244
+ .markdown-editor-surface .cm-editor.cm-show-indentation-guides,
245
+ .cm-editor.markdown-editor-surface.cm-show-indentation-guides
246
+ )
213
247
  .cm-hmd-list-indent
214
248
  .cm-indent-guide::before,
215
- .markdown-editor-surface
216
- .cm-editor.cm-show-indentation-guides
249
+ :is(
250
+ .markdown-editor-surface .cm-editor.cm-show-indentation-guides,
251
+ .cm-editor.markdown-editor-surface.cm-show-indentation-guides
252
+ )
217
253
  .cm-plain-indent-widget
218
254
  .cm-indent-guide::before {
219
255
  display: none;
@@ -1,3 +1,4 @@
1
+ // @vitest-environment jsdom
1
2
  import { readFileSync } from "node:fs";
2
3
  import { resolve } from "node:path";
3
4
  import { cwd } from "node:process";
@@ -6,8 +7,22 @@ const sourceModeStyles = () => readFileSync(resolve(cwd(), "src/preview/styles/s
6
7
  describe("source mode styles", () => {
7
8
  it("reserves full guide slots only for complete indentation guide segments", () => {
8
9
  const styles = sourceModeStyles();
9
- expect(styles).toContain(".markdown-editor-surface .cm-editor .cm-indent-guide");
10
- expect(styles).toContain("min-width: var(--list-indent)");
11
- expect(styles).not.toMatch(/\.markdown-editor-surface\s+\.cm-editor\s+\.cm-indent\s*\{[^}]*min-width:\s*var\(--list-indent\)/u);
10
+ const guideRules = Array.from(styles.matchAll(/([^{}]+)\{([^{}]*)\}/gu))
11
+ .map((match) => ({ selector: match[1], declarations: match[2] }))
12
+ .filter(({ declarations }) => /min-width:\s*var\(--list-indent\)/u.test(declarations));
13
+ expect(guideRules).toHaveLength(1);
14
+ for (const markup of [
15
+ '<div class="markdown-editor-surface"><div class="cm-editor"><span class="cm-indent-guide"></span><span class="cm-indent"></span></div></div>',
16
+ '<div class="cm-editor markdown-editor-surface"><span class="cm-indent-guide"></span><span class="cm-indent"></span></div>',
17
+ ]) {
18
+ const host = document.createElement("div");
19
+ host.innerHTML = markup;
20
+ const guide = host.querySelector(".cm-indent-guide");
21
+ const partial = host.querySelector(".cm-indent");
22
+ for (const { selector } of guideRules) {
23
+ expect(guide.matches(selector.trim())).toBe(true);
24
+ expect(partial.matches(selector.trim())).toBe(false);
25
+ }
26
+ }
12
27
  });
13
28
  });
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@lapismd/mira",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Composable Markdown editor, extension SDK, preview renderer, and UI for Mira.",
5
5
  "author": "Steve Juma <help@lapis.md>",
6
- "license": "AGPL-3.0-or-later",
6
+ "license": "Apache-2.0",
7
7
  "repository": {
8
8
  "type": "git",
9
9
  "url": "git+https://github.com/lapismd/mira-mde.git",
@@ -86,6 +86,7 @@
86
86
  "bits-ui": "2.18.1",
87
87
  "clsx": "^2.1.1",
88
88
  "hast-util-to-text": "^4.0.2",
89
+ "katex": "0.18.10",
89
90
  "lodash-es": "^4.17.21",
90
91
  "mdast-util-from-markdown": "^2.0.2",
91
92
  "mdast-util-gfm-table": "^2.0.0",
@@ -152,8 +153,7 @@
152
153
  "@types/lodash-es": "^4.17.12",
153
154
  "@types/mdast": "^4.0.4",
154
155
  "@types/unist": "^3.0.3",
155
- "katex": "^0.16.22",
156
- "svelte": "^5.46.1"
156
+ "svelte": "^5.57.1"
157
157
  },
158
158
  "publishConfig": {
159
159
  "access": "public",