Skip to content

Commit 2b0a2a7

Browse files
StartAutomatingStartAutomating
authored andcommitted
feat: Turtle.get/set_Element ( Fixes #248 )
1 parent 0d5ed3f commit 2b0a2a7

File tree

1 file changed

+206
-0
lines changed

1 file changed

+206
-0
lines changed

Turtle.types.ps1xml

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4937,6 +4937,212 @@ if (($this.'.Duration' -is [TimeSpan]) -and $this.PathAnimation) {
49374937
}
49384938
</SetScriptBlock>
49394939
</ScriptProperty>
4940+
<ScriptProperty>
4941+
<Name>Element</Name>
4942+
<GetScriptBlock>
4943+
&lt;#
4944+
.SYNOPSIS
4945+
Gets a Turtle as an Element
4946+
.DESCRIPTION
4947+
We can treat any Turtle as any arbitrary markup element.
4948+
4949+
To do this, all we need to do is set an element name, and, optionally, add some attributes or children.
4950+
.EXAMPLE
4951+
# Any bareword can become the name of an element, as long as it is not a method name
4952+
turtle element div element
4953+
.EXAMPLE
4954+
# We can provide anything that will cast to XML as an element
4955+
turtle element '&lt;div/&gt;' element
4956+
.EXAMPLE
4957+
# We can provide an element and attributes
4958+
turtle element '&lt;div class='myClass' /&gt;' element
4959+
.EXAMPLE
4960+
# We can put a turtle inside of an aribtrary element
4961+
turtle SpiderWeb element '&lt;div /&gt;'
4962+
#&gt;
4963+
4964+
# If we have set an element name
4965+
if ($this.'.Element'.ElementName) {
4966+
4967+
# make this little filter to recursively turn the element back into XML
4968+
filter toElement {
4969+
$in = $_
4970+
# If the input was a dictionary with an element name
4971+
if ($in -is [Collections.IDictionary] -and $in.ElementName) {
4972+
# start the markup
4973+
"&lt;$($in.ElementName)$(
4974+
# and pop in any element attributes
4975+
foreach ($attributeCollection in 'attr','attribute','attributes') {
4976+
if (-not $in.$attributeCollection) { continue }
4977+
if ($in.$attributeCollection -is [Collections.IDictionary]) {
4978+
foreach ($attributeName in $in.$attributeCollection.Keys) {
4979+
if ($attributeName -match '/') { continue }
4980+
' ', $attributeName,"='",$in.$attributeCollection[$attributeName],"'" -join ''
4981+
}
4982+
} elseif ($in.$attributeCollection -is [string]) {
4983+
$in.$attributeCollection
4984+
}
4985+
break
4986+
}
4987+
)&gt;$(
4988+
# Now include any child elements
4989+
if ($this.Steps -or $this.Text) {
4990+
$this.SVG.OuterXml
4991+
}
4992+
@(foreach ($childCollection in 'child','ChildNodes','Children','Content') {
4993+
if (-not $in.$childCollection) {
4994+
continue
4995+
}
4996+
foreach ($child in $in.$childCollection) {
4997+
# strings are directly included
4998+
if ($child -is [string]) {
4999+
$child
5000+
} elseif ($child -is [xml] -or $child -is [xml.xmlElement]) {
5001+
# xml elements will embed themselves
5002+
$child.OuterXml
5003+
} elseif ($child -is [Collections.IDictionary] -and $child.ElementName) {
5004+
# and dictionaries with an element name will recurisvely call ourselves.
5005+
$child | &amp; $MyInvocation.MyCommand.ScriptBlock
5006+
} else {
5007+
# Any other input will be stringified
5008+
"$child"
5009+
}
5010+
}
5011+
break
5012+
}) -join ([Environment]::NewLine)
5013+
)&lt;/$($in.ElementName)&gt;"
5014+
}
5015+
if ($_ -is [string]) {
5016+
$_
5017+
}
5018+
}
5019+
5020+
$elementMarkup = $this.'.Element' | toElement
5021+
$elementXml = $elementMarkup -as [xml]
5022+
if ($elementXml) {
5023+
$elementXml
5024+
} else {
5025+
$elementMarkup
5026+
}
5027+
return
5028+
}
5029+
else {
5030+
return $this.SVG
5031+
}
5032+
5033+
return
5034+
5035+
</GetScriptBlock>
5036+
<SetScriptBlock>
5037+
&lt;#
5038+
.SYNOPSIS
5039+
Sets the Turtle element
5040+
.DESCRIPTION
5041+
Sets the Turtle to an arbitrary element.
5042+
5043+
This lets us write web pages and xml entirely in turtle.
5044+
.EXAMPLE
5045+
# Any bareword can become the name of an element, as long as it is not a method name
5046+
turtle element div element
5047+
.EXAMPLE
5048+
# We can provide anything that will cast to XML as an element
5049+
turtle element '&lt;div/&gt;' element
5050+
.EXAMPLE
5051+
# We can provide an element and attributes
5052+
turtle element '&lt;div class='myClass' /&gt;' element
5053+
.EXAMPLE
5054+
# We can put a turtle inside of an aribtrary element
5055+
turtle SpiderWeb element '&lt;div /&gt;'
5056+
#&gt;
5057+
5058+
param()
5059+
5060+
if (-not $this.'.Element') {
5061+
$this | Add-Member NoteProperty '.Element' -Value ([Ordered]@{
5062+
ElementName=''
5063+
Attribute=$this.Attribute
5064+
Children=@()
5065+
})
5066+
}
5067+
5068+
$unrolledArgs = $args |. {process { $_ }}
5069+
5070+
foreach ($element in $unrolledArgs){
5071+
if ($element -is [string] -and
5072+
(-not ($element -as [xml])) -and
5073+
$element -notmatch '\s'
5074+
) {
5075+
$this.'.Element'.ElementName = $Element
5076+
continue
5077+
}
5078+
5079+
if ($element -is [xml] -or $Element -as [xml]) {
5080+
if ($Element -isnot [xml]) {
5081+
$element = $Element -as [xml]
5082+
}
5083+
$this.'.Element'.ElementName = $Element.ChildNodes[0].LocalName
5084+
foreach ($attribute in $element.ChildNodes[0].Attributes) {
5085+
$this.'.Element'.Attribute[$attribute.Name] = $attribute.Value
5086+
}
5087+
foreach ($grandchild in $element.ChildNodes[0].ChildNodes) {
5088+
$this.'.Element'.Children += $grandchild
5089+
}
5090+
continue
5091+
}
5092+
5093+
if ($element -is [Collections.IDictionary]) {
5094+
$elementKeys = 'ElementName','Name','E'
5095+
foreach ($potentialName in $elementKeys) {
5096+
if ($element.$potentialName) {
5097+
$this.'.Element'.ElementName = $element.$potentialName
5098+
break
5099+
}
5100+
}
5101+
$attributeKeys = 'Attribute', 'Attributes', 'A'
5102+
foreach ($potentialAttributeName in $attributeKeys) {
5103+
if ($element.$potentialAttributeName -is [Collections.IDictionary] -and
5104+
$element.$potentialAttributeName.Count) {
5105+
foreach ($attributeName in $element.$potentialAttributeName.Keys) {
5106+
$this.'.Element'.Attribute[$attributeName] = $element.$potentialAttributeName[$attributeName]
5107+
}
5108+
break
5109+
}
5110+
}
5111+
$childKeys = 'Child', 'Children', 'ChildNodes','Content', 'C'
5112+
5113+
foreach ($potentialChildrenName in $childKeys) {
5114+
$children = $element.$potentialChildrenName
5115+
if (-not $children) { continue }
5116+
$this.'.Element'.Children += $children
5117+
break
5118+
}
5119+
5120+
$specialKeys = @(
5121+
$elementKeys
5122+
$attributeKeys
5123+
$childKeys
5124+
)
5125+
5126+
foreach ($elementKey in $element.Keys) {
5127+
if ($elementKey -in $specialKeys) { continue }
5128+
$elementValue = $element[$elementKey]
5129+
if ($elementValue -is [ValueType] -or (
5130+
$elementValue -is [string] -and $elementValue -notmatch '[\r\n]'
5131+
)) {
5132+
$this.'.Element'.Attribute[$elementKey] = $elementValue
5133+
}
5134+
}
5135+
continue
5136+
}
5137+
5138+
if ($elementName) {
5139+
5140+
}
5141+
}
5142+
5143+
5144+
</SetScriptBlock>
5145+
</ScriptProperty>
49405146
<ScriptProperty>
49415147
<Name>Fill</Name>
49425148
<GetScriptBlock>

0 commit comments

Comments
 (0)