termflow-md 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. termflow_md-0.1.0/.github/workflows/ci.yml +67 -0
  2. termflow_md-0.1.0/.github/workflows/publish.yml +30 -0
  3. termflow_md-0.1.0/.gitignore +107 -0
  4. termflow_md-0.1.0/CHANGELOG.md +72 -0
  5. termflow_md-0.1.0/LICENSE +21 -0
  6. termflow_md-0.1.0/PKG-INFO +330 -0
  7. termflow_md-0.1.0/README.md +295 -0
  8. termflow_md-0.1.0/demo.py +244 -0
  9. termflow_md-0.1.0/examples/config.toml +78 -0
  10. termflow_md-0.1.0/pyproject.toml +119 -0
  11. termflow_md-0.1.0/termflow/__init__.py +58 -0
  12. termflow_md-0.1.0/termflow/__main__.py +6 -0
  13. termflow_md-0.1.0/termflow/ansi/__init__.py +103 -0
  14. termflow_md-0.1.0/termflow/ansi/codes.py +92 -0
  15. termflow_md-0.1.0/termflow/ansi/color.py +160 -0
  16. termflow_md-0.1.0/termflow/ansi/style.py +51 -0
  17. termflow_md-0.1.0/termflow/ansi/utils.py +352 -0
  18. termflow_md-0.1.0/termflow/cli.py +310 -0
  19. termflow_md-0.1.0/termflow/config/__init__.py +23 -0
  20. termflow_md-0.1.0/termflow/config/config.py +251 -0
  21. termflow_md-0.1.0/termflow/core/__init__.py +37 -0
  22. termflow_md-0.1.0/termflow/core/enums.py +151 -0
  23. termflow_md-0.1.0/termflow/core/state.py +549 -0
  24. termflow_md-0.1.0/termflow/parser/__init__.py +123 -0
  25. termflow_md-0.1.0/termflow/parser/entities.py +66 -0
  26. termflow_md-0.1.0/termflow/parser/events.py +352 -0
  27. termflow_md-0.1.0/termflow/parser/inline.py +303 -0
  28. termflow_md-0.1.0/termflow/parser/parser.py +662 -0
  29. termflow_md-0.1.0/termflow/render/__init__.py +134 -0
  30. termflow_md-0.1.0/termflow/render/code.py +190 -0
  31. termflow_md-0.1.0/termflow/render/heading.py +123 -0
  32. termflow_md-0.1.0/termflow/render/list.py +186 -0
  33. termflow_md-0.1.0/termflow/render/renderer.py +602 -0
  34. termflow_md-0.1.0/termflow/render/style.py +145 -0
  35. termflow_md-0.1.0/termflow/render/table.py +236 -0
  36. termflow_md-0.1.0/termflow/render/text.py +203 -0
  37. termflow_md-0.1.0/termflow/syntax/__init__.py +32 -0
  38. termflow_md-0.1.0/termflow/syntax/highlighter.py +506 -0
  39. termflow_md-0.1.0/test_document.md +341 -0
  40. termflow_md-0.1.0/tests/__init__.py +1 -0
  41. termflow_md-0.1.0/tests/conftest.py +162 -0
  42. termflow_md-0.1.0/tests/test_ansi.py +216 -0
  43. termflow_md-0.1.0/tests/test_config.py +213 -0
  44. termflow_md-0.1.0/tests/test_inline.py +175 -0
  45. termflow_md-0.1.0/tests/test_integration.py +348 -0
  46. termflow_md-0.1.0/tests/test_parser.py +353 -0
  47. termflow_md-0.1.0/tests/test_renderer.py +255 -0
  48. termflow_md-0.1.0/tests/test_syntax.py +191 -0
  49. termflow_md-0.1.0/uv.lock +897 -0
