fix: Code-Blöcke vor LaTeX-Parsing schützen ($-Zeichen in Code nicht mehr als Math interpretiert)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
MelekiandClaude Opus 4.6 committed 2026-04-04 22:56:53 +02:00
1 parent c23e22eefe
commit f180dbc842
1 file changed
+32 -13
+32 -13
View File
@@ -6,7 +6,21 @@ function renderMarkdown(text) {
if (!text) return '';
var src = text.trim();
// 1) LaTeX-Ausdrücke VOR dem Markdown-Parsing schützen
// 1) Code-Blöcke VOR dem LaTeX-Parsing schützen
// Sonst werden $-Zeichen in Code (z.B. PowerShell $Variable) als Math interpretiert
var preCodeBlocks = [];
// Fenced code blocks: ```...```
src = src.replace(/```[\s\S]*?```/g, function(m) {
preCodeBlocks.push(m);
return '%%PRECODE' + (preCodeBlocks.length - 1) + '%%';
});
// Inline code: `...`
src = src.replace(/`[^`]+`/g, function(m) {
preCodeBlocks.push(m);
return '%%PRECODE' + (preCodeBlocks.length - 1) + '%%';
});
// 2) LaTeX-Ausdrücke VOR dem Markdown-Parsing schützen
// Reihenfolge: zuerst Block ($$...$$), dann Inline ($...$)
var mathBlocks = [];
// Block-Math: $$...$$ (auch mehrzeilig)
@@ -20,48 +34,53 @@ function renderMarkdown(text) {
return '%%MATH' + (mathBlocks.length - 1) + '%%';
});
// 2) Markdown parsen
// 3) Code-Blöcke wiederherstellen (damit Markdown sie korrekt parst)
src = src.replace(/%%PRECODE(\d+)%%/g, function(m, idx) {
return preCodeBlocks[parseInt(idx)];
});
// 4) Markdown parsen
var html = marked.parse(src);
// 3) Code-Blöcke schützen (damit Emojis/Krea dort nicht greifen)
// 5) Code-Blöcke schützen (damit Emojis/Krea dort nicht greifen)
var codeBlocks = [];
html = html.replace(/<pre[\s>][\s\S]*?<\/pre>|<code[\s>][\s\S]*?<\/code>/gi, function(m) {
codeBlocks.push(m);
return '%%CODE' + (codeBlocks.length - 1) + '%%';
});
// 4a) [Review: AgentName] prefix → Review-Header
// 6a) [Review: AgentName] prefix → Review-Header
html = html.replace(/\[Review:\s*([^\]]+)\]\s*/g, function(match, agentName) {
return '<span class="review-inline-header"><i class="fa fa-check-circle-o"></i> <strong>' + esc(agentName.trim()) + '</strong></span> ';
});
// 4a2) [Finalizer: AgentName] prefix → Finalizer-Header
// 6a2) [Finalizer: AgentName] prefix → Finalizer-Header
html = html.replace(/\[Finalizer:\s*([^\]]+)\]\s*/g, function(match, agentName) {
return '<span class="review-inline-header finalizer-inline-header"><i class="fa fa-flag-checkered"></i> <strong>' + esc(agentName.trim()) + '</strong></span> ';
});
// 4a3) [Preparer: AgentName] prefix → Preparer-Header
// 6a3) [Preparer: AgentName] prefix → Preparer-Header
html = html.replace(/\[Preparer:\s*([^\]]+)\]\s*/g, function(match, agentName) {
return '<span class="review-inline-header preparer-inline-header"><i class="fa fa-filter"></i> <strong>' + esc(agentName.trim()) + '</strong></span> ';
});
// 4a4) [Vorbereitet von AgentName]: → Preparer-Forwarded-Header
// 6a4) [Vorbereitet von AgentName]: → Preparer-Forwarded-Header
html = html.replace(/\[Vorbereitet von\s+([^\]]+)\]:\s*/g, function(match, agentName) {
return '<div class="preparer-forwarded-header"><i class="fa fa-forward"></i> <strong>Vorbereitet von ' + esc(agentName.trim()) + '</strong></div>';
});
// 4b) [Review-Feedback von AgentName (Runde X/Y)]: → Review-Feedback-Header
// 6b) [Review-Feedback von AgentName (Runde X/Y)]: → Review-Feedback-Header
html = html.replace(/\[Review-Feedback von\s+([^\(]+)\(Runde\s+(\d+)\/(\d+)\)\]:\s*/g, function(match, agentName, round, maxRounds) {
return '<div class="review-inline-feedback"><i class="fa fa-repeat"></i> <strong>Feedback von ' + esc(agentName.trim()) + '</strong> <span class="review-round">Runde ' + esc(round) + '/' + esc(maxRounds) + '</span></div>';
});
// 4c) [APPROVED], [FORWARD], [QUESTION] und [FEEDBACK] ausblenden
// 6c) [APPROVED], [FORWARD], [QUESTION] und [FEEDBACK] ausblenden
html = html.replace(/\[APPROVED\]/g, '');
html = html.replace(/\[FORWARD\]\s*/g, '');
html = html.replace(/\[QUESTION\]\s*/g, '');
html = html.replace(/\[FEEDBACK\]\s*/g, '');
// 4d) [Krea: dateiname.png] → Inline-Thumbnail mit Klick für Vollbild
// 6d) [Krea: dateiname.png] → Inline-Thumbnail mit Klick für Vollbild
html = html.replace(/\[Krea:\s*([^\]]+)\]/g, function(match, filename) {
var fn = filename.trim();
var safeFn = esc(fn);
@@ -72,15 +91,15 @@ function renderMarkdown(text) {
+ '</span>';
});
// 5) Unicode-Emojis durch Fluent Emoji 3D ersetzen (außerhalb von Code-Blöcken)
// 7) Unicode-Emojis durch Fluent Emoji 3D ersetzen (außerhalb von Code-Blöcken)
html = replaceEmojisWithFluent(html);
// 6) Code-Blöcke wiederherstellen
// 8) Code-Blöcke wiederherstellen
html = html.replace(/%%CODE(\d+)%%/g, function(m, idx) {
return codeBlocks[parseInt(idx)];
});
// 7) LaTeX-Platzhalter durch KaTeX-gerenderten HTML ersetzen
// 9) LaTeX-Platzhalter durch KaTeX-gerenderten HTML ersetzen
html = html.replace(/%%MATH(\d+)%%/g, function(m, idx) {
var block = mathBlocks[parseInt(idx)];
try {