Skip to content

Commit

Permalink
doc and test access to formatters from formatters
Browse files Browse the repository at this point in the history
  • Loading branch information
KillyMXI committed Dec 6, 2022
1 parent 5e8e413 commit 69e3a24
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
29 changes: 29 additions & 0 deletions packages/html-to-text/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,35 @@ Refer to [generic formatters](https://github.com/html-to-text/node-html-to-text/

Refer to [BlockTextBuilder](https://github.com/html-to-text/node-html-to-text/blob/master/packages/base/src/block-text-builder.js) for available functions and arguments.

#### Call other formatters from a custom formatter

Most of the times this is *not* what you actually need. Most practical problems can be solved with [selectors](#selectors).

If you really need to inspect the node internals, not just attributes, then you can do it like this:

```javascript
const options = {
// ...
formatters: {
filterBlockFormatter: function (elem, walk, builder, formatOptions) {
// all built-in and custom formatters available by name
const blockFormatter = builder.options.formatters['block'];
if (blockFormatter && elem.children.some(/* predicate */)) {
blockFormatter(elem, walk, builder, formatOptions);
}
}
},
selectors: [
{
selector: 'div.questionable',
format: 'filterBlockFormatter',
options: { leadingLineBreaks: 1, trailingLineBreaks: 1 }
}
],
// ...
}
```

## Example

* Input text: [test.html](https://github.com/html-to-text/node-html-to-text/blob/master/packages/html-to-text/test/test.html)
Expand Down
26 changes: 26 additions & 0 deletions packages/html-to-text/test/tags.js
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,32 @@ describe('tags', function () {
expect(htmlToText(html, options)).to.equal(expected);
});

it('should allow to call existing formatters from other formatters', function () {
const html = '<div>Useful</div><div>Advertisement</div><article>Handy <section><div>info</div><div>Advertisement</div></section></article><article>ads galore</article>';
const options = {
formatters: {
adFreeBlock: function (elem, walk, builder, formatOptions) {
// domutils package has functions more suitable in similar situations. This is just a test.
const regExp = formatOptions.filterRegExp || /advertisement/i;
if (elem.children.some(ch => ch.type === 'text' && regExp.test(ch.data))) {
// do nothing
} else {
const blockFormatter = builder.options.formatters['block'];
if (blockFormatter) {
blockFormatter(elem, walk, builder, formatOptions);
}
}
}
},
selectors: [
{ selector: 'div', format: 'adFreeBlock' },
{ selector: 'article', format: 'adFreeBlock', options: { filterRegExp: /^ad/i, leadingLineBreaks: 4 } }
]
};
const expected = 'Useful\n\n\n\nHandy\ninfo';
expect(htmlToText(html, options)).to.equal(expected);
});

});

describe('selectors', function () {
Expand Down

0 comments on commit 69e3a24

Please sign in to comment.