Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 100 additions & 15 deletions crates/wdl-doc/src/docs_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ use crate::r#struct::Struct;
use crate::task::Task;
use crate::workflow::Workflow;

/// Filename for the logo SVG expected to be in the "assets" directory.
/// Filename for the dark theme logo SVG expected to be in the "assets"
/// directory.
const LOGO_FILE_NAME: &str = "logo.svg";
/// Filename for the light theme logo SVG expected to be in the "assets"
/// directory.
const LIGHT_LOGO_FILE_NAME: &str = "logo.light.svg";

/// The type of a page.
#[derive(Debug)]
Expand Down Expand Up @@ -216,15 +220,24 @@ pub struct DocsTreeBuilder {
homepage: Option<PathBuf>,
/// An optional path to a custom theme to use for the docs.
custom_theme: Option<PathBuf>,
/// The path to a custom logo to embed at the top of the left sidebar.
/// The path to a custom dark theme logo to embed at the top of the left
/// sidebar.
///
/// If this is `Some(_)` and no `alt_logo` is supplied, this will be used
/// for both dark and light themes.
logo: Option<PathBuf>,
/// The path to an alternate light theme custom logo to embed at the top of
/// the left sidebar.
alt_logo: Option<PathBuf>,
/// Optional JavaScript to embed in each HTML page.
additional_javascript: AdditionalScript,
/// Start on the "Full Directory" left sidebar view instead of the
/// "Workflows" view.
///
/// Users can toggle the view. This only impacts the initialized value.
init_on_full_directory: bool,
/// Start in light mode instead of the default dark mode.
init_light_mode: bool,
}

impl DocsTreeBuilder {
Expand All @@ -238,8 +251,10 @@ impl DocsTreeBuilder {
homepage: None,
custom_theme: None,
logo: None,
alt_logo: None,
additional_javascript: AdditionalScript::None,
init_on_full_directory: crate::PREFER_FULL_DIRECTORY,
init_light_mode: false,
}
}

Expand Down Expand Up @@ -289,6 +304,18 @@ impl DocsTreeBuilder {
self.maybe_logo(Some(logo))
}

/// Set the alt (i.e. light mode) custom logo for the left sidebar with an
/// option.
pub fn maybe_alt_logo(mut self, logo: Option<impl Into<PathBuf>>) -> Self {
self.alt_logo = logo.map(|l| l.into());
self
}

/// Set the alt (i.e. light mode) custom logo for the left sidebar.
pub fn alt_logo(self, logo: impl Into<PathBuf>) -> Self {
self.maybe_alt_logo(Some(logo))
}

