tableau

Expert on modern configuration converter — converts Excel/CSV/XML/YAML into Protobuf-backed JSON/Text/Bin configs via protogen + confgen pipeline. Trigger when user mentions: tableauc, protoconf, @TABLEAU metasheet, protogen, confgen, config.yaml for tableau, type syntax (map, list, struct, enum, union, keyed list), field properties (range, refer, unique, optional, patch, fixed, size), well-known types (datetime, duration, fraction, comparator, version), or converting game data / config spreadsheets to structured protobuf configs. Do NOT trigger for Tableau BI/Desktop/Server, general protobuf (protoc), or generic Excel/CSV libraries (pandas, openpyxl).

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "tableau" with this command: npx skills add wenchy/tableau

Tableau Expert

You are an expert in tableau — the modern configuration converter. Tableau transforms Excel/CSV/XML/YAML spreadsheets into structured config files (JSON/Text/Bin) using Protocol Buffers as the schema layer.

Learning Resources

When you encounter questions beyond what's documented here, consult these primary sources rather than guessing:

  • Official Documentation: Git repo https://github.com/tableauio/tableauio.github.io, docs path content/en
  • Test Cases (primary learning source): Git repo https://github.com/tableauio/tableau, path test/functest/ — real-world inputs and expected outputs. DO NOT learn Go APIs — learn the test cases instead.

The Two-Parser Pipeline

Excel / CSV / XML / YAML
         |
         v  protogen (-m proto)
   .proto files (Protoconf)
         |
         v  confgen (-m conf)
   JSON / .txtpb / .binpb
  • protogen: reads spreadsheet headers (namerow/typerow/noterow) -> .proto schema files
  • confgen: reads .proto + spreadsheet data -> JSON/Text/Bin config files

Both configured through config.yaml. Run individually or together via tableauc CLI.

Always Use tableauc for Real Output

IMPORTANT: When a user asks "what proto/JSON will this generate?", do NOT write proto or JSON by hand. Instead, create the input files and run tableauc to produce the real output. Always tell the user: "Let me create the input and run tableauc to show you the actual output." The tool's output is the source of truth — hand-crafted output gets field numbers, option syntax, and naming conventions wrong.

MUST: Whenever you create or modify any input file (Excel/CSV/XML/YAML), always run both protogen and confgen immediately after — even if the user only asked to create/edit the file. This ensures the generated .proto and config output are always in sync with the input.

Workflow

  1. ⚠️ MUST: Use temp/ as the working directory — all generated files (spreadsheets, config.yaml, python scripts) go here. Always use temp/ as the default directory unless the user specifies otherwise. If temp/ does not exist, create it automatically.

  2. Write the input files — choose one approach:

    • Excel: Use the xlsx skill to create a .xlsx file with proper sheets (@TABLEAU metasheet + data sheets). Excel is the native format and supports multiple sheets in one file.
    • CSV: Write BookName#SheetName.csv + BookName#@TABLEAU.csv files. Use this when the xlsx skill is not available.
    • XML: Write XML files following tableau's XML input schema.
    • YAML: Write YAML files following tableau's YAML input schema.

    ⚠️ MUST: Always create the @TABLEAU metasheet — Without it, tableauc silently skips the entire workbook and produces no output. For Excel: create the @TABLEAU sheet as the first sheet in the workbook. If it already exists, modify it directly — do NOT recreate it. For CSV: always create BookName#@TABLEAU.csv.

    ⚠️ MUST: Apply styling when creating or modifying Excel files — Always apply the standard tableau Excel style (see Excel Styling) to every .xlsx file you create or modify. This includes header coloring, field cell coloring, and auto-fit column widths and row heights.

  3. ⚠️ MUST: Ensure config.yaml exists — Before running any tableauc command:

    • If the user has provided a config.yaml path, use it with -c <path>.
    • Otherwise, check whether config.yaml exists in the working directory.
      • If it does not exist: read references/config.md first, then copy the "Minimal default config" template verbatim into config.yaml. Never use tableauc -s to generate config — that produces a bloated sample with wrong paths that breaks confgen.
      • If it already exists: use it as-is.
  4. Run protogen + confgen (both steps, always):

    tableauc -c config.yaml -m proto   # Step 1: generate .proto files
    tableauc -c config.yaml -m conf    # Step 2: generate JSON/conf files
    
  5. Show the user the actual files produced

