From bc154642dac26beb425ffe78885e58def3a2448b Mon Sep 17 00:00:00 2001 From: Mathias Jakobsen Date: Fri, 5 Sep 2025 11:03:23 +0100 Subject: [PATCH] Merge pull request #28315 from overleaf/mj-word-count-cite [web] Support citations in client side word count GitOrigin-RevId: d3ba3d6853d87059a202366f0c47bd9d7ba53cd8 --- .../utils/count-words-in-file.ts | 25 +++++++++++++------ .../utils/count-words-in-file.test.ts | 8 +++--- .../word-count-modal/utils/word-count.tex | 3 +++ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/services/web/frontend/js/features/word-count-modal/utils/count-words-in-file.ts b/services/web/frontend/js/features/word-count-modal/utils/count-words-in-file.ts index a57f7a84fb..1a1127f949 100644 --- a/services/web/frontend/js/features/word-count-modal/utils/count-words-in-file.ts +++ b/services/web/frontend/js/features/word-count-modal/utils/count-words-in-file.ts @@ -165,15 +165,24 @@ export const countWordsInFile = ( context: currentContext, }) }, - Command(nodeRef) { - const child = nodeRef.node.getChild('UnknownCommand') - if (!child) return + Cite(nodeRef) { + // Count as \cite[text]{citation} + const optionalArgs = nodeRef.node.getChildren('OptionalArgument') + for (const arg of optionalArgs) { + // We normally ignore ShortOptionalArg, so we need to iterate it + // explicitly + const child = arg.getChild('ShortOptionalArg') + if (!child) continue + iterateNode(child, 'text') + } + return false + }, + UnknownCommand(nodeRef) { + const macro = + nodeRef.node.getChild('$CtrlSeq') ?? nodeRef.node.getChild('$CtrlSym') + if (!macro) return - const grandchild = - child.getChild('$CtrlSeq') ?? child.getChild('$CtrlSym') - if (!grandchild) return - - const commandName = content.substring(grandchild.from + 1, grandchild.to) + const commandName = content.substring(macro.from + 1, macro.to) if (!commandName) return switch (commandName) { diff --git a/services/web/test/frontend/features/word-count-modal/utils/count-words-in-file.test.ts b/services/web/test/frontend/features/word-count-modal/utils/count-words-in-file.test.ts index 1a360e6386..c4ea396023 100644 --- a/services/web/test/frontend/features/word-count-modal/utils/count-words-in-file.test.ts +++ b/services/web/test/frontend/features/word-count-modal/utils/count-words-in-file.test.ts @@ -65,12 +65,12 @@ describe('word-count', function () { captionWords: 4, footnoteCharacters: 8, footnoteWords: 2, - headCharacters: 296, - headWords: 52, + headCharacters: 305, + headWords: 53, otherCharacters: 10, otherWords: 2, - textCharacters: 193, - textWords: 42, + textCharacters: 201, + textWords: 44, }) }) diff --git a/services/web/test/frontend/features/word-count-modal/utils/word-count.tex b/services/web/test/frontend/features/word-count-modal/utils/word-count.tex index 4522d6a3bc..f43572a925 100644 --- a/services/web/test/frontend/features/word-count-modal/utils/word-count.tex +++ b/services/web/test/frontend/features/word-count-modal/utils/word-count.tex @@ -115,4 +115,7 @@ $2+3=5$ % 0 $ 2+3 \text{ is equal to } 5 $ +\section{citations} +\cite[two words]{example2025} % 2 in text (citekey ignored) + \end{document}