|
1 |
| -use std::path::{Path, PathBuf}; |
| 1 | +use std::{ |
| 2 | + borrow::Cow, |
| 3 | + path::{Path, PathBuf}, |
| 4 | +}; |
2 | 5 |
|
3 | 6 | use chrono::{Local, SecondsFormat};
|
4 | 7 | use colored::Colorize;
|
@@ -64,35 +67,59 @@ impl AssetType {
|
64 | 67 | #[instrument(skip(base_path, full_path))]
|
65 | 68 | fn generate_content_title(base_path: &Path, full_path: &Path) -> String {
|
66 | 69 | debug!("Generating content title");
|
| 70 | + |
| 71 | + // Get relative path within content directory |
67 | 72 | let relative_path = full_path
|
68 | 73 | .strip_prefix(base_path.join("content"))
|
69 | 74 | .unwrap_or(full_path);
|
70 | 75 |
|
71 |
| - let mut components = relative_path |
72 |
| - .iter() |
73 |
| - .filter(|c| *c != "index.norg") |
74 |
| - .map(|c| { |
75 |
| - titlecase( |
76 |
| - &c.to_string_lossy() |
77 |
| - .trim_end_matches(".norg") |
78 |
| - .replace(['-', '_'], " "), |
79 |
| - ) |
80 |
| - }) |
81 |
| - .collect::<Vec<_>>(); |
82 |
| - |
83 |
| - if components.is_empty() { |
84 |
| - debug!("Using default title 'index'"); |
85 |
| - return "index".to_string(); |
86 |
| - } |
| 76 | + // Determine if we're dealing with an index file |
| 77 | + let is_index = relative_path.ends_with("index.norg"); |
87 | 78 |
|
88 |
| - if let Some(last) = components.last_mut() { |
89 |
| - if last == "index" { |
90 |
| - debug!("Removing trailing 'index' from title"); |
91 |
| - components.pop(); |
92 |
| - } |
93 |
| - } |
| 79 | + // Extract the relevant component name |
| 80 | + let raw_name = if is_index { |
| 81 | + // Get parent directory name for index files |
| 82 | + relative_path |
| 83 | + .parent() |
| 84 | + .and_then(|p| p.file_name()) |
| 85 | + .map(|n| n.to_string_lossy()) |
| 86 | + .unwrap_or_else(|| { |
| 87 | + debug!("Using default title for root index"); |
| 88 | + Cow::Borrowed("Home") |
| 89 | + }) |
| 90 | + } else { |
| 91 | + // Get filename stem for regular files |
| 92 | + relative_path |
| 93 | + .file_stem() |
| 94 | + .map(|s| s.to_string_lossy()) |
| 95 | + .unwrap_or_else(|| { |
| 96 | + debug!("No valid filename stem found"); |
| 97 | + Cow::Borrowed("Untitled") |
| 98 | + }) |
| 99 | + }; |
| 100 | + |
| 101 | + // Clean and format the title |
| 102 | + let title = raw_name |
| 103 | + .replace(['-', '_'], " ") |
| 104 | + .split_whitespace() |
| 105 | + .collect::<Vec<_>>() |
| 106 | + .join(" "); |
| 107 | + |
| 108 | + // Titlecase the first letter of each word |
| 109 | + let title = titlecase( |
| 110 | + &title |
| 111 | + .split(' ') |
| 112 | + .map(|word| { |
| 113 | + let mut chars = word.chars(); |
| 114 | + match chars.next() { |
| 115 | + Some(c) => c.to_uppercase().collect::<String>() + chars.as_str(), |
| 116 | + None => String::new(), |
| 117 | + } |
| 118 | + }) |
| 119 | + .collect::<Vec<_>>() |
| 120 | + .join(" "), |
| 121 | + ); |
94 | 122 |
|
95 |
| - let title = components.join(" | "); |
96 | 123 | debug!(title = %title, "Generated content title");
|
97 | 124 | title
|
98 | 125 | }
|
|
0 commit comments