overleaf-cep/services/web/frontend/js/features/word-count-modal/utils/find-preamble-extent.ts
Alf Eaton c6ac06b51c Start adding client-side word count (#24892)
GitOrigin-RevId: 6c17d7bf7095794c003e17939a8302fc6b059262
2025-04-28 08:05:38 +00:00

40 lines
1.1 KiB
TypeScript

import { NodeType, SyntaxNodeRef, Tree } from '@lezer/common'
import { ancestorOfNodeWithType } from '@/features/source-editor/utils/tree-operations/ancestors'
export const findPreambleExtent = (tree: Tree) => {
const preamble = { to: 0 }
let seenDocumentEnvironment = false
const preambleMatcher = NodeType.match<(nodeRef: SyntaxNodeRef) => void>({
'Title Author Affil Affiliation'(nodeRef) {
preamble.to = nodeRef.node.to
},
DocumentEnvironment(nodeRef) {
// only count the first instance of DocumentEnvironment
if (!seenDocumentEnvironment) {
preamble.to =
nodeRef.node.getChild('Content')?.from ?? nodeRef.node.from
seenDocumentEnvironment = true
}
},
Maketitle(nodeRef) {
// count \maketitle inside DocumentEnvironment
if (
ancestorOfNodeWithType(nodeRef.node, '$Environment')?.type.is(
'DocumentEnvironment'
)
) {
preamble.to = nodeRef.node.from
}
},
})
tree.iterate({
enter(nodeRef) {
return preambleMatcher(nodeRef.type)?.(nodeRef)
},
})
return preamble
}