Skip to content

Commit 83fdf44

Browse files
authored
Merge pull request #1116 from LPCIC/refman
Add Sphinx reference manual
2 parents f19534a + 87db879 commit 83fdf44

40 files changed

Lines changed: 8650 additions & 432 deletions

‎.github/workflows/doc.yml‎

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,40 @@ jobs:
3434
opam repo add coq-dev https://coq.inria.fr/opam/core-dev
3535
opam repo add extra-dev https://coq.inria.fr/opam/extra-dev
3636
opam update
37-
opam install rocq-core.9.0.0 vsrocq-language-server coq-core rocq-stdlib.9.0.0 coq-stdlib
37+
opam install rocq-core.9.2.0 vsrocq-language-server coq-core rocq-stdlib.9.2.0 coq-stdlib
3838
opam install ./rocq-elpi.opam
3939
sudo apt-get update
4040
sudo apt-get install python3-pip -y
41+
sudo pip3 install Sphinx sphinx-rtd-theme
4142
42-
- name: build doc
43+
- name: build alectryon tutorials
4344
run: opam exec -- make doc
4445

46+
- name: build sphinx reference manual
47+
run: opam exec -- make refman-build
48+
49+
# Combined GH Pages layout: the older Alectryon-rendered tutorials keep
50+
# their existing root-level paths
51+
# (https://lpcic.github.io/coq-elpi/tutorial_*.html -- already linked
52+
# from both README.md and the new manual's own tutorial pages, via
53+
# ".. seealso::" notes), and the new Sphinx reference manual (the one
54+
# linked as "the reference manual" from README.md) is added alongside
55+
# under refman/.
56+
- name: combine docs for deployment
57+
run: |
58+
mkdir -p site
59+
cp -r doc/. site/
60+
mkdir -p site/refman
61+
cp -r docs/build/. site/refman/
62+
4563
- name: Save artifact
4664
uses: actions/upload-artifact@v4
4765
with:
48-
path: doc
66+
path: site
4967

5068
- name: deploy
5169
uses: JamesIves/github-pages-deploy-action@4.1.4
5270
if: ${{ github.ref == 'refs/heads/master' }}
5371
with:
5472
branch: gh-pages
55-
folder: doc
73+
folder: site

‎.gitignore‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ src/rocq_elpi_vernacular_syntax.ml
3232
src/rocq_elpi_arg_syntax.ml
3333
src/rocq_elpi_builtins_HOAS.ml
3434
doc/
35+
docs/source/
36+
docs/build/
37+
docsenv/
38+
docs/base/__pycache__/
3539

3640
Makefile.coq
3741
Makefile.coq.conf

‎.vscode/settings.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,5 @@
3333
"ocaml.server.args": [
3434
"--fallback-read-dot-merlin"
3535
],
36+
"vscode-as-git-mergetool.settingsAssistantOnStartup": false,
3637
}

‎Makefile‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,25 @@ doc:
8888
$(tut) &&) true
8989
@cp etc/tracer.png doc/
9090

91+
# Sphinx-based reference manual (docs/base -> docs/source -> docs/build).
92+
# `.. rocqtop::` blocks in docs/base/**/*.rst run through a real `rocq top`
93+
# with rocq-elpi loaded, so rocq-elpi must be installed into the opam switch
94+
# `rocq top` resolves against (not just dune-built-in-place), and
95+
# builtin-doc/*.elpi must exist on disk (read by docs/base/_roles_elpi.py).
96+
refman-build:
97+
$(call dune,build) -p rocq-elpi @install
98+
$(call dune,build) builtin-doc
99+
$(call dune,install) rocq-elpi
100+
rm -rf docs/source docs/build
101+
cp -r docs/base docs/source
102+
sed -i "s/@@VERSION@@/$$(git describe --always)/" docs/source/conf.py
103+
sphinx-build -q -W -b html docs/source docs/build
104+
.PHONY: refman-build
105+
106+
refman-serve: refman-build
107+
cd docs/build && python3 -m http.server 8000
108+
.PHONY: refman-serve
109+
91110
clean:
92111
$(call dune,clean)
93112
.PHONY: clean

‎README.md‎

Lines changed: 10 additions & 405 deletions
Large diffs are not rendered by default.

‎builtin-doc/elpi-builtin.elpi‎

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ X s>= Y :- ge_ X Y.
242242

243243
% -- Standard data types (supported in the FFI) --
244244

245-
kind list type -> type.
245+
data list A.
246246

247247
builtin symb (::) : X -> list X -> list X = "core".
248248

@@ -266,8 +266,8 @@ func snd pair A B -> B.
266266
snd (pr _ B) B.
267267

268268

