diff options
author | Lars Wirzenius <liw@liw.fi> | 2022-04-02 12:40:52 +0300 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2022-04-10 15:57:57 +0300 |
commit | c9627df005b5344f437c9eaaa98bb5fe00c47313 (patch) | |
tree | 2ef11b14d1c6f3600fe3e806720d324b38b4d7fe | |
parent | 85212e8ddc54c6ede71912127eaf84aac403f10d (diff) | |
download | subplot-c9627df005b5344f437c9eaaa98bb5fe00c47313.tar.gz |
feat: make typesetting issues into warnings
Sponsored-by: author
-rw-r--r-- | src/doc.rs | 1 | ||||
-rw-r--r-- | src/error.rs | 11 | ||||
-rw-r--r-- | src/typeset.rs | 14 | ||||
-rw-r--r-- | src/visitor/typesetting.rs | 15 |
4 files changed, 30 insertions, 11 deletions
@@ -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") { |