lyric-romanizer 0.1.1 → 0.2.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/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![npm version](https://img.shields.io/npm/v/lyric-romanizer.svg)](https://www.npmjs.com/package/lyric-romanizer)
4
4
  [![license](https://img.shields.io/npm/l/lyric-romanizer.svg)](https://github.com/thedavidweng/lyric-romanizer/blob/main/LICENSE)
5
5
 
6
- Script detection and local romanization engine for lyrics. Supports 13 scripts across Japanese, Chinese, Korean, Cyrillic, Indic, Tamil, Thai, and Latin — all running locally with zero API calls.
6
+ Script detection and local romanization engine for lyrics. Supports 12 scripts across Japanese, Chinese (Mandarin and Cantonese), Korean, Cyrillic, Indic, Tamil, and Thai — all running locally with zero API calls.
7
7
 
8
8
  Extracted from [Spotify Karaoke](https://github.com/haroldalan/spotify-karaoke). Used by [OpenKara](https://github.com/thedavidweng/openkara).
9
9
 
@@ -63,14 +63,14 @@ type ScriptType =
63
63
  | 'devanagari' | 'gujarati' | 'gurmukhi' | 'telugu'
64
64
  | 'kannada' | 'odia' | 'tamil' | 'malayalam'
65
65
  | 'bengali' | 'arabic' | 'hebrew' | 'thai'
66
- | 'latin' | 'other';
66
+ | 'other';
67
67
 
68
68
  interface Romanizer {
69
69
  romanizeLine(line: string, options?: RomanizeOptions): Promise<string>;
70
70
  romanizeLines(lines: readonly string[], options?: RomanizeOptions): Promise<RomanizeResult>;
71
71
  }
72
72
 
73
- type RomanizeOptions = { script?: ScriptType };
73
+ type RomanizeOptions = { script?: ScriptType; dialect?: 'mandarin' | 'cantonese' };
74
74
  type RomanizeResult = { script: ScriptType; lines: string[] };
75
75
  type RomanizerOptions = { japaneseDictPath?: string };
76
76
  ```
@@ -128,11 +128,16 @@ requiresExternalRomanization('malayalam'); // true
128
128
 
129
129
  Romanizes a single line. If `script` is omitted, it is auto-detected via `detectScript`. Returns the original line unchanged for Latin text or non-letter content.
130
130
 
131
+ For Chinese text, the `dialect` option controls the romanization system: `'mandarin'` (default) uses Pinyin, `'cantonese'` uses [Jyutping](https://github.com/CanCLID/to-jyutping).
132
+
131
133
  **Throws** `UnsupportedRomanizationError` for external scripts.
132
134
 
133
135
  ```ts
134
136
  await romanizer.romanizeLine('你好世界');
135
- // 'nǐ hǎo shì jiè'
137
+ // 'nǐ hǎo shì jiè' (default: Mandarin/Pinyin)
138
+
139
+ await romanizer.romanizeLine('你好', { dialect: 'cantonese' });
140
+ // 'nei5 hou2' (Jyutping)
136
141
 
137
142
  await romanizer.romanizeLine('Привет мир');
138
143
  // 'Privet mir'
@@ -177,28 +182,49 @@ try {
177
182
 
178
183
  | Script | Engine | Example |
179
184
  |--------|--------|---------|
185
+ | Universal *(fallback)* | [transliteration](https://github.com/nickclaw/transliteration) | `Привет` → `Privet` |
180
186
  | Japanese | [kuroshiro](https://github.com/sglkc/kuroshiro-ts) + [kuromoji](https://github.com/takuyaa/kuromoji.js) | `こんにちは` → `konnichiha` |
181
- | Chinese | [pinyin-pro](https://github.com/zh-lx/pinyin-pro) | `你好` → `nǐ hǎo` |
187
+ | Mandarin | [pinyin-pro](https://github.com/zh-lx/pinyin-pro) | `你好` → `nǐ hǎo` |
188
+ | Cantonese | [to-jyutping](https://github.com/CanCLID/to-jyutping) | `佢冇` → `keoi5 mou5` |
182
189
  | Korean | [@romanize/korean](https://github.com/kntng/romanize) | `안녕` → `annyeong` |
183
190
  | Cyrillic | [cyrillic-to-translit-js](https://github.com/greybax/CyrillicToTranslitJS) | `Привет` → `Privet` |
184
- | Devanagari | [sanscript](https://github.com/indic-transliteration/sanscript.js) | `नमस्ते` → `namaste` |
185
- | Gujarati | sanscript | `નમસ્તે` → `namaste` |
186
- | Gurmukhi | sanscript | `ਨਮਸਤੇ` → `namaste` |
187
- | Telugu | sanscript | `నమస్తే` → `namaste` |
188
- | Kannada | sanscript | `ನಮಸ್ತೆ` → `namaste` |
189
- | Odia | sanscript | `ନମସ୍ତେ` → `namaste` |
191
+ | Devanagari | [sanscript](https://github.com/indic-transliteration/sanscript) | `नमस्ते` → `namaste` |
192
+ | Gujarati | [sanscript](https://github.com/indic-transliteration/sanscript) | `નમસ્તે` → `namaste` |
193
+ | Gurmukhi | [sanscript](https://github.com/indic-transliteration/sanscript) | `ਨਮਸਤੇ` → `namaste` |
194
+ | Telugu | [sanscript](https://github.com/indic-transliteration/sanscript) | `నమస్తే` → `namaste` |
195
+ | Kannada | [sanscript](https://github.com/indic-transliteration/sanscript) | `నಮస్తె` → `namaste` |
196
+ | Odia | [sanscript](https://github.com/indic-transliteration/sanscript) | `ନମସ୍ତେ` → `namaste` |
190
197
  | Tamil | [tamil-romanizer](https://github.com/haroldalan/tamil-romanizer) | `வணக்கம்` → `vanakkam` |
191
198
  | Thai | [@dehoist/romanize-thai](https://github.com/Dehoist/Open-Source) | `สวัสดี` → `sawatdi` |
192
- | Latin | *(no-op)* | `Hello` → `Hello` |
193
199
 
194
200
  ### External (requires API)
195
201
 
196
- `malayalam`, `bengali`, `arabic`, `hebrew`, `other` — use `requiresExternalRomanization()` to detect these and branch to your preferred API.
202
+ | Script | Method |
203
+ |--------|--------|
204
+ | Malayalam | Google Translate `dt=rm` |
205
+ | Bengali | Google Translate `dt=rm` |
206
+ | Arabic | Google Translate `dt=rm` |
207
+ | Hebrew | Google Translate `dt=rm` |
208
+ | Other | Google Translate `dt=rm` |
209
+
210
+ Use `requiresExternalRomanization()` to detect these and branch to your preferred API.
197
211
 
198
212
  ## Cyrillic Detection
199
213
 
200
214
  Cyrillic auto-detects Ukrainian-specific characters (`і`, `ї`, `є`, `ґ`) and applies the Ukrainian transliteration preset. All other Cyrillic text defaults to Russian.
201
215
 
216
+ ## Cantonese Support
217
+
218
+ Chinese text defaults to Mandarin (Pinyin). Pass `dialect: 'cantonese'` in `RomanizeOptions` to romanize Chinese text to [Jyutping](https://github.com/CanCLID/to-jyutping) instead.
219
+
220
+ ```ts
221
+ const { lines } = await romanizer.romanizeLines(['你好世界', '食飯'], {
222
+ script: 'chinese',
223
+ dialect: 'cantonese',
224
+ });
225
+ // ['nei5 hou2 sai3 gaai3', 'sik6 faan6']
226
+ ```
227
+
202
228
  ## License
203
229
 
204
230
  MIT
@@ -1 +1 @@
1
- {"version":3,"file":"romanizer.d.ts","sourceRoot":"","sources":["../src/romanizer.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAGV,SAAS,EACT,gBAAgB,EAChB,UAAU,EACX,MAAM,YAAY,CAAC;AAwBpB,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAExE;AAsFD,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAErE"}
1
+ {"version":3,"file":"romanizer.d.ts","sourceRoot":"","sources":["../src/romanizer.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAGV,SAAS,EACT,gBAAgB,EAChB,UAAU,EACX,MAAM,YAAY,CAAC;AAwBpB,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAExE;AA+GD,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAErE"}
package/dist/romanizer.js CHANGED
@@ -6,6 +6,7 @@ import Sanscript from '@indic-transliteration/sanscript';
6
6
  import { romanize as romanizeKorean } from '@romanize/korean';
7
7
  import romanizeThai from '@dehoist/romanize-thai';
8
8
  import { romanize as romanizeTamil } from 'tamil-romanizer';
9
+ import { transliterate } from 'transliteration';
9
10
  import { detectScript } from './detector.js';
10
11
  import { UnsupportedRomanizationError } from './types.js';
11
12
  const DEFAULT_JAPANESE_DICT_PATH = 'https://cdn.jsdelivr.net/npm/kuromoji/dict';
@@ -32,6 +33,7 @@ export function requiresExternalRomanization(script) {
32
33
  class DefaultRomanizer {
33
34
  japaneseDictPath;
34
35
  kuroshiroReady = null;
36
+ jyutpingReady = null;
35
37
  constructor(options) {
36
38
  this.japaneseDictPath = options?.japaneseDictPath ?? DEFAULT_JAPANESE_DICT_PATH;
37
39
  }
@@ -44,39 +46,56 @@ class DefaultRomanizer {
44
46
  if (requiresExternalRomanization(script)) {
45
47
  throw new UnsupportedRomanizationError(script);
46
48
  }
47
- switch (script) {
48
- case 'japanese': {
49
- const k = await this.getKuroshiro();
50
- return k.convert(line, { to: 'romaji', mode: 'spaced' });
51
- }
52
- case 'chinese':
53
- return pinyin(line, { toneType: 'symbol', type: 'string' });
54
- case 'korean':
55
- return romanizeKorean(line);
56
- case 'cyrillic':
57
- return /[іїєґ]/i.test(line)
58
- ? cyrillicTranslitUk.transform(line)
59
- : cyrillicTranslitRu.transform(line);
60
- case 'devanagari':
61
- case 'gujarati':
62
- case 'gurmukhi':
63
- case 'telugu':
64
- case 'kannada':
65
- case 'odia': {
66
- const scheme = SANSCRIPT_SCHEME[script];
67
- if (!scheme)
68
- throw new Error(`Missing Sanscript scheme mapping for '${script}'.`);
69
- if (!Sanscript.schemes?.[scheme]) {
70
- throw new Error(`Sanscript does not support scheme '${scheme}' for '${script}'.`);
49
+ try {
50
+ switch (script) {
51
+ case 'japanese': {
52
+ const k = await this.getKuroshiro();
53
+ return k.convert(line, { to: 'romaji', mode: 'spaced' });
54
+ }
55
+ case 'chinese': {
56
+ if (options?.dialect === 'cantonese') {
57
+ try {
58
+ const jyutping = await this.getJyutpingModule();
59
+ const result = jyutping.getJyutpingText(line);
60
+ if (result)
61
+ return result;
62
+ }
63
+ catch {
64
+ // fall through to pinyin
65
+ }
66
+ }
67
+ return pinyin(line, { toneType: 'symbol', type: 'string' });
71
68
  }
72
- return Sanscript.t(line, scheme, 'iast');
69
+ case 'korean':
70
+ return romanizeKorean(line);
71
+ case 'cyrillic':
72
+ return /[іїєґ]/i.test(line)
73
+ ? cyrillicTranslitUk.transform(line)
74
+ : cyrillicTranslitRu.transform(line);
75
+ case 'devanagari':
76
+ case 'gujarati':
77
+ case 'gurmukhi':
78
+ case 'telugu':
79
+ case 'kannada':
80
+ case 'odia': {
81
+ const scheme = SANSCRIPT_SCHEME[script];
82
+ if (!scheme)
83
+ throw new Error(`Missing Sanscript scheme mapping for '${script}'.`);
84
+ if (!Sanscript.schemes?.[scheme]) {
85
+ throw new Error(`Sanscript does not support scheme '${scheme}' for '${script}'.`);
86
+ }
87
+ return Sanscript.t(line, scheme, 'iast');
88
+ }
89
+ case 'tamil':
90
+ return romanizeTamil(line);
91
+ case 'thai':
92
+ return romanizeThai(line);
93
+ default:
94
+ return transliterate(line);
73
95
  }
74
- case 'tamil':
75
- return romanizeTamil(line);
76
- case 'thai':
77
- return romanizeThai(line);
78
- default:
79
- throw new UnsupportedRomanizationError(script);
96
+ }
97
+ catch {
98
+ return transliterate(line);
80
99
  }
81
100
  }
82
101
  async romanizeLines(lines, options) {
@@ -87,7 +106,7 @@ class DefaultRomanizer {
87
106
  if (script === 'latin') {
88
107
  return { script, lines: [...lines] };
89
108
  }
90
- const romanized = await Promise.all(lines.map((line) => this.romanizeLine(line, { script })));
109
+ const romanized = await Promise.all(lines.map((line) => this.romanizeLine(line, { script, dialect: options?.dialect })));
91
110
  return { script, lines: romanized };
92
111
  }
93
112
  async getKuroshiro() {
@@ -105,6 +124,15 @@ class DefaultRomanizer {
105
124
  }
106
125
  return this.kuroshiroReady;
107
126
  }
127
+ async getJyutpingModule() {
128
+ if (!this.jyutpingReady) {
129
+ this.jyutpingReady = import('to-jyutping').catch((e) => {
130
+ this.jyutpingReady = null;
131
+ throw e;
132
+ });
133
+ }
134
+ return this.jyutpingReady;
135
+ }
108
136
  }
109
137
  export function createRomanizer(options) {
110
138
  return new DefaultRomanizer(options);
@@ -1 +1 @@
1
- {"version":3,"file":"romanizer.js","sourceRoot":"","sources":["../src/romanizer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"romanizer.js","sourceRoot":"","sources":["../src/romanizer.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,kBAAkB,CAAC;AACzC,OAAO,gBAAgB,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,OAAO,kBAAkB,MAAM,yBAAyB,CAAC;AACzD,OAAO,SAAS,MAAM,kCAAkC,CAAC;AACzD,OAAO,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,YAAY,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,QAAQ,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAQ7C,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAE1D,MAAM,0BAA0B,GAAG,4CAA4C,CAAC;AAChF,MAAM,6BAA6B,GAAG,IAAI,GAAG,CAAa;IACxD,WAAW;IACX,SAAS;IACT,QAAQ;IACR,QAAQ;IACR,OAAO;CACR,CAAC,CAAC;AAEH,MAAM,kBAAkB,GAAG,kBAAkB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AAChE,MAAM,kBAAkB,GAAG,kBAAkB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AAEhE,MAAM,gBAAgB,GAAwC;IAC5D,UAAU,EAAE,YAAY;IACxB,QAAQ,EAAE,UAAU;IACpB,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,OAAO;CACd,CAAC;AAEF,MAAM,UAAU,4BAA4B,CAAC,MAAkB;IAC7D,OAAO,6BAA6B,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,gBAAgB;IACH,gBAAgB,CAAS;IAClC,cAAc,GAA8B,IAAI,CAAC;IACjD,aAAa,GAAiD,IAAI,CAAC;IAE3E,YAAY,OAA0B;QACpC,IAAI,CAAC,gBAAgB,GAAG,OAAO,EAAE,gBAAgB,IAAI,0BAA0B,CAAC;IAClF,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,IAAY,EAAE,OAAyB;QACxD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAEtD,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACvD,IAAI,MAAM,KAAK,OAAO;YAAE,OAAO,IAAI,CAAC;QACpC,IAAI,4BAA4B,CAAC,MAAM,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,4BAA4B,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,CAAC;YACH,QAAQ,MAAM,EAAE,CAAC;gBACf,KAAK,UAAU,CAAC,CAAC,CAAC;oBAChB,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;oBACpC,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAC3D,CAAC;gBACD,KAAK,SAAS,CAAC,CAAC,CAAC;oBACf,IAAI,OAAO,EAAE,OAAO,KAAK,WAAW,EAAE,CAAC;wBACrC,IAAI,CAAC;4BACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;4BAChD,MAAM,MAAM,GAAG,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;4BAC9C,IAAI,MAAM;gCAAE,OAAO,MAAM,CAAC;wBAC5B,CAAC;wBAAC,MAAM,CAAC;4BACP,yBAAyB;wBAC3B,CAAC;oBACH,CAAC;oBACD,OAAO,MAAM,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAC9D,CAAC;gBACD,KAAK,QAAQ;oBACX,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;gBAC9B,KAAK,UAAU;oBACb,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;wBACzB,CAAC,CAAC,kBAAkB,CAAC,SAAS,CAAC,IAAI,CAAC;wBACpC,CAAC,CAAC,kBAAkB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBACzC,KAAK,YAAY,CAAC;gBAClB,KAAK,UAAU,CAAC;gBAChB,KAAK,UAAU,CAAC;gBAChB,KAAK,QAAQ,CAAC;gBACd,KAAK,SAAS,CAAC;gBACf,KAAK,MAAM,CAAC,CAAC,CAAC;oBACZ,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;oBACxC,IAAI,CAAC,MAAM;wBAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,MAAM,IAAI,CAAC,CAAC;oBAClF,IAAI,CAAE,SAAiB,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC;wBAC1C,MAAM,IAAI,KAAK,CAAC,sCAAsC,MAAM,UAAU,MAAM,IAAI,CAAC,CAAC;oBACpF,CAAC;oBACD,OAAO,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;gBAC3C,CAAC;gBACD,KAAK,OAAO;oBACV,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;gBAC7B,KAAK,MAAM;oBACT,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;gBAC5B;oBACE,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,KAAwB,EAAE,OAAyB;QACrE,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;QACtD,IAAI,4BAA4B,CAAC,MAAM,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,4BAA4B,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC;QACD,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;YACvB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC;QACvC,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QACzH,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IACtC,CAAC;IAEO,KAAK,CAAC,YAAY;QACxB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,IAAI,CAAC,cAAc,GAAG,CAAC,KAAK,IAAI,EAAE;gBAChC,MAAM,QAAQ,GAAG,IAAI,SAAS,EAAE,CAAC;gBACjC,MAAM,QAAQ,CAAC,IAAI,CACjB,IAAI,gBAAgB,CAAC;oBACnB,QAAQ,EAAE,IAAI,CAAC,gBAAgB;iBAChC,CAAC,CACH,CAAC;gBACF,OAAO,QAAQ,CAAC;YAClB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBACnB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;gBAC3B,MAAM,KAAK,CAAC;YACd,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAEO,KAAK,CAAC,iBAAiB;QAC7B,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;gBACrD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;gBAC1B,MAAM,CAAC,CAAC;YACV,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;CACF;AAED,MAAM,UAAU,eAAe,CAAC,OAA0B;IACxD,OAAO,IAAI,gBAAgB,CAAC,OAAO,CAAC,CAAC;AACvC,CAAC"}
package/dist/types.d.ts CHANGED
@@ -4,6 +4,7 @@ export type RomanizerOptions = {
4
4
  };
5
5
  export type RomanizeOptions = {
6
6
  script?: ScriptType;
7
+ dialect?: 'mandarin' | 'cantonese';
7
8
  };
8
9
  export type RomanizeResult = {
9
10
  script: ScriptType;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAClB,UAAU,GACV,SAAS,GACT,QAAQ,GACR,UAAU,GACV,YAAY,GACZ,UAAU,GACV,UAAU,GACV,QAAQ,GACR,SAAS,GACT,MAAM,GACN,OAAO,GACP,WAAW,GACX,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,OAAO,GACP,OAAO,CAAC;AAEZ,MAAM,MAAM,gBAAgB,GAAG;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAEF,MAAM,WAAW,SAAS;IACxB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvE,aAAa,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAC7F;AAED,qBAAa,4BAA6B,SAAQ,KAAK;IACrD,SAAgB,MAAM,EAAE,UAAU,CAAC;gBAEvB,MAAM,EAAE,UAAU;CAK/B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAClB,UAAU,GACV,SAAS,GACT,QAAQ,GACR,UAAU,GACV,YAAY,GACZ,UAAU,GACV,UAAU,GACV,QAAQ,GACR,SAAS,GACT,MAAM,GACN,OAAO,GACP,WAAW,GACX,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,OAAO,GACP,OAAO,CAAC;AAEZ,MAAM,MAAM,gBAAgB,GAAG;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAEF,MAAM,WAAW,SAAS;IACxB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvE,aAAa,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAC7F;AAED,qBAAa,4BAA6B,SAAQ,KAAK;IACrD,SAAgB,MAAM,EAAE,UAAU,CAAC;gBAEvB,MAAM,EAAE,UAAU;CAK/B"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAsCA,MAAM,OAAO,4BAA6B,SAAQ,KAAK;IACrC,MAAM,CAAa;IAEnC,YAAY,MAAkB;QAC5B,KAAK,CAAC,WAAW,MAAM,mCAAmC,CAAC,CAAC;QAC5D,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAC;QAC3C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAuCA,MAAM,OAAO,4BAA6B,SAAQ,KAAK;IACrC,MAAM,CAAa;IAEnC,YAAY,MAAkB;QAC5B,KAAK,CAAC,WAAW,MAAM,mCAAmC,CAAC,CAAC;QAC5D,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAC;QAC3C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lyric-romanizer",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Script detection and local romanization engine for lyrics — supports Japanese, Chinese, Korean, Cyrillic, Indic scripts, Tamil, Thai, and more",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -25,13 +25,6 @@
25
25
  "dist",
26
26
  "README.md"
27
27
  ],
28
- "scripts": {
29
- "build": "rm -rf dist && tsc -p tsconfig.build.json",
30
- "clean": "rm -rf dist",
31
- "prepack": "npm run build",
32
- "test": "vitest run",
33
- "test:watch": "vitest"
34
- },
35
28
  "dependencies": {
36
29
  "@dehoist/romanize-thai": "^1.0.0",
37
30
  "@indic-transliteration/sanscript": "^1.3.3",
@@ -40,7 +33,9 @@
40
33
  "@sglkc/kuroshiro-analyzer-kuromoji": "^1.0.1",
41
34
  "cyrillic-to-translit-js": "^3.2.1",
42
35
  "pinyin-pro": "^3.28.0",
43
- "tamil-romanizer": "^1.0.2"
36
+ "tamil-romanizer": "^1.0.2",
37
+ "to-jyutping": "^3.1.1",
38
+ "transliteration": "^2.6.1"
44
39
  },
45
40
  "devDependencies": {
46
41
  "typescript": "^5.7.3",
@@ -67,5 +62,11 @@
67
62
  "bugs": {
68
63
  "url": "https://github.com/thedavidweng/lyric-romanizer/issues"
69
64
  },
70
- "homepage": "https://github.com/thedavidweng/lyric-romanizer#readme"
71
- }
65
+ "homepage": "https://github.com/thedavidweng/lyric-romanizer#readme",
66
+ "scripts": {
67
+ "build": "rm -rf dist && tsc -p tsconfig.build.json",
68
+ "clean": "rm -rf dist",
69
+ "test": "vitest run",
70
+ "test:watch": "vitest"
71
+ }
72
+ }