Merge pull request #28128 from overleaf/mj-client-word-count-magic-comments

[web] Support some texcount magic comments in client side word count

GitOrigin-RevId: 12749876edbf7940ca9adfc63fcc7e787894e727
This commit is contained in:
Mathias Jakobsen
2025-09-03 08:06:28 +00:00
committed by Copybot
parent 1625cc7848
commit 8282aa85f2
3 changed files with 79 additions and 3 deletions
@@ -139,6 +139,10 @@ export const countWordsInFile = (
const headMatcher = NodeType.match<
(nodeRef: SyntaxNodeRef) => boolean | void
>({
Comment(nodeRef) {
handleComment(nodeRef)
return false
},
Title(nodeRef) {
data.headers++
iterateNode(nodeRef, 'header')
@@ -149,6 +153,10 @@ export const countWordsInFile = (
const bodyMatcher = NodeType.match<
(nodeRef: SyntaxNodeRef) => boolean | void
>({
Comment(nodeRef) {
handleComment(nodeRef)
return false
},
Normal(nodeRef) {
textNodes.push({
from: nodeRef.from,
@@ -265,17 +273,48 @@ export const countWordsInFile = (
const preambleExtent = findPreambleExtent(tree)
const state = {
skipping: false,
}
const TC_REGEX = /^%+TC:\s*(\w+)\s*/i
const handleComment = (nodeRef: SyntaxNodeRef) => {
const comment = content.slice(nodeRef.from, nodeRef.to)
// look for TeXcount instructions
const match = TC_REGEX.exec(comment)
if (match) {
switch (match[1].toLowerCase()) {
case 'ignore':
state.skipping = true
break
case 'endignore':
state.skipping = false
break
default:
break
}
}
}
tree.iterate({
from: 0,
to: preambleExtent.to,
enter(nodeRef) {
enter(nodeRef: SyntaxNodeRef) {
if (state.skipping && !nodeRef.type.is('Comment')) {
return false
}
return headMatcher(nodeRef.type)?.(nodeRef)
},
})
tree.iterate({
from: preambleExtent.to,
enter(nodeRef) {
enter(nodeRef: SyntaxNodeRef) {
if (state.skipping && !nodeRef.type.is('Comment')) {
return false
}
return bodyMatcher(nodeRef.type)?.(nodeRef)
},
})