├── .gitignore
├── .travis.yml
├── README.md
├── index.js
├── lib
└── svg-namespaces.js
├── package.json
└── test
└── index_test.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .idea
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - '0.10'
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # html2hscript
2 |
3 | Parse html to hyperscript library.
4 |
5 | [](https://travis-ci.org/twilson63/html2hscript)
6 |
7 | ## Usage
8 |
9 | ``` js
10 | var parser = require('html2hscript');
11 | parser('
Hello World
', function(err, hscript) {
12 | console.log(hscript);
13 | });
14 | ```
15 |
16 | ## Install
17 |
18 | ``` sh
19 | npm install html2hscript
20 | ```
21 |
22 | ## Test
23 |
24 | ``` sh
25 | npm test
26 | ```
27 |
28 | ## Support
29 |
30 | Submit Issue in Github
31 |
32 | ## Contributions
33 |
34 | Pull Requests are welcome
35 |
36 | ## License
37 |
38 | MIT
39 |
40 | ## Thanks
41 |
42 | [https://www.npmjs.com/~unframework](https://www.npmjs.com/~unframework) who wrote the parsing code.
43 |
44 | [https://www.npmjs.com/~dominictarr](https://www.npmjs.com/~dominictarr) who wrote hyperscript.
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | // code pulled from https://www.npmjs.com/package/html2hyperscript
2 | var Parser = require('htmlparser2').Parser;
3 | var camel = require('to-camel-case');
4 | var ent = require('ent');
5 | var isEmpty = require('is-empty');
6 | var thisIsSVGTag = require('./lib/svg-namespaces').thisIsSVGTag,
7 | getSVGNamespace = require('./lib/svg-namespaces').getSVGNamespace,
8 | getSVGAttributeNamespace = require('./lib/svg-namespaces').getSVGAttributeNamespace;
9 |
10 | var elementStack = [];
11 |
12 | function ItemList(parent) {
13 | this.parent = parent;
14 | this.content = '';
15 | this.spacer = '';
16 | this.indent = parent ? parent.indent : '';
17 | this.isFirstItem = true;
18 | }
19 |
20 | ItemList.prototype.addSpace = function (space) {
21 | this.spacer += space;
22 |
23 | if (space.indexOf("\n") !== -1) {
24 | // reset indent when there are new lines
25 | this.indent = /[^\n]*$/.exec(space)[0];
26 | } else {
27 | // otherwise keep appending to current indent
28 | this.indent += space;
29 | }
30 | }
31 |
32 | ItemList.prototype.add = function (data, ignoreComma) {
33 | if (!ignoreComma) {
34 | if (!this.isFirstItem) {
35 | this.content += this.spacer.length ? ',' : ', ';
36 | }
37 |
38 | this.isFirstItem = false;
39 | }
40 |
41 | this.content += this.spacer;
42 | this.spacer = '';
43 |
44 | this.content += data;
45 | }
46 |
47 | module.exports = function(html, cb) {
48 | var currentItemList = new ItemList(null);
49 |
50 | var parser = new Parser({
51 | onopentag: function (name, attribs) {
52 | currentItemList = new ItemList(currentItemList);
53 | elementStack.unshift([ name, attribs ]);
54 | },
55 | ontext: function (text) {
56 | currentItemList.add(JSON.stringify(ent.decode(text)));
57 | /*var lines = text.split("\n");
58 |
59 | var isFirst = true;
60 |
61 | lines.forEach(function (line) {
62 | var lineMatch = /^(\s*)(.*?)(\s*)$/.exec(line);
63 |
64 | var preSpace = lineMatch[1],
65 | mainText = lineMatch[2],
66 | postSpace = lineMatch[3];
67 |
68 | if (!isFirst) {
69 | currentItemList.addSpace("\n");
70 | }
71 |
72 | currentItemList.addSpace(preSpace);
73 |
74 | if (mainText.length > 0) {
75 | currentItemList.add(JSON.stringify(mainText));
76 | }
77 |
78 | isFirst = false;
79 | });*/
80 | },
81 | onclosetag: function (tagname) {
82 | var element = elementStack.shift();
83 | var elementContent = currentItemList.content + currentItemList.spacer;
84 |
85 | currentItemList = currentItemList.parent;
86 |
87 | var indent = currentItemList.indent;
88 |
89 | var attribs = element[1];
90 |
91 | var id = attribs['id'];
92 |
93 | var idSuffix = id !== undefined ? '#' + id : '';
94 | delete attribs['id'];
95 |
96 | var classNames = attribs['class'];
97 | var classSuffix;
98 | if ( !thisIsSVGTag( element[ 0 ] ) ) {
99 | classSuffix = (classNames !== undefined ? classNames : '').split(/\s+/g).filter(function(v) {
100 | return v.length > 0;
101 | }).map(function(cls) {
102 | return '.' + cls;
103 | }).join('');
104 | delete attribs['class'];
105 | } else {
106 | classSuffix = '';
107 | }
108 | // Convert inline CSS style attribute to an object
109 | if(attribs['style']){
110 | var rules = attribs["style"].split(";");
111 | attribs["style"] = {};
112 | rules.forEach(function(rule){
113 | var split = rule.split(":");
114 | if(split.length == 2){
115 | attribs["style"][split[0].trim()] = split[1].trim();
116 | }
117 | });
118 | }
119 |
120 | var style = attribs['style']
121 | delete attribs['style']
122 |
123 | var dataset = {};
124 | var datasetKey;
125 | Object.keys(attribs).forEach(function (k) {
126 | if (k.slice(0, 5) === 'data-') {
127 | datasetKey = camel(k.slice(5));
128 | dataset[datasetKey] = attribs[k];
129 | delete attribs[k];
130 | }
131 | });
132 |
133 | var attrPairs = Object.keys( attribs ).map( function ( k ) {
134 | return JSON.stringify( k ) + ': ' + JSON.stringify( attribs[ k ] )
135 | } );
136 | var datasetPairs = Object.keys( dataset ).map( function ( k ) {
137 | return JSON.stringify( k ) + ': ' + JSON.stringify( dataset[ k ] )
138 | } );
139 |
140 | var objects = {}
141 | if (attribs.value) {
142 | objects.value = attribs.value;
143 | delete attribs.value;
144 | }
145 | if ( !isEmpty( style ) ) objects.style = style
146 | if ( !isEmpty( attribs ) ) objects.attributes = attribs
147 | if ( !isEmpty( dataset ) ) objects.dataset = dataset
148 | if ( thisIsSVGTag( element[ 0 ] ) ) {
149 | objects.namespace = getSVGNamespace();
150 |
151 | Object.keys(attribs).forEach(function (k) {
152 | var namespace = getSVGAttributeNamespace(k);
153 |
154 | if (namespace === void 0) { // not a svg attribute
155 | return;
156 | }
157 |
158 | var value = objects.attributes[ k ];
159 |
160 | if (typeof value !== 'string' &&
161 | typeof value !== 'number' &&
162 | typeof value !== 'boolean'
163 | ) {
164 | return;
165 | }
166 |
167 | if (namespace !== null) { // namespaced attribute
168 | objects[ k ] = 'SVGAttributeHook(\'' + namespace + '\',\'' + value + '\')';
169 | }
170 | });
171 | }
172 | var objectStr = !isEmpty(objects) ? JSON.stringify(objects) : ""
173 |
174 | var item = 'h(' + JSON.stringify(element[0] + idSuffix + classSuffix) + (
175 | (objectStr !== "") ? ", " + objectStr : ""
176 | )
177 | // attrPairs.length || datasetPairs.length
178 | // ? ", { \"attributes\": { "
179 | // : ''
180 | // ) + (
181 | // attrPairs.length
182 | // ? attrPairs.join(",\n" + indent + ' ')
183 | // : ''
184 | // ) + (
185 | // datasetPairs.length && attrPairs.length
186 | // ? ",\n" + indent + ' '
187 | // : ''
188 | // ) + (
189 | // datasetPairs.length
190 | // ? "\"dataset\": { " + datasetPairs.join(",\n" + indent + ' ') + "}"
191 | // : ''
192 | // ) + (
193 | // attrPairs.length || datasetPairs.length
194 | // ? "}}"
195 | // : ''
196 | // )
197 |
198 | + (
199 | elementContent.length
200 | ? ', [' + (elementContent[0] === "\n" ? '' : ' ') + elementContent + (elementContent.match(/\s$/) ? '' : ' ') + ']'
201 | : ''
202 | ) + ')';
203 |
204 | currentItemList.add(item);
205 | },
206 | oncomment: function (text) {
207 | currentItemList.add('/*' + text + '*/', false); // @todo comment-safety
208 | },
209 | onend: function () {
210 | cb(null, currentItemList.content);
211 | }
212 | }, {decodeEntities: true, xmlMode: true});
213 |
214 | parser.write(html);
215 | parser.end();
216 | }
217 |
--------------------------------------------------------------------------------
/lib/svg-namespaces.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | Adapted from https://github.com/Matt-Esch/virtual-dom/blob/master/virtual-hyperscript/svg-attribute-namespace.js
5 | */
6 |
7 | var DEFAULT_NAMESPACE = null;
8 | var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
9 | var EV_NAMESPACE = 'http://www.w3.org/2001/xml-events';
10 | var XLINK_NAMESPACE = 'http://www.w3.org/1999/xlink';
11 | var XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
12 |
13 | // http://www.w3.org/TR/SVGTiny12/elementTable.html
14 | // http://www.w3.org/TR/SVG/eltindex.html
15 | var SVG_ELEMENTS = {
16 | 'listener': SVG_NAMESPACE,
17 | // 'a': SVG_NAMESPACE,
18 | 'animate': SVG_NAMESPACE,
19 | 'altGlyph': SVG_NAMESPACE,
20 | 'altGlyphDef': SVG_NAMESPACE,
21 | 'altGlyphItem': SVG_NAMESPACE,
22 | 'animateColor': SVG_NAMESPACE,
23 | 'animateMotion': SVG_NAMESPACE,
24 | 'animateTransform': SVG_NAMESPACE,
25 | 'animation': SVG_NAMESPACE,
26 | // 'audio': SVG_NAMESPACE,
27 | 'circle': SVG_NAMESPACE,
28 | 'defs': SVG_NAMESPACE,
29 | 'desc': SVG_NAMESPACE,
30 | 'discard': SVG_NAMESPACE,
31 | 'ellipse': SVG_NAMESPACE,
32 | 'feBlend': SVG_NAMESPACE,
33 | 'feColorMatrix': SVG_NAMESPACE,
34 | 'feComponentTransfer': SVG_NAMESPACE,
35 | 'feComposite': SVG_NAMESPACE,
36 | 'feConvolveMatrix': SVG_NAMESPACE,
37 | 'feDiffuseLighting': SVG_NAMESPACE,
38 | 'feDisplacementMap': SVG_NAMESPACE,
39 | 'feDistantLight': SVG_NAMESPACE,
40 | 'feFlood': SVG_NAMESPACE,
41 | 'feFuncA': SVG_NAMESPACE,
42 | 'feFuncB': SVG_NAMESPACE,
43 | 'feFuncG': SVG_NAMESPACE,
44 | 'feFuncR': SVG_NAMESPACE,
45 | 'feGaussianBlur': SVG_NAMESPACE,
46 | 'feImage': SVG_NAMESPACE,
47 | 'feMerge': SVG_NAMESPACE,
48 | 'feMergeNode': SVG_NAMESPACE,
49 | 'feMorphology': SVG_NAMESPACE,
50 | 'feOffset': SVG_NAMESPACE,
51 | 'fePointLight': SVG_NAMESPACE,
52 | 'feSpecularLighting': SVG_NAMESPACE,
53 | 'feSpotLight': SVG_NAMESPACE,
54 | 'feTile': SVG_NAMESPACE,
55 | 'feTurbulence': SVG_NAMESPACE,
56 | 'filter': SVG_NAMESPACE,
57 | 'font': SVG_NAMESPACE,
58 | 'font-face': SVG_NAMESPACE,
59 | 'font-face-format': SVG_NAMESPACE,
60 | 'font-face-name': SVG_NAMESPACE,
61 | 'font-face-src': SVG_NAMESPACE,
62 | 'font-face-uri': SVG_NAMESPACE,
63 | 'foreignObject': SVG_NAMESPACE,
64 | 'g': SVG_NAMESPACE,
65 | 'glyph': SVG_NAMESPACE,
66 | 'glyphRef': SVG_NAMESPACE,
67 | 'handler': SVG_NAMESPACE,
68 | 'hkern': SVG_NAMESPACE,
69 | 'image': SVG_NAMESPACE,
70 | 'line': SVG_NAMESPACE,
71 | 'linearGradient': SVG_NAMESPACE,
72 | 'metadata': SVG_NAMESPACE,
73 | 'missing-glyph': SVG_NAMESPACE,
74 | 'mpath': SVG_NAMESPACE,
75 | 'path': SVG_NAMESPACE,
76 | 'polygon': SVG_NAMESPACE,
77 | 'polyline': SVG_NAMESPACE,
78 | 'prefetch': SVG_NAMESPACE,
79 | 'radialGradient': SVG_NAMESPACE,
80 | 'rect': SVG_NAMESPACE,
81 | // 'script': SVG_NAMESPACE,
82 | 'set': SVG_NAMESPACE,
83 | 'solidColor': SVG_NAMESPACE,
84 | 'stop': SVG_NAMESPACE,
85 | 'svg': SVG_NAMESPACE,
86 | 'switch': SVG_NAMESPACE,
87 | 'symbol': SVG_NAMESPACE,
88 | 'tbreak': SVG_NAMESPACE,
89 | 'text': SVG_NAMESPACE,
90 | // 'textArea': SVG_NAMESPACE,
91 | 'title': SVG_NAMESPACE,
92 | 'tspan': SVG_NAMESPACE,
93 | 'tref': SVG_NAMESPACE,
94 | 'use': SVG_NAMESPACE,
95 | 'vkern': SVG_NAMESPACE,
96 | // 'video': SVG_NAMESPACE,
97 | };
98 |
99 | // http://www.w3.org/TR/SVGTiny12/attributeTable.html
100 | // http://www.w3.org/TR/SVG/attindex.html
101 | var SVG_PROPERTIES = {
102 | 'about': DEFAULT_NAMESPACE,
103 | 'accent-height': DEFAULT_NAMESPACE,
104 | 'accumulate': DEFAULT_NAMESPACE,
105 | 'additive': DEFAULT_NAMESPACE,
106 | 'alignment-baseline': DEFAULT_NAMESPACE,
107 | 'alphabetic': DEFAULT_NAMESPACE,
108 | 'amplitude': DEFAULT_NAMESPACE,
109 | 'arabic-form': DEFAULT_NAMESPACE,
110 | 'ascent': DEFAULT_NAMESPACE,
111 | 'attributeName': DEFAULT_NAMESPACE,
112 | 'attributeType': DEFAULT_NAMESPACE,
113 | 'azimuth': DEFAULT_NAMESPACE,
114 | 'bandwidth': DEFAULT_NAMESPACE,
115 | 'baseFrequency': DEFAULT_NAMESPACE,
116 | 'baseProfile': DEFAULT_NAMESPACE,
117 | 'baseline-shift': DEFAULT_NAMESPACE,
118 | 'bbox': DEFAULT_NAMESPACE,
119 | 'begin': DEFAULT_NAMESPACE,
120 | 'bias': DEFAULT_NAMESPACE,
121 | 'by': DEFAULT_NAMESPACE,
122 | 'calcMode': DEFAULT_NAMESPACE,
123 | 'cap-height': DEFAULT_NAMESPACE,
124 | 'class': DEFAULT_NAMESPACE,
125 | 'clip': DEFAULT_NAMESPACE,
126 | 'clip-path': DEFAULT_NAMESPACE,
127 | 'clip-rule': DEFAULT_NAMESPACE,
128 | 'clipPathUnits': DEFAULT_NAMESPACE,
129 | 'color': DEFAULT_NAMESPACE,
130 | 'color-interpolation': DEFAULT_NAMESPACE,
131 | 'color-interpolation-filters': DEFAULT_NAMESPACE,
132 | 'color-profile': DEFAULT_NAMESPACE,
133 | 'color-rendering': DEFAULT_NAMESPACE,
134 | 'content': DEFAULT_NAMESPACE,
135 | 'contentScriptType': DEFAULT_NAMESPACE,
136 | 'contentStyleType': DEFAULT_NAMESPACE,
137 | 'cursor': DEFAULT_NAMESPACE,
138 | 'cx': DEFAULT_NAMESPACE,
139 | 'cy': DEFAULT_NAMESPACE,
140 | 'd': DEFAULT_NAMESPACE,
141 | 'datatype': DEFAULT_NAMESPACE,
142 | 'defaultAction': DEFAULT_NAMESPACE,
143 | 'descent': DEFAULT_NAMESPACE,
144 | 'diffuseConstant': DEFAULT_NAMESPACE,
145 | 'direction': DEFAULT_NAMESPACE,
146 | 'display': DEFAULT_NAMESPACE,
147 | 'divisor': DEFAULT_NAMESPACE,
148 | 'dominant-baseline': DEFAULT_NAMESPACE,
149 | 'dur': DEFAULT_NAMESPACE,
150 | 'dx': DEFAULT_NAMESPACE,
151 | 'dy': DEFAULT_NAMESPACE,
152 | 'edgeMode': DEFAULT_NAMESPACE,
153 | 'editable': DEFAULT_NAMESPACE,
154 | 'elevation': DEFAULT_NAMESPACE,
155 | 'enable-background': DEFAULT_NAMESPACE,
156 | 'end': DEFAULT_NAMESPACE,
157 | 'ev:event': EV_NAMESPACE,
158 | 'event': DEFAULT_NAMESPACE,
159 | 'exponent': DEFAULT_NAMESPACE,
160 | 'externalResourcesRequired': DEFAULT_NAMESPACE,
161 | 'fill': DEFAULT_NAMESPACE,
162 | 'fill-opacity': DEFAULT_NAMESPACE,
163 | 'fill-rule': DEFAULT_NAMESPACE,
164 | 'filter': DEFAULT_NAMESPACE,
165 | 'filterRes': DEFAULT_NAMESPACE,
166 | 'filterUnits': DEFAULT_NAMESPACE,
167 | 'flood-color': DEFAULT_NAMESPACE,
168 | 'flood-opacity': DEFAULT_NAMESPACE,
169 | 'focusHighlight': DEFAULT_NAMESPACE,
170 | 'focusable': DEFAULT_NAMESPACE,
171 | 'font-family': DEFAULT_NAMESPACE,
172 | 'font-size': DEFAULT_NAMESPACE,
173 | 'font-size-adjust': DEFAULT_NAMESPACE,
174 | 'font-stretch': DEFAULT_NAMESPACE,
175 | 'font-style': DEFAULT_NAMESPACE,
176 | 'font-variant': DEFAULT_NAMESPACE,
177 | 'font-weight': DEFAULT_NAMESPACE,
178 | 'format': DEFAULT_NAMESPACE,
179 | 'from': DEFAULT_NAMESPACE,
180 | 'fx': DEFAULT_NAMESPACE,
181 | 'fy': DEFAULT_NAMESPACE,
182 | 'g1': DEFAULT_NAMESPACE,
183 | 'g2': DEFAULT_NAMESPACE,
184 | 'glyph-name': DEFAULT_NAMESPACE,
185 | 'glyph-orientation-horizontal': DEFAULT_NAMESPACE,
186 | 'glyph-orientation-vertical': DEFAULT_NAMESPACE,
187 | 'glyphRef': DEFAULT_NAMESPACE,
188 | 'gradientTransform': DEFAULT_NAMESPACE,
189 | 'gradientUnits': DEFAULT_NAMESPACE,
190 | 'handler': DEFAULT_NAMESPACE,
191 | 'hanging': DEFAULT_NAMESPACE,
192 | 'height': DEFAULT_NAMESPACE,
193 | 'horiz-adv-x': DEFAULT_NAMESPACE,
194 | 'horiz-origin-x': DEFAULT_NAMESPACE,
195 | 'horiz-origin-y': DEFAULT_NAMESPACE,
196 | 'id': DEFAULT_NAMESPACE,
197 | 'ideographic': DEFAULT_NAMESPACE,
198 | 'image-rendering': DEFAULT_NAMESPACE,
199 | 'in': DEFAULT_NAMESPACE,
200 | 'in2': DEFAULT_NAMESPACE,
201 | 'initialVisibility': DEFAULT_NAMESPACE,
202 | 'intercept': DEFAULT_NAMESPACE,
203 | 'k': DEFAULT_NAMESPACE,
204 | 'k1': DEFAULT_NAMESPACE,
205 | 'k2': DEFAULT_NAMESPACE,
206 | 'k3': DEFAULT_NAMESPACE,
207 | 'k4': DEFAULT_NAMESPACE,
208 | 'kernelMatrix': DEFAULT_NAMESPACE,
209 | 'kernelUnitLength': DEFAULT_NAMESPACE,
210 | 'kerning': DEFAULT_NAMESPACE,
211 | 'keyPoints': DEFAULT_NAMESPACE,
212 | 'keySplines': DEFAULT_NAMESPACE,
213 | 'keyTimes': DEFAULT_NAMESPACE,
214 | 'lang': DEFAULT_NAMESPACE,
215 | 'lengthAdjust': DEFAULT_NAMESPACE,
216 | 'letter-spacing': DEFAULT_NAMESPACE,
217 | 'lighting-color': DEFAULT_NAMESPACE,
218 | 'limitingConeAngle': DEFAULT_NAMESPACE,
219 | 'local': DEFAULT_NAMESPACE,
220 | 'marker-end': DEFAULT_NAMESPACE,
221 | 'marker-mid': DEFAULT_NAMESPACE,
222 | 'marker-start': DEFAULT_NAMESPACE,
223 | 'markerHeight': DEFAULT_NAMESPACE,
224 | 'markerUnits': DEFAULT_NAMESPACE,
225 | 'markerWidth': DEFAULT_NAMESPACE,
226 | 'mask': DEFAULT_NAMESPACE,
227 | 'maskContentUnits': DEFAULT_NAMESPACE,
228 | 'maskUnits': DEFAULT_NAMESPACE,
229 | 'mathematical': DEFAULT_NAMESPACE,
230 | 'max': DEFAULT_NAMESPACE,
231 | 'media': DEFAULT_NAMESPACE,
232 | 'mediaCharacterEncoding': DEFAULT_NAMESPACE,
233 | 'mediaContentEncodings': DEFAULT_NAMESPACE,
234 | 'mediaSize': DEFAULT_NAMESPACE,
235 | 'mediaTime': DEFAULT_NAMESPACE,
236 | 'method': DEFAULT_NAMESPACE,
237 | 'min': DEFAULT_NAMESPACE,
238 | 'mode': DEFAULT_NAMESPACE,
239 | 'name': DEFAULT_NAMESPACE,
240 | 'nav-down': DEFAULT_NAMESPACE,
241 | 'nav-down-left': DEFAULT_NAMESPACE,
242 | 'nav-down-right': DEFAULT_NAMESPACE,
243 | 'nav-left': DEFAULT_NAMESPACE,
244 | 'nav-next': DEFAULT_NAMESPACE,
245 | 'nav-prev': DEFAULT_NAMESPACE,
246 | 'nav-right': DEFAULT_NAMESPACE,
247 | 'nav-up': DEFAULT_NAMESPACE,
248 | 'nav-up-left': DEFAULT_NAMESPACE,
249 | 'nav-up-right': DEFAULT_NAMESPACE,
250 | 'numOctaves': DEFAULT_NAMESPACE,
251 | 'observer': DEFAULT_NAMESPACE,
252 | 'offset': DEFAULT_NAMESPACE,
253 | 'opacity': DEFAULT_NAMESPACE,
254 | 'operator': DEFAULT_NAMESPACE,
255 | 'order': DEFAULT_NAMESPACE,
256 | 'orient': DEFAULT_NAMESPACE,
257 | 'orientation': DEFAULT_NAMESPACE,
258 | 'origin': DEFAULT_NAMESPACE,
259 | 'overflow': DEFAULT_NAMESPACE,
260 | 'overlay': DEFAULT_NAMESPACE,
261 | 'overline-position': DEFAULT_NAMESPACE,
262 | 'overline-thickness': DEFAULT_NAMESPACE,
263 | 'panose-1': DEFAULT_NAMESPACE,
264 | 'path': DEFAULT_NAMESPACE,
265 | 'pathLength': DEFAULT_NAMESPACE,
266 | 'patternContentUnits': DEFAULT_NAMESPACE,
267 | 'patternTransform': DEFAULT_NAMESPACE,
268 | 'patternUnits': DEFAULT_NAMESPACE,
269 | 'phase': DEFAULT_NAMESPACE,
270 | 'playbackOrder': DEFAULT_NAMESPACE,
271 | 'pointer-events': DEFAULT_NAMESPACE,
272 | 'points': DEFAULT_NAMESPACE,
273 | 'pointsAtX': DEFAULT_NAMESPACE,
274 | 'pointsAtY': DEFAULT_NAMESPACE,
275 | 'pointsAtZ': DEFAULT_NAMESPACE,
276 | 'preserveAlpha': DEFAULT_NAMESPACE,
277 | 'preserveAspectRatio': DEFAULT_NAMESPACE,
278 | 'primitiveUnits': DEFAULT_NAMESPACE,
279 | 'propagate': DEFAULT_NAMESPACE,
280 | 'property': DEFAULT_NAMESPACE,
281 | 'r': DEFAULT_NAMESPACE,
282 | 'radius': DEFAULT_NAMESPACE,
283 | 'refX': DEFAULT_NAMESPACE,
284 | 'refY': DEFAULT_NAMESPACE,
285 | 'rel': DEFAULT_NAMESPACE,
286 | 'rendering-intent': DEFAULT_NAMESPACE,
287 | 'repeatCount': DEFAULT_NAMESPACE,
288 | 'repeatDur': DEFAULT_NAMESPACE,
289 | 'requiredExtensions': DEFAULT_NAMESPACE,
290 | 'requiredFeatures': DEFAULT_NAMESPACE,
291 | 'requiredFonts': DEFAULT_NAMESPACE,
292 | 'requiredFormats': DEFAULT_NAMESPACE,
293 | 'resource': DEFAULT_NAMESPACE,
294 | 'restart': DEFAULT_NAMESPACE,
295 | 'result': DEFAULT_NAMESPACE,
296 | 'rev': DEFAULT_NAMESPACE,
297 | 'role': DEFAULT_NAMESPACE,
298 | 'rotate': DEFAULT_NAMESPACE,
299 | 'rx': DEFAULT_NAMESPACE,
300 | 'ry': DEFAULT_NAMESPACE,
301 | 'scale': DEFAULT_NAMESPACE,
302 | 'seed': DEFAULT_NAMESPACE,
303 | 'shape-rendering': DEFAULT_NAMESPACE,
304 | 'slope': DEFAULT_NAMESPACE,
305 | 'snapshotTime': DEFAULT_NAMESPACE,
306 | 'spacing': DEFAULT_NAMESPACE,
307 | 'specularConstant': DEFAULT_NAMESPACE,
308 | 'specularExponent': DEFAULT_NAMESPACE,
309 | 'spreadMethod': DEFAULT_NAMESPACE,
310 | 'startOffset': DEFAULT_NAMESPACE,
311 | 'stdDeviation': DEFAULT_NAMESPACE,
312 | 'stemh': DEFAULT_NAMESPACE,
313 | 'stemv': DEFAULT_NAMESPACE,
314 | 'stitchTiles': DEFAULT_NAMESPACE,
315 | 'stop-color': DEFAULT_NAMESPACE,
316 | 'stop-opacity': DEFAULT_NAMESPACE,
317 | 'strikethrough-position': DEFAULT_NAMESPACE,
318 | 'strikethrough-thickness': DEFAULT_NAMESPACE,
319 | 'string': DEFAULT_NAMESPACE,
320 | 'stroke': DEFAULT_NAMESPACE,
321 | 'stroke-dasharray': DEFAULT_NAMESPACE,
322 | 'stroke-dashoffset': DEFAULT_NAMESPACE,
323 | 'stroke-linecap': DEFAULT_NAMESPACE,
324 | 'stroke-linejoin': DEFAULT_NAMESPACE,
325 | 'stroke-miterlimit': DEFAULT_NAMESPACE,
326 | 'stroke-opacity': DEFAULT_NAMESPACE,
327 | 'stroke-width': DEFAULT_NAMESPACE,
328 | 'surfaceScale': DEFAULT_NAMESPACE,
329 | 'syncBehavior': DEFAULT_NAMESPACE,
330 | 'syncBehaviorDefault': DEFAULT_NAMESPACE,
331 | 'syncMaster': DEFAULT_NAMESPACE,
332 | 'syncTolerance': DEFAULT_NAMESPACE,
333 | 'syncToleranceDefault': DEFAULT_NAMESPACE,
334 | 'systemLanguage': DEFAULT_NAMESPACE,
335 | 'tableValues': DEFAULT_NAMESPACE,
336 | 'target': DEFAULT_NAMESPACE,
337 | 'targetX': DEFAULT_NAMESPACE,
338 | 'targetY': DEFAULT_NAMESPACE,
339 | 'text-anchor': DEFAULT_NAMESPACE,
340 | 'text-decoration': DEFAULT_NAMESPACE,
341 | 'text-rendering': DEFAULT_NAMESPACE,
342 | 'textLength': DEFAULT_NAMESPACE,
343 | 'timelineBegin': DEFAULT_NAMESPACE,
344 | 'title': DEFAULT_NAMESPACE,
345 | 'to': DEFAULT_NAMESPACE,
346 | 'transform': DEFAULT_NAMESPACE,
347 | 'transformBehavior': DEFAULT_NAMESPACE,
348 | 'type': DEFAULT_NAMESPACE,
349 | 'typeof': DEFAULT_NAMESPACE,
350 | 'u1': DEFAULT_NAMESPACE,
351 | 'u2': DEFAULT_NAMESPACE,
352 | 'underline-position': DEFAULT_NAMESPACE,
353 | 'underline-thickness': DEFAULT_NAMESPACE,
354 | 'unicode': DEFAULT_NAMESPACE,
355 | 'unicode-bidi': DEFAULT_NAMESPACE,
356 | 'unicode-range': DEFAULT_NAMESPACE,
357 | 'units-per-em': DEFAULT_NAMESPACE,
358 | 'v-alphabetic': DEFAULT_NAMESPACE,
359 | 'v-hanging': DEFAULT_NAMESPACE,
360 | 'v-ideographic': DEFAULT_NAMESPACE,
361 | 'v-mathematical': DEFAULT_NAMESPACE,
362 | 'values': DEFAULT_NAMESPACE,
363 | 'version': DEFAULT_NAMESPACE,
364 | 'vert-adv-y': DEFAULT_NAMESPACE,
365 | 'vert-origin-x': DEFAULT_NAMESPACE,
366 | 'vert-origin-y': DEFAULT_NAMESPACE,
367 | 'viewBox': DEFAULT_NAMESPACE,
368 | 'viewTarget': DEFAULT_NAMESPACE,
369 | 'visibility': DEFAULT_NAMESPACE,
370 | 'width': DEFAULT_NAMESPACE,
371 | 'widths': DEFAULT_NAMESPACE,
372 | 'word-spacing': DEFAULT_NAMESPACE,
373 | 'writing-mode': DEFAULT_NAMESPACE,
374 | 'x': DEFAULT_NAMESPACE,
375 | 'x-height': DEFAULT_NAMESPACE,
376 | 'x1': DEFAULT_NAMESPACE,
377 | 'x2': DEFAULT_NAMESPACE,
378 | 'xChannelSelector': DEFAULT_NAMESPACE,
379 | 'xlink:actuate': XLINK_NAMESPACE,
380 | 'xlink:arcrole': XLINK_NAMESPACE,
381 | 'xlink:href': XLINK_NAMESPACE,
382 | 'xlink:role': XLINK_NAMESPACE,
383 | 'xlink:show': XLINK_NAMESPACE,
384 | 'xlink:title': XLINK_NAMESPACE,
385 | 'xlink:type': XLINK_NAMESPACE,
386 | 'xml:base': XML_NAMESPACE,
387 | 'xml:id': XML_NAMESPACE,
388 | 'xml:lang': XML_NAMESPACE,
389 | 'xml:space': XML_NAMESPACE,
390 | 'y': DEFAULT_NAMESPACE,
391 | 'y1': DEFAULT_NAMESPACE,
392 | 'y2': DEFAULT_NAMESPACE,
393 | 'yChannelSelector': DEFAULT_NAMESPACE,
394 | 'z': DEFAULT_NAMESPACE,
395 | 'zoomAndPan': DEFAULT_NAMESPACE
396 | };
397 |
398 | function thisIsSVGTag(tag) {
399 | return SVG_ELEMENTS.hasOwnProperty(tag);
400 | }
401 |
402 | function getSVGNamespace() {
403 | return SVG_NAMESPACE;
404 | }
405 |
406 | function getSVGAttributeNamespace(value) {
407 | if (SVG_PROPERTIES.hasOwnProperty(value)) {
408 | return SVG_PROPERTIES[value];
409 | }
410 | }
411 |
412 | module.exports.thisIsSVGTag = thisIsSVGTag;
413 |
414 | module.exports.getSVGNamespace = getSVGNamespace;
415 |
416 | module.exports.getSVGAttributeNamespace = getSVGAttributeNamespace;
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "html2hscript",
3 | "version": "2.0.0",
4 | "description": "parse html into hyperscript",
5 | "main": "index.js",
6 | "directories": {
7 | "test": "test"
8 | },
9 | "dependencies": {
10 | "ent": "^2.2.0",
11 | "htmlparser2": "^3.8.2",
12 | "is-empty": "0.0.1",
13 | "to-camel-case": "^0.2.1"
14 | },
15 | "devDependencies": {
16 | "tap": "^1.3.1"
17 | },
18 | "scripts": {
19 | "test": "tap test/*.js"
20 | },
21 | "keywords": [
22 | "html",
23 | "parser",
24 | "hyperscript"
25 | ],
26 | "author": "https://www.npmjs.com/~unframework",
27 | "license": "MIT",
28 | "repository": {
29 | "type": "git",
30 | "url": "https://github.com/twilson63/html2hscript.git"
31 | },
32 | "bugs": {
33 | "url": "https://github.com/twilson63/html2hscript/issues"
34 | },
35 | "homepage": "https://github.com/twilson63/html2hscript"
36 | }
37 |
--------------------------------------------------------------------------------
/test/index_test.js:
--------------------------------------------------------------------------------
1 | var test = require('tap').test;
2 | var parser = require('../');
3 |
4 | test('should return attributes', function(t) {
5 | parser('Hello World
', function(err, hscript) {
6 | t.equals(hscript, 'h("h1", {"attributes":{"foo":"beep"}}, [ "Hello World" ])', 'success')
7 | t.end()
8 | })
9 | })
10 |
11 | test('should return hyperscript', function(t) {
12 | parser('', function(err, hscript) {
13 | t.equals(hscript, 'h("div", [ h("div", [ h("h1", {"attributes":{"foo":"beep"}}, [ "Hello World" ]) ]) ])', 'success')
14 | t.end()
15 | })
16 | })
17 |
18 | test('should return children', function(t) {
19 | parser('Hello\nWorld
', function(err, hscript) {
20 | t.equals(hscript, 'h("p", [ "Hello\\n", h("b", [ "World" ]) ])', 'success')
21 | t.end()
22 | })
23 | })
24 |
25 | test('should handle correctly pre', function(t) {
26 | parser('Hello\nWorld
', function(err, hscript) {
27 | t.equals(hscript, 'h("pre", [ "Hello\\nWorld" ])', 'success')
28 | t.end()
29 | })
30 | })
31 |
32 | test('should output style attribute as an object', function(t) {
33 | parser('Hello World
', function(err, hscript) {
34 | t.equals(hscript, 'h("h1", {"style":{"color":"red","font-size":"12px"}}, [ "Hello World" ])', 'success')
35 | t.end()
36 | })
37 | })
38 |
--------------------------------------------------------------------------------