Add YAML-metadata for notes and change the document title accordingly (#310)

* Added yaml-frontmatter extracting and error handling
* add tests
* changed document-title, so the editor can change the title to the title of the yaml metadata. closes #303
* extracted first line parsing in a core rule of markdown-it
document title will now be determined like this:
1. yaml metadata title
2. opengraph title
3. first level one heading
4. 'Untitled'
* added documentTitle e2e test

Co-authored-by: Erik Michelson <github@erik.michelson.eu>
Co-authored-by: Philip Molares <philip@mauricedoepke.de>
Co-authored-by: Tilman Vatteroth <tilman.vatteroth@tu-dortmund.de>
Co-authored-by: mrdrogdrog <mr.drogdrog@gmail.com>
This commit is contained in:
Philip Molares 2020-07-18 22:17:36 +02:00 committed by GitHub
parent 07fed5c67e
commit 29709d2ba4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 499 additions and 20 deletions

View file

@ -1,18 +1,31 @@
import React, { Fragment, useEffect, useState } from 'react'
import React, { Fragment, useCallback, useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useSelector } from 'react-redux'
import useMedia from 'use-media'
import { ApplicationState } from '../../redux'
import { setEditorModeConfig } from '../../redux/editor/methods'
import { DocumentTitle } from '../common/document-title/document-title'
import { Splitter } from '../common/splitter/splitter'
import { InfoBanner } from '../landing/layout/info-banner'
import { EditorWindow } from './editor-window/editor-window'
import { MarkdownRenderWindow } from './renderer-window/markdown-render-window'
import { EditorMode } from './task-bar/editor-view-mode'
import { TaskBar } from './task-bar/task-bar'
import { YAMLMetaData } from './yaml-metadata/yaml-metadata'
const Editor: React.FC = () => {
export const Editor: React.FC = () => {
const { t } = useTranslation()
const untitledNote = t('editor.untitledNote')
const editorMode: EditorMode = useSelector((state: ApplicationState) => state.editorConfig.editorMode)
const [markdownContent, setMarkdownContent] = useState(`# Embedding demo
const [markdownContent, setMarkdownContent] = useState(`---
title: Features
description: Many features, such wow!
robots: noindex
tags: codimd, demo, react
opengraph:
title: Features
---
# Embedding demo
[TOC]
## MathJax
@ -55,12 +68,36 @@ https://asciinema.org/a/117928
## Code highlighting
\`\`\`javascript=
let a = 1
\`\`\`
`)
const isWide = useMedia({ minWidth: 576 })
const [firstDraw, setFirstDraw] = useState(true)
const [documentTitle, setDocumentTitle] = useState(untitledNote)
const noteMetadata = useRef<YAMLMetaData>()
const firstHeading = useRef<string>()
const updateDocumentTitle = useCallback(() => {
if (noteMetadata.current?.title && noteMetadata.current?.title !== '') {
setDocumentTitle(noteMetadata.current.title)
} else if (noteMetadata.current?.opengraph && noteMetadata.current?.opengraph.get('title') && noteMetadata.current?.opengraph.get('title') !== '') {
setDocumentTitle(noteMetadata.current.opengraph.get('title') ?? untitledNote)
} else {
setDocumentTitle(firstHeading.current ?? untitledNote)
}
}, [untitledNote])
const onMetadataChange = useCallback((metaData: YAMLMetaData | undefined) => {
noteMetadata.current = metaData
updateDocumentTitle()
}, [updateDocumentTitle])
const onFirstHeadingChange = useCallback((newFirstHeading: string | undefined) => {
firstHeading.current = newFirstHeading
updateDocumentTitle()
}, [updateDocumentTitle])
useEffect(() => {
setFirstDraw(false)
@ -75,17 +112,16 @@ let a = 1
return (
<Fragment>
<InfoBanner/>
<DocumentTitle title={documentTitle}/>
<div className={'d-flex flex-column vh-100'}>
<TaskBar/>
<Splitter
showLeft={editorMode === EditorMode.EDITOR || editorMode === EditorMode.BOTH}
left={<EditorWindow onContentChange={content => setMarkdownContent(content)} content={markdownContent}/>}
showRight={editorMode === EditorMode.PREVIEW || (editorMode === EditorMode.BOTH)}
right={<MarkdownRenderWindow content={markdownContent} wide={editorMode === EditorMode.PREVIEW}/>}
right={<MarkdownRenderWindow content={markdownContent} wide={editorMode === EditorMode.PREVIEW} onMetadataChange={onMetadataChange} onFirstHeadingChange={onFirstHeadingChange}/>}
containerClassName={'overflow-hidden'}/>
</div>
</Fragment>
)
}
export { Editor }