This commit is contained in:
parent
bcf0092dd8
commit
26ddcbfa89
83
markdown-it-figcaption.js
Normal file
83
markdown-it-figcaption.js
Normal file
|
@ -0,0 +1,83 @@
|
|||
export default function figcaptionPlugin(md) {
|
||||
// Rule to identify images followed by italicized text for figcaption
|
||||
function figcaptionRule(state) {
|
||||
const tokens = state.tokens;
|
||||
let figcaptionStartIndex = -1;
|
||||
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
// Check for paragraph containing only an image
|
||||
if (
|
||||
tokens[i].type === 'paragraph_open' &&
|
||||
i + 2 < tokens.length &&
|
||||
tokens[i + 1].type === 'inline' &&
|
||||
tokens[i + 1].children &&
|
||||
tokens[i + 1].children.length === 1 &&
|
||||
tokens[i + 1].children[0].type === 'image' &&
|
||||
tokens[i + 2].type === 'paragraph_close'
|
||||
) {
|
||||
// Check if the next token is a paragraph starting with emphasis
|
||||
if (
|
||||
i + 5 < tokens.length &&
|
||||
tokens[i + 3].type === 'paragraph_open' &&
|
||||
tokens[i + 4].type === 'inline' &&
|
||||
tokens[i + 4].children &&
|
||||
tokens[i + 4].children.length > 0 &&
|
||||
tokens[i + 4].children[0].type === 'em_open' &&
|
||||
tokens[i + 5].type === 'paragraph_close'
|
||||
) {
|
||||
figcaptionStartIndex = i + 3; // Start index of the caption paragraph
|
||||
|
||||
// --- Replace tokens ---
|
||||
|
||||
// 1. Change paragraph_open to figure_open
|
||||
const figureOpen = new state.Token('figure_open', 'figure', 1);
|
||||
tokens[i] = figureOpen; // Replace paragraph_open
|
||||
|
||||
// 2. Keep the inline token with the image as is (tokens[i+1])
|
||||
|
||||
// 3. Change paragraph_close to figcaption_open
|
||||
const figcaptionOpen = new state.Token('figcaption_open', 'figcaption', 1);
|
||||
tokens[i + 2] = figcaptionOpen; // Replace paragraph_close
|
||||
|
||||
// 4. Remove the caption's paragraph_open
|
||||
tokens.splice(figcaptionStartIndex, 1); // Remove paragraph_open at i+3
|
||||
|
||||
// 5. Modify the caption's inline content: remove outer <em> tags
|
||||
const captionInlineToken = tokens[figcaptionStartIndex]; // Now at index i+3 after splice
|
||||
if (
|
||||
captionInlineToken.children[0].type === 'em_open' &&
|
||||
captionInlineToken.children[captionInlineToken.children.length - 1].type === 'em_close'
|
||||
) {
|
||||
captionInlineToken.children.shift(); // Remove em_open
|
||||
captionInlineToken.children.pop(); // Remove em_close
|
||||
}
|
||||
// Adjust level for caption content
|
||||
captionInlineToken.level += 1;
|
||||
captionInlineToken.children.forEach(child => { child.level += 1; });
|
||||
|
||||
|
||||
// 6. Change the caption's paragraph_close to figcaption_close
|
||||
const figcaptionClose = new state.Token('figcaption_close', 'figcaption', -1);
|
||||
tokens[figcaptionStartIndex + 1] = figcaptionClose; // Replace paragraph_close (now at i+4)
|
||||
|
||||
// 7. Add figure_close after figcaption_close
|
||||
const figureClose = new state.Token('figure_close', 'figure', -1);
|
||||
tokens.splice(figcaptionStartIndex + 2, 0, figureClose); // Insert figure_close (at i+5)
|
||||
|
||||
// Adjust token index to skip the newly inserted/modified tokens
|
||||
i += 6; // Move past the figure structure
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
md.core.ruler.after('inline', 'figcaption', figcaptionRule);
|
||||
|
||||
// Add renderer rules if they don't exist
|
||||
md.renderer.rules.figure_open = md.renderer.rules.figure_open || function () { return '<figure>\n'; };
|
||||
md.renderer.rules.figure_close = md.renderer.rules.figure_close || function () { return '</figure>\n'; };
|
||||
md.renderer.rules.figcaption_open = md.renderer.rules.figcaption_open || function () { return '<figcaption>'; };
|
||||
md.renderer.rules.figcaption_close = md.renderer.rules.figcaption_close || function () { return '</figcaption>\n'; };
|
||||
}
|
||||
|
||||
|
Loading…
Reference in a new issue