markon 0.3.1

A lightweight Markdown renderer with GitHub styling and Medium-like annotations
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
# Markon

A lightweight Markdown renderer with GitHub styling and Medium-like annotation features, written in Rust.

![Markon Banner](banner.png)

English | [简体中文]README.zh.md

## Use Cases

Markon makes it easy to read, print, and annotate Markdown files in beautiful HTML format. Whether you're:

- **Reading documentation** on remote servers without a GUI
- **Reviewing and annotating** technical documents with highlights and notes
- **Printing** Markdown files with professional formatting
- **Presenting** Markdown content with GitHub-style rendering

Simply run `markon` in any directory to browse and render Markdown files with a clean, distraction-free interface.

## Features

### Core Features
- **GitHub Styling**: Complete GitHub Markdown CSS (dark/light themes)
-**Syntax Highlighting**: Powered by Syntect
-**GitHub Alerts**: Support for NOTE, TIP, IMPORTANT, WARNING, CAUTION
-**Emoji Support**: Unicode emoji shortcodes (e.g., `:smile:` → 😄)
-**Mermaid Diagrams**: Flowcharts, sequence diagrams, pie charts, etc.
-**Theme Switching**: Light, dark, and auto themes
-**Table Support**: GitHub Flavored Markdown (GFM) tables
-**Task Lists**: Checkbox task lists
-**Print Optimization**: Professional print styles with multilingual font support
-**Table of Contents**: Auto-generated TOC
-**Directory Browsing**: Auto-list Markdown files in current directory
-**Zero Dependencies**: All resources embedded in a single binary

### Medium-Style Annotation Features
- **Text Highlighting**: Add orange, green, or yellow highlights to selected text
-**Strikethrough**: Mark text with strikethrough
-**Notes**: Add annotation notes to highlighted text
-**Sidebar Display**: Note cards displayed on the right side, linked to highlights
-**Unhighlight**: Remove highlights from selected text
-**Persistent Storage**: Annotation data saved in browser local storage

## Installation

### From crates.io

```bash
cargo install markon
```

### From source

```bash
cargo install --path .
```

### Run directly without installing

```bash
cargo run -- [OPTIONS] [FILE]
```

## Usage

### Basic Usage

```bash
# Display list of Markdown files in current directory
markon

# Render a specific Markdown file
markon README.md

# Specify port
markon -p 8080 README.md

# Use dark theme
markon -t dark README.md

# Use light theme
markon -t light README.md

# Auto theme (based on system settings)
markon -t auto README.md
```

### Command Line Options

```
Usage: markon [OPTIONS] [FILE]

Arguments:
  [FILE]  The markdown file to render

Options:
  -p, --port <PORT>                The port to use for the server [default: 6419]
  -t, --theme <THEME>              Theme selection (light, dark, auto) [default: auto]
      --qr [<BASE_URL>]            Generate QR code for server address. Optionally specify a base URL (e.g., http://192.168.1.100:6419) to override the default local address
  -b, --open-browser [<BASE_URL>]  Automatically open browser after starting the server. Optionally specify a base URL (e.g., http://example.com:8080) to override the default local address
      --shared-annotation          Enable shared annotation mode. Annotations are stored in SQLite and synced across clients via WebSocket
  -h, --help                       Print help
  -V, --version                    Print version
```

### Advanced Usage Examples

```bash
# Generate QR code for easy mobile access (uses local address)
markon --qr

# Generate QR code with a custom base URL (e.g., when using port forwarding or public IP)
markon --qr http://192.168.1.100:6419

# Auto-open browser after starting (opens local address)
markon -b

# Auto-open with custom base URL (useful when behind reverse proxy)
# Server listens on localhost:6419, but accessible via proxy at example.com
markon -b http://example.com

# Combine options: QR code + auto-open + dark theme
markon --qr -b -t dark README.md

# Complete example: Custom port, QR for public IP, auto-open local browser
markon -p 8080 --qr http://203.0.113.1:8080 -b

# Enable shared annotation mode for real-time collaboration
markon --shared-annotation README.md
```

**Understanding URL Parameters**:

Both `--qr` and `-b` options accept optional URL arguments:

**QR Code (`--qr` option)**:
- Without argument (`--qr`): Generates QR code for `http://127.0.0.1:6419` (local address)
- With base URL (`--qr <BASE_URL>`): Generates QR code for the specified URL
- Use cases:
  - **Port forwarding**: `--qr http://192.168.1.100:6419` (LAN IP)
  - **Public access**: `--qr http://example.com/docs` (public domain)
  - **Mobile access**: `--qr http://your-laptop-ip:6419` (for phones on same network)

