Commit graph

164 commits

Author SHA1 Message Date
Eric Huss
a097fe6232
Merge pull request #2891 from ehuss/divide-by-zero-heading-bug
Avoid divide-by-zero in heading nav computation
2025-10-21 00:52:17 +00:00
Eric Huss
4b5004b621 Avoid divide-by-zero in heading nav computation
This particular value can go to zero when the document height and the
window height are exactly the same value. This causes a NaN which causes
the "current" heading nav bug to not update properly. This clamps the
value to 1 to avoid that.
2025-10-20 17:43:34 -07:00
Eric Huss
5282083dec Fix heading nav with folded chapters
This fixes an issue when folding is enabled. The folding was not
properly hiding the sub-chapters because it was assuming it could hide
the next list element. However, the heading nav was the next list
element, so the remaining chapters remained visible.

The solution required some deeper changes to how the chapters were
organized in the sidebar. Instead of nested chapters being a list
element *sibling*, the nested chapter's `ol` is now a *child* of its
parent chapter. This makes it much easier to just hide everything
without regard of the exact sibling order.

This required wrapping the chapter title and the toggle chevron inside a
span so that the flex layout could be localized to just those elements,
and allow the following `ol` elements to lay out regularly.

Closes https://github.com/rust-lang/mdBook/issues/2880
2025-10-20 17:31:40 -07:00
Eric Huss
1620858032 Improve the heading nav debug
This updates the heading nav debug code with a few changes:

- Now enabled with the `mdbookEnableThresholdDebug` function.
- Adds a table with the relevant internal variables.
2025-10-20 17:05:44 -07:00
Eric Huss
3a2705d742 Remove tabs in chrome.css
This causes awkwardness with some editors which want to replace tabs
with spaces.
2025-10-20 15:41:33 -07:00
Eric Huss
4913bf82f1 Fix incorrect string formatting in xtask error message 2025-10-15 06:57:39 -07:00
Eric Huss
4e41c844c3
Merge pull request #2876 from ehuss/xtask-bump
Add `cargo xtask bump`
2025-09-28 23:21:34 +00:00
Eric Huss
0ae202ea85 Add cargo xtask bump
This is a simple script to assist with bumping the version.
2025-09-28 16:14:41 -07:00
Eric Huss
91842c3db6 Remove partially outdated CmdPreprocessor/CmdRenderer docs
These docs were slightly drifting from the user guide docs. Instead of
trying to maintain multiple copies of this, I have changed it so that
it just links out to the guide.

(The guide docs could be cleaned up a little, but that's a separate
issue.)
2025-09-28 15:22:49 -07:00
Eric Huss
2a93606727 Add a script to help update the changelog
This adds `cargo xtask changelog` to automatically add a new changelog
entry for a release.
2025-09-28 09:13:16 -07:00
Eric Huss
2c7d192b50 Add an xtask to help with running tests
During development I often need to run a bunch of tests. Instead of
having some unwieldy shell command, I have added this xtask to help with
running the testing commands.
2025-09-26 18:55:21 -07:00
Eric Huss
7fcacf3386 Move theme copy to the Theme type and reduce visibility
This moves the code for copying the theme to the theme directory to the
Theme type so that the code lives closer to the data definition. This
also then reduces the public API surface of the Theme to give a little
more flexibility for updating it in the future.
2025-09-20 17:55:12 -07:00
Eric Huss
797112ef36 Clean up some fs-related utilities
This does a little cleanup around the usage of filesystem functions:

- Add `mdbook_core::utils::fs::read_to_string` as a wrapper around
  `std::fs::read_to_string` to provide better error messages. Use
  this wherever a file is read.
- Add `mdbook_core::utils::fs::create_dir_all` as a wrapper around
  `std::fs::create_dir_all` to provide better error messages. Use
  this wherever a file is read.
- Replace `mdbook_core::utils::fs::write_file` with `write` to mirror
  the `std::fs::write` API.
- Remove `mdbook_core::utils::fs::create_file`. It was generally not
  used anymore.
- Scrub the usage of `std::fs` to use the new wrappers. This doesn't
  remove it 100%, but it is now significantly reduced.
