Skip to content

Instantly share code, notes, and snippets.

@boughtonp
Created October 19, 2010 14:44
Show Gist options
  • Save boughtonp/634306 to your computer and use it in GitHub Desktop.
Save boughtonp/634306 to your computer and use it in GitHub Desktop.
<cfcomponent output="false">
<cffunction name="init">
<cfargument name="InputFile" type="String" />
<cfset Variables.SourceFile = Arguments.InputFile />
<cfset Variables.ContentXml = XmlParse( "zip://" & Variables.SourceFile & "!content.xml" ) />
<cfset Variables.MetaXml = XmlParse( "zip://" & Variables.SourceFile & "!meta.xml" ) />
<cfreturn this />
</cffunction>
<cffunction name="save">
<cfset FileWrite( "zip://" & Variables.SourceFile & "!content.xml" , toString(Variables.ContentXml) ) />
<cfset FileWrite( "zip://" & Variables.SourceFile & "!meta.xml" , toString(Variables.MetaXml) ) />
</cffunction>
<cffunction name="clearPage">
<cfargument name="PageNumber" type="Numeric" />
<cfset ArrayClear(Variables.ContentXml.XmlRoot['office:body'][1]['office:drawing'][1]['draw:page'][Arguments.PageNumber].xmlChildren) />
</cffunction>
<cffunction name="addStyle">
<cfset var StyleNode = createStyle(ArgumentCollection=Arguments) />
<cfset ArrayAppend( Variables.ContentXml.XmlRoot['office:automatic-styles'][1].XmlChildren , StyleNode ) />
</cffunction>
<cffunction name="addShape">
<cfset var ShapeNode = createShape(ArgumentCollection=Arguments) />
<cfset ArrayAppend( Variables.ContentXml.XmlRoot['office:body'][1]['office:drawing'][1]['draw:page'][1].XmlChildren , ShapeNode ) />
<cfset incObjectCount() />
</cffunction>
<cffunction name="addConnector">
<cfset var ConnectorNode = createConnector(ArgumentCollection=Arguments) />
<cfset ArrayAppend( Variables.ContentXml.XmlRoot['office:body'][1]['office:drawing'][1]['draw:page'][1].XmlChildren , ConnectorNode ) />
<cfset incObjectCount() />
</cffunction>
<cffunction name="incObjectCount" access="private">
<cfset Variables.MetaXml.XmlRoot['office:meta'][1]['meta:document-statistic'].XmlAttributes['meta:object-count']++ />
</cffunction>
<cffunction name="createStyle">
<cfargument name="Name" type="String" required />
<cfargument name="Family" type="String" required hint="graphic,paragraph,etc" />
<cfargument name="ParentName" type="String" optional />
<cfargument name="Properties" type="Struct" required />
<cfset var StyleXml = "" />
<cfset var StyleNode = XmlElemNew(Variables.ContentXml,'style:style') />
<cfset StyleNode.XmlAttributes['style:name'] = Arguments.Name />
<cfset StyleNode.XmlAttributes['style:family'] = Arguments.Family />
<cfif StructKeyExists(Arguments,'ParentName') >
<cfset StyleNode.XmlAttributes['style:parent-style-name'] = Arguments.ParentName />
</cfif>
<cfswitch expression="#Arguments.Family#">
<cfcase value="graphic">
<cfparam name="Arguments.Properties.HorzAlign" default="center" />
<cfparam name="Arguments.Properties.VertAlign" default="middle" />
<cfset StyleNode.XmlChildren[1] = XmlElemNew(Variables.ContentXml,'style:graphic-properties') />
<cfset StyleNode.XmlChildren[1].XmlAttributes['draw:textarea-horizontal-align'] = Arguments.Properties.HorzAlign />
<cfset StyleNode.XmlChildren[1].XmlAttributes['draw:textarea-vertical-align'] = Arguments.Properties.VertAlign />
</cfcase>
<cfcase value="paragraph">
<!---
fo: is XSL:FO documented at http://www.w3.org/TR/xsl/
text: is additional aspects that fo lacks.
--->
<cfparam name="Arguments.Properties.TextAlign" default="center" />
<cfset StyleNode.XmlChildren[1] = XmlElemNew(Variables.ContentXml,'style:paragraph-properties') />
<cfset StyleNode.XmlChildren[1].XmlAttributes['fo:text-align'] = Arguments.Properties.TextAlign />
</cfcase>
</cfswitch>
<cfreturn StyleNode />
</cffunction>
<cffunction name="createShape">
<cfargument name="Id" type="String" required />
<cfargument name="Shape" type="String" required hint="rect,etc" />
<cfargument name="Style" type="String" required />
<cfargument name="Layer" type="String" default="layout" />
<cfargument name="Position" type="Struct" required hint="{x,y}"/>
<cfargument name="Size" type="Struct" required hint="{w,h}"/>
<cfargument name="Text" type="String" optional />
<cfargument name="TextStyle" type="String" optional />
<cfset var ShapeNode = XmlElemNew(Variables.ContentXml,'draw:#Arguments.Shape#') />
<cfset ShapeNode.XmlAttributes['draw:id'] = Arguments.Id />
<cfset ShapeNode.XmlAttributes['draw:layer'] = Arguments.Layer />
<cfset ShapeNode.XmlAttributes['draw:style-name'] = Arguments.Style />
<cfset ShapeNode.XmlAttributes['svg:x'] = Arguments.Position.X & 'cm' />
<cfset ShapeNode.XmlAttributes['svg:y'] = Arguments.Position.Y & 'cm' />
<cfset ShapeNode.XmlAttributes['svg:width'] = Arguments.Size.W & 'cm' />
<cfset ShapeNode.XmlAttributes['svg:height'] = Arguments.Size.H & 'cm' />
<cfif StructKeyExists(Arguments,'Text')>
<cfset ShapeNode.XmlChildren[1] = XmlElemNew(Variables.ContentXml,'text:p') />
<cfset ShapeNode.XmlChildren[1].XmlText = Arguments.Text />
<cfset ShapeNode.XmlChildren[1].XmlAttributes['text:style-name'] = Arguments.TextStyle />
<cfset ShapeNode.XmlAttributes['draw:text-style-name'] = Arguments.TextStyle />
</cfif>
<cfreturn ShapeNode />
</cffunction>
<cffunction name="createConnector">
<cfargument name="From" type="String" required />
<cfargument name="To" type="String" required />
<cfargument name="Style" type="String" required />
<cfargument name="Layer" type="String" default="layout" />
<cfargument name="Pos1" type="Struct" required hint="{x,y}"/>
<cfargument name="Pos2" type="Struct" required hint="{x,y}"/>
<cfset var ConnectorNode = XmlElemNew(Variables.ContentXml,'draw:connector') />
<cfset ConnectorNode.XmlAttributes['draw:type'] = "line" />
<cfset ConnectorNode.XmlAttributes['draw:layer'] = Arguments.Layer />
<cfset ConnectorNode.XmlAttributes['draw:style-name'] = Arguments.Style />
<cfset ConnectorNode.XmlAttributes['draw:start-shape'] = Arguments.From />
<cfset ConnectorNode.XmlAttributes['draw:end-shape'] = Arguments.To />
<cfset ConnectorNode.XmlAttributes['draw:start-glue-point'] = 2 />
<cfset ConnectorNode.XmlAttributes['draw:end-glue-point'] = 0 />
<cfset ConnectorNode.XmlAttributes['svg:d'] = "m"
& (Arguments.Pos1.X * 1000)
& " "
& (Arguments.Pos1.Y * 1000)
& " "
& (Arguments.Pos2.X - Arguments.Pos1.X) * 1000
& " "
& (Arguments.Pos2.Y - Arguments.Pos1.Y) * 1000
/>
<cfset ConnectorNode.XmlAttributes['svg:x1'] = Arguments.Pos1.X & 'cm' />
<cfset ConnectorNode.XmlAttributes['svg:y1'] = Arguments.Pos1.Y & 'cm' />
<cfset ConnectorNode.XmlAttributes['svg:x2'] = Arguments.Pos2.X & 'cm' />
<cfset ConnectorNode.XmlAttributes['svg:y2'] = Arguments.Pos2.Y & 'cm' />
<cfreturn ConnectorNode />
</cffunction>
</cfcomponent>
<cfset DrawDoc = createObject('component','odg').init( expandPath('./test.odg') ) />
<cfset DrawDoc.clearPage(1) />
<cfset DrawDoc.addStyle
( Name : 'GraStyle1'
, Family : 'graphic'
, ParentName : 'standard'
, Properties : {HorzAlign:'center',VertAlign:'middle'}
) />
<cfset DrawDoc.addStyle
( Name : 'ParStyle1'
, Family : 'paragraph'
, Properties : {TextAlign:'center'}
) />
<cfset DrawDoc.addShape
( Id : 'MyShape1'
, Shape : 'rect'
, Style : 'GraStyle1'
, Layer : 'layout'
, Position : {x:2,y:2}
, Size : {w:4,h:1}
, Text : 'Rectangle!'
, TextStyle : 'ParStyle1'
) />
<cfset DrawDoc.addShape
( Id : 'MyShape2'
, Shape : 'rect'
, Style : 'GraStyle1'
, Layer : 'layout'
, Position : {x:8,y:8}
, Size : {w:4,h:1}
, Text : 'Another one'
, TextStyle : 'ParStyle1'
) />
<cfset DrawDoc.addConnector
( From : 'MyShape1'
, To : 'MyShape2'
, Style : 'GraStyle1'
, Layer : 'layout'
, Pos1 : {x:4,y:3}
, Pos2 : {x:10,y:8}
) />
<cfset DrawDoc.save() />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment