Markdown processing using MarkdownIt
- relative image URLs get prepended with CDN domain
- other relative URLs get prepended with domain
- non-relative URLs have
target
attr set to_blank
Nice-to-have: set non-relative URLs rel
attribute noopener
const md = MarkdownIt({
html: true,
typographer: true,
replaceLink: (link, env) => {
let fullHref = link
// Add our domain prefix to relative URLs
if (/^\/\w/.test(link)) {
if ( /\.(gif|jpe?g|png|svg)$/i.test(link) ) {
// get images from CDN
fullHref = process.env.CDN_DOMAIN_IMAGES + link
} else {
fullHref = process.env.DOMAIN + link
}
}
return fullHref
},
linkTarget: (link, env) => {
let target = '_self'
// if href is NOT a relative URL set target to _blank
if (!/^\/\w/.test(link)) {
target = '_blank'
}
return target
},
})
.use(ReplaceLink)
.use(MarkdownItBetterLinkTarget)
function MarkdownItBetterLinkTarget (md) {
md.core.ruler.after(
'inline',
'better-link-target',
state => {
var targetFn = md.options.linkTarget
if (typeof targetFn === 'function') {
state.tokens.forEach(blockToken => {
if (blockToken.type === 'inline' && blockToken.children) {
blockToken.children.forEach(token => {
var type = token.type
if (type === 'link_open') {
setAttr(token, 'target', targetFn, state.env)
}
})
}
})
}
return false
}
)
}
function setAttr (token, attrName, targetFn, env) {
const hrefAttr = token.attrGet('href')
if (hrefAttr) {
token.attrSet(attrName, targetFn(hrefAttr[1], env, token))
} else {
token.attrSet(attrName, targetFn('', env, token))
}
}