docs(bgm): derive definition names from role.type

This commit is contained in:
2026-08-10 16:27:45 +08:00
parent aab0b66ee8
commit 23332ab786
+46 -30
View File
@@ -84,50 +84,51 @@ declaration, then uses its `include` paths to find the definitions.
### Code blocks as virtual files ### Code blocks as virtual files
A code block is a virtual definition file. To give it a name — so `include:` A code block is a virtual definition file. Its name is derived from the
and `$variants` paths can resolve against it — add a `file=` segment to the `role=` on its info string — `role.type.lang` — so it is discoverable by the
code block's info string. The name is relative to the current markdown file: default `include: ./**/*.yaml` and addressable by that name:
````md ````md
```yaml file=parts/cargo.yaml ```yaml role=part.cargo
... ...
``` ```
```csv file=parts/cargo.csv ```yaml role=surface.game#main
...
```
```yaml role=package
... ...
``` ```
```` ````
- A block with `file=` is addressable by that path. - `role=part.cargo` names the block `part.cargo.yaml`.
- A block without `file=` is auto-named `./${hash}.yaml`, where `hash` - `role=surface.game#main` names it `surface.game.yaml`.
is derived from its content. This makes every yaml block naturally - `role=package` names it `package.yaml`.
discoverable by the default `include: ./**/*.yaml`. Identical blocks dedupe - The name is what `$variants: ./cargo.csv` and `include: parts/*.yaml`
to the same hash. resolve against. When there is a real file in that path, the codeblock wins.
- The `file=` name is what `$variants: ./cargo.csv` and `include: parts/*.yaml` - `file=` overrides the auto-name when present, e.g. `file=parts/cargo.yaml`
resolve against. When there is a real file in that path, the codeblock wins. names the block `parts/cargo.yaml` regardless of its role.
- `file=` implies the file type from its extension; the language tag is - A block without `role=` is **not** a definition — it is ignored. Discovery
optional and only for editor highlighting. is explicit: a block is a definition only when its `role=` (or, for real
- **Hash vs explicit `file=`:** a hashed name is for auto-discovery, not for files, its filename) declares a known `role.type`.
referencing. To point at a specific yaml block by name, give it an explicit
`file=`; otherwise its name is content-derived and unstable.
### role= on the info string ### role= on the info string
A block's `role` can be declared on the info string instead of in the content, A block's role is declared on the info string, using the same `role.type#id`
using the same `role.type#id` shape as the block's identity. `type` and `id` shape as the block's identity. `type` and `id` are optional — anything not
are optional — anything not given comes from the content (or from `$variants` given comes from the content (or from `$variants` rows):
rows):
````md ````md
```yaml file=parts/cargo.yaml role=part.cargo ```yaml role=part.cargo
... ...
``` ```
```yaml file=board.yaml role=surface.game#main ```yaml role=surface.game#main
... ...
``` ```
```yaml file=game.yaml role=package ```yaml role=package
... ...
``` ```
```` ````
@@ -139,8 +140,21 @@ rows):
- A `role`/`type`/`id` given on the info string **conflicts** with the same - A `role`/`type`/`id` given on the info string **conflicts** with the same
key in the content and errors. `id` on the info string cannot combine with key in the content and errors. `id` on the info string cannot combine with
`$variants`, since every row supplies its own `id`. `$variants`, since every row supplies its own `id`.
- Without `role=`, discovery works exactly as before: the role comes from the - A block without `role=` is not a definition — discovery is explicit (see
content's `role:` field. above).
### Real files
A real `role.type.lang` file (e.g. `part.cargo.yaml`) is a definition by its
filename, with no `role=` needed. `role` and `type` are parsed from the name;
`id` comes from the content or `$variants`. A real file and a code block with
the same name are the same definition; the code block wins.
### Duplicates
Two definitions with the same `role.type` are grouped under the same name.
They must not define the same `id` — a duplicate `type#id` errors. Blocks with
the same `role.type` but different ids are fine.
### include ### include
@@ -160,7 +174,8 @@ package can use a `../`-relative pattern or an absolute-from-root pattern
## 3. Roles ## 3. Roles
json objects in yaml blocks are handled if they have a `role:` field for either json objects in yaml blocks are handled if they are declared as a definition
by their `role=` (or, for real files, their filename) for either
- `package` - `package`
- `part` - `part`
- `surface` - `surface`
@@ -171,9 +186,10 @@ a valid object can either be the root or in the list of the yaml block.
for all roles except package, `type` and `id` are needed. for all roles except package, `type` and `id` are needed.
`type#id` is used for identification so that combo must be unique in the package. `type#id` is used for identification so that combo must be unique in the package.
A block may declare its role on the info string instead — `role=part.cargo` is A block declares its role on the info string — `role=part.cargo` is equivalent
equivalent to `role: part` + `type: cargo` in the content (see §2). The info to `role: part` + `type: cargo` in the content (see §2). A real file declares
string and content must not both set the same key. it in its filename. The info string/filename and content must not both set the
same key.
### package ### package