Программирование привязанных объектов, часть 2
Отвязать привязанный объект
Отвязать привязанный объект можно при помощи метода 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() здесь не приводим, чтобы не повторяться. |
Последние комментарии