Skip to content

Commit

Permalink
Update how to generate toc
Browse files Browse the repository at this point in the history
  • Loading branch information
hayatoito committed May 16, 2021
1 parent 4e0d52c commit 2dcf66c
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 30 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/target
.cargo
Makefile
**/*.rs.bk
Makefile*
Make.zsh
81 changes: 54 additions & 27 deletions src/html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,34 +95,44 @@ fn wrap_header_with_link(
)
}

pub fn build_toc(html: &str) -> String {
let regex =
Regex::new(r#"<h(?P<level>[12]) id="(?P<id>.*?)">(<a.*?>)?(?P<text>.*?)(</a>)?</h\d>"#)
.unwrap();
pub fn build_toc(html: &str, toc_level: Option<u8>) -> String {
let header_level: String = match toc_level {
Some(level) if level <= 9 => (1..=level).map(|i| i.to_string()).collect(),
Some(level) => {
log::warn!("Invalid toc_level is found: {}. Using 1-9...", level);
"1-9".to_string()
}
None => "1-9".to_string(),
};
let regex = Regex::new(&format!(
r#"<h(?P<level>[{}]) id="(?P<id>.*?)">(<a.*?>)?(?P<text>.*?)(</a>)?</h\d>"#,
header_level
))
.unwrap();
let mut toc = String::new();
let nav_start = r#"<nav class="nav nav-pills flex-column">
let list_start = r#"<ul>
"#;
let nav_end = r#"</nav>
let list_end = r#"</ul>
"#;

let mut prev_level = 0;
for cap in regex.captures_iter(html) {
let level: usize = cap["level"].parse().unwrap();
let anchor = format!(
r##"<a class="nav-link" href="#{id}">{text}</a>
r##"<li><a href="#{id}">{text}</a></li>
"##,
id = &cap["id"],
text = &cap["text"]
);
match prev_level.cmp(&level) {
Ordering::Less => {
for _ in 0..(level - prev_level) {
toc.push_str(nav_start);
toc.push_str(list_start);
}
}
Ordering::Greater => {
for _ in 0..(prev_level - level) {
toc.push_str(nav_end);
toc.push_str(list_end);
}
}
Ordering::Equal => {
Expand All @@ -133,7 +143,7 @@ pub fn build_toc(html: &str) -> String {
prev_level = level;
}
for _ in 0..prev_level {
toc.push_str(nav_end);
toc.push_str(list_end);
}
toc
}
Expand All @@ -154,23 +164,42 @@ mod tests {
#[test]
fn build_toc_test() {
assert_eq!(
build_toc(r#"<h1 id="hello1">hello</h1>"#),
r##"<nav class="nav nav-pills flex-column">
<a class="nav-link" href="#hello1">hello</a>
</nav>
build_toc(r#"<h1 id="hello1">hello</h1>"#, None),
r##"<ul>
<li><a href="#hello1">hello</a></li>
</ul>
"##
);

assert_eq!(
build_toc(
r#"<h1 id="hello1">Hello 1</h1>
<h1 id="hello2">Hello 2</h1>
"#
"#,
None
),
r##"<ul>
<li><a href="#hello1">Hello 1</a></li>
<li><a href="#hello2">Hello 2</a></li>
</ul>
"##
);

assert_eq!(
build_toc(
r#"<h1 id="hello1">Hello 1</h1>
<h1 id="hello2">Hello 2</h1>
<h2 id="hello3">Hello 3</h2>
"#,
None
),
r##"<nav class="nav nav-pills flex-column">
<a class="nav-link" href="#hello1">Hello 1</a>
<a class="nav-link" href="#hello2">Hello 2</a>
</nav>
r##"<ul>
<li><a href="#hello1">Hello 1</a></li>
<li><a href="#hello2">Hello 2</a></li>
<ul>
<li><a href="#hello3">Hello 3</a></li>
</ul>
</ul>
"##
);

Expand All @@ -179,15 +208,13 @@ mod tests {
r#"<h1 id="hello1">Hello 1</h1>
<h1 id="hello2">Hello 2</h1>
<h2 id="hello3">Hello 3</h2>
"#
"#,
Some(1)
),
r##"<nav class="nav nav-pills flex-column">
<a class="nav-link" href="#hello1">Hello 1</a>
<a class="nav-link" href="#hello2">Hello 2</a>
<nav class="nav nav-pills flex-column">
<a class="nav-link" href="#hello3">Hello 3</a>
</nav>
</nav>
r##"<ul>
<li><a href="#hello1">Hello 1</a></li>
<li><a href="#hello2">Hello 2</a></li>
</ul>
"##
);
}
Expand Down
3 changes: 2 additions & 1 deletion src/site.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ struct MarkdownMetadata {
update_date: Option<chrono::NaiveDate>,
slug: Option<String>,
toc: Option<bool>,
toc_level: Option<u8>,
draft: Option<bool>,
template: Option<String>,
}
Expand Down Expand Up @@ -184,7 +185,7 @@ impl Article {
update_date: markdown.metadata.update_date,
toc,
toc_html: if toc {
Some(html::build_toc(&content))
Some(html::build_toc(&content, markdown.metadata.toc_level))
} else {
None
},
Expand Down

0 comments on commit 2dcf66c

Please sign in to comment.