unit_util.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import { AuditoryDescription } from '../audio/auditory_description.js';
  2. import * as XpathUtil from '../common/xpath_util.js';
  3. import { LOCALE } from '../l10n/locale.js';
  4. import { SemanticType } from '../semantic_tree/semantic_meaning.js';
  5. export function unitMultipliers(nodes, _context) {
  6. const children = nodes;
  7. let counter = 0;
  8. return function () {
  9. const descr = AuditoryDescription.create({
  10. text: rightMostUnit(children[counter]) &&
  11. leftMostUnit(children[counter + 1])
  12. ? LOCALE.MESSAGES.unitTimes
  13. : ''
  14. }, {});
  15. counter++;
  16. return [descr];
  17. };
  18. }
  19. const SCRIPT_ELEMENTS = [
  20. SemanticType.SUPERSCRIPT,
  21. SemanticType.SUBSCRIPT,
  22. SemanticType.OVERSCORE,
  23. SemanticType.UNDERSCORE
  24. ];
  25. function rightMostUnit(node) {
  26. while (node) {
  27. if (node.getAttribute('role') === 'unit') {
  28. return true;
  29. }
  30. const tag = node.tagName;
  31. const children = XpathUtil.evalXPath('children/*', node);
  32. node = (SCRIPT_ELEMENTS.indexOf(tag) !== -1
  33. ? children[0]
  34. : children[children.length - 1]);
  35. }
  36. return false;
  37. }
  38. function leftMostUnit(node) {
  39. while (node) {
  40. if (node.getAttribute('role') === 'unit') {
  41. return true;
  42. }
  43. const children = XpathUtil.evalXPath('children/*', node);
  44. node = children[0];
  45. }
  46. return false;
  47. }
  48. export function oneLeft(node) {
  49. while (node) {
  50. if (node.tagName === 'number' && node.textContent === '1') {
  51. return [node];
  52. }
  53. if (node.tagName !== 'infixop' ||
  54. (node.getAttribute('role') !== 'multiplication' &&
  55. node.getAttribute('role') !== 'implicit')) {
  56. return [];
  57. }
  58. node = XpathUtil.evalXPath('children/*', node)[0];
  59. }
  60. return [];
  61. }