UNPKG

@curvenote/schema

Version:

Schema and markdown parser for @curvenote/editor

126 lines 4.77 kB
import { MarkdownSerializer } from 'prosemirror-markdown'; import { blankTex, blankTexLines, createLatexStatement, stringToLatexText, stringToLatexMath, } from './utils'; import * as nodes from '../../nodes'; import { isPlainURL } from '../markdown/utils'; import { nodeNames } from '../../types'; import { TexFormatTypes } from '../types'; import { getIndent } from '../indent'; function createMarkOpenClose(name) { return { open: name ? `\\${name}{` : '', close: name ? '}' : '', }; } export const texSerializer = new MarkdownSerializer({ text(state, node, parent) { var _a, _b; let escaped; if (parent.type.name === nodeNames.equation || parent.type.name === nodeNames.math || parent.type.name === nodeNames.code_block) { escaped = stringToLatexMath((_a = node.text) !== null && _a !== void 0 ? _a : ''); } else { escaped = stringToLatexText((_b = node.text) !== null && _b !== void 0 ? _b : ''); } state.text(escaped, false); }, paragraph(state, node) { state.renderInline(node); state.closeBlock(node); }, heading: nodes.Heading.toTex, blockquote: createLatexStatement('quote', (state, node) => { state.renderContent(node); }), code_block: nodes.Code.toTex, link_block: nodes.LinkBlock.toTex, horizontal_rule(state, node) { state.write('\n\\bigskip\n\\centerline{\\rule{13cm}{0.4pt}}\n\\bigskip'); state.closeBlock(node); }, hard_break(state, node, parent, index) { for (let i = index + 1; i < parent.childCount; i += 1) { if (parent.child(i).type !== node.type) { state.write('\\\\\n'); return; } } }, ordered_list: createLatexStatement((state, node) => ({ command: 'enumerate', bracketOpts: node.attrs.order !== 1 ? 'resume' : undefined, }), (state, node) => { state.renderList(node, getIndent(state), () => '\\item '); }), bullet_list: createLatexStatement((state) => { if (state.isInTable) return null; return { command: 'itemize' }; }, (state, node) => { if (state.isInTable) { node.forEach((child) => { state.write('\\textbullet~~'); state.renderInline(child); state.write('\\newline'); state.ensureNewLine(); }); } else { state.renderList(node, getIndent(state), () => '\\item '); } }), list_item(state, node) { state.renderInline(node); }, image: nodes.Image.toTex, figure: nodes.Figure.toTex, figcaption: nodes.Figcaption.toTex, footnote: nodes.Footnote.toTex, iframe: blankTexLines, time: nodes.Time.toTex, cite: nodes.Cite.toTex, cite_group: nodes.CiteGroup.toTex, mention: nodes.Mention.toTex, math: nodes.Math.toTex, equation: nodes.Equation.toTex, table: nodes.Table.toTex, // \usepackage{framed} callout: nodes.Callout.toTex, aside: nodes.Aside.toTex, variable: blankTexLines, display: blankTex, dynamic: blankTex, range: blankTex, switch: blankTex, button: blankTex, }, { em: Object.assign(Object.assign({}, createMarkOpenClose('textit')), { mixable: true, expelEnclosingWhitespace: true }), strong: Object.assign(Object.assign({}, createMarkOpenClose('textbf')), { mixable: true, expelEnclosingWhitespace: true }), underline: Object.assign(Object.assign({}, createMarkOpenClose('uline')), { mixable: true }), link: { open(state, mark, parent, index) { var _a, _b; const { options } = state; const href = (_b = (_a = options.localizeLink) === null || _a === void 0 ? void 0 : _a.call(options, mark.attrs.href)) !== null && _b !== void 0 ? _b : mark.attrs.href; return isPlainURL(mark, href, parent, index, 1) ? '\\url{' : `\\href{${href}}{`; }, close() { // TODO: no title? mark.attrs.title return '}'; }, }, code: createMarkOpenClose('texttt'), // https://www.overleaf.com/learn/latex/glossaries // \newacronym{gcd}{GCD}{Greatest Common Divisor} abbr: createMarkOpenClose(), subscript: createMarkOpenClose('textsubscript'), superscript: createMarkOpenClose('textsuperscript'), // \usepackage[normalem]{ulem} strikethrough: createMarkOpenClose('sout'), }); export function toTex(doc, opts) { const defualtOpts = { tightLists: true, format: TexFormatTypes.tex }; return texSerializer.serialize(doc, Object.assign(Object.assign({}, defualtOpts), opts)); } //# sourceMappingURL=index.js.map