Skip to content

Commit

Permalink
feat: code line numbers (close: #365) (#379)
Browse files Browse the repository at this point in the history
  • Loading branch information
ulivz authored May 13, 2018
1 parent c4424c8 commit 9b42690
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 22 deletions.
7 changes: 7 additions & 0 deletions docs/config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
7 changes: 7 additions & 0 deletions docs/zh/config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,13 @@ module.exports = {

## Markdown

### markdown.lineNumbers

- 类型: `boolean`
- 默认值: `undefined`

是否在每个代码块的左侧显示行号。

### markdown.anchor

- 类型: `Object`
Expand Down
86 changes: 66 additions & 20 deletions lib/default-theme/styles/code.styl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"
3 changes: 3 additions & 0 deletions lib/default-theme/styles/config.styl
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ $MQNarrow = 959px
$MQMobile = 719px
$MQMobileNarrow = 419px

// code
$lineNumbersWrapperWidth = 3.5rem

@import '~@temp/override.styl' // generated from user config
2 changes: 1 addition & 1 deletion lib/default-theme/styles/theme.styl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions lib/markdown/index.js
Original file line number Diff line number Diff line change
@@ -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')
Expand Down Expand Up @@ -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) => {
Expand Down
26 changes: 26 additions & 0 deletions lib/markdown/lineNumbers.js
Original file line number Diff line number Diff line change
@@ -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('<code>'),
rawCode.indexOf('</code>')
)

const lines = code.split('\n')
const lineNumbersCode = [...Array(lines.length - 1)]
.map((line, index) => `<span class="line-number">${index + 1}</span><br>`).join('')

const lineNumbersWrapperCode =
`<div class="line-numbers-wrapper">${lineNumbersCode}</div>`

const finalCode = rawCode
.replace('<!--beforeend-->', `${lineNumbersWrapperCode}<!--beforeend-->`)
.replace('extra-class', 'line-numbers-mode')

return finalCode
}
}
2 changes: 1 addition & 1 deletion lib/markdown/preWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module.exports = md => {
const [tokens, idx] = args
const token = tokens[idx]
const rawCode = fence(...args)
return `<!--beforebegin--><div class="language-${token.info.trim()}">` +
return `<!--beforebegin--><div class="language-${token.info.trim()} extra-class">` +
`<!--afterbegin-->${rawCode}<!--beforeend--></div><!--afterend-->`
}
}

0 comments on commit 9b42690

Please sign in to comment.