diff --git a/commons/src/frontmatter-extractor/extractor.spec.ts b/commons/src/frontmatter-extractor/extractor.spec.ts index 7350330b5..3a646f6b4 100644 --- a/commons/src/frontmatter-extractor/extractor.spec.ts +++ b/commons/src/frontmatter-extractor/extractor.spec.ts @@ -96,4 +96,17 @@ describe('frontmatter extraction', () => { expect(extraction?.rawText).toEqual('multi\nline') }) }) + + describe('is incomplete', () => { + it('if frontmatter is closed with one dash', () => { + const testNote = ['---', 'type: document', '-', 'content'] + const extraction = extractFrontmatter(testNote) + expect(extraction?.incomplete).toBeTruthy() + }) + it('if frontmatter is closed with two dash', () => { + const testNote = ['---', 'type: document', '-', 'content'] + const extraction = extractFrontmatter(testNote) + expect(extraction?.incomplete).toBeTruthy() + }) + }) }) diff --git a/commons/src/frontmatter-extractor/extractor.ts b/commons/src/frontmatter-extractor/extractor.ts index 64515cd75..dbeaed6d8 100644 --- a/commons/src/frontmatter-extractor/extractor.ts +++ b/commons/src/frontmatter-extractor/extractor.ts @@ -7,6 +7,7 @@ import type { FrontmatterExtractionResult } from './types.js' const FRONTMATTER_BEGIN_REGEX = /^-{3,}$/ const FRONTMATTER_END_REGEX = /^(?:-{3,}|\.{3,})$/ +const FRONTMATTER_INCOMPLETE_END_REGEX = /^-{1,2}$/ /** * Extracts a frontmatter block from a given multiline string. @@ -25,13 +26,21 @@ export const extractFrontmatter = ( return undefined } for (let i = 1; i < lines.length; i++) { + if (FRONTMATTER_INCOMPLETE_END_REGEX.test(lines[i])) { + return { + rawText: '', + lineOffset: i + 1, + incomplete: true + } + } if ( lines[i].length === lines[0].length && FRONTMATTER_END_REGEX.test(lines[i]) ) { return { rawText: lines.slice(1, i).join('\n'), - lineOffset: i + 1 + lineOffset: i + 1, + incomplete: false } } } diff --git a/commons/src/frontmatter-extractor/types.ts b/commons/src/frontmatter-extractor/types.ts index 427b7a91c..007f93aed 100644 --- a/commons/src/frontmatter-extractor/types.ts +++ b/commons/src/frontmatter-extractor/types.ts @@ -7,4 +7,5 @@ export interface FrontmatterExtractionResult { rawText: string lineOffset: number + incomplete: boolean } diff --git a/frontend/src/components/editor-page/editor-pane/linter/frontmatter-linter.ts b/frontend/src/components/editor-page/editor-pane/linter/frontmatter-linter.ts index 3e6fce4b1..315df4fda 100644 --- a/frontend/src/components/editor-page/editor-pane/linter/frontmatter-linter.ts +++ b/frontend/src/components/editor-page/editor-pane/linter/frontmatter-linter.ts @@ -18,7 +18,7 @@ export class FrontmatterLinter implements Linter { lint(view: EditorView): Diagnostic[] { const lines = view.state.doc.toString().split('\n') const frontmatterExtraction = extractFrontmatter(lines) - if (frontmatterExtraction === undefined) { + if (frontmatterExtraction === undefined || frontmatterExtraction.incomplete) { return [] } const frontmatterLines = lines.slice(1, frontmatterExtraction.lineOffset - 1) diff --git a/frontend/src/components/render-page/renderers/document/document-markdown-renderer.tsx b/frontend/src/components/render-page/renderers/document/document-markdown-renderer.tsx index a659b8e6a..2e5d94bbc 100644 --- a/frontend/src/components/render-page/renderers/document/document-markdown-renderer.tsx +++ b/frontend/src/components/render-page/renderers/document/document-markdown-renderer.tsx @@ -19,10 +19,13 @@ import type { CommonMarkdownRendererProps, HeightChangeRendererProps } from '../ import { DocumentTocSidebar } from './document-toc-sidebar' import styles from './markdown-document.module.scss' import useResizeObserver from '@react-hook/resize-observer' -import React, { useMemo, useRef, useState } from 'react' +import React, { useEffect, useMemo, useRef, useState } from 'react' +import { Logger } from '../../../../utils/logger' export type DocumentMarkdownRendererProps = CommonMarkdownRendererProps & ScrollProps & HeightChangeRendererProps +const logger = new Logger('DocumentMarkdownRenderer') + /** * Renders a Markdown document and handles scrolling, yaml metadata and a floating table of contents. * @@ -64,6 +67,11 @@ export const DocumentMarkdownRenderer: React.FC = const markdownBodyRef = useRef(null) const currentLineMarkers = useRef() + // ToDo: Remove this + useEffect(() => { + logger.debug(markdownContentLines) + }, [markdownContentLines]) + const extensions = useMarkdownExtensions( baseUrl, RendererType.DOCUMENT, diff --git a/frontend/src/redux/note-details/build-state-from-updated-markdown-content.ts b/frontend/src/redux/note-details/build-state-from-updated-markdown-content.ts index 56fb0acde..80aa288d2 100644 --- a/frontend/src/redux/note-details/build-state-from-updated-markdown-content.ts +++ b/frontend/src/redux/note-details/build-state-from-updated-markdown-content.ts @@ -83,6 +83,10 @@ const buildStateFromFrontmatterUpdate = ( state: NoteDetails, frontmatterExtraction: FrontmatterExtractionResult ): NoteDetails => { + if (frontmatterExtraction.incomplete) { + frontmatterExtraction.rawText = state.rawFrontmatter + return buildStateFromFrontmatter(state, parseFrontmatter(frontmatterExtraction), frontmatterExtraction) + } if (frontmatterExtraction.rawText === state.rawFrontmatter) { return state }