feat: improve directives parsing
All checks were successful
Deploy MinIO Explorer / deploy (push) Successful in 40s
All checks were successful
Deploy MinIO Explorer / deploy (push) Successful in 40s
This commit is contained in:
122
script.js
122
script.js
@@ -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>`;
|
return `<div class="rst-metadata"><span class="metadata-key">${key}:</span> <span class="metadata-value">${processedValue}</span></div>`;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Custom directives (.. directive::)
|
// Process directives with their options and content - regex corrigée pour s'arrêter aux lignes non indentées
|
||||||
html = html.replace(/^\.\. ([^:]+)::\s*(.*)$/gim, '<div class="rst-directive rst-directive-$1" data-directive="$1" data-content="$2">');
|
html = html.replace(/\.\. ([^:]+)::([\s\S]*?)(?=\n\S|\.\.|$)/g, (match, directive, block) => {
|
||||||
|
// Gestion spéciale pour big_button
|
||||||
// Directive options (:option: value)
|
const isBigButton = directive === 'big_button';
|
||||||
html = html.replace(/^ :([^:]+):\s*(.*)$/gim, (match, key, value) => {
|
const className = isBigButton ? 'rst-big-button' : `rst-directive rst-directive-${directive}`;
|
||||||
// Remplacer les liens par des placeholders dans les options
|
|
||||||
const processedValue = value.replace(/`([^<]+) <([^>]+)>`_/g, (match, text, url) => {
|
let result = `<div class="${className}" data-directive="${directive}">`;
|
||||||
return createLinkPlaceholder(text, url);
|
|
||||||
});
|
if (block && block.trim()) {
|
||||||
return `<div class="directive-option" data-option="${key}" data-value="${value}"><span class="option-key">${key}:</span> <span class="option-value">${processedValue}</span></div>`;
|
const lines = block.split('\n');
|
||||||
});
|
let options = '';
|
||||||
|
let content = '';
|
||||||
// Special handling for big_button directive
|
let inContentSection = false;
|
||||||
html = html.replace(/<div class="rst-directive rst-directive-big_button"[^>]*>/g, '<div class="rst-big-button">');
|
|
||||||
|
// Séparer d'abord les lignes d'options et de contenu
|
||||||
// Process directive content blocks (indented text after directive)
|
let optionLines = [];
|
||||||
html = html.replace(/(<div class="rst-directive[^>]*>)\n((?: [^\n]*\n?)*)/gim, (match, directive, content) => {
|
let contentLines = [];
|
||||||
if (content.trim()) {
|
let isInOptions = true;
|
||||||
const cleanContent = content.replace(/^ /gm, '').trim();
|
|
||||||
// Remplacer les liens par des placeholders dans le contenu
|
for (const line of lines) {
|
||||||
const processedContent = cleanContent.replace(/`([^<]+) <([^>]+)>`_/g, (match, text, url) => {
|
if (!line.trim()) {
|
||||||
return createLinkPlaceholder(text, url);
|
// Ligne vide - si on est en section contenu, l'ajouter
|
||||||
});
|
if (!isInOptions) {
|
||||||
return directive + '<div class="directive-content">' + processedContent + '</div></div>';
|
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
|
// Bold
|
||||||
|
|||||||
Reference in New Issue
Block a user