commit - 8fdcd6d1ef8eb3670e5a29dc8d51fac32fd4546b
commit + 080678415d1f58a00080317e612af2dd2f6135e9
blob - e296698df90a959cf47d867a845648b0cc66077c
blob + 44f92662798219638306d3b6f1c7905418f338a9
--- kssg.rs
+++ kssg.rs
String::new()
};
- let html = if posts[i].meta.toc {
- add_heading_ids(&posts[i].html_content)
+ let is_post = posts[i].out_path.starts_with("public/posts");
+ let html = if is_post || posts[i].meta.toc {
+ add_heading_ids(&posts[i].html_content, is_post)
} else {
posts[i].html_content.clone()
};
toc
}
-fn add_heading_ids(html: &str) -> String {
+fn add_heading_ids(html: &str, linkify: bool) -> String {
let mut result = String::with_capacity(html.len());
let mut pos = 0;
while pos < html.len() {
- let h2 = html[pos..].find("<h2>");
- let h3 = html[pos..].find("<h3>");
- let (level, start) = match (h2, h3) {
- (Some(a), Some(b)) => {
- if a <= b {
- (2, pos + a)
- } else {
- (3, pos + b)
+ let mut best: Option<(u8, usize)> = None;
+ for level in 2u8..=6 {
+ let tag = format!("<h{}>", level);
+ if let Some(i) = html[pos..].find(&tag) {
+ let abs = pos + i;
+ if best.map(|(_, p)| abs < p).unwrap_or(true) {
+ best = Some((level, abs));
}
}
- (Some(a), None) => (2, pos + a),
- (None, Some(b)) => (3, pos + b),
- (None, None) => break,
+ }
+ let (level, start) = match best {
+ Some(v) => v,
+ None => break,
};
let tag_end = start + 4; // len of "<hN>"
let close = format!("</h{}>", level);
continue;
}
};
- let text = html[tag_end..end]
- .replace("<code>", "")
- .replace("</code>", "");
+ let inner = &html[tag_end..end];
+ let text = inner.replace("<code>", "").replace("</code>", "");
let id = slugify(&text);
result.push_str(&html[pos..start]);
- result.push_str(&format!("<h{} id=\"{}\">", level, id));
- result.push_str(&html[tag_end..end + close.len()]);
+ if linkify {
+ result.push_str(&format!(
+ "<h{} id=\"{}\"><a href=\"#{}\">{}</a></h{}>",
+ level, id, id, inner, level,
+ ));
+ } else {
+ result.push_str(&format!("<h{} id=\"{}\">", level, id));
+ result.push_str(&html[tag_end..end + close.len()]);
+ }
pos = end + close.len();
}
result.push_str(&html[pos..]);