Skip to content

Instantly share code, notes, and snippets.

@thomstratton
Created January 29, 2026 21:37
Show Gist options
  • Select an option

  • Save thomstratton/82e0d6c21c14e4a2485597a2b80af875 to your computer and use it in GitHub Desktop.

Select an option

Save thomstratton/82e0d6c21c14e4a2485597a2b80af875 to your computer and use it in GitHub Desktop.
Convert multiple source files to markdown (for example to feed the markdown to a web based ai)
#requires -version 7.4
function Get-FilesSkippingDirsAndExts {
param(
[Parameter(Mandatory)][string]$RootPath,
[string[]]$SkipNames = @(),
[string[]]$Extensions = @() # e.g. @(".cs",".js",".txt") or @("cs","js")
)
# Normalize extensions to start with dot and lower-case
$normExts = $Extensions |
ForEach-Object {
if ([string]::IsNullOrWhiteSpace($_)) { continue }
$e = $_.Trim()
if ($e.StartsWith('.')) { $e = $e.Substring(1) }
'.' + $e.ToLowerInvariant()
}
$rootDir = [System.IO.DirectoryInfo]::new($RootPath)
$stack = [System.Collections.Generic.Stack[System.IO.DirectoryInfo]]::new()
$stack.Push($rootDir)
while ($stack.Count -gt 0) {
$dir = $stack.Pop()
# files
try {
foreach ($file in $dir.EnumerateFiles()) {
if ($normExts.Count -eq 0 -or $normExts -contains $file.Extension.ToLowerInvariant()) {
$file
}
}
} catch {
# ignore access errors
}
# subdirectories to descend into
try {
foreach ($sub in $dir.EnumerateDirectories()) {
if ($SkipNames -notcontains $sub.Name) {
$stack.Push($sub)
}
}
} catch {
# ignore access errors
}
}
}
$markdownFile = 'd:\source\output.md'
$slnPath = 'd:\source\OnPrem'
$skipFolders = ('obj', 'Properties', 'bin', '.vs')
$sourceExtensionTagMap = @{
'.slnx' = 'xml'
'.sln' = 'xml'
'.csproj' = 'xml'
'.cs' = 'csharp'
'.json' = 'json'
}
$sourceExtensions = ($sourceExtensionTagMap.Keys) # | ForEach-Object {"$_" }) #-join ', '
$srcFiles = Get-FilesSkippingDirsAndExts -RootPath $slnPath -SkipNames $skipFolders -Extensions $sourceExtensions
#Get-ChildItem -Directory -Path $slnPath -exclude $excludedFolders -recurse | Where-Object { $excludedFolders -notcontains $_.Name }
#| ForEach-Object { Get-ChildItem -Path $_ -Include ($sourceExtensions) -recurse}
$srcFiles | ForEach-Object {
$RelativePath = Resolve-Path -Path $_ -RelativeBasePath $slnPath -Relative
$x = $_.Extension
Write-Output "Processing $x $RelativePath"
$langTag = $sourceExtensionTagMap[$x]
Add-Content -Path $markdownFile -Value "## $RelativePath"
Add-Content -Path $markdownFile -Value "" # a blank line
Add-Content -Path $markdownFile -Value "~~~$langTag"
Get-Content -Path $_.FullName | Add-Content -Path $markdownFile
Add-Content -Path $markdownFile -Value "~~~"
Add-Content -Path $markdownFile -Value ""
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment