gum-jsx 1.2.4 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/README.md +6 -2
  2. package/docs/code/arrays.jsx +6 -0
  3. package/docs/code/axis.jsx +6 -0
  4. package/docs/code/barplot.jsx +6 -0
  5. package/docs/code/box.jsx +4 -0
  6. package/docs/code/colors.jsx +11 -0
  7. package/docs/code/context.jsx +7 -0
  8. package/docs/code/edge.jsx +6 -0
  9. package/docs/code/element.jsx +3 -0
  10. package/docs/code/ellipse.jsx +6 -0
  11. package/docs/code/graph.jsx +7 -0
  12. package/docs/code/grid.jsx +12 -0
  13. package/docs/code/group.jsx +5 -0
  14. package/docs/code/gum.jsx +4 -0
  15. package/docs/code/latex.jsx +5 -0
  16. package/docs/code/line.jsx +13 -0
  17. package/docs/code/math.jsx +6 -0
  18. package/docs/code/network.jsx +8 -0
  19. package/docs/code/node.jsx +6 -0
  20. package/docs/code/plot.jsx +5 -0
  21. package/docs/code/points.jsx +12 -0
  22. package/docs/code/rect.jsx +2 -0
  23. package/docs/code/shape.jsx +14 -0
  24. package/docs/code/slide.jsx +8 -0
  25. package/docs/code/spline.jsx +13 -0
  26. package/docs/code/stack.jsx +8 -0
  27. package/docs/code/symfield.jsx +4 -0
  28. package/docs/code/symfill.jsx +6 -0
  29. package/docs/code/symline.jsx +5 -0
  30. package/docs/code/sympoints.jsx +6 -0
  31. package/docs/code/symshape.jsx +9 -0
  32. package/docs/code/symspline.jsx +10 -0
  33. package/docs/code/text.jsx +4 -0
  34. package/docs/code/textbox.jsx +2 -0
  35. package/docs/code/titleframe.jsx +9 -0
  36. package/docs/code/triangle.jsx +7 -0
  37. package/docs/code/unitline.jsx +5 -0
  38. package/docs/gala/complex_plot.jsx +21 -0
  39. package/docs/gala/flux_capacitance.jsx +5 -0
  40. package/docs/gala/metal_grid.jsx +17 -0
  41. package/docs/gala/plot_manual.jsx +11 -0
  42. package/docs/gala/polygon_slide.jsx +30 -0
  43. package/docs/gala/punk_rock.jsx +7 -0
  44. package/docs/gala/set_theory.jsx +11 -0
  45. package/docs/gala/slick_bars.jsx +12 -0
  46. package/docs/gala/spline_star.jsx +20 -0
  47. package/docs/gala/the_nexus.jsx +14 -0
  48. package/docs/meta.json +50 -0
  49. package/docs/text/arrays.md +25 -0
  50. package/docs/text/axis.md +20 -0
  51. package/docs/text/barplot.md +17 -0
  52. package/docs/text/box.md +23 -0
  53. package/docs/text/colors.md +22 -0
  54. package/docs/text/context.md +17 -0
  55. package/docs/text/edge.md +16 -0
  56. package/docs/text/element.md +26 -0
  57. package/docs/text/ellipse.md +5 -0
  58. package/docs/text/graph.md +10 -0
  59. package/docs/text/grid.md +12 -0
  60. package/docs/text/group.md +14 -0
  61. package/docs/text/gum.md +15 -0
  62. package/docs/text/latex.md +9 -0
  63. package/docs/text/line.md +12 -0
  64. package/docs/text/math.md +28 -0
  65. package/docs/text/network.md +14 -0
  66. package/docs/text/node.md +15 -0
  67. package/docs/text/plot.md +23 -0
  68. package/docs/text/points.md +11 -0
  69. package/docs/text/rect.md +10 -0
  70. package/docs/text/shape.md +10 -0
  71. package/docs/text/slide.md +13 -0
  72. package/docs/text/spline.md +13 -0
  73. package/docs/text/stack.md +17 -0
  74. package/docs/text/symfill.md +12 -0
  75. package/docs/text/symline.md +15 -0
  76. package/docs/text/sympoints.md +15 -0
  77. package/docs/text/symshape.md +11 -0
  78. package/docs/text/symspline.md +13 -0
  79. package/docs/text/text.md +19 -0
  80. package/docs/text/textbox.md +8 -0
  81. package/docs/text/titleframe.md +14 -0
  82. package/docs/text/triangle.md +5 -0
  83. package/docs/text/unitline.md +10 -0
  84. package/index.d.ts +54 -25
  85. package/package.json +37 -12
  86. package/prompt/docs.md +3 -0
  87. package/prompt/head.md +4 -0
  88. package/prompt/intro.md +101 -0
  89. package/prompt/refs.md +105 -0
  90. package/scripts/cli.js +48 -0
  91. package/{src → scripts}/server.js +3 -3
  92. package/src/defaults.js +2 -2
  93. package/src/eval.js +37 -3
  94. package/src/fonts.browser.js +16 -0
  95. package/src/fonts.js +32 -0
  96. package/src/fonts.node.js +17 -0
  97. package/src/gum.js +54 -75
  98. package/src/meta.js +47 -0
  99. package/src/render.js +54 -0
  100. package/src/term.js +71 -0
  101. package/src/text.js +5 -56
  102. package/src/utils.js +2 -2
  103. package/src/cli.js +0 -22
  104. package/src/error.js +0 -34
  105. package/src/katex.js +0 -99
  106. package/src/mark.js +0 -15
  107. package/src/node.js +0 -13
  108. package/src/symbols.js +0 -863
  109. package/src/test.js +0 -40
  110. /package/src/{acorn.js → parse.js} +0 -0