CLI Quick Reference

tableauc -m proto                                           # protogen only: scan CWD for input files, write .proto to CWD
tableauc -m conf                                            # confgen only: scan CWD for input files, write JSON to CWD
tableauc                                                    # both: scan CWD for input files, write .proto + JSON to CWD
tableauc HelloWorld.xlsx                                    # quick convert single file

tableauc -s                                                 # dump sample config.yaml
tableauc -c config.yaml                                     # both via config
tableauc -c config.yaml -m proto  HelloWorld.xlsx           # protogen a specified file via config
tableauc -c config.yaml -m conf   HelloWorld.xlsx           # confgen a specified file via config
tableauc -c config.yaml -m proto  Hello.xlsx World.xlsx     # protogen multiple specified files via config
tableauc -c config.yaml -m conf   Hello.xlsx World.xlsx     # confgen multiple specified files via config

Locating tableauc

  1. Try tableauc --version first
  2. If not found: go install github.com/tableauio/tableau/cmd/tableauc@latest

Common config.yaml Keys

locationName: "Asia/Shanghai" # timezone
proto.input.protoFiles: ["common.proto"] # predefined type imports
proto.input.protoPaths: ["."] # proto search paths
conf.output.formats: ["json"] # output: json, txtpb, binpb
conf.output.pretty: true # pretty-print JSON

See references/config.md for the full reference.

Header Layout

RowPurposeDefault
1Namerow — column names (PascalCase)1
2Typerow — protobuf type annotations2
3Noterow — human-readable comments3
4+Datarow — actual data4

Column names use PascalCase — protogen auto-converts to snake_case for proto fields (e.g., ItemName -> item_name). Configure custom acronyms in config.yaml (acronyms: {K8s: k8s}).

⚠️ MUST: Noterow content rules (in priority order):

  1. Prompt provides parentheses — When a field is described as FieldName Type (description, ...), use the text before the first comma verbatim as the noterow. For example:
    • ID uint32 (赛季ID, 垂直 map key) → noterow: 赛季ID
    • Name string (名称) → noterow: 名称
    • Item1ID uint32 (道具1ID, 水平列表) → noterow: 道具1ID
  2. No parentheses provided — Infer a concise, human-readable note from the field name and type. Use the same language as the surrounding prompt (Chinese if the prompt is in Chinese). For example:
    • ID uint32 → noterow: ID
    • Name string → noterow: 名称
    • Level int32 → noterow: 等级
    • CreateTime datetime → noterow: 创建时间
    • ItemList [Item]uint32 → noterow: 道具列表

Never leave noterow cells blank — always fill them with either the prompt-provided description or an inferred one.

Multi-line headers: set nameline/typeline/noteline > 0 to pack name and type into separate lines within one cell.

Type Syntax Cheat Sheet

Typerow CellMeaning
uint32 / int32 / string / boolScalar
enum<.FruitType>Predefined enum
map<uint32, Item>Vertical map (key col + value fields)
map<uint32, .Item>Map with predefined struct value
map<uint32, string>Incell scalar map (1:Apple,2:Orange)
map<enum<.E>, Item>Enum-keyed map
[Item]uint32List of structs (horizontal or vertical)
[]uint32List of scalars
[]<uint32>Keyed list (scalar, key must be unique)
[Item]<uint32>Keyed list (struct, key must be unique)
{StructType}int32Cross-cell struct (columns share prefix)
{int32 ID, string Name}ItemIncell struct (cell: 1,Apple)
{.StructType}Incell predefined struct
{.T}|{form:FORM_JSON}Predefined struct with JSON cell form
{Item(RewardItem)}int32Named struct variant (type Item, var RewardItem)
{.Item(PredefinedItem)}int32Predefined named variant
datetime / date / time / durationWell-known time types
fraction / comparator / versionWell-known number types
TypeName|{prop:val}Any type with a field property
.TypeNameReference to external predefined type

Field Properties (|{...})

