find-preamble-extent.ts 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. import { NodeType, SyntaxNodeRef, Tree } from '@lezer/common'
  2. import { ancestorOfNodeWithType } from '@/features/source-editor/utils/tree-operations/ancestors'
  3. export const findPreambleExtent = (tree: Tree) => {
  4. const preamble = { to: 0 }
  5. let seenDocumentEnvironment = false
  6. const preambleMatcher = NodeType.match<(nodeRef: SyntaxNodeRef) => void>({
  7. 'Title Author Affil Affiliation'(nodeRef) {
  8. preamble.to = nodeRef.node.to
  9. },
  10. DocumentEnvironment(nodeRef) {
  11. // only count the first instance of DocumentEnvironment
  12. if (!seenDocumentEnvironment) {
  13. preamble.to =
  14. nodeRef.node.getChild('Content')?.from ?? nodeRef.node.from
  15. seenDocumentEnvironment = true
  16. }
  17. },
  18. Maketitle(nodeRef) {
  19. // count \maketitle inside DocumentEnvironment
  20. if (
  21. ancestorOfNodeWithType(nodeRef.node, '$Environment')?.type.is(
  22. 'DocumentEnvironment'
  23. )
  24. ) {
  25. preamble.to = nodeRef.node.from
  26. }
  27. },
  28. })
  29. tree.iterate({
  30. enter(nodeRef) {
  31. return preambleMatcher(nodeRef.type)?.(nodeRef)
  32. },
  33. })
  34. return preamble
  35. }