Skip to main content

Crate outlint_core

Crate outlint_core 

Source
Expand description

§outlint-core

Validate the header structure (outline) of Markdown documents against a declarative schema.

This is the pure, IO-free core: it turns source text into normalized values and diagnostics. It never touches the filesystem, the network, the terminal, or the process exit status — that shell is the outlint CLI crate. Callers supply the schema text, the Markdown text, and any linked JSON Schema resources they read themselves.

This is a 0.x release: expect breaking changes to the API, the schema language, and the diagnostic set before 1.0. The normative specification is spec/outlint-spec.md; where the two disagree, the specification wins.

§What it checks

  • Outline structure — the section tree built from ATX and Setext headings, including skipped heading levels.
  • Section rules — first-match-wins matchers (exact, glob, regex, *), allow: false denials, and strict scopes that reject unmatched headings.
  • Cardinalityrequired and repeat: "min..max" per rule, per scope.
  • Cross-section logicone_of, any_of, at_most_one, all_or_none, requires, conflicts, and ordered constraints over rules addressed by id.
  • YAML frontmatter — presence policy and delegated validation of the frontmatter mapping against an inline or linked JSON Schema (draft 2020-12). Inline schemas are self-contained and permit fragment-only references; linked schemas may span local files. Frontmatter also supports fm. propositions in constraints: fm.key presence and fm.key=value typed scalar equality under the YAML core schema, with dotted paths into nested mappings.

Diagnostics carry stable ids (missing-section, unexpected-section, ordered, frontmatter-schema, …), document source anchors, and structural schema-node addresses. Resolve a diagnostic’s schema_node through loaded.locations.nodes, then use the resulting SourceRange::source to find the source text and label in loaded.sources.documents.

§Usage

use outlint_core::{
    load_schema, parse_markdown, DiagnosticTarget, MarkdownOptions, PreparedValidator,
};

fn main() {
    // 1. Load a schema from YAML (or JSON) source text.
    let loaded = load_schema(
        r#"
version: 1
title: "*"
sections:
  - match: "Overview"
    required: true
"#,
    )
    .expect("schema is valid");

    // 2. Compile it once; reuse for any number of documents.
    let validator = PreparedValidator::new(&loaded.schema).expect("schema compiles");

    // 3. Parse Markdown into a section tree.
    let document = parse_markdown(
        "# Widget Redesign\n\n## Usage\n",
        MarkdownOptions {
            strip_inline_markup: loaded.schema.options.strip_inline_markup,
        },
    );

    // 4. Inspect the diagnostics. The target distinguishes a heading that is
    //    really there from a schema matcher that nothing matched.
    for diagnostic in validator.validate(&document) {
        let target = match &diagnostic.target {
            DiagnosticTarget::Header(path) => path.to_string(),
            DiagnosticTarget::MissingHeader { matcher, .. } => format!("expected {matcher}"),
            DiagnosticTarget::Document => "document".to_owned(),
            DiagnosticTarget::Frontmatter { .. } => "frontmatter".to_owned(),
        };
        println!(
            "{}:{} [{}] {} ({target})",
            diagnostic.location.line,
            diagnostic.location.column,
            diagnostic.id.as_str(),
            diagnostic.message,
        );
    }
}

Output:

1:1 [missing-section] matched 0 sections, but at least 1 are required (expected Overview)

load_schema returns Result<LoadedSchema, InvalidSchema>; InvalidSchema carries every schema error together with the source text needed to render it:

use outlint_core::load_schema;

if let Err(invalid) = load_schema("version: 99\n") {
    for error in invalid.errors.iter() {
        let source = &invalid.sources.documents[&error.range.source];
        eprintln!(
            "{} at bytes {}..{} in {}",
            error.kind.as_str(),
            error.range.range.start.0,
            error.range.range.end.0,
            source.label.as_ref().map_or("<schema>", |label| &label.0),
        );
    }
}

For schemas whose frontmatter.schema points at an external JSON Schema file, the caller owns the IO boundary. Use linked_frontmatter_schema_path to find the root path, assign that file an absolute logical URI, then walk its local reference graph with json_schema_external_references. The helper returns both the lexical physical_uri to read and the $id-aware logical_uri under which to register the contents. Ignore same-document references, deduplicate or cycle-check reads, record read failures rather than dropping them, and place every attempted resource in a LinkedJsonSchemaInput passed to load_schema_with_resources. Core never retrieves remote references.

§MSRV

Rust 1.86.

§License

Licensed under either of Apache License, Version 2.0 or MIT license at your option (MIT OR Apache-2.0).

Structs§

AtLeastTwo
A collection statically guaranteed to contain at least two items.
ByteOffset
A byte offset in UTF-8 source text.
CanonicalFloat
The canonical, arbitrary-precision value of a YAML float scalar.
CanonicalInteger
The canonical, arbitrary-precision value of a YAML integer scalar.
Cardinality
The permitted number of sibling headers matched by one rule.
ConstraintIndex
A zero-based constraint index within one scope’s constraint list.
ConstraintPath
The structural address of a constraint.
Diagnostic
One validation violation, with both document and schema-side anchors.
DiagnosticLocation
A source anchor in the Markdown document.
Document
A Markdown document represented as the forest of its topmost sections.
ExactText
Literal text used by an exact matcher.
FrontmatterAnchor
Source position of one entry inside a YAML frontmatter block.
FrontmatterAnchors
Positions of the entries of a frontmatter mapping, keyed by JSON Pointer.
FrontmatterBlock
The frontmatter block a diagnostic is about, and the value within it.
FrontmatterKey
A frontmatter mapping key addressable by the fm. syntax.
FrontmatterLineRange
One-based inclusive line range.
FrontmatterLocation
Source extent of a YAML frontmatter block.
FrontmatterRef
A normalized fm. frontmatter proposition.
FrontmatterSchema
An opaque, normalized JSON Schema resource graph.
GlobPattern
The validated body of a glob matcher.
HeaderPath
A path of case-preserving visible heading texts.
Heading
A normalized and positioned Markdown heading.
HeadingLocation
Source position of a Markdown heading.
InvalidSchema
A schema document that could not be converted into a valid Schema.
InvolvedHeader
A concrete header relevant to a constraint violation.
JsonSchemaExternalReference
One external JSON Schema document reference resolved for both I/O and validation.
JsonSchemaResourceInput
One attempted JSON Schema resource supplied to the pure schema loader.
LinkedJsonSchemaInput
Complete immutable input graph for one linked frontmatter JSON Schema.
LoadedSchema
A valid semantic schema together with its source provenance.
MarkdownOptions
Options that affect conversion of a Markdown heading into matcher text.
NonEmpty
A collection statically guaranteed to contain at least one item.
Options
Options controlling Markdown parsing and matcher behavior.
PrepareValidationError
Failure to prepare a reusable validator from a semantic schema.
PreparedValidator
A schema compiled once for validating any number of documents.
RegexPattern
The validated body of a regular-expression matcher, without / delimiters.
RelatedLocation
A secondary source range attached to a schema error.
RuleId
A validated rule identifier.
RuleIndex
A zero-based rule index within one sibling rule list.
RulePath
The structural address of a section rule.
RuleRef
A normalized reference to a rule path.
Schema
A parsed Outlint schema.
SchemaError
A positioned error produced while loading a schema.
SchemaLocations
Side-car locations for nodes in a successfully built Schema.
SchemaSource
The available source text and optional display name of a schema document.
SchemaSources
All source documents participating in one schema load.
ScopePath
A path to a rule-owned child scope.
Section
A section opened by one Markdown heading.
SectionRule
A rule for headers within one scope.
SourceId
The identity of one source within SchemaSources.
SourceLabel
A human-readable name for a schema source.
SourceRange
A byte range associated with one source in SchemaSources.
SuppressedDiagnostic
A diagnostic identifier named by an Outlint suppression directive.
Suppressions
The distinct diagnostic ids disabled at one suppression scope.
TextRange
A half-open byte range in SchemaSource::text.

Enums§

Constraint
A cross-section presence or ordering constraint.
DiagnosticId
A stable identifier from the diagnostic vocabulary in specification §6.
DiagnosticReference
A normalized constraint reference retained for diagnostic presentation.
DiagnosticTarget
What a diagnostic is about.
DocumentFrontmatter
Frontmatter extracted from the first lines of a Markdown document.
FrontmatterPolicy
The document’s normalized frontmatter policy.
FrontmatterScalar
A scalar resolved according to the YAML 1.2 core schema.
HeaderLevel
A Markdown ATX header level.
JsonSchemaResourceContents
Contents of one attempted linked JSON Schema resource read.
Matcher
A normalized header matcher.
OutlineProvenance
The surface form a schema used to declare its h1 level.
Proposition
A proposition accepted by presence constraints.
RefAnchor
The starting scope for resolving a rule reference.
RuleOutcome
The result of matching a header against a section rule.
SchemaErrorKind
Machine-readable categories for schema loading failures.
SchemaNode
The address of a semantic schema node with retained source provenance.
SchemaVersion
A supported version of the Outlint schema language.
UpperBound
The inclusive upper bound of a rule’s cardinality.

Functions§

json_schema_external_references
Finds external documents referenced from one draft 2020-12 resource.
linked_frontmatter_schema_path
Returns the linked frontmatter schema path declared by valid outer YAML.
load_schema
Loads an Outlint schema from UTF-8 source text.
load_schema_with_label
Loads an Outlint schema from source text with a diagnostic display label.
load_schema_with_resources
Loads an Outlint schema with an already-preloaded linked JSON Schema graph.
parse_markdown
Parses source text into Outlint’s positioned Markdown section model.
validate
Prepares and validates one document.

Type Aliases§

LoadSchemaResult
The result of parsing, validating, and normalizing a schema document.