Skip to content

Commit d9553d6

Browse files
rustyconoverclaude
andcommitted
docs: header logo, hero centering, pattern icons, lead line breaks, fence fix
- Header logo: stop clipping to a circle — show the full wordmark at its natural aspect ratio (remove border-radius/object-fit:cover; height 1.8rem, width auto). - Home: center "Built by 🚜 Query.Farm"; add the SVG cardinality glyphs as a "Shape" column in the Function patterns table. - Lead lines: put "What this is" and "Who it's for" on separate lines (trailing <br>) across every tutorial/how-to/concept page; update the contributing-docs standard + template to match. - Fix broken filter-pushdown/http-auth rendering: pymdownx.superfences mishandles the `test="skip"` info string and leaked the fence delimiters into the page. Switch illustrative blocks to plain ```python with a render-safe `# illustrative` sentinel; the doc-example harness skips on that marker instead. Documented the gotcha in contributing-docs. Strict build green; fence leaks 0 across pages; 67 doc/e2e assertions pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent d8e8a0e commit d9553d6

14 files changed

Lines changed: 61 additions & 39 deletions

‎docs/concepts/index.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ description: "How VGI works: the worker process model, transports, the Apache Ar
55
# Concepts
66

77
**What this is:** the mental model behind VGI — enough to design workers correctly and debug them
8-
confidently. **Who it's for:** developers who want the "why," not just the "how." None of this is
8+
confidently.<br>
9+
**Who it's for:** developers who want the "why," not just the "how." None of this is
910
required to ship your first worker; do the [tutorial](../tutorial/index.md) for that.
1011

1112
## The worker process model

‎docs/contributing-docs.md‎

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ description: "Conventions for writing vgi-python documentation: the per-page ori
44

55
# Writing docs
66

7-
**What this is:** the conventions every vgi-python documentation page follows. **Who it's for:**
8-
anyone adding or editing docs. Following these keeps the site easy to orient in and keeps examples
9-
from rotting.
7+
**What this is:** the conventions every vgi-python documentation page follows.<br>
8+
**Who it's for:** anyone adding or editing docs. Following these keeps the site easy to orient in
9+
and keeps examples from rotting.
1010

1111
## Diátaxis: pick the right mode
1212

@@ -23,8 +23,9 @@ Every page belongs to exactly one of four modes. If a page is doing two jobs, sp
2323

2424
Every tutorial, how-to, and concept page **must** contain, in order:
2525

