(*~\Глагол\Отделы\Поле\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                            ОТДЕЛ Холст;
(*============================================================================* 
 * НАЗНАЧЕНИЕ: надел для работы с текстом (подобие ФАР-редактора).
 *   Часть холста, которая ограничена рамкой, выводится на экран.
 * Текст хранится построчно в виде связки (двусвязного списка) строк.
 * Строка состоит из ряда знаков <цепь>. Местоположение на холсте
 *   определяется точкой с порядковым номером строки <с> и колонки <к>.
 * При изменении текста все связанные с холстом точки соответственно сдвигаются.
 * Такими точками являются вешки, границы выделенного куска текста и указка
 *   ввода.
 * 
 * Разделители строк в запоминаемых кусках текста:
 *   0DX - для простого куска
 *   0AX - для вертикального куска
 *============================================================================*)

ИСПОЛЬЗУЕТ
        (*  \Глагол\                    *)
  ИзФайла ИЗ "..\..\Отделы\Обмен\ВводВывод\",
   ВФайл  ИЗ "..\..\Отделы\Обмен\ВводВывод\",
        (*  \Глагол\                    *)
 оЦепи    ИЗ "..\..\Отделы\Иное\",
 оБуквы   ИЗ "..\..\Отделы\Иное\",
 оЗнака   ИЗ "..\..\Отделы\Иное\",
        (*            \Глагол\              *)
  Надел             ИЗ "..\..\Отделы\Поле\",
  Памятка           ИЗ "..\..\Отделы\Поле\",
  ПолеПамятки       ИЗ "..\..\Отделы\Поле\",
  ПолеСВосклицанием ИЗ "..\..\Отделы\Поле\",
  ПолеЗамена        ИЗ "..\..\Отделы\Поле\",
  Поле              ИЗ "..\..\Отделы\Поле\",
        (*  \Глагол\              *)
  ОС      ИЗ "..\..\Отделы\Обмен\",
  ЦвЗнак  ИЗ "..\..\Отделы\Обмен\",
  Окно    ИЗ "..\..\Отделы\Обмен\",
  Текст   ИЗ "..\..\Отделы\Обмен\",
  Файл    ИЗ "..\..\Отделы\Обмен\",
  Ввод    ИЗ "..\..\Отделы\Обмен\";

ПОСТ
                                     (* последняя колонка холста (степень 2) *)
   ПК    = 1024; 
                                     (* приращение отступа строки (степень 2) *)
  Отступ = 2;   
                              (* цвета для раскраски текста на рус. ЯП Глагол *)
  цветРазделитель     = 1BX;
  цветСлово           = 1FX;
  цветЦепочка         = 1EX;
  цветЗнак            = 13X;
  цветПояснение       = 13X;
  цветВложПояснение   = 17X;
  цветВыход           = 1DX;
  цветОбход           = 1EX;
  цветОбщедост        = 1AX;
  цветТексторез       = 1EX;

ВИД
                                        (* текст хранится построчно на холсте *)
  РядЗнаковСтрокиХолста = РЯД ПК+1 ИЗ ЗНАК;

  ДкЗвенуСтрока = ДОСТУП К нЗвеноСтрока;
                           нЗвеноСтрока =
  НАБОР                            (* двусвязное звено цепочки *)
    преД,
    слеД:ДкЗвенуСтрока; (* связка строк (из рядов знаков) - двусвязных звеньев в цепочке *)

       цепь:РядЗнаковСтрокиХолста;
         пк:ЦЕЛ;                   (* последняя занятая колонка *)
    уровень:ЦЕЛ;                   (* уровень пояснений для начала строки *)
  КОН;

                 (*-- "нТочка" - местоположение на холсте --*)
  нТочка- = НАБОР
    с+,к+:ЦЕЛ;                    (* строка, колонка *)
  КОН;
                 (*-- "нОтметка" - отмеченный кусок на холсте --*)
  нОтметка = НАБОР
    перв,посл:Холст.нТочка;       (* граница отметки *)
          нач:Холст.нТочка;       (* начальная точка *)
    существует  :КЛЮЧ;
    изменяемая  :КЛЮЧ;
    вертикальная:КЛЮЧ;
  КОН;
                 (*-- "нВешка" - быстрый возврат указки на холсте --*)
  нВешка = НАБОР
    указка:Холст.нТочка;
     рамка:Холст.нТочка           (* угол рамки относительно указки *)
  КОН;
                 (*-- в "нЗнаки" удаляемые знаки хранятся рядами --*)
ПОСТ          
    размерРядаЗнаков = 2048;      (* степень 2-х   *)
  последнийРядЗнаков = 99;        (* 2*100 = 200Кб *)

ВИД
  ДкРядуЗнаков = ДОСТУП К РЯД размерРядаЗнаков ИЗ ЗНАК;

  нЗнаки = НАБОР
    рДкРядуЗнаков:РЯД последнийРядЗнаков+1 ИЗ ДкРядуЗнаков; (* = ДОСТУП К РЯД размерРядаЗнаков ИЗ ЗНАК; *)

    последнийРяд:ЦЕЛ;             (* последний используемый ряд *)
    чПоз,
    пПоз:ЦЕЛ;                     (* позиции чтения и писания (записи) *)
  КОН;

 (*--------------------------------------------------------------------
    виды - ПОСТоянные, ДОСТУПы и НАБОРы для отмены изменений на Холсте
  *--------------------------------------------------------------------*)

              (*-- род Отмены изменений, род # 0 --*)
ПОСТ
  отменаВставитьЗнак           = 1;
  отменаЗаменитьЗнак           = 2;
  отменаУдалитьЗнак            = 3;
  отменаУдалитьЗнакСлева       = 4;
  отменаНоваяСтрока            = 5;
  отменаУдалитьСтроку          = 6;
  отменаУдалитьДоКонцаСтроки   = 7;
  отменаУдалитьОтметку         = 8;
  отменаПереписатьЗнакиВОтметку= 9;
  отменаСдвинутьВправо         =10;
  отменаСдвинутьВлево          =11;
  отменаЗаменить               =12;

              (*-- "нОтмена" - набор 'отмена изменений' в строке знаков на холсте --*)
ВИД
  нОтмена = НАБОР
    родОтмены:ЦЕЛ;          (* отменаВставитьЗнак и др.    *)
     рамка:Холст.нТочка;    (* начало видимой части холста *)
    указка:Холст.нТочка;    (* текущая точка ввода         *)         
    чПоз:ЦЕЛ;               (* позиция чтения удалённых знаков *)
  КОН;
              (*-- отмены изменений хранятся рядами доступов к ряду из нОтмена -----*)
ПОСТ
    размерРядаОтмен = 1024; (* степень 2 *)
  последнийРядОтмен = 99;   (* ~100000 Отмен *)

ВИД
  ДкРядуОтмен = ДОСТУП К РЯД размерРядаОтмен ИЗ нОтмена;

              (*-- в "нОтмены" отмены изменений хранятся рядами доступов к ряду из нОтмена -----*)

  нОтмены = НАБОР
    рДкРядуОтмен:РЯД последнийРядОтмен+1 ИЗ ДкРядуОтмен; (* = ДОСТУП К РЯД размерРядаОтмен ИЗ нОтмена; *)

    последнийРяд:ЦЕЛ;       (* последний используемый ряд *)
    поз:ЦЕЛ;                (* ххх.отмена.поз - позиция чтения отменяемого знака *)
  КОН;

              (* жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж *)
              (*-- Холст.Вид - это цепной список из строк-звеньев --*)
              (* жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж *)

  Доступ- = ДОСТУП К Вид;     (* Холст.Доступ <- Надел.Доступ <- Рамка.Доступ *)

                     Вид- =   (* Холст.Вид    <- Надел.Вид    <- Рамка.Вид    *)
  НАБОР (Надел.Вид)        
       перваяСтрокаД:ДкЗвенуСтрока; (* начало связки строк-звеньев  *)
    последняяСтрокаД:ДкЗвенуСтрока; (* конец связки строк-звеньев   *)
      текущаяСтрокаД:ДкЗвенуСтрока; (* строка с указкой             *)
      верхняяСтрокаД:ДкЗвенуСтрока; (* верхняя видимая строка-звено *)

     рамка:Холст.нТочка;    (* начало видимой части холста *)
    указка:Холст.нТочка;    (* текущая точка ввода *)
    замена:КЛЮЧ;            (* будет замена или вставка букв *)
    пкр,пср:ЦЕЛ;            (* последняя колонка и строка рамки *)
    пс:ЦЕЛ;                 (* последняя строка холста *)
    отметка:нОтметка;       (* текущий отмеченный кусок текста *)
    вешка:РЯД 10 ИЗ нВешка; (* иначе говоря вешка - это закладка *)
    отмены:нОтмены;         (* хранилище описателей отмен *)
     знаки:нЗнаки;          (* хранилище сохраняемых знаков отмен *)
    началоОтмен:ЦЕЛ;        (* род начала объединения отмен *)
    продолжениеОтмен:ЦЕЛ;   (* род продолжения объединения отмен *)
    цветОбычный:ЗНАК;       (* обычный цвет *)
    цветОтметки:ЗНАК;       (* цвет отметки *)
                                                 (* для многострочного холста *)
    имяФ-:Файл.ВПолного;    (* полное имя файла *)
    имя- :Файл.ВИмени;      (* краткое имя *)
    изменён-:ЗНАК;          (* признак изменения текста после его сохранения *)
    отменыПоз:ЦЕЛ;          (* позиция отмены после сохранения текста *)
                                                 (* для однострочного холста *)
    однаСтрока:КЛЮЧ; 
    памяткаД:Памятка.Доступ;
  КОН;

ВИД
                            (* посылка для поля *)
  нПосылка- = НАБОР(Ввод.нПосылка)
    холстД-:Холст.Доступ;
  КОН;
                            (* поиск образца *)
  нПоиск- = НАБОР
    образец+:РядЗнаковСтрокиХолста;
    замена+ :РядЗнаковСтрокиХолста;
    заменить+     :КЛЮЧ;    (* нужна замена образца *)
    заглавные+    :КЛЮЧ;    (* учитываются заглавные буквы *)
    целые+        :КЛЮЧ;    (* только целые слова *)
    обратный+     :КЛЮЧ;    (* обратный просмотр *)
    подтверждение+:КЛЮЧ;    (* подтверждение замены *)
    отмеченная+   :КЛЮЧ;    (* в отмеченной области *)
    отУказки+     :КЛЮЧ;    (* начинаем от указки, а не от границы *)

    смещение:РЯД ВЦЕЛ(МАКС(ЗНАК))+1 ИЗ ЦЕЛ;(* смещение поиска при НЕсовпадении
                                               знаков в алгоритме Боуера-Мура *)
    длинаОбразца:ЦЕЛ;       (* длина образца *)
    длинаЗамены:ЦЕЛ;        (* длина замены *)
    точка:Холст.нТочка;     (* начало образца на холсте *)
    отметка:КЛЮЧ;           (* необходимо подсветить образец в строке *)
    нашли:КЛЮЧ;             (* работает во время поиска *)
    строкаД:ДкЗвенуСтрока;  (* работает во время поиска *)
    замен:ЦЕЛ;              (* всего произведено замен *)
  КОН;

ПЕР
  поиск+:Холст.нПоиск;      (* общедоступный набор <Холст.поиск> *)


(*-оооооооооооооо- опережающие определения/заготовки задач -ооооооооооооооооо-*)


(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА^ ОчиститьОтметку(отметка+:нОтметка);
ЗАДАЧА^(*(Холст.Вид)*)ДобавитьОтмену(холстД:Холст.Доступ; отмена-:нОтмена); (* отмена изменений *)
ЗАДАЧА^(*(Холст.Вид)*)ПрочитатьОтмену(холстД:Холст.Доступ; отмена+:нОтмена);(* отмена изменений *)
ЗАДАЧА^(*(Холст.Вид)*)ЗаписатьОтмену(холстД:Холст.Доступ; отмена-:нОтмена); (* отмена изменений *)

ЗАДАЧА^(*(Холст.Вид)*)ПосылкаИзменения(холстД:Холст.Доступ);

(*-------------------------------------общедоступная ЗАДАЧА-------------------*)
ЗАДАЧА^                                                          (*(Холст.Вид)*)
        ЗагрузитьСтрокуИзЦепи-(холстД:Холст.Доступ; цепь-:ЦЕПЬ);
(*
 * Цель:  загрузка из цепочки <цепь> текущей строки
 *)


(*=рррррррррррррррррррррррр= реализация задач =рррррррррррррррррррррррррррррр=*)


(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ОграничитьЦел(ц+,от,до:ЦЕЛ);
УКАЗ
  ЕСЛИ ц < от ТО ц:=от КОН;
  ЕСЛИ ц > до ТО ц:=до КОН
КОН ОграничитьЦел;


(*============================================================================* 
 * работа с двусвязными звеньями - строками на холсте - локальные задачи
 *============================================================================*)

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                         (*(Холст.нЗвеноСтрока) двусвязное звено цепочки *)
       ПредыдущаяСтрока(строкаД:ДкЗвенуСтрока;
                  смещение:ЦЕЛ):ДкЗвенуСтрока;
УКАЗ
  ПОКА смещение > 0 ВЫП
          строкаД:=строкаД.преД;
    УМЕНЬШИТЬ(смещение)
  КОН;
  ВОЗВРАТ строкаД
КОН ПредыдущаяСтрока;
(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                         (*(Холст.нЗвеноСтрока) двусвязное звено цепочки *)
       СледующаяСтрока(строкаД:ДкЗвенуСтрока;
                 смещение:ЦЕЛ):ДкЗвенуСтрока;
УКАЗ
  ПОКА смещение > 0 ВЫП
          строкаД:=строкаД.слеД;
    УМЕНЬШИТЬ(смещение)
  КОН;
  ВОЗВРАТ строкаД
КОН СледующаяСтрока;
(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                         (*(Холст.нЗвеноСтрока) двусвязное звено цепочки *)
       СоседняяСтрока(строкаД:ДкЗвенуСтрока;
                смещение:ЦЕЛ):ДкЗвенуСтрока;
УКАЗ
  ЕСЛИ смещение < 0 ТО
    ВОЗВРАТ ПредыдущаяСтрока(строкаД,-смещение)
  ИНАЧЕ
    ВОЗВРАТ  СледующаяСтрока(строкаД,смещение)
  КОН
КОН СоседняяСтрока;
(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                         (*(Холст.нЗвеноСтрока) двусвязное звено цепочки *)
       УбратьПробелы(строкаД:ДкЗвенуСтрока);
(*
 * удалить конечные пробелы из строки
 *)
УКАЗ
  ПОКА (строкаД.пк >= 0)
      И
       (строкаД.цепь[строкаД.пк] = ' ')
  ВЫП
    УМЕНЬШИТЬ(строкаД.пк)
  КОН
КОН УбратьПробелы;
(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                         (*(Холст.нЗвеноСтрока) двусвязное звено цепочки *)
       ДобавитьПробелы(строкаД:ДкЗвенуСтрока; к:ЦЕЛ);
УКАЗ
  ПОКА строкаД.пк < к ВЫП
    УВЕЛИЧИТЬ(строкаД.пк);
    строкаД.цепь[строкаД.пк]:=' '
  КОН
КОН ДобавитьПробелы;
(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                         (*(Холст.нЗвеноСтрока) двусвязное звено цепочки *)
       РаскраситьСтроку(строкаД:ДкЗвенуСтрока;
                         цвета+:РядЗнаковСтрокиХолста):ЦЕЛ;
(*
 * Цель:  раскрашивает строку в соответствии с правилами Глагола [Glagol.hrc]
 * До:    <строкаД> - данная строка
 * После: <цвета>   - цвет каждого знака из <строкаД.цепь>
 * Ответ: уровень пояснений в конце строки
 *)
ПОСТ
                                    (* предельная длина служебного слова *)
  длинаСлова = 14;
                                    (* виды раскрашиваемых областей *)
  облСлово      = 0;
  облОкончание  = 1;
  облПояснение  = 2;
  облТексторез  = 3;
  облЦепочка    = 4;
  облЗнаков     = 5;
  облРазделитель= 6;

ПЕР
  к:ЦЕЛ;                            (* колонка *)
  кс:ЦЕЛ;                           (* начальная колонка слова *)
  пк:ЦЕЛ;                           (* последняя колонка строки *)
  слово:РЯД длинаСлова+1 ИЗ ЗНАК;
  длина:ЦЕЛ;                        (* длина слова *)
  знак:ЗНАК;                        (* обрабатываемый знак *)
  цвет:ЗНАК;                        (* цвет знака *)
  уровень:ЦЕЛ;                      (* уровень вложенности пояснений *)
  область:ЦЕЛ;                      (* текущая область раскраски *)
  кавычка:ЗНАК;                     (* закрывающая кавычка цепочки *)
  цифра:ЦЕЛ;                        (* номер цифры в знаке "#nnnn" *)

 (*.......................подЗадача..*)
  ЗАДАЧА ЧитатьЗнакИзСтроки;        (* Цель:  читать из строки следующий знак *)
  УКАЗ
    ЕСЛИ к <= пк ТО
      цвета[к]:=цвет
    КОН;

    УВЕЛИЧИТЬ(к);

    ЕСЛИ к <= пк ТО
      знак:=строкаД.цепь[к]
    ИНАЧЕ
      знак:=0X
    КОН
  КОН ЧитатьЗнакИзСтроки;

УКАЗ
  к:=0;
  пк:=строкаД.пк;
  знак:=строкаД.цепь[0];
  уровень:=строкаД.уровень;
  ЕСЛИ
       уровень = 0
  ТО
    область:=облРазделитель;
    цвет:=цветРазделитель
  АЕСЛИ
       уровень = 1
  ТО
    область:=облПояснение;
    цвет:=цветПояснение
  ИНАЧЕ
    область:=облПояснение;
    цвет:=цветВложПояснение
  КОН;
                                                      (* разбор знаков строки *)
  ПОКА к <= пк+1 ВЫП
    ВЫБРАТЬ область ИЗ
    | облРазделитель:           (* область Разделитель *)
      ВЫБРАТЬ знак ИЗ
      | "'",'"':
        область:=облЦепочка;
        цвет:=цветЦепочка;
        кавычка:=знак;
        ЧитатьЗнакИзСтроки               (* подЗадача *)
      | "(":
        ЧитатьЗнакИзСтроки;              (* подЗадача *)
        ЕСЛИ знак = "*" ТО
          область:=облПояснение;
          уровень:=1;
          цвет:=цветПояснение;
          цвета[к-1]:=цвет;
          ЧитатьЗнакИзСтроки             (* подЗадача *)
        КОН
      | "<":
        ЧитатьЗнакИзСтроки;              (* подЗадача *)
        ЕСЛИ знак = "*" ТО
          ЧитатьЗнакИзСтроки;            (* подЗадача *)
          цвета[к-2]:=цветТексторез;
          цвета[к-1]:=цветТексторез
        КОН
      | "*":
        ЧитатьЗнакИзСтроки;              (* подЗадача *)
        ЕСЛИ знак = ">" ТО
          ЧитатьЗнакИзСтроки;            (* подЗадача *)
          цвета[к-2]:=цветТексторез;
          цвета[к-1]:=цветТексторез
        КОН
      ИНАЧЕ
        ЕСЛИ оБуквы.Известная(знак) ИЛИ (знак = "_") ТО
          область:=облСлово;
          длина:=0;
          кс:=к
        ИНАЧЕ
          ЧитатьЗнакИзСтроки             (* подЗадача *)
        КОН
      КОН
    | облЦепочка:               (* область Цепочки *)
      ЕСЛИ знак = кавычка ТО
        ЧитатьЗнакИзСтроки;              (* подЗадача *)
        область:=облРазделитель;
        цвет:=цветРазделитель
      АЕСЛИ знак = "##" ТО
        ЧитатьЗнакИзСтроки;              (* подЗадача *)
        ЕСЛИ знак = "##" ТО
          ЧитатьЗнакИзСтроки;            (* подЗадача *)
          цвета[к-1]:=цветЗнак;
          цвета[к-2]:=цветЗнак
        ИНАЧЕ
          область:=облЗнаков;
          цифра:=1
        КОН
      ИНАЧЕ
        ЧитатьЗнакИзСтроки               (* подЗадача *)
      КОН
    | облЗнаков:                (* область Знаков *)
      ЕСЛИ
            оЗнака.Цифра(знак)
          ИЛИ
           ("A" <= знак) И (знак <= "F")
      ТО
        ЧитатьЗнакИзСтроки;              (* подЗадача *)
        УВЕЛИЧИТЬ(цифра);
        ЕСЛИ цифра = 5 ТО
          ПОКА цифра > 0 ВЫП
            цвета[к-цифра]:=цветЗнак;
            УМЕНЬШИТЬ(цифра)
          КОН;
          область:=облЦепочка
        КОН
      ИНАЧЕ                                      (* ошибочное окончание знака *)
        область:=облЦепочка
      КОН
    | облПояснение:             (* область Пояснение *)
      ЕСЛИ знак = "*" ТО
        ЧитатьЗнакИзСтроки;              (* подЗадача *)
        ЕСЛИ знак = ")" ТО
          ЧитатьЗнакИзСтроки;            (* подЗадача *)
          УМЕНЬШИТЬ(уровень);
          ЕСЛИ уровень = 1 ТО
            цвет:=цветПояснение
          АЕСЛИ уровень = 0 ТО
            область:=облРазделитель;
            цвет:=цветРазделитель
          КОН
        КОН
      АЕСЛИ знак = "(" ТО
        ЧитатьЗнакИзСтроки;              (* подЗадача *)
        ЕСЛИ знак = "*" ТО
          УВЕЛИЧИТЬ(уровень);
          цвет:=цветВложПояснение;
          цвета[к-1]:=цвет;
          ЧитатьЗнакИзСтроки             (* подЗадача *)
        КОН
      ИНАЧЕ
        ЧитатьЗнакИзСтроки               (* подЗадача *)
      КОН
    | облСлово:                   (* область Слово *)
      ЕСЛИ
           НЕ оЗнака.ВСлове(знак)
      ТО
        слово[длина]:=0X;
                                                         (* слово служебное ? *)
        ВЫБРАТЬ слово[0] ИЗ
        | "А": ЕСЛИ (слово = "АЕСЛИ"     ) ТО цвет:=цветСлово КОН
        | "Б": ЕСЛИ (слово = "БЕГУНОК"   ) ТО цвет:=цветСлово КОН
        | "В": ЕСЛИ (слово = "ВЫП"       )    
                ИЛИ (слово = "ВИД"       )    
                ИЛИ (слово = "ВЫБРАТЬ"   )
                ИЛИ (слово = "В"         )      
                ИЛИ (слово = "ВЕЩ"       )      
                ИЛИ (слово = "ВКЛ"       )      
                ИЛИ (слово = "ВЗНАК"     )      
                ИЛИ (слово = "ВЦЕЛ"      )      
                ИЛИ (слово = "ВШИРЦЕЛ"   )      
                ИЛИ (слово = "ВИДА"      ) ТО цвет:=цветСлово 
              АЕСЛИ (слово = "ВОЗВРАТ"   )
                ИЛИ (слово = "ВЫЗОВ"     )
                ИЛИ (слово = "ВЫХОД"     ) ТО цвет:=цветВыход КОН
        | "Д": ЕСЛИ (слово = "ДОСТУП"    ) 
                ИЛИ (слово = "ДЕЛИТЬ"    ) 
                ИЛИ (слово = "ДЛЯ"       )    
                ИЛИ (слово = "ДЛИНА"     )    
                ИЛИ (слово = "ДО"        ) ТО цвет:=цветСлово КОН
        | "Е": ЕСЛИ (слово = "ЕСЛИ"      ) ТО цвет:=цветСлово КОН
        | "З": ЕСЛИ (слово = "ЗАДАЧА"    )
                ИЛИ (слово = "ЗНАК"      )
                ИЛИ (слово = "ЗАДАНО"    ) ТО цвет:=цветСлово КОН      
        | "И": ЕСЛИ (слово = "ИНАЧЕ"     )     
                ИЛИ (слово = "И"         )         
                ИЛИ (слово = "ИЛИ"       )       
                ИЛИ (слово = "ИЗ"        )        
                ИЛИ (слово = "ИСПОЛЬЗУЕТ") ТО цвет:=цветСлово КОН
        | "К": ЕСЛИ (слово = "КОН"       )       
                ИЛИ (слово = "К"         )         
                ИЛИ (слово = "КОЛЬЦО"    )    
                ИЛИ (слово = "КЛЮЧ"      )    
                ИЛИ (слово = "КОД"       ) ТО цвет:=цветСлово КОН
        | "М": ЕСЛИ (слово = "МНОЖ"      )
                ИЛИ (слово = "МАКС"      )
                ИЛИ (слово = "МИН"       )
                ИЛИ (слово = "МОДУЛЬ"    ) ТО цвет:=цветСлово КОН
        | "Н": ЕСЛИ (слово = "НАБОР"     )     
                ИЛИ (слово = "НЕ"        ) ТО цвет:=цветСлово КОН
        | "О": ЕСЛИ (слово = "ОТ"        )        
                ИЛИ (слово = "ОСТАТОК"   )   
                ИЛИ (слово = "ОТКЛ"      )   
                ИЛИ (слово = "ОБНУЛИТЬ"  )   
                ИЛИ (слово = "ОТДЕЛ"     ) ТО цвет:=цветСлово КОН;
               ЕСЛИ (слово = "ОБХОД"     ) ТО
                 ЕСЛИ знак = "." ТО длина:=0 ИНАЧЕ цвет:=цветОбход КОН
               КОН
        | "П": ЕСЛИ (слово = "ПЕР"       )       
                ИЛИ (слово = "ПУСТО"     )     
                ИЛИ (слово = "ПОКА"      )      
                ИЛИ (слово = "ПОВТОРЯТЬ" ) 
                ИЛИ (слово = "ПО"        )        
                ИЛИ (слово = "ПОСТАВИТЬ" )        
                ИЛИ (слово = "ПРОВЕРИТЬ" )        
                ИЛИ (слово = "ПОСТ"      ) ТО цвет:=цветСлово КОН
        | "Р": ЕСЛИ (слово = "РЯД"       )
                ИЛИ (слово = "РАЗМЕР"    ) ТО цвет:=цветСлово КОН
        | "С": ЕСЛИ (слово = "СМЕСТИТЬ"  )
                ИЛИ (слово = "СЖАТЫЙ"    )        
                ИЛИ (слово = "СОЗДАТЬ"   )        
                ИЛИ (слово = "СТОП"      )        
                ИЛИ (слово = "СПИСАТЬ"   ) ТО цвет:=цветСлово КОН
        | "Т": ЕСЛИ (слово = "ТО"        ) ТО цвет:=цветСлово КОН
        | "У": ЕСЛИ (слово = "УКАЗ"      )
                ИЛИ (слово = "УВЕЛИЧИТЬ" )        
                ИЛИ (слово = "УЗК"       )        
                ИЛИ (слово = "УЗКЦЕЛ"    )        
                ИЛИ (слово = "УМЕНЬШИТЬ" ) ТО цвет:=цветСлово КОН
        | "Ш": ЕСЛИ (слово = "ШИРЦЕЛ"    )
                ИЛИ (слово = "ШИРВЕЩ"    ) ТО цвет:=цветСлово КОН
        | "Ц": ЕСЛИ (слово = "ЦЕПЬ"      )
                ИЛИ (слово = "ЦЕЛЧАСТЬ"  )        
                ИЛИ (слово = "ЦЕЛ"       ) ТО цвет:=цветСлово КОН
        | "Ч": ЕСЛИ (слово = "ЧЕТ"       ) ТО цвет:=цветСлово КОН
        | "Я": ЕСЛИ (слово = "ЯВЛЯЕТСЯ"  )
                ИЛИ (слово = "ЯЧЦЕЛ"     ) ТО цвет:=цветСлово КОН
        ИНАЧЕ
             ЕСЛИ слово[0] = "." ТО
               ЕСЛИ (слово = ".Адрес"    )
                ИЛИ (слово = ".ПолучитьАдрес")      
                ИЛИ (слово = ".ВПамять"  )      
                ИЛИ (слово = ".Доступ"   ) 
                ИЛИ (слово = ".Значение" )
                ИЛИ (слово = ".ИзПамяти" )        
                ИЛИ (слово = ".Образ"    )   
                ИЛИ (слово = ".Цел8"     )
                ИЛИ (слово = ".Цел16"    )
                ИЛИ (слово = ".Цел32"    )
                ИЛИ (слово = ".Цел64"    )
                ИЛИ (слово = ".Вещ32"    )      
                ИЛИ (слово = ".Вещ64"    )      
                ИЛИ (слово = ".Ячейка"   )
                ИЛИ (слово = ".Ячейки"   ) ТО цвет:=цветОбход КОН
             КОН
        КОН;
                                             (* перекрашиваем служебное слово *)
        ЕСЛИ
             цвет # цветРазделитель
        ТО
          ПОКА кс < к ВЫП
            цвета[кс]:=цвет;
            УВЕЛИЧИТЬ(кс)
          КОН;
          область:=облРазделитель;
          цвет:=цветРазделитель
        АЕСЛИ
             длина = 0
        ТО                          (* ОБХОД *)
          слово[0]:=знак; (* "." *)
          длина:=1;
          ЧитатьЗнакИзСтроки             (* подЗадача *)
        ИНАЧЕ
          область:=облОкончание
        КОН
      АЕСЛИ
           длина >= длинаСлова
      ТО
        область:=облОкончание
      ИНАЧЕ                                              (* продолжение слова *)
        слово[длина]:=знак;
        УВЕЛИЧИТЬ(длина);
        ЧитатьЗнакИзСтроки               (* подЗадача *)
      КОН
    | облОкончание:               (* область Окончание *)
      ЕСЛИ
           НЕ оЗнака.ВСлове(знак)
      ТО                                           (* общедоступное понятие ? *)
        ЕСЛИ (знак = "+")
            ИЛИ
             (знак = "-")
        ТО
          ЧитатьЗнакИзСтроки;            (* подЗадача *)
          ЕСЛИ
               (знак = ":")
              ИЛИ
               (знак = ";")
              ИЛИ 
               (знак = "=")
              ИЛИ
               (знак = ",")
              ИЛИ
               (знак = "(")
          ТО
            ПОКА кс < к ВЫП
              цвета[кс]:=цветОбщедост;
              УВЕЛИЧИТЬ(кс)
            КОН
          КОН
        КОН;
        область:=облРазделитель
      ИНАЧЕ
        ЧитатьЗнакИзСтроки               (* подЗадача *)
      КОН
    КОН
  КОН;
  ВОЗВРАТ уровень
КОН РаскраситьСтроку;
(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                         (*(Холст.нЗвеноСтрока) двусвязное звено цепочки *)
       УровеньКонцаСтроки(строкаД:ДкЗвенуСтрока):ЦЕЛ;
(*
 * Цель:  вычислить уровень пояснений в конце данной строки
 *)
ПЕР
  цвета:РядЗнаковСтрокиХолста;
УКАЗ
  ВОЗВРАТ РаскраситьСтроку(строкаД,цвета)
КОН УровеньКонцаСтроки;
(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                         (*(Холст.нЗвеноСтрока) двусвязное звено цепочки *)
       ВыставитьУровеньСтрок(строкаД:ДкЗвенуСтрока; уровень:ЦЕЛ);
(*
 * Цель:  исправить уровень пояснений данной и всех последующих строк 
 * До:    <уровень> - новый уровень
 *)
УКАЗ
  ПОКА
       (строкаД # ПУСТО)
      И
       (уровень # строкаД.уровень)
  ВЫП
    строкаД.уровень:=уровень;
    уровень:=УровеньКонцаСтроки(строкаД);
    строкаД:=строкаД.слеД
  КОН
КОН ВыставитьУровеньСтрок;
(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                         (*(Холст.нЗвеноСтрока) двусвязное звено цепочки *)
       НовыйУровеньСтрок(строкаД:ДкЗвенуСтрока);
(*
 * Цель:  исправить уровень пояснений всех последующих строк
 *)
УКАЗ
  ЕСЛИ строкаД # ПУСТО ТО
    ВыставитьУровеньСтрок(строкаД.слеД,УровеньКонцаСтроки(строкаД))
  КОН
КОН НовыйУровеньСтрок;


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

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                         (*(Холст.нЗнаки)*)
       ОчиститьЗнаки(знаки+:нЗнаки);
ПЕР
  ряд:ЦЕЛ;
УКАЗ
  ОТ ряд:=0 ДО последнийРядЗнаков ВЫП
    знаки.рДкРядуЗнаков[ряд]:=ПУСТО
  КОН;
    знаки.последнийРяд:=-1;
    знаки.чПоз:=0;
    знаки.пПоз:=0
КОН ОчиститьЗнаки;
(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                         (*(Холст.нЗнаки)*)
       ЗнакВЗнаки(знаки+:нЗнаки; знак:ЗНАК);
ПЕР
  ряд:ЦЕЛ;
УКАЗ
         ряд:=знаки.пПоз ДЕЛИТЬ размерРядаЗнаков;
  ЕСЛИ
         ряд > знаки.последнийРяд
  ТО
    ЕСЛИ 
         ряд >       последнийРядЗнаков
    ТО
      ВОЗВРАТ
    КОН;
             знаки.последнийРяд:=ряд;
     СОЗДАТЬ(знаки.рДкРядуЗнаков[ряд])
  КОН;
             знаки.рДкРядуЗнаков[ряд][знаки.пПоз ОСТАТОК размерРядаЗнаков]:=знак;
   УВЕЛИЧИТЬ(знаки.пПоз)
КОН ЗнакВЗнаки;
(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                         (*(Холст.нЗнаки)*)
       ЗнакИзЗнаков(знаки+:нЗнаки):ЗНАК;
ПЕР
  знак:ЗНАК;
УКАЗ
  ЕСЛИ
       знаки.чПоз >= (знаки.последнийРяд+1)*размерРядаЗнаков
  ТО
    ВОЗВРАТ 0X
  КОН;
  знак:=знаки.рДкРядуЗнаков[знаки.чПоз ДЕЛИТЬ  размерРядаЗнаков]
                           [знаки.чПоз ОСТАТОК размерРядаЗнаков];
  УВЕЛИЧИТЬ(знаки.чПоз);
  ВОЗВРАТ знак
КОН ЗнакИзЗнаков;


(*============================================================================* 
 * разное - локальные задачи
 *============================================================================*)

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       РамкаПоУказке(холстД:Холст.Доступ);
ПЕР
       строк,колонок,смещение:ЦЕЛ;
УКАЗ
       строк:=холстД.указка.с-холстД.рамка.с;
  ЕСЛИ
       строк > холстД.пср
  ТО
    смещение:=строк-холстД.пср
  АЕСЛИ
       строк < 0
  ТО
    смещение:=строк
  ИНАЧЕ
    смещение:=0
  КОН;
  УВЕЛИЧИТЬ(холстД.рамка.с,смещение);

  холстД.верхняяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,
                                         холстД.рамка.с);
       колонок:=холстД.указка.к-холстД.рамка.к;
  ЕСЛИ
       колонок > холстД.пкр
  ТО
    смещение:=колонок-холстД.пкр
  АЕСЛИ
       колонок < 0
  ТО
    смещение:=колонок
  ИНАЧЕ
    смещение:=0
  КОН;
  УВЕЛИЧИТЬ(холстД.рамка.к,смещение)
КОН РамкаПоУказке;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ПоставитьУказку(холстД:Холст.Доступ; с,к:ЦЕЛ);
УКАЗ
  холстД.указка.с:=с;
  холстД.указка.к:=к;
  холстД.текущаяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,с);
  РамкаПоУказке(холстД)
КОН ПоставитьУказку;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ПереместитьУказкуНаХолсте(холстД:Холст.Доступ);
УКАЗ
  Окно.ПереместитьУказку(холстД.вс+холстД.указка.с-холстД.рамка.с,
                         холстД.лк+холстД.указка.к-холстД.рамка.к)
КОН ПереместитьУказкуНаХолсте;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       РазмерУказкиНаХолсте(холстД:Холст.Доступ);
УКАЗ
  ЕСЛИ
       холстД.замена
  ТО
    Окно.РазмерУказки(100)
  ИНАЧЕ
    Окно.РазмерУказки(15)
  КОН
КОН РазмерУказкиНаХолсте;


(*============================================================================* 
 * изменение указанного текста - локальные задачи
 *============================================================================*)

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       УдалитьЗнак(холстД:Холст.Доступ);
ПЕР
  строкаД:ДкЗвенуСтрока;
  к,пк,
  вешка :ЦЕЛ;

 (*...............................................подЗадача...*)
  ЗАДАЧА ПравуюТочкуВлево(точка+,опора-:Холст.нТочка);
  УКАЗ
    ЕСЛИ (точка.с = опора.с) И (точка.к >= опора.к) ТО
      УМЕНЬШИТЬ(точка.к)
    КОН
  КОН ПравуюТочкуВлево;

УКАЗ
  строкаД:=холстД.текущаяСтрокаД;
  к:=холстД.указка.к;
  пк:=строкаД.пк;
  ПОКА к < пк ВЫП
    строкаД.цепь[к]:=строкаД.цепь[к+1];
    УВЕЛИЧИТЬ(к)
  КОН;
  УМЕНЬШИТЬ(строкаД.пк);
                                                          (* исправляем точки *)
  ОТ вешка:=0 ДО 9 ВЫП
    ПравуюТочкуВлево(холстД.вешка[вешка].указка,холстД.указка)(* подЗадача *)
  КОН;
  ЕСЛИ
       НЕ холстД.отметка.вертикальная
  ТО
    ПравуюТочкуВлево(холстД.отметка.перв,холстД.указка);      (* подЗадача *)
    ПравуюТочкуВлево(холстД.отметка.посл,холстД.указка);      (* подЗадача *)
    ПравуюТочкуВлево(холстД.отметка.нач, холстД.указка)       (* подЗадача *) 
  КОН
КОН УдалитьЗнак;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ВставитьЗнак(холстД:Холст.Доступ;
                      знак:ЗНАК);
ПЕР
  строкаД:ДкЗвенуСтрока;
  к,пк,
  вешка :ЦЕЛ;

 (*...................................................подЗадача...*)
  ЗАДАЧА ПравуюТочкуВправо(точка+,опора-:Холст.нТочка);
  УКАЗ
    ЕСЛИ (точка.с = опора.с) И (точка.к >= опора.к) ТО
      УВЕЛИЧИТЬ(точка.к)
    КОН
  КОН ПравуюТочкуВправо;

УКАЗ
  строкаД:=холстД.текущаяСтрокаД;
  к:=холстД.указка.к;
  ДобавитьПробелы(строкаД,к-1);

       пк:=строкаД.пк;
  ПОКА пк >= к ВЫП
    строкаД.цепь[пк+1]:=строкаД.цепь[пк];
    УМЕНЬШИТЬ(пк)
  КОН;
  УВЕЛИЧИТЬ(строкаД.пк);
  строкаД.цепь[к]:=знак;
                                                          (* исправляем точки *)
  ОТ вешка:=0 ДО 9 ВЫП
    ПравуюТочкуВправо(холстД.вешка[вешка].указка,холстД.указка)(* подЗадача *)
  КОН;
  ЕСЛИ
       НЕ холстД.отметка.вертикальная
  ТО
    ПравуюТочкуВправо(холстД.отметка.перв,холстД.указка);      (* подЗадача *)
    ПравуюТочкуВправо(холстД.отметка.посл,холстД.указка);      (* подЗадача *)
    ПравуюТочкуВправо(холстД.отметка.нач, холстД.указка)       (* подЗадача *)
  КОН
КОН ВставитьЗнак;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       УдалитьСтроку(холстД:Холст.Доступ);
ПЕР
      строкаД:ДкЗвенуСтрока;
  следСтрокаД:ДкЗвенуСтрока;
        вешка:ЦЕЛ;

 (*..................................................подЗадача...*)
  ЗАДАЧА НижнююТочкуВверх(точка+,опора-:Холст.нТочка);
  УКАЗ
    ЕСЛИ  точка.с = опора.с ТО
          точка.к:=-1;
    АЕСЛИ точка.с > опора.с ТО
      УМЕНЬШИТЬ(точка.с)
    КОН
  КОН НижнююТочкуВверх;
 (*......................................................подЗадача...*)
  ЗАДАЧА НижнююТочкуВверхВерт(точка+,опора-:Холст.нТочка);
  УКАЗ
    ЕСЛИ точка.с >= опора.с ТО
      УМЕНЬШИТЬ(точка.с)
    КОН
  КОН НижнююТочкуВверхВерт;

УКАЗ
           строкаД:=холстД.текущаяСтрокаД;
       следСтрокаД:=строкаД.слеД;
  ЕСЛИ
       следСтрокаД # ПУСТО
  ТО
       следСтрокаД.уровень:=строкаД.уровень
  КОН;
    холстД.текущаяСтрокаД:=следСтрокаД;
  ЕСЛИ
       строкаД = холстД.перваяСтрокаД
  ТО
    холстД.перваяСтрокаД:=следСтрокаД
  ИНАЧЕ  
    строкаД.преД.слеД:=следСтрокаД
  КОН;
  ЕСЛИ
       строкаД = холстД.последняяСтрокаД
  ТО
    холстД.последняяСтрокаД:=строкаД.преД
  ИНАЧЕ  
    строкаД.слеД.преД:=строкаД.преД
  КОН;
  ЕСЛИ
       строкаД = холстД.верхняяСтрокаД
  ТО
    холстД.верхняяСтрокаД:=следСтрокаД
  КОН;
  УМЕНЬШИТЬ(холстД.пс);
                                                          (* исправляем точки *)
  ОТ вешка:=0 ДО 9 ВЫП
    НижнююТочкуВверх(холстД.вешка[вешка].указка,холстД.указка) (* подЗадача *)
  КОН;
  ЕСЛИ 
       холстД.отметка.вертикальная
  ТО
    НижнююТочкуВверхВерт(холстД.отметка.перв,холстД.указка);   (* подЗадача *)
    НижнююТочкуВверхВерт(холстД.отметка.посл,холстД.указка);   (* подЗадача *)
    НижнююТочкуВверхВерт(холстД.отметка.нач, холстД.указка)    (* подЗадача *)
  ИНАЧЕ
    НижнююТочкуВверх(холстД.отметка.перв,холстД.указка);       (* подЗадача *)
    НижнююТочкуВверх(холстД.отметка.посл,холстД.указка);       (* подЗадача *)
    НижнююТочкуВверх(холстД.отметка.нач, холстД.указка)        (* подЗадача *)
  КОН
КОН УдалитьСтроку;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ВставитьСтроку( холстД:Холст.Доступ;
                      строкаД:ДкЗвенуСтрока);
(*
 * Вставляет строку перед текущей строкой
 *)
ПЕР
  следСтрокаД:ДкЗвенуСтрока;
        вешка:ЦЕЛ;

 (*.................................................подЗадача...*)
  ЗАДАЧА НижнююТочкуВниз(точка+,опора-:Холст.нТочка);
  УКАЗ
    ЕСЛИ точка.с >= опора.с ТО
      УВЕЛИЧИТЬ(точка.с)
    КОН
  КОН НижнююТочкуВниз;

УКАЗ
                следСтрокаД:=холстД.текущаяСтрокаД;
  строкаД.слеД:=следСтрокаД;
  строкаД.преД:=следСтрокаД.преД;
  ЕСЛИ
                следСтрокаД = холстД.перваяСтрокаД
  ТО
      холстД.перваяСтрокаД:=строкаД
  ИНАЧЕ
               следСтрокаД.преД.слеД:=строкаД
  КОН;
               следСтрокаД.преД:=строкаД;
  УВЕЛИЧИТЬ(холстД.пс);
                                                          (* исправляем точки *)
  ОТ вешка:=0 ДО 9 ВЫП
    НижнююТочкуВниз(холстД.вешка[вешка].указка,холстД.указка)  (* подЗадача *)
  КОН;
  НижнююТочкуВниз(холстД.отметка.перв,холстД.указка);          (* подЗадача *)
  НижнююТочкуВниз(холстД.отметка.посл,холстД.указка);          (* подЗадача *)
  НижнююТочкуВниз(холстД.отметка.нач, холстД.указка)           (* подЗадача *)
КОН ВставитьСтроку;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       СклеитьСтроку(холстД:Холст.Доступ);
ПЕР
      строкаД:ДкЗвенуСтрока;
  следСтрокаД:ДкЗвенуСтрока;
      к,вешка:ЦЕЛ;

 (*..................................................подЗадача...*)
  ЗАДАЧА НижнююТочкуВверх(точка+,опора-:Холст.нТочка);
  УКАЗ
    ЕСЛИ точка.с > опора.с ТО
      УМЕНЬШИТЬ(точка.с);
      ЕСЛИ точка.с = опора.с ТО
        УВЕЛИЧИТЬ(точка.к,опора.к)
      КОН
    КОН
  КОН НижнююТочкуВверх;
 (*......................................................подЗадача...*)
  ЗАДАЧА НижнююТочкуВверхВерт(точка+,опора-:Холст.нТочка);
  УКАЗ
    ЕСЛИ точка.с > опора.с ТО
      УМЕНЬШИТЬ(точка.с)
    КОН
  КОН НижнююТочкуВверхВерт;

УКАЗ
      строкаД:=холстД.текущаяСтрокаД;
  следСтрокаД:=строкаД.слеД;
  к:=0;
  ПОКА (строкаД.пк < ПК) И (к <= следСтрокаД.пк) ВЫП
    УВЕЛИЧИТЬ(строкаД.пк);
    строкаД.цепь[строкаД.пк]:=следСтрокаД.цепь[к];
    УВЕЛИЧИТЬ(к)
  КОН;
       строкаД.слеД:=следСтрокаД.слеД;
  ЕСЛИ
       следСтрокаД = холстД.последняяСтрокаД
  ТО
    холстД.последняяСтрокаД:=строкаД
  ИНАЧЕ
    следСтрокаД.слеД.преД:=строкаД
  КОН;
  УМЕНЬШИТЬ(холстД.пс);
                                                          (* исправляем точки *)
  ОТ вешка:=0 ДО 9 ВЫП
    НижнююТочкуВверх(холстД.вешка[вешка].указка,холстД.указка) (* подЗадача *)
  КОН;
  ЕСЛИ
       холстД.отметка.вертикальная
  ТО
    НижнююТочкуВверхВерт(холстД.отметка.перв,холстД.указка);   (* подЗадача *)
    НижнююТочкуВверхВерт(холстД.отметка.посл,холстД.указка);   (* подЗадача *)
    НижнююТочкуВверхВерт(холстД.отметка.нач, холстД.указка)    (* подЗадача *)
  ИНАЧЕ
    НижнююТочкуВверх(холстД.отметка.перв,холстД.указка);       (* подЗадача *)
    НижнююТочкуВверх(холстД.отметка.посл,холстД.указка);       (* подЗадача *)
    НижнююТочкуВверх(холстД.отметка.нач, холстД.указка)        (* подЗадача *)
  КОН
КОН СклеитьСтроку;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       РазделитьСтроку(холстД:Холст.Доступ);
ПЕР
      строкаД:ДкЗвенуСтрока;
  следСтрокаД:ДкЗвенуСтрока;                                       
       к,пк,
       вешка :ЦЕЛ;

 (*.................................................подЗадача...*)
  ЗАДАЧА НижнююТочкуВниз(точка+,опора-:Холст.нТочка);
  УКАЗ
    ЕСЛИ точка.с > опора.с ТО
      УВЕЛИЧИТЬ(точка.с)
    АЕСЛИ (точка.с = опора.с) И (точка.к >= опора.к) ТО
      УВЕЛИЧИТЬ(точка.с);
      УМЕНЬШИТЬ(точка.к,опора.к)
    КОН
  КОН НижнююТочкуВниз;
 (*.....................................................подЗадача...*)
  ЗАДАЧА НижнююТочкуВнизВерт(точка+,опора-:Холст.нТочка);
  УКАЗ
    ЕСЛИ точка.с > опора.с ТО
      УВЕЛИЧИТЬ(точка.с)
    АЕСЛИ (точка.с = опора.с) И (точка.к >= опора.к) ТО
      УВЕЛИЧИТЬ(точка.с)
    КОН
  КОН НижнююТочкуВнизВерт;

УКАЗ
  строкаД:=холстД.текущаяСтрокаД;
  к:=холстД.указка.к;
  пк:=строкаД.пк;
  СОЗДАТЬ(следСтрокаД);
  следСтрокаД.преД:=строкаД;
  следСтрокаД.слеД:=строкаД.слеД;
  ЕСЛИ
       строкаД = холстД.последняяСтрокаД
  ТО
    холстД.последняяСтрокаД:=следСтрокаД
  ИНАЧЕ
    строкаД.слеД.преД:=следСтрокаД
  КОН;
    строкаД.слеД:=следСтрокаД;
                  следСтрокаД.пк:=-1;
  ПОКА к <= пк ВЫП
    УВЕЛИЧИТЬ(следСтрокаД.пк);
    следСтрокаД.цепь[следСтрокаД.пк]:=строкаД.цепь[к];
    УВЕЛИЧИТЬ(к)
  КОН;
  УМЕНЬШИТЬ(строкаД.пк,следСтрокаД.пк+1);
  УВЕЛИЧИТЬ(холстД.пс);
                                     (* исправляем точки *)
  ОТ вешка:=0 ДО 9 ВЫП
    НижнююТочкуВниз(холстД.вешка[вешка].указка,холстД.указка)  (* подЗадача *)
  КОН;
  ЕСЛИ
       холстД.отметка.вертикальная
  ТО
    НижнююТочкуВнизВерт(холстД.отметка.перв,холстД.указка);    (* подЗадача *)
    НижнююТочкуВнизВерт(холстД.отметка.посл,холстД.указка);    (* подЗадача *)
    НижнююТочкуВнизВерт(холстД.отметка.нач, холстД.указка)     (* подЗадача *)
  ИНАЧЕ
    НижнююТочкуВниз(холстД.отметка.перв,холстД.указка);        (* подЗадача *)
    НижнююТочкуВниз(холстД.отметка.посл,холстД.указка);        (* подЗадача *)
    НижнююТочкуВниз(холстД.отметка.нач, холстД.указка)         (* подЗадача *)
  КОН
КОН РазделитьСтроку;


(*============================================================================* 
 * отметка куска
 *============================================================================*)

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА
       ВнутриОтметки(отметка-:нОтметка;
                       точка-:Холст.нТочка):КЛЮЧ;
ПЕР
  место:ЦЕЛ;
УКАЗ
  ЕСЛИ отметка.вертикальная ТО
    ЕСЛИ
         (точка.с >= отметка.перв.с)
        И 
         (точка.к >= отметка.перв.к) 
        И 
         (точка.с <= отметка.посл.с)
        И 
         (точка.к <= отметка.посл.к)
    ТО
      ВОЗВРАТ ВКЛ
    КОН
  ИНАЧЕ
          место:=точка.с*ПК+точка.к;
    ЕСЛИ
         (место >= отметка.перв.с*ПК+отметка.перв.к)
        И 
         (место <= отметка.посл.с*ПК+отметка.посл.к)
    ТО
      ВОЗВРАТ ВКЛ
    КОН
  КОН;
  ВОЗВРАТ ОТКЛ
КОН ВнутриОтметки;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА
       ИзменитьОтметку(отметка+:нОтметка;
                           с,к :ЦЕЛ);
УКАЗ
  ЕСЛИ отметка.вертикальная ТО
    ЕСЛИ
         отметка.нач.с > с
    ТО
         отметка.перв.с:=с;
         отметка.посл.с:=отметка.нач.с
    ИНАЧЕ
         отметка.перв.с:=отметка.нач.с;
         отметка.посл.с:=с
    КОН;
    ЕСЛИ
         отметка.нач.к > к
    ТО
         отметка.перв.к:=к;
         отметка.посл.к:=отметка.нач.к-1
    ИНАЧЕ
         отметка.перв.к:=отметка.нач.к;
         отметка.посл.к:=к-1
    КОН
  ИНАЧЕ
    ЕСЛИ
         отметка.нач.с*ПК+отметка.нач.к > с*ПК+к
    ТО
         отметка.перв.с:=с;
         отметка.перв.к:=к;
         отметка.посл.с:=отметка.нач.с;
         отметка.посл.к:=отметка.нач.к-1
    ИНАЧЕ
         отметка.перв.с:=отметка.нач.с;
         отметка.перв.к:=отметка.нач.к;
         отметка.посл.с:=с;
         отметка.посл.к:=к-1
    КОН
  КОН;
  ЕСЛИ
       (отметка.перв.с < 0)
      ИЛИ
       (отметка.перв.к > отметка.посл.к)
      И
       (отметка.вертикальная ИЛИ (отметка.перв.с = отметка.посл.с))
   ТО
    отметка.существует:=ОТКЛ
  ИНАЧЕ
    отметка.существует:=ВКЛ
  КОН
КОН ИзменитьОтметку;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА
       ОчиститьОтметку(отметка+:нОтметка);
УКАЗ
  отметка.существует:=ОТКЛ;
  отметка.изменяемая:=ОТКЛ;
  отметка.вертикальная:=ОТКЛ;
  отметка.нач.с:=-1;
  отметка.нач.к:=-1;

  ИзменитьОтметку(отметка,-1,-1)

КОН ОчиститьОтметку;
(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА
       НачалоОтметки(     отметка+:нОтметка;
                     вертикальная :КЛЮЧ;
                              с,к :ЦЕЛ);
УКАЗ
  отметка.изменяемая:=ВКЛ;
  отметка.вертикальная:=вертикальная;
  отметка.нач.с:=с;
  отметка.нач.к:=к;
  ИзменитьОтметку(отметка,с,к)
КОН НачалоОтметки;


(*============================================================================* 
 * работа с отмеченным куском
 *============================================================================*)

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ОтметкуВЗнаки(холстД:Холст.Доступ);
ПЕР
          с,к:ЦЕЛ;
  первк,послк,
  первс,послс:ЦЕЛ;      (* граница отметки *)
  строкаД:ДкЗвенуСтрока;
УКАЗ
  первс:=холстД.отметка.перв.с;
  послс:=холстД.отметка.посл.с;
  первк:=холстД.отметка.перв.к;
  послк:=холстД.отметка.посл.к;

  строкаД:=СледующаяСтрока(холстД.перваяСтрокаД,первс);

       холстД.знаки.чПоз:=холстД.знаки.пПоз;
  ЕСЛИ
       холстД.отметка.вертикальная
  ТО
    ОТ с:=первс ДО послс ВЫП
      к:=первк;
      ПОКА   к <= послк ВЫП
        ЕСЛИ
             к <= строкаД.пк
        ТО
          ЗнакВЗнаки(холстД.знаки,строкаД.цепь[к])
        ИНАЧЕ
          ЗнакВЗнаки(холстД.знаки," ")
        КОН;
        УВЕЛИЧИТЬ(к)
      КОН;
      ЕСЛИ
           с # послс
      ТО
        ЗнакВЗнаки(холстД.знаки,0AX);
        строкаД:=строкаД.слеД
      КОН
    КОН
  ИНАЧЕ
    к:=первк;
    ОТ с:=первс ДО послс ВЫП
      ЕСЛИ
           с # послс
      ТО
        ПОКА к <= строкаД.пк ВЫП
          ЗнакВЗнаки(холстД.знаки,строкаД.цепь[к]);
          УВЕЛИЧИТЬ(к)
        КОН;
        ЗнакВЗнаки(холстД.знаки,0DX);
        строкаД:=строкаД.слеД;
        к:=0
      ИНАЧЕ
        ПОКА (к <= послк) И (к <= строкаД.пк) ВЫП
          ЗнакВЗнаки(холстД.знаки,строкаД.цепь[к]);
          УВЕЛИЧИТЬ(к)
        КОН
      КОН
    КОН
  КОН;
  ЗнакВЗнаки(холстД.знаки,0X)
КОН ОтметкуВЗнаки;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ЗнакиВОтметку(холстД:Холст.Доступ);
(*
 * Записывает знаки в текущее положение указки
 * Приходится явно исправлять уровень пояснений, т.к. при отмене указка
 * может находится и в невидимой области холста
 *)
ПЕР
     знак:ЗНАК;
  к,ус,ук,
  пк,чПоз,
    длина,
    вешка:ЦЕЛ;
  строкаД:ДкЗвенуСтрока;
  уровень:ЦЕЛ;

 (*...........................................................подЗадача...*)
  ЗАДАЧА ПравуюТочкуВправо(точка+:Холст.нТочка; с,к,длина:ЦЕЛ);
  УКАЗ
    ЕСЛИ (точка.с = с) И (точка.к >= к) ТО
      УВЕЛИЧИТЬ(точка.к,длина)
    КОН
  КОН ПравуюТочкуВправо;

УКАЗ
  строкаД:=холстД.текущаяСтрокаД;
  ус:=холстД.указка.с;
  ук:=холстД.указка.к;
                          (* узнаём длину 1-й строки и вертикальность отметки *)
  чПоз:=холстД.знаки.чПоз;
  длина:=0;
  знак:=ЗнакИзЗнаков(холстД.знаки);
  ПОКА знак >= " " ВЫП
    знак:=ЗнакИзЗнаков(холстД.знаки);
    УВЕЛИЧИТЬ(длина)
  КОН;
  холстД.знаки.чПоз:=чПоз;
  ЕСЛИ
       знак = 0AX
  ТО                                               (* для вертикального куска *)
    НачалоОтметки(холстД.отметка,ВКЛ,ус,ук);
    знак:=ЗнакИзЗнаков(холстД.знаки);
    ПОКА знак # 0X ВЫП
      ДобавитьПробелы(строкаД,ук-1);
      пк:=строкаД.пк;
                                       (* раздвигаем при необходимости строку *)
      ЕСЛИ пк+длина > ПК ТО      (* ! было бы правильнее отменить эту вставку *)
        длина:=ПК-пк
      КОН;
      к:=пк;
      ПОКА к >= ук ВЫП
        строкаД.цепь[к+длина]:=строкаД.цепь[к];
        УМЕНЬШИТЬ(к)
      КОН;
      УВЕЛИЧИТЬ(строкаД.пк,длина);
                                                          (* исправляем точки *)
      ОТ вешка:=0 ДО 9 ВЫП
        ПравуюТочкуВправо(холстД.вешка[вешка].указка,
                                                  ус,
                                                  ук,
                                               длина)            (* подЗадача *)
      КОН;
                                                   (* считываем строку знаков *)
      к:=ук;
      пк:=ук+длина;
      ПОКА знак >= " " ВЫП
        ЕСЛИ
             к <= пк
        ТО
          строкаД.цепь[к]:=знак;
        КОН;
        УВЕЛИЧИТЬ(к);
        знак:=ЗнакИзЗнаков(холстД.знаки)
      КОН;
                                                          (* следующая строка *)
      ЕСЛИ знак # 0X ТО
        ЕСЛИ
               строкаД # холстД.последняяСтрокаД
        ТО
          уровень:=УровеньКонцаСтроки(строкаД);
          строкаД:=строкаД.слеД;
          ЕСЛИ
               строкаД # ПУСТО
          ТО
               строкаД.уровень:=уровень
          КОН;
          УВЕЛИЧИТЬ(ус);
          знак:=ЗнакИзЗнаков(холстД.знаки)
        ИНАЧЕ                    (* ! было бы правильнее отменить эту вставку *)
          знак:=0X
        КОН
      КОН
    КОН;
    НовыйУровеньСтрок(строкаД);
    ИзменитьОтметку(холстД.отметка,ус,ук+длина)
  ИНАЧЕ                                                 (* для простого куска *)
    ДобавитьПробелы(строкаД,ук-1);
    РазделитьСтроку(холстД);
      НачалоОтметки(холстД.отметка,ОТКЛ,ус,ук);

              холстД.текущаяСтрокаД:=строкаД.слеД;
    УВЕЛИЧИТЬ(холстД.указка.с);
    знак:=ЗнакИзЗнаков(холстД.знаки);

    ПОКА
          знак # 0X
    ВЫП
                                                   (* считываем строку знаков *)
      ПОКА (знак >= " ") И (строкаД.пк < ПК) ВЫП
        УВЕЛИЧИТЬ(строкаД.пк);
        строкаД.цепь[строкаД.пк]:=знак;
        знак:=ЗнакИзЗнаков(холстД.знаки)
      КОН;
                                                          (* следующая строка *)
      ЕСЛИ
          знак # 0X
      ТО
        уровень:=УровеньКонцаСтроки(строкаД);
        СОЗДАТЬ(строкаД);
        строкаД.пк:=-1;
        строкаД.уровень:=уровень;
        ВставитьСтроку(холстД,строкаД);
        УВЕЛИЧИТЬ(холстД.указка.с);
        знак:=ЗнакИзЗнаков(холстД.знаки)
      КОН
    КОН;
    УМЕНЬШИТЬ(холстД.указка.с);
    холстД.указка.к:=строкаД.пк+1;
    холстД.текущаяСтрокаД:=строкаД;
    СклеитьСтроку(холстД);
    НовыйУровеньСтрок(строкаД);
    РамкаПоУказке(холстД);
    ИзменитьОтметку(холстД.отметка,холстД.указка.с,холстД.указка.к)
  КОН
КОН ЗнакиВОтметку;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       СтеретьОтметку(холстД:Холст.Доступ);
(*
 * приходится явно исправлять уровень пояснений, т.к. отметка
 * может находится и в невидимой области холста
 *)
ПЕР
  с,к,вешка,
  уровень   :ЦЕЛ;

  первк,послк,
  первс,послс,
  перв, посл:ЦЕЛ;    (* граница отметки *)

  строкаД,
  первСтрока,
  послСтрока:ДкЗвенуСтрока;

 (*.............................................подЗадача...*)
  ЗАДАЧА СтеретьКолонки(строкаД:ДкЗвенуСтрока;
                         первк,
                         послк :ЦЕЛ);
  ПЕР
    пк:ЦЕЛ;
  УКАЗ
    пк:=строкаД.пк;
    ЕСЛИ первк <= пк ТО
      ЕСЛИ послк >= пк ТО
        строкаД.пк:=первк-1
      ИНАЧЕ
        УВЕЛИЧИТЬ(послк);
        УМЕНЬШИТЬ(строкаД.пк,послк-первк);
        ПОКА послк <= пк ВЫП
          строкаД.цепь[первк]:=строкаД.цепь[послк];
          УВЕЛИЧИТЬ(первк);
          УВЕЛИЧИТЬ(послк)
        КОН
      КОН
    КОН
  КОН СтеретьКолонки;
 (*.............................................подЗадача...*)
  ЗАДАЧА ПравуюТочкуВлево(точка+:Холст.нТочка);
  УКАЗ
    ЕСЛИ (точка.с >= первс)
        И
         (точка.с <= послс)
        И
         (точка.к >= первк)
    ТО
      ЕСЛИ точка.к <= послк ТО
        точка.к:=первк
      ИНАЧЕ
        УМЕНЬШИТЬ(точка.к,послк-первк+1)
      КОН
    КОН
  КОН ПравуюТочкуВлево;
 (*.............................................подЗадача...*)
  ЗАДАЧА НижнююТочкуВверх(точка+:Холст.нТочка);
  ПЕР
    т:ЦЕЛ;
  УКАЗ
    т:=точка.с*ПК+точка.к;
    ЕСЛИ т >= перв ТО
      ЕСЛИ т <= посл ТО
        точка.с:=первс;
        точка.к:=первк
      ИНАЧЕ
          УМЕНЬШИТЬ(точка.с,послс-первс);
        ЕСЛИ точка.с = первс ТО
          УМЕНЬШИТЬ(точка.к,послк-первк+1)
        КОН
      КОН
    КОН
  КОН НижнююТочкуВверх;

УКАЗ
  первс:=холстД.отметка.перв.с;
  послс:=холстД.отметка.посл.с;
  первк:=холстД.отметка.перв.к;
  послк:=холстД.отметка.посл.к;

  ЕСЛИ 
         холстД.отметка.вертикальная
      ИЛИ
       (первс = послс)
  ТО
    строкаД:=СледующаяСтрока(холстД.перваяСтрокаД,первс);
    ОТ с:=первс ДО послс ВЫП
      СтеретьКолонки(строкаД,первк,послк);                      (* подЗадача *)
      уровень:=УровеньКонцаСтроки(строкаД);
      строкаД:=строкаД.слеД;
      ЕСЛИ
           строкаД # ПУСТО
      ТО
        строкаД.уровень:=уровень
      КОН
    КОН;
    НовыйУровеньСтрок(строкаД);
                                                 (* исправляем точки и указку *)
    ОТ вешка:=0 ДО 9 ВЫП
      ПравуюТочкуВлево(холстД.вешка[вешка].указка)             (* подЗадача *)
    КОН;
      ПравуюТочкуВлево(холстД.указка)                          (* подЗадача *)

  ИНАЧЕ                                      (* простая многострочная отметка *)

    первСтрока:=СледующаяСтрока(холстД.перваяСтрокаД,первс);
    послСтрока:=СледующаяСтрока(холстД.перваяСтрокаД,послс);
                                               (* отрежем конец первой строки *)
    ДобавитьПробелы(первСтрока,первк-1);
    первСтрока.пк:=первк-1;
                                           (* отрежем начало последней строки *)
    СтеретьКолонки(послСтрока,0,послк);                        (* подЗадача *)
                                                 (* склеим полученные остатки *)    
          к:=0;
    ПОКА
         (первСтрока.пк < ПК)
        И
         (к <= послСтрока.пк)
    ВЫП
      УВЕЛИЧИТЬ(первСтрока.пк);
      первСтрока.цепь[первСтрока.пк]:=послСтрока.цепь[к];
      УВЕЛИЧИТЬ(к)
    КОН;
         первСтрока.слеД:=послСтрока.слеД;
    ЕСЛИ
         послСтрока = холстД.последняяСтрокаД
    ТО
      холстД.последняяСтрокаД:=первСтрока
    ИНАЧЕ
         послСтрока.слеД.преД:=первСтрока
    КОН;
    УМЕНЬШИТЬ(холстД.пс,послс-первс);
    НовыйУровеньСтрок(первСтрока);
                                                 (* исправляем точки и указку *)
    перв:=первс*ПК+первк;
    посл:=послс*ПК+послк;

    ОТ вешка:=0 ДО 9 ВЫП
      НижнююТочкуВверх(холстД.вешка[вешка].указка)             (* подЗадача *)
    КОН;
      НижнююТочкуВверх(холстД.указка);                         (* подЗадача *)
                                            (* восстанавливаем указку и рамку *)
    холстД.текущаяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,холстД.указка.с);
    РамкаПоУказке(холстД)
  КОН;
  ОчиститьОтметку(холстД.отметка)
КОН СтеретьОтметку;


(*============================================================================* 
 * отрисовка на экране - локальные задачи
 *============================================================================*)

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ОтрисовкаСтроки(холстД:Холст.Доступ;
                      строкаД:ДкЗвенуСтрока;
                         с,
                        лк,вс:ЦЕЛ);
(*
 * Цель:  отрисовка части строки
 * До:    
 *        <с>       - номер строки на холсте
 *        <лк>,<вс> - начало отображения строки на экране
 *)
ПЕР
     цвСтрока:ЦвЗнак.РядСтрока;
         цвет,
    общийЦвет:ЗНАК;
  первк,послк:ЦЕЛ;           (* граница отметки *)
  первс,послс:ЦЕЛ;           (* граница отметки *) 
           кр:ЦЕЛ;           (* колонка рамки *)
           пк:ЦЕЛ;           (* последняя колонка строки *)
            к:ЦЕЛ;           (* первая отображаемая колонка холста *)
          пкр:ЦЕЛ;           (* последняя колонка рамки *)
  обычнПробел,               (* пробел цвета обычного *)
  отметПробел:ЦвЗнак.Вид;    (* пробел цвета отметки  *)
        цвета:РядЗнаковСтрокиХолста;
  сРаскраской:КЛЮЧ;
      уровень:ЦЕЛ;

УКАЗ
  ЦвЗнак.ИзЗнакаИЦвета(" ",холстД.цветОбычный,обычнПробел);
  ЦвЗнак.ИзЗнакаИЦвета(" ",холстД.цветОтметки,отметПробел);

  уровень:=строкаД.уровень;
      пкр:=холстД.пкр;
    первс:=холстД.отметка.перв.с;
    послс:=холстД.отметка.посл.с;
                                             (* общий цвет *)
  ЕСЛИ холстД.однаСтрока ТО
    ЕСЛИ
        холстД.состояние = Надел.состОтключён
    ТО
      общийЦвет:=Надел.цветОтключённойСтроки
    ИНАЧЕ
      общийЦвет:=холстД.цветОбычный
    КОН;
    сРаскраской:=ОТКЛ
  ИНАЧЕ
    ЕСЛИ
         холстД.состояние = Надел.состОтключён
    ТО
      общийЦвет:=Надел.цветОтключённогоХолста;
      сРаскраской:=ОТКЛ
    ИНАЧЕ
      сРаскраской:=ВКЛ
    КОН
  КОН;
                    (* повторять для следующих строк при изменении примечаний *)
  ПОВТОРЯТЬ 
    ЕСЛИ
               Холст.поиск.отметка
    ТО
      ЕСЛИ
           с = Холст.поиск.точка.с
      ТО
        первк:=Холст.поиск.точка.к;
        послк:=первк+Холст.поиск.длинаОбразца-1
      ИНАЧЕ
        первк:=ПК+1
      КОН
    ИНАЧЕ                                  (* границы отметки *)
      ЕСЛИ
           холстД.отметка.вертикальная
      ТО
        ЕСЛИ  с < первс ТО
          первк:=ПК+1
        ИНАЧЕ
          первк:=холстД.отметка.перв.к
        КОН;
        ЕСЛИ  с <= послс ТО
          послк:=холстД.отметка.посл.к
        ИНАЧЕ
          послк:=-1
        КОН
      ИНАЧЕ
        ЕСЛИ  с < первс ТО
          первк:=ПК+1
        АЕСЛИ с = первс ТО
          первк:=холстД.отметка.перв.к
        ИНАЧЕ
          первк:=0
        КОН;
        ЕСЛИ  с < послс ТО
          послк:=ПК
        АЕСЛИ с = послс ТО
          послк:=холстД.отметка.посл.к
        ИНАЧЕ
          послк:=-1
        КОН
      КОН
    КОН;
                                                  (* заполнение строки вывода *)
    к:=холстД.рамка.к;
    пк:=строкаД.пк;
    кр:=0;
    ЕСЛИ
         сРаскраской
    ТО
      строкаД.уровень:=уровень;
      уровень:=РаскраситьСтроку(строкаД,цвета)
    КОН;
    ПОКА (к <= пк) И (кр <= пкр) ВЫП
      ЕСЛИ
           (к >= первк) И (к <= послк)
      ТО
        цвет:=холстД.цветОтметки
      АЕСЛИ
            сРаскраской
      ТО
        цвет:=цвета[к]
      ИНАЧЕ
        цвет:=общийЦвет
      КОН;
      ЦвЗнак.ИзЗнакаИЦвета(строкаД.цепь[к],цвет,цвСтрока[кр]);
      УВЕЛИЧИТЬ(к);
      УВЕЛИЧИТЬ(кр)
    КОН;
    ПОКА кр <= пкр ВЫП
      ЕСЛИ
           (к >= первк) И (к <= послк)
      ТО
        цвСтрока[кр]:=отметПробел
      ИНАЧЕ
        цвСтрока[кр]:=обычнПробел
      КОН;
      УВЕЛИЧИТЬ(к);
      УВЕЛИЧИТЬ(кр)
    КОН;
    Окно.ПисатьСтроку(цвСтрока,вс,лк,пкр+1);
    строкаД:=строкаД.слеД;
    УВЕЛИЧИТЬ(с);
    УВЕЛИЧИТЬ(вс);
  ДО
     (НЕ сРаскраской)
    ИЛИ
     (строкаД = ПУСТО)
    ИЛИ
     (уровень = строкаД.уровень)
    ИЛИ
     (вс > холстД.нс);

  ЕСЛИ
       сРаскраской
  ТО                 (* исправить уровень пояснений на невидимой части холста *)
    ВыставитьУровеньСтрок(строкаД,уровень)
  КОН
КОН ОтрисовкаСтроки;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ОтрисовкаТекущейСтроки(холстД:Холст.Доступ);
УКАЗ
  ОтрисовкаСтроки(холстД,
                  холстД.текущаяСтрокаД,
                  холстД.указка.с,
                  холстД.лк,
                  холстД.вс + холстД.указка.с - холстД.рамка.с
                 )
КОН ОтрисовкаТекущейСтроки;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ОтрисовкаНизаРамки(холстД:Холст.Доступ;
                         строкаД:ДкЗвенуСтрока;
                            с,ср:ЦЕЛ);
(*
 * Цель:  отрисовка содержимого низа рамки
 *)
ПЕР
     пробелы:ЦвЗнак.РядСтрока;
   цвПробел :ЦвЗнак.Вид;
  былПробел :КЛЮЧ;
          к :ЦЕЛ;
        пкр,
        пср :ЦЕЛ;
         лк,
         вс :ЦЕЛ;
УКАЗ
  былПробел:=ОТКЛ;
         лк:=холстД.лк;
         вс:=холстД.вс;
        пкр:=холстД.пкр;
        пср:=холстД.пср;
  ПОКА
       ср <= пср
  ВЫП
    ЕСЛИ
         строкаД # ПУСТО
    ТО
      ОтрисовкаСтроки(холстД,строкаД,с,лк,вс+ср);
      строкаД:=строкаД.слеД
    ИНАЧЕ
      ЕСЛИ
           НЕ былПробел
      ТО
        ЦвЗнак.ИзЗнакаИЦвета(" ",холстД.цветОбычный,цвПробел);
        ОТ к:=0 ДО пкр ВЫП
          пробелы[к]:=цвПробел
        КОН;
        былПробел:=ВКЛ
      КОН;
      Окно.ПисатьСтроку(пробелы,вс+ср,лк,пкр+1)
    КОН;
    УВЕЛИЧИТЬ(с);
    УВЕЛИЧИТЬ(ср)
  КОН
КОН ОтрисовкаНизаРамки;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ОтрисовкаРамки(холстД:Холст.Доступ);
(*
 * отрисовка содержимого рамки
 *)
УКАЗ
  ОтрисовкаНизаРамки(холстД,холстД.верхняяСтрокаД,холстД.рамка.с,0)
КОН ОтрисовкаРамки;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       Отрисовка(холстД:Холст.Доступ);
(*
 * отрисовка холста и указки
 *)
УКАЗ
       холстД.пкр:=холстД.пк-холстД.лк;
       холстД.пср:=холстД.нс-холстД.вс;
  ЕСЛИ
       холстД.состояние = Надел.состВыбран
  ТО
    РамкаПоУказке(холстД);
    РазмерУказкиНаХолсте(холстД);
    ПереместитьУказкуНаХолсте(холстД);
    ПосылкаИзменения(холстД)
  КОН;
  ОтрисовкаРамки(холстД)
КОН Отрисовка;


(*-оооооооооооооо- опережающие определения/заготовки задач -ооооооооооооооооо-*)

(*----------------------------------------------------------------------------* 
 * отработка действий человека - локальные задачи
 *----------------------------------------------------------------------------*)

ЗАДАЧА^ ДСтраницуВверх       (холстД:Холст.Доступ);
ЗАДАЧА^ ДСтраницуВниз        (холстД:Холст.Доступ);
ЗАДАЧА^ ДВКонецСтроки        (холстД:Холст.Доступ);
ЗАДАЧА^ ДВНачалоСтроки       (холстД:Холст.Доступ);
ЗАДАЧА^ ДЗнакВлевоСУпором    (холстД:Холст.Доступ);
ЗАДАЧА^ ДСтрокуВверх         (холстД:Холст.Доступ);
ЗАДАЧА^ ДПрокруткаВверх      (холстД:Холст.Доступ);
ЗАДАЧА^ ДЗнакВправо          (холстД:Холст.Доступ);
ЗАДАЧА^ ДСтрокуВниз          (холстД:Холст.Доступ);
ЗАДАЧА^ ДПрокруткаВниз       (холстД:Холст.Доступ);
ЗАДАЧА^ ДСменаЗамены         (холстД:Холст.Доступ);
ЗАДАЧА^ ДЗнакВлево           (холстД:Холст.Доступ);
ЗАДАЧА^ ДСловоВправо         (холстД:Холст.Доступ);
ЗАДАЧА^ ДСловоВлево          (холстД:Холст.Доступ);
ЗАДАЧА^ ДВНачалоХолста       (холстД:Холст.Доступ);
ЗАДАЧА^ ДВКонецХолста        (холстД:Холст.Доступ);
ЗАДАЧА^ ДВКонецХолста        (холстД:Холст.Доступ);
ЗАДАЧА^ ДВНачалоХолста       (холстД:Холст.Доступ);
ЗАДАЧА^ ДВНачалоРамки        (холстД:Холст.Доступ);
ЗАДАЧА^ ДВКонецРамки         (холстД:Холст.Доступ);
ЗАДАЧА^ ДЗаменитьЗнак        (холстД:Холст.Доступ; знак:ЗНАК);
ЗАДАЧА^ ДВставитьЗнак        (холстД:Холст.Доступ; знак:ЗНАК);
ЗАДАЧА^ ДУдалитьЗнак         (холстД:Холст.Доступ);
ЗАДАЧА^ ДУдалитьЗнакСлева    (холстД:Холст.Доступ);
ЗАДАЧА^ ДНоваяСтрока         (холстД:Холст.Доступ);
ЗАДАЧА^ ДУдалитьДоКонцаСтроки(холстД:Холст.Доступ);
ЗАДАЧА^ ДУдалитьСтроку       (холстД:Холст.Доступ);
ЗАДАЧА^ ДУдалитьСловоСлева   (холстД:Холст.Доступ);
ЗАДАЧА^ ДУдалитьСловоСправа  (холстД:Холст.Доступ);
ЗАДАЧА^ ДПереместитьУказку   (холстД:Холст.Доступ; кр,ср:ЦЕЛ);
ЗАДАЧА^ ДСнятьОтметку        (холстД:Холст.Доступ);
ЗАДАЧА^ ДОтметитьВсё         (холстД:Холст.Доступ);
ЗАДАЧА^ ДПеренестиОтметку    (холстД:Холст.Доступ);
ЗАДАЧА^ ДПереписатьОтметку   (холстД:Холст.Доступ);
ЗАДАЧА^ ДУдалитьОтметку      (холстД:Холст.Доступ);
ЗАДАЧА^ ДСдвинутьВправо      (холстД:Холст.Доступ);
ЗАДАЧА^ ДСдвинутьВлево       (холстД:Холст.Доступ);
ЗАДАЧА^ ДОтменить            (холстД:Холст.Доступ);


(*=рррррррррррррррррррррррр= реализация задач =рррррррррррррррррррррррррррррр=*)


(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДСтрокуВверх(холстД:Холст.Доступ);
ПЕР
  цвПробел:ЦвЗнак.Вид; 
УКАЗ
                                                  (* проверяем выход за холст *)
  ЕСЛИ
       холстД.указка.с = 0
  ТО
    ВОЗВРАТ
  КОН;
                                              (* передвигаем указку по холсту *)
  УМЕНЬШИТЬ(холстД.указка.с);
  холстД.текущаяСтрокаД:=холстД.текущаяСтрокаД.преД;
                            (* передвигаем рамку по холсту и указку по экрану *)
  ЕСЛИ холстД.указка.с < холстД.рамка.с ТО
    УМЕНЬШИТЬ(холстД.рамка.с);
    холстД.верхняяСтрокаД:=холстД.текущаяСтрокаД;
    ЦвЗнак.ИзЗнакаИЦвета(" ",холстД.цветОбычный,цвПробел);
    Окно.Вниз(холстД.вс,холстД.лк,холстД.нс,холстД.пк,цвПробел);
    ОтрисовкаСтроки(холстД,
                    холстД.верхняяСтрокаД,холстД.рамка.с,холстД.лк,холстД.вс)
  КОН;
  ПереместитьУказкуНаХолсте(холстД)
КОН ДСтрокуВверх;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДПрокруткаВверх(холстД:Холст.Доступ);
ПЕР
  цвПробел:ЦвЗнак.Вид; 
УКАЗ
                                                  (* проверяем выход за холст *)
  ЕСЛИ
       холстД.указка.с = 0
  ТО
    ВОЗВРАТ
  КОН;
                                              (* передвигаем указку по холсту *)
  УМЕНЬШИТЬ(холстД.указка.с);
       холстД.текущаяСтрокаД:=холстД.текущаяСтрокаД.преД;

                            (* передвигаем рамку по холсту и указку по экрану *)
  ЕСЛИ
       холстД.рамка.с > 0
  ТО
    УМЕНЬШИТЬ(холстД.рамка.с);
    холстД.верхняяСтрокаД:=холстД.верхняяСтрокаД.преД;
    ЦвЗнак.ИзЗнакаИЦвета(" ",холстД.цветОбычный,цвПробел);
    Окно.Вниз(холстД.вс,холстД.лк,холстД.нс,холстД.пк,цвПробел);
 
    ОтрисовкаСтроки(холстД,
                    холстД.верхняяСтрокаД,
                    холстД.рамка.с,
                    холстД.лк,
                    холстД.вс
                   )
  КОН;
  ПереместитьУказкуНаХолсте(холстД)
КОН ДПрокруткаВверх;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДСтраницуВверх(холстД:Холст.Доступ);
ПЕР
       смещение,остаток:ЦЕЛ;
УКАЗ
                                              (* передвигаем указку по холсту *)
       смещение:=холстД.пср;
  ЕСЛИ
       смещение > холстД.указка.с
  ТО
       смещение:=холстД.указка.с
  КОН;
  УМЕНЬШИТЬ(холстД.указка.с,смещение);
  холстД.текущаяСтрокаД:=ПредыдущаяСтрока(холстД.текущаяСтрокаД,смещение);
                                               (* передвигаем рамку по холсту *)
  остаток:=холстД.рамка.с;
  ЕСЛИ
       смещение > остаток
  ТО
       смещение:=остаток
  КОН;
  ЕСЛИ
       смещение > 0
  ТО
    УМЕНЬШИТЬ(холстД.рамка.с,смещение);
    холстД.верхняяСтрокаД:=ПредыдущаяСтрока(холстД.верхняяСтрокаД,смещение);
    ОтрисовкаРамки(холстД)
  КОН;
  ПереместитьУказкуНаХолсте(холстД)
КОН ДСтраницуВверх;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДСтраницуВниз(холстД:Холст.Доступ);
ПЕР
       смещение,остаток:ЦЕЛ;
УКАЗ
                                                      (* холст меньше рамки ? *)
  ЕСЛИ холстД.пс <= холстД.пср ТО
    ДВКонецХолста(холстД);
    ВОЗВРАТ
  КОН;
                                              (* передвигаем указку по холстДу *)
       смещение:=холстД.пср;
  ЕСЛИ
       смещение > холстД.пс-холстД.указка.с
  ТО
       смещение:=холстД.пс-холстД.указка.с
  КОН;
  УВЕЛИЧИТЬ(холстД.указка.с,смещение);
  холстД.текущаяСтрокаД:=СледующаяСтрока(холстД.текущаяСтрокаД,смещение);

                                               (* передвигаем рамку по холсту *)
  остаток:=холстД.пс-холстД.рамка.с-холстД.пср;
  ЕСЛИ
       смещение > остаток
  ТО
       смещение:=остаток
  КОН;
  ЕСЛИ
       смещение > 0
  ТО
    УВЕЛИЧИТЬ(холстД.рамка.с,смещение);
    холстД.верхняяСтрокаД:=СледующаяСтрока(холстД.верхняяСтрокаД,смещение);
    ОтрисовкаРамки(холстД)
  КОН;
  ПереместитьУказкуНаХолсте(холстД)
КОН ДСтраницуВниз;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДСтрокуВниз(холстД:Холст.Доступ);
ПЕР
  цвПробел:ЦвЗнак.Вид; 
УКАЗ
                                                  (* проверяем выход за холст *)
  ЕСЛИ
       холстД.указка.с = холстД.пс
  ТО
    ВОЗВРАТ
  КОН;
                                              (* передвигаем указку по холсту *)
  УВЕЛИЧИТЬ(холстД.указка.с);
       холстД.текущаяСтрокаД:=холстД.текущаяСтрокаД.слеД;

                            (* передвигаем рамку по холсту и указку по экрану *)
  ЕСЛИ
       холстД.указка.с > холстД.рамка.с+холстД.пср
  ТО
    УВЕЛИЧИТЬ(холстД.рамка.с);
    холстД.верхняяСтрокаД:=холстД.верхняяСтрокаД.слеД;

    ЦвЗнак.ИзЗнакаИЦвета(" ",холстД.цветОбычный,цвПробел);

    Окно.Вверх(холстД.вс,холстД.лк,холстД.нс,холстД.пк,цвПробел);

    ОтрисовкаСтроки(холстД,
                    холстД.текущаяСтрокаД,
                    холстД.указка.с,
                    холстД.лк,
                    холстД.вс+холстД.пср
                   )
  КОН;
  ПереместитьУказкуНаХолсте(холстД)
КОН ДСтрокуВниз;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДПрокруткаВниз(холстД:Холст.Доступ);
ПЕР
  цвПробел:ЦвЗнак.Вид; 
УКАЗ
                                                  (* проверяем выход за холст *)
  ЕСЛИ
       холстД.указка.с = холстД.пс
  ТО
    ВОЗВРАТ
  КОН;
                                              (* передвигаем указку по холсту *)
  УВЕЛИЧИТЬ(холстД.указка.с);
  холстД.текущаяСтрокаД:=холстД.текущаяСтрокаД.слеД;

                            (* передвигаем рамку по холсту и указку по экрану *)
  ЕСЛИ
       холстД.рамка.с+холстД.пср < холстД.пс
  ТО
    УВЕЛИЧИТЬ(холстД.рамка.с);
    холстД.верхняяСтрокаД:=холстД.верхняяСтрокаД.слеД;

    ЦвЗнак.ИзЗнакаИЦвета(" ",холстД.цветОбычный,цвПробел);

    Окно.Вверх(холстД.вс,холстД.лк,холстД.нс,холстД.пк,цвПробел);
    ОтрисовкаСтроки(холстД,
                    СледующаяСтрока(холстД.верхняяСтрокаД,холстД.пср),
                    холстД.рамка.с+холстД.пср,
                    холстД.лк,
                    холстД.вс+холстД.пср)
  КОН;
  ПереместитьУказкуНаХолсте(холстД)
КОН ДПрокруткаВниз;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДЗнакВлевоСУпором(холстД:Холст.Доступ);
УКАЗ
                                                  (* проверяем выход за холст *)
  ЕСЛИ
       холстД.указка.к = 0
  ТО
    ВОЗВРАТ
  КОН;
                                              (* передвигаем указку по холсту *)
  УМЕНЬШИТЬ(холстД.указка.к);
                            (* передвигаем рамку по холсту и указку по экрану *)
  ЕСЛИ
       холстД.указка.к < холстД.рамка.к
  ТО
    УМЕНЬШИТЬ(холстД.рамка.к);
    ОтрисовкаРамки(холстД)
  ИНАЧЕ
    ПереместитьУказкуНаХолсте(холстД)
  КОН
КОН ДЗнакВлевоСУпором;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДЗнакВлево(холстД:Холст.Доступ);
УКАЗ
                                                  (* проверяем выход за холст *)
  ЕСЛИ
       холстД.указка.к = 0
  ТО
    ЕСЛИ
       холстД.указка.с = 0
    ТО
      ВОЗВРАТ
    КОН;
    ДСтрокуВверх(холстД);
    ДВКонецСтроки(холстД)
  ИНАЧЕ
    ДЗнакВлевоСУпором(холстД)
  КОН
КОН ДЗнакВлево;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДЗнакВправо(холстД:Холст.Доступ);
УКАЗ
  ЕСЛИ
         холстД.указка.к = ПК
  ТО
    ВОЗВРАТ
  КОН;
  ЕСЛИ   холстД.однаСтрока
       И
        (холстД.указка.к = холстД.текущаяСтрокаД.пк+1)
  ТО
    ВОЗВРАТ
  КОН;
                                              (* передвигаем указку по холсту *)
  УВЕЛИЧИТЬ(холстД.указка.к);
                            (* передвигаем рамку по холсту и указку по экрану *)
  ЕСЛИ холстД.указка.к > холстД.рамка.к+холстД.пкр ТО
    УВЕЛИЧИТЬ(холстД.рамка.к);
    ОтрисовкаРамки(холстД)
  КОН;
  ПереместитьУказкуНаХолсте(холстД)
КОН ДЗнакВправо;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДСловоВлево(холстД:Холст.Доступ);
ПЕР
  строкаД:ДкЗвенуСтрока;
УКАЗ
  строкаД:=холстД.текущаяСтрокаД;
  ЕСЛИ
           холстД.указка.к = 0
  ТО
    ДЗнакВлево(холстД)
  ИНАЧЕ
    ЕСЛИ
           холстД.указка.к > строкаД.пк
    ТО
      ДВКонецСтроки(холстД)
    КОН;
    ПОКА  (холстД.указка.к > 0)
        И
          НЕ оЗнака.ВСлове(строкаД.цепь[холстД.указка.к])
    ВЫП
      ДЗнакВлево(холстД)
    КОН;
    ПОКА  (холстД.указка.к > 0)
        И
             оЗнака.ВСлове(строкаД.цепь[холстД.указка.к])
    ВЫП
      ДЗнакВлево(холстД)
    КОН
  КОН
КОН ДСловоВлево;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДСловоВправо(холстД:Холст.Доступ);
ПЕР
  строкаД:ДкЗвенуСтрока;
УКАЗ
  строкаД:=холстД.текущаяСтрокаД;
  ЕСЛИ
           холстД.указка.к > строкаД.пк
  ТО
    ЕСЛИ
           холстД.указка.с = холстД.пс
    ТО
      ВОЗВРАТ
    КОН;
    ДСтрокуВниз(холстД);
    ДВНачалоСтроки(холстД)
  ИНАЧЕ
    ПОКА  (холстД.указка.к <= строкаД.пк)
        И
             оЗнака.ВСлове(строкаД.цепь[холстД.указка.к])
    ВЫП
      ДЗнакВправо(холстД)
    КОН;
    ПОКА  (холстД.указка.к <= строкаД.пк)
        И
          НЕ оЗнака.ВСлове(строкаД.цепь[холстД.указка.к])
    ВЫП
      ДЗнакВправо(холстД)
    КОН
  КОН
КОН ДСловоВправо;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДВНачалоСтроки(холстД:Холст.Доступ);
УКАЗ
       холстД.указка.к:=0;
  ЕСЛИ
       холстД.рамка.к # 0
  ТО
       холстД.рамка.к:=0;
    ОтрисовкаРамки(холстД)
  КОН;
  ПереместитьУказкуНаХолсте(холстД)
КОН ДВНачалоСтроки;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДВКонецСтроки(холстД:Холст.Доступ);
ПЕР
  смещение:ЦЕЛ;
УКАЗ
  смещение:=холстД.текущаяСтрокаД.пк-холстД.указка.к+1;
  УВЕЛИЧИТЬ(холстД.указка.к,смещение);
  ЕСЛИ
       холстД.указка.к-холстД.рамка.к > холстД.пкр
  ТО
       холстД.рамка.к:=холстД.указка.к-холстД.пкр;
    ОтрисовкаРамки(холстД)
  КОН;
  ПереместитьУказкуНаХолсте(холстД)
КОН ДВКонецСтроки;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДВНачалоХолста(холстД:Холст.Доступ);
УКАЗ
  холстД.текущаяСтрокаД:=холстД.перваяСтрокаД;
  холстД.верхняяСтрокаД:=холстД.перваяСтрокаД;
  холстД.указка.с:=0;
  холстД.рамка.с:=0;
  ОтрисовкаРамки(холстД);
  ПереместитьУказкуНаХолсте(холстД)
КОН ДВНачалоХолста;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДВКонецХолста(холстД:Холст.Доступ);
ПЕР
  пср,пс:ЦЕЛ;
УКАЗ
   пс:=холстД.пс;
  пср:=холстД.пср;
       холстД.указка.с:=пс;
       холстД.текущаяСтрокаД:=холстД.последняяСтрокаД;
  ЕСЛИ
       пс > пср
  ТО
    холстД.рамка.с:=пс-пср;
    холстД.верхняяСтрокаД:=ПредыдущаяСтрока(холстД.последняяСтрокаД,пср);
    ОтрисовкаРамки(холстД)
  КОН;
  ПереместитьУказкуНаХолсте(холстД)
КОН ДВКонецХолста;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДВНачалоРамки(холстД:Холст.Доступ);
УКАЗ
  холстД.текущаяСтрокаД:=холстД.верхняяСтрокаД;
  УМЕНЬШИТЬ(холстД.указка.с,холстД.указка.с-холстД.рамка.с);
  ПереместитьУказкуНаХолсте(холстД)
КОН ДВНачалоРамки;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДВКонецРамки(холстД:Холст.Доступ);
ПЕР
    смещение:ЦЕЛ;
УКАЗ
    смещение:=холстД.пср-холстД.указка.с-холстД.рамка.с;
  ЕСЛИ
       холстД.указка.с+смещение > холстД.пс
  ТО
    смещение:=холстД.пс-холстД.указка.с
  КОН;
  холстД.текущаяСтрокаД:=СледующаяСтрока(холстД.текущаяСтрокаД,смещение);
  УВЕЛИЧИТЬ(холстД.указка.с,смещение);
  ПереместитьУказкуНаХолсте(холстД)
КОН ДВКонецРамки;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДСменаЗамены(холстД:Холст.Доступ);
УКАЗ
  холстД.замена:=НЕ холстД.замена;
  РазмерУказкиНаХолсте(холстД)
КОН ДСменаЗамены;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДЗаменитьЗнак(холстД:Холст.Доступ; знак:ЗНАК);
ПЕР
  строкаД:ДкЗвенуСтрока;
  отмена:нОтмена;
УКАЗ
  строкаД:=холстД.текущаяСтрокаД;
  ЕСЛИ
       (знак = " ")
      И
       (холстД.указка.к > строкаД.пк)
  ТО
    ЕСЛИ  НЕ (
               холстД.однаСтрока
             И
              (холстД.указка.к = строкаД.пк+1)
             )
    ТО
      ДЗнакВправо(холстД);
      ВОЗВРАТ
    КОН
  КОН;
       холстД.началоОтмен:=отменаЗаменитьЗнак;
  ЕСЛИ
       холстД.продолжениеОтмен = отменаЗаменитьЗнак
  ТО                                                 (* затираем последний 0X *)
    УМЕНЬШИТЬ(холстД.знаки.пПоз)
  ИНАЧЕ
    отмена.родОтмены:=отменаЗаменитьЗнак;
    отмена.указка:=холстД.указка;
    отмена.рамка:=холстД.рамка;
    отмена.чПоз:=холстД.знаки.пПоз;
    ДобавитьОтмену(холстД,отмена);
    ДобавитьПробелы(строкаД,холстД.указка.к)
  КОН;

  ЗнакВЗнаки(холстД.знаки,строкаД.цепь[холстД.указка.к]);
  ЗнакВЗнаки(холстД.знаки,0X);
  строкаД.цепь[холстД.указка.к]:=знак;
  ОтрисовкаТекущейСтроки(холстД);
  ДЗнакВправо(холстД)
КОН ДЗаменитьЗнак;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ОДЗаменитьЗнак(холстД :Холст.Доступ;
                      отмена-:нОтмена);           (* отмена изменений *)
ПЕР
        к:ЦЕЛ;
     знак:ЗНАК;
  строкаД:ДкЗвенуСтрока;
УКАЗ
  холстД.указка:=отмена.указка;
  холстД.рамка:=отмена.рамка;
  холстД.знаки.чПоз:=отмена.чПоз;
  холстД.знаки.пПоз:=отмена.чПоз;
  холстД.верхняяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,холстД.рамка.с);
  холстД.текущаяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,холстД.указка.с);
  строкаД:=холстД.текущаяСтрокаД;
  к:=холстД.указка.к;
  КОЛЬЦО
    знак:=ЗнакИзЗнаков(холстД.знаки);
    ЕСЛИ знак = 0X ТО ВЫХОД КОН;
    строкаД.цепь[к]:=знак;
    УВЕЛИЧИТЬ(к)
  КОН;
  УбратьПробелы(холстД.текущаяСтрокаД)
КОН ОДЗаменитьЗнак;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДВставитьЗнак(холстД:Холст.Доступ;
                       знак:ЗНАК);
(*
 * в отмена.чПоз хранится число последовательных вставок
 *)
ПЕР
        отмена:нОтмена;
       строкаД:ДкЗвенуСтрока;
УКАЗ
       строкаД:=холстД.текущаяСтрокаД;
  ЕСЛИ
       строкаД.пк = ПК
  ТО
    ВОЗВРАТ
  КОН;
  ЕСЛИ
                  (знак = " ") И (холстД.указка.к > строкаД.пк)
  ТО
    ЕСЛИ
         НЕ (холстД.однаСтрока И (холстД.указка.к = строкаД.пк+1))
    ТО
      ДЗнакВправо(холстД);
      ВОЗВРАТ
    КОН
  КОН;
       холстД.началоОтмен:=отменаВставитьЗнак;
  ЕСЛИ
       холстД.продолжениеОтмен = отменаВставитьЗнак
  ТО
    ПрочитатьОтмену(холстД,отмена);
    УВЕЛИЧИТЬ(отмена.чПоз);
    ЗаписатьОтмену(холстД,отмена)
  ИНАЧЕ
    отмена.родОтмены:=отменаВставитьЗнак;
    отмена.указка:=холстД.указка;
    отмена.рамка:=холстД.рамка;
    отмена.чПоз:=1;
    ДобавитьОтмену(холстД,отмена)
  КОН;

  ВставитьЗнак(холстД,знак);
  ОтрисовкаТекущейСтроки(холстД);
  ДЗнакВправо(холстД)
КОН ДВставитьЗнак;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ОДВставитьЗнак(холстД:Холст.Доступ;
                     отмена-:нОтмена);            (* отмена изменений *)
ПЕР
  повторов:ЦЕЛ;
УКАЗ
  холстД.указка:=отмена.указка;
  холстД.рамка:=отмена.рамка;
  холстД.верхняяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,холстД.рамка.с);
  холстД.текущаяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,холстД.указка.с);

       повторов:=отмена.чПоз;
  ПОКА
       повторов > 0
  ВЫП
    УдалитьЗнак(холстД);
    УМЕНЬШИТЬ(повторов)
  КОН;
  УбратьПробелы(холстД.текущаяСтрокаД)
КОН ОДВставитьЗнак;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДУдалитьЗнак(холстД:Холст.Доступ);
ПЕР
  строкаД:ДкЗвенуСтрока;
   отмена:нОтмена;
УКАЗ
  ЕСЛИ
         холстД.однаСтрока И холстД.отметка.существует
  ТО
    ДУдалитьОтметку(холстД);
    ВОЗВРАТ
  КОН;
строкаД:=холстД.текущаяСтрокаД;
  ЕСЛИ
      (  холстД.указка.с = холстД.пс)
     И
      (  холстД.указка.к > строкаД.пк)
  ТО
    ВОЗВРАТ
  КОН;
         холстД.началоОтмен     := отменаУдалитьЗнак;
  ЕСЛИ
         холстД.продолжениеОтмен = отменаУдалитьЗнак
  ТО                                                 (* затираем последний 0X *)
    УМЕНЬШИТЬ(холстД.знаки.пПоз)
  ИНАЧЕ
    отмена.родОтмены:=отменаУдалитьЗнак;
    отмена.указка:=холстД.указка;
    отмена.рамка:=холстД.рамка;
    отмена.чПоз:=холстД.знаки.пПоз;
    ДобавитьОтмену(холстД,отмена)
  КОН;
  ЕСЛИ
         холстД.указка.к > строкаД.пк
  ТО
    ДобавитьПробелы(строкаД,холстД.указка.к-1);
    СклеитьСтроку(холстД);
    ЗнакВЗнаки(холстД.знаки,0DX);
    ЗнакВЗнаки(холстД.знаки,0X);
                                (* обрываем отмену *)
         холстД.началоОтмен:=0;
                                (* отрисовка *)
    ЕСЛИ
        (холстД.рамка.с > 0) И (холстД.рамка.с+холстД.пср > холстД.пс)
    ТО
      УМЕНЬШИТЬ(холстД.рамка.с);
      холстД.верхняяСтрокаД:=холстД.верхняяСтрокаД.преД;
      ОтрисовкаРамки(холстД);
      ПереместитьУказкуНаХолсте(холстД)
    ИНАЧЕ
      ОтрисовкаНизаРамки(холстД,строкаД,холстД.указка.с,холстД.указка.с-холстД.рамка.с)
    КОН;
    ВОЗВРАТ
  КОН;
                                                          (* отрисовка *)
   ЗнакВЗнаки(холстД.знаки,строкаД.цепь[холстД.указка.к]);
   ЗнакВЗнаки(холстД.знаки,0X);
  УдалитьЗнак(холстД);
  ОтрисовкаТекущейСтроки(холстД)
КОН ДУдалитьЗнак;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ОДУдалитьЗнак(холстД:Холст.Доступ;
                    отмена-:нОтмена);             (* отмена изменений *)
ПЕР
     к:ЦЕЛ;
  знак:ЗНАК;
  цепь:РЯД ПК+5 ИЗ ЗНАК;                (* знаков запомнено не больше строчки *)
УКАЗ
  холстД.указка:=отмена.указка;
  холстД.рамка:=отмена.рамка;
  холстД.знаки.чПоз:=отмена.чПоз;
  холстД.знаки.пПоз:=отмена.чПоз;
  холстД.верхняяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,холстД.рамка.с);
  холстД.текущаяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,холстД.указка.с);
                        (* считывание удалённых знаков вешка обратном порядке *)
  к:=-1;
  ПОВТОРЯТЬ
    УВЕЛИЧИТЬ(к);
    знак:=ЗнакИзЗнаков(холстД.знаки);
    цепь[к]:=знак;
  ДО знак = 0X;
                                                        (* обрабатываем знаки *)
  ПОКА к > 0 ВЫП
    УМЕНЬШИТЬ(к);
    знак:=цепь[к];
    ЕСЛИ знак = 0DX ТО
      РазделитьСтроку(холстД);
      УбратьПробелы(холстД.текущаяСтрокаД)
    ИНАЧЕ
      ВставитьЗнак(холстД,знак)
    КОН
  КОН
КОН ОДУдалитьЗнак;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДУдалитьЗнакСлева(холстД:Холст.Доступ);
ПЕР
  строкаД:ДкЗвенуСтрока;
   отмена:нОтмена;
УКАЗ
  ЕСЛИ
         холстД.однаСтрока
      И
         холстД.отметка.существует
  ТО
    ДУдалитьОтметку(холстД);
    ВОЗВРАТ
  КОН;
  ЕСЛИ
         холстД.указка.к = 0
  ТО
    ЕСЛИ
         холстД.указка.с = 0
    ТО
      ВОЗВРАТ
    КОН;
    ДСтрокуВверх(холстД);
    ДВКонецСтроки(холстД)
  ИНАЧЕ
    ДЗнакВлевоСУпором(холстД);
    ЕСЛИ
         холстД.указка.к > холстД.текущаяСтрокаД.пк
    ТО
      ВОЗВРАТ
    КОН
  КОН;
строкаД:=холстД.текущаяСтрокаД;

         холстД.началоОтмен     := отменаУдалитьЗнакСлева;
  ЕСЛИ
         холстД.продолжениеОтмен = отменаУдалитьЗнакСлева
  ТО
                                           (* новое положение указки *)
    ПрочитатьОтмену(холстД,отмена);
    отмена.указка:=холстД.указка;
    ЗаписатьОтмену(холстД,отмена);
                                           (* затираем последний 0X *)
    УМЕНЬШИТЬ(холстД.знаки.пПоз)
  ИНАЧЕ
    отмена.родОтмены:=отменаУдалитьЗнакСлева;
    отмена.указка:=холстД.указка;
    отмена.рамка:=холстД.рамка;
    отмена.чПоз:=холстД.знаки.пПоз;
    ДобавитьОтмену(холстД,отмена)
  КОН;
  ЕСЛИ
         холстД.указка.к > строкаД.пк
  ТО
    СклеитьСтроку(холстД);
    ЗнакВЗнаки(холстД.знаки,0DX);
    ЗнакВЗнаки(холстД.знаки,0X);
                                                                 (* отрисовка *)
    ЕСЛИ
        (холстД.рамка.с > 0)
       И
        (холстД.рамка.с+холстД.пср > холстД.пс)
    ТО
      УМЕНЬШИТЬ(холстД.рамка.с);
      холстД.верхняяСтрокаД:=холстД.верхняяСтрокаД.преД;
      ОтрисовкаРамки(холстД);
      ПереместитьУказкуНаХолсте(холстД)
    ИНАЧЕ
      ОтрисовкаНизаРамки(холстД,строкаД,холстД.указка.с,холстД.указка.с-холстД.рамка.с)
    КОН;
    ВОЗВРАТ
  КОН;
                                                                 (* отрисовка *)
  ЗнакВЗнаки(холстД.знаки,строкаД.цепь[холстД.указка.к]);
  ЗнакВЗнаки(холстД.знаки,0X);
  УдалитьЗнак(холстД);
  ОтрисовкаТекущейСтроки(холстД)
КОН ДУдалитьЗнакСлева;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ОДУдалитьЗнакСлева(холстД:Холст.Доступ;
                         отмена-:нОтмена);        (* отмена изменений *)
ПЕР
  знак:ЗНАК;
УКАЗ
  холстД.указка:=отмена.указка;
  холстД.рамка:=отмена.рамка;
  холстД.знаки.чПоз:=отмена.чПоз;
  холстД.знаки.пПоз:=отмена.чПоз;
  холстД.верхняяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,холстД.рамка.с);
  холстД.текущаяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,холстД.указка.с);
  КОЛЬЦО
          знак:=ЗнакИзЗнаков(холстД.знаки);
    ЕСЛИ
          знак = 0X
    ТО
      ВЫХОД
    АЕСЛИ
          знак = 0DX
    ТО
      РазделитьСтроку(холстД);
      УбратьПробелы(холстД.текущаяСтрокаД)
    ИНАЧЕ
      ВставитьЗнак(холстД,знак)
    КОН
  КОН
КОН ОДУдалитьЗнакСлева;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДУдалитьДоКонцаСтроки(холстД:Холст.Доступ);
ПЕР
  строкаД:ДкЗвенуСтрока;
   отмена:нОтмена;
        к:ЦЕЛ;
УКАЗ
  строкаД:=холстД.текущаяСтрокаД;
        к:=холстД.указка.к;
  ЕСЛИ
        к > строкаД.пк
  ТО
    ВОЗВРАТ
  КОН;
  отмена.родОтмены:=отменаУдалитьДоКонцаСтроки;
  отмена.указка:=холстД.указка;
  отмена.рамка:=холстД.рамка;
  отмена.чПоз:=холстД.знаки.пПоз;
  ДобавитьОтмену(холстД,отмена);

  ПОКА  к <= строкаД.пк ВЫП
    ЗнакВЗнаки(холстД.знаки,строкаД.цепь[к]);
    УВЕЛИЧИТЬ(к)
  КОН;

  ЗнакВЗнаки(холстД.знаки,0X);
  строкаД.пк:=холстД.указка.к-1;
  ОтрисовкаТекущейСтроки(холстД)
КОН ДУдалитьДоКонцаСтроки;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ОДУдалитьДоКонцаСтроки(холстД:Холст.Доступ;
                             отмена-:нОтмена);       (* отмена изменений *)
ПЕР
  строкаД:ДкЗвенуСтрока;
       пк:ЦЕЛ;
     знак:ЗНАК;
УКАЗ
  холстД.указка:=отмена.указка;
  холстД.рамка:=отмена.рамка;
  холстД.знаки.чПоз:=отмена.чПоз;
  холстД.знаки.пПоз:=отмена.чПоз;
  холстД.верхняяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,холстД.рамка.с);
  холстД.текущаяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,холстД.указка.с);
  строкаД:=холстД.текущаяСтрокаД;
  пк:=строкаД.пк;

  КОЛЬЦО
         знак:=ЗнакИзЗнаков(холстД.знаки);
    ЕСЛИ
         знак = 0X
    ТО
      ВЫХОД
    КОН;
    УВЕЛИЧИТЬ(пк);
    строкаД.цепь[пк]:=знак
  КОН;
    строкаД.пк:=пк
КОН ОДУдалитьДоКонцаСтроки;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДУдалитьСтроку(холстД:Холст.Доступ);
ПЕР
       к:ЦЕЛ;
  отмена:нОтмена;
УКАЗ
  ЕСЛИ
       холстД.указка.с = холстД.пс
  ТО
    ДВНачалоСтроки(холстД);
    ДУдалитьДоКонцаСтроки(холстД)
  ИНАЧЕ
    отмена.родОтмены:=отменаУдалитьСтроку;
    отмена.указка:=холстД.указка;
    отмена.рамка:=холстД.рамка;
    отмена.чПоз:=холстД.знаки.пПоз;

    ДобавитьОтмену(холстД,отмена);

    ОТ к:=0 ДО холстД.текущаяСтрокаД.пк ВЫП
      ЗнакВЗнаки(холстД.знаки,
                 холстД.текущаяСтрокаД.цепь[к])
    КОН;
    ЗнакВЗнаки(холстД.знаки,0X);
    УдалитьСтроку(холстД);
                                                  (* отрисовка *)
    ЕСЛИ (холстД.рамка.с > 0)
        И
         (холстД.рамка.с+холстД.пср > холстД.пс)
    ТО
      УМЕНЬШИТЬ(холстД.рамка.с);
      холстД.верхняяСтрокаД:=холстД.верхняяСтрокаД.преД;
      ОтрисовкаРамки(холстД);
      ПереместитьУказкуНаХолсте(холстД)
    ИНАЧЕ
      ОтрисовкаНизаРамки(холстД,
                         холстД.текущаяСтрокаД,
                         холстД.указка.с,
                         холстД.указка.с-холстД.рамка.с
                        )
    КОН
  КОН
КОН ДУдалитьСтроку;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ОДУдалитьСтроку(холстД:Холст.Доступ;
                      отмена-:нОтмена);           (* отмена изменений *)
ПЕР
  строкаД:ДкЗвенуСтрока;
       пк:ЦЕЛ;
     знак:ЗНАК;
УКАЗ
  холстД.указка:=отмена.указка;
  холстД.рамка:=отмена.рамка;
  холстД.знаки.чПоз:=отмена.чПоз;
  холстД.знаки.пПоз:=отмена.чПоз;
  холстД.верхняяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,холстД.рамка.с);
  холстД.текущаяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,холстД.указка.с);
  СОЗДАТЬ(строкаД);
  ВставитьСтроку(холстД,строкаД);
  пк:=-1;
  КОЛЬЦО
         знак:=ЗнакИзЗнаков(холстД.знаки);
    ЕСЛИ
         знак = 0X
    ТО
      ВЫХОД
    КОН;
    УВЕЛИЧИТЬ(пк);
    строкаД.цепь[пк]:=знак
  КОН;
  строкаД.пк:=пк;
  холстД.верхняяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,холстД.рамка.с);
  холстД.текущаяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,холстД.указка.с)
КОН ОДУдалитьСтроку;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДУдалитьСловоСлева(холстД:Холст.Доступ);
ПЕР
  строкаД:ДкЗвенуСтрока;
    буквы:КЛЮЧ;
УКАЗ
  ЕСЛИ 
         холстД.указка.к = 0
  ТО
    ДУдалитьЗнакСлева(холстД);
    ВОЗВРАТ
  КОН;
строкаД:=холстД.текущаяСтрокаД;
  ЕСЛИ
         холстД.указка.к > строкаД.пк
  ТО
    ДВКонецСтроки(холстД);
    ЕСЛИ
         холстД.указка.к = 0
    ТО
      ВОЗВРАТ
    КОН
  КОН;
  ДЗнакВлево(холстД);
  буквы:=оЗнака.ВСлове(строкаД.цепь[холстД.указка.к]);
  КОЛЬЦО
    ДУдалитьЗнак(холстД);
    ЕСЛИ
         холстД.указка.к = 0
    ТО
      ВЫХОД
    КОН;
    ДЗнакВлево(холстД);
    ЕСЛИ
         буквы # оЗнака.ВСлове(строкаД.цепь[холстД.указка.к])
    ТО 
      ДЗнакВправо(холстД);
      ВЫХОД 
    КОН
  КОН
КОН ДУдалитьСловоСлева;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДУдалитьСловоСправа(холстД:Холст.Доступ);
ПЕР
  строкаД:ДкЗвенуСтрока;
    буквы:КЛЮЧ;
УКАЗ
  строкаД:=холстД.текущаяСтрокаД;
  ЕСЛИ
         холстД.указка.к > строкаД.пк
  ТО
    ЕСЛИ
         холстД.указка.с = холстД.пс
    ТО
      ВОЗВРАТ
    КОН;
    ДУдалитьЗнак(холстД);
    ВОЗВРАТ
  КОН;
  буквы:=оЗнака.ВСлове(строкаД.цепь[холстД.указка.к]);
  ПОКА 
       (холстД.указка.к <= строкаД.пк)
      И
       (буквы = оЗнака.ВСлове(строкаД.цепь[холстД.указка.к])) ВЫП
    ДУдалитьЗнак(холстД)
  КОН
КОН ДУдалитьСловоСправа;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДНоваяСтрока(холстД:Холст.Доступ);
(*
 * Создать новую строку (разделить старую) и сделать отступ в начале
 *)
ПОСТ
  ПКС = 10; (* последняя колонка слова *)
ПЕР
  строкаД:ДкЗвенуСтрока;
   отмена:нОтмена;
   отступ:ЦЕЛ;
    пк,к,
       кс:ЦЕЛ;
    слово:РЯД ПКС+1 ИЗ ЗНАК;
УКАЗ
  строкаД:=холстД.текущаяСтрокаД;
  отмена.родОтмены:=отменаНоваяСтрока;
  отмена.указка:=холстД.указка;
  отмена.рамка:=холстД.рамка;
  отмена.чПоз:=холстД.знаки.пПоз;
  ДобавитьОтмену(холстД,отмена);
  РазделитьСтроку(холстД);
  ОтрисовкаНизаРамки(холстД,строкаД,холстД.указка.с,холстД.указка.с-холстД.рамка.с);
  ДСтрокуВниз(холстД);
  ДВНачалоСтроки(холстД);
                                  (* определяем старый отступ *)
  пк:=строкаД.пк;
  к:=0;
  ПОКА (к <= пк) И (строкаД.цепь[к] = ' ') ВЫП
    УВЕЛИЧИТЬ(к)
  КОН;
  отступ:=к;
                                  (* считываем 1-е слово верхней строки *)
  кс:=0;
  ПОКА
       (к <= пк)
      И
       (кс < ПКС)
      И
        оБуквы.Известная(строкаД.цепь[к])
  ВЫП
    слово[кс]:=строкаД.цепь[к];
    УВЕЛИЧИТЬ(кс);
    УВЕЛИЧИТЬ(к)
  КОН;
  слово[кс]:=0X;
                                  (* увеличиваем при необходимости отступ *)
  ЕСЛИ (слово = "ПОСТ"     ) ИЛИ
       (слово = "ВИД"      ) ИЛИ
       (слово = "ПЕР"      ) ИЛИ
       (слово = "УКАЗ"     ) ИЛИ
       (слово = "ЕСЛИ"     ) ИЛИ
       (слово = "АЕСЛИ"    ) ИЛИ
       (слово = "ИНАЧЕ"    ) ИЛИ
       (слово = "ПОКА"     ) ИЛИ
       (слово = "ПОВТОРЯТЬ") ИЛИ
       (слово = "КОЛЬЦО"   ) ИЛИ
       (слово = "ОТ"       ) ИЛИ
       (слово = "ВЫБРАТЬ"  ) ИЛИ
       (слово = "ДЛЯ"      ) ТО
    УВЕЛИЧИТЬ(отступ,Отступ)
  КОН;
                                 (* отступаем пробелами *)
  ПОКА отступ > 0 ВЫП
    ДВставитьЗнак(холстД," ");
    УМЕНЬШИТЬ(отступ)
  КОН
КОН ДНоваяСтрока;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ОДНоваяСтрока(холстД:Холст.Доступ;
                    отмена-:нОтмена);             (* отмена изменений *)
УКАЗ
  холстД.указка:=отмена.указка;
  холстД.рамка:=отмена.рамка;
  холстД.знаки.чПоз:=отмена.чПоз;
  холстД.знаки.пПоз:=отмена.чПоз;
  холстД.верхняяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,холстД.рамка.с);
  холстД.текущаяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,холстД.указка.с);
  СклеитьСтроку(холстД)
КОН ОДНоваяСтрока;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДПереместитьУказку(холстД:Холст.Доступ; кр,ср:ЦЕЛ);
ПЕР
    смещение:ЦЕЛ;
УКАЗ
    смещение:=холстД.рамка.с + ср - холстД.указка.с;
  ЕСЛИ
         холстД.указка.с+смещение > холстД.пс
  ТО
    смещение:=холстД.пс-холстД.указка.с
  ИНАЧЕ
         холстД.указка.к:=холстД.рамка.к+кр;
    ЕСЛИ
         холстД.однаСтрока И (холстД.указка.к > холстД.текущаяСтрокаД.пк+1)
    ТО
         холстД.указка.к:=холстД.текущаяСтрокаД.пк+1
    КОН
  КОН;
  УВЕЛИЧИТЬ(холстД.указка.с,смещение);
         холстД.текущаяСтрокаД:=СоседняяСтрока(холстД.текущаяСтрокаД,смещение);
  ПереместитьУказкуНаХолсте(холстД)
КОН ДПереместитьУказку;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДВешка(холстД:Холст.Доступ; вешка:ЦЕЛ; поставить:КЛЮЧ);
ПЕР
  с,к,
  смещение:ЦЕЛ;

 (*...............................подЗадача...*)
  ЗАДАЧА Ограничить(с+,к+,пс:ЦЕЛ);
  УКАЗ
    ЕСЛИ  с < 0 ТО
                   с:=0
    АЕСЛИ с > пс ТО
                   с:=пс
    КОН;
    ЕСЛИ  к < 0 ТО
                   к:=0
    АЕСЛИ к > ПК ТО
                   к:=ПК
    КОН
  КОН Ограничить;
   
