feat: use regex to parse checkboxes in text and return info about them
continuous-integration/drone/pr Build is passing
Details
continuous-integration/drone/pr Build is passing
Details
This commit is contained in:
parent
856166a4ae
commit
b70bba5401
|
@ -3,60 +3,54 @@ const listPrefixes = ['*', '-']
|
|||
const unchecked = '[ ]'
|
||||
const checked = '[x]'
|
||||
|
||||
interface CheckboxStatistics {
|
||||
total: number
|
||||
checked: number
|
||||
}
|
||||
|
||||
interface MatchedCheckboxes {
|
||||
checked: number[]
|
||||
unchecked: number[]
|
||||
}
|
||||
|
||||
const getCheckboxesInText = (text: string): MatchedCheckboxes => {
|
||||
const regex = /[*-] \[[ x]]/g
|
||||
let match
|
||||
const checkboxes: MatchedCheckboxes = {
|
||||
checked: [],
|
||||
unchecked: [],
|
||||
}
|
||||
|
||||
while ((match = regex.exec(text)) !== null) {
|
||||
if (match[0].endsWith(checked)) {
|
||||
checkboxes.checked.push(match.index)
|
||||
} else {
|
||||
checkboxes.unchecked.push(match.index)
|
||||
}
|
||||
}
|
||||
|
||||
return checkboxes
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the indices where checkboxes start and end in the given text.
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
export const findCheckboxesInText = (text: string): number[] => {
|
||||
let inChecked: number, inUnchecked: number, startIndex: number = 0
|
||||
// We're building an array with all checkboxes, checked or unchecked.
|
||||
// I've found this to be the best way to always get the results I need.
|
||||
// The difficulty without an index is that we need to get all checkboxes, checked and unchecked
|
||||
// and calculate our index based off that to compare it and find the checkbox we need.
|
||||
let checkboxes: number[] = []
|
||||
const checkboxes = getCheckboxesInText(text)
|
||||
|
||||
// Searching in two different loops for each search term since that is way easier and more predicatble
|
||||
// More "intelligent" solutions sometimes don't have all values or duplicates.
|
||||
// Because we're sorting and removing duplicates of them, we can safely put everything in one giant array.
|
||||
listPrefixes.forEach(pref => {
|
||||
while ((inChecked = text.indexOf(`${pref} ${checked}`, startIndex)) > -1) {
|
||||
checkboxes.push(inChecked)
|
||||
startIndex = startIndex + searchLength
|
||||
}
|
||||
|
||||
startIndex = 0
|
||||
while ((inUnchecked = text.indexOf(`${pref} ${unchecked}`, startIndex)) > -1) {
|
||||
checkboxes.push(inUnchecked)
|
||||
startIndex = startIndex + searchLength
|
||||
}
|
||||
})
|
||||
|
||||
checkboxes.sort((a, b) => a - b)
|
||||
checkboxes = checkboxes.filter((v, i, s) => s.indexOf(v) === i && v > -1)
|
||||
|
||||
return checkboxes
|
||||
}
|
||||
|
||||
interface CheckboxStatistics {
|
||||
total: number
|
||||
checked: number
|
||||
return [
|
||||
...checkboxes.checked,
|
||||
...checkboxes.unchecked,
|
||||
].sort()
|
||||
}
|
||||
|
||||
export const getChecklistStatistics = (text: string): CheckboxStatistics => {
|
||||
const checkboxes = findCheckboxesInText(text)
|
||||
const checkboxes = getCheckboxesInText(text)
|
||||
|
||||
const res: CheckboxStatistics = {
|
||||
total: checkboxes.length,
|
||||
checked: 0,
|
||||
return {
|
||||
total: checkboxes.checked.length + checkboxes.unchecked.length,
|
||||
checked: checkboxes.checked.length,
|
||||
}
|
||||
|
||||
checkboxes.forEach(c => {
|
||||
const box = text.substr(c, searchLength)
|
||||
if (box.trim().endsWith(checked)) {
|
||||
res.checked++
|
||||
}
|
||||
})
|
||||
|
||||
return res
|
||||
}
|
||||
|
|
Reference in New Issue