chore(format): fix lifting of trailing directives from tables
This commit is contained in:
parent
788c549948
commit
5faaf6c2b3
|
|
@ -27,11 +27,99 @@ function walkDirectiveAst(node: any): void {
|
|||
}
|
||||
}
|
||||
|
||||
// Without remark-directive, a `:::` line right after a list/table gets absorbed:
|
||||
// lists swallow it as lazy continuation, GFM tables consume it as another row.
|
||||
// Lift trailing `:::` out so it stringifies flush left.
|
||||
function shouldLiftFromList(list: any): boolean {
|
||||
const lastItem = list.children?.at(-1);
|
||||
if (lastItem?.type !== 'listItem') {
|
||||
return false;
|
||||
}
|
||||
const lastPara = lastItem.children?.at(-1);
|
||||
if (lastPara?.type !== 'paragraph') {
|
||||
return false;
|
||||
}
|
||||
const lastText = lastPara.children?.at(-1);
|
||||
if (lastText?.type !== 'text') {
|
||||
return false;
|
||||
}
|
||||
return (lastText.value as string).trimEnd().endsWith('\n:::');
|
||||
}
|
||||
|
||||
function liftFromList(list: any): void {
|
||||
const lastItem = list.children.at(-1);
|
||||
const lastPara = lastItem.children.at(-1);
|
||||
const lastText = lastPara.children.at(-1);
|
||||
lastText.value = (lastText.value as string).trimEnd().slice(0, -4);
|
||||
if (lastText.value === '') {
|
||||
lastPara.children.pop();
|
||||
}
|
||||
if (lastPara.children.length === 0) {
|
||||
lastItem.children.pop();
|
||||
}
|
||||
}
|
||||
|
||||
function shouldLiftFromTable(table: any): boolean {
|
||||
const lastRow = table.children?.at(-1);
|
||||
if (lastRow?.type !== 'tableRow') {
|
||||
return false;
|
||||
}
|
||||
const cells = lastRow.children;
|
||||
if (!Array.isArray(cells) || cells.length === 0) {
|
||||
return false;
|
||||
}
|
||||
const firstCell = cells[0];
|
||||
if (firstCell?.type !== 'tableCell' || firstCell.children?.length !== 1) {
|
||||
return false;
|
||||
}
|
||||
const text = firstCell.children[0];
|
||||
if (text?.type !== 'text' || text.value !== ':::') {
|
||||
return false;
|
||||
}
|
||||
for (let j = 1; j < cells.length; j++) {
|
||||
if (cells[j]?.type !== 'tableCell' || cells[j].children?.length !== 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function visitForLift(parent: any): void {
|
||||
if (!Array.isArray(parent.children)) {
|
||||
return;
|
||||
}
|
||||
for (const child of parent.children) {
|
||||
visitForLift(child);
|
||||
}
|
||||
for (let i = parent.children.length - 1; i >= 0; i--) {
|
||||
const node = parent.children[i];
|
||||
let lifted = false;
|
||||
if (node.type === 'list' && shouldLiftFromList(node)) {
|
||||
liftFromList(node);
|
||||
lifted = true;
|
||||
} else if (node.type === 'table' && shouldLiftFromTable(node)) {
|
||||
node.children.pop();
|
||||
lifted = true;
|
||||
}
|
||||
if (lifted) {
|
||||
parent.children.splice(i + 1, 0, {
|
||||
type: 'paragraph',
|
||||
children: [{ type: 'text', value: ':::' }],
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function remarkLiftClosingDirective() {
|
||||
return (tree: any) => visitForLift(tree);
|
||||
}
|
||||
|
||||
const processor = remark()
|
||||
.data('settings', {
|
||||
bullet: '-',
|
||||
})
|
||||
.use(remarkDirectiveSpace)
|
||||
.use(remarkLiftClosingDirective)
|
||||
.use(remarkPangu)
|
||||
.use(remarkGfm, {
|
||||
stringLength: stringWidth,
|
||||
|
|
|
|||
Loading…
Reference in New Issue