СПЕЦИАЛЬНЫЕ СРЕДСТВА ДЛЯ КОНТЕКСТНОГО РЕДАКТИРОВАНИЯ
 
ОБЩИЙ АРХИВ 
БЛОК РЕДАКТИРОВАНИЯ 
   Понятие блока редактирования и блокового контекста 
   Условный блоковый контекст
   Условное выражение
ГРУППОВОЙ ОПЕРАТОР В КОНТЕКСТЕ ЗАМЕНЫ 
   Понятие группового оператора 
   Простое групповое выражение 
   Циклическое групповое выражение 
   Блоковые функции 
      1.  Функция BlockOper 
      2.  Функция BlockConv 
      3.  Функция BlockEdit 
      4.  Функция BlockFile 
      5.  Функция BlockRepl 
      6.  Функция BlockLexm 
      7.  Функция BlockFind
      8.  Функция BlockEval
      9.  Функция BlockInfo
     10. Функция BlockList
     11. Функция BlockForm
     12. Функция BlockNumb
     13. Функция BlockOrfg
   Операция условного выбора
   Аппарат подстановок в контекстах и сценариях
      Источники и виды подстановок
      Конструкции подстановок
СПЕЦИАЛЬНЫЕ АНАЛИТИЧЕСКИЕ СРЕДСТВА 
   Граничные контексты в таблице контекстов
   Использование авторских идентификаторов
ПРИЕМЫ СОЗДАНИЯ СЛОЖНЫХ СЦЕНАРИЕВ 
 
 
 
ОБЩИЙ АРХИВ
 

Общий архив - это список (массив текстовых строк), содержащий контексты как в виде одной строки, так и в виде группы строк. В последнем случае строки представляются в ячейке архива разделенными символом EOLN (в его текстовом представлении). Область действия общего архива распространяется на весь сеанс редактирования, поэтому контексты архива могут создаваться либо заранее (вноситься пользователем), либо в процессе редактирования одного или нескольких файлов, а использоваться при редактировании любого файла. Такой механизм позволяет делать межфайловые контекстные замены.

 

Для создания, просмотра и редактирования архива служит окно "Просмотр и редактирование общего архива", в котором при загрузке отображается таблица архивных ячеек с указанием их номеров. Для редактирования определенной ячейки таблицы необходимо указать ее номер в редакторском окошке (явно или кликнуть ячейку мышкой) и вызвать через контекстное меню поле редактирования. Редактирование ячейки, а также определенные действия над ячейками архива, осуществляющиеся через обычное меню окна, могут быть внесены в сценарий. Весь архив или отдельную его ячейку можно сохранить в файле или загрузить из файла, что может быть использовано также в сценариях. Меню позволяет выбрать файл либо непосредственно из каталога, либо как файл списка, являющийся элементом левого или правого списка, и в этом случае задание файла списка производится через вызываемое окно "Выбор элемента списка". В этом окне задается вид списка и номер элемента по списку, при этом номер отсчитывается от 1 или может быть равен -1, что при контекстной замене по содержимому списка с именами файлов соответствует текущему значению ячейки списка с редактируемым в текущий момент файлом. Это обстоятельство может быть использовано в сценарии, где состояние архива на одном этапе редактирования для каждого файла левого списка запоминается в заданных файлах правого списка (например, с тем же именем, но с другим расширением), а затем восстанавливается при использовании на другом этапе редактирования файла из левого списка.

 

Архив не обязан заполняться последовательно, т.е. в любой момент может быть создана его ячейка с произвольным номером. Признаком работы с архивным контекстом при редактировании входного файла является использование конструкции {{n}}, где n>=1 - номер ячейки в архиве. Ячейка архива может участвовать в качестве операнда группового выражения и интерпретироваться не только как строковое значение, а и как числовое. Это обстоятельство позволяет использовать ячейку архива, например, как счетчик при программировании сложных преобразований :

 ""//{{1}}   или   "0"//{{1}}     - обнуление счетчика

{{1}}+1//{{1}}                         - увеличение значения счетчика на 1

 

 

БЛОК РЕДАКТИРОВАНИЯ
Понятие блока редактирования и блокового контекста
 

Блок редактирования  - это внутренний список (массив текстовых строк), который может включать одну или несколько файловых строк, как из текущего редактируемого файла, так и из группы редактируемых файлов (при включенной опции на странице контекстной замены "Сводный файл строк редакции"). В общем случае, блок редактирования создается при нахождении в редактируемом файле блокового контекста поиска, в котором специальные конструкции ( %% и $$ ) определяют поиск начальной и конечной строки блока:

 

%%<контекст поиска начальной строки блока>
<контекст поиска внутренних строк блока>
$$<контекст поиска конечной строки блока>
 

В качестве ограничителей начала и конца блока могут  использоваться спецконструкции без контекстов:

%%%        (в этом случае начальная строка блока совпадает с началом файла)
$$                (в этом случае конечная и начальная строки блока совпадают)
$$$              (в этом случае конечная строка блока совпадает с концом файла)
 

Примеры блоковых контекстов:

 

Контекст поиска:
Контекст замены:
Комментарий:
%%<pre>
{integer}
$$</pre>
 
{real}

блок между обрамляющими граничными тегами <pre> и </pre>, в котором контекст integer заменяется на real ;

%%{фаза}|{фазов}
{@[}
$${~@[}
 
 
""

блок карточек, заголовок которых содержит производные от слова фаза, а тело состоит из конструкций, содержащих квадратную скобку

%%{%Пример:}
$$
 

блок, состоящий из строки, в начале которой находится контекст Пример: ;

%%{%Пример:}
$$$
 

блок, начинающийся со строки с контекстом Пример: и заканчивающийся последней строкой редактируемого файла;

 

Таблица контекстов может  содержать  произвольное  число  блоковых  контекстов (идентифицируются условием), которые определяют области таблицы и строки файла, в которых только и будет производиться контекстный поиск и замена, заданные для этого блока редактирования. Контекстным  преобразованиям может быть подвергнута любая строка, удовлетворяющая   условию вхождения в блоковый контекст, перед непосредственной записью  ее  в  блок  редактирования, в том числе начальная и конечная. При этом поиск контекста внутренних строк блока распространяется также на начальную строку. Если конечная строка блока  содержит  в  контексте  поиска  более одного условия, то реальный конец блока  соответствует  выполнению  только  первого условия, а при необходимости определить конец блока  по  другому  условию,  следует написать ещё один контекст $$ с другим условием.  Начальных  контекстов  %%   для находжения различных контекстов поиска, которые будут обрабатываться в одном  блоке редактирования, может быть также несколько, но они определяют  "вход"  в блок при выполнении любого заданного условия в контексте поиска.

 

В качестве начальной и конечной строк блока могут быть как отдельные фиксированные конструкции (например, %%<pre> и $$</pre>), так и произвольные строки, содержащие контекст поиска начальной строки блока (например, %%{фаза}|{фазов} . В последнем случае, конец искомого блока определяется отсутствием в строке заданного контекста начальной строки блока и контекста внутренней строки блока, но тогда он не должен быть включен в блок, что достигается заданием пустого контекста замены "".

 

Найденные блоковые контексты могут быть подвержены контекстной замене, а также над ними возможность производить определенные действия с помощью групповых операторов, причем это можно делать и в процессе построения блока и после его создания. Для указания действий над найденным блоком служит специальная конструкция %$ , которая располагается после контекста поиска конца блока и определяет набор действий, записанных в таблице контекстов в позиции контекста замены. Таких строк, относящихся к текущему блоку, может быть несколько, и они определяют определенную последовательность действий через блоковые функции. Таким образом, в таблице контекстов может присутствовать структура вида:

 
Контекст поиска:
Контекст замены:
%%<контекст начала блока>
<контекст внутренних строк блока>
.  .  .
<контекст внутренних строк блока>
$$<контекст конца блока>
%$
.  .  .
%$
<контекст замены>
 
.  .  .
 
<контекст замены>
#[<блоковая функция>]
.  .  .
#[<блоковая функция>]
 

Контекстным преобразованиям может быть подвергнута любая строка, удовлетворяющая условию вхождения в блок, перед непосредственной записью ее в блок редактирования, в том числе начальная и конечная. При этом поиск контекста внутренних строк блока распространяется также на начальную строку.

 

Замечание.  Блоковый контекст таблицы контекстов фактически определяет блок редактирования и поэтому в общем случае под блоком редактирования можно понимать совокупность конструкций таблицы контекстов и формируемого в процессе контекстной замены фрагмента редактирования.

 

 
Условный блоковый контекст
 

В одном файле может быть задан контекстный поиск нескольких блоковых контекстов, для чего вводится критерий условие, который идентифицирует все строки, относящиеся к данному блоку:

|<условие>|%%<контекст начала блока>
|<условие>|<контекст внутренних строк блока>
   . . .
|<условие>|$$<контекст конца блока>
 

Здесь:

<условие>        -  конструкция вида :

                             <номер блока>   или

                            <номер блока>[<групповое условное выражение>]   или

                            <номер блока>[<групповое условное выражение> ::

         <групповое условное выражение> :: …<групповое условное выражение>]

 

Символ-разделитель :: (соответствует логической операции или) означает наличие набора групповых условных выражений. При выполнении очередного условия запоминается его номер в наборе и выполняется соответствующий этому номеру групповой оператор в контексте замены.

 

<номер блока>                -  целое число от 1 или пусто

 

<групповое условное выражение>  -  конструкция вида:

                      < условное выражение> [ ||  <условное выражение> … || <условное выражение>]

 

Символ-разделитель || (соответствует логической операции и) означает наличие нескольких условных выражений, каждое из которых должно выполняться для выполнения всего условного выражения. Эти условные выражения могут использоваться в подстановках в других условных выражениях набора:

 

>n|d0..d1

-

выборка диапазона условного выражения из набора условий с номером n , при этом до и после операторов выборки могут находиться другие условные выражения, например, <условие 1.1> // <условие 1.2> // <условие 1.3>  :: >1/1..2 // <условие 2.1> (при подстановке для второго условия получим последовательность <условие 1.1> // <условие 1.2> // <условие 2.1>);

 

Примеры условных блоковых контекстов (в таблице контекстов каждый контекст поиска или замены записывается в одну строку):

 

1).Поиск в файле отдельных разделов для "точечного" редактирования

 

Контекст поиска:

Контекст замены:

Комментарий:

|1|%%<h3> *Использование

|1|{_c(}

|1|$$<h3> *Параметры

|2|%%{<h3> *Версии}

|2|{external}

|2|$$<h3> *Примеры

 

"_c ("

 

 

extern

Редактирование в разделе 'Использование'  ;

 

редактирование в разделе 'Версии' ;

 

 

 
Условное выражение

 

<условное выражение>  -  конструкция вида:

[<модификатор>]<групповое выражение><операция>

                                                           [<модификатор>]<групповое выражение>

                        или

[<модификатор>]<идентификатор>[<операция>

                                                          <величина для сравнения>]

 

<модификатор>       - операции, применяемые к вычисленному операнду:

                              ~~           исключение всех пробелов в значении операнда

                              _>           перевод значения операнда в регистр больших букв

                              _<           перевод значения операнда в регистр малых букв

<групповое выражение> -    <простое групповое выражение>

                                                                       или

                                             <циклическое групповое выражение>

 

<операция>                       - допустимы следующие операции сравнения:

                              = , <> , > , < ,          (для простого группового выражения)

                              <=, >=                    

                                  для цикла в правой части условия -

                              = , <> , > , < ,          (для циклического группового

                               <=, >=                      выражения: true- хотя бы для

                                                                одной итерации цикла)

                              =* , <>* , >* , <*,   (для циклического группового

                              <=* ,>=*                   выражения: true - для всех

                                                                 итераций цикла)

                                  для цикла в левой части условия -

                              = , <> , > , < ,          (для циклического группового

                               <=, >=                      выражения: true- для всех

                                                                итераций цикла)

                             != , !<> , !> , !<,       (для циклического группового

                             !<= , !>=                    выражения: true - хотя бы для

                                                                одной итераций цикла)

                             Замечание. Не допускаются пробелы между символом '!'

                             и конечным символом условия. Например,

                             loop(sysvar|~1..-1~)/s!=0^^9  - условие выполнено,

                             если sysvar будет содержать хотя бы одну цифру;

                             loop(sysvar2|*.*)/s/sysvar3!=A^^Z - номер первой

                             найденной в sysvar2 буквы будет записан в sysvar3 .

 

<идентификатор>              -  смысловое имя (допустимые операции):

                                     else - условие выполняется при невыполнении всех

                                               предыдущих условий условного выражения,

                          block (>|<|=) - номер очередного вхождения блока в файле,
                                                   сравниваемый с числовым диапазоном (n или
                                                    n1..n2),
                                    file (=) - контроль существования файла, имя которого
                                                   задается в качестве выражения для сравнения,

                             fline (>|<|=) - номер текущей строки файла, сравниваемый с

                                                   числовым диапазоном (n или n1..n2, при n<0

                                                   отсчёт производится от конечной строки файла),

                  retBlockOper (=) - контроль кода возврата при выполнении
                                                   предшествующей блоковой операции BlockOper
                  retBlockConv (=) - контроль кода возврата при выполнении
                                                   предшествующей блоковой операции BlockConv
                    retBlockEdit (=) - контроль кода возврата при выполнении
                                                   предшествующей блоковой операции BlockEdit
                     retBlockFile (=) - контроль кода возврата при выполнении
                                                    предшествующей блоковой операции BlockFile
                    retBlockRepl (=) - контроль кода возврата при выполнении
                                                    предшествующей блоковой операции BlockRepl
                   retBlockLexm (=) - контроль кода возврата при выполнении
                                                     предшествующей блоковой операции BlockLexm
                     retBlockFind (=) - контроль кода возврата при выполнении
                                                     предшествующей блоковой операции BlockFind
                     retBlockEval (=) - контроль кода возврата при выполнении
                                                     предшествующей блоковой операции BlockEval
                                                     (текстовые константы сравнения  true  или  false)
                      retBlockList (=) - контроль кода возврата при выполнении
                                                     предшествующей блоковой операции BlockList
                                                     (текстовые константы сравнения  true  или  false)

                     retBlockForm (=) - контроль кода возврата при выполнении

                                                    предшествующей блоковой операции BlockForm

                                                   (текстовые константы сравнения  true  или  false)

                     retBlockNumb (=) - контроль кода возврата при выполнении

                                                   предшествующей блоковой операции BlockNumb

                                                   (текстовые константы сравнения  true  или  false)

                     retBlockOrfg (=) - контроль кода возврата при выполнении

                                                   предшествующей блоковой операции BlockOrfg

                                                   (текстовые константы сравнения  true  или  false)

 

В процессе анализа условия формируются системные переменные, которые могут в дальнейшем использоваться в блоковых функциях контекста замены:

 

SysLloop

-

содержит найденное значение по циклу для текущего проверяемого простого условия, при котором это простое условие выполняется (это значение может быть использовано в следующем условии, стоящим за разделителями || или ::, если оно имеет такую же левую часть);

SysRloop

-

содержит найденное значение по циклу для текущего проверяемого простого условия, при котором это простое условие выполняется (это значение может быть использовано в следующем условии, стоящим за разделителями || или ::, если оно имеет такую же правую часть);

SysNcond

-

номер условия, которое удовлетворяется;

SysLiter

-

номер итерации, найденной по циклу в левой части простого условного выражения; в записи диапазона используется условное обозначение l* или L* , например, {1}|L*..L*;

SysRiter

-

номер итерации, найденной по циклу в правой части простого условного выражения; в записи диапазона используется условное обозначение r* или R* , например, {1}|r*''r* ;

SysLval

-

содержит вычисленную левую часть для текущего проверяемого условия текущего простого условного выражения (это значение может быть использовано в следующем условии, стоящем после разделителей || или :: , если оно имеет такую же левую часть, например, последовательность лексем сравнения, задаваемая в цикле loop({{1}}|*''*)/l );

SysRval

-

содержит вычисленную правую часть для текущего проверяемого условия текущего простого условного выражения (это значение может быть использовано в следующем условии, стоящем после разделителей || или :: , если оно имеет такую же правую часть, например, три конечных байта из sysvar, получаемых в цикле loop(sysvar|-3..-1)/s );

 

 

Замечание.  Если условное выражение состоит из  нескольких простых условных выражений, объединяемых операцией  || , то значения соответствующих системных переменных считаются неопределёнными.

 
 

Примеры условных блоковых контекстов (в таблице контекстов каждый контекст поиска или замены записывается в одну строку):

 

1). Выборка блока, если он найден в файле первый раз

 
Контекст поиска:
Контекст замены:
Комментарий:
|3[block=1]|%%<table
|3|{<tr>}
|3|$$</table>
|3|%$
 
#[BlockEdit(selsp,sysfile1)]
 
#[BlockOper(del,{10},,&1|
   sysfile1 ..&2|sysfile1 -1)]

