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 ;
}
//