diff options
author | Daniel Silverstone <dsilvers+gitlab@digital-scurf.org> | 2023-02-01 23:49:11 +0000 |
---|---|---|
committer | Daniel Silverstone <dsilvers+gitlab@digital-scurf.org> | 2023-02-01 23:49:11 +0000 |
commit | b6df0fa5b7046bad97f63dc928a9776cecaee623 (patch) | |
tree | 7f2fe57569bdf9d77d0bc30e3fac78ba2d32ff92 | |
parent | e1d63019fdd6f0d24703197b6a6029f26e6f089f (diff) | |
parent | b160ad5b9f0e38859b0a6d3c3262afbb39067584 (diff) | |
download | subplot-b6df0fa5b7046bad97f63dc928a9776cecaee623.tar.gz |
Merge branch 'liw/refactor-md' into 'main'
improve Markdown API
See merge request subplot/subplot!307
-rw-r--r-- | src/doc.rs | 5 | ||||
-rw-r--r-- | src/lib.rs | 6 | ||||
-rw-r--r-- | src/md.rs | 98 | ||||
-rw-r--r-- | src/md/panhelper.rs (renamed from src/panhelper.rs) | 0 | ||||
-rw-r--r-- | src/md/typeset.rs (renamed from src/typeset.rs) | 0 | ||||
-rw-r--r-- | src/md/visitor/block_class.rs (renamed from src/visitor/block_class.rs) | 0 | ||||
-rw-r--r-- | src/md/visitor/embedded.rs (renamed from src/visitor/embedded.rs) | 2 | ||||
-rw-r--r-- | src/md/visitor/image.rs (renamed from src/visitor/image.rs) | 0 | ||||
-rw-r--r-- | src/md/visitor/linting.rs (renamed from src/visitor/linting.rs) | 2 | ||||
-rw-r--r-- | src/md/visitor/mod.rs (renamed from src/visitor/mod.rs) | 0 | ||||
-rw-r--r-- | src/md/visitor/structure.rs (renamed from src/visitor/structure.rs) | 2 | ||||
-rw-r--r-- | src/md/visitor/typesetting.rs (renamed from src/visitor/typesetting.rs) | 4 |
12 files changed, 55 insertions, 64 deletions
@@ -13,7 +13,6 @@ use crate::{Metadata, YamlMetadata}; use crate::{Warning, Warnings}; use std::collections::HashSet; -use std::convert::TryFrom; use std::default::Default; use std::fmt::Debug; use std::fs::read; @@ -105,7 +104,7 @@ impl Document { subplot: PathBuf, markdowns: Vec<PathBuf>, yamlmeta: &YamlMetadata, - mut md: Markdown, + md: Markdown, style: Style, template: Option<&str>, ) -> Result<Document, SubplotError> @@ -147,7 +146,7 @@ impl Document { let mdfile = meta.markdown(); let mdfile = basedir.join(mdfile); - let mut md = Markdown::try_from(mdfile.as_path())?; + let mut md = Markdown::load_file(mdfile.as_path())?; md.set_metadata(&meta); let markdowns = vec![mdfile]; @@ -27,12 +27,6 @@ mod embedded; pub use embedded::EmbeddedFile; pub use embedded::EmbeddedFiles; -mod panhelper; -mod typeset; - -mod visitor; -use visitor::LintingVisitor; - mod policy; pub use policy::get_basedir_from; @@ -1,34 +1,62 @@ //! A parsed Markdown document. use crate::{ - parse_scenario_snippet, visitor, Bindings, EmbeddedFiles, LintingVisitor, Scenario, - ScenarioStep, Style, SubplotError, Warning, YamlMetadata, + parse_scenario_snippet, Bindings, EmbeddedFiles, Scenario, ScenarioStep, Style, SubplotError, + Warning, YamlMetadata, }; use log::trace; use pandoc_ast::{Map, MetaValue, MutVisitor, Pandoc}; use serde_yaml::{Mapping, Value}; +use std::cell::RefCell; use std::collections::HashSet; -use std::convert::TryFrom; use std::path::{Path, PathBuf}; +mod panhelper; +mod typeset; + +mod visitor; +use visitor::LintingVisitor; + /// A parsed Markdown document. #[derive(Debug)] pub struct Markdown { - pandoc: Pandoc, + pandoc: RefCell<Pandoc>, } impl Markdown { - fn new(pandoc: Pandoc) -> Self { - Self { pandoc } + /// Load a Markdown file. + pub fn load_file(filename: &Path) -> Result<Self, SubplotError> { + trace!("parsing file as markdown: {}", filename.display()); + let mut pandoc = pandoc::new(); + pandoc.add_input(&filename); + pandoc.set_input_format( + pandoc::InputFormat::Markdown, + vec![pandoc::MarkdownExtension::Citations], + ); + pandoc.set_output_format(pandoc::OutputFormat::Json, vec![]); + pandoc.set_output(pandoc::OutputKind::Pipe); + + // Add external Pandoc filters. + crate::policy::add_citeproc(&mut pandoc); + + let json = match pandoc.execute().map_err(SubplotError::Pandoc)? { + pandoc::PandocOutput::ToBuffer(o) => o, + _ => return Err(SubplotError::NotJson), + }; + + let ast: Pandoc = serde_json::from_str(&json).map_err(SubplotError::AstJson)?; + Ok(Self::new(ast)) } - fn pandoc(&mut self) -> &mut Pandoc { - &mut self.pandoc + fn new(pandoc: Pandoc) -> Self { + Self { + pandoc: RefCell::new(pandoc), + } } /// Set document metadata from subplot. pub fn set_metadata(&mut self, meta: &YamlMetadata) { - self.pandoc.meta = to_pandoc_meta(meta); + self.pandoc.borrow_mut().meta = to_pandoc_meta(meta); } /// JSON representation of Pandoc AST. @@ -38,17 +66,17 @@ impl Markdown { } /// Find problems. - pub fn lint(&mut self) -> Vec<SubplotError> { + pub fn lint(&self) -> Vec<SubplotError> { let mut linter = LintingVisitor::default(); - linter.walk_pandoc(self.pandoc()); + linter.walk_pandoc(&mut self.pandoc.borrow_mut()); linter.issues } /// Find included images. - pub fn images(&mut self) -> Vec<PathBuf> { + pub fn images(&self) -> Vec<PathBuf> { let mut names = vec![]; let mut visitor = visitor::ImageVisitor::new(); - visitor.walk_pandoc(self.pandoc()); + visitor.walk_pandoc(&mut self.pandoc.borrow_mut()); for x in visitor.images().iter() { names.push(x.to_path_buf()); } @@ -56,31 +84,28 @@ impl Markdown { } /// Find classes used for fenced blocks. - pub fn block_classes(&mut self) -> HashSet<String> { + pub fn block_classes(&self) -> HashSet<String> { let mut visitor = visitor::BlockClassVisitor::default(); - // Irritatingly we can't immutably visit the AST for some reason - // This clone() is expensive and unwanted, but I'm not sure how - // to get around it for now - visitor.walk_pandoc(self.pandoc()); + visitor.walk_pandoc(&mut self.pandoc.borrow_mut()); visitor.classes } /// Typeset. pub fn typeset(&mut self, style: Style, bindings: &Bindings) -> Vec<Warning> { let mut visitor = visitor::TypesettingVisitor::new(style, bindings); - visitor.walk_pandoc(self.pandoc()); + visitor.walk_pandoc(&mut self.pandoc.borrow_mut()); visitor.warnings().warnings().to_vec() } /// Find scenarios. - pub fn scenarios(&mut self) -> Result<Vec<Scenario>, SubplotError> { + pub fn scenarios(&self) -> Result<Vec<Scenario>, SubplotError> { trace!( "Metadata::scenarios: looking for scenarios: {:#?}", self.pandoc ); let mut visitor = visitor::StructureVisitor::new(); - visitor.walk_pandoc(self.pandoc()); + visitor.walk_pandoc(&mut self.pandoc.borrow_mut()); trace!( "Metadata::scenarios: visitor found {} elements: {:#?}", visitor.elements.len(), @@ -102,9 +127,9 @@ impl Markdown { } /// Find embedded files. - pub fn embedded_files(&mut self) -> EmbeddedFiles { + pub fn embedded_files(&self) -> EmbeddedFiles { let mut files = EmbeddedFiles::default(); - files.walk_pandoc(self.pandoc()); + files.walk_pandoc(&mut self.pandoc.borrow_mut()); files } } @@ -209,33 +234,6 @@ fn meta_path_bufs(v: &[PathBuf]) -> MetaValue { MetaValue::MetaList(v.iter().map(|p| meta_path_buf(p)).collect()) } -impl TryFrom<&Path> for Markdown { - type Error = SubplotError; - - fn try_from(filename: &Path) -> Result<Self, Self::Error> { - trace!("parsing file as markdown: {}", filename.display()); - let mut pandoc = pandoc::new(); - pandoc.add_input(&filename); - pandoc.set_input_format( - pandoc::InputFormat::Markdown, - vec![pandoc::MarkdownExtension::Citations], - ); - pandoc.set_output_format(pandoc::OutputFormat::Json, vec![]); - pandoc.set_output(pandoc::OutputKind::Pipe); - - // Add external Pandoc filters. - crate::policy::add_citeproc(&mut pandoc); - - let json = match pandoc.execute().map_err(SubplotError::Pandoc)? { - pandoc::PandocOutput::ToBuffer(o) => o, - _ => return Err(SubplotError::NotJson), - }; - - let ast: Pandoc = serde_json::from_str(&json).map_err(SubplotError::AstJson)?; - Ok(Self::new(ast)) - } -} - fn extract_scenario(e: &[visitor::Element]) -> Result<(Option<Scenario>, usize), SubplotError> { if e.is_empty() { // If we get here, it's a programming error. diff --git a/src/panhelper.rs b/src/md/panhelper.rs index f7ab801..f7ab801 100644 --- a/src/panhelper.rs +++ b/src/md/panhelper.rs diff --git a/src/typeset.rs b/src/md/typeset.rs index f63206a..f63206a 100644 --- a/src/typeset.rs +++ b/src/md/typeset.rs diff --git a/src/visitor/block_class.rs b/src/md/visitor/block_class.rs index 303616b..303616b 100644 --- a/src/visitor/block_class.rs +++ b/src/md/visitor/block_class.rs diff --git a/src/visitor/embedded.rs b/src/md/visitor/embedded.rs index 891240b..840d9ed 100644 --- a/src/visitor/embedded.rs +++ b/src/md/visitor/embedded.rs @@ -1,4 +1,4 @@ -use crate::panhelper; +use crate::md::panhelper; use crate::EmbeddedFile; use crate::EmbeddedFiles; diff --git a/src/visitor/image.rs b/src/md/visitor/image.rs index be49d66..be49d66 100644 --- a/src/visitor/image.rs +++ b/src/md/visitor/image.rs diff --git a/src/visitor/linting.rs b/src/md/visitor/linting.rs index 6266516..d64b03e 100644 --- a/src/visitor/linting.rs +++ b/src/md/visitor/linting.rs @@ -1,4 +1,4 @@ -use crate::panhelper; +use crate::md::panhelper; use crate::SubplotError; use pandoc_ast::{Block, MutVisitor}; diff --git a/src/visitor/mod.rs b/src/md/visitor/mod.rs index 1c095ac..1c095ac 100644 --- a/src/visitor/mod.rs +++ b/src/md/visitor/mod.rs diff --git a/src/visitor/structure.rs b/src/md/visitor/structure.rs index f5693a6..d8faef6 100644 --- a/src/visitor/structure.rs +++ b/src/md/visitor/structure.rs @@ -1,4 +1,4 @@ -use crate::panhelper; +use crate::md::panhelper; use pandoc_ast::{Block, Inline, MutVisitor}; diff --git a/src/visitor/typesetting.rs b/src/md/visitor/typesetting.rs index da9c362..2405c03 100644 --- a/src/visitor/typesetting.rs +++ b/src/md/visitor/typesetting.rs @@ -1,5 +1,5 @@ -use crate::panhelper; -use crate::typeset; +use crate::md::panhelper; +use crate::md::typeset; use crate::{Bindings, Style, Warnings}; use pandoc_ast::{Block, Inline, MutVisitor}; |