Think.JS №12

  • Для начинающих: Настройка текстового фрейма
  • Учим матчасть: Помещение файлов
  • Полевые испытания: Как пройти в библиотеку
  • Полезный скрипт: Бесконечное размножение

Содержание

Для начинающих: Настройка текстового фрейма

Учим матчасть: Помещение файлов

Полевые испытания: Как пройти в библиотеку

Полезный скрипт: Бесконечное размножение

Для начинающих

Настройка текстового фрейма

Основной составляющей документов, которые создаются в InDesign, является текст, поэтому неудивительно, что значительная часть скриптов также предназначена для обработки текстов. Подтверждением приоритетности теста является то, что из всех объектов типа pageItem только текстовый фрейм (textFrame) имеет значительное количество настроек, сгруппированных в специальном свойстве – объекте textFramePreferences.

Обращаться к свойствам объекта textFramePreferences нужно через ссылку на тот текстовый фрейм, настройки которого нужно изменить. Например, для изменения свойства ignoreWrap можно использовать следующую конструкцию.

ignoreTextWrap.jsx
Скрипт устанавливает атрибут игнорирования обтекания
with (app) {
  var myDoc = documents.add();
  var myTextFrame = myDoc.pages[0].textFrames.add({visibleBounds: [10,10,60,60]});
  with (myTextFrame.textFramePreferences) {
    ignoreWrap = true;
//    Устанавливаем игнорирование обтекания текста
  }
}

Если нужно изменить только одно свойство, то можно обращаться к нему напрямую без использования конструкции with().

 

ignoreTextWrap.jsx
Скрипт устанавливает атрибут игнорирования обтекания
with (app) {
  var myDoc = documents.add();
  var myTextFrame = myDoc.pages[0].textFrames.add({visibleBounds: [10,10,60,60]});
  myTextFrame.textFramePreferences.ignoreWrap = true;
// Устанавливаем игнорирование обтекания текста
}

Кроме атрибута игнорирования обтекания текста, с помощью объекта textFramePreferences решаются три задачи: устанавливаются отступы внутри текстового фрейма, определяется количество колонок в нем и определяется выравнивание.

Чтобы определить отступы, нужно изменить свойство insetSpacing. Его значением является массив из четырех чисел от 0 до 8640 пунктов (хотя значения отступов задаются в текущих единицах измерения). Порядок следования значений в массиве таков: [верхний, левый, нижний, правый].

setSpasing.jsx
Скрипт демонстрирует установку отступов в текстовом фрейме
with (app) {
  var myDoc = documents.add();
  var myTextFrame = myDoc.pages[0].textFrames.add({visibleBounds: [10,10,60,60]});
  myTextFrame.textFramePreferences.insetSpacing = [5,3,5,3];
// Устанавливаем значения отступов в тестовом фрейме
}

Можно указывать значение не в текущих единицах измерения, а в произвольных, при этом используя разные единицы измерения (значения будут преобразованы автоматически).

setSpasing.jsx
Скрипт демонстрирует установку отступов в текстовом фрейме
with (app) {
  var myDoc = documents.add();
  var myTextFrame = myDoc.pages[0].textFrames.add({visibleBounds: [10,10,60,60]});
  myTextFrame.textFramePreferences.insetSpacing = ["5pt","3mm","5pt","3mm"];
// Устанавливаем значения отступов в тестовом фрейме, указав значение в пунктах
  alert(myTextFrame.textFramePreferences.insetSpacing);
}

