Search code examples
javascriptgoogle-apps-scriptdomgoogle-docsgoogle-docs-api

Google app script convert hard wrap to soft wrap for heading 4 in google doc


I am working on a google doc where one heading are spread in multiple lines separated by Enter(\n), I want such to be converted to Soft Return(Shift + Enter), I can do it manually but its very tedious to do it for 100's of such heading, wanted to check if their is a way to do it automatically using maybe google app script, this is what I have tried so far which didn't work:

Attempt 1

function convertHeading6ToSoftWrap() {
  var body = DocumentApp.getActiveDocument().getBody();
  
  var heading4Elements = body.getParagraphs().filter(function (paragraph) {
    return paragraph.getHeading() == DocumentApp.ParagraphHeading.HEADING4;
  });

  heading4Elements.forEach(function (element) {
    var text = element.getText();
    element.clear();
    
    element.setAttributes({
      'LINE_SPACING': 1.5,
      'SPACING_AFTER': 0,
      'SPACING_BEFORE': 0
    });
    
    element.appendText(text);
  });
}

Attempt 2

function convertHeading6ToSoftWrap() {
  var body = DocumentApp.getActiveDocument().getBody();

  var heading4Elements = body.getParagraphs().filter(function (paragraph) {
    return paragraph.getHeading() == DocumentApp.ParagraphHeading.HEADING4;
  });

  heading4Elements.forEach(function (element) {
    var text = element.getText();

    element.clear();

    applySoftWrap(text, body);
  });
}


function applySoftWrap(text, body) {
  var lines = text.split("\n");

  lines.forEach(function (line, index) {
    if (index > 0) {
      body.appendParagraph(line);
    } else {
      body.appendParagraph(line);
    }
  });
}

Any hints or clues are highly appreciated.

sample document illustrating the problem - https://docs.google.com/document/d/18w49xpuRQ9igGeyNPSa4PDhv_lqyrWHHVCL8k7DlCnY/edit?usp=sharing

---- Update ----- Thanks for the suggestions and comments the below code merges the hard return into soft H4 but the issues is it merges all H4 togther into one, i.e the ones that are separated by multiple new lines of if they have text other non H4 paragraph in between they are still merged as one:

function convertHeading4ToSoftWrap() {
  var body = DocumentApp.getActiveDocument().getBody();

  var paragraphs = body.getParagraphs();
  var mergedText = '';
  var isFirstHeading4 = true;

  paragraphs.forEach(function (paragraph) {
    try {
      if (paragraph.getHeading() === DocumentApp.ParagraphHeading.HEADING4) {
        if (isFirstHeading4) {
          mergedText = paragraph.getText();
          isFirstHeading4 = false;
        } else {
          mergedText += '\n' + paragraph.getText();
          paragraph.removeFromParent(); // Remove the redundant paragraph
        }
      }
    } catch (error) {
      console.error('Error processing paragraph:', error);
    }
  });

  // Create a new paragraph with the merged Heading 4 text
  var mergedParagraph = body.appendParagraph(mergedText);

  // Set the new paragraph as Heading 4
  mergedParagraph.setHeading(DocumentApp.ParagraphHeading.HEADING4);
}


Solution

  • Here is an example of combining two HEADING4 lines into one paragraph with a soft return.

    function test() {
      try {
        let doc = DocumentApp.getActiveDocument();
        let body = doc.getBody();
        let paragraphs = body.getParagraphs();
        let i = paragraphs.length-1;  // start from the bottom
        let head2 = null;
        while( i >= 0 ) {
          let paragraph = paragraphs[i];
          if( paragraph.getHeading() === DocumentApp.ParagraphHeading.HEADING4 ) {
            if( head2 ) {
              // join the 2 lines together
              paragraph.appendText(String.fromCharCode(13));
              paragraph.appendText(head2.getText());
              body.removeChild(head2);
              head2 = null;
            }
            else {
              head2 = paragraph;
            }
          }
          else {
            head2 = null;
          }
          i--;
        }
      }
      catch(err) {
        console.log(err);
      }
    }