-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathsplitSmartBlockArgs.ts
More file actions
72 lines (69 loc) · 2.27 KB
/
splitSmartBlockArgs.ts
File metadata and controls
72 lines (69 loc) · 2.27 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
const MONTH_DAY_REGEX =
/^(?:jan(?:uary)?|feb(?:ruary)?|mar(?:ch)?|apr(?:il)?|may|jun(?:e)?|jul(?:y)?|aug(?:ust)?|sep(?:t(?:ember)?)?|oct(?:ober)?|nov(?:ember)?|dec(?:ember)?)\s+\d{1,2}(?:st|nd|rd|th)?$/i;
const YEAR_REGEX = /^\d{4}$/;
/**
* Re-joins "Month Day, Year" date tokens that were split on commas.
*
* BLOCKMENTIONSDATED signature: (limit, title, startDate, endDate, sort, format, ...search)
* Positions 0-1 (limit, title) are passed through unchanged.
* Starting at position 2, up to 2 date tokens are coalesced (startDate + endDate).
* The `mergedDates < 2` guard stops coalescing after both date slots are filled.
*/
const coalesceBlockMentionsDatedDates = (args: string[]) => {
const merged = args.slice(0, 2);
let i = 2;
let mergedDates = 0;
while (i < args.length) {
const current = args[i] || "";
const next = args[i + 1];
if (
mergedDates < 2 &&
typeof next === "string" &&
MONTH_DAY_REGEX.test(current.trim()) &&
YEAR_REGEX.test(next.trim())
) {
merged.push(`${current.trimEnd()}, ${next.trimStart()}`);
i += 2;
mergedDates += 1;
} else {
merged.push(current);
i += 1;
}
}
return merged;
};
const splitSmartBlockArgs = (cmd: string, afterColon: string) => {
let commandStack = 0;
let pageRefStack = 0;
const args = [] as string[];
for (let i = 0; i < afterColon.length; i += 1) {
const cur = afterColon[i];
const prev = afterColon[i - 1];
const next = afterColon[i + 1];
if (cur === "%" && prev === "<") {
commandStack += 1;
} else if (cur === "%" && next === ">" && commandStack) {
commandStack -= 1;
} else if (cur === "[" && next === "[") {
pageRefStack += 1;
} else if (cur === "]" && prev === "]" && pageRefStack) {
pageRefStack -= 1;
}
if (cur === "," && !commandStack && !pageRefStack && prev !== "\\") {
args.push("");
continue;
} else if (cur === "\\" && next === ",") {
continue;
}
const current = args[args.length - 1] || "";
if (!args.length) {
args.push(cur);
} else {
args[args.length - 1] = `${current}${cur}`;
}
}
return cmd.toUpperCase() === "BLOCKMENTIONSDATED"
? coalesceBlockMentionsDatedDates(args)
: args;
};
export default splitSmartBlockArgs;