Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
2c52460
feat: add Release top-level menu entry in en and zh
wenchy Jun 11, 2026
5751ee8
feat: add Release section landing _index.md for en and zh
wenchy Jun 11, 2026
b9ad799
feat: pin release section permalink to /release/:slug/
wenchy Jun 11, 2026
e737e03
feat: add release sidebar partial
wenchy Jun 11, 2026
b0b3052
feat: add release single-page layout with iframe and markdown branches
wenchy Jun 11, 2026
ed41ba1
feat: add release section list layout
wenchy Jun 11, 2026
a2b59e3
feat: add release section SCSS
wenchy Jun 11, 2026
7c0a801
feat: add v0.1.0 sample markdown release in en and zh
wenchy Jun 11, 2026
95b7289
feat: add v0.2.0 sample HTML-stub release with iframe artifact
wenchy Jun 11, 2026
aad4784
fix: revert release permalink rule (use filename slug not :slug from …
wenchy Jun 11, 2026
c109784
fix: place Release as the last item in the main top nav
wenchy Jun 11, 2026
0995fc2
feat: add v0.16.0 release report (HTML stub + artifact)
wenchy Jun 11, 2026
7dfd4fd
fix(release): full-width iframe layout, drop sidebar, add fullscreen …
wenchy Jun 11, 2026
c9048ee
fix(dev): enable poll watcher + force-sync static for live reload of …
wenchy Jun 11, 2026
8f4c9ad
refactor(release): blog-style card list, drop sidebar from list and m…
wenchy Jun 11, 2026
200beef
refactor(release): match blog card styling exactly (same partial, sam…
wenchy Jun 11, 2026
4ecbe27
fix(release): align breadcrumb with action icons; hide lead on iframe…
wenchy Jun 11, 2026
8b0f25e
fix(release): match iframe page width to parent container (top-menu w…
wenchy Jun 11, 2026
55b323c
feat(release): make Tableau logo+text in v0.16.0 report a home link
wenchy Jun 11, 2026
33f4bbe
fix(release): compute reading time from HTML artifact for iframe stubs
wenchy Jun 11, 2026
513a8e1
feat(release): add v0.15.0 release notes (en + zh) from upstream GitH…
wenchy Jun 11, 2026
0e78bd3
fix(release): drop -webkit-full-screen vendor selector to satisfy sty…
wenchy Jun 11, 2026
a931fed
docs: rewrite README to be concise and aligned with current project s…
wenchy Jun 11, 2026
4c3ab5b
chore: enforce LF line endings via .gitattributes
wenchy Jun 11, 2026
d51a1c4
docs: trim README intro and refine v0.16.0 stub front-matter; add CLA…
wenchy Jun 11, 2026
a57fe33
chore: remove content/zh/release/v0-1-0.md
wenchy Jun 11, 2026
a273a47
ci: add lint + build workflow for branches and PRs
wenchy Jun 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Force LF line endings for text files, in both the repository and the
# working tree. Keeps CI (Linux) and local checkouts consistent on every
# platform regardless of each contributor's `core.autocrlf` setting.
* text=auto eol=lf

# Treat these as binary so Git never tries to normalize them.
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.webp binary
*.woff binary
*.woff2 binary
*.ttf binary
*.eot binary
*.pdf binary
*.zip binary
*.gz binary
*.mp4 binary
*.webm binary
*.mp3 binary

# SVGs are XML text — keep them text but pinned to LF.
*.svg text eol=lf
40 changes: 40 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Validate lint and build on every push and pull request.
# Mirrors what the GitHub Pages deploy job does, minus the publish step.
name: CI

on:
push:
branches: [master, main]
pull_request:
branches: [master, main]

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
test:
name: Lint & build
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 24
cache: 'npm'

- name: Install dependencies
run: npm install

- name: Lint scripts (eslint)
run: npm run lint:scripts

- name: Lint styles (stylelint)
run: npm run lint:styles

- name: Lint markdown
run: npm run lint:markdown

- name: Build production site
run: npm run build
68 changes: 68 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## What this repo is

The documentation/marketing site for [Tableau](https://github.com/tableauio/tableau) (a configuration converter that turns Excel/CSV/XML/YAML into JSON/Text/Bin), published at https://tableauio.github.io. It is a [Hugo](https://gohugo.io/) site built on the [Doks](https://getdoks.org) theme using Doks' "child-theme" pattern: the upstream theme is consumed via `node_modules/@hyas/doks` and is mounted into Hugo through `[module.mounts]` in `config/_default/config.toml`. Files under `layouts/`, `assets/`, `static/`, `data/`, etc. in this repo override (or extend) the same paths from the upstream theme — see the mount list at the bottom of that config to understand precedence.

Hugo itself is downloaded by `npm install` (via `hugo-installer`) into `node_modules/.bin/hugo/hugo`; the `otherDependencies.hugo` field in `package.json` pins the version. There is no global Hugo dependency — always invoke through npm scripts.

## Common commands

```bash
npm install # also installs Hugo into node_modules/.bin/hugo
npm run start # dev server on 0.0.0.0:1313 with --disableFastRender
npm run build # production build (--gc --minify) into ./public
npm run build:preview # build with drafts and future content (-D -F)
npm run clean # rm -rf public resources

npm run lint # all linters (scripts + styles + markdown)
npm run lint:scripts # eslint over assets/js, config, functions
npm run lint:styles # stylelint over assets/scss/**
npm run lint:markdown # markdownlint-cli2 over *.md and content/**/*.md
npm run lint:markdown-fix
```

`npm run lint:markdown` is the gating check on CI — see `.github/workflows/deploy-github.yml`. Run it before committing markdown changes; the rule config lives in `.markdownlint-cli2.jsonc` (notably MD013/MD024/MD026/MD033/MD034 are disabled).

There is no test framework — `npm test` is aliased to `npm run -s lint`.

## Architecture / things worth knowing before editing

### Multilingual content layout

Two languages are configured in `config/_default/languages.toml`: `en` (default, `content/en/`) and `zh` (`content/zh/`). Every doc page that should exist in both languages must have a counterpart at the same relative path under each `content/<lang>/` tree. Menus are split per-language in `config/_default/menus/menus.<lang>.toml`.

### Config layering

Hugo merges `config/_default/` with `config/<environment>/`. `production/` is used by `npm run build`; `next/` is used by Netlify's `context.next` (sets `HUGO_ENV=next`). When changing site-wide settings, the default goes in `_default/` and only deltas go in the env-specific dirs.

### Site params and version pins

`config/_default/params.toml` holds SEO metadata, feature toggles (`[options]` block — `kaTex`, `flexSearch`, `darkMode`, `spreadsheetJS`, …), and two version values that show up on the rendered site:

- `tableaucVersion` — surfaced via the `{{< tableauc-version >}}` shortcode and used in download links. Bump this when a new `tableauc` release should be the default download.
- `docsVersion` (commented out) and the version groups in `data/docs-versions.yml` drive the docs version selector when `docsVersioning` is enabled.

### Custom shortcodes (in `layouts/shortcodes/`)

These are project-specific extensions on top of Doks; review them before changing markdown that uses them:

- `sheet.html` + `spreadsheet.html` — render Excel-like tabbed tables. `spreadsheet` splits its `.Inner` on the literal HTML marker `<p hidden>--break-me-here--</p>` (emitted by `sheet`) to separate sheets, then renders each as a Bootstrap tab. The corresponding download/render JS is `assets/js/spreadsheet.js`, gated by `params.options.spreadsheetJS`.
- `tableauc-version.html` — emits `site.Params.tableaucVersion`.
- `alert`, `details`, `email`, `mermaid`, `video` — thin wrappers; check before assuming Hugo defaults.

### Asset pipeline

SCSS lives in `assets/scss/` (entry `app.scss`); JS in `assets/js/` (entry `index.js`, with feature modules like `darkmode.js`, `spreadsheet.js`, `mermaid.js`, `katex.js` loaded conditionally based on `[options]` in params.toml). Vendor libs (`flexsearch`, `katex`, `mermaid`) are mounted from `node_modules` into `assets/js/vendor/` by Hugo module mounts — do not vendor them manually.

### Output formats

`config.toml` defines custom output formats `REDIRECTS` and `HEADERS` that produce Netlify's `_redirects` and `_headers` from `layouts/index.redirects` and `layouts/index.headers`, plus a `SITEMAP` format for per-section `sitemap.xml`. The home page emits all four in addition to HTML/RSS.

### Deployment

**GitHub Pages** (see `.github/workflows/deploy-github.yml`) — on push to `master`, runs `npm install`, `npm run lint:markdown`, `npm run build`, then publishes `./public` via `peaceiris/actions-gh-pages@v3`. CI pins Node 24.

Treat upstream Doks files (delivered via `node_modules/@hyas/doks`) as read-only; override by creating same-path files in this repo's `layouts/`, `assets/`, etc.
60 changes: 37 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,48 @@
# tableauio.github.io
This website is based on [Doks](https://getdoks.org). And we choose [child-theme](https://getdoks.org/docs/prologue/quick-start/#child-theme).

## Install Requirements
The documentation and marketing site for [Tableau](https://github.com/tableauio/tableau) — a configuration converter that turns Excel / CSV / XML / YAML into JSON / Text / Bin.

- Install **nodejs**: https://nodejs.org/en/download/.
- macOS: `brew install nodejs`
## Requirements

## Quick Start
- **Node.js** ≥ 24 ([download](https://nodejs.org/en/download/))
- macOS: `brew install node`
- Hugo is installed automatically by `npm install` (pinned via `otherDependencies.hugo` in `package.json`). No global Hugo needed.

Change to this repo's working directory:
## Quick start

- Install dependencies: `npm install`
- Start development server: `npm run start`
```bash
npm install # also installs Hugo into node_modules/.bin/hugo
npm run start # dev server on http://localhost:1313 with live reload
npm run build # production build into ./public
npm run lint # all linters (scripts + styles + markdown)
```

## Lint Markdown
CI runs `npm run lint:markdown` and `npm run build` on every push to `master`. Run `npm run lint` locally before opening a PR.

> Please lint the markdown format before commit.
## Adding content

- Run: `npm run lint:markdown`
Content lives under `content/<lang>/<section>/`, with parallel `en/` and `zh/` trees:

## Upgrade Doks
| Section | Path | Notes |
|---|---|---|
| Docs | `content/<lang>/docs/` | Sidebar-driven, Doks-style docs. |
| Blog | `content/<lang>/blog/` | Card list at `/blog/`. |
| Release | `content/<lang>/release/` | Card list at `/release/`. Add `iframe: "/release/<file>.html"` in front-matter to embed a standalone HTML report from `static/release/`. |

1. Get new repo: `git clone https://github.com/h-enk/doks.git my-doks-site`
2. Install dependencies: `npm install`
3. Replace with our repo's files:
- README.md
- .github/
- content/
- config/_default/
- i18/
- layout/index.html
4. Run: `npm start`
5. Push to GitHub: `git push https://github.com/tableauio/tableauio.github.io master:master -f`
Front-matter follows the Doks convention (`title`, `description`, `lead`, `date`, `weight`, `toc`, …). For releases, `weight` controls sidebar order — newer releases use higher numeric weights so they sort above older ones.

## Deployment

Pushing to `master` triggers `.github/workflows/deploy-github.yml`, which lints, builds, and publishes `./public` to GitHub Pages via [`peaceiris/actions-gh-pages`](https://github.com/peaceiris/actions-gh-pages). CI pins Node 24.

## Project layout

```
config/_default/ # site config, menus, params, languages
content/{en,zh}/ # multilingual content
layouts/ # template overrides on top of @hyas/doks
assets/scss/ # styles (entry: app.scss)
assets/js/ # scripts (entry: index.js)
static/ # files served as-is at the URL root
.github/workflows/ # CI: lint + build + GitHub Pages deploy
```
1 change: 1 addition & 0 deletions assets/scss/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
@import "components/forms";
@import "components/images";
@import "components/mermaid";
@import "components/release";
@import "components/search";
@import "components/tables";
@import "components/sheet";
Expand Down
112 changes: 112 additions & 0 deletions assets/scss/components/_release.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/* Release section */

/* Iframe page wrapper. Width matches the top-menu container (`.container-xxl`),
inheriting the parent layout. No edge-to-edge breakout. */
.release-iframe-page {
width: 100%;
margin: 0;
padding: 0;
box-sizing: border-box;
}

.release-iframe-header {
padding: 0.5rem 0.25rem;
margin-bottom: 0.5rem;
border-bottom: 1px solid var(--bs-border-color, #dee2e6);
min-height: 2.5rem;
line-height: 1.5;
}

.release-iframe-header .breadcrumb {
background: transparent;
padding: 0;
margin: 0;
display: flex;
align-items: center;
flex-wrap: wrap;
line-height: 1.5;
}

.release-iframe-header nav[aria-label="breadcrumb"] {
margin: 0;
display: flex;
align-items: center;
}

.release-iframe-actions .release-iframe-action {
color: var(--bs-secondary-color, #495057);
padding: 0.25rem 0.5rem;
border-radius: 0.25rem;
text-decoration: none;
display: inline-flex;
align-items: center;
justify-content: center;
line-height: 1;
}

.release-iframe-actions .release-iframe-action:hover,
.release-iframe-actions .release-iframe-action:focus {
color: var(--bs-primary, #0d6efd);
background: var(--bs-secondary-bg, rgba(13, 110, 253, 0.08));
}

.release-iframe-lead {
margin: 0 0 0.5rem;
}

/* Iframe wrap: tall, edge-to-edge inside the page. */
.release-iframe-wrap {
position: relative;
width: 100%;
height: calc(100vh - 160px);
min-height: 520px;
margin-top: 0.5rem;
border: 1px solid var(--bs-border-color, #dee2e6);
border-radius: 0.25rem;
overflow: hidden;
background: #fff;
}

.release-iframe-wrap iframe {
width: 100%;
height: 100%;
border: 0;
display: block;
}

/* Browser native fullscreen: occupy whole screen with no padding. */
.release-iframe-wrap:fullscreen {
width: 100vw;
height: 100vh;
border: 0;
border-radius: 0;
margin: 0;
background: #fff;
}

.release-iframe-wrap:fullscreen iframe {
width: 100vw;
height: 100vh;
}

/* Active sidebar item: subtle highlight using the existing docs-sidebar look. */
.release-sidebar-item.active > a {
font-weight: 600;
color: var(--bs-primary, #0d6efd);
}

/* HTML badge in sidebar and list. */
.release-html-badge {
font-size: 0.65rem;
padding: 0.15rem 0.4rem;
background: var(--bs-secondary-bg, #e9ecef);
color: var(--bs-secondary-color, #495057);
border-radius: 0.25rem;
text-transform: uppercase;
letter-spacing: 0.04em;
}

/* Optional caption block above an iframe (when stub body is non-empty). */
.release-prelude {
margin-bottom: 1rem;
}
12 changes: 8 additions & 4 deletions assets/scss/layouts/_posts.scss
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
.home .card,
.contributors.list .card,
.blog.list .card {
.blog.list .card,
.release.list .card {
margin-top: 2rem;
margin-bottom: 2rem;
transition: transform 0.3s;
}

.home .card:hover,
.contributors.list .card:hover,
.blog.list .card:hover {
.blog.list .card:hover,
.release.list .card:hover {
transform: scale(1.025);
}

.home .card-body,
.contributors.list .card-body,
.blog.list .card-body {
.blog.list .card-body,
.release.list .card-body {
padding: 0 2rem 1rem;
}

.blog-header {
.blog-header,
.release-header {
text-align: center;
margin-bottom: 2rem;
}
Expand Down
5 changes: 5 additions & 0 deletions config/_default/menus/menus.en.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
url = "/blog/"
weight = 30

[[main]]
name = "Release"
url = "/release/"
weight = 40

[[social]]
name = "GitHub"
pre = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"feather feather-github\"><path d=\"M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22\"></path></svg>"
Expand Down
5 changes: 5 additions & 0 deletions config/_default/menus/menus.zh.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
url = "/blog/"
weight = 20

[[main]]
name = "发布"
url = "/release/"
weight = 30

[[social]]
name = "GitHub"
pre = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"feather feather-github\"><path d=\"M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22\"></path></svg>"
Expand Down
9 changes: 9 additions & 0 deletions content/en/release/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: "Release"
description: "Release notes and reports for Tableau."
date: 2026-06-11T00:00:00+08:00
lastmod: 2026-06-11T00:00:00+08:00
draft: false
images: []
weight: 9999
---
Loading
Loading