lssg_lib/sitetree/
page.rs

1use crate::{
2    lmarkdown::{parse_lmarkdown, Token},
3    lssg_error::LssgError,
4};
5
6use super::Input;
7
8#[derive(Debug)]
9pub struct Page {
10    tokens: Vec<Token>,
11}
12impl Page {
13    pub fn from_input(input: &Input) -> Result<Page, LssgError> {
14        let tokens = parse_lmarkdown(input.readable()?)?;
15        Ok(Page { tokens })
16    }
17
18    /// Discover any resources and links inside of the page will return vec with (text, href)
19    pub fn links(&self) -> Vec<(&Vec<Token>, &String)> {
20        let mut hrefs = vec![];
21        let mut queue = vec![&self.tokens];
22        while let Some(tokens) = queue.pop() {
23            for t in tokens {
24                match t {
25                    Token::Heading { tokens, .. } => queue.push(tokens),
26                    Token::Paragraph { tokens, .. } => queue.push(tokens),
27                    Token::Html { tokens, .. } => queue.push(tokens),
28                    Token::Link { href, tokens: text } => {
29                        hrefs.push((text, href));
30                    }
31                    _ => {}
32                }
33            }
34        }
35        return hrefs;
36    }
37
38    pub fn attributes(&self) -> Option<&toml::Table> {
39        if let Some(Token::Attributes { table }) = self.tokens().first() {
40            Some(table)
41        } else {
42            None
43        }
44    }
45
46    // only support relative links to markdown files for now
47    // because this will allow absolute links to markdown files links to for
48    // example https://github.com/Lyr-7D1h/airap/blob/master/README.md
49    // will render a readme even though this might not be appropiate
50    pub fn is_href_to_page(href: &str) -> bool {
51        href.ends_with(".md") && Input::is_relative(&href)
52    }
53
54    pub fn tokens(&self) -> &Vec<Token> {
55        &self.tokens
56    }
57}