CommunityADF.psm1
|
#Requires -Version 5.1 # MARK: ## BASE CLASSES ## enum ADFAttributeAction { Error Allow Skip } # MARK: ADFAttributeInfo Class # Utility class to define allowed attributes on ADF nodes, class ADFAttributeInfo { [string] $Name [Type] $Type = [object] [Type] $ReturnType = [object] [scriptblock] $Transform [bool] $Required = $false ADFAttributeInfo() {} ADFAttributeInfo( [string] $Name ) { $this.Name = $Name } ADFAttributeInfo( [string] $Name, [bool] $Required ) { $this.Name = $Name $this.Required = $Required } ADFAttributeInfo( [string] $Name, [Type] $Type ) { $this.Name = $Name $this.Type = $Type $this.ReturnType = $Type } ADFAttributeInfo( [string] $Name, [Type] $Type, [bool] $Required ) { $this.Name = $Name $this.Type = $Type $this.ReturnType = $Type $this.Required = $Required } ADFAttributeInfo( [string] $Name, [Type] $Type, [Type] $ReturnType ) { $this.Name = $Name $this.Type = $Type $this.ReturnType = $ReturnType } ADFAttributeInfo( [string] $Name, [Type] $Type, [Type] $ReturnType, [bool] $Required ) { $this.Name = $Name $this.Type = $Type $this.ReturnType = $ReturnType $this.Required = $Required } ADFAttributeInfo( [string] $Name, [Type] $Type, [Type] $ReturnType, [scriptblock] $Transform ) { $this.Name = $Name $this.Type = $Type $this.ReturnType = $ReturnType $this.Transform = $Transform } ADFAttributeInfo( [string] $Name, [Type] $Type, [Type] $ReturnType, [scriptblock] $Transform, [bool] $Required ) { $this.Name = $Name $this.Type = $Type $this.ReturnType = $ReturnType $this.Transform = $Transform $this.Required = $Required } [void] SetValue( [hashtable] $Hashtable, [object] $Value ) { Write-Debug ( 'Setting attribute "{0}" to value: {1}' -f $this.Name, ( $Value | Out-String ) ) # check for null or empty value # if it's required we throw, if not we just skip if ( [string]::IsNullOrEmpty($Value) ) { if ( $this.Required ) { $ExceptionMessage = 'Attribute "{0}" is required but no value was provided.' -f $this.Name throw [System.ArgumentNullException]::new( $this.Name, $ExceptionMessage ) } return } # check for expectd type and throw an error if not if ( $Value -isnot $this.Type ) { $ExceptionMessage = 'Attribute "{0}" expects a value of type "{1}", but got a value of type "{2}".' -f $this.Name, $this.Type.FullName, $Value.GetType().FullName throw [System.ArgumentException]::new( $ExceptionMessage, $this.Name ) } # if a transform scriptblock is defined, use it to transform the value before setting it if ( $this.Transform -is [scriptblock] ) { Write-Debug ( 'Transforming value for attribute "{0}" using the defined transform scriptblock.' -f $this.Name ) $Value = $Value | ForEach-Object $this.Transform } # finally set the value in the hashtable, casting to the return type $Hashtable[$this.Name] = $Value -as $this.ReturnType } } # MARK: ADFMark Class # Base class for ADF node markers, which are used to annotate AST nodes with ADF-specific information. class ADFMark { ADFMark() { Write-Debug ( 'Creating mark of type "{0}".' -f $this.type ) } [void] AddAttribute( [string] $Name, [object] $Value ) { Write-Debug ( 'Adding attribute "{0}" to mark "{1}" with value: {2}' -f $Name, $this.type, ( $Value | Out-String ) ) # if the class doesn't define any allowwed attributes, then it shouldn't allow setting any attributes if ( -not $this::AllowedAttributes ) { $ExceptionMessage = 'Mark of type "{0}" does not allow any attributes, but attempted to set attribute "{1}".' -f $this.type, $Name throw [System.ArgumentException]::new( $ExceptionMessage, $Name ) } # check if the attribute is defined in the class's AllowedAttributes and get the corresponding ADFAttributeInfo object $AttributeInfo = $this::AllowedAttributes | Where-Object { $_.Name -eq $Name } # if no matching attribute is found, throw an error if ( -not $AttributeInfo ) { $ExceptionMessage = 'Mark of type "{0}" does not allow an attribute named "{1}".' -f $this.type, $Name throw [System.ArgumentException]::new( $ExceptionMessage, $Name ) } # use the ADFAttributeInfo object to set the value, which will perform type checking and transformation as needed $AttributeInfo.SetValue( $this.attrs, $Value ) } hidden static [string] GetTypeName( [ADFMark] $Mark ) { return $Mark.GetType().Name -replace '^ADF' -replace 'Mark$' | ForEach-Object { $_.Substring( 0, 1 ).ToLower() + $_.Substring( 1 ) } } } # MARK: ADFNode Class # base class for ADF nodes, which represent elements of the ADF structure and are annotated with ADFMarks. class ADFNode { ADFNode() { Write-Debug ( 'Creating node of type "{0}".' -f $this.type ) } [void] AddAttribute( [string] $Name, [object] $Value ) { Write-Debug ( 'Adding attribute "{0}" to mark "{1}" with value: {2}' -f $Name, $this.type, ( $Value | Out-String ) ) # if the class doesn't define any allowwed attributes, then it shouldn't allow setting any attributes if ( -not $this::AllowedAttributes ) { $ExceptionMessage = 'Node of type "{0}" does not allow any attributes, but attempted to set attribute "{1}".' -f $this.type, $Name throw [System.ArgumentException]::new( $ExceptionMessage, $Name ) } # check if the attribute is defined in the class's AllowedAttributes and get the corresponding ADFAttributeInfo object $AttributeInfo = $this::AllowedAttributes | Where-Object { $_.Name -eq $Name } # if no matching attribute is found, throw an error if ( -not $AttributeInfo ) { $ExceptionMessage = 'Node of type "{0}" does not allow an attribute named "{1}".' -f $this.type, $Name throw [System.ArgumentException]::new( $ExceptionMessage, $Name ) } # use the ADFAttributeInfo object to set the value, which will perform type checking and transformation as needed $AttributeInfo.SetValue( $this.attrs, $Value ) } [void] AddMark( [ADFMark] $Mark ) { Write-Debug ( 'Adding mark of type "{0}" to node of type "{1}".' -f $Mark.type, $this.type ) # if the class doesn't define any allowed marks, then it shouldn't allow adding any marks if ( -not $this::AllowedMarks ) { $ExceptionMessage = 'Node of type "{0}" does not allow any marks, but attempted to add mark of type "{1}".' -f $this.type, $Mark.type throw [System.ArgumentException]::new( $ExceptionMessage, 'Mark' ) } # check if the mark's type is in the class's AllowedMarks if ( -not ( $this::AllowedMarks -contains $Mark.type ) ) { $ExceptionMessage = 'Node of type "{0}" does not allow marks of type "{1}".' -f $this.type, $Mark.type throw [System.ArgumentException]::new( $ExceptionMessage, 'Mark' ) } # if validation passes, add the mark to the node's list of marks $this.marks.Add( $Mark ) } hidden static [string] GetTypeName( [ADFNode] $Node ) { return $Node.GetType().Name -replace '^ADF' | ForEach-Object { $_.Substring( 0, 1 ).ToLower() + $_.Substring( 1 ) } } [void] AddChild( [ADFNode] $ChildNode ) { Write-Debug ( 'Adding child node of type "{0}" to parent node of type "{1}".' -f $ChildNode.type, $this.type ) # if the class doesn't define any allowed child node types, then it shouldn't allow adding any child nodes if ( -not $this::AllowedChildren ) { $ExceptionMessage = 'Node of type "{0}" does not allow any child nodes, but attempted to add child node of type "{1}".' -f $this.type, $ChildNode.type throw [System.ArgumentException]::new( $ExceptionMessage, 'ChildNode' ) } # check if the child node's type is in the class's AllowedChildren if ( -not ( $this::AllowedChildren -contains $ChildNode.type ) ) { $ExceptionMessage = 'Node of type "{0}" does not allow child nodes of type "{1}".' -f $this.type, $ChildNode.type throw [System.ArgumentException]::new( $ExceptionMessage, 'ChildNode' ) } # if validation passes, add the child node to the parent node's list of child nodes $this.content.Add( $ChildNode ) } } # MARK: ## MARKS ## # MARK: Add-ADFMark Function function Add-ADFMark { [CmdletBinding( PositionalBinding = $false )] param( [Parameter( Mandatory = $true, ValueFromPipeline = $true )] [ADFNode] $Node, [Parameter( Mandatory = $true )] [ADFMark] $Mark, [switch] $PassThru ) process { try { $Node.AddMark( $Mark ) } catch { Write-Error $_ } if ( $PassThru ) { Write-Output $Node } } } # MARK: ADFAlignment Enum enum ADFAlignment { Center End } # MARK: ADFAlignmentMark Class # Represents an alignment mark in the ADF structure. This mark can be applied to Heading and Paragraph nodes to specify text alignment. class ADFAlignmentMark : ADFMark { [string] $type = 'alignment' [hashtable] $attrs = @{} hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'align', [ADFAlignment], [string], { $_.ToString().ToLower() }, $true ) # required ) ADFAlignmentMark( [ADFAlignment] $Align ) : base() { $this.AddAttribute( 'align', $Align ) } } # MARK: Get-ADFAlignmentMark Function function Get-ADFAlignmentMark { [CmdletBinding( PositionalBinding = $false )] param( [Parameter( Mandatory = $true )] [ADFAlignment] $Align ) [ADFAlignmentMark]::new( $Align ) } # MARK:ADFAnnotationType Enum enum ADFAnnotationType { InlineComment } # MARK: ADFAnnotationMark Class # Represents an annotation mark in the ADF structure. This mark can be applied to text elements to provide additional information or context, such as comments or notes. class ADFAnnotationMark : ADFMark { [string] $type = 'annotation' [hashtable] $attrs = @{} hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'id', [string], $true ) # required, unique identifier for the annotation [ADFAttributeInfo]::new( 'annotationType', [ADFAnnotationType], [string], { $_.ToString()[0].ToLower() + $_.ToString().Substring(1) }, $true ) # required, type of annotation (e.g., inlineComment) ) ADFAnnotationMark( [string] $Id, [ADFAnnotationType] $AnnotationType ) : base() { $this.AddAttribute( 'id', $Id ) $this.AddAttribute( 'annotationType', $AnnotationType ) } } # MARK: Get-ADFAnnotationMark Function function Get-ADFAnnotationMark { [CmdletBinding( PositionalBinding = $false )] param( [Parameter( Mandatory = $true )] [string] $Id, [ADFAnnotationType] $AnnotationType = [ADFAnnotationType]::InlineComment ) [ADFAnnotationMark]::new( $Id, $AnnotationType ) } # MARK: Add-ADFAnnotationMark Function function Add-ADFAnnotationMark { [CmdletBinding( PositionalBinding = $false )] [Alias( 'ADFAnnotation' )] param( [Parameter( Mandatory = $true, ValueFromPipeline = $true )] [ADFNode] $Node, [Parameter( Mandatory = $true )] [string] $Id, [ADFAnnotationType] $AnnotationType = [ADFAnnotationType]::InlineComment, [switch] $PassThru ) process { $Mark = Get-ADFAnnotationMark -Id $Id -AnnotationType $AnnotationType $Node | Add-ADFMark -Mark $Mark -PassThru:$PassThru } } # MARK: Add-ADFAlignmentMark Function function Add-ADFAlignmentMark { [CmdletBinding( PositionalBinding = $false )] [Alias( 'ADFAlignment' )] param( [Parameter( Mandatory = $true, ValueFromPipeline = $true )] [ADFNode] $Node, [Parameter( Mandatory = $true )] [ADFAlignment] $Align, [switch] $PassThru ) process { $Mark = Get-ADFAlignmentMark -Align $Align $Node | Add-ADFMark -Mark $Mark -PassThru:$PassThru } } # MARK: ADFBackgroundColorMark Class # Represents a background color mark in the ADF structure. This mark can be applied to text and media elements to specify a background color. class ADFBackgroundColorMark : ADFMark { [string] $type = 'backgroundColor' [hashtable] $attrs = @{} hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'color', [string], $true ) # required, background color value in hex format (e.g., #FFFFFF for white) ) ADFBackgroundColorMark( [string] $Color ) : base() { $this.AddAttribute( 'color', $Color ) } } # MARK: Get-ADFBackgroundColorMark Function function Get-ADFBackgroundColorMark { [CmdletBinding( PositionalBinding = $false )] param( [Parameter( Mandatory = $true )] [ValidateScript({ if ( $_ -notmatch '^#[0-9a-fA-F]{6}$' ) { throw [System.ArgumentException]::new( 'Color must be a valid hex color code in the format #RRGGBB.', 'Color' ) } $true })] [string] $Color ) [ADFBackgroundColorMark]::new( $Color ) } # MARK: Add-ADFBackgroundColorMark Function function Add-ADFBackgroundColorMark { [CmdletBinding( PositionalBinding = $false )] [Alias( 'ADFBackgroundColor' )] param( [Parameter( Mandatory = $true, ValueFromPipeline = $true )] [ADFNode] $Node, [Parameter( Mandatory = $true )] [ValidateScript({ if ( $_ -notmatch '^#[0-9a-fA-F]{6}$' ) { throw [System.ArgumentException]::new( 'Color must be a valid hex color code in the format #RRGGBB.', 'Color' ) } $true })] [string] $Color, [switch] $PassThru ) process { $Mark = Get-ADFBackgroundColorMark -Color $Color $Node | Add-ADFMark -Mark $Mark -PassThru:$PassThru } } # MARK: ADFBorderMark Class # Represents a border mark in the ADF structure. This mark can be applied to block-level elements to specify a border style. class ADFBorderMark : ADFMark { [string] $type = 'border' [hashtable] $attrs = @{} hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'size', [int], $true ) # required, border size in pixels [ADFAttributeInfo]::new( 'color', [string], $true ) # optional, border color in hex format (e.g., #000000 for black) ) ADFBorderMark( [int] $Size, [string] $Color ) : base() { $this.AddAttribute( 'size', $Size ) $this.AddAttribute( 'color', $Color ) } } # MARK: Get-ADFBorderMark Function function Get-ADFBorderMark { [CmdletBinding( PositionalBinding = $false )] param( [Parameter( Mandatory = $true )] [ValidateRange( 1, 3 )] [int] $Size, [Parameter( Mandatory = $false )] [ValidateScript({ if ( $_ -and $_ -notmatch '^#[0-9a-fA-F]{8}$|^#[0-9a-fA-F]{6}$' ) { throw [System.ArgumentException]::new( 'Color must be a valid hex color code in the format #RRGGBBAA or #RRGGBB.', 'Color' ) } $true })] [string] $Color ) [ADFBorderMark]::new( $Size, $Color ) } # MARK: Add-ADFBorderMark Function function Add-ADFBorderMark { [CmdletBinding( PositionalBinding = $false )] [Alias( 'ADFBorder' )] param( [Parameter( Mandatory = $true, ValueFromPipeline = $true )] [ADFNode] $Node, [Parameter( Mandatory = $true )] [ValidateRange( 1, 3 )] [int] $Size, [Parameter( Mandatory = $false )] [ValidateScript({ if ( $_ -and $_ -notmatch '^#[0-9a-fA-F]{8}$|^#[0-9a-fA-F]{6}$' ) { throw [System.ArgumentException]::new( 'Color must be a valid hex color code in the format #RRGGBBAA or #RRGGBB.', 'Color' ) } $true })] [string] $Color, [switch] $PassThru ) process { $Mark = Get-ADFBorderMark -Size $Size -Color $Color $Node | Add-ADFMark -Mark $Mark -PassThru:$PassThru } } # MARK: ADFCodeMark Class # Represents a code mark in the ADF structure. This mark can be applied to text elements to indicate that the text is code and should be rendered in a monospace font. class ADFCodeMark : ADFMark { [string] $type = 'code' ADFCodeMark() : base() {} } # MARK: Get-ADFCodeMark Function function Get-ADFCodeMark { [CmdletBinding( PositionalBinding = $false )] param() [ADFCodeMark]::new() } # MARK: Add-ADFCodeMark Function function Add-ADFCodeMark { [CmdletBinding( PositionalBinding = $false )] [Alias( 'ADFCode' )] param( [Parameter( Mandatory = $true, ValueFromPipeline = $true )] [ADFNode] $Node, [switch] $PassThru ) process { $Mark = Get-ADFCodeMark $Node | Add-ADFMark -Mark $Mark -PassThru:$PassThru } } # MARK: ADFEmMark Class # Represents an emphasis mark in the ADF structure. This mark can be applied to text elements to indicate that the text should be emphasized, typically rendered in italics. class ADFEmMark : ADFMark { [string] $type = 'em' ADFEmMark() : base() {} } # MARK: Get-ADFEmMark Function function Get-ADFEmMark { [CmdletBinding( PositionalBinding = $false )] [Alias( 'Get-ADFItalicMark' )] param() [ADFEmMark]::new() } # MARK: Add-ADFEmMark Function function Add-ADFEmMark { [CmdletBinding( PositionalBinding = $false )] [Alias( 'ADFEm', 'ADFItalic', 'Add-ADFItalicMark' )] param( [Parameter( Mandatory = $true, ValueFromPipeline = $true )] [ADFNode] $Node, [switch] $PassThru ) process { $Mark = Get-ADFEmMark $Node | Add-ADFMark -Mark $Mark -PassThru:$PassThru } } # MARK: ADFIndentationMark Class # Represents an indentation mark in the ADF structure. This mark can be applied to block-level elements to indicate that the element should be indented. class ADFIndentationMark : ADFMark { [string] $type = 'indentation' [hashtable] $attrs = @{} hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'level', [int], $true ) # required, indentation level (e.g., 1 for first level of indentation) ) ADFIndentationMark( [int] $Level ) : base() { $this.AddAttribute( 'level', $Level ) } } # MARK: Get-ADFIndentationMark Function function Get-ADFIndentationMark { [CmdletBinding( PositionalBinding = $false )] param( [Parameter( Mandatory = $true )] [ValidateRange( 1, 6 )] [int] $Level ) [ADFIndentationMark]::new( $Level ) } # MARK: Add-ADFIndentationMark Function function Add-ADFIndentationMark { [CmdletBinding( PositionalBinding = $false )] [Alias( 'ADFIndent' )] param( [Parameter( Mandatory = $true, ValueFromPipeline = $true )] [ADFNode] $Node, [Parameter( Mandatory = $true )] [ValidateRange( 1, 6 )] [int] $Level, [switch] $PassThru ) process { $Mark = Get-ADFIndentationMark -Level $Level $Node | Add-ADFMark -Mark $Mark -PassThru:$PassThru } } # MARK: ADFLinkMark Class # Represents a link mark in the ADF structure. This mark can be applied to text elements to indicate that the text is a hyperlink and should be rendered as such. class ADFLinkMark : ADFMark { [string] $type = 'link' [hashtable] $attrs = @{} hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'href', [uri], [string], $true ) # required, URL that the link points to [ADFAttributeInfo]::new( 'title', [string] ) # optional, title attribute for the link, typically displayed as a tooltip on hover [ADFAttributeInfo]::new( 'id', [string] ) # optional, unique identifier for the link, can be used for tracking or referencing the link within the document [ADFAttributeInfo]::new( 'collection', [string] ) # optional, collection or category that the link belongs to, can be used for organizing links within the document [ADFAttributeInfo]::new( 'occurrenceKey', [string] ) # optional, unique key for tracking occurrences of the link, useful for analytics or link management purposes ) ADFLinkMark( [uri] $Href, [string] $Title, [string] $Id, [string] $Collection, [string] $OccurrenceKey ) : base() { $this.AddAttribute( 'href', $Href ) $this.AddAttribute( 'title', $Title ) $this.AddAttribute( 'id', $Id ) $this.AddAttribute( 'collection', $Collection ) $this.AddAttribute( 'occurrenceKey', $OccurrenceKey ) } } # MARK: Get-ADFLinkMark Function function Get-ADFLinkMark { [CmdletBinding( PositionalBinding = $false )] param( [Parameter( Mandatory = $true )] [uri] $Href, [string] $Title, [string] $Id, [string] $Collection, [string] $OccurrenceKey ) [ADFLinkMark]::new( $Href, $Title, $Id, $Collection, $OccurrenceKey ) } # MARK: Add-ADFLinkMark Function function Add-ADFLinkMark { [CmdletBinding( PositionalBinding = $false )] [Alias( 'ADFLink' )] param( [Parameter( Mandatory = $true, ValueFromPipeline = $true )] [ADFNode] $Node, [Parameter( Mandatory = $true )] [uri] $Href, [string] $Title, [string] $Id, [string] $Collection, [string] $OccurrenceKey, [switch] $PassThru ) process { $Mark = Get-ADFLinkMark -Href $Href -Title $Title -Id $Id -Collection $Collection -OccurrenceKey $OccurrenceKey $Node | Add-ADFMark -Mark $Mark -PassThru:$PassThru } } # MARK: ADFStrikeMark Class # Represents a strike-through mark in the ADF structure. This mark can be applied to text elements to indicate that the text should be rendered with a line through it, typically used to indicate deleted or irrelevant text. class ADFStrikeMark : ADFMark { [string] $type = 'strike' ADFStrikeMark() : base() {} } # MARK: Get-ADFStrikeMark Function function Get-ADFStrikeMark { [CmdletBinding( PositionalBinding = $false )] param() [ADFStrikeMark]::new() } # MARK: Add-ADFStrikeMark Function function Add-ADFStrikeMark { [CmdletBinding( PositionalBinding = $false )] [Alias( 'ADFStrike' )] param( [Parameter( Mandatory = $true, ValueFromPipeline = $true )] [ADFNode] $Node, [switch] $PassThru ) process { $Mark = Get-ADFStrikeMark $Node | Add-ADFMark -Mark $Mark -PassThru:$PassThru } } # MARK: ADFStrongMark Class # Represents a strong emphasis mark in the ADF structure. This mark can be applied to text elements to indicate that the text should be strongly emphasized, typically rendered in bold. class ADFStrongMark : ADFMark { [string] $type = 'strong' ADFStrongMark() : base() {} } # MARK: Get-ADFStrongMark Function function Get-ADFStrongMark { [CmdletBinding( PositionalBinding = $false )] [Alias( 'Get-ADFBoldMark' )] param() [ADFStrongMark]::new() } # MARK: Add-ADFStrongMark Function function Add-ADFStrongMark { [CmdletBinding( PositionalBinding = $false )] [Alias( 'ADFStrong', 'ADFBold', 'Add-ADFBoldMark' )] param( [Parameter( Mandatory = $true, ValueFromPipeline = $true )] [ADFNode] $Node, [switch] $PassThru ) process { $Mark = Get-ADFStrongMark $Node | Add-ADFMark -Mark $Mark -PassThru:$PassThru } } # MARK: ADFSubsupMarkType Enum # Enum to represent the allowed types for subsup marks in the ADF structure. enum ADFSubsupMarkType { Subscript Superscript } # MARK: ADFSubSupMark Class # Represents a subscript or superscript mark in the ADF structure. This mark can be applied to text elements to indicate that the text should be rendered as subscript or superscript, depending on the specified type. class ADFSubsupMark : ADFMark { [string] $type = 'subsup' [hashtable] $attrs = @{} hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'type', [ADFSubsupMarkType], [string], { $_.ToString().Substring(0,3).ToLower() }, $true ) # required ) ADFSubsupMark( [ADFSubsupMarkType] $Type ) : base() { $this.AddAttribute( 'type', $Type ) } } # MARK: Get-ADFSubsupMark Function function Get-ADFSubsupMark { [CmdletBinding( PositionalBinding = $false )] param( [Parameter( Mandatory = $true )] [ADFSubsupMarkType] $Type ) [ADFSubsupMark]::new( $Type ) } # MARK: Add-ADFSubsupMark Function function Add-ADFSubsupMark { [CmdletBinding( PositionalBinding = $false )] [Alias( 'ADFSubSup' )] param( [Parameter( Mandatory = $true, ValueFromPipeline = $true )] [ADFNode] $Node, [Parameter( Mandatory = $true )] [ADFSubsupMarkType] $Type, [switch] $PassThru ) process { $Mark = Get-ADFSubsupMark -Type $Type $Node | Add-ADFMark -Mark $Mark -PassThru:$PassThru } } # MARK: ADFTextColorMark Class # Represents a text color mark in the ADF structure. This mark can be applied to text elements to specify a text color. class ADFTextColorMark : ADFMark { [string] $type = 'textColor' [hashtable] $attrs = @{} hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'color', [string], $true ) # required, text color value in hex format (e.g., #000000 for black) ) ADFTextColorMark( [string] $Color ) : base() { $this.AddAttribute( 'color', $Color ) } } # MARK: Get-ADFTextColorMark Function function Get-ADFTextColorMark { [CmdletBinding( PositionalBinding = $false )] param( [Parameter( Mandatory = $true )] [string] $Color ) [ADFTextColorMark]::new( $Color ) } # MARK: Add-ADFTextColorMark Function function Add-ADFTextColorMark { [CmdletBinding( PositionalBinding = $false )] [Alias( 'ADFTextColor' )] param( [Parameter( Mandatory = $true, ValueFromPipeline = $true )] [ADFNode] $Node, [Parameter( Mandatory = $true )] [string] $Color, [switch] $PassThru ) process { $Mark = Get-ADFTextColorMark -Color $Color $Node | Add-ADFMark -Mark $Mark -PassThru:$PassThru } } # MARK: ADFUnderlineMark Class # Represents an underline mark in the ADF structure. This mark can be applied to text elements to indicate that the text should be rendered with an underline. class ADFUnderlineMark : ADFMark { [string] $type = 'underline' ADFUnderlineMark() : base() {} } # MARK: Get-ADFUnderlineMark Function function Get-ADFUnderlineMark { [CmdletBinding( PositionalBinding = $false )] param() [ADFUnderlineMark]::new() } # MARK: Add-ADFUnderlineMark Function function Add-ADFUnderlineMark { [CmdletBinding( PositionalBinding = $false )] [Alias( 'ADFUnderline' )] param( [Parameter( Mandatory = $true, ValueFromPipeline = $true )] [ADFNode] $Node, [switch] $PassThru ) process { $Mark = Get-ADFUnderlineMark $Node | Add-ADFMark -Mark $Mark -PassThru:$PassThru } } # MARK: ## ROOT NODE ## # MARK: ADFDoc Class # Root node of the ADF structure, representing an entire ADF document. class ADFDoc : ADFNode { [string] $type = 'doc' [int] $version = 1 [System.Collections.Generic.List[ADFNode]] $content = @() hidden static [string[]] $AllowedChildren = @( 'blockquote', 'bulletList', 'codeBlock', 'expand', 'heading', 'mediaGroup', 'mediaSingle', 'orderedList', 'panel', 'paragraph', 'rule', 'table' ) ADFDoc( [int] $Version ) : base() { $this.version = $Version } } # MARK: ADFDoc Function function New-ADFDoc { <# .SYNOPSIS Creates an ADF document root node. .PARAMETER Content Scriptblock whose output ADFNode objects will be added as children of the document node. .PARAMETER Version The version of the ADF document. #> [CmdletBinding( PositionalBinding = $false )] [OutputType( [ADFDoc] )] [Alias( 'ADFDoc' )] param( [Parameter( Position = 0 )] [scriptblock] $Content, [string] $Version = '1' ) $Node = [ADFDoc]::new( $Version ) if ( $Content ) { & $Content | ForEach-Object { $Node.AddChild( $_ ) } } return $Node } # MARK: ## TOP LEVEL NODES ## # MARK: ADFBlockquote Class # Represents a blockquote element in the ADF structure. class ADFBlockquote : ADFNode { [string] $type = 'blockquote' [System.Collections.Generic.List[ADFNode]] $content = @() hidden static [string[]] $AllowedChildren = @( 'paragraph', 'bulletList', 'orderedList', 'codeBlock', 'mediaGroup', 'mediaSingle' ) ADFBlockquote() : base() {} } # MARK: ADFBlockquote Function function New-ADFBlockquote { <# .SYNOPSIS Creates an ADF blockquote node. .PARAMETER Content Scriptblock whose output ADFNode objects will be added as children of the blockquote node. #> [CmdletBinding( PositionalBinding = $false )] [OutputType( [ADFBlockquote] )] [Alias( 'ADFBlockquote' )] param( [Parameter( Position = 0 )] [scriptblock] $Content ) $Node = [ADFBlockquote]::new() if ( $Content ) { & $Content | ForEach-Object { $Node.AddChild( $_ ) } } return $Node } # MARK: ADFBulletList Class # Represents a bullet list element in the ADF structure. class ADFBulletList : ADFNode { [string] $type = 'bulletList' [System.Collections.Generic.List[ADFNode]] $content = @() hidden static [string[]] $AllowedChildren = @( 'listItem' ) ADFBulletList() : base() {} } # MARK: ADFBulletList Function function New-ADFBulletList { <# .SYNOPSIS Creates an ADF bullet list node. .PARAMETER Content Scriptblock whose output ADFNode objects will be added as children of the bullet list node. #> [CmdletBinding( PositionalBinding = $false )] [OutputType( [ADFBulletList] )] [Alias( 'ADFBulletList' )] param( [Parameter( Position = 0 )] [scriptblock] $Content ) $Node = [ADFBulletList]::new() if ( $Content ) { & $Content | ForEach-Object { $Node.AddChild( $_ ) } } return $Node } # MARK: ADFCodeBlockLanguage Enum # Enum to represent the allowed languages for code blocks in the ADF structure. # See: https://github.com/react-syntax-highlighter/react-syntax-highlighter/blob/master/AVAILABLE_LANGUAGES_PRISM.MD enum ADFCodeBlockLanguage { abap abnf actionscript ada agda al antlr4 apacheconf apex apl applescript aql arduino arff armasm arturo asciidoc asm6502 asmatmel aspnet autohotkey autoit avisynth avroIdl # (avro-idl) awk bash basic batch bbcode bbj bicep birb bison bnf bqn brainfuck brightscript bro bsl c cfscript chaiscript cil cilkc cilkcpp clike clojure cmake cobol coffeescript concurnas cooklang coq cpp crystal csharp cshtml csp cssExtras # (css-extras) css csv cue cypher d dart dataweave dax dhall diff django dnsZoneFile # (dns-zone-file) docker dot ebnf editorconfig eiffel ejs elixir elm erb erlang etlua excelFormula # (excel-formula) factor falselang # (false) firestoreSecurityRules # (firestore-security-rules) flow fortran fsharp ftl gap gcode gdscript gedcom gettext gherkin git glsl gml gn goModule # (go-module) go gradle graphql groovy haml handlebars haskell haxe hcl hlsl hoon hpkp hsts http ichigojam icon icuMessageFormat # (icu-message-format) idris iecst ignore inform7 ini io j java javadoc javadoclike javascript javastacktrace jexl jolie jq jsExtras # (js-extras) jsTemplates # (js-templates) jsdoc json json5 jsonp jsstacktrace jsx julia keepalived keyman kotlin kumir kusto latex latte less lilypond linkerScript # (linker-script) liquid lisp livescript llvm log lolcode lua magma makefile markdown markupTemplating # (markup-templating) markup mata matlab maxscript mel mermaid metafont mizar mongodb monkey moonscript n1ql n4js nand2tetrisHdl # (nand2tetris-hdl) naniscript nasm neon nevod nginx nim nix none nsis objectivec ocaml odin opencl openqasm oz parigp parser pascal pascaligo pcaxis peoplecode perl phpExtras # (php-extras) php phpdoc plantUml # (plant-uml) plsql powerquery powershell processing prolog promql properties protobuf psl pug puppet pure purebasic purescript python q qml qore qsharp r racket reason regex rego renpy rescript rest rip roboconf robotframework ruby rust sas sass scala scheme scss shellSession # (shell-session) smali smalltalk smarty sml solidity solutionFile # (solution-file) soy sparql splunkSpl # (splunk-spl) sqf sql squirrel stan stata stylus supercollider swift systemd t4Cs # (t4-cs) t4Templating # (t4-templating) t4Vb # (t4-vb) tap tcl text textile toml tremor tsx tt2 turtle twig typescript typoscript unrealscript uorazor uri v vala vbnet velocity verilog vhdl vim visualBasic # (visual-basic) warpscript wasm webIdl # (web-idl) wgsl wiki wolfram wren xeora xmlDoc # (xml-doc) xojo xquery yaml yang zig } # MARK: ADFCodeBlock Class # Represents a code block element in the ADF structure. class ADFCodeBlock : ADFNode { [string] $type = 'codeBlock' [hashtable] $attrs = @{} [System.Collections.Generic.List[ADFNode]] $content = @() hidden static [string[]] $AllowedChildren = @( 'text' ) hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'language', [ADFCodeBlockLanguage], [string] ) ) ADFCodeBlock( [ADFCodeBlockLanguage] $Language ) : base() { $this.AddAttribute( 'language', $Language ) } } # MARK: ADFCodeBlock Function function New-ADFCodeBlock { <# .SYNOPSIS Creates an ADF code block node. .PARAMETER Content Scriptblock whose output ADFNode objects will be added as children of the code block node. .PARAMETER Language The programming language of the code block content, used for syntax highlighting. #> [CmdletBinding( PositionalBinding = $false )] [OutputType( [ADFCodeBlock] )] [Alias( 'ADFCodeBlock' )] param( [Parameter( Position = 0 )] [scriptblock] $Content, [ADFCodeBlockLanguage] $Language = [ADFCodeBlockLanguage]::none ) $Node = [ADFCodeBlock]::new( $Language ) if ( $Content ) { & $Content | ForEach-Object { $Node.AddChild( $_ ) } } return $Node } # ADFExpand Class # Represents an expand element in the ADF structure. class ADFExpand : ADFNode { [string] $type = 'expand' [hashtable] $attrs = @{} [System.Collections.Generic.List[ADFNode]] $content = @() [System.Collections.Generic.List[ADFMark]] $marks = @() hidden static [string[]] $AllowedChildren = @( 'bulletList', 'blockquote', 'codeBlock', 'heading', 'mediaGroup', 'mediaSingle', 'orderedList', 'panel', 'paragraph', 'rule', 'table', 'multiBodiedExtension', 'extensionFrame', 'nestedExpand' ) hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'title', [string], $true ) ) hidden static [string[]] $AllowedMarks = @( 'code', 'em', 'link', 'strike', 'strong', 'subsup', 'textColor', 'underline' ) ADFExpand( [string] $Title ) : base() { $this.AddAttribute( 'title', $Title ) } } # MARK: ADFExpand Function function New-ADFExpand { <# .SYNOPSIS Creates an ADF expand node. .PARAMETER Content Scriptblock whose output ADFNode objects will be added as children of the expand node. .PARAMETER Title The title of the expand node, displayed as the clickable text that expands or collapses the content. #> [CmdletBinding( PositionalBinding = $false, DefaultParameterSetName = 'Default' )] [OutputType( [ADFExpand] )] [Alias( 'ADFExpand' )] param( [Parameter( Position = 0 )] [scriptblock] $Content, [string] $Title ) $Node = [ADFExpand]::new( $Title ) if ( $Content ) { & $Content | ForEach-Object { $Node.AddChild( $_ ) } } return $Node } # MARK: ADFHeadingLevel Enum # Enum to represent the allowed levels for heading elements in the ADF structure. enum ADFHeadingLevel { H1 = 1 H2 = 2 H3 = 3 H4 = 4 H5 = 5 H6 = 6 } # MARK: ADFHeading Class # Represents a heading element in the ADF structure. class ADFHeading : ADFNode { [string] $type = 'heading' [hashtable] $attrs = @{} [System.Collections.Generic.List[ADFNode]] $content = @() [System.Collections.Generic.List[ADFMark]] $marks = @() hidden static [string[]] $AllowedChildren = @( 'date', 'emoji', 'hardBreak', 'inlineCard', 'mention', 'status', 'text', 'mediaInline' ) hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'level', [ADFHeadingLevel], [int] ) ) hidden static [string[]] $AllowedMarks = @( 'alignment' 'indentation' ) ADFHeading( [ADFHeadingLevel] $Level ) : base() { $this.AddAttribute( 'level', $Level ) } } # MARK: ADFHeading Function function New-ADFHeading { <# .SYNOPSIS Creates an ADF heading node. .PARAMETER Content Scriptblock whose output ADFNode objects will be added as children of the heading node. .PARAMETER Level The level of the heading, typically an integer from 1 to 6, where 1 represents the highest level (largest text) and 6 represents the lowest level (smallest text). #> [CmdletBinding( PositionalBinding = $false )] [OutputType( [ADFHeading] )] [Alias( 'ADFHeading' )] param( [Parameter( Position = 0 )] [scriptblock] $Content, [Parameter( Mandatory )] [ADFHeadingLevel] $Level, [ADFAlignment] $Align, [ValidateRange( 1, 6 )] [int] $IndentationLevel ) $Node = [ADFHeading]::new( $Level ) if ( $Align ) { $Node | Add-ADFAlignmentMark -Align $Align } if ( $IndentationLevel ) { $Node | Add-ADFIndentationMark -Level $IndentationLevel } if ( $Content ) { & $Content | ForEach-Object { $Node.AddChild( $_ ) } } return $Node } # MARK: ADFMediaGroup Class # Represents a media group element in the ADF structure. class ADFMediaGroup : ADFNode { [string] $type = 'mediaGroup' [System.Collections.Generic.List[ADFNode]] $content = @() hidden static [string[]] $AllowedChildren = @( 'media' ) ADFMediaGroup() : base() {} } # MARK: ADFMediaGroup Function function New-ADFMediaGroup { <# .SYNOPSIS Creates an ADF media group node, which can contain multiple media items. .PARAMETER Content Scriptblock whose output ADFNode objects will be added as children of the media group node. Typically, these will be ADFMedia nodes representing individual media items within the group. #> [CmdletBinding( PositionalBinding = $false )] [OutputType( [ADFMediaGroup] )] [Alias( 'ADFMediaGroup' )] param( [Parameter( Position = 0 )] [scriptblock] $Content ) $Node = [ADFMediaGroup]::new() if ( $Content ) { & $Content | ForEach-Object { $Node.AddChild( $_ ) } } return $Node } # MARK: ADFMediaSingleLayout Enum # Enum to represent the allowed layouts for media single elements in the ADF structure. enum ADFMediaSingleLayout { WrapLeft # wrap-left Center # center WrapRight # wrap-right Wide # wide FullWidth # full-width AlignStart # align-start AlignEnd # align-end } # MARK: ADFMediaSingleWidthType Enum # Enum to represent the allowed width types for media single elements in the ADF structure. enum ADFMediaSingleWidthType { Undefined Pixel Percentage } # MARK: ADFMediaSingle Class # Represents a media single element in the ADF structure. class ADFMediaSingle : ADFNode { [string] $type = 'mediaSingle' [hashtable] $attrs = @{} [System.Collections.Generic.List[ADFNode]] $content = @() hidden static [string[]] $AllowedChildren = @( 'media' ) hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'layout', [ADFMediaSingleLayout], [string], { ( $_.ToString() -creplace '(?<=[a-z])(?=[A-Z])', '-' ).ToLower() } ) # required [ADFAttributeInfo]::new( 'width', [double] ) [ADFAttributeInfo]::new( 'widthType', [ADFMediaSingleWidthType], [string], { $_.ToString().ToLower() } ) ) ADFMediaSingle( [ADFMediaSingleLayout] $Layout, [double] $Width, [ADFMediaSingleWidthType] $WidthType ) : base() { $this.AddAttribute( 'layout', $Layout ) $this.AddAttribute( 'width', $Width ) $this.AddAttribute( 'widthType', $WidthType ) } } # MARK: ADFMediaSingle Function function New-ADFMediaSingle { <# .SYNOPSIS Creates an ADF media single node, which represents a single media item with specific layout and optional width settings. .PARAMETER Content Scriptblock whose output ADFNode objects will be added as children of the media single node. Typically, this will be a single ADFMedia node representing the media item. .PARAMETER Layout The layout of the media single, which determines how the media item is displayed within the document. Common layout options include 'center', 'wrap-left', 'wrap-right', and 'wide'. #> [CmdletBinding( PositionalBinding = $false, DefaultParameterSetName = 'Default' )] [OutputType( [ADFMediaSingle] )] [Alias( 'ADFMediaSingle' )] param( [Parameter( Position = 0 )] [scriptblock] $Content, [Parameter( Mandatory )] [ADFMediaSingleLayout] $Layout = [ADFMediaSingleLayout]::Center, [Parameter( ParameterSetName = 'WithWidth', Mandatory )] [double] $Width = 0, [Parameter( ParameterSetName = 'WithWidth', Mandatory )] [ADFMediaSingleWidthType] $WidthType = [ADFMediaSingleWidthType]::Percentage ) $Node = [ADFMediaSingle]::new( $Layout, $Width, $WidthType ) if ( $Content ) { & $Content | ForEach-Object { $Node.AddChild( $_ ) } } return $Node } # MARK: ADFOrdereList Class # Represents an ordered list element in the ADF structure. class ADFOrderedList : ADFNode { [string] $type = 'orderedList' [hashtable] $attrs = @{} [System.Collections.Generic.List[ADFNode]] $content = @() hidden static [string[]] $AllowedChildren = @( 'listItem' ) hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'order', [int] ) ) ADFOrderedList() : base() {} ADFOrderedList( [int] $Order ) : base() { $this.AddAttribute( 'order', $Order ) } } # MARK: ADFOrderedList Function function New-ADFOrderedList { <# .SYNOPSIS Creates an ADF ordered list node. .PARAMETER Content Scriptblock whose output ADFNode objects will be added as children of the ordered list node. #> [CmdletBinding( PositionalBinding = $false )] [OutputType( [ADFOrderedList] )] [Alias( 'ADFOrderedList' )] param( [Parameter( Position = 0 )] [scriptblock] $Content, [Alias( 'Start' )] [int] $Order = 1 ) $Node = if ( $PSBoundParameters.ContainsKey('Order') ) { [ADFOrderedList]::new( $Order ) } else { [ADFOrderedList]::new() } if ( $Content ) { & $Content | ForEach-Object { $Node.AddChild( $_ ) } } return $Node } # MARK: ADFPanelType Enum # Enum to represent the allowed types for panel elements in the ADF structure. enum ADFPanelType { Info Note Success Warning Error } # MARK: ADFPanel Class # Represents a panel element in the ADF structure. class ADFPanel : ADFNode { [string] $type = 'panel' [hashtable] $attrs = @{} [System.Collections.Generic.List[ADFNode]] $content = @() hidden static [string[]] $AllowedChildren = @( 'bulletList', 'heading', 'orderedList', 'paragraph' ) hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'panelType', [ADFPanelType], [string], { $_.ToString().ToLower() } ) # required ) ADFPanel( [ADFPanelType] $PanelType ) : base() { $this.AddAttribute( 'panelType', $PanelType ) } } # MARK: ADFPanel Function function New-ADFPanel { <# .SYNOPSIS Creates an ADF panel node, which is a container element used to group related content together within a visually distinct panel. .PARAMETER Content Scriptblock whose output ADFNode objects will be added as children of the panel node. .PARAMETER Type The type of panel, which determines the visual styling and semantics of the panel. Common types include 'info', 'note', 'tip', 'success', 'warning', and 'error'. #> [CmdletBinding( PositionalBinding = $false )] [OutputType( [ADFPanel] )] [Alias( 'ADFPanel' )] param( [Parameter( Position = 0 )] [scriptblock] $Content, [Parameter( Mandatory )] [ADFPanelType] $Type ) $Node = [ADFPanel]::new( $Type ) if ( $Content ) { & $Content | ForEach-Object { $Node.AddChild( $_ ) } } return $Node } # MARK: ADFParagraph Class # Represents a paragraph element in the ADF structure. class ADFParagraph : ADFNode { [string] $type = 'paragraph' [System.Collections.Generic.List[ADFNode]] $content = @() [System.Collections.Generic.List[ADFMark]] $marks = @() hidden static [string[]] $AllowedChildren = @( 'date', 'emoji', 'hardBreak', 'inlineCard', 'mention', 'status', 'text', 'mediaInline' ) hidden static [string[]] $AllowedMarks = @( 'alignment' 'indentation' ) ADFParagraph() : base() {} } # MARK: ADFParagraph Function function New-ADFParagraph { <# .SYNOPSIS Creates an ADF paragraph node, which is a fundamental block-level element used to structure and format text content within the document. .PARAMETER Content Scriptblock whose output ADFNode objects will be added as children of the paragraph node. Typically, these will be ADFText nodes representing individual pieces of text within the paragraph, but can also include other inline elements such as ADFMention or ADFStatus. #> [CmdletBinding( PositionalBinding = $false )] [OutputType( [ADFParagraph] )] [Alias( 'ADFParagraph' )] param( [Parameter( Position = 0 )] [scriptblock] $Content, [ADFAlignment] $Align, [ValidateRange( 1, 6 )] [int] $IndentationLevel ) $Node = [ADFParagraph]::new() if ( $Align ) { $Node | Add-ADFAlignmentMark -Align $Align } if ( $IndentationLevel ) { $Node | Add-ADFIndentationMark -Level $IndentationLevel } if ( $Content ) { & $Content | ForEach-Object { $Node.AddChild( $_ ) } } return $Node } # MARK: ADFRule Class # Represents a rule element in the ADF structure. class ADFRule : ADFNode { [string] $type = 'rule' ADFRule() : base() {} } # MARK: ADFRule Function function New-ADFRule { <# .SYNOPSIS Creates an ADF rule node, which represents a thematic break or horizontal rule used to visually separate content within the document. #> [CmdletBinding( PositionalBinding = $false )] [OutputType( [ADFRule] )] [Alias( 'ADFRule' )] param() return [ADFRule]::new() } # MARK: ADFTableLayout Enum # Enum to represent the allowed layouts for table elements in the ADF structure. enum ADFTableLayout { Wide FullWidth Center AlignEnd AlignStart Default } # MARK: ADFTableDisplayMode Enum # Enum to represent the allowed display modes for table elements in the ADF structure. enum ADFTableDisplayMode { Default Fixed } # MARK: ADFTable Class # Represents a table element in the ADF structure. class ADFTable : ADFNode { [string] $type = 'table' [hashtable] $attrs = @{} [System.Collections.Generic.List[ADFNode]] $content = @() hidden static [string[]] $AllowedChildren = @( 'tableRow' ) hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'displayMode', [ADFTableDisplayMode], [string], { $_.ToString().ToLower() } ) [ADFAttributeInfo]::new( 'layout', [ADFTableLayout], [string], { $_.ToString() -creplace '(?<=[a-z])(?=[A-Z])', '-' | ForEach-Object ToLower } ) [ADFAttributeInfo]::new( 'width', [UInt32] ) [ADFAttributeInfo]::new( 'isNumberColumnEnabled', [bool], [bool] ) ) ADFTable() : base() {} ADFTable( [ADFTableDisplayMode] $DisplayMode ) : base() { $this.AddAttribute( 'displayMode', $DisplayMode ) } ADFTable( [ADFTableLayout] $Layout ) : base() { $this.AddAttribute( 'layout', $Layout ) } ADFTable( [ADFTableDisplayMode] $DisplayMode, [ADFTableLayout] $Layout ) : base() { $this.AddAttribute( 'displayMode', $DisplayMode ) $this.AddAttribute( 'layout', $Layout ) } ADFTable( [ADFTableDisplayMode] $DisplayMode, [ADFTableLayout] $Layout, [UInt32] $Width ) : base() { $this.AddAttribute( 'displayMode', $DisplayMode ) $this.AddAttribute( 'layout', $Layout ) $this.AddAttribute( 'width', $Width ) } ADFTable( [ADFTableDisplayMode] $DisplayMode, [ADFTableLayout] $Layout, [UInt32] $Width, [bool] $IsNumberColumnEnabled ) : base() { $this.AddAttribute( 'displayMode', $DisplayMode ) $this.AddAttribute( 'layout', $Layout ) $this.AddAttribute( 'width', $Width ) $this.AddAttribute( 'isNumberColumnEnabled', $IsNumberColumnEnabled ) } } # MARK: ADFTable Function function New-ADFTable { <# .SYNOPSIS Creates an ADF table node, which is a block-level element used to organize and display tabular data within the document. .PARAMETER Content Scriptblock whose output ADFNode objects will be added as children of the table node. Typically, these will be ADFTableRow nodes representing individual rows within the table, which in turn contain ADFTableCell nodes for each cell within the row. #> [CmdletBinding( PositionalBinding = $false )] [OutputType( [ADFTable] )] [Alias( 'ADFTable' )] param( [Parameter( Position = 0 )] [scriptblock] $Content, [ADFTableDisplayMode] $DisplayMode, [ADFTableLayout] $Layout, [UInt32] $Width, [switch] $IsNumberColumnEnabled ) $Node = [ADFTable]::new() if ( $PSBoundParameters.ContainsKey('DisplayMode') ) { $Node.AddAttribute( 'displayMode', $DisplayMode ) } if ( $PSBoundParameters.ContainsKey('Layout') ) { $Node.AddAttribute( 'layout', $Layout ) } if ( $PSBoundParameters.ContainsKey('Width') ) { $Node.AddAttribute( 'width', $Width ) } if ( $IsNumberColumnEnabled ) { $Node.AddAttribute( 'isNumberColumnEnabled', $true ) } if ( $Content ) { & $Content | ForEach-Object { $Node.AddChild( $_ ) } } return $Node } # MARK: ## CHILD BLOCK NODES ## # MARK: ADFListItem Class # Represents a list item element in the ADF structure, which can be a child of bullet list or ordered list elements. class ADFListItem : ADFNode { [string] $type = 'listItem' [System.Collections.Generic.List[ADFNode]] $content = @() hidden static [string[]] $AllowedChildren = @( 'bulletList', 'codeBlock', 'mediaSingle', 'orderedList', 'paragraph' ) ADFListItem() : base() {} } # MARK: ADFListItem Function function New-ADFListItem { <# .SYNOPSIS Creates an ADF list item node. .PARAMETER Content Scriptblock whose output ADFNode objects will be added as children of the list item node. #> [CmdletBinding( PositionalBinding = $false )] [OutputType( [ADFListItem] )] [Alias( 'ADFListItem' )] param( [Parameter( Position = 0 )] [scriptblock] $Content ) $Node = [ADFListItem]::new() if ( $Content ) { & $Content | ForEach-Object { $Node.AddChild( $_ ) } } return $Node } # MARK: ADFMediaType Enum # Enum to represent the allowed types for media elements in the ADF structure. enum ADFMediaType { File Link } # MARK: ADFMedia Class # Represents a media element in the ADF structure, which can be a child of media group or media single elements. class ADFMedia : ADFNode { [string] $type = 'media' [hashtable] $attrs = @{} [System.Collections.Generic.List[ADFMark]] $marks = @() hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'id', [string] ) # required [ADFAttributeInfo]::new( 'type', [ADFMediaType], [string], { $_.ToString().ToLower() } ) # required [ADFAttributeInfo]::new( 'collection', [string] ) # required [ADFAttributeInfo]::new( 'width', [UInt32] ) # required inside mediaSingle, ignored inside mediaGroup [ADFAttributeInfo]::new( 'height', [UInt32] ) # required inside mediaSingle, ignored inside mediaGroup [ADFAttributeInfo]::new( 'occurrenceKey', [string] ) # required for deletion ) hidden static [string[]] $AllowedMarks = @( 'annotation', 'border', 'link' ) ADFMedia( [string] $Id, [ADFMediaType] $Type, [string] $Collection ) : base() { $this.AddAttribute( 'id', $Id ) $this.AddAttribute( 'type', $Type ) $this.AddAttribute( 'collection', $Collection ) } ADFMedia( [string] $Id, [ADFMediaType] $Type, [string] $Collection, [UInt32] $Width, [UInt32] $Height ) : base() { $this.AddAttribute( 'id', $Id ) $this.AddAttribute( 'type', $Type ) $this.AddAttribute( 'collection', $Collection ) $this.AddAttribute( 'width', $Width ) $this.AddAttribute( 'height', $Height ) } ADFMedia( [string] $Id, [ADFMediaType] $Type, [string] $Collection, [string] $OccurrenceKey ) : base() { $this.AddAttribute( 'id', $Id ) $this.AddAttribute( 'type', $Type ) $this.AddAttribute( 'collection', $Collection ) $this.AddAttribute( 'occurrenceKey', $OccurrenceKey ) } ADFMedia( [string] $Id, [ADFMediaType] $Type, [string] $Collection, [string] $OccurrenceKey, [UInt32] $Width, [UInt32] $Height ) : base() { $this.AddAttribute( 'id', $Id ) $this.AddAttribute( 'type', $Type ) $this.AddAttribute( 'collection', $Collection ) $this.AddAttribute( 'occurrenceKey', $OccurrenceKey ) $this.AddAttribute( 'width', $Width ) $this.AddAttribute( 'height', $Height ) } } # MARK: ADFMedia Function function New-ADFMedia { <# .SYNOPSIS Creates an ADF media node. .PARAMETER Id Unique identifier of the media entity, used for referencing and tracking the media within the document. .PARAMETER Type The type of media, such as file or link, which determines how the media should be rendered and interacted with in the document. .PARAMETER Collection Optional collection or category that the media belongs to, can be used for organizing media within the document. .PARAMETER Width Optional width of the media in pixels, required when the media is a single item (mediaSingle) to ensure proper rendering and layout. .PARAMETER Height Optional height of the media in pixels, required when the media is a single item (mediaSingle) to ensure proper rendering and layout. .PARAMETER OccurrenceKey Optional unique key for tracking occurrences of the media, useful for analytics or media management purposes, especially when handling deletions or updates to the media. #> [CmdletBinding( PositionalBinding = $false, DefaultParameterSetName = 'Default' )] [OutputType( [ADFMedia] )] [Alias( 'ADFMedia' )] param( [Parameter( Mandatory )] [string] $Id, [Parameter( Mandatory )] [ADFMediaType] $Type, [Parameter( Mandatory )] [string] $Collection, [UInt32] $Width, [UInt32] $Height, [string] $OccurrenceKey, [Parameter( ParameterSetName = 'Link', Mandatory )] [uri] $LinkHref, [Parameter( ParameterSetName = 'Link' )] [string] $LinkTitle, [Parameter( ParameterSetName = 'Link' )] [string] $LinkId, [Parameter( ParameterSetName = 'Link' )] [string] $LinkCollection, [Parameter( ParameterSetName = 'Link' )] [string] $LinkOccurrenceKey ) $Node = [ADFMedia]::new( $Id, $Type, $Collection ) if ( $PSBoundParameters.ContainsKey('Width') ) { $Node.AddAttribute( 'width', $Width ) } if ( $PSBoundParameters.ContainsKey('Height') ) { $Node.AddAttribute( 'height', $Height ) } if ( $PSBoundParameters.ContainsKey('OccurrenceKey') ) { $Node.AddAttribute( 'occurrenceKey', $OccurrenceKey ) } if ( $PSBoundParameters.ContainsKey('LinkHref') ) { $LinkMark = [ADFLinkMark]::new( $LinkHref ) if ( $PSBoundParameters.ContainsKey('LinkTitle') ) { $LinkMark.AddAttribute( 'title', $LinkTitle ) } if ( $PSBoundParameters.ContainsKey('LinkId') ) { $LinkMark.AddAttribute( 'id', $LinkId ) } if ( $PSBoundParameters.ContainsKey('LinkCollection') ) { $LinkMark.AddAttribute( 'collection', $LinkCollection ) } if ( $PSBoundParameters.ContainsKey('LinkOccurrenceKey') ) { $LinkMark.AddAttribute( 'occurrenceKey', $LinkOccurrenceKey ) } $Node.AddMark( $LinkMark ) } return $Node } # MARK: ADFNestedExpand Class # Represents a nested expand element in the ADF structure, which can be a child of an expand element. class ADFNestedExpand : ADFExpand { [string] $type = 'nestedExpand' [hashtable] $attrs = @{} [System.Collections.Generic.List[ADFNode]] $content = @() hidden static [string[]] $AllowedChildren = @( 'paragraph', 'heading', 'mediaGroup', 'mediaSingle' ) hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'title', [string] ) ) ADFNestedExpand() : base() {} ADFNestedExpand( [string] $Title ) : base() { $this.AddAttribute( 'title', $Title ) } } # MARK: ADFNestedExpand Function function New-ADFNestedExpand { <# .SYNOPSIS Creates an ADF nested expand node, which is a specialized type of expand node that can be nested within other expand nodes to create multi-level expandable content. .PARAMETER Content Scriptblock whose output ADFNode objects will be added as children of the nested expand node .PARAMETER Title The title of the nested expand node, displayed as the clickable text that expands or collapses the content of the nested expand. This allows for better organization and readability when dealing with complex or lengthy content that can be expanded or collapsed by the user. #> [CmdletBinding( PositionalBinding = $false )] [OutputType( [ADFNestedExpand] )] [Alias( 'ADFNestedExpand' )] param( [Parameter( Position = 0 )] [scriptblock] $Content, [string] $Title ) $Node = if ( $PSBoundParameters.ContainsKey('Title') ) { [ADFNestedExpand]::new( $Title ) } else { [ADFNestedExpand]::new() } if ( $Content ) { & $Content | ForEach-Object { $Node.AddChild( $_ ) } } return $Node } # MARK ADFTableCell Class # Represents a table cell element in the ADF structure, which can be a child of a table row element. class ADFTableCell : ADFNode { [string] $type = 'tableCell' [hashtable] $attrs = @{} [System.Collections.Generic.List[ADFNode]] $content = @() hidden static [string[]] $AllowedChildren = @( 'blockquote', 'bulletList', 'codeBlock', 'heading', 'mediaGroup', 'nestedExpand', 'orderedList', 'panel', 'paragraph', 'rule' ) hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'background', [string] ) [ADFAttributeInfo]::new( 'colspan', [UInt32] ) [ADFAttributeInfo]::new( 'colwidth', [UInt32[]] ) [ADFAttributeInfo]::new( 'rowspan', [UInt32] ) ) ADFTableCell() : base() {} ADFTableCell( [string] $Background, [UInt32] $Colspan, [UInt32[]] $Colwidth, [UInt32] $Rowspan ) : base() { $this.AddAttribute( 'background', $Background ) $this.AddAttribute( 'colspan', $Colspan ) $this.AddAttribute( 'colwidth', $Colwidth ) $this.AddAttribute( 'rowspan', $Rowspan ) } } # MARK: ADFTableCell Function function New-ADFTableCell { <# .SYNOPSIS Creates an ADF table cell node, which represents an individual cell within a table row in the ADF structure. .PARAMETER Content Scriptblock whose output ADFNode objects will be added as children of the table cell node. This can include various block-level elements such as paragraphs, headings, lists, and media groups to structure the content within the cell. .PARAMETER Background Optional background color for the table cell, specified as a string (e.g., hex code or color name), which can be used to visually differentiate cells within the table. .PARAMETER Colspan Optional number of columns that the cell should span across, allowing for the creation of merged cells that extend horizontally across multiple columns in the table. .PARAMETER Colwidth Optional array of widths for each column that the cell spans across, specified in pixels or percentages, which can be used to control the layout and appearance of the table. .PARAMETER Rowspan Optional number of rows that the cell should span across, allowing for the creation of merged cells that extend vertically across multiple rows in the table. #> [CmdletBinding( PositionalBinding = $false )] [OutputType( [ADFTableCell] )] [Alias( 'ADFTableCell' )] param( [Parameter( Position = 0 )] [scriptblock] $Content, [string] $Background, [UInt32] $Colspan, [UInt32[]] $Colwidth, [UInt32] $Rowspan ) $Node = [ADFTableCell]::new() if ( $PSBoundParameters.ContainsKey('Background') ) { $Node.AddAttribute( 'background', $Background ) } if ( $PSBoundParameters.ContainsKey('Colspan') ) { $Node.AddAttribute( 'colspan', $Colspan ) } if ( $PSBoundParameters.ContainsKey('Colwidth') ) { $Node.AddAttribute( 'colwidth', $Colwidth ) } if ( $PSBoundParameters.ContainsKey('Rowspan') ) { $Node.AddAttribute( 'rowspan', $Rowspan ) } if ( $Content ) { & $Content | ForEach-Object { $Node.AddChild( $_ ) } } return $Node } # MARK: ADFTableHeader Class # Represents a table header cell element in the ADF structure, which can be a child of a table row element. class ADFTableHeader : ADFTableCell { [string] $type = 'tableHeader' [hashtable] $attrs = @{} [System.Collections.Generic.List[ADFNode]] $content = @() ADFTableHeader() : base() {} ADFTableHeader( [string] $Background, [UInt32] $Colspan, [UInt32[]] $Colwidth, [UInt32] $Rowspan ) : base( $Background, $Colspan, $Colwidth, $Rowspan ) {} } # MARK: ADFTableHeader Function function New-ADFTableHeader { <# .SYNOPSIS Creates an ADF table header cell node, which represents a header cell within a table row in the ADF structure, typically used to define column headers or row headers in a table. .PARAMETER Content Scriptblock whose output ADFNode objects will be added as children of the table header cell node. This can include various block-level elements such as paragraphs, headings, lists, and media groups to structure the content within the header cell. .PARAMETER Background Optional background color for the table header cell, specified as a string (e.g., hex code or color name), which can be used to visually differentiate header cells from regular cells within the table. .PARAMETER Colspan Optional number of columns that the header cell should span across, allowing for the creation of merged header cells that extend horizontally across multiple columns in the table. .PARAMETER Colwidth Optional array of widths for each column that the header cell spans across, specified in pixels or percentages, which can be used to control the layout and appearance of the table. .PARAMETER Rowspan Optional number of rows that the header cell should span across, allowing for the creation of merged header cells that extend vertically across multiple rows in the table. #> [CmdletBinding( PositionalBinding = $false )] [OutputType( [ADFTableHeader] )] [Alias( 'ADFTableHeader' )] param( [Parameter( Position = 0 )] [scriptblock] $Content, [string] $Background, [UInt32] $Colspan, [UInt32[]] $Colwidth, [UInt32] $Rowspan ) $Node = [ADFTableHeader]::new() if ( $PSBoundParameters.ContainsKey('Background') ) { $Node.AddAttribute( 'background', $Background ) } if ( $PSBoundParameters.ContainsKey('Colspan') ) { $Node.AddAttribute( 'colspan', $Colspan ) } if ( $PSBoundParameters.ContainsKey('Colwidth') ) { $Node.AddAttribute( 'colwidth', $Colwidth ) } if ( $PSBoundParameters.ContainsKey('Rowspan') ) { $Node.AddAttribute( 'rowspan', $Rowspan ) } if ( $Content ) { & $Content | ForEach-Object { $Node.AddChild( $_ ) } } return $Node } # MARK: ADFTableRow Class # Represents a table row element in the ADF structure, which can be a child of a table element and can contain table cell and table header elements. class ADFTableRow : ADFNode { [string] $type = 'tableRow' [System.Collections.Generic.List[ADFNode]] $content = @() hidden static [string[]] $AllowedChildren = @( 'tableCell', 'tableHeader' ) ADFTableRow() : base() {} } # MARK: ADFTableRow Function function New-ADFTableRow { <# .SYNOPSIS Creates an ADF table row node, which represents a single row within a table in the ADF structure. .PARAMETER Content Scriptblock whose output ADFNode objects will be added as children of the table row node. Typically, these will be ADFTableCell and ADFTableHeader nodes representing individual cells within the row, which can contain various block-level elements to structure the content within each cell. #> [CmdletBinding( PositionalBinding = $false )] [OutputType( [ADFTableRow] )] [Alias( 'ADFTableRow' )] param( [Parameter( Position = 0 )] [scriptblock] $Content ) $Node = [ADFTableRow]::new() if ( $Content ) { & $Content | ForEach-Object { $Node.AddChild( $_ ) } } return $Node } # MARK: ## INLINE NODES ## # MARK: ADFDate Class # Represents a date element in the ADF structure, which can be a child of paragraph or heading elements. class ADFDate : ADFNode { [string] $type = 'date' [hashtable] $attrs = @{} hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'timestamp', [DateTime], [Int64], { [System.DateTimeOffset]::new( $_ ).ToUnixTimeSeconds() } ) ) ADFDate() : base() {} ADFDate( [DateTime] $Timestamp ) : base() { $this.AddAttribute( 'timestamp', $Timestamp ) } } # MARK: ADFDate Function function New-ADFDate { <# .SYNOPSIS Creates an ADF date node. .PARAMETER Timestamp The date and time value to be represented by the date node. #> [CmdletBinding( PositionalBinding = $false )] [OutputType( [ADFDate] )] [Alias( 'ADFDate' )] param( [DateTime] $Timestamp ) return [ADFDate]::new( $Timestamp ) } # MARK: ADFEmoji Class # Represents an emoji element in the ADF structure, which can be a child of paragraph or heading elements. class ADFEmoji : ADFNode { [string] $type = 'emoji' [hashtable] $attrs = @{} hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'shortName', [string] ) # required [ADFAttributeInfo]::new( 'id', [string] ) # optional, service ID of the emoji [ADFAttributeInfo]::new( 'text', [string] ) # optional, fallback text to display if the emoji cannot be rendered, defaults to the shortName ) ADFEmoji( [string] $ShortName ) : base() { $this.AddAttribute( 'shortName', $ShortName ) } ADFEmoji( [string] $ShortName, [string] $Text ) : base() { $this.AddAttribute( 'shortName', $ShortName ) $this.AddAttribute( 'text', $Text ) } ADFEmoji( [string] $ShortName, [string] $Text, [string] $Id ) : base() { $this.AddAttribute( 'shortName', $ShortName ) $this.AddAttribute( 'text', $Text ) $this.AddAttribute( 'id', $Id ) } } # MARK: ADFEmoji Function function New-ADFEmoji { <# .SYNOPSIS Creates an ADF emoji node. .PARAMETER ShortName The short name of the emoji, typically in the format :emoji_name: (e.g., :smile:). .PARAMETER Text Optional text to display for the emoji, used as a fallback if the emoji cannot be rendered. Defaults to the short name if not provided. .PARAMETER Id Optional service ID of the emoji, used for tracking or referencing the emoji within the document. #> [CmdletBinding( PositionalBinding = $false )] [OutputType( [ADFEmoji] )] [Alias( 'ADFEmoji' )] param( [Parameter( Mandatory )] [string] $ShortName, [string] $Text, [string] $Id ) if ( $PSBoundParameters.ContainsKey('Id') -and $PSBoundParameters.ContainsKey('Text') ) { return [ADFEmoji]::new( $ShortName, $Text, $Id ) } elseif ( $PSBoundParameters.ContainsKey('Text') ) { return [ADFEmoji]::new( $ShortName, $Text ) } else { return [ADFEmoji]::new( $ShortName ) } } # MARK: ADFHardBreak Class # Represents a hard break element in the ADF structure, which can be a child of paragraph or heading elements. class ADFHardBreak : ADFNode { [string] $type = 'hardBreak' [hashtable] $attrs = @{} hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'text', [string] ) # optional, text to display for the hard break, defaults to a newline character ) ADFHardBreak() : base() {} ADFHardBreak( [string] $Text ) : base() { $this.AddAttribute( 'text', $Text ) } } # MARK: ADFHardBreak Function function New-ADFHardBreak { <# .SYNOPSIS Creates an ADF hard break node. .PARAMETER Text Optional text to display for the hard break, used as a fallback if the hard break cannot be rendered. Defaults to a newline character if not provided. #> [CmdletBinding( PositionalBinding = $false )] [OutputType( [ADFHardBreak] )] [Alias( 'ADFHardBreak' )] param( [string] $Text ) return if ( $PSBoundParameters.ContainsKey('Text') ) { [ADFHardBreak]::new( $Text ) } else { [ADFHardBreak]::new() } } # MARK: ADFInlineCard Class # Represents an inline card element in the ADF structure, which can be a child of paragraph or heading elements. class ADFInlineCard : ADFNode { [string] $type = 'inlineCard' [hashtable] $attrs = @{} hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'url', [uri], [string] ) [ADFAttributeInfo]::new( 'data', [string], [object], { ConvertFrom-Json -InputObject $_ -Depth 5 -ErrorAction Stop } ) # JSONLD representation ) ADFInlineCard( [uri] $Url ) : base() { $this.AddAttribute( 'url', $Url ) } ADFInlineCard( [string] $Data ) : base() { $this.AddAttribute( 'data', $Data ) } } # MARK: ADFInlineCard Function function New-ADFInlineCard { <# .SYNOPSIS Creates an ADF inline card node. .PARAMETER Url The URL that the inline card points to, making the card clickable and directing users to the specified URL when clicked. .PARAMETER Data JSONLD representation of the data to be displayed in the inline card, allowing for rich content and metadata to be included in the card. #> [CmdletBinding( PositionalBinding = $false, DefaultParameterSetName = 'Url' )] [OutputType( [ADFInlineCard] )] [Alias( 'ADFInlineCard' )] param( [Parameter( ParameterSetName = 'Url', Mandatory )] [uri] $Url, [Parameter( ParameterSetName = 'Data', Mandatory )] [string] $Data ) $Node = if ( $PSBoundParameters.ContainsKey('Url') ) { [ADFInlineCard]::new( $Url ) } else { [ADFInlineCard]::new( $Data ) } return $Node } # MARK: ADFMentionAccessLevel Enum # Enum to represent the allowed access levels for mention elements in the ADF structure. enum ADFMentionAccessLevel { None Site Application Container } # MARK: ADFMentionUserType Enum # Enum to represent the allowed user types for mention elements in the ADF structure. enum ADFMentionUserType { Default Special App } # MARK: ADFMention Class # Represents a mention element in the ADF structure, which can be a child of paragraph or heading elements. class ADFMention : ADFNode { [string] $type = 'mention' [hashtable] $attrs = @{} hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'id', [string] ) # required, unique identifier of the mentioned entity [ADFAttributeInfo]::new( 'text', [string] ) # optional, text to display for the mention, defaults to the id [ADFAttributeInfo]::new( 'accessLevel', [ADFMentionAccessLevel], [string], { $_.ToString().ToUpper() } ) # optional, access level of the mentioned entity [ADFAttributeInfo]::new( 'userType', [ADFMentionUserType], [string], { $_.ToString().ToUpper() } ) # optional, user type of the mentioned entity ) ADFMention( [string] $Id ) : base() { $this.AddAttribute( 'id', $Id ) } ADFMention( [string] $Id, [string] $Text ) : base() { $this.AddAttribute( 'id', $Id ) $this.AddAttribute( 'text', $Text ) } ADFMention( [string] $Id, [string] $Text, [ADFMentionAccessLevel] $AccessLevel, [ADFMentionUserType] $UserType ) : base() { $this.AddAttribute( 'id', $Id ) $this.AddAttribute( 'text', $Text ) $this.AddAttribute( 'accessLevel', $AccessLevel ) $this.AddAttribute( 'userType', $UserType ) } } # MARK: ADFMention Function function New-ADFMention { <# .SYNOPSIS Creates an ADF mention node. .PARAMETER Id Unique identifier of the mentioned entity, used for referencing and tracking the mention within the document. .PARAMETER Text Optional text to display for the mention, used as a fallback if the mention cannot be rendered. Defaults to the id if not provided. .PARAMETER AccessLevel Optional access level of the mentioned entity, which can be used to control visibility or permissions related to the mention. Defaults to None if not provided. .PARAMETER UserType Optional user type of the mentioned entity, which can be used to categorize mentions based on user roles or types. Defaults to Default if not provided. #> [CmdletBinding( PositionalBinding = $false )] [OutputType( [ADFMention] )] [Alias( 'ADFMention' )] param( [Parameter( Mandatory )] [string] $Id, [string] $Text, [ADFMentionAccessLevel] $AccessLevel, [ADFMentionUserType] $UserType ) $Node = [ADFMention]::new( $Id ) if ( $PSBoundParameters.ContainsKey('Text') ) { $Node.AddAttribute( 'text', $Text ) } if ( $PSBoundParameters.ContainsKey('AccessLevel') ) { $Node.AddAttribute( 'accessLevel', $AccessLevel ) } if ( $PSBoundParameters.ContainsKey('UserType') ) { $Node.AddAttribute( 'userType', $UserType ) } return $Node } # MARK: ADFStatusColor Enum # Enum to represent the allowed colors for status elements in the ADF structure. enum ADFStatusColor { Neutral Purple Blue Red Yellow Green } # MARK: ADFStatus Class # Represents a status element in the ADF structure, which can be a child of paragraph or heading elements. class ADFStatus : ADFNode { [string] $type = 'status' [hashtable] $attrs = @{} hidden static [ADFAttributeInfo[]] $AllowedAttributes = @( [ADFAttributeInfo]::new( 'text', [string] ) # required, text to display for the status [ADFAttributeInfo]::new( 'color', [ADFStatusColor], [string], { $_.ToString() } ) # required, color of the status, defaults to Neutral ) ADFStatus( [string] $Text ) : base() { $this.AddAttribute( 'text', $Text ) $this.AddAttribute( 'color', [ADFStatusColor]::Neutral ) } ADFStatus( [string] $Text, [ADFStatusColor] $Color ) : base() { $this.AddAttribute( 'text', $Text ) $this.AddAttribute( 'color', $Color ) } } # MARK: ADFStatus Function function New-ADFStatus { <# .SYNOPSIS Creates an ADF status node, which is an inline element used to display a status or label with specific text and color. .PARAMETER Text The text to display for the status, which provides a description or label for the status being represented. .PARAMETER Color The color of the status, which can be used to visually differentiate between different statuses. Common color options include 'neutral', 'purple', 'blue', 'red', 'yellow', and 'green'. #> [CmdletBinding( PositionalBinding = $false )] [OutputType( [ADFStatus] )] [Alias( 'ADFStatus' )] param( [Parameter( Mandatory )] [string] $Text, [ADFStatusColor] $Color = [ADFStatusColor]::Neutral ) return [ADFStatus]::new( $Text, $Color ) } # MARK: ADFText Class # Represents a text element in the ADF structure, which can be a child of paragraph or heading elements. class ADFText : ADFNode { [string] $type = 'text' [string] $text = '' [System.Collections.Generic.List[ADFMark]] $marks = @() hidden static [string[]] $AllowedMarks = @( 'annotation', 'backgroundColor', 'code', 'em', 'link', 'strike', 'strong', 'subsup', 'textColor', 'underline' ) ADFText( [object] $Object ) : base() { $this.Text = $Object } } # MARK: ADFText Function function New-ADFText { <# .SYNOPSIS Creates an ADF text node, which represents a piece of text content within a paragraph or heading in the ADF structure. .PARAMETER Text The text content to be represented by the ADF text node. This can be a string or any object that can be converted to a string, such as numbers or other data types. #> [CmdletBinding( PositionalBinding = $false, DefaultParameterSetName = 'Default' )] [OutputType( [ADFText] )] [Alias( 'ADFText' )] param( [Parameter( Position = 0, Mandatory )] [object] $Text, [switch] $Code, [switch] $Em, [switch] $Strike, [switch] $Strong, [ADFSubsupMarkType] $SubsupType, [string] $TextColor, [switch] $Underline, [Parameter( ParameterSetName = 'Link', Mandatory )] [uri] $LinkHref, [Parameter( ParameterSetName = 'Link' )] [string] $LinkTitle, [Parameter( ParameterSetName = 'Link' )] [string] $LinkId, [Parameter( ParameterSetName = 'Link' )] [string] $LinkCollection, [Parameter( ParameterSetName = 'Link' )] [string] $LinkOccurrenceKey ) $Node = [ADFText]::new( $Text ) if ( $Code ) { $Node.AddMark( [ADFCodeMark]::new() ) } if ( $Em ) { $Node.AddMark( [ADFEmMark]::new() ) } if ( $Strike ) { $Node.AddMark( [ADFStrikeMark]::new() ) } if ( $Strong ) { $Node.AddMark( [ADFStrongMark]::new() ) } if ( $SubsupType ) { $Node.AddMark( [ADFSubSupMark]::new( $SubsupType ) ) } if ( $TextColor ) { $Node.AddMark( [ADFTextColorMark]::new( $TextColor ) ) } if ( $Underline ) { $Node.AddMark( [ADFUnderlineMark]::new() ) } if ( $PSBoundParameters.ContainsKey('LinkHref') ) { $LinkMark = [ADFLinkMark]::new( $LinkHref ) if ( $PSBoundParameters.ContainsKey('LinkTitle') ) { $LinkMark.AddAttribute( 'title', $LinkTitle ) } if ( $PSBoundParameters.ContainsKey('LinkId') ) { $LinkMark.AddAttribute( 'id', $LinkId ) } if ( $PSBoundParameters.ContainsKey('LinkCollection') ) { $LinkMark.AddAttribute( 'collection', $LinkCollection ) } if ( $PSBoundParameters.ContainsKey('LinkOccurrenceKey') ) { $LinkMark.AddAttribute( 'occurrenceKey', $LinkOccurrenceKey ) } $Node.AddMark( $LinkMark ) } return $Node } |