269-
kind triple type -> type -> type -> type.
270-
type triple A -> B -> C -> triple A B C.
269+
data triple A B C.
270+
symb triple A -> B -> C -> triple A B C.
271271

272272
func triple_1 triple A B C -> A.
273273
triple_1 (triple A _ _) A.
@@ -1077,8 +1077,8 @@ builtin func std.loc.set.partition std.loc.set,
10771077
(func loc) -> std.loc.set, std.loc.set.
10781078

10791079
#line 1 "builtin_map.elpi"
1080-
kind std.map type -> type -> type.
1081-
type std.map std.map.private.map K V -> (func K, K -> cmp) -> std.map K V.
1080+
data std.map K V.
1081+
symb std.map std.map.private.map K V -> (func K, K -> cmp) -> std.map K V.
10821082

10831083
namespace std.map {
10841084

@@ -1105,9 +1105,9 @@ bindings (std.map M _) L :- private.bindings M [] L.
11051105
namespace private {
11061106

11071107
% Taken from OCaml's map.ml
1108-
kind map type -> type -> type.
1109-
type empty map K V.
1110-
type node map K V -> K -> V -> map K V -> int -> map K V.
1108+
data map K V.
1109+
symb empty map K V.
1110+
symb node map K V -> K -> V -> map K V -> int -> map K V.
11111111

11121112
func height map K V -> int.
11131113
height empty 0.
@@ -1193,8 +1193,8 @@ bindings (node L V D R _) X X1 :-
11931193

11941194
% Fast maps only work ground terms but do not perform occur check
11951195

1196-
kind std.fmap type -> type -> type.
1197-
type std.fmap std.fmap.private.map K V -> (func K, K -> cmp) -> std.fmap K V.
1196+
data std.fmap K V.
1197+
symb std.fmap std.fmap.private.map K V -> (func K, K -> cmp) -> std.fmap K V.
11981198

11991199
namespace std.fmap {
12001200

@@ -1233,9 +1233,9 @@ func assert-ground A.
12331233
assert-ground A :- std.assert! (ground_term A) "std.fmap: not ground".
12341234

12351235
% Taken from OCaml's map.ml
1236-
kind map type -> type -> type.
1237-
type empty map K V.
1238-
type node map K V -> K -> V -> map K V -> int -> map K V.
1236+
data map K V.
1237+
symb empty map K V.
1238+
symb node map K V -> K -> V -> map K V -> int -> map K V.
12391239

12401240
func height map K V -> int.
12411241
height empty 0.
@@ -1321,8 +1321,8 @@ bindings (node L V D R _) X X1 :-
13211321

13221322

13231323
#line 1 "builtin_set.elpi"
1324-
kind std.set type -> type.
1325-
type std.set std.set.private.set E -> (func E, E -> cmp) -> std.set E.
1324+
data std.set E.
1325+
symb std.set std.set.private.set E -> (func E, E -> cmp) -> std.set E.
13261326

13271327
namespace std.set {
13281328

@@ -1352,9 +1352,9 @@ elements (std.set M _) L :- private.elements M [] L.
13521352
namespace private {
13531353

13541354
% Taken from OCaml's set.ml
1355-
kind set type -> type.
1356-
type empty set E.
1357-
type node set E -> E -> set E -> int -> set E.
1355+
data set E.
1356+
symb empty set E.
1357+
symb node set E -> E -> set E -> int -> set E.
13581358

13591359
func height set E -> int.
13601360
height empty 0.
@@ -1443,8 +1443,8 @@ elements (node L E R _) Acc X :-
14431443

14441444
% Fast sets only work ground terms but do not perform occur check
14451445

1446-
kind std.fset type -> type.
1447-
type std.fset std.fset.private.set E -> (func E, E -> cmp) -> std.fset E.
1446+
data std.fset E.
1447+
symb std.fset std.fset.private.set E -> (func E, E -> cmp) -> std.fset E.
14481448

14491449
namespace std.fset {
14501450

@@ -1483,9 +1483,9 @@ func assert-ground A.
14831483
assert-ground A :- std.assert! (ground_term A) "std.fset: not ground".
14841484

14851485
% Taken from OCaml's set.ml
1486-
kind set type -> type.
1487-
type empty set E.
1488-
type node set E -> E -> set E -> int -> set E.
1486+
data set E.
1487+
symb empty set E.
1488+
symb node set E -> E -> set E -> int -> set E.
14891489

14901490
func height set E -> int.
14911491
height empty 0.

‎docs/README.md‎

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Rocq-Elpi reference manual
2+
3+
This directory holds the Sphinx-based reference manual published at
4+
<https://lpcic.github.io/coq-elpi/refman/>.
5+
6+
## Source layout
7+
8+
Only `docs/base/` is tracked by git; everything else under `docs/` is
9+
generated and gitignored.
10+
11+
- `docs/base/conf.py` — Sphinx configuration: registers the custom
12+
lexers/roles/directive below, sets the theme (`sphinx_rtd_theme`), etc.
13+
- `docs/base/_pygments_elpi.py` — a Pygments lexer for Elpi, and for Rocq
14+
with embedded `lp:{{ ... }}` Elpi quotations, used both for
15+
`.. code-block::`/`:e:`-style highlighting and by `_rocqtop_elpi.py` below.
16+
- `docs/base/_roles_elpi.py` — custom roles (`:builtin:`, `:stdlib:`,
17+
`:type:`, `:lib:`, ...) that link a predicate/type/macro name to its
18+
declaration in `builtin-doc/*.elpi` or `elpi/*.elpi`, resolved locally via
19+
`git log` (no network access at build time).
20+
- `docs/base/_rocqtop_elpi.py` — the `.. rocqtop::` directive: spawns a real
21+
`rocq top` process and feeds it the block's Rocq/Elpi sentences one at a
22+
time, rendering the sentence together with its *actually captured* output.
23+
This is what every tutorial/example page uses for its code samples instead
24+
of static transcripts, so a sample that no longer compiles breaks the
25+
build rather than silently going stale.
26+
- `docs/base/index.rst`, `getting-started.rst`, `apps.rst`,
27+
`tutorials/`, `reference/`, `examples/` — the manual's actual content.
28+
- `docs/base/_static/custom.css` — small CSS additions on top of the theme
29+
(ANSI colors for `.. rocqtop::` output, Elpi-specific token colors, ...).
30+
31+
## Building
32+
33+
```
34+
make refman-build
35+
```
36+
37+
(from the repository root) does, in order:
38+
39+
1. `dune build -p rocq-elpi @install` — builds the `.install` files
40+
`dune install` (next step) needs; without it, `dune install` fails with
41+
`<package>.install are missing` unless some earlier, unrelated full
42+
`dune build` happened to already produce them.
43+
2. `dune build builtin-doc` — `_roles_elpi.py` reads `builtin-doc/*.elpi`
44+
straight off disk, so it must exist and be up to date.
45+
3. `dune install rocq-elpi` — installs Rocq-Elpi into the current opam
46+
switch. This is required (not just building it in place) because
47+
`.. rocqtop::` spawns a real `rocq top` that loads `From elpi Require
48+
Import elpi.` the same way an end user's opam switch would.
49+
4. Copies `docs/base/` to `docs/source/` (gitignored), substituting
50+
`@@VERSION@@` in `conf.py` with `git describe --always`.
51+
5. Runs `sphinx-build -q -W -b html docs/source docs/build`. `-W` turns
52+
every warning into a hard build failure — a broken `:builtin:`/`:doc:`
53+
reference, a `.. rocqtop::` sentence that errors out, or a dangling
54+
toctree entry all fail the build rather than degrading quietly.
55+
56+
`docs/source/` and `docs/build/` are both deleted and recreated on every
57+
run; never edit files there by hand.
58+
59+
Requirements beyond the repository's usual opam/dune setup: `Sphinx` and
60+
`sphinx-rtd-theme` (`pip install Sphinx sphinx-rtd-theme`), installed into
61+
whichever Python `sphinx-build` resolves to on `$PATH`.
62+
63+
To build and preview locally:
64+
65+
```
66+
make refman-serve # builds, then serves docs/build/ on http://localhost:8000
67+
```
68+
69+
## Deployment
70+
71+
`.github/workflows/doc.yml` runs on every push/PR to `master`. On `master`
72+
it builds **two** things and deploys them together to the `gh-pages` branch
73+
(published at <https://lpcic.github.io/coq-elpi/>):
74+
75+
- `make doc` — the older per-tutorial pages rendered with
76+
[Alectryon](https://github.com/cpitclaudel/alectryon) from
77+
`examples/tutorial_*.v`, output to `doc/`. These keep their original,
78+
already-linked-elsewhere paths, e.g.
79+
`https://lpcic.github.io/coq-elpi/tutorial_elpi_lang.html` — every new
80+
manual tutorial page links back to its Alectryon-rendered original via a
81+
`.. seealso::` note, so these paths must not move.
82+
- `make refman-build` — this Sphinx manual, output to `docs/build/`, copied
83+
into the deployed site under `refman/`, i.e.
84+
`https://lpcic.github.io/coq-elpi/refman/`.
85+
86+
The workflow's `combine docs for deployment` step lays both out under one
87+
`site/` directory (`doc/*` at the root, `docs/build/*` under `site/refman/`)
88+
before handing it to `JamesIves/github-pages-deploy-action`, which force-pushes
89+
`site/` as the full contents of the `gh-pages` branch.

0 commit comments

Comments
 (0)