{"id":24429502,"url":"https://github.com/umk/mdformat","last_synced_at":"2026-04-14T04:03:38.299Z","repository":{"id":235045356,"uuid":"789959097","full_name":"umk/mdformat","owner":"umk","description":"An end user friendly Markdown template engine","archived":false,"fork":false,"pushed_at":"2024-07-06T01:50:22.000Z","size":95,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-20T13:40:43.885Z","etag":null,"topics":["format","formatter","generator","html","javascript","markdown","marked","render","template","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/umk.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}},"created_at":"2024-04-22T01:57:57.000Z","updated_at":"2024-12-30T20:44:06.000Z","dependencies_parsed_at":"2024-04-23T05:07:17.176Z","dependency_job_id":"4a7736a6-c59a-4b3f-84bb-d157e56a773e","html_url":"https://github.com/umk/mdformat","commit_stats":null,"previous_names":["umk/mdformat"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umk%2Fmdformat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umk%2Fmdformat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umk%2Fmdformat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umk%2Fmdformat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/umk","download_url":"https://codeload.github.com/umk/mdformat/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243456562,"owners_count":20293905,"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":["format","formatter","generator","html","javascript","markdown","marked","render","template","typescript"],"created_at":"2025-01-20T13:39:08.862Z","updated_at":"2025-10-26T21:17:27.478Z","avatar_url":"https://github.com/umk.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MDformat\n\nMDformat is a Markdown template engine designed with end users in mind.\n\nMDformat implements a significantly reduced number of template language constructs to ensure simplicity for users new to templating. It offers an intuitive experience for inexperienced users and integrates a hint of heuristics to expand the feature set without introducing unnecessary language complexity.\n\nFeatures:\n\n- Mapping hierarchical data onto templates\n- Automatic expansion of paragraphs, lists, and tables into multiple rows when generated from data fields scoped to collection elements\n- Implementation of zip groups, enabling the combination of elements from multiple collections into one unified collection\n- Automatically encoding placeholder values if it's a part of a URL\n\nThe engine leverages the [marked](https://www.npmjs.com/package/marked) package for Markdown parsing and rendering.\n\n## Installation\n\nYou can install MDformat via npm. Make sure you have Node.js installed on your machine.\n\n```bash\nnpm install mdformat\n```\n\nAlternatively, if you prefer using yarn:\n\n```bash\nyarn add mdformat\n```\n\nOnce installed, you can start using MDformat in your project.\n\n## Examples\n\n### Rendering template with a missing field\n\nMDformat won't throw an error if input data is missing, but rather render the placeholder as is.\n\n```typescript\nimport { renderTemplateToHtml } from 'mdformat'\n\nconst content = 'Lorem ipsum dolor sit amet, {{consectetur}} adipiscing elit'\nconst data = {}\nconst result = renderTemplateToHtml(content, data)\n// Output: \u003cp\u003eLorem ipsum dolor sit amet, {{consectetur}} adipiscing elit\u003c/p\u003e\\n\n```\n\n### Rendering template with array data\n\nMDformat defines Markdown structures commonly used for enumerating elements such as top-level paragraphs, list items, and table rows. If template for these structures include a reference to an array data field or its nested properties, MDformat replicates these structures within their respective parent elements.\n\n```typescript\nimport { renderTemplateToHtml } from 'mdformat'\n\nconst content = 'Lorem ipsum dolor {{sit}} amet'\nconst data = {\n  sit: ['consectetur', 'adipiscing', 'elit'],\n}\nconst result = renderTemplateToHtml(content, data)\n/* Output:\n\u003cp\u003eLorem ipsum dolor consectetur amet\u003c/p\u003e\n\u003cp\u003eLorem ipsum dolor adipiscing amet\u003c/p\u003e\n\u003cp\u003eLorem ipsum dolor elit amet\u003c/p\u003e\n*/\n```\n\n```typescript\nimport { renderTemplateToHtml } from 'mdformat'\n\nconst content = '- Lorem ipsum dolor {{sit}} amet'\nconst data = {\n  sit: ['consectetur', 'adipiscing', 'elit'],\n}\nconst result = renderTemplateToHtml(content, data)\n/* Output:\n\u003cul\u003e\n\u003cli\u003eLorem ipsum dolor consectetur amet\u003c/li\u003e\n\u003cli\u003eLorem ipsum dolor adipiscing amet\u003c/li\u003e\n\u003cli\u003eLorem ipsum dolor elit amet\u003c/li\u003e\n\u003c/ul\u003e\n*/\n```\n\n### Rendering template with permutated fields\n\nIf a Markdown structure references two or more fields that are arrays or nested properties within arrays, but do not share the same array as their common ancestor, the elements of the arrays are permuted. The max number of permutations can be configured to avoid out of memory, especially when using the library in the back-end.\n\n```typescript\nimport { renderTemplateToHtml } from 'mdformat'\n\nconst content = '{{name}} goes to {{city}}!'\nconst data = {\n  name: ['Eduardo', 'Leanna', 'Benjamin'],\n  city: ['Haydenmouth', 'Luzport'],\n}\nconst result = renderTemplateToHtml(content, data)\n/* Output:\n\u003cp\u003eEduardo goes to Fort Haydenmouth!\u003c/p\u003e\n\u003cp\u003eLeanna goes to Fort Haydenmouth!\u003c/p\u003e\n\u003cp\u003eBenjamin goes to Fort Haydenmouth!\u003c/p\u003e\n\u003cp\u003eEduardo goes to Lake Luzport!\u003c/p\u003e\n\u003cp\u003eLeanna goes to Lake Luzport!\u003c/p\u003e\n\u003cp\u003eBenjamin goes to Lake Luzport!\u003c/p\u003e\n*/\n```\n\n### Rendering template with zipped fields\n\nTo avoid permutation when a Markdown structure refers to two or more fields that are arrays or nested properties within arrays, but do not share the same array as their common ancestor, the user can define a zip group. This zip group combines the arrays into one by index of items. If arrays have different sizes, the lesser number of items is taken.\n\n```typescript\nimport { renderTemplateToHtml } from 'mdformat'\n\nconst content = '{{itinerary:name}} goes to {{itinerary:city}}!'\nconst data = {\n  name: ['Eduardo', 'Leanna', 'Benjamin'],\n  city: ['Haydenmouth', 'Luzport'],\n}\nconst result = renderTemplateToHtml(content, data)\n/* Output:\n\u003cp\u003eEduardo goes to Fort Haydenmouth!\u003c/p\u003e\n\u003cp\u003eLeanna goes to Lake Luzport!\u003c/p\u003e\n\u003cp\u003eBenjamin goes to Felicitystad!\u003c/p\u003e\n*/\n```\n\n### Rendering template with placeholder in query parameter\n\nThe placeholders are encoded if they are a part of a URL.\n\n```typescript\nimport { renderTemplateToHtml } from 'mdformat'\n\nconst content = 'Lorem [ipsum](https://dolor.com/?sit={{sit}}) amet'\nconst data = {\n  sit: 'do\u0026eiusmod=tempor',\n}\nconst result = renderTemplateToHtml(content, data)\n/* Output:\n\u003cp\u003eLorem \u003ca href=\"https://dolor.com/?sit=do%26eiusmod%3Dtempor\"\u003eipsum\u003c/a\u003e amet\u003c/p\u003e\\n\n*/\n```\n\n## API\n\n`renderTemplateToHtml(template, data, lexer?, parser?)`\n\nCreates an HTML markup based on provided Markdown template and the data object. Can accept a string, as well as a collection of tokens as a template.\n\n`renderTemplateToTokens(template, data, lexer?)`\n\nProvides ability to integrate the template into a bigger processing pipeline, that operates Markdown tokens.\n\n`createRender(template, lexer?)`\n\nCreates a function, that applies data to provided template. The returned function can be provided as an input to `renderTemplateToHtml` and `renderTemplateToTokens`, as well as used on its own. This is recommended to be used in scenarios, when data is changed more often than the template itself. The function is enhanced with `refs` property, which provides an array of placeholders, implemented in the template.\n\n## Security\n\nWhen using MDformat to generate HTML content from Markdown templates, it's essential to be cautious about potential security risks associated with untrusted user input or Markdown content. The generated HTML may include user-generated or dynamic content, which can pose risks if not properly sanitized.\n\nTo mitigate these risks, it's strongly recommended to employ post-processing techniques to sanitize the generated HTML before rendering it in a web application. One popular solution for this purpose is the dompurify package, which provides robust sanitization capabilities for ensuring that the HTML content is safe to use in a browser environment.\n\nHere's a basic example of how you can integrate [dompurify](https://www.npmjs.com/package/dompurify) into your application:\n\n```typescript\nimport DOMPurify from 'dompurify'\n\n// Define 'content' and 'data'\nconst content = ''\nconst data = {}\n\nconst htmlContent = renderTemplateToHtml(content, data)\n\n// Assume 'htmlContent' contains the generated HTML content\nconst sanitizedHTML = DOMPurify.sanitize(htmlContent)\n\n// Use 'sanitizedHTML' in your application\n```\n\nBy incorporating dompurify or similar sanitization libraries into your workflow, you can help protect your application from various security vulnerabilities associated with untrusted HTML content.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fumk%2Fmdformat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fumk%2Fmdformat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fumk%2Fmdformat/lists"}