|
// MultiExporter.js |
|
// Version 0.1 |
|
// Version 0.2 Adds PNG and EPS exports |
|
// Version 0.3 Adds support for exporting at different resolutions |
|
// |
|
// Exports Illustrator artboards and/or layers as individual PNG or PDF files |
|
// |
|
// Copyright 2011 Matthew Ericson |
|
// Comments or suggestions to [email protected] |
|
|
|
|
|
var docRef = app.activeDocument; |
|
|
|
var nyt_png_exporter = { |
|
|
|
png_info_lyr: null, |
|
|
|
prefix: null, |
|
suffix: null, |
|
base_path: null, |
|
transparency: false, |
|
|
|
format: null, |
|
export_type: null, |
|
|
|
dlg: null, |
|
prefs_xml: null, |
|
|
|
num_to_export: 0, |
|
|
|
num_layers: 0, |
|
num_layers_to_export: 0, |
|
|
|
num_artboards: 0, |
|
num_artboards_to_export: 0, |
|
|
|
init: function() { |
|
|
|
// figure out if there is stuff to process |
|
this.num_layers = docRef.layers.length; |
|
this.num_artboards = docRef.artboards.length; |
|
|
|
this.num_layers_to_export = this.get_num_layers_to_export(); |
|
this.num_artboards_to_export = this.get_num_artboards_to_export(); |
|
|
|
var parse_success = this.load_prefs(); |
|
|
|
if (parse_success) { |
|
this.show_dialog(); |
|
} |
|
}, |
|
|
|
load_prefs: function() { |
|
|
|
var parse_success = false; |
|
|
|
// find existing layers or add new one |
|
try { |
|
this.png_info_lyr = docRef.layers.getByName( 'nyt_exporter_info' ); |
|
|
|
} catch ( e ) { |
|
|
|
this.png_info_lyr = docRef.layers.add(); |
|
this.png_info_lyr.name = 'nyt_exporter_info'; |
|
|
|
var nyt_exporter_info_xml = this.png_info_lyr.textFrames.add(); |
|
|
|
var saved_data = new XML( '<nyt_prefs></nyt_prefs>' ); |
|
saved_data.appendChild( new XML('<nyt_prefix></nyt_prefix>') ); |
|
saved_data.appendChild( new XML('<nyt_suffix></nyt_suffix>') ); |
|
saved_data.appendChild( new XML('<nyt_base_path>~/Desktop</nyt_base_path>') ); |
|
saved_data.appendChild( new XML('<nyt_scaling>100%</nyt_scaling>') ); |
|
saved_data.appendChild( new XML('<nyt_transparency>true</nyt_transparency>') ); |
|
saved_data.appendChild( new XML('<nyt_format>PNG 24</nyt_format>') ); |
|
saved_data.appendChild( new XML('<nyt_export_code>artboards</nyt_export_code>') ); |
|
|
|
nyt_exporter_info_xml.contents = saved_data.toXMLString(); |
|
|
|
this.png_info_lyr.printable = false; |
|
this.png_info_lyr.visible = false; |
|
} |
|
|
|
|
|
// get xml out of the 1 text item on that layer and parse it |
|
if ( this.png_info_lyr.textFrames.length != 1 ) { |
|
Window.alert( 'Please delete the nyt_exporter_info layer and try again.' ); |
|
|
|
} else { |
|
|
|
try { |
|
this.prefs_xml = new XML( this.png_info_lyr.textFrames[0].contents ); |
|
this.prefix = this.prefs_xml.nyt_prefix; |
|
this.suffix = this.prefs_xml.nyt_suffix; |
|
this.base_path = this.prefs_xml.nyt_base_path; |
|
this.scaling = this.prefs_xml.nyt_scaling; |
|
this.transparency = this.prefs_xml.nyt_transparency == "true" ? true : false; |
|
this.format = this.prefs_xml.nyt_format; |
|
this.export_code = this.prefs_xml.nyt_export_code; |
|
|
|
if ( ! this.prefs_xml.nyt_scaling || this.prefs_xml.nyt_scaling == '' ) { |
|
this.scaling = '100%'; |
|
} |
|
|
|
parse_success = true; |
|
|
|
} catch ( e ) { |
|
Window.alert( 'Please delete the this.png_info_lyr layer and try again.' ); |
|
} |
|
|
|
} |
|
|
|
return parse_success; |
|
}, |
|
|
|
|
|
// dialog display |
|
show_dialog: function() { |
|
|
|
// Export dialog |
|
this.dlg = new Window('dialog', 'Export Artboards'); |
|
|
|
// PANEL to hold options |
|
var msgPnl = this.dlg.add('panel', undefined, 'Export Artboards and/or Layers'); |
|
|
|
// EXPORT TYPE ROW |
|
|
|
var typeGrp = msgPnl.add('group', undefined, '') |
|
typeGrp.oreintation = 'row'; |
|
typeGrp.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP] |
|
|
|
var typeSt = typeGrp.add('statictext', undefined, 'Export what:'); |
|
typeSt.size = [ 100,20 ]; |
|
|
|
var exportTypeList = typeGrp.add('dropdownlist', undefined, [ 'Artboards (with currently visible layers)', 'Layers (on currently selected artboard)', 'Artboards + Layers' ]); |
|
|
|
if ( this.export_code == 'artboards' ) { |
|
exportTypeList.selection = 0; |
|
} else if ( this.export_code == 'layers' ) { |
|
exportTypeList.selection = 1; |
|
} else { |
|
exportTypeList.selection = 2; |
|
} |
|
|
|
// PREFIX GRP |
|
var prefixGrp = msgPnl.add('group', undefined, '') |
|
prefixGrp.oreintation = 'row'; |
|
prefixGrp.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP] |
|
|
|
var prefixSt = prefixGrp.add('statictext', undefined, 'File prefix:'); |
|
prefixSt.size = [100,20] |
|
|
|
var prefixEt = prefixGrp.add('edittext', undefined, this.prefix); |
|
prefixEt.size = [ 300,20 ]; |
|
|
|
var prefixGrp = msgPnl.add('group', undefined, '') |
|
prefixGrp.oreintation = 'row'; |
|
prefixGrp.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP] |
|
|
|
var suffixGrp = msgPnl.add('group', undefined, '') |
|
suffixGrp.oreintation = 'row'; |
|
suffixGrp.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP] |
|
|
|
var suffixSt = suffixGrp.add('statictext', undefined, 'File suffix:'); |
|
suffixSt.size = [100,20] |
|
|
|
var suffixEt = suffixGrp.add('edittext', undefined, this.suffix); |
|
suffixEt.size = [ 300,20 ]; |
|
|
|
var dpiGrp = msgPnl.add('group', undefined, '') |
|
dpiGrp.oreintation = 'row'; |
|
dpiGrp.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP] |
|
|
|
var dpiSt = dpiGrp.add('statictext', undefined, 'Scaling:'); |
|
dpiSt.size = [100,20] |
|
|
|
var dpiEt = dpiGrp.add('edittext', undefined, this.scaling); |
|
dpiEt.size = [ 100,20 ]; |
|
|
|
var dpiSt2 = dpiGrp.add('statictext', undefined, '(Normally 100%; Use 200% for Retina dislay exports)'); |
|
dpiSt2.size = [300,20] |
|
|
|
// DIR GROUP |
|
var dirGrp = msgPnl.add( 'group', undefined, '') |
|
dirGrp.orientation = 'row' |
|
dirGrp.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP] |
|
|
|
var dirSt = dirGrp.add('statictext', undefined, 'Output directory:'); |
|
dirSt.size = [ 100,20 ]; |
|
|
|
var dirEt = dirGrp.add('edittext', undefined, this.base_path); |
|
dirEt.size = [ 300,20 ]; |
|
|
|
var chooseBtn = dirGrp.add('button', undefined, 'Choose ...' ); |
|
chooseBtn.onClick = function() { dirEt.text = Folder.selectDialog(); } |
|
|
|
// TRANSPARENCY AND FORMAT ROW |
|
var transPnl = msgPnl.add('group', undefined, ''); |
|
transPnl.orientation = 'row' |
|
transPnl.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP] |
|
|
|
var formatSt = transPnl.add('statictext', undefined, 'Export format:'); |
|
formatSt.size = [ 100,20 ]; |
|
|
|
var formatList = transPnl.add('dropdownlist', undefined, [ 'PNG 8', 'PNG 24', 'PDF', 'JPG', 'EPS' ]); |
|
|
|
formatList.selection = 1; |
|
for ( var i=0; i < formatList.items.length; i++ ) { |
|
if ( nyt_png_exporter.format == formatList.items[i].text ) { |
|
formatList.selection = i; |
|
} |
|
} |
|
|
|
transPnl.transparentChk = transPnl.add('checkbox', undefined, 'Transparency'); |
|
transPnl.transparentChk.value = this.transparency; |
|
|
|
var progBar = msgPnl.add( 'progressbar', undefined, 0, 100 ); |
|
progBar.size = [400,10] |
|
|
|
var progLabel = msgPnl.add('statictext', undefined, '...' ); |
|
progLabel.size = [ 400,20 ]; |
|
|
|
var btnPnl = this.dlg.add('group', undefined, ''); |
|
btnPnl.orientation = 'row' |
|
|
|
btnPnl.cancelBtn = btnPnl.add('button', undefined, 'Cancel', {name:'cancel'}); |
|
btnPnl.cancelBtn.onClick = function() { nyt_png_exporter.dlg.close() }; |
|
|
|
// OK button |
|
btnPnl.okBtn = btnPnl.add('button', undefined, 'Export', {name:'ok'}); |
|
btnPnl.okBtn.onClick = function() { |
|
|
|
nyt_png_exporter.prefix = prefixEt.text; |
|
nyt_png_exporter.suffix = suffixEt.text; |
|
nyt_png_exporter.base_path = dirEt.text; |
|
nyt_png_exporter.transparency = transPnl.transparentChk.value; |
|
nyt_png_exporter.format = formatList.selection.text; |
|
nyt_png_exporter.export_type = exportTypeList.selection.text; |
|
nyt_png_exporter.scaling = parseFloat( dpiEt.text.replace( /\% /, '' )); |
|
|
|
if ( nyt_png_exporter.export_type.match( /\+/ )) { |
|
nyt_png_exporter.export_code = 'both'; |
|
} else if ( nyt_png_exporter.export_type.match( /^Art/ )) { |
|
nyt_png_exporter.export_code = 'artboards'; |
|
} else { |
|
nyt_png_exporter.export_code = 'layers'; |
|
} |
|
|
|
nyt_png_exporter.run_export(); |
|
}; |
|
|
|
// Export type handler |
|
exportTypeList.onChange = function() { |
|
|
|
nyt_png_exporter.export_type = exportTypeList.selection.text; |
|
|
|
if ( nyt_png_exporter.export_type.match( /\+/ )) { |
|
nyt_png_exporter.export_code = 'both'; |
|
} else if ( nyt_png_exporter.export_type.match( /^Art/ )) { |
|
nyt_png_exporter.export_code = 'artboards'; |
|
} else { |
|
nyt_png_exporter.export_code = 'layers'; |
|
} |
|
|
|
nyt_png_exporter.update_export_desc( progLabel ); |
|
}; |
|
|
|
nyt_png_exporter.update_export_desc( progLabel ); |
|
|
|
this.dlg.progLabel = progLabel; |
|
this.dlg.progBar = progBar; |
|
|
|
this.dlg.show(); |
|
}, |
|
|
|
|
|
update_export_desc: function ( progLabel ) { |
|
|
|
if ( this.export_code == 'artboards' ) { |
|
progLabel.text = 'Will export ' + this.num_artboards_to_export + ' of ' + this.num_artboards + ' artboards'; |
|
this.num_to_export = this.num_artboards_to_export; |
|
|
|
} else if ( this.export_code == 'layers' ) { |
|
var current_name = docRef.artboards[ docRef.artboards.getActiveArtboardIndex() ].name; |
|
progLabel.text = 'Will export ' + this.num_layers_to_export + ' of ' + this.num_layers+ ' layers on artboard "' + current_name +'"' ; |
|
this.num_to_export = this.num_layers_to_export; |
|
|
|
} else { |
|
this.num_to_export = this.num_layers_to_export * this.num_layers_to_export ; |
|
progLabel.text = 'Will export ' + this.num_to_export + ' files (' + this.num_layers_to_export + ' layers * ' + this.num_artboards_to_export + ' artboards)'; |
|
|
|
} |
|
}, |
|
|
|
|
|
// run_export function. does the dirty work |
|
run_export: function() { |
|
|
|
var num_exported = 0; |
|
var options; |
|
|
|
if ( this.format =='PNG 8' ) { |
|
options = new ExportOptionsPNG8(); |
|
options.antiAliasing = true; |
|
options.transparency = this.transparency; |
|
options.artBoardClipping = true; |
|
options.horizontalScale = this.scaling; |
|
options.verticalScale = this.scaling; |
|
|
|
} else if ( this.format == 'PNG 24' ) { |
|
options = new ExportOptionsPNG24(); |
|
options.antiAliasing = true; |
|
options.transparency = this.transparency; |
|
options.artBoardClipping = true; |
|
options.horizontalScale = this.scaling; |
|
options.verticalScale = this.scaling; |
|
|
|
} else if ( this.format == 'PDF' ) { |
|
options = new PDFSaveOptions(); |
|
options.compatibility = PDFCompatibility.ACROBAT5; |
|
options.generateThumbnails = true; |
|
options.preserveEditability = false; |
|
|
|
} else if ( this.format == 'JPG' ) { |
|
options = new ExportOptionsJPEG(); |
|
options.antiAliasing = true; |
|
options.artBoardClipping = true; |
|
options.horizontalScale = this.scaling; |
|
options.verticalScale = this.scaling; |
|
|
|
} else if ( this.format == 'EPS' ) { |
|
options = new EPSSaveOptions(); |
|
options.embedLinkedFiles = true; |
|
options.includeDocumentThumbnails = true; |
|
options.saveMultipleArtboards = true; |
|
} |
|
|
|
var starting_artboard = 0; |
|
var num_artboards = docRef.artboards.length; |
|
|
|
if ( this.export_code == 'layers' ) { |
|
starting_artboard = docRef.artboards.getActiveArtboardIndex(); |
|
num_artboards = starting_artboard + 1; |
|
} |
|
|
|
for (var i = starting_artboard; i < num_artboards; i++ ) { |
|
|
|
var artboardName = docRef.artboards[i].name; |
|
starting_artboard = docRef.artboards.setActiveArtboardIndex(i); |
|
|
|
// Process this artbarod if we're exporting only a single one (layers mode) or if it doesn't have generic name or minus |
|
if ( this.export_code == 'layers' || ! ( artboardName.match( /^artboard/i ) || artboardName.match( /^\-/ ) )) { |
|
|
|
// if exporting artboard by artboard, export layers as is |
|
if ( this.export_code == 'artboards' ) { |
|
|
|
var base_filename = this.base_path + "/" + this.prefix + artboardName + this.suffix |
|
|
|
if ( this.format.match( /^PNG/ )) { |
|
var destFile = new File( base_filename + '.png' ); |
|
var export_type = this.format == 'PNG 8' ? ExportType.PNG8 : ExportType.PNG24; |
|
docRef.exportFile(destFile, export_type , options); |
|
|
|
} else if ( this.format.match( /^JPG/ )) { |
|
var destFile = new File( base_filename + '.jpg' ); |
|
var export_type = ExportType.JPEG; |
|
docRef.exportFile(destFile, export_type , options); |
|
|
|
} else if ( this.format.match( /^EPS/ )) { |
|
|
|
// dumb. specify a filename, saveAs saves as something else |
|
// so after we save it, we have to rename it to what we want. |
|
var eps_real_filename = base_filename + '_' + artboardName + '.eps' |
|
|
|
var destFile = new File( base_filename + '.eps' ); |
|
options.artboardRange = (i+1).toString(); |
|
docRef.saveAs( destFile, options ); |
|
|
|
var epsFile = new File ( eps_real_filename ); |
|
if ( epsFile.exists ) { |
|
epsFile.copy( base_filename + '.eps' ); |
|
epsFile.remove(); |
|
} |
|
|
|
} else if ( this.format.match( /^PDF/ )) { |
|
var destFile = new File( base_filename + '.pdf' ); |
|
options.artboardRange = (i+1).toString(); |
|
docRef.saveAs( destFile, options ) |
|
} |
|
|
|
// export layers as individual files |
|
} else if ( this.export_code == 'layers' || this.export_code = 'both' ) { |
|
|
|
for ( var j=0; j < docRef.layers.length; j++ ) { |
|
|
|
this.hide_all_layers(); |
|
|
|
var layer = docRef.layers[j]; |
|
var lyr_name = layer.name; |
|
|
|
if ( ! ( lyr_name.match( /^\+/ ) || lyr_name.match( /nyt_exporter_info/ ) || lyr_name.match( /^\-/) || lyr_name.match( /^Layer / ) )) { |
|
|
|
var base_filename; |
|
|
|
if ( this.export_code == 'layers' ) { |
|
base_filename = this.base_path + "/" + this.prefix + lyr_name + this.suffix |
|
|
|
} else if ( this.export_code == 'both' ) { |
|
base_filename = this.base_path + "/" + this.prefix + artboardName + '-' + lyr_name + this.suffix |
|
|
|
} |
|
|
|
layer.visible = true; |
|
|
|
if ( this.format.match( /^PNG/ )) { |
|
var destFile = new File( base_filename + '.png' ); |
|
var export_type = this.format == 'PNG 8' ? ExportType.PNG8 : ExportType.PNG24; |
|
docRef.exportFile(destFile, export_type , options); |
|
|
|
} else if ( this.format.match( /^JPG/ )) { |
|
var destFile = new File( base_filename + '.jpg' ); |
|
var export_type = ExportType.JPEG; |
|
docRef.exportFile(destFile, export_type , options); |
|
|
|
} else if ( this.format.match( /^EPS/ )) { |
|
|
|
var eps_real_filename = base_filename + '_' + artboardName + '.eps' |
|
|
|
var destFile = new File( base_filename + '.eps' ); |
|
options.artboardRange = (i+1).toString(); |
|
docRef.saveAs( destFile, options ) |
|
|
|
var epsFile = new File ( eps_real_filename ); |
|
if ( epsFile.exists ) { |
|
epsFile.copy( base_filename + '.eps' ); |
|
epsFile.remove(); |
|
|
|
} |
|
|
|
|
|
} else if ( this.format.match( /^PDF/ )) { |
|
var destFile = new File( base_filename + '.pdf' ); |
|
options.artboardRange = (i+1).toString(); |
|
docRef.saveAs( destFile, options ) |
|
} |
|
|
|
num_exported++; |
|
|
|
this.dlg.progLabel.text = 'Exported ' + num_exported + ' of ' + this.num_to_export; |
|
this.dlg.progBar.value = num_exported / this.num_to_export * 100; |
|
|
|
this.dlg.update(); |
|
} |
|
|
|
} |
|
} |
|
} |
|
} |
|
|
|
this.prefs_xml.nyt_base_path = this.base_path; |
|
this.prefs_xml.nyt_scaling = this.scaling; |
|
this.prefs_xml.nyt_prefix = this.prefix; |
|
this.prefs_xml.nyt_suffix = this.suffix; |
|
this.prefs_xml.nyt_transparency = this.transparency; |
|
this.prefs_xml.nyt_format = this.format; |
|
this.prefs_xml.nyt_export_code = this.export_code; |
|
|
|
this.png_info_lyr.textFrames[0].contents = this.prefs_xml.toXMLString(); |
|
this.dlg.close(); |
|
|
|
//end run_export |
|
}, |
|
|
|
hide_all_layers: function() { |
|
var export_count = 0; |
|
|
|
var n = docRef.layers.length; |
|
|
|
for(var i=0; i<n; ++i) { |
|
|
|
layer = docRef.layers[i]; |
|
|
|
lyr_name = layer.name; |
|
|
|
// any layers that start with + are always turned on |
|
if ( lyr_name.match( /^\+/ ) ) { |
|
layer.visible = true; |
|
|
|
// any layers that start with -, have default layer name, or named "nyt_exporter_info" are skipped |
|
} else if ( lyr_name.match( /nyt_exporter_info/ ) || lyr_name.match( /^Layer /) || lyr_name.match( /^\-/ ) ){ |
|
layer.visible = false; |
|
|
|
// everything else we should export |
|
} else { |
|
layer.visible = false; |
|
export_count++; |
|
} |
|
} |
|
return export_count; |
|
}, |
|
|
|
get_num_layers_to_export: function() { |
|
|
|
var num_to_export = 0; |
|
var num_layers = docRef.layers.length; |
|
|
|
for(var i=0; i<num_layers; ++i) { |
|
|
|
var layer = docRef.layers[i]; |
|
var lyr_name = layer.name; |
|
|
|
// any layers that start with + are always turned on |
|
if ( lyr_name.match( /^\+/ ) ) { |
|
|
|
} else if ( lyr_name.match( /nyt_exporter_info/ ) || lyr_name.match( /^Layer /) || lyr_name.match( /^\-/ ) ){ |
|
|
|
} else { |
|
num_to_export++; |
|
} |
|
} |
|
|
|
return num_to_export; |
|
}, |
|
|
|
get_num_artboards_to_export: function() { |
|
|
|
var num_artboards = docRef.artboards.length; |
|
var num_to_export = 0; |
|
|
|
for (var i = 0; i < num_artboards; i++ ) { |
|
|
|
var artboardName = docRef.artboards[i].name; |
|
if ( ! ( artboardName.match( /^artboard/i ) || artboardName.match( /^\-/ ) )){ |
|
num_to_export++; |
|
} |
|
} |
|
|
|
return num_to_export; |
|
|
|
}, |
|
|
|
|
|
show_all_layers: function() { |
|
var n = docRef.layers.length; |
|
for(var i=0; i<n; ++i) { |
|
layer = docRef.layers[i]; |
|
layer.visible = true; |
|
} |
|
}, |
|
|
|
}; |
|
|
|
nyt_png_exporter.init(); |