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()
    }
}