Skip to content

Commit 85d81ec

Browse files
committed
major revision; uses more routines in Entangled itself to read and manipulate markdown; include filter for repl-session
1 parent 00a2ace commit 85d81ec

16 files changed

Lines changed: 1302 additions & 296 deletions

File tree

.entangled/build/Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
# This Makefile is generated by Entangled. Modifications will be overwritten.
3+
4+
.PHONY = all
5+
6+
all:
7+
8+

.entangled/filedb.json

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,56 @@
11
{
2-
"version": "2.0.0-alpha-3",
32
"files": [
43
{
5-
"path": "README.md",
64
"deps": null,
7-
"modified": "2023-05-20T15:45:38.374816",
8-
"hexdigest": "dead468bea87407e2e6a7b229e76c812a231e0f6289eddf171ba8bd0534e364c"
5+
"hexdigest": "5a199ccde2b8e71f83105c9c8d8991a2330abc5cfc35ecaddc99202a0126f616",
6+
"modified": "2025-10-03T14:12:18.980572",
7+
"path": "docs/index.md",
8+
"size": 1444
99
},
1010
{
11-
"path": "docs/setup.md",
1211
"deps": null,
13-
"modified": "2023-05-21T19:42:18.759752",
14-
"hexdigest": "e56cec2fb11ac9540a06a92996e6b9ac6424c699dc1e6d6f33138f243a94d949"
12+
"hexdigest": "aca9aaefe77198c38904af9b3b10b40cec5f6ccdab88630ccf634e5d09d1cff3",
13+
"modified": "2025-10-03T14:11:22.118375",
14+
"path": "docs/setup.md",
15+
"size": 8610
1516
},
1617
{
17-
"path": "examples/hello_world.py",
1818
"deps": [
19-
"docs/index.md"
19+
"docs/setup.md"
2020
],
21-
"modified": "2023-05-20T15:50:49.652413",
22-
"hexdigest": "66e79b50c625e5edddbe3e1c1222b74ce0e5f776abc43ea6366816544219fc45"
21+
"hexdigest": "92862e6cb986fb6bed9b6c74cb54af86ccfd80d0e245af0569905ce005b3b92a",
22+
"modified": "2025-10-03T14:11:28.015952",
23+
"path": "examples/entangled.toml",
24+
"size": 382
2325
},
2426
{
25-
"path": "docs/index.md",
26-
"deps": null,
27-
"modified": "2023-05-20T22:25:25.108970",
28-
"hexdigest": "860d6dfc07cd8246a7fdb0c425eb6217677ef9006f84693c630b4faaf90bfcce"
29-
},
30-
{
31-
"path": "examples/plot.gp",
3227
"deps": [
3328
"docs/index.md"
3429
],
35-
"modified": "2023-05-20T22:13:50.926594",
36-
"hexdigest": "e0a44680408c7b2b7c4fec1551d0a6a835df6ecd0c1d68a758b43c2ef89ea29e"
30+
"hexdigest": "66e79b50c625e5edddbe3e1c1222b74ce0e5f776abc43ea6366816544219fc45",
31+
"modified": "2025-10-03T13:40:25.520753",
32+
"path": "examples/hello_world.py",
33+
"size": 189
34+
},
35+
{
36+
"deps": [],
37+
"hexdigest": "320ddf2659f09b1f60a03408016487064e8b3754fa96a4355ad6a7b9bbec553c",
38+
"modified": "2025-10-03T14:11:28.024507",
39+
"path": "examples/lua-session.json",
40+
"size": 545
41+
},
42+
{
43+
"deps": [],
44+
"hexdigest": "ca3da004e36b672abfbee4274ce33486ab6c7cd6585c3830dc55eb0582629a06",
45+
"modified": "2025-10-03T13:42:28.370463",
46+
"path": "test/lua-session.json",
47+
"size": 546
3748
}
3849
],
3950
"source": [],
4051
"target": [
41-
"examples/plot.gp",
52+
"examples/entangled.toml",
4253
"examples/hello_world.py"
43-
]
54+
],
55+
"version": "2.2.0"
4456
}

