Skip to content

Commit 4d1a20c

Browse files
committed
Initial commit
0 parents  commit 4d1a20c

File tree

10 files changed

+905
-0
lines changed

10 files changed

+905
-0
lines changed

.editorconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*]
4+
indent_style = space
5+
indent_size = 2
6+
end_of_line = lf
7+
charset = utf-8
8+
trim_trailing_whitespace = true
9+
insert_final_newline = true

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.DS_Store
2+
*.log
3+
.nyc_output/
4+
coverage/
5+
node_modules/
6+
yarn.lock

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package-lock=false

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
coverage/

.travis.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
language: node_js
2+
node_js:
3+
- lts/dubnium
4+
- node
5+
after_script: bash <(curl -s https://codecov.io/bash)

index.js

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
'use strict'
2+
3+
var xtend = require('xtend')
4+
var zwitch = require('zwitch')
5+
var namespaces = require('web-namespaces')
6+
var html = require('property-information/html')
7+
var svg = require('property-information/svg')
8+
var find = require('property-information/find')
9+
var spaces = require('space-separated-tokens').stringify
10+
var commas = require('comma-separated-tokens').stringify
11+
var position = require('unist-util-position')
12+
13+
module.exports = toXast
14+
15+
var one = zwitch('type')
16+
17+
one.invalid = invalid
18+
one.unknown = unknown
19+
one.handlers.root = root
20+
one.handlers.element = element
21+
one.handlers.text = text
22+
one.handlers.comment = comment
23+
one.handlers.doctype = doctype
24+
25+
function invalid(value) {
26+
throw new Error('Expected node, not `' + value + '`')
27+
}
28+
29+
function unknown(value) {
30+
throw new Error('Cannot transform node of type `' + value.type + '`')
31+
}
32+
33+
function toXast(tree, options) {
34+
var opts = typeof options === 'string' ? {space: options} : options || {}
35+
var space = opts.space === 'svg' ? 'svg' : 'html'
36+
37+
return one(tree, {schema: space === 'svg' ? svg : html, ns: null})
38+
}
39+
40+
function root(node, config) {
41+
return patch(node, {type: 'root'}, config)
42+
}
43+
44+
function text(node, config) {
45+
return patch(node, {type: 'text', value: node.value || ''}, config)
46+
}
47+
48+
function comment(node, config) {
49+
return patch(node, {type: 'comment', value: node.value || ''}, config)
50+
}
51+
52+
function doctype(node, config) {
53+
return patch(
54+
node,
55+
{
56+
type: 'doctype',
57+
name: node.name || '',
58+
public: node.public || undefined,
59+
system: node.system || undefined
60+
},
61+
config
62+
)
63+
}
64+
65+
function element(node, parentConfig) {
66+
var schema = parentConfig.schema
67+
var name = node.tagName
68+
var props = node.properties || {}
69+
var xmlns = props.xmlns || null
70+
var ns = namespaces[schema.space]
71+
var attrs = {}
72+
var config
73+
74+
if (xmlns) {
75+
if (xmlns === namespaces.svg) {
76+
schema = svg
77+
ns = xmlns
78+
} else if (xmlns === namespaces.html) {
79+
schema = html
80+
ns = xmlns
81+
} else {
82+
// We don’t support non-HTML, non-SVG namespaces, so stay in the same.
83+
}
84+
} else if (ns === namespaces.html && name === 'svg') {
85+
schema = svg
86+
ns = namespaces.svg
87+
}
88+
89+
if (parentConfig.ns !== ns) {
90+
attrs.xmlns = ns
91+
}
92+
93+
config = xtend(parentConfig, {schema: schema, ns: ns})
94+
attrs = xtend(attrs, toAttributes(props, config))
95+
96+
return patch(node, {type: 'element', name: name, attributes: attrs}, config)
97+
}
98+
99+
function patch(origin, node, config) {
100+
var pos = origin.position
101+
var hastChildren = origin.children
102+
var length
103+
var children
104+
var index
105+
106+
if (
107+
config.ns === namespaces.html &&
108+
origin.type === 'element' &&
109+
origin.tagName === 'template'
110+
) {
111+
node.children = root(origin.content, config).children
112+
} else if (origin.type === 'element' || origin.type === 'root') {
113+
length = hastChildren && hastChildren.length
114+
children = []
115+
index = -1
116+
117+
while (++index < length) {
118+
children[index] = one(hastChildren[index], config)
119+
}
120+
121+
node.children = children
122+
}
123+
124+
if (pos) {
125+
node.position = {
126+
start: position.start(origin),
127+
end: position.end(origin)
128+
}
129+
}
130+
131+
return node
132+
}
133+
134+
function toAttributes(props, config) {
135+
var attributes = {}
136+
var value
137+
var key
138+
var info
139+
var name
140+
141+
for (key in props) {
142+
info = find(config.schema, key)
143+
name = info.attribute
144+
value = props[key]
145+
146+
// Ignore nully, false, and `NaN` values, and falsey known booleans.
147+
if (
148+
value === null ||
149+
value === undefined ||
150+
value === false ||
151+
value !== value ||
152+
(info.boolean && !value)
153+
) {
154+
continue
155+
}
156+
157+
// Accept `array`.
158+
// Most props are space-separated.
159+
if (typeof value === 'object' && 'length' in value) {
160+
value = (info.commaSeparated ? commas : spaces)(value)
161+
}
162+
163+
// Treat `true` and truthy known booleans.
164+
if (value === true || info.boolean) {
165+
value = ''
166+
}
167+
168+
// Cast everything else to string.
169+
if (typeof value !== 'string') {
170+
value = String(value)
171+
}
172+
173+
attributes[name] = value
174+
}
175+
176+
return attributes
177+
}

license

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
(The MIT License)
2+
3+
Copyright (c) 2020 Titus Wormer <tituswormer@gmail.com>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining
6+
a copy of this software and associated documentation files (the
7+
'Software'), to deal in the Software without restriction, including
8+
without limitation the rights to use, copy, modify, merge, publish,
9+
distribute, sublicense, and/or sell copies of the Software, and to
10+
permit persons to whom the Software is furnished to do so, subject to
11+
the following conditions:
12+
13+
The above copyright notice and this permission notice shall be
14+
included in all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

package.json

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
{
2+
"name": "hast-util-to-xast",
3+
"version": "0.0.0",
4+
"description": "hast utility to transform to xast",
5+
"license": "MIT",
6+
"keywords": [
7+
"xast",
8+
"hast",
9+
"unist",
10+
"dsl",
11+
"xml",
12+
"html"
13+
],
14+
"repository": "syntax-tree/hast-util-to-xast",
15+
"bugs": "https://github.com/syntax-tree/hast-util-to-xast/issues",
16+
"funding": {
17+
"type": "opencollective",
18+
"url": "https://opencollective.com/unified"
19+
},
20+
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
21+
"contributors": [
22+
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)"
23+
],
24+
"files": [
25+
"index.js"
26+
],
27+
"dependencies": {
28+
"comma-separated-tokens": "^1.0.0",
29+
"property-information": "^5.0.0",
30+
"space-separated-tokens": "^1.0.0",
31+
"unist-util-position": "^3.0.0",
32+
"web-namespaces": "^1.0.0",
33+
"xtend": "^4.0.0",
34+
"zwitch": "^1.0.0"
35+
},
36+
"devDependencies": {
37+
"hastscript": "^5.0.0",
38+
"nyc": "^15.0.0",
39+
"prettier": "^1.0.0",
40+
"remark-cli": "^7.0.0",
41+
"remark-preset-wooorm": "^6.0.0",
42+
"tape": "^4.0.0",
43+
"unist-builder": "^2.0.0",
44+
"xastscript": "^1.0.0",
45+
"xo": "^0.25.0"
46+
},
47+
"scripts": {
48+
"format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix",
49+
"test-api": "node test",
50+
"test-coverage": "nyc --reporter lcov tape test.js",
51+
"test": "npm run format && npm run test-coverage"
52+
},
53+
"nyc": {
54+
"check-coverage": true,
55+
"lines": 100,
56+
"functions": 100,
57+
"branches": 100
58+
},
59+
"prettier": {
60+
"tabWidth": 2,
61+
"useTabs": false,
62+
"singleQuote": true,
63+
"bracketSpacing": false,
64+
"semi": false,
65+
"trailingComma": "none"
66+
},
67+
"xo": {
68+
"prettier": true,
69+
"esnext": false,
70+
"rules": {
71+
"unicorn/prefer-includes": "off",
72+
"no-self-compare": "off",
73+
"guard-for-in": "off"
74+
}
75+
},
76+
"remarkConfig": {
77+
"plugins": [
78+
"preset-wooorm"
79+
]
80+
}
81+
}

0 commit comments

Comments
 (0)