-
Notifications
You must be signed in to change notification settings - Fork 4k
/
index.js
104 lines (93 loc) · 3.58 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import { extend, flow } from 'lodash';
import { defaultSettings } from './defaultSettings'
import stripTags from './stripTags';
import transposeAstralsToCountableChar from './transposeAstralsToCountableChar';
import stripHTMLEntities from './stripHTMLEntities';
import stripConnectors from './stripConnectors';
import stripRemovables from './stripRemovables';
import stripHTMLComments from './stripHTMLComments';
import stripShortcodes from './stripShortcodes';
import stripSpaces from './stripSpaces';
import transposeHTMLEntitiesToCountableChars from './transposeHTMLEntitiesToCountableChars';
/**
* Private function to manage the settings.
*
* @param {string} type The type of count to be done.
* @param {Object} userSettings Custom settings for the count.
*
* @return {void|Object|*} The combined settings object to be used.
*/
function loadSettings( type, userSettings ) {
const settings = extend( defaultSettings, userSettings );
settings.shortcodes = settings.l10n.shortcodes || {};
if ( settings.shortcodes && settings.shortcodes.length ) {
settings.shortcodesRegExp = new RegExp( '\\[\\/?(?:' + settings.shortcodes.join( '|' ) + ')[^\\]]*?\\]', 'g' );
}
settings.type = type || settings.l10n.type;
if ( settings.type !== 'characters_excluding_spaces' && settings.type !== 'characters_including_spaces' ) {
settings.type = 'words';
}
return settings;
}
/**
* Match the regex for the type 'words'
*
* @param {string} text The text being processed
* @param {string} regex The regular expression pattern being matched
* @param {object} settings Settings object containing regular expressions for each strip function
*
* @return {Array|{index: number, input: string}} The matched string.
*/
function matchWords( text, regex, settings ) {
text = flow(
stripTags.bind( this, settings ),
stripHTMLComments.bind( this, settings ),
stripShortcodes.bind( this, settings ),
stripSpaces.bind( this, settings ),
stripHTMLEntities.bind( this, settings ),
stripConnectors.bind( this, settings ),
stripRemovables.bind( this, settings ),
)( text );
text = text + '\n';
return text.match( regex );
}
/**
* Match the regex for either 'characters_excluding_spaces' or 'characters_including_spaces'
*
* @param {string} text The text being processed
* @param {string} regex The regular expression pattern being matched
* @param {object} settings Settings object containing regular expressions for each strip function
*
* @return {Array|{index: number, input: string}} The matched string.
*/
function matchCharacters( text, regex, settings ) {
text = flow(
stripTags.bind( this, settings ),
stripHTMLComments.bind( this, settings ),
stripShortcodes.bind( this, settings ),
stripSpaces.bind( this, settings ),
transposeAstralsToCountableChar.bind( this, settings ),
transposeHTMLEntitiesToCountableChars.bind( this, settings ),
)( text );
text = text + '\n';
return text.match( regex );
}
/**
* Count some words.
*
* @param {String} text The text being processed
* @param {String} type The type of count. Accepts ;words', 'characters_excluding_spaces', or 'characters_including_spaces'.
* @param {Object} userSettings Custom settings object.
*
* @return {Number} The word or character count.
*/
export function count( text, type, userSettings ) {
const settings = loadSettings( type, userSettings );
if ( text ) {
let matchRegExp = settings[ type + 'RegExp' ];
const results = ( 'words' === settings.type ) ?
matchWords( text, matchRegExp, settings ) :
matchCharacters( text, matchRegExp, settings );
return results ? results.length : 0;
}
}