persNamer 1.2: один номер VIAF — девять авторитетных файлов

persNamer задумывался как мелкое удобство: на входе
номер VIAF, на выходе запись <person> в TEI да тег <persName>, которым
размечают текст. Больше он ничего не умел, и запись выходила тощей — имя,
две даты, один идентификатор. Версия 1.2, вышедшая сегодня, ничему другому
так и не научилась; зато запись стала такой, что её стоит хранить.
Что теперь входит в запись о персоне
Начнём с имени. В кластере VIAF каждая библиотека-участница держит имя
в своей форме, а старый persNamer брал первую, какая попадётся. Спросите
у него Вольтера — и получите «فولتير،»: по-арабски, с запятой на хвосте,
да ещё и с пустым xml:id в придачу. Версия 1.2 пересчитывает формы по
всему кластеру и оставляет ту, на которой исходные записи сходятся;
остальные идут следом как <persName type="variant">, по убыванию частоты.
Даты приводятся к норме (1572-08-00 становится 1572-08) и пишутся
дважды — текстом и в атрибуте @when: именно атрибут и прочтёт любая
обработка, которая вообще понимает даты. Пол и описания добавляются, когда
VIAF их отдаёт.
Но самое желанное для меня — другое: все идентификаторы, на которые VIAF
ссылается через schema:sameAs и через собственные идентификаторы
источников, теперь выписаны, каждый своим <idno> — BnF, GND, Библиотека
Конгресса, SUDOC, Wikidata, ISNI, BNE, LIBRIS, NDL. Один номер на входе —
девять каталогов на выходе. Для персонографии это и есть та грань, что
отделяет список имён от узла в сети авторитетных данных.
<person xml:id="pers-teligny-c">
<persName>Charles de Téligny</persName>
<birth when="1535">1535</birth>
<death when="1572-08-24">1572-08-24</death>
<sex value="M">M</sex>
<idno type="VIAF">314802260</idno>
<idno type="BNF">16133360</idno>
<idno type="Wikidata">Q1868249</idno>
<idno type="ISNI">0000000071126808</idno>
</person>
От фрагментов к персонографии
Пока персона одна, можно и в терминал XML напечатать. Но в издании их
сотни. Поэтому persNamer теперь берёт сразу несколько номеров VIAF, между
запросами вежливо выдерживает паузу, загруженное складывает в кэш, а с ключом
--merge сам вставляет новые записи в <listPerson> готового файла TEI.
Тех, кто в файле уже есть, он узнаёт по номеру VIAF и оставляет им прежний
xml:id; новые идентификаторы сверяет с файлом и при совпадении добавляет
суффикс (-2, -3); под конец заново расставляет отступы — предварительно
сохранив копию .bak.
persnamer --merge edition.xml 314802260 36925746
Одно изменение нужно иметь в виду: частица перед фамилией по умолчанию
в идентификатор больше не входит, так что Шарль де Телиньи теперь
pers-teligny-c, а не pers-deteligny-c. Если в вашем проекте уже
прижилась старая форма, --keep-particle её вернёт; а если не хочется
зависеть от имён вовсе, --id-format viaf даст pers-viaf-314802260.
По хозяйству
Из скрипта вырос пакет с командой persnamer: ставится одной строкой —
uv tool install или pipx, — а через uvx можно один раз запустить
и вовсе без установки. Двадцать шесть тестов гоняют его на записанных
ответах VIAF, так что сеть им не нужна; CI прогоняет их на Python от 3.9
до 3.13, а вывод проверяется на соответствие TEI P5. Лицензия прежняя —
Apache 2.0.
Чего он по-прежнему не скажет — где человек родился и чем зарабатывал на жизнь: в кластерном RDF VIAF нет ни мест, ни занятий. Зато они есть в связанных записях BnF и GND, а их номера у вас теперь на руках.
Код и документация — на GitHub.
