Add option to configure watch debounce time

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/6/head v0.31.1
trivernis 3 years ago
parent b21a6ddb5d
commit 31a4abff39
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

2
Cargo.lock generated

@ -2127,7 +2127,7 @@ checksum = "ae524f056d7d770e174287294f562e95044c68e88dec909a00d2094805db9d75"
[[package]] [[package]]
name = "snekdown" name = "snekdown"
version = "0.31.0" version = "0.31.1"
dependencies = [ dependencies = [
"asciimath-rs", "asciimath-rs",
"base64 0.12.3", "base64 0.12.3",

@ -1,6 +1,6 @@
[package] [package]
name = "snekdown" name = "snekdown"
version = "0.31.0" version = "0.31.1"
authors = ["trivernis <trivernis@protonmail.com>"] authors = ["trivernis <trivernis@protonmail.com>"]
edition = "2018" edition = "2018"
license-file = "LICENSE" license-file = "LICENSE"

@ -37,27 +37,50 @@ SUBCOMMANDS:
watch Watch the document and its imports and render on change watch Watch the document and its imports and render on change
``` ```
### Rendering / Watching ### Rendering
``` ```
Parse and render the document Parse and render the document
USAGE: USAGE:
snekdown render [FLAGS] [OPTIONS] <input> <output> snekdown render [OPTIONS] <input> <output>
FLAGS: FLAGS:
-h, --help Prints help information -h, --help Prints help information
--no-cache Don't use the cache -V, --version Prints version information
-V, --version Prints version information
OPTIONS: OPTIONS:
-f, --format <format> the output format [default: html] -f, --format <format> the output format [default: html]
ARGS:
<input> Path to the input file
<output> Path for the output file
```
### Watching
```
Watch the document and its imports and render on change
USAGE:
snekdown watch [OPTIONS] <input> <output>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
--debounce <debounce> The amount of time in milliseconds to wait after changes before rendering [default:
500]
-f, --format <format> the output format [default: html]
ARGS: ARGS:
<input> Path to the input file <input> Path to the input file
<output> Path for the output file <output> Path for the output file
``` ```
## Syntax ## Syntax
### Images ### Images

@ -16,17 +16,17 @@ use std::sync::mpsc::channel;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use structopt::StructOpt; use structopt::StructOpt;
#[derive(StructOpt, Debug)] #[derive(StructOpt, Debug, Clone)]
struct Opt { struct Opt {
#[structopt(subcommand)] #[structopt(subcommand)]
sub_command: SubCommand, sub_command: SubCommand,
} }
#[derive(StructOpt, Debug)] #[derive(StructOpt, Debug, Clone)]
#[structopt()] #[structopt()]
enum SubCommand { enum SubCommand {
/// Watch the document and its imports and render on change. /// Watch the document and its imports and render on change.
Watch(RenderOptions), Watch(WatchOptions),
/// Parse and render the document. /// Parse and render the document.
Render(RenderOptions), Render(RenderOptions),
@ -35,7 +35,7 @@ enum SubCommand {
ClearCache, ClearCache,
} }
#[derive(StructOpt, Debug)] #[derive(StructOpt, Debug, Clone)]
#[structopt()] #[structopt()]
struct RenderOptions { struct RenderOptions {
/// Path to the input file /// Path to the input file
@ -49,10 +49,17 @@ struct RenderOptions {
/// the output format /// the output format
#[structopt(short, long, default_value = "html")] #[structopt(short, long, default_value = "html")]
format: String, format: String,
}
#[derive(StructOpt, Debug, Clone)]
#[structopt()]
struct WatchOptions {
/// The amount of time in milliseconds to wait after changes before rendering
#[structopt(long, default_value = "500")]
debounce: u64,
/// Don't use the cache #[structopt(flatten)]
#[structopt(long)] render_options: RenderOptions,
no_cache: bool,
} }
fn main() { fn main() {
@ -101,16 +108,17 @@ fn get_level_style(level: Level) -> colored::Color {
} }
/// Watches a file with all of its imports and renders on change /// Watches a file with all of its imports and renders on change
fn watch(opt: &RenderOptions) { fn watch(opt: &WatchOptions) {
let parser = render(opt); let parser = render(&opt.render_options);
let (tx, rx) = channel(); let (tx, rx) = channel();
let mut watcher = watcher(tx, Duration::from_millis(250)).unwrap(); let mut watcher = watcher(tx, Duration::from_millis(opt.debounce)).unwrap();
for path in parser.get_paths() { for path in parser.get_paths() {
watcher.watch(path, RecursiveMode::NonRecursive).unwrap(); watcher.watch(path, RecursiveMode::NonRecursive).unwrap();
} }
while let Ok(_) = rx.recv() { while let Ok(_) = rx.recv() {
println!("---"); println!("---");
let parser = render(opt); let parser = render(&opt.render_options);
for path in parser.get_paths() { for path in parser.get_paths() {
watcher.watch(path, RecursiveMode::NonRecursive).unwrap(); watcher.watch(path, RecursiveMode::NonRecursive).unwrap();
} }
@ -129,11 +137,7 @@ fn render(opt: &RenderOptions) -> Parser {
} }
let start = Instant::now(); let start = Instant::now();
let mut parser = Parser::with_defaults( let mut parser = Parser::with_defaults(ParserOptions::default().add_path(opt.input.clone()));
ParserOptions::default()
.add_path(opt.input.clone())
.use_cache(!opt.no_cache),
);
let document = parser.parse(); let document = parser.parse();
log::info!("Parsing + Processing took: {:?}", start.elapsed()); log::info!("Parsing + Processing took: {:?}", start.elapsed());

@ -58,13 +58,6 @@ impl ParserOptions {
self self
} }
/// If external sources should be cached when after downloaded
pub fn use_cache(self, value: bool) -> Self {
self.document.downloads.lock().use_cache = value;
self
}
} }
pub struct Parser { pub struct Parser {
@ -159,18 +152,6 @@ impl Parser {
); );
return Err(self.ctm.assert_error(None)); return Err(self.ctm.assert_error(None));
} }
{
let mut paths = self.options.paths.lock().unwrap();
if paths.iter().find(|item| **item == path) != None {
log::warn!(
"Import of \"{}\" failed: Already imported.\n\t--> {}\n",
path.to_str().unwrap(),
self.get_position_string(),
);
return Err(self.ctm.assert_error(None));
}
paths.push(path.clone());
}
let anchor = Arc::new(RwLock::new(ImportAnchor::new())); let anchor = Arc::new(RwLock::new(ImportAnchor::new()));
let anchor_clone = Arc::clone(&anchor); let anchor_clone = Arc::clone(&anchor);
let wg = self.wg.clone(); let wg = self.wg.clone();
@ -277,6 +258,18 @@ impl Parser {
} }
} }
} }
{
let mut paths = self.options.paths.lock().unwrap();
if paths.iter().find(|item| **item == path).is_some() {
log::warn!(
"Import of \"{}\" failed: Already imported.\n\t--> {}\n",
path.to_str().unwrap(),
self.get_position_string(),
);
return ImportType::None;
}
paths.push(path.clone());
}
match args.get("type").map(|e| e.as_string().to_lowercase()) { match args.get("type").map(|e| e.as_string().to_lowercase()) {
Some(s) if s == "stylesheet".to_string() => { Some(s) if s == "stylesheet".to_string() => {
ImportType::Stylesheet(self.import_stylesheet(path)) ImportType::Stylesheet(self.import_stylesheet(path))

@ -10,7 +10,6 @@ use std::sync::Arc;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct DownloadManager { pub struct DownloadManager {
downloads: Vec<Arc<Mutex<PendingDownload>>>, downloads: Vec<Arc<Mutex<PendingDownload>>>,
pub use_cache: bool,
} }
impl DownloadManager { impl DownloadManager {
@ -18,14 +17,12 @@ impl DownloadManager {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
downloads: Vec::new(), downloads: Vec::new(),
use_cache: true,
} }
} }
/// Adds a new pending download /// Adds a new pending download
pub fn add_download(&mut self, path: String) -> Arc<Mutex<PendingDownload>> { pub fn add_download(&mut self, path: String) -> Arc<Mutex<PendingDownload>> {
let mut download = PendingDownload::new(path.clone()); let download = PendingDownload::new(path.clone());
download.use_cache = self.use_cache;
let pending = Arc::new(Mutex::new(download)); let pending = Arc::new(Mutex::new(download));
self.downloads.push(Arc::clone(&pending)); self.downloads.push(Arc::clone(&pending));
log::debug!("Added download {}", path); log::debug!("Added download {}", path);

Loading…
Cancel
Save