Снимок веб-сервиса Лебедева

Снят скриптом tools/oracle-snapshot.sh для планов 2b и 2c. Настройки запроса: entityType=3 (символы), useBr=false, useP=false, maxNobr=0. Неразрывный пробел показан как _, длинное тире как —.

Вход Выход оракула
Он сказал: "это важно, и т. д." - и ушёл в 1941-1945 гг. Он_сказал: «это важно, и_т.д.»— и_ушёл в_1941-1945_гг.
Тире - вот так. И дефис-минус. Тире_— вот так. И_дефис-минус.
Диапазон 1941-1945 и 10-15 штук Диапазон 1941-1945 и_10-15 штук
Минус -5 градусов и 5-й дом Минус −5 градусов и_5-й дом
Температура 25 C и угол 90 град. Температура 25_C и_угол 90_град.
Формула 3 x 4 = 12 и 2 x 2 Формула 3×4 = 12_и_2×2
Дробь 1/2, 3/4 и 1/4 Дробь 1/2, 3/4 и_1/4
Неравенства 5 <= 6, 7 >= 3, 8 != 9 Неравенства_5 <= 6, 7 >= 3, 8 != 9
Разряды 1000000 и 1 000 000 рублей Разряды 1000000 и_1_000_000 рублей
Копирайт (c) 2026, торговая марка (tm), знак (r) Копирайт ©_2026, торговая марка (tm), знак <sup class="reg">®</sup>
Стрелки -> и <- в тексте Стрелки -> и <- в_тексте
Многоточие... и ещё .... Многоточие... и_ещё ....
Двойная пунктуация!! и ?? и ?! Двойная пунктуация!! и ?? и ?!
Вопрос?.. и восклицание!.. Вопрос?.. и_восклицание!..
"Вложенные "кавычки" внутри" и 'одинарные' «Вложенные „кавычки“ внутри» и ’одинарные’
Апостроф д'Артаньян и 5" дюймов Апостроф д’Артаньян и_5″ дюймов
Инициалы А. С. Пушкин и Пушкин А. С. Инициалы А._С. Пушкин и_Пушкин_А._С.
Сокращения т. д., т. п., т. е., н. э. Сокращения_т._д., т._п., т._е., н._э.
Господин г-н Иванов и т-щ Петров Господин г-н Иванов и_т-щ Петров
Улица ул. Ленина, д. 5, кв. 12 Улица ул. Ленина, д._5, кв._12
Город г. Москва и с. Никольское Город г. Москва и_с. Никольское
Номер № 5 и параграф § 3 Номер №_5_и_параграф §3
Единицы 10 кг, 5 м, 100 км/ч, 3 л Единицы 10_кг, 5_м, 100_км/ч, 3_л
Деньги 100 руб., 50 долл., 5 000 р. Деньги 100_руб., 50_долл., 5_000_р.
Дата 2026-09-09 и 09.09.2026 Дата <nobr class="phone">2026-09-09</nobr> и_09.09.2026
Понедельник, 9 сентября 2026 года Понедельник, 9_сентября 2026 года
Время 10:30 и 10 ч. 30 мин. Время_10:30 и_10_ч.30_мин. <nobr class="phone">+7</nobr>
Телефон +7 (999) 123-45-67 Телефон(999)123-45-67
Сайт www.example.com и почта mail@example.com Сайт www.example.com и_почта mail@example.com
Проценты 50 % и 100% Проценты 50% и_100%
Слово в начале и предлог в конце строки Слово в_начале и_предлог в_конце строки
Повтор повтор слова Повтор повтор слова
Ударение а́ и ё вместо е Ударение а́_и_ё_вместо_е
Кавычки внутри "тега жирный текста" Кавычки внутри «тега <b>жирный</b> текста»
Абзац первый Абзац первый
Абзац второй Абзац второй

Расхождения с нашим Default

Раздел с ручным разбором расхождений, написанный для плана 2b, удалён: он описывал состояние кода до планов 2b, 2c и 2d и к концу плана 2d врал почти в каждом пункте. Проза не падает, когда правило меняют, — в этом и была беда.

