Repository navigation
Figures
Since 0.2.0 a media item can be a drawn figure instead of a file: {"figure": {...}, "alt": "..."}. ask.py draws it as SVG and sends it to the page as an image (a data: URL, which the page's Content Security Policy already allows), so no file is written and nothing is fetched. There are three types: graph, forces and shapes. Figures work in any set, but they were made for quizzes (Study mode): a distance-time graph, a free body diagram, a fraction bar.
Each figure sits on a white card with rounded corners, so it reads the same in a dark theme. graph and forces are 480 by 300; shapes takes its own width and height (480 by 300 when left out). Give every figure an alt saying what it shows; without one lint warns.
ask.py figure <spec.json> <out.svg> draws a spec to a file. The file may hold the figure object itself or a whole media item with a figure key. Each picture below is the SVG this command wrote from the 0.2.0 release zip.
x_label, y_label and lines (each with a label and at least two [x, y] points), plus optional x_max, y_max (by default the largest value), grid (default on), dashed per line and marks (labelled points). Lines differ by colour and dash; give a curve as many points.
{
"type": "graph", "x_label": "Time (s)", "y_label": "Distance (m)", "x_max": 10, "y_max": 50, "grid": true,
"lines": [
{"label": "Walker", "points": [[0, 0], [10, 20]]},
{"label": "Cyclist", "points": [[0, 0], [4, 40], [10, 40]], "dashed": true,
"marks": [{"x": 4, "y": 40, "label": "stops"}]}
]
}$ python ask.py figure graph.json graph.svg
{
"ok": true,
"path": "/work/proj/graph.svg"
}
$ echo $?
0A box (object names it) with an arrow per force. dir is right, left, up or down, and newtons must be above 0. The arrow is labelled with label, or with the newtons ("50 N") when there is no label, and is blue unless the force has a color. Several forces in one direction sit side by side.
{
"type": "forces", "object": "crate",
"forces": [
{"dir": "right", "newtons": 30, "label": "push 30 N"},
{"dir": "left", "newtons": 30, "label": "friction 30 N"},
{"dir": "up", "newtons": 50, "label": "normal 50 N"},
{"dir": "down", "newtons": 50}
]
}$ python ask.py figure forces.json forces.svg
{
"ok": true,
"path": "/work/proj/forces.svg"
}
$ echo $?
0Arrow lengths compare only along one axis. Each arrow is scaled to the largest force in the figure, but a sideways arrow has more room than an upright one. Here the 30 N arrows are drawn about as long as the 50 N ones. When the sizes matter to the question, put the newtons in the label, as this example does.
items, each with a shape and its numbers: rect (x, y, w, h), circle (x, y, r), line and arrow (x1, y1, x2, y2) and text (x, y, text). Any item can take a label, a color (the stroke, near black by default) and a fill (none by default). Text is centred on x and sits a little above y; a rectangle's label goes in its middle.
{
"type": "shapes", "width": 240, "height": 110,
"items": [
{"shape": "rect", "x": 20, "y": 20, "w": 50, "h": 50, "fill": "#9cc3e6"},
{"shape": "rect", "x": 70, "y": 20, "w": 50, "h": 50, "fill": "#9cc3e6"},
{"shape": "rect", "x": 120, "y": 20, "w": 50, "h": 50, "fill": "#9cc3e6"},
{"shape": "rect", "x": 170, "y": 20, "w": 50, "h": 50},
{"shape": "text", "x": 120, "y": 95, "text": "3/4 shaded"}
]
}$ python ask.py figure shapes.json shapes.svg
{
"ok": true,
"path": "/work/proj/shapes.svg"
}
$ echo $?
0figure prints what is wrong and writes nothing. In a set, the same messages are lint errors under the rule figure (Lint rules and errors).
$ python ask.py figure f.json f.svg # f.json is {"type": "pie"}
{
"ok": false,
"errors": [
"figure type must be graph, forces or shapes"
]
}
$ echo $?
1
$ python ask.py figure f.json f.svg # f.json is {"type": "forces"}
{
"ok": false,
"errors": [
"a forces figure needs forces: [{dir: right|left|up|down, newtons: n}]"
]
}
$ echo $?
1
$ python ask.py figure f.json f.svg # f.json is {"type": "shapes", "width": 100, "height": 50}
{
"ok": false,
"errors": [
"a shapes figure needs items: [{shape: rect|circle|line|arrow|text, ...}]"
]
}
$ echo $?
1The other messages, from the source: "a graph needs lines: [{label, points: [[x, y], ...]}]", "every graph line needs points: at least two [x, y] number pairs", "x_max must be a number above 0" (or y_max), "every force needs dir (right, left, up or down) and newtons above 0", and, for a shape item missing a number, "shape items need shape (...) and numbers for x, y, w, h (rect), r (circle) or x1, y1, x2, y2 (line, arrow)".
This wiki describes askwright 0.2.0 and was last updated on 2026-10-25. The skill is MIT licensed. Report problems in the issues. Download: askwright 0.2.0.
Using it
- Getting started
- Commands
- Question set format
- Lint rules and errors
- Server and security
- Study mode
- Figures
- Recipes
- FAQ
The releases
Contributing
Elsewhere