micromark-extension-wiki-link
Version:
Parse and render wiki-style links
244 lines (196 loc) • 5.91 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function html() {
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var permalinks = opts.permalinks || [];
var defaultPageResolver = function defaultPageResolver(name) {
return [name.replace(/ /g, '_').toLowerCase()];
};
var pageResolver = opts.pageResolver || defaultPageResolver;
var newClassName = opts.newClassName || 'new';
var wikiLinkClassName = opts.wikiLinkClassName || 'internal';
var defaultHrefTemplate = function defaultHrefTemplate(permalink) {
return "#/page/".concat(permalink);
};
var hrefTemplate = opts.hrefTemplate || defaultHrefTemplate;
function enterWikiLink() {
var stack = this.getData('wikiLinkStack');
if (!stack) this.setData('wikiLinkStack', stack = []);
stack.push({});
}
function top(stack) {
return stack[stack.length - 1];
}
function exitWikiLinkAlias(token) {
var alias = this.sliceSerialize(token);
var current = top(this.getData('wikiLinkStack'));
current.alias = alias;
}
function exitWikiLinkTarget(token) {
var target = this.sliceSerialize(token);
var current = top(this.getData('wikiLinkStack'));
current.target = target;
}
function exitWikiLink() {
var wikiLink = this.getData('wikiLinkStack').pop();
var pagePermalinks = pageResolver(wikiLink.target);
var permalink = pagePermalinks.find(function (p) {
return permalinks.indexOf(p) !== -1;
});
var exists = permalink !== undefined;
if (!exists) {
permalink = pagePermalinks[0];
}
var displayName = wikiLink.target;
if (wikiLink.alias) {
displayName = wikiLink.alias;
}
var classNames = wikiLinkClassName;
if (!exists) {
classNames += ' ' + newClassName;
}
this.tag('<a href="' + hrefTemplate(permalink) + '" class="' + classNames + '">');
this.raw(displayName);
this.tag('</a>');
}
return {
enter: {
wikiLink: enterWikiLink
},
exit: {
wikiLinkTarget: exitWikiLinkTarget,
wikiLinkAlias: exitWikiLinkAlias,
wikiLink: exitWikiLink
}
};
}
var 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() {
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var aliasDivider = opts.aliasDivider || ':';
var aliasMarker = aliasDivider;
var startMarker = '[[';
var 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
};
}
exports.html = html;
exports.syntax = wikiLink;