A simple example for using Milkdown with Svelte.
-
Clone the repo:
git clone https://github.com/semanticdata/svelte-milkdown.git
. -
Install dependencies:
pnpm install
. -
Run the example:
pnpm start
. -
Open
http://localhost:5173/
in your browser.
- Svelte - Documentation
- Milkdown - Documentation
By default, milkdown will create editor on the document.body. Alternatively, you can also point out which dom node you want it to load into:
import {rootCtx} from '@milkdown/core'
Editor.make().config((ctx) => {
ctx.set(rootCtx, document.querySelector('#editor'))
})
It's also possible to just pass a selector to rootCtx:
The selector will be passed to document.querySelector to get the dom.
import {rootCtx} from '@milkdown/core'
Editor.make().config((ctx) => {
ctx.set(rootCtx, '#editor')
})
We support three types of default values:
- Markdown strings.
- HTML DOM.
- Prosemirror documentation JSON.
You can set a markdown string as the default value of the editor.
import {defaultValueCtx} from '@milkdown/core'
const defaultValue = '# Hello milkdown'
Editor.make().config((ctx) => {
ctx.set(defaultValueCtx, defaultValue)
})
And then the editor will be rendered with default value.
You can also use HTML as default value.
Let's assume that we have the following html snippets:
<div id="pre">
<h1>Hello milkdown!</h1>
</div>
Then we can use it as a defaultValue with a type specification:
import {defaultValueCtx} from '@milkdown/core'
const defaultValue = {
type: 'html',
dom: document.querySelector('#pre')
}
Editor.make().config((ctx) => {
ctx.set(defaultValueCtx, defaultValue)
})
We can also use a JSON object as a default value.
This JSON object can be obtained by a listener through the listener-plugin, for example:
import {listener, listenerCtx} from '@milkdown/plugin-listener'
let jsonOutput
Editor.make()
.config((ctx) => {
ctx.get(listenerCtx).updated((ctx, doc, prevDoc) => {
jsonOutput = doc.toJSON()
})
})
.use(listener)
Then we can use this jsonOutput as default Value:
import {defaultValueCtx} from '@milkdown/core'
const defaultValue = {
type: 'json',
value: jsonOutput
}
Editor.make().config((ctx) => {
ctx.set(defaultValueCtx, defaultValue)
})
You can inspect the editor's status through the status property.
import {Editor, EditorStatus} from '@milkdown/core'
const editor = Editor.make().use(/*some plugins*/)
assert(editor.status === EditorStatus.Idle)
editor.create().then(() => {
assert(editor.status === EditorStatus.Created)
})
assert(editor.status === EditorStatus.OnCreate)
editor.destroy().then(() => {
assert(editor.status === EditorStatus.Destroyed)
})
assert(editor.status === EditorStatus.OnDestroyed)
You can also listen to the status changes:
import { Editor, EditorStatus } from '@milkdown/core';
const editor = Editor.make().use(/*some plugins*/);
editor.onStatusChange((status: EditorStatus) => {
console.log(status);
});
As mentioned above, you can add a listener to the editor, in order to get it's value when needed.
Markdown Listener
You can add markdown listener to get the editor's contents as a markdown string.
You can add as many listeners as you want, all the listeners will be triggered at once.
import {listener, listenerCtx} from '@milkdown/plugin-listener'
let output = ''
Editor.make()
.config((ctx) => {
ctx.get(listenerCtx).markdownUpdated((ctx, markdown, prevMarkdown) => {
output = markdown
})
})
.use(listener)
You can also listen to the raw prosemirror document node, and do things you want from there.
import {listener, listenerCtx} from '@milkdown/plugin-listener'
let jsonOutput
Editor.make()
.config((ctx) => {
ctx.get(listenerCtx).updated((ctx, doc, prevDoc) => {
jsonOutput = doc.toJSON()
})
})
.use(listener)
For more details about listeners, please check Using Listeners.
You can set the editor to readonly mode by setting the editable property.
import {editorViewOptionsCtx} from '@milkdown/core'
let readonly = false
const editable = () => !readonly
Editor.make().config((ctx) => {
ctx.update(editorViewOptionsCtx, (prev) => ({
...prev,
editable
}))
})
// set to readonly after 5 secs.
setTimeout(() => {
readonly = true
}, 5000)
You can use an action to get the context value in a running editor on demand.
For example, to get the markdown string by running an action:
import {Editor, editorViewCtx, serializerCtx} from '@milkdown/core'
async function playWithEditor() {
const editor = await Editor.make().use(commonmark).create()
const getMarkdown = () =>
editor.action((ctx) => {
const editorView = ctx.get(editorViewCtx)
const serializer = ctx.get(serializerCtx)
return serializer(editorView.state.doc)
})
// get markdown string:
getMarkdown()
}
We provide some macros out of the box, you can use them as actions:
import {insert} from '@milkdown/utils'
editor.action(insert('# Hello milkdown'))
For more details about macros, please check macros.
You can call editor.destroy to destroy an existing editor. You can create a new editor again with editor.create.
await editor.destroy()
// Then create again
await editor.create()
If you just want to recreate the editor, you can use editor.create, it will destroy the old editor and create a new one.
await editor.create()
// This equals to call `editor.destroy` and `editor.create` again.
await editor.create()
If you want to clear the plugins and configs for the editor when calling editor.destroy, you can pass true to editor.destroy.
await editor.destroy(true)
Milkdown provides the following official plugins: | name | description | | :--------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------- | | @milkdown/preset-commonmark | Add commonmark syntax support | | @milkdown/preset-gfm | Add gfm syntax support | | @milkdown/plugin-history | Add undo & redo support | | @milkdown/plugin-clipboard | Add markdown copy & paste support | | @milkdown/plugin-cursor | Add drop & gap cursor | | @milkdown/plugin-listener | Add listener support | | @milkdown/plugin-collaborative | Add collaborative editing support | | @milkdown/plugin-prism | Add prism support for code block highlight | | @milkdown/plugin-math | Add LaTeX support for math | | @milkdown/plugin-tooltip | Add selected tooltip for text | | @milkdown/plugin-slash | Add slash commands support | | @milkdown/plugin-emoji | Add emoji support | | @milkdown/plugin-diagram | Add mermaid diagram support | | @milkdown/plugin-indent | Add tab indent support | | @milkdown/plugin-upload | Add drop and upload support |
- milkdown-plugin-shiki
Add shiki support for code block highlight. - @star-dancer/milkdown
Angular integration for milkdown. - @ezone-devops/milkdown-plugin-directive-fallback
Render all directive as text to avoid parse error when use remark-directive. - milkdown-plugin-image-picker
Add support for select and upload pictures from file picker. - milkdown-plugin-placeholder
π Placeholder plugin for milkdown. - @milkdown-lab/plugin-split-editing
Show split editing view for milkdown. - milkdown-lab
Unofficial plugins collection for milkdown.
- milkdown-vscode
Use milkdown as markdown editor of VSCode. - standardnotes
Use milkdown as editor of Standard Notes, it's made by the official of standardnotes. - tagspaces
Use milkdown as editor of markdown files. - MarginNote-Milkdown
Use milkdown as markdown editor of MarginNote, it's made by the official of MarginNote. MarginNote is a brand new e-reader to better study and digest your books. - lactose
A web based note-taking tool. - vite-plugin-book
A magical vite plugin that helps you to generate and manage documentation website. - Howdz Dashboard
Custom your personal browser start page from some configurable components. - Doclea
Online doc editor. - ezone
δΈη«εΌδΊεηδΌδΈη εεεδΈζθ½εΉ³ε°. - standardnotes-milkdown
Use milkdown as editor of Standard Notes. - typelog
Microblogging platform for devs. Uses milkdown as the editor for writing posts and comments.
The site uses various technologies cobbled together. Here's some of them:
- Vite: next generation frontend tooling.
- Svelte: s new way to build web applications.
- Milkdown: plugin driven Markdown framework/editor.
- Tailwind CSS: utility-first CSS framework.
- Prettier: opinionated code formatter.
Source code in this repository is available under the MIT License.