lem-parser.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import { AppConfig } from 'src/app/app.config';
  2. import { xmlParser } from '.';
  3. /* add LemEntry FS */
  4. import { LemEntry, Note, Reading, XMLElement } from '../../models/evt-models';
  5. import { getOuterHTML } from '../../utils/dom-utils';
  6. import { removeSpaces } from '../../utils/xml-utils';
  7. import { AttributeParser, EmptyParser, NoteParser } from './basic-parsers';
  8. import { createParser, getID, Parser } from './parser-models';
  9. @xmlParser('rdg', RdgParser)
  10. export class RdgParser extends EmptyParser implements Parser<XMLElement> {
  11. private readingGroupTagName = 'rdgGrp';
  12. attributeParser = createParser(AttributeParser, this.genericParse);
  13. public parse(rdg: XMLElement): Reading {
  14. return {
  15. type: Reading,
  16. id: getID(rdg),
  17. attributes: this.attributeParser.parse(rdg),
  18. witIDs: this.parseReadingWitnesses(rdg) || [],
  19. content: this.parseAppReadingContent(rdg),
  20. significant: this.isReadingSignificant(rdg),
  21. class: rdg.tagName.toLowerCase(),
  22. };
  23. }
  24. private parseReadingWitnesses(rdg: XMLElement) {
  25. return rdg.getAttribute('wit')?.split('#')
  26. .map((el) => removeSpaces(el))
  27. .filter((el) => el.length !== 0);
  28. }
  29. private parseAppReadingContent(rdg: XMLElement) {
  30. return Array.from(rdg.childNodes)
  31. .map((child: XMLElement) => this.genericParse(child));
  32. }
  33. private isReadingSignificant(rdg: XMLElement): boolean {
  34. const lemNotSignificantReadings = AppConfig.evtSettings.edition.lemNotSignificantVariants;
  35. let isSignificant = true;
  36. if (lemNotSignificantReadings.length > 0) {
  37. isSignificant = this.isSignificant(lemNotSignificantReadings, rdg.attributes);
  38. if (isSignificant && rdg.parentElement.tagName === this.readingGroupTagName) {
  39. isSignificant = this.isSignificant(lemNotSignificantReadings, rdg.parentElement.attributes);
  40. }
  41. }
  42. return isSignificant;
  43. }
  44. private isSignificant(notSignificantReading: string[], attributes: NamedNodeMap): boolean {
  45. return !Array.from(attributes).some(({ name, value }) => notSignificantReading.includes(`${name}=${value}`));
  46. }
  47. }
  48. @xmlParser('evt-lem-entry-parser', LemParser)
  49. export class LemParser extends EmptyParser implements Parser<XMLElement> {
  50. private lemmaTagName = 'app[type="lemma"]';
  51. private noteTagName = 'note';
  52. private lemEntryTagName = 'lem';
  53. private readingTagName = 'rdg';
  54. attributeParser = createParser(AttributeParser, this.genericParse);
  55. noteParser = createParser(NoteParser, this.genericParse);
  56. rdgParser = createParser(RdgParser, this.genericParse);
  57. /* add lemEntry FS */
  58. public parse(lemEntry: XMLElement): LemEntry {
  59. return {
  60. type: LemEntry,
  61. id: getID(lemEntry),
  62. attributes: this.attributeParser.parse(lemEntry),
  63. content: [],
  64. lemma: this.parseLemma(lemEntry),
  65. readings: this.parseReadings(lemEntry),
  66. notes: this.parseLemNotes(lemEntry),
  67. originalEncoding: getOuterHTML(lemEntry),
  68. class: lemEntry.tagName.toLowerCase(),
  69. nestedLemsIDs: this.getNestedLemsIDs(lemEntry),
  70. };
  71. }
  72. private getNestedLemsIDs(lem: XMLElement): string[] {
  73. const nesLems = lem.querySelectorAll('app[type="lemma"]');
  74. return Array.from(nesLems).map((a: XMLElement) => getID(a));
  75. }
  76. private parseLemNotes(lemEntry: XMLElement): Note[] {
  77. const notes = Array.from(lemEntry.children)
  78. .filter(({ tagName }) => tagName === this.noteTagName)
  79. .map((note: XMLElement) => this.noteParser.parse(note));
  80. return notes;
  81. }
  82. /* add parseLemma FS */
  83. private parseLemma(lemEntry: XMLElement): Reading {
  84. return lemEntry.querySelector(`${this.lemmaTagName}`) ?
  85. this.rdgParser.parse(lemEntry.querySelector(`${this.lemmaTagName}`)) : undefined;
  86. }
  87. private parseReadings(lemEntry: XMLElement): Reading[] {
  88. return Array.from(lemEntry.querySelectorAll(`${this.readingTagName}`))
  89. .filter((el) => el.closest(this.lemEntryTagName) === lemEntry)
  90. .map((rdg: XMLElement) => this.rdgParser.parse(rdg));
  91. }
  92. }