mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 17:56:25 +00:00
@@ -2,51 +2,27 @@
|
|||||||
* @fileoverview Markdown table of contents generator
|
* @fileoverview Markdown table of contents generator
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { EOL } from 'os'
|
||||||
import toc from 'markdown-toc'
|
import toc from 'markdown-toc'
|
||||||
import diacritics from 'diacritics-map'
|
|
||||||
import stripColor from 'strip-color'
|
|
||||||
import mdlink from 'markdown-link'
|
import mdlink from 'markdown-link'
|
||||||
|
import slugify from './slugify'
|
||||||
|
|
||||||
const EOL = require('os').EOL
|
const hasProp = Object.prototype.hasOwnProperty
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @caseSensitiveSlugify Custom slugify function
|
* From @enyaxu/markdown-it-anchor
|
||||||
* Same implementation that the original used by markdown-toc (node_modules/markdown-toc/lib/utils.js),
|
|
||||||
* but keeps original case to properly handle https://github.com/BoostIO/Boostnote/issues/2067
|
|
||||||
*/
|
*/
|
||||||
function caseSensitiveSlugify (str) {
|
function uniqueSlug (slug, slugs, opts) {
|
||||||
function replaceDiacritics (str) {
|
let uniq = slug
|
||||||
return str.replace(/[À-ž]/g, function (ch) {
|
let i = opts.uniqueSlugStartIndex
|
||||||
return diacritics[ch] || ch
|
while (hasProp.call(slugs, uniq)) uniq = `${slug}-${i++}`
|
||||||
})
|
slugs[uniq] = true
|
||||||
}
|
return uniq
|
||||||
|
|
||||||
function getTitle (str) {
|
|
||||||
if (/^\[[^\]]+\]\(/.test(str)) {
|
|
||||||
var m = /^\[([^\]]+)\]/.exec(str)
|
|
||||||
if (m) return m[1]
|
|
||||||
}
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
str = getTitle(str)
|
|
||||||
str = stripColor(str)
|
|
||||||
// str = str.toLowerCase() //let's be case sensitive
|
|
||||||
|
|
||||||
// `.split()` is often (but not always) faster than `.replace()`
|
|
||||||
str = str.split(' ').join('-')
|
|
||||||
str = str.split(/\t/).join('--')
|
|
||||||
str = str.split(/<\/?[^>]+>/).join('')
|
|
||||||
str = str.split(/[|$&`~=\\\/@+*!?({[\]})<>=.,;:'"^]/).join('')
|
|
||||||
str = str.split(/[。?!,、;:“”【】()〔〕[]﹃﹄“ ”‘’﹁﹂—…-~《》〈〉「」]/).join('')
|
|
||||||
str = replaceDiacritics(str)
|
|
||||||
return str
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function linkify (tok, text, slug, opts) {
|
function linkify (token) {
|
||||||
var uniqeID = opts.num === 0 ? '' : '-' + opts.num
|
token.content = mdlink(token.content, '#' + token.slug)
|
||||||
tok.content = mdlink(text, '#' + slug + uniqeID)
|
return token
|
||||||
return tok
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const TOC_MARKER_START = '<!-- toc -->'
|
const TOC_MARKER_START = '<!-- toc -->'
|
||||||
@@ -91,8 +67,23 @@ export function generateInEditor (editor) {
|
|||||||
* @returns generatedTOC String containing generated TOC
|
* @returns generatedTOC String containing generated TOC
|
||||||
*/
|
*/
|
||||||
export function generate (markdownText) {
|
export function generate (markdownText) {
|
||||||
const generatedToc = toc(markdownText, {slugify: caseSensitiveSlugify, linkify: linkify})
|
const slugs = {}
|
||||||
return TOC_MARKER_START + EOL + EOL + generatedToc.content + EOL + EOL + TOC_MARKER_END
|
const opts = {
|
||||||
|
uniqueSlugStartIndex: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = toc(markdownText, {
|
||||||
|
slugify: title => {
|
||||||
|
return uniqueSlug(slugify(title), slugs, opts)
|
||||||
|
},
|
||||||
|
linkify: false
|
||||||
|
})
|
||||||
|
|
||||||
|
const md = toc.bullets(result.json.map(linkify), {
|
||||||
|
highest: result.highest
|
||||||
|
})
|
||||||
|
|
||||||
|
return TOC_MARKER_START + EOL + EOL + md + EOL + EOL + TOC_MARKER_END
|
||||||
}
|
}
|
||||||
|
|
||||||
function wrapTocWithEol (toc, editor) {
|
function wrapTocWithEol (toc, editor) {
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import _ from 'lodash'
|
|||||||
import ConfigManager from 'browser/main/lib/ConfigManager'
|
import ConfigManager from 'browser/main/lib/ConfigManager'
|
||||||
import katex from 'katex'
|
import katex from 'katex'
|
||||||
import { lastFindInArray } from './utils'
|
import { lastFindInArray } from './utils'
|
||||||
import anchor from '@enyaxu/markdown-it-anchor'
|
|
||||||
|
|
||||||
function createGutter (str, firstLineNumber) {
|
function createGutter (str, firstLineNumber) {
|
||||||
if (Number.isNaN(firstLineNumber)) firstLineNumber = 1
|
if (Number.isNaN(firstLineNumber)) firstLineNumber = 1
|
||||||
@@ -118,14 +117,8 @@ class Markdown {
|
|||||||
this.md.use(require('markdown-it-imsize'))
|
this.md.use(require('markdown-it-imsize'))
|
||||||
this.md.use(require('markdown-it-footnote'))
|
this.md.use(require('markdown-it-footnote'))
|
||||||
this.md.use(require('markdown-it-multimd-table'))
|
this.md.use(require('markdown-it-multimd-table'))
|
||||||
this.md.use(anchor, {
|
this.md.use(require('@enyaxu/markdown-it-anchor'), {
|
||||||
slugify: (title) => {
|
slugify: require('./slugify')
|
||||||
var slug = encodeURI(title.trim()
|
|
||||||
.replace(/[\]\[\!\"\#\$\%\&\'\(\)\*\+\,\.\/\:\;\<\=\>\?\@\\\^\_\{\|\}\~]/g, '')
|
|
||||||
.replace(/\s+/g, '-'))
|
|
||||||
.replace(/\-+$/, '')
|
|
||||||
return slug
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
this.md.use(require('markdown-it-kbd'))
|
this.md.use(require('markdown-it-kbd'))
|
||||||
this.md.use(require('markdown-it-admonition'), {types: ['note', 'hint', 'attention', 'caution', 'danger', 'error']})
|
this.md.use(require('markdown-it-admonition'), {types: ['note', 'hint', 'attention', 'caution', 'danger', 'error']})
|
||||||
|
|||||||
17
browser/lib/slugify.js
Normal file
17
browser/lib/slugify.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import diacritics from 'diacritics-map'
|
||||||
|
|
||||||
|
function replaceDiacritics (str) {
|
||||||
|
return str.replace(/[À-ž]/g, function (ch) {
|
||||||
|
return diacritics[ch] || ch
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function slugify (title) {
|
||||||
|
let slug = title.trim()
|
||||||
|
|
||||||
|
slug = replaceDiacritics(slug)
|
||||||
|
|
||||||
|
slug = slug.replace(/[^\w\s-]/g, '').replace(/\s+/g, '-')
|
||||||
|
|
||||||
|
return encodeURI(slug).replace(/\-+$/, '')
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user