26-
1. **A lead "what + who" line** — one sentence stating what the page is and who it's for, so a
27-
reader self-orients in under 10 seconds. (See the top of this page.)
26+
1. **A lead "what + who" block** — one sentence on what the page is, then **on its own line**
27+
(use a trailing `<br>`) one phrase on who it's for, so a reader self-orients in under 10 seconds.
28+
(See the top of this page.)
2829
2. **Prerequisites** — assumed knowledge, prior steps, and required extras (e.g.
2930
`pip install vgi-python[http]`), with links. Use a list or an admonition.
3031
3. **At least one complete, runnable example** — no `...` elisions in the primary example. It must
@@ -52,7 +53,9 @@ Every tutorial, how-to, and concept page **must** contain, in order:
5253
broken example fails the build.
5354
- **Mark illustrative-only blocks.** If a block genuinely can't run standalone (SQL, shell, a
5455
partial snippet), use a non-`python` fence or the ` ```python test="lint" ` / ` test="skip" `
55-
setting so the harness lints but doesn't execute it.
56+
setting so the harness lints but doesn't execute it. **Do not put blank lines inside a
57+
`test="skip"` block** — the renderer doesn't own that info string, so a blank line splits the
58+
fence and leaks the delimiters into the page. Keep skip snippets blank-line-free.
5659
- **Progressive disclosure for newcomers.** Put background that experts can skip inside a
5760
collapsible admonition (`??? info "New to X?"`).
5861
@@ -67,7 +70,8 @@ description: "One-line summary used for SEO and search."
6770
6871
# Page title
6972
70-
**What this is:** one sentence. **Who it's for:** one phrase.
73+
**What this is:** one sentence.<br>
74+
**Who it's for:** one phrase.
7175
7276
## Prerequisites
7377

‎docs/how-to/catalogs.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ description: "How to expose a VGI worker as a DuckDB catalog: schemas, function
55
# Expose a catalog
66

77
**What this is:** how a worker presents itself to DuckDB as a catalog — a named namespace of
8-
schemas, functions, tables, and views you reach with `ATTACH`. **Who it's for:** developers who've
9-
finished the [tutorial](../tutorial/index.md) and want to understand how their functions get
10-
qualified names, or who want to expose data (not just functions).
8+
schemas, functions, tables, and views you reach with `ATTACH`.<br>
9+
**Who it's for:** developers who've finished the [tutorial](../tutorial/index.md) and want to
10+
understand how their functions get qualified names, or who want to expose data (not just functions).
1111

1212
## Prerequisites
1313

‎docs/how-to/function-patterns.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ description: "How to write each of the four VGI function patterns: scalar, table
55
# Function patterns
66

77
**What this is:** a recipe showing each of the five VGI function patterns, with a complete,
8-
runnable worker for each. **Who it's for:** developers who've finished the
8+
runnable worker for each.<br>
9+
**Who it's for:** developers who've finished the
910
[tutorial](../tutorial/index.md) and want to know which pattern fits their problem.
1011

1112
## Prerequisites

‎docs/how-to/http-auth.md‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ description: "How to serve a VGI worker over HTTP and authenticate callers with
55
# Serve over HTTP with authentication
66

77
**What this is:** how to run a worker over **HTTP** instead of a subprocess, and gate it with
8-
authentication. **Who it's for:** developers deploying a worker as a network service. **Requires:**
9-
`pip install vgi-python[http]` (and `[oauth]` for JWT).
8+
authentication.<br>
9+
**Who it's for:** developers deploying a worker as a network service.<br>
10+
**Requires:** `pip install vgi-python[http]` (and `[oauth]` for JWT).
1011

1112
## Prerequisites
1213

@@ -26,7 +27,8 @@ DuckDB still attaches the worker over HTTP the usual way (`ATTACH ... (TYPE vgi,
2627
rather than from SQL — for tests, scripts, or another service. It connects with `transport="http"`
2728
instead of spawning a subprocess, and exposes the same call methods:
2829

29-
```python test="skip"
30+
```python
31+
# illustrative — calling the worker from Python over HTTP
3032
from vgi.client import Client
3133

3234
with Client(transport="http", base_url="http://localhost:8080", bearer_token="token1") as client:
@@ -47,7 +49,8 @@ Unauthenticated requests get HTTP 401. Authenticated requests carry the principa
4749
signature and the framework injects a per-call `CallContext` (auth, logging, transport info) — you
4850
don't pass it from SQL.
4951

50-
```python test="skip"
52+
```python
53+
# illustrative — reading the injected ctx in a function
5154
class Secret(ScalarFunction):
5255
@classmethod
5356
def compute(cls, value, *, ctx) -> ...:

‎docs/how-to/index.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ description: "Task-oriented recipes for building VGI workers: function patterns,
44

55
# How-to guides
66

7-
**What this is:** focused, task-oriented recipes for getting a specific thing done. **Who it's
8-
for:** developers who've finished the [tutorial](../tutorial/index.md) and want to build something
9-
real. Each guide assumes you can already write and run a basic worker.
7+
**What this is:** focused, task-oriented recipes for getting a specific thing done.<br>
8+
**Who it's for:** developers who've finished the [tutorial](../tutorial/index.md) and want to build
9+
something real. Each guide assumes you can already write and run a basic worker.
1010

1111
## Recipes
1212

‎docs/how-to/pushdown-and-statistics.md‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: "How to integrate VGI table functions with DuckDB's optimizer: acce
55
# Integrate with the optimizer
66

77
**What this is:** how to make table functions cooperate with DuckDB's query optimizer — receiving
8-
pushed-down `WHERE` predicates and reporting column statistics so the planner can skip work.
8+
pushed-down `WHERE` predicates and reporting column statistics so the planner can skip work.<br>
99
**Who it's for:** developers whose table functions back real data sources and want less data moved.
1010

1111
## Prerequisites
@@ -21,15 +21,16 @@ framework deserializes the predicates for you and exposes them on `params.curren
2121
as a `PushdownFilters` tree (or `None` when no filter applies), refreshed before each `process`
2222
call:
2323

24-
```python test="skip"
24+
```python
25+
# illustrative — sketch using your own types
2526
class Events(TableFunctionGenerator[EventsArgs]):
2627
class Meta:
2728
filter_pushdown = True # opt in to receiving WHERE predicates
2829

2930
@classmethod
3031
def process(cls, params, state, out):
3132
filters = params.current_pushdown_filters # PushdownFilters tree, or None
32-
# apply `filters` while generating rows, then out.emit(...) / out.finish()
33+
# apply the filters while generating rows, then out.emit(...) / out.finish()
3334
```
3435

3536
`PushdownFilters` is already decoded — you don't call `deserialize_filters` yourself (that helper is
@@ -43,7 +44,8 @@ When a table reports per-column min/max, null, and distinct-count statistics, Du
4344
can eliminate scans and order joins better. The declarative path is a `statistics` entry on the
4445
`Table` descriptor:
4546

46-
```python test="skip"
47+
```python
48+
# illustrative — `schema` and the table stand in for your own catalog
4749
from vgi.catalog import Table
4850
from vgi.catalog.descriptors import ColumnStatisticsInput
4951

‎docs/how-to/state-storage.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ description: "How to give VGI functions shared, persistent state across worker p
55
# Persist state across workers
66

77
**What this is:** how functions that span **multiple worker processes** (notably distributed
8-
aggregates) share and persist state. **Who it's for:** developers building aggregates or any
8+
aggregates) share and persist state.<br>
9+
**Who it's for:** developers building aggregates or any
910
function that coordinates partial results across workers.
1011

