locale.hpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #pragma once
  2. namespace nall {
  3. struct Locale {
  4. struct Dictionary {
  5. string location;
  6. string language;
  7. Markup::Node document;
  8. };
  9. auto scan(string pathname) -> void {
  10. dictionaries.reset();
  11. selected.reset();
  12. for(auto filename : directory::icontents(pathname, "*.bml")) {
  13. Dictionary dictionary;
  14. dictionary.location = {pathname, filename};
  15. dictionary.document = BML::unserialize(string::read(dictionary.location));
  16. dictionary.language = dictionary.document["locale/language"].text();
  17. dictionaries.append(dictionary);
  18. }
  19. }
  20. auto available() const -> vector<string> {
  21. vector<string> result;
  22. for(auto& dictionary : dictionaries) {
  23. result.append(dictionary.language);
  24. }
  25. return result;
  26. }
  27. auto select(string option) -> bool {
  28. selected.reset();
  29. for(auto& dictionary : dictionaries) {
  30. if(option == Location::prefix(dictionary.location) || option == dictionary.language) {
  31. selected = dictionary;
  32. return true;
  33. }
  34. }
  35. return false;
  36. }
  37. template<typename... P>
  38. auto operator()(string ns, string input, P&&... p) const -> string {
  39. vector<string> arguments{forward<P>(p)...};
  40. if(selected) {
  41. for(auto node : selected().document) {
  42. if(node.name() == "namespace" && node.text() == ns) {
  43. for(auto map : node) {
  44. if(map.name() == "map" && map["input"].text() == input) {
  45. input = map["value"].text();
  46. break;
  47. }
  48. }
  49. }
  50. }
  51. }
  52. for(uint index : range(arguments.size())) {
  53. input.replace({"{", index, "}"}, arguments[index]);
  54. }
  55. return input;
  56. }
  57. struct Namespace {
  58. Namespace(Locale& _locale, string _namespace) : _locale(_locale), _namespace(_namespace) {}
  59. template<typename... P>
  60. auto operator()(string input, P&&... p) const -> string {
  61. return _locale(_namespace, input, forward<P>(p)...);
  62. }
  63. template<typename... P>
  64. auto tr(string input, P&&... p) const -> string {
  65. return _locale(_namespace, input, forward<P>(p)...);
  66. }
  67. private:
  68. Locale& _locale;
  69. string _namespace;
  70. };
  71. private:
  72. vector<Dictionary> dictionaries;
  73. maybe<Dictionary&> selected;
  74. };
  75. }