continuwuity/packages/remark-callouts/src/tokeniseCallout.ts
2024-08-26 22:07:55 +01:00

245 lines
5.8 KiB
TypeScript

'use strict';
import trim from "trim";
export default blockquote;
var C_NEWLINE = '\n';
var C_TAB = '\t';
var C_SPACE = ' ';
var C_GT = '>';
// TODO:
// - Grow/shrink support
// - Customise AST output
/* Tokenise a blockquote. */
function blockquote(eat: { (arg0: string): any; (arg0: string): any; now: any; }, value: string, silent: boolean) {
var self = this;
var offsets = self.offset;
var tokenizers = self.blockTokenizers;
var interruptors = [
['indentedCode', { commonmark: true }],
['fencedCode', { commonmark: true }],
['atxHeading', { commonmark: true }],
['setextHeading', { commonmark: true }],
['thematicBreak', { commonmark: true }],
['html', { commonmark: true }],
['list', { commonmark: true }],
['definition', { commonmark: false }],
['footnote', { commonmark: false }]
];
var now = eat.now();
var currentLine = now.line;
var length = value.length;
var values = [];
var contents = [];
var indents = [];
var add;
var index = 0;
var character;
var rest;
var nextIndex;
var content;
var line;
var startIndex;
var prefixed;
var exit;
while (index < length) {
character = value.charAt(index);
if (character !== C_SPACE && character !== C_TAB) {
break;
}
index++;
}
if (value.charAt(index) !== C_GT) {
return;
}
const regex = /^>\s*\[!(?<keyword>(.*?))\][\t\f ]?(?<title>.*?)$/i;
nextIndex = value.indexOf(C_NEWLINE, index);
content = value.slice(index, nextIndex);
const m = regex.exec(content); // value.slice(index)
if (!m) {
return;
}
if (!m.groups?.keyword) return;
if (silent) {
return true;
}
index = 0;
let titleLine = true
while (index < length) {
nextIndex = value.indexOf(C_NEWLINE, index);
startIndex = index;
prefixed = false;
if (nextIndex === -1) {
nextIndex = length;
}
while (index < length) {
character = value.charAt(index);
if (character !== C_SPACE && character !== C_TAB) {
break;
}
index++;
}
if (value.charAt(index) === C_GT) {
index++;
prefixed = true;
if (value.charAt(index) === C_SPACE) {
index++;
}
} else {
index = startIndex;
}
// regex.lastIndex = index
content = value.slice(index, nextIndex);
if (!prefixed && !trim(content)) {
index = startIndex;
break;
}
if (!prefixed) {
rest = value.slice(index);
/* Check if the following code contains a possible
* block. */
if (interrupt(interruptors, tokenizers, self, [eat, rest, true])) {
break;
}
}
line = startIndex === index ? content : value.slice(startIndex, nextIndex);
indents.push(index - startIndex);
values.push(line);
if (titleLine) {
titleLine = false
} else {
contents.push(content);
}
index = nextIndex + 1;
}
index = -1;
length = indents.length;
add = eat(values.join(C_NEWLINE));
while (++index < length) {
offsets[currentLine] = (offsets[currentLine] || 0) + indents[index];
currentLine++;
}
exit = self.enterBlock();
const title = self.tokenizeInline(m.groups?.title, now);
contents = self.tokenizeBlock(contents.join(C_NEWLINE), now);
exit();
// console.log(title,)
return add({
type: 'callout',
children: [{
type: "heading",
children: title,
data: { hName: 'svelte:fragment',
hProperties: {
slot: "title"
} }
}, {
type: "block",
children: contents,
data: { hName: 'svelte:fragment',
hProperties: {
slot: "body"
} }
}],
keyword: m.groups?.keyword,
data: {
hName: 'Components.Callout',
hProperties: {
"calloutType": m.groups?.keyword
},
}
});
// return add({
// type: 'callout',
// children: [{
// type: "heading",
// children: title,
// data: { hName: 'div',
// hProperties: {
// className: "callout-title"
// } }
// }, {
// type: "block",
// children: contents,
// data: { hName: 'div',
// hProperties: {
// className: "callout-content"
// } }
// }],
// keyword: m.groups?.keyword,
// data: {
// hName: 'div',
// hProperties: {
// className: "callout",
// "data-callout": m.groups?.keyword
// },
// }
// });
}
function interrupt(interruptors, tokenizers, ctx, params) {
var bools = ['pedantic', 'commonmark'];
var count = bools.length;
var length = interruptors.length;
var index = -1;
var interruptor;
var config;
var fn;
var offset;
var bool;
var ignore;
while (++index < length) {
interruptor = interruptors[index];
config = interruptor[1] || {};
fn = interruptor[0];
offset = -1;
ignore = false;
while (++offset < count) {
bool = bools[offset];
if (config[bool] !== undefined && config[bool] !== ctx.options[bool]) {
ignore = true;
break;
}
}
if (ignore) {
continue;
}
if (tokenizers[fn].apply(ctx, params)) {
return true;
}
}
return false;
}