<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Цифровые Гуманитарные Науки |</title><link>https://clementgodbarge.com/ru/category/%D1%86%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D1%8B%D0%B5-%D0%B3%D1%83%D0%BC%D0%B0%D0%BD%D0%B8%D1%82%D0%B0%D1%80%D0%BD%D1%8B%D0%B5-%D0%BD%D0%B0%D1%83%D0%BA%D0%B8/</link><atom:link href="https://clementgodbarge.com/ru/category/%D1%86%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D1%8B%D0%B5-%D0%B3%D1%83%D0%BC%D0%B0%D0%BD%D0%B8%D1%82%D0%B0%D1%80%D0%BD%D1%8B%D0%B5-%D0%BD%D0%B0%D1%83%D0%BA%D0%B8/index.xml" rel="self" type="application/rss+xml"/><description>Цифровые Гуманитарные Науки</description><generator>HugoBlox Kit (https://hugoblox.com)</generator><language>ru-ru</language><lastBuildDate>Fri, 02 Oct 2026 00:00:00 +0000</lastBuildDate><image><url>https://clementgodbarge.com/media/icon_hu_64a6c3bec25b3d7b.png</url><title>Цифровые Гуманитарные Науки</title><link>https://clementgodbarge.com/ru/category/%D1%86%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D1%8B%D0%B5-%D0%B3%D1%83%D0%BC%D0%B0%D0%BD%D0%B8%D1%82%D0%B0%D1%80%D0%BD%D1%8B%D0%B5-%D0%BD%D0%B0%D1%83%D0%BA%D0%B8/</link></image><item><title>Новые инструменты, старые привычки</title><link>https://clementgodbarge.com/ru/post/edition-continue/</link><pubDate>Fri, 02 Oct 2026 00:00:00 +0000</pubDate><guid>https://clementgodbarge.com/ru/post/edition-continue/</guid><description>&lt;p&gt;Гуманисты раннего Нового времени, взявшие на вооружение печатный станок, придали изданию форму, которую оно сохраняет по сей день: текст устанавливают, набирают, выпускают один раз, а исправляют — если вообще исправляют — во втором издании, спустя годы. Компьютеры у нас уже полвека, а цифровые издания мы по-прежнему делаем так, словно это печатные книги: доводим текст до конца, публикуем разом, а список опечаток откладываем на потом. Инструменты новые, привычки старые.&lt;/p&gt;
&lt;p&gt;Мой новый урок для &lt;em&gt;Programming Historian en français&lt;/em&gt;,
, ловит новые инструменты на слове. Если TEI-разметка — это код (а это именно код), то её можно версионировать, валидировать и преобразовывать, как любой другой код. Разработчики давно перестали дожидаться готового продукта: каждое изменение автоматически проверяется и выпускается, едва пройдя проверку. Ничто не мешает критическому изданию жить по тем же правилам — публиковать каждое письмо, как только оно размечено и вычитано, и открыто исправлять его всякий раз, когда находится лучшее чтение.&lt;/p&gt;
&lt;h2 id="часть-первая-из-чего-всё-собрано"&gt;Часть первая: из чего всё собрано&lt;/h2&gt;
&lt;p&gt;Первая часть посвящена деталям, которые избавляют издателя от унаследованного порядка работы; все они с открытым исходным кодом:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ODD&lt;/strong&gt; — единый документ, задающий правила разметки проекта;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;схема RELAX NG&lt;/strong&gt;, которая порождается из него и следит за структурой;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;правила Schematron&lt;/strong&gt;, добавляющие редакционные ограничения, которые схеме выразить не под силу;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;скрипт валидации&lt;/strong&gt;, который одной командой проверяет весь корпус и с помощью XSLT выдаёт удобочитаемые результаты.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Примеры взяты из переписки Filippo Cavriana — издания, которое я
. Во второй части к этим деталям добавится цепочка, связывающая их воедино, чтобы каждое изменение в корпусе валидировалось и публиковалось в ту же минуту, когда оно внесено. Урок входит в мой проект
, который ищет способы удешевить научные издания; автоматизация публикации, при которой издателю больше не приходится ждать специалиста в конце цепочки, — одна из самых крупных статей экономии.&lt;/p&gt;
&lt;h2 id="возмущение-отрицание-или-показное-принятие"&gt;Возмущение, отрицание или показное принятие&lt;/h2&gt;
&lt;p&gt;Искусственный интеллект встречают по той же схеме: возмущение, отрицание или показное принятие. Отчасти поэтому я и люблю цифровые гуманитарные науки: мало где этот парадокс виден так отчётливо. Новые инструменты — это приглашение заново продумать, как работать лучше, а не свежий слой краски поверх старой рутины. Этот урок принимает приглашение применительно к изданию текстов. Ждите второй части.&lt;/p&gt;
&lt;p&gt;Спасибо редакторам урока (Daphné Mathelier, Matthias Gille Levenson), рецензентам (Jasmin Macarios, Elsa Van Kote), а также Anisa Hawes.&lt;/p&gt;
&lt;p&gt;Урок находится в открытом доступе:
(DOI:
).&lt;/p&gt;</description></item><item><title>persNamer 1.2: один номер VIAF — девять авторитетных файлов</title><link>https://clementgodbarge.com/ru/post/persnamer-1-2/</link><pubDate>Mon, 07 Sep 2026 00:00:00 +0000</pubDate><guid>https://clementgodbarge.com/ru/post/persnamer-1-2/</guid><description>&lt;p&gt;
задумывался как мелкое удобство: на входе
номер VIAF, на выходе запись &lt;code&gt;&amp;lt;person&amp;gt;&lt;/code&gt; в TEI да тег &lt;code&gt;&amp;lt;persName&amp;gt;&lt;/code&gt;, которым
размечают текст. Больше он ничего не умел, и запись выходила тощей — имя,
две даты, один идентификатор. Версия 1.2, вышедшая сегодня, ничему другому
так и не научилась; зато запись стала такой, что её стоит хранить.&lt;/p&gt;
&lt;h2 id="что-теперь-входит-в-запись-о-персоне"&gt;Что теперь входит в запись о персоне&lt;/h2&gt;
&lt;p&gt;Начнём с имени. В кластере VIAF каждая библиотека-участница держит имя
в своей форме, а старый persNamer брал первую, какая попадётся. Спросите
у него Вольтера — и получите «فولتير،»: по-арабски, с запятой на хвосте,
да ещё и с пустым &lt;code&gt;xml:id&lt;/code&gt; в придачу. Версия 1.2 пересчитывает формы по
всему кластеру и оставляет ту, на которой исходные записи сходятся;
остальные идут следом как &lt;code&gt;&amp;lt;persName type=&amp;quot;variant&amp;quot;&amp;gt;&lt;/code&gt;, по убыванию частоты.
Даты приводятся к норме (&lt;code&gt;1572-08-00&lt;/code&gt; становится &lt;code&gt;1572-08&lt;/code&gt;) и пишутся
дважды — текстом и в атрибуте &lt;code&gt;@when&lt;/code&gt;: именно атрибут и прочтёт любая
обработка, которая вообще понимает даты. Пол и описания добавляются, когда
VIAF их отдаёт.&lt;/p&gt;
&lt;p&gt;Но самое желанное для меня — другое: все идентификаторы, на которые VIAF
ссылается через &lt;code&gt;schema:sameAs&lt;/code&gt; и через собственные идентификаторы
источников, теперь выписаны, каждый своим &lt;code&gt;&amp;lt;idno&amp;gt;&lt;/code&gt; — BnF, GND, Библиотека
Конгресса, SUDOC, Wikidata, ISNI, BNE, LIBRIS, NDL. Один номер на входе —
девять каталогов на выходе. Для персонографии это и есть та грань, что
отделяет список имён от узла в сети авторитетных данных.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;person&lt;/span&gt; &lt;span class="na"&gt;xml:id=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;pers-teligny-c&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;persName&amp;gt;&lt;/span&gt;Charles de Téligny&lt;span class="nt"&gt;&amp;lt;/persName&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;birth&lt;/span&gt; &lt;span class="na"&gt;when=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;1535&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;1535&lt;span class="nt"&gt;&amp;lt;/birth&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;death&lt;/span&gt; &lt;span class="na"&gt;when=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;1572-08-24&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;1572-08-24&lt;span class="nt"&gt;&amp;lt;/death&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;sex&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;M&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;M&lt;span class="nt"&gt;&amp;lt;/sex&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;idno&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;VIAF&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;314802260&lt;span class="nt"&gt;&amp;lt;/idno&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;idno&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;BNF&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;16133360&lt;span class="nt"&gt;&amp;lt;/idno&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;idno&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Wikidata&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Q1868249&lt;span class="nt"&gt;&amp;lt;/idno&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;idno&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ISNI&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;0000000071126808&lt;span class="nt"&gt;&amp;lt;/idno&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/person&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="от-фрагментов-к-персонографии"&gt;От фрагментов к персонографии&lt;/h2&gt;
&lt;p&gt;Пока персона одна, можно и в терминал XML напечатать. Но в издании их
сотни. Поэтому persNamer теперь берёт сразу несколько номеров VIAF, между
запросами вежливо выдерживает паузу, загруженное складывает в кэш, а с ключом
&lt;code&gt;--merge&lt;/code&gt; сам вставляет новые записи в &lt;code&gt;&amp;lt;listPerson&amp;gt;&lt;/code&gt; готового файла TEI.
Тех, кто в файле уже есть, он узнаёт по номеру VIAF и оставляет им прежний
&lt;code&gt;xml:id&lt;/code&gt;; новые идентификаторы сверяет с файлом и при совпадении добавляет
суффикс (&lt;code&gt;-2&lt;/code&gt;, &lt;code&gt;-3&lt;/code&gt;); под конец заново расставляет отступы — предварительно
сохранив копию &lt;code&gt;.bak&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;persnamer --merge edition.xml &lt;span class="m"&gt;314802260&lt;/span&gt; &lt;span class="m"&gt;36925746&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Одно изменение нужно иметь в виду: частица перед фамилией по умолчанию
в идентификатор больше не входит, так что Шарль де Телиньи теперь
&lt;code&gt;pers-teligny-c&lt;/code&gt;, а не &lt;code&gt;pers-deteligny-c&lt;/code&gt;. Если в вашем проекте уже
прижилась старая форма, &lt;code&gt;--keep-particle&lt;/code&gt; её вернёт; а если не хочется
зависеть от имён вовсе, &lt;code&gt;--id-format viaf&lt;/code&gt; даст &lt;code&gt;pers-viaf-314802260&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="по-хозяйству"&gt;По хозяйству&lt;/h2&gt;
&lt;p&gt;Из скрипта вырос пакет с командой &lt;code&gt;persnamer&lt;/code&gt;: ставится одной строкой —
&lt;code&gt;uv tool install&lt;/code&gt; или &lt;code&gt;pipx&lt;/code&gt;, — а через &lt;code&gt;uvx&lt;/code&gt; можно один раз запустить
и вовсе без установки. Двадцать шесть тестов гоняют его на записанных
ответах VIAF, так что сеть им не нужна; CI прогоняет их на Python от 3.9
до 3.13, а вывод проверяется на соответствие TEI P5. Лицензия прежняя —
Apache 2.0.&lt;/p&gt;
&lt;p&gt;Чего он по-прежнему не скажет — где человек родился и чем зарабатывал на
жизнь: в кластерном RDF VIAF нет ни мест, ни занятий. Зато они есть
в связанных записях BnF и GND, а их номера у вас теперь на руках.&lt;/p&gt;
&lt;p&gt;Код и документация — на
.&lt;/p&gt;</description></item><item><title>tei-mcp v0.3: кодировать в TEI, не переписывая источник</title><link>https://clementgodbarge.com/ru/post/tei-mcp-span-locked/</link><pubDate>Tue, 05 May 2026 00:00:00 +0000</pubDate><guid>https://clementgodbarge.com/ru/post/tei-mcp-span-locked/</guid><description>&lt;p&gt;Когда я
, цель была одна: отучить
ИИ-ассистентов галлюцинировать разметку TEI. Заземление на схему решило часть
проблемы: имея прямой, инструментальный доступ к спецификации P5, модели больше
не нужно гадать, что означает элемент и какие атрибуты он принимает. Результат
проходит валидацию.&lt;/p&gt;
&lt;p&gt;Но у галлюцинации в кодировании TEI два лица, и схема ловит лишь одно. Валидация
по спецификации говорит, что &lt;em&gt;разметка&lt;/em&gt; корректна. О &lt;em&gt;тексте&lt;/em&gt;, который эта разметка
обёртывает, она не говорит ничего. А именно там — в самом тексте — живут самые
разрушительные галлюцинации. Сборка по закреплённым отрезкам (span-locked
composition), главная новинка v0.3, придумана специально, чтобы их не допускать.&lt;/p&gt;
&lt;details class="print:hidden xl:hidden" &gt;
&lt;summary&gt;Содержание&lt;/summary&gt;
&lt;div class="text-sm"&gt;
&lt;nav id="TableOfContents"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#галлюцинация-которую-схема-поймать-не-может"&gt;Галлюцинация, которую схема поймать не может&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#сборка-по-закреплённым-отрезкам"&gt;Сборка по закреплённым отрезкам&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#что-это-такое--и-чем-это-не-является"&gt;Что это такое — и чем это не является&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#почему-это-важно-и-за-пределами-tei"&gt;Почему это важно и за пределами TEI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#как-обновиться"&gt;Как обновиться&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/nav&gt;
&lt;/div&gt;
&lt;/details&gt;
&lt;h2 id="галлюцинация-которую-схема-поймать-не-может"&gt;Галлюцинация, которую схема поймать не может&lt;/h2&gt;
&lt;p&gt;Попросите модель закодировать французское письмо XVI века — и нередко
получите документ TEI безупречного вида. Заголовок заполнен, теги &lt;code&gt;&amp;lt;persName&amp;gt;&lt;/code&gt;
расставлены правильно, &lt;code&gt;&amp;lt;dateline&amp;gt;&lt;/code&gt; оформлен как положено. Прогоните его через
&lt;code&gt;validate_document&lt;/code&gt; — он пройдёт.&lt;/p&gt;
&lt;p&gt;А потом сравните основной текст с источником.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mesme&lt;/code&gt; превратилось в &lt;code&gt;même&lt;/code&gt;. Запятая переехала. &lt;code&gt;luy&lt;/code&gt; тихо осовременили до
&lt;code&gt;lui&lt;/code&gt;. Фразу, которую трудно было разобрать в рукописи, «исправили» во что-то
более гладкое. Ни одного из этих изменений никто не просил. Ни одно не помечено.
Документ валиден по схеме и тихо неверен.&lt;/p&gt;
&lt;p&gt;Для архивного процесса — где закодированный текст становится постоянной записью,
на которую опираются последующие читатели, поисковые индексы и цитаты, — это
самый важный вид сбоя. Кривой тег раздражает. Осовремененное написание, которого
никто не замечает пять лет, — это порча.&lt;/p&gt;
&lt;h2 id="сборка-по-закреплённым-отрезкам"&gt;Сборка по закреплённым отрезкам&lt;/h2&gt;
&lt;p&gt;Новый выпуск (v0.3) содержит механизм предотвращения галлюцинаций, нацеленный
ровно на этот сбой. Цель конструкции — сделать галлюцинации в основном тексте
невозможными по самому устройству, а не просто маловероятными.&lt;/p&gt;
&lt;p&gt;Идея проста: &lt;strong&gt;модель никогда не набирает основной текст&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Вместо этого процесс выглядит так:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Модель вызывает &lt;code&gt;get_source(&amp;quot;letter_001&amp;quot;)&lt;/code&gt; и получает исходный простой текст
в виде неизменяемой строки.&lt;/li&gt;
&lt;li&gt;Для каждого тега, который она хочет поставить, она вызывает
&lt;code&gt;tag_span(&amp;quot;letter_001&amp;quot;, start, end, element_path, attrs)&lt;/code&gt;, регистрируя
элемент TEI на диапазоне символов источника.&lt;/li&gt;
&lt;li&gt;Закончив, она вызывает &lt;code&gt;compose(&amp;quot;letter_001&amp;quot;)&lt;/code&gt;. Сервер переплетает записанные
теги с исходным простым текстом, отрисовывает итоговый TEI и затем проверяет
&lt;em&gt;байт за байтом&lt;/em&gt;, что плоское текстовое содержимое полученного документа
равно источнику.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Если байты совпадают, документ возвращается. Если нет — если теги модели
каким-то образом подразумевают основной текст, отличающийся от источника хотя бы
на один символ, — &lt;code&gt;compose()&lt;/code&gt; выбрасывает исключение вместо того, чтобы вернуть
испорченный документ.&lt;/p&gt;
&lt;p&gt;В этом процессе нет пути, на котором модель выдала бы документ TEI с основным
текстом, отличным от источника. Инвариант механический, а не поведенческий.
Вам не нужно верить, что модель не станет галлюцинировать; нужно верить лишь
проверке &lt;code&gt;==&lt;/code&gt; между двумя байтовыми строками.&lt;/p&gt;
&lt;h2 id="что-это-такое--и-чем-это-не-является"&gt;Что это такое — и чем это не является&lt;/h2&gt;
&lt;p&gt;Сборка по закреплённым отрезкам &lt;strong&gt;дополняет&lt;/strong&gt; заземление на схему, а не заменяет
его. Инструменты заземления (&lt;code&gt;validate_document&lt;/code&gt;, &lt;code&gt;lookup_element&lt;/code&gt;,
&lt;code&gt;valid_children&lt;/code&gt; и остальные из первоначальных шестнадцати) помогают модели
выдавать &lt;em&gt;валидный&lt;/em&gt; TEI. Сборка по закреплённым отрезкам гарантирует, что
основной текст внутри этого TEI &lt;em&gt;верен&lt;/em&gt; источнику. Пригодный к внедрению процесс
кодирования должен удовлетворять обеим осям, и теперь обе покрывает один сервер.&lt;/p&gt;
&lt;p&gt;Но и волшебной таблеткой от всего это не назовёшь. &lt;code&gt;compose()&lt;/code&gt; пока не проверяет,
допустимы ли зарегистрированные теги по загруженной ODD-настройке — это следующий
шаг. Записанные теги живут в памяти процесса и не переживают перезапуск. А
исходные файлы должны быть доступны для чтения оттуда, где запущен сервер. Всё
это решаемо; ничто из этого не подрывает основной инвариант.&lt;/p&gt;
&lt;h2 id="почему-это-важно-и-за-пределами-tei"&gt;Почему это важно и за пределами TEI&lt;/h2&gt;
&lt;p&gt;Этот приём обобщается. Всякий раз, когда модель просят аннотировать, преобразовать
или обернуть фрагмент текста — и всякий раз, когда целостность исходного текста
важнее, чем способность модели его «улучшить», — годится решение той же формы.
Не просите модель перепечатывать текст. Просите её выдать инструкции над
текстом, а применять их пусть будет детерминированный сборщик под инвариантом
равенства.&lt;/p&gt;
&lt;p&gt;Для цифровых изданий в частности это меняет то, что можно ответственно поручить
модели. Кодирование вдруг становится задачей, которую можно делегировать, не
сверяя вручную каждый результат с источником. Машина идёт скучным путём;
редактор проверяет разметку, а не орфографию.&lt;/p&gt;
&lt;h2 id="как-обновиться"&gt;Как обновиться&lt;/h2&gt;
&lt;p&gt;Если tei-mcp у вас уже установлен:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uvx tei-mcp@latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Или с нуля:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip install tei-mcp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Чтобы пользоваться сборкой по закреплённым отрезкам, укажите серверу каталог
с исходными текстовыми файлами:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;TEI_MCP_SPAN_SOURCE_ROOT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/path/to/sources
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uvx tei-mcp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Имя каждого файла без расширения становится идентификатором документа
(&lt;code&gt;letter_001.txt&lt;/code&gt; → &lt;code&gt;letter_001&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Исходный код, полная документация и заметки о конструкции инварианта:
&lt;/p&gt;</description></item><item><title>Цифровое издание другого рода</title><link>https://clementgodbarge.com/ru/post/cavriana-edition/</link><pubDate>Tue, 24 Mar 2026 00:00:00 +0000</pubDate><guid>https://clementgodbarge.com/ru/post/cavriana-edition/</guid><description>&lt;p&gt;Большинство первоисточников так и остаются неопубликованными. Модель, на которую мы полагаемся, чтобы это исправить, — цифровые издания на грантовые деньги, — слишком дорога, слишком централизована и слишком хрупка, чтобы работать в масштабе. Я только что опубликовал
, где объясняю, почему критическое издание писем Каврианы я строю иначе: оцифрованные первоисточники, которые растут органически, с минимальной инфраструктурой, автоматическим сопровождением, открытые для сотрудничества и настолько дешёвые, что гранты вовсе не нужны. Это довод в пользу таких цифровых гуманитарных наук, которые работают независимо от институциональной поддержки.&lt;/p&gt;</description></item><item><title>tei-mcp: TEI P5 для ИИ-агентов</title><link>https://clementgodbarge.com/ru/post/tei-mcp/</link><pubDate>Sun, 15 Mar 2026 00:00:00 +0000</pubDate><guid>https://clementgodbarge.com/ru/post/tei-mcp/</guid><description>&lt;p&gt;Если вы когда-нибудь писали TEI XML с помощью ИИ-ассистента для программирования,
вы наверняка замечали, что он ошибается. Элементы появляются там, где им не место.
Атрибуты выдумываются. Правила вложенности игнорируются. Модель примерно представляет,
как выглядит TEI, но надёжного знания спецификации у неё нет.&lt;/p&gt;
&lt;p&gt;tei-mcp решает эту проблему, давая ИИ-агентам прямой доступ к Руководству TEI P5
через инструменты.&lt;/p&gt;
&lt;details class="print:hidden xl:hidden" &gt;
&lt;summary&gt;Содержание&lt;/summary&gt;
&lt;div class="text-sm"&gt;
&lt;nav id="TableOfContents"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#что-такое-mcp"&gt;Что такое MCP?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#что-делает-tei-mcp"&gt;Что делает tei-mcp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#почему-это-важно"&gt;Почему это важно&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#с-чего-начать"&gt;С чего начать&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/nav&gt;
&lt;/div&gt;
&lt;/details&gt;
&lt;h2 id="что-такое-mcp"&gt;Что такое MCP?&lt;/h2&gt;
&lt;p&gt;
(MCP) — открытый стандарт,
позволяющий ИИ-приложениям подключаться к внешним источникам данных и инструментам.
Считайте его USB-портом для ИИ: единый протокол, через который любой совместимый
клиент — Claude, Cursor, Windsurf и другие — подключается к специализированным службам.&lt;/p&gt;
&lt;p&gt;MCP-сервер предоставляет &lt;em&gt;инструменты&lt;/em&gt;, которые ИИ может вызывать по ходу разговора.
Вместо того чтобы полагаться на заученные обучающие данные, модель обращается к живому
авторитетному источнику.&lt;/p&gt;
&lt;h2 id="что-делает-tei-mcp"&gt;Что делает tei-mcp&lt;/h2&gt;
&lt;p&gt;tei-mcp разбирает спецификацию TEI P5 в формате ODD и предоставляет 16 инструментов,
покрывающих самые частые вопросы редактора или кодировщика:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Что это за элемент?&lt;/strong&gt; Поиск любого элемента, класса, макроса или модуля по имени,
без учёта регистра и с подсказками при опечатках.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Какие у него атрибуты?&lt;/strong&gt; Разрешение атрибутов по всей иерархии классов: сначала
локальные, затем унаследованные по порядку.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Что может быть внутри?&lt;/strong&gt; Развёртывание моделей содержимого в структурированные
деревья или плоский список допустимых потомков.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Можно ли поставить элемент сюда?&lt;/strong&gt; Проверка вложенности «родитель — потомок»
или трассировка достижимости по всей иерархии элементов.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Валиден ли мой документ?&lt;/strong&gt; Проверка файла TEI XML по спецификации: модели
содержимого, значения атрибутов, закрытые списки значений, целостность ссылок
и предупреждения об устаревших элементах.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;А как же схема моего проекта?&lt;/strong&gt; Загрузка файла ODD-настройки, чтобы ограничить
всё перечисленное подмножеством TEI, принятым в вашем проекте.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="почему-это-важно"&gt;Почему это важно&lt;/h2&gt;
&lt;p&gt;Кодирование в TEI требует постоянно сверяться с Руководством. Опытные кодировщики
усваивают самые ходовые схемы, но даже им приходится заглядывать в спецификацию ради
менее знакомых элементов или сложных моделей содержимого. У ИИ-ассистентов такого
усвоенного знания нет, и им приходится хуже: они галлюцинируют правдоподобную на вид,
но неверную разметку.&lt;/p&gt;
&lt;p&gt;С tei-mcp ИИ не приходится гадать. Он может найти ответ в спецификации, прежде чем
напишет хоть одну угловую скобку. В результате разметка соответствует TEI P5 — или
ODD-настройке вашего проекта.&lt;/p&gt;
&lt;h2 id="с-чего-начать"&gt;С чего начать&lt;/h2&gt;
&lt;p&gt;Установите из PyPI:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip install tei-mcp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Затем добавьте сервер в конфигурацию вашего MCP-клиента:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;mcpServers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;tei&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;uvx&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;tei-mcp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;При первом запуске сервер скачивает спецификацию TEI и работает с любым
MCP-совместимым клиентом.&lt;/p&gt;
&lt;p&gt;Исходный код и полная документация:
&lt;/p&gt;</description></item><item><title>Учим двоичный код на эмуляторе телеграфа ITA2</title><link>https://clementgodbarge.com/ru/post/baudot/</link><pubDate>Thu, 13 Feb 2025 00:00:00 +0000</pubDate><guid>https://clementgodbarge.com/ru/post/baudot/</guid><description>&lt;h2 id="как-сделать-абстрактное-осязаемым"&gt;Как сделать абстрактное осязаемым&lt;/h2&gt;
&lt;p&gt;Эмулятор ITA2 — практическое учебное пособие. Делая абстрактные понятия кодирования зримыми и интерактивными, он знакомит студентов с одной из ключевых идей вычислительной техники и телекоммуникаций — двоичным представлением, то есть тем, как текст превращается в последовательности нулей и единиц.
Обычно мы преподаём это отвлечённо; но когда студент своими глазами видит, как в ленте появляются отверстия, ему куда легче понять, каким образом физическая система может нести цифровую информацию.
&lt;div class="baudot-emulator"&gt;
&lt;h2&gt;ITA2 (Baudot-Murray) Telegraph Type Emulator&lt;/h2&gt;
&lt;p&gt;Type a word in the input below to see its representation on the ITA2 tape.&lt;/p&gt;
&lt;div class="baudot-controls"&gt;
&lt;label for="baudot-input"&gt;Type word:&lt;/label&gt;
&lt;input id="baudot-input" class="text-input" size="50" maxlength="50" /&gt;
&lt;button type="button" id="baudot-ltr-button" class="control-button active"&gt;LTR&lt;/button&gt;
&lt;button type="button" id="baudot-fig-button" class="control-button"&gt;FIG&lt;/button&gt;
&lt;/div&gt;
&lt;div class="tape-outer-container"&gt;
&lt;div class="tape-container"&gt;
&lt;table&gt;
&lt;tbody id="baudot-tape"&gt;&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
.baudot-emulator {
--light-color: #f3f4f6;
--dark-color: #1f2937;
--light-alt-color: #e5e7eb;
--dark-alt-color: #374151;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;
max-width: 100%;
margin: 2rem 0;
padding: 0;
box-sizing: border-box;
}
.baudot-emulator {
--tape-bg: var(--light-color);
--hole-bg: var(--light-color);
--hole-border: #d1d5db;
--punched-bg: var(--dark-color);
--punched-border: var(--dark-color);
--sprocket-bg: var(--light-color);
--sprocket-border: #9ca3af;
--button-bg: var(--light-color);
--button-bg-active: #d1d5db;
--button-text: var(--dark-color);
--button-border: #d1d5db;
--input-bg: white;
--input-border: #d1d5db;
--input-text: var(--dark-color);
--line-number: #6b7280;
}
html.dark .baudot-emulator,
html[data-theme='dark'] .baudot-emulator,
body.dark .baudot-emulator {
--tape-bg: var(--dark-alt-color);
--hole-bg: var(--dark-alt-color);
--hole-border: #4b5563;
--punched-bg: var(--light-color);
--punched-border: var(--light-color);
--sprocket-bg: var(--dark-alt-color);
--sprocket-border: #9ca3af;
--button-bg: var(--dark-alt-color);
--button-bg-active: #4b5563;
--button-text: var(--light-color);
--button-border: #4b5563;
--input-bg: var(--dark-alt-color);
--input-border: #4b5563;
--input-text: var(--light-color);
--line-number: #9ca3af;
}
.baudot-controls {
margin-bottom: 1.5rem;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.5rem;
}
.baudot-emulator .text-input {
flex: 1;
min-width: 200px;
padding: 0.5rem;
font-size: 1rem;
border: 1px solid var(--input-border);
border-radius: 4px;
background: var(--input-bg);
color: var(--input-text);
}
.baudot-emulator .control-button {
padding: 0.5rem 1rem;
background: var(--button-bg);
color: var(--button-text);
border: 1px solid var(--button-border);
border-radius: 4px;
cursor: pointer;
font-size: 0.9rem;
}
.baudot-emulator .control-button.active {
background: var(--button-bg-active);
font-weight: bold;
}
.tape-outer-container {
padding: 0;
margin-bottom: 1.5rem;
border-radius: 4px;
overflow: hidden;
}
.tape-container {
width: 100%;
overflow-x: auto;
background: var(--tape-bg);
padding: 1rem 0.5rem;
}
.baudot-emulator table {
border-collapse: collapse;
width: 100%;
table-layout: fixed;
border: none;
}
.baudot-emulator tr {
height: 24px;
border: none;
}
.baudot-emulator td {
border: none;
padding: 0;
}
.baudot-emulator .line-number {
width: 20px;
text-align: center;
color: var(--line-number);
font-size: 0.8rem;
padding: 0 8px 0 0;
font-weight: bold;
}
.baudot-emulator .cell {
position: relative;
width: 20px;
height: 20px;
}
.baudot-emulator .cell-content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 12px;
height: 12px;
border-radius: 50%;
background: var(--hole-bg);
border: 1px solid var(--hole-border);
}
.baudot-emulator .punched .cell-content {
background: var(--punched-bg);
border: 1px solid var(--punched-border);
}
.baudot-emulator .sprocket-hole {
position: absolute;
left: 50%;
top: 100%;
transform: translate(-50%, -50%);
width: 4px;
height: 4px;
border-radius: 50%;
background: var(--sprocket-bg);
border: 1px solid var(--sprocket-border);
z-index: 2;
}
&lt;/style&gt;
&lt;script&gt;
document.addEventListener('DOMContentLoaded', function() {
initBaudotEmulator();
});
function initBaudotEmulator() {
if (!document.getElementById('baudot-input')) return;
const textInput = document.getElementById('baudot-input');
const tape = document.getElementById('baudot-tape');
const ltrButton = document.getElementById('baudot-ltr-button');
const figButton = document.getElementById('baudot-fig-button');
const ita2Code = {
'A': '00011', 'B': '11001', 'C': '01110', 'D': '01001', 'E': '00001',
'F': '01101', 'G': '11010', 'H': '10100', 'I': '00110', 'J': '01011',
'K': '01111', 'L': '10010', 'M': '11100', 'N': '01100', 'O': '11000',
'P': '10110', 'Q': '10111', 'R': '01010', 'S': '00101', 'T': '10000',
'U': '00111', 'V': '11110', 'W': '10011', 'X': '11101', 'Y': '10101',
'Z': '10001',
'1': '00011', '2': '11001', '3': '01110', '4': '01001', '5': '00001',
'6': '01101', '7': '11010', '8': '10100', '9': '01011', '0': '11000',
'-': '00011', '?': '00100', ':': '01010', '(': '11000', ')': '11101',
'.': '01000', ',': '00010', "'": '10001', '=': '01111', '/': '10011',
'+': '11011', ' ': '00100',
'FIG': '11011', 'LTR': '11111',
};
function generateTape() {
let rows = '';
for (let row = 0; row &lt; 5; row++) {
rows += '&lt;tr&gt;';
rows += `&lt;td class="line-number"&gt;${row + 1}&lt;/td&gt;`;
for (let col = 0; col &lt; 50; col++) {
rows += `&lt;td id="baudot_${row}_${col}" class="cell unpunched"&gt;
&lt;div class="cell-content"&gt;&lt;/div&gt;
${row === 2 ? '&lt;div class="sprocket-hole"&gt;&lt;/div&gt;' : ''}
&lt;/td&gt;`;
}
rows += '&lt;/tr&gt;';
}
tape.innerHTML = rows;
}
function updateITA2Code(word) {
clearTape();
word = word.toUpperCase();
let tapePosition = 0;
let currentCharType = 'LTR';
ltrButton.classList.add('active');
figButton.classList.remove('active');
for (let i = 0; i &lt; word.length; i++) {
const char = word[i];
let code = ita2Code[char] || ita2Code[' '];
let requiredCharType = /[A-Z ]/.test(char) ? 'LTR' : 'FIG';
if (requiredCharType !== currentCharType) {
const shiftCode = requiredCharType === 'LTR' ? ita2Code['LTR'] : ita2Code['FIG'];
punchTape(shiftCode, tapePosition++);
currentCharType = requiredCharType;
ltrButton.classList.toggle('active', currentCharType === 'LTR');
figButton.classList.toggle('active', currentCharType === 'FIG');
}
punchTape(code, tapePosition++);
}
}
function punchTape(code, tapePosition) {
if (tapePosition &gt;= 50) return;
for (let bit = 0; bit &lt; 5; bit++) {
const cell = document.getElementById(`baudot_${bit}_${tapePosition}`);
if (cell) {
cell.className = code[bit] === '1' ? 'cell punched' : 'cell unpunched';
}
}
}
function clearTape() {
for (let i = 0; i &lt; 50; i++) {
for (let bit = 0; bit &lt; 5; bit++) {
const cell = document.getElementById(`baudot_${bit}_${i}`);
if (cell) {
cell.className = 'cell unpunched';
}
}
}
}
generateTape();
textInput.addEventListener('input', function() {
updateITA2Code(this.value);
});
ltrButton.addEventListener('click', function() {
this.classList.add('active');
figButton.classList.remove('active');
if (textInput.value) {
updateITA2Code(textInput.value);
}
});
figButton.addEventListener('click', function() {
this.classList.add('active');
ltrButton.classList.remove('active');
if (textInput.value) {
updateITA2Code(textInput.value);
}
});
if (textInput.value) {
updateITA2Code(textInput.value);
}
}
&lt;/script&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id="исторический-контекст-от-телеграфа-к-компьютеру"&gt;Исторический контекст: от телеграфа к компьютеру&lt;/h2&gt;
&lt;p&gt;Код ITA2 (Международный телеграфный алфавит № 2), известный также как код Бодо — Мюррея, был разработан в 1920-е годы как усовершенствование первоначального телеграфного кода Эмиля Бодо 1870-х годов. Эти ранние системы связи напрямую повлияли на позднейшее развитие вычислительной техники:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;пятибитная схема была одним из первых примеров кодирования символов;&lt;/li&gt;
&lt;li&gt;ограниченность набора символов (пять бит дают всего 32 комбинации) породила остроумный механизм переключения регистров LETTERS/FIGURES (буквы/цифры);&lt;/li&gt;
&lt;li&gt;система использовалась в телетайпах ещё долгие десятилетия XX века.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="конечные-автоматы-в-игре"&gt;Конечные автоматы в игре&lt;/h2&gt;
&lt;p&gt;Механизм переключения LETTERS/FIGURES естественным образом подводит к понятию конечного автомата. Экспериментируя, студенты сами обнаруживают, что одна и та же комбинация может означать разные символы в зависимости от текущего режима. Такой живой опыт работы с кодированием, зависящим от состояния, готовит их к более сложным понятиям информатики.
Скажем, комбинация битов &lt;code&gt;00011&lt;/code&gt; означает:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;букву «A» в режиме LETTERS;&lt;/li&gt;
&lt;li&gt;цифру «1» в режиме FIGURES.
Эта двойственность прочтения, зависящая от состояния, лежит в самой основе того, как компьютеры обращаются с данными.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="задания-для-аудитории"&gt;Задания для аудитории&lt;/h2&gt;
&lt;p&gt;Вот несколько способов включить эмулятор ITA2 в занятия:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Взлом шифра&lt;/strong&gt;: предложите студентам расшифровать сообщения, закодированные в виде комбинаций ITA2.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Экономное кодирование&lt;/strong&gt;: обсудите, почему механизм переключения регистров был так важен для экономии пропускной способности.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Эволюция кодировок&lt;/strong&gt;: сравните пятибитный код ITA2 с ASCII (7 бит) и Unicode.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Физические вычисления&lt;/strong&gt;: свяжите эту историческую систему с современными микроконтроллерами вроде Arduino.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="польза-для-доступности"&gt;Польза для доступности&lt;/h2&gt;
&lt;p&gt;Помимо исторического интереса, такой подход помогает студентам с разными стилями обучения:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;визуалы видят узоры;&lt;/li&gt;
&lt;li&gt;кинестетики напрямую взаимодействуют с процессом кодирования;&lt;/li&gt;
&lt;li&gt;те, кто мыслит понятиями, могут заняться математической стороной теории информации.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="подробности-реализации"&gt;Подробности реализации&lt;/h2&gt;
&lt;p&gt;Эмулятор написан на JavaScript и легко встраивается в любую веб-платформу для обучения. Код модульный и настраивается под разные учебные задачи.
Исходный код можно посмотреть, а эмулятор — опробовать здесь:
&lt;/p&gt;</description></item></channel></rss>