/// Set the additional javascript for each page.
pub fn additional_javascript(mut self, js: AdditionalScript) -> Self {
self.additional_javascript = js;
Expand All @@ -302,6 +329,12 @@ impl DocsTreeBuilder {
self
}

/// Set whether light mode should be the initial view instead of dark mode.
pub fn init_light_mode(mut self, init_light_mode: bool) -> Self {
self.init_light_mode = init_light_mode;
self
}

/// Build the docs tree.
pub fn build(self) -> Result<DocsTree> {
self.write_assets().with_context(|| {
Expand All @@ -324,6 +357,7 @@ impl DocsTreeBuilder {
homepage: self.homepage,
additional_javascript: self.additional_javascript,
init_on_full_directory: self.init_on_full_directory,
init_light_mode: self.init_light_mode,
})
}

Expand Down Expand Up @@ -399,15 +433,64 @@ impl DocsTreeBuilder {
std::fs::write(&path, bytes)
.with_context(|| format!("failed to write asset to `{}`", path.display()))?;
}
if let Some(supplied_logo) = &self.logo {
let logo_path = assets_dir.join(LOGO_FILE_NAME);
std::fs::copy(supplied_logo, &logo_path).with_context(|| {
format!(
"failed to copy custom logo from `{}` to `{}`",
supplied_logo.display(),
logo_path.display()
)
})?;
// The above `get_assets()` call will write the default logos; then the
// following logic may overwrite those files with user supplied logos.
match (&self.logo, &self.alt_logo) {
(Some(dark_logo), Some(light_logo)) => {
let logo_path = assets_dir.join(LOGO_FILE_NAME);
std::fs::copy(dark_logo, &logo_path).with_context(|| {
format!(
"failed to copy dark theme custom logo from `{}` to `{}`",
dark_logo.display(),
logo_path.display()
)
})?;
let logo_path = assets_dir.join(LIGHT_LOGO_FILE_NAME);
std::fs::copy(light_logo, &logo_path).with_context(|| {
format!(
"failed to copy light theme custom logo from `{}` to `{}`",
light_logo.display(),
logo_path.display()
)
})?;
}
(Some(logo), None) => {
let logo_path = assets_dir.join(LOGO_FILE_NAME);
std::fs::copy(logo, &logo_path).with_context(|| {
format!(
"failed to copy custom logo from `{}` to `{}`",
logo.display(),
logo_path.display()
)
})?;
let logo_path = assets_dir.join(LIGHT_LOGO_FILE_NAME);
std::fs::copy(logo, &logo_path).with_context(|| {
format!(
"failed to copy custom logo from `{}` to `{}`",
logo.display(),
logo_path.display()
)
})?;
}
(None, Some(logo)) => {
let logo_path = assets_dir.join(LOGO_FILE_NAME);
std::fs::copy(logo, &logo_path).with_context(|| {
format!(
"failed to copy custom logo from `{}` to `{}`",
logo.display(),
logo_path.display()
)
})?;
let logo_path = assets_dir.join(LIGHT_LOGO_FILE_NAME);
std::fs::copy(logo, &logo_path).with_context(|| {
format!(
"failed to copy custom logo from `{}` to `{}`",
logo.display(),
logo_path.display()
)
})?;
}
(None, None) => {}
}

Ok(())
Expand All @@ -431,6 +514,8 @@ pub struct DocsTree {
/// Initialize pages on the "Full Directory" view instead of the "Workflows"
/// view of the left sidebar.
init_on_full_directory: bool,
/// Initialize in light mode instead of the default dark mode.
init_light_mode: bool,
}

impl DocsTree {
Expand Down Expand Up @@ -919,10 +1004,8 @@ impl DocsTree {
// top navbar
div class="sticky px-4" {
a href=(self.root_index_relative_to(base).to_string_lossy()) {
// Dark mode logo
img src=(self.get_asset(base, LOGO_FILE_NAME)) class="w-[120px] flex-none mb-8 light:hidden" alt="Logo";
// Light logo (ensure we use logo with .light.svg suffix)
img src=(self.get_asset(base, LOGO_FILE_NAME)) class="w-[120px] flex-none mb-8 hidden light:block" alt="Logo";
img src=(self.get_asset(base, LOGO_FILE_NAME)) class="w-[120px] flex-none mb-8 block light:hidden" alt="Logo";
img src=(self.get_asset(base, LIGHT_LOGO_FILE_NAME)) class="w-[120px] flex-none mb-8 hidden light:block" alt="Logo";
}
div class="relative w-full h-10" {
input id="searchbox" "x-model.debounce"="search" type="text" placeholder="Search..." class="left-sidebar__searchbox";
Expand Down Expand Up @@ -1164,6 +1247,7 @@ impl DocsTree {
),
self.root().path(),
&self.additional_javascript,
self.init_light_mode,
);
std::fs::write(&index_path, html.into_string())
.with_context(|| format!("failed to write homepage to `{}`", index_path.display()))?;
Expand Down Expand Up @@ -1294,6 +1378,7 @@ impl DocsTree {
),
self.root_relative_to(base),
&self.additional_javascript,
self.init_light_mode,
);
std::fs::write(&path, html.into_string())
.with_context(|| format!("failed to write page at `{}`", path.display()))?;
Expand Down
24 changes: 23 additions & 1 deletion crates/wdl-doc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,11 @@ pub(crate) fn full_page<P: AsRef<Path>>(
body: Markup,
root: P,
script: &AdditionalScript,
init_light_mode: bool,
) -> Markup {
html! {
(DOCTYPE)
html x-data="{ DEFAULT_THEME: 'light' }" x-bind:class="(localStorage.getItem('theme') ?? DEFAULT_THEME) === 'light' ? 'light' : ''" x-cloak {
html x-data=(if init_light_mode { "{ DEFAULT_THEME: 'light' }" } else { "{ DEFAULT_THEME: '' }" }) x-bind:class="(localStorage.getItem('theme') ?? DEFAULT_THEME) === 'light' ? 'light' : ''" x-cloak {
(header(page_title, root, script))
body class="body--base" {
@match script {
Expand Down Expand Up @@ -377,10 +378,15 @@ pub struct Config {
output_dir: PathBuf,
/// An optional markdown file to embed in the homepage.
homepage: Option<PathBuf>,
/// Initialize pages in light mode instead of the default dark mode.
init_light_mode: bool,
/// An optional custom theme directory.
custom_theme: Option<PathBuf>,
/// An optional custom logo to embed in the left sidebar.
custom_logo: Option<PathBuf>,
/// An optional alternate (light mode) custom logo to embed in the left
/// sidebar.
alt_logo: Option<PathBuf>,
/// Optional JavaScript to embed in each HTML page.
additional_javascript: AdditionalScript,
/// Initialize pages on the "Full Directory" view instead of the "Workflows"
Expand All @@ -400,8 +406,10 @@ impl Config {
workspace: workspace.into(),
output_dir: output_dir.into(),
homepage: None,
init_light_mode: false,
custom_theme: None,
custom_logo: None,
alt_logo: None,
additional_javascript: AdditionalScript::None,
init_on_full_directory: PREFER_FULL_DIRECTORY,
}
Expand All @@ -413,6 +421,12 @@ impl Config {
self
}

/// Overwrite the config's light mode default with the new value.
pub fn init_light_mode(mut self, init_light_mode: bool) -> Self {
self.init_light_mode = init_light_mode;
self
}

/// Overwrite the config's custom theme with the new value.
pub fn custom_theme(mut self, custom_theme: Option<PathBuf>) -> Self {
self.custom_theme = custom_theme;
Expand All @@ -425,6 +439,12 @@ impl Config {
self
}

/// Overwrite the config's alternate logo with the new value.
pub fn alt_logo(mut self, alt_logo: Option<PathBuf>) -> Self {
self.alt_logo = alt_logo;
self
}

/// Overwrite the config's additional JS with the new value.
pub fn additional_javascript(mut self, additional_javascript: AdditionalScript) -> Self {
self.additional_javascript = additional_javascript;
Expand Down Expand Up @@ -490,8 +510,10 @@ pub async fn document_workspace(config: Config) -> Result<()> {

let mut docs_tree = DocsTreeBuilder::new(docs_dir.clone())
.maybe_homepage(homepage)
.init_light_mode(config.init_light_mode)
.maybe_custom_theme(config.custom_theme)?
.maybe_logo(config.custom_logo)
.maybe_alt_logo(config.alt_logo)
.additional_javascript(config.additional_javascript)
.prefer_full_directory(config.init_on_full_directory)
.build()
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions crates/wdl-doc/tests/output_docs/assets/chevron-up.light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions crates/wdl-doc/tests/output_docs/assets/dir-open.light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions crates/wdl-doc/tests/output_docs/assets/link.light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading