diff --git a/docs/config/README.md b/docs/config/README.md index 2c4cd8370b..9582d02e2b 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -127,6 +127,13 @@ Provide config options to the used theme. The options will vary depending on the ## Markdown +### markdown.lineNumbers + +- Type: `boolean` +- Default: `undefined` + +Whether to show line numbers to the left of each code blocks. + ### markdown.slugify - Type: `Function` diff --git a/docs/zh/config/README.md b/docs/zh/config/README.md index 1cde934b7d..2bd994f758 100644 --- a/docs/zh/config/README.md +++ b/docs/zh/config/README.md @@ -126,6 +126,13 @@ module.exports = { ## Markdown +### markdown.lineNumbers + +- 类型: `boolean` +- 默认值: `undefined` + +是否在每个代码块的左侧显示行号。 + ### markdown.anchor - 类型: `Object` diff --git a/lib/default-theme/styles/code.styl b/lib/default-theme/styles/code.styl index 54cced7e3e..3c6c3fb45c 100644 --- a/lib/default-theme/styles/code.styl +++ b/lib/default-theme/styles/code.styl @@ -30,7 +30,8 @@ div[class*="language-"] user-select none padding-top 1.3rem position absolute - z-index 0 + top 0 + left 0 width 100% line-height 1.4 .highlighted @@ -45,61 +46,106 @@ div[class*="language-"] right 1em font-size 0.75rem color rgba(255, 255, 255, 0.4) - -div[class="language-js"], div[class="language-javascript"] + &:not(.line-numbers-mode) + .line-numbers-wrapper + display none + &.line-numbers-mode + .highlight-lines .highlighted + position relative + &:before + content ' ' + position absolute + z-index 3 + left 0 + top 0 + display block + width $lineNumbersWrapperWidth + height 100% + background-color rgba(0, 0, 0, 66%) + pre + padding-left $lineNumbersWrapperWidth + 1 rem + vertical-align middle + .line-numbers-wrapper + position absolute + top 0 + width $lineNumbersWrapperWidth + text-align center + color rgba(255, 255, 255, 0.3) + padding 1.25rem 0 + line-height 1.4 + br + user-select none + .line-number + position relative + z-index 4 + user-select none + font-size 0.85em + &::after + content '' + position absolute + z-index 2 + top 0 + left 0 + width $lineNumbersWrapperWidth + height 100% + border-radius 6px 0 0 6px + border-right 1px solid rgba(0, 0, 0, 66%) + background-color $codeBgColor + +div[class*="language-js"], div[class*="language-javascript"] &:before content "js" -div[class="language-ts"], div[class="language-typescript"] +div[class*="language-ts"], div[class*="language-typescript"] &:before content "ts" -div[class="language-html"], div[class="language-markup"] +div[class*="language-html"], div[class*="language-markup"] &:before content "html" -div[class="language-markdown"], div[class="language-md"] +div[class*="language-markdown"], div[class*="language-md"] &:before content "md" -div[class="language-vue"]:before +div[class*="language-vue"]:before content "vue" -div[class="language-css"]:before +div[class*="language-css"]:before content "css" -div[class="language-sass"]:before +div[class*="language-sass"]:before content "sass" -div[class="language-less"]:before +div[class*="language-less"]:before content "less" -div[class="language-scss"]:before +div[class*="language-scss"]:before content "scss" -div[class="language-stylus"]:before +div[class*="language-stylus"]:before content "stylus" -div[class="language-json"]:before +div[class*="language-json"]:before content "json" -div[class="language-ruby"]:before +div[class*="language-ruby"]:before content "rb" -div[class="language-python"]:before +div[class*="language-python"]:before content "py" -div[class="language-go"]:before +div[class*="language-go"]:before content "go" -div[class="language-java"]:before +div[class*="language-java"]:before content "java" -div[class="language-c"]:before +div[class*="language-c"]:before content "c" -div[class="language-bash"]:before +div[class*="language-bash"]:before content "sh" -div[class="language-yaml"]:before +div[class*="language-yaml"]:before content "yaml" diff --git a/lib/default-theme/styles/config.styl b/lib/default-theme/styles/config.styl index 158de9024f..385551e054 100644 --- a/lib/default-theme/styles/config.styl +++ b/lib/default-theme/styles/config.styl @@ -15,4 +15,7 @@ $MQNarrow = 959px $MQMobile = 719px $MQMobileNarrow = 419px +// code +$lineNumbersWrapperWidth = 3.5rem + @import '~@temp/override.styl' // generated from user config diff --git a/lib/default-theme/styles/theme.styl b/lib/default-theme/styles/theme.styl index cefae34472..1c62ec8ec3 100644 --- a/lib/default-theme/styles/theme.styl +++ b/lib/default-theme/styles/theme.styl @@ -138,7 +138,7 @@ a.header-anchor &:hover text-decoration none -code, kbd +code, kbd, .line-number font-family source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace p, ul, ol diff --git a/lib/markdown/index.js b/lib/markdown/index.js index 5ea8fef1f0..29c994039b 100644 --- a/lib/markdown/index.js +++ b/lib/markdown/index.js @@ -1,6 +1,7 @@ const highlight = require('./highlight') const highlightLines = require('./highlightLines') const preWrapper = require('./preWrapper') +const lineNumbers = require('./lineNumbers') const component = require('./component') const hoistScriptStyle = require('./hoist') const convertRouterLink = require('./link') @@ -49,6 +50,10 @@ module.exports = ({ markdown = {}} = {}) => { markdown.config(md) } + if (markdown.lineNumbers) { + md.use(lineNumbers) + } + // override render to allow custom plugins return data const render = md.render md.render = (...args) => { diff --git a/lib/markdown/lineNumbers.js b/lib/markdown/lineNumbers.js new file mode 100644 index 0000000000..bc95d2b064 --- /dev/null +++ b/lib/markdown/lineNumbers.js @@ -0,0 +1,26 @@ +// markdown-it plugin for generating line numbers. +// It depends on preWrapper plugin. + +module.exports = md => { + const fence = md.renderer.rules.fence + md.renderer.rules.fence = (...args) => { + const rawCode = fence(...args) + const code = rawCode.slice( + rawCode.indexOf(''), + rawCode.indexOf('') + ) + + const lines = code.split('\n') + const lineNumbersCode = [...Array(lines.length - 1)] + .map((line, index) => `${index + 1}
`).join('') + + const lineNumbersWrapperCode = + `
${lineNumbersCode}
` + + const finalCode = rawCode + .replace('', `${lineNumbersWrapperCode}`) + .replace('extra-class', 'line-numbers-mode') + + return finalCode + } +} diff --git a/lib/markdown/preWrapper.js b/lib/markdown/preWrapper.js index 1ade38753a..8f1b1d7396 100644 --- a/lib/markdown/preWrapper.js +++ b/lib/markdown/preWrapper.js @@ -13,7 +13,7 @@ module.exports = md => { const [tokens, idx] = args const token = tokens[idx] const rawCode = fence(...args) - return `
` + + return `
` + `${rawCode}
` } }