Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update for more counting statistics (i.e. sentences, paragraphs, etc.) #26

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
out
node_modules
node_modules
package-lock.json
*.vsix
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ This is a simple extension that illustrates a number of concepts when it comes t

## Functionality

It's pretty simple open up a `Markdown` file and the status bar will have an auto-updating wordcount in it...
It's pretty simple open up a `Markdown` file and the status bar will have an auto-updating wordcount in it. It also...

* Counts number of words highlighted
* Offers other counting data such as characters (excluding spaces), sentences (basic full stop counting) and paragraphs


![Word Count in status bar](images/wordcount.gif)
79 changes: 74 additions & 5 deletions extension.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import {window, workspace, commands, Disposable, ExtensionContext, StatusBarAlignment, StatusBarItem, TextDocument} from 'vscode';
import {window, workspace, commands, Disposable, ExtensionContext, StatusBarAlignment, StatusBarItem, TextDocument, Selection} from 'vscode';

// this method is called when your extension is activated. activation is
// controlled by the activation events defined in package.json
Expand All @@ -14,10 +14,32 @@ export function activate(ctx: ExtensionContext) {
let wordCounter = new WordCounter();
let controller = new WordCounterController(wordCounter);

// define the command to view the summary of the word count
let summaryCommand = commands.registerCommand('wordcount.viewSummary',() => {
// Get the current text editor
let editor = window.activeTextEditor;
if (!editor) {
return;
}

let doc = editor.document;
let sel = editor.selection;
let mode = sel == undefined || sel.isEmpty ? "Total" : "Selection"
window.showInformationMessage(`
${mode}: |
Words: ${wordCounter._getWordCount(doc, sel)} |
Characters (without spaces): ${wordCounter._getCharCount(doc, sel)} |
Sentences: ${wordCounter._getSentenceCount(doc, sel)} |
Paragraphs: ${wordCounter._getParagraphCount(doc, sel)}
`);
});


// add to a list of disposables which are disposed when this extension
// is deactivated again.
ctx.subscriptions.push(controller);
ctx.subscriptions.push(wordCounter);
ctx.subscriptions.push(summaryCommand);
}

export class WordCounter {
Expand All @@ -29,6 +51,7 @@ export class WordCounter {
// Create as needed
if (!this._statusBarItem) {
this._statusBarItem = window.createStatusBarItem(StatusBarAlignment.Left);
this._statusBarItem.command = 'wordcount.viewSummary';
}

// Get the current text editor
Expand All @@ -39,33 +62,79 @@ export class WordCounter {
}

let doc = editor.document;
let sel = editor.selection;

// Only update status if an MD file
if (doc.languageId === "markdown") {
let wordCount = this._getWordCount(doc);
let wordCount = this._getWordCount(doc, sel);

// Update the status bar
this._statusBarItem.text = wordCount !== 1 ? `$(pencil) ${wordCount} Words` : '$(pencil) 1 Word';
this._statusBarItem.text = sel === undefined || sel.isEmpty ? `${wordCount} Words` : `${wordCount} Selected`;
this._statusBarItem.show();
} else {
this._statusBarItem.hide();
}
}

public _getWordCount(doc: TextDocument): number {
let docContent = doc.getText();
public _getWordCount(doc: TextDocument, sel?: Selection): number {
let docContent = sel === undefined || sel.isEmpty ? doc.getText() : doc.getText(sel);

// Parse out unwanted whitespace so the split is accurate
docContent = docContent.replace(/(< ([^>]+)<)/g, '').replace(/\s+/g, ' ');
docContent = docContent.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
let wordCount = 0;

if (docContent != "") {
wordCount = docContent.split(" ").length;
}

return wordCount;
}

//this function counts the number of characters in the main content of the document
public _getCharCount(doc: TextDocument, sel?: Selection): number {
let docContent = sel === undefined || sel.isEmpty ? doc.getText() : doc.getText(sel);

// Parse out unwanted whitespace so the split is accurate
docContent = docContent.replace(/(< ([^>]+)<)/g, '').replace(/\s+/g, '');
docContent = docContent.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
docContent = docContent.replace(' ', '')
let charCount = 0;
if (docContent != "") {
charCount = docContent.length;
}

return charCount;
}

//this function counts the number of sentences across the document by just looking at the number of
// full stops.
public _getSentenceCount(doc: TextDocument, sel?: Selection): number {
let docContent = sel === undefined || sel.isEmpty ? doc.getText() : doc.getText(sel);
let sentenceCount = 0;
if (docContent != "") {
sentenceCount = docContent.split(".").length - 1;
}

return sentenceCount;
}

//this function counts the number of paragraphs across the document by defining a paragraph as characters split by
// two or more new lines
public _getParagraphCount(doc: TextDocument, sel?: Selection): number {
let docContent = sel === undefined || sel.isEmpty ? doc.getText() : doc.getText(sel);
docContent += "\r\n\r\n" /* Added so trailing newlines at the end of the document
can be factored out regardless if the user inputted it or not. Otherwise,
if the user leaves 2 trailing newlines, the program will split it and add both
sides to the counter. */
let paragraphCount = 0;
if (docContent != "") {
paragraphCount = docContent.split(/[^\r\n][\r\n]{4}[\s\n\r]*/).length - 1;
}

return paragraphCount;
}

public dispose() {
this._statusBarItem.dispose();
}
Expand Down
10 changes: 9 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@
"vscode": "0.10.x"
},
"main": "./out/extension",
"contributes": {
"commands": [
{
"command": "wordcount.viewSummary",
"title": "View Word Count Summary"
}
]
},
"scripts": {
"vscode:prepublish": "node ./node_modules/vscode/bin/compile",
"compile": "node ./node_modules/vscode/bin/compile -watch -p ./"
Expand All @@ -35,4 +43,4 @@
"vscode": "0.10.x",
"typescript": "^1.6.2"
}
}
}