diff --git a/crates/mdbook-core/src/config.rs b/crates/mdbook-core/src/config.rs index d7aa13bb89..977d2cba4d 100644 --- a/crates/mdbook-core/src/config.rs +++ b/crates/mdbook-core/src/config.rs @@ -45,11 +45,11 @@ use crate::static_regex; use crate::utils::{TomlExt, fs, log_backtrace}; -use anyhow::{Context, Error, Result, bail}; +use anyhow::{Context, Error, Result, anyhow, bail}; use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, HashMap}; use std::env; -use std::path::{Path, PathBuf}; +use std::path::{Component, Path, PathBuf}; use std::str::FromStr; use toml::Value; use toml::value::Table; @@ -303,6 +303,31 @@ impl Config { Ok(()) } + + /// The config can load properly with valid, but wrong values, for instance wrong paths. + /// This is the place to check for such config variables. + pub fn check>(&self, book_root: P) -> Result<()> { + if let Some(logo_path) = self.book.get_logo_absolute_path(book_root) { + // Forbid absolute paths and parent directory references in the config file + if let Some(logo_path) = &self.book.logo { + if logo_path.is_absolute() + || logo_path.components().any(|c| c == Component::ParentDir) + { + return Result::Err(anyhow!( + "invalid value for `logo`: should live under `{}/`", + self.book.src.to_string_lossy() + )); + } + } + if !logo_path.exists() { + return Result::Err(anyhow!( + "invalid value for `logo`: {} does not exist", + logo_path.to_str().unwrap_or(&logo_path.to_string_lossy()), + )); + } + } + Result::Ok(()) + } } fn parse_env(key: &str) -> Option { @@ -330,6 +355,9 @@ pub struct BookConfig { /// The direction of text in the book: Left-to-right (LTR) or Right-to-left (RTL). /// When not specified, the text direction is derived from [`BookConfig::language`]. pub text_direction: Option, + /// A logo to be displayed on top of the navigation bar. The path is relative to the source + /// path + pub logo: Option, } /// Helper for serde serialization. @@ -346,6 +374,7 @@ impl Default for BookConfig { src: PathBuf::from("src"), language: Some(String::from("en")), text_direction: None, + logo: None, } } } @@ -360,6 +389,19 @@ impl BookConfig { TextDirection::from_lang_code(self.language.as_deref().unwrap_or_default()) } } + + /// Compute the absolute path of the book's logo, if provided, and canonicalize it + pub fn get_logo_absolute_path>(&self, book_root: P) -> Option { + if let Some(logo_cfg) = self.logo.clone() { + Some(if logo_cfg.is_absolute() { + logo_cfg + } else { + book_root.into().join(&self.src).join(logo_cfg) + }) + } else { + None + } + } } /// Text direction to use for HTML output @@ -742,6 +784,7 @@ mod tests { description = "A completely useless book" src = "source" language = "ja" + logo = "images/logo.svg" [build] build-dir = "outputs" @@ -779,6 +822,7 @@ mod tests { src: PathBuf::from("source"), language: Some(String::from("ja")), text_direction: None, + logo: Some(PathBuf::from("images/logo.svg")), }; let build_should_be = BuildConfig { build_dir: PathBuf::from("outputs"), diff --git a/crates/mdbook-driver/src/mdbook.rs b/crates/mdbook-driver/src/mdbook.rs index 3e617de04b..92999aee6b 100644 --- a/crates/mdbook-driver/src/mdbook.rs +++ b/crates/mdbook-driver/src/mdbook.rs @@ -57,6 +57,7 @@ impl MDBook { }; config.update_from_env()?; + config.check(book_root.clone())?; if tracing::enabled!(tracing::Level::TRACE) { for line in format!("Config: {config:#?}").lines() { diff --git a/crates/mdbook-html/front-end/css/chrome.css b/crates/mdbook-html/front-end/css/chrome.css index 19b8e90f9d..dcdde8dbd6 100644 --- a/crates/mdbook-html/front-end/css/chrome.css +++ b/crates/mdbook-html/front-end/css/chrome.css @@ -498,6 +498,25 @@ html:not(.sidebar-resizing) .sidebar { right: 0; padding: 10px 10px; } +.sidebar .sidebar-scrollbox .sidebar-book-logo { + align-items: center; + column-gap: 20px; + display: flex; + justify-content: center; + margin: 20px 0; +} +.sidebar .sidebar-scrollbox .sidebar-book-logo img { + display: block; + max-height: 8rem; + width: 20%; +} +.sidebar .sidebar-scrollbox .sidebar-book-logo h2 { + margin: 0; + width: 70%; + overflow-wrap: anywhere; + text-wrap: balance; +} + .sidebar .sidebar-resize-handle { position: absolute; cursor: col-resize; diff --git a/crates/mdbook-html/front-end/templates/toc.js.hbs b/crates/mdbook-html/front-end/templates/toc.js.hbs index 3b0b70c365..09053047c3 100644 --- a/crates/mdbook-html/front-end/templates/toc.js.hbs +++ b/crates/mdbook-html/front-end/templates/toc.js.hbs @@ -8,7 +8,14 @@ class MDBookSidebarScrollbox extends HTMLElement { super(); } connectedCallback() { +{{#if book_logo }} + this.innerHTML = + '{{#toc}}{{/toc}}'; +{{else}} this.innerHTML = '{{#toc}}{{/toc}}'; +{{/if}} // Set the current, active page, and reveal it if it's hidden let current_page = document.location.href.toString().split('#')[0].split('?')[0]; if (current_page.endsWith('/')) { diff --git a/crates/mdbook-html/src/html_handlebars/hbs_renderer.rs b/crates/mdbook-html/src/html_handlebars/hbs_renderer.rs index 8edac3cace..850dd811f8 100644 --- a/crates/mdbook-html/src/html_handlebars/hbs_renderer.rs +++ b/crates/mdbook-html/src/html_handlebars/hbs_renderer.rs @@ -478,6 +478,10 @@ fn make_data( "description".to_owned(), json!(config.book.description.clone().unwrap_or_default()), ); + data.insert( + "book_logo".to_owned(), + json!(config.book.logo.clone().unwrap_or_default()), + ); if theme.favicon_png.is_some() { data.insert("favicon_png".to_owned(), json!("favicon.png")); } diff --git a/guide/book.toml b/guide/book.toml index 2e6ae364c6..14fb8bd21f 100644 --- a/guide/book.toml +++ b/guide/book.toml @@ -3,6 +3,7 @@ title = "mdBook Documentation" description = "Create book from markdown files. Like Gitbook but implemented in Rust" authors = ["Mathieu David", "Michael-F-Bryan"] language = "en" +logo = "images/logo.svg" [rust] edition = "2018" diff --git a/guide/src/format/configuration/general.md b/guide/src/format/configuration/general.md index a01b0b1008..89aff071e6 100644 --- a/guide/src/format/configuration/general.md +++ b/guide/src/format/configuration/general.md @@ -49,8 +49,10 @@ This is general information about your book. This is also used to derive the direction of text (RTL, LTR) within the book. - **text-direction**: The direction of text in the book: Left-to-right (LTR) or Right-to-left (RTL). Possible values: `ltr`, `rtl`. When not specified, the text direction is derived from the book's `language` attribute. +- **logo:** Path to a logo to displayed at the top of the navigation bar, relative to `//`. **book.toml** + ```toml [book] title = "Example book" @@ -59,6 +61,7 @@ description = "The example book covers examples." src = "my-src" # the source files will be found in `root/my-src` instead of `root/src` language = "en" text-direction = "ltr" +logo = "static/logo.svg" # logo lives at `root/my-src/static/logo.svg` ``` ### Rust options diff --git a/guide/src/images/logo.svg b/guide/src/images/logo.svg new file mode 120000 index 0000000000..d26ee9efe5 --- /dev/null +++ b/guide/src/images/logo.svg @@ -0,0 +1 @@ +../../../crates/mdbook-html/front-end/images/favicon.svg \ No newline at end of file diff --git a/tests/gui/books/sidebar-logo-large/book.toml b/tests/gui/books/sidebar-logo-large/book.toml new file mode 100644 index 0000000000..032ad94766 --- /dev/null +++ b/tests/gui/books/sidebar-logo-large/book.toml @@ -0,0 +1,3 @@ +[book] +title = "Large logo" +logo = "logo.svg" diff --git a/tests/gui/books/sidebar-logo-large/src/SUMMARY.md b/tests/gui/books/sidebar-logo-large/src/SUMMARY.md new file mode 100644 index 0000000000..22fc8fc79e --- /dev/null +++ b/tests/gui/books/sidebar-logo-large/src/SUMMARY.md @@ -0,0 +1 @@ +- [c1](c1.md) diff --git a/tests/gui/books/sidebar-logo-large/src/c1.md b/tests/gui/books/sidebar-logo-large/src/c1.md new file mode 100644 index 0000000000..3c62125d67 --- /dev/null +++ b/tests/gui/books/sidebar-logo-large/src/c1.md @@ -0,0 +1 @@ +# c1 diff --git a/tests/gui/books/sidebar-logo-large/src/logo.svg b/tests/gui/books/sidebar-logo-large/src/logo.svg new file mode 100644 index 0000000000..7d4745ee7e --- /dev/null +++ b/tests/gui/books/sidebar-logo-large/src/logo.svg @@ -0,0 +1,4 @@ + + + + diff --git a/tests/gui/books/sidebar-logo-tall/book.toml b/tests/gui/books/sidebar-logo-tall/book.toml new file mode 100644 index 0000000000..cc0e5b4844 --- /dev/null +++ b/tests/gui/books/sidebar-logo-tall/book.toml @@ -0,0 +1,3 @@ +[book] +title = "Tall logo" +logo = "logo.svg" diff --git a/tests/gui/books/sidebar-logo-tall/src/SUMMARY.md b/tests/gui/books/sidebar-logo-tall/src/SUMMARY.md new file mode 100644 index 0000000000..22fc8fc79e --- /dev/null +++ b/tests/gui/books/sidebar-logo-tall/src/SUMMARY.md @@ -0,0 +1 @@ +- [c1](c1.md) diff --git a/tests/gui/books/sidebar-logo-tall/src/c1.md b/tests/gui/books/sidebar-logo-tall/src/c1.md new file mode 100644 index 0000000000..3c62125d67 --- /dev/null +++ b/tests/gui/books/sidebar-logo-tall/src/c1.md @@ -0,0 +1 @@ +# c1 diff --git a/tests/gui/books/sidebar-logo-tall/src/logo.svg b/tests/gui/books/sidebar-logo-tall/src/logo.svg new file mode 100644 index 0000000000..b750ef0896 --- /dev/null +++ b/tests/gui/books/sidebar-logo-tall/src/logo.svg @@ -0,0 +1,4 @@ + + + + diff --git a/tests/gui/books/sidebar-logo/book.toml b/tests/gui/books/sidebar-logo/book.toml new file mode 100644 index 0000000000..d828346eec --- /dev/null +++ b/tests/gui/books/sidebar-logo/book.toml @@ -0,0 +1,4 @@ +[book] +title = "sidebar-logo test" +language = "en" +logo = "logo.svg" diff --git a/tests/gui/books/sidebar-logo/src/SUMMARY.md b/tests/gui/books/sidebar-logo/src/SUMMARY.md new file mode 100644 index 0000000000..d6aa0b7c79 --- /dev/null +++ b/tests/gui/books/sidebar-logo/src/SUMMARY.md @@ -0,0 +1,6 @@ +# Summary + +- [Chapter 1](./chapter_1.md) +- [Chapter 2](./chapter_2.md) +- [Nested](./nested/chapter_nested.md) +- [Deeper](./nested/again/chapter_nested.md) diff --git a/tests/gui/books/sidebar-logo/src/chapter_1.md b/tests/gui/books/sidebar-logo/src/chapter_1.md new file mode 100644 index 0000000000..9cfa366566 --- /dev/null +++ b/tests/gui/books/sidebar-logo/src/chapter_1.md @@ -0,0 +1,3 @@ +# Chapter 1 + +This is the first chapter to test logo display at root level. diff --git a/tests/gui/books/sidebar-logo/src/chapter_2.md b/tests/gui/books/sidebar-logo/src/chapter_2.md new file mode 100644 index 0000000000..620fffa1ea --- /dev/null +++ b/tests/gui/books/sidebar-logo/src/chapter_2.md @@ -0,0 +1,3 @@ +# Chapter 2 + +This is the second chapter. diff --git a/tests/gui/books/sidebar-logo/src/logo.svg b/tests/gui/books/sidebar-logo/src/logo.svg new file mode 100644 index 0000000000..1a6c762d4e --- /dev/null +++ b/tests/gui/books/sidebar-logo/src/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/gui/books/sidebar-logo/src/nested/again/chapter_nested.md b/tests/gui/books/sidebar-logo/src/nested/again/chapter_nested.md new file mode 100644 index 0000000000..9504f99f8e --- /dev/null +++ b/tests/gui/books/sidebar-logo/src/nested/again/chapter_nested.md @@ -0,0 +1,3 @@ +# Deeper Chapter + +This is a nested chapter to test logo display at different nesting levels. diff --git a/tests/gui/books/sidebar-logo/src/nested/chapter_nested.md b/tests/gui/books/sidebar-logo/src/nested/chapter_nested.md new file mode 100644 index 0000000000..8d4948d7eb --- /dev/null +++ b/tests/gui/books/sidebar-logo/src/nested/chapter_nested.md @@ -0,0 +1,3 @@ +# Nested Chapter + +This is a nested chapter to test logo display at different nesting levels. diff --git a/tests/gui/sidebar-logo.goml b/tests/gui/sidebar-logo.goml new file mode 100644 index 0000000000..001051d943 --- /dev/null +++ b/tests/gui/sidebar-logo.goml @@ -0,0 +1,87 @@ +// This GUI test checks that the logo is displayed when configured +// Test cases: +// - test if the logo is displayed when provided +// - test it is displayed above the toc +// - test if works in nested files (level 0, 1 and n > 1) +// - large pictures are properly displayed + +define-function: ( + "load", + [path], + block { + go-to: |DOC_PATH| + |path| + set-window-size: (1100, 600) + reload: + // Wait for the TOC to be populated by JavaScript + wait-for: "mdbook-sidebar-scrollbox" + wait-for: "ol.chapter" + wait-for: "#sidebar-book-logo" + }, +) + +define-function: ( + "assert-logo", + [], + block { + assert-css: ("#sidebar-book-logo", {"display": "flex"}) + assert-css: ("#sidebar-book-logo img", {"display": "block"}) + }, +) + +define-function: ( + "assert-logo-src", + [prefix], + block { + assert-attribute: (".sidebar-book-logo img", {"src": |prefix| + "logo.svg"}) + assert-find-text-false: "sidebar-logo test logo" + }, +) + +define-function: ( + "assert-logo-position", + [], + block { + store-position: ("#sidebar-book-logo img", {"y": logo_y}) + store-position: ("ol.chapter", {"y": chapter_y}) + assert: |logo_y| < |chapter_y| + }, +) + +call-function: ("load", {"path": "sidebar-logo/index.html"}) + +// The sidebar-book-logo should exist when logo is provided +call-function: ("assert-logo", {}) + +// Logo image should have the correct src path and loaded +call-function: ("assert-logo-src", {"prefix": ""}) + +// Logo should be above the TOC +call-function: ("assert-logo-position", {}) + +// Test on chapter_2, nested, and deeper +click: ".chapter a[href='chapter_2.html']" +wait-for-text: (".header", "Chapter 2") +call-function: ("assert-logo", {}) +call-function: ("assert-logo-src", {"prefix": ""}) +call-function: ("assert-logo-position", {}) + +click: ".chapter a[href='nested/chapter_nested.html']" +wait-for-text: (".header", "Nested Chapter") +call-function: ("assert-logo", {}) +call-function: ("assert-logo-src", {"prefix": "../"}) +call-function: ("assert-logo-position", {}) + +click: ".chapter a[href='../nested/again/chapter_nested.html']" +wait-for-text: (".header", "Deeper Chapter") +call-function: ("assert-logo", {}) +call-function: ("assert-logo-src", {"prefix": "../../"}) +call-function: ("assert-logo-position", {}) + +// Large images checks +call-function: ("load", {"path": "sidebar-logo-large/index.html"}) +store-property : (".sidebar-book-logo img", {"width": logo_width}) +assert: |logo_width| <= 200 + +call-function: ("load", {"path": "sidebar-logo-tall/index.html"}) +store-property : (".sidebar-book-logo img", {"height": logo_height}) +assert: |logo_height| <= 200 diff --git a/tests/gui/sidebar.goml b/tests/gui/sidebar.goml index 50dc71a940..bac0c98345 100644 --- a/tests/gui/sidebar.goml +++ b/tests/gui/sidebar.goml @@ -67,3 +67,6 @@ assert-local-storage: {|sidebar_storage_value|: |sidebar_storage_displayed_value // But the sidebar should be hidden anyway. assert-css: ("#mdbook-sidebar", {"display": "none"}) assert-position: ("#mdbook-page-wrapper", {"x": 0}) + +// The logo should not be displayed in the sidebar. +assert-false: "#sidebar-book-logo" diff --git a/tests/testsuite/config.rs b/tests/testsuite/config.rs index f3284c0426..017b52ecac 100644 --- a/tests/testsuite/config.rs +++ b/tests/testsuite/config.rs @@ -176,7 +176,7 @@ ERROR Invalid configuration file | 3 | foo = 123 | ^^^ -unknown field `foo`, expected one of `title`, `authors`, `description`, `src`, `language`, `text-direction` +unknown field `foo`, expected one of `title`, `authors`, `description`, `src`, `language`, `text-direction`, `logo` "#]]); @@ -232,7 +232,7 @@ fn env_invalid_value() { .expect_failure() .expect_stdout(str![[""]]) .expect_stderr(str![[r#" -ERROR unknown field `titlez`, expected one of `title`, `authors`, `description`, `src`, `language`, `text-direction` +ERROR unknown field `titlez`, expected one of `title`, `authors`, `description`, `src`, `language`, `text-direction`, `logo` "#]]); diff --git a/tests/testsuite/main.rs b/tests/testsuite/main.rs index 9ef11dd76e..18d0d69a78 100644 --- a/tests/testsuite/main.rs +++ b/tests/testsuite/main.rs @@ -20,6 +20,7 @@ mod renderer; mod rendering; #[cfg(feature = "search")] mod search; +mod sidebar_logo; mod test; mod theme; mod toc; diff --git a/tests/testsuite/preprocessor.rs b/tests/testsuite/preprocessor.rs index 33c320785e..b8c0a5c78b 100644 --- a/tests/testsuite/preprocessor.rs +++ b/tests/testsuite/preprocessor.rs @@ -362,6 +362,7 @@ fn extension_compatibility() { "authors": [], "description": null, "language": "en", + "logo": null, "text-direction": null, "title": "extension_compatibility" }, diff --git a/tests/testsuite/renderer.rs b/tests/testsuite/renderer.rs index 2dbe272735..27eb00bc3e 100644 --- a/tests/testsuite/renderer.rs +++ b/tests/testsuite/renderer.rs @@ -188,6 +188,7 @@ fn backends_receive_render_context_via_stdin() { "authors": [], "description": null, "language": "en", + "logo": null, "text-direction": null, "title": null }, diff --git a/tests/testsuite/sidebar/logo/absolute_unix/book.toml b/tests/testsuite/sidebar/logo/absolute_unix/book.toml new file mode 100644 index 0000000000..ffee968e8f --- /dev/null +++ b/tests/testsuite/sidebar/logo/absolute_unix/book.toml @@ -0,0 +1,5 @@ +[book] +title = "outside" +authors = ["Chocorean"] +language = "en" +logo = "/absolute/path/logo.svg" diff --git a/tests/testsuite/sidebar/logo/absolute_unix/src/SUMMARY.md b/tests/testsuite/sidebar/logo/absolute_unix/src/SUMMARY.md new file mode 100644 index 0000000000..7390c82896 --- /dev/null +++ b/tests/testsuite/sidebar/logo/absolute_unix/src/SUMMARY.md @@ -0,0 +1,3 @@ +# Summary + +- [Chapter 1](./chapter_1.md) diff --git a/tests/testsuite/sidebar/logo/absolute_unix/src/chapter_1.md b/tests/testsuite/sidebar/logo/absolute_unix/src/chapter_1.md new file mode 100644 index 0000000000..b743fda354 --- /dev/null +++ b/tests/testsuite/sidebar/logo/absolute_unix/src/chapter_1.md @@ -0,0 +1 @@ +# Chapter 1 diff --git a/tests/testsuite/sidebar/logo/absolute_windows/book.toml b/tests/testsuite/sidebar/logo/absolute_windows/book.toml new file mode 100644 index 0000000000..b71ee32822 --- /dev/null +++ b/tests/testsuite/sidebar/logo/absolute_windows/book.toml @@ -0,0 +1,5 @@ +[book] +title = "outside" +authors = ["Chocorean"] +language = "en" +logo = "C:/absolute/path/logo.svg" diff --git a/tests/testsuite/sidebar/logo/absolute_windows/logo.svg b/tests/testsuite/sidebar/logo/absolute_windows/logo.svg new file mode 120000 index 0000000000..718fa53dd7 --- /dev/null +++ b/tests/testsuite/sidebar/logo/absolute_windows/logo.svg @@ -0,0 +1 @@ +../../../../../crates/mdbook-html/front-end/images/favicon.svg \ No newline at end of file diff --git a/tests/testsuite/sidebar/logo/absolute_windows/src/SUMMARY.md b/tests/testsuite/sidebar/logo/absolute_windows/src/SUMMARY.md new file mode 100644 index 0000000000..7390c82896 --- /dev/null +++ b/tests/testsuite/sidebar/logo/absolute_windows/src/SUMMARY.md @@ -0,0 +1,3 @@ +# Summary + +- [Chapter 1](./chapter_1.md) diff --git a/tests/testsuite/sidebar/logo/absolute_windows/src/chapter_1.md b/tests/testsuite/sidebar/logo/absolute_windows/src/chapter_1.md new file mode 100644 index 0000000000..b743fda354 --- /dev/null +++ b/tests/testsuite/sidebar/logo/absolute_windows/src/chapter_1.md @@ -0,0 +1 @@ +# Chapter 1 diff --git a/tests/testsuite/sidebar/logo/good/book.toml b/tests/testsuite/sidebar/logo/good/book.toml new file mode 100644 index 0000000000..0f4da87e18 --- /dev/null +++ b/tests/testsuite/sidebar/logo/good/book.toml @@ -0,0 +1,4 @@ +[book] +title = "Passing test" +authors = ["Chocorean"] +language = "en" diff --git a/tests/testsuite/sidebar/logo/good/src/SUMMARY.md b/tests/testsuite/sidebar/logo/good/src/SUMMARY.md new file mode 100644 index 0000000000..7390c82896 --- /dev/null +++ b/tests/testsuite/sidebar/logo/good/src/SUMMARY.md @@ -0,0 +1,3 @@ +# Summary + +- [Chapter 1](./chapter_1.md) diff --git a/tests/testsuite/sidebar/logo/good/src/chapter_1.md b/tests/testsuite/sidebar/logo/good/src/chapter_1.md new file mode 100644 index 0000000000..b743fda354 --- /dev/null +++ b/tests/testsuite/sidebar/logo/good/src/chapter_1.md @@ -0,0 +1 @@ +# Chapter 1 diff --git a/tests/testsuite/sidebar/logo/good/src/logo.svg b/tests/testsuite/sidebar/logo/good/src/logo.svg new file mode 120000 index 0000000000..4a9621e800 --- /dev/null +++ b/tests/testsuite/sidebar/logo/good/src/logo.svg @@ -0,0 +1 @@ +../../../../../../crates/mdbook-html/front-end/images/favicon.svg \ No newline at end of file diff --git a/tests/testsuite/sidebar/logo/not_found/book.toml b/tests/testsuite/sidebar/logo/not_found/book.toml new file mode 100644 index 0000000000..30ec31e982 --- /dev/null +++ b/tests/testsuite/sidebar/logo/not_found/book.toml @@ -0,0 +1,2 @@ +[book] +logo = "does/not/exist" diff --git a/tests/testsuite/sidebar/logo/not_found/src/SUMMARY.md b/tests/testsuite/sidebar/logo/not_found/src/SUMMARY.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/testsuite/sidebar/logo/other_src/book.toml b/tests/testsuite/sidebar/logo/other_src/book.toml new file mode 100644 index 0000000000..b88292b563 --- /dev/null +++ b/tests/testsuite/sidebar/logo/other_src/book.toml @@ -0,0 +1,6 @@ +[book] +title = "Other src" +authors = ["Chocorean"] +language = "en" +src = "my-src" +logo = "logo.svg" diff --git a/tests/testsuite/sidebar/logo/other_src/my-src/SUMMARY.md b/tests/testsuite/sidebar/logo/other_src/my-src/SUMMARY.md new file mode 100644 index 0000000000..7390c82896 --- /dev/null +++ b/tests/testsuite/sidebar/logo/other_src/my-src/SUMMARY.md @@ -0,0 +1,3 @@ +# Summary + +- [Chapter 1](./chapter_1.md) diff --git a/tests/testsuite/sidebar/logo/other_src/my-src/chapter_1.md b/tests/testsuite/sidebar/logo/other_src/my-src/chapter_1.md new file mode 100644 index 0000000000..b743fda354 --- /dev/null +++ b/tests/testsuite/sidebar/logo/other_src/my-src/chapter_1.md @@ -0,0 +1 @@ +# Chapter 1 diff --git a/tests/testsuite/sidebar/logo/other_src/my-src/logo.svg b/tests/testsuite/sidebar/logo/other_src/my-src/logo.svg new file mode 100755 index 0000000000..90e0ea58bd --- /dev/null +++ b/tests/testsuite/sidebar/logo/other_src/my-src/logo.svg @@ -0,0 +1,22 @@ + + + + + diff --git a/tests/testsuite/sidebar/logo/outside/book.toml b/tests/testsuite/sidebar/logo/outside/book.toml new file mode 100644 index 0000000000..db6f90825c --- /dev/null +++ b/tests/testsuite/sidebar/logo/outside/book.toml @@ -0,0 +1,5 @@ +[book] +title = "outside" +authors = ["Chocorean"] +language = "en" +logo = "../logo.svg" diff --git a/tests/testsuite/sidebar/logo/outside/logo.svg b/tests/testsuite/sidebar/logo/outside/logo.svg new file mode 120000 index 0000000000..718fa53dd7 --- /dev/null +++ b/tests/testsuite/sidebar/logo/outside/logo.svg @@ -0,0 +1 @@ +../../../../../crates/mdbook-html/front-end/images/favicon.svg \ No newline at end of file diff --git a/tests/testsuite/sidebar/logo/outside/src/SUMMARY.md b/tests/testsuite/sidebar/logo/outside/src/SUMMARY.md new file mode 100644 index 0000000000..7390c82896 --- /dev/null +++ b/tests/testsuite/sidebar/logo/outside/src/SUMMARY.md @@ -0,0 +1,3 @@ +# Summary + +- [Chapter 1](./chapter_1.md) diff --git a/tests/testsuite/sidebar/logo/outside/src/chapter_1.md b/tests/testsuite/sidebar/logo/outside/src/chapter_1.md new file mode 100644 index 0000000000..b743fda354 --- /dev/null +++ b/tests/testsuite/sidebar/logo/outside/src/chapter_1.md @@ -0,0 +1 @@ +# Chapter 1 diff --git a/tests/testsuite/sidebar_logo.rs b/tests/testsuite/sidebar_logo.rs new file mode 100644 index 0000000000..c150deef5c --- /dev/null +++ b/tests/testsuite/sidebar_logo.rs @@ -0,0 +1,65 @@ +use crate::prelude::*; + +#[test] +fn bad_logo_path() { + BookTest::from_dir("sidebar/logo/not_found").run("build", |cmd| { + cmd.expect_failure(); + cmd.expect_stderr( + "ERROR invalid value for `logo`: [ROOT]/src/does/not/exist does not exist\n", + ); + }); +} + +#[test] +fn outside_src_dir() { + BookTest::from_dir("sidebar/logo/outside").run("build", |cmd| { + cmd.expect_failure(); + cmd.expect_stderr("ERROR invalid value for `logo`: should live under `src/`\n"); + }); +} + +#[test] +#[cfg(not(target_os = "windows"))] +fn abs_path() { + BookTest::from_dir("sidebar/logo/absolute_unix").run("build", |cmd| { + cmd.expect_failure(); + cmd.expect_stderr("ERROR invalid value for `logo`: should live under `src/`\n"); + }); +} + +#[test] +#[cfg(target_os = "windows")] +fn abs_path() { + BookTest::from_dir("sidebar/logo/absolute_windows").run("build", |cmd| { + cmd.expect_failure(); + cmd.expect_stderr("ERROR invalid value for `logo`: should live under `src/`\n"); + }); +} + +#[test] +fn good_logo() { + BookTest::from_dir("sidebar/logo/good") + .run("build", |cmd| { + cmd.expect_stderr(str![[r#" + INFO Book building has started + INFO Running the html backend + INFO HTML book written to `[ROOT]/book` + +"#]]); + }) + .check_file_contains("book/logo.svg", "