Code Monkey home page Code Monkey logo

jlatexmath's People

Contributors

calixteman avatar davidmoten avatar fnatter avatar lyessaadi avatar opcodevoid avatar snecklifter avatar sylvestre avatar vlad-ivanov-name avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jlatexmath's Issues

Rewrite the parser

Right now, the parser is slow, bad-designed. So the goal is to have something very fast but it requires to rewrite parser itself and rewrite almost all the macros which take some strings as arguments rather than atom.

mhchem Support

We use the mhchem (http://docs.mathjax.org/en/latest/tex.html#mhchem ) package for chemistry when using Latex/MathJax. It lets us easily format chemical formulas and reactions without typing too much.
There really is only one command you need to know here: \ce{...}. \ce{...} takes its parameters and automatically formats it. For example,

$\ce{HCl}$ dissociates in water as follows:
$$\ce{H2O + HCl <=> H3O+ + Cl-}$$

Would it be possible to add mchem to JLatexMath and would it be a big effort to add it to JLatexMath?

Thanks for an answer.

°C doesn't work

°C
gets changed to
\\circC

Suggested fix:
parseString.replace(pos, pos + 1, "^\\circ");
needs to be changed to this in TexParser.java
parseString.replace(pos, pos + 1, "^{\\circ}");

Test-case:
"\rotatebox{90.0}{ \text{ Temperature [°C] } }"

create releases on github

According to version.xml the current version is 1.0.5 - it would be nice if github releases reflected that and a offered a jar file for direct download.

add \cellcolor

eg
"{\begin{array}{|l|l|}\hline \cellcolor{#FFEFD5}{1}&\cellcolor{#FF0000}{3} \\ \hline \cellcolor{#0000FF}{2}&\cellcolor{#BFFF00}{4} \\ \hline \end{array}}"

Added in our fork here:
https://dev.geogebra.org/trac/changeset/48883
https://dev.geogebra.org/trac/changeset/48817
https://dev.geogebra.org/trac/changeset/48816
https://dev.geogebra.org/trac/changeset/48813
https://dev.geogebra.org/trac/changeset/48812
https://dev.geogebra.org/trac/changeset/48810

Clearer per-file changes:
https://dev.geogebra.org/trac/changeset/48810/trunk/geogebra/retex/renderer-base/src/main/java/com/himamis/retex/renderer/share/PredefinedCommands.java
https://dev.geogebra.org/trac/changeset?reponame=&new=48810%40trunk%2Fgeogebra%2Fretex%2Frenderer-base%2Fsrc%2Fmain%2Fjava%2Fcom%2Fhimamis%2Fretex%2Frenderer%2Fshare%2FMultlineAtom.java&old=45809%40trunk%2Fgeogebra%2Fretex%2Frenderer-base%2Fsrc%2Fmain%2Fjava%2Fcom%2Fhimamis%2Fretex%2Frenderer%2Fshare%2FMultlineAtom.java
https://dev.geogebra.org/trac/changeset?reponame=&new=48882%40trunk%2Fgeogebra%2Fretex%2Frenderer-base%2Fsrc%2Fmain%2Fjava%2Fcom%2Fhimamis%2Fretex%2Frenderer%2Fshare%2FMatrixAtom.java&old=48810%40trunk%2Fgeogebra%2Fretex%2Frenderer-base%2Fsrc%2Fmain%2Fjava%2Fcom%2Fhimamis%2Fretex%2Frenderer%2Fshare%2FMatrixAtom.java
https://dev.geogebra.org/trac/changeset?reponame=&new=49178%40trunk%2Fgeogebra%2Fretex%2Frenderer-base%2Fsrc%2Fmain%2Fjava%2Fcom%2Fhimamis%2Fretex%2Frenderer%2Fshare%2FPredefMacros.java&old=48810%40trunk%2Fgeogebra%2Fretex%2Frenderer-base%2Fsrc%2Fmain%2Fjava%2Fcom%2Fhimamis%2Fretex%2Frenderer%2Fshare%2FPredefMacros.java
https://dev.geogebra.org/trac/changeset?reponame=&new=48812%40trunk%2Fgeogebra%2Fretex%2Frenderer-base%2Fsrc%2Fmain%2Fjava%2Fcom%2Fhimamis%2Fretex%2Frenderer%2Fshare%2FTableBox.java&old=48447%40trunk%2Fgeogebra%2Fretex%2Frenderer-base%2Fsrc%2Fmain%2Fjava%2Fcom%2Fhimamis%2Fretex%2Frenderer%2Fshare%2FTableBox.java
https://dev.geogebra.org/trac/changeset?reponame=&new=48812%40trunk%2Fgeogebra%2Fretex%2Frenderer-base%2Fsrc%2Fmain%2Fjava%2Fcom%2Fhimamis%2Fretex%2Frenderer%2Fshare%2FArrayOfAtoms.java&old=45809%40trunk%2Fgeogebra%2Fretex%2Frenderer-base%2Fsrc%2Fmain%2Fjava%2Fcom%2Fhimamis%2Fretex%2Frenderer%2Fshare%2FArrayOfAtoms.java
https://dev.geogebra.org/trac/changeset?reponame=&new=48810%40trunk%2Fgeogebra%2Fretex%2Frenderer-base%2Fsrc%2Fmain%2Fjava%2Fcom%2Fhimamis%2Fretex%2Frenderer%2Fshare%2FTeXParser.java&old=48111%40trunk%2Fgeogebra%2Fretex%2Frenderer-base%2Fsrc%2Fmain%2Fjava%2Fcom%2Fhimamis%2Fretex%2Frenderer%2Fshare%2FTeXParser.java

Slightly deformed characters in SVG output

For some reason fonts in SVG output I'm getting from JLaTeXMath are just a bit misshapen.

Example:

A = \frac{2394}{b \cdot 1650}

PNG:

jlatexmath-problem

SVG:

B771A71686B3F75C52A0298E8288BF80A6738EA9A433A51140F9514884F50304.zip

Code I use:

    private final static String SVG_NS = "http://www.w3.org/2000/svg";
    private final static String SVG_ROOT = "svg";
    private final static String SVG_EXT = ".svg";
    private final static float FONT_SIZE = 12;

    private String renderLatex(String source) {
        DOMImplementation DOMImpl = GenericDOMImplementation.getDOMImplementation();
        Document document = DOMImpl.createDocument(SVG_NS, SVG_ROOT, null);
        SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(document);
        SVGGraphics2D g = new SVGGraphics2D(ctx, true);

        TeXFormula formula = new TeXFormula(source);
        TeXFormula.TeXIconBuilder builder = formula.new TeXIconBuilder();

        builder.setStyle(TeXConstants.STYLE_DISPLAY);
        builder.setSize(FONT_SIZE);

        TeXIcon icon = builder.build();

        icon.setInsets(new Insets(0, 0, 0, 0));

        g.setSVGCanvasSize(new Dimension(icon.getIconWidth(), icon.getIconHeight()));
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, icon.getIconWidth(), icon.getIconHeight());

        icon.paintIcon(null, g, 0, 0);

        StringWriter out = new StringWriter();

        try {
            g.stream(out, true);

            out.flush();
            out.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return out.toString();
    }

Package versions:

        <dependency>
            <groupId>org.scilab.forge</groupId>
            <artifactId>jlatexmath</artifactId>
            <version>1.0.6</version>
        </dependency>

        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-svggen</artifactId>
            <version>1.8</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-dom</artifactId>
            <version>1.8</version>
            <scope>provided</scope>
        </dependency>

TeXSymbolParser typeMappings init error?

env: jvm 1.8.0_45 jlatexmath 1.0.6
input formula string :a/leq b output image sometimes like this
test
or like this
test3.

after debug, i find the different, "leq" mapping to a symbol instance ,it's type sometimes 0 and sometimes 3.
jietu20180413-112639

in fact , "leq" symbol instance's type value should be 3, may be there is something wrong when init?

Add \cline{i-j) to add partial horizontal line beginning in column i and ending in column j

Examples

\begin{tabular}{lccccc c ccccc}
\hline
 & \multicolumn{5}{c}{Females} && \multicolumn{5}{c}{Males} \\
\cline{2-6} \cline{8-12}
Treatment     & V1   & V2  & V3 & V4 & V5 && V1   & V2  & V3 & V4 & V5 \\
Placebo       & 0.21 & 163 & 3  & 4  & 5  && 0.22 & 164 & 3  & 4  & 5  \\
ACE Inhibitor & 0.13 & 142 & 3  & 4  & 5  && 0.15 & 144 & 3  & 4  & 5  \\
Hydralazine   & 0.17 & 143 & 3  & 4  & 5  && 0.16 & 140 & 3  & 4  & 5  \\
\end{tabular}

image

\begin{tabular}{|r|l|}
  \hline
  7C0 & hexadecimal \\
  3700 & octal \\ \cline{2-2}
  11111000000 & binary \\
  \hline \hline
  1984 & decimal \\
  \hline
\end{tabular}

image

add \questeq

Another small suggestion:

NewCommandMacro.addNewCommand("questeq", "{\\stackrel{?}{=}}", 0);

How to render "closed square roots"?

This article describes how it is possible in LaTeX to render a "closed square root".
I would like to draw one myself, but the code provided does not work. I suppose I am doing something wrong, because I literally started using this library today.

This is the LaTeX code provided by the article

% New definition of square root:
% it renames \sqrt as \oldsqrt
\let\oldsqrt\sqrt
% it defines the new \sqrt in terms of the old one
\def\sqrt{\mathpalette\DHLhksqrt}
\def\DHLhksqrt#1#2{%
\setbox0=\hbox{$#1\oldsqrt{#2\,}$}\dimen0=\ht0
\advance\dimen0-0.2\ht0
\setbox2=\hbox{\vrule height\ht0 depth -\dimen0}%
{\box0\lower0.4pt\box2}}

image

This is the result from the article. I am thinking I could just do something like...

TeXFormula fx = new TeXFormula("% New definition of square root:\r\n" + 
				"% it renames \\sqrt as \\oldsqrt\r\n" + 
				"\\let\\oldsqrt\\sqrt\r\n" + 
				"% it defines the new \\sqrt in terms of the old one\r\n" + 
				"\\def\\sqrt{\\mathpalette\\DHLhksqrt}\r\n" + 
				"\\def\\DHLhksqrt#1#2{%\r\n" + 
				"\\setbox0=\\hbox{$#1\\oldsqrt{#2\\,}$}\\dimen0=\\ht0\r\n" + 
				"\\advance\\dimen0-0.2\\ht0\r\n" + 
				"\\setbox2=\\hbox{\\vrule height\\ht0 depth -\\dimen0}%\r\n" + 
				"{\\box0\\lower0.4pt\\box2}}");

...but it doesn't work. Please help me.

Can't compile!

I installed jlatexmath using mvn clean install but the lines

import org.apache.batik.dom.GenericDOMImplementation;
import org.apache.batik.svggen.SVGGeneratorContext;
import org.apache.batik.svggen.SVGGraphics2D;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.fop.render.ps.EPSTranscoder;
import org.apache.fop.render.ps.PSTranscoder;
import org.apache.fop.svg.AbstractFOPTranscoder;
import org.apache.fop.svg.PDFTranscoder;

are still red.

P.S: these lines are ok
import org.scilab.forge.jlatexmath.DefaultTeXFont;
import org.scilab.forge.jlatexmath.TeXConstants;
import org.scilab.forge.jlatexmath.TeXFormula;
import org.scilab.forge.jlatexmath.TeXIcon;
import org.scilab.forge.jlatexmath.cyrillic.CyrillicRegistration;
import org.scilab.forge.jlatexmath.greek.GreekRegistration;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;

ArrayOptions IndexOutOfBoundsException

ArrayOptions

 fun getAlignment(i: Int): TeXConstants.Align {
        return options[i + 1].alignment
    }

There is a problem with this function

 public ArrayOptions complete(final int n) {
        final int s = options.size();
        for (int i = 0; i < n - s; ++i) {
            addAlignment(TeXConstants.Align.CENTER);
        }
        return this;
    }

Because its options.size == n+1 ,Should be like this for (int i = 0; i <= n - s; ++i)

Test case

\begin{array}{cc}{-6-10} & {6-0} & {0+10} \\{9-35}& {3-5} & {12-30}\end{array}

\longleftarrow has gap

\longleftarrow has a gap/notch in when drawn large:
longleftarrow

Definition:
TeXFormula.predefinedTeXFormulasAsString.put("longleftarrow", "\\leftarrow\\joinrel\\relbar");

\joinrel has a constant of -2.6f

public static final Atom joinrel_macro() throws ParseException {
  return new TypedAtom(TeXConstants.TYPE_RELATION, TeXConstants.TYPE_RELATION, new SpaceAtom(
    TeXConstants.UNIT_MU, -2.6f, 0, 0));
}

changing this to around -3.4f seems to fix this case, which matches the value in XLeftRightArrowFactory but I don't know if this will break other things

Box kern = new SpaceAtom(TeXConstants.UNIT_MU, -3.4f, 0, 0).createBox(env);

Spacing computed from the length of a superscript not subscript even if subscript is longer (in Freeplane)

Latex code

\[||f||_{L^\infty(\mathbb{R}^N)}^{1-\alpha} ||f||^{\alpha}_{L_1(\mathbb{R}^N)}\]

in Freeplane will generate output as in the picture.

If there is only a subscript, the length is computed from the subscript correctly. Same with supersript.

But if both are used the spacing is NOT computed from the longer one but only from the length of the superscript resulting in a mess as seen in the picture.

This may be an issue of Freeplane (in which case I'm sorry) but I don't have the time to pinpoint it and to me it seems most likely that the issue is caused by this package.

EDIT: In GeoGebra it works just fine so the issue is probably on the side of Freeplane. I am sorry to bother.
PLEASE CLOSE THIS ISSUE

jlatexmathissue

Tries to download files in --offline regime

It has been built without --offline, repository has been saved and restored to build with --offline but it again tries to download something:

[ERROR] Error fetching link: /usr/ports/math/jlatexmath/work/jlatexmath-1.0.7/jlatexmath-font-cyrillic/target/apidocs/package-list. Ignored it.
[ERROR] Error fetching link: /usr/ports/math/jlatexmath/work/jlatexmath-1.0.7/jlatexmath-font-greek/target/apidocs/package-list. Ignored it.

\longdiv{10}{} -> Infinite loop

Needs checking/fixing in 2 places

  1. TeXParser.getArgAsPositiveInteger() returns -1 for the {} argument

  2. In LongDivAtom.makeResults() this could be improved :)
    while (q != 0) {

matrices wrong after one with empty cell

Just spotted this fix in a fork:
CBN-Polska@271489b

-                    boxarr[i][j - 1].type = TeXConstants.TYPE_INTERTEXT;
+                    if (boxarr[i][j - 1] != nullBox) // BUGFIX: EN-122
+                        boxarr[i][j - 1].type = TeXConstants.TYPE_INTERTEXT;

BUGFIX EN-122 solves problem:

When a matrix like this

\begin{tabular}{ccc}
  &     \\
  & 1 & 2  \\
\end{tabular}

is created then all next matrixes having first cell in a row empty have all row empty.

So when you call above tex and later write for example:

\begin{tabular}{ccc}
  & 2 & 3   \\
4 & 5 & 6  \\
  & 8 & 9  \\
\end{tabular}

you will see only 4 5 6. First and third line are print empty.

FontInfo has strange hashCode()

This looks odd, and I can't see a reason for it:

		public int hashCode() {
			return (left + right) % 128;
		}

I suggest:

		public int hashCode() {
			return left + (right << 16);
		}

Separate LaTeX, TeX, TeX Math, and ConTeXt

What are your thoughts on having separate modules (or packages) that allow developers to easily pick and choose what TeX flavours they'd like to bundle with their applications?

It would require changes to the project's organizational structure. See my fork of JMathTex for details, most relevant would be the resource readers and resource hierarchy. Broadly, consider:

Java

Under src/main/java/:

  • org/scilab/forge/jlatexmath/tex
  • org/scilab/forge/jlatexmath/latex
  • org/scilab/forge/jlatexmath/context
  • org/scilab/forge/jlatexmath/mathtex

Resources

Under src/main/resources/:

  • config/tex/*.xml
  • config/latex/*.xml
  • config/mathtex/*.xml
  • config/context/*.xml

Fonts

Under src/main/resources/fonts/:

  • cm/*.ttf

1.0.6: Parse error in fonts/language_cyrillic.xml

hello jlatexmath developers,

many thanks for this excellent library!

I have a small problem in 1.0.6 when rendering a formula "тся" in Freeplane
for the first time (on Freeplane startup):

WARNING: Problem with command text at position 4:10
fonts/language_cyrillic.xml
org.scilab.forge.jlatexmath.ParseException: Problem with command text at position 4:10
fonts/language_cyrillic.xml
	at org.scilab.forge.jlatexmath.PredefMacroInfo.invokeID(PredefMacroInfo.java:593)
	at org.scilab.forge.jlatexmath.PredefMacroInfo.invoke(PredefMacroInfo.java:70)
	at org.scilab.forge.jlatexmath.TeXParser.processCommands(TeXParser.java:1398)
	at org.scilab.forge.jlatexmath.TeXParser.processEscape(TeXParser.java:1238)
	at org.scilab.forge.jlatexmath.TeXParser.parse(TeXParser.java:712)
	at org.scilab.forge.jlatexmath.TeXFormula.<init>(TeXFormula.java:284)
	at org.scilab.forge.jlatexmath.TeXFormula.<init>(TeXFormula.java:268)
	at org.freeplane.plugin.latex.TeXText.createTeXIcon(TeXText.java:39)
	at org.freeplane.plugin.latex.LatexRenderer.getIcon(LatexRenderer.java:90)

Please tell me if you cannot reproduce this easily. In that case I will (try to) provide a minimal example.

Thanks and Best Regards,
Felix

Convert example: replace Apache Batik with JFreeSVG

Regarding the Convert example code, a quick performance comparison between Apache Batik and JFreeSVG revealed that Batik introduces a lot of garbage collection churn. (I did not tweak the GC parameters.) There are some benchmarks that show JFreeSVG can be up to five times faster than Batik when generating SVG representations.

Here's some example code for JFreeSVG:

    // JFreeSVG uses the default buffer size, which otherwise incurs reallocations.
    final StringBuilder buffer = new StringBuilder( 16384 );

    final var formula = new TeXFormula( EQUATIONS[ j ] );
    final var font = new DefaultTeXFont( size );
    final var env = new TeXEnvironment( STYLE_DISPLAY, font );
    final var box = formula.createBox( env );
    final var layout = new TeXLayout( box, size );

    final var g = new SVGGraphics2D(
        layout.getWidth(), layout.getHeight(), PX, buffer );
    g.setRenderingHint(
       KEY_DRAW_STRING_TYPE, VALUE_DRAW_STRING_TYPE_VECTOR
    );
    g.scale( size, size );

    box.draw( g, layout.getX(), layout.getY() );
    svg = g.getSVGElement( null, true, null, null, null );

    final String svg = g.getSVGElement( null, true, null, null, null );

    try( final var fos = new FileOutputStream( filename );
         final var out = new OutputStreamWriter( fos, UTF_8 ) ) {
      out.write( svg );
    }

This is, of course, a super minor issue. Here's the TeXLayout class that's equivalent to TeXIcon, but with some coupling to the rendering environment removed.

package be.ugent.caagt.jmathtex;

import java.awt.*;

/**
 * Responsible for computing the preferred layout dimensions for an instance
 * of {@link Box}. This provides similar functionality to {@link TeXIcon},
 * but without {@link Insets} or painting ability. It is meant to help with
 * calculating final layout dimensions that can be used to draw the
 * {@link Box} using third-party libraries.
 * <p>
 * The dimensions returned for the width and height are in pixels, by default.
 * </p>
 */
public class TeXLayout {
  private static final float ROUND = 0.99f;

  /**
   * The generated {@link Box} width is a little off for some reason (possibly
   * italics?), so this enlarges the resulting dimension a little.
   */
  private static final float TWEAK_WIDTH = 0.16f;

  /**
   * The generated {@link Box} height is a little off for some reason (possibly
   * italics?), so this enlarges the resulting dimension a little.
   */
  private static final float TWEAK_HEIGHT = 0.18f;

  private final Box mBox;
  private final float mSize;

  public TeXLayout( final Box box, final float size ) {
    mBox = box;
    mSize = size;
  }

  /**
   * Returns the suggested X position for to (mostly) center-align the result.
   *
   * @return Recommended X location for drawing the {@link Box}.
   */
  public float getX() {
    return TWEAK_WIDTH / 2;
  }

  /**
   * Returns the suggested Y position for to (mostly) center-align the result.
   *
   * @return Recommended Y location for drawing the {@link Box}.
   */
  public float getY() {
    return getBox().getHeight() + TWEAK_HEIGHT / 2;
  }

  /**
   * Get the total occupied space to render the {@link Box} width.
   *
   * @return The {@link Box} width multiplied by the size.
   */
  public int getWidth() {
    return (int) (getBox().getWidth() * getSize() + ROUND + (TWEAK_WIDTH * getSize()));
  }

  /**
   * Get the total occupied space to render the {@link Box} height.
   *
   * @return The {@link Box} height and depth multiplied by the size.
   */
  public int getHeight() {
    final var box = getBox();
    final var size = getSize();
    return (int) ((box.getHeight() + box.getDepth()) * size + (2 * ROUND) + (TWEAK_HEIGHT * size));
  }

  private Box getBox() {
    return mBox;
  }

  public float getSize() {
    return mSize;
  }

  @Override
  public String toString() {
    return getClass().getSimpleName() + "{" +
        "mBox=" + mBox +
        ", mSize=" + mSize +
        ", width=" + getWidth() +
        ", height=" + getHeight() +
        '}';
  }
}

Centering the output within the SVG is proving problematic, but the above code ensures that all the content fits (in the several test cases I tried).

Extra \\ in \begin{array} messes up subsequent commands

These two examples work fine:

"\begin{array}{|l|l|l||l|} \hline Frequency&a&a&Total \\  \hline a&1&1&2 \\  \hline a&1&1&2 \\  \hline   Total&2&2&4 \\  \hline \end{array}"
"\begin{array}{r|lllll}0&1&1&1&1 \\ 1&2&2& &  \\ 2& & & &  \\ 3&3&5& &  \\ 4&2& & &  \\ 5& & & &  \\ 6&3&3&6&  \\ \end{array} "

but if you add a spurious \\ in the first command then the second one draws only the first row:

"\begin{array}{|l|l|l||l|} \\ \hline Frequency&a&a&Total \\  \hline a&1&1&2 \\  \hline a&1&1&2 \\  \hline   Total&2&2&4 \\  \hline \end{array}"
"\begin{array}{r|lllll}0&1&1&1&1 \\ 1&2&2& &  \\ 2& & & &  \\ 3&3&5& &  \\ 4&2& & &  \\ 5& & & &  \\ 6&3&3&6&  \\ \end{array} "

firstrowonly

Retain the variable names of formula in the svg image?

Very nice work! I am using this to print formulas and it works very well.

I need some help. I'm in need of retaining the variable names in the exported svg image.

When using the constructor of SVGGraphics2D there is an option to use font instead of shapes in the resulting svg image. But using font instead of shapes, does not paint the mathematical formula nicely.

SVGGraphics2D g2 = new SVGGraphics2D(ctx, fontAsShapes);

I require the variables names for post processing the svg image to embed hyperlinks. Thanks!

This is the result I get passing fontAsShape as false
font
This is the result I get passing fontAsShape as true
1598963872683_shape

So in the above formula is it possible to group the entire variable End_fD in a single svg text group?

Support for formula elements

Does jlatexmath support following Elements? I am getting exception while processing them:

  • equation
    org.scilab.forge.jlatexmath.ParseException: Unknown environment: equation at position 1:2

  • eqnarray*, align* (eqnarray and align are working without *)
    org.scilab.forge.jlatexmath.ParseException: Unknown environment: eqnarray* at position 1:2

  • \nonumber
    org.scilab.forge.jlatexmath.ParseException: Problem with command [ at position 2:343 Problem with command array@@env at position 0:311 Unknown symbol or command or predefined TeXFormula: 'nonumber'

I am generating PDF using Apache fop, jlatexmath and jlatexmath-fop.

Thanks

maven build progress

Hi
@calixteman asked that I proceed with the refactor to use maven as a build tool as discussed in #6.

I have a fork at https://github.com/davidmoten/jlatexmath that is looking good and I'll submit it as a PR soon. As preparatory work with @calixteman's permission I've removed the recent commit d7d9456 (Massive reindent) to simplify the work on the PR. The state of the master branch before the commit removal is at the branch https://github.com/opencollab/jlatexmath/tree/before-massive-indent-removal.

I'll submit the maven rework as a PR so that people have some visibility and chance to comment. Merge will be pretty soon after I imagine as we can then deal with any minor issues on master than on the PR.

\neq incorrect After running for a while

I have a strange problem.
The command \neq work fine at the beginning,looks like this:
image

But after running for a while, i don't know when and how, it is changed:
image

Is it because of some other command that changed the environment?

SVG groups for each line

Hello,
thanks a lot for this library.

A question here. Is there a way to group equations into SVG groups? I am trying to render one line at a time and it will be easy to achieve if there are distinct groups.

Performance: replace exceptions used for conditional logic

Guided by async profiler, I've made some improvements to my fork of JMathTeX that may be relevant. JMH notwithstanding it appears that the time to parse TeX has been halved. The output documents are not perfectly identical, but close enough to show the performance gains---see below for one hot spot.

Once @murkle's changes are on the mainline branch, we'll see how much performance is gained from the updates.

Test Setup

This section describes the setup for the two code bases.

Equations

The following expressions were tested:

  private final static String[] EQUATIONS = {
      "(a+b)^2=a^2 + 2ab + b^2",
      "S_x = sqrt((SS_x)/(N-1))",
      "e^{\\pi i} + 1 = 0",
      "\\sigma=\\sqrt{\\sum_{i=1}^{k} p_i(x_i-\\mu)^2}",
      "\\sqrt[n]{\\pi}",
      "\\sqrt[n]{|z| . e^{i \\theta}} = " +
          "\\sqrt[n]{|z| . e^{i (\\frac{\\theta + 2 k \\pi}{n})}}," +
          " k \\in \\lbrace 0, ..., n-1 \\rbrace, n \\in NN",
      "\\vec{u}^2",
      "\\sum_{i=1}^n i = (\\sum_{i=1}^{n-1} i) + n =\n" +
          "\\frac{(n-1)(n)}{2} + n = \\frac{n(n+1)}{2}",
      "\\int_{a}^{b} x^2 dx",
      "G_{\\mu \\nu} = \\frac{8 \\pi G}{c^4} T_{{\\mu \\nu}}",
      "\\prod_{i=a}^{b} f(i)",
  };

JMathTeX Fork

Two loops, one through the equations and the other to parse 10,000,000 plain TeX strings.

    final var size = 20f;
    final var texFont = new DefaultTeXFont( size );

    final long startTime = System.currentTimeMillis();

    for( int j = 0; j < EQUATIONS.length; j++ ) {
      // Unused, but doesn't affect the outcome.
      final var filename = "/tmp/eq-" + j + ".svg";

      for( int i = 0; i < 10_000_000 / EQUATIONS.length; i++ ) {
        final var formula = new TeXFormula( EQUATIONS[ j ] );
        final var env = new TeXEnvironment( STYLE_DISPLAY, texFont );
        final var box = formula.createBox( env );
        final var layout = new TeXLayout( box, size );
      }
    }

    System.out.println( System.currentTimeMillis() - startTime );

JLaTeXMath

First, strip down Convert.toSVG to its TeX parsing parts:

    public static void toSVG(String latex, String file, boolean fontAsShapes) throws IOException {
        final TeXFormula formula = new TeXFormula(latex);
        final TeXIcon icon = formula.createTeXIcon(TeXConstants.STYLE_DISPLAY, 20);
        icon.setInsets(new Insets(5, 5, 5, 5));
        final Dimension dim = new Dimension(icon.getIconWidth(), icon.getIconHeight());
    }

Then change Example5 to:

  public static void main( String[] args ) throws IOException {
    final long startTime = System.currentTimeMillis();

    for( int j = 0; j < EQUATIONS.length; j++ ) {
      for( int i = 0; i < 10_000_000 / EQUATIONS.length; i++ ) {
        Convert.toSVG( EQUATIONS[ j ], "/tmp/example-" + j + ".svg", true );
      }
    }

    System.out.println( System.currentTimeMillis() - startTime );
  }

Benchmarks

Results with 1 run each (no best of times):

  • JLaTeXMath ran in 92618 milliseconds (1.54 minutes).
  • JMathTeX fork ran in 41019 milliseconds (0.68 minutes).

Three runs of 10,000 iterations after further micro-optimizations to JMathTeX fork:

  • JLaTeXMath: 1039 ms, 1027 ms, 1166 ms
  • JMathTeX fork: 239 ms, 219 ms, 227 ms

This gets the code within poking distance of real-time rendering for documents of significant size.

Gains

One of the larger performance gains was to eliminate using exceptions for conditional logic in TeXParser's processEscape() method. The following code is slow because Java will fill out an entire stack trace when a formula or a symbol cannot be found:

        try {
            return TeXFormula.get(command).root;
        } catch (FormulaNotFoundException e) {
            try {
                return SymbolAtom.get(command);
            } catch (SymbolNotFoundException e1) { }
        }

Instead, consider using Optional or return null instead. The processEscape() method is in a critical part of the code.

Distorted Graphics2D output (letter height) when using JRE11

There is a rendering issue that occurs with JRE11, but not with JRE8 (or 1.7).
It happens when doing vector rendering, e.g. using any of the following Graphics2d backends: epsgraphics, freehep, jfreesvg, orsonpdf, jtikz. But none of this backends is affected when using g.drawString() instead of jlatexmath.

png output (ok for both JRE8 and JRE11): out2_JRE11

JRE 11 (distorted):
out2_JRE11_eps.pdf

JRE 8 (ok):
out2_JRE8_eps.pdf

Unfortunately I was not able to track down the issue.

Example code (showIssue2.zip):

/* Test case */
package ShowIssue;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.io.FileOutputStream;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import net.sf.epsgraphics.ColorMode;
import net.sf.epsgraphics.EpsGraphics;
import org.scilab.forge.jlatexmath.Box;
import org.scilab.forge.jlatexmath.TeXConstants;
import org.scilab.forge.jlatexmath.TeXFormula;
import org.scilab.forge.jlatexmath.TeXIcon;

/**
 *
 * @author av 2019
 */
public class showIssue2 {
    boolean success = true;
    
    public showIssue2 () {
        int pxwidth = 80;
        int pxheight = 50;
        // writing to an image works in both JRE8 and JRE11
        writeOutput(pxwidth, pxheight, "out2.png");
        // writing to anything else distorts the height of jlatexmath formula
        // tested: epsgraphics, jfreesvg, orsonpdf, jtikz, freehep
        writeOutputEPS(pxwidth, pxheight, "out2.eps"); 
    }
    
    private void draw(Graphics2D g) {
        g.setColor(Color.BLACK);
        g.setStroke(new BasicStroke(1f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        
        int fontsize = 12;
        g.setFont(new java.awt.Font("Serif", Font.PLAIN, fontsize));
        g.drawString("x = √25", 10f, 15f);
        
        double xpix = 10;
        double ypix = 40;
        String latex = "x = \\sqrt{25}";
        TeXFormula formula = new TeXFormula(latex);
        
        formula.setColor(g.getColor());
        formula.setDEBUG(false);
        //formula.createPNG(TeXConstants.STYLE_TEXT, 200, "out.png", Color.WHITE, Color.BLACK);
        TeXIcon icon = formula.createTeXIcon(TeXConstants.STYLE_TEXT, fontsize, true);
        
        Graphics2D tempGraphics = (Graphics2D) g.create();
        tempGraphics.translate(xpix, ypix);
        tempGraphics.scale(fontsize, fontsize);

        // draw formula box
        Box box = icon.getBox();
        box.draw(tempGraphics, 0, 0);
        
        tempGraphics.dispose();
    }
    
    public static void main(String[] args) {
        showIssue2 c1 = new showIssue2();
    }
    
    private void writeOutputEPS(int pxwidth, int pxheight, String filename) {
        try {
            FileOutputStream file = new FileOutputStream(filename);
            EpsGraphics eps = new EpsGraphics(filename, file,
                    0, 0, pxwidth, pxheight, ColorMode.COLOR_RGB);
            
            draw(eps);
            
            eps.close();
            file.close();
        } catch (IOException ex) {
            System.err.println(ex.getLocalizedMessage());
            success = false;
        }

        if (success) {
            System.out.println("Output written to: " + filename);
        } else {
            System.out.println("Error occurred. Check for error messages.");
        }
    }
    
    private void writeOutput(int pxwidth, int pxheight, String filename) {
        try {
            FileOutputStream file = new FileOutputStream(filename);
            int imgtype = BufferedImage.TYPE_INT_ARGB; // including transparency (alpha channel)
            BufferedImage bi = new BufferedImage(pxwidth, pxheight, imgtype);
            Graphics2D ig2 = bi.createGraphics();
            ig2.setColor(Color.WHITE);
            ig2.fillRect(0, 0, pxwidth, pxheight);
            draw(ig2);
            ImageIO.write(bi, "png", file);
            file.close();
        } catch (IOException ex) {
            System.err.println(ex.getLocalizedMessage());
            success = false;
        }

        if (success) {
            System.out.println("Output written to: " + filename);
        } else {
            System.out.println("Error occurred. Check for error messages.");
        }
    }

}

add \brack \brace \bangle

Should be easy to backport from our fork, simple adaption of code for choose_macro() for {a \choose b}
http://dev.geogebra.org/trac/changeset/53154

eg
"{a \brace b}"
"{a \bangle b}"
"{a \brack b}"

There's a problem with the first bracket missing from both these which I didn't manage to solve though:
"{a \bangle b}"
"a \atopwithdelims \langle \rangle b"

I guess it's a font/glyph problem as it's OK in bold (but not italic)

banglebug

[Question] How to produce XML files from TTF?

Hello! I am maintaining another JMathTeX satellite project, WPF-Math, and I want to ask you a question about the legacy XML font description JMathTeX is using.

I can see that you're using and successfully modifying the same XML font format, and these XML files are obviously linked to the corresponding TTF files.

I'm curious: how are you extracting these XML files from the newly added fonts? How are you modifying these files? Are there any tools or scripts for that?

I've tried to ask JMathTeX author, Kris Coolsaet, but unfortunately it was so long ago that he didn't remember how these XML files were managed back then.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.