functions/powershell/module/Export-FunctionDocs.ps1

function Export-FunctionDocs {
<#
.SYNOPSIS
Exports Markdown documentation files for PowerShell functions from a source directory.
 
.DESCRIPTION
This function recursively scans a directory for `.ps1` files, filters them using an optional `exclude-files.json`, dot-sources each script, and generates one `.md` file per function using PlatyPS-style help content. The content is extracted using the helper function `Get-HelpContent`.
 
Each `.md` file contains sections such as SYNOPSIS, DESCRIPTION, PARAMETERS, EXAMPLES, NOTES, and LINKS based on the parsed help content of each function.
 
.PARAMETER SourcePath
The root path to recursively search for `.ps1` function files.
 
.PARAMETER OutputPath
The target folder where `.md` documentation files will be saved.
If the path does not exist, it will be created automatically.
 
.EXAMPLE
Export-FunctionDocs -SourcePath "C:\Repo\MyModule" -OutputPath "C:\Docs\MyModule"
 
Exports all functions from `.ps1` files under `C:\Repo\MyModule`, excluding those listed in `exclude-files.json`, and writes `.md` documentation files to `C:\Docs\MyModule`.
 
.NOTES
• All `.ps1` files are dot-sourced during execution – invalid or broken files will trigger warnings.
• Each function is written to its own `.md` file using Markdown syntax.
 
.LINK
Get-HelpContent
Get-FilteredFiles
#>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [string]$SourcePath,

        [Parameter(Mandatory)]
        [string]$OutputPath
    )

    $SourcePath = (Resolve-Path -Path $SourcePath).Path

    Write-Verbose "Suche nach .ps1-Dateien in $SourcePath"

    $allPs1Files = Get-ChildItem -Path $SourcePath -Recurse -Filter *.ps1
    $filteredFiles = Get-FilteredFiles -Files $allPs1Files -ExcludeListFile (Join-Path -Path $SourcePath -ChildPath 'exclude-files.json') -RootPath $SourcePath

    if (-not (Test-Path $OutputPath)) {
        New-Item -Path $OutputPath -ItemType Directory -Force | Out-Null
    }

    foreach ($file in $filteredFiles) {
        Write-Verbose "Analysiere Datei: $($file.FullName)"

        try {
            . $file.FullName
        } catch {
            Write-Warning "Fehler beim Dot-Sourcing der Datei '$($file.FullName)': $_"
            continue
        }

        $functions = Get-Command -CommandType Function | Where-Object { $_.ScriptBlock.File -eq $file.FullName }

        foreach ($func in $functions) {
            $funcName = $func.Name
            Write-Verbose "Verarbeite Funktion: $funcName"

            try {
                $helpContent = Get-HelpContent -FilePath $file.FullName -FunctionName $funcName

                if (-not $helpContent.SYNOPSIS) {
                    Write-Warning "Funktion '$funcName' hat keine .SYNOPSIS-Dokumentation."
                    continue
                }

                $mdPath = Join-Path $OutputPath "$funcName.md"
                Write-Verbose "Erstelle Dokumentation: $mdPath"

                $lines = @()
                $lines += "# $funcName"
                $lines += ""
                $lines += "## SYNOPSIS"
                $lines += $helpContent.SYNOPSIS
                $lines += ""

                if ($helpContent.DESCRIPTION) {
                    $lines += "## DESCRIPTION"
                    $lines += $helpContent.DESCRIPTION
                    $lines += ""
                }

                if ($helpContent.PARAMETER.Keys.Count -gt 0) {
                    $lines += "## PARAMETERS"
                    foreach ($param in $helpContent.PARAMETER.GetEnumerator()) {
                        $lines += "### -$($param.Key)"
                        $lines += $param.Value -split "`r?`n" | ForEach-Object { " $_" }
                        $lines += ""
                    }
                }

                if ($helpContent.EXAMPLE) {
                    $lines += "## EXAMPLES"
                    $lines += ($helpContent.EXAMPLE -split "(?m)^\s*$") | ForEach-Object {
                        '```powershell'
                        $_.Trim()
                        '```'
                        ''
                    }
                }

                if ($helpContent.NOTES) {
                    $lines += "## NOTES"
                    $lines += $helpContent.NOTES
                    $lines += ""
                }

                if ($helpContent.LINK) {
                    $lines += "## LINKS"
                    $lines += $helpContent.LINK
                    $lines += ""
                }

                $lines += "---"
                $lines += "*Datei: $($file.Name)*"

                Set-Content -Path $mdPath -Value $lines -Encoding UTF8
            } catch {
                Write-Warning "Fehler beim Verarbeiten von '$funcName': $_"
            }
        }
    }
}