УКАЗ
  ЕСЛИ
       поставить
  ТО
    холстД.вешка[вешка].указка:=холстД.указка;
                              (* запомним положение рамки относительно указки *)
    холстД.вешка[вешка].рамка.с:=холстД.указка.с-холстД.рамка.с;
    холстД.вешка[вешка].рамка.к:=холстД.указка.к-холстД.рамка.к;
    ВОЗВРАТ
  КОН;
                                                                    (* указка *)
  с:=холстД.вешка[вешка].указка.с;
  к:=холстД.вешка[вешка].указка.к;
  Ограничить(с,к,холстД.пс);                                   (* подЗадача *)
  холстД.текущаяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,с);
  холстД.указка.с:=с;
  холстД.указка.к:=к;
                                                                     (* рамка *)
  УМЕНЬШИТЬ(с,холстД.вешка[вешка].рамка.с);
  УМЕНЬШИТЬ(к,холстД.вешка[вешка].рамка.к);
  Ограничить(с,к,холстД.пс);                                   (* подЗадача *)
  холстД.верхняяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,с);
  холстД.рамка.с:=с;
  холстД.рамка.к:=к;
                                                                 (* отрисовка *)
  ОтрисовкаРамки(холстД);
  ПереместитьУказкуНаХолсте(холстД)
