desmost 0.1.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 (281) hide show
  1. package/dist/compiler/compile.d.ts +32 -0
  2. package/dist/compiler/compile.d.ts.map +1 -0
  3. package/dist/compiler/compile.js +101 -0
  4. package/dist/compiler/compile.js.map +1 -0
  5. package/dist/compiler/evaluate.d.ts +18 -0
  6. package/dist/compiler/evaluate.d.ts.map +1 -0
  7. package/dist/compiler/evaluate.js +83 -0
  8. package/dist/compiler/evaluate.js.map +1 -0
  9. package/dist/compiler/index.d.ts +3 -0
  10. package/dist/compiler/index.d.ts.map +1 -0
  11. package/dist/compiler/index.js +2 -0
  12. package/dist/compiler/index.js.map +1 -0
  13. package/dist/compiler/options.d.ts +54 -0
  14. package/dist/compiler/options.d.ts.map +1 -0
  15. package/dist/compiler/options.js +15 -0
  16. package/dist/compiler/options.js.map +1 -0
  17. package/dist/desmos.d.ts +12 -0
  18. package/dist/desmos.d.ts.map +1 -0
  19. package/dist/desmos.js +13 -0
  20. package/dist/desmos.js.map +1 -0
  21. package/dist/errors.d.ts +45 -0
  22. package/dist/errors.d.ts.map +1 -0
  23. package/dist/errors.js +38 -0
  24. package/dist/errors.js.map +1 -0
  25. package/dist/index.d.ts +2 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +2 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/magic/expr/index.d.ts +3 -0
  30. package/dist/magic/expr/index.d.ts.map +1 -0
  31. package/dist/magic/expr/index.js +8 -0
  32. package/dist/magic/expr/index.js.map +1 -0
  33. package/dist/magic/expr/latex.d.ts +10 -0
  34. package/dist/magic/expr/latex.d.ts.map +1 -0
  35. package/dist/magic/expr/latex.js +16 -0
  36. package/dist/magic/expr/latex.js.map +1 -0
  37. package/dist/magic/expr/text.d.ts +9 -0
  38. package/dist/magic/expr/text.d.ts.map +1 -0
  39. package/dist/magic/expr/text.js +13 -0
  40. package/dist/magic/expr/text.js.map +1 -0
  41. package/dist/magic/global/dark-mode.d.ts +7 -0
  42. package/dist/magic/global/dark-mode.d.ts.map +1 -0
  43. package/dist/magic/global/dark-mode.js +11 -0
  44. package/dist/magic/global/dark-mode.js.map +1 -0
  45. package/dist/magic/global/desmos.d.ts +9 -0
  46. package/dist/magic/global/desmos.d.ts.map +1 -0
  47. package/dist/magic/global/desmos.js +11 -0
  48. package/dist/magic/global/desmos.js.map +1 -0
  49. package/dist/magic/global/index.d.ts +3 -0
  50. package/dist/magic/global/index.d.ts.map +1 -0
  51. package/dist/magic/global/index.js +10 -0
  52. package/dist/magic/global/index.js.map +1 -0
  53. package/dist/magic/global/viewport.d.ts +16 -0
  54. package/dist/magic/global/viewport.d.ts.map +1 -0
  55. package/dist/magic/global/viewport.js +12 -0
  56. package/dist/magic/global/viewport.js.map +1 -0
  57. package/dist/magic/incantation.d.ts +74 -0
  58. package/dist/magic/incantation.d.ts.map +1 -0
  59. package/dist/magic/incantation.js +81 -0
  60. package/dist/magic/incantation.js.map +1 -0
  61. package/dist/magic/index.d.ts +6 -0
  62. package/dist/magic/index.d.ts.map +1 -0
  63. package/dist/magic/index.js +5 -0
  64. package/dist/magic/index.js.map +1 -0
  65. package/dist/magic/local/anim.d.ts +7 -0
  66. package/dist/magic/local/anim.d.ts.map +1 -0
  67. package/dist/magic/local/anim.js +11 -0
  68. package/dist/magic/local/anim.js.map +1 -0
  69. package/dist/magic/local/colour.d.ts +12 -0
  70. package/dist/magic/local/colour.d.ts.map +1 -0
  71. package/dist/magic/local/colour.js +27 -0
  72. package/dist/magic/local/colour.js.map +1 -0
  73. package/dist/magic/local/dashed.d.ts +7 -0
  74. package/dist/magic/local/dashed.d.ts.map +1 -0
  75. package/dist/magic/local/dashed.js +10 -0
  76. package/dist/magic/local/dashed.js.map +1 -0
  77. package/dist/magic/local/fill.d.ts +13 -0
  78. package/dist/magic/local/fill.d.ts.map +1 -0
  79. package/dist/magic/local/fill.js +12 -0
  80. package/dist/magic/local/fill.js.map +1 -0
  81. package/dist/magic/local/hide.d.ts +7 -0
  82. package/dist/magic/local/hide.d.ts.map +1 -0
  83. package/dist/magic/local/hide.js +10 -0
  84. package/dist/magic/local/hide.js.map +1 -0
  85. package/dist/magic/local/index.d.ts +3 -0
  86. package/dist/magic/local/index.d.ts.map +1 -0
  87. package/dist/magic/local/index.js +24 -0
  88. package/dist/magic/local/index.js.map +1 -0
  89. package/dist/magic/local/line.d.ts +15 -0
  90. package/dist/magic/local/line.d.ts.map +1 -0
  91. package/dist/magic/local/line.js +17 -0
  92. package/dist/magic/local/line.js.map +1 -0
  93. package/dist/magic/local/no-line.d.ts +7 -0
  94. package/dist/magic/local/no-line.d.ts.map +1 -0
  95. package/dist/magic/local/no-line.js +10 -0
  96. package/dist/magic/local/no-line.js.map +1 -0
  97. package/dist/magic/local/point.d.ts +15 -0
  98. package/dist/magic/local/point.d.ts.map +1 -0
  99. package/dist/magic/local/point.js +17 -0
  100. package/dist/magic/local/point.js.map +1 -0
  101. package/dist/magic/local/secret.d.ts +7 -0
  102. package/dist/magic/local/secret.d.ts.map +1 -0
  103. package/dist/magic/local/secret.js +10 -0
  104. package/dist/magic/local/secret.js.map +1 -0
  105. package/dist/magic/local/slider.d.ts +15 -0
  106. package/dist/magic/local/slider.d.ts.map +1 -0
  107. package/dist/magic/local/slider.js +13 -0
  108. package/dist/magic/local/slider.js.map +1 -0
  109. package/dist/parser/ast.d.ts +40 -0
  110. package/dist/parser/ast.d.ts.map +1 -0
  111. package/dist/parser/ast.js +13 -0
  112. package/dist/parser/ast.js.map +1 -0
  113. package/dist/parser/desmost-parser.d.ts +105 -0
  114. package/dist/parser/desmost-parser.d.ts.map +1 -0
  115. package/dist/parser/desmost-parser.js +379 -0
  116. package/dist/parser/desmost-parser.js.map +1 -0
  117. package/dist/parser/generic-parser.d.ts +62 -0
  118. package/dist/parser/generic-parser.d.ts.map +1 -0
  119. package/dist/parser/generic-parser.js +143 -0
  120. package/dist/parser/generic-parser.js.map +1 -0
  121. package/dist/parser/index.d.ts +8 -0
  122. package/dist/parser/index.d.ts.map +1 -0
  123. package/dist/parser/index.js +8 -0
  124. package/dist/parser/index.js.map +1 -0
  125. package/dist/src/compiler/compile.d.ts +32 -0
  126. package/dist/src/compiler/compile.d.ts.map +1 -0
  127. package/dist/src/compiler/compile.js +101 -0
  128. package/dist/src/compiler/compile.js.map +1 -0
  129. package/dist/src/compiler/evaluate.d.ts +18 -0
  130. package/dist/src/compiler/evaluate.d.ts.map +1 -0
  131. package/dist/src/compiler/evaluate.js +83 -0
  132. package/dist/src/compiler/evaluate.js.map +1 -0
  133. package/dist/src/compiler/index.d.ts +3 -0
  134. package/dist/src/compiler/index.d.ts.map +1 -0
  135. package/dist/src/compiler/index.js +2 -0
  136. package/dist/src/compiler/index.js.map +1 -0
  137. package/dist/src/compiler/options.d.ts +54 -0
  138. package/dist/src/compiler/options.d.ts.map +1 -0
  139. package/dist/src/compiler/options.js +15 -0
  140. package/dist/src/compiler/options.js.map +1 -0
  141. package/dist/src/desmos.d.ts +12 -0
  142. package/dist/src/desmos.d.ts.map +1 -0
  143. package/dist/src/desmos.js +13 -0
  144. package/dist/src/desmos.js.map +1 -0
  145. package/dist/src/errors.d.ts +45 -0
  146. package/dist/src/errors.d.ts.map +1 -0
  147. package/dist/src/errors.js +38 -0
  148. package/dist/src/errors.js.map +1 -0
  149. package/dist/src/index.d.ts +2 -0
  150. package/dist/src/index.d.ts.map +1 -0
  151. package/dist/src/index.js +2 -0
  152. package/dist/src/index.js.map +1 -0
  153. package/dist/src/magic/expr/index.d.ts +3 -0
  154. package/dist/src/magic/expr/index.d.ts.map +1 -0
  155. package/dist/src/magic/expr/index.js +8 -0
  156. package/dist/src/magic/expr/index.js.map +1 -0
  157. package/dist/src/magic/expr/latex.d.ts +10 -0
  158. package/dist/src/magic/expr/latex.d.ts.map +1 -0
  159. package/dist/src/magic/expr/latex.js +16 -0
  160. package/dist/src/magic/expr/latex.js.map +1 -0
  161. package/dist/src/magic/expr/text.d.ts +9 -0
  162. package/dist/src/magic/expr/text.d.ts.map +1 -0
  163. package/dist/src/magic/expr/text.js +13 -0
  164. package/dist/src/magic/expr/text.js.map +1 -0
  165. package/dist/src/magic/global/dark-mode.d.ts +7 -0
  166. package/dist/src/magic/global/dark-mode.d.ts.map +1 -0
  167. package/dist/src/magic/global/dark-mode.js +11 -0
  168. package/dist/src/magic/global/dark-mode.js.map +1 -0
  169. package/dist/src/magic/global/desmos.d.ts +9 -0
  170. package/dist/src/magic/global/desmos.d.ts.map +1 -0
  171. package/dist/src/magic/global/desmos.js +11 -0
  172. package/dist/src/magic/global/desmos.js.map +1 -0
  173. package/dist/src/magic/global/index.d.ts +3 -0
  174. package/dist/src/magic/global/index.d.ts.map +1 -0
  175. package/dist/src/magic/global/index.js +10 -0
  176. package/dist/src/magic/global/index.js.map +1 -0
  177. package/dist/src/magic/global/viewport.d.ts +16 -0
  178. package/dist/src/magic/global/viewport.d.ts.map +1 -0
  179. package/dist/src/magic/global/viewport.js +12 -0
  180. package/dist/src/magic/global/viewport.js.map +1 -0
  181. package/dist/src/magic/incantation.d.ts +74 -0
  182. package/dist/src/magic/incantation.d.ts.map +1 -0
  183. package/dist/src/magic/incantation.js +81 -0
  184. package/dist/src/magic/incantation.js.map +1 -0
  185. package/dist/src/magic/index.d.ts +6 -0
  186. package/dist/src/magic/index.d.ts.map +1 -0
  187. package/dist/src/magic/index.js +5 -0
  188. package/dist/src/magic/index.js.map +1 -0
  189. package/dist/src/magic/local/anim.d.ts +7 -0
  190. package/dist/src/magic/local/anim.d.ts.map +1 -0
  191. package/dist/src/magic/local/anim.js +11 -0
  192. package/dist/src/magic/local/anim.js.map +1 -0
  193. package/dist/src/magic/local/colour.d.ts +12 -0
  194. package/dist/src/magic/local/colour.d.ts.map +1 -0
  195. package/dist/src/magic/local/colour.js +27 -0
  196. package/dist/src/magic/local/colour.js.map +1 -0
  197. package/dist/src/magic/local/dashed.d.ts +7 -0
  198. package/dist/src/magic/local/dashed.d.ts.map +1 -0
  199. package/dist/src/magic/local/dashed.js +10 -0
  200. package/dist/src/magic/local/dashed.js.map +1 -0
  201. package/dist/src/magic/local/fill.d.ts +13 -0
  202. package/dist/src/magic/local/fill.d.ts.map +1 -0
  203. package/dist/src/magic/local/fill.js +12 -0
  204. package/dist/src/magic/local/fill.js.map +1 -0
  205. package/dist/src/magic/local/hide.d.ts +7 -0
  206. package/dist/src/magic/local/hide.d.ts.map +1 -0
  207. package/dist/src/magic/local/hide.js +10 -0
  208. package/dist/src/magic/local/hide.js.map +1 -0
  209. package/dist/src/magic/local/index.d.ts +3 -0
  210. package/dist/src/magic/local/index.d.ts.map +1 -0
  211. package/dist/src/magic/local/index.js +24 -0
  212. package/dist/src/magic/local/index.js.map +1 -0
  213. package/dist/src/magic/local/line.d.ts +15 -0
  214. package/dist/src/magic/local/line.d.ts.map +1 -0
  215. package/dist/src/magic/local/line.js +17 -0
  216. package/dist/src/magic/local/line.js.map +1 -0
  217. package/dist/src/magic/local/no-line.d.ts +7 -0
  218. package/dist/src/magic/local/no-line.d.ts.map +1 -0
  219. package/dist/src/magic/local/no-line.js +10 -0
  220. package/dist/src/magic/local/no-line.js.map +1 -0
  221. package/dist/src/magic/local/point.d.ts +15 -0
  222. package/dist/src/magic/local/point.d.ts.map +1 -0
  223. package/dist/src/magic/local/point.js +17 -0
  224. package/dist/src/magic/local/point.js.map +1 -0
  225. package/dist/src/magic/local/secret.d.ts +7 -0
  226. package/dist/src/magic/local/secret.d.ts.map +1 -0
  227. package/dist/src/magic/local/secret.js +10 -0
  228. package/dist/src/magic/local/secret.js.map +1 -0
  229. package/dist/src/magic/local/slider.d.ts +15 -0
  230. package/dist/src/magic/local/slider.d.ts.map +1 -0
  231. package/dist/src/magic/local/slider.js +13 -0
  232. package/dist/src/magic/local/slider.js.map +1 -0
  233. package/dist/src/parser/ast.d.ts +40 -0
  234. package/dist/src/parser/ast.d.ts.map +1 -0
  235. package/dist/src/parser/ast.js +13 -0
  236. package/dist/src/parser/ast.js.map +1 -0
  237. package/dist/src/parser/desmost-parser.d.ts +105 -0
  238. package/dist/src/parser/desmost-parser.d.ts.map +1 -0
  239. package/dist/src/parser/desmost-parser.js +379 -0
  240. package/dist/src/parser/desmost-parser.js.map +1 -0
  241. package/dist/src/parser/generic-parser.d.ts +62 -0
  242. package/dist/src/parser/generic-parser.d.ts.map +1 -0
  243. package/dist/src/parser/generic-parser.js +143 -0
  244. package/dist/src/parser/generic-parser.js.map +1 -0
  245. package/dist/src/parser/index.d.ts +8 -0
  246. package/dist/src/parser/index.d.ts.map +1 -0
  247. package/dist/src/parser/index.js +8 -0
  248. package/dist/src/parser/index.js.map +1 -0
  249. package/package.json +58 -0
  250. package/src/compiler/compile.ts +127 -0
  251. package/src/compiler/evaluate.ts +121 -0
  252. package/src/compiler/index.ts +2 -0
  253. package/src/compiler/options.ts +77 -0
  254. package/src/desmos.ts +13 -0
  255. package/src/errors.ts +46 -0
  256. package/src/index.ts +1 -0
  257. package/src/magic/.template.ts +22 -0
  258. package/src/magic/expr/index.ts +11 -0
  259. package/src/magic/expr/latex.ts +24 -0
  260. package/src/magic/expr/text.ts +19 -0
  261. package/src/magic/global/dark-mode.ts +17 -0
  262. package/src/magic/global/desmos.ts +20 -0
  263. package/src/magic/global/index.ts +13 -0
  264. package/src/magic/global/viewport.ts +25 -0
  265. package/src/magic/incantation.ts +142 -0
  266. package/src/magic/index.ts +6 -0
  267. package/src/magic/local/anim.ts +17 -0
  268. package/src/magic/local/colour.ts +38 -0
  269. package/src/magic/local/dashed.ts +16 -0
  270. package/src/magic/local/fill.ts +24 -0
  271. package/src/magic/local/hide.ts +16 -0
  272. package/src/magic/local/index.ts +27 -0
  273. package/src/magic/local/line.ts +29 -0
  274. package/src/magic/local/no-line.ts +16 -0
  275. package/src/magic/local/point.ts +29 -0
  276. package/src/magic/local/secret.ts +16 -0
  277. package/src/magic/local/slider.ts +27 -0
  278. package/src/parser/ast.ts +60 -0
  279. package/src/parser/desmost-parser.ts +486 -0
  280. package/src/parser/generic-parser.ts +191 -0
  281. package/src/parser/index.ts +8 -0
