Skip to content

Commit

Permalink
feat: PSJekyll.FormatYaml ( Fixes #21 )
Browse files Browse the repository at this point in the history
  • Loading branch information
James Brundage committed Oct 1, 2024
1 parent c114646 commit 2e18c7d
Showing 1 changed file with 188 additions and 0 deletions.
188 changes: 188 additions & 0 deletions Types/PSJekyll/FormatYAML.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
<#
.SYNOPSIS
Formats objects as YAML
.DESCRIPTION
Formats an object as YAML.
.EXAMPLE
Format-Yaml -InputObject @("a", "b", "c")
.EXAMPLE
@{a="b";c="d";e=@{f=@('g')}} | Format-Yaml
#>
param(
# The InputObject.
[Parameter(ValueFromPipeline)]
[PSObject]
$InputObject,

# If set, will make a YAML header by adding a YAML Document tag above and below output.
[Alias('YAMLDocument')]
[switch]
$YamlHeader,

[int]
$Indent = 0,

# The maximum depth of objects to include.
# Beyond this depth, an empty string will be returned.
[int]
$Depth
)

begin {
if (-not $Depth) { $depth = $FormatEnumerationLimit }
$toYaml = {
param(
[Parameter(ValueFromPipeline,Position=0)]$Object,
[Object]$Parent,
[Object]$GrandParent,
[int]$Indent = 0)

begin { $n = 0; $mySelf = $myInvocation.MyCommand.ScriptBlock }
process {
$n++
if ($Object -eq $null) { return }

if ($depth) {
$myDepth = $indent / 2
if ($myDepth -gt $depth) {
return ''
}
}

if ($Parent -and $Parent -is [Collections.IList]) {
if ($Parent.IndexOf($Object) -gt 0) { ' ' * $Indent }
'- '
}

#region Primitives
if ( $Object -is [string] ) { # If it's a string
if ($object -match '\n') { # see if it's a multline string.
"|" # If it is, emit the multiline indicator
$indent +=2
foreach ($l in $object -split '(?>\r\n|\n)') { # and emit each line indented
[Environment]::NewLine
' ' * $indent
$l
}
$indent -=2
} elseif ("$object".Contains('*')) {
"'$($Object -replace "'","''")'"
} else {
$object
}

if ($Parent -is [Collections.IList]) { # If the parent object was a list
[Environment]::NewLine # emit a newline.
}
return # Once the string has been emitted, return.
}
if ( $Object.GetType().IsPrimitive ) { # If it is a primitive type
"$Object".ToLower() # Emit it in lowercase.
if ($Parent -is [Collections.IList]) {
[Environment]::NewLine
}
return
}
#endregion Primitives

#region KVP
if ( $Object -is [Collections.DictionaryEntry] -or $object -is [Management.Automation.PSPropertyInfo]) {
if ($Parent -isnot [Collections.IList] -and
($GrandParent -isnot [Collections.IList] -or $n -gt 1)) {
[Environment]::NewLine + (" " * $Indent)
}
if ($object.Key -and $Object.Key -is [string]) {
$Object.Key +": "
} elseif ($object.Name -and $object.Name -is [string]) {
$Object.Name +": "
}
}

if ( $Object -is [Collections.DictionaryEntry] -or $Object -is [Management.Automation.PSPropertyInfo]) {
& $mySelf -Object $Object.Value -Parent $Object -GrandParent $parent -Indent $Indent
return
}
#endregion KVP


#region Nested
if ($parent -and ($Object -is [Collections.IDictionary] -or $Object -is [PSObject])) {
$Indent += 2
}
elseif ($object -is [Collections.IList]) {
$allPrimitive = 1
foreach ($Obj in $Object) {
$allPrimitive = $allPrimitive -band (
$Obj -is [string] -or
$obj.GetType().IsPrimitive
)
}
if ($parent -and -not $allPrimitive) {
$Indent += 2
}
}


if ( $Object -is [Collections.IDictionary] ) {
$Object.GetEnumerator() |
& $mySelf -Parent $Object -GrandParent $Parent -Indent $Indent
} elseif ($Object -is [Collections.IList]) {

[Environment]::NewLine + (' ' * $Indent)

$Object |
& $mySelf -Parent $Object -GrandParent $Parent -Indent $Indent

}
elseif ($object -is [enum]) {
$object.ToString()
}
elseif ($Object.PSObject.Properties) {
$Object.psobject.properties |
& $mySelf -Parent $Object -GrandParent $Parent -Indent $Indent
}

if ($Object -is [Collections.IDictionary] -or $Object -is [PSCustomObject] -or $Object -is [Collections.IList]) {
if ($Parent -is [Collections.IList]) { [Environment]::NewLine }
$Indent -= 2;
}
#endregion Nested
}
}
function IndentString([string]$String,[int]$Indent) {
@(foreach ($line in @($String -split '(?>\r\n|\n)')) {
(' ' * $indent) + $line
}) -join [Environment]::NewLine
}
$inputWasNotPiped = $PSBoundParameters.InputObject -as [bool]
$allInputObjects = @()
}

process {
if ($inputWasNotPiped) {
IndentString ('' + $(if ($YamlHeader) { '---' + [Environment]::NewLine }) + (
(& $toYaml -object $inputObject) -join '' -replace
"$([Environment]::NewLine * 2)", [Environment]::NewLine
) + $(if ($YamlHeader) { [Environment]::NewLine + '---'})) -Indent $Indent
} else {
$allInputObjects += $inputObject
}
}

end {
if (-not $allInputObjects) { return }
if ($allInputObjects.Length -eq 1) {
IndentString ('' + $(if ($YamlHeader) { '---' + [Environment]::NewLine}) + (
(& $toYaml -object $inputObject) -join '' -replace
"$([Environment]::NewLine * 2)", [Environment]::NewLine
) + $(if ($YamlHeader) { [Environment]::NewLine + '---'})) -Indent $Indent
} else {
IndentString ('' + $(if ($YamlHeader) { '---' + [Environment]::NewLine}) + (
(& $toYaml -object $allInputObjects) -join '' -replace
"$([Environment]::NewLine * 2)", [Environment]::NewLine
) + $(if ($YamlHeader) { [Environment]::NewLine + '---'})) -Indent $Indent
}
}



0 comments on commit 2e18c7d

Please sign in to comment.