damn i definitely did something

This commit is contained in:
KitsuneCafe 2024-02-17 10:46:21 -05:00
parent 696bfa0afe
commit fbea17767b
4 changed files with 113 additions and 87 deletions

39
Cargo.lock generated
View file

@ -80,6 +80,12 @@ dependencies = [
"windows-sys", "windows-sys",
] ]
[[package]]
name = "anyhow"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.1.0" version = "1.1.0"
@ -134,9 +140,9 @@ dependencies = [
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.14.0" version = "3.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" checksum = "d32a994c2b3ca201d9b263612a374263f05e7adde37c4707f693dcd375076d1f"
[[package]] [[package]]
name = "cc" name = "cc"
@ -189,9 +195,9 @@ dependencies = [
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.0" version = "4.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f" checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
"clap_derive", "clap_derive",
@ -199,9 +205,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.5.0" version = "4.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99" checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb"
dependencies = [ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
@ -303,9 +309,9 @@ dependencies = [
[[package]] [[package]]
name = "deunicode" name = "deunicode"
version = "1.4.2" version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ae2a35373c5c74340b79ae6780b498b2b183915ec5dacf263aac5a099bf485a" checksum = "b6e854126756c496b8c81dec88f9a706b15b875c5849d4097a3854476b9fdf94"
[[package]] [[package]]
name = "digest" name = "digest"
@ -813,6 +819,7 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
name = "roxy_cli" name = "roxy_cli"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow",
"clap", "clap",
"glob", "glob",
"roxy_core", "roxy_core",
@ -830,7 +837,11 @@ dependencies = [
[[package]] [[package]]
name = "roxy_core" name = "roxy_core"
version = "0.1.0" version = "0.1.0"
source = "git+https://fem.mint.lgbt/kitsunecafe/roxy-core.git#7839db8b062698adfe81a86d2a0cf041a6711456" source = "git+https://fem.mint.lgbt/kitsunecafe/roxy-core.git#6b5b3520b0623af071ffd3053c60448c8a0b66d3"
dependencies = [
"anyhow",
"thiserror",
]
[[package]] [[package]]
name = "roxy_markdown_parser" name = "roxy_markdown_parser"
@ -854,7 +865,7 @@ dependencies = [
[[package]] [[package]]
name = "roxy_syntect" name = "roxy_syntect"
version = "0.1.0" version = "0.1.0"
source = "git+https://fem.mint.lgbt/kitsunecafe/roxy-syntect.git#48601fc5e6e0ee0e753c892f0eb42a9b0b48be99" source = "git+https://fem.mint.lgbt/kitsunecafe/roxy-syntect.git#4a872d3642a428fc91afe3a519e9e4d1f3a6d3d0"
dependencies = [ dependencies = [
"once_cell", "once_cell",
"regex", "regex",
@ -978,9 +989,9 @@ checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.48" version = "2.0.49"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" checksum = "915aea9e586f80826ee59f8453c1101f9d1c4b3964cd2460185ee8e299ada496"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1105,9 +1116,9 @@ dependencies = [
[[package]] [[package]]
name = "toml_edit" name = "toml_edit"
version = "0.22.5" version = "0.22.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99e68c159e8f5ba8a28c4eb7b0c0c190d77bb479047ca713270048145a9ad28a" checksum = "2c1b5fd4128cc8d3e0cb74d4ed9a9cc7c7284becd4df68f5f940e1ad123606f6"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"serde", "serde",

View file

@ -16,4 +16,5 @@ toml = "0.8.8"
tera = "1.19.1" tera = "1.19.1"
serde = { version = "1.0.195", features = ["derive"]} serde = { version = "1.0.195", features = ["derive"]}
slugify = "0.1.0" slugify = "0.1.0"
anyhow = "1.0.79"

View file

@ -1,7 +1,14 @@
use std::{path::Path, borrow::BorrowMut}; use std::{
borrow::BorrowMut,
fs::File,
io::{BufReader, Read},
path::{Path, PathBuf},
};
use tera::{Map, Value}; use crate::{file_path::FilePath, iter_ext::Head};
use crate::iter_ext::Head; use roxy_core::result::Result;
use tera::{to_value, Map, Value};
use toml::Table;
fn merge(a: &mut Value, b: Value) { fn merge(a: &mut Value, b: Value) {
match (a, b) { match (a, b) {
@ -24,17 +31,64 @@ pub(crate) struct Context {
impl Context { impl Context {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
inner: tera::Value::Null inner: tera::Value::Null,
} }
} }
pub fn merge(&mut self, other: tera::Context) { pub fn merge(&mut self, other: tera::Context) {
merge( merge(self.inner.borrow_mut(), other.into_json())
self.inner.borrow_mut(),
other.into_json()
)
} }
fn as_formatted_path<P: AsRef<Path>>(path: &P) -> Option<PathBuf> {
let path = path.as_ref();
if path.with_extension("").file_name()? == "index" {
Some(path.with_file_name(""))
} else {
Some(path.with_extension(""))
}
}
pub fn from_files<'a, T: AsRef<Path>>(
files: Vec<&PathBuf>,
file_path: &'a FilePath<T>,
) -> Result<Context> {
let mut context = Context::new();
for path in files {
let mut buf = Vec::new();
let mut file = File::open(path).map(BufReader::new)?;
file.read_to_end(&mut buf)?;
let mut str = String::from_utf8(buf).map_err(anyhow::Error::from)?;
let toml: Table = toml::from_str(&mut str).map_err(anyhow::Error::from)?;
let path = file_path.strip_root(path).map_err(anyhow::Error::from)?;
context.insert(&path, &tera::to_value(toml).map_err(anyhow::Error::from)?);
}
Ok(context)
}
pub fn build_paths<'a, T: AsRef<Path>>(
&mut self,
files: &Vec<&PathBuf>,
file_path: &'a FilePath<T>,
) -> Result<()> {
for path in files {
let path = file_path.strip_root(path).map_err(anyhow::Error::from)?;
if let Some(path) = Self::as_formatted_path(&path) {
if let Some(slug) = file_path.as_slug(&path) {
let slug = PathBuf::from("/").join(slug);
if let Ok(slug) = to_value(slug) {
self.insert(&path.join("path"), &slug);
}
}
}
}
Ok(())
}
fn path_to_string<P: AsRef<Path>>(path: &P) -> String { fn path_to_string<P: AsRef<Path>>(path: &P) -> String {
path.as_ref().to_string_lossy().to_string() path.as_ref().to_string_lossy().to_string()
@ -57,9 +111,9 @@ impl Context {
Some(map.into()) Some(map.into())
} }
pub fn insert<P: AsRef<Path>>(&mut self, path: &P, value: &Value) { fn as_key<P: AsRef<Path>>(path: &P) -> Option<&Path> {
let path = path.as_ref(); let path = path.as_ref();
let path = if path if path
.with_extension("") .with_extension("")
.file_name() .file_name()
.map_or(false, |f| f.to_os_string() == "index") .map_or(false, |f| f.to_os_string() == "index")
@ -67,7 +121,11 @@ impl Context {
path.parent() path.parent()
} else { } else {
Some(path) Some(path)
}; }
}
pub fn insert<P: AsRef<Path>>(&mut self, path: &P, value: &Value) {
let path = Self::as_key(path).map(|p| p.with_extension(""));
if let Some(v) = Self::create_path(&path.unwrap(), value) { if let Some(v) = Self::create_path(&path.unwrap(), value) {
if let Ok(ctx) = tera::Context::from_value(v) { if let Ok(ctx) = tera::Context::from_value(v) {
@ -76,8 +134,12 @@ impl Context {
} }
} }
pub fn get<P: AsRef<Path>>(&self, _path: &P) -> Option<&Value> { pub fn get<P: AsRef<Path>>(&self, path: &P) -> Option<&Value> {
None Self::as_key(path)?
.with_extension("")
.components()
.filter_map(|c| c.as_os_str().to_str())
.try_fold(&self.inner, |acc, i| acc.get(i))
} }
} }
@ -90,8 +152,7 @@ impl Into<tera::Value> for Context {
impl TryInto<tera::Context> for Context { impl TryInto<tera::Context> for Context {
type Error = tera::Error; type Error = tera::Error;
fn try_into(self) -> Result<tera::Context, Self::Error> { fn try_into(self) -> std::result::Result<tera::Context, Self::Error> {
tera::Context::from_value(self.inner) tera::Context::from_value(self.inner)
} }
} }

View file

@ -19,30 +19,21 @@ use roxy_tera_parser::{TeraParser, TeraParserOptions};
use clap::Parser as Clap; use clap::Parser as Clap;
use std::{ use std::{
ffi, ffi,
fs::{self, File}, fs,
io::{BufReader, Read},
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
use tera::to_value;
use syntect::{highlighting::ThemeSet, parsing::SyntaxSet}; use syntect::{highlighting::ThemeSet, parsing::SyntaxSet};
use toml::Table;
use glob::glob; use glob::glob;
use roxy_core::roxy::{Parser, Roxy}; use roxy_core::roxy::{Parser, Roxy};
use roxy_core::result::Result;
use crate::{ use crate::iter_ext::{Head, MapFoldExt};
iter_ext::{Head, MapFoldExt},
result_ext::FilterExt,
};
const DEFAULT_THEME: &'static str = "base16-ocean.dark"; const DEFAULT_THEME: &'static str = "base16-ocean.dark";
const CONTENT_EXT: [&'static str; 4] = ["md", "tera", "html", "htm"]; const CONTENT_EXT: [&'static str; 4] = ["md", "tera", "html", "htm"];
fn handle_err<E: std::error::Error + 'static>(err: E) -> Error {
Error::new(err.to_string(), err)
}
#[derive(Clap)] #[derive(Clap)]
#[command(name = "Roxy")] #[command(name = "Roxy")]
#[command(author = "KitsuneCafe")] #[command(author = "KitsuneCafe")]
@ -53,14 +44,14 @@ pub struct Options {
pub output: String, pub output: String,
} }
fn get_files<P: AsRef<Path> + std::fmt::Debug>(path: &P) -> Result<Vec<PathBuf>, Error> { fn get_files<P: AsRef<Path> + std::fmt::Debug>(path: &P) -> Result<Vec<PathBuf>> {
let path = path let path = path
.as_ref() .as_ref()
.to_str() .to_str()
.ok_or_else(|| Error::from(format!("{path:?} is not a valid path.")))?; .ok_or_else(|| anyhow::Error::msg(format!("{path:?} is not a valid path.")))?;
let files: Vec<PathBuf> = glob(path) let files: Vec<PathBuf> = glob(path)
.map_err(handle_err)? .map_err(anyhow::Error::from)?
.filter_map(|x| x.ok()) .filter_map(|x| x.ok())
.filter(|f| Path::is_file(f)) .filter(|f| Path::is_file(f))
.collect(); .collect();
@ -101,49 +92,10 @@ fn load_config(path: &Path) -> Config {
.into() .into()
} }
fn as_formatted_path<P: AsRef<Path>>(path: &P) -> Option<PathBuf> {
let path = path.as_ref();
if path.with_extension("").file_name()? == "index" {
Some(path.with_file_name(""))
} else {
Some(path.with_extension(""))
}
}
fn context_from_meta_files<'a, T: AsRef<Path>>(
files: &Vec<&PathBuf>,
file_path: &'a FilePath<T>,
) -> Result<Context, Error> {
let mut context = Context::new();
for path in files {
let mut buf = Vec::new();
let mut file = File::open(path).map(BufReader::new)?;
file.read_to_end(&mut buf)?;
let mut str = String::from_utf8(buf).map_err(handle_err)?;
let toml: Table = toml::from_str(&mut str).map_err(handle_err)?;
let path = file_path.strip_root(path)?;
context.insert(&path, &tera::to_value(toml).map_err(handle_err)?);
if let Some(path) = as_formatted_path(&path) {
if let Some(slug) = file_path.as_slug(&path) {
let slug = PathBuf::from("/").join(slug);
if let Ok(slug) = to_value(slug) {
context.insert(&path.join("path"), &slug);
}
}
}
}
Ok(context)
}
fn copy_static<T: AsRef<Path>>( fn copy_static<T: AsRef<Path>>(
files: &Vec<&PathBuf>, files: &Vec<&PathBuf>,
file_path: &FilePath<T>, file_path: &FilePath<T>,
) -> Result<(), Error> { ) -> Result<()> {
for file in files { for file in files {
let output = file_path.to_output(file).unwrap(); let output = file_path.to_output(file).unwrap();
fs::create_dir_all(output.parent().unwrap())?; fs::create_dir_all(output.parent().unwrap())?;
@ -153,7 +105,7 @@ fn copy_static<T: AsRef<Path>>(
Ok(()) Ok(())
} }
fn main() -> Result<(), Box<dyn std::error::Error>> { fn main() -> Result<()> {
let opts = Options::parse(); let opts = Options::parse();
let mut file_path = FilePath::new(&opts.input, &opts.output); let mut file_path = FilePath::new(&opts.input, &opts.output);
@ -173,7 +125,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
CONTENT_EXT.contains(&ext) CONTENT_EXT.contains(&ext)
}); });
let mut context: Context = context_from_meta_files(&meta, &file_path)?; let mut context = Context::from_files(meta, &file_path)?;
context.build_paths(&content, &file_path)?;
let theme = config.syntect.theme; let theme = config.syntect.theme;
@ -205,7 +158,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut rewriter = MarkdownTeraRewriter::new(); let mut rewriter = MarkdownTeraRewriter::new();
parser.push(&mut rewriter); parser.push(&mut rewriter);
if let Ok(path) = &file_path.strip_root(&file_name) { if let Ok(path) = &file_path.strip_root(&file) {
if let Some(current_context) = context.get(path) { if let Some(current_context) = context.get(path) {
context.insert(&"this", &current_context.clone()); context.insert(&"this", &current_context.clone());
} }