diff options
Diffstat (limited to 'src/ast.rs')
-rw-r--r-- | src/ast.rs | 172 |
1 files changed, 0 insertions, 172 deletions
diff --git a/src/ast.rs b/src/ast.rs deleted file mode 100644 index ed163f0..0000000 --- a/src/ast.rs +++ /dev/null @@ -1,172 +0,0 @@ -use lazy_static::lazy_static; -use regex::Regex; -use serde::Deserialize; -use serde_yaml::Value; -use std::collections::{BTreeMap, HashMap}; -use std::path::{Path, PathBuf}; - -lazy_static! { - // Pattern that recognises a YAML block at the beginning of a file. - static ref LEADING_YAML_PATTERN: Regex = Regex::new(r"^(?:\S*\n)*(?P<yaml>-{3,}\n([^.].*\n)*\.{3,}\n)(?P<text>(.*\n)*)$").unwrap(); - - - // Pattern that recognises a YAML block at the end of a file. - static ref TRAILING_YAML_PATTERN: Regex = Regex::new(r"(?P<text>(.*\n)*)\n*(?P<yaml>-{3,}\n([^.].*\n)*\.{3,}\n)(?:\S*\n)*$").unwrap(); -} - -/// Errors from Markdown parsing. -#[derive(Debug, thiserror::Error)] -pub enum Error { - #[error(transparent)] - Regex(#[from] regex::Error), - - #[error("Markdown doesn't contain a YAML block for document metadata")] - NoMetadata, - - #[error(transparent)] - Yaml(#[from] serde_yaml::Error), -} - -/// Document metadata. -/// -/// This is expressed in the Markdown input file as an embedded YAML -/// block. -/// -/// Note that this structure needs to be able to capture any metadata -/// block we can work with, in any input file. By being strict here we -/// make it easier to tell the user when a metadata block has, say, a -/// misspelled field. -#[derive(Debug, Default, Clone, Deserialize)] -#[serde(deny_unknown_fields)] -pub struct YamlMetadata { - title: String, - subtitle: Option<String>, - authors: Option<Vec<String>>, - date: Option<String>, - classes: Option<Vec<String>>, - bibliography: Option<Vec<PathBuf>>, - markdowns: Vec<PathBuf>, - bindings: Option<Vec<PathBuf>>, - documentclass: Option<String>, - #[serde(default)] - impls: BTreeMap<String, Vec<PathBuf>>, - pandoc: Option<HashMap<String, Value>>, -} - -impl YamlMetadata { - #[cfg(test)] - fn new(yaml_text: &str) -> Result<Self, Error> { - let meta: Self = serde_yaml::from_str(yaml_text)?; - Ok(meta) - } - - /// Name of file with the Markdown for the subplot document. - pub fn markdown(&self) -> &Path { - &self.markdowns[0] - } - - /// Title. - pub fn title(&self) -> &str { - &self.title - } - - /// Subtitle. - pub fn subtitle(&self) -> Option<&str> { - self.subtitle.as_deref() - } - - /// Date. - pub fn date(&self) -> Option<&str> { - self.date.as_deref() - } - - /// Authors. - pub fn authors(&self) -> Option<&[String]> { - self.authors.as_deref() - } - - /// Names of bindings files. - pub fn bindings_filenames(&self) -> Option<&[PathBuf]> { - self.bindings.as_deref() - } - - /// Impls section. - pub fn impls(&self) -> &BTreeMap<String, Vec<PathBuf>> { - &self.impls - } - - /// Bibliographies. - pub fn bibliographies(&self) -> Option<&[PathBuf]> { - self.bibliography.as_deref() - } - - /// Classes.. - pub fn classes(&self) -> Option<&[String]> { - self.classes.as_deref() - } - - /// Documentclass. - pub fn documentclass(&self) -> Option<&str> { - self.documentclass.as_deref() - } - - /// Pandoc metadata. - pub fn pandoc(&self) -> Option<&HashMap<String, Value>> { - if let Some(x) = &self.pandoc { - Some(x) - } else { - None - } - } -} - -#[cfg(test)] -mod test { - use super::YamlMetadata; - use std::path::{Path, PathBuf}; - - #[test] - fn full_meta() { - let meta = YamlMetadata::new( - "\ -title: Foo Bar -date: today -classes: [json, text] -impls: - python: - - foo.py - - bar.py -bibliography: -- foo.bib -- bar.bib -markdowns: -- test.md -bindings: -- foo.yaml -- bar.yaml -", - ) - .unwrap(); - assert_eq!(meta.title, "Foo Bar"); - assert_eq!(meta.date.unwrap(), "today"); - assert_eq!(meta.classes.unwrap(), &["json", "text"]); - assert_eq!( - meta.bibliography.unwrap(), - &[path("foo.bib"), path("bar.bib")] - ); - assert_eq!(meta.markdowns, vec![Path::new("test.md")]); - assert_eq!( - meta.bindings.unwrap(), - &[path("foo.yaml"), path("bar.yaml")] - ); - assert!(!meta.impls.is_empty()); - for (k, v) in meta.impls.iter() { - assert_eq!(k, "python"); - assert_eq!(v, &[path("foo.py"), path("bar.py")]); - } - } - - fn path(s: &str) -> PathBuf { - PathBuf::from(s) - } -} |