Source code for pygacity.pythontex.monkeypatches.reaction

"""
Monkeypatches for the Reaction class to add LaTeX output functionality.
"""

from sandlertools import Reaction
from ..texutils import frac_or_int_as_tex

import fractions as fr

def _component_subscripts(self, base: str) -> list[str]:
    """
    Generates a list of LaTeX strings with component names and subscripts.

    Parameters
    ----------
    base : str
        base string to which subscripts are added

    Returns
    -------
    list of str
        list of LaTeX formatted strings with subscripts
    """
    subscripts = []
    for c in self.components:
        subscripts.append(base + r'_{' + c.Formula + r'}')
    return subscripts

def _split_reactants_products(self):
    """
    Splits the reaction into reactants and products lists for LaTeX formatting.

    Returns
    -------
    tuple
        (reactants, products, nureactants, nuproducts) where each is a list of strings
    """

    self.reactants = []
    self.products = []
    self.nureactants = []
    self.nuproducts = []
    emps = [c.Formula for c in self.components]
    for e, n in zip(emps, self.nu):
        if n < 0:
            self.reactants.append(e)
            f = fr.Fraction(-n).limit_denominator(1000)
            self.nureactants.append(frac_or_int_as_tex(f))
        elif n > 0:
            self.products.append(e)
            f = fr.Fraction(n).limit_denominator(1000)
            self.nuproducts.append(frac_or_int_as_tex(f))

[docs] def sum_nu(self) -> fr.Fraction: """ Computes the sum of stoichiometric coefficients as a Fraction. Returns ------- fr.Fraction sum of stoichiometric coefficients """ total = fr.Fraction(0) for n in self.nu: total += fr.Fraction(n).limit_denominator(1000) return total
[docs] def stoichiometric_product_as_tex(self, base_string: str = 'a', parens: bool = False) -> str: """ Formats a stoichiometric expression as a LaTeX string. Parameters ---------- base_string : str base string to which empirical-formula subscripts are added parens : bool, optional whether to enclose species in parentheses, default is False Returns ------- str LaTeX formatted stoichiometric expression """ self._split_reactants_products() base_strings = self._component_subscripts(base_string) reactants = base_strings[:len(self.reactants)] products = base_strings[len(self.reactants):] expreactants = ['' if n==1 else r'^{'+n+r'}' for n in self.nureactants] expproducts = ['' if n==1 else r'^{'+n+r'}' for n in self.nuproducts] if parens: numerator = ''.join([r'('+c+r')'+e for c,e in zip(products,expproducts)]) denominator = ''.join([r'('+c+r')'+e for c,e in zip(reactants,expreactants)]) else: numerator = ''.join([c+e for c,e in zip(products,expproducts)]) denominator = ''.join([c+e for c,e in zip(reactants,expreactants)]) return r'\frac{' + numerator + r'}{' + denominator + r'}'
[docs] def as_tex(self): """ Returns a LaTeX-formatted string of the reaction using the mhchem package's \\ce{} command. Returns ------- str LaTeX-formatted reaction string """ self._split_reactants_products() rxnstr = r'\ce{' + ' + '.join(['{:s} {:s}'.format(n, e) for n, e in zip(self.nureactants, self.reactants)]) rxnstr += r' <=> ' + ' + '.join(['{:s} {:s}'.format(n, e) for n, e in zip(self.nuproducts, self.products)]) + r'}' return rxnstr
Reaction._split_reactants_products = _split_reactants_products Reaction._component_subscripts = _component_subscripts Reaction.as_tex = as_tex Reaction.stoichiometric_product_as_tex = stoichiometric_product_as_tex Reaction.sum_nu = sum_nu