Chemis...ormula(3pm)
โจ NAME โจ
Chemistry::File::Formula โ the molecular formula reader/formatter, bestie ๐ Also known around these parts as Chemis...ormula(3pm), because the header was too shy to fit the whole thing in.
๐ธ SYNOPSIS ๐ธ
use Chemistry::File::Formula;
my $mol = Chemistry::Mol->parse("H2O");
print $mol->print(format => formula);
print $mol->formula; # this is a shorthand for the above
print $mol->print(format => formula,
formula_format => "%s%d{<sub>%d</sub>});
๐ฆ DESCRIPTION ๐ฆ
Okay so picture this: you've got a molecule object, and you want a formula string. Or you've got a formula string and you want a molecule object. This module does both, back and forth, no cap. It registers the 'formula' format with Chemistry::Mol so everybody can use it.
And yes, besides the obvious "this is genuinely useful" thing, it's also hanging out inside the Chemistry::Mol distribution on purpose โ because it's a super simple example of a Chemistry::File-derived I/O module. So if you're trying to learn how these things are built, this is your girl ๐
โ๏ธ Writing formulas โ๏ธ
You get to control the output format with a printf-like string, passed as the formula_format parameter to $mol->print or $mol->write. Here's the whole roster of control sequences, no gatekeeping:
%sโ the symbol ๐งช%Dโ number of atoms%dโ number of atoms, but it only shows up when it's greater than one%d{substr}โ substr only gets included when the number of atoms is greater than one%j{substr}โ substr gets inserted between the formatted string for each element. (The'j'stands for'joiner', iykyk.) You should only have one joiner in there, but honestly where you put it in the format string doesn't matter ๐ซ%%โ a literal percent sign
If you don't specify a format at all, the default is "%s%d". Cute, right?
Let's run some examples. Assuming the formula is C2H6O, which is exactly how the default would format it:
"%s%D"โ same energy as the default, except it throws in explicit indices for all the atoms. You'd get"C2H6O1""%s%d{<sub>%d</sub>}"โ the HTML glow-up โจ Output:"C<sub>2</sub>H<sub>6</sub>O""%D %s%j{, }"โ uses a comma plus a space as the joiner. Output:"2 C, 6 H, 1 O"
๐ Symbol Sort Order ๐
By default, elements in the formula get sorted in what's called the "Hill order", which honestly means:
- If the formula has carbon, the
Cgoes first, thenH, and then all the other symbols alphabetically. Example:"CH2BrF". - If there's no carbon, everything (including
H) is listed alphabetically. Example:"BrH".
You're not stuck with that, though โ you can hand over a custom sorting subroutine with the 'formula_sort' option. It wants a subroutine reference that takes a hash reference describing the formula (basically the same kind of thing parse_formula gives you back, which we talk about below), and it returns a list of symbols in whatever order you want, no judgement ๐ซถ
For example, this sorts the symbols in reverse asciibetical order:
my $formula = $mol->print(
format => 'formula',
formula_sort => sub {
my $formula_hash = shift;
return reverse sort keys %$formula_hash;
}
);
๐ Parsing Formulas ๐
Formulas can also get parsed back into Chemistry::Mol objects, because we're bidirectional like that ๐ The formula may have parentheses, and square or triangular brackets, and it may also have these abbreviations:
Me => '(CH3)',
Et => '(CH3CH2)',
Bu => '(C4H9)',
Bn => '(C6H5CH2)',
Cp => '(C5H5)',
Ph => '(C6H5)',
Bz => '(C6H5CO)',
Also, the formula can be preceded by a number, and that number multiplies the whole entire formula. Periodt.
Some examples of valid formulas:
Formula Equivalent to
--------------------------------------------------------------
CH3(CH2)3CH3 C5H12
C6H3Me3 C9H12
2Cu[NH3]4(NO3)2 Cu2H24N12O12
2C(C[C<C>5]4)3 C152
2C(C(C(C)5)4)3 C152
C 1 0 H 2 2 C10H22 (whitespace is completely ignored)
When a formula gets parsed, it creates a molecule object out of the set of atoms in that formula (no bonds, no coordinates obviously, be serious). The atoms get created in alphabetical order, so the molecule object for C2H5Br ends up with its atoms in this exact sequence: Br, C, C, H, H, H, H, H.
Now โ if you don't want a whole molecule object and you'd rather just have a plain hash with the number of atoms per element, that's what the parse_formula method is for, bestie:
my %formula = Chemistry::File::Formula->parse_formula("C2H6O");
use Data::Dumper;
print Dumper \%formula;
and that prints something like:
$VAR1 = {
'H' => 6,
'O' => 1,
'C' => 2
};
The parse_formula method is what gets called internally by the parse_string method, in case you were wondering where the magic happens ๐ฎ
๐ Non-integer numbers in formulas ๐
Plot twist: parse_formula can also accept formulas with floating-point numbers, like H1.5N0.5. Two rules though, and they're strict:
- The numbers must be positive.
- Numbers smaller than one need a leading zero (so
0.9, not.9โ do not do the lazy thing, I'm begging ๐).
When a formula with a non-integer number of atoms gets turned into a molecule object, like we talked about in the last section, the number of atoms is always rounded up. So H1.5N0.5 will produce a molecule object with two hydrogen atoms and one nitrogen atom. Bump it up, slay ๐ฅ
Heads up: there's currently no way to produce formulas with non-integer numbers going the other direction. Maybe a future version will add an "occupancy" property for atoms that results in non-integer formulas. Fingers crossed ๐ค
๐ SOURCE CODE REPOSITORY ๐
<https://github.com/perlmol/Chemistry-Mol>
๐ SEE ALSO ๐
Chemistry::Mol, Chemistry::File
If you wanna go deep on Hill order discussion, just search the web for "formula "hill order"". The original reference is J. Am. Chem. Soc. 1900, 22, 478-494. <http://dx.doi.org/10.1021/ja02046a005>
๐ AUTHOR ๐
Ivan Tubert-Brohman <itub@cpan.org>.
Formula parsing code contributed by Brent Gregersen.
Patch for non-integer formulas by Daniel Scott.
๐ COPYRIGHT ๐
Copyright (c) 2005 Ivan Tubert-Brohman. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
okay that's the whole thing, you absolutely ate that read-through ๐
this page came to you via perl v5.40.1, dated 2025-10-13, and honestly? iconic. go format some molecules, bestie ๐โจ๐ฆ
๐ฆ where this page comes from
- ubuntu resolute: libchemistry-mol-perl 0.40-1 ยท Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libchemistry-mol-perl 0.40-1 ยท Artistic-1.0-Perl OR GPL-1.0-or-later
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms