diff options
author | Daniel Silverstone <dsilvers+gitlab@digital-scurf.org> | 2023-11-11 10:46:41 +0000 |
---|---|---|
committer | Daniel Silverstone <dsilvers+gitlab@digital-scurf.org> | 2023-11-11 10:46:41 +0000 |
commit | dccf8d75321fca24caa8efd3a6eb41bc7af15f2f (patch) | |
tree | 41d50b6db9238b3ceb383b6032957e4c104ec9f2 | |
parent | 7252cf5c1e0288b1bbb54908999fc7524d12bf1e (diff) | |
parent | a53c5c551a513375bf66d551b9f72e02eb1003ff (diff) | |
download | subplot-dccf8d75321fca24caa8efd3a6eb41bc7af15f2f.tar.gz |
Merge branch 'liw/css' into 'main'
Add CSS support in HTML
Closes #36
See merge request subplot/subplot!361
-rw-r--r-- | src/doc.rs | 24 | ||||
-rw-r--r-- | src/metadata.rs | 33 | ||||
-rw-r--r-- | subplot.md | 79 |
3 files changed, 135 insertions, 1 deletions
@@ -155,11 +155,23 @@ impl Document { let mut css = Element::new(ElementTag::Style); css.push_child(Content::Text(CSS.into())); + for css_file in self.meta.css_embed() { + css.push_child(Content::Text(css_file.into())); + } head.push_child(Content::Elt(css)); + for css_url in self.meta.css_urls() { + let mut link = Element::new(ElementTag::Link); + link.push_attribute(Attribute::new("rel", "stylesheet")); + link.push_attribute(Attribute::new("type", "text/css")); + link.push_attribute(Attribute::new("href", css_url)); + head.push_child(Content::Elt(link)); + } + self.meta.set_date(date.into()); let mut body_content = Element::new(crate::html::ElementTag::Div); + body_content.push_attribute(Attribute::new("class", "content")); for md in self.markdowns.iter() { body_content.push_child(Content::Elt(md.root_element().clone())); } @@ -222,13 +234,19 @@ impl Document { assert!(level <= 6); let mut number = Element::new(ElementTag::Span); + number.push_attribute(Attribute::new("class", "heading-number")); number.push_child(Content::Text(numberer.number(level))); + let mut htext = Element::new(ElementTag::Span); + htext.push_attribute(Attribute::new("class", "heading-text")); + htext.push_child(Content::Text(text)); + let mut a = Element::new(ElementTag::A); a.push_attribute(crate::html::Attribute::new("href", &format!("#{}", id))); + a.push_attribute(Attribute::new("class", "toc-link")); a.push_child(Content::Elt(number)); a.push_child(Content::Text(" ".into())); - a.push_child(Content::Text(text)); + a.push_child(Content::Elt(htext)); let mut li = Element::new(ElementTag::Li); li.push_child(Content::Elt(a)); @@ -276,6 +294,7 @@ impl Document { fn typeset_meta(&self) -> Element { let mut div = Element::new(ElementTag::Div); + div.push_attribute(Attribute::new("class", "meta")); div.push_child(Content::Elt(Self::title(self.meta.title()))); @@ -292,12 +311,14 @@ impl Document { fn title(title: &str) -> Element { let mut e = Element::new(ElementTag::H1); + e.push_attribute(Attribute::new("class", "title")); e.push_child(Content::Text(title.into())); e } fn authors(authors: &[String]) -> Element { let mut list = Element::new(ElementTag::P); + list.push_attribute(Attribute::new("class", "authors")); list.push_child(Content::Text("By: ".into())); let mut first = true; for a in authors { @@ -312,6 +333,7 @@ impl Document { fn date(date: &str) -> Element { let mut e = Element::new(ElementTag::P); + e.push_attribute(Attribute::new("class", "date")); e.push_child(Content::Text(date.into())); e } diff --git a/src/metadata.rs b/src/metadata.rs index e3463b3..e382840 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -50,6 +50,8 @@ pub struct YamlMetadata { documentclass: Option<String>, #[serde(default)] impls: BTreeMap<String, Vec<PathBuf>>, + css_embed: Option<Vec<PathBuf>>, + css_urls: Option<Vec<String>>, } impl YamlMetadata { @@ -167,6 +169,8 @@ pub struct Metadata { impls: HashMap<String, DocumentImpl>, /// Extra class names which should be considered 'correct' for this document classes: Vec<String>, + css_embed: Vec<String>, + css_urls: Vec<String>, } #[derive(Debug)] @@ -208,6 +212,23 @@ impl Metadata { vec![] }; + let mut css_embed = vec![]; + if let Some(filenames) = &yaml.css_embed { + for filename in filenames.iter() { + let css = std::fs::read(filename) + .map_err(|e| SubplotError::ReadFile(filename.into(), e))?; + let css = String::from_utf8(css) + .map_err(|e| SubplotError::FileUtf8(filename.into(), e))?; + css_embed.push(css); + } + } + + let css_urls = if let Some(urls) = &yaml.css_urls { + urls.clone() + } else { + vec![] + }; + let meta = Self { basedir: basedir.as_ref().to_path_buf(), title: yaml.title().into(), @@ -218,6 +239,8 @@ impl Metadata { bindings, impls, classes, + css_embed, + css_urls, }; trace!("metadata: {:#?}", meta); @@ -278,6 +301,16 @@ impl Metadata { pub fn classes(&self) -> impl Iterator<Item = &str> { self.classes.iter().map(Deref::deref) } + + /// Contents of CSS files to embed into the HTML output. + pub fn css_embed(&self) -> impl Iterator<Item = &str> { + self.css_embed.iter().map(Deref::deref) + } + + /// List of CSS urls to add to the HTML output. + pub fn css_urls(&self) -> impl Iterator<Item = &str> { + self.css_urls.iter().map(Deref::deref) + } } impl DocumentImpl { @@ -3639,6 +3639,85 @@ markdowns: ~~~ ~~~~~~ +## HTML output + +### Embedded CSS + +_Requirement:_ The user can specify CSS files to embed in the HTML +output. + +Justification: We want to allow production of self-standing output +with user-defined styling. + +~~~scenario +given file embedded-css.subplot +given file embedded-css.md +given file embedded-css.css +given file b.yaml +given an installed subplot +when I run subplot docgen embedded-css.subplot -o foo.html +then file foo.html contains "silly: property;" +~~~ + +~~~{#embedded-css.subplot .file .yaml .numberLines} +title: Embedded CSS +markdowns: + - embedded-css.md +bindings: + - b.yaml +css_embed: + - embedded-css.css +~~~ + +~~~~~~{#embedded-css.md .file .markdown .numberLines} +# This is a title + +~~~scenario +given precondition +~~~ +~~~~~~ + +~~~{#embedded-css.css .file .css .numberLines} +html { + silly: property; +} +~~~ + +### CSS URLs + +_Requirement:_ The user can specify CSS URLs to add in the HTML +output. + +Justification: We want to allow users to specify non-embedded CSS. + +~~~scenario +given file css-urls.subplot +given file css-urls.md +given file b.yaml +given an installed subplot +when I run subplot docgen css-urls.subplot -o foo.html +then file foo.html contains "https://example.com/flushing.css" +~~~ + +~~~{#css-urls.subplot .file .yaml .numberLines} +title: Embedded CSS +markdowns: + - css-urls.md +bindings: + - b.yaml +css_urls: + - https://example.com/flushing.css +~~~ + +~~~~~~{#css-urls.md .file .markdown .numberLines} +# This is a title + +~~~scenario +given precondition +~~~ +~~~~~~ + + ## Running Subplot The scenarios in this section verify that the Subplot tool can be run |