add tag display to sidebar
This commit is contained in:
parent
f5d6c9c05b
commit
a2debf5b2c
3 changed files with 46 additions and 3 deletions
31
src/main.rs
31
src/main.rs
|
@ -14,6 +14,7 @@ use percent_encoding::{percent_decode_str, utf8_percent_encode};
|
|||
use pulldown_cmark::{html, Event, Options, Parser, Tag};
|
||||
use regex::{Captures, Regex};
|
||||
use slug::slugify;
|
||||
use std::cmp::Reverse;
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
|
@ -44,6 +45,7 @@ struct MutableState {
|
|||
struct GardenCache {
|
||||
pages: HashMap<String, ParsedPage>,
|
||||
files: Vec<PathBuf>,
|
||||
tags: HashMap<String, u32>,
|
||||
}
|
||||
|
||||
impl Default for GardenCache {
|
||||
|
@ -51,6 +53,7 @@ impl Default for GardenCache {
|
|||
GardenCache {
|
||||
pages: HashMap::new(),
|
||||
files: vec![],
|
||||
tags: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -297,6 +300,12 @@ async fn render(
|
|||
data.title.as_ref().unwrap_or(&"Digital Garden".to_string()),
|
||||
);
|
||||
context.insert("files", &cache.files);
|
||||
|
||||
let mut tags: Vec<(&String, &u32)> = cache.tags.iter().collect();
|
||||
tags.sort_by_key(|(t, _)| *t);
|
||||
tags.sort_by_key(|(_, n)| Reverse(*n));
|
||||
context.insert("tags", &tags);
|
||||
|
||||
context.insert(
|
||||
"recently_changed",
|
||||
&recently_changed
|
||||
|
@ -387,6 +396,7 @@ fn update_garden<P: AsRef<Path>>(
|
|||
}
|
||||
|
||||
let mut pages = current.pages;
|
||||
let mut tags = current.tags;
|
||||
|
||||
let markdown_paths = files
|
||||
.iter()
|
||||
|
@ -428,9 +438,13 @@ fn update_garden<P: AsRef<Path>>(
|
|||
},
|
||||
},
|
||||
);
|
||||
|
||||
result.tags.into_iter().for_each(|tag| {
|
||||
*tags.entry(tag).or_insert(0) += 1;
|
||||
});
|
||||
}
|
||||
|
||||
let result = GardenCache { pages, files };
|
||||
let result = GardenCache { pages, files, tags };
|
||||
trace!("{:#?}", result);
|
||||
Ok(result)
|
||||
}
|
||||
|
@ -439,6 +453,7 @@ struct ParseResult {
|
|||
html: String,
|
||||
title: Option<String>,
|
||||
links: Vec<String>,
|
||||
tags: Vec<String>,
|
||||
}
|
||||
|
||||
fn parse_garden<S: AsRef<str>>(text: S) -> anyhow::Result<ParseResult> {
|
||||
|
@ -448,10 +463,19 @@ fn parse_garden<S: AsRef<str>>(text: S) -> anyhow::Result<ParseResult> {
|
|||
let mut last_nontext_event: Option<Event> = None;
|
||||
|
||||
let mut links: Vec<String> = vec![];
|
||||
let mut tags: Vec<String> = vec![];
|
||||
|
||||
let parser = Parser::new_ext(text.as_ref(), Options::all()).map(|event| {
|
||||
if let Event::Start(Tag::Link(_, str, _)) = &event {
|
||||
links.push(str.to_string());
|
||||
if let Event::Start(Tag::Link(_, dest, _)) = &event {
|
||||
links.push(dest.to_string());
|
||||
}
|
||||
|
||||
if let Some(Event::Start(Tag::Link(_, dest, _))) = &last_nontext_event {
|
||||
if let Event::Text(str) = &event {
|
||||
if str.starts_with("#") {
|
||||
tags.push(dest.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(Event::Start(Tag::Heading(hl))) = last_nontext_event {
|
||||
|
@ -476,6 +500,7 @@ fn parse_garden<S: AsRef<str>>(text: S) -> anyhow::Result<ParseResult> {
|
|||
html,
|
||||
title: top_heading_text,
|
||||
links,
|
||||
tags,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -183,6 +183,10 @@ nav .graph-view {
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.tag .count {
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
footer {
|
||||
padding: 1em 0;
|
||||
color: gray;
|
||||
|
|
|
@ -73,6 +73,20 @@
|
|||
{% endfor %}
|
||||
</ul>
|
||||
</section>
|
||||
{% if tags %}
|
||||
<section>
|
||||
<h2>Tags</h2>
|
||||
<ul>
|
||||
{% for tag_cnt in tags %}
|
||||
<li class="tag">
|
||||
<a href="/{{tag_cnt.0}}">
|
||||
<span class="label">#{{tag_cnt.0}}</span> <span class="count">({{tag_cnt.1}})</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</section>
|
||||
{% endif %}
|
||||
<section class="graph-view">
|
||||
<a href="/!graph">Graph view (beta)</a>
|
||||
</section>
|
||||
|
|
Loading…
Reference in a new issue