diff options
author | Ferdinand Thiessen <rpm@fthiessen.de> | 2022-07-21 09:55:14 +0300 |
---|---|---|
committer | Ferdinand Thiessen <rpm@fthiessen.de> | 2022-07-29 17:07:53 +0300 |
commit | 1ee4b069ca17fa08121287fe9e6f2f3beb37df1a (patch) | |
tree | 1b60fbdc9d67816547be7b28fc075c1fb53931a4 /src | |
parent | e577eec1493e47178a795341c85a305a4597efb8 (diff) |
Add support for editing (not creating) FrontMatter
This adds support for parsing files containing FrontMatter and editing
it as like a code block.
Signed-off-by: Ferdinand Thiessen <rpm@fthiessen.de>
Diffstat (limited to 'src')
-rw-r--r-- | src/components/Editor.vue | 17 | ||||
-rw-r--r-- | src/extensions/RichText.js | 2 | ||||
-rw-r--r-- | src/nodes/FrontMatter.js | 47 |
3 files changed, 60 insertions, 6 deletions
diff --git a/src/components/Editor.vue b/src/components/Editor.vue index 6647c8b6b..0606f1ab2 100644 --- a/src/components/Editor.vue +++ b/src/components/Editor.vue @@ -91,6 +91,7 @@ import { extensionHighlight } from '../helpers/mappings.js' import { createEditor, serializePlainText, loadSyntaxHighlight } from './../EditorFactory.js' import { createMarkdownSerializer } from './../extensions/Markdown.js' import markdownit from './../markdownit/index.js' +import markdownitFrontMatter from 'markdown-it-front-matter' import { Collaboration, Keymap, UserColor } from './../extensions/index.js' import DocumentStatus from './Editor/DocumentStatus.vue' @@ -458,14 +459,18 @@ export default { }, onLoaded({ documentSource }) { - this.hasConnectionIssue = false + let frontMatter = '' + const rendered = !this.isRichEditor + ? `<pre>${escapeHtml(documentSource)}</pre>` + : markdownit.use(markdownitFrontMatter, (fm) => { + frontMatter = `<pre id="frontmatter"><code>${escapeHtml(fm)}</code></pre>` + }).render(documentSource) - const content = this.isRichEditor - ? markdownit.render(documentSource) - : '<pre>' + escapeHtml(documentSource) + '</pre>' - const language = extensionHighlight[this.fileExtension] || this.fileExtension + this.hasConnectionIssue = false + const content = frontMatter + rendered + const language = extensionHighlight[this.fileExtension] || this.fileExtension; - loadSyntaxHighlight(language) + (this.isRichEditor ? Promise.resolve() : loadSyntaxHighlight(language)) .then(() => { this.$editor = createEditor({ content, diff --git a/src/extensions/RichText.js b/src/extensions/RichText.js index ec41d6c85..d14af6a5a 100644 --- a/src/extensions/RichText.js +++ b/src/extensions/RichText.js @@ -33,6 +33,7 @@ import Code from '@tiptap/extension-code' import CodeBlock from '@tiptap/extension-code-block' import HorizontalRule from '@tiptap/extension-horizontal-rule' import Dropcursor from '@tiptap/extension-dropcursor' +import FrontMatter from './../nodes/FrontMatter.js' import HardBreak from './HardBreak.js' import KeepSyntax from './KeepSyntax.js' import Table from './../nodes/Table.js' @@ -89,6 +90,7 @@ export default Extension.create({ }), Dropcursor, KeepSyntax, + FrontMatter, ] if (this.options.link !== false) { defaultExtensions.push(Link.configure({ diff --git a/src/nodes/FrontMatter.js b/src/nodes/FrontMatter.js new file mode 100644 index 000000000..d374228d1 --- /dev/null +++ b/src/nodes/FrontMatter.js @@ -0,0 +1,47 @@ +import TiptapCodeBlock from '@tiptap/extension-code-block' + +const FrontMatter = TiptapCodeBlock.extend({ + name: 'frontMatter', + addAttributes() { + return { + ...this.parent?.(), + class: { + default: 'frontmatter', + rendered: true, + }, + } + }, + parseHTML: () => { + return [ + { + tag: 'pre[id="frontmatter"]', + preserveWhitespace: 'full', + priority: 9001, + attrs: { + language: 'yaml', + }, + }, + ] + }, + toMarkdown: (state, node) => { + if (!state.out.match(/^\s*/)) throw Error('FrontMatter must be the first node of the document!') + state.write('') + state.out = '' + state.write('---\n') + state.text(node.textContent, false) + state.ensureNewLine() + state.write('---') + state.closeBlock(node) + }, + // FrontMatter are only valid at the begin of a document + draggable: false, + // Override rules from Codeblock + addCommands() { + return {} + }, + addInputRules: () => [], + addPasteRules: () => [], + addProseMirrorPlugins: () => [], +}) + +export default FrontMatter |