diary_cli/
export.rs

1use std::path::Path;
2use crate::{entry::{Entry, Section}, Scribe, scribe_write, archive::Archive, search, moc::{MOC, Collection}, sort::sort_uids};
3use soulog::*;
4
5pub fn export_md(strict: bool, tags: Option<Vec<String>>, path: String, mut logger: impl Logger) {
6    log!((logger) Export("Exporting archive to path '{path}'..."));
7    let archive = Archive::load(logger.hollow());
8
9    // Get entries and mocs
10    let mut entries = match &tags {
11        Some(x) => 
12            (if strict { search::search(x, archive.list_entries(logger.hollow()), logger.hollow()) }
13            else { search::search_strict(x, archive.list_entries(logger.hollow()), logger.hollow()) })
14                .into_iter().map(|x| archive.get_entry(x, logger.hollow()).unwrap()).collect(),
15        None => archive.list_entries(logger.hollow()),
16    };
17    let mut mocs = match &tags {
18        Some(x) => 
19            (if strict { search::search(x, archive.list_mocs(logger.hollow()), logger.hollow()) }
20            else { search::search_strict(x, archive.list_mocs(logger.hollow()), logger.hollow()) })
21                .into_iter().map(|x| archive.get_moc(x, logger.hollow()).unwrap()).collect(),
22        None => archive.list_mocs(logger.hollow()),
23    };
24
25    // Export em
26    let path = Path::new(&path);
27    entries.iter_mut().for_each(|x| export_entry(path, x, logger.hollow()));
28    mocs.iter_mut().for_each(|x| export_moc(path, x, &archive, logger.hollow()));
29
30    log!((logger.vital) Export("Successfully exported all specified items") as Log);
31}
32
33pub fn export_entry(path: &Path, entry: &mut Entry, mut logger: impl Logger) {
34    log!((logger) Export("Exporting entry of uid '{}'...", entry.uid));
35    let mut scribe = Scribe::new(path.join(&entry.uid).with_extension("md"), logger.hollow());
36
37    // Tags, title and description
38    let date = *entry.date(logger.hollow());
39    scribe_tags_n_date(entry.tags(logger.hollow()), &date, &mut scribe);
40    scribe_write!((scribe) "# ", entry.title(logger.hollow()), "\n");
41    scribe.write_line("---");
42    scribe_write!((scribe) "**Description:** ", entry.description(logger.hollow()), "\n\n");
43
44    // Notes
45    let notes = entry.notes(logger.hollow());
46    let mut notes_header_written_to: bool = false;
47    if notes.len() > 0 {
48        notes_header_written_to = true;
49        scribe.write_line("## Notes");
50        notes.iter().for_each(|x| scribe_write!((scribe) "- ", x, "\n"));  
51    }
52
53    // Sections' notes
54    entry.sections(logger.hollow()).iter_mut().for_each(|section| {
55        let title = section.title(logger.hollow()).clone();
56        let notes = section.notes(logger.hollow());
57        if notes.len() > 0 {
58            if !notes_header_written_to { scribe.write_line("## Notes"); notes_header_written_to = true; }
59            scribe_write!((scribe) "- #### ", &title, "\n");
60            notes.iter().for_each(|x| scribe_write!((scribe) "\t- ", x, "\n"));
61        } section.clear_cache();
62    });
63    scribe.write_line("---");
64
65    // Sections
66    entry.sections(logger.hollow()).iter_mut().for_each(|x| export_section_content(&mut scribe, x, logger.hollow()));
67
68    entry.clear_cache();
69}
70
71pub fn export_moc(path: &Path, moc: &mut MOC, archive: &Archive, mut logger: impl Logger) {
72    log!((logger) Export("Exporting moc of uid '{}'...", moc.uid));
73    let mut scribe = Scribe::new(path.join(&moc.uid).with_extension("md"), logger.hollow());
74
75    // Tags, title and description
76    scribe_tags(moc.tags(logger.hollow()), &mut scribe);
77    scribe_write!((scribe) "# ", moc.title(logger.hollow()), "\n");
78    scribe.write_line("---");
79    scribe_write!((scribe) "**Description:** ", moc.description(logger.hollow()), "\n\n");
80
81    // Notes
82    let notes = moc.notes(logger.hollow());
83    if notes.len() > 0 {
84        scribe.write_line("## Notes");
85        notes.iter().for_each(|x| scribe_write!((scribe) "- ", x, "\n"));  
86    }
87
88    // Collections' notes
89    moc.collections(logger.hollow()).iter_mut().for_each(|collection| {
90        let title = collection.title(logger.hollow()).clone();
91        let notes = collection.notes(logger.hollow());
92        if notes.len() > 0 {
93            scribe_write!((scribe) "- #### ", &title, "\n");
94            notes.iter().for_each(|x| scribe_write!((scribe) "\t- ", x, "\n"));
95        } collection.clear_cache();
96    });
97    scribe.write_line("---");
98
99    // Collections
100    moc.collections(logger.hollow()).iter_mut().for_each(|x| export_collection_content(&mut scribe, x, archive, logger.hollow()));
101
102    moc.clear_cache();
103}
104
105fn export_collection_content(scribe: &mut Scribe<impl Logger>, collection: &mut Collection, archive: &Archive, logger: impl Logger) {
106    let tags = collection.include(logger.hollow());
107
108    let moc_uids = search::search_strict(tags, archive.list_mocs(logger.hollow()), logger.hollow());
109    let mut entry_uids = search::search_strict(tags, archive.list_entries(logger.hollow()), logger.hollow());
110
111    if moc_uids.is_empty() && entry_uids.is_empty() { return; }
112    scribe_write!((scribe) "## ", collection.title(logger.hollow()), "\n");
113
114    entry_uids = sort_uids(&entry_uids, logger.hollow()).to_vec(); // Sorting stuff
115
116    moc_uids.into_iter()
117        .map(|x| archive.get_moc(x, logger.hollow()).unwrap())
118        .enumerate()
119        .for_each(|(i, mut entry)| {
120            scribe_write!((scribe) &(i + 1).to_string(), ". \\[[", entry.title(logger.hollow()), "](", &entry.uid, ")\\] ", entry.description(logger.hollow()), &format!(" `notes: {:?}`\n", entry.notes(logger.hollow())));
121            entry.clear_cache();
122        });
123
124    entry_uids.into_iter()
125        .map(|x| archive.get_entry(x, logger.hollow()).unwrap())
126        .enumerate()
127        .for_each(|(i, mut entry)| {
128            scribe_write!((scribe) &(i + 1).to_string(), ". \\[[", entry.title(logger.hollow()), "](", &entry.uid, ")\\] ", entry.description(logger.hollow()), &format!(" `notes: {:?}`\n", entry.notes(logger.hollow())));
129            entry.clear_cache();
130        });
131}
132
133fn export_section_content(scribe: &mut Scribe<impl Logger>, section: &mut Section, logger: impl Logger) {
134    scribe_write!((scribe) "### ", section.title(logger.hollow()), "\n");
135    let content = section.content(logger.hollow()).trim_end_matches('\n').split('\n');
136    content.for_each(|x| {
137        scribe_write!((scribe) "> ", x, "\n");
138    });
139    section.clear_cache();
140}
141
142fn scribe_tags(tags: &[String], scribe: &mut Scribe<impl Logger>) {
143    scribe.write_line("---");
144    scribe.write("tags:\n  - obsidian-md\n  - diary-cli\n");
145    tags.iter().for_each(|x| scribe_write!((scribe) "  - ", x, "\n"));
146    scribe.write_line("---");
147}
148
149fn scribe_tags_n_date(tags: &[String], date: &[u16; 3], scribe: &mut Scribe<impl Logger>) {
150    scribe.write_line("---");
151    scribe.write("tags:\n  - obsidian-md\n  - diary-cli\n");
152    tags.iter().for_each(|x| scribe_write!((scribe) "  - ", x, "\n"));
153    scribe.write(&format!("date: {0}-{1}-{2}\n", date[2], date[1], date[0]));
154    scribe.write_line("---");
155}