Skip to content

Commit

Permalink
Merge pull request #122 from carceneaux-forks/json
Browse files Browse the repository at this point in the history
Adding JSON Plugin
  • Loading branch information
iainbrighton authored Jun 21, 2023
2 parents 572513f + 15c52f6 commit efeb6d9
Show file tree
Hide file tree
Showing 21 changed files with 3,025 additions and 1 deletion.
Binary file added ExampleJsonOutput.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2,346 changes: 2,346 additions & 0 deletions PScriboExample.json

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ PScribo can export documentation in a variety of formats and currently supports

[Example text Document Download](https://raw.githubusercontent.com/iainbrighton/PScribo/dev/PScriboExample.txt)

### Example Json Output ###

![](./ExampleJsonOutput.png)

[Example Json Document Download](https://raw.githubusercontent.com/iainbrighton/PScribo/dev/PScriboExample.json)

If you find it useful, unearth any bugs or have any suggestions for improvements,
feel free to add an [issue](https://github.com/iainbrighton/PScribo/issues) or
place a comment at the project home page.
Expand Down
23 changes: 23 additions & 0 deletions Src/Plugins/Json/Get-JsonTableCaption.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
function Get-JsonTableCaption
{
<#
.SYNOPSIS
Generates caption from a PScribo.Table object.
#>
[CmdletBinding()]
[OutputType([System.String])]
param
(
[Parameter(Mandatory, ValueFromPipeline)]
[ValidateNotNull()]
[System.Management.Automation.PSObject] $Table
)
process
{
$tableStyle = Get-PScriboDocumentStyle -TableStyle $Table.Style

return [PSCustomObject] @{
Caption = ('{0} {1} {2}' -f $tableStyle.CaptionPrefix, $Table.CaptionNumber, $Table.Caption)
}
}
}
26 changes: 26 additions & 0 deletions Src/Plugins/Json/New-PScriboJsonOption.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
function New-PScriboJsonOption
{
<#
.SYNOPSIS
Sets the Json plugin specific formatting/output options.
.NOTES
All plugin options should be prefixed with the plugin name.
#>
[CmdletBinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions','')]
[OutputType([System.Collections.Hashtable])]
param
(
## Text encoding
[Parameter(ValueFromPipelineByPropertyName)]
[ValidateSet('ASCII','Unicode','UTF7','UTF8')]
[System.String] $Encoding = 'ASCII'
)
process
{
return @{
Encoding = $Encoding
}
}
}
123 changes: 123 additions & 0 deletions Src/Plugins/Json/Out-JsonDocument.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
function Out-JsonDocument
{
<#
.SYNOPSIS
Json output plugin for PScribo.
.DESCRIPTION
Outputs a Json file representation of a PScribo document object.
#>
[CmdletBinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments','pluginName')]
param
(
## ThePScribo document object to convert to a Json document
[Parameter(Mandatory, ValueFromPipeline)]
[System.Management.Automation.PSObject] $Document,

## Output directory path for the .json file
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
[ValidateNotNull()]
[System.String] $Path,

### Hashtable of all plugin supported options
[Parameter()]
[AllowNull()]
[System.Collections.Hashtable] $Options
)
process
{
$pluginName = 'Json'
$stopwatch = [Diagnostics.Stopwatch]::StartNew()
Write-PScriboMessage -Message ($localized.DocumentProcessingStarted -f $Document.Name)

## Merge the document, plugin default and specified/specific plugin options
$mergePScriboPluginOptionParams = @{
DefaultPluginOptions = New-PScriboJsonOption
DocumentOptions = $Document.Options
PluginOptions = $Options
}
$Options = Merge-PScriboPluginOption @mergePScriboPluginOptionParams
$script:currentPageNumber = 1

## Initializing JSON object
$jsonBuilder = [ordered]@{}

## Initializing paragraph counter
[int]$paragraph = 1

## Initializing table counter
[int]$table = 1

## Generating header
$header = Out-JsonHeaderFooter -Header -FirstPage
if ($null -ne $header) {
[ref] $null = $jsonBuilder.Add("header", $header)
[ref] $null = $header
}

foreach ($subSection in $Document.Sections.GetEnumerator())
{
# Write-Host "Type: $($subSection.Type)"
switch ($subSection.Type)
{
'PScribo.Section'
{
## Corrects behavior where NOTOC* heading is used
if (("" -eq $subSection.Number))
{
[ref] $null = $jsonBuilder.Add($subSection.Name, (Out-JsonSection -Section $subSection))
}
else
{
[ref] $null = $jsonBuilder.Add($subSection.Number, (Out-JsonSection -Section $subSection))
}
}
'PScribo.Paragraph'
{
[ref] $null = $jsonBuilder.Add("paragraph$($paragraph)", (Out-JsonParagraph -Paragraph $subSection))
$paragraph++
}
'PScribo.Table'
{
[ref] $null = $jsonBuilder.Add("table$($table)", (Out-JsonTable -Table $subSection))
$table++
}
'PScribo.TOC'
{
[ref] $null = $jsonBuilder.Add("toc", (Out-JsonTOC))
}
Default
{
Write-PScriboMessage -Message ($localized.PluginUnsupportedSection -f $subSection.Type) -IsWarning
}
}
}

## Generating footer
$footer = Out-JsonHeaderFooter -Footer
if ($null -ne $footer) {
[ref] $null = $jsonBuilder.Add("footer", $footer)
[ref] $null = $footer
}

$stopwatch.Stop()
Write-PScriboMessage -Message ($localized.DocumentProcessingCompleted -f $Document.Name)
$destinationPath = Join-Path -Path $Path ('{0}.json' -f $Document.Name)
Write-PScriboMessage -Message ($localized.SavingFile -f $destinationPath)
$jsonBuilder | ConvertTo-Json -Depth 100 | Set-Content -Path $destinationPath -Encoding $Options.Encoding
[ref] $null = $jsonBuilder

if ($stopwatch.Elapsed.TotalSeconds -gt 90)
{
Write-PScriboMessage -Message ($localized.TotalProcessingTimeMinutes -f $stopwatch.Elapsed.TotalMinutes)
}
else
{
Write-PScriboMessage -Message ($localized.TotalProcessingTimeSeconds -f $stopwatch.Elapsed.TotalSeconds)
}

## Return the file reference to the pipeline
Write-Output (Get-Item -Path $destinationPath)
}
}
63 changes: 63 additions & 0 deletions Src/Plugins/Json/Out-JsonHeaderFooter.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
function Out-JsonHeaderFooter
{
<#
.SYNOPSIS
Output formatted header/footer.
#>
[CmdletBinding()]
param
(
[Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'DefaultHeader')]
[Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'FirstPageHeader')]
[System.Management.Automation.SwitchParameter] $Header,

[Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'DefaultFooter')]
[Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'FirstPageFooter')]
[System.Management.Automation.SwitchParameter] $Footer,

[Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'FirstPageHeader')]
[Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'FirstPageFooter')]
[System.Management.Automation.SwitchParameter] $FirstPage
)
begin
{
## Initializing header/footer object
$hfBuilder = [ordered]@{}

## Initializing paragraph counter
[int]$paragraph = 1

## Initializing table counter
[int]$table = 1
}
process
{
$headerFooter = Get-PScriboHeaderFooter @PSBoundParameters
if ($null -ne $headerFooter)
{
foreach ($subSection in $headerFooter.Sections.GetEnumerator())
{
## When replacing tokens (by reference), the tokens are removed
$cloneSubSection = Copy-Object -InputObject $subSection
switch ($cloneSubSection.Type)
{
'PScribo.Paragraph'
{
[ref] $null = $hfBuilder.Add("paragraph$($paragraph)", (Out-JsonParagraph -Paragraph $cloneSubSection))
$paragraph++
}
'PScribo.Table'
{
[ref] $null = $hfBuilder.Add("table$($table)", (Out-JsonTable -Table $cloneSubSection))
$table++
}
}
}

return $hfBuilder
}
else {
return $null
}
}
}
37 changes: 37 additions & 0 deletions Src/Plugins/Json/Out-JsonParagraph.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
function Out-JsonParagraph
{
<#
.SYNOPSIS
Output formatted paragraph run.
#>
[CmdletBinding()]
[OutputType([System.String])]
param
(
[Parameter(Mandatory, ValueFromPipeline)]
[ValidateNotNull()]
[System.Management.Automation.PSObject] $Paragraph
)
begin
{
## Initializing string object
[System.Text.StringBuilder] $paragraphBuilder = New-Object -TypeName 'System.Text.StringBuilder'
}
process
{
foreach ($paragraphRun in $Paragraph.Sections)
{
$text = Resolve-PScriboToken -InputObject $paragraphRun.Text
[ref] $null = $paragraphBuilder.Append($text)

if (($paragraphRun.IsParagraphRunEnd -eq $false) -and
($paragraphRun.NoSpace -eq $false))
{
[ref] $null = $paragraphBuilder.Append(' ')
}
}


return $paragraphBuilder.ToString()
}
}
66 changes: 66 additions & 0 deletions Src/Plugins/Json/Out-JsonSection.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
function Out-JsonSection
{
<#
.SYNOPSIS
Output formatted Json section.
#>
[CmdletBinding()]
param
(
## Section to output
[Parameter(Mandatory, ValueFromPipeline)]
[System.Management.Automation.PSObject] $Section
)
begin
{
## Initializing section object
$sectionBuilder = [ordered]@{}

## Initializing paragraph counter
[int]$paragraph = 1

## Initializing table counter
[int]$table = 1
}
process
{
$sectionBuilder.Add("name", $Section.Name)

foreach ($subSection in $Section.Sections.GetEnumerator())
{
# Write-Host "Section Type: $($subSection.Type)"
switch ($subSection.Type)
{
'PScribo.Section'
{
## Corrects behavior where NOTOC* heading is used
if (("" -eq $subSection.Number))
{
[ref] $null = $sectionBuilder.Add($subSection.Name, (Out-JsonSection -Section $subSection))
}
else
{
[ref] $null = $sectionBuilder.Add($subSection.Number, (Out-JsonSection -Section $subSection))
}
}
'PScribo.Paragraph'
{
[ref] $null = $sectionBuilder.Add("paragraph$($paragraph)", (Out-JsonParagraph -Paragraph $subSection))
$paragraph++
}
'PScribo.Table'
{
[ref] $null = $sectionBuilder.Add("table$($table)", (Out-JsonTable -Table $subSection))
$table++
}
Default
{
Write-PScriboMessage -Message ($localized.PluginUnsupportedSection -f $subSection.Type) -IsWarning
}
}
}


return $sectionBuilder
}
}
19 changes: 19 additions & 0 deletions Src/Plugins/Json/Out-JsonTOC.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
function Out-JsonTOC {
<#
.SYNOPSIS
Output formatted Table of Contents
#>
begin {
## Initializing TOC object
$tocBuilder = [ordered]@{}
}
process {
## Populating TOC
## Disregarding section numbering as its highly beneficial when parsing JSON after the fact
foreach ($tocEntry in $Document.TOC) {
[ref] $null = $tocBuilder.Add($tocEntry.Number, $tocEntry.Name)
}

return ($tocBuilder)
}
}
Loading

0 comments on commit efeb6d9

Please sign in to comment.