mirror of
https://github.com/docsifyjs/docsify.git
synced 2026-10-17 04:31:18 +08:00
refactor: improve blockquoteCompiler logic (#2624)
This commit is contained in:
@@ -1,36 +1,45 @@
|
||||
export const blockquoteCompiler = ({ renderer }) =>
|
||||
(renderer.blockquote = function ({ tokens }) {
|
||||
const calloutData =
|
||||
tokens[0].type === 'paragraph' &&
|
||||
// 0: Match "[!TIP] My Title"
|
||||
// 1: Mark "[!TIP]"
|
||||
// 2: Type "TIP"
|
||||
tokens[0].raw.match(/^(\[!(\w+)\])/);
|
||||
|
||||
let openTag = '<blockquote>';
|
||||
let closeTag = '</blockquote>';
|
||||
|
||||
if (calloutData) {
|
||||
const calloutMark = calloutData[1]; // "[!TIP]"
|
||||
const calloutType = calloutData[2].toLowerCase(); // "tip"
|
||||
const token = tokens[0].tokens[0];
|
||||
// Find the first paragraph token in the blockquote
|
||||
const firstParagraphIndex = tokens.findIndex(t => t.type === 'paragraph');
|
||||
const firstParagraph = tokens[firstParagraphIndex];
|
||||
|
||||
// Remove callout mark from tokens
|
||||
['raw', 'text'].forEach(key => {
|
||||
token[key] = token[key].replace(calloutMark, '').trimStart();
|
||||
});
|
||||
if (firstParagraph) {
|
||||
// Check if the paragraph starts with a callout like [!TIP] or [!NOTE]
|
||||
const calloutData = firstParagraph.raw.match(/^(\[!(\w+)\])/);
|
||||
|
||||
// Remove empty paragraph
|
||||
if (tokens.length > 1 && !token.raw.trim()) {
|
||||
tokens = tokens.slice(1);
|
||||
if (calloutData) {
|
||||
const calloutMark = calloutData[1]; // "[!TIP]"
|
||||
const calloutType = calloutData[2].toLowerCase(); // "tip"
|
||||
|
||||
// Remove the callout mark from the paragraph raw text
|
||||
firstParagraph.raw = firstParagraph.raw
|
||||
.replace(calloutMark, '')
|
||||
.trimStart();
|
||||
if (firstParagraph.tokens && firstParagraph.tokens.length > 0) {
|
||||
firstParagraph.tokens.forEach(t => {
|
||||
if (t.raw) {
|
||||
t.raw = t.raw.replace(calloutMark, '');
|
||||
}
|
||||
if (t.text) {
|
||||
t.text = t.text.replace(calloutMark, '');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// If the first paragraph is now empty after removing [!TIP], remove it
|
||||
if (!firstParagraph.raw.trim()) {
|
||||
tokens.splice(firstParagraphIndex, 1);
|
||||
}
|
||||
|
||||
openTag = `<div class="callout ${calloutType}">`;
|
||||
closeTag = `</div>`;
|
||||
}
|
||||
|
||||
openTag = `<div class="callout ${calloutType}">`;
|
||||
closeTag = `</div>`;
|
||||
}
|
||||
|
||||
const body = this.parser.parse(tokens);
|
||||
const html = `${openTag}${body}${closeTag}`;
|
||||
|
||||
return html;
|
||||
return `${openTag}${body}${closeTag}`;
|
||||
});
|
||||
|
||||
@@ -15,41 +15,46 @@ describe('render', function () {
|
||||
test('caution', () => {
|
||||
const output = window.marked('> [!CAUTION]\n> Text');
|
||||
|
||||
expect(output).toMatchInlineSnapshot(
|
||||
`"<div class="callout caution"><p>Text</p></div>"`,
|
||||
);
|
||||
expect(output).toMatchInlineSnapshot(`
|
||||
"<div class="callout caution"><p>
|
||||
Text</p></div>"
|
||||
`);
|
||||
});
|
||||
|
||||
test('important', () => {
|
||||
const output = window.marked('> [!IMPORTANT]\n> Text');
|
||||
|
||||
expect(output).toMatchInlineSnapshot(
|
||||
`"<div class="callout important"><p>Text</p></div>"`,
|
||||
);
|
||||
expect(output).toMatchInlineSnapshot(`
|
||||
"<div class="callout important"><p>
|
||||
Text</p></div>"
|
||||
`);
|
||||
});
|
||||
|
||||
test('note', () => {
|
||||
const output = window.marked('> [!NOTE]\n> Text');
|
||||
|
||||
expect(output).toMatchInlineSnapshot(
|
||||
`"<div class="callout note"><p>Text</p></div>"`,
|
||||
);
|
||||
expect(output).toMatchInlineSnapshot(`
|
||||
"<div class="callout note"><p>
|
||||
Text</p></div>"
|
||||
`);
|
||||
});
|
||||
|
||||
test('tip', () => {
|
||||
const output = window.marked('> [!TIP]\n> Text');
|
||||
|
||||
expect(output).toMatchInlineSnapshot(
|
||||
`"<div class="callout tip"><p>Text</p></div>"`,
|
||||
);
|
||||
expect(output).toMatchInlineSnapshot(`
|
||||
"<div class="callout tip"><p>
|
||||
Text</p></div>"
|
||||
`);
|
||||
});
|
||||
|
||||
test('warning', () => {
|
||||
const output = window.marked('> [!WARNING]\n> Text');
|
||||
|
||||
expect(output).toMatchInlineSnapshot(
|
||||
`"<div class="callout warning"><p>Text</p></div>"`,
|
||||
);
|
||||
expect(output).toMatchInlineSnapshot(`
|
||||
"<div class="callout warning"><p>
|
||||
Text</p></div>"
|
||||
`);
|
||||
});
|
||||
|
||||
test('important (legacy)', () => {
|
||||
|
||||
Reference in New Issue
Block a user