# encoding: ascii
# api: powershell
# title: GeSHi PowerShell Syntax 
# description: This is the PowerShell syntax file for GeSHi that we use on PoshCode 1.0
# version: 1.1.0
# type: function
# author: Joel Bennett 
# license: GNU GPL
# function: Join-String
# x-poshcode-id: 1101
# x-archived: 2009-05-19T06:34:57
#
#
<?php
/*************************************************************************************
 * posh.php
 * ---------------------------------
 * Author: Joel Bennett (Jaykul@HuddledMasses.org)
 * Copyright: (c) 2007 Joel Bennett (http://HuddledMasses.org/)
 * Release Version: 1.1.0
 * Date Started:  2007-06-08
 * Last Modified: 2008-12-27
 *
 * PowerShell language file for GeSHi.
 *
 * The lists of Nouns, Verbs, and Parameters are based on my personal install 
 * with PowerShell Community Extensions installed.  The really bad news is the 
 * fact that aliases are left out almost completely, along with anything from 
 * .Net or COM objects ...
 *

## You need to define this function before using any of the generation scripts below....
function Join-String { 
  param    ( [string]$separator="', '", [string]$append, [string]$prepend, [string]$prefix="'", [string]$postfix="'")
  begin    { [string[]]$items = @($prepend.split($separator)) }
  process  { $items += $_ }
  end      { $ofs = $separator; $items += @($append.split($separator)); return "$prefix$($items -ne '')$postfix" }
}
 
 * CHANGES
 * -------
 * 2007-06-08 (0.1.0)
 *  -  First Release
 * 2007-06-09 (1.0.0)
 *  -  Changed to use regular expressions for:
 *     verbs, nouns, and -parameters (was already using them for $variables)
 * 2007-06-10 (1.0.1)
 *  -  Ditched the specific list of parameters in favor of just assuming that
 *     anything that starts with a "-" is a parameter.  Otherwise it won't 
 *     highlight anything that you shorten.
 *  -  Improved the lists by *adding* the "deffinitive" list of verbs from the 
 *     MS CLI spec to my personal verb list.  I didn't remove anything because
 *     ultimately I don't care if it's an official verb if it's a command on my
 *     computer. You should still consider adding your personal verbs too!
 *  -  I improved the 4th Keyword list by exporting my personal list of aliases
 *     and functions ... (and showing the command, so you can generate your own)
 *     and removing the variables entirely (they're already highlighted anyway).
 * 2008-12-27 (1.1.0)
 *  -  Updated for CTP3 with powershell scripts
 *
 * TODO (last updated 2007-06-09)
 * -------------------------
 *  -  I would like to create a script which can dump this whole file out based 
 *     on an individual user's personal particular set of snapins, cmdlets and 
 *     functions.  After all, for YOUR personal site, the cmdlets and functions 
 *     which you have available are the only ones that actually matter :D
 *     HOWEVER: I don't think it's that important, because  
 *
 *************************************************************************************
 *
 *     This file is part of GeSHi.
 *
 *   GeSHi is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   GeSHi is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with GeSHi; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 ************************************************************************************/

