issue公式渲染、提交记录渲染问题

This commit is contained in:
黄心宇 2024-07-03 15:32:52 +08:00
parent 91a52ca628
commit c565a9a40f
7 changed files with 137 additions and 86 deletions

View File

@ -1418,28 +1418,6 @@
return this; return this;
}, },
/**
* 解析TeX(KaTeX)科学公式
* TeX(KaTeX) Renderer
*
* @returns {editormd} 返回editormd的实例对象
*/
katexRender: function () {
if (timer === null) {
return this;
}
this.previewContainer.find("." + editormd.classNames.tex).each(function () {
var tex = $(this);
editormd.$katex.render(tex.text(), tex[0]);
tex.find(".katex").css("font-size", "1.6em");
});
return this;
},
/** /**
* 解析和渲染流程图及时序图 * 解析和渲染流程图及时序图
* FlowChart and SequenceDiagram Renderer * FlowChart and SequenceDiagram Renderer
@ -1882,6 +1860,60 @@
} }
var marked = editormd.$marked; var marked = editormd.$marked;
const kateX = {
name: 'kateX',
level: 'block', // Is this a block-level or inline-level tokenizer?
start(src) {
// 匹配以 $$ 开头和结尾的 KaTeX 表达式
const startRegex = /^\$\$[^$]+?\$\$(?:\n|$)/;
// 匹配以 $ 开头和结尾的 KaTeX 表达式
const inlineRegex = /^\$[^$]+?\$(?:\n|$)/;
// 检查是否有块级 KaTeX 表达式
const blockMatch = src.match(startRegex);
if (blockMatch) {
return blockMatch.index;
}
// 检查是否有行内 KaTeX 表达式
const inlineMatch = src.match(inlineRegex);
if (inlineMatch) {
return inlineMatch.index;
}
// 如果没有匹配的内容,则返回 null 或 undefined
return null;
},
tokenizer(src, tokens) {
const match = src.match(/^\$([^\$]+)\$/);
if (match) {
return {
type: 'kateX',
raw: match[0],
text: match[1].trim(),
displayMode: false
};
}
const matchDisplay = src.match(/^\$\$([^\$]+)\$\$/);
if (matchDisplay) {
return {
type: 'kateX',
raw: matchDisplay[0],
text: matchDisplay[1].trim(),
displayMode: true
};
}
return false;
},
renderer(token) {
return katex.renderToString(token.text, { displayMode: token.displayMode });
}
};
marked.use({ extensions: [kateX] });
var markdownToC = this.markdownToC = []; var markdownToC = this.markdownToC = [];
var rendererOptions = this.markedRendererOptions = { var rendererOptions = this.markedRendererOptions = {
toc: settings.toc, toc: settings.toc,
@ -1958,12 +1990,10 @@
editormd.loadKaTeX(function () { editormd.loadKaTeX(function () {
editormd.$katex = katex; editormd.$katex = katex;
editormd.kaTeXLoaded = true; editormd.kaTeXLoaded = true;
_this.katexRender();
}); });
} }
else { else {
editormd.$katex = katex; editormd.$katex = katex;
this.katexRender();
} }
} }
@ -3418,20 +3448,10 @@
}; };
markedRenderer.paragraph = function (text) { markedRenderer.paragraph = function (text) {
var isTeXInline = /\$\$(.*)\$\$/g.test(text);
var isTeXLine = /^\$\$(.*)\$\$$/.test(text);
var isTeXAddClass = (isTeXLine) ? " class=\"" + editormd.classNames.tex + "\"" : "";
var isToC = (settings.tocm) ? /^(\[TOC\]|\[TOCM\])$/.test(text) : /^\[TOC\]$/.test(text); var isToC = (settings.tocm) ? /^(\[TOC\]|\[TOCM\])$/.test(text) : /^\[TOC\]$/.test(text);
var isToCMenu = /^\[TOCM\]$/.test(text); var isToCMenu = /^\[TOCM\]$/.test(text);
if (!isTeXLine && isTeXInline) {
text = text.replace(/(\$\$([^\$]*)\$\$)+/g, function ($1, $2) {
return "<span class=\"" + editormd.classNames.tex + "\">" + $2.replace(/\$/g, "") + "</span>";
});
}
else {
text = (isTeXLine) ? text.replace(/\$/g, "") : text;
}
var tocHTML = "<div class=\"markdown-toc editormd-markdown-toc\">" + text + "</div>"; var tocHTML = "<div class=\"markdown-toc editormd-markdown-toc\">" + text + "</div>";
@ -3803,26 +3823,6 @@
} }
} }
if (settings.tex) {
var katexHandle = function () {
div.find("." + editormd.classNames.tex).each(function () {
var tex = $(this);
katex.render(tex.text(), tex[0]);
tex.find(".katex").css("font-size", "1.6em");
});
};
if (settings.autoLoadKaTeX && !editormd.$katex && !editormd.kaTeXLoaded) {
this.loadKaTeX(function () {
editormd.$katex = katex;
editormd.kaTeXLoaded = true;
katexHandle();
});
}
else {
katexHandle();
}
}
div.getMarkdown = function () { div.getMarkdown = function () {
return saveTo.val(); return saveTo.val();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,6 @@
import marked from 'marked' import marked from 'marked'
import { escape } from 'marked/src/helpers' import { escape } from 'marked/src/helpers'
import { renderToString } from 'katex'
function indentCodeCompensation(raw, text) { function indentCodeCompensation(raw, text) {
const matchIndentToCode = raw.match(/^(\s+)(?:```)/); const matchIndentToCode = raw.match(/^(\s+)(?:```)/);
@ -91,7 +92,7 @@ const tokenizer = {
text text
} }
} }
} },
} }
const latexRegex = /(?:\${2})([^\n`]+?)(?:\${2})/gi const latexRegex = /(?:\${2})([^\n`]+?)(?:\${2})/gi
@ -119,20 +120,20 @@ function replace_math_with_ids(text) {
} }
const original_listitem = renderer.listitem // const original_listitem = renderer.listitem
renderer.listitem = function (text, task, checked) { // renderer.listitem = function (text, task, checked) {
return original_listitem(replace_math_with_ids(text), task, checked) // return original_listitem(replace_math_with_ids(text), task, checked)
} // }
const original_paragraph = renderer.paragraph // const original_paragraph = renderer.paragraph
renderer.paragraph = function (text) { // renderer.paragraph = function (text) {
return original_paragraph(replace_math_with_ids(text)) // return original_paragraph(replace_math_with_ids(text))
} // }
const original_tablecell = renderer.tablecell // const original_tablecell = renderer.tablecell
renderer.tablecell = function (content, flags) { // renderer.tablecell = function (content, flags) {
return original_tablecell(replace_math_with_ids(content), flags) // return original_tablecell(replace_math_with_ids(content), flags)
} // }
renderer.code = function (code, infostring, escaped) { renderer.code = function (code, infostring, escaped) {
const lang = (infostring || '').match(/\S*/)[0]; const lang = (infostring || '').match(/\S*/)[0];
@ -170,6 +171,7 @@ renderer.heading = function (text, level, raw) {
let id = cleanString(anchor); let id = cleanString(anchor);
return '<h' + level + ' id="' + id + '" class="markdown_anchors"><a name="#'+id+'" class="anchors"><i class="iconfont icon-lianjieicon font-14"></i></a>' + text + '</h' + level + '>' return '<h' + level + ' id="' + id + '" class="markdown_anchors"><a name="#'+id+'" class="anchors"><i class="iconfont icon-lianjieicon font-14"></i></a>' + text + '</h' + level + '>'
} }
marked.setOptions({ marked.setOptions({
silent: true, silent: true,
smartypants: true, smartypants: true,
@ -177,6 +179,60 @@ marked.setOptions({
pedantic: false pedantic: false
}) })
const kateX = {
name: 'kateX',
level: 'block', // Is this a block-level or inline-level tokenizer?
start(src) {
// 匹配以 $$ 开头和结尾的 KaTeX 表达式
const startRegex = /^\$\$[^$]+?\$\$(?:\n|$)/;
// 匹配以 $ 开头和结尾的 KaTeX 表达式
const inlineRegex = /^\$[^$]+?\$(?:\n|$)/;
// 检查是否有块级 KaTeX 表达式
const blockMatch = src.match(startRegex);
if (blockMatch) {
return blockMatch.index;
}
// 检查是否有行内 KaTeX 表达式
const inlineMatch = src.match(inlineRegex);
if (inlineMatch) {
return inlineMatch.index;
}
// 如果没有匹配的内容,则返回 null 或 undefined
return null;
},
tokenizer(src, tokens) {
const match = src.match(/^\$([^\$]+)\$/);
if (match) {
return {
type: 'kateX',
raw: match[0],
text: match[1].trim(),
displayMode: false
};
}
const matchDisplay = src.match(/^\$\$([^\$]+)\$\$/);
if (matchDisplay) {
return {
type: 'kateX',
raw: matchDisplay[0],
text: matchDisplay[1].trim(),
displayMode: true
};
}
return false;
},
renderer(token) {
return renderToString(token.text, { displayMode: token.displayMode });
}
};
marked.use({ extensions: [kateX] });
marked.use({ tokenizer, renderer }); marked.use({ tokenizer, renderer });
export default marked export default marked

View File

@ -1,5 +1,5 @@
import React, { useEffect, useRef, useMemo , useState } from 'react' import React, { useEffect, useRef, useMemo , useState } from 'react'
// import 'katex/dist/katex.min.css'; import "../modules/courses/katex.css";
import marked, { getTocContent, cleanToc, getMathExpressions, resetMathExpressions } from '../common/marked'; import marked, { getTocContent, cleanToc, getMathExpressions, resetMathExpressions } from '../common/marked';
import 'code-prettify'; import 'code-prettify';
import dompurify from 'dompurify'; import dompurify from 'dompurify';
@ -96,14 +96,13 @@ export default ({
rs = rs.split(`<a href="`+`/${owner}/${projectsId}/issues/${item.project_issues_index}`+`">#${item.project_issues_index}</a>`).join(content); rs = rs.split(`<a href="`+`/${owner}/${projectsId}/issues/${item.project_issues_index}`+`">#${item.project_issues_index}</a>`).join(content);
} }
} }
// rs = rs.replace(/(__special_katext_id_\d+__)/g, (_match, capture) => {
rs = rs.replace(/(__special_katext_id_\d+__)/g, (_match, capture) => { // const { type, expression } = math_expressions[capture];
const { type, expression } = math_expressions[capture]; // return renderToString(_unescape(expression) || '', { displayMode: type === 'block', throwOnError: false, output: 'html' })
return renderToString(_unescape(expression) || '', { displayMode: type === 'block', throwOnError: false, output: 'html' }) // })
}) // rs = dompurify.sanitize(rs.replace(//g, ""))
rs = dompurify.sanitize(rs.replace(/▁/g, "▁▁▁")) // rs = rs.split('<img ').join(`<img onerror="javascript:this.src='${ imgError }';"`) // replaceall
rs = rs.split('<img ').join(`<img onerror="javascript:this.src='${ imgError }';"`) // replaceall // resetMathExpressions()
resetMathExpressions()
return rs return rs
}, [str,issues]); }, [str,issues]);

