summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2020-06-08 07:58:46 +0300
committerLars Wirzenius <liw@liw.fi>2020-06-08 08:06:12 +0300
commitb16749ca50ced58631e79aadf0f74152c24435de (patch)
treee8b04ec94c1ba0a05b900297dfee67c1984d74dd
parent163ec445c2474698ba073333c11140be6bb4fddc (diff)
downloadsubplot-b16749ca50ced58631e79aadf0f74152c24435de.tar.gz
feat: add sp-extract for extracting data files from subplots
-rw-r--r--src/bin/sp-extract.rs46
-rw-r--r--src/error.rs4
-rw-r--r--subplot.md29
-rw-r--r--subplot.py6
-rw-r--r--subplot.yaml3
5 files changed, 87 insertions, 1 deletions
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<String>,
+
+ // 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