mirror of
https://github.com/marktext/marktext.git
synced 2025-05-02 06:29:26 +08:00
feat: add code block line numbers
This commit is contained in:
parent
b4af38b94d
commit
a028a7c2bb
@ -31,6 +31,7 @@ Preferences can be controlled and modified in the settings window or via the `pr
|
||||
| textDirection | String | ltr | The writing text direction, optional value: `ltr` or `rtl` |
|
||||
| codeFontSize | Number | 14 | Font size on code block, the range is 12 ~ 28 |
|
||||
| codeFontFamily | String | `DejaVu Sans Mono` | Code font family |
|
||||
| codeBlockLineNumbers | Boolean | true | Whether to show the line numbers in code block |
|
||||
| trimUnnecessaryCodeBlockEmptyLines | Boolean | true | Whether to trim the beginning and end empty line in Code block |
|
||||
| hideQuickInsertHint | Boolean | false | Hide hint for quickly creating paragraphs |
|
||||
| imageDropAction | String | folder | The default behavior after paste or drag the image to Mark Text, upload it to the image cloud (if configured), move to the specified folder, insert the path |
|
||||
|
@ -94,6 +94,11 @@
|
||||
"type": "string",
|
||||
"pattern": "^[_A-z0-9]+((-|\\s)*[_A-z0-9])*$"
|
||||
},
|
||||
"codeBlockLineNumbers": {
|
||||
"description": "Editor--Whether to show the line numbers",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"trimUnnecessaryCodeBlockEmptyLines": {
|
||||
"description": "Editor--Trim the beginning and ending empty lines in code block",
|
||||
"type": "boolean"
|
||||
|
@ -1107,3 +1107,49 @@ span.ag-reference-link {
|
||||
.vega-embed {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
pre[class*="language-"].line-numbers {
|
||||
position: relative;
|
||||
padding-left: 2.5em;
|
||||
counter-reset: linenumber;
|
||||
}
|
||||
|
||||
pre[class*="language-"].line-numbers > code {
|
||||
position: relative;
|
||||
white-space: inherit;
|
||||
}
|
||||
|
||||
figure:not(.ag-active) pre[class*="language-"].line-numbers {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.line-numbers .line-numbers-rows {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
top: 0;
|
||||
font-size: 100%;
|
||||
left: -2.5em;
|
||||
width: 2.5em; /* works for line-numbers below 1000 lines */
|
||||
letter-spacing: -1px;
|
||||
|
||||
user-select: none;
|
||||
|
||||
}
|
||||
|
||||
.line-numbers-rows > span {
|
||||
pointer-events: none;
|
||||
display: block;
|
||||
counter-increment: linenumber;
|
||||
}
|
||||
|
||||
.line-numbers-rows > span:before {
|
||||
content: counter(linenumber);
|
||||
color: var(--editorColor30);
|
||||
display: block;
|
||||
padding-right: .8em;
|
||||
text-align: right;
|
||||
transform: scale(.8);
|
||||
position: relative;
|
||||
top: .05em;
|
||||
}
|
||||
|
||||
|
@ -254,6 +254,7 @@ export const MUYA_DEFAULT_OPTION = {
|
||||
bulletListMarker: '-',
|
||||
orderListDelimiter: '.',
|
||||
tabSize: 4,
|
||||
codeBlockLineNumbers: true,
|
||||
// bullet/list marker width + listIndentation, tab or Daring Fireball Markdown (4 spaces) --> list indentation
|
||||
listIndentation: 1,
|
||||
frontmatterType: '-',
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { CLASS_OR_ID } from '../../../config'
|
||||
import { renderTableTools } from './renderToolBar'
|
||||
import { renderEditIcon } from './renderContainerEditIcon'
|
||||
import renderLineNumberRows from './renderLineNumber'
|
||||
import { renderLeftBar, renderBottomBar } from './renderTableDargBar'
|
||||
import { h } from '../snabbdom'
|
||||
|
||||
@ -45,8 +46,17 @@ export default function renderContainerBlock (parent, block, activeBlocks, match
|
||||
})
|
||||
}
|
||||
|
||||
if (/code|pre/.test(type) && typeof lang === 'string' && !!lang) {
|
||||
selector += `.language-${lang.replace(/[#.]{1}/g, '')}`
|
||||
if (/code|pre/.test(type)) {
|
||||
if (typeof lang === 'string' && !!lang) {
|
||||
selector += `.language-${lang.replace(/[#.]{1}/g, '')}`
|
||||
}
|
||||
if (this.muya.options.codeBlockLineNumbers) {
|
||||
if (type === 'pre') {
|
||||
selector += '.line-numbers'
|
||||
} else {
|
||||
children.unshift(renderLineNumberRows(block.children[0]))
|
||||
}
|
||||
}
|
||||
Object.assign(data.attrs, { spellcheck: 'false' })
|
||||
}
|
||||
|
||||
|
22
src/muya/lib/parser/render/renderBlock/renderLineNumber.js
Normal file
22
src/muya/lib/parser/render/renderBlock/renderLineNumber.js
Normal file
@ -0,0 +1,22 @@
|
||||
import { h } from '../snabbdom'
|
||||
|
||||
const NEW_LINE_EXP = /\n(?!$)/g
|
||||
|
||||
const renderLineNumberRows = codeContent => {
|
||||
const { text } = codeContent
|
||||
const match = text.match(NEW_LINE_EXP)
|
||||
let linesNum = match ? match.length + 1 : 1
|
||||
if (text.endsWith('\n')) {
|
||||
linesNum++
|
||||
}
|
||||
const data = {
|
||||
attrs: {
|
||||
'aria-hidden': true
|
||||
}
|
||||
}
|
||||
const children = [...new Array(linesNum)].map(() => h('span'))
|
||||
|
||||
return h('span.line-numbers-rows', data, children)
|
||||
}
|
||||
|
||||
export default renderLineNumberRows
|
@ -140,6 +140,7 @@ export default {
|
||||
fontSize: state => state.preferences.fontSize,
|
||||
codeFontSize: state => state.preferences.codeFontSize,
|
||||
codeFontFamily: state => state.preferences.codeFontFamily,
|
||||
codeBlockLineNumbers: state => state.preferences.codeBlockLineNumbers,
|
||||
trimUnnecessaryCodeBlockEmptyLines: state => state.preferences.trimUnnecessaryCodeBlockEmptyLines,
|
||||
editorFontFamily: state => state.preferences.editorFontFamily,
|
||||
hideQuickInsertHint: state => state.preferences.hideQuickInsertHint,
|
||||
@ -312,6 +313,12 @@ export default {
|
||||
})
|
||||
}
|
||||
},
|
||||
codeBlockLineNumbers: function (value, oldValue) {
|
||||
const { editor } = this
|
||||
if (value !== oldValue && editor) {
|
||||
editor.setOptions({ codeBlockLineNumbers: value }, true)
|
||||
}
|
||||
},
|
||||
codeFontFamily: function (value, oldValue) {
|
||||
if (value !== oldValue) {
|
||||
addCommonStyle({
|
||||
@ -443,6 +450,7 @@ export default {
|
||||
tabSize,
|
||||
fontSize,
|
||||
lineHeight,
|
||||
codeBlockLineNumbers,
|
||||
listIndentation,
|
||||
frontmatterType,
|
||||
superSubScript,
|
||||
@ -485,6 +493,7 @@ export default {
|
||||
tabSize,
|
||||
fontSize,
|
||||
lineHeight,
|
||||
codeBlockLineNumbers,
|
||||
listIndentation,
|
||||
frontmatterType,
|
||||
superSubScript,
|
||||
|
@ -39,6 +39,11 @@
|
||||
:value="codeFontFamily"
|
||||
:onChange="value => onSelectChange('codeFontFamily', value)"
|
||||
></font-text-box>
|
||||
<bool
|
||||
description="Whether to show the code block line numbers."
|
||||
:bool="codeBlockLineNumbers"
|
||||
:onChange="value => onSelectChange('codeBlockLineNumbers', value)"
|
||||
></bool>
|
||||
<bool
|
||||
description="Trim the beginning and ending empty lines in code block when open markdown."
|
||||
:bool="trimUnnecessaryCodeBlockEmptyLines"
|
||||
@ -148,6 +153,7 @@ export default {
|
||||
textDirection: state => state.preferences.textDirection,
|
||||
codeFontSize: state => state.preferences.codeFontSize,
|
||||
codeFontFamily: state => state.preferences.codeFontFamily,
|
||||
codeBlockLineNumbers: state => state.preferences.codeBlockLineNumbers,
|
||||
trimUnnecessaryCodeBlockEmptyLines: state => state.preferences.trimUnnecessaryCodeBlockEmptyLines,
|
||||
hideQuickInsertHint: state => state.preferences.hideQuickInsertHint,
|
||||
hideLinkPopup: state => state.preferences.hideLinkPopup,
|
||||
|
@ -19,6 +19,7 @@ const state = {
|
||||
lineHeight: 1.6,
|
||||
codeFontSize: 14,
|
||||
codeFontFamily: 'DejaVu Sans Mono',
|
||||
codeBlockLineNumbers: true,
|
||||
trimUnnecessaryCodeBlockEmptyLines: true,
|
||||
editorLineWidth: '',
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
"lineHeight": 1.6,
|
||||
"codeFontSize": 14,
|
||||
"codeFontFamily": "DejaVu Sans Mono",
|
||||
"codeBlockLineNumbers": true,
|
||||
"trimUnnecessaryCodeBlockEmptyLines": true,
|
||||
"editorLineWidth": "",
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user