feat: normalize Japanese artist/title names to romaji at storage time
- Add romajiForStorage() to romaji.js — smart word spacing + Title Case - ytdlp.js: apply to folder names, filenames, and embedded tags - novasonic-server.js: apply in edit-metadata endpoint and Spotify resolve - spotify.js: update track artist/name from iTunes canonical English names Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
c03463b66b
commit
446c583f7f
4 files changed
+57
-15
No files matched your search
+20
-1
@@ -75,6 +75,25 @@ function toRomaji(text) {
|
||||
return _hiraToRomaji(hira).toLowerCase();
|
||||
}
|
||||
|
||||
// Human-readable romaji for storage: spaces between words, Title Case, ASCII preserved as-is.
|
||||
function romajiForStorage(text) {
|
||||
if (!text || !_tokenizer || !JP_RE.test(text)) return text || '';
|
||||
const tokens = _tokenizer.tokenize(text);
|
||||
const parts = tokens.map(t => {
|
||||
const r = t.reading;
|
||||
if (!r || r === '*') return t.surface_form; // ASCII — keep original
|
||||
return _hiraToRomaji(_kataToHira(r)); // Japanese — convert (lowercase)
|
||||
});
|
||||
// Add space between adjacent alphabetic segments (word separation for names/titles)
|
||||
const joined = parts.reduce((acc, part, i) => {
|
||||
if (i === 0) return part;
|
||||
const needsSpace = /[a-zA-Z0-9]$/.test(parts[i - 1]) && /^[a-zA-Z]/.test(part);
|
||||
return acc + (needsSpace ? ' ' : '') + part;
|
||||
}, '');
|
||||
// Title-case: capitalize first lowercase letter of each word, preserve existing uppercase
|
||||
return joined.replace(/\b([a-z])/g, c => c.toUpperCase()).replace(/\s+/g, ' ').trim();
|
||||
}
|
||||
|
||||
// ─── INDEX BUILDER ────────────────────────────────────────────────────────────
|
||||
|
||||
const romajiCache = new Map();
|
||||
@@ -123,4 +142,4 @@ function clearRomajiCache() { romajiCache.clear(); }
|
||||
|
||||
function isTokenizerReady() { return !!_tokenizer; }
|
||||
|
||||
module.exports = { buildRomajiIndex, clearRomajiCache, isTokenizerReady, fetchNdSongs: _fetchNdSongs };
|
||||
module.exports = { buildRomajiIndex, clearRomajiCache, isTokenizerReady, fetchNdSongs: _fetchNdSongs, romajiForStorage };
|
||||
Reference in new issue
Block a user