create-asciidoc-multi-book-workspace 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +28 -0
  3. package/dist/create.js +11 -3
  4. package/dist/index.d.ts +1 -1
  5. package/dist/index.js +1 -1
  6. package/dist/init-workspace.d.ts +1 -0
  7. package/dist/init-workspace.js +15 -13
  8. package/dist/template-manifest.d.ts +9 -2
  9. package/dist/template-manifest.js +24 -9
  10. package/package.json +1 -1
  11. package/templates/default-workspace/books/07-structured-writing-conventions/backmatter/appendix-a.adoc +20 -13
  12. package/templates/default-workspace/books/07-structured-writing-conventions/backmatter/appendix-b-decision-trees.adoc +54 -19
  13. package/templates/default-workspace/books/07-structured-writing-conventions/backmatter/glossary.adoc +7 -5
  14. package/templates/default-workspace/books/07-structured-writing-conventions/book.adoc +9 -5
  15. package/templates/default-workspace/books/07-structured-writing-conventions/frontmatter/abstract.adoc +1 -1
  16. package/templates/default-workspace/books/07-structured-writing-conventions/frontmatter/acknowledgments.adoc +1 -1
  17. package/templates/default-workspace/books/07-structured-writing-conventions/frontmatter/preface.adoc +3 -10
  18. package/templates/default-workspace/books/07-structured-writing-conventions/parts/010-source-surface/010-source-and-projection.adoc +14 -14
  19. package/templates/default-workspace/books/07-structured-writing-conventions/parts/010-source-surface/020-heading-address-and-xref.adoc +55 -0
  20. package/templates/default-workspace/books/07-structured-writing-conventions/parts/010-source-surface/030-source-order-notation.adoc +3 -3
  21. package/templates/default-workspace/books/07-structured-writing-conventions/parts/010-source-surface/_partintro.adoc +1 -1
  22. package/templates/default-workspace/books/07-structured-writing-conventions/parts/020-names-roles-and-relations/010-names-and-address-labels.adoc +20 -0
  23. package/templates/default-workspace/books/07-structured-writing-conventions/parts/{020-identity-and-relation/010-role-identity.adoc → 020-names-roles-and-relations/020-heading-roles.adoc} +9 -7
  24. package/templates/default-workspace/books/07-structured-writing-conventions/parts/{020-identity-and-relation/020-relation-predicate.adoc → 020-names-roles-and-relations/030-relation-predicate.adoc} +5 -3
  25. package/templates/default-workspace/books/07-structured-writing-conventions/parts/020-names-roles-and-relations/_partintro.adoc +1 -0
  26. package/templates/default-workspace/books/07-structured-writing-conventions/parts/030-fields-and-terminology/010-surface-fields.adoc +41 -4
  27. package/templates/default-workspace/books/07-structured-writing-conventions/parts/030-fields-and-terminology/020-glossary.adoc +2 -2
  28. package/templates/default-workspace/books/07-structured-writing-conventions/parts/030-fields-and-terminology/030-declaring-conventions.adoc +70 -0
  29. package/templates/default-workspace/books/07-structured-writing-conventions/parts/030-fields-and-terminology/_partintro.adoc +1 -1
  30. package/templates/default-workspace/catalog.adoc +2 -2
  31. package/templates/solo-workspace/README.md +24 -0
  32. package/templates/solo-workspace/catalog.adoc +7 -0
  33. package/templates/default-workspace/books/07-structured-writing-conventions/parts/010-source-surface/020-default-semantics.adoc +0 -47
  34. package/templates/default-workspace/books/07-structured-writing-conventions/parts/020-identity-and-relation/_partintro.adoc +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.0 - 2026-10-21