КОН ДВешка;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДСнятьОтметку(холстД:Холст.Доступ);
УКАЗ
  ОчиститьОтметку(холстД.отметка);
  ОтрисовкаРамки(холстД)
КОН ДСнятьОтметку;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДОтметитьВсё(холстД:Холст.Доступ);
УКАЗ
  НачалоОтметки(холстД.отметка,ОТКЛ,0,0);
  ИзменитьОтметку(холстД.отметка,холстД.пс,ПК);
  ОтрисовкаРамки(холстД)
КОН ДОтметитьВсё;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       УдалитьОтметку(холстД:Холст.Доступ);             (* неявное действие *)
ПЕР
  отмена:нОтмена;
УКАЗ
  отмена.родОтмены:=отменаУдалитьОтметку;
  отмена.указка:=холстД.отметка.перв;
  отмена.чПоз:=холстД.знаки.пПоз;
  ДобавитьОтмену(холстД,отмена);
  ОтметкуВЗнаки(холстД);
  СтеретьОтметку(холстД)
КОН УдалитьОтметку;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ОУдалитьОтметку(холстД:Холст.Доступ;
                      отмена-:нОтмена);         (* отмена неявного действия *)
УКАЗ
  холстД.указка:=отмена.указка;
  холстД.знаки.чПоз:=отмена.чПоз;
  холстД.знаки.пПоз:=отмена.чПоз;
  холстД.текущаяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,холстД.указка.с);
  ЗнакиВОтметку(холстД);
  РамкаПоУказке(холстД) 
