add zephyr-cli

This commit is contained in:
annieversary 2022-09-09 18:54:18 +02:00
parent f56e0ec207
commit 527feed89a
5 changed files with 235 additions and 0 deletions

View File

@ -3,6 +3,9 @@ name = "zephyr"
version = "0.1.0"
edition = "2021"
[workspace]
members = ["zephyr-cli"]
[features]
default = []

View File

@ -4,6 +4,7 @@ zephyr is a [[https://tailwindcss.com/][tailwind]]-inspired css generator dsl. i
[[https://versary.town/zephyr/][playground]]
** how to use
*** as a library
to generate the css out of the list of classes, call =Zephyr::generate_classes=
#+begin_src rust
@ -21,6 +22,8 @@ let css = z.generate_classes(classes);
#+end_src
see [[examples/html.rs][examples/html.rs]] for a more detailed usage example
*** as a cli program
first go into =zephyr-cli= and run =cargo install --path .=. =zephry-cli= will now be available. you can use it like so: =zephyr-cli . -wr -o my.css=
** how to define classes
*** property and value
in the most simple case, classes have a property and a value: =name[value]=. zephyr will take this and generate the following css:

102
zephyr-cli/Cargo.lock generated Normal file
View File

@ -0,0 +1,102 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "once_cell"
version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0"
[[package]]
name = "pin-project-lite"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
[[package]]
name = "proc-macro2"
version = "1.0.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "1.0.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tracing"
version = "0.1.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307"
dependencies = [
"cfg-if",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tracing-core"
version = "0.1.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7"
dependencies = [
"once_cell",
]
[[package]]
name = "unicode-ident"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
[[package]]
name = "zephyr"
version = "0.1.0"
dependencies = [
"tracing",
]
[[package]]
name = "zephyr-cli"
version = "0.1.0"
dependencies = [
"zephyr",
]

12
zephyr-cli/Cargo.toml Normal file
View File

@ -0,0 +1,12 @@
[package]
name = "zephyr-cli"
version = "0.1.0"
edition = "2021"
[dependencies]
clap = { version = "3.2.12", features = ["derive", "wrap_help"] }
color-eyre = "0.6.2"
notify = "5.0.0"
notify-debouncer-mini = "0.2.1"
walkdir = "2.3.2"
zephyr = { path = "..", features = ["scraping"] }

115
zephyr-cli/src/main.rs Normal file
View File

@ -0,0 +1,115 @@
use std::{
path::{Path, PathBuf},
time::Duration,
};
use clap::Parser;
use color_eyre::eyre::Result;
use notify::RecursiveMode;
use notify_debouncer_mini::new_debouncer;
use walkdir::{self, WalkDir};
use zephyr::{scraping::*, Zephyr};
/// generate css :)
#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
struct Args {
/// file or directory
#[clap(value_parser)]
path: PathBuf,
/// output path. defaults to `zephyr.css`
#[clap(short, long, value_parser)]
output: Option<PathBuf>,
#[clap(short, long, value_parser)]
watch: bool,
/// use regex instead of an html parser to extract the classes
#[clap(short, long, value_parser)]
regex: bool,
/// disables recursion into subdirectories
#[clap(short, long, value_parser)]
no_recurse: bool,
}
fn main() -> Result<()> {
color_eyre::install()?;
let args = Args::parse();
let output = args.output.unwrap_or_else(|| PathBuf::from("zephyr.css"));
// this makes it so we can call canonicalize
std::fs::write(&output, "")?;
let output_canonical = output.canonicalize()?;
let z = Zephyr::new();
run(&z, &args.path, &output, args.regex, args.no_recurse)?;
println!("generated {}", output.as_os_str().to_string_lossy());
if args.watch {
let (tx, rx) = std::sync::mpsc::channel();
let mut debouncer = new_debouncer(Duration::from_secs(3), None, tx).unwrap();
debouncer
.watcher()
.watch(
&args.path,
if args.no_recurse {
RecursiveMode::NonRecursive
} else {
RecursiveMode::Recursive
},
)
.unwrap();
loop {
if let Ok(Ok(e)) = rx.recv() {
if e.into_iter().any(|e| e.path != output_canonical) {
run(&z, &args.path, &output, args.regex, args.no_recurse)?;
println!("generated {}", output.as_os_str().to_string_lossy());
}
}
}
}
Ok(())
}
fn run(z: &Zephyr, source: &Path, output: &Path, regex: bool, no_recurse: bool) -> Result<()> {
let mut files = vec![];
if source.is_dir() {
let mut w = WalkDir::new(source).follow_links(true);
if no_recurse {
w = w.max_depth(1);
}
for entry in w.into_iter().flatten() {
if entry.path().is_file() {
files.push(entry.into_path());
}
}
} else {
files.push(source.to_path_buf());
}
// TODO skip unneeded allocations
// it currently turns stuff to strings and vecs cause lifetime stuff
let classes = files
.into_iter()
.flat_map(std::fs::read_to_string)
.flat_map(|f| {
if regex {
get_classes_regex(&f)
.into_iter()
.map(ToString::to_string)
.collect::<Vec<_>>()
} else {
get_classes(&f)
}
})
.collect::<Vec<_>>();
let css = z.generate_classes(classes.iter().map(String::as_str));
std::fs::write(output, css)?;
Ok(())
}