summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2023-01-25 19:22:44 +0200
committerLars Wirzenius <liw@liw.fi>2023-01-25 19:22:44 +0200
commit528a4c1e20c2b9b8ecf451af72c77ae36e4f95b5 (patch)
tree46e575d1394dc1721c57b6fde28c5cd98ed2fe15
parent2ac4193a30c5ef6186666269c171b88fabd86143 (diff)
downloadriki-528a4c1e20c2b9b8ecf451af72c77ae36e4f95b5.tar.gz
feat: keep track of which pages a page links to
Via wiki links or the meta link directive. Sponsored-by: author
-rw-r--r--src/bin/riki.rs32
-rw-r--r--src/directive/meta.rs7
-rw-r--r--src/page.rs17
-rw-r--r--src/site.rs8
-rw-r--r--src/wikitext.rs1
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<PathBuf>,
+}
+
+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<String>,
date: Option<String>,
+ 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<String>,
mtime: SystemTime,
+ links_to: Vec<PathBuf>,
}
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<Vec<Name>, 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)
}