Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for data from XMLdoc for binary modules #618

Open
svrooij opened this issue Jan 11, 2024 · 4 comments
Open

Support for data from XMLdoc for binary modules #618

svrooij opened this issue Jan 11, 2024 · 4 comments
Labels
Idea-Helpv2 Issue-Enhancement Issue is more of a feature request than a bug

Comments

@svrooij
Copy link

svrooij commented Jan 11, 2024

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>.

  1. Execute New-MarkdownHelp ... first, to create the docs files.
  2. Put this script in the root of your project.
  3. Execute this script to update the markdown files, and to create the external help file in the root of your project.
  4. Mark the external help file as None and Copy 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
@svrooij svrooij added Issue-Enhancement Issue is more of a feature request than a bug Needs-Triage The issue is new and needs to be triaged by a work group. labels Jan 11, 2024
@sdwheeler sdwheeler added Idea-Helpv2 and removed Needs-Triage The issue is new and needs to be triaged by a work group. labels May 21, 2024
@sdwheeler sdwheeler added this to the Future-Consider milestone May 31, 2024
@svrooij
Copy link
Author

svrooij commented Aug 21, 2024

@sdwheeler are you accepting a PR for this? And can you help me get started? I have no clue where to look.

@sdwheeler
Copy link
Collaborator

@svrooij We are not considering support for XML docs at this time. We may consider it in the future. This would require further investigation.

@svrooij
Copy link
Author

svrooij commented Aug 22, 2024

I see the code in src\Markdown.MAML is not published as a nuget, can I just use a submodule to take that code and use it to write the xml file myself?

@sdwheeler
Copy link
Collaborator

No. That code is not supported and it is being replaced by a complete rewrite. You shouldn't take any dependencies on that code.

With the new version of PlatyPS that is being developed, you will import the cmdlet markdown files into a PowerShell object. You can then change property values in the object to update the documentation. So you could read documentation from the XMLdoc and inject it into the object. Then you write that object out as Markdown, Yaml, or MAML.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Idea-Helpv2 Issue-Enhancement Issue is more of a feature request than a bug
Projects
None yet
Development

No branches or pull requests

2 participants