View File

@ -133,8 +133,7 @@ function Files({ data,history,owner,projectsId , parentsSha }){
</span> </span>
<div style={{display:"flex"}}> <div style={{display:"flex"}}>
<span className="linetype">{item.type===2 ? "+" : item.type===3 ? "-" :""}</span> <span className="linetype">{item.type===2 ? "+" : item.type===3 ? "-" :""}</span>
<div dangerouslySetInnerHTML={{__html:(item.type===3 || item.type===2) ? subStrContent(item.content) : item.content}}></div> <div><span style={{whiteSpace:"pre-wrap"}}>{(item.type===3 || item.type===2) ? subStrContent(item.content) : item.content}</span></div>
{/* <div><span style={{whiteSpace:"pre-wrap"}}>{(item.type===3 || item.type===2) ? subStrContent(item.content) : item.content}</span></div> */}
</div> </div>
</div> </div>
) )

View File

@ -379,12 +379,12 @@ export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, cla
icon.addClass("none"); icon.addClass("none");
}, },
"inline-latex": function (cm, icon, cursor, selection) { "inline-latex": function (cm, icon, cursor, selection) {
cm.replaceSelection("$$" + selection + "$$"); cm.replaceSelection("$" + selection + "$");
cm.setCursor(cursor.line, cursor.ch + 2); cm.setCursor(cursor.line, cursor.ch + 2);
cm.focus() cm.focus()
}, },
"latex": function (cm, icon, cursor, selection) { "latex": function (cm, icon, cursor, selection) {
cm.replaceSelection("```latex\n\n" + selection + "```"); cm.replaceSelection("$$\n\n" + selection + "$$");
cm.setCursor(cursor.line + 1, 0); cm.setCursor(cursor.line + 1, 0);
cm.focus() cm.focus()
}, },