docs: classify Ebox DSL primitives and sugar

This commit is contained in:
Kinneyzhang 2026-08-26 15:14:27 +08:00
parent 2e3bbf3f47
commit c3ea8aa8ea
3 changed files with 111 additions and 4 deletions

View File

@ -20,6 +20,9 @@ ETAF 当前性能工作的最终结果是:通用性能工具能解释每次操
不把偶然的调用顺序、示例名称或当前数据形状伪装成抽象。
- 一个模块只拥有一项完整职责,并为这项职责提供少量、精确、正交的接口。
接口之间通过明确数据契约组合,不读取彼此的内部状态,不复制彼此的规则。
- 用户心智成本是公共 API 的硬指标。同一能力只能有一个规范名称和一条推荐路径;
内部算法、后端节点、兼容别名和便捷 wrapper 不得伪装成并列公共概念。常用路径
只要求学习最小模型,高级能力通过逐层展开获得,不能让用户先理解包内部实现。
- 区分语义身份、视觉槽位、布局坐标、绘制层和发布权限。只有模型本身允许时
才能合并概念;不能为了减少代码把不同生命周期的身份混在一起。
- 复杂系统通过小模块的组合与复用逐步形成。新增能力应优先扩展已有模型的

View File

@ -8,6 +8,11 @@ This document defines only the target model, module owners, dependency direction
completion criteria. Delivery sequencing belongs in a separate implementation plan;
historical names and compatibility do not shape the target architecture.
User mental cost is a hard constraint: one capability has one canonical name and one
recommended spelling. Internal algorithms, backend nodes, wrappers, and compatibility
aliases never become peer public concepts. Ordinary applications learn Text, Box, and
Component first; Fragment, layout detail, and lower packages are progressively disclosed.
## 1. Final model
```text
@ -92,7 +97,51 @@ child's `:outer` does not change ordering. `:outer` is consumed only by a normal
They are Box modes, not Components or alternate Runtime node names. The only canonical
surface is `(box :layout 'MODE ...)`; core provides no layout-name aliases.
### 2.5 Fragment
### 2.5 Ebox DSL primitives and sugar
ETAF View and Ebox DSL are different layers: ETAF has Text/Box/Fragment/Component,
while Ebox receives lowered content and layout. The target Ebox DSL has one structural
tag:
```elisp
(box :layout MODE ...)
```
An Ebox box may be a content leaf or own children and a layout context. A Range
descriptor is an incremental backend protocol, not an authoring node. A bare string is
content-literal shorthand, not a node type.
Current tags classify as follows:
| Current tag | Classification | Target expression |
| --- | --- | --- |
| `ebox` | compatibility alias for `box` | remove; use `box` |
| `spacer` | empty-Box convenience sugar | remove; use a childless `box` |
| `row` | layout-tag sugar | `(box :layout 'row ...)` |
| `column` | layout-tag sugar | `(box :layout 'column ...)` |
| `flex` | layout-tag sugar | `(box :layout 'flex ...)` |
| `grid` | layout-tag sugar | `(box :layout 'grid ...)` |
| `item` | Flex-child participation sugar | put flex/order/align-self properties on the child Box |
| `grid-item` | Grid-child placement sugar | put grid placement properties on the child Box |
Item wrappers are therefore unnecessary. Parent-participation properties belong to
the child Box and are validated by the parent layout mode:
```elisp
(box :layout 'flex
(box :flex-grow 1 :content "A"))
(box :layout 'grid
(box :grid-column '(1 :span 2) :content "Header"))
```
These are low-level Ebox examples, so Ebox `:content` is valid. ETAF View continues to
use Text/children and does not expose `:content`.
The target Ebox DSL retains none of those aliases or sugar tags. Ebox still implements
the layout algorithms independently, but algorithm kinds are not authoring node kinds.
### 2.6 Fragment
Fragment is a nonvisual structural Range. It may contain zero, one, or many sibling
Views, creates no Box or layout context, and may carry only a stable `:key` plus
@ -101,7 +150,7 @@ children. Runtime may retain and replace its Range independently.
A Component call has no fixed outer/layout properties. Its root Text/Box determines
participation. A transparent Component returning a Fragment may have multiple roots.
### 2.6 Strings, content, and empty Boxes
### 2.7 Strings, content, and empty Boxes
Strings under a Box normalize to Text, so `(box "text")` equals
`(box (text "text"))`. ETAF does not expose `(box :content ...)`; `:content` remains an
@ -269,6 +318,10 @@ Current code still registers `text`, `fragment`, `container`, `row`, `column`, `
`:layout 'normal` are not implemented, and the target public View does not retain
`raw-ebox`.
Current Ebox DSL still accepts `box`, `ebox`, `row`, `column`, `flex`, `item`, `grid`,
`grid-item`, and `spacer`. The target Ebox DSL keeps only `box`; all other tags are
removed or represented as Box properties according to the table above.
This is a clean redesign: old Host names and old `.etaf` sources need not continue to
run, and no long-lived compatibility layer is added. Formal architecture/user docs must
not present target syntax as delivered before implementation is complete.

View File

@ -7,6 +7,10 @@
本文只定义目标模型、模块 owner、依赖方向和完成条件。实现顺序属于单独的
实施计划;历史名称和兼容策略不参与目标架构设计。
用户心智成本是本提案的硬约束:同一能力只有一个规范名称和一种推荐写法;内部
算法、后端节点、wrapper 和兼容别名不能作为并列公共概念。普通应用只需学习
Text、Box、ComponentFragment、布局细节和底层包通过渐进披露进入。
## 1. 最终模型
ETAF 的表示链只有四层:
@ -117,7 +121,50 @@ run-in、list-item 或任意匿名盒规则。Ebox 可以把 `normal` 映射为
(box :layout 'grid ...)
```
### 2.5 Fragment
### 2.5 Ebox DSL 的基础节点与语法糖
ETAF View 和 Ebox DSL 是两层不同接口ETAF 有 Text/Box/Fragment/Component
Ebox 只接收已经降低的内容与布局。目标 Ebox DSL 只有一个基础结构 tag
```elisp
(box :layout MODE ...)
```
Ebox `box` 可以是 content leaf也可以包含 children 并建立布局上下文。Range
descriptor 是增量后端协议,不是作者 DSL 节点;裸字符串只是 content literal
简写,也不是节点类型。
当前 DSL 的其他 tag 必须明确分类,不能与基础节点并列:
| 当前 tag | 分类 | 目标表达 |
| --- | --- | --- |
| `ebox` | `box` 的兼容别名 | 删除,统一写 `box` |
| `spacer` | 空 Box 便捷糖 | 删除,使用无 children 的 `box` |
| `row` | layout tag 糖 | `(box :layout 'row ...)` |
| `column` | layout tag 糖 | `(box :layout 'column ...)` |
| `flex` | layout tag 糖 | `(box :layout 'flex ...)` |
| `grid` | layout tag 糖 | `(box :layout 'grid ...)` |
| `item` | Flex child participation 糖 | 把 `:flex-*`、`:order`、`:align-self` 直接写在 child Box |
| `grid-item` | Grid child placement 糖 | 把 `:grid-*` placement 直接写在 child Box |
因此 `item``grid-item` 不是必要 wrapper。父级参与属性属于 child Box并由
父级 layout mode 验证:
```elisp
(box :layout 'flex
(box :flex-grow 1 :content "A"))
(box :layout 'grid
(box :grid-column '(1 :span 2) :content "Header"))
```
以上示例是 Ebox 低层 DSL因此可以使用 Ebox 的 `:content`ETAF View 仍然只用
Text/children不暴露 `:content`
目标 Ebox DSL 不保留上述兼容别名或糖。布局算法仍由 Ebox 分别实现,但节点
分类只保留 `box`;算法种类不等于作者节点种类。
### 2.6 Fragment
`Fragment` 是无视觉 wrapper 的结构 Range
@ -130,7 +177,7 @@ Component call 本身没有 `:outer` 或 `:layout`。它的根 Text/Box 决定
布局;返回 Fragment 的透明 Component 可以产生多个兄弟节点,因此不存在单一的
“Component 外部盒子”。
### 2.6 字符串、content 与空 Box
### 2.7 字符串、content 与空 Box
Box 子节点中的字符串规范化为 Text
@ -336,6 +383,10 @@ Component identity、依赖所有权、TP 优先级和 generation authority 不
`flex`、`grid` 和 `spacer`,并提供 `raw-ebox`;目标 `box`、`:outer`、
`:layout 'normal` 尚未实现,目标公共 View 也不保留 `raw-ebox`
当前 Ebox DSL 仍接受 `box`、`ebox`、`row`、`column`、`flex`、`item`、`grid`、
`grid-item``spacer`。目标 Ebox DSL 只保留 `box`;其他 tag 按上表删除或改为
Box 属性。
这是干净重设计,不要求旧 Host 名称或旧 `.etaf` 文件继续运行,也不增加长期
兼容层。实现完成前,正式架构和用户指南不得把目标语法描述成当前 API。