Skip to content

Commit e947de8

Browse files
add proper name parser
1 parent 363b97c commit e947de8

File tree

1 file changed

+107
-7
lines changed

1 file changed

+107
-7
lines changed

scriptum.js

Lines changed: 107 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5530,12 +5530,11 @@ O.Get.any = (...getters) => o => k => {
55305530
███████████████████████████████████████████████████████████████████████████████*/
55315531

55325532

5533-
/* This isn't yet another parser implementation but a type that is meant to
5534-
replace ture/false validations suffering from boolean blindness. A parser takes
5535-
unstructured data and tries to add structre to it. It returns structured data
5536-
on success or the original data on error (or throws the error). Besides the
5537-
valid/invalid dichotomy the type also can represent a maybe valid value where
5538-
confidence quantifies the amount of indeterminism. */
5533+
/* The parser type is meant to replace ture/false validations suffering from
5534+
boolean blindness. A parser takes a value of a general type like string or
5535+
number and adds meta information on success or provides reason on failure. The
5536+
type can model a third state that represents a maybe successfully parsed value,
5537+
where confidence is quantified as a number between 0 and 1. */
55395538

55405539

55415540
export const Parser = {};
@@ -6593,7 +6592,7 @@ Parser.acronym = specialChars => s => {
65936592
if (rx.length < 2) {
65946593
return Parser.Invalid({
65956594
value: s,
6596-
reason: "less than 2 upper-case letters",
6595+
reason: "contains less than 2 upper-case letters",
65976596
kind: "acronym",
65986597
});
65996598
}
@@ -6610,6 +6609,107 @@ Parser.acronym = specialChars => s => {
66106609
Parser.acronym_ = Parser.acronym("&/");
66116610

66126611

6612+
// parse a proper name like Foo, Foo-Bar, O'Foo, McFoo
6613+
6614+
Parser.properName = prefixes => s => {
6615+
if (/[^\p{L}'\-]/v.test(s)) {
6616+
return Parser.Invalid({
6617+
value: s,
6618+
kind: "proper name",
6619+
reason: "contains invalid characters",
6620+
});
6621+
}
6622+
6623+
else if (!/\p{Lu}/v.test(s[0])) {
6624+
return Parser.Invalid({
6625+
value: s,
6626+
kind: "proper name",
6627+
reason: "first letter must be upper-case",
6628+
});
6629+
}
6630+
6631+
else if (S.countChar("-") (s) > 1) {
6632+
return Parser.Invalid({
6633+
value: s,
6634+
kind: "proper name",
6635+
reason: "contains more than one hyphen",
6636+
});
6637+
}
6638+
6639+
else if (S.countChar("'") (s) > 1) {
6640+
return Parser.Invalid({
6641+
value: s,
6642+
kind: "proper name",
6643+
reason: "contains more than one apostrophe",
6644+
});
6645+
}
6646+
6647+
else if (s.startsWith("-") || s.startsWith("'")) {
6648+
return Parser.Invalid({
6649+
value: s,
6650+
kind: "proper name",
6651+
reason: "special characters at the beginning",
6652+
});
6653+
}
6654+
6655+
else if (s.endsWith("-") || s.endsWith("'")) {
6656+
return Parser.Invalid({
6657+
value: s,
6658+
kind: "proper name",
6659+
reason: "special characters at the end",
6660+
});
6661+
}
6662+
6663+
for (let i = 1; i < s.length; i++) {
6664+
const c = s[i], prev = s[i - 1];
6665+
6666+
if (c === "-" || c === "'") continue;
6667+
6668+
else if (prev === "-" || prev === "'") {
6669+
if (/\p{Ll}/v.test(c)) {
6670+
return Parser.Invalid({
6671+
value: s,
6672+
kind: "proper name",
6673+
reason: "unexpected lower-case letter after special character",
6674+
});
6675+
}
6676+
}
6677+
6678+
else if (/\p{Lu}/v.test(c)) {
6679+
const sub = s.substring(0, i);
6680+
let match = false;
6681+
6682+
for (const prefix of prefixes) {
6683+
if (sub.endsWith(prefix)) {
6684+
match = true;
6685+
break;
6686+
}
6687+
}
6688+
6689+
if (match === false) return Parser.Invalid({
6690+
value: s,
6691+
kind: "proper name",
6692+
reason: "unexpected upper-case letter",
6693+
});
6694+
6695+
}
6696+
6697+
else if (!/\p{Ll}/v.test(c)) {
6698+
return Parser.Invalid({
6699+
value: s,
6700+
kind: "proper name",
6701+
reason: `letter expected at ${i + 1}`,
6702+
});
6703+
}
6704+
}
6705+
6706+
return Parser.Valid({
6707+
value: s,
6708+
kind: "proper name",
6709+
});
6710+
};
6711+
6712+
66136713
Parser.sentence = s => {
66146714
const last = s[s.length - 1];
66156715
let type = "";

0 commit comments

Comments
 (0)