Есть еще одно свойство, влияющее на отступ сверху в текстовом фрейме. Это firstBaselineOffset – свойство, определяющее, как будет вычисляться положение первой строки текста во фрейме. Для определения значений используется нумератор FirstBaseline, который содержит значения: FirstBaseline. ascentOffset (расстояние с учетом максимальной высоты букв), FirstBaseline.capHeight (расстояние в зависимости от высоты заглавных букв – при этом значении некоторые буквы могут быть выше границы фрейма), FirstBaseline.leadingOffset (отступ по размеру межстрочного расстояния), FirstBaseline.emboxHeight (такое свойство невозможно установить вручную, поэтому о значении можно только догадываться), FirstBaseline.xHeight (отступ по средней высоте строчной буквы), FirstBaseline.fixedHeight (фиксированное значение, по умолчанию равно нулю). Заметим, что в документации (по крайней мере, в варианте chm) есть ошибки в названии свойств нумератора. Правильные названия приведены выше.

Дополнительным модификатором отступа сверху является свойство minimumFirstBaselineOffset, которое определяет минимальное расстояние отступа сверху. Это свойство может принимать значение от 0 до 8640 пунктов, так же, как и значение отступов. Если реальное расстояние от границы фрейма меньше, чем указанное в этом свойстве, текст смещается на расстояние, соответствующее значению свойства.

При одновременном указании значения отступов в текстовом фрейме, смещения и минимального смещения эти значения накладываются друг на друга. Например, смещение (firstBaselineOffset) и минимальное смещение (minimumFirstBaselineOffset) будут определяться не от границы фрейма, а от границы отступов.

insetAndOffset.jsx
Скрипт демонстрирует различные свойства, отвечающие за реальное значение отступа сверху тестового фрейма
with (app) {
  var myDoc = documents.add();
  var myTextFrame = myDoc.pages[0].textFrames.add({visibleBounds: [10,10,60,60]});
  with (myTextFrame.textFramePreferences) {
    insetSpacing = [5,3,5,3];
// Устанавливаем значения отступов
    firstBaselineOffset = FirstBaseline.fixedHeight;
// Устанавливаем параметр смещения
    minimumFirstBaselineOffset = "5mm";
// Устанавливаем минимальное значение смещения    
  }
}

Разбиение текстового фрейма на колонки определяется при помощи трех свойств: textColumnCount, textColumnGutter и textColumnFixedWidth. Свойство textColumnCount определяет количество колонок во фрейме. По умолчанию значение этого свойства равно 1, максимальное значение – 40. Свойство textColumnGutter определяет межколоночное расстояние. Значение этого свойства может быть от 0 до 8640 пунктов. Свойство textColumnFixedWidth определяет фиксированную ширину колонки.

setColumns.jsx
Скрипт устанавливает количество колонок и межколоночное расстояние в текстовом фрейме
with (app) {
  var myDoc = documents.add();
  var myTextFrame = myDoc.pages[0].textFrames.add({visibleBounds: [10,10,60,60]});
  with (myTextFrame.textFramePreferences) {
    textColumnCount = 3;
// Устанавливаем количество колонок
    textColumnGutter = 0;
// Устанавливаем межколоночный интервал    
  }
}

Значение textColumnGutter = 0 устанавливается редко, поскольку при этом значении в сочетании с выключкой по формату колонки совершенно сливаются, что делает текст нечитаемым. Размер колонки в текстовом фрейме определяется так: сначала по свойству geometricBounds вычисляется ширина фрейма, затем из этого значение отнимается размер межколонного расстояния, умноженный на количество колонок, уменьшенное на единицу (количество межколонников всегда меньше количества колонок), затем полученное значение делится на количество колонок.

Свойство textColumnFixedWidth (значение от 0 до 8640 пунктов) действует очень интересно. Если свойство useFixedColumnWidth (использовать фиксированное значение колонки) будет установлено в значение true, то размер текстового фрейма будет зависеть от размера колонки и количества колонок во фрейме. При значении useFixedColumnWidth = false, наоборот, размер колонки будет определяться размером фрейма и количеством колонок в нем.

setFixedColumnWidth.jsx
Скрипт устанавливает фиксированное значение размера колонок
with (app) {
  var myDoc = documents.add();
  var myTextFrame = myDoc.pages[0].textFrames.add({visibleBounds: [10,10,60,60]});
  alert(myTextFrame.visibleBounds);
  with (myTextFrame.textFramePreferences) {
    textColumnCount = 3;
// Устанавливаем количество колонок
    textColumnGutter = 5;
// Устанавливаем межколоночный интервал
    textColumnFixedWidth = 30;
// Устанавливаем значение фиксированного размера колонки
    useFixedColumnWidth = true;
// Включаем использование фиксированного размера
  }
  alert(myTextFrame.visibleBounds);
}

Текстовый фрейм, у которого включено использование фиксированного размера колонки, может быть изменен по ширине без использования visibleBounds – при изменении количества колонок он автоматически изменяется в размерах. И обратно, изменение размеров такого фрейма приводит к изменению количества колонок в нем.

setBoundsWithFixedWidth.jsx
Скрипт демонстрирует изменение количества колонок в текстовом фрейме при изменении размеров.
with (app) {
  var myDoc = documents.add();
  var myTextFrame = myDoc.pages[0].textFrames.add({visibleBounds: [10,10,60,60]});
  with (myTextFrame.textFramePreferences) {
    textColumnCount = 3;
// Устанавливаем количество колонок
    textColumnGutter = 5;
// Устанавливаем межколоночный интервал
    textColumnFixedWidth = 30;
// Устанавливаем значение фиксированного размера колонки
    useFixedColumnWidth = true;
// Включаем использование фиксированного размера
  }
  myTextFrame.visibleBounds = [10,10,75,75];
  alert(myTextFrame.textFramePreferences.textColumnCount);
}

Вертикальное выравнивание текста определяется при помощи свойства verticalJustification, которое принимает одно из значений нумератора VerticalJustification. Возможные значения: VerticalJustification.topAlign (выравнивание по верхней границе, значение по умолчанию), VerticalJustification.centerAlign (выравнивание по центру), VerticalJustification.bottomAlign (выравнивание по нижней границе), VerticalJustification.justifyAlign (выравнивание по формату). В качестве дополнительного параметра используется свойство verticalThreshold
(от 0 до 8640 пунктов), которое определяет максимальное расстояние между абзацами при растягивании текста.

verticalJustify.jsx
Скрипт демонстрирует использование вертикального выравнивания
with (app) {
  var myDoc = documents.add();
  var myTextFrame = myDoc.pages[0].textFrames.add({visibleBounds: [10,10,60,60]});
  with (myTextFrame.textFramePreferences) {
    verticalJustification = VerticalJustification.justifyAlign;
// Устанавливаем значение выравнивания
    verticalThreshold = 6;
// Устанавливаем максимальный интервал между абзацами
  }
}

При установленных отступах и смещениях вертикальное выравнивание будет установлено в зависимости от значений отступов и смещений

justifyWithInset.jsx
Скрипт демонстрирует вертикальное выравнивание в зависимости от отступов
with (app) {
  var myDoc = documents.add();
  var myTextFrame = myDoc.pages[0].textFrames.add({visibleBounds: [10,10,60,60]});
  with (myTextFrame.textFramePreferences) {
    insetSpacing = [5,3,5,3];
    firstBaselineOffset = FirstBaseline.fixedHeight;
    minimumFirstBaselineOffset = "5mm";    
    verticalJustification = VerticalJustification.justifyAlign;
    verticalThreshold = 6;
  }
}

Учим матчасть

Помещение файлов

Интересная особенность: процесс сохранения файлов в формате, отличном от документа InDesign называется экспортом, а процесс помещения в InDesign файлов импортом не называется. Термин импорт (import) и одноименный метод предназначен для работы со стилями, которые могут передаваться между документами. Сегодня мы рассмотрим как раз процесс помещения файлов.

