Improve markdown support and css tokens (#246)
This commit is contained in:
@@ -162,19 +162,34 @@
|
|||||||
|
|
||||||
/**Markdown-html sanitizer-interpreter */
|
/**Markdown-html sanitizer-interpreter */
|
||||||
export async function markdown(text, {mode = "inline", codelines = Infinity} = {}) {
|
export async function markdown(text, {mode = "inline", codelines = Infinity} = {}) {
|
||||||
//Sanitize once user text and then apply markdown. Depending on mode, reapply stricter sanitization if required
|
//Sanitize user input once to prevent injections and parse into markdown
|
||||||
let rendered = htmlsanitize(await marked(htmlsanitize(text), {
|
let rendered = await marked(htmlsanitize(text).replace(/^>/gm, ">"), {
|
||||||
highlight(code, lang) {
|
highlight(code, lang) {
|
||||||
return lang in prism.languages ? prism.highlight(code, prism.languages[lang]) : code
|
return lang in prism.languages ? prism.highlight(code, prism.languages[lang]) : code
|
||||||
},
|
},
|
||||||
silent:true,
|
silent:true,
|
||||||
xhtml:true,
|
xhtml:true,
|
||||||
|
})
|
||||||
|
//Markdown mode
|
||||||
|
switch (mode) {
|
||||||
|
case "inline":{
|
||||||
|
rendered = htmlsanitize(htmlsanitize(rendered, {
|
||||||
|
allowedTags:["h1", "h2", "h3", "h4", "h5", "h6", "br", "blockquote", "code", "span"],
|
||||||
|
allowedAttributes:{code:["class"], span:["class"]},
|
||||||
}), {
|
}), {
|
||||||
inline:{allowedTags:["br", "code", "span"], allowedAttributes:{code:["class"], span:["class"]}},
|
allowedAttributes:{code:["class"], span:["class"]},
|
||||||
}[mode])
|
transformTags:{h1:"b", h2:"b", h3:"b", h4:"b", h5:"b", h6:"b", blockquote:"i"},
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
//Trim code snippets
|
//Trim code snippets
|
||||||
rendered = rendered.replace(/(?<open><code[\s\S]*?>)(?<code>[\s\S]*?)(?<close><\/code>)/g, (m, open, code, close) => { //eslint-disable-line max-params
|
rendered = rendered.replace(/(?<open><code[\s\S]*?>)(?<code>[\s\S]*?)(?<close><\/code>)/g, (m, open, code, close) => { //eslint-disable-line max-params
|
||||||
const lines = code.trim().split("\n")
|
const lines = code.trim().split("\n")
|
||||||
|
if ((lines.length > 1)&&(!/class="[\s\S]*"/.test(open)))
|
||||||
|
open = open.replace(">", ' class="language-multiline">')
|
||||||
return `${open}${lines.slice(0, codelines).join("\n")}${lines.length > codelines ? `\n<span class="token trimmed">(${lines.length-codelines} more ${lines.length-codelines === 1 ? "line was" : "lines were"} trimmed)</span>` : ""}${close}`
|
return `${open}${lines.slice(0, codelines).join("\n")}${lines.length > codelines ? `\n<span class="token trimmed">(${lines.length-codelines} more ${lines.length-codelines === 1 ? "line was" : "lines were"} trimmed)</span>` : ""}${close}`
|
||||||
})
|
})
|
||||||
return rendered
|
return rendered
|
||||||
|
|||||||
@@ -76,7 +76,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
<div class="body">
|
<div class="body markdown">
|
||||||
<%- entry.body %>
|
<%- entry.body %>
|
||||||
</div>
|
</div>
|
||||||
<div class="infos">
|
<div class="infos">
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
<div class="body">
|
<div class="body markdown">
|
||||||
<%- entry.body %>
|
<%- entry.body %>
|
||||||
</div>
|
</div>
|
||||||
<div class="infos">
|
<div class="infos">
|
||||||
|
|||||||
@@ -939,7 +939,11 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Syntax highlighting */
|
/* Markdown and syntax highlighting */
|
||||||
|
.markdown b, .markdown i {
|
||||||
|
display: inline-block;
|
||||||
|
width: 97%;
|
||||||
|
}
|
||||||
code {
|
code {
|
||||||
background-color: #7777771F;
|
background-color: #7777771F;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@@ -954,35 +958,23 @@
|
|||||||
width: 97%;
|
width: 97%;
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
.token.comment, .token.prolog, .token.doctype, .token.cdata {
|
.token.comment {
|
||||||
color: #6a737d;
|
color: #669900;
|
||||||
}
|
}
|
||||||
.token.punctuation {
|
.token.punctuation {
|
||||||
color: #24292e;
|
color: #8a93a8;
|
||||||
}
|
}
|
||||||
.token.namespace, .token.property, .token.tag, .token.boolean, .token.number, .token.constant, .token.symbol {
|
.token.namespace, .token.constant, .token.symbol, .token.keyword {
|
||||||
color: #d73a49;
|
color: #b44418;
|
||||||
}
|
}
|
||||||
.token.selector, .token.attr-name, .token.string, .token.char, .token.builtin, .token.inserted {
|
.token.regex, .token.string, .token.char, .token.number, .token.boolean {
|
||||||
color: #032f62;
|
color: #2777AA;
|
||||||
}
|
}
|
||||||
.token.operator, .token.entity, .token.url, .language-css .token.string, .style .token.string, .token.variable {
|
.token.property, .token.tag {
|
||||||
color: #005cc5;
|
color: #48428a;
|
||||||
}
|
}
|
||||||
.token.atrule, .token.attr-value, .token.keyword {
|
.token.builtin, .token.operator {
|
||||||
color: #6f42c1
|
color: #106cbc;
|
||||||
}
|
|
||||||
.token.regex, .token.important {
|
|
||||||
color: #e90;
|
|
||||||
}
|
|
||||||
.token.important, .token.bold {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.token.italic {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
.token.deleted {
|
|
||||||
color: red;
|
|
||||||
}
|
}
|
||||||
.token.trimmed {
|
.token.trimmed {
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
|||||||
Reference in New Issue
Block a user