Giter Club home page Giter Club logo

microtex's Introduction

logo

It is a dynamic, cross-platform, and embeddable LaTeX rendering library. Its main purpose is to display mathematical formulas written in LaTeX. It can be embedded in applications on various platforms (Android, iOS, Windows, Linux GTK, Qt...). The following pictures demonstrate the application run in Ubuntu (using GTK) and Windows.

demo ubuntu

demo windows

Here contains more demos you may want to take a look.

Build demo

First make sure you have a C++ compiler that supports C++ 17 standard. It uses CMake to build the demo, make sure you have it installed. Currently support Windows and Linux on PC, the version on Mac OS is in the plan, and you can find the Android version in here.

  • CygWin or MinGW is recommended to be installed on Windows, and Gdiplus is required.
  • GTKMM and GSVMM must be installed on Linux for a GTK build.
  • Qt development packages must be installed for a Qt installation.

After all the dependencies have been satisfied, run the following commands to build:

cd your/project/dir
mkdir build
cd build
cmake ..
make -j32

After all the works have done, run the executable file LaTeX in the directory build to check the demo.

If you wish to build in Qt mode on your plaform add -DQT=ON to the cmake command above.

Headless mode

It supports to run with headless mode (no GUI) on Linux OS, check the scripts below to learn how to do this.

Batch mode:

./LaTeX -headless \
    -samples=res/SAMPLES.tex \
    -outputdir=samples \
    -prefix=sample_ \
    # common options
    -textsize=14 \
    -foreground=black \
    -background=white \
    -padding=0 \
    -maxwidth=720

Single mode:

./LaTeX -headless \
    "-input=\sqrt[3]{(x-y)^3}=x-y" \
    -output=an_example.svg
    # other options...

COMMON OPTIONS

  • -h: show usages and exit

  • -headless: tells the application to run with the headless mode, that converts the input LaTeX codes into SVG images

  • -textsize: config the font size (in point) to display formulas, the default is 20

  • -foreground: config the foreground color to display formulas; the value can be a color name or in the form of #AARRGGBB; default is black

  • -background: config the background color to display formulas; the value can be a color name or in the form of #AARRGGBB; default is transparent

  • -padding: config spaces to add to the SVG images, the default is 10

  • -maxwidth: config the max width of the graphics context, the default is 720 pixels; this option has weak limits on the SVG images, thus the width of the SVG image may be wider than the value defined by this option

BATCH MODE OPTIONS

The program will save the SVG images produced by the LaTeX codes that parsed from the given file (specified by the option '-samples') into the directory specified by the option '-outputdir'.

  • -outputdir: indicates the directory to save the SVG images

  • -samples: specifies the file that contains several LaTeX codes split by a line that consists of the character '%' only, the default is './res/SAMPLES.tex'; check this file to get more details

  • -prefix: specifies the prefix of the filename of the SVG images, the default is ''; for example if 2 pieces of code have given with the option '-prefix=a_', the filename of the SVG images will be 'a_0.svg' and 'a_1.svg'

SINGLE MODE OPTIONS

  • -input: the source code that is written in LaTeX

  • -output: indicates where to save the produced SVG image, only works if the option '-input' has given

NOTICE

If both '-outputdir' and '-input' are specified, the '-input' option wins. Run the command ./LaTeX -h to get helps.

Please read this section to learn more.

Compile-time options

The program can be built just fine using the default compilation options. However, if required, the options documented below can be used to omit some features (that can reduce the library size) and to check memory only.

HAVE_LOG

If HAVE_LOG is defined, the program will output some logs (e.g.: the symbols parse result, generated box tree and so on) during runtime to help us to find out if there're issues or bugs, the default is ON. The option will be disabled when building with release mode, you can set it to OFF manually to make double insurance. For example, when parsing the following LaTeX code with the option is defined:

\sqrt[3]{(x-y)^3}=x-y

example have log

will produce the following box tree:

0    HBox
1    ├── HBox
2    │   ├── StrutBox
2    │   ├── CharBox
2    │   ├── StrutBox
2    │   └── HBox
3    │       ├── CharBox
3    │       └── OverBar
4    │           ├── StrutBox
4    │           ├── RuleBox
4    │           ├── StrutBox
4    │           └── HBox
5    │               ├── HBox
6    │               │   ├── CharBox
6    │               │   ├── GlueBox
6    │               │   ├── CharBox
6    │               │   ├── GlueBox
6    │               │   ├── CharBox
6    │               │   ├── GlueBox
6    │               │   ├── CharBox
6    │               │   ├── GlueBox
6    │               │   └── HBox
7    │               │       ├── CharBox
7    │               │       ├── HBox
8    │               │       │   ├── CharBox
8    │               │       │   └── StrutBox
7    │               │       └── StrutBox
5    │               └── StrutBox
1    ├── GlueBox
1    ├── CharBox
1    ├── GlueBox
1    ├── CharBox
1    ├── GlueBox
1    ├── CharBox
1    ├── GlueBox
1    └── CharBox

The number represents the depth of the tree node.

GRAPHICS_DEBUG

If this macro is defined, then the custom command \debug and \undebug will be compiled, the default is ON. The program will draw some assisted information to help us to check if there're issues when draw formulas after run \debug, and \undebug will close this feature. For example, parse the LaTeX code below:

