syntax_walker.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import { interleaveLists } from '../common/base_util.js';
  2. import { SemanticRole, SemanticType } from '../semantic_tree/semantic_meaning.js';
  3. import { AbstractWalker } from './abstract_walker.js';
  4. import { Levels } from './levels.js';
  5. export class SyntaxWalker extends AbstractWalker {
  6. constructor(node, generator, highlighter, xml) {
  7. super(node, generator, highlighter, xml);
  8. this.node = node;
  9. this.generator = generator;
  10. this.highlighter = highlighter;
  11. this.levels = null;
  12. this.restoreState();
  13. }
  14. initLevels() {
  15. const levels = new Levels();
  16. levels.push([this.primaryId()]);
  17. return levels;
  18. }
  19. up() {
  20. super.up();
  21. const parent = this.previousLevel();
  22. if (!parent) {
  23. return null;
  24. }
  25. this.levels.pop();
  26. return this.singletonFocus(parent);
  27. }
  28. down() {
  29. super.down();
  30. const children = this.nextLevel();
  31. if (children.length === 0) {
  32. return null;
  33. }
  34. const focus = this.singletonFocus(children[0]);
  35. if (focus) {
  36. this.levels.push(children);
  37. }
  38. return focus;
  39. }
  40. combineContentChildren(type, role, content, children) {
  41. switch (type) {
  42. case SemanticType.RELSEQ:
  43. case SemanticType.INFIXOP:
  44. case SemanticType.MULTIREL:
  45. return interleaveLists(children, content);
  46. case SemanticType.PREFIXOP:
  47. return content.concat(children);
  48. case SemanticType.POSTFIXOP:
  49. return children.concat(content);
  50. case SemanticType.MATRIX:
  51. case SemanticType.VECTOR:
  52. case SemanticType.FENCED:
  53. children.unshift(content[0]);
  54. children.push(content[1]);
  55. return children;
  56. case SemanticType.CASES:
  57. children.unshift(content[0]);
  58. return children;
  59. case SemanticType.PUNCTUATED:
  60. if (role === SemanticRole.TEXT) {
  61. return interleaveLists(children, content);
  62. }
  63. return children;
  64. case SemanticType.APPL:
  65. return [children[0], content[0], children[1]];
  66. case SemanticType.ROOT:
  67. return [children[0], children[1]];
  68. default:
  69. return children;
  70. }
  71. }
  72. left() {
  73. super.left();
  74. const index = this.levels.indexOf(this.primaryId());
  75. if (index === null) {
  76. return null;
  77. }
  78. const id = this.levels.get(index - 1);
  79. return id ? this.singletonFocus(id) : null;
  80. }
  81. right() {
  82. super.right();
  83. const index = this.levels.indexOf(this.primaryId());
  84. if (index === null) {
  85. return null;
  86. }
  87. const id = this.levels.get(index + 1);
  88. return id ? this.singletonFocus(id) : null;
  89. }
  90. findFocusOnLevel(id) {
  91. return this.singletonFocus(id.toString());
  92. }
  93. focusDomNodes() {
  94. return [this.getFocus().getDomPrimary()];
  95. }
  96. focusSemanticNodes() {
  97. return [this.getFocus().getSemanticPrimary()];
  98. }
  99. }