**Open Browser (`-b` option)**:
- Without argument (`-b`): Opens `http://127.0.0.1:6419` (local address)
- With base URL (`-b <BASE_URL>`): Opens the specified URL instead
- Use cases:
  - **Reverse proxy**: Server on `localhost:6419`, proxy at `https://docs.example.com`
  - **SSH tunnel**: Remote server tunneled to `http://localhost:8080`
  - **Custom routing**: Any URL that points to your running server instance

### Using Annotation Features

1. Open a Markdown file in your browser
2. Select any text to see the toolbar
3. Choose highlight color (orange/green/yellow), strikethrough, or note
4. Notes will appear on the right side of the page
5. Click highlighted text to view associated notes
6. Select highlighted text again to unhighlight

#### Two Annotation Modes

**Local Mode (Default)**:
- Annotation data is stored in browser's LocalStorage
- Limited to a single browser, not shared across browsers or devices
- Suitable for personal reading and annotation
- No additional configuration needed

**Shared Mode (`--shared-annotation`)**:
- Annotation data is stored in a SQLite database (default path: `~/.markon/annotation.sqlite`)
- Supports real-time synchronization across multiple clients via WebSocket
- Suitable for various collaboration scenarios:
  - Single-user multi-device: Sync annotations across phone, tablet, desktop, etc.
  - Team collaboration: Multiple users can simultaneously view and edit annotations on the same document
- Custom database path can be set via `MARKON_SQLITE_PATH` environment variable

```bash
# Use shared annotation mode
markon --shared-annotation README.md

# Customize database location
MARKON_SQLITE_PATH=/path/to/annotations.db markon --shared-annotation README.md
```

In both modes, you can use the "Clear Annotations" button at the bottom of the page to clear all annotations for the current page.

## Important Notes

### System Path Prefix

Markon uses `/_/` as a reserved path prefix for all system resources (CSS, JavaScript, WebSocket, favicon). This ensures complete separation between system files and your content:

- **Reserved path**: `/_/` (only this specific prefix)
- **What this means**: Do NOT create a directory named `_` (single underscore) in your working directory root
- **What you CAN do**:
  - ✅ Create directories like `_build/`, `__pycache__/`, `_test/`, `_cache/` (different from `_`)
  - ✅ Create directories like `ws/`, `static/`, `css/`, `js/` (no conflict!)
  - ✅ Use any file or directory names that don't start with exactly `_/`

**Examples**:
```bash
# ❌ This will conflict with system paths
mkdir _              # Don't create a single-underscore directory
markon               # System uses /_/css/*, /_/js/*, etc.

# ✅ All of these are perfectly fine
mkdir _build         # URL: /_build/* (not /_/*)
mkdir __pycache__    # URL: /__pycache__/* (not /_/*)
mkdir ws             # URL: /ws/* (not /_/ws - different!)
mkdir static         # URL: /static/* (not /_/*)
```

**When using reverse proxy**: Make sure to configure your proxy to forward the `/_/` path. See [REVERSE_PROXY.md](REVERSE_PROXY.md) ([中文版](REVERSE_PROXY.zh.md)) for detailed configuration examples for Nginx, Caddy, Apache, and Traefik.

## Supported Markdown Features

- **Headings** (H1-H6)
- **Bold/Italic/Strikethrough**
- **Lists** (ordered/unordered)
- **Task Lists** (- [ ] / - [x])
- **Tables**
- **Code Blocks** (with syntax highlighting)
- **Block Quotes**
- **Links and Images**
- **Horizontal Rules**
- **Footnotes**
- **Emoji** (:emoji_name:)
- **Mermaid Diagrams**
- **GitHub Alerts** ([!NOTE], [!TIP], etc.)

## Mermaid Diagram Example

Markon supports Mermaid diagram rendering using \`\`\`mermaid code blocks:

\`\`\`markdown
\`\`\`mermaid
graph TD
    A[Start] --> B{Decision}
    B -->|Yes| C[Action 1]
    B -->|No| D[Action 2]
\`\`\`
\`\`\`

Supported diagram types:
- Flowcharts (graph/flowchart)
- Sequence Diagrams (sequenceDiagram)
- Pie Charts (pie)
- Gantt Charts (gantt)
- Class Diagrams (classDiagram)
- State Diagrams (stateDiagram)
- And more...

## Emoji Support

Use standard emoji shortcodes:

```markdown
:smile: :heart: :rocket: :tada: :sparkles:
```

Result: 😄 ❤️ 🚀 🎉 ✨

## GitHub Alerts Example

Create alert boxes using special blockquote syntax:

```markdown
> [!NOTE]
> This is a note.

