Louis Sankey
Louis Sankey

Reputation: 492

google docs api - trouble creating single paragraph with multiple text styles like bold, italic, etc

So I have gotten comfortable with the google docs API, but I am still having one problem. When I try to mix styles like bold and italic into a single paragraph, the styles are not displaying correctly.

Instead when I set to bold and italic, the span of text is reverting to Areal font type (which is different than what I have set) and then continuing for the rest of the paragraph: it looks like this

The strange thing is, if I add a simple line break before and after the request it will work just fine. I can have one paragraph regular text, followed by bold, followed by regular, followed by italic:

enter image description here

But when I don't add the line break, it doesn't work correctly. I think it may be an index issue (although I'm taking the suggested approach of building the document backward with request so indexing really shouldn't be the problem, I'm not dealing with it directly. )

It could also be that I'm including paragraph styles with each textstyle update request, maybe its conflicting with something?

Or maybe what I am trying to do is actually not yet supported? It is v.1 of the api after all.

The fn I'm using to make the requests:

function textRequest(text: string, fontSize: number, alignment = 'CENTER', lineSpacing = 100, color = 0.3, style = ' '){
  const requests:Array<object> = [
    {
      insertText: {
        text: text,
        location: {
          index: 1,
        },
      },
    },
    {
      updateParagraphStyle: {           
        paragraphStyle: {
          lineSpacing: lineSpacing,
          namedStyleType: 'NORMAL_TEXT',
          alignment: alignment,
          direction: 'LEFT_TO_RIGHT'
        },
        fields: 'namedStyleType, alignment, direction, lineSpacing',
        range: {
          startIndex: 1,
          endIndex: text.length + 1,
        },
      }
    },
    {
      updateTextStyle: {
        textStyle: {
          bold: style === 'BOLD',
          italic: style === 'ITALIC',
          foregroundColor: {
            color: {
              rgbColor: {
                red: color,
                green: color,
                blue: color
              }
            }
          },
          fontSize: {
            magnitude: fontSize,
            unit: 'PT'
          },
          weightedFontFamily: {
            fontFamily: 'PT',
            weight: 400
          }
        },
        fields: 'bold, italic, foregroundColor, fontSize, weightedFontFamily',
        range: {
          startIndex: 1,
          endIndex: text.length + 1,
        },
      },
 
    }
  ];
  return requests;
}

then I'm building the full request by pushing calls like this:

request.push(textRequest(text.trim(), 12, 'START', 200, 0.3, 'BOLD')

Anyway, all thoughts or suggestings are welcome. Thanks!

Upvotes: 1

Views: 886

Answers (1)

Tanaike
Tanaike

Reputation: 201438

Question 1

I believe your goal is as follows.

  • For example, when a paragraph of sample1 sample2 sample3 is put to Google Document using Docs API, you want to set the bold type to sample2.

When I saw your request body, at updateTextStyle, range is {startIndex: 1, endIndex: text.length + 1,}. In this case, this text style is reflected in the whole text. I think that this might be the reason for your issue. If you want to set the bold to the part of the text in a paragraph, it is required to set the part of the text to range.

Here, I would like to introduce a simple sample request body as follows. When a paragraph of sample1 sample2 sample3 with the bold type to sample2 is put to Google Document using Docs API, the sample request body is as follows.

Sample request body:

{
  "requests": [
    {
      "insertText": {
        "text": "sample1 sample2 sample3",
        "location": {
          "index": 1
        }
      }
    },
    {
      "updateTextStyle": {
        "textStyle": {
          "bold": true
        },
        "range": {
          "startIndex": 9,
          "endIndex": 16
        },
        "fields": "bold"
      }
    }
  ]
}
  • When you use this request body to the batchUpdate method of Docs API, the following result is obtained. Also, you can simply test this request body at Try this method.

    enter image description here

Reference:

Question 2

From your following new question,

is there a way to accomplish the same thing, but with 3 SEPARATE insertText requests? So.. sample 1 is first request with style normal, sample 2 is second request with style bold, and sample 3 is normal again.

Unfortunately, I think that these process cannot be achieve by 3 requests. Because, at the batchUpdate method of Google Docs API, insertText and updateTextStyle cannot be inlcuded one batch request. In this case, it is required to separate them for each request. So, in order to achieve your new question, it is required to use the following request body.

Sample request body:

{
  "requests": [
    {
      "insertText": {
        "text": "sample1 ",
        "location": {
          "index": 1
        }
      }
    },
    {
      "insertText": {
        "text": "sample2 ",
        "location": {
          "index": 9
        }
      }
    },
    {
      "updateTextStyle": {
        "textStyle": {
          "bold": true
        },
        "range": {
          "startIndex": 9,
          "endIndex": 16
        },
        "fields": "bold"
      }
    },
    {
      "insertText": {
        "text": "sample3",
        "location": {
          "index": 17
        }
      }
    }
  ]
}
  • When this request body is run, the same result with the above image is obtained.

Question 3

From your following reply,

In my example I am trying to build the document in reverse so the index will always = 1. And the endIndex should always = text.length + 1. I do this because I do not know every start/endIndex for bold or italic. The request needs to be build dynamically.

From your 1st and 2nd question, I couldn't understand you wanted that. For example, if you want to put the values sample3, sample2 and sample1 in order. And you want to set the bold to sample2.

In this case, how about the following sample request body?

{
  "requests": [
    {
      "insertText": {
        "text": "sample3",
        "location": {
          "index": 1
        }
      }
    },
    {
      "insertText": {
        "text": "sample2 ",
        "location": {
          "index": 1
        }
      }
    },
    {
      "updateTextStyle": {
        "textStyle": {
          "bold": true
        },
        "range": {
          "startIndex": 1,
          "endIndex": 8
        },
        "fields": "bold"
      }
    },
    {
      "insertText": {
        "text": "sample1 ",
        "location": {
          "index": 1
        }
      }
    },
    {
      "updateTextStyle": {
        "range": {
          "startIndex": 1,
          "endIndex": 8
        },
        "fields": "*"
      }
    }
  ]
}

In this request body, when sample1 is put, it is required to use the default text style. Because when this is not used, sample1 is set as the bold type by the text style of sample2. Please be careful this.

About your following 3rd question,

I still do not understand why I cannot make updateStyle request after updateText request. This way I always know the start and endIndex will be correct.

In my sample request body of your 2nd question, I don't use updateText. When you miscopied updateText with insertText, when both insertText and updateTextStyle are used in one request, an error of Invalid value at 'requests[0]' (oneof), oneof field 'request' is already set. Cannot set 'updateTextStyle' occurs. So, I think that this is the current specification of the Google side. So, the answer of your 3rd question of why I cannot make updateStyle request after insertText request is due to the current specification of the Google side.

Upvotes: 4

Related Questions