Метод place(), с помощью которого происходит помещение файлов, определен практически для всех объектов типа pageItem (кроме объекта group), для некоторых текстовых объектов, а также для объектов типа документ (document) и страница (page). У разных типов объектов работа метода имеет свою специфику, поэтому для эффективной работы желательно знать, как происходит помещение файлов при вызове метода для разных типов объектов и использовать те, которые лучше подходят в конкретной ситуации.

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

Процесс помещения имеет весьма полезную особенность. Тип помещаемого файла определяется не расширением, а внутренней структурой (специфично для MacOS), поэтому есть возможность работы с файлами нестандартных расширений. Главное, чтобы внутренняя структура файла могла быть распознана InDesign.

В первую очередь рассмотрим работу метода place() объекта типа document

placeInDocument.jsx
Скрипт демонстрирует работу метода place() объекта типа document
with (app) {
  var myDoc = documents.add();
  var myFile = Folder.myDocuments.openDlg("Выберите помещаемый файл:", "Текстовые файлы: *.txt");
// Выбираем файл
  if (myFile != null) {
    myDoc.place(myFile, false);
// Помещаем файл
  }
}

В чем особенность этого метода? В том, что по своему действию он полностью схож с действием команды Place в меню в том случае, если перед вызовом команды не был выделен ни один объект. После выполнения метода курсор также принимает вид в зависимости от типа помещаемого файла (текстовый или графический). Пользователь может выбрать положение контейнера для помещения, его размеры, а в случае помещения текстового файла – автозаполнение.

В большинстве случаев метод place() принимает три параметра: имя помещаемого файла (обязательный параметр), логическое значение showingOptions, которое означает, будет ли показан диалог помещения файла (true – будет, false – нет) и массив с настройками импорта в виде {Свойство1: значение1, Свойство2: значение2, … СвойствоN: значениеN}. Метод возвращает помещенный объект – объект типов pageItem, image, story, text.

Метод place() объекта page (страница) имеет более широкие настойки. В качестве параметров используются следующие значения: имя помещаемого файла (обязательный параметр), координаты точки вставки (массив из двух чисел [x,y], определяющий координаты верхней левой точки объекта, который будет создан при помещении файла), слой, куда будет помещен файл (в виде переменной, ссылающейся на него), логическое значение showingOptions (управление диалогом), логическое значение autoflowing (автозаполнение: при true – включено, при false – выключено) и массив с настройками импорта.

placeTextOnPage.jsx
Скрипт демонстрирует помещение текстового файла на указанную страницу
with (app) {
  var myDoc = documents.add();
  var myFile = Folder.myDocuments.openDlg("Выберите помещаемый файл:", "Текстовые файлы: *.txt");
// Выбираем файл
  if (myFile != null) {
    var myObj = myDoc.pages[0].place(myFile, [30,20], undefined, false, false);
// Помещаем файл на первую страницу
  alert(myObj);
  }
}

При помещении файла в окне документа может быть открыта совсем другая страница – на работоспособность кода это никакого влияния не оказывает. Некоторые параметры можно не указывать – чтобы использовались значения по умолчанию, например, для помещения файла на активный слой, используется значение undefined.

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

placeImageOnPage.jsx
Скрипт демонстрирует помещение графического файла на указанную страницу
with (app) {
  var myDoc = documents.add();
  var myFile = Folder.myDocuments.openDlg("Выберите помещаемый файл:", "Файлы JPG: *.jpg");
// Выбираем файл
  if (myFile != null) {
    var myObj = myDoc.pages[0].place(myFile, [30,20], undefined, false, false);
// Помещаем файл на первую страницу
  alert(myObj)
  }
}

Помещение файлов в объекты типа pageItems выполняется с тем же списком параметров, как и помещение в объект типа document. После помещения файла предыдущее содержимое фрейма удаляется.

