Skip to content

Commit 6817bf6

Browse files
committed
Category column format and filter
1 parent 450767d commit 6817bf6

File tree

2 files changed

+103
-44
lines changed

2 files changed

+103
-44
lines changed

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ See it in action: [unicodesearch.org](https://www.unicodesearch.org/)
2626

2727
## To Do
2828

29-
- [ ] numeric search for codepoints
30-
- [ ] codepoint sort should be numeric
29+
3130
- [ ] preview column (SVGs)
3231
- [ ] copy to clipboard button
3332
- [ ] test dark mode

src/index.ts

Lines changed: 102 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,106 @@ type SearchData = {
3232

3333
const dataUrl = "/ucd.json";
3434

35+
const categoryMap: { [key: string]: string } = {
36+
"Cc": "Other, Control",
37+
"Cf": "Other, Format",
38+
"Cn": "Other, Not Assigned (no characters in the file have this property)",
39+
"Co": "Other, Private Use",
40+
"Cs": "Other, Surrogate",
41+
"LC": "Letter, Cased",
42+
"Ll": "Letter, Lowercase",
43+
"Lm": "Letter, Modifier",
44+
"Lo": "Letter, Other",
45+
"Lt": "Letter, Titlecase",
46+
"Lu": "Letter, Uppercase",
47+
"Mc": "Mark, Spacing Combining",
48+
"Me": "Mark, Enclosing",
49+
"Mn": "Mark, Nonspacing",
50+
"Nd": "Number, Decimal Digit",
51+
"Nl": "Number, Letter",
52+
"No": "Number, Other",
53+
"Pc": "Punctuation, Connector",
54+
"Pd": "Punctuation, Dash",
55+
"Pe": "Punctuation, Close",
56+
"Pf": "Punctuation, Final quote (may behave like Ps or Pe depending on usage)",
57+
"Pi": "Punctuation, Initial quote (may behave like Ps or Pe depending on usage)",
58+
"Po": "Punctuation, Other",
59+
"Ps": "Punctuation, Open",
60+
"Sc": "Symbol, Currency",
61+
"Sk": "Symbol, Modifier",
62+
"Sm": "Symbol, Math",
63+
"So": "Symbol, Other",
64+
"Zl": "Separator, Line",
65+
"Zp": "Separator, Paragraph",
66+
"Zs": "Separator, Space"
67+
}
68+
69+
function filterCategory(
70+
headerValue: string,
71+
rowValue: string,
72+
rowData: any,
73+
filterParams: any
74+
) {
75+
if (!headerValue) return true;
76+
77+
const headerUpper = headerValue.toUpperCase();
78+
if (headerValue.length == 2) {
79+
return rowValue.toUpperCase() == headerUpper;
80+
}
81+
82+
const description = categoryMap[rowValue].toUpperCase();
83+
84+
return description.startsWith(headerUpper);
85+
}
86+
87+
function filterName(
88+
headerValue: string,
89+
sortValue: string,
90+
rowData: any,
91+
filterParams: any
92+
) {
93+
if (!headerValue) return true;
94+
95+
const rowValue = rowData.name;
96+
97+
if (headerValue.length == 1 && headerValue != "^" && headerValue != "/") {
98+
// single character, do starts with
99+
const search = headerValue.toLowerCase();
100+
return rowValue.toLowerCase().startsWith(search);
101+
}
102+
103+
if (headerValue.startsWith("^")) {
104+
// starts with
105+
if (headerValue.length == 1) {
106+
return true;
107+
}
108+
const search = headerValue.substring(1).toLowerCase();
109+
return rowValue.toLowerCase().startsWith(search);
110+
}
111+
112+
if (headerValue.startsWith("/") && headerValue.endsWith("/")) {
113+
// regex
114+
const pattern = headerValue.substring(1, headerValue.length - 1);
115+
try {
116+
const re = new RegExp(pattern, "i");
117+
return re.test(rowValue);
118+
} catch (e) {
119+
// bad regex
120+
return false;
121+
}
122+
}
123+
124+
// contains
125+
const search = headerValue.toLowerCase();
126+
return rowValue.toLowerCase().includes(search);
127+
}
128+
35129
function fmtCategory(cell: CellComponent) {
36130
const val = cell.getValue() as string;
131+
if (!val) {
132+
return "(missing)";
133+
}
134+
return categoryMap[val] || val;
37135
}
38136

39137
function fmtCodepoint(cell: CellComponent) {
@@ -156,47 +254,7 @@ function makeTagMap(row: any, socialmedia: SocialMedia[]): Map<string, string> {
156254
return tagMap;
157255
}
158256

159-
function nameFilter(
160-
headerValue: string,
161-
sortValue: string,
162-
rowData: any,
163-
filterParams: any
164-
) {
165-
if (!headerValue) return true;
166-
167-
const rowValue = rowData.name;
168-
169-
if (headerValue.length == 1 && headerValue != "^" && headerValue != "/") {
170-
// single character, do starts with
171-
const search = headerValue.toLowerCase();
172-
return rowValue.toLowerCase().startsWith(search);
173-
}
174-
175-
if (headerValue.startsWith("^")) {
176-
// starts with
177-
if (headerValue.length == 1) {
178-
return true;
179-
}
180-
const search = headerValue.substring(1).toLowerCase();
181-
return rowValue.toLowerCase().startsWith(search);
182-
}
183-
184-
if (headerValue.startsWith("/") && headerValue.endsWith("/")) {
185-
// regex
186-
const pattern = headerValue.substring(1, headerValue.length - 1);
187-
try {
188-
const re = new RegExp(pattern, "i");
189-
return re.test(rowValue);
190-
} catch (e) {
191-
// bad regex
192-
return false;
193-
}
194-
}
195257

196-
// contains
197-
const search = headerValue.toLowerCase();
198-
return rowValue.toLowerCase().includes(search);
199-
}
200258

201259
async function main() {
202260
let data: SearchEntry[];
@@ -282,12 +340,14 @@ async function main() {
282340
},
283341
{
284342
field: "category",
343+
formatter: fmtCategory,
285344
headerFilter: "input",
345+
headerFilterFunc: filterCategory,
286346
headerHozAlign: "center",
287347
hozAlign: "center",
288348
responsive: 2,
289349
title: "Category",
290-
width: 175,
350+
width: 200,
291351
},
292352
{
293353
field: "age",
@@ -312,7 +372,7 @@ async function main() {
312372
target: "_blank",
313373
},
314374
headerFilter: "input",
315-
headerFilterFunc: nameFilter,
375+
headerFilterFunc: filterName,
316376
responsive: 0,
317377
//sorter: "string",
318378
width: 375,

0 commit comments

Comments
 (0)