.github/workflows/python-package.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,3 @@ jobs:
3232
- name: Run typechecker
3333
run: |
3434
poetry run mypy
35-
- name: Test with pytest
36-
run: |
37-
poetry run pytest

docs/index.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,25 @@ plugins:
1313
- entangled # this also runs `entangled sync` as a pre-build action
1414

1515
markdown_extensions:
16+
- attr_list
1617
- pymdownx.superfences
1718
- pymdownx.tabbed:
18-
alternate_style: true
19+
alternate_style: true
1920
```
2021
2122
Also create `entangled.toml`, the `version` field is obligatory.
2223

2324
```toml
2425
version = "2.0"
2526
watch_list = ["docs/**/*.md"]
26-
hooks = ["build"]
27+
hooks = ["repl"]
2728
```
2829

2930
## Components
3031
This plugin bundles functionality for literate programming with Entangled.
3132

3233
- Annotate code blocks with titles.
34+
- Insert results from `repl-session`.
3335

3436
### Annotate code blocks
3537
The default markdown syntax that Entangled supports has fenced code blocks as follows

docs/setup.md

Lines changed: 94 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Setup instructions for MkDocs with Entangled
2-
If you'd like to use Entangled together with MkDocs, here's an opiniated guide (if you have differing opinions, you'll know howto adapt).
2+
If you'd like to use Entangled together with MkDocs, here's an opiniated guide.
33

44
## Python and MkDocs
55
Start with an empty project folder, say `my-awesome-project`.
@@ -10,18 +10,17 @@ cd my_awesome_project
1010
git init
1111
```
1212

