- When setting fonts for app.findTextPreferences.appliedFont or app.changeTextPreferences.appliedFont if you set that to a non-existent font in CS3 it would fail (the value would not get set and there would be an error). In CS4 it succeeds silently, well sorta. The value will get set, but since the font doesn't exist, the find or change event will definitely fail. Which is better? I like the CS3 result.
- In CS3 if you a looking at a link to a file you can use .update() to import the link again. In CS4 you can't do that if the link isn't modified. I like the CS3 behavior because it allowed you to reimport a linked text file that has been modified in Adobe InDesign, but hasn't changed in the file system. Now in CS4 you have to use .place() on the frame.
- Definitely an improvement here. In ExtendScript you can use $.level = 0 to ignore many errors. In CS4 this works. In CS3 it was pretty much ignored. $.level has three values 2, 1, 0. When set to 2 it even stops at errors that are enclosed in try blocks. When set at 1 it ignores those errors. When set to 0 it ignores most errors.
- Another improvement in CS4 app.applyWorkspace(). Wonderful.
2009-10-02
CS3 to CS4 observations
I've been updating a few ExtendScript functions from CS3 to CS4. I've noticed two interesting cases where it could be argued that something is broke, but it is hard to tell.
2009-09-30
Collapse InDesign Text Frame to Descenders
It used to be as I taught Adobe InDesign to QuarkXPress users that I would always get asked why Adobe InDesign collapses the frame to the baseline instead of forcing the frame to the descenders as QuarkXPress does. For whatever reason, I don't get asked the question much anymore, but this function will make Adobe InDesign behave the same as QuarkXPress, and maybe even better.
If you pass this function a reference to a text frame it will automatically collapse it to the position of the final descender. It is great for headlines. However, if you pass it a second argument, a real in points, it will add that number of points to the frame. Great if you still haven't adopted a baseline grid (baseline grids make building pages easy).
I wrote this function for a project nearly a year ago and I know it gets used every day multiple times by the client who uses it. Now anybody that wants it can have it too.
This function could very easily be given an alternate keyboard shortcut to replace the default
control alt c
or
command option c
keyboard shortcuts for Fit Frame to Content.
function holdDescenders ( aTextFrame_o , extraHeight_n ) {
//-------------------------------------------------------------------------
//-- H O L D D E S C E N D E R S
//-------------------------------------------------------------------------
//-- Generic: Yes.
//-------------------------------------------------------------------------
//-- Purpose: To increase the height of the passed frame by the amount
//-- that Adobe InDesign indicates is the height of the largest
//-- descender of the frame.
//-- Assumptions: 2
//-- 1: This function assumes that the frame has already been collapsed
//-- to the baseline of the last line of text as if you had used
//-- its 'Fit Frame to Contents' function. Call this function
//-- _after_ collapseing the frame using your desired method.
//-- 2: The measurement system is assumed to be points.
//-- Warning: There is no error checking for text that is not visible.
//-------------------------------------------------------------------------
//-- Parameters: 2
//-- aTextFrame_o: A single text frame object. The frame whose height
//-- you want to increase the height of by adding the maximum
//-- descender height.
//-- extraHeight_n: a point value. If not supplied, zero is assumed.
//-- Returns: Nothing. The passed object is modified.
//-------------------------------------------------------------------------
//-- Written by Jon S. Winters on 2008.10.29
//-- eps@electronicpublishingsupport.com
//-------------------------------------------------------------------------
//-- Verify argument 2. If it isn't a number, make it zero.
extraHeight_n = parseFloat ( extraHeight_n ) ;
if ( isNaN ( extraHeight_n ) ) { extraHeight_n = 0 } ;
//-- Get the descender value
var descenderHeight = aTextFrame_o.parentStory.characters[-1].descent ;
//-- Increase the frame height
var currentBounds = aTextFrame_o.geometricBounds ;
currentBounds[2] = currentBounds[2] + descenderHeight + extraHeight_n ;
aTextFrame_o.geometricBounds = currentBounds ;
}
2009-09-24
Force Redraw Adobe InDesign
An Adobe InDesign or Adobe InCopy user can press the key combination:
shift F5
to force redraw or update the display of the screen. This is good for removing screen artifacts or screen trash when the video display can't keep up with the user's changes. That won't help panels or palettes that aren't displaying correctly, but it does update the page(s) being displayed.
Some scripts can also make changes that the display cannot keep up with. For example, I was writing a script to alter the position of guides on a page and I thought it wasn't working. In reality, Adobe InDesign just didn't bother to redraw the screen to show the new position.
This function will force Adobe InDesign to redraw the screen by rapidly changing the view mode.
function forceRedraw () {
//-------------------------------------------------------------------------
//-- F O R C E R E D R A W
//-------------------------------------------------------------------------
//-- Generic: Yes for Adobe InDesign
//-------------------------------------------------------------------------
//-- Purpose: To force Adobe InDesign to redraw the screen when it
//-- won't on its own accord. In the GUI the user can press the
//-- Shift F5
//-- key combination to force a redraw, the the script interface
//-- doesn't have a similar function. This works to solve this for
//-- when a script alter's the document but the window doesn't
//-- properly indicate the change.
//-------------------------------------------------------------------------
//-- Arguments: None.
//-------------------------------------------------------------------------
//-- Calls: Nothing.
//-------------------------------------------------------------------------
//-- Returns: Nothing
//-------------------------------------------------------------------------
//-- Sample Use:
//-- forceRedraw() ;
//-------------------------------------------------------------------------
//-- Written: 2009.09.22 by Jon S. Winters of electronic publishing support
//-- eps@electronicpublishingsupport.com
//-------------------------------------------------------------------------
//-- Store and then clear the redraw preferences
var originalRedraw = app.scriptPreferences.enableRedraw ;
app.scriptPreferences.enableRedraw = false ;
//-- Store the original view setting. The view setting will be changed
//-- to force the redraw to happen.
var originalView = app.activeWindow.viewDisplaySetting ;
//-- If the view is anything but Optimized, switch to optimized. This is
//-- the view the greeks the display. It is FAST.
if ( originalView != ViewDisplaySettings.OPTIMIZED ) {
app.activeWindow.viewDisplaySetting = ViewDisplaySettings.OPTIMIZED ;
}
//-- Otherwise switch to Typical as it is the second fastest.
else{
app.activeWindow.viewDisplaySetting = ViewDisplaySettings.TYPICAL ;
}
//-- Return the window as it was found.
app.activeWindow.viewDisplaySetting = originalView ;
//-- Restablish the redraw settings
app.scriptPreferences.enableRedraw = originalRedraw ;
return ;
}
//
2009-09-23
Compare Two Arrays
The method below compares two arrays to verify that they are the same.
It is a method, so be sure to place it above or before any code that uses it.
It was written to compare two arrays of
pageRef.marginPreferences.columnsPositions from Adobe InDesign.
Array.prototype.isSameAs = function ( compareTo ) {
//-------------------------------------------------------------------------
//-- I S S A M E A S
//-------------------------------------------------------------------------
//-- Generic: Yes, quite. JavaScript or ExtendScript
//-------------------------------------------------------------------------
//-- Purpose: To compare two arrays to verify that they are the same.
//-------------------------------------------------------------------------
//-- Arguments: The array to compare to. This is a method, it is attached
//-- to the first array.
//-------------------------------------------------------------------------
//-- Calls: Nothing.
//-------------------------------------------------------------------------
//-- Returns: True if the arrays are the same, false otherwise.
//-------------------------------------------------------------------------
//-- Sample Use:
//~ var a1 = [1,2,3] ;
//~ var a2 = [1,2,3] ;
//~ var a3 = [1,2,'3'] ;
//~ var a4 = '[1,2,3]' ;
//~ $.writeln ( a1.isSameAs(a2) ) ;
//~ $.writeln ( a1.isSameAs(a3) ) ;
//~ $.writeln ( a1.isSameAs(a4) ) ;
//-------------------------------------------------------------------------
//-- Notes:
//-- The function expects the elements to exactly match, change
//-- !== to != to allow duck type matches.
//-- This is a method. It must be declared BEFORE / ABOVE any code
//-- that uses it.
//-------------------------------------------------------------------------
//-- Written: 2009.09.22 by Jon S. Winters of electronic publishing support
//-- eps@electronicpublishingsupport.com
//-------------------------------------------------------------------------
//-- Make sure the passed argument is an array.
if ( ! ( ( typeof compareTo == 'object') &&
( compareTo.constructor.toString().match(/array/i) != null ) ) ) {
return false ;
}
//
//-- Make sure the length of both arrays is the same
var masterLength = this.length ;
if ( masterLength != compareTo.length ) {
return false ;
}
//
//-- Now compare every element
for ( var i = masterLength - 1 ; i >= 0 ; i-- ) {
if ( this[i] !== compareTo[i] ) {
return false ;
}
}
//
//-- At this point the arrays must be the same.
return true ;
}
2009-09-22
File Name Without a File Extension
The following is a method for the File object in ExtendScript to allow your ExtendScript (Adobe JavaScript) to get the name of a file without the original file extension. I use this code to create .log files and .xml files with the same name as an existing file in Adobe InDesign, but it is useable for many other things such as getting the base name of an Adobe Photoshop file.
File.prototype.nameWithoutExtension = function() {
//-------------------------------------------------------------------------
//-- N A M E W I T H O U T E X T E N S I O N
//-------------------------------------------------------------------------
//-- Generic: Yes for ExtendScript. Not JavaScript.
//-------------------------------------------------------------------------
//-- Purpose: to return the name of the file without the file extension.
//-------------------------------------------------------------------------
//-- Arguments: None. It is a method.
//-------------------------------------------------------------------------
//-- Calls: Nothing.
//-------------------------------------------------------------------------
//-- Returns: The name without the extenstion or the original name if no
//-- file extension is used.
//-------------------------------------------------------------------------
//-- Sample Use:
//~ var fileRef = File.saveDialog ('Pick an Adobe InDesign File', '*.indd' ) ;
//~ var baseName = fileRef.nameWithoutExtension() ;
//-------------------------------------------------------------------------
//-- Written: 2009.09.21 by Jon S. Winters of electronic publishing support
//-- eps@electronicpublishingsupport.com
//-------------------------------------------------------------------------
//-- Get the original name ;
var fullName = this.name
//-- Locate the final position of the final . before the extension.
var finalDotPosition = fullName.lastIndexOf( "." ) ;
//-- check that position. If it isn't -1 (missing) return the text
//-- up to that position.
//-- Note, there are some odd things that can happen when passing
//-- a file reference that begins with a single dot. Be wary.
if ( finalDotPosition > -1 ) {
return fullName.substr( 0 , finalDotPosition );
}
//-- implied else, return the original name because there is no dot.
return fullName ;
}
2009-09-21
Time Stamp
This is a basic function to produce a consistent length time stamp within a script. This produces a time stamp in the format of:
yyyy.mm.dd hh:mm:ss.mss
The function was built to be included in a log routine, so it is very bare bones.
function getTimeStamp () {
//-------------------------------------------------------------------------
//-- G E T T I M E S T A M P
//-------------------------------------------------------------------------
//-- Generic: Yes
//-------------------------------------------------------------------------
//-- Purpose: To create a time stamp string in the format of:
//-- yyyymmdd hh:mm:ss.mss
//-- 2009/06/13 01:23:45.678
//-------------------------------------------------------------------------
//-- Paremeters: none
//-------------------------------------------------------------------------
//-- Calls:
//-- PadWithZeros: Internal function to pad with zeros
//-------------------------------------------------------------------------
//-- Sample call:
//-- var ts = getTimeStamp() ;
//-------------------------------------------------------------------------
//-- Returns: A string of the current time as yyyy.mm.dd hh:mm:ss.mss
//-------------------------------------------------------------------------
//-- Written 2009.09.20 by Jon S. Winters
//-- eps@electronicpublishingsupport.com
//-------------------------------------------------------------------------
//-- Use the Date object to grab the time right now
var now = new Date() ;
//-- Construct the full string
return (now.getFullYear() ) + "." +
PadWithZeros( now.getMonth() + 1 , 2 ) + "." +
PadWithZeros( now.getDate() , 2 ) + " " +
PadWithZeros( now.getHours() , 2 ) + ":" +
PadWithZeros( now.getMinutes() , 2 ) + ":" +
PadWithZeros( now.getSeconds() , 2 ) + "." +
PadWithZeros( now.getMilliseconds() , 3 ) ;
//-- End of main body.
//-- Next is internal function
function PadWithZeros( value , digits ) {
//---------------------------------------------------------------------
//-- P A D W I T H Z E R O S
//---------------------------------------------------------------------
//-- Generic: Yes.
//---------------------------------------------------------------------
//-- Purpose: To pad a number with zeros.
//---------------------------------------------------------------------
//-- Parameters: 2
//-- value: the number to pad
//-- digits: How many total digits should the number become
//---------------------------------------------------------------------
//-- Returns: A string version of the number padded to the number of
//-- digits specified. If the value is already that number of
//-- digits or longer, the value is returned.
//---------------------------------------------------------------------
//-- Calls: Nothing
//---------------------------------------------------------------------
//-- Written: 2009.09.20 by Jon S. Winters
//---------------------------------------------------------------------
//-- Change the number into a string
var paddedString = String ( value ) ;
//-- Check the length of the string. And continue adding zeros to the
//-- front until the desired number of digits is reached.
while( digits > paddedString.length ) {
paddedString = '0' + paddedString ;
}
return paddedString ;
}
//-- end of internal function
}
2009-09-20
Verify or Create Folder Method
One of the limitations of ExtendScript's Folder object is its inability to create a chain of folder paths. It has an .exists property and a .create() method, but each only looks at the final folder in the path. If you pass .create() a path that is several folders away from a parent folder that exists, the creation will fail. Each folder in the chain of folders must be created individually.
This function does that. There are two ways of doing this, build and parse an array like a stack or use a recursive function. This uses a stack.
Folder.prototype.verify = function() {
//-------------------------------------------------------------------------
//-- V E R I F Y
//-------------------------------------------------------------------------
//-- Generic: Yes
//-------------------------------------------------------------------------
//-- Purpose: A folder object method to verify if the folder specified
//-- actually exists. If the folder doesn't exist, the method will
//-- attempt to create it.
//-------------------------------------------------------------------------
//-- Returns: True if the folder exists, false if it couldn't create it.
//-------------------------------------------------------------------------
//-- Sample Call:
//-- Folder ( '~/IsItHere' ).verify() ;
//-------------------------------------------------------------------------
//-- Calls: Nothing
//-------------------------------------------------------------------------
//-- Written 2009.09.19 on board US Airways flight 4376.
//-- eps@electronicpublishingsupport.com
//-------------------------------------------------------------------------
if ( this.exists ) {
return true ;
}
else {
//-- Create an array like a stack of folders that will need
//-- to be created.
var foldersToCreate = new Array () ;
//-- Create a local copy of the original folder
//-- because it needs to be modified within
//-- this routine.
//-- Using the absoluteURI version of the name to point
//-- all the way through to the sever. Only this version
//-- of the activeFolder needs to use this absoluteURI
//-- notation because.
var activeFolder = new Folder ( this.absoluteURI ) ;
//-- Loop through the path structure until every part of
//-- of the folder path is checked. Any non-existanet
//-- folder path will be added to the array to create.
while ( ! activeFolder.exists ) {
//-- Add the activeFolder to the array of folders to create
foldersToCreate.push( activeFolder ) ;
//-- Now get to the parent of the folder.
//-- Can't use .parent because if the active folder
//-- doesn't exist, it won't have a parent.
activeFolder = new Folder ( activeFolder.path ) ;
}
//-- At this point we have an array of folders that need to be
//-- created. The array will have one element too many because
//-- of the final line of the
while ( foldersToCreate.length > 0 ) {
//-- Remove the last item added to the array of folders to create
activeFolder = foldersToCreate.pop() ;
//-- Try to create this folder
if ( ! activeFolder.create() ) {
return false ;
} //-- end of if create
} //-- end of lower while
} //-- end of else from way up top
//-- At this point the folder has to exist else we already returned false
return true ;
}
//
Labels:
Adobe,
Create,
ExtendScript,
Folder,
JavaScript,
Make,
New,
Verify
Subscribe to:
Posts (Atom)