From b1da5d57984fbc4d0b922dec444c985f1b16ab9d Mon Sep 17 00:00:00 2001 From: Gregory Marco Date: Thu, 3 Jul 2025 22:15:17 -0500 Subject: [PATCH] Add an ability to resolve a file path to a historian instance and page object. Add a command for running resolve-links on a file directly, for use in an editor. --- src/lib.rs | 30 ++++++++++++++++++++++++ src/main.rs | 67 ++++++++++++++++++++++++++++++++--------------------- 2 files changed, 71 insertions(+), 26 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9f6a681..f9d0c1f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -58,6 +58,36 @@ impl Historian { } } + pub fn resolve_from_file(file_path_str: &str) -> Option<(Historian, Page)> { + let file_path: PathBuf = std::path::absolute(file_path_str).unwrap(); + match fs::metadata(&file_path) { + Err(_) => None, + Ok(metadata) => { + if !metadata.is_file() { + None + } else { + let mut wiki_path = file_path.parent().unwrap(); + while wiki_path.parent() != None { + let toml_path = wiki_path.join(DEFAULT_TOML_FILENAME); + match fs::metadata(&toml_path) { + Err(_) => { + wiki_path = wiki_path.parent().unwrap(); + }, + Ok(_) => { + let historian = Historian::new(wiki_path.to_str().unwrap().to_owned()); + let relative_page_path = diff_paths(&file_path, &wiki_path).unwrap(); + return relative_page_path.to_str() + .and_then(|page_path| historian.resolve_to_page(page_path)) + .map(|page| (historian, page)); + } + }; + } + None + } + } + } + } + pub fn resolve_to_page(&self, name: &str) -> Option { let mut file_path = self.source_root.clone().join(Path::new(name)); match fs::metadata(&file_path) { diff --git a/src/main.rs b/src/main.rs index e4b4585..4935932 100644 --- a/src/main.rs +++ b/src/main.rs @@ -171,7 +171,7 @@ fn action( #[command(version, about, long_about = None)] struct Args { /// Path to wiki repository - wiki_path: String, + wiki_path: Option, /// Render the wiki to a static website #[arg(long)] @@ -193,36 +193,51 @@ struct Args { #[rocket::main] async fn main() { let args = Args::parse(); - let historian = Historian::new(args.wiki_path); - let renderer = if let Some(template_path) = args.template_path { - PageRenderer::with_template_path(&template_path) - } else { - PageRenderer::new() - }; + if let Some(wiki_path) = args.wiki_path { + let historian = Historian::new(wiki_path); - let linker = Linker::new(&historian); + let renderer = if let Some(template_path) = args.template_path { + PageRenderer::with_template_path(&template_path) + } else { + PageRenderer::new() + }; + + let linker = Linker::new(&historian); + + if let Some(resolve_link) = args.resolve_link { + println!("{}", linker.resolve_link(&resolve_link).unwrap()); + return; + } + + if let Some(resolve_links) = args.resolve_links { + let page = historian.resolve_to_page(&resolve_links).expect("failed to find page"); + println!("{}", linker.resolve_links(&page)); + return; + } + + if let Some(render_to) = args.render_to { + export_wiki(&historian, &renderer, &render_to); + return; + } + + rocket::build() + .manage(historian) + .manage(renderer) + .mount("/", routes![page, action]) + .launch() + .await; + return; + } else if let Some(resolve_links) = args.resolve_links { + if let Some((historian, page)) = Historian::resolve_from_file(&resolve_links) { + let linker = Linker::new(&historian); + println!("{}", linker.resolve_links(&page)); + return; + } - if let Some(resolve_link) = args.resolve_link { - println!("{}", linker.resolve_link(&resolve_link).unwrap()); return; } - if let Some(resolve_links) = args.resolve_links { - let page = historian.resolve_to_page(&resolve_links).expect("failed to find page"); - println!("{}", linker.resolve_links(&page)); - return; - } + return; - if let Some(render_to) = args.render_to { - export_wiki(&historian, &renderer, &render_to); - return; - } - - rocket::build() - .manage(historian) - .manage(renderer) - .mount("/", routes![page, action]) - .launch() - .await; }