diff options
author | Ben Bridle <ben@derelict.engineering> | 2025-05-21 14:25:18 +1200 |
---|---|---|
committer | Ben Bridle <ben@derelict.engineering> | 2025-05-21 19:50:09 +1200 |
commit | 060c1f23a5585a5fdabc56eda808b4cfd90f9081 (patch) | |
tree | a8bd3d2aa0e5c87528a5b7c417cf4a63edb2dbef /src/collect_files.rs | |
parent | c749c1db30f2b757e63093ac39127b3e338cb704 (diff) | |
download | toaster-060c1f23a5585a5fdabc56eda808b4cfd90f9081.zip |
Implement syntax highlighting for syntax fragments
A new key 'highlighters' has been added to the toaster.conf file. The
value should be a line defining the languages to use that syntax for,
like [py/python]. The lines following are the template definitions, as
per the highlighter library.
Diffstat (limited to 'src/collect_files.rs')
-rw-r--r-- | src/collect_files.rs | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/src/collect_files.rs b/src/collect_files.rs index 7a3c464..18d75f1 100644 --- a/src/collect_files.rs +++ b/src/collect_files.rs @@ -1,5 +1,6 @@ use crate::*; +use highlight::*; use vagabond::*; use std::collections::HashMap; @@ -8,6 +9,7 @@ use std::collections::HashMap; pub struct Website { pub name: String, pub config: HashMap<String, String>, + pub highlighters: Highlighters, pub pages: Vec<Page>, pub redirects: Vec<Redirect>, pub static_files: Vec<StaticItem>, // Redirects, !-prefixed-dir contents @@ -60,6 +62,10 @@ pub trait LinkFrom { } } +pub struct Highlighters { + pub languages: HashMap<String, usize>, + pub highlighters: Vec<Highlighter>, +} impl Page { pub fn root(&self) -> String { @@ -96,8 +102,13 @@ impl Website { Err(err) => fatal!("Couldn't open {:?}: {:?}", &path, err), }, config: HashMap::new(), + highlighters: Highlighters { + languages: HashMap::new(), + highlighters: Vec::new(), + }, }; new.collect_entry(path, path); + new.parse_highlighters(); return new; } @@ -149,7 +160,7 @@ impl Website { let mut key = None; let mut value = String::new(); for line in config.lines() { - if line.starts_with(" ") { + if line.starts_with(" ") || line.trim().is_empty() { value.push_str(line.trim()); value.push('\n'); } else { @@ -268,6 +279,40 @@ impl Website { } } + pub fn parse_highlighters(&mut self) { + let mut languages = Vec::new(); + let mut source = String::new(); + for line in self.get_config("highlighters").lines() { + if let Some(line) = line.trim().strip_prefix('[') { + if let Some(line) = line.strip_suffix(']') { + // Bank the current source. + if !languages.is_empty() { + let i = self.highlighters.highlighters.len(); + for language in languages { + self.highlighters.languages.insert(language, i); + } + let highlighter = Highlighter::from_str(&source); + self.highlighters.highlighters.push(highlighter); + } + languages = line.split('/').map(|s| s.trim().to_string()).collect(); + source.clear(); + continue; + } + } + source.push_str(line); + source.push('\n'); + } + // Bank the current source. + if !languages.is_empty() { + let i = self.highlighters.highlighters.len(); + for language in languages { + self.highlighters.languages.insert(language, i); + } + let highlighter = Highlighter::from_str(&source); + self.highlighters.highlighters.push(highlighter); + } + } + // Ext is extension without a dot. // Checks if a relative link to an internal page name can be reached from // the current page, and returns a resolved absolute link to the page with extension. |