Private/Convert-JiraMarkdownToADF.ps1
|
function Convert-JiraMarkdownToADF { <# .SYNOPSIS Wandelt einen vollständigen Markdown-Text in ein ADF-Content-Array um. Unterstützt Überschriften (#), Tabellen (| ... |), Listen (- / 1.) und Absätze. #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [AllowEmptyString()] [string] $Markdown ) process { $Lines = $Markdown -split "`r?`n" $Blocks = [System.Collections.Generic.List[string[]]]::new() $Current = [System.Collections.Generic.List[string]]::new() foreach ($Line in $Lines) { if ($Line.Trim() -eq '') { if ($Current.Count -gt 0) { $Blocks.Add($Current.ToArray()); $Current.Clear() } } else { $Current.Add($Line) } } if ($Current.Count -gt 0) { $Blocks.Add($Current.ToArray()) } $Content = [System.Collections.Generic.List[hashtable]]::new() foreach ($Block in $Blocks) { $First = $Block[0].Trim() # --- Heading --- if ($First -match '^(#{1,6})\s+(.+)$') { $Content.Add(@{ type = 'heading' attrs = @{ level = $Matches[1].Length } content = @(@{ type = 'text'; text = $Matches[2] }) }) } # --- Table --- elseif ($Block | Where-Object { $_.Trim() -match '^\|' }) { $tableRows = [System.Collections.Generic.List[hashtable]]::new() $isFirst = $true foreach ($Row in ($Block | Where-Object { $_.Trim() -match '^\|' -and $_.Trim() -notmatch '^\|[-: |]+\|$' })) { $Cells = $Row.Trim().TrimStart('|').TrimEnd('|') -split '\|' $adfCells = foreach ($Cell in $Cells) { $cellContent = Convert-JiraMarkdownInlineToADF -Text $Cell.Trim() @{ type = if ($isFirst) { 'tableHeader' } else { 'tableCell' } attrs = @{} content = @(@{ type = 'paragraph'; content = $cellContent }) } } $tableRows.Add(@{ type = 'tableRow'; content = @($adfCells) }) $isFirst = $false } $Content.Add(@{ type = 'table' attrs = @{ isNumberColumnEnabled = $false; layout = 'default' } content = $tableRows.ToArray() }) } # --- Bullet list --- elseif ($First -match '^[-*+]\s+') { $Items = foreach ($BLine in $Block) { if ($BLine.Trim() -match '^[-*+]\s+(.+)$') { @{ type = 'listItem' content = @(@{ type = 'paragraph'; content = Convert-JiraMarkdownInlineToADF -Text $Matches[1] }) } } } $Content.Add(@{ type = 'bulletList'; content = @($Items) }) } # --- Ordered list --- elseif ($First -match '^\d+\.\s+') { $Items = foreach ($BLine in $Block) { if ($BLine.Trim() -match '^\d+\.\s+(.+)$') { @{ type = 'listItem' content = @(@{ type = 'paragraph'; content = Convert-JiraMarkdownInlineToADF -Text $Matches[1] }) } } } $Content.Add(@{ type = 'orderedList'; content = @($Items) }) } # --- Paragraph --- else { $ParaNodes = [System.Collections.Generic.List[hashtable]]::new() $LineCount = $Block.Count for ($i = 0; $i -lt $LineCount; $i++) { $InlineNodes = Convert-JiraMarkdownInlineToADF -Text $Block[$i].Trim() foreach ($n in $InlineNodes) { $ParaNodes.Add($n) } if ($i -lt $LineCount - 1) { $ParaNodes.Add(@{ type = 'hardBreak' }) } } $Content.Add(@{ type = 'paragraph'; content = $ParaNodes.ToArray() }) } } return , $Content.ToArray() } } |