ipa-core 1.1.1 → 1.1.12

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.
File without changes
File without changes
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "ipa-core",
3
- "version": "1.1.1",
3
+ "version": "1.1.12",
4
4
  "description": "Language-agnostic IPA core with features",
5
5
  "license": "ISC",
6
6
  "author": "Cody Bruno",
7
7
  "type": "commonjs",
8
8
  "bin": {
9
- "make-conlang": "./generate-conlang.cjs",
10
- "ipa-init": "./generate-config.cjs"
9
+ "make-conlang": "generate-conlang.js",
10
+ "ipa-init": "generate-config.js"
11
11
  },
12
12
  "main": "index.js",
13
13
  "scripts": {
@@ -1,131 +0,0 @@
1
- #!/usr/bin/env node
2
- // generate-config-cli.cjs
3
-
4
- const fs = require('fs');
5
- const path = require('path');
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
9
-
10
- // -----------------------------
11
- // GROUP IPA SYMBOLS BY TYPE
12
- // -----------------------------
13
- function groupByType(core) {
14
- const groups = {};
15
- for (const [symbol, data] of Object.entries(core)) {
16
- const type = data.type || 'other';
17
- if (!groups[type]) groups[type] = [];
18
- groups[type].push(symbol);
19
- }
20
- return groups;
21
- }
22
-
23
- // -----------------------------
24
- // WRAP SYMBOL LINES
25
- // -----------------------------
26
- function wrapSymbols(symbols, perLine = 12) {
27
- const lines = [];
28
- for (let i = 0; i < symbols.length; i += perLine) {
29
- lines.push('// ' + symbols.slice(i, i + perLine).join(' '));
30
- }
31
- return lines.join('\n');
32
- }
33
-
34
- // -----------------------------
35
- // IPA SECTION
36
- // -----------------------------
37
- function generateIPASection(core) {
38
- const grouped = groupByType(core);
39
- const sections = Object.entries(grouped).map(([type, symbols]) => {
40
- symbols.sort((a, b) => a.localeCompare(b));
41
- return [`// ${type.toUpperCase()}`, wrapSymbols(symbols), ''].join('\n');
42
- });
43
- return ['/**', ' * IPA SYMBOL REFERENCE', ' * Copy/paste symbols as needed', '', ...sections].join('\n');
44
- }
45
-
46
- // -----------------------------
47
- // WRAP MODIFIERS HORIZONTALLY
48
- // -----------------------------
49
- function wrapModifiers(modList, maxLineLength = 90) {
50
- const lines = [];
51
- let currentLine = '// ';
52
- modList.forEach((mod, index) => {
53
- const separator = index === 0 ? '' : ' | ';
54
- const nextChunk = separator + mod;
55
- if ((currentLine + nextChunk).length > maxLineLength) {
56
- lines.push(currentLine);
57
- currentLine = '// ' + mod;
58
- } else {
59
- currentLine += nextChunk;
60
- }
61
- });
62
- if (currentLine.trim()) lines.push(currentLine);
63
- return lines.join('\n');
64
- }
65
-
66
- // -----------------------------
67
- // MODIFIER SECTION
68
- // -----------------------------
69
- function generateModifierSection(modifiers) {
70
- const entries = Object.entries(modifiers);
71
- entries.sort(([a], [b]) => a.localeCompare(b));
72
- const formatted = entries.map(([key, data]) => {
73
- const appliesTo = Array.isArray(data.appliesTo) ? data.appliesTo.join(', ') : data.appliesTo || '';
74
- return `${key}(${appliesTo})`;
75
- });
76
- return ['/**', ' * MODIFIER REFERENCE', ' * modifier(appliesTo)', ' */', '', wrapModifiers(formatted), ''].join('\n');
77
- }
78
-
79
- // -----------------------------
80
- // ORTHOGRAPHY EXPORT SECTION
81
- // -----------------------------
82
- function generateOrthographyExport() {
83
- const commentedOrthography = [
84
- '// k: ["k", ["aspirated"]],',
85
- '// a: ["ɑ", ["more_rounded"]],',
86
- '// x̱: [',
87
- '// ["k", ["ejective", "aspirated"]],',
88
- '// ["x", []]',
89
- '// ],',
90
- '// l: ["ɬ"]'
91
- ].join('\n');
92
-
93
- return [
94
- '/**',
95
- ' * ORTHOGRAPHY CONFIG',
96
- ' * Use parseConfig() at runtime',
97
- ' *',
98
- ' * Fill in your orthography below; examples are commented out.',
99
- ' */',
100
- '',
101
- "const { parseConfig } = require('./parser.cjs');",
102
- '',
103
- 'const orthography = {',
104
- commentedOrthography,
105
- '};',
106
- '',
107
- 'module.exports = parseConfig(orthography);',
108
- ''
109
- ].join('\n');
110
- }
111
-
112
- // -----------------------------
113
- // MAIN GENERATOR
114
- // -----------------------------
115
- function generateConfig() {
116
- const content = [
117
- generateIPASection(core),
118
- '',
119
- generateModifierSection(modifiers),
120
- '',
121
- generateOrthographyExport()
122
- ].join('\n');
123
-
124
- const outputPath = path.join(process.cwd(), 'ipa.config.js');
125
- fs.writeFileSync(outputPath, content, 'utf-8');
126
-
127
- console.log('✅ ipa.config.js generated with parseConfig() export');
128
- }
129
-
130
- // RUN
131
- generateConfig();
@@ -1,125 +0,0 @@
1
- #!/usr/bin/env node
2
- // generate-conlang-cli.cjs
3
-
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
10
-
11
- /** Pick random element */
12
- const pickRandom = (arr) => arr[Math.floor(Math.random() * arr.length)];
13
-
14
- /** Shuffle array */
15
- const shuffle = (arr) => {
16
- for (let i = arr.length - 1; i > 0; i--) {
17
- const j = Math.floor(Math.random() * (i + 1));
18
- [arr[i], arr[j]] = [arr[j], arr[i]];
19
- }
20
- return arr;
21
- };
22
-
23
- /** Prompt helper */
24
- function prompt(query) {
25
- const rl = readline.createInterface({
26
- input: process.stdin,
27
- output: process.stdout,
28
- });
29
- return new Promise((resolve) =>
30
- rl.question(query, (ans) => {
31
- rl.close();
32
- resolve(ans);
33
- })
34
- );
35
- }
36
-
37
- /** Generate conlang orthography */
38
- function generateConlang({ alphabet, mod1Chance, mod2Chance, affricateChance }) {
39
- const letters = alphabet.split('');
40
- const usedIPA = new Set();
41
- const orthography = {};
42
- const coreKeys = shuffle(Object.keys(core));
43
-
44
- letters.forEach((letter) => {
45
- // Pick unused IPA
46
- let ipaKey;
47
- while (true) {
48
- const candidate = pickRandom(coreKeys);
49
- if (!usedIPA.has(candidate)) {
50
- ipaKey = candidate;
51
- usedIPA.add(candidate);
52
- break;
53
- }
54
- }
55
-
56
- const baseObj = core[ipaKey];
57
- const modifiersList = [];
58
-
59
- // Modifier 1
60
- if (Math.random() < mod1Chance) {
61
- const compatible = Object.entries(modifiers).filter(
62
- ([, mod]) => !mod.appliesTo || mod.appliesTo.includes(baseObj?.type)
63
- );
64
- if (compatible.length) modifiersList.push(pickRandom(compatible)[0]);
65
- }
66
-
67
- // Modifier 2
68
- if (Math.random() < mod2Chance && modifiersList.length) {
69
- const compatible = Object.entries(modifiers).filter(
70
- ([key, mod]) =>
71
- !modifiersList.includes(key) &&
72
- (!mod.appliesTo || mod.appliesTo.includes(baseObj?.type))
73
- );
74
- if (compatible.length) modifiersList.push(pickRandom(compatible)[0]);
75
- }
76
-
77
- // Plosive → affricate
78
- if (baseObj?.features?.manner === 'plosive' && Math.random() < affricateChance) {
79
- const fricatives = Object.entries(core).filter(
80
- ([, obj]) =>
81
- obj?.features?.manner === 'fricative' &&
82
- obj.features.place === baseObj.features.place
83
- );
84
- if (fricatives.length) {
85
- const fricKey = pickRandom(fricatives)[0];
86
- orthography[letter] = [
87
- [ipaKey, modifiersList],
88
- [fricKey, []],
89
- ];
90
- return;
91
- }
92
- }
93
-
94
- orthography[letter] = [ipaKey, modifiersList];
95
- });
96
-
97
- return orthography;
98
- }
99
-
100
- /** Main async function */
101
- async function main() {
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');
106
-
107
- const orthography = generateConlang({
108
- alphabet,
109
- mod1Chance: mod1,
110
- mod2Chance: mod2,
111
- affricateChance: aff,
112
- });
113
-
114
- const outPath = path.join(process.cwd(), 'generatedConlang.js');
115
- const lines = Object.entries(orthography).map(
116
- ([l, v]) => ` ${JSON.stringify(l)}:${JSON.stringify(v)}`
117
- );
118
-
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');
123
- }
124
-
125
- main();