Basic toml config support.
This commit is contained in:
parent
c8ffbb2af0
commit
38be7b7365
7 changed files with 274 additions and 31 deletions
129
Cargo.lock
generated
129
Cargo.lock
generated
|
|
@ -142,6 +142,27 @@ dependencies = [
|
||||||
"syn 2.0.104",
|
"syn 2.0.104",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs"
|
||||||
|
version = "6.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
|
||||||
|
dependencies = [
|
||||||
|
"dirs-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs-sys"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"option-ext",
|
||||||
|
"redox_users",
|
||||||
|
"windows-sys 0.60.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dtoa"
|
name = "dtoa"
|
||||||
version = "1.0.10"
|
version = "1.0.10"
|
||||||
|
|
@ -311,13 +332,16 @@ name = "htmlua-parser"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"dirs",
|
||||||
"html5ever 0.35.0",
|
"html5ever 0.35.0",
|
||||||
"kuchikiki",
|
"kuchikiki",
|
||||||
"markup5ever 0.11.0",
|
"markup5ever 0.11.0",
|
||||||
"mlua",
|
"mlua",
|
||||||
"pulldown-cmark",
|
"pulldown-cmark",
|
||||||
|
"serde",
|
||||||
"syntect",
|
"syntect",
|
||||||
"tendril",
|
"tendril",
|
||||||
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -375,6 +399,16 @@ version = "0.2.174"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libredox"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.9.1",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linked-hash-map"
|
name = "linked-hash-map"
|
||||||
version = "0.5.6"
|
version = "0.5.6"
|
||||||
|
|
@ -571,6 +605,12 @@ dependencies = [
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "option-ext"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ordered-float"
|
name = "ordered-float"
|
||||||
version = "2.10.1"
|
version = "2.10.1"
|
||||||
|
|
@ -915,6 +955,17 @@ dependencies = [
|
||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_users"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.2.16",
|
||||||
|
"libredox",
|
||||||
|
"thiserror 2.0.12",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.8.5"
|
version = "0.8.5"
|
||||||
|
|
@ -1044,6 +1095,15 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_spanned"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "servo_arc"
|
name = "servo_arc"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
|
|
@ -1148,7 +1208,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror",
|
"thiserror 1.0.69",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
"yaml-rust",
|
"yaml-rust",
|
||||||
]
|
]
|
||||||
|
|
@ -1176,7 +1236,16 @@ version = "1.0.69"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl 1.0.69",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "2.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl 2.0.12",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1190,6 +1259,17 @@ dependencies = [
|
||||||
"syn 2.0.104",
|
"syn 2.0.104",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "2.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.104",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.3.41"
|
version = "0.3.41"
|
||||||
|
|
@ -1221,6 +1301,45 @@ dependencies = [
|
||||||
"time-core",
|
"time-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.9.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed0aee96c12fa71097902e0bb061a5e1ebd766a6636bb605ba401c45c1650eac"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap 2.10.0",
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"toml_parser",
|
||||||
|
"toml_writer",
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_datetime"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_parser"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "97200572db069e74c512a14117b296ba0a80a30123fbbb5aa1f4a348f639ca30"
|
||||||
|
dependencies = [
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_writer"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typeid"
|
name = "typeid"
|
||||||
version = "1.0.3"
|
version = "1.0.3"
|
||||||
|
|
@ -1452,6 +1571,12 @@ version = "0.53.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.7.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winsafe"
|
name = "winsafe"
|
||||||
version = "0.0.19"
|
version = "0.0.19"
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,16 @@ edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.98"
|
anyhow = "1.0.98"
|
||||||
|
dirs = "6.0.0"
|
||||||
html5ever = "0.35.0"
|
html5ever = "0.35.0"
|
||||||
kuchikiki = "0.8.2"
|
kuchikiki = "0.8.2"
|
||||||
markup5ever = "0.11.0"
|
markup5ever = "0.11.0"
|
||||||
mlua = { version = "0.10.5", features = ["lua54", "vendored", "serialize"] }
|
mlua = { version = "0.10.5", features = ["lua54", "vendored", "serialize"] }
|
||||||
pulldown-cmark = "0.13.0"
|
pulldown-cmark = "0.13.0"
|
||||||
|
serde = { version = "1.0.219", features = ["derive"] }
|
||||||
syntect = "5.2.0"
|
syntect = "5.2.0"
|
||||||
tendril = "0.4.3"
|
tendril = "0.4.3"
|
||||||
|
toml = "0.9.2"
|
||||||
|
|
||||||
[lints.clippy]
|
[lints.clippy]
|
||||||
pedantic = { level = "warn", priority = -1 }
|
pedantic = { level = "warn", priority = -1 }
|
||||||
|
|
|
||||||
98
htmlua-parser/src/config.rs
Normal file
98
htmlua-parser/src/config.rs
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
use anyhow::{Context, Result};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::{fs, path::PathBuf};
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
|
pub struct Config {
|
||||||
|
pub paths: PathConfig,
|
||||||
|
pub server: ServerConfig,
|
||||||
|
pub syntax_highlighting: SyntaxConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
|
pub struct PathConfig {
|
||||||
|
pub pages: PathBuf,
|
||||||
|
pub components: PathBuf,
|
||||||
|
pub themes: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
|
pub struct ServerConfig {
|
||||||
|
pub host: String,
|
||||||
|
pub port: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
|
pub struct SyntaxConfig {
|
||||||
|
pub default_theme: String,
|
||||||
|
pub load_custom_themes: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Config {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
paths: PathConfig {
|
||||||
|
pages: PathBuf::from("/var/www/htmlua/pages"),
|
||||||
|
components: PathBuf::from("/var/www/htmlua/components"),
|
||||||
|
themes: PathBuf::from("/var/www/htmlua/themes"),
|
||||||
|
},
|
||||||
|
server: ServerConfig {
|
||||||
|
host: "127.0.0.1".to_string(),
|
||||||
|
port: 8080,
|
||||||
|
},
|
||||||
|
syntax_highlighting: SyntaxConfig {
|
||||||
|
default_theme: "base16-ocean.dark".to_string(),
|
||||||
|
load_custom_themes: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
pub fn load() -> Result<Self> {
|
||||||
|
let config_path = Self::get_config_path();
|
||||||
|
if config_path.exists() {
|
||||||
|
let config_content = fs::read_to_string(&config_path)
|
||||||
|
.with_context(|| format!("Failed to read config file: {}", config_path.display()))?;
|
||||||
|
let config: Config = toml::from_str(&config_content)
|
||||||
|
.with_context(|| format!("Failed to parse config file: {}", config_path.display()))?;
|
||||||
|
Ok(config)
|
||||||
|
} else {
|
||||||
|
let default_config = Config::default();
|
||||||
|
if let Some(parent) = config_path.parent() {
|
||||||
|
fs::create_dir_all(parent)
|
||||||
|
.with_context(|| format!("Failed to create config directory: {}", parent.display()))?;
|
||||||
|
}
|
||||||
|
let config_content =
|
||||||
|
toml::to_string_pretty(&default_config).context("Failed to serialize default config")?;
|
||||||
|
fs::write(&config_path, config_content)
|
||||||
|
.with_context(|| format!("Failed to write default config to: {}", config_path.display()))?;
|
||||||
|
Ok(default_config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_config_path() -> PathBuf {
|
||||||
|
if cfg!(windows) {
|
||||||
|
dirs::config_dir()
|
||||||
|
.unwrap_or_else(|| PathBuf::from("C:\\ProgramData"))
|
||||||
|
.join("htmlua")
|
||||||
|
.join("config.toml")
|
||||||
|
} else {
|
||||||
|
PathBuf::from("/etc/htmlua.toml")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn save(&self) -> Result<()> {
|
||||||
|
let config_path = Self::get_config_path();
|
||||||
|
if let Some(parent) = config_path.parent() {
|
||||||
|
fs::create_dir_all(parent)
|
||||||
|
.with_context(|| format!("Failed to create config directory: {}", parent.display()))?;
|
||||||
|
}
|
||||||
|
let config_content = toml::to_string_pretty(self).context("Failed to serialize config")?;
|
||||||
|
fs::write(&config_path, config_content)
|
||||||
|
.with_context(|| format!("Failed to write config to: {}", config_path.display()))?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn config_file_path() -> PathBuf { Self::get_config_path() }
|
||||||
|
}
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
use std::{fs::File, io::{BufRead, BufReader, Read, Seek, SeekFrom}, path::PathBuf};
|
use std::{
|
||||||
|
fs::File,
|
||||||
|
io::{BufRead, BufReader, Read, Seek, SeekFrom},
|
||||||
|
path::PathBuf,
|
||||||
|
};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use kuchikiki::NodeRef;
|
use kuchikiki::NodeRef;
|
||||||
use markup5ever::{LocalName, Namespace, QualName};
|
use markup5ever::{LocalName, Namespace, QualName};
|
||||||
use tendril::TendrilSink;
|
use tendril::TendrilSink;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub fn read_doc_from_file(path: PathBuf) -> Result<NodeRef> {
|
pub fn read_doc_from_file(path: PathBuf) -> Result<NodeRef> {
|
||||||
|
|
||||||
let mut file = File::open(path)?;
|
let mut file = File::open(path)?;
|
||||||
let mut reader = BufReader::new(&mut file);
|
let mut reader = BufReader::new(&mut file);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
pub mod config;
|
||||||
|
pub mod helpers;
|
||||||
pub mod render;
|
pub mod render;
|
||||||
pub mod serve;
|
pub mod serve;
|
||||||
pub mod helpers;
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{cell::RefCell, fmt::Write, fs::read_to_string, path::PathBuf, rc::Rc};
|
use std::{cell::RefCell, fmt::Write, path::PathBuf, rc::Rc};
|
||||||
|
|
||||||
use anyhow::{Result, anyhow};
|
use anyhow::{Result, anyhow};
|
||||||
use kuchikiki::{NodeRef, traits::TendrilSink};
|
use kuchikiki::{NodeRef, traits::TendrilSink};
|
||||||
|
|
@ -12,7 +12,7 @@ use syntect::{
|
||||||
util::LinesWithEndings,
|
util::LinesWithEndings,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::helpers::read_doc_from_file;
|
use crate::{helpers::read_doc_from_file, serve::get_config};
|
||||||
|
|
||||||
fn create_htmlua_stdlib(l: &Lua, stdout: &Rc<RefCell<String>>) -> mlua::Result<Table> {
|
fn create_htmlua_stdlib(l: &Lua, stdout: &Rc<RefCell<String>>) -> mlua::Result<Table> {
|
||||||
let t = l.create_table()?;
|
let t = l.create_table()?;
|
||||||
|
|
@ -108,7 +108,11 @@ pub fn expand_template(document: NodeRef, component_path: &PathBuf, include_from
|
||||||
let exported = from_node
|
let exported = from_node
|
||||||
.select_first(format!("exportelement.{name}").as_str())
|
.select_first(format!("exportelement.{name}").as_str())
|
||||||
.map_err(|()| anyhow!("Error finding exportelement"))?;
|
.map_err(|()| anyhow!("Error finding exportelement"))?;
|
||||||
exported.as_node().children().rev().for_each(|c| i.as_node().insert_after(c));
|
exported
|
||||||
|
.as_node()
|
||||||
|
.children()
|
||||||
|
.rev()
|
||||||
|
.for_each(|c| i.as_node().insert_after(c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while let Ok(i) = document.select_first("includeelement") {
|
while let Ok(i) = document.select_first("includeelement") {
|
||||||
|
|
@ -130,8 +134,13 @@ pub fn expand_template(document: NodeRef, component_path: &PathBuf, include_from
|
||||||
item_path.push(include_path);
|
item_path.push(include_path);
|
||||||
let new_node = read_doc_from_file(item_path)?;
|
let new_node = read_doc_from_file(item_path)?;
|
||||||
let replaced_node = expand_template(new_node, component_path, Some(i.as_node()))?;
|
let replaced_node = expand_template(new_node, component_path, Some(i.as_node()))?;
|
||||||
replaced_node.select_first("html").map_err(|()| anyhow!("Error finding html"))?.as_node().children().rev().for_each(|c| i.as_node().insert_after(c));
|
replaced_node
|
||||||
|
.select_first("html")
|
||||||
|
.map_err(|()| anyhow!("Error finding html"))?
|
||||||
|
.as_node()
|
||||||
|
.children()
|
||||||
|
.rev()
|
||||||
|
.for_each(|c| i.as_node().insert_after(c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while let Ok(i) = document.select_first("include") {
|
while let Ok(i) = document.select_first("include") {
|
||||||
|
|
@ -141,16 +150,15 @@ pub fn expand_template(document: NodeRef, component_path: &PathBuf, include_from
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn process_syntax_highlighting(document: NodeRef) -> Result<NodeRef> {
|
pub fn process_syntax_highlighting(document: NodeRef) -> Result<NodeRef> {
|
||||||
|
let config = get_config();
|
||||||
let ps = SyntaxSet::load_defaults_newlines();
|
let ps = SyntaxSet::load_defaults_newlines();
|
||||||
let mut ts = ThemeSet::load_defaults();
|
let mut ts = ThemeSet::load_defaults();
|
||||||
let syntax_elements: Vec<_> = match document.select("syntaxhighlight") {
|
let syntax_elements: Vec<_> = match document.select("syntaxhighlight") {
|
||||||
Ok(e) => e.collect(),
|
Ok(e) => e.collect(),
|
||||||
Err(()) => return Err(anyhow!("Unable to find syntaxhighlight elements")),
|
Err(()) => return Err(anyhow!("Unable to find syntaxhighlight elements")),
|
||||||
};
|
};
|
||||||
if !syntax_elements.is_empty() {
|
if !syntax_elements.is_empty() && config.syntax_highlighting.load_custom_themes {
|
||||||
// TODO: read from config
|
let _ = ts.add_from_folder(&config.paths.themes);
|
||||||
let themes = PathBuf::from("/var/www/htmlua/themes");
|
|
||||||
let _ = ts.add_from_folder(themes);
|
|
||||||
}
|
}
|
||||||
for node in syntax_elements {
|
for node in syntax_elements {
|
||||||
let attrs = match node.as_node().as_element() {
|
let attrs = match node.as_node().as_element() {
|
||||||
|
|
@ -158,7 +166,7 @@ pub fn process_syntax_highlighting(document: NodeRef) -> Result<NodeRef> {
|
||||||
None => continue,
|
None => continue,
|
||||||
};
|
};
|
||||||
let language = attrs.get("lang").unwrap_or("text");
|
let language = attrs.get("lang").unwrap_or("text");
|
||||||
let theme_name = attrs.get("theme").unwrap_or("base16-ocean.dark");
|
let theme_name = attrs.get("theme").unwrap_or(&config.syntax_highlighting.default_theme);
|
||||||
if let Some(text_node) = node.as_node().first_child() {
|
if let Some(text_node) = node.as_node().first_child() {
|
||||||
if let Some(code_text) = text_node.as_text() {
|
if let Some(code_text) = text_node.as_text() {
|
||||||
let syntax = ps
|
let syntax = ps
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,29 @@
|
||||||
use crate::helpers::read_doc_from_file;
|
use crate::{
|
||||||
|
config::Config,
|
||||||
use super::render::{execute_lua, expand_template, process_markdown, process_syntax_highlighting};
|
helpers::read_doc_from_file,
|
||||||
|
render::{execute_lua, expand_template, process_markdown, process_syntax_highlighting},
|
||||||
|
};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use std::path::{Path, PathBuf}
|
use std::{path::Path, sync::OnceLock};
|
||||||
;
|
|
||||||
|
static CONFIG: OnceLock<Config> = OnceLock::new();
|
||||||
|
|
||||||
|
pub fn get_config() -> &'static Config {
|
||||||
|
CONFIG.get_or_init(|| {
|
||||||
|
Config::load().unwrap_or_else(|e| {
|
||||||
|
eprintln!("Warning: Failed to load config: {}", e);
|
||||||
|
eprintln!("Using default configuration");
|
||||||
|
Config::default()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn serve_content(request_uri: &str) -> Result<String> {
|
pub fn serve_content(request_uri: &str) -> Result<String> {
|
||||||
// TODO: read from config
|
let config = get_config();
|
||||||
let pages = PathBuf::from("/var/www/htmlua/pages");
|
|
||||||
let components = PathBuf::from("/var/www/htmlua/components");
|
|
||||||
let safe_path = Path::new(request_uri).strip_prefix("/")?;
|
let safe_path = Path::new(request_uri).strip_prefix("/")?;
|
||||||
let page_path = pages.join(safe_path);
|
let page_path = config.paths.pages.join(safe_path);
|
||||||
|
|
||||||
let doc = read_doc_from_file(page_path)?;
|
let doc = read_doc_from_file(page_path)?;
|
||||||
|
let full_doc = expand_template(doc, &config.paths.components, None)?;
|
||||||
let full_doc = expand_template(doc, &components, None)?;
|
|
||||||
let markdown_doc = process_markdown(full_doc)?;
|
let markdown_doc = process_markdown(full_doc)?;
|
||||||
let highlighted_doc = process_syntax_highlighting(markdown_doc)?;
|
let highlighted_doc = process_syntax_highlighting(markdown_doc)?;
|
||||||
let executed_doc = execute_lua(highlighted_doc)?;
|
let executed_doc = execute_lua(highlighted_doc)?;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue