From b925f9601b30afd9b0c2a5e7354440a63aba8c60 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sat, 22 Oct 2022 08:37:30 +0300 Subject: feat: allow arbitrary Pandoc metadata in a .subplot The "pandoc" key gets added to the metadata given to Pandoc as-is. Sponsored-by: author --- src/ast.rs | 37 ++++++++++++++++++++++++++++++++++++- subplot.md | 26 ++++++++++++++++++++++++++ subplot.subplot | 3 +++ 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/ast.rs b/src/ast.rs index 7efe836..531208c 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -4,7 +4,8 @@ use pandoc_ast::{Attr, Block, Inline, Map, MetaValue, Pandoc}; use pulldown_cmark::{CodeBlockKind, Event, Options, Parser, Tag}; use regex::Regex; use serde::Deserialize; -use std::collections::BTreeMap; +use serde_yaml::{Mapping, Value}; +use std::collections::{BTreeMap, HashMap}; use std::path::{Path, PathBuf}; lazy_static! { @@ -293,6 +294,7 @@ pub struct YamlMetadata { documentclass: Option, #[serde(default)] impls: BTreeMap>, + pandoc: Option>, } impl YamlMetadata { @@ -351,11 +353,44 @@ impl YamlMetadata { map.insert("documentclass".into(), meta_string(v)); } + if let Some(pandoc) = &self.pandoc { + for (key, value) in pandoc.iter() { + map.insert(key.to_string(), value_to_pandoc(value)); + } + } + trace!("Created metadata map from parsed YAML"); map } } +fn mapping_to_pandoc(mapping: &Mapping) -> MetaValue { + let mut map = Map::new(); + for (key, value) in mapping.iter() { + assert!(matches!(key, Value::String(_))); + let key = if let MetaValue::MetaString(s) = value_to_pandoc(&key) { + s + } else { + panic!("key not a string: {:?}", key); + }; + map.insert(key, Box::new(value_to_pandoc(value))); + } + + MetaValue::MetaMap(map) +} + +fn value_to_pandoc(data: &Value) -> MetaValue { + match data { + Value::Null => unreachable!("null not OK"), + Value::Number(_) => unreachable!("number not OK"), + Value::Sequence(_) => unreachable!("sequence not OK"), + + Value::Bool(b) => MetaValue::MetaBool(*b), + Value::String(s) => MetaValue::MetaString(s.clone()), + Value::Mapping(mapping) => mapping_to_pandoc(mapping), + } +} + fn meta_string(s: &str) -> MetaValue { MetaValue::MetaString(s.to_string()) } diff --git a/subplot.md b/subplot.md index 8daf1dd..27da981 100644 --- a/subplot.md +++ b/subplot.md @@ -2474,6 +2474,32 @@ and file mtime.html contains "Geoffrey Butler" and file mtime.html contains "2020-02-26 07:53" ~~~ +### Pandoc metadata + +~~~scenario +given file pandoc.subplot +given file pandoc.md +and an installed subplot +when I run subplot docgen pandoc.subplot -o pandoc.html +when I run cat pandoc.html +then file pandoc.html exists +and file pandoc.html contains "The Fabulous Title" +and file pandoc.html contains "Superlative Subtitle" +~~~ + +~~~{#pandoc.subplot .file .yaml .numberLines} +title: The Fabulous Title +markdowns: +- pandoc.md +pandoc: + subtitle: Superlative Subtitle +~~~ + +~~~{#pandoc.md .file .markdown .numberLines} +# Introduction +This is a test document. That's all. +~~~ + ### Missing bindings file If a bindings file is missing, the error message should name the diff --git a/subplot.subplot b/subplot.subplot index 61ecd4f..d4a9353 100644 --- a/subplot.subplot +++ b/subplot.subplot @@ -16,3 +16,6 @@ impls: classes: - json - ignored +pandoc: + documentclass: report + subtitle: Yoyo -- cgit v1.2.1