КОН ОУдалитьОтметку;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ПереписатьЗнакиВОтметку(холстД:Холст.Доступ);  (* невидимое действие *)
ПЕР
  отмена:нОтмена;
УКАЗ
  ЗнакиВОтметку(холстД);
  отмена.родОтмены:=отменаПереписатьЗнакиВОтметку;
  отмена.указка:=холстД.отметка.перв;
  отмена.рамка:=холстД.отметка.посл;
  ЕСЛИ
       холстД.отметка.вертикальная
  ТО
    отмена.чПоз:=1
  ИНАЧЕ
    отмена.чПоз:=0
  КОН;
  ДобавитьОтмену(холстД,отмена)
КОН ПереписатьЗнакиВОтметку;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ОПереписатьЗнакиВОтметку(холстД:Холст.Доступ;
                               отмена-:нОтмена);(* отмена невидимого действия *)
УКАЗ
                                                   (* восстанавливаем отметку *)
    холстД.отметка.нач :=отмена.указка;
    холстД.отметка.перв:=отмена.указка;
    холстД.отметка.посл:=отмена.рамка;
    холстД.отметка.изменяемая:=ОТКЛ;
  ЕСЛИ
       отмена.чПоз = 1
  ТО
    холстД.отметка.вертикальная:=ВКЛ
  ИНАЧЕ
    холстД.отметка.вертикальная:=ОТКЛ
  КОН;
                                                    (* восстанавливаем указку *)
    холстД.указка:=отмена.указка;
    холстД.текущаяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,холстД.указка.с);
  СтеретьОтметку(холстД)
