{"id":50472478,"url":"https://github.com/semcod/clickmd","last_synced_at":"2026-06-01T11:04:03.447Z","repository":{"id":342397858,"uuid":"1173837890","full_name":"semcod/clickmd","owner":"semcod","description":"Markdown rendering for CLI applications with syntax highlighting.","archived":false,"fork":false,"pushed_at":"2026-05-13T15:08:58.000Z","size":7975,"stargazers_count":0,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-13T17:16:10.163Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://wronai.github.io/clickmd/","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/semcod.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"docs/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-05T20:01:27.000Z","updated_at":"2026-05-13T15:31:48.000Z","dependencies_parsed_at":"2026-03-10T15:01:05.858Z","dependency_job_id":null,"html_url":"https://github.com/semcod/clickmd","commit_stats":null,"previous_names":["wronai/clickmd","semcod/clickmd"],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/semcod/clickmd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fclickmd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fclickmd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fclickmd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fclickmd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/semcod","download_url":"https://codeload.github.com/semcod/clickmd/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fclickmd/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33771633,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-01T02:00:06.963Z","response_time":115,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-01T11:04:03.380Z","updated_at":"2026-06-01T11:04:03.440Z","avatar_url":"https://github.com/semcod.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# clickmd\n\n[![PyPI version](https://badge.fury.io/py/clickmd.svg)](https://badge.fury.io/py/clickmd)\n[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)\n[![License: Apache-2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![Tests](https://github.com/wronai/clickmd/actions/workflows/tests.yml/badge.svg)](https://github.com/wronai/clickmd/actions)\n[![codecov](https://codecov.io/gh/wronai/clickmd/branch/main/graph/badge.svg)](https://codecov.io/gh/wronai/clickmd)\n\n\n## AI Cost Tracking\n\n![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-0.1.31-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)\n![AI Cost](https://img.shields.io/badge/AI%20Cost-$4.91-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-9.3h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)\n\n- 🤖 **LLM usage:** $4.9091 (21 commits)\n- 👤 **Human dev:** ~$930 (9.3h @ $100/h, 30min dedup)\n\nGenerated on 2026-04-20 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)\n\n---\n\n**Markdown rendering for CLI applications with syntax highlighting.**\n\n`clickmd` provides beautiful terminal output with:\n- 🎨 **Syntax highlighting** for 25+ languages (Python, TypeScript, Go, Rust, SQL, etc.)\n- 📝 **Markdown rendering** with headers, bold, links, tables, panels, blockquotes\n- 📊 **Tables \u0026 panels** for structured data display\n- 📈 **Progress bars, spinners, live updates** for async operations\n- 🎭 **Theming system** with 5+ built-in themes (monokai, dracula, nord, etc.)\n- 🐛 **Developer tools** (debug, inspect, diff, tree, pretty exceptions)\n- 🔧 **Zero dependencies** for core functionality\n- 🖱️ **Optional Click integration** for CLI decorators\n- ✨ **Optional Rich backend** for enhanced rendering\n\n# With Click support\npip install clickmd[click]\n\n# With Rich backend (enhanced rendering)\npip install clickmd[rich]\n\n# All optional features\npip install clickmd[all]\n```\n\n### Basic Usage (No Dependencies)\n\n```python\nfrom clickmd import md, echo\n\n# Hello World\n\nThis is **bold** and this is a [link](https://example.com).\n\n```python\ndef greet(name: str) -\u003e str:\n    return f\"Hello, {name}!\"\n```\n\"\"\")\n\n# Smart echo - auto-detects markdown\necho(\"## Status Update\")\necho(\"Regular text without markdown\")\n```\n\n### With Click Integration\n\n```python\nimport clickmd as click\n\n@click.group()\ndef cli():\n    \"\"\"My awesome CLI tool\"\"\"\n    pass\n\n@cli.command()\n@click.option(\"--name\", \"-n\", default=\"World\")\ndef hello(name: str):\n    \"\"\"Say hello\"\"\"\n    click.md(f\"\"\"\n## 👋 Hello, {name}!\n\nWelcome to **clickmd** - making CLIs beautiful.\n    \"\"\")\n\nif __name__ == \"__main__\":\n    cli()\n```\n\n### Syntax Highlighting\n\n`clickmd` provides syntax highlighting for 25+ languages:\n\n| Category | Languages | Extensions |\n|----------|-----------|------------|\n| **Programming** | Python, TypeScript, JavaScript, Go, Rust, Java, Kotlin, C/C++, Ruby, PHP | `.py`, `.ts`, `.js`, `.go`, `.rs`, `.java`, `.kt`, `.c`, `.cpp`, `.rb`, `.php` |\n| **Data Formats** | JSON, YAML, TOML, INI, Config | `.json`, `.yaml`, `.yml`, `.toml`, `.ini`, `.cfg`, `.conf` |\n| **Web** | HTML, XML, CSS, SCSS, Sass, Less | `.html`, `.htm`, `.xml`, `.svg`, `.css`, `.scss`, `.sass`, `.less` |\n| **Shell** | Bash, Shell, Zsh, Dockerfile | `.sh`, `.bash`, `.zsh`, `Dockerfile` |\n| **Database** | SQL, MySQL, PostgreSQL, SQLite | `.sql` |\n| **Other** | Markdown, Log, Diff | `.md`, `.log`, `.diff`, `.patch` |\n\n### Markdown Elements\n\n```python\nfrom clickmd import md\n\nmd(\"\"\"\n### Heading 3\n\n**Bold text** and regular text.\n\n[Links](https://example.com) are supported.\n\n```python\n# Code blocks with syntax highlighting\nprint(\"Hello, World!\")\n```\n\n- List items\n- Are rendered\n- Correctly\n\"\"\")\n```\n\n### MarkdownRenderer Class\n\nFor more control, use the `MarkdownRenderer` class directly:\n\n```python\nfrom clickmd import MarkdownRenderer\nimport sys\n\nrenderer = MarkdownRenderer(use_colors=True, stream=sys.stdout)\nrenderer.heading(1, \"My Title\")\nrenderer.codeblock(\"python\", 'print(\"Hello!\")')\n```\n\n### Progress and Status Output\n\n```python\nfrom clickmd import md\n\n# Log-style output with automatic coloring\nmd(\"\"\"\n```log\n🚀 Starting process...\n📦 Installing dependencies...\n✅ Build successful!\n⚠️ Warning: deprecated API\n🛑 Error: connection failed\n```\n\"\"\")\n```\n\n### Core Functions (No Dependencies)\n\n| Function | Description |\n|----------|-------------|\n| `md(text: str) -\u003e None` | Render markdown text with syntax highlighting |\n| `echo(message, file=None, nl=True, err=False, color=None) -\u003e None` | Smart echo that auto-detects markdown and renders it |\n| `render_markdown(text, text_lang=\"markdown\", stream=None, use_colors=True) -\u003e None` | Low-level markdown rendering function |\n| `get_renderer(stream=None, use_colors=True) -\u003e MarkdownRenderer` | Get a `MarkdownRenderer` instance |\n| `strip_ansi(text: str) -\u003e str` | Remove ANSI escape codes from text |\n\n### Interactive Prompts\n\n| Function | Description |\n|----------|-------------|\n| `menu(title, items, default=1, prompt_text=\"Select\", exit_option=\"Exit\") -\u003e int` | Display a numbered markdown menu |\n| `select(prompt_text, items, default=1) -\u003e int` | Inline numbered selection without title |\n\n### Phase 1: Tables, Panels, Blockquotes\n\n| Function | Description |\n|----------|-------------|\n| `table(headers, rows, style=\"simple\") -\u003e None` | Render ASCII/Unicode tables |\n| `panel(text, title=None, style=\"default\") -\u003e None` | Display text in a bordered box |\n| `blockquote(text) -\u003e None` | Render a markdown blockquote |\n| `hr() -\u003e None` | Render a horizontal rule |\n| `checklist(items, checked=None) -\u003e None` | Render a markdown checklist |\n\n### Logger\n\n| Function/Class | Description |\n|----------------|-------------|\n| `Logger` | Markdown-aware logger with automatic codeblock wrapping |\n| `get_logger(name)` | Get a logger instance |\n| `log_info(msg)`, `log_success(msg)`, `log_warning(msg)`, `log_error(msg)`, `log_action(msg)` | Shortcut functions |\n\n### Phase 3: Progress, Spinners, Live Updates\n\n| Function/Class | Description |\n|----------------|-------------|\n| `progress(items, label=None, show_eta=True)` | Iterator wrapper with progress bar |\n| `ProgressBar` | Manual progress bar control |\n| `spinner(text, style=\"dots\")` | Context manager for animated spinners |\n| `Spinner` | Manual spinner control |\n| `live(text_fn, refresh_rate=0.5)` | Live updating display |\n| `countdown(seconds, message=None)` | Countdown timer display |\n| `SPINNERS` | Dictionary of spinner animation styles |\n\n### Phase 4: Theming\n\n| Function/Class | Description |\n|----------------|-------------|\n| `Theme` | Color theme definition |\n| `set_theme(name)` | Activate a theme |\n| `get_theme()` | Get current theme |\n| `list_themes()` | Show available themes |\n| `register_theme(name, theme)` | Register a custom theme |\n| `color(name)` | Get color code from current theme |\n| `is_no_color() -\u003e bool` | Check if NO_COLOR is set |\n| `get_color_support() -\u003e int` | Detect terminal color support (0/8/256/true) |\n| `THEMES` | Dictionary of built-in themes |\n\n### Phase 5: Developer Tools\n\n| Function/Class | Description |\n|----------------|-------------|\n| `debug(obj, name=None, depth=2)` | Pretty-print with type info |\n| `inspect_obj(obj, show_methods=True)` | Show object attributes |\n| `diff(a, b, context=3)` | Side-by-side diff visualization |\n| `tree(path, max_depth=3)` | Directory tree display |\n| `PrettyExceptionFormatter` | Format exceptions with syntax highlighting |\n| `install_excepthook()` | Enable pretty exception display |\n| `uninstall_excepthook()` | Restore default exception display |\n| `ClickmdHandler` | Logging handler with markdown styling |\n\n### Click Integration (requires `click` package)\n\nWhen `click` is installed, the full Click API is available:\n\n**Decorators:**\n- `@clickmd.group()` - Create a command group\n- `@clickmd.command()` - Create a command\n- `@clickmd.option()` - Add an option\n- `@clickmd.argument()` - Add an argument\n- `@clickmd.pass_context`, `@clickmd.pass_obj` - Context passing\n- `@clickmd.version_option()`, `@clickmd.help_option()`, etc.\n\n**Parameter Types:**\n- `clickmd.STRING`, `clickmd.INT`, `clickmd.FLOAT`, `clickmd.BOOL`, `clickmd.UUID`\n- `clickmd.Choice`, `clickmd.Path`, `clickmd.File`, `clickmd.DateTime`\n- `clickmd.IntRange`, `clickmd.FloatRange`, `clickmd.Tuple`, `clickmd.ParamType`\n\n**Core Classes:**\n- `clickmd.Context`, `clickmd.Command`, `clickmd.Group`\n- `clickmd.Option`, `clickmd.Argument`, `clickmd.Parameter`\n\n**Utility Functions:**\n- `clickmd.click_echo()`, `clickmd.secho()`, `clickmd.style()`, `clickmd.unstyle()`\n- `clickmd.prompt()`, `clickmd.confirm()`, `clickmd.getchar()`, `clickmd.clear()`\n- `clickmd.progressbar()`, `clickmd.open_file()`, `clickmd.get_app_dir()`\n\n**Exceptions:**\n- `clickmd.ClickException`, `clickmd.UsageError`, `clickmd.BadParameter`\n- `clickmd.Abort`, `clickmd.NoSuchOption`, `clickmd.MissingParameter`\n\n### Markdown Help for Click\n\n| Class/Decorator | Description |\n|----------------|-------------|\n| `MarkdownCommand` | Command class with markdown help rendering |\n| `MarkdownGroup` | Group class with markdown help rendering |\n| `MarkdownHelpFormatter` | Help formatter with markdown support |\n| `@markdown_help` | Decorator to enable markdown help |\n| `success(msg)`, `warning(msg)`, `error(msg)`, `info(msg)` | Styled output panels |\n| `echo_md(msg)` | Echo with markdown rendering |\n\n### Rich Backend (optional)\n\nWhen `rich` is installed:\n\n| Function | Description |\n|----------|-------------|\n| `is_rich_available() -\u003e bool` | Check if Rich is installed |\n| `get_console()` | Get Rich console instance |\n| `render_md(text)` | Render markdown with Rich |\n| `render_panel(text, **kwargs)` | Render panel with Rich |\n| `render_syntax(code, lang)` | Render syntax-highlighted code |\n| `render_table(data, **kwargs)` | Render table with Rich |\n\n### Constants\n\n| Constant | Description |\n|----------|-------------|\n| `CLICK_AVAILABLE: bool` | Whether Click is installed |\n| `RICH_AVAILABLE: bool` | Whether Rich is installed |\n\n### Interactive Menus\n\n```python\nimport clickmd\n\nchoice = clickmd.menu(\"## Choose Provider\", [\n    (\"groq\", \"Groq — fast \u0026 free tier\"),\n    (\"openrouter\", \"OpenRouter — multi-model\"),\n    (\"ollama\", \"Ollama — local, no API key\"),\n])\n```\n\n### Tables \u0026 Panels\n\n```python\nfrom clickmd import table, panel\n\ntable(\n    headers=[\"Name\", \"Version\", \"Status\"],\n    rows=[\n        [\"clickmd\", \"1.1.0\", \"✅ OK\"],\n        [\"click\", \"8.1.7\", \"✅ OK\"],\n    ],\n)\n\npanel(\"Deployment complete!\", title=\"Success\", style=\"green\")\n```\n\n### Logger\n\n```python\nfrom clickmd import get_logger\n\nlog = get_logger(\"myapp\")\nlog.info(\"Starting process...\")\nlog.success(\"Build complete!\")\nlog.warning(\"Deprecated API\")\nlog.error(\"Connection failed\")\n```\n\n### Themes\n\n```python\nfrom clickmd import set_theme, list_themes\n\nlist_themes()            # Show available themes\nset_theme(\"monokai\")     # Switch theme\n```\n\n### Developer Tools\n\n```python\nfrom clickmd import debug, inspect_obj, diff, tree\n\ndebug(my_variable)                    # Pretty-print with type info\ninspect_obj(my_object)                # Show object attributes\ndiff(\"old text\", \"new text\")          # Side-by-side diff\ntree(\"/path/to/dir\")                  # Directory tree\n```\n\n## Examples\n\nSee the [examples/](examples/) directory for 17 demo scripts:\n\n- `basic.py` — Basic markdown rendering\n- `cli_app.py` — Full CLI application with Click\n- `custom_renderer.py` — Custom renderer configuration\n- `colored_logging.py` — Log-style colored output\n- `phase1_features.py` — Tables, panels, blockquotes, checklists\n- `phase3_progress.py` — Progress bars, spinners, live updates\n- `phase4_themes.py` — Theming system\n- `phase5_devtools.py` — Debug, inspect, diff, tree tools\n- `logger_usage.py` — Structured logging\n- `markdown_help.py` — Markdown help formatter for Click\n\n## Project Structure\n\n```\nclickmd/\n├── src/clickmd/          # Package source (src layout)\n│   ├── __init__.py       # Public API: md(), echo(), menu(), select()\n│   ├── renderer.py       # Core markdown renderer \u0026 syntax highlighting\n│   ├── decorators.py     # Click decorator re-exports\n│   ├── help.py           # Markdown help formatter for Click\n│   ├── logger.py         # Markdown-aware structured logger\n│   ├── progress.py       # Progress bars, spinners, live updates\n│   ├── themes.py         # Color themes \u0026 NO_COLOR support\n│   ├── devtools.py       # Debug, inspect, diff, tree tools\n│   ├── rich_backend.py   # Optional Rich integration\n│   └── py.typed          # PEP 561 type marker\n├── tests/                # Test suite (69 tests)\n├── examples/             # 17 demo scripts\n├── docs/                 # API reference \u0026 contributing guide\n├── scripts/              # Build \u0026 version tools\n├── tools/                # Markdown-to-HTML converter\n├── pyproject.toml        # Project config (hatchling)\n└── Makefile              # Dev commands\n```\n\n# Clone the repository\ngit clone https://github.com/wronai/clickmd.git\ncd clickmd\n\n# Install development dependencies\npip install -e \".[dev,all]\"\n\n# Run linter \u0026 format\nmake lint\nmake format\n\n# Build \u0026 publish\nmake build\nmake publish\n```\n\n## License\n\nLicensed under Apache-2.0.\n## Contributing\n\nContributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) first.\n\n## Related Projects\n\n- [Click](https://click.palletsprojects.com/) - Python CLI framework\n- [Rich](https://github.com/Textualize/rich) - Rich text and beautiful formatting\n\n\u003c!-- taskill:status:start --\u003e\n\n## Status\n\n_Last updated by [taskill](https://github.com/oqlos/taskill) at 2026-04-25 18:20 UTC_\n\n| Metric | Value |\n|---|---|\n| HEAD | `f7e7a83` |\n| Coverage | — |\n| Failing tests | — |\n| Commits in last cycle | 0 |\n\n\u003e No changes since the last taskill run: there are no new commits and no changed files. TODO.md remains unchanged.\n\n\u003c!-- taskill:status:end --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsemcod%2Fclickmd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsemcod%2Fclickmd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsemcod%2Fclickmd/lists"}