Plus/Measure-Readability.ps1
function Measure-Readability { <# .SYNOPSIS Measure readability of input text. .DESCRIPTION This function can ingest text and return the minimum school grade level necessary to understand the text. The following tests are supported: - Flesch-Kincaid Grade Level (default) - Automated Readability Index (ARI) - Coleman-Liau Index (CLI) - Gunning Fog Index (GFI) - SMOG ("Simple Measure Of Gobbledygook") .PARAMETER Type Readability test type (ARI, CLI, etc...) Note: The SMOG readability test requires that the input text contains at least 30 sentences. .EXAMPLE 'This is a sentence. This is another sentence.' | Measure-Readability #> [CmdletBinding()] [OutputType([Int])] Param( [Parameter(Mandatory = $True, Position = 0, ValueFromPipeline = $True)] [String] $Text, [Parameter(Position = 1)] [ValidateSet('FleschKincaidGradeLevel', 'ARI', 'AutomatedReadabilityIndex', 'CLI', 'ColemanLiauIndex', 'GFI', 'GunningFogIndex', 'SMOG')] [String] $Type = 'FleschKincaidGradeLevel', [Switch] $AsJob ) Process { "==> Calculating readability using `"${Type}`" method" | Write-Verbose if ($AsJob) { $ModulePath = Join-Path $PSScriptRoot '..\Plus\Measure-Readability.ps1' $Job = if (Test-Command -Name 'Start-ThreadJob' -Silent) { Start-ThreadJob -Name 'Measure-Readability' -ScriptBlock { . $Using:ModulePath Measure-Readability -Text $Using:Text -Type $Using:Type } } else { Start-Job -Name 'Measure-Readability' -ScriptBlock { . $Using:ModulePath Measure-Readability -Text $Using:Text -Type $Using:Type } } "==> Started job (Id=$($Job.Id)) to measure readability of some text" | Write-Verbose "==> To get results, use `"`$Value = Receive-Job $($Job.Name)`"" | Write-Verbose } else { $Sentences = ($Text -split '(?<=\w)\.') | ForEach-Object { $_.Trim() } | Where-Object { $_.Length -gt 0 } $Words = @() foreach ($Sentence in $Sentences) { $Words += $Sentence -split '\s+' } $Syllables = @() foreach ($Word in $Words) { $Syllables += (Get-SyllableCount $Word) } $Result = switch ($Type) { { $_ -in 'ARI', 'AutomatedReadabilityIndex' } { '==> Measuring readability with Automated Readability Index' | Write-Verbose $LetterCount = ($Text | Measure-Object -Character -IgnoreWhiteSpace).Characters "==> # of Sentences: $($Sentences.Count)" | Write-Verbose "==> # of Words: $($Words.Count)" | Write-Verbose "==> # of Letters: ${LetterCount}" | Write-Verbose (4.71 * ($LetterCount / $Words.Count)) + (0.5 * ($Words.Count / $Sentences.Count)) - 21.43 } { $_ -in 'CLI', 'ColemanLiauIndex' } { '==> Measuring readability with Coleman-Liau Index' | Write-Verbose $LetterCount = ($Text | Measure-Object -Character -IgnoreWhiteSpace).Characters $L = 100 * ($LetterCount / $Words.Count) $S = 100 * ($Sentences.Count / $Words.Count) "==> L: ${L}" | Write-Verbose "==> S: ${S}" | Write-Verbose (0.0588 * $L) - (0.296 * $S) - 15.8 } { $_ -in 'GFI', 'GunningFogIndex' } { '==> Measuring readability with Gunning Fog Index' | Write-Verbose $TotalWords = $Words.Count $ComplexWords = ($Syllables | Where-Object { $_ -ge 3 }).Count "==> # of Sentences: $($Sentences.Count)" | Write-Verbose "==> # of Words: ${TotalWords}" | Write-Verbose "==> # of Complex Words: ${ComplexWords}" | Write-Verbose 0.4 * (($TotalWords / $Sentences.Count) + (100 * ($ComplexWords / $TotalWords))) } 'SMOG' { if ($Sentences.Count -lt 30) { '==> SMOG readability test is not accurate with less than 30 sentences' | Write-Warning } '==> Measuring readability with SMOG' | Write-Verbose $ComplexWords = ($Syllables | Where-Object { $_ -ge 3 }).Count "==> # of Sentences: $($Sentences.Count)" | Write-Verbose "==> # of Complex Words: ${ComplexWords}" | Write-Verbose (1.043 * [Math]::Sqrt($ComplexWords * (30 / $Sentences.Count))) + 3.1291 } Default { # Flesch-Kincaid Grade Level '==> Measuring readability with Flesch-Kincaid Grade Level' | Write-Verbose $TotalWords = $Words.Count $TotalSyllables = Get-Sum $Syllables "==> # of Sentences: $($Sentences.Count)" | Write-Verbose "==> # of Words: ${TotalWords}" | Write-Verbose "==> # of Syllables: ${TotalSyllables}" | Write-Verbose (0.39 * ($TotalWords / $Sentences.Count)) + (11.8 * ($TotalSyllables / $TotalWords)) - 15.59 } } [Math]::Round($Result, 1) } } } |