aboutsummaryrefslogtreecommitdiff
path: root/node_modules/markdown-it-anchor/index.js
diff options
context:
space:
mode:
authorruki <waruqi@gmail.com>2018-11-08 00:38:48 +0800
committerruki <waruqi@gmail.com>2018-11-07 21:53:09 +0800
commit26105034da4fcce7ac883c899d781f016559310d (patch)
treec459a5dc4e3aa0972d9919033ece511ce76dd129 /node_modules/markdown-it-anchor/index.js
parent2c77f00f1a7ecb6c8192f9c16d3b2001b254a107 (diff)
downloadxmake-docs-26105034da4fcce7ac883c899d781f016559310d.tar.gz
xmake-docs-26105034da4fcce7ac883c899d781f016559310d.zip
switch to vuepress
Diffstat (limited to 'node_modules/markdown-it-anchor/index.js')
-rw-r--r--node_modules/markdown-it-anchor/index.js93
1 files changed, 93 insertions, 0 deletions
diff --git a/node_modules/markdown-it-anchor/index.js b/node_modules/markdown-it-anchor/index.js
new file mode 100644
index 00000000..1a087b58
--- /dev/null
+++ b/node_modules/markdown-it-anchor/index.js
@@ -0,0 +1,93 @@
+const slugify = (s) => encodeURIComponent(String(s).trim().toLowerCase().replace(/\s+/g, '-'))
+
+const position = {
+ false: 'push',
+ true: 'unshift'
+}
+
+const hasProp = Object.prototype.hasOwnProperty
+
+const permalinkHref = slug => `#${slug}`
+
+const renderPermalink = (slug, opts, state, idx) => {
+ const space = () => Object.assign(new state.Token('text', '', 0), { content: ' ' })
+
+ const linkTokens = [
+ Object.assign(new state.Token('link_open', 'a', 1), {
+ attrs: [
+ ['class', opts.permalinkClass],
+ ['href', opts.permalinkHref(slug, state)],
+ ['aria-hidden', 'true']
+ ]
+ }),
+ Object.assign(new state.Token('html_block', '', 0), { content: opts.permalinkSymbol }),
+ new state.Token('link_close', 'a', -1)
+ ]
+
+ // `push` or `unshift` according to position option.
+ // Space is at the opposite side.
+ linkTokens[position[!opts.permalinkBefore]](space())
+ state.tokens[idx + 1].children[position[opts.permalinkBefore]](...linkTokens)
+}
+
+const uniqueSlug = (slug, slugs) => {
+ let uniq = slug
+ let i = 2
+ while (hasProp.call(slugs, uniq)) uniq = `${slug}-${i++}`
+ slugs[uniq] = true
+ return uniq
+}
+
+const isLevelSelectedNumber = selection => level => level >= selection
+const isLevelSelectedArray = selection => level => selection.includes(level)
+
+const anchor = (md, opts) => {
+ opts = Object.assign({}, anchor.defaults, opts)
+
+ md.core.ruler.push('anchor', state => {
+ const slugs = {}
+ const tokens = state.tokens
+
+ const isLevelSelected = Array.isArray(opts.level)
+ ? isLevelSelectedArray(opts.level)
+ : isLevelSelectedNumber(opts.level)
+
+ tokens
+ .filter(token => token.type === 'heading_open')
+ .filter(token => isLevelSelected(Number(token.tag.substr(1))))
+ .forEach(token => {
+ // Aggregate the next token children text.
+ const title = tokens[tokens.indexOf(token) + 1].children
+ .filter(token => token.type === 'text' || token.type === 'code_inline')
+ .reduce((acc, t) => acc + t.content, '')
+
+ let slug = token.attrGet('id')
+
+ if (slug == null) {
+ slug = uniqueSlug(opts.slugify(title), slugs)
+ token.attrPush(['id', slug])
+ }
+
+ if (opts.permalink) {
+ opts.renderPermalink(slug, opts, state, tokens.indexOf(token))
+ }
+
+ if (opts.callback) {
+ opts.callback(token, { slug, title })
+ }
+ })
+ })
+}
+
+anchor.defaults = {
+ level: 1,
+ slugify,
+ permalink: false,
+ renderPermalink,
+ permalinkClass: 'header-anchor',
+ permalinkSymbol: 'ΒΆ',
+ permalinkBefore: false,
+ permalinkHref
+}
+
+module.exports = anchor