Skip to content

Commit 09bee07

Browse files
committed
docs: draft
1 parent 095b6e9 commit 09bee07

File tree

1 file changed

+105
-1
lines changed

1 file changed

+105
-1
lines changed

slides.md

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1171,7 +1171,7 @@ function parse(str) {
11711171
}
11721172
```
11731173

1174-
解析器的参数是模板字符串,解析器会逐个读取字符串模板的字符,并根据一定的规则将其处理为我们想要的结果。
1174+
解析器的参数是模板字符串,会逐个读取字符串模板的字符,并根据一定的规则将其处理为我们想要的结果。
11751175

11761176
举例来说,假设有这样一段模板:
11771177

@@ -1181,6 +1181,110 @@ function parse(str) {
11811181

11821182
---
11831183

1184+
```js
1185+
/**
1186+
* 解析模板字符串
1187+
* @param {string} str 模板字符串
1188+
*/
1189+
function parse(str) {
1190+
const context = {
1191+
// 存储模板字符串
1192+
source: str,
1193+
// 前进 num 个字符
1194+
advanceBy(num) {
1195+
context.source = context.source.slice(num)
1196+
},
1197+
advanceSpaces() {
1198+
// 匹配空格换行符等
1199+
const match = /^[\t\r\n\f ]+/.exec(context.source)
1200+
if (match) {
1201+
context.advanceBy(match[0].length)
1202+
}
1203+
}
1204+
}
1205+
const nodes = parseChildren(context, [])
1206+
const root = { // 根节点
1207+
type: 'Root',
1208+
children: nodes
1209+
}
1210+
return root
1211+
}
1212+
```
1213+
1214+
---
1215+
1216+
```js
1217+
/**
1218+
* 解析子节点
1219+
* @param {*} context 上下文
1220+
* @param {*} ancestors 祖先节点列表
1221+
*/
1222+
function parseChildren(context, ancestors = []) {
1223+
const nodes = []
1224+
while (!isEnd(context, ancestors)) { // 如果还没有解析到模板的末尾
1225+
let node
1226+
const s = context.source
1227+
if (s.startsWith('{{')) {
1228+
// 解析插值表达式
1229+
node = parseInterpolation(context)
1230+
} else if (s[0] === '<') {
1231+
if (s[1] === '/') {
1232+
// 结束标签
1233+
} else if (/[a-z]/i.test(s[1])) { // 解析开始标签
1234+
node = parseElement(context, ancestors)
1235+
}
1236+
}
1237+
if (!node) { // 解析文本节点
1238+
node = parseText(context)
1239+
}
1240+
nodes.push(node)
1241+
}
1242+
return nodes
1243+
}
1244+
```
1245+
1246+
---
1247+
1248+
<div grid="~ cols-2 gap-2">
1249+
1250+
```js
1251+
/**
1252+
* 解析插值表达式
1253+
* @param {*} context 上下文
1254+
* @example
1255+
*
1256+
* 模板: {{ msg }}
1257+
*/
1258+
function parseInterpolation(context) {
1259+
const { advanceBy } = context
1260+
// 移除 {{
1261+
advanceBy(2)
1262+
const closeIndex = context.source.indexOf('}}')
1263+
const rawContent = context.source.slice(0, closeIndex)
1264+
// 去掉前后空格
1265+
const content = rawContent.trim()
1266+
advanceBy(rawContent.length)
1267+
// 移除 }}
1268+
advanceBy(2)
1269+
1270+
return {
1271+
type: 'Interpolation',
1272+
content: {
1273+
type: 'Expression',
1274+
content
1275+
}
1276+
}
1277+
}
1278+
```
1279+
1280+
```js
1281+
1282+
```
1283+
1284+
</div>
1285+
1286+
---
1287+
11841288
# Learn More
11851289

11861290
[Documentations](https://sli.dev) · [GitHub](https://github.com/slidevjs/slidev) · [Showcases](https://sli.dev/showcases.html)

0 commit comments

Comments
 (0)