{"id":15191234,"url":"https://github.com/nushell-prophet/numd","last_synced_at":"2026-02-12T03:16:25.376Z","repository":{"id":220176296,"uuid":"750921693","full_name":"nushell-prophet/numd","owner":"nushell-prophet","description":"numd - reproducible Nushell Markdown documents","archived":false,"fork":false,"pushed_at":"2026-01-01T03:26:21.000Z","size":787,"stargazers_count":40,"open_issues_count":14,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-01-05T19:24:44.901Z","etag":null,"topics":["markdown","nushell","nushell-module"],"latest_commit_sha":null,"homepage":"","language":"Nushell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nushell-prophet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"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}},"created_at":"2024-01-31T15:33:05.000Z","updated_at":"2026-01-01T03:26:25.000Z","dependencies_parsed_at":"2024-02-05T13:27:14.822Z","dependency_job_id":"b5a74ae5-cb93-4aa2-9cdc-222ea42c3705","html_url":"https://github.com/nushell-prophet/numd","commit_stats":null,"previous_names":["maxim-uvarov/nubook","nushell101/nudoc","nushell-prophet/nudoc","nushell-prophet/numd"],"tags_count":37,"template":false,"template_full_name":null,"purl":"pkg:github/nushell-prophet/numd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nushell-prophet%2Fnumd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nushell-prophet%2Fnumd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nushell-prophet%2Fnumd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nushell-prophet%2Fnumd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nushell-prophet","download_url":"https://codeload.github.com/nushell-prophet/numd/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nushell-prophet%2Fnumd/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29356243,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-12T01:03:07.613Z","status":"online","status_checked_at":"2026-02-12T02:00:06.911Z","response_time":55,"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":["markdown","nushell","nushell-module"],"created_at":"2024-09-27T21:00:43.125Z","updated_at":"2026-02-12T03:16:25.370Z","avatar_url":"https://github.com/nushell-prophet.png","language":"Nushell","readme":"[![CI](https://github.com/nushell-prophet/numd/actions/workflows/ci.yml/badge.svg)](https://github.com/nushell-prophet/numd/actions/workflows/ci.yml)\n\n# numd - reproducible Nushell Markdown documents\n\nExecute blocks of nushell code within markdown documents, write results back to your `.md` document, or output them to the terminal.\n\n## Quickstart\n\n```nushell no-run\n# clone the repo and `cd` into it\ngit clone https://github.com/nushell-prophet/numd\ncd numd\n\n# use definitions from the module\nuse numd\n\n# run it on any file to check (--echo outputs to stdout without saving)\nnumd run z_examples/1_simple_markdown/simple_markdown.md --echo\n```\n\n## How it works\n\n`numd run` parses the initial file ([example](/z_examples/1_simple_markdown/simple_markdown.md)), generates a script to execute the found commands ([example](/z_examples/1_simple_markdown/simple_markdown.md_intermed.nu)), executes this script in a new nushell instance, captures the results, updates the initial document accordingly, and/or outputs the resulting document into the terminal along with basic changes [stats](#stats-of-changes).\n\nExperienced nushell users can understand the logic better by looking at [examples](./z_examples/). Especially, seeing [numd in action describing its own commands](./z_examples/2_numd_commands_explanations/numd_commands_explanations.md).\n\n### Details on parsing code blocks and displaying the output\n\n1. `numd` looks for code blocks marked with ` ```nushell ` or ` ```nu `.\n2. Code blocks are split into command groups by blank lines (double newlines). Each command group is executed separately.\n3. Output from each command group is displayed inline with `# =\u003e` prefix immediately after the command.\n4. Multiline commands (pipelines split across lines without blank lines) are treated as a single command group.\n5. Plain `#` comments are preserved; `# =\u003e` output lines are regenerated on each run.\n6. Use the `separate-block` fence option to output results in a separate code block instead of inline.\n\n\u003e [!NOTE]\n\u003e This readme is a live `numd` document\n\n### `numd run` flags and params\n\n```nushell\nuse numd\nnumd run --help\n# =\u003e Run Nushell code blocks in a markdown file, output results back to the `.md`, and optionally to terminal\n# =\u003e\n# =\u003e Usage:\n# =\u003e   \u003e run {flags} \u003cfile\u003e\n# =\u003e\n# =\u003e Flags:\n# =\u003e   -h, --help: Display the help message for this command\n# =\u003e   --echo: output resulting markdown to stdout instead of saving to file\n# =\u003e   --eval \u003cstring\u003e: Nushell code to prepend to the script (use `open -r config.nu` for file-based config)\n# =\u003e   --ignore-git-check: skip the check for uncommitted changes before overwriting\n# =\u003e   --no-fail-on-error: skip errors (markdown is never saved on error)\n# =\u003e   --no-stats: do not output stats of changes (is activated via --echo by default)\n# =\u003e   --print-block-results: print blocks one by one as they are executed, useful for long running scripts\n# =\u003e   --save-intermed-script \u003cpath\u003e: optional path for keeping intermediate script (useful for debugging purposes). If not set, the temporary intermediate script will be deleted.\n# =\u003e   --use-host-config: load host's env, config, and plugin files (default: run with nu -n for reproducibility)\n# =\u003e\n# =\u003e Parameters:\n# =\u003e   file \u003cpath\u003e: path to a `.md` file containing Nushell code to be executed\n# =\u003e\n# =\u003e Input/output types:\n# =\u003e   ╭───┬─────────┬─────────╮\n# =\u003e   │ # │  input  │ output  │\n# =\u003e   ├───┼─────────┼─────────┤\n# =\u003e   │ 0 │ nothing │ string  │\n# =\u003e   │ 1 │ nothing │ nothing │\n# =\u003e   │ 2 │ nothing │ record  │\n# =\u003e   ╰───┴─────────┴─────────╯\n# =\u003e\n# =\u003e Examples:\n# =\u003e   update readme\n# =\u003e   \u003e numd run README.md\n# =\u003e\n```\n\n### Supported fence options\n\n`numd` understands the following fence options. Several comma-separated fence options can be combined together. Fence options are placed in the [infostring](https://github.github.com/gfm/#info-string) of the opening code fence, for example: ` ```nushell try, new-instance `\n\n```nushell\nnumd list-fence-options\n# =\u003e ╭──────long──────┬─short─┬───────────────────────────description────────────────────────────╮\n# =\u003e │ no-output      │ O     │ execute code without outputting results                          │\n# =\u003e │ no-run         │ N     │ do not execute code in block                                     │\n# =\u003e │ try            │ t     │ execute block inside `try {}` for error handling                 │\n# =\u003e │ new-instance   │ n     │ execute block in new Nushell instance (useful with `try` block)  │\n# =\u003e │ separate-block │ s     │ output results in a separate code block instead of inline `# =\u003e` │\n# =\u003e ╰──────long──────┴─short─┴───────────────────────────description────────────────────────────╯\n```\n\n### Stats of changes\n\nBy default, `numd` provides basic stats on changes made (when not using `--echo`).\n\n```nushell\n# Running without --echo saves the file and returns stats\nlet path = [z_examples 1_simple_markdown simple_markdown_with_no_output.md] | path join\nnumd run $path --ignore-git-check\n# =\u003e ╭──────────────────┬───────────────────────────────────╮\n# =\u003e │ filename         │ simple_markdown_with_no_output.md │\n# =\u003e │ nushell_blocks   │ 3                                 │\n# =\u003e │ levenshtein_dist │ 52                                │\n# =\u003e │ diff_lines       │ +8 (25.8%)                        │\n# =\u003e │ diff_words       │ +6 (8.5%)                         │\n# =\u003e │ diff_chars       │ +52 (11.6%)                       │\n# =\u003e ╰──────────────────┴───────────────────────────────────╯\n```\n\n### Styling outputs\n\nUse the `--eval` option to prepend Nushell code to the intermediate script. This lets you set visual settings and other configuration before your code runs.\n\n```nushell\nlet path = $nu.temp-dir | path join simple_nu_table.md\n\n# let's generate some markdown and save it to the `simple_nu_table.md` file in the temp directory\n\"```nushell\\n[[a b c]; [1 2 3]]\\n```\\n\" | save -f $path\n\n# let's run this file to see its outputs (--echo outputs to stdout without saving)\nnumd run $path --echo --no-stats --eval \"\n    $env.config.footer_mode = 'never'\n    $env.config.table.header_on_separator = false\n    $env.config.table.index_mode = 'never'\n    $env.config.table.mode = 'basic_compact'\n\"\n# =\u003e ```nushell\n# =\u003e [[a b c]; [1 2 3]]\n# =\u003e # =\u003e +---+---+---+\n# =\u003e # =\u003e | a | b | c |\n# =\u003e # =\u003e | 1 | 2 | 3 |\n# =\u003e # =\u003e +---+---+---+\n# =\u003e ```\n```\n\n### `numd clear-outputs`\n\n```nu\nnumd clear-outputs --help\n# =\u003e Remove numd execution outputs from the file\n# =\u003e Note: No git check here - clearing outputs is a reversible operation (just re-run numd)\n# =\u003e and users typically clear outputs intentionally before committing clean source\n# =\u003e\n# =\u003e Usage:\n# =\u003e   \u003e clear-outputs {flags} \u003cfile\u003e\n# =\u003e\n# =\u003e Flags:\n# =\u003e   -h, --help: Display the help message for this command\n# =\u003e   --echo: output resulting markdown to stdout instead of writing to file\n# =\u003e   --strip-markdown: keep only Nushell script, strip all markdown tags\n# =\u003e\n# =\u003e Parameters:\n# =\u003e   file \u003cpath\u003e: path to a `.md` file containing numd output to be cleared\n# =\u003e\n# =\u003e Input/output types:\n# =\u003e   ╭───┬─────────┬─────────╮\n# =\u003e   │ # │  input  │ output  │\n# =\u003e   ├───┼─────────┼─────────┤\n# =\u003e   │ 0 │ nothing │ string  │\n# =\u003e   │ 1 │ nothing │ nothing │\n# =\u003e   ╰───┴─────────┴─────────╯\n# =\u003e\n```\n\n### `numd capture`\n\n`numd` can use the `display_output` hook to write the current session prompts together with their output into a specified markdown file. There are corresponding commands `numd capture start` and `numd capture stop`.\n\n```nushell\nnumd capture start --help\n# =\u003e start capturing commands and their outputs into a file\n# =\u003e\n# =\u003e Usage:\n# =\u003e   \u003e capture start {flags} (file)\n# =\u003e\n# =\u003e Flags:\n# =\u003e   -h, --help: Display the help message for this command\n# =\u003e   --separate-blocks: create separate code blocks for each pipeline instead of inline `# =\u003e` output\n# =\u003e\n# =\u003e Parameters:\n# =\u003e   file \u003cpath\u003e:  (optional, default: 'numd_capture.md')\n# =\u003e\n# =\u003e Input/output types:\n# =\u003e   ╭───┬─────────┬─────────╮\n# =\u003e   │ # │  input  │ output  │\n# =\u003e   ├───┼─────────┼─────────┤\n# =\u003e   │ 0 │ nothing │ nothing │\n# =\u003e   ╰───┴─────────┴─────────╯\n# =\u003e\n```\n\n```nushell\nnumd capture stop --help\n# =\u003e stop capturing commands and their outputs\n# =\u003e\n# =\u003e Usage:\n# =\u003e   \u003e capture stop\n# =\u003e\n# =\u003e Flags:\n# =\u003e   -h, --help: Display the help message for this command\n# =\u003e\n# =\u003e Input/output types:\n# =\u003e   ╭───┬─────────┬─────────╮\n# =\u003e   │ # │  input  │ output  │\n# =\u003e   ├───┼─────────┼─────────┤\n# =\u003e   │ 0 │ nothing │ nothing │\n# =\u003e   ╰───┴─────────┴─────────╯\n# =\u003e\n```\n\n### `numd parse-md`\n\nParse markdown into a table of semantic blocks (headers, paragraphs, code blocks, lists, blockquotes, frontmatter) with extracted content and metadata.\n\n```nushell\nnumd parse-md --help\n# =\u003e Parse markdown into semantic blocks\n# =\u003e\n# =\u003e Usage:\n# =\u003e   \u003e parse-md (file)\n# =\u003e\n# =\u003e Flags:\n# =\u003e   -h, --help: Display the help message for this command\n# =\u003e\n# =\u003e Parameters:\n# =\u003e   file \u003cpath\u003e: optional path to markdown file (can also pipe content) (optional)\n# =\u003e\n# =\u003e Input/output types:\n# =\u003e   ╭───┬─────────┬────────╮\n# =\u003e   │ # │  input  │ output │\n# =\u003e   ├───┼─────────┼────────┤\n# =\u003e   │ 0 │ string  │ table  │\n# =\u003e   │ 1 │ nothing │ table  │\n# =\u003e   ╰───┴─────────┴────────╯\n# =\u003e\n```\n\n### Some random familiar examples\n\n```nushell\nls z_examples | sort-by name | reject modified size\n# =\u003e ╭──────────────────name───────────────────┬─type─╮\n# =\u003e │ z_examples/1_simple_markdown            │ dir  │\n# =\u003e │ z_examples/2_numd_commands_explanations │ dir  │\n# =\u003e │ z_examples/3_book_types_of_data         │ dir  │\n# =\u003e │ z_examples/4_book_working_with_lists    │ dir  │\n# =\u003e │ z_examples/5_simple_nu_table            │ dir  │\n# =\u003e │ z_examples/6_edge_cases                 │ dir  │\n# =\u003e │ z_examples/7_image_output               │ dir  │\n# =\u003e │ z_examples/8_parse_frontmatter          │ dir  │\n# =\u003e │ z_examples/999_numd_internals           │ dir  │\n# =\u003e │ z_examples/99_strip_markdown            │ dir  │\n# =\u003e │ z_examples/9_other                      │ dir  │\n# =\u003e ╰──────────────────name───────────────────┴─type─╯\n\n'hello world' | str length\n# =\u003e 11\n\n2 + 2\n# =\u003e 4\n\ngit tag | lines | sort -n | last\n# =\u003e 0.3.0\n```\n\n## Real fight examples to try\n\n```nushell no-output\n# output the result of execution to terminal without updating the file (--echo implies no save)\n[z_examples 1_simple_markdown simple_markdown.md]\n| path join\n| numd run $in --echo\n```\n\n## Development and testing\n\nNushell Markdown documents used together with Git could often serve as a convenient way to test custom and built-in Nushell commands.\n\nTesting of the `numd` module is done via `toolkit.nu`:\n\n```nushell no-run\n# Run all tests (unit + integration)\nnu toolkit.nu test\n\n# Run only unit tests (uses nutest framework)\nnu toolkit.nu test-unit\n\n# Run only integration tests (executes example markdown files)\nnu toolkit.nu test-integration\n```\n\n### Unit tests\n\nUnit tests in `tests/` use the [nutest](https://github.com/vyadh/nutest) framework to test internal functions like `parse-markdown-to-blocks`, `classify-block-action`, `extract-fence-options`, etc.\n\n### Integration tests\n\nIntegration tests run all example files in `z_examples/` through numd and report changes via Levenshtein distance. Whatever changes are made in the module - it can be easily seen if they break anything (both by the Levenshtein distance metric or by `git diff` of the updated example files versus their initial versions).\n\n```nushell no-run\nnu toolkit.nu test-integration\n# =\u003e ╭───────────────────────────────────────────────┬─────────────────┬───────────────────┬────────────┬──────────────┬─────╮\n# =\u003e │                   filename                    │ nushell_blocks  │ levenshtein_dist  │ diff_lines │  diff_words  │ ... │\n# =\u003e ├───────────────────────────────────────────────┼─────────────────┼───────────────────┼────────────┼──────────────┼─────┤\n# =\u003e │ types_of_data.md                              │              30 │               204 │ 0%         │ -29 (-1.1%)  │ ... │\n# =\u003e │ working_with_lists.md                         │              20 │                 4 │ 0%         │ 0%           │ ... │\n# =\u003e │ numd_commands_explanations.md                 │               6 │                 0 │ 0%         │ 0%           │ ... │\n# =\u003e │ simple_markdown.md                            │               3 │                 0 │ 0%         │ 0%           │ ... │\n# =\u003e │ error-with-try.md                             │               1 │                13 │ -1 (-4.3%) │ 0%           │ ... │\n# =\u003e │ simple_markdown_first_block.md                │               3 │                 0 │ 0%         │ 0%           │ ... │\n# =\u003e │ raw_strings_test.md                           │               2 │                 0 │ 0%         │ 0%           │ ... │\n# =\u003e │ simple_nu_table.md                            │               3 │                 0 │ 0%         │ 0%           │ ... │\n# =\u003e │ simple_nu_table_customized_width20.md         │               3 │               458 │ 0%         │ -42 (-23.7%) │ ... │\n# =\u003e │ simple_nu_table_customized_example_config.md  │               3 │                56 │ 0%         │ -4 (-2.3%)   │ ... │\n# =\u003e │ README.md                                     │               9 │                 0 │ 0%         │ 0%           │ ... │\n# =\u003e ╰───────────────────────────────────────────────┴─────────────────┴───────────────────┴────────────┴──────────────┴─────╯\n```\n","funding_links":[],"categories":["Scripts"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnushell-prophet%2Fnumd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnushell-prophet%2Fnumd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnushell-prophet%2Fnumd/lists"}