use crate::reference::Reference;
use crate::values::{ComponentValues, ProcHints, ProcValues, RenderOptions};
use citum_schema::template::{DelimiterPunctuation, TemplateGroup};
impl ComponentValues for TemplateGroup {
fn values<F: crate::render::format::OutputFormat<Output = String>>(
&self,
reference: &Reference,
hints: &ProcHints,
options: &RenderOptions<'_>,
) -> Option<ProcValues<F::Output>> {
let mut has_content = false;
let fmt = F::default();
let mut values = Vec::with_capacity(self.group.len());
for item in &self.group {
let Some(v) = item.values::<F>(reference, hints, options) else {
continue;
};
if v.value.is_empty() {
continue;
}
if !is_term_based(item) {
has_content = true;
}
let proc_item = crate::render::ProcTemplateComponent {
template_component: item.clone(),
template_index: options.current_template_index,
value: v.value,
prefix: v.prefix,
suffix: v.suffix,
url: v.url,
ref_type: Some(reference.ref_type().clone()),
config: Some(options.config.clone()),
bibliography_config: options.bibliography_config.clone(),
item_language: crate::values::effective_component_language(reference, item),
sentence_initial: false,
pre_formatted: v.pre_formatted,
};
let rendered = crate::render::render_component_with_format_and_renderer::<F>(
&proc_item,
&fmt,
options.show_semantics,
);
if !rendered.is_empty() {
values.push(rendered);
}
}
if values.is_empty() || !has_content {
return None;
}
let delimiter = self
.delimiter
.as_ref()
.unwrap_or(&DelimiterPunctuation::Comma)
.to_string_with_space();
Some(ProcValues {
value: fmt.join(values, &delimiter),
prefix: None,
suffix: None,
url: None,
substituted_key: None,
pre_formatted: true,
})
}
}
fn is_term_based(component: &citum_schema::template::TemplateComponent) -> bool {
use citum_schema::template::TemplateComponent;
match component {
TemplateComponent::Term(_) => true,
TemplateComponent::Group(l) => l.group.iter().all(is_term_based),
_ => false,
}
}