====== Фильтрация и обработка текста ======
Пример фильтрации текста при помощи сканера (TextMappers.Scanner) и вывода результата в новое окно.
===== Задача =====
Подсчитать количество целых чисел и их сумму в выделенном тексте активного текстового документа (АТД). Результаты показать в новом документе.
===== Алгоритм =====
==== Основной ====
Построение алгоритма методом пошагового уточнения начинается с одного единственного шага "решить задачу", который мы запишем так:
Обработать АТД
Вывести результаты
Обработка АТД, по условию задачи, заключается в обработке выделенного текста. При этом нужно учесть, что АТД не всегда есть:
Если есть АТД, то
  Получить АТД;
  Обработать выделенный текст;
  Вывести результаты
Конец
Соображения касательно обработки выделенного текста аналогичные:
Если есть АТД, то
  Получить АТД;
  Если есть выделение, то
    Получить границы выделения;
    Обработать текст пределах этих границ;
    Вывести результаты  
  Конец
Конец
==== Обработка участка текста документа ====
Обработка текста документа в заданном диапазоне выполняется на основе стандартной схемы цикла - полного прохода по элементам последовательности с фильтрацией:
Получить первый элемент;
Пока элемент получен, выполнять
  Если элемент удовлетворяет условию отбора (проходит через фильтр), то
    Обработать элемент
  Конец;
  Получить следующий элемент
Конец
В нашем случае последовательность представляет собой значения различных типов (целые, вещественные, строковые и т. п.), записанные в указанном промежутке текста. Условие отбора - тип значения - целое.
==== Вывод результатов ====
Вывод результатов - обычный линейный алгоритм:
Создать новый текстовый документ;
Записать количество чисел;
Записать сумму чисел;
Показать документ в новом окне
===== Реализация =====
==== Вариант 1 ====
MODULE ExamplesFilterInText;
  IMPORT TextControllers, TextMappers, TextModels, TextViews, Views;
  PROCEDURE GetInts*;
    VAR
      c: TextControllers.Controller;
      atd, sel: TextModels.Model;  (* активный текстовый документ, копия выделенного текста *)
      beg, end: INTEGER;   (* положение выделения в тексте [beg, end) *)
      num: INTEGER;   (* кол-во считанных чисел *)
      sum: INTEGER;   (* их сумма *)
    PROCEDURE ProcessText;
      VAR
        s: TextMappers.Scanner;
    BEGIN
      s.ConnectTo(sel);   (* подключаем сканер к тексту *)
      (* Читаем и обрабатываем целые из последовательности значений в тексте *)
      sum := 0; num := 0;
      s.Scan;   (* получаем первый элемент *)
      (* Пока получен (не конец текста) *)
      WHILE s.type # TextMappers.eot DO
        IF s.type = TextMappers.int THEN  (* отбираем целые *)
          (* Обрабатываем *)
          sum := sum + s.int;
          INC(num)
        END;
        s.Scan  (* получаем следующий элемент *)
      END
    END ProcessText;
    PROCEDURE PrintResults;
      VAR
        t: TextModels.Model;
        f: TextMappers.Formatter;
    BEGIN
      t := TextModels.dir.New();   (* создаем новый текстовый документ *)
      (* Пишем результат *)
      f.ConnectTo(t);   (* подключаем к тексту форматтер *)
      f.WriteString("Найдено целых чисел: "); f.WriteInt(num); f.WriteLn;
      f.WriteString("Их сумма равна: "); f.WriteInt(sum); f.WriteLn;
      Views.OpenView(TextViews.dir.New(t))  (* открываем документ в новом окне *)
    END PrintResults;
  BEGIN
    c := TextControllers.Focus();   (* получаем контроллер, связанный с АТД *)
    IF c # NIL THEN  (* если есть контроллер (значит есть и АТД) *)
      atd := c.text;   (* берем АТД *)
      IF c.HasSelection() THEN  (* если есть выделение *)
        c.GetSelection(beg, end);   (* получаем границы выделения *)
        sel := TextModels.dir.New();  (* создаем новый текстовый документ *)
        sel.InsertCopy(0, atd, beg, end); (* копируем выделенный текст из АТД *)
        ProcessText;   (* обрабатываем (выделенный) текст *)
        PrintResults  (* печатаем результат *)
      END
    END
  END GetInts;
END ExamplesFilterInText.
==== Вариант 2 ====
MODULE ExamplesFilterInText;
  IMPORT TextControllers, TextMappers, TextModels, TextViews, Views;
  PROCEDURE GetInts*;
    VAR
      s: TextMappers.Scanner;
      beg, end: INTEGER;
      sum, num: INTEGER;
    PROCEDURE ConnectScanner;
      VAR
        c: TextControllers.Controller;
    BEGIN
      s.ConnectTo(NIL);
      c := TextControllers.Focus();
      IF (c # NIL) & c.HasSelection() THEN
        c.GetSelection(beg, end);
        s.ConnectTo(c.text);
        ASSERT(s.rider # NIL)
      END
    END ConnectScanner;
    PROCEDURE PrintSum;
      VAR
        f: TextMappers.Formatter;
        t: TextModels.Model;
    BEGIN
      t := TextModels.dir.New();
      f.ConnectTo(t);
      f.WriteString("Найдено целых чисел:");
      f.WriteInt(num);
      f.WriteLn;
      f.WriteString("Их сумма равна:");
      f.WriteInt(sum);
      f.WriteLn;
      Views.OpenView(TextViews.dir.New(t))
    END PrintSum;
  BEGIN
    ConnectScanner;
    IF s.rider # NIL THEN
      sum := 0;
      num := 0;
      s.SetPos(beg);
      s.Scan;
      WHILE (s.type # TextMappers.eot) & (s.Pos() - 1 <= end) DO
        IF s.type = TextMappers.int THEN
          INC(sum, s.int);
          INC(num)
        END;
        s.Scan
      END;
      PrintSum
    END
  END GetInts;
END ExamplesFilterInText.
(*
@ExamplesFilterInText.GetInts
1 2 3 4 5 6 7 8 9
Mister Jack paid 99.99$ for 10 balls
11  12   13  14
*)
//Авторы: Slava, Темиргалеев Е.Э. Правки: PGR, Кривохатько С.А.//