math_compound_store.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import { Engine } from '../common/engine.js';
  2. import { locales } from '../l10n/l10n.js';
  3. import { addFunctionSemantic } from '../semantic_tree/semantic_attr.js';
  4. import { MathSimpleStore } from './math_simple_store.js';
  5. import { Axis, DynamicCstr } from './dynamic_cstr.js';
  6. let locale = DynamicCstr.DEFAULT_VALUES[Axis.LOCALE];
  7. let modality = DynamicCstr.DEFAULT_VALUES[Axis.MODALITY];
  8. export function changeLocale(json) {
  9. if (!json['locale'] && !json['modality']) {
  10. return false;
  11. }
  12. locale = json['locale'] || locale;
  13. modality = json['modality'] || modality;
  14. return true;
  15. }
  16. let siPrefixes = {};
  17. export function setSiPrefixes(prefixes) {
  18. siPrefixes = prefixes;
  19. }
  20. export const subStores = new Map();
  21. export const baseStores = new Map();
  22. function getSubStore(base, key) {
  23. let store = subStores.get(key);
  24. if (store) {
  25. return store;
  26. }
  27. store = new MathSimpleStore();
  28. store.base = baseStores.get(base);
  29. subStores.set(key, store);
  30. return store;
  31. }
  32. function completeWithBase(json) {
  33. const base = baseStores.get(json.key);
  34. if (!base) {
  35. return;
  36. }
  37. const names = json.names;
  38. Object.assign(json, base);
  39. if (names && base.names) {
  40. json.names = json.names.concat(names);
  41. }
  42. }
  43. export function defineRules(base, str, mappings) {
  44. const store = getSubStore(base, str);
  45. store.defineRulesFromMappings(locale, modality, mappings);
  46. }
  47. export function defineRule(domain, style, str, content) {
  48. const store = getSubStore(str, str);
  49. store.defineRuleFromStrings(locale, modality, domain, style, content);
  50. }
  51. export function addSymbolRules(json) {
  52. for (const rule of json) {
  53. if (changeLocale(rule)) {
  54. continue;
  55. }
  56. const key = MathSimpleStore.parseUnicode(rule['key']);
  57. if (locale === 'base') {
  58. baseStores.set(key, rule);
  59. continue;
  60. }
  61. defineRules(key, key, rule['mappings']);
  62. }
  63. }
  64. function addCharacterRule(json) {
  65. if (changeLocale(json)) {
  66. return;
  67. }
  68. for (const [key, value] of Object.entries(json)) {
  69. defineRule('default', 'default', key, value);
  70. }
  71. }
  72. export const addCharacterRules = (json) => json.forEach(addCharacterRule);
  73. function addFunctionRule(json) {
  74. for (let j = 0, name; (name = json.names[j]); j++) {
  75. defineRules(json.key, name, json.mappings);
  76. }
  77. }
  78. export function addFunctionRules(json) {
  79. for (const rule of json) {
  80. if (changeLocale(rule)) {
  81. continue;
  82. }
  83. addFunctionSemantic(rule.key, rule.names || []);
  84. if (locale === 'base') {
  85. baseStores.set(rule.key, rule);
  86. continue;
  87. }
  88. completeWithBase(rule);
  89. addFunctionRule(rule);
  90. }
  91. }
  92. export function addUnitRules(json) {
  93. for (const rule of json) {
  94. if (changeLocale(rule)) {
  95. continue;
  96. }
  97. rule.key += ':unit';
  98. if (locale === 'base') {
  99. baseStores.set(rule.key, rule);
  100. continue;
  101. }
  102. completeWithBase(rule);
  103. if (rule.names) {
  104. rule.names = rule.names.map(function (name) {
  105. return name + ':unit';
  106. });
  107. }
  108. if (rule.si) {
  109. addSiUnitRule(rule);
  110. }
  111. addFunctionRule(rule);
  112. }
  113. }
  114. function addSiUnitRule(json) {
  115. for (const key of Object.keys(siPrefixes)) {
  116. const newJson = Object.assign({}, json);
  117. newJson.mappings = {};
  118. const prefix = siPrefixes[key];
  119. newJson['names'] = newJson['names'].map(function (name) {
  120. return key + name;
  121. });
  122. for (const domain of Object.keys(json['mappings'])) {
  123. newJson.mappings[domain] = {};
  124. for (const style of Object.keys(json['mappings'][domain])) {
  125. newJson['mappings'][domain][style] = locales[locale]().FUNCTIONS.si(prefix, json['mappings'][domain][style]);
  126. }
  127. }
  128. addFunctionRule(newJson);
  129. }
  130. }
  131. export function lookupRule(node, dynamic) {
  132. const store = subStores.get(node);
  133. return store ? store.lookupRule(null, dynamic) : null;
  134. }
  135. export function lookupCategory(character) {
  136. const store = subStores.get(character);
  137. return (store === null || store === void 0 ? void 0 : store.base) ? store.base.category : '';
  138. }
  139. export function lookupString(text, dynamic) {
  140. const rule = lookupRule(text, dynamic);
  141. if (!rule) {
  142. return null;
  143. }
  144. return rule.action;
  145. }
  146. Engine.getInstance().evaluator = lookupString;
  147. export function enumerate(info = {}) {
  148. for (const store of subStores.values()) {
  149. for (const [, rules] of store.rules.entries()) {
  150. for (const { cstr: dynamic } of rules) {
  151. info = enumerate_(dynamic.getValues(), info);
  152. }
  153. }
  154. }
  155. return info;
  156. }
  157. function enumerate_(dynamic, info) {
  158. info = info || {};
  159. if (!dynamic.length) {
  160. return info;
  161. }
  162. info[dynamic[0]] = enumerate_(dynamic.slice(1), info[dynamic[0]]);
  163. return info;
  164. }
  165. export function reset() {
  166. locale = DynamicCstr.DEFAULT_VALUES[Axis.LOCALE];
  167. modality = DynamicCstr.DEFAULT_VALUES[Axis.MODALITY];
  168. }