summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2023-02-06 19:05:09 +0200
committerLars Wirzenius <liw@liw.fi>2023-02-06 19:05:09 +0200
commitc0e44d18d56ed625df5ff0224fe170e4d18add09 (patch)
tree47145ea52d523526bc2e7d679ee062de4cc02e52
parentca160fd27a31a030191055409d02fd7739a50179 (diff)
downloadriki-c0e44d18d56ed625df5ff0224fe170e4d18add09.tar.gz
feat: placeholder for "link(.)" in pagespec
Doesn't yet do anything useful. Sponsored-by: author
-rw-r--r--src/bin/riki.rs1
-rw-r--r--src/pagespec.lalrpop1
-rw-r--r--src/pagespec.rs37
3 files changed, 38 insertions, 1 deletions
diff --git a/src/bin/riki.rs b/src/bin/riki.rs
index bff1a72..131326b 100644
--- a/src/bin/riki.rs
+++ b/src/bin/riki.rs
@@ -229,6 +229,7 @@ impl PageSpec {
site.process()?;
let pagespec = pagespec::PageSpec::new(&self.path, &self.pagespec)?;
+ debug!("pagespec: {:#?}", pagespec);
for page in site.markdown_pages() {
let path = page.meta().path();
diff --git a/src/pagespec.lalrpop b/src/pagespec.lalrpop
index e1dd433..bc07744 100644
--- a/src/pagespec.lalrpop
+++ b/src/pagespec.lalrpop
@@ -9,6 +9,7 @@ pub Expr: Box<Expr> = {
Term: Box<Expr> = {
Glob => Box::new(Expr::Glob(<>)),
+ "link" "(" "." ")" => Box::new(Expr::LinksHereFunc),
"page" "(" <g:Glob> ")" => Box::new(Expr::PageFunc(<>)),
"!" <t:Term> => Box::new(Expr::Negate(t)),
"(" <e:Expr> ")" => e,
diff --git a/src/pagespec.rs b/src/pagespec.rs
index 55c83fb..e3f617d 100644
--- a/src/pagespec.rs
+++ b/src/pagespec.rs
@@ -22,6 +22,11 @@ pub struct PageSpec {
impl PageSpec {
/// Create a new PageSpec.
pub fn new(containing_page: &Path, spec: &str) -> Result<Self, PageSpecError> {
+ trace!(
+ "PageSpec::new: containing_page={} spec={:?}",
+ containing_page.display(),
+ spec
+ );
let expr = pagespec::ExprParser::new()
.parse(spec)
.map_err(|e| PageSpecError::Parse(format!("{}", e)))?;
@@ -59,6 +64,7 @@ pub enum PageSpecError {
#[derive(Debug)]
pub enum Expr {
Glob(String),
+ LinksHereFunc,
PageFunc(String),
Negate(Box<Expr>),
Op(Box<Expr>, OpCode, Box<Expr>),
@@ -69,6 +75,7 @@ impl Expr {
trace!("Expr::matches: path={:?} self={:?}", path, self);
match self {
Self::Glob(glob) => glob_matches(glob, path),
+ Self::LinksHereFunc => links_here(site, container, path), // FIXME: check its page
Self::PageFunc(glob) => page_matches(site, container, glob, path), // FIXME: check its page
Self::Negate(expr) => !expr.matches(site, container, path),
Self::Op(left, op, right) => match op {
@@ -91,9 +98,16 @@ pub enum OpCode {
}
fn glob_matches(glob: &str, path: &str) -> bool {
+ trace!("glob_matches: glob={:?} path={:?}", glob, path);
let glob: Vec<char> = glob.chars().collect();
let path: Vec<char> = path.chars().collect();
- glob_matches_helper(&glob, &path)
+ if glob_matches_helper(&glob, &path) {
+ trace!("glob_matches: match!");
+ true
+ } else {
+ trace!("glob_matches: no match");
+ false
+ }
}
fn glob_matches_helper(mut glob: &[char], mut path: &[char]) -> bool {
@@ -134,6 +148,27 @@ fn glob_matches_helper(mut glob: &[char], mut path: &[char]) -> bool {
glob.is_empty() && path.is_empty()
}
+fn links_here(site: &Site, container: &Path, path: &str) -> bool {
+ trace!(
+ "links_here: container={} path={:?}",
+ container.display(),
+ path
+ );
+ let path = Path::new(path);
+ if let Some(page) = site.page(path) {
+ trace!("links_here: found page {}", path.display());
+ for link in page.meta().links_to() {
+ trace!("links_here: page links to {}", link.display());
+ if link == container {
+ trace!("links to container!");
+ return true;
+ }
+ }
+ }
+ trace!("links_here: does not link to container");
+ false
+}
+
fn page_matches(site: &Site, container: &Path, glob: &str, path: &str) -> bool {
if glob_matches(glob, path) {
let full_path = container.join(path);