feat: improve directives parsing
All checks were successful
Deploy MinIO Explorer / deploy (push) Successful in 40s

This commit is contained in:
2025-09-06 09:47:55 +02:00
parent e097d19f07
commit edf273e604

122
script.js
View File

@@ -747,32 +747,104 @@ function parseRst(text) {
return `<div class="rst-metadata"><span class="metadata-key">${key}:</span> <span class="metadata-value">${processedValue}</span></div>`;
});
// Custom directives (.. directive::)
html = html.replace(/^\.\. ([^:]+)::\s*(.*)$/gim, '<div class="rst-directive rst-directive-$1" data-directive="$1" data-content="$2">');
// Directive options (:option: value)
html = html.replace(/^ :([^:]+):\s*(.*)$/gim, (match, key, value) => {
// Remplacer les liens par des placeholders dans les options
const processedValue = value.replace(/`([^<]+) <([^>]+)>`_/g, (match, text, url) => {
return createLinkPlaceholder(text, url);
});
return `<div class="directive-option" data-option="${key}" data-value="${value}"><span class="option-key">${key}:</span> <span class="option-value">${processedValue}</span></div>`;
});
// Special handling for big_button directive
html = html.replace(/<div class="rst-directive rst-directive-big_button"[^>]*>/g, '<div class="rst-big-button">');
// Process directive content blocks (indented text after directive)
html = html.replace(/(<div class="rst-directive[^>]*>)\n((?: [^\n]*\n?)*)/gim, (match, directive, content) => {
if (content.trim()) {
const cleanContent = content.replace(/^ /gm, '').trim();
// Remplacer les liens par des placeholders dans le contenu
const processedContent = cleanContent.replace(/`([^<]+) <([^>]+)>`_/g, (match, text, url) => {
return createLinkPlaceholder(text, url);
});
return directive + '<div class="directive-content">' + processedContent + '</div></div>';
// Process directives with their options and content - regex corrigée pour s'arrêter aux lignes non indentées
html = html.replace(/\.\. ([^:]+)::([\s\S]*?)(?=\n\S|\.\.|$)/g, (match, directive, block) => {
// Gestion spéciale pour big_button
const isBigButton = directive === 'big_button';
const className = isBigButton ? 'rst-big-button' : `rst-directive rst-directive-${directive}`;
let result = `<div class="${className}" data-directive="${directive}">`;
if (block && block.trim()) {
const lines = block.split('\n');
let options = '';
let content = '';
let inContentSection = false;
// Séparer d'abord les lignes d'options et de contenu
let optionLines = [];
let contentLines = [];
let isInOptions = true;
for (const line of lines) {
if (!line.trim()) {
// Ligne vide - si on est en section contenu, l'ajouter
if (!isInOptions) {
contentLines.push(line);
}
continue;
}
// Vérifier si c'est une option (:key: value)
const optionMatch = line.match(/^[ \t]*:([^:]+):\s*(.*)$/);
if (optionMatch && isInOptions) {
// C'est une option et on est toujours dans la section options
optionLines.push(line);
} else {
// C'est du contenu - marquer qu'on est sorti de la section options
isInOptions = false;
contentLines.push(line);
}
}
// Traiter les options
for (const line of optionLines) {
const optionMatch = line.match(/^[ \t]*:([^:]+):\s*(.*)$/);
if (optionMatch) {
const [, key, value] = optionMatch;
const processedValue = value.replace(/`([^<]+) <([^>]+)>`_/g, (match, text, url) => {
return createLinkPlaceholder(text, url);
});
options += `<div class="directive-option" data-option="${key}" data-value="${value}"><span class="option-key">${key}:</span> <span class="option-value">${processedValue}</span></div>`;
}
}
// Traiter le contenu - trouver l'indentation minimale du contenu uniquement
if (contentLines.length > 0) {
// Trouver l'indentation minimale parmi les lignes de contenu non vides
let minContentIndent = null;
for (const line of contentLines) {
if (line.trim()) {
const indentMatch = line.match(/^([ \t]*)/);
if (indentMatch) {
const indent = indentMatch[1];
if (minContentIndent === null || indent.length < minContentIndent.length) {
minContentIndent = indent;
}
}
}
}
// Construire le contenu en préservant l'indentation relative
for (const line of contentLines) {
if (!line.trim()) {
content += '\n';
} else {
let contentLine = line;
if (minContentIndent && line.startsWith(minContentIndent)) {
contentLine = line.substring(minContentIndent.length);
} else {
// Fallback : enlever toute indentation de début
contentLine = line.replace(/^[ \t]+/, '');
}
content += contentLine + '\n';
}
}
}
result += options;
if (content.trim()) {
const processedContent = content.trim().replace(/`([^<]+) <([^>]+)>`_/g, (match, text, url) => {
return createLinkPlaceholder(text, url);
});
result += `<div class="directive-content">${processedContent}</div>`;
}
}
return directive + '</div>';
result += '</div>';
return result;
});
// Bold