Skip to content

Commit 2bc6ab0

Browse files
committed
feat: highlighter markdown mark
1 parent 2fe0ad5 commit 2bc6ab0

File tree

3 files changed

+35
-16
lines changed

3 files changed

+35
-16
lines changed

demo/slides.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
layout: cover
33
download: 'https://antfu.me/talks/2021-04-29'
4-
# highlighter: shiki
4+
highlighter: shiki
55
---
66

77
# Composable Vue
@@ -140,9 +140,7 @@ bar = 1 // ts-error
140140

141141
# Reactive
142142

143-
<CodeHighlightController :ranges="['1,6', '2,7']">
144-
145-
```ts
143+
```ts {1,6|3,7}
146144
import { reactive } from 'vue'
147145

148146
const foo = { prop: 0 }
@@ -152,8 +150,6 @@ foo.prop = 1
152150
bar.prop = 1
153151
```
154152

155-
</CodeHighlightController>
156-
157153
<div v-click>
158154

159155
### Pros

packages/client/builtin/CodeHighlightController.vue

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,11 @@ function makeid(length = 5) {
2626
}
2727
2828
const prev = elements.value.length
29-
const index = computed(() => Math.min(Math.max(0, clicks.value - prev), props.ranges.length - 1))
29+
const index = computed(() => {
30+
if (disabled.value)
31+
return props.ranges.length - 1
32+
return Math.min(Math.max(0, clicks.value - prev), props.ranges.length - 1)
33+
})
3034
const rangeStr = computed(() => props.ranges[index.value] || '')
3135
if (props.ranges.length >= 2 && !disabled.value) {
3236
const id = makeid()
@@ -43,12 +47,16 @@ onMounted(() => {
4347
watchEffect(() => {
4448
if (!el.value)
4549
return
46-
const lines = Array.from(el.value.querySelectorAll('.line'))
47-
const hightlights: number[] = parseRangeString(lines.length, rangeStr.value)
48-
// console.log(hightlights, rangeStr.value)
49-
lines.forEach((line, idx) => {
50-
line.classList.toggle('opacity-30', !hightlights.includes(idx))
51-
})
50+
const duoTone = el.value.querySelector('.shiki-dark')
51+
const targets = duoTone ? Array.from(el.value.querySelectorAll('.shiki')) : [el.value]
52+
for (const target of targets) {
53+
const lines = Array.from(target.querySelectorAll('.line'))
54+
const hightlights: number[] = parseRangeString(lines.length, rangeStr.value)
55+
// console.log(hightlights, rangeStr.value)
56+
lines.forEach((line, idx) => {
57+
line.classList.toggle('opacity-30', !hightlights.includes(idx))
58+
})
59+
}
5260
})
5361
})
5462
</script>

packages/slidev/node/plugins/markdown.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,16 @@ export async function createMarkdownPlugin(
5656
setups.forEach(i => i(md))
5757
},
5858
transforms: {
59-
before: (config.monaco === true || config.monaco === mode)
60-
? transformMarkdownMonaco
61-
: truncateMancoMark,
59+
before(code) {
60+
const monaco = (config.monaco === true || config.monaco === mode)
61+
? transformMarkdownMonaco
62+
: truncateMancoMark
63+
64+
code = monaco(code)
65+
code = transformHighlighter(code)
66+
67+
return code
68+
},
6269
},
6370
...mdOptions,
6471
})
@@ -91,3 +98,11 @@ export function transformMarkdownMonaco(md: string) {
9198
export function truncateMancoMark(code: string) {
9299
return code.replace(/{monaco.*?}/g, '')
93100
}
101+
102+
export function transformHighlighter(md: string) {
103+
// transform monaco
104+
return md.replace(/\n```(\w+?)\s*{([\w,\|-]+)}[\s\n]*([\s\S]+?)\n```/mg, (full, lang = '', rangeStr: string, code: string) => {
105+
const ranges = rangeStr.split('|').map(i => i.trim())
106+
return `<CodeHighlightController :ranges='${JSON.stringify(ranges)}'>\n\n\`\`\`${lang}\n${code}\n\`\`\`\n\n</CodeHighlightController>`
107+
})
108+
}

0 commit comments

Comments
 (0)