diff --git a/CHANGELOG.md b/CHANGELOG.md index d8a2f08bd..d3d935b63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ +## 0.0.8: +* New Commands: + * New-PipeScript (#94) + * Search-PipeScript (#115) +* New Transpilers: + * REST (#114) + * Inline.Kotlin (#110) +* Bugfixes and improvements: + * Fixing Help Generation (#56) + * Anchoring match for Get-Transpiler (#109) + * Core Inline Transpiler Cleanup (#111) + * Shared Context within Inline Transpilers (#112) + * Fixing Include Transpiler Pattern (#96) + * Join-PipeScript interactive .Substring error (#116) +--- + ## 0.0.7: * Syntax Improvements: * Support for Dot Notation (#107) diff --git a/Formatting/Search.PipeScript.Result.format.ps1 b/Formatting/Search.PipeScript.Result.format.ps1 new file mode 100644 index 000000000..d3aef8ef0 --- /dev/null +++ b/Formatting/Search.PipeScript.Result.format.ps1 @@ -0,0 +1 @@ +Write-FormatView -TypeName Search.PipeScript.Result -GroupByProperty InputObject -Property Result, Expression diff --git a/Get-Transpiler.ps1 b/Get-Transpiler.ps1 index 26fd8e275..6063d2e30 100644 --- a/Get-Transpiler.ps1 +++ b/Get-Transpiler.ps1 @@ -1,7 +1,7 @@ #region Piecemeal [ 0.3.2 ] : Easy Extensible Plugins for PowerShell # Install-Module Piecemeal -Scope CurrentUser # Import-Module Piecemeal -Force -# Install-Piecemeal -ExtensionNoun 'Transpiler' -ExtensionPattern '\.psx\.ps1' -ExtensionTypeName 'PipeScript.Transpiler' -OutputPath '.\Get-Transpiler.ps1' +# Install-Piecemeal -ExtensionNoun 'Transpiler' -ExtensionPattern '\.psx\.ps1$' -ExtensionTypeName 'PipeScript.Transpiler' -OutputPath '.\Get-Transpiler.ps1' function Get-Transpiler { <# @@ -170,7 +170,7 @@ function Get-Transpiler ) begin { - $TranspilerPattern = '\.psx\.ps1' + $TranspilerPattern = '\.psx\.ps1$' $TranspilerTypeName = 'PipeScript.Transpiler' #region Define Inner Functions function WhereExtends { diff --git a/Invoke-PipeScript.ps1 b/Invoke-PipeScript.ps1 index d61a12445..3b18897a2 100644 --- a/Invoke-PipeScript.ps1 +++ b/Invoke-PipeScript.ps1 @@ -497,7 +497,10 @@ elseif ($script:TypeAcceleratorsList -notcontains $transpilerStepName -and $transpilerStepName -notin 'Ordered') { $psCmdlet.WriteError( [Management.Automation.ErrorRecord]::new( - [exception]::new("Unable to find a transpiler for [$TranspilerStepName]") + [exception]::new("Unable to find a transpiler for [$TranspilerStepName]"), + 'Transpiler.Not.Found', + 'ParserError', + $command ) ) diff --git a/Join-PipeScript.ps1 b/Join-PipeScript.ps1 index 5120a5246..767d9a060 100644 --- a/Join-PipeScript.ps1 +++ b/Join-PipeScript.ps1 @@ -120,7 +120,8 @@ function Join-PipeScript if ($BlockType -contains 'param') { foreach ($combined in $AllScriptBlocks.Ast.ParamBlock) { if (-not $combined.Parent.Extent) { continue } - $combined.Parent.Extent.ToString().Substring(0, $combined.Extent.StartOffset) + $offsetDifference = $combined.Extent.StartOffset - $combined.Parent.Extent.StartOffset + $combined.Parent.Extent.ToString().Substring(0, $offsetDifference) -replace '^[\r\n]+\{' } } # Start the param block diff --git a/New-PipeScript.ps1 b/New-PipeScript.ps1 new file mode 100644 index 000000000..d314b7649 --- /dev/null +++ b/New-PipeScript.ps1 @@ -0,0 +1,245 @@ +function New-PipeScript { + <# + .Synopsis + Creates new PipeScript. + .Description + Creates new PipeScript and PowerShell ScriptBlocks. + .EXAMPLE + New-PipeScript -Parameter @{a='b'} + #> + [Alias('New-ScriptBlock')] + param( + # Defines one or more parameters for a ScriptBlock. + # Parameters can be defined in a few ways: + # * As a ```[Collections.Dictionary]``` of Parameters + # * As the ```[string]``` name of an untyped parameter. + # * As an ```[Object[]]```. + # * As a ```[ScriptBlock]``` + [Parameter(ValueFromPipelineByPropertyName)] + [ValidateScript({ + $validTypeList = [System.Collections.IDictionary],[System.String],[System.Object[]],[System.Management.Automation.ScriptBlock] + $thisType = $_.GetType() + $IsTypeOk = + $(@( foreach ($validType in $validTypeList) { + if ($_ -as $validType) { + $true;break + } + })) + if (-not $isTypeOk) { + throw "Unexpected type '$(@($thisType)[0])'. Must be 'System.Collections.IDictionary','string','System.Object[]','scriptblock'." + } + return $true + })] + + $Parameter, + + # The dynamic parameter block. + [Parameter(ValueFromPipelineByPropertyName)] + [ValidateScript({ + if ($_.Ast.DynamicParamBlock -or $_.Ast.BeginBlock -or $_.Ast.ProcessBlock) { + throw "ScriptBlock should not have any named blocks" + } + return $true + })] + [ValidateScript({ + if ($_.Ast.ParamBlock.Parameters.Count) { + throw "ScriptBlock should not have parameters" + } + return $true + })] + [Alias('DynamicParameterBlock')] + [ScriptBlock] + $DynamicParameter, + # The begin block. + [Parameter(ValueFromPipelineByPropertyName)] + [ValidateScript({ + if ($_.Ast.DynamicParamBlock -or $_.Ast.BeginBlock -or $_.Ast.ProcessBlock) { + throw "ScriptBlock should not have any named blocks" + } + return $true + })] + [ValidateScript({ + if ($_.Ast.ParamBlock.Parameters.Count) { + throw "ScriptBlock should not have parameters" + } + return $true + })] + [Alias('BeginBlock')] + [ScriptBlock] + $Begin, + # The process block. + [Parameter(ValueFromPipelineByPropertyName)] + [ValidateScript({ + if ($_.Ast.DynamicParamBlock -or $_.Ast.BeginBlock -or $_.Ast.ProcessBlock) { + throw "ScriptBlock should not have any named blocks" + } + return $true + })] + [ValidateScript({ + if ($_.Ast.ParamBlock.Parameters.Count) { + throw "ScriptBlock should not have parameters" + } + return $true + })] + [Alias('ProcessBlock')] + [ScriptBlock] + $Process, + # The end block. + [Parameter(ValueFromPipelineByPropertyName)] + [ValidateScript({ + if ($_.Ast.DynamicParamBlock -or $_.Ast.BeginBlock -or $_.Ast.ProcessBlock) { + throw "ScriptBlock should not have any named blocks" + } + return $true + })] + [ValidateScript({ + if ($_.Ast.ParamBlock.Parameters.Count) { + throw "ScriptBlock should not have parameters" + } + return $true + })] + [Alias('EndBlock')] + [ScriptBlock] + $End, + + # The script header. + [Parameter(ValueFromPipelineByPropertyName)] + [string] + $Header + ) + begin { + $ParametersToCreate = [Ordered]@{} + $allDynamicParameters = @() + $allBeginBlocks = @() + $allEndBlocks = @() + $allProcessBlocks = @() + $allHeaders = @() + } + process { + if ($parameter) { + # The -Parameter can be a dictionary of parameters. + if ($Parameter -is [Collections.IDictionary]) { + $parameterType = '' + # If it is, walk thur each parameter in the dictionary + foreach ($EachParameter in $Parameter.GetEnumerator()) { + # Continue past any parameters we already have + if ($ParametersToCreate.Contains($EachParameter.Key)) { + continue + } + # If the parameter is a string and the value is not a variable + if ($EachParameter.Value -is [string] -and $EachParameter.Value -notlike '*$*') { + $parameterName = $EachParameter.Key + $ParametersToCreate[$EachParameter.Key] = + @( + $parameterAttribute = "[Parameter(ValueFromPipelineByPropertyName)]" + $parameterType + '$' + $parameterName + ) -ne '' + } + # If the value is a string and the value contains variables + elseif ($EachParameter.Value -is [string]) { + # embed it directly. + $ParametersToCreate[$EachParameter.Key] = $EachParameter.Value + } + # If the value is a ScriptBlock + elseif ($EachParameter.Value -is [ScriptBlock]) { + # Embed it + $ParametersToCreate[$EachParameter.Key] = + # If there was a param block on the script block + if ($EachParameter.Value.Ast.ParamBlock) { + # embed the parameter block (except for the param keyword) + $EachParameter.Value.Ast.ParamBlock.Extent.ToString() -replace + '^[\s\r\n]param(' -replace ')[\s\r\n]$' + } else { + # Otherwise + $EachParameter.Value.ToString() -replace + "\`$$($eachParameter.Key)[\s\r\n]$" -replace # Replace any trailing variables + 'param()[\s\r\n]{0,}$' # then replace any empty param blocks. + } + } + elseif ($EachParameter.Value -is [Object[]]) { + $ParametersToCreate[$EachParameter.Key] = + $EachParameter.Value -join [Environment]::Newline + } + } + } elseif ($Parameter -is [string]) { + $ParametersToCreate[$Parameter] = @( + "[Parameter(ValueFromPipelineByPropertyName)]" + "`$$Parameter" + ) + } elseif ($Parameter -is [Object[]]) { + $currentParam = @() + $currentParamName = '' + foreach ($EachParameter in $Parameter) { + if ($EachParameter -is [string] -and -not $EachParameter.Contains(' ')) { + if ($currentParam) { + $ParametersToCreate[$currentParamName] = $currentParam + $currentParam = @() + $currentParamName = '' + } + $currentParam += "`$$EachParameter" + $currentParamName = $EachParameter + } elseif ($EachParameter -is [string] -and $EachParameter.Contains(' ')) { + $currentParam = @( + if ($EachParameter.Contains("`n")) { + "<#" + [Environment]::newLine + $EachParameter + [Environment]::newLine + '#>' + } else { + "# $EachParameter" + } + ) + $currentParam + } elseif ($EachParameter -is [type]) { + $currentParam += "[$($EachParameter.Fullname)]" + } + } + if ($currentParamName) { + $ParametersToCreate[$currentParamName] = $currentParam + } + } + } + if ($header) { + $allHeaders += $Header + } + if ($DynamicParameter) { + $allDynamicParameters += $DynamicParameter + } + if ($Begin) { + $allBeginBlocks += $begin + } + if ($process) { + $allProcessBlocks += $process + } + if ($end) { + $allEndBlocks += $end + } + + } + end { + $newParamBlock = + "param(" + [Environment]::newLine + + $(@(foreach ($toCreate in $ParametersToCreate.GetEnumerator()) { + $toCreate.Value -join [Environment]::NewLine + }) -join (',' + [Environment]::NewLine)) + + [Environment]::NewLine + + ')' + $createdScriptBlock = [scriptblock]::Create(" +$($allHeaders -join [Environment]::Newline) +$newParamBlock +$(if ($allDynamicParameters) { + @(@("dynamicParam {") + $allDynamicParameters + '}') -join [Environment]::Newline +}) +$(if ($allBeginBlocks) { + @(@("begin {") + $allBeginBlocks + '}') -join [Environment]::Newline +}) +$(if ($allProcessBlocks) { + @(@("process {") + $allProcessBlocks + '}') -join [Environment]::Newline +}) +$(if ($allEndBlocks -and -not $allBeginBlocks -and -not $allProcessBlocks) { + $allEndBlocks -join [Environment]::Newline +} elseif ($allEndBlocks) { + @(@("end {") + $allEndBlocks + '}') -join [Environment]::Newline +}) +") + $createdScriptBlock + } +} + diff --git a/New-PipeScript.ps1.ps1 b/New-PipeScript.ps1.ps1 new file mode 100644 index 000000000..8c0d39fd6 --- /dev/null +++ b/New-PipeScript.ps1.ps1 @@ -0,0 +1,200 @@ +function New-PipeScript +{ + <# + .Synopsis + Creates new PipeScript. + .Description + Creates new PipeScript and PowerShell ScriptBlocks. + .EXAMPLE + New-PipeScript -Parameter @{a='b'} + #> + [Alias('New-ScriptBlock')] + param( + # Defines one or more parameters for a ScriptBlock. + # Parameters can be defined in a few ways: + # * As a ```[Collections.Dictionary]``` of Parameters + # * As the ```[string]``` name of an untyped parameter. + # * As an ```[Object[]]```. + # * As a ```[ScriptBlock]``` + [Parameter(ValueFromPipelineByPropertyName)] + [ValidateTypes(TypeName={[Collections.IDictionary], [string],[Object[]], [Scriptblock]})] + $Parameter, + + # The dynamic parameter block. + [Parameter(ValueFromPipelineByPropertyName)] + [ValidateScriptBlock(NoBlocks, NoParameters)] + [Alias('DynamicParameterBlock')] + [ScriptBlock] + $DynamicParameter, + + # The begin block. + [Parameter(ValueFromPipelineByPropertyName)] + [ValidateScriptBlock(NoBlocks, NoParameters)] + [Alias('BeginBlock')] + [ScriptBlock] + $Begin, + + # The process block. + [Parameter(ValueFromPipelineByPropertyName)] + [ValidateScriptBlock(NoBlocks, NoParameters)] + [Alias('ProcessBlock')] + [ScriptBlock] + $Process, + + # The end block. + [Parameter(ValueFromPipelineByPropertyName)] + [ValidateScriptBlock(NoBlocks, NoParameters)] + [Alias('EndBlock')] + [ScriptBlock] + $End, + + # The script header. + [Parameter(ValueFromPipelineByPropertyName)] + [string] + $Header + ) + + begin { + $ParametersToCreate = [Ordered]@{} + $allDynamicParameters = @() + $allBeginBlocks = @() + $allEndBlocks = @() + $allProcessBlocks = @() + $allHeaders = @() + } + + process { + if ($parameter) { + # The -Parameter can be a dictionary of parameters. + if ($Parameter -is [Collections.IDictionary]) { + $parameterType = '' + # If it is, walk thur each parameter in the dictionary + foreach ($EachParameter in $Parameter.GetEnumerator()) { + # Continue past any parameters we already have + if ($ParametersToCreate.Contains($EachParameter.Key)) { + continue + } + # If the parameter is a string and the value is not a variable + if ($EachParameter.Value -is [string] -and $EachParameter.Value -notlike '*$*') { + $parameterName = $EachParameter.Key + $ParametersToCreate[$EachParameter.Key] = + @( + $parameterAttribute = "[Parameter(ValueFromPipelineByPropertyName)]" + $parameterType + '$' + $parameterName + ) -ne '' + } + # If the value is a string and the value contains variables + elseif ($EachParameter.Value -is [string]) { + # embed it directly. + $ParametersToCreate[$EachParameter.Key] = $EachParameter.Value + } + # If the value is a ScriptBlock + elseif ($EachParameter.Value -is [ScriptBlock]) { + # Embed it + $ParametersToCreate[$EachParameter.Key] = + # If there was a param block on the script block + if ($EachParameter.Value.Ast.ParamBlock) { + # embed the parameter block (except for the param keyword) + $EachParameter.Value.Ast.ParamBlock.Extent.ToString() -replace + '^[\s\r\n]param(' -replace ')[\s\r\n]$' + } else { + # Otherwise + $EachParameter.Value.ToString() -replace + "\`$$($eachParameter.Key)[\s\r\n]$" -replace # Replace any trailing variables + 'param()[\s\r\n]{0,}$' # then replace any empty param blocks. + } + } + elseif ($EachParameter.Value -is [Object[]]) { + $ParametersToCreate[$EachParameter.Key] = + $EachParameter.Value -join [Environment]::Newline + } + } + } elseif ($Parameter -is [string]) { + $ParametersToCreate[$Parameter] = @( + "[Parameter(ValueFromPipelineByPropertyName)]" + "`$$Parameter" + ) + } elseif ($Parameter -is [Object[]]) { + $currentParam = @() + $currentParamName = '' + foreach ($EachParameter in $Parameter) { + if ($EachParameter -is [string] -and -not $EachParameter.Contains(' ')) { + if ($currentParam) { + $ParametersToCreate[$currentParamName] = $currentParam + $currentParam = @() + $currentParamName = '' + } + $currentParam += "`$$EachParameter" + $currentParamName = $EachParameter + } elseif ($EachParameter -is [string] -and $EachParameter.Contains(' ')) { + $currentParam = @( + if ($EachParameter.Contains("`n")) { + "<#" + [Environment]::newLine + $EachParameter + [Environment]::newLine + '#>' + } else { + "# $EachParameter" + } + ) + $currentParam + } elseif ($EachParameter -is [type]) { + $currentParam += "[$($EachParameter.Fullname)]" + } + } + if ($currentParamName) { + $ParametersToCreate[$currentParamName] = $currentParam + } + } + } + + if ($header) { + $allHeaders += $Header + } + + if ($DynamicParameter) { + $allDynamicParameters += $DynamicParameter + } + + if ($Begin) { + $allBeginBlocks += $begin + } + + if ($process) { + $allProcessBlocks += $process + } + + if ($end) { + $allEndBlocks += $end + } + + } + + end { + $newParamBlock = + "param(" + [Environment]::newLine + + $(@(foreach ($toCreate in $ParametersToCreate.GetEnumerator()) { + $toCreate.Value -join [Environment]::NewLine + }) -join (',' + [Environment]::NewLine)) + + [Environment]::NewLine + + ')' + + + $createdScriptBlock = [scriptblock]::Create(" +$($allHeaders -join [Environment]::Newline) +$newParamBlock +$(if ($allDynamicParameters) { + @(@("dynamicParam {") + $allDynamicParameters + '}') -join [Environment]::Newline +}) +$(if ($allBeginBlocks) { + @(@("begin {") + $allBeginBlocks + '}') -join [Environment]::Newline +}) +$(if ($allProcessBlocks) { + @(@("process {") + $allProcessBlocks + '}') -join [Environment]::Newline +}) +$(if ($allEndBlocks -and -not $allBeginBlocks -and -not $allProcessBlocks) { + $allEndBlocks -join [Environment]::Newline +} elseif ($allEndBlocks) { + @(@("end {") + $allEndBlocks + '}') -join [Environment]::Newline +}) +") + $createdScriptBlock + } +} diff --git a/PipeScript.HelpOut.ps1 b/PipeScript.HelpOut.ps1 index 782bdd075..0628c68ad 100644 --- a/PipeScript.HelpOut.ps1 +++ b/PipeScript.HelpOut.ps1 @@ -11,6 +11,8 @@ if ($PipeScriptLoaded) { "::error:: PipeScript not loaded" |Out-Host } -Save-MarkdownHelp -Module PipeScript -ReplaceScriptName '\.psx\.ps1$' -ReplaceScriptNameWith '-Transpiler' -SkipCommandType Alias -PassThru -IncludeTopic *.help.txt -IncludeExtension @() -ScriptPath '\.psx\.ps1$' +Save-MarkdownHelp -Module PipeScript <#-ReplaceScriptName '\.psx\.ps1$' -ReplaceScriptNameWith '-Transpiler'#> -SkipCommandType Alias -PassThru -IncludeTopic *.help.txt -IncludeExtension @( + +) -Command (Get-Transpiler) -ReplaceCommandName '\.psx\.ps1$' Pop-Location \ No newline at end of file diff --git a/PipeScript.Piecemeal.ps1 b/PipeScript.Piecemeal.ps1 index 828b1a76c..ea96380f1 100644 --- a/PipeScript.Piecemeal.ps1 +++ b/PipeScript.Piecemeal.ps1 @@ -1,7 +1,7 @@ #require -Module Piecemeal Push-Location $PSScriptRoot -Install-Piecemeal -ExtensionNoun 'Transpiler' -ExtensionPattern '\.psx\.ps1' -ExtensionTypeName 'PipeScript.Transpiler' -OutputPath '.\Get-Transpiler.ps1' +Install-Piecemeal -ExtensionNoun 'Transpiler' -ExtensionPattern '\.psx\.ps1$' -ExtensionTypeName 'PipeScript.Transpiler' -OutputPath '.\Get-Transpiler.ps1' Install-Piecemeal -ExtensionNoun 'PipeScript' -ExtensionPattern '\.psx\.ps1{0,1}$','\.ps1{0,1}\.(?[^.]+$)','\.ps1{0,1}$' -ExtensionTypeName 'PipeScript' -OutputPath '.\Get-PipeScript.ps1' diff --git a/PipeScript.format.ps1xml b/PipeScript.format.ps1xml index 932e931f3..2b255cd37 100644 --- a/PipeScript.format.ps1xml +++ b/PipeScript.format.ps1xml @@ -233,6 +233,35 @@ + + Search.PipeScript.Result + + Search.PipeScript.Result + + + InputObject + + + + + + + + + + + + + Result + + + Expression + + + + + + diff --git a/PipeScript.psd1 b/PipeScript.psd1 index 9a6304ca1..d10a30656 100644 --- a/PipeScript.psd1 +++ b/PipeScript.psd1 @@ -1,5 +1,5 @@ @{ - ModuleVersion = '0.0.7' + ModuleVersion = '0.0.8' Description = 'An Extensible Transpiler for PowerShell (and anything else)' RootModule = 'PipeScript.psm1' PowerShellVersion = '4.0' @@ -17,6 +17,22 @@ Tags = 'PipeScript','PowerShell', 'Transpilation', 'Compiler' ReleaseNotes = @' +## 0.0.8: +* New Commands: + * New-PipeScript (#94) + * Search-PipeScript (#115) +* New Transpilers: + * REST (#114) + * Inline.Kotlin (#110) +* Bugfixes and improvements: + * Fixing Help Generation (#56) + * Anchoring match for Get-Transpiler (#109) + * Core Inline Transpiler Cleanup (#111) + * Shared Context within Inline Transpilers (#112) + * Fixing Include Transpiler Pattern (#96) + * Join-PipeScript interactive .Substring error (#116) +--- + ## 0.0.7: * Syntax Improvements: * Support for Dot Notation (#107) diff --git a/PipeScript.psm1 b/PipeScript.psm1 index a503f727e..dcdd3e40c 100644 --- a/PipeScript.psm1 +++ b/PipeScript.psm1 @@ -1,6 +1,6 @@ foreach ($file in (Get-ChildItem -Path "$psScriptRoot" -Filter "*-*" -Recurse)) { if ($file.Extension -ne '.ps1') { continue } # Skip if the extension is not .ps1 - if ($file.Name -match '\.[^\.]\.ps1$') { continue } # Skip if the file is an unrelated file. + if ($file.Name -match '\.[^\.]+\.ps1$') { continue } # Skip if the file is an unrelated file. . $file.FullName } diff --git a/Search-PipeScript.ps1 b/Search-PipeScript.ps1 new file mode 100644 index 000000000..04bdef44b --- /dev/null +++ b/Search-PipeScript.ps1 @@ -0,0 +1,241 @@ +function Search-PipeScript { + <# + .Synopsis + Searches PowerShell and PipeScript ScriptBlocks + .Description + Searches PowerShell and PipeScript ScriptBlocks, files, and text + .Example + Search-PipeScript -ScriptBlock { + $a + $b + $c + "text" + } -AstType Variable + .LINK + Update-PipeScript + #> + [OutputType('Search.PipeScript.Result')] + [Alias('Search-ScriptBlock')] + param( + # The ScriptBlock that will be searched. + [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)] + [Alias('ScriptBlock','Text')] + [ValidateScript({ + $validTypeList = [System.String],[System.Management.Automation.ScriptBlock],[System.IO.FileInfo] + $thisType = $_.GetType() + $IsTypeOk = + $(@( foreach ($validType in $validTypeList) { + if ($_ -as $validType) { + $true;break + } + })) + if (-not $isTypeOk) { + throw "Unexpected type '$(@($thisType)[0])'. Must be 'string','scriptblock','System.IO.FileInfo'." + } + return $true + })] + + $InputObject, + # The AST Condition. + # These Script Blocks + [Parameter(ValueFromPipelineByPropertyName)] + [Alias('ASTDelegate')] + [ScriptBlock[]] + $AstCondition, + # A shortname for the abstract syntax tree types. + [Parameter(ValueFromPipelineByPropertyName)] + [ValidateScript({ + $validTypeList = [System.String],[System.Text.RegularExpressions.Regex],[System.String[]],[System.Text.RegularExpressions.Regex[]] + $thisType = $_.GetType() + $IsTypeOk = + $(@( foreach ($validType in $validTypeList) { + if ($_ -as $validType) { + $true;break + } + })) + if (-not $isTypeOk) { + throw "Unexpected type '$(@($thisType)[0])'. Must be 'string','regex','string[]','regex[]'." + } + return $true + })] + + $AstType, + + # One or more regular expressions to match. + [Parameter(ValueFromPipelineByPropertyName)] + [Alias('RegEx')] + [ValidateScript({ + $validTypeList = [System.String],[System.Text.RegularExpressions.Regex],[System.String[]],[System.Text.RegularExpressions.Regex[]] + $thisType = $_.GetType() + $IsTypeOk = + $(@( foreach ($validType in $validTypeList) { + if ($_ -as $validType) { + $true;break + } + })) + if (-not $isTypeOk) { + throw "Unexpected type '$(@($thisType)[0])'. Must be 'string','regex','string[]','regex[]'." + } + return $true + })] + + $RegularExpression, + # If set, will search nested script blocks. + [Alias('SearchNestedScriptBlock')] + [switch] + $Recurse + ) + process { + $ScriptBlock = $null + $Text = $null + # If the input was a file + if ($InputObject -is [IO.FileInfo]) { + $inputCommand = # get the resolved command + $ExecutionContext.SessionState.InvokeCommand.GetCommand( + $InputObject.Fullname, 'ExternalScript,Application') + # If the command was an external script + if ($inputCommand -is [Management.Automation.ExternalScriptInfo]) { + # Use it's ScriptBlock + $ScriptBlock = $inputCommand.ScriptBlock + } + # If the command was an application, and it looks like PipeScript + elseif ( + $inputCommand -is [Management.Automation.ApplicationInfo] -and + $inputCommand.Source -match '\.ps$' + ) { + # Load the file text + $text = [IO.File]::ReadAllText($inputCommand.Source) + # and create a script block. + $scriptBlock = [ScriptBlock]::Create($text) + } + # Otherwise + else + { + # Read the file contents as text. + $text = [IO.File]::ReadAllText($inputCommand.Source) + } + } + # If the inputObject was a [ScriptBlock] + if ($InputObject -is [scriptblock]) { + $scriptBlock = $InputObject # set $ScriptBlock + } + # If the InputObject is a string + if ($InputObject -is [string]) { + $Text = $InputObject # set $Text. + } + # If we have a ScriptBlock + if ($scriptBlock) { + # Reset $text to the ScriptBlock contents. + $Text = "$scriptBlock" + # If we have an ASTType to find + if ($AstType) { + foreach ($astTypeName in $AstType) { + # See if it's a real type + $realAstType = + foreach ($potentialType in $AstType, + "Management.Automation.Language.$AstType", + "Management.Automation.Language.${AstType}AST" + ) { + if ($potentialType -as [type]) { + $potentialType -as [type]; break + } + } + + # If it was a real type, but in the wrong namespace + if ($realAstType -and $realAstType.Namespace -eq 'Management.Automation.Language') { + Write-Error "'$astType' is not an AST type" # error and continue. + continue + } + # Set the search condition + $condition = + if ($realAstType) { + # If there was a real type, search for it. + [ScriptBlock]::Create('param($ast) $ast -is [' + $realAstType.FullName + ']') + } + elseif ($astType -is [Regex]) { + [scriptblock]::Create(( + 'param($ast) + $ast.GetType().Name -match ([Regex]::New(' + + $astType.ToString().Replace("'", "''") + "','" + + $astType.Options + "','" + + $(if ($AstType.MatchTimeout -lt 0) { + '00:00:05' + } else { + $AstType.MatchTimeout.ToString() + }) + '))' + )) + } + elseif ($astType -as [regex]) { + [ScriptBlock]::Create('param($ast) $ast.GetType().Name -match "'+ $astType +'"') + } else { + [ScriptBlock]::Create('param($ast) $ast.GetType().Name -like "*' + $astType +'*"') + } + + # Add this condition to the list of conditions. + $AstCondition += $condition + } + } + # If we have any AST conditions + if ($AstCondition) { + foreach ($condition in $AstCondition) { + # Find all of the results. + $ScriptBlock.Ast.FindAll($condition, ($Recurse -as [bool])) | + & { process { + $in = $this = $_ + [PSCustomObject][Ordered]@{ + 'InputObject' = + $inputObject + 'Result' = + & { + $_ + } + 'Expression' = + $condition + 'ScriptBlock' = + & { + $ScriptBlock + } + 'PSTypeName' = + "Search.PipeScript.Result" + } + } } + } + } + } + if ($text) { + if ($RegularExpression) { + foreach ($regex in $RegularExpression) { + $realRegex = + if ($regex -is [regex]) { + $regex + } else { + [Regex]::new($regex) + } + + $realRegex.Matches($text) | + & { process { + $in = $this = $_ + [PSCustomObject][Ordered]@{ + 'InputObject' = + $InputObject + 'Result' = + & { + $_ + } + 'Expression' = + $realRegex + 'RegularExpression' = + & { + $realRegex + } + 'PSTypeName' = + "Search.PipeScript.Result" + } + } } + } + } + } + } +} + + diff --git a/Search-PipeScript.ps1.ps1 b/Search-PipeScript.ps1.ps1 new file mode 100644 index 000000000..c57235018 --- /dev/null +++ b/Search-PipeScript.ps1.ps1 @@ -0,0 +1,183 @@ +function Search-PipeScript +{ + <# + .Synopsis + Searches PowerShell and PipeScript ScriptBlocks + .Description + Searches PowerShell and PipeScript ScriptBlocks, files, and text + .Example + Search-PipeScript -ScriptBlock { + $a + $b + $c + "text" + } -AstType Variable + .LINK + Update-PipeScript + #> + [OutputType('Search.PipeScript.Result')] + [Alias('Search-ScriptBlock')] + param( + # The ScriptBlock that will be searched. + [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)] + [Alias('ScriptBlock','Text')] + [ValidateTypes(TypeName={[string], [scriptblock],[IO.FileInfo]})] + $InputObject, + + # The AST Condition. + # These Script Blocks + [Parameter(ValueFromPipelineByPropertyName)] + [Alias('ASTDelegate')] + [ScriptBlock[]] + $AstCondition, + + # A shortname for the abstract syntax tree types. + [Parameter(ValueFromPipelineByPropertyName)] + [ValidateTypes(TypeName={[string], [Regex], [string[]], [regex[]]})] + $AstType, + + # One or more regular expressions to match. + [Parameter(ValueFromPipelineByPropertyName)] + [Alias('RegEx')] + [ValidateTypes(TypeName={[string], [Regex], [string[]], [regex[]]})] + $RegularExpression, + + # If set, will search nested script blocks. + [Alias('SearchNestedScriptBlock')] + [switch] + $Recurse + ) + + process { + $ScriptBlock = $null + $Text = $null + + # If the input was a file + if ($InputObject -is [IO.FileInfo]) { + $inputCommand = # get the resolved command + $ExecutionContext.SessionState.InvokeCommand.GetCommand( + $InputObject.Fullname, 'ExternalScript,Application') + # If the command was an external script + if ($inputCommand -is [Management.Automation.ExternalScriptInfo]) { + # Use it's ScriptBlock + $ScriptBlock = $inputCommand.ScriptBlock + } + # If the command was an application, and it looks like PipeScript + elseif ( + $inputCommand -is [Management.Automation.ApplicationInfo] -and + $inputCommand.Source -match '\.ps$' + ) { + # Load the file text + $text = [IO.File]::ReadAllText($inputCommand.Source) + # and create a script block. + $scriptBlock = [ScriptBlock]::Create($text) + } + # Otherwise + else + { + # Read the file contents as text. + $text = [IO.File]::ReadAllText($inputCommand.Source) + } + } + + # If the inputObject was a [ScriptBlock] + if ($InputObject -is [scriptblock]) { + $scriptBlock = $InputObject # set $ScriptBlock + } + + # If the InputObject is a string + if ($InputObject -is [string]) { + $Text = $InputObject # set $Text. + } + + # If we have a ScriptBlock + if ($scriptBlock) { + # Reset $text to the ScriptBlock contents. + $Text = "$scriptBlock" + + # If we have an ASTType to find + if ($AstType) { + foreach ($astTypeName in $AstType) { + # See if it's a real type + $realAstType = + foreach ($potentialType in $AstType, + "Management.Automation.Language.$AstType", + "Management.Automation.Language.${AstType}AST" + ) { + if ($potentialType -as [type]) { + $potentialType -as [type]; break + } + } + + # If it was a real type, but in the wrong namespace + if ($realAstType -and $realAstType.Namespace -eq 'Management.Automation.Language') { + Write-Error "'$astType' is not an AST type" # error and continue. + continue + } + + # Set the search condition + $condition = + if ($realAstType) { + # If there was a real type, search for it. + [ScriptBlock]::Create('param($ast) $ast -is [' + $realAstType.FullName + ']') + } + elseif ($astType -is [Regex]) { + [scriptblock]::Create(( + 'param($ast) + $ast.GetType().Name -match ([Regex]::New(' + + $astType.ToString().Replace("'", "''") + "','" + + $astType.Options + "','" + + $(if ($AstType.MatchTimeout -lt 0) { + '00:00:05' + } else { + $AstType.MatchTimeout.ToString() + }) + '))' + )) + } + elseif ($astType -as [regex]) { + [ScriptBlock]::Create('param($ast) $ast.GetType().Name -match "'+ $astType +'"') + } else { + [ScriptBlock]::Create('param($ast) $ast.GetType().Name -like "*' + $astType +'*"') + } + + # Add this condition to the list of conditions. + $AstCondition += $condition + } + } + + # If we have any AST conditions + if ($AstCondition) { + foreach ($condition in $AstCondition) { + # Find all of the results. + $ScriptBlock.Ast.FindAll($condition, ($Recurse -as [bool])) | + .InputObject = $inputObject .Result { + $_ + } .Expression = $condition .ScriptBlock { + $ScriptBlock + } .PSTypeName = "Search.PipeScript.Result" + } + } + } + + if ($text) { + if ($RegularExpression) { + foreach ($regex in $RegularExpression) { + $realRegex = + if ($regex -is [regex]) { + $regex + } else { + [Regex]::new($regex) + } + + $realRegex.Matches($text) | + .InputObject = $InputObject .Result { + $_ + } .Expression = $realRegex .RegularExpression { + $realRegex + } .PSTypeName = "Search.PipeScript.Result" + } + } + } + } +} + diff --git a/Transpilers/Core/PipeScript.Inline.psx.ps1 b/Transpilers/Core/PipeScript.Inline.psx.ps1 index 38ce81019..d4d76bb59 100644 --- a/Transpilers/Core/PipeScript.Inline.psx.ps1 +++ b/Transpilers/Core/PipeScript.Inline.psx.ps1 @@ -11,24 +11,13 @@ If a Regular Expression can match each section, then the content in each section can be replaced. #> param( -# A list of source sections -[Parameter(Mandatory,ParameterSetName='SourceSections',Position=0,ValueFromPipeline)] -[PSObject[]] -$SourceSection, # A string containing the text contents of the file -[Parameter(Mandatory,ParameterSetName='SourceTextAndPattern')] [Parameter(Mandatory,ParameterSetName='SourceTextReplace')] [Parameter(Mandatory,ParameterSetName='SourceStartAndEnd')] [string] $SourceText, -# A string containing the pattern used to recognize special sections of source code. -[Parameter(Mandatory,ParameterSetName='SourceTextAndPattern')] -[regex] -$SourcePattern, - - [Parameter(Mandatory,ParameterSetName='SourceTextReplace')] [Alias('Replace')] [ValidateScript({ @@ -57,6 +46,9 @@ $StartPattern, [Regex] $EndPattern, +# A custom replacement evaluator. +# If not provided, will run any embedded scripts encountered. +# The output of these scripts will be the replacement text. [Parameter(ParameterSetName='SourceTextReplace')] [Parameter(ParameterSetName='SourceStartAndEnd')] [Alias('Replacer')] @@ -64,32 +56,24 @@ $EndPattern, $ReplacementEvaluator, # If set, will not transpile script blocks. -[Parameter(ParameterSetName='SourceTextAndPattern')] -[Parameter(ParameterSetName='SourceSections')] [Parameter(ParameterSetName='SourceStartAndEnd')] [Parameter(ParameterSetName='SourceTextReplace')] [switch] $NoTranspile, # The path to the source file. -[Parameter(ParameterSetName='SourceTextAndPattern')] -[Parameter(ParameterSetName='SourceSections')] [Parameter(ParameterSetName='SourceTextReplace')] [Parameter(ParameterSetName='SourceStartAndEnd')] [string] $SourceFile, # A Script Block that will be injected before each inline is run. -[Parameter(ParameterSetName='SourceTextAndPattern')] -[Parameter(ParameterSetName='SourceSections')] [Parameter(ParameterSetName='SourceTextReplace')] [Parameter(ParameterSetName='SourceStartAndEnd')] [ScriptBlock] $Begin, # A Script Block that will be piped to after each output. -[Parameter(ParameterSetName='SourceTextAndPattern')] -[Parameter(ParameterSetName='SourceSections')] [Parameter(ParameterSetName='SourceTextReplace')] [Parameter(ParameterSetName='SourceStartAndEnd')] [Alias('Process')] @@ -97,8 +81,6 @@ $Begin, $ForeachObject, # A Script Block that will be injected after each inline script is run. -[Parameter(ParameterSetName='SourceTextAndPattern')] -[Parameter(ParameterSetName='SourceSections')] [Parameter(ParameterSetName='SourceTextReplace')] [Parameter(ParameterSetName='SourceStartAndEnd')] [ScriptBlock] @@ -106,7 +88,7 @@ $End ) begin { - $allSections = @() + $TempModule = New-Module -ScriptBlock { } } process { @@ -194,144 +176,11 @@ process { $codeToRun = [ScriptBlock]::Create($statements -join [Environment]::Newline) - "$(& $codeToRun)" + "$(. $TempModule $codeToRun)" } } return $ReplacePattern.Replace($fileText, $ReplacementEvaluator) } - - if ($psParameterSet -eq 'SourceTextAndPattern') { - - $fileText = $SourceText - $foundSpots = @($SourcePattern.Matches($fileText)) - - $SourceGeneratorInput = @( - $index = 0 - for ($spotIndex = 0; $spotIndex -lt $foundSpots.Count; $spotIndex++) { - - # If there's any distance between the last token and here, output it as a string. - if ($foundSpots[$spotIndex].Index -gt $index) { - $captureLength = $foundSpots[$spotIndex].Index - $index - if ($captureLength -ge 0) { - $fileText.Substring($index, $captureLength) - } - $index = $foundSpots[$spotIndex].Index + $foundSpots[$spotIndex].Length - } - - $isLastSpot = $spotIndex -ge ($foundSpots.Length - 1) - - if ($foundSpots[$spotIndex].Groups["PSStart"].Length) { - $absoluteStart = $foundSpots[$spotIndex].Groups["PSStart"].Index + - $foundSpots[$spotIndex].Groups["PSStart"].Length - - $index = $foundSpots[$spotIndex + 1].Index + - $foundSpots[$spotIndex + 1].Length - if (-not $isLastSpot -and $foundSpots[$spotIndex + 1].Groups["PSEnd"].Length) { - # If we find an end block, the next section becomes code - - $scriptToCreate = @( - if ($Begin) { $Begin } - $AddForeach = - $( - if ($ForeachObject) { - '|' + [Environment]::NewLine - @(foreach ($foreachStatement in $ForeachObject) { - if ($foreachStatement.Ast.ProcessBlock -or $foreachStatement.Ast.BeginBlock) { - ". {$ForeachStatement}" - } elseif ($foreachStatement.Ast.EndBlock.Statements -and - $foreachStatement.Ast.EndBlock.Statements[0].PipelineElements[0].CommandElements -and - $foreachStatement.Ast.EndBlock.Statements[0].PipelineElements[0].CommandElements.Value -in 'Foreach-Object', '%') { - "$ForeachStatement" - } else { - "Foreach-Object {$ForeachStatement}" - } - }) -join (' |' + [Environment]::NewLine) - } - ) - $Statement = $fileText.Substring($absoluteStart, - $index - $absoluteStart - $foundSpots[$spotIndex + 1].Groups["PSEnd"].Length - ) - if ($AddForeach) { - "@($Statement)" + $AddForeach.Trim() - } else { - $Statement - } - - if ($End) { $end} - ) -join [Environment]::Newline - [scriptblock]::Create($scriptToCreate) - - $spotIndex++ - } else { - Write-Error "Start Not Followed By End' $($foundSpots[$spotIndex].Index)'" - } - } - } - - if ($index -lt $fileText.Length) { - $fileText.Substring($index) - } - ) - - $null = $PSBoundParameters.Remove("SourceText") - $null = $PSBoundParameters.Remove("SourcePattern") - - & $myInvocation.MyCommand.ScriptBlock @PSBoundParameters -SourceSection $SourceGeneratorInput - return - } - - $allSections += @( - foreach ($section in $SourceSection) { - - if ($section -is [string]) { - if ($section -match '[\r\n]') { - "@'" + [Environment]::NewLine + $section + [Environment]::newLine + "'@" - } else { - "'" + $section.Replace("'", "''") + "'" - } - } - - if ($section -is [ScriptBlock]) { - if (-not $NoTranspile) { - $section | - .>Pipescript - } else { - $section - } - } - - }) } -end { - if ($allSections) { - - $combinedSections = @(for ($sectionIndex = 0 ; $sectionIndex -lt $allSections.Length; $sectionIndex++) { - $section = $allSections[$sectionIndex] - $isLastSection = $sectionIndex -eq $allSections.Length - 1 - if ($section -is [ScriptBlock]) { - "`$($section)" - } else { - $section - } - if (-not $isLastSection) { - '+' - } - }) - $combinedFile = $combinedSections -join ' ' - - if ($SourceFile -and $SourceFile -match '\.ps1{0,1}\.(?[^.]+$)') { - $sourceTempFilePath = $SourceFile -replace '\.ps1{0,1}\.(?[^.]+$)', '.${ext}.source.ps1' - $combinedFile | Set-Content $sourceTempFilePath -Force - } - - - try { - [scriptblock]::Create($combinedFile) - } catch { - $ex = $_ - Write-Error -ErrorRecord $ex - } - } -} \ No newline at end of file diff --git a/Transpilers/Core/PipeScript.ParameterAttribute.psx.ps1 b/Transpilers/Core/PipeScript.ParameterAttribute.psx.ps1 index 369829fac..0a3d2a59f 100644 --- a/Transpilers/Core/PipeScript.ParameterAttribute.psx.ps1 +++ b/Transpilers/Core/PipeScript.ParameterAttribute.psx.ps1 @@ -1,4 +1,5 @@ <# + #> [ValidateScript({ $_.Parent -is [Management.Automation.Language.ParameterAst] diff --git a/Transpilers/Core/PipeScript.TypeExpression.psx.ps1 b/Transpilers/Core/PipeScript.TypeExpression.psx.ps1 index f3c7c35ba..c430b35f4 100644 --- a/Transpilers/Core/PipeScript.TypeExpression.psx.ps1 +++ b/Transpilers/Core/PipeScript.TypeExpression.psx.ps1 @@ -58,7 +58,7 @@ process { } else { $TypeExpressionAst.TypeName.Name } - + if ($transpilerStepName -eq 'ordered') { return } $foundTranspiler = diff --git a/Transpilers/Include.psx.ps1 b/Transpilers/Include.psx.ps1 index dba1eac9d..54013da00 100644 --- a/Transpilers/Include.psx.ps1 +++ b/Transpilers/Include.psx.ps1 @@ -130,7 +130,7 @@ if ($psCmdlet.ParameterSetName -eq 'ScriptBlock' -or [ScriptBlock]::Create(@" foreach (`$file in (Get-ChildItem -Path "$($VariableAst)" -Filter "$FilePath" -Recurse)) { if (`$file.Extension -ne '.ps1') { continue } # Skip if the extension is not .ps1 - if (`$file.Name -match '\.[^\.]\.ps1$') { continue } # Skip if the file is an unrelated file. + if (`$file.Name -match '\.[^\.]+\.ps1$') { continue } # Skip if the file is an unrelated file. . `$file.FullName } "@) diff --git a/Transpilers/Inline/Inline.Kotlin.psx.ps1 b/Transpilers/Inline/Inline.Kotlin.psx.ps1 new file mode 100644 index 000000000..ec43d78be --- /dev/null +++ b/Transpilers/Inline/Inline.Kotlin.psx.ps1 @@ -0,0 +1,51 @@ +<# +.SYNOPSIS + Kotlin Inline PipeScript Transpiler. +.DESCRIPTION + Transpiles Kotlin with Inline PipeScript into Kotlin. + + Multiline comments with /*{}*/ will be treated as blocks of PipeScript. + + Multiline comments can be preceeded or followed by 'empty' syntax, which will be ignored. + + This for Inline PipeScript to be used with operators, and still be valid Kotlin syntax. + + The Kotlin Inline PipeScript Transpiler will consider the following syntax to be empty: + + * ```null``` + * ```""``` + * ```''``` +#> +[ValidateScript({ + $cmdInfo = $_ + if ($cmdInfo.Source -match '\.kt$') { + return $true + } + return $false +})] +param( +# The command information. This will include the path to the file. +[Parameter(Mandatory,ValueFromPipeline)] +$CommandInfo +) + +begin { + # We start off by declaring a number of regular expressions: + $startComment = '/\*' # * Start Comments ```\*``` + $endComment = '\*/' # * End Comments ```/*``` + $Whitespace = '[\s\n\r]{0,}' + # * IgnoredContext ```String.empty```, ```null```, blank strings and characters + $IgnoredContext = "(?(?>$("null", '""', "''" -join '|'))\s{0,}){0,1}" + # * StartRegex ```$IgnoredContext + $StartComment + '{' + $Whitespace``` + $startRegex = "(?${IgnoredContext}${startComment}\{$Whitespace)" + # * EndRegex ```$whitespace + '}' + $EndComment + $ignoredContext``` + $endRegex = "(?$Whitespace\}${endComment}\s{0,}${IgnoredContext})" +} + +process { + + $fileInfo = $commandInfo.Source -as [IO.FileInfo] + $fileText = [IO.File]::ReadAllText($fileInfo.Fullname) + + .>PipeScript.Inline -SourceFile $CommandInfo.Source -SourceText $fileText -StartPattern $startRegex -EndPattern $endRegex +} \ No newline at end of file diff --git a/Transpilers/Inline/README.md b/Transpilers/Inline/README.md index 56d344310..f40434f6f 100644 --- a/Transpilers/Inline/README.md +++ b/Transpilers/Inline/README.md @@ -1,6 +1,6 @@ This directory contains Inline PipeScript transpilers for several languages. -PipeScript can currently be embedded in 25 languages or file types. +PipeScript can currently be embedded in 26 languages or file types. Transpilers in this directory should be named ```Inline.NameOfLanguage.psx.ps1```. Each file should handle one and only one language (better explicit than terse). @@ -21,6 +21,7 @@ Transpilers should call ```.>PipeScript.Inline``` to simplify and standarize pro |[Java](Inline.Java.psx.ps1) |[Java Inline PipeScript Transpiler.](Inline.Java.psx.ps1) | |[JavaScript](Inline.JavaScript.psx.ps1)|[JavaScript Inline PipeScript Transpiler.](Inline.JavaScript.psx.ps1)| |[Json](Inline.Json.psx.ps1) |[JSON PipeScript Transpiler.](Inline.Json.psx.ps1) | +|[Kotlin](Inline.Kotlin.psx.ps1) |[Kotlin Inline PipeScript Transpiler.](Inline.Kotlin.psx.ps1) | |[Markdown](Inline.Markdown.psx.ps1) |[Markdown File Transpiler.](Inline.Markdown.psx.ps1) | |[ObjectiveC](Inline.ObjectiveC.psx.ps1)|[Objective C PipeScript Transpiler.](Inline.ObjectiveC.psx.ps1) | |[OpenSCAD](Inline.OpenSCAD.psx.ps1) |[OpenSCAD Inline PipeScript Transpiler.](Inline.OpenSCAD.psx.ps1) | diff --git a/Transpilers/Parameters/ValidateTypes.psx.ps1 b/Transpilers/Parameters/ValidateTypes.psx.ps1 index 5fa5e688c..caead0fd7 100644 --- a/Transpilers/Parameters/ValidateTypes.psx.ps1 +++ b/Transpilers/Parameters/ValidateTypes.psx.ps1 @@ -50,8 +50,33 @@ $TypeName, $VariableAST ) +# Determine the list of real types at this point in time +$realTypes = + @(foreach ($tn in $typeName) { + if ($tn -as [type]) { + $tn -as [type] + } + }) + +# If all of the types are .NET types +if ($realTypes.Length -eq $TypeName.Length) { + $checkTypes = @" +`$validTypeList = [$($realTypes -join '],[')] +"@ + { + +$thisType = $_.GetType() +$IsTypeOk = + $(@( foreach ($validType in $validTypeList) { + if ($_ -as $validType) { + $true;break + } + })) +} + + +} else { -$checkTypes = @" + $checkTypes = @" `$validTypeList = '$($typeName -join "','")' "@ + { $thisType = @( @@ -87,7 +112,7 @@ $IsTypeOk = } }) -eq $true) -as [bool] } - +} if ($PSCmdlet.ParameterSetName -eq 'Parameter') { [scriptblock]::Create(@" [ValidateScript({ diff --git a/Transpilers/Rest.psx.ps1 b/Transpilers/Rest.psx.ps1 new file mode 100644 index 000000000..8f6cb085f --- /dev/null +++ b/Transpilers/Rest.psx.ps1 @@ -0,0 +1,423 @@ +<# +.SYNOPSIS + Generates PowerShell to talk to a REST api. +.DESCRIPTION + Generates PowerShell that communicates with a REST api. +.EXAMPLE + { + function Get-Sentiment { + [Rest("http://text-processing.com/api/sentiment/", + ContentType="application/x-www-form-urlencoded", + Method = "POST", + BodyParameter="Text", + ForeachOutput = { + $_ | Select-Object -ExpandProperty Probability -Property Label + } + )] + param() + } + } | .>PipeScript | Set-Content .\Get-Sentiment.ps1 +.EXAMPLE + Invoke-PipeScript { + [Rest("http://text-processing.com/api/sentiment/", + ContentType="application/x-www-form-urlencoded", + Method = "POST", + BodyParameter="Text", + ForeachOutput = { + $_ | Select-Object -ExpandProperty Probability -Property Label + } + )] + param() + } -Parameter @{Text='wow!'} +.EXAMPLE + { + [Rest("https://api.github.com/users/{username}/repos", + QueryParameter={"type", "sort", "direction", "page", "per_page"} + )] + param() + } | .>PipeScript +.EXAMPLE + Invoke-PipeScript { + [Rest("https://api.github.com/users/{username}/repos", + QueryParameter={"type", "sort", "direction", "page", "per_page"} + )] + param() + } -UserName StartAutomating +.EXAMPLE + { + [Rest("http://text-processing.com/api/sentiment/", + ContentType="application/x-www-form-urlencoded", + Method = "POST", + BodyParameter={@{ + Text = ' + [Parameter(Mandatory,ValueFromPipelineByPropertyName)] + [string] + $Text + ' + }})] + param() + } | .>PipeScript +#> +param( +# The ScriptBlock. +# If not empty, the contents of this ScriptBlock will preceed the REST api call. +[Parameter(ValueFromPipeline)] +[scriptblock] +$ScriptBlock = {}, + +# One or more REST endpoints. This endpoint will be parsed for REST variables. +[Parameter(Mandatory,Position=0)] +[string[]] +$RESTEndpoint, + +# The content type. If provided, this parameter will be passed to the -InvokeCommand. +[string] +$ContentType, + +# The method. If provided, this parameter will be passed to the -InvokeCommand. +[string] +$Method, + +# The invoke command. This command _must_ have a parameter -URI. +[Alias('Invoker')] +[string] +$InvokeCommand = 'Invoke-RestMethod', + +# The name of a variable containing additional invoke parameters. +# By default, this is 'InvokeParams' +[Alias('InvokerParameters','InvokerParameter')] +[string] +$InvokeParameterVariable = 'InvokeParams', + +# A dictionary of help for uri parameters. +[Alias('UrlParameterHelp')] +[Collections.IDictionary] +$UriParameterHelp, + +# A dictionary of URI parameter types. +[Alias('UrlParameterType')] +[Collections.IDictionary] +$UriParameterType, + +# A dictionary or list of parameters for the body. +[PSObject] +$BodyParameter, + +# A dictionary or list of query parameters. +[PSObject] +$QueryParameter, + +# A script block to be run on each output. +[ScriptBlock] +$ForEachOutput +) + +begin { + # Declare a Regular Expression to match URL variables. + $RestVariable = [Regex]::new(@' +# Matches URL segments and query strings containing variables. +# Variables can be enclosed in brackets or curly braces, or preceeded by a $ or : +(?> # A variable can be in a URL segment or subdomain + (?[/\.]) # Match the ing slash|dot ... + (?\?)? # ... an optional ? (to indicate optional) ... + (?: + \{(?\w+)\}| # ... A name in {} OR + \[(?\w+)\]| # A name in [] OR + \<(?\w+)\>| # A name in <> OR + \:(?\w+) # A : followed by a + ) +| + (? # If it's optional it can also be + [{\[](?/) # a bracket or brace, followed by a slash + ) + (?\w+)[}\]] # then a name followed by } or ] +| # OR it can be in a query parameter: + (?[?&]) # Match The ing ? or & ... + (?[\w\-]+) # ... the parameter name ... + = # ... an equals ... + (?\?)? # ... an optional ? (to indicate optional) ... + (?: + \{(?\w+)\}| # ... A name in {} OR + \[(?\w+)\]| # A name in [] OR + \<(?\w+)\>| # A name in <> OR + \:(?\w+) # A : followed by a + ) +) +'@, 'IgnoreCase,IgnorePatternWhitespace') + + + # Next declare a script block that will replace the rest variable. + $ReplaceRestVariable = { + param($match) + + if ($uriParameter -and $uriParameter[$match.Groups["Variable"].Value]) { + return $match.Groups["Start"].Value + $( + if ($match.Groups["Query"].Success) { $match.Groups["Query"].Value + '=' } + ) + + ([Web.HttpUtility]::UrlEncode( + $uriParameter[$match.Groups["Variable"].Value] + )) + } else { + return '' + } + } + + $myCmd = $MyInvocation.MyCommand +} + +process { + # First, create a collection of URI parameters. + $uriParameters = [Ordered]@{} + # Then, walk over each potential endpoint + foreach ($endpoint in $RESTEndpoint) { + # and each match of a $RestVariable + foreach ($match in $RestVariable.Matches($endpoint)) { + # The name of the parameter will be in the named capture ${Variable}. + $parameterName = $match.Groups["Variable"].Value + # The parameter type will be a string + $parameterType = if ($UriParameterType.$parameterName) { + if ($UriParameterType.$parameterName -as [type]) { + $UriParameterType.$parameterName + } + } else { + '[string]' + } + # and we'll need to put it in the proper parameter set. + $parameterAttribute = "[Parameter($( + if (-not $match.Groups["IsOptional"].Value) {'Mandatory'} + ),ValueFromPipelineByPropertyName,ParameterSetName='$endpoint')]" + # Combine these three pieces to create the parameter attribute. + $uriParameters[$parameterName] = @( + if ($UriParameterHelp -and $UriParameterHelp.$parameterName) { + if ($UriParameterHelp.$parameterName -notmatch '^\<{0,1}\#' ) { + if ($UriParameterHelp.$parameterName -match '[\r\n]') { + "<# " + $UriParameterHelp.$parameterName + "#>" + } else { + "# " + $UriParameterHelp.$parameterName + } + } else { + $UriParameterHelp.$parameterName + } + } + $parameterAttribute + $parameterType + '$' + $parameterName + ) -join [Environment]::Newline + } + } + + # Create a parameter block out of the uri parameters. + $uriParamBlock = + New-PipeScript -Parameter $uriParameters + + # Next, create a parameter block out of any of the body parameters. + $bodyParamBlock = + if ($BodyParameter) { + New-PipeScript -Parameter $BodyParameter + } else { {} } + + # And one for each of the query parameters. + $QueryParamblock = + if ($QueryParameter) { + New-PipeScript -Parameter $QueryParameter + } else { {} } + + $myBeginBlock = + # If we used any URI parameters + if ($uriParamBlock.Ast.ParamBlock.Parameters) { + # Carry on the begin block from this command (this is a neat trick) + [scriptblock]::Create($myCmd.ScriptBlock.Ast.BeginBlock.Extent.ToString()) + } else { { begin { $myCmd = $MyInvocation.MyCommand }} } + + # Next, collect the names of bodyParameters, queryParameters, and uriParameters. + $bodyParameterNames = + foreach ($param in $bodyParamBlock.Ast.ParamBlock.Parameters) { $param.Name -replace '^\$' } + $queryParameterNames = + foreach ($param in $QueryParamblock.Ast.ParamBlock.Parameters) { $param.Name -replace '^\$' } + $uriParameterNames = + foreach ($param in $uriParamBlock.Ast.ParamBlock.Parameters) { $param.Name -replace '^\$' } + + + # Collect all of the parts of the script + $RestScript = @( + # Start with the underlying script block + $ScriptBlock + + # Then include the begin block from this command (or declare myCmd) + $myBeginBlock + + # Then declare the initial variables. + [scriptblock]::Create((@" +process { + `$InvokeCommand = '$InvokeCommand' + `$invokerCommandinfo = + `$ExecutionContext.SessionState.InvokeCommand.GetCommand('$InvokeCommand', 'All') + `$method = '$Method' + `$contentType = '$contentType' + `$bodyParameterNames = @('$($bodyParameterNames -join "','")') + `$queryParameterNames = @('$($queryParameterNames -join "','")') + `$uriParameterNames = @('$($uriParameterNames -join "','")') + `$endpoints = @("$($endpoint -join "','")") + `$ForEachOutput = { + $(if ($foreachOutput) { $ForEachOutput | .>Pipescript }) + } + if (`$ForEachOutput -match '^\s{0,}$') { + `$ForEachOutput = `$null + } +} +"@)) + # Next, add some boilerplate code for error handling and setting defaults +{ +process { + if (-not $invokerCommandinfo) { + Write-Error "Unable to find invoker '$InvokeCommand'" + return + } + if (-not $psParameterSet) { $psParameterSet = $psCmdlet.ParameterSetName} + if ($psParameterSet -eq '__AllParameterSets') { $psParameterSet = $endpoints[0]} +} +} + # If we had any uri parameters + if ($uriParameters.Count) { + # Add the uri parameter block + $uriParamBlock + # Then add a bit to process {} to extract out the URL +{ +process { + $originalUri = "$psParameterSet" + if (-not $PSBoundParameters.ContainsKey('UriParameter')) { + $uriParameter = [Ordered]@{} + } + foreach ($uriParameterName in $uriParameterNames) { + if ($psBoundParameters.ContainsKey($uriParameterName)) { + $uriParameter[$uriParameterName] = $psBoundParameters[$uriParameterName] + } + } + + $uri = $RestVariable.Replace($originalUri, $ReplaceRestVariable) +} +} + } else { + # If uri parameters were not supplied, default to the first endpoint. +{ + process { + $uri = $endpoints[0] + } +} + } + # Now create the invoke splat and populate it. +{ +process { + $invokeSplat = @{} + $invokeSplat.Uri = $uri + if ($method) { + $invokeSplat.Method = $method + } + if ($ContentType) { + $invokeSplat.ContentType = $ContentType + } +} +} + + # If we have an InvokeParameterVariable + if ($InvokeParameterVariable) { + # Create the code that looks for it and joins it with the splat. + $InvokeParameterVariable = $InvokeParameterVariable -replace '^\$' +[scriptblock]::Create(" +process { + if (`$$InvokeParameterVariable -and `$$InvokeParameterVariable -is [Collections.IDictionary]) { + `$invokeSplat += `$$InvokeParameterVariable + } +} +") + + } + + # If QueryParameter Names were provided + if ($queryParameterNames) { + # Include the query parameter block + $QueryParamblock + # And a section of process to handle query parameters. +{ +process { + $QueryParams = [Ordered]@{} + foreach ($QueryParameterName in $QueryParameterNames) { + if ($PSBoundParameters.ContainsKey($QueryParameterName)) { + $QueryParams[$QueryParameterName] = $PSBoundParameters[$QueryParameterName] + } + } +} +} +{ +process { + if ($invokerCommandinfo.Parameters['QueryParameter'] -and + $invokerCommandinfo.Parameters['QueryParameter'].ParameterType -eq [Collections.IDictionary]) { + $invokerCommandinfo.QueryParameter = $QueryParams + } else { + $queryParamStr = + @(foreach ($qp in $QueryParams.GetEnumerator()) { + "$($qp.Key)=$([Web.HttpUtility]::UrlEncode($qp.Value).Replace('+', '%20'))" + }) -join '&' + if ($invokeSplat.Uri.Contains('?')) { + $invokeSplat.Uri = "$($invokeSplat.Uri)" + '&' + $queryParamStr + } else { + $invokeSplat.Uri = "$($invokeSplat.Uri)" + '?' + $queryParamStr + } + } +} +} + } + + # If any body parameters exist + if ($bodyParameterNames) { + # Include the body parameter block + $bodyParamBlock + # and a process section to handle the body +{ +process { + $completeBody = [Ordered]@{} + foreach ($bodyParameterName in $bodyParameterNames) { + if ($bodyParameterName) { + if ($PSBoundParameters.ContainsKey($bodyParameterName)) { + $completeBody[$bodyParameterName] = $PSBoundParameters[$bodyParameterName] + } + } + } + + $bodyContent = + if ($ContentType -match 'x-www-form-urlencoded') { + @(foreach ($bodyPart in $completeBody.GetEnumerator()) { + "$($bodyPart.Key.ToString().ToLower())=$([Web.HttpUtility]::UrlEncode($bodyPart.Value))" + }) -join '&' + } elseif ($ContentType -match 'json') { + ConvertTo-Json $completeBody + } + + if ($bodyContent -and $method -ne 'get') { + $invokeSplat.Body = $bodyContent + } +} +} + } + + # Last but not least, include the part of process that calls the REST api. + { +process { + Write-Verbose "$($invokeSplat.Uri)" + if ($ForEachOutput) { + if ($ForEachOutput.Ast.ProcessBlock) { + & $invokerCommandinfo @invokeSplat | & $ForEachOutput + } else { + & $invokerCommandinfo @invokeSplat | ForEach-Object -Process $ForEachOutput + } + } else { + & $invokerCommandinfo @invokeSplat + } +} + } + ) + + # Join all of the parts together and you've got yourself a RESTful function. + $RestScript | + Join-PipeScript +} diff --git a/Transpilers/Syntax/README.md b/Transpilers/Syntax/README.md index 5b859fbc1..10f9ef52e 100644 --- a/Transpilers/Syntax/README.md +++ b/Transpilers/Syntax/README.md @@ -106,6 +106,14 @@ This directory and it's subdirectories contain syntax changes that enable common ## RegexLiteral Example 2 +~~~PowerShell + Invoke-PipeScript { + '/[a|b]/' +~~~ + +## RegexLiteral Example 3 + + ~~~PowerShell { "/[$a|$b]/" @@ -116,7 +124,7 @@ This directory and it's subdirectories contain syntax changes that enable common [regex]::new("[$a|$b]", 'IgnoreCase') ~~~ -## RegexLiteral Example 3 +## RegexLiteral Example 4 ~~~PowerShell @@ -139,7 +147,7 @@ This directory and it's subdirectories contain syntax changes that enable common '@, 'IgnorePatternWhitespace,IgnoreCase') ~~~ -## RegexLiteral Example 4 +## RegexLiteral Example 5 ~~~PowerShell diff --git a/Transpilers/Syntax/RegexLiteral.psx.ps1 b/Transpilers/Syntax/RegexLiteral.psx.ps1 index 3a5197648..6537e95b2 100644 --- a/Transpilers/Syntax/RegexLiteral.psx.ps1 +++ b/Transpilers/Syntax/RegexLiteral.psx.ps1 @@ -15,6 +15,10 @@ # This will become: [regex]::new('[a|b]', 'IgnoreCase') +.EXAMPLE + Invoke-PipeScript { + '/[a|b]/'.Matches('ab') + } .EXAMPLE { "/[$a|$b]/" diff --git a/docs/Aliases.md b/docs/Aliases.md new file mode 100644 index 000000000..15620ac6d --- /dev/null +++ b/docs/Aliases.md @@ -0,0 +1,107 @@ + +Aliases +------- +### Synopsis +Dynamically Defines Aliases + +--- +### Description + +Can Dynamically Define Aliases. + +When uses in a parameter attribute, -Aliases will define a list of aliases. + +When used with a variable, [Aliases] will Set-Alias on each value in the variable. + +--- +### Examples +#### EXAMPLE 1 +```PowerShell +{ + $aliases = "Foo", "Bar", "Baz" + [Aliases(Command="Get-Process")]$aliases +} | .>PipeScript +``` + +#### EXAMPLE 2 +```PowerShell +{ + param( + [Aliases(Aliases={ + ([char]'a'..[char]'z') + })] + [string] + $Drive + ) +} | .>PipeScript +``` + +--- +### Parameters +#### **Aliases** + +A list of aliases + + + +|Type |Requried|Postion|PipelineInput| +|----------------|--------|-------|-------------| +|```[String[]]```|true |named |false | +--- +#### **Prefix** + +If provided, will prefix each alias + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[String]```|false |named |false | +--- +#### **Suffix** + +If provided, will add a suffix to each alias + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[String]```|false |named |false | +--- +#### **Command** + +The command being aliased. This is only required when transpiling a variable. + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[String]```|true |named |false | +--- +#### **PassThru** + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[Switch]```|false |named |false | +--- +#### **VariableAST** + +A VariableExpression. +If provided, this will be treated as the alias name or list of alias names. + + + +|Type |Requried|Postion|PipelineInput | +|-----------------------------|--------|-------|--------------| +|```[VariableExpressionAst]```|true |named |true (ByValue)| +--- +### Syntax +```PowerShell +Aliases -Aliases [-Prefix ] [-Suffix ] [] +``` +```PowerShell +Aliases [-Prefix ] [-Suffix ] -Command [-PassThru] -VariableAST [] +``` +--- + + diff --git a/docs/Bash.md b/docs/Bash.md new file mode 100644 index 000000000..f115d5582 --- /dev/null +++ b/docs/Bash.md @@ -0,0 +1,35 @@ + +Bash +---- +### Synopsis +Wraps PowerShell in a Bash Script + +--- +### Description + +Wraps PowerShell in a Bash Script + +--- +### Parameters +#### **ScriptInfo** + +|Type |Requried|Postion|PipelineInput | +|--------------------------|--------|-------|--------------| +|```[ExternalScriptInfo]```|true |named |true (ByValue)| +--- +#### **ScriptBlock** + +|Type |Requried|Postion|PipelineInput | +|-------------------|--------|-------|--------------| +|```[ScriptBlock]```|true |named |true (ByValue)| +--- +### Syntax +```PowerShell +Bash -ScriptInfo [] +``` +```PowerShell +Bash -ScriptBlock [] +``` +--- + + diff --git a/docs/Batch.md b/docs/Batch.md new file mode 100644 index 000000000..91277e42d --- /dev/null +++ b/docs/Batch.md @@ -0,0 +1,45 @@ + +Batch +----- +### Synopsis +Wraps PowerShell in a Windows Batch Script + +--- +### Description + +Wraps PowerShell in a Windows Batch Script + +--- +### Parameters +#### **ScriptInfo** + +|Type |Requried|Postion|PipelineInput | +|--------------------------|--------|-------|--------------| +|```[ExternalScriptInfo]```|true |named |true (ByValue)| +--- +#### **ScriptBlock** + +|Type |Requried|Postion|PipelineInput | +|-------------------|--------|-------|--------------| +|```[ScriptBlock]```|true |named |true (ByValue)| +--- +#### **WindowsPowerShell** + +If set, will use Windows PowerShell core (powershell.exe). If not, will use PowerShell Core (pwsh.exe) + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[Switch]```|false |named |false | +--- +### Syntax +```PowerShell +Batch -ScriptInfo [-WindowsPowerShell] [] +``` +```PowerShell +Batch -ScriptBlock [-WindowsPowerShell] [] +``` +--- + + diff --git a/docs/BatchPowerShell.md b/docs/BatchPowerShell.md new file mode 100644 index 000000000..8c74e370a --- /dev/null +++ b/docs/BatchPowerShell.md @@ -0,0 +1,45 @@ + +BatchPowerShell +--------------- +### Synopsis +Wraps PowerShell in a Windows Batch Script + +--- +### Description + +Wraps PowerShell in a Windows Batch Script + +--- +### Parameters +#### **ScriptInfo** + +|Type |Requried|Postion|PipelineInput | +|--------------------------|--------|-------|--------------| +|```[ExternalScriptInfo]```|true |named |true (ByValue)| +--- +#### **ScriptBlock** + +|Type |Requried|Postion|PipelineInput | +|-------------------|--------|-------|--------------| +|```[ScriptBlock]```|true |named |true (ByValue)| +--- +#### **Pwsh** + +If set, will use PowerShell core (pwsh.exe). If not, will use Windows PowerShell (powershell.exe) + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[Switch]```|false |named |false | +--- +### Syntax +```PowerShell +BatchPowerShell -ScriptInfo [-Pwsh] [] +``` +```PowerShell +BatchPowerShell -ScriptBlock [-Pwsh] [] +``` +--- + + diff --git a/docs/Decorate-Transpiler.md b/docs/Decorate.md similarity index 100% rename from docs/Decorate-Transpiler.md rename to docs/Decorate.md diff --git a/docs/Dot.md b/docs/Dot.md new file mode 100644 index 000000000..4c363fcbb --- /dev/null +++ b/docs/Dot.md @@ -0,0 +1,3 @@ +Dot.psx.ps1 -CommandAst [] + + diff --git a/docs/Explicit-Transpiler.md b/docs/Explicit.md similarity index 81% rename from docs/Explicit-Transpiler.md rename to docs/Explicit.md index 7fad8e211..8970285f6 100644 --- a/docs/Explicit-Transpiler.md +++ b/docs/Explicit.md @@ -1,6 +1,6 @@ -Transpilers/Explicit.psx.ps1 ----------------------------- +Explicit +-------- ### Synopsis Makes Output from a PowerShell function Explicit. @@ -28,7 +28,7 @@ System.Collections.IDictionary --- ### Syntax ```PowerShell -Transpilers/Explicit.psx.ps1 [-ScriptBlock] [] +Explicit [-ScriptBlock] [] ``` --- diff --git a/docs/Help-Transpiler.md b/docs/Help.md similarity index 81% rename from docs/Help-Transpiler.md rename to docs/Help.md index 003ffcfc7..c7e5f8542 100644 --- a/docs/Help-Transpiler.md +++ b/docs/Help.md @@ -1,6 +1,6 @@ -Transpilers/Help.psx.ps1 ------------------------- +Help +---- ### Synopsis Help Transpiler @@ -74,10 +74,10 @@ The Help Transpiler allows you to write inline help without directly writing com --- ### Syntax ```PowerShell -Transpilers/Help.psx.ps1 [-Synopsis] [-Description ] [-Example ] [-Link ] [] +Help [-Synopsis] [-Description ] [-Example ] [-Link ] [] ``` ```PowerShell -Transpilers/Help.psx.ps1 [-Synopsis] [-Description ] [-Example ] [-Link ] [-ScriptBlock ] [] +Help [-Synopsis] [-Description ] [-Example ] [-Link ] [-ScriptBlock ] [] ``` --- diff --git a/docs/Include-Transpiler.md b/docs/Include.md similarity index 82% rename from docs/Include-Transpiler.md rename to docs/Include.md index 449028df3..f59c8e6fa 100644 --- a/docs/Include-Transpiler.md +++ b/docs/Include.md @@ -1,6 +1,6 @@ -Transpilers/Include.psx.ps1 ---------------------------- +Include +------- ### Synopsis Includes Files @@ -26,6 +26,13 @@ Includes Files or Functions into a Script. } | .>PipeScript ``` +#### EXAMPLE 3 +```PowerShell +{ + [Include('*-*.ps1')]$psScriptRoot +} | .>PipeScript +``` + --- ### Parameters #### **FilePath** @@ -56,7 +63,7 @@ If set, will include the content as a byte array --- ### Syntax ```PowerShell -Transpilers/Include.psx.ps1 [-FilePath] [-AsByte] -VariableAst [] +Include [-FilePath] [-AsByte] -VariableAst [] ``` --- diff --git a/docs/Inline.ATOM.md b/docs/Inline.ATOM.md new file mode 100644 index 000000000..d18166ba3 --- /dev/null +++ b/docs/Inline.ATOM.md @@ -0,0 +1,32 @@ + +Inline.ATOM +----------- +### Synopsis +ATOM Inline PipeScript Transpiler. + +--- +### Description + +Transpiles ATOM with Inline PipeScript into ATOM. + +Multiline comments blocks like this `````` will be treated as blocks of PipeScript. + +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.ATOM [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.Bicep.md b/docs/Inline.Bicep.md new file mode 100644 index 000000000..36a4aa7e7 --- /dev/null +++ b/docs/Inline.Bicep.md @@ -0,0 +1,37 @@ + +Inline.Bicep +------------ +### Synopsis +Bicep Inline PipeScript Transpiler. + +--- +### Description + +Transpiles Bicep with Inline PipeScript into Bicep. + +Multiline comments blocks like ```/*{}*/``` will be treated as blocks of PipeScript. + +Multiline comments can be preceeded or followed by 'empty' syntax, which will be ignored. + +* ```''``` +* ```{}``` + +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.Bicep [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.CPlusPlus.md b/docs/Inline.CPlusPlus.md new file mode 100644 index 000000000..a6990df32 --- /dev/null +++ b/docs/Inline.CPlusPlus.md @@ -0,0 +1,42 @@ + +Inline.CPlusPlus +---------------- +### Synopsis +C/C++ PipeScript Transpiler. + +--- +### Description + +Transpiles C/C++ with Inline PipeScript into C++. + +Multiline comments with /*{}*/ will be treated as blocks of PipeScript. + +Multiline comments can be preceeded or followed by 'empty' syntax, which will be ignored. + +This for Inline PipeScript to be used with operators, and still be valid C/C++ syntax. + +The C++ Inline Transpiler will consider the following syntax to be empty: + +* ```null``` +* ```""``` +* ```''``` + +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.CPlusPlus [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.CSS.md b/docs/Inline.CSS.md new file mode 100644 index 000000000..0a9a5d262 --- /dev/null +++ b/docs/Inline.CSS.md @@ -0,0 +1,59 @@ + +Inline.CSS +---------- +### Synopsis +CSS Inline PipeScript Transpiler. + +--- +### Description + +Transpiles CSS with Inline PipeScript into CSS. + +Multiline comments with /*{}*/ will be treated as blocks of PipeScript. + +Multiline comments can be preceeded or followed by 'empty' syntax, which will be ignored. + +This for Inline PipeScript to be used with operators, and still be valid CSS syntax. + +The CSS Inline Transpiler will consider the following syntax to be empty: + +* ```(?["'])\#[a-f0-9]{3}(\k)``` +* ```\#[a-f0-9]{6}``` +* ```[\d\.](?>pt|px|em)``` +* ```auto``` + +--- +### Examples +#### EXAMPLE 1 +```PowerShell +{ + $StyleSheet = @' +MyClass { +text-color: "#000000" /*{ +"'red'", "'green'","'blue'" | Get-Random +}*/; +} +'@ + [Save(".\StyleSheet.ps1.css")]$StyleSheet +} +``` +.> .\StyleSheet.ps1.css +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.CSS [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.CSharp.md b/docs/Inline.CSharp.md new file mode 100644 index 000000000..bd0a9325f --- /dev/null +++ b/docs/Inline.CSharp.md @@ -0,0 +1,82 @@ + +Inline.CSharp +------------- +### Synopsis +C# Inline PipeScript Transpiler. + +--- +### Description + +Transpiles C# with Inline PipeScript into C#. + +Multiline comments with /*{}*/ will be treated as blocks of PipeScript. + +Multiline comments can be preceeded or followed by 'empty' syntax, which will be ignored. + +This for Inline PipeScript to be used with operators, and still be valid C# syntax. + +The C# Inline Transpiler will consider the following syntax to be empty: + +* ```String.Empty``` +* ```null``` +* ```""``` +* ```''``` + +--- +### Examples +#### EXAMPLE 1 +```PowerShell +{ + $CSharpLiteral = @' +namespace TestProgram/*{Get-Random}*/ { +public static class Program { + public static void Main(string[] args) { + string helloMessage = /*{ + '"hello"', '"hello world"', '"hey there"', '"howdy"' | Get-Random + }*/ string.Empty; + System.Console.WriteLine(helloMessage); + } +} +} +'@ +``` +[OutputFile(".\HelloWorld.ps1.cs")]$CSharpLiteral +} + +$AddedFile = .> .\HelloWorld.ps1.cs +$addedType = Add-Type -TypeDefinition (Get-Content $addedFile.FullName -Raw) -PassThru +$addedType::Main(@()) +#### EXAMPLE 2 +```PowerShell +// HelloWorld.ps1.cs +namespace TestProgram { + public static class Program { + public static void Main(string[] args) { + string helloMessage = /*{ + '"hello"', '"hello world"', '"hey there"', '"howdy"' | Get-Random + }*/ string.Empty; + System.Console.WriteLine(helloMessage); + } + } +} +``` + +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.CSharp [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.Go.md b/docs/Inline.Go.md new file mode 100644 index 000000000..f375eea3f --- /dev/null +++ b/docs/Inline.Go.md @@ -0,0 +1,42 @@ + +Inline.Go +--------- +### Synopsis +Go PipeScript Transpiler. + +--- +### Description + +Transpiles Go with Inline PipeScript into Go. + +Multiline comments with /*{}*/ will be treated as blocks of PipeScript. + +Multiline comments can be preceeded or followed by 'empty' syntax, which will be ignored. + +This for Inline PipeScript to be used with operators, and still be valid Go syntax. + +The Go Transpiler will consider the following syntax to be empty: + +* ```nil``` +* ```""``` +* ```''``` + +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.Go [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.HLSL.md b/docs/Inline.HLSL.md new file mode 100644 index 000000000..6fcb83020 --- /dev/null +++ b/docs/Inline.HLSL.md @@ -0,0 +1,32 @@ + +Inline.HLSL +----------- +### Synopsis +HLSL Inline PipeScript Transpiler. + +--- +### Description + +Transpiles HLSL with Inline PipeScript into HLSL. + +Multiline comments with /*{}*/ will be treated as blocks of PipeScript. + +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.HLSL [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.HTML.md b/docs/Inline.HTML.md new file mode 100644 index 000000000..d604271e3 --- /dev/null +++ b/docs/Inline.HTML.md @@ -0,0 +1,3 @@ +Inline.HTML.psx.ps1 [-CommandInfo] [] + + diff --git a/docs/Inline.Java.md b/docs/Inline.Java.md new file mode 100644 index 000000000..a294d7147 --- /dev/null +++ b/docs/Inline.Java.md @@ -0,0 +1,42 @@ + +Inline.Java +----------- +### Synopsis +Java Inline PipeScript Transpiler. + +--- +### Description + +Transpiles Java with Inline PipeScript into Java. + +Multiline comments with /*{}*/ will be treated as blocks of PipeScript. + +Multiline comments can be preceeded or followed by 'empty' syntax, which will be ignored. + +This for Inline PipeScript to be used with operators, and still be valid JavaScript/TypeScript syntax. + +The Java Inline PipeScript Transpiler will consider the following syntax to be empty: + +* ```null``` +* ```""``` +* ```''``` + +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.Java [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.JavaScript.md b/docs/Inline.JavaScript.md new file mode 100644 index 000000000..745bb094c --- /dev/null +++ b/docs/Inline.JavaScript.md @@ -0,0 +1,43 @@ + +Inline.JavaScript +----------------- +### Synopsis +JavaScript Inline PipeScript Transpiler. + +--- +### Description + +Transpiles JavaScript with Inline PipeScript into JavaScript. + +Multiline comments with /*{}*/ will be treated as blocks of PipeScript. + +Multiline comments can be preceeded or followed by 'empty' syntax, which will be ignored. + +This is so that Inline PipeScript can be used with operators, and still be valid JavaScript syntax. + +The JavaScript Inline Transpiler will consider the following syntax to be empty: + +* ```undefined``` +* ```null``` +* ```""``` +* ```''``` + +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.JavaScript [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.Json.md b/docs/Inline.Json.md new file mode 100644 index 000000000..8490d3757 --- /dev/null +++ b/docs/Inline.Json.md @@ -0,0 +1,39 @@ + +Inline.Json +----------- +### Synopsis +JSON PipeScript Transpiler. + +--- +### Description + +Transpiles JSON with Inline PipeScript into JSON. + +Multiline comments blocks like ```/*{}*/``` will be treated as blocks of PipeScript. + +Multiline comments can be preceeded or followed by 'empty' syntax, which will be ignored. + +* ```null``` +* ```""``` +* ```{}``` +* ```[]``` + +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.Json [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.Kotlin.md b/docs/Inline.Kotlin.md new file mode 100644 index 000000000..8f2b1d568 --- /dev/null +++ b/docs/Inline.Kotlin.md @@ -0,0 +1,42 @@ + +Inline.Kotlin +------------- +### Synopsis +Kotlin Inline PipeScript Transpiler. + +--- +### Description + +Transpiles Kotlin with Inline PipeScript into Kotlin. + +Multiline comments with /*{}*/ will be treated as blocks of PipeScript. + +Multiline comments can be preceeded or followed by 'empty' syntax, which will be ignored. + +This for Inline PipeScript to be used with operators, and still be valid Kotlin syntax. + +The Kotlin Inline PipeScript Transpiler will consider the following syntax to be empty: + +* ```null``` +* ```""``` +* ```''``` + +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.Kotlin [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.Markdown.md b/docs/Inline.Markdown.md new file mode 100644 index 000000000..8cc1e171c --- /dev/null +++ b/docs/Inline.Markdown.md @@ -0,0 +1,62 @@ + +Inline.Markdown +--------------- +### Synopsis +Markdown File Transpiler. + +--- +### Description + +Transpiles Markdown with Inline PipeScript into Markdown. + +Because Markdown does not support comment blocks, PipeScript can be written inline inside of specialized Markdown code blocks. + +PipeScript can be included in a Markdown code block that has the Language ```PipeScript{``` + +In Markdown, PipeScript can also be specified as the language using any two of the following characters ```.<>``` + +--- +### Examples +#### EXAMPLE 1 +```PowerShell +{ + $markdownContent = @' +# Thinking of a Number Between 1 and 100: ```.<{Get-Random -Min 1 -Max 100}>.``` is the number +``` +### abc + +~~~PipeScript{ +'* ' + @("a", "b", "c" -join ([Environment]::Newline + '* ')) +} +~~~ + +#### Guess what, other code blocks are unaffected +~~~PowerShell +1 + 1 -eq 2 +~~~ + + +'@ + [OutputFile('.\HelloWorld.ps1.md')]$markdownContent +} + +.> .\HelloWorld.ps1.md +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.Markdown [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.ObjectiveC.md b/docs/Inline.ObjectiveC.md new file mode 100644 index 000000000..364f289e8 --- /dev/null +++ b/docs/Inline.ObjectiveC.md @@ -0,0 +1,43 @@ + +Inline.ObjectiveC +----------------- +### Synopsis +Objective C PipeScript Transpiler. + +--- +### Description + +Transpiles Objective C/C++ with Inline PipeScript into Objective C/C++. + +Multiline comments with /*{}*/ will be treated as blocks of PipeScript. + +Multiline comments can be preceeded or followed by 'empty' syntax, which will be ignored. + +This for Inline PipeScript to be used with operators, and still be valid C/C++ syntax. + +The Objective C Inline Transpiler will consider the following syntax to be empty: + +* ```null``` +* ```nil``` +* ```""``` +* ```''``` + +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.ObjectiveC [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.OpenSCAD.md b/docs/Inline.OpenSCAD.md new file mode 100644 index 000000000..0db66ef3f --- /dev/null +++ b/docs/Inline.OpenSCAD.md @@ -0,0 +1,65 @@ + +Inline.OpenSCAD +--------------- +### Synopsis +OpenSCAD Inline PipeScript Transpiler. + +--- +### Description + +Transpiles OpenSCAD with Inline PipeScript into OpenSCAD. + +Multiline comments with /*{}*/ will be treated as blocks of PipeScript. + +Multiline comments can be preceeded or followed by 'empty' syntax, which will be ignored. + +This for Inline PipeScript to be used with operators, and still be valid OpenSCAD syntax. + +The OpenSCAD Inline Transpiler will consider the following syntax to be empty: + +* ```"[^"]+"``` +* ```[\d\.]+``` + +--- +### Examples +#### EXAMPLE 1 +```PowerShell +{ + $OpenScadWithInlinePipeScript = @' +Shape = "cube" /*{'"cube"', '"sphere"', '"circle"' | Get-Random}*/; +Size = 1 /*{Get-Random -Min 1 -Max 100}*/ ; +``` +if (Shape == "cube") { +cube(Size); +} +if (Shape == "sphere") { +sphere(Size); +} +if (Shape == "circle") { +circle(Size); +} +'@ + + [OutputFile(".\RandomShapeAndSize.ps1.scad")]$OpenScadWithInlinePipeScript +} + +.> .\RandomShapeAndSize.ps1.scad +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.OpenSCAD [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.PHP.md b/docs/Inline.PHP.md new file mode 100644 index 000000000..6092efeca --- /dev/null +++ b/docs/Inline.PHP.md @@ -0,0 +1,34 @@ + +Inline.PHP +---------- +### Synopsis +PHP PipeScript Transpiler. + +--- +### Description + +Transpiles PHP with Inline PipeScript into PHP. + +Multiline comments blocks like this `````` will be treated as blocks of PipeScript. + +JavaScript/CSS/PHP comment blocks like ```/*{}*/``` will also be treated as blocks of PipeScript. + +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.PHP [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.PSD1.md b/docs/Inline.PSD1.md new file mode 100644 index 000000000..3423e2720 --- /dev/null +++ b/docs/Inline.PSD1.md @@ -0,0 +1,37 @@ + +Inline.PSD1 +----------- +### Synopsis +PSD1 Inline PipeScript Transpiler. + +--- +### Description + +Transpiles PSD1 with Inline PipeScript into PSD1. + +Multiline comments blocks enclosed with {} will be treated as Blocks of PipeScript. + +Multiline comments can be preceeded or followed by single-quoted strings, which will be ignored. + +* ```''``` +* ```{}``` + +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.PSD1 [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.Perl.md b/docs/Inline.Perl.md new file mode 100644 index 000000000..418d59292 --- /dev/null +++ b/docs/Inline.Perl.md @@ -0,0 +1,50 @@ + +Inline.Perl +----------- +### Synopsis +Perl Inline PipeScript Transpiler. + +--- +### Description + +Transpiles Perl with Inline PipeScript into Perl. + +Also Transpiles Plain Old Document + +PipeScript can be embedded in a Plain Old Document block that starts with ```=begin PipeScript``` and ends with ```=end PipeScript```. + +--- +### Examples +#### EXAMPLE 1 +```PowerShell +{ + $HelloWorldPerl = @' +=begin PipeScript +$msg = "hello", "hi", "hey", "howdy" | Get-Random +"print(" + '"' + $msg + '");' +=end PipeScript +'@ +``` +[Save(".\HelloWorld.ps1.pl")]$HelloWorldPerl +} + +.> .\HelloWorld.ps1.pl +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.Perl [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.Python.md b/docs/Inline.Python.md new file mode 100644 index 000000000..c7b07cb91 --- /dev/null +++ b/docs/Inline.Python.md @@ -0,0 +1,51 @@ + +Inline.Python +------------- +### Synopsis +Python Inline PipeScript Transpiler. + +--- +### Description + +Transpiles Python with Inline PipeScript into Python. + +Because Python does not support multiline comment blocks, PipeScript can be written inline inside of multiline string + +PipeScript can be included in a Python string that starts and ends with ```{}```, for example ```"""{}"""``` + +--- +### Examples +#### EXAMPLE 1 +```PowerShell +{ + $pythonContent = @' +"""{ +$msg = "Hello World", "Hey There", "Howdy" | Get-Random +@" +print("$msg") +"@ +}""" +'@ + [OutputFile('.\HelloWorld.ps1.py')]$PythonContent +} +``` +.> .\HelloWorld.ps1.py +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.Python [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.RSS.md b/docs/Inline.RSS.md new file mode 100644 index 000000000..c928d51d9 --- /dev/null +++ b/docs/Inline.RSS.md @@ -0,0 +1,32 @@ + +Inline.RSS +---------- +### Synopsis +RSS Inline PipeScript Transpiler. + +--- +### Description + +Transpiles RSS with Inline PipeScript into RSS. + +Multiline comments blocks like this `````` will be treated as blocks of PipeScript. + +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.RSS [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.Razor.md b/docs/Inline.Razor.md new file mode 100644 index 000000000..bac034580 --- /dev/null +++ b/docs/Inline.Razor.md @@ -0,0 +1,36 @@ + +Inline.Razor +------------ +### Synopsis +Razor Inline PipeScript Transpiler. + +--- +### Description + +Transpiles Razor with Inline PipeScript into Razor. + +Multiline comments blocks like this `````` will be treated as blocks of PipeScript. + +JavaScript/CSS comment blocks like ```/*{}*/``` will also be treated as blocks of PipeScript. + +Razor comment blocks like ```@*{}*@``` will also be treated as blocks of PipeScript. + +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.Razor [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.Ruby.md b/docs/Inline.Ruby.md new file mode 100644 index 000000000..61f93903a --- /dev/null +++ b/docs/Inline.Ruby.md @@ -0,0 +1,32 @@ + +Inline.Ruby +----------- +### Synopsis +Ruby Inline PipeScript Transpiler. + +--- +### Description + +Transpiles Ruby with Inline PipeScript into Ruby. + +PipeScript can be embedded in a multiline block that starts with ```=begin{``` and ends with } (followed by ```=end```) + +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.Ruby [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.Rust.md b/docs/Inline.Rust.md new file mode 100644 index 000000000..ba42842ed --- /dev/null +++ b/docs/Inline.Rust.md @@ -0,0 +1,32 @@ + +Inline.Rust +----------- +### Synopsis +Rust Inline PipeScript Transpiler. + +--- +### Description + +Transpiles Rust with Inline PipeScript into Rust. + +Multiline comments with /*{}*/ will be treated as blocks of PipeScript. + +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.Rust [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.TOML.md b/docs/Inline.TOML.md new file mode 100644 index 000000000..dd15147f0 --- /dev/null +++ b/docs/Inline.TOML.md @@ -0,0 +1,47 @@ + +Inline.TOML +----------- +### Synopsis +TOML Inline PipeScript Transpiler. + +--- +### Description + +Transpiles TOML with Inline PipeScript into TOML. + +Because TOML does not support comment blocks, PipeScript can be written inline inside of specialized Multiline string + +PipeScript can be included in a TOML string that starts and ends with ```{}```, for example ```"""{}"""``` + +--- +### Examples +#### EXAMPLE 1 +```PowerShell +{ + $tomlContent = @' +[seed] +RandomNumber = """{Get-Random}""" +'@ + [OutputFile('.\RandomExample.ps1.toml')]$tomlContent +} +``` +.> .\RandomExample.ps1.toml +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.TOML [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.TypeScript.md b/docs/Inline.TypeScript.md new file mode 100644 index 000000000..ad16e6db0 --- /dev/null +++ b/docs/Inline.TypeScript.md @@ -0,0 +1,43 @@ + +Inline.TypeScript +----------------- +### Synopsis +TypeScript Inline PipeScript Transpiler. + +--- +### Description + +Transpiles TypeScript with Inline PipeScript into TypeScript. + +Multiline comments with /*{}*/ will be treated as blocks of PipeScript. + +Multiline comments can be preceeded or followed by 'empty' syntax, which will be ignored. + +This is so that Inline PipeScript can be used with operators, and still be valid TypeScript syntax. + +The TypeScript Inline Transpiler will consider the following syntax to be empty: + +* ```undefined``` +* ```null``` +* ```""``` +* ```''``` + +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.TypeScript [-CommandInfo] [] +``` +--- + + diff --git a/docs/Inline.XML.md b/docs/Inline.XML.md new file mode 100644 index 000000000..48e2972b2 --- /dev/null +++ b/docs/Inline.XML.md @@ -0,0 +1,32 @@ + +Inline.XML +---------- +### Synopsis +XML Inline PipeScript Transpiler. + +--- +### Description + +Transpiles XML with Inline PipeScript into XML. + +Multiline comments blocks like this `````` will be treated as blocks of PipeScript. + +--- +### Parameters +#### **CommandInfo** + +The command information. This will include the path to the file. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|--------------| +|```[Object]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +Inline.XML [-CommandInfo] [] +``` +--- + + diff --git a/docs/ModuleExports.md b/docs/ModuleExports.md new file mode 100644 index 000000000..8aa20faf6 --- /dev/null +++ b/docs/ModuleExports.md @@ -0,0 +1,65 @@ + +ModuleExports +------------- +### Synopsis +Gets Module Exports + +--- +### Description + +Gets Exported Commands from a module. + +--- +### Examples +#### EXAMPLE 1 +```PowerShell +{ + $PipeScriptModule = Get-Module PipeScript + $exports = [ModuleExports()]$PipeScriptModule + $exports +} +``` + +--- +### Parameters +#### **CommandType** + +The command type + + + +Valid Values: + +* Alias +* Function +* Filter +* Cmdlet +* ExternalScript +* Application +* Script +* Configuration +* All +|Type |Requried|Postion|PipelineInput| +|----------------------|--------|-------|-------------| +|```[CommandTypes[]]```|false |1 |false | +--- +#### **VariableAST** + +A VariableExpression. This variable must contain a module. + + + +|Type |Requried|Postion|PipelineInput | +|-----------------------------|--------|-------|--------------| +|```[VariableExpressionAst]```|true |named |true (ByValue)| +--- +### Syntax +```PowerShell +ModuleExports [[-CommandType] {Alias | Function | Filter | Cmdlet | ExternalScript | Application | Script | Configuration | All}] [] +``` +```PowerShell +ModuleExports [[-CommandType] {Alias | Function | Filter | Cmdlet | ExternalScript | Application | Script | Configuration | All}] -VariableAST [] +``` +--- + + diff --git a/docs/ModuleRelationship.md b/docs/ModuleRelationship.md new file mode 100644 index 000000000..d339a2c9a --- /dev/null +++ b/docs/ModuleRelationship.md @@ -0,0 +1,45 @@ + +ModuleRelationship +------------------ +### Synopsis +Gets Module Relationships + +--- +### Description + +Gets Modules that are related to a given module. + +Modules can be related to each other by a few mechanisms: + +* A Module Can Include another Module's Name in it's ```.PrivateData.PSData.Tags``` +* A Module Can include data for another module it it's ```.PrivataData.``` + +--- +### Examples +#### EXAMPLE 1 +```PowerShell +{ + $Module = Get-Module PipeScript + [ModuleRelationships()]$Module +} +``` + +--- +### Parameters +#### **VariableAST** + +A VariableExpression. This variable must contain a module or name of module. + + + +|Type |Requried|Postion|PipelineInput | +|-----------------------------|--------|-------|--------------| +|```[VariableExpressionAst]```|true |named |true (ByValue)| +--- +### Syntax +```PowerShell +ModuleRelationship -VariableAST [] +``` +--- + + diff --git a/docs/New-PipeScript.md b/docs/New-PipeScript.md new file mode 100644 index 000000000..120f93cb2 --- /dev/null +++ b/docs/New-PipeScript.md @@ -0,0 +1,92 @@ + +New-PipeScript +-------------- +### Synopsis +Creates new PipeScript. + +--- +### Description + +Creates new PipeScript and PowerShell ScriptBlocks. + +--- +### Examples +#### EXAMPLE 1 +```PowerShell +New-PipeScript -Parameter @{a='b'} +``` + +--- +### Parameters +#### **Parameter** + +Defines one or more parameters for a ScriptBlock. +Parameters can be defined in a few ways: +* As a ```[Collections.Dictionary]``` of Parameters +* As the ```[string]``` name of an untyped parameter. +* As an ```[Object[]]```. +* As a ```[ScriptBlock]``` + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|---------------------| +|```[Object]```|false |1 |true (ByPropertyName)| +--- +#### **DynamicParameter** + +The dynamic parameter block. + + + +|Type |Requried|Postion|PipelineInput | +|-------------------|--------|-------|---------------------| +|```[ScriptBlock]```|false |2 |true (ByPropertyName)| +--- +#### **Begin** + +The begin block. + + + +|Type |Requried|Postion|PipelineInput | +|-------------------|--------|-------|---------------------| +|```[ScriptBlock]```|false |3 |true (ByPropertyName)| +--- +#### **Process** + +The process block. + + + +|Type |Requried|Postion|PipelineInput | +|-------------------|--------|-------|---------------------| +|```[ScriptBlock]```|false |4 |true (ByPropertyName)| +--- +#### **End** + +The end block. + + + +|Type |Requried|Postion|PipelineInput | +|-------------------|--------|-------|---------------------| +|```[ScriptBlock]```|false |5 |true (ByPropertyName)| +--- +#### **Header** + +The script header. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|---------------------| +|```[String]```|false |6 |true (ByPropertyName)| +--- +### Syntax +```PowerShell +New-PipeScript [[-Parameter] ] [[-DynamicParameter] ] [[-Begin] ] [[-Process] ] [[-End] ] [[-Header] ] [] +``` +--- + + diff --git a/docs/OutputFile.md b/docs/OutputFile.md new file mode 100644 index 000000000..577bd0329 --- /dev/null +++ b/docs/OutputFile.md @@ -0,0 +1,104 @@ + +OutputFile +---------- +### Synopsis +Outputs to a File + +--- +### Description + +Outputs the result of a script into a file. + +--- +### Examples +#### EXAMPLE 1 +```PowerShell +Invoke-PipeScript { + [OutputFile("hello.txt")] + param() +``` +'hello world' +} +#### EXAMPLE 2 +```PowerShell +Invoke-PipeScript { + param() +``` +$Message = 'hello world' + [Save(".\Hello.txt")]$Message +} +--- +### Parameters +#### **OutputPath** + +The Output Path + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[String]```|true |1 |false | +--- +#### **ScriptBlock** + +The Script Block that will be run. + + + +|Type |Requried|Postion|PipelineInput | +|-------------------|--------|-------|--------------| +|```[ScriptBlock]```|false |2 |true (ByValue)| +--- +#### **VariableAst** + +|Type |Requried|Postion|PipelineInput | +|-----------------------------|--------|-------|--------------| +|```[VariableExpressionAst]```|false |3 |true (ByValue)| +--- +#### **Encoding** + +The encoding parameter. + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[String]```|false |4 |false | +--- +#### **Force** + +If set, will force output, overwriting existing files. + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[Switch]```|false |named |false | +--- +#### **ExportScript** + +The export script + + + +|Type |Requried|Postion|PipelineInput| +|-------------------|--------|-------|-------------| +|```[ScriptBlock]```|false |5 |false | +--- +#### **Depth** + +The serialization depth. Currently only used when saving to JSON files. + + + +|Type |Requried|Postion|PipelineInput| +|-------------|--------|-------|-------------| +|```[Int32]```|false |6 |false | +--- +### Syntax +```PowerShell +OutputFile [-OutputPath] [[-ScriptBlock] ] [[-VariableAst] ] [[-Encoding] ] [-Force] [[-ExportScript] ] [[-Depth] ] [] +``` +--- + + diff --git a/docs/PipeScript.AttributedExpression.md b/docs/PipeScript.AttributedExpression.md new file mode 100644 index 000000000..3f61a2848 --- /dev/null +++ b/docs/PipeScript.AttributedExpression.md @@ -0,0 +1,37 @@ + +PipeScript.AttributedExpression +------------------------------- +### Synopsis +The PipeScript AttributedExpression Transpiler + +--- +### Description + +AttributedExpressions will be transpiled + +AttributedExpressions often apply to variables, for instance: + +```PowerShell +$hello = 'hello world' +[OutputFile(".\Hello.txt")]$hello +```PowerShell + +--- +### Parameters +#### **AttributedExpressionAst** + +The attributed expression + + + +|Type |Requried|Postion|PipelineInput | +|-------------------------------|--------|-------|--------------| +|```[AttributedExpressionAst]```|true |named |true (ByValue)| +--- +### Syntax +```PowerShell +PipeScript.AttributedExpression -AttributedExpressionAst [] +``` +--- + + diff --git a/docs/PipeScript.Inline.md b/docs/PipeScript.Inline.md new file mode 100644 index 000000000..90f728de4 --- /dev/null +++ b/docs/PipeScript.Inline.md @@ -0,0 +1,130 @@ + +PipeScript.Inline +----------------- +### Synopsis +Inline Transpiler + +--- +### Description + +The PipeScript Core Inline Transpiler. This makes Source Generators with inline PipeScript work. + +Regardless of underlying source language, a source generator works in a fairly straightforward way. + +Inline PipeScript will be embedded within the file (usually in comments). + +If a Regular Expression can match each section, then the content in each section can be replaced. + +--- +### Parameters +#### **SourceText** + +A string containing the text contents of the file + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[String]```|true |named |false | +--- +#### **ReplacePattern** + +|Type |Requried|Postion|PipelineInput| +|-------------|--------|-------|-------------| +|```[Regex]```|true |named |false | +--- +#### **StartPattern** + +The Start Pattern. +This indicates the beginning of what should be considered PipeScript. +An expression will match everything until -EndPattern + + + +|Type |Requried|Postion|PipelineInput| +|-------------|--------|-------|-------------| +|```[Regex]```|true |named |false | +--- +#### **EndPattern** + +The End Pattern +This indicates the end of what should be considered PipeScript. + + + +|Type |Requried|Postion|PipelineInput| +|-------------|--------|-------|-------------| +|```[Regex]```|true |named |false | +--- +#### **ReplacementEvaluator** + +A custom replacement evaluator. +If not provided, will run any embedded scripts encountered. +The output of these scripts will be the replacement text. + + + +|Type |Requried|Postion|PipelineInput| +|-------------------|--------|-------|-------------| +|```[ScriptBlock]```|false |named |false | +--- +#### **NoTranspile** + +If set, will not transpile script blocks. + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[Switch]```|false |named |false | +--- +#### **SourceFile** + +The path to the source file. + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[String]```|false |named |false | +--- +#### **Begin** + +A Script Block that will be injected before each inline is run. + + + +|Type |Requried|Postion|PipelineInput| +|-------------------|--------|-------|-------------| +|```[ScriptBlock]```|false |named |false | +--- +#### **ForeachObject** + +A Script Block that will be piped to after each output. + + + +|Type |Requried|Postion|PipelineInput| +|-------------------|--------|-------|-------------| +|```[ScriptBlock]```|false |named |false | +--- +#### **End** + +A Script Block that will be injected after each inline script is run. + + + +|Type |Requried|Postion|PipelineInput| +|-------------------|--------|-------|-------------| +|```[ScriptBlock]```|false |named |false | +--- +### Syntax +```PowerShell +PipeScript.Inline -SourceText -StartPattern -EndPattern [-ReplacementEvaluator ] [-NoTranspile] [-SourceFile ] [-Begin ] [-ForeachObject ] [-End ] [] +``` +```PowerShell +PipeScript.Inline -SourceText -ReplacePattern [-ReplacementEvaluator ] [-NoTranspile] [-SourceFile ] [-Begin ] [-ForeachObject ] [-End ] [] +``` +--- + + diff --git a/docs/PipeScript.ParameterAttribute.md b/docs/PipeScript.ParameterAttribute.md new file mode 100644 index 000000000..66c3ad42b --- /dev/null +++ b/docs/PipeScript.ParameterAttribute.md @@ -0,0 +1,3 @@ +PipeScript.ParameterAttribute.psx.ps1 -AttributeAst [] + + diff --git a/docs/PipeScript.ParameterTypeConstraint.md b/docs/PipeScript.ParameterTypeConstraint.md new file mode 100644 index 000000000..83de9e45d --- /dev/null +++ b/docs/PipeScript.ParameterTypeConstraint.md @@ -0,0 +1,3 @@ +PipeScript.ParameterTypeConstraint.psx.ps1 -TypeConstraintAST [] + + diff --git a/docs/PipeScript.TypeExpression.md b/docs/PipeScript.TypeExpression.md new file mode 100644 index 000000000..034073282 --- /dev/null +++ b/docs/PipeScript.TypeExpression.md @@ -0,0 +1,39 @@ + +PipeScript.TypeExpression +------------------------- +### Synopsis +The PipeScript TypeExpression Transpiler + +--- +### Description + +Type Expressions may be transpiled. + +--- +### Examples +#### EXAMPLE 1 +```PowerShell +{ + [include[a.ps1]] +} | .>PipeScript +``` + +--- +### Parameters +#### **TypeExpressionAst** + +The attributed expression + + + +|Type |Requried|Postion|PipelineInput | +|-------------------------|--------|-------|--------------| +|```[TypeExpressionAst]```|true |named |true (ByValue)| +--- +### Syntax +```PowerShell +PipeScript.TypeExpression -TypeExpressionAst [] +``` +--- + + diff --git a/docs/PipedAssignment.md b/docs/PipedAssignment.md new file mode 100644 index 000000000..ccc683816 --- /dev/null +++ b/docs/PipedAssignment.md @@ -0,0 +1,50 @@ + +PipedAssignment +--------------- +### Synopsis +Piped Assignment Transpiler + +--- +### Description + +Enables Piped Assignment (```|=|```). + +Piped Assignment allows for an expression to be reassigned based off of the pipeline input. + +--- +### Examples +#### EXAMPLE 1 +```PowerShell +{ + $Collection |=| Where-Object Name -match $Pattern +} | .>PipeScript +``` +# This will become: + +$Collection = $Collection | Where-Object Name -match $pattern +#### EXAMPLE 2 +```PowerShell +{ + $Collection |=| Where-Object Name -match $pattern | Select-Object -ExpandProperty Name +} | .>PipeScript +``` +# This will become + +$Collection = $Collection | + Where-Object Name -match $pattern | + Select-Object -ExpandProperty Name +--- +### Parameters +#### **PipelineAst** + +|Type |Requried|Postion|PipelineInput | +|-------------------|--------|-------|--------------| +|```[PipelineAst]```|true |1 |true (ByValue)| +--- +### Syntax +```PowerShell +PipedAssignment [-PipelineAst] [] +``` +--- + + diff --git a/docs/Pipescript.FunctionDefinition.md b/docs/Pipescript.FunctionDefinition.md new file mode 100644 index 000000000..72b5b30ce --- /dev/null +++ b/docs/Pipescript.FunctionDefinition.md @@ -0,0 +1,30 @@ + +Pipescript.FunctionDefinition +----------------------------- +### Synopsis +PipeScript Function Transpiler + +--- +### Description + +Transpiles Function Definitions. + +--- +### Parameters +#### **FunctionDefinition** + +An abstract syntax tree function definition. + + + +|Type |Requried|Postion|PipelineInput | +|-----------------------------|--------|-------|--------------| +|```[FunctionDefinitionAst]```|true |named |true (ByValue)| +--- +### Syntax +```PowerShell +Pipescript.FunctionDefinition -FunctionDefinition [] +``` +--- + + diff --git a/docs/Pipescript.md b/docs/Pipescript.md new file mode 100644 index 000000000..561ff601b --- /dev/null +++ b/docs/Pipescript.md @@ -0,0 +1,93 @@ + +Pipescript +---------- +### Synopsis +The Core PipeScript Transpiler + +--- +### Description + +The Core PipeScript Transpiler. + +This will convert various portions in the PowerShell Abstract Syntax Tree from their PipeScript syntax into regular PowerShell. + +It will run other converters as directed by the source code. + +--- +### Related Links +* [.>Pipescript.Function](.>Pipescript.Function.md) +* [.>Pipescript.AttributedExpression](.>Pipescript.AttributedExpression.md) +--- +### Examples +#### EXAMPLE 1 +```PowerShell +{ + function [explicit]ExplicitOutput { + "whoops" + return 1 + } +} | .>PipeScript +``` + +#### EXAMPLE 2 +```PowerShell +{ + [minify]{ + # Requires PSMinifier (this comment will be minified away) + "blah" + "de" + "blah" + } +} | .>PipeScript +``` + +#### EXAMPLE 3 +```PowerShell +.\PipeScript.psx.ps1 -ScriptBlock { + [bash]{param([string]$Message) $message} +} +``` + +#### EXAMPLE 4 +```PowerShell +.\PipeScript.psx.ps1 -ScriptBlock { + [explicit]{1;2;3;echo 4} +} +``` + +#### EXAMPLE 5 +```PowerShell +{ + function [ProxyCommand<'Get-Process'>]GetProcessProxy {} +} | .>PipeScript +``` + +--- +### Parameters +#### **ScriptBlock** + +A ScriptBlock that will be transpiled. + + + +|Type |Requried|Postion|PipelineInput | +|-------------------|--------|-------|--------------| +|```[ScriptBlock]```|true |named |true (ByValue)| +--- +#### **Transpiler** + +One or more transpilation expressions that apply to the script block. + + + +|Type |Requried|Postion|PipelineInput| +|----------------|--------|-------|-------------| +|```[String[]]```|false |named |false | +--- +### Syntax +```PowerShell +Pipescript -ScriptBlock [-Transpiler ] [] +``` +--- + + diff --git a/docs/ProxyCommand-Transpiler.md b/docs/ProxyCommand.md similarity index 89% rename from docs/ProxyCommand-Transpiler.md rename to docs/ProxyCommand.md index 426407a23..9f2c3fe21 100644 --- a/docs/ProxyCommand-Transpiler.md +++ b/docs/ProxyCommand.md @@ -1,6 +1,6 @@ -Transpilers/ProxyCommand.psx.ps1 --------------------------------- +ProxyCommand +------------ ### Synopsis Creates Proxy Commands @@ -103,7 +103,7 @@ Any default parameters for the ProxyCommand. --- ### Syntax ```PowerShell -Transpilers/ProxyCommand.psx.ps1 [-ScriptBlock ] [-CommandName] [-RemoveParameter ] [-DefaultParameter ] [] +ProxyCommand [-ScriptBlock ] [-CommandName] [-RemoveParameter ] [-DefaultParameter ] [] ``` --- diff --git a/docs/RegexLiteral.md b/docs/RegexLiteral.md new file mode 100644 index 000000000..026c149d0 --- /dev/null +++ b/docs/RegexLiteral.md @@ -0,0 +1,109 @@ + +RegexLiteral +------------ +### Synopsis +Regex Literal Transpiler + +--- +### Description + +Allows for Regex Literals within PipeScript. + +Regex Literals are strings enclosed within slashes. + +The ending slash may be followed by ```[Text.RegularExpressions.RegexOptions]```. + +--- +### Examples +#### EXAMPLE 1 +```PowerShell +{ + '/[a|b]/' +} | .>PipeScript +``` +# This will become: + +[regex]::new('[a|b]', 'IgnoreCase') +#### EXAMPLE 2 +```PowerShell +Invoke-PipeScript { + '/[a|b]/'.Matches('ab') +} +``` + +#### EXAMPLE 3 +```PowerShell +{ + "/[$a|$b]/" +} | .>PipeScript +``` +# This will become: + +[regex]::new("[$a|$b]", 'IgnoreCase') +#### EXAMPLE 4 +```PowerShell +{ +@' +/ +# Heredocs Regex literals will have IgnorePatternWhitespace by default, which allows comments +^ # Match the string start +(?\s{0,1}) +/ +'@ +} | .>PipeScript +``` +# This will become: + +[regex]::new(@' +# Heredocs Regex literals will have IgnorePatternWhitespace by default, which allows comments +^ # Match the string start +(?\s{0,1}) +'@, 'IgnorePatternWhitespace,IgnoreCase') +#### EXAMPLE 5 +```PowerShell +$Keywords = "looking", "for", "these", "words" +``` +{ +@" +/ +# Double quoted heredocs can still contain variables +[\s\p{P}]{0,1} # Whitespace or punctuation +$($Keywords -join '|') # followed by keywords +[\s\p{P}]{0,1} # followed by whitespace or punctuation +/ +"@ +} | .>PipeScript + + +# This will become: + +[regex]::new(@" +# Double quoted heredocs can still contain variables +[\s\p{P}]{0,1} # Whitespace or punctuation +$($Keywords -join '|') # followed by keywords +[\s\p{P}]{0,1} # followed by whitespace or punctuation +"@, 'IgnorePatternWhitespace,IgnoreCase') +--- +### Parameters +#### **StringConstantExpression** + +|Type |Requried|Postion|PipelineInput | +|-----------------------------------|--------|-------|--------------| +|```[StringConstantExpressionAst]```|true |named |true (ByValue)| +--- +#### **ExpandableStringExpression** + +|Type |Requried|Postion|PipelineInput | +|-------------------------------------|--------|-------|--------------| +|```[ExpandableStringExpressionAst]```|true |named |true (ByValue)| +--- +### Syntax +```PowerShell +RegexLiteral -StringConstantExpression [] +``` +```PowerShell +RegexLiteral -ExpandableStringExpression [] +``` +--- + + diff --git a/docs/Rest.md b/docs/Rest.md new file mode 100644 index 000000000..e73f13b66 --- /dev/null +++ b/docs/Rest.md @@ -0,0 +1,203 @@ + +Rest +---- +### Synopsis +Generates PowerShell to talk to a REST api. + +--- +### Description + +Generates PowerShell that communicates with a REST api. + +--- +### Examples +#### EXAMPLE 1 +```PowerShell +{ + function Get-Sentiment { + [Rest("http://text-processing.com/api/sentiment/", + ContentType="application/x-www-form-urlencoded", + Method = "POST", + BodyParameter="Text", + ForeachOutput = { + $_ | Select-Object -ExpandProperty Probability -Property Label + } + )] + param() + } +} | .>PipeScript | Set-Content .\Get-Sentiment.ps1 +``` + +#### EXAMPLE 2 +```PowerShell +Invoke-PipeScript { + [Rest("http://text-processing.com/api/sentiment/", + ContentType="application/x-www-form-urlencoded", + Method = "POST", + BodyParameter="Text", + ForeachOutput = { + $_ | Select-Object -ExpandProperty Probability -Property Label + } + )] + param() +} -Parameter @{Text='wow!'} +``` + +#### EXAMPLE 3 +```PowerShell +{ + [Rest("https://api.github.com/users/{username}/repos", + QueryParameter={"type", "sort", "direction", "page", "per_page"} + )] + param() +} | .>PipeScript +``` + +#### EXAMPLE 4 +```PowerShell +Invoke-PipeScript { + [Rest("https://api.github.com/users/{username}/repos", + QueryParameter={"type", "sort", "direction", "page", "per_page"} + )] + param() +} -UserName StartAutomating +``` + +#### EXAMPLE 5 +```PowerShell +{ + [Rest("http://text-processing.com/api/sentiment/", + ContentType="application/x-www-form-urlencoded", + Method = "POST", + BodyParameter={@{ + Text = ' + [Parameter(Mandatory,ValueFromPipelineByPropertyName)] + [string] + $Text + ' + }})] + param() +} | .>PipeScript +``` + +--- +### Parameters +#### **ScriptBlock** + +The ScriptBlock. +If not empty, the contents of this ScriptBlock will preceed the REST api call. + + + +|Type |Requried|Postion|PipelineInput | +|-------------------|--------|-------|--------------| +|```[ScriptBlock]```|false |named |true (ByValue)| +--- +#### **RESTEndpoint** + +One or more REST endpoints. This endpoint will be parsed for REST variables. + + + +|Type |Requried|Postion|PipelineInput| +|----------------|--------|-------|-------------| +|```[String[]]```|true |1 |false | +--- +#### **ContentType** + +The content type. If provided, this parameter will be passed to the -InvokeCommand. + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[String]```|false |named |false | +--- +#### **Method** + +The method. If provided, this parameter will be passed to the -InvokeCommand. + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[String]```|false |named |false | +--- +#### **InvokeCommand** + +The invoke command. This command _must_ have a parameter -URI. + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[String]```|false |named |false | +--- +#### **InvokeParameterVariable** + +The name of a variable containing additional invoke parameters. +By default, this is 'InvokeParams' + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[String]```|false |named |false | +--- +#### **UriParameterHelp** + +A dictionary of help for uri parameters. + + + +|Type |Requried|Postion|PipelineInput| +|-------------------|--------|-------|-------------| +|```[IDictionary]```|false |named |false | +--- +#### **UriParameterType** + +A dictionary of URI parameter types. + + + +|Type |Requried|Postion|PipelineInput| +|-------------------|--------|-------|-------------| +|```[IDictionary]```|false |named |false | +--- +#### **BodyParameter** + +A dictionary or list of parameters for the body. + + + +|Type |Requried|Postion|PipelineInput| +|----------------|--------|-------|-------------| +|```[PSObject]```|false |named |false | +--- +#### **QueryParameter** + +A dictionary or list of query parameters. + + + +|Type |Requried|Postion|PipelineInput| +|----------------|--------|-------|-------------| +|```[PSObject]```|false |named |false | +--- +#### **ForEachOutput** + +A script block to be run on each output. + + + +|Type |Requried|Postion|PipelineInput| +|-------------------|--------|-------|-------------| +|```[ScriptBlock]```|false |named |false | +--- +### Syntax +```PowerShell +Rest [-ScriptBlock ] [-RESTEndpoint] [-ContentType ] [-Method ] [-InvokeCommand ] [-InvokeParameterVariable ] [-UriParameterHelp ] [-UriParameterType ] [-BodyParameter ] [-QueryParameter ] [-ForEachOutput ] [] +``` +--- + + diff --git a/docs/Search-PipeScript.md b/docs/Search-PipeScript.md new file mode 100644 index 000000000..cc87754d7 --- /dev/null +++ b/docs/Search-PipeScript.md @@ -0,0 +1,91 @@ + +Search-PipeScript +----------------- +### Synopsis +Searches PowerShell and PipeScript ScriptBlocks + +--- +### Description + +Searches PowerShell and PipeScript ScriptBlocks, files, and text + +--- +### Related Links +* [Update-PipeScript](Update-PipeScript.md) +--- +### Examples +#### EXAMPLE 1 +```PowerShell +Search-PipeScript -ScriptBlock { + $a + $b + $c + "text" +} -AstType Variable +``` + +--- +### Parameters +#### **InputObject** + +The ScriptBlock that will be searched. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|------------------------------| +|```[Object]```|false |1 |true (ByValue, ByPropertyName)| +--- +#### **AstCondition** + +The AST Condition. +These Script Blocks + + + +|Type |Requried|Postion|PipelineInput | +|---------------------|--------|-------|---------------------| +|```[ScriptBlock[]]```|false |2 |true (ByPropertyName)| +--- +#### **AstType** + +A shortname for the abstract syntax tree types. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|---------------------| +|```[Object]```|false |3 |true (ByPropertyName)| +--- +#### **RegularExpression** + +One or more regular expressions to match. + + + +|Type |Requried|Postion|PipelineInput | +|--------------|--------|-------|---------------------| +|```[Object]```|false |4 |true (ByPropertyName)| +--- +#### **Recurse** + +If set, will search nested script blocks. + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[Switch]```|false |named |false | +--- +### Outputs +Search.PipeScript.Result + + +--- +### Syntax +```PowerShell +Search-PipeScript [[-InputObject] ] [[-AstCondition] ] [[-AstType] ] [[-RegularExpression] ] [-Recurse] [] +``` +--- + + diff --git a/docs/VBN.md b/docs/VBN.md new file mode 100644 index 000000000..4c6f6cc57 --- /dev/null +++ b/docs/VBN.md @@ -0,0 +1,60 @@ + +VBN +--- +### Synopsis +ValueFromPiplineByPropertyName Shorthand + +--- +### Description + +This is syntax shorthand to create [Parameter] attributes that take ValueFromPipelineByPropertyName. + +--- +### Parameters +#### **ParameterSet** + +The name of the parameter set + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[String]```|false |1 |false | +--- +#### **Mandatory** + +If set, the parameter will be Mandatory. + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[Switch]```|false |named |false | +--- +#### **ValueFromPipeline** + +If set, the parameter will also take value from Pipeline + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[Switch]```|false |named |false | +--- +#### **Position** + +The position of the parameter. + + + +|Type |Requried|Postion|PipelineInput| +|-------------|--------|-------|-------------| +|```[Int32]```|false |2 |false | +--- +### Syntax +```PowerShell +VBN [[-ParameterSet] ] [-Mandatory] [-ValueFromPipeline] [[-Position] ] [] +``` +--- + + diff --git a/docs/VFP.md b/docs/VFP.md new file mode 100644 index 000000000..269a96f20 --- /dev/null +++ b/docs/VFP.md @@ -0,0 +1,60 @@ + +VFP +--- +### Synopsis +ValueFromPipline Shorthand + +--- +### Description + +This is syntax shorthand to create [Parameter] attributes that take ValueFromPipeline. + +--- +### Parameters +#### **ParameterSet** + +The parameter set name. + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[String]```|false |1 |false | +--- +#### **Mandatory** + +If set, will mark this parameter as mandatory (within this parameter set). + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[Switch]```|false |named |false | +--- +#### **ValueFromPipelineByPropertyName** + +If set, will also mark this parameter as taking ValueFromPipelineByPropertyName. + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[Switch]```|false |named |false | +--- +#### **Position** + +The position of the parameter. + + + +|Type |Requried|Postion|PipelineInput| +|-------------|--------|-------|-------------| +|```[Int32]```|false |2 |false | +--- +### Syntax +```PowerShell +VFP [[-ParameterSet] ] [-Mandatory] [-ValueFromPipelineByPropertyName] [[-Position] ] [] +``` +--- + + diff --git a/docs/ValidateExtension.md b/docs/ValidateExtension.md new file mode 100644 index 000000000..ded298219 --- /dev/null +++ b/docs/ValidateExtension.md @@ -0,0 +1,78 @@ + +ValidateExtension +----------------- +### Synopsis +Validates Extensions + +--- +### Description + +Validates that a parameter or object has one or more extensions. + +This creates a [ValidatePattern] that will ensure the extension matches. + +--- +### Examples +#### EXAMPLE 1 +```PowerShell +{ + param( + [ValidateExtension(Extension=".cs", ".ps1")] + $FilePath + ) +} |.>PipeScript +``` + +#### EXAMPLE 2 +```PowerShell +{ + param( + [ValidateExtension(Extension=".cs", ".ps1")] + $FilePath + ) +``` +$FilePath +} -Parameter @{FilePath=".ps1"} +#### EXAMPLE 3 +```PowerShell +{ + param( + [ValidateExtension(Extension=".cs", ".ps1")] + $FilePath + ) +``` +$FilePath +} -Parameter @{FilePath="foo.txt"} +--- +### Parameters +#### **Extension** + +The extensions being validated. + + + +|Type |Requried|Postion|PipelineInput| +|----------------|--------|-------|-------------| +|```[String[]]```|true |1 |false | +--- +#### **VariableAST** + +A variable expression. +If this is provided, will apply a ```[ValidatePattern({})]``` attribute to the variable, constraining future values. + + + +|Type |Requried|Postion|PipelineInput | +|-----------------------------|--------|-------|--------------| +|```[VariableExpressionAst]```|false |named |true (ByValue)| +--- +### Syntax +```PowerShell +ValidateExtension [-Extension] [] +``` +```PowerShell +ValidateExtension [-Extension] [-VariableAST ] [] +``` +--- + + diff --git a/docs/ValidatePlatform.md b/docs/ValidatePlatform.md new file mode 100644 index 000000000..df5b8f20f --- /dev/null +++ b/docs/ValidatePlatform.md @@ -0,0 +1,57 @@ + +ValidatePlatform +---------------- +### Synopsis +Validates the Platform + +--- +### Description + +Validates the Platform. + +When used within Parameters, this adds a ```[ValidateScript({})]``` to ensure that the platform is correct. + +When used on a ```[Management.Automation.Language.VariableExpressionAst]``` will apply a +```[ValidateScript({})]``` to that variable, which will prevent assignemnt to the variable if not on the platform. + +--- +### Examples +#### EXAMPLE 1 +```PowerShell +{ + param( + [ValidatePlatform("Windows")] + [switch] + $UseWMI + ) +} | .>PipeScript +``` + +--- +### Parameters +#### **Platform** + +The name of one or more platforms. These will be interpreted as wildcards. + + + +|Type |Requried|Postion|PipelineInput| +|----------------|--------|-------|-------------| +|```[String[]]```|true |1 |false | +--- +#### **VariableAST** + +|Type |Requried|Postion|PipelineInput | +|-----------------------------|--------|-------|--------------| +|```[VariableExpressionAst]```|false |named |true (ByValue)| +--- +### Syntax +```PowerShell +ValidatePlatform [-Platform] [] +``` +```PowerShell +ValidatePlatform [-Platform] [-VariableAST ] [] +``` +--- + + diff --git a/docs/ValidatePropertyName.md b/docs/ValidatePropertyName.md new file mode 100644 index 000000000..4d93e1653 --- /dev/null +++ b/docs/ValidatePropertyName.md @@ -0,0 +1,80 @@ + +ValidatePropertyName +-------------------- +### Synopsis +Validates Property Names + +--- +### Description + +Validates that an object has one or more property names. + +--- +### Examples +#### EXAMPLE 1 +```PowerShell +{ + param( + [ValidatePropertyName(PropertyName='a','b')] + $InputObject + ) +} | .>PipeScript +``` + +#### EXAMPLE 2 +```PowerShell +[PSCustomObject]@{a='a';b='b'} | + .> { + param( + [ValidatePropertyName(PropertyName='a','b')] + [vfp] + $InputObject + ) +``` +$InputObject + } +#### EXAMPLE 3 +```PowerShell +@{a='a'} | + .> { + param( + [ValidatePropertyName(PropertyName='a','b')] + [vfp] + $InputObject + ) +``` +$InputObject + } +--- +### Parameters +#### **PropertyName** + +The property names being validated. + + + +|Type |Requried|Postion|PipelineInput| +|----------------|--------|-------|-------------| +|```[String[]]```|true |1 |false | +--- +#### **VariableAST** + +A variable expression. +If this is provided, will apply a ```[ValidateScript({})]``` attribute to the variable, constraining future values. + + + +|Type |Requried|Postion|PipelineInput | +|-----------------------------|--------|-------|--------------| +|```[VariableExpressionAst]```|false |named |true (ByValue)| +--- +### Syntax +```PowerShell +ValidatePropertyName [-PropertyName] [] +``` +```PowerShell +ValidatePropertyName [-PropertyName] [-VariableAST ] [] +``` +--- + + diff --git a/docs/ValidateScriptBlock.md b/docs/ValidateScriptBlock.md new file mode 100644 index 000000000..75182294a --- /dev/null +++ b/docs/ValidateScriptBlock.md @@ -0,0 +1,109 @@ + +ValidateScriptBlock +------------------- +### Synopsis +Validates Script Blocks + +--- +### Description + +Validates Script Blocks for a number of common scenarios. + +--- +### Examples +#### EXAMPLE 1 +```PowerShell +{ + param( + [ValidateScriptBlock(Safe)] + [ScriptBlock] + $ScriptBlock + ) +``` +$ScriptBlock +} | .>PipeScript +#### EXAMPLE 2 +```PowerShell +{ + param( + [ValidateScriptBlock(NoBlock,NoParameters)] + [ScriptBlock] + $ScriptBlock + ) +``` +$ScriptBlock +} | .>PipeScript +#### EXAMPLE 3 +```PowerShell +{ + param( + [ValidateScriptBlock(OnlyParameters)] + [ScriptBlock] + $ScriptBlock + ) +``` +$ScriptBlock +} | .>PipeScript +--- +### Parameters +#### **DataLanguage** + +If set, will validate that ScriptBlock is "safe". +This will attempt to recreate the Script Block as a datalanguage block and execute it. + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[Switch]```|false |named |false | +--- +#### **ParameterOnly** + +If set, will ensure that the [ScriptBlock] only has parameters + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[Switch]```|false |named |false | +--- +#### **NoBlock** + +If set, will ensure that the [ScriptBlock] has no named blocks. + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[Switch]```|false |named |false | +--- +#### **NoParameter** + +If set, will ensure that the [ScriptBlock] has no parameters. + + + +|Type |Requried|Postion|PipelineInput| +|--------------|--------|-------|-------------| +|```[Switch]```|false |named |false | +--- +#### **VariableAST** + +A VariableExpression. If provided, the Validation attributes will apply to this variable. + + + +|Type |Requried|Postion|PipelineInput | +|-----------------------------|--------|-------|--------------| +|```[VariableExpressionAst]```|true |named |true (ByValue)| +--- +### Syntax +```PowerShell +ValidateScriptBlock [-DataLanguage] [-ParameterOnly] [-NoBlock] [-NoParameter] [] +``` +```PowerShell +ValidateScriptBlock [-DataLanguage] [-ParameterOnly] [-NoBlock] [-NoParameter] -VariableAST [] +``` +--- + + diff --git a/docs/ValidateTypes.md b/docs/ValidateTypes.md new file mode 100644 index 000000000..d1f03f61f --- /dev/null +++ b/docs/ValidateTypes.md @@ -0,0 +1,83 @@ + +ValidateTypes +------------- +### Synopsis +Validates if an object is one or more types. + +--- +### Description + +Validates if an object is one or more types. + +This allows for a single parameter to handle multiple potential types. + +--- +### Examples +#### EXAMPLE 1 +```PowerShell +{ + param( + [ValidateTypes(TypeName="ScriptBlock","string")] + $In + ) +} | .>PipeScript +``` + +#### EXAMPLE 2 +```PowerShell +{"hello world"} | + Invoke-PipeScript -ScriptBlock { + param( + [vfp()] + [ValidateTypes(TypeName="ScriptBlock","string")] + $In + ) +``` +$In + } +#### EXAMPLE 3 +```PowerShell +1 | + Invoke-PipeScript -ScriptBlock { + param( + [vfp()] + [ValidateTypes(TypeName="ScriptBlock","string")] + $In + ) +``` +$In + } +--- +### Parameters +#### **TypeName** + +The name of one or more types. +Types can either be a .NET types of .PSTypenames +TypeNames will be treated first as real types, then as exact matches, then as wildcards, and then as regular expressions. + + + +|Type |Requried|Postion|PipelineInput| +|----------------|--------|-------|-------------| +|```[String[]]```|true |1 |false | +--- +#### **VariableAST** + +The variable that will be validated. + + + +|Type |Requried|Postion|PipelineInput | +|-----------------------------|--------|-------|--------------| +|```[VariableExpressionAst]```|false |named |true (ByValue)| +--- +### Syntax +```PowerShell +ValidateTypes [-TypeName] [] +``` +```PowerShell +ValidateTypes [-TypeName] [-VariableAST ] [] +``` +--- + +