@@ -0,0 +1,67 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+ push:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ quality:
11
+ name: Quality (${{ matrix.python-version }})
12
+ runs-on: ubuntu-latest
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ python-version: ["3.11", "3.12", "3.13"]
17
+
18
+ steps:
19
+ - name: Checkout code
20
+ uses: actions/checkout@v4
21
+
22
+ - name: Install uv
23
+ uses: astral-sh/setup-uv@v4
24
+ with:
25
+ enable-cache: true
26
+
27
+ - name: Set up Python ${{ matrix.python-version }}
28
+ run: uv python install ${{ matrix.python-version }}
29
+
30
+ - name: Install dependencies
31
+ run: uv sync --all-extras
32
+
33
+ - name: Lint with ruff
34
+ run: uvx ruff check .
35
+
36
+ - name: Format check with ruff
37
+ run: uvx ruff format --check .
38
+
39
+ - name: Type check with mypy
40
+ run: uv run mypy termflow --ignore-missing-imports
41
+ continue-on-error: true # Optional for now
42
+
43
+ - name: Run tests
44
+ run: uv run pytest tests/ -v --tb=short
45
+
46
+ build:
47
+ name: Build Package
48
+ runs-on: ubuntu-latest
49
+ steps:
50
+ - name: Checkout code
51
+ uses: actions/checkout@v4
52
+
53
+ - name: Install uv
54
+ uses: astral-sh/setup-uv@v4
55
+
56
+ - name: Build package
57
+ run: uv build
58
+
59
+ - name: Check distribution
60
+ run: uvx twine check dist/*
61
+
62
+ - name: Upload artifacts
63
+ uses: actions/upload-artifact@v4
64
+ with:
65
+ name: dist
66
+ path: dist/
67
+ retention-days: 5
@@ -0,0 +1,30 @@
1
+ # Publishes to PyPI on release
2
+ # Set PYPI_API_TOKEN in repo secrets
3
+
4
+ name: Publish to PyPI
5
+
6
+ on:
7
+ release:
8
+ types: [published]
9
+ workflow_dispatch:
10
+
11
+ jobs:
12
+ build-publish:
13
+ runs-on: ubuntu-latest
14
+ permissions:
15
+ contents: write
16
+ steps:
17
+ - name: Checkout code
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Install uv
21
+ uses: astral-sh/setup-uv@v4
22
+
23
+ - name: Build package
24
+ run: uv build
25
+
26
+ - name: Publish to PyPI
27
+ env:
28
+ TWINE_USERNAME: __token__
29
+ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
30
+ run: uvx twine upload dist/*
@@ -0,0 +1,107 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+ MANIFEST
27
+
28
+ # PyInstaller
29
+ *.manifest
30
+ *.spec
31
+
32
+ # Installer logs
33
+ pip-log.txt
34
+ pip-delete-this-directory.txt
35
+
36
+ # Unit test / coverage reports
37
+ htmlcov/
38
+ .tox/
39
+ .nox/
40
+ .coverage
41
+ .coverage.*
42
+ .cache
43
+ nosetests.xml
44
+ coverage.xml
45
+ *.cover
46
+ *.py,cover
47
+ .hypothesis/
48
+ .pytest_cache/
49
+
50
+ # Translations
51
+ *.mo
52
+ *.pot
53
+
54
+ # Environments
55
+ .env
56
+ .venv
57
+ env/
58
+ venv/
59
+ ENV/
60
+ env.bak/
61
+ venv.bak/
62
+
63
+ # IDE
64
+ .idea/
65
+ .vscode/
66
+ *.swp
67
+ *.swo
68
+ *~
69
+ .project
70
+ .pydevproject
71
+ .settings/
72
+ *.sublime-project
73
+ *.sublime-workspace
74
+
75
+ # Linting / Type checking
76
+ .ruff_cache/
77
+ .mypy_cache/
78
+ .dmypy.json
79
+ dmypy.json
80
+
81
+ # Jupyter Notebook
82
+ .ipynb_checkpoints
83
+
84
+ # pyenv
85
+ .python-version
86
+
87
+ # uv cache
88
+ .uv/
89
+
90
+ # OS files
91
+ .DS_Store
92
+ .DS_Store?
93
+ ._*
94
+ .Spotlight-V100
95
+ .Trashes
96
+ ehthumbs.db
97
+ Thumbs.db
98
+
99
+ # Local development
100
+ *.local
101
+ *.log
102
+ tmp/
103
+ temp/
104
+
105
+ # Documentation builds
106
+ docs/_build/
107
+ site/
@@ -0,0 +1,72 @@
1
+ # Changelog
2
+
3
+ All notable changes to termflow will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2025-01-XX
11
+
12
+ ### Added
13
+
14
+ - Initial release of termflow 🌊
15
+ - Streaming markdown parser with event-based architecture
16
+ - Terminal renderer with ANSI true-color (24-bit) support
17
+ - Syntax highlighting via Pygments (100+ languages supported)
18
+ - CLI tool (`tf`) with streaming support
19
+ - Configuration via TOML files
20
+
21
+ #### Markdown Support
22
+
23
+ - **Headings** (H1-H6) with distinct visual styles
24
+ - H1: Centered, bold, bright color with double-line underline
25
+ - H2: Bold, bright color with underline
26
+ - H3-H6: Progressively subtle styling
27
+ - **Code blocks** with:
28
+ - Unicode box drawing borders (╭╮╰╯│─)
29
+ - Language labels
30
+ - Syntax highlighting
31
+ - OSC 52 clipboard integration
32
+ - **Inline code** with background highlighting
33
+ - **Text formatting**: bold, italic, underline, strikethrough
34
+ - **Lists**:
35
+ - Bullet lists with cycling bullets (• ◦ ▪ ▫ ▸ ▹)
36
+ - Ordered lists with multiple styles (1. a) i. A))
37
+ - Nested lists with proper indentation
38
+ - **Tables** with Unicode box drawing borders
39
+ - **Block quotes** with vertical bar prefix
40
+ - **Think blocks** for LLM chain-of-thought (`<think>...</think>`)
41
+ - **Horizontal rules**
42
+ - **Links** with OSC 8 hyperlink support
43
+ - **Images** (displayed as alt text with 🖼 icon)
44
+ - **Footnotes**
45
+
46
+ #### CLI Features
47
+
48
+ - `tf <file>` - Render markdown file
49
+ - `cat file.md | tf` - Pipe markdown input
50
+ - `-w, --width` - Set terminal width
51
+ - `--style` - Choose color preset (default, dracula, nord, gruvbox)
52
+ - `--syntax-style` - Choose Pygments syntax style
53
+ - `--no-clipboard` - Disable OSC 52 clipboard
54
+ - `--no-hyperlinks` - Disable OSC 8 links
55
+ - `--no-pretty` - Disable decorative borders
56
+ - `--list-syntax-styles` - List available syntax styles
57
+
58
+ #### Configuration
59
+
60
+ - TOML configuration file support
61
+ - Search order: `$TERMFLOW_CONFIG` → `~/.config/termflow/config.toml` → `~/.termflow.toml`
62
+ - Customizable colors, features, and syntax style
63
+
64
+ #### Style Presets
65
+
66
+ - **default**: Soft, readable colors for dark backgrounds
67
+ - **dracula**: Purple-tinted dark theme
68
+ - **nord**: Arctic, bluish color scheme
69
+ - **gruvbox**: Warm, retro color scheme
70
+
71
+ [Unreleased]: https://github.com/username/termflow/compare/v0.1.0...HEAD
72
+ [0.1.0]: https://github.com/username/termflow/releases/tag/v0.1.0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 termflow contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,330 @@
1
+ Metadata-Version: 2.4
2
+ Name: termflow-md
3
+ Version: 0.1.0
4
+ Summary: A streaming markdown renderer for modern terminals
5
+ Project-URL: Homepage, https://github.com/mpfaffenberger/termflow
6
+ Project-URL: Repository, https://github.com/mpfaffenberger/termflow
7
+ Project-URL: Documentation, https://github.com/mpfaffenberger/termflow#readme
8
+ Project-URL: Issues, https://github.com/mpfaffenberger/termflow/issues
9
+ Author-email: Your Name <your.email@example.com>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: ansi,cli,markdown,renderer,streaming,syntax-highlighting,terminal
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Terminals
23
+ Classifier: Topic :: Text Processing :: Markup :: Markdown
24
+ Classifier: Typing :: Typed
25
+ Requires-Python: >=3.11
26
+ Requires-Dist: pygments>=2.17.0
27
+ Requires-Dist: wcwidth>=0.2.12
28
+ Provides-Extra: dev
29
+ Requires-Dist: mypy>=1.10.0; extra == 'dev'
30
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
31
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
32
+ Requires-Dist: ruff>=0.4.0; extra == 'dev'
33
+ Requires-Dist: twine>=6.0.0; extra == 'dev'
34
+ Description-Content-Type: text/markdown
35
+
36
+ <div align="center">
37
+
38
+ <!-- Logo placeholder -->
39
+ <!-- <img src="assets/logo.png" alt="termflow logo" width="200"/> -->
40
+
41
+ # termflow 🌊
42
+
43
+ **A streaming markdown renderer for modern terminals**
44
+
45
+ [![PyPI version](https://img.shields.io/pypi/v/termflow.svg)](https://pypi.org/project/termflow/)
46
+ [![Python versions](https://img.shields.io/pypi/pyversions/termflow.svg)](https://pypi.org/project/termflow/)
47
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
48
+ [![Build status](https://img.shields.io/github/actions/workflow/status/your-username/termflow/ci.yml?branch=main)](https://github.com/your-username/termflow/actions)
49
+
50
+ *Perfect for rendering LLM output in real-time.*
51
+
52
+ </div>
53
+
54
+ ---
55
+
56
+ ## ✨ Features
57
+
58
+ - **📡 Streaming Rendering** - Render markdown as it arrives, line by line
59
+ - **🎨 Syntax Highlighting** - Beautiful code blocks powered by Pygments
60
+ - **📊 Tables** - Full support for GitHub-flavored markdown tables
61
+ - **📝 Lists** - Ordered, unordered, and nested lists with smart indentation
62
+ - **💻 Code Blocks** - Fenced code blocks with language detection and clipboard support
63
+ - **💭 Think Blocks** - Special rendering for `<think>` tags (great for LLM chain-of-thought)
64
+ - **🔗 Hyperlinks** - OSC 8 clickable links in supported terminals
65
+ - **📋 Clipboard** - OSC 52 clipboard integration for code blocks
66
+ - **🎛️ Configurable** - Customize colors, styles, and features via TOML config
67
+ - **⚡ Fast** - Lightweight and performant, minimal dependencies
68
+
69
+ ## 🚀 Quick Installation
70
+
71
+ ### Using uvx (recommended)
72
+
73
+ ```bash
74
+ uvx termflow
75
+ ```
76
+
77
+ ### Using pip
78
+
79
+ ```bash
80
+ pip install termflow-md
81
+ ```
82
+
83
+ ### From source
84
+
85
+ ```bash
86
+ git clone https://github.com/your-username/termflow.git
87
+ cd termflow
88
+ pip install -e ".[dev]"
89
+ ```
90
+
91
+ ## 📖 Usage
92
+
93
+ ### Command Line
94
+
95
+ ```bash
96
+ # Render a file
97
+ tf README.md
98
+
99
+ # Pipe markdown content
100
+ echo "# Hello World" | tf
101
+
102
+ # Pipe from LLM output
103
+ curl -s https://api.example.com/chat | tf
104
+
105
+ # Set terminal width
106
+ tf -w 100 document.md
107
+
108
+ # Use a color preset
109
+ tf --style dracula README.md
110
+
111
+ # Use a syntax highlighting theme
112
+ tf --syntax-style nord file.md
113
+
114
+ # Disable clipboard integration
115
+ tf --no-clipboard document.md
116
+
117
+ # List available syntax styles
118
+ tf --list-syntax-styles
119
+ ```
120
+
121
+ ### CLI Options
122
+
123
+ ```
124
+ usage: tf [-h] [-w N] [-c PATH] [--style {default,dracula,nord,gruvbox}]
125
+ [--syntax-style NAME] [--list-syntax-styles] [--no-clipboard]
126
+ [--no-hyperlinks] [--no-pretty] [-V]
127
+ [file]
128
+
129
+ options:
130
+ -h, --help show this help message and exit
131
+ -w, --width N Terminal width (default: auto-detect)
132
+ -c, --config PATH Path to config file
133
+ --style PRESET Color style preset (default, dracula, nord, gruvbox)
134
+ --syntax-style NAME Pygments syntax highlighting style
135
+ --list-syntax-styles List available syntax highlighting styles
136
+ --no-clipboard Disable OSC 52 clipboard for code blocks
137
+ --no-hyperlinks Disable OSC 8 hyperlinks
138
+ --no-pretty Disable pretty code block borders
139
+ -V, --version show program's version number and exit
140
+ ```
141
+
142
+ ### Programmatic Usage
143
+
144
+ ```python
145
+ from termflow import Parser, Renderer, render_markdown
146
+
147
+ # Quick rendering to stdout
148
+ render_markdown("# Hello World!")
149
+
150
+ # Render to a file or buffer
151
+ from io import StringIO
152
+
153
+ output = StringIO()
154
+ render_markdown("# Hello\n\nThis is **bold** text.", output=output)
155
+ print(output.getvalue())
156
+ ```
157
+
158
+ ### Streaming Mode
159
+
160
+ For real-time rendering of streaming content (e.g., LLM responses):
161
+
162
+ ```python
163
+ from termflow import Parser, Renderer
164
+ import sys
165
+
166
+ # Create parser and renderer
167
+ parser = Parser()
168
+ renderer = Renderer(output=sys.stdout, width=80)
169
+
170
+ # Process markdown line by line as it streams in
171
+ for line in markdown_stream:
172
+ events = parser.parse_line(line)
173
+ renderer.render_all(events)
174
+
175
+ # Finalize to close any open blocks
176
+ renderer.render_all(parser.finalize())
177
+ ```
178
+
179
+ ### Custom Styling
180
+
181
+ ```python
182
+ from termflow import Renderer, RenderStyle, RenderFeatures
183
+ from io import StringIO
184
+
185
+ # Use a preset style
186
+ style = RenderStyle.dracula() # or .nord(), .gruvbox()
187
+
188
+ # Or create a custom style
189
+ style = RenderStyle(
190
+ bright="#87ceeb", # Main accent color
191
+ head="#98fb98", # Heading color
192
+ symbol="#dda0dd", # Bullets, borders
193
+ link="#87cefa", # Link color
194
+ )
195
+
196
+ # Configure features
197
+ features = RenderFeatures(
198
+ clipboard=True, # OSC 52 clipboard support
199
+ hyperlinks=True, # OSC 8 clickable links
200
+ pretty_pad=True, # Pretty code block borders
201
+ )
202
+
203
+ # Create renderer with custom config
204
+ output = StringIO()
205
+ renderer = Renderer(
206
+ output=output,
207
+ width=100,
208
+ style=style,
209
+ features=features,
210
+ )
211
+ ```
212
+
213
+ ## 🔧 Configuration
214
+
215
+ Create a config file at `~/.config/termflow/config.toml`:
216
+
217
+ ```toml
218
+ # Terminal width (null = auto-detect)
219
+ width = null
220
+ max_width = 120
221
+
222
+ # Pygments syntax highlighting style
223
+ syntax_style = "monokai"
224
+
225
+ # Color scheme
226
+ [style]
227
+ bright = "#87ceeb" # Main accent color
228
+ head = "#98fb98" # Heading color
229
+ symbol = "#dda0dd" # Bullets, table borders, code block borders
230
+ grey = "#808080" # Muted text
231
+ dark = "#404040" # Dark accents
232
+ mid = "#a0a0a0" # Medium text
233
+ light = "#d0d0d0" # Light accents
234
+ link = "#87cefa" # Hyperlink color
235
+ error = "#ff6b6b" # Error messages
236
+
237
+ # Feature toggles
238
+ [features]
239
+ clipboard = true # OSC 52 clipboard for code blocks
240
+ hyperlinks = true # OSC 8 clickable links
241
+ pretty_pad = true # Pretty unicode borders on code blocks
242
+ ```
243
+
244
+ You can also set the config path via environment variable:
245
+
246
+ ```bash
247
+ export TERMFLOW_CONFIG=/path/to/config.toml
248
+ ```
249
+
250
+ ## 🎨 Style Presets
251
+
252
+ termflow includes several built-in color presets:
253
+
254
+ | Preset | Description |
255
+ |--------|-------------|
256
+ | `default` | Soft pastel colors |
257
+ | `dracula` | Purple-tinted dark theme |
258
+ | `nord` | Arctic, bluish color palette |
259
+ | `gruvbox` | Retro, earthy colors |
260
+
261
+ Use them via CLI:
262
+
263
+ ```bash
264
+ tf --style dracula README.md
265
+ ```
266
+
267
+ Or programmatically:
268
+
269
+ ```python
270
+ from termflow import RenderStyle
271
+
272
+ style = RenderStyle.dracula()
273
+ style = RenderStyle.nord()
274
+ style = RenderStyle.gruvbox()
275
+ ```
276
+
277
+ ## 💭 Think Block Support
278
+
279
+ termflow has special support for `<think>` blocks, commonly used in LLM
280
+ chain-of-thought prompting:
281
+
282
+ ```markdown
283
+ <think>
284
+ Let me reason through this step by step...
285
+ 1. First, I'll analyze the problem
286
+ 2. Then, I'll formulate a solution
287
+ </think>
288
+
289
+ Here's my answer based on my reasoning above.
290
+ ```
291
+
292
+ Think blocks are rendered with a distinct style to visually separate the
293
+ model's reasoning from its final response.
294
+
295
+ ## 🦀 Origin
296
+
297
+ termflow is a Python port of [streamdown-rs](https://github.com/streamdown-rs/streamdown),
298
+ a high-performance streaming markdown renderer written in Rust. This project brings
299
+ the same streaming rendering capabilities to the Python ecosystem with a clean,
300
+ Pythonic API.
301
+
302
+ ## 🤝 Contributing
303
+
304
+ Contributions are welcome! Please feel free to submit a Pull Request.
305
+
306
+ ```bash
307
+ # Clone and install for development
308
+ git clone https://github.com/your-username/termflow.git
309
+ cd termflow
310
+ pip install -e ".[dev]"
311
+
312
+ # Run tests
313
+ pytest tests/ -v
314
+
315
+ # Run linter
316
+ ruff check .
317
+ ruff format .
318
+ ```
319
+
320
+ ## 📄 License
321
+
322
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
323
+
324
+ ---
325
+
326
+ <div align="center">
327
+
328
+ Made with ❤️ for the terminal
329
+
330
+ </div>