Files
orgweb/README.md
2026-02-16 09:18:24 -07:00

139 lines
4.4 KiB
Markdown

# Org Web Adapter
A lightweight local web app for browsing and editing Org files.
The app is implemented as a single Python server (`main.py`) plus one HTML template (`templates/index.html`) and one stylesheet (`static/style.css`). It scans a notes directory for `.org` files and renders a 3-pane UI.
⚠️ There is no authentication or encryption, only run this service on trusted networks. ⚠️
## Screenshots
### Desktop
![Desktop view](media/desktop.png)
### Mobile
![Mobile view](media/mobile.png)
## Instructions
1. Symlink your notes directory to `notes`.
2. Edit the bind address and port in `config.yaml` if desired.
3. `python3 main.py`.
## How's it work?
1. `main.py` starts an HTTP server.
2. On each page request (`GET /`), it rescans the notes directory for `.org` files.
3. It resolves links/backlinks and builds HTML fragments.
4. It injects those fragments into `templates/index.html` placeholders:
- `{{NAV_ITEMS}}`
- `{{MAIN_CONTENT}}`
- `{{BACKLINKS}}`
5. Browser JS in `templates/index.html` handles client-side interactions (search, shuffle, sorting, jump-to-current, theme toggle).
## Server-side components (`main.py`)
- File discovery and parsing:
- `scan_org_files(...)` recursively finds `.org` files.
- Extracts title from `#+TITLE:` and ID from `:ID:`.
- Org link/backlink handling:
- `resolve_link_target(...)` supports `file:...` and `id:...` links.
- `find_backlinks(...)` computes notes linking to the selected note.
- `build_backlink_counts(...)` computes backlink totals for sorting.
- Rendering:
- `render_org_to_html(...)` converts headings (`*`, `**`, ...) and paragraphs to simple HTML.
- `render_line_with_links(...)` converts org links in text to clickable app links where resolvable.
- `truncate_label(...)` caps sidebar labels to 32 chars with `...`.
- Editing:
- `POST /edit` updates a selected `.org` file and redirects back with status flags.
- Static files:
- `serve_static(...)` serves files under `static/` with path traversal protection.
## Frontend components
- `templates/index.html`:
- Base layout markup.
- Sidebar controls.
- Small JS controller for filtering/sorting/shuffling nav links.
- MathJax initialization for inline `$...$` rendering.
- `static/style.css`:
- 3-column desktop grid and stacked mobile layout.
- Independent scroll regions for note list and backlinks.
- Mobile note-list cap (about 5 notes visible before scrolling).
## Configuration
Startup config is read from `config.yaml` by default.
- `bind_addr`: host/IP to bind
- `bind_port`: TCP port (must be `1..65535`)
Notes:
- If `config.yaml` is missing, defaults are `127.0.0.1:8000`.
- CLI flags `--host` and `--port` override config values.
- You can choose a different config file with `--config /path/to/config.yaml`.
## Useful run commands
```bash
python3 main.py --dir notes
python3 main.py --host 127.0.0.1 --port 9000
python3 main.py --config ./config.yaml
python3 main.py --no-browser
```
## Features
### Note browsing
- Recursive `.org` file discovery.
- Sidebar note list with active-note highlighting.
- Title/path search filter.
### Sidebar ordering controls
- Shuffle notes.
- Sort by backlink count (descending).
- Sort by created date (ascending).
- Notes without timestamps are treated as older than notes with timestamps.
- Jump to current note button.
### Backlinks
- Right sidebar lists notes linking to the current note.
- Supports both `file:` and `id:` link resolution.
### Editing
- Toggle Preview/Edit for the selected note.
- Save changes from browser to disk.
- Inline status messages for save success/errors.
### Math rendering
- Inline math rendering via MathJax using `$...$` delimiters.
### UI behavior
- Light/dark theme toggle (persisted in `localStorage`).
- Desktop: independent scrollable sidebars.
- Mobile: notes list capped with its own scroll area.
- Sidebar text truncation with ellipsis and tooltip for full text.
## Project layout
- `main.py`: server, parsing, rendering, routing.
- `templates/index.html`: page template + UI behavior JS.
- `static/style.css`: styling and responsive layout.
- `config.yaml`: bind config.
- `notes/`: notes directory (can be a symlink).
- `old_notes/`: alternate local notes snapshot.
## Limitations
- Not a full Org parser; rendering is intentionally simple.
- Notes are rescanned on each request (simple and fresh, but not optimized for huge note sets).
- Math rendering depends on loading MathJax from CDN.