Markdown.psm1
[CmdletBinding()] param() $baseName = [System.IO.Path]::GetFileNameWithoutExtension($PSCommandPath) $script:PSModuleInfo = Test-ModuleManifest -Path "$PSScriptRoot\$baseName.psd1" $script:PSModuleInfo | Format-List | Out-String -Stream | ForEach-Object { Write-Debug $_ } $scriptName = $script:PSModuleInfo.Name Write-Debug "[$scriptName] - Importing module" #region [functions] - [public] Write-Debug "[$scriptName] - [functions] - [public] - Processing folder" #region [functions] - [public] - [Set-MarkdownCodeBlock] Write-Debug "[$scriptName] - [functions] - [public] - [Set-MarkdownCodeBlock] - Importing" function Set-MarkdownCodeBlock { <# .SYNOPSIS Generates a fenced code block for Markdown using the specified language. .DESCRIPTION This function takes a programming language and a script block, captures the script block’s contents, normalizes the indentation, removes the outer braces (if present) and then formats it as a fenced code block suitable for Markdown. .EXAMPLE Set-MarkdownCodeBlock -Language 'powershell' -Content { Get-Process } Output: ```powershell Get-Process ``` Generates a fenced code block with the specified PowerShell script. .EXAMPLE CodeBlock 'powershell' { Get-Process } Output: ```powershell Get-Process ``` Generates a fenced code block with the specified PowerShell script. .OUTPUTS string .NOTES Returns the formatted fenced code block as a string. .LINK https://psmodule.io/Markdown/Functions/Set-MarkdownCodeBlock/ #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Sets text in memory' )] [Alias('Block')] [Alias('CodeBlock')] [Alias('Fence')] [Alias('CodeFence')] [OutputType([string])] [CmdletBinding()] param( [Parameter(Mandatory, Position = 0)] [string]$Language, [Parameter(Mandatory, Position = 1)] [scriptblock]$Content ) # Capture the raw text of the script block $raw = $Content.Ast.Extent.Text $lines = $raw -split "`r?`n" # Remove leading and trailing blank lines while ($lines.Count -gt 0 -and $lines[0].Trim() -eq '') { $lines = $lines[1..($lines.Count - 1)] } while ($lines.Count -gt 0 -and $lines[-1].Trim() -eq '') { $lines = $lines[0..($lines.Count - 2)] } # If the first and last lines are only '{' and '}', remove them. if ($lines.Count -ge 2 -and $lines[0].Trim() -eq '{' -and $lines[-1].Trim() -eq '}') { $lines = $lines[1..($lines.Count - 2)] } # Determine common leading whitespace (indentation) on non-empty lines $nonEmpty = $lines | Where-Object { $_.Trim().Length -gt 0 } if ($nonEmpty) { $commonIndent = ($nonEmpty | ForEach-Object { $_.Length - $_.TrimStart().Length } | Measure-Object -Minimum).Minimum # Remove the common indent from each line $lines = $lines | ForEach-Object { if ($_.Length -ge $commonIndent) { $_.Substring($commonIndent) } else { $_ } } } $return = @() $return += '```{0}' -f $Language $return += $lines $return += '```' $return += '' $return -join [Environment]::NewLine } Write-Debug "[$scriptName] - [functions] - [public] - [Set-MarkdownCodeBlock] - Done" #endregion [functions] - [public] - [Set-MarkdownCodeBlock] #region [functions] - [public] - [Set-MarkdownDetails] Write-Debug "[$scriptName] - [functions] - [public] - [Set-MarkdownDetails] - Importing" function Set-MarkdownDetails { <# .SYNOPSIS Generates a collapsible Markdown details block. .DESCRIPTION This function creates a collapsible Markdown `<details>` block with a summary title and formatted content. It captures the output of the provided script block and wraps it in a Markdown details structure. .EXAMPLE Set-MarkdownDetails -Title 'More Information' -Content { 'This is detailed content.' } Output: ```powershell <details><summary>More Information</summary> <p> This is detailed content. </p> </details> ``` Generates a Markdown details block with the title "More Information" and the specified content. .EXAMPLE Details 'More Information' { 'This is detailed content.' } Output: ```powershell <details><summary>More Information</summary> <p> This is detailed content. </p> </details> ``` Generates a Markdown details block with the title "More Information" and the specified content. .OUTPUTS string .NOTES Returns the formatted Markdown details block as a string. .LINK https://psmodule.io/Markdown/Functions/Set-MarkdownDetails/ #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Sets text in memory' )] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseSingularNouns', '', Justification = 'Markdown details are a collection of information. Language specific' )] [Alias('Details')] [OutputType([string])] [CmdletBinding()] param ( # The title of the Markdown details block. [Parameter(Mandatory, Position = 0)] [string] $Title, # The content inside the Markdown details block. [Parameter(Mandatory, Position = 1)] [ScriptBlock] $Content ) $captured = . $Content | Out-String $captured = $captured.TrimEnd() $return = @() $return += "<details><summary>$Title</summary>" $return += '<p>' $return += '' $return += $captured $return += '' $return += '</p>' $return += '</details>' $return += '' $return -join [System.Environment]::NewLine } Write-Debug "[$scriptName] - [functions] - [public] - [Set-MarkdownDetails] - Done" #endregion [functions] - [public] - [Set-MarkdownDetails] #region [functions] - [public] - [Set-MarkdownSection] Write-Debug "[$scriptName] - [functions] - [public] - [Set-MarkdownSection] - Importing" function Set-MarkdownSection { <# .SYNOPSIS Generates a formatted Markdown section with a specified header level, title, and content. .DESCRIPTION This function creates a Markdown section with a specified header level, title, and formatted content. The header level determines the number of `#` symbols used for the Markdown heading. The content is provided as a script block and executed within the function. The function returns the formatted Markdown as a string. .EXAMPLE Set-MarkdownSection -Level 2 -Title "Example Section" -Content { "This is an example of Markdown content." } Output: ```powershell ## Example Section This is an example of Markdown content. ``` Generates a Markdown section with an H2 heading and the given content. .EXAMPLE Section 2 "Example Section" { "This is an example of Markdown content." } Output: ```powershell ## Example Section This is an example of Markdown content. ``` Generates a Markdown section with an H2 heading and the given content. .OUTPUTS string .NOTES The formatted Markdown section as a string. .LINK https://psmodule.io/Markdown/Functions/Set-MarkdownSection #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Sets text in memory' )] [Alias('Header')] [Alias('Heading')] [Alias('Section')] [OutputType([string])] [CmdletBinding()] param( # Specifies the Markdown header level (1-6). [Parameter(Mandatory, Position = 0)] [ValidateRange(1, 6)] [int] $Level, # The title of the Markdown section. [Parameter(Mandatory, Position = 1)] [string] $Title, # The content to be included in the Markdown section. [Parameter(Mandatory, Position = 2)] [scriptblock] $Content ) $captured = . $Content | Out-String $captured = $captured.TrimEnd() # Create the Markdown header by repeating the '#' character $hashes = '#' * $Level $return = @() $return += "$hashes $Title" $return += '' $return += $captured $return += '' $return -join [System.Environment]::NewLine } Write-Debug "[$scriptName] - [functions] - [public] - [Set-MarkdownSection] - Done" #endregion [functions] - [public] - [Set-MarkdownSection] #region [functions] - [public] - [Set-MarkdownTable] Write-Debug "[$scriptName] - [functions] - [public] - [Set-MarkdownTable] - Importing" function Set-MarkdownTable { <# .SYNOPSIS Converts objects from a script block into a Markdown table. .DESCRIPTION The Set-MarkdownTable function executes a provided script block and formats the resulting objects as a Markdown table. Each property of the objects becomes a column, and each object becomes a row in the table. If no objects are returned, a warning is displayed, and no output is produced. .EXAMPLE Table { Get-Process | Select-Object -First 3 Name, ID } Output: ```powershell | Name | ID | | ---- | -- | | notepad | 1234 | | explorer | 5678 | | chrome | 91011 | ``` Generates a Markdown table from the first three processes, displaying their Name and ID properties. .OUTPUTS string .NOTES The Markdown-formatted table as a string output. This function returns a Markdown-formatted table string, which can be used in documentation or exported. .LINK https://psmodule.io/Markdown/Functions/Set-MarkdownTable/ #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Sets text in memory' )] [Alias('Table')] [OutputType([string])] [CmdletBinding()] param ( # Script block containing commands whose output will be converted into a Markdown table. [Parameter(Mandatory, Position = 0)] [ScriptBlock] $InputScriptBlock ) # Execute the script block and capture the output objects. $results = & $InputScriptBlock if (-not $results) { Write-Warning 'No objects to display.' return } # Use the first object to get the property names. $first = $results | Select-Object -First 1 $props = $first.psobject.Properties.Name # Build the Markdown header row. $header = '| ' + ($props -join ' | ') + ' |' # Build the separator row. $separator = '| ' + ( ($props | ForEach-Object { '-' }) -join ' | ' ) + ' |' # Output header rows. $return = @() $return += $header $return += $separator # For each object, output a table row. foreach ($item in $results) { $rowValues = foreach ($prop in $props) { $val = $item.$prop if ($null -eq $val) { '' } else { $val.ToString() } } $row = '| ' + ($rowValues -join ' | ') + ' |' $return += $row } $return += '' $return -join [Environment]::NewLine } Write-Debug "[$scriptName] - [functions] - [public] - [Set-MarkdownTable] - Done" #endregion [functions] - [public] - [Set-MarkdownTable] Write-Debug "[$scriptName] - [functions] - [public] - Done" #endregion [functions] - [public] #region Member exporter $exports = @{ Alias = '*' Cmdlet = '' Function = @( 'Set-MarkdownCodeBlock' 'Set-MarkdownDetails' 'Set-MarkdownSection' 'Set-MarkdownTable' ) Variable = '' } Export-ModuleMember @exports #endregion Member exporter |