Skip to content

Commit cd84e9e

Browse files
tryptophawaAnts-Aareelegaanz
authored
typsium:0.3.0 (#2737)
Co-authored-by: Ants-Aare <[email protected]> Co-authored-by: Ana Gelez <[email protected]>
1 parent 0486786 commit cd84e9e

20 files changed

+2733
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 β-吲哚基丙氨酸
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
VERSION := $(shell grep '^version' typst.toml | awk -F ' = ' '{print $$2}' | tr -d '"')
2+
PACKAGE_NAME := $(shell grep '^name' typst.toml | awk -F ' = ' '{print $$2}' | tr -d '"')
3+
TARGET_DIR=./$(PACKAGE_NAME)/$(VERSION)
4+
5+
6+
check:
7+
typst compile ./src/lib.typ
8+
rm ./src/lib.pdf
9+
10+
module:
11+
mkdir -p $(TARGET_DIR)
12+
mkdir -p $(TARGET_DIR)/src
13+
cp ./typst.toml $(TARGET_DIR)/typst.toml
14+
cp ./LICENSE $(TARGET_DIR)/
15+
cp -r ./src/* $(TARGET_DIR)/src/
16+
awk '{gsub("https://typst.app/universe/package/$(PACKAGE_NAME)", "https://github.com/Typsium/$(PACKAGE_NAME)");print}' ./README.md > $(TARGET_DIR)/README.md
17+
18+
19+
20+
bump-minor:
21+
@current_version=$$(grep '^version' typst.toml | awk -F ' = ' '{print $$2}' | tr -d '"'); \
22+
new_version=$$(echo $$current_version | awk -F. '{printf "%d.%d.%d", $$1, $$2+1, $$3}'); \
23+
sed -i '' "s|^version = .*|version = \"$$new_version\"|" typst.toml; \
24+
sed -i '' "s|@preview/typsium:$$current_version|@preview/typsium:$$new_version|" README.md; \
25+
echo "Version bumped to $$new_version"
26+
bump-patch:
27+
@current_version=$$(grep '^version' typst.toml | awk -F ' = ' '{print $$2}' | tr -d '"'); \
28+
new_version=$$(echo $$current_version | awk -F. '{printf "%d.%d.%d", $$1, $$2, $$3+1}'); \
29+
sed -i '' "s|^version = .*|version = \"$$new_version\"|" typst.toml; \
30+
sed -i '' "s|@preview/typsium:$$current_version|@preview/typsium:$$new_version|" README.md; \
31+
echo "Version bumped to $$new_version"
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
[![Typst Package](https://img.shields.io/badge/dynamic/toml?url=https%3A%2F%2Fraw.githubusercontent.com%2FTypsium%2Ftypsium%2Fmain%2Ftypst.toml&query=%24.package.version&prefix=v&logo=typst&label=package&color=239DAD)](https://typst.app/universe/package/typsium)
2+
[![MIT License](https://img.shields.io/badge/license-MIT-blue)](https://github.com/Typsium/typsium/blob/main/LICENSE)
3+
![User Manual](https://img.shields.io/badge/manual-.pdf-purple)
4+
5+
# Write beautiful chemical formulas and reactions with Typsium
6+
## Usage
7+
```typst
8+
#import "@preview/typsium:0.3.0":*
9+
```
10+
Enter your chemical formula or reaction into the `#ce"` method like this:
11+
```typst
12+
#ce("[Cu(H2O)4]^2+ + 4NH3 -> [Cu(NH3)4]^2+ + 4H2O")
13+
```
14+
![result](https://raw.githubusercontent.com/Typsium/typsium/main/tests/README-graphic1/ref/1.png)
15+
16+
You can also embed any kind of content into your chemical reactions like by using square brackets instead of a passing in a string. This will also apply any styling to the reaction.
17+
18+
> **Warning:** Currently, brackets inside another bracket will not be parsed correctly.
19+
20+
```typst
21+
#ce[...]
22+
```
23+
24+
![result2](https://raw.githubusercontent.com/Typsium/typsium/main/tests/README-graphic1/ref/1.png)
25+
26+
There are many different kinds of arrows to choose from.
27+
```typst
28+
#ce[->]\
29+
#ce[=>]\
30+
#ce[<=>]\
31+
#ce[<=]\
32+
#ce("<->")\
33+
#ce("<-")\
34+
```
35+
36+
And you can add additional arguments to them (such as the top or bottom text) by adding square brackets.
37+
38+
```typst
39+
#ce("->[top text][bottom text]")
40+
```
41+
42+
The molecule parsing is flexible and allows many different ways of writing, so you can just copy paste in your formulas and they will probably work. Oxidation numbers can be added like this`^^`, radicals can be added like this`.` and hydration groups can be added like this`*`.
43+
44+
You can use many kinds of brackets. they will auto scale by default, but you can disable it with a show rule.
45+
46+
Inline formulas often need to be a bit more compact, for this purpose there is an `affect-layout` rule, which can be toggled on and off for each part of the reaction separately.
47+
48+
You can use Typsium inside other packages and the styling will be consistent across the entire document.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// #import "data-model.typ": get-element-counts, get-element, get-weight, define-molecule, define-hydrate
2+
// #import "display-shell-configuration.typ": get-electron-configuration,get-shell-configuration,display-electron-configuration,
3+
#import "parse-formula-intermediate-representation.typ": string-to-reaction
4+
#import "parse-content-intermediate-representation.typ": content-to-reaction
5+
#import "typing.typ": set-arrow, set-element, set-group, set-molecule, set-reaction, elembic, fields, selector
6+
#import "model/arrow-element.typ": arrow
7+
#import "model/element-element.typ": element
8+
#import "model/group-element.typ": group
9+
#import "model/molecule-element.typ": molecule
10+
#import "model/reaction-element.typ": reaction
11+
12+
#let ce(formula) = {
13+
14+
show "*": sym.dot
15+
16+
if type(formula) == str{
17+
let result = string-to-reaction(formula)
18+
if result.len() == 1{
19+
result.at(0)
20+
} else {
21+
reaction(result)
22+
}
23+
} else if type(formula) == content{
24+
let result = content-to-reaction(formula)
25+
if result.len() == 1{
26+
result.at(0)
27+
} else {
28+
reaction(result)
29+
}
30+
}
31+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#import "@preview/elembic:1.1.0" as e
2+
3+
#import "../utils.typ": (
4+
get-arrow,
5+
)
6+
7+
#let arrow(
8+
kind: 0,
9+
top: (),
10+
bottom: (),
11+
) = { }
12+
13+
#let draw-arrow(it) = {
14+
math.attach(
15+
math.stretch(
16+
get-arrow(it.kind),
17+
size: 100% + 2em,
18+
),
19+
t: for top-child in it.top {
20+
top-child
21+
},
22+
b: for bottom-child in it.bottom {
23+
bottom-child
24+
},
25+
)
26+
}
27+
28+
#let arrow = e.element.declare(
29+
"arrow",
30+
prefix: "@preview/typsium:0.3.0",
31+
32+
display: draw-arrow,
33+
34+
fields: (
35+
e.field("kind", int, default: 0),
36+
e.field("top", e.types.array(e.types.any), default: ()),
37+
e.field("bottom", e.types.array(e.types.any), default: ()),
38+
),
39+
)
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#import "@preview/elembic:1.1.0" as e
2+
#import "../utils.typ": (
3+
count-to-content,
4+
charge-to-content,
5+
oxidation-to-content,
6+
none-coalesce,
7+
customizable-attach,
8+
)
9+
10+
#let element(
11+
symbol: "",
12+
count: 1,
13+
charge: 0,
14+
oxidation: none,
15+
a: none,
16+
z: none,
17+
rest: none,
18+
radical: false,
19+
affect-layout: true,
20+
roman-oxidation: true,
21+
roman-charge: false,
22+
radical-symbol: sym.dot,
23+
negative-symbol: math.minus,
24+
positive-symbol: math.plus,
25+
) = { }
26+
27+
#let draw-element(it) = {
28+
let base = it.symbol
29+
if it.rest != none {
30+
if type(it.rest) == content {
31+
base += it.rest
32+
} else if type(it.rest) == int {
33+
base += box['] * it.rest
34+
}
35+
}
36+
37+
let mass-number = it.a
38+
if type(it.a) == int {
39+
mass-number = [#it.a]
40+
}
41+
let atomic-number = it.z
42+
if type(it.z) == int {
43+
atomic-number = [#it.z]
44+
}
45+
46+
customizable-attach(
47+
base,
48+
t: oxidation-to-content(
49+
it.oxidation,
50+
roman: it.roman-oxidation,
51+
negative-symbol: it.negative-symbol,
52+
positive-symbol: it.positive-symbol,
53+
),
54+
tr: charge-to-content(
55+
it.charge,
56+
radical: it.radical,
57+
roman: it.roman-charge,
58+
radical-symbol: it.radical-symbol,
59+
negative-symbol: it.negative-symbol,
60+
positive-symbol: it.positive-symbol,
61+
),
62+
br: count-to-content(it.count),
63+
tl: mass-number,
64+
bl: atomic-number,
65+
affect-layout: it.affect-layout,
66+
)
67+
}
68+
}
69+
70+
#let element = e.element.declare(
71+
"element",
72+
prefix: "@preview/typsium:0.3.0",
73+
74+
display: draw-element,
75+
76+
fields: (
77+
e.field("symbol", e.types.union(str, content), default: none, required: true),
78+
e.field("count", e.types.union(int, content), default: 1),
79+
e.field("charge", e.types.union(int, content), default: 0),
80+
e.field("oxidation", e.types.union(int, content), default: none),
81+
e.field("a", e.types.union(int, content), default: none),
82+
e.field("z", e.types.union(int, content), default: none),
83+
e.field("rest", e.types.union(int, content), default: none),
84+
e.field("radical", bool, default: false),
85+
e.field("affect-layout", bool, default: true),
86+
e.field("roman-oxidation", bool, default: true),
87+
e.field("roman-charge", bool, default: false),
88+
e.field("radical-symbol", content, default: sym.dot),
89+
e.field("negative-symbol", content, default: math.minus),
90+
e.field("positive-symbol", content, default: math.plus),
91+
),
92+
)

0 commit comments

Comments
 (0)