asciidoc-abundant-tree 0.2.5 → 0.3.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.
package/README.md CHANGED
@@ -18,8 +18,8 @@ The pretty tree format is designed for terminal reading. Its shape is intentiona
18
18
  - Section, paragraph, description list, listing, table, title, metadata, target, anchor, and xref nodes.
19
19
  - Raw source text and source spans for recoverable authored surfaces.
20
20
  - A target catalog for sections, blocks, listings, tables, inline anchors, and block anchors.
21
- - Xref occurrence records that keep raw target text, labels, local/external/unresolved scope, containing section, and resolved target kind.
22
- - Official Asciidoctor binding data for xrefs: `href`, `resolvedId`, `resolvedType`, and `reftext`.
21
+ - Xref occurrence records for exactly the xrefs Asciidoctor recognizes, keeping raw target text, the selector they address, the document they name, labels, local/external scope, containing section, and resolved target kind.
22
+ - Official Asciidoctor binding data for xrefs: `href`, `refid`, `path`, `fragment`, `resolvedId`, `resolvedType`, and `reftext`.
23
23
  - Pretty tree output for terminal inspection and JSON output for automation.
24
24
  - Explicit book-entry mode for parsing an entry file plus supported full-file includes with origin source coordinates.
25
25
  - RDF 1.2 graph, Turtle, and JSON-LD output through the single `rdf12` projection for source-aware graph queries, frontend consumption, and line-based edit loops.
@@ -63,9 +63,9 @@ It is especially useful when a tool needs to answer questions such as:
63
63
 
64
64
  The `rdf12` projection derives an RDF 1.2 graph from an `AbundantDocument`. The source document remains the fact source, `AbundantDocument` is the input contract, and the RDF graph is the queryable projection.
65
65
 
66
- Projection resources use deterministic IRIs generated from the document coordinate system, not author strings or ordering facts. Heading nodes expose their label space directly through `aat:addressLabel`, `aat:generatedAddressLabel`, and `aat:headline`. Query code can use those fields to find headings, then read `relativePath`, `startLine`, and `endLine` for source inspection or patching.
66
+ A heading node is named after its address: the document IRI (`urn:aat:doc:` plus the source path) followed by `#` and the shortest address that only this heading owns, so queries read `<#炒糖色>` or `<#红烧肉::火候>` where a reference would write `xref:炒糖色[]` or `xref:红烧肉::火候[]`. The name is also emitted as `aat:name`. A heading is addressed by its headline as written, by `::`-joined suffixes of its headline path when headlines repeat, and by its custom or generated ID; selectors match these addresses as whole strings. Resources the projector names itself (provenance, xref edge evidence, raw value objects) live under `<document IRI>/projection#`. Query code can find headings through those fields, then read `relativePath`, `startLine`, and `endLine` for source inspection or patching.
67
67
 
68
- The graph includes source document provenance, heading nodes, direct heading containment, same-parent child order, global heading preorder, selector binding, xref edge evidence, RDF 1.2 reifiers for resolved xref relations, direct field predicates, and raw value objects. `aat:containsDirectly` expresses direct parent-child heading relationships, `aat:childOrder` orders direct children within the same parent, and `aat:documentOrder` orders all headings by logical preorder. Source coordinate fields such as `relativePath`, `startLine`, `endLine`, `headingLine`, and `raw` describe the origin source location and slice; they are not a heading order fallback. Xref edges keep raw selectors and official Asciidoctor evidence as separate facts. Attribute lists such as `[#delivery.policy, status=active]` preserve the explicit ID as `aat:addressLabel`, `.policy` as `aat:role`, and named fields as direct `aat:` predicates such as `aat:status`.
68
+ The graph includes source document provenance, heading nodes, direct heading containment, same-parent child order, global heading preorder, selector binding, xref edge evidence, RDF 1.2 reifiers for resolved xref relations, direct field predicates, and raw value objects. `aat:containsDirectly` expresses direct parent-child heading relationships, `aat:childOrder` orders direct children within the same parent, and `aat:documentOrder` orders all headings by logical preorder. Source coordinate fields such as `relativePath`, `startLine`, `endLine`, `headingLine`, and `raw` describe the origin source location and slice; they are not a heading order fallback. Xref edges keep raw selectors and official Asciidoctor evidence as separate facts. Attribute lists such as `[#delivery.policy, status=active]` preserve the explicit ID as `aat:addressLabel`, `.policy` as `aat:role`, and named fields as field predicates written as named, such as `field:status`; book-defined field names live under `field:`, apart from the projector's own `aat:` vocabulary.
69
69
 
