{"id":18876626,"url":"https://github.com/vanjs-org/converter","last_synced_at":"2025-04-14T18:31:30.996Z","repository":{"id":195333749,"uuid":"692659231","full_name":"vanjs-org/converter","owner":"vanjs-org","description":"HTML and MD to VanJS Code Converter","archived":false,"fork":false,"pushed_at":"2025-01-26T19:43:08.000Z","size":63,"stargazers_count":11,"open_issues_count":2,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-09T14:52:20.708Z","etag":null,"topics":["code-generation","dom","lightweight","lightweight-framework","markdown","markdown-converter","reactive","reactive-ui","ultra-light","ultra-thin","vanjs"],"latest_commit_sha":null,"homepage":"https://vanjs.org","language":"TypeScript","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/vanjs-org.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-09-17T07:15:19.000Z","updated_at":"2025-01-26T19:43:13.000Z","dependencies_parsed_at":"2023-09-17T14:37:11.120Z","dependency_job_id":null,"html_url":"https://github.com/vanjs-org/converter","commit_stats":null,"previous_names":["vanjs-org/converter"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vanjs-org%2Fconverter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vanjs-org%2Fconverter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vanjs-org%2Fconverter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vanjs-org%2Fconverter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vanjs-org","download_url":"https://codeload.github.com/vanjs-org/converter/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248936656,"owners_count":21186074,"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":["code-generation","dom","lightweight","lightweight-framework","markdown","markdown-converter","reactive","reactive-ui","ultra-light","ultra-thin","vanjs"],"created_at":"2024-11-08T06:14:28.459Z","updated_at":"2025-04-14T18:31:30.696Z","avatar_url":"https://github.com/vanjs-org.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# HTML and MD to VanJS Code Converter\n\nThis is a library that can convert any MD or HTML snippet into valid **VanJS** code. The UI version of the code converter is [here](https://vanjs.org/convert).\n\n## Installation\n\nThe library is published as NPM package [vanjs-converter](https://www.npmjs.com/package/vanjs-converter).\n\nRun the following command to install the package:\n\n```shell\nnpm install vanjs-converter\n```\n\nTo use the NPM package, add this line to your script:\n\n```js\nimport { htmlToVanCode, mdToVanCode } from \"vanjs-converter\"\n```\n\n## `htmlToVanCode`: Convert HTML snippet to VanJS Code\n\n### Signature\n\n```js\nhtmlToVanCode(\u003cHTML string\u003e, \u003coptions\u003e) =\u003e {code: \u003ccode\u003e, tags: \u003ctags\u003e, components: \u003ccomponents\u003e}\n```\n\n### Example\n\n```js\nhtmlToVanCode('\u003cdiv\u003e\u003cp\u003e👋Hello\u003c/p\u003e\u003cul\u003e\u003cli\u003e🗺️World\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://vanjs.org/\"\u003e🍦VanJS\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/div\u003e', {indent: 4})\n/*\nThe following result will be returned:\n{\n  code: [\n    'div(',\n    '    p(',\n    '        \"👋Hello\",',\n    '    ),',\n    '    ul(',\n    '        li(',\n    '            \"🗺️World\",',\n    '        ),',\n    '        li(',\n    '            a({href: \"https://vanjs.org/\"},',\n    '                \"🍦VanJS\",',\n    '            ),',\n    '        ),',\n    '    ),',\n    ')',\n  ],\n  tags: [\"a\", \"div\", \"li\", \"p\", \"ul\"],\n  components: [],\n}\n*/\n```\n\n### Using VanJS Components\n\n_This is only supported in the converter library, not in the UI. The [root cause](https://github.com/remarkablemark/html-react-parser/issues/168#issuecomment-699536994) is [html-dom-parser](https://www.npmjs.com/package/html-dom-parser) doesn't support case-sensitive parsing on the client side._\n\nThe input HTML string can be a mix of HTML elements and custom UI components built with **VanJS**. To use custom UI components, just specify the component similar to regular HTML tags. For instance, assume we have custom UI components similar to the ones shown in https://vanjs.org/ home page:\n\n```js\nconst Hello = text =\u003e div(\n  p(\"👋Hello\"),\n  ul(\n    li(text),\n    li(a({href: \"https://vanjs.org/\"}, \"🍦VanJS\")),\n  ),\n)\n\nconst Counter = ({initValue}) =\u003e {\n  const counter = van.state(initValue)\n  return button({onclick: () =\u003e ++counter.val}, counter)\n}\n```\n\nYou can simply specify the input HTML string like this:\n\n```html\n\u003ch2\u003eHello\u003c/h2\u003e\n\u003cHello\u003e🗺️World\u003c/Hello\u003e\n\u003ch2\u003eCounter\u003c/h2\u003e\n\u003cCounter initValue=\"1\"\u003e\u003c/Counter\u003e\n\u003cCounter initValue=\"2\"\u003e\u003c/Counter\u003e\n```\n\nwhich will be converted into the following **VanJS** code:\n\n```js\nh2(\n  \"Hello\",\n),\nHello(\n  \"🗺️World\",\n),\nh2(\n  \"Counter\",\n),\nCounter({initValue: \"1\"}),\nCounter({initValue: \"2\"}),\n```\n\n### Options\n\n* `indent`: Type `number`. Default `2`. Optional. The indent level of the generated **VanJS code**.\n* `spacing`: Type `boolean`. Default `false`. Optional. The style of the property object in the generated **VanJS** code. If `true`, the property object will look like `{href: \"https://vanjs.org/\"}`; Otherwise, the property object will look like `{ href: \"https://vanjs.org/\" }`.\n* `skipEmptyText`: Type `boolean`. Default `false`. Optional. Whether to skip empty text nodes in the generated **VanJS code**. For instance, the HTML snippet:\n\n  ```html\n  \u003cdiv\u003e\n    \u003cp\u003e👋Hello\u003c/p\u003e\n    \u003cul\u003e\n      \u003cli\u003e🗺️World\u003c/li\u003e\n      \u003cli\u003e\u003ca href=\"https://vanjs.org/\"\u003e🍦VanJS\u003c/a\u003e\u003c/li\u003e\n    \u003c/ul\u003e\n  \u003c/div\u003e\n  ```\n\n  will be converted to:\n\n  ```js\n  div(\n    p(\n      \"👋Hello\",\n    ),\n    ul(\n      li(\n        \"🗺️World\",\n      ),\n      li(\n        a({href: \"https://vanjs.org/\"},\n          \"🍦VanJS\",\n        ),\n      ),\n    ),\n  )\n  ```\n\n  if `skipEmptyText` is `true`. But it will be converted to:\n\n  ```js\n  div(\n    \"\\n  \",\n    p(\n      \"👋Hello\",\n    ),\n    \"\\n  \",\n    ul(\n      \"\\n    \",\n      li(\n        \"🗺️World\",\n      ),\n      \"\\n    \",\n      li(\n        a({href: \"https://vanjs.org/\"},\n          \"🍦VanJS\",\n        ),\n      ),\n      \"\\n  \",\n    ),\n    \"\\n\",\n  )\n  ```\n\n  if `skipEmptyText` is `false`.\n\n* `htmlTagPred`: Type `(name: string) =\u003e boolean`. Default `s =\u003e s.toLowerCase() === s`. Optional. A predicate function to check whether a specific tag snippet such as `\u003cCounter\u003e` should be treated as a native HTML element or a custom UI component built with **VanJS**. By default, it will be treated as a native HTML element if the letters in the `name` are all lowercase.\n\n### Return Value\n\nA plain object with the following fields:\n* `code`: A `string[]` for all lines of the generated **VanJS** code.\n* `tags`: A `string[]` for all HTML tag names used in the generated **VanJS** code, which can be used in the importing line of tag functions such as:\n  ```js\n  const {\u003ctags needs to import\u003e} = van.tags\n  ```\n* `components`: A `string[]` for all custom **VanJS** components used in the generated **VanJS** code, which can be used in the importing line such as:\n  ```js\n  import {\u003ccomponents needs to import\u003e} from \"./my-component-lib.js\"\n  ```\n\n### `DUMMY`\n\n_This is only supported in the converter library, not in the UI._\n\nThere are 2 special cases while specifying custom **VanJS** components in the input HTML string. The first special case is that, sometimes, a custom component needs properties being specified in its first argument, even for empty properties `{}` (e.g.: the `Counter` component defined in the [section](#using-vanjs-components) above). In this case, you can specify the special `DUMMY` property as a placeholder. For instance:\n\n```html\n\u003cCustomElement DUMMY\u003econtent\u003c/CustomElement\u003e\n```\n\nwill be converted to:\n\n```js\nCustomElement({},\n  \"content\",\n)\n```\n\nwhereas\n\n```html\n\u003cCustomElement\u003econtent\u003c/CustomElement\u003e\n```\n\nwill be converted to:\n\n```js\nCustomElement(\n  \"content\",\n)\n```\n\nThe second special case is that, sometimes, a custom **VanJS** component needs consecutive string arguments. You can achieve that by inserting `\u003cDUMMY\u003e` element between text pieces. For instance:\n\n```html\n\u003cLink\u003e🍦VanJS\u003cDUMMY\u003e\u003c/DUMMY\u003ehttps://vanjs.org/\u003c/Link\u003e\n```\n\nwill be converted to:\n\n```js\nLink(\n  \"🍦VanJS\",\n  \"https://vanjs.org/\",\n)\n```\n\n## `mdToVanCode`: Convert MD snippet to VanJS Code\n\n### Signature\n\n```js\nmdToVanCode(\u003cMD string\u003e, \u003coptions\u003e) =\u003e {code: \u003ccode\u003e, tags: \u003ctags\u003e, components: \u003ccomponents\u003e}\n```\n\nUnder the hood, there are 2 steps for converting an MD snippet to **VanJS** code:\n1. Convert the MD string into an HTML string with [Marked](https://marked.js.org/) library.\n2. Convert the HTML string into **VanJS** code with `htmlToVanCode`.\n\n### Example\n\n```js\nmdToVanCode(`👋Hello\n* 🗺️World\n* [🍦VanJS](https://vanjs.org/)\n`)\n/*\nThe following result will be returned:\n{\n  code: [\n    'p(',\n    '  \"👋Hello\",',\n    '),',\n    'ul(',\n    '  li(',\n    '    \"🗺️World\",',\n    '  ),',\n    '  li(',\n    '    a({href: \"https://vanjs.org/\"},',\n    '      \"🍦VanJS\",',\n    '    ),',\n    '  ),',\n    '),',\n  ],\n  tags: [\"a\", \"li\", \"p\", \"ul\"],\n  components: [],\n}\n*/\n```\n\nNote that, you can insert custom HTML snippets, or even [custom **VanJS** components](#using-vanjs-components) in the input MD string.\n\n### Options\n\n* `indent`: Type `number`. Default `2`. Optional. The indent level of the generated **VanJS code**.\n* `spacing`: Type `boolean`. Default `false`. Optional. The style of the property object in the generated **VanJS** code. If `true`, the property object will look like `{href: \"https://vanjs.org/\"}`; Otherwise, the property object will look like `{ href: \"https://vanjs.org/\" }`.\n* `htmlTagPred`: Type `(name: string) =\u003e boolean`. Default `s =\u003e s.toLowerCase() === s`. Optional. A predicate function to check whether a specific tag snippet such as `\u003cCounter\u003e` represents a native HTML element or a custom UI component built with **VanJS**. By default, it will be considered a native HTML element if the letters in the `name` are all lowercase.\n* `renderer`: Optional. _Custom renderer is only supported in the converter library, not in the UI._ A custom object used to override how tokens in the MD string are being rendered. The specification of the `renderer` object can be found in Marked [doc](https://marked.js.org/using_pro#renderer). For instance, the `renderer` object:\n\n  ```js\n  {\n    codespan: s =\u003e `\u003cSymbol\u003e${s}\u003c/Symbol\u003e`,\n    link: (href, _unused_title, text) =\u003e `\u003cLink\u003e${text}\u003cDUMMY\u003e\u003c/DUMMY\u003e${href}\u003c/Link\u003e`,\n  }\n  ```\n\n  will convert `` `text` `` in MD string into `Symbol(\"text\")` (here `Symbol` is a custom **VanJS** component) instead of `code(\"text\")`, and will convert `[text](link)` in MD string into `Link(\"text\", \"link\")` instead of `a({href: \"link\"}, \"text\")`.\n\n### Return Value\n\nThe same as the [return value](#return-value) of `htmlToVanCode`.\n\n## Showroom\n\nThe https://vanjs.org/ website is using this library to keep `README.md` files in sync with their corresponding web pages ([source code](https://github.com/vanjs-org/vanjs-org.github.io/tree/master/codegen) of the code generation):\n* The [VanUI](https://vanjs.org/vanui) page is kept in sync with the [`README.md`](https://github.com/vanjs-org/van/tree/main/components#readme) file in GitHub with the help of this library.\n* This [`README.md`](https://github.com/vanjs-org/converter#readme) file is kept in sync with this [page](https://vanjs.org/converter-lib) in https://vanjs.org/ website.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvanjs-org%2Fconverter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvanjs-org%2Fconverter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvanjs-org%2Fconverter/lists"}