2025-09-20 17:13:31 -07:00
Eric Huss
f24221a1d7
Merge pull request #2855 from ehuss/move-get_404_output_file
Move get_404_output_file to HtmlConfig
2025-09-20 01:18:12 +00:00
Eric Huss
6223189b95 Move get_404_output_file to HtmlConfig
This function was essentially only operating on data from HtmlConfig. It
wasn't really a "filesystem" function. So this moves it to be more
logically associated with the data it works on.
2025-09-19 18:11:29 -07:00
Eric Huss
09c3e542da Move take_lines functions to mdbook-driver and make private
These functions are only used by the links preprocessor. I'm moving
these functions to put them closer to the code that they are associated
with, and to reduce the public API surface.
2025-09-19 18:01:33 -07:00
Eric Huss
8159dea9ea Remove outdated comment in mdbook-markdown
I missed this in https://github.com/rust-lang/mdBook/pull/2844.
2025-09-19 17:46:08 -07:00
Eric Huss
873e4fe40f Add support for admonitions
This enables the admonitions support from pulldown-cmark. This includes
a config option in case it causes problems with existing books.

I would like to make this extensible in the future, though I'm not sure
what that would look like. There's also some concerns with how this will
affect translations like mdbook-i18n-helpers, which we may need to work
out in a different way.

Closes https://github.com/rust-lang/mdBook/issues/2771
2025-09-18 19:54:20 -07:00
Eric Huss
ddeb3ce54f Fix missing css vars for no-js dark mode
These various were inadvertently missing from the no-js dark mode.
2025-09-18 18:53:46 -07:00
Eric Huss
ba4c3ed873 Add support for definition lists
This enables the definition lists support from pulldown-cmark.
This includes a config option in case it causes problems with existing
books.

Closes https://github.com/rust-lang/mdBook/issues/2770
2025-09-17 16:44:45 -07:00
Eric Huss
53d39a8654
Merge pull request #2846 from ehuss/fix-unique-id-loop
Fix ID collisions when the numeric suffix gets used
2025-09-17 21:42:08 +00:00
Eric Huss
f1731329e1 Fix ID collisions when the numeric suffix gets used
This fixes a collision with the ID generation where it a previous entry
could generate a unique ID like "foo-1", but then a header with the text
"Foo 1" would collide with it. This fixes it so that when generating the
ID for "Foo 1", it will loop unit it finds an ID that doesn't collide
(in this case, `foo-1-1`).
2025-09-17 14:36:16 -07:00
Eric Huss
d27a2bdd1d Fix raw status ending in the HTML tokenizer
This fixes a small mistake where the "raw" status wasn't being reset
once exiting the script or style tags. That means any text nodes that
followed would be misinterpreted as being raw.
2025-09-17 14:21:01 -07:00
Eric Huss
2b242494b0 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:26:35 -07:00
Eric Huss
21e8c08827 Add a basic utility to compare different versions of mdbook
This is a very simplistic utility to compare the output of different
versions of mdbook. This is useful when making changes to compare
real-world books to see what changes actually happen.

This is a variation of scripts that I have been using for a few years.
This could definitely use some improvements, but this seems like it
could be useful as-is.
2025-09-16 13:58:20 -07:00
Eric Huss
737090abf1 Fix broken a tag
This fixes the missing close `</a>` tag for the "previous" button.
2025-09-15 20:17:11 -07:00
Eric Huss
c606a010c7 Rewrite partition_source to return slices
This changes partition_source so that instead of allocating new strings,
it just returns slices into the original string. It probably doesn't
make a big difference perf-wise, but I felt more comfortable with this,
and also felt it was a little easier to understand exactly what it was
doing.

This is generally equivalent except for the possibility of not having a
newline at the end. In practice that doesn't matter because markdown
code blocks always have a newline. However, to be defensive, the caller
will check for this.
2025-09-15 18:42:43 -07:00
Eric Huss
09f05e8a86 Add a test for partition_source 2025-09-15 18:08:25 -07:00
Eric Huss
1daa650d61
Merge pull request #2839 from ehuss/to_url_path
Add ToUrlPath helper trait
2025-09-15 14:50:47 +00:00
Eric Huss
2474ae799b Add ToUrlPath helper trait
This adds the `ToUrlPath` helper trait to convert a Path to a path
suitable for use in HTML (replacing `normalize_path`).

