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

Commit

Permalink
🎯 Add preset schemas like "full" and "paragraph"
Browse files Browse the repository at this point in the history
  • Loading branch information
rowanc1 committed May 4, 2021
1 parent cf16ff6 commit 8aee7b7
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 31 deletions.
3 changes: 1 addition & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// Note: Sometimes you need to ensure that the libs are exactly the same
// Exporting the `prosemirror-model` schema from here does the trick.
export { Schema } from 'prosemirror-model';

export { nodes, marks } from './schema';
export * as schemas from './schemas';
export * as Nodes from './nodes';

export {
Expand Down
4 changes: 4 additions & 0 deletions src/nodes/basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ export const doc: NodeSpec = {
content: `(${NodeGroups.block} | ${NodeGroups.top})+`,
};

export const docParagraph: NodeSpec = {
content: 'paragraph',
};

export const paragraph: NodeSpec = {
content: `${NodeGroups.inline}*`,
group: NodeGroups.block,
Expand Down
84 changes: 69 additions & 15 deletions src/schema.ts → src/schemas.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,31 @@
import { Schema } from 'prosemirror-model';
import * as basic from './nodes/basic';
import * as basicMarks from './marks';
import * as Nodes from './nodes';


export const nodes = {
// Basic markdown
doc: basic.doc,
text: basic.text,
paragraph: basic.paragraph,
heading: basic.heading,
blockquote: basic.blockquote,
code_block: basic.code_block,
image: Nodes.Image.default,
horizontal_rule: basic.horizontal_rule,
hard_break: basic.hard_break,
export const listNodes = {
ordered_list: basic.ordered_list,
bullet_list: basic.bullet_list,
list_item: basic.list_item,
// Presentational components
};

export const presentationalNodes = {
aside: Nodes.Aside.default,
callout: Nodes.Callout.default,
iframe: Nodes.IFrame.default,
// Presentational components
};

export const citationNodes = {
cite: Nodes.Cite.default,
cite_group: Nodes.CiteGroup.default,
};

export const mathNodes = {
math: Nodes.Math.default,
equation: Nodes.Equation.default,
// Reactive components
};

export const reactiveNodes = {
variable: Nodes.Variable.default,
display: Nodes.Display.default,
dynamic: Nodes.Dynamic.default,
Expand All @@ -35,6 +34,25 @@ export const nodes = {
button: Nodes.Button.default,
};

export const nodes = {
// Basic markdown
doc: basic.doc,
text: basic.text,
paragraph: basic.paragraph,
heading: basic.heading,
blockquote: basic.blockquote,
code_block: basic.code_block,
image: Nodes.Image.default,
horizontal_rule: basic.horizontal_rule,
hard_break: basic.hard_break,
...listNodes,
// Presentational components
...presentationalNodes,
...citationNodes,
...mathNodes,
...reactiveNodes,
};

export const marks = {
link: basicMarks.link,
code: basicMarks.code,
Expand All @@ -46,3 +64,39 @@ export const marks = {
underline: basicMarks.underline,
abbr: basicMarks.abbr,
};

export const presets = {
full: {
nodes,
marks,
},
paragraph: {
nodes: {
doc: basic.docParagraph,
paragraph: basic.paragraph,
text: basic.text,
hard_break: basic.hard_break,
...citationNodes,
math: mathNodes.math,
...reactiveNodes,
},
marks,
},
};

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

export function getSchema(useSchema: UseSchema) {
if (typeof useSchema === 'string') {
switch (useSchema) {
case 'full':
return new Schema(presets.full);
case 'paragraph':
return new Schema(presets.paragraph);
default:
throw new Error(`Schema '${useSchema}' is not defined.`);
}
}
return new Schema(useSchema);
}
11 changes: 3 additions & 8 deletions src/server.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
import { Schema } from 'prosemirror-model';
import { Step as PMStep } from 'prosemirror-transform';
import { EditorState } from 'prosemirror-state';
import { collab, receiveTransaction } from 'prosemirror-collab';
import { nodes, marks } from './schema';
import { fromHTML } from './parse';

import { Parser } from './types';

export function getSchema() {
return new Schema({ nodes, marks });
}
import { getSchema, UseSchema } from './schemas';

export { EditorState };

Expand All @@ -18,9 +13,9 @@ function serverPlugins(version: number) {
}

export function getEditorState(
content: string, version: number, document: Document, DOMParser: Parser,
useSchema: UseSchema, content: string, version: number, document: Document, DOMParser: Parser,
) {
const schema = getSchema();
const schema = getSchema(useSchema);
try {
const data = JSON.parse(content);
return EditorState.fromJSON(
Expand Down
4 changes: 2 additions & 2 deletions test/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Node as ProsemirrorNode, Schema } from 'prosemirror-model';
import { builders } from 'prosemirror-test-builder';
import * as src from '../src';

const schema = new Schema({ nodes: src.nodes, marks: src.marks });
const schema = new Schema(src.schemas.presets.full);

export const tnodes = builders(schema, {
p: { nodeType: 'paragraph' },
Expand Down Expand Up @@ -50,7 +50,7 @@ export function compare(
expect(to(doc).replace(ctx, '')).toEqual(text);
}

function same(text: string | {before: string; after: string}, doc: ProsemirrorNode) {
function same(text: string | { before: string; after: string }, doc: ProsemirrorNode) {
const { before, after } = typeof text === 'string' ? { before: text, after: text } : text;
parse(before, doc);
serialize(doc, after);
Expand Down
5 changes: 3 additions & 2 deletions test/html.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { JSDOM } from 'jsdom';
import { Schema } from 'prosemirror-model';
import {
Schema, nodes, marks, fromHTML, toHTML, migrateHTML,
schemas, fromHTML, toHTML, migrateHTML,
} from '../src';
import { compare, tnodes, tdoc } from './build';

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

const same = compare(
(c) => fromHTML(c, schema, document, DOMParser),
Expand Down
5 changes: 3 additions & 2 deletions test/markdown.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { Schema } from 'prosemirror-model';
import { compare, tnodes, tdoc } from './build';
import {
nodes, marks, Schema, fromMarkdown, toMarkdown,
schemas, 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({ nodes, marks });
const schema = new Schema(schemas.presets.full);

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

Expand Down

0 comments on commit 8aee7b7

Please sign in to comment.