indesign color functions
class CInddexport
require 'rubygems'
require 'appscript'
include Appscript
def initialize(filePath, outputPath, test = false)
@filePath = filePath
@outputPath = outputPath
@idApp = (test == true) ? app('Adobe InDesign CS3') : app('InDesignServer')
end
# public functions
def openDoc
@idDoc = @idApp.open(MacTypes::FileURL.path(@filePath).hfs_path)
end
def closeDoc
@idDoc.close(:saving => :no)
end
def getDocArray
document = Hash.new
breakGroups
#FIXME add information about books, spreads, position pages on spread, etc to array
document[:layerGroups] = getLayerGroups()
#document[:preview] = 'test'
return document
end
def getPreview
docArray = getDocArray
return docArray[:preview]
end
# private functions
def getLayerGroups
layerGroups = Hash.new{|hash, key| hash[key] = Array.new}
layers = getLayers
lastLayer = ''
layers.each do |layer|
layerId = layer[:name].to_s[0, 2]
if(lastLayer == layerId || layerId == 'xx' || layerId == 'XX')
@idApp.set(@idDoc.layers[its.id_.eq(layer[:layerID])].visible, :to => false)
else
@idApp.set(@idDoc.layers[its.id_.eq(layer[:layerID])].visible, :to => true)
end
lastLayer = layerId
layerGroups[layerId.to_i] << layer
end
return layerGroups
end
def getCurrentLayerGroup(currLayer)
layerCount = 0
@idDoc.layers.get.each do |layer|
if(layer.name.get.to_s[0, 2] == currLayer) then layerCount += 1 end
end
return layerCount
end
def getLayers
layerArray = Array.new
i = 0
@idDoc.layers.get.each do |layer|
layerProps = Hash.new{|hash, key| hash[key] = Array.new}
layerProps[:layerID] = layer.id_.get
layerProps[:name] = layer.name.get.to_s
layerProps[:zindex] = @idDoc.layers.get.length-i
layerProps[:layerChilds] << getChilds(layer)
layerArray << layerProps
i = i+1
end
puts MacTypes::FileURL.path(@outputPath+'sourcedoc.eps').hfs_path
@idApp.export(@idDoc, :format => :EPS_type, :to => MacTypes::FileURL.path(@outputPath+'sourcedoc.eps').hfs_path, :showing_options => false)
return layerArray
end
def getChilds(layer)
childs = Array.new
#FIXME add support for tables
layer.page_items.get.each do |child|
#FIXME add support for ovals, polygons, and graphic lines
childProps = Hash.new{|hash, key| hash[key] = Array.new}
geom = child.geometric_bounds.get
childProps[:objectID] = child.id_.get
childProps[:name] = child.get.to_s
childProps[:x] = geom[1]
childProps[:y] = geom[0]
childProps[:w] = geom[3].to_f-geom[1].to_f
childProps[:h] = geom[2].to_f-geom[0].to_f
childProps[:label] = child.label.get.to_s
childProps[:isStatic] = getStatic(child.label.get.to_s)
childProps[:type] = getType(child)
childProps[:inGroup] = (getCurrentLayerGroup(layer.name.get.to_s[0, 2]) > 1) ? true : false
childProps[:group] = layer.name.get.to_s[0, 2]
childProps[:content] = 'content'
#FIXME indesign/appscript gives very 'special' output in case of Pantone colors - ignore for now
childProps[:background] = 'unknown' #getBackGroundColor(child)
childs << childProps
end
return childs
end
def breakGroups
groups = @idDoc.groups.get
groups.each do |group|
group.ungroup
end
if (@idDoc.groups.get.length > 0) then breakGroups end
end
def getStatic(label)
# pTextInput & pMergeField = plain text, rTextInput & rMergeField = rich text, mergeTextField need to have a label after the underscore
types = ['textInput', 'imageInput', 'colorInput', 'mergeTextField_', 'mergeImgField']
isStatic = true
types.each do |type|
if type.to_s == label || type.to_s[0,15] == label
isStatic = false
break
else
isStatic = true
end
end
return isStatic
end
def getType(child)
#FIXME add support for ovals, polygons, and graphic lines
if(child.class_.get.to_s == 'rectangle')
#FIXME add support for multiple images in rectangles
type = (child.graphics.get.length == 1) ? child.graphics.class_.get.to_s : 'rectangle'
elsif(child.class_.get.to_s == 'text_frame')
type = 'text'
else
type = 'undefined'
end
return type
end
def getBackGroundColor(child)
#FIXME possibly Indesign supports multiple color spaces, for now, presume it's always CMYK
if(child.fill_color.class_.get.to_s == 'color')
puts child.fill_color.space.get
return getCMYKtoHeX(child.fill_color.color_value.get.to_s)
else
return 'none'
end
end
def getCMYKtoHeX(cmyk)
#FIXME somehow this seems not as accurate as the ActionScript equivalent
colorArr = cmyk.split('.')
puts cmyk
c = stripLeadingZero(colorArr[0]).to_f/100
m = stripLeadingZero(colorArr[1]).to_f/100
y = stripLeadingZero(colorArr[2]).to_f/100
k = stripLeadingZero(colorArr[3]).to_f/100
#the adobe approach
ra = (1.0 - min(1.0, c + k))*255
ga = (1.0 - min(1.0, m + k))*255
ba = (1.0 - min(1.0, y + k))*255
#a custom interpretation
rc = (1.0 - (c * (1.0 - k) + k))*255
gc = (1.0 - (m * (1.0 - k) + k))*255
bc = (1.0 - (y * (1.0 - k) + k))*255
#another approach
ro = ((1.0 - k + c)*(k - 1.0))*255
go = ((1.0 - k + m)*(k - 1.0))*255
bo = ((1.0 - k + y)*(k - 1.0))*255
#return '#' + toHex(r) + toHex(g) + toHex(b)
end
def stripLeadingZero(string)
if (string[0,1] == '0' && string.length > 1)
return stripLeadingZero(string[1..-1])
else
return string
end
end
def toHex(color)
if(color < 0) then color = 0 end
return color.round.to_s(16)
end
def min(a,b)
return a <= b ? a : b
end
end
class CDebug
require 'YAML'
def debugArray(arr)
puts YAML::dump(arr)
end
end
class XMLParser
require 'XmlSimple'
def initialize
end
def convertXML(arr)
return XmlSimple.xml_out(arr)
end
end
indd = CInddexport.new('/Users/server/Desktop/sourcedoc.indd','/Users/server/Desktop/test/', true)
debug = CDebug.new()
xml = XMLParser.new()
indd.openDoc
#indd.getDocArray
debug.debugArray(indd.getDocArray)
#debug.debugArray(xml.convertXML(indd.getDocArray))
#indd.closeDoc