0

I need to remove trailing whitespace characters within specific ranges of a Word document (using the Office JavaScript API). I want to achieve this while preserving the formatting of the original range's text.

My first approach was to search for all characters in the range and iterate over them backwards to remove any whitespace character found, but creating so many Range objects hurts performance.

Here is an example of my initial code:

async function removeTrailingWhitespace(context, range) {
  const whitespaceChars = [" ", "\t", "\n", "\r"]; // List of whitespace characters to remove
  //search the range for any single character using wildcards
  const searchResults = range.search("?", { matchWildcards: true });
  //console the results
  searchResults.load("items");
  await context.sync();
  console.log(searchResults.items);

  for (let i = searchResults.items.length - 1; i >= 0; i--) {
    //get the last character in the range
    const lastChar = searchResults.items[i];

    console.log("the last character is " + JSON.stringify(lastChar.text));
    //if the last character is a whitespace character, remove it
    if (whitespaceChars.includes(lastChar.text)) {
      console.log("removing the last character");
      lastChar.delete();
      await context.sync();
    } else {
      break;
    }
  }
}

I then considered extracting all the text from the range, performing the removal operation, and replacing the original text with the processed version:

const trimmedText = range.text.trimEnd();
range.insertText(trimmedText, "Replace");

But this method ends up erasing the original formatting of the text.

How can I achieve this without running into the issues mentioned?

2
  • See Avoid using the context.sync method in loops Commented Jul 19, 2023 at 20:26
  • @EugeneAstafiev I removed the context.sync from the loop by grouping all of the deletion operations together and then syncing them all at once, but performance is still slow. My guess is that creating so many Range objects (one for each character) is problematic. Commented Jul 20, 2023 at 7:41

2 Answers 2

0

I had a similar problem with losing formatting, specifically font name and size, when I was editing search results. If you want to use your second method, you can save and restore the formatting as you go pretty easily as long as you load them.

context.load(DocBody, "text, font/size, font/name");
...
for (let i = 0; i < searchResults.items.length; i++) {
  //get font name and size
  var sFontName = searchResults.items[i].font.name;
  var sFontSize = searchResults.items[i].font.size;
  //Some processing here
  searchResults.items[i].font.name = sFontName;
  searchResults.items[i].font.size = sFontSize;
}

My original post and solution: MS-Word add-in won't preserve formatting using insertHTML to insert link

Sign up to request clarification or add additional context in comments.

Comments

-1

Your original method should work. But you have a call of context.sync in a loop. That hurts performance. You can use the techniques from this article to move the context.sync out of the loop.

1 Comment

I removed the context.sync from the loop by grouping all of the deletion operations together and then syncing them all at once, but performance is still slow. My guess is that creating so many Range objects (one for each character) is problematic.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.