You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
gog docs raw <docId> returns the document body but only for tab 0. Multi-tab documents have additional content under a tabs[] structure (per the Docs API's includeTabsContent parameter on documents.get), and that content is invisible to raw today. Any consumer that walks body.content to find textRuns, mailto links, named ranges, or table positions can only see tab 0 — content in tabs 1+ is silently absent.
The most concrete consumer hurt by this: any "scan the whole doc for mailto-linked names then promote them to Person smart chips" loop. That loop reads gog docs raw, walks body.content, finds mailto runs, computes (startIndex, endIndex) per match, calls delete + insert-person --index=N in reverse-index order. On a doc with tabs, the loop misses every mailto in tabs 1+. Today that path silently returns 0 promotions instead of erroring.
Adjacent prior art: #323 closed (added --tab to editing commands: write, insert, delete, find-replace). The read side — raw, plus any other walk-style command — never got the same treatment. This issue closes that gap.
Repro
# Create a doc with two tabs; put a mailto link in tab 2:
DOC=$(gog docs create "raw --tab test" -j | jq -r .id)
gog docs tabs add "$DOC" --title "Tab 2"
TAB2=$(gog docs list-tabs "$DOC" -j | jq -r '.tabs[1].id')
gog docs write "$DOC" --replace --markdown --tab="$TAB2" \
--file <(printf 'Hello [Sample Person](mailto:sample@example.com).\n')# Today: gog docs raw misses the tab-2 mailto entirely:
gog docs raw "$DOC"| jq -r ' .body.content[] | (.paragraph?.elements // [])[] | .textRun?.textStyle?.link?.url // empty'# Output: (empty — no mailto found, because raw returned tab 0)# Wanted:
gog docs raw "$DOC" --tab="$TAB2"| jq -r '...'# Output: mailto:sample@example.com
Proposed surface
gog docs raw <docId> [flags]
--tab=STRING Target a specific tab by title or ID (matches the --tab
flag on write/insert/delete/find-replace from #323)
--all-tabs Return a JSON envelope { tabs: [ { tabId, title, body }, ... ] }
instead of a single body. Useful for walk-everything consumers.
Behaviour:
Without --tab and without --all-tabs: backward-compatible (returns the default tab's body, same as today).
With --tab=<id|title>: returns just that tab's body, same JSON shape as today (so consumers don't need a new parser).
With --all-tabs: returns the envelope above. Consumers that want to walk the whole doc can iterate the array.
Same pattern as the existing gog docs export --tab= (experimental flag already in v0.21).
Acceptance criteria
gog docs raw <doc> --tab=<id> returns the body of the specified tab, with body.content semantics identical to the default-tab return.
--tab accepts either a tab ID (e.g. t.abc123) or the visible title (matching the existing --tab resolution on write/insert/delete).
--all-tabs returns every tab including nested child tabs (Docs supports tab hierarchy via childTabs). Document the shape in --help.
Without either flag, behaviour is unchanged from today (no breaking change for existing scripts).
Motivation
gog docs raw <docId>returns the document body but only for tab 0. Multi-tab documents have additional content under atabs[]structure (per the Docs API'sincludeTabsContentparameter ondocuments.get), and that content is invisible torawtoday. Any consumer that walksbody.contentto find textRuns, mailto links, named ranges, or table positions can only see tab 0 — content in tabs 1+ is silently absent.The most concrete consumer hurt by this: any "scan the whole doc for mailto-linked names then promote them to Person smart chips" loop. That loop reads
gog docs raw, walksbody.content, finds mailto runs, computes(startIndex, endIndex)per match, callsdelete+insert-person --index=Nin reverse-index order. On a doc with tabs, the loop misses every mailto in tabs 1+. Today that path silently returns 0 promotions instead of erroring.Adjacent prior art: #323 closed (added
--tabto editing commands:write,insert,delete,find-replace). The read side —raw, plus any other walk-style command — never got the same treatment. This issue closes that gap.Repro
Proposed surface
Behaviour:
--taband without--all-tabs: backward-compatible (returns the default tab's body, same as today).--tab=<id|title>: returns just that tab's body, same JSON shape as today (so consumers don't need a new parser).--all-tabs: returns the envelope above. Consumers that want to walk the whole doc can iterate the array.Same pattern as the existing
gog docs export --tab=(experimental flag already in v0.21).Acceptance criteria
gog docs raw <doc> --tab=<id>returns the body of the specified tab, withbody.contentsemantics identical to the default-tab return.--tabaccepts either a tab ID (e.g.t.abc123) or the visible title (matching the existing--tabresolution on write/insert/delete).--all-tabsreturns every tab including nested child tabs (Docs supports tab hierarchy viachildTabs). Document the shape in--help.find-replace(already covered by feat(docs): add --tab flag to editing commands (write, insert, delete, find-replace) #323) and any future find-range / comments-locate / named-range-list helpers that walk body content.References
documents.getwithincludeTabsContent=true: https://developers.google.com/workspace/docs/api/reference/rest/v1/documents/getTabresource (withchildTabsfor nested-tab hierarchy): https://developers.google.com/workspace/docs/api/reference/rest/v1/documents#Tabfeat(docs): add --tab flag to editing commands.--tabper-tab markdown nesting), feat(docs): add find-range primitive that maps text to Document index ranges #682 (find-range primitive), feat(docs comments): add locate subcommand to resolve a comment to a body range #687 (comments locate). All three benefit from / require a tab-aware raw walk.