RFC 015 - Structure, Views, and URIs
RFC 015: Structure, Views, and URIs
Section titled “RFC 015: Structure, Views, and URIs”Summary
Section titled “Summary”This RFC addresses four interrelated requirements for advancing the Vyasa document model:
- Views (Profiles): The ability to generate different output variations (e.g., “Reference/Chanting” vs. “Study”) from the same source content.
- Whole-Work Processing: Templates that operate on the entire collection (Book/Work) rather than just individual files.
- Scoped Metadata: Hierarchical metadata (titles for verse, chapter, canto, work) rather than flat file-scoped variables.
- Structural URNs: Constructing URIs based on the document hierarchy (
book.canto.chapter) rather than ad-hoc context variables.
1. Views (“Reference/Chanting” Mode)
Section titled “1. Views (“Reference/Chanting” Mode)”Body Projection Directive
Section titled “Body Projection Directive”A view template defines a body directive that acts as a whitelist and sequencer for document content.
- Whitelist: Only commands listed in
bodyappear in output. Everything else is implicitly excluded. - Sequencer: Commands appear in the order specified in
body, regardless of source document order. - Inheritance: Child templates (e.g.,
devanagariinsideverse) render normally using base templates fromcontext.vy.
reference.vy (entire file — verses only):
`body [ `verse ]study.vy (reordered — translation before verse):
`body [ `translation `verse `synonyms]Sibling Convention
Section titled “Sibling Convention”A .vy file paired with a .html file of the same name forms a view:
reference.html— the HTML shell (styles,{{ body }})reference.vy— the body projection (which commands, in what order)context.vy— shared base templates (loaded for all views)
2. Structural Templates (Implicit Layouts)
Section titled “2. Structural Templates (Implicit Layouts)”The default view (default.vy or context.vy) defines how all content types are rendered.
Without a body directive, all commands render in document order.
// context.vy — base templates for all views`verse [ `div { class="verse-box" } [ `div { class="verse-ref" } [ Verse $.argument ] `div { class="verse" } [ $.text ] ]]
`translation [ `div { class="translation-box" } [ $.text ]]3. Whole-Work Processing (“Collections”)
Section titled “3. Whole-Work Processing (“Collections”)”- Definition: A Collection refers to the aggregated set of all compilation units (individual
.vyfiles) that make up a single “Work” (Book). Currently, Vyasa compiles files in isolation. A “Collection Pass” is a post-compilation step that gathers all these compiled nodes into a single structure (The Work) for generating indices, TOCs, or single-page editions.
Proposed Solution: The Collection Object
The compiler performs a second pass where it exposes a work object to a master template (index.vy or work.vy).
4. Scoped Metadata & Flow Commands
Section titled “4. Scoped Metadata & Flow Commands”Problem
Section titled “Problem”User feedback highlights that using block-based commands for chapters (chapter { ... } [ ... ]) is tedious.
Revised Proposal: Flow-based State
Section titled “Revised Proposal: Flow-based State”We retain the “LaTeX-style” flow commands but improve their state management. Instead of loose variables, chapter updates a dedicated Structural Registry.
- Location: Often placed in
context.vyat the folder root. - Mandatory Fields:
idandtitleare required. Missing them is a Compiler Error. - Reset Logic: When a new Flow Command (like
chapterorcanto) is encountered, subordinate counters (likeverse) are automatically reset.
# This sets the interaction state.`chapter { title="Yoga of Despondency" id="1" }
# Notes:# 1. Pushes new Chapter to Registry.# 2. Resets Verse counter.# 3. Validates mandatory 'id' and 'title'.5. Structural URNs
Section titled “5. Structural URNs”Problem
Section titled “Problem”Nested structures are tedious. Explicit URNs are error-prone.
Revised Proposal: Prescriptive URN Scheme
Section titled “Revised Proposal: Prescriptive URN Scheme”We define the URN semantics once in configuration.
We simplify the placeholders to key names, implying the .id property.
vyasac.toml:
[urn]corpus = "vedabase.io:sb"hierarchy = ["canto", "chapter", "verse"]Content (1.vy):
`chapter { id="1" }`verse { id="1" } # -> urn:vyasa:bg:1:1:1Implicit Path-based Hierarchy Inference
Section titled “Implicit Path-based Hierarchy Inference”Instead of requiring repetitive context.vy files or flow commands in every stream folder just to define the chapter or canto, vyasac infers the hierarchy variables directly from the filesystem.
When a file is compiled (e.g., content/mula/18/78.vy), the compiler parses the relative path to the stream root:
- Path
18/78.vyhas components["18", "78.vy"]. - The file stem is extracted:
["18", "78"]. - These components are aligned with the
hierarchyarray backwards (since files are leaves):78aligns withverse-> setsverse=78in the document context.18aligns withchapter-> setschapter=18in the document context.
This makes the directory structure the single source of truth. Users can still use context.vy to provide folder-specific overrides (e.g. `set meta { author="Prabhupada" }) which take precedence over inferred values.
Compiler Validation, Warnings, and Errors
Section titled “Compiler Validation, Warnings, and Errors”To prevent users from making silent mistakes, the compiler generates warnings and errors during URN evaluation and path inference:
- Invalid Component Value (Warning): If a path component (e.g.,
13-17) is mapped to a hierarchy level but contains characters that violate strict URN formatting rules, a warning is generated. - Unresolved URN Variables (Error/Warning): If the URN scheme (e.g.,
urn:vyasa:bg:{chapter}:{verse}) is evaluated but{chapter}or{verse}cannot be resolved (meaning it wasn’t inferred from the path and wasn’t provided in acontext.vyor flow command), the compiler must generate a warning/error instead of silently leaving the literal{chapter}in the final URN.
Ad-hoc Markers & Segments
Section titled “Ad-hoc Markers & Segments”For addressing content within a compilation unit (e.g., a specific line or anchor):
- Path vs. Fragment: The Structural URN forms the Path (
urn:vyasa:bg:1:1:1). Markers and Segments form the Fragment (#...). - Collision Avoidance:
- Verse ID: Part of the URN Path (
...:1). - Marker ID: Part of the URN Fragment (
...:1#foo). They live in different namespaces and cannot clobber each other.
- Verse ID: Part of the URN Path (
- Disambiguation:
- Segments: Automatically indexed integers (
#1,#2). - Markers: Explicit string IDs (
#foo). If a marker ID is numeric, it shadows the segment index.
- Segments: Automatically indexed integers (
6. Multi-Verse Logic
Section titled “6. Multi-Verse Logic”When a single compilation unit represents a range of verses (e.g., 13-14.vy):
- URN Path: The file generates multiple URNs for the verses (
...:13,...:14). - URN Fragments: Any Markers or Segments within the content are semantically attached to the last verse in the range (
...:14#foo).- Rationale: Purports often reference the entire block, and the “anchor” is effectively the end of the sequence.
7. Command Context & Validity
Section titled “7. Command Context & Validity”To maintain strict separation of concerns, the compiler enforces Contextual Validity for commands.
-
Source Context (
book.vy):- Allowed: Semantic Commands (
verse,h1,p), Flow Commands (chapter), Ad-hoc Markers (mark,|). - Forbidden: Presentation Commands (
div,span, css classes). Usingdivin a source file is a Compiler Error.
- Allowed: Semantic Commands (
-
View Context (
template.vy,reference.vy):- Allowed: Presentation Commands (
div,span), Logic (if,each), Content Accessors ($.text). - Purpose: Defining how the semantic nodes are rendered.
- Allowed: Presentation Commands (
7. Template Convention: Sibling Pairing
Section titled “7. Template Convention: Sibling Pairing”We establish a flat convention for HTML generation:
- The Shell:
reference.html(Contains<html>,<head>, scripts, and{{ body }}). - The View:
reference.vy(Defines thebodyprojection — which commands to include and in what order). - Shared Logic:
context.vy(Base templates for all views. Loaded automatically;.vyfiles without a matching.htmlsibling are base templates).
The compiler automatically pairs them:
- Loads
context.vy(and any other unpaired.vyfiles) as base templates. - When
reference.htmlis selected, loadsreference.vyas view overrides. - Applies the
bodyprojection to filter/reorder document content. - Injects the rendered body into
reference.html.
8. Collection Templates (“Whole Work” Processing)
Section titled “8. Collection Templates (“Whole Work” Processing)”To generate indices, tables of contents, or glossaries, we introduce Collection Templates.
- Concept: Instead of processing a single content file, the compiler aggregates all compiled documents into a
Workobject. - Usage:
vyasac build --collection toc(looks fortemplates/html/toc.vy). - Context: The template receives a global
workobject containing a flat list or hierarchical tree of all compilation units.
9. Future Work: Segment Recitation Patterns (Ghana/Jata)
Section titled “9. Future Work: Segment Recitation Patterns (Ghana/Jata)”Oral traditions often require reciting segments in complex combinatorial patterns for memorization (e.g., Jata-patha, Ghana-patha).
- Requirement: Generate output where segments (identified by
|) are permuted according to a pattern. - Example: If a verse has segments
1 | 2 | 3:- Jata:
1-2-2-1,2-3-3-2.
- Jata:
- Design Implication: This will likely require a dedicated
transformpass or a specialized view helper (e.g.,{{#each (permute segments "1-2-2-1") }} ... {{/each}}) rather than simple static templates.
10. Update (2026-07): Composite URN Anchors & Zero-Bloat Projections
Section titled “10. Update (2026-07): Composite URN Anchors & Zero-Bloat Projections”When weaving interlinear content across parallel streams (e.g., Devanagari primary text vs. English commentary), a leaf sequence ID (e.g., bg:1:1) represents a Composite URN Anchor across all streams. However, the internal “shape” (sub-block composition) of that anchor varies by stream:
mula-deva: Contains a single primary text block (shlokaorverse).eng-prabhupada: Contains noverseblock, but instead contains three distinct sub-blocks:synonyms,translation, andpurport.
A. Zero-Bloat Projections in Compilation
Section titled “A. Zero-Bloat Projections in Compilation”To strictly adhere to the publication bloat invariant (with a target not exceeding 25% increase over raw source size), we avoid injecting verbose semantic wrapper attributes (e.g., <div class="vy-subblock vy-synonyms" data-block-type="synonyms">) into every stored row in html_blocks.
- Clean Projection Output: Each row in
html_blocksstores only the minimal HTML string output produced by the projection template (e.g.,<div class="set">...</div><div class="verse">...</div>), preserving structural semantic classes without redundant data attributes. - Runtime Weaving & Sideline Gutters: The viewer (via
VyasaViewerRuntimein WASM) joins fragments across selected streams forsequence_id = X. A 3-column grid layout positions the URN sequence anchor in the sticky left gutter, the leaf-block content in the center column, and localized interactive badges (speaker attributions, editorial notes) in the right gutter. - Graph-Based Discovery: Standalone metadata (such as speaker events and editorial notes) is extracted from peer
annotations/directories intograph_nodesandgraph_edgesduring compilation and localized at runtime using thevocabularytable, completely decoupling metadata discovery from textual content storage.