packages-rc/rc-markdown/stories/demo-extension-variables/extension-variables/syntax.ts (70 lines of code) (raw):
/* eslint-disable no-console */
import {
Extension,
Code,
State
} from 'micromark-util-types';
import {
codes
} from 'micromark-util-symbol/codes';
import {
types
} from 'micromark-util-symbol/types';
import {
VARIABLE_TYPES
} from './const';
export default function syntax(): Extension {
return {
text: {
[`${codes.leftCurlyBrace}`]: {
name: 'variables',
tokenize(effects, ok, nok): State {
function inside(code: Code): State | void {
switch (code) {
case null:
case codes.carriageReturn:
case codes.lineFeed:
case codes.carriageReturnLineFeed:
return nok(code);
case codes.backslash:
effects.consume(code);
// eslint-disable-next-line @typescript-eslint/no-use-before-define
return insideEscape;
case codes.rightCurlyBrace:
effects.exit(types.chunkString);
effects.exit(VARIABLE_TYPES.STRING);
effects.enter(VARIABLE_TYPES.MARKER_END);
effects.consume(code);
effects.exit(VARIABLE_TYPES.MARKER_END);
effects.exit(VARIABLE_TYPES._);
return ok;
default:
effects.consume(code);
return inside;
}
}
function insideEscape(code: Code): State | void {
if (code === codes.backslash || code === codes.rightCurlyBrace) {
effects.consume(code);
return inside;
}
return inside(code);
}
function begin(code: Code): State | void {
return code === codes.rightCurlyBrace ? nok(code) : inside(code);
}
return (code: Code): State => {
console.info('start', code);
effects.enter(VARIABLE_TYPES._);
effects.enter(VARIABLE_TYPES.MARKER_START);
effects.consume(code);
effects.exit(VARIABLE_TYPES.MARKER_START);
effects.enter(VARIABLE_TYPES.STRING);
effects.enter(types.chunkString, {
contentType: 'string'
});
return begin;
};
}
}
}
};
}