formelsammlung/scripts/periodic_table.py

79 lines
2.7 KiB
Python
Raw Normal View History

2025-01-02 18:12:26 +01:00
"""
Script to process the periodic table as json into latex stuff
Source for `elements.json` is this amazing project:
https://pse-info.de/de/data
Copyright Matthias Quintern 2024
"""
import json
import os
import re
outdir = "../src/ch"
def gen_periodic_table():
with open("elements.json") as file:
ptab = json.load(file)
# print(ptab["elements"][1])
s = "% This file was created by the periodic_table.py script.\n% Do not edit manually. Any changes might get lost.\n"
for i, el_key in enumerate(ptab):
el = ptab[el_key]
def get(*keys):
"""get keys or return empty string"""
val = el
for key in keys:
if not key in val: return ""
val = val[key]
return val
# print(i, el)
el_s = f"\\begin{{element}}{{{el['symbol']}}}{{{el['number']}}}{{{el['period']}}}{{{el['column']}}}"
# description
el_s += f"\n\t\\desc[english]{{{el['names']['en']}}}{{{get('appearance', 'en')}}}{{}}"
el_s += f"\n\t\\desc[german]{{{el['names']['de']}}}{{English: {get('names', 'en')}\\\\{get('appearance', 'de')}}}{{}}"
# simple properties
for field in ["crystal_structure", "set", "magnetic_ordering"]:
if field in el:
el_s += f"\n\t\\property{{{field}}}{{{el[field]}}}"
# mass
m = get("atomic_mass", "value")
if m:
assert(get("atomic_mass", "unit") == "u")
el_s += f"\n\t\\property{{{'atomic_mass'}}}{{{m}}}"
# refractive indices
temp = ""
add_refractive_index = lambda idx: f"\\GT{{{idx['label']}}}: ${idx['value']}$, "
idxs = get("optical", "refractive_index")
print(idxs)
if type(idxs) == list:
for idx in idxs: add_refractive_index(idx)
elif type(idxs) == dict: add_refractive_index(idxs)
elif type(idxs) == float: temp += f"${idxs}$, "
if temp:
el_s += f"\n\t\\property{{{'refractive_index'}}}{{{temp[:-2]}}}"
# electron configuration
match = re.fullmatch(r"([A-Z][a-z]*)? ?(.+?)", el["electron_config"])
if match:
el_s += f"\n\t\\property{{{'electron_config'}}}{{"
if match.groups()[0]:
el_s += f"\\elRef{{{match.groups()[0]}}} "
el_s += f"{match.groups()[1]}}}"
el_s += "\n\\end{element}"
print(el_s)
s += el_s + "\n"
# print(s)
return s
if __name__ == "__main__":
ptable = gen_periodic_table()
assert os.path.abspath(".").endswith("scripts"), "Please run from the `scripts` directory"
with open(f"{outdir}/periodic_table.tex", "w") as file:
file.write(ptable)