Действующий список живёт в коде: словарь Divergences в тесте OracleSnapshotTests. Тест падает и когда совпадение с оракулом сломалось, и когда записанное расхождение исчезло, так что список не может устареть молча. Читаемая проекция списка — docs/oracle/divergences.md, она генерируется тем же тестом.

Что закрыл план 2c

Прогон тех же 36 строк через Default и Lebedev после ветки feature/bind-rules (правила фазы Bind). Ниже только факты.

Закрыто:

  • пункт 1 — расхождение по диапазону лет вынесено в пресет: Lebedev даёт 1941-1945_гг., Default — 1941—1945_гг.;
  • пункт 2 в части единиц, денег, времени, даты и знаков: 10_кг, 100_руб., 10_ч._30_мин., 9_сентября, №~5, §~3. Знак номера и параграфа получают УЗКИЙ неразрывный пробел (U+202F, ГОСТ 16.4), оракул ставит обычный — расхождение осталось, но теперь в выборе символа, а не в наличии отбивки;
  • пункт 4 — в пресете Lebedev: 1_000_000 (разряды разбивает digitGrouping, включённый в этом пресете), Default по-прежнему оставляет обычные пробелы;
  • пункт 5 (знак умножения) и пункт 6 в части (c), (tm), (r) — закрыты планом 2b;
  • пункт 8 в части непоследовательности внутри Default: д._5, кв._12 — обе конструкции «сокращение + число» теперь склеиваются одинаково;
  • пункт 3 в части телефона: +7 (999) 123-45-67 → +7_999_123-45-67. Тег <nobr class="phone"> мы не ставим намеренно — правило Default не создаёт разметку из текста (гарантия 4).

Осталось:

  • пункт 2 в части процентов (50 % → Default 50%, оракул 50_%; в пресетах Gost и Lebedev пробел сохраняется) и температуры (25 C → Default 25 °C с ОБЫЧНЫМ пробелом, оракул 25_C — отбивки перед знаком градуса ни одно из 107 правил не требует);
  • пункт 3 в части ISO-даты: оракул оборачивает её в тег, мы переставляем на 09.09.2026 правилом ru/date/fromISO;
  • пункт 6 в части дюймов (5" остаётся прямой кавычкой) и пункт 7 (одинарные кавычки);
  • пункты 9 и 10 — дефекты фазы Scan вокруг delBeforePunctuation: 8 != 9 и и ?? теряют пробел, четыре точки теряют предшествующий пробел. План 2c их не касался.

Появилось нового: Default склеивает БОЛЬШЕ, чем оракул, из-за правила common/nbsp/beforeShortLastWord: короткий токен с точкой оно считает концом предложения, и любое сокращение получает неразрывный пробел слева — Улица_ул._Ленина, Город_г._Москва, Сокращения_т._д.. Отличить точку конца предложения от точки сокращения без разбора смысла нельзя (правый контекст не помогает: за сокращением часто стоит имя собственное с прописной буквы), а лишний неразрывный пробел безвреден и не противоречит Мильчину, который требует не отрывать сокращение от относящегося к нему слова. Принято осознанно.

Что закрыл план 2d

Строка Сайт www.example.com и почта mail@example.com — единственная в снимке, которой касаются правила последнего плана. Оракул ссылок не расставляет, и Default тоже: правила common/html/url и common/html/e-mail реализованы, но вне Default — они делают тег из текста, а гарантия 4 обещает, что правила по умолчанию так не поступают. Включаются по имени.

Адрес без схемы (www.example.com) не распознаётся ни одним из наших правил: признак ссылки — схема http:// или https://. Это решение, а не пропуск: «www» в тексте бывает частью предложения, и размечать его как адрес по одной этой примете — угадывание.

Висячая пунктуация (ru/optalign/*) в снимке не проверяется вовсе: оракул её тоже не применяет по умолчанию, а без CSS на стороне сайта вывод обоих неотличим от обычного.