Skip to content

Commit dfdd270

Browse files
isPANNGiggleLiuclaude
authored
Refactor the website around a Typst-backed reduction graph (#1156)
* Refactor the reduction website with a shared Typst-backed graph explorer * Use version tags for documentation workflow actions * Move open problems link to end of navigation * Refine Atlas layout and typography and align graph search styling * Rename Open problems to Open questions * Seed the website graph layout generator fCoSE draws its initial positions from Math.random and has no seed option, so every build shuffled the published node positions. Install a fixed mulberry32 stream in the Node generator and assert that two runs are byte-identical. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Keep graph shortcuts out of text fields The global keydown handler only exempted #graph-search, so typing "/" in the list search moved focus and split the query, and Escape in any field cleared the whole selection. Mirror the typing guard from site.js; Escape inside a field now clears that field through its own input handler and blurs it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Keep keyboard focus when the graph list re-renders renderBrowser replaces every button, so Enter on a list item dropped focus to <body>. When focus was inside the list, move it to the re-rendered counterpart of the focused item; canvas and mouse-free selections leave focus alone. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Share the paper-data prerequisite across doc targets build_website.py compiles docs/paper/reductions.typ, which reads the generated docs/paper/data/examples.json, but only `make website` exported it, so `make doc` and `make mdbook` failed on a clean checkout. Move the export into a paper-data target that website, doc, mdbook and paper all depend on, and let mdbook copy the API docs before the website builder finalizes them, as doc already does. The README names mdBook 0.5.2 as the deployment version. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Redirect retired mdBook pages and fix the design link design.md still linked the deleted open-problems.md, and the published reduction-graph.html and open-problems.html had no successor. Link the Open questions tab and add mdBook redirects to graph.html and index.html#open-questions; the meta refresh works under the site CSP. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Describe the graph divider range at startup aria-valuemax was only written by the first resize, so the separator exposed an incomplete range until then. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Report missing graph data through the init error path window.REDUCTIONS was read before the try block, so a failed graph-data.js left the workspace inert with no message. The preamble moves inside the try (whitespace-only re-indent) and a missing payload raises a readable error. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Load Typst footnotes and keep the article when they fail Typst 0.15 puts role=doc-noteref on the <sup>, not the link, so the footnote lookup never matched and footnotes were never shown. Match the link inside the noteref, and report a failed footnotes fetch in the footnote block instead of replacing the rendered article. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Keep website source-link metadata in documentation export --------- Co-authored-by: GiggleLiu <cacate0129@gmail.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
1 parent 286a7ac commit dfdd270

36 files changed

Lines changed: 3232 additions & 1261 deletions

‎.github/workflows/docs.yml‎

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ on:
77

88
permissions:
99
contents: read
10-
pages: write
11-
id-token: write
1210

1311
concurrency:
1412
group: "pages"
@@ -30,12 +28,16 @@ jobs:
3028
- name: Install mdBook
3129
run: |
3230
mkdir -p "$HOME/bin"
33-
curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.37/mdbook-v0.4.37-x86_64-unknown-linux-gnu.tar.gz | tar -xz -C "$HOME/bin"
31+
curl -fLsS https://github.com/rust-lang/mdBook/releases/download/v0.5.2/mdbook-v0.5.2-x86_64-unknown-linux-gnu.tar.gz -o mdbook.tar.gz
32+
echo '084e4342ba564db270108763e404a7d1f309d932651a22484e93c0dc1a071f6d mdbook.tar.gz' | sha256sum --check
33+
tar -xzf mdbook.tar.gz -C "$HOME/bin"
3434
echo "$HOME/bin" >> $GITHUB_PATH
3535
3636
- name: Install Typst
3737
run: |
38-
curl -sSL https://github.com/typst/typst/releases/download/v0.14.0/typst-x86_64-unknown-linux-musl.tar.xz | tar -xJ
38+
curl -fLsS https://github.com/typst/typst/releases/download/v0.15.1/typst-x86_64-unknown-linux-musl.tar.xz -o typst.tar.xz
39+
echo 'a6d077d0a95eed5a2eba715b2dae06be954f624ccbf85758a03f389ded33118c typst.tar.xz' | sha256sum --check
40+
tar -xJf typst.tar.xz
3941
mv typst-x86_64-unknown-linux-musl/typst "$HOME/bin/"
4042
4143
- name: Install Node dependencies
@@ -54,9 +56,6 @@ jobs:
5456
- name: Build mdBook
5557
run: mdbook build
5658

57-
- name: Build research website
58-
run: python3 scripts/build_website.py
59-
6059
- name: Build PDF
6160
run: typst compile --root . docs/paper/reductions.typ book/reductions.pdf
6261

@@ -68,21 +67,38 @@ jobs:
6867
mkdir -p book/api
6968
cp -r target/doc/* book/api/
7069
71-
- name: Setup Pages
72-
uses: actions/configure-pages@v4
70+
- name: Build research website
71+
run: python3 scripts/build_website.py
72+
73+
- name: Verify deployment artifact
74+
run: |
75+
python3 -m pip install playwright==1.58.0
76+
python3 -m playwright install --with-deps chromium
77+
npm audit --audit-level=moderate
78+
npm run test:reduction-graph-js
79+
python3 -m unittest discover -s scripts -p 'test_website_build.py'
80+
python3 -m http.server 3001 --bind 127.0.0.1 --directory book &
81+
server_pid=$!
82+
trap 'kill "$server_pid"' EXIT
83+
python3 scripts/test_website.py
7384
7485
- name: Upload artifact
7586
uses: actions/upload-pages-artifact@v3
7687
with:
7788
path: './book'
7889

7990
deploy:
91+
permissions:
92+
pages: write
93+
id-token: write
8094
environment:
8195
name: github-pages
8296
url: ${{ steps.deployment.outputs.page_url }}
8397
runs-on: ubuntu-latest
8498
needs: build
8599
steps:
100+
- name: Setup Pages
101+
uses: actions/configure-pages@v4
86102
- name: Deploy to GitHub Pages
87103
id: deployment
88104
uses: actions/deploy-pages@v4

‎Makefile‎

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Makefile for problemreductions
22

3-
.PHONY: help build test bench mcp-test fmt clippy doc mdbook website paper clean coverage rust-export compare qubo-testdata export-schemas release run-plan run-issue run-pipeline run-pipeline-forever run-review run-review-forever board-next board-claim board-ack board-move issue-context issue-guards pr-context pr-wait-ci worktree-issue worktree-pr diagrams jl-testdata cli cli-demo copilot-review papers papers-lookup papers-download papers-scihub papers-status papers-push papers-pull papers-index
3+
.PHONY: help build test bench mcp-test fmt clippy doc mdbook website paper paper-data clean coverage rust-export compare qubo-testdata export-schemas release run-plan run-issue run-pipeline run-pipeline-forever run-review run-review-forever board-next board-claim board-ack board-move issue-context issue-guards pr-context pr-wait-ci worktree-issue worktree-pr diagrams jl-testdata cli cli-demo copilot-review papers papers-lookup papers-download papers-scihub papers-status papers-push papers-pull papers-index
44

55
RUNNER ?= codex
66
CLAUDE_MODEL ?= opus
@@ -94,22 +94,28 @@ clippy:
9494
node_modules/elkjs/package.json: package.json package-lock.json
9595
npm ci
9696

97+
# Example data read by docs/paper/reductions.typ, which the PDF and the website details compile.
98+
paper-data:
99+
cargo run --features "$(TEST_FEATURES)" --example export_examples
100+
cargo run --features "$(TEST_FEATURES)" --example export_petersen_mapping
101+
97102
# Build mdBook documentation
98-
doc: node_modules/elkjs/package.json
103+
doc: node_modules/elkjs/package.json paper-data
99104
cargo run --example export_graph
100105
node scripts/generate_reduction_graph_layout.js
101106
cargo run --example export_schemas
102107
cargo build -p problemreductions-cli --bin pred
103108
bash scripts/generate_doc_snippets.sh target/debug/pred
104109
mdbook build
105-
python3 scripts/build_website.py
106110
RUSTDOCFLAGS="--default-theme=dark" cargo doc --no-deps
107111
rm -rf book/api
108112
cp -r target/doc book/api
113+
python3 scripts/build_website.py
109114

110115
# Build the product website with fresh atlas data; API/PDF builds remain in doc/paper.
111-
website:
116+
website: node_modules/elkjs/package.json paper-data
112117
cargo run --example export_graph
118+
node scripts/generate_reduction_graph_layout.js
113119
cargo run --example export_schemas
114120
cargo build -p problemreductions-cli --bin pred
115121
bash scripts/generate_doc_snippets.sh target/debug/pred
@@ -128,7 +134,7 @@ diagrams:
128134
done
129135

130136
# Build and serve mdBook with API docs
131-
mdbook: node_modules/elkjs/package.json
137+
mdbook: node_modules/elkjs/package.json paper-data
132138
@echo "Exporting graph..."
133139
@cargo run --example export_graph 2>&1 | tail -1
134140
@echo "Generating graph layout..."
@@ -142,9 +148,9 @@ mdbook: node_modules/elkjs/package.json
142148
@RUSTDOCFLAGS="--default-theme=dark" cargo doc --no-deps 2>&1 | tail -1
143149
@echo "Building mdBook..."
144150
@mdbook build
145-
@python3 scripts/build_website.py
146151
rm -rf book/api
147152
cp -r target/doc book/api
153+
@python3 scripts/build_website.py
148154
@-lsof -ti:3001 | xargs kill 2>/dev/null || true
149155
@echo "Serving at http://localhost:3001"
150156
python3 -m http.server 3001 -d book &
@@ -156,9 +162,7 @@ export-schemas:
156162
cargo run --example export_schemas
157163

158164
# Build Typst paper (generates example data on demand)
159-
paper:
160-
cargo run --features "$(TEST_FEATURES)" --example export_examples
161-
cargo run --features "$(TEST_FEATURES)" --example export_petersen_mapping
165+
paper: paper-data
162166
cargo run --features "$(TEST_FEATURES)" --example export_graph
163167
cargo run --features "$(TEST_FEATURES)" --example export_schemas
164168
typst compile --root . docs/paper/reductions.typ docs/paper/reductions.pdf

‎book.toml‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ src = "docs/src"
99
default-theme = "navy"
1010
git-repository-url = "https://github.com/CodingThrust/problem-reductions"
1111
edit-url-template = "https://github.com/CodingThrust/problem-reductions/edit/main/{path}"
12-
additional-css = ["docs/src/static/docs-theme.css", "docs/src/static/theme-images.css", "docs/src/static/reduction-graph.css"]
13-
additional-js = ["docs/src/static/docs-theme.js", "docs/src/static/cytoscape.min.js", "docs/src/static/reduction-graph.js"]
12+
additional-css = ["docs/src/static/docs-theme.css", "docs/src/static/theme-images.css"]
13+
additional-js = ["docs/src/static/docs-theme.js"]
1414
no-section-label = true
1515

1616
[output.html.fold]
@@ -32,3 +32,8 @@ boost-paragraph = 1
3232
expand = true
3333
heading-split-level = 3
3434
copy-js = true
35+
36+
# Pages that moved to the website keep their published URLs.
37+
[output.html.redirect]
38+
"/reduction-graph.html" = "graph.html"
39+
"/open-problems.html" = "index.html#open-questions"

‎docs/paper/reductions.typ‎

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#import "@preview/cetz:0.4.2": canvas, draw
5252
#import "@preview/ctheorems:1.1.3": thmbox, thmplain, thmproof, thmrules
5353
#import "lib.typ": g-node, g-edge, petersen-graph, house-graph, octahedral-graph, draw-grid-graph, draw-triangular-graph, graph-colors, selem, sregion, draw-node-highlight, draw-edge-highlight, draw-node-colors, sregion-selected, sregion-dimmed, gate-and, gate-or, gate-xor
54+
#import "web.typ": export-details, detail-key, detail-article
5455

5556
#set page(
5657
paper: "a4",
@@ -64,6 +65,36 @@
6465

6566
// Set up theorem environments with ctheorems
6667
#show: thmrules.with(qed-symbol: $square$)
68+
#show math.equation: it => context {
69+
if export-details and target() == "html" {
70+
html.elem(if it.block { "div" } else { "span" }, attrs: (class: "typst-math"), html.frame(it))
71+
} else { it }
72+
}
73+
#show figure: it => context {
74+
if export-details and target() == "html" {
75+
html.elem("figure")[
76+
#html.frame(it.body)
77+
#if it.caption != none { html.elem("figcaption", it.caption.body) }
78+
]
79+
} else { it }
80+
}
81+
#show block: it => context {
82+
if export-details and target() == "html" {
83+
if it.height != auto { html.frame(it) } else { html.elem("div", it.body) }
84+
} else { it }
85+
}
86+
#show align: it => context {
87+
if export-details and target() == "html" { it.body } else { it }
88+
}
89+
#show pad: it => context {
90+
if export-details and target() == "html" { it.body } else { it }
91+
}
92+
#show grid: it => context {
93+
if export-details and target() == "html" { html.frame(it) } else { it }
94+
}
95+
#show stack: it => context {
96+
if export-details and target() == "html" { html.frame(it) } else { it }
97+
}
6798

6899
// === Example JSON helpers ===
69100
// Load the generated canonical example database.
@@ -501,6 +532,7 @@
501532

502533
// Render a block of pred CLI commands for reproducibility
503534
#let pred-commands(..cmds) = {
535+
if export-details { return raw(cmds.pos().join("\n"), block: true) }
504536
block(
505537
width: 100%,
506538
fill: luma(245),
@@ -531,8 +563,22 @@
531563
)
532564

533565
// Problem definition wrapper: auto-adds schema, complexity, reductions list, and label
534-
#let problem-def(name, def, body) = {
535-
let lbl = label("def:" + name)
566+
#show ref: it => context {
567+
let name = str(it.target)
568+
if export-details and target() == "html" and name.starts-with("def:") {
569+
link(it.target, display-name.at(name.slice(4)))
570+
} else { it }
571+
}
572+
#let problem-def(name, def, body, variant: none) = {
573+
if export-details {
574+
return detail-article("problem:" + detail-key(name, variant))[
575+
#html.elem("h3")[Definition]
576+
#def
577+
#html.elem("h3")[Background and example]
578+
#body
579+
]
580+
}
581+
let lbl = label("def:" + detail-key(name, variant))
536582
let title = display-name.at(name)
537583
[#definition(title)[
538584
#def
@@ -586,8 +632,23 @@
586632
example-target-variant: none,
587633
example-caption: none,
588634
extra: none,
635+
source-variant: none,
636+
target-variant: none,
589637
theorem-body, proof-body,
590638
) = {
639+
if export-details {
640+
return detail-article("rule:" + detail-key(source, source-variant) + "->" + detail-key(target, target-variant))[
641+
#html.elem("h3")[Reduction]
642+
#theorem-body
643+
#html.elem("h3")[Proof]
644+
#proof-body
645+
#if example {
646+
html.elem("h3")[Example]
647+
if example-caption != none { strong(example-caption) }
648+
extra
649+
}
650+
]
651+
}
591652
let arrow = sym.arrow.r
592653
let edge = find-edge(source, target)
593654
let src-disp = if edge != none { variant-display(graph-data.nodes.at(edge.source)) }
@@ -597,7 +658,7 @@
597658
let src-lbl = label("def:" + source)
598659
let tgt-lbl = label("def:" + target)
599660
let parameters = if edge != none and edge.parameters.len() > 0 { edge.parameters } else { none }
600-
let thm-lbl = label("thm:" + source + "-to-" + target)
661+
let thm-lbl = label("thm:" + detail-key(source, source-variant) + "-to-" + detail-key(target, target-variant))
601662
covered-rules.update(old => old + ((source, target),))
602663

603664
[
@@ -19589,4 +19650,8 @@ The following table shows concrete target-variable counts for example instances,
1958919650
]
1959019651

1959119652
#pagebreak()
19592-
#bibliography("references.bib", style: "ieee")
19653+
#if export-details {
19654+
detail-article("references")[#bibliography("references.bib", style: "ieee")]
19655+
} else {
19656+
bibliography("references.bib", style: "ieee")
19657+
}

‎docs/paper/web.typ‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Web presentation only; all definitions, proofs, and examples stay in reductions.typ.
2+
#let export-details = sys.inputs.at("details", default: "false") == "true"
3+
4+
#let detail-key(name, variant) = {
5+
if variant == none { return name }
6+
name + "/" + variant.keys().sorted().map(key => key + "=" + str(variant.at(key))).join(",")
7+
}
8+
9+
#let detail-article(key, body) = {
10+
let anchor = key.replace("problem:", "def:").replace("rule:", "thm:").replace("->", "-to-")
11+
[#html.elem("article", attrs: ("data-detail-key": key), body)#label(anchor)]
12+
}

‎docs/src/SUMMARY.md‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
- [Quick start](cli.md)
88
- [Command reference](cli-commands.md)
9-
- [Reduction graph](reduction-graph.md)
109

1110
# Agents
1211

@@ -17,7 +16,3 @@
1716
- [Getting started](getting-started.md)
1817
- [API reference](api.md)
1918
- [Design](design.md)
20-
21-
# Research
22-
23-
- [Open problems](open-problems.md)

‎docs/src/design.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,4 +437,4 @@ let restored: MaximumIndependentSet<SimpleGraph, i64> = from_json(&json)?;
437437

438438
## Contributing
439439

440-
See [Call for Contributions](./open-problems.md) for the recommended issue-based workflow (no coding required).
440+
See [Call for Contributions](index.html#open-questions) for the recommended issue-based workflow (no coding required).

‎docs/src/open-problems.md‎

Lines changed: 0 additions & 3 deletions
This file was deleted.

‎docs/src/reduction-graph.md‎

Lines changed: 0 additions & 35 deletions
This file was deleted.

‎docs/src/static/cytoscape.min.js‎

Lines changed: 0 additions & 31 deletions
This file was deleted.

0 commit comments

Comments
 (0)