Как стать автором
Обновить

Подсчет знаков в формулах Microsoft Equation

Время на прочтение3 мин
Количество просмотров1.6K
image

В нашей компании существует несколько ставок для корректоров, которые вычитывают документы. В их обязанности также входит сверка набранных и заново распечатанных текстов, с оригиналами, которые есть изначально на бумаге. Зарплата для специалистов такого рода рассчитывается по сдельному принципу, то есть сколько прочитал, столько и получил. В качестве единицы измерения работы используются знаки, которые состоят из всех видимых символов, за исключением пробелов, табуляций, знаков абзаца и т.п.

Соответственно есть задача подсчитать количество знаков в текстах, которые поступают в работу. При подсчете обычного текста, никаких проблем не возникает и с такой задачей вполне по силам справиться любому студенту первого-второго курса. Проблемы в нашем случае появились при попытке учесть знаки в элементах, набранных с помощью Microsoft Equation. Дополнительно ситуация усугубилась еще и тем, что из многих документов была удалена служебная информация, которая описывала содержимое элемента. То есть от формул фактически остались одни картинки. Таким образом возникла задача, — подсчитать количество знаков в картинках оставшихся от Microsoft Equation.

Первым делом было нужно было разобраться с тем, что из себя представляют эти самые «картинки». Сохранив документ в xml формате и поковырявшись в нем (естественно параллельно используя великий и могучий гугл), выяснилось, что картинки — это ничто иное, как WMF-файлы, которые предварительно сжаты с помощью алгоритма Deflate (gzip) и преобразованы в base64.

Получилось, что исходная задача свелась к необходимости подсчитать количество знаков в WMF-файле. Учитывая, что данный формат векторный а не растровый, в нем доступны все данные о содержащихся объектах. Собственно в общем виде решение проблемы на данном этапе уже понятно, — пробежаться по элементам векторного файла и подсчитать их количество. Однако ниже я более подробно опишу процесс получения данных.

Так как WMF является устаревшим форматом, и на смену ему пришел EMF, все API-функции уже в Windows XP ориентированы именно на EMF. Поэтому для любых дальнейших действий необходимо преобразовать наш исходный файл в новый формат. Сделать это можно с помощью API функции SetWinMetaFileBits. Следующим шагом будет получение данных, содержащихся в файле. Для этого применим API команду EnumEnhMetaFile, которая с помощью callback-функции последовательно передаст в наше приложение все записи из EMF-файла. Данные будут передаваться в виде структуры ENHMETARECORD содержащей множество параметров, причем параметры будут различными для разных типов записей. В нашем случае для подсчета знаков, ключевыми являются записи, тип которых ENHMETARECORD.iType равен следующим константам EMR_EXTTEXTOUTW (84), EMR_MOVETOEX (27), EMR_LINETO (54).

Здесь, возможно, следует сделать паузу и рассказать о небольшом нюансе. Все элементы формул в данном векторном формате, делятся на текстовые (например, буквы латинского алфавита) и графические, состоящие из набора линий (например, знак дроби, знак корня и т.п.). При этом если для текстовых элементов можно просто подсчитать их количество, то с линиями все немного сложнее. В качестве решения, я придумал следующий способ: для каждой линии подсчитаем и запомним ее угловой коэффициент (считается по координатам начала и конца линии). Далее используя тот факт, что каждый графический элемент рисуется последовательным набором линий, любой знак можно представить в виде набора угловых коэффициентов. К примеру, знак деления — это одна линия, угловой коэффициент которой равен 0, а большая угловая скобка >, это два последовательных коэффициента 104, 76. Таким образом, исследовав различные формулы, можно составить конечный набор таких последовательностей, которые будут фактически однозначно сопоставляться с отображаемыми символами.

Итак, возвращаясь к подсчету. Используя записи с типом EMR_EXTTEXTOUTW мы получим данные о текстовых фрагментах, причем и их размер явно указан в структуре. А с помощью записей EMR_MOVETOEX и EMR_LINETO мы можем собрать координаты начала и концов всех линий. Преобразовав эти данные описанным выше способом мы получим количество графических знаков. На этом моменте подсчет можно считать завершенным.

Как результат, созданная на основе описанного алгоритма программа, показывает количество знаков в формулах, выдает сколько было текстовых символов и сколько графических, а также может сказать какие именно графические символы были использованы.

Более подробные описания API функций и различных констант не привожу, так как все эти данные легко можно посмотреть тут.
Теги:
Хабы:
+14
Комментарии18

Публикации

Изменить настройки темы

Истории

Ближайшие события