string-match-left-right 7.1.0 → 8.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,36 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## 8.0.3 (2021-11-02)
7
+
8
+ ### Bug Fixes
9
+
10
+ - bump TS and separate ESLint plugins away from this monorepo ([b1ebce1](https://github.com/codsen/codsen/commit/b1ebce1637d8c41c2d848fc24b0ba4058865bd5d))
11
+
12
+ ### Features
13
+
14
+ - migrate to ES Modules ([c579dff](https://github.com/codsen/codsen/commit/c579dff3b23205e383035ca10ddcec671e35d0fe))
15
+
16
+ ### BREAKING CHANGES
17
+
18
+ - programs now are in ES Modules and won't work with Common JS require()
19
+
20
+ ## 8.0.1 (2021-09-13)
21
+
22
+ ### Bug Fixes
23
+
24
+ - bump TS and separate ESLint plugins away from this monorepo ([2e07d42](https://github.com/codsen/codsen/commit/2e07d424222b6ffedf5fb45c83ad453627ec2904))
25
+
26
+ ## 8.0.0 (2021-09-09)
27
+
28
+ ### Features
29
+
30
+ - migrate to ES Modules ([8c9d95d](https://github.com/codsen/codsen/commit/8c9d95d5dea0b769c2f070397141918a4893d575))
31
+
32
+ ### BREAKING CHANGES
33
+
34
+ - programs now are in ES Modules and won't work with Common JS require()
35
+
6
36
  ## 7.1.0 (2021-05-24)
7
37
 
8
38
  ### Features
package/README.md CHANGED
@@ -26,10 +26,14 @@
26
26
 
27
27
  ## Install
28
28
 
29
+ This package is ESM only: Node 12+ is needed to use it and it must be imported instead of required:
30
+
29
31
  ```bash
30
32
  npm i string-match-left-right
31
33
  ```
32
34
 
35
+ If you need a legacy version which works with `require`, use version 7.1.0
36
+
33
37
  ## Quick Take
34
38
 
35
39
  ```js
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @name string-match-left-right
3
3
  * @fileoverview Match substrings on the left or right of a given index, ignoring whitespace
4
- * @version 7.1.0
4
+ * @version 8.0.3
5
5
  * @author Roy Revelt, Codsen Ltd
6
6
  * @license MIT
7
7
  * {@link https://codsen.com/os/string-match-left-right/}
@@ -207,52 +207,52 @@ function main(mode, str, position, originalWhatToMatch, originalOpts) {
207
207
  Array.isArray(whatToMatch) && !whatToMatch.length ||
208
208
  Array.isArray(whatToMatch) && whatToMatch.length === 1 && isStr(whatToMatch[0]) && !whatToMatch[0].trim()
209
209
  ) {
210
- if (typeof opts.cb === "function") {
211
- let firstCharOutsideIndex;
212
- let startingPosition = position;
213
- if (mode === "matchLeftIncl" || mode === "matchRight") {
214
- startingPosition += 1;
215
- }
216
- if (mode[5] === "L") {
217
- for (let y = startingPosition; y--;) {
218
- const currentChar = str[y];
219
- if ((!opts.trimBeforeMatching || opts.trimBeforeMatching && currentChar !== undefined && currentChar.trim()) && (!opts.trimCharsBeforeMatching || !opts.trimCharsBeforeMatching.length || currentChar !== undefined && !opts.trimCharsBeforeMatching.includes(currentChar))) {
220
- firstCharOutsideIndex = y;
221
- break;
222
- }
223
- }
224
- } else if (mode.startsWith("matchRight")) {
225
- for (let y = startingPosition; y < str.length; y++) {
226
- const currentChar = str[y];
227
- if ((!opts.trimBeforeMatching || opts.trimBeforeMatching && currentChar.trim()) && (!opts.trimCharsBeforeMatching || !opts.trimCharsBeforeMatching.length || !opts.trimCharsBeforeMatching.includes(currentChar))) {
228
- firstCharOutsideIndex = y;
229
- break;
230
- }
210
+ if (typeof opts.cb === "function") {
211
+ let firstCharOutsideIndex;
212
+ let startingPosition = position;
213
+ if (mode === "matchLeftIncl" || mode === "matchRight") {
214
+ startingPosition += 1;
215
+ }
216
+ if (mode[5] === "L") {
217
+ for (let y = startingPosition; y--;) {
218
+ const currentChar = str[y];
219
+ if ((!opts.trimBeforeMatching || opts.trimBeforeMatching && currentChar !== undefined && currentChar.trim()) && (!opts.trimCharsBeforeMatching || !opts.trimCharsBeforeMatching.length || currentChar !== undefined && !opts.trimCharsBeforeMatching.includes(currentChar))) {
220
+ firstCharOutsideIndex = y;
221
+ break;
231
222
  }
232
223
  }
233
- if (firstCharOutsideIndex === undefined) {
234
- return false;
235
- }
236
- const wholeCharacterOutside = str[firstCharOutsideIndex];
237
- const indexOfTheCharacterAfter = firstCharOutsideIndex + 1;
238
- let theRemainderOfTheString = "";
239
- if (indexOfTheCharacterAfter && indexOfTheCharacterAfter > 0) {
240
- theRemainderOfTheString = str.slice(0, indexOfTheCharacterAfter);
241
- }
242
- if (mode[5] === "L") {
243
- return opts.cb(wholeCharacterOutside, theRemainderOfTheString, firstCharOutsideIndex);
244
- }
245
- if (firstCharOutsideIndex && firstCharOutsideIndex > 0) {
246
- theRemainderOfTheString = str.slice(firstCharOutsideIndex);
224
+ } else if (mode.startsWith("matchRight")) {
225
+ for (let y = startingPosition; y < str.length; y++) {
226
+ const currentChar = str[y];
227
+ if ((!opts.trimBeforeMatching || opts.trimBeforeMatching && currentChar.trim()) && (!opts.trimCharsBeforeMatching || !opts.trimCharsBeforeMatching.length || !opts.trimCharsBeforeMatching.includes(currentChar))) {
228
+ firstCharOutsideIndex = y;
229
+ break;
230
+ }
247
231
  }
232
+ }
233
+ if (firstCharOutsideIndex === undefined) {
234
+ return false;
235
+ }
236
+ const wholeCharacterOutside = str[firstCharOutsideIndex];
237
+ const indexOfTheCharacterAfter = firstCharOutsideIndex + 1;
238
+ let theRemainderOfTheString = "";
239
+ if (indexOfTheCharacterAfter && indexOfTheCharacterAfter > 0) {
240
+ theRemainderOfTheString = str.slice(0, indexOfTheCharacterAfter);
241
+ }
242
+ if (mode[5] === "L") {
248
243
  return opts.cb(wholeCharacterOutside, theRemainderOfTheString, firstCharOutsideIndex);
249
244
  }
250
- let extraNote = "";
251
- if (!originalOpts) {
252
- extraNote = " More so, the whole options object, the fourth input argument, is missing!";
245
+ if (firstCharOutsideIndex && firstCharOutsideIndex > 0) {
246
+ theRemainderOfTheString = str.slice(firstCharOutsideIndex);
253
247
  }
254
- throw new Error(`string-match-left-right/${mode}(): [THROW_ID_08] the third argument, "whatToMatch", was given as an empty string. This means, you intend to match purely by a callback. The callback was not set though, the opts key "cb" is not set!${extraNote}`);
248
+ return opts.cb(wholeCharacterOutside, theRemainderOfTheString, firstCharOutsideIndex);
255
249
  }
250
+ let extraNote = "";
251
+ if (!originalOpts) {
252
+ extraNote = " More so, the whole options object, the fourth input argument, is missing!";
253
+ }
254
+ throw new Error(`string-match-left-right/${mode}(): [THROW_ID_08] the third argument, "whatToMatch", was given as an empty string. This means, you intend to match purely by a callback. The callback was not set though, the opts key "cb" is not set!${extraNote}`);
255
+ }
256
256
  for (let i = 0, len = whatToMatch.length; i < len; i++) {
257
257
  special = typeof whatToMatch[i] === "function";
258
258
  const whatToMatchVal = whatToMatch[i];
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @name string-match-left-right
3
3
  * @fileoverview Match substrings on the left or right of a given index, ignoring whitespace
4
- * @version 7.1.0
4
+ * @version 8.0.3
5
5
  * @author Roy Revelt, Codsen Ltd
6
6
  * @license MIT
7
7
  * {@link https://codsen.com/os/string-match-left-right/}
@@ -11,7 +11,7 @@
11
11
  /**
12
12
  * @name arrayiffy-if-string
13
13
  * @fileoverview Put non-empty strings into arrays, turn empty-ones into empty arrays. Bypass everything else.
14
- * @version 3.14.0
14
+ * @version 4.0.3
15
15
  * @author Roy Revelt, Codsen Ltd
16
16
  * @license MIT
17
17
  * {@link https://codsen.com/os/arrayiffy-if-string/}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "string-match-left-right",
3
- "version": "7.1.0",
3
+ "version": "8.0.3",
4
4
  "description": "Match substrings on the left or right of a given index, ignoring whitespace",
5
5
  "keywords": [
6
6
  "left",
@@ -24,17 +24,21 @@
24
24
  "email": "roy@codsen.com",
25
25
  "url": "https://codsen.com"
26
26
  },
27
- "main": "dist/string-match-left-right.cjs.js",
28
- "module": "dist/string-match-left-right.esm.js",
29
- "browser": "dist/string-match-left-right.umd.js",
27
+ "type": "module",
28
+ "exports": {
29
+ "script": "./dist/string-match-left-right.umd.js",
30
+ "default": "./dist/string-match-left-right.esm.js"
31
+ },
30
32
  "types": "types/index.d.ts",
31
33
  "scripts": {
32
34
  "build": "rollup -c",
33
- "esbuild": "node '../../scripts/esbuild.js'",
34
- "esbuild_dev": "cross-env MODE=dev node '../../scripts/esbuild.js'",
35
35
  "ci_test": "npm run build && npm run format && tap --no-only --reporter=silent --output-file=testStats.md && npm run clean_cov",
36
+ "clean_cov": "../../scripts/leaveCoverageTotalOnly.js",
37
+ "clean_types": "../../scripts/cleanTypes.js",
36
38
  "dev": "rollup -c --dev",
37
39
  "devunittest": "npm run dev && tap --only -R 'base'",
40
+ "esbuild": "node '../../scripts/esbuild.js'",
41
+ "esbuild_dev": "cross-env MODE=dev node '../../scripts/esbuild.js'",
38
42
  "format": "npm run lect && npm run prettier && npm run lint",
39
43
  "lect": "lect",
40
44
  "lint": "../../node_modules/eslint/bin/eslint.js . --ext .js --ext .ts --fix --config \"../../.eslintrc.json\" --quiet",
@@ -42,22 +46,22 @@
42
46
  "prettier": "../../node_modules/prettier/bin-prettier.js '*.{js,css,scss,vue,md,ts}' --write --loglevel silent",
43
47
  "republish": "npm publish || :",
44
48
  "tap": "tap",
45
- "tsc": "tsc",
46
49
  "pretest": "npm run build",
47
50
  "test": "npm run lint && npm run unittest && npm run test:examples && npm run clean_cov && npm run format",
48
51
  "test:examples": "../../scripts/test-examples.js && npm run lect && npm run prettier",
49
- "unittest": "./node_modules/.bin/tap --no-only --output-file=testStats.md --reporter=terse && tsc -p tsconfig.json --noEmit && npm run clean_cov && npm run perf",
50
- "clean_cov": "../../scripts/leaveCoverageTotalOnly.js",
51
- "clean_types": "../../scripts/cleanTypes.js"
52
+ "tsc": "tsc",
53
+ "unittest": "tap --no-only --output-file=testStats.md --reporter=terse && tsc -p tsconfig.json --noEmit && npm run clean_cov && npm run perf"
52
54
  },
53
55
  "tap": {
56
+ "check-coverage": false,
54
57
  "coverage-report": [
55
58
  "json-summary",
56
59
  "text"
57
60
  ],
58
- "nyc-arg": [
59
- "--exclude=**/*.cjs.js",
60
- "--exclude=**/*.umd.js"
61
+ "node-arg": [
62
+ "--no-warnings",
63
+ "--experimental-loader",
64
+ "@istanbuljs/esm-loader-hook"
61
65
  ],
62
66
  "timeout": 0
63
67
  },
@@ -75,46 +79,50 @@
75
79
  }
76
80
  },
77
81
  "dependencies": {
78
- "@babel/runtime": "^7.14.0",
79
- "arrayiffy-if-string": "^3.14.0",
82
+ "@babel/runtime": "^7.16.0",
83
+ "arrayiffy-if-string": "^4.0.3",
80
84
  "lodash.isplainobject": "^4.0.6",
81
- "string-character-is-astral-surrogate": "^1.13.0"
85
+ "string-character-is-astral-surrogate": "^2.0.3"
82
86
  },
83
87
  "devDependencies": {
84
- "@babel/cli": "^7.14.3",
85
- "@babel/core": "^7.14.3",
86
- "@babel/node": "^7.14.2",
87
- "@babel/plugin-external-helpers": "^7.12.13",
88
- "@babel/plugin-proposal-class-properties": "^7.13.0",
89
- "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.2",
90
- "@babel/plugin-proposal-object-rest-spread": "^7.14.2",
91
- "@babel/plugin-proposal-optional-chaining": "^7.14.2",
92
- "@babel/plugin-transform-runtime": "^7.14.3",
93
- "@babel/preset-env": "^7.14.2",
94
- "@babel/preset-typescript": "^7.13.0",
95
- "@babel/register": "^7.13.16",
88
+ "@babel/cli": "^7.16.0",
89
+ "@babel/core": "^7.16.0",
90
+ "@babel/node": "^7.16.0",
91
+ "@babel/plugin-external-helpers": "^7.16.0",
92
+ "@babel/plugin-proposal-class-properties": "^7.16.0",
93
+ "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0",
94
+ "@babel/plugin-proposal-object-rest-spread": "^7.16.0",
95
+ "@babel/plugin-proposal-optional-chaining": "^7.16.0",
96
+ "@babel/plugin-transform-runtime": "^7.16.0",
97
+ "@babel/preset-env": "^7.16.0",
98
+ "@babel/preset-typescript": "^7.16.0",
99
+ "@babel/register": "^7.16.0",
100
+ "@istanbuljs/esm-loader-hook": "^0.1.2",
96
101
  "@rollup/plugin-babel": "^5.3.0",
97
- "@rollup/plugin-commonjs": "^19.0.0",
98
- "@rollup/plugin-node-resolve": "^13.0.0",
99
- "@rollup/plugin-strip": "^2.0.1",
100
- "@rollup/plugin-typescript": "^8.2.1",
102
+ "@rollup/plugin-commonjs": "^21.0.1",
103
+ "@rollup/plugin-node-resolve": "^13.0.6",
104
+ "@rollup/plugin-strip": "^2.1.0",
105
+ "@rollup/plugin-typescript": "^8.3.0",
101
106
  "@types/lodash.isplainobject": "^4.0.6",
102
- "@types/node": "^15.6.0",
103
- "@types/tap": "^15.0.1",
104
- "@typescript-eslint/eslint-plugin": "^4.24.0",
105
- "@typescript-eslint/parser": "^4.24.0",
106
- "core-js": "^3.12.1",
107
+ "@types/node": "^16.11.6",
108
+ "@types/tap": "^15.0.5",
109
+ "@typescript-eslint/eslint-plugin": "^5.2.0",
110
+ "@typescript-eslint/parser": "^5.2.0",
111
+ "core-js": "^3.19.0",
107
112
  "cross-env": "^7.0.3",
108
- "eslint": "^7.27.0",
109
- "lect": "^0.17.0",
110
- "rollup": "^2.49.0",
113
+ "eslint": "^8.1.0",
114
+ "lect": "^0.18.3",
115
+ "rollup": "^2.59.0",
111
116
  "rollup-plugin-ascii": "^0.0.3",
112
117
  "rollup-plugin-banner": "^0.2.1",
113
118
  "rollup-plugin-cleanup": "^3.2.1",
114
- "rollup-plugin-dts": "^3.0.1",
119
+ "rollup-plugin-dts": "^4.0.0",
115
120
  "rollup-plugin-terser": "^7.0.2",
116
- "tap": "^14.11.0",
117
- "tslib": "^2.2.0",
118
- "typescript": "^4.2.4"
121
+ "tap": "^15.0.10",
122
+ "tslib": "^2.3.1",
123
+ "typescript": "^4.4.4"
124
+ },
125
+ "engines": {
126
+ "node": ">=12"
119
127
  }
120
128
  }
@@ -1,325 +0,0 @@
1
- /**
2
- * @name string-match-left-right
3
- * @fileoverview Match substrings on the left or right of a given index, ignoring whitespace
4
- * @version 7.1.0
5
- * @author Roy Revelt, Codsen Ltd
6
- * @license MIT
7
- * {@link https://codsen.com/os/string-match-left-right/}
8
- */
9
-
10
- 'use strict';
11
-
12
- Object.defineProperty(exports, '__esModule', { value: true });
13
-
14
- var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
15
- var _typeof = require('@babel/runtime/helpers/typeof');
16
- var arrayiffyIfString = require('arrayiffy-if-string');
17
-
18
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
19
-
20
- var _objectSpread__default = /*#__PURE__*/_interopDefaultLegacy(_objectSpread);
21
- var _typeof__default = /*#__PURE__*/_interopDefaultLegacy(_typeof);
22
-
23
- function isObj(something) {
24
- return something && _typeof__default['default'](something) === "object" && !Array.isArray(something);
25
- }
26
- function isStr(something) {
27
- return typeof something === "string";
28
- }
29
- var defaults = {
30
- cb: undefined,
31
- i: false,
32
- trimBeforeMatching: false,
33
- trimCharsBeforeMatching: [],
34
- maxMismatches: 0,
35
- firstMustMatch: false,
36
- lastMustMatch: false,
37
- hungry: false
38
- };
39
- var defaultGetNextIdx = function defaultGetNextIdx(index) {
40
- return index + 1;
41
- };
42
- function march(str, position, whatToMatchVal, originalOpts) {
43
- var special = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
44
- var getNextIdx = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : defaultGetNextIdx;
45
- var whatToMatchValVal = typeof whatToMatchVal === "function" ? whatToMatchVal() : whatToMatchVal;
46
- if (+position < 0 && special && whatToMatchValVal === "EOL") {
47
- return whatToMatchValVal;
48
- }
49
- var opts = _objectSpread__default['default'](_objectSpread__default['default']({}, defaults), originalOpts);
50
- if (position >= str.length && !special) {
51
- return false;
52
- }
53
- var charsToCheckCount = special ? 1 : whatToMatchVal.length;
54
- var charsMatchedTotal = 0;
55
- var patienceReducedBeforeFirstMatch = false;
56
- var lastWasMismatched = false;
57
- var atLeastSomethingWasMatched = false;
58
- var patience = opts.maxMismatches;
59
- var i = position;
60
- var somethingFound = false;
61
- var firstCharacterMatched = false;
62
- var lastCharacterMatched = false;
63
- function whitespaceInFrontOfFirstChar() {
64
- return (
65
- charsMatchedTotal === 1 &&
66
- patience < opts.maxMismatches - 1
67
- );
68
- }
69
- while (str[i]) {
70
- var nextIdx = getNextIdx(i);
71
- if (opts.trimBeforeMatching && str[i].trim() === "") {
72
- if (!str[nextIdx] && special && whatToMatchVal === "EOL") {
73
- return true;
74
- }
75
- i = getNextIdx(i);
76
- continue;
77
- }
78
- if (opts && !opts.i && opts.trimCharsBeforeMatching && opts.trimCharsBeforeMatching.includes(str[i]) || opts && opts.i && opts.trimCharsBeforeMatching && opts.trimCharsBeforeMatching.map(function (val) {
79
- return val.toLowerCase();
80
- }).includes(str[i].toLowerCase())) {
81
- if (special && whatToMatchVal === "EOL" && !str[nextIdx]) {
82
- return true;
83
- }
84
- i = getNextIdx(i);
85
- continue;
86
- }
87
- var charToCompareAgainst = nextIdx > i ? whatToMatchVal[whatToMatchVal.length - charsToCheckCount] : whatToMatchVal[charsToCheckCount - 1];
88
- if (!opts.i && str[i] === charToCompareAgainst || opts.i && str[i].toLowerCase() === charToCompareAgainst.toLowerCase()) {
89
- if (!somethingFound) {
90
- somethingFound = true;
91
- }
92
- if (!atLeastSomethingWasMatched) {
93
- atLeastSomethingWasMatched = true;
94
- }
95
- if (charsToCheckCount === whatToMatchVal.length) {
96
- firstCharacterMatched = true;
97
- if (patience !== opts.maxMismatches) {
98
- return false;
99
- }
100
- } else if (charsToCheckCount === 1) {
101
- lastCharacterMatched = true;
102
- }
103
- charsToCheckCount -= 1;
104
- charsMatchedTotal++;
105
- if (whitespaceInFrontOfFirstChar()) {
106
- return false;
107
- }
108
- if (!charsToCheckCount) {
109
- return (
110
- charsMatchedTotal !== whatToMatchVal.length ||
111
- patience === opts.maxMismatches ||
112
- !patienceReducedBeforeFirstMatch ? i : false
113
- );
114
- }
115
- } else {
116
- if (!patienceReducedBeforeFirstMatch && !charsMatchedTotal) {
117
- patienceReducedBeforeFirstMatch = true;
118
- }
119
- if (opts.maxMismatches && patience && i) {
120
- patience -= 1;
121
- for (var y = 0; y <= patience; y++) {
122
- var nextCharToCompareAgainst = nextIdx > i ? whatToMatchVal[whatToMatchVal.length - charsToCheckCount + 1 + y] : whatToMatchVal[charsToCheckCount - 2 - y];
123
- var nextCharInSource = str[getNextIdx(i)];
124
- if (nextCharToCompareAgainst && (!opts.i && str[i] === nextCharToCompareAgainst || opts.i && str[i].toLowerCase() === nextCharToCompareAgainst.toLowerCase()) && (
125
- !opts.firstMustMatch || charsToCheckCount !== whatToMatchVal.length)) {
126
- charsMatchedTotal++;
127
- if (whitespaceInFrontOfFirstChar()) {
128
- return false;
129
- }
130
- charsToCheckCount -= 2;
131
- somethingFound = true;
132
- break;
133
- } else if (nextCharInSource && nextCharToCompareAgainst && (!opts.i && nextCharInSource === nextCharToCompareAgainst || opts.i && nextCharInSource.toLowerCase() === nextCharToCompareAgainst.toLowerCase()) && (
134
- !opts.firstMustMatch || charsToCheckCount !== whatToMatchVal.length)) {
135
- if (!charsMatchedTotal && !opts.hungry) {
136
- return false;
137
- }
138
- charsToCheckCount -= 1;
139
- somethingFound = true;
140
- break;
141
- } else if (nextCharToCompareAgainst === undefined && patience >= 0 && somethingFound && (!opts.firstMustMatch || firstCharacterMatched) && (!opts.lastMustMatch || lastCharacterMatched)) {
142
- return i;
143
- }
144
- }
145
- if (!somethingFound) {
146
- lastWasMismatched = i;
147
- }
148
- } else if (i === 0 && charsToCheckCount === 1 && !opts.lastMustMatch && atLeastSomethingWasMatched) {
149
- return 0;
150
- } else {
151
- return false;
152
- }
153
- }
154
- if (lastWasMismatched !== false && lastWasMismatched !== i) {
155
- lastWasMismatched = false;
156
- }
157
- if (charsToCheckCount < 1) {
158
- return i;
159
- }
160
- i = getNextIdx(i);
161
- }
162
- if (charsToCheckCount > 0) {
163
- if (special && whatToMatchValVal === "EOL") {
164
- return true;
165
- }
166
- if (opts && opts.maxMismatches >= charsToCheckCount && atLeastSomethingWasMatched) {
167
- return lastWasMismatched || 0;
168
- }
169
- return false;
170
- }
171
- }
172
- function main(mode, str, position, originalWhatToMatch, originalOpts) {
173
- if (isObj(originalOpts) && Object.prototype.hasOwnProperty.call(originalOpts, "trimBeforeMatching") && typeof originalOpts.trimBeforeMatching !== "boolean") {
174
- throw new Error("string-match-left-right/".concat(mode, "(): [THROW_ID_09] opts.trimBeforeMatching should be boolean!").concat(Array.isArray(originalOpts.trimBeforeMatching) ? " Did you mean to use opts.trimCharsBeforeMatching?" : ""));
175
- }
176
- var opts = _objectSpread__default['default'](_objectSpread__default['default']({}, defaults), originalOpts);
177
- if (typeof opts.trimCharsBeforeMatching === "string") {
178
- opts.trimCharsBeforeMatching = arrayiffyIfString.arrayiffy(opts.trimCharsBeforeMatching);
179
- }
180
- opts.trimCharsBeforeMatching = opts.trimCharsBeforeMatching.map(function (el) {
181
- return isStr(el) ? el : String(el);
182
- });
183
- if (!isStr(str)) {
184
- return false;
185
- }
186
- if (!str.length) {
187
- return false;
188
- }
189
- if (!Number.isInteger(position) || position < 0) {
190
- throw new Error("string-match-left-right/".concat(mode, "(): [THROW_ID_03] the second argument should be a natural number. Currently it's of a type: ").concat(_typeof__default['default'](position), ", equal to:\n").concat(JSON.stringify(position, null, 4)));
191
- }
192
- var whatToMatch;
193
- var special;
194
- if (isStr(originalWhatToMatch)) {
195
- whatToMatch = [originalWhatToMatch];
196
- } else if (Array.isArray(originalWhatToMatch)) {
197
- whatToMatch = originalWhatToMatch;
198
- } else if (!originalWhatToMatch) {
199
- whatToMatch = originalWhatToMatch;
200
- } else if (typeof originalWhatToMatch === "function") {
201
- whatToMatch = [];
202
- whatToMatch.push(originalWhatToMatch);
203
- } else {
204
- throw new Error("string-match-left-right/".concat(mode, "(): [THROW_ID_05] the third argument, whatToMatch, is neither string nor array of strings! It's ").concat(_typeof__default['default'](originalWhatToMatch), ", equal to:\n").concat(JSON.stringify(originalWhatToMatch, null, 4)));
205
- }
206
- if (originalOpts && !isObj(originalOpts)) {
207
- throw new Error("string-match-left-right/".concat(mode, "(): [THROW_ID_06] the fourth argument, options object, should be a plain object. Currently it's of a type \"").concat(_typeof__default['default'](originalOpts), "\", and equal to:\n").concat(JSON.stringify(originalOpts, null, 4)));
208
- }
209
- var culpritsIndex = 0;
210
- var culpritsVal = "";
211
- if (opts && opts.trimCharsBeforeMatching && opts.trimCharsBeforeMatching.some(function (el, i) {
212
- if (el.length > 1) {
213
- culpritsIndex = i;
214
- culpritsVal = el;
215
- return true;
216
- }
217
- return false;
218
- })) {
219
- throw new Error("string-match-left-right/".concat(mode, "(): [THROW_ID_07] the fourth argument, options object contains trimCharsBeforeMatching. It was meant to list the single characters but one of the entries at index ").concat(culpritsIndex, " is longer than 1 character, ").concat(culpritsVal.length, " (equals to ").concat(culpritsVal, "). Please split it into separate characters and put into array as separate elements."));
220
- }
221
- if (!whatToMatch || !Array.isArray(whatToMatch) ||
222
- Array.isArray(whatToMatch) && !whatToMatch.length ||
223
- Array.isArray(whatToMatch) && whatToMatch.length === 1 && isStr(whatToMatch[0]) && !whatToMatch[0].trim()
224
- ) {
225
- if (typeof opts.cb === "function") {
226
- var firstCharOutsideIndex;
227
- var startingPosition = position;
228
- if (mode === "matchLeftIncl" || mode === "matchRight") {
229
- startingPosition += 1;
230
- }
231
- if (mode[5] === "L") {
232
- for (var y = startingPosition; y--;) {
233
- var currentChar = str[y];
234
- if ((!opts.trimBeforeMatching || opts.trimBeforeMatching && currentChar !== undefined && currentChar.trim()) && (!opts.trimCharsBeforeMatching || !opts.trimCharsBeforeMatching.length || currentChar !== undefined && !opts.trimCharsBeforeMatching.includes(currentChar))) {
235
- firstCharOutsideIndex = y;
236
- break;
237
- }
238
- }
239
- } else if (mode.startsWith("matchRight")) {
240
- for (var _y = startingPosition; _y < str.length; _y++) {
241
- var _currentChar = str[_y];
242
- if ((!opts.trimBeforeMatching || opts.trimBeforeMatching && _currentChar.trim()) && (!opts.trimCharsBeforeMatching || !opts.trimCharsBeforeMatching.length || !opts.trimCharsBeforeMatching.includes(_currentChar))) {
243
- firstCharOutsideIndex = _y;
244
- break;
245
- }
246
- }
247
- }
248
- if (firstCharOutsideIndex === undefined) {
249
- return false;
250
- }
251
- var wholeCharacterOutside = str[firstCharOutsideIndex];
252
- var indexOfTheCharacterAfter = firstCharOutsideIndex + 1;
253
- var theRemainderOfTheString = "";
254
- if (indexOfTheCharacterAfter && indexOfTheCharacterAfter > 0) {
255
- theRemainderOfTheString = str.slice(0, indexOfTheCharacterAfter);
256
- }
257
- if (mode[5] === "L") {
258
- return opts.cb(wholeCharacterOutside, theRemainderOfTheString, firstCharOutsideIndex);
259
- }
260
- if (firstCharOutsideIndex && firstCharOutsideIndex > 0) {
261
- theRemainderOfTheString = str.slice(firstCharOutsideIndex);
262
- }
263
- return opts.cb(wholeCharacterOutside, theRemainderOfTheString, firstCharOutsideIndex);
264
- }
265
- var extraNote = "";
266
- if (!originalOpts) {
267
- extraNote = " More so, the whole options object, the fourth input argument, is missing!";
268
- }
269
- throw new Error("string-match-left-right/".concat(mode, "(): [THROW_ID_08] the third argument, \"whatToMatch\", was given as an empty string. This means, you intend to match purely by a callback. The callback was not set though, the opts key \"cb\" is not set!").concat(extraNote));
270
- }
271
- for (var i = 0, len = whatToMatch.length; i < len; i++) {
272
- special = typeof whatToMatch[i] === "function";
273
- var whatToMatchVal = whatToMatch[i];
274
- var fullCharacterInFront = void 0;
275
- var indexOfTheCharacterInFront = void 0;
276
- var restOfStringInFront = "";
277
- var _startingPosition = position;
278
- if (mode === "matchRight") {
279
- _startingPosition += 1;
280
- } else if (mode === "matchLeft") {
281
- _startingPosition -= 1;
282
- }
283
- var found = march(str, _startingPosition, whatToMatchVal, opts, special, function (i2) {
284
- return mode[5] === "L" ? i2 - 1 : i2 + 1;
285
- });
286
- if (found && special && typeof whatToMatchVal === "function" && whatToMatchVal() === "EOL") {
287
- return whatToMatchVal() && (opts.cb ? opts.cb(fullCharacterInFront, restOfStringInFront, indexOfTheCharacterInFront) : true) ? whatToMatchVal() : false;
288
- }
289
- if (Number.isInteger(found)) {
290
- indexOfTheCharacterInFront = mode.startsWith("matchLeft") ? found - 1 : found + 1;
291
- if (mode[5] === "L") {
292
- restOfStringInFront = str.slice(0, found);
293
- } else {
294
- restOfStringInFront = str.slice(indexOfTheCharacterInFront);
295
- }
296
- }
297
- if (indexOfTheCharacterInFront < 0) {
298
- indexOfTheCharacterInFront = undefined;
299
- }
300
- if (str[indexOfTheCharacterInFront]) {
301
- fullCharacterInFront = str[indexOfTheCharacterInFront];
302
- }
303
- if (Number.isInteger(found) && (opts.cb ? opts.cb(fullCharacterInFront, restOfStringInFront, indexOfTheCharacterInFront) : true)) {
304
- return whatToMatchVal;
305
- }
306
- }
307
- return false;
308
- }
309
- function matchLeftIncl(str, position, whatToMatch, opts) {
310
- return main("matchLeftIncl", str, position, whatToMatch, opts);
311
- }
312
- function matchLeft(str, position, whatToMatch, opts) {
313
- return main("matchLeft", str, position, whatToMatch, opts);
314
- }
315
- function matchRightIncl(str, position, whatToMatch, opts) {
316
- return main("matchRightIncl", str, position, whatToMatch, opts);
317
- }
318
- function matchRight(str, position, whatToMatch, opts) {
319
- return main("matchRight", str, position, whatToMatch, opts);
320
- }
321
-
322
- exports.matchLeft = matchLeft;
323
- exports.matchLeftIncl = matchLeftIncl;
324
- exports.matchRight = matchRight;
325
- exports.matchRightIncl = matchRightIncl;
@@ -1,558 +0,0 @@
1
- /**
2
- * @name string-match-left-right
3
- * @fileoverview Match substrings on the left or right of a given index, ignoring whitespace
4
- * @version 7.1.0
5
- * @author Roy Revelt, Codsen Ltd
6
- * @license MIT
7
- * {@link https://codsen.com/os/string-match-left-right/}
8
- */
9
-
10
- (function (global, factory) {
11
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
12
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
13
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.stringMatchLeftRight = {}));
14
- }(this, (function (exports) { 'use strict';
15
-
16
- /**
17
- * @name arrayiffy-if-string
18
- * @fileoverview Put non-empty strings into arrays, turn empty-ones into empty arrays. Bypass everything else.
19
- * @version 3.14.0
20
- * @author Roy Revelt, Codsen Ltd
21
- * @license MIT
22
- * {@link https://codsen.com/os/arrayiffy-if-string/}
23
- */
24
-
25
- function arrayiffy(something) {
26
- if (typeof something === "string") {
27
- if (something.length) {
28
- return [something];
29
- }
30
- return [];
31
- }
32
- return something;
33
- }
34
-
35
- /* eslint no-plusplus:0 */
36
- function isObj(something) {
37
- return (something && typeof something === "object" && !Array.isArray(something));
38
- }
39
- function isStr(something) {
40
- return typeof something === "string";
41
- }
42
- const defaults = {
43
- cb: undefined,
44
- i: false,
45
- trimBeforeMatching: false,
46
- trimCharsBeforeMatching: [],
47
- maxMismatches: 0,
48
- firstMustMatch: false,
49
- lastMustMatch: false,
50
- hungry: false,
51
- };
52
- const defaultGetNextIdx = (index) => index + 1;
53
- // eslint-disable-next-line consistent-return
54
- function march(str, position, whatToMatchVal, originalOpts, special = false, getNextIdx = defaultGetNextIdx) {
55
- const whatToMatchValVal = typeof whatToMatchVal === "function" ? whatToMatchVal() : whatToMatchVal;
56
- // early ending case if matching EOL being at 0-th index:
57
- if (+position < 0 && special && whatToMatchValVal === "EOL") {
58
- return whatToMatchValVal;
59
- }
60
- const opts = { ...defaults, ...originalOpts };
61
- if (position >= str.length && !special) {
62
- return false;
63
- }
64
- // The "charsToCheckCount" varies, it decreases with skipped characters,
65
- // as long as "maxMismatches" allows. It's not the count of how many
66
- // characters de-facto have been matched from the source.
67
- let charsToCheckCount = special ? 1 : whatToMatchVal.length;
68
- // this is the counter of real characters matched. It is not reduced
69
- // from the holes in matched. For example, if source is "abc" and
70
- // maxMismatches=1 and we have "ac", result of the match will be true,
71
- // the following var will be equal to 2, meaning we matched two
72
- // characters:
73
- let charsMatchedTotal = 0;
74
- // used to catch frontal false positives, where too-eager matching
75
- // depletes the mismatches allowance before precisely matching the exact
76
- // string that follows, yielding too early false-positive start
77
- let patienceReducedBeforeFirstMatch = false;
78
- let lastWasMismatched = false; // value is "false" or index of where it was activated
79
- // if no character was ever matched, even through if opts.maxMismatches
80
- // would otherwise allow to skip characters, this will act as a last
81
- // insurance - at least one character must have been matched to yield a
82
- // positive result!
83
- let atLeastSomethingWasMatched = false;
84
- let patience = opts.maxMismatches;
85
- let i = position;
86
- // internal-use flag, not the same as "atLeastSomethingWasMatched":
87
- let somethingFound = false;
88
- // these two drive opts.firstMustMatch and opts.lastMustMatch:
89
- let firstCharacterMatched = false;
90
- let lastCharacterMatched = false;
91
- // bail early if there's whitespace in front, imagine:
92
- // abc important}
93
- // ^
94
- // start, match ["!important"], matchRightIncl()
95
- //
96
- // in case above, "c" consumed 1 patience, let's say 1 is left,
97
- // we stumble upon "i" where "!" is missing. "c" is false start.
98
- function whitespaceInFrontOfFirstChar() {
99
- return (
100
- // it's a first letter match
101
- charsMatchedTotal === 1 &&
102
- // and character in front exists
103
- // str[i - 1] &&
104
- // and it's whitespace
105
- // !str[i - 1].trim() &&
106
- // some patience has been consumed already
107
- patience < opts.maxMismatches - 1);
108
- }
109
- while (str[i]) {
110
- const nextIdx = getNextIdx(i);
111
- if (opts.trimBeforeMatching && str[i].trim() === "") {
112
- if (!str[nextIdx] && special && whatToMatchVal === "EOL") {
113
- return true;
114
- }
115
- i = getNextIdx(i);
116
- continue;
117
- }
118
- if ((opts &&
119
- !opts.i &&
120
- opts.trimCharsBeforeMatching &&
121
- opts.trimCharsBeforeMatching.includes(str[i])) ||
122
- (opts &&
123
- opts.i &&
124
- opts.trimCharsBeforeMatching &&
125
- opts.trimCharsBeforeMatching
126
- .map((val) => val.toLowerCase())
127
- .includes(str[i].toLowerCase()))) {
128
- if (special && whatToMatchVal === "EOL" && !str[nextIdx]) {
129
- // return true because we reached the zero'th index, exactly what we're looking for
130
- return true;
131
- }
132
- i = getNextIdx(i);
133
- continue;
134
- }
135
- const charToCompareAgainst = nextIdx > i
136
- ? whatToMatchVal[whatToMatchVal.length - charsToCheckCount]
137
- : whatToMatchVal[charsToCheckCount - 1];
138
- // let's match
139
- if ((!opts.i && str[i] === charToCompareAgainst) ||
140
- (opts.i && str[i].toLowerCase() === charToCompareAgainst.toLowerCase())) {
141
- if (!somethingFound) {
142
- somethingFound = true;
143
- }
144
- if (!atLeastSomethingWasMatched) {
145
- atLeastSomethingWasMatched = true;
146
- }
147
- // if this was the first character from the "to-match" list, flip the flag
148
- if (charsToCheckCount === whatToMatchVal.length) {
149
- firstCharacterMatched = true;
150
- // now, if the first character was matched and yet, patience was
151
- // reduced already, this means there's a false beginning in front
152
- if (patience !== opts.maxMismatches) {
153
- return false;
154
- }
155
- }
156
- else if (charsToCheckCount === 1) {
157
- lastCharacterMatched = true;
158
- }
159
- charsToCheckCount -= 1;
160
- charsMatchedTotal++;
161
- // bail early if there's whitespace in front, imagine:
162
- // abc important}
163
- // ^
164
- // start, match ["!important"], matchRightIncl()
165
- //
166
- // in case above, "c" consumed 1 patience, let's say 1 is left,
167
- // we stumble upon "i" where "!" is missing. "c" is false start.
168
- if (whitespaceInFrontOfFirstChar()) {
169
- return false;
170
- }
171
- if (!charsToCheckCount) {
172
- return (
173
- // either it was not a perfect match
174
- charsMatchedTotal !== whatToMatchVal.length ||
175
- // or it was, and in that case, no patience was reduced
176
- // (if a perfect match was found, yet some "patience" was reduced,
177
- // that means we have false positive characters)
178
- patience === opts.maxMismatches ||
179
- // mind you, it can be a case of rogue characters in-between
180
- // the what was matched, imagine:
181
- // source: "abxcd", matching ["bc"], maxMismatches=1
182
- // in above case, charsMatchedTotal === 2 and whatToMatchVal ("bc") === 2
183
- // - we want to exclude cases of frontal false positives, like:
184
- // source: "xy abc", match "abc", maxMismatches=2, start at 0
185
- // ^
186
- // match form here to the right
187
- !patienceReducedBeforeFirstMatch
188
- ? i
189
- : false);
190
- }
191
- }
192
- else {
193
- if (!patienceReducedBeforeFirstMatch && !charsMatchedTotal) {
194
- patienceReducedBeforeFirstMatch = true;
195
- }
196
- if (opts.maxMismatches && patience && i) {
197
- patience -= 1;
198
- // the bigger the maxMismatches, the further away we must check for
199
- // alternative matches
200
- for (let y = 0; y <= patience; y++) {
201
- // maybe str[i] will match against next charToCompareAgainst?
202
- const nextCharToCompareAgainst = nextIdx > i
203
- ? whatToMatchVal[whatToMatchVal.length - charsToCheckCount + 1 + y]
204
- : whatToMatchVal[charsToCheckCount - 2 - y];
205
- const nextCharInSource = str[getNextIdx(i)];
206
- if (nextCharToCompareAgainst &&
207
- ((!opts.i && str[i] === nextCharToCompareAgainst) ||
208
- (opts.i &&
209
- str[i].toLowerCase() ===
210
- nextCharToCompareAgainst.toLowerCase())) &&
211
- // ensure we're not skipping the first enforced character:
212
- (!opts.firstMustMatch ||
213
- charsToCheckCount !== whatToMatchVal.length)) {
214
- charsMatchedTotal++;
215
- // bail early if there's whitespace in front, imagine:
216
- // abc important}
217
- // ^
218
- // start, match ["!important"], matchRightIncl()
219
- //
220
- // in case above, "c" consumed 1 patience, let's say 1 is left,
221
- // we stumble upon "i" where "!" is missing. "c" is false start.
222
- if (whitespaceInFrontOfFirstChar()) {
223
- return false;
224
- }
225
- charsToCheckCount -= 2;
226
- somethingFound = true;
227
- break;
228
- }
229
- else if (nextCharInSource &&
230
- nextCharToCompareAgainst &&
231
- ((!opts.i && nextCharInSource === nextCharToCompareAgainst) ||
232
- (opts.i &&
233
- nextCharInSource.toLowerCase() ===
234
- nextCharToCompareAgainst.toLowerCase())) &&
235
- // ensure we're not skipping the first enforced character:
236
- (!opts.firstMustMatch ||
237
- charsToCheckCount !== whatToMatchVal.length)) {
238
- if (!charsMatchedTotal && !opts.hungry) {
239
- return false;
240
- }
241
- charsToCheckCount -= 1;
242
- somethingFound = true;
243
- break;
244
- }
245
- else if (nextCharToCompareAgainst === undefined &&
246
- patience >= 0 &&
247
- somethingFound &&
248
- (!opts.firstMustMatch || firstCharacterMatched) &&
249
- (!opts.lastMustMatch || lastCharacterMatched)) {
250
- // If "nextCharToCompareAgainst" is undefined, this
251
- // means there are no more characters left to match,
252
- // this is the last character to be matched.
253
- // This means, if patience >= 0, this is it,
254
- // the match is still positive.
255
- return i;
256
- }
257
- // ███████████████████████████████████████
258
- }
259
- if (!somethingFound) {
260
- // if the character was rogue, we mark it:
261
- lastWasMismatched = i;
262
- // patience--;
263
- // console.log(
264
- // `350 ${`\u001b[${32}m${`SET`}\u001b[${39}m`} ${`\u001b[${33}m${`patience`}\u001b[${39}m`} = ${patience}`
265
- // );
266
- }
267
- }
268
- else if (i === 0 &&
269
- charsToCheckCount === 1 &&
270
- !opts.lastMustMatch &&
271
- atLeastSomethingWasMatched) {
272
- return 0;
273
- }
274
- else {
275
- return false;
276
- }
277
- }
278
- // turn off "lastWasMismatched" if it's on and it hasn't been activated
279
- // on this current index:
280
- if (lastWasMismatched !== false && lastWasMismatched !== i) {
281
- lastWasMismatched = false;
282
- }
283
- // if all was matched, happy days
284
- if (charsToCheckCount < 1) {
285
- return i;
286
- }
287
- // iterate onto the next index, otherwise while would loop infinitely
288
- i = getNextIdx(i);
289
- }
290
- if (charsToCheckCount > 0) {
291
- if (special && whatToMatchValVal === "EOL") {
292
- return true;
293
- }
294
- if (opts &&
295
- opts.maxMismatches >= charsToCheckCount &&
296
- atLeastSomethingWasMatched) {
297
- return lastWasMismatched || 0;
298
- }
299
- return false;
300
- }
301
- }
302
- //
303
- //
304
- //
305
- //
306
- //
307
- //
308
- //
309
- //
310
- //
311
- //
312
- //
313
- //
314
- //
315
- //
316
- //
317
- //
318
- //
319
- //
320
- //
321
- //
322
- //
323
- //
324
- //
325
- //
326
- //
327
- //
328
- //
329
- //
330
- //
331
- //
332
- //
333
- //
334
- //
335
- //
336
- //
337
- //
338
- // Real deal
339
- function main(mode, str, position, originalWhatToMatch, originalOpts) {
340
- // insurance
341
- if (isObj(originalOpts) &&
342
- Object.prototype.hasOwnProperty.call(originalOpts, "trimBeforeMatching") &&
343
- typeof originalOpts.trimBeforeMatching !== "boolean") {
344
- throw new Error(`string-match-left-right/${mode}(): [THROW_ID_09] opts.trimBeforeMatching should be boolean!${Array.isArray(originalOpts.trimBeforeMatching)
345
- ? ` Did you mean to use opts.trimCharsBeforeMatching?`
346
- : ""}`);
347
- }
348
- const opts = { ...defaults, ...originalOpts };
349
- if (typeof opts.trimCharsBeforeMatching === "string") {
350
- // arrayiffy if needed:
351
- opts.trimCharsBeforeMatching = arrayiffy(opts.trimCharsBeforeMatching);
352
- }
353
- // stringify all:
354
- opts.trimCharsBeforeMatching = opts.trimCharsBeforeMatching.map((el) => (isStr(el) ? el : String(el)));
355
- if (!isStr(str)) {
356
- return false;
357
- }
358
- if (!str.length) {
359
- return false;
360
- }
361
- if (!Number.isInteger(position) || position < 0) {
362
- throw new Error(`string-match-left-right/${mode}(): [THROW_ID_03] the second argument should be a natural number. Currently it's of a type: ${typeof position}, equal to:\n${JSON.stringify(position, null, 4)}`);
363
- }
364
- let whatToMatch;
365
- let special;
366
- if (isStr(originalWhatToMatch)) {
367
- whatToMatch = [originalWhatToMatch];
368
- }
369
- else if (Array.isArray(originalWhatToMatch)) {
370
- whatToMatch = originalWhatToMatch;
371
- }
372
- else if (!originalWhatToMatch) {
373
- whatToMatch = originalWhatToMatch;
374
- }
375
- else if (typeof originalWhatToMatch === "function") {
376
- whatToMatch = [];
377
- whatToMatch.push(originalWhatToMatch);
378
- }
379
- else {
380
- throw new Error(`string-match-left-right/${mode}(): [THROW_ID_05] the third argument, whatToMatch, is neither string nor array of strings! It's ${typeof originalWhatToMatch}, equal to:\n${JSON.stringify(originalWhatToMatch, null, 4)}`);
381
- }
382
- if (originalOpts && !isObj(originalOpts)) {
383
- throw new Error(`string-match-left-right/${mode}(): [THROW_ID_06] the fourth argument, options object, should be a plain object. Currently it's of a type "${typeof originalOpts}", and equal to:\n${JSON.stringify(originalOpts, null, 4)}`);
384
- }
385
- let culpritsIndex = 0;
386
- let culpritsVal = "";
387
- if (opts &&
388
- opts.trimCharsBeforeMatching &&
389
- opts.trimCharsBeforeMatching.some((el, i) => {
390
- if (el.length > 1) {
391
- culpritsIndex = i;
392
- culpritsVal = el;
393
- return true;
394
- }
395
- return false;
396
- })) {
397
- throw new Error(`string-match-left-right/${mode}(): [THROW_ID_07] the fourth argument, options object contains trimCharsBeforeMatching. It was meant to list the single characters but one of the entries at index ${culpritsIndex} is longer than 1 character, ${culpritsVal.length} (equals to ${culpritsVal}). Please split it into separate characters and put into array as separate elements.`);
398
- }
399
- // action
400
- // CASE 1. If it's driven by callback-only, the 3rd input argument, what to look
401
- // for - is falsey - empty string within array (or not), OR given null
402
- if (!whatToMatch ||
403
- !Array.isArray(whatToMatch) || // 0
404
- (Array.isArray(whatToMatch) && !whatToMatch.length) || // []
405
- (Array.isArray(whatToMatch) &&
406
- whatToMatch.length === 1 &&
407
- isStr(whatToMatch[0]) &&
408
- !whatToMatch[0].trim()) // [""]
409
- ) {
410
- if (typeof opts.cb === "function") {
411
- let firstCharOutsideIndex;
412
- // matchLeft() or matchRightIncl() methods start at index "position"
413
- let startingPosition = position;
414
- if (mode === "matchLeftIncl" || mode === "matchRight") {
415
- startingPosition += 1;
416
- }
417
- if (mode[5] === "L") {
418
- for (let y = startingPosition; y--;) {
419
- // assemble the value of the current character
420
- const currentChar = str[y];
421
- // do the actual evaluation, is the current character non-whitespace/non-skiped
422
- if ((!opts.trimBeforeMatching ||
423
- (opts.trimBeforeMatching &&
424
- currentChar !== undefined &&
425
- currentChar.trim())) &&
426
- (!opts.trimCharsBeforeMatching ||
427
- !opts.trimCharsBeforeMatching.length ||
428
- (currentChar !== undefined &&
429
- !opts.trimCharsBeforeMatching.includes(currentChar)))) {
430
- firstCharOutsideIndex = y;
431
- break;
432
- }
433
- }
434
- }
435
- else if (mode.startsWith("matchRight")) {
436
- for (let y = startingPosition; y < str.length; y++) {
437
- // assemble the value of the current character
438
- const currentChar = str[y];
439
- // do the actual evaluation, is the current character non-whitespace/non-skiped
440
- if ((!opts.trimBeforeMatching ||
441
- (opts.trimBeforeMatching && currentChar.trim())) &&
442
- (!opts.trimCharsBeforeMatching ||
443
- !opts.trimCharsBeforeMatching.length ||
444
- !opts.trimCharsBeforeMatching.includes(currentChar))) {
445
- firstCharOutsideIndex = y;
446
- break;
447
- }
448
- }
449
- }
450
- if (firstCharOutsideIndex === undefined) {
451
- return false;
452
- }
453
- const wholeCharacterOutside = str[firstCharOutsideIndex];
454
- const indexOfTheCharacterAfter = firstCharOutsideIndex + 1;
455
- let theRemainderOfTheString = "";
456
- if (indexOfTheCharacterAfter && indexOfTheCharacterAfter > 0) {
457
- theRemainderOfTheString = str.slice(0, indexOfTheCharacterAfter);
458
- }
459
- if (mode[5] === "L") {
460
- return opts.cb(wholeCharacterOutside, theRemainderOfTheString, firstCharOutsideIndex);
461
- }
462
- // ELSE matchRight & matchRightIncl
463
- if (firstCharOutsideIndex && firstCharOutsideIndex > 0) {
464
- theRemainderOfTheString = str.slice(firstCharOutsideIndex);
465
- }
466
- return opts.cb(wholeCharacterOutside, theRemainderOfTheString, firstCharOutsideIndex);
467
- }
468
- let extraNote = "";
469
- if (!originalOpts) {
470
- extraNote =
471
- " More so, the whole options object, the fourth input argument, is missing!";
472
- }
473
- throw new Error(`string-match-left-right/${mode}(): [THROW_ID_08] the third argument, "whatToMatch", was given as an empty string. This means, you intend to match purely by a callback. The callback was not set though, the opts key "cb" is not set!${extraNote}`);
474
- }
475
- // Case 2. Normal operation where callback may or may not be present, but it is
476
- // only accompanying the matching of what was given in 3rd input argument.
477
- // Then if 3rd arg's contents were matched, callback is checked and its Boolean
478
- // result is merged using logical "AND" - meaning both have to be true to yield
479
- // final result "true".
480
- for (let i = 0, len = whatToMatch.length; i < len; i++) {
481
- special = typeof whatToMatch[i] === "function";
482
- // since input can be function, we need to grab the value explicitly:
483
- const whatToMatchVal = whatToMatch[i];
484
- let fullCharacterInFront;
485
- let indexOfTheCharacterInFront;
486
- let restOfStringInFront = "";
487
- let startingPosition = position;
488
- if (mode === "matchRight") {
489
- startingPosition += 1;
490
- }
491
- else if (mode === "matchLeft") {
492
- startingPosition -= 1;
493
- }
494
- const found = march(str, startingPosition, whatToMatchVal, opts, special, (i2) => (mode[5] === "L" ? i2 - 1 : i2 + 1));
495
- // if march() returned positive result and it was "special" case,
496
- // Bob's your uncle, here's the result:
497
- if (found &&
498
- special &&
499
- typeof whatToMatchVal === "function" &&
500
- whatToMatchVal() === "EOL") {
501
- return whatToMatchVal() &&
502
- (opts.cb
503
- ? opts.cb(fullCharacterInFront, restOfStringInFront, indexOfTheCharacterInFront)
504
- : true)
505
- ? whatToMatchVal()
506
- : false;
507
- }
508
- // now, the "found" is the index of the first character of what was found.
509
- // we need to calculate the character to the left/right of it:
510
- if (Number.isInteger(found)) {
511
- indexOfTheCharacterInFront = mode.startsWith("matchLeft")
512
- ? found - 1
513
- : found + 1;
514
- //
515
- if (mode[5] === "L") {
516
- restOfStringInFront = str.slice(0, found);
517
- }
518
- else {
519
- restOfStringInFront = str.slice(indexOfTheCharacterInFront);
520
- }
521
- }
522
- if (indexOfTheCharacterInFront < 0) {
523
- indexOfTheCharacterInFront = undefined;
524
- }
525
- if (str[indexOfTheCharacterInFront]) {
526
- fullCharacterInFront = str[indexOfTheCharacterInFront];
527
- }
528
- if (Number.isInteger(found) &&
529
- (opts.cb
530
- ? opts.cb(fullCharacterInFront, restOfStringInFront, indexOfTheCharacterInFront)
531
- : true)) {
532
- return whatToMatchVal;
533
- }
534
- }
535
- return false;
536
- }
537
- // External API functions
538
- function matchLeftIncl(str, position, whatToMatch, opts) {
539
- return main("matchLeftIncl", str, position, whatToMatch, opts);
540
- }
541
- function matchLeft(str, position, whatToMatch, opts) {
542
- return main("matchLeft", str, position, whatToMatch, opts);
543
- }
544
- function matchRightIncl(str, position, whatToMatch, opts) {
545
- return main("matchRightIncl", str, position, whatToMatch, opts);
546
- }
547
- function matchRight(str, position, whatToMatch, opts) {
548
- return main("matchRight", str, position, whatToMatch, opts);
549
- }
550
-
551
- exports.matchLeft = matchLeft;
552
- exports.matchLeftIncl = matchLeftIncl;
553
- exports.matchRight = matchRight;
554
- exports.matchRightIncl = matchRightIncl;
555
-
556
- Object.defineProperty(exports, '__esModule', { value: true });
557
-
558
- })));