1+ <#
2+ . SYNOPSIS
3+ README.md.ps1
4+ . DESCRIPTION
5+ README.md.ps1 makes README.md
6+
7+ This is a simple and helpful scripting convention for writing READMEs.
8+
9+ `./README.md.ps1 > ./README.md`
10+
11+ Feel free to copy and paste this code.
12+
13+ Please document your parameters, and add NOTES.
14+ . NOTES
15+ This README.md.ps1 is used to generate help for a module.
16+
17+ It:
18+
19+ * Outputs the name and description
20+ * Provides installation instructions
21+ * Lists commands
22+ * Lists parameters
23+ * Lists examples
24+ . EXAMPLE
25+ ./README.md.ps1 > ./README.md
26+ . EXAMPLE
27+ Get-Help ./README.md.ps1
28+ #>
29+ param (
30+ # The name of the module
31+ [string ]$ModuleName = $ ($PSScriptRoot | Split-Path - Leaf),
32+
33+ # The domains that serve git repositories.
34+ # If the project uri links to this domain,
35+ # installation instructions will show how to import the module locally.
36+ [string []]
37+ $GitDomains = @ (
38+ ' github.com' , ' tangled.org' , ' tangled.sh' , ' codeberg.org'
39+ ),
40+
41+ # If set, we don't need no badges.
42+ [switch ]
43+ $NoBadge ,
44+
45+ # If set, will not display gallery instructions or badges
46+ [switch ]
47+ $NotOnGallery
48+ )
49+
50+ Push-Location $PSScriptRoot
51+
52+ # Import the module
53+ $module = Import-Module " ./$ModuleName .psd1" - PassThru
54+
55+ # And output a header
56+ " # $module "
57+
58+ if (-not $NoBadge ) {
59+ # If it is on the gallery, show the downloads badge.
60+ if (-not $NotOnGallery ) {
61+ @ (
62+ " [!"
63+ " [$ModuleName ](https://img.shields.io/powershellgallery/dt/$ModuleName )"
64+ " ](https://www.powershellgallery.com/packages/$ModuleName /)"
65+ ) -join ' '
66+ }
67+ }
68+
69+ # Show the module description
70+ " ## $ ( $module.Description ) "
71+
72+ # Show any intro section defined in the manifest
73+ $module.PrivateData.PSData.PSIntro
74+
75+ # region Boilerplate installation instructions
76+ if (-not $NotOnGallery ) {
77+ @"
78+
79+ ## Installing and Importing
80+
81+ You can install $ModuleName from the [PowerShell gallery](https://powershellgallery.com/)
82+
83+ ~~~PowerShell
84+ Install-Module $ ( $ModuleName ) -Scope CurrentUser -Force
85+ ~~~
86+
87+ Once installed, you can import the module with:
88+
89+ ~~~PowerShell
90+ Import-Module $ModuleName -PassThru
91+ ~~~
92+
93+ "@
94+ }
95+ # endregion Gallery installation instructions
96+
97+ # region Git installation instructions
98+ $projectUri = $module.PrivateData.PSData.ProjectURI -as [uri ]
99+
100+ if ($projectUri.DnsSafeHost -in $GitDomains ) {
101+ @"
102+
103+ You can also clone the repo and import the module locally:
104+
105+ ~~~PowerShell
106+ git clone $projectUri
107+ cd ./$ModuleName
108+ Import-Module ./ -PassThru
109+ ~~~
110+
111+ "@
112+ }
113+ # endregion Git installation instructions
114+
115+ # region Exported Functions
116+ $exportedFunctions = $module.ExportedFunctions
117+ if ($exportedFunctions ) {
118+
119+ " ## Functions"
120+
121+ " $ ( $ModuleName ) has $ ( $exportedFunctions.Count ) function$ (
122+ if ($exportedFunctions.Count -gt 1 ) { " s" }
123+ ) "
124+
125+ foreach ($export in $exportedFunctions.Keys | Sort-Object ) {
126+ # Get help if it there is help to get
127+ $help = Get-Help $export
128+ # If the help is a string,
129+ if ($help -is [string ]) {
130+ # make it preformatted text
131+ " ~~~"
132+ " $export "
133+ " ~~~"
134+ } else {
135+ # Otherwise, add list the export
136+ " ### $ ( $export ) "
137+
138+ # And make it's synopsis a header
139+ " #### $ ( $help.SYNOPSIS ) "
140+
141+ # put the description below that
142+ " $ ( $help.Description.text -join [Environment ]::NewLine) "
143+
144+ if ($help.examples.example ) {
145+ # Show our examples
146+ " ##### Examples"
147+ }
148+
149+
150+ $exampleNumber = 0
151+ foreach ($example in $help.examples.example ) {
152+ $markdownLines = @ ()
153+ $exampleNumber ++
154+ $nonCommentLine = $false
155+ " ###### Example $exampleNumber "
156+
157+ # Combine the code and remarks
158+ $exampleLines =
159+ @ (
160+ $example.Code
161+ foreach ($remark in $example.Remarks.text ) {
162+ if (-not $remark ) { continue }
163+ $remark
164+ }
165+ ) -join ([Environment ]::NewLine) -split ' (?>\r\n|\n)' # and split into lines
166+
167+ # Go thru each line in the example as part of a loop
168+ $codeBlock = @ (foreach ($exampleLine in $exampleLines ) {
169+ # Any comments until the first uncommentedLine are markdown
170+ if ($exampleLine -match ' ^\#' -and -not $nonCommentLine ) {
171+ $markdownLines += $exampleLine -replace ' ^\#\s{0,1}'
172+ } else {
173+ $nonCommentLine = $true
174+ $exampleLine
175+ }
176+ }) -join [Environment ]::NewLine
177+
178+ $markdownLines
179+ " ~~~PowerShell"
180+ $CodeBlock
181+ " ~~~"
182+ }
183+
184+ $relatedUris = foreach ($link in $help.relatedLinks.navigationLink ) {
185+ if ($link.uri ) {
186+ $link.uri
187+ }
188+ }
189+ if ($relatedUris ) {
190+ " #### Links"
191+ foreach ($related in $relatedUris ) {
192+ " * [$related ]($related )"
193+ }
194+ }
195+
196+ # Make a table of parameters
197+ if ($help.parameters.parameter ) {
198+ " ##### Parameters"
199+
200+ " "
201+
202+ " |Name|Type|Description|"
203+ " |-|-|-|"
204+ foreach ($parameter in $help.Parameters.Parameter ) {
205+ " |$ ( $parameter.Name ) |$ ( $parameter.type.name ) |$ (
206+ $parameter.description.text -replace ' (?>\r\n|\n)' , ' <br/>'
207+ ) |"
208+ }
209+
210+ " "
211+ }
212+
213+ }
214+ }
215+ }
216+ # endregion Exported Functions
217+
218+ # region Copyright Notice
219+ if ($module.Copyright ) {
220+ " > $ ( $module.Copyright ) "
221+ }
222+
223+ if ($module.PrivateData.PSData.LicenseUri ) {
224+ " "
225+ " > [LICENSE]($ ( $module.PrivateData.PSData.LicenseUri ) )"
226+ }
227+ # endregion Copyright Notice
228+
229+ Pop-Location
0 commit comments