summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2023-05-10 09:10:25 +0300
committerLars Wirzenius <liw@liw.fi>2023-05-10 09:14:34 +0300
commitace211d2c2e9c775872c4a23087763afff5a5bb2 (patch)
treef6884f4b6c3ee43c9c736f7f91e12d8a5ec98c49 /src
parent0a81c16df535853c68d5c833a213a81c2a1a9388 (diff)
downloadsubplot-ace211d2c2e9c775872c4a23087763afff5a5bb2.tar.gz
feat! allow multiple markdown files for a subplot
Sponsored-by: author
Diffstat (limited to 'src')
-rw-r--r--src/bin/subplot.rs14
-rw-r--r--src/doc.rs68
-rw-r--r--src/metadata.rs16
3 files changed, 71 insertions, 27 deletions
diff --git a/src/bin/subplot.rs b/src/bin/subplot.rs
index 41d8894..8da6c2b 100644
--- a/src/bin/subplot.rs
+++ b/src/bin/subplot.rs
@@ -264,8 +264,18 @@ impl Docgen {
} else if let Some(date) = doc.meta().date() {
date.to_string()
} else {
- let filename = doc.meta().basedir().join(doc.meta().markdown_filename());
- Self::mtime_formatted(Self::mtime(&filename)?)
+ let mut newest = None;
+ for filename in doc.meta().markdown_filenames() {
+ let mtime = Self::mtime(filename)?;
+ if let Some(so_far) = newest {
+ if mtime > so_far {
+ newest = Some(mtime);
+ }
+ } else {
+ newest = Some(mtime);
+ }
+ }
+ Self::mtime_formatted(newest.unwrap())
};
if Self::need_output(&mut doc, self.template.as_deref(), &self.output) {
diff --git a/src/doc.rs b/src/doc.rs
index 0b0b9e7..640968c 100644
--- a/src/doc.rs
+++ b/src/doc.rs
@@ -66,7 +66,7 @@ static KNOWN_BLOCK_CLASSES: &[&str] = &["numberLines", "noNumberLines"];
#[derive(Debug)]
pub struct Document {
subplot: PathBuf,
- md: Markdown,
+ markdowns: Vec<Markdown>,
meta: Metadata,
files: EmbeddedFiles,
style: Style,
@@ -75,14 +75,14 @@ pub struct Document {
impl Document {
fn new(
subplot: PathBuf,
- md: Markdown,
+ markdowns: Vec<Markdown>,
meta: Metadata,
files: EmbeddedFiles,
style: Style,
) -> Document {
let doc = Document {
subplot,
- md,
+ markdowns,
meta,
files,
style,
@@ -95,7 +95,7 @@ impl Document {
basedir: P,
subplot: PathBuf,
yamlmeta: &YamlMetadata,
- md: Markdown,
+ markdowns: Vec<Markdown>,
style: Style,
template: Option<&str>,
) -> Result<Document, SubplotError>
@@ -104,12 +104,22 @@ impl Document {
{
let meta = Metadata::from_yaml_metadata(basedir, yamlmeta, template)?;
trace!("metadata from YAML: {:#?}", meta);
- let files = md.embedded_files();
- let doc = Document::new(subplot, md, meta, files, style);
+ let files = Self::all_files(&markdowns);
+ let doc = Document::new(subplot, markdowns, meta, files, style);
trace!("Loaded from JSON OK");
Ok(doc)
}
+ fn all_files(markdowns: &[Markdown]) -> EmbeddedFiles {
+ let mut files = EmbeddedFiles::default();
+ for md in markdowns {
+ for file in md.embedded_files().files() {
+ files.push(file.clone());
+ }
+ }
+ files
+ }
+
/// Construct a Document from a named file.
pub fn from_file(
basedir: &Path,
@@ -126,11 +136,13 @@ impl Document {
let meta = load_metadata_from_yaml_file(filename)?;
trace!("metadata from YAML file: {:#?}", meta);
- let mdfile = meta.markdown();
- let mdfile = basedir.join(mdfile);
- let md = Markdown::load_file(mdfile.as_path())?;
+ let mut markdowns = vec![];
+ for filename in meta.markdowns() {
+ let filename = basedir.join(filename);
+ markdowns.push(Markdown::load_file(&filename)?);
+ }
- let doc = Self::from_ast(basedir, filename.into(), &meta, md, style, template)?;
+ let doc = Self::from_ast(basedir, filename.into(), &meta, markdowns, style, template)?;
trace!("Loaded document OK");
Ok(doc)
@@ -146,7 +158,9 @@ impl Document {
self.meta.set_date(date.into());
let mut body = self.typeset_meta();
- body.push_child(Content::Elt(self.md.root_element().clone()));
+ for md in self.markdowns.iter() {
+ body.push_child(Content::Elt(md.root_element().clone()));
+ }
let page = HtmlPage::new(head, body);
page.serialize().unwrap() // FIXME
}
@@ -230,10 +244,14 @@ impl Document {
names.push(PathBuf::from(x))
}
- names.push(self.meta().markdown_filename().to_path_buf());
+ for name in self.meta().markdown_filenames() {
+ names.push(name.into());
+ }
- let mut images = self.md.images();
- names.append(&mut images);
+ for md in self.markdowns.iter() {
+ let mut images = md.images();
+ names.append(&mut images);
+ }
names
}
@@ -276,7 +294,7 @@ impl Document {
/// Check that all the block classes in the document are known
fn check_block_classes(&self) -> Result<(), SubplotError> {
- let classes_in_doc = self.md.block_classes();
+ let classes_in_doc = self.all_block_classes();
// Build the set of known good classes
let mut known_classes: HashSet<String> = HashSet::new();
@@ -299,6 +317,16 @@ impl Document {
}
}
+ fn all_block_classes(&self) -> HashSet<String> {
+ let mut set = HashSet::new();
+ for md in self.markdowns.iter() {
+ for class in md.block_classes() {
+ set.insert(class);
+ }
+ }
+ set
+ }
+
/// Check that all named files (in matched steps) are actually present in the
/// document.
pub fn check_named_files_exist(
@@ -402,12 +430,18 @@ impl Document {
/// Typeset a Subplot document.
pub fn typeset(&mut self, warnings: &mut Warnings) {
- warnings.push_all(self.md.typeset(self.style.clone(), self.meta.bindings()));
+ for md in self.markdowns.iter_mut() {
+ warnings.push_all(md.typeset(self.style.clone(), self.meta.bindings()));
+ }
}
/// Return all scenarios in a document.
pub fn scenarios(&self) -> Result<Vec<Scenario>, SubplotError> {
- self.md.scenarios()
+ let mut scenarios = vec![];
+ for md in self.markdowns.iter() {
+ scenarios.append(&mut md.scenarios()?);
+ }
+ Ok(scenarios)
}
/// Return matched scenarios in a document.
diff --git a/src/metadata.rs b/src/metadata.rs
index d569b40..e4d3d53 100644
--- a/src/metadata.rs
+++ b/src/metadata.rs
@@ -63,9 +63,9 @@ impl YamlMetadata {
Ok(meta)
}
- /// Name of file with the Markdown for the subplot document.
- pub fn markdown(&self) -> &Path {
- &self.markdowns[0]
+ /// Names of files with the Markdown for the subplot document.
+ pub fn markdowns(&self) -> &[PathBuf] {
+ &self.markdowns
}
/// Title.
@@ -177,7 +177,7 @@ pub struct Metadata {
title: String,
date: Option<String>,
authors: Option<Vec<String>>,
- markdown_filename: PathBuf,
+ markdown_filenames: Vec<PathBuf>,
bindings_filenames: Vec<PathBuf>,
bindings: Bindings,
impls: HashMap<String, DocumentImpl>,
@@ -236,7 +236,7 @@ impl Metadata {
title: yaml.title().into(),
date: yaml.date().map(|s| s.into()),
authors: yaml.authors().map(|a| a.into()),
- markdown_filename: yaml.markdown().into(),
+ markdown_filenames: yaml.markdowns().into(),
bindings_filenames,
bindings,
impls,
@@ -273,9 +273,9 @@ impl Metadata {
&self.basedir
}
- /// Return filename of the markdown file.
- pub fn markdown_filename(&self) -> &Path {
- &self.markdown_filename
+ /// Return filenames of the markdown files.
+ pub fn markdown_filenames(&self) -> &[PathBuf] {
+ &self.markdown_filenames
}
/// Return filename where bindings are specified.