Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/vanjs-org/converter
HTML and MD to VanJS Code Converter
https://github.com/vanjs-org/converter
code-generation dom lightweight lightweight-framework markdown markdown-converter reactive reactive-ui ultra-light ultra-thin vanjs
Last synced: about 1 month ago
JSON representation
HTML and MD to VanJS Code Converter
- Host: GitHub
- URL: https://github.com/vanjs-org/converter
- Owner: vanjs-org
- Created: 2023-09-17T07:15:19.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-09-01T17:05:15.000Z (4 months ago)
- Last Synced: 2024-10-29T00:54:10.874Z (about 2 months ago)
- Topics: code-generation, dom, lightweight, lightweight-framework, markdown, markdown-converter, reactive, reactive-ui, ultra-light, ultra-thin, vanjs
- Language: TypeScript
- Homepage: https://vanjs.org
- Size: 48.8 KB
- Stars: 10
- Watchers: 2
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# HTML and MD to VanJS Code Converter
This 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).
## Installation
The library is published as NPM package [vanjs-converter](https://www.npmjs.com/package/vanjs-converter).
Run the following command to install the package:
```shell
npm install vanjs-converter
```To use the NPM package, add this line to your script:
```js
import { htmlToVanCode, mdToVanCode } from "vanjs-converter"
```## `htmlToVanCode`: Convert HTML snippet to VanJS Code
### Signature
```js
htmlToVanCode(, ) => {code:, tags: , components: }
```### Example
```js
', {indent: 4})
htmlToVanCode('
/*
The following result will be returned:
{
code: [
'div(',
' p(',
' "👋Hello",',
' ),',
' ul(',
' li(',
' "🗺️World",',
' ),',
' li(',
' a({href: "https://vanjs.org/"},',
' "🍦VanJS",',
' ),',
' ),',
' ),',
')',
],
tags: ["a", "div", "li", "p", "ul"],
components: [],
}
*/
```### Using VanJS Components
_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._
The 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:
```js
const Hello = text => div(
p("👋Hello"),
ul(
li(text),
li(a({href: "https://vanjs.org/"}, "🍦VanJS")),
),
)const Counter = ({initValue}) => {
const counter = van.state(initValue)
return button({onclick: () => ++counter.val}, counter)
}
```You can simply specify the input HTML string like this:
```html
Hello
🗺️WorldCounter
```
which will be converted into the following **VanJS** code:
```js
h2(
"Hello",
),
Hello(
"🗺️World",
),
h2(
"Counter",
),
Counter({initValue: "1"}),
Counter({initValue: "2"}),
```### Options
* `indent`: Type `number`. Default `2`. Optional. The indent level of the generated **VanJS code**.
* `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/" }`.
* `skipEmptyText`: Type `boolean`. Default `false`. Optional. Whether to skip empty text nodes in the generated **VanJS code**. For instance, the HTML snippet:```html
```will be converted to:
```js
div(
p(
"👋Hello",
),
ul(
li(
"🗺️World",
),
li(
a({href: "https://vanjs.org/"},
"🍦VanJS",
),
),
),
)
```if `skipEmptyText` is `true`. But it will be converted to:
```js
div(
"\n ",
p(
"👋Hello",
),
"\n ",
ul(
"\n ",
li(
"🗺️World",
),
"\n ",
li(
a({href: "https://vanjs.org/"},
"🍦VanJS",
),
),
"\n ",
),
"\n",
)
```if `skipEmptyText` is `false`.
* `htmlTagPred`: Type `(name: string) => boolean`. Default `s => s.toLowerCase() === s`. Optional. A predicate function to check whether a specific tag snippet such as `` 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.
### Return Value
A plain object with the following fields:
* `code`: A `string[]` for all lines of the generated **VanJS** code.
* `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:
```js
const {} = van.tags
```
* `components`: A `string[]` for all custom **VanJS** components used in the generated **VanJS** code, which can be used in the importing line such as:
```js
import {} from "./my-component-lib.js"
```### `DUMMY`
_This is only supported in the converter library, not in the UI._
There 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:
```html
content
```will be converted to:
```js
CustomElement({},
"content",
)
```whereas
```html
content
```will be converted to:
```js
CustomElement(
"content",
)
```The second special case is that, sometimes, a custom **VanJS** component needs consecutive string arguments. You can achieve that by inserting `` element between text pieces. For instance:
```html
🍦VanJShttps://vanjs.org/
```will be converted to:
```js
Link(
"🍦VanJS",
"https://vanjs.org/",
)
```## `mdToVanCode`: Convert MD snippet to VanJS Code
### Signature
```js
mdToVanCode(, ) => {code:, tags: , components: }
```Under the hood, there are 2 steps for converting an MD snippet to **VanJS** code:
1. Convert the MD string into an HTML string with [Marked](https://marked.js.org/) library.
2. Convert the HTML string into **VanJS** code with `htmlToVanCode`.### Example
```js
mdToVanCode(`👋Hello
* 🗺️World
* [🍦VanJS](https://vanjs.org/)
`)
/*
The following result will be returned:
{
code: [
'p(',
' "👋Hello",',
'),',
'ul(',
' li(',
' "🗺️World",',
' ),',
' li(',
' a({href: "https://vanjs.org/"},',
' "🍦VanJS",',
' ),',
' ),',
'),',
],
tags: ["a", "li", "p", "ul"],
components: [],
}
*/
```Note that, you can insert custom HTML snippets, or even [custom **VanJS** components](#using-vanjs-components) in the input MD string.
### Options
* `indent`: Type `number`. Default `2`. Optional. The indent level of the generated **VanJS code**.
* `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/" }`.
* `htmlTagPred`: Type `(name: string) => boolean`. Default `s => s.toLowerCase() === s`. Optional. A predicate function to check whether a specific tag snippet such as `` 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.
* `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:```js
{
codespan: s => `${s}`,
link: (href, _unused_title, text) => `${text}${href}`,
}
```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")`.
### Return Value
The same as the [return value](#return-value) of `htmlToVanCode`.
## Showroom
The 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):
* 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.
* 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.