An open API service indexing awesome lists of open source software.

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

A starter project for building PostHTML plugins.
https://github.com/posthtml/posthtml-plugin-starter

html html-parsing posthtml posthtml-plugin

Last synced: 10 months ago
JSON representation

A starter project for building PostHTML plugins.

Awesome Lists containing this project

README

          


PostHTML

Plugin Starter Kit


A starter project for PostHTML plugins

[![Version][npm-version-shield]][npm]
[![Build][github-ci-shield]][github-ci]
[![License][license-shield]][license]
[![Downloads][npm-stats-shield]][npm-stats]

### About

This is a starter project for PostHTML plugins.

```sh
git clone https://github.com/posthtml/posthtml-plugin-starter.git
```

### Features

- [Async](#async-plugins) and [sync](#sync-plugins) examples
- Supports both ESM and CJS
- Node.js 18+
- Tests with [`vitest`](https://vitest.dev)
- Linting with [`biome`](https://biomejs.dev/)
- Releases with [`np`](https://github.com/sindresorhus/np)
- CI with GitHub Actions

#### Async plugins

When writing an async PostHTML plugin, you must return a `Promise` that resolves the current `tree`:

```js
export default (options = {}) => tree => {
// Accept options and set defaults
options.foo = options.foo || {}

return new Promise((resolve, reject) => {
try {
// do something async

// finally, resolve the promise by returning the tree
resolve(tree)
} catch (error) {
reject(error)
}
})
}
```

Note: async plugins can't be used in PostHTML's [`sync` mode](https://posthtml.org/#/core?id=posthtml-options).

#### Sync plugins

Synchronous plugins just need to return the `tree`.

You may use the `tree.walk` method to traverse the `tree` and handle nodes.

The handling of nodes can be a function that is passed to `tree.walk`, and which must return the node:

```js
export default (options = {}) => tree => {
options.foo = options.foo || {}

const handleNodes = node => {
// Write your code...

// Return the node
return node
}

return tree.walk(handleNodes)
}
```

#### Tests

The testing boilerplate includes a `process()` method which accepts 4 parameters:

- `t` the test object
- `name` the file name of the fixture/expected files, excluding extension
- `options` any options to pass to the plugin when testing
- `log` a boolean that turns on logging to console

For example, imagine we're writing a test that uses `/test/fixtures/skip-nodes.html`:

```js
test('It skips nodes defined in `skipNodes` option', t => {
return process(t, 'skip-nodes', {skipNodes: ['a']}, true)
})
```

As you can see, the second parameter passed to the `process()` method is the fixture file name, without the `.html` extension.

##### Testing for Errors

To test errors thrown by your plugin, use the `error()` method:

```js
test('Syntax error', t => {
return error('syntax-error', err => {
expect(err.message).toBe('Invalid or unexpected token')
})
})
```

Just like before, the first parameter passed to `error()` is the fixture file name, without the extension.

#### Linting

You may configure `eslint` in `.eslintrc`. See [ESLint rules](https://eslint.org/docs/rules/) for options.

#### Coverage

`@vitest/coverage-v8` defaults are used, you may [configure it](https://vitest.dev/guide/coverage.html).

#### Releases

The starter uses `np` for publishing to npm, take a look at its [configuration options](https://github.com/sindresorhus/np#config).

When publishing your first release, leave `"version": "0.0.0"` in `package.json` - you will set it through `np`'s interactive UI.

#### Continuous Integration

GitHub Actions is used for continuous integration, and you can configure it by editing the `.github/workflows/nodejs.yml` file.

A `.github/dependabot.yml` config file is also included, to help automate dependency updates.

### Other notes

- update shield icon URLs at the end of this file
- edit (or remove) the issue template
- update `package.json` fields
- update the `LICENSE` file

_Delete all of the above text, including the separator below - what follows is some boilerplate for your plugin's `README.md`._

---

## Introduction

Describe what your plugin does.

Optionally add a short before & after example, like so:

Input:

```html

Test

```

Output:

```html

TEST

```

## Install

```
npm i posthtml posthtml-myplugin
```

## Usage

Provide clear code samples showing how to use the plugin:

```js
import posthtml from 'posthtml'
import myplugin from 'posthtml-myplugin'

posthtml([
myplugin()
])
.process('

Test
')
.then(result => console.log(result.html))
```

Result:

```html

TEST

```

## Syntax

Most PostHTML plugins use custom HTML syntax, like custom tag names or even custom attributes. If your plugin requires using custom markup, document it here.

For example:

### Tag

Use the `` tag to transform all text inside it:

```xml
Test
```

The tag is removed in the output.

Result:

```html
TEST
```

### Attribute

You can use a filter by calling it as the value of the `filter` attribute:

```html

Test

```

The `filter` attribute is removed in the output.

Result:

```html

TEST

```

## Options

If your plugin can be configured through options, explain what they do and how to use them. Make sure to specify what the defaults are.

For example:

### `only`

Type: `array`\
Default: `[]`

Array of filter names to use. All other filters will be disabled.

```js
import posthtml from 'posthtml'
import myplugin from 'posthtml-myplugin'

posthtml([
myplugin({
only: ['uppercase', 'slugify']
})
])
.process('

Test
')
.then(result => console.log(result.html))
```

By default, this is set to an empty array, which means that all filters can be used.

## 3rd parties

If your plugin depends on third party libraries that require configuration, explain here what the user needs to do.

[npm]: https://www.npmjs.com/package/posthtml
[npm-version-shield]: https://img.shields.io/npm/v/posthtml.svg
[npm-stats]: http://npm-stat.com/charts.html?package=posthtml
[npm-stats-shield]: https://img.shields.io/npm/dt/posthtml.svg
[github-ci]: https://github.com/posthtml/posthtml-plugin-starter/actions/workflows/nodejs.yml
[github-ci-shield]: https://github.com/posthtml/posthtml-plugin-starter/actions/workflows/nodejs.yml/badge.svg
[license]: ./license
[license-shield]: https://img.shields.io/npm/l/posthtml.svg