Your prescription for increased productivity and profitability
When looking for samples of code don’t overlook the scripts provided by Adobe in the InDesign’s Scripts. Recently I had occasion to look at their TabUtilities script when working on one that involved tabs. The TabUtilities script includes a number of examples for creating a tab stop using properties for position, alignment, and leader.
Additionally, this script has a good example of creating a custom dialog with a rqdiobutton group. As a bonus, there is code for calculating horizontal positions on a page using the position of an insertion point, and properties of a text frame’s text frame preferences. Text frame preference provides inset spacing values and text column fixed widths which can be used to calculate horizontal coordinates. The code is fairly involved so we will let you explore this script on your own.
For the purpose of this post we will concntrate on creating tabs and using tab positions for creating items such as guides and image containers.
Creating a tab for a paragraph can be condensed into the following:
set tabPosition to 1 set tabLeader to "" tell application "Adobe InDesign CC 2019" set measurement unit of script preferences to inches set tabAlignment to left align set myTextObjects to ¬ {insertion point, character, word, line, text style range, paragraph, text column, text, story, text frame} set mySelection to object reference of selection if (count mySelection) > 0 then if class of item 1 of selection is in myTextObjects then set myClass to class of item 1 of mySelection set myParagraphs to object reference of paragraphs of item 1 of mySelection set myParagraph to object reference of item 1 of myParagraphs tell myParagraph make tab stop with properties {alignment:tabAlignment, position:tabPosition, leader:tabLeader} end tell end if end if end tell
For all of the paragraphs in a text frame, add a repeat loop to the above that iterates through the paragraph references returned to the variable myParagraphs.
If the paragraphs in a text frame or story have been assigned a paragraph style, its tab list property can be set to a list of tab records. Each tab record in the list can define the position, the alignment, and leader foor the tab. Following is an example of setting a tab for a paragraphs style. The tab in this example has a leadered right-aligned tab at the right edge of the text frame. This is often used to style text for tables of contents and event programs.
(*Expects a text frame selection with paragraphs assigned to a paragraph style*) set tabLeader to ". " tell application "Adobe InDesign CC 2019" set measurement unit of script preferences to points set mySelection to selection if mySelection is not {} and class of item 1 of mySelection is text frame then set frameRef to item 1 of mySelection copy geometric bounds of frameRef to {y0, x0, y1, x1} set frameRight to (x1 - x0) set paraStyle to applied paragraph style of paragraph 1 of frameRef set tab list of paraStyle to {{position:frameRight}} end if end tell
Should you wish to set tabs for a spanned headline so that tabbed text aligns to text frame columns this can be easily handled with the following:
tell application "Adobe InDesign CC 2019" set tabAlign to left align set tabLeader to "" set sideRef to 1 --for right align set sideRef to 2 set measurement unit of script preferences to points set selList to selection if selList is not {} and class of item 1 of selList is text frame then set frameRef to item 1 of selection tell text frame preferences of frameRef copy {text column fixed width, text column count, text column gutter} to ¬ {colWidths, numCol, colGut} end tell if numCol > 1 then set colList to my calcColumns(colWidths, numCol, colGut) end if set myPara to a reference to paragraph 1 of frameRef set myTabList to {} repeat with i from 2 to numCol set end of myTabList to ¬ {alignment:tabAlign, leader:tabLeader, position:item sideRef of item i of colList} end repeat if name of applied paragraph style of myPara is not "[Basic Paragraph]" then set myObject to applied paragraph style of myPara else set myObject to myPara end if tell myObject set span column type to span columns set tab list to myTabList end tell else display dialog ("Requires a selected text frame") end if end tell (*Returns left and right edge positions for columns in text frame*) on calcColumns(colWidths, numCol, colGut) set colList to {} set x0 to 0 repeat with i from 1 to numCol set x1 to x0 + colWidths copy {x0, x1} to end of colList set x0 to x1 + colGut end repeat return colList end calcColumns
…Before running script
…After running script
Notice that instead of creating tab stops individually, a paragraph reference can take advantage of the tab list property. Also, be aware that tab positions are relative to the left edge of the text frame. The calcColumns handler can also be used for placing text frames over the columns but the horizontal coordinates (x0, x1) would need to take into consideration the horizontal position of the subject text frame within the page. An example of this is shown in the following example.
Should you have a tabbed headline as was created above you might wish to create threaded text frames that align to the heads. This would be a best case scenario when your text columns are different widths.
(*Expects paragraph in header text frame to be selected*) set gutWid to 12 --gutter width in points set rectHgt to 200 --image container height in points tell application "Adobe InDesign CC 2019" set measurement unit of script preferences to points set selList to selection if selList is not {} and class of item 1 of selList is text then set myRef to a reference to item 1 of selection set myTabs to tab list of myRef set frameRef to item 1 of parent text frames of myRef set x0 to item 2 of geometric bounds of frameRef set pageRef to parent page of frameRef set colList to {} repeat with i from length of myTabs to 1 by -1 set colPos to (position of item i of myTabs) + x0 set end of colList to colPos end repeat my createLinkedFrames(frameRef, colList, rectHgt, gutWid) end if end tell (*Creates linked text frames based on tab positions in selected headline*) on createLinkedFrames(frameRef, colList, rectHgt, gutWid) tell application "Adobe InDesign CC 2019" set pageRef to parent page of frameRef copy geometric bounds of frameRef to {y0, x0, y1, x1} tell pageRef repeat with i from 1 to length of colList set colPos to item i of colList set thisBounds to {y1, colPos, y1 + rectHgt, x1} set thisFrame to make text frame with properties {geometric bounds:thisBounds} if i > 1 then set next text frame of thisFrame to lastFrame end if set x1 to colPos - gutWid set lastFrame to thisFrame end repeat set thisFrame to make text frame with properties {geometric bounds:{y1, x0, y1 + rectHgt, x1}} set next text frame of thisFrame to lastFrame end tell end tell end createLinkedFrames
…After creating linked text frames
Now that you have lots of code to work with, all you need is to add some error handling along with custom dialogs to allow users to define the values required for the scripts. And, don’t forget to spend some time with the TabUtilities script.
Disclaimer:
Scripts provided are for demonstration and educational purposes. No representation is made as to their accuracy or completeness. Readers are advised to use the code at their own risk.