diff --git a/src/transliteration/domain/columns.ts b/src/transliteration/domain/columns.ts index 0d0667c11..be88ae48a 100644 --- a/src/transliteration/domain/columns.ts +++ b/src/transliteration/domain/columns.ts @@ -88,7 +88,7 @@ export function annotationLineAccFromColumns( acc.addColumn(column.span) column.content.reduce( (acc: AnnotationLineAccumulator, token: Token, index: number) => { - acc.addColumnToken(token, index, false, false, false, {}, [], true) + acc.addColumnToken(token, index) return acc }, acc diff --git a/src/transliteration/ui/LineAccumulator.tsx b/src/transliteration/ui/LineAccumulator.tsx index 45a339deb..d367785d7 100644 --- a/src/transliteration/ui/LineAccumulator.tsx +++ b/src/transliteration/ui/LineAccumulator.tsx @@ -203,3 +203,124 @@ export class LineAccumulator { .sum() } } + +export class AnnotationLineAccumulator { + readonly columns: ColumnData[] = [] + private inGloss = false + private language = 'AKKADIAN' + private enclosureOpened = false + private protocol: Protocol | null = null + private isFirstWord = true + lemmas: string[] = [] + + getColumns(maxColumns: number): React.ReactNode[] { + return this.columns.map((column: ColumnData, index: number) => ( + + {column.content} + + )) + } + + get flatResult(): React.ReactNode[] { + return this.columns.flatMap((column) => column.content) + } + + get bemModifiers(): readonly string[] { + return this.protocol === null + ? [this.language] + : [this.language, this.protocol.replace('!', 'commentary-protocol-')] + } + + applyLanguage(token: Shift): void { + this.language = token.language + } + + applyCommentaryProtocol(token: CommentaryProtocol): void { + this.protocol = token.value + } + + pushToken(token: Token, index: number): void { + if (_.isEmpty(this.columns)) { + this.addColumn(1) + } + if (this.requireSeparator(token, index)) { + this.pushSeparator() + } + + _.last(this.columns)?.content.push( + + ) + this.enclosureOpened = isOpenEnclosure(token) + } + + private pushLemma(lemma: readonly string[] | null | undefined): void { + if (lemma) { + this.lemmas.push(...lemma) + } + } + + addColumn(span: number | null): void { + this.columns.push({ span: span, content: [] }) + } + + openGloss(): void { + this.inGloss = true + } + + closeGloss(): void { + this.inGloss = false + } + + addColumnToken(token: Token, index: number): void { + switch (token.type) { + case 'LanguageShift': + this.applyLanguage(token) + break + case 'CommentaryProtocol': + this.applyCommentaryProtocol(token) + break + case 'DocumentOrientedGloss': + isLeftSide(token) ? this.openGloss() : this.closeGloss() + break + case 'Column': + throw new Error('Unexpected column token.') + default: + this.pushToken(token, index) + this.pushLemma(token.uniqueLemma) + this.isFirstWord = false + } + } + + private requireSeparator(token: Token, index: number): boolean { + return ( + !this.isFirstWord && !isCloseEnclosure(token) && !this.enclosureOpened + ) + } + + private pushSeparator(): void { + _.last(this.columns)?.content.push( + this.inGloss ? ( + + + + ) : ( + + ) + ) + } + + private get index(): number { + return _(this.columns) + .map((column) => column.content.length) + .sum() + } +}