summaryrefslogtreecommitdiff
path: root/src/collect_files.rs
diff options
context:
space:
mode:
authorBen Bridle <ben@derelict.engineering>2025-05-21 14:25:18 +1200
committerBen Bridle <ben@derelict.engineering>2025-05-21 19:50:09 +1200
commit060c1f23a5585a5fdabc56eda808b4cfd90f9081 (patch)
treea8bd3d2aa0e5c87528a5b7c417cf4a63edb2dbef /src/collect_files.rs
parentc749c1db30f2b757e63093ac39127b3e338cb704 (diff)
downloadtoaster-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.rs47
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.