diff --git a/crates/mdbook-core/src/config.rs b/crates/mdbook-core/src/config.rs
index 44de130301..d4ae36aafa 100644
--- a/crates/mdbook-core/src/config.rs
+++ b/crates/mdbook-core/src/config.rs
@@ -436,6 +436,8 @@ pub struct HtmlConfig {
pub smart_punctuation: bool,
/// Support for definition lists.
pub definition_lists: bool,
+ /// Support for admonitions.
+ pub admonitions: bool,
/// Should mathjax be enabled?
pub mathjax_support: bool,
/// Additional CSS stylesheets to include in the rendered page's `
`.
@@ -504,6 +506,7 @@ impl Default for HtmlConfig {
preferred_dark_theme: None,
smart_punctuation: true,
definition_lists: true,
+ admonitions: true,
mathjax_support: false,
additional_css: Vec::new(),
additional_js: Vec::new(),
diff --git a/crates/mdbook-html/front-end/css/general.css b/crates/mdbook-html/front-end/css/general.css
index eca0e9da3b..df8a3efe2b 100644
--- a/crates/mdbook-html/front-end/css/general.css
+++ b/crates/mdbook-html/front-end/css/general.css
@@ -156,6 +156,8 @@ blockquote {
border-block-end: .1em solid var(--quote-border);
}
+/* TODO: Remove .warning in a future version of mdbook, it is replaced by
+blockquote tags. */
.warning {
margin: 20px;
padding: 0 20px;
@@ -324,3 +326,83 @@ dd > p {
space before the definition. */
margin-top: 0;
}
+
+/* Remove some excess space from the bottom. */
+.blockquote-tag p:last-child {
+ margin-bottom: 2px;
+}
+
+.blockquote-tag {
+ /* Add some padding to make the vertical bar a little taller than the text.*/
+ padding: 2px 0px 2px 20px;
+ /* Add a solid color bar on the left side. */
+ border-inline-start-style: solid;
+ border-inline-start-width: 4px;
+ /* Disable the background color from normal blockquotes . */
+ background-color: inherit;
+ /* Disable border blocks from blockquotes. */
+ border-block-start: none;
+ border-block-end: none;
+}
+
+.blockquote-tag-title svg {
+ fill: currentColor;
+ /* Add space between the icon and the title. */
+ margin-right: 8px;
+}
+
+.blockquote-tag-note {
+ border-inline-start-color: var(--blockquote-note-color);
+}
+
+.blockquote-tag-tip {
+ border-inline-start-color: var(--blockquote-tip-color);
+}
+
+.blockquote-tag-important {
+ border-inline-start-color: var(--blockquote-important-color);
+}
+
+.blockquote-tag-warning {
+ border-inline-start-color: var(--blockquote-warning-color);
+}
+
+.blockquote-tag-caution {
+ border-inline-start-color: var(--blockquote-caution-color);
+}
+
+.blockquote-tag-note .blockquote-tag-title {
+ color: var(--blockquote-note-color);
+}
+
+.blockquote-tag-tip .blockquote-tag-title {
+ color: var(--blockquote-tip-color);
+}
+
+.blockquote-tag-important .blockquote-tag-title {
+ color: var(--blockquote-important-color);
+}
+
+.blockquote-tag-warning .blockquote-tag-title {
+ color: var(--blockquote-warning-color);
+}
+
+.blockquote-tag-caution .blockquote-tag-title {
+ color: var(--blockquote-caution-color);
+}
+
+.blockquote-tag-title {
+ /* Slightly increase the weight for more emphasis. */
+ font-weight: 600;
+ /* Vertically center the icon with the text. */
+ display: flex;
+ align-items: center;
+ /* Remove default large margins for a more compact display. */
+ margin: 2px 0 8px 0;
+}
+
+.blockquote-tag-title .fa-svg {
+ fill: currentColor;
+ /* Add some space between the icon and the text. */
+ margin-right: 8px;
+}
diff --git a/crates/mdbook-html/front-end/css/variables.css b/crates/mdbook-html/front-end/css/variables.css
index ae287821c0..b715d672ed 100644
--- a/crates/mdbook-html/front-end/css/variables.css
+++ b/crates/mdbook-html/front-end/css/variables.css
@@ -67,6 +67,12 @@
--footnote-highlight: #2668a6;
--overlay-bg: rgba(33, 40, 48, 0.4);
+
+ --blockquote-note-color: #74b9ff;
+ --blockquote-tip-color: #09ca09;
+ --blockquote-important-color: #d3abff;
+ --blockquote-warning-color: #f0b72f;
+ --blockquote-caution-color: #f21424;
}
.coal {
@@ -120,6 +126,12 @@
--footnote-highlight: #4079ae;
--overlay-bg: rgba(33, 40, 48, 0.4);
+
+ --blockquote-note-color: #4493f8;
+ --blockquote-tip-color: #08ae08;
+ --blockquote-important-color: #ab7df8;
+ --blockquote-warning-color: #d29922;
+ --blockquote-caution-color: #d91b29;
}
.light, html:not(.js) {
@@ -173,6 +185,12 @@
--footnote-highlight: #7e7eff;
--overlay-bg: rgba(200, 200, 205, 0.4);
+
+ --blockquote-note-color: #0969da;
+ --blockquote-tip-color: #008000;
+ --blockquote-important-color: #8250df;
+ --blockquote-warning-color: #9a6700;
+ --blockquote-caution-color: #b52731;
}
.navy {
@@ -226,6 +244,12 @@
--footnote-highlight: #4079ae;
--overlay-bg: rgba(33, 40, 48, 0.4);
+
+ --blockquote-note-color: #4493f8;
+ --blockquote-tip-color: #09ca09;
+ --blockquote-important-color: #ab7df8;
+ --blockquote-warning-color: #d29922;
+ --blockquote-caution-color: #f21424;
}
.rust {
@@ -277,6 +301,12 @@
--footnote-highlight: #d3a17a;
--overlay-bg: rgba(150, 150, 150, 0.25);
+
+ --blockquote-note-color: #023b95;
+ --blockquote-tip-color: #007700;
+ --blockquote-important-color: #8250df;
+ --blockquote-warning-color: #603700;
+ --blockquote-caution-color: #aa1721;
}
@media (prefers-color-scheme: dark) {
@@ -331,5 +361,11 @@
--footnote-highlight: #4079ae;
--overlay-bg: rgba(33, 40, 48, 0.4);
+
+ --blockquote-note-color: #4493f8;
+ --blockquote-tip-color: #08ae08;
+ --blockquote-important-color: #ab7df8;
+ --blockquote-warning-color: #d29922;
+ --blockquote-caution-color: #d91b29;
}
}
diff --git a/crates/mdbook-html/src/html/admonitions.rs b/crates/mdbook-html/src/html/admonitions.rs
new file mode 100644
index 0000000000..e2bd4c0611
--- /dev/null
+++ b/crates/mdbook-html/src/html/admonitions.rs
@@ -0,0 +1,26 @@
+use pulldown_cmark::BlockQuoteKind;
+
+// This icon is from GitHub, MIT License, see https://github.com/primer/octicons
+const ICON_NOTE: &str = r#""#;
+
+// This icon is from GitHub, MIT License, see https://github.com/primer/octicons
+const ICON_TIP: &str = r#""#;
+
+// This icon is from GitHub, MIT License, see https://github.com/primer/octicons
+const ICON_IMPORTANT: &str = r#""#;
+
+// This icon is from GitHub, MIT License, see https://github.com/primer/octicons
+const ICON_WARNING: &str = r#""#;
+
+// This icon is from GitHub, MIT License, see https://github.com/primer/octicons
+const ICON_CAUTION: &str = r#""#;
+
+pub(crate) fn select_tag(kind: BlockQuoteKind) -> (&'static str, &'static str, &'static str) {
+ match kind {
+ BlockQuoteKind::Note => ("note", ICON_NOTE, "Note"),
+ BlockQuoteKind::Tip => ("tip", ICON_TIP, "Tip"),
+ BlockQuoteKind::Important => ("important", ICON_IMPORTANT, "Important"),
+ BlockQuoteKind::Warning => ("warning", ICON_WARNING, "Warning"),
+ BlockQuoteKind::Caution => ("caution", ICON_CAUTION, "Caution"),
+ }
+}
diff --git a/crates/mdbook-html/src/html/mod.rs b/crates/mdbook-html/src/html/mod.rs
index af1306ae23..8a70700f7e 100644
--- a/crates/mdbook-html/src/html/mod.rs
+++ b/crates/mdbook-html/src/html/mod.rs
@@ -16,6 +16,7 @@ use mdbook_core::config::{HtmlConfig, RustEdition};
use mdbook_markdown::{MarkdownOptions, new_cmark_parser};
use std::path::{Path, PathBuf};
+mod admonitions;
mod hide_lines;
mod print;
mod serialize;
@@ -51,6 +52,7 @@ impl<'a> HtmlRenderOptions<'a> {
let mut markdown_options = MarkdownOptions::default();
markdown_options.smart_punctuation = config.smart_punctuation;
markdown_options.definition_lists = config.definition_lists;
+ markdown_options.admonitions = config.admonitions;
HtmlRenderOptions {
markdown_options,
path,
diff --git a/crates/mdbook-html/src/html/tree.rs b/crates/mdbook-html/src/html/tree.rs
index 2efce9678a..ba441f6f91 100644
--- a/crates/mdbook-html/src/html/tree.rs
+++ b/crates/mdbook-html/src/html/tree.rs
@@ -15,9 +15,7 @@ use html5ever::{LocalName, QualName};
use indexmap::IndexMap;
use mdbook_core::config::RustEdition;
use mdbook_core::static_regex;
-use pulldown_cmark::{
- Alignment, BlockQuoteKind, CodeBlockKind, CowStr, Event, LinkType, Tag, TagEnd,
-};
+use pulldown_cmark::{Alignment, CodeBlockKind, CowStr, Event, LinkType, Tag, TagEnd};
use std::borrow::Cow;
use std::collections::{HashMap, HashSet};
use std::ops::Deref;
@@ -407,14 +405,27 @@ where
Tag::BlockQuote(kind) => {
let mut b = Element::new("blockquote");
if let Some(kind) = kind {
- let class = match kind {
- BlockQuoteKind::Note => "markdown-alert-note",
- BlockQuoteKind::Tip => "markdown-alert-tip",
- BlockQuoteKind::Important => "markdown-alert-important",
- BlockQuoteKind::Warning => "markdown-alert-warning",
- BlockQuoteKind::Caution => "markdown-alert-caution",
- };
+ let (class_kind, icon, text) = super::admonitions::select_tag(kind);
+ let class = format!("blockquote-tag blockquote-tag-{class_kind}");
b.insert_attr("class", class.into());
+ self.push(Node::Element(b));
+
+ let mut title = Element::new("p");
+ title.insert_attr("class", "blockquote-tag-title".into());
+ self.push(Node::Element(title));
+
+ let mut svg = Element::new("svg");
+ svg.insert_attr("viewbox", "0 0 16 16".into());
+ svg.insert_attr("width", "18".into());
+ svg.insert_attr("height", "18".into());
+ self.push(Node::Element(svg));
+ self.append_html(icon);
+ self.pop();
+
+ self.append(Node::Text(text.into()));
+
+ self.pop();
+ return;
}
b
}
diff --git a/crates/mdbook-markdown/src/lib.rs b/crates/mdbook-markdown/src/lib.rs
index 0f490ee1f8..339674a4e2 100644
--- a/crates/mdbook-markdown/src/lib.rs
+++ b/crates/mdbook-markdown/src/lib.rs
@@ -28,6 +28,10 @@ pub struct MarkdownOptions {
///
/// This is `true` by default.
pub definition_lists: bool,
+ /// Enables admonitions.
+ ///
+ /// This is `true` by default.
+ pub admonitions: bool,
}
impl Default for MarkdownOptions {
@@ -35,6 +39,7 @@ impl Default for MarkdownOptions {
MarkdownOptions {
smart_punctuation: true,
definition_lists: true,
+ admonitions: true,
}
}
}
@@ -53,5 +58,8 @@ pub fn new_cmark_parser<'text>(text: &'text str, options: &MarkdownOptions) -> P
if options.definition_lists {
opts.insert(Options::ENABLE_DEFINITION_LIST);
}
+ if options.admonitions {
+ opts.insert(Options::ENABLE_GFM);
+ }
Parser::new_ext(text, opts)
}
diff --git a/guide/src/format/configuration/renderers.md b/guide/src/format/configuration/renderers.md
index 6e9ccda7c1..ec2ea09243 100644
--- a/guide/src/format/configuration/renderers.md
+++ b/guide/src/format/configuration/renderers.md
@@ -99,6 +99,7 @@ default-theme = "light"
preferred-dark-theme = "navy"
smart-punctuation = true
definition-lists = true
+admonitions = true
mathjax-support = false
additional-css = ["custom.css", "custom2.css"]
additional-js = ["custom.js"]
@@ -127,6 +128,7 @@ The following configuration options are available:
See [Smart Punctuation](../markdown.md#smart-punctuation).
Defaults to `true`.
- **definition-lists:** Enables [definition lists](../markdown.md#definition-lists). Defaults to `true`.
+- **admonitions:** Enables [admonitions](../markdown.md#admonitions). Defaults to `true`.
- **mathjax-support:** Adds support for [MathJax](../mathjax.md). Defaults to
`false`.
- **additional-css:** If you need to slightly change the appearance of your book
diff --git a/guide/src/format/markdown.md b/guide/src/format/markdown.md
index f6f58a891f..60c62ac3c9 100644
--- a/guide/src/format/markdown.md
+++ b/guide/src/format/markdown.md
@@ -270,3 +270,46 @@ term B
Terms are clickable just like headers, which will set the browser's URL to point directly to that term.
See the [definition lists spec](https://github.com/pulldown-cmark/pulldown-cmark/blob/HEAD/pulldown-cmark/specs/definition_lists.txt) for more information on the specifics of the syntax. See the [Wikipedia guidelines for glossaries](https://en.wikipedia.org/wiki/Wikipedia:Manual_of_Style/Glossaries#General_guidelines_for_writing_glossaries) for some guidelines on how to write a glossary.
+
+### Admonitions
+
+An admonition is a special type of callout or notice block used to highlight important information. It is written as a blockquote with a special tag on the first line.
+
+```md
+> [!NOTE]
+> General information or additional context.
+
+> [!TIP]
+> A helpful suggestion or best practice.
+
+> [!IMPORTANT]
+> Key information that shouldn't be missed.
+
+> [!WARNING]
+> Critical information that highlights a potential risk.
+
+> [!CAUTION]
+> Information about potential issues that require caution.
+```
+
+These will render as:
+
+> [!NOTE]
+> General information or additional context.
+
+> [!TIP]
+> A helpful suggestion or best practice.
+
+> [!IMPORTANT]
+> Key information that shouldn't be missed.
+
+> [!WARNING]
+> Critical information that highlights a potential risk.
+
+> [!CAUTION]
+> Information about potential issues that require caution.
+
+This feature is enabled by default.
+To disable it, see the [`output.html.admonitions`] config option.
+
+[`output.html.admonitions`]: configuration/renderers.md#html-renderer-options
diff --git a/guide/src/format/mdbook.md b/guide/src/format/mdbook.md
index 4243627fd1..8b0e7314de 100644
--- a/guide/src/format/mdbook.md
+++ b/guide/src/format/mdbook.md
@@ -338,32 +338,6 @@ HTML tags with class `hidden` will not be shown.
This will not be seen.
-### `class="warning"`
-
-To make a warning or similar note stand out, wrap it in a warning div.
-
-```html
-
-
-This is a bad thing that you should pay attention to.
-
-Warning blocks should be used sparingly in documentation, to avoid "warning
-fatigue," where people are trained to ignore them because they usually don't
-matter for what they're doing.
-
-
-```
-
-
-
-This is a bad thing that you should pay attention to.
-
-Warning blocks should be used sparingly in documentation, to avoid "warning
-fatigue," where people are trained to ignore them because they usually don't
-matter for what they're doing.
-
-
\ No newline at end of file
diff --git a/tests/testsuite/markdown/admonitions/expected_disabled/admonitions.html b/tests/testsuite/markdown/admonitions/expected_disabled/admonitions.html
new file mode 100644
index 0000000000..3bb296ed5b
--- /dev/null
+++ b/tests/testsuite/markdown/admonitions/expected_disabled/admonitions.html
@@ -0,0 +1,26 @@
+
\ No newline at end of file
diff --git a/tests/testsuite/markdown/admonitions/src/SUMMARY.md b/tests/testsuite/markdown/admonitions/src/SUMMARY.md
new file mode 100644
index 0000000000..58da0f6c7f
--- /dev/null
+++ b/tests/testsuite/markdown/admonitions/src/SUMMARY.md
@@ -0,0 +1,3 @@
+# Summary
+
+- [Admonitions](./admonitions.md)
diff --git a/tests/testsuite/markdown/admonitions/src/admonitions.md b/tests/testsuite/markdown/admonitions/src/admonitions.md
new file mode 100644
index 0000000000..0bf6526fe0
--- /dev/null
+++ b/tests/testsuite/markdown/admonitions/src/admonitions.md
@@ -0,0 +1,21 @@
+# Admonitions
+
+> [!NOTE]
+> This is a note.
+>
+> There are multiple paragraphs.
+
+> [!TIP]
+> This is a tip.
+
+> [!IMPORTANT]
+> This is important.
+
+> [!WARNING]
+> This is a warning.
+
+> [!CAUTION]
+> This is a caution.
+
+> [!UNKNOWN]
+> This is an unknown tag.