Как копировать сценарий с синтаксической разметкой из PowerShell ISE

ОБНОВЛЕНО 03 февраля 2009:

Ли Холмс (Lee Holmes) опубликовал обновленную версию сценария, который гораздо лучше производит копирование и вставку HTML. Он также вставляет номера строк и имеет массу других усовершенствований.

В предыдущей статье мы демонстрировали, как использовать сценарий Console-Copy для создания цветной копии экрана консоли и его помещения в системный буфер. Как насчет того чтобы сделать то же самое с этим замечательным цветным сценарием, который вы видите в PowerShell ISE? Прямое копирование по Ctrl-C приведет к копированию только текста, без разметки. Но сильная сторона PowerShell ISE – его расширяемость, а это значит, что если вам нужна возможность – просто напишите для нее сценарий! Давайте пойдем по этому пути и посмотрим, что нам на нем попадется.

Начнем с конца и посмотрим, как нам присоединить сценарий расширяющий возможности пользовательского интерфейса PowerShell ISE. В примере ниже мы создаем новый элемент меню, который будет выводиться как команда меню Copy Script в меню Custom. Щелчок по этому пункту меню приведет к автоматическому выполнению функции Copy-Script. Третий параметр, как вы уже возможно догадались, устанавливает сочетание клавиш. Если вам не нужен быстрый доступ, просто установите это значение в $null.

 
$psise.CustomMenu.Submenus.Add("Copy Script", {Copy-Script}, "Shift+Ctrl+S")

А теперь перейдем к сценарию. Сначала вы должны проверить, открыто ли вообще окно сценария.

 
function Copy-Script
{
if (-not $psise.CurrentOpenedFile)
    {
Write-Error 'No script is available for copying.'
return
} 

Если окно сценария открыто, захватим текст из редактора и проведем его разбор.

 
$text = $psise.CurrentOpenedFile.Editor.Text 

    trap { break } 

    # Выполняем синтаксический разбор. 
    $errors = $null 
$tokens = [system.management.automation.psparser]::Tokenize($Text, [ref] $errors) 

Парсер может сгенерировать ошибку и выбросить исключение с помощью “throw”, поэтому перед тем, как его вызвать, вам следует настроить обработку ошибок.

В этой задаче мы можем игнорировать $errors, поскольку единственное, что нас заботит, это набор лексем, используемых для окрашивания. Ниже приведен список лексем, которые может содержать код PowerShell:

PS D:\> [Enum]::GetNames([System.Management.Automation.PSTokenType])
Unknown
Command
CommandParameter
CommandArgument
Number
String
Variable
Member
LoopLabel
Attribute
Type
Operator
GroupStart
GroupEnd
Keyword
Comment
StatementSeparator
NewLine
LineContinuation
Position

Парсер возвратит набор лексем, которые можно перебирать, создавая цветные блоки RTF и строки HTML по методике, описанной в заметке Захват синтаксически раскрашеного экрана консоли в HTML и RTF.

После того, как вы это сделаете, вам следует воспользоваться System.Windows.Clipboard и сохранить данные из него, которые можно получить в трех вариантах: UnicodeText, HTML и RTF:

 $dataObject = New-Object Windows.DataObject 
    $dataObject.SetText([string]$text, [Windows.TextDataFormat]"UnicodeText") 
    $dataObject.SetText([string]$rtf, [Windows.TextDataFormat]"Rtf") 
    $dataObject.SetText([string]$html, [Windows.TextDataFormat]"Html") 
    [Windows.Clipboard]::SetDataObject($dataObject, $true)

К заметке присоединен файл со сценарием. 

Не скучайте!
Владимир Аверкин (Vladimir Averkin)
Windows PowerShell Team

Перевод: Виктор Горбунков