package/README.md CHANGED
@@ -23,7 +23,7 @@ npm install gum-jsx
23
23
  Write some `gum.jsx` code:
24
24
 
25
25
  ```jsx
26
- <Plot xlim={[0, 2*pi]} ylim={[-1, 1]} grid margin={0.2} aspect={2}>
26
+ <Plot xlim={[0, 2*pi]} ylim={[-1.5, 1.5]} grid margin={[0.2, 0.1]} aspect={2}>
27
27
  <SymLine fy={sin} stroke={blue} stroke-width={2} />
28
28
  </Plot>
29
29
  ```
@@ -36,13 +36,17 @@ const elem = evaluateGum(jsx)
36
36
  const svg = elem.svg()
37
37
  ```
38
38
 
39
+ Which will produce the following:
40
+
41
+ <img src="image/plot.svg" alt="sine wave plot" width="750" />
42
+
39
43
  You can also use JavaScript directly:
40
44
 
41
45
  ```javascript
42
46
  import { Svg, Box, Text, Circle, Plot, SymLine, pi, sin } from 'gum'
43
47
  const elem = new Plot({
44
48
  children: new SymLine({ fy: sin, stroke: blue, stroke_width: 2 }),
45
- xlim: [0, 2*pi], ylim: [-1, 1], grid: true, margin: 0.2, aspect: 2,
49
+ xlim: [0, 2*pi], ylim: [-1.5, 1.5], grid: true, margin: [0.2, 0.1], aspect: 2,
46
50
  })
47
51
  const svg = elem.svg()
