@@ -78,44 +78,19 @@ let imageSizingXml = {
7878}
7979
8080/**
81- * Transforms a slide or slideLayout to resulting XML string - Creates `ppt/slide*.xml`
82- * @param {PresSlide|SlideLayout } slideObject - slide object created within createSlideObject
83- * @return {string } XML string with <p:cSld> as the root
81+ * Transforms a list of slide objects to an XML string and returns the position and size values for their container.
82+ * @param {ISlideObject[] } slideItemObjs
83+ * @param {PresSlide|SlideLayout } slide
84+ * @returns
8485 */
85- function slideObjectToXml ( slide : PresSlide | SlideLayout ) : string {
86- let strSlideXml : string = slide . _name ? '<p:cSld name="' + slide . _name + '">' : '<p:cSld>'
87- let intTableNum : number = 1
88-
89- // STEP 1: Add background
90- if ( slide . bkgd ) {
91- strSlideXml += genXmlColorSelection ( null , slide . bkgd )
92- } else if ( ! slide . bkgd && slide . _name && slide . _name === DEF_PRES_LAYOUT_NAME ) {
93- // NOTE: Default [white] background is needed on slideMaster1.xml to avoid gray background in Keynote (and Finder previews)
94- strSlideXml += '<p:bg><p:bgRef idx="1001"><a:schemeClr val="bg1"/></p:bgRef></p:bg>'
95- }
96-
97- // STEP 2: Add background image (using Strech) (if any)
98- if ( slide . _bkgdImgRid ) {
99- // FIXME: We should be doing this in the slideLayout...
100- strSlideXml +=
101- '<p:bg>' +
102- '<p:bgPr><a:blipFill dpi="0" rotWithShape="1">' +
103- '<a:blip r:embed="rId' +
104- slide . _bkgdImgRid +
105- '"><a:lum/></a:blip>' +
106- '<a:srcRect/><a:stretch><a:fillRect/></a:stretch></a:blipFill>' +
107- '<a:effectLst/></p:bgPr>' +
108- '</p:bg>'
109- }
110-
111- // STEP 3: Continue slide by starting spTree node
112- strSlideXml += '<p:spTree>'
113- strSlideXml += '<p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr>'
114- strSlideXml += '<p:grpSpPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="0" cy="0"/>'
115- strSlideXml += '<a:chOff x="0" y="0"/><a:chExt cx="0" cy="0"/></a:xfrm></p:grpSpPr>'
116-
117- // STEP 4: Loop over all Slide.data objects and add them to this slide
118- slide . _slideObjects . forEach ( ( slideItemObj : ISlideObject , idx : number ) => {
86+ function slideItemObjsToXml ( slideItemObjs : ISlideObject [ ] , slide : PresSlide | SlideLayout ) : { str : string , containerX : number , containerY : number , containerCx : number , containerCy : number } {
87+ let strSlideXml = ''
88+ let intTableNum = 1
89+ let containerX = Infinity
90+ let containerY = Infinity
91+ let containerCx = 0
92+ let containerCy = 0
93+ slideItemObjs . forEach ( ( slideItemObj : ISlideObject , idx : number ) => {
11994 let x = 0 ,
12095 y = 0 ,
12196 cx = getSmartParseNumber ( '75%' , 'X' , slide . _presLayout ) ,
@@ -142,6 +117,11 @@ function slideObjectToXml(slide: PresSlide | SlideLayout): string {
142117 if ( typeof slideItemObj . options . w !== 'undefined' ) cx = getSmartParseNumber ( slideItemObj . options . w , 'X' , slide . _presLayout )
143118 if ( typeof slideItemObj . options . h !== 'undefined' ) cy = getSmartParseNumber ( slideItemObj . options . h , 'Y' , slide . _presLayout )
144119
120+ containerX = Math . min ( containerX , x )
121+ containerY = Math . min ( containerY , y )
122+ containerCx = Math . max ( containerCx , cx )
123+ containerCy = Math . max ( containerCy , cy )
124+
145125 // If using a placeholder then inherit it's position
146126 if ( placeholderObj ) {
147127 if ( placeholderObj . options . x || placeholderObj . options . x === 0 ) x = getSmartParseNumber ( placeholderObj . options . x , 'X' , slide . _presLayout )
@@ -660,12 +640,77 @@ function slideObjectToXml(slide: PresSlide | SlideLayout): string {
660640 strSlideXml += '</p:graphicFrame>'
661641 break
662642
643+ case SLIDE_OBJECT_TYPES . group :
644+ if ( slideItemObj . group . _slideObjects . length > 0 ) {
645+ const {
646+ str : slideItemsXml ,
647+ containerX : x ,
648+ containerY : y ,
649+ containerCx : cx ,
650+ containerCy : cy
651+ } = slideItemObjsToXml ( slideItemObj . group . _slideObjects , slide )
652+ strSlideXml += '<p:grpSp>'
653+ strSlideXml += `<p:nvGrpSpPr><p:cNvPr id="${ idx + 1 } " name="Group"/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr>`
654+ strSlideXml += `<p:grpSpPr><a:xfrm><a:off x="${ x } " y="${ y } "/><a:ext cx="${ cx } " cy="${ cy } "/>`
655+ strSlideXml += `<a:chOff x="${ x } " y="${ y } "/><a:chExt cx="${ cx } " cy="${ cy } "/></a:xfrm></p:grpSpPr>`
656+ strSlideXml += slideItemsXml
657+ strSlideXml += "</p:grpSp>"
658+ }
659+ break
660+
663661 default :
664662 strSlideXml += ''
665663 break
666664 }
667665 } )
666+ return {
667+ str : strSlideXml ,
668+ containerX,
669+ containerY,
670+ containerCx,
671+ containerCy,
672+ }
673+ }
674+
675+ /**
676+ * Transforms a slide or slideLayout to resulting XML string - Creates `ppt/slide*.xml`
677+ * @param {PresSlide|SlideLayout } slideObject - slide object created within createSlideObject
678+ * @return {string } XML string with <p:cSld> as the root
679+ */
680+ function slideObjectToXml ( slide : PresSlide | SlideLayout ) : string {
681+ let strSlideXml : string = slide . _name ? '<p:cSld name="' + slide . _name + '">' : '<p:cSld>'
668682
683+ // STEP 1: Add background
684+ if ( slide . bkgd ) {
685+ strSlideXml += genXmlColorSelection ( null , slide . bkgd )
686+ } else if ( ! slide . bkgd && slide . _name && slide . _name === DEF_PRES_LAYOUT_NAME ) {
687+ // NOTE: Default [white] background is needed on slideMaster1.xml to avoid gray background in Keynote (and Finder previews)
688+ strSlideXml += '<p:bg><p:bgRef idx="1001"><a:schemeClr val="bg1"/></p:bgRef></p:bg>'
689+ }
690+
691+ // STEP 2: Add background image (using Strech) (if any)
692+ if ( slide . _bkgdImgRid ) {
693+ // FIXME: We should be doing this in the slideLayout...
694+ strSlideXml +=
695+ '<p:bg>' +
696+ '<p:bgPr><a:blipFill dpi="0" rotWithShape="1">' +
697+ '<a:blip r:embed="rId' +
698+ slide . _bkgdImgRid +
699+ '"><a:lum/></a:blip>' +
700+ '<a:srcRect/><a:stretch><a:fillRect/></a:stretch></a:blipFill>' +
701+ '<a:effectLst/></p:bgPr>' +
702+ '</p:bg>'
703+ }
704+
705+ // STEP 3: Continue slide by starting spTree node
706+ strSlideXml += '<p:spTree>'
707+ strSlideXml += '<p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr>'
708+ strSlideXml += '<p:grpSpPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="0" cy="0"/>'
709+ strSlideXml += '<a:chOff x="0" y="0"/><a:chExt cx="0" cy="0"/></a:xfrm></p:grpSpPr>'
710+
711+ // STEP 4: Loop over all Slide.data objects and add them to this slide
712+ const { str } = slideItemObjsToXml ( slide . _slideObjects , slide )
713+ strSlideXml += str
669714 // STEP 5: Add slide numbers (if any) last
670715 if ( slide . _slideNumberProps ) {
671716 strSlideXml +=
0 commit comments