placeImageInRectangle.jsx
Скрипт демонстрирует помещение графического файла в прямоугольник
with (app) {
  var myDoc = documents.add();
  var myFile = Folder.myDocuments.openDlg("Выберите помещаемый файл:", "Файлы JPG: *.jpg");
// Выбираем файл
  var myRectangle = myDoc.pages[0].rectangles.add({visibleBounds: [10,10,60,60]});
// Создаем прямоугольник
  if (myFile != null) {
    var myObj = myRectangle.place(myFile, false, undefined);
// Помещаем файл
  }
}

Если в pageItem поместить текстовый файл, то он автоматически трасформируется в текстовый фрейм, сохранив при этом внешний вид.

placeTextInRectangle.jsx
Скрипт демонстрирует помещение текстового файла в многоугольник
with (app) {
  var myDoc = documents.add();
  var myFile = Folder.myDocuments.openDlg("Выберите помещаемый файл:", "Текстовые файлы: *.txt");
// Выбираем файл
  var myPoly = myDoc.pages[0].polygons.add({visibleBounds: [10,10,60,60]});
// Создаем прямоугольник
  if (myFile != null) {
    var myObj = myPoly.place(myFile, false, undefined);
// Помещаем файл
  }
}

В одиночный текстовый фрейм файлы помещаются точно также как и в другие объекты типа pageItem, причем помещение графического файла автоматически преобразует текстовый фрейм в соответствующий объект типа pageItem. В текстовый фрейм, связанный с другими, файлы вообще не помещаются. В этом случае есть два решения. Если в текстовом фрейме уже есть текст и его нужно заменить, то определяется объект типа text, содержащий весь текст фрейма, для которого и вызывается метод place(). Если в текстовом фрейме текста нет (равно как и в том случае, если текста нет во всем объекте типа story), используется метод place() объекта типа insertPoint.

placeFileReplaceContents.jsx
Скрипт демонстрирует помещение текстового файла в связанный текстовый фрейм с заменой содержимого
with (app) {
  var myDoc = documents.add();
  var myFile = Folder.myDocuments.openDlg("Выберите помещаемый файл:", "Текстовые файлы: *.txt");
// Выбираем файл
  var myTextFrame = myDoc.pages[0].textFrames.add({visibleBounds: [10,10,60,60]});
// Создаем текстовый фрейм
  myTextFrame.nextTextFrame = myDoc.pages[0].textFrames.add({visibleBounds: [70,10,130,60]});
// Создаем связанный текстовый фрейм
  myTextFrame.parentStory.contents = "Ветер по морю гуляет и кораблик подгоняет.";
// Задаем содержимое
  if (myFile != null) {
    with (myTextFrame.parentStory) {
      var myText = insertionPoints.itemByRange(insertionPoints.firstItem(), insertionPoints.lastItem());
// Получаем объект типа text для всего текста статьи
    }
    var myObj = myText.place(myFile, false, undefined);
// Помещаем файл
  }
}

Если нужно добавить файл в конец уже существующего теста, или вставить его в произвольное место в тексте, используется метод place() объекта типа insertPoint.

placeFileAddContents.jsx
Скрипт демонстрирует помещение текстового файла в связанный текстовый фрейм с добавлением содержимого
with (app) {
  var myDoc = documents.add();
  var myFile = Folder.myDocuments.openDlg("Выберите помещаемый файл:", "Текстовые файлы: *.txt");
// Выбираем файл
  var myTextFrame = myDoc.pages[0].textFrames.add({visibleBounds: [10,10,60,60]});
// Создаем текстовый фрейм
  myTextFrame.nextTextFrame = myDoc.pages[0].textFrames.add({visibleBounds: [70,10,130,60]});
// Создаем связанный текстовый фрейм
  myTextFrame.parentStory.contents = "Ветер по морю гуляет и кораблик подгоняет.\u000D";
// Задаем содержимое
  if (myFile != null) {
     var myIP = myTextFrame.parentStory.insertionPoints.lastItem();
// Получаем последнюю точку вставки 
    var myObj = myIP.place(myFile, false, undefined);
// Помещаем файл
  }
}

