1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-13 01:36:22 +00:00

Merge pull request #2510 from nagledb/nagledb-front-matter-title

Title will now be extracted from front matter if title: is present.
This commit is contained in:
Junyoung Choi (Sai)
2018-10-23 17:50:28 +09:00
committed by GitHub
6 changed files with 93 additions and 17 deletions

View File

@@ -1,4 +1,4 @@
export function findNoteTitle (value) { export function findNoteTitle (value, enableFrontMatterTitle, frontMatterTitleField = 'title') {
const splitted = value.split('\n') const splitted = value.split('\n')
let title = null let title = null
let isInsideCodeBlock = false let isInsideCodeBlock = false
@@ -6,6 +6,11 @@ export function findNoteTitle (value) {
if (splitted[0] === '---') { if (splitted[0] === '---') {
let line = 0 let line = 0
while (++line < splitted.length) { while (++line < splitted.length) {
if (enableFrontMatterTitle && splitted[line].startsWith(frontMatterTitleField + ':')) {
title = splitted[line].substring(frontMatterTitleField.length + 1).trim()
break
}
if (splitted[line] === '---') { if (splitted[line] === '---') {
splitted.splice(0, line + 1) splitted.splice(0, line + 1)
@@ -14,17 +19,19 @@ export function findNoteTitle (value) {
} }
} }
splitted.some((line, index) => { if (title === null) {
const trimmedLine = line.trim() splitted.some((line, index) => {
const trimmedNextLine = splitted[index + 1] === undefined ? '' : splitted[index + 1].trim() const trimmedLine = line.trim()
if (trimmedLine.match('```')) { const trimmedNextLine = splitted[index + 1] === undefined ? '' : splitted[index + 1].trim()
isInsideCodeBlock = !isInsideCodeBlock if (trimmedLine.match('```')) {
} isInsideCodeBlock = !isInsideCodeBlock
if (isInsideCodeBlock === false && (trimmedLine.match(/^# +/) || trimmedNextLine.match(/^=+$/))) { }
title = trimmedLine if (isInsideCodeBlock === false && (trimmedLine.match(/^# +/) || trimmedNextLine.match(/^=+$/))) {
return true title = trimmedLine
} return true
}) }
})
}
if (title === null) { if (title === null) {
title = '' title = ''

View File

@@ -91,7 +91,7 @@ class MarkdownNoteDetail extends React.Component {
handleUpdateContent () { handleUpdateContent () {
const { note } = this.state const { note } = this.state
note.content = this.refs.content.value note.content = this.refs.content.value
note.title = markdown.strip(striptags(findNoteTitle(note.content))) note.title = markdown.strip(striptags(findNoteTitle(note.content, this.props.config.editor.enableFrontMatterTitle, this.props.config.editor.frontMatterTitleField)))
this.updateNote(note) this.updateNote(note)
} }

View File

@@ -112,7 +112,7 @@ class SnippetNoteDetail extends React.Component {
if (this.refs.tags) note.tags = this.refs.tags.value if (this.refs.tags) note.tags = this.refs.tags.value
note.description = this.refs.description.value note.description = this.refs.description.value
note.updatedAt = new Date() note.updatedAt = new Date()
note.title = findNoteTitle(note.description) note.title = findNoteTitle(note.description, false)
this.setState({ this.setState({
note note

View File

@@ -47,7 +47,9 @@ export const DEFAULT_CONFIG = {
scrollPastEnd: false, scrollPastEnd: false,
type: 'SPLIT', type: 'SPLIT',
fetchUrlTitle: true, fetchUrlTitle: true,
enableTableEditor: false enableTableEditor: false,
enableFrontMatterTitle: true,
frontMatterTitleField: 'title'
}, },
preview: { preview: {
fontSize: '14', fontSize: '14',

View File

@@ -89,7 +89,9 @@ class UiTab extends React.Component {
snippetDefaultLanguage: this.refs.editorSnippetDefaultLanguage.value, snippetDefaultLanguage: this.refs.editorSnippetDefaultLanguage.value,
scrollPastEnd: this.refs.scrollPastEnd.checked, scrollPastEnd: this.refs.scrollPastEnd.checked,
fetchUrlTitle: this.refs.editorFetchUrlTitle.checked, fetchUrlTitle: this.refs.editorFetchUrlTitle.checked,
enableTableEditor: this.refs.enableTableEditor.checked enableTableEditor: this.refs.enableTableEditor.checked,
enableFrontMatterTitle: this.refs.enableFrontMatterTitle.checked,
frontMatterTitleField: this.refs.frontMatterTitleField.value
}, },
preview: { preview: {
fontSize: this.refs.previewFontSize.value, fontSize: this.refs.previewFontSize.value,
@@ -428,6 +430,31 @@ class UiTab extends React.Component {
</div> </div>
</div> </div>
<div styleName='group-section'>
<div styleName='group-section-label'>
{i18n.__('Front matter title field')}
</div>
<div styleName='group-section-control'>
<input styleName='group-section-control-input'
ref='frontMatterTitleField'
value={config.editor.frontMatterTitleField}
onChange={(e) => this.handleUIChange(e)}
type='text'
/>
</div>
</div>
<div styleName='group-checkBoxSection'>
<label>
<input onChange={(e) => this.handleUIChange(e)}
checked={this.state.config.editor.enableFrontMatterTitle}
ref='enableFrontMatterTitle'
type='checkbox'
/>&nbsp;
{i18n.__('Extract title from front matter')}
</label>
</div>
<div styleName='group-checkBoxSection'> <div styleName='group-checkBoxSection'>
<label> <label>
<input onChange={(e) => this.handleUIChange(e)} <input onChange={(e) => this.handleUIChange(e)}

View File

@@ -20,7 +20,47 @@ test('findNoteTitle#find should return a correct title (string)', t => {
testCases.forEach(testCase => { testCases.forEach(testCase => {
const [input, expected] = testCase const [input, expected] = testCase
t.is(findNoteTitle(input), expected, `Test for find() input: ${input} expected: ${expected}`) t.is(findNoteTitle(input, false), expected, `Test for find() input: ${input} expected: ${expected}`)
}) })
}) })
test('findNoteTitle#find should ignore front matter when enableFrontMatterTitle=false', t => {
// [input, expected]
const testCases = [
['---\nlayout: test\ntitle: hoge hoge hoge \n---\n# fuga', '# fuga'],
['---\ntitle:hoge\n---\n# fuga', '# fuga'],
['title: fuga\n# hoge', '# hoge']
]
testCases.forEach(testCase => {
const [input, expected] = testCase
t.is(findNoteTitle(input, false), expected, `Test for find() input: ${input} expected: ${expected}`)
})
})
test('findNoteTitle#find should respect front matter when enableFrontMatterTitle=true', t => {
// [input, expected]
const testCases = [
['---\nlayout: test\ntitle: hoge hoge hoge \n---\n# fuga', 'hoge hoge hoge'],
['---\ntitle:hoge\n---\n# fuga', 'hoge'],
['title: fuga\n# hoge', '# hoge']
]
testCases.forEach(testCase => {
const [input, expected] = testCase
t.is(findNoteTitle(input, true), expected, `Test for find() input: ${input} expected: ${expected}`)
})
})
test('findNoteTitle#find should respect frontMatterTitleField when provided', t => {
// [input, expected]
const testCases = [
['---\ntitle: hoge\n---\n# fuga', '# fuga'],
['---\ncustom: hoge\n---\n# fuga', 'hoge']
]
testCases.forEach(testCase => {
const [input, expected] = testCase
t.is(findNoteTitle(input, true, 'custom'), expected, `Test for find() input: ${input} expected: ${expected}`)
})
})