$language_data = array (
  'LANG_NAME' => 'Posh',
  'COMMENT_SINGLE' => array(1 => '#'),
  'COMMENT_MULTI' => array('<#'=>'#>'),
  'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
  'QUOTEMARKS' => array('"', "'"),
  'HARDQUOTE' => array('@"$','^"@'),          // An optional 2-element array defining the beginning and end of a hard-quoted string
  'HARDESCAPE' => array(),  // Things that must still be escaped inside a hard-quoted string
                // If HARDQUOTE is defined, HARDESCAPE must be defined
                // This will not work unless the first character of each element is either in the
                // QUOTEMARKS array or is the ESCAPE_CHAR
  'ESCAPE_CHAR' => '`',
  'KEYWORDS' => array(
      1 => array( 
# PoSH keywords/reserved words
# [type]::gettype("System.Management.Automation.KeywordTokenReader").InvokeMember("_keywordTokens", "NonPublic,Static,GetField", $null, $_, @() ).GetEnumerator()|%{$_.Name.Trim("-")}|?{$_ -match "^[A-z]"}|Sort -Desc|Join-String
'while', 'until', 'try', 'trap', 'throw', 'switch', 'return', 'process', 'param', 'in', 'if', 'function', 'from', 'foreach', 'for', 'finally', 'filter', 'exit', 'end', 'elseif', 'else', 'dynamicparam', 'do', 'data', 'continue', 'catch', 'break', 'begin'
      ),
      2 => array(
# Operators
# [type]::gettype("System.Management.Automation.OperatorTokenReader").InvokeMember("_expressionOperatorTokens", "NonPublic,Static,GetField", $null, $_, @() ).GetEnumerator()|%{$_.Name.Trim("-")}|?{$_ -match "^[A-z]"}|Sort -Desc|Join-String
'xor', 'split', 'replace', 'or', 'notmatch', 'notlike', 'notcontains', 'not', 'ne', 'match', 'lt', 'like', 'le', 'join', 'isplit', 'isnot', 'is', 'ireplace', 'inotmatch', 'inotlike', 'inotcontains', 'ine', 'imatch', 'ilt', 'ilike', 'ile', 'igt', 'ige', 'ieq', 'icontains', 'gt', 'ge', 'f', 'eq', 'csplit', 'creplace', 'contains', 'cnotmatch', 'cnotlike', 'cnotcontains', 'cne', 'cmatch', 'clt', 'clike', 'cle', 'cgt', 'cge', 'ceq', 'ccontains', 'bxor', 'bor', 'bnot', 'band', 'as', 'and'
      ),
# built in language type shorcuts, plus a couple of .Net base types...
# [type]::gettype("System.Management.Automation.TypeAccelerators")::get.GetEnumerator()|%{$_.Key}|Sort -Desc|Join-String|Out-Clipboard
      3 => array(
'xml', 'wmisearcher', 'wmiclass', 'wmi', 'type', 'system', 'switch', 'string', 'single', 'scriptblock', 'runspacefactory', 'runspace', 'regex', 'ref', 'psobject', 'psmoduleinfo', 'pscustomobject', 'powershell', 'microsoft', 'long', 'ipaddress', 'int', 'hashtable', 'float', 'double', 'decimal', 'char', 'byte', 'bool', 'array', 'adsisearcher', 'adsi'
		),
      4 => array(
# MY list of aliases and functions (filtered to remove verb-noun functions which will already be highlighted, and to remove drive letter functions)
# Combined list generated with:
# gcm -type "Alias,Function,Filter" | Select -Expand Name | ?{$_ -match "[A-z]" -and $_ -notmatch "[A-z]-|:"}|Sort -Unique -Desc | %{[regex]::escape($_) -replace '.ps1$',''} | Join-String
'write', 'wjb', 'which', 'where', 'type', 'tee', 'TabExpansion', 'swmi', 'sv', 'Start', 'spsv', 'spps', 'spjb', 'sp', 'sort', 'sleep', 'sl', 'sign', 'si', 'set', 'select', 'sc', 'sbp', 'say', 'sasv', 'sas', 'sal', 'sajb', 'rwmi', 'rvpa', 'rv', 'rsnp', 'rsn', 'rp', 'rnp', 'rni', 'rmdir', 'rm', 'rjb', 'ri', 'ren', 'rdr', 'rd', 'rcjb', 'rbp', 'RandomLine', 'rand', 'r', 'pwd', 'pushd', 'ps', 'prompt', 'popd', 'oh', 'ogv', 'nv', 'nsn', 'nmo', 'ni', 'ndr', 'nal', 'mv', 'mp', 'move', 'mount', 'more', 'mkdir', 'mi', 'measure', 'md', 'man', 'ls', 'lp', 'kill', 'join', 'iwmi', 'IPSN', 'ipcsv', 'ipal', 'imo', 'ii', 'ihy', 'iex', 'icm', 'history', 'help', 'h', 'gwmi', 'gv', 'gu', 'gsv', 'gsnp', 'gsn', 'group', 'grid', 'gq', 'gps', 'gph', 'gp', 'gmo', 'gm', 'gl', 'gjb', 'gi', 'ghy', 'gdr', 'gcs', 'gcm', 'gci', 'gc', 'gbp', 'gas', 'gal', 'fw', 'ft', 'foreach', 'fl', 'fc', 'EXSN', 'exec', 'ETSN', 'erase', 'EPSN', 'epcsv', 'epal', 'emm', 'edit', 'echo', 'ebp', 'dir', 'diff', 'del', 'dbp', 'cvpa', 'cpp', 'cpi', 'cp', 'copy', 'compare', 'clv', 'cls', 'clp', 'cli', 'clhy', 'clear', 'clc', 'chdir', 'cd\\', 'cd\.\.', 'cd', 'cat', 'asnp', 'ac'
      ),
   ),
   'SYMBOLS' => array(
    '(', ')', '[', ']', '{', '}', "-", "+", "=", '!', '%', '&', '*', '|', '/', '<', '>',
   ),
   'CASE_SENSITIVE' => array(
      GESHI_COMMENTS => true,
      1 => false,
      2 => false,
      3 => false,
      4 => false,
      5 => false,
      6 => false,
   ),
   'STYLES' => array(
      'KEYWORDS' => array(
         1 => 'color: #666699; font-weight: bold;',
         2 => 'color: #333399; font-weight: bold; font-style: italic;',
         3 => 'color: #003366; font-weight: bold;',
         4 => 'color: #660033;',
      //~ 5 => 'color: #006600; font-style: italic;',
      //~ 6 => 'color: #000000; font-style: italic;',
      ),
      'COMMENTS' => array(
         1 => 'color: #666666; font-style: italic;',
         'MULTI' => 'color: #666666; font-style: italic;'
      ),
      'ESCAPE_CHAR' => array(
         0 => 'color: #000099; font-weight: bold;'
      ),
      'BRACKETS' => array(
         0 => 'color: #333;'
      ),
      'STRINGS' => array(
         0 => 'color: #009900;'
      ),
      'NUMBERS' => array(
         0 => 'color: #cc66cc;'
      ),
      'METHODS' => array(
         1 => 'color: #003366;',
         2 => 'color: #003366;',
//       3 => 'color: #666;'
      ),
      'SYMBOLS' => array(
         0 => 'color: #66cc66;'
      ),
      'REGEXPS' => array(
         0 => 'color: #0066cc; font-style: italic;',    # verb-noun
         1 => 'font-style: normal;',                    # noun
         2 => 'color: #000066;',                        # parameters
         3 => 'color: #660033; font-weight: bold;',     # variables
         4 => 'color: #003366; font-weight: bold;',     # types
      ),
      'SCRIPT' => array(
      )
   ),
   'URLS' => array(
   ),
   'OOLANG' => true,
   'OBJECT_SPLITTERS' => array(
      1 => '.',
      2 => '::',
   ),
   'REGEXPS' => array(
# Verbs. Full SEARCH pattern GENERATED with this:
# get-command | %{$_.verb} | sort -unique -descending | Join-String -prefix "((?:" -Separator "|" -postfix ")-[a-zA-Z_][a-zA-Z0-9_]*)"
# NOTE: THIS HIGHLIGHTS THE WHOLE COMMAND
      0 => array (
         GESHI_SEARCH => '((?:Write|Where|Wait|Use|Update|Unregister|Undo|Trace|Test|Tee|Suspend|Stop|Start|Split|Sort|Show|Set|Send|Select|Resume|Restore|Restart|Resolve|Reset|Rename|Remove|Register|Receive|Read|Push|Pop|Out|New|Move|Measure|Limit|Join|Invoke|Import|Group|Get|Format|ForEach|Export|Exit|Enter|Enable|Disconnect|Disable|Debug|Copy|ConvertTo|ConvertFrom|Convert|Connect|Complete|Compare|Clear|Checkpoint|Add)-[a-zA-Z_][a-zA-Z0-9_]*)',
         GESHI_REPLACE => '\\1',
         GESHI_MODIFIERS => 'i',
         GESHI_BEFORE => '',
         GESHI_AFTER => ''
      ),
# Nouns come after a Verb and a dash. It's basically the same as above, GENERATE YOUR OWN with this:
# get-command | foreach-object{$_.verb} | sort-object -unique -descending | Join-String -Separator "|" -prefix "((?:" -postfix ")-)([a-zA-Z_][a-zA-Z0-9_]*)"
# HYPOTHETICALLY, if you wanted a list of nouns on your system:
# get-command | foreach-object{$_.noun} | sort-object -unique -descending | Join-String -Separator "|" -prefix "((?:" -postfix "))"
# NOTE: THIS HIGHLIGHTS JUST THE NOUN
      1 => array (
         GESHI_SEARCH => '((?:Write|Where|Wait|Use|Update|Unregister|Undo|Trace|Test|Tee|Suspend|Stop|Start|Split|Sort|Show|Set|Send|Select|Resume|Restore|Restart|Resolve|Reset|Rename|Remove|Register|Receive|Read|Push|Pop|Out|New|Move|Measure|Limit|Join|Invoke|Import|Group|Get|Format|ForEach|Export|Exit|Enter|Enable|Disconnect|Disable|Debug|Copy|ConvertTo|ConvertFrom|Convert|Connect|Complete|Compare|Clear|Checkpoint|Add)-)([a-zA-Z_][a-zA-Z0-9_]*)',
         GESHI_REPLACE => '\\2',
         GESHI_MODIFIERS => 'i',
         GESHI_BEFORE => '\\1',
         GESHI_AFTER => ''
      ),      
# Parameters come after a " -" ... and although I can generate a list using:
# "(-(?:"+(get-command | foreach-object{$_.parametersets} | foreach-object {$_.parameters} | foreach-object {$_.name} | sort-object -unique -descending | Join-String -Separator "|")+"))" | Set-Clipboard
############### (?:Year|XsltPath|XPath|Write|Wrap|WorkingDirectory|Word|WindowStyle|Width|WhatIf|Warning|WaitTimeout|Wait|Volume|View|Version|Verify|Verbose|Verb|Variable|ValueOnly|Value|Validate|Utc|UseTimeFromFile|UserName|URL|Update|Unique|UFormat|TypeName|TTL|TrustLevel|Trusted|Truncate|Trace|TotalCount|To|Title|TimestampServer|TimeStamp|Timeout|Time|TID|Text|Temp|TargetObject|Target|Syntax|SyncWindow|Sum|Subject|Strings|StringEncoding|String|Strict|Stream|Step|Status|Statistic|Static|State|StartupType|Start|StackName|Stack|Speed|SourceId|SortBy|SmtpHost|Size|SingleLine|SimpleMatch|SID|ShowError|Shortname|SetModifiedTime|SetCreatedTime|SetAccessedTime|Server|Separator|Select|SecureString|SecureKey|SecondValue|SecondsRemaining|Seconds|Second|ScriptBlock|Scope|SchemaPath|SaveCred|Rtf|Root|Role|Retry|Resolve|ReplyTo|Repair|RemoveOriginal|RemoveListener|RemoveFileListener|RemoveEmptyStrings|Registered|RegexSeparator|Regex|ReferenceObject|Recurse|RecommendedAction|Reason|ReadOnly|ReadCount|Raw|Quiet|Query|Quality|Qualifier|PSSnapin|PSProvider|PSHost|PSDrive|PropertyType|Property|Prompt|Process|Privileges|Privilege|Priority|PrinterName|PrincipalName|PrependPath|PortNumber|PortName|PercentComplete|Percent|Pattern|PathType|Path|Password|PassThru|ParentID|Parent|Parameter|Paging|Owner|Overwrite|OutVariable|OutputPath|Output|OutBuffer|Option|Operation|OnType|OmitXmlDeclaration|Offset|Off|Object|NoWindow|Noun|NoTypeInformation|NoTrimEnd|Notify|NoShellExecute|NoQualifier|NoProfile|NoNewLine|NoLineBreak|NoHeader|NoElement|NoClobber|NoAscii|NoAddress|NewName|NewLine|Newest|Namespace|Name|MultiLine|Most|Month|Modified|Minutes|Minute|Minimum|Min|Milliseconds|Migrate|Message|MemberType|Maximum|Max|MacName|LogName|Log|Location|LocalizedHelpPath|LoadUserProfile|LiteralPath|LiteralName|ListenerOption|List|LineCount|Line|Level|Leaf|LastWord|Last|Label|KeyLength|KeyContainerName|KeyAlgorithm|Key|KeepAspectRatio|JobName|ItemType|IsValid|IsAbsolute|IpAddress|Interval|InterfaceName|Interactive|Insert|InputObject|Input|IndentString|Incremental|IncludeEqual|IncludeEmptyDirectories|IncludeChain|Include|Import|Image|IgnoreWhiteSpace|Ignore|Identity|Id|HtmlBody|Html|Hours|Hour|HostName|HideTableHeaders|Height|Head|Handle|GroupBy|Group|GlobalCatalog|Functionality|Full|From|FragmentOnly|Format|ForegroundColor|Force|Follow|FlattenPaths|First|FilterScript|Filter|Files|FilePath|FileName|Fast|Expression|ExpandProperty|Expand|ExecutionPolicy|ExcludeProperty|ExcludeDifferent|Exclude|Exception|Examples|Exact|EventName|ErrorVariable|ErrorRecord|ErrorLimit|ErrorLevel|ErrorId|ErrorAction|Erase|End|Encrypt|Encoding|EnableScript|Elapsed|DriveName|Drain|DomainName|Domain|DistinguishedName|DisplayName|DisplayHint|DisplayError|DirectoryName|DifferenceObject|Detailed|Destination|Description|Descending|Depth|DependsOn|Delimiter|Delete|Default|Debugger|Debug|Days|Day|Date|CurrentOperation|Culture|Csv|CSPType|CSPName|CryptoRng|Credential|Created|Create|Count|Continuous|Container|ConformanceLevel|Confirm|ComputerName|Compress|Component|Completed|Compatible|ComObject|CommandType|Command|Columns|Column|ClusterName|ClassName|Class|ChildPath|Character|Char|CertUsage|CertSubjectName|CertStoreLocation|CertSerialNumber|CertRequestFileName|CertIssuerName|Certificate|CertFile|Cc|CategoryTargetType|CategoryTargetName|CategoryReason|CategoryActivity|Category|CaseSensitive|Cache|BufferSize|Boost|Body|BlockCount|Bitmap|BinaryPathName|Binary|Begin|Before|Bcc|Base64Text|BackgroundColor|Average|AutoSize|Audit|Audio|AttributesOnNewLine|AttributeName|AttachmentPath|AttachmentLiteralPath|Asynchronous|AsString|AssemblyName|AsSecureString|AsPlainText|Ascending|As|Arguments|ArgumentList|ApplicationName|AppendPath|Append|Anonymous|Allocation|AllAddresses|All|Algorithm|After|Adjust|Activity|AclObject|ACL|Accessed)
# Since you can abbreviate a parameter to it's shortest representation, it seems like the best thing is to just match any word starting with -
# This *MIGHT* affect your math, but I think it'll be better than otherwise
      2 => array (
         GESHI_SEARCH => ' (-[a-zA-Z_][a-zA-Z0-9_]*)',
         GESHI_REPLACE => '\\1',
         GESHI_MODIFIERS => 'i',
         GESHI_BEFORE => ' ',
         GESHI_AFTER => ''
      ),
# Variables always start with $ and they can be pretty much whatever ...
      3 => array (
         GESHI_SEARCH => '(\\$[a-zA-Z_][a-zA-Z0-9_]*)',
         GESHI_REPLACE => '\\1',
         GESHI_MODIFIERS => '',
         GESHI_BEFORE => '',
         GESHI_AFTER => ''
      ),
      4 => array (
         GESHI_SEARCH => '(\[[a-z][a-z0-9_\.\]\[]+\])',
         GESHI_REPLACE => '\\1',
         GESHI_MODIFIERS => 'i',
         GESHI_BEFORE => '',
         GESHI_AFTER => ''
      ),
   ),
   'STRICT_MODE_APPLIES' => GESHI_NEVER,
   'SCRIPT_DELIMITERS' => array(
   ),
   'HIGHLIGHT_STRICT_BLOCK' => array(
   )
);

?>
