Skip to content

Commit b0c2d9c

Browse files
author
James Brundage
committed
Adding PS1XML Transpiler (Fixes #414)
Also, renaming .SaveTemplate to .Save and restricting XML template
1 parent f11059b commit b0c2d9c

4 files changed

Lines changed: 136 additions & 50 deletions

File tree

Transpilers/Core/PipeScript.Template.psx.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ $replacePattern
509509
}
510510
), `$true)
511511
`$templateObject.psobject.members.Add([PSScriptMethod]::new(
512-
'SaveTemplate', {
512+
'Save', {
513513
$SaveTemplate
514514
}
515515
), `$true)
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<#
2+
.SYNOPSIS
3+
PS1XML Template Transpiler.
4+
.DESCRIPTION
5+
Allows PipeScript to generate PS1XML.
6+
7+
Multiline comments blocks like this ```<!--{}-->``` will be treated as blocks of PipeScript.
8+
.EXAMPLE
9+
$typesFile, $typeDefinition, $scriptMethod = Invoke-PipeScript {
10+
11+
types.ps1xml template '
12+
<Types>
13+
<!--{param([Alias("TypeDefinition")]$TypeDefinitions) $TypeDefinitions }-->
14+
</Types>
15+
'
16+
17+
typeDefinition.ps1xml template '
18+
<Type>
19+
<!--{param([Alias("PSTypeName")]$TypeName) "<Name>$($typename)</Name>" }-->
20+
<!--{param([Alias("PSMembers","Member")]$Members) "<Members>$($members)</Members>" }-->
21+
</Type>
22+
'
23+
24+
scriptMethod.ps1xml template '
25+
<ScriptMethod>
26+
<!--{param([Alias("Name")]$MethodName) "<Name>$($MethodName)</Name>" }-->
27+
<!--{param([ScriptBlock]$MethodDefinition) "<Script>$([Security.SecurityElement]::Escape("$MethodDefinition"))</Script>" }-->
28+
</ScriptMethod>
29+
'
30+
}
31+
32+
33+
$typesFile.Save("Test.types.ps1xml",
34+
$typeDefinition.Evaluate(@{
35+
TypeName='foobar'
36+
Members =
37+
@($scriptMethod.Evaluate(
38+
@{
39+
MethodName = 'foo'
40+
MethodDefinition = {"foo"}
41+
}
42+
),$scriptMethod.Evaluate(
43+
@{
44+
MethodName = 'bar'
45+
MethodDefinition = {"bar"}
46+
}
47+
),$scriptMethod.Evaluate(
48+
@{
49+
MethodName = 'baz'
50+
MethodDefinition = {"baz"}
51+
}
52+
))
53+
})
54+
)
55+
#>
56+
[ValidatePattern('\.ps1xml$')]
57+
param(
58+
# The command information. This will include the path to the file.
59+
[Parameter(Mandatory,ValueFromPipeline,ParameterSetName='TemplateFile')]
60+
[Management.Automation.CommandInfo]
61+
$CommandInfo,
62+
63+
# If set, will return the information required to dynamically apply this template to any text.
64+
[Parameter(Mandatory,ParameterSetName='TemplateObject')]
65+
[switch]
66+
$AsTemplateObject,
67+
68+
# A dictionary of parameters.
69+
[Collections.IDictionary]
70+
$Parameter,
71+
72+
# A list of arguments.
73+
[PSObject[]]
74+
$ArgumentList
75+
)
76+
77+
begin {
78+
# We start off by declaring a number of regular expressions:
79+
$startComment = '<\!--' # * Start Comments ```<!--```
80+
$endComment = '-->' # * End Comments ```-->```
81+
$Whitespace = '[\s\n\r]{0,}'
82+
# * StartRegex ```$StartComment + '{' + $Whitespace```
83+
$startRegex = "(?<PSStart>${startComment}\{$Whitespace)"
84+
# * EndRegex ```$whitespace + '}' + $EndComment```
85+
$endRegex = "(?<PSEnd>$Whitespace\}${endComment}\s{0,})"
86+
87+
# Create a splat containing arguments to the core inline transpiler
88+
$Splat = [Ordered]@{
89+
StartPattern = $startRegex
90+
EndPattern = $endRegex
91+
}
92+
}
93+
94+
process {
95+
# If we have been passed a command
96+
if ($CommandInfo) {
97+
# add parameters related to the file.
98+
$Splat.SourceFile = $commandInfo.Source -as [IO.FileInfo]
99+
$Splat.SourceText = [IO.File]::ReadAllText($commandInfo.Source)
100+
}
101+
102+
if ($Parameter) { $splat.Parameter = $Parameter }
103+
if ($ArgumentList) { $splat.ArgumentList = $ArgumentList }
104+
105+
$splat.ForeachObject = {
106+
$in = $_
107+
if (($in -is [string]) -or
108+
($in.GetType -and $in.GetType().IsPrimitive)) {
109+
$in
110+
} elseif ($in.ChildNodes) {
111+
foreach ($inChildNode in $in.ChildNodes) {
112+
if ($inChildNode.NodeType -ne 'XmlDeclaration') {
113+
$inChildNode.OuterXml
114+
}
115+
}
116+
} else {
117+
$inXml = (ConvertTo-Xml -Depth 100 -InputObject $in)
118+
foreach ($inChildNode in $inXml.ChildNodes) {
119+
if ($inChildNode.NodeType -ne 'XmlDeclaration') {
120+
$inChildNode.OuterXml
121+
}
122+
}
123+
}
124+
}
125+
126+
# If we are being used within a keyword,
127+
if ($AsTemplateObject) {
128+
$splat # output the parameters we would use to evaluate this file.
129+
} else {
130+
# Otherwise, call the core template transpiler
131+
.>PipeScript.Template @Splat # and output the changed file.
132+
}
133+
}

Transpilers/Templates/SVG.template.psx.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
'
1515
}
1616
17-
$starsTemplate.SaveTemplate("$pwd\Stars.svg")
17+
$starsTemplate.Save("$pwd\Stars.svg")
1818
#>
1919
[ValidatePattern('\.svg$')]
2020
param(

Transpilers/Templates/XML.Template.psx.ps1

Lines changed: 1 addition & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5,55 +5,8 @@
55
Allows PipeScript to generate XML.
66
77
Multiline comments blocks like this ```<!--{}-->``` will be treated as blocks of PipeScript.
8-
.EXAMPLE
9-
$typesFile, $typeDefinition, $scriptMethod = Invoke-PipeScript {
10-
11-
types.ps1xml template '
12-
<Types>
13-
<!--{param([Alias("TypeDefinition")]$TypeDefinitions) $TypeDefinitions }-->
14-
</Types>
15-
'
16-
17-
typeDefinition.ps1xml template '
18-
<Type>
19-
<!--{param([Alias("PSTypeName")]$TypeName) "<Name>$($typename)</Name>" }-->
20-
<!--{param([Alias("PSMembers","Member")]$Members) "<Members>$($members)</Members>" }-->
21-
</Type>
22-
'
23-
24-
scriptMethod.ps1xml template '
25-
<ScriptMethod>
26-
<!--{param([Alias("Name")]$MethodName) "<Name>$($MethodName)</Name>" }-->
27-
<!--{param([ScriptBlock]$MethodDefinition) "<Script>$([Security.SecurityElement]::Escape("$MethodDefinition"))</Script>" }-->
28-
</ScriptMethod>
29-
'
30-
}
31-
32-
33-
$typesFile.Save("Test.types.ps1xml",
34-
$typeDefinition.Evaluate(@{
35-
TypeName='foobar'
36-
Members =
37-
@($scriptMethod.Evaluate(
38-
@{
39-
MethodName = 'foo'
40-
MethodDefinition = {"foo"}
41-
}
42-
),$scriptMethod.Evaluate(
43-
@{
44-
MethodName = 'bar'
45-
MethodDefinition = {"bar"}
46-
}
47-
),$scriptMethod.Evaluate(
48-
@{
49-
MethodName = 'baz'
50-
MethodDefinition = {"baz"}
51-
}
52-
))
53-
})
54-
)
558
#>
56-
[ValidatePattern('\.(?>xml|xaml|ps1xml)$')]
9+
[ValidatePattern('\.xml$')]
5710
param(
5811
# The command information. This will include the path to the file.
5912
[Parameter(Mandatory,ValueFromPipeline,ParameterSetName='TemplateFile')]

0 commit comments

Comments
 (0)