md p标签不换行

This commit is contained in:
caishi 2020-07-31 11:21:02 +08:00
parent efc96cfc8c
commit cefd974498
7 changed files with 118 additions and 52 deletions

View File

@ -66,6 +66,7 @@ body {
margin:10px 0px!important;
font-size: 16px !important;
line-height: 2 !important;
white-space: pre-wrap;
}
.markdown-body>p {

View File

@ -78,14 +78,6 @@ export function setImagesUrl(path){
}
export function getUrl(path, goTest) {
// https://www.educoder.net
// https://testbdweb.trustie.net
// 如果想所有url定位到测试版可以反注释掉下面这行
//goTest = true
// testbdweb.educoder.net testbdweb.trustie.net
// const local = goTest ? 'https://testeduplus2.educoder.net' : 'http://localhost:3000'
// const local = 'https://testeduplus2.educoder.net'
const local = 'https://testforgeplus.trustie.net'
if (isDev) {
return `${local}${path?path:''}`

View File

@ -1,8 +1,55 @@
import marked from 'marked'
import { escape, unescape } from 'marked/src/helpers'
import { renderToString } from 'katex';
import { escape, rtrim } from 'marked/src/helpers'
import { renderToString } from 'katex'
const latexRegex = /\$+([^\$\n]+?)\$+/g
function unescape(str) {
str = str
.replace(/( |\u00a0| )/g, '')
.replace(/>/g, '>')
.replace(/&lt;/g, '<')
.replace(/\\$/g, '')
.replace(/^\\(?:{)/, '\\\\{')
if (!str.match(/\S/)) {
return '';
}
return str
}
function toKatex(str) {
return renderToString(unescape(str), {
throwOnError: false
})
}
function indentCodeCompensation(raw, text) {
const matchIndentToCode = raw.match(/^(\s+)(?:```)/);
if (matchIndentToCode === null) {
return text;
}
const indentToCode = matchIndentToCode[1];
return text
.split('\n')
.map(node => {
const matchIndentInNode = node.match(/^\s+/);
if (matchIndentInNode === null) {
return node;
}
const [indentInNode] = matchIndentInNode;
if (indentInNode.length >= indentToCode.length) {
return node.slice(indentToCode.length);
}
return node;
})
.join('\n');
}
const latexRegex = /\`?\${2}([^\$\n]+?)\${2}\`?/g
//兼容之前的 ##标题式写法
const headingRegex = /^ *(#{1,6}) *([^\n]+?) *(?:#+ *)?(?:\n+|$)/
let toc = []
@ -40,36 +87,75 @@ export function getTocContent() {
const tokenizer = {
heading(src) {
const cap = headingRegex.exec(src);
const cap = headingRegex.exec(src)
if (cap) {
return {
type: 'heading',
raw: cap[0],
depth: cap[1].length,
text: cap[2]
}
}
},
paragraph(src) {
const cap = this.rules.block.paragraph.exec(src)
let text = cap[1].charAt(cap[1].length - 1) === '\n' ? cap[1].slice(0, -1) : cap[1]
let match = text.match(latexRegex)
if (match) {
text = text.replace(latexRegex, (_, $1) => {
return toKatex($1)
})
}
if (cap) {
return {
type: 'paragraph',
raw: cap[0],
text
};
}
},
codespan(src) {
const cap = this.rules.inline.code.exec(src);
code(src, tokens) {
const cap = this.rules.block.code.exec(src)
if (cap) {
let text = cap[2].replace(/\n/g, ' ');
const hasNonSpaceChars = /[^ ]/.test(text);
const hasSpaceCharsOnBothEnds = text.startsWith(' ') && text.endsWith(' ');
if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
text = text.substring(1, text.length - 1)
const lastToken = tokens[tokens.length - 1];
// An indented code block cannot interrupt a paragraph.
if (lastToken && lastToken.type === 'paragraph') {
return {
raw: cap[0],
text: cap[0].trimRight()
}
}
let text = cap[0].replace(/^ {4}/gm, '')
text = !this.options.pedantic ? rtrim(text, '\n') : text
let match = text.match(latexRegex)
if (match) {
text = text.replace(latexRegex, (_, $1) => {
return renderToString(unescape($1))
return toKatex($1)
})
} else {
text = escape(text, true);
}
return {
type: 'code',
raw: cap[0],
codeBlockStyle: 'indented',
text
}
}
},
fences(src) {
const cap = this.rules.block.fences.exec(src)
if (cap) {
const raw = cap[0]
let text = indentCodeCompensation(raw, cap[3] || '')
const lang = cap[2] ? cap[2].trim() : cap[2]
if (['latex', 'katex', 'math'].indexOf(lang) >= 0) {
text = toKatex(text)
}
return {
type: 'codespan',
raw: cap[0],
type: 'code',
raw,
lang,
text
}
}
@ -86,19 +172,10 @@ const renderer = {
}
if (['latex', 'katex', 'math'].indexOf(lang) >= 0) {
return `<p class='editormd-tex'>${renderToString(unescape(code))}</p>`
return `<p class='editormd-tex'>${code}</p>`
} else {
return `<pre class="prettyprint linenums"><code class="language-${infostring}">${escaped ? code : escape(code, true)}</code></pre>\n`
}
}
, paragraph(text) {
let match = text.match(latexRegex)
if (match) {
text = text.replace(latexRegex, (_, $1) => {
return renderToString(unescape($1))
})
}
return '<p>' + text + '</p>\n';
},
heading(text, level, raw, slugger) {
let anchor = this.options.headerPrefix + raw.toLowerCase().replace(/[^\w\\u4e00-\\u9fa5]]+/g, '-');

View File

@ -14,7 +14,7 @@ export default ({ value = "", is_md = true, className, style = {} }) => {
}
html = html.replace(/▁/g, "▁▁▁");
// html = html.replace(/\n/g,"<br/>");
// html = html.replace(/\n/g,"<br />");
const el = useRef();
function onAncherHandler(e) {

View File

@ -73,7 +73,7 @@ class Index extends Component {
array && this.props.load && this.props.load(array);
}
beforeUpload = (file)=>{
beforeUpload = (file) => {
const { size } = this.props;
const isLt100M = file.size / 1024 / 1024 < size;
if (!isLt100M) {
@ -84,7 +84,7 @@ class Index extends Component {
render() {
//判断是否已经提交,如已提交评论则上一条评论数据清除
const { isComplete , icon } = this.props;
const { isComplete, icon } = this.props;
const { fileList } = this.state;
let list = isComplete === true ? fileList : undefined;
@ -94,14 +94,14 @@ class Index extends Component {
action: `${getUploadActionUrl()}`,
onChange: this.handleChange,
onRemove: this.onAttachmentRemove,
beforeUpload:this.beforeUpload
beforeUpload: this.beforeUpload
};
return (
<Dragger {...upload} className={this.props.className}>
{ icon || <Icon type="inbox" />}
<p className="ant-upload-text font-14">拖动文件或<span className="color-blue">点击此处上传</span></p>
</Dragger>
{icon || <Icon type="inbox" />}
<p className="ant-upload-text font-14">拖动文件或<span className="color-blue">点击此处上传</span></p>
</Dragger>
)
}
}

View File

@ -12,7 +12,7 @@ import RenderHtml from "../../components/render-html";
import ChildrenComments from "./children_comments";
import "../Order/order.css";
const { TabPane } = Tabs;
class comments extends Component {
class comments extends Component {
constructor(props) {
super(props);
this.state = {

View File

@ -75,14 +75,14 @@ function md_elocalStorage(editor, mdu, id) {
}
export default ({ mdID,onChange,autoFocus,onCMBeforeChange, onCMBlur, error = false, className = '', noStorage = false, imageExpand = true, placeholder = '', width = '100%', height = 400, initValue = '', emoji, watch, showNullButton = false, showResizeBar = false, startInit = true }) => {
export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, className = '', noStorage = false, imageExpand = true, placeholder = '', width = '100%', height = 400, initValue = '', emoji, watch, showNullButton = false, showResizeBar = false, startInit = true }) => {
const editorEl = useRef()
const resizeBarEl = useRef()
const [editorInstance, setEditorInstance] = useState()
const containerId = `mdEditor_${mdID}`
const editorBodyId = `mdEditors_${mdID}`
const tipId = `e_tips_mdEditor_${mdID}`
const tipId = `e_tips_mdEditor_${mdID}`
function onLayout() {
let ro
@ -92,10 +92,7 @@ export default ({ mdID,onChange,autoFocus,onCMBeforeChange, onCMBlur, error = fa
if (entry.target.offsetHeight > 0 || entry.target.offsetWidth > 0) {
editorInstance.resize()
editorInstance.cm.refresh()
// if(autofocus){
// editorInstance.cm.focus()
// }
editorInstance.cm.focus()
}
}
})
@ -105,7 +102,6 @@ export default ({ mdID,onChange,autoFocus,onCMBeforeChange, onCMBlur, error = fa
}
useEffect(() => {
if (editorInstance) {
return
}
@ -124,7 +120,7 @@ export default ({ mdID,onChange,autoFocus,onCMBeforeChange, onCMBlur, error = fa
searchReplace: true,
htmlDecode: "style,script,iframe",
sequenceDiagram: true,
autoFocus: autoFocus === undefined ? false : autoFocus,
autoFocus: false,
watch: watch === undefined ? true : watch,
saveHTMLToTextarea: true,
@ -256,8 +252,8 @@ export default ({ mdID,onChange,autoFocus,onCMBeforeChange, onCMBlur, error = fa
}
}
}, [
editorInstance, resizeBarEl
])
editorInstance, resizeBarEl
])
return (
<Fragment>