summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2022-09-01 19:51:11 +0300
committerLars Wirzenius <liw@liw.fi>2022-09-01 19:51:20 +0300
commit67fca36ecc3388a553889d438a256db6be177a1b (patch)
treedc02388dfd36c0792a3849f082574b27a5b3824d
parent0ba22ee78aef7c05613773298319820520653270 (diff)
downloadriki-67fca36ecc3388a553889d438a256db6be177a1b.tar.gz
feat: allow shortcuts to be defined anywhere
ikiwiki requires shortcuts to be defined in a paged called "shortcuts". We allow them anywhere, but this requires us to introduce a preparation phase: directives (shortcuts only for now) can be asked to prepare before they're later processed. For shortcuts preparing means adding the shortcut to the site's list of shortcuts. Sponsored-by: author
-rw-r--r--riki.md13
-rw-r--r--src/directive/mod.rs10
-rw-r--r--src/directive/shortcut.rs9
-rw-r--r--src/page.rs9
-rw-r--r--src/site.rs1
-rw-r--r--src/wikitext.rs15
6 files changed, 51 insertions, 6 deletions
diff --git a/riki.md b/riki.md
index dffd617..9ec7d8e 100644
--- a/riki.md
+++ b/riki.md
@@ -469,17 +469,20 @@ like a directive._
~~~scenario
given an installed riki
-given file site/index.mdwn from shortcut
+given file site/a.mdwn from use_shortcut
+given file site/b.mdwn from define_shortcut
when I run riki build site output
-then file output/index.html contains "<a href="https://example.com/foo/123">foo!123</a>"
+then file output/a.html contains "<a href="https://example.com/foo/123">foo!123</a>"
~~~
-~~~{#shortcut .file .markdown}
-[[!shortcut name="foo" url="https://example.com/foo/%s" desc="foo!%s"]]
-
+~~~{#use_shortcut .file .markdown}
[[!foo 123]]
~~~
+~~~{#define_shortcut .file .markdown}
+[[!shortcut name="foo" url="https://example.com/foo/%s" desc="foo!%s"]]
+~~~
+
## Source file tree
### Listing source files
diff --git a/src/directive/mod.rs b/src/directive/mod.rs
index 02cf237..8e0c6fd 100644
--- a/src/directive/mod.rs
+++ b/src/directive/mod.rs
@@ -2,6 +2,8 @@ use crate::error::SiteError;
use crate::page::PageMeta;
use crate::site::Site;
use crate::wikitext::ParsedDirective;
+
+use log::trace;
use std::collections::HashSet;
#[derive(Debug, Eq, PartialEq)]
@@ -140,6 +142,14 @@ impl Directive {
Ok(())
}
+ pub fn prepare(&self, site: &mut Site) -> Result<(), SiteError> {
+ trace!("prepare directive {:?}", self);
+ if let Self::Shortcut(x) = self {
+ x.prepare(site)?;
+ }
+ Ok(())
+ }
+
pub fn process(&self, site: &mut Site, meta: &mut PageMeta) -> Result<String, SiteError> {
match self {
Self::Simple
diff --git a/src/directive/shortcut.rs b/src/directive/shortcut.rs
index 377482a..7b397d4 100644
--- a/src/directive/shortcut.rs
+++ b/src/directive/shortcut.rs
@@ -3,6 +3,8 @@ use crate::page::PageMeta;
use crate::site::{Shortcut as S, Site};
use crate::wikitext::ParsedDirective;
+use log::trace;
+
#[derive(Debug, Eq, PartialEq)]
pub struct Shortcut {
shortcut: S,
@@ -17,8 +19,13 @@ impl Shortcut {
Self { shortcut }
}
- pub fn process(&self, site: &mut Site, _meta: &mut PageMeta) -> Result<String, SiteError> {
+ pub fn prepare(&self, site: &mut Site) -> Result<(), SiteError> {
+ trace!("shortcut: prepare");
site.add_shortcut(self.shortcut.clone());
+ Ok(())
+ }
+
+ pub fn process(&self, _site: &mut Site, _meta: &mut PageMeta) -> Result<String, SiteError> {
Ok("".into())
}
}
diff --git a/src/page.rs b/src/page.rs
index f14dfde..2b4bd9f 100644
--- a/src/page.rs
+++ b/src/page.rs
@@ -74,9 +74,18 @@ impl UnprocessedPage {
Ok(snippets)
}
+ pub fn prepare(&self, site: &mut Site) -> Result<(), SiteError> {
+ trace!("UnprocessedPage: preparing snippets");
+ for snippet in self.snippets.iter() {
+ snippet.prepare(site)?;
+ }
+ Ok(())
+ }
+
pub fn process(&self, site: &mut Site) -> Result<MarkdownPage, SiteError> {
let mut meta = self.meta.clone();
let mut m = String::new();
+ trace!("UnprocessedPage: processing snippets");
for snippet in self.snippets.iter() {
m.push_str(&snippet.process(site, &mut meta)?);
}
diff --git a/src/site.rs b/src/site.rs
index 417676c..4c1d585 100644
--- a/src/site.rs
+++ b/src/site.rs
@@ -120,6 +120,7 @@ impl Site {
debug!("processing 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)?;
self.unprocessed_pages.push(page);
Ok(true)
} else {
diff --git a/src/wikitext.rs b/src/wikitext.rs
index a44c6a9..79f311f 100644
--- a/src/wikitext.rs
+++ b/src/wikitext.rs
@@ -13,6 +13,21 @@ pub enum Snippet {
}
impl Snippet {
+ pub fn prepare(&self, site: &mut Site) -> Result<(), SiteError> {
+ trace!("prepare snippet {:?}", self);
+ if let Snippet::Directive(p) = self {
+ trace!("creating directive from parsed directive");
+ let e = Directive::try_from(p);
+ if let Ok(d) = e {
+ trace!("prepare directive {:?}", d);
+ d.prepare(site)?;
+ } else {
+ trace!("failed to create directive: {}", e.unwrap_err());
+ }
+ }
+ Ok(())
+ }
+
pub fn process(&self, site: &mut Site, meta: &mut PageMeta) -> Result<String, SiteError> {
trace!("Snippet::process: self={:?}", self);
let s = match self {