контроль появления блока в первый раз и применение блоковых функций для удаления первой группы строк, описанной тегом  <tr> ;

 

В контексте замены использованы блоковые функции и аппарат подстановки лексем 1 и 2 из системного файла sysfile1, созданного при нахождении контекста <tr> внутри блока редактирования.

 

2). Поиск контекста во внешнем файле для замены в блоке

 
Контекст поиска:
Контекст замены:
Комментарий:
|4|%%{subroutine}{[a-z]+
   [_a-z0-9]* ]}{?*)}
|4|$${)}
|4[file=d:\file\{{1}}.ci :: 
file=d:\file\{{1}}.cr]|%$
#[{2}|1..-2//{{1}}]
 
 
#[BlockFile(extr,sysRcond,{10},
"int {{1}}",")", "subroutine",")") ::
BlockFile(extr,sysRcond,{10},
"real {{1}}",")", "subroutine",")")]

запись имени п/п в первую ячейку архива;

 

контроль наличия файла с расширением .ci или .cr, и выбор блоковой функции для контекстной замены обращения к п/п;

 

В контексте замены использованы блоковые функции и аппарат подстановки контекста из первой ячейки общего архива, созданного в процессе создания блока редактирования.

 

3). Поиск и замена левой части оператора присваивания для локальных и глобальных значений переменных (фрагмент п/п замены идентификаторов)

 

Контекст поиска:

Контекст замены:

Комментарий:

|[{1}|~1..-2~ = sysvar :: sysLval=loop({{3}}|*''*)/a :: else]|{ *[_A-Za-z][_A-Za-z0-9]* *=}

#[{{1}}|r*''r*//{1}|~1..-2~

:: :: {{5}} + 1//{{5}};

{1}|~1..-2~ & " "//{{2}}/b;

loop({{2}}|*''*)/a//sysvar;

"_" & {{5}} & " "//{{1}}/b;

{{1}}|1''1//{1}|~1..-2~]

Для найденного контекста поочередно проверяются ряд сравнений: со списком локальных переменных (находится в sysvar), со списком глобальных перем. (находится в ячейке общего архива {{3}}) не входит в списки;

 

В первом условии для ускорения общего процесса контекстного поиска/замены используется системная переменная sysvar, которая строится на основе списка локальных переменных из ячейки архива {{2}}, и содержит внутреннее представление списка. В силу этого первое условие фактически означает проверку элемента (лексемы) по списку локальных параметров и в случае нахождения элемента в списке на его номер указывает r* .По этому номеру из списка замены из ячейки архива {{1}} выбирается элемент замены и заменяет найденный контекст. Второе условие проверяет наличие контекста в списке глобальных переменных {{3}}, при этом исходный контекст не меняется. Здесь следует обратить внимание, что в качестве левой части условия используется вычисленное значение предыдущего условия, что существенно сокращает время выполнения всего процесса. Третье условие выполняется, если первые два не дали положительного результата. В этом случае дополняется список локальных переменных {{2}} и формируется новое значение переменной sysvar, в начало списка замены {{1}} добавляется элемент замены в виде _n (n - значение счетчика {{5}}, которое предварительно увеличивается на 1) и на это значение заменяется найденный контекст.

 
 
ГРУППОВОЙ ОПЕРАТОР В КОНТЕКСТЕ ЗАМЕНЫ
Понятие группового оператора
 

Вместо номера группы в контексте замены может быть задан групповой оператор или набор групповых операторов с разделителем ' ; ' :

#[<групповой оператор>]
#[<групповой оператор>; <групповой оператор>; …<групповой оператор>]

Здесь:

<групповой оператор>    -   конструкция вида:
                                          <простое групповое выражение> 
                                                               или
                                     <циклическое групповое выражение> 
                                                              или
                                               <блоковая функция>

                                                         или

                                   <операция условного выбора>

 

Наборы операторов могут быть условными, в этом случае они разделяются символом :: и выполняются при определенных условиях, заданных в контексте поиска условного блока редактирования:

 <набор операторов> :: <набор операторов> :: … <набор операторов>

(последний оператор условия не обязан заканчиваться ограничителем ' ; ' )

 

В качестве набора операторов могут фигурировать подстановки:

 

>n[;]

-

номер набора операторов текущего условия; например, если наборы операторов первого и второго условий совпадают, то для записи набора операторов второго условия можно использовать подстановку: <набор операторов для условия 1> :: >1 ;

>n|d0..d1[;]

-

выборка диапазона групповых операторов из набора операторов для условия с номером n , при этом до и после операторов выборки могут находиться другие групповые операторы, например, <групповой оператор 1.1>; <групповой оператор 1.2>; <групповой оператор 1.3>  :: >1/1..2; <групповой оператор 2.1> (при подстановке для второго условия получим последовательность <групповой оператор 1.1>; <групповой оператор 1.2>;<групповой оператор 2.1>);

 

 

Простое групповое выражение
 

Определим понятие простого группового выражения, которое для краткости будет называться групповым выражением. Групповое выражение позволяет выполнить некоторые строковые или арифметические действия над содержимым найденных групп (полным или взятом в заданном диапазоне), а затем поместить результат по стандартным правилам работы с группами или в место, указанное в самом контексте. Таким образом, групповое выражение определяет вычисляемый контекст замены и может быть задано в одном из следующих вариантов:

<выражение>

<выражение>//<место замены>/<режим замены>

<выражение>//<место замены>

 

Здесь:

<выражение>      - комбинация действий на основе конструкции

                               <операнд>  или   <операнд> <операция> <операнд>,

                                где допускается использование круглых скобок

                                для задания порядка выполнения операций;

<операнд>           - одна из конструкций:

                       <число>или<строковый операнд> или

                 <групповой операнд> или <системный операнд>;

<число>              -  целое или вещественное для арифметических операций;

<строковый операнд>  -  строка, заключенная в двойные кавычки

                                           ( "…" );

                                           Замечание. Если строковый операнд содержит

                                          символ "&", то его необходимо представить в виде

                                          "&&", т.к. иначе он будет рассматриваться как

                                           признак подчеркивания следующего за ним символа;

<групповой операнд>  -  конструкция вида:

                 - контекст группы: {n}  , где

                    n  -  номер группы (1<=n<=9), содержимое которой надо взять,

                    допускается выборка диапазона символов и лексем;

                 -  блок редактирования: {10} , где 10 - признак блока,

                    допускается выборка диапазона строк, символов и лексем;

                 -  входная строка: {0} , где 0 - признак строки редактирования, 

                    допускается выборка диапазона символов и лексем;

