diff options
Diffstat (limited to 'macros/luatex/latex/longmath/longmath.sty')
-rw-r--r-- | macros/luatex/latex/longmath/longmath.sty | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/macros/luatex/latex/longmath/longmath.sty b/macros/luatex/latex/longmath/longmath.sty new file mode 100644 index 0000000000..2b4848db3c --- /dev/null +++ b/macros/luatex/latex/longmath/longmath.sty @@ -0,0 +1,223 @@ +%% +%% longmath.sty is part of longmath version 0.1. +%% +%% (c) 2024 Hans-Jürgen Matschull +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2005/12/01 or later. +%% +%% This work has the LPPL maintenance status 'maintained'. +%% +%% The Current Maintainer of this work is Hans-Jürgen Matschull +%% +%% see README for a list of files belonging to longmath. +%% +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{longmath}[2024/03/25] + +\RequirePackage{luatexbase} + +% generic attribute used to mark special objects and send mathstyle to Lua. +\newattribute\longmath@info + +% attribute to tag large operators. +\newattribute\longmath@limits +\def\ignorelimits{\setattribute{\longmath@limits}{1}} +\def\includelimits{\unsetattribute{\longmath@limits}} + +% Save original primitives. +\let \longmath@left \left +\let \longmath@middle \middle +\let \longmath@right \right + +\directlua{ require( 'longmath.lua' ) } + +% Registers. +\newcount\delimiterscale \delimiterscale 902 +\newdimen\longmathlinesep \longmathlinesep 3pt + +\newif\iflongmath@star +\newcount\longmath@lines +\newdimen\longmath@extra +\newdimen\longmath@width +\newcount\longmath@xscale +\newcount\longmath@yscale +\newbox\longmath@box + +% The prefix for tags. +\def\longmath@prefix{} +\def\delimiterprefix#1{\def\longmath@prefix{#1}} + +% User macros +\def\lleft {\longmath@delimA \mathopen {1000}{opn}} +\def\rright {\longmath@delimA \mathclose {1000}{cls}} +\def\mleft {\longmath@delimA \mathopen {1000}{mid}} +\def\mright {\longmath@delimA \mathclose {1000}{mid}} +\def\mmord {\longmath@delimA \mathord \delimiterscale {mid}} +\def\mmbin {\longmath@delimA \mathbin \delimiterscale {mid}} +\def\mmrel {\longmath@delimA \mathrel \delimiterscale {mid}} +\def\mmpunct{\longmath@delimA \mathpunct \delimiterscale {mid}} +\def\mmiddle{\longmath@delimA \mathinner \delimiterscale {mid}} +\def\mmop {\longmath@delimA \mathop \delimiterscale {mid}} + +% This sets the math atom type, the default scale factor, and the command to be send to Lua, +% then checks if a tag in {} is following. +\def\longmath@delimA #1#2#3{\begingroup + \let\longmath@type #1 \longmath@xscale = #2 \relax \edef\longmath@comm{#3} + \futurelet \longmath@token \longmath@delimB } + +% If a tag is following, read it. Otherwise, skip this step. +\def\longmath@delimB{\ifx\longmath@token\bgroup \expandafter \longmath@delimC + \else \expandafter \longmath@delimD \fi } + +% Read the tag, prepend the prefix and append a @, then add it to the command. +\def\longmath@delimC #1{\edef\longmath@comm{\longmath@comm:\longmath@prefix#1@} \longmath@delimD } + +% Read the optional scale factor. If none is given, the scale is set to 0. +\def\longmath@delimD #1{\afterassignment\longmath@delimE \longmath@yscale = 0#1} + +% This creates a \special whatsit with the command as string argument, followed by +% a fake delimiter group with the requested delimiter always being the right one. +% For the delimiter nodes, the info attribute is set to the current math style. +% For the empty \hbox, it is set to the requested scale factor. +\def\longmath@delimE{ + \setattribute\longmath@info{\mathstyle} \special{\longmath@comm} + \longmath@type\bgroup \longmath@left . \aftergroup\egroup \aftergroup\endgroup + \begingroup \setattribute\longmath@info{\ifnum \longmath@yscale < 1 \longmath@xscale \else \longmath@yscale \fi} + \hbox to -\nulldelimiterspace{} \endgroup + \longmath@right } + + +% magic number to identify the variable delimiter. +\delcode`* = "FEFEFE %" + +% scanner to read the delimiter sample and create a nested \left-\right-group. +\def\longmath@autoL #1#2\relax{\ifx *#1 \longmath@autoR #2\relax + \else \longmath@left #1 \longmath@autoL #2\relax \fi } +\def\longmath@autoR #1#2\relax{\ifx *#1 + \else \longmath@right #1 \longmath@autoR #2\relax \fi} + +% Read the sample provided by the user, insert a set command, and typeset it into a box. +\def\autodelimiters #1{\begingroup \longmath@info = 0 + \setbox\longmath@box\hbox{$ \special{set} \longmath@autoL #1***\relax $} + \endgroup\aftergroup\longmath@autoreset} + +% To make the setting local to the current TeX group, send a reset command at the end of the group. +\def\longmath@autoreset{\begingroup \longmath@info = 0 + \setbox\longmath@box\hbox{$ \special{res} {} $} + \endgroup} + + +% Counter for automatic tag generation. +\newcount\longmath@tagnum + +% Stack to store pushed tags, separated by spaces. +\def\longmath@stack{} + +% Create a unique tag. +\def\longmath@unique{ + \global\advance\longmath@tagnum\@ne + \global\edef\longmath@stack{@\the\longmath@tagnum\space\longmath@stack} +} + +% Create an invisible closing delimiter. +\def\pushdelimiter{\longmath@unique + \expandafter\longmath@push\longmath@stack\relax} + +\def\longmath@push #1 #2\relax{\ifmmode\begingroup + \def\longmath@comm{mid:#1} \let\longmath@type\mathclose \longmath@yscale=1\relax + \longmath@delimE . \fi} + +% Create an invisible opening delimiter. +\def\pulldelimiter{\ifx\longmath@stack\empty \longmath@unique \fi + \expandafter\longmath@pull\longmath@stack\relax} + +\def\longmath@pull #1 #2\relax{\global\edef\longmath@stack{#2}\ifmmode\begingroup + \def\longmath@comm{mid:#1} \let\longmath@type\mathopen \longmath@yscale=1\relax + \longmath@delimE . \fi} + + +% Read width argument for the longmath environment. +% Expects to numbers or dimensions terminted by +. +% Numbers are multplied by \hsize. +\def\longmath@gobble #1\relax{} +\def\longmath@setwidth #1+#2+#3\relax{ + \afterassignment\longmath@gobble \longmath@width = #1 \hsize \relax + \afterassignment\longmath@gobble \longmath@extra = #2 \hsize \relax } + +% Alignment for the longmath box. +\let\longmath@align@t@\vtop +\let\longmath@align@b@\vbox +\let\longmath@align@c@\vcenter + +% Save and restore the current math style. +\newcount\longmath@style +\def\longmath@getstyle{\longmath@style = \mathstyle \relax} +\def\longmath@setstyle{\ifcase\longmath@style \relax \displaystyle \or \crampeddisplaystyle \or + \textstyle \or \crampedtextstyle \or \scriptstyle \or \crampedscriptstyle \or + \scriptscriptstyle \or \crampedscriptscriptstyle \else \textstyle \fi } + +% Begin of longmath environment. +% Set alignment and width and save the current math style. +% Then start a horizontal box in math mode. +\def\longmath@begin #1#2{\begingroup + \expandafter\let\expandafter\longmath@align\csname longmath@align@#1@\endcsname + \ifx \longmath@align\relax \let\longmath@align\longmath@align@c@ \fi + \longmath@getstyle \longmath@setwidth #2+0+\relax + %\rlap{\textcolor{green}{\rule{\longmath@width}{0.1pt}}\textcolor{yellow}{\rule{\longmath@extra}{0.1pt}}} + \setbox\longmath@box\hbox\bgroup $ \mathpenaltiesmode = 1 \longmath@setstyle +} + +% End of longmath environment. +% If the width of the box is smaller than the requsted width, just use it as is. +% Otherwise, modify the requested width if the * version was used. +% Then \unhbox the content into a paragraph with the requested width. +% \box0 and \box1 are used to adapt the baselineskip to the math style. +% \leftskip and \rightskip are set such that lines are centered but not justified. +% The glue is removed from the beginning of the first line with \hskip, +% and from the end of the last line with \parfilskip. +% If \longmath@extra is non-zero, Lua will stack the lines of the paragraph. +\def\longmath@end{$\egroup + \ifdim \wd\longmath@box < \dimexpr \longmath@width + \longmath@extra \relax + \longmath@extra = \z@ + \box\longmath@box + \else + \iflongmath@star + \longmath@lines = \dimexpr ( 1.1\wd\longmath@box + 0.5\longmath@width ) / \longmath@width \relax + \longmath@width = \dimexpr ( 1.1\wd\longmath@box / \longmath@lines ) + \fi + \setbox0\hbox{$1$} + \setbox1\hbox{$\longmath@setstyle 1$} + \longmath@align{\hsize\longmath@width + \baselineskip \dimexpr \baselineskip * \ht1 / \ht0 \relax \lineskip\z@ \lineskiplimit\z@ + \openup \longmathlinesep + \leftskip 0pt plus 0.6\longmath@width + \rightskip 0pt plus 0.6\longmath@width + \parfillskip-\rightskip \noindent\hskip-\leftskip \unhbox\longmath@box} + \longmath@extra = \z@ + \fi \endgroup +} + +\newenvironment{longmath}[2][c] + {\longmath@starfalse\longmath@begin{#1}{#2}}{\longmath@end} +\newenvironment{longmath*}[2][c] + {\longmath@startrue\longmath@begin{#1}{#2}}{\longmath@end} + +% Read the dimensions of tagged groups from the aux file. +\def\longmath@group#1#2{\directlua{longmath.read_group({#1},{#2})}} +\def\longmath@skip#1#2{} + +% Save the dimensions of the tagged groups at the end of the document. +\def\longmath@save{\let\longmath@group\longmath@skip\directlua{longmath.save_groups(\the\@auxout)}} +\AtEndDocument{\longmath@save} + + + + + + |