2025-04-22 08:54:31 -07:00
//! Tests for HTML rendering.
2025-09-16 14:07:54 -07:00
//!
//! Note that markdown-specific rendering tests are in the `markdown` module.
2025-04-22 08:54:31 -07:00
use crate ::prelude ::* ;
// Checks that edit-url-template works.
#[ test ]
fn edit_url_template ( ) {
BookTest ::from_dir ( " rendering/edit_url_template " ) . check_file_contains (
" book/index.html " ,
" <a href= \" https://github.com/rust-lang/mdBook/edit/master/guide/src/README.md \" \
2025-05-14 22:57:58 +01:00
title = \ " Suggest an edit \" aria-label= \" Suggest an edit \" rel= \" edit \" > " ,
2025-04-22 08:54:31 -07:00
) ;
}
// Checks that an alternate `src` setting works with the edit url template.
#[ test ]
fn edit_url_template_explicit_src ( ) {
BookTest ::from_dir ( " rendering/edit_url_template_explicit_src " ) . check_file_contains (
" book/index.html " ,
" <a href= \" https://github.com/rust-lang/mdBook/edit/master/guide/src2/README.md \" \
2025-05-14 22:57:58 +01:00
title = \ " Suggest an edit \" aria-label= \" Suggest an edit \" rel= \" edit \" > " ,
2025-04-22 08:54:31 -07:00
) ;
}
2025-04-22 08:55:24 -07:00
// Checks that index.html is generated correctly, even when the first few
// chapters are drafts.
#[ test ]
fn first_chapter_is_copied_as_index_even_if_not_first_elem ( ) {
BookTest ::from_dir ( " rendering/first_chapter_is_copied_as_index_even_if_not_first_elem " )
// These two files should be equal.
. check_main_file (
" book/chapter_1.html " ,
str ! [ [
r ## "<h1 id="chapter-1"><a class="header" href="#chapter-1">Chapter 1</a></h1>"##
] ] ,
)
. check_main_file (
" book/index.html " ,
str ! [ [
r ## "<h1 id="chapter-1"><a class="header" href="#chapter-1">Chapter 1</a></h1>"##
] ] ,
) ;
}
2025-09-16 14:07:54 -07:00
// Fontawesome `<i>` tag support.
#[ test ]
fn fontawesome ( ) {
2025-10-30 19:27:40 -07:00
BookTest ::from_dir ( " rendering/fontawesome " )
. run ( " build " , | cmd | {
cmd . expect_stderr ( str ! [ [ r #"
INFO Book building has started
INFO Running the html backend
2025-10-30 19:30:01 -07:00
WARN failed to find Font Awesome icon for icon ` does - not - exist ` with type ` regular ` in ` fa . md ` : Invalid Font Awesome icon name : visit https ://fontawesome.com/icons?d=gallery&m=free to see valid names
2025-10-30 19:27:40 -07:00
INFO HTML book written to ` [ ROOT ] / book `
" #]]);
} )
. check_all_main_files ( ) ;
2025-09-16 14:07:54 -07:00
}
2026-02-24 08:58:05 -05:00
// Verifies that an invalid `git-repository-icon` in book.toml produces a
// helpful error message with the icon name, type, and a link to FontAwesome.
#[ test ]
fn fontawesome_error_message ( ) {
BookTest ::from_dir ( " rendering/fontawesome_error " )
. run ( " build " , | cmd | {
cmd . expect_failure ( ) ;
cmd . expect_stderr ( str ! [ [ r #"
INFO Book building has started
INFO Running the html backend
ERROR Rendering failed
[ TAB ] Caused by : Error rendering " index " line [ .. ] , col [ .. ] : Unknown Font Awesome icon ` github ` for type ` regular ` . Hint : check the icon name and prefix ( fas ( solid ) , fab ( brands ) , or far ( regular ) ) at https ://fontawesome.com/v6/search?m=free
[ TAB ] Caused by : Unknown Font Awesome icon ` github ` for type ` regular ` . Hint : check the icon name and prefix ( fas ( solid ) , fab ( brands ) , or far ( regular ) ) at https ://fontawesome.com/v6/search?m=free
" #]]);
} ) ;
}
2025-09-16 14:07:54 -07:00
// Tests the rendering when setting the default rust edition.
#[ test ]
fn default_rust_edition ( ) {
BookTest ::from_dir ( " rendering/default_rust_edition " ) . check_all_main_files ( ) ;
}
// Tests the rendering for editable code blocks.
#[ test ]
fn editable_rust_block ( ) {
BookTest ::from_dir ( " rendering/editable_rust_block " ) . check_all_main_files ( ) ;
}
// Tests for custom hide lines.
#[ test ]
fn hidelines ( ) {
BookTest ::from_dir ( " rendering/hidelines " ) . check_all_main_files ( ) ;
}
// Tests for code blocks of basic rust code.
#[ test ]
fn language_rust_playground ( ) {
fn expect ( input : & str , info : & str , expected : impl snapbox ::IntoData ) {
BookTest ::init ( | _ | { } )
. change_file ( " book.toml " , " output.html.playground.editable = true " )
. change_file ( " src/chapter_1.md " , & format! ( " ```rust {info} \n {input} \n ``` " ) )
. check_main_file ( " book/chapter_1.html " , expected ) ;
}
// No-main should be wrapped in `fn main` boring lines.
expect (
" x() " ,
" " ,
str ! [ [ r #"
Add a new HTML rendering pipeline
This rewrites the HTML rendering pipeline to use a tree data structure,
and implements a custom HTML serializer. The intent is to make it easier
to make changes and to manipulate the output. This should make some
future changes much easier.
This is a large change, but I'll try to briefly summarize what's
changing:
- All of the HTML rendering support has been moved out of
mdbook-markdown into mdbook-html. For now, all of the API surface is
private, though we may consider ways to safely expose it in the
future.
- Instead of using pulldown-cmark's html serializer, this takes the
pulldown-cmark events and translates them into a tree data structure
(using the ego-tree crate to define the tree). See `tree.rs`.
- HTML in the markdown document is parsed using html5ever, and then
lives inside the same tree data structure. See `tokenizer.rs`.
- Transformations are then applied to the tree data structure. For
example, adding header links or hiding code lines.
- Serialization is a simple process of writing out the nodes to a
string. See `serialize.rs`.
- The search indexer works on the tree structure instead of re-rendering
every chapter twice. See `html_handlebars/search.rs`.
- The print page now takes a very different approach of taking the
same tree structure built for rendering the chapters, and applies
transformations to it. This avoid re-parsing everything again. See
`print.rs`.
- I changed the linking behavior so that links on the print page
link to items on the print page instead of outside the print page.
- There are a variety of small changes to how it serializes as can be
seen in the changes to the tests. Some highlights:
- Code blocks no longer have a second layer of `<pre>` tags wrapping
it.
- Fixed a minor issue where a rust code block with a specific
edition was having the wrong classes when there was a default
edition.
- Drops the ammonia dependency, which significantly reduces the number
of dependencies. It was only being used for a very minor task, and
we can handle it much more easily now.
- Drops `pretty_assertions`, they are no longer used (mostly being
migrated to the testsuite).
There's obviously a lot of risk trying to parse everything to such a low
level, but I think the benefits are worth it. Also, the API isn't super
ergonomic compared to say javascript (there are no selectors), but it
works well enough so far.
I have not run this through rigorous benchmarking, but it does have a
very noticeable performance improvement, especially in a debug build.
I expect in the future that we'll want to expose some kind of
integration with extensions so they have access to this tree structure
(or some kind of tree structure).
Closes https://github.com/rust-lang/mdBook/issues/1736
2025-09-16 20:14:00 -07:00
< pre class = " playground " > < code class = " language-rust " > < span class = " boring " > #![ allow(unused) ]
2025-09-16 14:07:54 -07:00
< / span > < span class = " boring " > fn main ( ) {
< / span > x ( )
Add a new HTML rendering pipeline
This rewrites the HTML rendering pipeline to use a tree data structure,
and implements a custom HTML serializer. The intent is to make it easier
to make changes and to manipulate the output. This should make some
future changes much easier.
This is a large change, but I'll try to briefly summarize what's
changing:
- All of the HTML rendering support has been moved out of
mdbook-markdown into mdbook-html. For now, all of the API surface is
private, though we may consider ways to safely expose it in the
future.
- Instead of using pulldown-cmark's html serializer, this takes the
pulldown-cmark events and translates them into a tree data structure
(using the ego-tree crate to define the tree). See `tree.rs`.
- HTML in the markdown document is parsed using html5ever, and then
lives inside the same tree data structure. See `tokenizer.rs`.
- Transformations are then applied to the tree data structure. For
example, adding header links or hiding code lines.
- Serialization is a simple process of writing out the nodes to a
string. See `serialize.rs`.
- The search indexer works on the tree structure instead of re-rendering
every chapter twice. See `html_handlebars/search.rs`.
- The print page now takes a very different approach of taking the
same tree structure built for rendering the chapters, and applies
transformations to it. This avoid re-parsing everything again. See
`print.rs`.
- I changed the linking behavior so that links on the print page
link to items on the print page instead of outside the print page.
- There are a variety of small changes to how it serializes as can be
seen in the changes to the tests. Some highlights:
- Code blocks no longer have a second layer of `<pre>` tags wrapping
it.
- Fixed a minor issue where a rust code block with a specific
edition was having the wrong classes when there was a default
edition.
- Drops the ammonia dependency, which significantly reduces the number
of dependencies. It was only being used for a very minor task, and
we can handle it much more easily now.
- Drops `pretty_assertions`, they are no longer used (mostly being
migrated to the testsuite).
There's obviously a lot of risk trying to parse everything to such a low
level, but I think the benefits are worth it. Also, the API isn't super
ergonomic compared to say javascript (there are no selectors), but it
works well enough so far.
I have not run this through rigorous benchmarking, but it does have a
very noticeable performance improvement, especially in a debug build.
I expect in the future that we'll want to expose some kind of
integration with extensions so they have access to this tree structure
(or some kind of tree structure).
Closes https://github.com/rust-lang/mdBook/issues/1736
2025-09-16 20:14:00 -07:00
< span class = " boring " > } < / span > < / code > < / pre >
2025-09-16 14:07:54 -07:00
" #]],
) ;
// `fn main` should not be wrapped, not boring.
expect (
" fn main() {} " ,
" " ,
Add a new HTML rendering pipeline
This rewrites the HTML rendering pipeline to use a tree data structure,
and implements a custom HTML serializer. The intent is to make it easier
to make changes and to manipulate the output. This should make some
future changes much easier.
This is a large change, but I'll try to briefly summarize what's
changing:
- All of the HTML rendering support has been moved out of
mdbook-markdown into mdbook-html. For now, all of the API surface is
private, though we may consider ways to safely expose it in the
future.
- Instead of using pulldown-cmark's html serializer, this takes the
pulldown-cmark events and translates them into a tree data structure
(using the ego-tree crate to define the tree). See `tree.rs`.
- HTML in the markdown document is parsed using html5ever, and then
lives inside the same tree data structure. See `tokenizer.rs`.
- Transformations are then applied to the tree data structure. For
example, adding header links or hiding code lines.
- Serialization is a simple process of writing out the nodes to a
string. See `serialize.rs`.
- The search indexer works on the tree structure instead of re-rendering
every chapter twice. See `html_handlebars/search.rs`.
- The print page now takes a very different approach of taking the
same tree structure built for rendering the chapters, and applies
transformations to it. This avoid re-parsing everything again. See
`print.rs`.
- I changed the linking behavior so that links on the print page
link to items on the print page instead of outside the print page.
- There are a variety of small changes to how it serializes as can be
seen in the changes to the tests. Some highlights:
- Code blocks no longer have a second layer of `<pre>` tags wrapping
it.
- Fixed a minor issue where a rust code block with a specific
edition was having the wrong classes when there was a default
edition.
- Drops the ammonia dependency, which significantly reduces the number
of dependencies. It was only being used for a very minor task, and
we can handle it much more easily now.
- Drops `pretty_assertions`, they are no longer used (mostly being
migrated to the testsuite).
There's obviously a lot of risk trying to parse everything to such a low
level, but I think the benefits are worth it. Also, the API isn't super
ergonomic compared to say javascript (there are no selectors), but it
works well enough so far.
I have not run this through rigorous benchmarking, but it does have a
very noticeable performance improvement, especially in a debug build.
I expect in the future that we'll want to expose some kind of
integration with extensions so they have access to this tree structure
(or some kind of tree structure).
Closes https://github.com/rust-lang/mdBook/issues/1736
2025-09-16 20:14:00 -07:00
str ! [ [ r # "<pre class="playground"><code class="language-rust">fn main() {}</code></pre>"# ] ] ,
2025-09-16 14:07:54 -07:00
) ;
// Lines starting with `#` are boring.
expect (
" let s = \" foo \n # bar \n \" ; " ,
" editable " ,
str ! [ [ r #"
Add a new HTML rendering pipeline
This rewrites the HTML rendering pipeline to use a tree data structure,
and implements a custom HTML serializer. The intent is to make it easier
to make changes and to manipulate the output. This should make some
future changes much easier.
This is a large change, but I'll try to briefly summarize what's
changing:
- All of the HTML rendering support has been moved out of
mdbook-markdown into mdbook-html. For now, all of the API surface is
private, though we may consider ways to safely expose it in the
future.
- Instead of using pulldown-cmark's html serializer, this takes the
pulldown-cmark events and translates them into a tree data structure
(using the ego-tree crate to define the tree). See `tree.rs`.
- HTML in the markdown document is parsed using html5ever, and then
lives inside the same tree data structure. See `tokenizer.rs`.
- Transformations are then applied to the tree data structure. For
example, adding header links or hiding code lines.
- Serialization is a simple process of writing out the nodes to a
string. See `serialize.rs`.
- The search indexer works on the tree structure instead of re-rendering
every chapter twice. See `html_handlebars/search.rs`.
- The print page now takes a very different approach of taking the
same tree structure built for rendering the chapters, and applies
transformations to it. This avoid re-parsing everything again. See
`print.rs`.
- I changed the linking behavior so that links on the print page
link to items on the print page instead of outside the print page.
- There are a variety of small changes to how it serializes as can be
seen in the changes to the tests. Some highlights:
- Code blocks no longer have a second layer of `<pre>` tags wrapping
it.
- Fixed a minor issue where a rust code block with a specific
edition was having the wrong classes when there was a default
edition.
- Drops the ammonia dependency, which significantly reduces the number
of dependencies. It was only being used for a very minor task, and
we can handle it much more easily now.
- Drops `pretty_assertions`, they are no longer used (mostly being
migrated to the testsuite).
There's obviously a lot of risk trying to parse everything to such a low
level, but I think the benefits are worth it. Also, the API isn't super
ergonomic compared to say javascript (there are no selectors), but it
works well enough so far.
I have not run this through rigorous benchmarking, but it does have a
very noticeable performance improvement, especially in a debug build.
I expect in the future that we'll want to expose some kind of
integration with extensions so they have access to this tree structure
(or some kind of tree structure).
Closes https://github.com/rust-lang/mdBook/issues/1736
2025-09-16 20:14:00 -07:00
< pre class = " playground " > < code class = " language-rust editable " > let s = " foo
2025-09-16 14:07:54 -07:00
< span class = " boring " > bar
Add a new HTML rendering pipeline
This rewrites the HTML rendering pipeline to use a tree data structure,
and implements a custom HTML serializer. The intent is to make it easier
to make changes and to manipulate the output. This should make some
future changes much easier.
This is a large change, but I'll try to briefly summarize what's
changing:
- All of the HTML rendering support has been moved out of
mdbook-markdown into mdbook-html. For now, all of the API surface is
private, though we may consider ways to safely expose it in the
future.
- Instead of using pulldown-cmark's html serializer, this takes the
pulldown-cmark events and translates them into a tree data structure
(using the ego-tree crate to define the tree). See `tree.rs`.
- HTML in the markdown document is parsed using html5ever, and then
lives inside the same tree data structure. See `tokenizer.rs`.
- Transformations are then applied to the tree data structure. For
example, adding header links or hiding code lines.
- Serialization is a simple process of writing out the nodes to a
string. See `serialize.rs`.
- The search indexer works on the tree structure instead of re-rendering
every chapter twice. See `html_handlebars/search.rs`.
- The print page now takes a very different approach of taking the
same tree structure built for rendering the chapters, and applies
transformations to it. This avoid re-parsing everything again. See
`print.rs`.
- I changed the linking behavior so that links on the print page
link to items on the print page instead of outside the print page.
- There are a variety of small changes to how it serializes as can be
seen in the changes to the tests. Some highlights:
- Code blocks no longer have a second layer of `<pre>` tags wrapping
it.
- Fixed a minor issue where a rust code block with a specific
edition was having the wrong classes when there was a default
edition.
- Drops the ammonia dependency, which significantly reduces the number
of dependencies. It was only being used for a very minor task, and
we can handle it much more easily now.
- Drops `pretty_assertions`, they are no longer used (mostly being
migrated to the testsuite).
There's obviously a lot of risk trying to parse everything to such a low
level, but I think the benefits are worth it. Also, the API isn't super
ergonomic compared to say javascript (there are no selectors), but it
works well enough so far.
I have not run this through rigorous benchmarking, but it does have a
very noticeable performance improvement, especially in a debug build.
I expect in the future that we'll want to expose some kind of
integration with extensions so they have access to this tree structure
(or some kind of tree structure).
Closes https://github.com/rust-lang/mdBook/issues/1736
2025-09-16 20:14:00 -07:00
< / span > " ;</code></pre>
2025-09-16 14:07:54 -07:00
" #]],
) ;
// `##` is not boring and is used as an escape.
expect (
" let s = \" foo \n ## bar \n \" ; " ,
" editable " ,
str ! [ [ r #"
Add a new HTML rendering pipeline
This rewrites the HTML rendering pipeline to use a tree data structure,
and implements a custom HTML serializer. The intent is to make it easier
to make changes and to manipulate the output. This should make some
future changes much easier.
This is a large change, but I'll try to briefly summarize what's
changing:
- All of the HTML rendering support has been moved out of
mdbook-markdown into mdbook-html. For now, all of the API surface is
private, though we may consider ways to safely expose it in the
future.
- Instead of using pulldown-cmark's html serializer, this takes the
pulldown-cmark events and translates them into a tree data structure
(using the ego-tree crate to define the tree). See `tree.rs`.
- HTML in the markdown document is parsed using html5ever, and then
lives inside the same tree data structure. See `tokenizer.rs`.
- Transformations are then applied to the tree data structure. For
example, adding header links or hiding code lines.
- Serialization is a simple process of writing out the nodes to a
string. See `serialize.rs`.
- The search indexer works on the tree structure instead of re-rendering
every chapter twice. See `html_handlebars/search.rs`.
- The print page now takes a very different approach of taking the
same tree structure built for rendering the chapters, and applies
transformations to it. This avoid re-parsing everything again. See
`print.rs`.
- I changed the linking behavior so that links on the print page
link to items on the print page instead of outside the print page.
- There are a variety of small changes to how it serializes as can be
seen in the changes to the tests. Some highlights:
- Code blocks no longer have a second layer of `<pre>` tags wrapping
it.
- Fixed a minor issue where a rust code block with a specific
edition was having the wrong classes when there was a default
edition.
- Drops the ammonia dependency, which significantly reduces the number
of dependencies. It was only being used for a very minor task, and
we can handle it much more easily now.
- Drops `pretty_assertions`, they are no longer used (mostly being
migrated to the testsuite).
There's obviously a lot of risk trying to parse everything to such a low
level, but I think the benefits are worth it. Also, the API isn't super
ergonomic compared to say javascript (there are no selectors), but it
works well enough so far.
I have not run this through rigorous benchmarking, but it does have a
very noticeable performance improvement, especially in a debug build.
I expect in the future that we'll want to expose some kind of
integration with extensions so they have access to this tree structure
(or some kind of tree structure).
Closes https://github.com/rust-lang/mdBook/issues/1736
2025-09-16 20:14:00 -07:00
< pre class = " playground " > < code class = " language-rust editable " > let s = " foo
2025-09-16 14:07:54 -07:00
# bar
Add a new HTML rendering pipeline
This rewrites the HTML rendering pipeline to use a tree data structure,
and implements a custom HTML serializer. The intent is to make it easier
to make changes and to manipulate the output. This should make some
future changes much easier.
This is a large change, but I'll try to briefly summarize what's
changing:
- All of the HTML rendering support has been moved out of
mdbook-markdown into mdbook-html. For now, all of the API surface is
private, though we may consider ways to safely expose it in the
future.
- Instead of using pulldown-cmark's html serializer, this takes the
pulldown-cmark events and translates them into a tree data structure
(using the ego-tree crate to define the tree). See `tree.rs`.
- HTML in the markdown document is parsed using html5ever, and then
lives inside the same tree data structure. See `tokenizer.rs`.
- Transformations are then applied to the tree data structure. For
example, adding header links or hiding code lines.
- Serialization is a simple process of writing out the nodes to a
string. See `serialize.rs`.
- The search indexer works on the tree structure instead of re-rendering
every chapter twice. See `html_handlebars/search.rs`.
- The print page now takes a very different approach of taking the
same tree structure built for rendering the chapters, and applies
transformations to it. This avoid re-parsing everything again. See
`print.rs`.
- I changed the linking behavior so that links on the print page
link to items on the print page instead of outside the print page.
- There are a variety of small changes to how it serializes as can be
seen in the changes to the tests. Some highlights:
- Code blocks no longer have a second layer of `<pre>` tags wrapping
it.
- Fixed a minor issue where a rust code block with a specific
edition was having the wrong classes when there was a default
edition.
- Drops the ammonia dependency, which significantly reduces the number
of dependencies. It was only being used for a very minor task, and
we can handle it much more easily now.
- Drops `pretty_assertions`, they are no longer used (mostly being
migrated to the testsuite).
There's obviously a lot of risk trying to parse everything to such a low
level, but I think the benefits are worth it. Also, the API isn't super
ergonomic compared to say javascript (there are no selectors), but it
works well enough so far.
I have not run this through rigorous benchmarking, but it does have a
very noticeable performance improvement, especially in a debug build.
I expect in the future that we'll want to expose some kind of
integration with extensions so they have access to this tree structure
(or some kind of tree structure).
Closes https://github.com/rust-lang/mdBook/issues/1736
2025-09-16 20:14:00 -07:00
" ;</code></pre>
2025-09-16 14:07:54 -07:00
" #]],
) ;
// `#` on a line by itself is boring.
expect (
" let s = \" foo \n # bar \n # \n \" ; " ,
" editable " ,
str ! [ [ r #"
Add a new HTML rendering pipeline
This rewrites the HTML rendering pipeline to use a tree data structure,
and implements a custom HTML serializer. The intent is to make it easier
to make changes and to manipulate the output. This should make some
future changes much easier.
This is a large change, but I'll try to briefly summarize what's
changing:
- All of the HTML rendering support has been moved out of
mdbook-markdown into mdbook-html. For now, all of the API surface is
private, though we may consider ways to safely expose it in the
future.
- Instead of using pulldown-cmark's html serializer, this takes the
pulldown-cmark events and translates them into a tree data structure
(using the ego-tree crate to define the tree). See `tree.rs`.
- HTML in the markdown document is parsed using html5ever, and then
lives inside the same tree data structure. See `tokenizer.rs`.
- Transformations are then applied to the tree data structure. For
example, adding header links or hiding code lines.
- Serialization is a simple process of writing out the nodes to a
string. See `serialize.rs`.
- The search indexer works on the tree structure instead of re-rendering
every chapter twice. See `html_handlebars/search.rs`.
- The print page now takes a very different approach of taking the
same tree structure built for rendering the chapters, and applies
transformations to it. This avoid re-parsing everything again. See
`print.rs`.
- I changed the linking behavior so that links on the print page
link to items on the print page instead of outside the print page.
- There are a variety of small changes to how it serializes as can be
seen in the changes to the tests. Some highlights:
- Code blocks no longer have a second layer of `<pre>` tags wrapping
it.
- Fixed a minor issue where a rust code block with a specific
edition was having the wrong classes when there was a default
edition.
- Drops the ammonia dependency, which significantly reduces the number
of dependencies. It was only being used for a very minor task, and
we can handle it much more easily now.
- Drops `pretty_assertions`, they are no longer used (mostly being
migrated to the testsuite).
There's obviously a lot of risk trying to parse everything to such a low
level, but I think the benefits are worth it. Also, the API isn't super
ergonomic compared to say javascript (there are no selectors), but it
works well enough so far.
I have not run this through rigorous benchmarking, but it does have a
very noticeable performance improvement, especially in a debug build.
I expect in the future that we'll want to expose some kind of
integration with extensions so they have access to this tree structure
(or some kind of tree structure).
Closes https://github.com/rust-lang/mdBook/issues/1736
2025-09-16 20:14:00 -07:00
< pre class = " playground " > < code class = " language-rust editable " > let s = " foo
2025-09-16 14:07:54 -07:00
< span class = " boring " > bar
< / span > < span class = " boring " >
Add a new HTML rendering pipeline
This rewrites the HTML rendering pipeline to use a tree data structure,
and implements a custom HTML serializer. The intent is to make it easier
to make changes and to manipulate the output. This should make some
future changes much easier.
This is a large change, but I'll try to briefly summarize what's
changing:
- All of the HTML rendering support has been moved out of
mdbook-markdown into mdbook-html. For now, all of the API surface is
private, though we may consider ways to safely expose it in the
future.
- Instead of using pulldown-cmark's html serializer, this takes the
pulldown-cmark events and translates them into a tree data structure
(using the ego-tree crate to define the tree). See `tree.rs`.
- HTML in the markdown document is parsed using html5ever, and then
lives inside the same tree data structure. See `tokenizer.rs`.
- Transformations are then applied to the tree data structure. For
example, adding header links or hiding code lines.
- Serialization is a simple process of writing out the nodes to a
string. See `serialize.rs`.
- The search indexer works on the tree structure instead of re-rendering
every chapter twice. See `html_handlebars/search.rs`.
- The print page now takes a very different approach of taking the
same tree structure built for rendering the chapters, and applies
transformations to it. This avoid re-parsing everything again. See
`print.rs`.
- I changed the linking behavior so that links on the print page
link to items on the print page instead of outside the print page.
- There are a variety of small changes to how it serializes as can be
seen in the changes to the tests. Some highlights:
- Code blocks no longer have a second layer of `<pre>` tags wrapping
it.
- Fixed a minor issue where a rust code block with a specific
edition was having the wrong classes when there was a default
edition.
- Drops the ammonia dependency, which significantly reduces the number
of dependencies. It was only being used for a very minor task, and
we can handle it much more easily now.
- Drops `pretty_assertions`, they are no longer used (mostly being
migrated to the testsuite).
There's obviously a lot of risk trying to parse everything to such a low
level, but I think the benefits are worth it. Also, the API isn't super
ergonomic compared to say javascript (there are no selectors), but it
works well enough so far.
I have not run this through rigorous benchmarking, but it does have a
very noticeable performance improvement, especially in a debug build.
I expect in the future that we'll want to expose some kind of
integration with extensions so they have access to this tree structure
(or some kind of tree structure).
Closes https://github.com/rust-lang/mdBook/issues/1736
2025-09-16 20:14:00 -07:00
< / span > " ;</code></pre>
2025-09-16 14:07:54 -07:00
" #]],
) ;
// `#` must be followed by a space to be boring.
expect (
" #x; " ,
" " ,
str ! [ [ r #"
Add a new HTML rendering pipeline
This rewrites the HTML rendering pipeline to use a tree data structure,
and implements a custom HTML serializer. The intent is to make it easier
to make changes and to manipulate the output. This should make some
future changes much easier.
This is a large change, but I'll try to briefly summarize what's
changing:
- All of the HTML rendering support has been moved out of
mdbook-markdown into mdbook-html. For now, all of the API surface is
private, though we may consider ways to safely expose it in the
future.
- Instead of using pulldown-cmark's html serializer, this takes the
pulldown-cmark events and translates them into a tree data structure
(using the ego-tree crate to define the tree). See `tree.rs`.
- HTML in the markdown document is parsed using html5ever, and then
lives inside the same tree data structure. See `tokenizer.rs`.
- Transformations are then applied to the tree data structure. For
example, adding header links or hiding code lines.
- Serialization is a simple process of writing out the nodes to a
string. See `serialize.rs`.
- The search indexer works on the tree structure instead of re-rendering
every chapter twice. See `html_handlebars/search.rs`.
- The print page now takes a very different approach of taking the
same tree structure built for rendering the chapters, and applies
transformations to it. This avoid re-parsing everything again. See
`print.rs`.
- I changed the linking behavior so that links on the print page
link to items on the print page instead of outside the print page.
- There are a variety of small changes to how it serializes as can be
seen in the changes to the tests. Some highlights:
- Code blocks no longer have a second layer of `<pre>` tags wrapping
it.
- Fixed a minor issue where a rust code block with a specific
edition was having the wrong classes when there was a default
edition.
- Drops the ammonia dependency, which significantly reduces the number
of dependencies. It was only being used for a very minor task, and
we can handle it much more easily now.
- Drops `pretty_assertions`, they are no longer used (mostly being
migrated to the testsuite).
There's obviously a lot of risk trying to parse everything to such a low
level, but I think the benefits are worth it. Also, the API isn't super
ergonomic compared to say javascript (there are no selectors), but it
works well enough so far.
I have not run this through rigorous benchmarking, but it does have a
very noticeable performance improvement, especially in a debug build.
I expect in the future that we'll want to expose some kind of
integration with extensions so they have access to this tree structure
(or some kind of tree structure).
Closes https://github.com/rust-lang/mdBook/issues/1736
2025-09-16 20:14:00 -07:00
< pre class = " playground " > < code class = " language-rust " > < span class = " boring " > #![ allow(unused) ]
2025-09-16 14:07:54 -07:00
< / span > < span class = " boring " > fn main ( ) {
< / span > #x ;
Add a new HTML rendering pipeline
This rewrites the HTML rendering pipeline to use a tree data structure,
and implements a custom HTML serializer. The intent is to make it easier
to make changes and to manipulate the output. This should make some
future changes much easier.
This is a large change, but I'll try to briefly summarize what's
changing:
- All of the HTML rendering support has been moved out of
mdbook-markdown into mdbook-html. For now, all of the API surface is
private, though we may consider ways to safely expose it in the
future.
- Instead of using pulldown-cmark's html serializer, this takes the
pulldown-cmark events and translates them into a tree data structure
(using the ego-tree crate to define the tree). See `tree.rs`.
- HTML in the markdown document is parsed using html5ever, and then
lives inside the same tree data structure. See `tokenizer.rs`.
- Transformations are then applied to the tree data structure. For
example, adding header links or hiding code lines.
- Serialization is a simple process of writing out the nodes to a
string. See `serialize.rs`.
- The search indexer works on the tree structure instead of re-rendering
every chapter twice. See `html_handlebars/search.rs`.
- The print page now takes a very different approach of taking the
same tree structure built for rendering the chapters, and applies
transformations to it. This avoid re-parsing everything again. See
`print.rs`.
- I changed the linking behavior so that links on the print page
link to items on the print page instead of outside the print page.
- There are a variety of small changes to how it serializes as can be
seen in the changes to the tests. Some highlights:
- Code blocks no longer have a second layer of `<pre>` tags wrapping
it.
- Fixed a minor issue where a rust code block with a specific
edition was having the wrong classes when there was a default
edition.
- Drops the ammonia dependency, which significantly reduces the number
of dependencies. It was only being used for a very minor task, and
we can handle it much more easily now.
- Drops `pretty_assertions`, they are no longer used (mostly being
migrated to the testsuite).
There's obviously a lot of risk trying to parse everything to such a low
level, but I think the benefits are worth it. Also, the API isn't super
ergonomic compared to say javascript (there are no selectors), but it
works well enough so far.
I have not run this through rigorous benchmarking, but it does have a
very noticeable performance improvement, especially in a debug build.
I expect in the future that we'll want to expose some kind of
integration with extensions so they have access to this tree structure
(or some kind of tree structure).
Closes https://github.com/rust-lang/mdBook/issues/1736
2025-09-16 20:14:00 -07:00
< span class = " boring " > } < / span > < / code > < / pre >
2025-09-16 14:07:54 -07:00
" #]],
) ;
// Other classes like "ignore" should not change things, and the class is
// included in the code tag.
expect (
" let s = \" foo \n # bar \n \" ; " ,
" ignore " ,
str ! [ [ r #"
< pre > < code class = " language-rust ignore " > let s = " foo
< span class = " boring " > bar
< / span > " ;</code></pre>
" #]],
) ;
// Inner attributes and normal attributes are not boring.
expect (
" #![no_std] \n let s = \" foo \" ; \n #[some_attr] " ,
" editable " ,
str ! [ [ r #"
Add a new HTML rendering pipeline
This rewrites the HTML rendering pipeline to use a tree data structure,
and implements a custom HTML serializer. The intent is to make it easier
to make changes and to manipulate the output. This should make some
future changes much easier.
This is a large change, but I'll try to briefly summarize what's
changing:
- All of the HTML rendering support has been moved out of
mdbook-markdown into mdbook-html. For now, all of the API surface is
private, though we may consider ways to safely expose it in the
future.
- Instead of using pulldown-cmark's html serializer, this takes the
pulldown-cmark events and translates them into a tree data structure
(using the ego-tree crate to define the tree). See `tree.rs`.
- HTML in the markdown document is parsed using html5ever, and then
lives inside the same tree data structure. See `tokenizer.rs`.
- Transformations are then applied to the tree data structure. For
example, adding header links or hiding code lines.
- Serialization is a simple process of writing out the nodes to a
string. See `serialize.rs`.
- The search indexer works on the tree structure instead of re-rendering
every chapter twice. See `html_handlebars/search.rs`.
- The print page now takes a very different approach of taking the
same tree structure built for rendering the chapters, and applies
transformations to it. This avoid re-parsing everything again. See
`print.rs`.
- I changed the linking behavior so that links on the print page
link to items on the print page instead of outside the print page.
- There are a variety of small changes to how it serializes as can be
seen in the changes to the tests. Some highlights:
- Code blocks no longer have a second layer of `<pre>` tags wrapping
it.
- Fixed a minor issue where a rust code block with a specific
edition was having the wrong classes when there was a default
edition.
- Drops the ammonia dependency, which significantly reduces the number
of dependencies. It was only being used for a very minor task, and
we can handle it much more easily now.
- Drops `pretty_assertions`, they are no longer used (mostly being
migrated to the testsuite).
There's obviously a lot of risk trying to parse everything to such a low
level, but I think the benefits are worth it. Also, the API isn't super
ergonomic compared to say javascript (there are no selectors), but it
works well enough so far.
I have not run this through rigorous benchmarking, but it does have a
very noticeable performance improvement, especially in a debug build.
I expect in the future that we'll want to expose some kind of
integration with extensions so they have access to this tree structure
(or some kind of tree structure).
Closes https://github.com/rust-lang/mdBook/issues/1736
2025-09-16 20:14:00 -07:00
< pre class = " playground " > < code class = " language-rust editable " > #![ no_std ]
2025-09-16 14:07:54 -07:00
let s = " foo " ;
Add a new HTML rendering pipeline
This rewrites the HTML rendering pipeline to use a tree data structure,
and implements a custom HTML serializer. The intent is to make it easier
to make changes and to manipulate the output. This should make some
future changes much easier.
This is a large change, but I'll try to briefly summarize what's
changing:
- All of the HTML rendering support has been moved out of
mdbook-markdown into mdbook-html. For now, all of the API surface is
private, though we may consider ways to safely expose it in the
future.
- Instead of using pulldown-cmark's html serializer, this takes the
pulldown-cmark events and translates them into a tree data structure
(using the ego-tree crate to define the tree). See `tree.rs`.
- HTML in the markdown document is parsed using html5ever, and then
lives inside the same tree data structure. See `tokenizer.rs`.
- Transformations are then applied to the tree data structure. For
example, adding header links or hiding code lines.
- Serialization is a simple process of writing out the nodes to a
string. See `serialize.rs`.
- The search indexer works on the tree structure instead of re-rendering
every chapter twice. See `html_handlebars/search.rs`.
- The print page now takes a very different approach of taking the
same tree structure built for rendering the chapters, and applies
transformations to it. This avoid re-parsing everything again. See
`print.rs`.
- I changed the linking behavior so that links on the print page
link to items on the print page instead of outside the print page.
- There are a variety of small changes to how it serializes as can be
seen in the changes to the tests. Some highlights:
- Code blocks no longer have a second layer of `<pre>` tags wrapping
it.
- Fixed a minor issue where a rust code block with a specific
edition was having the wrong classes when there was a default
edition.
- Drops the ammonia dependency, which significantly reduces the number
of dependencies. It was only being used for a very minor task, and
we can handle it much more easily now.
- Drops `pretty_assertions`, they are no longer used (mostly being
migrated to the testsuite).
There's obviously a lot of risk trying to parse everything to such a low
level, but I think the benefits are worth it. Also, the API isn't super
ergonomic compared to say javascript (there are no selectors), but it
works well enough so far.
I have not run this through rigorous benchmarking, but it does have a
very noticeable performance improvement, especially in a debug build.
I expect in the future that we'll want to expose some kind of
integration with extensions so they have access to this tree structure
(or some kind of tree structure).
Closes https://github.com/rust-lang/mdBook/issues/1736
2025-09-16 20:14:00 -07:00
#[ some_attr ] < / code > < / pre >
2025-09-16 14:07:54 -07:00
" #]],
) ;
}
// Rust code block in a list.
#[ test ]
fn code_block_in_list ( ) {
BookTest ::init ( | _ | { } )
. change_file (
" src/chapter_1.md " ,
r #" - inside list
` ` ` rust
fn foo ( ) {
let x = 1 ;
}
` ` `
" #,
)
. check_main_file (
" book/chapter_1.html " ,
str ! [ [ r #"
< ul >
< li >
< p > inside list < / p >
Add a new HTML rendering pipeline
This rewrites the HTML rendering pipeline to use a tree data structure,
and implements a custom HTML serializer. The intent is to make it easier
to make changes and to manipulate the output. This should make some
future changes much easier.
This is a large change, but I'll try to briefly summarize what's
changing:
- All of the HTML rendering support has been moved out of
mdbook-markdown into mdbook-html. For now, all of the API surface is
private, though we may consider ways to safely expose it in the
future.
- Instead of using pulldown-cmark's html serializer, this takes the
pulldown-cmark events and translates them into a tree data structure
(using the ego-tree crate to define the tree). See `tree.rs`.
- HTML in the markdown document is parsed using html5ever, and then
lives inside the same tree data structure. See `tokenizer.rs`.
- Transformations are then applied to the tree data structure. For
example, adding header links or hiding code lines.
- Serialization is a simple process of writing out the nodes to a
string. See `serialize.rs`.
- The search indexer works on the tree structure instead of re-rendering
every chapter twice. See `html_handlebars/search.rs`.
- The print page now takes a very different approach of taking the
same tree structure built for rendering the chapters, and applies
transformations to it. This avoid re-parsing everything again. See
`print.rs`.
- I changed the linking behavior so that links on the print page
link to items on the print page instead of outside the print page.
- There are a variety of small changes to how it serializes as can be
seen in the changes to the tests. Some highlights:
- Code blocks no longer have a second layer of `<pre>` tags wrapping
it.
- Fixed a minor issue where a rust code block with a specific
edition was having the wrong classes when there was a default
edition.
- Drops the ammonia dependency, which significantly reduces the number
of dependencies. It was only being used for a very minor task, and
we can handle it much more easily now.
- Drops `pretty_assertions`, they are no longer used (mostly being
migrated to the testsuite).
There's obviously a lot of risk trying to parse everything to such a low
level, but I think the benefits are worth it. Also, the API isn't super
ergonomic compared to say javascript (there are no selectors), but it
works well enough so far.
I have not run this through rigorous benchmarking, but it does have a
very noticeable performance improvement, especially in a debug build.
I expect in the future that we'll want to expose some kind of
integration with extensions so they have access to this tree structure
(or some kind of tree structure).
Closes https://github.com/rust-lang/mdBook/issues/1736
2025-09-16 20:14:00 -07:00
< pre class = " playground " > < code class = " language-rust " > < span class = " boring " > #![ allow(unused) ]
2025-09-16 14:07:54 -07:00
< / span > < span class = " boring " > fn main ( ) {
< / span > fn foo ( ) {
let x = 1 ;
}
Add a new HTML rendering pipeline
This rewrites the HTML rendering pipeline to use a tree data structure,
and implements a custom HTML serializer. The intent is to make it easier
to make changes and to manipulate the output. This should make some
future changes much easier.
This is a large change, but I'll try to briefly summarize what's
changing:
- All of the HTML rendering support has been moved out of
mdbook-markdown into mdbook-html. For now, all of the API surface is
private, though we may consider ways to safely expose it in the
future.
- Instead of using pulldown-cmark's html serializer, this takes the
pulldown-cmark events and translates them into a tree data structure
(using the ego-tree crate to define the tree). See `tree.rs`.
- HTML in the markdown document is parsed using html5ever, and then
lives inside the same tree data structure. See `tokenizer.rs`.
- Transformations are then applied to the tree data structure. For
example, adding header links or hiding code lines.
- Serialization is a simple process of writing out the nodes to a
string. See `serialize.rs`.
- The search indexer works on the tree structure instead of re-rendering
every chapter twice. See `html_handlebars/search.rs`.
- The print page now takes a very different approach of taking the
same tree structure built for rendering the chapters, and applies
transformations to it. This avoid re-parsing everything again. See
`print.rs`.
- I changed the linking behavior so that links on the print page
link to items on the print page instead of outside the print page.
- There are a variety of small changes to how it serializes as can be
seen in the changes to the tests. Some highlights:
- Code blocks no longer have a second layer of `<pre>` tags wrapping
it.
- Fixed a minor issue where a rust code block with a specific
edition was having the wrong classes when there was a default
edition.
- Drops the ammonia dependency, which significantly reduces the number
of dependencies. It was only being used for a very minor task, and
we can handle it much more easily now.
- Drops `pretty_assertions`, they are no longer used (mostly being
migrated to the testsuite).
There's obviously a lot of risk trying to parse everything to such a low
level, but I think the benefits are worth it. Also, the API isn't super
ergonomic compared to say javascript (there are no selectors), but it
works well enough so far.
I have not run this through rigorous benchmarking, but it does have a
very noticeable performance improvement, especially in a debug build.
I expect in the future that we'll want to expose some kind of
integration with extensions so they have access to this tree structure
(or some kind of tree structure).
Closes https://github.com/rust-lang/mdBook/issues/1736
2025-09-16 20:14:00 -07:00
< span class = " boring " > } < / span > < / code > < / pre >
2025-09-16 14:07:54 -07:00
< / li >
< / ul >
" #]],
) ;
}
// Checks the rendering of links added to headers.
#[ test ]
fn header_links ( ) {
BookTest ::from_dir ( " rendering/header_links " ) . check_all_main_files ( ) ;
}
// A corrupted HTML end tag.
#[ test ]
fn busted_end_tag ( ) {
BookTest ::init ( | _ | { } )
. change_file ( " src/chapter_1.md " , " <div>x<span>foo</span/>y</div> " )
. run ( " build " , | cmd | {
cmd . expect_stderr ( str ! [ [ r #"
INFO Book building has started
INFO Running the html backend
Add a new HTML rendering pipeline
This rewrites the HTML rendering pipeline to use a tree data structure,
and implements a custom HTML serializer. The intent is to make it easier
to make changes and to manipulate the output. This should make some
future changes much easier.
This is a large change, but I'll try to briefly summarize what's
changing:
- All of the HTML rendering support has been moved out of
mdbook-markdown into mdbook-html. For now, all of the API surface is
private, though we may consider ways to safely expose it in the
future.
- Instead of using pulldown-cmark's html serializer, this takes the
pulldown-cmark events and translates them into a tree data structure
(using the ego-tree crate to define the tree). See `tree.rs`.
- HTML in the markdown document is parsed using html5ever, and then
lives inside the same tree data structure. See `tokenizer.rs`.
- Transformations are then applied to the tree data structure. For
example, adding header links or hiding code lines.
- Serialization is a simple process of writing out the nodes to a
string. See `serialize.rs`.
- The search indexer works on the tree structure instead of re-rendering
every chapter twice. See `html_handlebars/search.rs`.
- The print page now takes a very different approach of taking the
same tree structure built for rendering the chapters, and applies
transformations to it. This avoid re-parsing everything again. See
`print.rs`.
- I changed the linking behavior so that links on the print page
link to items on the print page instead of outside the print page.
- There are a variety of small changes to how it serializes as can be
seen in the changes to the tests. Some highlights:
- Code blocks no longer have a second layer of `<pre>` tags wrapping
it.
- Fixed a minor issue where a rust code block with a specific
edition was having the wrong classes when there was a default
edition.
- Drops the ammonia dependency, which significantly reduces the number
of dependencies. It was only being used for a very minor task, and
we can handle it much more easily now.
- Drops `pretty_assertions`, they are no longer used (mostly being
migrated to the testsuite).
There's obviously a lot of risk trying to parse everything to such a low
level, but I think the benefits are worth it. Also, the API isn't super
ergonomic compared to say javascript (there are no selectors), but it
works well enough so far.
I have not run this through rigorous benchmarking, but it does have a
very noticeable performance improvement, especially in a debug build.
I expect in the future that we'll want to expose some kind of
integration with extensions so they have access to this tree structure
(or some kind of tree structure).
Closes https://github.com/rust-lang/mdBook/issues/1736
2025-09-16 20:14:00 -07:00
WARN html parse error in ` chapter_1 . md ` : Self - closing end tag
Html text was :
< div > x < span > foo < / span / > y < / div >
2025-09-16 14:07:54 -07:00
INFO HTML book written to ` [ ROOT ] / book `
" #]]);
} )
Add a new HTML rendering pipeline
This rewrites the HTML rendering pipeline to use a tree data structure,
and implements a custom HTML serializer. The intent is to make it easier
to make changes and to manipulate the output. This should make some
future changes much easier.
This is a large change, but I'll try to briefly summarize what's
changing:
- All of the HTML rendering support has been moved out of
mdbook-markdown into mdbook-html. For now, all of the API surface is
private, though we may consider ways to safely expose it in the
future.
- Instead of using pulldown-cmark's html serializer, this takes the
pulldown-cmark events and translates them into a tree data structure
(using the ego-tree crate to define the tree). See `tree.rs`.
- HTML in the markdown document is parsed using html5ever, and then
lives inside the same tree data structure. See `tokenizer.rs`.
- Transformations are then applied to the tree data structure. For
example, adding header links or hiding code lines.
- Serialization is a simple process of writing out the nodes to a
string. See `serialize.rs`.
- The search indexer works on the tree structure instead of re-rendering
every chapter twice. See `html_handlebars/search.rs`.
- The print page now takes a very different approach of taking the
same tree structure built for rendering the chapters, and applies
transformations to it. This avoid re-parsing everything again. See
`print.rs`.
- I changed the linking behavior so that links on the print page
link to items on the print page instead of outside the print page.
- There are a variety of small changes to how it serializes as can be
seen in the changes to the tests. Some highlights:
- Code blocks no longer have a second layer of `<pre>` tags wrapping
it.
- Fixed a minor issue where a rust code block with a specific
edition was having the wrong classes when there was a default
edition.
- Drops the ammonia dependency, which significantly reduces the number
of dependencies. It was only being used for a very minor task, and
we can handle it much more easily now.
- Drops `pretty_assertions`, they are no longer used (mostly being
migrated to the testsuite).
There's obviously a lot of risk trying to parse everything to such a low
level, but I think the benefits are worth it. Also, the API isn't super
ergonomic compared to say javascript (there are no selectors), but it
works well enough so far.
I have not run this through rigorous benchmarking, but it does have a
very noticeable performance improvement, especially in a debug build.
I expect in the future that we'll want to expose some kind of
integration with extensions so they have access to this tree structure
(or some kind of tree structure).
Closes https://github.com/rust-lang/mdBook/issues/1736
2025-09-16 20:14:00 -07:00
. check_main_file ( " book/chapter_1.html " , str ! [ " <div>x<span>foo</span>y</div> " ] ) ;
2025-09-16 14:07:54 -07:00
}
// Various html blocks.
#[ test ]
fn html_blocks ( ) {
BookTest ::from_dir ( " rendering/html_blocks " ) . check_all_main_files ( ) ;
}
2025-10-27 18:17:22 -07:00
// Test for a fenced code block that is also indented.
#[ test ]
fn code_block_fenced_with_indent ( ) {
BookTest ::from_dir ( " rendering/code_blocks_fenced_with_indent " ) . check_all_main_files ( ) ;
}
2025-11-05 10:45:46 -08:00
// Unclosed HTML tags.
//
// Note that the HTML parsing algorithm is much more complicated than what
// this is checking.
#[ test ]
fn unclosed_html_tags ( ) {
BookTest ::init ( | _ | { } )
. change_file ( " src/chapter_1.md " , " <div>x<span>foo<i>xyz " )
. run ( " build " , | cmd | {
cmd . expect_stderr ( str ! [ [ r #"
INFO Book building has started
INFO Running the html backend
2025-11-05 11:14:39 -08:00
WARN unclosed HTML tag ` < i > ` found in ` chapter_1 . md `
WARN unclosed HTML tag ` < span > ` found in ` chapter_1 . md `
WARN unclosed HTML tag ` < div > ` found in ` chapter_1 . md `
2025-11-05 10:45:46 -08:00
INFO HTML book written to ` [ ROOT ] / book `
" #]]);
} )
. check_main_file (
" book/chapter_1.html " ,
str ! [ " <div>x<span>foo<i>xyz</i></span></div> " ] ,
) ;
}
2025-11-05 11:17:48 -08:00
// Test for HTML tags out of sync.
#[ test ]
fn unbalanced_html_tags ( ) {
BookTest ::init ( | _ | { } )
. change_file ( " src/chapter_1.md " , " <div>x<span>foo</div></span> " )
. run ( " build " , | cmd | {
cmd . expect_stderr ( str ! [ [ r #"
INFO Book building has started
INFO Running the html backend
2025-11-05 11:42:43 -08:00
WARN unexpected HTML end tag ` < / div > ` found in ` chapter_1 . md `
Check that the HTML tags are properly balanced .
2025-11-05 11:17:48 -08:00
WARN unclosed HTML tag ` < div > ` found in ` chapter_1 . md `
INFO HTML book written to ` [ ROOT ] / book `
" #]]);
} )
2025-11-05 11:42:43 -08:00
. check_main_file ( " book/chapter_1.html " , str ! [ " <div>x<span>foo</span></div> " ] ) ;
2025-11-05 11:17:48 -08:00
}
2025-11-06 07:10:48 -08:00
// Test for bug with unbalanced HTML handling in the heading.
#[ test ]
fn heading_with_unbalanced_html ( ) {
BookTest ::init ( | _ | { } )
. change_file ( " src/chapter_1.md " , " ### Option<T> " )
. run ( " build " , | cmd | {
2025-11-06 07:31:45 -08:00
cmd . expect_stderr ( str ! [ [ r #"
2025-11-06 07:10:48 -08:00
INFO Book building has started
INFO Running the html backend
2025-11-06 07:31:45 -08:00
WARN unclosed HTML tag ` < t > ` found in ` chapter_1 . md ` while exiting Heading ( H3 )
HTML tags must be closed before exiting a markdown element .
INFO HTML book written to ` [ ROOT ] / book `
2025-11-06 07:10:48 -08:00
" #]]);
2025-11-06 07:31:45 -08:00
} )
. check_main_file (
" book/chapter_1.html " ,
str ! [ [ r ## "<h3 id="option"><a class="header" href="#option">Option<t></t></a></h3>"## ] ] ,
) ;
2025-11-06 07:10:48 -08:00
}
2026-06-18 23:03:22 +01:00
// The following tests cover the `output.html.site-url` feature, which makes
// every generated link absolute (rooted at `site-url`) so a book served from a
// subdirectory resolves cross-chapter, asset, and sidebar links regardless of
// the page's own depth. See https://github.com/rust-lang/mdBook/pull/1802.
// Root-relative `./` links written in chapter content are anchored to the site
// URL, while links with a scheme (e.g. `https`) are left untouched.
#[ test ]
fn site_url_rewrites_content_links ( ) {
BookTest ::from_dir ( " rendering/site_url " )
. check_file_contains (
" book/nested/deep.html " ,
" <a href= \" https://example.com/docs/other.html \" >other chapter</a> " ,
)
. check_file_contains (
" book/index.html " ,
" <a href= \" https://example.com/docs/nested/deep.html \" >deep chapter</a> " ,
)
. check_file_contains (
" book/index.html " ,
" <a href= \" https://rust-lang.org \" >external link</a> " ,
) ;
}
// `path_to_root` (used by the page chrome, prev/next navigation, and the
// JavaScript sidebar in `toc.js`) becomes the absolute site URL on every page,
// independent of how deeply the page is nested.
#[ test ]
fn site_url_sets_absolute_path_to_root ( ) {
BookTest ::from_dir ( " rendering/site_url " ) . check_file_contains (
" book/nested/deep.html " ,
" const path_to_root = \" https://example.com/docs/ \" ; " ,
) ;
}
// Static assets resolved through the `{{resource}}` helper are emitted with the
// absolute site URL rather than a depth-relative `../` prefix.
#[ test ]
fn site_url_makes_assets_absolute ( ) {
BookTest ::from_dir ( " rendering/site_url " ) . check_file_contains (
" book/nested/deep.html " ,
" <link rel= \" stylesheet \" href= \" https://example.com/docs/css/general " ,
) ;
}
// The no-JS sidebar fallback (`toc.html`, loaded in an iframe) carries a
// `<base href>` of the site URL so its root-relative chapter links resolve
// absolutely.
#[ test ]
fn site_url_sets_toc_html_base ( ) {
BookTest ::from_dir ( " rendering/site_url " )
. check_file_contains ( " book/toc.html " , " <base href= \" https://example.com/docs/ \" > " ) ;
}
// The `<base href>` from `toc.html` must not leak onto regular chapter pages,
// which would break their page-relative content links.
#[ test ]
fn site_url_no_base_href_on_chapter_pages ( ) {
BookTest ::from_dir ( " rendering/site_url " )
. check_file_doesnt_contain ( " book/nested/deep.html " , " <base href " )
. check_file_doesnt_contain ( " book/index.html " , " <base href " ) ;
}
// Without `site-url`, links and assets stay depth-relative and no `<base href>`
// is emitted: the feature is strictly opt-in.
#[ test ]
fn site_url_absent_keeps_links_relative ( ) {
BookTest ::init ( | _ | { } )
. check_file_contains ( " book/index.html " , " const path_to_root = \" \" ; " )
. check_file_doesnt_contain ( " book/index.html " , " <base href " )
. check_file_doesnt_contain ( " book/toc.html " , " <base href " ) ;
}
// The print page roots its chrome, assets and sidebar at the site URL, while
// cross-chapter references between chapters present on the page are folded into
// intra-page anchors so the consolidated page stays self-contained.
#[ test ]
fn site_url_print_page ( ) {
BookTest ::from_dir ( " rendering/site_url " )
. check_file_contains (
" book/print.html " ,
" const path_to_root = \" https://example.com/docs/ \" ; " ,
)
. check_file_contains (
" book/print.html " ,
" <link rel= \" stylesheet \" href= \" https://example.com/docs/css/general " ,
)
. check_file_contains ( " book/print.html " , " <a href= \" #deep \" >deep chapter</a> " )
. check_file_contains ( " book/print.html " , " <a href= \" #other \" >other chapter</a> " )
. check_file_contains (
" book/print.html " ,
" <a href= \" https://rust-lang.org \" >external link</a> " ,
) ;
}