Избранное »

22.09.2014 – 07:27 | 2 комментария | 8 222 views

Здравствуйте все, кто работает в Индизайне!
Извещаем вас о том, что на youtube.com начал работу канал «InDesign Мастерская вёрстки». Там уже размещены более 60 видео с полным описанием как работать с программой DoTextOK. Другие интересные темы, касающиеся работы …

Читать полностью »
Работа в InDesign

Хитрости и секреты, приемы работы, уроки

Новая версия!

Особенности новой версии Индизайна

Плагины

Описание плагинов, информация о плагинах для работы с Adobe InDesign

Скрипты

Готовые к использованию скрипты для Adobe InDesign

Скриптинг

Описание языка, приёмов и методов программирования для Adobe InDesign

Home » Скриптинг

Программирование привязанных объектов, часть 2

Добавлено на 02.04.2013 – 07:58Без комментариев | 1 759 views

Отвязать привязанный объект

Отвязать привязанный объект можно при помощи метода releaseAnchoredObject()

app.selection[0].anchoredObjectSettings.releaseAnchoredObject()// Отвязываем выделенный привязанный объект

Еще несколько неупомянутых выше параметров привязки

1. Свойство lockPosition (true, false). Если этот параметр получает значение true, то ручное позиционирование привязанного объекта будет запрещено.
2. Свойство pinPosition (true, false). Если pinPosition = true, то привязанный фрейм удерживается в границах колонок текстового фрейма по высоте.

Родители

Обычно родителем текстового фрейма, расположенного на полосе, является разворот (Spread), но по другому дело обстоит в случае привязанного фрейма. Он рассматривается как символ, как буква в текстовом фрейме, и его родителем является Character.

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

var isAnchoredTextFrame = function(obj)
{
if(obj.constructor.name == "TextFrame" && obj.parent.constructor.name == "Character")
return true;
else return false;
}

Функция будет возвращать значение true, если объект привязан, и false в противоположном случае.

// Вызов функции isAnchoredTextFrame для выделенного объекта
alert(isAnchoredTextFrame(app.selection[0]));
// Применение isAnchoredTextFrame для установки фиттинга во всех привязанных текстовых фремах документа
var pItems = app.activeDocument.allPageItems;
 
while (p=pItems.pop())
if (isAnchoredTextFrame(p))
p.fit(FitOptions.frameToContent);

Находится ли привязанный объект на странице?

Вручную в Индизайне создадим текстовый фрейм с привязаннм фреймом или сделаем такую конструкцию при помощи ранее приведенных скриптов, например CreateAnchoredFrame.jsx. Мы видим на странице документа 2 фрейма. Выполним этот скрипт:

myDoc = app.activeDocument;
myPage = myDoc.pages[0];
alert("На странице расположено текстовых фреймов - " + myPage.textFrames.length);

Будет получено сообщение, что фрейм на странице один! А привязанный фрейм? Он находится в основном, но не странице! И доступ к нему в нашем случае можно получить так

myPage.textFrames[0].textFrames[0];

Текстовые фреймы в Story (myStory.textFrames)

Создадим на полосе цепочку из двух связанных текстовых фреймов. В первом фрейме сделаем два привязанных текстовых фрейма, во втором — один привязанный фрейм (см. рис.)

Страница документа

Выполним скрипт:

// Текущая страница
myPage = app.activeWindow.activePage;
// Первый текстовый фрейм на полосе из цепочки
// (Мы уже знаем, что привязанные фреймы не находятся на полосе)
myTextFrame = myPage.textFrames[0];
// Получаем ссылку на материал (Story)
myStory = myTextFrame.parentStory;
// Сколько текстовых фреймов содержит материал?
alert("Текстовых фреймов в материале " + myStory.textFrames.length);

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

alert("Текстовых контейнеров в материале " + myStory.textContainers.length);

и запустим его.

В результате получим значение — 2, что и ожидалось.
Конечно, описанным выше действием выражение myStory.textFrames не исчерпывается, более подробно об этом будет рассказано в следующий раз.