> [!TIP]
> This is a helpful tip.

> [!IMPORTANT]
> This is important information.

> [!WARNING]
> This is a warning.

> [!CAUTION]
> This is a serious warning.
```

Supported types:
- **NOTE** (blue) - General information
- **TIP** (green) - Helpful tips or suggestions
- **IMPORTANT** (purple) - Key information
- **WARNING** (yellow) - Important warnings
- **CAUTION** (red) - Dangerous or critical warnings

## Project Origin

This project is a Rust port of [go-grip](https://github.com/kookyleo/go-grip) with added Medium-style annotation features.

### Key Differences from go-grip

| Feature | go-grip | markon |
|---------|---------|--------|
| Language | Go | Rust |
| GitHub Alerts | ✅ | ✅ |
| Emoji | Custom mapping | Unicode (emojis crate) |
| Medium Annotations | ❌ | ✅ |
| Hot Reload | ✅ | ❌ |
| Auto Browser Open | ✅ | ✅ |
| QR Code Generation | ❌ | ✅ |
| Print Optimization | ✅ | ✅ |

## Tech Stack

### Backend
- **Markdown Parsing**: [pulldown-cmark](https://github.com/raphlinus/pulldown-cmark)
- **Syntax Highlighting**: [syntect](https://github.com/trishume/syntect)
- **HTTP Server**: [axum](https://github.com/tokio-rs/axum) + [tokio](https://tokio.rs/)
- **Template Engine**: [tera](https://github.com/Keats/tera)
- **Static Asset Embedding**: [rust-embed](https://github.com/pyrossh/rust-embed)
- **Emoji**: [emojis](https://github.com/rosetta-rs/emojis)

### Frontend
- **Diagram Rendering**: [Mermaid.js](https://mermaid.js.org/)
- **Styling**: [GitHub Markdown CSS](https://github.com/sindresorhus/github-markdown-css)
- **Annotations**: Vanilla JavaScript + LocalStorage

## Development

### Project Structure

```
markon/
├── src/
│   ├── main.rs         # Entry point
│   ├── server.rs       # HTTP server
│   ├── markdown.rs     # Markdown renderer
│   └── assets.rs       # Static asset management
├── assets/
│   ├── css/            # Stylesheets
│   │   ├── github-markdown-dark.css
│   │   ├── github-markdown-light.css
│   │   ├── github-print.css
│   │   └── editor.css  # Annotation styles
│   ├── js/             # JavaScript
│   │   ├── mermaid.min.js
│   │   └── editor.js   # Annotation logic
│   └── templates/      # HTML templates
│       ├── layout.html
│       └── directory.html
├── Cargo.toml
├── README.md
└── README.zh.md
```

### Build

```bash
# Debug mode
cargo build

# Release mode
cargo build --release

# Run tests
cargo test

# Lint
cargo clippy

# JavaScript lint
npx eslint assets/js/editor.js
```

## Contributing

We welcome all forms of contributions! Whether it's reporting bugs, suggesting new features, or submitting code improvements.

### How to Contribute

1. **Report Issues**: Submit bug reports or feature requests in [GitHub Issues]https://github.com/kookyleo/markon/issues
2. **Submit PRs**:
   - Fork the project
   - Create a feature branch (`git checkout -b feature/amazing-feature`)
   - Commit your changes (`git commit -m 'Add some amazing feature'`)
   - Push to the branch (`git push origin feature/amazing-feature`)
   - Open a Pull Request

### Code Standards

Before submitting a PR, please ensure:
- ✅ Run `cargo test` to ensure all tests pass
- ✅ Run `cargo clippy` to ensure code follows Rust best practices
- ✅ Run `cargo fmt` to format the code
- ✅ Run `npx eslint assets/js/editor.js` for JavaScript code

## License

Apache License 2.0

## Acknowledgments

- [go-grip]https://github.com/kookyleo/go-grip - Original project
- [GitHub Markdown CSS]https://github.com/sindresorhus/github-markdown-css - Styling source
- [Medium]https://medium.com - Annotation feature inspiration
- All open-source contributors

## Links

- Original project: https://github.com/kookyleo/go-grip
- GitHub Markdown CSS: https://github.com/sindresorhus/github-markdown-css
- Mermaid documentation: https://mermaid.js.org/