Skip to content

Commit 93175b8

Browse files
authored
1 parent 06a135d commit 93175b8

File tree

1 file changed

+232
-0
lines changed

1 file changed

+232
-0
lines changed

writing-style.html

+232
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Writing Style Analyzer</title>
7+
<style>
8+
* {
9+
box-sizing: border-box;
10+
}
11+
12+
body {
13+
font-family: Helvetica, Arial, sans-serif;
14+
line-height: 1.6;
15+
margin: 0;
16+
padding: 20px;
17+
background: #f5f5f5;
18+
}
19+
20+
.container {
21+
max-width: 800px;
22+
margin: 0 auto;
23+
background: white;
24+
padding: 20px;
25+
border-radius: 8px;
26+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
27+
}
28+
29+
h1 {
30+
margin-top: 0;
31+
color: #333;
32+
}
33+
34+
textarea {
35+
width: 100%;
36+
height: 200px;
37+
padding: 12px;
38+
border: 1px solid #ddd;
39+
border-radius: 4px;
40+
margin-bottom: 20px;
41+
font-size: 16px;
42+
font-family: inherit;
43+
}
44+
45+
.results {
46+
margin-top: 20px;
47+
}
48+
49+
.category {
50+
margin-bottom: 20px;
51+
padding: 15px;
52+
background: #f8f9fa;
53+
border-radius: 4px;
54+
}
55+
56+
.category h2 {
57+
margin-top: 0;
58+
color: #444;
59+
font-size: 1.2em;
60+
}
61+
62+
.highlight {
63+
background: #ffd700;
64+
padding: 2px 4px;
65+
border-radius: 2px;
66+
}
67+
68+
.warning {
69+
color: #856404;
70+
background-color: #fff3cd;
71+
border: 1px solid #ffeeba;
72+
padding: 10px;
73+
margin-bottom: 10px;
74+
border-radius: 4px;
75+
}
76+
</style>
77+
</head>
78+
<body>
79+
<div class="container">
80+
<h1>Writing Style Analyzer</h1>
81+
<p>Adapted from <a href="https://matt.might.net/articles/shell-scripts-for-passive-voice-weasel-words-duplicates/">these shell scripts</a> published by Matt Might.</p>
82+
<p>Paste your text below to check for weasel words, passive voice, and duplicate words:</p>
83+
<textarea id="input" placeholder="Enter your text here..."></textarea>
84+
<div id="results" class="results"></div>
85+
</div>
86+
87+
<script type="module">
88+
// Weasel words from the bash script
89+
const weaselWords = [
90+
'many', 'various', 'very', 'fairly', 'several', 'extremely',
91+
'exceedingly', 'quite', 'remarkably', 'few', 'surprisingly',
92+
'mostly', 'largely', 'huge', 'tiny', 'excellent', 'interestingly',
93+
'significantly', 'substantially', 'clearly', 'vast', 'relatively',
94+
'completely'
95+
]
96+
97+
// Common irregular verbs for passive voice detection
98+
const irregularVerbs = [
99+
'awoken', 'been', 'born', 'beat', 'become', 'begun', 'bent',
100+
'bound', 'bitten', 'bled', 'blown', 'broken', 'brought',
101+
'built', 'burnt', 'bought', 'caught', 'chosen', 'come',
102+
'dealt', 'done', 'drawn', 'driven', 'eaten', 'fallen',
103+
'fought', 'found', 'flown', 'forgotten', 'given', 'gone',
104+
'grown', 'hung', 'heard', 'hidden', 'held', 'kept', 'known',
105+
'laid', 'led', 'left', 'lost', 'made', 'meant', 'met', 'paid',
106+
'put', 'read', 'run', 'said', 'seen', 'sold', 'sent', 'set',
107+
'shown', 'shut', 'sung', 'sat', 'slept', 'spoken', 'spent',
108+
'stood', 'taken', 'taught', 'told', 'thought', 'thrown',
109+
'understood', 'worn', 'won', 'written'
110+
]
111+
112+
function findWeaselWords(text) {
113+
const results = []
114+
const words = text.toLowerCase().split(/\b/)
115+
116+
words.forEach((word, index) => {
117+
if (weaselWords.includes(word.trim())) {
118+
results.push({
119+
word: word.trim(),
120+
index: index,
121+
context: getContext(text, index)
122+
})
123+
}
124+
})
125+
126+
return results
127+
}
128+
129+
function findPassiveVoice(text) {
130+
const results = []
131+
const beVerbs = ['am', 'is', 'are', 'was', 'were', 'be', 'been', 'being']
132+
const words = text.toLowerCase().split(/\s+/)
133+
134+
words.forEach((word, index) => {
135+
if (beVerbs.includes(word)) {
136+
const nextWord = words[index + 1]
137+
if (nextWord && (
138+
nextWord.endsWith('ed') ||
139+
irregularVerbs.includes(nextWord)
140+
)) {
141+
results.push({
142+
construction: `${word} ${nextWord}`,
143+
context: getContext(text, index)
144+
})
145+
}
146+
}
147+
})
148+
149+
return results
150+
}
151+
152+
function findDuplicateWords(text) {
153+
const results = []
154+
const words = text.toLowerCase().split(/\s+/)
155+
156+
words.forEach((word, index) => {
157+
if (index > 0 && word === words[index - 1]) {
158+
results.push({
159+
word: word,
160+
context: getContext(text, index)
161+
})
162+
}
163+
})
164+
165+
return results
166+
}
167+
168+
function getContext(text, index) {
169+
const words = text.split(/\s+/)
170+
const start = Math.max(0, index - 3)
171+
const end = Math.min(words.length, index + 4)
172+
return words.slice(start, end).join(' ')
173+
}
174+
175+
function displayResults(weasels, passives, duplicates) {
176+
const resultsDiv = document.getElementById('results')
177+
resultsDiv.innerHTML = ''
178+
179+
// Weasel Words
180+
const weaselDiv = document.createElement('div')
181+
weaselDiv.className = 'category'
182+
weaselDiv.innerHTML = `
183+
<h2>Weasel Words</h2>
184+
${weasels.length === 0 ? 'No weasel words found.' :
185+
weasels.map(w => `
186+
<div class="warning">
187+
Found "<span class="highlight">${w.word}</span>" in: "${w.context}"
188+
</div>
189+
`).join('')}
190+
`
191+
resultsDiv.appendChild(weaselDiv)
192+
193+
// Passive Voice
194+
const passiveDiv = document.createElement('div')
195+
passiveDiv.className = 'category'
196+
passiveDiv.innerHTML = `
197+
<h2>Passive Voice</h2>
198+
${passives.length === 0 ? 'No passive voice constructions found.' :
199+
passives.map(p => `
200+
<div class="warning">
201+
Found passive voice "<span class="highlight">${p.construction}</span>" in: "${p.context}"
202+
</div>
203+
`).join('')}
204+
`
205+
resultsDiv.appendChild(passiveDiv)
206+
207+
// Duplicate Words
208+
const duplicateDiv = document.createElement('div')
209+
duplicateDiv.className = 'category'
210+
duplicateDiv.innerHTML = `
211+
<h2>Duplicate Words</h2>
212+
${duplicates.length === 0 ? 'No duplicate words found.' :
213+
duplicates.map(d => `
214+
<div class="warning">
215+
Found duplicate word "<span class="highlight">${d.word}</span>" in: "${d.context}"
216+
</div>
217+
`).join('')}
218+
`
219+
resultsDiv.appendChild(duplicateDiv)
220+
}
221+
222+
// Set up event listener
223+
document.getElementById('input').addEventListener('input', (e) => {
224+
const text = e.target.value
225+
const weasels = findWeaselWords(text)
226+
const passives = findPassiveVoice(text)
227+
const duplicates = findDuplicateWords(text)
228+
displayResults(weasels, passives, duplicates)
229+
})
230+
</script>
231+
</body>
232+
</html>

0 commit comments

Comments
 (0)