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 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 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 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 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 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 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 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 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 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 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(); 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}