|
| 1 | +# chemformula |
| 2 | +Typst Packages for easy and extensible chemical formula formatting. |
| 3 | +This provide a `ch` function for writing chemical notations. |
| 4 | +Chemformula uses Typst's [math mode](https://typst.app/docs/reference/math/) to [evaluate](https://typst.app/docs/reference/foundations/eval/) the input string (or raw) in the `ch` function and render them into the document. |
| 5 | +# Usage |
| 6 | +Import this pacakge by |
| 7 | +```typ |
| 8 | +#import "@preview/chemformula:0.1.1": ch |
| 9 | +``` |
| 10 | +## Examples |
| 11 | + |
| 12 | +### Chemical Formulae |
| 13 | +The number preceding by other letters is subscripted by default. |
| 14 | +```typ |
| 15 | +#ch("H2O") |
| 16 | +
|
| 17 | +#ch("Sb2O3") |
| 18 | +``` |
| 19 | +<img alt="example-01" src="https://github.com/user-attachments/assets/17373f66-373d-49ed-b497-16241df870c4" /> |
| 20 | + |
| 21 | +### Chemical Equations |
| 22 | +You can use `->` to draw arrow. The length will changes according to the content being above or below the arrow. The arrow is rendered using Typst's [stretch function](https://typst.app/docs/reference/math/stretch/). |
| 23 | +```typ |
| 24 | +#ch("CO2 + C -> 2 CO") |
| 25 | +
|
| 26 | +// Multilines are allowed! |
| 27 | +#ch("Hg^2+ ->[I^-] HgI2 |
| 28 | + ->[I^-] [Hg^II I4]^2- ") |
| 29 | +``` |
| 30 | +<img alt="example-02" src="https://github.com/user-attachments/assets/c986a131-9765-4118-9cc9-303ce88d0c16" /> |
| 31 | + |
| 32 | +### Charges |
| 33 | +Plus and minus signs coming after the text are superscript positioned by default. However, you may use `^` operator to raise them upper. The `^` operator will superscript the content until a space or a semicolon (`;`) is typed. |
| 34 | +```typ |
| 35 | +#ch("H+") |
| 36 | +
|
| 37 | +#ch("CrO4^2-") // or |
| 38 | +#ch("CrO4 ^2-") // IUPAC recommended |
| 39 | +
|
| 40 | +#ch("[AgCl2]-") |
| 41 | +
|
| 42 | +#ch("Y^99+") // or |
| 43 | +#ch("Y^(99+)") // Same |
| 44 | +``` |
| 45 | +<img alt="example-03" src="https://github.com/user-attachments/assets/733f34c4-b12e-4c58-a569-897b6f37dd99" /> |
| 46 | + |
| 47 | +### Oxidation States |
| 48 | +Typing `^^` gives the ability to put things above the elements. This operator captures content in parenthesis/or until black space is met. |
| 49 | +```typ |
| 50 | +#ch("Fe^^II Fe^^III_2 O4") // or |
| 51 | +#ch("Fe^^(II)Fe^^(III)_(2)O4") // Same |
| 52 | +``` |
| 53 | +<img alt="example-04" src="https://github.com/user-attachments/assets/998bb37f-5368-41f6-b847-676a946af992" /> |
| 54 | + |
| 55 | +### Stoichiometric Numbers |
| 56 | +Since the content is evaluated in math mode, the fractions are rendered by default. If one space is present between the compound and digits, then thin space is used. If more than one spaces are typed, then full one normal space will be used. |
| 57 | +```typ |
| 58 | +#ch("2H2O") // Tight |
| 59 | +
|
| 60 | +#ch("2 H2O") // Spaced |
| 61 | +
|
| 62 | +#ch("2 H2O") // Very Spaced |
| 63 | +
|
| 64 | +#ch("1/2 H2O") // Automatic Fractions |
| 65 | +
|
| 66 | +#ch("1\/2 H2O") // |
| 67 | +``` |
| 68 | +<img alt="example-05" src="https://github.com/user-attachments/assets/9713350a-43db-416d-8bc7-52ca6a48ae6a" /> |
| 69 | + |
| 70 | +### Nuclides, Isotopes |
| 71 | +The syntax writing nuclides is *preceding* the `^` for mass number or `_` for atomic number with space/or begining of the string. Otherwise, the operator will attach to the preceding content. |
| 72 | +```typ |
| 73 | +#ch("^227_90 Th+") |
| 74 | +
|
| 75 | +#ch("^227_(90)Th+") |
| 76 | +
|
| 77 | +#ch("^0_-1 n-") |
| 78 | +
|
| 79 | +#ch("_-1^0 n-") |
| 80 | +``` |
| 81 | +<img alt="example-06" src="https://github.com/user-attachments/assets/f09940cb-58db-4a9d-a90c-f9d629f369d4" /> |
| 82 | + |
| 83 | +### Parenthesis, Braces, Brackets |
| 84 | +In Typst, parentheses are automatically sized by default. If you finding this ugly, you can disrupt them by typing `\` before the parentheses group. To force a group of parenthesis between substances to big-size, wrap the whole reaction with [display](https://typst.app/docs/reference/introspection/counter/#definitions-display) function. |
| 85 | +```typ |
| 86 | +#ch("(NH4)2S") // Automatic sizing |
| 87 | +
|
| 88 | +#ch("[{(X2)3}2]^3+") |
| 89 | +
|
| 90 | +#ch("\[{(X2)3}2]^3+") // To disable this behavior, just type `\` |
| 91 | +
|
| 92 | +$display(ch("CH4 + 2(O2 + 7/2N2)"))$ // Hack with math mode |
| 93 | +``` |
| 94 | +<img alt="example-07" src="https://github.com/user-attachments/assets/37520c8e-d760-406a-9e95-9ac9e870a193" /> |
| 95 | + |
| 96 | +### States of Aggregation |
| 97 | +Normally, lower case letters are considered math variables, and multiple form of them will be symbol/variable call. This follows the Typst's naive math syntax. However, `(aq)` is preserved by the parser as math variable that evaluates to `$a q$`. |
| 98 | +```typ |
| 99 | +#ch("H2(aq)") |
| 100 | +
|
| 101 | +#ch("CO3^2-_((aq))") |
| 102 | +
|
| 103 | +#ch("NaOH(aq, $oo$)") |
| 104 | +``` |
| 105 | +<img alt="example-08" src="https://github.com/user-attachments/assets/a73906d3-2fec-47f7-8573-be5919a43c06" /> |
| 106 | + |
| 107 | +You can use `$..$` syntax for escaping the parser so that the content inside will be directly evaluated by math mode. |
| 108 | + |
| 109 | + |
| 110 | +### Radical Dots |
| 111 | +`*` or `.` in superscript and subscript mode will be used as radical notation. This uses `sym.bullet` to display. |
| 112 | +```typ |
| 113 | +#ch("OCO^*-") |
| 114 | +
|
| 115 | +#ch("NO^((2*)-)") |
| 116 | +``` |
| 117 | +<img alt="example-09" src="https://github.com/user-attachments/assets/81bd6016-e607-44a0-80c9-c1d9dd58dafe" /> |
| 118 | + |
| 119 | +### Escaped Modes |
| 120 | +Contents inside `$..$` will be escaped by the parser and evaluated in math mode directly bypassing other grammars. So you can type greek letters or other variables in math in this mode, for example. |
| 121 | +```typ |
| 122 | +// Use Math Mode! |
| 123 | +#ch("NO_x") is the same as #ch("NO_$x$") |
| 124 | +
|
| 125 | +#ch("Fe^n+") is the same as #ch("Fe^$n+$") |
| 126 | +
|
| 127 | +#ch("Fe(CN)_$6/2$") // Fractions! |
| 128 | +
|
| 129 | +#ch("$#[*CO*]$_2^3") // bold text |
| 130 | +
|
| 131 | +// Or just type texts... |
| 132 | +#ch("mu\"-\"Cl") // Hyphen Escaped |
| 133 | +``` |
| 134 | +<img alt="example-10" src="https://github.com/user-attachments/assets/c8f04a9f-8969-431f-84b8-390a7323b192" /> |
| 135 | + |
| 136 | +## Reaction Arrows |
| 137 | +```typ |
| 138 | +#ch("A -> B") |
| 139 | +
|
| 140 | +#ch("A <- B") |
| 141 | +
|
| 142 | +#ch("A <-> B") |
| 143 | +
|
| 144 | +#ch("A <=> B") |
| 145 | +``` |
| 146 | +<img alt="example-11" src="https://github.com/user-attachments/assets/b75faaf3-ca93-467e-b6c6-6303c29da129" /> |
| 147 | + |
| 148 | +### Above/Below Arrow Text |
| 149 | +```typ |
| 150 | +#ch("A ->[Delta] B") |
| 151 | +
|
| 152 | +#ch("A <=>[Above][Below] B") |
| 153 | +
|
| 154 | +#ch("CH3COOH <=>[+ OH-][+ H+] CH3COO-") |
| 155 | +``` |
| 156 | +<img alt="example-12" src="https://github.com/user-attachments/assets/34d651ce-e4c3-4933-833e-d3b36e33bcb8" /> |
| 157 | + |
| 158 | +### Precipitation and Gas |
| 159 | +This feature has *very* dedicate syntax: the `^` or `v` must precede -and- folows by white space. |
| 160 | +```typ |
| 161 | +#ch("SO4^2- + Ba^2+ -> BaSO4 v") |
| 162 | +
|
| 163 | +#ch("A v B v -> B ^ B ^") |
| 164 | +``` |
| 165 | +<img alt="example-13" src="https://github.com/user-attachments/assets/f52e47bb-ed98-487b-a525-ca3f567de329" /> |
| 166 | + |
| 167 | +### Alignments |
| 168 | +```typ |
| 169 | +$ ch("A &-> B") \ |
| 170 | + ch("B &-> C + D") |
| 171 | +$ |
| 172 | +``` |
| 173 | +<img alt="example-14" src="https://github.com/user-attachments/assets/9bf7f6a3-92bf-40b8-a9fc-20a178b10bcd" /> |
| 174 | + |
| 175 | +### More Examples |
| 176 | +Integration seamlessly with Typst's math mode. |
| 177 | +```typ |
| 178 | +$ |
| 179 | + ch("Zn^2+ <=>[+ 2 OH-][+ 2 H+]") |
| 180 | + limits(ch("Zn(OH)2 v"))_"amphoteres Hydroxid" |
| 181 | + ch("<=>[+ 2 OH-][+ 2H+]") |
| 182 | + limits(ch("[Zn(OH)4]^2-"))_"Hydroxozikat" |
| 183 | +$ |
| 184 | +``` |
| 185 | +<img alt="example-15" src="https://github.com/user-attachments/assets/4da96416-ec73-4100-af90-23610ac7b3b1" /> |
| 186 | + |
| 187 | +You can use user-defined functions in `ch`. However, you must add the definition of this function into the `scope` parameter of `ch`. |
| 188 | + |
| 189 | +```typ |
| 190 | +#let tg = text.with(fill: olive) |
| 191 | +#let ch = ch.with(scope: (tg: tg, ch: ch)) |
| 192 | +$ ch("Cu^^II Cl2 + K2CO3 -> tg(Cu^^II)CO3 v + 2 KCl") $ |
| 193 | +
|
| 194 | +$ ch("Hg^2+ ->[I-] HgI2 |
| 195 | + ->[I-] [Hg^II I4]^2- |
| 196 | +") $ |
| 197 | +``` |
| 198 | +<img alt="example-16" src="https://github.com/user-attachments/assets/a870ad91-612e-471f-8bf6-ea8211311e08" /> |
| 199 | + |
| 200 | + |
| 201 | +# Acknowledgement |
| 202 | +This packages' examples and syntax are highly inspired by [mhchem](https://ctan.org/pkg/mhchem?lang=en) package. Please feel free to give any suggestions for improving the feature of this package! |
0 commit comments