This also fixes a minor bug where on Windows the next/prev links were
using a double forward slash. I don't think this is possible, since
chapter links are derived from the summary, but I'm noting just in case.
It's also not too much of an issue since double slashes are normally
just treated as a single.
2025-09-15 07:44:10 -07:00
Eric Huss
3629e2c051 Add an iterator over chapters
This adds the `Book::chapters` iterator (and `for_each_chapter_mut`) to
iterate over non-draft chapters. This is a common pattern I keep
encountering, and I figure it might simplify things. It runs a little
risk that callers may not be properly handling every item type, but I
think it should be ok.
2025-09-15 07:11:19 -07:00
Eric Huss
e3bb655663 Add a helper for defining a regex
This adds the `static_regex` macro to help with defining a regex.
2025-09-12 06:48:50 -07:00
Eric Huss
3e673ce424 Switch from log to tracing
This switches to using the tracing crate instead of log. Tracing
provides a lot of nice features which we can take advantage of moving
forward.

This also adjusts the output fairly significantly. This includes:

- Switched the environment variable from RUST_LOG to MDBOOK_LOG.
- Dropped the timestamp. I experimented with various different time
  displays, but ultimately decided to omit it for now. I don't think
  I've ever found it to be useful, and it takes up a very significant
  amount of space. It could potentially be useful for basic profiling,
  but I think there are other, better mechanisms for that. We could
  consider leveraging tracing itself for doing some basic profiling
  (like using something like tracing-chrome).
- Dropped the target unless MDBOOK_LOG is set. The target tends to be
  pretty noisy, and doesn't really convey much information unless you
  are debugging or otherwise trying to adjust the log output.
- Added color.
- Slightly reworked the way the error cause trace is displayed.
- Slightly changed the way html5ever filtering is done, as well as add
  handlebars to the list since they both are very noisy. You can
  override this now by explicitly listing them as targets.

I still expect that mdbook will eventually change how it displays things
to the console, possibly switching away from tracing and printing things
itself. However, that is a larger project for the future.
2025-09-12 06:13:45 -07:00
Eric Huss
30d3aeb691 Remove non_exhaustive from Book
This removes the `non_exhaustive` attribute from the `Book` and its
inner types `BookItem` and `Chapter`. These were added in
https://github.com/rust-lang/mdBook/pull/2779. After thinking about it
more, I realized that these types cannot be extended in a
semver-compatible way, so I am fine with allowing them be exhaustive.

The problem is that with CmdPreprocessor, the `Book` will be
re-serialized by a preprocessor, which could potentially be on an older
version. Attempting to add any new fields/variants means that either the
deserialization will fail, or the new fields will be stripped by the
preprocessor.

These could potentially be structured such that they have a
`serde(flatten)` or Other/Unknown variant so that a preprocessor would
at least see the extra fields/variants and pass them along back to the
output. However, a preprocessor or renderer wouldn't know what to do
with those new fields/variants (particularly `BookItem`) which would
itself be a problem. It's still possible to do something like this in
the future, but for now I think it's fine to restrict these to
semver-major changes.
2025-08-29 18:24:44 -07:00
Eric Huss
1b55d4a389 Add sidebar heading navigation
This adds dynamic navigation of headers of the current page in the
sidebar. This is intended to help the user see what is on the current
page, and to be able to more easily navigate it. The "current" header is
tracked based on the scrolling behavior of the user, and is marked with
a small circle. This includes automatic folding to help keep it from
being too unwieldy on a page with a lot of nested headers.

This includes the `output.html.sidebar-header-nav` option to disable it.

I'm sure there are tweaks, fixes, and improvements that can be made. I'd
like to get this out now, and iterate on it over time to make
improvements.
2025-08-27 14:44:12 -07:00
Eric Huss
6f3fac763c Enable hash-files by default
This enables the hash-files setting by default. We have been running it
for a while, and it seems most of the issues have been resolved. This
should help with more reliably loading content like the toc contents.
2025-08-26 16:25:49 -07:00
Eric Huss
3e421d353d Lint HBS JS templates
This updates eslint to lint on the toc.js.hbs file. This file uses a
small amount of hbs templating which eslint can't handle. This adds a
hacky preprocessor which will strips out the handlebars tags so that the
file can be linted.
2025-08-25 15:15:47 -07:00
Eric Huss
189eea5beb Update eslint to 9.34.0
This requires a switch to the configuration file format described at
https://eslint.org/docs/latest/use/configure/configuration-files. I used
the automatic tool to generate the new file, with some simplifications
around defaults.

