@@ -251,6 +251,60 @@ function transformBlockTags(children) {
|
||||
}
|
||||
}
|
||||
|
||||
function splitMixedTagParagraph(node) {
|
||||
if (node?.type !== 'paragraph' || !Array.isArray(node.children)) return [node];
|
||||
if (!node.children.some((child) => child.type === 'image')) return [node];
|
||||
|
||||
const source = node.children.map(inlineToSource).join('');
|
||||
if (!hexoTagPattern.test(source)) return [node];
|
||||
hexoTagPattern.lastIndex = 0;
|
||||
|
||||
const result = [];
|
||||
let currentChildren = [];
|
||||
|
||||
const flushParagraph = () => {
|
||||
if (currentChildren.length === 0) return;
|
||||
result.push({ type: 'paragraph', children: currentChildren });
|
||||
currentChildren = [];
|
||||
};
|
||||
|
||||
for (const child of node.children) {
|
||||
if (child.type !== 'text' || typeof child.value !== 'string') {
|
||||
currentChildren.push(child);
|
||||
continue;
|
||||
}
|
||||
|
||||
const pattern = new RegExp(hexoTagPattern);
|
||||
let lastIndex = 0;
|
||||
let match;
|
||||
|
||||
while ((match = pattern.exec(child.value))) {
|
||||
const before = child.value.slice(lastIndex, match.index);
|
||||
if (before) currentChildren.push({ type: 'text', value: before });
|
||||
|
||||
flushParagraph();
|
||||
result.push({ type: 'html', value: renderTag(match[1], match[2]) });
|
||||
lastIndex = pattern.lastIndex;
|
||||
}
|
||||
|
||||
const after = child.value.slice(lastIndex);
|
||||
if (after) currentChildren.push({ type: 'text', value: after });
|
||||
}
|
||||
|
||||
flushParagraph();
|
||||
return result.length > 0 ? result : [node];
|
||||
}
|
||||
|
||||
function transformMixedTagParagraphs(children) {
|
||||
for (let index = 0; index < children.length; index += 1) {
|
||||
const replacement = splitMixedTagParagraph(children[index]);
|
||||
if (replacement.length === 1 && replacement[0] === children[index]) continue;
|
||||
|
||||
children.splice(index, 1, ...replacement);
|
||||
index += replacement.length - 1;
|
||||
}
|
||||
}
|
||||
|
||||
function inlineToSource(node) {
|
||||
if (node.type === 'text' || node.type === 'inlineCode') return node.value ?? '';
|
||||
|
||||
@@ -259,6 +313,12 @@ function inlineToSource(node) {
|
||||
return `[${text}](${node.url})`;
|
||||
}
|
||||
|
||||
if (node.type === 'image') {
|
||||
const alt = node.alt ?? '';
|
||||
const title = node.title ? ` "${node.title}"` : '';
|
||||
return ``;
|
||||
}
|
||||
|
||||
if (Array.isArray(node.children)) return node.children.map(inlineToSource).join('');
|
||||
return '';
|
||||
}
|
||||
@@ -267,12 +327,25 @@ function visit(node) {
|
||||
if (!node || typeof node !== 'object') return;
|
||||
|
||||
if (Array.isArray(node.children)) transformBlockTags(node.children);
|
||||
if (Array.isArray(node.children)) transformMixedTagParagraphs(node.children);
|
||||
|
||||
if (node.type === 'paragraph' && Array.isArray(node.children)) {
|
||||
const source = node.children.map(inlineToSource).join('');
|
||||
const transformed = transformText(source);
|
||||
|
||||
if (transformed !== source) {
|
||||
if (node.children.some((child) => child.type === 'image')) {
|
||||
node.children = node.children.map((child) => {
|
||||
if (child.type !== 'text' || typeof child.value !== 'string') return child;
|
||||
|
||||
const childTransformed = transformText(child.value);
|
||||
if (childTransformed === child.value) return child;
|
||||
|
||||
return { type: 'html', value: childTransformed };
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
node.type = 'html';
|
||||
node.value = transformed;
|
||||
delete node.children;
|
||||
|
||||
Reference in New Issue
Block a user