PostHTML

PostHTML is a tool to transform HTML/XML with JS plugins

README

[![NPM][npm]][npm-url] [![Tests][build]][build-url] [![Coverage][cover]][cover-url] [![Standard Code Style][code-style]][code-style-url] [![Twitter][twitter]][twitter-url]

# 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.

For more detailed information about PostHTML in general take a look at the [docs][docs-url].

Dependencies


| Name | Status | Description |
|:----:|:------:|:-----------:|
|[posthtml-parser][parser]|[![npm][parser-badge]][parser-npm]| Parser HTML/XML to PostHTMLTree |
|[posthtml-render][render]|[![npm][render-badge]][render-npm]| Render PostHTMLTree to HTML/XML |


[docs]: https://github.com/posthtml/posthtml/blob/master/docs

[parser]: https://github.com/posthtml/posthtml-parser
[parser-badge]: https://img.shields.io/npm/v/posthtml-parser.svg
[parser-npm]: https://npmjs.com/package/posthtml-parser

[render]: https://github.com/posthtml/posthtml-render
[render-badge]: https://img.shields.io/npm/v/posthtml-render.svg
[render-npm]: https://npmjs.com/package/posthtml-render

Create to your project


  1. ```bash
  2. npm init posthtml
  3. ```

Install


  1. ```bash
  2. npm i -D posthtml
  3. ```

Usage


API


Sync

  1. ```js
  2. import posthtml from 'posthtml'

  3. const html = `
  4.   <component>
  5.     <title>Super Title</title>
  6.     <text>Awesome Text</text>
  7.   </component>
  8. `

  9. const result = posthtml()
  10.   .use(require('posthtml-custom-elements')())
  11.   .process(html, { sync: true })
  12.   .html

  13. console.log(result)
  14. ```

  1. ```html
  2. <div class="component">
  3.   <div class="title">Super Title</div>
  4.   <div class="text">Awesome Text</div>
  5. </div>
  6. ```

:warning: Async Plugins can't be used in sync mode and will throw an Error. It's recommended to use PostHTML asynchronously whenever possible.


Async

  1. ```js
  2. import posthtml from 'posthtml'

  3. const html = `
  4.   <html>
  5.     <body>
  6.       <p class="wow">OMG</p>
  7.     </body>
  8.   </html>
  9. `

  10. posthtml(
  11.   [
  12.     require('posthtml-to-svg-tags')(),
  13.     require('posthtml-extend-attrs')({
  14.       attrsTree: {
  15.         '.wow' : {
  16.           id: 'wow_id',
  17.           fill: '#4A83B4',
  18.           'fill-rule': 'evenodd',
  19.           'font-family': 'Verdana'
  20.         }
  21.       }
  22.     })
  23.   ])
  24.   .process(html/*, options */)
  25.   .then((result) =>  console.log(result.html))
  26. ```

  1. ```html
  2. <svg xmlns="http://www.w3.org/2000/svg">
  3.   <text
  4.     class="wow"
  5.     id="wow_id"
  6.     fill="#4A83B4"
  7.     fill-rule="evenodd" font-family="Verdana">
  8.       OMG
  9.   </text>
  10. </svg>
  11. ```

Directives

  1. ```js
  2. import posthtml from 'posthtml'

  3. const php = `
  4.   <component>
  5.     <title><?php echo $title; ?></title>
  6.     <text><?php echo $article; ?></text>
  7.   </component>
  8. `

  9. const result = posthtml()
  10.   .use(require('posthtml-custom-elements')())
  11.   .process(html, {
  12.     directives: [
  13.       { name: '?php', start: '<', end: '>' }
  14.     ]
  15.   })
  16.   .html

  17. console.log(result)
  18. ```

  1. ```html
  2. <div class="component">
  3.   <div class="title">?php echo $title; ?></div>
  4.   <div class="text">?php echo $article; ?></div>
  5. </div>
  6. ```


  1. ```bash
  2. npm i posthtml-cli
  3. ```

  1. ```json
  2. "scripts": {
  3.   "posthtml": "posthtml -o output.html -i input.html -c config.json"
  4. }
  5. ```

  1. ```bash
  2. npm run posthtml
  3. ```


  1. ```bash
  2. npm i -D gulp-posthtml
  3. ```

  1. ```js
  2. import tap from 'gulp-tap'
  3. import posthtml from 'gulp-posthtml'
  4. import { task, src, dest } from 'gulp'

  5. task('html', () => {
  6.   let path

  7.   const plugins = [ require('posthtml-include')({ root: `${path}` }) ]
  8.   const options = {}

  9.   src('src/**/*.html')
  10.     .pipe(tap((file) => path = file.path))
  11.     .pipe(posthtml(plugins, options))
  12.     .pipe(dest('build/'))
  13. })
  14. ```

