├── .gitignore
├── .travis.yml
├── README.md
├── index.js
├── license
├── package.json
└── test.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | npm-debug.log
3 | .DS_Store
4 | Thumbs.db
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - 'iojs'
4 | - '4'
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # trunc-html
2 |
3 | [](https://travis-ci.org/bevacqua/trunc-html)
4 |
5 | > truncate html by text length
6 |
7 | # install
8 |
9 | using `npm`.
10 |
11 | ```shell
12 | npm install -S trunc-html
13 | ```
14 |
15 | # features
16 |
17 | - fast, lean, extensible
18 | - truncate by text length, not html length
19 | - truncate by complete words, not just by characters
20 |
21 | # `trunc(html, limit, options?)`
22 |
23 | Returns the result of truncating the provided `html`. A plain-text version is provided as well.
24 |
25 | ```js
26 | var html = 'the force is with this one. some more rubbish';
27 | trunc(html, 30);
28 | // <-
29 | // { html: 'the force is with this one. …',
30 | // text: 'the force is with this one. …' }
31 | ```
32 |
33 | ## `limit`
34 |
35 | Maximum amount of text characters allowed. When the `limit` is reached, the algorithm will trace back to the last word separator and trim the rest into a `…` glyph.
36 |
37 | ## `options.ignoreTags`
38 |
39 | If you'd like to supress certain HTML tags from being output you can provide an array of tags to be excluded, set `ignoreTags` to something like `['strong']`.
40 |
41 | ## `options.imageAltText`
42 |
43 | If you'd like to use the `alt` attribute for the text portion of the result, instead of dropping images entirely in text flavor, set `imageAltText` to `true`.
44 |
45 | ## `options.sanitizer`
46 |
47 | Options passed to [`insane`][1]. Note that these options are overridden by the options provided by `trunc-html`, so you can't use `transformText`, which `trunc-html` reserves for itself.
48 |
49 | # related
50 |
51 | - [`trunc-text`](https://github.com/bevacqua/trunc-text)
52 |
53 | # license
54 |
55 | MIT
56 |
57 | [1]: http://github.com/bevacqua/insane
58 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var insane = require('insane');
4 | var assign = require('assignment');
5 | var truncText = require('trunc-text');
6 | var delimiter = '…';
7 |
8 | function intoHashMap (map, tag) {
9 | map[tag] = true;
10 | return map;
11 | }
12 |
13 | function truncHtml (input, limit, options) {
14 | var o = options || {};
15 | var remainder = Number(limit);
16 | var ignoreTags = (o.ignoreTags || []).reduce(intoHashMap, Object.create(null));
17 | var altBuffer = '';
18 | var plain = '';
19 | var insaneDefaults = {
20 | filter: filter,
21 | transformText: transformText
22 | };
23 | var sanitizer = o.sanitizer || {};
24 | var opts = assign({}, sanitizer, insaneDefaults);
25 | var html = insane(input, opts);
26 | return { html: html, text: plain + altBuffer };
27 | function filter (token) {
28 | if (token.tag in ignoreTags) {
29 | return false;
30 | }
31 | if (remainder <= 0) {
32 | return false;
33 | }
34 | if (sanitizer.filter && !sanitizer.filter(token)) {
35 | return false;
36 | }
37 | if (o.imageAltText && token.tag === 'img') {
38 | altBuffer += token.attrs.alt;
39 | }
40 | return true;
41 | }
42 | function transformText (text) {
43 | if (remainder <= 0) {
44 | return '';
45 | }
46 | var truncated = truncText(text, remainder);
47 | if (truncated[truncated.length - 1] === delimiter) {
48 | remainder = 0;
49 | } else {
50 | remainder -= truncated.length;
51 | }
52 | plain += altBuffer + truncated;
53 | altBuffer = '';
54 | return truncated;
55 | }
56 | }
57 |
58 | module.exports = truncHtml;
59 |
--------------------------------------------------------------------------------
/license:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright © 2016 Nicolas Bevacqua
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "trunc-html",
3 | "description": "truncate html by text length",
4 | "version": "1.1.2",
5 | "homepage": "https://github.com/bevacqua/trunc-html",
6 | "author": {
7 | "name": "Nicolás Bevacqua",
8 | "email": "hello@ponyfoo.com",
9 | "url": "https://ponyfoo.com"
10 | },
11 | "license": "MIT",
12 | "repository": {
13 | "type": "git",
14 | "url": "git://github.com/bevacqua/trunc-html.git"
15 | },
16 | "scripts": {
17 | "test": "ava"
18 | },
19 | "dependencies": {
20 | "assignment": "2.2.0",
21 | "insane": "2.6.1",
22 | "trunc-text": "1.0.1"
23 | },
24 | "devDependencies": {
25 | "ava": "0.11.0"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/test.js:
--------------------------------------------------------------------------------
1 | var test = require('ava');
2 | var trunc = require('./');
3 | var sw = 'the force is with this one. some more rubbish';
4 |
5 | test(t => {
6 | t.same(trunc(sw, 30), {
7 | html: 'the force is with this one. …',
8 | text: 'the force is with this one. …'
9 | });
10 | });
11 |
12 | test(t => {
13 | t.same(trunc(sw, 30, { ignoreTags: ['strong'] }), {
14 | html: 'the force is . some more …',
15 | text: 'the force is . some more …'
16 | });
17 | });
18 |
19 | test(t => {
20 | t.same(trunc(sw, 30, { sanitizer: { allowedTags: [] } }), {
21 | html: 'the force is . some more …',
22 | text: 'the force is . some more …'
23 | });
24 | });
25 |
26 |
27 | test(t => {
28 | t.same(trunc('some sort of tada
', 30, { imageAltText: true }), {
29 | html: 'some sort of tada
',
30 | text: 'some sort of tada 🎉'
31 | });
32 | t.same(trunc('some
sort of tada
', 30, { imageAltText: true }), {
33 | html: 'some
sort of tada
',
34 | text: 'some 🎉 sort of tada 🎉'
35 | });
36 | t.same(trunc('some sort of tada
then
scoop', 30, { imageAltText: true, sanitizer: { filter: token => token.tag !== 'img' || token.attrs.class === 'tj-emoji' } }), {
37 | html: 'some sort of tada
then scoop',
38 | text: 'some sort of tada 🎉 then scoop'
39 | });
40 | });
41 |
--------------------------------------------------------------------------------