GoogleAppsScript
gas

Google Document API の文書構造でハマった話

今回、Googleドキュメントの文書をスクリプトから編集する処理を書いていて、ハマったポイントがあるので共有します。

やりたい事

  • Googleドキュメントの本文をテンプレートとして使用し、テンプレートファイル内に、生成した本文を出力する

今回やろうとしたのは、文書を水平線(hr)で区切る構成です。

  • 水平線以前がテンプレート
  • 水平線以降に出力結果が表示される

という構成で、水平線以前/以降を判定する処理が必要でした。

水平線を取得する

水平線を取得するのは、
BodyオブジェクトのfindObjectメソッドで行います。

var firstHr = body.findElement(searchTypeHR);

こんな感じです。
これで取得できるのはRangeElementオブジェクトなので、さらにgetElement()メソッドで、中身のHorizontalRuleオブジェクトを取り出してあげます。

var theHr = firstHr.getElement();

これを基準に、段落(Paragraphオブジェクト)の位置を判定すれば、水平線以前と以降がわかるはずです。

水平線の前後要素が取れない

しかし、ここがハマりポイントとなりました。
すなわち、HorizontalRuleオブジェクトの、文書内の位置が取れません。

ここで読むべきものはドキュメントです。

https://developers.google.com/apps-script/guides/docs#structure_of_a_document

これによると、『水平線は、ListItemやParagraphの配下である』と書いてあります。
文書構造としては、このようになっているわけです。

Body
  ├ Paragraph
  │  ├ Text
  │  └ Text
  ├ Paragraph
  │  └ HorizontalRule
    .
    .
    .

解決法

HorizontalRuleオブジェクトはParagraphオブジェクトの子なので、文書内の位置を知るには、親要素となるParagraphオブジェクトを取得する必要がありました。

というわけで、以下のようにすると、文書内の位置が取れたのでした。

body.getChildIndex( theHr.getParent())

めでたし。