pub use rdx_ast::*;
pub use rdx_parser::parse;
mod transforms;
pub use transforms::abbreviation::AbbreviationExpand;
pub use transforms::auto_number::{AutoNumber, NumberEntry, NumberRegistry};
pub use transforms::citation_resolve::{BibEntry, CitationResolve, CitationStyle};
pub use transforms::cross_ref_resolve::CrossRefResolve;
pub use transforms::print_fallback::PrintFallback;
pub use transforms::slug::AutoSlug;
pub use transforms::strip_target::StripTarget;
pub use transforms::toc::TableOfContents;
pub trait Transform {
fn name(&self) -> &str;
fn transform(&self, root: &mut Root, source: &str);
}
pub struct Pipeline {
transforms: Vec<Box<dyn Transform>>,
}
impl Pipeline {
pub fn new() -> Self {
Pipeline {
transforms: Vec::new(),
}
}
#[allow(clippy::should_implement_trait)]
pub fn add(mut self, transform: impl Transform + 'static) -> Self {
self.transforms.push(Box::new(transform));
self
}
pub fn run(&self, input: &str) -> Root {
let mut root = parse(input);
for t in &self.transforms {
t.transform(&mut root, input);
}
root
}
pub fn apply(&self, root: &mut Root, source: &str) {
for t in &self.transforms {
t.transform(root, source);
}
}
}
impl Default for Pipeline {
fn default() -> Self {
Self::new()
}
}
pub fn parse_with_defaults(input: &str) -> Root {
Pipeline::new()
.add(AutoSlug::new())
.add(TableOfContents::default())
.run(input)
}
#[allow(clippy::ptr_arg)]
pub fn walk_mut(nodes: &mut Vec<Node>, f: &mut dyn FnMut(&mut Node)) {
for node in nodes.iter_mut() {
f(node);
if let Some(children) = node.children_mut() {
walk_mut(children, f);
}
}
}
pub fn walk<'a>(nodes: &'a [Node], f: &mut dyn FnMut(&'a Node)) {
for node in nodes {
f(node);
if let Some(children) = node.children() {
walk(children, f);
}
}
}
pub fn synthetic_pos() -> Position {
let pt = Point {
line: 0,
column: 0,
offset: 0,
};
Position {
start: pt.clone(),
end: pt,
}
}
pub fn collect_text(nodes: &[Node]) -> String {
let mut out = String::new();
walk(nodes, &mut |node| {
if let Node::Text(t) = node {
out.push_str(&t.value);
}
});
out
}