Skip to main content
Inspiring
June 17, 2025
Question

Word Count Script Issues

  • June 17, 2025
  • 2 replies
  • 187 views

Robohelp Version 2022.6.34 | WordCount (baseline script)

I need to generate a word count of our Robohelp projects for translation cost estimates and thought I'd try the WordCount script. When I tried to use it, however, I was greeted with a few errors.

When I double-click to execute the script, I get "Script Execution error withStyles is not a function",

then when I open in edit mode there are the following warnings/errors:

  • Line 19: ['MaterialUI'] is better written in dot notation.
  • Line 86: Unclosed regular expression. Unrecoverable syntax error . (47% scanned)

This is using the built-in WordCount script. I have not edited it in any way. I tried creating a new blank project and get the same with that version of the WordCount. I also tried running output with it as a post-generation script anyway and it failed to generate. 

 

If anyone has experience with these scripts, any tips would be greatly appreciated!

Thanks,

 

JS of the WordCount:

 

const _ = require('lodash')
const fs = require('fs')
const cheerio = require('cheerio')

const{
withStyles,
makeStyles,
Table,
TableBody,
TableCell,
TableHead,
TableRow,
Button,
Paper,
Dialog,
DialogActions,
DialogContent,
DialogTitle
} = window['MaterialUI'];

const StyledTableCell = withStyles(theme => ({
head: {
backgroundColor: theme.palette.common.black,
color: theme.palette.common.white
},
body: {
fontSize: 14,
borderRight: '1px solid rgba(224, 224, 224, 1)'
},
}))(TableCell);

const BoldStyledTableCell = withStyles(theme => ({
head: {
backgroundColor: theme.palette.common.black,
color: theme.palette.common.white,
},
body: {
fontSize: 14,
fontWeight:'bold',
borderRight: '1px solid rgba(224, 224, 224, 1)'
},
}))(TableCell);

const StyledTableRow = withStyles(theme => ({
root: {
'&:nth-of-type(odd)': {
backgroundColor: theme.palette.background.default,
},
},
}))(TableRow);

const useStyles = makeStyles(theme => ({
root: {
width: '99%',
overflowX: 'auto',
},
table: {
minWidth: '100%',
},
}));

function ReportTables() {
const classes = useStyles();

function handleClose(event){
RoboHelp.hideUi()
completed.resolve()
}

function handleDownload(event) {
let wordCountString = 'File Path, Word Count \n'
wordCountString += _.map(wordCounts, (count, path) => `${path},${count}`).join('\n')
wordCountString += `\nTotal,${totalWordCount}`
let newBlob = new Blob([wordCountString], { type: 'text/csv'})
const url = window.URL.createObjectURL(newBlob),
a = document.createElement('a')
a.href = url
a.download = "WordCounts.csv"
a.click()
window.URL.revokeObjectURL(url)
a.remove()
}

return (
<Dialog fullScreen style={{ border: 'rgb(234, 234, 234) solid' }} open={true} onClose={handleClose}>
<DialogTitle>Word Counts</DialogTitle>
<DialogContent>
<Paper className={classes.root}>
<Table className={classes.table}>
<TableHead>
<TableRow>
<StyledTableCell>File Name</StyledTableCell>
<StyledTableCell align="right">Word Count</StyledTableCell>
</TableRow>
</TableHead>
<TableBody>
{_.map(wordCounts, (count, path) => (
<StyledTableRow key={path}>
<StyledTableCell component="th" scope="row">
{RoboHelp.URL.fileName(RoboHelp.URL.toForwardSlash(path))}
</StyledTableCell>
<StyledTableCell align="right">{count}</StyledTableCell>
</StyledTableRow>
))}
<StyledTableRow key={'Total'}>
<BoldStyledTableCell component="th" scope="row">
{"Total"}
</BoldStyledTableCell>
<BoldStyledTableCell align="right">{totalWordCount}</BoldStyledTableCell>
</StyledTableRow>
</TableBody>
</Table>
</Paper>
</DialogContent>
<DialogActions>
<Button color="default" onClick={handleDownload}>
Download
</Button>
<Button color="primary" onClick={handleClose}>
Done
</Button>
</DialogActions>
</Dialog>
);
}

function defer() {
var deferred = {
promise: null,
resolve: null,
reject: null
};
deferred.promise = new Promise((resolve, reject) => {
deferred.resolve = resolve;
deferred.reject = reject;
});
return deferred;
}
let completed = defer();
let wordCounts = {}
let totalWordCount = 0;

async function main() {
//check if the project is open or not
let project = await RoboHelp.getValue(RoboHelp.DATA_KEYS.PROJECT_DATA)
let projectPath = await RoboHelp.getValue(RoboHelp.DATA_KEYS.PROJECT_PATH)
if (project !== undefined) {
DoWork(project, projectPath);
RoboHelp.showUi({ x: 700, y: 400 })
ReactDOM.render(<ReportTables/>, document.getElementById('scripting-container'));
await completed.promise
}
else
alert("Open Project and then run the script");
}

function DoWork(project, projectPath) {
//parse though every thing and count the words
let topFolder = RoboHelp.URL.makeFullPath(_.get(project, 'content.root.path'), projectPath)
let files = RoboHelp.FSUtil.readRecursive(topFolder)
let topics = _.filter(files, file => RoboHelp.FileTypes.isHTML(file))
let snippets = _.filter(files, file => RoboHelp.FileTypes.isSnippet(file))

_.each(topics, topic => GetWordCountFromFile(topic))
_.each(snippets, snippet => GetWordCountFromFile(snippet))
}

function GetWordCountFromFile(filePath) {
let content = fs.readFileSync(filePath)
let tex = RoboHelp.TextUtil.collectText(content)
let $ = cheerio.load(content)
let text = $('body').text()
let words = _.words(text)
let nCount = words.length
totalWordCount += nCount
wordCounts[filePath] = nCount
return nCount;
}

return main();

2 replies

Peter Grainge
Community Expert
Community Expert
June 17, 2025
Use menu (bottom right) to mark as Best Answer or to Highlight particularly useful replies. Found the answer elsewhere? Share it here.
Jeff_Coatsworth
Community Expert
Community Expert
June 17, 2025

Does it also misbehave on the sample project? If so, then unless a scripting expert like @frameexpert chimes in, I think you'd best contact the RH folks - see https://helpx.adobe.com/contact/enterprise-support.other.html#robohelp for your Adobe Support options. I'd recommend using the tcssup@adobe.com e-mail address as it reaches a team dedicated to Technical Communication Suite products including RoboHelp.