summaryrefslogtreecommitdiff
path: root/macros/luatex/generic
diff options
context:
space:
mode:
Diffstat (limited to 'macros/luatex/generic')
-rw-r--r--macros/luatex/generic/luamplib/Makefile1
-rw-r--r--macros/luatex/generic/luamplib/NEWS51
-rw-r--r--macros/luatex/generic/luamplib/luamplib.dtx2210
-rw-r--r--macros/luatex/generic/luamplib/luamplib.pdfbin212148 -> 253794 bytes
-rw-r--r--macros/luatex/generic/luamplib/test-luamplib-latex.tex102
-rw-r--r--macros/luatex/generic/luamplib/test-luamplib-plain.tex60
-rw-r--r--macros/luatex/generic/luatexja/README6
-rw-r--r--macros/luatex/generic/luatexja/doc/luatexja-en.pdfbin699725 -> 700023 bytes
-rw-r--r--macros/luatex/generic/luatexja/doc/luatexja-ja.pdfbin1143479 -> 1143849 bytes
-rw-r--r--macros/luatex/generic/luatexja/doc/luatexja.dtx30
-rw-r--r--macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-27c.sty16
-rw-r--r--macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-29c.sty16
-rw-r--r--macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-29e.sty16
-rw-r--r--macros/luatex/generic/luatexja/src/lltjext.sty8
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-latex.sty103
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-pretreat.lua7
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-rmlgbm.lua4
-rw-r--r--macros/luatex/generic/luatexja/src/luatexja.sty2
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjdefs.sty51
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjfont.sty319
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjp-array.sty11
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjp-geometry.sty24
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjp-siunitx.sty113
-rw-r--r--macros/luatex/generic/luaxml/README2
-rw-r--r--macros/luatex/generic/luaxml/luaxml-cssquery.lua14
-rw-r--r--macros/luatex/generic/luaxml/luaxml-domobject.lua95
-rw-r--r--macros/luatex/generic/luaxml/luaxml-encodings.lua88
-rw-r--r--macros/luatex/generic/luaxml/luaxml-mod-html.lua221
-rw-r--r--macros/luatex/generic/luaxml/luaxml-namedentities.lua4167
-rw-r--r--macros/luatex/generic/luaxml/luaxml-transform.lua13
-rw-r--r--macros/luatex/generic/luaxml/luaxml.pdfbin119150 -> 124725 bytes
-rw-r--r--macros/luatex/generic/luaxml/luaxml.tex92
32 files changed, 4344 insertions, 3498 deletions
diff --git a/macros/luatex/generic/luamplib/Makefile b/macros/luatex/generic/luamplib/Makefile
index 87f04f727e..a0a2282675 100644
--- a/macros/luatex/generic/luamplib/Makefile
+++ b/macros/luatex/generic/luamplib/Makefile
@@ -40,6 +40,7 @@ world: all ctan
%.pdf: %.dtx
@$(DOLATEX)
@if( grep rerunfilecheck $(NAME).log |grep 'has changed' > /dev/null ); then $(DOLATEX); fi
+ @if( grep 'Rerun to get' $(NAME).log > /dev/null ); then $(DOLATEX); fi
$(UNPACKED): $(DTX)
luatex -interaction=batchmode $< >/dev/null
diff --git a/macros/luatex/generic/luamplib/NEWS b/macros/luatex/generic/luamplib/NEWS
index b3919afaf3..1e4fcf9520 100644
--- a/macros/luatex/generic/luamplib/NEWS
+++ b/macros/luatex/generic/luamplib/NEWS
@@ -1,5 +1,56 @@
History of the luamplib package
+2024/07/27 2.34.3
+ * in DVI mode, use LaTeX's shipout hooks to generate new XObjects
+ or to put resources to pageresources. (in plain, load atbegshi.sty)
+
+ * fix shading to allow the even-odd rule
+
+2024/07/24 2.34.2
+ * With the newly introduced macros, \mplibgroup ... \endmplibgroup, users
+ can define a transparency group or a normal form XObject from TeX side.
+ The LaTeX environment 'mplibgroup' is identical to this pair of macros.
+ See the document for details.
+
+ * document: be more precise about the color effect of a transparency group
+
+ * remove trailing zeros from numeric objects to get smaller PDF
+
+2024/07/19 2.34.1
+ * transparency group is available with plain format as well.
+ * transparency group once used is reusable in the TeX code or
+ in other MetaPost code chunks. see the document for details.
+
+2024/07/17 2.34.0
+ * support transparency group with metafun format
+ * fix regarding default value in circular fading mode
+ * fix regarging the scope of graphics state
+
+2024/07/14 2.33.1
+ * refactor the manual, including some minor items undocumented so far
+ * improve fading routine to get possibly smaller pdf file
+
+2024/07/08 2.33.0
+ * provide a new metapost operator 'withfademethod' and related macros,
+ which make the color of an object gradiently transparent. see luamplib
+ document for details.
+
+ * fix spot-color shading routine to support user-defined colorspace
+
+2024/07/03 2.32.4
+ * make the variable 'patterns' local
+ * 'math.randomseed' on plain TeX
+ * remove redundant code 'fullcircle scaled 0'
+
+2024/06/21 2.32.3
+ * 'coloured' is a synonym of the option 'colored' in pattern definition.
+
+ * fix a bug related to pdf page resources in dvi mode
+
+ * users can access the lua table containing mplib instances 'luamplib.instances',
+ through which metapost variables are also easily accessible as documented in
+ LuaTeX manual 11.2.8.4.
+
2024/06/14 2.32.2
* fix matrix conversion between MP and PDF
diff --git a/macros/luatex/generic/luamplib/luamplib.dtx b/macros/luatex/generic/luamplib/luamplib.dtx
index edae80ada6..440558a64e 100644
--- a/macros/luatex/generic/luamplib/luamplib.dtx
+++ b/macros/luatex/generic/luamplib/luamplib.dtx
@@ -2,8 +2,8 @@
%
% Copyright (C) 2008-2024 by Hans Hagen, Taco Hoekwater, Elie Roux,
% Manuel Pégourié-Gonnard, Philipp Gesang and Kim Dohyun.
-% Currently maintained by the LuaLaTeX development team.
-% Support: <lualatex-dev@tug.org>
+% Currently maintained by Kim Dohyun.
+% Support: <https://github.com/lualatex/luamplib>
%
% This work is under the GPL v2.0 license.
%
@@ -85,9 +85,9 @@ See source file '\inFileName' for licencing and contact information.
%<*driver>
\NeedsTeXFormat{LaTeX2e}
\ProvidesFile{luamplib.drv}%
- [2024/06/14 v2.32.2 Interface for using the mplib library]%
+ [2024/07/27 v2.34.3 Interface for using the mplib library]%
\documentclass{ltxdoc}
-\usepackage{metalogo,multicol,mdwlist,fancyvrb,xspace}
+\usepackage{metalogo,multicol,xspace}
\usepackage[x11names]{xcolor}
%
\def\primarycolor{DodgerBlue4} %%-> rgb 16 78 139 | #104e8b
@@ -123,7 +123,9 @@ See source file '\inFileName' for licencing and contact information.
\newcommand*\email [1] {<\href{mailto:#1}{#1}>}
\newcommand \file {\nolinkurl}
-\newcommand \pk {\textsf}
+
+\newcommand*\metapost {\textsc{metapost}\xspace}
+\newcommand*\mplib {\pkg{mplib}\xspace}
\begin{document}
\DocInput{luamplib.dtx}%
@@ -149,125 +151,164 @@ See source file '\inFileName' for licencing and contact information.
% Grave accent \` Left brace \{ Vertical bar \|
% Right brace \} Tilde \~}
%
-% \title{The \textsf{luamplib} package}
+% \title{The \pkg{luamplib} package}
% \author{Hans Hagen, Taco Hoekwater, Elie Roux, Philipp Gesang and Kim Dohyun\\
-% Maintainer: LuaLaTeX Maintainers ---
-% Support: \email{lualatex-dev@tug.org}}
-% \date{2024/06/14 v2.32.2}
+% Current Maintainer: Kim Dohyun\\
+% Support: \url{https://github.com/lualatex/luamplib}}
+% \date{2024/07/27 v2.34.3}
%
% \maketitle
%
% \begin{abstract}
-% Package to have metapost code typeset directly in a document with \LuaTeX.
+% Package to have \metapost code typeset directly in a document with \LuaTeX.
% \end{abstract}
%
% \section{Documentation}
%
-% This packages aims at providing a simple way to typeset directly metapost
-% code in a document with \LuaTeX. \LuaTeX\ is built with the lua
-% \texttt{mplib} library, that runs metapost code. This package is basically a
-% wrapper (in Lua) for the Lua \texttt{mplib} functions and some \TeX\
-% functions to have the output of the \texttt{mplib} functions in the pdf.
-%
-% In the past,
-% the package required PDF mode in order to output something.
-% Starting with version 2.7 it works in DVI mode as well, though
-% DVIPDFMx is the only DVI tool currently supported.
-%
-% The metapost figures are put in a \TeX\ \texttt{hbox} with dimensions
-% adjusted to the metapost code.
+% This package aims at providing a simple way to typeset directly \metapost
+% code in a document with \LuaTeX. \LuaTeX\ is built with the Lua
+% \mplib library, that runs \metapost code. This package is basically a
+% wrapper for the Lua \mplib functions and some \TeX\
+% functions to have the output of the \mplib functions in the pdf.
%
-% Using this package is easy: in Plain, type your metapost code between the
+% Using this package is easy: in Plain, type your \metapost code between the
% macros \cs{mplibcode} and \cs{endmplibcode}, and in \LaTeX\ in the
-% \texttt{mplibcode} environment.
+% |mplibcode| environment.
%
-% The code is from the \texttt{luatex-mplib.lua} and \texttt{luatex-mplib.tex} files
-% from \ConTeXt, they have been adapted to \LaTeX\ and Plain by Elie Roux and
-% Philipp Gesang, new functionalities have been added by Kim Dohyun.
-% The changes are:
+% The resulting \metapost figures are put in a \TeX\ |hbox| with dimensions
+% adjusted to the \metapost code.
+%
+% The code of luamplib is basically from the |luatex-mplib.lua| and |luatex-mplib.tex| files
+% from \ConTeXt. They have been adapted to \LaTeX\ and Plain by Elie Roux and
+% Philipp Gesang and new functionalities have been added by Kim Dohyun.
+% The most notable changes are:
%
% \begin{itemize}
-% \item a \LaTeX\ environment
-% \item all \TeX\ macros start by |mplib|
-% \item use of our own function for errors, warnings and informations
% \item possibility to use |btex ... etex| to typeset \TeX\ code.
-% |textext()| is a more versatile macro equivalent to |TEX()| from TEX.mp.
-% |TEX()| is also allowed and is a synomym of |textext()|.\par\smallskip
-% \textsc{n.b.} Since v2.5, |btex ... etex| input from external |mp| files
-% will also be processed by \textsf{luamplib}.\par\smallskip
-% \textsc{n.b.} Since v2.20, |verbatimtex ... etex| from external |mp| files
-% will be also processed by \textsf{luamplib}. Warning: This is a change
-% from previous version.
+% |textext()| is a more versatile macro equivalent to |TEX()| from \pkg{TEX.mp}.
+% |TEX()| is also allowed and is a synonym of |textext()|.
+% The argument of
+% \mplib's primitive |maketext| will also be processed by the same routine.
+%
+% \item possibility to use |verbatimtex ... etex|, though it's behavior cannot
+% be the same as the stand-alone \pkg{mpost}.
+% Of course you cannot include \cs{documentclass}, \cs{usepackage} etc.
+% When these \TeX\ commands are found in |verbatimtex ... etex|, the entire code will be
+% ignored.
+% The treatment of |verbatimtex| command has changed a lot since v2.20:
+% see \hyperlink{mpliblegacybehavior}{below \S\,1.1}.
+%
+% \item in the past,
+% the package required PDF mode in order to have some output.
+% Starting with version 2.7 it works in DVI mode as well, though
+% DVIPDFMx is the only DVI tool currently supported.
% \end{itemize}
%
-% Some more changes and cautions are:
+% It seems to be convenient to divide the explanations of some more changes and cautions
+% into three parts: \TeX, \textsc{MetaPost}, and Lua interfaces.
+%
+% \subsection{\TeX}
%
% \paragraph{\cs{mplibforcehmode}}
-% When this macro is declared, every mplibcode figure box will be
+% When this macro is declared, every \metapost figure box will be
% typeset in horizontal mode, so \cs{centering}, \cs{raggedleft} etc
-% will have effects. |\mplibnoforcehmode|, being default, reverts this
-% setting. (Actually these commands redefine |\prependtomplibbox|. You
-% can define this command with anything suitable before a box.)
+% will have effects. \cs{mplibnoforcehmode}, being default, reverts this
+% setting. (Actually these commands redefine \cs{prependtomplibbox}; you
+% can redefine this command with anything suitable before a box.)
%
-% \paragraph{\cs{mpfig} \ldots\ \cs{endmpfig}}
-% Since v2.29 we provide unexpandable \TeX\ macros |\mpfig ... \endmpfig| and its starred version
-% |\mpfig* ... \endmpfig| to save typing toil.
-% The first is roughly the same as follows:
-% \begin{verbatim}
-% \begin{mplibcode}[@mpfig]
-% beginfig(0)
-% token list declared by \everymplib[@mpfig]
-% ...
-% token list declared by \everyendmplib[@mpfig]
-% endfig;
-% \end{mplibcode}
-% \end{verbatim}
-% and the starred version is roughly the same as follows:
-% \begin{verbatim}
-% \begin{mplibcode}[@mpfig]
-% ...
+% \paragraph{\cs{everymplib\{...\}}, \cs{everyendmplib\{...\}}}
+% \cs{everymplib} and \cs{everyendmplib} redefine
+% the lua table containing \metapost code
+% which will
+% be automatically inserted at the beginning and ending of each \metapost code chunk.
+%\begin{verbatim}
+% \everymplib{ beginfig(0); }
+% \everyendmplib{ endfig; }
+% \begin{mplibcode}
+% % beginfig/endfig not needed
+% draw fullcircle scaled 1cm;
% \end{mplibcode}
-% \end{verbatim}
-% In these macros |\mpliblegacybehavior{disable}| (see below)
-% is forcibly declared.
-% And as both share the same instance name, metapost codes are inherited among them.
-% A simple example:
-% \begin{verbatim}
-% \mpfig* input boxes \endmpfig
-% \everymplib[@mpfig]{ drawoptions(withcolor .5[red,white]); }
-% \mpfig circleit.a(btex Box 1 etex); drawboxed(a); \endmpfig
-% \end{verbatim}
-% The instance name (default: |@mpfig|) can be changed by redefining
-% \cs{mpfiginstancename}, after which a new MPlib instance will start and
-% code inheritance too will begin anew. |\let\mpfiginstancename\empty| will
-% prevent code inheritance if |\mplibcodeinherit{true}| (see below) is not declared.\footnote{%
-% As for user setting values, |enable|, |true|, |yes| are identical, and
-% |disable|, |false|, |no| are identical.}
-%
-% \paragraph{\cs{mpliblegacybehavior\{enable\}}}
-% By default, |\mpliblegacybehavior{enable}| is already declared,
-% in which case
-% a |verbatimtex ... etex| that comes just before |beginfig()|
-% is not ignored, but the \TeX\ code will be inserted before the
-% following mplib hbox. Using this command,
-% each mplib box can be freely moved horizontally and/or vertically.
-% Also, a box number might be assigned to mplib box, allowing it to be
-% reused later (see test files).
-% \begin{verbatim}
+%\end{verbatim}
+%
+% \paragraph{\cs{mplibsetformat\{plain\textbar metafun\}}}
+% There are (basically) two formats for \metapost: \emph{plain} and
+% \emph{metafun}. By default, the \emph{plain} format is used, but you can set
+% the format to be used by future figures at any time using
+% \cs{mplibsetformat\{<format name>\}}.
+%
+% \textsc{n.b.} As \emph{metafun} is such a complicated format,
+% we cannot support all the functionalities producing special effects provided by \emph{metafun}.
+% At least, however, transparency (actually opacity), transparency group, and shading (gradient colors)
+% are fully supported,
+% and outlinetext is supported by our own alternative |mpliboutlinetext|
+% (see \hyperlink{mpliboutlinetext}{below \S\,1.2}).
+%
+% \leavevmode\llap{\textcolor{red}{☞}\kern1.2\parindent}\relax
+% Among these, transparency is so simple that you can apply it to an object,
+% even with the \emph{plain} format,
+% just by appending |withprescript| |"tr_transparency=<number>"| to the sentence.
+% ($0 \le \hbox{\emph{<number>}} \le 1$)
+%
+% \hypertarget{metafunformat}{}\relax
+% As for transparency group, the current \emph{metafun} document \S\,8.8 is not correct.
+% The true syntax is:
+%\begin{verbatim}
+% draw <picture>|<path> asgroup <string>
+%\end{verbatim}
+% where \emph{<string>} should be |""| (empty), |"isolated"|, |"knockout"|, or |"isolated,knockout"|.
+% Beware that currently many of the PDF rendering applications, except Adobe Acrobat Reader,
+% cannot properly render the isolated or knockout effect.
+% Transparency group is available with \emph{plain} format as well, with extended functionality.
+% See \hyperlink{transparencygroup}{below \S\,1.2}.
+%
+% One thing worth mentioning about shading is:
+% when a color expression is given in string type,
+% it is regarded by luamplib as
+% a color expression of \TeX\ side.
+% For instance, when |withshadecolors("orange", 2/3red)| is given, the first color |"orange"| will be
+% interpreted as a \pkg{color}, \pkg{xcolor} or \pkg{l3color}'s expression.
+%
+% \paragraph{\cs{mplibnumbersystem\{scaled\textbar double\textbar decimal\}}}
+% Users can choose |numbersystem| option.
+% The default value is |scaled|, which can be changed
+% by declaring \cs{mplibnumbersystem\{double\}} or
+% \cs{mplibnumbersystem\{decimal\}}.
+%
+% \paragraph{\cs{mplibshowlog\{enable\textbar disable\}}}
+% Default: |disable|.
+% When \cs{mplibshowlog\{enable\}}\footnote{As for user's setting,
+% |enable|, |true| and |yes| are identical;
+% |disable|, |false| and |no| are identical.} is declared, log messages returned by
+% the \metapost process will be printed to the |.log| file.
+% This is the \TeX{} side interface for |luamplib.showlog|.
+%
+% \paragraph{\cs{mpliblegacybehavior\{enable\textbar disable\}}}
+% \hypertarget{mpliblegacybehavior}{}\relax
+% By default, \cs{mpliblegacybehavior\{enable\}}
+% is already declared for backward compatibility,
+% in which case \TeX\ code in
+% |verbatimtex| |...| |etex| that comes just before |beginfig()|
+% will be inserted before the
+% following \metapost figure box. In this way,
+% each figure box can be freely moved horizontally or vertically.
+% Also, a box number can be assigned to a figure box, allowing it to be
+% reused later.
+%\begin{verbatim}
% \mplibcode
% verbatimtex \moveright 3cm etex; beginfig(0); ... endfig;
% verbatimtex \leavevmode etex; beginfig(1); ... endfig;
% verbatimtex \leavevmode\lower 1ex etex; beginfig(2); ... endfig;
% verbatimtex \endgraf\moveright 1cm etex; beginfig(3); ... endfig;
% \endmplibcode
-% \end{verbatim}
+%\end{verbatim}
% \textsc{n.b.} \cs{endgraf} should be used instead of \cs{par} inside
% |verbatimtex ... etex|.
%
-% By contrast, \TeX\ code in |VerbatimTeX(...)| or |verbatimtex ... etex|
+% On the other hand, \TeX\ code in |verbatimtex ... etex|
% between |beginfig()| and |endfig| will be inserted
-% after flushing out the mplib figure.
-% \begin{verbatim}
+% after flushing out the \metapost figure.
+% As shown in the example below, |VerbatimTeX()| is a synonym of |verbatimtex| |...| |etex|.
+%\begin{verbatim}
% \mplibcode
% D := sqrt(2)**7;
% beginfig(0);
@@ -276,15 +317,15 @@ See source file '\inFileName' for licencing and contact information.
% endfig;
% \endmplibcode
% diameter: \Dia bp.
-% \end{verbatim}
+%\end{verbatim}
%
-% \paragraph{\cs{mpliblegacybehavior\{disable\}}}
-% If |\mpliblegacybehavior{disabled}| is declared by user, any
-% |verbatimtex ... etex| will be executed, along with |btex ... etex|,
+% By contrast,
+% when \cs{mpliblegacybehavior\{disable\}} is declared, any
+% |verbatimtex| |...| |etex| will be executed, along with |btex| |...| |etex|,
% sequentially one by one.
% So, some \TeX\ code in |verbatimtex ... etex| will have effects on
-% |btex ... etex| codes that follows.
-% \begin{verbatim}
+% following |btex| |...| |etex| codes.
+%\begin{verbatim}
% \begin{mplibcode}
% beginfig(0);
% draw btex ABC etex;
@@ -293,114 +334,72 @@ See source file '\inFileName' for licencing and contact information.
% draw btex GHI etex shifted (2cm,0); % bold face
% endfig;
% \end{mplibcode}
-% \end{verbatim}
-%
-% \paragraph{\cs{everymplib}, \cs{everyendmplib}}
-% Since v2.3, new macros \cs{everymplib} and \cs{everyendmplib} redefine
-% the lua table containing MetaPost code
-% which will
-% be automatically inserted at the beginning and ending of each |mplibcode|.
-% \begin{verbatim}
-% \everymplib{ beginfig(0); }
-% \everyendmplib{ endfig; }
-% \mplibcode % beginfig/endfig not needed
-% draw fullcircle scaled 1cm;
-% \endmplibcode
-% \end{verbatim}
-%
-% \paragraph{\cs{mpdim}}
-% Since v2.3, \cs{mpdim} and other raw \TeX\ commands are allowed
-% inside mplib code. This feature is inpired by gmp.sty authored by
-% Enrico Gregorio. Please refer the manual of gmp package for details.
-% \begin{verbatim}
-% \begin{mplibcode}
-% draw origin--(.6\mpdim{\linewidth},0) withpen pencircle scaled 4
-% dashed evenly scaled 4 withcolor \mpcolor{orange};
-% \end{mplibcode}
-% \end{verbatim}
-% \textsc{n.b.} Users should not use the protected variant of
-% |btex ... etex| as provided by gmp package. As \textsf{luamplib}
-% automatically protects \TeX\ code inbetween, \cs{btex} is not supported
-% here.
-%
-% \paragraph{\cs{mpcolor}}
-% With \cs{mpcolor} command, color names or expressions of
-% \textsf{color}/\textsf{xcolor} packages can be used inside mplibcode
-% enviroment (after |withcolor| operator),
-% though \textsf{luamplib} does not automatically load these
-% packages. See the example code above. For spot colors,
-% \textsf{colorspace}, \textsf{spotcolor}
-% (in PDF mode) and \textsf{xespotcolor} (in DVI mode) packages are supported
-% as well.
-%
-% From v2.26.1, \textsf{l3color} is also supported by the command
-% \cs{mpcolor\{color expression\}}, including spot colors.
+%\end{verbatim}
%
-% \paragraph{\cs{mplibnumbersystem}}
-% Users can choose |numbersystem| option since v2.4.
-% The default value |scaled| can be changed to |double| or |decimal|
-% by declaring |\mplibnumbersystem{double}| or |\mplibnumbersystem{decimal}|.
-% For details see
-% \url{http://github.com/lualatex/luamplib/issues/21}.
-%
-% \paragraph{\cs{mplibtextextlabel}}
-% Starting with v2.6, |\mplibtextextlabel{enable}| enables
-% string labels typeset via |textext()| instead of |infont| operator.
+% \paragraph{\cs{mplibtextextlabel\{enable\textbar disable\}}}
+% Default: |disable|.
+% \cs{mplibtextextlabel\{enable\}} enables
+% the labels typeset via |textext| instead of |infont| operator.
% So, |label("my text",origin)| thereafter is exactly the same as
-% |label(textext("my text"),origin)|. \textsc{n.b.} In the background,
-% \textsf{luamplib} redefines |infont| operator so that the right side
-% argument (the font part) is totally ignored. Every string label
-% therefore will be typeset with current \TeX\ font.
+% |label(textext("my text"),origin)|.
+%
+% \textsc{n.b.} In the background,
+% luamplib redefines |infont| operator so that the right side
+% argument (the font part) is totally ignored. Therefore the left side arguemnt
+% will be typeset with the current \TeX\ font.
% Also take care of |char| operator in the left side argument,
% as this might bring unpermitted characters into \TeX.
%
-% \paragraph{\cs{mplibcodeinherit}}
-% Starting with v2.9, |\mplibcodeinherit{enable}| enables the inheritance
-% of variables, constants, and macros defined by previous |mplibcode| chunks.
-% On the contrary, the default value |\mplibcodeinherit{disable}| will make
-% each code chunks being treated as an independent instance, and never
+% \paragraph{\cs{mplibcodeinherit\{enable\textbar disable\}}}
+% Default: |disable|.
+% \cs{mplibcodeinherit\{enable\}} enables the inheritance
+% of variables, constants, and macros defined by previous \metapost code chunks.
+% On the contrary, \cs{mplibcodeinherit\{disable\}} will make
+% each code chunk being treated as an independent instance, never
% affected by previous code chunks.
%
-% \paragraph{Separate instances for \LaTeX{} and plain \TeX}
-% v2.22 has added the support for several named MetaPost instances
+% \paragraph{Separate \metapost instances}
+% luamplib v2.22 has added the support for several named \metapost instances
% in \LaTeX{} |mplibcode| environment.
-% (And since v2.29 plain \TeX\ users can use this functionality as well.)
-% Syntax is like so:
-% \begin{verbatim}
+% Plain \TeX\ users also can use this functionality.
+% The syntax for \LaTeX\ is:
+%\begin{verbatim}
% \begin{mplibcode}[instanceName]
% % some mp code
% \end{mplibcode}
-% \end{verbatim}
-% Behaviour is as follows.
+%\end{verbatim}
+% The behavior is as follows.
% \begin{itemize}
% \item All the variables and functions are shared
% only among all the environments belonging to the same instance.
-% \item |\mplibcodeinherit| only affects environments
+% \item \cs{mplibcodeinherit} only affects environments
% with no instance name set (since if a name is set,
% the code is intended to be reused at some point).
-% \item From v2.27, |btex ... etex| boxes are also shared and do not
-% require |\mplibglobaltextext|.
+% \item |btex ... etex| boxes are also shared and do not
+% require \cs{mplibglobaltextext}.
% \item When an instance names is set,
-% respective |\currentmpinstancename| is set.
+% respective \cs{currentmpinstancename} is set as well.
% \end{itemize}
-% In parellel with this functionality, v2.23 and after supports
+% In parellel with this functionality, we support
% optional argument of instance name for \cs{everymplib} and
% \cs{everyendmplib}, affecting only those |mplibcode| environments
% of the same name.
% Unnamed \cs{everymplib} affects not only those instances with no name,
% but also those with name but with no corresponding \cs{everymplib}.
-% Syntax is:
-% \begin{verbatim}
+% The syntax is:
+%\begin{verbatim}
% \everymplib[instanceName]{...}
% \everyendmplib[instanceName]{...}
-% \end{verbatim}
+%\end{verbatim}
%
-% \paragraph{\cs{mplibglobaltextext}}
-% Formerly, to inherit |btex ... etex| boxes as well as metapost variables,
+% \paragraph{\cs{mplibglobaltextext\{enable\textbar disable\}}}
+% Default: |disable|.
+% Formerly, to inherit |btex| |...| |etex| boxes as well as other \metapost macros, variables and constants,
% it was necessary to declare \cs{mplibglobaltextext\{enable\}} in advance.
% But from v2.27, this is implicitly enabled when \cs{mplibcodeinherit}
-% is |true|.
-% \begin{verbatim}
+% is enabled.
+% This optional command still remains mostly for backward compatibility.
+%\begin{verbatim}
% \mplibcodeinherit{enable}
% %\mplibglobaltextext{enable}
% \everymplib{ beginfig(0);} \everyendmplib{ endfig;}
@@ -412,38 +411,92 @@ See source file '\inFileName' for licencing and contact information.
% \mplibcode
% currentpicture := pic scaled 2;
% \endmplibcode
-% \end{verbatim}
-% Generally speaking, it is recommended to turn |mplibglobaltextext|
-% always on, because it has the advantage of reusing metapost pictures
-% among code chunks.
-% But everything has its downside: it will waste more memory resources.
-%
-% \paragraph{\cs{mplibverbatim}}
-% Starting with v2.11, users can issue |\mplibverbatim{enable}|, after which
+%\end{verbatim}
+%
+% \paragraph{\cs{mplibverbatim\{enable\textbar disable\}}}
+% Default: |disable|.
+% Users can issue \cs{mplibverbatim\{enable\}}, after which
% the contents of mplibcode environment will be read verbatim. As a result,
-% except for |\mpdim| and |\mpcolor|, all other \TeX\ commands outside
-% |btex ... etex| or |verbatimtex ... etex| are not expanded and will be fed
-% literally into the mplib process.
-%
-% \paragraph{\cs{mplibshowlog}}
-% When |\mplibshowlog{enable}| is declared, log messages returned by
-% |mplib| instance will be printed into the |.log| file.
-% |\mplibshowlog{disable}| will revert this functionality.
-% This is a \TeX{} side interface for |luamplib.showlog|. (v2.20.8)
-%
-% \paragraph{Settings regarding cache files}
-% To support |btex ... etex| in external |.mp| files, \textsf{luamplib}
-% inspects the content of each and every |.mp| input files and makes caches
-% if nececcsary, before returning their paths to \LuaTeX's mplib library.
-% This would make the compilation time longer wastefully, as most |.mp| files
-% do not contain |btex ... etex| command. So \textsf{luamplib} provides
-% macros as follows, so that users can give instruction about files
+% except for \cs{mpdim} and \cs{mpcolor} (see \hyperlink{mpdim}{below}),
+% all other \TeX\ commands outside of the
+% |btex| or |verbatimtex| |...| |etex| are not expanded and will be fed
+% literally to the \mplib library.
+%
+% \paragraph{\cs{mpdim\{...\}}}
+% \hypertarget{mpdim}{}\relax
+% Besides other \TeX\ commands, \cs{mpdim} is specially allowed
+% in the mplibcode environment. This feature is inpired by \pkg{gmp} package authored by
+% Enrico Gregorio. Please refer to the manual of \pkg{gmp} package for details.
+%\begin{verbatim}
+% \begin{mplibcode}
+% beginfig(1)
+% draw origin--(.6\mpdim{\linewidth},0) withpen pencircle scaled 4
+% dashed evenly scaled 4 withcolor \mpcolor{orange};
+% endfig;
+% \end{mplibcode}
+%\end{verbatim}
+%
+% \paragraph{\cs{mpcolor[...]\{...\}}}
+% With \cs{mpcolor} command, color names or expressions of
+% \pkg{color}, \pkg{xcolor} and \pkg{l3color} module/packages can be used in the mplibcode
+% environment (after |withcolor| operator).
+% See the example \hyperlink{mpdim}{above}.
+% The optional |[...]| denotes the option of \pkg{xcolor}'s \cs{color} command.
+% For spot colors, \pkg{l3color} (in PDF/DVI mode),
+% \pkg{colorspace}, \pkg{spotcolor}
+% (in PDF mode) and \pkg{xespotcolor} (in DVI mode) packages are supported
+% as well.
+%
+% \paragraph{\cs{mpfig} \ldots\ \cs{endmpfig}}
+% Besides the |mplibcode| environment (for \LaTeX) and
+% \cs{mplibcode ...} \cs{endmplibcode} (for Plain),
+% we also provide unexpandable \TeX\ macros \cs{mpfig} |...| \cs{endmpfig} and its starred version
+% \cs{mpfig*} |...| \cs{endmpfig} to save typing toil.
+% The former is roughly the same as follows:
+%\begin{verbatim}
+% \begin{mplibcode}[@mpfig]
+% beginfig(0)
+% token list declared by \everymplib[@mpfig]
+% ...
+% token list declared by \everyendmplib[@mpfig]
+% endfig;
+% \end{mplibcode}
+%\end{verbatim}
+% and the starred version is roughly the same as follows:
+%\begin{verbatim}
+% \begin{mplibcode}[@mpfig]
+% ...
+% \end{mplibcode}
+%\end{verbatim}
+% In these macros \cs{mpliblegacybehavior\{disable\}}
+% is forcibly declared.
+% Again, as both share the same instance name, \metapost codes are inherited among them.
+% A simple example:
+%\begin{verbatim}
+% \everymplib[@mpfig]{ drawoptions(withcolor .5[red,white]); }
+% \mpfig* input boxes \endmpfig
+% \mpfig
+% circleit.a(btex Box 1 etex); drawboxed(a);
+% \endmpfig
+%\end{verbatim}
+% The instance name (default: |@mpfig|) can be changed by redefining
+% \cs{mpfiginstancename}, after which a new \mplib instance will start and
+% code inheritance too will begin anew. \cs{let}\cs{mpfiginstancename}\cs{empty} will
+% prevent code inheritance if \cs{mplibcodeinherit\{true\}} is not declared.
+%
+% \paragraph{About cache files}
+% To support |btex ... etex| in external |.mp| files, luamplib
+% inspects the content of each and every |.mp| file and makes caches
+% if nececcsary, before returning their paths to \LuaTeX's \mplib library.
+% This could waste the compilation time, as most |.mp| files
+% do not contain |btex ... etex| commands. So luamplib provides
+% macros as follows, so that users can give instructions about files
% that do not require this functionality.
% \begin{itemize}
-% \item |\mplibmakenocache{<filename>[,<filename>,...]}|
-% \item |\mplibcancelnocache{<filename>[,<filename>,...]}|
+% \item \cs{mplibmakenocache\{<filename>[,<filename>,...]\}}
+% \item \cs{mplibcancelnocache\{<filename>[,<filename>,...]\}}
% \end{itemize}
-% where |<filename>| is a file name excluding |.mp| extension.
+% where |<filename>| is a filename excluding |.mp| extension.
% Note that |.mp| files under |$TEXMFMAIN/metapost/base| and
% |$TEXMFMAIN/metapost/context/base| are already registered by default.
%
@@ -451,64 +504,96 @@ See source file '\inFileName' for licencing and contact information.
% if it's not available (mostly not writable),
% in the directory where output files are saved:
% to be specific, |$TEXMF_OUTPUT_DIRECTORY/luamplib_cache|,
-% |./luamplib_cache|, |$TEXMFOUTPUT/luamplib_cache|, and |.| in this order.
-% (|$TEXMF_OUTPUT_DIRECTORY| is normally the value of |--output-directory|
-% command-line option.)
-% This behavior however can be changed by the command
-% |\mplibcachedir{<directory path>}|, where tilde (|~|) is interpreted
+% |./luamplib_cache|, |$TEXMFOUTPUT/luamplib_cache|, and |.|, in this order.
+% |$TEXMF_OUTPUT_DIRECTORY| is normally the value of |--output-directory|
+% command-line option.
+%
+% Users can change this behavior by the command
+% \cs{mplibcachedir\{<directory path>\}}, where tilde (|~|) is interpreted
% as the user's home directory (on a windows machine as well).
-% As backslashes (|\|) should be escaped by users, it would be easier to use
+% As backslashes (\cs{}) should be escaped by users, it would be easier to use
% slashes (|/|) instead.
%
-% \paragraph{\texttt{mplibtexcolor}, \texttt{mplibrgbtexcolor}}
-% |mplibtexcolor| is a metapost operator that converts a \TeX\ color expression
-% to a MetaPost color expression. For instance:
-% \begin{verbatim}
+% \paragraph{About figure box metric}
+% Notice that, after each figure is processed, the macro \cs{MPwidth} stores
+% the width value of the latest figure; \cs{MPheight}, the height value.
+% Incidentally, also note that \cs{MPllx}, \cs{MPlly}, \cs{MPurx}, and
+% \cs{MPury} store the bounding box information of the latest figure
+% without the unit |bp|.
+%
+% \paragraph{luamplib.cfg}
+% At the end of package loading, luamplib searches
+% |luamplib.cfg| and, if found, reads the file in automatically.
+% Frequently used settings such as \cs{everymplib}, \cs{mplibforcehmode}
+% or \cs{mplibcodeinherit} are suitable for going into this file.
+%
+% \subsection{\textsc{MetaPost}}
+%
+% \paragraph{\texttt{mplibdimen(...)}, \texttt{mplibcolor(...)}}
+% These are \metapost interfaces for the \TeX\ commands
+% \cs{mpdim} and \cs{mpcolor} (see \hyperlink{mpdim}{above}). For example,
+% |mplibdimen("\linewidth")| is basically the same as \cs{mpdim\{\cs{linewidth}\}}, and
+% |mplibcolor("red!50")| is basically the same as \cs{mpcolor\{red!50\}}.
+% The difference is that these \metapost operators can also be used in external |.mp| files,
+% which cannot have \TeX\ commands outside of the |btex| or |verbatimtex| |...| |etex|.
+%
+% \paragraph{\texttt{mplibtexcolor ...}, \texttt{mplibrgbtexcolor ...}}
+% |mplibtexcolor|, which accepts a string argument, is a \metapost operator that converts a \TeX\ color expression
+% to a \metapost color expression, that can be used anywhere color expression is expected
+% as well as after the |withcolor| operator.
+% For instance:
+%\begin{verbatim}
% color col;
% col := mplibtexcolor "olive!50";
-% \end{verbatim}
-% The result may vary in its color model (gray/rgb/cmyk)
+%\end{verbatim}
+% But the result may vary in its color model (gray/rgb/cmyk)
% according to the given \TeX\ color. (Spot colors are forced to
% cmyk model, so this operator is not recommended for spot colors.)
-% Therefore the example shown above would raise a metapost error:
+% Therefore the example shown above would raise a \metapost error:
% |cmykcolor col;| should have been declared.
-% By contrast, |mplibrgbtexcolor| always returns rgb model expressions.
-%
-% \paragraph{\texttt{mplibgraphictext}}
-% For some amusement, luamplib provides its own metapost operator
-% |mplibgraphictext|, the effect of which is similar to that of
-% \ConTeXt's |graphictext|. However syntax is somewhat different.
-% \begin{verbatim}
+% By contrast, |mplibrgbtexcolor| \emph{<string>} always returns rgb model expressions.
+%
+% \paragraph{\texttt{mplibgraphictext ...}}
+% |mplibgraphictext| is a \metapost operator, the effect of which is similar to that of
+% \ConTeXt's |graphictext| or our own |mpliboutlinetext|
+% (see \hyperlink{mpliboutlinetext}{below}).
+% However the syntax is somewhat different.
+%\begin{verbatim}
% mplibgraphictext "Funny"
% fakebold 2.3 % fontspec option
% drawcolor .7blue fillcolor "red!50" % color expressions
-% \end{verbatim}
+%\end{verbatim}
% |fakebold|, |drawcolor| and |fillcolor| are optional;
% default values are |2|, |"black"| and |"white"| respectively.
-% When color expressions are given as string, they are regarded as
-% xcolor's or l3color's expressions (this is the same with shading colors).
-% From v2.30, |scale| option is deprecated and is now a synonym of |scaled|.
+% When the color expressions are given in string type, they are regarded as
+% \pkg{color}, \pkg{xcolor} or \pkg{l3color}'s expressions.
% All from |mplibgraphictext| to the end of sentence will compose an
% anonymous |picture|, which can be drawn or assigned to a variable.
% Incidentally, |withdrawcolor| and |withfillcolor| are synonyms of
% |drawcolor| and |fillcolor|, hopefully to be compatible with |graphictext|.
-% \textsc{n.b.} Because luamplib's current implementation is quite different
-% from the \ConTeXt's, there are some limitations such that you can't
-% apply shading (gradient colors) to the text (But see below).
-% In DVI mode, |unicode-math| package is needed for math formula graphictext,
+%
+% \textsc{n.b.}
+% In some cases, |mplibgraphictext| will produce better results than \ConTeXt\
+% or even than our own |mpliboutlinetext|,
+% especially when processing complicated \TeX\ code
+% such as the vertical writing in Chinese or Japanese.
+% However, because the implementation is quite different from others,
+% there are some limitations such that you can't
+% apply shading (gradient colors) to the text. Again,
+% in DVI mode, \pkg{unicode-math} package is needed for math formula,
% as we cannot embolden type1 fonts in DVI mode.
%
-% \paragraph{\texttt{mplibglyph}, \texttt{mplibdrawglyph}}
-% From v2.30, we provide a new metapost operator |mplibglyph|, which returns a metapost picture
+% \paragraph{\texttt{mplibglyph ... of ...}}
+% From v2.30, we provide a new \metapost operator |mplibglyph|, which returns a \metapost picture
% containing outline paths of a glyph in opentype, truetype or type1 fonts.
-% When a type1 font is specified, metapost primitive |glyph| will be called.
-% \begin{verbatim}
+% When a type1 font is specified, \metapost primitive |glyph| will be called.
+%\begin{verbatim}
% mplibglyph 50 of \fontid\font % slot 50 of current font
% mplibglyph "Q" of "TU/TeXGyrePagella(0)/m/n/10" % font csname
% mplibglyph "Q" of "texgyrepagella-regular.otf" % raw filename
% mplibglyph "Q" of "Times.ttc(2)" % subfont number
% mplibglyph "Q" of "SourceHanSansK-VF.otf[Regular]" % instance name
-% \end{verbatim}
+%\end{verbatim}
% Both arguments before and after of ``|of|'' can be either a number or a string.
% Number arguments are regarded as a glyph slot (GID) and a font id number, repectively.
% String argument at the left side is regarded as a glyph name in the font or a unicode character.
@@ -518,76 +603,102 @@ See source file '\inFileName' for licencing and contact information.
% subfont number (starting from zero) of a TTC font; a string within brackets denotes
% an instance name of a variable font.
%
-% The returned picture will be quite similar to the result of |glyph| primitive in its structure.
-% So, metapost's |draw| command will fill the inner path of the picture with background color.
-% In contrast, |mplibdrawglyph| command fills the paths according to the Nonzero Winding
-% Number Rule. As a result, for instance, the area surrounded by inner path of ``O''
+% \paragraph{\texttt{mplibdrawglyph ...}}
+% The picture returned by |mplibglyph| will be quite similar to the result of |glyph| primitive in its structure.
+% So, \metapost's |draw| command will fill the inner path of the picture with the background color.
+% In contrast, |mplibdrawglyph| \emph{<picture>} command fills the paths according to the nonzero winding
+% number rule. As a result, for instance, the area surrounded by inner path of ``O''
% will remain transparent.
%
-% \paragraph{\texttt{mpliboutlinetext}}
-% From v2.31, we provide a new metapost operator |mpliboutlinetext|, which mimicks
-% metafun's |outlinetext|. So the syntax is the same as metafun's. See the metafun
-% manual \textsection\,8.7 (|texdoc metafun|). A simple example:
-% \begin{verbatim}
+% \leavevmode\llap{\textcolor{red}{☞}\kern1.2\parindent}\relax
+% To apply the nonzero winding number rule to a picture containing paths,
+% luamplib appends |withpostscript| |"collect"|
+% to the paths except the last one in the picture.
+% If you want the even-odd rule instead, you can, with \emph{plain} format as well,
+% additionally declare |withpostscript| |"evenodd"| to the last path in the picture.
+%
+% \paragraph{\texttt{mpliboutlinetext (...)}}
+% \hypertarget{mpliboutlinetext}{}\relax
+% From v2.31, a new \metapost operator |mpliboutlinetext| is available, which mimicks
+% \emph{metafun}'s |outlinetext|. So the syntax is the same: see the \emph{metafun}
+% manual \S\,8.7 (|texdoc metafun|). A simple example:
+%\begin{verbatim}
% draw mpliboutlinetext.b ("$\sqrt{2+\alpha}$")
% (withcolor \mpcolor{red!50})
% (withpen pencircle scaled .2 withcolor red)
% scaled 2 ;
-% \end{verbatim}
-% After the process of |mpliboutlinetext|, |mpliboutlinepic[]|
+%\end{verbatim}
+% After the process, |mpliboutlinepic[]|
% and |mpliboutlinenum| will be preserved as global variables;
% |mpliboutlinepic[1]| \ldots{} |mpliboutlinepic[mpliboutlinenum]|
% will be an array of images each of which containing a glyph or a rule.
+%
% \textsc{n.b.} As Unicode grapheme cluster is not considered in the array, a unit that must be
% a single cluster might be separated apart.
%
-% \paragraph{\cs{mppattern} \ldots\ \cs{endmppattern}, \texttt{withpattern}}
-% |\mppattern{<name>}| \ldots\ |\endmppattern| defines a tiling pattern
+% \paragraph{\cs{mppattern\{...\} ...} \cs{endmppattern}, \texttt{... withpattern ...}}
+% \hypertarget{mppattern}{}\relax
+% \TeX\ macros
+% \cs{mppattern\{<name>\}} |...| \cs{endmppattern} define a tiling pattern
% associated with the |<name>|.
-% MetaPost operator |withpattern|, the syntax being
-% \textit{path} |withpattern| \textit{string}, will return a metapost picture which fills
-% the given path with a tiling pattern of the |<name>|.
-% \begin{verbatim}
-% \mppattern{mypatt} % or \begin{mppattern}{mypatt}
-% [ % options: see below
-% xstep = 10, ystep = 12,
-% matrix = {0,1,-1,0}, % or "0 1 -1 0"
-% ]
-% \mpfig % or any other TeX code,
-% picture q;
-% q := btex Q etex;
-% fill bbox q withcolor .8[red,white];
-% draw q withcolor .8red;
-% \endmpfig
-% \endmppattern % or \end{mppattern}
-%
-% \mpfig
-% fill fullcircle scaled 100 withpostscript "collect";
-% draw unitsquare shifted - center unitsquare scaled 45
-% withpattern "mypatt"
-% withpostscript "evenodd" ;
-% \endmpfig
-% \end{verbatim}
-% The available options are:
-% \begin{center}
+% \metapost operator |withpattern|, the syntax being
+% \emph{<path>} |withpattern| \emph{<string>}, will return a \metapost picture which fills
+% the given path with a tiling pattern of the |<name>|
+% by replicating it horizontally and vertically.
+% An example:
+%\begin{verbatim}
+% \mppattern{mypatt} % or \begin{mppattern}{mypatt}
+% [ % options: see below
+% xstep = 10, ystep = 12,
+% matrix = {0, 1, -1, 0}, % or "0 1 -1 0"
+% ]
+% \mpfig % or any other TeX code,
+% draw (llcorner unitsquare--urcorner unitsquare)
+% scaled 10
+% withcolor 1/3[blue,white]
+% ;
+% draw (ulcorner unitsquare--lrcorner unitsquare)
+% scaled 10
+% withcolor 1/3[red,white]
+% ;
+% \endmpfig
+% \endmppattern % or \end{mppattern}
+%
+% \mpfig
+% draw fullcircle scaled 90
+% withpostscript "collect"
+% ;
+% draw fullcircle scaled 200
+% withpattern "mypatt"
+% withpen pencircle scaled 1
+% withcolor \mpcolor{red!50!blue!50}
+% withpostscript "evenodd"
+% ;
+% \endmpfig
+%\end{verbatim}
+%
+% The available options are listed in Table~\ref{tab:mppatternoptions}.
+% \begin{table}
+% \centering
+% \caption{options for \cs{mppattern}}\label{tab:mppatternoptions}
% \begin{tabular}{lll}\hline
% Key & Value Type & Explanation\\\hline
-% |xstep| &\textit{number} & horizontal spacing between pattern cells\\
-% |ystep| &\textit{number} & vertical spacing between pattern cells\\
-% |xshift| &\textit{number} & horizontal shifting of pattern cells\\
-% |yshift| &\textit{number} & vertical shifting of pattern cells\\
-% |matrix| &\textit{table} or \textit{string} & |xx|, |yx|, |xy|, |yy| values\kern1pt* or MP transformation code\\
-% |bbox| &\textit{table} or \textit{string} & |llx|, |lly|, |urx|, |ury| values\kern1pt*\\
-% |resources|&\textit{string} & PDF resources if needed\\
-% |colored| &\textit{boolean}& |false| for uncolored pattern. default: |true|\\\hline
+% |xstep| &\emph{number} & horizontal spacing between pattern cells\\
+% |ystep| &\emph{number} & vertical spacing between pattern cells\\
+% |xshift| &\emph{number} & horizontal shifting of pattern cells\\
+% |yshift| &\emph{number} & vertical shifting of pattern cells\\
+% |matrix| &\emph{table} or \emph{string} & |xx|, |yx|, |xy|, |yy| values\kern1pt* or MP transform code\\
+% |bbox| &\emph{table} or \emph{string} & |llx|, |lly|, |urx|, |ury| values\kern1pt*\\
+% |resources|&\emph{string} & PDF resources if needed\\
+% |colored| or |coloured| &\emph{boolean}& |false| for uncolored pattern. default: |true|\\\hline
% & & \small *\,in string type, numbers are separated by spaces\\
% \end{tabular}
-% \end{center}
+% \end{table}
%
-% For the sake of convenience, width and height values of tiling patterns will be written down
+% For the sake of convenience, the width and height values of tiling patterns will be written down
% into the log file. (depth is always zero.) Users can refer to them for option setting.
%
-% As for |matrix| option, metapost code such as `|rotated 30 slanted .2|' is allowed as well
+% As for |matrix| option, \metapost code such as `|rotated 30 slanted .2|' is allowed as well
% as string or table of four numbers. You can also set |xshift| and |yshift|
% values by using `|shifted|' operator. But when |xshift| or |yshift| option is explicitly
% given, they have precedence over the effect of `|shifted|' operator.
@@ -597,58 +708,273 @@ See source file '\inFileName' for licencing and contact information.
% However, as luamplib automatically includes the resources of the current page, this option
% is not needed in most cases.
%
-% Option |colored=false| will generate an uncolored pattern which shall have no color at all.
-% Uncolored pattern will be painted later by the color of a metapost object.
+% Option |colored=false| (|coloured| is a synonym of |colored|) will generate an uncolored pattern which shall have no color at all.
+% Uncolored pattern will be painted later by the color of a \metapost object.
% An example:
-% \begin{verbatim}
-% \begin{mppattern}{pattuncolored}
+%\begin{verbatim}
+% \begin{mppattern}{pattnocolor}
% [
% colored = false,
-% matrix = "rotated 30",
+% matrix = "slanted .3 rotated 30",
% ]
% \tiny\TeX
% \end{mppattern}
%
% \begin{mplibcode}
% beginfig(1)
-% picture tex; tex := mpliboutlinetext.p ("\bfseries \TeX");
-% i:=0;
-% for item within tex:
-% i:=i+1;
-% if i < length tex:
-% fill pathpart item scaled 10
-% withpostscript "collect";
-% else:
+% picture tex;
+% tex = mpliboutlinetext.p ("\bfseries \TeX");
+% for i=1 upto mpliboutlinenum:
+% j:=0;
+% for item within mpliboutlinepic[i]:
+% j:=j+1;
% draw pathpart item scaled 10
-% withpattern "pattuncolored"
-% withpen pencircle scaled 0.5
-% withcolor 0.7 blue % paints the pattern
-% ;
-% fi
+% if j < length mpliboutlinepic[i]:
+% withpostscript "collect"
+% else:
+% withpattern "pattnocolor"
+% withpen pencircle scaled 1/2
+% withcolor (i/4)[red,blue] % paints the pattern
+% fi;
+% endfor
% endfor
% endfig;
% \end{mplibcode}
-% \end{verbatim}
-%
-% \paragraph{About figure box metrics}
-% Notice that, after each figure is processed, macro \cs{MPwidth} stores
-% the width value of latest figure; \cs{MPheight}, the height value.
-% Incidentally, also note that \cs{MPllx}, \cs{MPlly}, \cs{MPurx}, and
-% \cs{MPury} store the bounding box information of latest figure
-% without the unit |bp|.
-%
-% \paragraph{luamplib.cfg}
-% At the end of package loading, \textsf{luamplib} searches
-% |luamplib.cfg| and, if found, reads the file in automatically.
-% Frequently used settings such as \cs{everymplib}, \cs{mplibforcehmode}
-% or \cs{mplibcodeinherit} are suitable for going into this file.
+%\end{verbatim}
+%
+% \paragraph{\texttt{... withfademethod ...}}
+% This is a \metapost operator which makes the color of an object gradiently transparent.
+% The syntax is \emph{<path>}\texttt{\textbar}\emph{<picture>} |withfademethod| \emph{<string>},
+% the latter being either |"linear"| or |"circular"|.
+% Though it is similar to the |withshademethod| from \emph{metafun},
+% the differences are: (1) the operand of |withfademethod| can be a picture as well as a path;
+% (2) you cannot make gradient colors, but can only make gradient opacity.
+%
+% Related macros to control optional values are:
+% \begin{description}
+% \let\bfseries\relax
+% \item [|withfadeopacity (|\emph{number, number}|)|]
+% sets the starting opacity and the ending opacity, default value being |(1,0)|.
+% `|1|' denotes full color; `|0|' full transparency.
+% \item [|withfadevector (|\emph{pair, pair}|)|]
+% sets the starting and ending points. Default value in the linear mode is
+% |(llcorner p, lrcorner p)|, where |p| is the operand,
+% meaning that fading starts from the left edge and ends at the right edge.
+% Default value in the circular mode is |(center p, center p)|, which means
+% centers of both starting and ending circles are the center of the bounding box.
+% \item [|withfadecenter|] is a synonym of |withfadevector|.
+% \item [|withfaderadius (|\emph{number, number}|)|]
+% sets the radii of starting and ending circles. This is no-op in the linear mode.
+% Default value is |(0, abs(center p - urcorner p))|, meaning that fading starts from the
+% center and ends at the four corners of the bounding box.
+% \item [|withfadebbox (|\emph{pair, pair}|)|]
+% sets the bounding box of the fading area, default value being |(llcorner p, urcorner p)|.
+% Though this option is not needed in most cases, there could be cases when users want to
+% explicitly control the bounding box.
+% \end{description}
+% An example:
+%\begin{verbatim}
+% \mpfig
+% picture mill;
+% mill = btex \includegraphics[width=100bp]{mill} etex;
+% draw mill
+% withfademethod "circular"
+% withfadecenter (center mill, center mill)
+% withfaderadius (20, 50)
+% withfadeopacity (1, 0)
+% ;
+% \endmpfig
+%\end{verbatim}
+%
+% \paragraph{\texttt{... asgroup ...}}
+% \hypertarget{transparencygroup}{}\relax
+% As said \hyperlink{metafunformat}{before},
+% transparency group is available with \emph{plain} as well as \emph{metafun} format.
+% The syntax is exactly the same:
+% \emph{<picture>} \textbar\ \emph{<path>} |asgroup|
+% |""| \textbar\ |"isolated"| \textbar\ |"knockout"| \textbar\ |"isolated,knockout"|,
+% which will return a \metapost picture.
+% It is called \emph{Transparency Group} because the objects contained in the group are composited
+% to produce a single object, so that outer transparency effect, if any,
+% will be applied to the group as a whole, not to the individual objects cumulatively.
+%
+% The additional feature provided by luamplib is that
+% you can reuse the group as many times as you want
+% in the \TeX{} code or in other \metapost code chunks,
+% with infinitesimal increase in the size of PDF file.
+% For this functionality we provide \TeX{} and \metapost macros as follows:
+% \begin{description}
+% \let\bfseries\relax
+% \item[|withgroupname| \emph{<string>}] associates a transparency group with the given name.
+% When this is not appended to the sentense with |asgroup| operator,
+% the default group name `|lastmplibgroup|' will be used.
+%
+% \item[\cs{usemplibgroup\{...\}}]
+% \hypertarget{usemplibgroup}{}\relax
+% is a \TeX\ command to reuse a transparency group of the name
+% once used.
+% Note that the position of the group will be origin-based:
+% in other words, lower-left corner of the group will be shifted to the origin.
+%
+% \item[|usemplibgroup| \emph{<string>}] is a \metapost command which will add
+% a transparency group of the name to the |currentpicture|.
+% Contrary to the \TeX\ command just mentioned,
+% the position of the group is the same as the original transparency group.
+% \end{description}
+% An example showing the difference between the \TeX\ and \metapost commands:
+%\begin{verbatim}
+% \mpfig
+% draw image(
+% fill fullcircle scaled 100 shifted 25right withcolor .5[blue,white];
+% fill fullcircle scaled 100 withcolor .5[red,white] ;
+% ) asgroup "" withgroupname "mygroup";
+% draw (left--right) scaled 10;
+% draw (up--down) scaled 10;
+% \endmpfig
+%
+% \noindent
+% \clap{\vrule width 20pt height .25pt depth .25pt}%
+% \clap{\vrule width .5pt height 10pt depth 10pt}%
+% \usemplibgroup{mygroup}
+%
+% \mpfig
+% usemplibgroup "mygroup" rotated 15;
+% draw (left--right) scaled 10;
+% draw (up--down) scaled 10;
+% \endmpfig
+%\end{verbatim}
+%
+% Also note that normally the reused transparency groups are not affected by outer color commands.
+% However, if you have made the original transparency group using |withoutcolor| command,
+% colors will have effects on the uncolored objects in the group.
+%
+% \paragraph{\cs{mplibgroup\{...\} ...} \cs{endmplibgroup}}
+% These \TeX\ macros are described here in this subsection, as they are
+% deeply related to the |asgroup| operator.
+% Users can define a transparency group or a normal \emph{form XObject}
+% with these macros from \TeX\ side.
+% The syntax is similar to the \cs{mppattern} command (see \hyperlink{mppattern}{above}).
+% An example:
+%\begin{verbatim}
+% \mplibgroup{mygrx} % or \begin{mplibgroup}{mygrx}
+% [ % options: see below
+% asgroup="",
+% ]
+% \mpfig % or any other TeX code
+% draw (left--right) scaled 30 rotated 45 withpen pencircle scaled 10;
+% draw (left--right) scaled 30 rotated -45 withpen pencircle scaled 10;
+% \endmpfig
+% \endmplibgroup % or \end{mplibgroup}
+%
+% \usemplibgroup{mygrx}
+%
+% \mpfig
+% usemplibgroup "mygrx" scaled 1.5 withprescript "tr_transparency=0.5";
+% \endmpfig
+%\end{verbatim}
+% Availabe options, much fewer than those for \cs{mppattern},
+% are listed in Table~\ref{tab:mplibgroupoptions}.
+% \begin{table}
+% \centering
+% \caption{options for \cs{mplibgroup}}\label{tab:mplibgroupoptions}
+% \begin{tabular}{lll}
+% \hline
+% Key & Value Type & Explanation\\
+% \hline
+% |asgroup| &\emph{string} & |""|, |"isolated"|, |"knockout"|, or |"isolated,knockout"|\\
+% |bbox| &\emph{table} or \emph{string} & |llx|, |lly|, |urx|, |ury| values\kern1pt*\\
+% |matrix| &\emph{table} or \emph{string} & |xx|, |yx|, |xy|, |yy| values\kern1pt*
+% or MP transform code\\
+% |resources| &\emph{string} & PDF resources if needed\\
+% \hline
+% & & \small *\,in string type, numbers are separated by spaces\\
+% \end{tabular}
+% \end{table}
+%
+% When |asgroup| option, including empty string, is not given,
+% a normal form XObject will be generated rather than a transparency group.
+% So, the individual objects, not the XObject as a whole, will be affected
+% by outer transparency command.
+%
+% As shown in the example, you can reuse the transparency group or the normal form XObject
+% once defined
+% using the \TeX\ command \cs{usemplibgroup} or
+% the \metapost command |usemplibgroup|.
+% The behavior of these commands is the same as that described \hyperlink{usemplibgroup}{above}.
+%
+%
+% \subsection{Lua}
+%
+% \paragraph{\texttt{runscript ...}}
+% Using the primitive |runscript| \emph{<string>}, you can run a Lua code chunk from \metapost side
+% and get some \metapost code returned by Lua if you want.
+% As the functionality is provided by the \mplib library itself,
+% luamplib does not have much to say about it.
+%
+% One thing is worth mentioning, however:
+% if you return a Lua \emph{table} to the \metapost process,
+% it is automatically converted to a relevant \metapost value type
+% such as pair, color, cmykcolor or transform.
+% So users can save some extra toil of converting a table to a string, though it's not a big deal.
+% For instance, |runscript "return {1,0,0}"| will give you the \metapost color expression |(1,0,0)|
+% automatically.
+%
+% \paragraph{Lua table \texttt{luamplib.instances}}
+% Users can access the Lua table containing \mplib instances, |luamplib.instances|,
+% through which \metapost variables are also easily accessible from Lua side,
+% as documented in Lua\TeX{} manual \S\,11.2.8.4 (|texdoc luatex|).
+% The following will print |false|, |3.0|, |MetaPost| and
+% the knots and the cyclicity of the path |unitsquare|, consecutively.
+%\begin{verbatim}
+% \begin{mplibcode}[instance1]
+% boolean b; b = 1 > 2;
+% numeric n; n = 3;
+% string s; s = "MetaPost";
+% path p; p = unitsquare;
+% \end{mplibcode}
%
-% \bigskip
+% \directlua{
+% local instance1 = luamplib.instances.instance1
+% print( instance1:get_boolean "b" )
+% print( instance1:get_number "n" )
+% print( instance1:get_string "s" )
+% local t = instance1:get_path "p"
+% for k,v in pairs(t) do
+% print(k, type(v)=='table' and table.concat(v,' ') or v)
+% end
+% }
+%\end{verbatim}
+%
+% \paragraph{Lua function \texttt{luamplib.process\_mplibcode}}
+% Users can execute a \metapost code chunk from Lua side by using this function:
+%\begin{verbatim}
+% luamplib.process_mplibcode (<string> metapost code, <string> instance name)
+%\end{verbatim}
+% The second argument cannot be absent, but can be an empty string (|""|) which
+% means that it has no instance name.
+%
+% Some other elements in the |luamplib| namespace, listed in Table~\ref{tab:elementsinluamplib},
+% can have effects on the process of |process_mplibcode|.
+% \begin{table}
+% \centering
+% \caption{elements in \texttt{luamplib} table (partial)}\label{tab:elementsinluamplib}
+% \begin{tabular}{lll}\hline
+% Key & Type & Related \TeX\ macro \\\hline
+% |codeinherit| & \emph{boolean} & \cs{mplibcodeinherit}\\
+% |everyendmplib| & \emph{table} & \cs{everyendmplib}\\
+% |everymplib| & \emph{table} & \cs{everymplib}\\
+% |getcachedir| & \emph{function} (\emph{<string>}) & \cs{mplibcachedir}\\
+% |globaltextext| & \emph{boolean} & \cs{mplibglobaltextext}\\
+% |legacyverbatimtex| & \emph{boolean} & \cs{mpliblegacybehavior}\\
+% |noneedtoreplace| & \emph{table} & \cs{mplibmakenocache}\\
+% |numbersystem| & \emph{string} & \cs{mplibnumbersystem}\\
+% |setformat| & \emph{function} (\emph{<string>}) & \cs{mplibsetformat}\\
+% |showlog| & \emph{boolean} & \cs{mplibshowlog}\\
+% |textextlabel| & \emph{boolean} & \cs{mplibtextextlabel}\\
+% |verbatiminput| & \emph{boolean} & \cs{mplibverbatim}\\\hline
+% \end{tabular}
+% \end{table}
%
-% There are (basically) two formats for metapost: \emph{plain} and
-% \emph{metafun}. By default, the \emph{plain} format is used, but you can set
-% the format to be used by future figures at any time using
-% \cs{mplibsetformat}\marg{format name}.
%
% \section{Implementation}
%
@@ -662,14 +988,14 @@ See source file '\inFileName' for licencing and contact information.
luatexbase.provides_module {
name = "luamplib",
- version = "2.32.2",
- date = "2024/06/14",
+ version = "2.34.3",
+ date = "2024/07/27",
description = "Lua package to typeset Metapost with LuaTeX's MPLib.",
}
% \end{macrocode}
%
-% Use the |luamplib| namespace, since |mplib| is for the metapost library
+% Use the |luamplib| namespace, since |mplib| is for the \metapost library
% itself. \ConTeXt{} uses |metapost|.
% \begin{macrocode}
luamplib = luamplib or { }
@@ -705,7 +1031,6 @@ local function termorlog (target, text, kind)
if kind == "Error" then error() end
end
end
-
local function warn (...) -- beware '%' symbol
termorlog("term and log", select("#",...) > 1 and format(...) or ...)
end
@@ -721,33 +1046,23 @@ luamplib.showlog = luamplib.showlog or false
% \end{macrocode}
%
% This module is a stripped down version of libraries that are used by
-% \ConTeXt. Provide a few ``shortcuts'' expected by the imported code.
+% \ConTeXt. Provide a few ``shortcuts'' expected by the code.
% \begin{macrocode}
local tableconcat = table.concat
local tableinsert = table.insert
+local tableunpack = table.unpack
local texsprint = tex.sprint
local texgettoks = tex.gettoks
local texgetbox = tex.getbox
local texruntoks = tex.runtoks
-% \end{macrocode}
-%
-% We don't use |tex.scantoks| anymore. See below reagrding |tex.runtoks|.
-% \begin{verbatim}
-% local texscantoks = tex.scantoks
-% \end{verbatim}
-% \begin{macrocode}
-
if not texruntoks then
err("Your LuaTeX version is too old. Please upgrade it to the latest")
end
-
local is_defined = token.is_defined
local get_macro = token.get_macro
-
local mplib = require ('mplib')
local kpse = require ('kpse')
local lfs = require ('lfs')
-
local lfsattributes = lfs.attributes
local lfsisdir = lfs.isdir
local lfsmkdir = lfs.mkdir
@@ -763,7 +1078,6 @@ local file = file or { }
local replacesuffix = file.replacesuffix or function(filename, suffix)
return (filename:gsub("%.[%a%d]+$","")) .. "." .. suffix
end
-
local is_writable = file.is_writable or function(name)
if lfsisdir(name) then
name = name .. "/_luam_plib_temp_file_"
@@ -785,14 +1099,11 @@ end
% \end{macrocode}
%
% |btex ... etex| in input |.mp| files will be replaced in finder.
-% Because of the limitation of MPLib regarding |make_text|,
+% Because of the limitation of \mplib regarding |make_text|,
% we might have to make cache files modified from input files.
% \begin{macrocode}
-local luamplibtime = kpse.find_file("luamplib.lua")
-luamplibtime = luamplibtime and lfsattributes(luamplibtime,"modification")
-
+local luamplibtime = lfsattributes(kpse.find_file"luamplib.lua", "modification")
local currenttime = os.time()
-
local outputdir, cachedir
if lfstouch then
for i,v in ipairs{'TEXMFVAR','TEXMF_OUTPUT_DIRECTORY','.','TEXMFOUTPUT'} do
@@ -829,10 +1140,9 @@ function luamplib.getcachedir(dir)
end
end
end
-
% \end{macrocode}
%
-% Some basic MetaPost files not necessary to make cache files.
+% Some basic \metapost files not necessary to make cache files.
% \begin{macrocode}
local noneedtoreplace = {
["boxes.mp"] = true, -- ["format.mp"] = true,
@@ -851,7 +1161,6 @@ local noneedtoreplace = {
["mp-tool.mpiv"] = true, ["mp-cont.mpiv"] = true,
}
luamplib.noneedtoreplace = noneedtoreplace
-
% \end{macrocode}
%
% |format.mp| is much complicated, so specially treated.
@@ -873,7 +1182,6 @@ local function replaceformatmp(file,newfile,ofmodify)
lfstouch(newfile,currenttime,ofmodify)
return newfile
end
-
% \end{macrocode}
%
% Replace |btex ... etex| and |verbatimtex ... etex| in input files,
@@ -883,7 +1191,6 @@ local name_b = "%f[%a_]"
local name_e = "%f[^%a_]"
local btex_etex = name_b.."btex"..name_e.."%s*(.-)%s*"..name_b.."etex"..name_e
local verbatimtex_etex = name_b.."verbatimtex"..name_e.."%s*(.-)%s*"..name_b.."etex"..name_e
-
local function replaceinputmpfile (name,file)
local ofmodify = lfsattributes(file,"modification")
if not ofmodify then return file end
@@ -896,23 +1203,19 @@ local function replaceinputmpfile (name,file)
return nf.size == 0 and file or newfile
end
end
-
if name == "format.mp" then return replaceformatmp(file,newfile,ofmodify) end
-
local fh = ioopen(file,"r")
if not fh then return file end
local data = fh:read("*all"); fh:close()
-
% \end{macrocode}
-% ``|etex|'' must be followed by a space or semicolon as specified in
-% \LuaTeX\ manual, which is not the case of standalone MetaPost though.
+% ``|etex|'' must be preceded by a space and followed by a space or semicolon as specified in
+% \LuaTeX\ manual, which is not the case of standalone \metapost though.
% \begin{macrocode}
local count,cnt = 0,0
data, cnt = data:gsub(btex_etex, "btex %1 etex ") -- space
count = count + cnt
data, cnt = data:gsub(verbatimtex_etex, "verbatimtex %1 etex;") -- semicolon
count = count + cnt
-
if count == 0 then
noneedtoreplace[name] = true
fh = ioopen(newfile,"w");
@@ -922,7 +1225,6 @@ local function replaceinputmpfile (name,file)
end
return file
end
-
fh = ioopen(newfile,"w")
if not fh then return file end
fh:write(data); fh:close()
@@ -932,8 +1234,8 @@ end
% \end{macrocode}
%
-% As the finder function for MPLib, use the |kpse| library and
-% make it behave like as if MetaPost was used. And replace it with
+% As the finder function for \mplib, use the |kpse| library and
+% make it behave like as if \metapost was used. And replace |.mp| files with
% cache files if needed.
% See also \#74, \#97.
% \begin{macrocode}
@@ -945,12 +1247,10 @@ do
end
mpkpse = kpse.new(arg[exe], "mpost")
end
-
local special_ftype = {
pfb = "type1 fonts",
enc = "enc files",
}
-
function luamplib.finder (name, mode, ftype)
if mode == "w" then
if name and name ~= "mpout.log" then
@@ -976,9 +1276,9 @@ end
% \end{macrocode}
%
-% Create and load MPLib instances.
-% We do not support ancient version of MPLib any more.
-% (Don't know which version of MPLib started to support
+% Create and load \mplib instances.
+% We do not support ancient version of \mplib any more.
+% (Don't know which version of \mplib started to support
% |make_text| and |run_script|; let the users find it.)
% \begin{macrocode}
local preamble = [[
@@ -987,25 +1287,23 @@ local preamble = [[
let normalfontsize = fontsize;
input %s ;
]]
-
% \end{macrocode}
%
-% |plain| or |metafun|,
-% though we cannot support |metafun| format fully.
+% \emph{plain} or \emph{metafun},
+% though we cannot support \emph{metafun} format fully.
% \begin{macrocode}
local currentformat = "plain"
function luamplib.setformat (name)
currentformat = name
end
-
% \end{macrocode}
%
% v2.9 has introduced the concept of ``code inherit''
% \begin{macrocode}
luamplib.codeinherit = false
local mplibinstances = {}
+luamplib.instances = mplibinstances
local has_instancename = false
-
local function reporterror (result, prevlog)
if not result then
err("no result object returned")
@@ -1032,7 +1330,7 @@ local function reporterror (result, prevlog)
% \end{macrocode}
% v2.6.1: now luamplib does not disregard |show| command,
% even when |luamplib.showlog| is false. Incidentally,
-% it does not raise error but just prints an info,
+% it does not raise error nor prints an info,
% even if output has no figure.
% \begin{macrocode}
local show = log:match"\n>>? .+"
@@ -1046,17 +1344,20 @@ local function reporterror (result, prevlog)
return log
end
end
-
+% \end{macrocode}
+%
+% |lualibs-os.lua| installs a randomseed. When this file is not loaded,
+% we should explicitly seed a unique integer to get random randomseed for each run.
+% \begin{macrocode}
+if not math.initialseed then math.randomseed(currenttime) end
local function luamplibload (name)
local mpx = mplib.new {
ini_version = true,
find_file = luamplib.finder,
% \end{macrocode}
% Make use of |make_text| and |run_script|, which will co-operate
-% with \LuaTeX's |tex.runtoks|. And we
-% provide |numbersystem| option since v2.4. Default value ``|scaled|''
-% can be changed by declaring |\mplibnumbersystem{double}|
-% or |\mplibnumbersystem{decimal}|.
+% with \LuaTeX's |tex.runtoks| or other Lua functions. And we
+% provide |numbersystem| option since v2.4.
% See \url{https://github.com/lualatex/luamplib/issues/21}.
% \begin{macrocode}
make_text = luamplib.maketext,
@@ -1067,12 +1368,12 @@ local function luamplibload (name)
extensions = 1,
}
% \end{macrocode}
-% Append our own MetaPost preamble to the preamble above.
+% Append our own \metapost preamble to the preamble above.
% \begin{macrocode}
local preamble = tableconcat{
format(preamble, replacesuffix(name,"mp")),
luamplib.preambles.mplibcode,
- luamplib.legacy_verbatimtex and luamplib.preambles.legacyverbatimtex or "",
+ luamplib.legacyverbatimtex and luamplib.preambles.legacyverbatimtex or "",
luamplib.textextlabel and luamplib.preambles.textextlabel or "",
}
local result, log
@@ -1084,22 +1385,12 @@ local function luamplibload (name)
log = reporterror(result)
return mpx, result, log
end
-
% \end{macrocode}
%
% Here, excute each |mplibcode| data,
% ie |\begin{mplibcode} ... \end{mplibcode}|.
% \begin{macrocode}
local function process (data, instancename)
-% \end{macrocode}
-% The workaround of issue \#70 seems to be unnecessary, as we use
-% |make_text| now.
-% \begin{verbatim}
-% if not data:find(name_b.."beginfig%s*%([%+%-%s]*%d[%.%d%s]*%)") then
-% data = data .. "beginfig(-1);endfig;"
-% end
-% \end{verbatim}
-% \begin{macrocode}
local currfmt
if instancename and instancename ~= "" then
currfmt = instancename
@@ -1109,7 +1400,7 @@ local function process (data, instancename)
currentformat,
luamplib.numbersystem or "scaled",
tostring(luamplib.textextlabel),
- tostring(luamplib.legacy_verbatimtex),
+ tostring(luamplib.legacyverbatimtex),
}
has_instancename = false
end
@@ -1143,40 +1434,30 @@ end
% |dvipdfmx| is supported, though nobody seems to use it.
% \begin{macrocode}
local pdfmode = tex.outputmode > 0
+
% \end{macrocode}
%
-% |make_text| and some |run_script| uses \LuaTeX's |tex.runtoks|,
-% which made possible running \TeX\ code snippets inside |\directlua|.
+% |make_text| and some |run_script| uses \LuaTeX's |tex.runtoks|.
% \begin{macrocode}
local catlatex = luatexbase.registernumber("catcodetable@latex")
local catat11 = luatexbase.registernumber("catcodetable@atletter")
-
% \end{macrocode}
%
% |tex.scantoks| sometimes fail to read catcode properly, especially
% |\#|, |\&|, or |\%|. After some experiment, we dropped using it.
-% Instead, a function containing |tex.script| seems to work nicely.
-% \begin{verbatim}
-% local function run_tex_code_no_use (str, cat)
-% cat = cat or catlatex
-% texscantoks("mplibtmptoks", cat, str)
-% texruntoks("mplibtmptoks")
-% end
-% \end{verbatim}
+% Instead, a function containing |tex.sprint| seems to work nicely.
% \begin{macrocode}
local function run_tex_code (str, cat)
texruntoks(function() texsprint(cat or catlatex, str) end)
end
-
% \end{macrocode}
%
-% Prepare textext box number containers,
-% locals, globals and possibly instances.
+% Prepare textext box number containers, locals and globals.
% |localid| can be any number. They are local anyway.
% The number will be reset at the start of a new code chunk.
% Global boxes will use |\newbox| command in |tex.runtoks| process.
-% This is the same when |codeinherit| is declared as true.
-% Boxes of an instance will also be global, so that
+% This is the same when |codeinherit| is true.
+% Boxes in instances with name will also be global, so that
% their tex boxes can be shared among instances of the same name.
% \begin{macrocode}
local texboxes = { globalid = 0, localid = 4096 }
@@ -1184,11 +1465,9 @@ local texboxes = { globalid = 0, localid = 4096 }
% For conversion of |sp| to |bp|.
% \begin{macrocode}
local factor = 65536*(7227/7200)
-
local textext_fmt = 'image(addto currentpicture doublepath unitsquare \z
-xscaled %f yscaled %f shifted (0,-%f) \z
-withprescript "mplibtexboxid=%i:%f:%f")'
-
+ xscaled %f yscaled %f shifted (0,-%f) \z
+ withprescript "mplibtexboxid=%i:%f:%f")'
local function process_tex_text (str)
if str then
local global = (has_instancename or luamplib.globaltextext or luamplib.codeinherit)
@@ -1200,8 +1479,7 @@ local function process_tex_text (str)
else
local boxid = texboxes.globalid + 1
texboxes.globalid = boxid
- run_tex_code(format(
- [[\expandafter\newbox\csname luamplib.box.%s\endcsname]], boxid))
+ run_tex_code(format([[\expandafter\newbox\csname luamplib.box.%s\endcsname]], boxid))
tex_box_id = tex.getcount'allocationnumber'
end
run_tex_code(format("%s\\setbox%i\\hbox{%s}", global, tex_box_id, str))
@@ -1219,7 +1497,6 @@ end
% Make |color| or |xcolor|'s color expressions usable,
% with \cs{mpcolor} or |mplibcolor|. These commands should be used
% with graphical objects.
-%
% Attempt to support l3color as well.
% \begin{macrocode}
local mplibcolorfmt = {
@@ -1235,7 +1512,6 @@ local mplibcolorfmt = {
[[\color_select:n%s\endgroup]],
},
}
-
local colfmt = is_defined'color_select:n' and "l3color" or "xcolor"
if colfmt == "l3color" then
run_tex_code{
@@ -1249,7 +1525,6 @@ if colfmt == "l3color" then
}
end
local ccexplat = luatexbase.registernumber"luamplibcctabexplat"
-
local function process_color (str)
if str then
if not str:find("%b{}") then
@@ -1310,20 +1585,18 @@ end
%
% For legacy verbatimtex process.
% |verbatimtex ... etex| before |beginfig()| is not ignored,
-% but the \TeX\ code is inserted just before the mplib box. And
-% \TeX\ code inside |beginfig() ... endfig| is inserted after the mplib box.
+% but the \TeX\ code is inserted just before the \mplib box. And
+% \TeX\ code inside |beginfig() ... endfig| is inserted after the \mplib box.
% \begin{macrocode}
local tex_code_pre_mplib = {}
luamplib.figid = 1
luamplib.in_the_fig = false
-
local function process_verbatimtex_prefig (str)
if str then
tex_code_pre_mplib[luamplib.figid] = str
end
return ""
end
-
local function process_verbatimtex_infig (str)
if str then
return format('special "postmplibverbtex=%s";', str)
@@ -1342,17 +1615,16 @@ local runscript_funcs = {
% \end{macrocode}
%
-% For |metafun| format. see issue \#79.
+% For \emph{metafun} format. see issue \#79.
% \begin{macrocode}
mp = mp or {}
local mp = mp
mp.mf_path_reset = mp.mf_path_reset or function() end
mp.mf_finish_saving_data = mp.mf_finish_saving_data or function() end
mp.report = mp.report or info
-
% \end{macrocode}
%
-% metafun 2021-03-09 changes crashes luamplib.
+% \emph{metafun} 2021-03-09 changes crashes luamplib.
% \begin{macrocode}
catcodes = catcodes or {}
local catcodes = catcodes
@@ -1386,7 +1658,6 @@ local function mpprint(buffer,...)
end
end
end
-
function luamplib.runscript (code)
local id, str = code:match("(.-){(.*)}")
if id and str then
@@ -1408,7 +1679,7 @@ function luamplib.runscript (code)
return buffer
end
buffer = {}
- mpprint(buffer, table.unpack(res))
+ mpprint(buffer, tableunpack(res))
return tableconcat(buffer)
end
return ""
@@ -1425,9 +1696,7 @@ local function protecttexcontents (str)
:gsub("%zPerCent%z", "\\%%")
:gsub("%s+", " ")
end
-
-luamplib.legacy_verbatimtex = true
-
+luamplib.legacyverbatimtex = true
function luamplib.maketext (str, what)
if str and str ~= "" then
str = protecttexcontents(str)
@@ -1436,7 +1705,7 @@ function luamplib.maketext (str, what)
not str:find("\\begin%s*{document}") and
not str:find("\\documentstyle"..name_e) and
not str:find("\\usepackage"..name_e) then
- if luamplib.legacy_verbatimtex then
+ if luamplib.legacyverbatimtex then
if luamplib.in_the_fig then
return process_verbatimtex_infig(str)
else
@@ -1455,7 +1724,7 @@ end
% \end{macrocode}
%
-% luamplib's metapost color operators
+% luamplib's \metapost color operators
% \begin{macrocode}
local function colorsplit (res)
local t, tt = { }, res:gsub("[%[%]]",""):explode()
@@ -1495,7 +1764,7 @@ luamplib.shadecolor = function (str)
if res:find" cs " or res:find"@pdf.obj" then -- spot color shade: l3 only
% \end{macrocode}
% An example of spot color shading:
-% \begin{verbatim}
+%\begin{verbatim}
% \documentclass{article}
% \usepackage{luamplib}
% \mplibsetformat{metafun}
@@ -1541,37 +1810,63 @@ luamplib.shadecolor = function (str)
% endfig;
% \end{mplibcode}
% \end{document}
-% \end{verbatim}
+%\end{verbatim}
+% another one: user-defined DeviceN colorspace
+%\begin{verbatim}
+% \DocumentMetadata{ }
+% \documentclass{article}
+% \usepackage{luamplib}
+% \mplibsetformat{metafun}
+% \ExplSyntaxOn
+% \color_model_new:nnn { pantone1215 }
+% { Separation }
+% { name = PANTONE~1215~U ,
+% alternative-model = cmyk ,
+% alternative-values = {0, 0.15, 0.51, 0}
+% }
+% \color_model_new:nnn { pantone+black }
+% { DeviceN }
+% {
+% names = {pantone1215,black}
+% }
+% \color_set:nnn{purepantone}{pantone+black}{1,0}
+% \color_set:nnn{pureblack} {pantone+black}{0,1}
+% \ExplSyntaxOff
+% \begin{document}
+% \mpfig
+% fill unitsquare xscaled \mpdim{\textwidth} yscaled 30
+% withshademethod "linear"
+% withshadecolors ("purepantone","pureblack")
+% ;
+% \endmpfig
+% \end{document}
+%\end{verbatim}
% \begin{macrocode}
run_tex_code({
[[\color_export:nnN{]], str, [[}{backend}\mplib_@tempa]],
},ccexplat)
- local name = get_macro'mplib_@tempa':match'{(.-)}{.+}'
+ local name, value = get_macro'mplib_@tempa':match'{(.-)}{(.-)}'
local t, obj = res:explode()
if pdfmode then
- obj = t[1]:match"^/(.+)"
- if ltx.pdf and ltx.pdf.object_id then
- obj = format("%s 0 R", ltx.pdf.object_id(obj))
- else
- run_tex_code({
- [[\edef\mplib_@tempa{\pdf_object_ref:n{]], obj, "}}",
- },ccexplat)
- obj = get_macro'mplib_@tempa'
- end
+ obj = format("%s 0 R", ltx.pdf.object_id( t[1]:sub(2,-1) ))
else
obj = t[2]
end
- local value = t[3]:match"%[(.-)%]" or t[3]
- return format('(%s) withprescript"mplib_spotcolor=%s:%s"', value,obj,name)
+ return format('(1) withprescript"mplib_spotcolor=%s:%s:%s"', value,obj,name)
end
return colorsplit(res)
end
% \end{macrocode}
%
+% Remove trailing zeros for smaller PDF
+% \begin{macrocode}
+local function rmzeros(str) return str:gsub("%.?0+$","") end
+
+% \end{macrocode}
+%
% luamplib's mplibgraphictext operator
% \begin{macrocode}
-local running = -1073741824
local emboldenfonts = { }
local function getemboldenwidth (curr, fakebold)
local width = emboldenfonts.width
@@ -1604,13 +1899,14 @@ local function getrulewhatsit (line, wd, ht, dp)
fmt = "pdf:content "..fmt
pl = node.new("whatsit","special")
end
- pl.data = fmt:format(line, 0, -dp, wd, ht+dp, "B")
+ pl.data = fmt:format(line, 0, -dp, wd, ht+dp, "B") :gsub("%.%d+", rmzeros)
local ss = node.new"glue"
node.setglue(ss, 0, 65536, 65536, 2, 2)
pl.next = ss
return pl
end
local function getrulemetric (box, curr, bp)
+ local running = -1073741824
local wd,ht,dp = curr.width, curr.height, curr.depth
wd = wd == running and box.width or wd
ht = ht == running and box.height or ht
@@ -1868,7 +2164,7 @@ function luamplib.glyph (f, c)
if not gid then return mperr"cannot get GID (glyph id)" end
local fac = 1000 / (shapedata.units or 1000)
local t = shapedata.glyphs[gid].segments
- if not t then return "image(fill fullcircle scaled 0;)" end
+ if not t then return "image()" end
for i,v in ipairs(t) do
if type(v) == "table" then
for ii,vv in ipairs(v) do
@@ -1887,7 +2183,7 @@ end
% mpliboutlinetext : based on mkiv's font-mps.lua
% \begin{macrocode}
local rulefmt = "mpliboutlinepic[%i]:=image(addto currentpicture contour \z
-unitsquare shifted - center unitsquare;) xscaled %f yscaled %f shifted (%f,%f);"
+ unitsquare shifted - center unitsquare;) xscaled %f yscaled %f shifted (%f,%f);"
local outline_horz, outline_vert
function outline_vert (res, box, curr, xshift, yshift)
local b2u = box.dir == "LTL"
@@ -2122,13 +2418,13 @@ function luamplib.outlinetext (text)
local id = tonumber(fmt:match"mplibtexboxid=(%d+):")
local box = texgetbox(id)
local res = outline_horz({ }, box, box.head, 0, 0)
- if #res == 0 then res = { "mpliboutlinepic[1]:=image(fill fullcircle scaled 0;);" } end
+ if #res == 0 then res = { "mpliboutlinepic[1]:=image();" } end
return tableconcat(res) .. format("mpliboutlinenum:=%i;", #res)
end
% \end{macrocode}
%
-% Our MetaPost preambles
+% Our \metapost preambles
% \begin{macrocode}
luamplib.preambles = {
mplibcode = [[
@@ -2327,6 +2623,63 @@ vardef mplibtransformmatrix (text e) =
& decimal ypart t & ","
& "}");
enddef;
+primarydef p withfademethod s =
+ if picture p:
+ image(
+ draw p;
+ draw center p withprescript "mplibfadestate=stop";
+ )
+ else:
+ p withprescript "mplibfadestate=stop"
+ fi
+ withprescript "mplibfadetype=" & s
+ withprescript "mplibfadebbox=" &
+ decimal xpart llcorner p & ":" &
+ decimal ypart llcorner p & ":" &
+ decimal xpart urcorner p & ":" &
+ decimal ypart urcorner p
+enddef;
+def withfadeopacity (expr a,b) =
+ withprescript "mplibfadeopacity=" &
+ decimal a & ":" &
+ decimal b
+enddef;
+def withfadevector (expr a,b) =
+ withprescript "mplibfadevector=" &
+ decimal xpart a & ":" &
+ decimal ypart a & ":" &
+ decimal xpart b & ":" &
+ decimal ypart b
+enddef;
+let withfadecenter = withfadevector;
+def withfaderadius (expr a,b) =
+ withprescript "mplibfaderadius=" &
+ decimal a & ":" &
+ decimal b
+enddef;
+def withfadebbox (expr a,b) =
+ withprescript "mplibfadebbox=" &
+ decimal xpart a & ":" &
+ decimal ypart a & ":" &
+ decimal xpart b & ":" &
+ decimal ypart b
+enddef;
+primarydef p asgroup s =
+ image(
+ fill llcorner p--lrcorner p--urcorner p--ulcorner p--cycle
+ withprescript "gr_state=start"
+ withprescript "gr_type=" & s;
+ draw p;
+ draw center p withprescript "gr_state=stop";
+ )
+enddef;
+def withgroupname expr s =
+ withprescript "mplibgroupname=" & s
+enddef;
+def usemplibgroup primary s =
+ draw maketext("\usemplibgroup{" & s & "}")
+ shifted runscript("return luamplib.trgroupshifts['" & s & "']")
+enddef;
]],
legacyverbatimtex = [[
def specialVerbatimTeX (text t) = runscript("luamplibprefig{"&t&"}") enddef;
@@ -2356,7 +2709,6 @@ enddef;
% When \cs{mplibverbatim} is enabled, do not expand |mplibcode| data.
% \begin{macrocode}
luamplib.verbatiminput = false
-
% \end{macrocode}
%
% Do not expand |btex ... etex|, |verbatimtex ... etex|, and
@@ -2372,7 +2724,6 @@ local function protect_expansion (str)
return format("\\unexpanded{%s}",str)
end
end
-
local function unprotect_expansion (str)
if str then
return str:gsub("!!!Control!!!", "\\")
@@ -2382,25 +2733,20 @@ local function unprotect_expansion (str)
:gsub("!!!RBrace!!!", "}")
end
end
-
luamplib.everymplib = setmetatable({ [""] = "" },{ __index = function(t) return t[""] end })
luamplib.everyendmplib = setmetatable({ [""] = "" },{ __index = function(t) return t[""] end })
-
function luamplib.process_mplibcode (data, instancename)
texboxes.localid = 4096
-
% \end{macrocode}
% This is needed for legacy behavior
% \begin{macrocode}
- if luamplib.legacy_verbatimtex then
+ if luamplib.legacyverbatimtex then
luamplib.figid, tex_code_pre_mplib = 1, {}
end
-
local everymplib = luamplib.everymplib[instancename]
local everyendmplib = luamplib.everyendmplib[instancename]
data = format("\n%s\n%s\n%s\n",everymplib, data, everyendmplib)
:gsub("\r","\n")
-
% \end{macrocode}
% These five lines are needed for |mplibverbatim| mode.
% \begin{macrocode}
@@ -2440,7 +2786,6 @@ function luamplib.process_mplibcode (data, instancename)
return format("verbatimtex %s etex", unprotect_expansion(str))
end)
end
-
process(data, instancename)
end
@@ -2470,144 +2815,34 @@ end
% \end{macrocode}
%
-% Codes below for inserting PDF lieterals are mostly from ConTeXt general,
-% with small changes when needed.
+% pdfliterals will be stored in |figcontents| table, and written to pdf in one go
+% at the end of the flushing figure.
+% Subtable |post| is for the legacy behavior.
% \begin{macrocode}
-local function getobjects(result,figure,f)
- return figure:objects()
-end
-
-function luamplib.convert (result, flusher)
- luamplib.flush(result, flusher)
- return true -- done
-end
-
local figcontents = { post = { } }
local function put2output(a,...)
figcontents[#figcontents+1] = type(a) == "string" and format(a,...) or a
end
-
local function pdf_startfigure(n,llx,lly,urx,ury)
put2output("\\mplibstarttoPDF{%f}{%f}{%f}{%f}",llx,lly,urx,ury)
end
-
local function pdf_stopfigure()
put2output("\\mplibstoptoPDF")
end
-
% \end{macrocode}
%
% |tex.sprint| with catcode regime -2, as sometimes |#| gets doubled
% in the argument of pdfliteral.
% \begin{macrocode}
-local function pdf_literalcode (fmt,...)
- put2output{-2, format(fmt,...)}
-end
-
-local function pdf_textfigure(font,size,text,width,height,depth)
- text = text:gsub(".",function(c)
- return format("\\hbox{\\char%i}",string.byte(c)) -- kerning happens in metapost : false
- end)
- put2output("\\mplibtextext{%s}{%f}{%s}{%s}{%s}",font,size,text,0,0)
-end
-
-local bend_tolerance = 131/65536
-
-local rx, sx, sy, ry, tx, ty, divider = 1, 0, 0, 1, 0, 0, 1
-
-local function pen_characteristics(object)
- local t = mplib.pen_info(object)
- rx, ry, sx, sy, tx, ty = t.rx, t.ry, t.sx, t.sy, t.tx, t.ty
- divider = sx*sy - rx*ry
- return not (sx==1 and rx==0 and ry==0 and sy==1 and tx==0 and ty==0), t.width
-end
-
-local function concat(px, py) -- no tx, ty here
- return (sy*px-ry*py)/divider,(sx*py-rx*px)/divider
-end
-
-local function curved(ith,pth)
- local d = pth.left_x - ith.right_x
- if abs(ith.right_x - ith.x_coord - d) <= bend_tolerance and abs(pth.x_coord - pth.left_x - d) <= bend_tolerance then
- d = pth.left_y - ith.right_y
- if abs(ith.right_y - ith.y_coord - d) <= bend_tolerance and abs(pth.y_coord - pth.left_y - d) <= bend_tolerance then
- return false
- end
- end
- return true
-end
-
-local function flushnormalpath(path,open)
- local pth, ith
- for i=1,#path do
- pth = path[i]
- if not ith then
- pdf_literalcode("%f %f m",pth.x_coord,pth.y_coord)
- elseif curved(ith,pth) then
- pdf_literalcode("%f %f %f %f %f %f c",ith.right_x,ith.right_y,pth.left_x,pth.left_y,pth.x_coord,pth.y_coord)
- else
- pdf_literalcode("%f %f l",pth.x_coord,pth.y_coord)
- end
- ith = pth
- end
- if not open then
- local one = path[1]
- if curved(pth,one) then
- pdf_literalcode("%f %f %f %f %f %f c",pth.right_x,pth.right_y,one.left_x,one.left_y,one.x_coord,one.y_coord )
- else
- pdf_literalcode("%f %f l",one.x_coord,one.y_coord)
- end
- elseif #path == 1 then -- special case .. draw point
- local one = path[1]
- pdf_literalcode("%f %f l",one.x_coord,one.y_coord)
- end
-end
-
-local function flushconcatpath(path,open)
- pdf_literalcode("%f %f %f %f %f %f cm", sx, rx, ry, sy, tx ,ty)
- local pth, ith
- for i=1,#path do
- pth = path[i]
- if not ith then
- pdf_literalcode("%f %f m",concat(pth.x_coord,pth.y_coord))
- elseif curved(ith,pth) then
- local a, b = concat(ith.right_x,ith.right_y)
- local c, d = concat(pth.left_x,pth.left_y)
- pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(pth.x_coord, pth.y_coord))
- else
- pdf_literalcode("%f %f l",concat(pth.x_coord, pth.y_coord))
- end
- ith = pth
- end
- if not open then
- local one = path[1]
- if curved(pth,one) then
- local a, b = concat(pth.right_x,pth.right_y)
- local c, d = concat(one.left_x,one.left_y)
- pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(one.x_coord, one.y_coord))
- else
- pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord))
- end
- elseif #path == 1 then -- special case .. draw point
- local one = path[1]
- pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord))
- end
-end
-
-local function start_pdf_code()
- if pdfmode then
- pdf_literalcode("q")
- else
- put2output"\\special{pdf:bcontent}"
- end
-end
-local function stop_pdf_code()
- if pdfmode then
- pdf_literalcode("Q")
- else
- put2output"\\special{pdf:econtent}"
- end
+local function pdf_literalcode (...)
+ put2output{ -2, format(...) :gsub("%.%d+", rmzeros) }
end
+local start_pdf_code = pdfmode
+ and function() pdf_literalcode"q" end
+ or function() put2output"\\special{pdf:bcontent}" end
+local stop_pdf_code = pdfmode
+ and function() pdf_literalcode"Q" end
+ or function() put2output"\\special{pdf:econtent}" end
% \end{macrocode}
%
@@ -2679,32 +2914,42 @@ local pdfobjs, pdfetcs = {}, {}
pdfetcs.pgfextgs = "pgf@sys@addpdfresource@extgs@plain"
pdfetcs.pgfpattern = "pgf@sys@addpdfresource@patterns@plain"
pdfetcs.pgfcolorspace = "pgf@sys@addpdfresource@colorspaces@plain"
-
-local function update_pdfobjs (os)
- local on = pdfobjs[os]
+local function update_pdfobjs (os, stream)
+ local key = os
+ if stream then key = key..stream end
+ local on = pdfobjs[key]
if on then
return on,false
end
if pdfmode then
- on = pdf.immediateobj(os)
+ if stream then
+ on = pdf.immediateobj("stream",stream,os)
+ else
+ on = pdf.immediateobj(os)
+ end
else
on = pdfetcs.cnt or 1
- texsprint(format("\\special{pdf:obj @mplibpdfobj%s %s}",on,os))
+ if stream then
+ texsprint(format("\\special{pdf:stream @mplibpdfobj%s (%s) <<%s>>}",on,stream,os))
+ else
+ texsprint(format("\\special{pdf:obj @mplibpdfobj%s %s}",on,os))
+ end
pdfetcs.cnt = on + 1
end
- pdfobjs[os] = on
+ pdfobjs[key] = on
return on,true
end
-
+pdfetcs.resfmt = pdfmode and "%s 0 R" or "@mplibpdfobj%s"
if pdfmode then
pdfetcs.getpageres = pdf.getpageresources or function() return pdf.pageresources end
- pdfetcs.setpageres = pdf.setpageresources or function(s) pdf.pageresources = s end
- pdfetcs.initialize_resources = function (name)
+ local getpageres = pdfetcs.getpageres
+ local setpageres = pdf.setpageresources or function(s) pdf.pageresources = s end
+ local initialize_resources = function (name)
local tabname = format("%s_res",name)
pdfetcs[tabname] = { }
if luatexbase.callbacktypes.finish_pdffile then -- ltluatex
local obj = pdf.reserveobj()
- pdfetcs.setpageres(format("%s/%s %i 0 R", pdfetcs.getpageres() or "", name, obj))
+ setpageres(format("%s/%s %i 0 R", getpageres() or "", name, obj))
luatexbase.add_to_callback("finish_pdffile", function()
pdf.immediateobj(obj, format("<<%s>>", tableconcat(pdfetcs[tabname])))
end,
@@ -2712,21 +2957,38 @@ if pdfmode then
end
end
pdfetcs.fallback_update_resources = function (name, res)
+ local tabname = format("%s_res",name)
+ if not pdfetcs[tabname] then
+ initialize_resources(name)
+ end
if luatexbase.callbacktypes.finish_pdffile then
- local t = pdfetcs[format("%s_res",name)]
+ local t = pdfetcs[tabname]
t[#t+1] = res
else
- local tpr, n = pdfetcs.getpageres() or "", 0
+ local tpr, n = getpageres() or "", 0
tpr, n = tpr:gsub(format("/%s<<",name), "%1"..res)
if n == 0 then
tpr = format("%s/%s<<%s>>", tpr, name, res)
end
- pdfetcs.setpageres(tpr)
+ setpageres(tpr)
end
end
else
- texsprint("\\special{pdf:obj @MPlibTr<<>>}","\\special{pdf:obj @MPlibSh<<>>}",
- "\\special{pdf:obj @MPlibCS<<>>}","\\special{pdf:obj @MPlibPt<<>>}")
+ texsprint {
+ "\\luamplibatfirstshipout{",
+ "\\special{pdf:obj @MPlibTr<<>>}",
+ "\\special{pdf:obj @MPlibSh<<>>}",
+ "\\special{pdf:obj @MPlibCS<<>>}",
+ "\\special{pdf:obj @MPlibPt<<>>}}",
+ }
+ pdfetcs.resadded = { }
+ pdfetcs.fallback_update_resources = function (name,obj,res)
+ texsprint{"\\special{pdf:put ", obj, " <<", res, ">>}"}
+ if not pdfetcs.resadded[name] then
+ texsprint{"\\luamplibateveryshipout{\\special{pdf:put @resources <</", name, " ", obj, ">>}}"}
+ pdfetcs.resadded[name] = obj
+ end
+ end
end
% \end{macrocode}
@@ -2740,65 +3002,66 @@ local transparancy_modes = { [0] = "Normal",
"Hue", "Saturation", "Color", "Luminosity",
"Compatible",
}
-
-local function update_tr_res(mode,opaq)
- local os = format("<</BM /%s/ca %.3f/CA %.3f/AIS false>>",mode,opaq,opaq)
- local on, new = update_pdfobjs(os)
- if not new then return on end
+local function add_extgs_resources (on, new)
local key = format("MPlibTr%s", on)
- local val = format(pdfmode and "%s 0 R" or "@mplibpdfobj%s", on)
- if pdfmanagement then
- texsprint(ccexplat,
- format("\\pdfmanagement_add:nnn{Page/Resources/ExtGState}{%s}{%s}", key, val))
- else
- local tr = format("/%s %s", key, val)
- if is_defined(pdfetcs.pgfextgs) then
- texsprint(format("\\csname %s\\endcsname{%s}", pdfetcs.pgfextgs,tr))
- elseif pdfmode then
- if is_defined"TRP@list" then
- texsprint(catat11,{
- [[\if@filesw\immediate\write\@auxout{]],
- [[\string\g@addto@macro\string\TRP@list{]],
- tr,
- [[}}\fi]],
- })
- if not get_macro"TRP@list":find(tr) then
- texsprint(catat11,[[\global\TRP@reruntrue]])
+ if new then
+ local val = format(pdfetcs.resfmt, on)
+ if pdfmanagement then
+ texsprint {
+ "\\csname pdfmanagement_add:nnn\\endcsname{Page/Resources/ExtGState}{", key, "}{", val, "}"
+ }
+ else
+ local tr = format("/%s %s", key, val)
+ if is_defined(pdfetcs.pgfextgs) then
+ texsprint { "\\csname ", pdfetcs.pgfextgs, "\\endcsname{", tr, "}" }
+ elseif pdfmode then
+ if is_defined"TRP@list" then
+ texsprint(catat11,{
+ [[\if@filesw\immediate\write\@auxout{]],
+ [[\string\g@addto@macro\string\TRP@list{]],
+ tr,
+ [[}}\fi]],
+ })
+ if not get_macro"TRP@list":find(tr) then
+ texsprint(catat11,[[\global\TRP@reruntrue]])
+ end
+ else
+ pdfetcs.fallback_update_resources("ExtGState", tr)
end
else
- if not pdfetcs.ExtGState_res then
- pdfetcs.initialize_resources"ExtGState"
- end
- pdfetcs.fallback_update_resources("ExtGState", tr)
+ pdfetcs.fallback_update_resources("ExtGState","@MPlibTr",tr)
end
- else
- texsprint(format("\\special{pdf:put @MPlibTr<<%s>>}",tr))
- texsprint"\\special{pdf:put @resources<</ExtGState @MPlibTr>>}"
end
end
- return on
+ return key
end
-
local function do_preobj_TR(object,prescript)
if object.postscript == "collect" then return end
local opaq = prescript and prescript.tr_transparency
- local tron_no
if opaq then
+ local key, on, os, new
local mode = prescript.tr_alternative or 1
- mode = transparancy_modes[tonumber(mode)]
- tron_no = update_tr_res(mode, opaq)
- start_pdf_code()
- pdf_literalcode("/MPlibTr%i gs",tron_no)
+ mode = transparancy_modes[tonumber(mode)] or mode
+ for i,v in ipairs{ {mode,opaq},{"Normal",1} } do
+ mode, opaq = v[1], v[2]
+ os = format("<</BM/%s/ca %s/CA %s/AIS false>>",mode,opaq,opaq)
+ on, new = update_pdfobjs(os)
+ key = add_extgs_resources(on,new)
+ if i == 1 then
+ pdf_literalcode("/%s gs",key)
+ else
+ return format("/%s gs",key)
+ end
+ end
end
- return tron_no
end
% \end{macrocode}
%
-% Shading with |metafun| format.
+% Shading with \emph{metafun} format.
% \begin{macrocode}
local function sh_pdfpageresources(shtype,domain,colorspace,ca,cb,coordinates,steps,fractions)
- local fun2fmt,os = "<</FunctionType 2/Domain [%s]/C0 [%s]/C1 [%s]/N 1>>"
+ local fun2fmt,os = "<</FunctionType 2/Domain[%s]/C0[%s]/C1[%s]/N 1>>"
if steps > 1 then
local list,bounds,encode = { },{ },{ }
for i=1,steps do
@@ -2808,48 +3071,44 @@ local function sh_pdfpageresources(shtype,domain,colorspace,ca,cb,coordinates,st
encode[2*i-1] = 0
encode[2*i] = 1
os = fun2fmt:format(domain,tableconcat(ca[i],' '),tableconcat(cb[i],' '))
- list[i] = format(pdfmode and "%s 0 R" or "@mplibpdfobj%s",update_pdfobjs(os))
+ list[i] = format(pdfetcs.resfmt, update_pdfobjs(os))
end
os = tableconcat {
"<</FunctionType 3",
- format("/Bounds [%s]", tableconcat(bounds,' ')),
- format("/Encode [%s]", tableconcat(encode,' ')),
- format("/Functions [%s]", tableconcat(list, ' ')),
- format("/Domain [%s]>>", domain),
+ format("/Bounds[%s]", tableconcat(bounds,' ')),
+ format("/Encode[%s]", tableconcat(encode,' ')),
+ format("/Functions[%s]", tableconcat(list, ' ')),
+ format("/Domain[%s]>>", domain),
}
else
os = fun2fmt:format(domain,tableconcat(ca[1],' '),tableconcat(cb[1],' '))
end
- local objref = format(pdfmode and "%s 0 R" or "@mplibpdfobj%s",update_pdfobjs(os))
+ local objref = format(pdfetcs.resfmt, update_pdfobjs(os))
os = tableconcat {
format("<</ShadingType %i", shtype),
format("/ColorSpace %s", colorspace),
format("/Function %s", objref),
- format("/Coords [%s]", coordinates),
- "/Extend [true true]/AntiAlias true>>",
+ format("/Coords[%s]", coordinates :gsub("%.%d+", rmzeros)),
+ "/Extend[true true]/AntiAlias true>>",
}
local on, new = update_pdfobjs(os)
- if not new then return on end
- local key = format("MPlibSh%s", on)
- local val = format(pdfmode and "%s 0 R" or "@mplibpdfobj%s", on)
- if pdfmanagement then
- texsprint(ccexplat,
- format("\\pdfmanagement_add:nnn{Page/Resources/Shading}{%s}{%s}", key, val))
- else
- local res = format("/%s %s", key, val)
- if pdfmode then
- if not pdfetcs.Shading_res then
- pdfetcs.initialize_resources"Shading"
- end
- pdfetcs.fallback_update_resources("Shading", res)
+ if new then
+ local key, val = format("MPlibSh%s", on), format(pdfetcs.resfmt, on)
+ if pdfmanagement then
+ texsprint {
+ "\\csname pdfmanagement_add:nnn\\endcsname{Page/Resources/Shading}{", key, "}{", val, "}"
+ }
else
- texsprint(format("\\special{pdf:put @MPlibSh<<%s>>}", res))
- texsprint"\\special{pdf:put @resources<</Shading @MPlibSh>>}"
+ local res = format("/%s %s", key, val)
+ if pdfmode then
+ pdfetcs.fallback_update_resources("Shading", res)
+ else
+ pdfetcs.fallback_update_resources("Shading","@MPlibSh",res)
+ end
end
end
return on
end
-
local function color_normalize(ca,cb)
if #cb == 1 then
if #ca == 4 then
@@ -2861,7 +3120,6 @@ local function color_normalize(ca,cb)
cb[1], cb[2], cb[3], cb[4] = 1-cb[1], 1-cb[2], 1-cb[3], 0
end
end
-
pdfetcs.clrspcs = setmetatable({ }, { __index = function(t,names)
run_tex_code({
[[\color_model_new:nnn]],
@@ -2873,7 +3131,6 @@ pdfetcs.clrspcs = setmetatable({ }, { __index = function(t,names)
t[names] = colorspace
return colorspace
end })
-
local function do_preobj_SH(object,prescript)
local shade_no
local sh_type = prescript and prescript.sh_type
@@ -2927,15 +3184,14 @@ local function do_preobj_SH(object,prescript)
local script = object.prescript:explode"\13+"
for i=#script,1,-1 do
if script[i]:find"mplib_spotcolor" then
- local name, value
- objref, name = script[i]:match"=(.-):(.+)"
- value = script[i+1]:match"=(.+)"
+ local t, name, value = script[i]:explode"="[2]:explode":"
+ value, objref, name = t[1], t[2], t[3]
if not names[name] then
pos = pos+1
names[name] = pos
names[#names+1] = name
end
- local t = { }
+ t = { }
for j=1,names[name] do t[#t+1] = 0 end
t[#t+1] = value
tableinsert(#ca == #cb and ca or cb, t)
@@ -2995,15 +3251,80 @@ end
%
% Patterns
% \begin{macrocode}
-patterns = { }
+pdfetcs.patterns = { }
+local function gather_resources (optres)
+ local t, do_pattern = { }, not optres
+ local names = {"ExtGState","ColorSpace","Shading"}
+ if do_pattern then
+ names[#names+1] = "Pattern"
+ end
+ if pdfmode then
+ if pdfmanagement then
+ for _,v in ipairs(names) do
+ local pp = get_macro(format("g__pdfdict_/g__pdf_Core/Page/Resources/%s_prop",v))
+ if pp and pp:find"__prop_pair" then
+ t[#t+1] = format("/%s %s 0 R", v, ltx.pdf.object_id("__pdf/Page/Resources/"..v))
+ end
+ end
+ else
+ local res = pdfetcs.getpageres() or ""
+ run_tex_code[[\mplibtmptoks\expandafter{\the\pdfvariable pageresources}]]
+ res = res .. texgettoks'mplibtmptoks'
+ if do_pattern then return res end
+ res = res:explode"/+"
+ for _,v in ipairs(res) do
+ v = v:match"^%s*(.-)%s*$"
+ if not v:find"Pattern" and not optres:find(v) then
+ t[#t+1] = "/" .. v
+ end
+ end
+ end
+ else
+ if pdfmanagement then
+ for _,v in ipairs(names) do
+ local pp = get_macro(format("g__pdfdict_/g__pdf_Core/Page/Resources/%s_prop",v))
+ if pp and pp:find"__prop_pair" then
+ run_tex_code {
+ "\\mplibtmptoks\\expanded{{",
+ format("/%s \\csname pdf_object_ref:n\\endcsname{__pdf/Page/Resources/%s}",v,v),
+ "}}",
+ }
+ t[#t+1] = texgettoks'mplibtmptoks'
+ end
+ end
+ elseif is_defined(pdfetcs.pgfextgs) then
+ run_tex_code ({
+ "\\mplibtmptoks\\expanded{{",
+ "\\ifpgf@sys@pdf@extgs@exists /ExtGState @pgfextgs\\fi",
+ "\\ifpgf@sys@pdf@colorspaces@exists /ColorSpace @pgfcolorspaces\\fi",
+ do_pattern and "\\ifpgf@sys@pdf@patterns@exists /Pattern @pgfpatterns \\fi" or "",
+ "}}",
+ }, catat11)
+ t[#t+1] = texgettoks'mplibtmptoks'
+ else
+ for _,v in ipairs(names) do
+ local vv = pdfetcs.resadded[v]
+ if vv then
+ t[#t+1] = format("/%s %s", v, vv)
+ end
+ end
+ end
+ end
+ return tableconcat(t)
+end
function luamplib.registerpattern ( boxid, name, opts )
local box = texgetbox(boxid)
- local wd = format("%.3f",box.width/factor)
- local hd = format("%.3f",(box.height+box.depth)/factor)
- info("w/h/d of '%s': %s %s 0.0", name, wd, hd)
+ local wd = format("%.3f",box.width/factor) :gsub("%.%d+", rmzeros)
+ local hd = format("%.3f",(box.height+box.depth)/factor) :gsub("%.%d+", rmzeros)
+ info("w/h/d of '%s': %s %s 0", name, wd, hd)
if opts.xstep == 0 then opts.xstep = nil end
if opts.ystep == 0 then opts.ystep = nil end
- if opts.colored == nil then opts.colored = true end
+ if opts.colored == nil then
+ opts.colored = opts.coloured
+ if opts.colored == nil then
+ opts.colored = true
+ end
+ end
if type(opts.matrix) == "table" then opts.matrix = tableconcat(opts.matrix," ") end
if type(opts.bbox) == "table" then opts.bbox = tableconcat(opts.bbox," ") end
if opts.matrix and opts.matrix:find"%a" then
@@ -3021,87 +3342,53 @@ function luamplib.registerpattern ( boxid, name, opts )
"/TilingType 2",
format("/XStep %s", opts.xstep or wd),
format("/YStep %s", opts.ystep or hd),
- format("/Matrix [%s %s %s]", opts.matrix or "1 0 0 1", opts.xshift or 0, opts.yshift or 0),
+ format("/Matrix[%s %s %s]", opts.matrix or "1 0 0 1", opts.xshift or 0, opts.yshift or 0),
}
+ local optres = opts.resources or ""
+ optres = optres .. gather_resources(optres)
+ local patterns = pdfetcs.patterns
if pdfmode then
- local optres, t = opts.resources or "", { }
- if pdfmanagement then
- for _,v in ipairs{"ExtGState","ColorSpace","Shading"} do
- local pp = get_macro(format("g__pdfdict_/g__pdf_Core/Page/Resources/%s_prop",v))
- if pp and pp:find"__prop_pair" then
- t[#t+1] = format("/%s %s", v, ltx.__pdf.object["__pdf/Page/Resources/"..v])
- end
- end
- else
- local res = pdfetcs.getpageres() or ""
- run_tex_code[[\mplibtmptoks\expandafter{\the\pdfvariable pageresources}]]
- res = (res .. texgettoks'mplibtmptoks'):explode()
- res = tableconcat(res," "):explode"/+"
- for _,v in ipairs(res) do
- if not v:find"Pattern" and not optres:find(v) then
- t[#t+1] = "/" .. v
- end
- end
- end
- optres = optres .. tableconcat(t)
if opts.bbox then
- attr[#attr+1] = format("/BBox [%s]", opts.bbox)
+ attr[#attr+1] = format("/BBox[%s]", opts.bbox)
end
local index = tex.saveboxresource(boxid, tableconcat(attr), optres, true, opts.bbox and 4 or 1)
patterns[name] = { id = index, colored = opts.colored }
else
- local objname = "@mplibpattern"..name
+ local cnt = #patterns + 1
+ local objname = "@mplibpattern" .. cnt
local metric = format("bbox %s", opts.bbox or format("0 0 %s %s",wd,hd))
- local optres, t = opts.resources or "", { }
- if pdfmanagement then
- for _,v in ipairs{"ExtGState","ColorSpace","Shading"} do
- run_tex_code(format(
- [[\mplibtmptoks\expanded{{/%s \pdf_object_ref:n{__pdf/Page/Resources/%s}}}]],v,v),ccexplat)
- t[#t+1] = texgettoks'mplibtmptoks'
- end
- elseif is_defined(pdfetcs.pgfextgs) then
- run_tex_code("\\mplibtmptoks\\expanded{{\z
- \\ifpgf@sys@pdf@extgs@exists /ExtGState @pgfextgs\\fi\z
- \\ifpgf@sys@pdf@colorspaces@exists /ColorSpace @pgfcolorspaces\\fi}}",catat11)
- t[#t+1] = texgettoks'mplibtmptoks'
- else
- t[#t+1] = "/ExtGState @MPlibTr/Shading @MPlibSh/ColorSpace @MPlibCS"
- end
- optres = optres .. tableconcat(t)
texsprint {
- [[\ifvmode\nointerlineskip\fi]],
- format([[\hbox to0pt{\vbox to0pt{\hsize=\wd %i\vss\noindent]], boxid), -- force horiz mode?
- [[\special{pdf:bcontent}]],
- [[\special{pdf:bxobj ]], objname, format(" %s}", metric),
- format([[\raise\dp %i\box %i]], boxid, boxid),
- format([[\special{pdf:put @resources <<%s>>}]], optres),
- [[\special{pdf:exobj <<]], tableconcat(attr), ">>}",
- [[\special{pdf:econtent}]],
- [[\par}\hss}]],
+ "\\expandafter\\newbox\\csname luamplib.patternbox.", cnt, "\\endcsname",
+ "\\global\\setbox\\csname luamplib.patternbox.", cnt, "\\endcsname",
+ "\\hbox{\\unhbox ", boxid, "}\\luamplibatnextshipout{",
+ "\\special{pdf:bcontent}",
+ "\\special{pdf:bxobj ", objname, " ", metric, "}",
+ "\\raise\\dp\\csname luamplib.patternbox.", cnt, "\\endcsname",
+ "\\box\\csname luamplib.patternbox.", cnt, "\\endcsname",
+ "\\special{pdf:put @resources <<", optres, ">>}",
+ "\\special{pdf:exobj <<", tableconcat(attr), ">>}",
+ "\\special{pdf:econtent}}",
}
- patterns[#patterns+1] = objname
- patterns[name] = { id = #patterns, colored = opts.colored }
+ patterns[cnt] = objname
+ patterns[name] = { id = cnt, colored = opts.colored }
end
end
local function pattern_colorspace (cs)
local on, new = update_pdfobjs(format("[/Pattern %s]", cs))
if new then
- local key = format("MPlibCS%i",on)
- local val = pdfmode and format("%i 0 R",on) or format("@mplibpdfobj%i",on)
+ local key, val = format("MPlibCS%i",on), format(pdfetcs.resfmt,on)
if pdfmanagement then
- texsprint(ccexplat,format("\\pdfmanagement_add:nnn{Page/Resources/ColorSpace}{%s}{%s}",key,val))
+ texsprint {
+ "\\csname pdfmanagement_add:nnn\\endcsname{Page/Resources/ColorSpace}{", key, "}{", val, "}"
+ }
else
local res = format("/%s %s", key, val)
if is_defined(pdfetcs.pgfcolorspace) then
- texsprint(format("\\csname %s\\endcsname{%s}", pdfetcs.pgfcolorspace, res))
+ texsprint { "\\csname ", pdfetcs.pgfcolorspace, "\\endcsname{", res, "}" }
elseif pdfmode then
- if not pdfetcs.ColorSpace_res then
- pdfetcs.initialize_resources"ColorSpace"
- end
pdfetcs.fallback_update_resources("ColorSpace", res)
else
- texsprint(format("\\special{pdf:put @MPlibCS<<%s>>}", res))
- texsprint"\\special{pdf:put @resources<</ColorSpace @MPlibCS>>}"
+ pdfetcs.fallback_update_resources("ColorSpace","@MPlibCS",res)
end
end
end
@@ -3110,6 +3397,7 @@ end
local function do_preobj_PAT(object, prescript)
local name = prescript and prescript.mplibpattern
if not name then return end
+ local patterns = pdfetcs.patterns
local patt = patterns[name]
local index = patt and patt.id or err("cannot get pattern object '%s'", name)
local key = format("MPlibPt%s",index)
@@ -3139,22 +3427,21 @@ local function do_preobj_PAT(object, prescript)
end
pdf_literalcode("/MPlibCS%i cs %s /%s scn", pattern_colorspace(cs), color, key)
end
- if patt.done then return end
- local val = pdfmode and format("%s 0 R",index) or patterns[index]
- if pdfmanagement then
- texsprint(ccexplat, format("\\pdfmanagement_add:nnn{Page/Resources/Pattern}{%s}{%s}",key,val))
- else
- local res = format("/%s %s", key, val)
- if is_defined(pdfetcs.pgfpattern) then
- texsprint(format("\\csname %s\\endcsname{%s}", pdfetcs.pgfpattern, res))
- elseif pdfmode then
- if not pdfetcs.Pattern_res then
- pdfetcs.initialize_resources"Pattern"
- end
- pdfetcs.fallback_update_resources("Pattern", res)
+ if not patt.done then
+ local val = pdfmode and format("%s 0 R",index) or patterns[index]
+ if pdfmanagement then
+ texsprint {
+ "\\csname pdfmanagement_add:nnn\\endcsname{Page/Resources/Pattern}{", key, "}{", val, "}"
+ }
else
- texsprint(format("\\special{pdf:put @MPlibPt<<%s>>}", res))
- texsprint"\\special{pdf:put @resources<</Pattern @MPlibPt>>}"
+ local res = format("/%s %s", key, val)
+ if is_defined(pdfetcs.pgfpattern) then
+ texsprint { "\\csname ", pdfetcs.pgfpattern, "\\endcsname{", res, "}" }
+ elseif pdfmode then
+ pdfetcs.fallback_update_resources("Pattern", res)
+ else
+ pdfetcs.fallback_update_resources("Pattern","@MPlibPt",res)
+ end
end
end
patt.done = true
@@ -3162,6 +3449,305 @@ end
% \end{macrocode}
%
+% Fading
+% \begin{macrocode}
+pdfetcs.fading = { }
+local function do_preobj_FADE (object, prescript)
+ local fd_type = prescript and prescript.mplibfadetype
+ local fd_stop = prescript and prescript.mplibfadestate
+ if not fd_type then
+ return fd_stop -- returns "stop" (if picture) or nil
+ end
+ local bbox = prescript.mplibfadebbox:explode":"
+ local dx, dy = -bbox[1], -bbox[2]
+ local vec = prescript.mplibfadevector; vec = vec and vec:explode":"
+ if not vec then
+ if fd_type == "linear" then
+ vec = {bbox[1], bbox[2], bbox[3], bbox[2]} -- left to right
+ else
+ local centerx, centery = (bbox[1]+bbox[3])/2, (bbox[2]+bbox[4])/2
+ vec = {centerx, centery, centerx, centery} -- center for both circles
+ end
+ end
+ local coords = { vec[1]+dx, vec[2]+dy, vec[3]+dx, vec[4]+dy }
+ if fd_type == "linear" then
+ coords = format("%f %f %f %f", tableunpack(coords))
+ elseif fd_type == "circular" then
+ local width, height = bbox[3]-bbox[1], bbox[4]-bbox[2]
+ local radius = (prescript.mplibfaderadius or "0:"..math.sqrt(width^2+height^2)/2):explode":"
+ tableinsert(coords, 3, radius[1])
+ tableinsert(coords, radius[2])
+ coords = format("%f %f %f %f %f %f", tableunpack(coords))
+ else
+ err("unknown fading method '%s'", fd_type)
+ end
+ fd_type = fd_type == "linear" and 2 or 3
+ local opaq = (prescript.mplibfadeopacity or "1:0"):explode":"
+ local on, os, new
+ on = sh_pdfpageresources(fd_type, "0 1", "/DeviceGray", {{opaq[1]}}, {{opaq[2]}}, coords, 1)
+ os = format("<</PatternType 2/Shading %s>>", format(pdfetcs.resfmt, on))
+ on = update_pdfobjs(os)
+ bbox = format("0 0 %f %f", bbox[3]+dx, bbox[4]+dy) :gsub("%.%d+", rmzeros)
+ local streamtext = format("q /Pattern cs/MPlibFd%s scn %s re f Q", on, bbox)
+ os = format("<</Pattern<</MPlibFd%s %s>>>>", on, format(pdfetcs.resfmt, on))
+ on = update_pdfobjs(os)
+ local resources = format(pdfetcs.resfmt, on)
+ on = update_pdfobjs"<</S/Transparency/CS/DeviceGray>>"
+ local attr = tableconcat{
+ "/Subtype/Form",
+ format("/BBox[%s]", bbox),
+ format("/Matrix[1 0 0 1 %s]", format("%f %f", -dx,-dy) :gsub("%.%d+", rmzeros)),
+ format("/Resources %s", resources),
+ "/Group ", format(pdfetcs.resfmt, on),
+ }
+ on = update_pdfobjs(attr, streamtext)
+ os = "<</SMask<</S/Luminosity/G " .. format(pdfetcs.resfmt, on) .. ">>>>"
+ on, new = update_pdfobjs(os)
+ local key = add_extgs_resources(on,new)
+ start_pdf_code()
+ pdf_literalcode("/%s gs", key)
+ if fd_stop then return "standalone" end
+ return "start"
+end
+
+% \end{macrocode}
+%
+% Transparency Group
+% \begin{macrocode}
+pdfetcs.tr_group = { shifts = { } }
+luamplib.trgroupshifts = pdfetcs.tr_group.shifts
+local function do_preobj_GRP (object, prescript)
+ local grstate = prescript and prescript.gr_state
+ if not grstate then return end
+ local trgroup = pdfetcs.tr_group
+ if grstate == "start" then
+ trgroup.name = prescript.mplibgroupname or "lastmplibgroup"
+ trgroup.isolated, trgroup.knockout = false, false
+ for _,v in ipairs(prescript.gr_type:explode",+") do
+ trgroup[v] = true
+ end
+ local p = object.path
+ trgroup.bbox = {
+ math.min(p[1].x_coord, p[2].x_coord, p[3].x_coord, p[4].x_coord),
+ math.min(p[1].y_coord, p[2].y_coord, p[3].y_coord, p[4].y_coord),
+ math.max(p[1].x_coord, p[2].x_coord, p[3].x_coord, p[4].x_coord),
+ math.max(p[1].y_coord, p[2].y_coord, p[3].y_coord, p[4].y_coord),
+ }
+ put2output[[\begingroup\setbox\mplibscratchbox\hbox\bgroup]]
+ elseif grstate == "stop" then
+ local llx,lly,urx,ury = tableunpack(trgroup.bbox)
+ put2output(tableconcat{
+ "\\egroup",
+ format("\\wd\\mplibscratchbox %fbp", urx-llx),
+ format("\\ht\\mplibscratchbox %fbp", ury-lly),
+ "\\dp\\mplibscratchbox 0pt",
+ })
+ local grattr = format("/Group<</S/Transparency/I %s/K %s>>",trgroup.isolated,trgroup.knockout)
+ local res = gather_resources()
+ local bbox = format("%f %f %f %f", llx,lly,urx,ury) :gsub("%.%d+", rmzeros)
+ if pdfmode then
+ put2output(tableconcat{
+ "\\saveboxresource type 2 attr{/Type/XObject/Subtype/Form/FormType 1",
+ "/BBox[", bbox, "]", grattr, "} resources{", res, "}\\mplibscratchbox",
+ [[\setbox\mplibscratchbox\hbox{\useboxresource\lastsavedboxresourceindex}]],
+ [[\wd\mplibscratchbox 0pt\ht\mplibscratchbox 0pt\dp\mplibscratchbox 0pt]],
+ [[\box\mplibscratchbox\endgroup]],
+ "\\expandafter\\xdef\\csname luamplib.group.", trgroup.name, "\\endcsname{",
+ "\\noexpand\\mplibstarttoPDF{",llx,"}{",lly,"}{",urx,"}{",ury,"}",
+ "\\useboxresource \\the\\lastsavedboxresourceindex\\noexpand\\mplibstoptoPDF}",
+ })
+ else
+ trgroup.cnt = (trgroup.cnt or 0) + 1
+ local objname = format("@mplibtrgr%s", trgroup.cnt)
+ put2output(tableconcat{
+ "\\special{pdf:bxobj ", objname, " bbox ", bbox, "}",
+ "\\unhbox\\mplibscratchbox",
+ "\\special{pdf:put @resources <<", res, ">>}",
+ "\\special{pdf:exobj <<", grattr, ">>}",
+ "\\special{pdf:uxobj ", objname, "}\\endgroup",
+ })
+ token.set_macro("luamplib.group."..trgroup.name, tableconcat{
+ "\\mplibstarttoPDF{",llx,"}{",lly,"}{",urx,"}{",ury,"}",
+ "\\special{pdf:uxobj ", objname, "}\\mplibstoptoPDF",
+ }, "global")
+ end
+ trgroup.shifts[trgroup.name] = { llx, lly }
+ end
+ return grstate
+end
+function luamplib.registergroup (boxid, name, opts)
+ local box = texgetbox(boxid)
+ local res = (opts.resources or "") .. gather_resources()
+ local attr = { "/Type/XObject/Subtype/Form/FormType 1" }
+ if type(opts.matrix) == "table" then opts.matrix = tableconcat(opts.matrix," ") end
+ if type(opts.bbox) == "table" then opts.bbox = tableconcat(opts.bbox," ") end
+ if opts.matrix and opts.matrix:find"%a" then
+ local data = format("mplibtransformmatrix(%s);",opts.matrix)
+ process(data,"@mplibtransformmatrix")
+ opts.matrix = tableconcat(luamplib.transformmatrix, ' ')
+ end
+ local grtype = 3
+ if opts.bbox then
+ attr[#attr+1] = format("/BBox[%s]", opts.bbox :gsub("%.%d+", rmzeros))
+ grtype = 2
+ end
+ if opts.matrix then
+ attr[#attr+1] = format("/Matrix[%s]", opts.matrix :gsub("%.%d+", rmzeros))
+ grtype = opts.bbox and 4 or 1
+ end
+ if opts.asgroup then
+ local t = { isolated = false, knockout = false }
+ for _,v in ipairs(opts.asgroup:explode",+") do t[v] = true end
+ attr[#attr+1] = format("/Group<</S/Transparency/I %s/K %s>>", t.isolated, t.knockout)
+ end
+ local trgroup = pdfetcs.tr_group
+ trgroup.shifts[name] = { get_macro'MPllx', get_macro'MPlly' }
+ if pdfmode then
+ local index = tex.saveboxresource(boxid, tableconcat(attr), res, true, grtype)
+ token.set_macro("luamplib.group."..name, "\\useboxresource "..index, "global")
+ else
+ trgroup.cnt = (trgroup.cnt or 0) + 1
+ local objname = format("@mplibtrgr%s", trgroup.cnt)
+ local wd, ht, dp = node.getwhd(box)
+ texsprint {
+ "\\expandafter\\newbox\\csname luamplib.groupbox.", trgroup.cnt, "\\endcsname",
+ "\\global\\setbox\\csname luamplib.groupbox.", trgroup.cnt, "\\endcsname",
+ "\\hbox{\\unhbox ", boxid, "}\\luamplibatnextshipout{",
+ "\\special{pdf:bcontent}",
+ "\\special{pdf:bxobj ", objname, " width ", wd, "sp height ", ht, "sp depth ", dp, "sp}",
+ "\\unhbox\\csname luamplib.groupbox.", trgroup.cnt, "\\endcsname",
+ "\\special{pdf:put @resources <<", res, ">>}",
+ "\\special{pdf:exobj <<", tableconcat(attr), ">>}",
+ "\\special{pdf:econtent}}",
+ }
+ token.set_macro("luamplib.group."..name, tableconcat{
+ "\\begingroup\\setbox\\mplibscratchbox\\hbox{\\special{pdf:uxobj ", objname, "}}",
+ "\\wd\\mplibscratchbox ", wd, "sp",
+ "\\ht\\mplibscratchbox ", ht, "sp",
+ "\\dp\\mplibscratchbox ", dp, "sp",
+ "\\box\\mplibscratchbox\\endgroup",
+ }, "global")
+ end
+end
+
+local function stop_special_effects(fade,opaq,over)
+ if fade then -- fading
+ stop_pdf_code()
+ end
+ if opaq then -- opacity
+ pdf_literalcode(opaq)
+ end
+ if over then -- color
+ put2output"\\special{pdf:ec}"
+ end
+end
+
+% \end{macrocode}
+%
+% Codes below for inserting PDF lieterals are mostly from ConTeXt general,
+% with small changes when needed.
+% \begin{macrocode}
+local function getobjects(result,figure,f)
+ return figure:objects()
+end
+
+function luamplib.convert (result, flusher)
+ luamplib.flush(result, flusher)
+ return true -- done
+end
+
+local function pdf_textfigure(font,size,text,width,height,depth)
+ text = text:gsub(".",function(c)
+ return format("\\hbox{\\char%i}",string.byte(c)) -- kerning happens in metapost : false
+ end)
+ put2output("\\mplibtextext{%s}{%f}{%s}{%s}{%s}",font,size,text,0,0)
+end
+
+local bend_tolerance = 131/65536
+
+local rx, sx, sy, ry, tx, ty, divider = 1, 0, 0, 1, 0, 0, 1
+
+local function pen_characteristics(object)
+ local t = mplib.pen_info(object)
+ rx, ry, sx, sy, tx, ty = t.rx, t.ry, t.sx, t.sy, t.tx, t.ty
+ divider = sx*sy - rx*ry
+ return not (sx==1 and rx==0 and ry==0 and sy==1 and tx==0 and ty==0), t.width
+end
+
+local function concat(px, py) -- no tx, ty here
+ return (sy*px-ry*py)/divider,(sx*py-rx*px)/divider
+end
+
+local function curved(ith,pth)
+ local d = pth.left_x - ith.right_x
+ if abs(ith.right_x - ith.x_coord - d) <= bend_tolerance and abs(pth.x_coord - pth.left_x - d) <= bend_tolerance then
+ d = pth.left_y - ith.right_y
+ if abs(ith.right_y - ith.y_coord - d) <= bend_tolerance and abs(pth.y_coord - pth.left_y - d) <= bend_tolerance then
+ return false
+ end
+ end
+ return true
+end
+
+local function flushnormalpath(path,open)
+ local pth, ith
+ for i=1,#path do
+ pth = path[i]
+ if not ith then
+ pdf_literalcode("%f %f m",pth.x_coord,pth.y_coord)
+ elseif curved(ith,pth) then
+ pdf_literalcode("%f %f %f %f %f %f c",ith.right_x,ith.right_y,pth.left_x,pth.left_y,pth.x_coord,pth.y_coord)
+ else
+ pdf_literalcode("%f %f l",pth.x_coord,pth.y_coord)
+ end
+ ith = pth
+ end
+ if not open then
+ local one = path[1]
+ if curved(pth,one) then
+ pdf_literalcode("%f %f %f %f %f %f c",pth.right_x,pth.right_y,one.left_x,one.left_y,one.x_coord,one.y_coord )
+ else
+ pdf_literalcode("%f %f l",one.x_coord,one.y_coord)
+ end
+ elseif #path == 1 then -- special case .. draw point
+ local one = path[1]
+ pdf_literalcode("%f %f l",one.x_coord,one.y_coord)
+ end
+end
+
+local function flushconcatpath(path,open)
+ pdf_literalcode("%f %f %f %f %f %f cm", sx, rx, ry, sy, tx ,ty)
+ local pth, ith
+ for i=1,#path do
+ pth = path[i]
+ if not ith then
+ pdf_literalcode("%f %f m",concat(pth.x_coord,pth.y_coord))
+ elseif curved(ith,pth) then
+ local a, b = concat(ith.right_x,ith.right_y)
+ local c, d = concat(pth.left_x,pth.left_y)
+ pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(pth.x_coord, pth.y_coord))
+ else
+ pdf_literalcode("%f %f l",concat(pth.x_coord, pth.y_coord))
+ end
+ ith = pth
+ end
+ if not open then
+ local one = path[1]
+ if curved(pth,one) then
+ local a, b = concat(pth.right_x,pth.right_y)
+ local c, d = concat(one.left_x,one.left_y)
+ pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(one.x_coord, one.y_coord))
+ else
+ pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord))
+ end
+ elseif #path == 1 then -- special case .. draw point
+ local one = path[1]
+ pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord))
+ end
+end
+
+% \end{macrocode}
+%
% Finally, flush figures by inserting PDF literals.
% \begin{macrocode}
function luamplib.flush (result,flusher)
@@ -3181,11 +3767,11 @@ function luamplib.flush (result,flusher)
% luamplib silently ignores this invalid figure for those
% that do not contain |beginfig ... endfig|. (issue \#70)
% Original code of ConTeXt general was:
-% \begin{verbatim}
+%\begin{verbatim}
% -- invalid
% pdf_startfigure(fignum,0,0,0,0)
% pdf_stopfigure()
-% \end{verbatim}
+%\end{verbatim}
% \begin{macrocode}
else
% \end{macrocode}
@@ -3203,13 +3789,15 @@ function luamplib.flush (result,flusher)
local object = objects[o]
local objecttype = object.type
% \end{macrocode}
-% The following 6 lines are part of |btex...etex| patch.
+% The following 8 lines are part of |btex...etex| patch.
% Again, colors are processed at this stage.
% \begin{macrocode}
local prescript = object.prescript
prescript = prescript and script2table(prescript) -- prescript is now a table
local cr_over = do_preobj_CR(object,prescript) -- color
local tr_opaq = do_preobj_TR(object,prescript) -- opacity
+ local fading_ = do_preobj_FADE(object,prescript) -- fading
+ local trgroup = do_preobj_GRP(object,prescript) -- transparency group
if prescript and prescript.mplibtexboxid then
put_tex_boxes(object,prescript)
elseif objecttype == "start_bounds" or objecttype == "stop_bounds" then --skip
@@ -3235,7 +3823,7 @@ function luamplib.flush (result,flusher)
pdf_literalcode("%f %f %f %f %f %f cm",ot[3],ot[4],ot[5],ot[6],ot[1],ot[2])
pdf_textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth)
stop_pdf_code()
- else
+ elseif not trgroup and fading_ ~= "stop" then
local evenodd, collect, both = false, false, false
local postscript = object.postscript
if not object.istext then
@@ -3261,10 +3849,7 @@ function luamplib.flush (result,flusher)
else
% \end{macrocode}
% Removed from ConTeXt general: color stuff.
-% Added instead : shading stuff
% \begin{macrocode}
- local shade_no = do_preobj_SH(object,prescript) -- shading
- local pattern_ = do_preobj_PAT(object,prescript) -- pattern
local ml = object.miterlimit
if ml and ml ~= miterlimit then
miterlimit = ml
@@ -3291,6 +3876,11 @@ function luamplib.flush (result,flusher)
pdf_literalcode("[] 0 d")
dashed = false
end
+% \end{macrocode}
+% Added : shading and pattern
+% \begin{macrocode}
+ local shade_no = do_preobj_SH(object,prescript) -- shading
+ local pattern_ = do_preobj_PAT(object,prescript) -- pattern
local path = object.path
local transformed, penwidth = false, 1
local open = path and path[1].left_type and path[#path].right_type
@@ -3347,6 +3937,9 @@ function luamplib.flush (result,flusher)
stop_pdf_code()
end
local path = object.htap
+% \end{macrocode}
+% How can we generate an |htap| object? Please let us know if you have succeeded.
+% \begin{macrocode}
if path then
if transformed then
start_pdf_code()
@@ -3380,18 +3973,29 @@ function luamplib.flush (result,flusher)
end
end
% \end{macrocode}
-% Added to ConTeXt general: post-object color and shading stuff.
+% Added to ConTeXt general: post-object colors and shading stuff.
+% We should beware the |q ... Q| scope.
% \begin{macrocode}
if shade_no then -- shading
- pdf_literalcode("W n /MPlibSh%s sh Q",shade_no)
+ pdf_literalcode("W%s n /MPlibSh%s sh Q",evenodd and "*" or "",shade_no)
end
end
end
- if tr_opaq then -- opacity
- stop_pdf_code()
+ if fading_ == "start" then
+ pdfetcs.fading.specialeffects = {fading_, tr_opaq, cr_over}
+ elseif trgroup == "start" then
+ pdfetcs.tr_group.specialeffects = {fading_, tr_opaq, cr_over}
+ elseif fading_ == "stop" then
+ local se = pdfetcs.fading.specialeffects
+ if se then stop_special_effects(se[1], se[2], se[3]) end
+ elseif trgroup == "stop" then
+ local se = pdfetcs.tr_group.specialeffects
+ if se then stop_special_effects(se[1], se[2], se[3]) end
+ else
+ stop_special_effects(fading_, tr_opaq, cr_over)
end
- if cr_over then -- color
- put2output"\\special{pdf:ec}"
+ if fading_ or trgroup then -- extgs resetted
+ miterlimit, linecap, linejoin, dashed = -1, -1, -1, false
end
end
end
@@ -3444,15 +4048,34 @@ end
% First we need to load some packages.
%
% \begin{macrocode}
-\bgroup\expandafter\expandafter\expandafter\egroup
-\expandafter\ifx\csname selectfont\endcsname\relax
- \input ltluatex
-\else
+\ifcsname ProvidesPackage\endcsname
+% \end{macrocode}
+% We need \LaTeX\ 2024-06-01 as we use |ltx.pdf.object_id| when pdfmanagement is loaded.
+% But as \pkg{fp} package does not accept an option, we do not append the date option.
+% \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{luamplib}
- [2024/06/14 v2.32.2 mplib package for LuaTeX]
- \ifx\newluafunction\@undefined
+ [2024/07/27 v2.34.3 mplib package for LuaTeX]
+\fi
+\ifdefined\newluafunction\else
\input ltluatex
+\fi
+% \end{macrocode}
+%
+% In DVI mode, a new XObject (mppattern, mplibgroup) must be encapsulated in an \cs{hbox}.
+% But this should not affect typesetting. So we use Hook mechanism provided by \LaTeX\ kernel.
+% In Plain, \pkg{atbegshi.sty} is loaded.
+% \begin{macrocode}
+\ifnum\outputmode=0
+ \ifdefined\AddToHookNext
+ \def\luamplibatnextshipout{\AddToHookNext{shipout/background}}
+ \def\luamplibatfirstshipout{\AddToHook{shipout/firstpage}}
+ \def\luamplibateveryshipout{\AddToHook{shipout/background}}
+ \else
+ \input atbegshi.sty
+ \def\luamplibatnextshipout#1{\AtBeginShipoutNext{\AtBeginShipoutAddToBox{#1}}}
+ \let\luamplibatfirstshipout\AtBeginShipoutFirst
+ \def\luamplibateveryshipout#1{\AtBeginShipout{\AtBeginShipoutAddToBox{#1}}}
\fi
\fi
% \end{macrocode}
@@ -3472,7 +4095,7 @@ end
\fi
% \end{macrocode}
%
-% Set the format for metapost.
+% Set the format for \metapost.
% \begin{macrocode}
\def\mplibsetformat#1{\directlua{luamplib.setformat("#1")}}
% \end{macrocode}
@@ -3514,6 +4137,39 @@ end
\def\mplibputtextbox#1{\vbox to 0pt{\vss\hbox to 0pt{\raise\dp#1\copy#1\hss}}}
% \end{macrocode}
%
+% use Transparency Group
+% \begin{macrocode}
+\protected\def\usemplibgroup#1{\csname luamplib.group.#1\endcsname}
+\protected\def\mplibgroup#1{%
+ \begingroup
+ \def\MPllx{0}\def\MPlly{0}%
+ \def\mplibgroupname{#1}%
+ \mplibgroupgetnexttok
+}
+\def\mplibgroupgetnexttok{\futurelet\nexttok\mplibgroupbranch}
+\def\mplibgroupskipspace{\afterassignment\mplibgroupgetnexttok\let\nexttok= }
+\def\mplibgroupbranch{%
+ \ifx [\nexttok
+ \expandafter\mplibgroupopts
+ \else
+ \ifx\mplibsptoken\nexttok
+ \expandafter\expandafter\expandafter\mplibgroupskipspace
+ \else
+ \let\mplibgroupoptions\empty
+ \expandafter\expandafter\expandafter\mplibgroupmain
+ \fi
+ \fi
+}
+\def\mplibgroupopts[#1]{\def\mplibgroupoptions{#1}\mplibgroupmain}
+\def\mplibgroupmain{\setbox\mplibscratchbox\hbox\bgroup\ignorespaces}
+\protected\def\endmplibgroup{\egroup
+ \directlua{ luamplib.registergroup(
+ \the\mplibscratchbox, '\mplibgroupname', {\mplibgroupoptions}
+ )}%
+ \endgroup
+}
+% \end{macrocode}
+%
% Patterns
% \begin{macrocode}
{\def\:{\global\let\mplibsptoken= } \: }
@@ -3552,7 +4208,7 @@ end
}
% \end{macrocode}
%
-% simple way to use mplib:
+% simple way to use \mplib:
% |\mpfig draw fullcircle scaled 10; \endmpfig|
% \begin{macrocode}
\def\mpfiginstancename{@mpfig}
@@ -3575,16 +4231,16 @@ end
\long\def\mplibdomainmpfig#1\endmpfig{%
\endgroup
\directlua{
- local legacy = luamplib.legacy_verbatimtex
+ local legacy = luamplib.legacyverbatimtex
local everympfig = luamplib.everymplib["\mpfiginstancename"] or ""
local everyendmpfig = luamplib.everyendmplib["\mpfiginstancename"] or ""
- luamplib.legacy_verbatimtex = false
+ luamplib.legacyverbatimtex = false
luamplib.everymplib["\mpfiginstancename"] = ""
luamplib.everyendmplib["\mpfiginstancename"] = ""
luamplib.process_mplibcode(
"beginfig(0) "..everympfig.." "..[===[\unexpanded{#1}]===].." "..everyendmpfig.." endfig;",
"\mpfiginstancename")
- luamplib.legacy_verbatimtex = legacy
+ luamplib.legacyverbatimtex = legacy
luamplib.everymplib["\mpfiginstancename"] = everympfig
luamplib.everyendmplib["\mpfiginstancename"] = everyendmpfig
}%
@@ -3598,14 +4254,14 @@ end
\long\def\mplibdoprempfig#1\endmpfig{%
\endgroup
\directlua{
- local legacy = luamplib.legacy_verbatimtex
+ local legacy = luamplib.legacyverbatimtex
local everympfig = luamplib.everymplib["\mpfiginstancename"]
local everyendmpfig = luamplib.everyendmplib["\mpfiginstancename"]
- luamplib.legacy_verbatimtex = false
+ luamplib.legacyverbatimtex = false
luamplib.everymplib["\mpfiginstancename"] = ""
luamplib.everyendmplib["\mpfiginstancename"] = ""
luamplib.process_mplibcode([===[\unexpanded{#1}]===],"\mpfiginstancename")
- luamplib.legacy_verbatimtex = legacy
+ luamplib.legacyverbatimtex = legacy
luamplib.everymplib["\mpfiginstancename"] = everympfig
luamplib.everyendmplib["\mpfiginstancename"] = everyendmpfig
}%
@@ -3684,9 +4340,9 @@ end
\def\mpliblegacybehavior#1{\directlua{
local s = string.lower("#1")
if s == "enable" or s == "true" or s == "yes" then
- luamplib.legacy_verbatimtex = true
+ luamplib.legacyverbatimtex = true
else
- luamplib.legacy_verbatimtex = false
+ luamplib.legacyverbatimtex = false
end
}}
\def\mplibverbatim#1{\directlua{
@@ -3758,14 +4414,13 @@ end
%
% Allow \TeX\ dimen/color macros. Now |runscript| does the job,
% so the following lines are not needed for most cases.
-% But the macros will be expanded when they are used in another macro.
% \begin{macrocode}
\def\mpdim#1{ runscript("luamplibdimen{#1}") }
\def\mpcolor#1#{\domplibcolor{#1}}
\def\domplibcolor#1#2{ runscript("luamplibcolor{#1{#2}}") }
% \end{macrocode}
%
-% MPLib's number system. Now |binary| has gone away.
+% \mplib's number system. Now |binary| has gone away.
% \begin{macrocode}
\def\mplibnumbersystem#1{\directlua{
local t = "#1"
@@ -3830,12 +4485,13 @@ end
% \end{macrocode}
%
% The followings are from ConTeXt general, mostly.
-% % We use a dedicated scratchbox.
+%
+% We use a dedicated scratchbox.
% \begin{macrocode}
\ifx\mplibscratchbox\undefined \newbox\mplibscratchbox \fi
% \end{macrocode}
%
-% We encapsulate the litterals.
+% We encapsulate the literals.
% \begin{macrocode}
\def\mplibstarttoPDF#1#2#3#4{%
\prependtomplibbox
diff --git a/macros/luatex/generic/luamplib/luamplib.pdf b/macros/luatex/generic/luamplib/luamplib.pdf
index 407daa8245..448c237835 100644
--- a/macros/luatex/generic/luamplib/luamplib.pdf
+++ b/macros/luatex/generic/luamplib/luamplib.pdf
Binary files differ
diff --git a/macros/luatex/generic/luamplib/test-luamplib-latex.tex b/macros/luatex/generic/luamplib/test-luamplib-latex.tex
index c2d8cb498b..22b30b0760 100644
--- a/macros/luatex/generic/luamplib/test-luamplib-latex.tex
+++ b/macros/luatex/generic/luamplib/test-luamplib-latex.tex
@@ -7,7 +7,7 @@
\usepackage{fontspec}
\setmainfont{latin modern roman}
\usepackage{luamplib}
-\usepackage{xcolor}
+\usepackage{graphicx,xcolor}
\everymplib{ beginfig(0); }
\everyendmplib{ endfig; }
\mpliblegacybehavior{true}%
@@ -246,19 +246,19 @@ draw mpliboutlinetext.b ("$\displaystyle\frac{1}{1-x^2}$")
\endmpfig
\par\leavevmode
\mppattern{mypatt}
- \mpfig
- picture q;
- q := btex Q etex;
- fill bbox q withcolor .8[red,white];
- draw q withcolor .8red;
- \endmpfig
+[
+ xstep = 5, ystep = 6,
+% matrix = "rotated 30",
+]
+\mpfig
+draw (llcorner unitsquare--urcorner unitsquare) scaled 5 withcolor 1/3[blue,white] ;
+draw (ulcorner unitsquare--lrcorner unitsquare) scaled 5 withcolor 1/3[red,white] ;
+\endmpfig
\endmppattern
\mpfig
- fill fullcircle scaled 100 withpostscript "collect";
- draw unitsquare shifted - center unitsquare scaled 45
- withpattern "mypatt"
- withpostscript "evenodd"
- ;
+draw unitsquare shifted -center unitsquare scaled 45 withpostscript "collect" ;
+draw fullcircle scaled 100 withpattern "mypatt" withpen pencircle scaled 1
+ withcolor \mpcolor{red!50!blue!50} withpostscript "evenodd" ;
\endmpfig
\begin{mppattern}{pattuncolored}
[
@@ -268,19 +268,75 @@ draw mpliboutlinetext.b ("$\displaystyle\frac{1}{1-x^2}$")
\tiny\TeX
\end{mppattern}\relax
\mpfig
- picture tex; tex := mpliboutlinetext.p ("\bfseries \TeX");
- i:=0;
- for item within tex:
- i:=i+1;
- if i < length tex:
- fill pathpart item scaled 10 withpostscript "collect";
- else:
- draw pathpart item scaled 10 withpattern "pattuncolored"
- withpen pencircle scaled 1/2
- withcolor 0.7 blue;
- fi
+ picture tex;
+ tex = mpliboutlinetext.p ("\bfseries \TeX");
+ for i=1 upto mpliboutlinenum:
+ draw image(
+ j:=0;
+ for item within mpliboutlinepic[i]:
+ j:=j+1;
+ draw pathpart item scaled 10
+ if j < length mpliboutlinepic[i]:
+ withpostscript "collect"
+ else:
+ withpattern "pattuncolored"
+ withpen pencircle scaled 1/2
+ withcolor (i/4)[red,blue]
+ fi;
+ endfor
+ )
+ withfademethod "linear"
+ ;
endfor
\endmpfig
+\par\leavevmode
+\mpfig
+ picture mill; mill = btex \includegraphics[width=100bp]{mill} etex;
+ draw mill;
+ mill := mill shifted 125right;
+ draw mill
+ withfademethod "circular"
+ withfadecenter (center mill, center mill)
+ withfaderadius (30, abs(lrcorner mill - llcorner mill)/2)
+ withfadeopacity (1, 0)
+ ;
+\endmpfig
+\par
+\def\test#1{%
+ \mpfig
+ fill unitsquare shifted -center unitsquare scaled 200
+ withshademethod "linear"
+ withshadecolors (.3[red,white], .3[blue,white])
+ ;
+ label( btex MetaPost etex scaled 3, origin) ;
+ draw image(
+ fill fullcircle scaled 100 shifted 25left
+ withcolor .8white
+ withtransparency (2,1)
+ ;
+ fill fullcircle scaled 100 shifted 25right
+ withcolor .8white
+ withtransparency (2,1)
+ ;
+ )
+ asgroup "#1"
+ withgroupname "test:#1"
+ withtransparency (1,.5)
+ ;
+ currentpicture := currentpicture scaled 2/3;
+ \endmpfig
+}%
+\hbox{\test{isolated,knockout}\,\test{isolated}\vbox to\MPheight{\vss\hbox{~isolated}\vss}}%
+\hbox{\test{knockout}\,\test{}}%
+\hbox to\MPwidth{\hss knockout\hss}%
+\leavevmode
+\mpfig usemplibgroup "test:isolated,knockout" scaled 2/3 rotated 15 ; \endmpfig
+\usemplibgroup{test:isolated,knockout}%
+\begin{mplibgroup}{mytex}[matrix="rotated 15"] \TeX \end{mplibgroup}%
+\hbox to0pt{\hss\vrule width.5pt height5pt depth5pt\hss}%
+\hbox to0pt{\hss\vrule width10pt height.25pt depth.25pt\hss}%
+\usemplibgroup{mytex}%
+\mpfig usemplibgroup "mytex"; draw (left--right) scaled 5; draw (up--down) scaled 5; \endmpfig
\tracingcommands0
\vskip 2\baselineskip
diff --git a/macros/luatex/generic/luamplib/test-luamplib-plain.tex b/macros/luatex/generic/luamplib/test-luamplib-plain.tex
index c178acb31a..0804ca5a9b 100644
--- a/macros/luatex/generic/luamplib/test-luamplib-plain.tex
+++ b/macros/luatex/generic/luamplib/test-luamplib-plain.tex
@@ -261,19 +261,57 @@ draw mpliboutlinetext.b ("$\overbrace{x+\cdots+x}^k$")
\fiverm\TeX
\endmppattern
\mpfig
- picture tex; tex := mpliboutlinetext.p ("\bf \TeX");
- i:=0;
- for item within tex:
- i:=i+1;
- if i < length tex:
- fill pathpart item scaled 10 withpostscript "collect";
- else:
- draw pathpart item scaled 10 withpattern "pattuncolored"
- withpen pencircle scaled 1/2
- withcolor 0.7 blue;
- fi
+ picture tex;
+ tex = mpliboutlinetext.p ("\bf \TeX");
+ draw image(
+ for i=1 upto mpliboutlinenum:
+ j:=0;
+ for item within mpliboutlinepic[i]:
+ j:=j+1;
+ draw pathpart item scaled 10
+ if j < length mpliboutlinepic[i]:
+ withpostscript "collect"
+ else:
+ withpattern "pattuncolored"
+ withpen pencircle scaled 1/2
+ withcolor (i/4)[red,blue]
+ fi;
+ endfor
endfor
+ )
+ withfademethod "linear"
+ ;
+\endmpfig
+\par\leavevmode
+\mpfig
+fill fullcircle scaled 125 withcolor 2/3[blue,white];
+fill fullcircle scaled 80 withcolor 2/3[red,white];
+draw image(
+ draw (left--right) rotated 45 scaled 50
+ withpen pencircle scaled 20
+ ;
+ draw (left--right) rotated -45 scaled 50
+ withpen pencircle scaled 20
+ ;
+ )
+ asgroup ""
+ withgroupname "testTRgroup"
+ withprescript "tr_transparency=.3"
+ ;
+\endmpfig
+\mpfig
+fill fullcircle scaled 125 withcolor 2/3[red,white];
+fill fullcircle scaled 80 withcolor 2/3[blue,white];
+usemplibgroup "testTRgroup"
+ withfademethod "circular"
+ withfaderadius (0,60)
+ ;
\endmpfig
+\mplibgroup{mytex}[matrix="rotated 15"] \TeX \endmplibgroup
+\hbox to0pt{\hss\vrule width.5pt height5pt depth5pt\hss}%
+\hbox to0pt{\hss\vrule width10pt height.25pt depth.25pt\hss}%
+\usemplibgroup{mytex}%
+\mpfig usemplibgroup "mytex"; draw (left--right) scaled 5; draw (up--down) scaled 5; \endmpfig
\tracingcommands0
\vskip 2\baselineskip
diff --git a/macros/luatex/generic/luatexja/README b/macros/luatex/generic/luatexja/README
index 9224c83b0b..0bc40ac643 100644
--- a/macros/luatex/generic/luatexja/README
+++ b/macros/luatex/generic/luatexja/README
@@ -1,4 +1,4 @@
-The LuaTeX-ja Package 20240514.0
+The LuaTeX-ja Package 20240714.0
--------------------------------
Copyright (c) 2011--2024 The LuaTeX-ja project
License: modified BSD (see COPYING)
@@ -42,7 +42,7 @@ Installation
2. If you must/want to install manually:
a. Download the source archive from CTAN,
- or tagged as 20240514.0 in the Git repository by
+ or tagged as 20240714.0 in the Git repository by
<https://github.com/luatexja/luatexja/archive/refs/tags/$VER.zip>
b. Extract the archive and process following three files by LuaLaTeX
@@ -92,4 +92,4 @@ Notes
This file and ltj-kinsoku.lua are not used anymore.
(Do not remove ltj-kinsoku.tex.)
-Last commit date: Tue May 14 19:12:05 2024 +0900
+Last commit date: Sun Jul 14 08:56:04 2024 +0900
diff --git a/macros/luatex/generic/luatexja/doc/luatexja-en.pdf b/macros/luatex/generic/luatexja/doc/luatexja-en.pdf
index de28e1d279..eac7af315d 100644
--- a/macros/luatex/generic/luatexja/doc/luatexja-en.pdf
+++ b/macros/luatex/generic/luatexja/doc/luatexja-en.pdf
Binary files differ
diff --git a/macros/luatex/generic/luatexja/doc/luatexja-ja.pdf b/macros/luatex/generic/luatexja/doc/luatexja-ja.pdf
index 49a8a6feef..ee55789a60 100644
--- a/macros/luatex/generic/luatexja/doc/luatexja-ja.pdf
+++ b/macros/luatex/generic/luatexja/doc/luatexja-ja.pdf
Binary files differ
diff --git a/macros/luatex/generic/luatexja/doc/luatexja.dtx b/macros/luatex/generic/luatexja/doc/luatexja.dtx
index b550dc58d4..9ad5209465 100644
--- a/macros/luatex/generic/luatexja/doc/luatexja.dtx
+++ b/macros/luatex/generic/luatexja/doc/luatexja.dtx
@@ -1467,14 +1467,19 @@ Alphabetic fonts
&\cs{fontspec}&\cs{setmainfont}&\cs{setsansfont}&\cs{setmonofont}\\
\midrule
Japanese fonts
-&\cs{newjfontfamily}&\cs{renewjfontfamily}&\cs{setjfontfamily}\\
+&\cs{newjfontfamily}&\cs{renewjfontfamily}&\cs{setjfontfamily}&\cs{providejfontfamily}\\
Alphabetic fonts
-&\cs{newfontfamily}&\cs{renewfontfamily}&\cs{setfontfamily}\\
+&\cs{newfontfamily}&\cs{renewfontfamily}&\cs{setfontfamily}&\cs{providefontfamily}\\
\midrule
Japanese fonts
-&\cs{newjfontface}&\cs{defaultjfontfeatures}&\cs{addjfontfeatures}\\
+&\cs{newjfontface}&\cs{renewjfontface}&\cs{setjfontface}&\cs{providejfontface}\\
Alphabetic fonts
-&\cs{newfontface}&\cs{defaultfontfeatures}&\cs{addfontfeatures}\\
+&\cs{newfontface}&\cs{renewfontface}&\cs{setfontface}&\cs{providefontface}\\
+\midrule
+Japanese fonts
+&\cs{defaultjfontfeatures}&\cs{addjfontfeatures}\\
+Alphabetic fonts
+&\cs{defaultfontfeatures}&\cs{addfontfeatures}\\
\bottomrule
\end{tabular}\par}
\end{table}
@@ -1492,14 +1497,19 @@ Alphabetic fonts
&\cs{fontspec}&\cs{setmainfont}&\cs{setsansfont}&\cs{setmonofont}\\
\midrule
\emph{和文}
-&\cs{newjfontfamily}&\cs{renewjfontfamily}&\cs{setjfontfamily}\\
+&\cs{newjfontfamily}&\cs{renewjfontfamily}&\cs{setjfontfamily}&\cs{providejfontfamily}\\
+\emph{欧文}
+&\cs{newfontfamily}&\cs{renewfontfamily}&\cs{setfontfamily}&\cs{providefontfamily}\\
+\midrule
+\emph{和文}
+&\cs{newjfontface}&\cs{renewjfontface}&\cs{setjfontface}&\cs{providejfontface}\\
\emph{欧文}
-&\cs{newfontfamily}&\cs{renewfontfamily}&\cs{setfontfamily}\\
+&\cs{newfontface}&\cs{renewfontface}&\cs{setfontface}&\cs{providefontface}\\
\midrule
\emph{和文}
-&\cs{newjfontface}&\cs{defaultjfontfeatures}&\cs{addjfontfeatures}\\
+&\cs{defaultjfontfeatures}&\cs{addjfontfeatures}\\
\emph{欧文}
-&\cs{newfontface}&\cs{defaultfontfeatures}&\cs{addfontfeatures}\\
+&\cs{defaultfontfeatures}&\cs{addfontfeatures}\\
\bottomrule
\end{tabular}\par}
\end{table}
@@ -7833,7 +7843,7 @@ stretch_priority={kanjiskip=-35,xkanjiskip=-25,others=50}
さらに,バージョン20220211.0以降では次の命令が提供される.
\begin{cslist}
- \item[\cs{ltjghostbeginjachar}]
+ \item[\cs{ltjghostbeforejachar}]
\LuaTeX-ja本体が提供している\cs{ltjfakeparbegin}, \cs{ltjfakeboxbdd}と類似の命令である.
実行された箇所が(限定・非限定を問わず)水平モードであった場合に,実行された箇所は
「文字クラス0の\textbf{JAchar}」の直前であると,
@@ -7850,7 +7860,7 @@ A\LG 字 \par% ==> ALchar--(xkanjiskip)--\LG
\end{LTXexample}
\item[\cs{ltjghostafterjachar}]
- \cs{ltjghostbeginjachar}と対を成す命令で,実行された箇所は
+ \cs{ltjghostbeforejachar}と対を成す命令で,実行された箇所は
「文字クラス0の\textbf{JAchar}」の直後であると,
\LuaTeX-jaの和文処理グルー挿入処理に認識させる.以下の実行例を参照.
diff --git a/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-27c.sty b/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-27c.sty
index 76ebf8716c..6ef3ff1751 100644
--- a/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-27c.sty
+++ b/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-27c.sty
@@ -3,7 +3,7 @@
%
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{luatexja-fontspec-27c}[2024-02-19 fontspec support of LuaTeX-ja]
+\ProvidesPackage{luatexja-fontspec-27c}[2024-05-27 fontspec support of LuaTeX-ja]
\RequirePackage{l3keys2e}
\ExplSyntaxOn
@@ -359,10 +359,24 @@
\setfontfamily #1 [#2,#4] {#3}
\cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_orig_fontspec_set_family:Nnn
}
+\DeclareDocumentCommand \providejfontfamily { m O{} m O{} } {
+ \cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_fontspec_set_family:Nnn
+ \providefontfamily #1 [#2,#4] {#3}
+ \cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_orig_fontspec_set_family:Nnn
+}
\DeclareDocumentCommand \newjfontface { m O{} m O{} } {
\newjfontfamily #1 [ BoldFont={},ItalicFont={},SmallCapsFont={},#2,#4 ] {#3}
}
+\DeclareDocumentCommand \renewjfontface { m O{} m O{} } {
+ \renewjfontfamily #1 [ BoldFont={},ItalicFont={},SmallCapsFont={},#2,#4 ] {#3}
+}
+\DeclareDocumentCommand \setjfontface { m O{} m O{} } {
+ \setjfontfamily #1 [ BoldFont={},ItalicFont={},SmallCapsFont={},#2,#4 ] {#3}
+}
+\DeclareDocumentCommand \providejfontface { m O{} m O{} } {
+ \providejfontfamily #1 [ BoldFont={},ItalicFont={},SmallCapsFont={},#2,#4 ] {#3}
+}
\prop_new:N \l__ltj_fontspec_tmp_prop
\prop_new:N \g__ltj_fontspec_fontopts_prop
diff --git a/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-29c.sty b/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-29c.sty
index 1415cee127..51af33447c 100644
--- a/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-29c.sty
+++ b/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-29c.sty
@@ -3,7 +3,7 @@
%
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{luatexja-fontspec-29c}[2024-05-05 fontspec support of LuaTeX-ja]
+\ProvidesPackage{luatexja-fontspec-29c}[2024-05-27 fontspec support of LuaTeX-ja]
\RequirePackage{l3keys2e}
\ExplSyntaxOn
@@ -359,10 +359,24 @@
\setfontfamily #1 [#2,#4] {#3}
\cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_orig_fontspec_set_family:Nnn
}
+\DeclareDocumentCommand \providejfontfamily { m O{} m O{} } {
+ \cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_fontspec_set_family:Nnn
+ \providefontfamily #1 [#2,#4] {#3}
+ \cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_orig_fontspec_set_family:Nnn
+}
\DeclareDocumentCommand \newjfontface { m O{} m O{} } {
\newjfontfamily #1 [ BoldFont={},ItalicFont={},SmallCapsFont={},#2,#4 ] {#3}
}
+\DeclareDocumentCommand \renewjfontface { m O{} m O{} } {
+ \renewjfontfamily #1 [ BoldFont={},ItalicFont={},SmallCapsFont={},#2,#4 ] {#3}
+}
+\DeclareDocumentCommand \setjfontface { m O{} m O{} } {
+ \setjfontfamily #1 [ BoldFont={},ItalicFont={},SmallCapsFont={},#2,#4 ] {#3}
+}
+\DeclareDocumentCommand \providejfontface { m O{} m O{} } {
+ \providejfontfamily #1 [ BoldFont={},ItalicFont={},SmallCapsFont={},#2,#4 ] {#3}
+}
\prop_new:N \l__ltj_fontspec_tmp_prop
\prop_new:N \g__ltj_fontspec_fontopts_prop
diff --git a/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-29e.sty b/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-29e.sty
index e763d91ad7..02a79ad6ca 100644
--- a/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-29e.sty
+++ b/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-29e.sty
@@ -3,7 +3,7 @@
%
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{luatexja-fontspec-29e}[2024-05-14 fontspec support of LuaTeX-ja]
+\ProvidesPackage{luatexja-fontspec-29e}[2024-05-27 fontspec support of LuaTeX-ja]
\RequirePackage{l3keys2e}
\ExplSyntaxOn
@@ -359,10 +359,24 @@
\setfontfamily #1 [#2,#4] {#3}
\cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_orig_fontspec_set_family:Nnn
}
+\DeclareDocumentCommand \providejfontfamily { m O{} m O{} } {
+ \cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_fontspec_set_family:Nnn
+ \providefontfamily #1 [#2,#4] {#3}
+ \cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_orig_fontspec_set_family:Nnn
+}
\DeclareDocumentCommand \newjfontface { m O{} m O{} } {
\newjfontfamily #1 [ BoldFont={},ItalicFont={},SmallCapsFont={},#2,#4 ] {#3}
}
+\DeclareDocumentCommand \renewjfontface { m O{} m O{} } {
+ \renewjfontfamily #1 [ BoldFont={},ItalicFont={},SmallCapsFont={},#2,#4 ] {#3}
+}
+\DeclareDocumentCommand \setjfontface { m O{} m O{} } {
+ \setjfontfamily #1 [ BoldFont={},ItalicFont={},SmallCapsFont={},#2,#4 ] {#3}
+}
+\DeclareDocumentCommand \providejfontface { m O{} m O{} } {
+ \providejfontfamily #1 [ BoldFont={},ItalicFont={},SmallCapsFont={},#2,#4 ] {#3}
+}
\prop_new:N \l__ltj_fontspec_tmp_prop
\prop_new:N \g__ltj_fontspec_fontopts_prop
diff --git a/macros/luatex/generic/luatexja/src/lltjext.sty b/macros/luatex/generic/luatexja/src/lltjext.sty
index a83c9305c9..69e709f02e 100644
--- a/macros/luatex/generic/luatexja/src/lltjext.sty
+++ b/macros/luatex/generic/luatexja/src/lltjext.sty
@@ -3,7 +3,7 @@
%
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{lltjext}[2022-08-24 v1.2k-ltj-14 Macros for vertical writing]
+\ProvidesPackage{lltjext}[2024-05-16 v1.2k-ltj-15 Macros for vertical writing]
\RequirePackage{luatexja}
\newcount\ltj@ext@dir
\let\ltj@lltjext@orig@tabular=\tabular
@@ -541,17 +541,11 @@
\else \let\box@dir\utod
\fi
\fi
-\ifltj@ltfilehook@avail % LaTeX2e >= 2020-10-01
\@defaultunitsset\@picht{#3}\unitlength
\@defaultunitsset\@picwd{#2}\unitlength
\setbox\@picbox\hbox to\@picwd\bgroup\box@dir
\@defaultunitsset\@tempdimc{#4}\unitlength\hskip-\@tempdimc
\@defaultunitsset\@tempdimc{#5}\unitlength\lower\@tempdimc\hbox\bgroup
-\else % <= 2020-02-02
- \@picwd=#2\unitlength \@picht=#3\unitlength
- \setbox\@picbox\hbox to\@picwd\bgroup\box@dir
- \hskip-#4\unitlength\lower#5\unitlength\hbox\bgroup
-\fi
\ltj@@pic@reset@blshift
\ignorespaces}
\def\endpicture{%
diff --git a/macros/luatex/generic/luatexja/src/ltj-latex.sty b/macros/luatex/generic/luatexja/src/ltj-latex.sty
index 7e091d161d..9f6e4d0a36 100644
--- a/macros/luatex/generic/luatexja/src/ltj-latex.sty
+++ b/macros/luatex/generic/luatexja/src/ltj-latex.sty
@@ -12,45 +12,14 @@
\def\luatexjalatexLoaded{\endinput}
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{ltj-latex}[2022-10-15 LaTeX support of LuaTeX-ja]
+\ProvidesPackage{ltj-latex}[2024-05-16 LaTeX support of LuaTeX-ja]
\endlinechar=13
%%% LaTeX version detection
-\newif\ifltj@ltfilehook@avail
-\@ifl@t@r\fmtversion{2020-10-01}{%
- \@ifl@t@r\fmtversion{2020-10-02}%
- {\ltj@ltfilehook@availtrue}
- {%
- \ifnum\patch@level<0\relax \ifnum\patch@level<-6 \ltj@ltfilehook@availtrue\fi
- \else\ltj@ltfilehook@availtrue\fi
- }%
-}{}
-\@ifl@t@r\fmtversion{2021-05-01}{\count@=1 }{\count@=0 }
-\ifnum \count@<1
-%%%% \shipout
- \newluafunction\ltj@@lua@shipout@inner
- \directlua{
- local t = lua.get_functions_table()
- local getbox, setbox = tex.getbox, tex.setbox
- local shipout_lthook = luatexja.direction.shipout_lthook
- t[\the\ltj@@lua@shipout@inner]=function ()
- local a = shipout_lthook(getbox(\the\ltj@afbox))
- if a then setbox(\the\ltj@afbox, a) end
- end
- }
- \protected\luadef\ltj@@lua@shipout\ltj@@lua@shipout@inner
- \def\ltj@shipout@{\ltj@@lua@shipout\primitive\shipout\box\ltj@afbox}%
- \protected\def\ltj@shipout{\ltj@afterbox\ltj@shipout@}
- \ifprimitive\shipout\let\shipout\ltj@shipout\fi
- \ifcsname tex_shipout:D\endcsname
- \expandafter\let\csname tex_shipout:D\endcsname\ltj@shipout
- \fi
-\else
- \directlua{%
- luatexbase.add_to_callback('pre_shipout_filter',luatexja.direction.shipout_lthook, 'ltj.direction', 1)
- }
-\fi
+\directlua{%
+ luatexbase.add_to_callback('pre_shipout_filter',luatexja.direction.shipout_lthook, 'ltj.direction', 1)
+}
%%% patch for LaTeX
\usepackage{lltjfont}
@@ -59,36 +28,30 @@
\RequirePackage{lltjp-atbegshi}
%%% patching commands
-\ifltj@ltfilehook@avail
- %% \ltj@ExecuteBeforePackage <package><code> and \ltj@ExecuteAfterPackage <package><code>
- %% no-starred version: do nothing if the <package> is loaded
- %% starred version: do <code> right away if the <package> is loaded
- \def\ltj@ExecuteAfterPackage{\@ifstar\@@ltj@ExecuteAfterPackage@star\@@ltj@ExecuteAfterPackage}
- \def\ltj@ExecuteBeforePackage{\@ifstar\@@ltj@ExecuteBeforePackage@star\@@ltj@ExecuteBeforePackage}
- \@ifl@t@r\fmtversion{2021-11-15}{% 2021-11-15
- \def\@@ltj@ExecuteAfterPackage@star#1{\AddToHook{package/#1/after}}
- \def\@@ltj@ExecuteBeforePackage@star#1{\AddToHook{package/#1/before}}
- \long\def\@@ltj@ExecuteAfterPackage#1#2{%
- \@ifpackageloaded{#1}{}{\AddToHook{package/#1/after}{#2}}%
- }
- \long\def\@@ltj@ExecuteBeforePackage#1#2{%
- \@ifpackageloaded{#1}{}{\AddToHook{package/#1/before}{#2}}%
- }
- }{
- \def\@@ltj@ExecuteAfterPackage#1{\AddToHook{package/after/#1}}
- \def\@@ltj@ExecuteBeforePackage#1{\AddToHook{package/before/#1}}
- \long\def\@@ltj@ExecuteAfterPackage@star#1#2{%
- \@ifpackageloaded{#1}{#2}{\@@ltj@ExecuteAfterPackage{#1}{#2}}%
- }
- \long\def\@@ltj@ExecuteBeforePackage@star#1#2{%
- \@ifpackageloaded{#1}{#2}{\@@ltj@ExecuteBeforePackage{#1}{#2}}%
- }
+%% \ltj@ExecuteBeforePackage <package><code> and \ltj@ExecuteAfterPackage <package><code>
+%% no-starred version: do nothing if the <package> is loaded
+%% starred version: do <code> right away if the <package> is loaded
+\def\ltj@ExecuteAfterPackage{\@ifstar\@@ltj@ExecuteAfterPackage@star\@@ltj@ExecuteAfterPackage}
+\def\ltj@ExecuteBeforePackage{\@ifstar\@@ltj@ExecuteBeforePackage@star\@@ltj@ExecuteBeforePackage}
+\@ifl@t@r\fmtversion{2021-11-15}{% 2021-11-15
+ \def\@@ltj@ExecuteAfterPackage@star#1{\AddToHook{package/#1/after}}
+ \def\@@ltj@ExecuteBeforePackage@star#1{\AddToHook{package/#1/before}}
+ \long\def\@@ltj@ExecuteAfterPackage#1#2{%
+ \@ifpackageloaded{#1}{}{\AddToHook{package/#1/after}{#2}}%
}
-\else
- \RequirePackage{filehook}
- \let\ltj@ExecuteAfterPackage=\AtEndOfPackageFile
- \let\ltj@ExecuteBeforePackage=\AtBeginOfPackageFile
-\fi
+ \long\def\@@ltj@ExecuteBeforePackage#1#2{%
+ \@ifpackageloaded{#1}{}{\AddToHook{package/#1/before}{#2}}%
+ }
+}{
+ \def\@@ltj@ExecuteAfterPackage#1{\AddToHook{package/after/#1}}
+ \def\@@ltj@ExecuteBeforePackage#1{\AddToHook{package/before/#1}}
+ \long\def\@@ltj@ExecuteAfterPackage@star#1#2{%
+ \@ifpackageloaded{#1}{#2}{\@@ltj@ExecuteAfterPackage{#1}{#2}}%
+ }
+ \long\def\@@ltj@ExecuteBeforePackage@star#1#2{%
+ \@ifpackageloaded{#1}{#2}{\@@ltj@ExecuteBeforePackage{#1}{#2}}%
+ }
+}
\def\ltj@pkgpatch@im#1{\@ifnextchar[{\ltj@pkgpatch@im@{#1}}{\ltj@pkgpatch@im@{#1}[lltjp-#1]}}%]
\def\ltj@pkgpatch@im@#1[#2]{\ltj@ExecuteAfterPackage*{#1}{\ltj@pkgpatch@im@@{#2}}}
\def\ltj@pkgpatch@im@@#1{%
@@ -101,11 +64,7 @@
}
\def\ltj@pkgpatch#1{\@ifnextchar[{\ltj@pkgpatch@{#1}}{\ltj@pkgpatch@{#1}[lltjp-#1]}}%]
-\ifltj@ltfilehook@avail
- \def\ltj@pkgpatch@@{\AddToHook{begindocument/before}[luatexja.autopatch]}
-\else
- \def\ltj@pkgpatch@@{\gpreto\@begindocumenthook}
-\fi
+\def\ltj@pkgpatch@@{\AddToHook{begindocument/before}[luatexja.autopatch]}
\def\ltj@pkgpatch@#1[#2]{%
\ltj@pkgpatch@@{%
\@ifpackageloaded{#1}{\@ifpackageloaded{#2}{}{\RequirePackage{#2}}}{}%
@@ -121,18 +80,12 @@
\ltj@pkgpatch{tascmac}
\ltj@pkgpatch{ascmac}[lltjp-tascmac]
\ltj@pkgpatch@im{stfloats}
-\ifltj@ltfilehook@avail\else
- \ltj@pkgpatch{preview} %% at \begin{document}
- % (preview package has delayed option)
-\fi
\ltj@pkgpatch{array} %% at \begin{document}
\ltj@pkgpatch{collcell} %% at \begin{document}
\ltj@pkgpatch@im{unicode-math}
\ltj@pkgpatch@im{siunitx}
\ltj@pkgpatch@im{microtype}
-\ifltj@ltfilehook@avail\else\ltj@pkgpatch@im{everyshi}\fi
-
\RequirePackage{lltjp-geometry}
\ltj@ExecuteBeforePackage{breqn}{%
diff --git a/macros/luatex/generic/luatexja/src/ltj-pretreat.lua b/macros/luatex/generic/luatexja/src/ltj-pretreat.lua
index 43ecac806c..8f5632be4e 100644
--- a/macros/luatex/generic/luatexja/src/ltj-pretreat.lua
+++ b/macros/luatex/generic/luatexja/src/ltj-pretreat.lua
@@ -156,16 +156,17 @@ function set_box_stack_level(head, mode)
if ltjs.list_dir == dir_tate then
for p in traverse_glyph(to_direct(head)) do
if getlang(p)==lang_ja and has_attr(p, attr_icflag, 0) then
- local pf = ltjf_replace_altfont(attr_curtfnt, getchar(p), p)
+ local pc = ltjs_orig_char_table[p] or getchar(p)
+ local pf = ltjf_replace_altfont(attr_curtfnt, pc, p)
if ltjf_font_metric_table[pf].vert_activated then
- local pc = ltjf_font_metric_table[pf].vform[pc]; if pc then setchar(p, pc) end
+ pc = ltjf_font_metric_table[pf].vform[pc]; if pc then setchar(p, pc) end
end
end
end
else
for p in traverse_glyph(to_direct(head)) do
if getlang(p)==lang_ja and has_attr(p, attr_icflag, 0) then
- ltjf_replace_altfont(attr_curjfnt, getchar(p), p)
+ ltjf_replace_altfont(attr_curjfnt, ltjs_orig_char_table[p] or getchar(p), p)
end
end
end
diff --git a/macros/luatex/generic/luatexja/src/ltj-rmlgbm.lua b/macros/luatex/generic/luatexja/src/ltj-rmlgbm.lua
index 88352dd5b2..2b65eb5e5c 100644
--- a/macros/luatex/generic/luatexja/src/ltj-rmlgbm.lua
+++ b/macros/luatex/generic/luatexja/src/ltj-rmlgbm.lua
@@ -15,7 +15,7 @@ do
end
local cidfont_data = {}
local cache_chars = {}
-local cache_ver = 13
+local cache_ver = 14
local identifiers = fonts.hashes.identifiers
local cid_reg, cid_order, cid_supp, cid_name
@@ -147,7 +147,7 @@ do
descender = 655360*0.12,
},
embedding = "no", cache = "yes", factor = 0, hfactor = 0, vfactor = 0,
- tounicode = 1,
+ tounicode = 1, filename="",
properties = { language = "dflt", script = "dflt" },
}
cidfont_data[cid_name] = k
diff --git a/macros/luatex/generic/luatexja/src/luatexja.sty b/macros/luatex/generic/luatexja/src/luatexja.sty
index a54ede6758..f9ae793bb4 100644
--- a/macros/luatex/generic/luatexja/src/luatexja.sty
+++ b/macros/luatex/generic/luatexja/src/luatexja.sty
@@ -27,7 +27,7 @@
\newif\ifltj@disablejfam
%%%% VERSION
-\def\LuaTeXjaversion{20240514.0}
+\def\LuaTeXjaversion{20240714.0}
%% Check if LaTeX is used.
\begingroup\expandafter\expandafter\expandafter\endgroup
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjdefs.sty b/macros/luatex/generic/luatexja/src/patches/lltjdefs.sty
index bb63ac6877..00c858e349 100644
--- a/macros/luatex/generic/luatexja/src/patches/lltjdefs.sty
+++ b/macros/luatex/generic/luatexja/src/patches/lltjdefs.sty
@@ -3,7 +3,7 @@
%
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{lltjdefs}[2022-01-23 Default font settings of LuaTeX-ja]
+\ProvidesPackage{lltjdefs}[2024-05-16 Default font settings of LuaTeX-ja]
\ifdefined\ltj@stdmcfont\else\def\ltj@stdmcfont{file:HaranoAjiMincho-Regular.otf}\fi
\ifdefined\ltj@stdgtfont\else\def\ltj@stdgtfont{file:HaranoAjiGothic-Medium.otf}\fi
@@ -18,13 +18,8 @@
\DeclareKanjiEncodingDefaults{}{}
\DeclareErrorKanjiFont{JY3}{mc}{m}{n}{10}
\kanjifamily{mc}
-\ifnum\ltj@@latex@plv<1500 % <=2020-10-01
- \kanjiseries{m}
- \kanjishape{n}
-\else % >=2021-06-01
- \def\k@series{m}
- \def\k@shape{n}
-\fi
+\def\k@series{m}
+\def\k@shape{n}
\fontsize{10}{10}
\DeclareYokoKanjiEncoding{JY3}{}{}
\DeclareKanjiSubstitution{JY3}{mc}{m}{n}
@@ -37,12 +32,7 @@
\newcommand\kanjiencodingdefault{JY3}
\newcommand\kanjifamilydefault{\mcdefault}
\newcommand\kanjiseriesdefault{\mddefault}
-\ifnum 0\ifltj@ltfilehook@avail1\fi\ifdefined\@rmfamilyhook1\fi>0
- %% LaTeX 2020-02-02
- \newcommand\kanjishapedefault{\shapedefault}
-\else%% LaTeX 2019-10-01
- \newcommand\kanjishapedefault{\updefault}
-\fi
+\newcommand\kanjishapedefault{\shapedefault}
\DeclareKanjiFamily{JY3}{mc}{}
\DeclareFontShape{JY3}{mc}{m}{n}{<-> s*[\ifdefined\Cjascale\Cjascale\else 0.962216\fi]
@@ -90,57 +80,36 @@
\DeclareMathAlphabet{\mathgt}{JY3}{gt}{m}{n}
\fi
-\ifnum 0\ifltj@ltfilehook@avail1\fi\ifdefined\@rmfamilyhook1\fi>0
-%%%% LaTeX >= 2020-02-02
\edef\bfseries@mc{\bfdefault}
\edef\bfseries@gt{\bfdefault}
\def\bfseries@jtt{\bfseries@mc}
\edef\mdseries@mc{\mddefault}
\edef\mdseries@gt{\mddefault}
\def\mdseries@jtt{\mdseries@mc}
-\fi
\newif\if@ltj@match@family
\@ltj@match@familyfalse
\def\verbatim@font{\normalfont\ttfamily\kanjifamily\jttdefault\selectfont}
-\def\@ltj@hook@family#1#2{% #1: csname #2: contents
- \ifltj@ltfilehook@avail % LaTeX 2020-10-01
- \AddToHook{#1}{#2}%
- \else\ifcsname @#1hook\endcsname % LaTeX 2020-02-02
- \csappto{@#1hook}{#2}%
- \else % LaTeX 2019-10-01
- \ifcsname #1 \endcsname
- \expandafter\patchcmd\csname #1 \endcsname{\selectfont}{#2\selectfont}{}{}%
- \else
- \PackageWarningNoLine{luatexja}{%
- Patching to \expandafter\string\csname #1\endcsname\space failed%
- }%
- \fi
- \fi\fi
-}
-\@ltj@hook@family{rmfamily}{%
+\AddToHook{rmfamily}{%
\if@ltj@match@family
\prepare@family@series@update@kanji{mc}\mcdefault
\fi
}
-\@ltj@hook@family{sffamily}{%
+\AddToHook{sffamily}{%
\if@ltj@match@family
\prepare@family@series@update@kanji{gt}\gtdefault
\fi
}
-\@ltj@hook@family{ttfamily}{%
+\AddToHook{ttfamily}{%
\if@ltj@match@family
\prepare@family@series@update@kanji{jtt}\jttdefault
\fi
}
-\let\@ltj@hook@family\@undefined
-\ifltj@ltfilehook@avail % 2020-10-01
- \expandafter\def\expandafter\kanjiseriesdefault
- \expandafter{\kanjiseriesdefault\@empty}
- \let\kanjiseriesdefault@kernel\kanjiseriesdefault
-\fi
+\expandafter\def\expandafter\kanjiseriesdefault
+ \expandafter{\kanjiseriesdefault\@empty}
+\let\kanjiseriesdefault@kernel\kanjiseriesdefault
%%% \eminnershape
\expandafter\patchcmd\csname em \endcsname{\itshape}{\gtfamily\itshape}{}{}
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjfont.sty b/macros/luatex/generic/luatexja/src/patches/lltjfont.sty
index 2efc9435ab..52ac44d5cc 100644
--- a/macros/luatex/generic/luatexja/src/patches/lltjfont.sty
+++ b/macros/luatex/generic/luatexja/src/patches/lltjfont.sty
@@ -3,31 +3,10 @@
%
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{lltjfont}[2023-04-13 Patch to NFSS2 for LuaTeX-ja]
+\ProvidesPackage{lltjfont}[2023-05-16 Patch to NFSS2 for LuaTeX-ja]
%%%%%%%% LaTeX2e version detection
-\newcount\ltj@@latex@plv \ltj@@latex@plv=-1
-\ifltj@ltfilehook@avail
-\ExplSyntaxOn
- \cs_if_exist:NTF \__shipout_execute_main_cont:Nnnn
- {\ltj@@latex@plv=1500}% 2021-06-01
- {\ifnum\patch@level>2\relax \ltj@@latex@plv=1300\else \ltj@@latex@plv=1000\fi}% 2020-10-01
-\ExplSyntaxOff
-\else\ifdefined\@rmfamilyhook % 2020-02-02
- \ifx\@forced@seriestrue\@undefined % 2020-02-02 pl0--2
- \@latex@error
- {Please update LaTeX2e!^^J\space\space
- At least LaTeX2e 2020-02-02 patch level 3 is required}%
- {LaTeX2e 2020-02-02 patch level 2 (and 4) has a bug.}
- \else
- \ltj@@latex@plv=300
- \unless\ifx\series@maybe@drop@one@m@x\@undefined % pl5 + develop
- \ltj@@latex@plv=501
- \else\unless\ifx\series@maybe@drop@one@m\@undefined % patch level 5
- \ltj@@latex@plv=500
- \fi\fi
- \fi
-\fi\fi
+\newcount\ltj@@latex@plv \ltj@@latex@plv=1500
%% patching \DeclareTextComposite
\def\ltj@chardef@text@cmd#1{%
@@ -400,59 +379,7 @@
\directlua{luatexja.jfont.pickup_alt_font_a('\f@size')}%
}%
\fi}
-\ifnum\ltj@@latex@plv<1500 % <=2020-10-01
-\protected\def\ltj@selectfont@patch{%
- \ltj@@start@time@measure{selectfont}%
- \let\tmp@error@fontshape\error@fontshape
- \let\error@fontshape\error@kfontshape
- \ltj@@is@kyenc{\k@encoding}\ifin@%
- \let\cy@encoding\k@encoding
- \ensure@KanjiEncodingPair{t}%
- \edef\ct@encoding{\csname t@enc@\k@encoding\endcsname}%
- \else
- \ltj@@is@ktenc{\k@encoding}\ifin@%
- \let\ct@encoding\k@encoding
- \ensure@KanjiEncodingPair{y}%
- \edef\cy@encoding{\csname y@enc@\k@encoding\endcsname}%
- \else
- \@latex@error{KANJI Encoding scheme `\k@encoding' unknown}\@eha
- \fi
- \fi
- \global\let\ltj@afont@name=\font@name
- \ltj@selectfont@tate\ltj@selectfont@yoko
-%
- \edef\tmp@item{{\k@encoding}}\expandafter\def\expandafter\k@encoding\tmp@item
- \kenc@update
- \global\let\font@name=\ltj@afont@name
- \let\error@fontshape\tmp@error@fontshape
- \if@knjcmd \@knjcmdfalse
- \expandafter\ifx
- \csname rel@\k@encoding/\k@family/\k@series/\k@shape\endcsname\relax
- \expandafter\ifx
- \csname rel@\k@encoding/\k@family/\k@series/all\endcsname\relax
- \else
- \csname rel@\k@encoding/\k@family/\k@series/all\endcsname\selectfont
- % 警告: 再び \selectfont を呼んでいる.無限ループの可能性あり
- \fi
- \else
- \csname rel@\k@encoding/\k@family/\k@series/\k@shape\endcsname\selectfont
- % 警告: 再び \selectfont を呼んでいる.無限ループの可能性あり
- \fi
- \fi
- \global\let\font@name=\ltj@afont@name
- \ltj@@stop@time@measure{selectfont}%
-}
-\RequirePackage{everysel}
-\let\ltj@@EverySelectfont@Init=\@EverySelectfont@Init
-\expandafter\expandafter\expandafter\let
-\expandafter\expandafter\csname ltj@@orig@selectfont\endcsname\csname selectfont\space\endcsname
-\@EverySelectfont@Init% for LaTeX2e <=2020-10-01
-\def\@EverySelectfont@Init{%
- \expandafter\let\csname selectfont\space \endcsname \ltj@@orig@selectfont
- \ltj@@EverySelectfont@Init
-}
-\EverySelectfont{\ltj@selectfont@patch}
-\else % LaTeX2e >=2021-06-01
+
\AddToHook{selectfont}[luatexja]{%
\ltj@@start@time@measure{selectfont}%
\ifx\delayed@k@adjustment\@empty
@@ -514,7 +441,6 @@
\global\let\font@name=\ltj@afont@name
\ltj@@stop@time@measure{selectfont}%
}
-\fi
\bgroup
\def\ltj@@dir@patch#1#2#3{%
@@ -721,8 +647,6 @@
}
%%%%%%
-\ifnum\ltj@@latex@plv>0
-%%%% LaTeX >= 2020-02-02
\newif\if@shape@roman@kanji
\def\merge@kanji@series#1{%
@@ -740,76 +664,11 @@
\@nil
}
-\ifnum\ltj@@latex@plv>500 % !!! pl5 + develop
\def\set@target@series@kanji#1{%
\edef\k@series{#1}%
\series@maybe@drop@one@m\k@series\k@series
}
-\else\ifnum\ltj@@latex@plv>300 % !!! pl5
- \def\set@target@series@kanji#1{%
- \edef\k@series{#1}%
- \expandafter\series@maybe@drop@one@m\expandafter{\k@series}\k@series
- }
-\else % !!! pl 3, 4
- \def\set@target@series@kanji#1{%
- \edef\k@series{#1}%
- \edef\k@series{\expandafter\series@drop@one@m\k@series mm\series@drop@one@m}%
- }
-\fi\fi
-\ifnum\ltj@@latex@plv<1500% <=2020-10-01
-\def\merge@kanji@series@#1#2#3\@nil{%
- \def\reserved@a{#3}%
- \ifx\reserved@a\@empty
- \set@target@series@kanji{#2}%
- \else
- \begingroup\let\f@encoding\k@encoding\let\f@family\k@family
- \maybe@load@fontshape\endgroup
- \edef\reserved@a{\k@encoding /\k@family /#1/\k@shape}%
- \ifcsname \reserved@a \endcsname
- \set@target@series@kanji{#1}%
- \else
- \ifcsname \k@encoding /\k@family /#2/\k@shape \endcsname
- \set@target@series@kanji{#2}%
- {\let\curr@fontshape\curr@kfontshape\@font@shape@subst@warning}%
- \else
- \set@target@series@kanji{#3}%
- {\let\curr@fontshape\curr@kfontshape\@font@shape@subst@warning}%
- \fi
- \fi
- \fi
-}
-\def\merge@kanji@shape@#1#2#3\@nil{%
- \def\reserved@a{#3}%
- \ifx\reserved@a\@empty
- \if@shape@roman@kanji
- \set@safe@kanji@shape{#2}{}%
- \else
- \edef\k@shape{#2}%
- \fi
- \else
- \begingroup\let\f@encoding\k@encoding\let\f@family\k@family
- \maybe@load@fontshape\endgroup
- \edef\reserved@a{\k@encoding /\k@family /\k@series/#1}%
- \ifcsname \reserved@a\endcsname
- \edef\k@shape{#1}%
- \else
- \ifcsname \k@encoding /\k@family /\k@series/#2\endcsname
- \edef\k@shape{#2}%
- {\let\curr@fontshape\curr@kfontshape\@font@shape@subst@warning}%
- \else
- \if@shape@roman@kanji
- \set@safe@kanji@shape{#3}%
- {{\let\curr@fontshape\curr@kfontshape\@font@shape@subst@warning}}%
- \else
- \edef\k@shape{#3}%
- {\let\curr@fontshape\curr@kfontshape\@font@shape@subst@warning}%
- \fi
- \fi
- \fi
- \fi
-}
-\else % >=2021-06-01
\def\merge@kanji@series@#1#2#3\@nil{%
\def\reserved@a{#3}%
\ifx\reserved@a\@empty
@@ -892,20 +751,8 @@
\fi
}
\let\delayed@merge@kanji@shape\merge@kanji@shape@without@substitution
-\fi
\newif\if@forced@series@kanji
-\ifnum\ltj@@latex@plv=300 % 2020-02-02 pl3, 4
- \DeclareRobustCommand\romanseries[1]{\merge@font@series{#1}}
- \DeclareRobustCommand\kanjiseries[1]{\merge@kanji@series{#1}}
- \DeclareRobustCommand\romanseriesforce[1]{\edef\f@series{#1}}
- \DeclareRobustCommand\kanjiseriesforce[1]{\edef\k@series{#1}}
-\else\ifnum\ltj@@latex@plv<1500% >=2020-02-02 pl5 and <=2020-10-01
- \DeclareRobustCommand\romanseries[1]{\@forced@seriesfalse\merge@font@series{#1}}
- \DeclareRobustCommand\kanjiseries[1]{\@forced@series@kanjifalse\merge@kanji@series{#1}}
- \DeclareRobustCommand\romanseriesforce[1]{\@forced@seriestrue\edef\f@series{#1}}
- \DeclareRobustCommand\kanjiseriesforce[1]{\@forced@series@kanjitrue\edef\k@series{#1}}
-\else% >=2021-06-01
\DeclareRobustCommand\romanseries[1]{\@forced@seriesfalse
\expandafter\def\expandafter\delayed@f@adjustment\expandafter
{\delayed@f@adjustment\delayed@merge@font@series{#1}}}
@@ -919,22 +766,9 @@
\expandafter\def\expandafter\delayed@k@adjustment\expandafter
{\delayed@k@adjustment\edef\k@series{#1}}}
\let\delayed@k@adjustment\@empty
-\fi\fi
\DeclareRobustCommand\fontseries[1]{\kanjiseries{#1}\romanseries{#1}}%
\DeclareRobustCommand\fontseriesforce[1]{\kanjiseriesforce{#1}\romanseriesforce{#1}}%
-\ifnum\ltj@@latex@plv<1500% <=2020-10-01
- \DeclareRobustCommand\romanshape[1]{\merge@font@shape{#1}}
- \DeclareRobustCommand\kanjishape[1]{\merge@kanji@shape{#1}}
- \DeclareRobustCommand\fontshape[1]{%
- \@shape@roman@kanjitrue
- \merge@font@shape{#1}\merge@kanji@shape{#1}%
- \@shape@roman@kanjifalse
- }
- \DeclareRobustCommand\romanshapeforce[1]{\edef\f@shape{#1}}
- \DeclareRobustCommand\kanjishapeforce[1]{\edef\k@shape{#1}}
- \DeclareRobustCommand\fontshapeforce[1]{\set@safe@kanji@shape{#1}{}\romanshapeforce{#1}}
-\else% >=2021-06-01
\DeclareRobustCommand\romanshape[1]{%
\expandafter\def\expandafter\delayed@f@adjustment\expandafter
{\delayed@f@adjustment\delayed@merge@font@shape{#1}}}
@@ -956,9 +790,6 @@
\romanshapeforce{#1}%
\expandafter\def\expandafter\delayed@k@adjustment\expandafter
{\delayed@k@adjustment\set@safe@kanji@shape{#1}{}}}
-\fi
-\ifnum\ltj@@latex@plv>1499
-%%%% LaTeX >= 2021-06-01
\DeclareRobustCommand\usekanji[4]{%
\kanjiencoding{#1}\edef\k@family{#2}%
\set@target@series@kanji{#3}\edef\k@shape{#4}%
@@ -969,42 +800,6 @@
\set@target@series{#3}\edef\f@shape{#4}%
\let\delayed@f@adjustment\@empty
\selectfont\ignorespaces}
-\else\ifnum\ltj@@latex@plv>1000
-%%%% 2021-10-01 PL3 <= LaTeX < 2021-06-01
-\DeclareRobustCommand\usekanji[4]{%
- \kanjiencoding{#1}\edef\k@family{#2}%
- \set@target@series@kanji{#3}\edef\k@shape{#4}%
- \selectfont\ignorespaces}
-\DeclareRobustCommand\useroman[4]{%
- \romanencoding{#1}\edef\f@family{#2}%
- \set@target@series{#3}\edef\f@shape{#4}%
- \selectfont\ignorespaces}
-\else
-%%%% 2020-10-01 <= LaTeX < 2020-10-01 PL3
-\DeclareRobustCommand\usekanji[4]{%
- \kanjiencoding{#1}\edef\k@family{#2}\edef\k@series{#3}\edef\k@shape{#4}%
- \selectfont\ignorespaces}
-\DeclareRobustCommand\useroman[4]{%
- \romanencoding{#1}\edef\f@family{#2}\edef\f@series{#3}\edef\f@shape{#4}%
- \selectfont\ignorespaces}
-\fi\fi
-%%%% LaTeX >= 2020-02-02 END
-\else
-%%%% LaTeX 2019-10-01
-\DeclareRobustCommand\romanseries[1]{\edef\f@series{#1}}
-\DeclareRobustCommand\kanjiseries[1]{\edef\k@series{#1}}
-\DeclareRobustCommand\fontseries[1]{\kanjiseries{#1}\romanseries{#1}}
-\DeclareRobustCommand\romanshape[1]{\edef\f@shape{#1}}
-\DeclareRobustCommand\kanjishape[1]{\edef\k@shape{#1}}
-\DeclareRobustCommand\fontshape[1]{\set@safe@kanji@shape{#1}{}\romanshape{#1}}
-\DeclareRobustCommand\usekanji[4]{%
- \kanjiencoding{#1}\kanjifamily{#2}\kanjiseries{#3}\kanjishape{#4}%
- \selectfont\ignorespaces}
-\DeclareRobustCommand\useroman[4]{%
- \romanencoding{#1}\romanfamily{#2}\romanseries{#3}\romanshape{#4}%
- \selectfont\ignorespaces}
-%%%% LaTeX 2019-10-01 END
-\fi
%%%%
\def\set@safe@kanji@shape#1#2{%
@@ -1026,8 +821,6 @@
\else\useroman{#1}{#2}{#3}{#4}%
\fi}
-\ifnum 0\ifltj@ltfilehook@avail1\fi\ifdefined\@rmfamilyhook1\fi>0
-%%%% LaTeX >= 2020-02-02
\let\prepare@family@series@update@kanji=\prepare@family@series@update
\patchcmd\prepare@family@series@update{\fontfamily}{\romanfamily}{}{}
\patchcmd\prepare@family@series@update@kanji{\if@forced@series}{\if@forced@series@kanji}{}{}
@@ -1049,34 +842,16 @@
\patchcmd\update@series@target@value@kanji{\f@series}{\k@series}{}{}
\def\@meta@family@list@kanji{\@elt{mc}\@elt{gt}\@elt{jtt}}
-\def\@ltj@hook@series@default#1#2#3{%
- \ifltj@ltfilehook@avail % 2020-10-01
- \AddToHook{#1/defaults}{#2}%
- \else\ifcsname @set#1defaultshook\endcsname %after 2020-04-07
- \expandafter\g@addto@macro\csname @set#1defaultshook\endcsname{#2}%
- \else % 2020-02-02
- \expandafter\patchcmd\csname #1 \endcsname{#3}{#3#2}{}{}%
- \fi\fi
-}
-\@ltj@hook@series@default{bfseries}{%
+\AddToHook{bfseries/defaults}{%
\let\bfseries@mc\bfdef@ult
\let\bfseries@gt\bfdef@ult
\let\bfseries@jtt\bfdef@ult
-}{%
- \let\bfseries@rm\bfdef@ult
- \let\bfseries@sf\bfdef@ult
- \let\bfseries@tt\bfdef@ult
}
-\@ltj@hook@series@default{mdseries}{%
+\AddToHook{mdseries/defaults}{%
\let\mdseries@mc\mddef@ult
\let\mdseries@gt\mddef@ult
\let\mdseries@jtt\mddef@ult
-}{%
- \let\mdseries@rm\mddef@ult
- \let\mdseries@sf\mddef@ult
- \let\mdseries@tt\mddef@ult
}
-\let\@ltj@hook@series@default\@undefined
\expandafter\patchcmd\csname bfseries \endcsname{%
\ifx\f@family\rmdef@ult \fontseries\bfseries@rm
@@ -1105,105 +880,41 @@
\fi\fi\fi
}{}{}
-\def\@ltj@hook@series#1#2{%
- \ifltj@ltfilehook@avail % 2020-10-01
- \AddToHook{#1}{#2}%
- \else % 2020-02-02
- \expandafter\patchcmd\csname #1 \endcsname{\selectfont}{#2\selectfont}{}{}%
- \fi
-}
-\@ltj@hook@series{bfseries}{%
+\AddToHook{bfseries}{%
\ifx\k@family\mcdef@ult \kanjiseries\bfseries@mc
\else\ifx\k@family\gtdef@ult \kanjiseries\bfseries@gt
\else\ifx\k@family\jttdef@ult\kanjiseries\bfseries@jtt
\else \kanjiseries\bfdefault
\fi\fi\fi
}
-\@ltj@hook@series{mdseries}{%
+\AddToHook{mdseries}{%
\ifx\k@family\mcdef@ult \kanjiseries\mdseries@mc
\else\ifx\k@family\gtdef@ult \kanjiseries\mdseries@gt
\else\ifx\k@family\jttdef@ult\kanjiseries\mdseries@jtt
\else \kanjiseries\mddefault
\fi\fi\fi
}
-\let\@ltj@hook@series\@undefined
-\def\@ltj@hook@efd#1#2{%
- \ifltj@ltfilehook@avail % 2020-10-01
- \AddToHook{expand@font@defaults}{#1}%
- \else\ifdefined\@expandfontdefaultshook %after 2020-04-07
- \g@addto@macro\@expandfontdefaultshook{#1#2}%
- \else % 2020-02-02
- \appto\expand@font@defaults{#1#2}%
- \fi\fi
-}
-\@ltj@hook@efd{%
+\AddToHook{expand@font@defaults}{%
\edef\mcdef@ult{\mcdefault}%
\edef\gtdef@ult{\gtdefault}%
\edef\jttdef@ult{\jttdefault}%
-}{\edef\kanjidef@ult{\kanjifamilydefault}}
-\let\@ltj@hook@efd\@undefined
+ \edef\kanjidef@ult{\kanjifamilydefault}}
-\ifltj@ltfilehook@avail % 2020-10-01
- \appto\init@series@setup{%
- \ifx\kanjiseriesdefault\kanjiseriesdefault@kernel
- \mdseries
- \let\kanjiseriesdefault\k@series
- \fi
- }
-\else
- \appto\init@series@setup{%
- \ifx\kanjidef@ult\mcdef@ult \mcfamily
- \else\ifx\kanjidef@ult\gtdef@ult \gtfamily
- \else\ifx\kanjidef@ult\jttdef@ult \jttfamily
- \fi\fi\fi
- }
-\fi
-
-\def\@ltj@hook@dfh#1{%
- \ifltj@ltfilehook@avail % 2020-10-01
- \AddToHook{normalfont}{#1}%
- \else\ifdefined\@defaultfamilyhook
- \g@addto@macro\@defaultfamilyhook{#1}%
- \else % 2020-02-02
- \expandafter\patchcmd\csname normalfont \endcsname{\selectfont}{#1\selectfont}{}{}%
- \let\reset@font\normalfont
- \fi\fi
+\appto\init@series@setup{%
+ \ifx\kanjiseriesdefault\kanjiseriesdefault@kernel
+ \mdseries
+ \let\kanjiseriesdefault\k@series
+ \fi
}
-\ifnum\ltj@@latex@plv>1499
-\@ltj@hook@dfh{%
+\AddToHook{normalfont}{%
\kanjiencoding{\kanjiencodingdefault}%
\edef\k@family{\kanjifamilydefault}%
\edef\k@series{\kanjiseriesdefault}%
\edef\k@shape{\kanjishapedefault}%
\let\delayed@k@adjustment\empty
}
-\else
-\@ltj@hook@dfh{%
- \kanjiencoding{\kanjiencodingdefault}%
- \edef\k@family{\kanjifamilydefault}%
- \edef\k@series{\kanjiseriesdefault}%
- \edef\k@shape{\kanjishapedefault}%
-}
-\fi
-\let\@ltj@hook@dfh\@undefined
-%%%% LaTeX >= 2020-02-02 END
-\else
-%%%% LaTeX 2019-10-01
-\DeclareRobustCommand\normalfont{%
- \useroman\encodingdefault\familydefault\seriesdefault\shapedefault
- \usekanji\kanjiencodingdefault\kanjifamilydefault\kanjiseriesdefault\kanjishapedefault}
-\let\reset@font\normalfont
-%%%% LaTeX 2019-10-01 END
-\fi
-
-
-
-\ifdefined\prepare@family@series@update@kanji\else
-%%%% LaTeX 2019-10-01
-\def\prepare@family@series@update@kanji#1{\kanjifamily}
-\fi
\DeclareRobustCommand\mcfamily{%
\unless\ifltj@disablejfam\not@math@alphabet\mcfamily\mathmc\fi
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjp-array.sty b/macros/luatex/generic/luatexja/src/patches/lltjp-array.sty
index 9575dc3c04..8005153571 100644
--- a/macros/luatex/generic/luatexja/src/patches/lltjp-array.sty
+++ b/macros/luatex/generic/luatexja/src/patches/lltjp-array.sty
@@ -3,7 +3,7 @@
%
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{lltjp-array}[2019-07-18 Patch to array for LuaTeX-ja]
+\ProvidesPackage{lltjp-array}[2024-06-10 Patch to array for LuaTeX-ja]
\RequirePackage{etoolbox,array}
@@ -11,7 +11,14 @@
\ignorespaces\@sharp\unskip
}{%
\ltj@sharp
-}{}{}
+}{}{% >=2024-06-01
+ \def\ltj@sharp{\relax\pltx@next@inhibitglue\ltjfakeboxbdd\ignorespaces\@sharp\textonly@unskip\ltjfakeboxbdd}
+ \patchcmd\insert@column{%
+ \ignorespaces\@sharp\textonly@unskip
+ }{%
+ \ltj@sharp
+ }{}{}
+}
\@ifpackageloaded{lltjext}{}{%
%% remove extra \xkanjiskip (pLaTeX2e 2016/04/17)
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjp-geometry.sty b/macros/luatex/generic/luatexja/src/patches/lltjp-geometry.sty
index 67b0f5de7f..641fa4a34d 100644
--- a/macros/luatex/generic/luatexja/src/patches/lltjp-geometry.sty
+++ b/macros/luatex/generic/luatexja/src/patches/lltjp-geometry.sty
@@ -3,7 +3,7 @@
%
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{lltjp-geometry}[2021-10-24 Patch to geometry for LuaTeX-ja with vertical writing mode]
+\ProvidesPackage{lltjp-geometry}[2024-05-16 Patch to geometry for LuaTeX-ja with vertical writing mode]
\RequirePackage{expl3}
\ifdefined\if@ltj@@geometry@tate\expandafter\endinput\fi
\newif\if@ltj@@geometry@tate
@@ -31,15 +31,6 @@
%============================================
\unless\ifdefined\ltj@ExecuteAfterPackage
-\expandafter\newif\csname ifltj@ltfilehook@avail\endcsname
-\@ifl@t@r\fmtversion{2020-10-01}{%
- \@ifl@t@r\fmtversion{2020-10-02}{\ltj@ltfilehook@availtrue}
- {%
- \ifnum\patch@level<0\relax \ifnum\patch@level<-6 \ltj@ltfilehook@availtrue\fi
- \else\ltj@ltfilehook@availtrue\fi
- }%
-}{}
-\ifltj@ltfilehook@avail
%% \ltj@ExecuteBeforePackage <package><code> and \ltj@ExecuteAfterPackage <package><code>
%% no-starred version: do nothing if the <package> is loaded
%% starred version: do <code> right away if the <package> is loaded
@@ -64,11 +55,6 @@
\@ifpackageloaded{#1}{#2}{\@@ltj@ExecuteBeforePackage{#1}{#2}}%
}
}
-\else
- \RequirePackage{filehook}
- \let\ltj@ExecuteAfterPackage=\AtEndOfPackageFile
- \let\ltj@ExecuteBeforePackage=\AtBeginOfPackageFile
-\fi
\fi
%============================================
@@ -89,12 +75,8 @@
\else
\@gobble\iftrue\csname iftdir\endcsname \bool_set_true:N \l_tmpa_bool \fi
\fi
-\ifltj@ltfilehook@avail
- \prop_map_inline:Nn \g__hook_begindocument_code_prop
- { \tl_if_in:nnT {#2} {\tate} {\bool_set_true:N \l_tmpa_bool} }
-\else
- \tl_if_in:NnT \@begindocumenthook {\tate} {\bool_set_true:N \l_tmpa_bool}
-\fi
+\prop_map_inline:Nn \g__hook_begindocument_code_prop
+ { \tl_if_in:nnT {#2} {\tate} {\bool_set_true:N \l_tmpa_bool} }
\bool_if:NT \l_tmpa_bool {
\if@ltj@@geometry@forceoff
\@ltj@@geometry@tatefalse
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjp-siunitx.sty b/macros/luatex/generic/luatexja/src/patches/lltjp-siunitx.sty
index 9c4526c3fd..292cbf00bf 100644
--- a/macros/luatex/generic/luatexja/src/patches/lltjp-siunitx.sty
+++ b/macros/luatex/generic/luatexja/src/patches/lltjp-siunitx.sty
@@ -1,5 +1,5 @@
%
-% lltjp-siunitx.sty 2022-12-14
+% lltjp-siunitx.sty 2024-06-10
%
\NeedsTeXFormat{LaTeX2e}
@@ -7,7 +7,6 @@
\RequirePackage{siunitx}
\makeatletter
\ExplSyntaxOn
-\cs_if_exist:NTF \siunitx_print_text:n {% siunitx v3.00
\cs_set_protected:Npn \siunitx_print_text:n #1
{
\text
@@ -32,104 +31,26 @@
}
}
\cs_set_eq:NN \ltj_orig__siunitx_table_collect_begin:w \__siunitx_table_collect_begin:w
-\cs_set_protected:Npn \__siunitx_table_collect_begin:w #1 \relax
- { \ltj_orig__siunitx_table_collect_begin:w }
-\RenewDocumentCommand \tablenum { O { } m }
- {
- \mode_leave_vertical:
- \group_begin:
- \keys_set:nn { siunitx } {#1}
- \siunitx_cell_begin:w
- \relax \ignorespaces #2
- \siunitx_cell_end:
- \group_end:
- }
-}% siunitx v3.00 end
-{% siunitx v2.xx
-\cs_generate_variant:Nn \tl_if_in:NnT { coT }
-\cs_new:Nn \__ltj_siunix_patch_inner:n {
- \cs_if_exist:cT { #1_tl } {
- \tl_if_in:coT { #1_tl } { \tex_char:D } {
- \tl_replace_all:cnn { #1_tl } { \tex_char:D } { \ltjalchar }
- }
+\cs_set_protected:Npn \__siunitx_table_collect_begin:w #1 {
+ \token_if_eq_meaning:NNTF #1 \relax
+ {\ltj_orig__siunitx_table_collect_begin:w }
+ {\ltj_orig__siunitx_table_collect_begin:w #1 }
}
-}
-\cs_new:Nn \__ltj_siunix_patch_inner_math:n {
- \__ltj_siunix_patch_inner:n { l__siunitx_#1_math }
- \__ltj_siunix_patch_inner:n { l__siunitx_#1_text }
-}
-\AtBeginDocument {
- \__ltj_siunix_patch_inner:n { c__siunitx_minus }
- \__ltj_siunix_patch_inner:n { c__siunitx_mu }
- \__ltj_siunix_patch_inner_math:n { angstrom }
- \__ltj_siunix_patch_inner_math:n { arcminute }
- \__ltj_siunix_patch_inner_math:n { arcsecond }
- \__ltj_siunix_patch_inner_math:n { ohm }
-}
-
-%%%% new table column: S and s
-\bool_new:N \l__ltj_siunitx_table_collect_relax_bool
-\cs_set_protected:Npn \__siunitx_table_collect_begin_s: {
- \bool_set_false:N \l__ltj_siunitx_table_collect_relax_bool
- \cs_set_eq:NN \__siunitx_table_collect_token:N
- \__siunitx_table_collect_token_s:N
- \cs_set_eq:NN \__siunitx_table_print: \__siunitx_table_print_s:
- \__siunitx_table_collect_init_s:
- \__siunitx_table_collect_get:
-}
-
-\cs_set_protected:Npn \__siunitx_table_collect_not_braced:N #1
+\cs_set_protected:Npn \__siunitx_table_collect_token:N #1
{
- \token_if_eq_meaning:NNTF #1 \tex_relax:D {
- \bool_if:NTF \l__ltj_siunitx_table_collect_relax_bool {
- \__siunitx_table_collect_not_braced_aux_i:N #1
- } {
- \bool_set_true:N \l__ltj_siunitx_table_collect_relax_bool
- }
- } {
- \token_if_eq_meaning:NNF #1 \ltjfakeboxbdd {
- \token_if_eq_meaning:NNF #1 \pltx@next@inhibitglue {
- \token_if_eq_meaning:NNF #1 \tex_ignorespaces:D
+ \__siunitx_table_collect_search:NnF #1
{
- \token_if_eq_meaning:NNF #1 \tex_unskip:D
- { \__siunitx_table_collect_not_braced_aux_i:N #1 }
+ \ignorespaces { \__siunitx_table_collect_ignore_spaces:N #1}
+ \pltx@next@inhibitglue { \__siunitx_table_collect_loop:}
+ \ltjfakeboxbdd { \__siunitx_table_collect_loop:}
+ \textonly@unskip { \__siunitx_table_collect_loop:}
+ \unskip { \__siunitx_table_collect_loop:}
+ \end { \tabularnewline \end }
+ \relax { \__siunitx_table_collect_relax:N #1 }
+ \tabularnewline { \tabularnewline }
+ \siunitx_cell_end: { \siunitx_cell_end:}
}
- }}}
- \__siunitx_table_collect_next:
- }
-
-\AtBeginDocument
- {
- \@ifpackageloaded { mdwtab }
- {
- \cs_set_protected:Npn \__siunitx_table_collect_not_braced:N #1
- {
- \token_if_eq_meaning:NNTF #1 \tex_relax:D {
- \bool_if:NTF \l__ltj_siunitx_table_collect_relax_bool {
- \__siunitx_table_collect_not_braced_aux_i:N #1
- } {
- \bool_set_true:N \l__ltj_siunitx_table_collect_relax_bool
- }
- } {
- \token_if_eq_meaning:NNF #1 \ltjfakeboxbdd {
- \token_if_eq_meaning:NNF #1 \pltx@next@inhibitglue {
- \token_if_eq_meaning:NNF #1 \tex_ignorespaces:D
- {
- \token_if_eq_meaning:NNF #1 \tex_unskip:D
- {
- \token_if_eq_meaning:NNF #1 \tab@setcr
- {
- \token_if_eq_meaning:NNF #1 \@maybe@unskip
- { \__siunitx_table_collect_not_braced_aux_i:N #1 }
- }
- }
- }
- }}}
- \__siunitx_table_collect_next:
- }
- }
- { }
- }
+ { \__siunitx_table_collect_token_aux:N #1 }
}
\ExplSyntaxOff
\endinput
diff --git a/macros/luatex/generic/luaxml/README b/macros/luatex/generic/luaxml/README
index 5df074c453..6a81ab25ce 100644
--- a/macros/luatex/generic/luaxml/README
+++ b/macros/luatex/generic/luaxml/README
@@ -32,7 +32,7 @@ Author
------
Michal Hoftich
Email: michal.h21@gmail.com
-Version: v0.1r, 2024-02-23
+Version: v0.2, 2024-07-14
Original authors: Paul Chakravarti and Manoel Campos (http://manoelcampos.com)
diff --git a/macros/luatex/generic/luaxml/luaxml-cssquery.lua b/macros/luatex/generic/luaxml/luaxml-cssquery.lua
index ebb29abb15..452656845c 100644
--- a/macros/luatex/generic/luaxml/luaxml-cssquery.lua
+++ b/macros/luatex/generic/luaxml/luaxml-cssquery.lua
@@ -156,7 +156,7 @@ local function cssquery()
-- make sure we deal with a string
value = tostring(value)
-- make the search string safe for pattern matching
- local escaped_search = search:gsub("([%(%)%.%%%+%–%*%?%[%^%$])", "%%%1")
+ local escaped_search = search:gsub("([%(%)%.%%%+%-%#%*%?%[%^%$])", "%%%1")
if modifier == "" then
return value == search
elseif modifier == "|" then
@@ -434,6 +434,18 @@ local function cssquery()
return querylist
end
+ --- Remove selector from the CSS list object.
+ -- All actions that literaly match the given selector will be removed.
+ function CssQuery:remove_selector(
+ selector -- CSS selector to be removed
+ )
+ for pos, obj in ipairs(self.querylist) do
+ if obj.source == selector then
+ table.remove(self.querylist, pos)
+ end
+ end
+ end
+
--- It tests list of queries agaings a DOM element and executes the
--- coresponding function that is saved for the matched query.
-- @return nothing
diff --git a/macros/luatex/generic/luaxml/luaxml-domobject.lua b/macros/luatex/generic/luaxml/luaxml-domobject.lua
index 73689add5a..dca38df0db 100644
--- a/macros/luatex/generic/luaxml/luaxml-domobject.lua
+++ b/macros/luatex/generic/luaxml/luaxml-domobject.lua
@@ -6,16 +6,20 @@ local dom = {}
local xml
local handler
local css_query
+local html
if kpse then
xml = require("luaxml-mod-xml")
handler = require("luaxml-mod-handler")
css_query = require("luaxml-cssquery")
+ html = require("luaxml-mod-html")
else
xml = require("luaxml.mod-xml")
handler = require("luaxml.mod-handler")
css_query = require("luaxml.cssquery")
+ html = require("luaxml.mod-html")
end
+local HtmlParser = html.HtmlParser
local void = {area = true, base = true, br = true, col = true, hr = true, img = true, input = true, link = true, meta = true, param = true}
@@ -91,9 +95,14 @@ local function serialize_dom(parser, current,level, output)
local format = get_action(typ, "start")
insert(format, el, prepare_attributes(attr))
end
- local function text(typ, text)
+ local function text(typ, text, parent)
+ local parent = parent or {}
local format = get_action(typ, "text")
- insert(format, escape_element(text))
+ if parent.verbatim then
+ insert(format, text)
+ else
+ insert(format, escape_element(text))
+ end
end
local function stop(typ, el)
local format = get_action(typ, "stop")
@@ -141,7 +150,7 @@ local function serialize_dom(parser, current,level, output)
end
start(xtype, name, attributes)
- text(xtype,text_content)
+ text(xtype,text_content, (current or {})._parent)
local children = root._children or {}
for _, child in ipairs(children) do
output = serialize_dom(parser,child, level + 1, output)
@@ -411,8 +420,8 @@ local parse = function(
return strings
end
- --- Get table with the inner text of an element -- leading and trailing spaces are removed and elements that contain only white space are ignored.
- --- @return table
+ --- Get table with the inner text of an element - leading and trailing spaces are removed and elements that contain only white space are ignored.
+ -- @return table
function DOM_Object:stripped_strings(
current --- [optional] element to be selected
)
@@ -612,11 +621,83 @@ local parse = function(
-- include the methods to all xml nodes
save_methods(parser._handler.root)
-- parser:
- return parser
+ return parser, DOM_Object
+end
+
+-- table of elements that should be kept without XML escaping in the DOM serialization
+local verbatim_elements = {script=true, style=true}
+
+local function html_to_dom(html_object)
+ -- convert parsed HTML DOM to the XML DOM
+ local dom, DOM_Object = parse("") -- use empty text to just initialize the DOM object
+ -- use root of the DOM object as the original parent
+ local current_parent = dom._handler.root
+
+ local function create_node(tbl)
+ -- create node suitable for LuaXML DOM object
+ tbl._children = {}
+ -- this should copy methods from the DOM object to the newly created object
+ tbl.__index = DOM_Object
+ return setmetatable(tbl, DOM_Object)
+ end
+
+ local function build_tree(object)
+ -- convert tree produced by the HTML parser to LuaXML DOM
+ local typ = object._type
+ -- process particular node types from the HTML parser
+ if typ == "doctype" then
+ current_parent:add_child_node(create_node {_name=object.name, _type="DTD"})
+ elseif typ == "comment" then
+ current_parent:add_child_node(create_node {_text=object.text, _type="COMMENT"})
+ elseif typ == "element" then
+ local attributes = {}
+ -- convert attributes to the form expected by the DOM object
+ for _, attr in ipairs(object.attr) do
+ attributes[attr.name] = attr.value
+ end
+ local element = current_parent:create_element(object.tag, attributes)
+ -- disable escaping of text in dom:serialize() for <script> or <style> elements
+ if verbatim_elements[string.lower(object.tag)] then element.verbatim = true end
+ current_parent:add_child_node(element)
+ -- set the current element as parent for the processing of children
+ local old_parent = current_parent
+ current_parent = element
+ -- process children
+ for k,v in ipairs(object.children) do
+ build_tree(v)
+ end
+ -- restore original parent
+ current_parent = old_parent
+ elseif typ == "text" then
+ local text = current_parent:create_text_node(object.text)
+ current_parent:add_child_node(text)
+ else
+ -- for other node types, just process the children
+ for k,v in ipairs(object.children) do
+ build_tree(v)
+ end
+ end
+
+ end
+ build_tree(html_object)
+ return dom
+end
+
+--- Parse HTML text as a DOM object.
+-- It supports all methods as the object returned by the parse() function.
+-- @param html_str string with the HTML code to be parsed
+-- @return DOM_Object
+local function html_parse(html_str)
+ local html_obj = HtmlParser:init(html_str)
+ local html_dom = html_obj:parse()
+ return html_to_dom(html_dom)
end
+
+
--- @export
return {
parse = parse,
- serialize_dom= serialize_dom
+ serialize_dom= serialize_dom,
+ html_parse = html_parse
}
diff --git a/macros/luatex/generic/luaxml/luaxml-encodings.lua b/macros/luatex/generic/luaxml/luaxml-encodings.lua
new file mode 100644
index 0000000000..71bfc81dd1
--- /dev/null
+++ b/macros/luatex/generic/luaxml/luaxml-encodings.lua
@@ -0,0 +1,88 @@
+--- Convert 8-bit encodings to UTF-8
+--- @module luaxml-encodings
+-- this table is generated automatically by this command:
+-- texlua encodings/make_encodings.lua
+local encodings = {
+ ['ibm866'] = 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёЄєЇїЎў°∙·√№¤■ ',
+ ['iso-8859-5'] = '�������������������������������� ЁЂЃЄЅІЇЈЉЊЋЌ­ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђѓєѕіїјљњћќ§ўџ',
+ ['macintosh'] = 'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ',
+ ['windows-1251'] = 'ЂЃ‚ѓ„…†‡€‰Љ‹ЊЌЋЏђ‘’“”•–—�™љ›њќћџ ЎўЈ¤Ґ¦§Ё©Є«¬­®Ї°±Ііґµ¶·ё№є»јЅѕїАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя',
+ ['iso-8859-13'] = '�������������������������������� ”¢£¤„¦§Ø©Ŗ«¬­®Æ°±²³“µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž’',
+ ['iso-8859-6'] = '�������������������������������� ���¤�������،­�������������؛���؟�ءآأؤإئابةتثجحخدذرزسشصضطظعغ�����ـفقكلمنهوىيًٌٍَُِّْ',
+ ['iso-8859-8'] = '�������������������������������� �¢£¤¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾��������������������������������‗אבגדהוזחטיךכלםמןנסעףפץצקרשת��‎‏',
+ ['iso-8859-4'] = '�������������������������������� ĄĸŖ¤ĨĻ§¨ŠĒĢŦ­Ž¯°ą˛ŗ´ĩļˇ¸šēģŧŊžŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎĪĐŅŌĶÔÕÖ×ØŲÚÛÜŨŪßāáâãäåæįčéęëėíîīđņōķôõö÷øųúûüũū˙',
+ ['koi8-r'] = '─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ё╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡Ё╢╣╤╥╦╧╨╩╪╫╬©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ',
+ ['iso-8859-7'] = '�������������������������������� ‘’£€₯¦§¨©ͺ«¬­�―°±²³΄΅Ά·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ',
+ ['iso-8859-3'] = '�������������������������������� Ħ˘£¤�Ĥ§¨İŞĞĴ­�Ż°ħ²³´µĥ·¸ışğĵ½�żÀÁÂ�ÄĊĈÇÈÉÊËÌÍÎÏ�ÑÒÓÔĠÖ×ĜÙÚÛÜŬŜßàáâ�äċĉçèéêëìíîï�ñòóôġö÷ĝùúûüŭŝ˙',
+ ['windows-1256'] = '€پ‚ƒ„…†‡ˆ‰ٹ‹Œچژڈگ‘’“”•–—ک™ڑ›œ‌‍ں ،¢£¤¥¦§¨©ھ«¬­®¯°±²³´µ¶·¸¹؛»¼½¾؟ہءآأؤإئابةتثجحخدذرزسشصض×طظعغـفقكàلâمنهوçèéêëىيîïًٌٍَôُِ÷ّùْûü‎‏ے',
+ ['windows-1258'] = '€�‚ƒ„…†‡ˆ‰�‹Œ����‘’“”•–—˜™�›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖ×ØÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ',
+ ['iso-8859-14'] = '�������������������������������� Ḃḃ£ĊċḊ§Ẁ©ẂḋỲ­®ŸḞḟĠġṀṁ¶ṖẁṗẃṠỳẄẅṡÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏŴÑÒÓÔÕÖṪØÙÚÛÜÝŶßàáâãäåæçèéêëìíîïŵñòóôõöṫøùúûüýŷÿ',
+ ['windows-1252'] = '€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ',
+ ['iso-8859-15'] = '�������������������������������� ¡¢£€¥Š§š©ª«¬­®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ',
+ ['x-mac-cyrillic'] = 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°Ґ£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµґЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю€',
+ ['windows-1254'] = '€�‚ƒ„…†‡ˆ‰Š‹Œ����‘’“”•–—˜™š›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ',
+ ['windows-1255'] = '€�‚ƒ„…†‡ˆ‰�‹�����‘’“”•–—˜™�›���� ¡¢£₪¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾¿ְֱֲֳִֵֶַָֹֺֻּֽ־ֿ׀ׁׂ׃װױײ׳״�������אבגדהוזחטיךכלםמןנסעףפץצקרשת��‎‏',
+ ['windows-1250'] = '€�‚�„…†‡�‰Š‹ŚŤŽŹ�‘’“”•–—�™š›śťžź ˇ˘Ł¤Ą¦§¨©Ş«¬­®Ż°±˛ł´µ¶·¸ąş»Ľ˝ľżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙',
+ ['koi8-u'] = '─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ёє╔ії╗╘╙╚╛ґў╞╟╠╡ЁЄ╣ІЇ╦╧╨╩╪ҐЎ©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ',
+ ['iso-8859-10'] = '�������������������������������� ĄĒĢĪĨĶ§ĻĐŠŦŽ­ŪŊ°ąēģīĩķ·ļđšŧž―ūŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎÏÐŅŌÓÔÕÖŨØŲÚÛÜÝÞßāáâãäåæįčéęëėíîïðņōóôõöũøųúûüýþĸ',
+ ['windows-1257'] = '€�‚�„…†‡�‰�‹�¨ˇ¸�‘’“”•–—�™�›�¯˛� �¢£¤�¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙',
+ ['windows-1253'] = '€�‚ƒ„…†‡�‰�‹�����‘’“”•–—�™�›���� ΅Ά£¤¥¦§¨©�«¬­®―°±²³΄µ¶·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ',
+ ['iso-8859-2'] = '�������������������������������� Ą˘Ł¤ĽŚ§¨ŠŞŤŹ­ŽŻ°ą˛ł´ľśˇ¸šşťź˝žżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙',
+ ['windows-874'] = '€����…�����������‘’“”•–—�������� กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛',
+ ['iso-8859-16'] = '�������������������������������� ĄąŁ€„Š§š©Ș«Ź­źŻ°±ČłŽ”¶·žčș»ŒœŸżÀÁÂĂÄĆÆÇÈÉÊËÌÍÎÏĐŃÒÓÔŐÖŚŰÙÚÛÜĘȚßàáâăäćæçèéêëìíîïđńòóôőöśűùúûüęțÿ',
+}
+
+
+local utfchar = utf8.char
+
+--- Try to find an encoding in HTML string
+---@param str string HTML document
+---@param len number count of characters from the start of the string where it should search for the encoding metadata
+---@return string encoding identifier, or nil and message if no encoding was found
+local function find_html_encoding(str, len)
+ -- try to find encoding in the html document
+ -- we limit search length, because encoding should be in the document head, ideally near the start
+ local len = len or 4096
+ local sub = str:sub(1, len)
+ for meta in sub:gmatch("<meta (.-)>") do
+ local charset = meta:match("charset%s*=%s*[\"']?(.-)[\"']")
+ if charset then return string.lower(charset) end
+ end
+ return nil, "Cannot find the document encoding"
+end
+
+local function load_mapping(enc_name)
+ local enc_name = enc_name or ""
+ local enc = encodings[enc_name]
+ if not enc then return nil, "Cannot load encoding " .. enc_name end
+ local mapping,i = {}, 128
+ for pos, codepoint in utf8.codes(enc) do
+ mapping[i] = utfchar(codepoint)
+ i = i + 1
+ end
+ return mapping
+end
+
+--- Convert string to utf-8
+---@param text string for converting
+---@param mapping table
+---@return string converted string
+local function recode(text, mapping)
+ return text:gsub("(.)", function(char)
+ local charpoint = string.byte(char)
+ if charpoint > 127 then
+ return mapping[charpoint]
+ else
+ return false
+ end
+ end)
+end
+
+
+return {
+ encodings = encodings,
+ find_html_encoding = find_html_encoding,
+ load_mapping = load_mapping,
+ recode = recode
+}
+
diff --git a/macros/luatex/generic/luaxml/luaxml-mod-html.lua b/macros/luatex/generic/luaxml/luaxml-mod-html.lua
index 69e32b16e2..d8c2b7e932 100644
--- a/macros/luatex/generic/luaxml/luaxml-mod-html.lua
+++ b/macros/luatex/generic/luaxml/luaxml-mod-html.lua
@@ -1,3 +1,6 @@
+--- HTML parsing module for LuaXML
+-- @module luaxml-mod-html
+-- @author Michal Hoftich <michal.h21@gmail.com
-- Copyright Michal Hoftich, 2022
-- HTML parser inspired by https://browser.engineering/html.html
-- but then redone using https://html.spec.whatwg.org/multipage/parsing.html
@@ -1540,9 +1543,14 @@ local function is_formatting_element(name)
return formatting_element_names[name]
end
-local special_elements = {}
+local function hash_from_array(tbl)
+ local t = {}
+ for _, v in ipairs(tbl) do t[v] = true end
+ return t
+end
+
-local special_elements_list = {"address", "applet", "area", "article", "aside",
+local special_elements_list = hash_from_array {"address", "applet", "area", "article", "aside",
"base", "basefont", "bgsound", "blockquote", "body", "br", "button", "caption",
"center", "col", "colgroup", "dd", "details", "dir", "div", "dl", "dt",
"embed", "fieldset", "figcaption", "figure", "footer", "form", "frame",
@@ -1555,13 +1563,9 @@ local special_elements_list = {"address", "applet", "area", "article", "aside",
"mi","mo","mn","ms","mtext", "annotation-xml","foreignObject","desc", "title"
}
-for k,v in ipairs(special_elements_list) do
- special_elements[v] = true
-end
-
local function is_special(name)
- return special_elements[name]
+ return special_elements_list[name]
end
-- these lists are used in HtmlParser:generate_implied_endtags()
@@ -1649,8 +1653,12 @@ local HtmlTreeStates = {}
+--- @type HtmlParser
local HtmlParser = {}
+--- Initialize the HTML Object
+---@param body string HTML to be parsed
+---@return table initialized object
function HtmlParser:init(body)
local o ={}
setmetatable(o, self)
@@ -1686,10 +1694,11 @@ for _,v in ipairs(self_closing_tags_list) do self_closing_tags[v] = true end
-
+--- Execute the HTML parser
+--- @return table Root node of the HTML DOM
function HtmlParser:parse()
-- we assume utf8 input, you must convert it yourself if the source is
- -- in a different encoding
+ -- in a different encoding. for example using luaxml-encodings library
self.text = {}
self.state = self.default_state
-- this should enable us to pass over some characters that we want to ignore
@@ -1791,6 +1800,7 @@ function HtmlParser:emit(token)
elseif token_type == "start_tag" then
self:add_text()
-- self:start_attribute()
+ self:reset_insertion_mode()
self:start_tag()
-- print("Emit start tag", table.concat(token.name))
-- save last attribute
@@ -1882,8 +1892,139 @@ function HtmlParser:set_xmlns(node, parent)
end
end
+function HtmlParser:pop_element()
+ -- close the current element and add it to the DOM
+ local el = self:close_element()
+ local parent = self:get_parent()
+ parent:add_child(el)
+ return el
+end
+
+local close_p_at_start = hash_from_array {"address", "article", "aside", "blockquote", "center", "details", "dialog", "dir", "div", "dl", "fieldset", "figcaption", "figure", "footer", "header", "hgroup", "main", "menu", "nav", "ol", "p", "search", "section", "summary", "ul", "pre", "listing", "form", "table", "xmp", "hr"}
+
+local close_headers = hash_from_array {"h1", "h2", "h3", "h4", "h5", "h6"}
+
+local body_modes = hash_from_array {"in_body", "in_cell", "in_row", "in_select", "in_table", "in_table_body", "in_frameset"}
+
+local list_items = hash_from_array {"li", "dt", "dd"}
+
+local close_address_at_end = hash_from_array{"address", "article", "aside", "blockquote", "button", "center", "details", "dialog", "dir", "div", "dl", "fieldset", "figcaption", "figure", "footer", "header", "hgroup", "listing", "main", "menu", "nav", "ol", "pre", "search", "section", "summary", "ul", "form"}
+
+
+function HtmlParser:close_unfinished(name)
+ -- close all unfinished elements until the element with the given name is found
+ for i = #self.unfinished, 1, -1 do
+ local el = self:pop_element()
+ if el.tag == name then
+ break
+ end
+ end
+end
+
+
+function HtmlParser:close_paragraph()
+ -- close currently open <p> elements
+ self:close_unfinished("p")
+end
+
+function HtmlParser:current_element_name()
+ -- return name of the current element
+ return self:get_parent().tag
+end
+
+local not_specials = hash_from_array { "address", "div", "p"}
+
+local function handle_list_item(self, name)
+ -- we handle li, dt and dd. dt and dd should close each other, li closes only itself
+ local names = {dt = true, dd = true}
+ if name == "li" then names = {li=true} end
+ for i = #self.unfinished, 1, -1 do
+ local current = self.unfinished[i]
+ local current_tag = current.tag
+ if names[current_tag] then
+ self:generate_implied_endtags(nil, {current.tag})
+ for j = #self.unfinished, i, -1 do
+ self:pop_element()
+ end
+ break
+ elseif is_special(current_tag) and not not_specials[name] then
+ break
+ end
+ end
+end
+
+local close_paragraph = function(self)
+ if is_in_button_scope(self, "p") then
+ self:close_paragraph()
+ end
+end
+
+function HtmlParser:handle_insertion_mode(token)
+ -- simple handling of https://html.spec.whatwg.org/multipage/parsing.html#tree-construction
+ -- we don't support most rules, just the most important for avoiding mismatched tags
+
+ if body_modes[self.insertion_mode] then
+ if token.type == "start_tag" then
+ local name = table.concat(token.name)
+ if close_p_at_start[name] then close_paragraph(self) end
+ if close_headers[name] then
+ close_paragraph(self)
+ -- close current element if it is already header
+ if close_headers[self:current_element_name()] then
+ self:pop_element()
+ end
+ elseif name == "pre" or name == "listing" then
+ -- we should ignore next "\n" char token
+ elseif name == "image" then
+ -- image tag is an error, change to <img>
+ token.name = {"img"}
+ elseif list_items[name] then
+ handle_list_item(self, name)
+ close_paragraph(self)
+ end
+ elseif token.type == "end_tag" then
+ local name = table.concat(token.name)
+ if close_address_at_end[name] then
+ if is_in_scope(self, name, {}) then
+ self:close_unfinished(name)
+ else
+ token.type = "ignore"
+ end
+ elseif name == "p" then
+ if not is_in_button_scope(self, "p") then
+ local parent = self:get_parent()
+ local node = Element:init("p", parent)
+ table.insert(self.unfinished, node)
+ end
+ -- use self:close_paragraph() instead of close_paragraph() because we don't need to check scope at this point
+ self:close_paragraph()
+ elseif name == "br" then
+ token.type = "start_tag"
+ elseif close_headers[name] then
+ local header_in_scope = false
+ -- detect, if there are any open h1-h6 tag and close it
+ for el, _ in pairs(close_headers) do
+ if is_in_scope(self, el, {}) then
+ header_in_scope = el
+ break
+ end
+ end
+ if not header_in_scope then
+ token.type = "ignore"
+ else
+ self:close_unfinished(header_in_scope)
+ end
+ end
+ end
+ end
+end
+
+local rawtext_elements = hash_from_array {"style", "textarea", "xmp"}
+
+
function HtmlParser:start_tag()
local token = self.current_token
+ self:handle_insertion_mode(token)
if token.type == "start_tag" then
-- close all currently opened attributes
self:start_attribute()
@@ -1894,18 +2035,18 @@ function HtmlParser:start_tag()
node.attr = token.attr
node.self_closing = token.self_closing
self:set_xmlns(node)
- --
+ -- in this handler we should close <p> or <li> elements without explicit closing tags
if token.self_closing -- <img />
or self_closing_tags[name] -- void elements
then
- parent:add_child(node)
+ parent:add_child(node, node.tag)
else
-- add to the unfinished list
table.insert(self.unfinished, node)
end
if name == "title" then
self.element_state = "rcdata"
- elseif name == "style" then
+ elseif rawtext_elements[name] then
self.element_state = "rawtext"
elseif name == "script" then
self.element_state = "script_data"
@@ -1916,11 +2057,13 @@ end
function HtmlParser:end_tag()
-- close current opened element
local token = self.current_token
+ self:handle_insertion_mode(token)
if token.type == "end_tag" then
if #self.unfinished==0 then return nil end
- local node = self:close_element()
- local parent = self:get_parent()
- parent:add_child(node)
+ -- close the current element only if the token is in the current scope
+ if is_in_scope(self, table.concat(token.name), {}) then
+ self:pop_element()
+ end
end
end
@@ -1964,6 +2107,21 @@ function HtmlParser:adjusted_current_node()
end
+local simple_modes = {
+ body = "in_body",
+ td = "in_cell",
+ th = "in_cell",
+ tr = "in_row",
+ tbody = "in_table_body",
+ thead = "in_table_body",
+ tfoot = "in_table_body",
+ caption = "in_caption",
+ colgroup = "in_column_group",
+ table = "in_table",
+ template = "current_template_insertion_mode",
+ frameset = "in_frameset"
+}
+
function HtmlParser:reset_insertion_mode()
-- https://html.spec.whatwg.org/multipage/parsing.html#reset-the-insertion-mode-appropriately
local last = false
@@ -1977,16 +2135,33 @@ function HtmlParser:reset_insertion_mode()
if name == "head" and last == true then
self:switch_insertion("in_head")
return
- elseif name == "body" then
- self:switch_insertion("in_body")
- return
elseif name == "html" then
- if self.head_pointer then
+ if not self.head_pointer then
self:switch_insertion("before_head")
return
else
self:switch_insertion("after_head")
+ return
+ end
+ elseif name == "select" then
+ if not last then
+ for x = position -1, 1, -1 do
+ if x == 1 then break end
+ local ancestor = self.unfinished[x]
+ local ancestor_name = ancestor.tag
+ if ancestor_name == "template" then
+ break
+ elseif ancestor_name == "table" then
+ self:switch_insertion("in_select_in_table")
+ return
+ end
+ end
end
+ self:switch_insertion("in_select")
+ return
+ elseif simple_modes[name] then
+ self:switch_insertion(simple_modes[name])
+ return
elseif last == true then
self:switch_insertion("in_body")
return
@@ -2006,8 +2181,8 @@ function HtmlParser:generate_implied_endtags(included, ignored)
local current = self:current_node() or {}
-- keep removing elements while they are in the "included" list
if included[current.tag] then
- table.remove(self.unfinished)
- self:generate_implied_endtags(ignored)
+ self:pop_element()
+ self:generate_implied_endtags(included, ignored)
end
end
@@ -2023,9 +2198,7 @@ function HtmlParser:finish()
self:start_tag("html")
end
while #self.unfinished > 0 do
- local node = self:close_element()
- local parent = self:get_parent()
- parent:add_child(node)
+ self:pop_element()
end
-- return root element
return self.Document -- self:close_element()
diff --git a/macros/luatex/generic/luaxml/luaxml-namedentities.lua b/macros/luatex/generic/luaxml/luaxml-namedentities.lua
index 0e6399ab13..5c5ff00777 100644
--- a/macros/luatex/generic/luaxml/luaxml-namedentities.lua
+++ b/macros/luatex/generic/luaxml/luaxml-namedentities.lua
@@ -1,2234 +1,2233 @@
-local utf8 = require "utf8"
return {
-["Subset"]="⋐",
-["Chi"]="Χ",
-["tprime"]="‴",
-["lneq"]="⪇",
-["RightUpTeeVector"]="⥜",
-["cscr"]="𝒸",
-["leftrightarrows"]="⇆",
-["LeftRightVector"]="⥎",
-["Laplacetrf"]="ℒ",
-["boxHd"]="╤",
-["GreaterSlantEqual"]="⩾",
-["sqsub"]="⊏",
-["nvdash"]="⊬",
-["boxHu"]="╧",
-["vcy"]="в",
-["DiacriticalDoubleAcute"]="˝",
-["nvHarr"]="⤄",
-["lnapprox"]="⪉",
-["fscr"]="𝒻",
-["OverBracket"]="⎴",
-["pm"]="±",
-["ovbar"]="⌽",
-["larrhk"]="↩",
-["atilde"]="ã",
-["Igrave"]="Ì",
-["profsurf"]="⌓",
-["Sigma"]="Σ",
-["rHar"]="⥤",
-["Gcedil"]="Ģ",
-["sect"]="§",
-["nmid"]="∤",
-["escr"]="ℯ",
-["delta"]="δ",
-["male"]="♂",
-["Integral"]="∫",
-["RightUpVectorBar"]="⥔",
-["alefsym"]="ℵ",
-["nsqsube"]="⋢",
-["Nacute"]="Ń",
-["mcomma"]="⨩",
-["ApplyFunction"]=utf8.char(0x2061),
-["rfisht"]="⥽",
-["phmmat"]="ℳ",
-["rarrw"]="↝",
-["backepsilon"]="϶",
-["hscr"]="𝒽",
-["middot"]="·",
-["ldrushar"]="⥋",
-["supne"]="⊋",
-["Longleftrightarrow"]="⟺",
-["Oacute"]="Ó",
-["af"]="⁡",
+["Implies"]="⇒",
+["longrightarrow"]="⟶",
+["precneqq"]="⪵",
+["geqslant"]="⩾",
+["Product"]="∏",
+["Scirc"]="Ŝ",
+["lvnE"]="≨︀",
+["dotminus"]="∸",
+["sscr"]="𝓈",
+["capdot"]="⩀",
+["dlcrop"]="⌍",
+["omacr"]="ō",
+["sext"]="✶",
+["xutri"]="△",
+["xrArr"]="⟹",
+["glE"]="⪒",
+["NotSupersetEqual"]="⊉",
+["backsim"]="∽",
["sup"]="⊃",
-["lozenge"]="◊",
-["scy"]="с",
-["gscr"]="ℊ",
-["smallsetminus"]="∖",
+["realpart"]="ℜ",
["hardcy"]="ъ",
-["DoubleVerticalBar"]="∥",
-["Yuml"]="Ÿ",
-["plusdu"]="⨥",
-["NotSucceedsSlantEqual"]="⋡",
-["nwnear"]="⤧",
-["lfloor"]="⌊",
-["rcy"]="р",
-["jscr"]="𝒿",
-["AMP"]="&",
-["acute"]="´",
-["uacute"]="ú",
-["Or"]="⩔",
-["rdldhar"]="⥩",
-["langd"]="⦑",
-["Iacute"]="Í",
-["spar"]="∥",
-["ucy"]="у",
-["rsh"]="↱",
-["Kcedil"]="Ķ",
-["iscr"]="𝒾",
-["lambda"]="λ",
-["lbrkslu"]="⦍",
-["napE"]="⩰̸",
-["shcy"]="ш",
-["nsupE"]="⫆̸",
-["Ycirc"]="Ŷ",
-["sect"]="§",
-["precnapprox"]="⪹",
-["iocy"]="ё",
-["dzcy"]="џ",
+["sqcap"]="⊓",
+["brvbar"]="¦",
+["LT"]="<",
+["udarr"]="⇅",
+["lozf"]="⧫",
+["Eogon"]="Ę",
+["frac18"]="⅛",
+["lesssim"]="≲",
+["wedbar"]="⩟",
+["EmptyVerySmallSquare"]="▫",
+["aring"]="å",
+["lesdoto"]="⪁",
+["ltquest"]="⩻",
+["LeftUpTeeVector"]="⥠",
+["FilledSmallSquare"]="◼",
+["mho"]="℧",
+["NotGreaterTilde"]="≵",
+["xharr"]="⟷",
+["NotSucceedsEqual"]="⪰̸",
+["sqsupset"]="⊐",
+["Ccedil"]="Ç",
+["aacute"]="á",
+["succcurlyeq"]="≽",
+["gneq"]="⪈",
+["forall"]="∀",
+["rightharpoonup"]="⇀",
+["leftarrow"]="←",
+["ang"]="∠",
+["mapstoup"]="↥",
+["xscr"]="𝓍",
+["NotTildeEqual"]="≄",
+["ograve"]="ò",
+["boxdl"]="┐",
+["DownLeftVectorBar"]="⥖",
+["nsup"]="⊅",
+["shchcy"]="щ",
+["demptyv"]="⦱",
+["apos"]="'",
+["between"]="≬",
+["leftrightsquigarrow"]="↭",
+["gtcc"]="⪧",
+["grave"]="`",
+["bigodot"]="⨀",
+["oline"]="‾",
+["angmsdad"]="⦫",
+["NotCongruent"]="≢",
+["gtquest"]="⩼",
+["fltns"]="▱",
+["smeparsl"]="⧤",
+["Eta"]="Η",
+["ltdot"]="⋖",
+["rhard"]="⇁",
+["rscr"]="𝓇",
["ETH"]="Ð",
-["GreaterTilde"]="≳",
-["coprod"]="∐",
-["rpar"]=")",
-["lthree"]="⋋",
-["ImaginaryI"]="ⅈ",
-["DoubleUpDownArrow"]="⇕",
-["intercal"]="⊺",
-["spadesuit"]="♠",
-["boxVH"]="╬",
-["smashp"]="⨳",
-["nu"]="ν",
-["Agrave"]="À",
-["boxtimes"]="⊠",
-["sext"]="✶",
-["nsub"]="⊄",
-["oelig"]="œ",
-["GreaterEqual"]="≥",
-["TRADE"]="™",
-["dtrif"]="▾",
-["nless"]="≮",
-["mu"]="μ",
-["larrsim"]="⥳",
-["GreaterEqualLess"]="⋛",
-["Uuml"]="Ü",
-["LeftArrowBar"]="⇤",
-["ntrianglerighteq"]="⋭",
-["DiacriticalDot"]="˙",
-["LongLeftArrow"]="⟵",
-["agrave"]="à",
-["lmoustache"]="⎰",
-["nvDash"]="⊭",
-["para"]="¶",
-["nlt"]="≮",
-["Eacute"]="É",
-["spades"]="♠",
-["lrcorner"]="⌟",
-["checkmark"]="✓",
-["lessdot"]="⋖",
-["opar"]="⦷",
-["nVDash"]="⊯",
-["pertenk"]="‱",
-["range"]="⦥",
-["Pr"]="⪻",
-["Gammad"]="Ϝ",
-["ape"]="≊",
-["Longleftarrow"]="⟸",
-["boxV"]="║",
-["rightthreetimes"]="⋌",
+["iocy"]="ё",
+["semi"]=";",
+["nexists"]="∄",
+["approxeq"]="≊",
+["compfn"]="∘",
+["sstarf"]="⋆",
+["angrtvbd"]="⦝",
["gnap"]="⪊",
-["vzigzag"]="⦚",
-["Ecirc"]="Ê",
-["npar"]="∦",
-["notinvb"]="⋷",
-["Tau"]="Τ",
-["blank"]="␣",
-["Kappa"]="Κ",
-["rmoust"]="⎱",
-["GJcy"]="Ѓ",
-["ufisht"]="⥾",
-["NotLeftTriangleBar"]="⧏̸",
-["bigvee"]="⋁",
-["lrhar"]="⇋",
-["supset"]="⊃",
-["uwangle"]="⦧",
-["UpTeeArrow"]="↥",
-["supE"]="⫆",
-["imof"]="⊷",
-["leg"]="⋚",
-["notniva"]="∌",
-["nvgt"]=">⃒",
-["rthree"]="⋌",
-["yfr"]="𝔶",
-["uHar"]="⥣",
-["nshortmid"]="∤",
-["biguplus"]="⨄",
-["barvee"]="⊽",
-["iff"]="⇔",
-["boxvH"]="╪",
-["simrarr"]="⥲",
-["Egrave"]="È",
-["ntilde"]="ñ",
-["VerticalTilde"]="≀",
-["sigmaf"]="ς",
-["khcy"]="х",
-["planck"]="ℏ",
-["NotNestedGreaterGreater"]="⪢̸",
-["NonBreakingSpace"]=" ",
-["OpenCurlyQuote"]="‘",
-["supsim"]="⫈",
-["cudarrl"]="⤸",
-["theta"]="θ",
-["notindot"]="⋵̸",
-["Omicron"]="Ο",
-["ccedil"]="ç",
-["colone"]="≔",
-["bscr"]="𝒷",
-["Dagger"]="‡",
-["comma"]=",",
+["mDDot"]="∺",
+["udblac"]="ű",
["Acirc"]="Â",
-["plankv"]="ℏ",
-["boxdr"]="┌",
-["rarrap"]="⥵",
-["rmoustache"]="⎱",
-["LeftAngleBracket"]="⟨",
-["Cacute"]="Ć",
-["blk34"]="▓",
-["rfloor"]="⌋",
-["awconint"]="∳",
-["sfrown"]="⌢",
-["middot"]="·",
-["ascr"]="𝒶",
-["dot"]="˙",
-["caron"]="ˇ",
-["image"]="ℑ",
-["esdot"]="≐",
-["ohbar"]="⦵",
-["rarrb"]="⇥",
-["submult"]="⫁",
-["plusb"]="⊞",
-["oopf"]="𝕠",
-["breve"]="˘",
-["conint"]="∮",
-["angrt"]="∟",
-["nbump"]="≎̸",
-["raquo"]="»",
-["Iuml"]="Ï",
-["Rcedil"]="Ŗ",
-["minus"]="−",
-["nsucceq"]="⪰̸",
-["telrec"]="⌕",
-["CHcy"]="Ч",
-["nrightarrow"]="↛",
-["NotRightTriangle"]="⋫",
-["zfr"]="𝔷",
-["succ"]="≻",
-["Aacute"]="Á",
-["NestedLessLess"]="≪",
-["RightTeeArrow"]="↦",
-["homtht"]="∻",
-["Cup"]="⋓",
-["lcub"]="{",
-["race"]="∽̱",
-["THORN"]="Þ",
-["propto"]="∝",
-["odblac"]="ő",
-["mumap"]="⊸",
-["filig"]="fi",
-["ecir"]="≖",
-["DoubleRightArrow"]="⇒",
-["npreceq"]="⪯̸",
-["female"]="♀",
-["LeftFloor"]="⌊",
-["gtrarr"]="⥸",
-["dotsquare"]="⊡",
-["map"]="↦",
-["OverBrace"]="⏞",
-["zopf"]="𝕫",
-["rang"]="⟩",
-["laquo"]="«",
-["elsdot"]="⪗",
-["frac56"]="⅚",
-["Iuml"]="Ï",
-["ocirc"]="ô",
-["clubs"]="♣",
-["IOcy"]="Ё",
-["scnE"]="⪶",
-["deg"]="°",
-["simgE"]="⪠",
-["nap"]="≉",
-["blacktriangle"]="▴",
-["edot"]="ė",
-["epsiv"]="ϵ",
-["napprox"]="≉",
-["NotGreaterSlantEqual"]="⩾̸",
-["prap"]="⪷",
-["lnap"]="⪉",
-["circledS"]="Ⓢ",
-["lang"]="⟨",
-["qprime"]="⁗",
-["aelig"]="æ",
-["ncongdot"]="⩭̸",
-["supdsub"]="⫘",
-["nltrie"]="⋬",
-["xopf"]="𝕩",
+["UnderParenthesis"]="⏝",
+["nisd"]="⋺",
+["lneq"]="⪇",
+["Dagger"]="‡",
+["qscr"]="𝓆",
+["gneqq"]="≩",
+["doteqdot"]="≑",
+["DoubleVerticalBar"]="∥",
+["emptyset"]="∅",
+["lEg"]="⪋",
+["subseteq"]="⊆",
+["dwangle"]="⦦",
+["dotplus"]="∔",
+["NotPrecedesSlantEqual"]="⋠",
+["bnot"]="⌐",
["LeftDownVector"]="⇃",
-["duarr"]="⇵",
-["urcorner"]="⌝",
-["nvltrie"]="⊴⃒",
-["Pi"]="Π",
+["leg"]="⋚",
+["Therefore"]="∴",
+["Omega"]="Ω",
+["acE"]="∾̳",
+["Auml"]="Ä",
+["xvee"]="⋁",
["Eacute"]="É",
-["nGtv"]="≫̸",
-["icirc"]="î",
-["twoheadleftarrow"]="↞",
+["LeftFloor"]="⌊",
+["swnwar"]="⤪",
+["Jukcy"]="Є",
+["nless"]="≮",
+["NotSquareSupersetEqual"]="⋣",
+["larrfs"]="⤝",
+["gcy"]="г",
+["solbar"]="⌿",
+["rharul"]="⥬",
+["dscy"]="ѕ",
+["yen"]="¥",
+["ForAll"]="∀",
+["DownArrow"]="↓",
+["qprime"]="⁗",
+["NegativeThickSpace"]="​",
+["part"]="∂",
+["Iukcy"]="І",
+["ltcc"]="⪦",
+["xlArr"]="⟸",
+["fcy"]="ф",
+["gl"]="≷",
+["rsh"]="↱",
+["lrhar"]="⇋",
["divide"]="÷",
-["yopf"]="𝕪",
-["ntlg"]="≸",
-["Darr"]="↡",
+["bemptyv"]="⦰",
+["rx"]="℞",
+["ecy"]="э",
+["ApplyFunction"]="⁡",
+["divideontimes"]="⋇",
+["prod"]="∏",
+["boxHU"]="╩",
+["HARDcy"]="Ъ",
+["mstpos"]="∾",
+["llcorner"]="⌞",
+["rsquor"]="’",
+["NotTildeFullEqual"]="≇",
+["mlcp"]="⫛",
+["cemptyv"]="⦲",
+["Proportional"]="∝",
+["DiacriticalDoubleAcute"]="˝",
+["dcy"]="д",
+["Yacute"]="Ý",
+["egsdot"]="⪘",
["hslash"]="ℏ",
-["Coproduct"]="∐",
-["profline"]="⌒",
-["imagline"]="ℐ",
-["chcy"]="ч",
-["ccedil"]="ç",
-["PrecedesEqual"]="⪯",
-["jcirc"]="ĵ",
-["nang"]="∠⃒",
-["Icirc"]="Î",
-["nbumpe"]="≏̸",
-["incare"]="℅",
-["tint"]="∭",
-["nhArr"]="⇎",
-["emsp13"]=" ",
-["blacktriangleleft"]="◂",
-["Star"]="⋆",
-["hkswarow"]="⤦",
-["NegativeThickSpace"]="​",
-["eDot"]="≑",
-["Euml"]="Ë",
-["scaron"]="š",
-["RightDownVectorBar"]="⥕",
-["cent"]="¢",
-["jukcy"]="є",
-["backsimeq"]="⋍",
-["Ncy"]="Н",
-["DD"]="ⅅ",
-["circledast"]="⊛",
-["ccirc"]="ĉ",
-["rsaquo"]="›",
-["YIcy"]="Ї",
-["iquest"]="¿",
-["NotExists"]="∄",
-["iukcy"]="і",
-["Tab"]=" ",
-["Equilibrium"]="⇌",
-["nLt"]="≪⃒",
-["yen"]="¥",
-["CircleDot"]="⊙",
-["CircleMinus"]="⊖",
-["topf"]="𝕥",
-["equivDD"]="⩸",
-["DoubleLeftRightArrow"]="⇔",
-["ngsim"]="≵",
-["upuparrows"]="⇈",
-["ll"]="≪",
-["cirscir"]="⧂",
-["ShortLeftArrow"]="←",
-["angmsdag"]="⦮",
-["shortmid"]="∣",
-["ngeqslant"]="⩾̸",
-["subset"]="⊂",
-["curvearrowleft"]="↶",
-["gdot"]="ġ",
-["circledcirc"]="⊚",
-["Pcy"]="П",
-["asymp"]="≈",
-["boxUr"]="╙",
-["uopf"]="𝕦",
-["frac15"]="⅕",
-["Iacute"]="Í",
-["Utilde"]="Ũ",
-["Congruent"]="≡",
-["nhpar"]="⫲",
-["capbrcup"]="⩉",
-["ordf"]="ª",
-["SOFTcy"]="Ь",
-["nlArr"]="⇍",
-["not"]="¬",
-["ffllig"]="ffl",
-["nprec"]="⊀",
-["Hat"]="^",
+["infin"]="∞",
["Auml"]="Ä",
-["ntriangleleft"]="⋪",
-["longmapsto"]="⟼",
-["nvrtrie"]="⊵⃒",
-["timesb"]="⊠",
-["lsh"]="↰",
-["Jcy"]="Й",
-["gcirc"]="ĝ",
-["Oacute"]="Ó",
-["vartriangleright"]="⊳",
-["NotRightTriangleEqual"]="⋭",
-["Rightarrow"]="⇒",
-["ast"]="*",
-["hamilt"]="ℋ",
-["Ncedil"]="Ņ",
-["apE"]="⩰",
-["macr"]="¯",
-["cwconint"]="∲",
-["Kcy"]="К",
-["Ucirc"]="Û",
-["hcirc"]="ĥ",
-["yacy"]="я",
-["uml"]="¨",
-["popf"]="𝕡",
-["bumpE"]="⪮",
-["varnothing"]="∅",
-["RightUpVector"]="↾",
-["curren"]="¤",
-["Scedil"]="Ş",
-["FilledVerySmallSquare"]="▪",
-["dollar"]="$",
-["Lcy"]="Л",
-["longrightarrow"]="⟶",
-["LeftTee"]="⊣",
-["excl"]="!",
-["acirc"]="â",
-["wp"]="℘",
-["lcaron"]="ľ",
-["NotGreaterFullEqual"]="≧̸",
-["CounterClockwiseContourIntegral"]="∳",
-["sup2"]="²",
-["rnmid"]="⫮",
-["Lcedil"]="Ļ",
-["ddotseq"]="⩷",
-["tbrk"]="⎴",
-["mlcp"]="⫛",
-["rarrhk"]="↪",
-["Tilde"]="∼",
-["Mcy"]="М",
-["aring"]="å",
-["rarrsim"]="⥴",
-["nopf"]="𝕟",
-["aelig"]="æ",
-["order"]="ℴ",
-["diamondsuit"]="♦",
-["nvsim"]="∼⃒",
-["lhard"]="↽",
-["commat"]="@",
-["qint"]="⨌",
-["lsquo"]="‘",
-["sqcaps"]="⊓︀",
-["circlearrowleft"]="↺",
-["NotElement"]="∉",
-["measuredangle"]="∡",
-["Atilde"]="Ã",
-["CapitalDifferentialD"]="ⅅ",
-["kgreen"]="ĸ",
-["Cscr"]="𝒞",
+["Wcirc"]="Ŵ",
+["larrtl"]="↢",
+["Aacute"]="Á",
+["LeftTriangleEqual"]="⊴",
+["NegativeMediumSpace"]="​",
+["TripleDot"]="⃛",
+["utdot"]="⋰",
+["isinv"]="∈",
+["looparrowright"]="↬",
+["loang"]="⟬",
+["multimap"]="⊸",
["NotLessEqual"]="≰",
-["trpezium"]="⏢",
-["ne"]="≠",
-["NotSuperset"]="⊃⃒",
-["nearrow"]="↗",
-["ncong"]="≇",
-["doteqdot"]="≑",
-["supmult"]="⫂",
-["longleftrightarrow"]="⟷",
-["Rarr"]="↠",
-["DoubleUpArrow"]="⇑",
-["Dscr"]="𝒟",
-["mp"]="∓",
-["jmath"]="ȷ",
-["erarr"]="⥱",
-["searrow"]="↘",
-["Sup"]="⋑",
-["lvnE"]="≨︀",
-["ffilig"]="ffi",
-["NotSquareSupersetEqual"]="⋣",
-["bullet"]="•",
-["bigstar"]="★",
-["cylcty"]="⌭",
-["nvle"]="≤⃒",
-["TildeFullEqual"]="≅",
-["lopf"]="𝕝",
-["sqsupseteq"]="⊒",
-["lt"]="<",
-["geqslant"]="⩾",
+["midcir"]="⫰",
+["nge"]="≱",
["quot"]="\"",
-["le"]="≤",
-["square"]="□",
-["sigma"]="σ",
-["prE"]="⪳",
-["rtrie"]="⊵",
-["triangleq"]="≜",
+["REG"]="®",
+["div"]="÷",
+["complexes"]="ℂ",
+["lhblk"]="▄",
+["gvnE"]="≩︀",
+["leftharpoonup"]="↼",
+["it"]="⁢",
+["clubsuit"]="♣",
+["iff"]="⇔",
+["Hacek"]="ˇ",
+["CircleTimes"]="⊗",
+["Cacute"]="Ć",
+["rarrtl"]="↣",
+["RightDownVector"]="⇂",
+["rarrfs"]="⤞",
+["UpArrowBar"]="⤒",
+["male"]="♂",
+["RightTriangle"]="⊳",
+["GreaterTilde"]="≳",
+["Barwed"]="⌆",
+["ltlarr"]="⥶",
+["Zdot"]="Ż",
+["parsim"]="⫳",
+["Ugrave"]="Ù",
+["Dot"]="¨",
+["circleddash"]="⊝",
+["rsaquo"]="›",
+["hyphen"]="‐",
+["angrt"]="∟",
+["RightTriangleEqual"]="⊵",
+["Darr"]="↡",
+["ulcrop"]="⌏",
+["olcir"]="⦾",
+["gimel"]="ℷ",
+["gel"]="⋛",
+["SquareSubset"]="⊏",
+["Uacute"]="Ú",
+["gt"]=">",
+["lnap"]="⪉",
+["Union"]="⋃",
+["nu"]="ν",
+["and"]="∧",
+["ltcir"]="⩹",
["Fscr"]="ℱ",
+["ee"]="ⅇ",
+["laquo"]="«",
+["Hfr"]="ℌ",
+["prec"]="≺",
+["imagline"]="ℐ",
+["precnsim"]="⋨",
+["zhcy"]="ж",
+["mu"]="μ",
+["rlarr"]="⇄",
+["pound"]="£",
+["origof"]="⊶",
+["rfloor"]="⌋",
+["lnsim"]="⋦",
+["nVdash"]="⊮",
+["otimes"]="⊗",
+["iuml"]="ï",
+["Cscr"]="𝒞",
+["lsime"]="⪍",
+["ngeqq"]="≧̸",
+["Del"]="∇",
+["Coproduct"]="∐",
+["NotSubsetEqual"]="⊈",
+["HilbertSpace"]="ℋ",
+["frac58"]="⅝",
+["cap"]="∩",
+["roang"]="⟭",
+["intlarhk"]="⨗",
+["DownTee"]="⊤",
+["thickapprox"]="≈",
+["prnap"]="⪹",
+["laquo"]="«",
+["lesdot"]="⩿",
+["inodot"]="ı",
+["Hscr"]="ℋ",
+["YIcy"]="Ї",
+["ctdot"]="⋯",
+["thetav"]="ϑ",
+["DoubleUpDownArrow"]="⇕",
+["succ"]="≻",
+["nbumpe"]="≏̸",
+["ReverseElement"]="∋",
+["Oacute"]="Ó",
+["equest"]="≟",
+["Lt"]="≪",
+["Nacute"]="Ń",
["DiacriticalTilde"]="˜",
-["SucceedsSlantEqual"]="≽",
-["mopf"]="𝕞",
-["Ecaron"]="Ě",
-["UpArrowDownArrow"]="⇅",
-["ges"]="⩾",
-["nsqsupe"]="⋣",
-["ubrcy"]="ў",
-["Gscr"]="𝒢",
-["HARDcy"]="Ъ",
-["jopf"]="𝕛",
-["gtquest"]="⩼",
-["iinfin"]="⧜",
-["twixt"]="≬",
+["Escr"]="ℰ",
+["boxvH"]="╪",
+["Ifr"]="ℑ",
+["mp"]="∓",
+["ell"]="ℓ",
+["Iacute"]="Í",
+["NotNestedGreaterGreater"]="⪢̸",
+["raquo"]="»",
+["Zcy"]="З",
+["micro"]="µ",
+["dzigrarr"]="⟿",
+["rtrif"]="▸",
+["Uuml"]="Ü",
+["nvHarr"]="⤄",
+["leqslant"]="⩽",
+["tritime"]="⨻",
+["nlarr"]="↚",
+["NotRightTriangle"]="⋫",
+["apid"]="≋",
+["succeq"]="⪰",
+["NotEqualTilde"]="≂̸",
+["varphi"]="ϕ",
+["Vert"]="‖",
+["int"]="∫",
+["lurdshar"]="⥊",
+["lneqq"]="≨",
+["Jsercy"]="Ј",
+["Superset"]="⊃",
+["subsetneqq"]="⫋",
+["gap"]="⪆",
+["ssmile"]="⌣",
+["Ugrave"]="Ù",
+["IOcy"]="Ё",
+["ltimes"]="⋉",
+["UnderBracket"]="⎵",
+["subseteqq"]="⫅",
+["Dscr"]="𝒟",
+["dtrif"]="▾",
+["raquo"]="»",
+["hbar"]="ℏ",
+["ge"]="≥",
+["cudarrr"]="⤵",
+["icy"]="и",
+["plusdo"]="∔",
+["bull"]="•",
+["weierp"]="℘",
+["mapsto"]="↦",
+["Uring"]="Ů",
+["supplus"]="⫀",
+["Succeeds"]="≻",
+["Ascr"]="𝒜",
+["cdot"]="ċ",
+["nwarr"]="↖",
+["target"]="⌖",
+["dharr"]="⇂",
+["curlyvee"]="⋎",
+["supE"]="⫆",
+["emsp13"]=" ",
["ltrie"]="⊴",
+["olarr"]="↺",
+["RightTeeVector"]="⥛",
+["Vvdash"]="⊪",
+["larrsim"]="⥳",
+["varsubsetneq"]="⊊︀",
+["Not"]="⫬",
+["CenterDot"]="·",
+["PlusMinus"]="±",
+["aring"]="å",
+["Nscr"]="𝒩",
+["delta"]="δ",
+["npre"]="⪯̸",
+["Vcy"]="В",
+["NotVerticalBar"]="∤",
+["scpolint"]="⨓",
+["rcedil"]="ŗ",
+["Lmidot"]="Ŀ",
+["DScy"]="Ѕ",
+["nsubseteq"]="⊈",
+["ngE"]="≧̸",
+["NotSquareSubsetEqual"]="⋢",
+["edot"]="ė",
+["Ucy"]="У",
+["lessapprox"]="⪅",
+["niv"]="∋",
+["Kscr"]="𝒦",
+["LeftVectorBar"]="⥒",
+["nhpar"]="⫲",
+["scedil"]="ş",
+["Uacute"]="Ú",
+["ntrianglelefteq"]="⋬",
+["Otilde"]="Õ",
+["iexcl"]="¡",
+["lbrke"]="⦋",
+["simdot"]="⩪",
+["sigmaf"]="ς",
+["Bfr"]="𝔅",
+["pitchfork"]="⋔",
+["ngeqslant"]="⩾̸",
+["Pscr"]="𝒫",
+["gsime"]="⪎",
+["Ouml"]="Ö",
+["rarrsim"]="⥴",
+["subE"]="⫅",
+["otimesas"]="⨶",
+["lfloor"]="⌊",
+["prop"]="∝",
+["imacr"]="ī",
+["blacktriangleleft"]="◂",
+["Ntilde"]="Ñ",
+["llarr"]="⇇",
+["nsucc"]="⊁",
+["PartialD"]="∂",
+["Iacute"]="Í",
+["gdot"]="ġ",
+["Afr"]="𝔄",
+["Igrave"]="Ì",
["csub"]="⫏",
-["Hscr"]="ℋ",
-["leftharpoondown"]="↽",
+["Mscr"]="ℳ",
+["Scy"]="С",
+["bsime"]="⋍",
+["nequiv"]="≢",
+["scnap"]="⪺",
+["Tab"]=" ",
+["Equal"]="⩵",
+["blacklozenge"]="⧫",
+["nrarrc"]="⤳̸",
+["divide"]="÷",
["RightUpDownVector"]="⥏",
-["LongLeftRightArrow"]="⟷",
-["Im"]="ℑ",
-["dcaron"]="ď",
+["iinfin"]="⧜",
+["precnapprox"]="⪹",
+["dArr"]="⇓",
+["orslope"]="⩗",
+["Rcy"]="Р",
+["sqsub"]="⊏",
+["OverBracket"]="⎴",
+["sum"]="∑",
+["ncedil"]="ņ",
+["ltrPar"]="⦖",
+["ii"]="ⅈ",
+["Gcirc"]="Ĝ",
+["SucceedsTilde"]="≿",
+["RightFloor"]="⌋",
+["osol"]="⊘",
["barwedge"]="⌅",
-["nexist"]="∄",
-["blacktriangledown"]="▾",
-["fork"]="⋔",
-["rhard"]="⇁",
-["cent"]="¢",
-["RightTriangle"]="⊳",
-["Eta"]="Η",
-["dotminus"]="∸",
-["nles"]="⩽̸",
-["larrtl"]="↢",
-["LeftTriangleEqual"]="⊴",
-["hopf"]="𝕙",
-["gammad"]="ϝ",
-["gsime"]="⪎",
-["llhard"]="⥫",
-["precapprox"]="⪷",
-["profalar"]="⌮",
-["lnE"]="≨",
-["ddagger"]="‡",
-["leq"]="≤",
-["smile"]="⌣",
-["robrk"]="⟧",
-["Jscr"]="𝒥",
-["triangleleft"]="◃",
-["acd"]="∿",
-["prod"]="∏",
-["atilde"]="ã",
-["seArr"]="⇘",
-["therefore"]="∴",
-["iopf"]="𝕚",
-["solbar"]="⌿",
-["kcedil"]="ķ",
-["NotHumpEqual"]="≏̸",
-["nspar"]="∦",
-["frac14"]="¼",
-["nsime"]="≄",
-["DoubleLongLeftArrow"]="⟸",
-["sccue"]="≽",
-["models"]="⊧",
-["SupersetEqual"]="⊇",
-["iquest"]="¿",
-["oline"]="‾",
-["lparlt"]="⦓",
-["triplus"]="⨹",
-["nequiv"]="≢",
-["nlE"]="≦̸",
-["nldr"]="‥",
-["equals"]="=",
-["Agrave"]="À",
-["ccaron"]="č",
-["Yacute"]="Ý",
-["Oslash"]="Ø",
-["udarr"]="⇅",
-["ang"]="∠",
-["dopf"]="𝕕",
-["comp"]="∁",
-["caps"]="∩︀",
-["bowtie"]="⋈",
-["glj"]="⪤",
-["ltquest"]="⩻",
-["cirmid"]="⫯",
-["ordm"]="º",
-["esim"]="≂",
-["reals"]="ℝ",
-["LeftTriangle"]="⊲",
-["flat"]="♭",
-["eopf"]="𝕖",
-["lap"]="⪅",
-["not"]="¬",
-["ENG"]="Ŋ",
-["DiacriticalAcute"]="´",
-["sharp"]="♯",
-["longleftarrow"]="⟵",
-["dblac"]="˝",
-["UpArrow"]="↑",
-["npre"]="⪯̸",
-["bopf"]="𝕓",
-["DScy"]="Ѕ",
+["twoheadrightarrow"]="↠",
+["Gscr"]="𝒢",
+["acy"]="а",
+["dtdot"]="⋱",
+["rbrke"]="⦌",
+["imath"]="ı",
+["Hcirc"]="Ĥ",
+["num"]="#",
+["nprec"]="⊀",
+["smallsetminus"]="∖",
+["lesges"]="⪓",
+["LeftUpVector"]="↿",
+["gtdot"]="⋗",
+["theta"]="θ",
+["kappav"]="ϰ",
+["jmath"]="ȷ",
+["Lscr"]="ℒ",
+["Aogon"]="Ą",
+["ltrif"]="◂",
+["DownArrowUpArrow"]="⇵",
+["prap"]="⪷",
+["Racute"]="Ŕ",
+["curlyeqprec"]="⋞",
["bepsi"]="϶",
-["angrtvb"]="⊾",
-["ccaps"]="⩍",
-["UnderParenthesis"]="⏝",
-["subne"]="⊊",
-["succnsim"]="⋩",
-["Bumpeq"]="≎",
-["xvee"]="⋁",
-["colon"]=":",
-["deg"]="°",
-["fnof"]="ƒ",
-["Uarr"]="↟",
-["Zcaron"]="Ž",
-["copf"]="𝕔",
-["Theta"]="Θ",
-["omicron"]="ο",
-["ntriangleright"]="⋫",
-["DoubleLongRightArrow"]="⟹",
-["UnderBrace"]="⏟",
-["GT"]=">",
-["lEg"]="⪋",
-["supplus"]="⫀",
-["acute"]="´",
+["blacktriangle"]="▴",
+["nvap"]="≍⃒",
+["Supset"]="⋑",
+["angmsd"]="∡",
+["boxul"]="┘",
+["LessSlantEqual"]="⩽",
["GT"]=">",
-["upsilon"]="υ",
-["sc"]="≻",
-["xrarr"]="⟶",
-["eng"]="ŋ",
-["it"]="⁢",
-["Ntilde"]="Ñ",
-["Mu"]="Μ",
-["CircleTimes"]="⊗",
-["NotTildeTilde"]="≉",
-["NotLessLess"]="≪̸",
-["vellip"]="⋮",
-["cularrp"]="⤽",
-["UnderBracket"]="⎵",
-["aopf"]="𝕒",
-["itilde"]="ĩ",
-["latail"]="⤙",
-["Nu"]="Ν",
-["Ascr"]="𝒜",
-["complement"]="∁",
-["gjcy"]="ѓ",
-["radic"]="√",
-["maltese"]="✠",
-["glE"]="⪒",
-["plusmn"]="±",
-["curvearrowright"]="↷",
-["gt"]=">",
-["Colone"]="⩴",
-["Bscr"]="ℬ",
-["ic"]="⁣",
-["clubsuit"]="♣",
-["djcy"]="ђ",
-["Oopf"]="𝕆",
-["ltrPar"]="⦖",
-["ngtr"]="≯",
-["eqcirc"]="≖",
-["Hacek"]="ˇ",
-["vdash"]="⊢",
-["NotCupCap"]="≭",
-["Gdot"]="Ġ",
-["jsercy"]="ј",
-["marker"]="▮",
+["nexist"]="∄",
+["ccupssm"]="⩐",
+["Eacute"]="É",
+["ddarr"]="⇊",
+["ntlg"]="≸",
+["Iscr"]="ℐ",
+["Jcirc"]="Ĵ",
+["Sacute"]="Ś",
+["capand"]="⩄",
+["gesdoto"]="⪂",
+["olcross"]="⦻",
+["amalg"]="⨿",
+["rarrlp"]="↬",
+["NotLeftTriangle"]="⋪",
+["reals"]="ℝ",
+["bigcup"]="⋃",
+["NJcy"]="Њ",
+["Odblac"]="Ő",
+["hArr"]="⇔",
+["RightArrowLeftArrow"]="⇄",
+["SOFTcy"]="Ь",
+["Lambda"]="Λ",
+["RightCeiling"]="⌉",
+["Vdash"]="⊩",
+["elinters"]="⏧",
+["lsimg"]="⪏",
["Nopf"]="ℕ",
-["Wfr"]="𝔚",
-["boxHD"]="╦",
-["mho"]="℧",
-["ulcrop"]="⌏",
-["DifferentialD"]="ⅆ",
-["aacute"]="á",
-["lpar"]="(",
+["Esim"]="⩳",
+["vzigzag"]="⦚",
+["acd"]="∿",
+["ccedil"]="ç",
+["lbarr"]="⤌",
+["nmid"]="∤",
+["Backslash"]="∖",
+["Laplacetrf"]="ℒ",
+["npr"]="⊀",
+["nap"]="≉",
+["nsupseteqq"]="⫆̸",
+["igrave"]="ì",
+["LJcy"]="Љ",
+["lessgtr"]="≶",
["angle"]="∠",
-["rharu"]="⇀",
-["Breve"]="˘",
-["Dot"]="¨",
-["rect"]="▭",
-["NotNestedLessLess"]="⪡̸",
-["boxplus"]="⊞",
-["NotSucceeds"]="⊁",
-["gnapprox"]="⪊",
-["DownLeftTeeVector"]="⥞",
-["Xfr"]="𝔛",
-["Lang"]="⟪",
-["Element"]="∈",
-["sung"]="♪",
-["RightVectorBar"]="⥓",
-["simne"]="≆",
-["LeftVector"]="↼",
-["Idot"]="İ",
+["lAarr"]="⇚",
+["notin"]="∉",
+["orv"]="⩛",
+["gtreqqless"]="⪌",
+["CircleMinus"]="⊖",
+["Diamond"]="⋄",
+["map"]="↦",
+["nvsim"]="∼⃒",
+["pi"]="π",
+["pluscir"]="⨢",
+["boxVH"]="╬",
["QUOT"]="\"",
-["nsmid"]="∤",
-["fjlig"]="fj",
-["Ufr"]="𝔘",
-["cuvee"]="⋎",
+["duarr"]="⇵",
+["lgE"]="⪑",
+["lmoust"]="⎰",
+["lsquo"]="‘",
+["rightrightarrows"]="⇉",
+["times"]="×",
+["iuml"]="ï",
+["andslope"]="⩘",
+["order"]="ℴ",
+["Sub"]="⋐",
+["capcap"]="⩋",
+["nabla"]="∇",
+["ntriangleleft"]="⋪",
+["blk14"]="░",
+["Kopf"]="𝕂",
+["lArr"]="⇐",
+["Qopf"]="ℚ",
+["circledS"]="Ⓢ",
+["omid"]="⦶",
+["ord"]="⩝",
+["lvertneqq"]="≨︀",
+["updownarrow"]="↕",
+["yacute"]="ý",
+["ni"]="∋",
+["hamilt"]="ℋ",
+["Jopf"]="𝕁",
+["CupCap"]="≍",
+["lbrack"]="[",
+["preccurlyeq"]="≼",
+["Ropf"]="ℝ",
+["lessdot"]="⋖",
+["blank"]="␣",
+["SucceedsEqual"]="⪰",
+["triangleleft"]="◃",
+["ring"]="˚",
+["omega"]="ω",
+["bowtie"]="⋈",
+["Sqrt"]="√",
+["uuml"]="ü",
+["Udblac"]="Ű",
+["diams"]="♦",
+["Oslash"]="Ø",
["real"]="ℜ",
-["luruhar"]="⥦",
-["NotRightTriangleBar"]="⧐̸",
-["target"]="⌖",
-["lharu"]="↼",
-["CloseCurlyQuote"]="’",
-["rAtail"]="⤜",
-["nparallel"]="∦",
-["brvbar"]="¦",
-["Vfr"]="𝔙",
-["wedbar"]="⩟",
-["REG"]="®",
-["boxur"]="└",
-["Rcaron"]="Ř",
-["Rang"]="⟫",
-["sqsubseteq"]="⊑",
-["div"]="÷",
-["boxul"]="┘",
-["Cdot"]="Ċ",
-["vsupnE"]="⫌︀",
-["zeetrf"]="ℨ",
-["Sfr"]="𝔖",
-["roang"]="⟭",
-["LessTilde"]="≲",
-["equiv"]="≡",
-["frac12"]="½",
-["eacute"]="é",
-["rrarr"]="⇉",
-["nearhk"]="⤤",
-["Zopf"]="ℤ",
-["SucceedsTilde"]="≿",
+["egrave"]="è",
+["prurel"]="⊰",
+["LeftUpDownVector"]="⥑",
+["TildeEqual"]="≃",
+["cuwed"]="⋏",
+["times"]="×",
["ap"]="≈",
-["lfisht"]="⥼",
-["timesd"]="⨰",
-["UpDownArrow"]="↕",
-["xuplus"]="⨄",
-["cularr"]="↶",
-["iprod"]="⨼",
-["AElig"]="Æ",
-["rationals"]="ℚ",
-["geqq"]="≧",
-["Tfr"]="𝔗",
-["Yopf"]="𝕐",
-["rtimes"]="⋊",
-["Tcaron"]="Ť",
-["srarr"]="→",
-["diam"]="⋄",
-["mid"]="∣",
-["imath"]="ı",
-["PlusMinus"]="±",
-["isin"]="∈",
-["vprop"]="∝",
-["RightArrowLeftArrow"]="⇄",
-["NotSubset"]="⊂⃒",
-["bigtriangledown"]="▽",
-["ldsh"]="↲",
-["Qfr"]="𝔔",
-["nvap"]="≍⃒",
-["vert"]="|",
-["Xopf"]="𝕏",
-["lBarr"]="⤎",
-["egsdot"]="⪘",
-["Tcedil"]="Ţ",
-["xi"]="ξ",
-["LeftUpVectorBar"]="⥘",
-["circ"]="ˆ",
-["ocir"]="⊚",
-["gtlPar"]="⦕",
-["Rfr"]="ℜ",
-["RightTriangleBar"]="⧐",
-["nwarhk"]="⤣",
-["zhcy"]="ж",
-["Iukcy"]="І",
-["plusdo"]="∔",
+["lowast"]="∗",
+["Lopf"]="𝕃",
+["bdquo"]="„",
+["blacktriangledown"]="▾",
+["vBarv"]="⫩",
+["Longleftarrow"]="⟸",
+["lesg"]="⋚︀",
+["Popf"]="ℙ",
+["iogon"]="į",
+["vellip"]="⋮",
+["Ntilde"]="Ñ",
+["cwconint"]="∲",
["boxv"]="│",
-["minusb"]="⊟",
-["Ncaron"]="Ň",
-["angmsdaa"]="⦨",
-["varsubsetneqq"]="⫋︀",
-["cirfnint"]="⨐",
-["LongRightArrow"]="⟶",
-["ddarr"]="⇊",
-["piv"]="ϖ",
-["fopf"]="𝕗",
-["Ofr"]="𝔒",
-["fflig"]="ff",
-["Jukcy"]="Є",
-["xhArr"]="⟺",
-["ncy"]="н",
-["Scaron"]="Š",
-["TildeEqual"]="≃",
-["subrarr"]="⥹",
-["iacute"]="í",
-["ogt"]="⧁",
-["nvge"]="≥⃒",
-["vee"]="∨",
-["UnderBar"]="_",
-["andslope"]="⩘",
-["gopf"]="𝕘",
-["Pfr"]="𝔓",
-["die"]="¨",
+["boxbox"]="⧉",
+["langd"]="⦑",
+["diam"]="⋄",
+["boxHu"]="╧",
+["acute"]="´",
["Uopf"]="𝕌",
+["Fcy"]="Ф",
+["vee"]="∨",
+["eqslantless"]="⪕",
+["NotLeftTriangleEqual"]="⋬",
+["OverBrace"]="⏞",
+["beta"]="β",
+["Otilde"]="Õ",
+["fjlig"]="fj",
+["uacute"]="ú",
+["CirclePlus"]="⊕",
+["Mellintrf"]="ℳ",
+["Vopf"]="𝕍",
+["Gcy"]="Г",
+["searhk"]="⤥",
+["boxur"]="└",
+["LeftTeeVector"]="⥚",
+["nsubE"]="⫅̸",
+["gvertneqq"]="≩︀",
+["eqcirc"]="≖",
+["nrightarrow"]="↛",
+["DJcy"]="Ђ",
+["tdot"]="⃛",
+["Dcy"]="Д",
+["Sopf"]="𝕊",
+["range"]="⦥",
+["agrave"]="à",
+["gtrsim"]="≳",
["RightArrowBar"]="⇥",
-["orarr"]="↻",
-["Precedes"]="≺",
-["oror"]="⩖",
-["straightepsilon"]="ϵ",
-["cong"]="≅",
-["TScy"]="Ц",
-["nleftarrow"]="↚",
-["DZcy"]="Џ",
-["horbar"]="―",
+["larrlp"]="↫",
+["le"]="≤",
+["xi"]="ξ",
+["gla"]="⪥",
+["GT"]=">",
+["leftarrowtail"]="↢",
+["commat"]="@",
+["rightarrowtail"]="↣",
+["approx"]="≈",
+["sdot"]="⋅",
["Topf"]="𝕋",
-["Cayleys"]="ℭ",
-["leqq"]="≦",
-["curlyeqprec"]="⋞",
-["nLeftarrow"]="⇍",
-["pcy"]="п",
-["realine"]="ℛ",
-["nlsim"]="≴",
+["Ecy"]="Э",
+["eplus"]="⩱",
+["cir"]="○",
["Rarrtl"]="⤖",
-["CupCap"]="≍",
-["vDash"]="⊨",
-["shortparallel"]="∥",
-["ExponentialE"]="ⅇ",
-["Sopf"]="𝕊",
-["iiota"]="℩",
-["Nfr"]="𝔑",
-["pointint"]="⨕",
-["NotGreaterLess"]="≹",
-["olcross"]="⦻",
-["kcy"]="к",
-["complexes"]="ℂ",
-["varepsilon"]="ϵ",
-["Fouriertrf"]="ℱ",
-["rho"]="ρ",
-["Lsh"]="↰",
-["exponentiale"]="ⅇ",
-["hookrightarrow"]="↪",
-["Ropf"]="ℝ",
-["lAtail"]="⤛",
-["Kfr"]="𝔎",
-["bsim"]="∽",
-["jcy"]="й",
-["frac34"]="¾",
-["DotDot"]="⃜",
+["Emacr"]="Ē",
+["Dcaron"]="Ď",
+["Sc"]="⪼",
+["cent"]="¢",
+["rtri"]="▹",
+["cedil"]="¸",
+["spades"]="♠",
+["upsilon"]="υ",
+["boxminus"]="⊟",
+["angmsdaa"]="⦨",
+["zdot"]="ż",
+["Bcy"]="Б",
+["Zscr"]="𝒵",
+["looparrowleft"]="↫",
+["Dfr"]="𝔇",
+["Bumpeq"]="≎",
+["nLeftarrow"]="⇍",
+["equiv"]="≡",
+["Ccaron"]="Č",
+["UpperLeftArrow"]="↖",
+["SubsetEqual"]="⊆",
+["nrArr"]="⇏",
+["loarr"]="⇽",
+["minusdu"]="⨪",
+["sup3"]="³",
+["Zopf"]="ℤ",
+["elsdot"]="⪗",
+["NotLessLess"]="≪̸",
+["eta"]="η",
+["ubrcy"]="ў",
+["Yscr"]="𝒴",
+["subset"]="⊂",
+["Cfr"]="ℭ",
+["harrcir"]="⥈",
+["supsetneq"]="⊋",
+["LeftUpVectorBar"]="⥘",
+["LT"]="<",
+["DoubleLeftArrow"]="⇐",
+["circledcirc"]="⊚",
+["bkarow"]="⤍",
+["rangd"]="⦒",
+["downharpoonright"]="⇂",
+["Wopf"]="𝕎",
+["ast"]="*",
+["planck"]="ℏ",
+["gtrdot"]="⋗",
+["Ffr"]="𝔉",
+["rArr"]="⇒",
+["VeryThinSpace"]=" ",
+["Ecaron"]="Ě",
+["RightVectorBar"]="⥓",
+["divonx"]="⋇",
+["Xopf"]="𝕏",
+["nsubset"]="⊂⃒",
+["Otimes"]="⨷",
+["bot"]="⊥",
+["nsime"]="≄",
["thorn"]="þ",
-["ThickSpace"]="  ",
-["SquareUnion"]="⊔",
-["frac58"]="⅝",
-["dfisht"]="⥿",
-["MediumSpace"]=" ",
-["Lfr"]="𝔏",
-["Qopf"]="ℚ",
+["subsetneq"]="⊊",
+["nltri"]="⋪",
+["Cayleys"]="ℭ",
+["Efr"]="𝔈",
+["Intersection"]="⋂",
+["UnderBar"]="_",
+["fpartint"]="⨍",
+["Iuml"]="Ï",
+["rsquo"]="’",
+["ecir"]="≖",
+["nis"]="⋼",
+["fscr"]="𝒻",
+["hellip"]="…",
+["ogt"]="⧁",
["ntgl"]="≹",
-["LessFullEqual"]="≦",
-["malt"]="✠",
-["mcy"]="м",
-["NotGreaterEqual"]="≱",
-["bottom"]="⊥",
-["NotSucceedsEqual"]="⪰̸",
-["lcedil"]="ļ",
-["infintie"]="⧝",
-["Lcaron"]="Ľ",
-["NotSquareSubset"]="⊏̸",
-["brvbar"]="¦",
-["fallingdotseq"]="≒",
-["AElig"]="Æ",
-["swarhk"]="⤦",
-["Ifr"]="ℑ",
-["pi"]="π",
-["lcy"]="л",
-["copy"]="©",
-["dlcorn"]="⌞",
-["oacute"]="ó",
-["gtreqless"]="⋛",
-["neArr"]="⇗",
+["frac14"]="¼",
+["squf"]="▪",
+["circ"]="ˆ",
+["prE"]="⪳",
+["ordf"]="ª",
["ZHcy"]="Ж",
-["Vdashl"]="⫦",
-["darr"]="↓",
-["circeq"]="≗",
+["NegativeVeryThinSpace"]="​",
+["quot"]="\"",
+["excl"]="!",
+["sqcaps"]="⊓︀",
+["gfr"]="𝔤",
+["varsigma"]="ς",
+["nwarrow"]="↖",
+["reg"]="®",
+["longmapsto"]="⟼",
+["And"]="⩓",
+["cuvee"]="⋎",
+["zwj"]="‍",
+["plankv"]="ℏ",
+["varepsilon"]="ϵ",
+["Aopf"]="𝔸",
+["UpTee"]="⊥",
+["lescc"]="⪨",
+["ltri"]="◃",
+["iiint"]="∭",
+["ccups"]="⩌",
+["alefsym"]="ℵ",
+["succneqq"]="⪶",
+["hscr"]="𝒽",
+["Or"]="⩔",
["yuml"]="ÿ",
-["Jfr"]="𝔍",
-["Product"]="∏",
-["boxDL"]="╗",
-["el"]="⪙",
-["supe"]="⊇",
-["frac13"]="⅓",
-["Barwed"]="⌆",
-["larrpl"]="⤹",
-["SHCHcy"]="Щ",
-["LeftUpDownVector"]="⥑",
-["Diamond"]="⋄",
-["DownLeftVectorBar"]="⥖",
-["Cross"]="⨯",
-["ncup"]="⩂",
-["supnE"]="⫌",
-["lne"]="⪇",
-["micro"]="µ",
-["lowbar"]="_",
-["perp"]="⊥",
-["sqcap"]="⊓",
-["Gfr"]="𝔊",
-["raemptyv"]="⦳",
-["gesl"]="⋛︀",
-["drcrop"]="⌌",
-["boxUL"]="╝",
-["becaus"]="∵",
-["gne"]="⪈",
-["scap"]="⪸",
-["swarrow"]="↙",
-["nesim"]="≂̸",
-["DoubleDot"]="¨",
-["Mopf"]="𝕄",
-["apid"]="≋",
-["InvisibleComma"]="⁣",
-["Backslash"]="∖",
-["mnplus"]="∓",
-["niv"]="∋",
-["Hfr"]="ℌ",
-["rarrlp"]="↬",
-["Because"]="∵",
-["parsl"]="⫽",
-["sup1"]="¹",
-["Lt"]="≪",
-["par"]="∥",
-["Iota"]="Ι",
-["beth"]="ℶ",
-["Lopf"]="𝕃",
+["rcub"]="}",
+["lt"]="<",
+["vArr"]="⇕",
+["EqualTilde"]="≂",
+["vDash"]="⊨",
+["RightArrow"]="→",
+["dlcorn"]="⌞",
+["Barv"]="⫧",
+["nsc"]="⊁",
+["Proportion"]="∷",
+["iota"]="ι",
+["gscr"]="ℊ",
+["abreve"]="ă",
+["ThickSpace"]="  ",
+["szlig"]="ß",
+["lhard"]="↽",
+["emptyv"]="∅",
+["Tau"]="Τ",
+["sharp"]="♯",
+["bNot"]="⫭",
+["LongLeftRightArrow"]="⟷",
+["frac23"]="⅔",
+["NotEqual"]="≠",
+["scE"]="⪴",
+["jfr"]="𝔧",
+["bscr"]="𝒷",
+["uhblk"]="▀",
+["frac35"]="⅗",
+["TSHcy"]="Ћ",
+["ntrianglerighteq"]="⋭",
+["Tcedil"]="Ţ",
+["NotGreaterFullEqual"]="≧̸",
+["asympeq"]="≍",
+["oror"]="⩖",
+["ecirc"]="ê",
+["ohbar"]="⦵",
+["Rho"]="Ρ",
+["iacute"]="í",
+["ascr"]="𝒶",
+["RightUpVector"]="↾",
+["Ocirc"]="Ô",
+["cedil"]="¸",
+["sect"]="§",
+["angmsdab"]="⦩",
+["FilledVerySmallSquare"]="▪",
+["curlywedge"]="⋏",
+["lesdotor"]="⪃",
+["esdot"]="≐",
+["eqvparsl"]="⧥",
["Cap"]="⋒",
-["Aring"]="Å",
-["rarr"]="→",
-["Efr"]="𝔈",
-["bigcup"]="⋃",
-["DownLeftRightVector"]="⥐",
-["lesges"]="⪓",
-["NegativeThinSpace"]="​",
-["DownRightTeeVector"]="⥟",
-["npolint"]="⨔",
-["gEl"]="⪌",
-["lltri"]="◺",
-["ogon"]="˛",
-["LessEqualGreater"]="⋚",
-["sqsupset"]="⊐",
-["NotSubsetEqual"]="⊈",
-["Ubrcy"]="Ў",
-["ShortDownArrow"]="↓",
-["ugrave"]="ù",
-["Dcaron"]="Ď",
-["subE"]="⫅",
-["divide"]="÷",
-["bigotimes"]="⨂",
-["dscy"]="ѕ",
-["wreath"]="≀",
-["Jopf"]="𝕁",
-["pre"]="⪯",
-["tdot"]="⃛",
-["Cfr"]="ℭ",
-["Uogon"]="Ų",
-["softcy"]="ь",
-["isinE"]="⋹",
-["Dstrok"]="Đ",
-["Jsercy"]="Ј",
-["capdot"]="⩀",
-["realpart"]="ℜ",
-["hearts"]="♥",
-["Atilde"]="Ã",
-["LeftArrowRightArrow"]="⇆",
-["upharpoonleft"]="↿",
-["Iopf"]="𝕀",
-["Intersection"]="⋂",
-["midcir"]="⫰",
-["ocirc"]="ô",
-["sdot"]="⋅",
-["Dfr"]="𝔇",
-["gla"]="⪥",
-["DiacriticalGrave"]="`",
+["dscr"]="𝒹",
+["rbrace"]="}",
+["nsccue"]="⋡",
+["neArr"]="⇗",
+["rightthreetimes"]="⋌",
+["plusmn"]="±",
["Ubreve"]="Ŭ",
-["int"]="∫",
-["PrecedesSlantEqual"]="≼",
-["Square"]="□",
-["Acy"]="А",
+["ifr"]="𝔦",
+["Poincareplane"]="ℌ",
+["leftrightarrows"]="⇆",
+["scnsim"]="⋩",
+["cscr"]="𝒸",
+["NotHumpEqual"]="≏̸",
+["capbrcup"]="⩉",
+["curarr"]="↷",
+["notinvb"]="⋷",
+["LeftArrow"]="←",
+["Gopf"]="𝔾",
+["ldrushar"]="⥋",
+["nscr"]="𝓃",
+["Gg"]="⋙",
+["ouml"]="ö",
+["nsce"]="⪰̸",
+["cupbrcap"]="⩈",
+["nLt"]="≪⃒",
+["bullet"]="•",
+["nsqsupe"]="⋣",
+["rect"]="▭",
+["lbrace"]="{",
+["Fopf"]="𝔽",
+["COPY"]="©",
+["epar"]="⋕",
+["mscr"]="𝓂",
+["odsold"]="⦼",
+["cupor"]="⩅",
+["not"]="¬",
+["subsim"]="⫇",
+["hoarr"]="⇿",
+["Scedil"]="Ş",
+["eacute"]="é",
+["emsp"]=" ",
+["uml"]="¨",
+["igrave"]="ì",
+["pscr"]="𝓅",
+["LeftTee"]="⊣",
+["Cedilla"]="¸",
+["Iopf"]="𝕀",
+["HumpEqual"]="≏",
+["les"]="⩽",
+["Rcedil"]="Ŗ",
+["lsquor"]="‚",
+["raemptyv"]="⦳",
+["NotSucceedsSlantEqual"]="⋡",
+["SuchThat"]="∋",
+["vert"]="|",
+["backcong"]="≌",
["Hopf"]="ℍ",
-["precsim"]="≾",
-["nleq"]="≰",
-["urcorn"]="⌝",
-["hyphen"]="‐",
-["FilledSmallSquare"]="◼",
-["zdot"]="ż",
-["ndash"]="–",
-["hbar"]="ℏ",
-["Wopf"]="𝕎",
-["Esim"]="⩳",
-["subsetneq"]="⊊",
-["boxhD"]="╥",
-["searhk"]="⤥",
-["late"]="⪭",
+["CircleDot"]="⊙",
+["Kappa"]="Κ",
+["conint"]="∮",
+["DZcy"]="Џ",
+["prsim"]="≾",
+["Copf"]="ℂ",
+["curvearrowright"]="↷",
+["twixt"]="≬",
+["curren"]="¤",
+["rtriltri"]="⧎",
+["jscr"]="𝒿",
+["cupcup"]="⩊",
+["Lcedil"]="Ļ",
+["supseteqq"]="⫆",
+["bfr"]="𝔟",
+["lesseqqgtr"]="⪋",
+["leftleftarrows"]="⇇",
+["Bopf"]="𝔹",
+["acute"]="´",
["blacktriangleright"]="▸",
-["auml"]="ä",
-["NotLessTilde"]="≴",
-["Bfr"]="𝔅",
-["grave"]="`",
-["ltlarr"]="⥶",
-["Aogon"]="Ą",
-["sdote"]="⩦",
-["gtrsim"]="≳",
-["nvinfin"]="⧞",
-["lgE"]="⪑",
-["mdash"]="—",
-["Vopf"]="𝕍",
-["leftrightarrow"]="↔",
-["RBarr"]="⤐",
-["amalg"]="⨿",
-["preccurlyeq"]="≼",
-["EqualTilde"]="≂",
-["scpolint"]="⨓",
-["NotHumpDownHump"]="≎̸",
-["uparrow"]="↑",
-["downarrow"]="↓",
-["boxdL"]="╕",
-["Hstrok"]="Ħ",
-["Ccaron"]="Č",
-["succsim"]="≿",
-["RightFloor"]="⌋",
-["DownBreve"]="̑",
-["succapprox"]="⪸",
-["dsol"]="⧶",
-["napid"]="≋̸",
-["nprcue"]="⋠",
+["frac34"]="¾",
+["Gbreve"]="Ğ",
+["Updownarrow"]="⇕",
+["iscr"]="𝒾",
+["sigmav"]="ς",
+["trade"]="™",
+["minusb"]="⊟",
+["GJcy"]="Ѓ",
+["TildeFullEqual"]="≅",
+["DoubleRightTee"]="⊨",
+["nang"]="∠⃒",
+["ddotseq"]="⩷",
+["copy"]="©",
["Eopf"]="𝔼",
-["ell"]="ℓ",
-["cupdot"]="⊍",
-["Not"]="⫬",
-["zigrarr"]="⇝",
-["downharpoonright"]="⇂",
-["nisd"]="⋺",
-["lotimes"]="⨴",
-["plusmn"]="±",
-["ngE"]="≧̸",
-["odash"]="⊝",
-["emptyset"]="∅",
+["Psi"]="Ψ",
+["UpperRightArrow"]="↗",
+["geqq"]="≧",
+["subedot"]="⫃",
+["nvlArr"]="⤂",
+["Ncedil"]="Ņ",
+["vsupne"]="⊋︀",
+["supset"]="⊃",
["squarf"]="▪",
-["NotGreaterTilde"]="≵",
-["NotTildeFullEqual"]="≇",
-["DownArrowUpArrow"]="⇵",
-["nwarrow"]="↖",
-["looparrowright"]="↬",
+["LeftDoubleBracket"]="⟦",
+["utrif"]="▴",
["Dopf"]="𝔻",
-["oplus"]="⊕",
-["UpEquilibrium"]="⥮",
-["leftthreetimes"]="⋋",
-["DoubleLeftTee"]="⫤",
-["nabla"]="∇",
-["RuleDelayed"]="⧴",
-["euml"]="ë",
-["varsupsetneqq"]="⫌︀",
-["upsi"]="υ",
-["supsup"]="⫖",
-["bsol"]="\\",
-["Copf"]="ℂ",
-["DDotrahd"]="⤑",
-["Upsilon"]="Υ",
-["UpperRightArrow"]="↗",
-["nedot"]="≐̸",
-["NotEqual"]="≠",
-["bumpeq"]="≏",
-["emsp14"]=" ",
-["frac38"]="⅜",
-["DownTeeArrow"]="↧",
-["Bopf"]="𝔹",
-["capand"]="⩄",
-["nleqq"]="≦̸",
-["ratio"]="∶",
-["eplus"]="⩱",
-["nge"]="≱",
-["laquo"]="«",
-["urtri"]="◹",
-["LeftUpVector"]="↿",
-["gl"]="≷",
-["Gt"]="≫",
-["andd"]="⩜",
+["ape"]="≊",
+["gEl"]="⪌",
+["COPY"]="©",
+["afr"]="𝔞",
+["Acy"]="А",
+["ldquor"]="„",
+["because"]="∵",
+["Pr"]="⪻",
+["OverBar"]="‾",
+["lang"]="⟨",
+["mopf"]="𝕞",
+["crarr"]="↵",
+["Epsilon"]="Ε",
+["Nfr"]="𝔑",
+["kjcy"]="ќ",
+["TildeTilde"]="≈",
+["bsim"]="∽",
+["lcy"]="л",
+["larrb"]="⇤",
+["ncong"]="≇",
+["ENG"]="Ŋ",
+["brvbar"]="¦",
+["Rightarrow"]="⇒",
+["nopf"]="𝕟",
+["Wfr"]="𝔚",
+["ljcy"]="љ",
+["diamondsuit"]="♦",
+["latail"]="⤙",
+["lambda"]="λ",
+["frac14"]="¼",
+["mcy"]="м",
+["nparsl"]="⫽⃥",
+["lBarr"]="⤎",
+["subdot"]="⪽",
+["frac12"]="½",
+["kopf"]="𝕜",
+["LeftCeiling"]="⌈",
+["erarr"]="⥱",
+["pre"]="⪯",
+["varr"]="↕",
+["Pi"]="Π",
+["sub"]="⊂",
+["ncy"]="н",
+["marker"]="▮",
+["rpargt"]="⦔",
+["supe"]="⊇",
+["veebar"]="⊻",
+["checkmark"]="✓",
+["nbsp"]=" ",
+["sqsupseteq"]="⊒",
+["upharpoonright"]="↾",
+["lopf"]="𝕝",
+["Omicron"]="Ο",
+["ccaps"]="⩍",
+["lrhard"]="⥭",
["Lstrok"]="Ł",
-["gamma"]="γ",
-["Sc"]="⪼",
-["Aopf"]="𝔸",
-["pluscir"]="⨢",
-["Itilde"]="Ĩ",
-["DoubleRightTee"]="⊨",
-["pluse"]="⩲",
-["iiint"]="∭",
-["dotplus"]="∔",
-["vrtri"]="⊳",
-["Proportion"]="∷",
-["bne"]="=⃥",
-["cuepr"]="⋞",
+["Mfr"]="𝔐",
+["njcy"]="њ",
+["ocy"]="о",
+["Zcaron"]="Ž",
+["NotSucceeds"]="⊁",
+["rarrbfs"]="⤠",
+["gtrapprox"]="⪆",
+["oS"]="Ⓢ",
+["diamond"]="⋄",
+["gesdot"]="⪀",
+["urcorner"]="⌝",
+["lotimes"]="⨴",
+["pertenk"]="‱",
+["rfisht"]="⥽",
+["Zfr"]="ℨ",
+["Map"]="⤅",
+["cross"]="✗",
+["DifferentialD"]="ⅆ",
+["boxtimes"]="⊠",
+["horbar"]="―",
+["lg"]="≶",
+["orarr"]="↻",
+["Vbar"]="⫫",
+["ropf"]="𝕣",
+["NotDoubleVerticalBar"]="∦",
+["Sfr"]="𝔖",
+["Iuml"]="Ï",
+["leftharpoondown"]="↽",
+["atilde"]="ã",
+["VerticalTilde"]="≀",
+["DoubleContourIntegral"]="∯",
+["longleftarrow"]="⟵",
+["Im"]="ℑ",
+["RightUpVectorBar"]="⥔",
+["nGg"]="⋙̸",
+["scap"]="⪸",
+["nrarr"]="↛",
+["ycy"]="ы",
+["ucirc"]="û",
+["qopf"]="𝕢",
+["oopf"]="𝕠",
+["yacute"]="ý",
+["Xfr"]="𝔛",
+["fork"]="⋔",
+["in"]="∈",
+["xcap"]="⋂",
+["check"]="✓",
+["jcy"]="й",
+["Phi"]="Φ",
+["doteq"]="≐",
["vBar"]="⫨",
-["yucy"]="ю",
-["PrecedesTilde"]="≾",
-["varr"]="↕",
-["leftarrowtail"]="↢",
-["rangle"]="⟩",
-["subsub"]="⫕",
-["rightarrowtail"]="↣",
-["oslash"]="ø",
-["mapstodown"]="↧",
-["sqsube"]="⊑",
-["NewLine"]="\n",
-["Vdash"]="⊩",
-["num"]="#",
-["umacr"]="ū",
-["InvisibleTimes"]="⁢",
-["bemptyv"]="⦰",
+["frown"]="⌢",
["Iogon"]="Į",
-["ssmile"]="⌣",
-["timesbar"]="⨱",
-["Tstrok"]="Ŧ",
-["Icy"]="И",
-["zacute"]="ź",
-["Cedilla"]="¸",
-["daleth"]="ℸ",
-["semi"]=";",
-["ssetmn"]="∖",
-["subdot"]="⪽",
-["Bernoullis"]="ℬ",
-["otimesas"]="⨶",
-["circleddash"]="⊝",
-["circlearrowright"]="↻",
-["NotLeftTriangleEqual"]="⋬",
-["NotTilde"]="≁",
-["npart"]="∂̸",
-["Gbreve"]="Ğ",
-["gtrless"]="≷",
-["pound"]="£",
-["curlyeqsucc"]="⋟",
-["blacklozenge"]="⧫",
-["ldca"]="⤶",
-["nsucc"]="⊁",
-["top"]="⊤",
-["ufr"]="𝔲",
-["sscr"]="𝓈",
-["eDDot"]="⩷",
-["Updownarrow"]="⇕",
-["loz"]="◊",
-["Gcy"]="Г",
-["boxdl"]="┐",
+["gnsim"]="⋧",
+["nsupset"]="⊃⃒",
+["equals"]="=",
+["angmsdac"]="⦪",
+["odash"]="⊝",
+["Hstrok"]="Ħ",
+["homtht"]="∻",
+["maltese"]="✠",
+["esim"]="≂",
+["realine"]="ℛ",
+["straightepsilon"]="ϵ",
+["utri"]="▵",
+["primes"]="ℙ",
+["dbkarow"]="⤏",
+["NotLessTilde"]="≴",
+["nvrArr"]="⤃",
+["cularrp"]="⤽",
+["supsup"]="⫖",
+["rang"]="⟩",
+["nshortmid"]="∤",
+["NotCupCap"]="≭",
+["gnE"]="≩",
+["otilde"]="õ",
+["LeftTriangle"]="⊲",
+["oelig"]="œ",
+["curarrm"]="⤼",
+["orderof"]="ℴ",
+["DoubleLongLeftArrow"]="⟸",
+["OverParenthesis"]="⏜",
+["amacr"]="ā",
+["copysr"]="℗",
+["acirc"]="â",
+["LeftArrowRightArrow"]="⇆",
+["filig"]="fi",
+["uopf"]="𝕦",
+["rlhar"]="⇌",
+["dharl"]="⇃",
+["rAarr"]="⇛",
+["rarrw"]="↝",
+["isin"]="∈",
+["simg"]="⪞",
+["NoBreak"]="⁠",
+["rAtail"]="⤜",
+["ndash"]="–",
+["IJlig"]="IJ",
+["dfr"]="𝔡",
+["ohm"]="Ω",
+["breve"]="˘",
+["ccedil"]="ç",
+["topf"]="𝕥",
+["nvDash"]="⊭",
+["RBarr"]="⤐",
+["clubs"]="♣",
["napos"]="ʼn",
-["Sqrt"]="√",
-["xsqcup"]="⨆",
-["Implies"]="⇒",
-["uring"]="ů",
-["thetav"]="ϑ",
-["iiiint"]="⨌",
-["nLeftrightarrow"]="⇎",
-["lobrk"]="⟦",
-["xfr"]="𝔵",
-["Abreve"]="Ă",
-["micro"]="µ",
-["quatint"]="⨖",
-["congdot"]="⩭",
-["nrtrie"]="⋭",
-["Fcy"]="Ф",
-["hksearow"]="⤥",
-["LowerLeftArrow"]="↙",
-["rdca"]="⤷",
-["OverBar"]="‾",
-["frac12"]="½",
-["imacr"]="ī",
-["boxVL"]="╣",
-["sfr"]="𝔰",
-["ensp"]=" ",
-["dwangle"]="⦦",
-["boxh"]="─",
-["Eogon"]="Ę",
+["ngtr"]="≯",
+["Tstrok"]="Ŧ",
+["lrarr"]="⇆",
+["eqslantgtr"]="⪖",
+["efr"]="𝔢",
+["gne"]="⪈",
+["csube"]="⫑",
+["Xi"]="Ξ",
+["sopf"]="𝕤",
+["LeftVector"]="↼",
+["ggg"]="⋙",
+["Ubrcy"]="Ў",
+["die"]="¨",
+["topbot"]="⌶",
+["Rfr"]="ℜ",
+["ofcir"]="⦿",
["imped"]="Ƶ",
-["Ecy"]="Э",
-["lates"]="⪭︀",
-["phi"]="φ",
-["minusd"]="∸",
-["planckh"]="ℎ",
-["Ocirc"]="Ô",
-["lE"]="≦",
-["sum"]="∑",
-["lrtri"]="⊿",
-["ruluhar"]="⥨",
-["lAarr"]="⇚",
-["DownArrow"]="↓",
-["zscr"]="𝓏",
-["questeq"]="≟",
-["ngeqq"]="≧̸",
-["And"]="⩓",
-["Dcy"]="Д",
-["angrtvbd"]="⦝",
-["rarrpl"]="⥅",
-["thkap"]="≈",
-["Otimes"]="⨷",
-["lesssim"]="≲",
-["gE"]="≧",
-["ouml"]="ö",
-["nsubseteq"]="⊈",
-["bigcirc"]="◯",
+["plusmn"]="±",
+["nles"]="⩽̸",
+["pcy"]="п",
+["permil"]="‰",
+["notinE"]="⋹̸",
+["bigoplus"]="⨁",
+["boxplus"]="⊞",
+["doublebarwedge"]="⌆",
+["ccaron"]="č",
+["asymp"]="≈",
+["sup1"]="¹",
+["bumpeq"]="≏",
+["nrtrie"]="⋭",
+["larrbfs"]="⤟",
+["emacr"]="ē",
+["gtrless"]="≷",
+["Kfr"]="𝔎",
+["plus"]="+",
+["risingdotseq"]="≓",
+["notindot"]="⋵̸",
+["Subset"]="⋐",
+["CloseCurlyDoubleQuote"]="”",
+["nlsim"]="≴",
+["dcaron"]="ď",
["boxVR"]="╠",
-["Vert"]="‖",
-["naturals"]="ℕ",
-["plussim"]="⨦",
-["wscr"]="𝓌",
-["raquo"]="»",
-["bigodot"]="⨀",
-["dashv"]="⊣",
-["hairsp"]=" ",
-["inodot"]="ı",
-["vnsup"]="⊃⃒",
+["lne"]="⪇",
+["Pfr"]="𝔓",
+["rightsquigarrow"]="↝",
+["phone"]="☎",
+["DiacriticalDot"]="˙",
+["Congruent"]="≡",
+["SquareIntersection"]="⊓",
+["ordf"]="ª",
+["loz"]="◊",
["cire"]="≗",
-["vartriangleleft"]="⊲",
-["rbrke"]="⦌",
-["boxuL"]="╛",
-["sce"]="⪰",
-["nrtri"]="⋫",
-["loarr"]="⇽",
-["ShortRightArrow"]="→",
-["xscr"]="𝓍",
-["Bcy"]="Б",
-["HumpEqual"]="≏",
-["lmidot"]="ŀ",
-["DownLeftVector"]="↽",
-["leftharpoonup"]="↼",
+["ecaron"]="ě",
+["nsub"]="⊄",
+["Fouriertrf"]="ℱ",
+["Qfr"]="𝔔",
+["dblac"]="˝",
+["sc"]="≻",
+["xrarr"]="⟶",
+["ImaginaryI"]="ⅈ",
+["angmsdag"]="⦮",
+["wopf"]="𝕨",
+["middot"]="·",
+["gsiml"]="⪐",
+["biguplus"]="⨄",
+["Prime"]="″",
+["bigcirc"]="◯",
+["vsubnE"]="⫋︀",
+["lrtri"]="⊿",
+["nparallel"]="∦",
["lbbrk"]="❲",
-["rarrtl"]="↣",
-["SucceedsEqual"]="⪰",
-["HumpDownHump"]="≎",
-["Vee"]="⋁",
-["Gopf"]="𝔾",
-["otilde"]="õ",
-["ofr"]="𝔬",
-["Sub"]="⋐",
-["gnE"]="≩",
-["SquareSuperset"]="⊐",
-["leftrightharpoons"]="⇋",
-["tosa"]="⤩",
-["Ucirc"]="Û",
-["mscr"]="𝓂",
-["Exists"]="∃",
-["langle"]="⟨",
-["rfr"]="𝔯",
-["THORN"]="Þ",
-["gtreqqless"]="⪌",
-["eqvparsl"]="⧥",
-["NotCongruent"]="≢",
-["phiv"]="ϕ",
-["lsquor"]="‚",
-["prec"]="≺",
-["igrave"]="ì",
-["Fopf"]="𝔽",
-["nwArr"]="⇖",
-["nscr"]="𝓃",
-["gescc"]="⪩",
-["intprod"]="⨼",
-["larrlp"]="↫",
-["AMP"]="&",
-["psi"]="ψ",
-["mDDot"]="∺",
-["VDash"]="⊫",
-["Lleftarrow"]="⇚",
-["mfr"]="𝔪",
+["dotsquare"]="⊡",
+["rceil"]="⌉",
["gesles"]="⪔",
-["kscr"]="𝓀",
-["Omega"]="Ω",
-["bumpe"]="≏",
-["NotDoubleVerticalBar"]="∦",
-["frac18"]="⅛",
-["ecolon"]="≕",
-["compfn"]="∘",
-["supdot"]="⪾",
-["Alpha"]="Α",
-["rsquor"]="’",
+["roarr"]="⇾",
+["simplus"]="⨤",
+["lagran"]="ℒ",
+["pr"]="≺",
+["mnplus"]="∓",
+["Iota"]="Ι",
+["NestedLessLess"]="≪",
+["utilde"]="ũ",
+["mldr"]="…",
+["bigstar"]="★",
+["micro"]="µ",
["percnt"]="%",
-["pfr"]="𝔭",
-["frasl"]="⁄",
-["lscr"]="𝓁",
-["aleph"]="ℵ",
-["swArr"]="⇙",
-["uuml"]="ü",
-["uacute"]="ú",
-["scE"]="⪴",
-["hellip"]="…",
+["fllig"]="fl",
+["euml"]="ë",
+["circledR"]="®",
+["lltri"]="◺",
+["IEcy"]="Е",
+["notniva"]="∌",
+["or"]="∨",
+["curvearrowleft"]="↶",
+["gnapprox"]="⪊",
+["NotLessSlantEqual"]="⩽̸",
+["Cconint"]="∰",
+["NotSucceedsTilde"]="≿̸",
+["gammad"]="ϝ",
+["rightharpoondown"]="⇁",
+["CounterClockwiseContourIntegral"]="∳",
+["supdot"]="⪾",
+["upsi"]="υ",
+["nvle"]="≤⃒",
+["beth"]="ℶ",
+["nhArr"]="⇎",
+["Gamma"]="Γ",
+["complement"]="∁",
+["xoplus"]="⨁",
+["chi"]="χ",
+["backepsilon"]="϶",
+["nsube"]="⊈",
+["aopf"]="𝕒",
+["para"]="¶",
+["drbkarow"]="⤐",
+["Dstrok"]="Đ",
+["isinE"]="⋹",
+["Ecirc"]="Ê",
+["aelig"]="æ",
["ulcorner"]="⌜",
-["prnap"]="⪹",
-["Gg"]="⋙",
-["wedge"]="∧",
-["SquareSubset"]="⊏",
-["qscr"]="𝓆",
-["kfr"]="𝔨",
-["RightTee"]="⊢",
-["eqsim"]="≂",
-["rbrksld"]="⦎",
-["ohm"]="Ω",
-["lozf"]="⧫",
-["cups"]="∪︀",
-["epsilon"]="ε",
-["ncap"]="⩃",
-["Leftarrow"]="⇐",
-["ultri"]="◸",
-["egrave"]="è",
-["vBarv"]="⫩",
-["bNot"]="⫭",
-["nfr"]="𝔫",
-["rsqb"]="]",
-["OpenCurlyDoubleQuote"]="“",
-["rsquo"]="’",
-["Del"]="∇",
-["smtes"]="⪬︀",
-["varphi"]="ϕ",
-["CirclePlus"]="⊕",
-["prcue"]="≼",
-["curren"]="¤",
-["nltri"]="⋪",
-["oscr"]="ℴ",
-["Wcirc"]="Ŵ",
-["prime"]="′",
-["ifr"]="𝔦",
-["apos"]="'",
-["UpTee"]="⊥",
-["lescc"]="⪨",
-["NegativeMediumSpace"]="​",
-["DownTee"]="⊤",
-["NotSquareSubsetEqual"]="⋢",
-["LowerRightArrow"]="↘",
-["wr"]="≀",
+["Lcaron"]="Ľ",
+["bopf"]="𝕓",
+["midast"]="*",
+["barvee"]="⊽",
+["nvgt"]=">⃒",
+["bnequiv"]="≡⃥",
+["caron"]="ˇ",
["andand"]="⩕",
-["gvnE"]="≩︀",
-["lfr"]="𝔩",
-["lowast"]="∗",
-["gfr"]="𝔤",
-["digamma"]="ϝ",
-["cemptyv"]="⦲",
-["ubreve"]="ŭ",
-["dstrok"]="đ",
+["eparsl"]="⧣",
+["xhArr"]="⟺",
+["Yuml"]="Ÿ",
+["fallingdotseq"]="≒",
+["vltri"]="⊲",
+["gtrarr"]="⥸",
+["nGtv"]="≫̸",
+["congdot"]="⩭",
+["lfisht"]="⥼",
+["nrtri"]="⋫",
+["prnsim"]="⋨",
+["nsupE"]="⫆̸",
+["Colone"]="⩴",
+["SquareSuperset"]="⊐",
+["boxUL"]="╝",
+["Rrightarrow"]="⇛",
+["nleftrightarrow"]="↮",
+["Conint"]="∯",
+["ffilig"]="ffi",
+["nleqq"]="≦̸",
+["drcrop"]="⌌",
+["boxh"]="─",
+["Lang"]="⟪",
+["ldrdhar"]="⥧",
+["rbrack"]="]",
+["nvinfin"]="⧞",
+["succsim"]="≿",
+["boxhu"]="┴",
+["tau"]="τ",
+["incare"]="℅",
+["flat"]="♭",
+["angst"]="Å",
+["Oslash"]="Ø",
+["Vfr"]="𝔙",
+["tscy"]="ц",
+["lates"]="⪭︀",
+["eopf"]="𝕖",
+["Because"]="∵",
+["frac25"]="⅖",
+["daleth"]="ℸ",
+["ic"]="⁣",
+["ensp"]=" ",
+["lrm"]="‎",
+["DoubleLeftRightArrow"]="⇔",
+["kappa"]="κ",
+["fopf"]="𝕗",
+["cularr"]="↶",
+["shy"]="­",
+["yen"]="¥",
+["glj"]="⪤",
+["dzcy"]="џ",
["expectation"]="ℰ",
-["sime"]="≃",
-["ltrif"]="◂",
-["iacute"]="í",
-["chi"]="χ",
+["dash"]="‐",
+["female"]="♀",
+["UnderBrace"]="⏟",
+["rotimes"]="⨵",
+["caps"]="∩︀",
+["copf"]="𝕔",
+["lparlt"]="⦓",
+["NotLess"]="≮",
+["simrarr"]="⥲",
+["dtri"]="▿",
+["supne"]="⊋",
+["block"]="█",
+["siml"]="⪝",
+["blk12"]="▒",
+["natural"]="♮",
+["frac34"]="¾",
+["frac38"]="⅜",
+["Ufr"]="𝔘",
+["gg"]="≫",
+["Square"]="□",
+["lt"]="<",
["erDot"]="≓",
-["Vcy"]="В",
+["RightAngleBracket"]="⟩",
+["LeftDownTeeVector"]="⥡",
+["NotGreaterGreater"]="≫̸",
+["uogon"]="ų",
+["ocirc"]="ô",
+["sung"]="♪",
+["dollar"]="$",
+["Scaron"]="Š",
+["top"]="⊤",
+["iopf"]="𝕚",
+["udhar"]="⥮",
+["gjcy"]="ѓ",
+["ncap"]="⩃",
+["circlearrowleft"]="↺",
+["bernou"]="ℬ",
+["angmsdaf"]="⦭",
+["ldsh"]="↲",
+["isins"]="⋴",
+["RoundImplies"]="⥰",
+["bigtriangledown"]="▽",
+["LeftAngleBracket"]="⟨",
+["HorizontalLine"]="─",
+["Vdashl"]="⫦",
+["rHar"]="⥤",
+["Tcaron"]="Ť",
+["LeftDownVectorBar"]="⥙",
+["jopf"]="𝕛",
+["LeftRightVector"]="⥎",
+["LessGreater"]="≶",
+["npart"]="∂̸",
+["nsmid"]="∤",
+["RightTriangleBar"]="⧐",
+["nesim"]="≂̸",
+["deg"]="°",
+["LeftTeeArrow"]="↤",
+["NotHumpDownHump"]="≎̸",
+["tridot"]="◬",
+["lceil"]="⌈",
+["ExponentialE"]="ⅇ",
+["tosa"]="⤩",
+["gopf"]="𝕘",
+["ContourIntegral"]="∮",
+["late"]="⪭",
+["bbrk"]="⎵",
+["half"]="½",
["boxhd"]="┬",
-["DoubleDownArrow"]="⇓",
-["lArr"]="⇐",
-["demptyv"]="⦱",
-["smt"]="⪪",
-["intcal"]="⊺",
-["in"]="∈",
-["capcup"]="⩇",
-["kjcy"]="ќ",
-["Ccirc"]="Ĉ",
-["bnequiv"]="≡⃥",
-["Emacr"]="Ē",
-["siml"]="⪝",
-["jfr"]="𝔧",
-["gesdoto"]="⪂",
-["efr"]="𝔢",
-["precneqq"]="⪵",
-["because"]="∵",
-["Udblac"]="Ű",
-["lg"]="≶",
-["boxvr"]="├",
-["fpartint"]="⨍",
-["rbbrk"]="❳",
-["LT"]="<",
-["cap"]="∩",
-["circledR"]="®",
-["notinvc"]="⋶",
-["zwj"]="‍",
-["nle"]="≰",
-["hfr"]="𝔥",
-["bigsqcup"]="⨆",
-["nGg"]="⋙̸",
-["doublebarwedge"]="⌆",
+["hopf"]="𝕙",
+["Ouml"]="Ö",
+["Atilde"]="Ã",
+["planckh"]="ℎ",
+["MinusPlus"]="∓",
+["uharl"]="↿",
+["aleph"]="ℵ",
+["boxHD"]="╦",
+["lesseqgtr"]="⋚",
+["colon"]=":",
+["SquareSupersetEqual"]="⊒",
+["isinsv"]="⋳",
+["lnapprox"]="⪉",
+["PrecedesSlantEqual"]="≼",
+["boxuL"]="╛",
+["csup"]="⫐",
+["hstrok"]="ħ",
+["leftrightharpoons"]="⇋",
+["boxuR"]="╘",
+["DD"]="ⅅ",
+["Longrightarrow"]="⟹",
+["epsilon"]="ε",
+["NotTildeTilde"]="≉",
+["nfr"]="𝔫",
+["Vscr"]="𝒱",
+["Ncy"]="Н",
+["boxUl"]="╜",
+["searr"]="↘",
+["ddagger"]="‡",
+["KHcy"]="Х",
+["NotSuperset"]="⊃⃒",
+["Uparrow"]="⇑",
+["nsqsube"]="⋢",
+["Imacr"]="Ī",
+["nspar"]="∦",
+["supsetneqq"]="⫌",
+["Sscr"]="𝒮",
+["lobrk"]="⟦",
+["mfr"]="𝔪",
+["acirc"]="â",
+["subne"]="⊊",
+["Icirc"]="Î",
+["Re"]="ℜ",
+["nearrow"]="↗",
["YUcy"]="Ю",
-["empty"]="∅",
-["nacute"]="ń",
-["Acirc"]="Â",
-["bigtriangleup"]="△",
-["hybull"]="⁃",
-["Ycy"]="Ы",
-["isindot"]="⋵",
-["iota"]="ι",
-["numero"]="№",
-["cfr"]="𝔠",
-["llarr"]="⇇",
-["lrhard"]="⥭",
-["cross"]="✗",
+["eqsim"]="≂",
+["UnionPlus"]="⊎",
+["topcir"]="⫱",
+["boxVL"]="╣",
+["Xscr"]="𝒳",
+["QUOT"]="\"",
+["RightDownVectorBar"]="⥕",
+["epsi"]="ε",
+["natur"]="♮",
+["leftthreetimes"]="⋋",
+["hercon"]="⊹",
+["lHar"]="⥢",
+["Aring"]="Å",
+["Kcedil"]="Ķ",
+["kfr"]="𝔨",
+["Oacute"]="Ó",
["zwnj"]="‌",
+["plusdu"]="⨥",
+["Kcy"]="К",
+["sqcup"]="⊔",
+["zscr"]="𝓏",
+["Assign"]="≔",
+["zopf"]="𝕫",
+["lstrok"]="ł",
+["zigrarr"]="⇝",
+["ShortDownArrow"]="↓",
+["simlE"]="⪟",
+["mid"]="∣",
["zeta"]="ζ",
-["precnsim"]="⋨",
-["zcy"]="з",
+["gE"]="≧",
+["zeetrf"]="ℨ",
+["qfr"]="𝔮",
["zcaron"]="ž",
-["xodot"]="⨀",
-["RightDownTeeVector"]="⥝",
-["ljcy"]="љ",
+["Yacute"]="Ý",
+["hksearow"]="⤥",
+["Atilde"]="Ã",
+["zacute"]="ź",
+["bsemi"]="⁏",
+["bigtriangleup"]="△",
+["yuml"]="ÿ",
+["yucy"]="ю",
["yscr"]="𝓎",
+["yopf"]="𝕪",
["yicy"]="ї",
-["Rcy"]="Р",
-["nsubset"]="⊂⃒",
-["yen"]="¥",
-["ycy"]="ы",
-["simeq"]="≃",
-["dharr"]="⇂",
-["ycirc"]="ŷ",
-["hArr"]="⇔",
-["yacute"]="ý",
-["yacute"]="ý",
+["urcorn"]="⌝",
+["Aacute"]="Á",
+["backsimeq"]="⋍",
+["ShortUpArrow"]="↑",
["xwedge"]="⋀",
-["xoplus"]="⨁",
-["nparsl"]="⫽⃥",
-["PartialD"]="∂",
-["YAcy"]="Я",
-["xrArr"]="⟹",
-["xotime"]="⨂",
-["sstarf"]="⋆",
-["yuml"]="ÿ",
-["Int"]="∬",
-["bsolb"]="⧅",
+["Jcy"]="Й",
+["nltrie"]="⋬",
+["starf"]="★",
+["zfr"]="𝔷",
+["comma"]=",",
+["xsqcup"]="⨆",
+["boxVr"]="╟",
+["cirscir"]="⧂",
+["ucirc"]="û",
+["Cross"]="⨯",
+["naturals"]="ℕ",
+["quaternions"]="ℍ",
+["xopf"]="𝕩",
+["xodot"]="⨀",
["xnis"]="⋻",
-["xmap"]="⟼",
-["hercon"]="⊹",
-["xlArr"]="⟸",
-["xharr"]="⟷",
-["rbrack"]="]",
+["lsaquo"]="‹",
+["xlarr"]="⟵",
+["Zacute"]="Ź",
+["vdash"]="⊢",
+["submult"]="⫁",
+["Oscr"]="𝒪",
["xdtri"]="▽",
-["diamond"]="⋄",
+["LowerRightArrow"]="↘",
["xcup"]="⋃",
-["subsup"]="⫓",
-["lneqq"]="≨",
-["dharl"]="⇃",
-["Scy"]="С",
-["wopf"]="𝕨",
-["rightleftharpoons"]="⇌",
-["wfr"]="𝔴",
-["nsupseteqq"]="⫆̸",
-["boxuR"]="╘",
-["permil"]="‰",
+["Ycy"]="Ы",
+["timesb"]="⊠",
+["Ucirc"]="Û",
+["eth"]="ð",
+["wscr"]="𝓌",
+["ratail"]="⤚",
+["wr"]="≀",
+["Ograve"]="Ò",
+["wp"]="℘",
+["euml"]="ë",
+["yfr"]="𝔶",
+["rangle"]="⟩",
+["hearts"]="♥",
["wedgeq"]="≙",
-["eparsl"]="⧣",
-["RoundImplies"]="⥰",
-["afr"]="𝔞",
-["vsubne"]="⊊︀",
-["sup2"]="²",
+["wedge"]="∧",
+["gtcir"]="⩺",
+["par"]="∥",
+["swarr"]="↙",
+["phiv"]="ϕ",
+["NotElement"]="∉",
+["alpha"]="α",
+["SquareUnion"]="⊔",
+["parsl"]="⫽",
["vscr"]="𝓋",
+["rharu"]="⇀",
+["vrtri"]="⊳",
+["comp"]="∁",
+["Agrave"]="À",
+["rdca"]="⤷",
+["vprop"]="∝",
+["Tscr"]="𝒯",
["vopf"]="𝕧",
-["lbrace"]="{",
+["ldca"]="⤶",
["vnsub"]="⊂⃒",
-["vltri"]="⊲",
-["Uacute"]="Ú",
-["vfr"]="𝔳",
-["sacute"]="ś",
-["njcy"]="њ",
-["frac35"]="⅗",
-["squf"]="▪",
+["gbreve"]="ğ",
+["NotSquareSubset"]="⊏̸",
+["verbar"]="|",
+["YAcy"]="Я",
["veeeq"]="≚",
-["lsime"]="⪍",
-["mapstoleft"]="↤",
+["downharpoonleft"]="⇃",
+["Star"]="⋆",
+["xfr"]="𝔵",
+["nges"]="⩾̸",
+["GreaterGreater"]="⪢",
+["vartriangleright"]="⊳",
+["rcy"]="р",
+["vartheta"]="ϑ",
+["varsupsetneqq"]="⫌︀",
+["dashv"]="⊣",
["varsupsetneq"]="⊋︀",
-["varsubsetneq"]="⊊︀",
-["Tcy"]="Т",
-["cwint"]="∱",
-["varsigma"]="ς",
-["LessGreater"]="≶",
+["Ncaron"]="Ň",
+["varsubsetneqq"]="⫋︀",
["varrho"]="ϱ",
-["varpropto"]="∝",
-["pr"]="≺",
-["backprime"]="‵",
+["triangledown"]="▿",
+["varpi"]="ϖ",
+["sol"]="/",
+["ssetmn"]="∖",
+["varnothing"]="∅",
["varkappa"]="ϰ",
-["Poincareplane"]="ℌ",
-["roplus"]="⨮",
-["Edot"]="Ė",
-["copysr"]="℗",
+["vangrt"]="⦜",
+["Leftarrow"]="⇐",
+["Qscr"]="𝒬",
+["uwangle"]="⦧",
+["rarrap"]="⥵",
["uuml"]="ü",
-["dfr"]="𝔡",
["uuarr"]="⇈",
-["uogon"]="ų",
-["Uscr"]="𝒰",
-["gel"]="⋛",
-["olarr"]="↺",
-["lsaquo"]="‹",
-["omacr"]="ō",
-["utdot"]="⋰",
-["or"]="∨",
-["Ocirc"]="Ô",
-["ClockwiseContourIntegral"]="∲",
-["SmallCircle"]="∘",
-["gtcc"]="⪧",
["uscr"]="𝓊",
+["urtri"]="◹",
+["uring"]="ů",
+["sect"]="§",
+["quatint"]="⨖",
["urcrop"]="⌎",
-["ContourIntegral"]="∮",
-["szlig"]="ß",
-["egs"]="⪖",
-["Ucy"]="У",
-["ange"]="⦤",
-["upharpoonright"]="↾",
-["xcap"]="⋂",
+["wfr"]="𝔴",
+["duhar"]="⥯",
+["upuparrows"]="⇈",
+["macr"]="¯",
+["SmallCircle"]="∘",
+["upsih"]="ϒ",
+["uplus"]="⊎",
+["shy"]="­",
+["uparrow"]="↑",
["uml"]="¨",
-["nsubseteqq"]="⫅̸",
+["eDot"]="≑",
+["blk34"]="▓",
+["umacr"]="ū",
+["ultri"]="◸",
+["rbbrk"]="❳",
["ulcorn"]="⌜",
-["uhblk"]="▀",
-["scirc"]="ŝ",
-["shy"]="­",
-["uharl"]="↿",
+["uharr"]="↾",
["ugrave"]="ù",
-["lstrok"]="ł",
-["Gamma"]="Γ",
-["udhar"]="⥮",
-["udblac"]="ű",
-["ucirc"]="û",
-["loang"]="⟬",
-["uarr"]="↑",
+["Ograve"]="Ò",
+["nsupseteq"]="⊉",
+["ufisht"]="⥾",
+["Breve"]="˘",
+["ucy"]="у",
+["cylcty"]="⌭",
+["ubreve"]="ŭ",
+["SHcy"]="Ш",
+["boxdR"]="╒",
+["awint"]="⨑",
+["uHar"]="⥣",
["uArr"]="⇑",
-["twoheadrightarrow"]="↠",
+["REG"]="®",
+["twoheadleftarrow"]="↞",
["tstrok"]="ŧ",
+["iprod"]="⨼",
["tshcy"]="ћ",
-["tscy"]="ц",
-["angsph"]="∢",
-["kappa"]="κ",
["tscr"]="𝓉",
-["tritime"]="⨻",
-["trisb"]="⧍",
+["trpezium"]="⏢",
+["ycirc"]="ŷ",
+["larrhk"]="↩",
+["triplus"]="⨹",
["triminus"]="⨺",
-["trie"]="≜",
-["tridot"]="◬",
-["aacute"]="á",
+["Rsh"]="↱",
+["becaus"]="∵",
+["Acirc"]="Â",
["trianglerighteq"]="⊵",
-["RightTeeVector"]="⥛",
["triangleright"]="▹",
+["hkswarow"]="⤦",
+["triangleq"]="≜",
+["AElig"]="Æ",
["trianglelefteq"]="⊴",
+["varpropto"]="∝",
["triangle"]="▵",
-["NegativeVeryThinSpace"]="​",
-["triangledown"]="▿",
-["dash"]="‐",
-["trade"]="™",
+["tprime"]="‴",
["topfork"]="⫚",
-["Upsi"]="ϒ",
-["topcir"]="⫱",
-["loplus"]="⨭",
-["Zdot"]="Ż",
-["lbrke"]="⦋",
-["angmsd"]="∡",
-["dArr"]="⇓",
-["topbot"]="⌶",
["toea"]="⤨",
-["iexcl"]="¡",
-["acirc"]="â",
-["easter"]="⩮",
-["CloseCurlyDoubleQuote"]="”",
-["cupcup"]="⩊",
-["rlhar"]="⇌",
-["nsimeq"]="≄",
-["Uparrow"]="⇑",
-["tau"]="τ",
-["npr"]="⊀",
-["phone"]="☎",
-["emacr"]="ē",
-["SHcy"]="Ш",
-["gtdot"]="⋗",
-["ReverseUpEquilibrium"]="⥯",
+["ac"]="∾",
+["timesd"]="⨰",
+["UpArrowDownArrow"]="⇅",
+["timesbar"]="⨱",
+["llhard"]="⥫",
+["CHcy"]="Ч",
+["odblac"]="ő",
+["THORN"]="Þ",
+["notni"]="∌",
+["nbump"]="≎̸",
+["eqcolon"]="≕",
["tilde"]="˜",
-["angmsdac"]="⦪",
-["duhar"]="⥯",
-["approxeq"]="≊",
-["NotSupersetEqual"]="⊉",
-["thorn"]="þ",
-["thksim"]="∼",
-["subsim"]="⫇",
-["bnot"]="⌐",
+["simgE"]="⪠",
+["intercal"]="⊺",
+["thetasym"]="ϑ",
+["xcirc"]="◯",
["thinsp"]=" ",
["thicksim"]="∼",
-["gt"]=">",
-["UpperLeftArrow"]="↖",
-["thetasym"]="ϑ",
-["simlE"]="⪟",
-["bbrktbrk"]="⎶",
-["Jcirc"]="Ĵ",
-["cedil"]="¸",
-["NotLessSlantEqual"]="⩽̸",
-["rx"]="℞",
-["infin"]="∞",
-["curlyvee"]="⋎",
-["LeftArrow"]="←",
-["tfr"]="𝔱",
-["blacksquare"]="▪",
-["emptyv"]="∅",
-["Mellintrf"]="ℳ",
-["aogon"]="ą",
-["succnapprox"]="⪺",
-["tcy"]="т",
-["ecaron"]="ě",
+["LeftArrowBar"]="⇤",
+["Uuml"]="Ü",
+["DownTeeArrow"]="↧",
+["cent"]="¢",
+["hookleftarrow"]="↩",
+["odiv"]="⨸",
+["therefore"]="∴",
+["ClockwiseContourIntegral"]="∲",
+["Ofr"]="𝔒",
+["auml"]="ä",
+["frac12"]="½",
+["nRightarrow"]="⇏",
+["kcedil"]="ķ",
+["DownRightVectorBar"]="⥗",
+["boxDL"]="╗",
["tcedil"]="ţ",
-["boxhU"]="╨",
-["boxVl"]="╢",
-["gacute"]="ǵ",
-["tcaron"]="ť",
-["boxDr"]="╓",
-["bump"]="≎",
-["blk12"]="▒",
-["RightArrow"]="→",
-["els"]="⪕",
-["apacir"]="⩯",
-["acy"]="а",
-["omid"]="⦶",
-["boxbox"]="⧉",
-["iecy"]="е",
-["szlig"]="ß",
-["upsih"]="ϒ",
-["swnwar"]="⤪",
-["Icirc"]="Î",
-["swarr"]="↙",
-["times"]="×",
-["Ograve"]="Ò",
-["hoarr"]="⇿",
-["NotTildeEqual"]="≄",
-["IEcy"]="Е",
-["iexcl"]="¡",
-["bdquo"]="„",
-["TildeTilde"]="≈",
+["boxUr"]="╙",
+["icirc"]="î",
+["lmoustache"]="⎰",
+["prime"]="′",
+["ngeq"]="≱",
["nshortparallel"]="∦",
-["subedot"]="⫃",
-["supsetneq"]="⊋",
-["CenterDot"]="·",
-["lessapprox"]="⪅",
-["LeftVectorBar"]="⥒",
-["bigoplus"]="⨁",
-["supseteqq"]="⫆",
-["drcorn"]="⌟",
-["hstrok"]="ħ",
-["HorizontalLine"]="─",
-["curarrm"]="⤼",
-["lopar"]="⦅",
+["szlig"]="ß",
+["Egrave"]="È",
+["sqsubset"]="⊏",
+["NotRightTriangleEqual"]="⋭",
+["swarrow"]="↙",
+["Ucirc"]="Û",
+["DownArrowBar"]="⤓",
+["Lfr"]="𝔏",
["wcirc"]="ŵ",
+["LessLess"]="⪡",
+["Tilde"]="∼",
+["empty"]="∅",
+["swarhk"]="⤦",
+["DownLeftVector"]="↽",
+["Uscr"]="𝒰",
+["khcy"]="х",
+["gesl"]="⋛︀",
+["supsub"]="⫔",
+["malt"]="✠",
+["cirmid"]="⫯",
+["PrecedesTilde"]="≾",
+["lharul"]="⥪",
+["rightleftharpoons"]="⇌",
+["Ccedil"]="Ç",
+["plusb"]="⊞",
+["nsupe"]="⊉",
+["geq"]="≥",
+["dHar"]="⥥",
+["lcedil"]="ļ",
+["ange"]="⦤",
+["supseteq"]="⊇",
+["Upsi"]="ϒ",
+["mapstodown"]="↧",
+["profalar"]="⌮",
+["cupdot"]="⊍",
+["mapstoleft"]="↤",
+["xotime"]="⨂",
+["tbrk"]="⎴",
+["supmult"]="⫂",
+["disin"]="⋲",
["suphsub"]="⫗",
-["Otilde"]="Õ",
-["EmptySmallSquare"]="◻",
+["eg"]="⪚",
["supedot"]="⫄",
-["Kopf"]="𝕂",
-["boxminus"]="⊟",
-["csupe"]="⫒",
-["Ffr"]="𝔉",
-["origof"]="⊶",
-["sup3"]="³",
-["boxH"]="═",
-["vsubnE"]="⫋︀",
-["Hcirc"]="Ĥ",
-["block"]="█",
+["NonBreakingSpace"]=" ",
+["Euml"]="Ë",
["bsolhsub"]="⟈",
-["Supset"]="⋑",
-["GreaterFullEqual"]="≧",
+["supdsub"]="⫘",
+["sup3"]="³",
+["DoubleLeftTee"]="⫤",
+["angrtvb"]="⊾",
+["supsim"]="⫈",
+["sup2"]="²",
+["sup2"]="²",
+["circledast"]="⊛",
+["rfr"]="𝔯",
+["darr"]="↓",
+["rarrhk"]="↪",
+["macr"]="¯",
["sup1"]="¹",
-["llcorner"]="⌞",
-["sopf"]="𝕤",
-["larrbfs"]="⤟",
-["succneqq"]="⪶",
-["part"]="∂",
-["eacute"]="é",
-["COPY"]="©",
-["frac23"]="⅔",
-["dbkarow"]="⤏",
-["succeq"]="⪰",
-["notni"]="∌",
-["Euml"]="Ë",
-["harrcir"]="⥈",
-["leftrightsquigarrow"]="↭",
-["xcirc"]="◯",
-["caret"]="⁁",
-["les"]="⩽",
-["lharul"]="⥪",
-["bsime"]="⋍",
-["DoubleLeftArrow"]="⇐",
-["ecirc"]="ê",
-["subsetneqq"]="⫋",
-["crarr"]="↵",
-["cuwed"]="⋏",
-["Ugrave"]="Ù",
-["Gcirc"]="Ĝ",
-["LeftTriangleBar"]="⧏",
+["aacute"]="á",
+["oscr"]="ℴ",
+["lharu"]="↼",
+["telrec"]="⌕",
+["Dashv"]="⫤",
+["succnsim"]="⋩",
+["AElig"]="Æ",
+["Vee"]="⋁",
+["succnapprox"]="⪺",
+["CapitalDifferentialD"]="ⅅ",
["gsim"]="≳",
-["RightTriangleEqual"]="⊵",
-["lacute"]="ĺ",
-["Ccedil"]="Ç",
-["ee"]="ⅇ",
-["heartsuit"]="♥",
-["coloneq"]="≔",
-["subseteq"]="⊆",
-["NotSucceedsTilde"]="≿̸",
+["succapprox"]="⪸",
+["rmoustache"]="⎱",
+["DotEqual"]="≐",
+["subsup"]="⫓",
+["Gcedil"]="Ģ",
+["questeq"]="≟",
+["lthree"]="⋋",
+["cong"]="≅",
+["lcub"]="{",
+["radic"]="√",
+["subrarr"]="⥹",
+["nvlt"]="<⃒",
["subplus"]="⪿",
-["cupcap"]="⩆",
-["Amacr"]="Ā",
-["angst"]="Å",
-["supsetneqq"]="⫌",
-["sube"]="⊆",
-["imagpart"]="ℑ",
-["Lambda"]="Λ",
-["Afr"]="𝔄",
-["sub"]="⊂",
+["bigsqcup"]="⨆",
+["downarrow"]="↓",
+["auml"]="ä",
+["boxdL"]="╕",
+["boxvr"]="├",
+["lbrkslu"]="⦍",
+["bigwedge"]="⋀",
+["apacir"]="⩯",
+["Wscr"]="𝒲",
+["iecy"]="е",
+["VerticalSeparator"]="❘",
+["Yfr"]="𝔜",
["strns"]="¯",
["straightphi"]="ϕ",
-["boxvL"]="╡",
-["dagger"]="†",
-["eta"]="η",
-["KHcy"]="Х",
-["Yfr"]="𝔜",
-["lbrack"]="[",
-["VerticalBar"]="∣",
-["rightleftarrows"]="⇄",
-["fltns"]="▱",
-["verbar"]="|",
-["RightAngleBracket"]="⟩",
-["DownRightVector"]="⇁",
-["Lacute"]="Ĺ",
-["sol"]="/",
-["lrm"]="‎",
-["lesdot"]="⩿",
-["nleqslant"]="⩽̸",
-["capcap"]="⩋",
+["kcy"]="к",
+["aogon"]="ą",
+["star"]="☆",
+["caret"]="⁁",
+["cups"]="∪︀",
+["iquest"]="¿",
+["spar"]="∥",
+["NotExists"]="∄",
+["Gt"]="≫",
["squ"]="□",
-["xutri"]="△",
-["TSHcy"]="Ћ",
-["gap"]="⪆",
-["gtrdot"]="⋗",
-["scnap"]="⪺",
-["bkarow"]="⤍",
-["NotPrecedes"]="⊀",
-["suphsol"]="⟉",
+["sqsupe"]="⊒",
+["subnE"]="⫋",
["sqsup"]="⊐",
-["epsi"]="ε",
-["sqsubset"]="⊏",
-["check"]="✓",
-["UpArrowBar"]="⤒",
-["NotPrecedesEqual"]="⪯̸",
-["csube"]="⫑",
-["nsupset"]="⊃⃒",
-["lesdoto"]="⪁",
+["sqsubseteq"]="⊑",
+["ffr"]="𝔣",
+["UpTeeArrow"]="↥",
+["middot"]="·",
+["DoubleLongRightArrow"]="⟹",
+["sqsube"]="⊑",
+["sce"]="⪰",
+["Sup"]="⋑",
+["cacute"]="ć",
+["GreaterFullEqual"]="≧",
+["pfr"]="𝔭",
+["Lleftarrow"]="⇚",
+["heartsuit"]="♥",
+["precsim"]="≾",
+["nsucceq"]="⪰̸",
["sqcups"]="⊔︀",
-["suplarr"]="⥻",
-["nsim"]="≁",
-["NotEqualTilde"]="≂̸",
-["nearr"]="↗",
-["SquareIntersection"]="⊓",
-["intlarhk"]="⨗",
-["Ecirc"]="Ê",
-["vangrt"]="⦜",
-["fllig"]="fl",
-["Leftrightarrow"]="⇔",
-["primes"]="ℙ",
-["nvlArr"]="⤂",
+["Igrave"]="Ì",
+["iquest"]="¿",
+["Pcy"]="П",
+["thksim"]="∼",
+["djcy"]="ђ",
+["hfr"]="𝔥",
+["spadesuit"]="♠",
+["rbrkslu"]="⦐",
+["shcy"]="ш",
+["barwed"]="⌅",
+["rpar"]=")",
+["iiiint"]="⨌",
+["solb"]="⧄",
+["Integral"]="∫",
+["napE"]="⩰̸",
+["softcy"]="ь",
+["NotRightTriangleBar"]="⧐̸",
+["Mu"]="Μ",
+["frasl"]="⁄",
+["Icy"]="И",
+["dfisht"]="⥿",
["smte"]="⪬",
-["ltri"]="◃",
-["Tscr"]="𝒯",
+["smt"]="⪪",
+["bottom"]="⊥",
+["oacute"]="ó",
+["ofr"]="𝔬",
["smid"]="∣",
-["smeparsl"]="⧤",
-["rarrc"]="⤳",
-["divideontimes"]="⋇",
-["eth"]="ð",
-["boxvR"]="╞",
-["copy"]="©",
-["nges"]="⩾̸",
-["fcy"]="ф",
-["ShortUpArrow"]="↑",
-["simplus"]="⨤",
-["frac45"]="⅘",
-["nexists"]="∄",
-["LeftTeeArrow"]="↤",
-["leftleftarrows"]="⇇",
-["simg"]="⪞",
-["euro"]="€",
-["simdot"]="⩪",
-["sim"]="∼",
-["sigmav"]="ς",
-["iuml"]="ï",
-["updownarrow"]="↕",
-["shy"]="­",
-["solb"]="⧄",
+["ReverseUpEquilibrium"]="⥯",
+["smashp"]="⨳",
+["slarr"]="←",
+["simne"]="≆",
+["LeftRightArrow"]="↔",
+["thkap"]="≈",
+["nlArr"]="⇍",
+["chcy"]="ч",
+["not"]="¬",
+["kgreen"]="ĸ",
+["simeq"]="≃",
+["LongRightArrow"]="⟶",
+["sime"]="≃",
+["sigma"]="σ",
+["odot"]="⊙",
+["amp"]="&",
+["Longleftrightarrow"]="⟺",
+["Upsilon"]="Υ",
+["upharpoonleft"]="↿",
+["bigotimes"]="⨂",
+["parallel"]="∥",
+["ffllig"]="ffl",
+["shortparallel"]="∥",
+["boxdr"]="┌",
+["shortmid"]="∣",
+["Euml"]="Ë",
+["UpDownArrow"]="↕",
+["lcaron"]="ľ",
+["sfrown"]="⌢",
+["harr"]="↔",
+["dsol"]="⧶",
+["Beta"]="Β",
+["srarr"]="→",
+["boxHd"]="╤",
["nesear"]="⤨",
-["Umacr"]="Ū",
-["uharr"]="↾",
-["Therefore"]="∴",
-["Barv"]="⫧",
-["amacr"]="ā",
["setmn"]="∖",
+["DoubleDot"]="¨",
["setminus"]="∖",
-["Sscr"]="𝒮",
+["andd"]="⩜",
+["leftrightarrow"]="↔",
["seswar"]="⤩",
-["ccupssm"]="⩐",
-["searr"]="↘",
+["eogon"]="ę",
+["bne"]="=⃥",
+["DownBreve"]="̑",
+["nLtv"]="≪̸",
+["nprcue"]="⋠",
+["SucceedsSlantEqual"]="≽",
+["downdownarrows"]="⇊",
+["seArr"]="⇘",
+["Utilde"]="Ũ",
+["Gammad"]="Ϝ",
+["sdote"]="⩦",
+["iexcl"]="¡",
+["nvdash"]="⊬",
+["csupe"]="⫒",
["sdotb"]="⊡",
-["icirc"]="î",
-["amp"]="&",
-["gcy"]="г",
-["Aacute"]="Á",
-["boxvh"]="┼",
-["bfr"]="𝔟",
-["OverParenthesis"]="⏜",
-["sqsupe"]="⊒",
-["amp"]="&",
-["frac14"]="¼",
-["ZeroWidthSpace"]="​",
-["Colon"]="∷",
-["Proportional"]="∝",
-["thickapprox"]="≈",
-["subseteqq"]="⫅",
-["IJlig"]="IJ",
-["scedil"]="ş",
-["lrarr"]="⇆",
-["angmsdaf"]="⦭",
-["downharpoonleft"]="⇃",
+["scsim"]="≿",
+["bcy"]="б",
+["NotTilde"]="≁",
+["minus"]="−",
+["scnE"]="⪶",
+["scirc"]="ŝ",
+["oplus"]="⊕",
+["para"]="¶",
+["Ycirc"]="Ŷ",
+["notinva"]="∉",
+["nLl"]="⋘̸",
+["Aring"]="Å",
+["THORN"]="Þ",
+["numero"]="№",
+["scaron"]="š",
+["bsol"]="\\",
+["harrw"]="↭",
+["exponentiale"]="ⅇ",
+["eDDot"]="⩷",
+["AMP"]="&",
+["gamma"]="γ",
+["opar"]="⦷",
+["cwint"]="∱",
+["GreaterEqual"]="≥",
+["bigcap"]="⋂",
+["rtimes"]="⋊",
+["integers"]="ℤ",
+["easter"]="⩮",
["RightDoubleBracket"]="⟧",
-["half"]="½",
-["larr"]="←",
["sbquo"]="‚",
-["Vscr"]="𝒱",
-["nVdash"]="⊮",
-["DownRightVectorBar"]="⥗",
-["RightDownVector"]="⇂",
-["disin"]="⋲",
-["nsce"]="⪰̸",
-["rbrace"]="}",
-["MinusPlus"]="∓",
-["rtrif"]="▸",
-["parsim"]="⫳",
-["supseteq"]="⊇",
-["Superset"]="⊃",
-["Verbar"]="‖",
+["cfr"]="𝔠",
+["ruluhar"]="⥨",
+["image"]="ℑ",
+["nleqslant"]="⩽̸",
+["Yopf"]="𝕐",
+["apE"]="⩰",
+["NotPrecedesEqual"]="⪯̸",
+["rsqb"]="]",
+["rtrie"]="⊵",
+["rthree"]="⋌",
+["amp"]="&",
+["eng"]="ŋ",
+["ll"]="≪",
+["rrarr"]="⇉",
+["RightTee"]="⊢",
+["ETH"]="Ð",
+["ReverseEquilibrium"]="⇋",
+["langle"]="⟨",
["Zeta"]="Ζ",
-["nsccue"]="⋡",
-["bsemi"]="⁏",
-["ldquor"]="„",
-["curarr"]="↷",
-["rscr"]="𝓇",
-["rppolint"]="⨒",
-["rpargt"]="⦔",
-["rotimes"]="⨵",
-["Equal"]="⩵",
-["ropf"]="𝕣",
-["ropar"]="⦆",
-["roarr"]="⇾",
-["odot"]="⊙",
-["natural"]="♮",
-["slarr"]="←",
-["angmsdae"]="⦬",
-["acE"]="∾̳",
+["roplus"]="⨮",
+["there4"]="∴",
+["DownRightTeeVector"]="⥟",
+["npar"]="∦",
+["robrk"]="⟧",
+["exist"]="∃",
+["lfr"]="𝔩",
+["VDash"]="⊫",
+["rnmid"]="⫮",
+["rmoust"]="⎱",
["rlm"]="‏",
-["COPY"]="©",
-["iogon"]="į",
-["nleftrightarrow"]="↮",
-["reg"]="®",
-["risingdotseq"]="≓",
-["rightsquigarrow"]="↝",
-["dtri"]="▿",
-["Larr"]="↞",
-["icy"]="и",
-["gimel"]="ℷ",
+["Ccirc"]="Ĉ",
+["imagpart"]="ℑ",
+["Equilibrium"]="⇌",
+["dd"]="ⅆ",
+["cuepr"]="⋞",
+["Agrave"]="À",
+["cuesc"]="⋟",
+["square"]="□",
+["notnivc"]="⋽",
+["rbrksld"]="⦎",
["cup"]="∪",
-["DJcy"]="Ђ",
-["gtrapprox"]="⪆",
-["rightharpoonup"]="⇀",
-["prsim"]="≾",
-["rightharpoondown"]="⇁",
-["frac16"]="⅙",
-["nbsp"]=" ",
-["cedil"]="¸",
-["numsp"]=" ",
+["OpenCurlyDoubleQuote"]="“",
+["Lacute"]="Ĺ",
+["NewLine"]="\n",
+["Sigma"]="Σ",
+["Abreve"]="Ă",
+["rightleftarrows"]="⇄",
+["tint"]="∭",
+["angmsdae"]="⦬",
+["Leftrightarrow"]="⇔",
+["rdquor"]="”",
+["Verbar"]="‖",
+["Gfr"]="𝔊",
["rightarrow"]="→",
["rhov"]="ϱ",
-["rdquo"]="”",
-["rharul"]="⥬",
-["frac34"]="¾",
-["ldrdhar"]="⥧",
-["gnsim"]="⋧",
-["rtriltri"]="⧎",
-["emsp"]=" ",
-["rlarr"]="⇄",
-["Oslash"]="Ø",
-["LeftDownTeeVector"]="⥡",
+["Alpha"]="Α",
+["rho"]="ρ",
+["DownLeftTeeVector"]="⥞",
+["ntriangleright"]="⋫",
["reg"]="®",
-["LeftTeeVector"]="⥚",
-["gsiml"]="⪐",
-["QUOT"]="\"",
-["blk14"]="░",
-["rightrightarrows"]="⇉",
-["NotGreaterGreater"]="≫̸",
-["Xscr"]="𝒳",
-["Re"]="ℜ",
-["Ouml"]="Ö",
+["Int"]="∬",
+["agrave"]="à",
+["Ecirc"]="Ê",
+["NotReverseElement"]="∌",
+["backprime"]="‵",
+["Jfr"]="𝔍",
["rdsh"]="↳",
-["and"]="∧",
-["larrb"]="⇤",
-["TripleDot"]="⃛",
-["bcy"]="б",
-["diams"]="♦",
-["veebar"]="⊻",
-["rcub"]="}",
-["Scirc"]="Ŝ",
-["ac"]="∾",
-["rceil"]="⌉",
-["rcedil"]="ŗ",
-["cupbrcap"]="⩈",
-["rcaron"]="ř",
-["cuesc"]="⋟",
-["HilbertSpace"]="ℋ",
-["plus"]="+",
-["rbrkslu"]="⦐",
-["LessLess"]="⪡",
-["macr"]="¯",
-["notinE"]="⋹̸",
+["jsercy"]="ј",
+["Bscr"]="ℬ",
+["boxH"]="═",
+["leq"]="≤",
+["NotPrecedes"]="⊀",
+["coloneq"]="≔",
+["boxvh"]="┼",
+["larr"]="←",
+["ncup"]="⩂",
+["EmptySmallSquare"]="◻",
+["vartriangleleft"]="⊲",
+["iacute"]="í",
+["nVDash"]="⊯",
+["lap"]="⪅",
+["precapprox"]="⪷",
+["ecolon"]="≕",
+["lsqb"]="[",
["rbarr"]="⤍",
-["abreve"]="ă",
-["sqcup"]="⊔",
-["ratail"]="⤚",
-["VeryThinSpace"]=" ",
-["Uarrocir"]="⥉",
-["rarrfs"]="⤞",
-["Odblac"]="Ő",
-["Imacr"]="Ī",
-["ordm"]="º",
-["odsold"]="⦼",
-["NJcy"]="Њ",
-["Yacute"]="Ý",
-["rarrbfs"]="⤠",
-["prop"]="∝",
-["notin"]="∉",
-["vsupne"]="⊋︀",
-["bigcap"]="⋂",
-["Phi"]="Φ",
-["Ograve"]="Ò",
-["Yscr"]="𝒴",
-["approx"]="≈",
-["racute"]="ŕ",
-["ggg"]="⋙",
-["lmoust"]="⎰",
+["yacy"]="я",
+["efDot"]="≒",
+["ratio"]="∶",
+["wreath"]="≀",
+["nearhk"]="⤤",
+["rarrpl"]="⥅",
+["nvge"]="≥⃒",
+["searrow"]="↘",
+["thorn"]="þ",
+["rdquo"]="”",
+["LessFullEqual"]="≦",
+["nvrtrie"]="⊵⃒",
+["nsubseteqq"]="⫅̸",
+["nedot"]="≐̸",
+["VerticalLine"]="|",
+["lsh"]="↰",
+["DownRightVector"]="⇁",
+["ecirc"]="ê",
+["andv"]="⩚",
+["trie"]="≜",
+["race"]="∽̱",
["rBarr"]="⤏",
-["gneqq"]="≩",
-["isinv"]="∈",
-["harr"]="↔",
-["rArr"]="⇒",
-["rAarr"]="⇛",
-["quot"]="\"",
+["lbrksld"]="⦏",
+["emsp14"]=" ",
+["RuleDelayed"]="⧴",
+["vsubne"]="⊊︀",
+["ShortLeftArrow"]="←",
+["gtlPar"]="⦕",
["quest"]="?",
-["iuml"]="ï",
-["LeftRightArrow"]="↔",
-["LeftDoubleBracket"]="⟦",
-["gesdot"]="⪀",
-["Ntilde"]="Ñ",
-["boxUR"]="╚",
-["exist"]="∃",
-["subnE"]="⫋",
-["ograve"]="ò",
-["qopf"]="𝕢",
-["Zacute"]="Ź",
-["qfr"]="𝔮",
-["dcy"]="д",
-["NotReverseElement"]="∌",
-["DotEqual"]="≐",
-["VerticalLine"]="|",
-["pscr"]="𝓅",
-["prurel"]="⊰",
-["cdot"]="ċ",
-["bprime"]="‵",
-["ltdot"]="⋖",
-["prnsim"]="⋨",
-["curlywedge"]="⋏",
-["prnE"]="⪵",
-["REG"]="®",
-["sup3"]="³",
+["dot"]="˙",
+["RightVector"]="⇀",
+["rppolint"]="⨒",
+["Hat"]="^",
+["zcy"]="з",
+["suplarr"]="⥻",
+["boxhU"]="╨",
+["puncsp"]=" ",
+["GreaterLess"]="≷",
+["psi"]="ψ",
+["ncaron"]="ň",
+["SupersetEqual"]="⊇",
+["propto"]="∝",
["preceq"]="⪯",
-["LeftDownVectorBar"]="⥙",
-["ForAll"]="∀",
+["frac56"]="⅚",
+["NotLessGreater"]="≸",
+["jukcy"]="є",
+["swArr"]="⇙",
+["profline"]="⌒",
+["prnE"]="⪵",
+["larrpl"]="⤹",
+["af"]="⁡",
+["profsurf"]="⌓",
+["Larr"]="↞",
["forkv"]="⫙",
-["varpi"]="ϖ",
-["nrArr"]="⇏",
+["prcue"]="≼",
+["RightUpTeeVector"]="⥜",
["pound"]="£",
+["ugrave"]="ù",
+["popf"]="𝕡",
+["frac78"]="⅞",
+["suphsol"]="⟉",
+["loplus"]="⨭",
+["pointint"]="⨕",
+["cupcap"]="⩆",
+["LessTilde"]="≲",
+["pm"]="±",
+["blacksquare"]="▪",
["plustwo"]="⨧",
-["shchcy"]="щ",
-["cacute"]="ć",
-["Dashv"]="⫤",
-["lHar"]="⥢",
-["NotLeftTriangle"]="⋪",
-["gbreve"]="ğ",
-["boxDl"]="╖",
-["Beta"]="Β",
-["ReverseEquilibrium"]="⇋",
+["copy"]="©",
+["plussim"]="⨦",
+["Lcy"]="Л",
+["pluse"]="⩲",
+["ropar"]="⦆",
+["OpenCurlyQuote"]="‘",
["plusacir"]="⨣",
-["eqslantgtr"]="⪖",
-["ecy"]="э",
-["pitchfork"]="⋔",
-["ctdot"]="⋯",
-["odiv"]="⨸",
-["lesseqqgtr"]="⪋",
-["GreaterLess"]="≷",
-["Ocy"]="О",
-["weierp"]="℘",
-["Uring"]="Ů",
-["period"]=".",
-["nis"]="⋼",
-["cudarrr"]="⤵",
-["boxHU"]="╩",
-["Ouml"]="Ö",
-["Assign"]="≔",
-["Lscr"]="ℒ",
-["parallel"]="∥",
-["there4"]="∴",
-["cupor"]="⩅",
-["nwarr"]="↖",
-["para"]="¶",
-["ouml"]="ö",
-["otimes"]="⊗",
-["drbkarow"]="⤐",
-["puncsp"]=" ",
-["otilde"]="õ",
-["Vvdash"]="⊪",
-["osol"]="⊘",
+["Exists"]="∃",
+["piv"]="ϖ",
+["phmmat"]="ℳ",
+["angzarr"]="⍼",
+["vsupnE"]="⫌︀",
+["phi"]="φ",
+["perp"]="⊥",
+["rdldhar"]="⥩",
+["ccirc"]="ĉ",
+["Tfr"]="𝔗",
+["Tcy"]="Т",
+["circeq"]="≗",
+["InvisibleTimes"]="⁢",
+["OElig"]="Œ",
+["trisb"]="⧍",
+["Rcaron"]="Ř",
+["olt"]="⧀",
+["UpArrow"]="↑",
+["DDotrahd"]="⤑",
+["Uarrocir"]="⥉",
+["lacute"]="ĺ",
["oslash"]="ø",
-["dd"]="ⅆ",
-["NotPrecedesSlantEqual"]="⋠",
-["orv"]="⩛",
-["orslope"]="⩗",
-["KJcy"]="Ќ",
-["larrfs"]="⤝",
-["orderof"]="ℴ",
-["asympeq"]="≍",
-["ord"]="⩝",
-["NotLess"]="≮",
-["NotGreater"]="≯",
-["ThinSpace"]=" ",
-["ominus"]="⊖",
+["Uarr"]="↟",
+["bsolb"]="⧅",
+["gt"]=">",
+["ordm"]="º",
+["Itilde"]="Ĩ",
+["ordm"]="º",
+["Jscr"]="𝒥",
+["Rarr"]="↠",
+["measuredangle"]="∡",
["DoubleLongLeftRightArrow"]="⟺",
-["lesseqgtr"]="⋚",
+["lmidot"]="ŀ",
+["period"]=".",
["operp"]="⦹",
-["quaternions"]="ℍ",
-["boxdR"]="╒",
-["omega"]="ω",
-["Kscr"]="𝒦",
-["lessgtr"]="≶",
-["utilde"]="ũ",
-["olt"]="⧀",
-["Rho"]="Ρ",
-["olcir"]="⦾",
-["oint"]="∮",
+["bprime"]="‵",
+["numsp"]=" ",
+["ominus"]="⊖",
+["nldr"]="‥",
["ograve"]="ò",
-["Succeeds"]="≻",
-["Igrave"]="Ì",
-["eogon"]="ę",
-["Uacute"]="Ú",
-["bbrk"]="⎵",
-["ocy"]="о",
-["bcong"]="≌",
+["omicron"]="ο",
+["nearr"]="↗",
+["jcirc"]="ĵ",
+["nlE"]="≦̸",
+["deg"]="°",
+["frac13"]="⅓",
+["tcy"]="т",
+["lowbar"]="_",
+["vfr"]="𝔳",
+["ogon"]="˛",
+["sim"]="∼",
+["ocirc"]="ô",
+["Icirc"]="Î",
+["ocir"]="⊚",
+["ZeroWidthSpace"]="​",
["oast"]="⊛",
+["smile"]="⌣",
+["bigvee"]="⋁",
["oacute"]="ó",
-["cir"]="○",
-["angmsdab"]="⦩",
-["Iscr"]="ℐ",
-["ldquo"]="“",
-["RightVector"]="⇀",
-["euml"]="ë",
-["between"]="≬",
-["oS"]="Ⓢ",
-["downdownarrows"]="⇊",
-["nvlt"]="<⃒",
-["lurdshar"]="⥊",
-["starf"]="★",
-["xlarr"]="⟵",
-["Aring"]="Å",
-["Xi"]="Ξ",
-["gtcir"]="⩺",
-["Nscr"]="𝒩",
-["elinters"]="⏧",
-["ntrianglelefteq"]="⋬",
-["Vbar"]="⫫",
+["Egrave"]="È",
+["nwnear"]="⤧",
+["nwarhk"]="⤣",
+["rationals"]="ℚ",
+["DiacriticalGrave"]="`",
+["npreceq"]="⪯̸",
+["rarrc"]="⤳",
+["Uogon"]="Ų",
+["InvisibleComma"]="⁣",
+["nvltrie"]="⊴⃒",
+["digamma"]="ϝ",
+["cirE"]="⧃",
+["AMP"]="&",
+["Theta"]="Θ",
+["frac15"]="⅕",
+["fnof"]="ƒ",
+["icirc"]="î",
+["Cdot"]="Ċ",
+["ngsim"]="≵",
+["sube"]="⊆",
+["tcaron"]="ť",
["ntilde"]="ñ",
-["andv"]="⩚",
-["Rsh"]="↱",
-["angmsdad"]="⦫",
-["nsup"]="⊅",
-["nbsp"]=" ",
-["SquareSupersetEqual"]="⊒",
-["ETH"]="Ð",
-["nsube"]="⊈",
-["DoubleContourIntegral"]="∯",
-["nsubE"]="⫅̸",
-["angmsdah"]="⦯",
-["NotLessGreater"]="≸",
-["awint"]="⨑",
-["rtri"]="▹",
-["nsc"]="⊁",
-["boxvl"]="┤",
-["beta"]="β",
-["LessSlantEqual"]="⩽",
-["supsub"]="⫔",
-["agrave"]="à",
-["LeftUpTeeVector"]="⥠",
-["nrarrw"]="↝̸",
-["ltcc"]="⪦",
-["nrarrc"]="⤳̸",
-["frac78"]="⅞",
-["nvrArr"]="⤃",
-["igrave"]="ì",
-["barwed"]="⌅",
-["Mscr"]="ℳ",
-["nrarr"]="↛",
-["SubsetEqual"]="⊆",
-["notnivc"]="⋽",
-["notnivb"]="⋾",
-["succcurlyeq"]="≽",
-["eth"]="ð",
-["notinva"]="∉",
-["Otilde"]="Õ",
-["star"]="☆",
-["rangd"]="⦒",
-["Psi"]="Ψ",
-["nsupe"]="⊉",
-["mapstoup"]="↥",
-["LJcy"]="Љ",
-["looparrowleft"]="↫",
-["nlarr"]="↚",
-["Ll"]="⋘",
-["ordf"]="ª",
-["ni"]="∋",
+["ufr"]="𝔲",
+["Mcy"]="М",
["Delta"]="Δ",
-["NotVerticalBar"]="∤",
-["backcong"]="≌",
-["NoBreak"]="⁠",
+["vnsup"]="⊃⃒",
+["lAtail"]="⤛",
+["DoubleUpArrow"]="⇑",
+["aelig"]="æ",
+["lscr"]="𝓁",
+["Rscr"]="ℛ",
+["capcup"]="⩇",
+["npolint"]="⨔",
+["gesdotol"]="⪄",
+["uacute"]="ú",
+["bumpE"]="⪮",
+["drcorn"]="⌟",
+["notnivb"]="⋾",
+["notinvc"]="⋶",
+["ovbar"]="⌽",
+["Mopf"]="𝕄",
+["NotGreater"]="≯",
+["boxDr"]="╓",
+["lrcorner"]="⌟",
+["nleq"]="≰",
+["nleftarrow"]="↚",
+["nle"]="≰",
+["boxvl"]="┤",
+["Downarrow"]="⇓",
+["hcirc"]="ĥ",
["nharr"]="↮",
+["tfr"]="𝔱",
+["nlt"]="≮",
+["gacute"]="ǵ",
+["colone"]="≔",
+["Rang"]="⟫",
["ngt"]="≯",
-["Pscr"]="𝒫",
-["laemptyv"]="⦴",
-["utrif"]="▴",
-["ngeq"]="≱",
-["ncedil"]="ņ",
-["ncaron"]="ň",
-["boxhu"]="┴",
-["NotSquareSuperset"]="⊐̸",
-["bull"]="•",
+["ntilde"]="ñ",
+["vcy"]="в",
+["boxvL"]="╡",
+["NotLeftTriangleBar"]="⧏̸",
+["NestedGreaterGreater"]="≫",
+["xmap"]="⟼",
+["napid"]="≋̸",
+["LeftTriangleBar"]="⧏",
["SquareSubsetEqual"]="⊑",
-["VerticalSeparator"]="❘",
-["natur"]="♮",
-["ffr"]="𝔣",
-["rdquor"]="”",
-["lagran"]="ℒ",
-["nRightarrow"]="⇏",
-["nLtv"]="≪̸",
-["nLl"]="⋘̸",
-["Epsilon"]="Ε",
-["csup"]="⫐",
-["leftarrow"]="←",
-["nGt"]="≫⃒",
-["multimap"]="⊸",
-["mstpos"]="∾",
-["SuchThat"]="∋",
-["mldr"]="…",
-["midast"]="*",
-["Sum"]="∑",
-["vartheta"]="ϑ",
-["mapsto"]="↦",
-["nsupseteq"]="⊉",
-["Oscr"]="𝒪",
-["forall"]="∀",
-["aring"]="å",
-["ltimes"]="⋉",
-["ltcir"]="⩹",
-["lt"]="<",
-["ii"]="ⅈ",
-["equest"]="≟",
-["scsim"]="≿",
-["lsqb"]="[",
-["lsimg"]="⪏",
-["Egrave"]="È",
-["Downarrow"]="⇓",
-["lsim"]="≲",
-["eqslantless"]="⪕",
-["ucirc"]="û",
-["Auml"]="Ä",
-["lnsim"]="⋦",
-["uplus"]="⊎",
-["lhblk"]="▄",
-["Ugrave"]="Ù",
-["dlcrop"]="⌍",
-["OElig"]="Œ",
-["lesg"]="⋚︀",
-["lesdotor"]="⪃",
-["eg"]="⪚",
-["lvertneqq"]="≨︀",
-["leqslant"]="⩽",
-["ccups"]="⩌",
-["lceil"]="⌈",
-["auml"]="ä",
-["RightCeiling"]="⌉",
-["lbrksld"]="⦏",
-["lbarr"]="⤌",
+["eacute"]="é",
+["ne"]="≠",
+["ncongdot"]="⩭̸",
+["boxvR"]="╞",
+["PrecedesEqual"]="⪯",
+["Omacr"]="Ō",
+["egs"]="⪖",
+["ouml"]="ö",
+["nbsp"]=" ",
+["xuplus"]="⨄",
+["napprox"]="≉",
+["CloseCurlyQuote"]="’",
+["nacute"]="ń",
+["Chi"]="Χ",
+["subsub"]="⫕",
+["gescc"]="⪩",
+["gcirc"]="ĝ",
+["Lsh"]="↰",
+["sfr"]="𝔰",
+["circlearrowright"]="↻",
+["rcaron"]="ř",
+["ThinSpace"]=" ",
+["otilde"]="õ",
+["TRADE"]="™",
+["cudarrl"]="⤸",
["lat"]="⪫",
-["Rscr"]="ℛ",
-["Zcy"]="З",
-["bigwedge"]="⋀",
-["Prime"]="″",
+["nLeftrightarrow"]="⇎",
+["leqq"]="≦",
+["dagger"]="†",
+["dstrok"]="đ",
+["sacute"]="ś",
+["Amacr"]="Ā",
+["mumap"]="⊸",
+["models"]="⊧",
+["DiacriticalAcute"]="´",
+["minusd"]="∸",
+["hybull"]="⁃",
+["ijlig"]="ij",
+["fflig"]="ff",
+["NotGreaterEqual"]="≱",
+["Colon"]="∷",
+["boxV"]="║",
+["DotDot"]="⃜",
+["mdash"]="—",
+["hairsp"]=" ",
+["bcong"]="≌",
+["mcomma"]="⨩",
+["cirfnint"]="⨐",
+["TScy"]="Ц",
+["luruhar"]="⥦",
+["awconint"]="∳",
+["nsim"]="≁",
+["els"]="⪕",
+["imof"]="⊷",
+["lpar"]="(",
+["lozenge"]="◊",
+["oint"]="∮",
+["Umacr"]="Ū",
+["Sum"]="∑",
+["lopar"]="⦅",
+["racute"]="ŕ",
+["LessEqualGreater"]="⋚",
+["Wedge"]="⋀",
+["bbrktbrk"]="⎶",
+["RightDownTeeVector"]="⥝",
+["HumpDownHump"]="≎",
+["rarrb"]="⇥",
+["longleftrightarrow"]="⟷",
+["lnE"]="≨",
+["NotGreaterSlantEqual"]="⩾̸",
+["Nu"]="Ν",
+["NotNestedLessLess"]="⪡̸",
+["UpEquilibrium"]="⥮",
+["boxhD"]="╥",
+["el"]="⪙",
["boxDR"]="╔",
-["scnsim"]="⋩",
-["efDot"]="≒",
-["kopf"]="𝕜",
-["minusdu"]="⨪",
-["kappav"]="ϰ",
+["Gdot"]="Ġ",
+["itilde"]="ĩ",
+["isindot"]="⋵",
+["GreaterEqualLess"]="⋛",
+["Ll"]="⋘",
+["nrarrw"]="↝̸",
+["supnE"]="⫌",
+["epsiv"]="ϵ",
+["Element"]="∈",
+["gtreqless"]="⋛",
+["laemptyv"]="⦴",
+["nGt"]="≫⃒",
+["angsph"]="∢",
+["lE"]="≦",
+["kscr"]="𝓀",
+["Ocy"]="О",
+["LowerLeftArrow"]="↙",
+["dopf"]="𝕕",
+["iukcy"]="і",
+["atilde"]="ã",
+["DoubleRightArrow"]="⇒",
+["oslash"]="ø",
+["rarr"]="→",
+["intprod"]="⨼",
+["hookrightarrow"]="↪",
+["intcal"]="⊺",
+["infintie"]="⧝",
+["escr"]="ℯ",
+["iiota"]="℩",
+["curren"]="¤",
+["Bernoullis"]="ℬ",
+["angmsdah"]="⦯",
+["ShortRightArrow"]="→",
+["boxUR"]="╚",
+["ges"]="⩾",
+["DoubleDownArrow"]="⇓",
+["NotSquareSuperset"]="⊐̸",
+["lsim"]="≲",
+["bump"]="≎",
+["curlyeqsucc"]="⋟",
+["SHCHcy"]="Щ",
+["frac45"]="⅘",
+["qint"]="⨌",
+["Precedes"]="≺",
+["RightTeeArrow"]="↦",
+["frac16"]="⅙",
+["euro"]="€",
+["smtes"]="⪬︀",
+["eth"]="ð",
+["ldquo"]="“",
+["equivDD"]="⩸",
+["Oopf"]="𝕆",
["boxVh"]="╫",
-["Uuml"]="Ü",
-["centerdot"]="·",
-["isinsv"]="⋳",
-["isins"]="⋴",
-["bot"]="⊥",
-["integers"]="ℤ",
-["Racute"]="Ŕ",
-["ijlig"]="ij",
-["bernou"]="ℬ",
-["Cconint"]="∰",
-["doteq"]="≐",
-["hookleftarrow"]="↩",
-["epar"]="⋕",
-["harrw"]="↭",
-["dzigrarr"]="⟿",
-["Zscr"]="𝒵",
-["alpha"]="α",
-["times"]="×",
+["GreaterSlantEqual"]="⩾",
+["KJcy"]="Ќ",
["egrave"]="è",
-["UnionPlus"]="⊎",
-["Qscr"]="𝒬",
-["Omacr"]="Ō",
-["Zfr"]="ℨ",
-["gneq"]="⪈",
-["divonx"]="⋇",
-["gesdotol"]="⪄",
-["gvertneqq"]="≩︀",
-["geq"]="≥",
-["utri"]="▵",
-["ge"]="≥",
-["vArr"]="⇕",
-["Rrightarrow"]="⇛",
-["frac25"]="⅖",
-["LeftCeiling"]="⌈",
-["GreaterGreater"]="⪢",
-["LT"]="<",
-["Longrightarrow"]="⟹",
-["eqcolon"]="≕",
-["ofcir"]="⦿",
-["boxUl"]="╜",
-["Wscr"]="𝒲",
-["Sacute"]="Ś",
-["Union"]="⋃",
-["gg"]="≫",
-["DownArrowBar"]="⤓",
-["Escr"]="ℰ",
-["ecirc"]="ê",
-["Lmidot"]="Ŀ",
-["Wedge"]="⋀",
-["frown"]="⌢",
-["ring"]="˚",
-["dtdot"]="⋱",
-["Ccedil"]="Ç",
-["Conint"]="∯",
-["dscr"]="𝒹",
-["Map"]="⤅",
-["EmptyVerySmallSquare"]="▫",
-["backsim"]="∽",
-["angzarr"]="⍼",
-["dHar"]="⥥",
-["Mfr"]="𝔐",
-["cirE"]="⧃",
-["Popf"]="ℙ",
-["NestedGreaterGreater"]="≫",
-["ReverseElement"]="∋",
-["boxVr"]="╟",
+["NotGreaterLess"]="≹",
+["boxVl"]="╢",
+["MediumSpace"]=" ",
+["LongLeftArrow"]="⟵",
+["uarr"]="↑",
+["Ocirc"]="Ô",
+["Idot"]="İ",
+["bumpe"]="≏",
+["nwArr"]="⇖",
+["NegativeThinSpace"]="​",
+["coprod"]="∐",
+["VerticalBar"]="∣",
+["sccue"]="≽",
+["boxDl"]="╖",
+["NotSubset"]="⊂⃒",
+["Edot"]="Ė",
+["scy"]="с",
+["Cup"]="⋓",
+["centerdot"]="·",
+["nsimeq"]="≄",
+["DownLeftRightVector"]="⥐",
}
diff --git a/macros/luatex/generic/luaxml/luaxml-transform.lua b/macros/luatex/generic/luaxml/luaxml-transform.lua
index b6841fea5f..4b51eed117 100644
--- a/macros/luatex/generic/luaxml/luaxml-transform.lua
+++ b/macros/luatex/generic/luaxml/luaxml-transform.lua
@@ -198,6 +198,10 @@ local function add_action(selector, template, parameters, csspar)
end
+local function reset_actions(selector, csspar)
+ local css = csspar or css
+ css:remove_selector(selector)
+end
--- Transform XML string
@@ -243,7 +247,7 @@ end
local Transformer
--- Make new Transformer object
--- @return Tranformer object
+-- @return Transformer object
local function new()
local self = setmetatable({}, Transformer)
self.css = cssquery()
@@ -289,6 +293,12 @@ function Transformer:add_custom_action(selector, fn )
add_custom_action(selector, fn, self.css)
end
+--- Remove all actions that match the given selector
+---@param selector string
+function Transformer:reset_actions(selector)
+ reset_actions(selector, self.css)
+end
+
-- all methods that use transformation functions must
-- correctly handle the cssquery object that this library uses
@@ -338,6 +348,7 @@ local M = {
print_tex = print_tex,
add_action = add_action,
add_custom_action = add_custom_action,
+ reset_actions = reset_actions,
simple_content = simple_content,
load_file = load_file,
process_dom = process_dom,
diff --git a/macros/luatex/generic/luaxml/luaxml.pdf b/macros/luatex/generic/luaxml/luaxml.pdf
index f574a0a528..071fa4e4cd 100644
--- a/macros/luatex/generic/luaxml/luaxml.pdf
+++ b/macros/luatex/generic/luaxml/luaxml.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaxml/luaxml.tex b/macros/luatex/generic/luaxml/luaxml.tex
index 5031a0468e..bf3b8fbaa7 100644
--- a/macros/luatex/generic/luaxml/luaxml.tex
+++ b/macros/luatex/generic/luaxml/luaxml.tex
@@ -7,7 +7,7 @@
\usepackage{framed}
% Version is defined in the makefile, use default values when compiled directly
\ifdefined\version\else
-\def\version{v0.1r}
+\def\version{v0.2}
\let\gitdate\date
\fi
\newcommand\modulename[1]{\subsection{#1}\label{sec:#1}}
@@ -99,6 +99,67 @@ end
\end{luacode*}
\end{framed}
+\subsection{HTML parsing}
+
+You can parse HTML documents using the \verb|DOM_Object.html_parse| function. This parser is slower
+than the default XML parser, but it can load files that would cause errors in the XML mode.
+It can handle wrongly nested HTML tags, inline JavaScript and CSS styles, and other HTML features
+that would cause XML errors.
+
+\begin{verbatim}
+dom = require "luaxml-domobject"
+local document = [[
+<html>
+<head><title>sample</title></head>
+<body>
+<h1>test</h1>
+<p>hello
+<p>another paragraph
+<ul>
+<li>first
+<li>second
+</ul>
+</body>
+</html>
+ ]]
+
+-- dom.html_parse returns the DOM_Object
+obj = dom.html_parse(document)
+-- print names of all elements contained in body
+for _, x in ipairs(obj:query_selector("body *")) do
+ tex.print(x:get_element_name().. "\\par")
+end
+\end{verbatim}
+
+
+\begin{framed}
+\begin{luacode*}
+dom = require "luaxml-domobject"
+local document = [[
+<html>
+<head><title>sample</title></head>
+<body>
+<h1>test</h1>
+<p>hello
+<p>another paragraph
+<ul>
+<li>first
+<li>second
+</ul>
+</body>
+</html>
+ ]]
+
+-- dom.html_parse returns the DOM_Object
+obj = dom.html_parse(document)
+-- print names of all elements contained in body
+for _, x in ipairs(obj:query_selector("body *")) do
+ tex.print(x:get_element_name().. "\\par")
+end
+\end{luacode*}
+\end{framed}
+
+
\subsection{Void elements}
The \verb|DOM_Object.parse| function tries to support the HTML void elements,
@@ -641,6 +702,35 @@ transform.print_tex("\\verb|" .. result .. "|")
\end{luacode*}
\end{framed}
+\section{Character sets handling}
+
+The \texttt{luaxml-encodings} library provides functions to convert texts in legacy 8-bit encodings such as WINDOWS-1250
+or ISO-8859-2 to UTF-8. This can be useful in fixing document encoding before HTML parsing using the \texttt{luaxml-mod-html}
+library.
+
+\subsection{Example}
+
+
+\begin{verbatim}
+kpse.set_program_name "luatex"
+local encodings = require "luaxml-encodings"
+
+--read HTML page from the standard input
+local text = io.read("*all")
+-- find the character encoding in HTML metadata
+local enc = encodings.find_html_encoding(text)
+if enc then
+ -- local conversion table for the found encoding
+ local mapping = encodings.load_mapping(enc)
+ if mapping then
+ -- if the mapping exists, recode the HTML input and print it
+ local converted = encodings.recode(text, mapping)
+ print(converted)
+ end
+end
+\end{verbatim}
+
+
\section{The API documentation}