КОН ОПереписатьЗнакиВОтметку;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДПеренестиОтметку(холстД:Холст.Доступ);
УКАЗ
  ЕСЛИ
       НЕ холстД.отметка.существует
  ТО
    ВОЗВРАТ
  КОН;
  УдалитьОтметку(холстД);
           (* холстД.знаки.чПоз указывают на данные для отмены УдалитьОтметку *)
  ПереписатьЗнакиВОтметку(холстД);
  ОтрисовкаРамки(холстД);
  ПереместитьУказкуНаХолсте(холстД)
КОН ДПеренестиОтметку;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДПереписатьОтметку(холстД:Холст.Доступ);
УКАЗ
  ЕСЛИ
       НЕ холстД.отметка.существует
  ТО
    ВОЗВРАТ
  КОН;
  ОтметкуВЗнаки(холстД);
                                                       (* знаки будут ненужны *)
  холстД.знаки.пПоз:=холстД.знаки.чПоз;
  ПереписатьЗнакиВОтметку(холстД);                      (* невидимое действие *)
  ОтрисовкаРамки(холстД);
  ПереместитьУказкуНаХолсте(холстД)
КОН ДПереписатьОтметку;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДУдалитьОтметку(холстД:Холст.Доступ);
УКАЗ
  ЕСЛИ
       НЕ холстД.отметка.существует
  ТО
    ВОЗВРАТ
  КОН;
  УдалитьОтметку(холстД);
  ОтрисовкаРамки(холстД);
  ПереместитьУказкуНаХолсте(холстД)
КОН ДУдалитьОтметку;


(*============================================================================* 
 * работа с памяткой (для однострочного холста) - локальные задачи
 *============================================================================*)

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДНайтиСтрокуВПамятке(холстД:Холст.Доступ);
ПЕР
    цепьД:ДОСТУП К ЦЕПЬ;
  строкаД:ДкЗвенуСтрока;
     ку,к:ЦЕЛ;
  строкаПамятки:ЦЕЛ;
УКАЗ
  строкаД:=холстД.текущаяСтрокаД;
       ку:=холстД.указка.к;
  ЕСЛИ
       ку # строкаД.пк+1
  ТО
    ВОЗВРАТ
  КОН;
  строкаД.цепь[ку]:=0X;

       строкаПамятки:=Памятка.ПохожаяСтрока(холстД.памяткаД,строкаД.цепь);
  ЕСЛИ
       строкаПамятки # -1
  ТО
    цепьД:=холстД.памяткаД.рСтроки[строкаПамятки];
                                                 (* перепишем добавок в знаки *)
    холстД.знаки.чПоз:=холстД.знаки.пПоз;

    ОТ к:=ку ДО ДЛИНА(цепьД^)-1 ВЫП
      ЗнакВЗнаки(холстД.знаки,цепьД[к])
    КОН;
      ЗнакВЗнаки(холстД.знаки,0X);
                                                      (* знаки больше ненужны *)
    холстД.знаки.пПоз:=холстД.знаки.чПоз;

    ПереписатьЗнакиВОтметку(холстД);                    (* невидимое действие *)

    холстД.указка.к:=ку;
    Отрисовка(холстД)
  КОН
КОН ДНайтиСтрокуВПамятке;

(*----------------------------отработка действий человека - локальная ЗАДАЧА--*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДВыбратьСтрокуВПамятке(холстД:Холст.Доступ);
ПЕР
  строкаПамятки:ЦЕЛ;
УКАЗ
  строкаПамятки:=ПолеПамятки.Выполнить(холстД,
                                       холстД.памяткаД,
                            (* преобразование
                                              полеД             из Рамка.Доступ в
                                                    Поле.Доступ <- Рамка.Доступ   *)
                                       холстД.полеД(Поле.Доступ)
                                      );
  ЕСЛИ
       строкаПамятки # -1
  ТО
    ЗагрузитьСтрокуИзЦепи(холстД,
                          холстД.памяткаД.рСтроки[строкаПамятки]^);
    Отрисовка(холстД)
  КОН
КОН ДВыбратьСтрокуВПамятке;


(*============================================================================*)
(* ******* работа с обменником ******* *)
(*============================================================================*)

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ЗнакиВОбменник(холстД:Холст.Доступ);
ПЕР
        знак:ЗНАК;
    чПоз,
  размер,поз:ЦЕЛ;
     памятьД:ДОСТУП К ЦЕПЬ;
УКАЗ
                                             (* выясняем длину цепочки знаков *)
    чПоз:=холстД.знаки.чПоз;
  размер:=0;
  ПОВТОРЯТЬ 
    знак:=ЗнакИзЗнаков(холстД.знаки);
    УВЕЛИЧИТЬ(размер);
    ЕСЛИ
         знак = 0DX
    ТО                                       (* вставляем для порядка LF *)
      УВЕЛИЧИТЬ(размер)
    КОН
  ДО знак = 0X;
  холстД.знаки.чПоз:=чПоз;
                                           (* записываем цепочку вешка память *)
  СОЗДАТЬ(памятьД,размер);
  поз:=0;
  ПОВТОРЯТЬ 
    знак:=ЗнакИзЗнаков(холстД.знаки);
    памятьД[поз]:=знак;
    УВЕЛИЧИТЬ(поз);
    ЕСЛИ
         знак = 0DX
    ТО                                       (* вставляем для порядка LF *)
      памятьД[поз]:=0AX;
      УВЕЛИЧИТЬ(поз)
    КОН
  ДО знак = 0X;

  холстД.знаки.чПоз:=чПоз;
  ОС.ЦепочкуВОбменник(памятьД^)
КОН ЗнакиВОбменник;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ОбменникВЗнаки(холстД:Холст.Доступ);
ПЕР
       знак,
       знак1 :ЗНАК;
     размер,
        поз  :ЦЕЛ;
     памятьД :ДОСТУП К ЦЕПЬ;
УКАЗ
  холстД.знаки.чПоз:=холстД.знаки.пПоз;
  размер:=ОС.РазмерЦепочкиОбменника();

  СОЗДАТЬ(памятьД,размер);
  ОС.ЦепочкуИзОбменника(памятьД^);
  знак1:=0X;

  ОТ поз:=0 ДО размер-1 ВЫП
    знак:=памятьД[поз];
                                                      (* пропускаем лишний LF *)
    ЕСЛИ ((знак # 0AX) ИЛИ (знак1 # 0DX))
        И
          НЕ (холстД.однаСтрока И (знак = 0DX))
    ТО
      ЗнакВЗнаки(холстД.знаки,знак)
    КОН;
    знак1:=знак
  КОН;
  ЗнакВЗнаки(холстД.знаки,0X)
КОН ОбменникВЗнаки;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДПереписатьВОбменник(холстД:Холст.Доступ);
УКАЗ
  ЕСЛИ
       НЕ холстД.отметка.существует
  ТО 
    НачалоОтметки(холстД.отметка,ОТКЛ,холстД.указка.с,0);
    ИзменитьОтметку(холстД.отметка,холстД.указка.с+1,-1);
    ОтрисовкаТекущейСтроки(холстД)
  КОН;

  ОтметкуВЗнаки(холстД);
                                                       (* знаки будут ненужны *)
  холстД.знаки.пПоз:=холстД.знаки.чПоз;
  ЗнакиВОбменник(холстД);
КОН ДПереписатьВОбменник;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДПеренестиВОбменник(холстД:Холст.Доступ);
УКАЗ
  ЕСЛИ
       НЕ холстД.отметка.существует
  ТО
    ВОЗВРАТ
  КОН;
  УдалитьОтметку(холстД);

  ЗнакиВОбменник(холстД);

  ОтрисовкаРамки(холстД);
  ПереместитьУказкуНаХолсте(холстД)
КОН ДПеренестиВОбменник;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДПереписатьИзОбменника(холстД:Холст.Доступ);
УКАЗ
  ЕСЛИ
       холстД.однаСтрока 
      И
       холстД.отметка.существует
  ТО
    ДУдалитьОтметку(холстД)
  КОН;

  ОбменникВЗнаки(холстД);
                                                       (* знаки будут ненужны *)
  холстД.знаки.пПоз:=холстД.знаки.чПоз;

  ПереписатьЗнакиВОтметку(холстД);                      (* невидимое действие *)

  ОтрисовкаРамки(холстД);
  ПереместитьУказкуНаХолсте(холстД)
КОН ДПереписатьИзОбменника;


(*============================================================================* 
 * сдвиг отметки или строки
 *============================================================================*)

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.нЗвеноСтрока)*)
       ВставляемПервыйПробел(строкаД:ДкЗвенуСтрока):КЛЮЧ;
ПЕР
  пк:ЦЕЛ;
УКАЗ
  ЕСЛИ
       строкаД.пк >= ПК
  ТО
    ВОЗВРАТ ОТКЛ
  КОН;
  ОТ пк:=строкаД.пк ДО 0 ПО -1 ВЫП
    строкаД.цепь[пк+1]:=строкаД.цепь[пк]
  КОН;
  УВЕЛИЧИТЬ(строкаД.пк);
  строкаД.цепь[0]:=' ';
  ВОЗВРАТ ВКЛ
КОН ВставляемПервыйПробел;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.нЗвеноСтрока)*)
       УбираемПервыйПробел(строкаД:ДкЗвенуСтрока):КЛЮЧ;
ПЕР
     пк:ЦЕЛ;
УКАЗ
  ЕСЛИ (строкаД.пк < 0)
      ИЛИ
       (строкаД.цепь[0] # ' ')
  ТО
    ВОЗВРАТ ОТКЛ
  КОН;
  ОТ пк:=1 ДО строкаД.пк ВЫП
    строкаД.цепь[пк-1]:=строкаД.цепь[пк]
  КОН;
  УМЕНЬШИТЬ(строкаД.пк);
  ВОЗВРАТ ВКЛ
КОН УбираемПервыйПробел;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.нТочка)*)
       ТочкуВправо(точка+:Холст.нТочка;
                       с :ЦЕЛ);
УКАЗ
  ЕСЛИ (точка.с = с) И (точка.к < ПК) ТО
    УВЕЛИЧИТЬ(точка.к)
  КОН
КОН ТочкуВправо;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.нТочка)*)
       ТочкуВлево(точка+:Холст.нТочка;
                      с :ЦЕЛ);
УКАЗ
  ЕСЛИ
       (точка.с = с) И (точка.к > 0)
  ТО
    УМЕНЬШИТЬ(точка.к)
  КОН
КОН ТочкуВлево;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДСдвинутьВправо(холстД:Холст.Доступ);
ПЕР
    первс,
    первк,
    послс:ЦЕЛ;
  строкаД:ДкЗвенуСтрока;
   отмена:нОтмена;
   вешка,
       с :ЦЕЛ;
УКАЗ
  отмена.родОтмены:=отменаСдвинутьВправо;
  ЕСЛИ
          НЕ холстД.отметка.существует
  ТО 
    строкаД:=холстД.текущаяСтрокаД;
    ЕСЛИ 
         ВставляемПервыйПробел(строкаД)
    ТО
      отмена.указка:=холстД.указка;
      отмена.рамка:=холстД.рамка;
      отмена.чПоз:=-1;                    (* невозможная позиция *)
      ДобавитьОтмену(холстД,отмена);
                                                          (* исправляем точки *)
      ОТ вешка:=0 ДО 9 ВЫП
        ТочкуВправо(холстД.вешка[вешка].указка,холстД.указка.с)
      КОН;
      ЕСЛИ холстД.указка.к < ПК ТО
        УВЕЛИЧИТЬ(холстД.указка.к)
      КОН
    КОН
  ИНАЧЕ
    первс:=холстД.отметка.перв.с;
    ЕСЛИ
         холстД.отметка.вертикальная
    ТО
      первк:=холстД.отметка.перв.к-1;
      ЕСЛИ первк >= 0 ТО 
        УдалитьОтметку(холстД);
        ПоставитьУказку(холстД,первс,первк);
        ПереписатьЗнакиВОтметку(холстД)                 (* невидимое действие *)
      КОН
    ИНАЧЕ
      отмена.указка:=холстД.отметка.перв;
      отмена.рамка:=холстД.отметка.посл;
      отмена.чПоз:=холстД.знаки.пПоз;
      ДобавитьОтмену(холстД,отмена);
      послс:=холстД.отметка.посл.с;
      ЕСЛИ
           холстД.отметка.посл.к < 0
      ТО
        УМЕНЬШИТЬ(послс)
      КОН;
      строкаД:=СледующаяСтрока(холстД.перваяСтрокаД,первс);
      ОТ с:=первс ДО послс ВЫП
        ЕСЛИ
             ВставляемПервыйПробел(строкаД)
        ТО
          ЗнакВЗнаки(холстД.знаки," ");
          (* исправляем точки *)
          ОТ вешка:=0 ДО 9 ВЫП
            ТочкуВправо(холстД.вешка[вешка].указка,с)
          КОН;
          ТочкуВправо(холстД.отметка.перв,с);
          ТочкуВправо(холстД.отметка.посл,с);
          ТочкуВправо(холстД.отметка.нач, с)
        КОН;
        ЕСЛИ с # послс ТО
          ЗнакВЗнаки(холстД.знаки,0DX);
          строкаД:=строкаД.слеД
        КОН
      КОН;
      ЗнакВЗнаки(холстД.знаки,0X)
    КОН
  КОН;
  ОтрисовкаРамки(холстД);
  ПереместитьУказкуНаХолсте(холстД)
КОН ДСдвинутьВправо;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ОДСдвинутьВправо(холстД:Холст.Доступ;
                       отмена-:нОтмена);          (* отмена изменений *)
ПЕР
  строкаД :ДкЗвенуСтрока;
    вешка,
        с :ЦЕЛ;
     знак :ЗНАК;
УКАЗ
  ЕСЛИ отмена.чПоз = -1 ТО                  (* одна строка *)
    ОчиститьОтметку(холстД.отметка);
    холстД.указка:=отмена.указка;
    холстД.рамка:=отмена.рамка;

    холстД.верхняяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,
                                           холстД.рамка.с);
    холстД.текущаяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,
                                           холстД.указка.с);
    ЕСЛИ
         УбираемПервыйПробел(холстД.текущаяСтрокаД)
    ТО                                             (* всегда исправляем точки *)
      ОТ вешка:=0 ДО 9 ВЫП
        ТочкуВлево(холстД.вешка[вешка].указка,холстД.указка.с)
      КОН
    КОН
  ИНАЧЕ                                                       (* была отметка *)
                                    (* восстанавливаем отметку *)
    холстД.отметка.нач:=отмена.указка;
    холстД.отметка.перв:=отмена.указка;
    холстД.отметка.посл:=отмена.рамка;
    холстД.отметка.изменяемая:=ОТКЛ;
    холстД.отметка.вертикальная:=ОТКЛ;
    холстД.знаки.чПоз:=отмена.чПоз;
    холстД.знаки.пПоз:=отмена.чПоз;
                                                           (* убираем пробелы *)
    с:=холстД.отметка.перв.с;
    строкаД:=СледующаяСтрока(холстД.перваяСтрокаД,с);
    КОЛЬЦО
           знак:=ЗнакИзЗнаков(холстД.знаки);
      ЕСЛИ
           знак = 0X
      ТО
        ВЫХОД
      АЕСЛИ
           знак = 0DX
      ТО
        УВЕЛИЧИТЬ(с);
        строкаД:=строкаД.слеД
      ИНАЧЕ
        ЕСЛИ УбираемПервыйПробел(строкаД) ТО (* всегда *)
                                                          (* исправляем точки *)
          ОТ вешка:=0 ДО 9 ВЫП
            ТочкуВлево(холстД.вешка[вешка].указка,с)
          КОН;
          ТочкуВлево(холстД.указка,с)
        КОН
      КОН
    КОН
  КОН;
  ОтрисовкаРамки(холстД);
  ПереместитьУказкуНаХолсте(холстД)
КОН ОДСдвинутьВправо;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДСдвинутьВлево(холстД:Холст.Доступ);
ПЕР
   первс,
   первк,
   послс :ЦЕЛ;
  отмена :нОтмена;
  строкаД:ДкЗвенуСтрока;
   вешка,
       с :ЦЕЛ;
УКАЗ
  отмена.родОтмены:=отменаСдвинутьВлево;
  ЕСЛИ
          НЕ холстД.отметка.существует
  ТО 
    строкаД:=холстД.текущаяСтрокаД;
    ЕСЛИ
         УбираемПервыйПробел(строкаД)
    ТО
      отмена.указка:=холстД.указка;
      отмена.рамка:=холстД.рамка;
      отмена.чПоз:=-1;                  (* невозможная позиция *)
      ДобавитьОтмену(холстД,отмена);
                                                          (* исправляем точки *)
      ОТ вешка:=0 ДО 9 ВЫП
        ТочкуВлево(холстД.вешка[вешка].указка,холстД.указка.с)
      КОН;
      ЕСЛИ холстД.указка.к > 0 ТО
        УМЕНЬШИТЬ(холстД.указка.к)
      КОН
    КОН
  ИНАЧЕ
    первс:=холстД.отметка.перв.с;
    ЕСЛИ
           холстД.отметка.вертикальная
    ТО
      ЕСЛИ
           холстД.отметка.посл.к < ПК
      ТО 
        первк:=холстД.отметка.перв.к+1;
        УдалитьОтметку(холстД);
        ПоставитьУказку(холстД,первс,первк);
        ПереписатьЗнакиВОтметку(холстД)                 (* невидимое действие *)
      КОН
    ИНАЧЕ
      отмена.указка:=холстД.отметка.перв;
      отмена.рамка:=холстД.отметка.посл;
      отмена.чПоз:=холстД.знаки.пПоз;
      ДобавитьОтмену(холстД,отмена);
      послс:=холстД.отметка.посл.с;
      ЕСЛИ
           холстД.отметка.посл.к < 0
      ТО
        УМЕНЬШИТЬ(послс)
      КОН;
      строкаД:=СледующаяСтрока(холстД.перваяСтрокаД,первс);
      ОТ с:=первс ДО послс ВЫП
        ЕСЛИ
             УбираемПервыйПробел(строкаД)
        ТО
          ЗнакВЗнаки(холстД.знаки," ");
                                                          (* исправляем точки *)
          ОТ вешка:=0 ДО 9 ВЫП
            ТочкуВлево(холстД.вешка[вешка].указка,с)
          КОН;
          ТочкуВлево(холстД.отметка.перв,с);
          ТочкуВлево(холстД.отметка.посл,с);
          ТочкуВлево(холстД.отметка.нач, с)
        КОН;
        ЕСЛИ с # послс ТО
          ЗнакВЗнаки(холстД.знаки,0DX);
          строкаД:=строкаД.слеД
        КОН
      КОН;
      ЗнакВЗнаки(холстД.знаки,0X)
    КОН
  КОН;
  ОтрисовкаРамки(холстД);
  ПереместитьУказкуНаХолсте(холстД)
КОН ДСдвинутьВлево;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ОДСдвинутьВлево(холстД:Холст.Доступ;
                      отмена-:нОтмена);           (* отмена изменений *)
ПЕР
  строкаД:ДкЗвенуСтрока;
  вешка,с:ЦЕЛ;
  знак:ЗНАК;
УКАЗ
  ЕСЛИ
       отмена.чПоз = -1
  ТО                                (* одна строка *)
    ОчиститьОтметку(холстД.отметка);
    холстД.указка:=отмена.указка;
    холстД.рамка:=отмена.рамка;

    холстД.верхняяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,
                                           холстД.рамка.с);
    холстД.текущаяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,
                                           холстД.указка.с);
    ЕСЛИ
         ВставляемПервыйПробел(холстД.текущаяСтрокаД)
    ТО                                             (* всегда исправляем точки *)
      ОТ вешка:=0 ДО 9 ВЫП
        ТочкуВправо(холстД.вешка[вешка].указка,холстД.указка.с)
      КОН
    КОН
  ИНАЧЕ                                                       (* была отметка *)
                                   (* восстанавливаем отметку *)
    холстД.отметка.нач:=отмена.указка;
    холстД.отметка.перв:=отмена.указка;
    холстД.отметка.посл:=отмена.рамка;
    холстД.отметка.изменяемая:=ОТКЛ;
    холстД.отметка.вертикальная:=ОТКЛ;
    холстД.знаки.чПоз:=отмена.чПоз;
    холстД.знаки.пПоз:=отмена.чПоз;
                                   (* убираем пробелы *)
    с:=холстД.отметка.перв.с;
    строкаД:=СледующаяСтрока(холстД.перваяСтрокаД,с);
    КОЛЬЦО
           знак:=ЗнакИзЗнаков(холстД.знаки);
      ЕСЛИ 
           знак = 0X
      ТО
        ВЫХОД
      АЕСЛИ
           знак = 0DX
      ТО
        УВЕЛИЧИТЬ(с);
        строкаД:=строкаД.слеД
      ИНАЧЕ
        ЕСЛИ
             ВставляемПервыйПробел(строкаД)
        ТО                                  (* всегда *)
                                                          (* исправляем точки *)
          ОТ вешка:=0 ДО 9 ВЫП
            ТочкуВправо(холстД.вешка[вешка].указка,с)
          КОН;
            ТочкуВправо(холстД.указка,с)
        КОН
      КОН
    КОН
  КОН;
  ОтрисовкаРамки(холстД);
  ПереместитьУказкуНаХолсте(холстД)
КОН ОДСдвинутьВлево;


(*============================================================================* 
 * работа с отменами - локальные задачи
 *============================================================================*)

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ОчиститьОтмены(отмены+:нОтмены);    (* очистить все отмены изменений *)
ПЕР
  ряд:ЦЕЛ;
УКАЗ
  ОТ ряд:=0 ДО последнийРядОтмен ВЫП
    отмены.рДкРядуОтмен[ряд]:=ПУСТО
  КОН;
    отмены.последнийРяд:=-1;
    отмены.поз:=-1
КОН ОчиститьОтмены;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ПрочитатьОтмену(холстД:Холст.Доступ;
                      отмена+:нОтмена);           (* отмена считывается *)
ПЕР
       поз:ЦЕЛ;
УКАЗ
       поз:=холстД.отмены.поз;
  ЕСЛИ
       поз < 0
  ТО
    ВОЗВРАТ
  КОН;
  отмена:=холстД.отмены.рДкРядуОтмен[поз ДЕЛИТЬ  размерРядаОтмен]
                                    [поз ОСТАТОК размерРядаОтмен];
КОН ПрочитатьОтмену;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ЗаписатьОтмену(холстД:Холст.Доступ;
                     отмена-:нОтмена);            (* отмена изменений *)
ПЕР
  поз,   ряд:ЦЕЛ;
УКАЗ
  поз:=холстД.отмены.поз;
         ряд:=поз ДЕЛИТЬ размерРядаОтмен;
  ЕСЛИ
         ряд > холстД.отмены.последнийРяд
  ТО
    ЕСЛИ
         ряд > последнийРядОтмен
    ТО
      ВОЗВРАТ
    КОН;                                             (* лучше бы кольцо отмен *)
             холстД.отмены.последнийРяд:=ряд;
     СОЗДАТЬ(холстД.отмены.рДкРядуОтмен[ряд])
  КОН;
             холстД.отмены.рДкРядуОтмен[ряд][поз ОСТАТОК размерРядаОтмен]:=отмена
КОН ЗаписатьОтмену;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДобавитьОтмену(холстД:Холст.Доступ;
                     отмена-:нОтмена);            (* отмена изменений *)
ПЕР
  ряд,поз:ЦЕЛ;
