diff --git a/CHANGELOG.md b/CHANGELOG.md index fe0b52582..b4b16a064 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log +## [3.1.0] - Prepare for release +### Added +- (#142) LaTeX project word counter by TeXCount. + - Windows users are suggested to upgrade [TeXCount](http://app.uio.no/ifi/texcount/download.html) to version 3.0.1. + ## [3.0.1] - 2017-07-28 ### Fixed - (#208) Extension initialization failed when no root file is found. diff --git a/package.json b/package.json index 16b78864d..670b14a3d 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "displayName": "LaTeX Workshop", "description": "Boost LaTeX typesetting efficiency with preview, compile, autocomplete, colorize, and more.", "icon": "icon.png", - "version": "3.0.1", + "version": "3.1.0", "publisher": "James-Yu", "license": "MIT", "homepage": "https://github.com/James-Yu/LaTeX-Workshop", @@ -153,6 +153,11 @@ "title": "Open citation browser", "category": "LaTeX Workshop" }, + { + "command": "latex-workshop.wordcount", + "title": "Count words in LaTeX document", + "category": "LaTeX Workshop" + }, { "command": "latex-workshop.log", "title": "Show LaTeX log", @@ -293,7 +298,7 @@ "latex-workshop.chktex.path": { "type": "string", "default": "chktex", - "description": "Define the location of ChkTeX executive file.\nThis command will be joint with `latex-workshop.linter_arguments_*` and required arguments to form a complete command of ChkTeX." + "description": "Define the location of ChkTeX executive file.\nThis command will be joint with `latex-workshop.chktex.args.*` and required arguments to form a complete command of ChkTeX." }, "latex-workshop.chktex.args.active": { "type": "array", @@ -322,6 +327,18 @@ "default": 300, "description": "Defines the time interval in milliseconds between invoking LaTeX linter on the active file." }, + "latex-workshop.texcount.path": { + "type": "string", + "default": "texcount", + "description": "Define the location of TeXCount executive file/script.\nThis command will be joint with `latex-workshop.texcount.args` and required arguments to form a complete command of TeXCount." + }, + "latex-workshop.texcount.args": { + "type": "array", + "default": [ + "-merge" + ], + "description": "TeXCount arguments to count words in LaTeX document of the entire project from the root file.\nArguments must be in separate strings in the array. Additional arguments, i.e., `%DOC%` will be appended when constructing the command." + }, "latex-workshop.intellisense.citation.type": { "type": "string", "enum": [ diff --git a/src/commander.ts b/src/commander.ts index f6853ccbd..e4f764d78 100644 --- a/src/commander.ts +++ b/src/commander.ts @@ -84,6 +84,11 @@ export class Commander { this.extension.completer.citation.browser() } + wordcount() { + this.extension.logger.addLogMessage(`WORDCOUNT command invoked.`) + this.extension.counter.count() + } + log() { this.extension.logger.addLogMessage(`LOG command invoked.`) this.extension.logger.showLog() diff --git a/src/components/counter.ts b/src/components/counter.ts new file mode 100644 index 000000000..7f5208380 --- /dev/null +++ b/src/components/counter.ts @@ -0,0 +1,51 @@ +import * as vscode from 'vscode' +import * as cp from 'child_process' + +import {Extension} from '../main' + +export class Counter { + extension: Extension + + constructor(extension: Extension) { + this.extension = extension + } + + count() { + if (this.extension.manager.rootFile !== undefined) { + this.extension.manager.findRoot() + } + const configuration = vscode.workspace.getConfiguration('latex-workshop') + const args = configuration.get('texcount.args') as string[] + const proc = cp.spawn(configuration.get('texcount.path') as string, args.concat([this.extension.manager.rootFile])) + proc.stdout.setEncoding('utf8') + proc.stderr.setEncoding('utf8') + + let stdout = '' + proc.stdout.on('data', newStdout => { + stdout += newStdout + }) + + let stderr = '' + proc.stderr.on('data', newStderr => { + stderr += newStderr + }) + + proc.on('error', err => { + this.extension.logger.addLogMessage(`Cannot count words: ${err.message}, ${stderr}`) + vscode.window.showErrorMessage('TeXCount failed. Please refer to LaTeX Workshop Output for details.') + }) + + proc.on('exit', exitCode => { + if (exitCode !== 0) { + this.extension.logger.addLogMessage(`Cannot count words, code: ${exitCode}, ${stderr}`) + vscode.window.showErrorMessage('TeXCount failed. Please refer to LaTeX Workshop Output for details.') + } else { + const result = /Words in text: ([0-9]*)/g.exec(stdout) + if (result) { + vscode.window.showInformationMessage(`There are ${result[1]} words in the current LaTeX project. Please refer to LaTeX Workshop Output for details.`) + } + this.extension.logger.addLogMessage(`TeXCount log:\n${stdout}`) + } + }) + } +} diff --git a/src/components/logger.ts b/src/components/logger.ts index 4546e1371..2157aac80 100644 --- a/src/components/logger.ts +++ b/src/components/logger.ts @@ -43,7 +43,7 @@ export class Logger { } const icon = this.status.text.split(' ')[0] const message = this.status.tooltip - this.status.text = `${icon} Previous message: ${message}` + this.status.text = `${icon} ${message}` if (timeout > 0) { this.statusTimeout = setTimeout(() => this.status.text = `${icon}`, timeout) } diff --git a/src/main.ts b/src/main.ts index 82b58d5d2..9d25c874c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -13,6 +13,7 @@ import {Locator} from './components/locator' import {Parser} from './components/parser' import {Linter} from './components/linter' import {Cleaner} from './components/cleaner' +import {Counter} from './components/counter' import {Completer} from './providers/completion' import {CodeActions} from './providers/codeactions' @@ -116,6 +117,7 @@ export async function activate(context: vscode.ExtensionContext) { vscode.commands.registerCommand('latex-workshop.clean', () => extension.commander.clean()) vscode.commands.registerCommand('latex-workshop.actions', () => extension.commander.actions()) vscode.commands.registerCommand('latex-workshop.citation', () => extension.commander.citation()) + vscode.commands.registerCommand('latex-workshop.wordcount', () => extension.commander.wordcount()) vscode.commands.registerCommand('latex-workshop.log', () => extension.commander.log()) vscode.commands.registerCommand('latex-workshop.code-action', (d, r, c, m) => extension.codeActions.runCodeAction(d, r, c, m)) vscode.commands.registerCommand('latex-workshop.goto-section', (filePath, lineNumber) => extension.commander.gotoSection(filePath, lineNumber)) @@ -213,6 +215,7 @@ export class Extension { completer: Completer linter: Linter cleaner: Cleaner + counter: Counter codeActions: CodeActions logProvider: LaTeXLogProvider nodeProvider: SectionNodeProvider @@ -230,6 +233,7 @@ export class Extension { this.completer = new Completer(this) this.linter = new Linter(this) this.cleaner = new Cleaner(this) + this.counter = new Counter(this) this.codeActions = new CodeActions(this) this.logProvider = new LaTeXLogProvider(this) this.nodeProvider = new SectionNodeProvider(this)