Skip to content

Commit

Permalink
feat(CodeBlock): add line number attribute to code block lines (#1973)
Browse files Browse the repository at this point in the history
  • Loading branch information
nobkd committed Apr 12, 2023
1 parent 1823c0d commit 7bb8b10
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 3 deletions.
2 changes: 2 additions & 0 deletions docs/content/3.guide/1.writing/2.markdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ Nuxt Content uses [Shiki](https://github.com/shikijs/shiki), that colors tokens

Code highlighting works both on [`ProseCode`](/api/components/prose#prosecode) and [`ProseCodeInline`](/api/components/prose#prosecodeinline).

Each line of a code block gets its line number in the `line` attribute so lines can be labeled or individually styled.

::alert{type="info"}
[Read the API reference to configure or entirely disable syntax highlighting.](/api/configuration#highlight)
::
Expand Down
14 changes: 11 additions & 3 deletions src/runtime/transformers/shiki/highlighter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ export const useShikiHighlighter = createSingleton((opts?: Exclude<ModuleOptions
return promise
}

const splitCodeToLines = (code: string) => {
const lines = code.split(/\r\n|\r|\n/)
return [...lines.map((line: string) => [{ content: line }])]
}

const getHighlightedTokens = async (code: string, lang: Lang, theme: Theme) => {
const highlighter = await getShikiHighlighter()
// Remove trailing carriage returns
Expand All @@ -90,7 +95,7 @@ export const useShikiHighlighter = createSingleton((opts?: Exclude<ModuleOptions

// Skip highlight if lang is not supported
if (!lang) {
return [[{ content: code }]]
return splitCodeToLines(code)
}

// Load supported language on-demand
Expand All @@ -101,7 +106,7 @@ export const useShikiHighlighter = createSingleton((opts?: Exclude<ModuleOptions
await highlighter.loadLanguage(languageRegistration)
} else {
logger.warn(`Language '${lang}' is not supported by shiki. Skipping highlight.`)
return [[{ content: code }]]
return splitCodeToLines(code)
}
}

Expand Down Expand Up @@ -144,7 +149,10 @@ export const useShikiHighlighter = createSingleton((opts?: Exclude<ModuleOptions
return lines.map((line, lineIndex) => ({
type: 'element',
tag: 'div',
props: { class: ['line', highlights.includes(lineIndex + 1) ? 'highlight' : ''].join(' ').trim() },
props: {
class: ['line', highlights.includes(lineIndex + 1) ? 'highlight' : ''].join(' ').trim(),
line: lineIndex + 1
},
children: line.map(tokenSpan)
}))

Expand Down

0 comments on commit 7bb8b10

Please sign in to comment.