Alt3.Docusaurus.Powershell.psm1
#Region 'PREFIX' 0 Set-StrictMode -Version Latest $PSDefaultParameterValues['*:ErrorAction'] = 'Stop' # full stop on first error #EndRegion 'PREFIX' #Region '.\Private\GetCustomEditUrl.ps1' 0 function GetCustomEditUrl() { <# .SYNOPSIS Returns the `custom_edit_url` for the given .md file. .DESCRIPTION Generates a URL pointing to the Powershell source file that was used to generate the markdown file. .NOTES - URLs for non-monolithic modules point to a .ps1 file with same name as the markdown file - URLs for monolithic modules will always point to a .psm1 with same name as passed module #> param( [Parameter(Mandatory = $True)][string]$Module, [Parameter(Mandatory = $True)][System.IO.FileSystemInfo]$MarkdownFile, [Parameter(Mandatory = $True)][string]$EditUrl, [switch]$Monolithic ) # use command for non-monlithics if (-not($Monolithic)) { $command = [System.IO.Path]::GetFileNameWithoutExtension($MarkdownFile) return $EditUrl + '/' + $command + ".ps1" } # use module name for monolithics if (Test-Path $Module) { $Module = [System.IO.Path]::GetFileNameWithoutExtension($Module) } return $EditUrl + '/' + $Module + ".psm1" } #EndRegion '.\Private\GetCustomEditUrl.ps1' 33 #Region '.\Private\GetMdxFilePath.ps1' 0 function GetMdxFilePath() { <# .SYNOPSIS Returns the .mdx file path for a given .md file. #> param( [Parameter(Mandatory = $True)][System.IO.FileSystemInfo]$MarkdownFile ) Join-Path $MarkdownFile.DirectoryName -ChildPath "$([System.IO.Path]::GetFileNameWithoutExtension($MarkdownFile.Name)).mdx" } #EndRegion '.\Private\GetMdxFilePath.ps1' 11 #Region '.\Private\NewSidebarIncludeFile.ps1' 0 function NewSidebarIncludeFile() { <# .SYNOPSIS Generates a `.js` file holding an array with all .mdx 'ids` to be imported in Docusaurus `sidebar.js`. .LINK https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-powershell-1.0/ff730948(v=technet.10) #> param( [Parameter(Mandatory = $True)][string]$OutputFolder, [Parameter(Mandatory = $True)][string]$Sidebar, [Parameter(Mandatory = $True)][Object]$MarkdownFiles ) # generate a list of Powershell commands by stripping .md from the generated PlatyPs files [array]$commands = $MarkdownFiles | Select-Object @{ Name = "PowershellCommand"; Expression={ "'$Sidebar/" + [System.IO.Path]::GetFileNameWithoutExtension($_) + "'" } } | Select-Object -Expand PowershellCommand # generate content using Here-String block $content = @" /** * Import this file in your Docusaurus ``sidebars.js`` file. * * Auto-generated by Alt3.Powershell.Docusaurus. * * Copyright (c) 2019-present, ALT3 B.V. * * Licensed under the MIT license. */ module.exports = [ $($commands -Join ",`n ") ]; "@ # generate file path, convert relative outputfolder to absolute if needed if (-Not([System.IO.Path]::IsPathRooted($OutputFolder))) { $outputFolder = Join-Path "$(Get-Location)" -ChildPath $OutputFolder } $filePath = Join-Path -Path $OutputFolder -ChildPath "docusaurus.sidebar.js" # create the file $fileEncoding = New-Object System.Text.UTF8Encoding $False [System.IO.File]::WriteAllLines($filePath, $content, $fileEncoding) # add created file to output Get-Item $filePath } #EndRegion '.\Private\NewSidebarIncludeFile.ps1' 48 #Region '.\Private\RemoveMarkdownHeaderOne.ps1' 0 function RemoveMarkdownHeaderOne() { <# .SYNOPSIS Removes the H1 element from the markdown content because Docusaurus already generates H1 using the `title` front matter. #> param( [Parameter(Mandatory = $True)][System.IO.FileSystemInfo]$MarkdownFile ) $content = (Get-Content -Path $MarkdownFile.FullName -Raw).TrimEnd() $regex = '\n#{1}\s.+\n\r' $newContent = [regex]::replace($content, $regex, '') # replace file (UTF-8 without BOM) $fileEncoding = New-Object System.Text.UTF8Encoding $False [System.IO.File]::WriteAllLines($markdownFile.FullName, $newContent, $fileEncoding) } #EndRegion '.\Private\RemoveMarkdownHeaderOne.ps1' 19 #Region '.\Private\SetMarkdownFrontMatter.ps1' 0 function SetMarkdownFrontMatter() { <# .SYNOPSIS Replaces PlatyPS generated front matter with Docusaurus compatible front matter. .LINK https://www.apharmony.com/software-sagacity/2014/08/multi-line-regular-expression-replace-in-powershell/ #> param( [Parameter(Mandatory = $True)][System.IO.FileSystemInfo]$MarkdownFile, [Parameter(Mandatory = $True)][string]$CustomEditUrl ) # prepare front matter $powershellCommandName = [System.IO.Path]::GetFileNameWithoutExtension($markdownFile.Name) $newFrontMatter = @( "---" "id: $powershellCommandName" "title: $powershellCommandName" "custom_edit_url: $customEditUrl" "---" ) | Out-String # replace front matter $content = (Get-Content -Path $MarkdownFile.FullName -Raw).TrimEnd() $regex = "(?sm)^(---)(.+)^(---).$\n" $newContent = $content -replace $regex, $newFrontMatter # replace file (UTF-8 without BOM) $fileEncoding = New-Object System.Text.UTF8Encoding $False [System.IO.File]::WriteAllLines($markdownFile.FullName, $newContent, $fileEncoding) } #EndRegion '.\Private\SetMarkdownFrontMatter.ps1' 35 #Region '.\Private\UpdateMarkdownBackticks.ps1' 0 function UpdateMarkdownBackticks() { <# .SYNOPSIS Replaces platyPS-produced "escaped backticks" with normal backticks so markdown gets rendered as expected. #> param( [Parameter(Mandatory = $True)][System.IO.FileSystemInfo]$MarkdownFile ) $content = (Get-Content -Path $MarkdownFile.FullName -Raw).TrimEnd() $regex = '\\`' $newContent = [regex]::replace($content, $regex, '`') # replace file (UTF-8 without BOM) $fileEncoding = New-Object System.Text.UTF8Encoding $False [System.IO.File]::WriteAllLines($markdownFile.FullName, $newContent, $fileEncoding) } #EndRegion '.\Private\UpdateMarkdownBackticks.ps1' 19 #Region '.\Private\UpdateMarkdownCodeBlocks.ps1' 0 function UpdateMarkdownCodeBlocks() { <# .SYNOPSIS Add `powershell` syntax highlighting to generated code blocks. .NOTES 1. unfortunately we need to do this because PlatyPS does not add the language (design choice) 2. @todo change regex so it will match on \n as well (now only works on CRLF files) #> param( [Parameter(Mandatory = $True)][System.IO.FileSystemInfo]$MarkdownFile ) $content = (Get-Content -Path $MarkdownFile.FullName -Raw).TrimEnd() # this regex replaces all code blocks without a language (test on https://regex101.com using /$regex/g) $regex = '(```)\r((?:(?!```)[\s\S])+)(```)\r' $newContent = [regex]::replace($content, $regex, '```powershell$2```') # replace file (UTF-8 without BOM) $fileEncoding = New-Object System.Text.UTF8Encoding $False [System.IO.File]::WriteAllLines($markdownFile.FullName, $newContent, $fileEncoding) } #EndRegion '.\Private\UpdateMarkdownCodeBlocks.ps1' 24 #Region '.\Public\New-DocusaurusHelp.ps1' 0 function New-DocusaurusHelp() { <# .SYNOPSIS Generates Get-Help documentation in Docusaurus compatible `.mdx` format. .DESCRIPTION The `New-DocusaurusHelp` cmdlet generates Get-Help documentation in Docusaurus compatible format by creating an `.mdx` file for each command exported by the module, enriched with command-specific front matter variables. Also creates a `sidebar.js` file for simplified integration into the Docusaurus sidebar menu. .OUTPUTS System.Object .EXAMPLE New-DocusaurusHelp -Module Alt3.Docusaurus.Powershell -EditUrl "https://github.com/alt3/Docusaurus.Powershell/edit/master/source/Public" .PARAMETER Module Specifies the module this cmdlet will generate Docusaurus documentation for. You may specify a module name, a `.psd1` file or a `.psm1` file. .PARAMETER OutputFolder Specifies the folder where the Docusaurus sidebar subfolder will be created. Optional, defaults to `docusaurus/docs`, case sensitive. .PARAMETER Sidebar Specifies the subfolder where the Get-Help `.mdx` files for the module will be created. Optional, defaults to `CmdLets`, case sensitive. .PARAMETER EditUrl Specifies the URL prefixed to all Docusaurus `custom_edit_url` front matter variables. .PARAMETER Monolithic Use this optional argument if the Powershell module source is monolithic. Will point all `custom_edit_url` front matter variables to the `.psm1` file. .NOTES Please note that Docusaurus v2 is an early and alpha version, just like this module. .LINK https://v2.docusaurus.io/ .LINK https://github.com/PowerShell/platyPS #> [cmdletbinding()] param( [Parameter(Mandatory = $True)][string]$Module, [Parameter(Mandatory = $False)][string]$OutputFolder = "docusaurus/docs", [Parameter(Mandatory = $False)][string]$Sidebar = "CmdLets", [Parameter(Mandatory = $True)][string]$EditUrl, [switch]$Monolithic ) # make sure the passed module is valid if (Test-Path($Module)) { Import-Module $Module -Force -Global $Module = [System.IO.Path]::GetFileNameWithoutExtension($Module) } if (-Not(Get-Module -Name $Module)) { $Module = $Module throw "New-DocusaurusHelp: Specified module '$Module' is not loaded" } # markdown for the module will be isolated in a subfolder $markdownFolder = Join-Path -Path $OutputFolder -ChildPath $Sidebar # generate PlatyPs markdown files $markdownFiles = New-MarkdownHelp -Module $Module -OutputFolder $markdownFolder -Force # update generated markdown file(s) to make them Docusaurus compatible ForEach ($markdownFile in $markdownFiles) { $customEditUrl = GetCustomEditUrl -Module $Module -MarkdownFile $markdownFile -EditUrl $EditUrl -Monolithic:$Monolithic SetMarkdownFrontMatter -MarkdownFile $markdownFile -CustomEditUrl $customEditUrl RemoveMarkdownHeaderOne -MarkdownFile $markdownFile UpdateMarkdownCodeBlocks -MarkdownFile $markdownFile UpdateMarkdownBackticks -MarkdownFile $markdownFile # rename to .mdx $mdxFilePath = GetMdxFilePath -MarkdownFile $markdownFile Move-Item -Path $markdownFile.FullName -Destination $mdxFilePath -Force | Out-Null # output .mdx item so end-user can post-process files as they see fit Get-Item $mdxFilePath } # generate the `.js` file used for the docusaurus sidebar NewSidebarIncludeFile -MarkdownFiles $markdownFiles -OutputFolder $markdownFolder -Sidebar $Sidebar } #EndRegion '.\Public\New-DocusaurusHelp.ps1' 96 |