mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-11-27 03:58:02 -05:00
fix: frontmatter headline
If one wrote a frontmatter the incomplete ending dashes where interpreted as a headline and therefore the last line in the frontmatter was handled as the first heading of the document. Signed-off-by: Philip Molares <philip.molares@udo.edu>
This commit is contained in:
parent
61fc33fc73
commit
02a5f62d27
6 changed files with 38 additions and 3 deletions
|
@ -96,4 +96,17 @@ describe('frontmatter extraction', () => {
|
||||||
expect(extraction?.rawText).toEqual('multi\nline')
|
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()
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -7,6 +7,7 @@ import type { FrontmatterExtractionResult } from './types.js'
|
||||||
|
|
||||||
const FRONTMATTER_BEGIN_REGEX = /^-{3,}$/
|
const FRONTMATTER_BEGIN_REGEX = /^-{3,}$/
|
||||||
const FRONTMATTER_END_REGEX = /^(?:-{3,}|\.{3,})$/
|
const FRONTMATTER_END_REGEX = /^(?:-{3,}|\.{3,})$/
|
||||||
|
const FRONTMATTER_INCOMPLETE_END_REGEX = /^-{1,2}$/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts a frontmatter block from a given multiline string.
|
* Extracts a frontmatter block from a given multiline string.
|
||||||
|
@ -25,13 +26,21 @@ export const extractFrontmatter = (
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
for (let i = 1; i < lines.length; i++) {
|
for (let i = 1; i < lines.length; i++) {
|
||||||
|
if (FRONTMATTER_INCOMPLETE_END_REGEX.test(lines[i])) {
|
||||||
|
return {
|
||||||
|
rawText: '',
|
||||||
|
lineOffset: i + 1,
|
||||||
|
incomplete: true
|
||||||
|
}
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
lines[i].length === lines[0].length &&
|
lines[i].length === lines[0].length &&
|
||||||
FRONTMATTER_END_REGEX.test(lines[i])
|
FRONTMATTER_END_REGEX.test(lines[i])
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
rawText: lines.slice(1, i).join('\n'),
|
rawText: lines.slice(1, i).join('\n'),
|
||||||
lineOffset: i + 1
|
lineOffset: i + 1,
|
||||||
|
incomplete: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,4 +7,5 @@
|
||||||
export interface FrontmatterExtractionResult {
|
export interface FrontmatterExtractionResult {
|
||||||
rawText: string
|
rawText: string
|
||||||
lineOffset: number
|
lineOffset: number
|
||||||
|
incomplete: boolean
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ export class FrontmatterLinter implements Linter {
|
||||||
lint(view: EditorView): Diagnostic[] {
|
lint(view: EditorView): Diagnostic[] {
|
||||||
const lines = view.state.doc.toString().split('\n')
|
const lines = view.state.doc.toString().split('\n')
|
||||||
const frontmatterExtraction = extractFrontmatter(lines)
|
const frontmatterExtraction = extractFrontmatter(lines)
|
||||||
if (frontmatterExtraction === undefined) {
|
if (frontmatterExtraction === undefined || frontmatterExtraction.incomplete) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
const frontmatterLines = lines.slice(1, frontmatterExtraction.lineOffset - 1)
|
const frontmatterLines = lines.slice(1, frontmatterExtraction.lineOffset - 1)
|
||||||
|
|
|
@ -19,10 +19,13 @@ import type { CommonMarkdownRendererProps, HeightChangeRendererProps } from '../
|
||||||
import { DocumentTocSidebar } from './document-toc-sidebar'
|
import { DocumentTocSidebar } from './document-toc-sidebar'
|
||||||
import styles from './markdown-document.module.scss'
|
import styles from './markdown-document.module.scss'
|
||||||
import useResizeObserver from '@react-hook/resize-observer'
|
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
|
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.
|
* Renders a Markdown document and handles scrolling, yaml metadata and a floating table of contents.
|
||||||
*
|
*
|
||||||
|
@ -64,6 +67,11 @@ export const DocumentMarkdownRenderer: React.FC<DocumentMarkdownRendererProps> =
|
||||||
const markdownBodyRef = useRef<HTMLDivElement>(null)
|
const markdownBodyRef = useRef<HTMLDivElement>(null)
|
||||||
const currentLineMarkers = useRef<LineMarkers[]>()
|
const currentLineMarkers = useRef<LineMarkers[]>()
|
||||||
|
|
||||||
|
// ToDo: Remove this
|
||||||
|
useEffect(() => {
|
||||||
|
logger.debug(markdownContentLines)
|
||||||
|
}, [markdownContentLines])
|
||||||
|
|
||||||
const extensions = useMarkdownExtensions(
|
const extensions = useMarkdownExtensions(
|
||||||
baseUrl,
|
baseUrl,
|
||||||
RendererType.DOCUMENT,
|
RendererType.DOCUMENT,
|
||||||
|
|
|
@ -83,6 +83,10 @@ const buildStateFromFrontmatterUpdate = (
|
||||||
state: NoteDetails,
|
state: NoteDetails,
|
||||||
frontmatterExtraction: FrontmatterExtractionResult
|
frontmatterExtraction: FrontmatterExtractionResult
|
||||||
): NoteDetails => {
|
): NoteDetails => {
|
||||||
|
if (frontmatterExtraction.incomplete) {
|
||||||
|
frontmatterExtraction.rawText = state.rawFrontmatter
|
||||||
|
return buildStateFromFrontmatter(state, parseFrontmatter(frontmatterExtraction), frontmatterExtraction)
|
||||||
|
}
|
||||||
if (frontmatterExtraction.rawText === state.rawFrontmatter) {
|
if (frontmatterExtraction.rawText === state.rawFrontmatter) {
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue