Skip to content

Commit c2037f9

Browse files
revise R.bound + add S.updateAt
1 parent 8c0c237 commit c2037f9

File tree

1 file changed

+91
-43
lines changed

1 file changed

+91
-43
lines changed

scriptum.js

Lines changed: 91 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7183,37 +7183,20 @@ R.sliceTo = search => s => {
71837183
classes like `[x-z]` or "\w" or even "ß" in a disjunctive manner. */
71847184

71857185

7186-
R.preBound = flags => (...classes) => {
7187-
const bound = "(?<=^|" + classes.join("|") + ")";
7188-
return R(bound, flags);
7189-
};
7190-
7191-
7192-
// default prefix bound
7186+
R.preBound = (...classes) => `(?<=^|${classes.join("|")})`;
71937187

7194-
R.preBound_ = R.preBound("v") ("[^\\p{L}]");
71957188

7189+
// default prefix bound (like "\b" but inlcuding special letters and excluding "_")
71967190

7197-
R.sufBound = flags => (...classes) => {
7198-
const bound = "(?=$|" + classes.join("|") + ")";
7199-
return R(bound, flags);
7200-
};
7201-
7191+
R.preBound_ = R.preBound("[^\\p{L}\\d]");
72027192

7203-
// default suffix bound
72047193

7205-
R.sufBound_ = R.sufBound("v") ("[^\\p{L}]");
7194+
R.sufBound = (...classes) => `(?=$|${classes.join("|")})`;
72067195

72077196

7208-
R.inBound = flags => (...classes) => {
7209-
const bound = "(?:" + classes.join("|") + ")";
7210-
return R(bound, flags);
7211-
};
7197+
// default suffix bound (like "\b" but inlcuding special letters and excluding "_")
72127198

7213-
7214-
// default infix bound
7215-
7216-
R.inBound_ = R.preBound("v") ("[^\\p{L}]");
7199+
R.sufBound_ = R.sufBound("[^\\p{L}\\d]");
72177200

72187201

72197202
//█████ Generalizing ██████████████████████████████████████████████████████████
@@ -9235,6 +9218,46 @@ S.countSubstr = t => s => {
92359218
//█████ Replacing █████████████████████████████████████████████████████████████
92369219

92379220

9221+
S.replaceAt = ({sub, is}) => s => {
9222+
const xs = s.split("");
9223+
for (let i = 0; i < is.length; i++) xs[is[i]] = sub;
9224+
return xs.join("");
9225+
};
9226+
9227+
9228+
S.replaceAtAccum = ({sub, is}) => s => {
9229+
const xs = [s];
9230+
9231+
for (let i = 0; i < is.length; i++) {
9232+
const ys = s.split("");
9233+
ys[is[i]] = sub;
9234+
xs.push(ys.join(""));
9235+
}
9236+
9237+
return xs;
9238+
};
9239+
9240+
9241+
S.updateAt = ({f, is}) => s => {
9242+
const xs = s.split("");
9243+
for (let i = 0; i < is.length; i++) xs[is[i]] = f(xs[is[i]]);
9244+
return xs.join("");
9245+
};
9246+
9247+
9248+
S.updateAtAccum = ({f, is}) => s => {
9249+
const xs = [s];
9250+
9251+
for (let i = 0; i < is.length; i++) {
9252+
const ys = s.split("");
9253+
ys[is[i]] = f(ys[is[i]]);
9254+
xs.push(ys.join(""));
9255+
}
9256+
9257+
return xs;
9258+
};
9259+
9260+
92389261
S.replaceChar = (c, sub) => s => {
92399262
let t = "";
92409263

@@ -9263,13 +9286,13 @@ S.replaceCharAccum = (c, sub) => s => {
92639286
};
92649287

92659288

9266-
S.replaceSub = (c, sub) => s => {
9289+
S.replaceSub = (sub, sub2) => s => {
92679290
let r = "", j = 0;
92689291

9269-
for (let i = s.indexOf(c, j); i !== -1; i = s.indexOf(c, j)) {
9292+
for (let i = s.indexOf(sub, j); i !== -1; i = s.indexOf(sub, j)) {
92709293
r += s.substring(j, i);
9271-
r += sub;
9272-
j = i + c.length;
9294+
r += sub2;
9295+
j = i + sub.length;
92739296
}
92749297

92759298
r += s.substring(j);
@@ -9361,12 +9384,12 @@ S.splitAscii = s => {
93619384
};
93629385

93639386

9364-
S.splitName = titles => s => {
9387+
S.splitName = (...titles) => s => {
93659388
const titles2 = [];
93669389

93679390
for (const title of titles) {
93689391
const rx = R.giv(
9369-
`${R.preBound_.source}${R.escape(title)}( |${R.sufBound_.source})`
9392+
`${R.preBound_}${R.escape(title)}( |${R.sufBound_})`
93709393
);
93719394

93729395
if (rx.test(s)) {
@@ -9422,7 +9445,7 @@ S.splitMergedWord = (...exceptions) => s => {
94229445

94239446
for (let i = 0; i < xs.length; i++) {
94249447
for (const exception of exceptions) {
9425-
if (R.v(`\\b${R.escape(exception)}$`).test(xs[i])) {
9448+
if (R.v(`${R.preBound_}${R.escape(exception)}$`).test(xs[i])) {
94269449
if (i < xs.length - 1) {
94279450
ys.push(xs[i] + xs[i + 1]);
94289451
i++;
@@ -11463,42 +11486,67 @@ S.Ctor.cmpWith = opt => (o, p) =>
1146311486
//█████ Casing ████████████████████████████████████████████████████████████████
1146411487

1146511488

11466-
// capitalize a word and its potential word components
11489+
// convert a word into title case form while considering word components
1146711490

11468-
S.capitalize = nouns => {
11469-
const lowercasedName = nouns.toLowerCase();
11491+
S.capitalize = (...exceptions) => word => {
11492+
const lcWord = word.toLowerCase();
1147011493

11471-
return lowercasedName.replace(/(^|[\s'-\.])(\w)/g, (match, separator, char) => {
11494+
const word2 = lcWord.replace(/(^|['-\.])(\w)/gu, (match, separator, char) => {
1147211495
return separator + char.toUpperCase();
1147311496
});
11497+
11498+
const is = exceptions.reduce((acc, exception) => {
11499+
const i = word2.search(R.v(`${R.preBound_}${exception}(?=\\p{L})`))
11500+
if (i === notFound) return acc;
11501+
else return A.push(i + exception.length) (acc);
11502+
}, []);
11503+
11504+
return is.reduce((acc, i) =>
11505+
S.updateAt({f: c => c.toUpperCase(), is: [i]}) (acc), word2);
11506+
};
11507+
11508+
11509+
// convert allcaps into title case form while considering word components
11510+
11511+
S.capitalizeAcronym = (...exceptions) => word => {
11512+
const casing = S.determineCasing(...exceptions) (word);
11513+
if (casing === "acronym") return S.capitalize(...exceptions);
11514+
else return word;
1147411515
};
1147511516

1147611517

1147711518
/* Possible casings:
1147811519
1147911520
• lower-case: foo
11480-
sentence-case: Foo
11521+
title-case: Foo
1148111522
• camel-case: fooBar or FooBar
1148211523
• acronym: FOO
1148311524
• arbitrary-case: FOOBar */
1148411525

11485-
S.determineCasing = word => {
11526+
S.determineCasing = (...exceptions) => word => {
1148611527
const lc = word.toLowerCase(),
11487-
uc = s.toUpperCase();
11528+
uc = word.toUpperCase();
1148811529

1148911530
if (lc === word) return "lower-case";
1149011531
else if (uc === word) return "acronym";
1149111532

1149211533
else {
11493-
const guess = "";
11534+
let guess = "";
1149411535

1149511536
for (let i = 0; i < word.length; i++) {
1149611537
if (lc[i] !== word[i]) {
11497-
if (i === 0) guess = "sentence-case";
11498-
else if (s[i - 1] === "-") continue;
11499-
else if (s[i - 1] === ".") continue;
11500-
else if (s[i - 1] === "'") continue;
11501-
else if (s[i - 1] === word[i - 1]) guess = "camel-case";
11538+
if (i === 0) guess = "title-case";
11539+
else if (word[i - 1] === "-") continue;
11540+
else if (word[i - 1] === ".") continue;
11541+
else if (word[i - 1] === "'") continue;
11542+
11543+
else if (lc[i - 1] === word[i - 1]) {
11544+
const isException = exceptions.some(exception =>
11545+
word.slice(i - 2).startsWith(exception));
11546+
11547+
if (isException) continue;
11548+
else guess = "camel-case";
11549+
}
1150211550

1150311551
else {
1150411552
guess = "arbitrary-case";

0 commit comments

Comments
 (0)