Merge pull request #2839 from ehuss/to_url_path

Add ToUrlPath helper trait
This commit is contained in:
Eric Huss
2025-09-15 14:50:47 +00:00
committed by GitHub
6 changed files with 27 additions and 24 deletions

View File

@@ -6,14 +6,6 @@ use std::io::Write;
use std::path::{Component, Path, PathBuf};
use tracing::{debug, trace};
/// Naively replaces any path separator with a forward-slash '/'
pub fn normalize_path(path: &str) -> String {
use std::path::is_separator;
path.chars()
.map(|ch| if is_separator(ch) { '/' } else { ch })
.collect::<String>()
}
/// Write the given data to a file, creating it first if necessary
pub fn write_file<P: AsRef<Path>>(build_dir: &Path, filename: P, content: &[u8]) -> Result<()> {
let path = build_dir.join(filename);

View File

@@ -1,6 +1,7 @@
use super::helpers;
use super::static_files::StaticFiles;
use crate::theme::Theme;
use crate::utils::ToUrlPath;
use anyhow::{Context, Result, bail};
use handlebars::Handlebars;
use mdbook_core::book::{Book, BookItem, Chapter};
@@ -122,9 +123,7 @@ impl HtmlHandlebars {
.as_ref()
.unwrap()
.with_extension("html")
.to_str()
.unwrap()
.replace('\\', "//");
.to_url_path();
let obj = json!( {
"title": ch.name,
"link": path,
@@ -1048,7 +1047,7 @@ fn collect_redirects_for_path(
path: &Path,
redirects: &HashMap<String, String>,
) -> Result<BTreeMap<String, String>> {
let path = format!("/{}", path.display().to_string().replace('\\', "/"));
let path = format!("/{}", path.to_url_path());
if redirects.contains_key(&path) {
bail!(
"redirect found for existing chapter at `{path}`\n\

View File

@@ -1,3 +1,4 @@
use crate::utils::ToUrlPath;
use std::path::Path;
use std::{cmp::Ordering, collections::BTreeMap};
@@ -109,12 +110,7 @@ impl HelperDef for RenderToc {
let path_exists = match item.get("path") {
Some(path) if !path.is_empty() => {
out.write("<a href=\"")?;
let tmp = Path::new(path)
.with_extension("html")
.to_str()
.unwrap()
// Hack for windows who tends to use `\` as separator instead of `/`
.replace('\\', "/");
let tmp = Path::new(path).with_extension("html").to_url_path();
// Add link
out.write(&tmp)?;

View File

@@ -1,6 +1,7 @@
use super::static_files::StaticFiles;
use crate::theme::searcher;
use anyhow::{Context, Result, bail};
use crate::utils::ToUrlPath;
use anyhow::{Result, bail};
use elasticlunr::{Index, IndexBuilder};
use mdbook_core::book::{Book, Chapter};
use mdbook_core::config::{Search, SearchChapterSettings};
@@ -124,11 +125,9 @@ fn render_item(
.path
.as_ref()
.expect("Checked that path exists above");
let filepath = Path::new(&chapter_path).with_extension("html");
let filepath = filepath
.to_str()
.with_context(|| "Could not convert HTML path to str")?;
let anchor_base = utils::fs::normalize_path(filepath);
let anchor_base = Path::new(&chapter_path)
.with_extension("html")
.to_url_path();
let options = HtmlRenderOptions::new(&chapter_path);
let mut p = new_cmark_parser(&chapter.content, &options.markdown_options).peekable();

View File

@@ -2,6 +2,7 @@
mod html_handlebars;
pub mod theme;
pub(crate) mod utils;
pub use html_handlebars::HtmlHandlebars;
use mdbook_core::config::HtmlConfig;

View File

@@ -0,0 +1,16 @@
//! Utilities for processing HTML.
use std::path::Path;
/// Helper trait for converting a [`Path`] to a string suitable for an HTML path.
pub(crate) trait ToUrlPath {
fn to_url_path(&self) -> String;
}
impl ToUrlPath for Path {
fn to_url_path(&self) -> String {
// We're generally assuming that all paths we deal with are utf-8.
// The replace here is to handle Windows paths.
self.to_str().unwrap().replace('\\', "/")
}
}