From 316b90d5c645702336c08d1f5e7d716f993ca6a6 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 27 Mar 2021 12:18:04 +0000 Subject: bin: Add filter support to subplot binary Signed-off-by: Daniel Silverstone --- src/bin/subplot.rs | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file 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, + + #[structopt(name = "OUTPUT", long = "output", short = "o", parse(from_os_str))] + /// Output file (uses STDOUT if omitted) + output: Option, + + #[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, +} + +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(); -- cgit v1.2.1