Check project-stub for an example with Gulp


  1. ```bash
  2. npm i -D grunt-posthtml
  3. ```

  1. ```js
  2. posthtml: {
  3.   options: {
  4.     use: [
  5.       require('posthtml-doctype')({ doctype: 'HTML 5' }),
  6.       require('posthtml-include')({ root: './', encoding: 'utf-8' })
  7.     ]
  8.   },
  9.   build: {
  10.     files: [
  11.       {
  12.         dot: true,
  13.         cwd: 'html/',
  14.         src: ['*.html'],
  15.         dest: 'tmp/',
  16.         expand: true,
  17.       }
  18.     ]
  19.   }
  20. }
  21. ```


  1. ```bash
  2. npm i -D html-loader posthtml-loader
  3. ```

v1.x


webpack.config.js

  1. ```js
  2. const config = {
  3.   module: {
  4.     loaders: [
  5.       {
  6.         test: /\.html$/,
  7.         loader: 'html!posthtml'
  8.       }
  9.     ]
  10.   },
  11.   posthtml: (ctx) => ({
  12.     parser: require('posthtml-pug'),
  13.     plugins: [
  14.       require('posthtml-bem')()
  15.     ]
  16.   })
  17. }

  18. export default config
  19. ```

v2.x


webpack.config.js

  1. ```js
  2. import { LoaderOptionsPlugin } from 'webpack'

  3. const config = {
  4.   module: {
  5.     rules: [
  6.       {
  7.         test: /\.html$/,
  8.         use: [
  9.           {
  10.             loader: 'html-loader',
  11.             options: { minimize: true }
  12.           },
  13.           {
  14.             loader: 'posthtml-loader'
  15.           }
  16.         ]
  17.       }
  18.     ]
  19.   },
  20.   plugins: [
  21.     new LoaderOptionsPlugin({
  22.       options: {
  23.         posthtml(ctx) {
  24.           return {
  25.             parser: require('posthtml-pug'),
  26.             plugins: [
  27.               require('posthtml-bem')()
  28.             ]
  29.           }
  30.         }
  31.       }
  32.     })
  33.   ]
  34. }

  35. export default config
  36. ```


  1. ```bash
  2. $ npm i rollup-plugin-posthtml -D
  3. # or
  4. $ npm i rollup-plugin-posthtml-template -D
  5. ```

  1. ```js
  2. import { join } from 'path';

  3. import posthtml from 'rollup-plugin-posthtml-template';
  4. // or
  5. // import posthtml from 'rollup-plugin-posthtml';

  6. import sugarml from 'posthtml-sugarml';  // npm i posthtml-sugarml -D
  7. import include from 'posthtml-include';  // npm i posthtml-include -D

  8. export default {
  9.   entry: join(__dirname, 'main.js'),
  10.   dest: join(__dirname, 'bundle.js'),
  11.   format: 'iife',
  12.   plugins: [
  13.     posthtml({
  14.       parser: sugarml(),
  15.       plugins: [include()],
  16.       template: true  // only rollup-plugin-posthtml-template
  17.     })
  18.   ]
  19. };
  20. ```

Parser


  1. ```js
  2. import pug from 'posthtml-pug'

  3. posthtml().process(html, { parser: pug(options) }).then((result) => result.html)
  4. ```

| Name |Status|Description|
|:-----|:-----|:----------|
|[posthtml-pug][pug]|[![npm][pug-badge]][pug-npm]|Pug Parser|
|[sugarml][sugar]|[![npm][sugar-badge]][sugar-npm]|SugarML Parser|


[pug]: https://github.com/posthtml/posthtml-pug
[pug-badge]: https://img.shields.io/npm/v/posthtml-pug.svg
[pug-npm]: https://npmjs.com/package/posthtml-pug

[sugar]: https://github.com/posthtml/sugarml
[sugar-badge]: https://img.shields.io/npm/v/sugarml.svg
[sugar-npm]: https://npmjs.com/package/sugarml

Plugins


In case you want to develop your own plugin, we recommend using [posthtml-plugin-starter][plugin] to get started.


[plugin]: https://github.com/posthtml/posthtml-plugin-starter

Maintainers


      <img width="150 height="150"
      src="https://avatars0.githubusercontent.com/u/2789192?s=460&v=4">

Ivan Demidov
      <img width="150 height="150"
      src="https://avatars.githubusercontent.com/u/1510217?v=3&s=150">

Ivan Voischev

Contributors



Backers


Thank you to all our backers! 🙏 [Become a backer]



[npm]: https://img.shields.io/npm/v/posthtml.svg
[npm-url]: https://npmjs.com/package/posthtml

[build]: https://github.com/posthtml/posthtml/workflows/Actions%20Status/badge.svg?style=flat-square
[build-url]: https://github.com/posthtml/posthtml/actions?query=workflow%3A%22CI+tests%22

[cover]: https://coveralls.io/repos/posthtml/posthtml/badge.svg?branch=master
[cover-url]: https://coveralls.io/r/posthtml/posthtml?branch=master

[code-style]: https://img.shields.io/badge/code%20style-standard-yellow.svg
[code-style-url]: http://standardjs.com/

[twitter]: https://badgen.net/twitter/follow/posthtml
[twitter-url]: https://twitter.com/PostHTML

[chat]: https://badges.gitter.im/posthtml/PostHTML.svg
[chat-url]: https://gitter.im/posthtml/posthtml?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"
[docs-url]: https://github.com/posthtml/posthtml/tree/master/docs