Михаил Борисов
Автоматизируем форматирование таблиц.
Хотя InDesign CS3 стал поддерживать стили для таблиц, их форматирование с помощью скриптов не утратило актуальности: встроенные функции решают часть проблем, но все не охватывают. Первая причина — переход на версию CS3 произойдёт не сразу, многие ещё долго будут работать в InDesign CS2; вторая — скриптинг предоставляет ни с чем не сравнимую гибкость при решении задач, что позволяет полностью автоматизировать форматирование. Предлагаемый пример (я активно использую этот скрипт) — отправная точка для создания собственных скриптов по форматированию таблиц; кроме того, он решает вопросы оптимизации, т. е. универсален.
При импорте документа Word в InDesign параметры ячеек теряются (рис. 1, вверху). Наша задача — из полуфабриката создать полноценную таблицу (рис. 1, внизу).
|
| Pис. 1. Таблица до и после |
Предположим, вёрстка у нас двухколоночная, поэтому предусмотрим, чтобы таблицы были двух видов: узкие (в одну колонку) и широкие (занимающие всю полосу набора). Для заливки строк будем использовать два чередующихся цвета, цвет окантовки у всех ячеек выберем белым. Для текста в шапке таблицы возьмём стиль абзаца Tbl Hdr, для остального текста — Table contents.
Обеспечим выключку во всех ячейках по центру, а ширину крайней левой колонки зададим такой, чтобы по возможности не было переноса текста. В моей практике в последней колонке текста всегда больше, чем в остальных, поэтому ради компактности таблицы увеличим её ширину за счёт других. В случае же слишком длинного текста ограничим её ширину, например, 5 см. Присвоим стили абзацам, окружающим таблицу, и получим полностью сформатированную по нашим правилам, что невозможно даже в InDesign СS3, не говоря уже о более ранних версиях.
Перечисляем необходимые параметры:
DEFAULT_SIDE_INSET = DEFAULT_STROKE_WIDTH =
"0.5 mm" ;
VERTICAL_INSET = "1 mm";
narrow = "120 mm";
wide = "174 mm";
Используем нестандартный метод задания параметров — в явном виде, в миллиметрах, что зачастую нагляднее. Поскольку они превратятся из чисел в текстовые строки, соответствующе их оформим, заключив с обеих сторон в кавычки. Интересно, что InDesign понимает такую запись без дополнительных действий с нашей стороны — правильно считывает единицы измерения и устанавливает требуемые значения.
Как вариант подойдёт способ принудительного переключения в нужные единицы:
app.activeDocument.viewPreferences.horizontal
MeasurementUnits = MeasurementUnits.centimeters;
app.activeDocument.viewPreferences.vertical
MeasurementUnits = MeasurementUnits.centimeters;
Нам придётся использовать цвета для заливки ячеек таблицы. В отличие от названия стиля, который непосредственно в скрипте задать нельзя (как мы его видим в палитре Paragraph Styles, например, «Table»), с цветом ситуация значительно проще. InDesign понимает их названия такими, как мы видим в окне Swatches, и для цвета содержимого таблицы можно записать:
alterFill = "alterFillColor"; для шапки: headerFill = "headerFillColor";
Разумеется, эти цвета перед запуском скрипта должны присутствовать в публикации. Устанавливаем ссылки на объекты, с которыми будем работать:
myDocument = app.activeDocument;
Стандартная строка для работы с любым выделенным объектом:
mySelection = myDocument.selection[0];
Чтобы скрипт работал корректно, ничего в таблице выделять не будем, а просто обозначим установкой в неё курсора (это необходимо, если на странице несколько таблиц). Для обращения ко всей таблице получим:
myTable = mySelection.parent.parent;
Прямой родитель у точки вставки — ячейка, а у неё — таблица, а у той — текстовый фрейм, в котором она находится.
myTextFrame = myTable.parent;
Для использования стилей публикации создаём ссылки на них:
parStyles = myDocument.paragraphStyles;
Следующий шаг — проверка публикации на наличие требуемых стилей: это позволит избежать ошибки, если нужного нам не окажется. Перебираем по очереди все стили, найдя один из требуемых, устанавливаем соответствующий признак. InDesign хранит стили не по названиям, как цвета, а по индексам, поэтому присвоить стиль непосредственно по его названию не получится. Запоминать будем их индексы, по которым в дальнейшем будем обращаться.
Создадим временное хранилище для них.
parStylesStorage = new Array();//хранилище для индексов стилей
flagStorage = new Array();//здесь будем хранить признаки наличия требуемых стилей.
Запоминаем индексы используемых стилей:
for (i=0; i< parStyles.length; i++){
switch(parStyles[i].name){
case ‘Table Header’: parStylesStorage [‘Table Header’] = i;
flagStorage [0]=true; break;
case ‘Table Footer’: parStylesStorage [‘Table Footer’] = i;
flagStorage [1]=true; break;
case ‘Table contents’: parStylesStorage [‘Table contents’] = i;
flagStorage [2]=true; break;
case ‘Table’: parStylesStorage [‘Table’] = i;
flagStorage [3]=true; break;
case ‘Tbl Hdr’: parStylesStorage [‘Tbl Hdr’] = i;
flagStorage [4]=true; break;
}}
Операция break оптимизирует производительность скрипта: если искомый стиль найден, нет смысла продолжать его поиск, и можно переходить к следующему. Проверяем, все ли используемые стили есть в публикации:
if(flagStorage[0] && flagStorage[1] && flagStorage[2] && flagStorage[3] && flagStorage[4]) {
По умолчанию булевы выражения всегда сравниваются с true, поэтому не надо каждый раз использовать конструкцию типа if(flagStorage[…]==true).
Если все стили на месте, переходим к проверке типа выделенной области для корректной работы скрипта. Ведь нам нужно гарантировать, чтобы он был либо точкой вставки, либо абзацем, иначе (например, если выделена ячейка) выражение
myTable = mySelection.parent.parent;
потеряет смысл, т. к. жёстко привязано к конкретному типу выделенной области. Удостоверяемся, что выделение допустимо:
if (mySelection.constructor.name == "InsertionPoint" || mySelection.constructor.name == "Paragraph"){
Свойство constructor позволяет определить тип любого объекта и постоянно применяется для проверки корректности условий перед началом работы. Используется в связке со свойством name, позволяющим определять этот тип в удобной форме.
Приступаем к форматированию. Сначала присваиваем тексту в ячейках таблицы стиль Table contents:
for (i=0; i< myTable.cells.length; i++)…
Метод хороший, но медленный. Эксперименты с таблицами, занимающими от страницы и более, показали: нужно искать иное решение. Одна из причин медлительности — не оптимизированный подход к форматированию ячеек. В самом деле, мы по очереди перебираем все ячейки и к каждой по отдельности применяем несколько параметров форматирования. В таблицах с сотнями ячеек работа скрипта займёт много времени даже на мощной машине. Попробуем исправить ситуацию.