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.