{"_id":"@btnguyen2k/mdr","name":"@btnguyen2k/mdr","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@btnguyen2k/mdr","version":"0.1.0","description":"Render Markdown to HTML with rich extensions.","type":"module","main":"./lib/index.cjs","module":"./src/index.js","browser":"./lib/index.umd.js","exports":{".":{"import":"./src/index.js","require":"./lib/index.cjs"}},"scripts":{"build":"npm run lint && babel ./src -d ./lib","lint":"eslint .","test":"jest --verbose","test:cover":"jest --verbose --coverage"},"repository":{"type":"git","url":"git+https://github.com/btnguyen2k/js-mdr.git"},"keywords":["Markdown"],"author":{"name":"Thanh Nguyen","email":"btnguyen2k (at) gmail (dot) com","url":"at"},"license":"MIT","bugs":{"url":"https://github.com/btnguyen2k/js-mdr/issues"},"homepage":"https://github.com/btnguyen2k/js-mdr#readme","dependencies":{"@btnguyen2k/checksum":"^0.1.3","dompurify":"^3.0.4","github-slugger":"^2.0.0","highlight.js":"^11.8.0","jsdom":"^22.1.0","katex":"^0.16.8","marked":"^5.1.1","marked-base-url":"^1.0.3","marked-mangle":"^1.1.0"},"devDependencies":{"@babel/cli":"^7.22.6","@babel/core":"^7.22.8","@babel/preset-env":"^7.22.7","@babel/preset-typescript":"^7.22.5","@babel/register":"^7.22.5","@semantic-release/changelog":"^6.0.3","@semantic-release/commit-analyzer":"^10.0.1","@semantic-release/git":"^10.0.1","@semantic-release/github":"^9.0.4","@semantic-release/npm":"^10.0.4","@semantic-release/release-notes-generator":"^11.0.4","babel-jest":"^29.6.1","dom-compare":"^0.1.1","eslint":"^8.44.0","eslint-config-standard":"^17.1.0","eslint-plugin-import":"^2.27.5","eslint-plugin-n":"^16.0.1","eslint-plugin-promise":"^6.1.1","jest-cli":"^29.6.1","semantic-release":"^21.0.7"},"gitHead":"8164b9cd4380059dc4aa0d4f8107d2e1c5214bcb","_id":"@btnguyen2k/mdr@0.1.0","_nodeVersion":"18.16.0","_npmVersion":"8.5.5","dist":{"integrity":"sha512-0M0GcovGXlHH+5kEieu9Ilx4t9CkagVTv/4IbIb09vYMnyr/zgqSEL+ICU3JiVpldFB6IA0nvhRsKn+54ATcJQ==","shasum":"5be607509c55b06b02117beb6f92f16b427ef1e9","tarball":"https://registry.npmjs.org/@btnguyen2k/mdr/-/mdr-0.1.0.tgz","fileCount":22,"unpackedSize":54225,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFYP+Ou6STOvokKbxPcMAYWRo1dF8LvGq7cVwsOdWYRtAiEAjOKJuPplqiZw9tfbmkdHPXVSlJGcaZ+wbqKThjkwsBQ="}]},"_npmUser":{"name":"btnguyen2k","email":"btnguyen2k@gmail.com"},"directories":{},"maintainers":[{"name":"btnguyen2k","email":"btnguyen2k@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/mdr_0.1.0_1691058306063_0.8234526532588613"},"_hasShrinkwrap":false}},"time":{"created":"2023-08-03T10:25:06.000Z","0.1.0":"2023-08-03T10:25:06.237Z","modified":"2023-08-03T10:25:06.421Z"},"maintainers":[{"name":"btnguyen2k","email":"btnguyen2k@gmail.com"}],"description":"Render Markdown to HTML with rich extensions.","homepage":"https://github.com/btnguyen2k/js-mdr#readme","keywords":["Markdown"],"repository":{"type":"git","url":"git+https://github.com/btnguyen2k/js-mdr.git"},"author":{"name":"Thanh Nguyen","email":"btnguyen2k (at) gmail (dot) com","url":"at"},"bugs":{"url":"https://github.com/btnguyen2k/js-mdr/issues"},"license":"MIT","readme":"# mdr\r\n\r\n[![npm](https://badgen.net/npm/v/@btnguyen2k/mdr)](https://www.npmjs.com/package/@btnguyen2k/mdr)\r\n[![Actions Status](https://github.com/btnguyen2k/js-mdr/actions/workflows/ci.yaml/badge.svg)](https://github.com/btnguyen2k/js-mdr/actions)\r\n[![codecov](https://codecov.io/gh/btnguyen2k/js-mdr/branch/main/graph/badge.svg)](https://codecov.io/gh/btnguyen2k/js-mdr)\r\n\r\nRender Markdown to HTML with rich extensions.\r\n\r\n⭐ Based on [markedjs](https://marked.js.org/) with GFM flavor. Enabled extensions:\r\n- marked-base-url\r\n- marked-mangle\r\n- GFM header-id\r\n\r\n⭐ Code highlight with [highlight.js](https://highlightjs.org/).\r\n\r\n⭐ Support [Katex](https://katex.org/) math formula.\r\n\r\n## Installation\r\n\r\n**with npm**\r\n\r\n```shell\r\n$ npm install -S @btnguyen2k/mdr\r\n```\r\n\r\n## Usage\r\n\r\nThis package exports a function `mdr` that can be used to render Markdown to HTML:\r\n\r\n```javascript\r\nimport {mdr} from '@btnguyen2k/mdr'\r\n\r\nconst markdown = '# Hello World!'\r\nconst options = {} // optional\r\nconsole.log(mdr(markdown, options)) // <h1 id=\"hello-world\">Hello World!</h1>\r\n```\r\n\r\n## Options\r\n\r\nFunction `mdr` takes an optional 2nd argument, which is an object with the following properties:\r\n\r\n| Property                      | Type     | Default                                          | Description                                                                                                                                                                           |\r\n|-------------------------------|----------|--------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\r\n| inline                        | boolean  | `false`                                          | If `true`, the output HTML will _not_ be wrapped in `<p>` tag.                                                                                                                        |\r\n| safety                        | boolean  | `true`                                           | If `true`, the output HTML will be sanitized using DOMPurify.                                                                                                                         |\r\n| safety_opts                   | object   | (see bellow)                                     | Options for DOMPurify if `safety=true`.                                                                                                                                               |\r\n| safety_opts.add_tags          | array    | `['iframe']`                                     | Additional tags to allow <sup>[1]</sup>.                                                                                                                                              |\r\n| safety_opts.add_data_uri_tags | array    | `['iframe']`                                     | Additional tags to allow data URI <sup>[1]</sup>.                                                                                                                                     |\r\n| safety_opts.add_attrs         | array    | `['target', 'allow']`                            | Additional attributes to allow <sup>[1][2]</sup>.                                                                                                                                     |\r\n| toc_container                 | array    | undefined                                        | If supplied, the generated table of content will be pushed to this array.                                                                                                             |\r\n| katex                         | boolean  | `true`                                           | If `true`, KaTeX support is enabled.                                                                                                                                                  |\r\n| katex_opts                    | object   | `{output: 'htmlAndMathml', throwOnError: false}` | Options for KaTeX if `katex=true`. See see https://katex.org/docs/options.html                                                                                                        |\r\n| ghgist                        | boolean  | `true`                                           | If `true`, GitHub Gist support is enabled.                                                                                                                                            |\r\n| ghgist_opts                   | object   | `{}`                                             | Options for GitHub Gist if `ghgist=true`. See below for details.                                                                                                                      |\r\n| video                         | boolean  | `true`                                           | If `true`, video embedding is enabled.                                                                                                                                                |\r\n| video_opts                    | object   | `{}`                                             | Options for video embedding if `video=true`. See below for details.                                                                                                                   |\r\n| code_handlers                 | object   | `{}`                                             | Custom code block handlers, in format `{code_id: handler}`. If matched, the code enclosed between ```code_id and ``` will be handled by the specified handler. See below for details. |\r\n| baseUrl (*)                   | string   | undefined                                        | If supplied, `marked-base-url` extension is enabled.                                                                                                                                  |\r\n| headerIds (*)                 | boolean  | `true`                                           | If `true`, headings are generated with id attribute.                                                                                                                                  |\r\n| headerPrefix (*)              | string   | `''`                                             | If present, values of generated id attributes are prefixed by this value (imply `headingIds=true`).                                                                                   |\r\n| mangle (*)                    | boolean  | `true`                                           | If `true`, `marked-mangle` extension is enabled.                                                                                                                                      |\r\n| highlight (*)                 | function | undefined                                        | If supplied, `highlight` function is used to highlight source code.                                                                                                                   |\r\n| langPrefix (*)                | string   | `null`                                           | If present, `langPrefix` is used to prefix language name in generated code block.                                                                                                     |\r\n\r\n> - [1] `iframe` is used by GitHub Gist and Youtube video extensions. `allow` attribute is also used to enable Youtube features such as fullscreen, autoplay, picture-in-picture, etc.\r\n> - [2] `target` attribute is useful for extrernal links.\r\n> - (*) Do use these options with `mdr`, do _not_ use marked's extensions (e.g. `marked-highlight`, etc) directly.\r\n\r\n### Embedding GitHub Gist\r\n\r\n`mdr` supports embedding GitHub Gist in Markdown using the following syntax:\r\n\r\n<pre>\r\n```gh-gist gistUrl [options]\r\n```\r\n</pre>\r\n\r\n| Parameters/Options       | Description                                                                                                                                                                                 |\r\n|--------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\r\n| gistUrl                  | The GitHub Gist to embed, can be in short form (e.g. `btnguyen2k/d7577db0981cb157ae95b67b9f6dd733`) or full URL (e.g. https://gist.github.com/btnguyen2k/d7577db0981cb157ae95b67b9f6dd733). |\r\n| style=\"custom-css-style\" | Custom CSS style to apply to the embedded Gist.                                                                                                                                             |\r\n| class=\"custom-css-class\" | Custom CSS class to apply to the embedded Gist.                                                                                                                                             |\r\n\r\nExample:\r\n\r\n<pre>\r\n```gh-gist btnguyen2k/d7577db0981cb157ae95b67b9f6dd733 class=\"gist-embed\" style=\"width: 100%; padding-bottom: 8px;\"\r\n```\r\n</pre>\r\n\r\nDefault values for options `style` and `class` can be specified in `ghgist_opts`:\r\n\r\n```javascript\r\nimport {mdr} from '@btnguyen2k/mdr'\r\n\r\nconst input = '```gh-gist btnguyen2k/d7577db0981cb157ae95b67b9f6dd733\\n```'\r\nconst output = mdr(input, {\r\n  ghgist_opts: {\r\n    style: 'width: 100%; padding-bottom: 8px;',\r\n    class: 'gist-embed'\r\n  }\r\n})\r\n```\r\n\r\n### Embedding video\r\n\r\n`mdr` supports embedding video in Markdown using the following syntax:\r\n\r\n<pre>\r\n```video videoUrl [options]\r\n```\r\n</pre>\r\n\r\n| Parameters/Options       | Description                                      |\r\n|--------------------------|--------------------------------------------------|\r\n| videoUrl                 | The video embed.                                 |\r\n| style=\"custom-css-style\" | Custom CSS style to apply to the embedded video. |\r\n| class=\"custom-css-class\" | Custom CSS class to apply to the embedded video. |\r\n\r\nExample:\r\n\r\n<pre>\r\n```video my-video.mp4 class=\"video-embed\" style=\"width: 100%; padding-bottom: 8px;\"\r\n```\r\n</pre>\r\n\r\nDefault values for options `style` and `class` can be specified in `video_opts`:\r\n\r\n```javascript\r\nimport {mdr} from '@btnguyen2k/mdr'\r\n\r\nconst input = '```video my-video.mp4\\n```'\r\nconst output = mdr(input, {\r\n  video_opts: {\r\n    style: 'width: 100%; padding-bottom: 8px;',\r\n    class: 'gist-embed'\r\n  }\r\n})\r\n```\r\n\r\n### Extending MDR\r\n\r\nApplication developers can extend `mdr` by adding custom code block handlers. For example, the following code adds a custom code block handler to support [Bootstrap Alerts](https://getbootstrap.com/docs/5.0/components/alerts/:\r\n\r\n```javascript\r\nconst opts = {\r\n  code_handlers: {\r\n    'bs-alert': (code, infoString) => {\r\n      const alertStyle = infoString ? infoString.slice('bs-alert'.length).trim() : 'primary'\r\n      return `<div class=\"alert alert-${alertStyle}\" role=\"alert\">${code}</div>`\r\n    }\r\n  }\r\n}\r\n\r\nconst input = '```bs-alert info\\nA simple primary alert—check it out!\\n```'\r\nconst output = mdr(input, opts) // '<div class=\"alert alert-info\" role=\"alert\">A simple primary alert—check it out!</div>'\r\n```\r\n\r\n## License\r\n\r\nMIT - see [LICENSE.md](LICENSE.md).\r\n","readmeFilename":"README.md"}