Terminal tile presenter for structured markdown content.
Navigate a hierarchy of sections → tiles → detail views. Everything — structure, titles, colors, borders, fills — is declared in markdown files. The renderer has zero domain knowledge.
mosaic [content_dir | file.md]
Main view — sections as tiles
Section view — tiles inside a section
Detail view — full markdown content
curl -fsSL https://raw.githubusercontent.com/macino/mosaic/main/install.sh | shInstalls to ~/.local/bin/mosaic. Requires Python 3.6+, Unix/Linux/macOS.
mosaic # runs built-in demo (content/ directory)
mosaic ~/my/docs # directory-based content
mosaic notes.md # single flat markdown filecontent/
├── index.md ← optional: sets app title
├── section-a/
│ ├── index.md ← required: section title, style, order, summary
│ ├── tile-one.md ← subsection tile
│ └── tile-two.md
└── section-b/
├── index.md
└── ...
Sections are discovered alphabetically from subdirectories. Each directory with an index.md becomes a section. Files without index.md are skipped with a warning.
Optional. Sets the app title shown in the top bar.
---
title: My App
------
title: Section Name
style: GREEN
order: tile-one, tile-two, tile-three
---
Summary text shown in the main grid view.
Can be multiple lines.| field | required | description |
|---|---|---|
title |
no | Display name. Defaults to directory name. |
style |
no | Named style preset. Defaults to default. |
order |
no | Comma-separated list of subsection ids (stems). Defaults to alphabetical. |
| body | no | Summary text shown in main grid. |
---
title: Tile Name
style: CYAN
style.bg: BLACK
style.border: bold
---
Preview text shown in tile.
Multiple lines OK.
---
# Full content heading
Detail view content here. Supports full markdown rendering.
- Bullet list
- Another item
**Bold** and *italic* and `code` are rendered.The body has two sections separated by ---:
- Before second
---: preview text (shown in tile grid) - After second
---: full content (shown in detail view)
If there's no --- separator, all text is shown in detail but tile preview is empty.
Pass a single .md file instead of a directory. Headings become the navigation hierarchy.
mosaic notes.md
| heading level | role |
|---|---|
# H1 |
App title (not a tile) |
## H2 |
Top-level tiles |
### H3 |
Sub-tiles under the H2 above |
#### H4+ |
Further nesting, as deep as needed |
Leaf nodes (headings with no sub-headings) open as detail views. Non-leaf nodes drill into the next level.
Add an HTML comment on the first line after the heading:
## Alerts
<!-- style: RED; style.bg: BLACK; style.border: bold -->
Preview text shown in tile.
---
Full detail content here.The comment accepts the same fields as frontmatter: style, style.fg, style.bg, style.fill, style.border, style.attrs.
Same separator as directory mode: --- on its own line. Text before = tile preview; text after = detail view.
# My Notes
## Projects
<!-- style: CYAN; style.bg: BLACK -->
Active work.
### Website Redesign
<!-- style: CYAN; style.bg: BLACK; style.border: bold -->
Due next month.
---
# Website Redesign
- wireframes done
- awaiting content from marketing
### API Migration
<!-- style: YELLOW; style.bg: BLACK -->
In progress.
---
# API Migration
Migrating from v2 to v3 endpoints.
## Reference
<!-- style: MAGENTA; style.bg: BLACK; style.border: double -->
Docs and links.
---
# Reference
...Display name for the section or tile.
Named preset from the built-in STYLES dict. Available presets:
| name | fg | border | fill |
|---|---|---|---|
RED |
red | bold | space |
GREEN |
green | single | space |
YELLOW |
yellow | single | space |
CYAN |
cyan | single | space |
MAGENTA |
magenta | double | space |
WHITE |
white | single | space |
default |
white | single | space |
Override foreground color. Values: RED GREEN YELLOW CYAN MAGENTA WHITE BLACK BLUE
Override background color. Same values as style.fg. Use BLACK for explicit dark background, or omit for terminal default (-1).
Override fill character used to paint tile interior. Any single character. Common choices:
(space) clean / no texture
· subtle dots
░ light shade
▒ medium shade
▓ dark shade
▪ small squares
Override border style. Values: single double bold none
Override text attributes. Values: BOLD or empty (normal).
Comma-separated list of subsection file stems defining display order.
order: intro, quickstart, advanced, faq
The style system follows a browser-model cascade:
STYLES['default']— baseline (white, single border, space fill)- Named preset from
style: NAME— overrides default - Inline
style.field: value— overrides individual fields
Example combining preset + overrides:
---
title: Alert
style: RED
style.fg: WHITE
style.bg: RED
style.fill: ▒
---Result: white text on red background, medium-shade fill, bold border (from RED preset).
Four built-in presets:
single ┌──┐ double ╔══╗ bold ┏━━┓ none (no border)
│ │ ║ ║ ┃ ┃
└──┘ ╚══╝ ┗━━┛
Custom inline border dict (in Python, not frontmatter):
{'top': '~', 'bottom': '~', 'left': '|', 'right': '|',
'tl': '+', 'tr': '+', 'bl': '+', 'br': '+'}Avoid duplicating content that belongs in multiple sections:
---
title: Shared Topic
style: MAGENTA
---
<!-- include: ../shared-topic.md -->The renderer replaces the entire body with the referenced file's content (frontmatter stripped). Only one include per file. Path is relative to the containing file.
| key | action |
|---|---|
← → |
Select section (main) / navigate tiles (section) / prev-next subsection (detail) |
↑ ↓ |
Navigate tile rows (section) / scroll (detail) |
Enter |
Expand section / open tile |
Esc |
Back |
? |
Help overlay |
q |
Quit |
| action | effect |
|---|---|
| Click tile | Select + open |
| Scroll wheel | Scroll in detail view |
| syntax | renders as |
|---|---|
# H1 |
Full-width reversed block |
## H2 |
Bold, section color |
### H3 |
Bold, indented |
--- / *** / ___ |
Horizontal rule ───── |
- item * item |
• item bullet |
1. item |
Numbered list |
> text |
│ text blockquote |
```...``` |
Indented code block |
`code` |
Inline reversed |
**bold** |
Bold |
*italic* |
Underline |
Flat file (simplest):
mosaic my-notes.mdStructure with # headings — see Flat-file mode above.
Directory (more control):
- Create a directory:
mkdir ~/my-mosaic - Create sections:
mkdir ~/my-mosaic/section-one - Add
index.mdto each section - Add subsection
.mdfiles - Run:
mosaic ~/my-mosaic
Minimal example:
my-mosaic/
├── index.md ← title: My Project
└── overview/
├── index.md ← title: Overview, style: CYAN
└── intro.md ← title: Introduction
overview/intro.md:
---
title: Introduction
style: CYAN
style.bg: BLACK
---
Short preview text.
---
# Introduction
Full content here.

