Package Exports
- posthtml
- posthtml/lib/api
- posthtml/lib/parser
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (posthtml) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
PostHTML
PostHTML is a tool for transforming HTML/XML with JS plugins. PostHTML itself is very small. It includes only a HTML parser, a HTML node tree API and a node tree stringifier.
All HTML transformations are made by plugins. And these plugins are just small plain JS functions, which receive a HTML node tree, transform it, and return a modified tree.
Usage
Install PostHTML
npm install --save-dev posthtml
Simple example
var posthtml = require('posthtml');
var html = '<myComponent><myTitle>Super Title</myTitle><myText>Awesome Text</myText></myComponent>';
posthtml()
.use(require('posthtml-custom-elements')())
.process(html/*, options */)
.then(function(result) {
console.log(result.html);
// <div class="myComponent"><div class="myTitle">Super Title</div><div class="myText">Awesome Text</div></div>
});
Сomplex example
var posthtml = require('posthtml');
var html = '<html><body><p class="wow">OMG</p></body></html>';
posthtml([
require('posthtml-doctype')('<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'),
require('posthtml-to-svg-tags')(),
require('posthtml-extend-attrs')({
attrsTree: {
'.wow' : {
id: 'wow_id',
fill: '#4A83B4',
'fill-rule': 'evenodd',
'font-family': 'Verdana'
}
}
})
])
.process(html/*, options */)
.then(function(result) {
console.log(result.html);
// <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
// <svg xmlns="http://www.w3.org/2000/svg"><text class="wow" id="wow_id" fill="#4A83B4" fill-rule="evenodd" font-family="Verdana">OMG</text></svg>
});
Gulp plugin for PostHTML
Install gulp-posthtml
npm install --save-dev gulp-posthtml
gulp.task('html', function() {
var posthtml = require('gulp-posthtml');
return gulp.src('src/**/*.html')
.pipe(posthtml([ require('posthtml-custom-elements')() ]/*, options */))
.pipe(gulp.dest('build/'));
});
PostHTML JSON tree example
input HTML
<a class="animals" href="#">
<span class="animals__cat" style="background: url(cat.png)">Cat</span>
</a>
Tree in PostHTML (PostHTMLTree)
[{
tag: 'a',
attrs: {
class: 'animals',
href: '#'
},
content: [{
tag: 'span',
attrs: {
class: 'animals__cat',
style: 'background: url(cat.png)'
},
content: ['Cat']
}]
}]
Create PostHTML plugin
This is a simple function with a single argument
Synchronous plugin example
module.exports = function pluginName(tree) {
// do something for tree
tree.match({ tag: 'img' }, function(node) {
node = Object.assign(node, { attrs: { class: 'img-wrapped' } }});
return {
tag: 'span',
attrs: { class: 'img-wrapper' },
content: node
}
});
};
Classic asynchronous plugin example
var request = request('request');
module.exports = function pluginName(tree, cb) {
var tasks = 0;
tree.match({ tag: 'a' }, function(node) {
// skip local anchors
if (!/^(https?:)?\/\//.test(node.attrs.href)) {
return node;
}
request.head(node.attrs.href, function (err, resp) {
if (err) return done();
if (resp.statusCode >= 400) {
node.attrs.class += ' ' + 'Erroric';
}
if (resp.headers.contentType) {
node.attrs.class += ' content-type_' + resp.headers.contentType;
}
done();
});
tasks += 1;
return node;
});
function done() {
tasks -= 1;
if (!tasks) cb(null, tree);
}
};
Promised asynchronous plugin example
import { PostHTML } from 'posthtml';
import request from 'request';
export default tree => {
return new Promise(resolve => {
tree.match({ tag: 'user-info' }, (node) => {
request(`/api/user-info?${node.attrs.dataUserId}`, (err, resp, body) {
if (!err && body) node.content = PostHTML.parse(body);
resolve(tree);
});
});
});
};
class PostHTML
#parse ({String} html): {PostHTMLTree}
Parses HTML string into a PostHTMLTree object.
Example
import { PostHTML } from 'posthtml';
PostHTML.parse('<div></div>'); // [{ tag: 'div' }]
.use ({Function} plugin): {PostHTML}
Adds a plugin into the flow.
Example
var posthtml = require('posthtml');
var ph = posthtml()
.use(function(tree) {
return { tag: 'div', content: tree };
});
.process ({String|PostHTMLTree} html, {Object} options): {{tree: PostHTMLTree, html: String}}
Applies all plugins to the incoming html
object.
Returns (eventually) an Object with modified html and/or tree.
Example
var ph = posthtml()
.process('<div></div>'/*, { options }*/);
Options
singleTags
Array tags for extend default list single tags
Default: []
Options { singleTags: ['rect', 'custom'] }
...
<div>
...
<rect>
<custom>
</div>
closingSingleTag
Option to specify version closing single tags.
Accepts values: default
, slash
, tag
.
Default: default
Options { closingSingleTag: 'default' }
<singletag>
Options { closingSingleTag: 'slash' }
<singletag />
Options { closingSingleTag: 'tag' }
<singletag></singletag>
skipParse
Skips input html parsing process.
Default: null
posthtml()
.use(function(tree) { tree.tag = 'section'; })
.process({ tag: 'div' }, { skipParse: true })
.then(function (result) {
result.tree; // { tag: 'section' }
result.html; // <section></section>
});
sync
Try to run plugins synchronously. Throws if some plugins are async.
Default: null
posthtml()
.use(function(tree) { tree.tag = 'section'; })
.process('<div>foo</div>', { sync: true })
.html; // <section>foo</section>
class API
.walk ({function(PostHTMLNode): PostHTMLNode})
Walk for all nodes in tree, run callback.
Example
tree.walk(function(node) {
let classes = node.attrs && node.attrs.class.split(' ') || [];
if(classes.includes(className)) {
// do something for node
return node;
}
return node;
});
.match ({Object|String}, {function(PostHTMLNode): PostHTMLNode|String})
Find subtree in tree, run callback.
Example
tree.match({ tag: 'custom-tag' }, function(node) {
// do something for node
return Object.assign(node, {
tag: 'div',
attrs: { class: node.tag }
});
});
Support Array matchers
Example
tree.match([{ tag: 'b' }, { tag: 'strong' }], function(node) {
var style = 'font-weight: bold;';
node.tag = 'span';
node.attrs ? (
node.attrs.style ? (
node.attrs.style += style
) : node.attrs.style = style;
) : node.attrs = { style: style };
return node
});
.matchClass ({String}, {function(PostHTMLNode): PostHTMLNode})
For each found of class run callback
Example
tree.matchClass('class-for-delete', function(node) {
// do something for node
return ''; // delete this node in tree
});
Plugins
- posthtml-textr — Modular typographic framework
- posthtml-custom-elements — Use custom elements now
- posthtml-style-to-file — Save HTML style nodes and attributes to CSS file
- posthtml-doctype — Extend html tags doctype
- posthtml-to-svg-tags — Convert html tags to svg equals
- posthtml-extend-attrs — Extend html tags attributes with custom data and attributes
- posthtml-modular-css — Makes css modular
Ideas for plugins
- retext — Extensible system for analysing and manipulating natural language
- posthtml-include — Include html file
- posthtml-imports — Support W3C HTML imports
- posthtml-style — Include css file in HTML. Save <style>, style attrs to CSS file
- posthtml-classes — Configure node in classes
- beml — HTML preprocessor for BEM
- mimic
Something more? ;)