Skip to content

Commit d2a5b96

Browse files
committed
fix: don't transform <style> inside code block, close #101
1 parent 0fba680 commit d2a5b96

File tree

5 files changed

+56
-306
lines changed

5 files changed

+56
-306
lines changed

demo/test/package.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"private": true,
3+
"scripts": {
4+
"dev": "nodemon -w '../../packages/slidev/dist/*.js' --exec 'slidev --log=info'",
5+
"build": "slidev build",
6+
"export": "slidev export"
7+
},
8+
"devDependencies": {
9+
"@slidev/cli": "workspace:*",
10+
"@slidev/theme-default": "^0.7.3",
11+
"@slidev/theme-seriph": "^0.7.0",
12+
"@slidev/types": "workspace:*",
13+
"nodemon": "^2.0.7"
14+
}
15+
}

demo/test/slides.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../packages/create-app/template/slides.md
Lines changed: 15 additions & 305 deletions
Original file line numberDiff line numberDiff line change
@@ -1,323 +1,33 @@
1-
---
2-
# try also 'default' to start simple
3-
theme: seriph
4-
# random image from a curated Unsplash collection by Anthony
5-
# like them? see https://unsplash.com/collections/94734566/slidev
6-
background: https://source.unsplash.com/collection/94734566/1920x1080
7-
# apply any windi css classes to the current slide
8-
class: 'text-center'
9-
# https://sli.dev/custom/highlighters.html
10-
highlighter: shiki
11-
# some information about the slides, markdown enabled
12-
info: |
13-
## Slidev Starter Template
14-
Presentation slides for developers.
15-
16-
Learn more at [Sli.dev](https://sli.dev)
17-
---
18-
19-
# Welcome to Slidev
20-
21-
Presentation slides for developers
1+
# Page 1
222

23-
<div class="pt-12">
24-
<span @click="$slidev.nav.next" class="px-2 p-1 rounded cursor-pointer" hover="bg-white bg-opacity-10">
25-
Press Space for next page <carbon:arrow-right class="inline"/>
26-
</span>
27-
</div>
28-
29-
<a href="https://github.com/slidevjs/slidev" target="_blank" alt="GitHub"
30-
class="abs-br m-6 text-xl icon-btn opacity-50 !border-none !hover:text-white">
31-
<carbon-logo-github />
32-
</a>
33-
34-
<!--
35-
The last comment block of each slide will be treated as slide notes. It will be visible and editable in Presenter Mode along with the slide. [Read more in the docs](https://sli.dev/guide/syntax.html#notes)
36-
-->
3+
Hello World
374

385
---
396

40-
# What is Slidev?
41-
42-
Slidev is a slides maker and presenter designed for developers, consist of the following features
43-
44-
- 📝 **Text-based** - focus on the content with Markdown, and then style them later
45-
- 🎨 **Themable** - theme can be shared and used with npm packages
46-
- 🧑‍💻 **Developer Friendly** - code highlighting, live coding with autocompletion
47-
- 🤹 **Interactive** - embedding Vue components to enhance your expressions
48-
- 🎥 **Recording** - built-in recording and camera view
49-
- 📤 **Portable** - export into PDF, PNGs, or even a hostable SPA
50-
- 🛠 **Hackable** - anything possible on a webpage
51-
52-
<br>
53-
<br>
54-
55-
Read more about [Why Slidev?](https://sli.dev/guide/why)
56-
57-
<!--
58-
You can have `style` tag in markdown to override the style for the current page.
59-
Learn more: https://sli.dev/guide/syntax#embedded-styles
60-
-->
7+
# Page 2
618

9+
```html
6210
<style>
63-
h1 {
64-
background-color: #2B90B6;
65-
background-image: linear-gradient(45deg, #4EC5D4 10%, #146b8c 20%);
66-
background-size: 100%;
67-
-webkit-background-clip: text;
68-
-moz-background-clip: text;
69-
-webkit-text-fill-color: transparent;
70-
-moz-text-fill-color: transparent;
11+
p {
12+
color: red;
7113
}
7214
</style>
73-
74-
75-
---
76-
77-
# Navigation
78-
79-
Hover on the bottom-left corner to see the navigation's controls panel, [learn more](https://sli.dev/guide/navigation.html)
80-
81-
### Keyboard Shortcuts
82-
83-
| | |
84-
| --- | --- |
85-
| <kbd>right</kbd> / <kbd>space</kbd>| next animation or slide |
86-
| <kbd>left</kbd> | previous animation or slide |
87-
| <kbd>up</kbd> | previous slide |
88-
| <kbd>down</kbd> | next slide |
89-
90-
<img
91-
v-click
92-
class="absolute -bottom-9 -left-7 w-80 opacity-50"
93-
src="https://sli.dev/assets/arrow-bottom-left.svg"
94-
/>
95-
<p v-after class="absolute bottom-23 left-45 opacity-30 transform -rotate-10">Here!</p>
96-
97-
98-
---
99-
layout: image-right
100-
image: https://source.unsplash.com/collection/94734566/1920x1080
101-
---
102-
103-
# Code
104-
105-
Use code snippets and get the highlighting directly!
106-
107-
```ts {all|2|1-6|9|all}
108-
interface User {
109-
id: number
110-
firstName: string
111-
lastName: string
112-
role: string
113-
}
114-
115-
function updateUser(id: number, update: Partial<User>) {
116-
const user = getUser(id)
117-
const newUser = {...user, ...update}
118-
saveUser(id, newUser)
119-
}
120-
```
121-
122-
---
123-
124-
# Components
125-
126-
<div grid="~ cols-2 gap-4">
127-
<div>
128-
129-
You can use Vue components directly inside your slides.
130-
131-
We have provided a few built-in components like `<Tweet/>` and `<Youtube/>` that you can use directly use. And add your custom components are also super easy.
132-
133-
```html
134-
<Counter :count="10" />
135-
```
136-
137-
<!-- ./components/Counter.vue -->
138-
<Counter :count="10" m="t-4" />
139-
140-
Check out [the guides](https://sli.dev/custom/#components) for more.
141-
142-
</div>
143-
<div>
144-
145-
```html
146-
<Tweet id="1390115482657726468" />
14715
```
14816

149-
<Tweet id="1390115482657726468" scale="0.65" />
150-
151-
</div>
152-
</div>
153-
154-
155-
---
156-
class: px-20
157-
---
158-
159-
# Themes
160-
161-
Slidev comes with powerful theming support. Themes are able to provide styles, layouts, components, or even configurations for tools. Switching between themes by just **one edit** in your frontmatter:
162-
163-
<div grid="~ cols-2 gap-2" m="-t-2">
17+
`<p>` should have a green border, but no red text
16418

165-
```yaml
166-
---
167-
theme: default
168-
---
169-
```
170-
171-
```yaml
172-
---
173-
theme: seriph
174-
---
175-
```
176-
177-
<img border="rounded" src="https://github.com/slidevjs/themes/blob/main/screenshots/theme-default/01.png?raw=true">
178-
179-
<img border="rounded" src="https://github.com/slidevjs/themes/blob/main/screenshots/theme-seriph/01.png?raw=true">
180-
181-
</div>
182-
183-
Read more about [How to use a theme](https://sli.dev/themes/use.html) and
184-
check out the [Awesome Themes Gallery](https://sli.dev/themes/gallery.html).
185-
186-
---
187-
preload: false
188-
---
189-
190-
# Animations
191-
192-
Animations are powered by [@vueuse/motion](https://motion.vueuse.org/).
193-
194-
```html
195-
<div
196-
v-motion
197-
:initial="{ x: -80 }"
198-
:enter="{ x: 0 }">
199-
Slidev
200-
</div>
201-
```
202-
203-
<div class="w-60 relative mt-6">
204-
<div class="relative w-40 h-40">
205-
<img
206-
v-motion
207-
:initial="{ x: 800, y: -100, scale: 1.5, rotate: -50 }"
208-
:enter="final"
209-
class="absolute top-0 left-0 right-0 bottom-0"
210-
src="https://sli.dev/logo-square.png"
211-
/>
212-
<img
213-
v-motion
214-
:initial="{ y: 500, x: -100, scale: 2 }"
215-
:enter="final"
216-
class="absolute top-0 left-0 right-0 bottom-0"
217-
src="https://sli.dev/logo-circle.png"
218-
/>
219-
<img
220-
v-motion
221-
:initial="{ x: 600, y: 400, scale: 2, rotate: 100 }"
222-
:enter="final"
223-
class="absolute top-0 left-0 right-0 bottom-0"
224-
src="https://sli.dev/logo-triangle.png"
225-
/>
226-
</div>
227-
228-
<div
229-
class="text-5xl absolute top-14 left-40 text-[#2B90B6] -z-1"
230-
v-motion
231-
:initial="{ x: -80, opacity: 0}"
232-
:enter="{ x: 0, opacity: 1, transition: { delay: 2000, duration: 1000 } }">
233-
Slidev
234-
</div>
235-
</div>
236-
237-
<!-- vue script setup scripts can be directly used in markdown, and will only affects current page -->
238-
<script setup lang="ts">
239-
const final = {
240-
x: 0,
241-
y: 0,
242-
rotate: 0,
243-
scale: 1,
244-
transition: {
245-
type: 'spring',
246-
damping: 10,
247-
stiffness: 20,
248-
mass: 2
249-
}
19+
<style>
20+
p {
21+
border: 1px solid green;
25022
}
251-
</script>
252-
253-
<div
254-
v-motion
255-
:initial="{ x:35, y: 40, opacity: 0}"
256-
:enter="{ y: 0, opacity: 1, transition: { delay: 3500 } }">
257-
258-
[Learn More](https://sli.dev/guide/animations.html#motion)
259-
260-
</div>
261-
262-
---
263-
264-
# LaTeX
265-
266-
LaTeX is supported out-of-box powered by [KaTeX](https://katex.org/).
267-
268-
<br>
269-
270-
Inline $\sqrt{3x-1}+(1+x)^2$
271-
272-
Block
273-
$$
274-
\begin{array}{c}
275-
276-
\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} &
277-
= \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \\
278-
279-
\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \\
280-
281-
\nabla \cdot \vec{\mathbf{B}} & = 0
282-
283-
\end{array}
284-
$$
285-
286-
<br>
287-
288-
[Learn more](https://sli.dev/guide/syntax#latex)
23+
</style>
28924

29025
---
29126

292-
# Diagrams
27+
# Page 3
29328

294-
You can create diagrams / graphs from textual descriptions, directly in your Markdown.
295-
296-
<div class="grid grid-cols-2 gap-4 pt-4 -mb-6">
297-
298-
```mermaid {scale: 0.9}
299-
sequenceDiagram
300-
Alice->John: Hello John, how are you?
301-
Note over Alice,John: A typical interaction
302-
```
303-
304-
```mermaid {theme: 'neutral', scale: 0.8}
305-
graph TD
306-
B[Text] --> C{Decision}
307-
C -->|One| D[Result 1]
308-
C -->|Two| E[Result 2]
29+
```html
30+
<div>{{$slidev.nav.currentPage}}</div>
30931
```
31032

311-
</div>
312-
313-
[Learn More](https://sli.dev/guide/syntax.html#diagrams)
314-
315-
316-
---
317-
layout: center
318-
class: text-center
319-
---
320-
321-
# Learn More
322-
323-
[Documentations](https://sli.dev) / [GitHub Repo](https://github.com/slidevjs/slidev)
33+
Current Page: {{$slidev.nav.currentPage}}

packages/slidev/node/plugins/markdown.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export function truncateMancoMark(code: string) {
101101
* Transform Monaco code block to component
102102
*/
103103
export function transformHighlighter(md: string) {
104-
return md.replace(/\n```(\w+?)\s*{([\d\w*,\|-]+)}[\s\n]*([\s\S]+?)\n```/mg, (full, lang = '', rangeStr: string, code: string) => {
104+
return md.replace(/^```(\w+?)\s*{([\d\w*,\|-]+)}[\s\n]*([\s\S]+?)^```/mg, (full, lang = '', rangeStr: string, code: string) => {
105105
const ranges = rangeStr.split(/\|/g).map(i => i.trim())
106106
return `\n<CodeHighlightController :ranges='${JSON.stringify(ranges)}'>\n\n\`\`\`${lang}\n${code}\n\`\`\`\n\n</CodeHighlightController>`
107107
})
@@ -115,9 +115,16 @@ export function transformPageCSS(md: string, id: string) {
115115
if (!page)
116116
return md
117117

118+
const codeblocks = Array.from(md.matchAll(/^```[\s\S]*?^```/mg))
119+
.map(m => ([m.index!, m.index! + m[0].length]))
120+
118121
const result = md.replace(
119122
/(\n<style[^>]*?>)([\s\S]+?)(<\/style>)/g,
120123
(full, start, css, end) => {
124+
const index = md.search(full)
125+
// don't replace `<style>` inside code blocks, #101
126+
if (index < 0 || codeblocks.some(([s, e]) => s <= index && index <= e))
127+
return full
121128
if (!start.includes('scoped'))
122129
start = start.replace('<style', '<style scoped')
123130
return `${start}\n.slidev-page-${page}{${css}}${end}`
@@ -140,6 +147,9 @@ export function transformMermaid(md: string): string {
140147
})
141148
}
142149

150+
/**
151+
* Escape `{{}}` in code block to prevent Vue interpret it, #99
152+
*/
143153
export function escapeVueInCode(md: string) {
144154
return md.replace(/{{(.*)}}/g, '&lbrace;&lbrace;$1&rbrace;&rbrace;')
145155
}

0 commit comments

Comments
 (0)