mod bibliography;
mod citation;
mod note_context;
mod setup;
pub mod disambiguation;
pub mod document;
pub mod labels;
pub mod matching;
pub mod rendering;
pub mod sorting;
#[cfg(test)]
#[allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::panic,
clippy::indexing_slicing,
clippy::todo,
clippy::unimplemented,
clippy::unreachable,
clippy::get_unwrap,
reason = "Panicking is acceptable and often desired in tests."
)]
mod tests;
use crate::reference::Bibliography;
use crate::render::ProcEntry;
use crate::values::ProcHints;
use citum_schema::Style;
use citum_schema::locale::Locale;
use citum_schema::options::Config;
use indexmap::IndexMap;
use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
#[derive(Debug)]
pub struct Processor {
pub style: Style,
pub bibliography: Bibliography,
pub locale: Locale,
pub default_config: Config,
pub hints: HashMap<String, ProcHints>,
pub citation_numbers: RefCell<HashMap<String, usize>>,
pub cited_ids: RefCell<HashSet<String>>,
pub compound_sets: IndexMap<String, Vec<String>>,
pub compound_set_by_ref: HashMap<String, String>,
pub compound_member_index: HashMap<String, usize>,
pub compound_groups: RefCell<IndexMap<usize, Vec<String>>>,
pub dynamic_compound_set_by_ref: RefCell<HashMap<String, String>>,
pub dynamic_compound_member_index: RefCell<HashMap<String, usize>>,
pub dynamic_compound_sets: RefCell<IndexMap<String, Vec<String>>>,
pub show_semantics: bool,
pub inject_ast_indices: bool,
pub abbreviation_map: Option<crate::api::AbbreviationMap>,
}
#[derive(Debug, Default)]
pub struct ProcessedReferences {
pub bibliography: Vec<ProcEntry>,
pub citations: Option<Vec<String>>,
}
pub fn validate_compound_sets(
sets: Option<IndexMap<String, Vec<String>>>,
bibliography: &Bibliography,
) -> Result<Option<IndexMap<String, Vec<String>>>, crate::error::ProcessorError> {
let Some(sets) = sets else {
return Ok(None);
};
let mut member_owner: HashMap<String, String> = HashMap::new();
for (set_id, members) in &sets {
let mut seen_in_set: std::collections::HashSet<String> = std::collections::HashSet::new();
for member in members {
if !seen_in_set.insert(member.clone()) {
return Err(crate::error::ProcessorError::ParseError(
"BIBLIOGRAPHY".to_string(),
format!(
"reference '{member}' appears more than once in compound set '{set_id}'"
),
));
}
if !bibliography.contains_key(member) {
return Err(crate::error::ProcessorError::ParseError(
"BIBLIOGRAPHY".to_string(),
format!("compound set '{set_id}' references unknown id '{member}'"),
));
}
if let Some(existing) = member_owner.insert(member.clone(), set_id.clone()) {
return Err(crate::error::ProcessorError::ParseError(
"BIBLIOGRAPHY".to_string(),
format!(
"reference '{member}' appears in both compound sets '{existing}' and '{set_id}'"
),
));
}
}
}
Ok(Some(sets))
}