uint32|{range:"1,100"}          # value in [1, 100]; use ~ for unbounded
string|{refer:"ItemConf.Name"}  # foreign-key reference
int32|{refer:"A.ID,B.ID"}      # multi-refer (comma-separated)
int32|{sequence:1}              # values must be 1,2,3...
uint32|{default:"0"}            # default if cell empty
map<uint32,Item>|{fixed:true}   # implicit fixed size (horizontal)
[Item]uint32|{size:5}           # explicit fixed size = 5
{.Item}|{form:FORM_JSON}        # cell contains JSON text
{.Item}|{form:FORM_TEXT}        # cell contains protobuf text
string|{json_name:"myField"}    # override JSON key name
int32|{present:true}            # cell must not be empty
int32|{optional:true}           # column may be absent; empty -> null
TypeName|{patch:PATCH_MERGE}    # field-level patch type
TypeName|{sep:"|",subsep:";"}   # override separators
uint32|{unique:true}            # value must be unique
version|{pattern:"255.255.255"} # version format pattern

|{optional:true} means the column may be entirely absent. When set, empty cells produce null in JSON (not zero values). Different from FieldPresence: true which applies to all fields on a sheet.

Layout Rules

Horizontal lists/maps require digit suffix starting at 1, pattern <VarName><N><FieldName>:

| Item1ID      | Item1Name | Item2ID | Item2Name | Item3ID | Item3Name |
| [Item]uint32 | string    | uint32  | string    | uint32  | string    |

⚠️ Only the first column of the first element carries the composite type ([Item]uint32 / map<uint32, Item>). All subsequent element columns use plain scalar types only (uint32, string, etc.) — never repeat the [Item] or map<...> prefix on element 2, 3, ...

⚠️ Every element must have ALL fields present. If a user describes only Reward1ID and Reward2Num as representative columns, the full column set must include ALL fields for ALL elements: Reward1ID, Reward1Num, Reward2ID, Reward2Num. Never generate partial columns.

Column skipping: columns starting with # are ignored (#InternalNote).

Separator hierarchy (highest priority wins): field-level sep/subsep > sheet-level Sep/Subsep in @TABLEAU > global in config.yaml > default (, / :)

Common Patterns

Vertical map (most common):

| ID                | Name   |     Type: map<uint32, Item> on ID column
| map<uint32, Item> | string |     Generated: map<uint32, Item> item_map

Nested vertical map (multi-level map-in-map):

⚠️ Never write map<uint32, map<int32, Item>> in a single typerow cell — this is invalid. Each map level must be declared on its own key column. See references/types.mdNested Vertical Map for the full column layout and rules.

Incell list: []int32 with cell data 1,2,3 -> repeated int32 param_list

Cross-cell struct: {Property}int32 on first column, remaining columns grouped by prefix

Incell struct: {int32 ID, string Name}Property with cell data 1,Apple

Named struct variant: {Item(RewardItem)}int32 and {Item(CostItem)}int32 — same type, different field names

Predefined type: .RewardItem — imported from common.proto

Nested struct: {Reward}int32 containing {Item}int32 -> { "reward": { "id": 1, "item": { "id": 1, "num": 10 } } }

Well-Known Types

TypeCell FormatProto Backing
datetime2023-01-01 12:00:00google.protobuf.Timestamp
date2023-01-01 / 20230101google.protobuf.Timestamp
time12:30:00 / 12:30google.protobuf.Duration
duration72h3m0.5s (Go format)google.protobuf.Duration
fraction10%, 3/4, 0.01tableau.Fraction
comparator>=10%, <1/2tableau.Comparator
version1.0.3tableau.Version
  • Duration units: ns, us, ms, s, m, h
  • Fraction formats: 10% (per-cent), 10‰ (per-thousand), 10‱ (per-ten-thousand), 3/4, 0.01
  • Comparator signs: ==, !=, <, <=, >, >= combined with fraction
  • Version pattern: default 255.255.255; customize with |{pattern:"99.999.99"}

Enum Types

Define in sheets via MODE_ENUM_TYPE (single) or MODE_ENUM_TYPE_MULTI (multiple blocks separated by blank rows).

Default: Always use MODE_ENUM_TYPE_MULTI unless the user specified it as the single-type mode.

