Public/ConvertTo-String.ps1
function ConvertTo-String { <# .SYNOPSIS Converts a mermaid definition to string. .DESCRIPTION Generates mermaid syntax for definitions created with this module. .INPUTS Mermaid diagram definition object. .OUTPUTS String. .EXAMPLE PS C:\> $diagram = New-MermaidDiagram -ErDiagram PS C:\> $diagram | Add-MermaidErRelation Exactly-one Customer places Zero-or-more Order PS C:\> $diagram | Add-MermaidErRelation Exactly-one Order contains One-or-more LineItem PS C:\> $diagram | Add-MermaidErRelation One-or-more Customer uses One-or-more DeliveryAddress -NonIdentifying PS C:\> $diagram | ConvertTo-MermaidString erDiagram Customer ||--o{ Order : places Order ||--|{ LineItem : contains Customer }|..|{ DeliveryAddress : uses Create a erDiagram, add a few relations and convert it to a diagram string. #> [CmdletBinding()] param ( #region diagram # The diagram link type. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'erDiagram')] [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'flowchart')] [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'C4ComponentDiagram')] [string] $Type, # Title of the diagram. [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'erDiagram')] [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'flowchart')] [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartSubgraph')] [string] $Title, #endregion #region erDiagram # Collection of relations. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'erDiagram')] [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'C4ComponentDiagram')] [AllowEmptyCollection()] [PSCustomObject[]] $Relations, #endregion #region flowchart # Orientation of the flowchart. [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'flowchart')] [string] $Orientation, # Collection of nodes for a flowchart. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'flowchart')] [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartSubgraph')] [AllowEmptyCollection()] [PSCustomObject[]] $Nodes, # Collection of links for a flowchart. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'flowchart')] [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartSubgraph')] [AllowEmptyCollection()] [PSCustomObject[]] $Links, # Collection of classes for a flowchart. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'flowchart')] [AllowEmptyCollection()] [PSCustomObject[]] $Classes, # Collection of clicks for a flowchart. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'flowchart')] [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartSubgraph')] [AllowEmptyCollection()] [PSCustomObject[]] $Clicks, # Collection of subgraphs for a flowchart. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'flowchart')] [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartSubgraph')] [AllowEmptyCollection()] [PSCustomObject[]] $Subgraphs, #endregion #region C4ComponentDiagram # Collection of container boundaries for a C4Component diagram. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'C4ComponentDiagram')] [AllowEmptyCollection()] [PSCustomObject[]] $ContainerBoundaries, # Collection of components for a C4Component diagram. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'C4ContainerBoundary')] [AllowEmptyCollection()] [PSCustomObject[]] $Components, #endregion #region C4Relation # [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'C4Relation')] [string] $From, # [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'C4Relation')] [string] $To, #endregion #region C4Component # The component technology / implementation. [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'C4Component')] [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'C4Relation')] [string] $Technology, # Describes the component. [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'C4Component')] [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'C4Relation')] [string] $Description, #endregion #region erRelation # First entity of the relation. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'erRelation')] [string] $FirstEntity, # Relationship of the relation. [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'erRelation')] [PSCustomObject] $Relationship, # First second of the relation. [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'erRelation')] [string] $SecondEntity, # Describes the relation. [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'erRelation')] [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'C4Relation')] [string] $Label, #endregion #region flowchartLink [Parameter(ParameterSetName = 'flowchartLink')] [switch] $FromFlowchartLink, # Source node of the link. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartLink')] [string] $SourceNode, # Source node of the link. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartLink')] [string] $SourceHead, # Destination node of the link. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartLink')] [string] $DestinationNode, # Destination node of the link. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartLink')] [string] $DestinationHead, # Link text. [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartLink')] [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartNode')] [string] $Text, [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartLink')] [string] $Line, #endregion #region flowchartNode [Parameter(ParameterSetName = 'flowchartNode')] [switch] $FromFlowchartNode, # Identifier of the node/container/component. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartNode')] [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartSubgraph')] [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'C4ContainerBoundary')] [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'C4Component')] [string] $Key, # Shape of the node. [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartNode')] [string] $Shape, # Class of the node. [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartNode')] [string] $Class, #endregion #region flowchartClass [Parameter(ParameterSetName = 'flowchartClass')] [switch] $FromFlowchartClass, # Name of the class/container. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartClass')] [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'C4ContainerBoundary')] [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'C4Component')] [string] $Name, # Style of the class. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartClass')] [string] $Style, #endregion #region flowchartClick [Parameter(ParameterSetName = 'flowchartClick')] [switch] $FromFlowchartClick, # Node of the click. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartClick')] [string] $Node, # Url of the click. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartClick')] [string] $Url, # Url of the click. [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartClick')] [string] $Tooltip, # Target of the click. [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'flowchartClick')] [string] $Target, #endregion #region flowchartSubgraph [Parameter(ParameterSetName = 'flowchartSubgraph')] [switch] $FromFlowchartSubgraph, #endregion #region erRelationship # Cardinality of the first entity. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'erRelationship')] [string] $FirstCardinality, # Cardinality of the second entity. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'erRelationship')] [string] $SecondCardinality, # Flags if one entity may exist without the other. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'erRelationship')] [bool] $Identifying #endregion ) process { @( switch ($PSCmdlet.ParameterSetName) { erDiagram { if ( $Title ) { '---' | Write-Output "title: $Title" | Write-Output '---' | Write-Output } $Type | Write-Output $Relations | ConvertTo-String | Write-Output } flowchart { if ( $Title ) { '---' | Write-Output "title: $Title" | Write-Output '---' | Write-Output } switch ( $Orientation ) { top-to-bottom { "$Type TB" | Write-Output } top-down { "$Type TD" | Write-Output } bottom-to-top { "$Type BT" | Write-Output } right-to-left { "$Type RL" | Write-Output } left-to-right { "$Type LR" | Write-Output } default { $Type | Write-Output } } $( $Classes | ConvertTo-String -FromFlowchartClass | Write-Output $Nodes | ConvertTo-String -FromFlowchartNode | Write-Output $Clicks | ConvertTo-String -FromFlowchartClick | Write-Output $Links | ConvertTo-String -FromFlowchartLink | Write-Output ( $Subgraphs | ConvertTo-String -FromFlowchartSubgraph ) -split [Environment]::NewLine | Write-Output ) | ForEach-Object { " $_" | Write-Output } } C4ComponentDiagram { $Type | Write-Output $ContainerBoundaries | ConvertTo-String | Write-Output $Relations | ConvertTo-String | Write-Output } erRelation { $( if ( $SecondEntity ) { Write-Output "$FirstEntity $( $Relationship | ConvertTo-String ) $SecondEntity$( if ( $Label ) {" : $Label" })" } else { Write-Output "$FirstEntity" } ) | ForEach-Object { " $_" | Write-Output } } flowchartLink { Write-Output "$SourceNode $( switch ( $Line ) { solid { "$( switch ( $SourceHead ) { open { '-' } arrow { '<' } circle { 'o' } cross { 'x' } Default { Write-Error "convert $_ is not supported." } } )$( if ( $SourceHead -ne 'open' ) { '-'} )-$( switch ( $DestinationHead ) { open { '-' } arrow { '>' } circle { 'o' } cross { 'x' } Default { Write-Error "convert $_ is not supported." } } )" } dotted { "$( switch ( $SourceHead ) { open { '' } arrow { '>' } circle { 'o' } cross { 'x' } Default { Write-Error "convert $_ is not supported." } } )-.-$( switch ( $DestinationHead ) { open { '' } arrow { '>' } circle { 'o' } cross { 'x' } Default { Write-Error "convert $_ is not supported." } } )" } thick { "$( switch ( $SourceHead ) { open { '=' } arrow { '<' } circle { 'o' } cross { 'x' } Default { Write-Error "convert $_ is not supported." } } )=$( if ( $SourceHead -ne 'open' ) { '=' } )$( switch ( $DestinationHead ) { open { '=' } arrow { '>' } circle { 'o' } cross { 'x' } Default { Write-Error "convert $_ is not supported." } } )" } Default { Write-Error "convert $_ is not supported." } } )$( if ( $Text ) { "|$Text|" } ) $DestinationNode" } flowchartNode { Write-Output "$Key$( switch ( $Shape ) { '' { "$( $Text ? "[$Text]" : '' )" } rectangle { "[$( $Text ? $Text : $Key )]" } round-edges { "($( $Text ? $Text : $Key ))" } stadium { "([$( $Text ? $Text : $Key )])" } subroutine { "[[$( $Text ? $Text : $Key )]]" } cylindrical { "[($( $Text ? $Text : $Key ))]" } circle { "(($( $Text ? $Text : $Key )))" } asymmetric { ">$( $Text ? $Text : $Key )]" } rhombus { "{$( $Text ? $Text : $Key )}" } hexagon { "{{$( $Text ? $Text : $Key )}}" } parallelogram { "[/$( $Text ? $Text : $Key )/]" } parallelogram-alt { "[\$( $Text ? $Text : $Key )\]" } trapezoid { "[/$( $Text ? $Text : $Key )\]" } trapezoid-alt { "[\$( $Text ? $Text : $Key )/]" } double-circle { "((($( $Text ? $Text : $Key ))))" } Default { Write-Error "'$_' is not supported for Node Shape." } } )$( $Class ? ":::$Class" : '' )" } flowchartClass { Write-Output "classDef $Name $Style" } flowchartClick { Write-Output "click $Node ""$Url""$( if ( $Tooltip ) { ' "' + $Tooltip + '"' } )$( if ( $Target ) { " _$Target" } )" } flowchartSubgraph { Write-Output "subgraph $Key$( $Title ? " [$Title]" : '' )" $( $Nodes | ConvertTo-String -FromFlowchartNode | Write-Output $Clicks | ConvertTo-String -FromFlowchartClick | Write-Output $Links | ConvertTo-String -FromFlowchartLink | Write-Output ( $Subgraphs | ConvertTo-String -FromFlowchartSubgraph ) -split [Environment]::NewLine | Write-Output ) | ForEach-Object { " $_" | Write-Output } Write-Output "end" } C4ContainerBoundary { Write-Output "Container_Boundary($Key, ""$Name"") {" $Components | ForEach-Object { Write-Output " $( $_ | ConvertTo-String )" } Write-Output '}' } C4Component { Write-Output "Component($Key, ""$Name""$( if ( $Technology ) { ', "' + $Technology + '"' } )$( if ( $Description ) { ', "' + $Description + '"' } ))" } C4Relation { Write-Output "Rel($From, $To, ""$Label""$( if ( $Technology ) { ', "' + $Technology + '"' } )$( if ( $Description ) { ', "' + $Description + '"' } ))" } erRelationship { $FirstCardinalityCode = switch ($FirstCardinality) { Zero-or-one { '|o' } Exactly-one { '||' } Zero-or-more { '{o' } One-or-more { '}|' } Default { Write-Error "'$_' is not supported for FirstCardinality." } } $SecondCardinalityCode = switch ($SecondCardinality) { Zero-or-one { 'o|' } Exactly-one { '||' } Zero-or-more { 'o{' } One-or-more { '|{' } Default { Write-Error "'$_' is not supported for SecondCardinality." } } $IdentifyingCode = if ( $Identifying ) { '--' } else { '..' } Write-Output "$FirstCardinalityCode$IdentifyingCode$SecondCardinalityCode" } Default { Write-Error "convert $_ is not supported." } } ) -join [Environment]::NewLine | Write-Output } } |