summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2012-02-05 12:12:42 +0100
committerGeorg Brandl <georg@python.org>2012-02-05 12:12:42 +0100
commit853ead03f3dea69a76d34e9bb5a85d4df881ed59 (patch)
tree33a34de0fcd85fed440925e319325152ebb5fc42
parentb89ed802bc78e49a2923a656742861c24a49e2c6 (diff)
downloadpygments-853ead03f3dea69a76d34e9bb5a85d4df881ed59.tar.gz
Closes #654: add PowerShell lexer.
-rw-r--r--CHANGES1
-rw-r--r--pygments/lexers/_mapping.py1
-rw-r--r--pygments/lexers/shell.py89
-rw-r--r--tests/examplefiles/test.ps1108
4 files changed, 198 insertions, 1 deletions
diff --git a/CHANGES b/CHANGES
index bb5699c0..65a3bfb8 100644
--- a/CHANGES
+++ b/CHANGES
@@ -34,6 +34,7 @@ Version 1.5
* OpenEdge ABL (PR#27)
* SystemVerilog (PR#35)
* Coq (#734)
+ * PowerShell (#654)
- In the LaTeX formatter, escape special &, < and > chars (#648).
diff --git a/pygments/lexers/_mapping.py b/pygments/lexers/_mapping.py
index 180037f7..3ac9229e 100644
--- a/pygments/lexers/_mapping.py
+++ b/pygments/lexers/_mapping.py
@@ -176,6 +176,7 @@ LEXERS = {
'PostgresConsoleLexer': ('pygments.lexers.sql', 'PostgreSQL console (psql)', ('psql', 'postgresql-console', 'postgres-console'), (), ('text/x-postgresql-psql',)),
'PostgresLexer': ('pygments.lexers.sql', 'PostgreSQL SQL dialect', ('postgresql', 'postgres'), (), ('text/x-postgresql',)),
'PovrayLexer': ('pygments.lexers.other', 'POVRay', ('pov',), ('*.pov', '*.inc'), ('text/x-povray',)),
+ 'PowerShellLexer': ('pygments.lexers.shell', 'PowerShell', ('powershell', 'posh'), ('*.ps1',), ('text/x-powershell',)),
'PrologLexer': ('pygments.lexers.compiled', 'Prolog', ('prolog',), ('*.prolog', '*.pro', '*.pl'), ('text/x-prolog',)),
'PropertiesLexer': ('pygments.lexers.text', 'Properties', ('properties',), ('*.properties',), ('text/x-java-properties',)),
'ProtoBufLexer': ('pygments.lexers.other', 'Protocol Buffer', ('protobuf',), ('*.proto',), ()),
diff --git a/pygments/lexers/shell.py b/pygments/lexers/shell.py
index e2fa5191..51c4ec3c 100644
--- a/pygments/lexers/shell.py
+++ b/pygments/lexers/shell.py
@@ -17,7 +17,8 @@ from pygments.token import Punctuation, \
from pygments.util import shebang_matches
-__all__ = ['BashLexer', 'BashSessionLexer', 'TcshLexer', 'BatchLexer']
+__all__ = ['BashLexer', 'BashSessionLexer', 'TcshLexer', 'BatchLexer',
+ 'PowerShellLexer']
line_re = re.compile('.*?\n')
@@ -271,3 +272,89 @@ class TcshLexer(RegexLexer):
include('root'),
],
}
+
+
+class PowerShellLexer(RegexLexer):
+ """
+ For Windows PowerShell code.
+
+ *New in Pygments 1.5.*
+ """
+ name = 'PowerShell'
+ aliases = ['powershell', 'posh', 'ps1']
+ filenames = ['*.ps1']
+ mimetypes = ['text/x-powershell']
+
+ flags = re.DOTALL | re.IGNORECASE | re.MULTILINE
+
+ keywords = (
+ 'while validateset validaterange validatepattern validatelength '
+ 'validatecount until trap switch return ref process param parameter in '
+ 'if global: function foreach for finally filter end elseif else '
+ 'dynamicparam do default continue cmdletbinding break begin alias \\? '
+ '% #script #private #local #global mandatory parametersetname position '
+ 'valuefrompipeline valuefrompipelinebypropertyname '
+ 'valuefromremainingarguments helpmessage try catch').split()
+
+ operators = (
+ 'and as band bnot bor bxor casesensitive ccontains ceq cge cgt cle '
+ 'clike clt cmatch cne cnotcontains cnotlike cnotmatch contains '
+ 'creplace eq exact f file ge gt icontains ieq ige igt ile ilike ilt '
+ 'imatch ine inotcontains inotlike inotmatch ireplace is isnot le like '
+ 'lt match ne not notcontains notlike notmatch or regex replace '
+ 'wildcard').split()
+
+ verbs = (
+ 'write where wait use update unregister undo trace test tee take '
+ 'suspend stop start split sort skip show set send select scroll resume '
+ 'restore restart resolve resize reset rename remove register receive '
+ 'read push pop ping out new move measure limit join invoke import '
+ 'group get format foreach export expand exit enter enable disconnect '
+ 'disable debug cxnew copy convertto convertfrom convert connect '
+ 'complete compare clear checkpoint aggregate add').split()
+
+ commenthelp = (
+ 'component description example externalhelp forwardhelpcategory '
+ 'forwardhelptargetname forwardhelptargetname functionality inputs link '
+ 'notes outputs parameter remotehelprunspace role synopsis').split()
+
+ tokens = {
+ 'root': [
+ (r'\s+', Text),
+ (r'^(\s*#[#\s]*)(\.(?:%s))([^\n]*$)' % '|'.join(commenthelp),
+ bygroups(Comment, String.Doc, Comment)),
+ (r'#[^\n]*?$', Comment),
+ (r'(&lt;|<)#', Comment.Multiline, 'multline'),
+ (r'@"\n.*?\n"@', String.Heredoc),
+ (r"@'\n.*?\n'@", String.Heredoc),
+ (r'"', String.Double, 'string'),
+ (r"'([^']|'')*'", String.Single),
+ (r'(\$|@@|@)((global|script|private|env):)?[a-z0-9_]+',
+ Name.Variable),
+ (r'(%s)\b' % '|'.join(keywords), Keyword),
+ (r'-(%s)\b' % '|'.join(operators), Operator),
+ (r'(%s)-[a-z_][a-z0-9_]*\b' % '|'.join(verbs), Name.Builtin),
+ (r'\[[a-z_\[][a-z0-9_. `,\[\]]*\]', Name.Constant), # .net [type]s
+ (r'-[a-z_][a-z0-9_]*', Name),
+ (r'\w+', Name),
+ (r'[.,{}\[\]$()=+*/\\&%!~?^`|<>-]', Punctuation),
+ ],
+ 'multline': [
+ (r'[^#&.]+', Comment.Multiline),
+ (r'#(>|&gt;)', Comment.Multiline, '#pop'),
+ (r'\.(%s)' % '|'.join(commenthelp), String.Doc),
+ (r'[#&.]', Comment.Multiline),
+ ],
+ 'string': [
+ (r'[^$`"]+', String.Double),
+ (r'\$\(', String.Interpol, 'interpol'),
+ (r'`"|""', String.Double),
+ (r'[`$]', String.Double),
+ (r'"', String.Double, '#pop'),
+ ],
+ 'interpol': [
+ (r'[^$)]+', String.Interpol),
+ (r'\$\(', String.Interpol, '#push'),
+ (r'\)', String.Interpol, '#pop'),
+ ]
+ }
diff --git a/tests/examplefiles/test.ps1 b/tests/examplefiles/test.ps1
new file mode 100644
index 00000000..385fb6f4
--- /dev/null
+++ b/tests/examplefiles/test.ps1
@@ -0,0 +1,108 @@
+<#
+.SYNOPSIS
+Runs a T-SQL Query and optional outputs results to a delimited file.
+.DESCRIPTION
+Invoke-Sql script will run a T-SQL query or stored procedure and optionally outputs a delimited file.
+.EXAMPLE
+PowerShell.exe -File "C:\Scripts\Invoke-Sql.ps1" -ServerInstance "Z003\sqlprod2" -Database orders -Query "EXEC usp_accounts '12445678'"
+This example connects to Z003\sqlprod2.Orders and executes a stored procedure which does not return a result set
+.EXAMPLE
+PowerShell.exe -File "C:\Scripts\Invoke-Sql.ps1" -ServerInstance "Z003\sqlprod2" -Database orders -Query "SELECT * FROM dbo.accounts" -FilePath "C:\Scripts\accounts.txt" -Delimiter ","
+This example connects to Z003\sqlprod2.Orders and selects the records from the accounts tables, the data is outputed to a CSV file
+.NOTES
+Version History
+v1.0 - Chad Miller - 12/14/2010 - Initial release
+IMPORTANT!!! The EventLog source which is set to the application needs to be registered with
+the Event log:
+New-EventLog -LogName Application -Source $Application
+#>
+param(
+#ServerInstance is Mandatory!
+[Parameter(Position=0, Mandatory=$false)] [string]$ServerInstance,
+#Database is Mandatory!
+[Parameter(Position=1, Mandatory=$false)] [string]$Database,
+#Query is Mandatory!
+[Parameter(Position=2, Mandatory=$false)] [string]$Query,
+[Parameter(Position=3, Mandatory=$false)] [string]$Application="Invoke-Sql.ps1",
+[Parameter(Position=4, Mandatory=$false)] [string]$FilePath,
+[Parameter(Position=7, Mandatory=$false)] [string]$Delimiter="|",
+#If UserName isn't supplied a trusted connection will be used
+[Parameter(Position=5, Mandatory=$false)] [string]$UserName,
+[Parameter(Position=6, Mandatory=$false)] [string]$Password,
+[Parameter(Position=8, Mandatory=$false)] [Int32]$QueryTimeout=600,
+[Parameter(Position=9, Mandatory=$false)] [Int32]$ConnectionTimeout=15
+)
+
+
+#This must be run as administrator on Windows 2008 and higher!
+New-EventLog -LogName Application -Source $Application -EA SilentlyContinue
+$Error.Clear()
+
+#######################
+function Invoke-SqlCmd2
+{
+ param(
+ [Parameter(Position=0, Mandatory=$true)] [string]$ServerInstance,
+ [Parameter(Position=1, Mandatory=$true)] [string]$Database,
+ [Parameter(Position=2, Mandatory=$true)] [string]$Query,
+ [Parameter(Position=3, Mandatory=$false)] [string]$UserName,
+ [Parameter(Position=4, Mandatory=$false)] [string]$Password,
+ [Parameter(Position=5, Mandatory=$false)] [Int32]$QueryTimeout,
+ [Parameter(Position=6, Mandatory=$false)] [Int32]$ConnectionTimeout
+ )
+
+ try {
+ if ($Username)
+ { $ConnectionString = "Server={0};Database={1};User ID={2};Password={3};Trusted_Connection=False;Connect Timeout={4}" -f $ServerInstance,$Database,$Username,$Password,$ConnectionTimeout }
+ else
+ { $ConnectionString = "Server={0};Database={1};Integrated Security=True;Connect Timeout={2}" -f $ServerInstance,$Database,$ConnectionTimeout }
+ $conn=new-object System.Data.SqlClient.SQLConnection
+ $conn.ConnectionString=$ConnectionString
+ $conn.Open()
+ $cmd=new-object system.Data.SqlClient.SqlCommand($Query,$conn)
+ $cmd.CommandTimeout=$QueryTimeout
+ $ds=New-Object system.Data.DataSet
+ $da=New-Object system.Data.SqlClient.SqlDataAdapter($cmd)
+ [void]$da.fill($ds)
+ Write-Output ($ds.Tables[0])
+ }
+ finally {
+ $conn.Dispose()
+ }
+
+} #Invoke-SqlCmd2
+
+#######################
+# MAIN #
+#######################
+if ($PSBoundParameters.Count -eq 0)
+{
+ get-help $myInvocation.MyCommand.Path -full
+ break
+}
+
+try {
+ $msg = $null
+ $msg += "Application/Job Name: $Application`n"
+ $msg += "Query: $Query`n"
+ $msg += "ServerInstance: $ServerInstance`n"
+ $msg += "Database: $Database`n"
+ $msg += "FilePath: $FilePath`n"
+
+ Write-EventLog -LogName Application -Source "$Application" -EntryType Information -EventId 12345 -Message "Starting`n$msg"
+ $dt = Invoke-SqlCmd2 -ServerInstance $ServerInstance -Database $Database -Query $Query -UserName $UserName -Password $Password -QueryTimeOut $QueryTimeOut -ConnectionTimeout $ConnectionTimeout
+ if ($FilePath)
+ {
+ if ($dt)
+ { $dt | export-csv -Delimiter $Delimiter -Path $FilePath -NoTypeInformation }
+ else #Query Returned No Output!
+ {Write-EventLog -LogName Application -Source "$Application" -EntryType Warning -EventId 12345 -Message "NoOutput`n$msg" }
+ }
+
+ Write-EventLog -LogName Application -Source "$Application" -EntryType Information -EventId 12345 -Message "Completed`n$msg"
+}
+catch {
+ $Exception = "{0}, {1}" -f $_.Exception.GetType().FullName,$( $_.Exception.Message -replace "'" )
+ Write-EventLog -LogName Application -Source "$Application" -EntryType Error -EventId 12345 -Message "Error`n$msg`n$Exception"
+ throw
+}