├── ConvertFromMarkdown.psd1
├── ConvertFromMarkdown.psm1
├── DoTests.ps1
├── Example
├── README.md
├── lintThis.ps1
└── manuscript
│ ├── Book.txt
│ ├── chapter00.md
│ └── chapter01.md
├── InstallModule.ps1
├── LICENSE
├── PublishToGallery.ps1
├── README.md
├── TestPSCodeBlock.ps1
├── TestREADME.md
├── __tests__
├── ConvertFromReadmeMD.tests.ps1
├── README.md
├── READMECodeThatErrors.md
├── READMEExcludeCode.md
├── READMEGoodCode.md
├── READMEOneChapterNoCode.md
└── changelog.md
├── appveyor.yml
├── exportManuscript.ps1
└── images
├── Convert.png
├── ConvertExampleReadme.png
└── manuscript.png
/ConvertFromMarkdown.psd1:
--------------------------------------------------------------------------------
1 | @{
2 |
3 | # Script module or binary module file associated with this manifest.
4 | RootModule = 'ConvertFromMarkdown.psm1'
5 |
6 | # Version number of this module.
7 | ModuleVersion = '1.2.0'
8 |
9 | # ID used to uniquely identify this module
10 | GUID = '83c87d12-6c30-424f-ab67-9016daada1d4'
11 |
12 | # Author of this module
13 | Author = 'Douglas Finke'
14 |
15 | # Company or vendor of this module
16 | CompanyName = 'Doug Finke'
17 |
18 | # Copyright statement for this module
19 | Copyright = 'c 2018 All rights reserved.'
20 |
21 | # Description of the functionality provided by this module
22 | Description = @'
23 | From your Markdown to generated chapters, run ScriptAnalyzer on your examples and generate HTML, a Word Doc or PDF. Table of Contents included
24 | '@
25 |
26 | # Minimum version of the Windows PowerShell engine required by this module
27 | # PowerShellVersion = ''
28 |
29 | # Name of the Windows PowerShell host required by this module
30 | # PowerShellHostName = ''
31 |
32 | # Minimum version of the Windows PowerShell host required by this module
33 | # PowerShellHostVersion = ''
34 |
35 | # Minimum version of Microsoft .NET Framework required by this module
36 | # DotNetFrameworkVersion = ''
37 |
38 | # Minimum version of the common language runtime (CLR) required by this module
39 | # CLRVersion = ''
40 |
41 | # Processor architecture (None, X86, Amd64) required by this module
42 | # ProcessorArchitecture = ''
43 |
44 | # Modules that must be imported into the global environment prior to importing this module
45 | # RequiredModules = @()
46 |
47 | # Assemblies that must be loaded prior to importing this module
48 | # RequiredAssemblies = @()
49 |
50 | # Script files (.ps1) that are run in the caller's environment prior to importing this module.
51 | # ScriptsToProcess = @()
52 |
53 | # Type files (.ps1xml) to be loaded when importing this module
54 | # TypesToProcess = @()
55 |
56 | # Format files (.ps1xml) to be loaded when importing this module
57 | # FormatsToProcess = @()
58 |
59 | # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
60 | # NestedModules = @()
61 |
62 | # Functions to export from this module
63 | FunctionsToExport = '*'
64 |
65 | # Cmdlets to export from this module
66 | CmdletsToExport = '*'
67 |
68 | # Variables to export from this module
69 | VariablesToExport = '*'
70 |
71 | # Aliases to export from this module
72 | AliasesToExport = '*'
73 |
74 | # List of all modules packaged with this module
75 | # ModuleList = @()
76 |
77 | # List of all files packaged with this module
78 | # FileList = @()
79 |
80 | # Private data to pass to the module specified in RootModule/ModuleToProcess
81 | PrivateData = @{
82 | # PSData is module packaging and gallery metadata embedded in PrivateData
83 | # It's for rebuilding PowerShellGet (and PoshCode) NuGet-style packages
84 | # We had to do this because it's the only place we're allowed to extend the manifest
85 | # https://connect.microsoft.com/PowerShell/feedback/details/421837
86 | PSData = @{
87 | # The primary categorization of this module (from the TechNet Gallery tech tree).
88 | Category = "PowerShell Documentation Markdown"
89 |
90 | # Keyword tags to help users find this module via navigations and search.
91 | Tags = @("PowerShell", "Markdown")
92 |
93 | # The web address of an icon which can be used in galleries to represent this module
94 | # IconUri = ""
95 |
96 | # The web address of this module's project or support homepage.
97 | ProjectUri = "https://github.com/dfinke/ConvertFromMarkdown"
98 |
99 | # The web address of this module's license. Points to a page that's embeddable and linkable.
100 | LicenseUri = "https://github.com/dfinke/ConvertFromMarkdown/blob/master/LICENSE"
101 |
102 | # Release notes for this particular version of the module
103 | #ReleaseNotes = $True
104 |
105 | # If true, the LicenseUrl points to an end-user license (not just a source license) which requires the user agreement before use.
106 | # RequireLicenseAcceptance = ""
107 |
108 | # Indicates this is a pre-release/testing version of the module.
109 | IsPrerelease = 'False'
110 | }
111 | }
112 |
113 | # HelpInfo URI of this module
114 | # HelpInfoURI = ''
115 |
116 | # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
117 | # DefaultCommandPrefix = ''
118 |
119 | }
--------------------------------------------------------------------------------
/ConvertFromMarkdown.psm1:
--------------------------------------------------------------------------------
1 | . $PSScriptRoot\exportManuscript.ps1
2 | . $PSScriptRoot\TestPSCodeBlock.ps1
3 |
4 | function Test-Chapter {
5 | param (
6 | $outputPath = $pwd
7 | )
8 |
9 | (Get-ChildItem $outputPath).Count -gt 0
10 | }
11 |
12 | function ConvertFrom-Markdown {
13 | param (
14 | $markdownFile = "$pwd\README.md",
15 | $outputPath = $pwd,
16 | [ValidateSet("Html", "Docx", "PDF")]
17 | $OutputType,
18 | [Switch]$Show
19 | )
20 |
21 | Write-Progress -Activity "Generating manuscript" -Status "[$(Get-Date)] Creating chapters"
22 | Export-Manuscript -markdownFile $markdownFile -outputPath $outputPath
23 |
24 | $targetPath = "$($outputPath)\manuscript"
25 |
26 | Write-Progress -Activity "Generating manuscript" -Status "[$(Get-Date)] Analyzing PowerShell"
27 | Test-PSCodeBlock -markdownFile $markdownFile -outputPath $outputPath
28 |
29 |
30 | if (!(Test-Chapter $targetPath)) {
31 | "No chapters found"
32 | return
33 | }
34 |
35 | #if ((Get-Command pandoc.exe -ErrorAction SilentlyContinue) -and $AsPDF) {
36 | if ($OutputType) {
37 |
38 | if (!(Get-Command pandoc.exe -ErrorAction SilentlyContinue)) {
39 | Write-Warning @"
40 | To generate that output type, you need to install Pandoc, https://pandoc.org/installing.html
41 | If you want a PDF, you need to also install LaTeX, https://miktex.org/
42 | "@
43 | return
44 | }
45 |
46 | # $chapters = (Get-Content "$targetPath\book.txt") -join ' '
47 | $chapters = (Get-ChildItem $targetPath chap* | ForEach-Object FullName ) -join ' '
48 |
49 | # if ($chapters.trim().length -gt 0) {
50 | $outFile = "$($targetPath)\book.$($OutputType)"
51 | Write-Progress -Activity "Generating manuscript" -Status "[$(Get-Date)] Creating $($OutputType)"
52 | "pandoc $chapters -S --toc --standalone -o $outFile" | Invoke-Expression
53 |
54 | Write-Progress -Activity "Generating manuscript" -Status "[$(Get-Date)] Launching $($OutputType)"
55 | if ($Show) {
56 | Invoke-Item $outFile
57 | }
58 | # }
59 | # else {
60 | # "No chapters found"
61 | # }
62 | }
63 | }
64 |
65 | function Test-IsUri {
66 | param($targetUri)
67 |
68 | [System.Uri]::IsWellFormedUriString($targetUri, 'Absolute')
69 | }
--------------------------------------------------------------------------------
/DoTests.ps1:
--------------------------------------------------------------------------------
1 | $PSVersionTable.PSVersion
2 |
3 | $ErrorActionPreference = "Continue"
4 |
5 | if ((Get-Module -ListAvailable pester) -eq $null) {
6 | Install-Module -Name Pester -Repository PSGallery -Force -Scope CurrentUser
7 | }
8 |
9 | if ((Get-Module -ListAvailable PSScriptAnalyzer) -eq $null) {
10 | Install-Module -Name PSScriptAnalyzer -Repository PSGallery -Force -Scope CurrentUser
11 | }
12 |
13 | $result = Invoke-Pester -Script $PSScriptRoot\__tests__ -Verbose -PassThru
14 |
15 | if ($result.FailedCount -gt 0) {
16 | throw "$($result.FailedCount) tests failed."
17 | }
--------------------------------------------------------------------------------
/Example/README.md:
--------------------------------------------------------------------------------
1 |
2 | # STRINGS
3 |
4 | ## Trim leading and trailing white-space from string
5 |
6 | This is an alternative to using the `Trim()` method. The
7 | function below works by finding all leading and trailing white-space and
8 | removing it from the start and end of the string.
9 |
10 | **Example Function:**
11 |
12 | ```ps
13 | function Invoke-TrimString {
14 | param($targetText)
15 |
16 | $targetText -replace '^[ \t]+|[ \t]+$', ''
17 | }
18 | ```
19 |
20 | **Example Usage:**
21 |
22 | ```powershell
23 | PS C:\> Invoke-TrimString " Hello, World "
24 | Hello, World
25 |
26 | PS C:\> $name = " John Black "
27 | PS C:\> Invoke-TrimString $name
28 | John Black
29 | ```
30 |
31 | ## Strip all instances of pattern from string
32 |
33 | **Example Function:**
34 |
35 | ```ps
36 | function Invoke-StripAll {
37 | param($targetText, $pattern)
38 |
39 | $count = 0
40 | $targetText -replace $pattern, ''
41 | }
42 | ```
43 |
44 | **Example Usage:**
45 |
46 | ```powershell
47 | PS C:\> Invoke-StripAll "The Quick Brown Fox" "[aeiou]"
48 | Th Qck Brwn Fx
49 |
50 | PS C:\> Invoke-StripAll "The Quick Brown Fox" " "
51 | TheQuickBrownFox
52 |
53 | PS C:\> Invoke-StripAll "The Quick Brown Fox" "Quick "
54 | The Brown Fox
55 | ```
56 |
57 |
58 |
59 |
60 | # ARRAYS
61 |
62 |
--------------------------------------------------------------------------------
/Example/lintThis.ps1:
--------------------------------------------------------------------------------
1 | function Invoke-TrimString {
2 | param($targetText)
3 |
4 | $targetText -replace '^[ \t]+|[ \t]+$', ''
5 | }
6 |
7 | function Invoke-StripAll {
8 | param($targetText, $pattern)
9 |
10 | $count = 0
11 | $targetText -replace $pattern, ''
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/Example/manuscript/Book.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dfinke/ConvertFromMarkdown/c6a04ae1991baba336fc001a8b434e6e15c2b55c/Example/manuscript/Book.txt
--------------------------------------------------------------------------------
/Example/manuscript/chapter00.md:
--------------------------------------------------------------------------------
1 | # STRINGS
2 |
3 | ## Trim leading and trailing white-space from string
4 |
5 | This is an alternative to using the `Trim()` method. The
6 | function below works by finding all leading and trailing white-space and
7 | removing it from the start and end of the string.
8 |
9 | **Example Function:**
10 |
11 | ```ps
12 | function Invoke-TrimString {
13 | param($targetText)
14 |
15 | $targetText -replace '^[ \t]+|[ \t]+$', ''
16 | }
17 | ```
18 |
19 | **Example Usage:**
20 |
21 | ```powershell
22 | PS C:\> Invoke-TrimString " Hello, World "
23 | Hello, World
24 |
25 | PS C:\> $name = " John Black "
26 | PS C:\> Invoke-TrimString $name
27 | John Black
28 | ```
29 |
30 | ## Strip all instances of pattern from string
31 |
32 | **Example Function:**
33 |
34 | ```ps
35 | function Invoke-StripAll {
36 | param($targetText, $pattern)
37 |
38 | $count = 0
39 | $targetText -replace $pattern, ''
40 | }
41 | ```
42 |
43 | **Example Usage:**
44 |
45 | ```powershell
46 | PS C:\> Invoke-StripAll "The Quick Brown Fox" "[aeiou]"
47 | Th Qck Brwn Fx
48 |
49 | PS C:\> Invoke-StripAll "The Quick Brown Fox" " "
50 | TheQuickBrownFox
51 |
52 | PS C:\> Invoke-StripAll "The Quick Brown Fox" "Quick "
53 | The Brown Fox
54 | ```
55 |
56 |
--------------------------------------------------------------------------------
/Example/manuscript/chapter01.md:
--------------------------------------------------------------------------------
1 | # ARRAYS
2 |
--------------------------------------------------------------------------------
/InstallModule.ps1:
--------------------------------------------------------------------------------
1 | $fullPath = 'C:\Program Files\WindowsPowerShell\Modules\ConvertFromMarkdown'
2 |
3 | Robocopy . $fullPath /mir /XD .vscode .git /XF appveyor.yml
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Doug Finke
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/PublishToGallery.ps1:
--------------------------------------------------------------------------------
1 | $p = @{
2 | Name = "ConvertFromMarkdown"
3 | NuGetApiKey = $NuGetApiKey
4 | #ReleaseNote = "Add NumberFormat parameter"
5 | }
6 |
7 | Publish-Module @p
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ## Convert From Markdown: In Action Video
6 |
7 | Check it out, How to ConvertFrom-Markdown with all the bells and whistles.
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | ## Updates
17 |
18 | - Added `KeepLintFile` switch
19 | - Added try/catch around `Invoke-ScriptAnalyzer`
20 | - Added `` and ``. For example, if have code blocks that define the same class, you can exclude
21 | it so PSScriptAnalyzer doesn't fail
22 |
23 | # Convert From Markdown
24 | Quickly re-purpose your markdown as input to a service like LeanPub (for self publishing), and run the PowerShell ScriptAnalyzer against your PowerShell samples in the markdown.
25 |
26 | This PowerShell module significantly improves your workflow for authoring your PowerShell `README.md`
27 |
28 | Leveraging markdown, a typical workflow is creating a README.md for your PowerShell module/scripts. Describing your functions, parameters and how they operate. Next, supplying examples of these functions in action, and followed by sample output.
29 |
30 | While this is a great way to communicate with your audience, it causes a few problems for you, the author. First it locks your documentation into your README, making it difficult to re-purpose, for example as input to a service like LeanPub, a platform which is the combination of two things: a publishing workflow and a storefront.
31 |
32 | The second challenge is, how can you make sure that your PowerShell examples are correct? One way to solve this is you do the double work of "testing" the code you add to the markdown.
33 |
34 | This module improves that with two simple additions to your markdown authoring.
35 |
36 | ## Fenced code blocks and Chapters
37 |
38 | ### Fenced code blocks
39 | Fenced code blocks let you create highlighted coding in your `README`. You can create fenced code blocks by placing triple backticks ```.
40 |
41 | Syntax highlighting can be done with ```ps. For example:
42 |
43 | ```
44 | ```ps
45 | function test {
46 | param(
47 | $name
48 | )
49 | }
50 | ```
51 | ```
52 |
53 | Becomes this:
54 | ```ps
55 | function test {
56 | param(
57 | $name
58 | )
59 | }
60 | ```
61 |
62 | ### Chapters
63 |
64 | In markdown you can have comments, they take the form of ``.
65 | Let's leverage that with `` an ``
66 |
67 | Wrapping sections of your markdown with these enable cool automation opportunities by becoming "`fenced chapter blocks`".
68 |
69 | ## Where are we?
70 |
71 | By continuing to use `fenced code blocks`, and adopting `fenced chapter blocks`, next level automation can be achieved.
72 |
73 | This module reads your markdown and when it finds these blocks it extracts two things. First it creates a manuscript (ready for LeanPub), by creating a `manuscript` directory and placing "`fenced chapter blocks`" in numbered `chapterNNN.txt` files, including a `book.txt`
74 |
75 | Then, it pulls out the PowerShell code and runs the PowerShell ScriptAnalyzer on it, reporting any issues.
76 |
77 |
78 | ## In Action
79 |
80 | Running the `ConverFrom-ReadmeMD` on a markdown file does a few things. It extracts the code in the fenced code blocks and runs the PowerShell ScriptAnalyzer against it
81 |
82 | ### The Analyzer
83 | 
84 |
85 | And, it extracts all the `fenced chapter blocks` into the `manuscript` director, ready for shipping to LeanPub for publishing.
86 |
87 | ### The Manuscript
88 |
89 | Here is the extraction of the `fenced chapter blocks` ready for your book publishing.
90 |
91 | 
92 |
93 | ## Summary
94 |
95 | Re-purposing effort makes us more agile, improves cycle time (from idea to customers using it). This module bumps you up to the next level.
96 |
97 | Enjoy
--------------------------------------------------------------------------------
/TestPSCodeBlock.ps1:
--------------------------------------------------------------------------------
1 | #Requires -modules PSScriptAnalyzer
2 |
3 | function Test-PSCodeBlock {
4 | param (
5 | $markdownFile = "$pwd\README.md",
6 | $outputPath = $pwd,
7 | [Switch]$KeepLintFile
8 | )
9 |
10 | $codeBlocks = [ordered]@{}
11 | $inCodeBlock = $false
12 | $codeBlockIndex = 0
13 | $excludeCode = $false
14 |
15 | if (!(Test-IsUri $markdownFile)) {
16 | $markdownContent = Get-Content $markdownFile
17 | }
18 | else {
19 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
20 | $markdownContent = Invoke-RestMethod $markdownFile
21 | $markdownContent = $markdownContent -split "`n"
22 | }
23 |
24 | # switch -File ($markdownFile) {
25 | switch ($markdownContent) {
26 |
27 | '' {$excludeCode = $true}
28 | '' {$excludeCode = $false}
29 |
30 | '```' {
31 | $inCodeBlock = $false
32 | $codeBlockIndex += 1
33 | }
34 |
35 | {$inCodeBlock} {
36 | if (!$excludeCode) {
37 | $currentBlock = "block{0:0#}" -f $codeBlockIndex
38 | $codeBlocks.$currentBlock += $_ + "`r`n"
39 | }
40 | }
41 |
42 | '```ps' {$inCodeBlock = $true}
43 |
44 | default {}
45 | }
46 |
47 | if ($codeBlocks.Values.count -gt 0) {
48 | #$targetFile = "$pwd\lintThis.ps1"
49 | $targetFile = "$outputPath\lintThis.ps1"
50 | $codeBlocks.Values | Set-Content -Encoding Ascii $targetFile
51 |
52 | try {
53 | $analysis = Invoke-ScriptAnalyzer $targetFile -ErrorAction Stop
54 |
55 | if ($analysis.count -gt 0) {
56 | $analysis
57 | }
58 | else {
59 | "all analyzed - no issues"
60 | if (!$KeepLintFile) {
61 | Remove-Item $targetFile
62 | }
63 | }
64 | }
65 | catch {
66 | $_.Exception
67 | #throw 'caught'
68 | }
69 | }
70 | else {
71 | "no code found"
72 | }
73 | }
--------------------------------------------------------------------------------
/TestREADME.md:
--------------------------------------------------------------------------------
1 |
2 | # Let's Talk about Strings
3 | Lets convert lowercase strings to uppercase
4 |
5 | ```ps
6 | 'this Is MixEd CaSe'.ToUpper()
7 | ```
8 |
9 | ## Prints
10 |
11 | ```
12 | THIS IS MIXED CASE
13 | ```
14 |
15 |
16 |
17 |
18 | # Let's Talk about Functions
19 | Here is a simple function.
20 |
21 | ```ps
22 | function test {
23 | "Hello World"
24 | }
25 | ```
26 |
27 | ### Example Usage
28 |
29 | ```powershell
30 | PS C:\> test
31 |
32 | Hello World
33 | ```
34 |
35 |
36 |
37 |
38 | # Let's Talk about ScriptAnalyzer Errors
39 |
40 | Spot the issue
41 |
42 |
43 | ```ps
44 | function test {
45 | param($p)
46 |
47 | $result = "Hello $p"
48 | }
49 | ```
50 |
51 | ### Example Usage
52 |
53 | ```powershell
54 | PS C:\> test
55 | ```
56 |
57 |
--------------------------------------------------------------------------------
/__tests__/ConvertFromReadmeMD.tests.ps1:
--------------------------------------------------------------------------------
1 | Describe "Convertfrom ReadmdMD" {
2 |
3 | BeforeAll {
4 | Import-Module $PSScriptRoot\..\ConvertFromMarkdown.psm1 -Force
5 | }
6 |
7 | AfterEach {
8 | Remove-Item $env:TEMP\manuscript -Recurse -Force -ErrorAction Ignore
9 | Remove-Item $env:TEMP\lintThis.ps1 -Force -ErrorAction Ignore
10 | }
11 |
12 | It "Should create a manuscript folder" {
13 | ConvertFrom-Markdown $PSScriptRoot\README.md $env:TEMP
14 |
15 | Test-Path $env:TEMP\manuscript | Should Be $true
16 | Test-Path $env:TEMP\lintThis.ps1 | Should Be $true
17 | }
18 |
19 | It "Should have six files in the manuscript directory" {
20 | ConvertFrom-Markdown $PSScriptRoot\README.md $env:TEMP
21 |
22 | (Get-ChildItem $env:TEMP\manuscript | Measure-Object ).Count | Should Be 6
23 | }
24 |
25 | It "Read from the web, should have six files in the manuscript directory" {
26 | ConvertFrom-Markdown https://raw.githubusercontent.com/dfinke/ConvertFromMarkdown/master/__tests__/README.md $env:TEMP
27 | (Get-ChildItem $env:TEMP\manuscript | Measure-Object ).Count | Should Be 6
28 | }
29 |
30 | It "Should have book.md in the manuscript directory" {
31 | ConvertFrom-Markdown $PSScriptRoot\README.md $env:TEMP
32 |
33 | Test-Path $env:TEMP\manuscript\book.txt | Should Be $true
34 | }
35 |
36 | It "Should have five chapter files in the manuscript directory" {
37 | ConvertFrom-Markdown $PSScriptRoot\README.md $env:TEMP
38 |
39 | (Get-ChildItem $env:TEMP\manuscript chapter*.txt | Measure-Object ).Count | Should Be 5
40 | }
41 |
42 | It "Should create a manuscript folder no code blocks" {
43 | ConvertFrom-Markdown $PSScriptRoot\READMEOneChapterNoCode.md $env:TEMP
44 |
45 | Test-Path $env:TEMP\manuscript | Should Be $true
46 | Test-Path $env:TEMP\lintThis.ps1 | Should Be $false
47 | }
48 |
49 | It "Should create a test code blocks and delete lint file" {
50 | $actual = Test-PSCodeBlock $PSScriptRoot\READMEGoodCode.md $env:TEMP
51 | $actual | Should Be "all analyzed - no issues"
52 | Test-Path $env:TEMP\lintThis.ps1 | Should Be $false
53 | }
54 |
55 | It "Reads from the web, should create a test code blocks and delete lint file" {
56 | $actual = Test-PSCodeBlock https://raw.githubusercontent.com/dfinke/ConvertFromMarkdown/master/__tests__/READMEGoodCode.md $env:TEMP
57 | $actual | Should Be "all analyzed - no issues"
58 | Test-Path $env:TEMP\lintThis.ps1 | Should Be $false
59 | }
60 |
61 | It "Should keep lint file" {
62 | $actual = Test-PSCodeBlock $PSScriptRoot\READMEGoodCode.md $env:TEMP -KeepLintFile
63 | $actual | Should Be "all analyzed - no issues"
64 |
65 | Test-Path $env:TEMP\lintThis.ps1 | Should Be $true
66 | }
67 |
68 | It "Should handle errors in the fenced blocks" {
69 | $actual = Test-PSCodeBlock $PSScriptRoot\READMECodeThatErrors.md $env:TEMP
70 | $actual | Should Not Be "all analyzed - no issues"
71 |
72 | Test-Path $env:TEMP\lintThis.ps1 | Should Be $true
73 | }
74 |
75 | It "Should respect excluded blocks" {
76 | $actual = Test-PSCodeBlock $PSScriptRoot\READMEExcludeCode.md $env:TEMP
77 | $actual | Should Be "all analyzed - no issues"
78 |
79 | Test-Path $env:TEMP\lintThis.ps1 | Should Be $false
80 | }
81 |
82 | It "Should fail as a Uri" {
83 | Test-IsUri .\README.md | Should Be $false
84 | }
85 |
86 | It "Should be a Uri" {
87 | Test-IsUri https://raw.githubusercontent.com/dfinke/ConvertFromMarkdown/master/README.md | Should Be $true
88 | }
89 |
90 | AfterAll {
91 | Remove-Item $env:TEMP\manuscript -Recurse -Force -ErrorAction Ignore
92 | Remove-Item $env:TEMP\lintThis.ps1 -Force -ErrorAction Ignore
93 | }
94 | }
95 |
96 | Describe "Test markdown file with no chapters and no code" {
97 | BeforeAll {
98 | Import-Module $PSScriptRoot\..\ConvertFromMarkdown.psm1 -Force
99 | }
100 |
101 | It "Should report no code" {
102 | $actual = ConvertFrom-Markdown $PSScriptRoot\changelog.md -OutputType PDF
103 |
104 | $actual.Count | Should Be 2
105 |
106 | $actual[0] | Should Be 'no code found'
107 | $actual[1] | Should Be 'No chapters found'
108 | }
109 |
110 | AfterAll {
111 | Remove-Item $env:TEMP\manuscript -Recurse -Force -ErrorAction Ignore
112 | Remove-Item $env:TEMP\lintThis.ps1 -Force -ErrorAction Ignore
113 | }
114 |
115 | }
--------------------------------------------------------------------------------
/__tests__/README.md:
--------------------------------------------------------------------------------
1 | # ConvertFromReadmeMD
2 | Transform a README.md
3 |
4 |
5 |
6 | ## Let's talk about strings
7 |
8 | PowerShell strings are textual
9 |
10 |
11 |
12 |
13 | ## Let's talk about variables
14 |
15 | All variables start with a `$`.
16 |
17 | ```ps
18 | $a=1
19 | $a++
20 | $a
21 | ```
22 |
23 | Prints
24 |
25 | ```powershell
26 | 2
27 | ```
28 |
29 |
30 |
31 |
32 | ## Let's talk about Cmdlets
33 |
34 | verb-noun
35 |
36 |
37 |
38 |
39 |
40 | ## Let's talk about Functions
41 |
42 | ```ps
43 | function test {
44 | $n = "World"
45 | "Hello "
46 | }
47 | ```
48 |
49 | ### Example Usage:
50 |
51 | ```powershell
52 | PS C:\> test "World"
53 |
54 | ```
55 |
56 |
57 |
58 |
59 | ## Let's talk about REST
60 |
61 | `Invoke-RestMethod`
62 |
63 |
64 |
--------------------------------------------------------------------------------
/__tests__/READMECodeThatErrors.md:
--------------------------------------------------------------------------------
1 |
2 | ## Let's talk about strings
3 |
4 | PowerShell strings are textual
5 |
6 | ```ps
7 | class Test {}
8 | ```
9 |
10 | ```ps
11 | class Test {}
12 | ```
13 |
--------------------------------------------------------------------------------
/__tests__/READMEExcludeCode.md:
--------------------------------------------------------------------------------
1 |
2 | ## Let's talk about strings
3 |
4 | PowerShell strings are textual
5 |
6 |
7 | ```ps
8 | class Test {}
9 | ```
10 |
11 |
12 | ```ps
13 | class Test {}
14 | ```
15 |
--------------------------------------------------------------------------------
/__tests__/READMEGoodCode.md:
--------------------------------------------------------------------------------
1 |
2 | ## Let's talk about strings
3 |
4 | PowerShell strings are textual
5 |
6 | ```ps
7 | function Test {
8 | "Hello World"
9 | }
10 | ```
11 |
12 |
--------------------------------------------------------------------------------
/__tests__/READMEOneChapterNoCode.md:
--------------------------------------------------------------------------------
1 |
2 | ## Let's talk about strings
3 |
4 | PowerShell strings are textual
5 |
6 |
--------------------------------------------------------------------------------
/__tests__/changelog.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## unreleased
4 |
5 | - Test3
6 | - Test4
7 |
8 | ## 4.0.30
9 |
10 | - Test1
11 | - Test2
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dfinke/ConvertFromMarkdown/c6a04ae1991baba336fc001a8b434e6e15c2b55c/appveyor.yml
--------------------------------------------------------------------------------
/exportManuscript.ps1:
--------------------------------------------------------------------------------
1 | function Export-Manuscript {
2 | param(
3 | $markdownFile = "$pwd\README.md",
4 | $outputPath = $pwd,
5 | [ValidateSet('txt', 'md')]
6 | $chapterExtension = "txt"
7 | )
8 |
9 | $manuscriptPath = "$outputPath\manuscript"
10 |
11 | Remove-Item -Recurse -Force $manuscriptPath -ErrorAction Ignore
12 |
13 | $null = mkdir $manuscriptPath
14 |
15 | $chapters = [ordered]@{}
16 | $chapterIndex = 0
17 |
18 | if (!(Test-IsUri $markdownFile)) {
19 | $markdownContent = Get-Content $markdownFile
20 | }
21 | else {
22 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
23 | $markdownContent = Invoke-RestMethod $markdownFile
24 | $markdownContent = $markdownContent -split "`n"
25 | }
26 |
27 | # switch -File ($markdownFile) {
28 | switch ($markdownContent) {
29 |
30 | "" {
31 | $inChapter = $false
32 | $chapterIndex += 1
33 | }
34 |
35 | {$inChapter} {
36 | $currentChapter = "chapter{0:0#}" -f $chapterIndex
37 | if (!$chapters.$currentChapter) {
38 | $chapters.$currentChapter = @()
39 | }
40 |
41 | $chapters.$currentChapter += $_
42 | }
43 |
44 | "" {$inChapter = $true}
45 | }
46 |
47 | foreach ($chapter in $chapters.Keys) {
48 |
49 | #$chapter
50 | $chapterName = "$($chapter).$($chapterExtension)"
51 | $chapterFile = "$($manuscriptPath)\$($chapterName)"
52 |
53 | $chapters.$chapter | Set-Content -Encoding Ascii $chapterFile
54 | $chapterName >> "$manuscriptPath\Book.txt"
55 | }
56 | }
--------------------------------------------------------------------------------
/images/Convert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dfinke/ConvertFromMarkdown/c6a04ae1991baba336fc001a8b434e6e15c2b55c/images/Convert.png
--------------------------------------------------------------------------------
/images/ConvertExampleReadme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dfinke/ConvertFromMarkdown/c6a04ae1991baba336fc001a8b434e6e15c2b55c/images/ConvertExampleReadme.png
--------------------------------------------------------------------------------
/images/manuscript.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dfinke/ConvertFromMarkdown/c6a04ae1991baba336fc001a8b434e6e15c2b55c/images/manuscript.png
--------------------------------------------------------------------------------