Удаление пустых привязанных текстовых фреймов

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

//Olav Martin Kvern (okvern@ix.netcom.com)
//RemoveEmptyTextFrames.jsx
//An InDesign CS6 ExtendScript
//
#target indesign
main();
function main(){
//If there's at least one document open, process the first document.
if(app.documents.length > 0){
removeEmptyTextFrames(app.documents.item(0));
}
}
function removeEmptyTextFrames(document){
//Iterate through the stories in the document.
for(var counter = document.stories.length -1; counter >= 0; counter--){
processStory(document.stories.item(counter));
}
}
function processStory(story){
//Iterate through the text containers (which will include any linked text paths) in the story.
for(var counter = story.textContainers.length-1; counter >= 0; counter--){
//if the text container (text frame or text path) does not contain
//anything, remove it.
if(story.textContainers[counter].contents == ""){
story.textContainers[counter].remove();
}
}
//Now process any inline text frames in the story.
//Comment this function out to retain empty inline text frames.
for(counter = story.textFrames.length-1; counter >= 0; counter --){
//If the inline text frame does not contain anything, remove it.
if(story.textFrames.item(counter).contents == ""){
story.textFrames.item(counter).remove();
}
}
}

Привязка графических фреймов, уже расположенных на полосе

В рассмотренных выше примерах привязанный объект создавался скриптом. Но как быть, если требуется привязать уже готовый объект, расположенный на полосе? Основная идея в этом случае — вырезать объект будущей привязки (app.cut()) и вставить его в нужное место текстового фрейма (app.paste()).
Пример:

// CreateAnchoredRectangle.jsx
var myDocument = app.documents.add();
// Устанавливаем единицы измерения
myDocument.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.points;
myDocument.viewPreferences.verticalMeasurementUnits = MeasurementUnits.points;
// Получаем ссылку на 1-ю страницу документа
var myPage = myDocument.pages.item(0);
// Добавляем текстовый фрейм
var myTextFrame = myPage.textFrames.add({geometricBounds:myGetBounds(myDocument, myPage), contents:TextFrameContents.placeholderText});
myTextFrame.texts.item(0).leftIndent = 104;
// Добавляем прямоугольник на страницу
var myRectangle = myPage.rectangles.add({geometricBounds:[0,0, 20,100]});
// Текстовый фрейм и прямоугольник уже на полосе.
// Приступаем к привязке прямоугольника, находим точку вставки - после первого абзаца
var myInsertionPoint = myTextFrame.paragraphs.item(1).insertionPoints.item(0);
// Вставляем прямоугольник как привязанный объект
myRectangle.select();
app.cut();
myInsertionPoint.select();
app.paste();
myTextFrame.texts.item(0).recompose;
// Ссылка на вставленный прямоугольник
var myAnchoredRectangle = myTextFrame.rectangles[0];
// Параметры привязки:
with(myAnchoredRectangle.anchoredObjectSettings){
anchoredPosition = AnchorPosition.anchored;
spineRelative = false;
anchorPoint = AnchorPoint.topLeftAnchor;
horizontalReferencePoint = AnchoredRelativeTo.anchorLocation;
horizontalAlignment = HorizontalAlignment.leftAlign;
anchorXoffset = 104;
verticalReferencePoint = VerticallyRelativeTo.lineBaseline;
anchorYoffset = 10;
anchorSpaceAbove = 10;
}
 
function myGetBounds(myDocument, myPage){
var myPageWidth = myDocument.documentPreferences.pageWidth;
var myPageHeight = myDocument.documentPreferences.pageHeight
if(myPage.side == PageSideOptions.leftHand){
var myX2 = myPage.marginPreferences.left;
var myX1 = myPage.marginPreferences.right;
}
else{
var myX1 = myPage.marginPreferences.left;
var myX2 = myPage.marginPreferences.right;
}
var myY1 = myPage.marginPreferences.top;
var myX2 = myPageWidth - myX2;
var myY2 = myPageHeight - myPage.marginPreferences.bottom;
return [myY1, myX1, myY2, myX2];
}

