// Helper function to find matching closing tag function findMatchingClosingTag(src, openTag, closeTag) { let depth = 1; let index = openTag.length; while (depth > 0 && index < src.length) { if (src.startsWith(openTag, index)) { depth++; } else if (src.startsWith(closeTag, index)) { depth--; } if (depth > 0) { index++; } } return depth === 0 ? index + closeTag.length : -1; } function detailsTokenizer(src) { const detailsRegex = /^
\n/; const summaryRegex = /^(.*?)<\/summary>\n/; if (detailsRegex.test(src)) { const endIndex = findMatchingClosingTag(src, '
', '
'); if (endIndex === -1) return; const fullMatch = src.slice(0, endIndex); let content = fullMatch.slice(10, -10).trim(); // Remove
and
let summary = ''; const summaryMatch = summaryRegex.exec(content); if (summaryMatch) { summary = summaryMatch[1].trim(); content = content.slice(summaryMatch[0].length).trim(); } return { type: 'details', raw: fullMatch, summary: summary, text: content }; } } function detailsStart(src) { return src.match(/^
/) ? 0 : -1; } function detailsRenderer(token) { return `
${token.summary ? `${token.summary}` : ''} ${token.text}
`; } function detailsExtension() { return { name: 'details', level: 'block', start: detailsStart, tokenizer: detailsTokenizer, renderer: detailsRenderer }; } export default function (options = {}) { return { extensions: [detailsExtension(options)] }; }