\debug
\newcolumntype{s}{>{\color{#1234B6}}c}
\begin{array}{|c|c|c|s|}
  \hline
  \rowcolor{Tan}\multicolumn{4}{|c|}{\textcolor{white}{\bold{\text{Table Head}}}}\\
  \hline
  \text{Matrix}&\multicolumn{2}{|c|}{\text{Multicolumns}}&\text{Font size commands}\\
  \hline
  \begin{pmatrix}
      \alpha_{11}&\cdots&\alpha_{1n}\\
      \hdotsfor{3}\\
      \alpha_{n1}&\cdots&\alpha_{nn}
  \end{pmatrix}
  &\large \text{Left}&\cellcolor{#00bde5}\small \textcolor{white}{\text{\bold{Right}}}
  &\small \text{small Small}\\
  \hline
  \multicolumn{4}{|c|}{\text{Table Foot}}\\
  \hline
\end{array}

will produce:

example debug

The red blocks represent the depth of the boxes, and these rectangles represent the boxes' bounds.

MEM_CHECK

Basically, the program implemented an empty graphics interface (check this file), all the other implementations will be ignored if the MEM_CHECK option is defined, the default is OFF. It is useful when using valgrind to detect memory leaks and memory misuse, make sure you have compiled it with the option -DCMAKE_BUILD_TYPE=Debug before using valgrind. The following script shows how to do memory check using valgrind.

cmake 
    -DCMAKE_BUILD_TYPE=Debug \
    -DGRAPHICS_DEBUG=ON \
    -DMEM_CHECK=ON \
    -DHAVE_LOG=OFF ..
make -j32
valgrind --leak-check=full -v ./LaTeX

will produce:

==26443== HEAP SUMMARY:
==26443==     in use at exit: 72,704 bytes in 1 blocks
==26443==   total heap usage: 84,520 allocs, 84,519 frees, 12,515,092 bytes allocated
==26443== 
==26443== Searching for pointers to 1 not-freed blocks
==26443== Checked 111,952 bytes
==26443== 
==26443== LEAK SUMMARY:
==26443==    definitely lost: 0 bytes in 0 blocks
==26443==    indirectly lost: 0 bytes in 0 blocks
==26443==      possibly lost: 0 bytes in 0 blocks
==26443==    still reachable: 72,704 bytes in 1 blocks
==26443==         suppressed: 0 bytes in 0 blocks
==26443== Reachable blocks (those to which a pointer was found) are not shown.
==26443== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==26443== 
==26443== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Meson build manifest

You can also build the cairo version of cLaTeXMath with Meson:

meson _build -DTARGET_DEMO=NONE # you can specify TARGET_DEMO=GTK if you want a GTK+ GUI to test cLaTeXMath, otherwise only the library (TARGET_DEVEL) will be built.
ninja -C _build
_build/clatexmath

Prebuilt packages

@sp1ritCS maintains more or less upto date packages of cLaTeXMath/cairo for Arch, CentOS, Debian, Fedora, Mageia, SLE, openSUSE & Ubuntu on the openSUSE Buildservice: home:sp1rit:notekit/clatexmath.

The binaries (built packages) are publicly (without SUSE univention account) available here: download.opensuse.org/repositories/home:/sp1rit:/notekit/. Install instructions can be found on openSUSE's software-o-o instance:

If you just want to use cLaTeXMath for your GTK/Cairo project, this may be best way to get started.

How to use

This section shows how to use this library to display mathematical formulas.

First, load the required resources at the very beginning:

#include "latex.h"

using namespace tex;

/**
 * Initialize the program with the default parameter (directory
 * path of the resources) value "res" to load required resources,
 * that may take a long time, you may call it from a background
 * thread.
 *
 * Also, you can use the code below to specifies your custom
 * resources directory:
 * 
 *      LaTex::init("your/resources/root/directory");
 */
LaTeX::init();

// After initialization, you could display your formulas now

You could set the point size (pixels per point) use the code below:

/** 
 * Set the point size; the default value is 1 that means
 * use 1 pixel to represent 1 point.
 */
TeXFormula::PIXELS_PER_POINT = 2;

Also, you could set the DPI (dots per inch) use the code below:

/**
 * For example, set the DPI-target to 74, the point size
 * will be 74/72
 */
TeXFormula::setDPITarget(74);

Write the code below to release resources before application exit, it is not necessary but is a good habit.

// ... some other code ...
// before application exit

LaTeX::release();

Display mathematical formulas

General mode:

// ... initialization ...

/**
 * The LaTeX code to parse.
 * 
 * The program uses wide string to represent UTF characters, you
 * could use the code below to convert a string with UTF-8 encoding
 * to a wide string:
 * 
 *      wstring wstr = utf82wide("A string with UTF-8 encoding.");
 */
wstring code = L"\\int_{now}^{+\\infty} \\text{Keep trying}";
// Convert the code to a paintable object (TeXRender)
auto r = LaTeX::parse(
    code,   // LaTeX code to parse
    720,    // logical width of the graphics context (in pixel)
    20,     // font size (in point)
    10,     // space between 2 lines (in pixel)
    BLACK   // foreground color
);

Builder mode:

wstring code = L"\\int_{now}^{+\\infty} \\text{Keep trying}";
TeXFormula formula;
TeXRenderBuilder builder;
formula.setLaTeX(code);

auto r = builder
    // environment style, see TeXConstants (defined in common.h) to
    // get more details
    .setStyle(STYLE_DISPLAY)
    // text size (in point)
    .setSize(20)
    // the logical width and the alignment of the graphics context
    .setWidth(UnitType::pixel, 720, Alignment::left)
    // set if the logical width of the graphics context specified
    // above is the max width to display the formula, the formula
    // will be centered if set to true; you must call this method
    // after 'setWidth' has called, otherwise an ex_invalid_state 
    // exception will be thrown
    .setIsMaxWidth(false)
    // space between 2 lines
    .setLineSpace(UnitType::pixel, 10)
    .setForground(tex::BLACK)
    // convert the formula to a paintable object (TeXRender)
    .build(formula);

NOTICE

A style and text size are required to build a TeXRender, in another word, you must call method setStyle and setSize before method build has been called, otherwise an ex_invalid_state exception will be thrown. If the logical width has not set, the generated TeXRender may be wide enough to overflow into the graphics context.

Now you can draw the generated TeXRender (take Graphics2D_cairo that uses cairomm to implement the graphics (2D) context that run in Linux as an example):

// cairomm implementation
Graphics2D_cairo g2;
// draw the formula on the coordinate (10, 10) of the graphics context
r->draw(10, 10);
// IMPORTANT: remember to delete the generated TeXRender after there
// is no use on it.
delete r;

The code above will produce:

example keep trying

Implement the graphical interfaces

Basically, you need to implement all the interfaces declared in this file. There're 4 implementations list below, check it out before the start.

  • graphic_cairo: that uses cairomm and gtkmm to implement these interfaces that run in Linux, declared in here, and implemented here.

  • graphic_win32: is a Windows implementation that uses gdiplus to implement these interfaces, please check here and here.

  • And implementations on Android OS can be found at here.

  • And the empty implementations to perform memory check are defined in here.

The following sections illustrate these interfaces.

tex::Font

This interface represents a font (typeface). The program uses it to draw characters and layout boxes. The code below shows how to implement this interface with the name Font_impl.

#include "graphic/graphic.h"

namespace tex {

class Font_impl : public tex::Font {
public:

    Font_impl(const string& file, float size) {
        // load platform-specific font from given file and size
    }

    Font_impl(const string& name, int style, float size) {
        // create platform-specific font with given name, style
        // and size
    }

    // ... implementations of the other methods ...
};

/**
 * IMPORTANT: do not forget to implement the 2 static methods below,
 * it is the factory methods to create a new font.
 */

Font* Font::create(const string& file, float size) {
    return new Font_impl(file, size);
}

sptr<Font> Font::_create(const string& name, int style, float size) {
    return sptrOf<Font_impl>(name, style, size);
}

} // namespace tex

tex::TextLayout

An alphabet contains several Unicode-blocks on a Basic Multilingual Plane (BMP), check here for more information.

For these characters in unregistered alphabets, the library uses tex::TextLayout to layout it. For example, parse the following LaTeX code:

\int_{now}^{\infty} \text{努力}

The character "努" and "力" are under the Unicode-block CJK Unified Ideographs belongs to the alphabet CJK that has not registered with the program, it will use the implementation of the class tex::TextLayout to layout the text "努力" and calculate the layout bounds. The tex::TextLayout_cairo implementation (declared in here) demonstrates how to do this.

The LaTeX code above will produce:

example cjk trying

The predefined Unicode-blocks are list below, check this file for more details.

name               code range
-----------------  ---------------
BASIC_LATIN        0x0020 ~ 0x007F
LATIN1_SUPPLEMENT  0x0080 ~ 0x00FF
CYRILLIC           0x0400 ~ 0x04FF
GREEK              0x0370 ~ 0x03FF
GREEK_EXTENDED     0x1f00 ~ 0x1FFF
UNKNOWN            0xFFFF ~ 0xFFFF

Write the code below to register a new alphabet with the program:

class NewAlphabetRegistration : public AlphabetRegistration {
private:
    vector<UnicodeBlock> _blocks;

public:
    NewAlphabetRegistration(const vector<UnicodeBlock>& blocks)
        :_blocks(blocks) {}

    const vector<UnicodeBlock>& getUnicodeBlock() const override {
        return _blocks;
    }

    const string getPackage() const override {
        // the root directory path of the font-mapping and
        // symbols-mapping for this alphabet
    }

    const string getTeXFontFile() const override {
        // language settings (a xml file) for this alphabet
    }
};

// ... some other code ...

// Define a new Unicode-block
auto newBlock = UnicodeBlock::define(
    newAlphabetCodePointStart, 
    newAlphabetCodePointEnd);

// Register the new alphabet
DefaultTeXFont::registerAlphabet(new NewAlphabetRegistration({newBlock});

tex::Graphics2D

This interface defines a 2D graphics context, all the TeX drawing operations will on it. It declares various basic 2D graphics operations, including affine transformations and meta graphical operations. The class Graphics2D_cairo (defined in this file) uses cariomm to implement this interface, take it a look to learn how to achieve it. It is the most important part of the graphical environment, and also very simple, all you need to do is wrap these functions on a specific platform into the form of this interface declared. This file declares some built-in colors and various entity classes to support the graphical environment.

Custom commands and symbols

\debug and \undebug

As mentioned above, the command \debug and \undebug is used to switch graphical debug mode on/off, please check it out.

\fatalIfCmdConflict

This command takes a boolean argument to determine whether to raise an error that when defining a new command but it has defined already or redefining a command but it has not defined. The default value is true. The script below shows how to use it.

\fatalIfCmdConflict{true}
% define a new command with the name R
\newcommand{\R}{\mathbb{R}}
\R
% here will cause the program throws an error
% use \fatalIfCmdConflict{false} to disable it
\newcommand{\R}{\mathcal{R}}

\breakEverywhere

This command takes a boolean argument, the predefined value is false. Its functionality is hard to describe, an example worths thousands of words, the examples below show the difference between when it set to true and false.

\text{What is real? How do you define ‘real’? If you're talking about what you can feel, what you can smell, what you can taste and see, then ‘real’ is simply electrical signals interpreted by your brain. \bold{\text{― Morpheus The Matrix}}}

When with \breakEverywhere{false}, the result will be:

bw false

And with \breakEverywhere{true}, the result will be:

bw true

NOTICE

The program has a weak ability to handle line feeds when laying out texts, you should try to avoid using it to lay out large amounts of text, delegate these tasks to the text-layout system, and use this program to display formulas is a good choice.

\TeX and \AndroidTeX

The logo and the logo of the Android version are produced by the command \TeX and \AndroidTeX, take a quick look:

\TeX \\
\AndroidTeX

logos

Custom symbols

There're 4 custom symbols in the script below:

AB \varparallel CD
AB \nvarparallel CD
AB \varparalleleq CD
\parallelogram ABCD

that will produce:

custom symbols

TODO

  • port Gtk+ 3 to Windows and macOS
  • buitin resources
  • support for webassembly
  • native support for SVG
  • make the use of XML configurable
  • make the built-in resources a loadable/unloadable dynamic plugin
  • eliminate the use of 'dynamic_cast'
  • rewrite the parsing algorithm, make it more efficient
  • support for dynamic parsing
  • implement the \def command

License

Excluding the fonts and xml resources (under the directory res) that under different licenses (check out res/fonts/license, res/greek and res/cyrillic), this project is under the MIT license.

 The MIT License (MIT)

 Copyright (c) 2020 Nano Michael

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in all
 copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.

microtex's People

Contributors

alexxey593 avatar blackhole89 avatar dorianrudolph avatar iven avatar jeremysanders avatar lazingor avatar lyessaadi avatar nanojeomichael avatar nanomichael avatar peteschaefer avatar pikachuhy avatar sp1ritcs avatar xrysnow 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

microtex's Issues

Size of math within \text in context with modified font size

This is extremely low priority, but you might be interested. I noticed that font sizing of encapsulated math within a \text does not respect the sizing of the context. Take for example
x^{\text{a $n$}} \sum_{\substack{k \geq 0 \\ j \geq 0 \\ \text{and $k > j$}}} f(k,j)
The "a" and the "and" are rendered in the correct, smaller size, but the math within the \text is rendered at regular size.

I attach screenshots from the project demo and from latex.

cLaTeXMath:
mathInText

LaTeX:
mathInTextLaTeX

Obtaining baseline

If the library is used to render a single line, say \text{Let } f(x) = \int_0^x g(t) dt, is there a convenient way to pull out the baseline position of that line, i.e. the vertical position just below the L?

I thought it might be TeXRender::getBaseline(), but I find it hard to read what this function actually returns. The code is

((_box->_height * _textSize + 0.99f + _insets.top) /
          ((_box->_height + _box->_depth) * _textSize + 0.99f + _insets.top + _insets.bottom));

The denominator here is almost the value of getHeight(), except that getHeight() has another + 0.99f. Does the numerator somehow give the actual baseline?

Or is there some other way to retrieve the baseline?

Passing data up the render/box tree

Is there a way for an Atom to store some data at the top level of the box tree (or somewhere), in the createBox() method?

Basically, I have a custom macro that creates a custom Atom, and I want that atom to add some data (say a string) to some top-level object, whether it's the very top atom of the tree, or the TeXEnvironment, or a TeXRender object, in a way that can be exposed to other methods, but I can't quite see what the best way to implement it is. Any suggestions?

Inconsistent rendering results

When I use Qt, I meet

render_bug

Sometimes the rendered result is the lower part of the picture.

I guess there is something that affects the calculation of the spacing.

"x = \pi" leads to segmentation fault in demo

Typing in x = \pi in the demo app leads to a segmentation fault. Curiously = \pi is fine, as is x = 2. Is it because there's a shared font between x and \pi? Here's the end of the debug log output:

FILE: /home/code/cLaTeXMath/src/fonts/fonts.cpp, LINE: 190, FUNCTION: getChar, MSG: { char: x, font id: 2, path: res/fonts/base/cmmi10.ttf }
FILE: /home/code/cLaTeXMath/src/fonts/fonts.cpp, LINE: 190, FUNCTION: getChar, MSG: { char: =, font id: 18, path: res/fonts/latin/cmr10.ttf }
FILE: /home/code/cLaTeXMath/src/fonts/fonts.cpp, LINE: 190, FUNCTION: getChar, MSG: { char: �, font id: 5, path: res/fonts/base/cmmi10.ttf }
res/fonts/base/cmmi10.ttf already loaded, skip
[BOX TREE]:
0    HorizontalBox
1    ├── CharBox
1    ├── GlueBox
1    ├── CharBox
1    ├── GlueBox
1    └── CharBox

FILE: /home/code/cLaTeXMath/src/fonts/fonts.cpp, LINE: 45, FUNCTION: ~DefaultTeXFont, MSG: DefaultTeXFont destruct
Segmentation fault (core dumped)

Unresolved external symbol -- How to use the library ?

Hello,

I discovered this library because I want to include LaTeX equations in my app (I am using Dear ImGui as my GUI library).
I looked into the samples to get inspiration. I figured out that I need to implement my own derived classes Font , TextLayout and Graphics2D in graphic.h. So I generated some empty classes that basically do nothing but that are still implemented (like in win32_main.cpp).

However, if I call just LaTex::init() in my main, the application does not link. I get:
LaTeX.lib(box_single.obj) : error LNK2019: unresolved external symbol "public: static class std::shared_ptr<class tex::TextLayout> __cdecl tex::TextLayout::create(class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const &,class std::shared_ptr<class tex::Font> const &)" (?create@TextLayout@tex@@SA?AV?$shared_ptr@VTextLayout@tex@@@std@@AEBV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@4@AEBV?$shared_ptr@VFont@tex@@@4@@Z) referenced in function "private: void __cdecl tex::TextRenderingBox::init(class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const &,int,float,class std::shared_ptr<class tex::Font> const &,bool)" (?init@TextRenderingBox@tex@@AEAAXAEBV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@HMAEBV?$shared_ptr@VFont@tex@@@4@_N@Z)
I kind of understand the issue: the linker is trying to find implementations of Font , TextLayout and Graphics2D but can't because they are abstract classes.

So, my basic question is: what is the minimal code I need to write to get MicroTeX compiling and embedded into a C++ application ? I don't really care about functionnality (I will implement the different draw calls one by one)

Here are some informations:

  • Compiler: MSVC (I tried MingGw, but I have other problems with it)
  • OS: windows 10
  • GUI library: Dear ImGui + glfw
  • Version of MicroTex: the latest commit in master
  • I add MicroTeX to my app by doing add_subdirectory(external/MicroTeX) in a CMakeLists.txt and link it properly with target_link_libraries(${PROJECT_NAME} PRIVATE LaTeX)
  • Tinyxml2 is installed on my system

Thank you for your help

Flutter support

flutter is a great cross-platform framework. If you support flutter, it will make cross-platform extremely simple.

Licensing

Great project! I notice there is currently no word on the license in the repository. It would be great if you could make it available under GPL or something compatible with it, since it appears to be a perfect match for my markdown notetaking program (which currently uses the abandoned and buggy Lasem for rendering LaTeX instead).

compile error in macro_def.cpp

The macro mac in core/macro_def.cpp dosen't work well in VS and will give compile error.

错误 C2440 “初始化”: 无法从“initializer list”转换为“std::map<std::wstring,tex::MacroInfo *,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>”

Unrecognized environment: equation

\begin{equation}
  L(Y, f(X))=\left\{
  	\begin{aligned}
  	1, \quad Y \neq f(X)\\
  	0, \quad Y = f(X)\\
  	\end{aligned}
  	\right
  	.
  \end{equation}

expect:
image
actual:
image

Peculiar linebreaking in long equations

We seem to get some peculiar linebreaking effects in long equations. Say we run it with

x = y + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a

(enough to fill the drawing width on my screen), then the line never breaks, and we render out of bounds in the sample Cairo program.
without3
(The canvas renders dark, I think because the line goes out of bounds.)

But if we add a + 3 somewhere in the middle, it breaks the line before the 3:

x = y + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + 3 + a + a + a + a + a + a + a + a + a + a + a

with3

With \breakEverywhere{true} it seems to break at the correct point:

\breakEverywhere{true} x = y + a + a + a + a + a + a + a + a + a + a + a + a + a + b + a + a + a + b + b + b

breakEverywhere

But \breakEverywhere{true} will probably cause some other issues, so it'd be good to figure out why the first equation isn't being split as one would expect.

I haven't had a chance to dig into the code to figure out what's special about the 3, or why it doesn't break the original equation without breakEverywhere, but I figured I'd file this issue here for later.

Is cLaTeXMath violating the GPL?

So... Who isn't excited from some licensing fun (: ?

Anyway... I'm trying to package cLaTeXMath for Fedora... The package have been approved for ~1.5 week and I still haven't even imported it into the Fedora Git. Why ? Because of Licensing (: ...

So, it seems that cLaTeXMath is a rewrite of jlatexmath in C.

To my (very) limited understanding of copyright law, cLaTeXMath is violating the GPL in three ways... Let's review them, shall we?

The issues

  1. Font licenses: So, thanks to eclipseo (a Fedora contributor who reviewed the package, and, honestly, a heavenly gift sent upon this cursed land) cLaTeXMath gets its fonts from jlatexmath... jlatexmath breaks down the licenses of each font, and cLaTeXMath has respected this breakdown wonderfully and provided all the licenses (thank you for that :D). BUT, in jlatexmath some fonts have... No license specified? It would be assumed then that those licenses are under GPL... Which... Would be weird, but whatever. Those fonts are the cyrillic and greek ones as well as special.ttf. I have opened a ticket upstream to try and clear up things, but nothing yet (if you have any clue, I'd be happy to know it !)...
  2. XML files: Anyway, even if those fonts are not under GPL, there is another problem: the xml files for the cyrillic and greek fonts definitely are though, as they seem to gave been created by the jlatexmath devs (btw, are those really needed?).
  3. Rewriting of a GPL project: I discovered this one entirely by chance ^.^, and it actually is the one that pushed me to create this ticket right now as for the fonts one I was waiting for the jlatexmath answer. Anyway, according to the gnu.org GPL FAQ, when we rewrite a GPL code under a new programming language, it also needs to be GPL! Though, I am not confident about this one. Is cLaTeXMath really a rewrite of jlatexmath or just a program doing the same thing in a different programming language? Where is the line between those two? I have no idea, and this is making me MAD.

What should be done

  1. Adding a breakdown similar to jlatexmath's describing in details which font file is under which license to maybe help future helpless packager souls which may enter this cursed words of font licenses and help them through their quest.
  2. Adding the GPL to the fonts licenses if the xml files are needed.
  3. Eventually adding new licenses when the jlatexmath project finally answers my helpless plead for forgiveness upon my soul for having dared to decipher legalese.
  4. Sacrifice lawyers to the all mighty GPL god and pray for its benevolence.
  5. Relicense cLaTeXMath to the GPL if it indeed is a rewrite of the jlatexmath project. That should not be an issue since the MIT license is compatible with the GPL license (no need to ask for every contributor's agreement).

Conclusion

Copyright laws are annoying and let's blame the British for that.

special.ttf symbols

Hello 😀!

Who you gonna call when there's a licensing issue with a font? Ghostbusters! Me 😛!

Anyway, still on my quest to get this packaged in Fedora, I'm looking again into special.ttf!

  • \android: Let's begin with this symbol. Using my amazing detective skills, I scoured through the archive, went through the files, entered the matrix, hacked Nasa's website with HTML and just simply typed android svg font on DuckDuckGo to determine that it probably came from here. The issue is that this website doesn't really seem to be reliable when checking submission's licenses, and using a Google Reverse image search point to other duplicates, most with a proprietary license, which is not really great... So, I need to ask if it was really from there or from somewhere else? Also, as I'm typing this @sp1ritCS is trying to redo the image on Inkscape.
  • \TeX: It's a bit weird not using the standard TeX symbol (it's apparently from AndroidLaTeXMath)? But, do you remember what font is that?
  • \texteuro: I can't find the origin of this glyph, and it's probably from a Debian font according to calitexman (jlatexmath), but he can't remember. Unfortunately, as the killjoy that I am, that is not enough 😛! Are you open to me swapping it with another font's Euro symbol? URW Bookman's euro symbol is quite similar, for instance.
  • \textmu: This is the euro symbol, but it shouldn't be? Is this a bug?
  • And, most importantly, crucial to this entire project, what will decide of the fate of this world, which may bring death or eternal happiness on this land: Are you the one to have drawn the magnificent, the superb, the incredible, the absolute, the unique and the holy \parallelogram? This piece of art is indeed the essence of this whole project. No, to be serious, that seems quite silly, but I still need to make sure of whether you drew it yourself or if it is from somewhere else 😛!

Anyway, I'm going back to hide in the shadows until my master, © Copyright™, calls for me again.

Conflict with some macros

My environment has macro UNICODE and DEBUG defiened and they conflict with some names in the project. I think it's better to rename them to avoid this.

Security and implementation

This project looks awesome! I was wondering: can one get an overview of how much of LaTeX it implements? Is it based on some other implementation? Are all the LaTeX commands it supports in one and the same file, or are they spread out?

Second question: are there any security implications from using this library? Does it allow any shell escaping or system calls, or that kind of thing? I know TeX is its own programming language and has commands like \input.

Qt interface

Hi -

Are there any objections to looking at a possible Qt interface?

Fonts don't work when building with Cairo on Windows

When building with the Cairo graphics backend under Windows (using msys2-mingw64, which seems to be the best solution for porting a Gtk+ 3 application to Windows at the moment), all fonts fall back to the default sans font (so no math symbols render correctly, etc.) This is because Cairo::select_font_face always uses the "system default" font selector, which is the native win32 mechanism when building under Windows, but Font_cairo loads fonts by making them visible to fontconfig only.

I have a solution to this that stores a Cairo::FtFontFace object inside Font_cairo and loads it using Cairo::set_font_face, and can make a PR if you are interested. I haven't tested it that extensively though, and you might want pick a different approach.

cross "platformnes" of the cairo/gtk version

Hi Nano,

we are currently working on getting NoteKit on as many as possible distros / OS's working. As we depend on cLaTeXMath we have also created packages (and patches) for it.

home:sp1rit:testing:notekit/clatexmath builds deb packages for Debian and Ubuntu, rpm's for *SUSE, Fedora, Mageia & CentOS, and .pkg.tar.zst for Arch. I think the Debian copyright file (within the debian.tar.xz) should get updated to explicitly mention the licenses from the fonts (and those xml files :D)

home:sp1rit:mingw/mingw-clatexmath build x86_64 and i686 mingw dlls for use in fedora's mingw space that we use to automatically nightly build notekit for Windows. However building cLaTeXMath on MinGW some issues.
First M_PI is not supported and has to be replaced with the G_PI constant: use_glib_pi_const.diff

Also on newer versions of some *mm package (I think it was pangomm) that fedora 34 carries, the way symbols are exposed on windows changed and that caused clatexmath to stop building. @LyesSaadi solution was just to remove the samples since the offending line was in there (afaik Pango::Init) in the spec file:

rm -rf src/samples/
sed -i '99,104d' meson.build
sed -i '163,167d' meson.build

However that also affects our notekit build on anything newer than f33, until the bug is fixed.

Also regarding MinGW, if you run clatexmath within native MinGW on Windows, the LaTeX::queryResourceLocation( is unable to detect /mingw64/share/clatexmath because it's wraped in an #ifndef _WIN32 by @Xrysnow .

The block

char* xdg = getenv("XDG_DATA_DIRS");
  if (xdg != NULL && strcmp(xdg, "") != 0) {
    stringstream xdg_paths(xdg);
    string xdg_path;
    while (getline(xdg_paths, xdg_path, ':')) {
      paths.push(xdg_path);
    }
  }

would have to be moved of of the ifndef block in order for it to work.

On OS X I have a homebrew tap setup here @sp1ritCS/homebrew-tap, so if you have homebrew installed you can simply type brew install sp1ritCS/tap/clatexmath.

Unimath: \not shifts itself incorrectly

To reproduce, try:

$-5\not\in [0;11]$

The upper window is notekit w. unimath that has the broken \not, while the lower window is notekit with current clm 0.0.4, which looks as expected.
Bildschirmfoto von 2022-03-14 14-10-28


what I've also noticed is, that the ' for derivative functions looked far better in current clm than it does with unimath. Is this some kind of font issue?

Different fonts

Is there some documentation on how to go about using another font with this library?

I wonder if some more modern fonts might avoid the need for so many font files. For example, another library just has latinmodern-math.otf and xits-math.otf available. (See e.g. https://github.com/kostub/iosMath/tree/master/fonts )

MathJax and KaTeX have also done some nice work on math fonts for on-screen display, and it could be worth including these. (I think they've just fattened up some AMS fonts.)

Again, great work with this library!

Error in calculation of height?

I wonder if there is an issue in the calculation of the height of some pieces of latex: if you have the library render \debug x^2 you get
heightIssue
As you can see, the 2 sticks out of the top of the bounding box, and I think this translates to the _height of the overall box being calculated incorrectly. There seem to be lots of places _height gets set for various boxes, and I don't quite know where to start debugging this one - any tips?

Generate canvas instructions when no direct access to a canvas

I just discovered that the programming language to which I was hoping to link this library does not support callbacks, which means I cannot directly have the library draw on my program's canvas. In other words, I can only pull data from the library, not have the library pull data from my program.

I was thinking of trying to get around this by implementing the interfaces in graphics.h as outputting text, that I could then interpret and lay out in my program's canvas. So I would pull text like

setColor(red)
setFont(...)
drawText(...)

Do you think this is at all feasible? I am a little bit worried about data that the library might need, that it pulls from elsewhere while it is layout out. For example, does the need for TextLayout.getBounds() break the above idea?

Use macro instead of configure file

In #48, a configure file is added for compatibility with older gcc. But this can be done through macro __GNUC__. Use the macro is more portable for cross compiling and embedding.

Errors from font files in demo

I've set up the demo, but when I type something as simply as "x+y" I am getting error messages like so:

block of char: 43 is 0
FILE: /home/code/cLaTeXMath/src/fonts/fonts.cpp, LINE: 191, FUNCTION: getChar, MSG: { char: x, font id: 2, path: res/fonts/base/cmmi10.ttf }
FILE: /home/code/cLaTeXMath/src/platform/cairo/graphic_cairo.cpp, LINE: 45, FUNCTION: loadFont, MSG: Load font: res/fonts/base/cmmi10.ttf, count: 32766
Null pattern
FILE: /home/code/cLaTeXMath/src/platform/cairo/graphic_cairo.cpp, LINE: 52, FUNCTION: loadFont, MSG: Load res/fonts/base/cmmi10.ttf failed
[1]    53223 segmentation fault  /home/code/cLaTeXMath/build/LaTeX

I found a similar issue here

Mac/Apple support

I'm opening this issue to let others know that I'm working on Apple platform support right now (hopefully avoiding duplicate work). I have a branch in my fork named "macport" for this work. It's rendering all of the samples correctly in my test app. The only thing left to do is check the Windows & Linux builds to make sure I haven't broken anything, and clean up my test app.

Note that my changes should work on all Apple platforms. I'll test on iOS before submitting my PR since that's likely the one most people would be interested in.

version 0.0.1: make: *** [Makefile:91:all] error 2

compile for version 0.0.1 error

      |                                                       ^~~~~
In file included from /home/guoyi/Downloads/clatexmath/src/cLaTeXMath-0.0.1/src/res/builtin/tex_param.res.cpp:1:
/home/guoyi/Downloads/clatexmath/src/cLaTeXMath-0.0.1/src/fonts/fonts.h:60:20: 警告:dynamic exception specifications are deprecated in C++11 [-Wdeprecated]
   60 |         int style) throw(ex_text_style_mapping_not_found) = 0;
      |                    ^~~~~
/home/guoyi/Downloads/clatexmath/src/cLaTeXMath-0.0.1/src/fonts/fonts.h:80:57: 警告:dynamic exception specifications are deprecated in C++11 [-Wdeprecated]
   80 |     virtual Char getChar(const string& name, int style) throw(ex_symbol_mapping_not_found) = 0;
      |                                                         ^~~~~
/home/guoyi/Downloads/clatexmath/src/cLaTeXMath-0.0.1/src/fonts/fonts.h:310:79: 警告:dynamic exception specifications are deprecated in C++11 [-Wdeprecated]
  310 |     static void addTeXFontDescription(const string& base, const string& file) throw(ex_res_parse);
      |                                                                               ^~~~~
/home/guoyi/Downloads/clatexmath/src/cLaTeXMath-0.0.1/src/fonts/fonts.h:317:29: 警告:dynamic exception specifications are deprecated in C++11 [-Wdeprecated]
  317 |         const string& lang) throw(ex_res_parse);
      |                             ^~~~~
/home/guoyi/Downloads/clatexmath/src/cLaTeXMath-0.0.1/src/fonts/fonts.h:348:20: 警告:dynamic exception specifications are deprecated in C++11 [-Wdeprecated]
  348 |         int style) throw(ex_text_style_mapping_not_found) override;
      |                    ^~~~~
/home/guoyi/Downloads/clatexmath/src/cLaTeXMath-0.0.1/src/fonts/fonts.h:352:55: 警告:dynamic exception specifications are deprecated in C++11 [-Wdeprecated]
  352 |     Char getChar(const string& symbolName, int style) throw(ex_symbol_mapping_not_found) override;
      |                                                       ^~~~~
/home/guoyi/Downloads/clatexmath/src/cLaTeXMath-0.0.1/src/core/macro_def.cpp:336:28: 警告:dynamic exception specifications are deprecated in C++11 [-Wdeprecated]
  336 |     const wstring& enddef) throw(ex_parse) {
      |                            ^~~~~
/home/guoyi/Downloads/clatexmath/src/cLaTeXMath-0.0.1/src/core/macro_def.cpp:343:26: 警告:dynamic exception specifications are deprecated in C++11 [-Wdeprecated]
  343 |     const wstring& code) throw(ex_parse) {
      |                          ^~~~~
make[1]: *** [CMakeFiles/Makefile2:83:CMakeFiles/LaTeX.dir/all] 错误 2
make: *** [Makefile:91:all] 错误 2
==> 错误: 在 build() 中发生一个错误。
    正在放弃...

My opertaing

	cd "${srcdir}/${_pkgname}-$pkgver"
	mkdir build
	cd "${srcdir}/${_pkgname}-$pkgver"
	cd build
	cmake ..
	make -j32

'path' is unavailable: introduced in macOS 10.15

This feature #99 use std::filesystem, while std::filesystem is not available under macOS 10.15.

my version
macOS Mojave 10.14.6

due to this limitation, we need to add compatible code.

when std::filesystem is not available, we can fallback to boost::filesytem.

Check XDG/FHS locations

As @blackhole89 has already written in #36, cLaTeXMath is not checking locations for it's resources. The best way to do this, is to have a hidden file (.clatexmath-res_root) inside the resource directory. Then check the list of XDG/FHS complainant paths to see if one of them contains the file. I've written a small sample how this could be done - tho it requires c++17 and cLaTeXMath does not compile with std=c++17.

https://gist.github.com/sp1ritCS/9c81ae26a283ec5102c59a77c7fb5c3c

need support chemmacros \ce for chemical formulars

It seems that cLaTeXMath do not support chemical \ce macro.Will it be supported infuture?
such as : \ce{Hg^2+ ->[I-] HgI2 ->[I-] [Hg^{II}I4]^2-}

image

It's very important for me.Thank you for your efforts to make such a powerful library for C++.

convert otf file to clm file fail

error info

fontforge -lang=py -script otf2clm.py --sinle ../res/xits/XITSMath-Regular.otf true ../res/xits/XITSMath-Regular.clm2
Copyright (c) 2000-2020. See AUTHORS for Contributors.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 with many parts BSD <http://fontforge.org/license.html>. Please read LICENSE.
 Version: 20190801
 Based on sources from 03:10 UTC  6-Mar-2020-ML-D-GDK3.
parsing font ../res/xits/XITSMath-Regular.otf, please wait...
Traceback (most recent call last):
  File "otf2clm.py", line 719, in <module>
    main()
  File "otf2clm.py", line 710, in main
    parse_otf(
  File "otf2clm.py", line 625, in parse_otf
    glyphs.append(read_glyph(
  File "otf2clm.py", line 312, in read_glyph
    None if not parse_path else read_glyph_path(glyph),
  File "otf2clm.py", line 252, in read_glyph_path
    glyph.export(tf.name, usetransform=True)
TypeError: export() takes no keyword arguments

https://github.com/NanoMichael/cLaTeXMath/blob/a0493830bffccc30c4567b474319684ec9747166/prebuilt/otf2clm.py#L252

my env

  • WSL. Ubuntu 20.04.2 LTS (GNU/Linux 5.4.72-microsoft-standard-WSL2 x86_64)
  • fontforge
fontforge --version
Copyright (c) 2000-2020. See AUTHORS for Contributors.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 with many parts BSD <http://fontforge.org/license.html>. Please read LICENSE.
 Version: 20190801
 Based on sources from 03:10 UTC  6-Mar-2020-ML-D-GDK3.
fontforge 20190801
build date: 03:10 UTC  6-Mar-2020
  • python
python3
Python 3.8.5 (default, Jan 27 2021, 15:41:15)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

tmp solution
change glyph.export(tf.name, usetransform=True) to glyph.export(tf.name)

note: I don't have a deep understanding of the cause of this problem, and I'm not aware of the side effects of the tmp solution.

Wrong main font selection

I also found a bug (I think), in the way non math font families are handled. I've tried to put NoteKit's fontfamily "Charter" (https://github.com/blackhole89/notekit/tree/master/data/fonts) into the search dir, and the font senser also found all of them and added all of them with a single LaTeX::addMainFont invocation as "Charter" family. However, after calling LaTeX::setDefaultMainFont("Charter") instead of picking the correct style for \text{} it instead used the one that was in the last position of the FontSrcList, which happened to be "Charter Italic".

See #99

Make a template version of the latex parser that doesn't use `wchar_t`

Hi. Most LaTeX is not possible to use as UTF-16, so the wchar_t support seems mostly to be needed for the internationalisation support, and not LaTeX.

As it stands, it may be worth exploring a code path that doesn't rely on wchar_t and instead directly uses UTF-8 strings. In my case, this would significantly reduce the memory footprint, (embedded systems need to be miserly with the RAM), so I was wondering if you'd accept a PR that did that?

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.