summaryrefslogtreecommitdiff
path: root/src/doc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/doc.rs')
-rw-r--r--src/doc.rs93
1 files changed, 92 insertions, 1 deletions
diff --git a/src/doc.rs b/src/doc.rs
index c5bb2c7..ffdd4ac 100644
--- a/src/doc.rs
+++ b/src/doc.rs
@@ -1,4 +1,6 @@
use crate::ast;
+use crate::generate_test_program;
+use crate::get_basedir_from;
use crate::visitor;
use crate::DataFile;
use crate::DataFiles;
@@ -10,6 +12,7 @@ use crate::Scenario;
use crate::ScenarioStep;
use crate::Style;
use crate::{bindings::CaptureType, parser::parse_scenario_snippet};
+use crate::{template_spec, TemplateSpec};
use crate::{Result, SubplotError};
use std::collections::HashSet;
@@ -21,7 +24,7 @@ use std::str::FromStr;
use pandoc_ast::{MutVisitor, Pandoc};
-use tracing::{event, instrument, Level};
+use tracing::{event, instrument, span, Level};
/// The set of known (special) classes which subplot will always recognise
/// as being valid.
@@ -421,6 +424,94 @@ impl<'a> Document {
}
}
+/// Load a `Document` from a file.
+///
+/// This version uses Pandoc to parse the Markdown.
+#[instrument(level = "trace")]
+pub fn load_document<P>(filename: P, style: Style) -> Result<Document>
+where
+ P: AsRef<Path> + Debug,
+{
+ let filename = filename.as_ref();
+ let base_path = get_basedir_from(filename);
+ event!(
+ Level::TRACE,
+ ?filename,
+ ?base_path,
+ "Loading document based at `{}` called `{}` with {:?}",
+ base_path.display(),
+ filename.display(),
+ style
+ );
+ let doc = Document::from_file(&base_path, filename, style)?;
+ event!(Level::TRACE, "Loaded doc from file OK");
+
+ Ok(doc)
+}
+
+/// Load a `Document` from a file.
+///
+/// This version uses the `cmark-pullmark` crate to parse Markdown.
+#[instrument(level = "trace")]
+pub fn load_document_with_pullmark<P>(filename: P, style: Style) -> Result<Document>
+where
+ P: AsRef<Path> + Debug,
+{
+ let filename = filename.as_ref();
+ let base_path = get_basedir_from(filename);
+ event!(
+ Level::TRACE,
+ ?filename,
+ ?base_path,
+ "Loading document based at `{}` called `{}` with {:?} using pullmark-cmark",
+ base_path.display(),
+ filename.display(),
+ style
+ );
+ crate::resource::add_search_path(filename.parent().unwrap());
+ let doc = Document::from_file_with_pullmark(&base_path, filename, style)?;
+ event!(Level::TRACE, "Loaded doc from file OK");
+ Ok(doc)
+}
+
+/// Generate code for one document.
+pub fn codegen(filename: &Path, output: &Path) -> Result<CodegenOutput> {
+ let span = span!(Level::TRACE, "codegen");
+ let _enter = span.enter();
+
+ let mut doc = load_document_with_pullmark(filename, Style::default())?;
+ doc.lint()?;
+ let template = doc
+ .meta()
+ .template_name()
+ .ok_or(SubplotError::MissingTemplate)?
+ .to_string();
+ event!(Level::TRACE, ?template);
+ if !doc.check_named_files_exist(&template)? || !doc.check_matched_steps_have_impl(&template) {
+ event!(Level::ERROR, "Found problems in document, cannot continue");
+ eprintln!("Unable to continue");
+ std::process::exit(1);
+ }
+
+ event!(Level::TRACE, "Generating code");
+ let spec = template_spec(&doc)?;
+ generate_test_program(&mut doc, &spec, output, &template)?;
+ event!(Level::TRACE, "Finished generating code");
+
+ Ok(CodegenOutput::new(spec, doc))
+}
+
+pub struct CodegenOutput {
+ pub spec: TemplateSpec,
+ pub doc: Document,
+}
+
+impl CodegenOutput {
+ fn new(spec: TemplateSpec, doc: Document) -> Self {
+ Self { spec, doc }
+ }
+}
+
fn extract_scenario(e: &[visitor::Element]) -> Result<(Option<Scenario>, usize)> {
if e.is_empty() {
// If we get here, it's a programming error.