From fe4d6b0324ce9ca6341c6dd593c4c38cd86dfc6f Mon Sep 17 00:00:00 2001 From: miaogaolin <57740293+miaogaolin@users.noreply.github.com> Date: Fri, 3 Dec 2021 14:35:25 +0800 Subject: [PATCH] feat: support custom code block theme (#112) close #75 --- .gitignore | 5 +- package.json | 2 + src/App.vue | 2 +- src/assets/less/code-theme.less | 2 - .../less/codeTheme/github-code-block.less | 49 ------------- .../less/codeTheme/wechat-code-block.less | 62 ---------------- src/assets/less/github-v2.min.css | 72 ------------------- src/assets/scripts/config.js | 27 +++++-- src/assets/scripts/renderers/wx-renderer.js | 37 ++++------ src/assets/scripts/themes/default-theme.js | 42 ++++++----- src/assets/scripts/util.js | 17 ----- src/components/CodemirrorEditor/header.vue | 22 +++++- src/pages/index/view/CodemirrorEditor.vue | 21 +++++- src/store/index.js | 2 +- 14 files changed, 107 insertions(+), 255 deletions(-) delete mode 100644 src/assets/less/code-theme.less delete mode 100644 src/assets/less/codeTheme/github-code-block.less delete mode 100644 src/assets/less/codeTheme/wechat-code-block.less delete mode 100644 src/assets/less/github-v2.min.css diff --git a/.gitignore b/.gitignore index 9c387af..7b3f102 100644 --- a/.gitignore +++ b/.gitignore @@ -43,5 +43,8 @@ yarn-error.log* # mockm httpData + +package-lock.json public/upload/** -!public/upload/*.gitkeep \ No newline at end of file +!public/upload/*.gitkeep + diff --git a/package.json b/package.json index 25650a3..53f336e 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "crypto-js": "^4.1.1", "element-ui": "^2.15.6", "form-data": "4.0.0", + "highlight.js": "^11.3.1", "jquery": "^3.6.0", "juice": "^8.0.0", "marked": "^4.0.5", @@ -39,6 +40,7 @@ "@vue/cli-service": "~4.5.15", "async-validator": "^4.0.7", "babel-plugin-import": "^1.13.3", + "cache-loader": "^4.1.0", "cross-env": "^7.0.3", "jest": "^27.4.0", "less": "^4.1.2", diff --git a/src/App.vue b/src/App.vue index 3c99dfd..58c415c 100644 --- a/src/App.vue +++ b/src/App.vue @@ -20,7 +20,7 @@ body, /* 每个页面公共css */ @import url("./assets/less/style-mirror.css"); @import url("./assets/less/theme.less"); -@import url("./assets/less/code-theme.less"); + ::-webkit-scrollbar { width: 6px; height: 6px; diff --git a/src/assets/less/code-theme.less b/src/assets/less/code-theme.less deleted file mode 100644 index 2315e23..0000000 --- a/src/assets/less/code-theme.less +++ /dev/null @@ -1,2 +0,0 @@ -@import url("./codeTheme/wechat-code-block.less"); -@import url("./codeTheme/github-code-block.less"); diff --git a/src/assets/less/codeTheme/github-code-block.less b/src/assets/less/codeTheme/github-code-block.less deleted file mode 100644 index 0fb6e11..0000000 --- a/src/assets/less/codeTheme/github-code-block.less +++ /dev/null @@ -1,49 +0,0 @@ -@import url("../github-v2.min.css"); -/*github code block*/ -.code-snippet__github { - display: flex; - font-size: 12px; - margin: 10px 8px; - position: relative; - height: auto; - background-color: #f7f7f7; - border-radius: 8px; - - .code-snippet__line-index { - display: none; - } - - .code__pre { - display: grid; - position: relative; - counter-reset: line; - overflow-x: auto; - padding: 1em; - white-space: normal; - flex: 1; - line-height: 20px; - font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; - -webkit-overflow-scrolling: touch; - } - - pre { - display: inline-block; - font-size: 12px; - } - - code { - display: flex; - position: relative; - padding-right: 8px; - text-align: left; - white-space: pre; - font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; - &::before { - display: none; - } - } - - ul li { - list-style: none; - } -} diff --git a/src/assets/less/codeTheme/wechat-code-block.less b/src/assets/less/codeTheme/wechat-code-block.less deleted file mode 100644 index 526559d..0000000 --- a/src/assets/less/codeTheme/wechat-code-block.less +++ /dev/null @@ -1,62 +0,0 @@ -/*wechat code block*/ -.rich_media_content .code-snippet *, -.rich_media_content .code-snippet__wechat * { - max-width: 1000% !important; -} - -.code-snippet__wechat { - word-wrap: break-word !important; - font-size: 14px; - margin: 10px 8px; - color: #333; - position: relative; - background-color: rgba(27, 31, 35, 0.05); - border: 1px solid #f0f0f0; - border-radius: 2px; - display: flex; - line-height: 24px; -} - -.code-snippet__wechat .code-snippet__line-index { - counter-reset: line; - flex-shrink: 0; - height: 100%; - padding: 1em; - list-style-type: none; -} - -.code-snippet__wechat .code-snippet__line-index li { - list-style-type: none; - text-align: right; -} - -.code-snippet__wechat .code-snippet__line-index li::before { - min-width: 1.5em; - text-align: right; - left: -2.5em; - counter-increment: line; - content: counter(line); - display: inline; - color: rgba(0, 0, 0, 0.15); -} - -.code-snippet__wechat pre { - overflow-x: auto; - padding: 1em 1em 1em 1em; - white-space: normal; - flex: 1; - -webkit-overflow-scrolling: touch; -} - -.code-snippet__wechat code { - text-align: left; - font-size: 14px; - white-space: pre; - display: flex; - position: relative; - font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; -} - -.code-snippet__wechat ul li { - list-style: none; -} diff --git a/src/assets/less/github-v2.min.css b/src/assets/less/github-v2.min.css deleted file mode 100644 index 3ff324c..0000000 --- a/src/assets/less/github-v2.min.css +++ /dev/null @@ -1,72 +0,0 @@ -/*! Color themes for Google Code Prettify | MIT License | github.com/jmblog/color-themes-for-google-code-prettify */ -.prettyprint { - font-family: Menlo, Bitstream Vera Sans Mono, DejaVu Sans Mono, Monaco, - Consolas, monospace; - border: 0 !important; -} -.pln { - color: #333; -} -ol.linenums { - margin-top: 0; - margin-bottom: 0; - color: #ccc; -} -li.L0, -li.L1, -li.L2, -li.L3, -li.L4, -li.L5, -li.L6, -li.L7, -li.L8, -li.L9 { - padding-left: 1em; - background-color: #fff; - list-style-type: decimal; -} -@media screen { - .str { - color: #183691; - } - .kwd { - color: #a71d5d; - } - .com { - color: #969896; - } - .typ { - color: #0086b3; - } - .lit { - color: #0086b3; - } - .pun { - color: #333; - } - .opn { - color: #333; - } - .clo { - color: #333; - } - .tag { - color: navy; - } - .atn { - color: #795da3; - } - .atv { - color: #183691; - } - .dec { - color: #333; - } - .var { - color: teal; - } - .fun { - color: #900; - } -} diff --git a/src/assets/scripts/config.js b/src/assets/scripts/config.js index ded88d7..f6b794a 100644 --- a/src/assets/scripts/config.js +++ b/src/assets/scripts/config.js @@ -57,14 +57,29 @@ export default { ], codeThemeOption: [ { - label: "微信", - value: "wechat", - desc: "默认样式", + label: "github", + value: "https://lib.baomitu.com/highlight.js/10.7.3/styles/github.min.css", + desc: "light", }, { - label: "GitHub", - value: "github", - desc: "精简风格", + label: "solarized-light", + value: "https://lib.baomitu.com/highlight.js/11.3.1/styles/base16/solarized-light.min.css", + desc: "light", + }, + { + label: "atom-one-dark", + value: "https://lib.baomitu.com/highlight.js/11.3.1/styles/atom-one-dark.min.css", + desc: "dark", + }, + { + label: "obsidian", + value: "https://lib.baomitu.com/highlight.js/11.3.1/styles/obsidian.min.css", + desc: "dark", + }, + { + label: "vs2015", + value: "https://lib.baomitu.com/highlight.js/11.3.1/styles/vs2015.min.css", + desc: "dark", }, ], form: { diff --git a/src/assets/scripts/renderers/wx-renderer.js b/src/assets/scripts/renderers/wx-renderer.js index 46a1bdf..07cb9e0 100644 --- a/src/assets/scripts/renderers/wx-renderer.js +++ b/src/assets/scripts/renderers/wx-renderer.js @@ -1,4 +1,5 @@ import { Renderer } from "marked"; +import hljs from 'highlight.js'; class WxRenderer { constructor(opts) { @@ -7,9 +8,6 @@ class WxRenderer { let footnoteIndex = 0; let styleMapping = new Map(); - const CODE_FONT_FAMILY = - "Menlo, Operator Mono, Consolas, Monaco, monospace"; - let merge = (base, extend) => Object.assign({}, base, extend); this.buildTheme = (themeTpl) => { @@ -25,13 +23,10 @@ class WxRenderer { } } - let base_block = merge(base, {}); + let base_block = merge(base, {}); for (let ele in themeTpl.block) { if (themeTpl.block.hasOwnProperty(ele)) { let style = themeTpl.block[ele]; - if (ele === "code") { - style["font-family"] = CODE_FONT_FAMILY; - } mapping[ele] = merge(base_block, style); } } @@ -126,23 +121,17 @@ class WxRenderer { return `
${text}`; }; renderer.code = (text, lang) => { - text = text.replace(//g, ">"); - const codeLines = text - .split("\n") - .map( - (line) => - `
${
- line || " "
- }
`
- );
- const codeTheme = "github";
- return `
- - ${codeLines.join("")} --
${text}
`
};
renderer.codespan = (text, lang) =>
`${text}
`;
diff --git a/src/assets/scripts/themes/default-theme.js b/src/assets/scripts/themes/default-theme.js
index ccb2266..f42d115 100644
--- a/src/assets/scripts/themes/default-theme.js
+++ b/src/assets/scripts/themes/default-theme.js
@@ -1,11 +1,9 @@
+let baseColor = "#3f3f3f"
+
export default {
BASE: {
"text-align": "left",
- color: "#3f3f3f",
- "line-height": "1.75",
- },
- BASE_BLOCK: {
- margin: "1em 8px",
+ "line-height": "1.75"
},
block: {
// 一级标题样式
@@ -17,6 +15,7 @@ export default {
margin: "2em auto 1em",
padding: "0 1em",
"border-bottom": "2px solid rgba(0, 152, 116, 0.9)",
+ color: baseColor,
},
// 二级标题样式
@@ -39,6 +38,7 @@ export default {
"line-height": "1.2",
"padding-left": "8px",
"border-left": "3px solid rgba(0, 152, 116, 0.9)",
+ color: baseColor,
},
// 四级标题样式
@@ -53,6 +53,7 @@ export default {
p: {
margin: "1.5em 8px",
"letter-spacing": "0.1em",
+ color: baseColor,
},
// 引用样式
@@ -72,20 +73,20 @@ export default {
"font-size": "1em",
display: "block",
},
-
- code: {
- "font-size": "80%",
- overflow: "auto",
- color: "#333",
- "white-space": "pre",
- background: "rgb(247, 247, 247)",
+ code_pre: {
+ "font-size": "14px",
+ "overflow-x": "auto",
"border-radius": "8px",
- padding: "10px",
+ padding: "1em",
"line-height": "1.5",
- border: "1px solid rgb(236,236,236)",
- margin: "20px 0",
+ margin: "10px 8px"
},
-
+ code: {
+ "margin": 0,
+ "white-space": "nowrap",
+ "font-family": "Menlo, Operator Mono, Consolas, Monaco, monospace"
+ },
+
image: {
"border-radius": "4px",
display: "block",
@@ -96,21 +97,25 @@ export default {
ol: {
"margin-left": "0",
"padding-left": "1em",
+ color: baseColor,
},
ul: {
"margin-left": "0",
"padding-left": "1em",
"list-style": "circle",
+ color: baseColor,
},
footnotes: {
margin: "0.5em 8px",
"font-size": "80%",
+ color: baseColor,
},
figure: {
margin: "1.5em 8px",
+ color: baseColor,
},
hr: {
"border-style": "solid",
@@ -127,6 +132,7 @@ export default {
"text-indent": "-1em",
display: "block",
margin: "0.2em 8px",
+ color: baseColor,
},
codespan: {
@@ -157,20 +163,24 @@ export default {
"border-collapse": "collapse",
"text-align": "center",
margin: "1em 8px",
+ color: baseColor,
},
thead: {
background: "rgba(0, 0, 0, 0.05)",
"font-weight": "bold",
+ color: baseColor,
},
td: {
border: "1px solid #dfdfdf",
padding: "0.25em 0.5em",
+ color: baseColor,
},
footnote: {
"font-size": "12px",
+ color: baseColor,
},
figcaption: {
diff --git a/src/assets/scripts/util.js b/src/assets/scripts/util.js
index d8f1754..44b48f8 100644
--- a/src/assets/scripts/util.js
+++ b/src/assets/scripts/util.js
@@ -215,15 +215,6 @@ export function formatCss(content) {
return doc;
}
-export function fixCodeWhiteSpace(value = "pre") {
- const preDomList = document.getElementsByClassName("code__pre");
- if (preDomList.length > 0) {
- preDomList.forEach((pre) => {
- pre.style.whiteSpace = value;
- });
- }
-}
-
/**
* 导出原始 Markdown 文档
* @param {文档内容} doc
@@ -264,7 +255,6 @@ export function exportHTML() {
function setStyles(element) {
switch (true) {
- case isSection(element):
case isPre(element):
case isCode(element):
case isSpan(element):
@@ -275,13 +265,6 @@ export function exportHTML() {
Array.from(element.children).forEach((child) => setStyles(child));
}
- // 判断是否是包裹代码块的 section 元素
- function isSection(element) {
- return (
- element.tagName === "SECTION" &&
- Array.from(element.classList).includes("code-snippet__github")
- );
- }
// 判断是否是包裹代码块的 pre 元素
function isPre(element) {
return (
diff --git a/src/components/CodemirrorEditor/header.vue b/src/components/CodemirrorEditor/header.vue
index 4d7e610..11c1392 100644
--- a/src/components/CodemirrorEditor/header.vue
+++ b/src/components/CodemirrorEditor/header.vue
@@ -109,6 +109,22 @@
{{ color.desc }}
+