#include "global.h" #include "TitleSubstitution.h" #include "arch/arch.h" #include "RageUtil.h" #include "RageLog.h" #include "FontCharAliases.h" #include "RageFile.h" #define TRANSLATION_PATH "Data/Translation.dat" struct TitleTrans { Regex TitleFrom, SubFrom, ArtistFrom; CString TitleTo, SubTo, ArtistTo; /* plain text */ CString TitleTransTo, SubTransTo, ArtistTransTo; /* plain text */ /* If this is true, no translit fields will be generated automatically. */ bool translit; TitleTrans() { translit = true; } TitleTrans(CString tf, CString sf, CString af, CString tt, CString st, CString at, bool translit_): TitleFrom(tf), SubFrom(sf), ArtistFrom(af), TitleTo(tt), SubTo(st), ArtistTo(at), translit(translit_) { } bool Matches(CString title, CString sub, CString artist); }; vector ttab; bool TitleTrans::Matches(CString title, CString sub, CString artist) { if(!TitleFrom.Compare(title)) return false; /* no match */ if(!SubFrom.Compare(sub)) return false; /* no match */ if(!ArtistFrom.Compare(artist)) return false; /* no match */ return true; } void TitleSubst::AddTrans(const TitleTrans &tr) { ttab.push_back(new TitleTrans(tr)); } void TitleSubst::Subst(CString &title, CString &subtitle, CString &artist, CString &ttitle, CString &tsubtitle, CString &tartist) { for(unsigned i = 0; i < ttab.size(); ++i) { if(!ttab[i]->Matches(title, subtitle, artist)) continue; /* The song matches. Replace whichever strings aren't empty. */ if(!ttab[i]->TitleTo.empty()) { if(ttab[i]->translit && title != ttab[i]->TitleTo) ttitle = title; title = ttab[i]->TitleTo; FontCharAliases::ReplaceMarkers( title ); } if(!ttab[i]->SubTo.empty()) { if(ttab[i]->translit && subtitle != ttab[i]->SubTo) tsubtitle = subtitle; subtitle = ttab[i]->SubTo; FontCharAliases::ReplaceMarkers( subtitle ); } if(!ttab[i]->ArtistTo.empty() && artist != ttab[i]->ArtistTo) { if(ttab[i]->translit) tartist = artist; artist = ttab[i]->ArtistTo; FontCharAliases::ReplaceMarkers( artist ); } /* These are used when applying kanji to a field that doesn't have the * correct data. Should be used sparingly. */ if(!ttab[i]->TitleTransTo.empty()) { ttitle = ttab[i]->TitleTransTo; FontCharAliases::ReplaceMarkers( ttitle ); } if(!ttab[i]->SubTransTo.empty()) { tsubtitle = ttab[i]->SubTransTo; FontCharAliases::ReplaceMarkers( tsubtitle ); } if(!ttab[i]->ArtistTransTo.empty()) { tartist = ttab[i]->ArtistTransTo; FontCharAliases::ReplaceMarkers( tartist ); } } } TitleSubst::TitleSubst(const CString §ion) { Load( TRANSLATION_PATH, section); } void TitleSubst::Load(const CString &filename, const CString §ion) { RageFile f; if( !f.Open(filename) ) { LOG->Trace("Error opening %s: %s", filename.c_str(), f.GetError().c_str() ); return; } CString CurrentSection; TitleTrans tr; while (!f.AtEOF()) { CString line; int ret = f.GetLine( line ); if( ret == 0 ) break; if( ret == -1 ) { LOG->Trace("Error reading %s: %s", filename.c_str(), f.GetError().c_str() ); break; } if(line.size() > 0 && utf8_get_char(line.c_str()) == 0xFEFF) { /* Annoying header that Windows puts on UTF-8 plaintext * files; remove it. */ line.erase(0, utf8_get_char_len(line[0])); } TrimLeft(line); TrimRight(line); if(line.size() == 0) continue; /* blank */ if(line[0] == '#') continue; /* comment */ if(!line.CompareNoCase("DontTransliterate")) { tr.translit = false; continue; } unsigned pos = line.find_first_of(':'); if(pos != string::npos) { /* x: y */ CString id = line.substr(0, pos); CString txt = line.substr(pos+1); TrimLeft(txt); /* Surround each regex with ^(...)$, to force all comparisons to default * to being a full-line match. (Add ".*" manually if this isn't wanted.) */ if(!id.CompareNoCase("TitleFrom")) tr.TitleFrom = "^(" + txt + ")$"; else if(!id.CompareNoCase("ArtistFrom")) tr.ArtistFrom = "^(" + txt + ")$"; else if(!id.CompareNoCase("SubtitleFrom")) tr.SubFrom = "^(" + txt + ")$"; else if(!id.CompareNoCase("TitleTo")) tr.TitleTo = txt; else if(!id.CompareNoCase("ArtistTo")) tr.ArtistTo = txt; else if(!id.CompareNoCase("SubtitleTo")) tr.SubTo = txt; else if(!id.CompareNoCase("TitleTransTo")) tr.TitleTransTo = txt; else if(!id.CompareNoCase("ArtistTransTo")) tr.ArtistTransTo = txt; else if(!id.CompareNoCase("SubtitleTransTo")) tr.SubTransTo = txt; else LOG->Warn( "Unknown TitleSubst tag: \"%s\"", id.c_str() ); } /* Add the translation if this is a terminator (*) or section * marker ([foo]). */ if(line[0] == '*' || line[0] == '[') { if(!CurrentSection.CompareNoCase(section)) AddTrans(tr); /* Reset. */ tr = TitleTrans(); } if(line[0] == '[' && line[line.size()-1] == ']') { CurrentSection = line.substr(1, line.size()-2); } } } TitleSubst::~TitleSubst() { for(unsigned i = 0; i < ttab.size(); ++i) delete ttab[i]; } /* * Copyright (c) 2003 by the person(s) listed below. All rights reserved. * * Glenn Maynard */