@@ -0,0 +1,142 @@
1
+ import Json5 from "json5";
2
+
3
+ import { UnrecoverableError, type Unrecoverable } from "../errors";
4
+
5
+
6
+ /**
7
+ * An *Incantation* is like a slash command that tells Desmost to do something - like changing the properties of an expression, or applying some settings to the calculator as a whole.
8
+ *
9
+ * Incantations must be prefixed by a `/`. They look like this:
10
+ *
11
+ * ```math
12
+ * /viewport{ left: -1, right: 1 }
13
+ * /hidden :: x = 69
14
+ * /text :: Never gonna give you up
15
+ * ```
16
+ *
17
+ * Incantations that accept an argument derive from `ArgIncantation`.
18
+ */
19
+ export abstract class Incantation<
20
+ Effect extends Incantation.Effect = Incantation.Effect
21
+ >
22
+ {
23
+ /** Short user-facing description of what the incantation does. */
24
+ public abstract readonly description: string
25
+
26
+ /** The raw text sequence that matches this incantation, such as `viewport` or `hidden`. */
27
+ public abstract readonly identifier: string
28
+
29
+ /** An alternative `.identifier`, strictly for localisation purposes only. */
30
+ public readonly alias?: string
31
+
32
+
33
+ /** Apply this incantation's effect to `target`, using the provided `data` if required. */
34
+ public abstract apply(
35
+ target: Effect extends GLOBAL ? Desmos.Calculator : Desmos.ExpressionState,
36
+ data?: unknown,
37
+ ): void
38
+
39
+ /** Error if the `actual` type of the given expression is not `required`. */
40
+ protected require_expr_type<T extends Desmos.ExpressionState["type"]>(
41
+ actual: unknown,
42
+ required: T,
43
+ ): asserts actual is T
44
+ {
45
+ if ((actual ?? "expression") !== required)
46
+ {
47
+ throw new UnrecoverableError.IllegalIncantation(
48
+ `/${this.identifier} can only applied to ${required === "expression" ? "latex" : required} expressions, but target block has type: ${actual}`
49
+ );
50
+ }
51
+ }
52
+ }
53
+
54
+
55
+ /**
56
+ * An incantation that accepts an argument.
57
+ */
58
+ export abstract class ArgIncantation<
59
+ Effect extends Incantation.Effect = Incantation.Effect
60
+ >
61
+ extends Incantation<Effect>
62
+ {
63
+ /** Does this incantation always require an argument to be passed? */
64
+ public readonly requires_arg: boolean = true
65
+
66
+ /** What type of argument does this incantation accept? */
67
+ public abstract readonly arg_type: Incantation.ArgType
68
+
69
+
70
+ /**
71
+ * Evaluate the argument provided to this incantation, throwing if an error is encountered.
72
+ *
73
+ * For instance, for `/viewport{ left: -1, right: 1 }`, this returns the POJO `{ left: -1, right: 1 }`.
74
+ *
75
+ * ## Notes
76
+ *
77
+ * Child incantation classes should override this method, though the defaults should cover most cases (except `ArgType.ENUM`).
78
+ */
79
+ public evaluate_arg(raw: string): Unrecoverable<unknown>
80
+ {
81
+ switch (this.arg_type) {
82
+ case Incantation.ArgType.STRING: return raw;
83
+ case Incantation.ArgType.LATEX: return raw;
84
+ case Incantation.ArgType.ENUM: return raw;
85
+
86
+ case Incantation.ArgType.OBJECT:
87
+ try {
88
+ return Json5.parse(`{${raw}}`);
89
+ }
90
+ catch (e) {
91
+ // @ts-expect-error: fine
92
+ throw new UnrecoverableError.InvalidArgument(e.message);
93
+ }
94
+ }
95
+ }
96
+ }
97
+
98
+
99
+ export namespace Incantation
100
+ {
101
+ /** The kind of effect an incantation produces - it either modifies only one block, or modifies the calculator as a whole. */
102
+ export enum Effect
103
+ {
104
+ /** An incantation that affects the entire Desmos calculator state, like `/desmos` or `/viewport`. */
105
+ GLOBAL,
106
+
107
+ /** An incantation that affects only the expression immediately following it, like `/hide` or `/slider`. */
108
+ LOCAL,
109
+
110
+ /** An incantation that produces an expression, like `/latex` or `/text`. */
111
+ EXPR,
112
+ }
113
+
114
+ /** The type of argument an incantation accepts, which affects how it is parsed. */
115
+ export enum ArgType
116
+ {
117
+ /** Any arbitrary user text content, where characters like `"` and `'` don't have semantic meaning and can be ignored. */
118
+ STRING = "String",
119
+
120
+ /** LaTeX, which should have balanced `{}` braces. */
121
+ LATEX = "LaTeX",
122
+
123
+ /** Specific value from an allowed set of values, which will map to an enum value in the Desmos API. */
124
+ ENUM = "Enum",
125
+
126
+ /** JavaScript object fields, where characters like `{}` and `"` all have semantic meaning, and must be balanced. */
127
+ OBJECT = "Object",
128
+ }
129
+ }
130
+
131
+
132
+ // == ALIASES == //
133
+
134
+ /** An incantation that affects the entire Desmos calculator state, like `/desmos` or `/viewport`. */
135
+ export type GLOBAL = Incantation.Effect.GLOBAL;
136
+
137
+ /** An incantation that affects only the expression immediately following it, like `/hide` or `/slider`. */
138
+ export type LOCAL = Incantation.Effect.LOCAL;
139
+
140
+ /** An incantation that produces an expression, like `/latex` or `/text`. */
141
+ export type EXPR = Incantation.Effect.EXPR;
142
+
@@ -0,0 +1,6 @@
1
+ export { Incantation, ArgIncantation } from "./incantation";
2
+ export type { GLOBAL, LOCAL, EXPR } from "./incantation";
3
+
4
+ export { GLOBAL_INCANTATIONS } from "./global";
5
+ export { LOCAL_INCANTATIONS } from "./local";
6
+ export { EXPR_INCANTATIONS } from "./expr";
@@ -0,0 +1,17 @@
1
+ import { Incantation, type LOCAL } from "../incantation";
2
+
3
+
4
+ export class AnimIncantation extends Incantation<LOCAL>
5
+ {
6
+ override readonly description
7
+ = "Animates the slider of a block."
8
+
9
+ override readonly identifier = "anim"
10
+
11
+ override apply(target: Desmos.ExpressionState)
12
+ {
13
+ super.require_expr_type(target.type, "expression");
14
+ // @ts-expect-error: outdated types
15
+ target.playing = true;
16
+ }
17
+ }
@@ -0,0 +1,38 @@
1
+ import { Incantation, ArgIncantation, type LOCAL } from "../incantation";
2
+ import { UnrecoverableError } from "../../errors";
3
+
4
+ import { DesmosColour } from "../../desmos";
5
+
6
+
7
+ export class ColourIncantation extends ArgIncantation<LOCAL>
8
+ {
9
+ override readonly description
10
+ = ""
11
+
12
+ override readonly identifier = "color"
13
+ override readonly alias = "colour"
14
+ override readonly requires_arg = true
15
+ override readonly arg_type = Incantation.ArgType.ENUM
16
+
17
+ override apply(target: Desmos.ExpressionState, data: DesmosColour)
18
+ {
19
+ super.require_expr_type(target.type, "expression");
20
+ target.color = data;
21
+ }
22
+
23
+ override evaluate_arg(data: string): DesmosColour
24
+ {
25
+ switch (data.trim()) {
26
+ case "RED": return DesmosColour.RED;
27
+ case "BLUE": return DesmosColour.BLUE;
28
+ case "GREEN": return DesmosColour.GREEN;
29
+ case "PURPLE": return DesmosColour.PURPLE;
30
+ case "ORANGE": return DesmosColour.ORANGE;
31
+ case "BLACK": return DesmosColour.BLACK;
32
+ default:
33
+ throw new UnrecoverableError(
34
+ `Invalid colour: \`${data}\``
35
+ );
36
+ }
37
+ }
38
+ }
@@ -0,0 +1,16 @@
1
+ import { Incantation, type LOCAL } from "../incantation";
2
+
3
+
4
+ export class DashedIncantation extends Incantation<LOCAL>
5
+ {
6
+ override readonly description
7
+ = "Render a block as a dashed line."
8
+
9
+ override readonly identifier = "dashed"
10
+
11
+ override apply(target: Desmos.ExpressionState)
12
+ {
13
+ super.require_expr_type(target.type, "expression");
14
+ target.lineStyle = Desmos.Styles.DASHED;
15
+ }
16
+ }
@@ -0,0 +1,24 @@
1
+ import { Incantation, ArgIncantation, type LOCAL } from "../incantation";
2
+
3
+
4
+ interface FillOptions
5
+ {
6
+ opacity: number;
7
+ }
8
+
9
+
10
+ export class FillIncantation extends ArgIncantation<LOCAL>
11
+ {
12
+ override readonly description
13
+ = "Change fill styles for a rendered block."
14
+
15
+ override readonly identifier = "fill"
16
+ override readonly requires_arg = true
17
+ override readonly arg_type = Incantation.ArgType.OBJECT
18
+
19
+ override apply(target: Desmos.ExpressionState, data: FillOptions)
20
+ {
21
+ super.require_expr_type(target.type, "expression");
22
+ target.fillOpacity = data.opacity;
23
+ }
24
+ }
@@ -0,0 +1,16 @@
1
+ import { Incantation, type LOCAL } from "../incantation";
2
+
3
+
4
+ export class HideIncantation extends Incantation<LOCAL>
5
+ {
6
+ override readonly description
7
+ = "Hide rendering for a block. This includes graphs, points, polygons, etc."
8
+
9
+ override readonly identifier = "hide"
10
+
11
+ apply(target: Desmos.ExpressionState)
12
+ {
13
+ super.require_expr_type(target.type, "expression");
14
+ target.hidden = true;
15
+ }
16
+ }
@@ -0,0 +1,27 @@
1
+ import { Incantation, type LOCAL } from "../incantation";
2
+ import { AnimIncantation } from "./anim";
3
+
4
+ import { ColourIncantation } from "./colour";
5
+ import { DashedIncantation } from "./dashed";
6
+ import { FillIncantation } from "./fill";
7
+ import { HideIncantation } from "./hide";
8
+ import { LineIncantation } from "./line";
9
+ import { NoLineIncantation } from "./no-line";
10
+ import { PointIncantation } from "./point";
11
+ import { SecretIncantation } from "./secret";
12
+ import { SliderIncantation } from "./slider";
13
+
14
+
15
+ export const LOCAL_INCANTATIONS: Incantation<LOCAL>[] =
16
+ [
17
+ new AnimIncantation(),
18
+ new ColourIncantation(),
19
+ new DashedIncantation(),
20
+ new FillIncantation(),
21
+ new HideIncantation(),
22
+ new LineIncantation(),
23
+ new NoLineIncantation(),
24
+ new PointIncantation(),
25
+ new SecretIncantation(),
26
+ new SliderIncantation(),
27
+ ];
@@ -0,0 +1,29 @@
1
+ import { Incantation, ArgIncantation, type LOCAL } from "../incantation";
2
+
3
+
4
+ interface LineOptions
5
+ {
6
+ style?: keyof typeof Desmos.Styles; // TODO allow raw enum
7
+ width?: number;
8
+ opacity?: number;
9
+ }
10
+
11
+
12
+ export class LineIncantation extends ArgIncantation<LOCAL>
13
+ {
14
+ override readonly description
15
+ = "Change line styles for a rendered block."
16
+
17
+ override readonly identifier = "line"
18
+ override readonly requires_arg = true
19
+ override readonly arg_type = Incantation.ArgType.OBJECT
20
+
21
+ override apply(target: Desmos.ExpressionState, data: LineOptions)
22
+ {
23
+ super.require_expr_type(target.type, "expression");
24
+
25
+ if (data.style != undefined) target.lineStyle = data.style;
26
+ if (data.width != undefined) target.lineWidth = data.width;
27
+ if (data.opacity != undefined) target.lineOpacity = data.opacity;
28
+ }
29
+ }
@@ -0,0 +1,16 @@
1
+ import { Incantation, type LOCAL } from "../incantation";
2
+
3
+
4
+ export class NoLineIncantation extends Incantation<LOCAL>
5
+ {
6
+ override readonly description
7
+ = "Disable rendering lines for a block."
8
+
9
+ override readonly identifier = "no-line"
10
+
11
+ override apply(target: Desmos.ExpressionState)
12
+ {
13
+ super.require_expr_type(target.type, "expression");
14
+ target.lines = false;
15
+ }
16
+ }
@@ -0,0 +1,29 @@
1
+ import { Incantation, ArgIncantation, type LOCAL } from "../incantation";
2
+
3
+
4
+ interface PointStyles
5
+ {
6
+ style?: keyof typeof Desmos.Styles;
7
+ size?: number;
8
+ opacity?: number;
9
+ }
10
+
11
+
12
+ export class PointIncantation extends ArgIncantation<LOCAL>
13
+ {
14
+ override readonly description
15
+ = ""
16
+
17
+ override readonly identifier = "point"
18
+ override readonly requires_arg = true
19
+ override readonly arg_type = Incantation.ArgType.OBJECT
20
+
21
+ override apply(target: Desmos.ExpressionState, data: Partial<PointStyles>)
22
+ {
23
+ super.require_expr_type(target.type, "expression");
24
+
25
+ if (data.style != undefined) target.pointStyle = data.style;
26
+ if (data.size != undefined) target.pointSize = data.size;
27
+ if (data.opacity != undefined) target.pointOpacity = data.opacity;
28
+ }
29
+ }
@@ -0,0 +1,16 @@
1
+ import { Incantation, type LOCAL } from "../incantation";
2
+
3
+
4
+ export class SecretIncantation extends Incantation<LOCAL>
5
+ {
6
+ override readonly description
7
+ = "Turn a block into a secret expression, which is hidden from the end user."
8
+
9
+ override readonly identifier = "secret"
10
+
11
+ override apply(target: Desmos.ExpressionState)
12
+ {
13
+ super.require_expr_type(target.type, "expression");
14
+ target.secret = true;
15
+ }
16
+ }
@@ -0,0 +1,27 @@
1
+ import { Incantation, ArgIncantation, type LOCAL } from "../incantation";
2
+
3
+
4
+ interface SliderBounds
5
+ {
6
+ min?: number | string;
7
+ max?: number | string;
8
+ step?: number | string;
9
+ }
10
+
11
+
12
+ export class SliderIncantation extends ArgIncantation<LOCAL>
13
+ {
14
+ override readonly description
15
+ = "Set the bounds of the slider for a variable."
16
+
17
+ override readonly identifier = "slider"
18
+ override readonly requires_arg = true
19
+ override readonly arg_type = Incantation.ArgType.OBJECT
20
+
21
+ override apply(target: Desmos.ExpressionState, data: SliderBounds)
22
+ {
23
+ super.require_expr_type(target.type, "expression");
24
+ // @ts-expect-error: outdated types
25
+ target.sliderBounds = data;
26
+ }
27
+ }
@@ -0,0 +1,60 @@
1
+ import { UnrecoverableError } from "../errors";
2
+ import { Incantation, ArgIncantation } from "../magic";
3
+
4
+
5
+ export namespace Ast
6
+ {
7
+ /** What kind of parse result this is. */
8
+ export enum Kind
9
+ {
10
+ EXPRESSION = "Expression",
11
+ INCANTATION_INVOCATION = "Incantation-Invocation",
12
+ INVALID_INCANTATION = "Invalid-Incantation",
13
+ }
14
+
15
+
16
+ /** A Desmos expression to add to the calculator. */
17
+ export interface Expression
18
+ {
19
+ kind: Kind.EXPRESSION
20
+ data: Desmos.ExpressionState
21
+ incantations: Array<
22
+ | IncantationInvocation<Incantation.Effect.LOCAL>
23
+ | InvalidInvocation
24
+ >
25
+ }
26
+
27
+
28
+ /** A pending incantation invocation that requires applying its argument (if any), then applying its effect. */
29
+ export type IncantationInvocation<Effect extends Incantation.Effect = Incantation.Effect> =
30
+ | {
31
+ kind: Kind.INCANTATION_INVOCATION
32
+ incantation: Incantation<Effect>
33
+ arg_raw: undefined
34
+ }
35
+ | {
36
+ kind: Kind.INCANTATION_INVOCATION
37
+ incantation: ArgIncantation<Effect>
38
+ arg_raw: string | undefined
39
+ };
40
+
41
+ /**
42
+ * An invalid invantation invocation that raised an error when parsed.
43
+ *
44
+ * This will be propogated to the user as an extra Desmos text expression (unless they have `errors: false` configured).
45
+ */
46
+ export interface InvalidInvocation
47
+ {
48
+ kind: Kind.INVALID_INCANTATION
49
+ incantation: Incantation
50
+ arg_raw?: string
51
+ error: UnrecoverableError
52
+ }
53
+ }
54
+
55
+ /** An abstract object produced by parsing a block of source code. */
56
+ export type Ast =
57
+ | Ast.Expression
58
+ | Ast.IncantationInvocation
59
+ | Ast.InvalidInvocation
60
+ ;