这一页是 code 和 data。两者放一起,因为它们是一对镜像:code 装处理器永不解释的文本,data 装必须解析通过的值;两者共用一套 src= 路由语法,却对「解析不到」给出相反的轻重。每条规则标出处,右边是 geml check、geml get 和 --to html 的实测输出。
规范已定 规范正文写死的。GEP 草案 提案定义、本分支已实现但规范未收。实现偏差 规范这样说,1.9.2 不这样做。
| 规则 | 出处 | 状态 | |
|---|---|---|---|
| 两者共用 | |||
| 1 | 一套路由语法:src=<path>[#L<start>[-<end>]],1 起始、闭区间;相对文档解析,给了 --root 也可相对根;http(s) 由渲染器取,其它 scheme 拒绝。 | §3.3 · §9.4 | 规范已定 |
| 2 | 同一个属性两种轻重:code 的 src 解析不到是 warning(块描述的是某处的一段代码,源码不在手边文档仍成立);data 的 src 解析不到是 error(值就是文档承诺的内容)。范围漂移两者都是 error。 | §3.3 · §3.2 | 规范已定 |
| 3 | code 与 data 都不许 src 与正文同在(code-src-and-body、data-src-and-body error)。code 的路由不看后缀,data 的必须是 .json/.jsonl。 | §3.3 · §3.2 · A.5 | 规范已定 |
| code | |||
| 4 | raw 体,lang= 只是标签;正文永不执行。渲染为 <pre><code class="language-xx">。 | §3 · §9.1 | 规范已定 |
| 5 | src=<path>[#L<s>[-<e>]] 引用源码。src 与正文同在 error;范围漂移 error;解析不到 warning(图仍有效);非法 scheme error。 | §3.3 · A.5 | 规范已定 |
| data | |||
| 6 | 值树(JSON 值域)。json 默认,jsonl 每行一值、空行忽略。解析失败是 data-parse error,指出行号。 | §3.2 · A.5 | 规范已定 |
| 7 | yaml/toml 是保留名:无引擎时正文保留、给 warning、不猜。未知 format 同样降级。csv 不是 data 格式。 | §3.2 | 规范已定 |
| 8 | src= 与正文互斥 error;文件须 .json/.jsonl;schema= 保留,形状不对 error,不做校验。 | §3.2 · A.5 | 规范已定 |
| 9 | #cfg["tags"][1]、#log[1]["t"] 按坐标读值树里的一个节点。 | GEP-0011 | GEP 草案 |
code:原文,或者一段源码的路由正文是文本,永不执行(§9.1)。可以不抄代码,用 src= 指向文件和行号,drift 会被抓住。
src= 结局 规范已定helper.js 只有 3 行。=== code {#inline lang=ts caption="Inline body"} export const x = 1; === === code {#routed lang=js src=helper.js#L1-2} === === code {#both lang=js src=helper.js} body and src together === === code {#drift lang=js src=helper.js#L40-50} === === code {#missing lang=js src=nowhere.js} === === code {#scheme lang=js src=ftp://x/y.js} ===
error: code: carries both `src=` and an inline body; exactly one is permitted (line 11) error: code source `helper.js#L40-50`: the file has 3 line(s), so lines 40-50 no longer exist — the range is stale (line 14) warning: cannot resolve code source `nowhere.js` — not checked (line 16) error: code source `ftp://x/y.js` names a disallowed URL scheme (line 18) 3 error(s), 1 warning(s)
<path>[#L<start>[-<end>]],1 起始、闭区间。相对文档解析,给了 --root 也可相对根解析,都不出 §9.4 的围栏。data 的 src= 解析不到是 error(§3.2):它的值就是文档承诺的内容,取不到就是承诺落空。两个类型对同一个属性的轻重相反,各有理由。data:被验证的值树GEP-0005 加进来的。code 装的是不许解释的文本,data 装的是必须解析通过的值。
=== data {#cfg} %% format 缺省 = json {"name": "geml", "tags": ["a", "b"], "n": 3} === === data {#log format=jsonl} {"t": 1, "ok": true} {"t": 2, "ok": false} %% 空行忽略;末尾追加一块就是一条新记录 === === data {#ext src=rows.json} %% 内容在文件里,块是它的可寻址视图 ===
$ geml get p5-data.geml '#cfg["tags"][1]' b $ geml get p5-data.geml '#log[1]["t"]' 2
value,暴露在文档模型里。默认 json,因为它是值树自己的序列化,零依赖处理器一定能验。[ 不能出现在合法 id 里所以不会混淆。geml list 不枚举坐标,由作者构造。本分支已实现,规范正文未收。=== data {#bad} {"name": "geml", ← 不是一个完整 JSON 值 === === data {#y format=yaml} %% 保留名 name: geml === === data {#both src=rows.json} {"x": 1} ← src 与正文同在 === === data {#sch schema=not-a-ref} {"x": 1} === === data {#csvish format=csv} a,b ===
error: data: body is not valid JSON (Expected double-quoted property name in JSON at position 16 (line 1 column 17)) (line 14) warning: data: no `yaml` engine in this processor; body kept raw, not verified (line 16) warning: data: no `toml` engine in this processor; body kept raw, not verified (line 20) error: data: carries both `src=` and an inline body; exactly one is permitted (the body wins here) (line 25) error: data: `schema=not-a-ref` must name a block (`#id`) or a GEML document (`doc.geml[#id]`) (line 28) warning: unknown data format `weird`; body kept raw (line 31) warning: unknown data format `csv`; body kept raw (line 34) 3 error(s), 4 warning(s)
data-parse 指出行号。yaml/toml 是保留名,无引擎时保留正文、不验证、不猜,与未知 diagram format 同一套降级(§7)。未知 format 同理。csv 不是 data 格式:它不自描述(分隔符、表头、引号都是参数),只对列模型有意义,所以是 table 的格式(§6)。全部用仓库内当前构建 node geml-parser/dist/geml.js 跑出。探针文件在会话临时目录,内容已完整贴在上面各图左侧。
| 探针 | 覆盖 | check 结果 | 页面里对应 |
|---|---|---|---|
| p3-code.geml · helper.js | 内联、路由、src+正文、范围漂移、解析不到、非法 scheme | 3 error 1 warning | code |
| p5-data.geml · rows.json | json、jsonl、src、坏 JSON、yaml、toml、src+正文、schema、未知 format、csv、坐标 | 3 error 4 warning | data |