forked from NovemLinguae/UserScripts
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStringFilter.js
More file actions
75 lines (73 loc) · 2.66 KB
/
Copy pathStringFilter.js
File metadata and controls
75 lines (73 loc) · 2.66 KB
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
/**
* Lets you use regex to specify what parts of a very long string you want to specify as "off limits", then you can do additional regex's and search/replace to the remaining parts of the string.
*/
export class StringFilter {
/**
* Does a replace, but specifies areas of the file that should NOT be replaced. Those areas are specified by providing an openingTag and a closingTag, and those areas are marked as off limits.
*/
surgicalReplaceOutsideTags(regex, replacement, haystack, openingTags, closingTags) {
let allTags = [...openingTags, ...closingTags];
let parts = this._splitStringUsingMultiplePatterns(haystack, allTags);
let resultArray = [];
for ( let part of parts ) {
let openingTagMatch = false;
for ( let tag of openingTags ) {
if ( part.startsWith(tag) ) {
openingTagMatch = true;
break;
}
}
if ( ! openingTagMatch ) {
part = part.replace(regex, replacement);
}
resultArray.push(part);
}
return resultArray.join('');
}
/**
* Does a replace, but specifies areas of the file that SHOULD be replaced, then skips the rest of the file. The area that should be replaced is specified by providing an openingTag and a closingTag.
*/
surgicalReplaceInsideTags(regex, replacement, haystack, openingTags, closingTags) {
let allTags = [...openingTags, ...closingTags];
let parts = this._splitStringUsingMultiplePatterns(haystack, allTags);
let resultArray = [];
for ( let part of parts ) {
for ( let tag of openingTags ) {
if ( part.startsWith(tag) ) {
part = part.replace(regex, replacement);
}
}
resultArray.push(part);
}
return resultArray.join('');
}
/**
* Also keeps the pattern in the result, unlike string.prototype.split. Algorithm isn't perfect, will fail with this pattern: <ref>Test/>Test</ref>. But should be good enough for DraftCleaner stuff.
* @param {string[]} patterns
* @returns {string[]}
*/
_splitStringUsingMultiplePatterns(string, patterns) {
let length = string.length;
let result = [];
let positionOfLastMatch = 0;
for ( let i = 0; i < length; i++ ) {
let lookAhead = string.substring(i); // the rest of the string after current position
let patternMatch = false;
for ( let pattern of patterns ) {
if ( lookAhead.startsWith(pattern) ) {
patternMatch = true;
break;
}
}
if ( patternMatch ) {
let chunk = string.slice(positionOfLastMatch, i);
if ( ! chunk ) continue; // if blank (happens if i=0 matches), continue instead of putting an empty "" into the array
result.push(chunk);
positionOfLastMatch = i;
}
}
// Don't forget the last chunk.
result.push(string.substring(positionOfLastMatch));
return result;
}
}