issue公式渲染、提交记录渲染问题
This commit is contained in:
parent
91a52ca628
commit
c565a9a40f
|
@ -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
|
@ -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
|
|
@ -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]);
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
)
|
)
|
||||||
|
|
|
@ -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()
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue