wikioxide 0.1.0

MediaWiki wikitext parser producing typed domain models (templates, links, categories, warnings) with template expansion — no HTML, no network
Documentation
//! # wikioxide
//!
//! Parse MediaWiki wikitext into **typed domain models** — locally, deterministically and
//! without HTML: template calls with full parameter maps, categories with sort keys,
//! internal/external links, typed parser warnings and structural statistics, mirroring what
//! the Action API's `action=parse` reports for
//! `prop=templates|categories|links|externallinks|parsewarnings`.
//!
//! Configure a [`WikitextParser`] once per wiki (vendored presets for en/ru Wikipedia ship
//! behind the default `presets` feature), then parse any number of pages:
//!
//! ```
//! use wikioxide::{DocumentView, NamespaceDef, PageContext, SiteConfig, WikitextParser};
//!
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let config = SiteConfig::builder("ru", "Вики")
//!     .namespace(NamespaceDef::main())
//!     .namespace(NamespaceDef::new(10, "Template", "Шаблон", ["Ш"], true))
//!     .link_trail("a-zа-яё")
//!     .build()?;
//! let parser = WikitextParser::builder().site_config(config).build()?;
//!
//! let doc = parser.parse(
//!     "Стихи [[кота|котика]] в {{рамке|цвет=серый}}",
//!     &PageContext::default(),
//! );
//! assert_eq!(doc.links()[0].target().text(), "Кота");
//! assert_eq!(doc.links()[0].anchor_text(), Some("котика"));
//! assert_eq!(doc.templates()[0].title().text(), "Шаблон:Рамке");
//! assert_eq!(doc.templates()[0].param("цвет"), Some("серый"));
//! # Ok(())
//! # }
//! ```
//!
//! The parser is **total over input**: malformed wikitext yields a document plus typed
//! [`Warning`]s, never an error. Template expansion (with a pluggable template source)
//! arrives with the next milestone; today's [`ParsedDocument`] is the faithful *as-written*
//! view of a page.

#![cfg_attr(coverage_nightly, feature(coverage_attribute))]

mod clock;
mod config;
pub mod discussion;
mod doc;
mod engine;
mod error;
mod model;
mod parser;
#[allow(
    dead_code,
    reason = "the template/existence seams are consumed by the expansion engine landing next"
)]
mod source;
mod title;
mod warn;

pub use clock::{Clock, FixedClock, SystemClock, Timestamp};
pub use config::{
    ExtTagContent, Limits, MagicLinks, MagicWordDef, MonthNames, NamespaceDef, SiteConfig,
    SiteConfigBuilder,
};
pub use doc::{DocumentView, ExpandOutcome, ExpandedDocument, MissingTemplates, ParsedDocument};
pub use engine::expand::UnresolvedPolicy;
pub use error::{BuildError, ConfigError, TitleError};
pub use model::{
    CategoryLink, ExternalLink, InterLanguageLink, InternalLink, ModuleInvocation, Origin,
    Redirect, Section, Span, StructuralStats, TemplateCall,
};
pub use parser::{PageContext, WikitextParser, WikitextParserBuilder};
pub use source::{
    EmptyTemplateSource, ExistenceMap, ExistenceProvider, ExistenceRecord, InMemoryTemplateStore,
    ProviderError, TemplateFetch, TemplateSource,
};
pub use title::{Namespace, Title};
pub use warn::Warning;