Implement base table of contents logic
This commit is contained in:
parent
d604ca637d
commit
17f49c2107
|
@ -10,8 +10,14 @@ A discussion on pretty much every aspect of the mobile rhythm game "Arcaea".
|
||||||
|
|
||||||
# Why I love arcaea
|
# Why I love arcaea
|
||||||
|
|
||||||
## What is arcaea
|
## Introduction
|
||||||
- explain the base mechanics
|
|
||||||
|
- What is arcaea
|
||||||
|
- What this article is
|
||||||
|
- How to read this article
|
||||||
|
|
||||||
|
::: toc
|
||||||
|
:::
|
||||||
|
|
||||||
## What makes a good rhythm game
|
## What makes a good rhythm game
|
||||||
- I don't need to reinvent the wheel here, I can link that one `mental checkpoint` video
|
- I don't need to reinvent the wheel here, I can link that one `mental checkpoint` video
|
||||||
|
|
59
src/html.rs
59
src/html.rs
|
@ -1,3 +1,4 @@
|
||||||
|
use std::cmp::Ordering;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
|
@ -311,6 +312,64 @@ impl<'s> Writer<'s> {
|
||||||
self.states.push(State::Ignore);
|
self.states.push(State::Ignore);
|
||||||
}
|
}
|
||||||
// }}}
|
// }}}
|
||||||
|
// {{{ Table of contents
|
||||||
|
Container::Div { class: "toc" } => {
|
||||||
|
template!("templates/table-of-contents.html", out)?.feed_fully(
|
||||||
|
out,
|
||||||
|
|label, out| {
|
||||||
|
if label == "content" {
|
||||||
|
let mut level_stack = Vec::with_capacity(6);
|
||||||
|
level_stack.push(1);
|
||||||
|
|
||||||
|
for (i, heading) in self.metadata.toc.iter().enumerate() {
|
||||||
|
loop {
|
||||||
|
let level = level_stack.last().unwrap();
|
||||||
|
match heading.level.cmp(level) {
|
||||||
|
Ordering::Greater => {
|
||||||
|
writeln!(out, "<ol>")?;
|
||||||
|
level_stack.push(heading.level);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Ordering::Equal => {
|
||||||
|
if i != 0 {
|
||||||
|
writeln!(out, "</li>")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Ordering::Less => {
|
||||||
|
writeln!(out, "</li></ol>")?;
|
||||||
|
level_stack.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
write!(out, r##"<li><a href="#{}">"##, heading.id)?;
|
||||||
|
|
||||||
|
for event in &heading.events {
|
||||||
|
self.render_event(event, out)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
writeln!(out, "</a>")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ in 0..level_stack.len() - 1 {
|
||||||
|
writeln!(out, "</li></ol>")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
writeln!(out, "</li>")?;
|
||||||
|
|
||||||
|
Ok(true)
|
||||||
|
} else {
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// We don't care about the contents of this block
|
||||||
|
self.states.push(State::Ignore);
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
// {{{ Div
|
// {{{ Div
|
||||||
Container::Div { class } => {
|
Container::Div { class } => {
|
||||||
if has_role(attrs, "description") {
|
if has_role(attrs, "description") {
|
||||||
|
|
|
@ -129,6 +129,7 @@ impl<'a> TemplateRenderer<'a> {
|
||||||
}
|
}
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
|
/// Automatically fill in placeholders until the provided lambda returns false.
|
||||||
pub fn feed<W: std::fmt::Write>(
|
pub fn feed<W: std::fmt::Write>(
|
||||||
&mut self,
|
&mut self,
|
||||||
out: &mut W,
|
out: &mut W,
|
||||||
|
@ -144,6 +145,18 @@ impl<'a> TemplateRenderer<'a> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Equivalent to running [Self::feed] and then [Self::finish].
|
||||||
|
pub fn feed_fully<W: std::fmt::Write>(
|
||||||
|
mut self,
|
||||||
|
out: &mut W,
|
||||||
|
f: impl FnMut(&str, &mut W) -> anyhow::Result<bool>,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
self.feed(out, f)?;
|
||||||
|
self.finish(out)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// }}}
|
// }}}
|
||||||
// {{{ Macro
|
// {{{ Macro
|
||||||
|
|
9
src/templates/table-of-contents.html
Normal file
9
src/templates/table-of-contents.html
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<details>
|
||||||
|
<summary>Toggle table of contents</summary>
|
||||||
|
<nav role="doc-toc" aria-labelledby="toc-title">
|
||||||
|
<h2 id="toc-title">Table of Contents</h2>
|
||||||
|
<ol>
|
||||||
|
{{content}}
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
</details>
|
Loading…
Reference in a new issue