{"id":17246295,"url":"https://github.com/davidwells/markdown-magic","last_synced_at":"2026-01-19T22:10:38.899Z","repository":{"id":47435798,"uuid":"75155212","full_name":"DavidWells/markdown-magic","owner":"DavidWells","description":"💫  Automatically format markdown files via comment blocks using source code, external data \u0026 custom transforms.","archived":false,"fork":false,"pushed_at":"2025-04-24T20:53:10.000Z","size":1324,"stargazers_count":824,"open_issues_count":12,"forks_count":228,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-04-24T21:27:19.241Z","etag":null,"topics":["docs","docs-generator","dx","markdown","readme"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DavidWells.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"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},"funding":{"github":"davidwells"}},"created_at":"2016-11-30T05:40:10.000Z","updated_at":"2025-04-24T20:53:12.000Z","dependencies_parsed_at":"2024-04-05T23:29:33.858Z","dependency_job_id":"d0ff2197-adaa-4ffe-ab62-6efb87b78bd2","html_url":"https://github.com/DavidWells/markdown-magic","commit_stats":{"total_commits":334,"total_committers":13,"mean_commits":"25.692307692307693","dds":0.5598802395209581,"last_synced_commit":"0bcfb13304cb12a0f33d24667dd679631be13cd1"},"previous_names":[],"tags_count":66,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DavidWells%2Fmarkdown-magic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DavidWells%2Fmarkdown-magic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DavidWells%2Fmarkdown-magic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DavidWells%2Fmarkdown-magic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DavidWells","download_url":"https://codeload.github.com/DavidWells/markdown-magic/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254052671,"owners_count":22006716,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["docs","docs-generator","dx","markdown","readme"],"created_at":"2024-10-15T06:33:09.639Z","updated_at":"2026-01-19T22:10:38.892Z","avatar_url":"https://github.com/DavidWells.png","language":"JavaScript","funding_links":["https://github.com/sponsors/davidwells"],"categories":[],"sub_categories":[],"readme":"# Markdown Magic [![npm-version][npm-badge]][npm-link]\n\n✨ Add a little magic to your markdown! ✨\n\n## About\n\n\u003cimg align=\"right\" width=\"200\" height=\"183\" src=\"https://cloud.githubusercontent.com/assets/532272/21507867/3376e9fe-cc4a-11e6-9350-7ec4f680da36.gif\"\u003eMarkdown magic uses comment blocks in markdown files to automatically sync or transform its contents.\n\n- Automatically keep markdown files up to date from local or remote code sources\n- Transform markdown content with custom transform functions\n- Render markdown with any template engine\n- Automatically generate a table of contents\n- ... etc\n\nThe comments markdown magic uses are hidden in markdown and when viewed as HTML.\n\nThis `README.md` is generated with `markdown-magic` [view the raw file](https://raw.githubusercontent.com/DavidWells/markdown-magic/master/README.md) to see how.\n\n[Video demo](http://www.youtube.com/watch?v=4V2utrvxwJ8) • [Example Repo](https://github.com/DavidWells/repo-using-markdown-magic)\n\n## Table of Contents\n\u003c!-- ⛔️ MD-MAGIC-EXAMPLE:START TOC collapseText=\"Click to expand\" --\u003e\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand\u003c/summary\u003e\n\n- [About](#about)\n- [Install](#install)\n- [Usage](#usage)\n  - [Running via CLI](#running-via-cli)\n  - [Running programmatically](#running-programmatically)\n- [Syntax Examples](#syntax-examples)\n  - [Basic](#basic)\n  - [Curly braces](#curly-braces)\n  - [Square brackets](#square-brackets)\n  - [Parentheses](#parentheses)\n  - [Functions](#functions)\n  - [API](#api)\n    - [`MarkdownMagicOptions`](#markdownmagicoptions)\n    - [`OutputConfig`](#outputconfig)\n    - [`MarkdownMagicResult`](#markdownmagicresult)\n- [Transforms](#transforms)\n  - [\u003e TOC](#-toc)\n  - [\u003e CODE](#-code)\n  - [\u003e FILE](#-file)\n  - [\u003e REMOTE](#-remote)\n  - [\u003e fileTree](#-filetree)\n  - [\u003e install](#-install)\n- [Inline transforms](#inline-transforms)\n- [Legacy v1 \u0026 v2 plugins](#legacy-v1--v2-plugins)\n- [Adding Custom Transforms](#adding-custom-transforms)\n- [Plugin Example](#plugin-example)\n- [Other usage examples](#other-usage-examples)\n- [Custom Transform Demo](#custom-transform-demo)\n- [Usage examples](#usage-examples)\n- [Misc Markdown helpers](#misc-markdown-helpers)\n- [Prior Art](#prior-art)\n- [License](#license)\n\n\u003c/details\u003e\n\u003c!-- ⛔️ MD-MAGIC-EXAMPLE:END --\u003e\n\n\u003c!-- ⛔️ MD-MAGIC-EXAMPLE:START FILE src=./docs/1_Getting-Started.md --\u003e\n## Install\n\n**Via npm**\n\n```bash\nnpm install markdown-magic --save-dev\n```\n\n**Via binary (no Node.js required)**\n\nDownload the prebuilt binary for your platform from [GitHub Releases](https://github.com/DavidWells/markdown-magic/releases):\n\n```bash\n# macOS (Apple Silicon)\ncurl -fsSL https://github.com/DavidWells/markdown-magic/releases/latest/download/md-magic-darwin-arm64 -o md-magic\nchmod +x md-magic\n\n# macOS (Intel)\ncurl -fsSL https://github.com/DavidWells/markdown-magic/releases/latest/download/md-magic-darwin-x64 -o md-magic\nchmod +x md-magic\n\n# Linux (x64)\ncurl -fsSL https://github.com/DavidWells/markdown-magic/releases/latest/download/md-magic-linux-x64 -o md-magic\nchmod +x md-magic\n\n# Linux (ARM64)\ncurl -fsSL https://github.com/DavidWells/markdown-magic/releases/latest/download/md-magic-linux-arm64 -o md-magic\nchmod +x md-magic\n```\n\n## Usage\n\nUse comment blocks in your markdown\n\n**Example:**\n```md\n\u003c!-- docs remote url=http://url-to-raw-md-file.md --\u003e\nThis content will be dynamically replaced from the remote url\n\u003c!-- /docs --\u003e\n```\n\nThen run `markdown-magic` via it's CLI or programmatically.\n\n### Running via CLI\n\nRun `markdown --help` to see all available CLI options\n\n```bash\nmarkdown\n# or\nmd-magic\n```\n\nCLI usage example with options\n\n```bash\nmd-magic --file '**/*.md' --config ./config.file.js\n```\n\nIn NPM scripts, `npm run docs` would run the markdown magic and parse all the `.md` files in the directory.\n\n```json\n\"scripts\": {\n  \"docs\": \"md-magic --file '**/*.md'\"\n},\n```\n\nIf you have a `markdown.config.js` file where `markdown-magic` is invoked, it will automatically use that as the configuration unless otherwise specified by `--config` flag.\n\n### Running programmatically\n\n```js\nconst { markdownMagic } = require('../src')\n\n/* By default all .md files in cwd will be processed */\nmarkdownMagic().then((results) =\u003e {\n  console.log('result keys', Object.keys(results))\n})\n```\n\n```js\nimport path from 'path'\nimport markdownMagic from 'markdown-magic'\n\n// Process a Single File\nconst markdownPath = path.join(__dirname, 'README.md')\nmarkdownMagic(markdownPath)\n```\n\n### Running in GitHub Actions\n\nUse the prebuilt binary to automatically update markdown files on push:\n\n```yaml\nname: Update Markdown\n\non:\n  push:\n    paths:\n      - '**.md'\n      - 'src/**'\n\njobs:\n  update-docs:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Download md-magic\n        run: |\n          curl -fsSL https://github.com/DavidWells/markdown-magic/releases/latest/download/md-magic-linux-x64 -o md-magic\n          chmod +x md-magic\n\n      - name: Run markdown-magic\n        run: ./md-magic --files '**/*.md'\n\n      - name: Commit changes\n        run: |\n          git config user.name \"github-actions[bot]\"\n          git config user.email \"github-actions[bot]@users.noreply.github.com\"\n          git add -A\n          git diff --staged --quiet || git commit -m \"docs: update markdown\"\n          git push\n```\n\n#### Alternative GitHub Actions\n\n- [markdown-code-inject](https://github.com/Cox65/markdown-code-inject) - Inject code snippets into markdown\n- [markdown-autodocs](https://github.com/dineshsonachalam/markdown-autodocs) - Auto-generate docs from code\n\u003c!-- ⛔️ MD-MAGIC-EXAMPLE:END *--\u003e\n\n\u003c!-- ⛔️ MD-MAGIC-EXAMPLE:START (FILE:src=./docs/Syntax.md) --\u003e\n## Syntax Examples\n\nThere are various syntax options. Choose your favorite.\n\n### Basic\n\n`openWord transformName [opts]`\n\n```md\n\u003c!-- docs transformName optionOne='hello' optionTwo='there' --\u003e\ncontent to be replaced\n\u003c!-- /docs --\u003e\n```\n\n### Curly braces\n\n`openWord {transformName} [opts]`\n\n```md\n\u003c!-- docs {transformName} optionOne='hello' optionTwo='there' --\u003e\ncontent to be replaced\n\u003c!-- /docs --\u003e\n```\n\n### Square brackets\n\n`openWord [transformName] [opts]`\n\n```md\n\u003c!-- docs [transformName] optionOne='hello' optionTwo='there' --\u003e\ncontent to be replaced\n\u003c!-- /docs --\u003e\n```\n\n### Parentheses\n\n`openWord (transformName) [opts]`\n\n```md\n\u003c!-- docs (transformName) optionOne='hello' optionTwo='there' --\u003e\ncontent to be replaced\n\u003c!-- /docs --\u003e\n```\n\n### Functions\n\n`openWord transformName([opts])`\n\n```md\n\u003c!-- docs transformName(\n  foo='bar'\n  baz=['qux', 'quux']\n) --\u003e\ncontent to be replaced\n\u003c!-- /docs --\u003e\n```\n\u003c!-- ⛔️ MD-MAGIC-EXAMPLE:END *--\u003e\n\n\u003c!-- ⛔️ MD-MAGIC-EXAMPLE:START JSDocs path=\"./src/index.js\" --\u003e\n### API\n\nMarkdown Magic Instance\n\n```js\nmarkdownMagic(globOrOpts, options)\n```\n\n| Name | Type | Description |\n|:---------------------------|:---------------:|:-----------|\n| `globOrOpts` | `FilePathsOrGlobs or MarkdownMagicOptions` | Files to process or config. |\n| `options` (optional) | `MarkdownMagicOptions` | Markdown magic config. |\n\n**Returns**\n\n`Promise\u003cMarkdownMagicResult\u003e`\n\n**Example**\n\n```js\nmarkdownMagic(['**.**.md'], options).then((result) =\u003e {\n  console.log(`Processing complete`, result)\n})\n```\n\n#### `MarkdownMagicOptions`\n\nConfiguration for markdown magic\n\nBelow is the main config for `markdown-magic`\n\n| Name | Type | Description |\n|:---------------------------|:---------------:|:-----------|\n| `files` (optional) | `FilePathsOrGlobs` | Files to process. |\n| `transforms` (optional) | `Array` | Custom commands to transform block contents, see transforms \u0026 custom transforms sections below. Default: `defaultTransforms` |\n| `output` (optional) | `OutputConfig` | Output configuration. |\n| `syntax` (optional) | `SyntaxType` | Syntax to parse. Default: `md` |\n| `open` (optional) | `string` | Opening match word. Default: `docs` |\n| `close` (optional) | `string` | Closing match word. If not defined will be same as opening word. Default: `/docs` |\n| `cwd` (optional) | `string` | Current working directory. Default process.cwd(). Default: `process.cwd() ` |\n| `outputFlatten` (optional) | `boolean` | Flatten files that are output. |\n| `useGitGlob` (optional) | `boolean` | Use git glob for LARGE file directories. |\n| `dryRun` (optional) | `boolean` | See planned execution of matched blocks. Default: `false` |\n| `debug` (optional) | `boolean` | See debug details. Default: `false` |\n| `silent` (optional) | `boolean` | Silence all console output. Default: `false` |\n| `applyTransformsToSource` (optional) | `boolean` | Apply transforms to source file. Default is true. Default: `true` |\n| `failOnMissingTransforms` (optional) | `boolean` | Fail if transform functions are missing. Default skip blocks. Default: `false` |\n| `failOnMissingRemote` (optional) | `boolean` | Fail if remote file is missing. Default: `true` |\n\n#### `OutputConfig`\n\nOptional output configuration\n\n| Name | Type | Description |\n|:---------------------------|:---------------:|:-----------|\n| `directory` (optional) | `string` | Change output path of new content. Default behavior is replacing the original file. |\n| `removeComments` (optional) | `boolean` | Remove comments from output. Default is false. Default: `false` |\n| `pathFormatter` (optional) | `function` | Custom function for altering output paths. |\n| `applyTransformsToSource` (optional) | `boolean` | Apply transforms to source file. Default is true. This is for when outputDir is set. Default: `false` |\n\n#### `MarkdownMagicResult`\n\nResult of markdown processing\n\n| Name | Type | Description |\n|:---------------------------|:---------------:|:-----------|\n| `errors` | `Array` | Any errors encountered. |\n| `filesChanged` | `Array\u003cstring\u003e` | Modified files. |\n| `results` | `Array` | md data. |\n\u003c!-- ⛔️ MD-MAGIC-EXAMPLE:END - Do not remove or modify this section --\u003e\n\n## Transforms\n\nMarkdown Magic comes with a couple of built-in transforms for you to use or you can extend it with your own transforms. See 'Custom Transforms' below.\n\n\u003c!-- ⛔️ MD-MAGIC-EXAMPLE:START JSDocs path=\"./src/transforms/index.js\" --\u003e\n### \u003e TOC\n\nGenerate table of contents from markdown file\n\n**Options:**\n- `firstH1` - *boolean* - (optional): Show first h1 of doc in table of contents. Default `false`\n- `collapse` - *boolean* - (optional): Collapse the table of contents in a detail accordion. Default `false`\n- `collapseText` - *string* - (optional): Text the toc accordion summary\n- `excludeText` - *string* - (optional): Text to exclude in the table of contents. Default `Table of Contents`\n- `maxDepth` - *number* - (optional): Max depth of headings. Default 4\n\n**Example:**\n```md\n\u003c!-- docs TOC --\u003e\ntoc will be generated here\n\u003c!-- /docs --\u003e\n```\n\nDefault `matchWord` is `docs`\n\n---\n\n| Name | Type | Description |\n|:---------------------------|:---------------:|:-----------|\n| `content` | `string` | The current content of the comment block. |\n| `options` | `object` | The options passed in from the comment declaration. |\n\n### \u003e CODE\n\nGet code from file or URL and put in markdown\n\n**Options:**\n- `src`: The relative path to the code to pull in, or the `URL` where the raw code lives\n- `syntax` (optional): Syntax will be inferred by fileType if not specified\n- `header` (optional): Will add header comment to code snippet. Useful for pointing to relative source directory or adding live doc links\n- `lines` (optional): a range with lines of code which will then be replaced with code from the file. The line range should be defined as: \"lines=*startLine*-*EndLine*\" (for example: \"lines=22-44\"). Please see the example below\n\n**Example:**\n```md\n\u003c!-- docs CODE src=\"./relative/path/to/code.js\" --\u003e\nThis content will be dynamically replaced with code from the file\n\u003c!-- /docs --\u003e\n```\n\n```md\n \u003c!-- docs CODE src=\"./relative/path/to/code.js\" lines=22-44 --\u003e\n This content will be dynamically replaced with code from the file lines 22 through 44\n \u003c!-- /docs --\u003e\n ```\n\nDefault `matchWord` is `docs`\n\n---\n\n| Name | Type | Description |\n|:---------------------------|:---------------:|:-----------|\n| `content` | `string` | The current content of the comment block. |\n| `options` | `object` | The options passed in from the comment declaration. |\n\n### \u003e FILE\n\nGet local file contents.\n\n**Options:**\n- `src`: The relative path to the file to pull in\n\n**Example:**\n```md\n\u003c!-- docs FILE src=./path/to/file --\u003e\nThis content will be dynamically replaced from the local file\n\u003c!-- /docs --\u003e\n```\n\nDefault `matchWord` is `docs`\n\n---\n\n| Name | Type | Description |\n|:---------------------------|:---------------:|:-----------|\n| `content` | `string` | The current content of the comment block. |\n| `options` | `object` | The options passed in from the comment declaration. |\n\n### \u003e REMOTE\n\nGet any remote Data and put in markdown\n\n**Options:**\n- `url`: The URL of the remote content to pull in\n\n**Example:**\n```md\n\u003c!-- docs REMOTE url=http://url-to-raw-md-file.md --\u003e\nThis content will be dynamically replaced from the remote url\n\u003c!-- /docs --\u003e\n```\n\nDefault `matchWord` is `docs`\n\n---\n\n| Name | Type | Description |\n|:---------------------------|:---------------:|:-----------|\n| `content` | `string` | The current content of the comment block. |\n| `options` | `object` | The options passed in from the comment declaration. |\n\n### \u003e fileTree\n\nGenerate a file tree table of contents\n\n**Options:**\n- `src` (optional): The directory path to generate the file tree for. Default `.` (current directory)\n- `maxDepth` (optional): Maximum depth to traverse in the directory tree. Default `3`\n- `includeFiles` (optional): Whether to include files in the tree or just directories. Default `true`\n- `exclude` (optional): Array of glob patterns to exclude from the tree. Default `[]`\n- `showSize` (optional): Whether to show file sizes. Default `false`\n- `format` (optional): Output format: \"tree\" or \"list\". Default `\"tree\"`\n\n**Example:**\n```md\n\u003c!-- docs fileTree src=\"./src\" maxDepth=2 --\u003e\nfile tree will be generated here\n\u003c!-- /docs --\u003e\n```\n\n**Example Output (tree format):**\n```\n└── src/\n    ├── transforms/\n    │   ├── code/\n    │   │   ...\n    │   ├── fileTree.js\n    │   ├── index.js\n    │   └── toc.js\n    ├── utils/\n    │   ├── fs.js\n    │   ├── logs.js\n    │   └── text.js\n    └── index.js\n```\n\n**Example Output (list format):**\n```md\n- **src/**\n  - **transforms/**\n    - **code/**\n      - ...\n    - fileTree.js\n    - index.js\n    - toc.js\n  - **utils/**\n    - fs.js\n    - logs.js\n    - text.js\n  - index.js\n```\n\n**Example with file sizes:**\n```\n└── src/\n    ├── index.js (15.2 KB)\n    └── package.json (552 B)\n```\n\nDefault `matchWord` is `docs`\n\n---\n\n| Name | Type | Description |\n|:---------------------------|:---------------:|:-----------|\n| `content` | `string` | The current content of the comment block. |\n| `options` | `object` | The options passed in from the comment declaration. |\n\n### \u003e install\n\nGenerate installation instructions in a markdown table format\n\n**Options:**\n- `packageName` (optional): The name of the package to install. If not provided, will try to read from package.json\n- `isDev` (optional): Whether to install the package as a dev dependency. Default `false`\n- `header` (optional): The header to use for the installation instructions. Default `# Installation`\n- `body` (optional): The body to use for the installation instructions. Default `Install the \\`${packageName}\\` cli using your favorite package manager.`\n\n**Example:**\n```md\n\u003c!-- docs install --\u003e\nInstallation instructions will be generated here\n\u003c!-- /docs --\u003e\n```\n\nDefault `matchWord` is `docs`\n\n---\n\n| Name | Type | Description |\n|:---------------------------|:---------------:|:-----------|\n| `content` | `string` | The current content of the comment block. |\n| `options` | `object` | The options passed in from the comment declaration. |\n\u003c!-- ⛔️ MD-MAGIC-EXAMPLE:END - Do not remove or modify this section --\u003e\n\n## Inline transforms\n\nAny transform, including custom transforms can be used inline as well to insert content into paragraphs and other places.\n\nThe face symbol 👉 \u003c!-- MD-MAGIC-EXAMPLE:START (INLINE_EXAMPLE) --\u003e**⊂◉‿◉つ**\u003c!-- MD-MAGIC-EXAMPLE:END --\u003e is auto generated inline.\n\n**Example:**\n```md\n\u003c!-- docs (FILE:src=./path/to/file) --\u003exyz\u003c!-- /docs --\u003e\n```\n\n## Legacy v1 \u0026 v2 plugins\n\nThese plugins work with older versions of markdown-magic. Adapting them to the newer plugin syntax should be pretty straight forward.\n\n* [wordcount](https://github.com/DavidWells/markdown-magic-wordcount/) - Add wordcount to markdown files\n* [github-contributors](https://github.com/DavidWells/markdown-magic-github-contributors) - List out the contributors of a given repository\n* [directory-tree](https://github.com/camacho/markdown-magic-directory-tree) - Add directory tree to markdown files\n* [install-command](https://github.com/camacho/markdown-magic-install-command) - Add install command to markdown files with `peerDependencies` included\n* [subpackage-list](https://github.com/camacho/markdown-magic-subpackage-list) - Add list of all subpackages (great for projects that use [Lerna](https://github.com/lerna/lerna))\n* [version-badge](https://github.com/camacho/markdown-magic-version-badge) - Add a badge with the latest version of the project\n* [template](https://github.com/camacho/markdown-magic-template) - Add Lodash template support\n* [dependency-table](https://github.com/camacho/markdown-magic-dependency-table) - Add a table of dependencies with links to their repositories, version information, and a short description\n* [package-scripts](https://github.com/camacho/markdown-magic-package-scripts) - Add a table of `package.json` scripts with descriptions\n* [prettier](https://github.com/camacho/markdown-magic-prettier) - Format code blocks with [`prettier`](https://github.com/prettier/prettier)\n* [engines](https://github.com/camacho/markdown-magic-engines) - Print engines list from `package.json`\n* [jsdoc](https://github.com/bradtaylorsf/markdown-magic-jsdoc) - Adds jsdoc comment support\n* [build-badge](https://github.com/rishichawda/markdown-magic-build-badge) - Update branch badges to auto-magically point to current branches.\n* [package-json](https://github.com/forresst/markdown-magic-package-json) - Add the package.json properties to markdown files\n* [figlet](https://github.com/lafourchette/markdown-magic-figlet) - Add FIGfont text to markdown files\n* [local-image](https://github.com/stevenbenisek/markdown-magic-local-image) - plugin to add local images to markdown\n* [markdown-magic-build-badge](https://github.com/rishichawda/markdown-magic-build-badge) - A plugin to update your branch badges to point to correct branch status\n* [markdown-magic-json-path](https://github.com/mariohamann/markdown-magic-json-path) – Extract and insert specific values from any JSON file into your Markdown documents.\n\n## Adding Custom Transforms\n\nMarkdown Magic is extendable via plugins.\n\nPlugins allow developers to add new transforms to the `config.transforms` object. This allows for things like using different rendering engines, custom formatting, or any other logic you might want.\n\nPlugins run in order of registration.\n\nThe below code is used to generate **this markdown file** via the plugin system.\n\n\u003c!-- ⛔️ MD-MAGIC-EXAMPLE:START (CODE:src=./examples/generate-readme.js) --\u003e\n```js\nconst path = require('path')\nconst { readFileSync } = require('fs')\nconst { parseComments } = require('doxxx')\nconst { markdownMagic } = require('../src')\nconst { deepLog } = require('../src/utils/logs')\n\nconst config = {\n  matchWord: 'MD-MAGIC-EXAMPLE', // default matchWord is AUTO-GENERATED-CONTENT\n  transforms: {\n    /* Match \u003c!-- AUTO-GENERATED-CONTENT:START (customTransform:optionOne=hi\u0026optionOne=DUDE) --\u003e */\n    customTransform({ content, options }) {\n      console.log('original content in comment block', content)\n      console.log('options defined on transform', options)\n      // options = { optionOne: hi, optionOne: DUDE}\n      return `This will replace all the contents of inside the comment ${options.optionOne}`\n    },\n    /* Match \u003c!-- AUTO-GENERATED-CONTENT:START JSDocs path=\"../file.js\" --\u003e */\n    JSDocs(markdownMagicPluginAPI) {\n      const { options } = markdownMagicPluginAPI\n      const fileContents = readFileSync(options.path, 'utf8')\n      const docBlocs = parseComments(fileContents, { skipSingleStar: true })\n        .filter((item) =\u003e {\n          return !item.isIgnored\n        })\n        /* Remove empty comments with no tags */\n        .filter((item) =\u003e {\n          return item.tags.length\n        })\n        /* Remove inline type defs */\n        .filter((item) =\u003e {\n          return item.description.text !== ''\n        })\n        /* Sort types to end */\n        .sort((a, b) =\u003e {\n          if (a.type \u0026\u0026 !b.type) return 1\n          if (!a.type \u0026\u0026 b.type) return -1\n          return 0\n        })\n\n      docBlocs.forEach((data) =\u003e {\n        // console.log('data', data)\n        delete data.code\n      })\n      // console.log('docBlocs', docBlocs)\n\n      if (docBlocs.length === 0) {\n        throw new Error('No docBlocs found')\n      }\n\n      // console.log(docBlocs.length)\n      let updatedContent = ''\n      docBlocs.forEach((data) =\u003e {\n        if (data.type) {\n          updatedContent += `#### \\`${data.type}\\`\\n\\n`\n        }\n\n        updatedContent += `${data.description.text}\\n`\n\n        if (data.tags.length) {\n         let table =  '| Name | Type | Description |\\n'\n          table += '|:---------------------------|:---------------:|:-----------|\\n'\n          data.tags.filter((tag) =\u003e {\n            if (tag.tagType === 'param') return true\n            if (tag.tagType === 'property') return true\n            return false\n          }).forEach((tag) =\u003e {\n            const optionalText = tag.isOptional ? ' (optional) ' : ' '\n            const defaultValueText = (typeof tag.defaultValue !== 'undefined') ? ` Default: \\`${tag.defaultValue}\\` ` : ' '\n            table += `| \\`${tag.name}\\`${optionalText}`\n            table += `| \\`${tag.type.replace('|', 'or')}\\` `\n            table += `| ${tag.description.replace(/\\.\\s?$/, '')}.${defaultValueText}|\\n`\n          })\n          updatedContent+= `\\n${table}\\n`\n\n          const returnValues = data.tags.filter((tag) =\u003e tag.tagType === 'returns')\n          if (returnValues.length) {\n            returnValues.forEach((returnValue) =\u003e {\n              updatedContent += `**Returns**\\n\\n`\n              updatedContent += `\\`${returnValue.type}\\`\\n\\n`\n            })\n          }\n\n          const examples = data.tags.filter((tag) =\u003e tag.tagType === 'example')\n          if (examples.length) {\n            examples.forEach((example) =\u003e {\n              updatedContent += `**Example**\\n\\n`\n              updatedContent += `\\`\\`\\`js\\n${example.tagValue}\\n\\`\\`\\`\\n\\n`\n            })\n          }\n        }\n      })\n      return updatedContent.replace(/^\\s+|\\s+$/g, '')\n    },\n    INLINE_EXAMPLE: () =\u003e {\n      return '**⊂◉‿◉つ**'\n    },\n    lolz() {\n      return `This section was generated by the cli config markdown.config.js file`\n    },\n    /* Match \u003c!-- AUTO-GENERATED-CONTENT:START (pluginExample) --\u003e */\n    pluginExample: require('./plugin-example')({ addNewLine: true }),\n    /* Include plugins from NPM */\n    // count: require('markdown-magic-wordcount'),\n    // github: require('markdown-magic-github-contributors')\n  }\n}\n\nconst markdownPath = path.join(__dirname, '..', 'README.md')\nmarkdownMagic(markdownPath, config, () =\u003e {\n  console.log('Docs ready')\n})\n```\n\u003c!-- ⛔️ MD-MAGIC-EXAMPLE:END --\u003e\n\n## Plugin Example\n\nPlugins must return a transform function with the following signature.\n\n```js\nreturn function myCustomTransform (content, options)\n```\n\n\u003c!-- ⛔️ MD-MAGIC-EXAMPLE:START (CODE:src=./examples/plugin-example.js) --\u003e\n```js\n/* Custom Transform Plugin example */\nmodule.exports = function customPlugin(pluginOptions) {\n  // set plugin defaults\n  const defaultOptions = {\n    addNewLine: false\n  }\n  const userOptions = pluginOptions || {}\n  const pluginConfig = Object.assign(defaultOptions, userOptions)\n  // return the transform function\n  return function myCustomTransform ({ content, options }) {\n    const newLine = (pluginConfig.addNewLine) ? '\\n' : ''\n    const updatedContent = content + newLine\n    return updatedContent\n  }\n}\n```\n\u003c!-- ⛔️ MD-MAGIC-EXAMPLE:END --\u003e\n\n[View the raw file](https://raw.githubusercontent.com/DavidWells/markdown-magic/master/README.md) file and run `npm run docs` to see this plugin run\n\u003c!-- ⛔️ MD-MAGIC-EXAMPLE:START (pluginExample) ⛔️ --\u003e\nThis content is altered by the `pluginExample` plugin registered in `examples/generate-readme.js`\n\u003c!-- ⛔️ MD-MAGIC-EXAMPLE:END --\u003e\n\n## Other usage examples\n\n- [With Github Actions](https://github.com/dineshsonachalam/repo-using-markdown-autodocs)\n- [Serverless Plugin Repo](https://github.com/serverless/plugins/blob/master/generate-docs.js) this example takes a `json` file and converts it into a github flavored markdown table\n- [MochaJS](https://github.com/mochajs/mocha/blob/4cc711fa00f7166a2303b77bf2487d1c2cc94621/scripts/markdown-magic.config.js)\n- [tc39/agendas](https://github.com/tc39/agendas#agendas) - [code](https://github.com/tc39/agendas/blob/65945b1b6658e9829ef95a51bf2632ff44f951e6/scripts/generate.js)\n- [moleculerjs/moleculer-addons](https://github.com/moleculerjs/moleculer-addons/blob/7cf0f72140717c52621b724cd54a710517106df0/readme-generator.js)\n- [good-first-issue](https://github.com/bnb/good-first-issue/blob/e65513a1f26167dea3c137008b8796640d8d5303/markdown.config.js)\n- [navikt/nav-frontend-moduler](https://github.com/navikt/nav-frontend-moduler/blob/20ad521c27a43d3203eab4bc32121e5b8270c077/_scripts/generateReadmes.js)\n- [country-flags-svg](https://github.com/ronatskiy/country-flags-svg/blob/cfb2368c7e634ebc1679855e13cc3e26ca11187f/markdown.config.js)\n- [react-typesetting](https://github.com/exogen/react-typesetting/blob/7114cdc8c4cb1b0d59ebc8b5364e808687419889/markdown.config.js)\n- [and many more!](https://github.com/search?o=desc\u0026p=1\u0026q=markdown-magic+filename%3Apackage.json+-user%3Ah13i32maru+-user%3Aesdoc+-user%3Aes-doc\u0026s=indexed\u0026type=Code)\n\n## Custom Transform Demo\n\nView the raw source of this `README.md` file to see the comment block and see how the `customTransform` function in `examples/generate-readme.js` works\n\n\u003c!-- ⛔️ MD-MAGIC-EXAMPLE:START (customTransform:optionOne=hi\u0026optionOne=DUDE) - Do not remove or modify this section --\u003e\nThis will replace all the contents of inside the comment DUDE\n\u003c!-- ⛔️ MD-MAGIC-EXAMPLE:END - Do not remove or modify this section --\u003e\n\n## Usage examples\n\n- [Projects using markdown-magic](https://github.com/search?q=path%3A**%2Fpackage.json+%22markdown-magic%22\u0026type=code)\n- [Examples in md](https://github.com/search?l=Markdown\u0026o=desc\u0026q=AUTO-GENERATED-CONTENT\u0026s=indexed\u0026type=Code)\n\n\n## Misc Markdown helpers\n\n- https://github.com/azu/markdown-function\n\n## Prior Art\n\nThis was inspired by [Kent C Dodds](https://twitter.com/kentcdodds) and [jfmengels](https://github.com/jfmengels)'s [all contributors cli](https://github.com/jfmengels/all-contributors-cli) project.\n\n## License\n\n[MIT][mit] © [DavidWells][author]\n\n[npm-badge]:https://img.shields.io/npm/v/markdown-magic.svg?style=flat-square\n[npm-link]: http://www.npmjs.com/package/markdown-magic\n[mit]:      http://opensource.org/licenses/MIT\n[author]:   http://github.com/davidwells\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavidwells%2Fmarkdown-magic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavidwells%2Fmarkdown-magic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavidwells%2Fmarkdown-magic/lists"}