ipa-core 1.0.8 → 1.0.99
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/core.js +1 -1
- package/generate-config.js +11 -51
- package/generate-conlang.js +19 -16
- package/index.js +15 -6
- package/modifiers.js +1 -1
- package/package.json +2 -2
- package/parser.js +4 -4
- package/generate-config-cli.js +0 -7
- package/generate-conlang-cli.js +0 -8
package/core.js
CHANGED
package/generate-config.js
CHANGED
|
@@ -1,29 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// generate-config.
|
|
2
|
+
// generate-config-cli.cjs
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import core from './core.js';
|
|
8
|
-
import modifiers from './modifiers.js';
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
9
6
|
|
|
7
|
+
const core = require('./core.cjs'); // your ES6 exports can stay; if core.js is ES module, you can require with .default
|
|
8
|
+
const modifiers = require('./modifiers.cjs'); // same as above
|
|
10
9
|
|
|
11
10
|
// -----------------------------
|
|
12
11
|
// GROUP IPA SYMBOLS BY TYPE
|
|
13
12
|
// -----------------------------
|
|
14
13
|
function groupByType(core) {
|
|
15
14
|
const groups = {};
|
|
16
|
-
|
|
17
15
|
for (const [symbol, data] of Object.entries(core)) {
|
|
18
16
|
const type = data.type || 'other';
|
|
19
17
|
if (!groups[type]) groups[type] = [];
|
|
20
18
|
groups[type].push(symbol);
|
|
21
19
|
}
|
|
22
|
-
|
|
23
20
|
return groups;
|
|
24
21
|
}
|
|
25
22
|
|
|
26
|
-
|
|
27
23
|
// -----------------------------
|
|
28
24
|
// WRAP SYMBOL LINES
|
|
29
25
|
// -----------------------------
|
|
@@ -35,45 +31,27 @@ function wrapSymbols(symbols, perLine = 12) {
|
|
|
35
31
|
return lines.join('\n');
|
|
36
32
|
}
|
|
37
33
|
|
|
38
|
-
|
|
39
34
|
// -----------------------------
|
|
40
35
|
// IPA SECTION
|
|
41
36
|
// -----------------------------
|
|
42
37
|
function generateIPASection(core) {
|
|
43
38
|
const grouped = groupByType(core);
|
|
44
|
-
|
|
45
39
|
const sections = Object.entries(grouped).map(([type, symbols]) => {
|
|
46
40
|
symbols.sort((a, b) => a.localeCompare(b));
|
|
47
|
-
|
|
48
|
-
return [
|
|
49
|
-
`// ${type.toUpperCase()}`,
|
|
50
|
-
wrapSymbols(symbols),
|
|
51
|
-
''
|
|
52
|
-
].join('\n');
|
|
41
|
+
return [`// ${type.toUpperCase()}`, wrapSymbols(symbols), ''].join('\n');
|
|
53
42
|
});
|
|
54
|
-
|
|
55
|
-
return [
|
|
56
|
-
'/**',
|
|
57
|
-
' * IPA SYMBOL REFERENCE',
|
|
58
|
-
' * Copy/paste symbols as needed',
|
|
59
|
-
' */',
|
|
60
|
-
'',
|
|
61
|
-
...sections
|
|
62
|
-
].join('\n');
|
|
43
|
+
return ['/**', ' * IPA SYMBOL REFERENCE', ' * Copy/paste symbols as needed', '', ...sections].join('\n');
|
|
63
44
|
}
|
|
64
45
|
|
|
65
|
-
|
|
66
46
|
// -----------------------------
|
|
67
47
|
// WRAP MODIFIERS HORIZONTALLY
|
|
68
48
|
// -----------------------------
|
|
69
49
|
function wrapModifiers(modList, maxLineLength = 90) {
|
|
70
50
|
const lines = [];
|
|
71
51
|
let currentLine = '// ';
|
|
72
|
-
|
|
73
52
|
modList.forEach((mod, index) => {
|
|
74
53
|
const separator = index === 0 ? '' : ' | ';
|
|
75
54
|
const nextChunk = separator + mod;
|
|
76
|
-
|
|
77
55
|
if ((currentLine + nextChunk).length > maxLineLength) {
|
|
78
56
|
lines.push(currentLine);
|
|
79
57
|
currentLine = '// ' + mod;
|
|
@@ -81,39 +59,23 @@ function wrapModifiers(modList, maxLineLength = 90) {
|
|
|
81
59
|
currentLine += nextChunk;
|
|
82
60
|
}
|
|
83
61
|
});
|
|
84
|
-
|
|
85
62
|
if (currentLine.trim()) lines.push(currentLine);
|
|
86
|
-
|
|
87
63
|
return lines.join('\n');
|
|
88
64
|
}
|
|
89
65
|
|
|
90
|
-
|
|
91
66
|
// -----------------------------
|
|
92
67
|
// MODIFIER SECTION
|
|
93
68
|
// -----------------------------
|
|
94
69
|
function generateModifierSection(modifiers) {
|
|
95
70
|
const entries = Object.entries(modifiers);
|
|
96
71
|
entries.sort(([a], [b]) => a.localeCompare(b));
|
|
97
|
-
|
|
98
72
|
const formatted = entries.map(([key, data]) => {
|
|
99
|
-
const appliesTo = Array.isArray(data.appliesTo)
|
|
100
|
-
? data.appliesTo.join(', ')
|
|
101
|
-
: data.appliesTo || '';
|
|
73
|
+
const appliesTo = Array.isArray(data.appliesTo) ? data.appliesTo.join(', ') : data.appliesTo || '';
|
|
102
74
|
return `${key}(${appliesTo})`;
|
|
103
75
|
});
|
|
104
|
-
|
|
105
|
-
return [
|
|
106
|
-
'/**',
|
|
107
|
-
' * MODIFIER REFERENCE',
|
|
108
|
-
' * modifier(appliesTo)',
|
|
109
|
-
' */',
|
|
110
|
-
'',
|
|
111
|
-
wrapModifiers(formatted),
|
|
112
|
-
''
|
|
113
|
-
].join('\n');
|
|
76
|
+
return ['/**', ' * MODIFIER REFERENCE', ' * modifier(appliesTo)', ' */', '', wrapModifiers(formatted), ''].join('\n');
|
|
114
77
|
}
|
|
115
78
|
|
|
116
|
-
|
|
117
79
|
// -----------------------------
|
|
118
80
|
// ORTHOGRAPHY EXPORT SECTION
|
|
119
81
|
// -----------------------------
|
|
@@ -136,18 +98,17 @@ function generateOrthographyExport() {
|
|
|
136
98
|
' * Fill in your orthography below; examples are commented out.',
|
|
137
99
|
' */',
|
|
138
100
|
'',
|
|
139
|
-
"
|
|
101
|
+
"const { parseConfig } = require('./parser.cjs');",
|
|
140
102
|
'',
|
|
141
103
|
'const orthography = {',
|
|
142
104
|
commentedOrthography,
|
|
143
105
|
'};',
|
|
144
106
|
'',
|
|
145
|
-
'
|
|
107
|
+
'module.exports = parseConfig(orthography);',
|
|
146
108
|
''
|
|
147
109
|
].join('\n');
|
|
148
110
|
}
|
|
149
111
|
|
|
150
|
-
|
|
151
112
|
// -----------------------------
|
|
152
113
|
// MAIN GENERATOR
|
|
153
114
|
// -----------------------------
|
|
@@ -166,6 +127,5 @@ function generateConfig() {
|
|
|
166
127
|
console.log('✅ ipa.config.js generated with parseConfig() export');
|
|
167
128
|
}
|
|
168
129
|
|
|
169
|
-
|
|
170
130
|
// RUN
|
|
171
131
|
generateConfig();
|
package/generate-conlang.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
// generate-conlang-cli.cjs
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const readline = require('readline');
|
|
7
|
+
|
|
8
|
+
const core = require('./core.cjs'); // Use .default if core.js is ES module
|
|
9
|
+
const modifiers = require('./modifiers.cjs'); // Use .default if modifiers.js is ES module
|
|
8
10
|
|
|
9
11
|
/** Pick random element */
|
|
10
12
|
const pickRandom = (arr) => arr[Math.floor(Math.random() * arr.length)];
|
|
@@ -34,7 +36,7 @@ function prompt(query) {
|
|
|
34
36
|
|
|
35
37
|
/** Generate conlang orthography */
|
|
36
38
|
function generateConlang({ alphabet, mod1Chance, mod2Chance, affricateChance }) {
|
|
37
|
-
const letters = alphabet.split(
|
|
39
|
+
const letters = alphabet.split('');
|
|
38
40
|
const usedIPA = new Set();
|
|
39
41
|
const orthography = {};
|
|
40
42
|
const coreKeys = shuffle(Object.keys(core));
|
|
@@ -73,10 +75,10 @@ function generateConlang({ alphabet, mod1Chance, mod2Chance, affricateChance })
|
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
// Plosive → affricate
|
|
76
|
-
if (baseObj?.features?.manner ===
|
|
78
|
+
if (baseObj?.features?.manner === 'plosive' && Math.random() < affricateChance) {
|
|
77
79
|
const fricatives = Object.entries(core).filter(
|
|
78
80
|
([, obj]) =>
|
|
79
|
-
obj?.features?.manner ===
|
|
81
|
+
obj?.features?.manner === 'fricative' &&
|
|
80
82
|
obj.features.place === baseObj.features.place
|
|
81
83
|
);
|
|
82
84
|
if (fricatives.length) {
|
|
@@ -97,10 +99,10 @@ function generateConlang({ alphabet, mod1Chance, mod2Chance, affricateChance })
|
|
|
97
99
|
|
|
98
100
|
/** Main async function */
|
|
99
101
|
async function main() {
|
|
100
|
-
const alphabet = (await prompt(
|
|
101
|
-
const mod1 = parseFloat((await prompt(
|
|
102
|
-
const mod2 = parseFloat((await prompt(
|
|
103
|
-
const aff = parseFloat((await prompt(
|
|
102
|
+
const alphabet = (await prompt('Enter alphabet (default a-z): ')) || 'abcdefghijklmnopqrstuvwxyz';
|
|
103
|
+
const mod1 = parseFloat((await prompt('Modifier 1 chance (default 0.33): ')) || '0.33');
|
|
104
|
+
const mod2 = parseFloat((await prompt('Modifier 2 chance (default 0.06): ')) || '0.06');
|
|
105
|
+
const aff = parseFloat((await prompt('Plosive → affricate chance (default 0.1): ')) || '0.1');
|
|
104
106
|
|
|
105
107
|
const orthography = generateConlang({
|
|
106
108
|
alphabet,
|
|
@@ -109,14 +111,15 @@ async function main() {
|
|
|
109
111
|
affricateChance: aff,
|
|
110
112
|
});
|
|
111
113
|
|
|
112
|
-
const outPath = path.join(process.cwd(),
|
|
114
|
+
const outPath = path.join(process.cwd(), 'generatedConlang.js');
|
|
113
115
|
const lines = Object.entries(orthography).map(
|
|
114
116
|
([l, v]) => ` ${JSON.stringify(l)}:${JSON.stringify(v)}`
|
|
115
117
|
);
|
|
116
|
-
const content = `/** Generated conlang orthography */\nconst generatedOrthography={\n${lines.join(",\n")}\n};\nexport default generatedOrthography;`;
|
|
117
118
|
|
|
118
|
-
|
|
119
|
-
|
|
119
|
+
const content = `/** Generated conlang orthography */\nconst generatedOrthography = {\n${lines.join(',\n')}\n};\nmodule.exports = generatedOrthography;\n`;
|
|
120
|
+
|
|
121
|
+
fs.writeFileSync(outPath, content, 'utf-8');
|
|
122
|
+
console.log('✅ generatedConlang.js written');
|
|
120
123
|
}
|
|
121
124
|
|
|
122
125
|
main();
|
package/index.js
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
// Import your data layers
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
const core = require("./core.js"); // base consonants & vowels
|
|
3
|
+
const modifiers = require("./modifiers.js"); // diacritics, tones, suprasegmentals
|
|
4
|
+
const rules = require("./rules.js"); // modifier compatibility rules
|
|
5
|
+
const parser = require("./parser.js"); // parser (parsePhoneme, parseUnit, parseConfig)
|
|
6
6
|
|
|
7
7
|
// Export the layers so users can access them if needed
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
const { parsePhoneme, parseUnit, parseConfig } = parser;
|
|
9
|
+
|
|
10
|
+
module.exports = {
|
|
11
|
+
core,
|
|
12
|
+
modifiers,
|
|
13
|
+
rules,
|
|
14
|
+
parser,
|
|
15
|
+
parsePhoneme,
|
|
16
|
+
parseUnit,
|
|
17
|
+
parseConfig
|
|
18
|
+
};
|
package/modifiers.js
CHANGED
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ipa-core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.99",
|
|
4
4
|
"description": "Language-agnostic IPA core with features",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"author": "Cody Bruno",
|
|
7
|
-
"type": "
|
|
7
|
+
"type": "commonjs",
|
|
8
8
|
"bin": {
|
|
9
9
|
"make-conlang": "./generate-conlang.js",
|
|
10
10
|
"ipa-init": "./generate-config.js"
|
package/parser.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// parser.js
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
const core = require("./core");
|
|
4
|
+
const modifiers = require("./modifiers");
|
|
5
|
+
const rules = require("./rules");
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Parses a single phoneme with optional modifiers.
|
|
@@ -134,4 +134,4 @@ function parseConfig(config) {
|
|
|
134
134
|
return parsed;
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
module.exports = { parsePhoneme, parseUnit, parseConfig };
|
package/generate-config-cli.js
DELETED