@@ -183,15 +183,19 @@ func buildSlidesObjectReplaceTextRequests(pres *slides.Presentation, objectID, f
183183 return nil , 0 , usage ("object-scoped replace-text currently supports shape text objects only" )
184184 }
185185
186- matches := slidesTextMatches (text , find , matchCase )
186+ matches := slidesTextMatches (text . content , find , matchCase )
187187 if len (matches ) == 0 {
188188 return nil , 0 , usage ("no matching text found in object" )
189189 }
190190
191191 requests := make ([]* slides.Request , 0 , len (matches )* 2 )
192192 for i := len (matches ) - 1 ; i >= 0 ; i -- {
193193 match := matches [i ]
194- textRange , err := slidesFixedTextRange (match .start , match .end )
194+ start , end , err := text .slidesRange (match .start , match .end )
195+ if err != nil {
196+ return nil , 0 , err
197+ }
198+ textRange , err := slidesFixedTextRange (start , end )
195199 if err != nil {
196200 return nil , 0 , err
197201 }
@@ -205,7 +209,7 @@ func buildSlidesObjectReplaceTextRequests(pres *slides.Presentation, objectID, f
205209 requests = append (requests , & slides.Request {
206210 InsertText : & slides.InsertTextRequest {
207211 ObjectId : objectID ,
208- InsertionIndex : match . start ,
212+ InsertionIndex : start ,
209213 Text : replacement ,
210214 },
211215 })
@@ -214,9 +218,37 @@ func buildSlidesObjectReplaceTextRequests(pres *slides.Presentation, objectID, f
214218 return requests , len (matches ), nil
215219}
216220
217- func slidesShapeTextByObjectID (pres * slides.Presentation , objectID string ) (string , bool , bool ) {
221+ type slidesIndexedText struct {
222+ content string
223+ codeUnitIndexes []int64
224+ }
225+
226+ func (t slidesIndexedText ) slidesRange (start , end int64 ) (int64 , int64 , error ) {
227+ if start < 0 || end <= start || end > int64 (len (t .codeUnitIndexes )) {
228+ return 0 , 0 , usage ("matched text range is outside the object's Slides text indexes" )
229+ }
230+ return t .codeUnitIndexes [start ], t .codeUnitIndexes [end - 1 ] + 1 , nil
231+ }
232+
233+ func (t * slidesIndexedText ) appendTextRun (startIndex int64 , content string ) {
234+ var b strings.Builder
235+ b .WriteString (t .content )
236+ b .WriteString (content )
237+ t .content = b .String ()
238+
239+ index := startIndex
240+ for _ , r := range content {
241+ units := utf16CodeUnits (string (r ))
242+ for i := int64 (0 ); i < units ; i ++ {
243+ t .codeUnitIndexes = append (t .codeUnitIndexes , index + i )
244+ }
245+ index += units
246+ }
247+ }
248+
249+ func slidesShapeTextByObjectID (pres * slides.Presentation , objectID string ) (slidesIndexedText , bool , bool ) {
218250 if pres == nil {
219- return "" , false , false
251+ return slidesIndexedText {} , false , false
220252 }
221253 for _ , page := range pres .Slides {
222254 if page == nil {
@@ -227,18 +259,18 @@ func slidesShapeTextByObjectID(pres *slides.Presentation, objectID string) (stri
227259 continue
228260 }
229261 if el .Shape == nil || el .Shape .Text == nil {
230- return "" , true , false
262+ return slidesIndexedText {} , true , false
231263 }
232- var b strings. Builder
264+ var text slidesIndexedText
233265 for _ , textElement := range el .Shape .Text .TextElements {
234266 if textElement != nil && textElement .TextRun != nil {
235- b . WriteString ( textElement .TextRun .Content )
267+ text . appendTextRun ( textElement . StartIndex , textElement .TextRun .Content )
236268 }
237269 }
238- return b . String () , true , true
270+ return text , true , true
239271 }
240272 }
241- return "" , false , false
273+ return slidesIndexedText {} , false , false
242274}
243275
244276type slidesTextMatch struct {
0 commit comments