Guide · 10 of 15
Organic chemistry
A molecule is drawn from a SMILES string in a scene plane that says aspect: equal. SMILES writes a structure as text: C is carbon, = and # are double and triple bonds, a branch goes in parentheses, a ring is a digit that opens and closes, and lowercase letters are aromatic (c1ccccc1 is benzene). Hydrogens are filled in from the valences, so CCO is ethanol. Elements outside C, N, O, S, P, F, Cl, Br, I need square brackets ([Na+]). The compiler does the drawing, so a molecule is plain objects the rest of the scene can point at. In a scene space3 the same SMILES is a ball-and-stick model (view: ball) with the true bond angles, which spins with the camera like any other 3D figure. A reaction is a reaction SMILES (reactants>>products) with atom maps that says which atom becomes which, and morphs the one picture into the other as by goes from 0 to 1. A name exercise has the student type the IUPAC name of a drawn structure.
molecule#
Draws a molecule from its SMILES string, the way the book draws it. full shows every atom and every hydrogen (methane is a carbon with four bonds), condensed writes the hydrogens into the carbons (CH3, CH2) and draws only the chain, skeletal is the zig-zag with a bare line for each carbon. A single ring of benzene gets its circle. The scene must say aspect: equal, so the bond angles stay true. at is where the middle of the drawing sits (default (0, 0)). size is the length of one drawn bond in scene units (default 1; in full view a C-C bond is two of them, because the C-H bonds are one). Atom text grows with the scene, so a bigger size means bigger letters. A SMILES that does not parse, or an atom with too many bonds, is a compile error that points at the column. The drawing is ordinary objects: <id> names the whole molecule in indicate, focus, surround and morph, <id>_C2 is the second carbon (counted in SMILES order, <id>_O1, <id>_Cl1), <id>_C1_C2 is the bond between two atoms and <id>_C1_H2 a bond to a drawn hydrogen. A carbon with no letter in the skeletal view has no object of its own, only its bonds do. A functional group in it is a group too: <id>_OH lights every hydroxyl (its O, its H and the bond between them), and the names are OH, COOH, CHO, ketone, ester, ether, NH2, F, Cl, Br, I, alkene, alkyne and benzene (a group the molecule does not have is an error in indicate). Labels read the molecule: {formula(<id>)} is its formula in Hill order (C₂H₆O, or C_{2}H_{6}O in a tex label) and {mass(<id>)} its molar mass in g/mol, both filled in at compile time from a molecule declared above the label. To move or turn a molecule with a param, put it in a group.
In a scene space3 the same molecule is view: ball, the default there: balls and sticks with the real bond lengths and angles, built by the compiler (methane is a tetrahedron with 109.5 degrees between the bonds, ethene is flat with 120, ethyne is a straight line with 180, and a chain of carbons zig-zags). at is then (x, y, z), size scales the whole model (default 1 is about one angstrom per scene unit, so a scene from -2 to 2 fits a small molecule), and the flag labels writes the element letter on each ball. Carbon is dark, hydrogen light, oxygen red, nitrogen blue, the halogens green and orange and purple, and a color on the molecule paints every ball one colour. A double bond is two sticks and a triple is three, lying in the plane of the molecule. An aromatic bond is one stick. view: ball in a plane scene, and full, condensed or skeletal in a space3 scene, are compile errors. The model is ordinary ball3 and segment3 objects, so the camera, slider for the spin and indicate, focus and the groups work as in the flat view. Every atom is named like the flat view (<id>_C1, <id>_H3, <id>_C1_H2, <id>_C1_C2) and can stand in for a point in any 3D position: arc3 a = [m_H1, m_C1, m_H2] { label: "109.5°" } marks the angle between two bonds, and segment3 or label3 take the same names.
molecule <id> = "" { [at: (x, y)], [view: full | condensed | skeletal | ball], [size: <n>], [labels], [props] }
| prop | type | description |
|---|---|---|
| at | (x, y) or (x, y, z) | where the middle of the drawing sits, (x, y) or (x, y, z) in space3 (default the origin) |
| view | full | condensed | skeletal | ball | how it is drawn (default full in a plane scene, ball in space3) |
| size | number | scene units per drawn bond, text scales with it (default 1) |
| labels | flag | write the element letter on each ball |
Example
reaction#
A reaction drawn as a morph: at by: 0 the reactants stand side by side, at by: 1 the products do, and in between every atom is on its way. It is written as a reaction SMILES, reactants and products either side of >>, with a number after a colon in a bracket atom saying which atom becomes which ([CH2:1]=[CH2:2].[Br:3][Br:4]>>[Br:3][CH2:1][CH2:2][Br:4] is bromine adding across ethene). A mapped atom travels from its place among the reactants to its place among the products. A bond on both sides stays and follows its atoms. A bond only among the reactants fades out over the first half of by (a double bond that becomes single fades just its second line, the pi bond), and one only among the products fades in over the second half. An atom with no map fades out (reactants) or in (products), so map everything that should travel. Hydrogens are drawn as in the full view of a molecule and need no map: a mapped atom keeps its hydrogens, and one hydrogen lost where another is gained (the H of HBr landing on a carbon) is paired by distance and travels. A mapped hydrogen needs a mapped atom to sit on ([H:4][Br:5]). The compiler checks the chemistry: every element, hydrogens included, and the charge are conserved, a map is used once on each side, and a mapped atom keeps its element. by takes any expression, so a slider, a timeline step or a button drives it. The scene needs aspect: equal. The drawing is centred on at (default (0, 0)), size is the scene length of one bond. The products are laid out from the reactants: every mapped heavy atom stays where it was, an atom or group that joins from another molecule lands on a free 90 degree spot of its new neighbour, and the hydrogens fill the free spots of their atom. That holds for additions, substitutions, esterification and the like, where the skeleton is kept. A reaction that closes or opens a ring, or whose skeleton changes shape, falls back to laying the products out on their own and fitting them to the reactants, so atoms may swing on the way (write each molecule's atoms in the same order on both sides to help). Parts: <id>_broken and <id>_formed (the bonds that break and form), <id>_m1 (the atom with map 1 and its bonds), <id>_C1 (the first carbon among the reactants, the products' new atoms count on from there), <id>_C1_C2 (a bond), <id>_H1. Put an arrow and conditions beside it with a vector and a label.
reaction <id> = ">> { by: <expr from 0 to 1>, [at: (x, y)], [size: <n>], [props] }"
| prop | type | description |
|---|---|---|
| by* | expr | how far the reaction has gone, 0 (reactants) to 1 (products) |
| at | (x, y) | where the middle of the drawing sits (default (0, 0)) |
| size | number | scene units per drawn bond, text scales with it (default 1) |
Example
name#
The student sees the structure drawn from molecule and types its IUPAC name. The right answer is worked out from the SMILES by the compiler (the same code that names every molecule), so it cannot be mistyped, and a name the compiler cannot work out (a rare group or a strange skeleton) needs answer: "...". An answer: for a molecule the compiler can name must agree with it, or the build fails. Typed names are compared after folding spelling that does not matter: capitals, spaces, hyphens and commas (2,2-dimethylbutane = 2 2 dimethyl butane), Arabic-Indic digits and the hamza and ya variants of Arabic letters, and حمض with or without ال. accept lists extra names to count (a trivial name the book also allows). lang picks the language of the name, and defaults to Arabic when the ask is written in Arabic, else English; the field then types right to left. The structure always draws left to right. wrong "<name>" names a classic mistake (not the longest chain, numbering from the wrong end): its "why" shows when a student types that name, and -> "detour-id" sends them to a scaffold made for it (see onwrong). A wrong name that folds to a right one is a compile error. Everything else an exercise takes works: hint, !, skill:, onwrong:, a worked ladder.
name { ask "..." molecule: "" [view: full | condensed | skeletal] [lang: en | ar] [answer: "" ] [accept: ["" , ...]] [wrong "" "why" [-> "detour-id" [retry]]] }
| prop | type | description |
|---|---|---|
| molecule* | string | the SMILES of the structure shown |
| view | full | condensed | skeletal | how it is drawn (default condensed) |
| lang | en | ar | the language of the name (default from the ask) |
| answer | string | the name, only for a molecule the compiler cannot name |
| accept | string[] | extra names that count (repeatable) |
| wrong | "<name>" "why" [-> "slide-id" [retry]] | a known wrong name, its feedback and its own detour (repeatable) |
Example