mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 17:56:25 +00:00
Create Markdown TOC at current cursor position
If there is no TOC in the current document, it's created at current cursor position. Subsequent generation calls update TOC at existing position. Add additional tests with CodeMirror editor mock.
This commit is contained in:
@@ -6,6 +6,8 @@ import toc from 'markdown-toc'
|
|||||||
import diacritics from 'diacritics-map'
|
import diacritics from 'diacritics-map'
|
||||||
import stripColor from 'strip-color'
|
import stripColor from 'strip-color'
|
||||||
|
|
||||||
|
const EOL = require('os').EOL
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @caseSensitiveSlugify Custom slugify function
|
* @caseSensitiveSlugify Custom slugify function
|
||||||
* Same implementation that the original used by markdown-toc (node_modules/markdown-toc/lib/utils.js),
|
* Same implementation that the original used by markdown-toc (node_modules/markdown-toc/lib/utils.js),
|
||||||
@@ -17,6 +19,7 @@ function caseSensitiveSlugify (str) {
|
|||||||
return diacritics[ch] || ch
|
return diacritics[ch] || ch
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTitle (str) {
|
function getTitle (str) {
|
||||||
if (/^\[[^\]]+\]\(/.test(str)) {
|
if (/^\[[^\]]+\]\(/.test(str)) {
|
||||||
var m = /^\[([^\]]+)\]/.exec(str)
|
var m = /^\[([^\]]+)\]/.exec(str)
|
||||||
@@ -24,6 +27,7 @@ function caseSensitiveSlugify (str) {
|
|||||||
}
|
}
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
str = getTitle(str)
|
str = getTitle(str)
|
||||||
str = stripColor(str)
|
str = stripColor(str)
|
||||||
// str = str.toLowerCase() //let's be case sensitive
|
// str = str.toLowerCase() //let's be case sensitive
|
||||||
@@ -38,15 +42,59 @@ function caseSensitiveSlugify (str) {
|
|||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generate (currentValue, updateCallback) {
|
const TOC_MARKER_START = '<!-- toc -->'
|
||||||
const TOC_MARKER = '<!-- toc -->'
|
const TOC_MARKER_END = '<!-- tocstop -->'
|
||||||
if (!currentValue.includes(TOC_MARKER)) {
|
|
||||||
currentValue = TOC_MARKER + currentValue
|
/**
|
||||||
|
* Takes care of proper updating given editor with TOC.
|
||||||
|
* If TOC doesn't exit in the editor, it's inserted at current caret position.
|
||||||
|
* Otherwise,TOC is updated in place.
|
||||||
|
* @param editor CodeMirror editor to be updated with TOC
|
||||||
|
*/
|
||||||
|
export function generateInEditor (editor) {
|
||||||
|
const tocRegex = new RegExp(`${TOC_MARKER_START}[\\s\\S]*?${TOC_MARKER_END}`)
|
||||||
|
|
||||||
|
function tocExistsInEditor () {
|
||||||
|
return tocRegex.test(editor.getValue())
|
||||||
}
|
}
|
||||||
updateCallback(toc.insert(currentValue, {slugify: caseSensitiveSlugify}))
|
|
||||||
|
function updateExistingToc () {
|
||||||
|
const toc = generate(editor.getValue())
|
||||||
|
const search = editor.getSearchCursor(tocRegex)
|
||||||
|
while (search.findNext()) {
|
||||||
|
search.replace(toc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addTocAtCursorPosition () {
|
||||||
|
const toc = generate(editor.getRange(editor.getCursor(), {line: Infinity}))
|
||||||
|
editor.replaceRange(wrapTocWithEol(toc, editor), editor.getCursor())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tocExistsInEditor()) {
|
||||||
|
updateExistingToc()
|
||||||
|
} else {
|
||||||
|
addTocAtCursorPosition()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates MD TOC based on MD document passed as string.
|
||||||
|
* @param markdownText MD document
|
||||||
|
* @returns generatedTOC String containing generated TOC
|
||||||
|
*/
|
||||||
|
export function generate (markdownText) {
|
||||||
|
const generatedToc = toc(markdownText, {slugify: caseSensitiveSlugify})
|
||||||
|
return TOC_MARKER_START + EOL + EOL + generatedToc.content + EOL + EOL + TOC_MARKER_END
|
||||||
|
}
|
||||||
|
|
||||||
|
function wrapTocWithEol (toc, editor) {
|
||||||
|
const leftWrap = editor.getCursor().ch === 0 ? '' : EOL
|
||||||
|
const rightWrap = editor.getLine(editor.getCursor().line).length === editor.getCursor().ch ? '' : EOL
|
||||||
|
return leftWrap + toc + rightWrap
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
generate
|
generate,
|
||||||
|
generateInEditor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -267,8 +267,8 @@ class MarkdownNoteDetail extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleGenerateToc () {
|
handleGenerateToc () {
|
||||||
markdownToc.generate(this.refs.content.value,
|
const editor = this.refs.content.refs.code.editor
|
||||||
(modifiedValue) => this.refs.content.refs.code.setValue(modifiedValue))
|
markdownToc.generateInEditor(editor)
|
||||||
}
|
}
|
||||||
|
|
||||||
handleFocus (e) {
|
handleFocus (e) {
|
||||||
|
|||||||
@@ -100,9 +100,8 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
handleGenerateToc () {
|
handleGenerateToc () {
|
||||||
const currentMode = this.state.note.snippets[this.state.snippetIndex].mode
|
const currentMode = this.state.note.snippets[this.state.snippetIndex].mode
|
||||||
if (currentMode.includes('Markdown')) {
|
if (currentMode.includes('Markdown')) {
|
||||||
const currentValue = this.refs['code-' + this.state.snippetIndex].value
|
|
||||||
const currentEditor = this.refs['code-' + this.state.snippetIndex].refs.code.editor
|
const currentEditor = this.refs['code-' + this.state.snippetIndex].refs.code.editor
|
||||||
markdownToc.generate(currentValue, (modifiedValue) => currentEditor.setValue(modifiedValue))
|
markdownToc.generateInEditor(currentEditor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,23 @@
|
|||||||
import browserEnv from 'browser-env'
|
import browserEnv from 'browser-env'
|
||||||
browserEnv(['window', 'document'])
|
browserEnv(['window', 'document', 'navigator'])
|
||||||
|
|
||||||
|
// for CodeMirror mockup
|
||||||
|
document.body.createTextRange = function () {
|
||||||
|
return {
|
||||||
|
setEnd: function () {},
|
||||||
|
setStart: function () {},
|
||||||
|
getBoundingClientRect: function () {
|
||||||
|
return {right: 0}
|
||||||
|
},
|
||||||
|
getClientRects: function () {
|
||||||
|
return {
|
||||||
|
length: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
window.localStorage = {
|
window.localStorage = {
|
||||||
// polyfill
|
// polyfill
|
||||||
|
|||||||
@@ -1,19 +1,22 @@
|
|||||||
/**
|
/**
|
||||||
* @fileoverview Unit test for browser/lib/markdown-toc-generator
|
* @fileoverview Unit test for browser/lib/markdown-toc-generator
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import CodeMirror from 'codemirror'
|
||||||
|
require('codemirror/addon/search/searchcursor.js')
|
||||||
const test = require('ava')
|
const test = require('ava')
|
||||||
const markdownToc = require('browser/lib/markdown-toc-generator')
|
const markdownToc = require('browser/lib/markdown-toc-generator')
|
||||||
const EOL = require('os').EOL
|
const EOL = require('os').EOL
|
||||||
|
|
||||||
test(t => {
|
test(t => {
|
||||||
/**
|
/**
|
||||||
* @testCases Contains array of test cases in format :
|
* Contains array of test cases in format :
|
||||||
* [
|
* [
|
||||||
* test title
|
* test title
|
||||||
* input markdown,
|
* input markdown,
|
||||||
* expected output markdown with toc
|
* expected toc
|
||||||
* ]
|
* ]
|
||||||
*
|
* @type {*[]}
|
||||||
*/
|
*/
|
||||||
const testCases = [
|
const testCases = [
|
||||||
[
|
[
|
||||||
@@ -39,8 +42,6 @@ test(t => {
|
|||||||
- [one](#one)
|
- [one](#one)
|
||||||
|
|
||||||
<!-- tocstop -->
|
<!-- tocstop -->
|
||||||
|
|
||||||
# one
|
|
||||||
`
|
`
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -55,10 +56,7 @@ test(t => {
|
|||||||
- [one](#one)
|
- [one](#one)
|
||||||
- [two](#two)
|
- [two](#two)
|
||||||
|
|
||||||
<!-- tocstop -->
|
<!-- tocstop -->
|
||||||
|
|
||||||
# one
|
|
||||||
# two
|
|
||||||
`
|
`
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -82,13 +80,6 @@ test(t => {
|
|||||||
* [three three](#three-three)
|
* [three three](#three-three)
|
||||||
|
|
||||||
<!-- tocstop -->
|
<!-- tocstop -->
|
||||||
|
|
||||||
# one
|
|
||||||
## one one
|
|
||||||
# two
|
|
||||||
## two two
|
|
||||||
# three
|
|
||||||
## three three
|
|
||||||
`
|
`
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -120,17 +111,6 @@ test(t => {
|
|||||||
+ [three three three three three three](#three-three-three-three-three-three)
|
+ [three three three three three three](#three-three-three-three-three-three)
|
||||||
|
|
||||||
<!-- tocstop -->
|
<!-- tocstop -->
|
||||||
|
|
||||||
# one
|
|
||||||
## one one
|
|
||||||
# two
|
|
||||||
## two two
|
|
||||||
# three
|
|
||||||
## three three
|
|
||||||
### three three three
|
|
||||||
#### three three three three
|
|
||||||
##### three three three three three
|
|
||||||
###### three three three three three three
|
|
||||||
`
|
`
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -193,148 +173,8 @@ this is a level one text
|
|||||||
+ [three three three three three three](#three-three-three-three-three-three)
|
+ [three three three three three three](#three-three-three-three-three-three)
|
||||||
|
|
||||||
<!-- tocstop -->
|
<!-- tocstop -->
|
||||||
|
|
||||||
# one
|
|
||||||
this is a level one text
|
|
||||||
this is a level one text
|
|
||||||
## one one
|
|
||||||
# two
|
|
||||||
this is a level two text
|
|
||||||
this is a level two text
|
|
||||||
## two two
|
|
||||||
this is a level two two text
|
|
||||||
this is a level two two text
|
|
||||||
# three
|
|
||||||
this is a level three three text
|
|
||||||
this is a level three three text
|
|
||||||
## three three
|
|
||||||
this is a text
|
|
||||||
this is a text
|
|
||||||
### three three three
|
|
||||||
this is a text
|
|
||||||
this is a text
|
|
||||||
### three three three 2
|
|
||||||
this is a text
|
|
||||||
this is a text
|
|
||||||
#### three three three three
|
|
||||||
this is a text
|
|
||||||
this is a text
|
|
||||||
#### three three three three 2
|
|
||||||
this is a text
|
|
||||||
this is a text
|
|
||||||
##### three three three three three
|
|
||||||
this is a text
|
|
||||||
this is a text
|
|
||||||
##### three three three three three 2
|
|
||||||
this is a text
|
|
||||||
this is a text
|
|
||||||
###### three three three three three three
|
|
||||||
this is a text
|
|
||||||
this is a text
|
|
||||||
this is a text
|
|
||||||
`
|
`
|
||||||
],
|
],
|
||||||
[
|
|
||||||
'***************************** already generated toc',
|
|
||||||
`
|
|
||||||
<!-- toc -->
|
|
||||||
|
|
||||||
- [one](#one)
|
|
||||||
* [one one](#one-one)
|
|
||||||
- [two](#two)
|
|
||||||
* [two two](#two-two)
|
|
||||||
- [three](#three)
|
|
||||||
* [three three](#three-three)
|
|
||||||
+ [three three three](#three-three-three)
|
|
||||||
- [three three three three](#three-three-three-three)
|
|
||||||
* [three three three three three](#three-three-three-three-three)
|
|
||||||
+ [three three three three three three](#three-three-three-three-three-three)
|
|
||||||
|
|
||||||
<!-- tocstop -->
|
|
||||||
|
|
||||||
# one
|
|
||||||
## one one
|
|
||||||
# two
|
|
||||||
## two two
|
|
||||||
# three
|
|
||||||
## three three
|
|
||||||
### three three three
|
|
||||||
#### three three three three
|
|
||||||
##### three three three three three
|
|
||||||
###### three three three three three three
|
|
||||||
`,
|
|
||||||
`
|
|
||||||
<!-- toc -->
|
|
||||||
|
|
||||||
- [one](#one)
|
|
||||||
* [one one](#one-one)
|
|
||||||
- [two](#two)
|
|
||||||
* [two two](#two-two)
|
|
||||||
- [three](#three)
|
|
||||||
* [three three](#three-three)
|
|
||||||
+ [three three three](#three-three-three)
|
|
||||||
- [three three three three](#three-three-three-three)
|
|
||||||
* [three three three three three](#three-three-three-three-three)
|
|
||||||
+ [three three three three three three](#three-three-three-three-three-three)
|
|
||||||
|
|
||||||
<!-- tocstop -->
|
|
||||||
|
|
||||||
# one
|
|
||||||
## one one
|
|
||||||
# two
|
|
||||||
## two two
|
|
||||||
# three
|
|
||||||
## three three
|
|
||||||
### three three three
|
|
||||||
#### three three three three
|
|
||||||
##### three three three three three
|
|
||||||
###### three three three three three three
|
|
||||||
`
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'***************************** note with just an opening TOC marker',
|
|
||||||
`
|
|
||||||
<!-- toc -->
|
|
||||||
|
|
||||||
|
|
||||||
# one
|
|
||||||
## one one
|
|
||||||
|
|
||||||
`,
|
|
||||||
`
|
|
||||||
<!-- toc -->
|
|
||||||
|
|
||||||
- [one](#one)
|
|
||||||
* [one one](#one-one)
|
|
||||||
|
|
||||||
<!-- tocstop -->
|
|
||||||
|
|
||||||
# one
|
|
||||||
## one one
|
|
||||||
`
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'***************************** note with just a closing TOC marker',
|
|
||||||
`
|
|
||||||
<!-- tocstop -->
|
|
||||||
|
|
||||||
# one
|
|
||||||
## one one
|
|
||||||
`,
|
|
||||||
`
|
|
||||||
<!-- toc -->
|
|
||||||
|
|
||||||
- [one](#one)
|
|
||||||
* [one one](#one-one)
|
|
||||||
|
|
||||||
<!-- tocstop -->
|
|
||||||
|
|
||||||
# one
|
|
||||||
## one one
|
|
||||||
|
|
||||||
`
|
|
||||||
],
|
|
||||||
|
|
||||||
[
|
[
|
||||||
'***************************** outdated TOC',
|
'***************************** outdated TOC',
|
||||||
`
|
`
|
||||||
@@ -346,8 +186,7 @@ this is a level one text
|
|||||||
<!-- tocstop -->
|
<!-- tocstop -->
|
||||||
|
|
||||||
# one modified
|
# one modified
|
||||||
## one one
|
## one one
|
||||||
|
|
||||||
`,
|
`,
|
||||||
`
|
`
|
||||||
<!-- toc -->
|
<!-- toc -->
|
||||||
@@ -356,9 +195,6 @@ this is a level one text
|
|||||||
* [one one](#one-one)
|
* [one one](#one-one)
|
||||||
|
|
||||||
<!-- tocstop -->
|
<!-- tocstop -->
|
||||||
|
|
||||||
# one modified
|
|
||||||
## one one
|
|
||||||
`
|
`
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -374,9 +210,6 @@ this is a level one text
|
|||||||
* [oNe one](#oNe-one)
|
* [oNe one](#oNe-one)
|
||||||
|
|
||||||
<!-- tocstop -->
|
<!-- tocstop -->
|
||||||
|
|
||||||
# onE
|
|
||||||
## oNe one
|
|
||||||
`
|
`
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -397,19 +230,12 @@ this is a text
|
|||||||
## oNe one
|
## oNe one
|
||||||
`,
|
`,
|
||||||
`
|
`
|
||||||
# title
|
|
||||||
|
|
||||||
this is a text
|
|
||||||
|
|
||||||
<!-- toc -->
|
<!-- toc -->
|
||||||
|
|
||||||
- [onE](#onE)
|
- [onE](#onE)
|
||||||
* [oNe one](#oNe-one)
|
* [oNe one](#oNe-one)
|
||||||
|
|
||||||
<!-- tocstop -->
|
<!-- tocstop -->
|
||||||
|
|
||||||
# onE
|
|
||||||
## oNe one
|
|
||||||
`
|
`
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -424,11 +250,7 @@ this is a text
|
|||||||
|
|
||||||
- [hoge](#hoge)
|
- [hoge](#hoge)
|
||||||
|
|
||||||
<!-- tocstop -->
|
<!-- tocstop -->
|
||||||
|
|
||||||
# hoge
|
|
||||||
|
|
||||||
##
|
|
||||||
`
|
`
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@@ -436,9 +258,411 @@ this is a text
|
|||||||
testCases.forEach(testCase => {
|
testCases.forEach(testCase => {
|
||||||
const title = testCase[0]
|
const title = testCase[0]
|
||||||
const inputMd = testCase[1].trim()
|
const inputMd = testCase[1].trim()
|
||||||
const expectedOutput = testCase[2].trim()
|
const expectedToc = testCase[2].trim()
|
||||||
let generatedOutput
|
const generatedToc = markdownToc.generate(inputMd)
|
||||||
markdownToc.generate(inputMd, (o) => { generatedOutput = o.trim() })
|
|
||||||
t.is(generatedOutput, expectedOutput, `Test ${title} , generated : ${EOL}${generatedOutput}, expected : ${EOL}${expectedOutput}`)
|
t.is(generatedToc, expectedToc, `generate test : ${title} , generated : ${EOL}${generatedToc}, expected : ${EOL}${expectedToc}`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test(t => {
|
||||||
|
/**
|
||||||
|
* Contains array of test cases in format :
|
||||||
|
* [
|
||||||
|
* title
|
||||||
|
* cursor
|
||||||
|
* inputMd
|
||||||
|
* expectedMd
|
||||||
|
* ]
|
||||||
|
* @type {*[]}
|
||||||
|
*/
|
||||||
|
const testCases = [
|
||||||
|
[
|
||||||
|
`***************************** Empty note, cursor at the top`,
|
||||||
|
{line: 0, ch: 0},
|
||||||
|
``,
|
||||||
|
`
|
||||||
|
<!-- toc -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- tocstop -->
|
||||||
|
`
|
||||||
|
],
|
||||||
|
[
|
||||||
|
`***************************** Two level note,TOC at the beginning `,
|
||||||
|
{line: 0, ch: 0},
|
||||||
|
`
|
||||||
|
# one
|
||||||
|
this is a level one text
|
||||||
|
this is a level one text
|
||||||
|
|
||||||
|
## one one
|
||||||
|
# two
|
||||||
|
this is a level two text
|
||||||
|
this is a level two text
|
||||||
|
## two two
|
||||||
|
this is a level two two text
|
||||||
|
this is a level two two text
|
||||||
|
`,
|
||||||
|
`
|
||||||
|
<!-- toc -->
|
||||||
|
|
||||||
|
- [one](#one)
|
||||||
|
* [one one](#one-one)
|
||||||
|
- [two](#two)
|
||||||
|
* [two two](#two-two)
|
||||||
|
|
||||||
|
<!-- tocstop -->
|
||||||
|
# one
|
||||||
|
this is a level one text
|
||||||
|
this is a level one text
|
||||||
|
|
||||||
|
## one one
|
||||||
|
# two
|
||||||
|
this is a level two text
|
||||||
|
this is a level two text
|
||||||
|
## two two
|
||||||
|
this is a level two two text
|
||||||
|
this is a level two two text
|
||||||
|
`
|
||||||
|
],
|
||||||
|
[
|
||||||
|
`***************************** Two level note, cursor just after 'header text' `,
|
||||||
|
{line: 1, ch: 12},
|
||||||
|
`
|
||||||
|
# header
|
||||||
|
header text
|
||||||
|
|
||||||
|
# one
|
||||||
|
this is a level one text
|
||||||
|
this is a level one text
|
||||||
|
|
||||||
|
## one one
|
||||||
|
# two
|
||||||
|
this is a level two text
|
||||||
|
this is a level two text
|
||||||
|
## two two
|
||||||
|
this is a level two two text
|
||||||
|
this is a level two two text
|
||||||
|
`,
|
||||||
|
`
|
||||||
|
# header
|
||||||
|
header text
|
||||||
|
<!-- toc -->
|
||||||
|
|
||||||
|
- [one](#one)
|
||||||
|
* [one one](#one-one)
|
||||||
|
- [two](#two)
|
||||||
|
* [two two](#two-two)
|
||||||
|
|
||||||
|
<!-- tocstop -->
|
||||||
|
|
||||||
|
# one
|
||||||
|
this is a level one text
|
||||||
|
this is a level one text
|
||||||
|
|
||||||
|
## one one
|
||||||
|
# two
|
||||||
|
this is a level two text
|
||||||
|
this is a level two text
|
||||||
|
## two two
|
||||||
|
this is a level two two text
|
||||||
|
this is a level two two text
|
||||||
|
`
|
||||||
|
],
|
||||||
|
[
|
||||||
|
`***************************** Two level note, cursor at empty line under 'header text' `,
|
||||||
|
{line: 2, ch: 0},
|
||||||
|
`
|
||||||
|
# header
|
||||||
|
header text
|
||||||
|
|
||||||
|
# one
|
||||||
|
this is a level one text
|
||||||
|
this is a level one text
|
||||||
|
|
||||||
|
## one one
|
||||||
|
# two
|
||||||
|
this is a level two text
|
||||||
|
this is a level two text
|
||||||
|
## two two
|
||||||
|
this is a level two two text
|
||||||
|
this is a level two two text
|
||||||
|
`,
|
||||||
|
`
|
||||||
|
# header
|
||||||
|
header text
|
||||||
|
<!-- toc -->
|
||||||
|
|
||||||
|
- [one](#one)
|
||||||
|
* [one one](#one-one)
|
||||||
|
- [two](#two)
|
||||||
|
* [two two](#two-two)
|
||||||
|
|
||||||
|
<!-- tocstop -->
|
||||||
|
# one
|
||||||
|
this is a level one text
|
||||||
|
this is a level one text
|
||||||
|
|
||||||
|
## one one
|
||||||
|
# two
|
||||||
|
this is a level two text
|
||||||
|
this is a level two text
|
||||||
|
## two two
|
||||||
|
this is a level two two text
|
||||||
|
this is a level two two text
|
||||||
|
`
|
||||||
|
],
|
||||||
|
[
|
||||||
|
`***************************** Two level note, cursor just before 'text' word`,
|
||||||
|
{line: 1, ch: 8},
|
||||||
|
`
|
||||||
|
# header
|
||||||
|
header text
|
||||||
|
|
||||||
|
# one
|
||||||
|
this is a level one text
|
||||||
|
this is a level one text
|
||||||
|
|
||||||
|
## one one
|
||||||
|
# two
|
||||||
|
this is a level two text
|
||||||
|
this is a level two text
|
||||||
|
## two two
|
||||||
|
this is a level two two text
|
||||||
|
this is a level two two text
|
||||||
|
`,
|
||||||
|
`
|
||||||
|
# header
|
||||||
|
header
|
||||||
|
<!-- toc -->
|
||||||
|
|
||||||
|
- [one](#one)
|
||||||
|
* [one one](#one-one)
|
||||||
|
- [two](#two)
|
||||||
|
* [two two](#two-two)
|
||||||
|
|
||||||
|
<!-- tocstop -->
|
||||||
|
text
|
||||||
|
|
||||||
|
# one
|
||||||
|
this is a level one text
|
||||||
|
this is a level one text
|
||||||
|
|
||||||
|
## one one
|
||||||
|
# two
|
||||||
|
this is a level two text
|
||||||
|
this is a level two text
|
||||||
|
## two two
|
||||||
|
this is a level two two text
|
||||||
|
this is a level two two text
|
||||||
|
`
|
||||||
|
],
|
||||||
|
[
|
||||||
|
`***************************** Already generated TOC without header file, regenerate TOC in place, no changes`,
|
||||||
|
{line: 13, ch: 0},
|
||||||
|
`
|
||||||
|
# header
|
||||||
|
header text
|
||||||
|
<!-- toc -->
|
||||||
|
|
||||||
|
- [one](#one)
|
||||||
|
* [one one](#one-one)
|
||||||
|
- [two](#two)
|
||||||
|
* [two two](#two-two)
|
||||||
|
|
||||||
|
<!-- tocstop -->
|
||||||
|
# one
|
||||||
|
this is a level one text
|
||||||
|
this is a level one text
|
||||||
|
|
||||||
|
## one one
|
||||||
|
# two
|
||||||
|
this is a level two text
|
||||||
|
this is a level two text
|
||||||
|
## two two
|
||||||
|
this is a level two two text
|
||||||
|
this is a level two two text
|
||||||
|
`,
|
||||||
|
`
|
||||||
|
# header
|
||||||
|
header text
|
||||||
|
<!-- toc -->
|
||||||
|
|
||||||
|
- [one](#one)
|
||||||
|
* [one one](#one-one)
|
||||||
|
- [two](#two)
|
||||||
|
* [two two](#two-two)
|
||||||
|
|
||||||
|
<!-- tocstop -->
|
||||||
|
# one
|
||||||
|
this is a level one text
|
||||||
|
this is a level one text
|
||||||
|
|
||||||
|
## one one
|
||||||
|
# two
|
||||||
|
this is a level two text
|
||||||
|
this is a level two text
|
||||||
|
## two two
|
||||||
|
this is a level two two text
|
||||||
|
this is a level two two text
|
||||||
|
`
|
||||||
|
],
|
||||||
|
[
|
||||||
|
`***************************** Already generated TOC, needs updating in place`,
|
||||||
|
{line: 0, ch: 0},
|
||||||
|
`
|
||||||
|
# header
|
||||||
|
header text
|
||||||
|
<!-- toc -->
|
||||||
|
|
||||||
|
- [one](#one)
|
||||||
|
* [one one](#one-one)
|
||||||
|
- [two](#two)
|
||||||
|
* [two two](#two-two)
|
||||||
|
|
||||||
|
<!-- tocstop -->
|
||||||
|
# This is the one
|
||||||
|
this is a level one text
|
||||||
|
this is a level one text
|
||||||
|
|
||||||
|
## one one
|
||||||
|
# two
|
||||||
|
this is a level two text
|
||||||
|
this is a level two text
|
||||||
|
## two two
|
||||||
|
this is a level two two text
|
||||||
|
this is a level two two text
|
||||||
|
`,
|
||||||
|
`
|
||||||
|
# header
|
||||||
|
header text
|
||||||
|
<!-- toc -->
|
||||||
|
|
||||||
|
- [This is the one](#This-is-the-one)
|
||||||
|
* [one one](#one-one)
|
||||||
|
- [two](#two)
|
||||||
|
* [two two](#two-two)
|
||||||
|
|
||||||
|
<!-- tocstop -->
|
||||||
|
# This is the one
|
||||||
|
this is a level one text
|
||||||
|
this is a level one text
|
||||||
|
|
||||||
|
## one one
|
||||||
|
# two
|
||||||
|
this is a level two text
|
||||||
|
this is a level two text
|
||||||
|
## two two
|
||||||
|
this is a level two two text
|
||||||
|
this is a level two two text
|
||||||
|
`
|
||||||
|
],
|
||||||
|
[
|
||||||
|
`***************************** Document with cursor at the last line, expecting empty TOC `,
|
||||||
|
{line: 13, ch: 30},
|
||||||
|
`
|
||||||
|
# header
|
||||||
|
header text
|
||||||
|
|
||||||
|
# This is the one
|
||||||
|
this is a level one text
|
||||||
|
this is a level one text
|
||||||
|
|
||||||
|
## one one
|
||||||
|
# two
|
||||||
|
this is a level two text
|
||||||
|
this is a level two text
|
||||||
|
## two two
|
||||||
|
this is a level two two text
|
||||||
|
this is a level two two text
|
||||||
|
`,
|
||||||
|
`
|
||||||
|
# header
|
||||||
|
header text
|
||||||
|
|
||||||
|
# This is the one
|
||||||
|
this is a level one text
|
||||||
|
this is a level one text
|
||||||
|
|
||||||
|
## one one
|
||||||
|
# two
|
||||||
|
this is a level two text
|
||||||
|
this is a level two text
|
||||||
|
## two two
|
||||||
|
this is a level two two text
|
||||||
|
this is a level two two text
|
||||||
|
<!-- toc -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- tocstop -->
|
||||||
|
`
|
||||||
|
],
|
||||||
|
[
|
||||||
|
`***************************** Empty, not actual TOC , should be supplemented with two new points beneath`,
|
||||||
|
{line: 0, ch: 0},
|
||||||
|
`
|
||||||
|
# header
|
||||||
|
header text
|
||||||
|
|
||||||
|
# This is the one
|
||||||
|
this is a level one text
|
||||||
|
this is a level one text
|
||||||
|
|
||||||
|
## one one
|
||||||
|
# two
|
||||||
|
this is a level two text
|
||||||
|
this is a level two text
|
||||||
|
## two two
|
||||||
|
this is a level two two text
|
||||||
|
this is a level two two text
|
||||||
|
<!-- toc -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- tocstop -->
|
||||||
|
# new point included in toc
|
||||||
|
## new subpoint
|
||||||
|
`,
|
||||||
|
`
|
||||||
|
# header
|
||||||
|
header text
|
||||||
|
|
||||||
|
# This is the one
|
||||||
|
this is a level one text
|
||||||
|
this is a level one text
|
||||||
|
|
||||||
|
## one one
|
||||||
|
# two
|
||||||
|
this is a level two text
|
||||||
|
this is a level two text
|
||||||
|
## two two
|
||||||
|
this is a level two two text
|
||||||
|
this is a level two two text
|
||||||
|
<!-- toc -->
|
||||||
|
|
||||||
|
- [new point included in toc](#new-point-included-in-toc)
|
||||||
|
* [new subpoint](#new-subpoint)
|
||||||
|
|
||||||
|
<!-- tocstop -->
|
||||||
|
# new point included in toc
|
||||||
|
## new subpoint
|
||||||
|
`
|
||||||
|
]
|
||||||
|
]
|
||||||
|
testCases.forEach(testCase => {
|
||||||
|
const title = testCase[0]
|
||||||
|
const cursor = testCase[1]
|
||||||
|
const inputMd = testCase[2].trim()
|
||||||
|
const expectedMd = testCase[3].trim()
|
||||||
|
|
||||||
|
const editor = CodeMirror()
|
||||||
|
editor.setValue(inputMd)
|
||||||
|
editor.setCursor(cursor)
|
||||||
|
markdownToc.generateInEditor(editor)
|
||||||
|
|
||||||
|
t.is(expectedMd, editor.getValue(), `generateInEditor test : ${title} , generated : ${EOL}${editor.getValue()}, expected : ${EOL}${expectedMd}`)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user