|
@@ -1,5 +1,5 @@
|
|
// Helper function to find matching closing tag
|
|
// Helper function to find matching closing tag
|
|
-function findMatchingClosingTag(src, openTag, closeTag) {
|
|
|
|
|
|
+function findMatchingClosingTag(src: string, openTag: string, closeTag: string): number {
|
|
let depth = 1;
|
|
let depth = 1;
|
|
let index = openTag.length;
|
|
let index = openTag.length;
|
|
while (depth > 0 && index < src.length) {
|
|
while (depth > 0 && index < src.length) {
|
|
@@ -15,29 +15,37 @@ function findMatchingClosingTag(src, openTag, closeTag) {
|
|
return depth === 0 ? index + closeTag.length : -1;
|
|
return depth === 0 ? index + closeTag.length : -1;
|
|
}
|
|
}
|
|
|
|
|
|
-function detailsTokenizer(src) {
|
|
|
|
- const detailsRegex = /^<details>\n/;
|
|
|
|
|
|
+// Function to parse attributes from tag
|
|
|
|
+function parseAttributes(tag: string): { [key: string]: string } {
|
|
|
|
+ const attributes: { [key: string]: string } = {};
|
|
|
|
+ const attrRegex = /(\w+)="(.*?)"/g;
|
|
|
|
+ let match;
|
|
|
|
+ while ((match = attrRegex.exec(tag)) !== null) {
|
|
|
|
+ attributes[match[1]] = match[2];
|
|
|
|
+ }
|
|
|
|
+ return attributes;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function detailsTokenizer(src: string) {
|
|
|
|
+ // Updated regex to capture attributes inside <details>
|
|
|
|
+ const detailsRegex = /^<details(\s+[^>]*)?>\n/;
|
|
const summaryRegex = /^<summary>(.*?)<\/summary>\n/;
|
|
const summaryRegex = /^<summary>(.*?)<\/summary>\n/;
|
|
- const loadingRegex = /<loading\s*\/>/; // Detect <loading/>
|
|
|
|
|
|
|
|
- if (detailsRegex.test(src)) {
|
|
|
|
- const endIndex = findMatchingClosingTag(src, '<details>', '</details>');
|
|
|
|
|
|
+ const detailsMatch = detailsRegex.exec(src);
|
|
|
|
+ if (detailsMatch) {
|
|
|
|
+ const endIndex = findMatchingClosingTag(src, '<details', '</details>');
|
|
if (endIndex === -1) return;
|
|
if (endIndex === -1) return;
|
|
|
|
+
|
|
const fullMatch = src.slice(0, endIndex);
|
|
const fullMatch = src.slice(0, endIndex);
|
|
- let content = fullMatch.slice(10, -10).trim(); // Remove <details> and </details>
|
|
|
|
|
|
+ const detailsTag = detailsMatch[0];
|
|
|
|
+ const attributes = parseAttributes(detailsTag); // Parse attributes from <details>
|
|
|
|
+
|
|
|
|
+ let content = fullMatch.slice(detailsTag.length, -10).trim(); // Remove <details> and </details>
|
|
let summary = '';
|
|
let summary = '';
|
|
- let isLoading = false;
|
|
|
|
|
|
|
|
const summaryMatch = summaryRegex.exec(content);
|
|
const summaryMatch = summaryRegex.exec(content);
|
|
if (summaryMatch) {
|
|
if (summaryMatch) {
|
|
summary = summaryMatch[1].trim();
|
|
summary = summaryMatch[1].trim();
|
|
-
|
|
|
|
- // Detect and remove <loading/>
|
|
|
|
- if (loadingRegex.test(summary)) {
|
|
|
|
- isLoading = true;
|
|
|
|
- summary = summary.replace(loadingRegex, '').trim(); // Remove <loading/> from summary
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
content = content.slice(summaryMatch[0].length).trim();
|
|
content = content.slice(summaryMatch[0].length).trim();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -46,22 +54,29 @@ function detailsTokenizer(src) {
|
|
raw: fullMatch,
|
|
raw: fullMatch,
|
|
summary: summary,
|
|
summary: summary,
|
|
text: content,
|
|
text: content,
|
|
- isLoading: isLoading // Include loading property to indicate if <loading/> was present
|
|
|
|
|
|
+ attributes: attributes // Include extracted attributes from <details>
|
|
};
|
|
};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-function detailsStart(src) {
|
|
|
|
|
|
+function detailsStart(src: string) {
|
|
return src.match(/^<details>/) ? 0 : -1;
|
|
return src.match(/^<details>/) ? 0 : -1;
|
|
}
|
|
}
|
|
|
|
|
|
-function detailsRenderer(token) {
|
|
|
|
- return `<details>
|
|
|
|
|
|
+function detailsRenderer(token: any) {
|
|
|
|
+ const attributesString = token.attributes
|
|
|
|
+ ? Object.entries(token.attributes)
|
|
|
|
+ .map(([key, value]) => `${key}="${value}"`)
|
|
|
|
+ .join(' ')
|
|
|
|
+ : '';
|
|
|
|
+
|
|
|
|
+ return `<details ${attributesString}>
|
|
${token.summary ? `<summary>${token.summary}</summary>` : ''}
|
|
${token.summary ? `<summary>${token.summary}</summary>` : ''}
|
|
${token.text}
|
|
${token.text}
|
|
</details>`;
|
|
</details>`;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// Extension wrapper function
|
|
function detailsExtension() {
|
|
function detailsExtension() {
|
|
return {
|
|
return {
|
|
name: 'details',
|
|
name: 'details',
|