Chemis...ormula(3pm)

๐Ÿ“ฆ
version 0.40 ยท 4 versions
, in ubuntu resolute, ubuntu stonking

โœจ 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:

  1. If the formula has carbon, the C goes first, then H, and then all the other symbols alphabetically. Example: "CH2BrF".
  2. 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 (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