{"id":13998133,"url":"https://github.com/rodneylab/parsedown","last_synced_at":"2025-04-26T08:31:14.923Z","repository":{"id":65223324,"uuid":"579300131","full_name":"rodneylab/parsedown","owner":"rodneylab","description":"WASM code for parsing Markdown into HTML with light output tweaking","archived":false,"fork":false,"pushed_at":"2025-04-14T08:19:02.000Z","size":7315,"stargazers_count":18,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-16T07:12:41.878Z","etag":null,"topics":["html5ever","markdown","markdown-to-html","pulldown-cmark","rust","wasm"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rodneylab.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-12-17T08:19:24.000Z","updated_at":"2025-04-07T13:28:16.000Z","dependencies_parsed_at":"2024-01-15T19:44:03.567Z","dependency_job_id":"08e34aab-591b-4e5b-9944-9bdb6651b007","html_url":"https://github.com/rodneylab/parsedown","commit_stats":{"total_commits":64,"total_committers":1,"mean_commits":64.0,"dds":0.0,"last_synced_commit":"eb6947b1fd90fa586d58a7dc84fa9ab34d63d827"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodneylab%2Fparsedown","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodneylab%2Fparsedown/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodneylab%2Fparsedown/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodneylab%2Fparsedown/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rodneylab","download_url":"https://codeload.github.com/rodneylab/parsedown/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250959612,"owners_count":21514298,"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":["html5ever","markdown","markdown-to-html","pulldown-cmark","rust","wasm"],"created_at":"2024-08-09T19:01:25.203Z","updated_at":"2025-04-26T08:31:14.911Z","avatar_url":"https://github.com/rodneylab.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"\u003cimg src=\"./images/rodneylab-github-parsedown.png\" alt=\"Rodney Lab parse down Git Hub banner\"\u003e\n\n\u003cp align=\"center\" style=\"display:grid;place-items:center;margin-block:2rem\"\u003e\n  \u003ca aria-label=\"Open Rodney Lab site\" href=\"https://rodneylab.com\" rel=\"nofollow noopener noreferrer\"\u003e\n    \u003cimg alt=\"Rodney Lab logo\" src=\"https://rodneylab.com/assets/icon.png\" width=\"60\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\u003ch1 align=\"center\"\u003e\n  parsedown\n\u003c/h1\u003e\n\nLight touch Markdown parsing into HTML written in Rust. Generates WASM and can\nbe used with Deno Fresh.\n\n- adds an id and anchor link to each h2 heading for easy linking\n- adds pretty punctuation\n- uses html5ever for HTML manipulation and pulldown-cmark for Markdown parsing\n\n## Using Module\n\nThe module is hosted on deno.x, and you can import directly into your TypeScript\nproject (no need to touch WASM or Rust source). See the later sections below if\nyou want to compile the WASM yourself.\n\n- Parse Markdown to HTML\n\n```typescript\nimport {\n  markdownToHtml,\n  markdownToPlaintext,\n  mjmlToHtml,\n} from \"https://deno.land/x/parsedown@1.4.3/mod.ts\";\n\nconst { errors, headings, html, statistics } = await markdownToHtml(\n  `\n## 👋🏽 Hello You\n\n* alpha\n* beta\n`,\n  {},\n);\n\n/*\nerrors: \"undefined\"\n\nheadings: [{\n  heading: \"👋🏽 Hello You\",\n  id: \"wave-skin-tone-4-hello-you\",\n}]\n\nhtml: `\u003ch2 id=\"wave-skin-tone-4-hello-you\"\u003e👋🏽 Hello You \u003ca href=\"#wave-skin-tone-4-hello-you\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003ealpha\u003c/li\u003e\n\u003cli\u003ebeta\u003c/li\u003e\n\u003c/ul\u003e\n`\n\nstatistics: {\n  reading_time: 1, // in minutes\n  word_count: 4\n}\n*/\n```\n\n```javascript\nconst { html } = await markdownToHtml(\n  \"Nobody likes maple in their apple flavoured Snapple.\",\n  { searchTerm: \"apple\" },\n);\n\nhtml:\n`\u003cp\u003eNobody likes maple in their \u003cmark id=\"search-match\"\u003eapple\u003c/mark\u003e flavoured Sn\u003cmark\u003eapple\u003c/mark\u003e\u003c/p\u003e`;\n```\n\nNote the `id` added to the first search match. You can use this to scroll the\nfirst match into view.\n\n- Parse Markdown to Plain Text\n\n```typescript\nimport {\n  markdownToHtml,\n  markdownToPlaintext,\n  mjmlToHtml,\n} from \"https://deno.land/x/parsedown@1.4.3/mod.ts\";\n\nconst plaintext = await markdownToPlaintext(\n  `\n## 👋🏽 Hello You\n\n* alpha\n* beta\n\n[Example Link](https://example.com/)\n`,\n  {},\n);\n\n/*\nplaintext: `👋🏽 Hello You\n\n- alpha\n\n- beta\n\nExample Link (https://example.com/)\n`\n*/\n```\n\n- Parse MJML (email template) to HTML\n\n```typescript\nimport {\n  markdownToHtml,\n  markdownToPlaintext,\n  mjmlToHtml,\n} from \"https://deno.land/x/parsedown@1.4.3/mod.ts\";\n\nconst html = await mjmlToHtml(\"\u003cmjml\u003e\u003c/mjml\u003e\");\n\n/*\nplaintext: `\u003c!doctype html\u003e\u003chtml xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:o=\"urn:schemas-microsoft-com:office:office\"\u003e\u003chead\u003e\u003ctitle\u003e\u003c/title\u003e\u003c!--[if !mso]\u003e\u003c!--\u003e\u003cmeta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"\u003e\u003c!--\u003c![endif]--\u003e\u003cmeta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"\u003e\u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\"\u003e\n\u003cstyle type=\"text/css\"\u003e\n#outlook a { padding: 0; }\nbody { margin: 0; padding: 0; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }\ntable, td { border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; }\nimg { border: 0; height: auto; line-height: 100%; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; }\np { display: block; margin: 13px 0; }\n\u003c/style\u003e\n\u003c!--[if mso]\u003e\n\u003cnoscript\u003e\n\u003cxml\u003e\n\u003co:OfficeDocumentSettings\u003e\n  \u003co:AllowPNG/\u003e\n  \u003co:PixelsPerInch\u003e96\u003c/o:PixelsPerInch\u003e\n\u003c/o:OfficeDocumentSettings\u003e\n\u003c/xml\u003e\n\u003c/noscript\u003e\n\u003c![endif]--\u003e\n\u003c!--[if lte mso 11]\u003e\n\u003cstyle type=\"text/css\"\u003e\n.mj-outlook-group-fix { width:100% !important; }\n\u003c/style\u003e\n\u003c![endif]--\u003e\n\u003c/head\u003e\u003cbody\u003e\u003c/body\u003e\u003c/html\u003e`\n*/\n```\n\n## Compile WASM (see next section instead, if working with Deno)\n\n_Method above is tested with Deno, you only need to compile the WASM yourself if\nyou have issues in other runtimes or are customizing the Rust source code for\nyour own needs._\n\n1. Clone the project and change into the project directory. Then run these\n   commands:\n\n```shell\ncargo install wasm-pack # skip if you already have it installed\nwasm-pack build --target web\n```\n\n2. Copy the generated `pkg` folder into your JavaScript or TypeScript project.\n3. Import and use the code in one of your project source files (expected output\n   is as shown in previous section):\n\n- Parse Markdown to HTML\n\n```typescript\nimport init, {\n  markdown_to_html,\n  markdown_to_plaintext,\n  mjml_to_html,\n} from \"pkg/parsedown.js\";\n\nawait init();\n\n// alternative if top level await is not available\n(async () =\u003e {\n  await init();\n})();\n\nconst { errors, headings, html, statistics } = await markdown_to_html(\n  `\n## 👋🏽 Hello You\n\n* alpha\n* beta\n`,\n  {},\n);\n```\n\n- Parse Markdown to Plain Text\n\n```typescript\nimport init, {\n  markdown_to_html,\n  markdown_to_plaintext,\n  mjml_to_html,\n} from \"pkg/parsedown.js\";\n\nawait init();\n\nconst plaintext = markdown_to_plaintext(\n  `\n## 👋🏽 Hello You\n\n* alpha\n* beta\n\n[Example Link](https://example.com/)\n`,\n  {},\n);\n```\n\n- Parse MJML (email template) to HTML\n\n```typescript\nimport init, {\n  markdown_to_html,\n  markdown_to_plaintext,\n  mjml_to_html,\n} from \"pkg/parsedown.js\";\n\nawait init();\n\nconst html = await mjml_to_html(\"\u003cmjml\u003e\u003c/mjml\u003e\");\n```\n\n**You must call `init` once before using any of the other functions.**\n\n## Compile WASM in Deno project\n\nIf you are working in Deno, you will probably find the `wasmbuild` package\nuseful.\n\n1. Add a `wasmbuild` task to your `deno.json` file:\n\n```json5\n{\n  \"tasks\": {\n    // ...TRUNCATED\n    \"wasmbuild\": \"deno run -A https://deno.land/x/wasmbuild@0.10.2/main.ts\"\n  }\n  // TRUNCATED...\n}\n```\n\n2. Run `deno task wasmbuild new` to initialize `wasmbuild` in your project. This\n   will create a skeleton WASM project with an `rs_lib` directory.\n\n3. Clone this repo and replace the contents of the `rs_lib/src` directory in\n   your project with the contents of this repo\u0026rsquo;s `src` directory. Also\n   replace `rs_lib/Cargo.toml` with `Cargo.toml` from this repo.\n\n4. Run the `deno task wasmbuild` command. This will generate JavaScript code and\n   WASM modules from the Rust source code. In particular, there should now be\n   `lib/rs_lib_bg.wasm` and `lib/rs_lib.generated.js` files in your project.\n\n5. You can now use the library functions in your JavaScript or TypeScript code.\n   Usage is only slightly different from the descriptions above.\n\n   - You can import the functions from `lib/rs_lib.generated.js`:\n\n   ```typescript\n   import {\n     instantiate,\n     markdown_to_html,\n     markdown_to_plaintext,\n     mjml_to_html,\n   } from \"@/lib/rs_lib.generated.js\";\n   ```\n\n   - **Before using any of the functions call `instantiate`**:\n\n   ```typescript\n   await instantiate();\n   ```\n\n   - The functions will now work as above:\n\n   ```typescript\n   const { errors, headings, html, statistics } = await markdown_to_html(\n     `\n   ## 👋🏽 Hello You\n\n   * alpha\n   * beta\n    `,\n     {},\n   );\n\n   const plaintext = markdown_to_plaintext(\n     `\n   ## 👋🏽 Hello You\n\n   * alpha\n   * beta\n\n   [Example Link](https://example.com/)\n   `,\n     {},\n   );\n\n   const html = mjml_to_html(\"\u003cmjml\u003e\u003c/mjml\u003e\");\n   ```\n\n## 🗺️ Roadmap\n\n- add text readability statistics (Gunning Fog index, for example)\n\n## ☎️ Reach Out\n\nFeel free to jump into the\n[Rodney Lab matrix chat room](https://matrix.to/#/%23rodney:matrix.org).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frodneylab%2Fparsedown","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frodneylab%2Fparsedown","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frodneylab%2Fparsedown/lists"}