Skip to content
This repository has been archived by the owner on Aug 4, 2022. It is now read-only.

Commit

Permalink
Merge pull request #11 from curvenote/feat/schema
Browse files Browse the repository at this point in the history
📖  Schema updates and better typings
  • Loading branch information
rowanc1 authored May 5, 2021
2 parents e1b1628 + e6e6b73 commit fe441bf
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 25 deletions.
6 changes: 4 additions & 2 deletions src/parse/html/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Schema, DOMParser as DOMParserPM } from 'prosemirror-model';
import { DOMParser as DOMParserPM } from 'prosemirror-model';
import { setInnerHTML } from './utils';
import { Parser } from '../../types';
import { getSchema, UseSchema } from '../../schemas';


function migrateV0(element: HTMLDivElement, document: Document, DOMParser: Parser): HTMLDivElement {
Expand Down Expand Up @@ -63,8 +64,9 @@ export function migrateHTML(content: string, document: Document, DOMParser: Pars
}

export function fromHTML(
content: string, schema: Schema, document: Document, DOMParser: Parser,
content: string, useSchema: UseSchema, document: Document, DOMParser: Parser,
) {
const schema = getSchema(useSchema);
const element = migrateHTML(content, document, DOMParser);
const doc = DOMParserPM.fromSchema(schema).parse(element);
return doc;
Expand Down
10 changes: 6 additions & 4 deletions src/parse/markdown/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Schema, Node as ProsemirrorNode } from 'prosemirror-model';
import { Node as ProsemirrorNode } from 'prosemirror-model';
import Token from 'markdown-it/lib/token';
import { MarkdownParser, TokenConfig } from 'prosemirror-markdown';
import MyST from 'markdown-it-myst';
import { DEFAULT_IMAGE_WIDTH } from '../../utils';
import { getSchema, UseSchema } from '../../schemas';

type Tokens = {
[key: string]: TokenConfig & { noCloseToken?: boolean };
Expand Down Expand Up @@ -78,14 +79,15 @@ const tokens: Tokens = {
// myst_role: { mark: 'code', noCloseToken: true },
};

export function getMarkdownParser(schema: Schema) {
export function getMarkdownParser(useSchema: UseSchema) {
const tokenizer = MyST();
type Parser = { parse: (content: string) => ProsemirrorNode };
const schema = getSchema(useSchema);
const parser: Parser = new MarkdownParser(schema, tokenizer, tokens);
return parser;
}

export function fromMarkdown(content: string, schema: Schema) {
const doc = getMarkdownParser(schema).parse(content);
export function fromMarkdown(content: string, useSchema: UseSchema) {
const doc = getMarkdownParser(useSchema).parse(content);
return doc;
}
6 changes: 4 additions & 2 deletions src/parse/text/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Schema, DOMParser as DOMParserPM } from 'prosemirror-model';
import { DOMParser as DOMParserPM } from 'prosemirror-model';
import { getSchema, UseSchema } from '../../schemas';

export function fromText(
content: string, schema: Schema, document: Document,
content: string, useSchema: UseSchema, document: Document,
) {
const schema = getSchema(useSchema);
const div = document.createElement('div');
const pre = document.createElement('pre');
pre.textContent = content;
Expand Down
39 changes: 34 additions & 5 deletions src/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ export const mathNodes = {
equation: Nodes.Equation.default,
};

export const reactiveNodes = {
variable: Nodes.Variable.default,
export const reactiveDisplayNodes = {
// Does NOT include variable definitions
display: Nodes.Display.default,
dynamic: Nodes.Dynamic.default,
range: Nodes.Range.default,
Expand All @@ -50,9 +50,37 @@ export const nodes = {
...presentationalNodes,
...citationNodes,
...mathNodes,
...reactiveNodes,
variable: Nodes.Variable.default,
...reactiveDisplayNodes,
};

export enum nodeNames {
text = 'text',
paragraph = 'paragraph',
heading = 'heading',
blockquote = 'blockquote',
code_block = 'code_block',
image = 'image',
horizontal_rule = 'horizontal_rule',
hard_break = 'hard_break',
ordered_list = 'ordered_list',
bullet_list = 'bullet_list',
list_item = 'list_item',
aside = 'aside',
callout = 'callout',
iframe = 'iframe',
cite = 'cite',
cite_group = 'cite_group',
math = 'math',
equation = 'equation',
variable = 'variable',
display = 'display',
dynamic = 'dynamic',
range = 'range',
switch = 'switch',
button = 'button',
}

export const marks = {
link: basicMarks.link,
code: basicMarks.code,
Expand All @@ -78,14 +106,14 @@ export const presets = {
hard_break: basic.hard_break,
...citationNodes,
math: mathNodes.math,
...reactiveNodes,
...reactiveDisplayNodes,
},
marks,
},
};

export type PresetSchemas = keyof typeof presets;
export type UseSchema = PresetSchemas | { nodes: Record<string, Node>; };
export type UseSchema = PresetSchemas | { nodes: Record<string, Node>; } | Schema;

export function getSchema(useSchema: UseSchema) {
if (typeof useSchema === 'string') {
Expand All @@ -98,5 +126,6 @@ export function getSchema(useSchema: UseSchema) {
throw new Error(`Schema '${useSchema}' is not defined.`);
}
}
if ('spec' in useSchema) return useSchema;
return new Schema(useSchema);
}
6 changes: 4 additions & 2 deletions src/serialize/html/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Node as ProsemirrorNode, DOMSerializer, Schema } from 'prosemirror-model';
import { Node as ProsemirrorNode, DOMSerializer } from 'prosemirror-model';
import { getSchema, UseSchema } from '../../schemas';

export function toHTML(doc: ProsemirrorNode, schema: Schema, document: Document) {
export function toHTML(doc: ProsemirrorNode, useSchema: UseSchema, document: Document) {
const schema = getSchema(useSchema);
const div = document.createElement('div');
const frag = DOMSerializer
.fromSchema(schema)
Expand Down
2 changes: 1 addition & 1 deletion src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function getEditorState(
{ doc: data, selection: { type: 'text', anchor: 0, head: 0 } },
);
} catch (error) {
const doc = fromHTML(content, schema, document, DOMParser);
const doc = fromHTML(content, useSchema, document, DOMParser);
return EditorState.create({
doc,
plugins: serverPlugins(version),
Expand Down
8 changes: 3 additions & 5 deletions test/html.spec.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { JSDOM } from 'jsdom';
import { Schema } from 'prosemirror-model';
import {
schemas, fromHTML, toHTML, migrateHTML,
fromHTML, toHTML, migrateHTML,
} from '../src';
import { compare, tnodes, tdoc } from './build';

const { document, DOMParser } = new JSDOM('').window;
const schema = new Schema(schemas.presets.full);

const same = compare(
(c) => fromHTML(c, schema, document, DOMParser),
(doc) => toHTML(doc, schema, document),
(c) => fromHTML(c, 'full', document, DOMParser),
(doc) => toHTML(doc, 'full', document),
);

const {
Expand Down
6 changes: 2 additions & 4 deletions test/markdown.spec.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { Schema } from 'prosemirror-model';
import { compare, tnodes, tdoc } from './build';
import {
schemas, fromMarkdown, toMarkdown,
fromMarkdown, toMarkdown,
} from '../src';

const {
blockquote, h1, h2, p, hr, li, ol, ol3, ul, pre, em, strong, code, code_block, a, link, br, img,
abbr, subscript, superscript,
math, equation, callout,
} = tnodes;
const schema = new Schema(schemas.presets.full);

const same = compare((c) => fromMarkdown(c, schema), toMarkdown);
const same = compare((c) => fromMarkdown(c, 'full'), toMarkdown);

describe('Markdown', () => {
it('parses a paragraph', () => same('hello!', tdoc(p('hello!'))));
Expand Down

0 comments on commit fe441bf

Please sign in to comment.