在 [Day-28] 中,昨天我們用 Lezer.js 定義了一個語法讓 (a+1)
. (100-(2+4))
這類的字串可以被解析。
我們來將定義好的 Grammar 拿到 CodeMirror 中使用,讓其可以被 Highlight 吧!
import {EditorView, basicSetup} from "codemirror"
import {html} from "@codemirror/lang-html"
let editor = new EditorView({
doc: "The document\nis\nshared",
extensions: [
basicSetup,
html(),
],
parent: document.body
})
在 [day-22] 中我們用 import {html} from "@codemirror/lang-html"
引入 html 的語法包
那就是說今天生成的語法包,也可以使用 import {myLang} from "../myLang.js"
的方式來引入。
@top Program { expression }
expression {
Name |
Number |
BinaryExpression
}
@skip { space | Comment }
BinaryExpression { "(" expression ("+" | "-") expression ")" }
@tokens {
space { @whitespace+ }
Comment { "//" ![\n]* }
Name { @asciiLetter+ }
Number { @digit+ }
}
引入 @lezer/highlight
並設定要高亮的 token 類型
import {parser} from "./lang.grammar"
import {LRLanguage, LanguageSupport, indentNodeProp, foldNodeProp, foldInside, delimitedIndent} from "@codemirror/language"
import {styleTags, tags as t} from "@lezer/highlight"
export const MyLanguage = LRLanguage.define({
parser: parser.configure({
props: [
indentNodeProp.add({
Program: delimitedIndent({closing: ")", align: false})
}),
foldNodeProp.add({
Program: foldInside
}),
styleTags({
Number: t.number,
"( )": t.paren
})
]
})
})
export function MyLang() {
return new LanguageSupport(MyLanguage)
}
利用下方的 rollup-grammar.config.js 來建立語法包,並執行 rollup src/grammar.js -c rollup-grammar.config.js
來建立語法包。
import {lezer} from "@lezer/generator/rollup"
export default {
input: "src/index.js",
external: id => id != "tslib" && !/^(\.?\/|\w:)/.test(id),
output: [
{file: "./dist/myLang.js", format: "es"}
],
plugins: [lezer()]
}
import {EditorView,basicSetup} from "codemirror"
import {MyLang} from "../dist/myLang.js"
let editor = new EditorView({
doc: "(((8+9)+10)-20)", // ((((((((a=10))))))))
extensions: [
basicSetup,
MyLang(),
],
parent: document.body
})
利用下方的 rollup-editor.config.js 來建立語法包,並執行 rollup src/editor.js -c rollup-editor.config.js
來建立語法包。
import {nodeResolve} from "@rollup/plugin-node-resolve"
export default {
input: "./src/editor.js",
output: {
file: "./output/editor.bundle.js",
format: "iife"
},
plugins: [nodeResolve()]
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CodeMirror</title>
<link rel="shortcut icon" href="code.ico" />
</head>
<body>
<h1>CodeMirror!</h1>
<script src="editor.bundle.js"></script>
</body>
</html>