summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers+gitlab@digital-scurf.org>2023-11-11 10:46:41 +0000
committerDaniel Silverstone <dsilvers+gitlab@digital-scurf.org>2023-11-11 10:46:41 +0000
commitdccf8d75321fca24caa8efd3a6eb41bc7af15f2f (patch)
tree41d50b6db9238b3ceb383b6032957e4c104ec9f2
parent7252cf5c1e0288b1bbb54908999fc7524d12bf1e (diff)
parenta53c5c551a513375bf66d551b9f72e02eb1003ff (diff)
downloadsubplot-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.rs24
-rw-r--r--src/metadata.rs33
-rw-r--r--subplot.md79
3 files changed, 135 insertions, 1 deletions
diff --git a/src/doc.rs b/src/doc.rs
index f3f9641..07831c2 100644
--- a/src/doc.rs
+++ b/src/doc.rs
@@ -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 {
diff --git a/subplot.md b/subplot.md
index 06e9e38..432b571 100644
--- a/subplot.md
+++ b/subplot.md
@@ -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