summaryrefslogtreecommitdiff
path: root/src/collect_files.rs
diff options
context:
space:
mode:
authorBen Bridle <ben@derelict.engineering>2025-12-12 19:59:27 +1300
committerBen Bridle <ben@derelict.engineering>2025-12-12 19:59:27 +1300
commit50df287852367d3e50779155c6e92b6e2a388c9d (patch)
treefc3d5322dcbe44eb235f40996a533b265b030fef /src/collect_files.rs
parente83e426f7e01a05086418fe8246aef95e5e13dfb (diff)
downloadtoaster-50df287852367d3e50779155c6e92b6e2a388c9d.zip
Allow pages to contain duplicate headings under different h1 headings
This kind of works, but the whole system will have to be rewritten from the ground up so that every heading knows its own canonical name.
Diffstat (limited to 'src/collect_files.rs')
-rw-r--r--src/collect_files.rs30
1 files changed, 26 insertions, 4 deletions
diff --git a/src/collect_files.rs b/src/collect_files.rs
index cb785fc..30dcb98 100644
--- a/src/collect_files.rs
+++ b/src/collect_files.rs
@@ -33,6 +33,7 @@ pub struct Heading {
pub name: String,
pub url: String,
pub level: Level,
+ pub block_id: usize,
}
pub struct StaticItem {
@@ -199,23 +200,44 @@ impl Website {
"md" => {
let markdown = std::fs::read_to_string(&source_path).unwrap();
let document = MarkdownDocument::from_str(&markdown);
+ // Collect headings, check for duplicates.
let mut heading_set = HashSet::new();
let mut duplicates = HashSet::new();
- let headings = document.blocks.iter()
- .filter_map(|block| if let Block::Heading { line, level } = block {
+ let mut headings: Vec<_> = document.blocks.iter().enumerate()
+ .filter_map(|(block_id, block)| if let Block::Heading { line, level } = block {
let name = line.to_string();
let url = make_url_safe(strip_appendix(&name));
let level = level.to_owned();
if !heading_set.insert(url.clone()) {
duplicates.insert(url.clone());
}
- Some(Heading { name, url, level })
+ Some(Heading { name, url, level, block_id })
} else {
None
}).collect();
+
+ // Namespace any duplicate headings to the parent h1 heading.
+ let mut parent_url = String::new();
+ for heading in &mut headings {
+ if let Level::Heading1 = heading.level {
+ parent_url = heading.url.clone();
+ }
+ if duplicates.contains(&heading.url) {
+ heading.url = format!("{parent_url}-{}", heading.url);
+ }
+ }
+ // Check for duplicates again, and warn if any.
+ heading_set.clear();
+ duplicates.clear();
+ for heading in &headings {
+ if !heading_set.insert(heading.url.clone()) {
+ duplicates.insert(heading.url.clone());
+ }
+ }
for url in duplicates {
warn!("Page {full_name:?} contains multiple headings with ID \"#{url}\"");
}
+
if name_url == "+index" {
if parents.is_empty() {
// This is the index file for the whole site.
@@ -351,7 +373,7 @@ impl Website {
if !path.starts_with('/') {
path = format!("{}{path}", from.parent_url());
}
- let path = make_url_safe(&collapse_path(&path));
+ path = make_url_safe(&collapse_path(&path));
// Find page with this path in website.
for page in &self.pages {