При помощи этого же метода в текст могут быть вставлены графические inline-объекты.

placeInline.jsx
Скрипт демонстрирует возможность вставки графического файла как inline
with (app) {
  var myDoc = documents.add();
  var myFile = Folder.myDocuments.openDlg("Выберите помещаемый файл:", "Файлы jpg: *.jpg");
// Выбираем файл
  var myTextFrame = myDoc.pages[0].textFrames.add({visibleBounds: [10,10,60,60]});
// Создаем текстовый фрейм
  myTextFrame.nextTextFrame = myDoc.pages[0].textFrames.add({visibleBounds: [70,10,130,60]});
// Создаем связанный текстовый фрейм
  myTextFrame.parentStory.contents = "Ветер по морю гуляет и кораблик подгоняет.\u000D";
// Задаем содержимое
  if (myFile != null) {
     var myIP = myTextFrame.parentStory.insertionPoints.lastItem();
// Получаем последнюю точку вставки 
    var myObj = myIP.place(myFile, false, undefined);
// Помещаем файл
  }
}

Полевые испытания

Как пройти в библиотеку

Не только в три часа ночи, но и в любое другое удобное время можно открыть объект типа library и получить из него сохраненный объект совершенно безвозмездно, то есть даром. Можно также сохранить в библиотеке любой объект типа pageItem для дальнейшего использования. О том, как это сделать – в сегодняшней статье.

Что такое библиотека (library) в InDesign? В общем виде – это хранилище объектов, который были сохранены пользователем (или скриптом, который запустил пользователь). Технически – это файл. Внутренняя структура этого файла нам в данный момент неинтересна, важно только то, что с библиотекой можно обращаться как со всяким другим файлом, например, открывать, предоставив пользователю возможность выбора библиотеке в диалоге открытия файлов.

openLibrary.jsx
Скрипт открывает выбранную пользователем библиотеку
with (app) {
  var myFile = Folder.myDocuments.openDlg("Открыть библиотеку:", "Библиотека InDesign: *.indl");
// Выбираем файл библиотеки
  if (myFile != null) {
    open(myFile);
// Открываем библиотеку как документ
  }
}

Чтобы создать новую библиотеку, также нужен файл – для сохранения.

createLibrary.jsx
Скрипт создает новую библиотеку
with (app) {
  var myFile = Folder.myDocuments.saveDlg("Сохранить библиотеку:", "Библиотека InDesign: *.indl");
// Выбираем файл библиотеки
  if (myFile != null) {
    libraries.add(myFile);
// Сохраняем библиотеку
  }
}

Как и документ, библиотека в InDesign имеет свойства name, fullName и fullPath для определения имени, полного имени и имени родительской папки соответственно. И точно так же, как документ, библиотека может быть закрыта путем вызова метода close(). Разница только в том, что, в отличие от документа, закрытие библиотеки не вызывает подтверждения о сохранении. Видимо, библиотека сохраняется в процессе работы.

saveCloseLibrary.jsx
Скрипт создает библиотеку и закрывает ее
with (app) {
  var myFile = Folder.myDocuments.saveDlg("Сохранить библиотеку:", "Библиотека InDesign: *.indl");
// Выбираем файл библиотеки
  if (myFile != null) {
    var myLib = libraries.add(myFile);
// Сохраняем библиотеку
  }
  alert(myLib.fullName);
  myLib.close();
// Закрываем библиотеку  
}

Объект, содержащийся в библиотеке, называется asset
(актив). В качестве актива могут быть сохранены объекты pageItems, графические изображения различных форматов и даже элементы xml-структуры документа. Создаются активы при помощи метода store() той библиотеки, куда их нужно сохранить. В качестве параметра всегда передается массив, даже в том случае, когда в состав актива входит всего один элемент. Все элементы массива должны находиться на одном развороте, иначе InDesign завершится аварийно. Эта ошибка при обычной работе невозможна, поскольку InDesign не позволяет выделять объекты на разных разворотах одновременно.

