add tag display to sidebar

master
Tomáš Mládek 2021-10-05 22:34:29 +02:00
parent f5d6c9c05b
commit a2debf5b2c
3 changed files with 46 additions and 3 deletions

View File

@ -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,
})
}

View File

@ -183,6 +183,10 @@ nav .graph-view {
text-align: center;
}
.tag .count {
opacity: .5;
}
footer {
padding: 1em 0;
color: gray;

View File

@ -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>