From 528a4c1e20c2b9b8ecf451af72c77ae36e4f95b5 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Wed, 25 Jan 2023 19:22:44 +0200 Subject: feat: keep track of which pages a page links to Via wiki links or the meta link directive. Sponsored-by: author --- src/bin/riki.rs | 32 ++++++++++++++++++++++++++++++++ src/directive/meta.rs | 7 +++++++ src/page.rs | 17 ++++++++++++++++- src/site.rs | 8 +++++++- src/wikitext.rs | 1 + 5 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/bin/riki.rs b/src/bin/riki.rs index c1f9e4b..bff1a72 100644 --- a/src/bin/riki.rs +++ b/src/bin/riki.rs @@ -52,6 +52,7 @@ fn real_main() -> Result<(), RikiError> { Command::Timestamps(cmd) => cmd.run()?, Command::ParseDate(cmd) => cmd.run()?, Command::PageSpec(cmd) => cmd.run()?, + Command::Links(cmd) => cmd.run()?, } } @@ -77,6 +78,7 @@ enum Command { Timestamps(Timestamps), ParseDate(ParseDate), PageSpec(PageSpec), + Links(Links), } /// Build the site. @@ -247,3 +249,33 @@ impl PageSpec { Ok(()) } } + +/// List links in the pages listed on the command line. +#[derive(Parser)] +struct Links { + /// Directory where source files are. + srcdir: PathBuf, + + /// Path to pages whose links are to be listed. + pages: Vec, +} + +impl Links { + fn run(&self) -> Result<(), RikiError> { + let srcdir = canonicalize(&self.srcdir)?; + let mut site = Site::new(&srcdir, &PathBuf::from("/tmp")); + site.scan()?; + site.process()?; + + for path in self.pages.iter() { + if let Some(page) = site.page(path) { + println!("page: {:?}", page.meta().path().display()); + for path in page.meta().links_to() { + println!(" {}", path.display()); + } + } + } + + Ok(()) + } +} diff --git a/src/directive/meta.rs b/src/directive/meta.rs index 974a955..5e07eed 100644 --- a/src/directive/meta.rs +++ b/src/directive/meta.rs @@ -4,10 +4,13 @@ use crate::site::Site; use crate::time::parse_timestamp; use crate::wikitext::ParsedDirective; +use std::path::PathBuf; + #[derive(Default, Debug, Eq, PartialEq)] pub struct Meta { title: Option, date: Option, + link: PathBuf, } impl DirectiveImplementation for Meta { @@ -24,6 +27,9 @@ impl DirectiveImplementation for Meta { if let Some(date) = args.get("date") { meta.set_date(date); } + if let Some(link) = args.get("link") { + meta.link = PathBuf::from(link); + } meta } @@ -34,6 +40,7 @@ impl DirectiveImplementation for Meta { if let Some(mtime) = &self.date { meta.set_mtime(parse_timestamp(mtime)?); } + meta.add_link(&self.link); Ok(Processed::Markdown("".into())) } } diff --git a/src/page.rs b/src/page.rs index d84721c..453c29b 100644 --- a/src/page.rs +++ b/src/page.rs @@ -30,6 +30,7 @@ pub enum PageError { Parser(#[from] crate::parser::ParserError), } +#[derive(Debug)] pub struct Page { meta: PageMeta, unprocessed: UnprocessedPage, @@ -193,6 +194,7 @@ pub struct PageMeta { name: Name, title: Option, mtime: SystemTime, + links_to: Vec, } impl PageMeta { @@ -203,7 +205,12 @@ impl PageMeta { title, mtime, ); - Self { name, title, mtime } + Self { + name, + title, + mtime, + links_to: vec![], + } } pub fn destination_filename(&self) -> PathBuf { @@ -234,6 +241,14 @@ impl PageMeta { pub fn set_mtime(&mut self, mtime: SystemTime) { self.mtime = mtime; } + + pub fn add_link(&mut self, path: &Path) { + self.links_to.push(path.into()); + } + + pub fn links_to(&self) -> &[PathBuf] { + &self.links_to + } } #[derive(Debug, Default)] diff --git a/src/site.rs b/src/site.rs index 4d2ce29..cfd5017 100644 --- a/src/site.rs +++ b/src/site.rs @@ -93,7 +93,7 @@ impl Site { info!("add wikitext page {}", page.meta().path().display()); self.pages_that_will_exist.insert(&page); - debug!("parsing wikitext page {}", page.meta().path().display()); + trace!("parsing wikitext page {}", page.meta().path().display()); let mut parser = WikitextParser::new(page.wikitext(), &self.patterns); let page = UnprocessedPage::new(page.meta().clone(), &mut parser)?; page.prepare(self)?; @@ -151,6 +151,12 @@ impl Site { self.pages_that_will_exist.get_path(path).is_some() } + pub fn page(&self, path: &Path) -> Option<&MarkdownPage> { + self.markdown_pages + .iter() + .find(|&page| page.meta().path() == path) + } + fn all_files(&self) -> Result, SiteError> { let whatchanged = git_whatchanged(self.name_builder.srcdir())?; diff --git a/src/wikitext.rs b/src/wikitext.rs index 4d8578a..57dff88 100644 --- a/src/wikitext.rs +++ b/src/wikitext.rs @@ -48,6 +48,7 @@ impl Snippet { Snippet::WikiLink(w) => { let resolved = site.resolve(meta.path(), Path::new(w.target()))?; trace!("resolved {} to {}", w.target(), resolved.display()); + meta.add_link(&resolved); let link = format!("[{}]({})", w.link_text(), resolved.display()); Processed::Markdown(link) } -- cgit v1.2.1