4
+
5
+ ### Added
6
+
7
+ - Add `--solo` to the `create` command and export `initSoloWorkspace` from the package root: generate a workspace that contains only the structured writing conventions book, shelved as book 01.
8
+ - Add the chapter "声明本书的约定" (declaring the book's conventions) to the structured writing conventions sample: `.convention` headings with `declares=roles|relations|values|fields` write a book's controlled vocabularies in the book itself, so readers, check scripts, and query tools read one source. A `fields` declaration can carry `id-prefix` for roles whose address labels are existing technical addresses.
9
+
10
+ ### Changed
11
+
12
+ - Show in the structured writing conventions sample how a field value attaches a code block or table with `+`, and list every way a description list stops counting as fields: an unattached block, another block between the heading and the list, block attributes on the list, or a nested description list. It also shows how to keep a description list under a heading as body text.
13
+ - State that a heading's role scope is a reading context: projection, checks, and query tools read only the role written on each heading.
14
+ - Add a decision tree for declaring and maintaining conventions, and update the quick reference, glossary, and part introductions.
15
+
16
+ ## 0.3.1 - 2026-10-15
17
+
18
+ ### Changed
19
+
20
+ - Rework the structured writing conventions sample around names and addressing: headings now serve as the canonical name and default xref target, while `[#...]` is presented only as an explicit address label for existing technical or external addresses.
21
+ - Reorganize part two of the structured writing conventions sample from identity-and-relation into names-roles-and-relations, adding guidance on renames, aliases, concept-boundary changes, splits, and retirements.
22
+ - Update the quick reference, decision trees, glossary, part introductions, and catalog descriptions to drop the stable-ID teaching path.
23
+
3
24
  ## 0.3.0 - 2026-07-26
4
25
 
5
26
  ### Changed
package/README.md CHANGED
@@ -13,6 +13,14 @@ pnpm install
13
13
  pnpm run build
14
14
  ```
15
15
 
16
+ For a workspace with only the structured writing conventions book (shelved as book 01), add `--solo`:
17
+
18
+ ```bash
19
+ pnpm create asciidoc-multi-book-workspace my-book --solo
20
+ ```
21
+
22
+ See [Solo Workspace](#solo-workspace).
23
+
16
24
  npm users can run:
17
25
 
18
26
  ```bash
@@ -36,6 +44,8 @@ console.log(result.targetDir);
36
44
 
37
45
  The host CLI owns command parsing and user-facing output. This package owns the workspace files it creates.
38
46
 
47
+ `initSoloWorkspace` takes the same options and creates the [solo workspace](#solo-workspace).
48
+
39
49
  The generated workspace contains:
40
50
 
41
51
  ```text
@@ -58,6 +68,23 @@ shared/images/workspace-map.svg
58
68
 
59
69
  It does not include this repository's `test/`, `.github/`, `src/`, `dist/`, `DESIGN.adoc`, or maintainer release checks.
60
70
 
71
+ ## Solo Workspace
72
+
73
+ The solo workspace holds one book: sample book `07-structured-writing-conventions`, shelved as
74
+ `books/01-structured-writing-conventions`, with a short catalog and README written for it:
75
+
76
+ ```text
77
+ README.md
78
+ catalog.adoc
79
+ package.json
80
+ .gitignore
81
+ tools/adoc-books.mjs
82
+ books/01-structured-writing-conventions
83
+ shared/attributes.adoc
84
+ ```
85
+
86
+ The other sample books stay in the template and are generated only by the default workspace.
87
+
61
88
  ## Generated Workspace
62
89
 
63
90
  The generated `package.json` directly lists the AsciiDoc toolchain:
@@ -81,6 +108,7 @@ pnpm run clean
81
108
  ```text
82
109
  src/ # TypeScript initializer and user runtime source
83
110
  templates/default-workspace/ # true source for the generated user workspace
111
+ templates/solo-workspace/ # catalog and README written for the solo workspace
84
112
  test/ # maintainer tests
85
113
  DESIGN.adoc # maintainer design specification
86
114
  .github/ # maintainer CI
package/dist/create.js CHANGED
@@ -1,13 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
  import path from "node:path";
3
- import { initWorkspace } from "./init-workspace.js";
3
+ import { initSoloWorkspace, initWorkspace } from "./init-workspace.js";
4
4
  function usage() {
5
5
  return [
6
6
  "Usage:",
7
- " create-asciidoc-multi-book-workspace <target>",
7
+ " create-asciidoc-multi-book-workspace <target> [--solo] [--force]",
8
+ "",
9
+ "Options:",
10
+ " --solo one book only: the structured writing conventions sample, shelved as",
11
+ " books/01-structured-writing-conventions",
12
+ " --force write into a non-empty target; template output paths are overwritten,",
13
+ " other files are kept",
8
14
  "",
9
15
  "Examples:",
10
16
  " pnpm create asciidoc-multi-book-workspace my-books",
17
+ " pnpm create asciidoc-multi-book-workspace my-book --solo",
11
18
  " npm create asciidoc-multi-book-workspace@latest my-books"
12
19
  ].join("\n");
13
20
  }
@@ -23,7 +30,8 @@ async function main() {
23
30
  process.exitCode = 1;
24
31
  return;
25
32
  }
26
- const result = await initWorkspace({ targetDir: target, force: args.includes("--force") });
33
+ const init = args.includes("--solo") ? initSoloWorkspace : initWorkspace;
34
+ const result = await init({ targetDir: target, force: args.includes("--force") });
27
35
  const displayTarget = path.relative(process.cwd(), result.targetDir) || ".";
28
36
  console.log(`Created AsciiDoc multi-book workspace in ${displayTarget}`);
29
37
  console.log("");
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { initWorkspace } from "./init-workspace.js";
1
+ export { initSoloWorkspace, initWorkspace } from "./init-workspace.js";
2
2
  export type { InitWorkspaceOptions, InitWorkspaceResult } from "./init-workspace.js";
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- export { initWorkspace } from "./init-workspace.js";
1
+ export { initSoloWorkspace, initWorkspace } from "./init-workspace.js";
@@ -7,3 +7,4 @@ export interface InitWorkspaceResult {
7
7
  packageName: string;
8
8
  }
9
9
  export declare function initWorkspace(options: InitWorkspaceOptions): Promise<InitWorkspaceResult>;
10
+ export declare function initSoloWorkspace(options: InitWorkspaceOptions): Promise<InitWorkspaceResult>;
@@ -1,10 +1,10 @@
1
1
  import { cp, mkdir, readdir, readFile, stat, writeFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
- import { defaultWorkspaceTemplate, templatePackageNamePlaceholder } from "./template-manifest.js";
4
+ import { defaultWorkspaceCopies, packageJsonTemplate, soloWorkspaceCopies, templatePackageNamePlaceholder } from "./template-manifest.js";
5
5
  const sourceDir = path.dirname(fileURLToPath(import.meta.url));
6
6
  const packageRoot = path.resolve(sourceDir, "..");
7
- const templateRoot = path.join(packageRoot, "templates", defaultWorkspaceTemplate);
7
+ const templatesRoot = path.join(packageRoot, "templates");
8
8
  const runtimeScript = path.join(packageRoot, "dist", "runtime", "adoc-books.mjs");
9
9
  async function exists(filePath) {
10
10
  try {
@@ -32,27 +32,29 @@ function safePackageName(rawName) {
32
32
  .replaceAll(/^-+|-+$/g, "");
33
33
  return normalized || "asciidoc-books";
34
34
  }
35
- async function copyTemplatePath(name, targetDir) {
36
- await cp(path.join(templateRoot, name), path.join(targetDir, name), {
37
- force: true,
38
- recursive: true
39
- });
40
- }
41
- export async function initWorkspace(options) {
35
+ async function createWorkspace(options, copies) {
42
36
  const targetDir = path.resolve(options.targetDir);
43
37
  const targetExists = await exists(targetDir);
44
38
  if (targetExists && !options.force && !await isEmptyDirectory(targetDir)) {
45
39
  throw new Error(`target directory is not empty: ${targetDir}`);
46
40
  }
47
41
  await mkdir(targetDir, { recursive: true });
48
- for (const name of ["README.md", "catalog.adoc", "books", "shared"]) {
49
- await copyTemplatePath(name, targetDir);
42
+ for (const { from, to } of copies) {
43
+ await cp(path.join(templatesRoot, from), path.join(targetDir, to), {
44
+ force: true,
45
+ recursive: true
46
+ });
50
47
  }
51
- const packageTemplate = await readFile(path.join(templateRoot, "package.json.template"), "utf8");
48
+ const packageTemplate = await readFile(path.join(templatesRoot, packageJsonTemplate), "utf8");
52
49
  const packageName = safePackageName(path.basename(targetDir));
53
50
  await writeFile(path.join(targetDir, "package.json"), packageTemplate.replaceAll(templatePackageNamePlaceholder, packageName), "utf8");
54
- await writeFile(path.join(targetDir, ".gitignore"), await readFile(path.join(templateRoot, "gitignore.template"), "utf8"), "utf8");
55
51
  await mkdir(path.join(targetDir, "tools"), { recursive: true });
56
52
  await cp(runtimeScript, path.join(targetDir, "tools", "adoc-books.mjs"), { force: true });
57
53
  return { targetDir, packageName };
58
54
  }
55
+ export async function initWorkspace(options) {
56
+ return createWorkspace(options, defaultWorkspaceCopies);
57
+ }
58
+ export async function initSoloWorkspace(options) {
59
+ return createWorkspace(options, soloWorkspaceCopies);
60
+ }
@@ -1,3 +1,10 @@
1
- export declare const defaultWorkspaceTemplate = "default-workspace";
1
+ export interface TemplateCopy {
2
+ /** Path under `templates/`. */
3
+ from: string;
4
+ /** Path inside the generated workspace. */
5
+ to: string;
6
+ }
2
7
  export declare const templatePackageNamePlaceholder = "{{name}}";
3
- export declare const fixedTemplateOutputPaths: readonly ["README.md", "catalog.adoc", "package.json", ".gitignore", "tools/adoc-books.mjs", "books", "shared"];
8
+ export declare const packageJsonTemplate = "default-workspace/package.json.template";
9
+ export declare const defaultWorkspaceCopies: readonly TemplateCopy[];
10
+ export declare const soloWorkspaceCopies: readonly TemplateCopy[];
@@ -1,11 +1,26 @@
1
- export const defaultWorkspaceTemplate = "default-workspace";
2
1
  export const templatePackageNamePlaceholder = "{{name}}";
3
- export const fixedTemplateOutputPaths = [
4
- "README.md",
5
- "catalog.adoc",
6
- "package.json",
7
- ".gitignore",
8
- "tools/adoc-books.mjs",
9
- "books",
10
- "shared"
2
+ // Rendered with the target's package name instead of copied, so it stays outside the copy
3
+ // tables; every workspace shape renders this same file.
4
+ export const packageJsonTemplate = "default-workspace/package.json.template";
5
+ // A copy table is the complete list of template content a workspace shape receives;
6
+ // the initializer adds only the rendered package.json and tools/adoc-books.mjs.
7
+ // `gitignore.template` exists because npm drops `.gitignore` files from published packages.
8
+ export const defaultWorkspaceCopies = [
9
+ { from: "default-workspace/README.md", to: "README.md" },
10
+ { from: "default-workspace/catalog.adoc", to: "catalog.adoc" },
11
+ { from: "default-workspace/books", to: "books" },
12
+ { from: "default-workspace/shared", to: "shared" },
13
+ { from: "default-workspace/gitignore.template", to: ".gitignore" }
14
+ ];
15
+ // One book on its own shelf: sample book 07 is shelved as 01. The catalog and README are
16
+ // written for this shelf; shared/images/ stays behind because only the sample catalog uses it.
17
+ export const soloWorkspaceCopies = [
18
+ { from: "solo-workspace/README.md", to: "README.md" },
19
+ { from: "solo-workspace/catalog.adoc", to: "catalog.adoc" },
20
+ {
21
+ from: "default-workspace/books/07-structured-writing-conventions",
22
+ to: "books/01-structured-writing-conventions"
23
+ },
24
+ { from: "default-workspace/shared/attributes.adoc", to: "shared/attributes.adoc" },
25
+ { from: "default-workspace/gitignore.template", to: ".gitignore" }
11
26
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-asciidoc-multi-book-workspace",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Create a complete AsciiDoc multi-book workspace.",
5
5
  "license": "Apache-2.0",
6
6
  "author": {
@@ -32,33 +32,40 @@
32
32
  |`010-opening.adoc`
33
33
  |Chapter 文件的源文件编排号。规则与 Part 目录编排号一致。
34
34
 
35
- |`[#stable-id]`
36
- |为标题声明一个稳定的引用地址。稳定 ID 仅当以下两个条件同时满足时才需显式声明:
37
- (1) 该标题被至少一个 `xref` 交叉引用;
38
- (2) 标题文本本身可能变更或在全书范围内可能重复。
39
- 若标题本身已是领域内唯一且稳定的标识符(如专有名词、唯一实体名、标准化编号),即使被交叉引用,也无需额外声明稳定 ID——标题文本即地址。
35
+ |`== 标题`
36
+ |创建标题节点;标题给出当前规范名称。
40
37
 
41
- |`[#stable-id.concept]`
42
- |声明稳定 ID,并用 role 标明标题身份。
43
- 需要能够回答: “这个标题在整本书的知识体系中扮演什么认知功能”
38
+ |`[.concept]`
39
+ |用 role 标记标题在书中的作用。
44
40
 
45
- |`[#example.example, owner=writing-team]`
46
- |role 声明标题身份;named attributes 保留附加字段。
41
+ |`[#address-label]`
42
+ |为标题附加显式寻址标签。它用于找到标题。
43
+
44
+ |`[.example, owner=writing-team]`
45
+ |role 和 named attributes 保留标题的作用与附加字段。
46
+
47
+ |`[.convention, declares=roles]`
48
+ |约定声明。标题下的描述列表是本书的 role 词表;`declares` 还可以取 `relations`、`values`(配 `for` 与 `field`)和 `fields`(配 `for`)。
47
49
 
48
50
  |`summary::` + 下一行说明文本
49
51
  |标题下描述列表字段。用于较多字段或多行字段值。
50
52
 
51
- |`pass:[xref:stable-id[显示文本]]`
53
+ |字段文字之后的 `+` + 块
54
+ |把代码块、表格等挂到字段上,块属于字段值。字段之间不插入不带 `+` 的块。
55
+
56
+ |`pass:[xref:标题[显示文本]]`
52
57
  |显示为链接,投影为 references。
53
58
 
54
- |`pass:[xref:stable-id[显示文本, rel=depends-on]]`
59
+ |`pass:[xref:标题[显示文本, rel=depends-on]]`
55
60
  |显示为链接,同时声明 depends-on 关系。
56
61
 
57
62
  |===
58
63
 
59
64
  全书标题需要保持 `标题层级连续`。
60
65
 
61
- role 描述标题身份。rel 描述 xref 边上的关系谓词。附加字段可以写在标题 attrlist、标题下描述列表或 xref named attributes 中。
66
+ role 描述标题在书中的作用。rel 描述 xref 边上的关系谓词。附加字段可以写在标题 attrlist、标题下描述列表或 xref named attributes 中。
67
+
68
+ 标题改名时,更新引用;旧称有保留价值时写入别名。概念被拆分或废止时,保留历史标题并写明后续使用的标题。
62
69
 
63
70
  `[appendix]`、`[glossary]` 和 `[bibliography]` 是 section style。它们改变紧随其后 section 的语义;标题层级仍由 `=` 数量决定。
64
71
 
@@ -27,33 +27,38 @@
27
27
  └─ 否:写入标准等号标题。流程结束。
28
28
  ----
29
29
 
30
- == stable ID 的生命周期与寻址机制
30
+ == 名称变化与寻址标签
31
31
 
32
- 触发场景:: 作者评估是否需要为当前标题显式声明寻址 ID。
32
+ 触发场景:: 作者发现当前标题、旧称或引用地址发生变化。
33
33
 
34
34
  [source,text]
35
35
  ----
36
- 1. 当前标题文本是否已是领域内唯一且稳定的标识符?
37
- ├─ 是:不声明 `[#stable-id]`;直接使用标题文本作为引用地址。流程结束。
38
- └─ 否:评估交叉引用状态。
36
+ 1. 当前标题还是该对象的规范名称吗?
37
+ ├─ 是:继续使用标题。
38
+ └─ 否:判断变化类型。
39
39
 
40
- 2. 该标题在全书范围内是否被至少一个 `xref` 交叉引用?
41
- ├─ 否:不声明 `[#stable-id]`。流程结束。
42
- └─ 是:在等号标题上方的 attrlist 中显式声明 `[#stable-id]`。流程结束。
43
- ----
40
+ 2. 只是换成更准确的名称吗?
41
+ ├─ 是:改标题,更新引用;旧称有价值时写入别名。
42
+ └─ 否:检查概念边界。
44
43
 
45
- 触发场景:: 项目全局构建或审查阶段检查 stable ID 消费状态。
44
+ 3. 概念边界改变了吗?
45
+ ├─ 是:检查描述、纳入条件、排除条件、相关标题和既有结论。
46
+ └─ 否:完成名称更新。
46
47
 
47
- [source,text]
48
- ----
49
- 1. 扫描源文件中所有手工显式声明的 `[#stable-id]`。
50
- ├─ 每个 ID 对应的 xref 引用次数 >= 1:保留声明,审查通过。
51
- └─ 某个 ID 对应的 xref 引用次数 == 0:移除该 `[#stable-id]` 声明。
48
+ 4. 旧概念被拆分或废止了吗?
49
+ ├─ 是:保留历史标题,写明后续标题。
50
+ └─ 否:继续维护当前标题。
51
+
52
+ 5. 是否已有外部技术地址必须保留?
53
+ ├─ 是:为标题保留显式寻址标签。
54
+ └─ 否:不增加标签。
52
55
  ----
53
56
 
57
+ 跨改名追踪记录和冻结内容版本,由工具层分别处理,不由标题的显式寻址标签承担。
58
+
54
59
  == role 的作用域与语境管理
55
60
 
56
- 触发场景:: 作者为标题标记认知功能与身份语义。
61
+ 触发场景:: 作者为标题标记认知作用。
57
62
  前提:: 当前书稿已经约定 role 受控词表,例如 `.concept`、`.rule`、`.example`。
58
63
 
59
64
  [source,text]
@@ -63,7 +68,8 @@
63
68
  └─ 是:评估语境连续性。
64
69
 
65
70
  2. 当前子标题承载的认知角色是否与父标题声明的 role 相同?
66
- ├─ 是:不重复声明 role;下级标题默认属于同一角色范围。流程结束。
71
+ ├─ 是:写作时可以不重复声明 role,读者按语境理解为同一角色范围。
72
+ │ 工具只读标题自己写下的 role:想让检查核对它的字段、让查询列出它,就自己写上 role。流程结束。
67
73
  └─ 否:从受控词表中选取匹配新语境的 role,显式写入当前标题 attrlist。
68
74
  该声明完成语境切换。流程结束。
69
75
  ----
@@ -85,7 +91,7 @@
85
91
 
86
92
  3. 引用目的是什么?
87
93
  ├─ 表达阅读顺序、先读建议或普通参见:
88
- │ 写入普通 xref,例如 `xref:target-id[显示文本]`。
94
+ │ 写入普通 xref,例如 `xref:目标标题[显示文本]`。
89
95
  │ 投影为默认谓词 `aat:references`。流程结束。
90
96
  └─ 声明明确的逻辑关系边:选取 `rel` 谓词。
91
97
 
@@ -111,9 +117,38 @@
111
117
  │ 例如 `[owner=writing-team, status=active]`。流程结束。
112
118
  └─ 字段较多,或包含多行字段值:
113
119
  写入紧随标题下方的第一个连续描述列表。
114
- 例如 `key:: value`。流程结束。
120
+ 例如 `key:: value`。进入块评估。
121
+
122
+ 3. 字段值是否需要附带代码块、表格或另一段正文?
123
+ ├─ 是:在字段文字之后写一行 `+`,再写块;块属于字段值。
124
+ │ 字段之间不插入不带 `+` 的块,否则字段列表在块前结束。流程结束。
125
+ └─ 否:流程结束。
115
126
  ----
116
127
 
128
+ == 约定的声明与维护
129
+
130
+ 触发场景:: 作者为本书引入或修改 role、rel 谓词、字段取值或字段。
131
+
132
+ [source,text]
133
+ ----
134
+ 1. 本书是否已有对应的约定声明?
135
+ ├─ 是:在该声明的描述列表中增加、修改或删除 term;进入类型评估。
136
+ └─ 否:新建声明标题,放在读者最先读到约定的地方(例如前言里专设一节“本书的书写约定”),
137
+ 写 `[.convention, declares=...]`;进入类型评估。
138
+
139
+ 2. 声明的是什么?
140
+ ├─ role:`declares=roles`。
141
+ ├─ rel 谓词:`declares=relations`。
142
+ ├─ 某个 role 的附加字段取值:`declares=values, for=<role>, field=<字段名>`。
143
+ └─ 某个 role 的标题下描述列表字段:`declares=fields, for=<role>`。
144
+
145
+ 3. term 是否写成写作时使用的那个词?
146
+ ├─ 否:去掉点号与反引号,例如 `.concept` 写成 `concept`;回到本步重新判断。
147
+ └─ 是:在描述中写出这个词的含义。流程结束。
148
+ ----
149
+
150
+ 约定变化时只改声明。检查脚本和查询工具从声明读出词表,不另外维护一份。
151
+
117
152
  == 源文件物理编排与编号运算
118
153
 
119
154
  触发场景:: 作者为 Part 目录或 Chapter 源文件生成文件编排号。
@@ -4,14 +4,16 @@
4
4
 
5
5
  [glossary]
6
6
  heading:: 使用等号标题创建的书稿结构单位。
7
- stable ID:: 作者为标题显式声明的稳定引用地址,语法为 `[#id]`。
8
- 仅当标题被交叉引用、且标题文本自身不能保证全局唯一和不变时才需使用。
9
- 若标题文本已是领域内唯一的稳定标识符(如实体名称、标准化编号),
10
- 标题文本本身即承担 stable ID 的寻址功能,无需额外声明。
7
+ 规范名称:: 当前书稿采用的标题名称。
8
+ 显式寻址标签:: 作者用 `[#label]` 附加给标题的地址标签。它用于找到标题。
9
+ 别名:: 标题以外仍有检索、历史或语境价值的名称。
10
+ 不透明记录键:: 工具层用于跨改名追踪同一条记录的机器键。
11
+ 内容哈希:: 标识某次冻结内容的校验值。
11
12
  source-order notation:: 写在源文件路径表面的排序符号。
12
- role:: 标题身份标记,例如 `.concept` 或 `.rule`。
13
+ role:: 标题节点在书中承担的叙述作用,例如 `.concept`、`.rule` 或 `.example`。
13
14
  ordinary reference:: 普通 xref。投影时使用默认谓词 `aat:references`。
14
15
  relation predicate:: xref `rel` 字段选择的边谓词。
15
16
  source heading:: xref 所在的标题。
16
17
  target heading:: xref selector 指向的标题。
17
18
  surface field:: 源文档表面的附加字段。标题字段可来自标题 attrlist 或标题下描述列表;xref 边字段来自 xref named attributes。
19
+ 约定声明:: 带 `.convention` role 的标题。`declares` 字段说明它声明 role、rel 谓词、字段取值还是字段;标题下的描述列表是词表,term 是词,描述是含义。
@@ -36,18 +36,20 @@ include::parts/010-source-surface/_partintro.adoc[]
36
36
 
37
37
  include::parts/010-source-surface/010-source-and-projection.adoc[]
38
38
 
39
- include::parts/010-source-surface/020-default-semantics.adoc[]
39
+ include::parts/010-source-surface/020-heading-address-and-xref.adoc[]
40
40
 
41
41
  include::parts/010-source-surface/030-source-order-notation.adoc[]
42
42
 
43
- = 给标题和引用加意图
43
+ = 名称、角色与关系
44
44
 
45
45
  [partintro]
46
- include::parts/020-identity-and-relation/_partintro.adoc[]
46
+ include::parts/020-names-roles-and-relations/_partintro.adoc[]
47
47
 
48
- include::parts/020-identity-and-relation/010-role-identity.adoc[]
48
+ include::parts/020-names-roles-and-relations/010-names-and-address-labels.adoc[]
49
49
 
50
- include::parts/020-identity-and-relation/020-relation-predicate.adoc[]
50
+ include::parts/020-names-roles-and-relations/020-heading-roles.adoc[]
51
+
52
+ include::parts/020-names-roles-and-relations/030-relation-predicate.adoc[]
51
53
 
52
54
  = 字段与术语
53
55
 
@@ -58,6 +60,8 @@ include::parts/030-fields-and-terminology/010-surface-fields.adoc[]
58
60
 
59
61
  include::parts/030-fields-and-terminology/020-glossary.adoc[]
60
62
 
63
+ include::parts/030-fields-and-terminology/030-declaring-conventions.adoc[]
64
+
61
65
  [appendix]
62
66
  include::backmatter/appendix-a.adoc[]
63
67
 
@@ -1,3 +1,3 @@
1
1
  == 摘要
2
2
 
3
- 本书展示标题、稳定 ID、role、xref、rel 和附加字段形成可读、可维护、可投影的源文档的方式。作者可按写作目的选择其中写法。
3
+ 本书说明标题、引用、role、rel 和附加字段怎样共同构成可读、可维护、可投影的源文档。标题保存当前规范名称;引用用地址找到标题;显式寻址标签只在已有技术地址需要保留时使用。
@@ -1,3 +1,3 @@
1
1
  == 致谢
2
2
 
3
- 感谢 Asciidoctor 和 RDF 投影相关文档提供稳定术语和结构坐标。
3
+ 感谢 Asciidoctor 和 RDF 投影相关文档提供术语与结构坐标。
@@ -1,14 +1,7 @@
1
1
  == 前言
2
2
 
3
- 这本书按源文档写法组织。阅读时先看源文档片段和投影片段,再对照后续章节理解每个标记承担的职责。
3
+ 这本书把标题、引用、role、rel 和附加字段放在同一份 AsciiDoc 源文档中。标题给出当前规范名称;xref 找到标题;role 说明标题在书中的作用;rel 说明引用表达的关系。
4
4
 
5
- 实际书稿按写作目的选择这些写法。
6
- 长期引用且标题文本可能变更的标题使用稳定 ID;
7
- 若标题本身已是唯一且稳定的实体名称,标题文本直接作为引用地址。
8
- 带有明确身份的标题使用 role;表达关系的引用使用 rel;
9
- 随源稿保留的短字段使用 named attributes;字段较多或需要多行值的标题字段使用标题下描述列表。
5
+ 显式寻址标签只保留已经存在的技术地址。旧称、俗称和历史名称写入别名,不隐藏在地址字符串中。字段较少且值较短时写在标题 attrlist;字段较多或需要多行值时写在标题下的连续描述列表。
10
6
 
11
- 业务含义由书稿自己的约定承载。本书展示同一份 AsciiDoc 源文本如何同时服务阅读、维护和工具链投影。
12
-
13
- 通过展示标题、稳定 ID、role、xref、rel 和附加字段如何形成可读、可维护、可投影的源文档,让你能够理解,你可以拥有一种这样的表达方式,可以按照某种约定,就能够提升你书籍的质量,能够让下游的工具链继续消费你的书。 你可以参考本书里你所需要的结构。
14
- 合适的结构能够提升书籍的可阅读、可维护性。你可以按写作目的选择其中写法。
7
+ 同一份源文档因此同时保留阅读结构、维护所需的名称和关系,以及工具可以继续投影的字段。
@@ -2,49 +2,49 @@
2
2
  == 源文本与投影
3
3
 
4
4
  本章用一段示例展示结构化书写约定。Turtle 片段列出关键投影事实;完整投影还会保留 raw、路径、行号和边证据。
5
- 希望你能通过本章节的演示来理解你写下的文字能够给未来的你提供稳定的查询与导航结构。
5
+ 本章节的演示展示文字如何形成清晰的查询与导航结构。
6
6
 
7
7
  [source,asciidoc]
8
8
  ----
9
9
  = 结构化写作样例
10
10
 
11
- [#regular-heading.concept]
11
+ [.concept]
12
12
  == 常规标题
13
13
 
14
14
  常规标题提供可引用的阅读单位。
15
15
 
16
- [#basic-syntax.example]
16
+ [.example]
17
17
  === 基本语法
18
18
 
19
19
  基本语法是常规标题下的直接子标题。
20
20
 
21
- [#xref-rule.rule]
21
+ [.rule]
22
22
  == 引用规则
23
23
 
24
- 引用规则参见 xref:regular-heading[常规标题]。
25
- 引用规则依赖 xref:regular-heading[常规标题, rel=depends-on, weight=strong]。
24
+ 引用规则参见 xref:常规标题[]。
25
+ 引用规则依赖 xref:常规标题[常规标题, rel=depends-on, weight=strong]。
26
26
  ----
27
27
 
28
28
  源文档把 `常规标题` 写成可引用的阅读单位,在其下写出 `基本语法` 子标题,把 `引用规则` 写成规则说明,并在正文里写出参见和依赖两种引用。
29
29
 
30
- Turtle 示例中的 `<urn:aat:doc:...#heading-*>` 和 `<urn:aat:doc:...#xref-edge-*>` 表示投影生成的 IRI;`aat:addressLabel` 保留源文档中的寻址 label。
30
+ Turtle 示例中的 `<urn:aat:doc:...#heading-*>` 和 `<urn:aat:doc:...#xref-edge-*>` 表示投影生成的文档节点 IRI。本例没有为标题附加显式寻址标签,因此 `aat:addressLabel` 与标题文字一致。
31
31
 
32
32
  [source,turtle]
33
33
  ----
34
34
  <urn:aat:doc:...#heading-l3-o0> a aat:Heading ;
35
35
  aat:headline "常规标题" ;
36
- aat:addressLabel "regular-heading" ;
36
+ aat:addressLabel "常规标题" ;
37
37
  aat:role "concept" ;
38
38
  aat:containsDirectly <urn:aat:doc:...#heading-l8-o0> .
39
39
 
40
40
  <urn:aat:doc:...#heading-l8-o0> a aat:Heading ;
41
41
  aat:headline "基本语法" ;
42
- aat:addressLabel "basic-syntax" ;
42
+ aat:addressLabel "基本语法" ;
43
43
  aat:role "example" .
44
44
 
45
45
  <urn:aat:doc:...#heading-l13-o0> a aat:Heading ;
46
46
  aat:headline "引用规则" ;
47
- aat:addressLabel "xref-rule" ;
47
+ aat:addressLabel "引用规则" ;
48
48
  aat:role "rule" ;
49
49
  aat:references <urn:aat:doc:...#heading-l3-o0> ;
50
50
  rel:depends-on <urn:aat:doc:...#heading-l3-o0> .
@@ -54,7 +54,7 @@ Turtle 示例中的 `<urn:aat:doc:...#heading-*>` 和 `<urn:aat:doc:...#xref-edg
54
54
  aat:weight "strong" .
55
55
  ----
56
56
 
57
- 读者看源文档,能直接看到 [.concept]#常规标题# 是被引用的阅读单位,`基本语法` 是它的下级标题, [.rule]#引用规则# 说明引用写法。投影读取同一份源文档,为标题生成 IRI,并在标题节点上保留 `aat:headline`、`aat:addressLabel` 和 `aat:role`;标题层级投影为 `aat:containsDirectly`,xref 投影为 `aat:references` 和 `rel:depends-on`。
57
+ 源文档中的 [.concept]#常规标题# 是被引用的阅读单位,`基本语法` 是它的下级标题, [.rule]#引用规则# 说明引用写法。投影读取同一份源文档,为标题生成 IRI,并在标题节点上保留 `aat:headline`、`aat:addressLabel` 和 `aat:role`;标题层级投影为 `aat:containsDirectly`,xref 投影为 `aat:references` 和 `rel:depends-on`。
58
58
 
59
59
  [source,asciidoc]
60
60
  ----
@@ -65,8 +65,8 @@ Turtle 示例中的 `<urn:aat:doc:...#heading-*>` 和 `<urn:aat:doc:...#xref-edg
65
65
  ----
66
66
 
67
67
  此处的 `pass:[xref:贾宝玉]` 直接使用标题文本作为寻址地址,
68
- 因为“贾宝玉”在本书范围内唯一且不会变更为其他名称。
69
- 交叉引用宏语法是 `pass:[xref:target-id[optional-display-text]]` ,所以这里省略了别名,渲染引擎默认会展示标题文字。
68
+ 因为“贾宝玉”在当前书稿中作为唯一标题名称使用。
69
+ 交叉引用宏语法是 `pass:[xref:目标标题[可选显示文本]]`,所以这里省略了显示文本,渲染引擎默认会展示标题文字。
70
70
 
71
71
  '''
72
72
 
@@ -80,4 +80,4 @@ Turtle 示例中的 `<urn:aat:doc:...#heading-*>` 和 `<urn:aat:doc:...#xref-edg
80
80
  == REQ-2024-0088
81
81
  ----
82
82
 
83
- 引用时可以这样: `pass:[xref:REQ-2024-0088[REQ-2024-0088, rel=constrains]]`
83
+ `REQ-2024-0088` 是本书采用的编号名称。编号制度负责分配和唯一性,引用直接使用该编号:`pass:[xref:REQ-2024-0088[REQ-2024-0088, rel=constrains]]`
@@ -0,0 +1,55 @@
1
+ [#heading-address-and-xref]
2
+ == 标题、寻址与引用
3
+
4
+ 等号行创建标题和层级。标题给出当前规范名称;标题前的 attrlist 可以承载 role 和字段。
5
+
6
+ [source,asciidoc]
7
+ ----
8
+ [.concept]
9
+ == 常规标题
10
+ ----
11
+
12
+ `.concept` 标明标题在书中的作用。`常规标题` 是当前规范名称。
13
+
14
+ [source,asciidoc]
15
+ ----
16
+ 引用规则参见 xref:常规标题[]。
17
+ ----
18
+
19
+ 该 xref 投影为 `aat:references`,即默认引用谓词。
20
+
21
+ [source,asciidoc]
22
+ ----
23
+ 引用规则依赖 xref:常规标题[常规标题, rel=depends-on]。
24
+ ----
25
+
26
+ `rel=depends-on` 声明从当前标题到目标标题的依赖关系,投影为 `rel:depends-on`。
27
+
28
+ [source,asciidoc]
29
+ ----
30
+ [#catalog-entry-482]
31
+ == 宿舍集中备考者
32
+ ----
33
+
34
+ `catalog-entry-482` 是附加给标题的显式寻址标签。外部目录已经使用这个地址时,引用可以继续使用它;标题“宿舍集中备考者”仍是当前规范名称。本书各章开头的英文标签用于阅读器页面地址;它们负责找到章节。
35
+
36
+ [TIP]
37
+ ====
38
+ 1. 显式寻址标签只在已有技术地址、外部链接或阅读器页面需要保留时出现。没有这种需要时,标题直接承担引用地址。写法速查见 xref:structured-writing-quick-reference[附录 A:结构化写法速查];完整判断流程见 xref:structured-writing-decision-trees[附录 B:结构化写法决策树]。
39
+ 2. 按照书籍结构,跨越 `= 书名`、`= 卷/部`、`== 章` 这些大跨度的指代均需要使用 `xref` 手动标注,平衡隐式上下文的阅读压力。
40
+ ====
41
+
42
+ 标题声明角色后,其下级标题默认属于同一角色范围。下级标题可声明不同角色以切换语境。角色范围是阅读上的语境;投影、检查和查询工具只读标题自己写下的 role,下级标题不会因此被当作同一 role 的标题核对字段或列出。
43
+
44
+ 例如:
45
+
46
+ [source,asciidoc]
47
+ ----
48
+ [.rule]
49
+ == 引用规则
50
+
51
+ === 基本语法
52
+
53
+ [.example]
54
+ === 一个完整示例
55
+ ----
@@ -13,7 +13,7 @@ Part 目录和 Chapter 文件统一使用三位数 `0X0` 格式进行编排。
13
13
  ----
14
14
  parts/010-source-surface/
15
15
  parts/015-new-topic/ <1>
16
- parts/020-identity-and-relation/
16
+ parts/020-names-roles-and-relations/
17
17
 
18
18
  010-opening.adoc
19
19
  015-new-context.adoc <2>
@@ -31,6 +31,6 @@ parts/020-identity-and-relation/
31
31
 
32
32
  使用三位数 `0X0` 格式,能够解决书籍动态维护过程中编号格式的稳定。
33
33
 
34
- 标题文本保留语义名称。长期引用的标题使用显式 ID。
34
+ 编排号只安排源文件顺序。标题保存当前规范名称;引用用标题或已有的显式寻址标签找到标题。
35
35
 
36
- 编排号帮助维护者观察源文件顺序;显式 ID 帮助读者和工具链稳定引用标题。
36
+ 编排号、标题和寻址标签承担不同职责,不互相替代。
@@ -1 +1 @@
1
- 本部从一段源文档出发,展示读者看到的写作意图和投影得到的结构事实。
1
+ 标题、引用和文件路径同时构成书稿的阅读结构与可投影的源文档表面。
@@ -0,0 +1,20 @@
1
+ [#names-and-address-labels]
2
+ == 名称变化与寻址标签
3
+
4
+ 标题不只是排版上的显示文字。它是当前书稿采用的名称,也是读者、项目和引用者正在使用的名称。
5
+
6
+ [.population]
7
+ === 宿舍集中备考者
8
+
9
+ 别名::
10
+
11
+ * 宿舍高强度备考者(旧称)
12
+ * 宿舍备考学生(常用称呼)
13
+
14
+ 标题改成“宿舍集中备考者”后,书中的 xref 与装配引用随标题更新。“宿舍高强度备考者”仍有历史检索价值时,作为旧称保留在别名中。
15
+
16
+ 名称变得更准确时,改标题并更新引用。概念边界改变时,同时检查描述、纳入条件、排除条件、相关标题和既有结论。旧概念被拆分或废止时,保留历史标题,写明后续应使用的标题。
17
+
18
+ 显式寻址标签只保留已有的技术地址。带有语义的标签是地址别名,不替代标题,也不代替概念变化的审查。
19
+
20
+ 工具若要跨改名追踪同一条记录,由工具层保存不透明记录键。某次冻结内容的校验,由内容哈希或快照承担。标题继续保存当前规范名称。
@@ -1,22 +1,22 @@
1
- [#role-identity]
2
- == role 身份
1
+ [#heading-roles]
2
+ == 标题的 role
3
3
 
4
4
  role 写在标题 attrlist 的点号 token 位置。
5
5
 
6
6
  [source,asciidoc]
7
7
  ----
8
- [#regular-heading.concept]
8
+ [.concept]
9
9
  == 常规标题
10
10
 
11
- [#xref-rule.rule]
11
+ [.rule]
12
12
  == 引用规则
13
13
  ----
14
14
 
15
- `#regular-heading` 和 `#xref-rule` 是稳定 ID,`.concept` 和 `.rule` 是 role,标明标题身份。
15
+ `.concept` 和 `.rule` 是 role。它们说明标题在当前书中承担概念说明或规则说明的作用。
16
16
 
17
17
  [cols="1,2", options="header"]
18
18
  |===
19
- |写法 |读者看到的身份
19
+ |写法 |读者看到的作用
20
20
 
21
21
  |`[.concept]`
22
22
  |标记概念说明。
@@ -28,8 +28,10 @@ role 写在标题 attrlist 的点号 token 位置。
28
28
  |标记示例。
29
29
  |===
30
30
 
31
- role 的职责,是在全书范围内保持身份含义的稳定。
31
+ 同一个 role 在全书中保持同一种叙述作用。
32
32
 
33
33
  一本书使用的 role 种类和数量,取决于该领域的概念结构。每种 role 的语义在全书中保持唯一。
34
34
 
35
+ 全书的 role 词表写成约定声明,见 xref:declaring-conventions[声明本书的约定]。
36
+
35
37
  读者和工具链可以依据 role 进行导航文本和提取结构。
@@ -5,20 +5,22 @@
5
5
 
6
6
  [source,asciidoc]
7
7
  ----
8
- 引用规则参见 xref:regular-heading[常规标题]。
9
- 引用规则依赖 xref:regular-heading[常规标题, rel=depends-on]。
8
+ 引用规则参见 xref:常规标题[]。
9
+ 引用规则依赖 xref:常规标题[常规标题, rel=depends-on]。
10
10
  ----
11
11
 
12
12
  第一行投影为 `aat:references`,即默认引用谓词。第二行声明 `rel=depends-on`,投影为 `rel:depends-on`。
13
13
 
14
14
  `rel` 可以被读者和工具当作关系谓词,所以在全书范围内,每种 `rel` 谓词的语义需要保持唯一且不变。
15
15
 
16
+ 全书采用的 rel 谓词写成约定声明,见 xref:declaring-conventions[声明本书的约定]。下面列出常用的几种:
17
+
16
18
  [horizontal]
17
19
  depends-on:: 当前标题的判断、规则或操作以目标标题为依据。阅读顺序和先读建议使用普通 xref 表达。
18
20
  illustrates:: 当前标题提供目标标题的示例。
19
21
  defines:: 当前标题给出目标标题所代表对象的定义。
20
22
  constrains:: 当前标题对目标标题的合法写法或范围施加约束。
21
23
 
22
- 关系谓词描述标题之间的边。标题自身的身份使用 role 表达。
24
+ 关系谓词描述标题之间的边。标题在书中的作用由 role 表达。
23
25
 
24
26
  标题之间的阅读顺序和先读建议,使用普通 xref(默认 `aat:references`)表达。
@@ -0,0 +1 @@
1
+ 标题给出当前名称;寻址标签提供已有的技术地址;role 说明标题节点在书中的作用;rel 说明标题之间的关系。
@@ -5,10 +5,10 @@
5
5
 
6
6
  [source,asciidoc]
7
7
  ----
8
- [#example.example, owner=writing-team]
8
+ [.example, owner=writing-team]
9
9
  == 示例
10
10
 
11
- 示例说明 xref:regular-heading[常规标题, rel=illustrates, weight=strong]。
11
+ 示例说明 xref:常规标题[rel=illustrates, weight=strong]。
12
12
  ----
13
13
 
14
14
  `.example` 是 role。`owner=writing-team` 是标题附加字段。`weight=strong` 是 xref 边证据上的附加字段。
@@ -19,7 +19,7 @@
19
19
 
20
20
  [source,asciidoc]
21
21
  ----
22
- [#rule.example, status=active]
22
+ [.example, status=active]
23
23
  == 示例规则
24
24
 
25
25
  priority:: normal
@@ -30,6 +30,43 @@ summary::
30
30
  示例规则正文从这里开始。
31
31
  ----
32
32
 
33
- `priority:: normal` 和 `summary::` 属于 `示例规则` 标题的附加字段。投影时它们成为标题字段,例如 `aat:priority` 和 `aat:summary`。
33
+ `priority:: normal` 和 `summary::` 属于 `示例规则` 标题的附加字段。投影时它们成为标题字段,例如 `aat:priority` 和 `aat:summary`;`情况` 这样不是 ASCII 标识符的字段名投影为 `aat:field-` 加百分号编码。
34
+
35
+ 字段值需要附带代码块、表格或另一段正文时,用 `+` 把块挂到字段上。挂上来的块属于这个字段的值。
36
+
37
+ [source,asciidoc]
38
+ ------
39
+ [.rule, verdict=adapt]
40
+ == 关闭标签
41
+
42
+ 情况:: 关闭当前标签。
43
+ 规则:: 先结束输入法的组字,再关闭。
44
+ 出处:: `editorCommands.ts:835-839`。
45
+ +
46
+ [source,ts]
47
+ ----
48
+ closeActiveEditor()
49
+ ----
50
+ 判定:: 改写。
51
+ ------
52
+
53
+ `出处` 的值是出处那一行文字和挂上来的代码块。字段值按作者写下的原文保存:反引号、xref 和 include 指令都保留原样。
54
+
55
+ 没有 `+` 的块不属于字段。字段列表在那个块之前结束,块和它之后的内容都是标题的正文;块之后再写的描述列表也不再是字段。字段之间需要代码时,用 `+` 挂上,不要直接插入代码块。
56
+
57
+ 另有三种写法让整串描述列表都不算字段,标题一个字段也得不到:标题与描述列表之间有别的块(段落、提示块、代码块、图片等);描述列表带 style(如 `[horizontal]`)、ID、块标题或其他块属性;某个条目里嵌套了描述列表。这时描述列表是标题的正文。反过来,要让标题正下方的描述列表是正文而不是字段,就在它前面放一段导语,或给它加 `[horizontal]` 等 style。
34
58
 
35
59
  字段名和字段值来自本书自己的约定。同一本书使用附加字段时,应保持字段写法和字段含义稳定。
60
+
61
+ [source,asciidoc]
62
+ ----
63
+ [.concept]
64
+ == 宿舍集中备考者
65
+
66
+ aliases::
67
+
68
+ * 宿舍高强度备考者(旧称)
69
+ * 宿舍备考学生(常用称呼)
70
+ ----
71
+
72
+ `aliases` 记录其他名称;它不取代标题,也不作为隐藏的第二个规范名称。
@@ -1,6 +1,6 @@
1
1
  [#glossary-conventions]
2
2
  == 术语表
3
3
 
4
- 术语表记录本书采用的关键用词,并为它们给出稳定定义。role 标明标题身份,rel 标明引用关系。
4
+ 术语表记录本书采用的关键用词。规范名称、显式寻址标签、别名、role、rel 和附加字段分别指向不同对象。
5
5
 
6
- 稳定术语帮助作者、读者和维护者使用同一组词理解源文档。术语的定义集中维护在书后的术语表中。
6
+ role 说明标题节点在书中的作用;rel 说明引用边表达的关系。术语的定义集中维护在书后的术语表中。
@@ -0,0 +1,70 @@
1
+ [#declaring-conventions]
2
+ == 声明本书的约定
3
+
4
+ 一本书采用的 role、rel、字段取值和字段构成它的约定。约定写在书里:读者从这里知道每个词的含义,检查脚本和查询工具从同一处读出受控词表。词表只写这一处,书和工具不会各说各的。
5
+
6
+ 声明约定的标题带 `.convention` role 和 `declares` 字段。声明的内容写成标题下的第一个连续描述列表:每个 term 是一个词,描述是这个词的含义。
7
+
8
+ [source,asciidoc]
9
+ ----
10
+ [.convention, declares=roles]
11
+ === 标题的 role
12
+
13
+ concept:: 概念:本书使用的一个词及其含义。
14
+ rule:: 规则:一条可检查的写法规定。
15
+ example:: 示例:用一个具体场景说明抽象判断。
16
+ convention:: 约定:声明本书的 role、rel、字段取值或字段。
17
+
18
+ [.convention, declares=relations]
19
+ === 关系谓词
20
+
21
+ depends-on:: 当前标题的判断、规则或操作以目标标题为依据。
22
+ illustrates:: 当前标题提供目标标题的示例。
23
+ ----
24
+
25
+ `declares` 的取值说明描述列表里的 term 是什么:
26
+
27
+ [horizontal]
28
+ roles:: role 名称。写作时用在 `[.concept]` 的位置。
29
+ relations:: rel 谓词。写作时用在 `rel=depends-on` 的位置。
30
+ values:: 某个 role 的某个附加字段允许的取值。`for` 写这个 role,`field` 写字段名。
31
+ fields:: 某个 role 的标题下描述列表要写出的字段。`for` 写这个 role。这个 role 的标题带显式寻址标签、标签本身又是已有的技术地址时(例如规则的标签同时是测试的名字),可以再写 `id-prefix`,规定标签的开头,例如 `id-prefix=rule-`;一旦写了,这个 role 的每个标题都要写出以它开头的标签。
32
+
33
+ 字段取值和字段用同样的写法声明:
34
+
35
+ [source,asciidoc]
36
+ ----
37
+ [.convention, declares=values, for=rule, field=verdict]
38
+ ==== 规则的判定
39
+
40
+ adopt:: 照搬:理由成立,形式也照搬。
41
+ adapt:: 改写:理由成立,形式换成本项目更顺手的写法。
42
+ skip:: 不搬:只服务于原来的处境。
43
+
44
+ [.convention, declares=fields, for=rule]
45
+ ==== 规则的格式
46
+
47
+ 情况:: 在什么情况下。
48
+ 规则:: 发生什么。
49
+ 出处:: 依据的源文件与行号。
50
+ ----
51
+
52
+ `规则的判定` 说明:带 `.rule` 的标题写 `verdict` 字段,取值是 `adopt`、`adapt` 或 `skip`。`规则的格式` 说明:带 `.rule` 的标题,标题下的描述列表写出 `情况`、`规则` 和 `出处`。xref:surface-fields[附加字段] 中的 `关闭标签` 就是一条符合这两项声明的规则;它多写的 `判定` 字段不在声明里,声明只规定必须写出的字段。
53
+
54
+ 声明的写法:
55
+
56
+ * term 写词本身:写 `concept`,不写 `.concept`,也不加反引号。term 就是写作时使用的那个词。
57
+ * 声明的描述列表紧跟在声明标题之下,与标题之间没有别的块(段落、提示块、图片等);它不带 `[horizontal]` 等 style,也不带 ID、块标题或其他块属性,条目里不嵌套描述列表。违反任何一条,整串描述列表都是正文,声明标题读不出任何词。导语写在上一级标题里。
58
+ * 一个声明标题只声明一种内容。同一个 role 的取值和字段分开声明。
59
+ * `convention` 本身也写进 role 词表,因为声明标题使用这个 role。
60
+
61
+ 声明通常放在读者最先读到约定的地方,例如前言里的“本书的书写约定”一节;某个 role 的格式也可以放在最先使用这个 role 的部分。工具按 `.convention` role 找到声明,不依赖位置。
62
+
63
+ 检查脚本读出声明以后,对每个带 role 的标题核对,不论它写没写寻址标签:
64
+
65
+ * role 在 role 词表中。
66
+ * `declares=values` 声明的字段写了,取值在列表中。没有声明的附加字段(如 `owner`)不受约束;`.convention` 标题例外,它只带 `declares`、`for`、`field` 和 `id-prefix`。
67
+ * `declares=fields` 声明的字段全部写出。
68
+ * 声明了 `id-prefix` 时,标题写出寻址标签,标签以它开头。
69
+
70
+ 正文中的每个 xref,若带 `rel`,谓词在关系谓词词表中。约定变化时只改声明,检查跟着变。
@@ -1 +1 @@
1
- 本部展示字段和术语表。字段随源文档保留;术语表帮助读者统一理解本书采用的用词。
1
+ 字段补充标题与引用已经表达的内容;术语表统一全书采用的名称;约定声明把本书的 role、rel 和字段写成工具可读的词表。
@@ -46,7 +46,7 @@ v0.1, 2026-05
46
46
 
47
47
  |让源书稿保持可读,同时保留可被工具链读取的结构关系
48
48
  |xref:books/07-structured-writing-conventions/book.adoc[07 结构化书写约定标本]
49
- |它展示标题、稳定 ID、role、xref、rel 和附加字段如何形成结构化书稿表面。
49
+ |它展示标题、引用、role、xref、rel 和附加字段如何形成结构化书稿表面。
50
50
  |===
51
51
 
52
52
  == 样本书
@@ -58,7 +58,7 @@ v0.1, 2026-05
58
58
  * xref:books/04-reference-manual/book.adoc[04 参考手册]:结构选择、路径规则和引用模式。
59
59
  * xref:books/05-upper-volume/book.adoc[05 上册]:独立分卷的上册。
60
60
  * xref:books/06-lower-volume/book.adoc[06 下册]:独立分卷的下册,并用示例说明跨卷引用写法。
61
- * xref:books/07-structured-writing-conventions/book.adoc[07 结构化书写约定标本]:标题、稳定 ID、role、xref、rel 和附加字段的结构化写法。
61
+ * xref:books/07-structured-writing-conventions/book.adoc[07 结构化书写约定标本]:标题、引用、role、xref、rel 和附加字段的结构化写法。
62
62
 
63
63
  == 工作区地图
64
64
 
@@ -0,0 +1,24 @@
1
+ # My Books
2
+
3
+ An AsciiDoc multi-book workspace that starts with one book: `books/01-structured-writing-conventions`.
4
+
5
+ ## Commands
6
+
7
+ ```bash
8
+ pnpm install
9
+ pnpm run build # writes build/html/index.html
10
+ pnpm run check # checks the catalog, books, xrefs, anchors, and local HTML resources
11
+ pnpm run clean # removes build/
12
+ ```
13
+
14
+ To fetch diagram images into the local HTML output instead of linking Kroki URLs:
15
+
16
+ ```bash
17
+ ADOC_BOOKS_FETCH_DIAGRAMS=1 pnpm run build
18
+ ```
19
+
20
+ ## Add A Book
21
+
22
+ Copy `books/01-structured-writing-conventions` to `books/<NN-book-id>`, edit its `book.adoc`, then add an
23
+ `xref:books/<NN-book-id>/book.adoc[...]` line to `catalog.adoc`.
24
+ `pnpm run check` fails until `catalog.adoc` and `books/` list the same books.
@@ -0,0 +1,7 @@
1
+ = AsciiDoc 书架
2
+ :idprefix:
3
+ :idseparator: -
4
+
5
+ == 书目
6
+
7
+ * xref:books/01-structured-writing-conventions/book.adoc[01 结构化书写约定标本]:标题、引用、role、xref、rel 和附加字段的结构化写法。
@@ -1,47 +0,0 @@
1
- [#heading-and-xref]
2
- == 标题与引用
3
-
4
- 等号行声明标题和层级。标题前的 attrlist 承载地址、role 和字段。
5
-
6
- [source,asciidoc]
7
- ----
8
- [#regular-heading.concept]
9
- == 常规标题
10
- ----
11
-
12
- `[#regular-heading]` 声明一个稳定地址。 `.concept` 标明标题身份。 `常规标题` 是标题文本。
13
-
14
- [source,asciidoc]
15
- ----
16
- 引用规则参见 xref:regular-heading[常规标题]。
17
- ----
18
-
19
- 该 xref 投影为 `aat:references`,即默认引用谓词。
20
-
21
- [source,asciidoc]
22
- ----
23
- 引用规则依赖 xref:regular-heading[常规标题, rel=depends-on]。
24
- ----
25
-
26
- `rel=depends-on` 声明从当前标题到目标标题的依赖关系,投影为 `rel:depends-on`。
27
-
28
- [TIP]
29
- ====
30
- 1. 全书中手工声明的稳定地址至少需要一个 `xref` 消费。写法速查见 xref:structured-writing-quick-reference[附录 A:结构化写法速查];完整判断流程见 xref:structured-writing-decision-trees[附录 B:结构化写法决策树]。
31
- 2. 按照书籍结构,跨越 `= 书名`、`= 卷/部`、`== 章` 这些大跨度的指代均需要使用 `xref` 手动标注,平衡隐式上下文的阅读压力。
32
- ====
33
-
34
- 标题声明角色后,其下级标题默认属于同一角色范围。下级标题可声明不同角色以切换语境。
35
-
36
- 例如:
37
-
38
- [source,asciidoc]
39
- ----
40
- [.rule]
41
- == 引用规则
42
-
43
- === 基本语法
44
-
45
- [.example]
46
- === 一个完整示例
47
- ----
@@ -1 +0,0 @@
1
- 本部展示标题身份和引用关系。role 标明标题身份;rel 标明引用关系。 在书籍中,你需要主动根据你当前所建模的概念结构对各类词表(`role`、`rel` 或者其他更多)进行建模与约定,需要专门的词表约定章节清晰的写出你需要使用的受控词表,方便后续的使用。