12. ОПЕРАЦИИ С ТЕКСТОВЫМ МАССИВОМ

Текстовый массив t() является одновременно массивом двухбайтовых целых чисел без знака. В этом качестве с его элементами можно проводить вычисления и делать различный анализ. Однако существуют такие стандартные операции, которые желательно выполнить быстрее и одной командой. В таком виде программа становится короче и проще для понимания. Для реализации таких операций разработана команда #text или короче #te. К настоящему времени разработано 7 операций. Минимальное число символов в названии операции равно 4. Рассмотрим эти операции по очереди.
Первая операция

.

 #te [op=find; b=; le=; n=; c=;]

Эта операция сканирует часть текстового массива начиная с индекса [b] и c длиной [le]. Здесь и далее, для краткости, пишется имя параметра, но вместо указанного имени параметра имеется в виду его значение. Операция определяет все положения символа, юникод которого равен [c]. Результат в виде индексов массива t() записывается в целый массив i() начиная с первого индекса, равного значению [n]. Число повторений этого знака возвращается в параметр s(1).
Вторая операция

.

 #te [op=repl; b=; le=; c=; mo=;]

Эта операция сканирует часть текстового массива начиная с индекса [b] и с длиной [le]. Она заменяет все символы с юникодом [c] на юникод [mo]. Отмечу, что первые 127 уникодов равны ASCII кодам.
Третья операция

.

 #te [op=trim; b=; le=; n=;]

Эта операция сканирует часть текстового массива начиная с индекса [b] и с длиной [le]. Она находит части текста, окруженные пробелами, и их координаты записывает в целый массив i(). Если таких частей несколько, то возвращаются все. Результат анализа записывается в целый массив i() начиная с первого индекса [n]. Пусть [n=k;]. Тогда i(k) будет равно первому элементу первого куска, что может быть использовано как значение параметра [b], и i(k+1) будет равно длине этого куска, что может быть использовано для задания параметра [le]. Если существует два куска, то i(k+2) будет равно началу второго куска, а i(k+3) длине второго куска. Полное число кусков показывает параметр s(1).
4-я операция

.

 #te [op=show; b=; le=;] FT

Эта операция полностью аналогична команде #f [op=edit; file=here; mo=-1; c=1, ...]. Она показывает часть текстового массива, начиная с индекса [b] и с длиной [le] в редакторе текста без возможности его редактировать. Эту команду можно использовать как более простую запись команды #f. Все детали можно посмотреть в описании указанной команды. Так параметр s(1) в начале задает стартовую позицию курсора, а в конце возвращает позицию курсора перед выходом из редактора. Имя окна редактора указывает аргумент команды -- форматированный текст.
5-я операция

.

 #te [op=edit; b=; le=;] FT

Эта операция полностью аналогична команде #f [op=edit; file=here; mo=-2; c=1; ...]. Она показывает часть текстового массива, начиная с индекса [b] и с длиной [le] в редакторе с возможностью отредактировать текст. Эту команду можно использовать как более простую запись команды #f. Все детали можно посмотреть в описании указанной команды. Так параметр s(1) в начале задает стартовую позицию курсора, а в конце возвращает позицию курсора перед выходом из редактора. Имя окна редактора указывает аргумент команды - форматированный текст. Отредактированный текст будет снова записан в текстовый массив, начиная с индекса, указанного параметром s(3). Как обычно, после записи параметры s(4) и s(5) указывают начало и длину проведенной записи.
6-я операция

.

 #te [op=tail; b=; le=;]

Эта операция сканирует часть текстового массива начиная с индекса [b] и длиной [le] и изменяет значение параметра [le] таким образом, что символы пробелов на конце, а также символы '\n' или '\r' отсекаются. При этом [le] = s(10) либо остается прежним либо уменьшается.
7-я операция

.

 #te [op=fitt; b=; le=; n=; c=; tw=;]

Эта операция сканирует часть текстового массива начиная с индекса [b] и c длиной [le]. Операция определяет все положения заданной последовательности символов, аналогично операции find, но в данном случае строка юникодов, которая ищется начинается с индекса [c] и имеет [tw] символов. Результат в виде индексов массива t() записывается в целый массив i() начиная с первого индекса, равного значению [n]. Число повторений этого знака возвращается в параметр s(1).
8-я операция

.

 #te [op=emls;] FT 

Эта операция имеет специальное значение. Она не работает с текстовым массивом, но использует его весьма существенно. По этой причине я отнес ее к этой команде. Она отправляет письмо по электронной почте через любые почтовые серверы интернета. Естественно, что без интернета она не работает. У нее нет параметров, но зато есть очень сложный аргумент. Этот аргумент содержит 10 полей, разделенных символом вертикальной черты. Последнее, десятое поле -- это текст письма, которое будет отправлено. А первые 9 содержат необходимую информацию для работы команды. Фактически это ядро почтовой машины рассылки писем по электронной почте. Пример использования команды с данной операцией находится в программе emls1.acl в папке pro. Там можно посмотреть что означают первые 9 полей. Эта программа является первой, где эта команда успешно используется.

Есть еще одна команда, которая работает с текстовым массивом, а именно #read или короче #rea

.

 #rea [fir=; n=; b=; le=;]

Эта команда в определенном смысле обратная команде #print. Она позволяет получить числа из их текстового представления. Она работает подобно команде #io [op=rf; ], но читает текст из текстового массива t(), а не из файла. Параметр [fir] определяет, как обычно, тип и первый элемент числового массива, в который будут записаны числа, [n] задает сколько чисел должно быть прочитано, [b] определяет индекс первого элемента текстового массива t(), и [le] определяет длину части текстового массива, из которой будут прочитаны числа методом сканирования. Длина обычно известна из процедуры записи чисел. Например, команда #print сообщает об этом через параметры s(4) и s(5). По этой причине часть программы

 #print \G a b c;\E
 #read [fir=i(1); n=3; b=s(4); le=s(5);]

полностью эквивалентна коду

 # i(1)=a; i(2)=b; i(3)=c;

Эту команду удобно использовать в комбинации с командой #input (см. выше), так как она позволяет получить численные значения из окон ввода динамически. Размер реально просканированной области текстового массива t() после получения всех чисел возвращается в параметре s(1). Он может быть меньше заказанного. С другой стороны, число реально прочитанных чисел при сканировании всей заказанной области равно s(2)-1. Когда текст содержит и слова и числа можно использовать команды #te [op=trim;] и далее #read только для частей с числами. Все, что при этом необходимо знать -- это структуру записи.