c6o_obsidian_export/
context.rs

1use crate::Frontmatter;
2use std::path::{Path, PathBuf};
3
4#[derive(Debug, Clone)]
5/// Context holds metadata about a note which is being parsed.
6///
7/// This is used internally to keep track of nesting and help with constructing proper references
8/// to other notes.
9///
10/// It is also passed to [postprocessors][crate::Postprocessor] to provide contextual information
11/// and allow modification of a note's frontmatter.
12pub struct Context {
13    file_tree: Vec<PathBuf>,
14
15    /// The path where this note will be written to when exported.
16    ///
17    /// Changing this path will result in the note being written to that new path instead, but
18    /// beware: links will not be updated automatically.  If this is changed by a
19    /// [postprocessor][crate::Postprocessor], it's up to that postprocessor to rewrite any
20    /// existing links to this new path.
21    pub destination: PathBuf,
22
23    /// The [Frontmatter] for this note. Frontmatter may be modified in-place (see
24    /// [serde_yaml::Mapping] for available methods) or replaced entirely.
25    ///
26    /// # Example
27    ///
28    /// Insert `foo: bar` into a note's frontmatter:
29    ///
30    /// ```
31    /// # use obsidian_export::Frontmatter;
32    /// # use obsidian_export::Context;
33    /// # use std::path::PathBuf;
34    /// use obsidian_export::serde_yaml::Value;
35    ///
36    /// # let mut context = Context::new(PathBuf::from("source"), PathBuf::from("destination"));
37    /// let key = Value::String("foo".to_string());
38    ///
39    /// context.frontmatter.insert(
40    ///     key.clone(),
41    ///     Value::String("bar".to_string()),
42    /// );
43    /// ```
44    pub frontmatter: Frontmatter,
45}
46
47impl Context {
48    /// Create a new `Context`
49    pub fn new(src: PathBuf, dest: PathBuf) -> Context {
50        Context {
51            file_tree: vec![src],
52            destination: dest,
53            frontmatter: Frontmatter::new(),
54        }
55    }
56
57    /// Create a new `Context` which inherits from a parent Context.
58    pub fn from_parent(context: &Context, child: &Path) -> Context {
59        let mut context = context.clone();
60        context.file_tree.push(child.to_path_buf());
61        context
62    }
63
64    /// Return the path of the file currently being parsed.
65    pub fn current_file(&self) -> &PathBuf {
66        self.file_tree
67            .last()
68            .expect("Context not initialized properly, file_tree is empty")
69    }
70
71    /// Return the path of the root file.
72    ///
73    /// Typically this will yield the same element as `current_file`, but when a note is embedded
74    /// within another note, this will return the outer-most note.
75    pub fn root_file(&self) -> &PathBuf {
76        self.file_tree
77            .first()
78            .expect("Context not initialized properly, file_tree is empty")
79    }
80
81    /// Return the note depth (nesting level) for this context.
82    pub fn note_depth(&self) -> usize {
83        self.file_tree.len()
84    }
85
86    /// Return the list of files associated with this context.
87    ///
88    /// The first element corresponds to the root file, the final element corresponds to the file
89    /// which is currently being processed (see also `current_file`).
90    pub fn file_tree(&self) -> Vec<PathBuf> {
91        self.file_tree.clone()
92    }
93}