summaryrefslogtreecommitdiff
path: root/src/directive/inline.rs
blob: 7c0114be38365e2d8bdee1a115d17ddc7c9c6c48 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use crate::directive::{DirectiveError, DirectiveImplementation, Processed};
use crate::page::PageMeta;
use crate::pagespec::PageSpec;
use crate::site::Site;
use crate::util::make_relative_link;
use crate::wikitext::ParsedDirective;
use std::path::Path;

#[derive(Debug, Default, Eq, PartialEq)]
pub struct Inline {
    pages: String,
}

impl DirectiveImplementation for Inline {
    const REQUIRED: &'static [&'static str] = &["pages"];
    const ALLOWED: &'static [&'static str] = &[
        "actions",
        "archive",
        "description",
        "feedlimit",
        "feeds",
        "feedshow",
        "limit",
        "quick",
        "reverse",
        "rootpage",
        "show",
        "sort",
        "template",
        "trail",
    ];
    const ALLOW_ANY_UNNAMED: bool = true;

    fn from_parsed(p: &ParsedDirective) -> Self {
        let args = p.args();
        let pages = args.get("pages").unwrap();
        Inline::new(pages.to_string())
    }

    fn process(&self, site: &Site, meta: &mut PageMeta) -> Result<Processed, DirectiveError> {
        let pagespec = PageSpec::new(meta.path(), &self.pages).map_err(DirectiveError::PageSpec)?;
        let matches: Vec<String> = site
            .markdown_pages()
            .filter(|page| pagespec.matches(site, page.meta().path()))
            .map(|page| format!("* {}\n", Self::link(meta.path(), page.meta())))
            .collect();
        Ok(Processed::Markdown(matches.join("")))
    }
}

impl Inline {
    pub fn new(pages: String) -> Self {
        Self { pages }
    }

    fn link(container: &Path, meta: &PageMeta) -> String {
        let link = make_relative_link(container, meta.path());
        format!("[{}]({})", meta.title(), link.display())
    }
}