fix(viewer): pretty print fallback tokenizer quand highlight.js ne produit aucun token (txt/log/plaintext) (#89)
This commit is contained in:
+54
-1
@@ -467,6 +467,58 @@ function buildPrettyHtml(data, raw) {
|
||||
return `<div class="pretty-view"><div class="pp-gutter" aria-hidden="true">${gutter}</div><pre class="pp-pre"><code class="language-${lang}">${escapeHtml(text)}</code></pre></div>`;
|
||||
}
|
||||
|
||||
// Colorateur générique de secours: utilisé quand highlight.js ne produit
|
||||
// aucun token (langage plaintext — .txt/.log —, langue absente du bundle,
|
||||
// ou CDN hljs indisponible). Réutilise les classes hljs existantes (le
|
||||
// thème CDN colore string/comment/number/attr) + classes .pp-* maison
|
||||
// pour les niveaux de log qui n'ont pas d'équivalent sémantique hljs.
|
||||
const PP_TOKEN_RE = /("[^"\n]*"?|'[^'\n]*'?|`[^`\n]*`?)|(^\s*(?:#|\/\/|;)\s.*$|\s+(?:#|\/\/)\s.*$)|\b(\d+(?:\.\d+)?)\b|\b(ERROR|FATAL|CRITICAL|SEVERE|WARN(?:ING)?|INFO|DEBUG|TRACE|NOTICE)\b|^(\s*[\w.\-\/ ]+)=(?=\S)|\b(true|false|null|None|TRUE|FALSE|NULL)\b/gm;
|
||||
|
||||
function ppClassFor(m) {
|
||||
if (m[1] !== undefined) return "hljs-string";
|
||||
if (m[2] !== undefined) return "hljs-comment";
|
||||
if (m[3] !== undefined) return "hljs-number";
|
||||
if (m[4] !== undefined) {
|
||||
const lvl = m[4];
|
||||
if (/ERROR|FATAL|CRITICAL|SEVERE/.test(lvl)) return "pp-level pp-err";
|
||||
if (/WARN/.test(lvl)) return "pp-level pp-warn";
|
||||
if (/INFO|NOTICE/.test(lvl)) return "pp-level pp-info";
|
||||
return "pp-level pp-debug";
|
||||
}
|
||||
if (m[5] !== undefined) return "hljs-attr";
|
||||
if (m[6] !== undefined) return "hljs-literal";
|
||||
return null;
|
||||
}
|
||||
|
||||
function fallbackTokenize(text) {
|
||||
let out = "";
|
||||
let last = 0;
|
||||
PP_TOKEN_RE.lastIndex = 0;
|
||||
let m;
|
||||
while ((m = PP_TOKEN_RE.exec(text)) !== null) {
|
||||
if (m.index > last) out += escapeHtml(text.slice(last, m.index));
|
||||
const cls = ppClassFor(m);
|
||||
out += cls ? `<span class="${cls}">${escapeHtml(m[0])}</span>` : escapeHtml(m[0]);
|
||||
last = m.index + (m[0].length || 1);
|
||||
if (m[0].length === 0) PP_TOKEN_RE.lastIndex++; // garde anti-boucle infinie
|
||||
}
|
||||
out += escapeHtml(text.slice(last));
|
||||
return out;
|
||||
}
|
||||
|
||||
// Applique la coloration: hljs si le langage est connu et que des tokens
|
||||
// sortent, sinon fallback regex générique.
|
||||
function applyPrettyHighlight(codeEl, lang, text) {
|
||||
if (typeof hljs !== "undefined" && lang !== "plaintext") {
|
||||
try { hljs.highlightElement(codeEl); } catch (_) { /* CDN pas charge */ }
|
||||
}
|
||||
const tokens = codeEl.querySelectorAll('[class^="hljs-"]').length;
|
||||
if (!tokens && text.trim()) {
|
||||
codeEl.innerHTML = fallbackTokenize(text);
|
||||
codeEl.classList.add("hljs");
|
||||
}
|
||||
}
|
||||
|
||||
export function renderFile(data) {
|
||||
const area = getContentArea();
|
||||
|
||||
@@ -814,7 +866,8 @@ export function renderFile(data) {
|
||||
state.cachedRawSource = mdDiv.textContent || "";
|
||||
}
|
||||
mdDiv.innerHTML = buildPrettyHtml(data, state.cachedRawSource);
|
||||
safeHighlight(mdDiv.querySelector("code"));
|
||||
const codeEl = mdDiv.querySelector("code");
|
||||
applyPrettyHighlight(codeEl, detectPrettyLang(data), state.cachedRawSource);
|
||||
prettyBtn.classList.add("active");
|
||||
} else {
|
||||
mdDiv.innerHTML = data.html;
|
||||
|
||||
@@ -2092,6 +2092,31 @@ select {
|
||||
line-height: 1.55;
|
||||
white-space: pre;
|
||||
}
|
||||
/* Niveaux de log colorises par le fallback pretty-print (pas d'equivalent hljs) */
|
||||
.pretty-view .pp-level {
|
||||
font-weight: 700;
|
||||
}
|
||||
.pretty-view .pp-err {
|
||||
color: #f87171;
|
||||
}
|
||||
.pretty-view .pp-warn {
|
||||
color: #fbbf24;
|
||||
}
|
||||
.pretty-view .pp-info {
|
||||
color: #38bdf8;
|
||||
}
|
||||
.pretty-view .pp-debug {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
[data-theme="light"] .pretty-view .pp-err {
|
||||
color: #dc2626;
|
||||
}
|
||||
[data-theme="light"] .pretty-view .pp-warn {
|
||||
color: #b45309;
|
||||
}
|
||||
[data-theme="light"] .pretty-view .pp-info {
|
||||
color: #0369a1;
|
||||
}
|
||||
|
||||
/* --- Markdown Rendered Content --- */
|
||||
.md-content h1,
|
||||
|
||||
Reference in New Issue
Block a user