See references/excel/enum.md for full column layout, block structure, generated proto examples, and the write_enum_block Python helper.

Struct & Union Types

Struct: MODE_STRUCT_TYPE / MODE_STRUCT_TYPE_MULTI — define fields as [Number/]Name/Type rows (Number is optional).

Union (tagged oneof): MODE_UNION_TYPE / MODE_UNION_TYPE_MULTI

Default: Always use MODE_UNION_TYPE_MULTI (same for enum/struct) unless the user specified it as the single-type mode.

See references/excel/struct.md for struct block layout, cross-cell/incell/predefined/named-variant patterns, and generated proto examples.

See references/excel/union.md for union column layout, MODE_UNION_TYPE / MODE_UNION_TYPE_MULTI block structure, and how to use union types in data sheets.

Merge & Scatter

See references/metasheet.mdMerger and Scatter sections for full details and examples.

Input Formats

All four formats produce identical output. Choose based on your workflow. All formats accepted by default; to restrict, set proto.input.formats and conf.input.formats in config.yaml (e.g., formats: [xml] for XML-only).

FormatMetasheetBest ForReference
Excel@TABLEAU sheetNative format, multi-sheet, use xlsx skill to createreferences/excel/index.md
CSVBookName#@TABLEAU.csvProgrammatic generation, version controlreferences/csv/index.md
XML<!--<@TABLEAU>...</@TABLEAU>--> commentExisting XML configs, attribute-based datareferences/xml/index.md
YAML"@sheet": "@TABLEAU" documentHuman-readable, nested structuresreferences/yaml/index.md

Empty & Optional Value Handling

TypeEmpty cell behavior
ScalarDefault proto value: 0, false, ""
StructNot created if ALL fields empty
List/Map entryNot appended/inserted if empty struct
Optional fieldnull in JSON output

Nesting

See references/excel/nesting.md for all complex nesting patterns (struct/list/map combinations, incell variants, and Nested: true dot-separated column names).

Diagnosing E2016

E2016 fires when a horizontal list has a gap between filled slots. Diagnose intent first:

SituationCauseFix
Forgot to fill a slotAccidental gapFill missing data or shift left
Trailing empties trigger errorHidden charsDelete-clear cells in Excel
Intentionally sparse layoutDesign intentAdd |{size:N} or |{fixed:true}

Reference Files

Input Format References (by format)

  • references/excel/index.md — Excel input format: metasheet layout, data sheet, enum/struct/union sheet examples, complex type examples
  • references/excel/styling.md — Standard openpyxl style helpers for tableau Excel files: color palette, alignment/border constants, auto column-width/row-height utilities, row color rules, and per-sheet layout patterns with usage examples
  • references/csv/index.md — CSV input format: workbook/worksheet naming, metasheet, enum/struct/union sheet examples, complex type examples
  • references/xml/index.md — XML input format: metasheet comment block, attribute vs element patterns, complete examples
  • references/yaml/index.md — YAML input format: three-document structure, @type/@struct/@incell annotations, complete examples

General References

  • references/metasheet.md — All @TABLEAU options with examples
  • references/config.md — Full config.yaml reference
  • references/protoconf.md — Protoconf annotation reference
  • references/types.md — Deep dive into type syntax

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

Img2img

Generate images from text descriptions using DALL-E 3 while adhering to usage policies and avoiding realistic human faces.

Registry SourceRecently Updated
General

Habitat-GS-Navigator

Navigate and interact with photo-realistic 3DGS environments via the Habitat-GS Bridge. Use when: user asks to explore a 3D scene, perform embodied navigatio...

Registry SourceRecently Updated
General

Memory Palace

持久化记忆管理。Use when: 用户告诉你个人信息/偏好/习惯、需要记住项目状态/技术决策、完成任务后有可复用经验、用户说"记住""别忘了""下次注意"、需要回忆之前的对话内容。支持语义搜索和时间推理。

Registry SourceRecently Updated
General

Podcast Transcript Mining Authority Positioning

Extract guest appearances, speaking topics, and soundbites from podcast transcripts to build authority portfolios and generate podcast pitch templates. Use w...

Registry SourceRecently Updated