1112
## Prerequisites

‎docs/index.md‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ Write a function, `uv run` the script, query it from SQL. Other languages work t
1414
<img src="assets/logo.png" alt="VGI logo" width="360">
1515
</p>
1616

17+
<p align="center" markdown>
1718
Built by [🚜 Query.Farm](https://query.farm).
19+
</p>
1820

1921
## See it in action
2022

@@ -85,13 +87,13 @@ custom ETL transforms, expose external data sources as queryable tables and view
8587

8688
## Function patterns
8789

88-
| Type | Base class | SQL pattern | Use case |
90+
| Shape | Type | Base class | Use case |
8991
|---|---|---|---|
90-
| **Scalar** | `ScalarFunction` | `SELECT func(col) FROM t` | Per-row transforms (1:1) |
91-
| **Table** | `TableFunctionGenerator` | `SELECT * FROM func(args)` | Generate data |
92-
| **Table-in-out** | `TableInOutFunction` | `SELECT * FROM func((SELECT ...))` | Streaming transforms, filtering |
93-
| **Aggregate** | `AggregateFunction` | `SELECT func(col) ... GROUP BY` | Grouped accumulation |
94-
| **Buffering** | `TableBufferingFunction` | `SELECT * FROM func((SELECT ...))` | Sees every row first (sort, top-k) |
92+
| ![scalar shape](assets/kinds/scalar.svg){ height="32" } | **Scalar** | `ScalarFunction` | Per-row transforms (1:1) |
93+
| ![table shape](assets/kinds/table.svg){ height="32" } | **Table** | `TableFunctionGenerator` | Generate data |
94+
| ![table-in-out shape](assets/kinds/table-in-out.svg){ height="32" } | **Table-in-out** | `TableInOutFunction` | Streaming transforms, filtering |
95+
| ![aggregate shape](assets/kinds/aggregate.svg){ height="32" } | **Aggregate** | `AggregateFunction` | Grouped accumulation |
96+
| ![buffering shape](assets/kinds/buffering.svg){ height="32" } | **Buffering** | `TableBufferingFunction` | Sees every row first (sort, top-k) |
9597

9698
See the [API Reference](api/index.md) for the full surface, or jump into the guides below.
9799

‎docs/stylesheets/extra.css‎

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -234,13 +234,11 @@
234234
transform: scale(1.05);
235235
}
236236

237-
/* Header logo — bigger than default, clipped to circle */
237+
/* Header logo — slightly bigger than default, full logo at its natural aspect ratio */
238238
.md-header__button.md-logo img,
239239
.md-nav__button.md-logo img {
240-
height: 3rem;
241-
width: 3rem;
242-
border-radius: 50%;
243-
object-fit: cover;
240+
height: 1.8rem;
241+
width: auto;
244242
}
245243

246244
/* ── D2 diagrams — constrain size and center ── */

0 commit comments

Comments
 (0)