Skip to content

feat(docs raw): add --tab to traverse a specific tab; default returns tab 0 only #697

@sebsnyk

Description

@sebsnyk

Motivation

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).
  • The same pattern applies to any other walk-style command that today silently operates on tab 0 only: most relevant are 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions