platyPS
platyPS copied to clipboard
Support for data from XMLdoc for binary modules
Summary of the new feature / enhancement
As a developer of a binary powershell module I would like to document in inside the C# files, as I'm used to for creating C# libraries.
Proposed technical implementation details (optional)
I suggest supporting XML docs above the PsCmdLet
as follows:
/// <summary>
/// <para type="synopsis">Synopsis here</para>
/// <para type="description">Long description here</para>
/// <para type="link" uri="https://wintuner.app/docs/related/content-prep-tool">Documentation</para>
/// </summary>
/// <example>
/// <para type="description">Sample description here</para>
/// <code>Sample code here</code>
/// </example>
And I wrote a powershell script that parses the generated C# xml documentation file and updates the markdown files accordingly. This powershell replaces the placeholders with data from the xml docs. If the data is already updated nothing will happen. Off-course it would be better to integrate this right into the normal c# code that does the markdown generation. Something like -GenerateUsingXmlDocs <docsLocation>
.
- Execute
New-MarkdownHelp ...
first, to create the docs files. - Put this script in the root of your project.
- Execute this script to update the markdown files, and to create the external help file in the root of your project.
- Mark the external help file as
None
andCopy Always
in the properties in Visual Studio.
# change accordingly
$xmlDocsPath = ".\bin\Release\net7.0\ProjectName.xml"
$docsFolder = "docs"
# Start Process to build the project
$buildOutput = & dotnet build -c Release -v quiet
# Check if the build succeeded by looking for the string "Build succeeded."
if ($buildOutput -match "Build succeeded.") {
Write-Output "Project build succeeded"
}
else {
Write-Output "Build failed"
Write-Output $buildOutput
exit
}
Write-Output "Generating docs from XML file $xmlDocsPath"
# Load the XML documentation file
[xml]$xmlDocs = Get-Content $xmlDocsPath
$assemblyName = $xmlDocs.doc.assembly.name
Write-Debug "Updating docs for Assembly: $assemblyName"
$members = $xmlDocs.doc.members.member
# Iterate over all <member> objects
foreach ($member in $members) {
# member looks like this:
# <member name="T:Your.Namespace.ClassNameForPsCmdLet">
# <summary>
# <para type="synopsis">synopsis here</para>
# <para type="description">PsCmdLet description here</para>
# <para type="link" uri="https://wintuner.app/docs/related/content-prep-tool">Documentation</para>
# </summary>
# <example>
# <para type="description">Sample description here</para>
# <code>Sample Code here</code>
# </example>
# </member>
# Extract the name of the member
$name = $member.Attributes[0].'#text'
if ($name.startsWith("T:" + $assemblyName)) {
$name = $name.substring(2 + $assemblyName.length + 1)
# name NewIntuneWinPackage
Write-Output "Try to update markdown file for: $name"
# Extract the synopsis
$synopsis = $member.summary.'para' | Where-Object { $_.type -eq 'synopsis' } | Select-Object -ExpandProperty '#text'
Write-Debug "Synopsis: $synopsis"
# Extract the description
$description = $member.summary.'para' | Where-Object { $_.type -eq 'description' } | Select-Object -ExpandProperty '#text'
Write-Debug "Description: $description"
# Extract the example
$exampleDescription = $member.example.'para'| Where-Object { $_.type -eq 'description' } | Select-Object -ExpandProperty '#text'
$exampleCode = $member.example.'code'
Write-Debug "Example Description: $exampleDescription"
Write-Debug "Example Code: $exampleCode"
# Create the MD file name by putting a - only before the second capital letter, so NewIntuneWinPackage becomes New-IntuneWinPackage
$index = $name.IndexOfAny([char[]]"ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray(), 1)
$mdFile = $name.Substring(0, $index) + "-" + $name.Substring($index) + ".md"
Write-Debug "MD Filename: $mdFile"
# Check if the $mdFile exists in the docs folder
$mdFilePath = Join-Path "${PSScriptRoot}\$docsFolder" $mdFile
if (Test-Path $mdFilePath) {
# load the existing file
$mdFileContent = Get-Content $mdFilePath
# Replace the synopsis placeholder '{{ Fill in the Synopsis }}' with the actual synopsis
$mdFileContent = $mdFileContent.Replace('{{ Fill in the Synopsis }}', $synopsis)
# Replace the description placeholder '{{ Fill in the Description }}' with the actual description
$mdFileContent = $mdFileContent.Replace('{{ Fill in the Description }}', $description)
# Replace the example description placeholder '{{ Add example description here }}' with the actual example description
$mdFileContent = $mdFileContent.Replace('{{ Add example description here }}', $exampleDescription)
# Replace the example code placeholder '{{ Add example code here }}' with the actual example code
$mdFileContent = $mdFileContent.Replace('{{ Add example code here }}', $exampleCode)
# Write the updated file back to disk
$mdFileContent | Set-Content $mdFilePath
}
else {
Write-Warning "File $mdFilePath does not exist"
}
}
}
Write-Output "Done updating markdown files with XML documentation"
New-ExternalHelp -Path "${PSScriptRoot}\$docsFolder" -OutputPath "${PSScriptRoot}" -Force