Skip to content
Merged
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
54 changes: 45 additions & 9 deletions src/converter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pub fn convert_to_markdown_multifile(
let item_paths = build_path_map(crate_data);

// Group items by module (no longer duplicating re-exports)
let modules = group_by_module(crate_data, &item_paths, include_private);
let mut modules = group_by_module(crate_data, &item_paths, include_private);

// Build a map of re-exported modules (module_path -> list of re-exported submodule paths)
let reexported_modules = build_reexported_modules(crate_data, &item_paths, include_private);
Expand All @@ -84,9 +84,32 @@ pub fn convert_to_markdown_multifile(
let root_module_key = crate_name.to_string();
let has_root_items = modules.contains_key(&root_module_key);

// First, ensure ALL modules (including empty ones) are in the modules map
// This is crucial for generating index.md files and sidebar entries for parent modules
// that only contain submodules (prevents Docusaurus referencing missing doc ids).
for (_id, item) in &crate_data.index {
if let ItemEnum::Module(_) = &item.inner {
if let Some(path) = item_paths.get(_id) {
let module_path = path.join("::");
// Ensure this module exists in the map (even if empty)
modules.entry(module_path).or_default();
}
}
}

// Build module hierarchy to determine which modules have submodules
let module_hierarchy = build_module_hierarchy(&modules, crate_name);

// Ensure parent modules from hierarchy are present in `modules` so we
// generate index pages and matching sidebar keys for parent modules that
// only contain submodules (prevents Docusaurus referencing missing doc ids).
// This is a minimal change: it inserts empty item lists for parents that
// don't already exist so `generate_module_overview` will still create
// a corresponding `index.md` file.
for parent in module_hierarchy.keys() {
modules.entry(parent.clone()).or_default();
}

// Generate index.md - either with crate overview or with root module content
if has_root_items {
// If there are items in the root module, combine crate overview with root content
Expand Down Expand Up @@ -3504,8 +3527,11 @@ fn generate_all_sidebars(
all_sidebars.insert(root_path_for_modules, root_sidebar_for_modules);

// Generate sidebar for each submodule (for dynamic sidebar when entering modules)
eprintln!("[DEBUG] Total modules to process: {}", modules.keys().len());
for module_key in modules.keys() {
eprintln!("[DEBUG] Processing module: {}", module_key);
if module_key == crate_name {
eprintln!("[DEBUG] Skipping root crate: {}", crate_name);
continue; // Skip root, already handled
}

Expand All @@ -3530,20 +3556,30 @@ fn generate_all_sidebars(
};
all_sidebars.insert(module_path.clone(), sidebar);

// Check if this module has sub-modules (direct children)
let has_submodules = modules.keys().any(|key| {
// Check if this module has sub-modules (direct children) or items
// Generate a _children sidebar if the module has submodules or items (structs, enums, etc.)
let has_submodules_or_items = modules.keys().any(|key| {
if let Some(stripped) = key.strip_prefix(&format!("{}::", module_key)) {
// Make sure it's a direct child (no more ::)
!stripped.contains("::")
} else {
false
}
});
}) || modules
.get(module_key)
.map(|items| {
items
.iter()
.any(|(_, item)| !matches!(&item.inner, ItemEnum::Module(_) | ItemEnum::Use(_)))
})
.unwrap_or(false);

eprintln!(
"[DEBUG] Module '{}' has_submodules_or_items: {}",
module_key, has_submodules_or_items
);

// If this module has sub-modules, generate an additional sidebar for them
// This sidebar shows "In <module>" with the module's own contents
// Similar to how leaf items get a sidebar showing their parent module's contents
if has_submodules {
// If this module has sub-modules or items, generate an additional sidebar for them
if has_submodules_or_items {
let submodule_sidebar = generate_sidebar_for_module(
crate_name,
module_key, // Use this module as the "parent"
Expand Down