summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2021-03-27 12:18:04 +0000
committerDaniel Silverstone <dsilvers@digital-scurf.org>2021-04-09 16:42:49 +0100
commit316b90d5c645702336c08d1f5e7d716f993ca6a6 (patch)
tree2004fbfa3ae1d3ba9301993c418322705091f076
parentc01c05e6cb9199832b9067b66f757044b7493170 (diff)
downloadsubplot-316b90d5c645702336c08d1f5e7d716f993ca6a6.tar.gz
bin: Add filter support to subplot binary
Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
-rw-r--r--src/bin/subplot.rs58
1 files changed, 55 insertions, 3 deletions
diff --git a/src/bin/subplot.rs b/src/bin/subplot.rs
index 38e129e..94c4b53 100644
--- a/src/bin/subplot.rs
+++ b/src/bin/subplot.rs
@@ -4,10 +4,11 @@
use anyhow::Result;
use structopt::StructOpt;
-use subplot::{resource, DataFile, Style};
+use subplot::{resource, DataFile, Document, Style};
-use std::fs::write;
-use std::path::PathBuf;
+use std::fs::{write, File};
+use std::io::{Read, Write};
+use std::path::{Path, PathBuf};
use std::process;
mod cli;
@@ -30,12 +31,14 @@ impl Toplevel {
#[derive(Debug, StructOpt)]
enum Cmd {
Extract(Extract),
+ Filter(Filter),
}
impl Cmd {
fn run(&self) -> Result<()> {
match self {
Cmd::Extract(e) => e.run(),
+ Cmd::Filter(f) => f.run(),
}
}
}
@@ -98,6 +101,55 @@ impl Extract {
}
}
+#[derive(Debug, StructOpt)]
+/// Filter a pandoc JSON document.
+///
+/// This filters a pandoc JSON document, applying Subplot's formatting rules and
+/// image conversion support.
+///
+/// If input/output filename is provided, this operates on STDIN/STDOUT.
+struct Filter {
+ #[structopt(name = "INPUT", long = "input", short = "i", parse(from_os_str))]
+ /// Input file (uses STDIN if omitted)
+ input: Option<PathBuf>,
+
+ #[structopt(name = "OUTPUT", long = "output", short = "o", parse(from_os_str))]
+ /// Output file (uses STDOUT if omitted)
+ output: Option<PathBuf>,
+
+ #[structopt(name = "BASE", long = "base", short = "b", parse(from_os_str))]
+ /// Base directory (defaults to dir of input if given, or '.' if using STDIN)
+ base: Option<PathBuf>,
+}
+
+impl Filter {
+ fn run(&self) -> Result<()> {
+ let mut buffer = String::new();
+ if let Some(filename) = &self.input {
+ File::open(filename)?.read_to_string(&mut buffer)?;
+ } else {
+ std::io::stdin().read_to_string(&mut buffer)?;
+ }
+ let basedir = if let Some(path) = &self.base {
+ path.as_path()
+ } else if let Some(path) = &self.input {
+ path.parent().unwrap_or_else(|| Path::new("."))
+ } else {
+ Path::new(".")
+ };
+ let style = Style::default();
+ let mut doc = Document::from_json(basedir, vec![], &buffer, style)?;
+ doc.typeset();
+ let bytes = doc.ast()?.into_bytes();
+ if let Some(filename) = &self.output {
+ File::create(filename)?.write_all(&bytes)?;
+ } else {
+ std::io::stdout().write_all(&bytes)?;
+ }
+ Ok(())
+ }
+}
+
fn main() {
let args = Toplevel::from_args();
args.resources.handle();