48
52
  ```
@@ -0,0 +1,6 @@
1
+ // a scatter plot of points with emojis for: mount fuji, a rocket, a whale, a watermellon, and a donut
2
+ <Plot xlim={[0, 6]} ylim={[0, 6]} xticks={7} yticks={7} margin={0.15}>
3
+ { [ '🗻', '🚀', '🐋', '🍉', '🍩' ].map((e, i) =>
4
+ <Text pos={[i+1, i+1]} rad={0.4}>{e}</Text>
5
+ ) }
6
+ </Plot>
@@ -0,0 +1,6 @@
1
+ // a horizontal axis with 5 ticks labeled with emojis for: mount fuji, a rocket, a whale, a watermellon, and a donut
2
+ const emoji = ['🗻', '🚀', '🐳', '🍉', '🍩']
3
+ const ticks = zip(linspace(0, 1, emoji.length), emoji)
4
+ return <Box padding={[0.5, 1]}>
5
+ <HAxis aspect={10} ticks={ticks} tick-side="outer" label-size={1} />
6
+ </Box>
@@ -0,0 +1,6 @@
1
+ // A plot with three bars with black borders at "A", "B", and "C". The first bar is red and is the shortest, the second bar is blue and is the tallest, while the third bar is green and its height is in between.
2
+ <BarPlot ylim={[0, 10]} yticks={6} ygrid title="Example BarPlot" xlabel="Category" ylabel="Value" margin={0.25}>
3
+ <Bar label="A" size={3} fill={red} />
4
+ <Bar label="B" size={8.5} fill={blue} />
5
+ <Bar label="C" size={6.5} fill={green} />
6
+ </BarPlot>
@@ -0,0 +1,4 @@
1
+ // the text "hello!" in a frame with a dashed border and rounded corners
2
+ <Box padding border rounded border-stroke-dasharray={5}>
3
+ <Text>hello!</Text>
4
+ </Box>
@@ -0,0 +1,11 @@
1
+ // A plot of an inverted sine wave where the line markers are sized in proportion to the amplitude and the color ranges from blue to red depending on the phase. The x-axis ticks are labeled with multiples of π. The x-axis is labeled "phase" and the y-axis is labeled "amplitude". The title is "Inverted Sine Wave".
2
+ const func = x => -sin(x)
3
+ const pal = palette(blue, red, [-1, 1])
4
+ const size = (x, y) => 0.1 * (1+abs(y))/2
5
+ const shape = (x, y) => <Circle fill={pal(y)} />
6
+ const xticks = linspace(0, 2, 6).slice(1).map(x => [x*pi, `${rounder(x, 1)} π`])
7
+ return <Plot xlim={[0, 2*pi]} ylim={[-1, 1]} aspect={1.5} xanchor={0} xaxis-tick-side="both" xticks={xticks} grid xlabel="phase" ylabel="amplitude" title="Inverted Sine Wave" margin={0.25}>
8
+ <SymLine fy={func} />
9
+ <SymPoints fy={func} size={size} shape={shape} N={21}>
10
+ </SymPoints>
11
+ </Plot>
@@ -0,0 +1,7 @@
1
+ // create a square context of radius 50 centered at 100 and map [0.3, 0.5] to pixel coordinates
2
+ const prect = [ 50, 50, 150, 150 ]
3
+ const ctx = <Context prect={prect} />
4
+ const [fx, fy] = [0.3, 0.5]
5
+ const [px, py] = ctx.mapPoint([fx, fy])
6
+ const text = `[${fx}, ${fy}] → [${px}, ${py}]`
7
+ return <Text>{text}</Text>
@@ -0,0 +1,6 @@
1
+ // Two boxes with text in them that have black borders and gray interiors. The box in the upper left says "hello" and the box in the lower right says "world!". The arrowhead from "Hello" is filled in red and the arrowhead to "World!" is filled in blue.
2
+ <Network aspect node-fill={gray} edge-arrow>
3
+ <Node id="hello" pos={[0.25, 0.25]}>Hello</Node>
4
+ <Node id="world" pos={[0.75, 0.75]}>World!</Node>
5
+ <Edge from="hello" to="world" from-fill={red} to-fill={blue} />
6
+ </Network>
@@ -0,0 +1,3 @@
1
+ // create a custom triangle element called `Tri` and use it to create a triangle with a gray fill
2
+ const Tri = ({ pos0, pos1, pos2, ...attr }) => <Shape {...attr}>{[pos0, pos1, pos2]}</Shape>
3
+ return <Tri pos0={[0.5, 0.1]} pos1={[0.9, 0.9]} pos2={[0.1, 0.9]} fill={gray} />
@@ -0,0 +1,6 @@
1
+ // two ellipses, one wider and one taller
2
+ <Group>
3
+ <Ellipse pos={[0.3, 0.2]} rad={[0.2, 0.1]} />
4
+ <Ellipse pos={[0.6, 0.6]} rad={[0.2, 0.25]} />
5
+ </Group>
6
+
@@ -0,0 +1,7 @@
1
+ // a series of closely spaced squares rotating clockwise along a sinusoidal path
2
+ <Graph ylim={[-1.5, 1.5]} padding={0.2} aspect={2}>
3
+ <SymPoints
4
+ fy={sin} xlim={[0, 2*pi]} size={0.5} N={100}
5
+ shape={x => <Square rounded spin={r2d*x} />}
6
+ />
7
+ </Graph>
@@ -0,0 +1,12 @@
1
+ // draw a grid of square boxes filled in light gray. each box contains an arrow that is pointing in a particular direction. that direction rotates clockwise as we move through the grid.
2
+ <Frame padding rounded>
3
+ <Grid rows={3} spacing>
4
+ { linspace(0, 360, 10).slice(0, 9).map(th =>
5
+ <Frame padding rounded fill>
6
+ <Group aspect={1} spin={th}>
7
+ <Arrow direc={0} tail={1} pos={[1, 0.5]} rad={0.5} />
8
+ </Group>
9
+ </Frame>
10
+ ) }
11
+ </Grid>
12
+ </Frame>
@@ -0,0 +1,5 @@
1
+ // a square in the top left and a circle in the bottom right
2
+ <Group>
3
+ <Rect pos={[0.3, 0.3]} rad={0.1} spin={15} />
4
+ <Ellipse pos={[0.7, 0.7]} rad={0.1} />
5
+ </Group>
@@ -0,0 +1,4 @@
1
+ // The text "GUM" in a simple frame
2
+ <Frame padding rounded>
3
+ <Text>GUM</Text>
4
+ </Frame>
@@ -0,0 +1,5 @@
1
+ // There are two latex equations framed by rounded borders arranged vertically. The top one shows a Gaussian integral and the bottom one shows a trigonometric identity. They are framed by a square with the title "Facts".
2
+ <VStack spacing>
3
+ <TextFrame><Equation>{"\\int_0^{\\infty} \\exp(-x^2) dx = \\sqrt{\\pi}"}</Equation></TextFrame>
4
+ <TextFrame><Equation>{"\\sin^2(\\theta) + \\cos^2(\\theta) = 1"}</Equation></TextFrame>
5
+ </VStack>
@@ -0,0 +1,13 @@
1
+ // draw a diagonal line in blue and a cup shaped line in red
2
+ <Group>
3
+ <Line stroke={blue}>{[
4
+ [0.2, 0.2],
5
+ [0.8, 0.8],
6
+ ]}</Line>
7
+ <Line stroke={red}>{[
8
+ [0.3, 0.3],
9
+ [0.3, 0.7],
10
+ [0.7, 0.7],
11
+ [0.7, 0.3],
12
+ ]}</Line>
13
+ </Group>
@@ -0,0 +1,6 @@
1
+ // plot the exponential of sin(x) over [0, 2π]
2
+ <Box margin={0.15}>
3
+ <Plot aspect={phi} xlim={[0, 2*pi]} ylim={[0, 3]} grid>
4
+ <SymLine fy={x => exp(sin(x))} />
5
+ </Plot>
6
+ </Box>
@@ -0,0 +1,8 @@
1
+ // A network with a node on the left saying "Hello world" and two nodes on the right, one saying "This is a test of wrapping capabilities" and the other containing a blue ellipse. There are arrows going from the left node to each of the right nodes. The nodes have gray backgrounds and rounded corners. The edges have white arrowheads.
2
+ <Network aspect={1.5} node-yrad={0.15} node-rounded node-fill={gray} edge-fill={white}>
3
+ <Node id="hello" pos={[0.25, 0.5]} wrap={3}>Hello world</Node>
4
+ <Node id="test" pos={[0.75, 0.25]} wrap={6}>This is a test of wrapping capabilities</Node>
5
+ <Node id="ball" pos={[0.75, 0.75]}><Ellipse aspect={1.5} fill={blue}/></Node>
6
+ <Edge from="hello" to="test" />
7
+ <Edge from="hello" to="ball" from-dir="s" curve={3} />
8
+ </Network>
@@ -0,0 +1,6 @@
1
+ // Two boxes with text in them that have black borders and gray interiors. The box in the upper left says "hello" and the box in the lower right says "world!".
2
+ <Network aspect node-fill={gray}>
3
+ <Node id="hello" pos={[0.25, 0.25]}>Hello</Node>
4
+ <Node id="world" pos={[0.75, 0.75]}>World!</Node>
5
+ <Edge from="hello" to="world" />
6
+ </Network>
@@ -0,0 +1,5 @@
1
+ // plot an inverted sine wave with ticks labeled in multiples of π. There is a faint dashed grid. The x-axis is labeled "phase" and the y-axis is labeled "amplitude". The title is "Inverted Sine Wave".
2
+ const xticks = linspace(0, 2, 6).slice(1).map(x => [x*pi, `${rounder(x, 1)} π`])
3
+ return <Plot aspect={phi} margin={0.25} xanchor={0} xticks={xticks} xlabel="phase" ylabel="amplitude" title="Inverted Sine Wave" xaxis-tick-side="both" grid grid-stroke-dasharray={3}>
4
+ <SymLine fy={x => -sin(x)} xlim={[0, 2*pi]} />
5
+ </Plot>
@@ -0,0 +1,12 @@
1
+ // A plot of three different increasing curves of varying steepness and multiple points spaced at regular intervals. The x-axis label is "time (seconds)", the y-axis label is "space (meters)", and the title is "Spacetime Vibes". There are axis ticks in both directions with assiated faint grid lines.
2
+ <Plot xlim={[-1, 1]} ylim={[-1, 1]} grid margin={0.3} aspect xlabel="time (seconds)" ylabel="space (meters)" title="Spacetime Vibes">
3
+ <Points size={0.02}>{[
4
+ [0, 0.5], [0.5, 0], [-0.5, 0], [0, -0.5]
5
+ ]}
6
+ </Points>
7
+ <Rect pos={[0.5, 0.5]} rad={0.1} />
8
+ <Circle pos={[-0.5, -0.5]} rad={0.1} />
9
+ {[0.5, 0.9, 1.5].map(a =>
10
+ <SymLine fy={x => sin(a*x)} />
11
+ )}
12
+ </Plot>
@@ -0,0 +1,2 @@
1
+ // a rectangle on the left side of the figure with an aspect of roughly 1/2
2
+ <Rect pos={[0.25, 0.5]} rad={[0.1, 0.2]}/>
@@ -0,0 +1,14 @@
1
+ // draw a blue triangle with a semi-transparent green square overlaid on top
2
+ <Group>
3
+ <Shape fill={blue} stroke={none}>{[
4
+ [0.5, 0.2],
5
+ [0.8, 0.8],
6
+ [0.2, 0.8]
7
+ ]}</Shape>
8
+ <Shape fill={green} stroke={none} opacity={0.5}>{[
9
+ [0.3, 0.3],
10
+ [0.7, 0.3],
11
+ [0.7, 0.7],
12
+ [0.3, 0.7]
13
+ ]}</Shape>
14
+ </Group>
@@ -0,0 +1,8 @@
1
+ // A slide with a title, a plot of a sine wave, and some text describing the plot. Let the title be "The Art of the Sine Wave".
2
+ <Slide title="The Art of the Sine Wave">
3
+ <Text>Here's a plot of a sine wave below. It has to be the right size to fit in with the figure correctly.</Text>
4
+ <Plot xlim={[0, 2*pi]} ylim={[-1.5, 1.5]} grid fill={lightgray} margin={[0.25, 0.05]} aspect={2}>
5
+ <SymLine fy={sin} stroke={blue} stroke-width={2} />
6
+ </Plot>
7
+ <Text>It ranges from low to high and has some extra vertical space to allow us to see the full curve.</Text>
8
+ </Slide>
@@ -0,0 +1,13 @@
1
+ // draw a blue cubic spline path filled with gray that looks like a pacman facing left, using 5 vertices. label the vertices with black dots and connect them with straight red lines. place the whole thing in a rounded frame.
2
+ const points = [
3
+ [0.25, 0.25],
4
+ [0.75, 0.25],
5
+ [0.75, 0.75],
6
+ [0.25, 0.75],
7
+ [0.50, 0.50],
8
+ ]
9
+ return <Frame rounded margin>
10
+ <Spline closed stroke={blue} fill={gray}>{points}</Spline>
11
+ <Shape stroke={red}>{points}</Shape>
12
+ <Points size={0.0075}>{points}</Points>
13
+ </Frame>
@@ -0,0 +1,8 @@
1
+ // a wide blue rectangle on top, with red and green squares side by side on the bottom. each one has rounded corners.
2
+ <VStack spacing>
3
+ <Rect rounded fill={blue} />
4
+ <HStack stack-size={0.5} spacing>
5
+ <Square rounded fill={red} />
6
+ <Square rounded fill={green} />
7
+ </HStack>
8
+ </VStack>
@@ -0,0 +1,4 @@
1
+ // A vector field showing a function with gradient 100 * x * y. There should be a grid of 15 by 15 arrows. The stroke width should be 2.
2
+ <Frame rounded={0.02} margin padding={0.075} border={2} fill>
3
+ <DataField func={(x, y) => 100 * x * y} xlim={[0, 1]} ylim={[0, 1]} N={15} stroke-width={2} />
4
+ </Frame>
@@ -0,0 +1,6 @@
1
+ // a decaying sine wave filled in with blue
2
+ const decay = x => exp(-0.1*x) * sin(x)
3
+ return <Graph xlim={[0, 6*pi]} ylim={[-1, 1]} aspect={phi}>
4
+ <SymFill fy1={decay} fy2={0} fill={blue} fill-opacity={0.5} N={250} />
5
+ <SymLine fy={decay} N={250} />
6
+ </Graph>
@@ -0,0 +1,5 @@
1
+ // plot two lines: (1) a sine wave in red; (2) the same sine wave with a lower amplitude higher frequency sine wave added on top (in blue)
2
+ <Plot xlim={[0, 2*pi]} ylim={[-1.5, 1.5]} aspect={phi} margin={0.2} grid>
3
+ <SymLine fy={sin} stroke={red} stroke-width={2} />
4
+ <SymLine fy={x => sin(x) + 0.2*sin(5*x)} stroke={blue} stroke-width={2} />
5
+ </Plot>
@@ -0,0 +1,6 @@
1
+ // A plot of a sine wave in blue. There are white pill shaped line markers along the sine wave that are rotated to follow the slope of the curve.
2
+ const Pill = args => <Rect fill={white} rounded={0.3} aspect={2} {...args} />
3
+ return <Plot xlim={[0, 2*pi]} ylim={[-1.5, 1.5]} grid fill={lightgray} margin={[0.25, 0.1]} aspect="auto">
4
+ <SymLine fy={sin} stroke={blue} stroke-width={2} />
5
+ <SymPoints fy={sin} size={0.125} N={11} shape={x => <Pill spin={-r2d*atan(cos(x))}/>} />
6
+ </Plot>
@@ -0,0 +1,9 @@
1
+ // Draw a rounded star shape with a blue fill. Wrap it in a rounded frame.
2
+ const rad = t => 1 - 0.3 * cos(2.5 * t)**2
3
+ return <Frame rounded padding margin>
4
+ <SymShape aspect fill={blue}
5
+ tlim={[0, 2*pi]} N={200}
6
+ fx={t => rad(t) * sin(t)}
7
+ fy={t => rad(t) * cos(t)}
8
+ />
9
+ </Frame>
@@ -0,0 +1,10 @@
1
+ // smooth damped oscillation using sparse sampling (N=10)
2
+ // shows how spline interpolates between discrete function samples
3
+ // display the true function in gray with low opacity
4
+ const decay = x => exp(-x/2) * sin(3*x)
5
+
6
+ return <Plot xlim={[0, 2*pi]} ylim={[-1, 1]} grid margin={0.15} aspect={phi}>
7
+ <SymLine fy={decay} opacity={0.25} N={200} />
8
+ <SymSpline fy={decay} N={10} stroke={blue} stroke-width={2} />
9
+ <SymPoints fy={decay} N={10} size={0.05} fill={red} />
10
+ </Plot>
@@ -0,0 +1,4 @@
1
+ // The text "Hello World! You can mix text and other elements together." with a blue square between "and" and "other". Put it in a rounded frame with padding.
2
+ <TextFrame rounded wrap={10}>
3
+ Hello World! You can mix text and <Square rounded fill={blue} /> other elements together.
4
+ </TextFrame>
@@ -0,0 +1,2 @@
1
+ // draw the word "hello" in a rounded rectangular frame
2
+ <TextBox border rounded margin>hello</TextBox>
@@ -0,0 +1,9 @@
1
+ // Various food emojis are arrnaged in a spaced out grid and framed with the title "Fruits & Veggies". Each emoji is framed by a rounded square with a gray background.
2
+ const emoji = [ '🍇', '🥦', '🍔', '🍉', '🍍', '🌽', '🍩', '🥝', '🍟' ]
3
+ return <TitleFrame title="Fruits & Veggies" margin padding rounded>
4
+ <Grid rows={3} spacing={0.05}>
5
+ {emoji.map(e =>
6
+ <Frame aspect rounded fill padding><Text>{e}</Text></Frame>
7
+ )}
8
+ </Grid>
9
+ </TitleFrame>
@@ -0,0 +1,7 @@
1
+ // make a diamond shape with two triangles, the triangle on top is red and the triangle on the bottom is blue
2
+ <Frame margin rounded padding fill>
3
+ <VStack>
4
+ <Triangle fill={red} aspect={1} stroke-width={0} />
5
+ <Triangle fill={blue} aspect={1} stroke-width={0} vflip />
6
+ </VStack>
7
+ </Frame>
@@ -0,0 +1,5 @@
1
+ // draw a plus symbol in a frame and place it in the bottom left corner
2
+ <Group pos={[0.3, 0.7]} rad={0.2}>
3
+ <VLine />
4
+ <HLine />
5
+ </Group>
@@ -0,0 +1,21 @@
1
+ const xlim = [ -4, 4 ]; const ylim = [ -2, 2 ]
2
+ const Curve = ({ fx, stroke }) => <SymLine fx={fx} ylim={ylim} stroke={stroke} stroke-width={2} N={250} />
3
+ const xlabel = <Latex>x = a + bi</Latex>
4
+ const ylabel = <Latex>c</Latex>
5
+ return <Plot aspect={2} margin={0.3} xlim={xlim} ylabel={ylabel} xlabel={xlabel} ylabel-offset={0.075} ylabel-size={0.02}>
6
+ <Mesh2D xlocs={41} ylocs={21} xlim={xlim} ylim={ylim} opacity={0.3} />
7
+ <HLine loc={0} lim={xlim} opacity={0.3} />
8
+ <VLine loc={0} lim={ylim} opacity={0.3} />
9
+ <Curve fx={y => -y + sqrt(max(0, y*y-1))} stroke={blue} />
10
+ <Curve fx={y => -y - sqrt(max(0, y*y-1))} stroke={blue} />
11
+ <Curve fx={y => +sqrt(max(0, 1-y*y))} stroke={red} />
12
+ <Curve fx={y => -sqrt(max(0, 1-y*y))} stroke={red} />
13
+ <Dot pos={[-1, 1]} rad={0.04} color={blue} />
14
+ <Dot pos={[1, -1]} rad={0.04} color={blue} />
15
+ <Dot pos={[0, -1]} rad={0.04} color={red} />
16
+ <Dot pos={[0, +1]} rad={0.04} color={red} />
17
+ <Dot pos={[0, 0]} rad={0.04} />
18
+ <Text color={blue} pos={[-2.5, 1.1]} yrad={0.2}>real</Text>
19
+ <Text color={red} pos={[1.6, -0.4]} yrad={0.2}>imag</Text>
20
+ <Latex pos={[2.3, 1.6]} yrad={0.2}>f(x) = x^2 + 2cx + 1</Latex>
21
+ </Plot>
@@ -0,0 +1,5 @@
1
+ <Plot grid margin={0.3} xlim={[0, 2*pi]} ylim={[-1.5, 1.5]} xlabel="Phase (radians)" ylabel="Interference" title="Flux Capacitance">
2
+ <SymFill fy1={sin} fy2={cos} fill={blue} opacity={0.25} />
3
+ <SymLine fy={sin} />
4
+ <SymLine fy={cos} />
5
+ </Plot>
@@ -0,0 +1,17 @@
1
+ const [ n, m ] = [ 9, 16 ]
2
+ const pal = palette('#00d4ff', '#7c3aed', [0, m-1])
3
+ const pts = [
4
+ [0.12, 0.55], [0.25, 0.20], [0.42, 0.78],
5
+ [0.60, 0.30], [0.78, 0.72], [0.88, 0.45],
6
+ ]
7
+ return <Frame border={2} rounded={0.03} fill={darkgray} padding={0.03} margin>
8
+ <Frame rounded={0.02} fill={black} padding={0.025}>
9
+ <Grid rows={n} cols={m} opacity={0.7}>
10
+ {range(0, n*m).map(i => <Rect rounded={0.2} fill={pal(i%m)} /> )}
11
+ </Grid>
12
+ <Group stroke-linecap="round">
13
+ <Spline curve={0.65} stroke={gray} stroke-width={15} opacity={0.25}>{pts}</Spline>
14
+ <Spline curve={0.65} stroke={gray} stroke-width={5}>{pts}</Spline>
15
+ </Group>
16
+ </Frame>
17
+ </Frame>
@@ -0,0 +1,11 @@
1
+ const aspect = 2
2
+ const ratio = pi / aspect
3
+ return <Box margin={0.3}>
4
+ <Group coord={[0, 1, 2*pi, -1]} aspect={aspect}>
5
+ <HMesh locs={5} lim={[0, 2*pi]} opacity={0.3} />
6
+ <VMesh locs={5} lim={[-1, 1]} opacity={0.3} />
7
+ <HAxis ticks={5} lim={[0, 2*pi]} pos={[pi, -1]} rad={[pi, 0.04]} />
8
+ <VAxis ticks={5} lim={[-1, 1]} pos={[0, 0]} rad={[0.04*ratio, 1]} />
9
+ <SymLine fy={sin} xlim={[0, 2*pi]} />
10
+ </Group>
11
+ </Box>
@@ -0,0 +1,30 @@
1
+ const pal = palette(blue, purple, [3, 8])
2
+ const shapes = [
3
+ [3, 'Triangle'], [4, 'Square' ], [5, 'Pentagon'],
4
+ [6, 'Hexagon' ], [7, 'Heptagon'], [8, 'Octagon' ],
5
+ ]
6
+
7
+ const RegularPolygon = ({ n, ...args }) =>
8
+ <SymShape {...args}
9
+ aspect spin={90*(n-2)/n}
10
+ xlim={[-1, 1]} ylim={[-1, 1]}
11
+ tvals={linspace(0, 2*pi, n+1)}
12
+ fx={cos} fy={sin}
13
+ />
14
+
15
+ return <Slide title="Simple Regular Polygons" wrap={25}>
16
+ <Text>
17
+ A regular polygon has equal side lengths and equal interior angles. Below are examples for
18
+ <Latex>{"n \\in \\{3, \\ldots, 8\\}"}</Latex>
19
+ </Text>
20
+ <Grid rows={2} spacing={[0.05, 0.075]}>
21
+ { shapes.map(([n, s]) =>
22
+ <Frame rounded fill padding aspect>
23
+ <VStack spacing>
24
+ <RegularPolygon stack-size={0.8} n={n} fill={pal(n)} />
25
+ <Text stack-size={0.2}>{`${s} (${n})`}</Text>
26
+ </VStack>
27
+ </Frame>
28
+ ) }
29
+ </Grid>
30
+ </Slide>
@@ -0,0 +1,7 @@
1
+ <Frame rounded={0.15} padding margin fill={gray} rotate={-25}>
2
+ <HStack aspect={7.5} spacing={0.075}>
3
+ <TextFrame fill={red} padding rounded={[0.1, 0, 0, 0.1]}>Punk</TextFrame>
4
+ <TextFrame fill={blue} padding rounded={0}>Rock</TextFrame>
5
+ <TextFrame fill={green} padding rounded={[0, 0.1, 0.1, 0]} aspect>→</TextFrame>
6
+ </HStack>
7
+ </Frame>
@@ -0,0 +1,11 @@
1
+ const Set = ({ label, label_pos, label_rad = 0.15, fill = "#C8CAE3", ...args }) =>
2
+ <Frame flex fill={fill} shape={<Ellipse/>} {...args}>
3
+ <Text pos={label_pos} rad={label_rad}>{label}</Text>
4
+ </Frame>
5
+ return <TitleFrame rounded padding={0.2} margin={0.3} title="Set Theory">
6
+ <Group aspect>
7
+ <Set label="A" label-pos={[0.2, 0.7]} label-rad={0.07} fill-opacity={0.5} />
8
+ <Set label="B" pos={[0.60, 0.20]} rad={0.1} />
9
+ <Set label="C" pos={[0.55, 0.75]} rad={0.15} />
10
+ </Group>
11
+ </TitleFrame>
@@ -0,0 +1,12 @@
1
+ const [labs, vals] = zip(
2
+ ["GPT-4o", 0.4], ["OpenAI o1", 3.2], ["OpenAI o4-mini", 8.3], ["Gemini 3 Pro", 12.4],
3
+ ["OpenAI o3", 14.1], ["Grok 4", 15.9], ["Claude Opus 4.5", 17.5], ["GPT-5.2", 25.2],
4
+ )
5
+ return <Plot
6
+ aspect={1.6} margin={[0.2, 0.1, 0.2, 0.35]} ylim={[0, 30]} xanchor={-0.6} yanchor={-0.55}
7
+ xticks={enumerate(labs)} yticks={linspace(0, 30, 7)} axis-tick-side="outer" xaxis-line-lim={[0, 7]}
8
+ xaxis-label-spin={-45} xaxis-label-justify="right" xaxis-label-loc={0.7}
9
+ >
10
+ <Bars rounded={0.1} width={0.85}>{vals}</Bars>
11
+ {vals.map((s, i) => <Span pos={[i, s+1.3]} yrad={0.75}>{`${s}%`}</Span> )}
12
+ </Plot>
@@ -0,0 +1,20 @@
1
+ // parameters
2
+ const n = 5
3
+ const R = 0.7
4
+ const c = 0.6
5
+
6
+ // get inner/outer vertex angles
7
+ const theta0 = linspace(0, 2 * pi, n + 1).slice(0, -1).map(t => t - pi / 2)
8
+ const theta1 = theta0.map(t => t + pi / n)
9
+
10
+ // get inner/outer point positions
11
+ const polar = (r, t) => [ r * cos(t), r * sin(t) ]
12
+ const points0 = theta0.map(t => polar(1, t))
13
+ const points1 = theta1.map(t => polar(R, t))
14
+
15
+ // return full spline
16
+ return <Frame aspect margin padding rounded fill={gray}>
17
+ <Spline closed fill={blue} curve={c} coord={[-1, -1, 1, 1]}>
18
+ {zip(points0, points1).flat()}
19
+ </Spline>
20
+ </Frame>
@@ -0,0 +1,14 @@
1
+ <Frame border={2} rounded={0.02} clip margin>
2
+ <Plot
3
+ aspect={1.5} axis={false} xgrid={31} ygrid={21}
4
+ xlim={[-4*pi, 4*pi]} ylim={[-1.5, 1.5]}
5
+ >
6
+ { linspace(0, pi, 10).map(p =>
7
+ <SymSpline
8
+ fy={x => cos(x-p) * exp(-0.05*x*x)}
9
+ stroke={interp(red, blue, p/pi)}
10
+ stroke-width={2} N={50}
11
+ />
12
+ )}
13
+ </Plot>
14
+ </Frame>
package/docs/meta.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "core": [
3
+ "gum",
4
+ "element",
5
+ "group",
6
+ "context"
7
+ ],
8
+ "layout": [
9
+ "box",
10
+ "stack",
11
+ "grid",
12
+ "points"
13
+ ],
14
+ "shapes": [
15
+ "rect",
16
+ "ellipse",
17
+ "line",
18
+ "shape",
19
+ "spline"
20
+ ],
21
+ "text": [
22
+ "text",
23
+ "latex",
24
+ "titleframe",
25
+ "slide"
26
+ ],
27
+ "symbolic": [
28
+ "sympoints",
29
+ "symline",
30
+ "symshape",
31
+ "symspline",
32
+ "symfill"
33
+ ],
34
+ "plotting": [
35
+ "graph",
36
+ "plot",
37
+ "axis",
38
+ "barplot"
39
+ ],
40
+ "networks": [
41
+ "node",
42
+ "edge",
43
+ "network"
44
+ ],
45
+ "utilities": [
46
+ "math",
47
+ "arrays",
48
+ "colors"
49
+ ]
50
+ }
@@ -0,0 +1,25 @@
1
+ # Arrays
2
+
3
+ There are a number of functions designed to make working with arrays easier. They largely mimic similar functions found in core Python or the `numpy` library.
4
+
5
+ ## Functions
6
+
7
+ - `zip(...arrs)` — combine arrays `arrs` element-wise
8
+ - `min(arrs)` — the minimum of arrays `arrs`
9
+ - `max(arrs)` — the maximum of arrays `arrs`
10
+ - `reshape(arr, shape)` — reshape array `arr` to given dimensions `shape`
11
+ - `split(arr, len)` — split array `arr` into subarrays of length `len`
12
+ - `sum(arr)` — sum the elements of array `arr`
13
+ - `all(arr)` — check if all elements of array `arr` are true
14
+ - `any(arr)` — check if any element of array `arr` is true
15
+ - `add(arr1, arr2)` — add arrays `arr1` and `arr2` element-wise
16
+ - `mul(arr1, arr2)` — multiply arrays `arr1` and `arr2` element-wise
17
+ - `cumsum(arr, first=true)` — compute the cumulative sum of array `arr` with the option to start at zero
18
+ - `norm(arr, degree=1)` — compute the `degree`-norm of array `arr`
19
+ - `normalize(arr, degree=1)` — normalize array `arr` to have `degree`-norm one
20
+ - `range(i0, i1, step=1)` — generate an array of evenly spaced values from `i0` to `i1` with spacing `step`
21
+ - `linspace(x0, x1, n=50)` — generate an array of `n` evenly spaced values between `x0` and `x1`
22
+ - `enumerate(arr)` — pair each element of array `arr` with its index
23
+ - `repeat(x, n)` — repeat array `x` a total of `n` times
24
+ - `meshgrid(x, y)` — create a mesh grid from arrays `x` and `y`
25
+ - `lingrid(xlim, ylim, N)` — create a 2D grid of `N = [Nx, Ny]` points over the ranges `xlim` and `ylim`
@@ -0,0 +1,20 @@
1
+ # Axis
2
+
3
+ *Inherits*: [Group](/docs/Group) > [Element](/docs/Element)
4
+
5
+ A single vertical or horizontal axis for plotting. This includes the central line, the perpendicual ticks, and their associated tick labels. Note that the proper bounds encompass only the central line and ticks, while the tick labels may fall well outside of them. Use **HAxis** and **VAxis** for specific directions.
6
+
7
+ Because `Axis` is used primarily for [Plot](/docs/Plot), the `tick-side` parameter is inverted for `VAxis`, meaning `outer` points up and `inner` points down. Meanwhile, for `HAxis`, `outer` points to the left and `inner` points to the right.
8
+
9
+ Parameters:
10
+ - `direc` — the orientation of the axis, either `v` (vertical) or `h` (horizontal)
11
+ - `ticks` — a list of tick `[location, label]` pairs. The label can either be an `Element` or a string
12
+ - `lim` = `[0, 1]` — the extent of the element along the main axis
13
+ - `tick-side` = `'both'` — one of `'inner'` / `'outer'` / `'both'` / `'none'` , or a pair representing a numerical range in `[0, 1]`, where zero is oriented in the inner direction
14
+ - `label-side` = same as `tick-side` but for the labels
15
+ - `children` = a list of `Element`s to use as the tick labels instead of `ticks`. These must have a `loc` to tell `Axis` where to place the label and associated tick.
16
+
17
+ Subunits:
18
+ - `line`: the central line along the main axis
19
+ - `tick`: the perpendicular tick marks (collectively)
20
+ - `label`: the labels annotating the tick marks (collectively)