This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Browser-based documentation generator for Power BI PBIP/TMDL semantic models. Part of the pbip-* tool family by Jihwan Kim (Microsoft MVP). Live demo: https://jonathanjihwankim.github.io/pbip-documenter/
- Vanilla JS, no build step — single-page app deployed to GitHub Pages. Open
index.htmldirectly in a browser to run locally; nonpm install, bundler, or transpiler. - File System Access API — reads PBIP folders directly in the browser (Chrome/Edge/Opera 86+; not supported in Firefox/Safari)
- No backend — all processing happens client-side; user files never leave the browser
- Dark mode — CSS custom properties with
[data-theme="dark"]+prefers-color-schemeauto-detect - Responsive — sidebar collapses to toggle button at 768px
- Run the app locally: open
index.htmlin Chrome/Edge/Opera. No server needed; the File System Access API works onfile://andhttps://. (Some browsers prefer a local static server — any will do, e.g.python -m http.server.) - Run tests: open
tests/test-runner.htmlin a browser and click "Run All Tests". Test files (tests/test-mparser-lineage.js,tests/test-lineage-reverse.js) are loaded as<script>tags by the runner. - Generate sample data: open
scripts/generate-sample.html(Contoso) orscripts/generate-sample-large.html(enterprise — internal only) in Chrome and point at the source folder. Output is written tosamples/contoso.jsonfor demo mode. - Node.js is not used — there is no
package.json. Don't reach for npm tooling.
index.html— SPA shell with Mondrian/De Stijl themed UI; loads all JS files as<script>tags in dependency orderstyles.css— App styling with CSS variables (light + dark themes, responsive breakpoints)app.js— UI logic, File System Access API integration, event handlers, diagram export routing, sponsor toast/banner orchestrationtmdl-parser.js— Line-by-line state machine parser for TMDL files; also exposesDAXReferenceExtractorvisual-parser.js— PBIRvisual.jsonparser (extracts field references, includingfieldParametersandvisualContainerObjects)m-parser.js— M expression parser (data sources, parameters, 15+ connectors, 10-kind step decomposition,Value.NativeQuerySQL extraction)doc-generator.js— Output formatting (Markdown, HTML, JSON), Physical-Source Index, per-visual back-tracediagram.js— SVG rendering (relationship diagrams, visual usage maps) with dynamic star-schema layout, FP/CG header tinting, parallel-edge offsettinglineage-engine.js— Dependency graph builder (data sources → tables → measures → visuals); emitsphysicalColumnnodes,brokenRefsarraylineage-diagram.js— SVG lineage visualization (full, trace, impact, column impact); FP edges dashed purple, broken refs flaggeddetailed-erd.js— Full-detail ERD with every column/measure and row-level relationship lines; large-format-print friendlydrawio-exporter.js— draw.io XML export (ERD + lineage diagrams)mermaid-exporter.js— Mermaid syntax export (erDiagram + flowchart)
All diagram views share a unified toolbar with zoom controls and export buttons:
- SVG download — standalone SVG with embedded fonts, explicit dimensions from viewBox
- draw.io export — mxGraph XML with
shape=tablecontainers, ER cardinality arrows, star-schema layout. ReadsfromCardinality/toCardinalityfrom the TMDL parser (don't re-default to many-to-one). - Mermaid export — copies to clipboard; falls back to
.mmdfile download - Export routing:
app.js_handleDiagramExport()→_exportDiagramSVG/Drawio/Mermaid(). The container map in_exportDiagramSVG()maps diagram types to DOM container IDs — when adding a new diagram, register it there.
State machine with states: IDLE → TABLE_BODY → PROPERTIES → EXPRESSION. Handles: table, column, measure, hierarchy, partition, relationship, role, expression. Key challenges: multi-line DAX (indentation-based), backtick blocks, quoted names, bare boolean keywords (isHidden, isKey, etc. without colons).
- Dynamic Features (field parameters + calculation groups) are first-class: surfaced in
app.jsvia_getDynamicFeaturesSummary(), dedicated sidebar section, sponsor value-moment tracking, and dedicated Markdown/HTML/JSON export sections. - Field parameter detection requires
\bNAMEOF\s*(in the partition source (not generic SWITCH). - Calculation group columns look ordinary in PBIR JSON — the model insights cards and "What PBIR Hides" callouts exist to flag this gap.
- Auto-date tables (
LocalDateTable_*,DateTableTemplate_*) are tagged_isAutoDateby the parser and filtered out of all visible counts and tables indoc-generator.jsvia_getVisibleTables()/_getAutoDateCount().
D:\Contoso\Contoso— small dataset (10 tables, 11 measures, 15 visuals); critical pivot table for FP regression testing:fffa0f95499eb9d4e940on page43eb9eb32ca503831335D:\sample_powerbi— enterprise dataset (61 tables, 87 relationships, 246 measures, 542 visuals); BigQuery-only, 16 FP tables, incremental refresh, no.pbiprootsamples/contoso.json— pre-generated demo-mode payload loaded by "Try with Contoso sample data" button
isHiddenInViewMode— PBIR Visual Manager (Van Gogh theme)pbip-impact-analyzer— Impact Analysis + Safe Refactoring (Picasso Cubism theme)pbip-lineage-explorer— Source-column tracing
- Same sponsor integration pattern as sibling repos (GitHub Sponsors + Buy Me a Coffee)
- Sponsor toast shows once per session after first download; gratitude toast precedes it
- Footer cross-links to other
pbip-*tools - Generated documents include "Generated with pbip-documenter" watermark
- Enterprise sample data is for internal testing only — not exposed in the UI
- When switching datasets,
_resetState()must be called at the top ofparseModel()andloadSampleData()to clear diagram containers, lineage selects, stale warning banners, and the static M-parser cache