micromark-extension-lemmy-supersub
Version:
micromark extension to support lemmy supersub format
97 lines (90 loc) • 2.27 kB
JavaScript
/**
* @typedef {import('micromark-util-types').Construct} Construct
* @typedef {import('micromark-util-types').Extension} Extension
* @typedef {import('micromark-util-types').State} State
* @typedef {import('micromark-util-types').Token} Token
* @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext
* @typedef {import('micromark-util-types').Tokenizer} Tokenizer
* @typedef {import('micromark-util-types').TokenType} TokenType
* @typedef {import('micromark-util-types').Code} Code
*/
import { markdownLineEndingOrSpace } from 'micromark-util-character';
const codeFor = {
sup: 94,
sub: 126
};
/** @type {Extension} */
export const supersub = {
text: {
[codeFor.sub]: {
tokenize: tokenizeSupersub
},
[codeFor.sup]: {
tokenize: tokenizeSupersub
}
}
};
/**
* @this {TokenizeContext}
* @type {Tokenizer}
*/
function tokenizeSupersub(effects, ok, nok) {
/** @type {'sub' | 'sup'} */
let type;
return start;
/** @type {State} */
function start(code) {
if (code === codeFor.sup) {
type = 'sup';
} else if (code === codeFor.sub) {
type = 'sub';
} else {
return nok(code);
}
effects.enter(type);
effects.enter(`${type}Marker`);
effects.consume(code);
effects.exit(`${type}Marker`);
return data;
}
/** @type {State} */
function data(code) {
if (code === null || markdownLineEndingOrSpace(code)) {
return nok(code);
}
effects.enter("chunkText", {
contentType: "text"
});
effects.consume(code);
return content;
}
/** @type {State} */
function content(code) {
if (code === null || markdownLineEndingOrSpace(code)) {
return nok(code);
}
if (code === 92) {
effects.consume(code);
return escaped;
}
if (code === codeFor[type]) {
effects.exit("chunkText");
effects.enter(`${type}Marker`);
effects.consume(code);
effects.exit(`${type}Marker`);
effects.exit(type);
return ok;
}
effects.consume(code);
return content;
}
/** @type {State} */
function escaped(code) {
if (code === codeFor[type]) {
effects.consume(code);
return content;
}
effects.consume(code);
return content;
}
}