@chr33s/pdf-unicode-properties 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md ADDED
@@ -0,0 +1,8 @@
1
+ Copyright 2018
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8
+
package/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # @chr33s/pdf-unicode-properties
2
+
3
+ > Fast lookup of Unicode character metadata packaged as modern ES modules.
4
+
5
+ `@chr33s/pdf-unicode-properties` is part of the [`chr33s/pdf`](https://github.com/chr33s/pdf) monorepo and continues the
6
+ [Hopding/unicode-properties](https://github.com/Hopding/unicode-properties) fork of the original foliojs project. This
7
+ edition is native ES modules only:
8
+
9
+ - ships native ES modules with NodeNext resolution (Node.js 18+ or a modern bundler required),
10
+ - is authored in TypeScript with generated declaration files, and
11
+ - keeps the compressed trie assets embedded for seamless usage across Node.js, browsers, and React Native.
12
+
13
+ # unicode-properties
14
+
15
+ Provides fast access to unicode character properties. Uses [@chr33s/pdf-unicode-trie](https://github.com/chr33s/pdf/tree/main/packages/unicode-trie) to compress the
16
+ properties for all code points into just 12KB.
17
+
18
+ ## Usage
19
+
20
+ ```ts
21
+ import unicodeProperties, {
22
+ getCategory,
23
+ getNumericValue,
24
+ } from "@chr33s/pdf-unicode-properties";
25
+
26
+ getCategory("2".codePointAt(0) ?? 0); //=> 'Nd'
27
+ getNumericValue("2".codePointAt(0) ?? 0); //=> 2
28
+
29
+ // The default export bundles all helpers together when that is convenient.
30
+ unicodeProperties.isDigit("9".codePointAt(0) ?? 0); //=> true
31
+ ```
32
+
33
+ ## Installation
34
+
35
+ ```bash
36
+ npm install @chr33s/pdf-unicode-properties
37
+ ```
38
+
39
+ The package is distributed as native ES modules. Use Node.js 18+ or configure your bundler to resolve NodeNext-style imports.
40
+
41
+ ## API
42
+
43
+ ### getCategory(codePoint)
44
+
45
+ Returns the unicode [general category](http://www.fileformat.info/info/unicode/category/index.htm) for the given code point.
46
+
47
+ ### getScript(codePoint)
48
+
49
+ Returns the [script](http://unicode.org/standard/supported.html) for the given code point.
50
+
51
+ ### getCombiningClass(codePoint)
52
+
53
+ Returns the [canonical combining class](http://unicode.org/glossary/#combining_class) for the given code point.
54
+
55
+ ### getEastAsianWidth(codePoint)
56
+
57
+ Returns the [East Asian width](http://www.unicode.org/reports/tr11/tr11-28.html) for the given code point.
58
+
59
+ ### getNumericValue(codePoint)
60
+
61
+ Returns the numeric value for the given code point, or null if there is no numeric value for that code point.
62
+
63
+ ### isAlphabetic(codePoint)
64
+
65
+ Returns whether the code point is an alphabetic character.
66
+
67
+ ### isDigit(codePoint)
68
+
69
+ Returns whether the code point is a digit.
70
+
71
+ ### isPunctuation(codePoint)
72
+
73
+ Returns whether the code point is a punctuation character.
74
+
75
+ ### isLowerCase(codePoint)
76
+
77
+ Returns whether the code point is lower case.
78
+
79
+ ### isUpperCase(codePoint)
80
+
81
+ Returns whether the code point is upper case.
82
+
83
+ ### isTitleCase(codePoint)
84
+
85
+ Returns whether the code point is title case.
86
+
87
+ ### isWhiteSpace(codePoint)
88
+
89
+ Returns whether the code point is whitespace: specifically, whether the category is one of Zs, Zl, or Zp.
90
+
91
+ ### isBaseForm(codePoint)
92
+
93
+ Returns whether the code point is a base form. A code point of base form does not graphically combine with preceding
94
+ characters.
95
+
96
+ ### isMark(codePoint)
97
+
98
+ Returns whether the code point is a mark character (e.g. accent).
99
+
100
+ ## License
101
+ [MIT](https://choosealicense.com/licenses/mit/)
package/dist/data.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export default payload;
2
+ declare const payload: "eJxtVttu4zYQ/Rc9+2Hj9LLbt1hJkzS2Y8RuFt0iEI4thpyIIl2KTKAt+u/FDCnvpugLZ0gOz9xH+rs6ICrtA6mh+uXPqj5Us+rLUM2qja9m1Za3G9kq3vbMtdWsWvOyTHzW8RnLLS1v+dmSlw1Vs6p+ZmHZMreMvDDKyvHCoCt+u+a3X2Q58jNWWfvqaVYdfL8nR07XFsOQrVz72DwoH1oVFBtysfevaqLNA2nDehbK+jc+jREHo9rm/fXpeJK7f1XBYqxm1a2PaLZpPxwCHVn20qe9VSfJsp3UyvE3XNGyVM+8qev67EOhZ4XOCz0v9IdCfyz0p0J/LvRjoZ8ynRe8ecGbF7x5wZsXvHnBOy/y50X+fJIv+POCPy/45wXnvOCcTzhs1zp1EdWseqSAHvniYxH8NDn4YfLsw+TCyYfJ2LNJ29lk3pnY9T5Xp9iWaBZyB4fm0dOBnC62s205AU+zKqct17Pve8+ltkQkpgt/9L1/5oq8dUYFilJB10GpTmruGIkLsh4DWSvsReiVI/DrG7UPSmoqYC+X2zEQmNkZwHFE1p10DnoEivJqBddCpC/VKxw0AolrTsMyd51CnzqT2RcERGbvA40MuENP3Bk7ZZNO2X+HFoJsMcKCO2pLzsAim0LiMhuyo70qZoxwPQIrUT7o4hGcTox+FQ35Y/bdqOA7xeGv4dASHOcjkCYHlr3XRlQ+JCcPdtCwXme45DzrXSRDbb7bw72xXXemV6x+5Z32NutfUr9PIkbNkjWu1VsjmyTpT5qcGlSR2GW9C9jpdJtci8IvENFJmRwPhhXe26Y21EmwA8halrq2YO05zTt6Jgdtsum8UoDOibxjuMz+IfGkgS19lOAu0CeJ+mh9pGYNLTndGOih2UAqIAUMJoaMNcI0SxZ5UC+Quv0Nr5PldfaLXXwkFWU0qqioWWGUuhT1TiE0C2bHQ45ejZCZe9s2txG5YK99NMLw6UaFXja/c9nF78+H/PZSDSqI0q3Ba8EbejipvvsBmk28snsMRWk6YJCisHu4KY9i3YW0zjGQZ7zb/qgCwTYXPC1E9Qa2H4NykmrsEaFKHcYgzMZ45aj4txzbzKxU8Gx8c0MqeG3Hoxm+P65TGEgGxp1B8IOJ0k3s6NanaBpp2FOo1j68O1vB0cEUUy5e1ZA75tblUULewTYbhGjofy+Mxaukf4CNKnx3wtp2KXSnuN8kp6es3cDRMzUP3pDTOdpisC5ef+Ou7FgCuAgwPUlJUXZy6wOare+PKo9Dg67Pw8HgBY5yYkOeGHfGv0hDrJKN+fLOpBZvaGX8BLgovbNW0rM7CibJyN9S2+YyXXmR3aGTmr8wvpePopZS/4wAp5uaZIit4Vo6jbwvcNjjK0Kz/SshSAP70fd7+UNAampyzQ24zRYG1A0p24pwMConakBA31x7l+1N7gUWp/0KHUtwGJJT9OwDm3alx2Pkgn1fPRcOUebQf6sqyADDMKB5hBHTDN5Mc9N7CfFKteoZ1Ab5pKwoD1qepFG+kYNhDy7T0foxJ5K0+8zdJ8/XI6FTTjebhINJ6oT7Ge5gvChwrWruqEOXJMQtz/inWaXwJj9AElm+4FdcSdWs+rV6+udfRvMHTw==";
package/dist/data.js ADDED
@@ -0,0 +1,3 @@
1
+ const payload = "eJxtVttu4zYQ/Rc9+2Hj9LLbt1hJkzS2Y8RuFt0iEI4thpyIIl2KTKAt+u/FDCnvpugLZ0gOz9xH+rs6ICrtA6mh+uXPqj5Us+rLUM2qja9m1Za3G9kq3vbMtdWsWvOyTHzW8RnLLS1v+dmSlw1Vs6p+ZmHZMreMvDDKyvHCoCt+u+a3X2Q58jNWWfvqaVYdfL8nR07XFsOQrVz72DwoH1oVFBtysfevaqLNA2nDehbK+jc+jREHo9rm/fXpeJK7f1XBYqxm1a2PaLZpPxwCHVn20qe9VSfJsp3UyvE3XNGyVM+8qev67EOhZ4XOCz0v9IdCfyz0p0J/LvRjoZ8ynRe8ecGbF7x5wZsXvHnBOy/y50X+fJIv+POCPy/45wXnvOCcTzhs1zp1EdWseqSAHvniYxH8NDn4YfLsw+TCyYfJ2LNJ29lk3pnY9T5Xp9iWaBZyB4fm0dOBnC62s205AU+zKqct17Pve8+ltkQkpgt/9L1/5oq8dUYFilJB10GpTmruGIkLsh4DWSvsReiVI/DrG7UPSmoqYC+X2zEQmNkZwHFE1p10DnoEivJqBddCpC/VKxw0AolrTsMyd51CnzqT2RcERGbvA40MuENP3Bk7ZZNO2X+HFoJsMcKCO2pLzsAim0LiMhuyo70qZoxwPQIrUT7o4hGcTox+FQ35Y/bdqOA7xeGv4dASHOcjkCYHlr3XRlQ+JCcPdtCwXme45DzrXSRDbb7bw72xXXemV6x+5Z32NutfUr9PIkbNkjWu1VsjmyTpT5qcGlSR2GW9C9jpdJtci8IvENFJmRwPhhXe26Y21EmwA8halrq2YO05zTt6Jgdtsum8UoDOibxjuMz+IfGkgS19lOAu0CeJ+mh9pGYNLTndGOih2UAqIAUMJoaMNcI0SxZ5UC+Quv0Nr5PldfaLXXwkFWU0qqioWWGUuhT1TiE0C2bHQ45ejZCZe9s2txG5YK99NMLw6UaFXja/c9nF78+H/PZSDSqI0q3Ba8EbejipvvsBmk28snsMRWk6YJCisHu4KY9i3YW0zjGQZ7zb/qgCwTYXPC1E9Qa2H4NykmrsEaFKHcYgzMZ45aj4txzbzKxU8Gx8c0MqeG3Hoxm+P65TGEgGxp1B8IOJ0k3s6NanaBpp2FOo1j68O1vB0cEUUy5e1ZA75tblUULewTYbhGjofy+Mxaukf4CNKnx3wtp2KXSnuN8kp6es3cDRMzUP3pDTOdpisC5ef+Ou7FgCuAgwPUlJUXZy6wOare+PKo9Dg67Pw8HgBY5yYkOeGHfGv0hDrJKN+fLOpBZvaGX8BLgovbNW0rM7CibJyN9S2+YyXXmR3aGTmr8wvpePopZS/4wAp5uaZIit4Vo6jbwvcNjjK0Kz/SshSAP70fd7+UNAampyzQ24zRYG1A0p24pwMConakBA31x7l+1N7gUWp/0KHUtwGJJT9OwDm3alx2Pkgn1fPRcOUebQf6sqyADDMKB5hBHTDN5Mc9N7CfFKteoZ1Ab5pKwoD1qepFG+kYNhDy7T0foxJ5K0+8zdJ8/XI6FTTjebhINJ6oT7Ge5gvChwrWruqEOXJMQtz/inWaXwJj9AElm+4FdcSdWs+rV6+udfRvMHTw==";
2
+ export default payload;
3
+ //# sourceMappingURL=data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data.js","sourceRoot":"","sources":["../src/data.js"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG,slDAAslD,CAAC;AACvmD,eAAe,OAAO,CAAC"}
@@ -0,0 +1,39 @@
1
+ export type PropertyAccessor = (codePoint: number) => string;
2
+ export type NumericAccessor = (codePoint: number) => number | null;
3
+ export type PropertyPredicate = (codePoint: number) => boolean;
4
+ export type UnicodePropertiesAPI = {
5
+ getCategory: PropertyAccessor;
6
+ getCombiningClass: PropertyAccessor;
7
+ getScript: PropertyAccessor;
8
+ getEastAsianWidth: PropertyAccessor;
9
+ getNumericValue: NumericAccessor;
10
+ isAlphabetic: PropertyPredicate;
11
+ isDigit: PropertyPredicate;
12
+ isPunctuation: PropertyPredicate;
13
+ isLowerCase: PropertyPredicate;
14
+ isUpperCase: PropertyPredicate;
15
+ isTitleCase: PropertyPredicate;
16
+ isWhiteSpace: PropertyPredicate;
17
+ isBaseForm: PropertyPredicate;
18
+ isMark: PropertyPredicate;
19
+ };
20
+ /**
21
+ * Creates a UnicodeProperties instance asynchronously.
22
+ * Uses cached singleton after first initialization.
23
+ */
24
+ export declare function createUnicodeProperties(): Promise<UnicodePropertiesAPI>;
25
+ /**
26
+ * Checks if unicode-properties has been initialized.
27
+ */
28
+ export declare function isInitialized(): boolean;
29
+ /**
30
+ * Gets the initialized instance. Throws if not initialized.
31
+ * Use this after calling createUnicodeProperties().
32
+ */
33
+ export declare function getUnicodeProperties(): UnicodePropertiesAPI;
34
+ /**
35
+ * Proxy object that provides sync access to unicode-properties after initialization.
36
+ * Will throw if accessed before createUnicodeProperties() resolves.
37
+ */
38
+ export declare const unicode: UnicodePropertiesAPI;
39
+ export default createUnicodeProperties;
package/dist/index.js ADDED
@@ -0,0 +1,187 @@
1
+ import { base64, inflate } from "@chr33s/pdf-common";
2
+ import UnicodeTrie from "@chr33s/pdf-unicode-trie";
3
+ import base64DeflatedData from "./data.js";
4
+ import base64DeflatedTrie from "./trie.js";
5
+ const decodeBase64 = (encoded) => new Uint8Array(base64.decode(encoded));
6
+ const textDecoder = new TextDecoder();
7
+ const inflateJson = async (encoded) => JSON.parse(textDecoder.decode(await inflate(decodeBase64(encoded))));
8
+ const inflateBinary = (encoded) => inflate(decodeBase64(encoded));
9
+ const log2 = (value) => Math.log2?.(value) ?? Math.log(value) / Math.LN2;
10
+ const bits = (value) => (value > 0 ? (log2(value) + 1) | 0 : 0);
11
+ // Singleton instance and initialization promise
12
+ let instance = null;
13
+ let initPromise = null;
14
+ /**
15
+ * Creates a UnicodeProperties instance asynchronously.
16
+ * Uses cached singleton after first initialization.
17
+ */
18
+ export async function createUnicodeProperties() {
19
+ if (instance)
20
+ return instance;
21
+ if (initPromise)
22
+ return initPromise;
23
+ initPromise = (async () => {
24
+ const encodedData = base64DeflatedData;
25
+ const encodedTrie = base64DeflatedTrie;
26
+ const [data, trieData] = await Promise.all([
27
+ inflateJson(encodedData),
28
+ inflateBinary(encodedTrie),
29
+ ]);
30
+ const trie = await UnicodeTrie.create(trieData);
31
+ // compute the number of bits stored for each field
32
+ const CATEGORY_BITS = bits(data.categories.length - 1);
33
+ const COMBINING_BITS = bits(data.combiningClasses.length - 1);
34
+ const SCRIPT_BITS = bits(data.scripts.length - 1);
35
+ const EAW_BITS = bits(data.eaw.length - 1);
36
+ const NUMBER_BITS = 10;
37
+ // compute shift and mask values for each field
38
+ const CATEGORY_SHIFT = COMBINING_BITS + SCRIPT_BITS + EAW_BITS + NUMBER_BITS;
39
+ const COMBINING_SHIFT = SCRIPT_BITS + EAW_BITS + NUMBER_BITS;
40
+ const SCRIPT_SHIFT = EAW_BITS + NUMBER_BITS;
41
+ const EAW_SHIFT = NUMBER_BITS;
42
+ const CATEGORY_MASK = (1 << CATEGORY_BITS) - 1;
43
+ const COMBINING_MASK = (1 << COMBINING_BITS) - 1;
44
+ const SCRIPT_MASK = (1 << SCRIPT_BITS) - 1;
45
+ const EAW_MASK = (1 << EAW_BITS) - 1;
46
+ const NUMBER_MASK = (1 << NUMBER_BITS) - 1;
47
+ const getCategory = (codePoint) => {
48
+ const val = trie.get(codePoint);
49
+ return data.categories[(val >> CATEGORY_SHIFT) & CATEGORY_MASK];
50
+ };
51
+ const getCombiningClass = (codePoint) => {
52
+ const val = trie.get(codePoint);
53
+ return data.combiningClasses[(val >> COMBINING_SHIFT) & COMBINING_MASK];
54
+ };
55
+ const getScript = (codePoint) => {
56
+ const val = trie.get(codePoint);
57
+ return data.scripts[(val >> SCRIPT_SHIFT) & SCRIPT_MASK];
58
+ };
59
+ const getEastAsianWidth = (codePoint) => {
60
+ const val = trie.get(codePoint);
61
+ return data.eaw[(val >> EAW_SHIFT) & EAW_MASK];
62
+ };
63
+ const getNumericValue = (codePoint) => {
64
+ let val = trie.get(codePoint);
65
+ let num = val & NUMBER_MASK;
66
+ if (num === 0) {
67
+ return null;
68
+ }
69
+ if (num <= 50) {
70
+ return num - 1;
71
+ }
72
+ if (num < 0x1e0) {
73
+ const numerator = (num >> 4) - 12;
74
+ const denominator = (num & 0xf) + 1;
75
+ return numerator / denominator;
76
+ }
77
+ if (num < 0x300) {
78
+ val = (num >> 5) - 14;
79
+ let exp = (num & 0x1f) + 2;
80
+ while (exp > 0) {
81
+ val *= 10;
82
+ exp--;
83
+ }
84
+ return val;
85
+ }
86
+ val = (num >> 2) - 0xbf;
87
+ let exp = (num & 3) + 1;
88
+ while (exp > 0) {
89
+ val *= 60;
90
+ exp--;
91
+ }
92
+ return val;
93
+ };
94
+ const isAlphabetic = (codePoint) => {
95
+ const category = getCategory(codePoint);
96
+ return (category === "Lu" ||
97
+ category === "Ll" ||
98
+ category === "Lt" ||
99
+ category === "Lm" ||
100
+ category === "Lo" ||
101
+ category === "Nl");
102
+ };
103
+ const isDigit = (codePoint) => getCategory(codePoint) === "Nd";
104
+ const isPunctuation = (codePoint) => {
105
+ const category = getCategory(codePoint);
106
+ return (category === "Pc" ||
107
+ category === "Pd" ||
108
+ category === "Pe" ||
109
+ category === "Pf" ||
110
+ category === "Pi" ||
111
+ category === "Po" ||
112
+ category === "Ps");
113
+ };
114
+ const isLowerCase = (codePoint) => getCategory(codePoint) === "Ll";
115
+ const isUpperCase = (codePoint) => getCategory(codePoint) === "Lu";
116
+ const isTitleCase = (codePoint) => getCategory(codePoint) === "Lt";
117
+ const isWhiteSpace = (codePoint) => {
118
+ const category = getCategory(codePoint);
119
+ return category === "Zs" || category === "Zl" || category === "Zp";
120
+ };
121
+ const isBaseForm = (codePoint) => {
122
+ const category = getCategory(codePoint);
123
+ return (category === "Nd" ||
124
+ category === "No" ||
125
+ category === "Nl" ||
126
+ category === "Lu" ||
127
+ category === "Ll" ||
128
+ category === "Lt" ||
129
+ category === "Lm" ||
130
+ category === "Lo" ||
131
+ category === "Me" ||
132
+ category === "Mc");
133
+ };
134
+ const isMark = (codePoint) => {
135
+ const category = getCategory(codePoint);
136
+ return category === "Mn" || category === "Me" || category === "Mc";
137
+ };
138
+ instance = {
139
+ getCategory,
140
+ getCombiningClass,
141
+ getScript,
142
+ getEastAsianWidth,
143
+ getNumericValue,
144
+ isAlphabetic,
145
+ isDigit,
146
+ isPunctuation,
147
+ isLowerCase,
148
+ isUpperCase,
149
+ isTitleCase,
150
+ isWhiteSpace,
151
+ isBaseForm,
152
+ isMark,
153
+ };
154
+ return instance;
155
+ })();
156
+ return initPromise;
157
+ }
158
+ /**
159
+ * Checks if unicode-properties has been initialized.
160
+ */
161
+ export function isInitialized() {
162
+ return instance !== null;
163
+ }
164
+ /**
165
+ * Gets the initialized instance. Throws if not initialized.
166
+ * Use this after calling createUnicodeProperties().
167
+ */
168
+ export function getUnicodeProperties() {
169
+ if (!instance) {
170
+ throw new Error("unicode-properties not initialized. Call createUnicodeProperties() first and await its result.");
171
+ }
172
+ return instance;
173
+ }
174
+ /**
175
+ * Proxy object that provides sync access to unicode-properties after initialization.
176
+ * Will throw if accessed before createUnicodeProperties() resolves.
177
+ */
178
+ export const unicode = new Proxy({}, {
179
+ get(_target, prop) {
180
+ if (!instance) {
181
+ throw new Error(`unicode-properties not initialized. Call createUnicodeProperties() first before accessing '${String(prop)}'.`);
182
+ }
183
+ return instance[prop];
184
+ },
185
+ });
186
+ export default createUnicodeProperties;
187
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/trie.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export default payload;
2
+ declare const payload: "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";
package/dist/trie.js ADDED
@@ -0,0 +1,3 @@
1
+ const payload = "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";
2
+ export default payload;
3
+ //# sourceMappingURL=trie.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trie.js","sourceRoot":"","sources":["../src/trie.js"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG,kihBAAkihB,CAAC;AACnjhB,eAAe,OAAO,CAAC"}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@chr33s/pdf-unicode-properties",
3
+ "version": "5.0.0",
4
+ "description": "Provides fast access to unicode character properties",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ }
12
+ },
13
+ "scripts": {
14
+ "build": "npm run clean && npm run generate && tsc",
15
+ "clean": "rm -rf dist src/*.js src/*.d.ts",
16
+ "generate": "node scripts/generate.ts",
17
+ "test": "vitest run",
18
+ "typecheck": "tsc --project tsconfig.typecheck.json"
19
+ },
20
+ "dependencies": {
21
+ "@chr33s/pdf-common": "file:../common",
22
+ "@chr33s/pdf-unicode-trie": "file:../unicode-trie"
23
+ },
24
+ "devDependencies": {
25
+ "@chr33s/pdf-codepoints": "file:../codepoints",
26
+ "@types/node": "24.10.1",
27
+ "@vitest/coverage-v8": "4.0.15",
28
+ "typescript": "5.9.3",
29
+ "vitest": "4.0.15"
30
+ },
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/chr33s/pdf.git"
34
+ },
35
+ "keywords": [
36
+ "unicode",
37
+ "metadata",
38
+ "character",
39
+ "codepoint"
40
+ ],
41
+ "author": "Andrew Dillon <andrew.dillon.j@gmail.com>",
42
+ "contributors": [
43
+ "Devon Govett <devongovett@gmail.com> (http://badassjs.com/)"
44
+ ],
45
+ "bugs": {
46
+ "url": "https://github.com/chr33s/pdf/issues"
47
+ },
48
+ "license": "MIT",
49
+ "homepage": "https://github.com/chr33s/pdf"
50
+ }
@@ -0,0 +1,149 @@
1
+ import codePoints from "@chr33s/pdf-codepoints";
2
+ import { base64, deflate } from "@chr33s/pdf-common";
3
+ import { builder as UnicodeTrieBuilder } from "@chr33s/pdf-unicode-trie";
4
+ import { writeFile } from "node:fs/promises";
5
+ import path from "node:path";
6
+
7
+ type IndexLookup = Record<string, number>;
8
+
9
+ const bits = (value: number): number => (value > 0 ? (Math.log2(value) + 1) | 0 : 0);
10
+
11
+ const numericValue = (numeric?: string | null): number => {
12
+ if (!numeric) {
13
+ return 0;
14
+ }
15
+
16
+ const fractionMatch = numeric.match(/^(-?\d+)\/(\d+)$/);
17
+ if (fractionMatch) {
18
+ const numerator = parseInt(fractionMatch[1], 10);
19
+ const denominator = parseInt(fractionMatch[2], 10);
20
+ return ((numerator + 12) << 4) + (denominator - 1);
21
+ }
22
+
23
+ if (/^\d0+$/.test(numeric)) {
24
+ const mantissa = parseInt(numeric[0]!, 10);
25
+ const exponent = numeric.length - 1;
26
+ return ((mantissa + 14) << 5) + (exponent - 2);
27
+ }
28
+
29
+ const value = parseInt(numeric, 10);
30
+ if (value <= 50) {
31
+ return 1 + value;
32
+ }
33
+
34
+ let mantissa = value;
35
+ let exponent = 0;
36
+ while (mantissa % 60 === 0) {
37
+ mantissa /= 60;
38
+ exponent += 1;
39
+ }
40
+
41
+ return ((mantissa + 0xbf) << 2) + (exponent - 1);
42
+ };
43
+
44
+ const addIndex = (
45
+ lookup: IndexLookup,
46
+ key: string | null | undefined,
47
+ currentCount: number,
48
+ ): number => {
49
+ const normalizedKey = key ?? "";
50
+ if (lookup[normalizedKey] == null) {
51
+ lookup[normalizedKey] = currentCount;
52
+ return currentCount + 1;
53
+ }
54
+ return currentCount;
55
+ };
56
+
57
+ const getIndex = (lookup: IndexLookup, key: string | null | undefined): number =>
58
+ lookup[key ?? ""] ?? 0;
59
+
60
+ const srcDir = path.resolve(process.cwd(), "src");
61
+ const trieFilePath = path.join(srcDir, "trie.js");
62
+ const dataFilePath = path.join(srcDir, "data.js");
63
+
64
+ const categories: IndexLookup = Object.create(null);
65
+ const combiningClasses: IndexLookup = Object.create(null);
66
+ const scripts: IndexLookup = Object.create(null);
67
+ const eaws: IndexLookup = Object.create(null);
68
+
69
+ let categoryCount = 0;
70
+ let combiningClassCount = 0;
71
+ let scriptCount = 0;
72
+ let eawCount = 0;
73
+
74
+ const entries = Array.from(codePoints);
75
+
76
+ for (const entry of entries) {
77
+ if (!entry) {
78
+ continue;
79
+ }
80
+
81
+ categoryCount = addIndex(categories, entry.category, categoryCount);
82
+ combiningClassCount = addIndex(combiningClasses, entry.combiningClassName, combiningClassCount);
83
+ scriptCount = addIndex(scripts, entry.script, scriptCount);
84
+ eawCount = addIndex(eaws, entry.eastAsianWidth, eawCount);
85
+ }
86
+
87
+ const numberBits = 10;
88
+ const combiningClassBits = bits(combiningClassCount - 1);
89
+ const scriptBits = bits(scriptCount - 1);
90
+ const eawBits = bits(eawCount - 1);
91
+
92
+ const categoryShift = combiningClassBits + scriptBits + eawBits + numberBits;
93
+ const combiningShift = scriptBits + eawBits + numberBits;
94
+ const scriptShift = eawBits + numberBits;
95
+ const eawShift = numberBits;
96
+
97
+ const trie = new UnicodeTrieBuilder();
98
+ for (const entry of entries) {
99
+ if (!entry) {
100
+ continue;
101
+ }
102
+
103
+ const category = getIndex(categories, entry.category);
104
+ const combiningClass = getIndex(combiningClasses, entry.combiningClassName);
105
+ const script = getIndex(scripts, entry.script);
106
+ const eaw = getIndex(eaws, entry.eastAsianWidth);
107
+ const numeric = numericValue(entry.numeric);
108
+
109
+ const val =
110
+ (category << categoryShift) |
111
+ (combiningClass << combiningShift) |
112
+ (script << scriptShift) |
113
+ (eaw << eawShift) |
114
+ numeric;
115
+
116
+ trie.set(entry.code, val);
117
+ }
118
+
119
+ const trieBuffer = await trie.toBuffer();
120
+ const compressedTrie = await deflate(trieBuffer);
121
+ const triePayload = base64.encode(
122
+ compressedTrie.buffer.slice(
123
+ compressedTrie.byteOffset,
124
+ compressedTrie.byteOffset + compressedTrie.byteLength,
125
+ ) as ArrayBuffer,
126
+ );
127
+
128
+ const emitModule = (value: string): string =>
129
+ `const payload = ${JSON.stringify(value)};\nexport default payload;\n`;
130
+
131
+ await writeFile(trieFilePath, emitModule(triePayload));
132
+
133
+ const encoder = new TextEncoder();
134
+ const data = {
135
+ categories: Object.keys(categories),
136
+ combiningClasses: Object.keys(combiningClasses),
137
+ scripts: Object.keys(scripts),
138
+ eaw: Object.keys(eaws),
139
+ };
140
+
141
+ const dataBytes = encoder.encode(JSON.stringify(data));
142
+ const compressedData = await deflate(dataBytes);
143
+ const dataPayload = base64.encode(
144
+ compressedData.buffer.slice(
145
+ compressedData.byteOffset,
146
+ compressedData.byteOffset + compressedData.byteLength,
147
+ ) as ArrayBuffer,
148
+ );
149
+ await writeFile(dataFilePath, emitModule(dataPayload));
package/src/data.js ADDED
@@ -0,0 +1,2 @@
1
+ const payload = "eJxtVttu4zYQ/Rc9+2Hj9LLbt1hJkzS2Y8RuFt0iEI4thpyIIl2KTKAt+u/FDCnvpugLZ0gOz9xH+rs6ICrtA6mh+uXPqj5Us+rLUM2qja9m1Za3G9kq3vbMtdWsWvOyTHzW8RnLLS1v+dmSlw1Vs6p+ZmHZMreMvDDKyvHCoCt+u+a3X2Q58jNWWfvqaVYdfL8nR07XFsOQrVz72DwoH1oVFBtysfevaqLNA2nDehbK+jc+jREHo9rm/fXpeJK7f1XBYqxm1a2PaLZpPxwCHVn20qe9VSfJsp3UyvE3XNGyVM+8qev67EOhZ4XOCz0v9IdCfyz0p0J/LvRjoZ8ynRe8ecGbF7x5wZsXvHnBOy/y50X+fJIv+POCPy/45wXnvOCcTzhs1zp1EdWseqSAHvniYxH8NDn4YfLsw+TCyYfJ2LNJ29lk3pnY9T5Xp9iWaBZyB4fm0dOBnC62s205AU+zKqct17Pve8+ltkQkpgt/9L1/5oq8dUYFilJB10GpTmruGIkLsh4DWSvsReiVI/DrG7UPSmoqYC+X2zEQmNkZwHFE1p10DnoEivJqBddCpC/VKxw0AolrTsMyd51CnzqT2RcERGbvA40MuENP3Bk7ZZNO2X+HFoJsMcKCO2pLzsAim0LiMhuyo70qZoxwPQIrUT7o4hGcTox+FQ35Y/bdqOA7xeGv4dASHOcjkCYHlr3XRlQ+JCcPdtCwXme45DzrXSRDbb7bw72xXXemV6x+5Z32NutfUr9PIkbNkjWu1VsjmyTpT5qcGlSR2GW9C9jpdJtci8IvENFJmRwPhhXe26Y21EmwA8halrq2YO05zTt6Jgdtsum8UoDOibxjuMz+IfGkgS19lOAu0CeJ+mh9pGYNLTndGOih2UAqIAUMJoaMNcI0SxZ5UC+Quv0Nr5PldfaLXXwkFWU0qqioWWGUuhT1TiE0C2bHQ45ejZCZe9s2txG5YK99NMLw6UaFXja/c9nF78+H/PZSDSqI0q3Ba8EbejipvvsBmk28snsMRWk6YJCisHu4KY9i3YW0zjGQZ7zb/qgCwTYXPC1E9Qa2H4NykmrsEaFKHcYgzMZ45aj4txzbzKxU8Gx8c0MqeG3Hoxm+P65TGEgGxp1B8IOJ0k3s6NanaBpp2FOo1j68O1vB0cEUUy5e1ZA75tblUULewTYbhGjofy+Mxaukf4CNKnx3wtp2KXSnuN8kp6es3cDRMzUP3pDTOdpisC5ef+Ou7FgCuAgwPUlJUXZy6wOare+PKo9Dg67Pw8HgBY5yYkOeGHfGv0hDrJKN+fLOpBZvaGX8BLgovbNW0rM7CibJyN9S2+YyXXmR3aGTmr8wvpePopZS/4wAp5uaZIit4Vo6jbwvcNjjK0Kz/SshSAP70fd7+UNAampyzQ24zRYG1A0p24pwMConakBA31x7l+1N7gUWp/0KHUtwGJJT9OwDm3alx2Pkgn1fPRcOUebQf6sqyADDMKB5hBHTDN5Mc9N7CfFKteoZ1Ab5pKwoD1qepFG+kYNhDy7T0foxJ5K0+8zdJ8/XI6FTTjebhINJ6oT7Ge5gvChwrWruqEOXJMQtz/inWaXwJj9AElm+4FdcSdWs+rV6+udfRvMHTw==";
2
+ export default payload;
package/src/index.ts ADDED
@@ -0,0 +1,262 @@
1
+ import { base64, inflate } from "@chr33s/pdf-common";
2
+ import UnicodeTrie from "@chr33s/pdf-unicode-trie";
3
+
4
+ import base64DeflatedData from "./data.js";
5
+ import base64DeflatedTrie from "./trie.js";
6
+
7
+ type UnicodeDataset = {
8
+ categories: string[];
9
+ combiningClasses: string[];
10
+ scripts: string[];
11
+ eaw: string[];
12
+ };
13
+
14
+ export type PropertyAccessor = (codePoint: number) => string;
15
+ export type NumericAccessor = (codePoint: number) => number | null;
16
+ export type PropertyPredicate = (codePoint: number) => boolean;
17
+
18
+ const decodeBase64 = (encoded: string): Uint8Array => new Uint8Array(base64.decode(encoded));
19
+
20
+ const textDecoder = new TextDecoder();
21
+ const inflateJson = async <T>(encoded: string): Promise<T> =>
22
+ JSON.parse(textDecoder.decode(await inflate(decodeBase64(encoded))));
23
+
24
+ const inflateBinary = (encoded: string): Promise<Uint8Array> => inflate(decodeBase64(encoded));
25
+
26
+ const log2 = (value: number): number => Math.log2?.(value) ?? Math.log(value) / Math.LN2;
27
+ const bits = (value: number): number => (value > 0 ? (log2(value) + 1) | 0 : 0);
28
+
29
+ export type UnicodePropertiesAPI = {
30
+ getCategory: PropertyAccessor;
31
+ getCombiningClass: PropertyAccessor;
32
+ getScript: PropertyAccessor;
33
+ getEastAsianWidth: PropertyAccessor;
34
+ getNumericValue: NumericAccessor;
35
+ isAlphabetic: PropertyPredicate;
36
+ isDigit: PropertyPredicate;
37
+ isPunctuation: PropertyPredicate;
38
+ isLowerCase: PropertyPredicate;
39
+ isUpperCase: PropertyPredicate;
40
+ isTitleCase: PropertyPredicate;
41
+ isWhiteSpace: PropertyPredicate;
42
+ isBaseForm: PropertyPredicate;
43
+ isMark: PropertyPredicate;
44
+ };
45
+
46
+ // Singleton instance and initialization promise
47
+ let instance: UnicodePropertiesAPI | null = null;
48
+ let initPromise: Promise<UnicodePropertiesAPI> | null = null;
49
+
50
+ /**
51
+ * Creates a UnicodeProperties instance asynchronously.
52
+ * Uses cached singleton after first initialization.
53
+ */
54
+ export async function createUnicodeProperties(): Promise<UnicodePropertiesAPI> {
55
+ if (instance) return instance;
56
+ if (initPromise) return initPromise;
57
+
58
+ initPromise = (async () => {
59
+ const encodedData = base64DeflatedData as string;
60
+ const encodedTrie = base64DeflatedTrie as string;
61
+
62
+ const [data, trieData] = await Promise.all([
63
+ inflateJson<UnicodeDataset>(encodedData),
64
+ inflateBinary(encodedTrie),
65
+ ]);
66
+
67
+ const trie = await UnicodeTrie.create(trieData);
68
+
69
+ // compute the number of bits stored for each field
70
+ const CATEGORY_BITS = bits(data.categories.length - 1);
71
+ const COMBINING_BITS = bits(data.combiningClasses.length - 1);
72
+ const SCRIPT_BITS = bits(data.scripts.length - 1);
73
+ const EAW_BITS = bits(data.eaw.length - 1);
74
+ const NUMBER_BITS = 10;
75
+
76
+ // compute shift and mask values for each field
77
+ const CATEGORY_SHIFT = COMBINING_BITS + SCRIPT_BITS + EAW_BITS + NUMBER_BITS;
78
+ const COMBINING_SHIFT = SCRIPT_BITS + EAW_BITS + NUMBER_BITS;
79
+ const SCRIPT_SHIFT = EAW_BITS + NUMBER_BITS;
80
+ const EAW_SHIFT = NUMBER_BITS;
81
+ const CATEGORY_MASK = (1 << CATEGORY_BITS) - 1;
82
+ const COMBINING_MASK = (1 << COMBINING_BITS) - 1;
83
+ const SCRIPT_MASK = (1 << SCRIPT_BITS) - 1;
84
+ const EAW_MASK = (1 << EAW_BITS) - 1;
85
+ const NUMBER_MASK = (1 << NUMBER_BITS) - 1;
86
+
87
+ const getCategory: PropertyAccessor = (codePoint) => {
88
+ const val = trie.get(codePoint);
89
+ return data.categories[(val >> CATEGORY_SHIFT) & CATEGORY_MASK];
90
+ };
91
+
92
+ const getCombiningClass: PropertyAccessor = (codePoint) => {
93
+ const val = trie.get(codePoint);
94
+ return data.combiningClasses[(val >> COMBINING_SHIFT) & COMBINING_MASK];
95
+ };
96
+
97
+ const getScript: PropertyAccessor = (codePoint) => {
98
+ const val = trie.get(codePoint);
99
+ return data.scripts[(val >> SCRIPT_SHIFT) & SCRIPT_MASK];
100
+ };
101
+
102
+ const getEastAsianWidth: PropertyAccessor = (codePoint) => {
103
+ const val = trie.get(codePoint);
104
+ return data.eaw[(val >> EAW_SHIFT) & EAW_MASK];
105
+ };
106
+
107
+ const getNumericValue: NumericAccessor = (codePoint) => {
108
+ let val = trie.get(codePoint);
109
+ let num = val & NUMBER_MASK;
110
+
111
+ if (num === 0) {
112
+ return null;
113
+ }
114
+
115
+ if (num <= 50) {
116
+ return num - 1;
117
+ }
118
+
119
+ if (num < 0x1e0) {
120
+ const numerator = (num >> 4) - 12;
121
+ const denominator = (num & 0xf) + 1;
122
+ return numerator / denominator;
123
+ }
124
+
125
+ if (num < 0x300) {
126
+ val = (num >> 5) - 14;
127
+ let exp = (num & 0x1f) + 2;
128
+
129
+ while (exp > 0) {
130
+ val *= 10;
131
+ exp--;
132
+ }
133
+ return val;
134
+ }
135
+
136
+ val = (num >> 2) - 0xbf;
137
+ let exp = (num & 3) + 1;
138
+ while (exp > 0) {
139
+ val *= 60;
140
+ exp--;
141
+ }
142
+ return val;
143
+ };
144
+
145
+ const isAlphabetic: PropertyPredicate = (codePoint) => {
146
+ const category = getCategory(codePoint);
147
+ return (
148
+ category === "Lu" ||
149
+ category === "Ll" ||
150
+ category === "Lt" ||
151
+ category === "Lm" ||
152
+ category === "Lo" ||
153
+ category === "Nl"
154
+ );
155
+ };
156
+
157
+ const isDigit: PropertyPredicate = (codePoint) => getCategory(codePoint) === "Nd";
158
+
159
+ const isPunctuation: PropertyPredicate = (codePoint) => {
160
+ const category = getCategory(codePoint);
161
+ return (
162
+ category === "Pc" ||
163
+ category === "Pd" ||
164
+ category === "Pe" ||
165
+ category === "Pf" ||
166
+ category === "Pi" ||
167
+ category === "Po" ||
168
+ category === "Ps"
169
+ );
170
+ };
171
+
172
+ const isLowerCase: PropertyPredicate = (codePoint) => getCategory(codePoint) === "Ll";
173
+
174
+ const isUpperCase: PropertyPredicate = (codePoint) => getCategory(codePoint) === "Lu";
175
+
176
+ const isTitleCase: PropertyPredicate = (codePoint) => getCategory(codePoint) === "Lt";
177
+
178
+ const isWhiteSpace: PropertyPredicate = (codePoint) => {
179
+ const category = getCategory(codePoint);
180
+ return category === "Zs" || category === "Zl" || category === "Zp";
181
+ };
182
+
183
+ const isBaseForm: PropertyPredicate = (codePoint) => {
184
+ const category = getCategory(codePoint);
185
+ return (
186
+ category === "Nd" ||
187
+ category === "No" ||
188
+ category === "Nl" ||
189
+ category === "Lu" ||
190
+ category === "Ll" ||
191
+ category === "Lt" ||
192
+ category === "Lm" ||
193
+ category === "Lo" ||
194
+ category === "Me" ||
195
+ category === "Mc"
196
+ );
197
+ };
198
+
199
+ const isMark: PropertyPredicate = (codePoint) => {
200
+ const category = getCategory(codePoint);
201
+ return category === "Mn" || category === "Me" || category === "Mc";
202
+ };
203
+
204
+ instance = {
205
+ getCategory,
206
+ getCombiningClass,
207
+ getScript,
208
+ getEastAsianWidth,
209
+ getNumericValue,
210
+ isAlphabetic,
211
+ isDigit,
212
+ isPunctuation,
213
+ isLowerCase,
214
+ isUpperCase,
215
+ isTitleCase,
216
+ isWhiteSpace,
217
+ isBaseForm,
218
+ isMark,
219
+ };
220
+
221
+ return instance;
222
+ })();
223
+
224
+ return initPromise;
225
+ }
226
+
227
+ /**
228
+ * Checks if unicode-properties has been initialized.
229
+ */
230
+ export function isInitialized(): boolean {
231
+ return instance !== null;
232
+ }
233
+
234
+ /**
235
+ * Gets the initialized instance. Throws if not initialized.
236
+ * Use this after calling createUnicodeProperties().
237
+ */
238
+ export function getUnicodeProperties(): UnicodePropertiesAPI {
239
+ if (!instance) {
240
+ throw new Error(
241
+ "unicode-properties not initialized. Call createUnicodeProperties() first and await its result.",
242
+ );
243
+ }
244
+ return instance;
245
+ }
246
+
247
+ /**
248
+ * Proxy object that provides sync access to unicode-properties after initialization.
249
+ * Will throw if accessed before createUnicodeProperties() resolves.
250
+ */
251
+ export const unicode: UnicodePropertiesAPI = new Proxy({} as UnicodePropertiesAPI, {
252
+ get(_target, prop: keyof UnicodePropertiesAPI) {
253
+ if (!instance) {
254
+ throw new Error(
255
+ `unicode-properties not initialized. Call createUnicodeProperties() first before accessing '${String(prop)}'.`,
256
+ );
257
+ }
258
+ return instance[prop];
259
+ },
260
+ });
261
+
262
+ export default createUnicodeProperties;
package/src/trie.js ADDED
@@ -0,0 +1,2 @@
1
+ const payload = "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";
2
+ export default payload;
@@ -0,0 +1,91 @@
1
+ import { beforeAll, describe, expect, test } from "vitest";
2
+ import createUnicodeProperties, { type UnicodePropertiesAPI } from "../src/index.js";
3
+
4
+ const code = (char: string) => char.charCodeAt(0);
5
+
6
+ describe("unicode-properties", () => {
7
+ let unicode: UnicodePropertiesAPI;
8
+
9
+ beforeAll(async () => {
10
+ unicode = await createUnicodeProperties();
11
+ });
12
+
13
+ test("getCategory", () => {
14
+ expect(unicode.getCategory(code("2"))).toBe("Nd");
15
+ expect(unicode.getCategory(code("x"))).toBe("Ll");
16
+ });
17
+
18
+ test("getCombiningClass", () => {
19
+ expect(unicode.getCombiningClass(code("x"))).toBe("Not_Reordered");
20
+ expect(unicode.getCombiningClass(code("́"))).toBe("Above");
21
+ expect(unicode.getCombiningClass(code("ٕ"))).toBe("Below");
22
+ expect(unicode.getCombiningClass(code("ٔ"))).toBe("Above");
23
+ });
24
+
25
+ test("getScript", () => {
26
+ expect(unicode.getScript(code("x"))).toBe("Latin");
27
+ expect(unicode.getScript(code("غ"))).toBe("Arabic");
28
+ });
29
+
30
+ test("getEastAsianWidth", () => {
31
+ expect(unicode.getEastAsianWidth(code("x"))).toBe("Na");
32
+ expect(unicode.getEastAsianWidth(code("杜"))).toBe("W");
33
+ expect(unicode.getEastAsianWidth(code("Æ"))).toBe("A");
34
+ });
35
+
36
+ test("getNumericValue", () => {
37
+ expect(unicode.getNumericValue(code("2"))).toBe(2);
38
+ expect(unicode.getNumericValue(code("x"))).toBeNull();
39
+ });
40
+
41
+ test("isAlphabetic", () => {
42
+ expect(unicode.isAlphabetic(code("x"))).toBe(true);
43
+ expect(unicode.isAlphabetic(code("2"))).toBe(false);
44
+ });
45
+
46
+ test("isDigit", () => {
47
+ expect(unicode.isDigit(code("x"))).toBe(false);
48
+ expect(unicode.isDigit(code("2"))).toBe(true);
49
+ });
50
+
51
+ test("isPunctuation", () => {
52
+ expect(unicode.isPunctuation(code("x"))).toBe(false);
53
+ expect(unicode.isPunctuation(code("."))).toBe(true);
54
+ });
55
+
56
+ test("isLowerCase", () => {
57
+ expect(unicode.isLowerCase(code("X"))).toBe(false);
58
+ expect(unicode.isLowerCase(code("2"))).toBe(false);
59
+ expect(unicode.isLowerCase(code("x"))).toBe(true);
60
+ });
61
+
62
+ test("isUpperCase", () => {
63
+ expect(unicode.isUpperCase(code("X"))).toBe(true);
64
+ expect(unicode.isUpperCase(code("2"))).toBe(false);
65
+ expect(unicode.isUpperCase(code("x"))).toBe(false);
66
+ });
67
+
68
+ test("isTitleCase", () => {
69
+ expect(unicode.isTitleCase(code("Dz"))).toBe(true);
70
+ expect(unicode.isTitleCase(code("2"))).toBe(false);
71
+ expect(unicode.isTitleCase(code("x"))).toBe(false);
72
+ });
73
+
74
+ test("isWhiteSpace", () => {
75
+ expect(unicode.isWhiteSpace(code(" "))).toBe(true);
76
+ expect(unicode.isWhiteSpace(code("2"))).toBe(false);
77
+ expect(unicode.isWhiteSpace(code("x"))).toBe(false);
78
+ });
79
+
80
+ test("isBaseForm", () => {
81
+ expect(unicode.isBaseForm(code("2"))).toBe(true);
82
+ expect(unicode.isBaseForm(code("x"))).toBe(true);
83
+ expect(unicode.isBaseForm(code("́"))).toBe(false);
84
+ });
85
+
86
+ test("isMark", () => {
87
+ expect(unicode.isMark(code("2"))).toBe(false);
88
+ expect(unicode.isMark(code("x"))).toBe(false);
89
+ expect(unicode.isMark(code("́"))).toBe(true);
90
+ });
91
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "allowJs": true,
5
+ "rootDir": "src",
6
+ "outDir": "dist"
7
+ },
8
+ "include": ["src/**/*.ts", "src/**/*.js"],
9
+ "exclude": ["dist", "node_modules", "test"]
10
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "noEmit": true,
5
+ "rootDir": "."
6
+ },
7
+ "include": [
8
+ "**/*.ts",
9
+ ],
10
+ "exclude": [
11
+ "dist",
12
+ "node_modules",
13
+ "src/data.js",
14
+ "src/trie.js"
15
+ ]
16
+ }
@@ -0,0 +1,12 @@
1
+ import { defineConfig } from "vitest/config";
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ environment: "node",
6
+ include: ["test/**/*.test.ts"],
7
+ coverage: {
8
+ provider: "v8",
9
+ reporter: ["text", "lcov"],
10
+ },
11
+ },
12
+ });