docs/library.mdtype: Reference
One type per spec concern.
The OKF4net namespace mirrors the spec: Bundle (§3), ConceptId (§2), OkfDocument/Frontmatter (§4), links (§5, §8), IndexGenerator (§6), ChangeLog (§7), BundleValidator (§9). Zero third-party dependencies — the YAML subset and link scanner are the library's own.
##
At a glance
load · validate · traverseusing OKF4net;
var bundle = Bundle.Load("./my_bundle"); // §3 — permissive walk
var report = BundleValidator.Validate(bundle); // §9 — diagnostics
Console.WriteLine(report.IsConformant
? $"conformant with OKF v{OkfSpec.Version}" : $"{report.ErrorCount} error(s)");
var id = ConceptId.Parse("tables/orders"); // §2
foreach (var link in bundle.LinksFrom(id)) // §5
Console.WriteLine($"{id} -> {link.Target} (exists: {link.Exists})");
foreach (var back in bundle.Backlinks(id))
Console.WriteLine($"cited by {back}");##
Bundle
§3 — a directory of conceptsBundle.Load walks the tree, parses every concept, and builds the cross-link graph. It is permissive: a bad file lands in ParseErrors and never aborts the load.
| Member | Description |
|---|
| Load(string root) → Bundle | Walk a directory and build the graph. Throws BundleLoadException only when the root itself is unreadable. |
| Root → string | The bundle's root path. |
| Concepts → IReadOnlyList<Concept> | All parsed concepts, in component-wise walk order. |
| Count → int · IsEmpty → bool | Number of concepts. |
| Get(ConceptId) → Concept? | Look up one concept; null if absent. |
| Contains(ConceptId) → bool | Whether the id resolves. |
| LinksFrom(ConceptId) → IReadOnlyList<ResolvedLink> | Outgoing links, each flagged Exists. |
| Backlinks(ConceptId) → IReadOnlyList<ConceptId> | Concepts that link to this one. |
| BrokenLinks() → IReadOnlyList<(ConceptId, string)> | Every edge to a missing concept. |
| IndexFiles · LogFiles → IReadOnlyList<string> | Reserved index.md / log.md paths found. |
| ParseErrors → IReadOnlyList<(string Path, string Error)> | Files that failed to parse, with why. |
| Concept | Record: Id, Path, Document. |
##
ConceptId
§2 — id ↔ pathA concept id is the file path with .md removed, as ordered segments. Sortable and value-equal.
| Member | Description |
|---|
| Parse(string) → ConceptId | Parse "tables/orders"; throws ConceptIdException on an invalid segment. |
| TryParse(string, out ConceptId?) → bool | Non-throwing parse. |
| FromPath(root, path) → ConceptId | Derive an id from a file path under a bundle root. |
| ToPath(root) → string | Inverse: the .md file path under a root. |
| Segments → IReadOnlyList<string> | The path components. |
| Name → string · Parent → ConceptId? | Last segment; id of the containing directory. |
| ValidateSegment(string) | Throw if a single segment is not spec-legal. |
##
OkfDocument & Frontmatter
§4 — one conceptFrontmatter keeps the full ordered mapping and layers typed getters on top, so producer-defined keys survive round-trips. Two validation levels: ValidateConformance() enforces only §9 (non-empty type); Validate() is the stricter producer check (type, title, description, timestamp).
| OkfDocument | Description |
|---|
| Parse(string) → OkfDocument | Parse frontmatter + body; throws DocumentParseException. |
| TryParse(string, out doc, out error) → bool | Non-throwing parse. |
| Serialize() → string | Re-emit; preserves key order and unknown keys. |
| Validate() · ValidateConformance() | Producer check / §9 check; throw DocumentValidationException. |
| Links() → IReadOnlyList<ConceptLink> | Markdown links in the body. |
| Citations() → IReadOnlyList<Citation> | Numbered citations in the body. |
| Frontmatter → Frontmatter · Body → string | The two halves of the document. |
| Frontmatter | Description |
|---|
| Type · Title · Description · Resource · Timestamp → string? | Typed getters over the mapping. |
| Tags → IReadOnlyList<string> | The tags sequence, or empty. |
| ExtensionKeys → IReadOnlyList<string> | Producer-defined keys beyond the reserved set. |
| AsMapping() → YamlMapping | The underlying ordered mapping. |
| Set(string, YamlValue) · FromMapping(YamlMapping) | Mutate a key / wrap an existing mapping. |
##
The YAML subset
Yaml — frontmatter onlyA documented subset: scalars, sequences, shallow maps, block and flow styles, |/> block scalars. It rejects anchors, tags, and multi-document streams with clear errors — frontmatter never needs them.
| Member | Description |
|---|
| YamlValue.Parse(string) → YamlValue | Parse the subset; throws YamlParseException (with a line number). |
| YamlEmitter.Emit(YamlValue) → string | Serialize back to the same subset. |
| AsString() · AsBool() · AsSequence() · AsMapping() | Typed views; null if the node is another kind. |
| ToYamlString() → string | Emit a single value. |
| YamlMapping: Get · ContainsKey · Entries · Keys · Count | Order-preserving map access. |
##
Links & citations
§5, §8 — the graph edges| Member | Description |
|---|
| LinkScanner.ExtractLinks(body) → IReadOnlyList<ConceptLink> | Markdown links, classified by LinkKind. |
| LinkScanner.ExtractCitations(body) → IReadOnlyList<Citation> | Numbered [n] citations. |
| ConceptLink(Text, Target, Kind) | A link; Resolve(source) → ConceptId? turns it into a target id. |
| ResolvedLink(Target, Exists, Text, Raw) | A link resolved against the bundle — Exists tells you if the target is real. |
| Citation(Number, Text, Target, Raw) | One numbered citation. |
| LinkKind | Enum: absolute vs relative link classification. |
##
IndexGenerator & ChangeLog
§6, §7 — reserved files| Member | Description |
|---|
| IndexGenerator.RegenerateIndexes(root) → IReadOnlyList<string> | Write every index.md; returns the paths written. |
| RegenerateIndexesWith(root, Synthesize) | Same, with a custom description synthesizer. |
| BuildIndexText(entries) → string | Render one listing without touching disk. |
| IndexEntry(Type, Title, Link, Description) | One row of a generated index. |
| ChangeLog: Days · Title · ToMarkdown() · InvalidDates() | Parse / render a log.md (§7); IsIsoDate(s) validates a date. |
| LogDay(Date, Entries) · LogEntry(Kind, Text) | A day's block and one entry. |
##
Validation
§9 — conformance| Member | Description |
|---|
| BundleValidator.Validate(Bundle) → ValidationReport | Run the §9 conformance check. |
| ValidationReport.IsConformant → bool | True when there are no Error diagnostics. |
| Diagnostics → IReadOnlyList<Diagnostic> | Every finding; Of(severity) filters. |
| ErrorCount · WarningCount → int | Tallies by severity. |
| Diagnostic(Severity, Path, Concept, Message) | One finding; ToString() is the CLI line. |
| Severity | Enum: Error, Warning, Info. |
| OkfSpec.Version → string | The implemented spec version ("0.1"). |
##
Errors
one base exceptionEvery library exception derives from OkfException, so one catch covers the surface. Loading is permissive, so most day-to-day work throws nothing — failures accumulate in ParseErrors instead.
| Exception | Thrown by |
|---|
| OkfException | Base type for all of the below. |
| ConceptIdException | ConceptId.Parse / ValidateSegment. |
| BundleLoadException | Bundle.Load, when the root is unreadable. |
| DocumentParseException | OkfDocument.Parse. |
| DocumentValidationException | Validate / ValidateConformance. |
| YamlParseException | The YAML subset parser (carries a Line). |
→ cli.md — the same engine as a binary · getting-started.md