Холст.отд
Главная     ◄Глагол     ◄Азбука     ◄Задачи на Глаголе     Примеры приложений ►   Среда разработки ►   Отладка программ ►   Отличия от Оберона ►   Отличия от Паскаля ►   Ассемблер ARM ►   Глагол для ARM ►   ? и Ответы
 
 glagol.png Программируем по-русски
 

Основная задача Глагола — дать человеку возможность воплощать свои мысли на языке, близком к его родному языку.

Издатель Глагола
 

 
(*~\Глагол\Отделы\Поле~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                          ОТДЕЛ Холст;
(*============================================================================* 
 * НАЗНАЧЕНИЕ: надел для работы с текстом (подобие консольного ФАР-редактора).
 *   Часть холста, которая ограничена рамкой, выводится на экран.
 *   Текст хранится построчно в виде связки строк.
 *   Строка состоит из ряда знаков <цепь>.
 *   Местоположение на холсте определяется точкой
 *    с порядковым номером строки <с> и колонки <к>.
 *   При изменении текста все связанные с холстом точки
 *    соответственно сдвигаются.
 *   Такими точками являются вешки, границы выделенного куска текста и указка
 *    ввода.
 *   Разделители строк в запоминаемых кусках текста:
 *     0DX - для простого куска
 *     0AX - для вертикального куска
 *============================================================================*)
ИСПОЛЬЗУЕТ
  Надел,
  Поле,
  Памятка,
  ПолеПамятки,
  ПолеСВосклицанием,
  ПолеЗамена,
  ОС     ИЗ "..\Обмен\",
  ЦвЗнак ИЗ "..\Обмен\",
  Окно   ИЗ "..\Обмен\",
  Файл   ИЗ "..\Обмен\",
  Читать ИЗ "..\Обмен\",
  Писать ИЗ "..\Обмен\",
  Ввод   ИЗ "..\Обмен\",
  Текст  ИЗ "..\Числа\",
  Цепь   ИЗ "..\Иное\",
  Буква  ИЗ "..\Иное\",
  Знак   ИЗ "..\Иное\";
ПОСТ
                (* последняя колонка холста (степень 2) *)
<*ЕСЛИ ЗАДАНО("МПГ") ТО*>
  ПК     = 128;
<*ИНАЧЕ*>
  ПК     = 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) И (строка.цепь[строка.пк] = ' ') ВЫП
    УМЕНЬШИТЬ(строка.пк)
  КОН
КОН УбратьПробелы;

(******************************************************************************)
ЗАДАЧА ДобавитьПробелы(строка:Строка; к:ЦЕЛ);
УКАЗ
  ПОКА строка.пк < к ВЫП
    УВЕЛИЧИТЬ(строка.пк);
    строка.цепь[строка.пк]:=' '
  КОН
КОН ДобавитьПробелы;

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

(******************************************************************************)
ЗАДАЧА ИскатьВСтрокеНазад(строка:Строка);
(* Цель:  поиск образца из <поиск> в строке <строка>
 *        начиная с колонки <поиск.точка.к> по алгоритму Боуера-Мура *)
ПЕР
  знак:ЗНАК;
  кс,ко:ЦЕЛ;
  длинас:ЦЕЛ;
  смещение:ЦЕЛ;
УКАЗ
  длинас:=строка.пк+1;
  ЕСЛИ (поиск.длинао > длинас) ИЛИ (поиск.точка.к < 0) ТО ВОЗВРАТ КОН;
  ЕСЛИ поиск.точка.к+поиск.длинао > длинас ТО
    поиск.точка.к:=длинас-поиск.длинао
  КОН;
  УМЕНЬШИТЬ(поиск.точка.к);
  ПОВТОРЯТЬ
    ко:=-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];
  УКАЗ
    ПОВТОРЯТЬ
      Заменить(холст);
      Искать(холст)
    ДО НЕ поиск.нашли;
    ОтрисовкаРамки(холст);
    Текст.ИзЧЦел("Всего произведено замен: %d",поиск.замен,0,0,0,текст);
    ПолеСВосклицанием.Выполнить("Поиск и замена",1,ДЛИНА(текст),холст.поле(Поле.Доступ),
                                 текст)
  КОН ЗаменитьВсё;

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

КОН Холст.

 
 


Вопросы, замечания и предложения высылайте на atimopheyev@yahoo.com

 
Главная     ◄Глагол     ◄Азбука     ◄Задачи на Глаголе     Примеры приложений ►   Среда разработки ►   Отладка программ ►   Отличия от Оберона ►   Отличия от Паскаля ►   Ассемблер ARM ►   Глагол для ARM ►   ? и Ответы