pravapis 0.1.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.
@@ -0,0 +1,146 @@
1
+ type Direction = "narkamauka_to_taraskievica" | "taraskievica_to_narkamauka";
2
+ type Alternation = "l" | "i" | "e" | "g" | "eu";
3
+ interface RuleTestCase {
4
+ input: string;
5
+ expected: string;
6
+ }
7
+ interface RuleJson {
8
+ id: string;
9
+ description: string;
10
+ citation: string;
11
+ direction: Direction;
12
+ /** JS RegExp source, already translated from the Python dialect. Absent for a
13
+ * function-based rule. */
14
+ pattern?: string;
15
+ /** JS replacement template ($1, $<name>, $$ for a literal $). Only with `pattern`. */
16
+ replacement?: string;
17
+ /** 'module:callable' — unimplemented here. A port must supply this behaviour by
18
+ * hand; see rules.schema.json. */
19
+ function?: string;
20
+ priority: number;
21
+ repeat: boolean;
22
+ optional: boolean;
23
+ requires: string[];
24
+ exceptions: string[];
25
+ requiresClass?: "loan" | "native";
26
+ alternation?: Alternation;
27
+ tests: {
28
+ positive: RuleTestCase[];
29
+ negative: RuleTestCase[];
30
+ };
31
+ }
32
+ interface StemRow {
33
+ stem: string;
34
+ anchored: boolean;
35
+ class: "loan" | "native";
36
+ alternations: Alternation[];
37
+ forwardOnly: Alternation[];
38
+ source: string;
39
+ provenance: "cited" | "reviewed" | "derived" | "uncertain";
40
+ target: string | null;
41
+ }
42
+ interface FunctionWordRow {
43
+ form: string;
44
+ role: "particle_n2t" | "particle_t2n" | "softening_preposition" | "clitic" | "stressed_initial_u" | "dative_locative_preposition";
45
+ target: string | null;
46
+ citation: string;
47
+ }
48
+ interface CaseFormsRow {
49
+ genitive: string;
50
+ dativeLocative: string;
51
+ }
52
+ /** One lexicon TSV, indexed both ways. `n2t`/`t2n` are independent maps (not
53
+ * inverses of each other): a row's optional third column can restrict it to one
54
+ * direction, so a key present in `n2t` need not be present in `t2n` at all, and
55
+ * `t2n`'s keys are the file's taraskievica column, not `n2t`'s values reversed. */
56
+ interface DirectedPairs {
57
+ n2t: Record<string, string>;
58
+ t2n: Record<string, string>;
59
+ }
60
+ interface CoreData {
61
+ schema: "tag:pravapis,2026:schema:js-core:1";
62
+ dataVersion: string;
63
+ dataHash: string;
64
+ rules: RuleJson[];
65
+ stems: StemRow[];
66
+ /** data/lexicon/loanwords.tsv. */
67
+ loanwords: DirectedPairs;
68
+ /** data/lexicon/exceptions.tsv. */
69
+ exceptions: DirectedPairs;
70
+ /** narkamauka -> {genitive, dativeLocative} (data/lexicon/case/ambiguous.tsv). */
71
+ caseForms: Record<string, CaseFormsRow>;
72
+ functionWords: FunctionWordRow[];
73
+ /** Lemmas of the -мент/-мэнт alternation (morphology/ment_lemmas.marisa, decoded at
74
+ * build time — see lib/marisa-bridge.ts). Small (116 keys), unlike the stress
75
+ * tables, which this build does not decode; see js/src/rules/morphology.ts. */
76
+ mentLemmas: string[];
77
+ }
78
+ interface TranslitMapping {
79
+ from: string;
80
+ to: string;
81
+ when: string;
82
+ lossy: boolean;
83
+ }
84
+ interface TranslitScheme {
85
+ scheme: string;
86
+ description: string;
87
+ source: string;
88
+ reverseOf?: string;
89
+ mappings: TranslitMapping[];
90
+ tests: RuleTestCase[];
91
+ }
92
+ interface TranslitData {
93
+ schema: "tag:pravapis,2026:schema:js-translit:1";
94
+ dataVersion: string;
95
+ dataHash: string;
96
+ schemes: Record<string, TranslitScheme>;
97
+ }
98
+
99
+ type Orthography = "narkamauka" | "taraskievica";
100
+ type Script = "cyrillic" | "lacinka" | "official";
101
+ type Method = "identity" | "lexicon" | "rule" | "model" | "unknown";
102
+ /** Why a *cross-word* rule fired: what it looked at outside the word itself. Populated
103
+ * only for rules that read a neighbouring word — null positively means the change is
104
+ * reproducible from the word alone. */
105
+ interface ChangeContext {
106
+ trigger: "prev_word_vowel" | "prev_word" | "next_word";
107
+ across?: string;
108
+ rule?: string;
109
+ }
110
+ interface Conversion {
111
+ source: string;
112
+ target: string;
113
+ method: Method;
114
+ ruleId: string | null;
115
+ confidence: number;
116
+ /** Code-point offset of `target` in the **output** text; -1 until assigned. */
117
+ start: number;
118
+ end: number;
119
+ citation: string | null;
120
+ context: ChangeContext | null;
121
+ }
122
+ interface ConversionResult {
123
+ text: string;
124
+ conversions: readonly Conversion[];
125
+ stats: Record<Method, number>;
126
+ direction: Orthography;
127
+ unresolved: readonly string[];
128
+ }
129
+ /** The frozen public wire shape — identical across every implementation of pravapis.
130
+ * See docs/API.md. */
131
+ declare function conversionResultToDict(result: ConversionResult, engineVersion: string, dataVersion: string): Record<string, unknown>;
132
+ interface RuleTrace {
133
+ ruleId: string;
134
+ before: string;
135
+ after: string;
136
+ }
137
+ interface TokenExplanation {
138
+ source: string;
139
+ target: string;
140
+ method: Method;
141
+ ruleId: string | null;
142
+ confidence: number;
143
+ traces: readonly RuleTrace[];
144
+ }
145
+
146
+ export { type Alternation as A, type Conversion as C, type DirectedPairs as D, type FunctionWordRow as F, type Method as M, type Orthography as O, type RuleJson as R, type StemRow as S, type TokenExplanation as T, type ConversionResult as a, type CaseFormsRow as b, conversionResultToDict as c, type CoreData as d, type TranslitScheme as e, type Script as f, type TranslitData as g };
@@ -0,0 +1,146 @@
1
+ type Direction = "narkamauka_to_taraskievica" | "taraskievica_to_narkamauka";
2
+ type Alternation = "l" | "i" | "e" | "g" | "eu";
3
+ interface RuleTestCase {
4
+ input: string;
5
+ expected: string;
6
+ }
7
+ interface RuleJson {
8
+ id: string;
9
+ description: string;
10
+ citation: string;
11
+ direction: Direction;
12
+ /** JS RegExp source, already translated from the Python dialect. Absent for a
13
+ * function-based rule. */
14
+ pattern?: string;
15
+ /** JS replacement template ($1, $<name>, $$ for a literal $). Only with `pattern`. */
16
+ replacement?: string;
17
+ /** 'module:callable' — unimplemented here. A port must supply this behaviour by
18
+ * hand; see rules.schema.json. */
19
+ function?: string;
20
+ priority: number;
21
+ repeat: boolean;
22
+ optional: boolean;
23
+ requires: string[];
24
+ exceptions: string[];
25
+ requiresClass?: "loan" | "native";
26
+ alternation?: Alternation;
27
+ tests: {
28
+ positive: RuleTestCase[];
29
+ negative: RuleTestCase[];
30
+ };
31
+ }
32
+ interface StemRow {
33
+ stem: string;
34
+ anchored: boolean;
35
+ class: "loan" | "native";
36
+ alternations: Alternation[];
37
+ forwardOnly: Alternation[];
38
+ source: string;
39
+ provenance: "cited" | "reviewed" | "derived" | "uncertain";
40
+ target: string | null;
41
+ }
42
+ interface FunctionWordRow {
43
+ form: string;
44
+ role: "particle_n2t" | "particle_t2n" | "softening_preposition" | "clitic" | "stressed_initial_u" | "dative_locative_preposition";
45
+ target: string | null;
46
+ citation: string;
47
+ }
48
+ interface CaseFormsRow {
49
+ genitive: string;
50
+ dativeLocative: string;
51
+ }
52
+ /** One lexicon TSV, indexed both ways. `n2t`/`t2n` are independent maps (not
53
+ * inverses of each other): a row's optional third column can restrict it to one
54
+ * direction, so a key present in `n2t` need not be present in `t2n` at all, and
55
+ * `t2n`'s keys are the file's taraskievica column, not `n2t`'s values reversed. */
56
+ interface DirectedPairs {
57
+ n2t: Record<string, string>;
58
+ t2n: Record<string, string>;
59
+ }
60
+ interface CoreData {
61
+ schema: "tag:pravapis,2026:schema:js-core:1";
62
+ dataVersion: string;
63
+ dataHash: string;
64
+ rules: RuleJson[];
65
+ stems: StemRow[];
66
+ /** data/lexicon/loanwords.tsv. */
67
+ loanwords: DirectedPairs;
68
+ /** data/lexicon/exceptions.tsv. */
69
+ exceptions: DirectedPairs;
70
+ /** narkamauka -> {genitive, dativeLocative} (data/lexicon/case/ambiguous.tsv). */
71
+ caseForms: Record<string, CaseFormsRow>;
72
+ functionWords: FunctionWordRow[];
73
+ /** Lemmas of the -мент/-мэнт alternation (morphology/ment_lemmas.marisa, decoded at
74
+ * build time — see lib/marisa-bridge.ts). Small (116 keys), unlike the stress
75
+ * tables, which this build does not decode; see js/src/rules/morphology.ts. */
76
+ mentLemmas: string[];
77
+ }
78
+ interface TranslitMapping {
79
+ from: string;
80
+ to: string;
81
+ when: string;
82
+ lossy: boolean;
83
+ }
84
+ interface TranslitScheme {
85
+ scheme: string;
86
+ description: string;
87
+ source: string;
88
+ reverseOf?: string;
89
+ mappings: TranslitMapping[];
90
+ tests: RuleTestCase[];
91
+ }
92
+ interface TranslitData {
93
+ schema: "tag:pravapis,2026:schema:js-translit:1";
94
+ dataVersion: string;
95
+ dataHash: string;
96
+ schemes: Record<string, TranslitScheme>;
97
+ }
98
+
99
+ type Orthography = "narkamauka" | "taraskievica";
100
+ type Script = "cyrillic" | "lacinka" | "official";
101
+ type Method = "identity" | "lexicon" | "rule" | "model" | "unknown";
102
+ /** Why a *cross-word* rule fired: what it looked at outside the word itself. Populated
103
+ * only for rules that read a neighbouring word — null positively means the change is
104
+ * reproducible from the word alone. */
105
+ interface ChangeContext {
106
+ trigger: "prev_word_vowel" | "prev_word" | "next_word";
107
+ across?: string;
108
+ rule?: string;
109
+ }
110
+ interface Conversion {
111
+ source: string;
112
+ target: string;
113
+ method: Method;
114
+ ruleId: string | null;
115
+ confidence: number;
116
+ /** Code-point offset of `target` in the **output** text; -1 until assigned. */
117
+ start: number;
118
+ end: number;
119
+ citation: string | null;
120
+ context: ChangeContext | null;
121
+ }
122
+ interface ConversionResult {
123
+ text: string;
124
+ conversions: readonly Conversion[];
125
+ stats: Record<Method, number>;
126
+ direction: Orthography;
127
+ unresolved: readonly string[];
128
+ }
129
+ /** The frozen public wire shape — identical across every implementation of pravapis.
130
+ * See docs/API.md. */
131
+ declare function conversionResultToDict(result: ConversionResult, engineVersion: string, dataVersion: string): Record<string, unknown>;
132
+ interface RuleTrace {
133
+ ruleId: string;
134
+ before: string;
135
+ after: string;
136
+ }
137
+ interface TokenExplanation {
138
+ source: string;
139
+ target: string;
140
+ method: Method;
141
+ ruleId: string | null;
142
+ confidence: number;
143
+ traces: readonly RuleTrace[];
144
+ }
145
+
146
+ export { type Alternation as A, type Conversion as C, type DirectedPairs as D, type FunctionWordRow as F, type Method as M, type Orthography as O, type RuleJson as R, type StemRow as S, type TokenExplanation as T, type ConversionResult as a, type CaseFormsRow as b, conversionResultToDict as c, type CoreData as d, type TranslitScheme as e, type Script as f, type TranslitData as g };
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "pravapis",
3
+ "version": "0.1.0",
4
+ "description": "Bidirectional Narkamaŭka ↔ Taraškievica Belarusian orthography converter, plus Cyrillic ↔ Łacinka transliteration",
5
+ "keywords": [
6
+ "belarusian",
7
+ "taraskievica",
8
+ "narkamauka",
9
+ "orthography",
10
+ "transliteration",
11
+ "cyrillic",
12
+ "lacinka",
13
+ "nlp"
14
+ ],
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/sewstie/pravapis.git",
18
+ "directory": "js"
19
+ },
20
+ "license": "MIT",
21
+ "type": "module",
22
+ "sideEffects": false,
23
+ "engines": {
24
+ "node": ">=18"
25
+ },
26
+ "exports": {
27
+ ".": {
28
+ "import": { "types": "./dist/index.d.ts", "default": "./dist/index.js" },
29
+ "require": { "types": "./dist/index.d.cts", "default": "./dist/index.cjs" }
30
+ },
31
+ "./translit": {
32
+ "import": { "types": "./dist/translit.d.ts", "default": "./dist/translit.js" },
33
+ "require": { "types": "./dist/translit.d.cts", "default": "./dist/translit.cjs" }
34
+ },
35
+ "./names": {
36
+ "import": { "types": "./dist/names.d.ts", "default": "./dist/names.js" },
37
+ "require": { "types": "./dist/names.d.cts", "default": "./dist/names.cjs" }
38
+ },
39
+ "./package.json": "./package.json"
40
+ },
41
+ "main": "./dist/index.cjs",
42
+ "module": "./dist/index.js",
43
+ "types": "./dist/index.d.ts",
44
+ "files": [
45
+ "dist"
46
+ ],
47
+ "scripts": {
48
+ "build-data": "tsx scripts/build-data.ts",
49
+ "build": "npm run build-data && tsup",
50
+ "typecheck": "tsc --noEmit",
51
+ "test": "tsx scripts/test-conformance.ts",
52
+ "prepack": "npm run build"
53
+ },
54
+ "devDependencies": {
55
+ "@types/js-yaml": "^4.0.9",
56
+ "@types/node": "^22.10.2",
57
+ "ajv": "^8.17.1",
58
+ "js-yaml": "^4.1.0",
59
+ "tsup": "^8.5.1",
60
+ "tsx": "^4.19.2",
61
+ "typescript": "^5.7.2"
62
+ }
63
+ }