summaryrefslogtreecommitdiff
path: root/macros
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2024-02-29 03:02:00 +0000
committerNorbert Preining <norbert@preining.info>2024-02-29 03:02:00 +0000
commitcd2d035c39e23ef720cdd58ad3e377f7c60e9858 (patch)
treeca7f11c779775df04a7709bdd75d46d53b380f2e /macros
parent0afdc3e8c2d8e96d0cd0a5f05f1481a4eecc51d2 (diff)
CTAN sync 202402290301
Diffstat (limited to 'macros')
-rw-r--r--macros/latex/contrib/didec/CHANGES.md27
-rw-r--r--macros/latex/contrib/didec/README.md42
-rw-r--r--macros/latex/contrib/didec/didec.doc.sty157
-rw-r--r--macros/latex/contrib/didec/didec.pdfbin0 -> 495045 bytes
-rw-r--r--macros/latex/contrib/didec/didec.sty1349
-rw-r--r--macros/latex/contrib/didec/didec.tex1209
-rw-r--r--macros/latex/contrib/easybook/easybook.dtx10
-rw-r--r--macros/latex/contrib/easybook/easybook.pdfbin604258 -> 604372 bytes
-rw-r--r--macros/latex/contrib/easybook/easybook.tex8
-rw-r--r--macros/latex/contrib/mandi/mandi.dtx147
-rw-r--r--macros/latex/contrib/mandi/mandi.ins4
-rw-r--r--macros/latex/contrib/mandi/mandi.pdfbin514465 -> 516791 bytes
-rw-r--r--macros/latex/contrib/mandi/mandiexp.dtx8
-rw-r--r--macros/latex/contrib/mandi/mandistudent.dtx14
-rw-r--r--macros/luatex/generic/luaotfload/NEWS4
-rw-r--r--macros/luatex/generic/luaotfload/README.md2
-rw-r--r--macros/luatex/generic/luaotfload/filegraph.pdfbin40007 -> 40007 bytes
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-basics-gen.lua3
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-arabic.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-colors.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-conf.pdfbin79376 -> 79552 bytes
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-configuration.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-database.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-dvi.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-embolden.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-fallback.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-features.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-filelist.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-harf-define.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua21
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-harf-var-cff2.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-harf-var-t2-writer.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-harf-var-ttf.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-init.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-latex.pdfbin506279 -> 506592 bytes
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-letterspace.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-loaders.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-log.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-main.tex10
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-multiscript.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-notdef.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-parsers.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-realpath.lua28
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-resolvers.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-scripts.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-status.lua62
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-suppress.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-szss.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.142
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.pdfbin76779 -> 76970 bytes
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.rst2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tounicode.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-unicode.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload.conf.56
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload.conf.rst2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload.sty2
-rw-r--r--macros/luatex/generic/luaotfload/scripts-demo.pdfbin21682 -> 21682 bytes
-rw-r--r--macros/luatex/generic/luaotfload/shaper-demo-graphite.pdfbin8562 -> 8562 bytes
-rw-r--r--macros/luatex/generic/luaotfload/shaper-demo.pdfbin8478 -> 8478 bytes
64 files changed, 3010 insertions, 211 deletions
diff --git a/macros/latex/contrib/didec/CHANGES.md b/macros/latex/contrib/didec/CHANGES.md
new file mode 100644
index 0000000000..388a94cf06
--- /dev/null
+++ b/macros/latex/contrib/didec/CHANGES.md
@@ -0,0 +1,27 @@
+# Changelog
+All notable changes to this project will be documented in this file.
+
+The format is based on
+[Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
+and this project adheres to
+[Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+
+## [Unreleased]
+
+### Added
+### Changed
+### Deprecated
+### Removed
+### Fixed
+### Security
+
+
+
+## [1.0.0] - 2024-02-28
+
+### Added
+- Initial public release
+
+
+## [-.-.-]
+- Not public releases
diff --git a/macros/latex/contrib/didec/README.md b/macros/latex/contrib/didec/README.md
new file mode 100644
index 0000000000..d3027e39f5
--- /dev/null
+++ b/macros/latex/contrib/didec/README.md
@@ -0,0 +1,42 @@
+# The LaTeX package didec - version 1.0.0 (2024/02/28)
+
+> Copyright (c) 2024-2024 by Prof. Dr. Dr. Thomas F. Sturm <thomas dot sturm at unibw dot de>
+
+> 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 `author-maintained`.
+
+> This work consists of all files listed in README.md
+
+
+The `didec` package supports fixed-point arithmetic with two
+decimal places (di-decimal) which is typical for financial
+transactions in many currencies.
+The intended use case is (personal) bookkeeping.
+
+
+## Contents of the package
+
+- `README.md` this file
+- `CHANGES.md` log of changes (history)
+- `didec.sty` LaTeX package file (style file)
+- `didec.pdf` Documentation for didec
+- `didec.tex` Source code of the documentation
+- `didec.doc.sty` Source code of the documentation
+
+
+## Installation
+
+Copy the contents of the `didec.tds.zip` from CTAN to your local TeX file tree.
+
+Alternatively, put the files to their respective locations within the TeX installation:
+
+- `didec.sty` -> /tex/latex/didec
+- all other files -> /doc/latex/didec
+
diff --git a/macros/latex/contrib/didec/didec.doc.sty b/macros/latex/contrib/didec/didec.doc.sty
new file mode 100644
index 0000000000..0e5944e43f
--- /dev/null
+++ b/macros/latex/contrib/didec/didec.doc.sty
@@ -0,0 +1,157 @@
+% !TeX root = didec.tex
+% !TeX encoding=UTF-8
+%% The LaTeX package didec - version 1.0.0 (2024/02/28)
+%% didec.doc.sty: style file for the documentation
+%%
+%% -------------------------------------------------------------------------------------------
+%% Copyright (c) 2024-2024 by Prof. Dr. Dr. Thomas F. Sturm <thomas dot sturm at unibw dot de>
+%% -------------------------------------------------------------------------------------------
+%%
+%% 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 `author-maintained'.
+%%
+%% This work consists of all files listed in README.md
+%%
+% include file (style) of didec.tex (manual of the LaTeX package didec)
+
+\def\version{1.0.0}%
+\def\datum{2024/02/28}%
+
+\IfFileExists{didec.doc.cfg}{\input{didec.doc.cfg}}{}
+
+\renewcommand*\l@subsection{\@dottedtocline{2}{1.5em}{2.7em}}
+\renewcommand*\l@subsubsection{\@dottedtocline{3}{4.2em}{3.2em}}
+
+\RequirePackage[T1]{fontenc}
+\RequirePackage[english]{babel}
+\RequirePackage{lmodern,parskip,array}
+\RequirePackage[svgnames,table]{xcolor}
+\RequirePackage{tikz}
+\RequirePackage{varioref}
+\RequirePackage[makeindex]{imakeidx}
+\RequirePackage[bookmarks,raiselinks,pageanchor,hyperindex,colorlinks]{hyperref}
+\RequirePackage{cleveref}
+\RequirePackage{varwidth,incgraph}
+\RequirePackage[official]{eurosym}
+
+\RequirePackage[a4paper,left=2.5cm,right=2.5cm,top=1.5cm,bottom=1.5cm,
+ marginparsep=3mm,marginparwidth=18mm,
+ headheight=0mm,headsep=0cm,
+ footskip=1.5cm,includeheadfoot%,showframe
+ ]{geometry}
+\RequirePackage{fancyhdr}
+\fancyhf{}
+\fancyfoot[C]{\thepage}%
+\renewcommand{\headrulewidth}{0pt}
+\renewcommand{\footrulewidth}{0pt}
+\pagestyle{fancy}
+\tolerance=2000%
+\setlength{\emergencystretch}{20pt}%
+
+\RequirePackage{array,tabularx,booktabs}
+\RequirePackage{lipsum}
+\RequirePackage[extendedchars,encoding,filenameencoding=utf-8]{grffile}
+\RequirePackage{siunitx,xfp}
+
+\RequirePackage{tcolorbox}
+\tcbuselibrary{skins,minted,breakable,documentation,raster}
+
+\ifdefined\didecpackageprefix
+ \RequirePackage{\didecpackageprefix didec}
+\else
+ \RequirePackage{didec}
+\fi
+
+\definecolor{Green_Dark}{rgb}{0.078431,0.407843,0.176471}
+\definecolor{Blue_Dark}{rgb}{0.090196,0.211765,0.364706}
+\definecolor{Blue_Bright}{rgb}{0.858824,0.898039,0.945098}
+
+\colorlet{Blue_Gray}{blue!50!gray}
+
+\tcbset{skin=enhanced,
+ doc head={colback=yellow!10!white,interior style=fill},
+ doc head key={colback=magenta!5!white,interior style=fill},
+ color key=DarkViolet,
+ color value=Teal,
+ color color=Teal,
+ color counter=Orange!85!black,
+ color length=Orange!85!black,
+ index colorize,
+ index annotate,
+ beforeafter example/.style={
+ before skip=4pt plus 2pt minus 1pt,
+ after skip=8pt plus 4pt minus 2pt
+ },
+ docexample/.style={bicolor,
+ beforeafter example,
+ arc=0.66mm,
+ boxrule=0.33mm,
+ fonttitle=\bfseries,
+ fontlower=\footnotesize,
+ colframe=Blue_Gray,
+ colback=Blue_Gray!5!white,
+ colbacklower=white,
+ drop small lifted shadow,
+ listing engine=minted,
+ documentation minted options={tabsize=2,fontsize=\small,breaklines,autogobble},
+ documentation minted style=colorful,
+ },
+}
+\urlstyle{sf}
+
+\newtcblisting{fullexample}[1]{docexample,minted style=colorful,
+ listing and comment,pdf comment,freeze pdf,compilable listing,#1}
+
+\DeclareTotalTCBox{\myverb}{ O{} v }{tile,fontupper=\ttfamily,nobeforeafter,
+ tcbox raise base,boxsep=0.5mm,top=0pt,bottom=0pt,left=0pt,right=0pt,boxrule=0.3mm,
+ colback=yellow!10,
+ borderline horizontal={0.3mm}{0pt}{red!50},
+ #1}{#2}
+
+\renewcommand*{\tcbdocnew}[1]{\textcolor{green!50!black}{\sffamily\bfseries N} #1}
+\renewcommand*{\tcbdocupdated}[1]{\textcolor{blue!75!black}{\sffamily\bfseries U} #1}
+
+\newcommand{\formatPackageOption}[1]{package option}
+\newcommand{\formatPackageOptions}[1]{Package options}
+
+\tcbmakedocSubKey[doc key prefix=]{docDidecKey}{didec}
+\tcbmakedocSubKeys[doc key prefix=]{docDidecKeys}{didec}
+\tcbmakedocSubKey[doc key prefix=,
+ index key formatter=\formatPackageOption,
+ index keys formatter=\formatPackageOptions
+]{docPackageOption}{didec}
+\tcbmakedocSubKeys[doc key prefix=,
+ index key formatter=\formatPackageOption,
+ index keys formatter=\formatPackageOptions
+]{docPackageOptions}{didec}
+
+
+\tcbset{
+ deprecated*/.style={%
+ doc head={colback=black!1!white,interior style=fill},
+ doc head key={colback=black!3!white,interior style=fill},
+ color command={black!80!white},
+ color option={black!60!white},
+ },
+ deprecated/.style={%
+ deprecated*,
+ before doc body command={\textcolor{black!80!white}{\textsc{Deprecated! }}}
+ },
+}
+
+\ExplSyntaxOn
+\NewDocumentCommand \docColorExample { m }
+ {
+ \color_group_begin:
+ \color_select:n { #1 }
+ \rule[-1mm]{5mm}{4mm}~\docColor{#1}
+ \color_group_end:
+ }
+\ExplSyntaxOff
diff --git a/macros/latex/contrib/didec/didec.pdf b/macros/latex/contrib/didec/didec.pdf
new file mode 100644
index 0000000000..b9d867eb7c
--- /dev/null
+++ b/macros/latex/contrib/didec/didec.pdf
Binary files differ
diff --git a/macros/latex/contrib/didec/didec.sty b/macros/latex/contrib/didec/didec.sty
new file mode 100644
index 0000000000..885e28b258
--- /dev/null
+++ b/macros/latex/contrib/didec/didec.sty
@@ -0,0 +1,1349 @@
+%% The LaTeX package didec - version 1.0.0 (2024/02/28)
+%% didec.sty: numbers with two decimal places
+%% !TeX encoding=UTF-8
+%%
+%% -------------------------------------------------------------------------------------------
+%% Copyright (c) 2024-2024 by Prof. Dr. Dr. Thomas F. Sturm <thomas dot sturm at unibw dot de>
+%% -------------------------------------------------------------------------------------------
+%%
+%% 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 `author-maintained'.
+%%
+%% This work consists of all files listed in README.md
+%%
+\NeedsTeXFormat{LaTeX2e}[2023-11-01]
+\ProvidesExplPackage{didec}{2024/02/28}{1.0.0}
+ {Fixed-point arithmetic with two decimal places}
+
+%------- package options -------------------
+
+\DeclareKeys
+ {
+ int .code:n =
+ {
+ \prg_set_conditional:Nnn \didec_if_kernel_int: { p, T, TF } { \prg_return_true: }
+ \prg_set_conditional:Nnn \didec_if_kernel_fp: { p, T, TF } { \prg_return_false: }
+ },
+ fp .code:n =
+ {
+ \prg_set_conditional:Nnn \didec_if_kernel_int: { p, T, TF } { \prg_return_false: }
+ \prg_set_conditional:Nnn \didec_if_kernel_fp: { p, T, TF } { \prg_return_true: }
+ },
+ }
+
+\ProcessKeyOptions
+
+\cs_if_exist:NF \didec_if_kernel_int_p:
+ {
+ \SetKeys{ int }
+ }
+
+%------- integer kernel (int) -------------------
+
+\if_predicate:w \didec_if_kernel_int_p:
+
+\str_const:Nn \c_didec_kernel_str { int }
+
+% <int>
+% test on existence of didec variable #1
+% adapted from \cs_if_exist:c
+\prg_new_conditional:Npnn \didec_if_exist:n #1 { p, T, F, TF }
+ {
+ \if_cs_exist:w g_didec_var_#1_int \cs_end:
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ {
+ \exp_after:wN \if_meaning:w \cs:w g_didec_var_#1_int \cs_end: \scan_stop:
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+ \prg_return_false:
+ }
+
+% <int>
+% #1 integer value
+\prg_new_conditional:Npnn \__didec_if_negative:n #1 { TF }
+ {
+ \if_int_compare:w #1 < \c_zero_int
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+
+% <int>
+% #1 didec variable
+\prg_new_conditional:Npnn \didec_if_negative:n #1 { p, T, F, TF }
+ {
+ \if_int_compare:w \didec_to_int:n { #1 } < \c_zero_int
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+
+% <int>
+% #1 didec variable
+\prg_new_conditional:Npnn \didec_if_positive:n #1 { p, T, F, TF }
+ {
+ \if_int_compare:w \didec_to_int:n { #1 } > \c_zero_int
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+
+% <int>
+% #1 didec variable
+\prg_new_conditional:Npnn \didec_if_zero:n #1 { p, T, F, TF }
+ {
+ \if_int_compare:w \didec_to_int:n { #1 } = \c_zero_int
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+
+% <int>
+% #1 didec variable
+% #2 relation
+% #3 didec variable
+\prg_new_conditional:Npnn \didec_compare:nNn #1#2#3 { p, T, F, TF }
+ {
+ \if_int_compare:w \__didec_eval:n { #1 } #2 \__didec_eval:n { #3 }
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+
+% <int>
+% #1 didec variable
+\cs_new:Npn \didec_to_int:n #1
+ {
+ \int_use:c { g_didec_var_#1_int }
+ }
+
+% <int>
+% #1 didec variable
+\cs_new_protected:Npn \didec_new:n #1
+ {
+ \didec_if_exist:nTF { #1 }
+ {
+ \msg_error:nne { didec }{ already-defined }{ #1 }
+ }
+ {
+ \int_new:c { g_didec_var_#1_int }
+ }
+ }
+
+% <int>
+% Sets didec variable #1 to the current value of didec variable #2
+\cs_new_protected:Npn \didec_gset_eq:nn #1#2
+ {
+ \int_gset_eq:cc { g_didec_var_#1_int }{ g_didec_var_#2_int }
+ }
+
+% <int>
+% set didec variable #1 to integer value #2
+\cs_new_protected:Npn \__didec_gset_int:nn #1#2
+ {
+ \int_gset:cn { g_didec_var_#1_int }{ #2 }
+ }
+
+% <int>
+% add integer #2 to didec variable #1
+\cs_new_protected:Npn \__didec_gadd_int:nn #1#2
+ {
+ \int_gadd:cn { g_didec_var_#1_int }{ #2 }
+ }
+
+\fi:
+
+%------- floating point kernel (fp) -------------------
+
+\if_predicate:w \didec_if_kernel_fp_p:
+
+\str_const:Nn \c_didec_kernel_str { fp }
+
+% <fp>
+% test on existence of didec variable #1
+% adapted from \cs_if_exist:c
+\prg_new_conditional:Npnn \didec_if_exist:n #1 { p, T, F, TF }
+ {
+ \if_cs_exist:w g_didec_var_#1_fp \cs_end:
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ {
+ \exp_after:wN \if_meaning:w \cs:w g_didec_var_#1_fp \cs_end: \scan_stop:
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+ \prg_return_false:
+ }
+
+% <fp>
+% #1 large integer value
+\prg_new_conditional:Npnn \__didec_if_negative:n #1 { TF }
+ {
+ \exp_last_unbraced:Ne \token_if_eq_charcode:NNTF { \tl_head:n { #1 } }{ - }
+ {
+ \prg_return_true:
+ }
+ {
+ \prg_return_false:
+ }
+ }
+
+% <fp>
+% #1 didec variable
+\prg_new_conditional:Npnn \didec_if_negative:n #1 { p, T, F, TF }
+ {
+ \exp_last_unbraced:Ne \token_if_eq_charcode:NNTF { \exp_args:Ne \tl_head:n { \didec_to_int:n { #1 } } }{ - }
+ {
+ \prg_return_true:
+ }
+ {
+ \prg_return_false:
+ }
+ }
+
+% <fp>
+% #1 didec variable
+\prg_new_conditional:Npnn \didec_if_positive:n #1 { p, T, F, TF }
+ {
+ \exp_args:Ne \__didec_if_positive_token:n { \exp_args:Ne \tl_head:n { \didec_to_int:n { #1 } } }
+ }
+
+% <fp>
+% #1 didec variable
+\cs_new:Npn \__didec_if_positive_token:n #1
+ {
+ \token_if_eq_charcode:NNTF { #1 }{ - }
+ {
+ \prg_return_false:
+ }
+ {
+ \token_if_eq_charcode:NNTF { #1 }{ 0 }
+ {
+ \prg_return_false:
+ }
+ {
+ \prg_return_true:
+ }
+ }
+ }
+
+% <fp>
+% #1 didec variable
+\prg_new_conditional:Npnn \didec_if_zero:n #1 { p, T, F, TF }
+ {
+ \exp_last_unbraced:Ne \token_if_eq_charcode:NNTF { \exp_args:Ne \tl_head:n { \didec_to_int:n { #1 } } }{ 0 }
+ {
+ \prg_return_true:
+ }
+ {
+ \prg_return_false:
+ }
+ }
+
+% <fp>
+% #1 didec variable
+% #2 relation
+% #3 didec variable
+\prg_new_conditional:Npnn \didec_compare:nNn #1#2#3 { p, T, F, TF }
+ {
+ \fp_compare:nNnTF { \__didec_eval:n { #1 } } #2 { \__didec_eval:n { #3 } }
+ {
+ \prg_return_true:
+ }
+ {
+ \prg_return_false:
+ }
+ }
+
+% <fp>
+% #1 didec variable
+\cs_new:Npn \didec_to_int:n #1
+ {
+ \fp_use:c { g_didec_var_#1_fp }
+ }
+
+% <fp>
+% #1 didec variable
+\cs_new_protected:Npn \didec_new:n #1
+ {
+ \didec_if_exist:nTF { #1 }
+ {
+ \msg_error:nne { didec }{ already-defined }{ #1 }
+ }
+ {
+ \fp_new:c { g_didec_var_#1_fp }
+ }
+ }
+
+% <fp>
+% Sets didec variable #1 to the current value of didec variable #2
+\cs_new_protected:Npn \didec_gset_eq:nn #1#2
+ {
+ \fp_gset_eq:cc { g_didec_var_#1_fp }{ g_didec_var_#2_fp }
+ }
+
+% <fp>
+% set didec variable #1 to integer value #2
+\cs_new_protected:Npn \__didec_gset_int:nn #1#2
+ {
+ \fp_gset:cn { g_didec_var_#1_fp }{ #2 }
+ }
+
+% <fp>
+% add integer #2 to didec variable #1
+\cs_new_protected:Npn \__didec_gadd_int:nn #1#2
+ {
+ \fp_gadd:cn { g_didec_var_#1_fp }{ #2 }
+ }
+
+
+\fi:
+
+
+%------- didec variables -------------------
+
+
+\cs_new:Npn \__didec_if_exist_else_error:nT #1#2
+ {
+ \didec_if_exist:nTF { #1 }
+ {
+ #2
+ }
+ {
+ \msg_error:nne { didec }{ no-variable }{ #1 }
+ }
+ }
+
+
+% set didec variable #1 to didec expression #2
+% #1 didec variable
+% #2 didec expression
+\cs_new_protected:Npn \didec_gset:nn #1#2
+ {
+ \__didec_gset_int:nn { #1 }{ \__didec_eval:n { #2 } }
+ }
+
+
+% set didec variable #1 to didec expression #2
+% #1 didec variable
+% #2 didec expression
+\cs_new_protected:Npn \didec_gset_negative:nn #1#2
+ {
+ \__didec_gset_int:nn { #1 }{ - \__didec_eval:n { #2 } }
+ }
+
+
+% set didec variable #1 to floating-point expression #2
+% #1 didec variable
+% #2 floating-point expression
+\cs_new_protected:Npn \didec_gset_fp:nn #1#2
+ {
+ \__didec_gset_int:nn { #1 }{ \fp_to_int:n { (#2)*100 } }
+ }
+
+
+% add didec expression #2 to didec variable #1
+% #1 didec variable
+% #2 didec expression
+\cs_new_protected:Npn \didec_gadd:nn #1#2
+ {
+ \__didec_gadd_int:nn { #1 }{ \__didec_eval:n { #2 } }
+ }
+
+
+% add sum of didec expression #2 and #3 to didec variable #1
+% #1 didec variable
+% #2 didec expression
+% #3 didec expression
+\cs_new_protected:Npn \didec_gadd_to:nnn #1#2#3
+ {
+ \__didec_gset_int:nn { #1 }{ \__didec_eval:n { #2 } + \__didec_eval:n { #3 } }
+ }
+
+
+% subtract didec expression #2 from didec variable #1
+% #1 didec variable
+% #2 didec expression
+\cs_new_protected:Npn \didec_gsub:nn #1#2
+ {
+ \__didec_gadd_int:nn { #1 }{ - \__didec_eval:n { #2 } }
+ }
+
+
+% set didec variable #1 to the difference of didec expression #2 and #3
+% #1 didec variable
+% #2 didec expression
+% #3 didec expression
+\cs_new_protected:Npn \didec_gsub_to:nnn #1#2#3
+ {
+ \__didec_gset_int:nn { #1 }{ \__didec_eval:n { #2 } - \__didec_eval:n { #3 } }
+ }
+
+
+% multiply didec variable #1 with floating-point expression #2
+% #1 didec variable
+% #2 floating-point expression
+\cs_new_protected:Npn \didec_gmul_fp:nn #1#2
+ {
+ \__didec_gset_int:nn { #1 }{ \fp_to_int:n { \didec_to_int:n { #1 } * (#2) } }
+ }
+
+
+% set didec variable #1 to the product of didec variable #2 with floating-point expression #3
+% #1 didec variable
+% #2 didec variable
+% #3 floating-point expression
+\cs_new_protected:Npn \didec_gmul_fp_to:nnn #1#2#3
+ {
+ \__didec_gset_int:nn { #1 }{ \fp_to_int:n { \didec_to_int:n { #2 } * (#3) } }
+ }
+
+
+% divide didec variable #1 by floating-point expression #2
+% #1 didec variable
+% #2 floating-point expression
+\cs_new_protected:Npn \didec_gdiv_fp:nn #1#2
+ {
+ \__didec_gset_int:nn { #1 }{ \fp_to_int:n { \didec_to_int:n { #1 } / (#2) } }
+ }
+
+
+% set didec variable #1 to the quotient of didec variable #2 with floating-point expression #3
+% #1 didec variable
+% #2 didec variable
+% #3 floating-point expression
+\cs_new_protected:Npn \didec_gdiv_fp_to:nnn #1#2#3
+ {
+ \__didec_gset_int:nn { #1 }{ \fp_to_int:n { \didec_to_int:n { #2 } / (#3) } }
+ }
+
+
+%------- formatting didec variables -------------------
+
+
+% fp value of didec variable #1
+% #1 didec variable
+\cs_new:Npn \didec_to_fp:n #1
+ {
+ \exp_args:Nf \__didec_format:nn { \didec_to_int:n {#1} }{ . }
+ }
+
+
+% fp value of didec variable #1
+% #1 didec variable
+\cs_new:Npn \didec_to_fc:n #1
+ {
+ \exp_args:Nf \__didec_format:nn { \didec_to_int:n {#1} }{ , }
+ }
+
+
+% #1 (large) integer value (from didec variable)
+% #2 decimal separator
+\cs_new:Npn \__didec_format:nn #1#2
+ {
+ \__didec_if_negative:nTF { #1 }
+ { - \exp_args:No \__didec_format_pos:nn { \use_none:n #1 }{ #2 } }
+ { \__didec_format_pos:nn { #1 }{ #2 } }
+ }
+
+\cs_new:Npn \__didec_format_pos:nn #1#2
+ {
+ \exp_args:Ne \__didec_format_pos_i:w { \tl_count:n {#1} }{ #2 } #1 \q_nil \q_nil \q_nil \q_nil \q_nil \q_nil \q_stop
+ }
+
+\cs_new:Npn \__didec_format_pos_i:w #1#2#3#4#5#6#7#8#9 \q_stop
+ {
+ \if_case:w #1 \exp_stop_f:
+ \or: 0 #2 0 #3 % 1
+ \or: 0 #2 #3#4 % 2
+ \or: #3 #2 #4#5 % 3
+ \or: #3#4 #2 #5#6 % 4
+ \or: #3#4#5 #2 #6#7 % 5
+ \or: #3#4#5#6 #2 #7#8 % 6
+ \or: #3#4#5#6#7 #2 #8 \__didec_format_pos_ii:w { 0 }{ #2 } #9 \q_stop % 7
+ \or: #3#4#5#6#7#8 #2 \__didec_format_pos_ii:w { 1 }{ #2 } #9 \q_stop % 8
+ \or: #3#4#5#6#7#8 \__didec_format_pos_ii:w { 2 }{ #2 } #9 \q_stop % 9
+ \or: #3#4#5#6#7#8 \__didec_format_pos_ii:w { 3 }{ #2 } #9 \q_stop % 10
+ \or: #3#4#5#6#7#8 \__didec_format_pos_ii:w { 4 }{ #2 } #9 \q_stop % 11
+ \or: #3#4#5#6#7#8 \__didec_format_pos_ii:w { 5 }{ #2 } #9 \q_stop % 12
+ \or: #3#4#5#6#7#8 \__didec_format_pos_ii:w { 6 }{ #2 } #9 \q_stop % 13
+ \or: #3#4#5#6#7#8 \__didec_format_pos_ii:w { 7 }{ #2 } #9 \q_stop % 14
+ \or: #3#4#5#6#7#8 \__didec_format_pos_ii:w { 8 }{ #2 } #9 \q_stop % 15
+ \or: #3#4#5#6#7#8 \__didec_format_pos_ii:w { 9 }{ #2 } #9 \q_stop % 16
+ \else 0 #2 00 % error
+ \fi:
+ }
+
+\cs_new:Npn \__didec_format_pos_ii:w #1#2#3#4#5#6#7#8#9 \q_stop
+ {
+ \if_case:w #1 \exp_stop_f:
+ #3 % 0 = 7 = 13
+ \or: #3#4 % 1 = 8 = 14
+ \or: #3 #2 #4#5 % 2 = 9 = 15
+ \or: #3#4 #2 #5#6 % 3 = 10 = 16
+ \or: #3#4#5 #2 #6#7 % 4 = 11
+ \or: #3#4#5#6 #2 #7#8 % 5 = 12
+ \or: #3#4#5#6#7 #2 #8 \__didec_format_pos_ii:w { 0 }{ #2 } #9 \q_stop % 6 = 13
+ \or: #3#4#5#6#7#8 #2 \__didec_format_pos_ii:w { 1 }{ #2 } #9 \q_stop % 7 = 14
+ \or: #3#4#5#6#7#8 \__didec_format_pos_ii:w { 2 }{ #2 } #9 \q_stop % 8 = 15
+ \or: #3#4#5#6#7#8 \__didec_format_pos_ii:w { 3 }{ #2 } #9 \q_stop % 9 = 16
+ \fi:
+ }
+
+
+% #1 (large) integer value (from didec variable)
+% #2 positive extra
+% #3 negative extra
+\cs_new:Npn \__didec_format_group:nnn #1#2#3
+ {
+ \__didec_if_negative:nTF { #1 }
+ {
+ #3
+ \l__didec_currency_negative_prefix_tl
+ \exp_args:No \__didec_format_group_pos:nnn
+ { \use_none:n #1 }
+ { \l__didec_decimal_separator_tl }
+ { \l__didec_grouping_separator_tl }
+ \l__didec_currency_negative_postfix_tl
+ }
+ {
+ #2
+ \l__didec_currency_prefix_tl
+ \__didec_format_group_pos:nnn
+ { #1 }
+ { \l__didec_decimal_separator_tl }
+ { \l__didec_grouping_separator_tl }
+ \l__didec_currency_postfix_tl
+ }
+ }
+
+\cs_new:Npn \__didec_format_group_pos:nnn #1#2#3
+ {
+ \exp_args:Ne \__didec_format_group_pos_i:w { \tl_count:n {#1} }{ #2 }{ #3 } #1 \q_nil \q_nil \q_nil \q_nil \q_nil \q_stop
+ }
+
+\cs_new:Npn \__didec_format_group_pos_i:w #1#2#3#4#5#6#7#8#9 \q_stop
+ {
+ \if_case:w #1 \exp_stop_f:
+ \or: 0 #2 0 #4 % 1
+ \or: 0 #2 #4#5 % 2
+ \or: #4 #2 #5#6 % 3
+ \or: #4#5 #2 #6#7 % 4
+ \or: #4#5#6 #2 #7#8 % 5
+ \or: #4 #3 #5#6#7 #2 #8 \__didec_format_group_pos_ii:w { 0 }{ #2 }{ #3 } #9 \q_stop % 6
+ \or: #4#5 #3 #6#7#8 #2 \__didec_format_group_pos_ii:w { 1 }{ #2 }{ #3 } #9 \q_stop % 7
+ \or: #4#5#6 #3 #7#8 \__didec_format_group_pos_ii:w { 2 }{ #2 }{ #3 } #9 \q_stop % 8
+ \or: #4 #3 #5#6#7 #3 #8 \__didec_format_group_pos_ii:w { 3 }{ #2 }{ #3 } #9 \q_stop % 9
+ \or: #4#5 #3 #6#7#8 #3 \__didec_format_group_pos_ii:w { 4 }{ #2 }{ #3 } #9 \q_stop % 10
+ \or: #4#5#6 #3 #7#8 \__didec_format_group_pos_ii:w { 5 }{ #2 }{ #3 } #9 \q_stop % 11
+ \or: #4 #3 #5#6#7 #3 #8 \__didec_format_group_pos_ii:w { 6 }{ #2 }{ #3 } #9 \q_stop % 12
+ \or: #4#5 #3 #6#7#8 #3 \__didec_format_group_pos_ii:w { 7 }{ #2 }{ #3 } #9 \q_stop % 13
+ \or: #4#5#6 #3 #7#8 \__didec_format_group_pos_ii:w { 8 }{ #2 }{ #3 } #9 \q_stop % 14
+ \or: #4 #3 #5#6#7 #3 #8 \__didec_format_group_pos_ii:w { 9 }{ #2 }{ #3 } #9 \q_stop % 15
+ \or: #4#5 #3 #6#7#8 #3 \__didec_format_group_pos_ii:w { 10 }{ #2 }{ #3 } #9 \q_stop % 16
+ \else 1 #2 00 % error
+ \fi:
+ }
+
+\cs_new:Npn \__didec_format_group_pos_ii:w #1#2#3#4#5#6#7#8#9 \q_stop
+ {
+ \if_case:w #1 \exp_stop_f:
+ #4 % 0 = 6 = 11
+ \or: #4#5 % 1 = 7 = 12
+ \or: #4 #2 #5#6 % 2 = 8 = 13
+ \or: #4#5 #2 #6#7 % 3 = 9 = 14
+ \or: #4#5#6 #2 #7#8 % 4 = 10 = 15
+ \or: #4 #3 #5#6#7 #2 #8 \__didec_format_group_pos_ii:w { 0 }{ #2 }{ #3 } #9 \q_stop % 5 = 11 = 16
+ \or: #4#5 #3 #6#7#8 #2 \__didec_format_group_pos_ii:w { 1 }{ #2 }{ #3 } #9 \q_stop % 6 = 12
+ \or: #4#5#6 #3 #7#8 \__didec_format_group_pos_ii:w { 2 }{ #2 }{ #3 } #9 \q_stop % 7 = 13
+ \or: #4 #3 #5#6#7 #3 #8 \__didec_format_group_pos_ii:w { 3 }{ #2 }{ #3 } #9 \q_stop % 8 = 14
+ \or: #4#5 #3 #6#7#8 #3 \__didec_format_group_pos_ii:w { 4 }{ #2 }{ #3 } #9 \q_stop % 9 = 15
+ \or: #4#5#6 #3 #7#8 \__didec_format_group_pos_ii:w { 5 }{ #2 }{ #3 } #9 \q_stop % 10 = 16
+ \fi:
+ }
+
+
+% #1 didec variable
+% #2 stream
+\cs_new_protected:Npn \didec_write:nn #1#2
+ {
+ \iow_now:Ne #2
+ {
+ \c_backslash_str didecset
+ { #1 }
+ { \didec_to_fp:n { #1 } }
+ \c_percent_str
+ }
+ }
+
+
+% #1 didec variable
+% #2 stream
+\cs_new_protected:Npn \didec_write_check:nn #1#2
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \didec_write:nn { #1 }{ #2 }
+ }
+ }
+
+
+
+%------- number scanner -------------------
+
+% Evaluates #1 and leaves the result in the input stream as an integer denotation
+% #1 can be a single didec variable or a number with floating-comma or floating-point
+\cs_new:Npn \__didec_eval:n #1
+ {
+ \exp_args:Ne \__didec_eval_expanded:n { \exp_args:Ne \tl_trim_spaces:n { #1 } }
+ }
+
+
+\cs_new:Npn \__didec_eval_expanded:n #1
+ {
+ \didec_if_exist:nTF { #1 }
+ {
+ \didec_to_int:n { #1 }
+ }
+ {
+ \__didec_eval_p_a:w #1.\q_nil \q_stop
+ }
+ }
+
+
+\cs_new:Npn \__didec_eval_p_a:w #1.#2#3 \q_stop
+ {
+ \quark_if_nil:NTF #2
+ {
+ \__didec_eval_c_a:w #1,\q_nil\q_stop
+ }
+ {
+ #1\__didec_eval_p_b:w #2#3
+ }
+ }
+
+\cs_new:Npn \__didec_eval_p_b:w #1. \q_nil
+ {
+ \__didec_eval_c:w #1 00 \q_stop
+ }
+
+\cs_new:Npn \__didec_eval_c_a:w #1,#2#3 \q_stop
+ {
+ \quark_if_nil:NTF #2
+ {
+ #100
+ }
+ {
+ #1\__didec_eval_c_b:w #2#3
+ }
+ }
+
+\cs_new:Npn \__didec_eval_c_b:w #1, \q_nil
+ {
+ \__didec_eval_c:w #1 00 \q_stop
+ }
+
+\cs_new:Npn \__didec_eval_c:w #1#2#3 \q_stop
+ {
+ #1#2
+ }
+
+
+%------- didec variables (extended) -------------------
+
+% #1 didec variable
+\cs_new_protected:Npn \didec_show:n #1
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \didec_if_kernel_int:T
+ {
+ \int_show:c { g_didec_var_#1_int }
+ }
+ \didec_if_kernel_fp:T
+ {
+ \fp_show:c { g_didec_var_#1_fp }
+ }
+ }
+ }
+
+% #1 didec variable
+\cs_new:Npn \didec_to_int_check:n #1
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \didec_to_int:n { #1 }
+ }
+ }
+
+% #1 didec variable
+\cs_new:Npn \didec_to_fp_check:n #1
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \didec_to_fp:n { #1 }
+ }
+ }
+
+% #1 didec variable
+\cs_new:Npn \didec_to_fc_check:n #1
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \didec_to_fc:n { #1 }
+ }
+ }
+
+
+% set didec variable #1 to integer value #2
+\cs_new_protected:Npn \__didec_gset_int_check:nn #1#2
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \__didec_gset_int:nn { #1 }{ #2 }
+ }
+ }
+
+% Sets didec variable #1 to the current value of didec variable #2
+\cs_new_protected:Npn \didec_gset_eq_check:nn #1#2
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \__didec_if_exist_else_error:nT { #2 }
+ {
+ \didec_gset_eq:nn { #1 }{ #2 }
+ }
+ }
+ }
+
+% set didec variable #1 to didec expression #2
+% #1 didec variable
+% #2 didec expression
+\cs_new_protected:Npn \didec_gset_check:nn #1#2
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \didec_gset:nn { #1 }{ #2 }
+ }
+ }
+
+% set didec variable #1 to didec expression #2
+% #1 didec variable
+% #2 didec expression
+\cs_new_protected:Npn \didec_gset_negative_check:nn #1#2
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \didec_gset_negative:nn { #1 }{ #2 }
+ }
+ }
+
+% set didec variable #1 to floating-point expression #2
+% #1 didec variable
+% #2 floating-point expression
+\cs_new_protected:Npn \didec_gset_fp_check:nn #1#2
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \didec_gset_fp:nn { #1 }{ #2 }
+ }
+ }
+
+% add didec expression #2 to didec variable #1
+% #1 didec variable
+% #2 didec expression
+\cs_new_protected:Npn \didec_gadd_check:nn #1#2
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \didec_gadd:nn { #1 }{ #2 }
+ }
+ }
+
+% add sum of didec expression #2 and #3 to didec variable #1
+% #1 didec variable
+% #2 didec expression
+% #3 didec expression
+\cs_new_protected:Npn \didec_gadd_to_check:nnn #1#2#3
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \didec_gadd_to:nnn { #1 }{ #2 }{ #3 }
+ }
+ }
+
+% subtract didec expression #2 from didec variable #1
+% #1 didec variable
+% #2 didec expression
+\cs_new_protected:Npn \didec_gsub_check:nn #1#2
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \didec_gsub:nn { #1 }{ #2 }
+ }
+ }
+
+% set didec variable #1 to the difference of didec expression #2 and #3
+% #1 didec variable
+% #2 didec expression
+% #3 didec expression
+\cs_new_protected:Npn \didec_gsub_to_check:nnn #1#2#3
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \didec_gsub_to:nnn { #1 }{ #2 }{ #3 }
+ }
+ }
+
+% multiply didec variable #1 with floating-point expression #2
+% #1 didec variable
+% #2 floating-point expression
+\cs_new_protected:Npn \didec_gmul_fp_check:nn #1#2
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \didec_gmul_fp:nn { #1 }{ #2 }
+ }
+ }
+
+% set didec variable #1 to the product of didec variable #2 with floating-point expression #3
+% #1 didec variable
+% #2 didec variable
+% #3 floating-point expression
+\cs_new_protected:Npn \didec_gmul_fp_to_check:nnn #1#2#3
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \didec_gmul_fp_to:nnn { #1 }{ #2 }{ #3 }
+ }
+ }
+
+% divide didec variable #1 by floating-point expression #2
+% #1 didec variable
+% #2 floating-point expression
+\cs_new_protected:Npn \didec_gdiv_fp_check:nn #1#2
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \didec_gdiv_fp:nn { #1 }{ #2 }
+ }
+ }
+
+% set didec variable #1 to the quotient of didec variable #2 with floating-point expression #3
+% #1 didec variable
+% #2 didec variable
+% #3 floating-point expression
+\cs_new_protected:Npn \didec_gdiv_fp_to_check:nnn #1#2#3
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \didec_gdiv_fp_to:nnn { #1 }{ #2 }{ #3 }
+ }
+ }
+
+
+%------- formatting didec variables (extended) -------------------
+
+\tl_new:N \l__didec_decimal_separator_tl
+\tl_new:N \l__didec_grouping_separator_tl
+\tl_new:N \l__didec_currency_prefix_tl
+\tl_new:N \l__didec_currency_postfix_tl
+\tl_new:N \l__didec_currency_negative_prefix_tl
+\tl_new:N \l__didec_currency_negative_postfix_tl
+
+\keys_define:nn { didec }
+ {
+ decimal-separator .tl_set:N = \l__didec_decimal_separator_tl,
+ grouping-separator .tl_set:N = \l__didec_grouping_separator_tl,
+ currency .code:n =
+ {
+ \tl_set:No \l__didec_currency_prefix_tl { \use_i:nn #1 }
+ \tl_set:No \l__didec_currency_postfix_tl { \use_ii:nn #1 }
+ \tl_set:No \l__didec_currency_negative_prefix_tl { \use_i:nn #1 - }
+ \tl_set:No \l__didec_currency_negative_postfix_tl { \use_ii:nn #1 }
+ },
+ currency-negative .code:n =
+ {
+ \tl_set:No \l__didec_currency_negative_prefix_tl { \use_i:nn #1 }
+ \tl_set:No \l__didec_currency_negative_postfix_tl { \use_ii:nn #1 }
+ },
+ german .meta:n =
+ {
+ decimal-separator = {,},
+ grouping-separator = {.},
+ currency = {}{},
+ },
+ english .meta:n =
+ {
+ decimal-separator = {.},
+ grouping-separator = {,},
+ currency = {}{},
+ },
+ french .meta:n =
+ {
+ decimal-separator = {,},
+ grouping-separator = {\;},
+ currency = {}{},
+ },
+ float .meta:n =
+ {
+ decimal-separator = {.},
+ grouping-separator = ,
+ currency = {}{},
+ },
+ color-positive .code:n =
+ {
+ \color_set:nn { didec-positive }{ #1 }
+ },
+ color-negative .code:n =
+ {
+ \color_set:nn { didec-negative }{ #1 }
+ },
+ }
+
+\color_set:nn { didec-gray }{ black!85!white }
+
+\color_set:nnn { didec-green }{ rgb }{ 0, 0.35, 0 }
+\color_set:nnn { didec-red }{ rgb }{ 0.35, 0, 0 }
+\color_set:nnn { didec-blue }{ rgb }{ 0, 0, 0.35 }
+
+
+\keys_set:nn { didec }
+ {
+ german,
+ color-positive = didec-green,
+ color-negative = didec-red,
+ }
+
+% #1 didec variable
+\cs_new:Npn \didec_use:n #1
+ {
+ \exp_args:Nf \__didec_format_group:nnn { \didec_to_int:n {#1} }{}{}
+ }
+
+% #1 didec variable
+\cs_new:Npn \didec_use_check:n #1
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \didec_use:n { #1 }
+ }
+ }
+
+% #1 didec variable
+\cs_new:Npn \didec_color_use:n #1
+ {
+ \color_group_begin:
+ \exp_args:Nf \__didec_format_group:nnn { \didec_to_int:n {#1} }
+ { \color_select:n { didec-positive } }
+ { \color_select:n { didec-negative } }
+ \color_group_end:
+ }
+
+% #1 didec variable
+\cs_new:Npn \didec_color_use_check:n #1
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \didec_color_use:n { #1 }
+ }
+ }
+
+% #1 didec variable
+\cs_new:Npn \didec_color_inverse_use:n #1
+ {
+ \color_group_begin:
+ \exp_args:Nf \__didec_format_group:nnn { \didec_to_int:n {#1} }
+ { \color_select:n { didec-negative } }
+ { \color_select:n { didec-positive } }
+ \color_group_end:
+ }
+
+% #1 didec variable
+\cs_new:Npn \didec_color_inverse_use_check:n #1
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \didec_color_inverse_use:n { #1 }
+ }
+ }
+
+
+%------- messages -------------------
+
+\msg_new:nnnn { didec }{ already-defined }
+ { Didec~variable~'#1'~already~defined. }
+ { You~tried~to~create~a~new~didec~variable~'#1',~but~it~was~already~defined~elsewhere. }
+
+
+\msg_new:nnnn { didec }{ no-variable }
+ { Unknown~didec~variable~'#1'. }
+ { The~didec~variable~'#1'~you~used~is~unknown. }
+
+
+
+%------- didec user functions -------------------
+
+% #1 didec variable
+\NewExpandableDocumentCommand \didectoint { m }
+ {
+ \exp_args:Ne \didec_to_int_check:n{ \tl_trim_spaces:n { #1 } }
+ }
+
+% #1 didec variable
+\NewExpandableDocumentCommand \didectofp { m }
+ {
+ \exp_args:Ne \didec_to_fp_check:n{ \tl_trim_spaces:n { #1 } }
+ }
+
+% #1 didec variable
+\NewExpandableDocumentCommand \didectofc { m }
+ {
+ \exp_args:Ne \didec_to_fc_check:n{ \tl_trim_spaces:n { #1 } }
+ }
+
+% #1 didec variable
+\NewDocumentCommand \didecnew { m }
+ {
+ \exp_args:Ne \didec_new:n{ \tl_trim_spaces:n { #1 } }
+ }
+\NewCommandCopy \didecnewvar \didecnew
+
+% Sets didec variable #1 to the current value of didec variable #2
+\NewDocumentCommand \didecsetequal { m m }
+ {
+ \exp_args:Nee \didec_gset_eq_check:nn { \tl_trim_spaces:n { #1 } }{ \tl_trim_spaces:n { #2 } }
+ }
+
+% set didec variable #1 to didec expression #2
+% #1 didec variable
+% #2 didec expression
+\NewDocumentCommand \didecset { m m }
+ {
+ \exp_args:Ne \didec_gset_check:nn { \tl_trim_spaces:n { #1 } }{ #2 }
+ }
+
+% set didec variable #1 to didec expression #2
+% #1 didec variable
+% #2 didec expression
+\NewDocumentCommand \didecsetnegative { m m }
+ {
+ \exp_args:Ne \didec_gset_negative_check:nn { \tl_trim_spaces:n { #1 } }{ #2 }
+ }
+
+% set didec variable #1 to floating-point expression #2
+% #1 didec variable
+% #2 floating-point expression
+\NewDocumentCommand \didecsetfp { m m }
+ {
+ \exp_args:Ne \didec_gset_fp_check:nn { \tl_trim_spaces:n { #1 } }{ #2 }
+ }
+
+
+% #1 didec variable
+% #2 didec expression / variable
+% #3 didec expression
+\NewDocumentCommand \didecadd { o m m }
+ {
+ \IfNoValueTF {#1}
+ {
+ \exp_args:Ne \didec_gadd_check:nn { \tl_trim_spaces:n { #2 } }{ #3 }
+ }
+ {
+ \exp_args:Ne \didec_gadd_to_check:nnn { \tl_trim_spaces:n { #1 } }{ #2 }{ #3 }
+ }
+ }
+
+
+% #1 didec variable
+% #2 didec expression / variable
+% #3 didec expression
+\NewDocumentCommand \didecsub { o m m }
+ {
+ \IfNoValueTF {#1}
+ {
+ \exp_args:Ne \didec_gsub_check:nn { \tl_trim_spaces:n { #2 } }{ #3 }
+ }
+ {
+ \exp_args:Ne \didec_gsub_to_check:nnn { \tl_trim_spaces:n { #1 } }{ #2 }{ #3 }
+ }
+ }
+
+% #1 didec variable
+% #2 didec variable
+% #3 floating-point expression
+\NewDocumentCommand \didecmulfp { o m m }
+ {
+ \IfNoValueTF {#1}
+ {
+ \exp_args:Ne \didec_gmul_fp_check:nn { \tl_trim_spaces:n { #2 } }{ #3 }
+ }
+ {
+ \exp_args:Nee \didec_gmul_fp_to_check:nnn { \tl_trim_spaces:n { #1 } }{ \tl_trim_spaces:n { #2 } }{ #3 }
+ }
+ }
+
+% #1 didec variable
+% #2 didec variable
+% #3 floating-point expression
+\NewDocumentCommand \didecdivfp { o m m }
+ {
+ \IfNoValueTF {#1}
+ {
+ \exp_args:Ne \didec_gdiv_fp_check:nn { \tl_trim_spaces:n { #2 } }{ #3 }
+ }
+ {
+ \exp_args:Nee \didec_gdiv_fp_to_check:nnn { \tl_trim_spaces:n { #1 } }{ \tl_trim_spaces:n { #2 } }{ #3 }
+ }
+ }
+
+
+% Deprecated
+\NewDocumentCommand \didecmul { >{\TrimSpaces} O{#2} >{\TrimSpaces} m >{\TrimSpaces} m }
+ {
+ \__didec_gset_int_check:nn { #1 }{ \fp_to_int:n { \__didec_eval:n { #2 } / 100 * \__didec_eval:n { #3 } } }
+ }
+
+
+% Deprecated
+\NewDocumentCommand \didecdiv { >{\TrimSpaces} O{#2} >{\TrimSpaces} m >{\TrimSpaces} m }
+ {
+ \__didec_gset_int_check:nn { #1 }{ \fp_to_int:n { \__didec_eval:n { #2 } / \__didec_eval:n { #3 } * 100 } }
+ }
+
+
+% Deprecated
+\NewDocumentCommand \didecpercent { >{\TrimSpaces} O{#2} >{\TrimSpaces} m >{\TrimSpaces} m }
+ {
+ \__didec_gset_int_check:nn { #1 }{ \fp_to_int:n { \__didec_eval:n { #2 } / \__didec_eval:n { #3 } * 10000 } }
+ }
+
+
+\cs_new:Npn \__didec_sum:w #1#2+#3#4 \q_stop
+ {
+ \exp_args:Nne \didec_gadd:nn { #1 }{ #2 }
+ \quark_if_nil:NF #3
+ {
+ \__didec_sum:w {#1} #3#4 \q_stop
+ }
+ }
+
+\didec_new:n {__@temp@__}
+
+% #1 didec variable
+% #2 sum of didec expressions
+\NewDocumentCommand \didecsetsum { m m }
+ {
+ \__didec_if_exist_else_error:nT { #1 }
+ {
+ \__didec_gset_int:nn {__@temp@__}{ 0 }
+ \__didec_sum:w {__@temp@__} #2 + \q_nil \q_stop
+ \didec_gset_eq:nn { #1 }{__@temp@__}
+ }
+ }
+
+
+% Deprecated
+% #1 type (german,english,float)
+% #2 didec expression
+\NewDocumentCommand \didecprint { O{german} m }
+ {
+ \didecset{__@temp@__}{ #2 }
+ \didecuse [ #1 ]{__@temp@__}
+ }
+
+
+\tl_new:N \g__didec_temp_tl
+
+% Deprecated
+% #1 type (german,english,float)
+% #2 didec expression
+% #3 target macro without backslash
+\NewDocumentCommand \didecstore { O{german} m >{\TrimSpaces}m }
+ {
+ \didecset{__@temp@__}{ #2 }
+ \group_begin:
+ \keys_set:nn { didec }{ #1 }
+ \tl_gset:Ne \g__didec_temp_tl { \didec_use:n { __@temp@__ } }
+ \group_end:
+ \cs_set_eq:cN { #3 } \g__didec_temp_tl
+ }
+
+% #1 key list
+% #2 didec variable
+\NewDocumentCommand \didecuse { o m }
+ {
+ \IfNoValueTF {#1}
+ {
+ \exp_args:Ne \didec_use_check:n { \tl_trim_spaces:n { #2 } }
+ }
+ {
+ \group_begin:
+ \keys_set:nn { didec }{ #1 }
+ \exp_args:Ne \didec_use_check:n { \tl_trim_spaces:n { #2 } }
+ \group_end:
+ }
+ }
+
+% #1 key list
+% #2 didec variable
+\NewDocumentCommand \dideccoluse { o m }
+ {
+ \IfNoValueTF {#1}
+ {
+ \exp_args:Ne \didec_color_use_check:n { \tl_trim_spaces:n { #2 } }
+ }
+ {
+ \group_begin:
+ \keys_set:nn { didec }{ #1 }
+ \exp_args:Ne \didec_color_use_check:n { \tl_trim_spaces:n { #2 } }
+ \group_end:
+ }
+ }
+
+% #1 key list
+% #2 didec variable
+\NewDocumentCommand \dideccolinvuse { o m }
+ {
+ \IfNoValueTF {#1}
+ {
+ \exp_args:Ne \didec_color_inverse_use_check:n { \tl_trim_spaces:n { #2 } }
+ }
+ {
+ \group_begin:
+ \keys_set:nn { didec }{ #1 }
+ \exp_args:Ne \didec_color_inverse_use_check:n { \tl_trim_spaces:n { #2 } }
+ \group_end:
+ }
+ }
+
+% #1 key list
+% #2 didec expression
+\NewDocumentCommand \didecformat { o m }
+ {
+ \didec_gset:nn { __@temp@__ }{ #2 }
+ \IfNoValueTF {#1}
+ {
+ \didec_use:n { __@temp@__ }
+ }
+ {
+ \group_begin:
+ \keys_set:nn { didec }{ #1 }
+ \didec_use:n { __@temp@__ }
+ \group_end:
+ }
+ }
+
+% #1 key list
+% #2 didec expression
+\NewDocumentCommand \dideccolformat { o m }
+ {
+ \didec_gset:nn { __@temp@__ }{ #2 }
+ \IfNoValueTF {#1}
+ {
+ \didec_color_use:n { __@temp@__ }
+ }
+ {
+ \group_begin:
+ \keys_set:nn { didec }{ #1 }
+ \didec_color_use:n { __@temp@__ }
+ \group_end:
+ }
+ }
+
+% #1 key list
+% #2 didec expression
+\NewDocumentCommand \dideccolinvformat { o m }
+ {
+ \didec_gset:nn { __@temp@__ }{ #2 }
+ \IfNoValueTF {#1}
+ {
+ \didec_color_inverse_use:n { __@temp@__ }
+ }
+ {
+ \group_begin:
+ \keys_set:nn { didec }{ #1 }
+ \didec_color_inverse_use:n { __@temp@__ }
+ \group_end:
+ }
+ }
+
+% #1 key list
+\NewDocumentCommand \didecsetup { m }
+ {
+ \keys_set:nn { didec }{ #1 }
+ }
+
+% #1 didec variable
+% #2 stream
+\NewDocumentCommand \didecwrite { m m }
+ {
+ \exp_args:Ne \didec_write_check:nn { \tl_trim_spaces:n { #1 } }{ #2 }
+ }
+
+
+%------- didec conditionals -------------------
+
+% #1 didec variable
+\NewDocumentCommand \didecifnegative { m }
+ {
+ \exp_args:Ne \didec_if_negative:nTF { \tl_trim_spaces:n { #1 } }
+ }
+\NewCommandCopy \didecifnegativ \didecifnegative % Deprecated
+
+% #1 didec variable
+\NewDocumentCommand \didecifpositive { m }
+ {
+ \exp_args:Ne \didec_if_positive:nTF { \tl_trim_spaces:n { #1 } }
+ }
+\NewCommandCopy \didecifpositiv \didecifpositive % Deprecated
+
+% #1 didec variable
+\NewDocumentCommand \didecifzero { m }
+ {
+ \exp_args:Ne \didec_if_zero:nTF { \tl_trim_spaces:n { #1 } }
+ }
+\NewCommandCopy \didecifnull \didecifzero % Deprecated
+
+% #1 didec expression
+% #2 didec expression
+\NewDocumentCommand \dideciflowerthan { m m }
+ {
+ \didec_compare:nNnTF { #1 } < { #2 }
+ }
+
+% #1 didec expression
+% #2 didec expression
+\NewDocumentCommand \didecifequal { m m }
+ {
+ \didec_compare:nNnTF { #1 } = { #2 }
+ }
+
+% #1 didec expression
+% #2 didec expression
+\NewDocumentCommand \didecifgreaterthan { m m }
+ {
+ \didec_compare:nNnTF { #1 } > { #2 }
+ }
diff --git a/macros/latex/contrib/didec/didec.tex b/macros/latex/contrib/didec/didec.tex
new file mode 100644
index 0000000000..fd3d26e0a3
--- /dev/null
+++ b/macros/latex/contrib/didec/didec.tex
@@ -0,0 +1,1209 @@
+% \LaTeX-Main\
+% !TeX encoding=UTF-8
+% !TeX spellcheck=en_US
+%%
+%% The LaTeX package didec - version 1.0.0 (2024/02/28)
+%% didec.tex: Manual
+%%
+%% -------------------------------------------------------------------------------------------
+%% Copyright (c) 2024-2024 by Prof. Dr. Dr. Thomas F. Sturm <thomas dot sturm at unibw dot de>
+%% -------------------------------------------------------------------------------------------
+%%
+%% 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 `author-maintained'.
+%%
+%% This work consists of all files listed in README
+%%
+\documentclass[a4paper,11pt]{ltxdoc}
+\usepackage{didec.doc}
+
+\hypersetup{
+ pdftitle={Manual for the didec package},
+ pdfauthor={Thomas F. Sturm},
+ pdfsubject={Calculations with two decimal places},
+ pdfkeywords={fixed-point arithmetic, two decimal places, calculations, cash book, bookkeeping, accountancy}
+}
+
+\makeindex
+
+\pdfsuppresswarningpagegroup=1
+
+\DeclareUnicodeCharacter{20AC}{\euro{}}
+\didecsetup{
+ decimal-separator = {,},
+ grouping-separator = {.},
+ currency = {}{\;€},
+}
+
+\didecnew{A}
+\didecnew{B}
+\didecnew{C}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{document}
+
+\begin{center}
+\begin{tcolorbox}[enhanced,hbox,tikznode,left=8mm,right=8mm,boxrule=0.4pt,
+ colback=white,colframe=Blue_Gray,
+ drop lifted shadow=Blue_Gray!50,arc is angular,
+ before=\par\vspace*{5mm},after=\par\bigskip]
+{\bfseries\LARGE The didec package}\\[3mm]
+{\large Manual for version \version\ (\datum)}
+\end{tcolorbox}
+{\large Thomas F.~Sturm%
+ \footnote{Prof.~Dr.~Dr.~Thomas F.~Sturm, Institut f\"{u}r Mathematik und Informatik,
+ University of the Bundeswehr Munich, D-85577 Neubiberg, Germany;
+ email: \href{mailto:thomas.sturm@unibw.de}{thomas.sturm@unibw.de}}\par\medskip
+\normalsize%
+\url{https://www.ctan.org/pkg/didec}\par
+\url{https://github.com/T-F-S/didec}
+}
+\end{center}
+\bigskip
+\begin{absquote}
+ \begin{center}\bfseries Abstract\end{center}
+ The \texttt{didec} package supports fixed-point arithmetic with two
+ decimal places (\emph{di-decimal}) which is typical for financial transactions
+ in many currencies. The intended use case is (personal) bookkeeping.
+\end{absquote}
+
+\tableofcontents
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\clearpage
+\section{Quick start}%
+For the impatient: this package provides fixed-point arithmetic with
+two decimal places. You may use it for any purpose where exactly two decimal
+places are needed or suffice, but the main application case is (personal) bookkeeping.
+
+Say, John wants to keep track about his money. With
+\begin{dispListing}
+\didecnew{John}
+\end{dispListing}
+\didecnew{John}
+a so-called \emph{didec variable} is created to store currency values.
+
+Now, lets fill in some money:
+\begin{dispListing}
+\didecset{John}{1000}
+\end{dispListing}
+\didecset{John}{1000}
+
+How much money has John now?
+\begin{dispExample}
+\didecuse{John}
+\end{dispExample}
+
+Obviously, John has Euros and the amount is displayed in a German style manor.
+Of course, this can be adapted to your liking, see \refCom{didecsetup}.
+But now, let us spend some money.
+\begin{dispExample}
+\didecsub{John}{19.75}
+\didecuse{John}
+\end{dispExample}
+
+Preferably, the package functions are used inside convenient user commands.
+You can choose between \LaTeX2e and \LaTeX3 programming layer functions.
+
+For this quick start, we make some convenience commands for John.
+|\transaction| shall be one purchase made in cash and |\transaction*| one made
+by credit card.
+\begin{dispExample*}{breakable}
+%\usepackage{booktabs}
+\didecsetup{english,
+ currency = {\pounds}{},
+ currency-negative = {-\pounds}{},
+}
+
+%\didecnew{John}
+\didecnew{cash}
+\didecnew{credit}
+\didecnew{transaction}
+
+% Let's keep record in a table
+\NewDocumentEnvironment{householdbook}{}{%
+ \begin{center}
+ \begin{tabular}{lp{9cm}rr}\toprule%
+ & Transaction & Expenses & Budget\\\midrule
+ }{%
+ \midrule%
+ \multicolumn{3}{r}{Cash} & \dideccoluse{cash}\\%
+ \multicolumn{3}{r}{Credit card} & \dideccoluse{credit}\\\bottomrule%
+ \end{tabular}%
+ \end{center}
+ }
+
+% One transaction
+\NewDocumentCommand \transaction{ s m m }
+ {
+ \didecset{transaction}{#3}%
+ \didecsub{John}{transaction}%
+ \IfBooleanTF {#1}%
+ {\didecsub{credit}{transaction}CC}%
+ {\didecsub{cash}{transaction}}%
+ & #2
+ & \dideccolinvuse{transaction}
+ & \dideccoluse{John}\\%
+ }
+
+% Ready to start our tiny accountancy
+
+\didecset{John}{1000} % John's money
+\didecsetequal{cash}{John} % in cash
+\didecset{credit}{0} % blank credit card
+
+\begin{householdbook}
+ \transaction{Coffee break with snack}{19.75}
+ \transaction*{Refuel}{62.87}
+ \transaction{Gift from Aunt Mary for helping her}{-30}
+ \transaction{Parking meter}{4.50}
+ \transaction*{Shopping for weekend}{147.23}
+ \transaction*{Fancy thing on the Internet}{270}
+ \transaction*{Cinema}{17.70}
+\end{householdbook}
+
+\end{dispExample*}
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\clearpage
+\section{Didec kernels and didec expressions}%
+
+All calculations are done on cent basis as integer operations, but all
+displayed figures have two decimal places which give the name for the package
+(\emph{di}-\emph{dec}imal).
+
+The package provides two numerical kernels which can be selected mutually
+by package options \refKey{didec/int} or \refKey{didec/fp}.
+The \refKey{didec/int} kernel is faster, but provides a smaller number range,
+while the \refKey{didec/int} kernel is slower with a larger number range.
+For ordinary people like you and me, the \refKey{didec/int} kernel will suffice
+to do all personal financial calculations.
+Upgrading later from \refKey{didec/int} to \refKey{didec/fp} is a matter of
+just switching the package option setting.
+
+%-------------------------------------------------------------------------------
+\begin{docPackageOptions}{{
+ doc name = int,
+ doc description = {no value, initially set},
+ }}
+Selects the \meta{int} (integer) based numerical kernel with up to
+9.33\footnote{joke for the mathematicians} significant figures and fast computation.
+The number range for valid figures $n$ is:
+\begin{center}
+$ -21\;474\;836.47 \le n \le 21\;474\;836.47 $
+\end{center}
+\begin{dispListing}
+\usepackage[int]{didec}
+\end{dispListing}
+Using figures outside the valid range will result in \LaTeX\ errors complaining
+about too large numbers.
+\end{docPackageOptions}
+%-------------------------------------------------------------------------------
+
+
+%-------------------------------------------------------------------------------
+\begin{docPackageOptions}{{
+ doc name = fp,
+ doc description = {no value, initially unset},
+ }}
+Selects the \meta{fp} (floating-point) based numerical kernel with up to
+16 significant figures and somewhat slower computation.
+The number range for valid figures $n$ is:
+\begin{center}
+$ -99\;999\;999\;999\;999.99 \le n \le 99\;999\;999\;999\;999.99 $
+\end{center}
+\begin{dispListing}
+\usepackage[fp]{didec}
+\end{dispListing}
+Using figures outside the valid range will result in \emph{silent calculation errors},
+because \LaTeX3 \meta{fp} can use much larger numbers but is restricted to 16
+significant figures.
+\end{docPackageOptions}
+%-------------------------------------------------------------------------------
+
+\medskip
+
+In the following, a \meta{didec expr} (didec expression) denotes one of
+the following:
+\begin{itemize}
+\item a number in floating-point notation, e.g. |123.45|
+\item a number in floating-comma notation, e.g. |123,45|
+\item a \meta{didec var} (didec variable), e.g. |expenses|.
+\end{itemize}
+Note that the notation \meta{didec expr} is inspired by \meta{int expr} and \meta{fp expr}
+from \LaTeX3 but is in comparison very restricted and allows only the three choices above.
+A \meta{didec expr} is always expanded and spaces are trimmed.
+
+\medskip
+
+Many provided commands or functions of the package come in three flavors, for
+example:
+\begin{itemize}
+\item \refCom{didecadd}: This is a user command where arguments are space trimmed
+ and some check on variable existence is done.
+ Not existing variables are reported by speaking error messages (not in all cases!).
+\item \refCom{didec_gadd_check:nn}: This a programming layer function
+ with no space trimming for arguments, but some check on variable existence is done.
+ Not existing variables are reported by speaking error messages (not in all cases!).
+\item \refCom{didec_gadd:nn}: This a programming layer function
+ with no space trimming for arguments and no check on variable existence.
+ Not existing variables give strange errors.
+ This is the fasted function and base of the others above.
+\end{itemize}
+
+
+\clearpage
+The following tables compare the computation time for selected functions of
+the package for the two numerical kernels. Time values will differ on other
+computers and also depend on selected values for the examples calculations.
+Nevertheless, you get an impression of the differences.
+
+
+%-------------------------------------------------------------------------------
+\begin{tcbverbatimwrite}{\jobname.temp}
+\begin{tcblisting}{
+ blankest,
+ pdf comment,
+ comment style={raster columns=1,blankest,enhanced/.style=},
+ comment only,
+ freeze pdf,
+ compilable listing,
+ run pdflatex
+}
+\IfFileExists{didec.doc.cfg}{\input{didec.doc.cfg}}{\def\didecpackageprefix{}}
+\documentclass[a4paper,11pt]{ltxdoc}
+\usepackage[a4paper,textwidth=8cm]{geometry}
+\usepackage{lmodern,array,booktabs,incgraph}
+\usepackage[skins,documentation]{tcolorbox}
+\input{didec.tempinc}
+\usepackage{l3benchmark,siunitx}
+\begin{document}
+\begin{inctext}
+\begin{tcolorbox}[blankest]
+\makeatletter
+\ExplSyntaxOn
+\cs_new_protected:Npn \didec_benchmark:n #1
+{
+ \benchmark:n { #1 }
+ \tablenum[table-format=4.0]{ \fp_to_decimal:n { round( \g_benchmark_time_fp * 1 000 000 ) } }\,\unit{\micro\second}
+}
+\didecnew{A}\didecnew{B}
+\fp_set:Nn \g_benchmark_duration_target_fp { 1 }
+\begin{center}
+\begin{tabular}{lr}\toprule
+\multicolumn{2}{c}{
+ kernel:~\texttt{\c_didec_kernel_str},~engine:~\texttt{\c_sys_engine_str}
+}\\\midrule
+\docAuxCommand*{didec_gset:nn} & \didec_benchmark:n{ \didec_gset:nn{A}{-9876,324} }
+\\\docAuxCommand*{didec_gset_check:nn} & \didec_benchmark:n{ \didec_gset_check:nn{A}{-9876,324} }
+\\\docAuxCommand*{didecset} & \didec_benchmark:n{ \didecset{A}{-9876,324} }
+\\\midrule
+\docAuxCommand*{didec_gset_eq:nn} & \didecset{B}{1234.56} \didec_benchmark:n{ \didec_gset_eq:nn{A}{B} }
+\\\docAuxCommand*{didec_gset_eq_check:nn} & \didecset{B}{1234.56} \didec_benchmark:n{ \didec_gset_eq_check:nn{A}{B} }
+\\\docAuxCommand*{didecsetequal} & \didecset{B}{1234.56} \didec_benchmark:n{ \didecsetequal{A}{B} }
+\\\midrule
+\docAuxCommand*{didec_gset_fp:nn} & \didec_benchmark:n{ \didec_gset_fp:nn{A}{51234.56} }
+\\\docAuxCommand*{didec_gset_fp_check:nn} & \didec_benchmark:n{ \didec_gset_fp_check:nn{A}{51234.56} }
+\\\docAuxCommand*{didecsetfp} & \didec_benchmark:n{ \didecsetfp{A}{51234.56} }
+\\\midrule
+\docAuxCommand*{didec_gadd:nn} & \didecset{A}{-987.34} \didec_benchmark:n{ \didec_gadd:nn{A}{12345} }
+\\\docAuxCommand*{didec_gadd_check:nn} & \didecset{A}{-987.34}\didec_benchmark:n{ \didec_gadd_check:nn{A}{12345} }
+\\\docAuxCommand*{didecadd} & \didecset{A}{-987.34} \didec_benchmark:n{ \didecadd{A}{12345} }
+\\\midrule
+\docAuxCommand*{didec_gadd_to:nnn} & \didec_benchmark:n{ \didec_gadd_to:nnn{A}{-4564}{12345} }
+\\\docAuxCommand*{didec_gadd_to_check:nnn} & \didec_benchmark:n{ \didec_gadd_to_check:nnn{A}{-4564}{12345} }
+\\\docAuxCommand*{didecadd} & \didec_benchmark:n{ \didecadd[A]{-4564}{12345} }
+\\\midrule
+\docAuxCommand*{didec_gmul_fp:nn} & \didecset{A}{-987.34} \didec_benchmark:n{ \didec_gmul_fp:nn{A}{0.99} }
+\\\docAuxCommand*{didec_gmul_fp_check:nn} & \didecset{A}{-987.34}\didec_benchmark:n{ \didec_gmul_fp_check:nn{A}{0.99} }
+\\\docAuxCommand*{didecmulfp} & \didecset{A}{-987.34} \didec_benchmark:n{ \didecmulfp{A}{0.99} }
+\\\midrule
+%
+\docAuxCommand*{didec_if_positive:nTF} & \didecset{A}{-987.34} \didec_benchmark:n{ \didec_if_positive:nTF{A}{}{} }
+\\\docAuxCommand*{didecifpositive} & \didecset{A}{-987.34} \didec_benchmark:n{ \didecifpositive{A}{}{} }
+\\\docAuxCommand*{didec_compare:nNnTF} & \didecset{A}{-987.34} \didec_benchmark:n{ \didec_compare:nNnTF{A}>{12345}{}{} }
+\\\docAuxCommand*{didecifgreaterthan} & \didecset{A}{-987.34} \didec_benchmark:n{ \didecifgreaterthan{A}{12345}{}{} }
+\\\midrule
+\docAuxCommand*{didec_to_fp:n} & \didecset{A}{-1234987.34} \didec_benchmark:n{ \setbox\z@\hbox{\didec_to_fp:n{A}} }
+\\\docAuxCommand*{didec_to_fp_check:n} & \didecset{A}{-1234987.34} \didec_benchmark:n{ \setbox\z@\hbox{\didec_to_fp_check:n{A}} }
+\\\docAuxCommand*{didectofp} & \didecset{A}{-1234987.34} \didec_benchmark:n{ \setbox\z@\hbox{\didectofp{A}} }
+\\\midrule
+\docAuxCommand*{didec_use:n} & \didecset{A}{-1234987.34} \didec_benchmark:n{ \setbox\z@\hbox{\didec_use:n{A}} }
+\\\docAuxCommand*{didec_use_check:n} & \didecset{A}{-1234987.34} \didec_benchmark:n{ \setbox\z@\hbox{\didec_use_check:n{A}} }
+\\\docAuxCommand*{didecuse} & \didecset{A}{-1234987.34} \didec_benchmark:n{ \setbox\z@\hbox{\didecuse{A}} }
+\\\docAuxCommand*{didecformat} & \didec_benchmark:n{ \setbox\z@\hbox{\didecformat{-1234987.34}} }
+\\\docAuxCommand*{didec_color_use:n} & \didecset{A}{-1234987.34} \didec_benchmark:n{ \setbox\z@\hbox{\didec_color_use:n{A}} }
+\\\docAuxCommand*{didec_color_use_check:n} & \didecset{A}{-1234987.34} \didec_benchmark:n{ \setbox\z@\hbox{\didec_color_use_check:n{A}} }
+\\\docAuxCommand*{dideccoluse} & \didecset{A}{-1234987.34} \didec_benchmark:n{ \setbox\z@\hbox{\dideccoluse{A}} }
+\\\docAuxCommand*{dideccolformat} & \didec_benchmark:n{ \setbox\z@\hbox{\dideccolformat{-1234987.34}} }
+\\\bottomrule
+\end{tabular}
+\end{center}
+\ExplSyntaxOff
+\makeatother
+\end{tcolorbox}
+\end{inctext}
+\end{document}
+\end{tcblisting}
+\end{tcbverbatimwrite}
+%
+\begin{tcbraster}[raster column skip=0pt]
+\begin{tcbverbatimwrite}{\jobname.tempinc}
+\usepackage[int]{\didecpackageprefix didec}
+\end{tcbverbatimwrite}
+\input{\jobname.temp}
+%
+\begin{tcbverbatimwrite}{\jobname.tempinc}
+\usepackage[fp]{\didecpackageprefix didec}
+\end{tcbverbatimwrite}
+\input{\jobname.temp}
+\end{tcbraster}
+%-------------------------------------------------------------------------------
+
+
+\clearpage
+If needed, the selected kernel can be questioned by the following:
+
+%-------------------------------------------------------------------------------
+\begin{docCommands}[
+ % doc parameter = \marg{didec var},
+ ]
+{
+ { doc name = c_didec_kernel_str },
+}
+The current kernel given as a lower case string: one of
+\docValue*{int} or \docValue*{fp}.
+\begin{dispExample}
+\ExplSyntaxOn
+\c_didec_kernel_str
+\ExplSyntaxOff
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+
+%-------------------------------------------------------------------------------
+\begin{docCommands}[
+ % doc parameter = \marg{didec var},
+ ]
+{
+ { doc name = didec_if_kernel_int_p: },
+ { doc name = didec_if_kernel_int:T, doc parameter = ~\marg{true code} },
+ { doc name = didec_if_kernel_int:TF, doc parameter = ~\marg{true code}\marg{false code} },
+ { doc name = didec_if_kernel_fp_p: },
+ { doc name = didec_if_kernel_fp:T, doc parameter = ~\marg{true code} },
+ { doc name = didec_if_kernel_fp:TF, doc parameter = ~\marg{true code}\marg{false code} },
+}
+Conditionals which allow kernel-specific code to be used. The names follow
+naturally from those of the kernels.
+\begin{dispExample}
+\ExplSyntaxOn
+\didec_if_kernel_int:T { Integer~kernel~used. }\par
+Floating~point~kernel
+\didec_if_kernel_fp:TF { ~used. }{ ~not~used. }
+\ExplSyntaxOff
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\clearpage
+\section{Creating didec variables}%
+
+%-------------------------------------------------------------------------------
+\begin{docCommands}[
+ doc parameter = \marg{didec var},
+ ]
+{
+ { doc name = didecnew },
+ { doc name = didec_new:n },
+ }
+Creates a new \meta{didec var} or raises an error if the name is already taken.
+\refCom{didecnew} trims spaces while \refCom{didec_new:n} does not.
+\begin{dispExample}
+\didecnew{konto}
+\didecset{konto}{99.75}
+\didecuse{konto}
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+%\clearpage
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{Setting didec variables}%
+
+
+%-------------------------------------------------------------------------------
+\begin{docCommands}[
+ doc parameter = \marg{didec var}\marg{didec expr},
+ ]
+{
+ { doc name = didecset },
+ { doc name = didec_gset:nn },
+ { doc name = didec_gset_check:nn },
+ }
+Sets \meta{didec var} to the value of \meta{didec expr} which can be
+\begin{itemize}
+\item a number in floating-point notation,
+\item a number in floating-comma notation,
+\item another \meta{didec var}.
+\end{itemize}
+\refCom{didecset} trims spaces and performs an existence check for \meta{didec var}.
+\refCom{didec_gset_check:nn} performs an existence check for \meta{didec var}.
+Decimals places 3 and beyond are cut not rounded.
+If rounding is an issue, use \refCom{didecsetfp} instead.
+\begin{dispExample}
+\didecset{A}{1234.56}
+\didecuse{A}
+
+\didecset{A}{2345,6789}
+\didecuse{A}
+
+\didecset{B}{-3500}
+\didecset{A}{B}
+\didecuse{A}
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+
+%-------------------------------------------------------------------------------
+\begin{docCommands}[
+ doc parameter = \marg{didec var\textsubscript{1}}\marg{didec var\textsubscript{2}},
+ ]
+{
+ { doc name = didecsetequal },
+ { doc name = didec_gset_eq:nn },
+ { doc name = didec_gset_eq_check:nn },
+ }
+Sets the \meta{didec var\textsubscript{1}} to the current value of \meta{didec var\textsubscript{2}}
+\begin{dispExample}
+\didecset{A}{1234.56}
+\didecsetequal{B}{A}
+\didecuse{A}
+\didecuse{B}
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+\clearpage
+%-------------------------------------------------------------------------------
+\begin{docCommands}[
+ doc parameter = \marg{didec var}\marg{didec expr},
+ ]
+{
+ { doc name = didecsetnegative },
+ { doc name = didec_gset_negative:nn },
+ { doc name = didec_gset_negative_check:nn },
+ }
+Sets \meta{didec var} to the negated (opposite) value of \meta{didec expr}.
+\refCom{didecsetnegative} trims spaces and performs an existence check for \meta{didec var}.
+\begin{dispExample}
+\didecsetnegative{A}{1234.56}
+\didecuse{A}
+
+\didecsetnegative{A}{-42.55}
+\didecuse{A}
+
+\didecset{B}{-3500}
+\didecsetnegative{A}{B}
+\didecuse{A}
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+
+%-------------------------------------------------------------------------------
+\begin{docCommands}[
+ doc parameter = \marg{didec var}\marg{fp expr},
+ ]
+{
+ { doc name = didecsetfp },
+ { doc name = didec_gset_fp:nn },
+ { doc name = didec_gset_fp_check:nn },
+ }
+Sets \meta{didec var} to the value of \meta{fp expr} which can
+by any \LaTeX3 floating-point expression.
+\refCom{didecsetfp} trims spaces and performs an existence check for \meta{didec var}.
+Other didec variables can be used inside \meta{fp expr} if guarded with \refCom{didectofp}.
+The result is rounded to 2 decimal places.
+\refCom{didec_gset_fp_check:nn} performs an existence check for \meta{didec var}.
+\begin{dispExample}
+\didecsetfp{A}{2345.6789}
+\didecuse{A}
+
+\didecsetfp{A}{ ln( 12345678 ) }
+\didecuse{A}
+
+\didecset{A}{123456,78}
+\didecsetfp{B}{ \didectofp{A} * 2.35 / 100 }
+2.35\% of \didecuse{A} are \didecuse{B}.
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+\clearpage
+%-------------------------------------------------------------------------------
+\begin{docCommands}
+{
+ { doc name = didecadd, doc parameter = \oarg{didec var}\marg{didec expr\textsubscript{1}}\marg{didec expr\textsubscript{2}} },
+ { doc name = didec_gadd:nn, doc parameter = \marg{didec var}\marg{didec expr} },
+ { doc name = didec_gadd_check:nn, doc parameter = \marg{didec var}\marg{didec expr} },
+ { doc name = didec_gadd_to:nnn, doc parameter = \marg{didec var}\marg{didec expr\textsubscript{1}}\marg{didec expr\textsubscript{2}} },
+ { doc name = didec_gadd_to_check:nnn, doc parameter = \marg{didec var}\marg{didec expr\textsubscript{1}}\marg{didec expr\textsubscript{2}} },
+ }
+\begin{itemize}
+\item Adds the result of computing the \meta{didec expr} to the \meta{didec var}
+\item or sets \meta{didec var} to the sum of \meta{didec expr\textsubscript{1}} and \meta{didec expr\textsubscript{2}}.
+\item For \refCom{didecadd}, if the optional \meta{didec var} is not available,
+ the sum is stored into \meta{didec expr\textsubscript{1}} which has to be a \meta{didec var}
+ in this case.
+\end{itemize}
+\begin{dispExample}
+\didecset{A}{123}
+\didecset{B}{5,88}
+\didecadd{A}{B}
+\didecuse{A}
+
+\didecadd[A]{B}{1000}
+\didecuse{A}
+
+\didecadd{A}{-2750}
+\didecuse{A}
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+%\clearpage
+%-------------------------------------------------------------------------------
+\begin{docCommands}
+{
+ { doc name = didecsub, doc parameter = \oarg{didec var}\marg{didec expr\textsubscript{1}}\marg{didec expr\textsubscript{2}} },
+ { doc name = didec_gsub:nn, doc parameter = \marg{didec var}\marg{didec expr} },
+ { doc name = didec_gsub_check:nn, doc parameter = \marg{didec var}\marg{didec expr} },
+ { doc name = didec_gsub_to:nnn, doc parameter = \marg{didec var}\marg{didec expr\textsubscript{1}}\marg{didec expr\textsubscript{2}} },
+ { doc name = didec_gsub_to_check:nnn, doc parameter = \marg{didec var}\marg{didec expr\textsubscript{1}}\marg{didec expr\textsubscript{2}} },
+ }
+\begin{itemize}
+\item Subtracts the result of computing the \meta{didec expr} to the \meta{didec var}
+\item or sets \meta{didec var} to the difference of \meta{didec expr\textsubscript{1}} and \meta{didec expr\textsubscript{2}}.
+\item For \refCom{didecsub}, if the optional \meta{didec var} is not available,
+ the difference is stored into \meta{didec expr\textsubscript{1}} which has to be a \meta{didec var}
+ in this case.
+\end{itemize}
+\begin{dispExample}
+\didecset{A}{123}
+\didecset{B}{5,88}
+\didecsub{A}{B}
+\didecuse{A}
+
+\didecsub[A]{B}{1000}
+\didecuse{A}
+
+\didecsub{A}{-2750}
+\didecuse{A}
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+\clearpage
+%-------------------------------------------------------------------------------
+\begin{docCommands}
+{
+ { doc name = didecmulfp, doc parameter = \oarg{didec var\textsubscript{2}}\marg{didec var}\marg{fp expr} },
+ { doc name = didec_gmul_fp:nn, doc parameter = \marg{didec var}\marg{fp expr} },
+ { doc name = didec_gmul_fp_check:nn, doc parameter = \marg{didec var}\marg{fp expr} },
+ { doc name = didec_gmul_fp_to:nnn, doc parameter = \marg{didec var\textsubscript{2}}\marg{didec var}\marg{fp expr} },
+ { doc name = didec_gmul_fp_to_check:nnn, doc parameter = \marg{didec var\textsubscript{2}}\marg{didec var}\marg{fp expr} },
+ }
+\begin{itemize}
+\item Multiplies \meta{didec var} with the result of computing the \meta{fp expr}
+\item and sets \meta{didec var} or respectively \meta{didec var\textsubscript{2}} to the result.
+\end{itemize}
+\begin{dispExample}
+\didecset{A}{123}
+\didecmulfp{A}{0.9675}
+\didecuse{A}
+
+\didecmulfp[B]{A}{ln(42)}
+\didecuse{B}
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+
+%-------------------------------------------------------------------------------
+\begin{docCommands}
+{
+ { doc name = didecdivfp, doc parameter = \oarg{didec var\textsubscript{2}}\marg{didec var}\marg{fp expr} },
+ { doc name = didec_gdiv_fp:nn, doc parameter = \marg{didec var}\marg{fp expr} },
+ { doc name = didec_gdiv_fp_check:nn, doc parameter = \marg{didec var}\marg{fp expr} },
+ { doc name = didec_gdiv_fp_to:nnn, doc parameter = \marg{didec var\textsubscript{2}}\marg{didec var}\marg{fp expr} },
+ { doc name = didec_gdiv_fp_to_check:nnn, doc parameter = \marg{didec var\textsubscript{2}}\marg{didec var}\marg{fp expr} },
+ }
+\begin{itemize}
+\item Divides \meta{didec var} by the result of computing the \meta{fp expr}
+\item and sets \meta{didec var} or respectively \meta{didec var\textsubscript{2}} to the result.
+\end{itemize}
+\begin{dispExample}
+\didecset{A}{123}
+\didecdivfp{A}{0.9675}
+\didecuse{A}
+
+\didecdivfp[B]{A}{ln(42)}
+\didecuse{B}
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+%-------------------------------------------------------------------------------
+\begin{docCommands}
+{
+ { doc name = didecsetsum, doc parameter = \oarg{didec var}\marg{sum of didec exp} },
+}
+Sets \meta{didec var} to the result of computing the given \meta{sum of didec exp}.\par
+Here, \meta{sum of didec exp} = \meta{didec exp\textsubscript{1}}
++ \meta{didec exp\textsubscript{2}} + \ldots + \meta{didec exp\textsubscript{n}}
+\begin{dispExample}
+\didecset{A}{123}
+\didecset{B}{-32.15}
+\didecsetsum{A}{ A + B + -22.5 }
+\didecuse{A}
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+
+\clearpage
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{Using didecs}%
+
+
+%-------------------------------------------------------------------------------
+\begin{docCommands}
+{
+ { doc name = didectoint, doc parameter = \marg{didec var} },
+ { doc name = didec_to_int:n, doc parameter = \marg{didec var} },
+ { doc name = didec_to_int_check:n, doc parameter = \marg{didec var} },
+}
+Expresses the \meta{didec var} as Cent integer value, i.e. 100 times the
+value.
+All functions are expandable.
+\begin{dispExample}
+\didecset{A}{27123.45}
+\didectoint{A}
+
+\didecset{A}{-17}
+\didectoint{A}
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+
+%-------------------------------------------------------------------------------
+\begin{docCommands}
+{
+ { doc name = didectofp, doc parameter = \marg{didec var} },
+ { doc name = didec_to_fp:n, doc parameter = \marg{didec var} },
+ { doc name = didec_to_fp_check:n, doc parameter = \marg{didec var} },
+}
+Expresses the \meta{didec var} as floating-point value.
+All functions are expandable.
+\begin{dispExample}
+\didecset{A}{27123.45}
+\didectofp{A}
+
+\didecset{A}{-17}
+\didectofp{A}
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+
+%-------------------------------------------------------------------------------
+\begin{docCommands}
+{
+ { doc name = didectofc, doc parameter = \marg{didec var} },
+ { doc name = didec_to_fc:n, doc parameter = \marg{didec var} },
+ { doc name = didec_to_fc_check:n, doc parameter = \marg{didec var} },
+}
+Expresses the \meta{didec var} as floating-comma value.
+All functions are expandable.
+\begin{dispExample}
+\didecset{A}{27123.45}
+\didectofc{A}
+
+\didecset{A}{-17}
+\didectofc{A}
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+\clearpage
+%-------------------------------------------------------------------------------
+\begin{docCommands}
+{
+ { doc name = didecuse, doc parameter = \oarg{key list}\marg{didec var} },
+ { doc name = didec_use:n, doc parameter = \marg{didec var} },
+ { doc name = didec_use_check:n, doc parameter = \marg{didec var} },
+}
+Expresses the \meta{didec var} as formatted value.
+With \refCom{didecsetup}, the standard format can be set.
+This standard format can be overwritten by \meta{key list}.
+\begin{dispExample}
+\didecset{A}{123456.78}
+\didecuse{A}
+
+\didecuse[
+ currency = {\pounds}{},
+ decimal-separator = {.},
+ grouping-separator = {,},
+ ]{A}
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+
+%-------------------------------------------------------------------------------
+\begin{docCommands}
+{
+ { doc name = dideccoluse, doc parameter = \oarg{key list}\marg{didec var} },
+ { doc name = didec_color_use:n, doc parameter = \marg{didec var} },
+ { doc name = didec_color_use_check:n, doc parameter = \marg{didec var} },
+}
+Expresses the \meta{didec var} as colorized formatted value.
+With \refCom{didecsetup}, the standard format can be set.
+This standard format can be overwritten by \meta{key list}.
+\begin{dispExample}
+\didecset{A}{123456.78}
+\dideccoluse{A}
+
+\didecset{A}{-125}
+\dideccoluse{A}
+
+\dideccoluse[color-negative=didec-blue]{A}
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+%-------------------------------------------------------------------------------
+\begin{docCommands}
+{
+ { doc name = dideccolinvuse, doc parameter = \oarg{key list}\marg{didec var} },
+ { doc name = didec_color_inverse_use:n, doc parameter = \marg{didec var} },
+ { doc name = didec_color_inverse_use_check:n, doc parameter = \marg{didec var} },
+}
+Expresses the \meta{didec var} as colorized formatted value.
+The coloring is switched between positive and negative.
+The standard
+coloring and format can be overwritten by \meta{key list}.
+\begin{dispExample}
+\didecset{A}{123456.78}
+\dideccolinvuse{A}
+
+\didecset{A}{-125}
+\dideccolinvuse{A}
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+\clearpage
+%-------------------------------------------------------------------------------
+\begin{docCommands}
+{
+ { doc name = didecformat, doc parameter = \oarg{key list}\marg{didec expr} },
+ { doc name = dideccolformat, doc parameter = \oarg{key list}\marg{didec expr} },
+ { doc name = dideccolinvformat, doc parameter = \oarg{key list}\marg{didec expr} },
+}
+Like \refCom{didecuse}, \refCom{dideccoluse}, \refCom{dideccolinvuse},
+but accepts a \meta{didec expr} instead of a \meta{didec var}.
+If the \meta{didec expr} is a \meta{didec var},
+\refCom{didecuse}, \refCom{dideccoluse}, \refCom{dideccolinvuse} are more efficient.
+\begin{dispExample}
+\didecformat{123456.78}\\
+\didecformat{A}\\
+\didecformat[english]{123456.78}\\
+\dideccolformat{123456.78}\\
+\dideccolinvformat{123456.78}
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+%-------------------------------------------------------------------------------
+\begin{docCommands}
+{
+ { doc name = didecsetup, doc parameter = \marg{key list} },
+}
+Sets all keys of the given \meta{key list}. See the following documentation
+for available settings.
+\begin{dispExample}
+\didecsetup{
+ currency = {\pounds}{},
+ decimal-separator = {.},
+ grouping-separator = {,},
+}
+\didecset{A}{123456.78}
+\didecuse{A}
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+\clearpage
+%-------------------------------------------------------------------------------
+\begin{docDidecKeys}
+{
+ {
+ doc name = decimal-separator,
+ doc parameter = {=\marg{separator}},
+ doc description = {initially |,|},
+ },
+}
+Sets some \meta{separator} as decimal separator.
+\begin{dispExample}
+\didecset{A}{123456.78}
+\didecuse[ decimal-separator={\#} ]{A} \par
+\end{dispExample}
+\end{docDidecKeys}
+%-------------------------------------------------------------------------------
+
+
+
+%-------------------------------------------------------------------------------
+\begin{docDidecKeys}
+{
+ {
+ doc name = grouping-separator,
+ doc parameter = {=\marg{separator}},
+ doc description = {initially |.|},
+ },
+}
+Sets some \meta{separator} as grouping separator.
+\begin{dispExample}
+\didecset{A}{123456.78}
+\didecuse[ grouping-separator={'} ]{A}
+\end{dispExample}
+\end{docDidecKeys}
+%-------------------------------------------------------------------------------
+
+
+
+%-------------------------------------------------------------------------------
+\begin{docDidecKeys}
+{
+ {
+ doc name = currency,
+ doc parameter = {=\marg{prefix}\marg{postfix}},
+ doc description = {initially empty},
+ },
+}
+Sets some \meta{prefix} and \meta{postfix} to denote the currency of the
+didec variable.
+This also sets\\
+\refKey{didec/currency-negative}\brackets{\meta{prefix}-}\marg{postfix}
+\begin{dispExample}
+\didecset{A}{123456.78}
+\didecuse[ currency = {\pounds}{} ]{A} \par
+\didecuse[ currency = {}{\:Gulden} ]{A}
+\end{dispExample}
+\end{docDidecKeys}
+%-------------------------------------------------------------------------------
+
+
+
+%-------------------------------------------------------------------------------
+\begin{docDidecKeys}
+{
+ {
+ doc name = currency-negative,
+ doc parameter = {=\marg{prefix}\marg{postfix}},
+ doc description = {initially empty},
+ },
+}
+Sets some \meta{prefix} and \meta{postfix} to denote the currency of the
+didec variable, if the resulting value is negative. Otherwise, the settings of
+\refKey{didec/currency} are used.
+Note that you need to set a minus sign |-| explicitly, if you want to see it.
+Also note that setting \refKey{didec/currency} overwrites values given
+by \refKey{didec/currency-negative}.
+\begin{dispExample}
+\didecset{A}{-123456.78}
+\didecuse{A}\par
+\didecuse[ currency-negative = {$-$}{\;€} ]{A} \par
+\didecuse[ currency-negative = {(}{\;€)} ]{A} \par
+\didecuse[ currency-negative = {(}{)\;€} ]{A} \par
+\didecuse[ currency-negative = {-€}{} ]{A} \par
+\end{dispExample}
+\end{docDidecKeys}
+%-------------------------------------------------------------------------------
+
+
+\clearpage
+%-------------------------------------------------------------------------------
+\begin{docDidecKeys}[
+ doc parameter = ,
+ doc description = style,
+]
+{
+ { doc name = german },
+ { doc name = english },
+ { doc name = french },
+ { doc name = float },
+}
+Styles to set some format preferences combined.
+Any currency settings are removed and should be applied afterwards,
+if needed.
+Note that \refCom{didectofp} is more efficient than \refCom{didecuse} with
+style \refKey{didec/float}.
+\begin{center}
+\begin{tabular}{>{\ttfamily}l>{\ttfamily}c>{\ttfamily}c>{\ttfamily}c>{\ttfamily}c}\toprule
+ & german & english & french & float\\\midrule
+decimal-separator & , & . & , & . \\
+grouping-separator & . & , & |\;| & \\\bottomrule
+\end{tabular}
+\end{center}
+\begin{dispExample}
+\didecset{A}{12345678.90}
+\didecuse[german]{A} \par
+\didecuse[english]{A} \par
+\didecuse[french]{A} \par
+\didecuse[float]{A} \par
+\end{dispExample}
+\end{docDidecKeys}
+%-------------------------------------------------------------------------------
+
+
+%-------------------------------------------------------------------------------
+\begin{docDidecKeys}
+{
+ {
+ doc name = color-positive,
+ doc parameter = {=\meta{positive color}},
+ doc description = {initially |didec-green|},
+ },
+ {
+ doc name = color-negative,
+ doc parameter = {=\meta{negative color}},
+ doc description = {initially |didec-red|},
+ },
+}
+Sets \meta{positive color} to denote positive (and zero) values
+and \meta{negative color} to denote negative values.
+Any valid |l3color| \meta{color expression} can be used.
+The package defines additional colors
+\begin{itemize}
+\item\docColorExample{didec-green}
+\item\docColorExample{didec-red}
+\item\docColorExample{didec-blue}
+\end{itemize}
+\begin{dispExample}
+\didecset{A}{123456.78}
+\dideccoluse[ color-positive = magenta ]{A}
+\end{dispExample}
+\end{docDidecKeys}
+%-------------------------------------------------------------------------------
+
+
+
+
+%-------------------------------------------------------------------------------
+\begin{docCommands}
+{
+ { doc name = didecwrite, doc parameter = \marg{didec var}\marg{stream} },
+ { doc name = didec_write:nn, doc parameter = \marg{didec var}\marg{stream} },
+ { doc name = didec_write_check:nn, doc parameter = \marg{didec var}\marg{stream} },
+}
+Writes \refCom{didecset}\marg{didec var}\marg{current value} to the given
+already opened output \meta{stream}.
+\begin{dispListing}
+\didecwrite{A}{output}
+% writes to output:
+% \didecset{A}{VALUE}
+\end{dispListing}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+\clearpage
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{Didec conditionals}%
+%-------------------------------------------------------------------------------
+\begin{docCommands}[
+ doc parameter = \marg{didec var}\marg{true code}\marg{false code},
+ ]
+{
+ { doc name = didecifpositive },
+ { doc name = didec_if_positive_p:n, doc parameter = \marg{didec var} },
+ { doc name = didec_if_positive:nTF, },
+ { doc name = didec_if_positive:nT, doc parameter = \marg{didec var}\marg{true code} },
+ { doc name = didec_if_positive:nF, doc parameter = \marg{didec var}\marg{false code} },
+ }
+Evaluates the \meta{didec var}
+and returns |true| or executes the \meta{true code} if the value is positive,
+otherwise returns |false| or executes the \meta{false code}.
+\begin{dispExample}
+\didecset{A}{2799.50}
+\didecuse{A} is \didecifpositive{A}{positive}{not positive}.
+
+\didecset{B}{-584}
+\didecuse{B} is \didecifpositive{B}{positive}{not positive}.
+
+\didecset{A}{0}
+\didecuse{A} is \didecifpositive{A}{positive}{not positive}.
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+%-------------------------------------------------------------------------------
+\begin{docCommands}[
+ doc parameter = \marg{didec var}\marg{true code}\marg{false code},
+ ]
+{
+ { doc name = didecifnegative },
+ { doc name = didec_if_negative_p:n, doc parameter = \marg{didec var} },
+ { doc name = didec_if_negative:nTF, },
+ { doc name = didec_if_negative:nT, doc parameter = \marg{didec var}\marg{true code} },
+ { doc name = didec_if_negative:nF, doc parameter = \marg{didec var}\marg{false code} },
+ }
+Evaluates the \meta{didec var}
+and returns |true| or executes the \meta{true code} if the value is negative,
+otherwise returns |false| or executes the \meta{false code}.
+\begin{dispExample}
+\didecset{A}{2799.50}
+\didecuse{A} is \didecifnegative{A}{negative}{not negative}.
+
+\didecset{B}{-584}
+\didecuse{B} is \didecifnegative{B}{negative}{not negative}.
+
+\didecset{A}{0}
+\didecuse{A} is \didecifnegative{A}{negative}{not negative}.
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+\clearpage
+%-------------------------------------------------------------------------------
+\begin{docCommands}[
+ doc parameter = \marg{didec var}\marg{true code}\marg{false code},
+ ]
+{
+ { doc name = didecifzero },
+ { doc name = didec_if_zero_p:n, doc parameter = \marg{didec var} },
+ { doc name = didec_if_zero:nTF, },
+ { doc name = didec_if_zero:nT, doc parameter = \marg{didec var}\marg{true code} },
+ { doc name = didec_if_zero:nF, doc parameter = \marg{didec var}\marg{false code} },
+ }
+Evaluates the \meta{didec var}
+and returns |true| or executes the \meta{true code} if the value is zero,
+otherwise returns |false| or executes the \meta{false code}.
+\begin{dispExample}
+\didecset{A}{2799.50}
+\didecuse{A} is \didecifzero{A}{zero}{not zero}.
+
+\didecset{B}{-584}
+\didecuse{B} is \didecifzero{B}{zero}{not zero}.
+
+\didecset{A}{0}
+\didecuse{A} is \didecifzero{A}{zero}{not zero}.
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+
+
+
+
+%-------------------------------------------------------------------------------
+\begin{docCommands}[
+ doc parameter = \marg{didec expr\textsubscript{1}}\marg{didec expr\textsubscript{2}}\marg{true code}\marg{false code},
+ ]
+{
+ { doc name = dideciflowerthan },
+ { doc name = didecifequal },
+ { doc name = didecifgreaterthan },
+ { doc name = didec_compare_p:nNn, doc parameter = \marg{didec expr\textsubscript{1}}\meta{relation}\marg{didec expr\textsubscript{2}} },
+ { doc name = didec_compare:nNnTF, doc parameter = \marg{didec expr\textsubscript{1}}\meta{relation}\marg{didec expr\textsubscript{2}}\marg{true code}\marg{false code} },
+ { doc name = didec_compare:nNnT, doc parameter = \marg{didec expr\textsubscript{1}}\meta{relation}\marg{didec expr\textsubscript{2}}\marg{true code} },
+ { doc name = didec_compare:nNnF, doc parameter = \marg{didec expr\textsubscript{1}}\meta{relation}\marg{didec expr\textsubscript{2}}\marg{false code} },
+ }
+Compares the \meta{didec expr\textsubscript{1}} and the \meta{didec expr\textsubscript{2}},
+and returns |true| or executes the \meta{true code} if the \meta{relation} (given by function respectively)
+is obeyed, otherwise returns |false| or executes the \meta{false code}.
+\begin{dispExample}
+\didecset{A}{2799.50}
+\didecset{B}{-584}
+\didecuse{A} is \dideciflowerthan{A}{B}{lower}{not lower} than \didecuse{B}
+
+\didecuse{A} is \didecifequal{A}{B}{equal}{not equal} to \didecuse{B}
+
+\didecuse{A} is \didecifequal{A}{A}{equal}{not equal} to \didecuse{A}
+
+\didecuse{A} is \didecifgreaterthan{A}{B}{greater}{not greater} than \didecuse{B}
+\end{dispExample}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+\clearpage
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{Viewing didecs}%
+
+%-------------------------------------------------------------------------------
+\begin{docCommands}
+{
+ { doc name = didec_show:n, doc parameter = \marg{didec var} },
+ }
+Displays the content of \meta{didec var} in the terminal.
+\begin{dispListing}
+\didecset{A}{2799.50}
+\ExplSyntaxOn
+\didec_show:n{A}
+\ExplSyntaxOff
+\end{dispListing}
+\end{docCommands}
+%-------------------------------------------------------------------------------
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\clearpage
+\phantomsection
+\printindex
+
+\end{document}
diff --git a/macros/latex/contrib/easybook/easybook.dtx b/macros/latex/contrib/easybook/easybook.dtx
index 1921c11313..e0506e460d 100644
--- a/macros/latex/contrib/easybook/easybook.dtx
+++ b/macros/latex/contrib/easybook/easybook.dtx
@@ -15,7 +15,7 @@
%<*class>
\NeedsTeXFormat{LaTeX2e}[2021/11/15]
\RequirePackage{l3keys2e}
-\ProvidesExplClass{easybook}{2024/02/25}{2024al}
+\ProvidesExplClass{easybook}{2024/02/28}{2024an}
{Easily typesetting Chinese theses or books}
\bool_new:N \l__eb_compile_draft_bool
@@ -297,7 +297,7 @@
%<*package>
\NeedsTeXFormat{LaTeX2e}[2021/11/15]
\RequirePackage{l3keys2e,etoolbox}
-\ProvidesExplPackage{easybase}{2024/02/25}{2024al}
+\ProvidesExplPackage{easybase}{2024/02/28}{2024an}
{Easily typesetting Chinese theses or books}
\cs_generate_variant:Nn \dim_set:Nn { NV }
@@ -668,9 +668,9 @@
\cs_set:Npn \markdouble #1 { \markboth{#1}{\ifbool{@twoside}{#1}{}} }
\cs_new:Npn \eb@level@markdouble #1#2
- { \markdouble{\use:c { eb@mark@#1@whole } {#2}} }
+ { \markdouble{\use:c { eb@mark@#1@whole }{#2}} }
\cs_new:Npn \eb@level@markright #1#2
- { \markright{\use:c { eb@mark@#1@whole } {#2}} }
+ { \markright{\use:c { eb@mark@#1@whole }{#2}} }
\cs_gset:Npn \chaptermark #1 { \eb@level@markdouble{chapter}{#1} }
\cs_gset:Npn \sectionmark #1
{
@@ -2390,7 +2390,7 @@
}
%</package>
%<*tcolorbox>
-\ProvidesExplFile{eb-tcolorbox.cfg}{2024/02/25}{2024al}
+\ProvidesExplFile{eb-tcolorbox.cfg}{2024/02/28}{2024an}
{Customization of tcolorbox for easybook}
\cs_set_protected:Npn \addtotcbstyle #1#2
diff --git a/macros/latex/contrib/easybook/easybook.pdf b/macros/latex/contrib/easybook/easybook.pdf
index 707045d46f..3bc9fb4d0e 100644
--- a/macros/latex/contrib/easybook/easybook.pdf
+++ b/macros/latex/contrib/easybook/easybook.pdf
Binary files differ
diff --git a/macros/latex/contrib/easybook/easybook.tex b/macros/latex/contrib/easybook/easybook.tex
index 061dcd0b08..58886c011f 100644
--- a/macros/latex/contrib/easybook/easybook.tex
+++ b/macros/latex/contrib/easybook/easybook.tex
@@ -10,7 +10,7 @@
\definecolorscheme{blue}
{
cs => violet,
- option => Green,
+ option => DarkGreen,
cnltx => DarkBlue,
link => DeepPink,
module => FireBrick,
@@ -23,8 +23,8 @@
name = easybook,
color-scheme = blue,
title = EASYBOOK使用手册,
- version = v2024al,
- date = 2024/02/25,
+ version = v2024an,
+ date = 2024/02/28,
authors = 瞿毅,
info = 简便地排版中文学位论文或书籍,
email = toquyi@163.com,
@@ -1401,7 +1401,7 @@
\shortversion{v = 1.638,date = 2022/03/04,changes = 增加目录条目样式选项注册命令 \cs{RegisterTocName}。}
\shortversion{v = 1.644,date = 2022/03/10,changes = 增加浮动环境目录声明命令 \cs{DeclareFloatList} 配合 \pkg*{caption} 宏包。}
\shortversion{v = 1.682,date = 2022/05/01,changes = 将迷你页判断命令 \cs{notminipage} 改为被保护命令兼容 \pkg*{circledtext} 宏包。}
- \begin{version}[v = 2024al,date = 2024/02/25]
+ \begin{version}[v = 2024an,date = 2024/02/28]
\fixed
\item 修复图表等浮动环境题注目录中条目标签编号的计数器值显示错误问题。
\item 修复附录命令 \cs{appendix} 的可选参数设置英文目录中条目名字和编号失效的问题。
diff --git a/macros/latex/contrib/mandi/mandi.dtx b/macros/latex/contrib/mandi/mandi.dtx
index 3907b21e1b..d1a72ab2b2 100644
--- a/macros/latex/contrib/mandi/mandi.dtx
+++ b/macros/latex/contrib/mandi/mandi.dtx
@@ -1,7 +1,7 @@
% \iffalse meta-comment
% !TEX program = lualatexmk
%
-% Copyright (C) 2023 by Paul J. Heafner <heafnerj@gmail.com>
+% Copyright (C) 2021-2024 by Paul J. Heafner <heafnerj@gmail.com>
% ---------------------------------------------------------------------------
% This work may be distributed and/or modified under the conditions of the
% LaTeX Project Public License, either version 1.3c of this license or (at
@@ -181,7 +181,7 @@
% \title{The \href{https://ctan.org/pkg/mandi}{\mandi} Bundle}
% \author{^^A
% Paul J. Heafner\thanks{^^A
-% Email: \href{mailto:heafnerj@gmail.com?subject=[Heafner]\%20mandi}
+% Email: \href{mailto:heafnerj@gmail.com?subject=from mandi documentation}
% {heafnerj@gmail.com}^^A
% }^^A
% }^^A
@@ -259,6 +259,10 @@
% {\linktoplace{sec:mandia}{mandi} \linktoplace{sec:mandib}{mandistudent}
% \linktoplace{sec:mandic}{mandiexp} Source updated and bumped version for new
% \texttt{CTAN} upload}
+% \changes{v3.2.2}{2024-02-27}{\linktoplace{sec:mandia}{mandi} Removed unnecessary
+% \cs{ExplSyntaxOn} and \cs{ExplSyntaxOff} pairs}
+% \changes{v3.2.2}{2024-02-27}{\linktoplace{sec:mandia}{mandi} Ensured all
+% subscripts and superscripts are braced}
%
% \section{Introduction}
% The \mandi \footnote{The bundle name can be pronounced either with two
@@ -380,7 +384,7 @@
%<*example>
%\fi
\begin{dispExample*}{sidebyside = false}
- \( \mivector{\slot,\slot,\slot} \) or \( \mivector{p_x,p_y,p_z} \) \\
+ \( \mivector{\slot,\slot,\slot} \) or \( \mivector{p_{x},p_{y},p_{z}} \) \\
\( \direction{\frac{1}{\sqrt{3}},\frac{1}{\sqrt{3}},\frac{1}{\sqrt{3}}} \) or
\end{dispExample*}
%\iffalse
@@ -502,11 +506,11 @@
{%
doc new = 2021-02-24,%
doc name = momentumvector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectormomentum,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
Command for momentum and its vector variants. The default units will depend
@@ -548,8 +552,9 @@
%
% Commands that include the name of a physical quantity typeset units, so
% they shouldn't be used for algebraic or symbolic values of components.
-% For example, one shouldn't use |\vectormomentum{mv_x,mv_y,mv_z}| but
-% instead the generic |\mivector{mv_x,mv_y,mv_z}| instead.
+% Don't use
+% |\vectormomentum{mv_{x},mv_{y},mv_{z}}| but
+% instead the generic |\mivector{mv_{x},mv_{y},mv_{z}}| instead.
%
% \subsubsection{Checking Physical Quantities}
%
@@ -587,11 +592,11 @@
{%
doc new = 2021-02-24,%
doc name = accelerationvector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectoracceleration,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -608,11 +613,11 @@
{%
doc new = 2021-02-24,%
doc name = angularaccelerationvector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectorangularacceleration,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -629,11 +634,11 @@
{%
doc new = 2021-02-24,%
doc name = angularimpulsevector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectorangularimpulse,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -647,11 +652,11 @@
{%
doc new = 2021-02-24,%
doc name = angularmomentumvector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectorangularmomentum,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -665,11 +670,11 @@
{%
doc new = 2021-02-24,%
doc name = angularvelocityvector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectorangularvelocity,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -698,11 +703,11 @@
{%
doc new = 2021-02-24,%
doc name = cmagneticfieldvector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectorcmagneticfield,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -728,11 +733,11 @@
{%
doc new = 2021-02-24,%
doc name = currentdensityvector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectorcurrentdensity,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -749,11 +754,11 @@
},%
{%
doc name = directionvector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectordirection,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -767,11 +772,11 @@
{%
doc new = 2021-02-24,%
doc name = displacementvector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectordisplacement,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -788,10 +793,10 @@
{%
doc new = 2021-02-24,%
doc name = electricdipolemomentvector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{ doc name = vectorelectricdipolemoment,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -805,11 +810,11 @@
{%
doc new = 2021-02-24,%
doc name = electricfieldvector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectorelectricfield,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -853,11 +858,11 @@
{%
doc new = 2021-02-24,%
doc name = energyfluxvector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectorenergyflux,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -874,11 +879,11 @@
{%
doc new = 2021-02-24,%
doc name = forcevector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectorforce,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -895,11 +900,11 @@
{%
doc new = 2021-02-24,%
doc name = gravitationalfieldvector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectorgravitationalfield,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -919,11 +924,11 @@
{%
doc new = 2021-02-24,%
doc name = impulsevector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectorimpulse,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -958,11 +963,11 @@
{%
doc new = 2021-02-24,%
doc name = magneticdipolemomentvector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectormagneticdipolemoment,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -976,11 +981,11 @@
{%
doc new = 2021-02-24,%
doc name = magneticfieldvector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectormagneticfield,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -1008,12 +1013,12 @@
doc new = 2021-02-24,%
doc name = momentumvector,%
doc label = momentumvectordemo,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectormomentum,%
doc label = vectormomentumdemo,%
- doc parameter = \marg{\( c_1,\dots,c_n \)} },%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)} },%
}%
\end{docCommands}
\CheckQuantity{momentum}
@@ -1026,11 +1031,11 @@
{%
doc new = 2021-02-24,%
doc name = momentumfluxvector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectormomentumflux,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -1062,11 +1067,11 @@
{%
doc new = 2021-02-24,%
doc name = poyntingvector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectorpoynting,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -1116,11 +1121,11 @@
{%
doc new = 2021-02-24,%
doc name = torquevector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectortorque,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -1134,11 +1139,11 @@
{%
doc new = 2021-02-24,%
doc name = velocityvector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectorvelocity,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -1152,11 +1157,11 @@
{%
doc new = 2021-02-24,%
doc name = velocitycvector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectorvelocityc,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -1182,11 +1187,11 @@
{%
doc new = 2021-02-24,%
doc name = wavenumbervector,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
{%
doc name = vectorwavenumber,%
- doc parameter = \marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \marg{\( c_{1},\dots,c_{n} \)},%
},%
}%
\end{docCommands}
@@ -1842,7 +1847,7 @@
\begin{dispExample}
\( \per \) \\
\( \usk \) \\
- \( \units{3}{\meter\per\second} \) \\
+ \( \units{3}{\meter\per\second} \) \\
\( \emptyunit \) \\
\( \ampere \) \\
\( \atomicmassunit \) \\
@@ -1930,7 +1935,7 @@
%<*example>
%\fi
\begin{docCommand}[doc updated = 2022-01-27]{mivector}{%
- \oarg{delimiter}\marg{\( c_1,\dots,c_n \)}\oarg{units}
+ \oarg{delimiter}\marg{\( c_{1},\dots,c_{n} \)}\oarg{units}
}%
Typesets a vector as either numeric or symbolic components with an
optional unit (for numerical components only). There must be more
@@ -1940,12 +1945,12 @@
\emph{Matter \& Interactions}.
\end{docCommand}
\begin{dispExample*}{lefthand ratio = 0.70}
- \( \mivector{p_0,p_1,p_2,p_3} \) \\
- \( \mivector{\gamma mc,\gamma mv_x,\gamma mv_y,\gamma mv_z} \) \\
- \( \mivector{\frac{Q_1Q_2}{x^2},0,0} \) \\
- \( \mivector{-1,0,0} \) \\
- \( \mivector{-1,0,0}[\velocityonlyderivedunits] \) \\
- \( \mivector{-1,0,0}[\meter\per\second] \) \\
+ \( \mivector{p_0,p_1,p_2,p_3} \) \\
+ \( \mivector{\gamma mc,\gamma mv_{x},\gamma mv_{y},\gamma mv_{z}} \) \\
+ \( \mivector{\frac{Q_1Q_2}{x^2},0,0} \) \\
+ \( \mivector{-1,0,0} \) \\
+ \( \mivector{-1,0,0}[\velocityonlyderivedunits] \) \\
+ \( \mivector{-1,0,0}[\meter\per\second] \) \\
\( \velocity{\mivector{-1,0,0}} \)
\end{dispExample*}
%\iffalse
@@ -1966,10 +1971,10 @@
% in the name) that are not for the user to know about.
%
% \begin{macrocode}
-\def\mandi@version{3.2.1}
-\def\mandi@date{2023-11-22}
+\def\mandi@version{3.2.2}
+\def\mandi@date{2024-02-27}
\NeedsTeXFormat{LaTeX2e}[2020-02-02]
-\DeclareRelease{v3.2.1}{2023-11-22}{mandi.sty}
+\DeclareRelease{v3.2.2}{2024-02-27}{mandi.sty}
\DeclareCurrentRelease{v\mandi@version}{\mandi@date}
\ProvidesPackage{mandi}
[\mandi@date\space v\mandi@version\space Macros for physical quantities]
@@ -2268,13 +2273,11 @@
{
\__mandi_newscalarquantity:nnnn { #1 }{ #2 }{ #3 }{ #4 }
}
-\ExplSyntaxOff
% \end{macrocode}
%
% Redefining an existing scalar quantity.
%
% \begin{macrocode}
-\ExplSyntaxOn
\cs_new:Npn \__mandi_renewscalarquantity:nnnn #1#2#3#4
{
\cs_set:cpn {#1} ##1 {\units{##1}{\mandi@selectunits{#2}{#3}{#4}}}
@@ -2290,13 +2293,11 @@
{
\__mandi_renewscalarquantity:nnnn { #1 }{ #2 }{ #3 }{ #4 }
}
-\ExplSyntaxOff
% \end{macrocode}
%
% Defining a new vector quantity. Note that a corresponding scalar is also defined.
%
% \begin{macrocode}
-\ExplSyntaxOn
\cs_new:Npn \__mandi_newvectorquantity:nnnn #1#2#3#4
{
\__mandi_newscalarquantity:nnnn { #1 }{ #2 }{ #3 }{ #4 }
@@ -2321,13 +2322,11 @@
{
\__mandi_newvectorquantity:nnnn { #1 }{ #2 }{ #3 }{ #4 }
}
-\ExplSyntaxOff
% \end{macrocode}
%
% Redefining an existing vector quantity. Note that a corresponding scalar is also redefined.
%
% \begin{macrocode}
-\ExplSyntaxOn
\cs_new:Npn \__mandi_renewvectorquantity:nnnn #1#2#3#4
{
\__mandi_renewscalarquantity:nnnn { #1 }{ #2 }{ #3 }{ #4 }
@@ -2352,13 +2351,11 @@
{
\__mandi_renewvectorquantity:nnnn { #1 }{ #2 }{ #3 }{ #4 }
}
-\ExplSyntaxOff
% \end{macrocode}
%
% Defining a new physical constant.
%
% \begin{macrocode}
-\ExplSyntaxOn
\cs_new:Npn \__mandi_newphysicalconstant:nnnnnnn #1#2#3#4#5#6#7
{
\cs_new:cpn {#1} {\units{\mandi@selectprecision{#3}{#4}}{\mandi@selectunits{#5}{#6}{#7}}}
@@ -2379,13 +2376,11 @@
{
\__mandi_newphysicalconstant:nnnnnnn { #1 }{ #2 }{ #3 }{ #4 }{ #5 }{ #6 }{ #7 }
}
-\ExplSyntaxOff
% \end{macrocode}
%
% Redefining an existing physical constant.
%
% \begin{macrocode}
-\ExplSyntaxOn
\cs_new:Npn \__mandi_renewphysicalconstant:nnnnnnn #1#2#3#4#5#6#7
{
\cs_set:cpn {#1} {\units{\mandi@selectprecision{#3}{#4}}{\mandi@selectunits{#5}{#6}{#7}}}
diff --git a/macros/latex/contrib/mandi/mandi.ins b/macros/latex/contrib/mandi/mandi.ins
index a479906b68..c5ba38a19b 100644
--- a/macros/latex/contrib/mandi/mandi.ins
+++ b/macros/latex/contrib/mandi/mandi.ins
@@ -6,7 +6,7 @@
%%
%% mandi.dtx (with options: `install')
%%
-%% Copyright (C) 2023 by Paul J. Heafner <heafnerj@gmail.com>
+%% Copyright (C) 2021-2024 by Paul J. Heafner <heafnerj@gmail.com>
%% ---------------------------------------------------------------------------
%% This work may be distributed and/or modified under the conditions of the
%% LaTeX Project Public License, either version 1.3c of this license or (at
@@ -38,7 +38,7 @@
\usedir{tex/latex/mandi}
\preamble
- Copyright (C) 2023 by Paul J. Heafner <heafnerj@gmail.com>
+ Copyright (C) 2021-2024 by Paul J. Heafner <heafnerj@gmail.com>
---------------------------------------------------------------------------
This work may be distributed and/or modified under the conditions of the
LaTeX Project Public License, either version 1.3c of this license or (at
diff --git a/macros/latex/contrib/mandi/mandi.pdf b/macros/latex/contrib/mandi/mandi.pdf
index 9b3fa83b44..a3d53d4794 100644
--- a/macros/latex/contrib/mandi/mandi.pdf
+++ b/macros/latex/contrib/mandi/mandi.pdf
Binary files differ
diff --git a/macros/latex/contrib/mandi/mandiexp.dtx b/macros/latex/contrib/mandi/mandiexp.dtx
index bbd1501a73..7ea77c5f84 100644
--- a/macros/latex/contrib/mandi/mandiexp.dtx
+++ b/macros/latex/contrib/mandi/mandiexp.dtx
@@ -1,7 +1,7 @@
% \iffalse meta-comment
% !TEX program = lualatexmk
%
-% Copyright (C) 2023 by Paul J. Heafner <heafnerj@gmail.com>
+% Copyright (C) 2021-2024 by Paul J. Heafner <heafnerj@gmail.com>
% ---------------------------------------------------------------------------
% This work may be distributed and/or modified under the conditions of the
% LaTeX Project Public License, either version 1.3c of this license or (at
@@ -571,10 +571,10 @@
% \changes{v3.1.0}{2022-01-27}
% {\linktoplace{sec:mandic}{mandiexp} Version number works}
% \begin{macrocode}
-\def\mandiexp@version{3.2.1}
-\def\mandiexp@date{2023-11-22}
+\def\mandiexp@version{3.2.2}
+\def\mandiexp@date{2024-02-27}
\NeedsTeXFormat{LaTeX2e}[2020-02-02]
-\DeclareRelease{v3.2.1}{2023-11-22}{mandiexp.sty}
+\DeclareRelease{v3.2.2}{2024-02-27}{mandiexp.sty}
\DeclareCurrentRelease{v\mandiexp@version}{\mandiexp@date}
\ProvidesPackage{mandiexp}
[\mandiexp@date\space v\mandiexp@version\space Macros for Matter & Interactions]
diff --git a/macros/latex/contrib/mandi/mandistudent.dtx b/macros/latex/contrib/mandi/mandistudent.dtx
index da277a0baa..0360617b50 100644
--- a/macros/latex/contrib/mandi/mandistudent.dtx
+++ b/macros/latex/contrib/mandi/mandistudent.dtx
@@ -1,7 +1,7 @@
% \iffalse meta-comment
% !TEX program = lualatexmk
%
-% Copyright (C) 2023 by Paul J. Heafner <heafnerj@gmail.com>
+% Copyright (C) 2021-2024 by Paul J. Heafner <heafnerj@gmail.com>
% ---------------------------------------------------------------------------
% This work may be distributed and/or modified under the conditions of the
% LaTeX Project Public License, either version 1.3c of this license or (at
@@ -722,7 +722,7 @@ while t < 10:
%<*example>
%\fi
\begin{docCommands}[%
- doc parameter = \oarg{delimiter}\marg{\( c_1,\dots,c_n \)},%
+ doc parameter = \oarg{delimiter}\marg{\( c_{1},\dots,c_{n} \)},%
]%
{%
{%
@@ -740,8 +740,8 @@ while t < 10:
\begin{dispExample}
\[ \colvec{1,2,3} \]
\[ \rowvec{1,2,3} \]
- \[ \colvec{x^0,x^1,x^2,x^3} \]
- \[ \rowvec{x_0,x_1,x_2,x_3} \]
+ \[ \colvec{x^{0},x^{1},x^{2},x^{3}} \]
+ \[ \rowvec{x_{0},x_{1},x_{2},x_{3}} \]
\end{dispExample}
%\iffalse
%</example>
@@ -1243,10 +1243,10 @@ while t < 10:
% \changes{v3.1.0}{2022-01-27}
% {\linktoplace{sec:mandib}{mandistudent} Version number works}
% \begin{macrocode}
-\def\mandistudent@version{3.2.1}
-\def\mandistudent@date{2023-11-22}
+\def\mandistudent@version{3.2.2}
+\def\mandistudent@date{2024-02-27}
\NeedsTeXFormat{LaTeX2e}[2020-02-02]
-\DeclareRelease{v3.2.1}{2023-11-22}{mandistudent.sty}
+\DeclareRelease{v3.2.2}{2024-02-27}{mandistudent.sty}
\DeclareCurrentRelease{v\mandistudent@version}{\mandistudent@date}
\ProvidesPackage{mandistudent}
[\mandistudent@date\space v\mandistudent@version\space Macros for introductory physics]
diff --git a/macros/luatex/generic/luaotfload/NEWS b/macros/luatex/generic/luaotfload/NEWS
index 17ce0a00c4..eae0df4b3d 100644
--- a/macros/luatex/generic/luaotfload/NEWS
+++ b/macros/luatex/generic/luaotfload/NEWS
@@ -1,5 +1,9 @@
Change History
--------------
+2024-02-28 luaotfload v3.28
+
+ * Improving compatibility with Windows paths
+
2024-02-14 luaotfload v3.27
* Improved support for arabic mark rendering in \texttt{node} mode.
diff --git a/macros/luatex/generic/luaotfload/README.md b/macros/luatex/generic/luaotfload/README.md
index ed2ece5f29..e99e633fe4 100644
--- a/macros/luatex/generic/luaotfload/README.md
+++ b/macros/luatex/generic/luaotfload/README.md
@@ -1,6 +1,6 @@
# The Luaotfload Package
-VERSION: 3.27
+VERSION: 3.28
DATE: 2024-02-14
diff --git a/macros/luatex/generic/luaotfload/filegraph.pdf b/macros/luatex/generic/luaotfload/filegraph.pdf
index d0640d1ad6..f1b58572af 100644
--- a/macros/luatex/generic/luaotfload/filegraph.pdf
+++ b/macros/luatex/generic/luaotfload/filegraph.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/fontloader-basics-gen.lua b/macros/luatex/generic/luaotfload/fontloader-basics-gen.lua
index 5a6e90ceee..c79c31392b 100644
--- a/macros/luatex/generic/luaotfload/fontloader-basics-gen.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-basics-gen.lua
@@ -19,6 +19,7 @@ local formatters, split, format, dump = string.formatters, string.split, string.
local loadfile, type = loadfile, type
local setmetatable, getmetatable, collectgarbage = setmetatable, getmetatable, collectgarbage
local floor = math.floor
+local mkdirp = lfs.mkdirp or lfs.mkdirs
local dummyfunction = function()
end
@@ -231,7 +232,7 @@ do
for i=1,#cachepaths do
local cachepath = cachepaths[i]
if not lfs.isdir(cachepath) then
- lfs.mkdirs(cachepath) -- needed for texlive and latex
+ mkdirp(cachepath .. '/') -- needed for texlive and latex
if lfs.isdir(cachepath) then
logs.report("system","creating cache path '%s'",cachepath)
end
diff --git a/macros/luatex/generic/luaotfload/luaotfload-arabic.lua b/macros/luatex/generic/luaotfload/luaotfload-arabic.lua
index ac599ebca7..110e0d4694 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-arabic.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-arabic.lua
@@ -5,7 +5,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-arabic",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / features",
license = "GPL v2.0",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua b/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua
index 71abb0e1bd..ae7316f9df 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua
@@ -6,7 +6,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-auxiliary",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / auxiliary functions",
license = "GPL v2.0"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-colors.lua b/macros/luatex/generic/luaotfload/luaotfload-colors.lua
index 944d1745e4..1504cb7269 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-colors.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-colors.lua
@@ -5,7 +5,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-colors",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / color",
license = "GPL v2.0",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-conf.pdf b/macros/luatex/generic/luaotfload/luaotfload-conf.pdf
index 001729a1e2..b52716c8b5 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-conf.pdf
+++ b/macros/luatex/generic/luaotfload/luaotfload-conf.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/luaotfload-configuration.lua b/macros/luatex/generic/luaotfload/luaotfload-configuration.lua
index d8590666af..53d0543b84 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-configuration.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-configuration.lua
@@ -7,7 +7,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-configuration",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / config file reader",
license = "GPL v2.0"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-database.lua b/macros/luatex/generic/luaotfload/luaotfload-database.lua
index f1b59fcc7b..a466921d00 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-database.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-database.lua
@@ -5,7 +5,7 @@
do -- block to avoid to many local variables error
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-database",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / database",
license = "GPL v2.0",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua b/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua
index 83780b9929..d3a195c6cf 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua
@@ -7,7 +7,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-diagnostics",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload-tool submodule / diagnostics",
license = "GPL v2.0"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-dvi.lua b/macros/luatex/generic/luaotfload/luaotfload-dvi.lua
index f8d4d268f7..0200fc6ed1 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-dvi.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-dvi.lua
@@ -6,7 +6,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-dvi",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / DVI",
license = "GPL v2.0",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-embolden.lua b/macros/luatex/generic/luaotfload/luaotfload-embolden.lua
index caff50ed4d..30abf27ba4 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-embolden.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-embolden.lua
@@ -5,7 +5,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-embolden",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / embolden",
license = "GPL v2.0",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-fallback.lua b/macros/luatex/generic/luaotfload/luaotfload-fallback.lua
index a527095618..3a47473699 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-fallback.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-fallback.lua
@@ -5,7 +5,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-fallback",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / fallback",
license = "GPL v2.0",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-features.lua b/macros/luatex/generic/luaotfload/luaotfload-features.lua
index d4d96217aa..1029809fc7 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-features.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-features.lua
@@ -5,7 +5,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-features",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / features",
license = "GPL v2.0",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-filelist.lua b/macros/luatex/generic/luaotfload/luaotfload-filelist.lua
index 9b5f618cc2..33c8b16f82 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-filelist.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-filelist.lua
@@ -6,7 +6,7 @@
if luaotfload_module then luaotfload_module {
name = "luaotfload-filelist",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / filelist",
license = "GPL v2.0"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua b/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua
index f300d4955d..2a931282a3 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua
@@ -1,7 +1,7 @@
if luaotfload_module then
luaotfload_module {
name = "luaotfload-glyphlist",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / autogenerated glyphlist",
copyright = "derived from https://raw.githubusercontent.com/adobe-type-tools/agl-aglfn/master/glyphlist.txt",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua
index 7eb795d176..3dfb74a302 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua
@@ -5,7 +5,7 @@
do -- block to avoid to many local variables error
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-harf-define",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / HarfBuzz font loading",
license = "GPL v2.0",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua
index 5c2d13df00..f26c872734 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua
@@ -4,7 +4,7 @@
-----------------------------------------------------------------------
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-harf-plug",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / HarfBuzz shaping",
license = "GPL v2.0",
@@ -23,8 +23,10 @@ local format = string.format
local open = io.open
local tableinsert = table.insert
local tableremove = table.remove
-local ostmpname = os.tmpname
+local ostmpdir = os.tmpdir
local osremove = os.remove
+local dir = lfs.dir
+local rmdir = lfs.rmdir
local direct = node.direct
local tonode = direct.tonode
@@ -704,13 +706,17 @@ end
-- Cache of color glyph PNG data for bookkeeping, only because I couldn't
-- figure how to make the engine load the image from the binary data directly.
+local tmpdirname
+local tmpcount = 0
local pngcache = {}
local pngcachefiles = {}
local function cachedpng(data)
local hash = md5.sumhexa(data)
local i = pngcache[hash]
if not i then
- local path = ostmpname()
+ tmpdirname = tmpdirname or ostmpdir()
+ tmpcount = tmpcount + 1
+ local path = format('%s/%i.png', tmpdirname, tmpcount)
pngcachefiles[#pngcachefiles + 1] = path
open(path, "wb"):write(data):close()
-- local file = open(path, "wb"):write():close()
@@ -1106,9 +1112,14 @@ end
local function run_cleanup()
-- Remove temporary PNG files that we created, if any.
-- FIXME: It would be nice if we wouldn't need this
- for _, path in next, pngcachefiles do
- osremove(path)
+ if not tmpdirname then return end
+ for file in dir(tmpdirname) do
+ if file ~= '.' and file ~= '..' then
+ assert(osremove(format('%s/%s', tmpdirname, file)))
+ end
end
+ assert(rmdir(tmpdirname))
+ tmpdirname = nil
end
local function set_tounicode()
diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-var-cff2.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-var-cff2.lua
index ad8fbdcd26..3dbf28fc1d 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-harf-var-cff2.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-harf-var-cff2.lua
@@ -5,7 +5,7 @@
do
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-harf-var-cff2",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / CFF2 table processing",
license = "GPL v2.0",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-var-t2-writer.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-var-t2-writer.lua
index 1d40d09ad0..78f403473c 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-harf-var-t2-writer.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-harf-var-t2-writer.lua
@@ -5,7 +5,7 @@
do
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-harf-var-t2-writer",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / Type 2 charstring writer",
license = "GPL v2.0",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-var-ttf.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-var-ttf.lua
index a6d4d36aba..508e35a1d0 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-harf-var-ttf.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-harf-var-ttf.lua
@@ -5,7 +5,7 @@
do
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-harf-var-ttf",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / gvar table processing",
license = "GPL v2.0",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-init.lua b/macros/luatex/generic/luaotfload/luaotfload-init.lua
index 13b1099752..cbfcdd7774 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-init.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-init.lua
@@ -7,7 +7,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-init",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / initialization",
license = "GPL v2.0"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-latex.pdf b/macros/luatex/generic/luaotfload/luaotfload-latex.pdf
index bc1e5abae6..c53211a235 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-latex.pdf
+++ b/macros/luatex/generic/luaotfload/luaotfload-latex.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua b/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua
index b2b848bfc6..957ae8564c 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua
@@ -5,7 +5,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-letterspace",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / letterspacing",
license = "GPL v2.0",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-loaders.lua b/macros/luatex/generic/luaotfload/luaotfload-loaders.lua
index 86f48ee69a..88f791a487 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-loaders.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-loaders.lua
@@ -8,7 +8,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-loaders",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / callback handling",
license = "GPL v2.0"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-log.lua b/macros/luatex/generic/luaotfload/luaotfload-log.lua
index d22c48eda5..99ac182a4b 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-log.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-log.lua
@@ -6,7 +6,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-log",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / logging",
license = "GPL v2.0",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-main.tex b/macros/luatex/generic/luaotfload/luaotfload-main.tex
index f631263dee..96415cf402 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-main.tex
+++ b/macros/luatex/generic/luaotfload/luaotfload-main.tex
@@ -32,7 +32,7 @@
\beginfrontmatter
\setdocumenttitle {The \identifier{luaotfload} package}
- \setdocumentdate {2024-02-14 v3.27}
+ \setdocumentdate {2024-02-14 v3.28}
\setdocumentauthor {LaTeX3 Project\\
Elie Roux · Khaled Hosny · Philipp Gesang · Ulrike Fischer · Marcel Krüger\\
Home: \hyperlink {https://github.com/latex3/luaotfload}}
@@ -62,13 +62,9 @@ Supported is the \identifier{luatex} versions of a current TeXLive 2019 (and a c
\endsection
\beginsection{Changes}
-\beginsubsection{New in version 3.27}
+\beginsubsection{New in version 3.28}
\begin{itemize}
- \item Improved support for arabic mark rendering in \texttt{node} mode.
- \item Better ordering of GSUB substitutions.
- \item Avoid dropping hyphens in DVI mode
- \item Compatibility with \identifier{luatex} 1.18
- \item Various bug fixes
+ \item Improving compatibility with Windows paths
\end{itemize}
\endsubsection
diff --git a/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua b/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua
index c3a611a1f8..c4b0a28f90 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua
@@ -5,7 +5,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-multiscript",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / multiscript",
license = "GPL v2.0",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-notdef.lua b/macros/luatex/generic/luaotfload/luaotfload-notdef.lua
index f738fbdae9..7c298d9c58 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-notdef.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-notdef.lua
@@ -5,7 +5,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-notdef",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / notdef",
license = "GPL v2.0",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-parsers.lua b/macros/luatex/generic/luaotfload/luaotfload-parsers.lua
index 27c8c449ca..edbd6aa07d 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-parsers.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-parsers.lua
@@ -7,7 +7,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-parsers",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / parsers",
license = "GPL v2.0"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-realpath.lua b/macros/luatex/generic/luaotfload/luaotfload-realpath.lua
index 2738da8a1b..34f60f4d82 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-realpath.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-realpath.lua
@@ -9,18 +9,22 @@ local move = table.move
local newtable = lua.newtable
local setmetatable = setmetatable
+-- Windows should just adapt reasonable path conventions like every other operating system.
+-- But some people like to do their own thing, so we need lots of special casing here.
+local windows_style_paths = os.type ~= 'unix'
+
-- Marker key for elements of result_tree to indicate the path components entry and the file mode
local path_components, file_mode = {}, {}
local tree_root
local split_path do
local l = lpeg
- local separator = os.type == 'unix' and l.S'/' or l.S'/\\'
+ local separator = windows_style_paths and l.S'/\\' or l.S'/'
-- We do not allow empty segments here because they get ignored.
local segment = l.C((1 - separator)^1)
-- Duplicate and trailing separators are dropped.
- local unc = os.type == 'unix' and l.P(false) or separator * separator * l.Cg(l.P(1)^0 * -1, 'unc')
- local drive_letter = os.type == 'unix' and l.P(false) or l.Cg(l.R('az', 'AZ') * ':', 'drive')
+ local unc = windows_style_paths and separator * separator * l.Cg(l.P(1)^0 * -1, 'unc') or l.P(false)
+ local drive_letter = windows_style_paths and l.Cg(l.R('az', 'AZ') * ':', 'drive') or l.P(false)
local path_pat = l.Ct(unc + drive_letter^-1 * (l.Cc'' * separator^1)^-1 * (segment * separator^1)^0 * segment^-1 * -1)
function split_path(path)
local splitted = path_pat:match(path)
@@ -45,7 +49,11 @@ end
local function lookup_split_path_in_tree(components, tree)
if components[1] == '' then
- tree = tree_root
+ if windows_style_paths then
+ tree = tree_root[components.drive or tree[path_components].drive]
+ else
+ tree = tree_root
+ end
end
for i=1, #components do
local next_tree = tree[components[i]]
@@ -62,8 +70,8 @@ tree_meta = {
__index = function(parent, component)
local parent_components = parent[path_components]
local depth = #parent_components
- local components = move(parent[path_components], 1, depth, 1, newtable(depth + 1, 0))
- components[depth + 1] = component
+ local components = move(parent_components, 1, depth, 1, newtable(depth + 1, 1))
+ components.drive, components[depth + 1] = parent_components.drive, component
local path = recombine_path(components)
local mode = symlinkattributes(path, 'mode')
@@ -101,17 +109,17 @@ function build_root_dir(drive)
}, tree_meta)
root_dir['.'] = root_dir
root_dir['..'] = root_dir
- return root_dir
+ return {[''] = root_dir}
end
-tree_root = os.type == 'unix' and build_root_dir() or setmetatable({}, {__index = function(t, drive)
+tree_root = windows_style_paths and setmetatable({}, {__index = function(t, drive)
local root_dir = build_root_dir(drive)
t[drive] = root_dir
return root_dir
-end})
+end}) or build_root_dir()
local function resolve_path_to_tree(path)
local splitted = split_path(path)
- if splitted[1] == '' then -- Optimization to avoid currentdir lookup.
+ if splitted[1] == '' and (not windows_style_paths or splitted.drive) then -- Optimization to avoid currentdir lookup.
return lookup_split_path_in_tree(splitted, tree_root)
else
local splitted_currentdir = split_path(currentdir())
diff --git a/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua b/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua
index 93e8f61c30..2b6575f2fd 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua
@@ -11,7 +11,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-resolvers",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / resolvers",
license = "GPL v2.0"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-scripts.lua b/macros/luatex/generic/luaotfload/luaotfload-scripts.lua
index 75f9e3b579..cabb5b1c81 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-scripts.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-scripts.lua
@@ -5,7 +5,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-script",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / Script helpers",
license = "CC0 1.0 Universal",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-status.lua b/macros/luatex/generic/luaotfload/luaotfload-status.lua
index 530fc06edd..07959f2cd5 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-status.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-status.lua
@@ -54,46 +54,46 @@ return {
{ "fontloader-font-ini.lua", "16b855c98602e4a3e9df39512916a427" },
{ "fontloader-data-con.lua", "b4ab51aaeab872d86d827f3e216bf05e" },
{ "fontloader-reference.lua", "23d03b682af6417aa08995f2ec10de22" },
- { "fontloader-basics-gen.lua", "4bc43036e9796fccb0b8869f4b05bf2e" },
+ { "fontloader-basics-gen.lua", "578c251c496bed783075709e94c2be26" },
{ "mktests", "918cb50be9ee8bd645ac1a27dc501e8c" },
- { "mkstatus", "201011fcb01d8d804cc27b69d184b1e5" },
+ { "mkstatus", "855ec00d090bd8949a1e2d2a59ca553e" },
{ "mkcharacters", "bfca0e96e1e351afe7077502f9595af9" },
{ "mkglyphlist", "7a8a8fdc0eac7fac2f13ec8f4e8e7aa9" },
{ "mkimport", "7d62f1042e548f8b9368f26b9ba4be5c" },
- { "luaotfload-glyphlist.lua", "5b7427a864ba333f2f674b172bba2b63" },
+ { "luaotfload-glyphlist.lua", "61c0df805e753d4408972d93c1f4fef4" },
{ "luaotfload-characters.lua", "76415ca3ede312cad6e09038323489ae" },
- { "luaotfload-dvi.lua", "a88ce85492b935becf9de00d168b9fc6" },
- { "luaotfload-tounicode.lua", "834c7cb80bd7793c516187aa67a5dab8" },
- { "luaotfload-unicode.lua", "7559a279476f189206b248117d80f70d" },
- { "luaotfload-resolvers.lua", "aa07ed5021ce7bfb381ddd584910af6b" },
- { "luaotfload-parsers.lua", "eb862d8075e5e0b6130beed3f89f29be" },
- { "luaotfload-fallback.lua", "49bc7a9f026fd23e13cd1b4be30be43c" },
- { "luaotfload-szss.lua", "b174020a2eb6021e0b8838f0ad4f0fe4" },
- { "luaotfload-scripts.lua", "cf7669cbc2e1585e5e9f63b2ebef5a0f" },
- { "luaotfload-multiscript.lua", "478c8afcc416be47c861474a3b64096b" },
- { "luaotfload-loaders.lua", "178c47e50037b1455c29b10a826b8ebc" },
- { "luaotfload-harf-plug.lua", "eb202ef8123cf63e6d4820452391697f" },
- { "luaotfload-harf-define.lua", "5723873002793c7ea723c8f1abfc412d" },
- { "luaotfload-notdef.lua", "ffae44eac263adc9e7b6c5f6373637ed" },
- { "luaotfload-embolden.lua", "85ef9409937b25da3f3f4bbb0d72cebc" },
- { "luaotfload-letterspace.lua", "b608dac037f4b173833eac25d205ed91" },
- { "luaotfload-features.lua", "b43dedff88145a0626bdfcb77f8791ee" },
- { "luaotfload-database.lua", "d92cce26908694dbbb30232252e12f80" },
- { "luaotfload-configuration.lua", "84379ea613f7e55c07f17b55b9dfb67b" },
- { "luaotfload-colors.lua", "89386fcb44e2887b1be60b8acbe251b3" },
- { "luaotfload-auxiliary.lua", "a43134987a5cf7fc22bfd240745440fe" },
- { "luaotfload-filelist.lua", "e40105831b58e5f0fa4908a7a131da1f" },
- { "luaotfload-tool.lua", "89fc6f4c6e2630305a91dd6a29c1449d" },
- { "luaotfload-diagnostics.lua", "7e07c0b2d9470c016d72d36900904792" },
- { "luaotfload-log.lua", "e008c6135446dff77813079ce11a10e8" },
- { "luaotfload-init.lua", "9f354ea115993d9a9238d5f74c7d7e63" },
+ { "luaotfload-dvi.lua", "8d3f9adeaf8896eb94baf4f4a7cb72a4" },
+ { "luaotfload-tounicode.lua", "245271ce518c136c96f22fee6cb810ab" },
+ { "luaotfload-unicode.lua", "cebc6454abe34f2fe1c1248f8b2453da" },
+ { "luaotfload-resolvers.lua", "0f87b7c297120189ddbd31f6ee324a9f" },
+ { "luaotfload-parsers.lua", "73f67f95af947fe741c931e6f60b84cb" },
+ { "luaotfload-fallback.lua", "3b1569703b22fabe9661f2188fa0dbd3" },
+ { "luaotfload-szss.lua", "bdf184e24947478dc89307adf866a3ca" },
+ { "luaotfload-scripts.lua", "2026f40b86c3e93eba401524424e71d9" },
+ { "luaotfload-multiscript.lua", "1415dc53c2ad56f6dc892212090d7c03" },
+ { "luaotfload-loaders.lua", "80907f5cf87e2d5f946936a1ef08b6a8" },
+ { "luaotfload-harf-plug.lua", "201bbdd109fa1f0b02068e59f2f5384d" },
+ { "luaotfload-harf-define.lua", "f1319af7f3837fbda6db470b77627c71" },
+ { "luaotfload-notdef.lua", "920854a37e695604457cb1fcad35a814" },
+ { "luaotfload-embolden.lua", "6b15c8ae9e49cfb4a5e319aadf1ef3ac" },
+ { "luaotfload-letterspace.lua", "45fe7d691be75f6ef7f0c058c40113d9" },
+ { "luaotfload-features.lua", "756bc857a0d63bf1a6abbd1406e85844" },
+ { "luaotfload-database.lua", "0e2f26fead21ffdb36f36a5090220f8d" },
+ { "luaotfload-configuration.lua", "0abab568ba9c0082c9ad3e1b75897d49" },
+ { "luaotfload-colors.lua", "cda35651d19ec5ae24d18f3b0e1cfeec" },
+ { "luaotfload-auxiliary.lua", "6dbe1a2a3f36cf57845e54c1927ccfee" },
+ { "luaotfload-filelist.lua", "bd805bc5b92346005cde05679a4db421" },
+ { "luaotfload-tool.lua", "244ec7b1febf40d9e153e7aab7ad7237" },
+ { "luaotfload-diagnostics.lua", "8a51337bd7dcaf772ced0c16d13654cc" },
+ { "luaotfload-log.lua", "b0cd5d77653fae19eceb1c1f195d9b77" },
+ { "luaotfload-init.lua", "5808f9c69b6a266fef8b923aefaecdc3" },
{ "luaotfload-main.lua", "b19c9cc34cf1d676c39f872cfb41aef6" },
},
["notes"]={
["committer"]="Marcel Fabian Krüger <tex@2krueger.de>",
- ["description"]="v3.27/2024-02-14",
+ ["description"]="v3.28/2024-02-14",
["loader"]="fontloader-2023-12-28.lua",
- ["revision"]="17a160cd9eacf04cb179e7405f2d616824314868",
- ["timestamp"]="2024-02-14 22:31:40 +0100",
+ ["revision"]="73dac18445938c6c54118045944817c4e8c59a1c",
+ ["timestamp"]="2024-02-28 06:18:10 +0100",
},
} \ No newline at end of file
diff --git a/macros/luatex/generic/luaotfload/luaotfload-suppress.lua b/macros/luatex/generic/luaotfload/luaotfload-suppress.lua
index 1df46db80b..9735dbf679 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-suppress.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-suppress.lua
@@ -5,7 +5,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-suppress",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / suppress",
license = "GPL v2.0",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-szss.lua b/macros/luatex/generic/luaotfload/luaotfload-szss.lua
index c01d271d59..9c88f6f1e5 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-szss.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-szss.lua
@@ -5,7 +5,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-szss",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / Special feature handling",
license = "GPL v2.0",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.1 b/macros/luatex/generic/luaotfload/luaotfload-tool.1
index 1334d48da9..f1b902ae62 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-tool.1
+++ b/macros/luatex/generic/luaotfload/luaotfload-tool.1
@@ -1,8 +1,5 @@
.\" Man page generated from reStructuredText.
.
-.TH LUAOTFLOAD-TOOL 1 "2024-02-14" "3.27" "text processing"
-.SH NAME
-luaotfload-tool \- generate and query the Luaotfload font names database
.
.nr rst2man-indent-level 0
.
@@ -30,6 +27,9 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
+.TH "LUAOTFLOAD-TOOL" 1 "2024-02-14" "3.28" "text processing"
+.SH NAME
+luaotfload-tool \- generate and query the Luaotfload font names database
.SH SYNOPSIS
.sp
\fBluaotfload\-tool\fP [ \-bcDfFiIlLnpqRSuvVhw ]
@@ -77,14 +77,14 @@ the \fILuaotfload\fP package. There are two general modes: \fBupdate\fP and
.SS update mode
.INDENT 0.0
.TP
-.B \-\-update\fP,\fB \-u
+.B \-\-update\fP,\fB \-u
Update the database; indexes new fonts.
.TP
-.B \-\-force\fP,\fB \-f
+.B \-\-force\fP,\fB \-f
Force rebuilding of the database; re\-indexes
all fonts.
.TP
-.B \-\-local\fP,\fB \-L
+.B \-\-local\fP,\fB \-L
Include font files in \fB$PWD\fP\&. This option
will cause large parts of the database to be
rebuilt. Thus it is quite inefficient.
@@ -93,16 +93,16 @@ the database is prevented from being saved
to disk, so the local fonts need to be parsed
with every invocation of \fBluaotfload\-tool\fP\&.
.TP
-.B \-\-no\-reload\fP,\fB \-n
+.B \-\-no\-reload\fP,\fB \-n
Suppress auto\-updates to the database (e.g.
when \fB\-\-find\fP is passed an unknown name).
.TP
-.B \-\-no\-compress\fP,\fB \-c
+.B \-\-no\-compress\fP,\fB \-c
Do not filter the plain text version of the
font index through gzip. Useful for debugging
if your editor is built without zlib.
.TP
-.B \-\-prefer\-texmf\fP,\fB \-p
+.B \-\-prefer\-texmf\fP,\fB \-p
Organize the file name database in a way so
that it prefer fonts in the \fITEXMF\fP tree over
system fonts if they are installed in both.
@@ -139,16 +139,16 @@ mapped to.
i.e. \fB\-\-find=file:foo.otf\fP checks whether
\fBfoo.otf\fP is indexed.
.TP
-.B \-\-fuzzy\fP,\fB \-F
+.B \-\-fuzzy\fP,\fB \-F
Show approximate matches to the file name if
the lookup was unsuccessful (requires
\fB\-\-find\fP).
.TP
-.B \-\-info\fP,\fB \-i
+.B \-\-info\fP,\fB \-i
Display basic information to a resolved font
file (requires \fB\-\-find\fP).
.TP
-.B \-\-inspect\fP,\fB \-I
+.B \-\-inspect\fP,\fB \-I
Display detailed information by loading the
font and analyzing the font table; very slow!
For the meaning of the returned fields see
@@ -230,7 +230,7 @@ The default is plainname,version*.
.SS font and lookup caches
.INDENT 0.0
.TP
-.B \-\-flush\-lookups
+.B \-\-flush\-lookups
Clear font name lookup cache (experimental).
.TP
.BI \-\-cache\fB= DIRECTIVE
@@ -249,15 +249,15 @@ cache;
.SS debugging methods
.INDENT 0.0
.TP
-.B \-\-show\-blacklist\fP,\fB \-b
+.B \-\-show\-blacklist\fP,\fB \-b
Show blacklisted files (not directories).
.TP
-.B \-\-dry\-run\fP,\fB \-D
+.B \-\-dry\-run\fP,\fB \-D
Don’t load fonts when updating the database;
scan directories only.
(For debugging file system related issues.)
.TP
-.B \-\-no\-strip
+.B \-\-no\-strip
Do not strip redundant information after
building the database. Warning: this will
inflate the index to about two to three times
@@ -331,7 +331,7 @@ state.
Set verbosity level to \fIn\fP or the number of
repetitions of \fB\-v\fP\&.
.TP
-.B \-\-quiet
+.B \-\-quiet
No verbose output (log level set to zero).
.TP
.BI \-\-log\fB= CHANNEL
@@ -347,11 +347,11 @@ directory (the name will be chosen
automatically.
.UNINDENT
.TP
-.B \-\-version\fP,\fB \-V
+.B \-\-version\fP,\fB \-V
Show version numbers of components as well as
some basic information and exit.
.TP
-.B \-\-help\fP,\fB \-h
+.B \-\-help\fP,\fB \-h
Show help message and exit.
.TP
.BI \-\-diagnose\fB= CHECK
@@ -387,12 +387,12 @@ Read the configuration from \fIFILE\fP\&. See
\fBluaotfload.conf\fP(%) for documentation
concerning the format and available options.
.TP
-.B \-\-dumpconf
+.B \-\-dumpconf
Print the currently active configuration; the
output can be saved to a file and used for
bootstrapping a custom configuration files.
.TP
-.B \-\-aliases
+.B \-\-aliases
Dump the font name database as a kpathsea
aliases file. This option is experimental and
might go away.
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.lua b/macros/luatex/generic/luaotfload/luaotfload-tool.lua
index 45517448e7..fb676f7d59 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-tool.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-tool.lua
@@ -9,7 +9,7 @@
local ProvidesLuaModule = {
name = "luaotfload-tool",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload-tool / database functionality",
license = "GPL v2.0"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.pdf b/macros/luatex/generic/luaotfload/luaotfload-tool.pdf
index b87a1914e0..27abd95740 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-tool.pdf
+++ b/macros/luatex/generic/luaotfload/luaotfload-tool.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.rst b/macros/luatex/generic/luaotfload/luaotfload-tool.rst
index 778bbf5f1b..acbbaf2704 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-tool.rst
+++ b/macros/luatex/generic/luaotfload/luaotfload-tool.rst
@@ -8,7 +8,7 @@
:Date: 2024-02-14
:Copyright: GPL v2.0
-:Version: 3.27
+:Version: 3.28
:Manual section: 1
:Manual group: text processing
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua b/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua
index c0d7046689..da89ee9769 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua
@@ -5,7 +5,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-tounicode",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / tounicode",
license = "GPL v2.0",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-unicode.lua b/macros/luatex/generic/luaotfload/luaotfload-unicode.lua
index b83ac25461..afeb4293fe 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-unicode.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-unicode.lua
@@ -5,7 +5,7 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-unicode",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "luaotfload submodule / Unicode helpers",
license = "CC0 1.0 Universal",
diff --git a/macros/luatex/generic/luaotfload/luaotfload.conf.5 b/macros/luatex/generic/luaotfload/luaotfload.conf.5
index 3ebd68b72a..27473f7d1e 100644
--- a/macros/luatex/generic/luaotfload/luaotfload.conf.5
+++ b/macros/luatex/generic/luaotfload/luaotfload.conf.5
@@ -1,8 +1,5 @@
.\" Man page generated from reStructuredText.
.
-.TH LUAOTFLOAD.CONF 5 "2024-02-14" "3.27" "text processing"
-.SH NAME
-luaotfload.conf \- Luaotfload configuration file
.
.nr rst2man-indent-level 0
.
@@ -30,6 +27,9 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
+.TH "LUAOTFLOAD.CONF" 5 "2024-02-14" "3.28" "text processing"
+.SH NAME
+luaotfload.conf \- Luaotfload configuration file
.SH SYNOPSIS
.INDENT 0.0
.IP \(bu 2
diff --git a/macros/luatex/generic/luaotfload/luaotfload.conf.rst b/macros/luatex/generic/luaotfload/luaotfload.conf.rst
index f9e48cb7a2..4aef3b1595 100644
--- a/macros/luatex/generic/luaotfload/luaotfload.conf.rst
+++ b/macros/luatex/generic/luaotfload/luaotfload.conf.rst
@@ -8,7 +8,7 @@
:Date: 2024-02-14
:Copyright: GPL v2.0
-:Version: 3.27
+:Version: 3.28
:Manual section: 5
:Manual group: text processing
diff --git a/macros/luatex/generic/luaotfload/luaotfload.lua b/macros/luatex/generic/luaotfload/luaotfload.lua
index 893309f9db..97c6d2ed75 100644
--- a/macros/luatex/generic/luaotfload/luaotfload.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload.lua
@@ -20,7 +20,7 @@ local authors = "\z
-- version number is used below!
local ProvidesLuaModule = {
name = "luaotfload",
- version = "3.27", --TAGVERSION
+ version = "3.28", --TAGVERSION
date = "2024-02-14", --TAGDATE
description = "Lua based OpenType font support",
author = authors,
diff --git a/macros/luatex/generic/luaotfload/luaotfload.sty b/macros/luatex/generic/luaotfload/luaotfload.sty
index 262834e95c..de64836531 100644
--- a/macros/luatex/generic/luaotfload/luaotfload.sty
+++ b/macros/luatex/generic/luaotfload/luaotfload.sty
@@ -39,7 +39,7 @@
\fi
\ifdefined\ProvidesPackage
\ProvidesPackage{luaotfload}%
- [2024/02/14 v3.27 OpenType layout system]
+ [2024/02/14 v3.28 OpenType layout system]
\fi
\directlua{
if xpcall(function ()%
diff --git a/macros/luatex/generic/luaotfload/scripts-demo.pdf b/macros/luatex/generic/luaotfload/scripts-demo.pdf
index 0049165b55..267ae6373f 100644
--- a/macros/luatex/generic/luaotfload/scripts-demo.pdf
+++ b/macros/luatex/generic/luaotfload/scripts-demo.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf b/macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf
index d46132c76e..cd6bc398ca 100644
--- a/macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf
+++ b/macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/shaper-demo.pdf b/macros/luatex/generic/luaotfload/shaper-demo.pdf
index 3ad7f54fa1..444a29224d 100644
--- a/macros/luatex/generic/luaotfload/shaper-demo.pdf
+++ b/macros/luatex/generic/luaotfload/shaper-demo.pdf
Binary files differ