MarkX.types.ps1xml
|
<!-- Generated with EZOut 2.0.6: Install-Module EZOut or https://github.com/StartAutomating/EZOut --> <Types> <Type> <Name>MarkX</Name> <Members> <MemberSet> <Name>PSStandardMembers</Name> <Members> <PropertySet> <Name>DefaultDisplayPropertySet</Name> <ReferencedProperties> <Name>Markdown</Name> <Name>XML</Name> </ReferencedProperties> </PropertySet> </Members> </MemberSet> <AliasProperty> <Name>DB</Name> <ReferencedMemberName>DataSet</ReferencedMemberName> </AliasProperty> <AliasProperty> <Name>Heading</Name> <ReferencedMemberName>Headings</ReferencedMemberName> </AliasProperty> <AliasProperty> <Name>Link</Name> <ReferencedMemberName>Links</ReferencedMemberName> </AliasProperty> <AliasProperty> <Name>Tables</Name> <ReferencedMemberName>Table</ReferencedMemberName> </AliasProperty> <ScriptMethod> <Name>Sync</Name> <Script> $currentRows = @() $allMarkdown = @(:nextInput foreach ($md in $this.Input) { if ($md -isnot [string]) { # If the markdown was a file if ($md -is [IO.FileInfo] -and # and it had the extension .md or markdown $md.Extension -in '.md', '.markdown') { $md = Get-Content -LiteralPath $md.Fullname -Raw $md continue } if ($md -is [Management.Automation.CommandInfo]) { $cmdHelp = if ( $md -is [Management.Automation.FunctionInfo] -or $md -is [Management.Automation.AliasInfo] ) { Get-Help -Name $md.Name } elseif ($md -is [Management.Automation.ExternalScriptInfo]) { Get-Help -Name $md.Source } else { continue nextInput } if ($cmdHelp) { $md = $cmdHelp } } if ($md.pstypenames -match 'HelpInfo') { @( if ($md.Name -match '[\\/]') { "# $(@($md.Name -split '[\\/]')[-1] -replace '\.ps1')" } else { "# $($md.Name)" } if ($md.Synopsis) { "## $($md.Synopsis)" } $description = $md.Description.text -join [Environment]::NewLine if ($description) { "### $($description)" } $md.alertset.alert.text -join [Environment]::NewLine foreach ($example in $md.examples.example) { $exampleNumber++ # Combine the code and remarks $exampleLines = @( $example.Code foreach ($remark in $example.Remarks.text) { if (-not $remark) { continue } $remark } ) -join ([Environment]::NewLine) -split '(?>\r\n|\n)' # and split into lines # Anything until the first non-comment line is a markdown predicate to the example $nonCommentLine = $false $markdownLines = @() # Go thru each line in the example as part of a loop $codeBlock = @(foreach ($exampleLine in $exampleLines) { # Any comments until the first uncommentedLine are markdown if ($exampleLine -match '^\#' -and -not $nonCommentLine) { $markdownLines += $exampleLine -replace '^\#' -replace '^\s+' } else { $nonCommentLine = $true $exampleLine } }) -join [Environment]::NewLine # Join all of our markdown lines together $markdownLines -join [Environment]::NewLine "~~~PowerShell" $codeBlock "~~~" } ) -join [Environment]::NewLine continue nextInput } if ($md -is [ScriptBlock]) { "<pre><code class='language-powershell'>$( [Web.HttpUtility]::HtmlEncode( "$md" ) )</code><pre>" continue nextInput } if ($md -is [Collections.IDictionary] -or ($md.GetType -and (-not $md.GetType().IsPrimitive) ) ) { $currentRows += $md continue } } if ($currentRows) { $this.ToTable($currentRows) $currentRows = @() } if ($md -match '(?>\.md|markdown)$' -and (Test-Path $md -ErrorAction Ignore) ) { $md = Get-Content -Raw $md } $yamlheader = '' if ($md -match '^---') { $null, $yamlheader, $md = $in -split '---', 3 if ($yamlheader) { $this | Add-Member NoteProperty '#YamlHeader' $yamlheader -Force } } $md }) if ($currentRows) { $allMarkdown += $this.ToTable($currentRows) $currentRows = @() } $yamlHeaders = @() $allMarkdown = @(foreach ($md in $allMarkdown) { if ($md -match '^---') { $null, $yamlheader, $restOfMakdown = $md -split '---', 3 if ($yamlheader) { $yamlHeaders+= $yamlheader } $restOfMakdown } else { $md } }) if ($yamlHeaders) { $yamlHeader = $yamlHeaders -join ( [Environment]::NewLine + '---' + [Environment]::NewLine ) $this | Add-Member NoteProperty '#YamlHeader' $yamlHeader -Force } $markdown = $allMarkdown -join [Environment]::NewLine $this | Add-Member NoteProperty '#Markdown' $Markdown -Force $Markdown = $this.'#Markdown' if (-not $Markdown) { return } $this | Add-Member NoteProperty '#HTML' ( $Markdown | ConvertFrom-Markdown | Select-Object -ExpandProperty Html ) -Force $this | Add-Member NoteProperty '#XML' ( "<xhtml>$($this.'#HTML')</xhtml>" -as [xml] ) -Force if (-not $this.'#XML') { return } $tables = $this.'#XML' | Select-Xml //table filter innerText { $in = $_ if ($in -is [string]) { "$in" } elseif ($in.innerText) { "$($in.innerText)" } elseif ($in.'#text') { "$($in.'#text')" } } function bestType { $allIn = @($input) + @(if ($args) { $args}) switch ($true) { { $allIn -as [float[]] } { [float]; break } { $allIn -as [double[]] } { [double]; break } { $allIn -as [long[]] } { [long]; break } { $allIn -as [ulong[]] } { [uint32]; break } { $allIn -as [decimal[]] } { [decimal]; break } { $allIn -as [timespan[]] } { [timespan]; break } { $allIn -as [DateTime[]] } { [DateTime]; break } default { [string] } } } $markdownData = [Data.DataSet]::new('MarkX') $tableNumber = 0 foreach ($table in $tables) { $tableNumber++ $markdownDataTable = $markdownData.Tables.Add("MarkdownTable$tableNumber") [string[]]$PropertyNames = @( $table.Node.thead.tr.th | innerText ) # We want to upcast our datatable as much as possible # so we need to collect the rows first $TableDictionary = [Ordered]@{} $propertyIndex = 0 foreach ($property in $propertyNames) { $TableDictionary[$property] = @( foreach ($row in $table.Node.tbody.tr) { @($row.td)[$propertyIndex] | innerText } ) $propertyIndex++ } # Now that we have all of the data collected, $markdownDataTable.Columns.AddRange(@( foreach ($property in $propertyNames) { $propertyIndex = 0 $bestType = $TableDictionary[$property] | bestType [Data.DataColumn]::new($property, $bestType, '', 'Attribute') } [Data.DataColumn]::new('tr', [xml.xmlelement], '', 'Hidden') )) foreach ($row in $table.Node.tbody.tr) { $propertyValues = @( $row.td | innerText $row ) $null = $markdownDataTable.Rows.Add($propertyValues) } $previous = $table.Node.PreviousSibling if ($previous.LocalName -eq 'blockquote') { $markdownDataTable.ExtendedProperties.Add("description", $previous.InnerText) $previous = $previous.PreviousSibling } if ($previous.LocalName -match 'h[1-6]') { $markdownDataTable.TableName = $previous.InnerText } } $this | Add-Member NoteProperty '#DataSet' $markdownData -Force </Script> </ScriptMethod> <ScriptMethod> <Name>ToString</Name> <Script> if ($args) { $anyOutput = foreach ($arg in $args) { $thisArg = $this.$arg if ($thisArg) { if ($thisArg.XHTML.InnerXML) { "$($thisArg.XHTML.InnerXML)" + [Environment]::NewLine } else { "$thisArg" } } } if ($anyOutput) { return $anyOutput -join [Environment]::NewLine } } if (-not $this.XML.XHTML) { return '' } return ("$($this.XML.XHTML.InnerXML)" + [Environment]::NewLine) </Script> </ScriptMethod> <ScriptMethod> <Name>ToTable</Name> <Script> param( [PSObject[]] $Rows ) $allInput = @($input) $allRows = @($allInput) + $(if ($Rows) { $rows }) $MarkdownLines = @() $IsFirst = $true foreach ($in in $Rows) { $propertyList = @( # we first need to get a list of properties. if ($in -is [Collections.IDictionary]) { foreach ($k in $in.Keys) { # take all keys from the dictionary $k } } # Otherwise, walk over all properties on the object else { foreach ($psProp in $In.psobject.properties) { $psProp } } ) # If we're rendering the first row of a table if ($IsFirst) { # Create the header $markdownLines += '|' + (@(foreach ($prop in $propertyList) { if ($prop -is [string]) { $prop } else { $prop.Name } }) -replace ([Environment]::newline), '<br/>' -replace '\|', '\|' -join '|') + '|' # Then create the alignment row. $markdownLines += '|' + $( $columnNumber =0 @( foreach ($prop in $propertyList) { $colLength = if ($prop -is [string]) { $prop.Length } else { $prop.Name.Length } "-" * $colLength $columnNumber++ } ) -replace ([Environment]::newline), '<br/>' -replace '\|', '\|' -join '|') + '|' $IsFirst = $false } # Now we create the row for this object. $markdownLine = '|' + ( @( foreach ($prop in $propertyList) { if ($prop -is [string]) { $in.$prop } else { $prop.Value } } ) -replace ([Environment]::newline), '<br/>' -replace '\|', '\|' -join '|') + '|' $markdownLines += $markdownLine } $markdownLines </Script> </ScriptMethod> <ScriptProperty> <Name>Code</Name> <GetScriptBlock> <# .SYNOPSIS Gets code .DESCRIPTION Gets code within Markdown / MarkX, grouped by language. .EXAMPLE " # Hello World in PowerShell ~~~PowerShell 'Hello World' ~~~ " | markx | Select-Object -ExpandProperty Code #> $codeByLanguage = [Ordered]@{} foreach ($element in $this.XML | Select-Xml -XPath //code) { $language = 'unknown' if ($element.node.class -match 'language-(?<language>\S+)?') { $language = $matches.language } if (-not $codeByLanguage[$language]) { $codeByLanguage[$language] = @() } $codeByLanguage[$language] += $element.node.InnerText } return $codeByLanguage </GetScriptBlock> </ScriptProperty> <ScriptProperty> <Name>CodeBlock</Name> <GetScriptBlock> <# .SYNOPSIS Gets code blocks .DESCRIPTION Gets code blocks within Markdown / MarkX .EXAMPLE " # Hello World in PowerShell ~~~PowerShell 'Hello World' ~~~ " | markx | Select-Object -ExpandProperty CodeBlock #> $codeByLanguage = [Ordered]@{} foreach ($element in $this.XML | Select-Xml -XPath //code) { $language = 'unknown' if ($element.node.class -match 'language-(?<language>\S+)?') { $language = $matches.language } if (-not $codeByLanguage[$language]) { $codeByLanguage[$language] = @() } $codeByLanguage[$language] += $element.node } return $codeByLanguage </GetScriptBlock> </ScriptProperty> <ScriptProperty> <Name>DataSet</Name> <GetScriptBlock> return $this.'#DataSet' </GetScriptBlock> </ScriptProperty> <ScriptProperty> <Name>Header</Name> <GetScriptBlock> if (-not $this.'#YamlHeader') { return } $convertFromYaml = $ExecutionContext.SessionState.InvokeCommand.GetCommand('ConvertFrom-Yaml', 'Alias,Cmdlet,Function') if (-not $convertFromYaml) { Write-Warning "Cannot get header without ConvertFrom-Yaml" return } return ($this.'#YamlHeader' | & $convertFromYaml) </GetScriptBlock> <SetScriptBlock> param($header) $this.YamlHeader = $header </SetScriptBlock> </ScriptProperty> <ScriptProperty> <Name>Headings</Name> <GetScriptBlock> <# .SYNOPSIS Gets Markdown headings .DESCRIPTION Gets any heading elements in the markdown #> $this.XML | Select-Xml -XPath //* | Where-Object { $_.Node.LocalName -match 'h[1-6]' } | Select-Object -ExpandProperty Node </GetScriptBlock> </ScriptProperty> <ScriptProperty> <Name>HTML</Name> <GetScriptBlock> if (-not $this.XML.XHTML) { return '' } return ("$($this.XML.XHTML.InnerXML)" + [Environment]::NewLine) </GetScriptBlock> </ScriptProperty> <ScriptProperty> <Name>Images</Name> <GetScriptBlock> foreach ($aNode in $this.XML | Select-Xml //img) { if ($aNode.Node.src) { $aNode.Node } } </GetScriptBlock> </ScriptProperty> <ScriptProperty> <Name>InnerText</Name> <GetScriptBlock> $this.XML.XHTML.InnerText </GetScriptBlock> </ScriptProperty> <ScriptProperty> <Name>Input</Name> <GetScriptBlock> return $this.'#input' </GetScriptBlock> <SetScriptBlock> param( [PSObject[]]$InputObject ) $this | Add-Member NoteProperty '#Input' $InputObject -Force $this.Sync() </SetScriptBlock> </ScriptProperty> <ScriptProperty> <Name>Lexicon</Name> <GetScriptBlock> <# .SYNOPSIS Gets Lexicons from Markdown .DESCRIPTION Gets At Protocol Lexicons defined in Markdown. A lexicon table must have at least three columns: * Property * Type * Description It must also contain a row containing the property `$type`. This will be considered the lexicon's type. Any bolded or italic fields will be considered required. Lexicon tables may also be preceeded by an element containing the description. #> $markdownData = $this.DataSet :nextTable foreach ($table in $markdownData.Tables) { $isLexiconTable = $table.Columns['Property'] -and $table.Columns['Type'] -and $table.Columns['Description'] if (-not $isLexiconTable) { continue nextTable } $hasType = $table.Select("Property='`$type'") if (-not $hasType) { Write-Warning "Missing `$type" continue nextTable } $lexiconType = if ($hasType.Description -match '(?:[^\.\s]+\.){3}[^\.\s]+') { $matches.0 } if (-not $lexiconType) { continue nextTable } $lexiconObject = [Ordered]@{ lexicon = 1 id = $lexiconType defs = @{ main = [Ordered]@{ type = 'record' description = if ($table.ExtendedProperties.Description) { $table.ExtendedProperties.Description } else { $lexiconType } required = @() properties = [Ordered]@{} } } } foreach ($row in $table) { if ($row.Property -eq '$type') { continue } $lexProp = [Ordered]@{} $lexProp.type = switch -regex ($row.type) { '\[\]' { 'array' } 'object' { 'object' } 'string' { 'string' } 'bool|switch' { 'boolean' } 'int|number|float|double' { 'number' } 'date' { 'datetime' } 'ur[il]' { 'uri'} } $lexProp.description = $row.Description if ($row.Property -match '\*') { $lexiconObject.defs.main.required += $row.Property -replace '\*' } elseif ($row.tr.td.outerxml -match '<(?>b|i|strong)>') { $lexiconObject.defs.main.required += $row.Property -replace '\*' } $lexiconObject.defs.main.properties[$row.Property -replace '\*'] = $lexProp } $lexiconObject } </GetScriptBlock> </ScriptProperty> <ScriptProperty> <Name>Links</Name> <GetScriptBlock> foreach ($aNode in $this.XML | Select-Xml //a) { if ($aNode.Node.href) { $aNode.Node } } </GetScriptBlock> </ScriptProperty> <ScriptProperty> <Name>Markdown</Name> <GetScriptBlock> return $this.'#Markdown' </GetScriptBlock> <SetScriptBlock> param( [PSObject[]]$Markdown ) $this.Input = $Markdown </SetScriptBlock> </ScriptProperty> <ScriptProperty> <Name>Table</Name> <GetScriptBlock> $this.XML | Select-Xml -XPath '//table' | Select-Object -ExpandProperty Node </GetScriptBlock> </ScriptProperty> <ScriptProperty> <Name>XML</Name> <GetScriptBlock> return $this.'#XMl' </GetScriptBlock> </ScriptProperty> <ScriptProperty> <Name>YamlHeader</Name> <GetScriptBlock> return $this.'#YamlHeader' </GetScriptBlock> <SetScriptBlock> param($header) if ($header -is [string]) { $this | Add-Member NoteProperty '#YamlHeader' $header -Force return } $convertToYaml = $ExecutionContext.SessionState.InvokeCommand.GetCommand('ConvertTo-Yaml', 'Alias,Cmdlet,Function') if (-not $convertToYaml) { Write-Warning "Cannot set yaml header without converter" return } $convertParameters = @{} if ($convertToYaml.Parameters['Depth']) { $convertParameters['Depth'] = $FormatEnumerationLimit } $toYaml = $header | & $convertToYaml @convertParameters if ($toYaml -is [string]) { $this | Add-Member NoteProperty '#YamlHeader' $toYaml -Force } </SetScriptBlock> </ScriptProperty> <NoteProperty> <Name>DefaultDisplay</Name> <Value>Markdown XML</Value> </NoteProperty> </Members> </Type> </Types> |