File size: 1,579 Bytes
a4d7fd9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// 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 = /^<details>\n/;
	const summaryRegex = /^<summary>(.*?)<\/summary>\n/;

	if (detailsRegex.test(src)) {
		const endIndex = findMatchingClosingTag(src, '<details>', '</details>');
		if (endIndex === -1) return;

		const fullMatch = src.slice(0, endIndex);
		let content = fullMatch.slice(10, -10).trim(); // Remove <details> and </details>

		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(/^<details>/) ? 0 : -1;
}

function detailsRenderer(token) {
	return `<details>
  ${token.summary ? `<summary>${token.summary}</summary>` : ''}
  ${token.text}
  </details>`;
}

function detailsExtension() {
	return {
		name: 'details',
		level: 'block',
		start: detailsStart,
		tokenizer: detailsTokenizer,
		renderer: detailsRenderer
	};
}

export default function (options = {}) {
	return {
		extensions: [detailsExtension(options)]
	};
}