Cybrkyd's Git Repositories

writegood - commit: c1834fb

commit c1834fbbef1276640dda1cfb1070bec431686e260bd4daa4ca7b9922b4a3496e
author cybrkyd <noreply@cybrkyd.com> 2024-02-18 13:51:06 +0000
committer cybrkyd <noreply@cybrkyd.com> 2024-02-18 13:51:06 +0000

Commit Message

Grammar check

📊 Diffstat

index.html 148
1 files changed, 148 insertions(+), 0 deletions(-)

Diff

commit c1834fbbef1276640dda1cfb1070bec431686e260bd4daa4ca7b9922b4a3496e
Author: cybrkyd <noreply@cybrkyd.com>
Date: Sun Feb 18 13:51:06 2024 +0000
Grammar check
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..ff7ad73
--- /dev/null
+++ b/index.html
@@ -0,0 +1,148 @@
+ <!DOCTYPE html>
+ <html lang="en">
+ <head>
+ <meta charset="UTF-8" />
+ <title>Transition Word Checker</title>
+ <style>
+ body { font-family: sans-serif; padding: 2em; max-width: 700px; margin: auto; }
+ #editor {
+ border: 1px solid #ccc;
+ padding: 1em;
+ height: 300px;
+ resize: both;
+ overflow: auto;
+ margin-bottom: 1em;
+ font-size: 1em;
+ white-space: pre-wrap;
+ }
+
+ button { padding: 0.5em 1em; font-size: 1em; }
+ #result { margin-top: 1em; font-size: 1.2em; font-weight: bold; }
+ .low { color: red; }
+ .high { color: green; }
+ .highlight { background-color: yellow; }
+ #breakdown { margin-top: 0.5em; font-size: 1em; font-weight: normal; }
+ #breakdown ul { margin: 0.5em 0 0 1em; padding: 0; }
+ </style>
+ </head>
+ <body>
+ <h1>Transition Word Checker</h1>
+ <div id="editor" contenteditable="true" spellcheck="true" placeholder="Paste article text here..."></div>
+ <button onclick="checkTransitions()">Check</button>
+ <div id="result"></div>
+ <div id="breakdown"></div>
+
+ <script>
+ const transitionalWords = [
+ "above all", "accordingly", "additionally", "after all", "again", "albeit", "all in all", "all things considered", "also", "alternatively", "although", "altogether", "another key point", "another view is", "as a matter of fact", "as a result", "as an example", "as an illustration", "as can be seen", "as exemplified by", "as follows", "as has been noted", "as shown above", "as soon as", "as well as", "at the present time", "at the same time", "at this instant", "basically", "be that as it may", "because of", "because of this", "besides", "better", "by all means", "by and large", "by contrast", "by the same token", "certainly", "chiefly", "comparatively", "compared with", "consequently", "conversely", "correspondingly", "count", "despite", "different from", "due to", "equally", "equally important", "especially", "even if", "even so", "eventually", "evidence illustrates that", "expressively", "finally moreover", "for example", "for instance", "for one thing", "for the most part", "for the purpose of", "for this reason", "formerly", "forthwith", "frequently", "from time to time", "further", "furthermore", "generally speaking", "given that", "given these points", "hence", "henceforth", "however", "identically", "immediately", "important to realise", "in a moment", "in a word", "in addition", "in any event", "in brief", "in case", "in comparison", "in conclusion", "in contrast", "in detail", "in due time", "in either case", "in essence", "in fact", "in general", "in light of", "in like manner", "in order to", "in other terms", "in other words", "in particular", "in reality", "in short", "in spite of", "in summary", "in that case", "in the event that", "in the final analysis", "in the first place", "in the hope that", "in the long run", "in the meantime", "in the same way", "in this case", "in time", "in view of", "in view of this", "inasmuch as", "including", "indeed", "instead", "it can be seen", "it follows that", "it must be remembered", "lest", "likewise", "mainly", "markedly", "meanwhile", "moreover", "namely", "nevertheless", "next", "nonetheless", "not only", "not to mention", "notably", "notwithstanding", "of course", "on balance", "on the condition that", "on the contrary", "on the negative side", "on the other hand", "on the positive side", "on the whole", "or", "ordinarily", "otherwise", "overall", "owing to", "particularly", "point often overlooked", "prior to", "provided that", "quickly", "rather", "regarding", "regardless", "resulting from", "significantly", "similarly", "since", "so as to", "so long as", "so that", "sooner or later", "specifically", "straightaway", "subsequently", "such as", "surely", "surprisingly", "that implies", "that is to say", "the consequence is", "the consequences are", "the first thing to remember", "the result is", "the results are", "then", "then again", "therefore", "thereupon", "this suggests that", "thus", "to be sure", "to begin with", "to clarify", "to conclude", "to demonstrate", "to emphasise", "to enumerate", "to explain", "to point out", "to put it another way", "to put it differently", "to repeat", "to say nothing of", "to sum up", "to summarise", "to the end that", "together with", "too", "truly", "under those circumstances", "uniquely", "unless", "until now", "up to the present time", "usually", "whenever", "whereas", "while it may be true", "while that may be true", "with attention to", "with this in mind", "with this intention", "without delay", "yet", "whereas"
+ ];
+
+ const midSentenceOnlyWords = [
+ "suggests that", "because", "especially"
+ ];
+
+ function escapeHtml(text) {
+ const div = document.createElement("div");
+ div.textContent = text;
+ return div.innerHTML;
+ }
+
+ function checkTransitions() {
+ const editor = document.getElementById("editor");
+ const inputText = editor.innerText;
+ const rawText = inputText.toLowerCase();
+ const sentences = rawText.match(/[^.!?]+[.!?]+/g) || [];
+
+ let totalCount = 0;
+ let midCount = 0;
+ const found = {};
+ const midFound = {};
+
+ let highlightedHTML = escapeHtml(inputText);
+
+ for (const sentence of sentences) {
+ const trimmed = sentence.trim();
+ const lower = trimmed.toLowerCase();
+
+ for (const phrase of transitionalWords) {
+ const phraseRegexStart = new RegExp(`^${phrase}\\b`, "i");
+ const phraseRegexAfterSemi = new RegExp(`;\\s*${phrase}\\b`, "gi");
+
+ let count = 0;
+
+ if (phraseRegexStart.test(lower)) {
+ count++;
+ }
+
+ const semiMatches = lower.match(phraseRegexAfterSemi);
+ if (semiMatches) {
+ count += semiMatches.length;
+ }
+
+ if (count > 0) {
+ totalCount += count;
+ found[phrase] = (found[phrase] || 0) + count;
+ }
+ }
+
+ for (const phrase of midSentenceOnlyWords) {
+ const midRegex = new RegExp(`\\b${phrase}\\b`, "gi");
+
+ let match;
+ while ((match = midRegex.exec(lower)) !== null) {
+ const before = lower.slice(0, match.index).trim();
+ if (before.length > 0 && !before.endsWith(".")) {
+ midCount++;
+ midFound[phrase] = (midFound[phrase] || 0) + 1;
+ }
+ }
+ }
+ }
+
+ for (const phrase of Object.keys(found)) {
+ const regex = new RegExp(`\\b(${phrase})\\b`, "gi");
+ highlightedHTML = highlightedHTML.replace(regex, `<span class="highlight">$1</span>`);
+ }
+
+ for (const phrase of Object.keys(midFound)) {
+ const regex = new RegExp(`\\b(${phrase})\\b`, "gi");
+ highlightedHTML = highlightedHTML.replace(regex, `<span class="highlight">$1</span>`);
+ }
+
+ editor.innerHTML = highlightedHTML;
+
+ const combinedCount = totalCount + midCount;
+ const percentage = sentences.length
+ ? ((combinedCount / sentences.length) * 100).toFixed(1)
+ : 0;
+
+ const result = document.getElementById("result");
+ result.innerText = `Transitions: ${combinedCount} (${percentage}%)`;
+ result.className = (percentage < 10) ? "low" : "high";
+
+ const breakdown = document.getElementById("breakdown");
+ let html = "<div><strong>Found:</strong><ul>";
+
+ const sorted = Object.entries(found).sort((a, b) => a[0].localeCompare(b[0]));
+ for (const [word, count] of sorted) {
+ html += `<li>${word}: ${count}</li>`;
+ }
+
+ if (midCount > 0) {
+ html += "</ul><br><strong>Mid-sentence only:</strong><ul>";
+ const sortedMid = Object.entries(midFound).sort((a, b) => a[0].localeCompare(b[0]));
+ for (const [word, count] of sortedMid) {
+ html += `<li>${word}: ${count}</li>`;
+ }
+ }
+
+ html += "</ul></div>";
+ breakdown.innerHTML = html;
+ }
+ </script>
+
+
+
+ </body>
+ </html>
+