Getting Started
This guide describes how to get a basic instance of ProseMark running on a web app. It’s equivalent to our Demo.
Installing ProseMark
Section titled “Installing ProseMark”The main npm package for ProseMark is @prosemark/core
; install that using your package manager of choice. You may also be interested in installing these optional ProseMark packages:
@prosemark/render-html
: renders HTML tags within the markdown content. Supports most standard attributes; sanitized using DOMPurify.
You will also need to install some standard CodeMirror packages:
npm install @codemirror/view @codemirror/lang-markdown @lezer/markdown @codemirror/language-data
Setting Up the Editor
Section titled “Setting Up the Editor”We’ll start by creating the DOM element to which we can mount the CodeMirror editor. In vanilla HTML/CSS/JavaScript, this would look something like this:
...<div id="codemirror-container"></div>...
Then, in our JavaScript file, we’ll set up the CodeMirror editor object. Here, we’re assuming that you have a bundler set up that supports ESM imports.
import { EditorView } from '@codemirror/view';import { markdown } from '@codemirror/lang-markdown';import { GFM } from '@lezer/markdown';
import { prosemarkBasicSetup, prosemarkBaseThemeSetup, prosemarkMarkdownSyntaxExtensions,} from '@prosemark/core';import { htmlBlockExtension } from '@prosemark/render-html';
const editor = new EditorView({ doc: "# Hello World", parent: document.getElementById('codemirror-container')!, extensions: [ // Adds support for the Markdown language markdown({ // adds support for standard syntax highlighting inside code fences codeLanguages: languages, extensions: [ // GitHub Flavored Markdown (support for autolinks, strikethroughs) GFM, // additional parsing tags for existing markdown features, backslash escapes, emojis prosemarkMarkdownSyntaxExtensions, ] }), // Basic prosemark extensions prosemarkBasicSetup(), // Theme extensions prosemarkBaseThemeSetup(), // Render HTML blocks (optional) htmlBlockExtension ]})
ProseMark can be styled using CSS variables. The following CSS is used in our demo:
:root { font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; line-height: 1.5; font-weight: 400;
font-synthesis: none; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
--pm-header-mark-color: oklch(82.8% 0.111 230.318); --pm-link-color: oklch(58.8% 0.158 241.966); --pm-muted-color: oklch(37.2% 0.044 257.287); --pm-code-background-color: oklch(92.9% 0.013 255.508); --pm-code-btn-background-color: oklch(86.9% 0.022 252.894); --pm-code-btn-hover-background-color: oklch(70.4% 0.04 256.788); --pm-blockquote-vertical-line-background-color: oklch(70.4% 0.04 256.788);
--pm-syntax-link: oklch(62.75% 0.188 259.38); --pm-syntax-keyword: oklch(58.13% 0.248 297.57); --pm-syntax-atom: oklch(51.29% 0.219 260.63); --pm-syntax-literal: oklch(57.38% 0.111 170.31); --pm-syntax-string: oklch(54.86% 0.184 25.53); --pm-syntax-regexp: oklch(65.88% 0.184 43.8); --pm-syntax-definition-variable: oklch(45.32% 0.171 260.3); --pm-syntax-local-variable: oklch(64.13% 0.09 184.42); --pm-syntax-type-namespace: oklch(49.1% 0.091 165.52); --pm-syntax-class-name: oklch(64.42% 0.11 168.83); --pm-syntax-special-variable-macro: oklch(52.58% 0.212 282.71); --pm-syntax-definition-property: oklch(42.1% 0.142 260.08); --pm-syntax-comment: oklch(62.79% 0.022 252.89); --pm-syntax-invalid: oklch(64.62% 0.203 29.2); --pm-cursor-color: black;}
:root[data-theme='dark'] { --pm-header-mark-color: oklch(44.3% 0.11 240.79); --pm-link-color: oklch(58.8% 0.158 241.966); --pm-muted-color: oklch(55.4% 0.046 257.417); --pm-code-background-color: oklch(27.9% 0.041 260.031); --pm-code-btn-background-color: oklch(37.2% 0.044 257.287); --pm-code-btn-hover-background-color: oklch(44.6% 0.043 257.281); --pm-blockquote-vertical-line-background-color: oklch(44.6% 0.043 257.281);
--pm-syntax-link: oklch(73.24% 0.17 258.63); --pm-syntax-keyword: oklch(70.05% 0.217 296.83); --pm-syntax-atom: oklch(65.69% 0.2 259.93); --pm-syntax-literal: oklch(71.27% 0.101 169.93); --pm-syntax-string: oklch(68.53% 0.164 25.1); --pm-syntax-regexp: oklch(76.88% 0.16 43.42); --pm-syntax-definition-variable: oklch(61.42% 0.158 259.6); --pm-syntax-local-variable: oklch(75.88% 0.082 184.11); --pm-syntax-type-namespace: oklch(64.51% 0.083 165.19); --pm-syntax-class-name: oklch(76.14% 0.1 168.52); --pm-syntax-special-variable-macro: oklch(66.67% 0.193 282.06); --pm-syntax-definition-property: oklch(58.92% 0.132 259.4); --pm-syntax-comment: oklch(74.9% 0.02 252.89); --pm-syntax-invalid: oklch(75.93% 0.182 28.91); --pm-cursor-color: white;}
#codemirror-container { min-height: 100px; width: 100%; --font: Inter; * { margin-top: 0px; }}