From b16749ca50ced58631e79aadf0f74152c24435de Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Mon, 8 Jun 2020 07:58:46 +0300 Subject: feat: add sp-extract for extracting data files from subplots --- src/bin/sp-extract.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/error.rs | 4 ++++ subplot.md | 29 ++++++++++++++++++++++++++++- subplot.py | 6 ++++++ subplot.yaml | 3 +++ 5 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 src/bin/sp-extract.rs diff --git a/src/bin/sp-extract.rs b/src/bin/sp-extract.rs new file mode 100644 index 0000000..d63fa0a --- /dev/null +++ b/src/bin/sp-extract.rs @@ -0,0 +1,46 @@ +use anyhow::Result; +use std::fs::write; +use std::path::PathBuf; + +use structopt::StructOpt; + +use subplot::{DataFile, Document, SubplotError}; + +#[derive(Debug, StructOpt)] +#[structopt(name = "sp-meta", about = "Show Subplot document metadata.")] +struct Opt { + /// Input subplot document filename + #[structopt(parse(from_os_str))] + filename: PathBuf, + + /// Names of embedded files to be extracted. + #[structopt()] + embedded: Vec, + + // Set output directory. + #[structopt(name = "DIR", long = "--directory", short = "-o", parse(from_os_str))] + directory: PathBuf, +} + +fn main() -> Result<()> { + let opt = Opt::from_args(); + let basedir = subplot::get_basedir_from(&opt.filename)?; + let doc = Document::from_file(&basedir, &opt.filename)?; + + for filename in opt.embedded { + let file = get_embedded(&doc, &filename)?; + let output = opt.directory.join(filename); + write(output, file.contents())?; + } + + Ok(()) +} + +fn get_embedded<'a>(doc: &'a Document, filename: &str) -> Result<&'a DataFile> { + for file in doc.files() { + if file.filename() == filename { + return Ok(file); + } + } + Err(SubplotError::EmbeddedFileNotFound(filename.to_owned()).into()) +} diff --git a/src/error.rs b/src/error.rs index f988c86..1f4fcc7 100644 --- a/src/error.rs +++ b/src/error.rs @@ -187,6 +187,10 @@ pub enum SubplotError { #[error("template.yaml does not specify how to run generated program")] TemplateNoRun, + /// An embedded file was not found. + #[error("emedded file {0} was not found in the subplot document")] + EmbeddedFileNotFound(String), + /// I/O error /// /// Subplot did some I/O, and it failed. This is a generic wrapper diff --git a/subplot.md b/subplot.md index b2cdecf..e0a31b2 100644 --- a/subplot.md +++ b/subplot.md @@ -2093,8 +2093,35 @@ It does not have a YAML metadata block. ~~~~~~~~ +# Extract embedded files + +`sp-extract` extracts embedded files from a subplot file. + +~~~scenario +given file embedded-file.md +and file expected.txt +when I run sp-extract embedded-file.md foo.txt -d . +then files foo.txt and expected.txt match +~~~ + +~~~~~~{#embedded-file.md .file .markdown .numberLines} +--- +title: Embedded file +... + +~~~{#foo.txt .file} +This is a test file. +~~~ + +~~~~~~ + +~~~{#expected.txt .file} +This is a test file. +~~~ + + + - --- title: "Subplot" author: The Subplot project diff --git a/subplot.py b/subplot.py index fa3d502..1bb42d7 100644 --- a/subplot.py +++ b/subplot.py @@ -61,6 +61,12 @@ def run_meta_json(ctx, filename=None): exit_code_is(ctx, 0) +def run_extract(ctx, filename=None, embedded=None, dirname=None): + extract = binary("sp-extract") + runcmd(ctx, [extract, filename, embedded, "-o", dirname]) + exit_code_is(ctx, 0) + + def run_pandoc_with_filter(ctx, filename=None, output=None): sp_filter = binary("sp-filter") runcmd(ctx, ["pandoc", "--filter", sp_filter, filename, "-o", output]) diff --git a/subplot.yaml b/subplot.yaml index 84e52e4..0b63302 100644 --- a/subplot.yaml +++ b/subplot.yaml @@ -28,6 +28,9 @@ - when: I run sp-meta {filename} -o json function: run_meta_json +- when: I run sp-extract {filename} {embedded} -d {dirname} + function: run_extract + - when: I run pandoc --filter sp-filter {filename} -o {output} function: run_pandoc_with_filter -- cgit v1.2.1