public/Find-MarkdownImages.ps1
|
<#
.SYNOPSIS Finds all image references in a markdown file. .DESCRIPTION Parses a markdown file and extracts all image references including: - Standard markdown format:  - Obsidian format: ![[image_path|alt text]] Returns information about each image including the original markdown syntax, image path, alt text, and title. .PARAMETER File The path to the markdown file to analyze. .EXAMPLE Find-MarkdownImages -File "post.md" #> function Find-MarkdownImages { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [ValidateScript({ Test-Path -Path $_ -PathType Leaf })] [string]$File ) $content = Get-Content -Path $File -Raw $images = @() $fileDirectory = Split-Path -Path $File -Parent # If the file is in the current directory, use the current directory if ([string]::IsNullOrEmpty($fileDirectory)) { $fileDirectory = "." } # Regex pattern for standard markdown images:  $standardPattern = '!\[([^\]]*)\]\(([^)]+?)(?:\s+"([^"]*)")?\)' # Regex pattern for Obsidian images: ![[image_path|alt text]] $obsidianPattern = '!\[\[([^|\]]+?)(?:\|([^\]]*))?\]\]' # Collect all matches with their positions $allMatches = @() # Find all standard markdown image matches $standardMatches = [regex]::Matches($content, $standardPattern) foreach ($match in $standardMatches) { $allMatches += @{ Match = $match Position = $match.Index Format = "Standard" } } # Find all Obsidian image matches $obsidianMatches = [regex]::Matches($content, $obsidianPattern) foreach ($match in $obsidianMatches) { $allMatches += @{ Match = $match Position = $match.Index Format = "Obsidian" } } # Sort matches by position in document $allMatches = $allMatches | Sort-Object Position # Process each match in document order foreach ($matchInfo in $allMatches) { $match = $matchInfo.Match $format = $matchInfo.Format if ($format -eq "Standard") { $altText = $match.Groups[1].Value $imagePath = $match.Groups[2].Value.Trim() $title = if ($match.Groups[3].Success) { $match.Groups[3].Value } else { "" } } else { # Obsidian format $imagePath = $match.Groups[1].Value.Trim() $altText = if ($match.Groups[2].Success) { $match.Groups[2].Value } else { "" } $title = "" # Obsidian format doesn't support titles } # Skip URLs (images already hosted online) if ($imagePath -match '^https?://') { continue } # Resolve relative paths if (-not [System.IO.Path]::IsPathRooted($imagePath)) { $resolvedPath = Join-Path -Path $fileDirectory -ChildPath $imagePath } else { $resolvedPath = $imagePath } # Check if the file exists if (Test-Path -Path $resolvedPath -PathType Leaf) { $images += New-MarkdownImage ` -OriginalMarkdown $match.Value ` -AltText $altText ` -LocalPath $resolvedPath ` -RelativePath $imagePath ` -Title $title ` -FileName $(Split-Path -Path $resolvedPath -Leaf) } } return $images } Function New-MarkdownImage { param( [string]$OriginalMarkdown, [string]$AltText, [string]$LocalPath, [string]$RelativePath, [string]$Title = "", [string]$FileName ) return [PSCustomObject]@{ OriginalMarkdown = $OriginalMarkdown AltText = $AltText LocalPath = $LocalPath RelativePath = $RelativePath Title = $Title FileName = $FileName NewUrl = $null # This will be set after uploading to Google Drive } } |