lyric-romanizer 0.1.0 → 0.1.1

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.
Files changed (2) hide show
  1. package/README.md +164 -30
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,69 +1,203 @@
1
1
  # lyric-romanizer
2
2
 
3
- Script detection and local romanization engine for lyrics. Supports Japanese, Chinese, Korean, Cyrillic, Indic scripts (Devanagari, Gujarati, Gurmukhi, Telugu, Kannada, Odia), Tamil, Thai, and Latin.
3
+ [![npm version](https://img.shields.io/npm/v/lyric-romanizer.svg)](https://www.npmjs.com/package/lyric-romanizer)
4
+ [![license](https://img.shields.io/npm/l/lyric-romanizer.svg)](https://github.com/thedavidweng/lyric-romanizer/blob/main/LICENSE)
4
5
 
5
- Extracted from [Spotify Karaoke](https://github.com/haroldalan/spotify-karaoke).
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
7
 
7
- ## Install
8
+ Extracted from [Spotify Karaoke](https://github.com/haroldalan/spotify-karaoke). Used by [OpenKara](https://github.com/thedavidweng/openkara).
9
+
10
+ ## Installation
8
11
 
9
12
  ```bash
10
13
  npm install lyric-romanizer
11
14
  ```
12
15
 
16
+ ```bash
17
+ yarn add lyric-romanizer
18
+ ```
19
+
20
+ ```bash
21
+ pnpm add lyric-romanizer
22
+ ```
23
+
24
+ ## Quick Start
25
+
26
+ ```ts
27
+ import { createRomanizer, detectScript } from 'lyric-romanizer';
28
+
29
+ const romanizer = createRomanizer();
30
+
31
+ // Auto-detect script and romanize
32
+ const result = await romanizer.romanizeLines(['你好世界', 'こんにちは']);
33
+ // { script: 'chinese', lines: ['nǐ hǎo shì jiè', 'こんにちは'] }
34
+
35
+ // Romanize a single line
36
+ const line = await romanizer.romanizeLine('안녕하세요');
37
+ // 'annyeonghaseyo'
38
+ ```
39
+
13
40
  ## API
14
41
 
42
+ ### Imports
43
+
15
44
  ```ts
45
+ // Main entry — full romanization engine
16
46
  import {
17
47
  createRomanizer,
18
48
  detectScript,
19
49
  isLatinScript,
20
50
  requiresExternalRomanization,
51
+ UnsupportedRomanizationError,
21
52
  } from 'lyric-romanizer';
22
53
 
23
- // Subpath import for detector only
24
- import { detectScript } from 'lyric-romanizer/detector';
54
+ // Detector-only subpath lightweight, no romanization dependencies
55
+ import { detectScript, isLatinScript, NON_LATIN_SCRIPT_RE } from 'lyric-romanizer/detector';
56
+ ```
57
+
58
+ ### Types
59
+
60
+ ```ts
61
+ type ScriptType =
62
+ | 'japanese' | 'chinese' | 'korean' | 'cyrillic'
63
+ | 'devanagari' | 'gujarati' | 'gurmukhi' | 'telugu'
64
+ | 'kannada' | 'odia' | 'tamil' | 'malayalam'
65
+ | 'bengali' | 'arabic' | 'hebrew' | 'thai'
66
+ | 'latin' | 'other';
67
+
68
+ interface Romanizer {
69
+ romanizeLine(line: string, options?: RomanizeOptions): Promise<string>;
70
+ romanizeLines(lines: readonly string[], options?: RomanizeOptions): Promise<RomanizeResult>;
71
+ }
72
+
73
+ type RomanizeOptions = { script?: ScriptType };
74
+ type RomanizeResult = { script: ScriptType; lines: string[] };
75
+ type RomanizerOptions = { japaneseDictPath?: string };
76
+ ```
77
+
78
+ ### Functions
79
+
80
+ #### `createRomanizer(options?)`
81
+
82
+ Factory that returns a `Romanizer` instance. The Kuroshiro engine (Japanese) is lazily initialized on first use and cached.
83
+
84
+ ```ts
85
+ const romanizer = createRomanizer();
86
+
87
+ // Override the Kuromoji dictionary CDN path (e.g. for self-hosting)
88
+ const romanizer = createRomanizer({
89
+ japaneseDictPath: 'https://my-cdn.com/kuromoji/dict',
90
+ });
25
91
  ```
26
92
 
27
- ### `detectScript(lines: readonly string[]): ScriptType`
93
+ #### `detectScript(lines)`
28
94
 
29
- Detects the dominant script in the given lines. Returns one of: `japanese`, `chinese`, `korean`, `cyrillic`, `devanagari`, `gujarati`, `gurmukhi`, `telugu`, `kannada`, `odia`, `tamil`, `malayalam`, `bengali`, `arabic`, `hebrew`, `thai`, `latin`, `other`.
95
+ Detects the dominant script in the given text lines. Checks for Japanese kana first (definitive), then scores all other scripts by character count.
30
96
 
31
- ### `isLatinScript(lines: readonly string[]): boolean`
97
+ ```ts
98
+ detectScript(['こんにちは']); // 'japanese'
99
+ detectScript(['你好世界']); // 'chinese'
100
+ detectScript(['Привет']); // 'cyrillic'
101
+ detectScript(['Hello world']); // 'latin'
102
+ detectScript(['123 ???']); // 'other'
103
+ ```
104
+
105
+ #### `isLatinScript(lines)`
106
+
107
+ Fast check — returns `true` if the text contains only Latin letters (no CJK, Cyrillic, Indic, etc.). Useful for skipping romanization entirely.
108
+
109
+ ```ts
110
+ isLatinScript(['Hello world']); // true
111
+ isLatinScript(['안녕하세요']); // false
112
+ isLatinScript(['♪♪♪']); // false (no letters)
113
+ ```
114
+
115
+ #### `requiresExternalRomanization(script)`
116
+
117
+ Returns `true` for scripts that cannot be romanized locally and require an external API.
118
+
119
+ ```ts
120
+ requiresExternalRomanization('chinese'); // false
121
+ requiresExternalRomanization('arabic'); // true
122
+ requiresExternalRomanization('malayalam'); // true
123
+ ```
124
+
125
+ ### `Romanizer` Interface
32
126
 
33
- Fast check for whether the text is Latin-only (no non-Latin characters).
127
+ #### `romanizer.romanizeLine(line, options?)`
34
128
 
35
- ### `requiresExternalRomanization(script: ScriptType): boolean`
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.
36
130
 
37
- Returns `true` for scripts that cannot be romanized locally (`malayalam`, `bengali`, `arabic`, `hebrew`, `other`).
131
+ **Throws** `UnsupportedRomanizationError` for external scripts.
38
132
 
39
- ### `createRomanizer(options?: { japaneseDictPath?: string }): Romanizer`
133
+ ```ts
134
+ await romanizer.romanizeLine('你好世界');
135
+ // 'nǐ hǎo shì jiè'
136
+
137
+ await romanizer.romanizeLine('Привет мир');
138
+ // 'Privet mir'
40
139
 
41
- Creates a romanizer instance. The optional `japaneseDictPath` overrides the default [Kuromoji](https://github.com/takuyaa/kuromoji.js) dictionary CDN path.
140
+ await romanizer.romanizeLine('Hello world');
141
+ // 'Hello world' (no-op)
142
+
143
+ await romanizer.romanizeLine('مرحبا');
144
+ // throws UnsupportedRomanizationError { script: 'arabic' }
145
+ ```
42
146
 
43
- ### `Romanizer.romanizeLine(line: string, options?: { script?: ScriptType }): Promise<string>`
147
+ #### `romanizer.romanizeLines(lines, options?)`
148
+
149
+ Romanizes multiple lines in parallel. Returns the detected script and romanized lines.
150
+
151
+ ```ts
152
+ const { script, lines } = await romanizer.romanizeLines([
153
+ 'สวัสดี',
154
+ 'ชาวโลก',
155
+ ]);
156
+ // { script: 'thai', lines: ['sawatdi', 'chaolok'] }
157
+ ```
158
+
159
+ ### `UnsupportedRomanizationError`
160
+
161
+ Thrown when attempting to romanize a script that requires an external API. Has a `script` property for programmatic handling.
162
+
163
+ ```ts
164
+ try {
165
+ await romanizer.romanizeLine('مرحبا');
166
+ } catch (err) {
167
+ if (err instanceof UnsupportedRomanizationError) {
168
+ console.log(err.script); // 'arabic'
169
+ // fall back to external API
170
+ }
171
+ }
172
+ ```
44
173
 
45
- Romanizes a single line. If `script` is omitted, it is auto-detected.
174
+ ## Supported Scripts
46
175
 
47
- ### `Romanizer.romanizeLines(lines: readonly string[], options?: { script?: ScriptType }): Promise<{ script: ScriptType, lines: string[] }>`
176
+ ### Local (fully offline)
48
177
 
49
- Romanizes multiple lines at once.
178
+ | Script | Engine | Example |
179
+ |--------|--------|---------|
180
+ | 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` |
182
+ | Korean | [@romanize/korean](https://github.com/kntng/romanize) | `안녕` → `annyeong` |
183
+ | 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` |
190
+ | Tamil | [tamil-romanizer](https://github.com/haroldalan/tamil-romanizer) | `வணக்கம்` → `vanakkam` |
191
+ | Thai | [@dehoist/romanize-thai](https://github.com/Dehoist/Open-Source) | `สวัสดี` → `sawatdi` |
192
+ | Latin | *(no-op)* | `Hello` → `Hello` |
50
193
 
51
- ## Supported Local Scripts
194
+ ### External (requires API)
52
195
 
53
- | Script | Library |
54
- |--------|---------|
55
- | Japanese | [@sglkc/kuroshiro](https://github.com/sglkc/kuroshiro-ts) + [kuromoji](https://github.com/takuyaa/kuromoji.js) |
56
- | Chinese | [pinyin-pro](https://github.com/zh-lx/pinyin-pro) |
57
- | Korean | [@romanize/korean](https://github.com/kntng/romanize) |
58
- | Cyrillic (Russian/Ukrainian) | [cyrillic-to-translit-js](https://github.com/greybax/CyrillicToTranslitJS) |
59
- | Devanagari, Gujarati, Gurmukhi, Telugu, Kannada, Odia | [@indic-transliteration/sanscript](https://github.com/indic-transliteration/sanscript.js) |
60
- | Tamil | [tamil-romanizer](https://github.com/haroldalan/tamil-romanizer) |
61
- | Thai | [@dehoist/romanize-thai](https://github.com/Dehoist/Open-Source) |
62
- | Latin | no-op (returned as-is) |
196
+ `malayalam`, `bengali`, `arabic`, `hebrew`, `other` — use `requiresExternalRomanization()` to detect these and branch to your preferred API.
63
197
 
64
- ## External Romanization Scripts
198
+ ## Cyrillic Detection
65
199
 
66
- `malayalam`, `bengali`, `arabic`, `hebrew`, and `other` are marked as external. Use `requiresExternalRomanization(script)` to branch to an API-based romanizer. Calling `romanizeLine`/`romanizeLines` for these throws `UnsupportedRomanizationError`.
200
+ Cyrillic auto-detects Ukrainian-specific characters (`і`, `ї`, `є`, `ґ`) and applies the Ukrainian transliteration preset. All other Cyrillic text defaults to Russian.
67
201
 
68
202
  ## License
69
203
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lyric-romanizer",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
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",