70
70
  Local non-heading target IDs from listings, tables, blocks, inline anchors, and source value blocks become `aat:addressLabel` values on the owning heading. They participate in the heading label space without creating listing, table, block, anchor, or source-value-block structure resources.
71
71
 
@@ -73,7 +73,7 @@ The RDF 1.2 heading projection does not emit `aat:previousSibling`. Consumers th
73
73
 
74
74
  Heading complex properties use a `for` or `forSelector` marker to bind a raw value object to a heading through a field predicate. A marker with a selector value queries the heading label space; a no-value marker binds by source ownership. Edge complex properties use a named xref attribute such as `relation-evidence=<source-value-id>` and a source value block id to bind a raw value object to xref edge evidence through a field predicate. Field names come from source roles or xref named attribute keys; they determine the public query entry. Raw value format comes from the source block language such as `[source,json]` or `[source,yaml]`; raw value objects preserve raw text and source coordinates without separate kind, id, or role predicates. Raw value objects are opaque and are not expanded into business RDF predicates.
75
75
 
76
- Ordinary xref target selectors and xref field values use separate spaces. The xref target selector queries `aat:addressLabel`, `aat:generatedAddressLabel`, and `aat:headline`; a named xref attribute value queries source value ids. The `rel` control field is retained as `aat:rel` while selecting the main relation predicate, and xref named attribute keys become field predicates; neither is emitted as a legacy surface-attribute resource.
76
+ Ordinary xref target selectors and xref field values use separate spaces. The xref selector is the written target with its attribute references expanded and any document part cut off; it queries `aat:addressLabel`, `aat:generatedAddressLabel`, and `aat:headline`. An xref that names another document records it as `aat:targetDocument` and is not bound in this document. A named xref attribute value queries source value ids. The `rel` control field is retained as `aat:rel` while selecting the main relation predicate, and xref named attribute keys become field predicates; neither is emitted as a legacy surface-attribute resource.
77
77
 
78
78
  JSON-LD output is a frontend-friendly projection of the same RDF graph. RDF 1.2 triple terms are represented as structured `rdf12:TripleTerm` objects rather than flattened strings.
79
79
 
@@ -112,30 +112,33 @@ signals:
112
112
  Projected Turtle:
113
113
 
114
114
  ```turtle
115
+ @base <urn:aat:doc:book.adoc>.
115
116
  @prefix aat: <https://micheng.dev/ns/asciidoc-abundant-tree#>.
116
117
  @prefix rel: <https://micheng.dev/ns/asciidoc-relation#>.
118
+ @prefix field: <https://micheng.dev/ns/asciidoc-field#>.
117
119
  @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
118
120
 
119
- <urn:aat:doc:...#heading-l3-o0> a aat:Heading;
121
+ <#配送策略> a aat:Heading;
120
122
  aat:addressLabel "delivery", "rel-delivery-capacity";
121
123
  aat:headline "配送策略";
124
+ aat:name "配送策略";
122
125
  aat:role "policy";
123
- aat:policy-risk-profile <urn:aat:doc:...#payload-l8-o0>;
124
- rel:depends-on <urn:aat:doc:...#heading-l22-o0>.
126
+ field:policy-risk-profile <book.adoc/projection#payload-l8-o0>;
127
+ rel:depends-on <#运力规则>.
125
128
 
126
- <urn:aat:doc:...#payload-l8-o0> aat:forSelector "delivery";
129
+ <book.adoc/projection#payload-l8-o0> aat:forSelector "delivery";
127
130
  aat:format "json";
128
131
  aat:raw "{\"owner\":{\"team\":\"ops\"},\"risk\":{\"signals\":[\"capacity\"]}}".
129
132
 
130
- <urn:aat:doc:...#xref-edge-l6-c8-o0> rdf:reifies <<(<urn:aat:doc:...#heading-l3-o0> rel:depends-on <urn:aat:doc:...#heading-l22-o0>)>>;
133
+ <book.adoc/projection#xref-edge-l6-c8-o0> rdf:reifies <<(<#配送策略> rel:depends-on <#运力规则>)>>;
131
134
  a aat:XrefEdge;
132
- aat:sourceHeading <urn:aat:doc:...#heading-l3-o0>;
133
- aat:targetHeading <urn:aat:doc:...#heading-l22-o0>;
135
+ aat:sourceHeading <#配送策略>;
136
+ aat:targetHeading <#运力规则>;
134
137
  aat:targetSelector "capacity";
135
- aat:relation-evidence <urn:aat:doc:...#payload-l14-o0>;
138
+ field:relation-evidence <book.adoc/projection#payload-l14-o0>;
136
139
  aat:rel "depends-on".
137
140
 
138
- <urn:aat:doc:...#payload-l14-o0> aat:sourceValueId "rel-delivery-capacity";
141
+ <book.adoc/projection#payload-l14-o0> aat:sourceValueId "rel-delivery-capacity";
139
142
  aat:format "yaml";
140
143
  aat:raw "reason: risk-control\nsignals:\n - capacity".
141
144
  ```
