1use doing_config::Config;
2use doing_taskpaper::Entry;
3use doing_time::{DurationFormat, FormattedDuration};
4use indexmap::IndexMap;
5
6pub fn format_interval(entry: &Entry, config: &Config) -> Option<String> {
8 entry.interval().and_then(|iv| {
9 let fmt = DurationFormat::from_config(&config.interval_format);
10 let formatted = FormattedDuration::new(iv, fmt).to_string();
11 if formatted == "00:00:00" { None } else { Some(formatted) }
12 })
13}
14
15pub fn group_by_section(entries: &[Entry]) -> Vec<(&str, Vec<&Entry>)> {
17 let mut map: IndexMap<&str, Vec<&Entry>> = IndexMap::new();
18 for entry in entries {
19 map.entry(entry.section()).or_default().push(entry);
20 }
21 map.into_iter().collect()
22}
23
24pub fn note_to_html_list(entry: &Entry, css_class: &str, escape: fn(&str) -> String) -> String {
28 if entry.note().is_empty() {
29 return String::new();
30 }
31
32 let items: Vec<String> = entry
33 .note()
34 .lines()
35 .iter()
36 .map(|line| format!("<li>{}</li>", escape(line.trim())))
37 .collect();
38
39 format!(r#"<ul class="{css_class}">{}</ul>"#, items.join(""))
40}