Skip to content

Commit

Permalink
feat: repeated words check validation
Browse files Browse the repository at this point in the history
  • Loading branch information
NGPixel committed Feb 17, 2025
1 parent 494b69d commit 0c03890
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 2 deletions.
31 changes: 31 additions & 0 deletions src/components/DrawerChecks.vue
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ q-list
import { onBeforeUnmount, onMounted } from 'vue'
import { useQuasar } from 'quasar'
import { checkArticles } from 'src/tools/articles'
import { checkRepeatedWords } from 'src/tools/repeated-words'
import { checkHyphenation } from 'src/tools/hyphenation'
import { checkInclusiveLanguage } from 'src/tools/inclusive-language'
import { checkNonAscii } from 'src/tools/non-ascii'
Expand Down Expand Up @@ -153,6 +154,13 @@ const valChecks = [
description: 'Check for common placeholders',
icon: 'mdi-select-remove',
click: () => placeholdersCheck()
},
{
key: 'repeatedWords',
title: 'Repeated Words Check',
description: 'Check for accidental repeated terms',
icon: 'mdi-repeat',
click: () => repeatedWordsCheck()
}
]
Expand Down Expand Up @@ -251,13 +259,33 @@ function placeholdersCheck (silent = false) {
}
}
function repeatedWordsCheck (silent) {
const results = checkRepeatedWords(modelStore[docsStore.activeDocument.id].getValue())
if (results.count < 1) {
editorStore.setValidationCheckState('repeatedWords', 1)
editorStore.setValidationCheckDetails('repeatedWords', [])
if (!silent) {
$q.notify({
message: 'Looks good!',
caption: 'No repeated terms found.',
color: 'positive',
icon: 'mdi-repeat'
})
}
} else {
editorStore.setValidationCheckState('repeatedWords', -2)
editorStore.setValidationCheckDetails('repeatedWords', results)
}
}
function runAllChecks () {
editorStore.clearErrors()
articlesCheck(true)
hyphenationCheck(true)
inclusiveLangCheck(true)
nonAsciiCheck(true)
placeholdersCheck(true)
repeatedWordsCheck(true)
if (editorStore.errors.length < 1) {
$q.notify({
Expand Down Expand Up @@ -290,6 +318,9 @@ function runSelectedCheck (key) {
case 'placeholders':
placeholdersCheck(true)
break
case 'repeatedWords':
repeatedWordsCheck(true)
break
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/stores/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,16 @@ export const useEditorStore = defineStore('editor', {
hyphenation: 0,
inclusiveLanguage: 0,
nonAscii: 0,
placeholders: 0
placeholders: 0,
repeatedWords: 0
},
validationChecksDetails: {
articles: [],
hyphenation: [],
inclusiveLanguage: [],
nonAscii: [],
placeholders: []
placeholders: [],
repeatedWords: []
},
wordWrap: true,
workingDirectory: '',
Expand Down
69 changes: 69 additions & 0 deletions src/tools/repeated-words.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { sortBy } from 'lodash-es'
import { decorationsStore } from 'src/stores/models'

export function checkRepeatedWords (text) {
const matchRgx = /\b(\w+)\s+\1\b/gi
const textLines = text.split('\n')

const decorations = []
const occurences = []
const details = []
const termCount = {}
for (const [lineIdx, line] of textLines.entries()) {
for (const match of line.matchAll(matchRgx)) {
const term = match[1].toLowerCase()
let occIdx = occurences.indexOf(term)
if (occIdx < 0) {
occIdx = occurences.push(term) - 1
}
decorations.push({
options: {
hoverMessage: {
value: `Repeated term "${match[1]}" detected.`
},
className: 'dec-warning',
minimap: {
position: 1
},
glyphMarginClassName: 'dec-warning-margin'
},
range: {
startLineNumber: lineIdx + 1,
startColumn: match.index + 1,
endLineNumber: lineIdx + 1,
endColumn: match.index + 1 + match[0].length
}
})
details.push({
key: crypto.randomUUID(),
group: occIdx + 1,
message: match[1].toLowerCase(),
range: {
startLineNumber: lineIdx + 1,
startColumn: match.index + 1,
endLineNumber: lineIdx + 1,
endColumn: match.index + 1 + match[0].length
}
})
if (termCount[term]) {
termCount[term]++
} else {
termCount[term] = 1
}
}
}

decorationsStore.get('repeatedWords').set(decorations)

return {
count: decorations.length,
details: sortBy(details, d => d.range.startLineNumber),
hasTextOutput: true,
getTextOutput: () => {
return `Repeated Words
-------------
${Object.entries(termCount).map(([k, v]) => `${k} (${v})`).join('\n')}
`
}
}
}

0 comments on commit 0c03890

Please sign in to comment.