@@ -277,13 +277,61 @@ function ConvertFrom-YamlSuiteEventText {
277277 [string ] $Text
278278 )
279279
280+ function ConvertTo-YamlSuiteEventEscapedText {
281+ param ([AllowNull ()][string ] $Value )
282+ if ($null -eq $Value ) {
283+ return ' '
284+ }
285+ $builder = [System.Text.StringBuilder ]::new()
286+ foreach ($character in $Value.ToCharArray ()) {
287+ switch ($character ) {
288+ ' \' { [void ] $builder.Append (' \\' ) }
289+ " `n " { [void ] $builder.Append (' \n' ) }
290+ " `r " { [void ] $builder.Append (' \r' ) }
291+ " `t " { [void ] $builder.Append (' \t' ) }
292+ default { [void ] $builder.Append ($character ) }
293+ }
294+ }
295+ $builder.ToString ()
296+ }
297+
298+ function ConvertFrom-YamlSuiteEventEscapes {
299+ param ([AllowNull ()][string ] $Value )
300+ if ($null -eq $Value ) {
301+ return ' '
302+ }
303+ $builder = [System.Text.StringBuilder ]::new()
304+ $index = 0
305+ while ($index -lt $Value.Length ) {
306+ $current = $Value [$index ]
307+ if ($current -eq ' \' -and $index + 1 -lt $Value.Length ) {
308+ $index ++
309+ switch ($Value [$index ]) {
310+ ' n' { [void ] $builder.Append (" `n " ) }
311+ ' r' { [void ] $builder.Append (" `r " ) }
312+ ' t' { [void ] $builder.Append (" `t " ) }
313+ ' b' { [void ] $builder.Append (" `b " ) }
314+ ' \' { [void ] $builder.Append (' \' ) }
315+ default {
316+ [void ] $builder.Append ($Value [$index ])
317+ }
318+ }
319+ $index ++
320+ continue
321+ }
322+ [void ] $builder.Append ($current )
323+ $index ++
324+ }
325+ $builder.ToString ()
326+ }
327+
280328 $anchorMap = [System.Collections.Generic.Dictionary [string , string ]]::new([System.StringComparer ]::Ordinal)
281329 $anchorCounter = 0
282330 $canonical = [System.Collections.Generic.List [string ]]::new()
283331 $lines = $Text -split ' \r?\n'
284332
285333 foreach ($rawLine in $lines ) {
286- $line = $rawLine.Trim ()
334+ $line = $rawLine
287335 if ([string ]::IsNullOrWhiteSpace($line )) {
288336 continue
289337 }
@@ -305,8 +353,14 @@ function ConvertFrom-YamlSuiteEventText {
305353 $anchor = ' '
306354 $tag = ' '
307355 $value = ' '
356+ $style = ' '
308357
309358 while ($rest.Length -gt 0 ) {
359+ if ($rest.StartsWith (' []' , [System.StringComparison ]::Ordinal) -or
360+ $rest.StartsWith (' {}' , [System.StringComparison ]::Ordinal)) {
361+ $rest = $rest.Substring (2 ).TrimStart()
362+ continue
363+ }
310364 if ($rest [0 ] -eq ' &' ) {
311365 $space = $rest.IndexOf (' ' )
312366 if ($space -lt 0 ) {
@@ -330,11 +384,20 @@ function ConvertFrom-YamlSuiteEventText {
330384 }
331385
332386 if ($prefix -eq ' =VAL' ) {
333- if ($rest.Length -gt 0 -and ($rest [0 ] -eq ' :' -or $rest [0 ] -eq ' "' -or $rest [0 ] -eq " '" )) {
387+ if ($rest.Length -gt 0 -and
388+ ($rest [0 ] -eq ' :' -or $rest [0 ] -eq ' "' -or $rest [0 ] -eq " '" -or
389+ $rest [0 ] -eq ' |' -or $rest [0 ] -eq ' >' )) {
390+ $style = [string ] $rest [0 ]
334391 $value = $rest.Substring (1 )
335392 } else {
336393 $value = $rest
337394 }
395+ if ($style -in @ (' |' , ' >' ) -and [string ]::IsNullOrEmpty($value )) {
396+ $value = ' '
397+ }
398+ $value = ConvertTo-YamlSuiteEventEscapedText - Value (
399+ ConvertFrom-YamlSuiteEventEscapes - Value $value
400+ )
338401 }
339402
340403 $anchorToken = ' '
@@ -347,7 +410,7 @@ function ConvertFrom-YamlSuiteEventText {
347410 }
348411 $parts = [System.Collections.Generic.List [string ]]::new()
349412 $parts.Add ($prefix )
350- if ($tag ) { $parts.Add (" tag=$tag " ) }
413+ if ($tag -and $tag -ne ' ! ' ) { $parts.Add (" tag=$tag " ) }
351414 if ($anchorToken ) { $parts.Add (" anchor=$anchorToken " ) }
352415 if ($prefix -eq ' =VAL' ) { $parts.Add (" value=$value " ) }
353416 $canonical.Add (($parts -join ' |' ))
@@ -382,21 +445,31 @@ function ConvertTo-YamlSuiteActualEvent {
382445 [object []] $Documents
383446 )
384447
385- $anchorMap = [System.Collections.Generic.Dictionary [int , string ]]::new()
448+ function ConvertTo-YamlSuiteEventEscapedText {
449+ param ([AllowNull ()][string ] $Value )
450+ if ($null -eq $Value ) {
451+ return ' '
452+ }
453+ $builder = [System.Text.StringBuilder ]::new()
454+ foreach ($character in $Value.ToCharArray ()) {
455+ switch ($character ) {
456+ ' \' { [void ] $builder.Append (' \\' ) }
457+ " `n " { [void ] $builder.Append (' \n' ) }
458+ " `r " { [void ] $builder.Append (' \r' ) }
459+ " `t " { [void ] $builder.Append (' \t' ) }
460+ default { [void ] $builder.Append ($character ) }
461+ }
462+ }
463+ $builder.ToString ()
464+ }
465+
466+ $anchorMap = [System.Collections.Generic.Dictionary [string , string ]]::new(
467+ [System.StringComparer ]::Ordinal
468+ )
386469 $anchorCounter = 0
387470 $events = [System.Collections.Generic.List [string ]]::new()
388471 $events.Add (' +STR' )
389472
390- $getAnchor = {
391- param ([pscustomobject ] $Node )
392- if ($null -eq $Node ) { return ' ' }
393- if (-not $anchorMap.ContainsKey ($Node.Id )) {
394- $anchorCounter ++
395- $anchorMap [$Node.Id ] = ' a{0:d3}' -f $anchorCounter
396- }
397- return $anchorMap [$Node.Id ]
398- }
399-
400473 foreach ($document in $Documents ) {
401474 $events.Add (' +DOC' )
402475 $stack = [System.Collections.Generic.Stack [object ]]::new()
@@ -411,25 +484,43 @@ function ConvertTo-YamlSuiteActualEvent {
411484
412485 $node = $frame.Node
413486 if ($node.Kind -eq ' Alias' ) {
414- $targetAnchor = & $getAnchor $node.Target
487+ $targetAnchorKey = if ([string ]::IsNullOrEmpty($node.Target.Anchor )) {
488+ ' id:{0}' -f $node.Target.Id
489+ } else {
490+ $node.Target.Anchor
491+ }
492+ $targetAnchor = Get-YamlSuiteAnchorToken - Key $targetAnchorKey `
493+ - AnchorMap $anchorMap - AnchorCounter ([ref ] $anchorCounter )
415494 $events.Add (" =ALI|target=$targetAnchor " )
416495 continue
417496 }
418497 if ($node.Kind -eq ' Scalar' ) {
419498 $parts = [System.Collections.Generic.List [string ]]::new()
420499 $parts.Add (' =VAL' )
421- if ($node.Tag ) { $parts.Add (" tag=$ ( $node.Tag ) " ) }
422- if ($node.Anchor ) { $parts.Add (" anchor=$ ( & $getAnchor $node ) " ) }
423- $parts.Add ((" value={0}" -f [string ] $node.Value ))
500+ if ($node.Tag -and $node.Tag -ne ' !' ) { $parts.Add (" tag=$ ( $node.Tag ) " ) }
501+ if ($node.Anchor ) {
502+ $parts.Add (" anchor=$ (
503+ Get-YamlSuiteAnchorToken - Key $node.Anchor - AnchorMap $anchorMap `
504+ - AnchorCounter ([ref ] $anchorCounter )
505+ ) " )
506+ }
507+ $parts.Add ((" value={0}" -f (
508+ ConvertTo-YamlSuiteEventEscapedText - Value ([string ] $node.Value )
509+ )))
424510 $events.Add (($parts -join ' |' ))
425511 continue
426512 }
427513
428514 $startParts = [System.Collections.Generic.List [string ]]::new()
429515 $startToken = if ($node.Kind -eq ' Sequence' ) { ' +SEQ' } else { ' +MAP' }
430516 $startParts.Add ($startToken )
431- if ($node.Tag ) { $startParts.Add (" tag=$ ( $node.Tag ) " ) }
432- if ($node.Anchor ) { $startParts.Add (" anchor=$ ( & $getAnchor $node ) " ) }
517+ if ($node.Tag -and $node.Tag -ne ' !' ) { $startParts.Add (" tag=$ ( $node.Tag ) " ) }
518+ if ($node.Anchor ) {
519+ $startParts.Add (" anchor=$ (
520+ Get-YamlSuiteAnchorToken - Key $node.Anchor - AnchorMap $anchorMap `
521+ - AnchorCounter ([ref ] $anchorCounter )
522+ ) " )
523+ }
433524 $events.Add (($startParts -join ' |' ))
434525
435526 if ($node.Kind -eq ' Sequence' ) {
@@ -471,6 +562,27 @@ function Compare-YamlSuiteCanonicalList {
471562 return $true
472563}
473564
565+ function Get-YamlSuiteAnchorToken {
566+ [CmdletBinding ()]
567+ [OutputType ([string ])]
568+ param (
569+ [Parameter (Mandatory )]
570+ [string ] $Key ,
571+
572+ [Parameter (Mandatory )]
573+ [System.Collections.Generic.Dictionary [string , string ]] $AnchorMap ,
574+
575+ [Parameter (Mandatory )]
576+ [ref ] $AnchorCounter
577+ )
578+
579+ if (-not $AnchorMap.ContainsKey ($Key )) {
580+ $AnchorCounter.Value ++
581+ $AnchorMap [$Key ] = ' a{0:d3}' -f $AnchorCounter.Value
582+ }
583+ $AnchorMap [$Key ]
584+ }
585+
474586$readYamlSuiteRepresentation = {
475587 param ([string ] $YamlText )
476588 Read-YamlStreamCore - Yaml $YamlText - Depth 128 - MaxNodes 100000 `
@@ -492,6 +604,19 @@ $projectYamlSuiteStream = {
492604 }
493605 New-YamlValueBox - Value ([object []] $values.ToArray ())
494606}
607+ $projectYamlSuiteText = {
608+ param ([string ] $YamlText )
609+
610+ $stream = Read-YamlStream - Yaml $YamlText - Depth 128 - MaxNodes 100000 `
611+ - MaxAliases 1000 - MaxScalarLength 1048576 - MaxTagLength 1024 `
612+ - MaxTotalTagLength 65536 - MaxNumericLength 4096
613+ $values = [System.Collections.Generic.List [object ]]::new()
614+ foreach ($node in $stream.Value ) {
615+ $cache = [System.Collections.Generic.Dictionary [int , object ]]::new()
616+ $values.Add ((ConvertFrom-YamlNode - Node $node - Cache $cache - AsHashtable).Value)
617+ }
618+ New-YamlValueBox - Value ([object []] $values.ToArray ())
619+ }
495620
496621$suiteRoot = (Resolve-Path - LiteralPath $Path ).Path
497622$inputFiles = @ (
@@ -711,7 +836,7 @@ foreach ($inputFile in $inputFiles) {
711836 $emitted = Invoke-InYamlModule - ScriptBlock {
712837 param ($InputValue )
713838 ConvertTo-Yaml - InputObject $InputValue - ExplicitDocumentStart
714- } - Arguments @ ( $value )
839+ } - Arguments ( , $value )
715840 $emittedDocuments.Add ([string ] $emitted )
716841 }
717842 $emittedText = ($emittedDocuments.ToArray () -join " `n " )
@@ -725,14 +850,8 @@ foreach ($inputFile in $inputFiles) {
725850 $emitResult = ' Fail'
726851 $emitReason = ' EmittedYamlInvalid'
727852 } else {
728- $roundTripValues = @ (
729- Invoke-InYamlModule - ScriptBlock {
730- param ($YamlText )
731- ConvertFrom-Yaml - Yaml $YamlText - AsHashtable - NoEnumerate - Depth 128 `
732- - MaxNodes 100000 - MaxAliases 1000 - MaxScalarLength 1048576 `
733- - MaxTagLength 1024 - MaxTotalTagLength 65536 - MaxNumericLength 4096
734- } - Arguments @ ($emittedText )
735- )
853+ $roundTripValues = (Invoke-InYamlModule - ScriptBlock $projectYamlSuiteText `
854+ - Arguments @ ($emittedText )).Value
736855 $roundCanonical = ConvertTo-YamlSuiteCanonicalValue - Value ([object []] $roundTripValues )
737856 $roundReference = ConvertTo-YamlSuiteReferenceSignature - Value ([object []] $roundTripValues )
738857 $emitCanonical = $roundCanonical
@@ -789,5 +908,7 @@ foreach ($inputFile in $inputFiles) {
789908 OutYamlActual = $outYamlCanonical
790909 EmitActual = $emitCanonical
791910 EmitReferences = $emitReference
911+ ProjectedActual = $projectedCanonical
912+ ProjectedRefs = $projectedReference
792913 }
793914}
0 commit comments