@thomaskoppelaar/markdown-it-wikilinks
Version:
WikiMedia-style links for the markdown-it parser
95 lines (81 loc) • 2.6 kB
JavaScript
const Plugin = require('markdown-it-regexp')
const extend = require('extend')
const sanitize = require('sanitize-filename')
module.exports = (options) => {
const defaults = {
baseURL: '/',
relativeBaseURL: './',
makeAllLinksAbsolute: false,
uriSuffix: '.html',
description_then_file: false,
separator: "\\|",
htmlAttributes: {
},
generatePageNameFromLabel: (label) => {
return label
},
postProcessPageName: (pageName) => {
pageName = pageName.trim()
pageName = pageName.split('/').map(sanitize).join('/')
pageName = pageName.replace(/\s+/, '_')
return pageName
},
postProcessLabel: (label) => {
label = label.trim()
return label
}
}
options = extend(true, defaults, options)
function isAbsolute(pageName) {
return options.makeAllLinksAbsolute || pageName.charCodeAt(0) === 0x2F/* / */
}
function removeInitialSlashes(str) {
return str.replace(/^\/+/g, '')
}
return Plugin(
new RegExp("\\[\\[([^sep\\]]+)(sep[^sep\\]]+)?\\]\\]".replace(/sep/g, options.separator)),
(match, utils) => {
let label = ''
let pageName = ''
let href = ''
let htmlAttrs = []
let htmlAttrsString = ''
const isSplit = !!match[2]
if (isSplit) {
if (options.description_then_file) {
label = match[1]
pageName = options.generatePageNameFromLabel(match[2].replace(new RegExp(options.separator), ''))
} else {
label = match[2].replace(new RegExp(options.separator), '')
pageName = options.generatePageNameFromLabel(match[1])
}
}
else {
label = match[1]
pageName = options.generatePageNameFromLabel(label)
}
label = options.postProcessLabel(label)
pageName = options.postProcessPageName(pageName)
// make sure none of the values are empty
if (!label || !pageName) {
return match.input
}
if (isAbsolute(pageName)) {
pageName = removeInitialSlashes(pageName)
href = options.baseURL + pageName + options.uriSuffix
}
else {
href = options.relativeBaseURL + pageName + options.uriSuffix
}
href = utils.escape(href)
htmlAttrs.push(`href="${href}"`)
for (let attrName in options.htmlAttributes) {
const attrValue = options.htmlAttributes[attrName]
htmlAttrs.push(`${attrName}="${attrValue}"`)
}
htmlAttrsString = htmlAttrs.join(' ')
return `<a ${htmlAttrsString}>${label}</a>`
}
)
}