diff options
author | Lars Wirzenius <liw@liw.fi> | 2022-09-03 13:47:16 +0300 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2022-09-06 07:24:31 +0300 |
commit | 765b2e1d4d94b2274de28d4efd24bfe77e8d93ac (patch) | |
tree | a7c22c35da5811f19fa02772ecc6498d87d63030 /src/doc.rs | |
parent | c230684f3bab80154d5224d4f2f71eafd00fd100 (diff) | |
download | subplot-765b2e1d4d94b2274de28d4efd24bfe77e8d93ac.tar.gz |
feat! read document metadata from a YAML file
This is a huge change all in one commit, sorry. However, as it changes
a fundamental part of the command line interface (namely, what
constitutes as the input file), there doesn't seem a way to break this
into a tidy series of small commits.
Most of the diff is in subplot.md, where every scenario that invokes
Subplot needs multiple changes, thus touching much of the file.
The overall change is that where we previously had document metadata
in embedded YAML in the Markdown file, we now have it in a separate
YAML file. The Markdown file is named in the YAML file.
We still parse the Markdown with Pandoc for everything, except
codegen. Switching from Pandoc to pulldown_cmark for parsing will be
another big change that I didn't want to include in this huge change
set.
Sponsored-by: author
Diffstat (limited to 'src/doc.rs')
-rw-r--r-- | src/doc.rs | 51 |
1 files changed, 38 insertions, 13 deletions
@@ -12,12 +12,14 @@ use crate::Scenario; use crate::ScenarioStep; use crate::Style; use crate::SubplotError; +use crate::YamlMetadata; use crate::{bindings::CaptureType, parser::parse_scenario_snippet}; use crate::{Warning, Warnings}; use std::collections::HashSet; use std::default::Default; use std::fmt::Debug; +use std::fs::read; use std::ops::Deref; use std::path::{Path, PathBuf}; @@ -58,7 +60,7 @@ static KNOWN_PANDOC_CLASSES: &[&str] = &["numberLines", "noNumberLines"]; /// # Example /// /// fix this example; -/// ~~~~ +/// ~~~~ignored /// let markdown = "\ /// --- /// title: Test Title @@ -114,6 +116,7 @@ impl Document { fn from_ast<P>( basedir: P, markdowns: Vec<PathBuf>, + yamlmeta: &ast::YamlMetadata, mut ast: Pandoc, style: Style, template: Option<&str>, @@ -121,7 +124,7 @@ impl Document { where P: AsRef<Path> + Debug, { - let meta = Metadata::new(basedir, &ast, template)?; + let meta = Metadata::new(basedir, yamlmeta, template)?; let mut linter = LintingVisitor::default(); trace!("Walking AST for linting..."); linter.walk_pandoc(&mut ast); @@ -151,10 +154,15 @@ impl Document { basedir.display(), filename.display() ); - let markdowns = vec![filename.to_path_buf()]; + + let meta = load_metadata_from_yaml_file(filename)?; + + let mdfile = meta.markdown(); + let mdfile = basedir.join(mdfile); + let markdowns = vec![mdfile.clone()]; let mut pandoc = pandoc::new(); - pandoc.add_input(&filename); + pandoc.add_input(&mdfile); pandoc.set_input_format( pandoc::InputFormat::Markdown, vec![pandoc::MarkdownExtension::Citations], @@ -167,7 +175,7 @@ impl Document { trace!( "Invoking Pandoc to parse document {:?} into AST as JSON", - filename + mdfile, ); let json = match pandoc.execute().map_err(SubplotError::Pandoc)? { pandoc::PandocOutput::ToBuffer(o) => o, @@ -176,8 +184,9 @@ impl Document { trace!("Pandoc was happy"); trace!("Parsing document AST as JSON..."); - let ast: Pandoc = serde_json::from_str(&json).map_err(SubplotError::AstJson)?; - let doc = Self::from_ast(basedir, markdowns, ast, style, template)?; + let mut ast: Pandoc = serde_json::from_str(&json).map_err(SubplotError::AstJson)?; + ast.meta = meta.to_map(); + let doc = Self::from_ast(basedir, markdowns, &meta, ast, style, template)?; trace!("Loaded document OK"); Ok(doc) @@ -195,14 +204,22 @@ impl Document { template: Option<&str>, ) -> Result<Document, SubplotError> { trace!("Parsing document with pullmark-cmark from {:?}", filename); - let filename = filename.to_path_buf(); - let markdown = std::fs::read_to_string(&filename) - .map_err(|err| SubplotError::ReadFile(filename.clone(), err))?; - let (meta, markdown) = ast::extract_metadata(&markdown)?; - let ast = ast::AbstractSyntaxTree::new(meta, markdown); + let meta = load_metadata_from_yaml_file(filename)?; + let mdfile = meta.markdown(); + let mdfile = basedir.join(mdfile); + let markdown = std::fs::read_to_string(&mdfile) + .map_err(|err| SubplotError::ReadFile(mdfile.clone(), err))?; + let ast = ast::AbstractSyntaxTree::new(meta.clone(), &markdown); trace!("Parsed document OK"); - Self::from_ast(basedir, vec![filename], ast.to_pandoc(), style, template) + Self::from_ast( + basedir, + vec![filename.into()], + &meta, + ast.to_pandoc(), + style, + template, + ) } /// Return the AST of a Document, serialized as JSON. @@ -481,6 +498,14 @@ impl Document { } } +fn load_metadata_from_yaml_file(filename: &Path) -> Result<YamlMetadata, SubplotError> { + let yaml = read(filename).map_err(|e| SubplotError::ReadFile(filename.into(), e))?; + trace!("Parsing YAML metadata from {}", filename.display()); + let meta: ast::YamlMetadata = serde_yaml::from_slice(&yaml) + .map_err(|e| SubplotError::MetadataFile(filename.into(), e))?; + Ok(meta) +} + /// Load a `Document` from a file. /// /// This version uses Pandoc to parse the Markdown. |