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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions crates/mdbook-core/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,12 @@ pub struct HtmlConfig {
/// If enabled, the sidebar includes navigation for headers on the current
/// page. Default is `true`.
pub sidebar_header_nav: bool,
/// File extensions to exclude when copying files from the source directory.
/// These files will not be copied to the output directory.
/// By default, only `.md` files are excluded.
/// Example: `["md", "rs", "toml"]`
#[serde(rename = "copy-exclude-extensions")]
pub copy_exclude_extensions: Vec<String>,
}

impl Default for HtmlConfig {
Expand Down Expand Up @@ -548,6 +554,7 @@ impl Default for HtmlConfig {
redirect: HashMap::new(),
hash_files: true,
sidebar_header_nav: true,
copy_exclude_extensions: Vec::new(),
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion crates/mdbook-html/src/html_handlebars/hbs_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,12 @@ impl Renderer for HtmlHandlebars {
.context("Unable to emit redirects")?;

// Copy all remaining files, avoid a recursive copy from/to the book build dir
fs::copy_files_except_ext(&src_dir, destination, true, Some(&build_dir), &["md"])?;
let exclude_exts: Vec<&str> = html_config
.copy_exclude_extensions
.iter()
.map(|s| s.as_str())
.collect();
fs::copy_files_except_ext(&src_dir, destination, true, Some(&build_dir), &exclude_exts)?;

info!("HTML book written to `{}`", destination.display());

Expand Down
21 changes: 19 additions & 2 deletions guide/src/cli/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,24 @@ book. Relative paths are interpreted relative to the current directory. If
not specified it will default to the value of the `build.build-dir` key in
`book.toml`, or to `./book`.

#### `--copy-exclude-extensions`

The `--copy-exclude-extensions` option allows you to exclude specific file extensions
when copying files from the source directory to the build directory. This is useful when
your source directory contains symlinks to other directories with files you don't want to
include in the output.

Provide a comma-separated list of extensions (without dots):

```bash
mdbook build --copy-exclude-extensions rs,toml,lock
```

This supplements any extensions configured in `book.toml` via the
`output.html.copy-exclude-extensions` setting.

-------------------

***Note:*** *The build command copies all files (excluding files with `.md` extension) from the source directory
into the build directory.*
***Note:*** *The build command copies all files from the source directory into the build directory.
You can exclude specific file extensions using the `--copy-exclude-extensions` flag or the
`output.html.copy-exclude-extensions` configuration option.*
5 changes: 5 additions & 0 deletions guide/src/format/configuration/renderers.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ site-url = "/example-book/"
cname = "myproject.rs"
input-404 = "not-found.md"
sidebar-header-nav = true
copy-exclude-extensions = ["rs", "toml"]
```

The following configuration options are available:
Expand Down Expand Up @@ -170,6 +171,10 @@ The following configuration options are available:
Static CSS and JS files can reference each other using `{{ resource "filename" }}` directives.
Defaults to `true`.
- **sidebar-header-nav:** If `true`, the sidebar will contain navigation for headers on the current page. Default is `true`.
- **copy-exclude-extensions:** A list of file extensions to exclude when copying files from the source directory
to the build directory. By default, all files are copied. This is useful when your source directory contains
symlinks to other directories with files you don't want to include in the output. Provide extensions without dots.
Example: `["rs", "toml", "lock"]`. Defaults to `[]` (no exclusions).

[custom domain]: https://docs.github.com/en/github/working-with-github-pages/managing-a-custom-domain-for-your-github-pages-site

Expand Down
15 changes: 15 additions & 0 deletions src/cmd/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub fn make_subcommand() -> Command {
.arg_dest_dir()
.arg_root_dir()
.arg_open()
.arg_copy_exclude_extensions()
}

// Build command implementation
Expand All @@ -20,6 +21,20 @@ pub fn execute(args: &ArgMatches) -> Result<()> {

set_dest_dir(args, &mut book);

// Apply CLI copy-exclude-extensions to config
if let Some(exts) = args.get_one::<String>("copy-exclude-extensions") {
let additional_exts: Vec<String> = exts
.split(',')
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
.collect();

if let Ok(Some(mut html_config)) = book.config.get::<mdbook_core::config::HtmlConfig>("output.html") {
html_config.copy_exclude_extensions.extend(additional_exts);
book.config.set("output.html", html_config)?;
}
}

book.build()?;

if args.get_flag("open") {
Expand Down
13 changes: 13 additions & 0 deletions src/cmd/command_prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,19 @@ pub trait CommandExt: Sized {
self._arg(arg!(-o --open "Opens the compiled book in a web browser"))
}

fn arg_copy_exclude_extensions(self) -> Self {
self._arg(
Arg::new("copy-exclude-extensions")
.long("copy-exclude-extensions")
.value_name("EXTENSIONS")
.help(
"Comma-separated list of file extensions to exclude when copying files\n\
from the source directory (e.g., 'rs,toml,lock')\n\
This supplements any extensions configured in book.toml.",
)
)
}

#[cfg(any(feature = "watch", feature = "serve"))]
fn arg_watcher(self) -> Self {
#[cfg(feature = "watch")]
Expand Down
Loading