citum_engine/values/
list.rs1use crate::reference::Reference;
12use crate::values::{ComponentValues, ProcHints, ProcValues, RenderOptions};
13use citum_schema::template::{DelimiterPunctuation, TemplateGroup};
14
15impl ComponentValues for TemplateGroup {
16 fn values<F: crate::render::format::OutputFormat<Output = String>>(
17 &self,
18 reference: &Reference,
19 hints: &ProcHints,
20 options: &RenderOptions<'_>,
21 ) -> Option<ProcValues<F::Output>> {
22 let mut has_content = false;
23 let fmt = F::default();
24
25 let values: Vec<F::Output> = self
27 .group
28 .iter()
29 .filter_map(|item| {
30 let v = item.values::<F>(reference, hints, options)?;
31 if v.value.is_empty() {
32 return None;
33 }
34
35 if !is_term_based(item) {
37 has_content = true;
38 }
39
40 let proc_item = crate::render::ProcTemplateComponent {
42 template_component: item.clone(),
43 template_index: options.current_template_index,
44 value: v.value,
45 prefix: v.prefix,
46 suffix: v.suffix,
47 url: v.url,
48 ref_type: Some(reference.ref_type().clone()),
49 config: Some(options.config.clone()),
50 bibliography_config: options.bibliography_config.clone(),
51 item_language: crate::values::effective_component_language(reference, item),
52 sentence_initial: false,
53 pre_formatted: v.pre_formatted,
54 };
55
56 let rendered = crate::render::render_component_with_format_and_renderer::<F>(
57 &proc_item,
58 &fmt,
59 options.show_semantics,
60 );
61 if rendered.is_empty() {
62 None
63 } else {
64 Some(rendered)
65 }
66 })
67 .collect();
68
69 if values.is_empty() || !has_content {
70 return None;
71 }
72
73 let delimiter = self
75 .delimiter
76 .as_ref()
77 .unwrap_or(&DelimiterPunctuation::Comma)
78 .to_string_with_space();
79
80 Some(ProcValues {
81 value: fmt.join(values, &delimiter),
82 prefix: None,
83 suffix: None,
84 url: None,
85 substituted_key: None,
86 pre_formatted: true,
87 })
88 }
89}
90
91fn is_term_based(component: &citum_schema::template::TemplateComponent) -> bool {
93 use citum_schema::template::TemplateComponent;
94 match component {
95 TemplateComponent::Term(_) => true,
96 TemplateComponent::Group(l) => l.group.iter().all(is_term_based),
97 _ => false,
98 }
99}