Add highlight and line number for the code block #518
-
Is it possible to add custom engine for const { Marp } = require('@marp-team/marp-core')
const { Marpit } = require('@marp-team/marpit')
const highlightLines = require('markdown-it-highlight-lines')
const marpit = new Marpit()
module.exports = (opts) => new Marp(opts)
.use(highlightLines)
.use(({ marpit }) => {
const { highlighter } = marpit
marpit.highlighter = function (...args) {
const original = highlighter.apply(this, args)
const listItems = original
.split(/\n(?!$)/) // Don't split at the trailing newline
.map(
(line) =>
`<li><span data-marp-line-number></span><span>${line}</span></li>`
)
return `<ol>${listItems.join('')}</ol>`
}
}) |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
The Instead, you have to implement the logic of line highlights by your own. Fortunately that is not that difficult. // engine.js
module.exports = ({ marp }) =>
marp.use(({ marpit }) => {
const { highlighter } = marpit
marpit.highlighter = function (code, lang, attrs) {
const original = highlighter.call(this, code, lang, attrs)
// Parse code highlight
const matched = attrs.toString().match(/{([\d,-]+)}/)
const lineNumbers = matched?.[1]
.split(',')
.map((v) => v.split('-').map((v) => parseInt(v, 10)))
// Apply line numbers
const listItems = original
.split(/\n(?!$)/) // Don't split at the trailing newline
.map((line, index) => {
const lineNum = index + 1
const highlighted = lineNumbers?.find(([start, end]) => {
if (end != null && start <= lineNum && lineNum <= end) return true
return start === lineNum
})
return `<li${
highlighted ? ' class="highlighted-line"' : ''
}><span data-marp-line-number></span><span>${line}</span></li>`
})
return `<ol>${listItems.join('')}</ol>`
}
}) /**
* Custom theme
*
* @theme your-custom-theme
* @auto-scaling false
*/
@import 'default';
pre ol {
all: unset;
display: grid;
grid-template-columns: auto 1fr;
counter-reset: line-number 0;
}
pre ol li {
display: contents;
}
pre ol li span[data-marp-line-number]::before {
display: block;
content: counter(line-number) ': ';
counter-increment: line-number;
text-align: right;
}
pre .highlighted-line > * {
background-color: #ff6;
} To get the full-width line highlights, it's important disabling Marp Core's auto-scaling feature for the code block by Examplemarp --engine engine.js --theme custom-theme.css markdown.md ```js {4-8}
marpit.highlighter = function (code, lang, attrs) {
const original = highlighter.call(this, code, lang, attrs)
// Parse code highlight
const matched = attrs.toString().match(/{([\d,-]+)}/)
const lineNumbers = matched?.[1]
.split(',')
.map((v) => v.split('-').map((v) => parseInt(v, 10)))
// Apply line numbers
// ...
}
``` |
Beta Was this translation helpful? Give feedback.
-
It works! Thank you very much! |
Beta Was this translation helpful? Give feedback.
The
markdown-it-highlight-lines
markdown-it plugin seems to target the code block for the general Markdown document. If the rendering of code blocks is customized by Marp (Marpit) plugins to render the list items instead of plain codes, that plugin would become incompatible.Instead, you have to implement the logic of line highlights by your own. Fortunately that is not that difficult.