@meowdown/core 0.63.1 → 0.64.1
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/README.md +25 -68
- package/dist/index.d.ts +352 -114
- package/dist/index.js +8044 -39
- package/dist/katex-chunk-CfdGokmi.js +3 -0
- package/dist/style.css +2 -0
- package/package.json +4 -4
- package/dist/katex-chunk-Ch7kgbXr.js +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# @meowdown/core
|
|
2
2
|
|
|
3
|
-
The engine
|
|
3
|
+
The engine behind Meowdown, a hybrid (live-preview) Markdown editor: Markdown
|
|
4
|
+
parsing, serializing, editing commands, and a default theme. Framework-free;
|
|
5
|
+
pairs with [@meowdown/react](https://www.npmjs.com/package/@meowdown/react).
|
|
4
6
|
|
|
5
7
|
[**Live demo**](https://meowdown.vercel.app/)
|
|
6
8
|
|
|
@@ -25,40 +27,22 @@ editor.mount(document.querySelector<HTMLElement>('#editor')!)
|
|
|
25
27
|
const markdown = docToMarkdown(editor.state.doc)
|
|
26
28
|
```
|
|
27
29
|
|
|
28
|
-
##
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
- Ordered lists (`1. item`, `2) item`, etc.)
|
|
35
|
-
- Blockquotes (`> quote`)
|
|
36
|
-
- Fenced code blocks (` ```lang\ncode\n``` `), keeping tilde fences (`~~~`) and fence lengths through a round-trip
|
|
37
|
-
- Indented code blocks (four leading spaces)
|
|
38
|
-
- Thematic breaks (`---`, `***`, `___`)
|
|
39
|
-
- Bold (`**bold**`), italic (`*italic*`), and inline code
|
|
40
|
-
- Inline and reference links (`[text](url)`, `[text][label]`, `[label][]`, `[label]`)
|
|
41
|
-
- Inline and reference images (``, `![alt][label]`)
|
|
42
|
-
- Link reference definitions (`[label]: url "title"`)
|
|
43
|
-
- Autolinks (`<https://example.com>`)
|
|
44
|
-
- Hard line breaks
|
|
45
|
-
- GitHub Flavored Markdown (GFM)
|
|
46
|
-
- Tables, including column alignment (`:--`, `:-:`, `--:`)
|
|
47
|
-
- Strikethrough (`~~text~~`)
|
|
48
|
-
- Task lists (`- [ ]`, `- [x]`)
|
|
49
|
-
- Autolinks for `www.`, scheme, and email URLs
|
|
50
|
-
- Wikilinks (`[[target]]` and `[[target|alias]]`)
|
|
51
|
-
- Highlight (`==highlight==`)
|
|
30
|
+
## Markdown features
|
|
31
|
+
|
|
32
|
+
[CommonMark](https://commonmark.org/) and [GFM](https://github.github.com/gfm/), plus:
|
|
33
|
+
|
|
34
|
+
- Wikilinks (`[[target]]`, `[[target|alias]]`)
|
|
35
|
+
- Wiki embeds (`![[path]]`)
|
|
52
36
|
- Tags (`#tag`)
|
|
53
|
-
-
|
|
54
|
-
- Math
|
|
55
|
-
|
|
56
|
-
- Display math (`$$` fences on their own lines), kept as `$$` through a round-trip
|
|
57
|
-
- ` ```math ` fenced code blocks
|
|
37
|
+
- Highlight (`==highlight==`)
|
|
38
|
+
- Math (`$x$`, `$$x$$`, and ` ```math ` fenced code blocks), rendered as native MathML
|
|
39
|
+
- Bare-domain autolinks (`google.com`), behind a curated TLD allowlist so `README.md` and `node.js` stay plain text
|
|
58
40
|
|
|
59
41
|
## Keyboard shortcuts
|
|
60
42
|
|
|
61
|
-
`Mod` is Cmd on macOS and Ctrl elsewhere.
|
|
43
|
+
`Mod` is Cmd on macOS and Ctrl elsewhere. Formatting shortcuts insert or remove
|
|
44
|
+
the literal Markdown delimiters around the selection; heading shortcuts toggle
|
|
45
|
+
the current block to that level (or back to a paragraph).
|
|
62
46
|
|
|
63
47
|
| Key | Action | Markdown |
|
|
64
48
|
| ---------------------- | --------------------------------------------------------- | ------------------- |
|
|
@@ -89,21 +73,24 @@ const markdown = docToMarkdown(editor.state.doc)
|
|
|
89
73
|
| `Shift-Meta-ArrowDown` | Select to the document end | |
|
|
90
74
|
| `Escape` | Collapse the selection | |
|
|
91
75
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
`
|
|
76
|
+
`Mod-Shift-7/8/9` wrap the current block, convert a list of a different kind in
|
|
77
|
+
place, and unwrap a list of the same kind back to a paragraph. `Alt-ArrowUp` /
|
|
78
|
+
`Alt-ArrowDown` move the block or list item with its nested children. Typing `[`
|
|
79
|
+
over a selection wraps it into an open wikilink (`[[selection`) with the
|
|
80
|
+
wikilink menu searching it. `EDITOR_KEY_BINDINGS` exports this table as a
|
|
81
|
+
literal object for host settings UIs.
|
|
95
82
|
|
|
96
83
|
## Round-trip fidelity
|
|
97
84
|
|
|
98
|
-
[`checkRoundTrip(markdown)`](https://npmx.dev/package-docs/@meowdown%2Fcore#function-checkRoundTrip) reports how faithfully
|
|
85
|
+
[`checkRoundTrip(markdown)`](https://npmx.dev/package-docs/@meowdown%2Fcore#function-checkRoundTrip) reports how faithfully Markdown survives a parse-then-serialize round trip: `'exact'`, `'normalizing'`, or `'lossy'`.
|
|
99
86
|
|
|
100
87
|
## Styling
|
|
101
88
|
|
|
102
|
-
`@meowdown/core/style.css` ships a default
|
|
89
|
+
`@meowdown/core/style.css` ships a default theme. Colors use `light-dark()`, so they follow the page's `color-scheme` (set `color-scheme: light dark` on `:root` for automatic dark mode). Override the `--meowdown-*` variables on `:root` or any ancestor; the full list, with a one-line description and default for each, lives in the commented `:root` block at the top of `style.css`, which is the single source of truth.
|
|
103
90
|
|
|
104
|
-
|
|
91
|
+
CSS is wrapped in `@layer meowdown` (sub-layers `meowdown.base`, `meowdown.theme`, `meowdown.editor`). An un-layered rule always beats a layered one, so any plain rule you write overrides meowdown with no `!important` and no specificity hacks. Put your overrides outside any `@layer`, or in a layer you declare after `meowdown`.
|
|
105
92
|
|
|
106
|
-
**With Tailwind CSS v4**, import `@meowdown/core/style.css` _after_ `@import 'tailwindcss'` so the `meowdown` layer sorts after Tailwind's `
|
|
93
|
+
**With Tailwind CSS v4**, import `@meowdown/core/style.css` _after_ `@import 'tailwindcss'` so the `meowdown` layer sorts after Tailwind's `base` (Preflight). If you also need Tailwind utilities to win over meowdown (while meowdown still beats Preflight), declare the layer order yourself:
|
|
107
94
|
|
|
108
95
|
```css
|
|
109
96
|
@layer theme, base, components, meowdown, utilities;
|
|
@@ -111,36 +98,6 @@ meowdown's CSS is wrapped in a cascade layer, `@layer meowdown` (with sub-layers
|
|
|
111
98
|
@import '@meowdown/core/style.css';
|
|
112
99
|
```
|
|
113
100
|
|
|
114
|
-
Two things the variable list cannot show: `--meowdown-gutter` is the horizontal editor padding, applied to the editable root's `.meowdown-content` class, not `.ProseMirror`, so the block handle's drag preview stays unpadded; floating UI such as the block handle lives inside it, so keep it at least `3.5rem`. `defineEditorExtension` puts `.meowdown-content` on the editable root itself, so every mount (the headless quick start above included) is padded from the first paint. The selection variables (`--meowdown-selection`, `--meowdown-node-outline`, `--meowdown-node-selection`) are standalone, not derived from `--meowdown-accent`, so selection can be restyled independently.
|
|
115
|
-
|
|
116
|
-
Tags (`#tag`) render as pills via the `.md-tag` class, tinted from `--meowdown-accent`. Wire click handling with `defineTagClickHandler(({ tag, event }) => ...)` (or `@meowdown/react`'s `onTagClick` prop); `tag` is read from the rendered text without the leading `#`.
|
|
117
|
-
|
|
118
|
-
Wikilinks (`[[target]]`/`[[target|alias]]`) render in place via a mark view as an immutable label (the alias, or the target when there is no alias), with the raw source hidden in hide and focus modes and shown dimmed in show mode. The label uses the `.md-wikilink-view-label` class, dashed-underlined and colored by `--meowdown-accent`. In every mark mode the link is a single immutable caret stop: arrowing onto it selects the whole source (ringed with `--meowdown-node-outline` in hide and focus, the native selection over the visible source in show), and Backspace/Delete remove it as a unit, and `Enter` on the selected unit fires the click handler instead of replacing it. Wire click navigation with `defineWikilinkClickHandler(({ target, event }) => ...)` (or `@meowdown/react`'s `onWikilinkClick` prop); `Mod-Enter` with the caret on a wikilink, tag, or Markdown link fires the same handler, with the `KeyboardEvent` as `event`. `defineWikilinkHoverHandler` reports the hovered target, source range, and visible anchor element, then reports `undefined` on leave, deletion, replacement, or editor teardown.
|
|
119
|
-
|
|
120
|
-
Markdown links render the label as an `<a href>` with the `.md-link` class, colored by `--meowdown-accent`; the source syntax dims in show mode and hides in hide and focus modes. This includes inline links (`[text](url)`), full references (`[text][label]`), collapsed references (`[label][]`), and shortcut references (`[label]`). Definitions use CommonMark label normalization and first-definition-wins semantics. Definitions remain visible and editable as literal source in the editor, while unresolved references remain literal and preserve nested formatting. Reference destinations are read-only through the link commands and menu because editing one safely requires a definition-aware workflow. Citing links update after a 200 ms pause in definition editing, which coalesces large fan-out restyles; definition-shaped textblocks longer than 1,024 characters stay literal and are not indexed. `[[target]]` continues to use meowdown's wikilink syntax. Wire click handling with `defineLinkClickHandler(({ href, event }) => ...)` (or `@meowdown/react`'s `onLinkClick` prop).
|
|
121
|
-
|
|
122
|
-
Low-level renderers can import `collectReferenceDefinitions` and `inlineTextToMarkChunksWithContext` directly from `@meowdown/core` to share the editor's definition collection and reference resolution.
|
|
123
|
-
|
|
124
|
-
Bare URLs autolink without `[text](url)` brackets and share the same `.md-link` rendering and click handling: a scheme URL (`https://example.com`), an angle autolink (`<https://example.com>`), a `www.` host (`www.example.com`), an email (`me@example.com`), and a bare domain (`google.com`, `sub.domain.io/path`). Bare domains are matched against a curated list of common TLDs, so file names and prose keep their dots without linkifying (`README.md`, `node.js`, `i.e.` stay plain text); reach for `[text](url)` or `<url>` to link anything off that list. Autolinks are derived live from the text, so editing one re-evaluates it; the caret sitting inside a link never un-links it.
|
|
125
|
-
|
|
126
|
-
Inline and reference images (``, `![alt][label]`, `![label][]`, and `![label]`) stay literal text and render in place via a mark view, with their raw source hidden in hide and focus modes. Add an inline image with [`defineImage`](https://npmx.dev/package-docs/@meowdown%2Fcore#function-defineImage) (or `@meowdown/react`'s image props) and wire click handling with [`defineImageClickHandler`](https://npmx.dev/package-docs/@meowdown%2Fcore#function-defineImageClickHandler) (`@meowdown/react`'s `onImageClick` prop).
|
|
127
|
-
|
|
128
|
-
Pasted or dropped files persist through [`defineFilePaste`](https://npmx.dev/package-docs/@meowdown%2Fcore#function-defineFilePaste) (or `@meowdown/react`'s `onFilePaste` prop): the handler persists each file and returns its markdown destination. An image (`image/*` MIME type) inserts ``; any other file inserts a `[name](src)` link; multiple files insert one link per line, in the order they appear in the drop. Without `onFilePaste`, file events are left to the browser's default handling. A host command that inserts file links itself (e.g. an attach-file picker) can build the same markdown with [`buildFileMarkdown`](https://npmx.dev/package-docs/@meowdown%2Fcore#function-buildFileMarkdown).
|
|
129
|
-
|
|
130
|
-
A host can render chosen file links as inline **file pills**: pass `resolveFileLink` to [`defineEditorExtension`](https://npmx.dev/package-docs/@meowdown%2Fcore#function-defineEditorExtension) (or `@meowdown/react`'s `resolveFileLink` prop) to claim inline or resolved reference links by their href (e.g. everything under `assets/`), and add [`defineFileView`](https://npmx.dev/package-docs/@meowdown%2Fcore#function-defineFileView) to render each claimed link as a pill: a file-kind icon, the name, and the size supplied (possibly async) by `resolveFileInfo`. The markdown text is untouched, and a claimed link behaves like an image: one caret unit with an editable source, clicks (and `Enter` on the selected pill or `Mod-Enter` with the caret on it) reported through [`defineFileClickHandler`](https://npmx.dev/package-docs/@meowdown%2Fcore#function-defineFileClickHandler) (`@meowdown/react`'s `onFileClick`) rather than the link click handler, and no link hover or edit menu.
|
|
131
|
-
|
|
132
|
-
Rendered images are resizable: drag the corner handle and the chosen size is written back into the source as a trailing comment, `<!-- {"width":320,"height":240} -->`, which round-trips as plain Markdown. A comment immediately after an image is folded into its mark and drives the image's `width` and `height` attributes, so the box keeps its dimensions before the image loads; any other comment stays literal text.
|
|
133
|
-
|
|
134
|
-
GFM table column alignment (`| :-: |` in the delimiter row) is kept as an `align` attribute on every cell and rendered through a `data-align` DOM attribute (`text-align` in the bundled stylesheet). Alignment is a column property: the header row's cells carry the source of truth, data cells (including rows inserted later) follow it automatically. Change it with the `setTableColumnAlign` command (`editor.commands.setTableColumnAlign('center')`, `null` resets to `---`), and read the alignment of the selection's column with [`getTableColumnAlign`](https://npmx.dev/package-docs/@meowdown%2Fcore#function-getTableColumnAlign).
|
|
135
|
-
|
|
136
|
-
Pasting a lone tweet or YouTube link can auto-embed it: [`defineEmbedPaste`](https://npmx.dev/package-docs/@meowdown%2Fcore#function-defineEmbedPaste) (`@meowdown/react`'s `embedPaste` prop, on by default).
|
|
137
|
-
|
|
138
|
-
The clipboard pipeline ships inside `defineEditorExtension`. Copying writes two flavors: `text/html` is standard semantic HTML (`<h3>`, `<ol><li>`, `<strong>`, real `<table>`) with the Markdown source preserved in `data-md` attributes so meowdown-to-meowdown pastes stay byte-exact, and `text/plain` is Markdown, where opening markers such as ATX heading and blockquote prefixes are kept when the selection includes the block's content start, while fenced code blocks and tables keep their markers only when selected completely; the mark mode decides the inline layer (hide strips the syntax characters, focus and show keep the full source). Pasting picks a path by flavor: meowdown's own HTML (stamped `data-meowdown`) parses natively; foreign rich-text HTML, including other ProseMirror editors, converts to Markdown through the unified (rehype / remark) pipeline; plain text follows Markdown newline semantics (a blank line separates paragraphs without inserting an empty one, a single newline stays a soft break) while a Shift-paste keeps ProseMirror's line-per-paragraph behavior; a paste landing in a code block stays plain text.
|
|
139
|
-
|
|
140
|
-
Enter at the end of the document's first heading (the title line) can start a fresh empty bullet instead of a plain paragraph: [`defineBulletAfterHeading`](https://npmx.dev/package-docs/@meowdown%2Fcore#function-defineBulletAfterHeading) (`@meowdown/react`'s `bulletAfterHeading` prop). Not part of `defineEditorExtension`.
|
|
141
|
-
|
|
142
|
-
An arrow press that can move the caret no further can notify the host, so it can move focus elsewhere (a previous/next note or page): [`defineExitBoundaryHandler`](https://npmx.dev/package-docs/@meowdown%2Fcore#function-defineExitBoundaryHandler) (`@meowdown/react`'s `onExitBoundary` prop). Not part of `defineEditorExtension`.
|
|
143
|
-
|
|
144
101
|
## API
|
|
145
102
|
|
|
146
103
|
See the full API reference [here](https://npmx.dev/package-docs/@meowdown%2Fcore/).
|