УКАЗ
  УВЕЛИЧИТЬ(холстД.отмены.поз);
  ЗаписатьОтмену(холстД,отмена)
КОН ДобавитьОтмену;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА^                                                          (*(Холст.Вид)*)
        ОЗаменить(холстД:Холст.Доступ;
                 отмена-:нОтмена);                (* отмена изменений *)

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДОтменить(холстД:Холст.Доступ);
ПЕР
              отмена:нОтмена;
УКАЗ
  ЕСЛИ
       холстД.отмены.поз < 0
  ТО
    ВОЗВРАТ
  КОН;
  ПрочитатьОтмену(холстД,отмена);

        УМЕНЬШИТЬ(холстД.отмены.поз);

  ВЫБРАТЬ
          отмена.родОтмены
  ИЗ                                  (* локальные задачи по отмене изменений *)
  | отменаУдалитьОтметку:          ОУдалитьОтметку         (холстД,отмена)
  | отменаПереписатьЗнакиВОтметку: ОПереписатьЗнакиВОтметку(холстД,отмена)
  | отменаЗаменитьЗнак:            ОДЗаменитьЗнак          (холстД,отмена)
  | отменаВставитьЗнак:            ОДВставитьЗнак          (холстД,отмена)
  | отменаУдалитьЗнак:             ОДУдалитьЗнак           (холстД,отмена)
  | отменаУдалитьЗнакСлева:        ОДУдалитьЗнакСлева      (холстД,отмена)
  | отменаНоваяСтрока:             ОДНоваяСтрока           (холстД,отмена)
  | отменаУдалитьСтроку:           ОДУдалитьСтроку         (холстД,отмена)
  | отменаУдалитьДоКонцаСтроки:    ОДУдалитьДоКонцаСтроки  (холстД,отмена)
  | отменаСдвинутьВправо:          ОДСдвинутьВправо        (холстД,отмена)
  | отменаСдвинутьВлево:           ОДСдвинутьВлево         (холстД,отмена)
  | отменаЗаменить:                ОЗаменить               (холстД,отмена)
  КОН;
  ОтрисовкаРамки(холстД);
  ПереместитьУказкуНаХолсте(холстД)
КОН ДОтменить;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ДОтметкаПеремещение(холстД:Холст.Доступ;
                              код:ЦЕЛ;
                                                упрШифт,
                                                упрКонтр,
                                                упрАльт:КЛЮЧ);
ПЕР
        простаяОтметка,
   вертикальнаяОтметка :КЛЮЧ;
УКАЗ
        простаяОтметка:=упрШифт И НЕ упрАльт;
   вертикальнаяОтметка:=упрАльт;
  ЕСЛИ
        простаяОтметка
      И
       (НЕ холстД.отметка.изменяемая ИЛИ холстД.отметка.вертикальная)
  ТО
    НачалоОтметки(холстД.отметка,ОТКЛ,холстД.указка.с,холстД.указка.к)
  АЕСЛИ
        вертикальнаяОтметка
      И
       (НЕ холстД.отметка.изменяемая ИЛИ НЕ холстД.отметка.вертикальная)
  ТО
    НачалоОтметки(холстД.отметка,ВКЛ,холстД.указка.с,холстД.указка.к)
  КОН;
  ЕСЛИ
       упрКонтр
  ТО
    ВЫБРАТЬ код ИЗ
(* PgUp*) | 21H: ДВНачалоХолста       (холстД)                  
(* PgDn*) | 22H: ДВКонецХолста        (холстД)                  
(* End *) | 23H: ДВКонецХолста        (холстД)                  
(* Home*) | 24H: ДВНачалоХолста       (холстД)                  
(* <-  *) | 25H: ДСловоВлево          (холстД)                  
(* ^   *) | 26H: ДПрокруткаВверх      (холстД)
(* ->  *) | 27H: ДСловоВправо         (холстД)                  
(* V   *) | 28H: ДПрокруткаВниз       (холстД)
    КОН
  ИНАЧЕ
    ВЫБРАТЬ код ИЗ      
(* PgUp*) | 21H: ДСтраницуВверх       (холстД)                  
(* PgDn*) | 22H: ДСтраницуВниз        (холстД)                  
(* End *) | 23H: ДВКонецСтроки        (холстД)                  
(* Home*) | 24H: ДВНачалоСтроки       (холстД)                  
(* <-  *) | 25H: ДЗнакВлево           (холстД)                  
(* ^   *) | 26H: ДСтрокуВверх         (холстД)                  
(* ->  *) | 27H: ДЗнакВправо          (холстД)                  
(* V   *) | 28H: ДСтрокуВниз          (холстД)                  
    КОН
  КОН;
  ЕСЛИ
         холстД.отметка.изменяемая
      И 
       ( (вертикальнаяОтметка И холстД.отметка.вертикальная)
        ИЛИ
         (  простаяОтметка И НЕ холстД.отметка.вертикальная)
       )
  ТО
    ИзменитьОтметку(холстД.отметка,холстД.указка.с,холстД.указка.к);
    ОтрисовкаРамки(холстД)
  ИНАЧЕ
    ЕСЛИ
         холстД.однаСтрока
       И
         холстД.отметка.существует
    ТО
      ДСнятьОтметку(холстД)
    ИНАЧЕ
      холстД.отметка.изменяемая:=ОТКЛ
    КОН
  КОН
КОН ДОтметкаПеремещение;


(*============================================================================* 
 * ввод действий - локальные задачи
 *============================================================================*)

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                             (* (Холст.Вид <- Надел.Вид)*)(* приём посылок из вне (снаружи) = от человека *)
       Приём(наделД:Надел.Доступ;
           посылка+:Ввод.нПосылка); (* = Пустой.Вид; - абстрактный опорный набор *)
(*
 * обработка посланий от человека
 *)
ПЕР
  прокрут:ЦЕЛ;
  холстД:Холст.Доступ;
        кодПосылки:ЦЕЛ;