13-
You may want to setup a virtual environment to install MkDocs into. Even if your project is not Python related, it pays to have a reproducible build environment for your documentation. I use [Poetry](https://python-poetry.org/) to manage my environments.
13+
You may want to setup a virtual environment to install MkDocs into. Even if your project is not Python related, it pays to have a reproducible build environment for your documentation. I use [`uv`](https://docs.astral.sh/uv/) to manage my environments.
1414

15-
```sh
16-
poetry init
17-
# <<follow the gentle instructions>>
18-
poetry add -D mkdocs mkdocs-material entangled-cli[rich] mkdocs-entangled-plugin
19-
poetry shell
15+
```bash
16+
uv init --bare
17+
uv add -D mkdocs mkdocs-material entangled-cli mkdocs-entangled-plugin
18+
uv sync
19+
source .venv/bin/activate
2020
```
2121

22-
Using virtual environments will take up some disk space. With these moderate requirements however, we're still under 200 MB.
23-
24-
Next we initialize, configure, and run MkDocs.
22+
Now you have created a virtual environment using UV and activated it (alas there is no `uv shell` command that I know of).
23+
Next we initialize, configure, and run MkDocs.
2524

2625
```sh
2726
mkdocs new .
@@ -38,13 +37,14 @@ plugins:
3837
- entangled
3938

4039
markdown_extensions:
40+
- attr_list
4141
- pymdownx.superfences
4242

4343
theme:
4444
name: material
4545
```
4646
47-
This sets the title, repo name and a toggle for dark mode viewing. the `entangled` plugin needs `pymdownx.superfences` to be enabled.
47+
This sets the title, repo name and a toggle for dark mode viewing. the `entangled` plugin expects the `attr_list` and `pymdownx.superfences` markdown extensions to be enabled.
4848
Make sure to check out [MkDocs Material](https://squidfunk.github.io/mkdocs-material/) for more documentation on configuring MkDocs with Material.
4949

5050
```sh
@@ -56,25 +56,21 @@ This will start a build loop and web server. That means that every time one of t
5656
## Setup Entangled
5757
Entangled will work without any additional configuration in `entangled.toml`. The default config monitors the entire source repository for Markdown files. Files that are extracted from the Markdown are also watched for changes. If you'd like to limit the scope of Markdown files that are monitored, you can set `watch_list` to a list of glob patterns. For MkDocs projects it makes sense to set `watch_list = [ "docs/**/*.md" ]`.
5858

59-
To enable building artifacts add the `build` hook, by setting `hooks = ["build"]`.
59+
We will also demo the `repl` hook for Entangled later on.
6060

6161
The complete configuration then looks like this:
6262

6363
``` {.toml file=examples/entangled.toml}
6464
version = "2.0"
6565
watch_list = ["docs/**/*.md"]
66-
hooks = ["build"]
67-
```
68-
69-
Entangled runs as a pre-build action in MkDocs. So, you may want to add your generated source files in the watch list of MkDocs. Assuming your source files are in `./src`:
66+
hooks = ["repl"]
7067
71-
```yaml
72-
watch:
73-
- docs
74-
- src
68+
<<repl-config>>
7569
```
7670

7771
## Extras
72+
Some extras.
73+
7874
### Syntax Highlighting
7975
Add the following to the `markdown_extensions` section in `mkdocs.yml`:
8076

@@ -88,6 +84,45 @@ markdown_extensions:
8884
pygments_lang_class: true
8985
```
9086

87+
### Evaluating a REPL session
88+
When you write documentation or teaching material it can be nice to automatically evaluate commands in a REPL and show the results in your rendered output. Entangled ships with a command-line tool `repl-session` that evaluates a series of commands in a configured REPL. Both input and output are JSON data.
89+
Entangled contains a hook that integrates with `repl-session`.
90+
91+
For each language you need to configure the REPL in `entangled.toml` in the `[hook.repl.config.<language>]` section. For example,
92+
93+
``` {toml #repl-config}
94+
[hook.repl.config.Lua]
95+
command = "lua"
96+
first_prompt = "> "
97+
change_prompt = '_PROMPT = "{key}> "; _PROMPT2 = "{key}+ "'
98+
prompt = "{key}> "
99+
continuation_prompt = "{key}\\+ "
100+
strip_ansi = true
101+
```
102+
103+
Each repl block must be attached to a session, which is the JSON file to which the session is written. It is the responsibility of the user to make sure, with whatever build system tool (say GNU Make or Brei), that the resulting JSON file is passed through `repl-session` to a file in the same directory with the `out.json` extension. This way, the REPL session will only be rerun when the session file changes.
104+
105+
Did you know that Lua supports tail-call elimination? We can define a factorial function,
106+
107+
``` {.lua .repl #lua-repl session=examples/lua-session.json}
108+
function fac(n, m)
109+
if m == nil then
110+
return fac(n, 1)
111+
end
112+
if n == 0 then
113+
return m
114+
else
115+
return fac(n-1, m*n)
116+
end
117+
end
118+
```
119+
120+
and this runs in constant stack space!
121+
122+
``` {.lua .repl #lua-repl}
123+
fac(63)
124+
```
125+
91126
### Equations using Mathjax
92127
A common requirement is to have support for equations. Add the following to your `mkdocs.yml`
93128

@@ -132,11 +167,11 @@ You can enable a dark-mode toggle by adding to your `mkdocs.yml`
132167
```yaml
133168
theme:
134169
name: material
135-
palette:
170+
palette:
136171
# Palette toggle for light mode
137172
- scheme: default
138173
toggle:
139-
icon: material/brightness-7
174+
icon: material/brightness-7
140175
name: Switch to dark mode
141176
142177
# Palette toggle for dark mode
@@ -151,60 +186,77 @@ You may want to use Github Actions to deploy the website. I use the following `.
151186

152187
<details><summary>Deploy Pages action</summary>
153188

189+
Note from two years later: Github Actions are extraordinarily fickle and require constant maintenance. Always make sure that you update to the newest versions. This version is from October 2025:
190+
154191
```yaml
155-
name: Deploy Pages
192+
name: Deploy pages
156193
157194
# Controls when the workflow will run
158195
on:
159196
# Triggers the workflow on push or pull request events but only for the "main" branch
160197
push:
161-
branches: [ "main" ]
198+
branches: ["main"]
162199
163200
# Allows you to run this workflow manually from the Actions tab
164201
workflow_dispatch:
165202
166-
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
167203
permissions:
168204
contents: read
169205
pages: write
170206
id-token: write
171207
208+
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
209+
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
210+
concurrency:
211+
group: "pages"
212+
cancel-in-progress: false
213+
214+
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
172215
jobs:
216+
# This workflow contains a single job called "build"
173217
build:
174-
environment:
175-
name: github-pages
176-
url: ${{ steps.deployment.outputs.page_url }}
177218
# The type of runner that the job will run on
178219
runs-on: ubuntu-latest
179220
180221
# Steps represent a sequence of tasks that will be executed as part of the job
181222
steps:
182223
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
183-
- uses: actions/checkout@v3
224+
- uses: actions/checkout@v4
225+
226+
- name: Install uv
227+
uses: astral-sh/setup-uv@v6
184228
185-
- name: Install
186-
run: |
187-
pip install poetry
188-
poetry install
229+
- name: Install dependencies
230+
run: uv sync
231+
232+
- name: Run MkDocs
233+
run: uv run mkdocs build
234+
235+
- name: Configure GitHub Pages
236+
uses: actions/configure-pages@v5
189237
190-
- name: Generate site
191-
run: poetry run mkdocs build
192-
193238
- name: Upload artifact
194-
uses: actions/upload-pages-artifact@v1
239+
uses: actions/upload-pages-artifact@v4
195240
with:
196-
path: 'site'
241+
path: "site"
197242
243+
deploy:
244+
environment:
245+
name: github-pages
246+
url: ${{ steps.deployment.outputs.page_url }}
247+
runs-on: ubuntu-latest
248+
needs: build
249+
steps:
198250
- name: Deploy to GitHub Pages
199251
id: deployment
200-
uses: actions/deploy-pages@v2
252+
uses: actions/deploy-pages@v4
201253
```
202254

203255
</details>
204256

205257
## Commit
206-
Don't forget to create a `README.md`, `LICENSE`, and later on a `CITATION.cff`. You may want to add `poetry.lock` to `.gitignore`.
207-
You should be good to go! A fresh Entangled/MkDocs project should have the following files:
258+
Don't forget to create a `README.md`, `LICENSE`, and later on a `CITATION.cff`.
259+
A fresh Entangled/MkDocs project should have the following files:
208260

209261
```
210262
.
@@ -225,7 +277,7 @@ Create a home for your new project and push.
225277
```sh
226278
git add .
227279
git commit -m 'initial commit'
228-
git remote add origin git@github.com:joeplummer/my-awesome-project.git
280+
git remote add origin git@github.com:johndoe/my-awesome-project.git
229281
git push -u origin main
230282
```
231283

entangled.toml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
11
version = "2.0"
22
watch_list = ["docs/**/*.md"]
3-
hooks = ["build"]
3+
hooks = ["build", "repl"]
4+
5+
[hook.repl.config.Lua]
6+
command = "lua"
7+
first_prompt = "> "
8+
change_prompt = '_PROMPT = "{key}> "; _PROMPT2 = "{key}+ "'
9+
prompt = "{key}> "
10+
continuation_prompt = "{key}\\+ "
11+
strip_ansi = true

examples/entangled.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# ~/~ begin <<docs/setup.md#examples/entangled.toml>>[init]
2+
version = "2.0"
3+
watch_list = ["docs/**/*.md"]
4+
hooks = ["repl"]
5+
6+
# ~/~ begin <<docs/setup.md#repl-config>>[init]
7+
[hook.repl.config.Lua]
8+
command = "lua"
9+
first_prompt = "> "
10+
change_prompt = '_PROMPT = "{key}> "; _PROMPT2 = "{key}+ "'
11+
prompt = "{key}> "
12+
continuation_prompt = "{key}\\+ "
13+
strip_ansi = true
14+
# ~/~ end
15+
# ~/~ end

0 commit comments

Comments
 (0)