From ca52fa6bf5e4532ae7b2c7d031f15cb530d46bb1 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 17 Feb 2024 22:43:19 +0000 Subject: [PATCH] Add note about tag navigation --- docs/colophon.md | 2 +- docs/notes/mkdocs-nav-by-tag.md | 16 ++++++++++ hooks/notes.py | 50 +----------------------------- hooks/tag_nav.py | 55 +++++++++++++++++++++++++++++++++ mkdocs.yml | 1 + 5 files changed, 74 insertions(+), 50 deletions(-) create mode 100644 docs/notes/mkdocs-nav-by-tag.md create mode 100644 hooks/tag_nav.py diff --git a/docs/colophon.md b/docs/colophon.md index d71db97..b7433c4 100644 --- a/docs/colophon.md +++ b/docs/colophon.md @@ -4,7 +4,7 @@ hide: [toc] # Colophon -This site is built with [`mkdocs`](https://www.mkdocs.org/) and [`mkdocs-material`](https://squidfunk.github.io/mkdocs-material/). Sure, it's designed for docs, but with a few modifications (like the [`tags`](https://squidfunk.github.io/mkdocs-material/plugins/tags/) plugin) it can be used for notes. I made some fairly large modifications to how tags work, so the sidebar is structured by tag rather than by directory (directories are fairly arbitrary, and might get removed entirely in future). +This site is built with [`mkdocs`](https://www.mkdocs.org/) and [`mkdocs-material`](https://squidfunk.github.io/mkdocs-material/). Sure, it's designed for docs, but with a few modifications (like the [`tags`](https://squidfunk.github.io/mkdocs-material/plugins/tags/) plugin) it can be used for notes. I made some fairly [large modifications](notes/mkdocs-nav-by-tag.md) to how tags work, so the sidebar is structured by tag rather than by directory (directories are fairly arbitrary, and might get removed entirely in future). It's been through a few iterations in the past, starting with [`gatsby-theme-code-notes`](https://github.com/mrmartineau/gatsby-theme-code-notes/), on to [`hugo-theme-notes`](https://github.com/RealOrangeOne/hugo-theme-notes/), and finally here. diff --git a/docs/notes/mkdocs-nav-by-tag.md b/docs/notes/mkdocs-nav-by-tag.md new file mode 100644 index 0000000..80e829d --- /dev/null +++ b/docs/notes/mkdocs-nav-by-tag.md @@ -0,0 +1,16 @@ +--- +title: Navigate mkdocs by tag +tags: + - mkdocs +--- + +The sidebar for this notes site uses tags for the hierarchy, rather than by the filesystem structure. + +This works by retrieving the tags for each note, creating fake sections for each, and replacing the existing sections with those. + +!!! warning + Here be dragons. + +```python +{! ../hooks/tag_nav.py !} +``` diff --git a/hooks/notes.py b/hooks/notes.py index efd6609..7cf9f4e 100644 --- a/hooks/notes.py +++ b/hooks/notes.py @@ -1,8 +1,5 @@ import jinja2 -from mkdocs.structure.nav import Navigation, Section -from collections import defaultdict -from mkdocs.utils import meta -from mkdocs.plugins import event_priority +from mkdocs.structure.nav import Navigation @jinja2.pass_context def get_page(context, slug): @@ -33,48 +30,3 @@ def on_env(env, config, files): env.tests["startswith"] = str.startswith env.globals["get_page"] = get_page env.globals["get_notes"] = get_notes - - -class TagSection(Section): - """ - A modified section which is active if any of its children are active - (regardless of what mkdocs tells it). - """ - @property - def active(self): - return any(c.active for c in self.children) - - @active.setter - def active(self, value: bool): - pass - - -@event_priority(100) -def on_nav(nav: Navigation, config, files): - """ - Structure the nav sections by - """ - notes_section, notes = get_notes_from_nav(nav) - - notes_page = notes_section.children[0] - - pages_to_tag = defaultdict(list) - - orphan_pages = [] - - for note in notes: - with open(note.file.abs_src_path) as f: - _, metadata = meta.get_data(f.read()) - - if tags := metadata.get("tags"): - for tag in tags: - pages_to_tag[tag].append(note) - else: - orphan_pages.append(note) - - tag_sections = [ - TagSection(tag, pages) - for tag, pages in pages_to_tag.items() - ] - - notes_section.children = tag_sections + orphan_pages + [notes_page] diff --git a/hooks/tag_nav.py b/hooks/tag_nav.py new file mode 100644 index 0000000..506f929 --- /dev/null +++ b/hooks/tag_nav.py @@ -0,0 +1,55 @@ +import sys +import os + +sys.path.insert(0, os.path.dirname(__file__)) + +from notes import get_notes_from_nav +from mkdocs.structure.nav import Navigation, Section +from collections import defaultdict +from mkdocs.utils import meta +from mkdocs.plugins import event_priority + + +class TagSection(Section): + """ + A modified section which is active if any of its children are active + (regardless of what mkdocs tells it). + """ + @property + def active(self): + return any(c.active for c in self.children) + + @active.setter + def active(self, value: bool): + pass + + +@event_priority(100) +def on_nav(nav: Navigation, config, files): + """ + Structure the nav sections by tag + """ + notes_section, notes = get_notes_from_nav(nav) + + notes_page = notes_section.children[0] + + pages_to_tag = defaultdict(list) + + orphan_pages = [] + + for note in notes: + with open(note.file.abs_src_path) as f: + _, metadata = meta.get_data(f.read()) + + if tags := metadata.get("tags"): + for tag in tags: + pages_to_tag[tag].append(note) + else: + orphan_pages.append(note) + + tag_sections = [ + TagSection(tag, pages) + for tag, pages in pages_to_tag.items() + ] + + notes_section.children = tag_sections + orphan_pages + [notes_page] diff --git a/mkdocs.yml b/mkdocs.yml index 1674616..3522171 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -53,6 +53,7 @@ theme: hooks: - hooks/notes.py + - hooks/tag_nav.py # Extensions markdown_extensions: