public Renderer() { _fontLoader = new FontLoader(); _textMeasurer = new HyperfontTextMeasurer(_fontLoader); _typesetter = new Typesetter(_textMeasurer); _exporter = new PNGExporter(_fontLoader); _parser = new LaTeXParser(); }
public static string ConvertToMathString(string latexIn) { var parseResult = LaTeXParser.MathListFromLaTeX(latexIn); if (parseResult.Error == null) { parseResult.Deconstruct(out MathList atoms, out _); return(ConvertToMathString(atoms)); } return(null); }
public static GenericFunction ParseFunction(string latexIn) { var parseResult = LaTeXParser.MathListFromLaTeX(latexIn); if (parseResult.Error == null) { parseResult.Deconstruct(out MathList atoms, out _); return(ParseFunction(atoms)); } return(null); }
MathList ParseLaTeX(string latex) => LaTeXParser.MathListFromLaTeX(latex).Match(list => list, e => throw new Xunit.Sdk.XunitException(e));
public static string ConvertToMathString(IList <MathAtom> atoms) { string output = ""; for (int i = 0; i < atoms.Count; i++) { var atom = atoms[i]; if (atom is Variable variable) { output += atom.Nucleus; if (i + 1 < atoms.Count && atoms[i + 1] is Variable) { output += "*"; } } else if (atom is Fraction fraction) { output += $"({ConvertToMathString(fraction.Numerator)})/({ConvertToMathString(fraction.Denominator)})"; } else if (atom is Inner inner) { output += $"({ConvertToMathString(inner.InnerList)})"; } else if (atom is BinaryOperator binaryOperator) { if (binaryOperator.Nucleus == "·") { output += "*"; } } else if (atom is LargeOperator largeOperator) { if (largeOperator.Nucleus == "∫") { // Figure out which kind of intergral we're dealing with if (largeOperator.Subscript.Count > 0 || largeOperator.Superscript.Count > 0) { // Definite integral // Find the variable to integrate with respect to bool foundWRT = false; int idxOfWRT = i + 1; while (!foundWRT && idxOfWRT + 1 < atoms.Count) { foundWRT = atoms[idxOfWRT] is Variable intWRTMarker && intWRTMarker.Nucleus == "d" && atoms[idxOfWRT + 1] is Variable; idxOfWRT++; } // Get the bounds of integration LaTeXParser.MathListFromLaTeX(@"\infty").Deconstruct(out MathList defaultUpperBound, out _); LaTeXParser.MathListFromLaTeX(@"-\infty").Deconstruct(out MathList defaultLowerBound, out _); var upperBound = MathS.FromString( ConvertToMathString(largeOperator.Superscript.Count == 0 ? defaultUpperBound : largeOperator.Superscript) ); var lowerBound = MathS.FromString( ConvertToMathString(largeOperator.Subscript.Count == 0 ? defaultLowerBound : largeOperator.Subscript) ); // Get the list of atoms that we need to integrate // i+1 to skip the integral symbol, and idxOfWRT-i-2 to remove the dx var intAtoms = atoms.Skip(i + 1).Take(idxOfWRT - i - 2).ToList(); // Calculate the integral of the expression var varWRT = MathS.Var(foundWRT ? atoms[idxOfWRT].Nucleus : "x"); var antiderivative = MathS.FromString(ConvertToMathString(intAtoms)).Integrate(varWRT).Simplify(); output += (antiderivative.Substitute(varWRT, upperBound) - antiderivative.Substitute(varWRT, lowerBound)).Simplify().ToString(); // Make sure the atoms involved in the integration aren't parsed again i = idxOfWRT; continue; } else { // Indefinite integral // Find the variable to integrate with respect to bool foundWRT = false; int idxOfWRT = i + 1; while (!foundWRT && idxOfWRT + 1 < atoms.Count) { foundWRT = atoms[idxOfWRT] is Variable intWRTMarker && intWRTMarker.Nucleus == "d" && atoms[idxOfWRT + 1] is Variable; idxOfWRT++; } // Get the list of atoms that we need to integrate // i+1 to skip the integral symbol, and idxOfWRT-i-2 to remove the dx var intAtoms = atoms.Skip(i + 1).Take(idxOfWRT - i - 2).ToList(); // Calculate the integral of the expression var varWRT = MathS.Var(foundWRT ? atoms[idxOfWRT].Nucleus : "x"); output += MathS.FromString(ConvertToMathString(intAtoms)).Integrate(varWRT).Simplify().ToString(); // Make sure the atoms involved in the integration aren't parsed again i = idxOfWRT; continue; } } else { output += atom.Nucleus; } } else { output += atom.Nucleus; } if (atom.Superscript.Count > 0) { output += $"^({ConvertToMathString(atom.Superscript)})"; } } return(output); }