УКАЗ                                                         (* преобразование
          наделД               из Надел.Доступ в
                 Холст.Доступ  <- Надел.Доступ <- Рамка.Доступ                *)
  холстД:=наделД(Холст.Доступ);
                             (* анализ многоформия (полиморфизма) у <посылка> = Пустой.Вид *)
  ДЛЯ      посылка ВИДА
  | Поле.нОтрисовка:
      Отрисовка(холстД)

  | Ввод.нОтКлавиш:
        кодПосылки:=посылка.код;
                    посылка.код:=0;        (* скорее всего отработаем посылку *)

      холстД.началоОтмен:=0;               (* скорее всего отмены не нужны    *)
      ЕСЛИ
       НЕ (посылка.упрАльт ИЛИ посылка.упрКонтр)
     И
          (посылка.знак >= ' ')
      ТО                                                       (* ввод текста *)
        ЕСЛИ
              холстД.однаСтрока
            И
              холстД.отметка.существует
        ТО
          ДУдалитьОтметку         (холстД);
          холстД.продолжениеОтмен:=холстД.началоОтмен;
          холстД.началоОтмен:=0
        КОН;
        ЕСЛИ
              холстД.замена
        ТО
          ДЗаменитьЗнак           (холстД,посылка.знак)
        ИНАЧЕ
          ДВставитьЗнак           (холстД,посылка.знак)
        КОН;
        ЕСЛИ
              холстД.однаСтрока
            И
             (холстД.памяткаД # ПУСТО)
        ТО
          холстД.продолжениеОтмен:=холстД.началоОтмен;
          холстД.началоОтмен:=0;
          ДНайтиСтрокуВПамятке    (холстД)
        КОН
      ИНАЧЕ                                            (* управляющие клавиши *)
        ЕСЛИ
                 (кодПосылки >= 21H)
              И
                 (кодПосылки <= 28H)
        ТО                                             (* клавиши перемещения *)
          ЕСЛИ
                холстД.однаСтрока
              И
               ( (кодПосылки = 26H)
                ИЛИ
                 (кодПосылки = 28H)
               )
          ТО                                                       (* стрелки *)
            ЕСЛИ
                  посылка.упрКонтр
                И
                 (холстД.памяткаД # ПУСТО)
            ТО
              ДВыбратьСтрокуВПамятке   (холстД)
            ИНАЧЕ
              посылка.код:=кодПосылки
            КОН
          ИНАЧЕ
            ДОтметкаПеремещение(холстД,
                                   кодПосылки,
                       посылка.упрШифт,
                      посылка.упрКонтр,
                      посылка.упрАльт);
          КОН;
          ПосылкаИзменения(холстД);
          холстД.продолжениеОтмен:=0;
          ВОЗВРАТ
        ИНАЧЕ
          холстД.отметка.изменяемая:=ОТКЛ
        КОН;
        ЕСЛИ
            посылка.упрКонтр
        ТО
          ВЫБРАТЬ кодПосылки ИЗ
(* BS  *)       | 08H: ДУдалитьСловоСлева    (холстД)
(* "S" *)       | 53H: ДЗнакВлевоСУпором     (холстД)
(* "T" *)       | 54H: ДУдалитьСловоСправа   (холстД)
(* Del *)       | 2EH: ДУдалитьСловоСправа   (холстД)
(* Ins *)       | 2DH: ДПереписатьВОбменник  (холстД)
(* "C" *)       | 43H: ДПереписатьВОбменник  (холстД)
(* "V" *)       | 56H: ДПереписатьИзОбменника(холстД)
(* "X" *)       | 58H: ДПеренестиВОбменник   (холстД)
(* "Z" *)       | 5AH: ДОтменить             (холстД)
(* "A" *)       | 41H: ДОтметитьВсё          (холстД)
(* "D" *)       | 44H: ДУдалитьОтметку       (холстД)
(* "U" *)       | 55H: ДСнятьОтметку         (холстД)
(* "P" *)       | 50H: ДПереписатьОтметку    (холстД)
(* "M" *)       | 4DH: ДПеренестиОтметку     (холстД)
(* "N" *)       | 4EH: ДВНачалоРамки         (холстД)
(* "E" *)       | 45H: ДВКонецРамки          (холстД)
(* "K" *)       | 4BH: ДУдалитьДоКонцаСтроки (холстД)
(* "Y" *)       | 59H: ДУдалитьСтроку        (холстД)
          ИНАЧЕ
            ЕСЛИ
                 (кодПосылки >= 30H)
                И
                 (кодПосылки <= 39H)
            ТО                 (* вешка *)
              ДВешка(холстД,
                     кодПосылки-30H,
                     посылка.упрШифт ИЛИ (Ввод.пКонтр В посылка.упрКнопки)
                    );
              ВОЗВРАТ
            КОН;
            посылка.код:=кодПосылки
          КОН
        АЕСЛИ
            посылка.упрАльт
        ТО
          ВЫБРАТЬ кодПосылки ИЗ
(* BS  *)       | 08H: ДОтменить             (холстД)
(* "D" *)       | 44H: ДУдалитьДоКонцаСтроки (холстД)
(* "U" *)       | 55H: ДСдвинутьВлево        (холстД)
(* "I" *)       | 49H: ДСдвинутьВправо       (холстД)
          ИНАЧЕ                        
            посылка.код:=кодПосылки
          КОН                          
        АЕСЛИ
            посылка.упрШифт
        ТО
          ВЫБРАТЬ кодПосылки ИЗ
(* Ins *)       | 2DH: ДПереписатьИзОбменника(холстД)
(* Del *)       | 2EH: ДПеренестиВОбменник   (холстД)
          ИНАЧЕ                        
            посылка.код:=кодПосылки
          КОН                          
        ИНАЧЕ
          ВЫБРАТЬ кодПосылки ИЗ      
(* BS  *)       | 08H: ДУдалитьЗнакСлева     (холстД)
(* Ent *)       | 0DH: ЕСЛИ
                            холстД.однаСтрока
                       ТО
                          посылка.код:=кодПосылки
                       ИНАЧЕ
                         ДНоваяСтрока        (холстД)
                       КОН;
(* Ins *)       | 2DH: ДСменаЗамены          (холстД)
(* Del *)       | 2EH: ДУдалитьЗнак          (холстД)
          ИНАЧЕ
                          посылка.код:=кодПосылки
          КОН
        КОН;
        ЕСЛИ    холстД.однаСтрока
            И
                холстД.отметка.существует
            И
             НЕ холстД.отметка.изменяемая
        ТО
         ДСнятьОтметку(холстД)
        КОН
      КОН;
      ПосылкаИзменения(холстД);
                       холстД.продолжениеОтмен:=холстД.началоОтмен
  | Ввод.нОтМышки:
      ЕСЛИ
           Ввод.прокрут В посылка.события
      ТО
        ЕСЛИ
             холстД.однаСтрока
        ТО
          ДВыбратьСтрокуВПамятке       (холстД)
        ИНАЧЕ
          прокрут:=посылка.прокрут;
          ПОКА прокрут > 0 ВЫП
            ДПрокруткаВверх            (холстД);
            УМЕНЬШИТЬ(прокрут)
          КОН;
          ПОКА прокрут < 0 ВЫП
            ДПрокруткаВниз             (холстД);
            УВЕЛИЧИТЬ(прокрут)
          КОН
        КОН
      ИНАЧЕ
        ДПереместитьУказку             (холстД,посылка.к,посылка.с)
      КОН;
      ПосылкаИзменения(холстД);
      посылка.отработана:=ВКЛ;
      холстД.продолжениеОтмен:=0
  ИНАЧЕ
  КОН             
КОН Приём;


(*============================================================================* 
 * взаимодействие с холстом - локальные и общедоступные задачи
 *============================================================================*)

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ПосылкаИзменения(холстД:Холст.Доступ);
ПЕР
  полеД:Поле.Доступ;
  посылка:Холст.нПосылка;
УКАЗ
  ЕСЛИ
       холстД.отменыПоз > холстД.отмены.поз
  ТО
       холстД.отменыПоз:=-1
  КОН;
  ЕСЛИ
       холстД.отменыПоз = холстД.отмены.поз
  ТО
       холстД.изменён:=" "
  ИНАЧЕ
       холстД.изменён:="*"
  КОН;
                    посылка.холстД:=холстД;
          (* преобразование
                            полеД             из Рамка.Доступ в
                                  Поле.Доступ <- Рамка.Доступ                 *)
              полеД:=холстД.полеД(Поле.Доступ);

  полеД.Приём(полеД,посылка)
КОН ПосылкаИзменения;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ОчиститьХолст(холстД:Холст.Доступ);
(*
 * Цель: привести в начальное состояние холст 
*)
ПЕР
  вешка:ЦЕЛ;
УКАЗ
  холстД.рамка.с:=0;
  холстД.рамка.к:=0;
  холстД.указка.с:=0;
  холстД.указка.к:=0;
  ОчиститьОтметку(холстД.отметка);
  ОчиститьЗнаки  (холстД.знаки);
  ОчиститьОтмены (холстД.отмены);
  холстД.пс:=-1;
  холстД.замена:=ОТКЛ;
  холстД.перваяСтрокаД   :=ПУСТО;
  холстД.последняяСтрокаД:=ПУСТО;
  холстД.верхняяСтрокаД  :=ПУСТО;
  холстД.текущаяСтрокаД  :=ПУСТО;

  ОТ вешка:=0 ДО 9 ВЫП
    холстД.вешка[вешка].рамка.с:=0;
    холстД.вешка[вешка].рамка.к:=0;
    холстД.вешка[вешка].указка.с:=-1;
    холстД.вешка[вешка].указка.к:=-1
  КОН;

  холстД.началоОтмен:=0;
  холстД.продолжениеОтмен:=0;
  холстД.отменыПоз:=холстД.отмены.поз;
  холстД.имяФ:="";
  холстД.имя:="";
КОН ОчиститьХолст;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ПерваяСтрокаХолста(холстД:Холст.Доступ);
(*
 * Цель: создать на холсте 1-ю строку
 *)
ПЕР
                           строкаД:ДкЗвенуСтрока;
УКАЗ
                   СОЗДАТЬ(строкаД);
                           строкаД.пк:= -1;
  холстД.пс:=0;
  холстД.перваяСтрокаД   :=строкаД;
  холстД.последняяСтрокаД:=строкаД;
  холстД.верхняяСтрокаД  :=строкаД;
  холстД.текущаяСтрокаД  :=строкаД;
КОН ПерваяСтрокаХолста;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       СоздатьХолст(верх,лево,строк,колонок:ЦЕЛ):Холст.Доступ;
ПЕР
                    холстД:Холст.Доступ;
УКАЗ
            СОЗДАТЬ(холстД);
  Надел.Подготовить(холстД,
                      верх,
                      лево,
                     строк,
                   колонок,
 {Надел.признакВыбираемый},
                     Приём   (* посылок для <наделД> *)
                   );
      ОчиститьХолст(холстД);
            ВОЗВРАТ холстД
КОН СоздатьХолст;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       СоздатьИзФайла-(верх, лево,
                       строк,колонок :ЦЕЛ;
                                имяФ-:ЦЕПЬ):Холст.Доступ;
(*
 * Цель:  создаёт холст и заполняет его содержимым файла
 *)
ПЕР
          строкаД,
    перваяСтрокаД,
 последняяСтрокаД:ДкЗвенуСтрока;
                к:ЦЕЛ;
   путь:Файл.ВПути;
    тип:Файл.ВТипа;
  потокД:ИзФайла.ДкПотоку;
  холстД:Холст.Доступ;

УКАЗ
  холстД:=СоздатьХолст(верх,лево,строк,колонок);
  холстД.цветОбычный:=Надел.цветХолста;
  холстД.цветОтметки:=Надел.цветОтметкиХолста;

       СПИСАТЬ(имяФ,холстД.имяФ);

  Файл.РазобратьИмя(холстД.имяФ,путь,холстД.имя,тип);

       потокД:=ИзФайла.Открыть(имяФ);
  ЕСЛИ
       потокД # ПУСТО
  ТО
       потокД.цВидЗнаков:=ИзФайла.знУни;
                 строкаД:=ПУСТО;
           перваяСтрокаД:=ПУСТО;
        последняяСтрокаД:=ПУСТО;
    ПОКА 
         ИзФайла.НачалоСтроки(потокД)
    ВЫП
                       СОЗДАТЬ(строкаД);
         ИзФайла.Строку(потокД,строкаД.цепь);
             строкаД.пк:=ДЛИНА(строкаД.цепь)-1;
      ЕСЛИ
           перваяСтрокаД = ПУСТО
      ТО
           перваяСтрокаД:=строкаД
      ИНАЧЕ
        последняяСтрокаД.слеД:=строкаД;
        строкаД.преД:=последняяСтрокаД
      КОН;
      УВЕЛИЧИТЬ(холстД.пс);
      последняяСтрокаД:=строкаД
    КОН;
    ИзФайла.Закрыть(потокД);
    холстД.верхняяСтрокаД:=перваяСтрокаД;
    холстД.текущаяСтрокаД:=перваяСтрокаД;
    холстД.перваяСтрокаД:=перваяСтрокаД;
    холстД.последняяСтрокаД:=последняяСтрокаД
  ИНАЧЕ
  КОН;
  ЕСЛИ
       холстД.пс = -1
  ТО                                                   (* ничего не прочитали *)
    ПерваяСтрокаХолста(холстД)
  КОН;
  ВОЗВРАТ холстД
КОН СоздатьИзФайла;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ЗаписатьВФайл-(холстД :Холст.Доступ;
                        имяФ-:ЦЕПЬ):КЛЮЧ;
(*
 * Цель:  запись содержимого холста в файл с именем <имя>
 *)
ПЕР
   потокД:ВФайл.ДкПотоку;
  строкаД:ДкЗвенуСтрока;
  к:ЦЕЛ;
УКАЗ
        потокД:=ВФайл.Открыть(имяФ);
  ЕСЛИ
        потокД = ПУСТО
  ТО
    ВОЗВРАТ ОТКЛ
  КОН;
  потокД.цВидЗнаков:=ВФайл.знУни;

         строкаД:=холстД.перваяСтрокаД;
  ПОКА
         строкаД # ПУСТО
  ВЫП
    ОТ к:=0 ДО строкаД.пк ВЫП
      ВФайл.ЗнакЦепи(потокД,строкаД.цепь[к])
    КОН;
         строкаД:=строкаД.слеД;
    ЕСЛИ
         строкаД # ПУСТО
    ТО
      ВФайл.ЗнакЦепи(потокД,0DX);
      ВФайл.ЗнакЦепи(потокД,0AX)
    КОН
  КОН;
  ВФайл.Закрыть(потокД);
  ВОЗВРАТ ВКЛ
КОН ЗаписатьВФайл;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       СохранитьВФайл-(холстД:Холст.Доступ):КЛЮЧ;
(*
 * Цель:  сохранение содержимого холста в свой файл с удалением отмен
 *)
УКАЗ
  ЕСЛИ
       Холст.ЗаписатьВФайл(холстД,холстД.имяФ)
  ТО
    холстД.отменыПоз:=холстД.отмены.поз;
    ПосылкаИзменения(холстД);
    ВОЗВРАТ ВКЛ
  КОН;
    ВОЗВРАТ ОТКЛ
КОН СохранитьВФайл;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       СоздатьСтроку-(верх,лево,
                        колонок :ЦЕЛ;
                        памяткаД:Памятка.Доступ):Холст.Доступ;
ПЕР
  холстД:Холст.Доступ;
УКАЗ
  холстД:=СоздатьХолст(верх,лево,1,колонок);

  холстД.однаСтрока:=ВКЛ;
  холстД.памяткаД:=памяткаД;
  холстД.цветОбычный:=Надел.цветСтроки;
  холстД.цветОтметки:=Надел.цветОтметкиСтроки;

  ПерваяСтрокаХолста(холстД);
  ЕСЛИ
       (памяткаД # ПУСТО)
      И
       (памяткаД.строк > 0)
  ТО
    Холст.ЗагрузитьСтрокуИзЦепи(холстД,памяткаД.рСтроки[0]^)
  КОН;
  ВОЗВРАТ холстД
КОН СоздатьСтроку;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА                                                         (*(Холст.Вид)*)
       ЗагрузитьСтрокуИзЦепи-(холстД :Холст.Доступ;
                                цепь-:ЦЕПЬ);
(*
 * Цель:  загрузка из цепочки <цепь> текущей строки
 *)
ПЕР
  строкаД:ДкЗвенуСтрока;
        к:ЦЕЛ;
УКАЗ
  строкаД:=холстД.текущаяСтрокаД;

  СПИСАТЬ(цепь,строкаД.цепь);

  строкаД.пк:=ДЛИНА(строкаД.цепь)-1;

                холстД.указка.к:=строкаД.пк+1;
  НачалоОтметки(холстД.отметка,ОТКЛ,0,0);

  ИзменитьОтметку(холстД.отметка,0,строкаД.пк+1);
                  холстД.отметка.изменяемая:=ОТКЛ
КОН ЗагрузитьСтрокуИзЦепи;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       СтрокуВЦепь-(холстД :Холст.Доступ;
                      цепь+:ЦЕПЬ);
(*
 * Цель:  запись в цепочку <цепь> текущей строки
 *)
ПЕР
  строкаД:ДкЗвенуСтрока;
УКАЗ
  строкаД:=холстД.текущаяСтрокаД;
  строкаД.цепь[строкаД.пк+1]:=0X;
  СПИСАТЬ(строкаД.цепь,цепь)
КОН СтрокуВЦепь;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       СтрокуВПамятку-(холстД:Холст.Доступ);
(*
 * Цель:  сохранение в памятке текущей строки
 *)
ПЕР
  строкаД:ДкЗвенуСтрока;
УКАЗ
  строкаД:=холстД.текущаяСтрокаД;
  строкаД.цепь[строкаД.пк+1]:=0X;
  Памятка.ДобавитьСтроку(холстД.памяткаД,строкаД.цепь)
КОН СтрокуВПамятку;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ПонятиеВЦепь-(холстД :Холст.Доступ;
                       цепь+:ЦЕПЬ);
(*
 * Цель:  запись в цепочку <цепь> текущего понятия
 *)
ПЕР
  строкаД:ДкЗвенуСтрока;
     нач,
     кон :ЦЕЛ;

 (*............................................подЗадача...*)
  ЗАДАЧА ЗнакПонятия(знак:ЗНАК):КЛЮЧ;
  УКАЗ
    ВОЗВРАТ оЗнака.ВСлове(знак) ИЛИ (знак = ".")
  КОН ЗнакПонятия;
   
УКАЗ
  строкаД:=холстД.текущаяСтрокаД;
  кон:=холстД.указка.к;
  нач:=кон-1;
                                                               (* поиск конца *)
  КОЛЬЦО
    ЕСЛИ кон > строкаД.пк ТО
      кон:=строкаД.пк;
      ВЫХОД
    КОН;
    ЕСЛИ НЕ ЗнакПонятия(строкаД.цепь[кон]) ТО
      УМЕНЬШИТЬ(кон);
      ВЫХОД
    КОН;
    УВЕЛИЧИТЬ(кон)
  КОН;
                                                              (* поиск начала *)
  КОЛЬЦО
    ЕСЛИ нач < 0 ТО
      нач:=0;
      ВЫХОД
    КОН;
    ЕСЛИ НЕ ЗнакПонятия(строкаД.цепь[нач]) ТО
      УВЕЛИЧИТЬ(нач);
      ВЫХОД
    КОН;
    УМЕНЬШИТЬ(нач)
  КОН;
                                                   (* убираем начальные точки *)
  ПОКА (строкаД.цепь[нач] = ".") И (нач < строкаД.пк) ВЫП
    УВЕЛИЧИТЬ(нач)
  КОН;
                                                         (* списываем понятие *)
  ЕСЛИ нач <= кон ТО
    оЦепи.Часть(строкаД.цепь,цепь,нач,кон-нач+1)
  ИНАЧЕ
    цепь[0]:=0X
  КОН
КОН ПонятиеВЦепь;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ВыставитьУказку-(холстД:Холст.Доступ; с,к:ЦЕЛ);
УКАЗ
  ОграничитьЦел(с,0,холстД.пс);
  ОграничитьЦел(к,0,ПК);
  ПоставитьУказку(холстД,с,к);
  ОтрисовкаРамки(холстД);
  ПереместитьУказкуНаХолсте(холстД);
  ПосылкаИзменения(холстД)
КОН ВыставитьУказку;


(*============================================================================*
 * поиск образца из <Холст.поиск> - локальные задачи
 *============================================================================*)

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ИскатьВСтрокеВперёд(строкаД:ДкЗвенуСтрока);
(*
 * Цель:  поиск образца из <Холст.поиск> в строке <строкаД>
 *        начиная с колонки <Холст.поиск.точка.к> по алгоритму Боуера-Мура
 *)
ПЕР
  знак:ЗНАК;
  кс,
  ко:ЦЕЛ;
  длинаСтрокиПлюс1:ЦЕЛ;
  смещение:ЦЕЛ;
УКАЗ
  длинаСтрокиПлюс1:=строкаД.пк+1;

  УВЕЛИЧИТЬ(Холст.поиск.точка.к,
            Холст.поиск.длинаОбразца);
  ЕСЛИ
            Холст.поиск.точка.к > длинаСтрокиПлюс1
  ТО
    ВОЗВРАТ
  КОН;
  ПОВТОРЯТЬ
    ко:=Холст.поиск.длинаОбразца;
    кс:=Холст.поиск.точка.к;
    ПОВТОРЯТЬ
      УМЕНЬШИТЬ(кс);
      УМЕНЬШИТЬ(ко);
      ЕСЛИ
           ко < 0
      ТО                           (* нашли образец *)
        ЕСЛИ Холст.поиск.целые ТО
          ЕСЛИ
               ( (кс < 0)
                ИЛИ
                   НЕ оЗнака.ВСлове(строкаД.цепь[кс])
               )
              И
               ( (Холст.поиск.точка.к = длинаСтрокиПлюс1)
                ИЛИ
                   НЕ оЗнака.ВСлове(строкаД.цепь[Холст.поиск.точка.к])
               )
          ТО
            Холст.поиск.нашли:=ВКЛ;
            УМЕНЬШИТЬ(Холст.поиск.точка.к,
                      Холст.поиск.длинаОбразца); 
            ВОЗВРАТ 
          ИНАЧЕ                    (* это не слово *)
            ко:=0;
            знак:=0X
          КОН
        ИНАЧЕ
                      Холст.поиск.нашли:=ВКЛ;
            УМЕНЬШИТЬ(Холст.поиск.точка.к,
                      Холст.поиск.длинаОбразца); 
          ВОЗВРАТ 
        КОН
      ИНАЧЕ
        знак:=строкаД.цепь[кс]
      КОН;
      ЕСЛИ
           НЕ Холст.поиск.заглавные
      ТО
        знак:=оБуквы.ВСтрочную(знак)
      КОН
    ДО знак # Холст.поиск.образец[ко];

    УВЕЛИЧИТЬ(Холст.поиск.точка.к)

         смещение:= Холст.поиск.смещение[ВЦЕЛ(знак)];
    ЕСЛИ
         смещение = Холст.поиск.длинаОбразца
    ТО                                       (* нет такой буквы *)
         смещение:=ко+1
    КОН;
    УВЕЛИЧИТЬ(Холст.поиск.точка.к,смещение)

  ДО Холст.поиск.точка.к > длинаСтрокиПлюс1
КОН ИскатьВСтрокеВперёд;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА
       ИскатьВСтрокеНазад(строкаД:ДкЗвенуСтрока);
(*
 * Цель:  поиск образца из <Холст.поиск> в строке <строкаД>,
 *        начиная с колонки <Холст.поиск.точка.к> по алгоритму Боуера-Мура
 *)
ПЕР
              знак:ЗНАК;
               кс,
               ко :ЦЕЛ;
  длинаСтрокиПлюс1:ЦЕЛ;
         смещение :ЦЕЛ;
УКАЗ
                                   длинаСтрокиПлюс1:=строкаД.пк+1;
  ЕСЛИ
       (Холст.поиск.длинаОбразца > длинаСтрокиПлюс1)
      ИЛИ
       (Холст.поиск.точка.к < 0)
  ТО
    ВОЗВРАТ
  КОН;
  ЕСЛИ
        Холст.поиск.точка.к + Холст.поиск.длинаОбразца > длинаСтрокиПлюс1
  ТО
        Холст.поиск.точка.к:=длинаСтрокиПлюс1 - Холст.поиск.длинаОбразца
  КОН;
  УМЕНЬШИТЬ(Холст.поиск.точка.к);
  ПОВТОРЯТЬ
    ко:=-1;
    кс:=Холст.поиск.точка.к;
    ПОВТОРЯТЬ
      УВЕЛИЧИТЬ(кс);
      УВЕЛИЧИТЬ(ко);
      ЕСЛИ
           ко = Холст.поиск.длинаОбразца
      ТО                                 (* нашли образец *)
        ЕСЛИ    Холст.поиск.целые ТО
          ЕСЛИ
               ( (кс = длинаСтрокиПлюс1)
                ИЛИ
                   НЕ оЗнака.ВСлове(строкаД.цепь[кс])
               )
              И
               ( (Холст.поиск.точка.к = -1)
                ИЛИ
                   НЕ оЗнака.ВСлове(строкаД.цепь[Холст.поиск.точка.к])
               )
          ТО
                      Холст.поиск.нашли:=ВКЛ;
            УВЕЛИЧИТЬ(Холст.поиск.точка.к); 
            ВОЗВРАТ 
          ИНАЧЕ                      (* это не слово *)
            ко:=0;
            знак:=0X
          КОН
        ИНАЧЕ
                    Холст.поиск.нашли:=ВКЛ;
          УВЕЛИЧИТЬ(Холст.поиск.точка.к); 
          ВОЗВРАТ 
        КОН
      ИНАЧЕ
        знак:=строкаД.цепь[кс]
      КОН;
      ЕСЛИ
           НЕ Холст.поиск.заглавные
      ТО
        знак:=оБуквы.ВСтрочную(знак)
      КОН
    ДО знак # Холст.поиск.образец[ко];

    УМЕНЬШИТЬ(Холст.поиск.точка.к)

         смещение:= Холст.поиск.смещение[ВЦЕЛ(знак)];
    ЕСЛИ
         смещение = Холст.поиск.длинаОбразца
    ТО                                            (* нет такой буквы *)
         смещение:= Холст.поиск.длинаОбразца - ко
    КОН;
    УМЕНЬШИТЬ(Холст.поиск.точка.к,смещение)

  ДО Холст.поиск.точка.к < -1
КОН ИскатьВСтрокеНазад;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       Искать(холстД:Холст.Доступ);
(*
 * Цель: поиск образца из набора <Холст.поиск>
 *)
УКАЗ
       Холст.поиск.нашли:=ОТКЛ;
  ЕСЛИ
       Холст.поиск.обратный
  ТО
    УМЕНЬШИТЬ(Холст.поиск.точка.к);            
                                          (* ищем дальше *)
    КОЛЬЦО
      ИскатьВСтрокеНазад(Холст.поиск.строкаД);
      ЕСЛИ
            Холст.поиск.нашли
      ТО
        ЕСЛИ
            Холст.поиск.отмеченная
        ТО
          ЕСЛИ
               ВнутриОтметки(холстД.отметка,Холст.поиск.точка)
          ТО
            ВЫХОД 
          ИНАЧЕ
            Холст.поиск.нашли:=ОТКЛ
          КОН
        ИНАЧЕ
          ВЫХОД 
        КОН
      КОН;
  УМЕНЬШИТЬ(Холст.поиск.точка.с);
            Холст.поиск.строкаД:=поиск.строкаД.преД;
      ЕСЛИ
            Холст.поиск.строкаД = ПУСТО
      ТО
        ВЫХОД
      КОН;
            Холст.поиск.точка.к:=Холст.поиск.строкаД.пк
    КОН
  ИНАЧЕ
  УВЕЛИЧИТЬ(Холст.поиск.точка.к);
                                          (* ищем дальше *)
    КОЛЬЦО
      ИскатьВСтрокеВперёд(Холст.поиск.строкаД);
      ЕСЛИ
            Холст.поиск.нашли
      ТО
        ЕСЛИ
            Холст.поиск.отмеченная
        ТО
          ЕСЛИ
               ВнутриОтметки(холстД.отметка,Холст.поиск.точка)
          ТО
            ВЫХОД 
          ИНАЧЕ
            Холст.поиск.нашли:=ОТКЛ
          КОН
        ИНАЧЕ
          ВЫХОД 
        КОН
      КОН;
  УВЕЛИЧИТЬ(Холст.поиск.точка.с);
            Холст.поиск.строкаД:=Холст.поиск.строкаД.слеД;
      ЕСЛИ
            Холст.поиск.строкаД = ПУСТО
      ТО
        ВЫХОД
      КОН;
            Холст.поиск.точка.к:=0
    КОН
  КОН
КОН Искать;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ОтрисовкаДляЗамены(холстД:Холст.Доступ);
(*
 * Цель: выставить рамку в соответствии с точкой поиска
 *       и перерисовать рамку с выделением найденной подстроки
 *)
ПОСТ
  запас=15;  (* отступ сверху (или снизу) при выходе образца за границу рамки *)
ПЕР
        строк,колонок,смещение:ЦЕЛ;
УКАЗ
  холстД.указка:=Холст.поиск.точка;
                                                           (* продвинем рамку *)
       строк:=Холст.поиск.точка.с-холстД.рамка.с;
  ЕСЛИ
       строк > холстД.пср
  ТО
    смещение:=строк-холстД.пср+запас
  АЕСЛИ
       строк < 0
  ТО
    смещение:=строк-запас
  ИНАЧЕ
    смещение:=0
  КОН;
  УВЕЛИЧИТЬ(холстД.рамка.с,смещение);
  ЕСЛИ
       холстД.рамка.с < 0
  ТО
       холстД.рамка.с:=0
  КОН;
  холстД.верхняяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,
                                         холстД.рамка.с);
       колонок:=Холст.поиск.точка.к-холстД.рамка.к;
  ЕСЛИ
       колонок > холстД.пкр-Холст.поиск.длинаОбразца+1
  ТО
    смещение:=колонок-холстД.пкр+Холст.поиск.длинаОбразца-1
  АЕСЛИ
       колонок < 0
  ТО
    смещение:=колонок
  ИНАЧЕ
    смещение:=0
  КОН;
  УВЕЛИЧИТЬ(холстД.рамка.к,смещение);
                                                                 (* отрисовка *)
  холстД.текущаяСтрокаД:=СледующаяСтрока(холстД.перваяСтрокаД,Холст.поиск.точка.с);
  Холст.поиск.отметка:=ВКЛ;
  ОтрисовкаРамки(холстД);
  Холст.поиск.отметка:=ОТКЛ
КОН ОтрисовкаДляЗамены;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ЗнакиВставить(холстД :Холст.Доступ;
                    строкаД :ДкЗвенуСтрока;
                     начало-:Холст.нТочка);
(*
 * Цель:  вставить цепочку из <холстД.знаки> в <начало> строки <строкаД>
 *)
ПЕР
  знак:ЗНАК;
  к,ко,длина,вешка:ЦЕЛ;
  цепь:РядЗнаковСтрокиХолста;

 (*............................................подЗадача...*)
  ЗАДАЧА ПравуюТочкуВправо(точка+:Холст.нТочка);
  УКАЗ
    ЕСЛИ
         (точка.с = начало.с)
        И
         (точка.к >= начало.к)
    ТО
      УВЕЛИЧИТЬ(точка.к,длина)
    КОН
  КОН ПравуюТочкуВправо;

УКАЗ
                                       (* считываем цепь *)
              длина:=-1;
  ПОВТОРЯТЬ
    УВЕЛИЧИТЬ(длина);
    знак:=ЗнакИзЗнаков(холстД.знаки);
    цепь[длина]:=знак
  ДО знак = 0X;
                                       (* раздвигаем при необходимости строку *)
  ДобавитьПробелы(строкаД,начало.к-1);
  ко:=строкаД.пк;
  ПОКА ко >= начало.к ВЫП
    строкаД.цепь[ко+длина]:=строкаД.цепь[ко];
    УМЕНЬШИТЬ(ко)
  КОН;
    УВЕЛИЧИТЬ(строкаД.пк,длина);
                                       (* переписываем цепь *)
  к:=начало.к;
  ОТ ко:=0 ДО длина-1 ВЫП
    строкаД.цепь[к]:=цепь[ко];
    УВЕЛИЧИТЬ(к)
  КОН;
                                       (* исправляем точки *)
  ОТ вешка:=0 ДО 9 ВЫП
    ПравуюТочкуВправо(холстД.вешка[вешка].указка)
  КОН
КОН ЗнакиВставить;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       УдалитьЧасть(холстД :Холст.Доступ;
                   строкаД :ДкЗвенуСтрока;
                    начало-:Холст.нТочка;
                     длина :ЦЕЛ);
ПЕР
  вешка:ЦЕЛ;
  к,пк,послк:ЦЕЛ;

 (*...........................................подЗадача...*)
  ЗАДАЧА ПравуюТочкуВлево(точка+:Холст.нТочка);
  УКАЗ
    ЕСЛИ 
         (точка.с = начало.с)
        И
         (точка.к >= начало.к)
    ТО
      ЕСЛИ точка.к < послк ТО
        точка.к:=начало.к
      ИНАЧЕ
        УМЕНЬШИТЬ(точка.к,длина)
      КОН
    КОН
  КОН ПравуюТочкуВлево;

УКАЗ
  послк:=начало.к+длина;
                                                   (* удаляем знаки *)
  пк:=строкаД.пк;
  ЕСЛИ послк > пк ТО
    строкаД.пк:=начало.к-1
  ИНАЧЕ
    к:=начало.к;
    УМЕНЬШИТЬ(строкаД.пк,длина);
    ПОКА послк <= пк ВЫП
      строкаД.цепь[к]:=строкаД.цепь[послк];
      УВЕЛИЧИТЬ(к);
      УВЕЛИЧИТЬ(послк)
    КОН
  КОН;
                                                   (* исправляем точки *)
  ОТ вешка:=0 ДО 9 ВЫП
    ПравуюТочкуВлево(холстД.вешка[вешка].указка)
  КОН
КОН УдалитьЧасть;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       Заменить(холстД:Холст.Доступ);
ПЕР
  отмена:нОтмена;
  к:ЦЕЛ;
УКАЗ
  отмена.родОтмены:=отменаЗаменить;
  отмена.указка:=Холст.поиск.точка;
  отмена.рамка.с:=Холст.поиск.длинаЗамены; (* запоминаем длину замены *)
  отмена.чПоз:=холстД.знаки.пПоз;
  ДобавитьОтмену(холстД,отмена);
                                              (* запоминаем удаляемую находку *)
  ОТ к:=0 ДО Холст.поиск.длинаОбразца-1 ВЫП
    ЗнакВЗнаки(холстД.знаки,Холст.поиск.строкаД.цепь[Холст.поиск.точка.к+к])
  КОН;
  ЗнакВЗнаки(холстД.знаки,0X);
                                                           (* удаляем находку *)
  УдалитьЧасть(холстД,
               Холст.поиск.строкаД,
               Холст.поиск.точка,
               Холст.поиск.длинаОбразца);
                                          (* временно помещаем в знаки замену *)
  холстД.знаки.чПоз:=холстД.знаки.пПоз;

  ОТ к:=0 ДО ДЛИНА(Холст.поиск.замена) ВЫП
    ЗнакВЗнаки(холстД.знаки,
               Холст.поиск.замена[к])
  КОН;
  холстД.знаки.пПоз:=холстД.знаки.чПоз;
                                                (* вставляем замену из знаков *)
  ЗнакиВставить(холстД,
                Холст.поиск.строкаД,поиск.точка);
      УВЕЛИЧИТЬ(Холст.поиск.замен)
КОН Заменить;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ОЗаменить(холстД :Холст.Доступ;
                 отмена-:нОтмена);                 (* отмена изменений *)
ПЕР
  строкаД:ДкЗвенуСтрока;
УКАЗ
  холстД.указка:=отмена.указка;
  холстД.знаки.чПоз:=отмена.чПоз;
  холстД.знаки.пПоз:=отмена.чПоз;

  строкаД:=СледующаяСтрока(холстД.перваяСтрокаД,холстД.указка.с);

  холстД.текущаяСтрокаД:=строкаД;
                                                            (* удаляем замену *)
  УдалитьЧасть(холстД,строкаД,отмена.указка,отмена.рамка.с);
                                       (* восстанавливаем сохранённую находку *)
  ЗнакиВставить(холстД,строкаД,отмена.указка);
  РамкаПоУказке(холстД) 
КОН ОЗаменить;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА                                                           (*(Холст.Вид)*)
       ИскатьЗаменить-(холстД:Холст.Доступ;
                       далее :КЛЮЧ);
ПЕР
  к:ЦЕЛ;

 (*.....................подЗадача...*)
  ЗАДАЧА ЗаменитьВсё();
  ПЕР
    текст:ЦЕПЬ[100];
  УКАЗ
    ПОВТОРЯТЬ
      Заменить(холстД);
        Искать(холстД)
    ДО НЕ Холст.поиск.нашли;

    ОтрисовкаРамки(холстД);

    Текст.Из4хЦел("Всего произведено замен: %d",
                  Холст.поиск.замен,
                  0,
                  0,
                  0,
                  текст);
    ПолеСВосклицанием.Выполнить("Поиск и замена",
                                  1,
                           ДЛИНА(текст),
        (* преобразование
                                        полеД             из Рамка.Доступ в
                                              Поле.Доступ <- Рамка.Доступ     *)
                                 холстД.полеД(Поле.Доступ),
                                 текст
                               )
  КОН ЗаменитьВсё;

УКАЗ
       Холст.поиск.длинаОбразца:=ДЛИНА(Холст.поиск.образец);
  ЕСЛИ
       Холст.поиск.длинаОбразца = 0
  ТО 
    ПолеСВосклицанием.Выполнить("Поиск и замена",
                                  1,
                                 29,
        (* преобразование
                                        полеД             из Рамка.Доступ в
                                              Поле.Доступ <- Рамка.Доступ     *)
                                 холстД.полеД(Поле.Доступ),
                                " Не задано выражение поиска!"
                               );
    ВОЗВРАТ 
  КОН;
  ЕСЛИ
       НЕ Холст.поиск.заглавные
  ТО
    оЦепи.ВСтрочные(Холст.поиск.образец)
  КОН;
  Холст.поиск.длинаЗамены:=ДЛИНА(Холст.поиск.замена);
  Холст.поиск.замен:=0;
                                                       (* готовим Боуера-Мура *)
  ОТ к:=0 ДО ВЦЕЛ(МАКС(ЗНАК)) ВЫП
    Холст.поиск.смещение[к]:=Холст.поиск.длинаОбразца
  КОН;
  ЕСЛИ
       Холст.поиск.обратный
  ТО
    ОТ к:=Холст.поиск.длинаОбразца-1 ДО 1 ПО -1 ВЫП
       Холст.поиск.смещение[ВЦЕЛ(Холст.поиск.образец[к])]:=к
    КОН
  ИНАЧЕ
    ОТ к:=0 ДО Холст.поиск.длинаОбразца-2 ВЫП
       Холст.поиск.смещение[ВЦЕЛ(Холст.поиск.образец[к])]:=Холст.поиск.длинаОбразца-к-1
    КОН
  КОН;
                                           (* выставим начальную точку поиска *)
  ЕСЛИ
             Холст.поиск.отмеченная
  ТО
    ЕСЛИ
             Холст.поиск.отУказки
         ИЛИ
             далее
    ТО
             Холст.поиск.точка:=холстД.указка;
      ЕСЛИ
           НЕ ВнутриОтметки(холстД.отметка,
                            Холст.поиск.точка)
      ТО
        ЕСЛИ
             Холст.поиск.обратный
        ТО
             Холст.поиск.точка:=холстД.отметка.посл
        ИНАЧЕ
             Холст.поиск.точка:=холстД.отметка.перв
        КОН
      КОН
    ИНАЧЕ
      ЕСЛИ
             Холст.поиск.обратный
      ТО
             Холст.поиск.точка:=холстД.отметка.посл
      ИНАЧЕ
             Холст.поиск.точка:=холстД.отметка.перв
      КОН
    КОН
  ИНАЧЕ                                    (* по всему тексту *)
    ЕСЛИ
             Холст.поиск.отУказки
         ИЛИ
             далее
    ТО
             Холст.поиск.точка:=холстД.указка
    ИНАЧЕ
      ЕСЛИ
             Холст.поиск.обратный
      ТО
             Холст.поиск.точка.с:=холстД.пс;
             Холст.поиск.точка.к:=холстД.текущаяСтрокаД.пк
      ИНАЧЕ
             Холст.поиск.точка.с:=0;
             Холст.поиск.точка.к:=0
      КОН
    КОН
  КОН;
  ЕСЛИ
             Холст.поиск.обратный
  ТО
    ЕСЛИ
          НЕ далее
    ТО
   УВЕЛИЧИТЬ(Холст.поиск.точка.к)
    КОН
  ИНАЧЕ
    ЕСЛИ
          НЕ далее
    ТО
   УМЕНЬШИТЬ(Холст.поиск.точка.к)
    КОН
  КОН;
             Холст.поиск.строкаД:=СледующаяСтрока(холстД.перваяСтрокаД,
                                                  Холст.поиск.точка.с);

                                                          (* начинаем искать *)
  КОЛЬЦО
    Искать(холстД);
    ЕСЛИ
             Холст.поиск.нашли
   ТО
      ЕСЛИ 
             Холст.поиск.заменить
      ТО
        ЕСЛИ
             Холст.поиск.подтверждение
        ТО
          ОтрисовкаДляЗамены(холстД);
          ВЫБРАТЬ
                  ПолеЗамена.Выполнить(
(* преобразование
                                              полеД             из Рамка.Доступ в
                                                    Поле.Доступ <- Рамка.Доступ   *)
                                       холстД.полеД(Поле.Доступ),
                                       Холст.поиск.образец,
                                       Холст.поиск.замена
                                      )
          ИЗ
          | ПолеЗамена.состЗаменить:
              Заменить(холстД)
          | ПолеЗамена.состВсе:
              ЗаменитьВсё;                                     (* подЗадача *)
              ВЫХОД
          | Поле.состОтмена: 
              ВЫХОД
          ИНАЧЕ
          КОН
        ИНАЧЕ
          ЗаменитьВсё;                                         (* подЗадача *)
          ВЫХОД
        КОН
      ИНАЧЕ
        ВыставитьУказку(холстД,
                        Холст.поиск.точка.с,
                        Холст.поиск.точка.к);
        ВЫХОД
      КОН
    ИНАЧЕ
      ОтрисовкаРамки(холстД);

      ПолеСВосклицанием.Выполнить("Строка не найдена",
                                    1,
                                   70,
                (* преобразование
                                          полеД             из Рамка.Доступ в
                                                Поле.Доступ <- Рамка.Доступ   *)
                                   холстД.полеД(Поле.Доступ),
                                   Холст.поиск.образец
                                 );
      ВЫХОД
    КОН
  КОН
КОН ИскатьЗаменить;

КОН Холст.
