summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers+gitlab@digital-scurf.org>2023-02-01 23:49:11 +0000
committerDaniel Silverstone <dsilvers+gitlab@digital-scurf.org>2023-02-01 23:49:11 +0000
commitb6df0fa5b7046bad97f63dc928a9776cecaee623 (patch)
tree7f2fe57569bdf9d77d0bc30e3fac78ba2d32ff92
parente1d63019fdd6f0d24703197b6a6029f26e6f089f (diff)
parentb160ad5b9f0e38859b0a6d3c3262afbb39067584 (diff)
downloadsubplot-b6df0fa5b7046bad97f63dc928a9776cecaee623.tar.gz
Merge branch 'liw/refactor-md' into 'main'
improve Markdown API See merge request subplot/subplot!307
-rw-r--r--src/doc.rs5
-rw-r--r--src/lib.rs6
-rw-r--r--src/md.rs98
-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
diff --git a/src/doc.rs b/src/doc.rs
index a39ab99..faa3a84 100644
--- a/src/doc.rs
+++ b/src/doc.rs
@@ -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];
diff --git a/src/lib.rs b/src/lib.rs
index 1ae64d4..90c183f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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;
diff --git a/src/md.rs b/src/md.rs
index 15fe57a..f43b462 100644
--- a/src/md.rs
+++ b/src/md.rs
@@ -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};