-
Notifications
You must be signed in to change notification settings - Fork 32
Expand file tree
/
Copy pathConvertTo-FileName.ps1
More file actions
93 lines (83 loc) · 2.97 KB
/
ConvertTo-FileName.ps1
File metadata and controls
93 lines (83 loc) · 2.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<#
.SYNOPSIS
Returns a valid and safe filename from a given string.
.INPUTS
System.String containing a filename that may contain invalid characters.
.OUTPUTS
System.String containing a filename without any invalid characters.
.FUNCTIONALITY
Unicode
.EXAMPLE
'app*.log' |ConvertTo-FileName.ps1
app_.log
.EXAMPLE
'one|two-<three>' |ConvertTo-FileName.ps1 -CurrentPlatformOnly
one_two-_three_
.EXAMPLE
'app-${value}.config' |ConvertTo-FileName.ps1 Ascii -ExcludeChars '%','$','{','}','`'
app-_value_.config
#>
using namespace System.Text
#Requires -Version 7
[CmdletBinding()][OutputType([string])] Param(
# Allows limiting the filename to either ASCII or Basic Multilingual Plane characters, if specified.
[ValidateSet('Bmp', 'Ascii')][string] $OutputBlock,
# The character to use to replace a range of invalid characters.
[rune] $Replacement = '_'[0],
# Characters to include (overrides exclusions).
[ValidateNotNull()][char[]] $IncludeChars = @(),
# Characters to exclude.
[ValidateNotNull()][char[]] $ExcludeChars = @(),
# Runes to include (overrides excludes).
[ValidateNotNull()][rune[]] $IncludeRunes = @(),
# Runes to exclude.
[ValidateNotNull()][rune[]] $ExcludeRunes = @(),
# Indicates that only characters invalid for the current platform should be excluded by default,
# otherwise invalid characters from any platform will be excluded by default (unless overridden).
[switch] $CurrentPlatformOnly,
# The string value to sanitize for use as a filename.
[Parameter(Mandatory=$true,ValueFromPipeline=$true)][string] $InputObject
)
Begin
{
[char[]] $skipchars = $CurrentPlatformOnly ? ([IO.Path]::GetInvalidFileNameChars()) :
@('"', '*', '/', ':', '<', '>', '?', '\', '|')
function Copy-Rune
{
[CmdletBinding()] Param(
[Parameter(Position=0,Mandatory=$true)][rune] $Rune
)
Set-Variable skipping $false -Scope 1
(Get-Variable value -Scope 1).Value.Append($Rune) |Out-Null
}
function Skip-Rune
{
$skipping = Get-Variable skipping -Scope 1
if(!$skipping.Value)
{
$skipping.Value = $true
(Get-Variable value -Scope 1).Value.Append($Replacement) |Out-Null
}
}
}
Process
{
$skipping, $value = $false, (New-Object StringBuilder)
foreach ($rune in $InputObject.EnumerateRunes())
{
if($rune -in $IncludeRunes) {Copy-Rune $rune}
elseif($rune -in $ExcludeRunes) {Skip-Rune}
elseif($rune.IsBmp)
{
[char] $char = $rune.Value
if($char -in $IncludeChars) {Copy-Rune $rune}
elseif($char -in $ExcludeChars) {Skip-Rune}
elseif($char -in $skipchars -or [char]::IsControl($char)) {Skip-Rune}
elseif($OutputBlock -eq 'Ascii' -and !$rune.IsAscii) {Skip-Rune}
else {Copy-Rune $rune}
}
elseif($OutputBlock -eq 'Bmp') {Skip-Rune}
else {Copy-Rune $rune}
}
return $value.ToString()
}