В InDesign CS5.5 (и в ID CS6) появился новый метод привязки объектов, который в объектной модели описан так:

void insertAnchoredObject (storyOffset: InsertionPoint[, anchoredPosition: AnchorPosition]),

где необязательный параметр AnchorPosition является режимом привязки:
AnchorPosition.INLINE_POSITION
AnchorPosition.ABOVE_LINE
AnchorPosition.ANCHORED

Поэтому можно строки скрипта

myRectangle.select();
app.cut();
myInsertionPoint.select();
app.paste();

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

myRectangle.anchoredObjectSettings.insertAnchoredObject(myInsertionPoint);

Хотя метод cut()-paste() также работает в InDesign CS5.5, CS6, но скрипт с использованием нового метода insertAnchoredObject будет выполняться быстрее. Поэтому целесообразно сделать развилку в скрипте для старых и новых версий.

// Начало скрипта
//.........................
// Определяем версию Индизайна
var appVersion = parseFloat(app.version);
// Развилка по версии
if(appVersion > 7)
myRectangle.anchoredObjectSettings.insertAnchoredObject(myInsertionPoint);
else {
myRectangle.select();
app.cut();
myInsertionPoint.select();
app.paste();
}
// Продолжение и окончание скрипта

Использование объектного стиля

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

Пример:

// CreateAnchoredFrameWithObjStyle.jsx
var myDocument = app.documents.add();
// Устанавливаем единицы измерения
myDocument.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.points;
myDocument.viewPreferences.verticalMeasurementUnits = MeasurementUnits.points;
// Получаем ссылку на 1-ю страницу документа
var myPage = myDocument.pages.item(0);
// Добавляем текстовый фрейм
var myTextFrame = myPage.textFrames.add({geometricBounds:myGetBounds(myDocument, myPage), contents:TextFrameContents.placeholderText});
myTextFrame.texts.item(0).leftIndent = 104;
// Вставляем объект после первого абзаца
var myInsertionPoint = myTextFrame.paragraphs.item(1).insertionPoints.item(0);
var myAnchoredFrame = myInsertionPoint.textFrames.add();
//Recompose the text to make sure that getting the geometric bounds of the inline graphic will work.
myTextFrame.texts.item(0).recompose;
//Получаем координаты geometric bounds привязанного фрейма.
var myBounds = myAnchoredFrame.geometricBounds;
//Устанавливаем высоту и ширину inline-фрейма. В этом примере они будут 40 и 100 pt
var myArray = [myBounds[0], myBounds[1], myBounds[0]+40, myBounds[1]+100];
myAnchoredFrame.geometricBounds = myArray;
// Задаем содержимое привязанному фрейму
myAnchoredFrame.contents = "This is an anchored frame.";
// Задание параметров привязки при помощи объектного стиля
myObjStyle = createObjectStyle ("AnchoredObjects");
myAnchoredFrame.appliedObjectStyle = myObjStyle;
function createObjectStyle (nameStyle)
{
var myObjStyle = app.documents[0].objectStyles.add ({name: nameStyle});
myObjStyle.basedOn = app.documents[0].objectStyles[0];
myObjStyle.enableAnchoredObjectOptions = true;
with (myObjStyle.anchoredObjectSettings)
{
spineRelative = false;
anchoredPosition = AnchorPosition.anchored;
anchorPoint = AnchorPoint.topLeftAnchor;
horizontalReferencePoint = AnchoredRelativeTo.anchorLocation;
horizontalAlignment = HorizontalAlignment.leftAlign;
anchorXoffset = 100;
verticalReferencePoint = VerticallyRelativeTo.lineBaseline;
anchorYoffset = 24;
anchorSpaceAbove = 24;
pinPosition = true;
}
return myObjStyle;
}
// Функцию myGetBounds() здесь не приводим, чтобы не повторяться.

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

Вы должны быть в системе чтобы оставить комментарий.