ChemPal Documentation - v1.7.0
    Preparing search index...

    Function findFormulaInHtml

    • Match for a chemical formula (with or without subscript tags) in a string of html, converting <sub>/<sup> tags to unicode sub/superscripts. Numbers that aren't tagged (e.g. a salt/hydrate coefficient denoting how many of the whole molecule) are matched but left as regular digits.

      Handles:

      • multi-digit subscripts (C<sub>18</sub>…);
      • parenthesised/bracketed groups (KN(C(O)CH<sub>2</sub>)<sub>2</sub>);
      • salt/hydrate components after a ·//* separator, with an optional leading coefficient that may be a number, a <sub>-tagged number, or a variable x/n (…O·xH<sub>2</sub>O, … • <sub>4</sub>K, …O<sub>5</sub>·K).

      Element symbols gate the match — at least two element/bracket "units" are required — so ordinary prose isn't mistaken for a formula. A clean, subscript-free formula like KBr is a single unit and is intentionally NOT matched here (callers store those verbatim via isMoleForm).

      Parameters

      • html: string

        The HTML string to search for a formula

      Returns undefined | string

      The formula with proper sub/superscript formatting, or undefined if none is found

      findFormulaInHtml('foobar K<sub>2</sub>Cr<sub>2</sub>O<sub>7</sub> baz') // "K₂Cr₂O₇"
      findFormulaInHtml('C<sub>18</sub>H<sub>14</sub>N<sub>2</sub>O') // "C₁₈H₁₄N₂O"
      findFormulaInHtml('C<sub>20</sub>H<sub>20</sub>O<sub>5</sub>·K') // "C₂₀H₂₀O₅·K"
      findFormulaInHtml('Just some text') // undefined

      https://regex101.com/r/H6DXwK/6 - Regex pattern explanation

      export const findFormulaInHtml = (html: string): string | undefined => {
      // Collect every candidate and keep the most likely one (see findFormulaInText). The subscript
      // token here is the HTML-only `<sub>`/`<sup>` tag; the rest of the grammar is shared.
      const taggedSub = '<su[bp]>[1-9][0-9]*</su[bp]>';
      const best = pickBestFormula([...html.matchAll(buildFormulaPattern(taggedSub))].map((m) => m[0]));
      if (best === undefined) {
      return;
      }
      return best
      .replace(/<sub>(\d+)<\/sub>/g, (_match, p1) => subscript(p1 || ''))
      .replace(/<sup>(\d+)<\/sup>/g, (_match, p1) => superscript(p1 || ''));
      };