{"id":27615384,"url":"https://github.com/drupol/markdown-code-runner","last_synced_at":"2026-02-28T16:32:28.669Z","repository":{"id":286836080,"uuid":"962716701","full_name":"drupol/markdown-code-runner","owner":"drupol","description":"Execute and optionally rewrite code blocks in Markdown files based on external commands","archived":false,"fork":false,"pushed_at":"2026-01-04T17:55:24.000Z","size":102,"stargazers_count":20,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-15T20:59:03.589Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"eupl-1.2","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/drupol.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"drupol"}},"created_at":"2025-04-08T15:08:46.000Z","updated_at":"2026-01-04T17:54:56.000Z","dependencies_parsed_at":"2025-04-23T03:13:55.557Z","dependency_job_id":null,"html_url":"https://github.com/drupol/markdown-code-runner","commit_stats":null,"previous_names":["drupol/nix-shell"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/drupol/markdown-code-runner","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drupol%2Fmarkdown-code-runner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drupol%2Fmarkdown-code-runner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drupol%2Fmarkdown-code-runner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drupol%2Fmarkdown-code-runner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/drupol","download_url":"https://codeload.github.com/drupol/markdown-code-runner/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drupol%2Fmarkdown-code-runner/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29942859,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-28T13:49:17.081Z","status":"ssl_error","status_checked_at":"2026-02-28T13:48:50.396Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":"2025-04-23T03:02:09.124Z","updated_at":"2026-02-28T16:32:28.640Z","avatar_url":"https://github.com/drupol.png","language":"Rust","funding_links":["https://github.com/sponsors/drupol"],"categories":["Rust"],"sub_categories":[],"readme":"![GitHub stars][github stars]\n[![Donate!][donate github]][5]\n\n# Markdown-code-runner\n\nA configurable command-line tool written in **Rust** that parses Markdown files, extracts fenced code blocks, executes them via external arbitrary commands, and optionally replaces the content of the blocks with the command output.\n\nUseful for:\n\n- Validating Markdown tutorials with executable code\n- Auto-updating examples and documentation\n- Code formatting code blocks (e.g. `black`, `nixfmt`, `shfmt`, `php-cs-fixer`, etc)\n- Linting code blocks (e.g. `ruff`, `php -l`, `prettier`, etc)\n\n## Features\n\n- Clean configuration via a TOML file\n- Fast and dependency-free thanks to Rust\n- Scans fenced Markdown code blocks by language\n- Configurable per-language command execution\n- Optional block replacement based on command output\n- `--check` mode for CI/linting use cases\n- Markdown code blocks can opt-out using the `mdcr-skip` flag\n- Placeholder support (`{file}`, `{lang}`, etc.)\n\n## Installation\n\n```bash\ngit clone https://github.com/drupol/markdown-code-runner\ncd markdown-code-runner\ncargo build --release\n./target/release/mdcr --help\n```\n\n### Via nix\n\nAvailable soon through [`markdown-code-runner` package][markdown-code-runner package], the binary is called `mdcr`.\n\n## Usage\n\n```bash\nmdcr --config config.toml path/to/file.md\n```\n\n### Check Mode (non-destructive)\n\n```bash\nmdcr --config config.toml --check path/to/file.md\n```\n\nThis will:\n\n- Execute configured commands for each code block\n- Fail with exit code `1` if output differs from original (like a linter)\n- Do **not** modify files\n\n## Configuration: `config.toml`\n\nThe configuration file defines which commands to run for which Markdown block languages.\n\n### Example\n\nSave this file as `config.toml`:\n\n```toml\n[presets.ruff-format]\nlanguages = [\"python\", \"py\"]\ncommand = [\"ruff\", \"format\", \"-\"]\n\n[presets.nixfmt]\nlanguage = \"nix\"\ncommand = [\"nixfmt\"]\n\n[presets.php]\nlanguage = \"php\"\n# php-cs-fixer does not support STDIN, so we use a temporary file\ncommand = [\n  \"sh\",\n  \"-c\",\n  \"php-cs-fixer fix -q --rules=@PSR12 {file}; cat {file}\"\n]\ninput_mode = \"file\"\n\n[presets.rust]\nlanguage = \"rust\"\ncommand = [\"rustfmt\"]\n\n[presets.typstyle]\nlanguage = \"typst\"\ncommand = [\"typstyle\"]\n\n[presets.latex]\nlanguage = \"latex\"\ncommand = [\"tex-fmt\", \"--stdin\"]\n```\n\n#### Input Modes\n\nEach preset supports an optional `input_mode`, which defines how the code block is passed to the command:\n\n- `stdin` (default): The code is passed via standard input (`STDIN`)\n- `file`: The code is written to a temporary file and its path is passed, the temporary file is deleted immediately after execution\n\n#### Output Modes\n\nEach preset also supports an optional `output_mode`, which defines how the command output is used:\n\n- `replace` (default): Replace the code block content with the command's output\n- `check`: Check the command's exit code, if it is different from `0`, the command failed, and the tool will return a non-zero exit code\n\nIf not specified, both `input_mode` and `output_mode` default to `stdin` and `replace`, respectively.\n\n## Markdown Syntax\n\nThe tool scans for fenced code blocks like:\n\n````\n```python\nprint( \"hello\" )\n```\n````\n\nIt will execute all matching commands whose `language` is `python`.\n\n### Skipping a code block\n\nTo exclude a block from processing, add `mdcr-skip` after the language:\n\n````\n```python mdcr-skip\nprint(\"don't touch this\")\n```\n````\n\n## Supported Placeholders\n\nYou can use placeholders in the `command` field:\n\n| Placeholder | Description                      |\n| ----------- | -------------------------------- |\n| `{file}`    | Path to the temporary code file  |\n| `{lang}`    | Language of the block (`python`) |\n| `{suffix}`  | File suffix (e.g. `.py`)         |\n| `{tmpdir}`  | Temporary directory path         |\n\n## Safeguards\n\n- Blocks with unsupported languages are skipped with a warning.\n- `{file}` placeholder is **only available** in `input_mode: \"file\"` mode.\n\n## CI Integration\n\nRecommended usage in continuous integration:\n\n```bash\nmdcr --config config.toml --check docs/\n```\n\nThis runs all configured checks and returns a non-zero exit code if:\n\n- Output differs from the original\n- A command fails\n\nThe `--check` mode will not modify any files.\n\n## Logging\n\nThe CLI option `--log` allows you to control the verbosity and destination of log messages emitted during execution.\n\n### Usage\n\n```bash\nmdcr --config config.toml --log debug path/to/file.md\n```\n\n### Available log levels\n\nThe logging system uses standard log levels, from most verbose to least:\n\n| Level   | Description                                           |\n| ------- | ----------------------------------------------------- |\n| `trace` | Highly detailed, useful for debugging internal issues |\n| `debug` | General debugging information                         |\n| `info`  | Informational messages about execution progress       |\n| `warn`  | Non-critical issues that deserve attention            |\n| `error` | Critical problems encountered during execution        |\n\nBy default, if no `--log` option is provided, the logging level defaults to `warn`.\n\n[github stars]: https://img.shields.io/github/stars/drupol/markdown-code-runner.svg?style=flat-square\n[donate github]: https://img.shields.io/badge/Sponsor-Github-brightgreen.svg?style=flat-square\n[5]: https://github.com/sponsors/drupol\n[markdown-code-runner package]: https://search.nixos.org/packages?channel=unstable\u0026from=0\u0026size=50\u0026sort=relevance\u0026type=packages\u0026query=markdown-code-runner\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrupol%2Fmarkdown-code-runner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdrupol%2Fmarkdown-code-runner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrupol%2Fmarkdown-code-runner/lists"}