@@ -297,7 +300,7 @@ const book = await parseAbundantTree({
297
300
 
298
301
  `attributes` are the include attributes as Asciidoctor parses them, the same an Asciidoctor include processor receives, so the bookshelf build and this parser can register the same selector. A blank positional attribute is `null`: the first one in `[,beta]`, the second one in `[beta,,gamma]`. A resolver that throws fails construction with `include.resolver-failed`; returned text that does not match its source leaves those lines without coordinates and reports `origin-map.selection-mismatch`.
299
302
 
300
- `parseAbundantTree` reads only the supplied source file. Interdocument xrefs keep their raw target and official href when Asciidoctor exposes one, but this package does not open the referenced `.adoc` file.
303
+ `parseAbundantTree` reads only the supplied source file. Interdocument xrefs keep their raw target, the document and selector they name, and the official href, but this package does not open the referenced `.adoc` file.
301
304
 
302
305
  Browser tools that already hold AsciiDoc source text can use the browser-safe subpath:
303
306
 
@@ -324,11 +327,11 @@ Source-layer fields describe the file surface: raw text, source line, line span,
324
327
 
325
328
  Official-layer fields describe Asciidoctor results: context, node name, href, resolved ID, resolved type, and reftext.
326
329
 
327
- The separation matters. Raw xref targets are not overwritten by official bindings, and official xref data is not inferred from ordinary links in converted HTML. Each source xref occurrence receives its official binding from the Asciidoctor xref conversion for that occurrence.
330
+ The separation matters. Raw xref targets are not overwritten by official bindings, and official xref data is not inferred from ordinary links in converted HTML. An xref exists where Asciidoctor's own substitution recognizes one, so passthroughs, escapes, attribute references, and fragments read the way Asciidoctor reads them; the parser only locates each one in the source, and the occurrence carries the facts of the xref node Asciidoctor created at that position.
328
331
 
329
332
  ## Example Tasks
330
333
 
331
- List unresolved local xrefs:
334
+ List the xrefs that name another document:
332
335
 
333
336
  ```ts
334
337
  import { parseAbundantTree } from "asciidoc-abundant-tree";
@@ -336,8 +339,10 @@ import { parseAbundantTree } from "asciidoc-abundant-tree";
336
339
  const document = await parseAbundantTree({ sourcePath: "docs/index.adoc" });
337
340
 
338
341
  for (const xref of document.xrefOccurrences) {
339
- if (xref.scope === "unresolved") {
340
- console.log(`${xref.target} at line ${xref.sourceSpan?.start.line}`);
342
+ if (xref.scope === "external") {
343
+ console.log(
344
+ `${xref.document}#${xref.selector ?? ""} at line ${xref.sourceSpan?.start.line}`,
345
+ );
341
346
  }
342
347
  }
343
348
  ```
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { o as exportAnimationYaml } from "../src-DdGRLADG.mjs";
2
+ import { o as exportAnimationYaml } from "../src-Dld2ZP6Z.mjs";
3
3
  import process from "node:process";
4
4
  //#region src/animation-yaml-export/cli.ts
5
5
  const USAGE = `Usage:
@@ -32,6 +32,9 @@ type AsciidoctorLayer = {
32
32
  context?: string;
33
33
  nodeName?: string;
34
34
  href?: string;
35
+ refid?: string;
36
+ path?: string;
37
+ fragment?: string;
35
38
  resolvedId?: string;
36
39
  resolvedType?: TargetType;
37
40
  reftext?: string;
@@ -145,12 +148,13 @@ type XrefOccurrenceNode = NodeBase & {
145
148
  syntax: "shorthand" | "macro";
146
149
  raw: string;
147
150
  target: string;
151
+ selector?: string;
152
+ document?: string;
148
153
  label?: string;
149
154
  attributes?: Record<string, string | number | boolean>;
150
155
  sourceSpan?: SourceSpan;
151
156
  containingSectionId?: string;
152
- scope?: "local" | "external" | "unresolved";
153
- targetKind?: string;
157
+ scope?: "local" | "external";
154
158
  };
155
159
  type AnchorOccurrenceNode = NodeBase & {
156
160
  kind: "anchor";