Credit на Божо от Hack TUES X за този скрипт.
# `namesub.py`
Малък скрипт, който генерира сертификати и lower thirds (name tags) за участници, ментори, доброволци и т.н.
Написан е за 5 минути по време на среща.
Само трябва някой от Дизайн ✨ да export-не .svg файл и на мястото на текста да напише "Име Фамилия" на мястото, където е
името на човека.
Скриптът може да генерира .pdf и/или .png-та, като прочита всичките имена от стандартния вход или от файл.
`--help` за повече информация.Това е скрипт, който генерира сертификати и lower thirds (name tags) за участници, ментори, доброволци и т.н.
Накратко: вземаш един дизайн (темплейт) с placeholder текст на мястото на името и генерираш по един персонализиран файл за всеки човек от списъка. Сертификати, баджове, табелки за отбори, табелки за жури - каквото ти поръча екип дизайн.
namesub.py чете всичките имена от файл и за всяко от тях скриптът намира текста "Име Фамилия" в темплейта, заменя го със съответното име и накрая конвертира всичко към .pdf и/или .png чрез Inkscape.
- Чете темплейта -
.svgфайл, който някой от екип дизайн е експортнал, с текст "Име Фамилия" на мястото на името (и по желание "описание" на мястото на подзаглавие/категория). - Чете имената - от стандартния вход или от файл (
--input-file), по едно име на ред. Ако на реда има табулация (\t), лявата част е името, а дясната - подзаглавието (например отбор или категория). - Заменя текста - Функцията
replace_text_with_html_supportсе бори с факта, че различните софтуери за дизайн кодират кирилицата по различни начини в svg-то. Затова пробва няколко варианта последователно: обикновен текст → hex HTML entities (И) → decimal entities (И) → разкодиране и повторно кодиране. Така името се намира и заменя, независимо как Figma или друг дизайн софтуер е решил да го запише. Replacement-ът се escape-ва, за да остане svg-то валиден XML. - Оправя дубликатите - ако двама души се казват еднакво, файловете получават наставки
(1),(2)и т.н., за да не се презаписват. - Конвертира чрез Inkscape - функцията
batch_processпуска Inkscape през CLI-то му на партиди по 20 файла наведнъж (за да не стартира Inkscape 300 пъти, което би отнело часове). За всеки файл правиselect-all+object-to-path- тоест конвертира текста към path, за да не зависи крайният файл от инсталирани шрифтовеа - и след това експортва към.pngи/или.pdf. - Изплюва JSON - накрая на стандартния изход излиза метадата за всички генерирани файлове.
namesub.py приема списък с имена. Тези скриптчета ти го приготвят, за да не пишеш имената на ръка:
excel-to-namesub.py- взема Excel таблица с две колони (отбор и участник, като отборът често е merge-нат през няколко реда) и я превръща в редовеиме<TAB>отбор. Използваpandasиopenpyxl.get_duplicate_names.py- бързо ти казва кои имена се повтарят в списъка. Полезно, преди да генерираш, за да не се чудиш грешка ли има или наистина са двама души с еднакви име и фамилия.sponsors-for-namesub.ts- Bun/TypeScript скрипт, който вади спонсорите от конфигурациите наht-webпроекта и ги изплюва катоиме<TAB>пакет(Алфа/Бета/Гама спонсор, партньор, медиен партньор).teams-for-namesub.ts- Bun/TypeScript скрипт, който вади отборите директно от базата наht-web(Postgres) и ги изплюва катоиме<TAB>Отбор(или "Отбор на завършили" за alumni).
Тоест за спонсорите и отборите не пишеш нищо на ръка - дърпаш ги от сайта и ги наливаш в namesub.py.
Дизайнът на различните типове печатни материали изисква различно позициониране на текста, затова namesub има няколко варианта в няколко бранча.
-
main- базовата версия. Центрирането на текста е изключено, текстът се конвертира към path при експорт. -
variants/Not-centered-text- буквално същото катоmain(същият комит). Стои само като именован указател за варианта "без центриране", за да ти е ясно кой бранч за какво е. -
variants/Centered-text- разликата е три реда: включва центрирането на текста. Използвай го, когато искаш името да е центрирано хоризонтално. -
variants/Tabelki-juri- за табелките на журито. Пренаписваcenter_text_in_svg, така че да работи на ниво всеки отделен<text>елемент. Това е нужно, защото при табелките текстът е огледален от двете страни (за да се чете, когато табелката е сгъната). Скриптът смята правилния локаленxзаtranslate(...)и за обърнат текст, така че текстът да е центриран правилно и от двете страни. -
variants/Team-table-signs- най-тежкият вариант (горе-долу +575 реда) за табелките на отборите с лого на спонсорска компания. Добавя логика за вграждане на логота в две кутии на дизайна (Rectangle 341нормално иRectangle 342обърнато на 180° за сгъваемите табелки):embed_logos_in_svg- вгражда векторни (SVG) лога, като преименува всичкиid-та с уникален префикс (за да не се бият с темплейта) и маха Inkscape метаданни, които чупят рендера.embed_raster_logos_in_svg- вгражда растерни (PNG/WebP) логота като base64 data URI. WebP се конвертира към PNG (защото Inkscape не обича WebP data URI-та), а размерите се четат директно от хедъра на файла, без да е нужен Pillow.- Полето след табулацията тук вече се третира като път до файл с лого (пробват се много кандидат-пътища и разширения), а ако такъв файл няма - пада обратно към подзаглавие текст. Добавен е и флаг
--logos-dir.
-
Python 3
tqdm(за progress bar - ако го няма, скриптът просто няма да ти показва лентичка)pandas+openpyxl(само заexcel-to-namesub.py)Pillow(само за WebP лога вTeam-table-signs). -
Inkscape
Пътят е хардкоднат в скрипта като
C:\Program Files\Inkscape\bin\inkscape.exe. Ако твоят е другаде, подавай--inkscape-pathили го смени. -
Темплейт
.svgфайл, в който на мястото на името пише точно "Име Фамилия" (а ако има подзаглавие - "описание"), като текстът, който ще се заменя, трябва да е истински<text>елемент, а не конвертиран към path. В противен случай няма какво да се замени.
Трябва ти обикновен текстов файл с по едно име на ред:
Иван Иванов
Мария Петрова
Ако искаш и подзаглавие (отбор, категория, компания), сложи табулация:
Иван Иванов Отбор Свежи
Мария Петрова Алфа Спонсор
Или си генерирай файла автоматично:
# от Excel таблица с отбори и участници
python excel-to-namesub.py participants.xlsx -o names.txt
# спонсори от ht-web
bun sponsors-for-namesub.ts > names.txt
# отбори от базата на ht-web
bun teams-for-namesub.ts --postgresUrl "postgres://..." > names.txtПреди да генерираш - провери за дубликати:
python get_duplicate_names.py names.txtgit checkout variants/Team-table-signs # табелки на отбори с лого
# или variants/Tabelki-juri, variants/Centered-text, main ...Първо приготви txt файл с едно име, пусни скрипта върху него и виж дали дизайнът не се е счупил при експорта, преди да чакаш 5 минути за всичките 300 човека:
python namesub.py template.svg --input test.txt --pdfАко всичко е наред:
python namesub.py template.svg --input-file names.txt --pdf --pngПолезни флагове:
--pdf/--png- какви формати да изкара (печатниците обикновено работят с.pdf).--input-file FILE- откъде да чете имената.--output-dir DIR- къде да слага резултата (по подразбиранеoutput/).--replace-text/--subtitle-replace-text- ако placeholder-ите в темплейта не са "Име Фамилия" и "описание".--inkscape-path- ако Inkscape ти е на друго място.--overwrite- да презапише вече генерирани файлове (по подразбиране ги прескача, което е удобно, когато добавяш няколко нови имена).--logos-dir(само вTeam-table-signs) - къде да търси файловете с логота.
Резултатите излизат в output/svg/, output/png/ и output/pdf/, по един файл на човек.