Markdown notes that tag themselves.
NoteFlow is a local Markdown notes system with two interfaces: a fast CLI for writing from the terminal, and a Flask web server for reading notes as clean, syntax-highlighted HTML. Basically a personal Notion — local, offline, and yours.
You never touch a tag.
Most notes apps make tagging a chore, so it never happens. NoteFlow reads what you wrote and figures out where it belongs.
Auto-tagging
No manual tagging. config.json defines a keyword → tag map — things like "binary search": "DSA", "flask": "Web-Dev", "docker": "DevOps". Every time you run noteflow.py new, the note's content is scanned case-insensitively against every keyword, and matching tags are attached automatically into the note's frontmatter.
Tag filtering
The web UI sidebar lists every tag currently in use across your notes. Click one — say DSA — and the note list is filtered server-side to only notes carrying that tag, via a plain GET /?tag=DSA. No client-side state, no JS framework.
Highlighted search
Search from the CLI with search, or from the web search box. On the web, the matching term is wrapped in <mark> and highlighted inline inside the rendered note — the highlighter walks rendered HTML and only touches text nodes, so a search hit that happens to sit inside a syntax-highlighted code block still highlights cleanly instead of breaking the markup.
What it looks like
Write from the terminal, read in the browser. Search once and the match is filtered in the list and highlighted inline on the note itself.
- SQL Joins ExplainedMay 18
A SQL JOIN combines rows from two or more tables based on a related column. INNER JOIN returns only matching rows...
Database - Binary Search NotesMay 14
Binary search runs in O(log n) time by repeatedly halving the search interval over a sorted array...
DSA - Flask Routing BasicsMay 11
Routes map a URL path to a view function via @app.route(). Dynamic segments like <slug> are passed as arguments...
Web-Dev - Docker BasicsMay 9
A Dockerfile describes an image layer by layer. docker build tags an image; docker run starts a container from it...
DevOps - Git CheatsheetMay 6
git commit -m records staged changes. git rebase -i rewrites history interactively. Use git stash to shelve work...
Tools
# Binary Search
# O(log n) search over a sorted array
def binary_search(arr, target):
lo, hi = 0, len(arr) - 1
while lo <= hi:
mid = (lo + hi) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
lo = mid + 1
else:
hi = mid - 1markdown (fenced_code + codehilite) → served with a Pygments-generated /pygments.css$ python noteflow.py new "Binary Search Notes" \
--content "Binary search runs in O(log n)..."
Saved note: Binary Search Notes
file: notes/binary-search-notes.md
auto-tags: DSA
$ python noteflow.py search "binary search"
- Binary Search Notes [DSA]
...runs in O(log n) time by repeatedly halving the search interval...Key concepts & stack
CLI subcommands
argparse wires new / list / search / serve into one entry point, noteflow.py.
Frontmatter storage
Every note is a plain .md file with a lightweight header: title, slug, created, tags.
Markdown → HTML
The markdown library renders bodies with fenced_code, codehilite, tables, and toc extensions.
Pygments highlighting
Fenced code blocks are syntax-highlighted and styled via a generated /pygments.css route.
Auto-tag engine
auto_tag() scans content against config.json's keyword map so the taxonomy grows without code changes.
Safe inline highlighting
highlight_text() splits rendered HTML into tag/text segments so only text nodes get wrapped in <mark>.
Two interfaces, one notes folder
Install once, then write from the terminal and read in the browser — both point at the same notes/ directory.
Setup
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txtCLI — write
- 1Create a note (content via flag, file, or piped stdin):
python noteflow.py new "My Note" \ --content "..." - 2List every note with its auto-extracted tags:
python noteflow.py list - 3Full-text search from the terminal:
python noteflow.py search "binary search"
Web — read
- 1Start the Flask server:
python noteflow.py serve - 2Open it in your browser:
http://localhost:5000 - 3Browse rendered notes, filter by tag, or search — matches highlight inline on the note page.
python noteflow.py serve \ --port 5050 --debug