Skip to content

Latest commit

 

History

History
528 lines (457 loc) · 7.61 KB

README.md

File metadata and controls

528 lines (457 loc) · 7.61 KB

mʌrκup.json

logo

DOM Markup Abstract Syntax Tree representation in compact JSON

Specification, Transformer Library and CLI

First Class Attribute Strings



preview-json preview-html

Tip

Here are some real usage examples


Library Usage

# install
npm install markup.json
# or
pnpm add markup.json

cat .github/preview.json
[
  "headless",
  "",
  ["h1", "marκup.json"],
  ["hr"],
  [
    "h4",
    "DOM tree",
    "representation in",
    ["i", "compact"],
    "JSON"
  ],
  [
    "a",
    {
      "class": "primary",
      "data-planet-id": "92432",
      "href": [
        "github.com/search?",
        {
          "q": "markup",
          "type": "repositories"
        }
      ],
      "style": {
        "color": "indigo",
        "background": "fuchsia"
      }
    },
    "🔥 First Class Attribute Strings"
  ],
  "Spec",
  "CLI",
  "Library"
]
import { readFile } from 'node:fs/promises'
import markup from 'markup.json'

const opt = { encoding: 'utf8' }
const tpl = await readFile('./tpl.json', opt)

const html = markup(JSON.parse(tpl))
headless

<h1>
  marκup.json
</h1>
<hr />
<h4>
  DOM tree
  representation in
  <i>
    compact
  </i>
  JSON
</h4>
<a
  class="primary"
  data-planet-id="92432"
  href="github.com/search?q=markup&type=repositories&"
  style="color:indigo; background:fuchsia;"
>
  🔥 First Class Attribute Strings
</a>
Spec
CLI
Library

CLI Installation

# install globally
npm i -g markup.json
# or
pnpm add -g markup.json

# or with npx
npx markup.json

CLI Synopsis

markup [-]|FILE [FILE]

Reads input from standard input or FILE

Writes to stdout or FILE


CLI Usage

  # read input and output path from args
markup [FILE] [FILE]
markup tpl.json index.html
    # or with npx
npx markup.json tpl.json index.html
  # read input path from args
  # write output to standard output
markup [FILE]
markup tpl.json
markup tpl.json > index.html
    # or with npx
npx markup.json tpl.json > index.html
  # read input from standard input
  # write output to standard output
cat FILE | markup
cat tpl.json | markup
cat tpl.json | markup > index.html
    # or with npx
cat tpl.json | npx markup.json > index.html
  # read from file descriptor
  # write output to standard output
markup < FILE
markup < tpl.json
markup < tpl.json > index.html
    # or with npx
npx markup.json < tpl.json > index.html

Types

type Tag = string

type primitive = string | number | boolean

type AttributeString = [string, { [k: string]: primitive }]

type Attribute =
  | { [k: string]: primitive | AttributeString | object }
  | primitive

type Node = [Tag, Attribute?, ...primitive[]] | string

type Markup = Node[]

Primitive Attribute values

Attributes with Primitive values are rendered as is;

[
  "top level",
  "can be without tag",
  [
    "button",
    {
      "class": "primary btn",
      "name": "xorg"
    },
    "hi",
    ["b", "main"],
    "btn",
    "here"
  ]
]
top level
can be without tag
<button
  class="primary btn"
  name="xorg"
>
  hi
  <b> main </b>
  btn here
</button>

Tip

Attributes can come at any position after tag

[
  "attributes open",
  "position",
  [
    "button",
    "hell",
    {
      "class": "primary btn",
      "name": "xorg"
    },
    "OoO",
    ["b", "main"],
    "btn",
    "here"
  ]
]
attributes open
position
<button
  class="primary btn"
  name="xorg"
>
  hell
  OoO
  <b>
    main
  </b>
  btn
  here
</button>

Tip

Repeated attributes will merge

[
  "repeated",
  "attributes",
  [
    "button",
    {
      "class": "primary btn",
      "name": "xorg"
    },
    "hi",
    { "class": "shadowed", "id": "usr" },
    ["b", "main"],
    "btn",
    "here"
  ],
  "EO"
]
repeated
attributes
<button
  class="shadowed"
  name="xorg"
  id="usr"
>
  hi
  <b>
    main
  </b>
  btn
  here
</button>
EO

Attribute with Object values

Attributes with Object values are folded delimit key and value pairs with ; delimit keys and values with :

[
  "OBJ Values",
  ["h4", "Attribute with Object values"],
  [
    "span",
    {
      "class": "secondary",
      "style": {
        "color": "indigo",
        "background": "fuchsia"
      },
      "anything": {
        "name": "etc",
        "planet": "8e81"
      }
    },
    "Object values",
    ["b", "x11"],
    "xorg"
  ]
]
OBJ Values
<h4>
  Attribute with Object values
</h4>
<span
  class="secondary"
  style="color:indigo; background:fuchsia;"
  anything="name:etc; planet:8e81;"
>
  Object values
  <b>
    x11
  </b>
  xorg
</span>

Attribute with Array values

Attributes with Object values are folded delimit key and value pairs with & delimit keys and values with =

[
  "begin",
  ["h4", "Attribute with Array values"],
  [
    "a",
    {
      "class": "secondary",
      "href": [
        "github.com/search?",
        {
          "q": "markup",
          "type": "repositories",
          "l": "Lua"
        }
      ]
    },
    "go",
    ["b", "find"],
    "repos"
  ]
]
begin
<h4>
  Attribute with Array values
</h4>
<a
  class="secondary"
  href="github.com/search?q=markup&type=repositories&l=Lua&"
>
  go
  <b>
    find
  </b>
  repos
</a>
[
  "attributes with",
  "array values",
  [
    "img",
    {
      "width": "80%",
      "alt": "stats",
      "src": [
        "github-readme-stats.vercel.app/api?",
        {
          "username": "metaory",
          "ring_color": "5522CC",
          "text_color": "44BBFF",
          "border_radius": 30,
          "hide_title": true,
          "hide_rank": false,
          "show_icons": true
        }
      ]
    }
  ]
]
attributes with
array values
<img
  width="80%"
  alt="stats"
  src="github-readme-stats.vercel.app/api?username=metaory&ring_color=5522CC&text_color=44BBFF&border_radius=30&hide_title=true&hide_rank=false&show_icons=true&"
 />

Tip

Values are normalized with Unicode NFC Form Canonical Composition

"\u0041\u006d\u00e9\u006c\u0069\u0065" would be "Amélie"

ref: Unicode_equivalence


Note

The values "true" and "false" are not allowed on boolean attributes. To represent a false value, the attribute has to be omitted altogether.

ref: 2.3.2 Boolean attributes -- html.spec.whatwg.org

[
  "Boolean attributes",
  ["hr"],
  [
    "label",
    [
      "input",
      {
        "type": "checkbox",
        "name": "cheese",
        "disabled": false,
        "checked": true
      }
    ],
    "Cheese"
  ]
]
Boolean attributes
<hr />
<label>
  <input
    type="checkbox"
    name="cheese"
    checked
   />
  Cheese
</label>

License

MIT