summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2022-04-02 12:40:52 +0300
committerLars Wirzenius <liw@liw.fi>2022-04-10 15:57:57 +0300
commitc9627df005b5344f437c9eaaa98bb5fe00c47313 (patch)
tree2ef11b14d1c6f3600fe3e806720d324b38b4d7fe
parent85212e8ddc54c6ede71912127eaf84aac403f10d (diff)
downloadsubplot-c9627df005b5344f437c9eaaa98bb5fe00c47313.tar.gz
feat: make typesetting issues into warnings
Sponsored-by: author
-rw-r--r--src/doc.rs1
-rw-r--r--src/error.rs11
-rw-r--r--src/typeset.rs14
-rw-r--r--src/visitor/typesetting.rs15
4 files changed, 30 insertions, 11 deletions
diff --git a/src/doc.rs b/src/doc.rs
index db37389..660b83a 100644
--- a/src/doc.rs
+++ b/src/doc.rs
@@ -436,6 +436,7 @@ impl<'a> Document {
let mut visitor =
visitor::TypesettingVisitor::new(self.style.clone(), self.meta.bindings());
visitor.walk_pandoc(&mut self.ast);
+ self.warnings.push_all(visitor.warnings());
}
/// Return all scenarios in a document.
diff --git a/src/error.rs b/src/error.rs
index 6e7eddd..13d6a6c 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -342,7 +342,7 @@ pub type Result<T> = std::result::Result<T, SubplotError>;
/// A warning, or non-fatal error.
///
/// Errors prevent Subplot from producing output. Warnings don't do that.
-#[derive(Debug, thiserror::Error)]
+#[derive(Debug, Clone, thiserror::Error)]
pub enum Warning {
/// Document refers to an embedded file that doesn't exist.
#[error(
@@ -357,6 +357,10 @@ pub enum Warning {
/// Missing step implementation.
#[error("Missing step implementation: \"{1}\"\n in scenario \"{0}\"")]
MissingStepImplementation(String, String),
+
+ /// Unknown binding when typesetting a scenario.
+ #[error("Unknown binding: {0}")]
+ UnknownBinding(String),
}
/// A list of warnings.
@@ -374,6 +378,11 @@ impl Warnings {
self.warnings.push(w);
}
+ /// Append all warnings from one list to another.
+ pub fn push_all(&mut self, mut other: Warnings) {
+ self.warnings.append(&mut other.warnings);
+ }
+
/// Return a slice with all the warnings in the list.
pub fn warnings(&self) -> &[Warning] {
&self.warnings
diff --git a/src/typeset.rs b/src/typeset.rs
index c6301e4..49b8aed 100644
--- a/src/typeset.rs
+++ b/src/typeset.rs
@@ -5,6 +5,7 @@ use crate::ScenarioStep;
use crate::StepKind;
use crate::SubplotError;
use crate::{DotMarkup, GraphMarkup, PikchrMarkup, PlantumlMarkup};
+use crate::{Warning, Warnings};
use pandoc_ast::Attr;
use pandoc_ast::Block;
@@ -53,13 +54,13 @@ pub fn file_block(attr: &Attr, text: &str) -> Block {
///
/// The snippet is given as a text string, which is parsed. It need
/// not be a complete scenario, but it should consist of complete steps.
-pub fn scenario_snippet(bindings: &Bindings, snippet: &str) -> Block {
+pub fn scenario_snippet(bindings: &Bindings, snippet: &str, warnings: &mut Warnings) -> Block {
let lines = parse_scenario_snippet(snippet);
let mut steps = vec![];
let mut prevkind: Option<StepKind> = None;
for line in lines {
- let (this, thiskind) = step(bindings, line, prevkind);
+ let (this, thiskind) = step(bindings, line, prevkind, warnings);
steps.push(this);
prevkind = thiskind;
}
@@ -71,6 +72,7 @@ fn step(
bindings: &Bindings,
text: &str,
prevkind: Option<StepKind>,
+ warnings: &mut Warnings,
) -> (Vec<Inline>, Option<StepKind>) {
let step = ScenarioStep::new_from_str(text, prevkind);
if step.is_err() {
@@ -84,11 +86,9 @@ fn step(
let m = match bindings.find("", &step) {
Ok(m) => m,
Err(e) => {
- eprintln!("Could not select binding: {:?}", e);
- return (
- error_msg(&format!("Could not select binding for: {}", text)),
- prevkind,
- );
+ let w = Warning::UnknownBinding(format!("{}", e));
+ warnings.push(w.clone());
+ return (error_msg(&format!("{}", w)), prevkind);
}
};
diff --git a/src/visitor/typesetting.rs b/src/visitor/typesetting.rs
index e29a434..f2f435e 100644
--- a/src/visitor/typesetting.rs
+++ b/src/visitor/typesetting.rs
@@ -1,6 +1,6 @@
use crate::panhelper;
use crate::typeset;
-use crate::{Bindings, Style};
+use crate::{Bindings, Style, Warnings};
use pandoc_ast::{Block, Inline, MutVisitor};
@@ -10,11 +10,20 @@ use pandoc_ast::{Block, Inline, MutVisitor};
pub struct TypesettingVisitor<'a> {
style: Style,
bindings: &'a Bindings,
+ warnings: Warnings,
}
impl<'a> TypesettingVisitor<'a> {
pub fn new(style: Style, bindings: &'a Bindings) -> Self {
- TypesettingVisitor { style, bindings }
+ TypesettingVisitor {
+ style,
+ bindings,
+ warnings: Warnings::default(),
+ }
+ }
+
+ pub fn warnings(self) -> Warnings {
+ self.warnings
}
}
@@ -30,7 +39,7 @@ impl<'a> MutVisitor for TypesettingVisitor<'a> {
match block {
Block::CodeBlock(attr, s) => {
if is_class(attr, "scenario") {
- *block = typeset::scenario_snippet(self.bindings, s)
+ *block = typeset::scenario_snippet(self.bindings, s, &mut self.warnings)
} else if is_class(attr, "file") {
*block = typeset::file_block(attr, s)
} else if is_class(attr, "dot") {