mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-12-24 09:31:40 +08:00
NEW: added command line tool jkatmathtext_render that renders LaTeX into images, using it to generate the documentation images for JKQTMathText
This commit is contained in:
parent
afa14cbbfb
commit
bd1afe2a0a
@ -48,5 +48,11 @@ if(JKQtPlotter_BUILD_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
|
||||
if(JKQtPlotter_BUILD_TOOLS)
|
||||
add_subdirectory(tools)
|
||||
endif()
|
||||
|
||||
add_subdirectory(doc)
|
||||
|
||||
|
||||
|
||||
|
24
Doxyfile
24
Doxyfile
@ -877,7 +877,8 @@ WARN_LOGFILE =
|
||||
INPUT = . \
|
||||
./doc/dox/ \
|
||||
./lib \
|
||||
./examples
|
||||
./examples \
|
||||
./tools
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||
@ -906,9 +907,7 @@ INPUT_ENCODING = UTF-8
|
||||
# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd,
|
||||
# *.vhdl, *.ucf, *.qsf and *.ice.
|
||||
|
||||
FILE_PATTERNS = *.d \
|
||||
*.java \
|
||||
*.ii \
|
||||
FILE_PATTERNS = *.ii \
|
||||
*.ixx \
|
||||
*.ipp \
|
||||
*.i++ \
|
||||
@ -920,18 +919,8 @@ FILE_PATTERNS = *.d \
|
||||
*.h++ \
|
||||
*.idl \
|
||||
*.odl \
|
||||
*.cs \
|
||||
*.php \
|
||||
*.php3 \
|
||||
*.inc \
|
||||
*.m \
|
||||
*.mm \
|
||||
*.dox \
|
||||
*.py \
|
||||
*.f90 \
|
||||
*.f \
|
||||
*.vhd \
|
||||
*.vhdl \
|
||||
*.md
|
||||
|
||||
# The RECURSIVE tag can be used to specify whether or not subdirectories should
|
||||
@ -993,7 +982,9 @@ EXCLUDE_PATTERNS = */build-* \
|
||||
*/html/* \
|
||||
*examples/*.cpp \
|
||||
*examples/*.h \
|
||||
*/doc/html/*
|
||||
*/doc/html/* \
|
||||
*tools/*.cpp \
|
||||
*tools/*.h
|
||||
|
||||
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
|
||||
# (namespaces, classes, functions, etc.) that should be excluded from the
|
||||
@ -1010,7 +1001,8 @@ EXCLUDE_SYMBOLS =
|
||||
# that contain example code fragments that are included (see the \include
|
||||
# command).
|
||||
|
||||
EXAMPLE_PATH = ./examples/
|
||||
EXAMPLE_PATH = ./examples/ \
|
||||
./tools/
|
||||
|
||||
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
||||
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
|
||||
|
@ -11,7 +11,10 @@ if(NOT DEFINED JKQtPlotter_BUILD_DECORATE_LIBNAMES_WITH_BUILDTYPE)
|
||||
option(JKQtPlotter_BUILD_DECORATE_LIBNAMES_WITH_BUILDTYPE "If set, the build-type (debug/release/...) is appended to the library name" ON)
|
||||
endif()
|
||||
if(NOT DEFINED JKQtPlotter_BUILD_EXAMPLES)
|
||||
option(JKQtPlotter_BUILD_EXAMPLES "Build the examples examples" ON)
|
||||
option(JKQtPlotter_BUILD_EXAMPLES "Build the examples" ON)
|
||||
endif()
|
||||
if(NOT DEFINED JKQtPlotter_BUILD_TOOLS)
|
||||
option(JKQtPlotter_BUILD_TOOLS "Build the tools" ON)
|
||||
endif()
|
||||
if(NOT DEFINED JKQtPlotter_BUILD_FORCE_NO_PRINTER_SUPPORT)
|
||||
option(JKQtPlotter_BUILD_FORCE_NO_PRINTER_SUPPORT "Build the library with printer support switched off, even if it is available" OFF)
|
||||
|
@ -42,3 +42,5 @@ else()
|
||||
set(JKQtPlotter_QT_CXX_STANDARD_REQUIRED TRUE)
|
||||
set(JKQtPlotter_QT_CXX_COMPILE_FEATURE cxx_std_17)
|
||||
endif()
|
||||
|
||||
set(JKQtPlotter_QT_BINDIR $<TARGET_FILE_DIR:Qt${QT_VERSION_MAJOR}::qmake>) # ${QT_DIR}../../../../bin
|
@ -5,7 +5,9 @@ This section assembles some simple examples of usage.
|
||||
You can find more (complex) examples for the classes in this repository in the subfolder "test".
|
||||
All test-projects are Qt-projects that use qmake to build. You can load them into QtCreator easily.
|
||||
|
||||
\section jkqtp_extut Overview of Examples&Tutorials
|
||||
\tableofcontents
|
||||
|
||||
\section jkqtp_extut_jkqtplotter Examples&Tutorials for JKQTPlotter
|
||||
|
||||
\subsection jkqtp_extut_plotstyles Different Plot Data Styles
|
||||
|
||||
@ -219,24 +221,7 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
|
||||
<td> \subpage JKQTPlotterMandelbrot
|
||||
<td> Allows to zoom into the Mandelbrot Set, using the different Zooming methods of JKQTPlotter
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
\subsection jkqtp_extut_specialfeatures Tools and Special Features
|
||||
|
||||
<table>
|
||||
<tr><th> Screenshot <th> Description <th> Notes
|
||||
<tr><td> \image html jkqtmathtext_simpletest_small.png
|
||||
<td> \subpage JKQTMathTextSimpleExample
|
||||
<td> JKQTMathText<br>render LaTeX markup (Schrödinger's equation)
|
||||
<tr><td> \image html jkqtmathtext_testapp_small.png
|
||||
<td> \subpage JKQTMathTextTestApp
|
||||
<td> JKQTMathText<br>render LaTeX markup
|
||||
<tr><td> \image html jkqtfastplotter_test_small.png
|
||||
<td> \subpage JKQTFastPlotterTest
|
||||
<td> JKQTFastPlotter
|
||||
</table>
|
||||
|
||||
|
||||
\subsection jkqtp_extut_cmake_build CMake Build System
|
||||
|
||||
@ -245,6 +230,45 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
|
||||
<tr><td> \image html jkqtplotter_cmakelink_small.png
|
||||
<td> \subpage JKQTCMakeLinkExample
|
||||
<td> explains how to link against JKQTPlotter with CMake
|
||||
</table>
|
||||
|
||||
|
||||
\section jkqtp_extut_jkqtmathtext Examples for JKQTMathText
|
||||
|
||||
<table>
|
||||
<tr><th> Screenshot <th> Description <th> Notes
|
||||
<tr><td> \image html jkqtmathtext_simpletest_small.png
|
||||
<td> \subpage JKQTMathTextSimpleExample
|
||||
<td> JKQTMathText<br>render LaTeX markup (Schrödinger's equation)
|
||||
<tr><td> \image html jkqtmathtext_render_small.png
|
||||
<td> \subpage JKQTMathTextRenderCmdLineTool
|
||||
<td> JKQTMathText<br>command-line utility
|
||||
<tr><td> \image html jkqtmathtext_testapp_small.png
|
||||
<td> \subpage JKQTMathTextTestApp
|
||||
<td> JKQTMathText<br>render LaTeX markup
|
||||
</table>
|
||||
|
||||
|
||||
\section jkqtp_extut_jkqtfastplotter Examples for JKQTFastPlotter
|
||||
|
||||
<table>
|
||||
<tr><th> Screenshot <th> Description <th> Notes
|
||||
<tr><td> \image html jkqtfastplotter_test_small.png
|
||||
<td> \subpage JKQTFastPlotterTest
|
||||
<td> JKQTFastPlotter
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
\section jkqtp_extut_tools Tool Programs
|
||||
|
||||
<table>
|
||||
<tr><th> Screenshot <th> Name <th> Notes/Description
|
||||
<tr><td> \image html jkqtmathtext_render_small.png
|
||||
<td> \subpage JKQTMathTextRenderCmdLineTool
|
||||
<td> uses JKQTMathText to render LaTeX Markup into an image file
|
||||
</table>
|
||||
|
||||
|
||||
*/
|
@ -10,6 +10,7 @@
|
||||
|
||||
Examples for the usage of this class can be found here:
|
||||
- \ref JKQTMathTextSimpleExample
|
||||
- \ref JKQTMathTextRenderCmdLineTool
|
||||
- \ref JKQTMathTextTestApp
|
||||
.
|
||||
|
||||
|
@ -122,7 +122,7 @@
|
||||
- \c \\left| \c \\right| : absolute value braces | |, \image html jkqtmathtext/jkqtmathtext_bracejkqtmathtext_brace_ucorner_oneline.png
|
||||
- \c \\left\\| \c \\right\\| \endcode : norm braces || ||, \image html jkqtmathtext/jkqtmathtext_brace_dblline.png
|
||||
- \c \\left\\llcorner \c \\right\\lrcorner : lower corner braces , \image html jkqtmathtext/jkqtmathtext_brace_lcorner.png
|
||||
- \c \\left\\ulcorner \c \\right\\urcorner : upper corner braces , \image html jkqtmathtext/.png
|
||||
- \c \\left\\ulcorner \c \\right\\urcorner : upper corner braces , \image html jkqtmathtext/jkqtmathtext_brace_ucorner.png
|
||||
- You can use \c \\left. or \c \\right. to have only right or only left brace
|
||||
.
|
||||
|
||||
@ -143,12 +143,12 @@
|
||||
|
||||
\subsection JKQTMathTextSuppoertedLaTeXUnderOver Undersetting, Oversetting, Underbraces, Overbraces ...
|
||||
There are also instructions that allow to under/overset braces, arrows, ...:
|
||||
- <code>$\\underbrace{x+x+...+x}{k\\ \\mathrm{times}}$</code> \image html jkqtmathtext/jkqtmathtext_brace_underbrace.png
|
||||
- <code>$\\overbrace{x+x+...+x}{k\\ \\mathrm{times}}$</code> \image html jkqtmathtext/jkqtmathtext_brace_overbrace.png
|
||||
- <code>$\\underbrace{x+x+...+x}{k\\ \\mathrm{times}}$</code> \image html jkqtmathtext/MTFMunderbrace.png
|
||||
- <code>$\\overbrace{x+x+...+x}{k\\ \\mathrm{times}}$</code> \image html jkqtmathtext/MTFMoverbrace.png
|
||||
- <code>$\\underbracket{x+x+...+x}{k\\ \\mathrm{times}}$</code> \image html jkqtmathtext/MTFMunderbracket.png
|
||||
- <code>$\\overbracket{x+x+...+x}{k\\ \\mathrm{times}}$</code> \image html jkqtmathtext/MTFMoverbracket.png
|
||||
- <code>$\\overset{main}{over}$</code> \image html jkqtmathtext/jkqtmathtext_brace_overset.png
|
||||
- <code>$\\underset{main}{under}$</code> \image html jkqtmathtext/jkqtmathtext_brace_underset.png
|
||||
- <code>$\\overset{main}{over}$</code> \image html jkqtmathtext/MTFMoverset.png
|
||||
- <code>$\\underset{main}{under}$</code> \image html jkqtmathtext/MTFMunderset.png
|
||||
.
|
||||
|
||||
\subsection JKQTMathTextSuppoertedLaTeXFrac Fraction Type Instructions
|
||||
|
@ -41,8 +41,6 @@ This page lists several todos and wishes for future version of JKQTPlotter
|
||||
<li>JKQTMathText:<ul>
|
||||
<li>check sub/superscript with italic text in math mode, possibly a correction is necessary</li>
|
||||
<li>explore options to make font-environment-modifying commands avails, like "{blacktext\\color{red}redtext}", today only commands like "\\textcolor{red}{redtext}" work</li>
|
||||
<li>maybe: add support for text with linebreaks by adding a JKQTMathTextVerticalListNode in addition to JKQTMathTextListNode</li>
|
||||
<li>maybe: add tool programs to auto-generate some example images</li>
|
||||
<li>improve support for array-environment with limited support for formatting string like l|r|c and maybe add support for \\hline command, possibly also \\cellcolor etz.</li>
|
||||
<li></li>
|
||||
</ul></li>
|
||||
|
@ -82,6 +82,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
|
||||
<li>NEW: added support for \\begin{verbatim}...\\end{verbatim}, \\begin{verbatim*}...\\end{verbatim*}</li>
|
||||
<li>NEW: additional method JKQTMathtext::getSizeDetail() that returns all size-properties as a convenient struct, also added matching varinat JKQTMathTextNode::getSize() </li>
|
||||
<li>NEW: additional method JKQTMathtext::drawIntoPixmap(), JKQTMathtext::drawIntoPicture(), JKQTMathtext::drawIntoImage() which returns a QPixmap, QPicture and QImage respectively that contains the render result of the currently parsed markup</li>
|
||||
<li>NEW: added command line tool \ref JKQTMathTextRenderCmdLineTool that renders LaTeX into images, using it to generate the documentation images for JKQTMathText</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
|
||||
|
@ -99,6 +99,7 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
|
||||
| Screenshot | Description | Notes |
|
||||
|:-------------:| ------------- | ------------- |
|
||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtmathtext_simpletest_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/jkqtmathtext_simpletest) | [JKQTMathText: Simple Demonstration](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/jkqtmathtext_simpletest) | |
|
||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtmathtext_render_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/tools/jkqtmathtext_render) | [JKQTMathText: Command-Line Utility](https://github.com/jkriege2/JKQtPlotter/tree/master/tools/jkqtmathtext_render) | |
|
||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtmathtext_testapp_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/jkqtmathtext_test) | [JKQTMathText: Full Testing Application](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/jkqtmathtext_test) | |
|
||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtfastplotter_test_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/jkqtfastplotter_test) | [JKQTFastPlotter: Example](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/jkqtfastplotter_test) | |
|
||||
|
||||
|
BIN
screenshots/jkqtmathtext_render_output.png
Normal file
BIN
screenshots/jkqtmathtext_render_output.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
screenshots/jkqtmathtext_render_small.png
Normal file
BIN
screenshots/jkqtmathtext_render_small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.4 KiB |
22
tools/CMakeLists.txt
Normal file
22
tools/CMakeLists.txt
Normal file
@ -0,0 +1,22 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
|
||||
message( STATUS )
|
||||
message( STATUS "............................................................................." )
|
||||
message( STATUS ".. BUILDING TOOLS" )
|
||||
message( STATUS "............................................................................." )
|
||||
if (JKQtPlotter_BUILD_WITH_PRECOMPILED_HEADERS)
|
||||
message( STATUS ".. - Precompiled Header: ON" )
|
||||
else()
|
||||
message( STATUS ".. - Precompiled Header: OFF")
|
||||
endif()
|
||||
|
||||
message( STATUS "............................................................................." )
|
||||
|
||||
|
||||
|
||||
|
||||
# examples specific to JKQtMathText
|
||||
message( STATUS ".. BUILDING TOOLS FOR JKQTMATHTEXT:" )
|
||||
add_subdirectory(jkqtmathtext_render)
|
||||
|
33
tools/jkqtmathtext_render/CMakeLists.txt
Normal file
33
tools/jkqtmathtext_render/CMakeLists.txt
Normal file
@ -0,0 +1,33 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(EXAMPLE_NAME jkqtmathtext_render)
|
||||
set(EXENAME ${EXAMPLE_NAME})
|
||||
|
||||
message( STATUS ".. Building Tool ${EXAMPLE_NAME}" )
|
||||
|
||||
|
||||
# Set up source files
|
||||
set(SOURCES
|
||||
${EXAMPLE_NAME}.cpp
|
||||
)
|
||||
set(HEADERS )
|
||||
set(RESOURCES )
|
||||
set(UIS )
|
||||
|
||||
add_executable(${EXENAME} WIN32 ${SOURCES} ${HEADERS} ${RESOURCES} ${UIS})
|
||||
target_include_directories(${EXENAME} PRIVATE ../../lib)
|
||||
if(JKQtPlotter_BUILD_STATIC_LIBS)
|
||||
target_link_libraries(${EXENAME} JKQTMathTextLib)
|
||||
elseif(JKQtPlotter_BUILD_SHARED_LIBS)
|
||||
target_link_libraries(${EXENAME} JKQTMathTextSharedLib)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
# Installation
|
||||
install(TARGETS ${EXENAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
|
||||
#Installation of Qt DLLs on Windows
|
||||
jkqtplotter_deployqt(${EXENAME})
|
||||
|
||||
|
80
tools/jkqtmathtext_render/README.md
Normal file
80
tools/jkqtmathtext_render/README.md
Normal file
@ -0,0 +1,80 @@
|
||||
# Example (JKQTMathText): Command-Line Utility jkqtmathtext_render {#JKQTMathTextRenderCmdLineTool}
|
||||
JKQTMathText is a hand-written LaTeX-renderer for Qt (implemented in native C++, using Qt). It supports a large set of standard LaTeX markup and can render it to a QPainter.
|
||||
|
||||
This project (see `./examples/jkqtmathtext_render/`) is a command-line utility that accepts a LaTeX markup string and a filename for the generated image.
|
||||
It then renders the string into the image.
|
||||
The source code of the main application can be found in [`jkqtmathtext_render.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/jkqtmathtext_render/jkqtmathtext_render.cpp).
|
||||
The major rendering portion look like this:
|
||||
|
||||
First we generate dummy QPixmap that is needed to use the QPainter, that is required for determining the size of the rendering.
|
||||
|
||||
```.cpp
|
||||
QPixmap pix(10,10);
|
||||
```
|
||||
|
||||
Now we create a JKQTMathText object and configure it
|
||||
|
||||
```.cpp
|
||||
QPainter painter;
|
||||
JKQTMathText mathText;
|
||||
if (useXITS) mathText.useXITS();
|
||||
mathText.setFontSize(fontsize);
|
||||
```
|
||||
|
||||
Now we parse some LaTeX code and thus generate its memory representation.
|
||||
|
||||
```.cpp
|
||||
mathText.parse(latex);
|
||||
```
|
||||
|
||||
|
||||
Finally we can generate a QImage with the output of the rendering algorithm and save it as a file.
|
||||
|
||||
```.cpp
|
||||
const QImage pix=mathText.drawIntoImage(drawBoxes, backgroundColor, sizeincrease);
|
||||
pix.save(outputFilename);
|
||||
```
|
||||
|
||||
|
||||
calling this utility with the LaTeX code:
|
||||
|
||||
```.sh
|
||||
> jkqtmathtext_render "$x_{1/2}=\frac{-b\pm\sqrt{b^2-4ac}}{2a}$" jkqtmathtext_render_output.png
|
||||
```
|
||||
|
||||
results in this output:
|
||||
|
||||
![jkqtmathtext_render_output](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtmathtext_render_output.png)
|
||||
|
||||
The tool supports these command-line options:
|
||||
- *command-line mode*: call `jkqtmathtext_render LATEX OUTPUTFILE`
|
||||
- The extension of the `OUTPUTFILE` determines the file type. The tool supports `.png`, `.bmp`, `.jpg`, `.ppm`, `.xbm` and `.xpm`
|
||||
- *file-mode*: call `jkqtmathtext_render --inputfile=INPUTFILE.jkmt --outputdir=OUTPUTDIR`
|
||||
- The file `INPUTFILE.jkmt` is a text file with several "render jobs", deparated by `---` lines.
|
||||
- The first line in each job defines the output filename (relative to `OUTPUTDIR`)
|
||||
- The second line is optional and contains a list of altered command-line options, e.g. `--fontsize=24 --fontmathroman=XITS`, Note however that only options concerning formatting are allowed, `--verbose` or the file/directory-options will not be processed!
|
||||
- The third and further lines is concatenated to form the LaTeX markup to be rendered.
|
||||
- All modes support these command-line options:
|
||||
- `--verbose`: verbose output of the tool
|
||||
- `--sizeincrease=SIZE_PIXELS`: set the width of the additional margin around the rendering result
|
||||
- `--drawboxes`: flag that enables drawing of rectangles around each box
|
||||
- `--font=FONT_SERIF`: sets text- and math-mode serif font to `FONT_SERIF`
|
||||
- `--font=FONT_SERIF,FONT_SANS`: sets text- and math-mode serif font to `FONT_SERIF` and sans font to `FONT_SANS`
|
||||
- `--font=FONT_TEXT_SERIF,FONT_TEXT_SANS,FONT_MATH_SERIF,FONT_MATH_SANS`: sets text- and math-mode serif font to `FONT_TEXT_SERIF` and `FONT_MATH_SERIF` and sans fonts to `FONT_TEXT_SANS` and `FONT_MATH_SANS`
|
||||
- `--font=...+XITS|STIX|ASANA`: set fonts as given above and then use XITS-/STIX- or ASANA-fonts for math-roman
|
||||
- `--fontsize=SIZE_PT`: set the font-size in pt
|
||||
- `--fontroman=FONT`: set the text-mode roman font
|
||||
- `--fontsans=FONT`: set the text-mode sans font
|
||||
- `--fontmathroman=FONT`: set the math-mode roman font
|
||||
- `--fontmathsans=FONT`: set the math-mode sans font
|
||||
- `--fontblackboard=FONT`: use the given font as blackboard-font and de-activate the simulate-feature
|
||||
- `--fontblackboardsimulated=FONT`: use the given font as blackboard-font and activate the simulate-feature
|
||||
- `--fonttypewriter=FONT`: set the typewriter font
|
||||
- `--fontscript=FONT`: set the script font
|
||||
- `--fontcaligraphic=FONT`: set the caligraphic font
|
||||
- `--fontfraktur=FONT`: set the fraktur font
|
||||
- `--fontfallbacksymbol=FONT`: set the fallback symbol font, using unicode encoding
|
||||
- `--fontfallbacksymbol_symbolencoding=FONT`: set the fallback symbol font, using WinSymbol encoding
|
||||
- `--background=COLOR`: set the background color of the output image
|
||||
- `--textcolor=COLOR`: set the text color of the output image
|
||||
|
341
tools/jkqtmathtext_render/jkqtmathtext_render.cpp
Normal file
341
tools/jkqtmathtext_render/jkqtmathtext_render.cpp
Normal file
@ -0,0 +1,341 @@
|
||||
/** \example jkqtmathtext_render.cpp
|
||||
* A very basic example for the usage of JKQTMathText
|
||||
*
|
||||
* \ref JKQTMathTextRenderCmdLineTool
|
||||
|
||||
*/
|
||||
|
||||
#include <QApplication>
|
||||
#include <QPixmap>
|
||||
#include <QPainter>
|
||||
#include <QCommandLineParser>
|
||||
#include <QCommandLineOption>
|
||||
#include <QElapsedTimer>
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
#if (QT_VERSION>=QT_VERSION_CHECK(6, 0, 0))
|
||||
#include<QRegularExpression>
|
||||
#include<QRegularExpressionMatch>
|
||||
#else
|
||||
#include<QRegExp>
|
||||
#endif
|
||||
#include "jkqtmathtext/jkqtmathtextlabel.h"
|
||||
#include "jkqtcommon/jkqtpstringtools.h"
|
||||
#include <iostream>
|
||||
|
||||
void processFont(const QString font, QStringList& fonts, QString& mathFont)
|
||||
{
|
||||
fonts.clear();
|
||||
mathFont="";
|
||||
QString current="";
|
||||
bool isExtra=false;
|
||||
for (int i=0; i<font.size(); i++) {
|
||||
if (font[i]==',') {
|
||||
fonts.push_back(current);
|
||||
current="";
|
||||
} else if (font[i]=='+') {
|
||||
fonts.push_back(current);
|
||||
isExtra=true;
|
||||
current="";
|
||||
} else {
|
||||
if (isExtra) {
|
||||
mathFont+=font[i];
|
||||
} else {
|
||||
current+=font[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (current.size()>0) {
|
||||
fonts.append(current);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// 1. create Qt Appcilation object and a QCommandLineParser to go with it
|
||||
QApplication app(argc, argv);
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription("JKQTMathText command line tool that renders LaTeX markup into an image");
|
||||
parser.addHelpOption();
|
||||
parser.addVersionOption();
|
||||
parser.addPositionalArgument("latex", "LaTeX markup to be rendered");
|
||||
parser.addPositionalArgument("output", "output image file (extensions determines file type)");
|
||||
QCommandLineOption inputfileOption("inputfile", "read from a file instead of from command line.", "inputfile", "");
|
||||
parser.addOption(inputfileOption);
|
||||
QCommandLineOption outputDirectoryOption("outputdir", "write results into this directory.", "outputdir", app.applicationDirPath());
|
||||
parser.addOption(outputDirectoryOption);
|
||||
QCommandLineOption drawBoxesOption("drawboxes", "draw boxes.");
|
||||
parser.addOption(drawBoxesOption);
|
||||
QCommandLineOption verboseOption("verbose", "verbose output.");
|
||||
parser.addOption(verboseOption);
|
||||
QCommandLineOption fontOption("font", "font( size)s) to use.", "font", "XITS");
|
||||
parser.addOption(fontOption);
|
||||
QCommandLineOption fontsizeOption("fontsize", "font size.", "fontsize", "12");
|
||||
parser.addOption(fontsizeOption);
|
||||
QCommandLineOption fontBlackboardSimOption("fontblackboardsimulated", "set the blackboard font and activate simulated-mode.", "fontblackboardsimulated", "");
|
||||
parser.addOption(fontBlackboardSimOption);
|
||||
QCommandLineOption fontRomanOption("fontroman", "set the text-mode roman font to use.", "fontroman", "");
|
||||
parser.addOption(fontRomanOption);
|
||||
QCommandLineOption fontSansOption("fontsans", "set the text-mode sans font to use.", "fontsans", "");
|
||||
parser.addOption(fontSansOption);
|
||||
QCommandLineOption fontMathRomanOption("fontmathroman", "set the math-mode roman font to use.", "fontmathroman", "");
|
||||
parser.addOption(fontMathRomanOption);
|
||||
QCommandLineOption fontMathSansOption("fontmathsans", "set the math-mode sans font to use.", "fontmathsans", "");
|
||||
parser.addOption(fontMathSansOption);
|
||||
QCommandLineOption fontFallbackSymbolOption("fontfallbacksymbol", "set the fallback symbol font to use.", "fontfallbacksymbol", "");
|
||||
parser.addOption(fontFallbackSymbolOption);
|
||||
QCommandLineOption fontFallbackSymbol_symbolencodingOption("fontfallbacksymbol_symbolencoding", "set the fallback symbol font to use and use the encoding of the MS Symbol font for it.", "fontfallbacksymbol_symbolencoding", "");
|
||||
parser.addOption(fontFallbackSymbol_symbolencodingOption);
|
||||
QCommandLineOption fontTypewriterOption("fonttypewriter", "set the typewriter font to use.", "fonttypewriter", "");
|
||||
parser.addOption(fontTypewriterOption);
|
||||
QCommandLineOption fontScriptOption("fontscript", "set the Script font to use.", "fontscript", "");
|
||||
parser.addOption(fontScriptOption);
|
||||
QCommandLineOption fontFrakturOption("fontfraktur", "set the Fraktur font to use.", "fontfraktur", "");
|
||||
parser.addOption(fontFrakturOption);
|
||||
QCommandLineOption fontcaligraphicOption("fontcaligraphic", "set the caligraphic font to use.", "fontcaligraphic", "");
|
||||
parser.addOption(fontcaligraphicOption);
|
||||
QCommandLineOption fontblackboardOption("fontblackboard", "set the blackboard font to use.", "fontblackboard", "");
|
||||
parser.addOption(fontblackboardOption);
|
||||
QCommandLineOption textcolorOption("textcolor", "set the color of the text.", "textcolor", "black");
|
||||
parser.addOption(textcolorOption);
|
||||
QCommandLineOption sizeincreaseOption("sizeincrease", "additional pixels around output.", "sizeincrease", "2");
|
||||
parser.addOption(sizeincreaseOption);
|
||||
QCommandLineOption resolutionOption("resolution", "set output image resolution in DPI.", "resolution", "96");
|
||||
parser.addOption(resolutionOption);
|
||||
QCommandLineOption backgroundOption("background", "background color.", "background", "white");
|
||||
parser.addOption(backgroundOption);
|
||||
parser.process(app);
|
||||
|
||||
const QStringList args = parser.positionalArguments();
|
||||
const QString latex_cmdline=args.value(0, "$x_{1/2}=\\frac{-b\\pm\\sqrt{b^2-4ac}}{2a}$");
|
||||
const QDir outputDir(parser.value(outputDirectoryOption));
|
||||
const QString outputFilename_cmdline=outputDir.absoluteFilePath(args.value(1, "output.png"));
|
||||
const QString inputfile=parser.value(inputfileOption);
|
||||
const bool verbose = parser.isSet(verboseOption);
|
||||
|
||||
QStringList latex, outputFilename;
|
||||
QList<QMap<QString,QString>> cmdoptions;
|
||||
if (inputfile.size()<=0) {
|
||||
latex.append(latex_cmdline);
|
||||
outputFilename.append(outputFilename_cmdline);
|
||||
cmdoptions.append(QMap<QString,QString>());
|
||||
} else {
|
||||
QFile f(inputfile);
|
||||
if (f.open(QFile::ReadOnly|QFile::Text)) {
|
||||
QString currentOutFile="";
|
||||
QString currentLatex="";
|
||||
QMap<QString,QString> currentOptions;
|
||||
bool isFile=true;
|
||||
bool beforeLatex=true;
|
||||
while (!f.atEnd()) {
|
||||
const QString line=f.readLine().trimmed();
|
||||
const QString line_simple=line.simplified();
|
||||
if (line_simple=="---" || line_simple=="###") {
|
||||
if (currentOutFile.size()>0) {
|
||||
outputFilename.append(currentOutFile);
|
||||
latex.append(currentLatex);
|
||||
cmdoptions.append(currentOptions);
|
||||
isFile=true;
|
||||
beforeLatex=true;
|
||||
currentLatex="";
|
||||
currentOutFile="";
|
||||
currentOptions.clear();
|
||||
}
|
||||
} else if (isFile) {
|
||||
currentOutFile=line;
|
||||
isFile=false;
|
||||
} else if (beforeLatex) {
|
||||
if (line.startsWith("--")) {
|
||||
QStringList commands=line.right(line.size()-2).split("--");
|
||||
for (QString cmd: commands) {
|
||||
cmd=cmd.trimmed();
|
||||
QString cmdn="", param="";
|
||||
bool iscmd=true;
|
||||
for (const QChar& ch: cmd) {
|
||||
if (iscmd) {
|
||||
if (ch=='=') {
|
||||
iscmd=false;
|
||||
} else {
|
||||
cmdn+=ch;
|
||||
}
|
||||
} else {
|
||||
param+=ch;
|
||||
}
|
||||
}
|
||||
currentOptions[cmdn.trimmed()]=param.trimmed();
|
||||
}
|
||||
} else {
|
||||
if (currentLatex.size()>0) currentLatex+="\n";
|
||||
currentLatex+=line;
|
||||
}
|
||||
beforeLatex=false;
|
||||
} else {
|
||||
if (currentLatex.size()>0) currentLatex+="\n";
|
||||
currentLatex+=line;
|
||||
}
|
||||
}
|
||||
f.close();
|
||||
if (currentOutFile.size()>0) {
|
||||
outputFilename.append(currentOutFile);
|
||||
latex.append(currentLatex);
|
||||
cmdoptions.append(currentOptions);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
std::cout
|
||||
<<"===========================================================\n"
|
||||
<<"= jkqtmathtext_render: ";
|
||||
if (inputfile.size()>0) std::cout<<"FILE-MODE ("<<inputfile.toStdString()<<")\n";
|
||||
else std::cout<<"COMMAND-LINE-MODE\n";
|
||||
std::cout<<"\n"
|
||||
<<"===========================================================\n";
|
||||
}
|
||||
|
||||
|
||||
for (int i=0; i<latex.size(); i++) {
|
||||
if (inputfile.size()>0 && verbose) {
|
||||
std::cout<<"\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
|
||||
<<"+ processing entry "<<(i+1)<<"/"<<latex.size()<<"\n";
|
||||
if (cmdoptions[i].size()>0) {
|
||||
std::cout<<"+ additional command-line options: ";
|
||||
for (const QString& key: cmdoptions[i].keys()) {
|
||||
std::cout<<" --"<<key.toStdString()<<"="<<cmdoptions[i].value(key).toStdString();
|
||||
}
|
||||
std::cout<<"\n";
|
||||
}
|
||||
|
||||
}
|
||||
QStringList fonts;
|
||||
QString mathFont="";
|
||||
processFont(parser.value(fontOption), fonts, mathFont);
|
||||
bool drawBoxes = parser.isSet(drawBoxesOption);
|
||||
double fontsize = parser.value(fontsizeOption).toDouble();
|
||||
int sizeincrease = parser.value(sizeincreaseOption).toInt();
|
||||
int resolution_dpi = parser.value(resolutionOption).toInt();
|
||||
QColor backgroundColor = jkqtp_String2QColor(parser.value(backgroundOption));
|
||||
QColor textColor = jkqtp_String2QColor(parser.value(textcolorOption));
|
||||
QString fontBlackboardSim = parser.value(fontBlackboardSimOption);
|
||||
QString fontBlackboard=parser.value(fontblackboardOption);
|
||||
QString fontRoman=parser.value(fontRomanOption);
|
||||
QString fontSans=parser.value(fontSansOption);
|
||||
QString fontMathRoman=parser.value(fontMathRomanOption);
|
||||
QString fontMathSans=parser.value(fontMathSansOption);
|
||||
QString fontFallbackSymbol=parser.value(fontFallbackSymbolOption);
|
||||
QString fontFallbackSymbol_symbolencoding=parser.value(fontFallbackSymbol_symbolencodingOption);
|
||||
QString fontTypewriter=parser.value(fontTypewriterOption);
|
||||
QString fontScript=parser.value(fontScriptOption);
|
||||
QString fontFraktur=parser.value(fontFrakturOption);
|
||||
QString fontCaligraphic=parser.value(fontcaligraphicOption);
|
||||
|
||||
if (cmdoptions[i].size()>0) {
|
||||
for (const QString& key: cmdoptions[i].keys()) {
|
||||
if (key=="drawboxes") drawBoxes=true;
|
||||
else if (key=="fontsize") fontsize=cmdoptions[i].value(key).toDouble();
|
||||
else if (key=="sizeincrease") sizeincrease=cmdoptions[i].value(key).toInt();
|
||||
else if (key=="background") backgroundColor=jkqtp_String2QColor(cmdoptions[i].value(key));
|
||||
else if (key=="textcolor") textColor=jkqtp_String2QColor(cmdoptions[i].value(key));
|
||||
else if (key=="fontblackboardsimulated") fontBlackboardSim=cmdoptions[i].value(key);
|
||||
else if (key=="fontblackboard") fontBlackboard=cmdoptions[i].value(key);
|
||||
else if (key=="font") processFont(cmdoptions[i].value(key), fonts, mathFont);
|
||||
else if (key=="fontroman") fontRoman=cmdoptions[i].value(key);
|
||||
else if (key=="fontsans") fontSans=cmdoptions[i].value(key);
|
||||
else if (key=="fontmathroman") fontMathRoman=cmdoptions[i].value(key);
|
||||
else if (key=="fontmathsans") fontMathSans=cmdoptions[i].value(key);
|
||||
else if (key=="fonttypewriter") fontTypewriter=cmdoptions[i].value(key);
|
||||
else if (key=="fontfallbacksymbol") fontFallbackSymbol=cmdoptions[i].value(key);
|
||||
else if (key=="fontfallbacksymbol_symbolencoding") fontFallbackSymbol_symbolencoding=cmdoptions[i].value(key);
|
||||
else if (key=="fontscript") fontScript=cmdoptions[i].value(key);
|
||||
else if (key=="fontcaligraphic") fontCaligraphic=cmdoptions[i].value(key);
|
||||
else if (key=="fontfraktur") fontFraktur=cmdoptions[i].value(key);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. now we create a JKQTMathText object and configure it
|
||||
JKQTMathText mathText;
|
||||
if (fonts.size()==1) {
|
||||
mathText.useAnyUnicode(fonts[0], mathText.getFontSans());
|
||||
} else if (fonts.size()==2) {
|
||||
mathText.useAnyUnicode(fonts[0], fonts[1]);
|
||||
} else if (fonts.size()==4) {
|
||||
mathText.useAnyUnicodeForTextOnly(fonts[0], fonts[1]);
|
||||
mathText.useAnyUnicodeForMathOnly(fonts[2], fonts[3]);
|
||||
}
|
||||
if (mathFont.toUpper() == "XITS") mathText.useXITS(true);
|
||||
else if (mathFont.toUpper() == "XITS_MATHANDTEXT") mathText.useXITS(false);
|
||||
if (mathFont.toUpper() == "STIX") mathText.useSTIX(true);
|
||||
else if (mathFont.toUpper() == "STIX_MATHANDTEXT") mathText.useSTIX(false);
|
||||
if (mathFont.toUpper() == "ASANA") mathText.useASANA(true);
|
||||
else if (mathFont.toUpper() == "ASANA_MATHANDTEXT") mathText.useASANA(false);
|
||||
if (fontRoman.size()>0) mathText.setFontRoman(fontRoman, MTFEUnicode);
|
||||
if (fontSans.size()>0) mathText.setFontSans(fontSans, MTFEUnicode);
|
||||
if (fontMathRoman.size()>0) {
|
||||
if (fontMathRoman.toUpper()=="XITS") mathText.useXITS(true);
|
||||
else if (fontMathRoman.toUpper()=="STIX") mathText.useSTIX(true);
|
||||
else if (fontMathRoman.toUpper()=="ASANA") mathText.useASANA(true);
|
||||
else mathText.setFontMathRoman(fontMathRoman, MTFEUnicode);
|
||||
}
|
||||
if (fontMathSans.size()>0) mathText.setFontMathSans(fontMathSans, MTFEUnicode);
|
||||
if (fontTypewriter.size()>0) mathText.setFontTypewriter(fontTypewriter, MTFEUnicode);
|
||||
if (fontScript.size()>0) mathText.setFontScript(fontScript, MTFEUnicode);
|
||||
if (fontCaligraphic.size()>0) mathText.setFontCaligraphic(fontCaligraphic, MTFEUnicode);
|
||||
if (fontFraktur.size()>0) mathText.setFontFraktur(fontFraktur, MTFEUnicode);
|
||||
if (fontFallbackSymbol.size()>0) mathText.setFallbackFontSymbols(fontFallbackSymbol, MTFEUnicode);
|
||||
if (fontFallbackSymbol_symbolencoding.size()>0) mathText.setFallbackFontSymbols(fontFallbackSymbol_symbolencoding, MTFEWinSymbol);
|
||||
|
||||
if (fontBlackboardSim.size()>0) {
|
||||
mathText.setFontBlackboard(fontBlackboardSim, MTFEUnicode);
|
||||
mathText.setFontBlackboardSimulated(true);
|
||||
}
|
||||
if (fontBlackboard.size()>0) {
|
||||
mathText.setFontBlackboard(fontBlackboard, MTFEUnicode);
|
||||
mathText.setFontBlackboardSimulated(false);
|
||||
}
|
||||
mathText.setFontSize(fontsize);
|
||||
mathText.setFontColor(textColor);
|
||||
|
||||
// 3. now we parse some LaTeX code
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
mathText.parse(latex[i]);
|
||||
const double durParseMS=static_cast<double>(timer.nsecsElapsed())/1.0e6;
|
||||
if (mathText.hadErrors()) {
|
||||
std::cerr<<"ERRORS while parsing LaTeX:\n"
|
||||
<<"-----------------------------------------------------------\n"
|
||||
<<latex[i].toStdString()<<"\n"
|
||||
<<"-----------------------------------------------------------\n"
|
||||
<<mathText.getErrorList().join("\n").toStdString()<<"\n"
|
||||
<<"-----------------------------------------------------------\n"
|
||||
;
|
||||
} else if (verbose) {
|
||||
std::cout<<"parsing LaTeX: OK\n"
|
||||
<<"parsing duration: "<<durParseMS<<"ms\n"
|
||||
<<"-----------------------------------------------------------\n"
|
||||
<<latex[i].toStdString()<<"\n"
|
||||
<<"-----------------------------------------------------------\n";
|
||||
}
|
||||
|
||||
// 4. now we draw the result into a QPixmap
|
||||
timer.start();
|
||||
const QImage pix=mathText.drawIntoImage(drawBoxes, backgroundColor, sizeincrease, 1.0, resolution_dpi);
|
||||
const double durRenderMS=static_cast<double>(timer.nsecsElapsed())/1.0e6;
|
||||
if (verbose) std::cout<<"rendering into QImage "<<pix.width()<<"x"<<pix.height()<<"pixels\n"
|
||||
<<"rendering duration: "<<durRenderMS<<"ms\n"
|
||||
<<"rendering resolution: "<<pix.dotsPerMeterX()/(1000.0/25.4)<<"x"<<pix.dotsPerMeterY()/(1000.0/25.4)<<"dpi\n"
|
||||
<<"devicepixelratio: "<<pix.devicePixelRatioF()<<"\n"
|
||||
;
|
||||
|
||||
// 5. before ending the application, we store the result into a file
|
||||
const QString outname=outputDir.absoluteFilePath(outputFilename[i]);
|
||||
if (QFileInfo::exists(outname)) QFile::remove(outname);
|
||||
if (!pix.save(outname)) {
|
||||
std::cerr<<"ERROR storing to "<<outname.toStdString()<<"\n";
|
||||
} else {
|
||||
if (verbose) std::cout<<"stored to "<<outname.toStdString()<<"\n"
|
||||
<<" size "<<static_cast<double>(QFileInfo(outname).size())/1024.0<<"kBytes\n";
|
||||
}
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
23
tools/jkqtmathtext_render/jkqtmathtext_render.pro
Normal file
23
tools/jkqtmathtext_render/jkqtmathtext_render.pro
Normal file
@ -0,0 +1,23 @@
|
||||
TARGET = jkqtmathtext_render
|
||||
TEMPLATE = app
|
||||
|
||||
SOURCES += jkqtmathtext_render.cpp
|
||||
|
||||
CONFIG += link_prl qt
|
||||
QT += core gui
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
|
||||
|
||||
|
||||
DEPENDPATH += ../../lib ../../qmake/staticlib/jkqtmathtextlib
|
||||
INCLUDEPATH += ../../lib
|
||||
CONFIG (debug, debug|release) {
|
||||
DEPENDPATH += ../../qmake/staticlib/jkqtmathtextlib/debug
|
||||
LIBS += -L../../qmake/staticlib/jkqtmathtextlib/debug -L../../../qmake/staticlib/jkqtmathtextlib/debug -ljkqtmathtextlib_debug
|
||||
} else {
|
||||
DEPENDPATH += ../../qmake/staticlib/jkqtmathtextlib/release
|
||||
LIBS += -L../../qmake/staticlib/jkqtmathtextlib/release -L../../../qmake/staticlib/jkqtmathtextlib/release -ljkqtmathtextlib
|
||||
}
|
||||
message("LIBS = $$LIBS")
|
||||
|
||||
win32-msvc*: DEFINES += _USE_MATH_DEFINES
|
||||
win32-msvc*: DEFINES += NOMINMAX
|
@ -0,0 +1,8 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += jkqtmathtextlib jkqtmathtext_render
|
||||
|
||||
jkqtmathtextlib.file = ../../qmake/staticlib/jkqtmathtextlib/jkqtmathtextlib.pro
|
||||
|
||||
jkqtmathtext_render.file=$$PWD/jkqtmathtext_render.pro
|
||||
jkqtmathtext_render.depends = jkqtmathtextlib
|
Loading…
Reference in New Issue
Block a user