Broke up modules
This commit is contained in:
parent
2bebd0e540
commit
07f304066a
18
Cargo.lock
generated
18
Cargo.lock
generated
|
@ -824,6 +824,7 @@ dependencies = [
|
||||||
"roxy_core",
|
"roxy_core",
|
||||||
"roxy_markdown_parser",
|
"roxy_markdown_parser",
|
||||||
"roxy_markdown_tera_rewriter",
|
"roxy_markdown_tera_rewriter",
|
||||||
|
"roxy_syntect",
|
||||||
"roxy_tera_parser",
|
"roxy_tera_parser",
|
||||||
"serde",
|
"serde",
|
||||||
"syntect",
|
"syntect",
|
||||||
|
@ -848,15 +849,28 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "roxy_markdown_tera_rewriter"
|
name = "roxy_markdown_tera_rewriter"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
source = "git+https://fem.mint.lgbt/kitsunecafe/roxy-markdown-tera-rewriter.git#5c33c0c2625c239694c8b7bb16f5da902cfd5e44"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"regex",
|
"regex",
|
||||||
"roxy_core",
|
"roxy_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "roxy_syntect"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://fem.mint.lgbt/kitsunecafe/roxy-syntect.git#0cdfa876f9ca13be475dfac77b0d37ebb7d45da3"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"regex",
|
||||||
|
"roxy_core",
|
||||||
|
"syntect",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "roxy_tera_parser"
|
name = "roxy_tera_parser"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
source = "git+https://fem.mint.lgbt/kitsunecafe/roxy-tera-parser.git#d8bd4aa1f0bbe4f9982ae17711ed69fead71c327"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"regex",
|
"regex",
|
||||||
|
@ -1370,9 +1384,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winnow"
|
name = "winnow"
|
||||||
version = "0.5.36"
|
version = "0.5.37"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "818ce546a11a9986bc24f93d0cdf38a8a1a400f1473ea8c82e59f6e0ffab9249"
|
checksum = "a7cad8365489051ae9f054164e459304af2e7e9bb407c958076c8bf4aef52da5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
|
@ -9,6 +9,7 @@ syntect = "5.1.0"
|
||||||
roxy_markdown_parser = { git = "https://fem.mint.lgbt/kitsunecafe/roxy-markdown-parser.git" }
|
roxy_markdown_parser = { git = "https://fem.mint.lgbt/kitsunecafe/roxy-markdown-parser.git" }
|
||||||
roxy_tera_parser = { git = "https://fem.mint.lgbt/kitsunecafe/roxy-tera-parser.git" }
|
roxy_tera_parser = { git = "https://fem.mint.lgbt/kitsunecafe/roxy-tera-parser.git" }
|
||||||
roxy_markdown_tera_rewriter = { git = "https://fem.mint.lgbt/kitsunecafe/roxy-markdown-tera-rewriter.git" }
|
roxy_markdown_tera_rewriter = { git = "https://fem.mint.lgbt/kitsunecafe/roxy-markdown-tera-rewriter.git" }
|
||||||
|
roxy_syntect = { git = "https://fem.mint.lgbt/kitsunecafe/roxy-syntect.git" }
|
||||||
roxy_core = { git = "https://fem.mint.lgbt/kitsunecafe/roxy-core.git" }
|
roxy_core = { git = "https://fem.mint.lgbt/kitsunecafe/roxy-core.git" }
|
||||||
clap = { version = "4.4.17", features = ["derive"] }
|
clap = { version = "4.4.17", features = ["derive"] }
|
||||||
toml = "0.8.8"
|
toml = "0.8.8"
|
||||||
|
|
31
src/config.rs
Normal file
31
src/config.rs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize)]
|
||||||
|
pub(crate) struct Config {
|
||||||
|
pub theme: Option<String>,
|
||||||
|
pub themes: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
pub fn merge(self, other: Config) -> Self {
|
||||||
|
Self {
|
||||||
|
theme: self.theme.or(other.theme),
|
||||||
|
themes: if self.themes.is_empty() {
|
||||||
|
other.themes
|
||||||
|
} else {
|
||||||
|
self.themes
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Config {
|
||||||
|
type Err = toml::de::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
toml::from_str(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
39
src/context.rs
Normal file
39
src/context.rs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
use std::path::{Path, MAIN_SEPARATOR_STR};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct Context {
|
||||||
|
inner: tera::Context,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Context {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
inner: tera::Context::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_inner(&self) -> &tera::Context {
|
||||||
|
&self.inner
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn normalize_path<P: AsRef<Path>>(path: &P) -> String {
|
||||||
|
path.as_ref()
|
||||||
|
.with_extension("")
|
||||||
|
.to_string_lossy()
|
||||||
|
.trim()
|
||||||
|
.split(MAIN_SEPARATOR_STR)
|
||||||
|
.fold(String::new(), |a, b| format!("{a}.{b}"))
|
||||||
|
.trim_matches('.')
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert<P: AsRef<Path>>(&mut self, path: &P, value: &tera::Value) {
|
||||||
|
self.inner
|
||||||
|
.insert(Self::normalize_path(path).trim_start_matches('.'), &value);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get<P: AsRef<Path>>(&self, path: &P) -> Option<&tera::Value> {
|
||||||
|
self.inner.get(&Self::normalize_path(path))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
36
src/error.rs
Normal file
36
src/error.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
use std::{io::{Error as IOError, ErrorKind}, path::StripPrefixError};
|
||||||
|
|
||||||
|
use glob::PatternError;
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Error {
|
||||||
|
message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for Error {
|
||||||
|
fn from(value: String) -> Self {
|
||||||
|
Self { message: value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<PatternError> for Error {
|
||||||
|
fn from(value: PatternError) -> Self {
|
||||||
|
Self {
|
||||||
|
message: value.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<StripPrefixError> for Error {
|
||||||
|
fn from(value: StripPrefixError) -> Self {
|
||||||
|
Self {
|
||||||
|
message: value.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Error> for IOError {
|
||||||
|
fn from(value: Error) -> Self {
|
||||||
|
IOError::new(ErrorKind::Other, value.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
52
src/file_path.rs
Normal file
52
src/file_path.rs
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
use std::path::{PathBuf, Path, StripPrefixError};
|
||||||
|
|
||||||
|
use crate::error::Error;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub(crate) struct FilePath<'a, P: AsRef<Path>> {
|
||||||
|
pub input: PathBuf,
|
||||||
|
pub root_dir: PathBuf,
|
||||||
|
pub output: &'a P,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, P: AsRef<Path> + 'a> FilePath<'a, P> {
|
||||||
|
pub fn new(input: &'a P, output: &'a P) -> Self {
|
||||||
|
Self {
|
||||||
|
input: Self::make_recursive(input),
|
||||||
|
root_dir: Self::strip_wildcards(input),
|
||||||
|
output,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_recursive(path: &'a P) -> PathBuf {
|
||||||
|
path.as_ref().join("**/*")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_no_wildcard<S: AsRef<str>>(path: &S) -> bool {
|
||||||
|
!path.as_ref().contains("*")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn strip_wildcards<P2: AsRef<Path> + ?Sized>(path: &'a P2) -> PathBuf {
|
||||||
|
path.as_ref()
|
||||||
|
.ancestors()
|
||||||
|
.map(Path::to_str)
|
||||||
|
.flatten()
|
||||||
|
.find(Self::has_no_wildcard)
|
||||||
|
.map_or_else(|| PathBuf::new(), PathBuf::from)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_output<P2: AsRef<Path>>(&self, value: &'a P2) -> Result<PathBuf, Error> {
|
||||||
|
value
|
||||||
|
.as_ref()
|
||||||
|
.strip_prefix(&self.root_dir)
|
||||||
|
.map(|path| self.output.as_ref().join(path))
|
||||||
|
.map_err(Error::from)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn strip_root<P2: AsRef<Path>>(&self, value: &'a P2) -> Result<&Path, StripPrefixError> {
|
||||||
|
value.as_ref().strip_prefix(&self.root_dir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
159
src/main.rs
159
src/main.rs
|
@ -1,17 +1,29 @@
|
||||||
|
pub mod error;
|
||||||
|
pub mod context;
|
||||||
|
pub mod config;
|
||||||
|
mod file_path;
|
||||||
|
|
||||||
use clap::Parser as Clap;
|
use clap::Parser as Clap;
|
||||||
|
use config::Config;
|
||||||
|
use context::Context;
|
||||||
|
use file_path::FilePath;
|
||||||
|
use crate::error::Error;
|
||||||
use roxy_markdown_parser::MarkdownParser;
|
use roxy_markdown_parser::MarkdownParser;
|
||||||
use roxy_markdown_tera_rewriter::{MarkdownTeraRewriter, MarkdownTeraPreformatter};
|
use roxy_markdown_tera_rewriter::{MarkdownTeraPreformatter, MarkdownTeraRewriter};
|
||||||
|
use roxy_syntect::SyntectParser;
|
||||||
use roxy_tera_parser::{TeraParser, TeraParserOptions};
|
use roxy_tera_parser::{TeraParser, TeraParserOptions};
|
||||||
use std::{
|
use std::{
|
||||||
fs::File,
|
fs::{self, File},
|
||||||
io::{BufReader, Error, ErrorKind, Read},
|
io::{BufReader, Read},
|
||||||
path::{self, Path, PathBuf, StripPrefixError},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
use toml::Table;
|
use toml::Table;
|
||||||
|
|
||||||
use glob::{glob, PatternError};
|
use glob::glob;
|
||||||
use roxy_core::roxy::{Parser, Roxy};
|
use roxy_core::roxy::{Parser, Roxy};
|
||||||
|
|
||||||
|
const DEFAULT_THEME: &'static str = "base16-ocean.dark";
|
||||||
|
|
||||||
#[derive(Clap)]
|
#[derive(Clap)]
|
||||||
#[command(name = "Roxy")]
|
#[command(name = "Roxy")]
|
||||||
#[command(author = "KitsuneCafe")]
|
#[command(author = "KitsuneCafe")]
|
||||||
|
@ -22,44 +34,11 @@ pub struct Options {
|
||||||
pub output: String,
|
pub output: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
fn get_files<P: AsRef<Path> + std::fmt::Debug>(path: &P) -> Result<Vec<PathBuf>, Error> {
|
||||||
struct RoxyError {
|
|
||||||
message: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<String> for RoxyError {
|
|
||||||
fn from(value: String) -> Self {
|
|
||||||
Self { message: value }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<PatternError> for RoxyError {
|
|
||||||
fn from(value: PatternError) -> Self {
|
|
||||||
Self {
|
|
||||||
message: value.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<StripPrefixError> for RoxyError {
|
|
||||||
fn from(value: StripPrefixError) -> Self {
|
|
||||||
Self {
|
|
||||||
message: value.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<RoxyError> for Error {
|
|
||||||
fn from(value: RoxyError) -> Self {
|
|
||||||
Error::new(ErrorKind::Other, value.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_files<P: AsRef<Path> + std::fmt::Debug>(path: &P) -> Result<Vec<PathBuf>, RoxyError> {
|
|
||||||
let path = path
|
let path = path
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.to_str()
|
.to_str()
|
||||||
.ok_or_else(|| RoxyError::from(format!("{path:?} is not a valid path.")))?;
|
.ok_or_else(|| Error::from(format!("{path:?} is not a valid path.")))?;
|
||||||
|
|
||||||
let files: Vec<PathBuf> = glob(path)?
|
let files: Vec<PathBuf> = glob(path)?
|
||||||
.filter_map(|x| x.ok())
|
.filter_map(|x| x.ok())
|
||||||
|
@ -69,89 +48,21 @@ fn get_files<P: AsRef<Path> + std::fmt::Debug>(path: &P) -> Result<Vec<PathBuf>,
|
||||||
Ok(files)
|
Ok(files)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
fn main() -> Result<(), Error> {
|
||||||
struct FilePath<'a, P: AsRef<Path>> {
|
|
||||||
input: PathBuf,
|
|
||||||
root_dir: PathBuf,
|
|
||||||
output: &'a P,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, P: AsRef<Path> + 'a> FilePath<'a, P> {
|
|
||||||
pub fn new(input: &'a P, output: &'a P) -> Self {
|
|
||||||
Self {
|
|
||||||
input: Self::make_recursive(input),
|
|
||||||
root_dir: Self::strip_wildcards(input),
|
|
||||||
output,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn make_recursive(path: &'a P) -> PathBuf {
|
|
||||||
path.as_ref().join("**/*")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn has_no_wildcard<S: AsRef<str>>(path: &S) -> bool {
|
|
||||||
!path.as_ref().contains("*")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn strip_wildcards<P2: AsRef<Path> + ?Sized>(path: &'a P2) -> PathBuf {
|
|
||||||
path.as_ref()
|
|
||||||
.ancestors()
|
|
||||||
.map(Path::to_str)
|
|
||||||
.flatten()
|
|
||||||
.find(Self::has_no_wildcard)
|
|
||||||
.map_or_else(|| PathBuf::new(), PathBuf::from)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_output<P2: AsRef<Path>>(&self, value: &'a P2) -> Result<PathBuf, RoxyError> {
|
|
||||||
value
|
|
||||||
.as_ref()
|
|
||||||
.strip_prefix(&self.root_dir)
|
|
||||||
.map(|path| self.output.as_ref().join(path))
|
|
||||||
.map_err(RoxyError::from)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn strip_root<P2: AsRef<Path>>(&self, value: &'a P2) -> Result<&Path, StripPrefixError> {
|
|
||||||
value.as_ref().strip_prefix(&self.root_dir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct Context {
|
|
||||||
pub inner: tera::Context,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Context {
|
|
||||||
fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
inner: tera::Context::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn normalize_path<P: AsRef<Path>>(path: &P) -> String {
|
|
||||||
path.as_ref()
|
|
||||||
.with_extension("")
|
|
||||||
.to_string_lossy()
|
|
||||||
.trim()
|
|
||||||
.split(path::MAIN_SEPARATOR_STR)
|
|
||||||
.fold(String::new(), |a, b| format!("{a}.{b}"))
|
|
||||||
.trim_matches('.')
|
|
||||||
.to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn insert<P: AsRef<Path>>(&mut self, path: &P, value: &tera::Value) {
|
|
||||||
self.inner
|
|
||||||
.insert(Self::normalize_path(path).trim_start_matches('.'), &value);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get<P: AsRef<Path>>(&self, path: &P) -> Option<&tera::Value> {
|
|
||||||
self.inner.get(&Self::normalize_path(path))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() -> Result<(), RoxyError> {
|
|
||||||
let opts = Options::parse();
|
let opts = Options::parse();
|
||||||
|
|
||||||
let file_path = FilePath::new(&opts.input, &opts.output);
|
let file_path = FilePath::new(&opts.input, &opts.output);
|
||||||
|
|
||||||
|
let config_path = file_path.input.with_file_name("config.toml");
|
||||||
|
let config = fs::read_to_string(&config_path).map_or_else(
|
||||||
|
|_| Config::default(),
|
||||||
|
|f| {
|
||||||
|
toml::from_str::<Config>(f.as_str())
|
||||||
|
.unwrap()
|
||||||
|
.merge(Config::default())
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
let files = get_files(&file_path.input)?;
|
let files = get_files(&file_path.input)?;
|
||||||
let (meta, files): (Vec<&PathBuf>, Vec<&PathBuf>) =
|
let (meta, files): (Vec<&PathBuf>, Vec<&PathBuf>) =
|
||||||
files.iter().partition(|f| f.extension().unwrap() == "toml");
|
files.iter().partition(|f| f.extension().unwrap() == "toml");
|
||||||
|
@ -172,11 +83,15 @@ fn main() -> Result<(), RoxyError> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let theme = config.theme.unwrap_or(DEFAULT_THEME.to_string());
|
||||||
for file in files {
|
for file in files {
|
||||||
let mut parser = Parser::new();
|
let mut parser = Parser::new();
|
||||||
let mut preformatter = MarkdownTeraPreformatter::new();
|
let mut preformatter = MarkdownTeraPreformatter::new();
|
||||||
parser.push(&mut preformatter);
|
parser.push(&mut preformatter);
|
||||||
|
|
||||||
|
let mut syntect = SyntectParser::new(&theme.as_str());
|
||||||
|
parser.push(&mut syntect);
|
||||||
|
|
||||||
let mut md = MarkdownParser::new();
|
let mut md = MarkdownParser::new();
|
||||||
parser.push(&mut md);
|
parser.push(&mut md);
|
||||||
|
|
||||||
|
@ -194,10 +109,10 @@ fn main() -> Result<(), RoxyError> {
|
||||||
|
|
||||||
let mut tera = tera::Tera::default();
|
let mut tera = tera::Tera::default();
|
||||||
let mut html = TeraParser::new(&mut tera, TeraParserOptions::default());
|
let mut html = TeraParser::new(&mut tera, TeraParserOptions::default());
|
||||||
html.add_context(&context.inner);
|
html.add_context(context.to_inner());
|
||||||
parser.push(&mut html);
|
parser.push(&mut html);
|
||||||
|
|
||||||
Roxy::process_file(&file, &output_path, &mut parser).unwrap();
|
Roxy::process_file(&file, &output_path, &mut parser).unwrap();
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue