MegaBites-AI/Windows-powershell
0372
1# Copyright (c) Microsoft Corporation.2# Licensed under the MIT License.3 4#requires -version 75# Markdig is always available in PowerShell 76<#7.SYNOPSIS8 Parse CHANGELOG files using Markdig to extract links.9 10.DESCRIPTION11 This script uses Markdig.Markdown.Parse to parse all markdown files in the CHANGELOG directory12 and extract different types of links (inline links, reference links, etc.).13 14.PARAMETER ChangelogPath15 Path to the CHANGELOG directory. Defaults to ./CHANGELOG16 17.PARAMETER LinkType18 Filter by link type: All, Inline, Reference, AutoLink. Defaults to All.19 20.EXAMPLE21 .\Parse-MarkdownLink.ps122 23.EXAMPLE24 .\Parse-MarkdownLink.ps1 -LinkType Reference25#>26 27param(28 [string]$ChangelogPath = "./CHANGELOG",29 [ValidateSet("All", "Inline", "Reference", "AutoLink")]30 [string]$LinkType = "All"31)32 33Write-Verbose "Using built-in Markdig functionality to parse markdown files"34 35function Get-LinksFromMarkdownAst {36 param(37 [Parameter(Mandatory)]38 [object]$Node,39 [Parameter(Mandatory)]40 [string]$FileName,41 [System.Collections.ArrayList]$Links42 )43 44 if ($null -eq $Links) {45 return46 }47 48 # Check if current node is a link49 if ($Node -is [Markdig.Syntax.Inlines.LinkInline]) {50 $linkInfo = [PSCustomObject]@{51 Path = $FileName52 Line = $Node.Line + 1 # Convert to 1-based line numbering53 Column = $Node.Column + 1 # Convert to 1-based column numbering54 Url = $Node.Url ?? ""55 Text = $Node.FirstChild?.ToString() ?? ""56 Type = "Inline"57 IsImage = $Node.IsImage58 }59 [void]$Links.Add($linkInfo)60 }61 elseif ($Node -is [Markdig.Syntax.Inlines.AutolinkInline]) {62 $linkInfo = [PSCustomObject]@{63 Path = $FileName64 Line = $Node.Line + 165 Column = $Node.Column + 166 Url = $Node.Url ?? ""67 Text = $Node.Url ?? ""68 Type = "AutoLink"69 IsImage = $false70 }71 [void]$Links.Add($linkInfo)72 }73 elseif ($Node -is [Markdig.Syntax.LinkReferenceDefinitionGroup]) {74 foreach ($refDef in $Node) {75 $linkInfo = [PSCustomObject]@{76 Path = $FileName77 Line = $refDef.Line + 178 Column = $refDef.Column + 179 Url = $refDef.Url ?? ""80 Text = $refDef.Label ?? ""81 Type = "Reference"82 IsImage = $false83 }84 [void]$Links.Add($linkInfo)85 }86 }87 elseif ($Node -is [Markdig.Syntax.LinkReferenceDefinition]) {88 $linkInfo = [PSCustomObject]@{89 Path = $FileName90 Line = $Node.Line + 191 Column = $Node.Column + 192 Url = $Node.Url ?? ""93 Text = $Node.Label ?? ""94 Type = "Reference"95 IsImage = $false96 }97 [void]$Links.Add($linkInfo)98 }99 100 # For MarkdownDocument (root), iterate through all blocks101 if ($Node -is [Markdig.Syntax.MarkdownDocument]) {102 foreach ($block in $Node) {103 Get-LinksFromMarkdownAst -Node $block -FileName $FileName -Links $Links104 }105 }106 # For block containers, iterate through children107 elseif ($Node -is [Markdig.Syntax.ContainerBlock]) {108 foreach ($child in $Node) {109 Get-LinksFromMarkdownAst -Node $child -FileName $FileName -Links $Links110 }111 }112 # For leaf blocks with inlines, process the inline content113 elseif ($Node -is [Markdig.Syntax.LeafBlock] -and $Node.Inline) {114 Get-LinksFromMarkdownAst -Node $Node.Inline -FileName $FileName -Links $Links115 }116 # For inline containers, process all child inlines117 elseif ($Node -is [Markdig.Syntax.Inlines.ContainerInline]) {118 $child = $Node.FirstChild119 while ($child) {120 Get-LinksFromMarkdownAst -Node $child -FileName $FileName -Links $Links121 $child = $child.NextSibling122 }123 }124 # For other inline elements that might have children125 elseif ($Node.PSObject.Properties.Name -contains "FirstChild" -and $Node.FirstChild) {126 $child = $Node.FirstChild127 while ($child) {128 Get-LinksFromMarkdownAst -Node $child -FileName $FileName -Links $Links129 $child = $child.NextSibling130 }131 }132}133 134function Parse-ChangelogFiles {135 param(136 [string]$Path137 )138 139 if (-not (Test-Path $Path)) {140 Write-Error "CHANGELOG directory not found: $Path"141 return142 }143 144 $markdownFiles = Get-ChildItem -Path $Path -Filter "*.md" -File145 146 if ($markdownFiles.Count -eq 0) {147 Write-Warning "No markdown files found in $Path"148 return149 }150 151 $allLinks = [System.Collections.ArrayList]::new()152 153 foreach ($file in $markdownFiles) {154 Write-Verbose "Processing file: $($file.Name)"155 156 try {157 $content = Get-Content -Path $file.FullName -Raw -Encoding UTF8158 159 # Parse the markdown content using Markdig160 $document = [Markdig.Markdown]::Parse($content, [Markdig.MarkdownPipelineBuilder]::new())161 162 # Extract links from the AST163 Get-LinksFromMarkdownAst -Node $document -FileName $file.FullName -Links $allLinks164 165 } catch {166 Write-Warning "Error processing file $($file.Name): $($_.Exception.Message)"167 }168 } 169 170 # Filter by link type if specified171 if ($LinkType -ne "All") {172 $allLinks = $allLinks | Where-Object { $_.Type -eq $LinkType }173 }174 175 return $allLinks176}177 178# Main execution179$links = Parse-ChangelogFiles -Path $ChangelogPath180 181# Output PowerShell objects182$links183 