Skip to content

Commit

Permalink
add AnnotationLineAccumulator
Browse files Browse the repository at this point in the history
  • Loading branch information
fsimonjetz committed Jul 31, 2024
1 parent c765430 commit 59aba97
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/transliteration/domain/columns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
121 changes: 121 additions & 0 deletions src/transliteration/ui/LineAccumulator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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) => (
<td key={index} colSpan={column.span ?? maxColumns}>
{column.content}
</td>
))
}

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(
<DisplayToken
key={this.index}
token={token}
bemModifiers={this.bemModifiers}
Wrapper={this.inGloss && !isEnclosure(token) ? GlossWrapper : undefined}
isInPopover={true}
/>
)
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 ? (
<GlossWrapper key={`${this.index}-separator`}>
<WordSeparator modifiers={this.bemModifiers} />
</GlossWrapper>
) : (
<WordSeparator
key={`${this.index}-separator`}
modifiers={this.bemModifiers}
/>
)
)
}

private get index(): number {
return _(this.columns)
.map((column) => column.content.length)
.sum()
}
}

0 comments on commit 59aba97

Please sign in to comment.