summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2020-02-15 08:35:43 +0200
committerLars Wirzenius <liw@liw.fi>2020-02-15 09:00:18 +0200
commite975bd5b30eb7f3f46cba32e16ca813e110bc497 (patch)
tree9e33c085db46629672b566bfd7712c002a2c6ed3
parentb0c3b2f3158611caf3f7bcc4ce8b277abde1e035 (diff)
downloadsubplot-e975bd5b30eb7f3f46cba32e16ca813e110bc497.tar.gz
Change: require docgen, codegen to fail if document has no title
sp-filter already has a test that requires it to work without a title.
-rw-r--r--src/ast.rs9
-rw-r--r--src/bin/sp-codegen.rs2
-rw-r--r--src/bin/sp-docgen.rs1
-rw-r--r--subplot.md43
-rw-r--r--subplot.py13
-rw-r--r--subplot.yaml9
-rw-r--r--templates/python.py6
7 files changed, 80 insertions, 3 deletions
diff --git a/src/ast.rs b/src/ast.rs
index e6fd5db..f59d9f4 100644
--- a/src/ast.rs
+++ b/src/ast.rs
@@ -109,6 +109,15 @@ impl<'a> Document {
self.files.files()
}
+ /// Check that document has a title in its metadata.
+ pub fn has_title(&self) -> Result<()> {
+ if self.meta().title().is_empty() {
+ Err(Error::no_title())
+ } else {
+ Ok(())
+ }
+ }
+
/// Typeset a Subplot document.
pub fn typeset(&mut self) {
let mut visitor = TypesettingVisitor::new(&self.meta.bindings);
diff --git a/src/bin/sp-codegen.rs b/src/bin/sp-codegen.rs
index 3342b97..e15a8e2 100644
--- a/src/bin/sp-codegen.rs
+++ b/src/bin/sp-codegen.rs
@@ -50,6 +50,8 @@ fn main() -> Result<()> {
let scenarios = doc.matched_scenarios()?;
let meta = doc.meta();
+ doc.has_title()?;
+
let mut context = Context::new();
context.insert("scenarios", &scenarios);
diff --git a/src/bin/sp-docgen.rs b/src/bin/sp-docgen.rs
index c9e4879..fc53e47 100644
--- a/src/bin/sp-docgen.rs
+++ b/src/bin/sp-docgen.rs
@@ -52,6 +52,7 @@ fn main() -> subplot::Result<()> {
// file from the AST.
pandoc.add_filter(|json| {
let mut doc = subplot::Document::from_json(&json).expect("error parsing JSON AST");
+ doc.has_title().expect("document has no title");
doc.typeset();
doc.ast().expect("error serializing into JSON AST")
});
diff --git a/subplot.md b/subplot.md
index 7c72ea8..59e9736 100644
--- a/subplot.md
+++ b/subplot.md
@@ -736,6 +736,49 @@ given precondition foo
~~~~
+### Document titles
+
+The document and code generators require a document title, because
+it's a common user error to not have one, and Subplot should help make
+good documents. The Pandoc filter, however, mustn't require a document
+title, because it's used for things like formatting websites using
+ikiwiki, and ikiwiki has a different way of specifying page titles.
+
+#### Document generator gives an error if input document lacks title
+
+~~~scenario
+given file notitle.md
+when I try to run sp-docgen notitle.md -o foo.md
+then exit code is non-zero
+~~~
+
+~~~{.file #notitle.md .markdown .numberLines}
+---
+bindings: b.yaml
+functions: f.py
+...
+
+
+# Introduction
+
+This is a very simple Markdown file without a YAML metadata block,
+and thus also no document title.
+
+```scenario
+given precondition foo
+when I do bar
+then bar was done
+~~~
+
+#### Code generator gives an error if input document lacks title
+
+~~~scenario
+given file notitle.md
+when I try to run sp-codegen --run notitle.md -o test.py
+then exit code is non-zero
+~~~
+
+
Using a Pandoc filter
-----------------------------------------------------------------------------
diff --git a/subplot.py b/subplot.py
index f4549ee..57b0fa5 100644
--- a/subplot.py
+++ b/subplot.py
@@ -6,15 +6,21 @@ def create_file(ctx, filename=None):
with open(filename, 'wb') as f:
f.write(get_file(filename))
-def run_docgen(ctx, md=None, output=None):
+def try_docgen(ctx, md=None, output=None):
docgen = binary('sp-docgen')
runcmd(ctx, [docgen, md, '-o', output])
+
+def run_docgen(ctx, md=None, output=None):
+ try_docgen(ctx, md=md, output=output)
exit_code_zero(ctx)
-def run_codegen(ctx, filename=None):
+def try_codegen(ctx, filename=None):
codegen = binary('sp-codegen')
tmpldir = os.path.join(srcdir, 'templates')
runcmd(ctx, [codegen, filename, '-o', 'test.py', '--run', '--templates', tmpldir])
+
+def run_codegen(ctx, filename=None):
+ try_codegen(ctx, filename=filename)
exit_code_zero(ctx)
def run_meta(ctx, filename=None):
@@ -50,6 +56,9 @@ def exit_code_zero(ctx):
print('context:', ctx.as_dict())
assert_eq(ctx.get('exit'), 0)
+def exit_code_nonzero(ctx):
+ assert_ne(ctx.get('exit'), 0)
+
def binary(basename):
return os.path.join(srcdir, 'target', 'debug', basename)
diff --git a/subplot.yaml b/subplot.yaml
index 1f8acb2..e309d78 100644
--- a/subplot.yaml
+++ b/subplot.yaml
@@ -4,15 +4,24 @@
- when: I run sp-docgen (?P<md>\S+) -o (?P<output>\S+)
function: run_docgen
+- when: I try to run sp-docgen (?P<md>\S+) -o (?P<output>\S+)
+ function: try_docgen
+
- when: I run sp-codegen --run (?P<filename>\S+) -o test.py
function: run_codegen
+- when: I try to run sp-codegen --run (?P<filename>\S+) -o test.py
+ function: try_codegen
+
- when: I run sp-meta (?P<filename>\S+)
function: run_meta
- when: I run pandoc --filter sp-filter (?P<filename>\S+) -o (?P<output>\S+)
function: run_pandoc_with_filter
+- then: exit code is non-zero
+ function: exit_code_nonzero
+
- then: file (?P<filename>\S+) exists
function: file_exists
diff --git a/templates/python.py b/templates/python.py
index d8905f1..5768534 100644
--- a/templates/python.py
+++ b/templates/python.py
@@ -43,10 +43,14 @@ _files['''{{ file.filename }}'''] = '''{{ file.contents | base64 }}'''
def get_file(filename):
return base64.b64decode(_files[filename])
-# Check two values for equality and give error if they
+# Check two values for equality and give error if they are not equal
def assert_eq(a, b):
assert a == b, 'expected %r == %r' % (a, b)
+# Check two values for inequality and give error if they are equal
+def assert_ne(a, b):
+ assert a != b, 'expected %r != %r' % (a, b)
+
# Remember where we started from. The step functions may need to refer
# to files there.
srcdir = os.getcwd()