ReplaceTextFmt.vb
''
'' This code is part of GrapeCity Documents for Word samples.
'' Copyright (c) GrapeCity, Inc. All rights reserved.
''
Imports System.Drawing
Imports System.Text
Imports System.Linq
Imports System.Collections.Generic
Imports System.Text.RegularExpressions
Imports GrapeCity.Documents.Word

'' This sample loads an existing document, finds all occurrences
'' of a certain string in it, And replaces that string with another one,
'' also changing the character format of the replacement string.
'' This sample Is similar to ReplaceText, with the addition of
'' formatting change, And has the same limitation - it only finds
'' occurrences of the search string that are completely within a single run.
'' See ReplaceTextFmt2 for an example of using PersistentRange in the
'' same scenario.
Public Class ReplaceTextFmt
    Function CreateDocx() As GcWordDocument
        '' The document to replace text in:
        Dim path = IO.Path.Combine("Resources", "WordDocs", "JsFrameworkExcerpt.docx")
        '' The text to find
        Const tFind = "javascript"
        '' The replacement
        Const tRepl = "ArabicaScroll"

        Dim doc = New GcWordDocument()
        doc.Load(path)

        Dim runs = doc.Body.Runs
        Dim runRanges = New List(Of Range)(runs.Count)
        For Each run In runs
            runRanges.Add(run.GetRange())
        Next

        For Each rr In runRanges
            Dim str = rr.Text
            Dim matches = Regex.Matches(str, tFind, RegexOptions.IgnoreCase)
            If matches.Count = 0 Then
                Continue For
            End If

            Dim color = rr.ParentRun.Font.Color.RGB
            rr.Clear()
            Dim r = rr.Runs.Last
            Dim pos = 0
            For Each m In matches
                r = r.GetRange().Runs.Insert(str.Substring(pos, m.Index - pos), InsertLocation.After)
                r.Font.Color.RGB = color
                r = r.GetRange().Runs.Insert(tRepl, InsertLocation.After)
                r.Font.Color.RGB = Color.Red
                pos = m.Index + m.Length
            Next
            r = r.GetRange().Runs.Insert(str.Substring(pos), InsertLocation.After)
            r.Font.Color.RGB = color
            If Not String.IsNullOrEmpty(rr.Runs.First.GetRange().Text) Then
                Throw New Exception("Unexpected")
            End If
            rr.Runs.First.Delete()
        Next
        '' Not strictky necessary but a good practice:
        runRanges.Clear()

        '' Add a note at the end of the document
        doc.Body.Sections.Last.GetRange().Paragraphs.Add(
            $"GcWord replaced '{tFind}' with '{tRepl}' on {DateTime.Now}.")

        '' Done
        Return doc
    End Function
End Class