1 module rpui.resources.strings; 2 3 import std.path; 4 import std.typecons; 5 import std.algorithm: canFind; 6 import std.ascii; 7 import std.conv; 8 9 import rpui.primitives; 10 import rpui.paths; 11 12 import rpdl.tree; 13 14 /** 15 * This class uses RPDL as strings repository, strings needed for 16 * internationalization. 17 */ 18 final class StringsRes { 19 private RpdlTree strings = null; 20 21 this() { 22 } 23 24 void setLocale(in string locale) { 25 const paths = createPathes(); 26 const string path = buildPath(paths.resources, "strings", locale); 27 this.strings = new RpdlTree(path); 28 } 29 30 void addStrings(in string fileName) { 31 if (strings is null) 32 return; 33 34 strings.load(fileName); 35 } 36 37 utf32string parseString(in utf32string source) { 38 if (strings is null) 39 return source; 40 41 utf32string result = ""; 42 43 for (size_t i = 0; i < source.length; ++i) { 44 const utf32char ch = source[i]; 45 46 if (ch == '@') { 47 auto reference = parseReference(source, i); 48 result ~= reference.value; 49 i = reference.endPosition; 50 } else { 51 result ~= ch; 52 } 53 } 54 55 return result; 56 } 57 58 private struct Reference { 59 dstring value; 60 size_t endPosition; 61 } 62 63 private Reference parseReference(in utf32string source, in size_t position) { 64 utf32string reference = ""; 65 size_t endPosition = position + 1; 66 const referenceAlphabet = letters ~ digits ~ "."; 67 68 for (size_t i = position + 1; i < source.length; ++i) { 69 const utf32char ch = source[i]; 70 71 if (!referenceAlphabet.canFind(ch)) 72 break; 73 74 reference ~= ch; 75 endPosition = i; 76 } 77 78 const value = strings.data.optUTF32String(to!string(reference) ~ ".0", reference); 79 return Reference(value, endPosition); 80 } 81 }