Правило номер N+0: не бойтесь копнуть глбуже

в 8:42, , рубрики: Программирование
Предыстория

Всем привет! Меня зовут Женя и я программист. Ничего особенного. Пока что.

Сегодня я хотел бы поделиться историей с хорошим концом, которая убедила меня в том, что даже если ты не относишь себя к программистам выше среднего и решаешь тривиальные задачи, программирование как процесс может всё равно быть очень увлекательным!

Перед мной стояла одна из самых типичных задач: вывести данные в какой-то текстовый файл. Формат файла такой, чтобы открылся на любом настольном среднестатистическом устройстве. Я был уверен в простоте решения этой задачи. Но в эту неделю судьба решила преподать мне урок…

История

Всё началось с выбора библиотеки для облегчения жизни и выбора формата. Формат был выбран docx а библиотека OenTBS. Вроде бы всё в ней было как надо — и формат файла тот и использовать шаблон можно. Но как показали 3 дня работы, эта штука если и может работать с вложенными массивами, то таким не очевидным образом, что, возможно, нужно вступить в какую-то секту, что бы постичь сие. Я решил идти по пути наименьшего сопротивления и просто поделился с монитором своими мыслями по поводу этой библиотеки и начал искать другую.

Далее был простой инструмент под названием odtPHP. Чей сайт, похоже, не работает до сих пор. Как Вы уже догадались вместе с библиотекой пришлось сменить и формат — им стал odt. Если очень захотеть можно даже порадоваться — открытый формат и всё такое.

Вот тут и началось самое веселое. Документ генерируется из шаблона. Если сделать шаблон в LibreOffice (а именно он был у меня первым под рукой), то в Word`е он будет открываться только после вопроса о восстановлении. А если создать шаблон в Word`е? Тогда без восстановления. Но после минимальных правок в шаблоне odtPHP выдавал ошибку, мол в шаблоне не найдена переменная. Неистовый воплю и тыканье пальцем в название переменной в шаблоне делу не помогли. Странно. То есть получалось, что нужная переменная как бы прописана в шаблоне, но odtPHP не может найти эту переменную через регулярные выражение.

Начали закрадываться подозрения, что пробел/тире/любой-другой-символ в Word`e в самом исходнике может обозначаться как-то иначе. Так как я знал что odt, как и docx, это по простому архивированные XML я решил углубиться в этот вопрос и для пущей уверенности создал такой же odt-шаблон через Google Drive. После разархивирования odt-файлов от разных «создателей» получилась вот такая картина:

image

Стало очевидно что формат форматом, но у программ может быть разный на него взгляд. Как несложно догадаться, всё содержимое файла хранится в content.xml. Открываю. Ищу свои переменные. И, о чудо! Я на верном пути! Вот так моя переменная выглядит в Word`е (вариант созданный в Word`e):

image

А вот так этот фрагмент выглядит в content.xml:

image

А регулярное выражение было максимально простым:

$reg = '@[!--sBEGINs' . $string . 's--](.*)[!--.+ENDs' . $string . 's--]@smU';

Что такое <text:s/> узнать так и не удалось. Можно подумать, что это пробел, но почему он вставился именно тут, а в других местах просто пробел? Не понятно. Предугадать расстановку таких магических пробелов в Word`е не предоставилось возможным. Вот и получилось, что Word где-то вставляет пробел как пробел, а где-то как <text:s/>, что обламывает нахождение переменной по минимальному шаблону.

Вот так тривиальная задача превратилась в увлекательное довольно путешествие по структуре формата odt!

Мораль

Каким бы уровнем знаний вы не обладали и как низко бы не падала оценка собственных навыков, не бойтесь копнуть глубже! Если, конечно, вы не водитель экскаватора и рядом не визит табличка «Копать запрещено».

P.S. Было бы очень интересно почитать такие истории в формате Предыстория-История-Мораль от крутых разработчиков, которые потом можно было бы рассказывать в образовательных целях

Автор: Turowskiy

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js