summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers+gitlab@digital-scurf.org>2020-06-20 15:19:03 +0000
committerDaniel Silverstone <dsilvers+gitlab@digital-scurf.org>2020-06-20 15:19:03 +0000
commit35aa4d6710389e5b5b364109ac5a0cb375112d87 (patch)
tree2cb10fa7995c88c54bab014ab9b809fa6ee47a6e
parentf9e5f30e17f22240dee3a6b99fafea7ec0a0a066 (diff)
parent5ad766749a214a0ce0b320258d16fb5a74fa81b6 (diff)
downloadsubplot-35aa4d6710389e5b5b364109ac5a0cb375112d87.tar.gz
Merge branch 'extract' into 'master'
Add sp-extract Closes #41 See merge request larswirzenius/subplot!53
-rw-r--r--files.py9
-rw-r--r--files.yaml3
-rw-r--r--src/ast.rs2
-rw-r--r--src/bin/sp-extract.rs46
-rw-r--r--src/error.rs4
-rw-r--r--src/lib.rs1
-rw-r--r--subplot.md29
-rw-r--r--subplot.py6
-rw-r--r--subplot.yaml3
9 files changed, 102 insertions, 1 deletions
diff --git a/files.py b/files.py
index 9ee1739..1a7451f 100644
--- a/files.py
+++ b/files.py
@@ -50,6 +50,15 @@ def file_matches(ctx, filename=None, regex=None):
assert_eq(bool(m), True)
+# Check that two files have the same content
+def files_match(ctx, filename1=None, filename2=None):
+ with open(filename1, "rb") as f:
+ data1 = f.read()
+ with open(filename2, "rb") as f:
+ data2 = f.read()
+ assert_eq(data1, data2)
+
+
# Check that a file contains a fixed string.
def file_contains(ctx, filename=None, pattern=None):
with open(filename) as f:
diff --git a/files.yaml b/files.yaml
index 2cc53e1..4fc44ac 100644
--- a/files.yaml
+++ b/files.yaml
@@ -21,6 +21,9 @@
function: file_matches
regex: true
+- then: files {filename1} and {filename2} match
+ function: files_match
+
- then: file (?P<filename>\S+) contains "(?P<pattern>.+)"
function: file_contains
regex: true
diff --git a/src/ast.rs b/src/ast.rs
index 4e1d33b..fedacc2 100644
--- a/src/ast.rs
+++ b/src/ast.rs
@@ -981,10 +981,12 @@ impl DataFile {
DataFile { filename, contents }
}
+ /// Return name of embedded file.
pub fn filename(&self) -> &str {
&self.filename
}
+ /// Return contents of embedded file.
pub fn contents(&self) -> &str {
&self.contents
}
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 daef85c..451ff54 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -194,6 +194,10 @@ pub enum SubplotError {
#[error("template.yaml does not specify how to run generated program")]
TemplateNoRun,
+ /// An embedded file was not found.
+ #[error("embedded 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/src/lib.rs b/src/lib.rs
index d717a36..c2a2ec7 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -14,6 +14,7 @@ pub use graphmarkup::{DotMarkup, GraphMarkup, PlantumlMarkup};
mod ast;
pub use ast::get_basedir_from;
+pub use ast::DataFile;
pub use ast::Document;
mod scenarios;
diff --git a/subplot.md b/subplot.md
index d975e97..a73b805 100644
--- a/subplot.md
+++ b/subplot.md
@@ -2178,8 +2178,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