storeAsset.jsx
Скрипт демонстрирует метод добавления актива в библиотеку
with (app) {
  var myFile = Folder.myDocuments.openDlg("Открыть библиотеку:", "Библиотека InDesign: *.indl");
// Выбираем файл библиотеки
  if (myFile != null) {
    var myLib = open(myFile);
// Открываем библиотеку
  }
  var myDoc = documents.add();
  var myTextFrame = myDoc.pages[0].textFrames.add({visibleBounds: [10,10,60,60], contents: "Дробясь о мрачные скалы, шумят и пенятся валы"});
// Подготавливаем текстовый фрейм для сохранения
  var myAsset = myLib.store([myTextFrame]);
// Сохраняем фрейм как актив (параметр - всегда массив)
  myAsset.name = "Стих";
// Задаем имя актива
  myAsset.description = "Из классиков"
// Задаем описание актива
  alert(myLib.assets.length);  
}

Чтобы поместить актив из библиотеки в документ, используется метод placeAsset(), который в качестве параметра принимает целевой документ.

placeAsset.jsx
Скрипт помещает в новый документ первый актив выбранной библиотеки
with (app) {
  var myFile = Folder.myDocuments.openDlg("Открыть библиотеку:", "Библиотека InDesign: *.indl");
// Выбираем файл библиотеки
  if (myFile != null) {
    var myLib = open(myFile);
// Открываем библиотеку
  }
  alert(myLib.assets.length);
  if (myLib.assets.length > 0) {
// Проверяем наличие активов в библиотеке
    var myDoc = documents.add();
// Создаем документ
    var myArr = myLib.assets.firstItem().placeAsset(myDoc);
// Помещаем актив на страницу
    alert(myArr.constructor.name);
  }
}

Метод placeAsset() возвращает массив объектов, что вполне логично, поскольку метод store() принимает в качестве параметра также массив. Этим можно воспользоваться и сгруппировать все элементы актива для того, чтобы иметь возможность трансформировать и удалять все элементы актива одновременно.

Удаляются активы из библиотеки при помощи метода remove(). После удаления актива восстановить его невозможно.

removeAssets.jsx
Скрипт удаляет все активы из выбранной библиотеки
with (app) {
  var myFile = Folder.myDocuments.openDlg("Открыть библиотеку:", "Библиотека InDesign: *.indl");
// Выбираем файл библиотеки
  if (myFile != null) {
    var myLib = open(myFile);
// Открываем библиотеку
  }
  while (myLib.assets.length > 0) {
// Пока в библиотеке есть хотя бы один актив
    myLib.assets.firstItem().remove();
// Удаляем первый актив
  }
}

Полезный скрипт

Бесконечное размножение

Когда-то давным-давно, когда Data Merge не входил в стандартную поставку InDesign, задачу по обработке переменных данных решить было нелегко. Приходилось выкручиваться при помощи скриптов, причем некоторые выкрутасы были довольно удачными. Один пример такого решения мы рассмотрим.

Скрипт основан а использовании переменных данных, которые хранятся в csv. В прошлой рассылке я уже рассказывал, как этот полезный формат (его, кстати, использует и Data Merge) может пригодиться нам в работе. Порядок работы следующий. В csv сохраняются некие данные, причем верхняя строка считается заголовочной. Содержимое ячеек в ней будем считать именами полей переменных данных. В InDesign подготавливается библиотека как минимум с одним активом, в котором присутствуют текстовые объекты, которые содержат имена полей данных. При работе скрипта выбранный актив помещается на новую страницу создаваемого скриптом документа, после чего происходит замена имен полей данных на данные из очередной строки.