<системный операнд>  -  конструкция вида:

                 -  контекст архива: {{n}}  , где

                       n    -  номер ячейки общего архива (n=1,2,…);

                       допускается выборка диапазона символов и лексем;

                 -  системная переменная:  элемент списка TStringList типа String

                       (объект ObjectPascal) с именем  sysvar[n] (n=0,1,2,…)

                       (например, sysvar (=sysvar0), sysvar1,sysvar99);

                       допускается выборка диапазона символов и лексем;

                 -  системный список:  список типа TStringList (объект ObjectPascal)

                       с именем syslist[n] (n=0,1,2,…)

                       (например, syslist (=syslist0), syslist1,syslist99);

                       допускается выборка диапазона строк, символов и лексем;

                 -  системный файл: файл, располагающийся в том же каталоге,

                       что и TeConv.exe, c именем  sysfile, sysfile1 или sysfile2 ;

                       эти файлы создаются с использованием блоковой функции

                       BlockEdit и  используются  в блоковой функции BlockConv;

                  допускается выборка диапазона лексем;

<операция>       -  допустимы следующие операции (по убыванию приоритета):

                           Max , Min , Abs , Int , Fruc , Sqr , Sqrt   (встроенные функции)

                           div , mod , * , /

                           + , -

                           &   (объединение операндов в одну строку);

<место замены>   -   <групповой операнд>|<системный операнд>;

<режим замены>  -  r  (заменить диапазон, режим работает по умолчанию)

                                   b (вставить перед начальным символом диапазона замены)

                                   e (вставить после конечного символа диапазона замены);

 

В записи группового выражения общие правила использования спецсимвола @ для "погашения" спецсимволов не действует, т.е. спецсимволы можно свободно использовать в строковых операндах наряду с обычными символами. Исключение составляет использование в строковом операнде спецсимвола $ (конец строки), что позволяет разбивать строку или вставлять в текст новые строки.

 

Вычисление выражения производится в соответствии с правилами арифметики над операндами, выделенными из найденных контекстных групп с учетом заданного диапазона, причем для арифметических операций эти операнды должны быть числовыми значениями. Если надо взять для контекстной замены символьный контекст или часть контекста группы, тогда выражение состоит только из операнда соответствующего вида. При задании места замены и режима замены возможности контекстного редактирования с использованием групп существенно возрастают. Если номер группы замены равен 0, то в режиме r вся исходная строка заменяется выражением, в режиме b выражение вставляется в начало строки, в режиме e выражение добавляется в конец строки.

 

Пример использования в контексте замены группового выражения:

исходная строка:     Х1:200  Х2:20  Х3:2  
контекст поиска:     {Х1:[~ ]+}{Х2:[~ ]+}{Х3:[~ ]+}
контекст замены:    #[">>>$Итог: " & ({1}|4..-1 + {2}|4..-1 + {3}|4..-1)//{0}/r]
выходные строки:    >>>
                                  Итог: 222 
 

Область действия группового контекста ограничивается текущей строкой редактирования, однако есть возможность сохранять нужные контексты в ячейке архива и использовать их в течение одного сеанса редактирования. Признаком работы с архивным контекстом в групповом операнде является конструкция {{n}}, где n>=1 - номер ячейки в архиве. Если в выражении используется архивный контекст, который к этому времени не был определен, то считается, что он пустой для строковой операции и равен нулю для арифметической операции (исключение составляют оба операнда операции умножения и второй операнд операции деления, которые в случае неопределенности полагаются равными 1).

 

Пример использования архивных контекстов и контекстов групп:

исходные строки:         S1:1   S2:2 

                                       S1:10  S2:20 

                                       R1:00  R2:00 

a) контекст поиска:     {S:[~ ]+}{S:[~ ]+}

    контекст замены:    #[{{1}}+{1}|4..-1//{{1}};  {{2}}+{2}|4..-1//{{2}}]

б) контекст поиска:     {R1:[~ ]+}{R2:[~ ]+}

     контекст замены:    #[{{1}}//{1}|4..-1; {{2}}//{2}|4..-1]

выходные строки:        S1:1    S2:2 

                                       S1:10  S2:20 

                                       R1:11  R2:22 

 

 
Циклическое групповое выражение
 

Циклическое групповое выражение позволяет организовать циклический поиск по контекстам общего архива (ключ a), по группам (ключ g), по лексемам входной строки (ключ l), сканировать символы строки (ключ s), работать с элементами системного списка (ключ r), формировать итерационные символьные строки (ключ i) :

