micromark-extension-wiki-link
Version:
Parse and render wiki-style links
168 lines (128 loc) • 3.63 kB
JavaScript
import { html } from './html'
const codes = {
horizontalTab: -2,
virtualSpace: -1,
nul: 0,
eof: null,
space: 32
}
function markdownLineEndingOrSpace (code) {
return code < codes.nul || code === codes.space
}
function markdownLineEnding (code) {
return code < codes.horizontalTab
}
function wikiLink (opts = {}) {
const aliasDivider = opts.aliasDivider || ':'
const aliasMarker = aliasDivider
const startMarker = '[['
const endMarker = ']]'
function tokenize (effects, ok, nok) {
var data
var alias
var aliasCursor = 0
var startMarkerCursor = 0
var endMarkerCursor = 0
return start
function start (code) {
if (code !== startMarker.charCodeAt(startMarkerCursor)) return nok(code)
effects.enter('wikiLink')
effects.enter('wikiLinkMarker')
return consumeStart(code)
}
function consumeStart (code) {
if (startMarkerCursor === startMarker.length) {
effects.exit('wikiLinkMarker')
return consumeData(code)
}
if (code !== startMarker.charCodeAt(startMarkerCursor)) {
return nok(code)
}
effects.consume(code)
startMarkerCursor++
return consumeStart
}
function consumeData (code) {
if (markdownLineEnding(code) || code === codes.eof) {
return nok(code)
}
effects.enter('wikiLinkData')
effects.enter('wikiLinkTarget')
return consumeTarget(code)
}
function consumeTarget (code) {
if (code === aliasMarker.charCodeAt(aliasCursor)) {
if (!data) return nok(code)
effects.exit('wikiLinkTarget')
effects.enter('wikiLinkAliasMarker')
return consumeAliasMarker(code)
}
if (code === endMarker.charCodeAt(endMarkerCursor)) {
if (!data) return nok(code)
effects.exit('wikiLinkTarget')
effects.exit('wikiLinkData')
effects.enter('wikiLinkMarker')
return consumeEnd(code)
}
if (markdownLineEnding(code) || code === codes.eof) {
return nok(code)
}
if (!markdownLineEndingOrSpace(code)) {
data = true
}
effects.consume(code)
return consumeTarget
}
function consumeAliasMarker (code) {
if (aliasCursor === aliasMarker.length) {
effects.exit('wikiLinkAliasMarker')
effects.enter('wikiLinkAlias')
return consumeAlias(code)
}
if (code !== aliasMarker.charCodeAt(aliasCursor)) {
return nok(code)
}
effects.consume(code)
aliasCursor++
return consumeAliasMarker
}
function consumeAlias (code) {
if (code === endMarker.charCodeAt(endMarkerCursor)) {
if (!alias) return nok(code)
effects.exit('wikiLinkAlias')
effects.exit('wikiLinkData')
effects.enter('wikiLinkMarker')
return consumeEnd(code)
}
if (markdownLineEnding(code) || code === codes.eof) {
return nok(code)
}
if (!markdownLineEndingOrSpace(code)) {
alias = true
}
effects.consume(code)
return consumeAlias
}
function consumeEnd (code) {
if (endMarkerCursor === endMarker.length) {
effects.exit('wikiLinkMarker')
effects.exit('wikiLink')
return ok(code)
}
if (code !== endMarker.charCodeAt(endMarkerCursor)) {
return nok(code)
}
effects.consume(code)
endMarkerCursor++
return consumeEnd
}
}
var call = { tokenize: tokenize }
return {
text: { 91: call } // left square bracket
}
}
export {
wikiLink as syntax,
html
}