multiAsset.jsx
Скрипт для обработки переменных данных с использованием активов
function readFile () {   
  var myResult = [];   
  try {   
    var myFile = Folder.myDocuments.openDlg("Выберите файл:", "CSV (разделители - запятые): *.csv");   
    with (myFile) {   
      open("r");   
      while (!eof) {   
        var myString = readln();   
        if (myString != "") {   
          var myArr = myString.split(";");   
          myResult.push(myArr);   
        }   
      }   
      close();   
      return myResult;   
    }   
  } catch (error) {   
    return null;   
  }     
}
function multiAssets (myAsst, myData) {
  var myDoc = app.documents.add();
  myDoc.documentPreferences.facingPages = false;
// Отключаем развороты в документе
  for (var counter = 1; counter < myData.length; counter++) {
// Для каждой записи в файле, кроме первой
    var myPage = myDoc.pages.add();
// Добавляем страницу
    var myArr = myAsst.placeAsset(myDoc);
// Помещаем актив
    var myGroup = myPage.groups.add(myArr);
// Группируем актив 
    myGroup.move(myPage);
    myGroup.move([0,0]);
// Перемещаем группу в 0 
    app.findPreferences = null;
    app.changePreferences = null;
    for (var dcounter = 0; dcounter < myData[0].length; dcounter++) {
// Для каждой ячейки в записи производим замену заголовочного значения на реальное.      
      myDoc.search(myData[0][dcounter], false, false, myData[counter][dcounter]);
    }
    app.findPreferences = null;
    app.changePreferences = null;
  }
}
with (app) {
  if (libraries.length < 1) {
// Если не открыта ни одна библиотека, предлагаем открыть
    var myFile = Folder.myDocuments.openDlg("Открыть библиотеку:", "Библиотека InDesign: *.indl");
    if (myFile != null) {
      var myLib = open(myFile);
    } else {
      alert("Библиотека не выбрана!");
      exit();
    }
  }
  if (libraries.length > 1) {
// Если открыто несколько библиотек, то собираем их имена и предлагаем выбор в диалоге
    var myNames = [];
    for (var counter = 0; counter < libraries.length; counter++) {
      myNames.push(libraries[counter].name);
    }
    var myDialog = dialogs.add();
    with (myDialog.dialogColumns.add().borderPanels.add().dialogColumns.add()) {
      dialogRows.add().staticTexts.add({staticLabel: "Выберите библиотеку:"});
      var userLib = dialogRows.add().dropdowns.add({stringList: myNames, selectedIndex: 0});
    }
    var myResult = myDialog.show();
    if (!myResult) {
      exit();
    }
    var myLib = libraries[userLib.selectedIndex];
  } else {
// Если открыта одна библиотека, выбираем ее
    var myLib = libraries[0];
  }
  if (myLib.assets.length == 0) {
// Проверяем наличие активов    
    alert("В библиотеке нет активов");
    exit();
  }
  if (myLib.assets.length > 1) {
// Если активов больше, чем один, предлагаем выбор
    var myNames = [];
    for (var counter = 0; counter < myLib.assets.length; counter++) {
      myNames.push(myLib.assets[counter].name);
    }
    var myDialog = dialogs.add();
    with (myDialog.dialogColumns.add().borderPanels.add().dialogColumns.add()) {
      dialogRows.add().staticTexts.add({staticLabel: "Выберите актив:"});
      var userAsst = dialogRows.add().dropdowns.add({stringList: myNames, selectedIndex: 0});
    }
    var myResult = myDialog.show();
    if (!myResult) {
      exit();
    }
    var myAsst = myLib.assets[userAsst.selectedIndex];
  } else {
// Если актив один - выбираем его    
    var myAsst = myLib.assets[0];
  }
  var myData = readFile();
  if (myData.length < 2) {
    alert("Неполные исходные данные!");
    exit();
  }
  multiAssets(myAsst, myData);
}

Олег Бутрин
THINK.JS выпуск № 12 от 2007-01-22

Оставьте комментарий