Utils/fold.ps1
|
Register-GnuUtil @{ Name = 'fold' Category = 'Viewing file contents' Synopsis = 'Wrap each input line to fit in specified width.' Usage = @('fold [OPTION]... [FILE]...') Description = @('Wrap input lines in each FILE, writing to standard output.', '', 'With no FILE, or when FILE is -, read standard input.') FileOperands = $true NumericOption = 'w' Options = @( @{ Short = 'b'; Long = 'bytes'; Help = 'count bytes rather than columns' } @{ Short = 's'; Long = 'spaces'; Help = 'break at spaces' } @{ Short = 'w'; Long = 'width'; Arg = 'WIDTH'; Help = 'use WIDTH columns instead of 80' } ) Notes = @('PowerShell note: -b counts characters (UTF-16 code units), not UTF-8 bytes.') } function script:Get-GnuFoldColumn { <# .SYNOPSIS The column after printing Char at Column (GNU fold's adjust_column). #> param([int]$Column, [char]$Char, [bool]$Bytes) if ($Bytes) { return $Column + 1 } switch ([int]$Char) { 8 { if ($Column -gt 0) { return $Column - 1 } else { return 0 } } 13 { return 0 } 9 { return $Column + 8 - ($Column % 8) } } $Column + 1 } function script:Split-GnuFoldLine { <# .SYNOPSIS Folds one input line into output lines. #> param( [Parameter(Mandatory)][AllowEmptyString()][string]$Line, [int]$Width, [bool]$Bytes, [bool]$Spaces ) $buffer = New-Object System.Text.StringBuilder $column = 0 $index = 0 while ($index -lt $Line.Length) { $char = $Line[$index] $next = Get-GnuFoldColumn -Column $column -Char $char -Bytes $Bytes if ($next -gt $Width -and $buffer.Length -gt 0) { if ($Spaces) { $text = $buffer.ToString() $blank = $text.LastIndexOfAny([char[]]@(' ', "`t")) if ($blank -ge 0) { $text.Substring(0, $blank + 1) $rest = $text.Substring($blank + 1) [void]$buffer.Clear().Append($rest) $column = 0 foreach ($restChar in $rest.ToCharArray()) { $column = Get-GnuFoldColumn -Column $column -Char $restChar -Bytes $Bytes } continue } } $buffer.ToString() [void]$buffer.Clear() $column = 0 continue } [void]$buffer.Append($char) $column = $next $index++ } $buffer.ToString() } |