Skip to content

Commit 845bc84

Browse files
committed
fix(quarto-core): handle Windows paths in !path metadata adjustment
adjust_paths_to_document_dir rebases !path metadata values (css, resources, bibliography, ...) relative to the document directory. Two Windows-only defects lived in that one function: - The rebased value is stringified with to_string_lossy, so on Windows pathdiff's native separators leaked into the value. Since it is used verbatim in HTML hrefs (a css: !path <link>), the emitted attribute became href="..\..\shared\styles.css" instead of forward slashes. Normalize at the emission site with quarto_util::to_forward_slashes, the same helper the SCSS and JSON-writer separator fixes reuse. - The relative-path guard used Path::is_relative, which on Windows is false only for drive-prefixed paths; a POSIX-absolute value like /usr/share/base.css is not is_absolute there, so it was wrongly rebased into ../../../usr/share/base.css. Guard on is_rooted (has_root) instead, matching the helper's documented purpose. The suite's dir-metadata-paths fixture and the existing directory_metadata_tests (previously red on Windows, green elsewhere) now pass on all platforms.
1 parent 815248c commit 845bc84

1 file changed

Lines changed: 9 additions & 3 deletions

File tree

  • crates/quarto-core/src/project

crates/quarto-core/src/project/mod.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,14 +230,20 @@ fn adjust_paths_recursive(value: &mut ConfigValue, metadata_dir: &Path, document
230230
match &mut value.value {
231231
ConfigValueKind::Path(path_str) => {
232232
let path = PathBuf::from(&*path_str);
233-
// Only adjust relative paths (not absolute, not URLs)
234-
if path.is_relative()
233+
// Only adjust relative paths (not absolute, not URLs). Use
234+
// `is_rooted` (has_root), not `Path::is_relative`: on Windows a
235+
// POSIX-absolute path like `/usr/share/base.css` is not
236+
// `is_absolute` (no drive prefix) and would be wrongly rebased.
237+
if !quarto_util::is_rooted(&path)
235238
&& !path_str.starts_with("http://")
236239
&& !path_str.starts_with("https://")
237240
{
238241
let abs_path = metadata_dir.join(&path);
239242
if let Some(adjusted) = pathdiff::diff_paths(&abs_path, document_dir) {
240-
*path_str = adjusted.to_string_lossy().into_owned();
243+
// The adjusted value is used verbatim in HTML hrefs (e.g. a
244+
// `css: !path` <link>), so it must use forward slashes on
245+
// every platform; pathdiff yields native separators.
246+
*path_str = quarto_util::to_forward_slashes(&adjusted);
241247
}
242248
}
243249
}

0 commit comments

Comments
 (0)