MetaNullWiki.psm1
#Requires -Module ConfluencePS #Requires -Module MetaNullUtils # Module Constants Set-Variable CWikiNamespaces -option Constant -value @('ac','ri') Function Clear-Placeholder { <# .Synopsis Remove any Wiki placeholders (template values, that are not displayed in view mode) from a piece of html .PARAMETER InputHtml The HTML input .EXAMPLE $Body | Select-Placeholder #> [CmdletBinding(SupportsShouldProcess=$false)] [OutputType([string])] param ( [Parameter(Position=0, ValueFromPipeline)] [AllowEmptyString()] [Alias('Html','String')] [string]$InputHtml ) Process { $InputHtml -replace '<(ac:placeholder\b).*?>.*?</\1>' | Write-Output } } Function ConvertFrom-Artifact { <# .SYNOPSIS Convert a WikiArtifact object into the best matching type of artifact .Description Convert a WikiArtifact object into the best matching type of artifact. The function checks the presence of specific Page Properties OR specific Labels .PARAMETER InputArtifact The input object. #> [CmdletBinding()] [OutputType( [WikiArtifact], [WikiDomain], [WikiProduct], [WikiContainer], [WikiTechnology], [WikiKeyDataEntity] ) ] param ( [Parameter(ValueFromPipeline, Position=0)] [AllowEmptyString()] [Alias('Artifact','Product','Container','Technology','KeyDataEntity','Object')] [WikiArtifact]$InputArtifact ) Process { if($InputArtifact.Properties.Id -contains 'info' -or $InputArtifact.Labels -contains 'product') { [WikiProduct]::new($InputArtifact) | Write-Output } elseif($InputArtifact.Properties.Id -contains 'container' -or $InputArtifact.Labels -contains 'container') { [WikiContainer]::new($InputArtifact) | Write-Output } elseif($InputArtifact.Properties.Id -contains 'technology' -or $InputArtifact.Labels -contains 'technology') { [WikiTechnology]::new($InputArtifact) | Write-Output } elseif($InputArtifact.Properties.Id -contains 'domain' -or $InputArtifact.Labels -contains 'domain') { [WikiDomain]::new($InputArtifact) | Write-Output } elseif($InputArtifact.Properties.Id -contains [string]::Empty -or $InputArtifact.Labels -contains 'key-data-entity') { [WikiKeyDataEntity]::new($InputArtifact) | Write-Output } elseif($InputArtifact.Properties.Length -gt 0) { $InputArtifact | Write-Output } else { # Nothing to return, Input Object was probably not a valid artifact } } } Function ConvertTo-XDocument { <# .SYNOPSIS Convert a piece of html into a XDocument .Description Convert a piece of (well formed) html into a XDocument .PARAMETER InputString The input string. It must contain a valid piece of XHTML #> [CmdletBinding()] [OutputType([System.Xml.Linq.XDocument])] param ( [Parameter(ValueFromPipeline, Position=0)] [AllowEmptyString()] [Alias('String','Html')] [String]$InputString ) Process { &([MetaNullWiki]::Utils('ConvertTo-XDocument')) -InputString $InputString -Namespaces $CWikiNamespaces | Write-Output } } Function Select-HyperLink { <# .Synopsis Select the title and uri of html hyperlinks .PARAMETER InputHtml The HTML input .EXAMPLE # Get all hyperlinks in a html page $Body | Select-Hyperlink #> [CmdletBinding()] [OutputType([string[]])] param ( [Parameter(Position=0, ValueFromPipeline)] [AllowEmptyString()] [Alias('Html','String')] [string]$InputHtml ) Process { $InputHtml | ConvertTo-XDocument | Select-Xpath -XPath '//a[@href]' | Foreach-Object { $Href = $_ | Select-XPath -XPath './@href' | Select-Object -ExpandProperty Node | Select-Object -ExpandProperty Value $Node = $_ | Select-XPath -XPath '.' | Select-Object -ExpandProperty Node $Body = $Node | Select-Object -ExpandProperty InnerXml $Text = $Node | Select-Object -ExpandProperty InnerText [PSCustomObject]@{ Href = $Href Text = $Text Body = $Body } | Write-Output } } } Function Select-LinkCard { <# .Synopsis Select the "titles" of all wiki link cards in a blob of (html) text .PARAMETER InputHtml The HTML input .EXAMPLE # Get the titles from all link cards $Body | Select-LinkCard #> [CmdletBinding()] [OutputType([string[]])] param ( [Parameter(Position=0, ValueFromPipeline)] [AllowEmptyString()] [Alias('Html','String')] [string]$InputHtml ) Begin { $xpathSelectors = @( "//ac:link/ri:page/@ri:content-title" ) $xpathExpression = "($($xpathSelectors -join ' | '))" } Process { $InputHtml | ConvertTo-XDocument | Select-Xpath -XPath $xpathExpression | Select-Object -ExpandProperty Node | Select-Object -ExpandProperty Value | Write-Output } } Function Select-Macro { <# .Synopsis Select the content of all excerpt macros in a wiki page (html) .EXAMPLE # Get the body from all exerpt macros $Body | Select-Excerpt #> [CmdletBinding()] [OutputType([MetaNullWiki.Macro[]])] param ( [Parameter(Position=0, ValueFromPipeline)] [AllowEmptyString()] [Alias('Html','String')] [string]$InputHtml ) Process { $Macros = $InputHtml | ConvertTo-XDocument | Select-Xpath -XPath '//ac:structured-macro' $Macros | ForEach-Object { $Object = [MetaNullWiki.Macro]::new() $Macro = $_ $Object.Name = $Macro | Select-Xpath -XPath '@ac:name[position()=1]' | Select-Object -ExpandProperty Node | Select-Object -ExpandProperty Value $Object.Parameters = @{} $Macro | Select-Xpath -XPath 'ac:parameter' | Select-Object -ExpandProperty Node | Select-Object name,InnerText | Foreach-Object { $Object.Parameters.($_.name) = $_.InnerText } $Object.Body = $Macro | Select-Xpath -XPath 'ac:rich-text-body' | Select-Object -ExpandProperty Node | Select-Object -ExpandProperty InnerXml $Object.Attributes = @{} $Macro | Select-Xpath -XPath '@*' | Select-Object -ExpandProperty Node | Select-Object Name,Value | Foreach-Object { $Object.Attributes.($_.Name) = $_.Value } $Object | Write-Output } } } Function Select-Placeholder { <# .Synopsis Select the content of all Wiki placeholders (template values, that are not displayed in view mode) .PARAMETER InputHtml The HTML input .EXAMPLE $Body | Select-Placeholder #> [CmdletBinding()] [OutputType([string[]])] param ( [Parameter(Position=0, ValueFromPipeline)] [AllowEmptyString()] [Alias('Html','String')] [string]$InputHtml ) Begin { $xpathExpression = "//ac:placeholder" } Process { $InputHtml | ConvertTo-XDocument | Select-Xpath -XPath $xpathExpression | Select-Object -ExpandProperty Node | Select-Object -ExpandProperty InnerXml | Write-Output } } Function Select-Text { <# .Synopsis Select the content of all text nodes in a blob of (html) text .PARAMETER InputHtml The HTML input .EXAMPLE # Extract the piexes of text from (x|ht)ml '<strong>Meta<u>Null</u></strong><p>was here</p>' | Select-Text #> [CmdletBinding()] [OutputType([string[]])] param ( [Parameter(Position=0, ValueFromPipeline)] [AllowEmptyString()] [Alias('Html','String')] [string]$InputHtml ) Begin { $xpathSelectors = @( "/xml//*[local-name()=name()]" "//ac:link/ac:link-body" "//ac:structured-macro[@ac:name='status']/ac:parameter[@ac:name='title']" ) $xpathExpression = "($($xpathSelectors -join ' | '))/text()[normalize-space()]" } Process { if($InputHtml -notmatch '[<>]') { $InputHtml | Write-Output } else { $InputHtml | ConvertTo-XDocument | Select-Xpath -XPath $xpathExpression | Select-Object -ExpandProperty Node | Select-Object -ExpandProperty InnerText | Write-Output } } } Function Select-VersionLinkCard { <# .Synopsis Select "Versions", representred by a wiki link card and a free text version number in (html) text .PARAMETER InputHtml The HTML input .EXAMPLE # Get the titles from all link cards $Body | Select-VersionLinkCard #> [CmdletBinding()] [OutputType([WikiVersionLink[]])] param ( [Parameter(Mandatory, Position=0, ValueFromPipeline)] [AllowEmptyString()] [Alias('Html','String')] [string]$InputHtml ) Process { [WikiVersionLink]::CreateFromHtml($InputHtml) } } Function Select-Xpath { <# .SYNOPSIS Use XPath on a blob of (xhtml) text .Description Use XPath on a blob of (xhtml) text. .PARAMETER InputDocument The input XML onwhich to run xpath .PARAMETER Xpath The xpath query string .PARAMETER Namespaces A list of additional NS to declare .EXAMPLE # Get URL from all hyperlinks in a page $Html | ConvertTo-XDocument | Select-Xpath -XPath '//a/@href/text()' #> [CmdletBinding(DefaultParameterSetName)] [OutputType([object[]])] param ( [Parameter(Mandatory, Position=0)] [string]$XPath, [Parameter(ValueFromPipeline,Mandatory,Position=1)] [Alias('Document','Xml','Node')] [object]$InputDocument ) Process { $InputDocument | &([MetaNullWiki]::Utils('Select-XPath')) -Namespaces $CWikiNamespaces -XPath $Xpath | Write-Output } } |