loop(<групповое выражение>)/a [// <место записи итерации цикла>]    

loop(<групповое выражение>)/g [// <место записи итерации цикла>]    

loop(<групповое выражение>)/l [// <место записи итерации цикла>] 

loop(<строковый операнд>)/s [// < место записи итерации цикла>]

loop(<системный список>)/r [// < место записи итерации цикла>]

loop(<шаблон>#<число повторов>)/i // <место записи>

 

При этом цикл для параметров a и g производится либо по параметру группового выражения, который содержит в качестве архивного контекста или группы конструкции {{*}} или {*}, либо по значениям диапазона или лексем контекстов, заданных конструкциями типа  {n}|*..* , {n}|*''* , {{n}}|*..* , {{n}}|*''* (см. простое групповое выражение и конструкции подстановок) , а для параметра l – по строке с лексемами ( например, цикл loop({{1}}|*..*)/l определяет  выборку всех лексем из ячейки архива {{1}} ). При этом <место записи итерации цикла>  указывает системную переменную или ячейку архива для сохранения итерации цикла, удовлетворяющей заданному условию. Параметр i определяет цикл создания итерационной строки по заданному шаблону и числу повторов ( например, цикл формирования в системной переменной sysvar строки из 6 пробелов: loop(" "#6)/i//sysvar ). Параметр s определяет цикл выборки байтов из заданного строкового операнда ( например, цикл loop(sysvar1|1..3)/s определяет  выборку первых трёх байтов из системной переменной sysvar1 ). Параметр r определяет цикл выборки строк из системного списка ( например, цикл loop(syslist2|*..*)/r определяет  выборку всех строк из системного списка syslist2 ).

 

Разновидностью циклического выражения является неявный цикл по заданному диапазону значений символов:

<начальная граница диапазона>^^<конечная граница диапазона>

( например, 0^^9  - цикл по цифрам,  A^^Z  - цикл по латинским буквам).  

 

 
Блоковые функции
 

Блоковая функция позволяет выполнить некоторые дополнительные действия в процессе контекстного редактирования. Определен следующий набор блоковых функций:

 

BlockOper

-

основные блоковые операции: сохранение, замена, вставка, удаление строк блока;

BlockConv

-

преобразование символов блока: кодировка, регистр;

BlockEdit

-

создание файлов с характеристиками состояния найденных контекстов в блоке редактирования;

BlockFile

-

работа с внешним файлом: выделение, запись контекстов;

BlockRepl

-

выполнение контекста замены в групповом операторе;

BlockLexm

-

работа с лексемами строки: чтение, добавление, замена, удаление;

BlockFind

-

работа с текстовой строкой: вхождение шаблона, длина строки и др.;

BlockEval

-

вычисление числовых подвыражений в строке;

BlockInfo

-

выдача информационной строки в StatusBar;

BlockList

-

работа со строками системного списка: загрузка, чтение, запись, добавление, замена, удаление, очистка и др.;

BlockForm

-

форматирование строки в рамках заданного поля шаблона;

BlockNumb

-

перевод целых числе между системами счисления ( от 2 до 36);

BlockOrfg

-

проверка орфографии и создание протокола ошибок.

 

Каждая функция имеет определенный набор входных параметров. При обращении, отсутствующие или заданные по умолчанию параметры в конце списка могут опускаться, а внутри списка (после параметров чтения/записи) задаваться как число 0 .

 

При работе с блоковыми функциями следует четко понимать, где будет находиться указатель по входной строке после выполнения функции, чтобы обеспечить в дальнейшем правильный поиск по оставшейся части редактируемой строки. Функции, не изменяющие входную строку, устанавливают указатель на символ, следующий за конечным значением найденного диапазона контекста поиска, а функции, изменяющие входную строку, устанавливают указатель на символ, следующий за контекстом произведенной замены. После выполнения контекста замены поиск контекста по оставшейся части входной строки начинается с начала таблицы контекстов. Если после выполнения замены указатель перешел за границу строки, то начинается поиск с первой позиции следующей строки редактируемого файла. Для изменения значений выходного указателя по строке, порядка выбора контекстов поиска из таблицы контекстов или чтения строки редактирования из входного файла, следует воспользоваться соответствующими операциями возврата функции BlockOper (brk, setln, setst, setcn).
 
 
                        1. Функция BlockOper
 

Функция BlockOper осуществляет взаимосвязь между блоком редактирования и общим архивом, а также позволяет управлять порядком чтения строк входного файла редактирования. В функции определены семь параметров:

 
BlockOper  (<операция>,<блок чтения>,<блок записи>,
                      <диапазон строк чтения>,<диапазон строк записи>,
                     <признак записи блока в файл>,
                      <признак игнорирования пустых строк блока>)
 
<операция>:

save

-

сохранение строк блока редактирования (блок чтения) в ячейке общего архива (блок записи);

 

repl

-

замена строк в блоке записи на блок чтения;

 

insb

-

вставка строк блока чтения перед строками блока записи;

 

inse

-

вставка строк блока чтения после строк блока записи;

 

del

-

удаление строк блока редактирования (по умолчанию удаляется весь блок);

 

add

-

добавление строк в блок редактирования (строки добавления определяются параметром блока чтения);

 

coll

-

слияние строк блока редактирования (по умолчанию сливается весь блок);

 

brk

-

прерывание поиска контекстов по файлу редактирования после того, как найден блок редактирования, в котором находится контекст замены (выполненная в блоке редактирования редакция заносится в выходной файл);

например, BlockOper(brk) ;

 

brkbl

-

прерывание рекурсии текущего блока и установка курсора на ячейку таблицы, стоящую за строкой входа в итерационный цикл по операции retbl, а если такой ячейки таблицы не существует, то на начало таблицы контекстов (принудительно изменить установку курсора можно операцией setcn);

например, BlockOper(brkbl,,,11);

 

reted

-

переход по таблице контекстов из текущего блокового контекста на блоковый контекст, номер которого указан в четвертом параметре блоковой функции, причем на вход вызываемому блоковому контексту подаётся входная строка, к началу которой добавлены все строки, содержащиеся в блоке редактирования, возврат из нового блокового контекста производится на следующую ячейку таблицы основного блокового контекста;

например,BlockOper(reted,,,3)

 

retbl

-

рекурсия по текущему блоковому контексту таблицы контекстов, номер которого указывается в параметре, причём на вход подаётся строка, отредактированная на прошлом шаге итерации (эта строка берётся из блока редактирования);

например,BlockOper(retbl,,,5);

 

setln

-

позиция указателя по входному файлу:

-сдвиг от текущего значения при чтении очередной строки исходного файла редактирования на n (n>=1) строк вверх (по умолчанию на одну строку вверх);

-сдвиг строки чтения на число строк в блоке редактирования (при n=#), т.е. к началу текущей входной строки добавляются все строки из блока редактирования;

например,BlockOper(setln,,,2),BlockOper(setln,,,#);

setst

-

позиция указателя по входной строке:

 -установка указателя на n-ю позицию строки (для n без знака);

-сдвиг указателя по строке файла редактирования на n символов от конца найденного контекста поиска (при -n к началу строки, при +n к концу строки, при n=-0 сдвиг на начало строки, при n=+0 за пределы строки); -игнорирование найденного контекста при n=0 (по умолчанию), в этом случае  контекст считается ненайденым и курсор не изменяет своего значения;

например, BlockOper(setst), BlockOper(setst,,,-2) ;

setcn

-

позиция указателя по таблице контекстов:

-установка указателя на n-ю (n>=1) ячейку таблицы контекстов;

-сдвиг указателя по таблице контекстов n ячеек от текущего значения (при -n к началу таблицы, при +n к концу таблицы);

-сохранение указателя по таблице для следующего шага редактирования при  n=0 (по умолчанию);

-установка указателя на ячейку таблицы контекстов для  "нестандартного" возврата из блока редактирования nblk, если он был  вызван  из  другого блока редактирования оператором BlockOper(reted,,,nblk); стандартно возврат              из блока производится на ячеку, следующую за оператором вызова, а  для изменения этого порядка следующим  параметром  после setcn  необходимо указать параметр return и этот оператор должен  находиться  в  конечной              конструкции '%$' блока редактирования nblk;

например, BlockOper(setcn), BlockOper(setcn,,,+5), BlockOper(setcn,return,,-4);

 
<блок чтения> или <блок записи>:

{10}

-

блок редактирования (10 - стандартный номер);

{{n}}

-

ячейка с номером  n=1,2,…  из общего архива;

sysvar[n]

-

системная переменная (n=1,2,3…);

 

"  "

-

явно заданный в блоке чтения контекст чтения (если содержит пробел, запятую, закрывающие круглую или квадратную скобку, то заключается в двойные кавычки);

 

 
 
<диапазон строк чтения> или <диапазон строк записи>:
n
-

номер строки блока чтения или записи (при отрицательном значении номера отсчет строк идет от конечной строки блока: -1 – последняя, -2 – предпоследняя и т.д.);

n1..n2
-

диапазон строк блока чтения или записи (значение по умолчанию '1..-1' );.

fname
-

системное или полное имя файла с лексемами, являющимися диапазонами строк блока чтения или записи (системные файловые имена:  sysfile, sysfile1, sysfile2);

 

<признак записи блока в файл>  -  если задано true, то после выполнения блоковой функции блок редактирования записывается в выходной файл редактирования, если задано false (значение по умолчанию), то записи блока не происходит.

Замечание: Если блок редактирования записывается в файл и его последняя строка совпадает с входной строкой {0}, отредактированной на момент записи блока, то запись этой входной строки в файл в дальнейшем не происходит.

 

<признак игнорирования пустых строк блока>  -  если задано true, то пустые строки блока редактирования при записи в выходной файл редактирования игнорируются, если задано false (значение по умолчанию), то пустые строки сохраняются при записи в файл.

 

Примеры обращения к функции:

 

BlockOper(save,{10},{{1}})
-

сохранение блока редактирования в первой ячейке общего архива;

 

BlockOper(del,{10},,1..-2)
-

удаление из общего блока диапазона строк от первой до предпоследней;

 

BlockOper(retn)
-

возврат на одну строку чтения вверх по входному файлу редактирования;

 

BlockOper(setcn,0,0,11)

-

дальнейший поиск контекста по входной строке начнется с 11-й ячейки таблицы контекстов;

 

BlockOper(repl,{10},{10},,,True)
-

запись блока редактирования (после его изменения) в выходной файл;

 

BlockOper(insb,{{1}},{10},,&1|sysfile )
-

вставка перед строкой блока редактирования, определяемой первой лексемой системного файла sysfile1, содержимого первой ячейки общего архива;

BlockOper(retbl,,,20)
-

рекурсия по текущему блоку редактирования с номером 20.

 
 
                        2. Функция BlockConv
 

Функция BlockConv осуществляет различные преобразования символов строк блока. В функции определены шесть параметров:

 
BlockConv  (<блок чтения>,<диапазон строк>,<диапазон символов в строке>,
                       <режим языка перевода>,<режим регистра перевода>,
                       <признак записи блока в файл>)
 
<блок чтения>:

{10}

-

блок редактирования (10 - стандартный номер);

{{n}}

-

ячейка с номером  n=1,2,…  из общего архива;

sysvar[n]

-

системная переменная (n=1,2,3…);

 
 
<диапазон строк>:
n
-

номер строки блока чтения (при отрицательном значении номера отсчет строк идет от конечной строки блока: -1 – последняя, -2 – предпоследняя и т.д.);

n1..n2
-

диапазон строк блока чтения (значение по умолчанию '1..-1' );

 
<диапазон символов в строке>:
n
-

номер символа в строке блока чтения (при отрицательном значении номера отсчет символов идет от длины строки блока: -1 – последний, -2 – предпоследний и т.д.);

n1..n2
-

диапазон символов в строке блока чтения;

fname
-

системное или полное имя файла со строками, состоящими из лексем: номер строки блока чтения, номер символа начала диапазона, номер символа конца диапазона (системные файловые имена:  sysfile, sysfile1, sysfile2);

 
<режим языка перевода>:

en

-

перекодирование символов строки на латинский регистр;

ru

-

перекодирование символов строки на русский регистр;

eneq

-

перекодирование символов строки c одинаковым написанием букв с русского на английский;

rueq

-

перекодирование символов строки c одинаковым написанием букв с английского на русский;

doswin

-

перекодирование символов строки из dos в  win1251;

windos

-

перекодирование символов строки из win1251 в  dos;

koiwin

-

перекодирование символов строки из koi8-r в  win1251;

winkoi

-

перекодирование символов строки из win1251 в  koi8-r;

 
 
<режим регистра перевода>:
up
-

перекодирование символов строки на верхний регистр;

dn
-

перекодирование символов строки на нижний регистр;

 

<признак записи блока в файл>  -  если задано true, то после выполнения блоковой функции блок редактирования записывается в выходной файл редактирования, если задано false (значение по умолчанию), то записи блока не происходит.

 

Примеры обращения к функции:

 

BlockConv({10},0,sysfile,rueq,dn,true)

-

перевод символов строк блока (указываются в системном файле sysfile), совпадающих по написанию (ABEKMHOPCTXY), с английского на русский, а также на нижний регистр; ключ false указывает на то, что после перекодировки блок записывается в выходной файл;

BlockConv({10},0,sysfile1,eneq,dn)

-

перевод символов строк блока (указываются в системном файле sysfile1), совпадающих по написанию (АВЕКМНОРСТХУ), с русского на английский, а также на нижний регистр;

BlockConv(sysvar2,0,0,doswin)

-

перевод из dos в win1251 символов строки, находящейся в системной переменной sysvar2.

 
 
                        3. Функция BlockEdit
 

Функция BlockEdit предназначена для создания рабочих файлов, в которых записываются определенные характеристики найденных контекстов в блоке редактирования. Эти файлы в дальнейшем могут использоваться как параметры в других блоковых функциях. В функции может быть два, три и более параметров:

 
 
BlockEdit  (<операция>,<имя выходного файла>,
                     <диапазон контекста>, … <диапазон контекста>)
 
<операция>:
selcn
-

выборка заданных в качестве параметров функции диапазонов контекста и запись их в создаваемый файл в виде строк:

<номер строки блока>  <начало диапазона контекста>  <конец диапазона контекста>

selsp
-

создание файла с диапазоном min и max номеров строк блока, содержащих найденный в блоке контекст, т.е. файл будет содержать строку вида:

<min номер строки>  <max номер строки>

selln
-

создание файла с перечнем номеров строк блока, содержащих контекст, т.е. файл будет содержать строку вида:

<номер строки блока>  <номер строки блока>    <номер строки блока>;

crtfl
-

создание нового выходного файла с заданным именем.

 

<имя выходного файла> - системное или полное имя выходного файла (системные файловые имена:  sysfile, sysfile1, sysfile2).

 

Примеры обращения к функции:

 
Контекст поиска:
Контекст замены:
Комментарий:
|4|{Пример:}
#[BlockEdit(selln,sysfile2)}

номера строк блока с найденным контекстом Пример: будут записаны в рабочий файл sysfile2;

 

|3|{[A-Z0-9]*}
#[BlockEdit(selcn,sysfile1,
                     _{1}..{1}_)]

при нахождении в строке блока данного контекста, третий параметр блоковой функции будет заменен значениями начала и конца диапазона найденного контекста, а при выполнении блоковой функции эти значения будут записаны в рабочий файл sysfile1 ;. 

 

|2|{%@*}
#[BlockEdit(selsp,d:\rf.txt)]

при работе блоковой функции сформируется рабочий файл d:\rf.txt, в котором будет находиться строка с диапазоном номеров строк блока, где встречаются строки, начинающиеся с символа * ;

 
#[BlockEdit(crtfl,sysfile)]

создание нового выходного файла с системным именем sysfile .

 
 
                        4. Функция BlockFile
 

Функция BlockFile дает возможность работать во время редактирования входного файла с другим внешним файлом, при этом поиск информации по файлу происходит путем задания начального и конечного контекстов поиска. В функции определены одиннадцать параметров:

 
BlockFile  (<операция>,<блок чтения>,<блок записи>,
                    <начальный контекст чтения>,<конечный контекст чтения>,
                    <начальный контекст записи>,<конечный контекст записи>,
                     <признак записи блока в файл>,
                     <признак позиционного/блокового контекста чтения>,
                     <признак позиционного/блокового контекста записи>,
                      <признак учета регистра при поиске контекста>),

                      <диапазон строк блока чтения>)

 
 
<операция>:

extr

-

выделение контекста из внешнего файла и запись его в блок;

repl

-

замена во внешнем файле из блока контекста или строк в зависимости от позиционного или блокового признака;

insb

-

вставка контекста перед контекстом или строкой в зависимости от позиционного или блокового признака из блока во внешний файл;

inse

-

вставка контекста после контекста или строки в зависимости от позиционного или блокового признака из блока во внешний файл;

svarh

-

сохранение общего архива в файле записи;

ldarh

-

загрузка общего архива из файла чтения;

svllist

-

сохранение левого списка в файле записи;

ldllist

-

загрузка левого списка из файла чтения;

svrlist

-

сохранение правого списка в файле записи;

ldrlist

-

загрузка правого списка из файла чтения;

 
<блок чтения> или < блок записи>:

{10}

-

блок редактирования (10 - стандартный номер);

{{n}}

-

ячейка с номером  n=1,2,…  из общего архива;

sysvar[n]

-

системная переменная (n=1,2,3…);

fname

-

полное имя внешнего файла (с путём доступа <имя диска>:\… ); может образоваться также путем подстановки системной переменной в конструкцию "sysvar[n]" при обязательном присутствии двойных кавычек;

LeftList:n

RightList:n

-

файл берётся из ячейки n левого/правого списка; если n=-1, то текущий номер ячейки  списка соответствует номеру редактируемого файла (например при редактировании по правому списку – номер ячейки левого списка соответствует номеру ячейки правого списка с именем редактируемого файла);

FileRes

-

файл результата текущего редактирования;

 

Замечание. Наличие имени файла fname в одном из блоков обязательно для данной блоковой функции.

 

<начальный контекст…> или <конечный контекст…>  -  параметр, являющийся контекстом поиска в файле или блоке редактирования (для системной переменной игнорируется), который обязан заключаться в двойные кавычки, если содержит следующие служебные символы: пробел, , , " , ) , ] , > , :: , || , ; . Контекст может также содержать спецсимволы, используемые в таблице контекстов. Если контекст не задан, то по умолчанию его значение устанавливается равным @ , это означает, что начальный контекст совпадает с началом файла, а конечный контекст - с концом файла. Если конечный контекст представляет собой пустые двойные кавычки "" , то он совпадает с начальным контекстом. Допускается задание в параметре альтернативного контекста. В этом случае контексты, заключенные в двойные кавычки, отделяются друг от друга спецсимволом :: , а при поиске перебираются все допустимые сочетания заданных начального и конечного контекстов (например задание параметров "int func(" :: "real func(" , ")"  означают, что будет искаться вхождение одной из конструкций:  int func( … )  или  real func( … ) .

 

<признак записи блока в файл>  -  если задано true, то после выполнения блоковой функции блок редактирования записывается в выходной файл редактирования, если задано false (значение по умолчанию), то записи блока не происходит.

 

<признак позиционного/блокового контекста>  -  если задано true (значение по умолчанию), то контекст является позиционным и точно соответствует своими границами началу и концу контекстов, заданным в параметрах, если задано false,то контекст является блоковым и соответствует своими границами номерам строк, в которых найдены начало и конец контекста.

 

<признак учета регистра при поиске контекста>  -  если задано true (значение по умолчанию), то регистр учитывается, если задано false, то регистр не учитывается.

 

<диапазон строк блока чтения>:

n

-

номер строки блока чтения (при отрицательном значении номера отсчет строк идет от конечной строки блока: -1 – последняя, -2 – предпоследняя и т.д.);

n1..n2

-

диапазон строк блока чтения (значение по умолчанию 1..-1 );

 

Замечание. Для системной переменной диапазон игнорируется.

 

 

Примеры обращения к функции:

 

BlockFile(extr,sysRcond,{10},"int {{2}}"::"real {{2}}",")", "subroutine",")")

-

выделение контекста из внешнего файла, имя которого содержится в sysRcond  (вычисленная правая часть условного выражения из блока редактирования), причем контекст поиска является альтернативным (от int до ) или от real до ) ), и замена на него в блоке контекста от subroutine до );

BlockFile(extr,d:\zorg\pass.txt, {10},"?*","","Cum","",,,,,3)

-

третью строку из внешнего файла pass.txt (строка выбирается по контексту поиска "?*") вставить вместо контекста "Cum" в блоке редактирования;

BlockFile(extr,"sysvar",sysvar1, %procedure,%\0d\0a,,,,false)

-

поиск контекста - фрагмента, начинающейся со строки procedure и заканчивающегося пустой строкой в файле, полное имя которого определяется через переменную sysvar, и записью найденного фрагмента в переменную sysvar1;

BlockFile(repl,{{2}},d:\fn.txt,,, ""{{1}} "","")

-

содержимое второй ячейки общего архива замещает контекст во внешнем файле с именем d:\fn.txt, заменяемый контекст определяется содержимым первой ячейки общего архива с добавлением конечного пробела;

BlockFile(svarh,,RightList:-1)

-

сохранение общего архива в файле, указанном в текущей ячейке правого списка;

BlockFile(ldarh,RightList:-1)

-

загрузка общего архива из файла, указанного в текущей ячейке правого списка.

 
 
                        5. Функция BlockRepl

 

Функция BlockRepl дает возможность выполнить контекст замены в групповом операторе. Это бывает необходимо, если надо выполнить для найденного контекста несколько действий подряд. В функции определен один параметр:

 

BlockRepl  (<контекст замены>)

 

<контекст замены>  -  параметр, являющийся контекстом замены найденного контекста поиска, который обязан заключаться в двойные кавычки, если содержит пробел, двойные кавычки в качестве граничного символа контекста, запятую, закрывающие круглую или квадратную скобку; контекст может также содержать спецсимволы, используемые в таблице контекстов.

 

Примеры обращения к функции:

 

Контекст поиска:

Контекст замены:

Комментарий:

|1|{%/@*}

#["true"//{{3}}; BlockRepl(%)]

признак разбора блока комментария по символам /* в начале строки: в ячейку архива с номером 3 заносится признак true , после чего входная строка уничтожается;

|1|{%@*/}

#[""//{{3}}; BlockRepl(%)]

снятие признака разбора блока комментария по признаку */ в конце строки: ячейка архива с номером 3 очищается (снятие признака), после чего входная строка уничтожается;

{%//?*}

#[BlockRepl(""""); BlockOper(setcn,0,0,11)]

игнорирование записи строки в выходной файл и задание начального номера выборки запросов по таблице контекстов;

 
 

                        6. Функция BlockLexm

 

Функция BlockLexm предназначена для работы с лексемами строки, причем понимая под лексемой не только последовательности символов, разделенные пробелом (классическое представление), но также допуская в качестве разделителя произвольные наборы символов. Если лексема содержит внутри себя разделитель, то она должна быть заключена в двойные кавычки. Фактически эта функция может быть использована для реализации аппарата работы со списками, располагающимися, например, в отдельной ячейке общего архива или системной переменной, и рассматривать эти списки как  аналог стеков. В функции определены семь параметров:

 

BlockLexm  (<операция>,<строка чтения>,<строка записи>,

                    <контекст вставки/замены/удаления>,<номер начальной лексемы>,

                    <номер конечной лексемы>,<разделитель лексем>)

 

<операция>:

addlex

-

добавление лексемы в конец строки чтения (пробел-разделитель в конце строки-списка сохраняется, если он был в исходной строке);

addchklex

-

добавление лексемы в конец строки чтения, если её  в строке нет (пробел-разделитель в конце строки-списка сохраняется, если он был в исходной строке);

artlex

-

подсчет числа лексем в строке чтения (0, если лексем нет), результат в строке записи;

numlex

-

определение номера лексемы из контекста редактирования в строке чтения (<b>0</b>, если лексемы нет), результат в строке записи;

dellex

-

удаление заданных лексем из строки чтения;

delpatlex

-

удаление лексем из строки чтения по шаблону;

inslex

-

вставка лексем в строку чтения перед заданной; 

rpllex

-

замена лексем в строке чтения в заданном диапазоне; 

getlex

-

получение лексем заданного диапазона из строки чтения; 

dlmlex

-

замена разделителя лексем в строке чтения;

 

<строка чтения> или < контекст вставки/замены>:

{{n}}

-

ячейка с номером  n=1,2,…  из общего архива;

sysvar[n]

-

системная переменная (n=1,2,3…);

"  "

-

явно заданный контекст чтения (обязательно заключается в двойные кавычки, если содержит пробел, запятую, двойные кавычки, закрывающие круглую или квадратную скобку);

 

<строка записи>:

{{n}}

-

ячейка с номером  n=1,2,…  из общего архива;

sysvar[n]

-

системная переменная (n=1,2,3…);

 

<номер начальной лексемы> или <номер конечной лексемы>:

целое число, заданное явно или получаемое в результате подстановки и вычисления  группового выражения; по умолчанию – первая и последняя (-1) лексемы строки чтения (отрицательное число задаёт отсчет лексем от конца строки);

 

<разделитель лексем>:

произвольный контекст (по умолчанию - пробел);  разделитель в виде двойного пробела "  ", указывает на то, что контекст  вставки/замены, содержащий пробелы, рассматривается как строка, состоящая из нескольких лексем, разделённых пробелом, в противном случае контекст вставки/замены всегда представляется как одна лексема.

 

Примеры обращения к функции:

 

BlockLexm(addlex,{{11}},,"a b c" , , ,"  " )

-

добавление в 11-ю ячейку общего архива трёх лексем "a", "b" и "c", поскольку в качестве разделителя задан двойной пробел;

BlockLexm(artlex,{{3}},sysvar3, , , , ",")

-

подсчёт числа лексем с разделителем "," в третьей ячейке архива и занесение результата в sysvar3;

BlockLexm(getlex,sysvar,sysvar1, , sysvar2|-1''-1, sysvar2|-1''-1)

-

выборка лексемы из переменной sysvar по номеру, хранящемуся в  последней лексеме переменной sysvar2, и помещение результата в переменную sysvar1;

BlockLexm(rpllex,{{sysvar}},{{sysvar}},sysvar1 & sysvar2,r*,r*)

-

замена лексемы с номером r* (значение циклического поиска в условном блоковом контексте) в ячейке архива с номером  sysvar на конструкцию, получаемую в результате подстановки значений переменных в выражение:

 sysvar1 & sysvar2;

BlockLexm(numlex,{{33}},sysvar2,sysvar1)

-

определение номера лексемы из переменной sysvar1 по списку лексем из ячейки общего архива {{33}} и занесение результата в sysvar2 (разделитель лексем по умолчанию пробел).

 

 

                       7. Функция BlockFind

 

Функция BlockFind  предназначена для получения определённой информации, касающейся входной строки. В функции определены шесть параметров:

 

BlockFind  (<операция>,<строка чтения>,<строка записи>,

                    <контекст шаблона>,<переменная для позиции найденного контекста);

)

 

<операция>:

postxt

-

нахождение начальной позиции вхождения контекста шаблона в строку чтения (0, если вхождения нет);

posetxt

-

нахождение позиции последнего вхождения символа-шаблона в строку чтения (0, если вхождения нет);

lngtxt

-

длина строки чтения в байтах;

contxt

-

поиск контекста (простого или с использованием спецсимволов) в строке чтения; найденный контекст помещается в строку записи, а номер позиции начала контекста в переменную для позиции найденного контекста (-1, если контекст не найден);

 

<строка чтения> или < контекст шаблона>:

{{n}}

-

ячейка с номером  n=1,2,…  из общего архива;

sysvar[n]

-

системная переменная (n=1,2,3…);

"  "

-

явно заданный контекст чтения (обязательно заключается в двойные кавычки, если содержит пробел, запятую, двойные кавычки, закрывающие круглую или квадратную скобку);

{n}

-

контекст группы  ( 1<=n<=9 );

 

<строка записи>:

{{n}}

-

ячейка с номером  n=1,2,…  из общего архива;

sysvar[n]

-

системная переменная (n=1,2,3…);

 

<контекст шаблона>  - может задаваться через переменную или непосредственно в виде текстовой строки в двойных кавычках;

 

<признак учета регистра>  -  если задано true (значение по умолчанию), то регистр учитывается, если задано false, то регистр не учитывается;

 

<переменная для позиции найденного контекста>  - номер позиции найденного контекста во входной строке для операции contxt.

 

Примеры обращения к функции:

 

BlockFind(postxt,{{11}},sysvar ,". " )

-

нахождение позиции вхождения в 11-ю ячейку общего архива шаблона  "." и занесение номера позиции в переменную  sysvar ;

BlockFind(lngtxt,sysvar3,sysvar)

-

подсчёт длины переменной sysvar3 и занесение результата в sysvar.

BlockFind(contxt,sysvar,sysvar1,{[A-Z][A-Z0-9]*},false,sysvar2)

-

нахождение в переменной sysvar идентификатора (по заданному контексту поиска, без учета регистра) и занесение найденного контекста в sysvar1, а номер позиции начала контекста в sysvar2 ;

 

                        8. Функция BlockEval

 

Функция BlockEval  предназначена для вычисления арифметического выражения, если оно найдено в поданной на вход строке и замене этого выражения на его значение.  В функции определены два параметра:

 

BlockEval  (<строка чтения>,<строка записи>)

 

<строка чтения> :

{{n}}

-

ячейка с номером  n=1,2,…  из общего архива;

sysvar[n]

-

системная переменная (n=1,2,3…);

"  "

-

явно заданный контекст чтения (обязательно заключается в двойные кавычки, если содержит пробел, запятую, двойные кавычки, закрывающие круглую или квадратную скобку);

 

<строка записи>:

{{n}}

-

ячейка с номером  n=1,2,…  из общего архива;

sysvar[n]

-

системная переменная (n=1,2,3…);

 

Примеры обращения к функции:

 

BlockEval(sysvar,sysvar)

-

вычисление выражения в переменной sysvar и занесение в неё результата (например, если sysvar содержит строку  "D7+5-1", то на выходе получим "D7+4", т.к. последний символ идентификатора  D7 в выражение не входит).

 
 

                        9. Функция BlockInfo

 

Функция BlockInfo  предназначена для выдачи информационной строки. В функции определены три параметра:

 

BlockInfo  (<информационная строка>,<параметр выдачи>,<признак выдачи>)

 

<информационная строка>  -  строка текстовых символов;

 

<параметр выдачи>:

0

-

выдача сообщения в StatusBar (по умолчанию);

 

<признак выдачи> - если задано true, то информационная строка добавляется в строку сообщения в виде комментария, заключенного в фигурные скобки (в случае пустой информационной строки скобки не ставятся), если задано false (значение по умолчанию), то выдаётся новая строка сообщения.

 

Пример обращения к функции:

 

BlockInfo("комплексная арифметика",,True )

-

добавление комментария  {комплексная арифметика} в StatusBar ;

BlockInfo("",,True )

-

снятие комментария.

 

 

                  10. Функция BlockList

 

Функция BlockList предназначена для работы с системными списками, создаваемыми как объекты Object Pascal типа TStringList. Использование системных списков вместо системных переменных в качестве стеков или для хранения информационных списков намного сокращает время обработки текущей информации. В функции определены пять параметров:

 

BlockList  (<операция>,<блок чтения>,<блок записи>,
                      <индекс списка>,<разделитель лексем>)

 

<операция>:

ladd

-

добавление в системный список блока записи  строки из блока чтения;

lins

-

вставка перед заданным индексом в системный список блока записи строки из блока чтения;

ldel

-

удаление по заданному индексу из системного списка блока записи строки из блока чтения;

lclear

-

очистка строк системного блока чтения;

lcount

-

размер (число строк) системного блока чтения;

lgetstr

-

получение строки с заданным индексом из системного списка блока чтения в блоке записи (переменной или архиве);

lsetstr

-

занесение строки из блока чтения (переменной или архива) в строку системного списка с заданным индексом блока записи;

ltext

-

получение строк системного списка блока чтения в виде текстовой строки с разделителями EOLN в блоке записи (переменной или архиве);

ldlexm

-

загрузка системного списка блока записи лексемами с заданным разделителем из блока чтения (переменная или архив);

svlexm

-

выгрузка системного списка блока чтения в виде лексем с заданным разделителем (пустой разделитель - """" ) в блок записи (переменную или архив);

ldfile

-

загрузка системного списка блока записи строками файла, полное имя которого задано в блоке чтения;

svfile

-

выгрузка системного списка блока чтения в файл, полное имя которого задано в блоке записи;

lcopy

-

копирование системных списков;

 

<блок чтения> или <блок записи>:

{10}

-

блок редактирования (10 - стандартный номер);

{{n}}

-

ячейка с номером  n=1,2,…  из общего архива;

sysvar[n]

-

системная переменная (n=1,2,3…);

syslist[n]

-

системный список (n=1,2,3…);

""   

-

явно заданный контекст чтения (обязательно заключается в двойные кавычки, если содержит пробел, запятую, закрывающие круглую или квадратную скобку);

fname

-

полное имя файла;

 

<индекс списка>:

целое число (n>=1), которое не должно превышать размер списка;

 

<разделитель лексем>:

произвольный контекст (по умолчанию - пробел);  разделитель в виде двойного пробела "  ", указывает на то, что контекст, содержит лексемы, заключенные в двойные кавычки и содержащие внутри себя пробелы-разделители (например, контекст, состоящий из трех лексем: "a b c" "a1 b1" c1), либо определяет контекст вида  ( a b c )  как одну лексему.

 

Примеры обращения к функции:

 

BlockList(ldlexm,syslist2,sysvar2)

-

загрузка системного списка syslist2 из системнеой переменной sysvar2;

BlockList(ldel,syslist2,,sysvar10)

-

удаление из системного списка syslist2, строки с индексом, содержащимся в sysvar10;

BlockList(ladd, ""a b c" "a1 b1" c1",syslist)

 

добавление в список syslist строки из трех лексем.

 

 

                        11. Функция BlockForm

 

Функция BlockForm предназначена для форматирования строки в  рамках заданного поля шаблона. Поле шаблона - это строка заданной  длины, образованная  повторением символа поля шаблона, в пределах границ которой позицинируется  входная  строка  в соответствии с заданной операцией выравнивания, т.е. символы в строке записи  после выравнивая строки чтения относительно поля шаблона являются символами поля шаблона. В функции определены пять параметров:

 

BlockForm  (<операция>,<строка чтения>,<строка записи>,

                      <длина поля шаблона>,<символ поля шаблона>)

 

<операция>:

ljust

-

выравнивание строки чтения по левому краю поля шаблона;

rjust

-

выравнивание строки чтения по правому краю поля шаблона;

cjust

-

центрирование строки чтения по полю шаблона;

 

<строка чтения>:

{10}

-

блок редактирования (10 - стандартный номер);

{{n}}

-

ячейка с номером  n=1,2,…  из общего архива;

sysvar[n]

sysvar[n]|<диапазон>

-

системная переменная (n=1,2,3…);

"  "

-

явно заданный контекст чтения (если содержит пробел, запятую, закрывающие круглую или квадратную скобку, то заключается в двойные кавычки);

 

<диапазон>:

n1..n2

-

диапазон символов строки чтения, где n - номер символа в строке  (при отрицательном значении номера идет отсчет от конца строки: -1 – последняя, -2 – предпоследняя и т.д.);

n1''n2

-

диапазон лексем строки чтения, где n - номер лексемы в строке (при отрицательном значении номера идет отсчет от конца строки: -1 – последняя, -2 – предпоследняя и т.д.);

 

<строка записи>:

{10}

-

блок редактирования (10 - стандартный номер);

{{n}}

-

яейка с номером  n=1,2,…  из общего архива;

sysvar[n]

-

системная переменная (n=1,2,3…);

 

<длина поля шаблона>  - целое число (n>=1), определяющее размер строки записи;

 

< символ поля шаблона>  -  символ, из которого образовано поле шаблона  (по умолчанию - пробел);

 

Примеры обращения к функции:

 

BlockForm(сjust,"Комментарий",sysvar1,25)

-

центрирование строки 'Комментарий' по полю шаблона, представляющего

строку из 25-ти пробелов (шаблон по умолчанию); ка результат записывается в системную переменную sysvar1 ;

BlockForm(rjust,{{2}}|1''1,sysvar,6,"0")

-

выравнивание по правому краю строки, являющейся 1-ой лексемой ячейки общего архива {{2}}, по полю шаблона '000000', и запись результата в системную переменную sysvar (например, если выбранная лексема – '125', то  выходная строка - '000125' ;

 

 

                       12. Функция BlockNumb

 

Функция BlockNumb  предназначена для перевода целых чисел в  различные системы счисления (диапазон основания счисления от 2 до 36). В функции определены четыре параметра:

 

BlockNumb  (<основание входной константы>,<основание выходной

                          константы>, <константа чтения>,<константа записи>)

 

 

<основание входной константы>|основание выходной константы>|

<константа чтения>:

{n}

{n}|<диапазон>

-

групповой контекст с номером группы n=1,2,3,…9;

{{n}}

{{n}}|<диапазон>

-

ячейка с номером  n=1,2,…  из общего архива;

sysvar[n]

sysvar[n]|<диапазон>

-

системная переменная (n=1,2,3…);

"  "

-

явно заданная константа;

 

<диапазон>:

n1..n2

-

диапазон символов строки чтения, где n - номер символа в строке  (при отрицательном значении номера идет отсчет от конца строки: -1 – последняя, -2 – предпоследняя и т.д.);

n1''n2

-

диапазон лексем строки чтения, где n - номер лексемы в строке (при отрицательном значении номера идет отсчет от конца строки: -1 – последняя, -2 – предпоследняя и т.д.);

 

<константа записи>:

{10}

-

блок редактирования (10 - стандартный номер);

{{n}}

-

яейка с номером  n=1,2,…  из общего архива;

sysvar[n]

-

системная переменная (n=1,2,3…);

 

 

Пример обращения к функции:

 

BlockNumb("10",{1},"2011",{{sysvar}})

-

перевод константы '2011'  из десятичной системы счисления в систему счисления, определяемую сожержимым найденной контекстной группы {1} и запись результата в ячейку общего архива с номером  sysvar ;

 

 

                       13. Функция BlockOrfg

 

Функция BlockOrfg  дает возможность создать протокол ошибок,  обнаруженных  при  проверке орфографии текстового файла, отражающий строку файла с  ошибочным  словом, слово и варианты его замены,  ведется  также  подсчет количества ошибочных  слов  в файле. В  функции  определены четыре параметра:

 

BlockOrfg  (<блок чтения>,<блок записи>,<режим записи>,<язык проверки>)

 

<блок чтения>  или  <блок записи>:

{{n}}

-

ячейка с номером  n=1,2,…  из общего архива;

 

sysvar[n]

-

системная переменная (n=1,2,3…);

 

fname  

-

полное имя внешнего файла с путём доступа <имя диска>:\…; имя файла может образоваться также путем подстановки системной переменной в  конструкцию "sysvar[n]" при обязательном присутствии двойных кавычек;

 

LeftList:n  или  RightList:n

-

файл берётся из ячейки n левого или правого списка; если n=-1, то текущий  номер ячейки списка соответствует номеру редактируемого файла (например, при редактировании по  правому  списку    номер  ячейки  левого  списка соответствует номеру  ячейки  правого  списка  с  именем  редактируемого файла);

замечание:

 

блоки чтения и записи при подстановке должны содержать полное имя  файла с контрольным текстом и с протоколом соответственно; блок  чтения  может отсутствовать, тогда имя  файла  проверки  совпадает  с  текущим  файлом редактирования, а блок записи должен быть задан всегда;

 

<режим записи> -  режим записи в протокол:

                                  new - для создания нового файла протокола,

                                  add - для добавления в файл протокола;

 

<язык проверки> -  язык проверки орфографии:

                                    ru - для проверки русского текста,

                                    en - для проверки английского текста.

 

 

Пример обращения к функции:

 

BlockOrfg(,D:\RA\protorf.txt,add,ru)

-

проверка орфографии русского текста (ru) с добавлением (add) найденных ошибок в файл протокола D:\RA\protorf.txt;

 

 

Операция условного выбора

 

Операция условного выбора  cond  предназначена для выполнения тех или иных действий в зависимости от истинности или ложности  задаваемого условия. Операция имеет две формы представления, содержащие набор операторов для истинного и ложного значения условия или только для его истинного значения:

 

     cond( <условие> )/ <набор операторов> /,/ <набор операторов> /;

или         

     cond( <условие> )/ <набор операторов> /;

 

Здесь:

 

    <условие>      - условное выражение (простое или сложное );

                     сложное условное выражение может содержать символы-разделители:

                     ||  (соответствует логической операции ‘И’)  означает  наличие

                     нескольких одноуровневых условных выражений, каждое из которых

                     должно выполняться для истинности всего условия,

                     ::  (соответствует логической операции ‘ИЛИ’)  означает

                     наличие нескольких одноуровневых условных выражений, из которых

                     должно выполняться хотя бы одно для  истинности всего условия.

 

    <набор операторов>     - один или несколько групповых операторов, оканчивающихся

                    обязательным символом ; (рекурсия операций условного выбора в наборе

                    операторов не допускается).

 

Пример операции условного выбора:

 

cond( sysvar3<0  ::  sysvar3>0  ||  (sysvar3-sysvar1)>=0 )/{{1}} & {1} & " "//{{1}} /,/ {{2}} & {1} & " "//{{2}} /;

-

условная операция с участием системных переменных содержит сложное условие вида условие1 или (условие2 и условие3), и при истинности сложного условия контекстная группа {1} приформировывается в ячейку  {{1}} общего архива, а при ложности условия - в ячейку {{2}};

 

 

Аппарат подстановок в контекстах и сценариях

                        Источники и виды подстановок

 

Перед выполнением группового оператора сначала производится подстановка значений в групповой или системный операнды, а также значений в переменные выполнения условия. Кроме этого в подстановках могут быть использованы списки  и  файлы.  Таким  образом, различного  вида  информация  может  быть  получена   и   использована   в   процессе редактирования, что  позволяет  задавать  в  контекстах  поиска/замены  сложные  виды контрольных проверок и преобразований. Аналогичные  подстановки  производятся  и  при анализе параметров блоковой функции перед её реализацией.

 

Исходные конструкции подстановки:

 

 - группа: {n} (n=1,…,9);

 - блок редактирования: {10} ;

 - входная строка: {0} ;

 - системная переменная:sysvar[n] (n>=1);

 - системный список: syslist[n] (n>=1);

 - ячейка общего архива: {{n}} (n>=1);

 - переменные выполнения условия: SysLloop, SysRloop, SysNcond, SysLiter,

                                                               SysRiter, SysLval, SysRval, r*, R*, l*, L*;

 - правый и левый список: RightList[:n], LefttList[:n] (n>=-1);

 - системный файл: sysfile[n] (n=1,2);

 - внешний файл с полным путем доступа;

 

Выборка информации из исходных конструкций подстановки  может  определяться  заданием соответствующих диапазонов строк, символов или лексем:

 

 s0..s1  - диапазон строк , где        s0 - номер начальной строки выборки,

                                                         s1 - номер конечной строки выборки;  

 d0..d1  - диапазон символов, где d0 - номер начального символа выборки,

                                                         d1 - номер конечного символа выборки;

 d0''d1  - диапазон лексем, где     d0 - номер начальной лексемы выборки,

                                                         d1 - номер конечной лексемы выборки;

 Замечание: последний элемент выборки может быть задан как -1, предпоследний - -2 и т.д.

 

При выборе диапазона могут использоваться служебные символы-модификаторы:

 

<модификатор диапазона>       -

                     ..           байтовый диапазон строки | строковый диапазон блока

                     ''           диапазон лексем строки

                     ~           удаление пробелов левой или правой границы диапазона

                     non       признак непустой строки диапазона блока,

                                   удаление пробелов до «взятия» диапазона

                     _{…}    номер начального байта контекста группы по строке

                     {…}_    номер конечного байта контекста группы по строке

 

При занесении однотипной информации сразу во все созданные на данный момент ячейки общего архива в групповом выражении может использоваться конструкция {{*}} в качестве места замены. Например, чтобы очистить все ячейки архива следует написать оператор:  ""//{{*}}

 

Особый вид подстановок может использоваться в сценарии. Эти подстановки  связаны с реализацией цикла в сценарии и  основываются  на  последовательных  строках  файла, содержащих информацию, считываемую для использования в текущей  итерации  цикла  (см. раздел  "Приемы создания сложных сценариев").  Признаком  конструкции  подстановки  в сценарии является символ  & .

 

                        Конструкции подстановок

 

{n}

{n}|d0..d1

{n}|d0''d1

-

по номеру группы (n=1,…,9), найденной в процессе контекстного поиска по входной строке файла, берется текстовое значение контекста и при необходимости из него выделяется диапазон символов от d0 до d1 (разделитель - две точки) или лексемы от d0 до d1 (разделитель – два апострофа);

{{n}}

{{n}}|d0..d1

{n}|d0''d1

-

по номеру ячейки общего архива (n>=1) берется текстовое значение контекста и при необходимости из него выделяется диапазон символов от d0 до d1 (разделитель - две точки) или лексемы от d0 до d1 (разделитель - два апострофа);

{n}|~d0..d1

{n}|d0..d1~

{n}|~d0..d1~

-

из контекста, соответствующего номеру группы (n=1,…,9), выделяется диапазон символов от d0 до d1, при этом из него удаляются начальные, конечные или обрамляющие пробелы;

{{n}}|~d0..d1

{{n}}|d0..d1~

{{n}}|~d0..d1~

-

из контекста, соответствующего номеру ячейки общего архива (n>=1), выделяется диапазон символов от d0 до d1, потом из него удаляются начальные, конечные или обрамляющие пробелы; например, “__bbcc”|~1..-1 (здесь __ заменяет для наглядности два пробела) соответствует выборке подстроки “bbcc”, а при “__bbcc”|1..-1 выбирается вся строка с начальными пробелами;

{{n}}|nond0..d1

{{n}}|d0..d1non

{{n}}|nond0..d1non

-

из строки сначала удаляются начальные, конечные или обрамляющие пробелы, и из полученной строки выделяется диапазон символов от d0 до d1; например, “__bbcc”|non1..1 (здесь __ заменяет для наглядности два пробела) соответствует выборке символа b, а при “__bbcc”|1..1 выбирается первый пробел;

_{n}

  {n}_

-

по номеру группы (n=1,…,9), найденной в процессе контекстного поиска по входной строке файла, определяется номер начального или конечного символа контекста группы в строке; такая конструкция может быть использована в задании границ диапазона (например, _{2}+1..{2}_);

_{n}|non

  {n}_|non

-

номер начального или конечного непустого байта для найденного контекста группы в строке; например, контекст поиска первой группы { *b+} в строке aa__bbcc (здесь __ заменяет для наглядности два пробела) имеет диапазон символов в строке 3..6 , т.е. _{1} равно 3, а при использовании модификатора _{1}|non равно 5;

{10}|s0..s1

{10}|nons0..s1non

-

из блока редактирования выбирается диапазон строк от s0 до s1; признак non указывает на то, что пустые граничные строки диапазона игнорируются, т.е. происходит сужение диапазона выборки строк;

{10}|s0..s0|d0..d1

{10}|nons0..s0|d0..d1

{10}|s0..s0non|d0..d1

{10}|~s0..s0~|d0..d1

-

из блока редактирования выбирается строка с номером s0, из которой далее выделяется диапазон символов от d0 до d1; признак non указывает на непустую строку выборки при движении вниз или вверх по блоку от заданной строки, если она пустая, а признак ~ обеспечивает удаление граничных пробелов в выбранной строке (например, последний символ предыдущей непустой строки редактирования, исключая пробел: {10}|non-1..-1~|-1..-1);

{10}_

syslist[n]_

sysvar[n]_

-

длина (число строк) блока редактирования;

длина (число строк) системного списка;

длина строки системной переменной;

&n|m|d:\rab\fn.txt

&n|d:\rab\fn.txt

&n|m|sysfile

&n|sysfile

-

из строки файла с номером m (если номер не задан, то из первой строки) с указанным полным или системным (sysfile, sysfile1, sysfile2) именем выбирается лексема с номером n, при этом строка файла должна соcтоять из лексем, разделенных одним или несколькими пробелами; например, такая конструкция может быть использована в задании границ диапазона &1|sysfile ..&2|sysfile -1 ;

&n|m

-

из файла, образующего цикл m (m>=1) в сценарии, выбирается лексема с номером n (после номера цикла m должен стоять пробел); строка файла должна содержать не менее n лексем, разделенных одним или несколькими пробелами; при n=0 берётся номер итерации текущего цикла сценария;

&n|LeftList:m

&n|RightList:m

-

из файла, имя которого берётся из m-ой ячейки левого или правого списка выбирается лексема с номером n; если m=-1, то текущий номер ячейки  списка соответствует номеру редактируемого по списку файла (например, &2|RightList:-1); при n=0 берётся номер итерации текущего цикла по списку;

sysvar[n]|d0..d1

sysvar[n]|d0''d1

-

выделение диапазона из системной переменной с номером n (n>=1); можно применять все модификаторы диапазона;

sysvar&sysvar[n]

-

подстановка целого значения из системной переменной sysvar[n] как номер другой системной переменной;

syslist&sysvar[n]

-

подстановка целого значения из системной переменной sysvar[n] как номер системного списка;

 

Конструкции подстановок с использованием диапазонов, имен файлов, начинающиеся с символа ‘& , обязательно должны завершаться символом пробел. Значениями диапазонов d0 и d1 могут быть целые числа больше или меньше 0, а также групповые выражения, вычисленными значениями которых являются числа, при этом запись диапазона любого вида внутри себя не должна содержать пробелов (например для выделения символа, следующего за найденным контекстом группы, {1}|-1+1..-1+1 ).

 

Отрицательное значение (номер последнего байта или лексемы) определяет границу диапазона от конца аргумента, к которому относится этот диапазон. Граница диапазона может также являться результатом подстановки целого значения из некоторых исходных конструкций подстановки. Подстановка итерационных значений в  диапазон  может  быть сделана в шаблоне оператора цикла для  генерации  итерационной  строки  (ключ i), в этом случае для указания границ диапазона используется конструкция &*..&* или &*''&* .

 

.Например, есть два списка идентификаторов, разделенных пробелами, в ячейках архива {{1}} и {{2}} и необходимо, в случае нахождения в файле идентификатора из списка {{2}}, заменить его на соответствующий по порядку идентификатор из списка {{1}} плюс смещение, находящееся в архивной ячейке {{3}}:

 

контекст поиска

|[{1}=loop({{2}}|*''*)/a]|{[_A-Za-z][_A-Za-z0-9]*}

содержит условие проверки найденного контекста группы {1} со списком лексем (идентификаторов), находящимся в архивной ячейке {{2}};

контекст замены

#[{{1}}|r*+{{3}}''r*+{{3}}//{1}]

найденный контекст группы {1} заменяется на соответствующую лексему (идентификатор) с учетом смещения {{3}} из списка лексем (идентификаторов), находящегося в архивной ячейке {{1}}.

 

Использование конструкций подстановок намного расширяет возможности применения групповых операторов и обеспечивает организацию циклов в сценариях.

 
 
 
СПЕЦИАЛЬНЫЕ АНАЛИТИЧЕСКИЕ СРЕДСТВА

Граничные контексты в таблице контекстов

 

В многоуровневом сеансе редактирования может возникнуть необходимость в выполнении некоторых действий перед началом или перед завершением определенного этапа редактирования, обусловленного заданным запросом на редактирование (например, занести информацию в некоторые архивные ячейки или системные переменные перед началом или после редактирования). Для выполнения этой цели служат граничные контексты, которые содержат в качестве контекста поиска   <!>  или <!!> , а необходимые для выполнения действия могут быть заданы через групповые операторы в контексте замены. Эти контексты отличаются своим функциональным назначением:

 

<!!>

-

граничный контекст, выполняющийся один раз для текущего запроса редактирования, который может включать группу файлов редактирования;

<!>

-

граничный контекст, выполняющийся в текущем запросе редактирования для каждого файла редактирования.

 

Один или несколько идущих подряд граничных контекстов могут находиться в начале или в конце таблицы контекстов и выполняться, соответственно, перед началом или после завершения редактирования входной информации (при основном поиске/замене по файлу граничные контексты игнорируются). При наличии в таблице контекстов граничных контекстов обоих видов, сначала располагаются строки с контекстом поиска  <!!>  , а потом с контекстом поиска  <!>  .

 

Граничные контексты могут быть использованы для анализа и коррекции состояния ячеек общего архива  до начала или после конца редактирования текущего файла. В этом случае к началу строки с контекстом поиска может быть добавлено условие (в виде конструкции |[…]| ), в котором задаются условные выражения для проверки текущего состояния ячеек общего архива, а в контексте замены -  реакция на выполнение соответствующего условного выражения. Особенностью граничных контекстов является то, что они могут организовывать циклы по таблице контекстов, причём вложенность циклов не ограничена. Область действия цикла определяется позиционным расположением в таблице операторов начала цикла (repeat) и конца цикла (until), но прямое вхождение в середину цикла (явный переход на ячейку таблицы, принадлежащей циклу) может привести к неадекватным действиям. В циклах определены следующие операторы:

 

<!>repeat

-

начало цикла граничного контекста, в контексте замены  могут инициироваться начальные значения системных переменных;

<!>until|[…]|

-

конец цикла граничного контекста, достигается при выполнении первого условия контекста поиска;

<!>continue|[…]|

-

уход на конец текущего цикла после выполнения соответствующего контекста замены (только для первого условия контекста поиска, иначе переход на следующую ячейку таблицы);

<!>break|[…]|

-

выход за конец цикла после выполнения соответствующего контекста замены (только для первого условия контекста поиска, иначе переход на следующую ячейку таблицы).

 

Замечание.  Если условное выражение состоит из нескольких условных выражений, разделяемых операцией  :: , то оператор цикла выполняется только в том случае, если удовлетворяется первое из них, а иначе продолжается поиск контекстов по телу цикла.

 

 

Примеры граничных контекстов:

 

Контекст поиска:

Контекст замены:

Комментарий:

<!!>

#[""//{{*}}]

очистка всех ячеек архива;

<!>

#[loop({{2}}|*''*)/a//sysvar]

цикл формирования в системной переменной sysvar строки из списка лексем, находящихся в архивной ячейке {{2}};

<!>

 

<!>repeat

 

<!>

 

<!>until|[sysvar<=250 :: else]|

 

 

<!>|[sysvar2<>{{2}}]|

#[{{2}}//sysvar1;  ""//sysvar2]

 

 

 

#[BlockFind(lngtxt,"sysvar1",sysvar)]

 

#[sysvar2 & sysvar1//sysvar2 :: sysvar2 & sysvar1|1..250 & "$"//sysvar2; sysvar1|251..-1//sysvar1]

 

#[BlockLexm(rpllex,{{2}},{{2}}, sysvar2)]

 

цикл разбиения длинной строки  архива {{2}} :

sysvar1 - копия строки, sysvar2  - строка замены;

длина строки sysvar1 в

sysvar;

если длина строки <=250, то цикл заканчивается, иначе в sysvar2 ставится признак переноса строки;

если архивная строка не совпадает с sysvar2, то происходит её замена.

 

 

Использование авторских идентификаторов

 

При создании таблицы контекстов чаще удобно употреблять идентификаторы, отражающие мнемонику задаваемого процесса контекстного поиска. Однако все внутренние преобразования и подстановки в таблице контекстов настроены на работу с системными переменными (sysvar, sysvarN, N>=0,1,2,…) и списками /массивами/ (syslist, syslistN, N>=0,1,2,…), поэтому необходим аппарат, обеспечивающий их соответствие. Для создания внутренних таблиц соответствий между авторскими и системными идентификаторами (вне зависимости от регистра набора), необходимо декларировать все используемые авторские идентификаторы для переменных и списков, при этом идентификаторы должны относиться к определенным областям таблицы контекстов:

-          глобальные для всех областей таблицы контекстов;

-          локальные вне блоков редактирования;

-          локальные для отдельного блока редактирования.

 

Декларация переменных и списков в таблице контекстов:

 

Контекст поиска:

Контекст замены:

Комментарий:

<var>|*|

<var>|*|

<lst>|*|

<lst>|*|

# [идент1; идент2;…идентN]

# [идент1=знач1;идент2=знач2…]

# [идент1; идент2;…идентN]

# [идент1=знач1;идент2=знач2…]

 

декларация глобальных переменных и списков; допускается наделение их начальными значениями;

<var>

<lst>

# [идент1; идент2;…идентN]

# [идент1; идент2;…идентN]

декларация  локальных переменных и списков вне блоков редактирования;

<var>||

<lst>||

# [идент1; идент2;…идентN]

# [идент1; идент2;…идентN]

декларация  локальных переменных и списков для блока редактирования без номера;

<var>|n|

<lst>|n|

# [идент1; идент2;      идентN]

# [идент1; идент2;      идентN]

декларация  локальных переменных и списков для блока  редактирования с номером n (n>=1,2…);

 

Конструкции декларации могут располагаться в начале таблицы контекстов или непосредственно перед блоком редактирования. Каждому идентификатору ставится в соответствие системное имя, причем L всех глобальных объектов имеют системные имена с номерами от 0 до L-1, а локальные объекты имеют системные имена с номерами, от L и выше, которые для разных блоков редактирования могут повторяться. Таблица соответствия авторских и системных идентификаторов может быть просмотрена в окне задания параметров отладочного протокола, когда становится доступной кнопка "Идентификация", и использована для определения показа соответствующих системных переменных и списков в режиме отладки.

 
 
 

ПРИЕМЫ СОЗДАНИЯ СЛОЖНЫХ СЦЕНАРИЕВ

 

 

Создавать и дополнять сценарии следует путем выполнения операции "Создать сценарий" в окне "Сценарий редактирования каталогов и файлов", которое появляется после нажатия клавиши {Сценарий} . Здесь следует указать имя файла и режим создаваемого сценария. Тогда при реальном выполнении в редакторе TeConv любого шага редактирования появляется запрос на возможность включения этого шага в файл сценария. Доступ к сценарию открывается при вызове операции "Выполнить сценарий", загрузке сценария из файла и просмотра его через контекстное меню (на этом этапе сценарий можно редактировать: переставлять макросы, изменять их номера, корректировать отдельные параметры макроса). После ручного редактирования сценарий следует сохранить в файле сценария.

 

При создании сценария группа макросов, идентифицированных своим номером в сценарии, может быть оформлена как цикл. Для этого следует войти в специальное окно "Проектировщик циклов в сценарии" по кнопке {Организовать цикл …} и вставить в нужные места операции начала и конца цикла:

#ЦИКЛ:<метка цикла>?<имя файла цикла>
#КОНЕЦ: <метка цикла>

 

Файл цикла должен быть предварительно создан и должен содержать в каждой строке набор заменяемых в цикле параметров, в виде лексем, разделяемых одним или несколькими пробелами. Если параметр содержит пробел, то он должен быть заключен в двойные кавычки, а пустые строки и строки-комментарии, начинающиеся с символа ! , исключаются из цикла. Параметры, подлежащие изменению при очередном проходе цикла (в сценарии и в файле запроса с таблицей контекстов), должны быть вручную заменены на конструкцию подстановки '&n ' или '&n|m ' (n,m >=1), где  n – номер параметра (лексемы) замены из строки файла цикла, а m – метка цикла, по которой ищется соответствующий файл цикла. Метки вложенных циклов не должны совпадать. Если метка не задана, то по умолчанию берется файл текущего цикла. Имя файла цикла может быть как с полным путем доступа, так и без пути, но тогда считается, что файл цикла находится в том же каталоге, что и файл текущего сценария.

 

Создать сложные сценарии, содержащие циклы, чисто механически не удастся в силу того, что в цикл основывается на строках и лексемах этих строк из конкретного файла цикла. Файл цикла может быть заранее написан вручную или создан в процессе работы самого сценария. Рассмотрим для примера создание сценария распаковки zip-файлов, находящиеся в подкаталоге d:\wrk\ .

 

Сначала создадим сценарий, включающий в себя распаковку в подкаталоге d:\wrk\  файла с именем  file1.zip . Этот сценарий создается в режиме "Создать сценарий" при запуске внешнего процесса на странице "Файловые операции", причем путь доступа к имени файла распаковщика pkunzip.exe выбирается с диска C: , а в качестве командной строки задается режим и имя распаковываемого файла (режим -o означает распаковку без запросов). Внешний процесс распаковки выполняется в виде консольного приложения, которое само закроется по истечении заданного времени ( 2,5 сек ):

 

#[ФАЙЛОВЫЕ ОПЕРАЦИИ] {1}
/1/тип операции (индекс): 4
/2/входной (базовый) каталог: 
/3/шаблоны входных файлов: *.*
/4/базировать путь к файлу (признак): 0
/5/выходной каталог: d:\wrk\
/6/шаблоны файлов очистки: *
/7/режим очистки подкаталогов (индекс): 0
/8/создать структуру базы (признак): 0
/9/левый список (признак): 1
/10/правый список (признак): 0
/11/содержимое списка (индекс): 0
[ЗАПУСК ВНЕШНЕГО ПРОЦЕССА]
/1/имя внешнего процесса: c:\exe\pkunzip.exe
/2/источник выбора процесса (индекс): -1
/3/параметры командной строки: -o file1.zip
/4/путь доступа: d:\wrk\
/5/добавить параметр (признак): 0
/6/режим открытия внешнего процесса (индекс): 0
/7/время внешнего процесса: 2500
>ВНЕШНИЙ ПРОЦЕСС
 

Для организации цикла для распаковки списка файлов необходимо иметь файл цикла d:\wrk\listzip.txt , который содержит список zip-файлов, подлежащих распаковке. Тогда первая лексема каждой строки файла образует параметр подстановки, значение которого будет меняться с каждой итерацией цикла:

 
#ЦИКЛ:1?d:\wrk\listzip.txt
#[ФАЙЛОВЫЕ ОПЕРАЦИИ] {1}
/1/тип операции (индекс): 4
/2/входной (базовый) каталог: 
/3/шаблоны входных файлов: *.*
/4/базировать путь к файлу (признак): 0
/5/выходной каталог: d:\wrk\
/6/шаблоны файлов очистки: *
/7/режим очистки подкаталогов (индекс): 0
/8/создать структуру базы (признак): 0
/9/левый список (признак): 1
/10/правый список (признак): 0
/11/содержимое списка (индекс): 0
[ЗАПУСК ВНЕШНЕГО ПРОЦЕССА]
/1/имя внешнего процесса: c:\exe\pkunzip.exe
/2/источник выбора процесса (индекс): -1
/3/параметры командной строки: -o &1 
/4/путь доступа: d:\wrk\
/5/добавить параметр (признак): 0
/6/режим открытия внешнего процесса (индекс): 0
/7/время внешнего процесса: 2500
>ВНЕШНИЙ ПРОЦЕСС
#КОНЕЦ:1
 

Для создания файла цикла d:\wrk\listzip.txt вставим перед макросом цикла элемент сценария, обеспечивающий создание правого списка, содержащего zip-файлы из каталога d:\wrk\ , и запись этого списка в файл цикла (можно сначала дозаписать этот макрос в сценарий при выполнении реальных действий в режиме "Создать сценарий", а потом переставить макросы местами, скорректировав их номера в фигурных скобках):

 

#[СОЗДАНИЕ СПИСКОВ] {2}
/1/источник списка (индекс): 0
/2/входной (базовый) каталог: d:\wrk\
/3/шаблоны входных файлов: *.zip
/4/искать в подкаталогах (признак): 1
/5/неполный путь к файлу (признак): 0
/6/левый список (признак): 0
/7/правый список (признак): 1
/8/новый список (признак): 1
/9/добавить в список (признак): 0
/10/содержимое списка (индекс): 0
/11/уровень от базы (режим):   >=
/12/уровень от базы (значение): 0
>ПО ВХОДНОМУ КАТАЛОГУ
>ЗАПИСАТЬ СПИСОК: d:\wrk\listzip.txt,fNew,fRight,rAll
 

Таким образом, полный сценарий включает в себя два макроса:

 

#[СОЗДАНИЕ СПИСКОВ] {1}
   .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
>ЗАПИСАТЬ СПИСОК: d:\wrk\listzip.txt,fNew,fRight,rAll
#ЦИКЛ:1?d:\wrk\listzip.txt
 
#[ФАЙЛОВЫЕ ОПЕРАЦИИ] {2}
   .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
>ВНЕШНИЙ ПРОЦЕСС
#КОНЕЦ:1