- Removed no-cond-assign override, it is no longer needed.
- Fixed `catch (e)` where `e` is not used. This seems a little pedantic
  to me, but seems like a relatively easy fix to just remove it, and I
  believe the syntax without the variable has been supported for quite
  some time. Alternatively it could also be `_e`, or explicitly allowed.
- Added `--no-warn-ignored` to the script since it was very noisy.
2025-08-25 14:29:00 -07:00
Gabor Szabo
aced9f609c test case: verify the more specific exception message 2025-08-24 11:18:57 +03:00
Eric Huss
800fb54aeb Rename Book.sections to Book.items
This renames the "sections" list to "items". In practice, this list has
contained more than just "sections" since parts were added. Also, the
rest of the code consistently uses the term "items", since the values it
contains are called `BookItem`s. Finally, the naming has always been a
little confusing to me.

This is a very disruptive change, and I'm not doing it lightly. However,
since there are a number of other API changes going into 0.5, I think
now is an ok time to change this.
2025-08-22 18:51:04 -07:00
Eric Huss
45e700db00
Merge pull request #2811 from ehuss/core-book-tests
Fix mdbook-core book tests
2025-08-23 00:11:25 +00:00
Eric Huss
24c7ffcd62 Fix mdbook-core book tests
These tests were moved in https://github.com/rust-lang/mdBook/pull/2766,
but the `mod tests` was missing. This fixes this missing `mod`, and
updates the tests so that they pass.
2025-08-22 17:04:21 -07:00
Eric Huss
b8ad85c16f Enable smart-punctuation by default
This enables the smart-punctuation setting by default. The long term
plan is to continue to enable more markdown extensions by default across
semver breaking releases.
2025-08-22 16:52:08 -07:00
Eric Huss
f4012757a7 Introduce options struct for markdown rendering
This adds `MarkdownOptions` for creating the pulldown-cmark parser, and
`HtmlRenderOptions` for converting markdown to HTML. These types should
help make it easier to extend the rendering options while remaining
semver compatible. It should also help with just general ergonomics of
using these functions.
2025-08-22 16:17:41 -07:00
Eric Huss
402d11414c Change all HTML IDs to have a prefix
This changes all HTML IDs so that they have the `mdbook-` prefix. This
should help avoid ID conflicts between internal IDs and IDs from user
content such as section headers.

This is a relatively disruptive change and has a high risk of breaking
something. However, I think I have covered everything, and if anything
is missed, hopefully it will get detected.

I did not change class names since the chance of a collision is much
smaller than with IDs. However, that is something that could be
considered in the future.

Closes https://github.com/rust-lang/mdBook/issues/880
2025-08-19 19:38:22 -07:00
Eric Huss
988ed9b5bc
Merge pull request #2807 from ehuss/footnotes-in-a-row
Test and add a fix for multiple footnotes in a row
2025-08-19 00:18:40 +00:00
Eric Huss
4a47b3d18a Add space between consecutive footnotes
This fixes it so that consecutive footnotes have a little space between
them so they aren't jammed together.
2025-08-18 17:11:18 -07:00
Eric Huss
c177081104 Change CLI dest-dir to be relative to the current directory
This changes the `--dest-dir` flag so that it is relative to the current
directory, not the book root. This has been a source of confusion for
several people.

Fixes https://github.com/rust-lang/mdBook/issues/698
2025-08-18 16:28:08 -07:00
Eric Huss
6746df7ce9 Add tests for preprocessor/output default sort order 2025-08-18 11:59:15 -07:00
Hollow Man
a0a01ecd60 Keep preprocessors/backends execution order deterministic
There's a regression caused by recent refactor work, as it used to execute preprocessors/backends in a deterministic way, but now this is not the case, which causes trouble when some backends implicitly depend on the result from another backend and happen to work (e.g. mdbook-pdf). The root cause is that a HashMap has no order, so this PR switches this into `BTreeMap` instead.

Signed-off-by: Hollow Man <hollowman@opensuse.org>
2025-08-18 11:58:23 -07:00