From bb669917488dc9c559ccaac25bb66a30e133707b Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Thu, 18 Feb 2021 22:17:56 +0000 Subject: l3 (18feb21) git-svn-id: svn://tug.org/texlive/trunk@57789 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/l3backend/CHANGELOG.md | 11 +- Master/texmf-dist/doc/latex/l3backend/README.md | 2 +- .../doc/latex/l3backend/l3backend-code.pdf | Bin 805972 -> 805668 bytes .../doc/latex/l3experimental/CHANGELOG.md | 9 +- .../texmf-dist/doc/latex/l3experimental/README.md | 14 +- .../l3experimental/l3benchmark/l3benchmark.pdf | Bin 314447 -> 314359 bytes .../doc/latex/l3experimental/l3bitset/l3bitset.pdf | Bin 382530 -> 382437 bytes .../doc/latex/l3experimental/l3color/l3color.pdf | Bin 369039 -> 0 bytes .../latex/l3experimental/l3draw/l3draw-code.pdf | Bin 606904 -> 607244 bytes .../doc/latex/l3experimental/l3draw/l3draw.pdf | Bin 490075 -> 489992 bytes .../latex/l3experimental/l3graphics/l3graphics.pdf | Bin 363302 -> 363213 bytes .../doc/latex/l3experimental/l3pdf/l3pdf-code.pdf | Bin 279001 -> 0 bytes .../doc/latex/l3experimental/l3pdf/l3pdf-code.tex | 56 - .../doc/latex/l3experimental/l3pdf/l3pdf.pdf | Bin 377364 -> 0 bytes .../latex/l3experimental/l3str/l3str-format.pdf | Bin 345158 -> 345067 bytes .../l3experimental/l3sys-shell/l3sys-shell.pdf | Bin 311867 -> 311776 bytes .../doc/latex/l3experimental/xcoffins/xcoffins.pdf | Bin 373136 -> 373064 bytes .../doc/latex/l3experimental/xgalley/l3galley.pdf | Bin 386004 -> 385907 bytes .../doc/latex/l3experimental/xgalley/xgalley.pdf | Bin 285978 -> 285883 bytes Master/texmf-dist/doc/latex/l3kernel/CHANGELOG.md | 52 +- Master/texmf-dist/doc/latex/l3kernel/README.md | 2 +- Master/texmf-dist/doc/latex/l3kernel/expl3.pdf | Bin 590739 -> 590636 bytes .../texmf-dist/doc/latex/l3kernel/interface3.pdf | Bin 1575865 -> 1608206 bytes .../texmf-dist/doc/latex/l3kernel/interface3.tex | 4 +- .../texmf-dist/doc/latex/l3kernel/l3docstrip.pdf | Bin 263501 -> 263408 bytes Master/texmf-dist/doc/latex/l3kernel/l3news.pdf | Bin 380237 -> 380237 bytes Master/texmf-dist/doc/latex/l3kernel/l3news01.pdf | Bin 113669 -> 113669 bytes Master/texmf-dist/doc/latex/l3kernel/l3news02.pdf | Bin 140944 -> 140944 bytes Master/texmf-dist/doc/latex/l3kernel/l3news03.pdf | Bin 138141 -> 138141 bytes Master/texmf-dist/doc/latex/l3kernel/l3news04.pdf | Bin 107188 -> 107188 bytes Master/texmf-dist/doc/latex/l3kernel/l3news05.pdf | Bin 105169 -> 105169 bytes Master/texmf-dist/doc/latex/l3kernel/l3news06.pdf | Bin 140971 -> 140971 bytes Master/texmf-dist/doc/latex/l3kernel/l3news07.pdf | Bin 119190 -> 119190 bytes Master/texmf-dist/doc/latex/l3kernel/l3news08.pdf | Bin 152604 -> 152604 bytes Master/texmf-dist/doc/latex/l3kernel/l3news09.pdf | Bin 236052 -> 236052 bytes Master/texmf-dist/doc/latex/l3kernel/l3news10.pdf | Bin 140521 -> 140521 bytes Master/texmf-dist/doc/latex/l3kernel/l3news11.pdf | Bin 159391 -> 159391 bytes Master/texmf-dist/doc/latex/l3kernel/l3news12.pdf | Bin 192710 -> 192710 bytes .../texmf-dist/doc/latex/l3kernel/l3prefixes.csv | 1 + .../texmf-dist/doc/latex/l3kernel/l3prefixes.pdf | Bin 75619 -> 75605 bytes .../texmf-dist/doc/latex/l3kernel/l3styleguide.pdf | Bin 280295 -> 280201 bytes .../texmf-dist/doc/latex/l3kernel/l3styleguide.tex | 2 +- .../doc/latex/l3kernel/l3syntax-changes.pdf | Bin 228483 -> 228390 bytes .../doc/latex/l3kernel/l3syntax-changes.tex | 2 +- .../doc/latex/l3kernel/l3term-glossary.pdf | Bin 217942 -> 217846 bytes .../doc/latex/l3kernel/l3term-glossary.tex | 2 +- Master/texmf-dist/doc/latex/l3kernel/source3.pdf | Bin 5998896 -> 6160884 bytes Master/texmf-dist/doc/latex/l3kernel/source3.tex | 2 +- .../texmf-dist/doc/latex/l3kernel/source3body.tex | 163 +- .../source/latex/l3backend/l3backend-basics.dtx | 14 +- .../source/latex/l3backend/l3backend-box.dtx | 2 +- .../source/latex/l3backend/l3backend-color.dtx | 72 +- .../source/latex/l3backend/l3backend-draw.dtx | 2 +- .../source/latex/l3backend/l3backend-graphics.dtx | 2 +- .../source/latex/l3backend/l3backend-header.dtx | 2 +- .../source/latex/l3backend/l3backend-opacity.dtx | 8 +- .../source/latex/l3backend/l3backend-pdf.dtx | 2 +- .../l3experimental/l3benchmark/l3benchmark.dtx | 4 +- .../latex/l3experimental/l3bitset/l3bitset.dtx | 4 +- .../latex/l3experimental/l3color/l3color.dtx | 2553 ------------------- .../latex/l3experimental/l3color/l3color.ins | 58 - .../latex/l3experimental/l3draw/l3draw-boxes.dtx | 2 +- .../latex/l3experimental/l3draw/l3draw-layers.dtx | 2 +- .../latex/l3experimental/l3draw/l3draw-paths.dtx | 2 +- .../latex/l3experimental/l3draw/l3draw-points.dtx | 2 +- .../latex/l3experimental/l3draw/l3draw-scopes.dtx | 2 +- .../l3experimental/l3draw/l3draw-softpath.dtx | 2 +- .../latex/l3experimental/l3draw/l3draw-state.dtx | 2 +- .../l3experimental/l3draw/l3draw-transforms.dtx | 2 +- .../source/latex/l3experimental/l3draw/l3draw.dtx | 18 +- .../latex/l3experimental/l3graphics/l3graphics.dtx | 4 +- .../source/latex/l3experimental/l3pdf/l3pdf.dtx | 442 ---- .../source/latex/l3experimental/l3pdf/l3pdf.ins | 60 - .../latex/l3experimental/l3str/l3str-format.dtx | 4 +- .../l3experimental/l3sys-shell/l3sys-shell.dtx | 4 +- .../latex/l3experimental/xcoffins/xcoffins.dtx | 4 +- .../latex/l3experimental/xgalley/l3galley.dtx | 4 +- .../latex/l3experimental/xgalley/xgalley.dtx | 4 +- Master/texmf-dist/source/latex/l3kernel/expl3.dtx | 4 +- Master/texmf-dist/source/latex/l3kernel/l3.ins | 3 +- .../texmf-dist/source/latex/l3kernel/l3basics.dtx | 2 +- .../source/latex/l3kernel/l3bootstrap.dtx | 2 +- Master/texmf-dist/source/latex/l3kernel/l3box.dtx | 2 +- .../source/latex/l3kernel/l3candidates.dtx | 32 +- .../texmf-dist/source/latex/l3kernel/l3cctab.dtx | 2 +- .../texmf-dist/source/latex/l3kernel/l3clist.dtx | 2 +- .../texmf-dist/source/latex/l3kernel/l3coffins.dtx | 38 +- .../source/latex/l3kernel/l3color-base.dtx | 183 -- .../texmf-dist/source/latex/l3kernel/l3color.dtx | 2655 ++++++++++++++++++++ .../texmf-dist/source/latex/l3kernel/l3debug.dtx | 2 +- .../source/latex/l3kernel/l3deprecation.dtx | 2 +- Master/texmf-dist/source/latex/l3kernel/l3doc.dtx | 2 +- .../source/latex/l3kernel/l3docstrip.dtx | 2 +- .../texmf-dist/source/latex/l3kernel/l3expan.dtx | 2 +- Master/texmf-dist/source/latex/l3kernel/l3file.dtx | 2 +- Master/texmf-dist/source/latex/l3kernel/l3flag.dtx | 2 +- .../source/latex/l3kernel/l3fp-assign.dtx | 2 +- .../texmf-dist/source/latex/l3kernel/l3fp-aux.dtx | 2 +- .../source/latex/l3kernel/l3fp-basics.dtx | 2 +- .../source/latex/l3kernel/l3fp-convert.dtx | 2 +- .../texmf-dist/source/latex/l3kernel/l3fp-expo.dtx | 2 +- .../source/latex/l3kernel/l3fp-extended.dtx | 2 +- .../source/latex/l3kernel/l3fp-logic.dtx | 2 +- .../source/latex/l3kernel/l3fp-parse.dtx | 2 +- .../source/latex/l3kernel/l3fp-random.dtx | 2 +- .../source/latex/l3kernel/l3fp-round.dtx | 2 +- .../source/latex/l3kernel/l3fp-traps.dtx | 2 +- .../texmf-dist/source/latex/l3kernel/l3fp-trig.dtx | 2 +- Master/texmf-dist/source/latex/l3kernel/l3fp.dtx | 2 +- .../texmf-dist/source/latex/l3kernel/l3fparray.dtx | 2 +- Master/texmf-dist/source/latex/l3kernel/l3int.dtx | 2 +- .../source/latex/l3kernel/l3intarray.dtx | 2 +- .../source/latex/l3kernel/l3kernel-functions.dtx | 2 +- Master/texmf-dist/source/latex/l3kernel/l3keys.dtx | 2 +- .../texmf-dist/source/latex/l3kernel/l3legacy.dtx | 2 +- .../texmf-dist/source/latex/l3kernel/l3luatex.dtx | 2 +- Master/texmf-dist/source/latex/l3kernel/l3msg.dtx | 30 +- .../texmf-dist/source/latex/l3kernel/l3names.dtx | 2 +- Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx | 458 ++++ Master/texmf-dist/source/latex/l3kernel/l3prg.dtx | 2 +- Master/texmf-dist/source/latex/l3kernel/l3prop.dtx | 2 +- .../texmf-dist/source/latex/l3kernel/l3quark.dtx | 2 +- .../texmf-dist/source/latex/l3kernel/l3regex.dtx | 9 +- Master/texmf-dist/source/latex/l3kernel/l3seq.dtx | 2 +- Master/texmf-dist/source/latex/l3kernel/l3skip.dtx | 2 +- Master/texmf-dist/source/latex/l3kernel/l3sort.dtx | 2 +- .../source/latex/l3kernel/l3str-convert.dtx | 15 +- Master/texmf-dist/source/latex/l3kernel/l3str.dtx | 2 +- Master/texmf-dist/source/latex/l3kernel/l3sys.dtx | 2 +- .../source/latex/l3kernel/l3text-case.dtx | 2 +- .../source/latex/l3kernel/l3text-purify.dtx | 2 +- Master/texmf-dist/source/latex/l3kernel/l3text.dtx | 4 +- .../source/latex/l3kernel/l3tl-analysis.dtx | 2 +- Master/texmf-dist/source/latex/l3kernel/l3tl.dtx | 2 +- .../texmf-dist/source/latex/l3kernel/l3token.dtx | 2 +- .../texmf-dist/source/latex/l3kernel/l3unicode.dtx | 2 +- .../tex/latex/l3backend/l3backend-dvipdfmx.def | 64 +- .../tex/latex/l3backend/l3backend-dvips.def | 2 +- .../tex/latex/l3backend/l3backend-dvisvgm.def | 2 +- .../tex/latex/l3backend/l3backend-luatex.def | 64 +- .../tex/latex/l3backend/l3backend-pdftex.def | 64 +- .../tex/latex/l3backend/l3backend-xetex.def | 64 +- .../l3experimental/l3benchmark/l3benchmark.sty | 2 +- .../tex/latex/l3experimental/l3bitset/l3bitset.sty | 2 +- .../tex/latex/l3experimental/l3color/l3color.sty | 1448 ----------- .../tex/latex/l3experimental/l3draw/l3draw.sty | 3 +- .../latex/l3experimental/l3graphics/l3graphics.sty | 2 +- .../tex/latex/l3experimental/l3pdf/l3pdf.sty | 118 - .../latex/l3experimental/l3str/l3str-format.sty | 2 +- .../l3experimental/l3sys-shell/l3sys-shell.sty | 2 +- .../tex/latex/l3experimental/xcoffins/xcoffins.sty | 2 +- .../tex/latex/l3experimental/xgalley/l3galley.sty | 2 +- .../tex/latex/l3experimental/xgalley/xgalley.sty | 2 +- .../texmf-dist/tex/latex/l3kernel/expl3-code.tex | 1874 ++++++++++++-- .../tex/latex/l3kernel/expl3-generic.tex | 2 +- Master/texmf-dist/tex/latex/l3kernel/expl3.ltx | 2 +- Master/texmf-dist/tex/latex/l3kernel/expl3.sty | 2 +- 157 files changed, 5336 insertions(+), 5519 deletions(-) delete mode 100644 Master/texmf-dist/doc/latex/l3experimental/l3color/l3color.pdf delete mode 100644 Master/texmf-dist/doc/latex/l3experimental/l3pdf/l3pdf-code.pdf delete mode 100644 Master/texmf-dist/doc/latex/l3experimental/l3pdf/l3pdf-code.tex delete mode 100644 Master/texmf-dist/doc/latex/l3experimental/l3pdf/l3pdf.pdf delete mode 100644 Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx delete mode 100644 Master/texmf-dist/source/latex/l3experimental/l3color/l3color.ins delete mode 100644 Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.dtx delete mode 100644 Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.ins delete mode 100644 Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx create mode 100644 Master/texmf-dist/source/latex/l3kernel/l3color.dtx create mode 100644 Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx delete mode 100644 Master/texmf-dist/tex/latex/l3experimental/l3color/l3color.sty delete mode 100644 Master/texmf-dist/tex/latex/l3experimental/l3pdf/l3pdf.sty (limited to 'Master') diff --git a/Master/texmf-dist/doc/latex/l3backend/CHANGELOG.md b/Master/texmf-dist/doc/latex/l3backend/CHANGELOG.md index b04d1fd1959..f787acd709c 100644 --- a/Master/texmf-dist/doc/latex/l3backend/CHANGELOG.md +++ b/Master/texmf-dist/doc/latex/l3backend/CHANGELOG.md @@ -6,6 +6,14 @@ this project uses date-based 'snapshot' version identifiers. ## [Unreleased] +## [2021-02-18] + +### Changed +- Update tracking of PDF management functions + +### Fixed +- Opacity support for pdfTeX/LuaTeX + ## [2021-02-06] ### Changed @@ -151,7 +159,8 @@ this project uses date-based 'snapshot' version identifiers. - Include `l3backend` in file names - Moved backend code to internal for each 'parent' module -[Unreleased]: https://github.com/latex3/latex3/compare/2021-02-06...HEAD +[Unreleased]: https://github.com/latex3/latex3/compare/2021-02-18...HEAD +[2021-02-18]: https://github.com/latex3/latex3/compare/2021-02-06...2021-02-18 [2021-02-06]: https://github.com/latex3/latex3/compare/2021-01-29...2021-02-06 [2021-01-29]: https://github.com/latex3/latex3/compare/2021-01-09...2021-01-29 [2021-01-09]: https://github.com/latex3/latex3/compare/2020-09-24...2021-01-09 diff --git a/Master/texmf-dist/doc/latex/l3backend/README.md b/Master/texmf-dist/doc/latex/l3backend/README.md index 07d6aadd6a0..02118d1218b 100644 --- a/Master/texmf-dist/doc/latex/l3backend/README.md +++ b/Master/texmf-dist/doc/latex/l3backend/README.md @@ -1,7 +1,7 @@ LaTeX3 Backend Drivers ====================== -Release 2021-02-06 +Release 2021-02-18 This package forms parts of `expl3`, and contains the code used to interface with backends (drivers) across the `expl3` codebase. The functions here are diff --git a/Master/texmf-dist/doc/latex/l3backend/l3backend-code.pdf b/Master/texmf-dist/doc/latex/l3backend/l3backend-code.pdf index c6f39549e56..a70f304b62f 100644 Binary files a/Master/texmf-dist/doc/latex/l3backend/l3backend-code.pdf and b/Master/texmf-dist/doc/latex/l3backend/l3backend-code.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3experimental/CHANGELOG.md b/Master/texmf-dist/doc/latex/l3experimental/CHANGELOG.md index 5c3d6b7d4a3..2180a6864bf 100644 --- a/Master/texmf-dist/doc/latex/l3experimental/CHANGELOG.md +++ b/Master/texmf-dist/doc/latex/l3experimental/CHANGELOG.md @@ -7,6 +7,12 @@ this project uses date-based 'snapshot' version identifiers. ## [Unreleased] +## [2021-02-18] + +### Removed +- `l3color`: moved to `l3kernel` +- `l3pdf`: moved to `l3kernel` + ## [2021-02-06] ### Changed @@ -195,7 +201,8 @@ this project uses date-based 'snapshot' version identifiers. - New `l3color` module using `xcolor`-like expression syntax - New `l3draw` module, based on `pgf` layer of the TikZ system -[Unreleased]: https://github.com/latex3/latex3/compare/2021-02-06...HEAD +[Unreleased]: https://github.com/latex3/latex3/compare/2021-02-18...HEAD +[2021-02-18]: https://github.com/latex3/latex3/compare/2021-02-06...2021-02-18 [2021-02-06]: https://github.com/latex3/latex3/compare/2021-01-29...2021-02-06 [2021-01-29]: https://github.com/latex3/latex3/compare/2021-10-27...2021-01-29 [2020-10-27]: https://github.com/latex3/latex3/compare/2020-09-24...2020-10-27 diff --git a/Master/texmf-dist/doc/latex/l3experimental/README.md b/Master/texmf-dist/doc/latex/l3experimental/README.md index 417d53493ec..110132faf0e 100644 --- a/Master/texmf-dist/doc/latex/l3experimental/README.md +++ b/Master/texmf-dist/doc/latex/l3experimental/README.md @@ -1,7 +1,7 @@ Experimental LaTeX3 Concepts ============================ -Release 2021-02-06 +Release 2021-02-18 Overview -------- @@ -22,7 +22,6 @@ updated at the same time. Currently included in the CTAN release of l3experimental are the following bundles: * `l3benchmark` -* `l3color` * `l3draw` * `l3graphics` * `l3pdf` @@ -36,15 +35,6 @@ bundles: This module provides support for benchmarking the performance of code. - -`l3color` ---------- - -This module provides support for setting colors using a range of color models. -It also allows the construction of 'color expressions', in which multiple colors -are mixed together at the macro level. There is also support for spot colors: -the latter is highly experimental. - `l3draw` -------- @@ -127,7 +117,7 @@ The LaTeX Project ------------------ Development of LaTeX3 is carried out by -[The LaTeX Project](https://www.latex-project.org/latex3/). +[The LaTeX Project](https://www.latex-project.org/latex3/). The development team can be contacted by e-mail: ; for general LaTeX3 discussion diff --git a/Master/texmf-dist/doc/latex/l3experimental/l3benchmark/l3benchmark.pdf b/Master/texmf-dist/doc/latex/l3experimental/l3benchmark/l3benchmark.pdf index a7881986748..ee7144dba86 100644 Binary files a/Master/texmf-dist/doc/latex/l3experimental/l3benchmark/l3benchmark.pdf and b/Master/texmf-dist/doc/latex/l3experimental/l3benchmark/l3benchmark.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3experimental/l3bitset/l3bitset.pdf b/Master/texmf-dist/doc/latex/l3experimental/l3bitset/l3bitset.pdf index 68490cb185a..2c9b2877c25 100644 Binary files a/Master/texmf-dist/doc/latex/l3experimental/l3bitset/l3bitset.pdf and b/Master/texmf-dist/doc/latex/l3experimental/l3bitset/l3bitset.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3experimental/l3color/l3color.pdf b/Master/texmf-dist/doc/latex/l3experimental/l3color/l3color.pdf deleted file mode 100644 index aacda29a30b..00000000000 Binary files a/Master/texmf-dist/doc/latex/l3experimental/l3color/l3color.pdf and /dev/null differ diff --git a/Master/texmf-dist/doc/latex/l3experimental/l3draw/l3draw-code.pdf b/Master/texmf-dist/doc/latex/l3experimental/l3draw/l3draw-code.pdf index c52386b2b10..38889a0dc3b 100644 Binary files a/Master/texmf-dist/doc/latex/l3experimental/l3draw/l3draw-code.pdf and b/Master/texmf-dist/doc/latex/l3experimental/l3draw/l3draw-code.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3experimental/l3draw/l3draw.pdf b/Master/texmf-dist/doc/latex/l3experimental/l3draw/l3draw.pdf index c93d56a3e66..d0eb4918824 100644 Binary files a/Master/texmf-dist/doc/latex/l3experimental/l3draw/l3draw.pdf and b/Master/texmf-dist/doc/latex/l3experimental/l3draw/l3draw.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3experimental/l3graphics/l3graphics.pdf b/Master/texmf-dist/doc/latex/l3experimental/l3graphics/l3graphics.pdf index 835fc347628..2ae274ac53f 100644 Binary files a/Master/texmf-dist/doc/latex/l3experimental/l3graphics/l3graphics.pdf and b/Master/texmf-dist/doc/latex/l3experimental/l3graphics/l3graphics.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3experimental/l3pdf/l3pdf-code.pdf b/Master/texmf-dist/doc/latex/l3experimental/l3pdf/l3pdf-code.pdf deleted file mode 100644 index cc3e9f9c5e9..00000000000 Binary files a/Master/texmf-dist/doc/latex/l3experimental/l3pdf/l3pdf-code.pdf and /dev/null differ diff --git a/Master/texmf-dist/doc/latex/l3experimental/l3pdf/l3pdf-code.tex b/Master/texmf-dist/doc/latex/l3experimental/l3pdf/l3pdf-code.tex deleted file mode 100644 index db2a7d5bf09..00000000000 --- a/Master/texmf-dist/doc/latex/l3experimental/l3pdf/l3pdf-code.tex +++ /dev/null @@ -1,56 +0,0 @@ -\iffalse meta-comment - -File: l3pdf-code.tex - -Copyright (C) 2019,2021 The LaTeX Project - -It may be distributed and/or modified under the conditions of the -LaTeX Project Public License (LPPL), either version 1.3c of this -license or (at your option) any later version. The latest version -of this license is in the file - - https://www.latex-project.org/lppl.txt - -This file is part of the "l3experimental bundle" (The Work in LPPL) -and all files in that bundle must be distributed together. - -The released version of this bundle is available from CTAN. - ------------------------------------------------------------------------ - -The development version of the bundle can be found at - - https://github.com/latex3/latex3 - -for those people who are interested. - -\fi - -\documentclass{l3doc} - -\begin{document} - -\makeatletter -\let\DelayPrintIndex\PrintIndex -\let\PrintIndex\@empty -\makeatother - -\ExplSyntaxOn -\clist_gput_right:Nn \g_docinput_clist - { - l3pdf.dtx , - } -\ExplSyntaxOff - -\part{Implementation} - -\def\maketitle{} -\EnableImplementation -\DisableDocumentation -\DocInputAgain - -\clearpage - -\DelayPrintIndex - -\end{document} diff --git a/Master/texmf-dist/doc/latex/l3experimental/l3pdf/l3pdf.pdf b/Master/texmf-dist/doc/latex/l3experimental/l3pdf/l3pdf.pdf deleted file mode 100644 index 38b9038f824..00000000000 Binary files a/Master/texmf-dist/doc/latex/l3experimental/l3pdf/l3pdf.pdf and /dev/null differ diff --git a/Master/texmf-dist/doc/latex/l3experimental/l3str/l3str-format.pdf b/Master/texmf-dist/doc/latex/l3experimental/l3str/l3str-format.pdf index df1b4600dc9..b0b07a632e7 100644 Binary files a/Master/texmf-dist/doc/latex/l3experimental/l3str/l3str-format.pdf and b/Master/texmf-dist/doc/latex/l3experimental/l3str/l3str-format.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3experimental/l3sys-shell/l3sys-shell.pdf b/Master/texmf-dist/doc/latex/l3experimental/l3sys-shell/l3sys-shell.pdf index a2de0baee3c..44d84d1d9bb 100644 Binary files a/Master/texmf-dist/doc/latex/l3experimental/l3sys-shell/l3sys-shell.pdf and b/Master/texmf-dist/doc/latex/l3experimental/l3sys-shell/l3sys-shell.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3experimental/xcoffins/xcoffins.pdf b/Master/texmf-dist/doc/latex/l3experimental/xcoffins/xcoffins.pdf index 6c76fdd7b29..cb1e4bd9ad4 100644 Binary files a/Master/texmf-dist/doc/latex/l3experimental/xcoffins/xcoffins.pdf and b/Master/texmf-dist/doc/latex/l3experimental/xcoffins/xcoffins.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3experimental/xgalley/l3galley.pdf b/Master/texmf-dist/doc/latex/l3experimental/xgalley/l3galley.pdf index 4e836f86ad8..743d8ac6f2d 100644 Binary files a/Master/texmf-dist/doc/latex/l3experimental/xgalley/l3galley.pdf and b/Master/texmf-dist/doc/latex/l3experimental/xgalley/l3galley.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3experimental/xgalley/xgalley.pdf b/Master/texmf-dist/doc/latex/l3experimental/xgalley/xgalley.pdf index 3d8a23cec11..b882769cf5f 100644 Binary files a/Master/texmf-dist/doc/latex/l3experimental/xgalley/xgalley.pdf and b/Master/texmf-dist/doc/latex/l3experimental/xgalley/xgalley.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/CHANGELOG.md b/Master/texmf-dist/doc/latex/l3kernel/CHANGELOG.md index 2f39d7d20d8..9663dc05512 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/CHANGELOG.md +++ b/Master/texmf-dist/doc/latex/l3kernel/CHANGELOG.md @@ -7,6 +7,17 @@ this project uses date-based 'snapshot' version identifiers. ## [Unreleased] +## [2021-02-18] + +### Added +- `l3color`: Moved from `l3experimental` +- `l3pdf`: Moved from `l3experimental` +- `default` alias to str_convert + +### Changed +- Re-ordered `interface3` documentation +- Moved `msg_show:nn(nnnn)` to stable + ## [2021-02-06] ### Changed @@ -755,35 +766,35 @@ this project uses date-based 'snapshot' version identifiers. ## [2018-05-13] ### Fixed -- Cor­rect date string in `ex­pl3.dtx` -- Cor­rect `\c_sys_en­gine_ver­sion_str` when using XeTeX +- Correct date string in `expl3.dtx` +- Correct `\c_sys_engine_version_str` when using XeTeX ## [2018-05-12] ### Added - Define `\c_zero_int` and `\c_one_int` -- Im­ple­ment `\c_sys_en­gine_ver­sion_str` -- Im­ple­ment `\seq_in­dexed_map_func­tion/in­line` -- Im­ple­ment `\in­tar­ray_gzero:N` -- Im­ple­ment `\in­tar­ray_const_from_clist:Nn` -- Im­ple­ment `\bool_set_in­verse:N` -- Im­ple­ment `\bool_xor:nnTF` in­stead of just `\bool_xor_p:nn` -- Im­ple­ment can­di­date `\int_rand:n` -- Im­ple­ment `\in­tar­ray_gset_rand:Nnn` -- Im­ple­ment can­di­date `l3f­par­ray` mod­ule +- Implement `\c_sys_engine_version_str` +- Implement `\seq_indexed_map_function/inline` +- Implement `\intarray_gzero:N` +- Implement `\intarray_const_from_clist:Nn` +- Implement `\bool_set_inverse:N` +- Implement `\bool_xor:nnTF` instead of just `\bool_xor_p:nn` +- Implement candidate `\int_rand:n` +- Implement `\intarray_gset_rand:Nnn` +- Implement candidate `l3fparray` module ## Changed -- Up­date min­i­mal re­quired ver­sions of XeTeX and LuaTeX -- Dep­re­cate named in­te­ger con­stants `\c_zero`. etc. -- Move all prim­i­tives to `\tex_...:D names­pace`, - dep­re­cat­ing older en­gine-de­pen­dent pre­fixes +- Update minimal required versions of XeTeX and LuaTeX +- Deprecate named integer constants `\c_zero`. etc. +- Move all primitives to `\tex_...:D namespace`, + deprecating older engine-dependent prefixes - Several internal optimisations ### Fixed -- Ex­pand boolean ex­pres­sion be­fore call­ing `\chardef` (fixes #461) +- Expand boolean expression before calling `\chardef` (fixes #461) ### Removed -- Re­move un­doc­u­mented `\fp_func­tion:Nw` and `\fp_new_func­tion:Npn` +- Remove undocumented `\fp_function:Nw` and `\fp_new_function:Npn` ## [2018-04-30] @@ -833,10 +844,11 @@ this project uses date-based 'snapshot' version identifiers. ### Added - Tuple support in fp expressions -- Step func­tions have been added for dim vari­ables, - e.g. `\dim_step_in­line:nnnn` +- Step functions have been added for dim variables, + e.g. `\dim_step_inline:nnnn` -[Unreleased]: https://github.com/latex3/latex3/compare/2021-02-06...HEAD +[Unreleased]: https://github.com/latex3/latex3/compare/2021-02-18...HEAD +[2021-02-18]: https://github.com/latex3/latex3/compare/2021-02-06...2021-02-18 [2021-02-06]: https://github.com/latex3/latex3/compare/2021-02-02...2021-02-06 [2021-02-02]: https://github.com/latex3/latex3/compare/2021-01-09...2021-02-02 [2021-01-09]: https://github.com/latex3/latex3/compare/2020-12-07...2021-01-09 diff --git a/Master/texmf-dist/doc/latex/l3kernel/README.md b/Master/texmf-dist/doc/latex/l3kernel/README.md index 5e747122628..42b975abcc1 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/README.md +++ b/Master/texmf-dist/doc/latex/l3kernel/README.md @@ -1,7 +1,7 @@ LaTeX3 Programming Conventions ============================== -Release 2021-02-06 +Release 2021-02-18 Overview -------- diff --git a/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf b/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf index cf1c397ce16..14921ac34fb 100644 Binary files a/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf and b/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/interface3.pdf b/Master/texmf-dist/doc/latex/l3kernel/interface3.pdf index 62ac1b4490d..f07ab43a0b6 100644 Binary files a/Master/texmf-dist/doc/latex/l3kernel/interface3.pdf and b/Master/texmf-dist/doc/latex/l3kernel/interface3.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/interface3.tex b/Master/texmf-dist/doc/latex/l3kernel/interface3.tex index 3243a6e00e7..10449fd4741 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/interface3.tex +++ b/Master/texmf-dist/doc/latex/l3kernel/interface3.tex @@ -1,6 +1,6 @@ \iffalse meta-comment -File: interfaces3.tex +File: interface3.tex Copyright (C) 1990-2011,2017-2021 The LaTeX Project @@ -54,7 +54,7 @@ for those people who are interested. {latex-team@latex-project.org}% }% } -\date{Released 2021-02-06} +\date{Released 2021-02-18} \pagenumbering{roman} \maketitle diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3docstrip.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3docstrip.pdf index 9ad75d5745a..887de467170 100644 Binary files a/Master/texmf-dist/doc/latex/l3kernel/l3docstrip.pdf and b/Master/texmf-dist/doc/latex/l3kernel/l3docstrip.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3news.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3news.pdf index dd8b0b931e6..8a9da281493 100644 Binary files a/Master/texmf-dist/doc/latex/l3kernel/l3news.pdf and b/Master/texmf-dist/doc/latex/l3kernel/l3news.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3news01.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3news01.pdf index f14be433278..aedb8f2b060 100644 Binary files a/Master/texmf-dist/doc/latex/l3kernel/l3news01.pdf and b/Master/texmf-dist/doc/latex/l3kernel/l3news01.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3news02.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3news02.pdf index e60449a7720..36d2b99d43d 100644 Binary files a/Master/texmf-dist/doc/latex/l3kernel/l3news02.pdf and b/Master/texmf-dist/doc/latex/l3kernel/l3news02.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3news03.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3news03.pdf index f4b9bbed9bb..ba772dcdc3f 100644 Binary files a/Master/texmf-dist/doc/latex/l3kernel/l3news03.pdf and b/Master/texmf-dist/doc/latex/l3kernel/l3news03.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3news04.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3news04.pdf index 3370183ddb7..3f4fd28f649 100644 Binary files a/Master/texmf-dist/doc/latex/l3kernel/l3news04.pdf and b/Master/texmf-dist/doc/latex/l3kernel/l3news04.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3news05.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3news05.pdf index 7ce5287d256..2dd69516d76 100644 Binary files a/Master/texmf-dist/doc/latex/l3kernel/l3news05.pdf and b/Master/texmf-dist/doc/latex/l3kernel/l3news05.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3news06.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3news06.pdf index f8947010588..d9b6818517f 100644 Binary files a/Master/texmf-dist/doc/latex/l3kernel/l3news06.pdf and b/Master/texmf-dist/doc/latex/l3kernel/l3news06.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3news07.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3news07.pdf index 4d31b834cec..49696d137c0 100644 Binary files a/Master/texmf-dist/doc/latex/l3kernel/l3news07.pdf and b/Master/texmf-dist/doc/latex/l3kernel/l3news07.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3news08.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3news08.pdf index 1bd8516026c..83680088d14 100644 Binary files a/Master/texmf-dist/doc/latex/l3kernel/l3news08.pdf and b/Master/texmf-dist/doc/latex/l3kernel/l3news08.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3news09.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3news09.pdf index 0e9df261fc6..8cb98e99b99 100644 Binary files a/Master/texmf-dist/doc/latex/l3kernel/l3news09.pdf and b/Master/texmf-dist/doc/latex/l3kernel/l3news09.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3news10.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3news10.pdf index dd97f75d0bb..532a383802d 100644 Binary files a/Master/texmf-dist/doc/latex/l3kernel/l3news10.pdf and b/Master/texmf-dist/doc/latex/l3kernel/l3news10.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3news11.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3news11.pdf index a0e9a272c66..3b74f69402a 100644 Binary files a/Master/texmf-dist/doc/latex/l3kernel/l3news11.pdf and b/Master/texmf-dist/doc/latex/l3kernel/l3news11.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3news12.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3news12.pdf index 13621d6f7ce..c6701103dc6 100644 Binary files a/Master/texmf-dist/doc/latex/l3kernel/l3news12.pdf and b/Master/texmf-dist/doc/latex/l3kernel/l3news12.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.csv b/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.csv index 4259c37c301..321f9c17999 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.csv +++ b/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.csv @@ -4,6 +4,7 @@ GS,gs1,Markus Kohm,,,,2013-03-16,2013-03-16, MOdiagram,modiagram,Clemens Niederberger,https://bitbucket.org/cgnieder/modiagram/,git@bitbucket.org:cgnieder/modiagram.git,https://bitbucket.org/cgnieder/modiagram/issues,2013-03-16,2013-03-16, UFca,citeall,Ulrike Fischer,,,,2015-04-09,2016-02-26, acro,acro,Clemens Niederberger,https://github.com/cgnieder/acro/,https://github.com/cgnieder/acro.git,https://github.com/cgnieder/acro/issues,2013-03-16,2020-04-14, +affiliations,langsci-affiliations,Felix Kopecky,https://ctan.org/pkg/langsci-affiliations,https://github.com/langsci/langsci-affiliations,https://github.com/langsci/langsci-affiliations/issues,2021-02-18,2021-02-18, akshar,akshar,Vu Van Dung,https://github.com/joulev/akshar,https://github.com/joulev/akshar.git,https://github.com/joulev/akshar/issues,2020-05-27,2020-05-27, algobox,algobox,Julien Rivaud,,,,2018-06-13,2018-06-13, alignment,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12, diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.pdf index ebb1745f91d..b9bea84aa7b 100644 Binary files a/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.pdf and b/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf index 484275928c9..0ad0ba30d62 100644 Binary files a/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf and b/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex b/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex index 645fe07fd97..c9a61be054f 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex +++ b/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex @@ -32,7 +32,7 @@ The released version of this bundle is available from CTAN. {latex-team@latex-project.org}% }% } -\date{Released 2021-02-06} +\date{Released 2021-02-18} \begin{document} diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf index 0a29f62dc56..f119e34fdb0 100644 Binary files a/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf and b/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex b/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex index 670bbd3e135..75bdfb87d29 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex +++ b/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex @@ -32,7 +32,7 @@ The released version of this bundle is available from CTAN. {latex-team@latex-project.org}% }% } -\date{Released 2021-02-06} +\date{Released 2021-02-18} \newcommand{\TF}{\textit{(TF)}} diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.pdf index 26c76842fd5..7aa607d2bb7 100644 Binary files a/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.pdf and b/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.tex b/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.tex index 97580c6b7c0..23b05b09fdf 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.tex +++ b/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.tex @@ -32,7 +32,7 @@ The released version of this bundle is available from CTAN. {latex-team@latex-project.org}% }% } -\date{Released 2021-02-06} +\date{Released 2021-02-18} \newcommand{\TF}{\textit{(TF)}} diff --git a/Master/texmf-dist/doc/latex/l3kernel/source3.pdf b/Master/texmf-dist/doc/latex/l3kernel/source3.pdf index 2c5c8920da9..8cfe3b177fa 100644 Binary files a/Master/texmf-dist/doc/latex/l3kernel/source3.pdf and b/Master/texmf-dist/doc/latex/l3kernel/source3.pdf differ diff --git a/Master/texmf-dist/doc/latex/l3kernel/source3.tex b/Master/texmf-dist/doc/latex/l3kernel/source3.tex index 60ca6166208..e3134302c78 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/source3.tex +++ b/Master/texmf-dist/doc/latex/l3kernel/source3.tex @@ -53,7 +53,7 @@ for those people who are interested. {latex-team@latex-project.org}% }% } -\date{Released 2021-02-06} +\date{Released 2021-02-18} \pagenumbering{roman} \maketitle diff --git a/Master/texmf-dist/doc/latex/l3kernel/source3body.tex b/Master/texmf-dist/doc/latex/l3kernel/source3body.tex index 2f36e993eef..588dba1008c 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/source3body.tex +++ b/Master/texmf-dist/doc/latex/l3kernel/source3body.tex @@ -55,33 +55,14 @@ these conventions. However, in the main direct use of the primitives is not required or encouraged: the \pkg{expl3} modules define an independent low-level \LaTeX3 programming language. -At present, the \pkg{expl3} modules are designed to be loaded on top of -\LaTeXe{}. In time, a \LaTeX3 format will be produced based on this code. -This allows the code to be used in \LaTeXe{} packages \emph{now} while a -stand-alone \LaTeX3 is developed. - -\begin{bfseries} - While \pkg{expl3} is still experimental, the bundle is now regarded as - broadly stable. The syntax conventions and functions provided are now - ready for wider use. There may still be changes to some functions, but - these will be minor when compared to the scope of \pkg{expl3}. - - New modules will be added to the distributed version of \pkg{expl3} as - they reach maturity. -\end{bfseries} +The \pkg{expl3} modules are designed to be loaded on top of +\LaTeXe{}. With an up-to-date \LaTeXe{} kernel, this material is loaded +as part of the format. The fundamental programming code can also be loaded +with other \TeX{} formats, subject to restrictions on the full range of +functionality. \end{abstract} -\clearpage - -{% - \def\\{:}% fix "newlines" in the ToC - \tableofcontents -} - -\clearpage -\pagenumbering{arabic} - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Each of the following \DocInput lines includes a file with extension @@ -97,15 +78,98 @@ stand-alone \LaTeX3 is developed. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \makeatletter +% l3doc is based on article, but for these very large documents we need +% chapters; the code is based on the standard classes but somewhat simplified +\renewcommand\part{% + \clearpage + \thispagestyle{plain}% + \@tempswafalse + \null\vfil + \secdef\@part\@spart} +\newcounter {chapter} +\numberwithin{section}{chapter} +\renewcommand \thechapter {\@arabic\c@chapter} +\renewcommand \thesection {\thechapter.\@arabic\c@section} +\newcommand*\chaptermark[1]{} +\setcounter{secnumdepth}{2} +\newcommand\@chapapp{\chaptername} +\newcommand\chaptername{Chapter} + \def\ps@headings{% + \let\@oddfoot\@empty + \def\@oddhead{{\slshape\rightmark}\hfil\thepage}% + \let\@mkboth\markboth + \def\chaptermark##1{% + \markright {\MakeUppercase{% + \ifnum \c@secnumdepth >\m@ne + \@chapapp\ \thechapter. \ % + \fi + ##1}}}} +\newcommand\chapter{\clearpage + \thispagestyle{plain}% + \global\@topnum\z@ + \@afterindentfalse + \secdef\@chapter\@schapter} +\def\@chapter[#1]#2{\refstepcounter{chapter}% + \typeout{\@chapapp\space\thechapter.}% + \addcontentsline{toc}{chapter}% + {\protect\numberline{\thechapter}#1}% + \chaptermark{#1}% + \addtocontents{lof}{\protect\addvspace{10\p@}}% + \addtocontents{lot}{\protect\addvspace{10\p@}}% + \@makechapterhead{#2}% + \@afterheading} +\def\@makechapterhead#1{% + \vspace*{50\p@}% + {\parindent \z@ \raggedright \normalfont + \huge\bfseries \@chapapp\space \thechapter + \par\nobreak + \vskip 20\p@ + \interlinepenalty\@M + \Huge \bfseries #1\par\nobreak + \vskip 40\p@ + }} +\newcommand*\l@chapter[2]{% + \ifnum \c@tocdepth >\m@ne + \addpenalty{-\@highpenalty}% + \vskip 1.0em \@plus\p@ + \setlength\@tempdima{1.5em}% + \begingroup + \parindent \z@ \rightskip \@pnumwidth + \parfillskip -\@pnumwidth + \leavevmode \bfseries + \advance\leftskip\@tempdima + \hskip -\leftskip + #1\nobreak\hfil + \nobreak\hb@xt@\@pnumwidth{\hss #2% + \kern-\p@\kern\p@}\par + \penalty\@highpenalty + \endgroup + \fi} +\renewcommand*\l@section{\@dottedtocline{1}{1.5em}{2.8em}} +\renewcommand*\l@subsection{\@dottedtocline{2}{3.8em}{3.2em}} +\renewcommand*\l@subsubsection{\@dottedtocline{3}{7.0em}{4.1em}} \def\partname{Part} -\def\maketitle{\clearpage\part{\@title}} +\def\toclevel@part{-1} +\def\maketitle{\chapter{\@title}} \let\thanks\@gobble \let\DelayPrintIndex\PrintIndex \let\PrintIndex\@empty \providecommand*{\hexnum}[1]{\text{\texttt{\char`\"}#1}} \makeatother -\part{Introduction to \pkg{expl3} and this document} +\clearpage + +{% + \def\\{:}% fix "newlines" in the ToC + \tableofcontents +} + +\clearpage +\pagenumbering{arabic} + +\part{Introduction} + +\chapter{Introduction to \pkg{expl3} and this document} This document is intended to act as a comprehensive reference manual for the \pkg{expl3} language. A general guide to the \LaTeX3 @@ -441,27 +505,43 @@ used on top of \LaTeXe{} if \cs{outer} tokens are used in the arguments. \DisableImplementation +\part{Bootstrapping} + \DocInput{l3bootstrap.dtx} \DocInput{l3names.dtx} \ExplSyntaxOn \clist_gput_right:Nn \g_docinput_clist { l3kernel-functions.dtx } \ExplSyntaxOff + +\part{Programming Flow} + \DocInput{l3basics.dtx} \DocInput{l3expan.dtx} -\DocInput{l3quark.dtx} +\DocInput{l3sort.dtx} +\DocInput{l3tl-analysis.dtx} +\DocInput{l3regex.dtx} +\DocInput{l3prg.dtx} +\DocInput{l3sys.dtx} +\DocInput{l3msg.dtx} +\DocInput{l3file.dtx} + +\DocInput{l3luatex.dtx} + +\DocInput{l3legacy.dtx} + + +\part{Data types} + \DocInput{l3tl.dtx} \DocInput{l3str.dtx} \DocInput{l3str-convert.dtx} +\DocInput{l3quark.dtx} \DocInput{l3seq.dtx} \DocInput{l3int.dtx} \DocInput{l3flag.dtx} -\DocInput{l3prg.dtx} -\DocInput{l3sys.dtx} \DocInput{l3clist.dtx} \DocInput{l3token.dtx} \DocInput{l3prop.dtx} -\DocInput{l3msg.dtx} -\DocInput{l3file.dtx} \DocInput{l3skip.dtx} \DocInput{l3keys.dtx} \DocInput{l3intarray.dtx} @@ -489,13 +569,9 @@ used on top of \LaTeXe{} if \cs{outer} tokens are used in the arguments. \DocInput{l3fparray.dtx} \DocInput{l3cctab.dtx} -\DocInput{l3sort.dtx} -\DocInput{l3tl-analysis.dtx} -\DocInput{l3regex.dtx} -\DocInput{l3box.dtx} -\DocInput{l3coffins.dtx} -\DocInput{l3color-base.dtx} -\DocInput{l3luatex.dtx} + +\part{Text manipulation} + \DocInput{l3unicode.dtx} \DocInput{l3text.dtx} \ExplSyntaxOn @@ -505,7 +581,16 @@ used on top of \LaTeXe{} if \cs{outer} tokens are used in the arguments. l3text-purify.dtx } \ExplSyntaxOff -\DocInput{l3legacy.dtx} + +\part{Typesetting} + +\DocInput{l3box.dtx} +\DocInput{l3coffins.dtx} +\DocInput{l3color.dtx} +\DocInput{l3pdf.dtx} + +\part{Additions and removals} + \DocInput{l3candidates.dtx} \ExplSyntaxOn diff --git a/Master/texmf-dist/source/latex/l3backend/l3backend-basics.dtx b/Master/texmf-dist/source/latex/l3backend/l3backend-basics.dtx index 80504ebf034..b7f09e7dbde 100644 --- a/Master/texmf-dist/source/latex/l3backend/l3backend-basics.dtx +++ b/Master/texmf-dist/source/latex/l3backend/l3backend-basics.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % @@ -70,27 +70,27 @@ % \begin{macrocode} \ProvidesExplFile %<*dvipdfmx> - {l3backend-dvipdfmx.def}{2021-02-06}{} + {l3backend-dvipdfmx.def}{2021-02-18}{} {L3 backend support: dvipdfmx} % %<*dvips> - {l3backend-dvips.def}{2021-02-06}{} + {l3backend-dvips.def}{2021-02-18}{} {L3 backend support: dvips} % %<*dvisvgm> - {l3backend-dvisvgm.def}{2021-02-06}{} + {l3backend-dvisvgm.def}{2021-02-18}{} {L3 backend support: dvisvgm} % %<*luatex> - {l3backend-luatex.def}{2021-02-06}{} + {l3backend-luatex.def}{2021-02-18}{} {L3 backend support: PDF output (LuaTeX)} % %<*pdftex> - {l3backend-pdftex.def}{2021-02-06}{} + {l3backend-pdftex.def}{2021-02-18}{} {L3 backend support: PDF output (pdfTeX)} % %<*xetex> - {l3backend-xetex.def}{2021-02-06}{} + {l3backend-xetex.def}{2021-02-18}{} {L3 backend support: XeTeX} % % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3backend/l3backend-box.dtx b/Master/texmf-dist/source/latex/l3backend/l3backend-box.dtx index f6268a776c5..bc0a3ffdd5f 100644 --- a/Master/texmf-dist/source/latex/l3backend/l3backend-box.dtx +++ b/Master/texmf-dist/source/latex/l3backend/l3backend-box.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx b/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx index 9373df677d3..451a0039a55 100644 --- a/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx +++ b/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % @@ -241,13 +241,13 @@ % \end{variable} % \end{macro} % -% \begin{macro}{\@@_backend_stack_push:nn, \@@_backend_stack_push:nx} -% \begin{macro}{\@@_backend_stack_pop:n} +% \begin{macro}{\__kernel_color_backend_stack_push:nn, \__kernel_color_backend_stack_push:nx} +% \begin{macro}{\__kernel_color_backend_stack_pop:n} % Simple enough but needs a version check. % \begin{macrocode} \int_compare:nNnF \c__kernel_sys_dvipdfmx_version_int < { 20201111 } { - \cs_new_protected:Npn \@@_backend_stack_push:nn #1#2 + \cs_new_protected:Npn \__kernel_color_backend_stack_push:nn #1#2 { \__kernel_backend_literal:x { @@ -256,8 +256,8 @@ push ~ (#2) } } - \cs_generate_variant:Nn \@@_backend_stack_push:nn { nx } - \cs_new_protected:Npn \@@_backend_stack_pop:n #1 + \cs_generate_variant:Nn \__kernel_color_backend_stack_push:nn { nx } + \cs_new_protected:Npn \__kernel_color_backend_stack_pop:n #1 { \__kernel_backend_literal:x { @@ -300,10 +300,10 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_backend_stack_push:nn, \@@_backend_stack_push:nx} -% \begin{macro}{\@@_backend_stack_pop:n} +% \begin{macro}{\__kernel_color_backend_stack_push:nn, \__kernel_color_backend_stack_push:nx} +% \begin{macro}{\__kernel_color_backend_stack_pop:n} % \begin{macrocode} -\cs_new_protected:Npn \@@_backend_stack_push:nn #1#2 +\cs_new_protected:Npn \__kernel_color_backend_stack_push:nn #1#2 { %<*luatex> \tex_pdfextension:D colorstack ~ @@ -313,8 +313,8 @@ % \int_eval:n {#1} ~ push ~ {#2} } -\cs_generate_variant:Nn \@@_backend_stack_push:nn { nx } -\cs_new_protected:Npn \@@_backend_stack_pop:n #1 +\cs_generate_variant:Nn \__kernel_color_backend_stack_push:nn { nx } +\cs_new_protected:Npn \__kernel_color_backend_stack_pop:n #1 { %<*luatex> \tex_pdfextension:D colorstack ~ @@ -410,11 +410,11 @@ { \tl_set:Nn \l_@@_backend_fill_tl {#1} \tl_set:Nn \l_@@_backend_stroke_tl {#2} - \@@_backend_stack_push:nn \l_@@_backend_stack_int { #1 ~ #2 } + \__kernel_color_backend_stack_push:nn \l_@@_backend_stack_int { #1 ~ #2 } \group_insert_after:N \@@_backend_reset: } \cs_new_protected:Npn \@@_backend_reset: - { \@@_backend_stack_pop:n \l_@@_backend_stack_int } + { \__kernel_color_backend_stack_pop:n \l_@@_backend_stack_int } % \end{macrocode} % \end{macro} % \end{macro} @@ -790,7 +790,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_backend_separation_init:nnnnn #1#2#3#4#5 { - \pdf_object_now:nx { dict } + \pdf_object_unnamed_write:nx { dict } { /FunctionType ~ 2 /Domain ~ [0 ~ 1] @@ -802,21 +802,22 @@ { /Separation ~ / \str_convert_pdfname:n {#1} ~ #2 ~ - \pdf_object_last: + \pdf_object_ref_last: } - \use:x + \cs_if_exist:NT \pdfmanagement_add:nnn { - \pdfmanagement_add:nnn - { Page / Resources / ColorSpace } - { color \int_use:N \g_@@_model_int } - { \pdf_object_last: } + \use:x + { + \pdfmanagement_add:nnn + { Page / Resources / ColorSpace } + { color \int_use:N \g_@@_model_int } + { \pdf_object_ref_last: } + } } } -\cs_if_exist:NF \pdf_object_now:nn - { \cs_gset_protected:Npn \@@_backend_separation_init:nnnnn #1#2#3#4#5 { } } \cs_new_protected:Npn \@@_backend_separation_init:n #1 { - \pdf_object_now:nx { array } {#1} + \pdf_object_unnamed_write:nx { array } {#1} } % \end{macrocode} % For CIELAB colors, we need one object per document for the illuminant, @@ -844,7 +845,7 @@ { 100 ~ 0 ~ 0 } {#3} } -\cs_if_exist:NF \pdf_object_now:nn +\cs_if_exist:NF \pdf_object_unnamed_write:nn { \cs_gset_protected:Npn \@@_backend_separation_init_CIELAB:nnn #1#2#3 { } @@ -862,7 +863,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_backend_devicen_init:nnn #1#2#3 { - \pdf_object_now:nx { stream } + \pdf_object_unnamed_write:nx { stream } { { /FunctionType ~ 4 ~ @@ -889,18 +890,19 @@ /DeviceN ~ [ ~ #1 ~ ] ~ #2 ~ - \pdf_object_last: + \pdf_object_ref_last: } - \use:x + \cs_if_exist:NT \pdfmanagement_add:nnn { - \pdfmanagement_add:nnn - { Page / Resources / ColorSpace } - { color \int_use:N \g_@@_model_int } - { \pdf_object_last: } + \use:x + { + \pdfmanagement_add:nnn + { Page / Resources / ColorSpace } + { color \int_use:N \g_@@_model_int } + { \pdf_object_ref_last: } + } } } -\cs_if_exist:NF \pdf_object_now:nn - { \cs_gset_protected:Npn \@@_backend_devicen_init:nnn #1#2#3 { } } \cs_new:Npn \@@_backend_devicen_init:w #1 ~ #2 \s_@@_stop { + 1 @@ -976,7 +978,7 @@ \cs_new_protected:Npn \@@_backend_fill:n #1 { \tl_set:Nn \l_@@_backend_fill_tl {#1} - \@@_backend_stack_push:nn \l_@@_backend_stack_int + \__kernel_color_backend_stack_push:nn \l_@@_backend_stack_int { #1 ~ \l_@@_backend_stroke_tl } \group_insert_after:N \@@_backend_reset: } @@ -989,7 +991,7 @@ \cs_new_protected:Npn \@@_backend_stroke:n #1 { \tl_set:Nn \l_@@_backend_stroke_tl {#1} - \@@_backend_stack_push:nn \l_@@_backend_stack_int + \__kernel_color_backend_stack_push:nn \l_@@_backend_stack_int { \l_@@_backend_fill_tl \c_space_tl #1 } \group_insert_after:N \@@_backend_reset: } diff --git a/Master/texmf-dist/source/latex/l3backend/l3backend-draw.dtx b/Master/texmf-dist/source/latex/l3backend/l3backend-draw.dtx index 8602a4da4cf..5536391276a 100644 --- a/Master/texmf-dist/source/latex/l3backend/l3backend-draw.dtx +++ b/Master/texmf-dist/source/latex/l3backend/l3backend-draw.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3backend/l3backend-graphics.dtx b/Master/texmf-dist/source/latex/l3backend/l3backend-graphics.dtx index 484e5b20b9d..c3ec121c073 100644 --- a/Master/texmf-dist/source/latex/l3backend/l3backend-graphics.dtx +++ b/Master/texmf-dist/source/latex/l3backend/l3backend-graphics.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3backend/l3backend-header.dtx b/Master/texmf-dist/source/latex/l3backend/l3backend-header.dtx index 77d1d93a266..eafd36f50d7 100644 --- a/Master/texmf-dist/source/latex/l3backend/l3backend-header.dtx +++ b/Master/texmf-dist/source/latex/l3backend/l3backend-header.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3backend/l3backend-opacity.dtx b/Master/texmf-dist/source/latex/l3backend/l3backend-opacity.dtx index 06d17b6745f..ee4702a3cdf 100644 --- a/Master/texmf-dist/source/latex/l3backend/l3backend-opacity.dtx +++ b/Master/texmf-dist/source/latex/l3backend/l3backend-opacity.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % @@ -151,7 +151,7 @@ \pdfmanagement_add:nnn { Page / Resources / ExtGState } { opacity #1 } { << /ca ~ #1 /CA ~ #1 >> } - \@@_backend_stack_push:nn \c_@@_backend_stack_int + \__kernel_color_backend_stack_push:nn \c_@@_backend_stack_int { /opacity #1 ~ gs } \group_insert_after:N \@@_backend_reset: } @@ -160,7 +160,7 @@ \cs_gset_protected:Npn \@@_backend_select_aux:n #1 { } } \cs_new_protected:Npn \@@_backend_reset: - { \@@_backend_stack_pop:n \c_@@_backend_stack_int } + { \__kernel_color_backend_stack_pop:n \c_@@_backend_stack_int } % \end{macrocode} % \end{macro} % \end{macro} @@ -195,7 +195,7 @@ \pdfmanagement_add:nnn { Page / Resources / ExtGState } { opacity.stroke #1 } { << /CA ~ #2 >> } - \@@_backend_stack_push:nn \c_@@_backend_stack_int + \__kernel_color_backend_stack_push:nn \c_@@_backend_stack_int { /opacity.fill #1 ~ gs /opacity.stroke #2 ~ gs } \group_insert_after:N \@@_backend_reset: } diff --git a/Master/texmf-dist/source/latex/l3backend/l3backend-pdf.dtx b/Master/texmf-dist/source/latex/l3backend/l3backend-pdf.dtx index dd279399d95..ad2b0d51705 100644 --- a/Master/texmf-dist/source/latex/l3backend/l3backend-pdf.dtx +++ b/Master/texmf-dist/source/latex/l3backend/l3backend-pdf.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx b/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx index 76f36777816..1771ac26668 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % @@ -129,7 +129,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{l3benchmark}{2021-02-06}{} +\ProvidesExplPackage{l3benchmark}{2021-02-18}{} {L3 Experimental benchmarking} % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3bitset/l3bitset.dtx b/Master/texmf-dist/source/latex/l3experimental/l3bitset/l3bitset.dtx index 7c61b81f834..686df60ccd4 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3bitset/l3bitset.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3bitset/l3bitset.dtx @@ -42,7 +42,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % \begin{documentation} @@ -264,7 +264,7 @@ %<@@=bitset> % \end{macrocode} % \begin{macrocode} -\ProvidesExplPackage{l3bitset}{2021-02-06}{} +\ProvidesExplPackage{l3bitset}{2021-02-18}{} {L3 Experimental bitset support} % \end{macrocode} % A bitset is a string variable. diff --git a/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx b/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx deleted file mode 100644 index 0f1b130da88..00000000000 --- a/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx +++ /dev/null @@ -1,2553 +0,0 @@ -% \iffalse meta-comment -% -%% File: l3color.dtx -% -% Copyright (C) 2017-2021 The LaTeX Project -% -% It may be distributed and/or modified under the conditions of the -% LaTeX Project Public License (LPPL), either version 1.3c of this -% license or (at your option) any later version. The latest version -% of this license is in the file -% -% http://www.latex-project.org/lppl.txt -% -% This file is part of the "l3experimental bundle" (The Work in LPPL) -% and all files in that bundle must be distributed together. -% -% ----------------------------------------------------------------------- -% -% The development version of the bundle can be found at -% -% https://github.com/latex3/latex3 -% -% for those people who are interested. -% -%<*driver|package> -\RequirePackage{expl3} -% -%<*driver> -\documentclass[full]{l3doc} -\begin{document} - \DocInput{\jobname.dtx} -\end{document} -% -% \fi -% -% \title{^^A -% The \textsf{l3color} package\\ Experimental color support^^A -% } -% -% \author{^^A -% The \LaTeX{} Project\thanks -% {^^A -% E-mail: -% \href{mailto:latex-team@latex-project.org} -% {latex-team@latex-project.org}^^A -% }^^A -% } -% -% \date{Released 2021-02-06} -% -% \maketitle -% -% \begin{documentation} -% -% \section{Color models} -% -% A color \emph{model} is a way to represent sets of colors. Different models -% are particularly suitable for different output methods, \emph{e.g.}~screen -% or print. Parameter-based models can describe a very large number of unique -% colors, and have a varying number of \emph{axes} which define a color -% space. In contrast, various proprietary models are available which define -% \emph{spot} colors (more formally separations). -% -% Core models are used to pass color information to output; these are -% \enquote{native} to \pkg{l3color}. Core models use real numbers in the range -% $[0,1]$ to represent values. The core models supported here are -% \begin{itemize} -% \item \texttt{gray} Grayscale color, with a single axis running from -% $0$ (fully black) to $1$ (fully white) -% \item \texttt{rgb} Red-green-blue color, with three axes, one for each of -% the components -% \item \texttt{cmyk} Cyan-magenta-yellow-black color, with four axes, one for -% each of the components -% \end{itemize} -% There are also interface models: these are convenient for users but have -% to be manipulated before storing/passing to the backend. Interface models -% are primarily integer-based: see below for more detail. The supported -% interface models are -% \begin{itemize} -% \item \texttt{Gray} Grayscale color, with a single axis running from -% $0$ (fully black) to $15$ (fully white) -% \item \texttt{hsb} Hue-saturation-brightness color, with three axes,all -% real values in the range $[0,1]$ for hue saturation and brightness -% \item \texttt{Hsb} Hue-saturation-brightness color, with three axes, integer -% in the range $[0,360]$ for hue, real values in the range $[0,1]$ for -% saturation and brightness -% \item \texttt{HSB} Hue-saturation-brightness color, with three axes, integers -% in the range $[0,240]$ for hue, saturation and brightness -% \item \texttt{HTML} HTML format representation of RGB color given as a -% single six-digit hexadecimal number -% \item \texttt{RGB} Red-green-blue color, with three axes, one for each of -% the components, values as integers from $0$ to $255$ -% \item \texttt{wave} Light wavelength, a real number in the range -% $380$ to $780$ (nanometres) -% \end{itemize} -% All interface models are internally stored as |rgb|. -% -% To allow parsing of data from \pkg{xcolor}, any leading model up the first -% \texttt{:} will be discarded; the approach of selecting an internal form -% for data is \emph{not} used in \pkg{l3color}. -% -% Additional models may be created to allow mixing of separation colors -% with each other or with those from other models. See -% Section~\ref{l3color:sec:new-models} for more detail of color support -% for additional models. -% -% When color is selected by model, the \meta{values} given are specified as -% a comma-separated list. The length of the list will therefore be determined -% by the detail of the model involved. -% -% Color models (and interconversion) are complex, and more details are given -% in the manual to the \LaTeXe{} \pkg{xcolor} package and in the -% \emph{PostScript Language Reference Manual}, published by Addison--Wesley. -% -% \section{Color expressions} -% -% In addition to allowing specification of color by model and values, -% \pkg{l3color} also supports color expressions. These are created -% by combining one or more color names, with the amount of each specified -% as a percentage. The latter is given between |!| symbols in the expression. -% Thus for example -% \begin{verbatim} -% red!50!green -% \end{verbatim} -% is a mixture of $50\,\%$ red and $50\,\%$ green. A trailing percentage is -% interpreted as implicitly followed by |white|, and so -% \begin{verbatim} -% red!25 -% \end{verbatim} -% specifies $25\,\%$ red mixed with $75\,\%$ white. -% -% Where the models for the mixed colors are different, the model of the first -% color is used. Thus -% \begin{verbatim} -% red!50!cyan -% \end{verbatim} -% will result in a color specification using the |rgb| model, made up of -% $50\,\%$ red and $50\,\%$ of cyan \emph{expressed in \texttt{rgb}}. As color -% model interconversion is not exact. -% -% The one exception to the above is where the first model in an expression is -% |gray|. In this case, the order of mixing is \enquote{swapped} internally, so -% that for example -% \begin{verbatim} -% black!50!red -% \end{verbatim} -% has the same result as -% \begin{verbatim} -% red!50!black -% \end{verbatim} -% (the predefined colors |black| and |white| use the |gray| model). -% -% Where more than two colors are mixed in an expression, evaluation takes place -% in a stepwise fashion. Thus in -% \begin{verbatim} -% cyan!50!magenta!10!yellow -% \end{verbatim} -% the sub-expression -% \begin{verbatim} -% cyan!50!magenta -% \end{verbatim} -% is first evaluated to give an intermediate color specification, before -% the second step -% \begin{verbatim} -% !10!yellow -% \end{verbatim} -% where || represents this transitory calculated value. -% -% Within a color expression, |.| may be used to represent the color active -% for typesetting (the current color). This allows for example -% \begin{verbatim} -% .!50 -% \end{verbatim} -% to mean a mixture of $50\,\%$ of current color with white. -% -% (Color expressions supported here are a subset of those provided by -% the \LaTeXe{} \pkg{xcolor} package. At present, only such features as are -% clearly useful have been added here.) -% -% \section{Named colors} -% -% Color names are stored in a single namespace, which makes them accessible -% as part of color expressions. Whilst they are not reserved in a technical -% sense, the names |black|, |white|, |red|, |green|, |blue|, |cyan|, |magenta| -% and |yellow| have special meaning and should not be redefined. Color names -% should be made up of letters, numbers and spaces only: other characters are -% reserved for use in color expressions. In particular, |.| represents the -% current color at the start of a color expression. -% -% \begin{function}{\color_set:nn} -% \begin{syntax} -% \cs{color_set:nn} \Arg{name} \Arg{color expression} -% \end{syntax} -% Evaluates the \meta{color expression} and stores the resulting -% color specification as the \meta{name}. -% \end{function} -% -% \begin{function}{\color_set:nnn} -% \begin{syntax} -% \cs{color_set:nnn} \Arg{name} \Arg{model(s)} \Arg{value(s)} -% \end{syntax} -% Stores the color specification equivalent to the \meta{model(s)} and -% \meta{values} as the \meta{name}. -% \end{function} -% -% \begin{function}{\color_set_eq:nn} -% \begin{syntax} -% \cs{color_set_eq:nn} \Arg{name1} \Arg{name2} -% \end{syntax} -% Copies the color specification in \meta{name2} to \meta{name1}. The -% special name |.| may be used to represent the current color, allowing -% it to be saved to a name. -% \end{function} -% -% \begin{function}{\color_show:n} -% \begin{syntax} -% \cs{color_show:n} \Arg{name} -% \end{syntax} -% Displays the color specification stored in the \meta{name} on the -% terminal. -% \end{function} -% -% \section{Selecting colors} -% -% General selection of color is safe when split across pages: a stack is -% used to ensure that the correct color is re-selected on the new page. -% -% \begin{function}{\color_select:n} -% \begin{syntax} -% \cs{color_select:n} \Arg{color expression} -% \end{syntax} -% Parses the \meta{color expression} and then activates the resulting -% color specification for typeset material. -% \end{function} -% -% \begin{function}{\color_select:nn} -% \begin{syntax} -% \cs{color_select:nn} \Arg{model(s)} \Arg{value(s)} -% \end{syntax} -% Activates the color specification equivalent to the \meta{model(s)} and -% \meta{value(s)} for typeset material. -% \end{function} -% -% \begin{variable}{\l_color_fixed_model_tl} -% When this is set to a non-empty value, colors will be converted to -% the specified model when they are selected. Note that included images -% and similar are not influenced by this setting. -% \end{variable} -% -% \section{Colors for fills and strokes} -% -% Colors for drawing operations and so forth are split into strokes and fills -% (the latter may also be referred to as non-stroke color). The fill color is -% used for text under normal circumstances. Depending on the backend, stroke -% color may use a \emph{stack}, in which case it exhibits the same page breaking -% behavior as general color. However, \texttt{dvips}/\texttt{dvisvgm} do not -% support this, and so color will need to be contained within a scope, such -% as \cs{draw_begin:}/\cs{draw_end:}. -% -% Note that the \emph{current color} is the fill color, as this is used for -% running text. -% -% \begin{function}{\color_fill:n, \color_stroke:n} -% \begin{syntax} -% \cs{color_fill:n} \Arg{color expression} -% \end{syntax} -% Parses the \meta{color expression} and then activates the resulting -% color specification for filling or stroking. -% \end{function} -% -% \begin{function}{\color_fill:nn, \color_stroke:nn} -% \begin{syntax} -% \cs{color_fill:nn} \Arg{model(s)} \Arg{value(s)} -% \end{syntax} -% Activates the color specification equivalent to the \meta{model(s)} and -% \meta{value(s)} for filling or stroking. -% \end{function} -% -% \begin{variable}{color.sc} -% When using \texttt{dvips}, this PostScript variables hold the stroke color. -% \end{variable} -% -% \section{Multiple color models} -% -% When selecting or setting a color with an explicit model, it is possible -% to give values for more than one model at one time. This is particularly -% useful where automated conversion between models does not give the desired -% outcome. To do this, the list of models and list of values are both subdivided -% using |/| characters (as for the similar function in \pkg{xcolor}). For -% example, to save a color with explicit |cmyk| and |rgb| values, one could -% use -% \begin{verbatim} -% \color_set:nnn { foo } { cmyk / rgb } -% { 0.1 , 0.2 , 0.3 , 0.4 / 0.1, 0.2 , 0.3 } -% \end{verbatim} -% The manually-specified conversion will be used in preference to automated -% calculation whenever the model(s) listed are used: both in expressions and -% when a fixed model is active. -% -% Similarly, the same syntax can be applied to directly selecting a color. -% \begin{verbatim} -% \color_select:nn { cmyk / rgb } -% { 0.1 , 0.2 , 0.3 , 0.4 / 0.1, 0.2 , 0.3 } -% \end{verbatim} -% Again, this list is used when a fixed model is active: the first entry is used -% unless there is a fixed model matching one of the other entries. -% -% \section{Exporting color specifications} -% -% The major use of color expressions is in setting typesetting output, but there -% are other places in which some form of color information is required. These -% may need data in a different format or using a different model to the internal -% representation. Thus a set of functions are available to export colors in -% different formats. -% -% Valid export targets are -% \begin{itemize} -% \item \texttt{backend} Two brace groups: the first containing the -% model, the second containing space-separated values appropriate -% for the model; this is the format required by backend functions -% of \pkg{expl3} -% \item \texttt{HTML} Uppercase two-digit hexadecimal values, expressing -% a red-green-blue color; the digits are \emph{not} separated -% \item \texttt{space-sep-cmyk} Space-separated cyan-magenta-yellow-black -% values -% \item \texttt{space-sep-rgb} Space-separated red-green-blue values -% suitable for use as a PDF annotation color -% \end{itemize} -% -% \begin{function}{\color_export:nnN} -% \begin{syntax} -% \cs{color_export:nnN} \Arg{color expression} \Arg{format} \Arg{tl} -% \end{syntax} -% Parses the \meta{color expression} as described earlier, -% then converts to the \meta{format} specified and assigns the data to the -% \meta{tl}. -% \end{function} -% -% \begin{function}{\color_export:nnnN} -% \begin{syntax} -% \cs{color_export:nnnN} \Arg{model} \Arg{value(s)} \Arg{format} \Arg{tl} -% \end{syntax} -% Expresses the combination of \meta{model} and \meta{value(s)} in an -% internal representation, then converts to the \meta{format} specified and -% assigns the data to the \meta{tl}. -% \end{function} -% -% \section{Creating new color models} -% \label{l3color:sec:new-models} -% -% Additional color models are required to support specialist workflows, for -% example those involving separations (see -% \url{https://helpx.adobe.com/indesign/using/spot-process-colors.html} -% for details of the use of separations in print). Color models may be split -% into families; for the standard device-based color models (\texttt{DeviceCMYK}, -% \texttt{DeviceRGB}, \texttt{DeviceGray}), these are synonymous. This -% is not generally the case: see the PDF reference for more details. (Note that -% \pkg{l3color} uses the shorter names \texttt{cmyk}, etc.) -% -% \begin{function}{\color_model_new:nnn} -% \begin{syntax} -% \cs{color_model_new:nnn} \Arg{model} \Arg{family} \Arg{params} -% \end{syntax} -% Creates a new \meta{model} which is derived from the color model \meta{family}. -% The latter should be one of -% \begin{itemize} -% \item \texttt{DeviceN} -% \item \texttt{Separation} -% \end{itemize} -% (The \meta{family} may be given in mixed case as-in the PDF reference: -% internally, case of these strings is folded.) -% Depending on the \meta{family}, one or more \meta{params} are mandatory or -% optional. -% \end{function} -% -% For a \texttt{Separation} space, there are three \emph{compulsory} keys. -% \begin{itemize} -% \item \texttt{name} The name of the Separation, for example the formal -% name of a spot color ink. Such a \meta{name} may contain spaces, etc., -% which are not permitted in the \meta{model}. -% \item \texttt{alternative-model} An alternative device colorspace, one of -% \texttt{cmyk}, \texttt{rgb}, \texttt{gray} or \texttt{CIELAB}. The three -% parameter-based models work as described above; see below for -% details of CIELAB colors. -% \item \texttt{alternative-values} A comma-separated list of values -% appropriate to the \texttt{alternative-model}. This information is used by -% the PDF application if the \texttt{Separation} is not available. -% \end{itemize} -% -% CIELAB color separations are created using the -% \texttt{alternative-model = CIELAB} setting. These colors must also have an -% \texttt{illuminant} key, one of \texttt{a}, \texttt{c}, \texttt{e}, -% \texttt{d50}, \texttt{d55}, \texttt{d65} or \texttt{d75}. The -% \texttt{alternative-values} in this case are the three parameters $L*$, $a*$ -% and $b*$ of the CIELAB model. Full details of this device-independent color -% approach are given in the documentation to the \pkg{colorspace} package. -% -% CIELAB colors \emph{cannot} be converted into other device-dependent color -% spaces, and as such, mixing can only occur if colors set up using the CIELAB -% model are also given with an alternative parameter-based model. If that is -% not the case, \pkg{l3color} will fallback to using black as the colorant in -% any mixing. -% -% For a \texttt{DeviceN} space, there is one \emph{compulsory} key. -% \begin{itemize} -% \item \texttt{names} The names of the components of the \texttt{DeviceN} -% space. Each should be either the \meta{name} of a \texttt{Separation} model, -% a process color name (\texttt{cyan}, etc.) or the special name \texttt{none}. -% \end{itemize} -% -% \end{documentation} -% -% \begin{implementation} -% -% \section{\pkg{l3color} Implementation} -% -% \begin{macrocode} -%<*package> -% \end{macrocode} -% -% \begin{macrocode} -%<@@=color> -% \end{macrocode} -% -% \begin{macrocode} -\ProvidesExplPackage{l3color}{2021-02-06}{} - {L3 Experimental color support} -% \end{macrocode} -% -% \subsection{Predefined color names} -% -% The ability to predefine colors with a name is a key part of this module and -% means there has to be a method for storing the results. At first sight, it -% seems natural to follow the usual \pkg{expl3} model and create a -% \texttt{color} variable type for the process. That would then allow both -% local and global colors, constant colors and the like. However, these names -% need to be accessible in some form at the user level, for selection of colors -% either simply by name or as part of a more complex expression. This does not -% require that the full name is exposed but does require that they can be -% looked up in a predictable way. As such, it is more useful to expose just the -% color names as part of the interface, with the result that only local color -% names can be created. (This is also seen for example in key creation in -% \pkg{l3keys}.) As a result, color names are declarative (no \texttt{new} -% functions). -% -% Since there is no need to manipulate colors \emph{en masse}, each is stored -% in a two-part structure: a \texttt{prop} for the colors themselves, and a -% \texttt{tl} for the default model for each color. -% -% \subsection{Setup} -% -% \begin{variable}{\l_@@_internal_int, \l_@@_internal_tl} -% \begin{macrocode} -\int_new:N \l_@@_internal_int -\tl_new:N \l_@@_internal_tl -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\s_@@_mark} -% Internal scan marks. \cs{s_@@_stop} is already defined in \pkg{l3color-base}. -% \begin{macrocode} -\scan_new:N \s_@@_mark -% \end{macrocode} -% \end{variable} -% -% \subsection{Utility functions} -% -% \begin{macro}[int, TF, EXP]{\@@_if_defined:n} -% A simple wrapper to avoid needing to have the lookup repeated in too many -% places. -% \begin{macrocode} -\prg_new_conditional:Npnn \@@_if_defined:n #1 { T, F, TF } - { - \prop_if_exist:cTF { l_@@_named_ #1 _prop } - \prg_return_true: - \prg_return_false: - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[EXP]{\@@_model:N, \@@_values:N} -% Simple abstractions. -% \begin{macrocode} -\cs_new:Npn \@@_model:N #1 { \exp_after:wN \use_i:nn #1 } -\cs_new:Npn \@@_values:N #1 { \exp_after:wN \use_ii:nn #1 } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_extract:nNN, \@@_extract:VNN} -% Recover the values for the standard model for a color. -% \begin{macrocode} -\cs_new_protected:Npn \@@_extract:nNN #1#2#3 - { - \tl_set_eq:Nc #2 { l_@@_named_ #1 _tl } - \prop_get:cVN { l_@@_named_ #1 _prop } #2 #3 - } -\cs_generate_variant:Nn \@@_extract:nNN { V } -% \end{macrocode} -% \end{macro} -% -% \subsection{Model conversion} -% -% \begin{macro}{\@@_convert:nnN, \@@_convert:VVN} -% \begin{macro}{\@@_convert:nnnN, \@@_convert:nVnN, \@@_convert:nnVN} -% \begin{macro}[aux, EXP] -% { -% \@@_convert_gray_rgb:w -% \@@_convert_gray_cmyk:w -% \@@_convert_cmyk_gray:w -% \@@_convert_cmyk_rgb:w -% \@@_convert_rgb_gray:w -% \@@_convert_rgb_cmyk:w -% } -% \begin{macro}[aux, EXP]{\@@_convert_rgb_cmyk:nnnn} -% Model conversion is carried out using standard formulae, as described in -% the manual for \pkg{xcolor} (see also the \emph{PostScript Language -% Reference Manual}). -% \begin{macrocode} -\cs_new_protected:Npn \@@_convert:nnN #1#2#3 - { \@@_convert:nnVN {#1} {#2} #3 #3 } -\cs_generate_variant:Nn \@@_convert:nnN { VV } -\cs_new_protected:Npn \@@_convert:nnnN #1#2#3#4 - { - \tl_set:Nx #4 - { - \cs_if_exist:cTF { @@_convert_ #1 _ #2 :w } - { \use:c { @@_convert_ #1 _ #2 :w } #3 ~ 0 ~ 0 ~ 0 \s_@@_stop } - { \use:c { c_@@_fallback_ #2 _tl } } - } - } -\cs_generate_variant:Nn \@@_convert:nnnN { nV , nnV } -\cs_new:Npn \@@_convert_gray_rgb:w #1 ~ #2 \s_@@_stop - { #1 ~ #1 ~ #1 } -\cs_new:Npn \@@_convert_gray_cmyk:w #1 ~ #2 \s_@@_stop - { 0 ~ 0 ~ 0 ~ \fp_eval:n { 1 - #1 } } -% \end{macrocode} -% These rather odd values are based on \textsc{ntsc} television: the set are -% used for the |cmyk| conversion. -% \begin{macrocode} -\cs_new:Npn \@@_convert_rgb_gray:w #1 ~ #2 ~ #3 ~ #4 \s_@@_stop - { \fp_eval:n { 0.3 * #1 + 0.59 * #2 + 0.11 * #3 } } -% \end{macrocode} -% The conversion from |rgb| to |cmyk| is the most complex: a two-step -% procedure which requires \emph{black generation} and \emph{undercolor -% removal} functions. The PostScript reference describes them as -% device-dependent, but following \pkg{xcolor} we assume they are linear. -% Moreover, as the likelihood of anyone using a non-unitary matrix here is -% tiny, we simplify and treat those two concepts as no-ops. -% \begin{macrocode} -\cs_new:Npn \@@_convert_rgb_cmyk:w #1 ~ #2 ~ #3 ~ #4 \s_@@_stop - { - \exp_args:Nf \@@_convert_rgb_cmyk:nnnn - { \fp_eval:n { min ( 1 - #1 , 1 - #2 , 1 - #3 ) } } {#1} {#2} {#3} - } -\cs_new:Npn \@@_convert_rgb_cmyk:nnnn #1#2#3#4 - { - \fp_eval:n { min ( 1 , max ( 0 , 1 - #2 - #1 ) ) } \c_space_tl - \fp_eval:n { min ( 1 , max ( 0 , 1 - #3 - #1 ) ) } \c_space_tl - \fp_eval:n { min ( 1 , max ( 0 , 1 - #4 - #1 ) ) } \c_space_tl - #1 - } -\cs_new:Npn \@@_convert_cmyk_gray:w #1 ~ #2 ~ #3 ~ #4 ~ #5 \s_@@_stop - { \fp_eval:n { 1 - min ( 1 , 0.3 * #1 + 0.59 * #2 + 0.11 * #3 + #4 ) } } -\cs_new:Npn \@@_convert_cmyk_rgb:w #1 ~ #2 ~ #3 ~ #4 ~ #5 \s_@@_stop - { - \fp_eval:n { 1 - min ( 1 , #1 + #4 ) } \c_space_tl - \fp_eval:n { 1 - min ( 1 , #2 + #4 ) } \c_space_tl - \fp_eval:n { 1 - min ( 1 , #3 + #4 ) } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \subsection{Color expressions} -% -% \begin{variable} -% {\l_@@_model_tl, \l_@@_value_tl, \l_@@_next_model_tl, \l_@@_next_value_tl} -% Working space to store the color data whilst doing calculations: keeping -% it on the stack is attractive but gets tricky (return is non-trivial). -% \begin{macrocode} -\tl_new:N \l_@@_model_tl -\tl_new:N \l_@@_value_tl -\tl_new:N \l_@@_next_model_tl -\tl_new:N \l_@@_next_value_tl -% \end{macrocode} -% \end{variable} -% -% \begin{macro}{\@@_parse:nN} -% \begin{macro}{\@@_parse_aux:nN} -% \begin{macro}{\@@_parse_eq:Nn} -% \begin{macro}{\@@_parse_eq:nNn} -% \begin{macro}{\@@_parse:Nw} -% \begin{macro}{\@@_parse_loop_init:Nnn} -% \begin{macro}{\@@_parse_loop:w} -% \begin{macro}{\@@_parse_loop:nn} -% \begin{macro}{\@@_parse_gray:n, \@@_parse_std:n} -% \begin{macro}{\@@_parse_break:w} -% \begin{macro}{\@@_parse_end:} -% \begin{macro}[aux, EXP]{\@@_parse_mix:Nnnn, \@@_parse_mix:NVVn} -% \begin{macro}[aux, EXP]{\@@_parse_mix:nNnn} -% \begin{macro}[aux, EXP] -% { -% \@@_parse_mix_gray:nw , -% \@@_parse_mix_rgb:nw , -% \@@_parse_mix_cmyk:nw -% } -% The main function for parsing color expressions removes actives but -% otherwise expands, then starts working through the expression itself. -% At the end, we apply the payload. -% \begin{macrocode} -\cs_new_protected:Npx \@@_parse:nN #1#2 - { - \exp_not:N \@@_backend_pickup:N \exp_not:N \l_@@_current_tl - \tl_set:Nx \exp_not:c { l_@@_named_ . _tl } - { \exp_not:N \@@_model:N \exp_not:N \l_@@_current_tl } - \prop_put:NVx \exp_not:c { l_@@_named_ . _prop } - \exp_not:c { l_@@_named_ . _tl } - { \exp_not:N \@@_values:N \exp_not:N \l_@@_current_tl } - \exp_not:N \exp_args:Ne \exp_not:N \@@_parse_aux:nN - { \exp_not:N \tl_to_str:n {#1} } #2 - } -% \end{macrocode} -% Before going to all of the effort of parsing an expression, these two -% precursor functions look for a pre-defined name, either on its own or -% with a trailing |!| (which is the same thing). -% \begin{macrocode} -\cs_new_protected:Npn \@@_parse_aux:nN #1#2 - { - \tl_if_exist:cTF { l_@@_named_ #1 _prop } - { \@@_parse_set_eq:Nn #2 {#1} } - { \@@_parse:Nw #2#1 ! \s_@@_stop } - \@@_check_model:N #2 - } -\cs_new_protected:Npn \@@_parse_set_eq:Nn #1#2 - { - \tl_if_empty:NTF \l_color_fixed_model_tl - { \exp_args:Nv \@@_parse_set_eq:nNn { l_@@_named_ #2 _tl } } - { \exp_args:NV \@@_parse_set_eq:nNn \l_color_fixed_model_tl } - #1 {#2} - } -% \end{macrocode} -% Here, we have to allow for the case where there is a fixed model: -% that can't be swept up by generic conversion as we are dealing with a -% named color. -% \begin{macrocode} -\cs_new_protected:Npn \@@_parse_set_eq:nNn #1#2#3 - { - \prop_get:cnNTF - { l_@@_named_ #3 _prop } {#1} - \l_@@_value_tl - { \tl_set:Nx #2 { {#1} { \l_@@_value_tl } } } - { - \tl_set_eq:Nc \l_@@_model_tl { l_@@_named_ #3 _tl } - \prop_get:cVN { l_@@_named_ #3 _prop } \l_@@_model_tl - \l_@@_value_tl - \@@_convert:nnN - \l_@@_model_tl {#1} \l_@@_value_tl - \tl_set:Nx #2 - { - {#1} - { \l_@@_value_tl } - } - } - } -\cs_new_protected:Npn \@@_parse:Nw #1#2 ! #3 \s_@@_stop - { - \@@_if_defined:nTF {#2} - { - \tl_if_blank:nTF {#3} - { \@@_parse_set_eq:Nn #1 {#2} } - { \@@_parse_loop_init:Nnn #1 {#2} {#3} } - } - { - \__kernel_msg_error:nnn { color } { unknown-color } {#2} - \tl_set:Nn \l_@@_current_tl { { gray } { 0 } } - } - } -% \end{macrocode} -% Once we establish that a full parse is needed, the next job is to get the -% detail of the first color. That will determine the model we use for the -% calculation: splitting here makes checking that a bit easier. -% \begin{macrocode} -\cs_new_protected:Npn \@@_parse_loop_init:Nnn #1#2#3 - { - \group_begin: - \@@_extract:nNN {#2} \l_@@_model_tl \l_@@_value_tl - \@@_parse_loop:w #3 ! ! ! ! \s_@@_stop - \tl_set:Nx \l_@@_internal_tl - { { \l_@@_model_tl } { \l_@@_value_tl } } - \exp_args:NNNV \group_end: - \tl_set:Nn #1 \l_@@_internal_tl - } -% \end{macrocode} -% This is the loop proper: there can be an open-ended set of colors to parse, -% separated by |!| tokens. There are a few cases to look out for. At the end -% of the expression and with we find a mix of $100$ then we simply skip the -% next color entirely (we can't stop the loop as there might be a further -% valid color to mix in). On the other hand, if we get a mix of $0$ then -% drop everything so far and start again. There is also a trailing -% |white| to \enquote{read in} if the final explicit data is a mix. -% Those conditions are separate from actually looping, which is therefore -% sorted out by checking if we have further data to process: in contrast -% to \pkg{xcolor}, we don't allow |!!| so the test can be simplified. -% \begin{macrocode} -\cs_new_protected:Npn \@@_parse_loop:w #1 ! #2 ! #3 ! #4 ! #5 \s_@@_stop - { - \bool_lazy_or:nnF - { \tl_if_blank_p:n {#1} } - { \int_compare_p:nNn {#1} = { 100 } } - { - \int_compare:nNnTF {#1} = { 0 } - { - \tl_if_blank:nTF {#2} - { \@@_extract:nNN { white } } - { \@@_extract:nNN {#2} } - \l_@@_model_tl \l_@@_value_tl - } - { - \use:x - { - \@@_parse_loop:nn {#1} - { \tl_if_blank:nTF {#2} { white } {#2} } - } - } - } - \tl_if_blank:nF {#3} - { \@@_parse_loop:w #3 ! #4 ! #5 \s_@@_stop } - \@@_parse_end: - } -% \end{macrocode} -% The \enquote{payload} of calculation in the loop first. If the model for -% the upcoming color is different from that of the existing (partial) color, -% convert the model. For |gray| the two are flipped round so that the outcome -% is something with \enquote{real} color. We are then in a position to do the -% actual calculation itself. The two auxiliaries here give us a way to break -% the loop should an invalid name be found. -% \begin{macrocode} -\cs_new_protected:Npn \@@_parse_loop:nn #1#2 - { - \@@_if_defined:nTF {#2} - { - \@@_extract:nNN {#2} \l_@@_next_model_tl \l_@@_next_value_tl - \tl_if_eq:NNF \l_@@_model_tl \l_@@_next_model_tl - { - \str_if_eq:VnTF \l_@@_model_tl { gray } - { \@@_parse_gray:n {#2} } - { \@@_parse_std:n {#2} } - } - \tl_set:Nx \l_@@_value_tl - { - \@@_parse_mix:NVVn - \l_@@_model_tl \l_@@_value_tl \l_@@_next_value_tl {#1} - } - } - { - \__kernel_msg_error:nnn { color } { unknown-color } {#2} - \@@_extract:nNN { black } \l_@@_model_tl \l_@@_value_tl - \@@_parse_break:w - } - } -% \end{macrocode} -% The \texttt{gray} model needs special handling: the models need to be -% swapped: we do that using a dedicated function. -% \begin{macrocode} -\cs_new_protected:Npn \@@_parse_gray:n #1 - { - \tl_set_eq:NN \l_@@_model_tl \l_@@_next_model_tl - \tl_set:Nn \l_@@_next_model_tl { gray } - \exp_args:NnV \@@_convert:nnN { gray } \l_@@_model_tl - \l_@@_value_tl - \prop_get:cVN { l_@@_named_ #1 _prop } \l_@@_model_tl - \l_@@_next_value_tl - } -\cs_new_protected:Npn \@@_parse_std:n #1 - { - \prop_get:cVNF { l_@@_named_ #1 _prop } - \l_@@_model_tl - \l_@@_next_value_tl - { - \@@_convert:VVN - \l_@@_next_model_tl - \l_@@_model_tl - \l_@@_next_value_tl - } - } -\cs_new_protected:Npn \@@_parse_break:w #1 \@@_parse_end: { } -\cs_new_protected:Npn \@@_parse_end: { } -% \end{macrocode} -% Do the vector arithmetic: mainly a question of shuffling input, along -% with one pre-calculation to keep down the use of division. -% \begin{macrocode} -\cs_new:Npn \@@_parse_mix:Nnnn #1#2#3#4 - { - \exp_args:Nf \@@_parse_mix:nNnn - { \fp_eval:n { #4 / 100 } } - #1 {#2} {#3} - } -\cs_generate_variant:Nn \@@_parse_mix:Nnnn { NVV } -\cs_new:Npn \@@_parse_mix:nNnn #1#2#3#4 - { - \use:c { @@_parse_mix_ #2 :nw } {#1} - #3 \s_@@_mark #4 \s_@@_stop - } -\cs_new:Npn \@@_parse_mix_gray:nw #1#2 \s_@@_mark #3 \s_@@_stop - { \fp_eval:n { #2 * #1 + #3 * ( 1 - #1 ) } } -\cs_new:Npn \@@_parse_mix_rgb:nw - #1#2 ~ #3 ~ #4 \s_@@_mark #5 ~ #6 ~ #7 \s_@@_stop - { - \fp_eval:n { #2 * #1 + #5 * ( 1 - #1 ) } \c_space_tl - \fp_eval:n { #3 * #1 + #6 * ( 1 - #1 ) } \c_space_tl - \fp_eval:n { #4 * #1 + #7 * ( 1 - #1 ) } - } -\cs_new:Npn \@@_parse_mix_cmyk:nw - #1#2 ~ #3 ~ #4 ~ #5 \s_@@_mark #6 ~ #7 ~ #8 ~ #9 \s_@@_stop - { - \fp_eval:n { #2 * #1 + #6 * ( 1 - #1 ) } \c_space_tl - \fp_eval:n { #3 * #1 + #7 * ( 1 - #1 ) } \c_space_tl - \fp_eval:n { #4 * #1 + #8 * ( 1 - #1 ) } \c_space_tl - \fp_eval:n { #5 * #1 + #9 * ( 1 - #1 ) } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}[EXP] -% { -% \@@_parse_model_gray:w, \@@_parse_model_rgb:w, -% \@@_parse_model_cmyk:w -% } -% \begin{macro}[EXP]{\@@_parse_number:n} -% \begin{macro}[EXP]{\@@_parse_number:w} -% Turn the input into internal form, also tidying up the number quickly. -% \begin{macrocode} -\cs_new:Npn \@@_parse_model_gray:w #1 , #2 \s_@@_stop - { { gray } { \@@_parse_number:n {#1} } } -\cs_new:Npn \@@_parse_model_rgb:w #1 , #2 , #3 , #4 \s_@@_stop - { - { rgb } - { - \@@_parse_number:n {#1} ~ - \@@_parse_number:n {#2} ~ - \@@_parse_number:n {#3} - } - } -\cs_new:Npn \@@_parse_model_cmyk:w #1 , #2 , #3 , #4 , #5 \s_@@_stop - { - { cmyk } - { - \@@_parse_number:n {#1} ~ - \@@_parse_number:n {#2} ~ - \@@_parse_number:n {#3} ~ - \@@_parse_number:n {#4} - } - } -\cs_new:Npn \@@_parse_number:n #1 - { \@@_parse_number:w #1 . 0 . \s_@@_stop } -\cs_new:Npn \@@_parse_number:w #1 . #2 . #3 \s_@@_stop - { \tl_if_blank:nTF {#1} { 0 } {#1} . #2 } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}[EXP] -% { -% \@@_parse_model_Gray:w, \@@_parse_model_hsb:w, -% \@@_parse_model_Hsb:w, \@@_parse_model_HSB:w, -% \@@_parse_model_HTML:w, \@@_parse_model_RGB:w -% } -% \begin{macro}[EXP]{\@@_parse_model_hsb:nnn, \@@_parse_model_hsb_aux:nnn} -% \begin{macro}[EXP]{\@@_parse_model_hsb:nnnn} -% \begin{macro}[EXP]{\@@_parse_model_hsb:nnnnn} -% \begin{macro}[EXP] -% { -% \@@_parse_model_hsb_0:nnnn , -% \@@_parse_model_hsb_1:nnnn , -% \@@_parse_model_hsb_2:nnnn , -% \@@_parse_model_hsb_3:nnnn , -% \@@_parse_model_hsb_4:nnnn , -% \@@_parse_model_hsb_5:nnnn -% } -% \begin{macro}[EXP]{\@@_parse_model_wave:w} -% \begin{macro}[EXP] -% {\@@_parse_model_wave_auxi:nn, \@@_parse_model_wave_auxii:nn} -% \begin{macro}[EXP]{\@@_parse_model_wave_rho:n} -% \begin{macrocode} -\cs_new:Npn \@@_parse_model_Gray:w #1 , #2 \s_@@_stop - { { gray } { \fp_eval:n { #1 / 15 } } } -\cs_new:Npn \@@_parse_model_hsb:w #1 , #2 , #3 , #4 \s_@@_stop - { \@@_parse_model_hsb:nnn {#1} {#2} {#3} } -\cs_new:Npn \@@_parse_model_Hsb:w #1 , #2 , #3 , #4 \s_@@_stop - { - \exp_args:Ne \@@_parse_model_hsb:nnn { \fp_eval:n { #1 / 360 } } - {#2} {#3} - } -% \end{macrocode} -% The conversion here is non-trivial but is described at length -% in the \pkg{xcolor} manual. For ease, we calculate the integer -% and fractional parts of the hue first, then use them to work out the -% possible values for $r$, $g$ and $b$ before putting them in the correct -% places. -% \begin{macrocode} -\cs_new:Npn \@@_parse_model_hsb:nnn #1#2#3 - { - { rgb } - { - \exp_args:Ne \@@_parse_model_hsb_aux:nnn - { \fp_eval:n { 6 * #1 } } {#2} {#3} - } - } -\cs_new:Npn \@@_parse_model_hsb_aux:nnn #1#2#3 - { - \exp_args:Nee \@@_parse_model_hsb_aux:nnnn - { \fp_eval:n { floor(#1) } } { \fp_eval:n { #1 - floor(#1) } } - {#2} {#3} - } -\cs_new:Npn \@@_parse_model_hsb_aux:nnnn #1#2#3#4 - { - \use:e - { - \exp_not:N \@@_parse_model_hsb_aux:nnnnn - { \@@_parse_number:n {#4} } - { \fp_eval:n { round(#4 * (1 - #3) ,5) } } - { \fp_eval:n { round(#4 * ( 1 - #3 * #2 ) ,5) } } - { \fp_eval:n { round(#4 * ( 1 - #3 * (1 - #2) ) ,5) } } - {#1} - } - } -\cs_new:Npn \@@_parse_model_hsb_aux:nnnnn #1#2#3#4#5 - { \use:c { @@_parse_model_hsb_ #5 :nnnn } {#1} {#2} {#3} {#4} } -\cs_new:cpn { @@_parse_model_hsb_0:nnnn } #1#2#3#4 { #1 ~ #4 ~ #2 } -\cs_new:cpn { @@_parse_model_hsb_1:nnnn } #1#2#3#4 { #3 ~ #1 ~ #2 } -\cs_new:cpn { @@_parse_model_hsb_2:nnnn } #1#2#3#4 { #2 ~ #1 ~ #4 } -\cs_new:cpn { @@_parse_model_hsb_3:nnnn } #1#2#3#4 { #2 ~ #3 ~ #1 } -\cs_new:cpn { @@_parse_model_hsb_4:nnnn } #1#2#3#4 { #4 ~ #2 ~ #1 } -\cs_new:cpn { @@_parse_model_hsb_5:nnnn } #1#2#3#4 { #1 ~ #2 ~ #3 } -\cs_new:cpn { @@_parse_model_hsb_6:nnnn } #1#2#3#4 { #1 ~ #2 ~ #2 } -\cs_new:Npn \@@_parse_model_HSB:w #1 , #2 , #3 , #4 \s_@@_stop - { - \exp_args:Neee \@@_parse_model_hsb:nnn - { \fp_eval:n {#1 / 240} } - { \fp_eval:n {#2 / 240} } - { \fp_eval:n {#3 / 240} } - } -\cs_new:Npn \@@_parse_model_HTML:w #1 , #2 \s_@@_stop - { \@@_parse_model_HTML_aux:w #1 0 0 0 0 0 0 \s_@@_stop } -\cs_new:Npn \@@_parse_model_HTML_aux:w #1#2#3#4#5#6#7 \s_@@_stop - { - { rgb } - { - \fp_eval:n { round(\int_from_hex:n {#1#2} / 255,5) } ~ - \fp_eval:n { round(\int_from_hex:n {#3#4} / 255,5) } ~ - \fp_eval:n { round(\int_from_hex:n {#5#6} / 255,5) } - } - } -\cs_new:Npn \@@_parse_model_RGB:w #1 , #2 , #3 , #4 \s_@@_stop - { - { rgb } - { - \fp_eval:n { round(#1 / 255,5) } ~ - \fp_eval:n { round(#2 / 255,5) } ~ - \fp_eval:n { round(#3 / 255,5) } - } - } -% \end{macrocode} -% Following the description in the \pkg{xcolor} manual. As we always use |rgb|, -% there is no need to find the sixth, we just pas the information straight -% to the |hsb| auxiliary defined earlier. -% \begin{macrocode} -\cs_new:Npn \@@_parse_model_wave:w #1 , #2 \s_@@_stop - { - { rgb } - { - \fp_compare:nNnTF {#1} < { 420 } - { \@@_parse_model_wave_auxi:nn {#1} { 0.3 + 0.7 * (#1 - 380) / 40 } - } - { - \fp_compare:nNnTF {#1} > { 700 } - { \@@_parse_model_wave_auxi:nn {#1} { 0.3 + 0.7 * (#1 - 780) / -80 } } - { \@@_parse_model_wave_auxi:nn {#1} { 1 } } - } - } - } -\cs_new:Npn \@@_parse_model_wave_auxi:nn #1#2 - { - \fp_compare:nNnTF {#1} < { 440 } - { - \@@_parse_model_wave_auxii:nn - { 4 + \@@_parse_model_wave_rho:n { (#1 - 440) / -60 } } - {#2} - } - { - \fp_compare:nNnTF {#1} < { 490 } - { - \@@_parse_model_wave_auxii:nn - { 4 - \@@_parse_model_wave_rho:n { (#1 - 440) / 50 } } - {#2} - } - { - \fp_compare:nNnTF {#1} < { 510 } - { - \@@_parse_model_wave_auxii:nn - { 2 + \@@_parse_model_wave_rho:n { (#1 - 510) / -20 } } - {#2} - } - { - \fp_compare:nNnTF {#1} < { 580 } - { - \@@_parse_model_wave_auxii:nn - { 2 - \@@_parse_model_wave_rho:n { (#1 - 510) / 70 } } - {#2} - } - { - \fp_compare:nNnTF {#1} < { 645 } - { - \@@_parse_model_wave_auxii:nn - { \@@_parse_model_wave_rho:n { (#1 - 645) / -65 } } - {#2} - } - { \@@_parse_model_wave_auxii:nn { 0 } {#2} } - } - } - } - } - } -\cs_new:Npn \@@_parse_model_wave_auxii:nn #1#2 - { - \exp_args:Neee \@@_parse_model_hsb_aux:nnn - { \fp_eval:n {#1} } - { 1 } - { \@@_parse_model_wave_rho:n {#2} } - } -\cs_new:Npn \@@_parse_model_wave_rho:n #1 - { \fp_eval:n { min(1, max(0,#1) ) } } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \subsection{Selecting colors (and color models)} -% -% \begin{variable}{\l_color_fixed_model_tl} -% For selecting a single fixed model. -% \begin{macrocode} -\tl_new:N \l_color_fixed_model_tl -% \end{macrocode} -% \end{variable} -% -% \begin{macro}{\@@_check_model:N} -% \begin{macro}{\@@_check_model:nn} -% Check that the model in use is the one required. -% \begin{macrocode} -\cs_new_protected:Npn \@@_check_model:N #1 - { - \tl_if_empty:NF \l_color_fixed_model_tl - { - \exp_after:wN \@@_check_model:nn #1 - \tl_if_eq:NNF \l_@@_model_tl \l_color_fixed_model_tl - { - \@@_convert:VVN \l_@@_model_tl \l_color_fixed_model_tl - \l_@@_value_tl - } - \tl_set:Nx #1 - { { \l_color_fixed_model_tl } { \l_@@_value_tl } } - } - } -\cs_new_protected:Npn \@@_check_model:nn #1#2 - { - \tl_set:Nn \l_@@_model_tl {#1} - \tl_set:Nn \l_@@_value_tl {#2} - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\@@_select:} -% A backend-neutral location for \enquote{last minute} manipulations before -% handing off to the backend code. We set the special |.| syntax here: this -% will therefore always be available. The finalisation is separate from the -% main function so it can also be applied to \emph{e.g.}~page color. -% \begin{macrocode} -\cs_new_protected:Npx \@@_select: - { - \tl_set:Nx \exp_not:c { l_@@_named_ . _tl } - { \exp_not:N \@@_model:N \exp_not:N \l_@@_current_tl } - \prop_clear:N \exp_not:c { l_@@_named_ . _prop } - \prop_put:NVx \exp_not:c { l_@@_named_ . _prop } - \exp_not:c { l_@@_named_ . _tl } - { \exp_not:N \@@_values:N \exp_not:N \l_@@_current_tl } - \@@_select:N \exp_not:N \l_@@_current_tl - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\color_select:n} -% \begin{macro}{\color_select:nn} -% \begin{macro}{\@@_select_main:Nw, \@@_select_loop:Nw} -% \begin{macro}{\@@_select:nnN} -% \begin{macro}{\@@_select_swap:Nnn} -% Parse the input expressions then get the backend to actually activate -% them. The main complexity here is the need to check through multiple models. -% That is done \enquote{locally} here as the approach is subtly different to -% when different models are being stored. -% \begin{macrocode} -\cs_new_protected:Npn \color_select:n #1 - { - \@@_parse:nN {#1} \l_@@_current_tl - \@@_select: - } -\cs_new_protected:Npn \color_select:nn #1#2 - { - \@@_select_main:Nw \l_@@_current_tl - #1 / / \s_@@_mark #2 / / \s_@@_stop - \@@_select: - } -% \end{macrocode} -% If the first color model is the fixed one, or if there is no fixed -% model, we don't need most of the data: just set up and apply the backend -% function. -% \begin{macrocode} -\cs_new_protected:Npn \@@_select_main:Nw - #1 #2 / #3 / #4 \s_@@_mark #5 / #6 / #7 \s_@@_stop - { - \@@_select:nnN {#2} {#5} #1 - \bool_lazy_or:nnF - { \tl_if_empty_p:N \l_color_fixed_model_tl } - { \str_if_eq_p:nV {#2} \l_color_fixed_model_tl } - { \@@_select_loop:Nw #1 #3 / #4 \s_@@_mark #6 / #7 \s_@@_stop } - } -% \end{macrocode} -% If a fixed model applies, we need to check each possible value in order. -% If there is no hit at all, fall back on the generic formula-based -% interchange. -% \begin{macrocode} -\cs_new_protected:Npn \@@_select_loop:Nw - #1 #2 / #3 \s_@@_mark #4 / #5 \s_@@_stop - { - \str_if_eq:nVTF {#2} \l_color_fixed_model_tl - { \@@_select:nnN {#2} {#4} #1 } - { - \tl_if_blank:nTF {#2} - { \exp_after:wN \@@_select_swap:Nnn \exp_after:wN #1 #1 } - { \@@_select_loop:Nw #1 #3 \s_@@_mark #5 \s_@@_stop } - } - } -\cs_new_protected:Npn \@@_select:nnN #1#2#3 - { - \cs_if_exist:cTF { @@_parse_model_ #1 :w } - { - \tl_set:Nx #3 - { \use:c { @@_parse_model_ #1 :w } #2 , 0 , 0 , 0 , 0 \s_@@_stop } - } - { \__kernel_msg_error:nnn { color } { unknown-model } {#1} } - } -\cs_new_protected:Npn \@@_select_swap:Nnn #1#2#3 - { - \@@_convert:nVnN {#2} \l_color_fixed_model_tl {#3} \l_@@_value_tl - \tl_set:Nx #1 - { { \l_color_fixed_model_tl } { \l_@@_value_tl } } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \subsection{Fill and stroke color} -% -% \begin{macro}{\color_fill:n, \color_stroke:n} -% \begin{macro}{\color_fill:nn, \color_stroke:nn} -% \begin{macro}{\@@_draw:nnn} -% \begin{macrocode} -\cs_new_protected:Npn \color_fill:n #1 - { - \@@_parse:nN {#1} \l_@@_current_tl - \exp_after:wN \@@_draw:nnn \l_@@_current_tl { fill } - } -\cs_new_protected:Npn \color_stroke:n #1 - { - \@@_parse:nN {#1} \l_@@_current_tl - \exp_after:wN \@@_draw:nnn \l_@@_current_tl { stroke } - } -\cs_new_protected:Npn \color_fill:nn #1#2 - { - \@@_select_main:Nw \l_@@_current_tl - #1 / / \s_@@_mark #2 / / \s_@@_stop - \exp_after:wN \@@_draw:nnn \l_@@_current_tl { fill } - } -\cs_new_protected:Npn \color_stroke:nn #1#2 - { - \@@_select_main:Nw \l_@@_current_tl - #1 / / \s_@@_mark #2 / / \s_@@_stop - \exp_after:wN \@@_draw:nnn \l_@@_current_tl { stroke } - } -\cs_new_protected:Npn \@@_draw:nnn #1#2#3 - { \use:c { @@_backend_ #3 _ #1 :n } {#2} } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \subsection{Defining named colors} -% -% \begin{variable}{\l_@@_named_tl} -% Space to store the detail of the named color. -% \begin{macrocode} -\tl_new:N \l_@@_named_tl -% \end{macrocode} -% \end{variable} -% -% \begin{macro}{\color_set:nn} -% \begin{macro}{\@@_set:nnn} -% \begin{macro}{\@@_set:nn} -% \begin{macro}{\@@_set:nnw} -% \begin{macro}{\color_set:nnn} -% \begin{macro}{\@@_set_colon:nnw} -% \begin{macro}{\@@_set_loop:nw} -% \begin{macro}{\color_set_eq:nn} -% Defining named colors means working through the model list and saving -% both the \enquote{main} color and any equivalents in other models. Even -% if there is only one model, we store a |prop| as well as a |tl|, as there -% could be grouping weirdness, etc. When setting using an expression, -% we need to avoid any fixed model issues, which is done without a group as -% in \pkg{l3keys}. -% \begin{macrocode} -\cs_new_protected:Npn \color_set:nn #1#2 - { - \exp_args:NV \@@_set:nnn - \l_color_fixed_model_tl {#1} {#2} - } -\cs_new_protected:Npn \@@_set:nnn #1#2#3 - { - \tl_clear:N \l_color_fixed_model_tl - \@@_set:nn {#2} {#3} - \tl_set:Nn \l_color_fixed_model_tl {#1} - } -\cs_new_protected:Npn \@@_set:nn #1#2 - { - \str_if_eq:nnF {#1} { . } - { - \@@_parse:nN {#2} \l_@@_named_tl - \tl_clear_new:c { l_@@_named_ #1 _tl } - \tl_set:cx { l_@@_named_ #1 _tl } - { \@@_model:N \l_@@_named_tl } - \prop_clear_new:c { l_@@_named_ #1 _prop } - \prop_put:cvx { l_@@_named_ #1 _prop } { l_@@_named_ #1 _tl } - { \@@_values:N \l_@@_named_tl } - \@@_set:nnw {#1} {#2} #2 ! \s_@@_stop - } - } -% \end{macrocode} -% When setting an expression-based color, there could be multiple model -% data available for one or more of the input colors. Where that is true for -% the \emph{first} named color in an expression, we re-parse the expression -% when they are also parameter-based: only |cmyk|, |gray| and |rgb| make -% any sense here. There is a bit of a performance hit but this should be -% rare and taking place during set-up. -% \begin{macrocode} -\cs_new_protected:Npn \@@_set:nnw #1#2#3 ! #4 \s_@@_stop - { - \clist_map_inline:nn { cmyk , gray , rgb } - { - \prop_get:cnNT { l_@@_named_ #3 _prop } {##1} \l_@@_internal_tl - { - \prop_if_in:cnF { l_@@_named_ #1 _prop } {##1} - { - \group_begin: - \tl_set:cn { l_@@_named_ #3 _tl } {##1} - \@@_parse:nN {#2} \l_@@_internal_tl - \exp_args:NNNV \group_end: - \tl_set:Nn \l_@@_internal_tl \l_@@_internal_tl - \prop_put:cxx { l_@@_named_ #1 _prop } - { \@@_model:N \l_@@_internal_tl } - { \@@_values:N \l_@@_internal_tl } - } - } - } - } -\cs_new_protected:Npx \color_set:nnn #1#2#3 - { - \exp_not:N \str_if_eq:nnF {#1} { . } - { - \tl_clear_new:c { l_@@_named_ #1 _tl } - \prop_clear_new:c { l_@@_named_ #1 _prop } - \exp_not:N \@@_set_colon:nnw {#1} {#3} - #2 \c_colon_str \c_colon_str \exp_not:N \s_@@_stop - } - } -\use:x - { - \cs_new_protected:Npn \exp_not:N \@@_set_colon:nnw - ##1##2 ##3 \c_colon_str ##4 \c_colon_str - ##5 \exp_not:N \s_@@_stop - } - { - \tl_if_blank:nTF {#4} - { \@@_set_loop:nw {#1} #3 } - { \@@_set_loop:nw {#1} #4 } - / / \s_@@_mark #2 / / \s_@@_stop - } -\cs_new_protected:Npn \@@_set_loop:nw - #1#2 / #3 \s_@@_mark #4 / #5 \s_@@_stop - { - \tl_if_blank:nF {#2} - { - \@@_select:nnN {#2} {#4} \l_@@_named_tl - \tl_set:Nx \l_@@_internal_tl { \@@_model:N \l_@@_named_tl } - \tl_if_empty:cT { l_@@_named_ #1 _tl } - { \tl_set_eq:cN { l_@@_named_ #1 _tl } \l_@@_internal_tl } - \prop_put:cVx { l_@@_named_ #1 _prop } \l_@@_internal_tl - { \@@_values:N \l_@@_named_tl } - \@@_set_loop:nw {#1} #3 \s_@@_mark #5 \s_@@_stop - } - } -\cs_new_protected:Npn \color_set_eq:nn #1#2 - { - \@@_if_defined:nTF {#2} - { - \tl_clear_new:c { l_@@_named_ #1 _tl } - \prop_clear_new:c { l_@@_named_ #1 _prop } - \str_if_eq:nnTF {#2} { . } - { - \tl_set:cx { l_@@_named_ #1 _tl } - { \@@_model:N \l_@@_current_tl } - \prop_put:cvx { l_@@_named_ #1 _prop } { l_@@_named_ #1 _tl } - { \@@_values:N \l_@@_current_tl } - } - { - \tl_set_eq:cc { l_@@_named_ #1 _tl } { l_@@_named_ #2 _tl } - \prop_set_eq:cc { l_@@_named_ #1 _prop } { l_@@_named_ #2 _prop } - } - } - { - \__kernel_msg_error:nnn { color } { unknown-color } {#2} - } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% A small set of colors are always defined. -% \begin{macrocode} -\color_set:nnn { black } { gray } { 0 } -\color_set:nnn { white } { gray } { 1 } -\color_set:nnn { cyan } { cmyk } { 1 , 0 , 0 , 0 } -\color_set:nnn { magenta } { cmyk } { 0 , 1 , 0 , 0 } -\color_set:nnn { yellow } { cmyk } { 0 , 0 , 1 , 0 } -\color_set:nnn { red } { rgb } { 1 , 0 , 0 } -\color_set:nnn { green } { rgb } { 0 , 1 , 0 } -\color_set:nnn { blue } { rgb } { 0 , 0 , 1 } -% \end{macrocode} -% -% \begin{variable}{\l_@@_named_._prop, \l_@@_named_._tl} -% A special named color: this is always defined though not fixed in -% definition. -% \begin{macrocode} -\prop_new:c { l_@@_named_._prop } -\tl_new:c { l_@@_named_._tl } -\tl_set:cx { l_@@_named_._tl } { \@@_model:N \l_@@_current_tl } -% \end{macrocode} -% \end{variable} -% -% \subsection{Exporting colors} -% -% \begin{macro}{\color_export:nnN} -% \begin{macro}{\color_export:nnnN} -% \begin{macro}{\@@_export:nN} -% \begin{macro}{\@@_export:nnnN} -% \begin{macrocode} -\cs_new_protected:Npn \color_export:nnN #1#2#3 - { - \group_begin: - \tl_if_exist:cT { c_@@_export_ #2 _tl } - { \tl_set_eq:Nc \l_color_fixed_model_tl { c_@@_export_ #2 _tl } } - \@@_parse:nN {#1} #3 - \@@_export:nN {#2} #3 - \exp_args:NNNV \group_end: - \tl_set:Nn #3 #3 - } -\cs_new_protected:Npn \color_export:nnnN #1#2#3#4 - { - \@@_select_main:Nw #4 - #1 / / \s_@@_mark #2 / / \s_@@_stop - \@@_export:nN {#3} #4 - } -\cs_new_protected:Npn \@@_export:nN #1#2 - { \exp_after:wN \@@_export:nnnN #2 {#1} #2 } -\cs_new:Npn \@@_export:nnnN #1#2#3#4 - { - \cs_if_exist_use:cF { @@_export_format_ #3 :nnN } - { - \__kernel_msg_error:nnn { color } { unknown-export-format } {#3} - \use_none:nnn - } - {#1} {#2} #4 - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\@@_export_format_backend:nnN} -% Simple. -% \begin{macrocode} -\cs_new_protected:Npn \@@_export_format_backend:nnN #1#2#3 - { \tl_set:Nn #3 { {#1} {#2} } } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_export:nnnNN} -% A generic auxiliary for cases where only one model is appropriate. -% \begin{macrocode} -\cs_new_protected:Npn \@@_export:nnnNN #1#2#3#4#5 - { - \str_if_eq:nnTF {#2} {#1} - { #5 #4 #3 \s_@@_stop } - { - \@@_convert:nnnN {#2} {#1} {#3} #4 - \exp_after:wN #5 \exp_after:wN #4 - #4 \s_@@_stop - } - } -% \end{macrocode} -% \end{macro} -% -% \begin{variable} -% { -% \c_@@_export_HTML_tl , -% \c_@@_export_space-sep-cmyk_tl , -% \c_@@_export_space-sep-rgb_tl -% } -% \begin{macrocode} -\tl_const:Nn \c_@@_export_HTML_tl { rgb } -\tl_const:cn { c_@@_export_space-sep-cmyk_tl } { cmyk } -\tl_const:cn { c_@@_export_space-sep-rgb_tl } { rgb } -% \end{macrocode} -% \end{variable} -% -% \begin{macro}{\@@_export_format_space-sep-cmyk:nnN} -% \begin{macro}{\@@_export_space-sep-cmyk:Nw} -% \begin{macrocode} -\cs_new_protected:cpx { @@_export_format_space-sep-cmyk:nnN } #1#2#3 - { - \exp_not:N \@@_export:nnnNN { cmyk } {#1} {#2} #3 - \exp_not:c { @@_export_space-sep-cmyk:Nw } - } -\cs_new_protected:cpn { @@_export_space-sep-cmyk:Nw } #1#2 \s_@@_stop - { \tl_set:Nx #1 {#2} } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro} -% { -% \@@_export_format_HTML:nnN , -% \@@_export_format_space-sep-rgb:nnN -% } -% \begin{macro} -% { -% \@@_export_HTML:Nw , -% \@@_export_space-sep-rgb:Nw -% } -% \begin{macro}[EXP]{\@@_export_HTML:n} -% \textsc{html} values must be given in |rgb|: we force conversion if -% required, then do some simple maths. -% \begin{macrocode} -\cs_new_protected:Npn \@@_export_format_HTML:nnN #1#2#3 - { \@@_export:nnnNN { rgb } {#1} {#2}#3 \@@_export_HTML:Nw } -\cs_new_protected:cpx { @@_export_format_space-sep-rgb:nnN } #1#2#3 - { - \exp_not:N \@@_export:nnnNN { rgb } {#1} {#2} #3 - \exp_not:c { @@_export_space-sep-rgb:Nw } - } -\cs_new_protected:Npn \@@_export_HTML:Nw #1#2 ~ #3 ~ #4 \s_@@_stop - { - \tl_set:Nx #1 - { - \@@_export_HTML:n {#2} - \@@_export_HTML:n {#3} - \@@_export_HTML:n {#4} - } - } -\cs_new:Npn \@@_export_HTML:n #1 - { - \fp_compare:nNnTF {#1} = { 0 } - { 00 } - { \int_to_Hex:n { \fp_to_int:n { #1 * 255 } } } - } -\cs_new_protected:cpn { @@_export_space-sep-rgb:Nw } #1#2 \s_@@_stop - { \tl_set:Nx #1 {#2} } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \subsection{Additional color models} -% -% \begin{variable}{\l_@@_internal_prop} -% \begin{macrocode} -\prop_new:N \l_@@_internal_prop -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\g_@@_model_int} -% A tracker for the total number of new models. -% \begin{macrocode} -\int_new:N \g_@@_model_int -% \end{macrocode} -% \end{variable} -% -% \begin{variable} -% {\c_@@_fallback_cmyk_tl, \c_@@_fallback_gray_tl, \c_@@_fallback_rgb_tl} -% Conversion from Separation or DeviceN spaces may not be possible; have -% a fallback to black. -% \begin{macrocode} -\tl_const:Nn \c_@@_fallback_cmyk_tl { 0 ~ 0 ~ 0 ~ 1 } -\tl_const:Nn \c_@@_fallback_gray_tl { 1 } -\tl_const:Nn \c_@@_fallback_rgb_tl { 1 ~ 1 ~ 1 } -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\g_@@_colorants_prop} -% Mapping from names to colorants. -% \begin{macrocode} -\prop_new:N \g_@@_colorants_prop -\prop_gput:Nnn \g_@@_colorants_prop { black } { Black } -\prop_gput:Nnn \g_@@_colorants_prop { blue } { Blue } -\prop_gput:Nnn \g_@@_colorants_prop { cyan } { Cyan } -\prop_gput:Nnn \g_@@_colorants_prop { green } { Green } -\prop_gput:Nnn \g_@@_colorants_prop { magenta } { Magenta } -\prop_gput:Nnn \g_@@_colorants_prop { none } { None } -\prop_gput:Nnn \g_@@_colorants_prop { red } { Red } -\prop_gput:Nnn \g_@@_colorants_prop { yellow } { Yellow } -% \end{macrocode} -% \end{variable} -% -% \begin{variable} -% { -% \c_@@_model_whitepoint_CIELAB_a_tl , -% \c_@@_model_whitepoint_CIELAB_b_tl , -% \c_@@_model_whitepoint_CIELAB_e_tl , -% \c_@@_model_whitepoint_CIELAB_d50_tl , -% \c_@@_model_whitepoint_CIELAB_d55_tl , -% \c_@@_model_whitepoint_CIELAB_d65_tl , -% \c_@@_model_whitepoint_CIELAB_d75_tl -% } -% Whitepoint data for the CIELAB profiles. -% \begin{macrocode} -\tl_const:Nn \c_@@_model_whitepoint_CIELAB_a_tl { 1.0985 ~ 1 ~ 0.3558 } -\tl_const:Nn \c_@@_model_whitepoint_CIELAB_b_tl { 0.9807 ~ 1 ~ 1.1822 } -\tl_const:Nn \c_@@_model_whitepoint_CIELAB_e_tl { 1 ~ 1 ~ 1 } -\tl_const:cn { c_@@_model_whitepoint_CIELAB_d50_tl } { 0.9642 ~ 1 ~ 0.8251 } -\tl_const:cn { c_@@_model_whitepoint_CIELAB_d55_tl } { 0.9568 ~ 1 ~ 0.9214 } -\tl_const:cn { c_@@_model_whitepoint_CIELAB_d65_tl } { 0.9504 ~ 1 ~ 1.0888 } -\tl_const:cn { c_@@_model_whitepoint_CIELAB_d75_tl } { 0.9497 ~ 1 ~ 1.2261 } -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\c_@@_model_range_CIELAB_tl} -% The range for CIELAB color spaces. -% \begin{macrocode} -\tl_const:Nn \c_@@_model_range_CIELAB_tl { 0 ~ 100 ~ -128 ~ 127 ~ -128 ~ 127 } -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\g_@@_alternative_model_prop} -% For tracking the alternative model set up for separations, etc. -% \begin{macrocode} -\prop_new:N \g_@@_alternative_model_prop -\clist_map_inline:nn { cyan , magenta , yellow , black } - { \prop_gput:Nnn \g_@@_alternative_model_prop {#1} { cmyk } } -\clist_map_inline:nn { red , green , blue } - { \prop_gput:Nnn \g_@@_alternative_model_prop {#1} { rgb } } -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\g_@@_alternative_values_prop} -% Same for the values: a bit more involved. -% \begin{macrocode} -\prop_new:N \g_@@_alternative_values_prop -\prop_gput:Nnn \g_@@_alternative_values_prop { cyan } { 1 , 0 , 0 , 0 } -\prop_gput:Nnn \g_@@_alternative_values_prop { magenta } { 0 , 1 , 0 , 0 } -\prop_gput:Nnn \g_@@_alternative_values_prop { yellow } { 0 , 0 , 1 , 0 } -\prop_gput:Nnn \g_@@_alternative_values_prop { black } { 0 , 0 , 0 , 1 } -\prop_gput:Nnn \g_@@_alternative_values_prop { red } { 1 , 0 , 0 } -\prop_gput:Nnn \g_@@_alternative_values_prop { green } { 0 , 1 , 0 } -\prop_gput:Nnn \g_@@_alternative_values_prop { blue } { 0 , 0 , 1 } -% \end{macrocode} -% \end{variable} -% -% \begin{macro}{\color_model_new:nnn, \@@_model_new:nnn} -% Set up a new model: in general this has to be handled by a family-dependent -% function. To avoid some \enquote{interesting} questions with casing, we -% fold the case of the family name. The key--value list should always be -% present, so we convert it up-front to a |prop|, then deal with the detail -% on a per-family basis. -% \begin{macrocode} -\cs_new_protected:Npn \color_model_new:nnn #1#2#3 - { - \exp_args:Nee \@@_model_new:nnn - { \tl_to_str:n {#1} } - { \str_foldcase:n {#2} } {#3} - } -\cs_new_protected:Npn \@@_model_new:nnn #1#2#3 - { - \cs_if_exist:cTF { @@_parse_model_ #1 :w } - { - \__kernel_msg_error:nnn { color } { model-already-defined } {#1} - } - { - \cs_if_exist:cTF { @@_model_ #2 :n } - { - \prop_set_from_keyval:Nn \l_@@_internal_prop {#3} - \use:c { @@_model_ #2 :n } {#1} - } - { - \__kernel_msg_error:nnn { color } { unknown-model-type } {#2} - } - } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_model_separation:n} -% \begin{macro}{\@@_model_separation:nn} -% \begin{macro}{\@@_model_separation:nnn} -% \begin{macro}{\@@_model_separation:w} -% \begin{macro} -% { -% \@@_model_separation_cmyk:nnnnnn , -% \@@_model_separation_gray:nnnnnn , -% \@@_model_separation_rgb:nnnnnn -% } -% \begin{macro}{\@@_model_convert:nnn} -% \begin{macro}{\@@_model_separation_CIELAB:nnnnnn} -% \begin{macro}{\@@_model_separation_CIELAB:nnnnnnn} -% Separations must have a \enquote{real} name, which is pretty easy to find. -% \begin{macrocode} -\cs_new_protected:Npn \@@_model_separation:n #1 - { - \prop_get:NnNTF \l_@@_internal_prop { name } - \l_@@_internal_tl - { - \exp_args:NV \@@_model_separation:nn - \l_@@_internal_tl {#1} - } - { - \__kernel_msg_error:nnn { color } - { separation-requires-name } {#1} - } - } -% \end{macrocode} -% We have two keys to find at this stage: the alternative space model -% and linked values. -% \begin{macrocode} -\cs_new_protected:Npn \@@_model_separation:nn #1#2 - { - \prop_get:NnNTF \l_@@_internal_prop { alternative-model } - \l_@@_internal_tl - { - \exp_args:NV \@@_model_separation:nnn - \l_@@_internal_tl {#2} {#1} - } - { - \__kernel_msg_error:nnn { color } - { separation-alternative-model } {#2} - } - } -\cs_new_protected:Npn \@@_model_separation:nnn #1#2#3 - { - \cs_if_exist:cTF { @@_model_separation_ #1 :nnnnnn } - { - \prop_get:NnNTF \l_@@_internal_prop { alternative-values } - \l_@@_internal_tl - { - \exp_after:wN \@@_model_separation:w \l_@@_internal_tl - , 0 , 0 , 0 , 0 \s_@@_stop {#2} {#3} {#1} - } - { - \__kernel_msg_error:nnn { color } - { separation-alternative-values } {#2} - } - } - { - \__kernel_msg_error:nnn { color } - { unknown-alternative-model } {#1} - } - } -% \end{macrocode} -% As each alternative space leads to a different requirement for conversion, -% and as there are only a small number of choices, we manually split the data -% and then set up. Notice that mixing tints is really just the same -% as mixing \texttt{gray}. The \texttt{white} color is special, as it allows -% tints to be adjusted without an additional color space. To make sure the -% data is set for that at all group levels, we need to work on a per-level -% basis. Within the output, only the set-up needs the \enquote{real} name -% of the colorspace: we use a simple tracking number for general usage -% as this is a clear namespace without issues of escaping chars. -% \begin{macrocode} -\cs_new_protected:Npn \@@_model_separation:w - #1 , #2 , #3 , #4 , #5 \s_@@_stop #6#7#8 - { - \int_gincr:N \g_@@_model_int - \tl_const:cn { c_@@_fallback_ #6 _tl } { 1 } - \cs_new_eq:cN { @@_parse_mix_ #6 :nw } \@@_parse_mix_gray:nw - \cs_new:cpn { @@_parse_model_ #6 :w } ##1 , ##2 \s_@@_stop - { {#6} { \@@_parse_number:n {##1} } } - \clist_map_inline:nn { fill , stroke , select } - { - \cs_new_protected:cpx { @@_backend_ ##1 _ #6 :n } ####1 - { - \exp_not:c { @@_backend_ ##1 _ separation:nn } - { color \int_use:N \g_@@_model_int } {####1} - } - } - \use:c { @@_model_separation_ #8 :nnnnnn } - {#6} {#7} {#1} {#2} {#3} {#4} - \prop_gput:Nnn \g_@@_alternative_model_prop {#6} {#8} - \prop_gput:Nnx \g_@@_colorants_prop {#6} - { \str_convert_pdfname:n {#7} } - \cs_new_protected:cpx { @@_model_ #6 _white: } - { - \prop_put:Nnn \exp_not:N \l_@@_named_white_prop {#6} { 0 } - \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0 - { \group_insert_after:N \exp_not:c { @@_model_ #6 _ white: } } - } - \use:c { @@_model_ #6 _white: } - } -\cs_new_protected:Npn \@@_model_separation_cmyk:nnnnnn #1#2#3#4#5#6 - { - \cs_new:cpn { @@_convert_ #1 _cmyk:w } ##1 ~ ##2 \s_@@_stop - { - \fp_eval:n {##1 * #3} ~ - \fp_eval:n {##1 * #4} ~ - \fp_eval:n {##1 * #5} ~ - \fp_eval:n {##1 * #6} - } - \@@_model_convert:nnn {#1} { cmyk } { rgb } - \@@_model_convert:nnn {#1} { cmyk } { gray } - \prop_gput:Nnn \g_@@_alternative_values_prop {#1} { #3 , #4 , #5 , #6 } - \@@_backend_separation_init:nnnnn {#2} { /DeviceCMYK } { } - { 0 ~ 0 ~ 0 ~ 0 } { #3 ~ #4 ~ #5 ~ #6 } - } -\cs_new_protected:Npn \@@_model_separation_rgb:nnnnnn #1#2#3#4#5#6 - { - \cs_new:cpn { @@_convert_ #1 _rgb:w } ##1 ~ ##2 \s_@@_stop - { - \fp_eval:n {##1 * #3} ~ - \fp_eval:n {##1 * #4} ~ - \fp_eval:n {##1 * #5} - } - \@@_model_convert:nnn {#1} { rgb } { cmyk } - \@@_model_convert:nnn {#1} { rgb } { gray } - \prop_gput:Nnn \g_@@_alternative_values_prop {#1} { #3 , #4 , #5 } - \@@_backend_separation_init:nnnnn {#2} { /DeviceRGB } { } - { 0 ~ 0 ~ 0 } { #3 ~ #4 ~ #5 } - } -\cs_new_protected:Npn \@@_model_separation_gray:nnnnnn #1#2#3#4#5#6 - { - \cs_new:cpn { @@_convert_ #1 _cmyk:w } ##1 ~ ##2 \s_@@_stop - { - \fp_eval:n {##1 * #3} ~ - \fp_eval:n {##1 * #3} ~ - \fp_eval:n {##1 * #3} ~ - \fp_eval:n {##1 * #3} - } - \cs_new:cpn { @@_convert_ #1 _gray:w } ##1 ~ ##2 \s_@@_stop - { \fp_eval:n {##1 * #3} } - \cs_new:cpn { @@_convert_ #1 _rgb:w } ##1 ~ ##2 \s_@@_stop - { - \fp_eval:n {##1 * #3} ~ - \fp_eval:n {##1 * #3} ~ - \fp_eval:n {##1 * #3} - } - \prop_gput:Nnn \g_@@_alternative_values_prop {#1} {#3} - \@@_backend_separation_init:nnnnn {#2} { /DeviceGray } { } { 0 } {#3} - } -% \end{macrocode} -% Generic model conversion \emph{via} an alternative intermediate. -% \begin{macrocode} -\cs_new_protected:Npn \@@_model_convert:nnn #1#2#3 - { - \cs_new:cpx { @@_convert_ #1 _ #3 :w } ##1 ~ ##2 \s_@@_stop - { - \exp_not:N \exp_args:NNe \exp_not:N \use:nn - \exp_not:c { @@_convert_ #2 _ #3 :w } - { \exp_not:c { @@_convert_ #1 _ #2 :w } ##1 ~ ##2 \s_@@_stop } - \c_space_tl \exp_not:N \s_@@_stop - } - } -% \end{macrocode} -% Setting up for CIELAB needs a bit more work: there is the illuminant and -% the need for an appropriate object. -% \begin{macrocode} -\cs_new_protected:Npn \@@_model_separation_CIELAB:nnnnnn #1#2#3#4#5#6 - { - \prop_get:NnNF \l_@@_internal_prop { illuminant } - \l_@@_internal_tl - { - \__kernel_msg_error:nnn { color } - { CIELAB-requires-illuminant } {#1} - \tl_set:Nn \l_@@_internal_tl { d50 } - } - \exp_args:NV \@@_model_separation_CIELAB:nnnnnnn - \l_@@_internal_tl {#1} {#2} {#3} {#4} {#5} {#6} - } -% \end{macrocode} -% If a CIELAB space is being set up, we need the illuminant, then create -% the appropriate set up. At present, this doesn't include \texttt{BlackPoint} -% or \texttt{Range} data, but that may be added later. As CIELAB colors -% cannot be converted to anything else, we fallback to producing black: the -% user should set up a second model for colors set up this way. -% \begin{macrocode} -\cs_new_protected:Npn \@@_model_separation_CIELAB:nnnnnnn #1#2#3#4#5#6#7 - { - \tl_if_exist:cTF { c_@@_model_whitepoint_CIELAB_ #1 _tl } - { - \@@_backend_separation_init_CIELAB:nnn {#1} {#3} { #4 ~ #5 ~ #6 } - \cs_new:cpn { @@_convert_ #2 _cmyk:w } ##1 ~ ##2 \s_@@_stop - { 0 ~ 0 ~ 0 ~ 1 } - \cs_new:cpn { @@_convert_ #2 _rgb:w } ##1 ~ ##2 \s_@@_stop - { 1 ~ 1 ~ 1 } - \cs_new:cpn { @@_convert_ #2 _gray:w } ##1 ~ ##2 \s_@@_stop - { 1 } - } - { - \__kernel_msg_error:nnn { color } - { unknown-CIELAB-illuminant } {#1} - } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\@@_model_devicen:n} -% \begin{macro}{\@@_model_devicen:nn} -% \begin{macro}{\@@_model_devicen:nnn} -% \begin{macro}{\@@_model_devicen:nnnn} -% \begin{macro} -% { -% \@@_model_devicen_parse_1:nn , -% \@@_model_devicen_parse_2:nn , -% \@@_model_devicen_parse_3:nn , -% \@@_model_devicen_parse_4:nn , -% \@@_model_devicen_parse_generic:nn -% } -% \begin{macro}[EXP]{\@@_model_devicen_parse:nw} -% \begin{macro}[EXP]{\@@_model_devicen_mix:nw} -% \begin{macro}{\@@_model_devicen_init:nnn} -% \begin{macro}{\@@_model_devicen_init:nnnn} -% \begin{macro}{\@@_model_devicen_tranform:w} -% \begin{macro} -% { -% \@@_model_devicen_tranform_1:nnnnn , -% \@@_model_devicen_tranform_3:nnnnn , -% \@@_model_devicen_tranform_4:nnnnn , -% } -% \begin{macro}{\@@_model_devicen_tranform:nnn} -% \begin{macro}[EXP]{\@@_model_devicen_colorant:n} -% \begin{macro}{\@@_model_devicen_convert:nnn} -% \begin{macro} -% { -% \@@_model_devicen_convert_cmyk:n , -% \@@_model_devicen_convert_gray:n , -% \@@_model_devicen_convert_rgb:n -% } -% \begin{macro}{\@@_model_devicen_convert:nnnn} -% \begin{macro}[EXP]{\@@_model_devicen_convert:n, \@@_model_devicen_convert_aux:n} -% \begin{macro}[EXP]{\@@_model_devicen_convert:w} -% \begin{macro}[EXP]{\@@_convert_devicen_cmyk:nnnnw} -% \begin{macro}[EXP]{\@@_convert_devicen_cmyk:nnnnnnnnn} -% \begin{macro}[EXP]{\@@_convert_devicen_cmyk_aux:nnnnw} -% \begin{macro}[EXP]{\@@_convert_devicen_gray:nw} -% \begin{macro}[EXP]{\@@_convert_devicen_gray:nnn} -% \begin{macro}[EXP]{\@@_convert_devicen_gray_aux:nw} -% \begin{macro}[EXP]{\@@_convert_devicen_rgb:nnnw} -% \begin{macro}[EXP]{\@@_convert_devicen_rgb:nnnnnnn} -% \begin{macro}[EXP]{\@@_convert_devicen_rgb_aux:nnnw} -% We require a list of component names here: one might call them colorants, -% but it's convenient to use \TeX{} names instead so we slightly adjust the -% terminology. -% \begin{macrocode} -\cs_new_protected:Npn \@@_model_devicen:n #1 - { - \prop_get:NnNTF \l_@@_internal_prop { names } - \l_@@_internal_tl - { - \exp_args:NV \@@_model_devicen:nn - \l_@@_internal_tl {#1} - } - { - \__kernel_msg_error:nnn { color } - { DeviceN-requires-names } {#1} - } - } -% \end{macrocode} -% All valid models will have an alternative listed, either hard-coded for -% the core device ones, or dynamically added for Separations, etc. -% \begin{macrocode} -\cs_new_protected:Npn \@@_model_devicen:nn #1#2 - { - \tl_clear:N \l_@@_model_tl - \clist_map_inline:nn {#1} - { - \prop_get:NnNTF \g_@@_alternative_model_prop {##1} - \l_@@_internal_tl - { - \tl_if_empty:NTF \l_@@_model_tl - { \tl_set_eq:NN \l_@@_model_tl \l_@@_internal_tl } - { - \str_if_eq:VVF \l_@@_model_tl \l_@@_internal_tl - { - \__kernel_msg_error:nnn { color } - { DeviceN-inconsistent-alternative } - {#2} - \clist_map_break:n { \use_none:nnnn } - } - } - } - { - \str_if_eq:nnF {##1} { none } - { - \__kernel_msg_error:nnn { color } - { DeviceN-no-alternative } - {#2} - } - } - } - \tl_if_empty:NTF \l_@@_model_tl - { - \__kernel_msg_error:nnn { color } - { DeviceN-no-alternative } {#2} - } - { \exp_args:NV \@@_model_devicen:nnn \l_@@_model_tl {#1} {#2} } - } -% \end{macrocode} -% We now complete the data we require by first finding out how many -% colorants there are, then moving on to begin constructing the function -% required to map to the alternative color space. -% \begin{macrocode} -\cs_new_protected:Npn \@@_model_devicen:nnn #1#2#3 - { - \exp_args:Nx \@@_model_devicen:nnnn - { \clist_count:n {#2} } {#1} {#2} {#3} - } -% \end{macrocode} -% At this stage, we have checked everything is in place, so we can set up -% the \TeX{} and backend data structures. As for separations, it's not really -% possible in general to have a fallback, so we simply provide -% \enquote{black} for each element. -% \begin{macrocode} -\cs_new_protected:Npn \@@_model_devicen:nnnn #1#2#3#4 - { - \int_gincr:N \g_@@_model_int - \tl_const:cx { c_@@_fallback_ #4 _tl } - { \prg_replicate:nn {#1} { 1 ~ } } - \cs_if_exist_use:cF { @@_model_devicen_parse_ #1 :nn } - { \@@_model_devicen_parse_generic:nn } - {#4} {#1} - \clist_map_inline:nn { fill , stroke , select } - { - \cs_new_protected:cpx { @@_backend_ ##1 _ #4 :n } ####1 - { - \exp_not:c { @@_backend_ ##1 _ devicen:nn } - { color \int_use:N \g_@@_model_int } {####1} - } - } - \cs_new_protected:cpx { @@_model_ #4 _white: } - { - \prop_put:Nnn \exp_not:N \l_@@_named_white_prop {#4} - { \prg_replicate:nn {#1} { 0 ~ } } - \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0 - { \group_insert_after:N \exp_not:c { @@_model_ #4 _ white: } } - } - \use:c { @@_model_ #4 _white: } - \@@_model_devicen_init:nnn {#1} {#2} {#3} - \@@_model_devicen_convert:nnn {#4} {#2} {#3} - } -% \end{macrocode} -% For short lists of DeviceN colors, wee can use hand-tuned parsing. This -% lines up with other models, where we allow for up to four components. For -% larger spaces,. rather than limit artificially, we use a somewhat slow -% approach based on open-ended commas-lists. -% \begin{macrocode} -\cs_new_protected:cpn { @@_model_devicen_parse_1:nn } #1#2 - { - \cs_new:cpn { @@_parse_model_ #1 :w } ##1 , ##2 \s_@@_stop - { {#1} { \@@_parse_number:n {##1} } } - \cs_new_eq:cN { @@_parse_mix_ #1 :nw } \@@_parse_mix_gray:nw - } -\cs_new_protected:cpn { @@_model_devicen_parse_2:nn } #1#2 - { - \cs_new:cpn { @@_parse_model_ #1 :w } ##1 , ##2 , ##3 \s_@@_stop - { {#1} { \@@_parse_number:n {##1} ~ \@@_parse_number:n {##2} } } - \cs_new:cpn { @@_parse_mix_ #1 :nw } - ##1##2 ~ ##3 \s_@@_mark ##4 ~ ##5 \s_@@_stop - { - \fp_eval:n { ##2 * ##1 + ##4 * ( 1 - ##1 ) } \c_space_tl - \fp_eval:n { ##3 * ##1 + ##5 * ( 1 - ##1 ) } - } - } -\cs_new_protected:cpn { @@_model_devicen_parse_3:nn } #1#2 - { - \cs_new:cpn { @@_parse_model_ #1 :w } ##1 , ##2 , ##3 , ##4 \s_@@_stop - { - {#1} - { - \@@_parse_number:n {##1} ~ - \@@_parse_number:n {##2} ~ - \@@_parse_number:n {##3} - } - } - \cs_new_eq:cN { @@_parse_mix_ #1 :nw } \@@_parse_mix_rgb:nw - } -\cs_new_protected:cpn { @@_model_devicen_parse_4:nn } #1#2 - { - \cs_new:cpn { @@_parse_model_ #1 :w } - ##1 , ##2 , ##3 , ##4 , ##5 \s_@@_stop - { - {#1} - { - \@@_parse_number:n {##1} ~ - \@@_parse_number:n {##2} ~ - \@@_parse_number:n {##3} ~ - \@@_parse_number:n {##4} - } - } - \cs_new_eq:cN { @@_parse_mix_ #1 :nw } \@@_parse_mix_cmyk:nw - } -\cs_new_protected:Npn \@@_model_devicen_parse_generic:nn #1#2 - { - \cs_new:cpn { @@_parse_model_ #1 :w } ##1 , ##2 \s_@@_stop - { - {#1} - { \@@_model_devicen_parse:nw {#2} ##1 , ##2 , \q_nil , \s_@@_stop } - } - \cs_new:cpx { @@_parse_mix_ #1 :nw } - ##1 ##2 \s_@@_mark ##3 \s_@@_stop - { - \exp_not:N \@@_model_devicen_mix:nw {##1} - ##2 \c_space_tl \exp_not:N \q_nil \c_space_tl \exp_not:N \s_@@_mark - ##3 \c_space_tl \exp_not:N \q_nil \c_space_tl \exp_not:N \s_@@_stop - } - } -\cs_new:Npn \@@_model_devicen_parse:nw #1#2 , #3 \s_@@_stop - { - \int_compare:nNnT {#1} > 0 - { - \quark_if_nil:nTF {#2} - { \prg_replicate:nn {#1} { 0 ~ } } - { - \@@_parse_number:n {#2} - \int_compare:nNnT {#1} > 1 { ~ } - \exp_args:Nf \@@_model_devicen_parse:nw - { \int_eval:n { #1 - 1 } } #3 \s_@@_stop - } - } - } -\cs_new:Npn \@@_model_devicen_mix:nw #1#2 ~ #3 \s_@@_mark #4 ~ #5 \s_@@_stop - { - \fp_eval:n { #2 * #1 + #4 * ( 1 - #1 ) } - \quark_if_nil:oF { \tl_head:w #3 \q_stop } - { - \c_space_tl - \@@_model_devicen_mix:nw {#1} #3 \s_@@_mark #5 \s_@@_stop - } - } -% \end{macrocode} -% To construct the tint transformation, we have to use PostScript. The -% aim is to have the final tint for each device colorant as -% \[ -% 1 - \prod_{n} (1 - X_{n} D_{X_{n}}) -% \] -% where $X$ is a DeviceN colorant and $D$ is the amount of device colorant -% that the DeviceN colorant maps to. At the start of the process, the -% PostScript stack will contain the $X_{n}$ values, whilst we have the -% $D$ values on a per-DeviceN colorant basis. The more convenient approach -% for us is therefore to take each DeviceN colorant in turn and find the -% value $1 - X_{n} D_{X_{n}}$, multiplying as we go, and finalise with the -% subtraction. That contrasts to \pkg{colorspace}: it splits the process -% up by process color, which works better when you have a fixed list -% of colorants. (\pkg{colorspace} only supports up to $4$ DeviceN colors, -% and only \texttt{cmyk} as the alternative space.) To set this up, -% we first need to know the number of values in the target color space: -% this is easily handled as there are a very small range of possibles. -% Once we have that information, it's relatively easy to build the required -% PostScript using some generic code. -% \begin{macrocode} -\cs_new_protected:Npn \@@_model_devicen_init:nnn #1#2#3 - { - \exp_args:Ne \@@_model_devicen_init:nnnn - { - \str_case:nn {#2} - { - { cmyk } { 4 } - { gray } { 1 } - { rgb } { 3 } - } - } - {#1} {#2} {#3} - } -% \end{macrocode} -% As we always need to split the alternative values into parts, we use a -% shared auxiliary and only use a minimal difference between code paths. -% Construction of the tint transformation is as far as possible done using -% loops, which means there are some inefficiencies for device colors in -% the \texttt{DeviceN} space: we roll the stack one-at-a-time even if there -% is a potential shortcut. However, that way there is nothing to special-case. -% Once this is sorted, we can write the tint transform object, which will -% remain as the last object until we sort out the final step: the colorant -% list. -% \begin{macrocode} -\cs_new_protected:Npn \@@_model_devicen_init:nnnn #1#2#3#4 - { - \tl_set:Nx \l_@@_internal_tl - { \prg_replicate:nn {#1} { 1.0 ~ } } - \int_zero:N \l_@@_internal_int - \clist_map_inline:nn {#4} - { - \int_incr:N \l_@@_internal_int - \prop_get:NnN \g_@@_alternative_values_prop {##1} - \l_@@_value_tl - \exp_after:wN \@@_model_devicen_transform:w - \l_@@_value_tl , 0 , 0 , 0 \s_@@_stop {#1} {#2} - } - \tl_put_right:Nx \l_@@_internal_tl - { - \prg_replicate:nn {#1} - { neg ~ 1.0 ~ add ~ #1 ~ -1 ~ roll ~ } - \int_eval:n { #2 + 4 } ~ 4 ~ roll - \prg_replicate:nn {#2} { ~ pop } - } - \use:x - { - \@@_backend_devicen_init:nnn - { - \clist_map_function:nN {#4} - \@@_model_devicen_colorant:n - } - { - \str_case:nn {#3} - { - { cmyk } { /DeviceCMYK } - { gray } { /DeviceGray } - { rgb } { /DeviceRGB } - } - } - { \exp_not:V \l_@@_internal_tl } - } - } -\cs_new_protected:Npn \@@_model_devicen_transform:w - #1 , #2 , #3 , #4 , #5 \s_@@_stop #6#7 - { - \use:c { @@_model_devicen_transform_ #6 :nnnnn } - {#1} {#2} {#3} {#4} {#7} - } -\cs_new_protected:cpn { @@_model_devicen_transform_1:nnnnn } #1#2#3#4#5 - { \@@_model_devicen_transform:nnn {#5} { 1 } {#1} } -\cs_new_protected:cpn { @@_model_devicen_transform_3:nnnnn } #1#2#3#4#5 - { - \clist_map_inline { #1 , #2 , #3 } - { \@@_model_devicen_transform:nnn {#5} { 3 } {##1} } - } -\cs_new_protected:cpn { @@_model_devicen_transform_4:nnnnn } #1#2#3#4#5 - { - \clist_map_inline:nn { #1 , #2 , #3 , #4 } - { \@@_model_devicen_transform:nnn {#5} { 4 } {##1} } - } -\cs_new_protected:Npn \@@_model_devicen_transform:nnn #1#2#3 - { - \tl_put_right:Nx \l_@@_internal_tl - { - \fp_compare:nNnF {#3} = \c_zero_fp - { - \int_eval:n { #1 - \l_@@_internal_int + #2 } ~ index ~ - #3 ~ neg ~ mul ~ 1.0 ~ add ~ mul ~ - } - #2 ~ -1 ~ roll ~ - } - } -\cs_new:Npn \@@_model_devicen_colorant:n #1 - { - / \prop_item:Nn \g_@@_colorants_prop {#1} ~ - } -% \end{macrocode} -% Here we need to set up conversion from the DeviceN space to the alternative -% at the \TeX{} level. This also means supplying methods for inter-converting -% to other parameter-based spaces. Essentially the approach is exactly the same -% as the PostScript, just expressed in \TeX{} terms. -% \begin{macrocode} -\cs_new_protected:Npn \@@_model_devicen_convert:nnn #1#2#3 - { - \use:c { @@_model_devicen_convert_ #2 :nn } {#1} {#3} - } -\cs_new_protected:Npn \@@_model_devicen_convert_cmyk:nn #1#2 - { - \@@_model_convert:nnn {#1} { cmyk } { gray } - \@@_model_convert:nnn {#1} { cmyk } { rgb } - \@@_model_devicen_convert:nnnn {#1} { cmyk } { 4 } {#2} - } -\cs_new_protected:Npn \@@_model_devicen_convert_gray:nn #1#2 - { - \@@_model_convert:nnn {#1} { gray } { cmyk } - \@@_model_convert:nnn {#1} { gray } { rgb } - \@@_model_devicen_convert:nnnn {#1} { gray } { 1 } {#2} - } -\cs_new_protected:Npn \@@_model_devicen_convert_rgb:nn #1#2 - { - \@@_model_convert:nnn {#1} { rgb } { cmyk } - \@@_model_convert:nnn {#1} { rgb } { gray } - \@@_model_devicen_convert:nnnn {#1} { rgb } { 3 } {#2} - } -\cs_new_protected:Npn \@@_model_devicen_convert:nnnn #1#2#3#4 - { - \cs_new:cpx { @@_convert_ #1 _ #2 :w } ##1 \s_@@_stop - { - \exp_not:c { @@_convert_devicen_ #2 : \prg_replicate:nn {#3} { n } w } - \prg_replicate:nn {#3} { { 1 } } - ##1 \exp_not:N \s_@@_mark - \clist_map_function:nN {#4} \@@_model_devicen_convert:n - \exp_not:N \s_@@_stop - } - } -\cs_new:Npn \@@_model_devicen_convert:n #1 - { - { - \exp_args:Ne \@@_model_devicen_convert_aux:n - { \prop_item:Nn \g_@@_alternative_values_prop {#1} } - } - } -\cs_new:Npn \@@_model_devicen_convert_aux:n #1 - { \@@_model_devicen_convert_aux:w #1 , , , , \s_@@_stop } -\cs_new:Npn \@@_model_devicen_convert_aux:w #1 , #2 , #3 , #4 , #5 \s_@@_stop - { - {#1} - \tl_if_blank:nF {#2} - { - {#2} - \tl_if_blank:nF {#3} - { - {#3} - \tl_if_blank:nF {#4} { {#4} } - } - } - } -\cs_new:Npn \@@_convert_devicen_cmyk:nnnnw - #1#2#3#4#5 ~ #6 \s_@@_mark #7#8 \s_@@_stop - { - \@@_convert_devicen_cmyk:nnnnnnnnn {#5} {#1} {#2} {#3} {#4} #7 - #6 \s_@@_mark #8 \s_@@_stop - } -\cs_new:Npn \@@_convert_devicen_cmyk:nnnnnnnnn #1#2#3#4#5#6#7#8#9 - { - \use:e - { - \exp_not:N \@@_convert_devicen_cmyk_aux:nnnnw - { \fp_eval:n { #2 * (1 - (#1 * #6)) } } - { \fp_eval:n { #3 * (1 - (#1 * #7)) } } - { \fp_eval:n { #4 * (1 - (#1 * #8)) } } - { \fp_eval:n { #5 * (1 - (#1 * #9)) } } - } - } -\cs_new:Npn \@@_convert_devicen_cmyk_aux:nnnnw - #1#2#3#4 #5 \s_@@_mark #6 \s_@@_stop - { - \tl_if_blank:nTF {#5} - { - \fp_eval:n { 1 - #1 } ~ - \fp_eval:n { 1 - #2 } ~ - \fp_eval:n { 1 - #3 } ~ - \fp_eval:n { 1 - #4 } - } - { - \@@_convert_devicen_cmyk:nnnnw {#1} {#2} {#3} {#4} - #5 \s_@@_mark #6 \s_@@_stop - } - } -\cs_new:Npn \@@_convert_devicen_gray:nw - #1#2 ~ #3 \s_@@_mark #4#5 \s_@@_stop - { - \@@_convert_devicen_gray:nnn {#2} {#1} #4 - #3 \s_@@_mark #5 \s_@@_stop - } -\cs_new:Npn \@@_convert_devicen_gray:nnn #1#2#3 - { - \exp_arsgs:Ne \@@_convert_devicen_gray_aux:nw - { \fp_eval:n { #2 * (1 - (#1 * #3)) } } - } -\cs_new:Npn \@@_convert_devicen_gray_aux:nw - #1 #2 \s_@@_mark #3 \s_@@_stop - { - \tl_if_blank:nTF {#2} - { \fp_eval:n { 1 - #1 } } - { - \@@_convert_devicen_gray:nw {#1} - #2 \s_@@_mark #3 \s_@@_stop - } - } -\cs_new:Npn \@@_convert_devicen_rgb:nnnw - #1#2#3#4 ~ #5 \s_@@_mark #6#7 \s_@@_stop - { - \@@_convert_devicen_cmyk:nnnnnn {#4} {#1} {#2} {#3} #6 - #5 \s_@@_mark #7 \s_@@_stop - } -\cs_new:Npn \@@_convert_devicen_rgb:nnnnnnn #1#2#3#4#5#6#7 - { - \use:e - { - \exp_not:N \@@_convert_devicen_rgb_aux:nnnw - { \fp_eval:n { #2 * (1 - (#1 * #5)) } } - { \fp_eval:n { #3 * (1 - (#1 * #6)) } } - { \fp_eval:n { #4 * (1 - (#1 * #7)) } } - } - } -\cs_new:Npn \@@_convert_devicen_rgb_aux:nnnw - #1#2#3 #4 \s_@@_mark #5 \s_@@_stop - { - \tl_if_blank:nTF {#4} - { - \fp_eval:n { 1 - #1 } ~ - \fp_eval:n { 1 - #2 } ~ - \fp_eval:n { 1 - #3 } - } - { - \@@_convert_devicen_rgb:nnnw {#1} {#2} {#3} - #4 \s_@@_mark #5 \s_@@_stop - } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \subsection{Diagnostics} -% -% \begin{macro}{\color_show:n} -% \begin{macro}{\@@_show:n} -% Extract the information about a color and format for the user: the approach -% is similar to the keys module here. -% \begin{macrocode} -\cs_new_protected:Npn \color_show:n #1 - { - \msg_show:nnxxxx { LaTeX / color } { show } - {#1} - { - \@@_if_defined:nT {#1} - { - \exp_args:Nv \@@_show:n { l_@@_named_ #1 _tl } - \prop_map_function:cN - { l_@@_named_ #1 _prop } - \msg_show_item_unbraced:nn - } - } - { } - { } - } -\cs_new:Npn \@@_show:n #1 - { - \msg_show_item_unbraced:nn { model } {#1} - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \subsection{Messages} -% -% \begin{macrocode} -\__kernel_msg_new:nnnn { color } { CIELAB-requires-illuminant } - { CIELAB~color~space~'#1'~require~an~illuminant. } - { - LaTeX~has~been~asked~to~create~a~separation~color~space~using~ - CIELAB~specifications,~but~no~\\ \\ - \iow_indent:n { illuminant~=~ } - \\ \\ - key~was~given~with~the~correct~information.~LaTeX~will~use~illuminant~ - 'd50'~for~recovery. - } -\__kernel_msg_new:nnnn { color } { conversion-not-available } - { No~model~conversion~available~from~'#1'~to~'#2'. } - { - LaTeX~has~been~asked~to~convert~a~color~from~model~'#1'~ - to~model'#2',~but~there~is~no~method~available~to~do~that. - } -\__kernel_msg_new:nnnn { color } { DeviceN-inconsistent-alternative } - { DeviceN~color~spaces~require~a~single~alternative~space. } - { - LaTeX~has~been~asked~to~create~a~DeviceN~color~space~'#1',~ - but~the~constituent~colors~do~not~have~a~common~alternative~ - color. - } -\__kernel_msg_new:nnnn { color } { DeviceN-no-alternative } - { DeviceN~color~spaces~require~an~alternative~space. } - { - LaTeX~has~been~asked~to~create~a~DeviceN~color~space~'#1',~ - but~the~constituent~colors~do~not~all~have~a~device-based~alternative. - } -\__kernel_msg_new:nnnn { color } { DeviceN-requires-names } - { DeviceN~color~space~'#1'~require~a~list~of~names. } - { - LaTeX~has~been~asked~to~create~a~DeviceN~color~space,~ - but~no~\\ \\ - \iow_indent:n { names~=~ } - \\ \\ - key~was~given~with~the~correct~information. - } -\__kernel_msg_new:nnnn { color } { model-already-defined } - { Color~model~'#1'~already~defined. } - { - LaTeX~was~asked~to~define~a~new~color~model~called~'#1',~but~ - this~color~model~already~exists. - } -\__kernel_msg_new:nnnn { color } { separation-alternative-model } - { Separation~color~space~'#1'~require~an~alternative~model. } - { - LaTeX~has~been~asked~to~create~a~separation~color~space,~ - but~no~\\ \\ - \iow_indent:n { alternative-model~=~ } - \\ \\ - key~was~given~with~the~correct~information. - } -\__kernel_msg_new:nnnn { color } { separation-alternative-values } - { Separation~color~space~'#1'~require~values~for~the~alternative~space. } - { - LaTeX~has~been~asked~to~create~a~separation~color~space,~ - but~no~\\ \\ - \iow_indent:n { alternative-values~=~ } - \\ \\ - key~was~given~with~the~correct~information. - } -\__kernel_msg_new:nnnn { color } { separation-requires-name } - { Separation~color~space~'#1'~require~a~formal~name. } - { - LaTeX~has~been~asked~to~create~a~separation~color~space,~ - but~no~\\ \\ - \iow_indent:n { name~=~ } - \\ \\ - key~was~given~with~the~correct~information. - } -\__kernel_msg_new:nnnn { color } { unknown-color } - { Unknown~color~'#1'. } - { - LaTeX~has~been~asked~to~use~a~color~named~'#1',~ - but~this~has~never~been~defined. - } -\__kernel_msg_new:nnnn { color } { unknown-alternative-model } - { Separation~color~space~'#1'~require~an~valid~alternative~space. } - { - LaTeX~has~been~asked~to~create~a~separation~color~space,~ - but~the~model~given~as\\ \\ - \iow_indent:n { alternative-model~=~ } - \\ \\ - is~unknown. - } -\__kernel_msg_new:nnnn { color } { unknown-export-format } - { Unknown~export~format~'#1'. } - { - LaTeX~has~been~asked~to~export~a~color~in~format~'#1',~ - but~this~has~never~been~defined. - } -\__kernel_msg_new:nnnn { color } { unknown-CIELAB-illuminant } - { Unknown~illuminant~model~'#1'. } - { - LaTeX~has~been~asked~to~use~create~a~color~space~using~CIELAB~ - illuminant~'#1',~but~this~does~not~exist. - } -\__kernel_msg_new:nnnn { color } { unknown-model } - { Unknown~color~model~'#1'. } - { - LaTeX~has~been~asked~to~use~a~color~model~called~'#1',~ - but~this~model~is~not~set~up. - } -\__kernel_msg_new:nnnn { color } { unknown-model-type } - { Unknown~color~model~type~'#1'. } - { - LaTeX~has~been~asked~to~create~a~new~color~model~called~'#1',~ - but~this~type~of~model~was~never~set~up. - } -% \end{macrocode} -% -% \begin{macrocode} -\__kernel_msg_new:nnn { color } { show } - { - The~color~#1~ - \tl_if_empty:nTF {#2} - { is~undefined. } - { has~the~properties: #2 } - } -% \end{macrocode} -% -% \begin{macrocode} -% -% \end{macrocode} -% -% \end{implementation} -% -% \PrintIndex diff --git a/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.ins b/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.ins deleted file mode 100644 index e1704a9715b..00000000000 --- a/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.ins +++ /dev/null @@ -1,58 +0,0 @@ -\iffalse meta-comment - -File: l3color.ins - -Copyright (C) 2017-2021 The LaTeX Project - -It may be distributed and/or modified under the conditions of the -LaTeX Project Public License (LPPL), either version 1.3c of this -license or (at your option) any later version. The latest version -of this license is in the file - - http://www.latex-project.org/lppl.txt - -This file is part of the "l3experimental bundle" (The Work in LPPL) -and all files in that bundle must be distributed together. - ------------------------------------------------------------------------ - -The development version of the bundle can be found at - - https://github.com/latex3/latex3 - -for those people who are interested. - ------------------------------------------------------------------------ - -Any modification of this file should ensure that the copyright and -license information is placed in the derived files. - -\fi - -\input l3docstrip.tex -\askforoverwritefalse - -\preamble - -Copyright (C) 2017-2021 The LaTeX Project - -It may be distributed and/or modified under the conditions of -the LaTeX Project Public License (LPPL), either version 1.3c of -this license or (at your option) any later version. The latest -version of this license is in the file: - - http://www.latex-project.org/lppl.txt - -This file is part of the "l3experimental bundle" (The Work in LPPL) -and all files in that bundle must be distributed together. - -\endpreamble -% stop docstrip adding \endinput -\postamble -\endpostamble - -\keepsilent - -\generate{\file{l3color.sty}{\from{l3color.dtx}{package}}} - -\endbatchfile diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx index 29103416ee0..64bc0cfa646 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx index 0ed23162fda..f193ceb4d64 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx index bfad9e14a3a..a846d4046a2 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx index 8c170eeb27e..70e088d0cf7 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx index 4b28b103970..60792f27ed0 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx index 2bda7e3c2d4..9d70d5d7e2c 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx index 42709122b70..105120a391d 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx index 880fff8b1a8..839fce91a61 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx index 68f83903ecb..1b6cdd8ab9f 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx @@ -110,7 +110,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % @@ -231,7 +231,7 @@ % \begin{syntax} % \cs{draw_linewidth:n} \Arg{width} % \end{syntax} -% Sets the width to be used for stroking to the \meta{width} (an +% Sets the width to be used for stroking to the \meta{width} (an % \meta{fp expr}). % \end{function} % @@ -268,7 +268,7 @@ % \draw_end: % \end{demo} % Setting an empty pattern will produce a solid line. -% +% % Note the \meta{pattern} interface here is different from that in \pkg{pgf}: % the list is comma-separated not given in brace groups. % \end{function} @@ -410,7 +410,7 @@ % Gives the co-ordinates of the point at \meta{angle} (an \meta{fp expr} in % \emph{degrees}) and \meta{radius}. The three-argument version accepts % two radii of different lengths. -% +% % Note the interface here is somewhat different from that in \pkg{pgf}: % the one- and two-radii versions in \pkg{l3draw} use separate functions, % whilst in \pkg{pgf} they use the same function and a keyword. @@ -470,7 +470,7 @@ % \emph{degrees}) and \meta{radius}, relative to the prevailing % $x$- and $y$-vectors. The three-argument version accepts two radii of % different lengths. -% +% % Note the interface here is somewhat different from that in \pkg{pgf}: % the one- and two-radii versions in \pkg{l3draw} use separate functions, % whilst in \pkg{pgf} they use the same function and a keyword. @@ -795,7 +795,7 @@ % \begin{syntax} % \cs{draw_path_circle:nn} \Arg{center} \Arg{radius} % \end{syntax} -% Appends a circle of \meta{radius} at \meta{center} to the current path. +% Appends a circle of \meta{radius} at \meta{center} to the current path. % This is a shortcut for \cs{draw_path_ellipse:nnn}. % \end{function} % @@ -1136,14 +1136,10 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{l3draw}{2021-02-06}{} +\ProvidesExplPackage{l3draw}{2021-02-18}{} {L3 Experimental core drawing support} % \end{macrocode} % -% \begin{macrocode} -\RequirePackage { l3color } -% \end{macrocode} -% % \subsection{Internal auxiliaries} % % \begin{variable}{\s_@@_mark,\s_@@_stop} diff --git a/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx b/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx index c244ad7258f..5b4144c062e 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % @@ -240,7 +240,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{l3graphics}{2021-02-06}{} +\ProvidesExplPackage{l3graphics}{2021-02-18}{} {L3 Experimental graphics inclusion support} % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.dtx b/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.dtx deleted file mode 100644 index f5a5c72cfe3..00000000000 --- a/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.dtx +++ /dev/null @@ -1,442 +0,0 @@ -% \iffalse meta-comment -% -%% File: l3pdf.dtx -% -% Copyright(C) 2019-2021 The LaTeX Project -% -% It may be distributed and/or modified under the conditions of the -% LaTeX Project Public License (LPPL), either version 1.3c of this -% license or (at your option) any later version. The latest version -% of this license is in the file -% -% http://www.latex-project.org/lppl.txt -% -% This file is part of the "l3experimental bundle" (The Work in LPPL) -% and all files in that bundle must be distributed together. -% -% ----------------------------------------------------------------------- -% -% The development version of the bundle can be found at -% -% https://github.com/latex3/latex3 -% -% for those people who are interested. -% -%<*driver|package> -\RequirePackage{expl3} -% -%<*driver> -\documentclass[full]{l3doc} -\begin{document} - \DocInput{\jobname.dtx} -\end{document} -% -% \fi -% -% \title{^^A -% The \pkg{l3pdf} package\\ Core PDF support^^A -% } -% -% \author{^^A -% The \LaTeX{} Project\thanks -% {^^A -% E-mail: -% \href{mailto:latex-team@latex-project.org} -% {latex-team@latex-project.org}^^A -% }^^A -% } -% -% \date{Released 2021-02-06} -% -% \maketitle -% -% \begin{documentation} -% -% \section{\pkg{l3pdf} documentation} -% -% \subsection{Objects} -% -% \begin{function}[added = 2019-06-02]{\pdf_object_new:nn} -% \begin{syntax} -% \cs{pdf_object_new:nn} \Arg{object} \Arg{type} -% \end{syntax} -% Declares \meta{object} as a PDF object of \meta{type}, which should be -% one of -% \begin{itemize} -% \item \texttt{array} -% \item \texttt{dict} -% \item \texttt{fstream} -% \item \texttt{stream} -% \end{itemize} -% The object may be referenced from this point on, and written later -% using \cs{pdf_object_write:nn}. -% \end{function} -% \begin{function}[EXP, pTF, added=2020-05-15]{\pdf_object_if_exist:n} -% \begin{syntax} -% \cs{pdf_object_if_exist_p:n} \Arg{object} -% \cs{pdf_object_if_exist:nTF} \Arg{object} -% \end{syntax} -% Tests whether an object with name \Arg{object} has been defined. -% \end{function} -% \begin{function}[added = 2019-06-02] -% {\pdf_object_write:nn, \pdf_object_write:nx} -% \begin{syntax} -% \cs{pdf_object_write:nn} \Arg{object} \Arg{content} -% \end{syntax} -% Writes the \meta{content} as content of the \meta{object}. Depending on the -% \meta{type} declared for the object, the format required for the -% \meta{data} will vary -% \begin{itemize} -% \item[\texttt{array}] A space-separated list of values -% \item[\texttt{dict}] Key--value pairs in the form -% \texttt{/\meta{key} \meta{value}} -% \item[\texttt{fstream}] Two brace groups: \meta{file name} and -% \meta{file content} -% \item[\texttt{stream}] Two brace groups: \meta{attributes (dictionary)} -% and \meta{stream contents} -% \end{itemize} -% \end{function} -% -% \begin{function}[EXP, added = 2019-06-02]{\pdf_object_ref:n} -% \begin{syntax} -% \cs{pdf_object_ref:n} \Arg{object} -% \end{syntax} -% Inserts the appropriate information to reference the \meta{object} -% in for example page resource allocation -% \end{function} -% -% \begin{function}[added = 2019-06-02] -% {\pdf_object_now:nn, \pdf_object_now:nx} -% \begin{syntax} -% \cs{pdf_object_now:nn} \Arg{type} \Arg{content} -% \end{syntax} -% Writes the \meta{content} as content of an anonymous object. Depending on the -% \meta{type}, the format required for the \meta{data} will vary -% \begin{itemize} -% \item[\texttt{array}] A space-separated list of values -% \item[\texttt{dict}] Key--value pairs in the form -% \texttt{/\meta{key} \meta{value}} -% \item[\texttt{fstream}] Two brace groups: \meta{file name} and -% \meta{file content} -% \item[\texttt{stream}] Two brace groups: \meta{attributes (dictionary)} -% and \meta{stream contents} -% \end{itemize} -% \end{function} -% -% \begin{function}[EXP, added = 2019-06-02]{\pdf_object_last:} -% \begin{syntax} -% \cs{pdf_object_last:} -% \end{syntax} -% Inserts the appropriate information to reference the last \meta{object} -% created. This is particularly useful for anonymous objects. -% \end{function} -% -% \subsection{Version} -% -% \begin{function}[pTF, EXP, added = 2019-06-02]{\pdf_version_compare:Nn} -% \begin{syntax} -% \cs{pdf_version_compare:NnTF} \meta{comparator} \Arg{version} \Arg{true code} \Arg{false code} -% \end{syntax} -% Compares the version of the PDF being created with the \meta{version} -% string specified, using the \meta{comparator}. Either the \meta{true code} -% or \meta{false code} will be left in the output stream. -% \end{function} -% -% \begin{function}[added = 2019-06-02] -% {\pdf_version_gset:n, \pdf_version_min_gset:n} -% \begin{syntax} -% \cs{pdf_version_gset:n} \Arg{version} -% \end{syntax} -% Sets the \meta{version} of the PDF being created. The |min| version will -% not alter the output version unless it is currently lower than the -% \meta{version} requested. -% -% This function may only be used up to the point where the PDF file is -% initialised. -% \end{function} -% -% \begin{function}[EXP, added = 2019-06-02] -% {\pdf_version:, \pdf_version_major:, \pdf_version_minor:} -% \begin{syntax} -% \cs{pdf_version:} -% \end{syntax} -% Expands to the currently-active PDF version. -% \end{function} -% -% \subsection{Compression} -% -% \begin{function}[added = 2019-06-02]{\pdf_uncompress:} -% \begin{syntax} -% \cs{pdf_uncompress:} -% \end{syntax} -% Disables any compression of the PDF, where possible. -% -% This function may only be used up to the point where the PDF file is -% initialised. -% \end{function} -% -% \subsection{Destinations} -% -% Destinations are the places a link jumped too. -% Unlike the name may suggest they don't described -% an exact location in the PDF. Instead a destination contains a reference to -% a page along with an instruction how to display this page. -% The normally used \enquote{XYZ \textit{top left zoom}} for example instructs -% the viewer to show the page with the given \textit{zoom} and -% the top left corner at the \textit{top left} coordinates---which then gives -% the impression that there is an anchor at this position. -% -% If an instruction takes a coordinate, it is calculated by the following -% commands relative to the location the command is issued. -% So to get a specific coordinate one has to move the command to the right place. -% -% \begin{function}[added = 2021-01-03] -% {\pdf_destination:nn} -% \begin{syntax} -% \cs{pdf_destination:nn} \Arg{name} \Arg{type or integer} -% \end{syntax} -% This creates a destination. \Arg{type or integer} can be one of |fit|, |fith|, -% |fitv|, |fitb|, |fitbh|, |fitbv|, |fitr|, |xyz| -% or an integer representing a scale factor in percent. -% |fitr| here gives only a lightweight version of |/FitR|: -% The backend code defines |fitr| so that it will with pdf\LaTeX{} and -% Lua\LaTeX{} use the coordinates of the surrounding box, -% with \texttt{dvips} and \texttt{dvipdfmx} it falls back to |fit|. -% For full control use \cs{pdf_destination:nnnn}. -% -% The keywords match to the PDF names as described in the following tabular. -% -% \medskip -% \noindent\begin{tabular}{ll>{\raggedright\arraybackslash}p{6cm}} -% \toprule -% Keyword & PDF & Remarks \\ \midrule -% |fit| & |/Fit| -% & Fits the page to the window\\ -% |fith| & |/FitH| \textit{top} -% & Fits the width of the page to the window \\ -% |fitv| & |/FitV| \textit{left} -% & Fits the height of the page to the window \\ -% |fitb| & |/FitB| -% & Fits the page bounding box to the window \\ -% |fitbh|& |/FitBH| \textit{top} -% & Fits the width of the page bounding box to the window. \\ -% |fitbv|& |/FitBV| \textit{left} -% & Fits the height of the page bounding box to the window. \\ -% |fitr| & |/FitR| \textit{left bottom right top} -% & Fits the rectangle specified by the four coordinates to the window -% (see above for the restrictions)\\ -% |xyz| & |/XYZ| \textit{left top} null -% & Sets a coordinate but doesn't change the zoom.\\ -% \Arg{integer} & |/XYZ| \textit{left top zoom} -% & Sets a coordinate and a zoom meaning \Arg{integer}\%. -% \\\bottomrule -% \end{tabular} -% -% \end{function} -% -% \begin{function}[added = 2021-01-17] -% {\pdf_destination:nnnn} -% \begin{syntax} -% \cs{pdf_destination:nnnn} \Arg{name} \Arg{width} \Arg{height} \Arg{depth} -% \end{syntax} -% This creates a destination with |/FitR| type with the given dimensions relative -% to the current location. The destination is in a box of size zero, but it doesn't -% switch to horizontal mode. -% \end{function} -% \end{documentation} -% -% \begin{implementation} -% -% \section{\pkg{l3pdf} implementation} -% -% \begin{macrocode} -%<*package> -% \end{macrocode} -% -% \begin{macrocode} -%<@@=pdf> -% \end{macrocode} -% -% \begin{macrocode} -\ProvidesExplPackage{l3pdf}{2021-02-06}{} - {L3 Experimental core PDF support} -% \end{macrocode} -% -% \begin{variable}{\s_@@_stop} -% Internal scan marks. -% \begin{macrocode} -\scan_new:N \s_@@_stop -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\g_@@_init_bool} -% A flag so we have some chance of avoiding setting things we are not -% allowed to. -% \begin{macrocode} -\bool_new:N \g_@@_init_bool -%<*package> -\cs_if_exist:NT \documentclass - { - \AtBeginDocument - { \bool_gset_true:N \g_@@_init_bool } - } -% -% \end{macrocode} -% \end{variable} -% -% \subsection{Compression} -% -% \begin{macro}{\pdf_uncompress:} -% Simple to do. -% \begin{macrocode} -\cs_new_protected:Npn \pdf_uncompress: - { - \bool_if:NF \g_@@_init_bool - { - \@@_backend_compresslevel:n { 0 } - \@@_backend_compress_objects:n { \c_false_bool } - } - } -% \end{macrocode} -% \end{macro} -% -% \subsection{Objects} -% -% \begin{macro}{\pdf_object_new:nn, \pdf_object_write:nn, \pdf_object_write:nx} -% \begin{macro}[pTF]{\pdf_object_if_exist:n} -% \begin{macro}{\pdf_object_ref:n} -% \begin{macro}{\pdf_object_now:nn, \pdf_object_now:nx} -% \begin{macro}{\pdf_object_last:} -% Simple to do. -% \begin{macrocode} -\cs_new_protected:Npn \pdf_object_new:nn #1#2 - { \@@_backend_object_new:nn {#1} {#2} } -\prg_new_conditional:Npnn \pdf_object_if_exist:n #1 { p , T , F , TF } - { - \int_if_exist:cTF { c__pdf_backend_object_ \tl_to_str:n {#1} _int } - { \prg_return_true: } - { \prg_return_false:} - } -\cs_new_protected:Npn \pdf_object_write:nn #1#2 - { \@@_backend_object_write:nn {#1} {#2} } -\cs_generate_variant:Nn \pdf_object_write:nn { nx } -\cs_new:Npn \pdf_object_ref:n #1 { \@@_backend_object_ref:n {#1} } -\cs_new_protected:Npn \pdf_object_now:nn #1#2 - { \@@_backend_object_now:nn {#1} {#2} } -\cs_generate_variant:Nn \pdf_object_now:nn { nx } -\cs_new:Npn \pdf_object_last: { \@@_backend_object_last: } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \subsection{Version} -% -% \begin{macro}{\pdf_version_compare:Nn} -% \begin{macro} -% { -% @@_version_compare_=:w , -% @@_version_compare_<:w , -% @@_version_compare_>:w -% } -% \begin{macrocode} -% To compare version, we need to split the given value then deal with both -% major and minor version -\prg_new_conditional:Npnn \pdf_version_compare:Nn #1#2 { p , T , F , TF } - { \use:c { @@_version_compare_ #1 :w } #2 . . \s_@@_stop } -\cs_new:cpn { @@_version_compare_=:w } #1 . #2 . #3 \s_@@_stop - { - \bool_lazy_and:nnTF - { \int_compare_p:nNn \@@_backend_version_major: = {#1} } - { \int_compare_p:nNn \@@_backend_version_minor: = {#2} } - { \prg_return_true: } - { \prg_return_false: } - } -\cs_new:cpn { @@_version_compare_<:w } #1 . #2 . #3 \s_@@_stop - { - \bool_lazy_or:nnTF - { \int_compare_p:nNn \@@_backend_version_major: < {#1} } - { - \bool_lazy_and_p:nn - { \int_compare_p:nNn \@@_backend_version_major: = {#1} } - { \int_compare_p:nNn \@@_backend_version_minor: < {#2} } - } - { \prg_return_true: } - { \prg_return_false: } - } -\cs_new:cpn { @@_version_compare_>:w } #1 . #2 . #3 \s_@@_stop - { - \bool_lazy_or:nnTF - { \int_compare_p:nNn \@@_backend_version_major: > {#1} } - { - \bool_lazy_and_p:nn - { \int_compare_p:nNn \@@_backend_version_major: = {#1} } - { \int_compare_p:nNn \@@_backend_version_minor: > {#2} } - } - { \prg_return_true: } - { \prg_return_false: } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\pdf_version_gset:n, \pdf_version_min_gset:n} -% \begin{macro}{\@@_version_gset:w} -% Split the version and set. -% \begin{macrocode} -\cs_new_protected:Npn \pdf_version_gset:n #1 - { \@@_version_gset:w #1 . . \s_@@_stop } -\cs_new_protected:Npn \pdf_version_min_gset:n #1 - { - \pdf_version_compare:NnT < {#1} - { \@@_version_gset:w #1 . . \s_@@_stop } - } -\cs_new_protected:Npn \@@_version_gset:w #1 . #2 . #3\s_@@_stop - { - \bool_if:NF \g_@@_init_bool - { - \@@_backend_version_major_gset:n {#1} - \@@_backend_version_minor_gset:n {#2} - } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[EXP]{\pdf_version:, \pdf_version_major:, \pdf_version_minor:} -% Wrappers. -% \begin{macrocode} -\cs_new:Npn \pdf_version: - { \@@_backend_version_major: . \@@_backend_version_minor: } -\cs_new:Npn \pdf_version_major: { \@@_backend_version_major: } -\cs_new:Npn \pdf_version_minor: { \@@_backend_version_minor: } -% \end{macrocode} -% \end{macro} -% -% \subsection{Destinations} -% -% \begin{macro}{\pdf_destination:nn} -% \begin{macrocode} -\cs_new_protected:Npn \pdf_destination:nn #1 #2 - { \@@_backend_destination:nn {#1}{#2} } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\pdf_destination:nnnn} -% \begin{macrocode} -\cs_new_protected:Npn \pdf_destination:nnnn #1 #2 #3 #4 - { - \hbox_to_zero:n - { \@@_backend_destination:nnnn {#1} {#2} {#3} {#4} } - } -% \end{macrocode} -% \end{macro} -% \begin{macrocode} -% -% \end{macrocode} -% -% \end{implementation} -% -% \PrintIndex diff --git a/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.ins b/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.ins deleted file mode 100644 index e422ceb995e..00000000000 --- a/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.ins +++ /dev/null @@ -1,60 +0,0 @@ -\iffalse meta-comment - -File: l3pdf.ins - -Copyright (C) 2019-2021 The LaTeX Project - -It may be distributed and/or modified under the conditions of the -LaTeX Project Public License (LPPL), either version 1.3c of this -license or (at your option) any later version. The latest version -of this license is in the file - - http://www.latex-project.org/lppl.txt - -This file is part of the "l3experimental bundle" (The Work in LPPL) -and all files in that bundle must be distributed together. - ------------------------------------------------------------------------ - -The development version of the bundle can be found at - - https://github.com/latex3/latex3 - -for those people who are interested. - ------------------------------------------------------------------------ - -Any modification of this file should ensure that the copyright and -license information is placed in the derived files. - -\fi - -\input l3docstrip.tex -\askforoverwritefalse - -\preamble - -Copyright (C) 2019-2021 The LaTeX Project - -It may be distributed and/or modified under the conditions of -the LaTeX Project Public License (LPPL), either version 1.3c of -this license or (at your option) any later version. The latest -version of this license is in the file: - - http://www.latex-project.org/lppl.txt - -This file is part of the "l3pdf bundle" (The Work in LPPL) -and all files in that bundle must be distributed together. - -\endpreamble -% stop docstrip adding \endinput -\postamble -\endpostamble - -\keepsilent - -\generate{\file{l3pdf.sty} - {\from{l3pdf.dtx}{package}} -} - -\endbatchfile diff --git a/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx b/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx index e39f2e7e032..9b0cf4a5a4d 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx @@ -48,7 +48,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % @@ -166,7 +166,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{l3str-format}{2021-02-06}{} +\ProvidesExplPackage{l3str-format}{2021-02-18}{} {L3 Experimental string formatting} % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx b/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx index 2e1d15d8db0..9a7920fe3f3 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % @@ -135,7 +135,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{l3sys-shell}{2021-02-06}{} +\ProvidesExplPackage{l3sys-shell}{2021-02-18}{} {L3 Experimental system shell functions} % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx b/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx index 37ef1c2cfe2..86d3add8ae5 100644 --- a/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx @@ -53,7 +53,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % @@ -672,7 +672,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xcoffins}{2021-02-06}{} +\ProvidesExplPackage{xcoffins}{2021-02-18}{} {L3 Experimental design level coffins} % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx b/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx index 2209ce8d9e0..1c7c9bd9418 100644 --- a/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx @@ -61,7 +61,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % @@ -686,7 +686,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{l3galley}{2021-02-06}{} +\ProvidesExplPackage{l3galley}{2021-02-18}{} {L3 Experimental galley code} % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx b/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx index 9292de08894..680e288fe37 100644 --- a/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % @@ -731,7 +731,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xgalley}{2021-02-06}{} +\ProvidesExplPackage{xgalley}{2021-02-18}{} {L3 Experimental galley} \RequirePackage{xtemplate,l3galley} % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx index bf589f7c8c2..23bbb5a8084 100644 --- a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx @@ -24,7 +24,7 @@ % %<*driver|generic|package|2ekernel> % -\def\ExplFileDate{2021-02-06}% +\def\ExplFileDate{2021-02-18}% %<*driver> \documentclass[full]{l3doc} \usepackage{graphicx} @@ -51,7 +51,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3.ins b/Master/texmf-dist/source/latex/l3kernel/l3.ins index d9ecef35e00..91c471e75e8 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3.ins +++ b/Master/texmf-dist/source/latex/l3kernel/l3.ins @@ -99,7 +99,8 @@ and all files in that bundle must be distributed together. \from{l3tl-analysis.dtx}{package} \from{l3regex.dtx} {package} \from{l3box.dtx} {package} - \from{l3color-base.dtx} {package} + \from{l3color.dtx} {package} + \from{l3pdf.dtx} {package} \from{l3coffins.dtx} {package} \from{l3luatex.dtx} {package,tex} \from{l3unicode.dtx} {package} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx index 535226f9b44..9a82102634f 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx index 2849deda777..81fb06a5796 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3box.dtx b/Master/texmf-dist/source/latex/l3kernel/l3box.dtx index 0247deaf42e..5dcf864f73c 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3box.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3box.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx index a19ed84dd39..aa0f4e1f8ae 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % @@ -86,8 +86,6 @@ % % \section{Additions to \pkg{l3box}} % -% \subsection{Viewing part of a box} -% % \begin{function}[updated = 2019-01-23] % {\box_clip:N, \box_clip:c, \box_gclip:N, \box_gclip:c} % \begin{syntax} @@ -254,8 +252,6 @@ % This is not available in older versions of \XeTeX{}. % \end{function} % -% \subsection{Working with contents of integer arrays} -% % \begin{function}[added = 2018-05-04, rEXP]{\intarray_to_clist:N} % \begin{syntax} % \cs{intarray_to_clist:N} \meta{intarray~var} @@ -279,32 +275,6 @@ % |1+2| then this logs |> 1+2=3.| % \end{function} % -% \begin{function}[added = 2017-12-04] -% { -% \msg_show:nnnnnn , -% \msg_show:nnnnn , -% \msg_show:nnnn , -% \msg_show:nnn , -% \msg_show:nn , -% \msg_show:nnxxxx , -% \msg_show:nnxxx , -% \msg_show:nnxx , -% \msg_show:nnx -% } -% \begin{syntax} -% \cs{msg_show:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four} -% \end{syntax} -% Issues \meta{module} information \meta{message}, passing \meta{arg -% one} to \meta{arg four} to the text-creating functions. The -% information text is shown on the terminal and the \TeX{} run is -% interrupted in a manner similar to \cs{tl_show:n}. This is used in -% conjunction with \cs{msg_show_item:n} and similar functions to print -% complex variable contents completely. If the formatted text does -% not contain |>~| at the start of a line, an additional line |>~.| -% will be put at the end. In addition, a final period is added if not -% present. -% \end{function} -% % \begin{function}[EXP, added = 2017-12-04] % {\msg_show_item:n, \msg_show_item_unbraced:n, \msg_show_item:nn, \msg_show_item_unbraced:nn} % \begin{syntax} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx b/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx index 6e9d1c240ca..46d682bd544 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx index 05b2ca2255e..02064b80ea9 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx index 6dc7ab596e0..ae2e660caa5 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % @@ -2247,34 +2247,6 @@ % \end{macrocode} % \end{variable} % -% \begin{macro}{\@@_color:n} -% Calls \tn{color}, and otherwise does nothing if \tn{color} is not defined. -% As this is relatively rarely used, we have it self-define rather than delay -% using a hook. -% \begin{macrocode} -\cs_new_protected:Npn \@@_color:n #1 {#1} -\bool_lazy_and:nnT - { \cs_if_exist_p:N \fmtname } - { \str_if_eq_p:Vn \fmtname { LaTeX2e } } - { - \cs_gset_protected:Npn \@@_color:n - { - \cs_gset_protected:Npx \@@_color:n - { - \cs_if_exist:NTF \color_select:n - { \color_select:n } - { - \cs_if_exist:NTF \color - { \exp_not:N \color } - { \exp_not:N \use_none:n } - } - } - \@@_color:n - } - } -% \end{macrocode} -% \end{macro} -% % \begin{macro}{\@@_rule:nn} % Abstract out creation of rules here until there is a higher-level interface. % \begin{macrocode} @@ -2298,14 +2270,14 @@ { \hcoffin_set:Nn \l_@@_display_pole_coffin { - \@@_color:n {#4} + \color_select:n {#4} \@@_rule:nn { 1pt } { 1pt } } \@@_attach_mark:NnnNnnnn #1 {#2} {#3} \l_@@_display_pole_coffin { hc } { vc } { 0pt } { 0pt } \hcoffin_set:Nn \l_@@_display_coord_coffin { - \@@_color:n {#4} + \color_select:n {#4} \l_@@_display_font_tl ( \tl_to_str:n { #2 , #3 } ) } @@ -2357,7 +2329,7 @@ { \hcoffin_set:Nn \l_@@_display_pole_coffin { - \@@_color:n {#2} + \color_select:n {#2} \@@_rule:nn { 1pt } { 1pt } } \prop_set_eq:Nc \l_@@_display_poles_prop @@ -2398,7 +2370,7 @@ { 0pt } { 0pt } \hcoffin_set:Nn \l_@@_display_coord_coffin { - \@@_color:n {#6} + \color_select:n {#6} \l_@@_display_font_tl ( \tl_to_str:n { #1 , ##1 } ) } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx b/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx deleted file mode 100644 index 497f7fbe781..00000000000 --- a/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx +++ /dev/null @@ -1,183 +0,0 @@ -% \iffalse meta-comment -% -%% File: l3color-base.dtx -% -% Copyright (C) 2011,2012,2014,2016-2021 The LaTeX Project -% -% It may be distributed and/or modified under the conditions of the -% LaTeX Project Public License (LPPL), either version 1.3c of this -% license or (at your option) any later version. The latest version -% of this license is in the file -% -% https://www.latex-project.org/lppl.txt -% -% This file is part of the "l3kernel bundle" (The Work in LPPL) -% and all files in that bundle must be distributed together. -% -% ----------------------------------------------------------------------- -% -% The development version of the bundle can be found at -% -% https://github.com/latex3/latex3 -% -% for those people who are interested. -% -%<*driver> -\documentclass[full,kernel]{l3doc} -\begin{document} - \DocInput{\jobname.dtx} -\end{document} -% -% \fi -% -% \title{^^A -% The \textsf{l3color-base} package\\ Color support^^A -% } -% -% \author{^^A -% The \LaTeX{} Project\thanks -% {^^A -% E-mail: -% \href{mailto:latex-team@latex-project.org} -% {latex-team@latex-project.org}^^A -% }^^A -% } -% -% \date{Released 2021-02-06} -% -% \maketitle -% -% \begin{documentation} -% -% This module provides support for color in \LaTeX3{}. At present, the -% material here is mainly intended to support a small number of low-level -% requirements in other \pkg{l3kernel} modules. -% -% \section{Color in boxes} -% -% Controlling the color of text in boxes requires a small number of control -% functions, so that the boxed material uses the color at the point where -% it is set, rather than where it is used. -% -% \begin{function}[added = 2011-09-03]{\color_group_begin:, \color_group_end:} -% \begin{syntax} -% \cs{color_group_begin:} -% \ldots -% \cs{color_group_end:} -% \end{syntax} -% Creates a color group: one used to \enquote{trap} color settings. -% This grouping is built in to for example \cs{hbox_set:Nn}. -% \end{function} -% -% \begin{function}[added = 2011-09-03]{\color_ensure_current:} -% \begin{syntax} -% \cs{color_ensure_current:} -% \end{syntax} -% Ensures that material inside a box uses the foreground color -% at the point where the box is set, rather than that in force when the -% box is used. This function should usually be used within a -% \cs{color_group_begin:} \ldots \cs{color_group_end:} group. -% \end{function} -% -% \end{documentation} -% -% \begin{implementation} -% -% \section{\pkg{l3color-base} Implementation} -% -% \begin{macrocode} -%<*package> -% \end{macrocode} -% -% \begin{macrocode} -%<@@=color> -% \end{macrocode} -% -% \begin{variable} -% {\l_@@_current_tl} -% The color currently active for foreground (text, \emph{etc.}) material. -% This is stored in the form of a color model followed by one or more -% values. There are four pre-defined models, three of which take numerical -% values in the range $[0,1]$: -% \begin{itemize} -% \item \texttt{gray \meta{gray}} Grayscale color with the \meta{gray} -% value running from $0$ (fully black) to $1$ (fully white) -% \item \texttt{cmyk \meta{cyan} \meta{magenta} \meta{yellow} \meta{black}} -% \item \texttt{rgb \meta{red} \meta{green} \meta{blue}} -% \end{itemize} -% Notice that the value are separated by spaces. There is a fourth pre-defined -% model using a string value and a numerical one: -% \begin{itemize} -% \item \texttt{spot \meta{name} \meta{tint}} A pre-defined spot color, -% where the \meta{name} should be a pre-defined string color name and the -% \meta{tint} should be in the range $[0,1]$. -% \end{itemize} -% -% Additional models may be created to allow mixing of spot colors. The -% number of data entries these require will depend on the number of -% colors to be mixed. -% \begin{texnote} -% The content of \cs{l_@@_current_tl} comprises two brace groups, the -% first containing the color model and the second containing the value(s) -% applicable in that model. -% \end{texnote} -% \end{variable} -% -% \begin{macro}{\color_group_begin:, \color_group_end:} -% Grouping for color is the same as using the basic \cs{group_begin:} -% and \cs{group_end:} functions. However, for semantic reasons, they -% are renamed here. -% \begin{macrocode} -\cs_new_eq:NN \color_group_begin: \group_begin: -\cs_new_eq:NN \color_group_end: \group_end: -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\color_ensure_current:} -% A driver-independent wrapper for setting the foreground color to the -% current color \enquote{now}. -% \begin{macrocode} -\cs_new_protected:Npn \color_ensure_current: - { - \@@_backend_pickup:N \l_@@_current_tl - \@@_select:N \l_@@_current_tl - } -% \end{macrocode} -% \end{macro} -% -% \begin{variable}{\s_@@_stop} -% Internal scan marks. -% \begin{macrocode} -\scan_new:N \s_@@_stop -% \end{macrocode} -% \end{variable} -% -% \begin{macro}{\@@_select:N} -% \begin{macro}{\@@_select:nn} -% Take an internal color specification and pass it to the driver. This code -% is needed to ensure the current color but will also be used by the -% higher-level experimental material. -% \begin{macrocode} -\cs_new_protected:Npn \@@_select:N #1 - { \exp_after:wN \@@_select:nn #1 } -\cs_new_protected:Npn \@@_select:nn #1#2 - { \use:c { @@_backend_select_ #1 :n } {#2} } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{variable}{\l_@@_current_tl} -% The current color, with the model and -% \begin{macrocode} -\tl_new:N \l_@@_current_tl -\tl_set:Nn \l_@@_current_tl { { gray } { 0 } } -% \end{macrocode} -% \end{variable} -% -% \begin{macrocode} -% -% \end{macrocode} -% -% \end{implementation} -% -% \PrintIndex diff --git a/Master/texmf-dist/source/latex/l3kernel/l3color.dtx b/Master/texmf-dist/source/latex/l3kernel/l3color.dtx new file mode 100644 index 00000000000..b3fd3cfa7a3 --- /dev/null +++ b/Master/texmf-dist/source/latex/l3kernel/l3color.dtx @@ -0,0 +1,2655 @@ +% \iffalse meta-comment +% +%% File: l3color.dtx +% +% Copyright (C) 2017-2021 The LaTeX Project +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% license or (at your option) any later version. The latest version +% of this license is in the file +% +% http://www.latex-project.org/lppl.txt +% +% This file is part of the "l3kernel bundle" (The Work in LPPL) +% and all files in that bundle must be distributed together. +% +% ----------------------------------------------------------------------- +% +% The development version of the bundle can be found at +% +% https://github.com/latex3/latex3 +% +% for those people who are interested. +% +%<*driver> +\documentclass[full]{l3doc} +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +% +% \fi +% +% \title{^^A +% The \textsf{l3color} package\\ Color support^^A +% } +% +% \author{^^A +% The \LaTeX{} Project\thanks +% {^^A +% E-mail: +% \href{mailto:latex-team@latex-project.org} +% {latex-team@latex-project.org}^^A +% }^^A +% } +% +% \date{Released 2021-02-18} +% +% \maketitle +% +% \begin{documentation} +% +% \section{Color in boxes} +% +% Controlling the color of text in boxes requires a small number of control +% functions, so that the boxed material uses the color at the point where +% it is set, rather than where it is used. +% +% \begin{function}[added = 2011-09-03]{\color_group_begin:, \color_group_end:} +% \begin{syntax} +% \cs{color_group_begin:} +% \ldots +% \cs{color_group_end:} +% \end{syntax} +% Creates a color group: one used to \enquote{trap} color settings. +% This grouping is built in to for example \cs{hbox_set:Nn}. +% \end{function} +% +% \begin{function}[added = 2011-09-03]{\color_ensure_current:} +% \begin{syntax} +% \cs{color_ensure_current:} +% \end{syntax} +% Ensures that material inside a box uses the foreground color +% at the point where the box is set, rather than that in force when the +% box is used. This function should usually be used within a +% \cs{color_group_begin:} \ldots \cs{color_group_end:} group. +% \end{function} +% +% \section{Color models} +% +% A color \emph{model} is a way to represent sets of colors. Different models +% are particularly suitable for different output methods, \emph{e.g.}~screen +% or print. Parameter-based models can describe a very large number of unique +% colors, and have a varying number of \emph{axes} which define a color +% space. In contrast, various proprietary models are available which define +% \emph{spot} colors (more formally separations). +% +% Core models are used to pass color information to output; these are +% \enquote{native} to \pkg{l3color}. Core models use real numbers in the range +% $[0,1]$ to represent values. The core models supported here are +% \begin{itemize} +% \item \texttt{gray} Grayscale color, with a single axis running from +% $0$ (fully black) to $1$ (fully white) +% \item \texttt{rgb} Red-green-blue color, with three axes, one for each of +% the components +% \item \texttt{cmyk} Cyan-magenta-yellow-black color, with four axes, one for +% each of the components +% \end{itemize} +% There are also interface models: these are convenient for users but have +% to be manipulated before storing/passing to the backend. Interface models +% are primarily integer-based: see below for more detail. The supported +% interface models are +% \begin{itemize} +% \item \texttt{Gray} Grayscale color, with a single axis running from +% $0$ (fully black) to $15$ (fully white) +% \item \texttt{hsb} Hue-saturation-brightness color, with three axes,all +% real values in the range $[0,1]$ for hue saturation and brightness +% \item \texttt{Hsb} Hue-saturation-brightness color, with three axes, integer +% in the range $[0,360]$ for hue, real values in the range $[0,1]$ for +% saturation and brightness +% \item \texttt{HSB} Hue-saturation-brightness color, with three axes, integers +% in the range $[0,240]$ for hue, saturation and brightness +% \item \texttt{HTML} HTML format representation of RGB color given as a +% single six-digit hexadecimal number +% \item \texttt{RGB} Red-green-blue color, with three axes, one for each of +% the components, values as integers from $0$ to $255$ +% \item \texttt{wave} Light wavelength, a real number in the range +% $380$ to $780$ (nanometres) +% \end{itemize} +% All interface models are internally stored as |rgb|. +% +% To allow parsing of data from \pkg{xcolor}, any leading model up the first +% \texttt{:} will be discarded; the approach of selecting an internal form +% for data is \emph{not} used in \pkg{l3color}. +% +% Additional models may be created to allow mixing of separation colors +% with each other or with those from other models. See +% Section~\ref{l3color:sec:new-models} for more detail of color support +% for additional models. +% +% When color is selected by model, the \meta{values} given are specified as +% a comma-separated list. The length of the list will therefore be determined +% by the detail of the model involved. +% +% Color models (and interconversion) are complex, and more details are given +% in the manual to the \LaTeXe{} \pkg{xcolor} package and in the +% \emph{PostScript Language Reference Manual}, published by Addison--Wesley. +% +% \section{Color expressions} +% +% In addition to allowing specification of color by model and values, +% \pkg{l3color} also supports color expressions. These are created +% by combining one or more color names, with the amount of each specified +% as a percentage. The latter is given between |!| symbols in the expression. +% Thus for example +% \begin{verbatim} +% red!50!green +% \end{verbatim} +% is a mixture of $50\,\%$ red and $50\,\%$ green. A trailing percentage is +% interpreted as implicitly followed by |white|, and so +% \begin{verbatim} +% red!25 +% \end{verbatim} +% specifies $25\,\%$ red mixed with $75\,\%$ white. +% +% Where the models for the mixed colors are different, the model of the first +% color is used. Thus +% \begin{verbatim} +% red!50!cyan +% \end{verbatim} +% will result in a color specification using the |rgb| model, made up of +% $50\,\%$ red and $50\,\%$ of cyan \emph{expressed in \texttt{rgb}}. As color +% model interconversion is not exact. +% +% The one exception to the above is where the first model in an expression is +% |gray|. In this case, the order of mixing is \enquote{swapped} internally, so +% that for example +% \begin{verbatim} +% black!50!red +% \end{verbatim} +% has the same result as +% \begin{verbatim} +% red!50!black +% \end{verbatim} +% (the predefined colors |black| and |white| use the |gray| model). +% +% Where more than two colors are mixed in an expression, evaluation takes place +% in a stepwise fashion. Thus in +% \begin{verbatim} +% cyan!50!magenta!10!yellow +% \end{verbatim} +% the sub-expression +% \begin{verbatim} +% cyan!50!magenta +% \end{verbatim} +% is first evaluated to give an intermediate color specification, before +% the second step +% \begin{verbatim} +% !10!yellow +% \end{verbatim} +% where || represents this transitory calculated value. +% +% Within a color expression, |.| may be used to represent the color active +% for typesetting (the current color). This allows for example +% \begin{verbatim} +% .!50 +% \end{verbatim} +% to mean a mixture of $50\,\%$ of current color with white. +% +% (Color expressions supported here are a subset of those provided by +% the \LaTeXe{} \pkg{xcolor} package. At present, only such features as are +% clearly useful have been added here.) +% +% \section{Named colors} +% +% Color names are stored in a single namespace, which makes them accessible +% as part of color expressions. Whilst they are not reserved in a technical +% sense, the names |black|, |white|, |red|, |green|, |blue|, |cyan|, |magenta| +% and |yellow| have special meaning and should not be redefined. Color names +% should be made up of letters, numbers and spaces only: other characters are +% reserved for use in color expressions. In particular, |.| represents the +% current color at the start of a color expression. +% +% \begin{function}{\color_set:nn} +% \begin{syntax} +% \cs{color_set:nn} \Arg{name} \Arg{color expression} +% \end{syntax} +% Evaluates the \meta{color expression} and stores the resulting +% color specification as the \meta{name}. +% \end{function} +% +% \begin{function}{\color_set:nnn} +% \begin{syntax} +% \cs{color_set:nnn} \Arg{name} \Arg{model(s)} \Arg{value(s)} +% \end{syntax} +% Stores the color specification equivalent to the \meta{model(s)} and +% \meta{values} as the \meta{name}. +% \end{function} +% +% \begin{function}{\color_set_eq:nn} +% \begin{syntax} +% \cs{color_set_eq:nn} \Arg{name1} \Arg{name2} +% \end{syntax} +% Copies the color specification in \meta{name2} to \meta{name1}. The +% special name |.| may be used to represent the current color, allowing +% it to be saved to a name. +% \end{function} +% +% \begin{function}{\color_show:n} +% \begin{syntax} +% \cs{color_show:n} \Arg{name} +% \end{syntax} +% Displays the color specification stored in the \meta{name} on the +% terminal. +% \end{function} +% +% \section{Selecting colors} +% +% General selection of color is safe when split across pages: a stack is +% used to ensure that the correct color is re-selected on the new page. +% +% \begin{function}{\color_select:n} +% \begin{syntax} +% \cs{color_select:n} \Arg{color expression} +% \end{syntax} +% Parses the \meta{color expression} and then activates the resulting +% color specification for typeset material. +% \end{function} +% +% \begin{function}{\color_select:nn} +% \begin{syntax} +% \cs{color_select:nn} \Arg{model(s)} \Arg{value(s)} +% \end{syntax} +% Activates the color specification equivalent to the \meta{model(s)} and +% \meta{value(s)} for typeset material. +% \end{function} +% +% \begin{variable}{\l_color_fixed_model_tl} +% When this is set to a non-empty value, colors will be converted to +% the specified model when they are selected. Note that included images +% and similar are not influenced by this setting. +% \end{variable} +% +% \section{Colors for fills and strokes} +% +% Colors for drawing operations and so forth are split into strokes and fills +% (the latter may also be referred to as non-stroke color). The fill color is +% used for text under normal circumstances. Depending on the backend, stroke +% color may use a \emph{stack}, in which case it exhibits the same page breaking +% behavior as general color. However, \texttt{dvips}/\texttt{dvisvgm} do not +% support this, and so color will need to be contained within a scope, such +% as \cs{draw_begin:}/\cs{draw_end:}. +% +% Note that the \emph{current color} is the fill color, as this is used for +% running text. +% +% \begin{function}{\color_fill:n, \color_stroke:n} +% \begin{syntax} +% \cs{color_fill:n} \Arg{color expression} +% \end{syntax} +% Parses the \meta{color expression} and then activates the resulting +% color specification for filling or stroking. +% \end{function} +% +% \begin{function}{\color_fill:nn, \color_stroke:nn} +% \begin{syntax} +% \cs{color_fill:nn} \Arg{model(s)} \Arg{value(s)} +% \end{syntax} +% Activates the color specification equivalent to the \meta{model(s)} and +% \meta{value(s)} for filling or stroking. +% \end{function} +% +% \begin{variable}{color.sc} +% When using \texttt{dvips}, this PostScript variables hold the stroke color. +% \end{variable} +% +% \section{Multiple color models} +% +% When selecting or setting a color with an explicit model, it is possible +% to give values for more than one model at one time. This is particularly +% useful where automated conversion between models does not give the desired +% outcome. To do this, the list of models and list of values are both subdivided +% using |/| characters (as for the similar function in \pkg{xcolor}). For +% example, to save a color with explicit |cmyk| and |rgb| values, one could +% use +% \begin{verbatim} +% \color_set:nnn { foo } { cmyk / rgb } +% { 0.1 , 0.2 , 0.3 , 0.4 / 0.1, 0.2 , 0.3 } +% \end{verbatim} +% The manually-specified conversion will be used in preference to automated +% calculation whenever the model(s) listed are used: both in expressions and +% when a fixed model is active. +% +% Similarly, the same syntax can be applied to directly selecting a color. +% \begin{verbatim} +% \color_select:nn { cmyk / rgb } +% { 0.1 , 0.2 , 0.3 , 0.4 / 0.1, 0.2 , 0.3 } +% \end{verbatim} +% Again, this list is used when a fixed model is active: the first entry is used +% unless there is a fixed model matching one of the other entries. +% +% \section{Exporting color specifications} +% +% The major use of color expressions is in setting typesetting output, but there +% are other places in which some form of color information is required. These +% may need data in a different format or using a different model to the internal +% representation. Thus a set of functions are available to export colors in +% different formats. +% +% Valid export targets are +% \begin{itemize} +% \item \texttt{backend} Two brace groups: the first containing the +% model, the second containing space-separated values appropriate +% for the model; this is the format required by backend functions +% of \pkg{expl3} +% \item \texttt{HTML} Uppercase two-digit hexadecimal values, expressing +% a red-green-blue color; the digits are \emph{not} separated +% \item \texttt{space-sep-cmyk} Space-separated cyan-magenta-yellow-black +% values +% \item \texttt{space-sep-rgb} Space-separated red-green-blue values +% suitable for use as a PDF annotation color +% \end{itemize} +% +% \begin{function}{\color_export:nnN} +% \begin{syntax} +% \cs{color_export:nnN} \Arg{color expression} \Arg{format} \Arg{tl} +% \end{syntax} +% Parses the \meta{color expression} as described earlier, +% then converts to the \meta{format} specified and assigns the data to the +% \meta{tl}. +% \end{function} +% +% \begin{function}{\color_export:nnnN} +% \begin{syntax} +% \cs{color_export:nnnN} \Arg{model} \Arg{value(s)} \Arg{format} \Arg{tl} +% \end{syntax} +% Expresses the combination of \meta{model} and \meta{value(s)} in an +% internal representation, then converts to the \meta{format} specified and +% assigns the data to the \meta{tl}. +% \end{function} +% +% \section{Creating new color models} +% \label{l3color:sec:new-models} +% +% Additional color models are required to support specialist workflows, for +% example those involving separations (see +% \url{https://helpx.adobe.com/indesign/using/spot-process-colors.html} +% for details of the use of separations in print). Color models may be split +% into families; for the standard device-based color models (\texttt{DeviceCMYK}, +% \texttt{DeviceRGB}, \texttt{DeviceGray}), these are synonymous. This +% is not generally the case: see the PDF reference for more details. (Note that +% \pkg{l3color} uses the shorter names \texttt{cmyk}, etc.) +% +% \begin{function}{\color_model_new:nnn} +% \begin{syntax} +% \cs{color_model_new:nnn} \Arg{model} \Arg{family} \Arg{params} +% \end{syntax} +% Creates a new \meta{model} which is derived from the color model \meta{family}. +% The latter should be one of +% \begin{itemize} +% \item \texttt{DeviceN} +% \item \texttt{Separation} +% \end{itemize} +% (The \meta{family} may be given in mixed case as-in the PDF reference: +% internally, case of these strings is folded.) +% Depending on the \meta{family}, one or more \meta{params} are mandatory or +% optional. +% \end{function} +% +% For a \texttt{Separation} space, there are three \emph{compulsory} keys. +% \begin{itemize} +% \item \texttt{name} The name of the Separation, for example the formal +% name of a spot color ink. Such a \meta{name} may contain spaces, etc., +% which are not permitted in the \meta{model}. +% \item \texttt{alternative-model} An alternative device colorspace, one of +% \texttt{cmyk}, \texttt{rgb}, \texttt{gray} or \texttt{CIELAB}. The three +% parameter-based models work as described above; see below for +% details of CIELAB colors. +% \item \texttt{alternative-values} A comma-separated list of values +% appropriate to the \texttt{alternative-model}. This information is used by +% the PDF application if the \texttt{Separation} is not available. +% \end{itemize} +% +% CIELAB color separations are created using the +% \texttt{alternative-model = CIELAB} setting. These colors must also have an +% \texttt{illuminant} key, one of \texttt{a}, \texttt{c}, \texttt{e}, +% \texttt{d50}, \texttt{d55}, \texttt{d65} or \texttt{d75}. The +% \texttt{alternative-values} in this case are the three parameters $L*$, $a*$ +% and $b*$ of the CIELAB model. Full details of this device-independent color +% approach are given in the documentation to the \pkg{colorspace} package. +% +% CIELAB colors \emph{cannot} be converted into other device-dependent color +% spaces, and as such, mixing can only occur if colors set up using the CIELAB +% model are also given with an alternative parameter-based model. If that is +% not the case, \pkg{l3color} will fallback to using black as the colorant in +% any mixing. +% +% For a \texttt{DeviceN} space, there is one \emph{compulsory} key. +% \begin{itemize} +% \item \texttt{names} The names of the components of the \texttt{DeviceN} +% space. Each should be either the \meta{name} of a \texttt{Separation} model, +% a process color name (\texttt{cyan}, etc.) or the special name \texttt{none}. +% \end{itemize} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3color} Implementation} +% +% \begin{macrocode} +%<*package> +% \end{macrocode} +% +% \begin{macrocode} +%<@@=color> +% \end{macrocode} +% +% \subsection{Basics} +% +% \begin{variable} +% {\l_@@_current_tl} +% The color currently active for foreground (text, \emph{etc.}) material. +% This is stored in the form of a color model followed by one or more +% values. There are four pre-defined models, three of which take numerical +% values in the range $[0,1]$: +% \begin{itemize} +% \item \texttt{gray \meta{gray}} Grayscale color with the \meta{gray} +% value running from $0$ (fully black) to $1$ (fully white) +% \item \texttt{cmyk \meta{cyan} \meta{magenta} \meta{yellow} \meta{black}} +% \item \texttt{rgb \meta{red} \meta{green} \meta{blue}} +% \end{itemize} +% Notice that the value are separated by spaces. There is a fourth pre-defined +% model using a string value and a numerical one: +% \begin{itemize} +% \item \texttt{spot \meta{name} \meta{tint}} A pre-defined spot color, +% where the \meta{name} should be a pre-defined string color name and the +% \meta{tint} should be in the range $[0,1]$. +% \end{itemize} +% +% Additional models may be created to allow mixing of spot colors. The +% number of data entries these require will depend on the number of +% colors to be mixed. +% \begin{texnote} +% The content of \cs{l_@@_current_tl} comprises two brace groups, the +% first containing the color model and the second containing the value(s) +% applicable in that model. +% \end{texnote} +% \end{variable} +% +% \begin{macro}{\color_group_begin:, \color_group_end:} +% Grouping for color is the same as using the basic \cs{group_begin:} +% and \cs{group_end:} functions. However, for semantic reasons, they +% are renamed here. +% \begin{macrocode} +\cs_new_eq:NN \color_group_begin: \group_begin: +\cs_new_eq:NN \color_group_end: \group_end: +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\color_ensure_current:} +% A driver-independent wrapper for setting the foreground color to the +% current color \enquote{now}. +% \begin{macrocode} +\cs_new_protected:Npn \color_ensure_current: + { + \@@_backend_pickup:N \l_@@_current_tl + \@@_select:N \l_@@_current_tl + } +% \end{macrocode} +% \end{macro} +% +% \begin{variable}{\s_@@_stop} +% Internal scan marks. +% \begin{macrocode} +\scan_new:N \s_@@_stop +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_select:N} +% \begin{macro}{\@@_select:nn} +% Take an internal color specification and pass it to the driver. This code +% is needed to ensure the current color but will also be used by the +% higher-level experimental material. +% \begin{macrocode} +\cs_new_protected:Npn \@@_select:N #1 + { \exp_after:wN \@@_select:nn #1 } +\cs_new_protected:Npn \@@_select:nn #1#2 + { \use:c { @@_backend_select_ #1 :n } {#2} } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{variable}{\l_@@_current_tl} +% The current color, with the model and +% \begin{macrocode} +\tl_new:N \l_@@_current_tl +\tl_set:Nn \l_@@_current_tl { { gray } { 0 } } +% \end{macrocode} +% \end{variable} + +% +% \subsection{Predefined color names} +% +% The ability to predefine colors with a name is a key part of this module and +% means there has to be a method for storing the results. At first sight, it +% seems natural to follow the usual \pkg{expl3} model and create a +% \texttt{color} variable type for the process. That would then allow both +% local and global colors, constant colors and the like. However, these names +% need to be accessible in some form at the user level, for selection of colors +% either simply by name or as part of a more complex expression. This does not +% require that the full name is exposed but does require that they can be +% looked up in a predictable way. As such, it is more useful to expose just the +% color names as part of the interface, with the result that only local color +% names can be created. (This is also seen for example in key creation in +% \pkg{l3keys}.) As a result, color names are declarative (no \texttt{new} +% functions). +% +% Since there is no need to manipulate colors \emph{en masse}, each is stored +% in a two-part structure: a \texttt{prop} for the colors themselves, and a +% \texttt{tl} for the default model for each color. +% +% \subsection{Setup} +% +% \begin{variable}{\l_@@_internal_int, \l_@@_internal_tl} +% \begin{macrocode} +\int_new:N \l_@@_internal_int +\tl_new:N \l_@@_internal_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\s_@@_mark} +% Internal scan marks. \cs{s_@@_stop} is already defined in \pkg{l3color-base}. +% \begin{macrocode} +\scan_new:N \s_@@_mark +% \end{macrocode} +% \end{variable} +% +% \subsection{Utility functions} +% +% \begin{macro}[int, TF, EXP]{\@@_if_defined:n} +% A simple wrapper to avoid needing to have the lookup repeated in too many +% places. +% \begin{macrocode} +\prg_new_conditional:Npnn \@@_if_defined:n #1 { T, F, TF } + { + \prop_if_exist:cTF { l_@@_named_ #1 _prop } + \prg_return_true: + \prg_return_false: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_model:N, \@@_values:N} +% Simple abstractions. +% \begin{macrocode} +\cs_new:Npn \@@_model:N #1 { \exp_after:wN \use_i:nn #1 } +\cs_new:Npn \@@_values:N #1 { \exp_after:wN \use_ii:nn #1 } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_extract:nNN, \@@_extract:VNN} +% Recover the values for the standard model for a color. +% \begin{macrocode} +\cs_new_protected:Npn \@@_extract:nNN #1#2#3 + { + \tl_set_eq:Nc #2 { l_@@_named_ #1 _tl } + \prop_get:cVN { l_@@_named_ #1 _prop } #2 #3 + } +\cs_generate_variant:Nn \@@_extract:nNN { V } +% \end{macrocode} +% \end{macro} +% +% \subsection{Model conversion} +% +% \begin{macro}{\@@_convert:nnN, \@@_convert:VVN} +% \begin{macro}{\@@_convert:nnnN, \@@_convert:nVnN, \@@_convert:nnVN} +% \begin{macro}[aux, EXP] +% { +% \@@_convert_gray_rgb:w +% \@@_convert_gray_cmyk:w +% \@@_convert_cmyk_gray:w +% \@@_convert_cmyk_rgb:w +% \@@_convert_rgb_gray:w +% \@@_convert_rgb_cmyk:w +% } +% \begin{macro}[aux, EXP]{\@@_convert_rgb_cmyk:nnnn} +% Model conversion is carried out using standard formulae, as described in +% the manual for \pkg{xcolor} (see also the \emph{PostScript Language +% Reference Manual}). +% \begin{macrocode} +\cs_new_protected:Npn \@@_convert:nnN #1#2#3 + { \@@_convert:nnVN {#1} {#2} #3 #3 } +\cs_generate_variant:Nn \@@_convert:nnN { VV } +\cs_new_protected:Npn \@@_convert:nnnN #1#2#3#4 + { + \tl_set:Nx #4 + { + \cs_if_exist:cTF { @@_convert_ #1 _ #2 :w } + { \use:c { @@_convert_ #1 _ #2 :w } #3 ~ 0 ~ 0 ~ 0 \s_@@_stop } + { \use:c { c_@@_fallback_ #2 _tl } } + } + } +\cs_generate_variant:Nn \@@_convert:nnnN { nV , nnV } +\cs_new:Npn \@@_convert_gray_rgb:w #1 ~ #2 \s_@@_stop + { #1 ~ #1 ~ #1 } +\cs_new:Npn \@@_convert_gray_cmyk:w #1 ~ #2 \s_@@_stop + { 0 ~ 0 ~ 0 ~ \fp_eval:n { 1 - #1 } } +% \end{macrocode} +% These rather odd values are based on \textsc{ntsc} television: the set are +% used for the |cmyk| conversion. +% \begin{macrocode} +\cs_new:Npn \@@_convert_rgb_gray:w #1 ~ #2 ~ #3 ~ #4 \s_@@_stop + { \fp_eval:n { 0.3 * #1 + 0.59 * #2 + 0.11 * #3 } } +% \end{macrocode} +% The conversion from |rgb| to |cmyk| is the most complex: a two-step +% procedure which requires \emph{black generation} and \emph{undercolor +% removal} functions. The PostScript reference describes them as +% device-dependent, but following \pkg{xcolor} we assume they are linear. +% Moreover, as the likelihood of anyone using a non-unitary matrix here is +% tiny, we simplify and treat those two concepts as no-ops. +% \begin{macrocode} +\cs_new:Npn \@@_convert_rgb_cmyk:w #1 ~ #2 ~ #3 ~ #4 \s_@@_stop + { + \exp_args:Nf \@@_convert_rgb_cmyk:nnnn + { \fp_eval:n { min ( 1 - #1 , 1 - #2 , 1 - #3 ) } } {#1} {#2} {#3} + } +\cs_new:Npn \@@_convert_rgb_cmyk:nnnn #1#2#3#4 + { + \fp_eval:n { min ( 1 , max ( 0 , 1 - #2 - #1 ) ) } \c_space_tl + \fp_eval:n { min ( 1 , max ( 0 , 1 - #3 - #1 ) ) } \c_space_tl + \fp_eval:n { min ( 1 , max ( 0 , 1 - #4 - #1 ) ) } \c_space_tl + #1 + } +\cs_new:Npn \@@_convert_cmyk_gray:w #1 ~ #2 ~ #3 ~ #4 ~ #5 \s_@@_stop + { \fp_eval:n { 1 - min ( 1 , 0.3 * #1 + 0.59 * #2 + 0.11 * #3 + #4 ) } } +\cs_new:Npn \@@_convert_cmyk_rgb:w #1 ~ #2 ~ #3 ~ #4 ~ #5 \s_@@_stop + { + \fp_eval:n { 1 - min ( 1 , #1 + #4 ) } \c_space_tl + \fp_eval:n { 1 - min ( 1 , #2 + #4 ) } \c_space_tl + \fp_eval:n { 1 - min ( 1 , #3 + #4 ) } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Color expressions} +% +% \begin{variable} +% {\l_@@_model_tl, \l_@@_value_tl, \l_@@_next_model_tl, \l_@@_next_value_tl} +% Working space to store the color data whilst doing calculations: keeping +% it on the stack is attractive but gets tricky (return is non-trivial). +% \begin{macrocode} +\tl_new:N \l_@@_model_tl +\tl_new:N \l_@@_value_tl +\tl_new:N \l_@@_next_model_tl +\tl_new:N \l_@@_next_value_tl +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_parse:nN} +% \begin{macro}{\@@_parse_aux:nN} +% \begin{macro}{\@@_parse_eq:Nn} +% \begin{macro}{\@@_parse_eq:nNn} +% \begin{macro}{\@@_parse:Nw} +% \begin{macro}{\@@_parse_loop_init:Nnn} +% \begin{macro}{\@@_parse_loop:w} +% \begin{macro}{\@@_parse_loop:nn} +% \begin{macro}{\@@_parse_gray:n, \@@_parse_std:n} +% \begin{macro}{\@@_parse_break:w} +% \begin{macro}{\@@_parse_end:} +% \begin{macro}[aux, EXP]{\@@_parse_mix:Nnnn, \@@_parse_mix:NVVn} +% \begin{macro}[aux, EXP]{\@@_parse_mix:nNnn} +% \begin{macro}[aux, EXP] +% { +% \@@_parse_mix_gray:nw , +% \@@_parse_mix_rgb:nw , +% \@@_parse_mix_cmyk:nw +% } +% The main function for parsing color expressions removes actives but +% otherwise expands, then starts working through the expression itself. +% At the end, we apply the payload. +% \begin{macrocode} +\cs_new_protected:Npx \@@_parse:nN #1#2 + { + \exp_not:N \@@_backend_pickup:N \exp_not:N \l_@@_current_tl + \tl_set:Nx \exp_not:c { l_@@_named_ . _tl } + { \exp_not:N \@@_model:N \exp_not:N \l_@@_current_tl } + \prop_put:NVx \exp_not:c { l_@@_named_ . _prop } + \exp_not:c { l_@@_named_ . _tl } + { \exp_not:N \@@_values:N \exp_not:N \l_@@_current_tl } + \exp_not:N \exp_args:Ne \exp_not:N \@@_parse_aux:nN + { \exp_not:N \tl_to_str:n {#1} } #2 + } +% \end{macrocode} +% Before going to all of the effort of parsing an expression, these two +% precursor functions look for a pre-defined name, either on its own or +% with a trailing |!| (which is the same thing). +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_aux:nN #1#2 + { + \tl_if_exist:cTF { l_@@_named_ #1 _prop } + { \@@_parse_set_eq:Nn #2 {#1} } + { \@@_parse:Nw #2#1 ! \s_@@_stop } + \@@_check_model:N #2 + } +\cs_new_protected:Npn \@@_parse_set_eq:Nn #1#2 + { + \tl_if_empty:NTF \l_color_fixed_model_tl + { \exp_args:Nv \@@_parse_set_eq:nNn { l_@@_named_ #2 _tl } } + { \exp_args:NV \@@_parse_set_eq:nNn \l_color_fixed_model_tl } + #1 {#2} + } +% \end{macrocode} +% Here, we have to allow for the case where there is a fixed model: +% that can't be swept up by generic conversion as we are dealing with a +% named color. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_set_eq:nNn #1#2#3 + { + \prop_get:cnNTF + { l_@@_named_ #3 _prop } {#1} + \l_@@_value_tl + { \tl_set:Nx #2 { {#1} { \l_@@_value_tl } } } + { + \tl_set_eq:Nc \l_@@_model_tl { l_@@_named_ #3 _tl } + \prop_get:cVN { l_@@_named_ #3 _prop } \l_@@_model_tl + \l_@@_value_tl + \@@_convert:nnN + \l_@@_model_tl {#1} \l_@@_value_tl + \tl_set:Nx #2 + { + {#1} + { \l_@@_value_tl } + } + } + } +\cs_new_protected:Npn \@@_parse:Nw #1#2 ! #3 \s_@@_stop + { + \@@_if_defined:nTF {#2} + { + \tl_if_blank:nTF {#3} + { \@@_parse_set_eq:Nn #1 {#2} } + { \@@_parse_loop_init:Nnn #1 {#2} {#3} } + } + { + \__kernel_msg_error:nnn { color } { unknown-color } {#2} + \tl_set:Nn \l_@@_current_tl { { gray } { 0 } } + } + } +% \end{macrocode} +% Once we establish that a full parse is needed, the next job is to get the +% detail of the first color. That will determine the model we use for the +% calculation: splitting here makes checking that a bit easier. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_loop_init:Nnn #1#2#3 + { + \group_begin: + \@@_extract:nNN {#2} \l_@@_model_tl \l_@@_value_tl + \@@_parse_loop:w #3 ! ! ! ! \s_@@_stop + \tl_set:Nx \l_@@_internal_tl + { { \l_@@_model_tl } { \l_@@_value_tl } } + \exp_args:NNNV \group_end: + \tl_set:Nn #1 \l_@@_internal_tl + } +% \end{macrocode} +% This is the loop proper: there can be an open-ended set of colors to parse, +% separated by |!| tokens. There are a few cases to look out for. At the end +% of the expression and with we find a mix of $100$ then we simply skip the +% next color entirely (we can't stop the loop as there might be a further +% valid color to mix in). On the other hand, if we get a mix of $0$ then +% drop everything so far and start again. There is also a trailing +% |white| to \enquote{read in} if the final explicit data is a mix. +% Those conditions are separate from actually looping, which is therefore +% sorted out by checking if we have further data to process: in contrast +% to \pkg{xcolor}, we don't allow |!!| so the test can be simplified. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_loop:w #1 ! #2 ! #3 ! #4 ! #5 \s_@@_stop + { + \bool_lazy_or:nnF + { \tl_if_blank_p:n {#1} } + { \int_compare_p:nNn {#1} = { 100 } } + { + \int_compare:nNnTF {#1} = { 0 } + { + \tl_if_blank:nTF {#2} + { \@@_extract:nNN { white } } + { \@@_extract:nNN {#2} } + \l_@@_model_tl \l_@@_value_tl + } + { + \use:x + { + \@@_parse_loop:nn {#1} + { \tl_if_blank:nTF {#2} { white } {#2} } + } + } + } + \tl_if_blank:nF {#3} + { \@@_parse_loop:w #3 ! #4 ! #5 \s_@@_stop } + \@@_parse_end: + } +% \end{macrocode} +% The \enquote{payload} of calculation in the loop first. If the model for +% the upcoming color is different from that of the existing (partial) color, +% convert the model. For |gray| the two are flipped round so that the outcome +% is something with \enquote{real} color. We are then in a position to do the +% actual calculation itself. The two auxiliaries here give us a way to break +% the loop should an invalid name be found. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_loop:nn #1#2 + { + \@@_if_defined:nTF {#2} + { + \@@_extract:nNN {#2} \l_@@_next_model_tl \l_@@_next_value_tl + \tl_if_eq:NNF \l_@@_model_tl \l_@@_next_model_tl + { + \str_if_eq:VnTF \l_@@_model_tl { gray } + { \@@_parse_gray:n {#2} } + { \@@_parse_std:n {#2} } + } + \tl_set:Nx \l_@@_value_tl + { + \@@_parse_mix:NVVn + \l_@@_model_tl \l_@@_value_tl \l_@@_next_value_tl {#1} + } + } + { + \__kernel_msg_error:nnn { color } { unknown-color } {#2} + \@@_extract:nNN { black } \l_@@_model_tl \l_@@_value_tl + \@@_parse_break:w + } + } +% \end{macrocode} +% The \texttt{gray} model needs special handling: the models need to be +% swapped: we do that using a dedicated function. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_gray:n #1 + { + \tl_set_eq:NN \l_@@_model_tl \l_@@_next_model_tl + \tl_set:Nn \l_@@_next_model_tl { gray } + \exp_args:NnV \@@_convert:nnN { gray } \l_@@_model_tl + \l_@@_value_tl + \prop_get:cVN { l_@@_named_ #1 _prop } \l_@@_model_tl + \l_@@_next_value_tl + } +\cs_new_protected:Npn \@@_parse_std:n #1 + { + \prop_get:cVNF { l_@@_named_ #1 _prop } + \l_@@_model_tl + \l_@@_next_value_tl + { + \@@_convert:VVN + \l_@@_next_model_tl + \l_@@_model_tl + \l_@@_next_value_tl + } + } +\cs_new_protected:Npn \@@_parse_break:w #1 \@@_parse_end: { } +\cs_new_protected:Npn \@@_parse_end: { } +% \end{macrocode} +% Do the vector arithmetic: mainly a question of shuffling input, along +% with one pre-calculation to keep down the use of division. +% \begin{macrocode} +\cs_new:Npn \@@_parse_mix:Nnnn #1#2#3#4 + { + \exp_args:Nf \@@_parse_mix:nNnn + { \fp_eval:n { #4 / 100 } } + #1 {#2} {#3} + } +\cs_generate_variant:Nn \@@_parse_mix:Nnnn { NVV } +\cs_new:Npn \@@_parse_mix:nNnn #1#2#3#4 + { + \use:c { @@_parse_mix_ #2 :nw } {#1} + #3 \s_@@_mark #4 \s_@@_stop + } +\cs_new:Npn \@@_parse_mix_gray:nw #1#2 \s_@@_mark #3 \s_@@_stop + { \fp_eval:n { #2 * #1 + #3 * ( 1 - #1 ) } } +\cs_new:Npn \@@_parse_mix_rgb:nw + #1#2 ~ #3 ~ #4 \s_@@_mark #5 ~ #6 ~ #7 \s_@@_stop + { + \fp_eval:n { #2 * #1 + #5 * ( 1 - #1 ) } \c_space_tl + \fp_eval:n { #3 * #1 + #6 * ( 1 - #1 ) } \c_space_tl + \fp_eval:n { #4 * #1 + #7 * ( 1 - #1 ) } + } +\cs_new:Npn \@@_parse_mix_cmyk:nw + #1#2 ~ #3 ~ #4 ~ #5 \s_@@_mark #6 ~ #7 ~ #8 ~ #9 \s_@@_stop + { + \fp_eval:n { #2 * #1 + #6 * ( 1 - #1 ) } \c_space_tl + \fp_eval:n { #3 * #1 + #7 * ( 1 - #1 ) } \c_space_tl + \fp_eval:n { #4 * #1 + #8 * ( 1 - #1 ) } \c_space_tl + \fp_eval:n { #5 * #1 + #9 * ( 1 - #1 ) } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP] +% { +% \@@_parse_model_gray:w, \@@_parse_model_rgb:w, +% \@@_parse_model_cmyk:w +% } +% \begin{macro}[EXP]{\@@_parse_number:n} +% \begin{macro}[EXP]{\@@_parse_number:w} +% Turn the input into internal form, also tidying up the number quickly. +% \begin{macrocode} +\cs_new:Npn \@@_parse_model_gray:w #1 , #2 \s_@@_stop + { { gray } { \@@_parse_number:n {#1} } } +\cs_new:Npn \@@_parse_model_rgb:w #1 , #2 , #3 , #4 \s_@@_stop + { + { rgb } + { + \@@_parse_number:n {#1} ~ + \@@_parse_number:n {#2} ~ + \@@_parse_number:n {#3} + } + } +\cs_new:Npn \@@_parse_model_cmyk:w #1 , #2 , #3 , #4 , #5 \s_@@_stop + { + { cmyk } + { + \@@_parse_number:n {#1} ~ + \@@_parse_number:n {#2} ~ + \@@_parse_number:n {#3} ~ + \@@_parse_number:n {#4} + } + } +\cs_new:Npn \@@_parse_number:n #1 + { \@@_parse_number:w #1 . 0 . \s_@@_stop } +\cs_new:Npn \@@_parse_number:w #1 . #2 . #3 \s_@@_stop + { \tl_if_blank:nTF {#1} { 0 } {#1} . #2 } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP] +% { +% \@@_parse_model_Gray:w, \@@_parse_model_hsb:w, +% \@@_parse_model_Hsb:w, \@@_parse_model_HSB:w, +% \@@_parse_model_HTML:w, \@@_parse_model_RGB:w +% } +% \begin{macro}[EXP]{\@@_parse_model_hsb:nnn, \@@_parse_model_hsb_aux:nnn} +% \begin{macro}[EXP]{\@@_parse_model_hsb:nnnn} +% \begin{macro}[EXP]{\@@_parse_model_hsb:nnnnn} +% \begin{macro}[EXP] +% { +% \@@_parse_model_hsb_0:nnnn , +% \@@_parse_model_hsb_1:nnnn , +% \@@_parse_model_hsb_2:nnnn , +% \@@_parse_model_hsb_3:nnnn , +% \@@_parse_model_hsb_4:nnnn , +% \@@_parse_model_hsb_5:nnnn +% } +% \begin{macro}[EXP]{\@@_parse_model_wave:w} +% \begin{macro}[EXP] +% {\@@_parse_model_wave_auxi:nn, \@@_parse_model_wave_auxii:nn} +% \begin{macro}[EXP]{\@@_parse_model_wave_rho:n} +% \begin{macrocode} +\cs_new:Npn \@@_parse_model_Gray:w #1 , #2 \s_@@_stop + { { gray } { \fp_eval:n { #1 / 15 } } } +\cs_new:Npn \@@_parse_model_hsb:w #1 , #2 , #3 , #4 \s_@@_stop + { \@@_parse_model_hsb:nnn {#1} {#2} {#3} } +\cs_new:Npn \@@_parse_model_Hsb:w #1 , #2 , #3 , #4 \s_@@_stop + { + \exp_args:Ne \@@_parse_model_hsb:nnn { \fp_eval:n { #1 / 360 } } + {#2} {#3} + } +% \end{macrocode} +% The conversion here is non-trivial but is described at length +% in the \pkg{xcolor} manual. For ease, we calculate the integer +% and fractional parts of the hue first, then use them to work out the +% possible values for $r$, $g$ and $b$ before putting them in the correct +% places. +% \begin{macrocode} +\cs_new:Npn \@@_parse_model_hsb:nnn #1#2#3 + { + { rgb } + { + \exp_args:Ne \@@_parse_model_hsb_aux:nnn + { \fp_eval:n { 6 * #1 } } {#2} {#3} + } + } +\cs_new:Npn \@@_parse_model_hsb_aux:nnn #1#2#3 + { + \exp_args:Nee \@@_parse_model_hsb_aux:nnnn + { \fp_eval:n { floor(#1) } } { \fp_eval:n { #1 - floor(#1) } } + {#2} {#3} + } +\cs_new:Npn \@@_parse_model_hsb_aux:nnnn #1#2#3#4 + { + \use:e + { + \exp_not:N \@@_parse_model_hsb_aux:nnnnn + { \@@_parse_number:n {#4} } + { \fp_eval:n { round(#4 * (1 - #3) ,5) } } + { \fp_eval:n { round(#4 * ( 1 - #3 * #2 ) ,5) } } + { \fp_eval:n { round(#4 * ( 1 - #3 * (1 - #2) ) ,5) } } + {#1} + } + } +\cs_new:Npn \@@_parse_model_hsb_aux:nnnnn #1#2#3#4#5 + { \use:c { @@_parse_model_hsb_ #5 :nnnn } {#1} {#2} {#3} {#4} } +\cs_new:cpn { @@_parse_model_hsb_0:nnnn } #1#2#3#4 { #1 ~ #4 ~ #2 } +\cs_new:cpn { @@_parse_model_hsb_1:nnnn } #1#2#3#4 { #3 ~ #1 ~ #2 } +\cs_new:cpn { @@_parse_model_hsb_2:nnnn } #1#2#3#4 { #2 ~ #1 ~ #4 } +\cs_new:cpn { @@_parse_model_hsb_3:nnnn } #1#2#3#4 { #2 ~ #3 ~ #1 } +\cs_new:cpn { @@_parse_model_hsb_4:nnnn } #1#2#3#4 { #4 ~ #2 ~ #1 } +\cs_new:cpn { @@_parse_model_hsb_5:nnnn } #1#2#3#4 { #1 ~ #2 ~ #3 } +\cs_new:cpn { @@_parse_model_hsb_6:nnnn } #1#2#3#4 { #1 ~ #2 ~ #2 } +\cs_new:Npn \@@_parse_model_HSB:w #1 , #2 , #3 , #4 \s_@@_stop + { + \exp_args:Neee \@@_parse_model_hsb:nnn + { \fp_eval:n {#1 / 240} } + { \fp_eval:n {#2 / 240} } + { \fp_eval:n {#3 / 240} } + } +\cs_new:Npn \@@_parse_model_HTML:w #1 , #2 \s_@@_stop + { \@@_parse_model_HTML_aux:w #1 0 0 0 0 0 0 \s_@@_stop } +\cs_new:Npn \@@_parse_model_HTML_aux:w #1#2#3#4#5#6#7 \s_@@_stop + { + { rgb } + { + \fp_eval:n { round(\int_from_hex:n {#1#2} / 255,5) } ~ + \fp_eval:n { round(\int_from_hex:n {#3#4} / 255,5) } ~ + \fp_eval:n { round(\int_from_hex:n {#5#6} / 255,5) } + } + } +\cs_new:Npn \@@_parse_model_RGB:w #1 , #2 , #3 , #4 \s_@@_stop + { + { rgb } + { + \fp_eval:n { round(#1 / 255,5) } ~ + \fp_eval:n { round(#2 / 255,5) } ~ + \fp_eval:n { round(#3 / 255,5) } + } + } +% \end{macrocode} +% Following the description in the \pkg{xcolor} manual. As we always use |rgb|, +% there is no need to find the sixth, we just pas the information straight +% to the |hsb| auxiliary defined earlier. +% \begin{macrocode} +\cs_new:Npn \@@_parse_model_wave:w #1 , #2 \s_@@_stop + { + { rgb } + { + \fp_compare:nNnTF {#1} < { 420 } + { \@@_parse_model_wave_auxi:nn {#1} { 0.3 + 0.7 * (#1 - 380) / 40 } + } + { + \fp_compare:nNnTF {#1} > { 700 } + { \@@_parse_model_wave_auxi:nn {#1} { 0.3 + 0.7 * (#1 - 780) / -80 } } + { \@@_parse_model_wave_auxi:nn {#1} { 1 } } + } + } + } +\cs_new:Npn \@@_parse_model_wave_auxi:nn #1#2 + { + \fp_compare:nNnTF {#1} < { 440 } + { + \@@_parse_model_wave_auxii:nn + { 4 + \@@_parse_model_wave_rho:n { (#1 - 440) / -60 } } + {#2} + } + { + \fp_compare:nNnTF {#1} < { 490 } + { + \@@_parse_model_wave_auxii:nn + { 4 - \@@_parse_model_wave_rho:n { (#1 - 440) / 50 } } + {#2} + } + { + \fp_compare:nNnTF {#1} < { 510 } + { + \@@_parse_model_wave_auxii:nn + { 2 + \@@_parse_model_wave_rho:n { (#1 - 510) / -20 } } + {#2} + } + { + \fp_compare:nNnTF {#1} < { 580 } + { + \@@_parse_model_wave_auxii:nn + { 2 - \@@_parse_model_wave_rho:n { (#1 - 510) / 70 } } + {#2} + } + { + \fp_compare:nNnTF {#1} < { 645 } + { + \@@_parse_model_wave_auxii:nn + { \@@_parse_model_wave_rho:n { (#1 - 645) / -65 } } + {#2} + } + { \@@_parse_model_wave_auxii:nn { 0 } {#2} } + } + } + } + } + } +\cs_new:Npn \@@_parse_model_wave_auxii:nn #1#2 + { + \exp_args:Neee \@@_parse_model_hsb_aux:nnn + { \fp_eval:n {#1} } + { 1 } + { \@@_parse_model_wave_rho:n {#2} } + } +\cs_new:Npn \@@_parse_model_wave_rho:n #1 + { \fp_eval:n { min(1, max(0,#1) ) } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Selecting colors (and color models)} +% +% \begin{variable}{\l_color_fixed_model_tl} +% For selecting a single fixed model. +% \begin{macrocode} +\tl_new:N \l_color_fixed_model_tl +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_check_model:N} +% \begin{macro}{\@@_check_model:nn} +% Check that the model in use is the one required. +% \begin{macrocode} +\cs_new_protected:Npn \@@_check_model:N #1 + { + \tl_if_empty:NF \l_color_fixed_model_tl + { + \exp_after:wN \@@_check_model:nn #1 + \tl_if_eq:NNF \l_@@_model_tl \l_color_fixed_model_tl + { + \@@_convert:VVN \l_@@_model_tl \l_color_fixed_model_tl + \l_@@_value_tl + } + \tl_set:Nx #1 + { { \l_color_fixed_model_tl } { \l_@@_value_tl } } + } + } +\cs_new_protected:Npn \@@_check_model:nn #1#2 + { + \tl_set:Nn \l_@@_model_tl {#1} + \tl_set:Nn \l_@@_value_tl {#2} + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_select:} +% A backend-neutral location for \enquote{last minute} manipulations before +% handing off to the backend code. We set the special |.| syntax here: this +% will therefore always be available. The finalisation is separate from the +% main function so it can also be applied to \emph{e.g.}~page color. +% \begin{macrocode} +\cs_new_protected:Npx \@@_select: + { + \tl_set:Nx \exp_not:c { l_@@_named_ . _tl } + { \exp_not:N \@@_model:N \exp_not:N \l_@@_current_tl } + \prop_clear:N \exp_not:c { l_@@_named_ . _prop } + \prop_put:NVx \exp_not:c { l_@@_named_ . _prop } + \exp_not:c { l_@@_named_ . _tl } + { \exp_not:N \@@_values:N \exp_not:N \l_@@_current_tl } + \@@_select:N \exp_not:N \l_@@_current_tl + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\color_select:n} +% \begin{macro}{\color_select:nn} +% \begin{macro}{\@@_select_main:Nw, \@@_select_loop:Nw} +% \begin{macro}{\@@_select:nnN} +% \begin{macro}{\@@_select_swap:Nnn} +% Parse the input expressions then get the backend to actually activate +% them. The main complexity here is the need to check through multiple models. +% That is done \enquote{locally} here as the approach is subtly different to +% when different models are being stored. +% \begin{macrocode} +\cs_new_protected:Npn \color_select:n #1 + { + \@@_parse:nN {#1} \l_@@_current_tl + \@@_select: + } +\cs_new_protected:Npn \color_select:nn #1#2 + { + \@@_select_main:Nw \l_@@_current_tl + #1 / / \s_@@_mark #2 / / \s_@@_stop + \@@_select: + } +% \end{macrocode} +% If the first color model is the fixed one, or if there is no fixed +% model, we don't need most of the data: just set up and apply the backend +% function. +% \begin{macrocode} +\cs_new_protected:Npn \@@_select_main:Nw + #1 #2 / #3 / #4 \s_@@_mark #5 / #6 / #7 \s_@@_stop + { + \@@_select:nnN {#2} {#5} #1 + \bool_lazy_or:nnF + { \tl_if_empty_p:N \l_color_fixed_model_tl } + { \str_if_eq_p:nV {#2} \l_color_fixed_model_tl } + { \@@_select_loop:Nw #1 #3 / #4 \s_@@_mark #6 / #7 \s_@@_stop } + } +% \end{macrocode} +% If a fixed model applies, we need to check each possible value in order. +% If there is no hit at all, fall back on the generic formula-based +% interchange. +% \begin{macrocode} +\cs_new_protected:Npn \@@_select_loop:Nw + #1 #2 / #3 \s_@@_mark #4 / #5 \s_@@_stop + { + \str_if_eq:nVTF {#2} \l_color_fixed_model_tl + { \@@_select:nnN {#2} {#4} #1 } + { + \tl_if_blank:nTF {#2} + { \exp_after:wN \@@_select_swap:Nnn \exp_after:wN #1 #1 } + { \@@_select_loop:Nw #1 #3 \s_@@_mark #5 \s_@@_stop } + } + } +\cs_new_protected:Npn \@@_select:nnN #1#2#3 + { + \cs_if_exist:cTF { @@_parse_model_ #1 :w } + { + \tl_set:Nx #3 + { \use:c { @@_parse_model_ #1 :w } #2 , 0 , 0 , 0 , 0 \s_@@_stop } + } + { \__kernel_msg_error:nnn { color } { unknown-model } {#1} } + } +\cs_new_protected:Npn \@@_select_swap:Nnn #1#2#3 + { + \@@_convert:nVnN {#2} \l_color_fixed_model_tl {#3} \l_@@_value_tl + \tl_set:Nx #1 + { { \l_color_fixed_model_tl } { \l_@@_value_tl } } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Fill and stroke color} +% +% \begin{macro}{\color_fill:n, \color_stroke:n} +% \begin{macro}{\color_fill:nn, \color_stroke:nn} +% \begin{macro}{\@@_draw:nnn} +% \begin{macrocode} +\cs_new_protected:Npn \color_fill:n #1 + { + \@@_parse:nN {#1} \l_@@_current_tl + \exp_after:wN \@@_draw:nnn \l_@@_current_tl { fill } + } +\cs_new_protected:Npn \color_stroke:n #1 + { + \@@_parse:nN {#1} \l_@@_current_tl + \exp_after:wN \@@_draw:nnn \l_@@_current_tl { stroke } + } +\cs_new_protected:Npn \color_fill:nn #1#2 + { + \@@_select_main:Nw \l_@@_current_tl + #1 / / \s_@@_mark #2 / / \s_@@_stop + \exp_after:wN \@@_draw:nnn \l_@@_current_tl { fill } + } +\cs_new_protected:Npn \color_stroke:nn #1#2 + { + \@@_select_main:Nw \l_@@_current_tl + #1 / / \s_@@_mark #2 / / \s_@@_stop + \exp_after:wN \@@_draw:nnn \l_@@_current_tl { stroke } + } +\cs_new_protected:Npn \@@_draw:nnn #1#2#3 + { \use:c { @@_backend_ #3 _ #1 :n } {#2} } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Defining named colors} +% +% \begin{variable}{\l_@@_named_tl} +% Space to store the detail of the named color. +% \begin{macrocode} +\tl_new:N \l_@@_named_tl +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\color_set:nn} +% \begin{macro}{\@@_set:nnn} +% \begin{macro}{\@@_set:nn} +% \begin{macro}{\@@_set:nnw} +% \begin{macro}{\color_set:nnn} +% \begin{macro}{\@@_set_colon:nnw} +% \begin{macro}{\@@_set_loop:nw} +% \begin{macro}{\color_set_eq:nn} +% Defining named colors means working through the model list and saving +% both the \enquote{main} color and any equivalents in other models. Even +% if there is only one model, we store a |prop| as well as a |tl|, as there +% could be grouping weirdness, etc. When setting using an expression, +% we need to avoid any fixed model issues, which is done without a group as +% in \pkg{l3keys}. +% \begin{macrocode} +\cs_new_protected:Npn \color_set:nn #1#2 + { + \exp_args:NV \@@_set:nnn + \l_color_fixed_model_tl {#1} {#2} + } +\cs_new_protected:Npn \@@_set:nnn #1#2#3 + { + \tl_clear:N \l_color_fixed_model_tl + \@@_set:nn {#2} {#3} + \tl_set:Nn \l_color_fixed_model_tl {#1} + } +\cs_new_protected:Npn \@@_set:nn #1#2 + { + \str_if_eq:nnF {#1} { . } + { + \@@_parse:nN {#2} \l_@@_named_tl + \tl_clear_new:c { l_@@_named_ #1 _tl } + \tl_set:cx { l_@@_named_ #1 _tl } + { \@@_model:N \l_@@_named_tl } + \prop_clear_new:c { l_@@_named_ #1 _prop } + \prop_put:cvx { l_@@_named_ #1 _prop } { l_@@_named_ #1 _tl } + { \@@_values:N \l_@@_named_tl } + \@@_set:nnw {#1} {#2} #2 ! \s_@@_stop + } + } +% \end{macrocode} +% When setting an expression-based color, there could be multiple model +% data available for one or more of the input colors. Where that is true for +% the \emph{first} named color in an expression, we re-parse the expression +% when they are also parameter-based: only |cmyk|, |gray| and |rgb| make +% any sense here. There is a bit of a performance hit but this should be +% rare and taking place during set-up. +% \begin{macrocode} +\cs_new_protected:Npn \@@_set:nnw #1#2#3 ! #4 \s_@@_stop + { + \clist_map_inline:nn { cmyk , gray , rgb } + { + \prop_get:cnNT { l_@@_named_ #3 _prop } {##1} \l_@@_internal_tl + { + \prop_if_in:cnF { l_@@_named_ #1 _prop } {##1} + { + \group_begin: + \tl_set:cn { l_@@_named_ #3 _tl } {##1} + \@@_parse:nN {#2} \l_@@_internal_tl + \exp_args:NNNV \group_end: + \tl_set:Nn \l_@@_internal_tl \l_@@_internal_tl + \prop_put:cxx { l_@@_named_ #1 _prop } + { \@@_model:N \l_@@_internal_tl } + { \@@_values:N \l_@@_internal_tl } + } + } + } + } +\cs_new_protected:Npx \color_set:nnn #1#2#3 + { + \exp_not:N \str_if_eq:nnF {#1} { . } + { + \tl_clear_new:c { l_@@_named_ #1 _tl } + \prop_clear_new:c { l_@@_named_ #1 _prop } + \exp_not:N \@@_set_colon:nnw {#1} {#3} + #2 \c_colon_str \c_colon_str \exp_not:N \s_@@_stop + } + } +\use:x + { + \cs_new_protected:Npn \exp_not:N \@@_set_colon:nnw + ##1##2 ##3 \c_colon_str ##4 \c_colon_str + ##5 \exp_not:N \s_@@_stop + } + { + \tl_if_blank:nTF {#4} + { \@@_set_loop:nw {#1} #3 } + { \@@_set_loop:nw {#1} #4 } + / / \s_@@_mark #2 / / \s_@@_stop + } +\cs_new_protected:Npn \@@_set_loop:nw + #1#2 / #3 \s_@@_mark #4 / #5 \s_@@_stop + { + \tl_if_blank:nF {#2} + { + \@@_select:nnN {#2} {#4} \l_@@_named_tl + \tl_set:Nx \l_@@_internal_tl { \@@_model:N \l_@@_named_tl } + \tl_if_empty:cT { l_@@_named_ #1 _tl } + { \tl_set_eq:cN { l_@@_named_ #1 _tl } \l_@@_internal_tl } + \prop_put:cVx { l_@@_named_ #1 _prop } \l_@@_internal_tl + { \@@_values:N \l_@@_named_tl } + \@@_set_loop:nw {#1} #3 \s_@@_mark #5 \s_@@_stop + } + } +\cs_new_protected:Npn \color_set_eq:nn #1#2 + { + \@@_if_defined:nTF {#2} + { + \tl_clear_new:c { l_@@_named_ #1 _tl } + \prop_clear_new:c { l_@@_named_ #1 _prop } + \str_if_eq:nnTF {#2} { . } + { + \tl_set:cx { l_@@_named_ #1 _tl } + { \@@_model:N \l_@@_current_tl } + \prop_put:cvx { l_@@_named_ #1 _prop } { l_@@_named_ #1 _tl } + { \@@_values:N \l_@@_current_tl } + } + { + \tl_set_eq:cc { l_@@_named_ #1 _tl } { l_@@_named_ #2 _tl } + \prop_set_eq:cc { l_@@_named_ #1 _prop } { l_@@_named_ #2 _prop } + } + } + { + \__kernel_msg_error:nnn { color } { unknown-color } {#2} + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% A small set of colors are always defined. +% \begin{macrocode} +\color_set:nnn { black } { gray } { 0 } +\color_set:nnn { white } { gray } { 1 } +\color_set:nnn { cyan } { cmyk } { 1 , 0 , 0 , 0 } +\color_set:nnn { magenta } { cmyk } { 0 , 1 , 0 , 0 } +\color_set:nnn { yellow } { cmyk } { 0 , 0 , 1 , 0 } +\color_set:nnn { red } { rgb } { 1 , 0 , 0 } +\color_set:nnn { green } { rgb } { 0 , 1 , 0 } +\color_set:nnn { blue } { rgb } { 0 , 0 , 1 } +% \end{macrocode} +% +% \begin{variable}{\l_@@_named_._prop, \l_@@_named_._tl} +% A special named color: this is always defined though not fixed in +% definition. +% \begin{macrocode} +\prop_new:c { l_@@_named_._prop } +\tl_new:c { l_@@_named_._tl } +\tl_set:cx { l_@@_named_._tl } { \@@_model:N \l_@@_current_tl } +% \end{macrocode} +% \end{variable} +% +% \subsection{Exporting colors} +% +% \begin{macro}{\color_export:nnN} +% \begin{macro}{\color_export:nnnN} +% \begin{macro}{\@@_export:nN} +% \begin{macro}{\@@_export:nnnN} +% \begin{macrocode} +\cs_new_protected:Npn \color_export:nnN #1#2#3 + { + \group_begin: + \tl_if_exist:cT { c_@@_export_ #2 _tl } + { \tl_set_eq:Nc \l_color_fixed_model_tl { c_@@_export_ #2 _tl } } + \@@_parse:nN {#1} #3 + \@@_export:nN {#2} #3 + \exp_args:NNNV \group_end: + \tl_set:Nn #3 #3 + } +\cs_new_protected:Npn \color_export:nnnN #1#2#3#4 + { + \@@_select_main:Nw #4 + #1 / / \s_@@_mark #2 / / \s_@@_stop + \@@_export:nN {#3} #4 + } +\cs_new_protected:Npn \@@_export:nN #1#2 + { \exp_after:wN \@@_export:nnnN #2 {#1} #2 } +\cs_new:Npn \@@_export:nnnN #1#2#3#4 + { + \cs_if_exist_use:cF { @@_export_format_ #3 :nnN } + { + \__kernel_msg_error:nnn { color } { unknown-export-format } {#3} + \use_none:nnn + } + {#1} {#2} #4 + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_export_format_backend:nnN} +% Simple. +% \begin{macrocode} +\cs_new_protected:Npn \@@_export_format_backend:nnN #1#2#3 + { \tl_set:Nn #3 { {#1} {#2} } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_export:nnnNN} +% A generic auxiliary for cases where only one model is appropriate. +% \begin{macrocode} +\cs_new_protected:Npn \@@_export:nnnNN #1#2#3#4#5 + { + \str_if_eq:nnTF {#2} {#1} + { #5 #4 #3 \s_@@_stop } + { + \@@_convert:nnnN {#2} {#1} {#3} #4 + \exp_after:wN #5 \exp_after:wN #4 + #4 \s_@@_stop + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{variable} +% { +% \c_@@_export_HTML_tl , +% \c_@@_export_space-sep-cmyk_tl , +% \c_@@_export_space-sep-rgb_tl +% } +% \begin{macrocode} +\tl_const:Nn \c_@@_export_HTML_tl { rgb } +\tl_const:cn { c_@@_export_space-sep-cmyk_tl } { cmyk } +\tl_const:cn { c_@@_export_space-sep-rgb_tl } { rgb } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_export_format_space-sep-cmyk:nnN} +% \begin{macro}{\@@_export_space-sep-cmyk:Nw} +% \begin{macrocode} +\cs_new_protected:cpx { @@_export_format_space-sep-cmyk:nnN } #1#2#3 + { + \exp_not:N \@@_export:nnnNN { cmyk } {#1} {#2} #3 + \exp_not:c { @@_export_space-sep-cmyk:Nw } + } +\cs_new_protected:cpn { @@_export_space-sep-cmyk:Nw } #1#2 \s_@@_stop + { \tl_set:Nx #1 {#2} } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro} +% { +% \@@_export_format_HTML:nnN , +% \@@_export_format_space-sep-rgb:nnN +% } +% \begin{macro} +% { +% \@@_export_HTML:Nw , +% \@@_export_space-sep-rgb:Nw +% } +% \begin{macro}[EXP]{\@@_export_HTML:n} +% \textsc{html} values must be given in |rgb|: we force conversion if +% required, then do some simple maths. +% \begin{macrocode} +\cs_new_protected:Npn \@@_export_format_HTML:nnN #1#2#3 + { \@@_export:nnnNN { rgb } {#1} {#2}#3 \@@_export_HTML:Nw } +\cs_new_protected:cpx { @@_export_format_space-sep-rgb:nnN } #1#2#3 + { + \exp_not:N \@@_export:nnnNN { rgb } {#1} {#2} #3 + \exp_not:c { @@_export_space-sep-rgb:Nw } + } +\cs_new_protected:Npn \@@_export_HTML:Nw #1#2 ~ #3 ~ #4 \s_@@_stop + { + \tl_set:Nx #1 + { + \@@_export_HTML:n {#2} + \@@_export_HTML:n {#3} + \@@_export_HTML:n {#4} + } + } +\cs_new:Npn \@@_export_HTML:n #1 + { + \fp_compare:nNnTF {#1} = { 0 } + { 00 } + { \int_to_Hex:n { \fp_to_int:n { #1 * 255 } } } + } +\cs_new_protected:cpn { @@_export_space-sep-rgb:Nw } #1#2 \s_@@_stop + { \tl_set:Nx #1 {#2} } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Additional color models} +% +% \begin{variable}{\l_@@_internal_prop} +% \begin{macrocode} +\prop_new:N \l_@@_internal_prop +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\g_@@_model_int} +% A tracker for the total number of new models. +% \begin{macrocode} +\int_new:N \g_@@_model_int +% \end{macrocode} +% \end{variable} +% +% \begin{variable} +% {\c_@@_fallback_cmyk_tl, \c_@@_fallback_gray_tl, \c_@@_fallback_rgb_tl} +% Conversion from Separation or DeviceN spaces may not be possible; have +% a fallback to black. +% \begin{macrocode} +\tl_const:Nn \c_@@_fallback_cmyk_tl { 0 ~ 0 ~ 0 ~ 1 } +\tl_const:Nn \c_@@_fallback_gray_tl { 1 } +\tl_const:Nn \c_@@_fallback_rgb_tl { 1 ~ 1 ~ 1 } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\g_@@_colorants_prop} +% Mapping from names to colorants. +% \begin{macrocode} +\prop_new:N \g_@@_colorants_prop +\prop_gput:Nnn \g_@@_colorants_prop { black } { Black } +\prop_gput:Nnn \g_@@_colorants_prop { blue } { Blue } +\prop_gput:Nnn \g_@@_colorants_prop { cyan } { Cyan } +\prop_gput:Nnn \g_@@_colorants_prop { green } { Green } +\prop_gput:Nnn \g_@@_colorants_prop { magenta } { Magenta } +\prop_gput:Nnn \g_@@_colorants_prop { none } { None } +\prop_gput:Nnn \g_@@_colorants_prop { red } { Red } +\prop_gput:Nnn \g_@@_colorants_prop { yellow } { Yellow } +% \end{macrocode} +% \end{variable} +% +% \begin{variable} +% { +% \c_@@_model_whitepoint_CIELAB_a_tl , +% \c_@@_model_whitepoint_CIELAB_b_tl , +% \c_@@_model_whitepoint_CIELAB_e_tl , +% \c_@@_model_whitepoint_CIELAB_d50_tl , +% \c_@@_model_whitepoint_CIELAB_d55_tl , +% \c_@@_model_whitepoint_CIELAB_d65_tl , +% \c_@@_model_whitepoint_CIELAB_d75_tl +% } +% Whitepoint data for the CIELAB profiles. +% \begin{macrocode} +\tl_const:Nn \c_@@_model_whitepoint_CIELAB_a_tl { 1.0985 ~ 1 ~ 0.3558 } +\tl_const:Nn \c_@@_model_whitepoint_CIELAB_b_tl { 0.9807 ~ 1 ~ 1.1822 } +\tl_const:Nn \c_@@_model_whitepoint_CIELAB_e_tl { 1 ~ 1 ~ 1 } +\tl_const:cn { c_@@_model_whitepoint_CIELAB_d50_tl } { 0.9642 ~ 1 ~ 0.8251 } +\tl_const:cn { c_@@_model_whitepoint_CIELAB_d55_tl } { 0.9568 ~ 1 ~ 0.9214 } +\tl_const:cn { c_@@_model_whitepoint_CIELAB_d65_tl } { 0.9504 ~ 1 ~ 1.0888 } +\tl_const:cn { c_@@_model_whitepoint_CIELAB_d75_tl } { 0.9497 ~ 1 ~ 1.2261 } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\c_@@_model_range_CIELAB_tl} +% The range for CIELAB color spaces. +% \begin{macrocode} +\tl_const:Nn \c_@@_model_range_CIELAB_tl { 0 ~ 100 ~ -128 ~ 127 ~ -128 ~ 127 } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\g_@@_alternative_model_prop} +% For tracking the alternative model set up for separations, etc. +% \begin{macrocode} +\prop_new:N \g_@@_alternative_model_prop +\clist_map_inline:nn { cyan , magenta , yellow , black } + { \prop_gput:Nnn \g_@@_alternative_model_prop {#1} { cmyk } } +\clist_map_inline:nn { red , green , blue } + { \prop_gput:Nnn \g_@@_alternative_model_prop {#1} { rgb } } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\g_@@_alternative_values_prop} +% Same for the values: a bit more involved. +% \begin{macrocode} +\prop_new:N \g_@@_alternative_values_prop +\prop_gput:Nnn \g_@@_alternative_values_prop { cyan } { 1 , 0 , 0 , 0 } +\prop_gput:Nnn \g_@@_alternative_values_prop { magenta } { 0 , 1 , 0 , 0 } +\prop_gput:Nnn \g_@@_alternative_values_prop { yellow } { 0 , 0 , 1 , 0 } +\prop_gput:Nnn \g_@@_alternative_values_prop { black } { 0 , 0 , 0 , 1 } +\prop_gput:Nnn \g_@@_alternative_values_prop { red } { 1 , 0 , 0 } +\prop_gput:Nnn \g_@@_alternative_values_prop { green } { 0 , 1 , 0 } +\prop_gput:Nnn \g_@@_alternative_values_prop { blue } { 0 , 0 , 1 } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\color_model_new:nnn, \@@_model_new:nnn} +% Set up a new model: in general this has to be handled by a family-dependent +% function. To avoid some \enquote{interesting} questions with casing, we +% fold the case of the family name. The key--value list should always be +% present, so we convert it up-front to a |prop|, then deal with the detail +% on a per-family basis. +% \begin{macrocode} +\cs_new_protected:Npn \color_model_new:nnn #1#2#3 + { + \exp_args:Nee \@@_model_new:nnn + { \tl_to_str:n {#1} } + { \str_foldcase:n {#2} } {#3} + } +\cs_new_protected:Npn \@@_model_new:nnn #1#2#3 + { + \cs_if_exist:cTF { @@_parse_model_ #1 :w } + { + \__kernel_msg_error:nnn { color } { model-already-defined } {#1} + } + { + \cs_if_exist:cTF { @@_model_ #2 :n } + { + \prop_set_from_keyval:Nn \l_@@_internal_prop {#3} + \use:c { @@_model_ #2 :n } {#1} + } + { + \__kernel_msg_error:nnn { color } { unknown-model-type } {#2} + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_model_separation:n} +% \begin{macro}{\@@_model_separation:nn} +% \begin{macro}{\@@_model_separation:nnn} +% \begin{macro}{\@@_model_separation:w} +% \begin{macro} +% { +% \@@_model_separation_cmyk:nnnnnn , +% \@@_model_separation_gray:nnnnnn , +% \@@_model_separation_rgb:nnnnnn +% } +% \begin{macro}{\@@_model_convert:nnn} +% \begin{macro}{\@@_model_separation_CIELAB:nnnnnn} +% \begin{macro}{\@@_model_separation_CIELAB:nnnnnnn} +% Separations must have a \enquote{real} name, which is pretty easy to find. +% \begin{macrocode} +\cs_new_protected:Npn \@@_model_separation:n #1 + { + \prop_get:NnNTF \l_@@_internal_prop { name } + \l_@@_internal_tl + { + \exp_args:NV \@@_model_separation:nn + \l_@@_internal_tl {#1} + } + { + \__kernel_msg_error:nnn { color } + { separation-requires-name } {#1} + } + } +% \end{macrocode} +% We have two keys to find at this stage: the alternative space model +% and linked values. +% \begin{macrocode} +\cs_new_protected:Npn \@@_model_separation:nn #1#2 + { + \prop_get:NnNTF \l_@@_internal_prop { alternative-model } + \l_@@_internal_tl + { + \exp_args:NV \@@_model_separation:nnn + \l_@@_internal_tl {#2} {#1} + } + { + \__kernel_msg_error:nnn { color } + { separation-alternative-model } {#2} + } + } +\cs_new_protected:Npn \@@_model_separation:nnn #1#2#3 + { + \cs_if_exist:cTF { @@_model_separation_ #1 :nnnnnn } + { + \prop_get:NnNTF \l_@@_internal_prop { alternative-values } + \l_@@_internal_tl + { + \exp_after:wN \@@_model_separation:w \l_@@_internal_tl + , 0 , 0 , 0 , 0 \s_@@_stop {#2} {#3} {#1} + } + { + \__kernel_msg_error:nnn { color } + { separation-alternative-values } {#2} + } + } + { + \__kernel_msg_error:nnn { color } + { unknown-alternative-model } {#1} + } + } +% \end{macrocode} +% As each alternative space leads to a different requirement for conversion, +% and as there are only a small number of choices, we manually split the data +% and then set up. Notice that mixing tints is really just the same +% as mixing \texttt{gray}. The \texttt{white} color is special, as it allows +% tints to be adjusted without an additional color space. To make sure the +% data is set for that at all group levels, we need to work on a per-level +% basis. Within the output, only the set-up needs the \enquote{real} name +% of the colorspace: we use a simple tracking number for general usage +% as this is a clear namespace without issues of escaping chars. +% \begin{macrocode} +\cs_new_protected:Npn \@@_model_separation:w + #1 , #2 , #3 , #4 , #5 \s_@@_stop #6#7#8 + { + \int_gincr:N \g_@@_model_int + \tl_const:cn { c_@@_fallback_ #6 _tl } { 1 } + \cs_new_eq:cN { @@_parse_mix_ #6 :nw } \@@_parse_mix_gray:nw + \cs_new:cpn { @@_parse_model_ #6 :w } ##1 , ##2 \s_@@_stop + { {#6} { \@@_parse_number:n {##1} } } + \clist_map_inline:nn { fill , stroke , select } + { + \cs_new_protected:cpx { @@_backend_ ##1 _ #6 :n } ####1 + { + \exp_not:c { @@_backend_ ##1 _ separation:nn } + { color \int_use:N \g_@@_model_int } {####1} + } + } + \use:c { @@_model_separation_ #8 :nnnnnn } + {#6} {#7} {#1} {#2} {#3} {#4} + \prop_gput:Nnn \g_@@_alternative_model_prop {#6} {#8} + \prop_gput:Nnx \g_@@_colorants_prop {#6} + { \str_convert_pdfname:n {#7} } + \cs_new_protected:cpx { @@_model_ #6 _white: } + { + \prop_put:Nnn \exp_not:N \l_@@_named_white_prop {#6} { 0 } + \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0 + { \group_insert_after:N \exp_not:c { @@_model_ #6 _ white: } } + } + \use:c { @@_model_ #6 _white: } + } +\cs_new_protected:Npn \@@_model_separation_cmyk:nnnnnn #1#2#3#4#5#6 + { + \cs_new:cpn { @@_convert_ #1 _cmyk:w } ##1 ~ ##2 \s_@@_stop + { + \fp_eval:n {##1 * #3} ~ + \fp_eval:n {##1 * #4} ~ + \fp_eval:n {##1 * #5} ~ + \fp_eval:n {##1 * #6} + } + \@@_model_convert:nnn {#1} { cmyk } { rgb } + \@@_model_convert:nnn {#1} { cmyk } { gray } + \prop_gput:Nnn \g_@@_alternative_values_prop {#1} { #3 , #4 , #5 , #6 } + \@@_backend_separation_init:nnnnn {#2} { /DeviceCMYK } { } + { 0 ~ 0 ~ 0 ~ 0 } { #3 ~ #4 ~ #5 ~ #6 } + } +\cs_new_protected:Npn \@@_model_separation_rgb:nnnnnn #1#2#3#4#5#6 + { + \cs_new:cpn { @@_convert_ #1 _rgb:w } ##1 ~ ##2 \s_@@_stop + { + \fp_eval:n {##1 * #3} ~ + \fp_eval:n {##1 * #4} ~ + \fp_eval:n {##1 * #5} + } + \@@_model_convert:nnn {#1} { rgb } { cmyk } + \@@_model_convert:nnn {#1} { rgb } { gray } + \prop_gput:Nnn \g_@@_alternative_values_prop {#1} { #3 , #4 , #5 } + \@@_backend_separation_init:nnnnn {#2} { /DeviceRGB } { } + { 0 ~ 0 ~ 0 } { #3 ~ #4 ~ #5 } + } +\cs_new_protected:Npn \@@_model_separation_gray:nnnnnn #1#2#3#4#5#6 + { + \cs_new:cpn { @@_convert_ #1 _cmyk:w } ##1 ~ ##2 \s_@@_stop + { + \fp_eval:n {##1 * #3} ~ + \fp_eval:n {##1 * #3} ~ + \fp_eval:n {##1 * #3} ~ + \fp_eval:n {##1 * #3} + } + \cs_new:cpn { @@_convert_ #1 _gray:w } ##1 ~ ##2 \s_@@_stop + { \fp_eval:n {##1 * #3} } + \cs_new:cpn { @@_convert_ #1 _rgb:w } ##1 ~ ##2 \s_@@_stop + { + \fp_eval:n {##1 * #3} ~ + \fp_eval:n {##1 * #3} ~ + \fp_eval:n {##1 * #3} + } + \prop_gput:Nnn \g_@@_alternative_values_prop {#1} {#3} + \@@_backend_separation_init:nnnnn {#2} { /DeviceGray } { } { 0 } {#3} + } +% \end{macrocode} +% Generic model conversion \emph{via} an alternative intermediate. +% \begin{macrocode} +\cs_new_protected:Npn \@@_model_convert:nnn #1#2#3 + { + \cs_new:cpx { @@_convert_ #1 _ #3 :w } ##1 ~ ##2 \s_@@_stop + { + \exp_not:N \exp_args:NNe \exp_not:N \use:nn + \exp_not:c { @@_convert_ #2 _ #3 :w } + { \exp_not:c { @@_convert_ #1 _ #2 :w } ##1 ~ ##2 \s_@@_stop } + \c_space_tl \exp_not:N \s_@@_stop + } + } +% \end{macrocode} +% Setting up for CIELAB needs a bit more work: there is the illuminant and +% the need for an appropriate object. +% \begin{macrocode} +\cs_new_protected:Npn \@@_model_separation_CIELAB:nnnnnn #1#2#3#4#5#6 + { + \prop_get:NnNF \l_@@_internal_prop { illuminant } + \l_@@_internal_tl + { + \__kernel_msg_error:nnn { color } + { CIELAB-requires-illuminant } {#1} + \tl_set:Nn \l_@@_internal_tl { d50 } + } + \exp_args:NV \@@_model_separation_CIELAB:nnnnnnn + \l_@@_internal_tl {#1} {#2} {#3} {#4} {#5} {#6} + } +% \end{macrocode} +% If a CIELAB space is being set up, we need the illuminant, then create +% the appropriate set up. At present, this doesn't include \texttt{BlackPoint} +% or \texttt{Range} data, but that may be added later. As CIELAB colors +% cannot be converted to anything else, we fallback to producing black: the +% user should set up a second model for colors set up this way. +% \begin{macrocode} +\cs_new_protected:Npn \@@_model_separation_CIELAB:nnnnnnn #1#2#3#4#5#6#7 + { + \tl_if_exist:cTF { c_@@_model_whitepoint_CIELAB_ #1 _tl } + { + \@@_backend_separation_init_CIELAB:nnn {#1} {#3} { #4 ~ #5 ~ #6 } + \cs_new:cpn { @@_convert_ #2 _cmyk:w } ##1 ~ ##2 \s_@@_stop + { 0 ~ 0 ~ 0 ~ 1 } + \cs_new:cpn { @@_convert_ #2 _rgb:w } ##1 ~ ##2 \s_@@_stop + { 1 ~ 1 ~ 1 } + \cs_new:cpn { @@_convert_ #2 _gray:w } ##1 ~ ##2 \s_@@_stop + { 1 } + } + { + \__kernel_msg_error:nnn { color } + { unknown-CIELAB-illuminant } {#1} + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_model_devicen:n} +% \begin{macro}{\@@_model_devicen:nn} +% \begin{macro}{\@@_model_devicen:nnn} +% \begin{macro}{\@@_model_devicen:nnnn} +% \begin{macro} +% { +% \@@_model_devicen_parse_1:nn , +% \@@_model_devicen_parse_2:nn , +% \@@_model_devicen_parse_3:nn , +% \@@_model_devicen_parse_4:nn , +% \@@_model_devicen_parse_generic:nn +% } +% \begin{macro}[EXP]{\@@_model_devicen_parse:nw} +% \begin{macro}[EXP]{\@@_model_devicen_mix:nw} +% \begin{macro}{\@@_model_devicen_init:nnn} +% \begin{macro}{\@@_model_devicen_init:nnnn} +% \begin{macro}{\@@_model_devicen_tranform:w} +% \begin{macro} +% { +% \@@_model_devicen_tranform_1:nnnnn , +% \@@_model_devicen_tranform_3:nnnnn , +% \@@_model_devicen_tranform_4:nnnnn , +% } +% \begin{macro}{\@@_model_devicen_tranform:nnn} +% \begin{macro}[EXP]{\@@_model_devicen_colorant:n} +% \begin{macro}{\@@_model_devicen_convert:nnn} +% \begin{macro} +% { +% \@@_model_devicen_convert_cmyk:n , +% \@@_model_devicen_convert_gray:n , +% \@@_model_devicen_convert_rgb:n +% } +% \begin{macro}{\@@_model_devicen_convert:nnnn} +% \begin{macro}[EXP]{\@@_model_devicen_convert:n, \@@_model_devicen_convert_aux:n} +% \begin{macro}[EXP]{\@@_model_devicen_convert:w} +% \begin{macro}[EXP]{\@@_convert_devicen_cmyk:nnnnw} +% \begin{macro}[EXP]{\@@_convert_devicen_cmyk:nnnnnnnnn} +% \begin{macro}[EXP]{\@@_convert_devicen_cmyk_aux:nnnnw} +% \begin{macro}[EXP]{\@@_convert_devicen_gray:nw} +% \begin{macro}[EXP]{\@@_convert_devicen_gray:nnn} +% \begin{macro}[EXP]{\@@_convert_devicen_gray_aux:nw} +% \begin{macro}[EXP]{\@@_convert_devicen_rgb:nnnw} +% \begin{macro}[EXP]{\@@_convert_devicen_rgb:nnnnnnn} +% \begin{macro}[EXP]{\@@_convert_devicen_rgb_aux:nnnw} +% We require a list of component names here: one might call them colorants, +% but it's convenient to use \TeX{} names instead so we slightly adjust the +% terminology. +% \begin{macrocode} +\cs_new_protected:Npn \@@_model_devicen:n #1 + { + \prop_get:NnNTF \l_@@_internal_prop { names } + \l_@@_internal_tl + { + \exp_args:NV \@@_model_devicen:nn + \l_@@_internal_tl {#1} + } + { + \__kernel_msg_error:nnn { color } + { DeviceN-requires-names } {#1} + } + } +% \end{macrocode} +% All valid models will have an alternative listed, either hard-coded for +% the core device ones, or dynamically added for Separations, etc. +% \begin{macrocode} +\cs_new_protected:Npn \@@_model_devicen:nn #1#2 + { + \tl_clear:N \l_@@_model_tl + \clist_map_inline:nn {#1} + { + \prop_get:NnNTF \g_@@_alternative_model_prop {##1} + \l_@@_internal_tl + { + \tl_if_empty:NTF \l_@@_model_tl + { \tl_set_eq:NN \l_@@_model_tl \l_@@_internal_tl } + { + \str_if_eq:VVF \l_@@_model_tl \l_@@_internal_tl + { + \__kernel_msg_error:nnn { color } + { DeviceN-inconsistent-alternative } + {#2} + \clist_map_break:n { \use_none:nnnn } + } + } + } + { + \str_if_eq:nnF {##1} { none } + { + \__kernel_msg_error:nnn { color } + { DeviceN-no-alternative } + {#2} + } + } + } + \tl_if_empty:NTF \l_@@_model_tl + { + \__kernel_msg_error:nnn { color } + { DeviceN-no-alternative } {#2} + } + { \exp_args:NV \@@_model_devicen:nnn \l_@@_model_tl {#1} {#2} } + } +% \end{macrocode} +% We now complete the data we require by first finding out how many +% colorants there are, then moving on to begin constructing the function +% required to map to the alternative color space. +% \begin{macrocode} +\cs_new_protected:Npn \@@_model_devicen:nnn #1#2#3 + { + \exp_args:Nx \@@_model_devicen:nnnn + { \clist_count:n {#2} } {#1} {#2} {#3} + } +% \end{macrocode} +% At this stage, we have checked everything is in place, so we can set up +% the \TeX{} and backend data structures. As for separations, it's not really +% possible in general to have a fallback, so we simply provide +% \enquote{black} for each element. +% \begin{macrocode} +\cs_new_protected:Npn \@@_model_devicen:nnnn #1#2#3#4 + { + \int_gincr:N \g_@@_model_int + \tl_const:cx { c_@@_fallback_ #4 _tl } + { \prg_replicate:nn {#1} { 1 ~ } } + \cs_if_exist_use:cF { @@_model_devicen_parse_ #1 :nn } + { \@@_model_devicen_parse_generic:nn } + {#4} {#1} + \clist_map_inline:nn { fill , stroke , select } + { + \cs_new_protected:cpx { @@_backend_ ##1 _ #4 :n } ####1 + { + \exp_not:c { @@_backend_ ##1 _ devicen:nn } + { color \int_use:N \g_@@_model_int } {####1} + } + } + \cs_new_protected:cpx { @@_model_ #4 _white: } + { + \prop_put:Nnn \exp_not:N \l_@@_named_white_prop {#4} + { \prg_replicate:nn {#1} { 0 ~ } } + \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0 + { \group_insert_after:N \exp_not:c { @@_model_ #4 _ white: } } + } + \use:c { @@_model_ #4 _white: } + \@@_model_devicen_init:nnn {#1} {#2} {#3} + \@@_model_devicen_convert:nnn {#4} {#2} {#3} + } +% \end{macrocode} +% For short lists of DeviceN colors, wee can use hand-tuned parsing. This +% lines up with other models, where we allow for up to four components. For +% larger spaces,. rather than limit artificially, we use a somewhat slow +% approach based on open-ended commas-lists. +% \begin{macrocode} +\cs_new_protected:cpn { @@_model_devicen_parse_1:nn } #1#2 + { + \cs_new:cpn { @@_parse_model_ #1 :w } ##1 , ##2 \s_@@_stop + { {#1} { \@@_parse_number:n {##1} } } + \cs_new_eq:cN { @@_parse_mix_ #1 :nw } \@@_parse_mix_gray:nw + } +\cs_new_protected:cpn { @@_model_devicen_parse_2:nn } #1#2 + { + \cs_new:cpn { @@_parse_model_ #1 :w } ##1 , ##2 , ##3 \s_@@_stop + { {#1} { \@@_parse_number:n {##1} ~ \@@_parse_number:n {##2} } } + \cs_new:cpn { @@_parse_mix_ #1 :nw } + ##1##2 ~ ##3 \s_@@_mark ##4 ~ ##5 \s_@@_stop + { + \fp_eval:n { ##2 * ##1 + ##4 * ( 1 - ##1 ) } \c_space_tl + \fp_eval:n { ##3 * ##1 + ##5 * ( 1 - ##1 ) } + } + } +\cs_new_protected:cpn { @@_model_devicen_parse_3:nn } #1#2 + { + \cs_new:cpn { @@_parse_model_ #1 :w } ##1 , ##2 , ##3 , ##4 \s_@@_stop + { + {#1} + { + \@@_parse_number:n {##1} ~ + \@@_parse_number:n {##2} ~ + \@@_parse_number:n {##3} + } + } + \cs_new_eq:cN { @@_parse_mix_ #1 :nw } \@@_parse_mix_rgb:nw + } +\cs_new_protected:cpn { @@_model_devicen_parse_4:nn } #1#2 + { + \cs_new:cpn { @@_parse_model_ #1 :w } + ##1 , ##2 , ##3 , ##4 , ##5 \s_@@_stop + { + {#1} + { + \@@_parse_number:n {##1} ~ + \@@_parse_number:n {##2} ~ + \@@_parse_number:n {##3} ~ + \@@_parse_number:n {##4} + } + } + \cs_new_eq:cN { @@_parse_mix_ #1 :nw } \@@_parse_mix_cmyk:nw + } +\cs_new_protected:Npn \@@_model_devicen_parse_generic:nn #1#2 + { + \cs_new:cpn { @@_parse_model_ #1 :w } ##1 , ##2 \s_@@_stop + { + {#1} + { \@@_model_devicen_parse:nw {#2} ##1 , ##2 , \q_nil , \s_@@_stop } + } + \cs_new:cpx { @@_parse_mix_ #1 :nw } + ##1 ##2 \s_@@_mark ##3 \s_@@_stop + { + \exp_not:N \@@_model_devicen_mix:nw {##1} + ##2 \c_space_tl \exp_not:N \q_nil \c_space_tl \exp_not:N \s_@@_mark + ##3 \c_space_tl \exp_not:N \q_nil \c_space_tl \exp_not:N \s_@@_stop + } + } +\cs_new:Npn \@@_model_devicen_parse:nw #1#2 , #3 \s_@@_stop + { + \int_compare:nNnT {#1} > 0 + { + \quark_if_nil:nTF {#2} + { \prg_replicate:nn {#1} { 0 ~ } } + { + \@@_parse_number:n {#2} + \int_compare:nNnT {#1} > 1 { ~ } + \exp_args:Nf \@@_model_devicen_parse:nw + { \int_eval:n { #1 - 1 } } #3 \s_@@_stop + } + } + } +\cs_new:Npn \@@_model_devicen_mix:nw #1#2 ~ #3 \s_@@_mark #4 ~ #5 \s_@@_stop + { + \fp_eval:n { #2 * #1 + #4 * ( 1 - #1 ) } + \quark_if_nil:oF { \tl_head:w #3 \q_stop } + { + \c_space_tl + \@@_model_devicen_mix:nw {#1} #3 \s_@@_mark #5 \s_@@_stop + } + } +% \end{macrocode} +% To construct the tint transformation, we have to use PostScript. The +% aim is to have the final tint for each device colorant as +% \[ +% 1 - \prod_{n} (1 - X_{n} D_{X_{n}}) +% \] +% where $X$ is a DeviceN colorant and $D$ is the amount of device colorant +% that the DeviceN colorant maps to. At the start of the process, the +% PostScript stack will contain the $X_{n}$ values, whilst we have the +% $D$ values on a per-DeviceN colorant basis. The more convenient approach +% for us is therefore to take each DeviceN colorant in turn and find the +% value $1 - X_{n} D_{X_{n}}$, multiplying as we go, and finalise with the +% subtraction. That contrasts to \pkg{colorspace}: it splits the process +% up by process color, which works better when you have a fixed list +% of colorants. (\pkg{colorspace} only supports up to $4$ DeviceN colors, +% and only \texttt{cmyk} as the alternative space.) To set this up, +% we first need to know the number of values in the target color space: +% this is easily handled as there are a very small range of possibles. +% Once we have that information, it's relatively easy to build the required +% PostScript using some generic code. +% \begin{macrocode} +\cs_new_protected:Npn \@@_model_devicen_init:nnn #1#2#3 + { + \exp_args:Ne \@@_model_devicen_init:nnnn + { + \str_case:nn {#2} + { + { cmyk } { 4 } + { gray } { 1 } + { rgb } { 3 } + } + } + {#1} {#2} {#3} + } +% \end{macrocode} +% As we always need to split the alternative values into parts, we use a +% shared auxiliary and only use a minimal difference between code paths. +% Construction of the tint transformation is as far as possible done using +% loops, which means there are some inefficiencies for device colors in +% the \texttt{DeviceN} space: we roll the stack one-at-a-time even if there +% is a potential shortcut. However, that way there is nothing to special-case. +% Once this is sorted, we can write the tint transform object, which will +% remain as the last object until we sort out the final step: the colorant +% list. +% \begin{macrocode} +\cs_new_protected:Npn \@@_model_devicen_init:nnnn #1#2#3#4 + { + \tl_set:Nx \l_@@_internal_tl + { \prg_replicate:nn {#1} { 1.0 ~ } } + \int_zero:N \l_@@_internal_int + \clist_map_inline:nn {#4} + { + \int_incr:N \l_@@_internal_int + \prop_get:NnN \g_@@_alternative_values_prop {##1} + \l_@@_value_tl + \exp_after:wN \@@_model_devicen_transform:w + \l_@@_value_tl , 0 , 0 , 0 \s_@@_stop {#1} {#2} + } + \tl_put_right:Nx \l_@@_internal_tl + { + \prg_replicate:nn {#1} + { neg ~ 1.0 ~ add ~ #1 ~ -1 ~ roll ~ } + \int_eval:n { #2 + 4 } ~ 4 ~ roll + \prg_replicate:nn {#2} { ~ pop } + } + \use:x + { + \@@_backend_devicen_init:nnn + { + \clist_map_function:nN {#4} + \@@_model_devicen_colorant:n + } + { + \str_case:nn {#3} + { + { cmyk } { /DeviceCMYK } + { gray } { /DeviceGray } + { rgb } { /DeviceRGB } + } + } + { \exp_not:V \l_@@_internal_tl } + } + } +\cs_new_protected:Npn \@@_model_devicen_transform:w + #1 , #2 , #3 , #4 , #5 \s_@@_stop #6#7 + { + \use:c { @@_model_devicen_transform_ #6 :nnnnn } + {#1} {#2} {#3} {#4} {#7} + } +\cs_new_protected:cpn { @@_model_devicen_transform_1:nnnnn } #1#2#3#4#5 + { \@@_model_devicen_transform:nnn {#5} { 1 } {#1} } +\cs_new_protected:cpn { @@_model_devicen_transform_3:nnnnn } #1#2#3#4#5 + { + \clist_map_inline { #1 , #2 , #3 } + { \@@_model_devicen_transform:nnn {#5} { 3 } {##1} } + } +\cs_new_protected:cpn { @@_model_devicen_transform_4:nnnnn } #1#2#3#4#5 + { + \clist_map_inline:nn { #1 , #2 , #3 , #4 } + { \@@_model_devicen_transform:nnn {#5} { 4 } {##1} } + } +\cs_new_protected:Npn \@@_model_devicen_transform:nnn #1#2#3 + { + \tl_put_right:Nx \l_@@_internal_tl + { + \fp_compare:nNnF {#3} = \c_zero_fp + { + \int_eval:n { #1 - \l_@@_internal_int + #2 } ~ index ~ + #3 ~ neg ~ mul ~ 1.0 ~ add ~ mul ~ + } + #2 ~ -1 ~ roll ~ + } + } +\cs_new:Npn \@@_model_devicen_colorant:n #1 + { + / \prop_item:Nn \g_@@_colorants_prop {#1} ~ + } +% \end{macrocode} +% Here we need to set up conversion from the DeviceN space to the alternative +% at the \TeX{} level. This also means supplying methods for inter-converting +% to other parameter-based spaces. Essentially the approach is exactly the same +% as the PostScript, just expressed in \TeX{} terms. +% \begin{macrocode} +\cs_new_protected:Npn \@@_model_devicen_convert:nnn #1#2#3 + { + \use:c { @@_model_devicen_convert_ #2 :nn } {#1} {#3} + } +\cs_new_protected:Npn \@@_model_devicen_convert_cmyk:nn #1#2 + { + \@@_model_convert:nnn {#1} { cmyk } { gray } + \@@_model_convert:nnn {#1} { cmyk } { rgb } + \@@_model_devicen_convert:nnnn {#1} { cmyk } { 4 } {#2} + } +\cs_new_protected:Npn \@@_model_devicen_convert_gray:nn #1#2 + { + \@@_model_convert:nnn {#1} { gray } { cmyk } + \@@_model_convert:nnn {#1} { gray } { rgb } + \@@_model_devicen_convert:nnnn {#1} { gray } { 1 } {#2} + } +\cs_new_protected:Npn \@@_model_devicen_convert_rgb:nn #1#2 + { + \@@_model_convert:nnn {#1} { rgb } { cmyk } + \@@_model_convert:nnn {#1} { rgb } { gray } + \@@_model_devicen_convert:nnnn {#1} { rgb } { 3 } {#2} + } +\cs_new_protected:Npn \@@_model_devicen_convert:nnnn #1#2#3#4 + { + \cs_new:cpx { @@_convert_ #1 _ #2 :w } ##1 \s_@@_stop + { + \exp_not:c { @@_convert_devicen_ #2 : \prg_replicate:nn {#3} { n } w } + \prg_replicate:nn {#3} { { 1 } } + ##1 \exp_not:N \s_@@_mark + \clist_map_function:nN {#4} \@@_model_devicen_convert:n + \exp_not:N \s_@@_stop + } + } +\cs_new:Npn \@@_model_devicen_convert:n #1 + { + { + \exp_args:Ne \@@_model_devicen_convert_aux:n + { \prop_item:Nn \g_@@_alternative_values_prop {#1} } + } + } +\cs_new:Npn \@@_model_devicen_convert_aux:n #1 + { \@@_model_devicen_convert_aux:w #1 , , , , \s_@@_stop } +\cs_new:Npn \@@_model_devicen_convert_aux:w #1 , #2 , #3 , #4 , #5 \s_@@_stop + { + {#1} + \tl_if_blank:nF {#2} + { + {#2} + \tl_if_blank:nF {#3} + { + {#3} + \tl_if_blank:nF {#4} { {#4} } + } + } + } +\cs_new:Npn \@@_convert_devicen_cmyk:nnnnw + #1#2#3#4#5 ~ #6 \s_@@_mark #7#8 \s_@@_stop + { + \@@_convert_devicen_cmyk:nnnnnnnnn {#5} {#1} {#2} {#3} {#4} #7 + #6 \s_@@_mark #8 \s_@@_stop + } +\cs_new:Npn \@@_convert_devicen_cmyk:nnnnnnnnn #1#2#3#4#5#6#7#8#9 + { + \use:e + { + \exp_not:N \@@_convert_devicen_cmyk_aux:nnnnw + { \fp_eval:n { #2 * (1 - (#1 * #6)) } } + { \fp_eval:n { #3 * (1 - (#1 * #7)) } } + { \fp_eval:n { #4 * (1 - (#1 * #8)) } } + { \fp_eval:n { #5 * (1 - (#1 * #9)) } } + } + } +\cs_new:Npn \@@_convert_devicen_cmyk_aux:nnnnw + #1#2#3#4 #5 \s_@@_mark #6 \s_@@_stop + { + \tl_if_blank:nTF {#5} + { + \fp_eval:n { 1 - #1 } ~ + \fp_eval:n { 1 - #2 } ~ + \fp_eval:n { 1 - #3 } ~ + \fp_eval:n { 1 - #4 } + } + { + \@@_convert_devicen_cmyk:nnnnw {#1} {#2} {#3} {#4} + #5 \s_@@_mark #6 \s_@@_stop + } + } +\cs_new:Npn \@@_convert_devicen_gray:nw + #1#2 ~ #3 \s_@@_mark #4#5 \s_@@_stop + { + \@@_convert_devicen_gray:nnn {#2} {#1} #4 + #3 \s_@@_mark #5 \s_@@_stop + } +\cs_new:Npn \@@_convert_devicen_gray:nnn #1#2#3 + { + \exp_arsgs:Ne \@@_convert_devicen_gray_aux:nw + { \fp_eval:n { #2 * (1 - (#1 * #3)) } } + } +\cs_new:Npn \@@_convert_devicen_gray_aux:nw + #1 #2 \s_@@_mark #3 \s_@@_stop + { + \tl_if_blank:nTF {#2} + { \fp_eval:n { 1 - #1 } } + { + \@@_convert_devicen_gray:nw {#1} + #2 \s_@@_mark #3 \s_@@_stop + } + } +\cs_new:Npn \@@_convert_devicen_rgb:nnnw + #1#2#3#4 ~ #5 \s_@@_mark #6#7 \s_@@_stop + { + \@@_convert_devicen_cmyk:nnnnnn {#4} {#1} {#2} {#3} #6 + #5 \s_@@_mark #7 \s_@@_stop + } +\cs_new:Npn \@@_convert_devicen_rgb:nnnnnnn #1#2#3#4#5#6#7 + { + \use:e + { + \exp_not:N \@@_convert_devicen_rgb_aux:nnnw + { \fp_eval:n { #2 * (1 - (#1 * #5)) } } + { \fp_eval:n { #3 * (1 - (#1 * #6)) } } + { \fp_eval:n { #4 * (1 - (#1 * #7)) } } + } + } +\cs_new:Npn \@@_convert_devicen_rgb_aux:nnnw + #1#2#3 #4 \s_@@_mark #5 \s_@@_stop + { + \tl_if_blank:nTF {#4} + { + \fp_eval:n { 1 - #1 } ~ + \fp_eval:n { 1 - #2 } ~ + \fp_eval:n { 1 - #3 } + } + { + \@@_convert_devicen_rgb:nnnw {#1} {#2} {#3} + #4 \s_@@_mark #5 \s_@@_stop + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Diagnostics} +% +% \begin{macro}{\color_show:n} +% \begin{macro}{\@@_show:n} +% Extract the information about a color and format for the user: the approach +% is similar to the keys module here. +% \begin{macrocode} +\cs_new_protected:Npn \color_show:n #1 + { + \msg_show:nnxxxx { LaTeX / color } { show } + {#1} + { + \@@_if_defined:nT {#1} + { + \exp_args:Nv \@@_show:n { l_@@_named_ #1 _tl } + \prop_map_function:cN + { l_@@_named_ #1 _prop } + \msg_show_item_unbraced:nn + } + } + { } + { } + } +\cs_new:Npn \@@_show:n #1 + { + \msg_show_item_unbraced:nn { model } {#1} + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Messages} +% +% \begin{macrocode} +\__kernel_msg_new:nnnn { color } { CIELAB-requires-illuminant } + { CIELAB~color~space~'#1'~require~an~illuminant. } + { + LaTeX~has~been~asked~to~create~a~separation~color~space~using~ + CIELAB~specifications,~but~no~\\ \\ + \iow_indent:n { illuminant~=~ } + \\ \\ + key~was~given~with~the~correct~information.~LaTeX~will~use~illuminant~ + 'd50'~for~recovery. + } +\__kernel_msg_new:nnnn { color } { conversion-not-available } + { No~model~conversion~available~from~'#1'~to~'#2'. } + { + LaTeX~has~been~asked~to~convert~a~color~from~model~'#1'~ + to~model'#2',~but~there~is~no~method~available~to~do~that. + } +\__kernel_msg_new:nnnn { color } { DeviceN-inconsistent-alternative } + { DeviceN~color~spaces~require~a~single~alternative~space. } + { + LaTeX~has~been~asked~to~create~a~DeviceN~color~space~'#1',~ + but~the~constituent~colors~do~not~have~a~common~alternative~ + color. + } +\__kernel_msg_new:nnnn { color } { DeviceN-no-alternative } + { DeviceN~color~spaces~require~an~alternative~space. } + { + LaTeX~has~been~asked~to~create~a~DeviceN~color~space~'#1',~ + but~the~constituent~colors~do~not~all~have~a~device-based~alternative. + } +\__kernel_msg_new:nnnn { color } { DeviceN-requires-names } + { DeviceN~color~space~'#1'~require~a~list~of~names. } + { + LaTeX~has~been~asked~to~create~a~DeviceN~color~space,~ + but~no~\\ \\ + \iow_indent:n { names~=~ } + \\ \\ + key~was~given~with~the~correct~information. + } +\__kernel_msg_new:nnnn { color } { model-already-defined } + { Color~model~'#1'~already~defined. } + { + LaTeX~was~asked~to~define~a~new~color~model~called~'#1',~but~ + this~color~model~already~exists. + } +\__kernel_msg_new:nnnn { color } { separation-alternative-model } + { Separation~color~space~'#1'~require~an~alternative~model. } + { + LaTeX~has~been~asked~to~create~a~separation~color~space,~ + but~no~\\ \\ + \iow_indent:n { alternative-model~=~ } + \\ \\ + key~was~given~with~the~correct~information. + } +\__kernel_msg_new:nnnn { color } { separation-alternative-values } + { Separation~color~space~'#1'~require~values~for~the~alternative~space. } + { + LaTeX~has~been~asked~to~create~a~separation~color~space,~ + but~no~\\ \\ + \iow_indent:n { alternative-values~=~ } + \\ \\ + key~was~given~with~the~correct~information. + } +\__kernel_msg_new:nnnn { color } { separation-requires-name } + { Separation~color~space~'#1'~require~a~formal~name. } + { + LaTeX~has~been~asked~to~create~a~separation~color~space,~ + but~no~\\ \\ + \iow_indent:n { name~=~ } + \\ \\ + key~was~given~with~the~correct~information. + } +\__kernel_msg_new:nnnn { color } { unknown-color } + { Unknown~color~'#1'. } + { + LaTeX~has~been~asked~to~use~a~color~named~'#1',~ + but~this~has~never~been~defined. + } +\__kernel_msg_new:nnnn { color } { unknown-alternative-model } + { Separation~color~space~'#1'~require~an~valid~alternative~space. } + { + LaTeX~has~been~asked~to~create~a~separation~color~space,~ + but~the~model~given~as\\ \\ + \iow_indent:n { alternative-model~=~ } + \\ \\ + is~unknown. + } +\__kernel_msg_new:nnnn { color } { unknown-export-format } + { Unknown~export~format~'#1'. } + { + LaTeX~has~been~asked~to~export~a~color~in~format~'#1',~ + but~this~has~never~been~defined. + } +\__kernel_msg_new:nnnn { color } { unknown-CIELAB-illuminant } + { Unknown~illuminant~model~'#1'. } + { + LaTeX~has~been~asked~to~use~create~a~color~space~using~CIELAB~ + illuminant~'#1',~but~this~does~not~exist. + } +\__kernel_msg_new:nnnn { color } { unknown-model } + { Unknown~color~model~'#1'. } + { + LaTeX~has~been~asked~to~use~a~color~model~called~'#1',~ + but~this~model~is~not~set~up. + } +\__kernel_msg_new:nnnn { color } { unknown-model-type } + { Unknown~color~model~type~'#1'. } + { + LaTeX~has~been~asked~to~create~a~new~color~model~called~'#1',~ + but~this~type~of~model~was~never~set~up. + } +% \end{macrocode} +% +% \begin{macrocode} +\__kernel_msg_new:nnn { color } { show } + { + The~color~#1~ + \tl_if_empty:nTF {#2} + { is~undefined. } + { has~the~properties: #2 } + } +% \end{macrocode} +% +% \begin{macrocode} +% +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx b/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx index 80a2cc426a6..107601afe8e 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx b/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx index 96d386ecfec..e5a70436f62 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx index e3fd13dab6d..47f57dfb669 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx @@ -79,7 +79,7 @@ and all files in that bundle must be distributed together. % % \title{The \cls{l3doc} class} % \author{\Team} -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % \maketitle % \tableofcontents % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx b/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx index a1f86a9c19c..c0b1db04876 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx @@ -63,7 +63,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx index 0025d711d8b..c4de266f4e9 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx index 01693e26dc2..76c21c537e7 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx b/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx index 0e6892fc6db..c55b5564537 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx index 4e5c3d6b456..30d9cc9ad57 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % \maketitle % % \begin{documentation} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx index be4dec34c95..451f0952fc0 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx index 445ea0006d7..0742eafffd3 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx index dbdee9f5b8e..ccac4b8a42c 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx index 38e41cd8fa0..09e0a27689f 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx index 549e9451ab2..d3654cf4f5b 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx index b2060ef461b..e6da23c805c 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx index c8c0ed52dd2..ce534ca6c68 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx index 5cf52ba78e5..cf909120d9a 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx index e2f868e939c..c67804df2be 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx index 1e0524c0923..c9d3d19deb2 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % \maketitle % % \begin{documentation} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx index 287efa3d54f..55460c8a8fe 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx index aabdf049248..476e7a8789b 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx @@ -49,7 +49,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx index 8ed455c2df4..9d4ca672adb 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx index 9a96fb09eba..85da3a199e1 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx b/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx index 97185bab736..dc7b7fdee8c 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx b/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx index 31484c04732..f0fd4227077 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx index 03e7b5210cd..4c2b01526a0 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx b/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx index 02b7e3037ef..b3c3627c6f7 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx b/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx index d58eeb50106..e4aed9498ce 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx index 747d087bc98..e51d93a30e9 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % @@ -444,6 +444,34 @@ % all (see the discussion of message redirection). % \end{function} % +% \subsection{Messages for showing material} +% +% \begin{function}[added = 2017-12-04] +% { +% \msg_show:nnnnnn , +% \msg_show:nnnnn , +% \msg_show:nnnn , +% \msg_show:nnn , +% \msg_show:nn , +% \msg_show:nnxxxx , +% \msg_show:nnxxx , +% \msg_show:nnxx , +% \msg_show:nnx +% } +% \begin{syntax} +% \cs{msg_show:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four} +% \end{syntax} +% Issues \meta{module} information \meta{message}, passing \meta{arg +% one} to \meta{arg four} to the text-creating functions. The +% information text is shown on the terminal and the \TeX{} run is +% interrupted in a manner similar to \cs{tl_show:n}. This is used in +% conjunction with \cs{msg_show_item:n} and similar functions to print +% complex variable contents completely. If the formatted text does +% not contain |>~| at the start of a line, an additional line |>~.| +% will be put at the end. In addition, a final period is added if not +% present. +% \end{function} +% % \subsection{Expandable error messages} % % In very rare cases it may be necessary to produce errors in an diff --git a/Master/texmf-dist/source/latex/l3kernel/l3names.dtx b/Master/texmf-dist/source/latex/l3kernel/l3names.dtx index a456c295d3b..bc7d4f12384 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3names.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3names.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx b/Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx new file mode 100644 index 00000000000..58f99438acc --- /dev/null +++ b/Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx @@ -0,0 +1,458 @@ +% \iffalse meta-comment +% +%% File: l3pdf.dtx +% +% Copyright(C) 2019-2021 The LaTeX Project +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% license or (at your option) any later version. The latest version +% of this license is in the file +% +% http://www.latex-project.org/lppl.txt +% +% This file is part of the "l3kernel bundle" (The Work in LPPL) +% and all files in that bundle must be distributed together. +% +% ----------------------------------------------------------------------- +% +% The development version of the bundle can be found at +% +% https://github.com/latex3/latex3 +% +% for those people who are interested. +% +%<*driver> +\documentclass[full]{l3doc} +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +% +% \fi +% +% \title{^^A +% The \pkg{l3pdf} package\\ Core PDF support^^A +% } +% +% \author{^^A +% The \LaTeX{} Project\thanks +% {^^A +% E-mail: +% \href{mailto:latex-team@latex-project.org} +% {latex-team@latex-project.org}^^A +% }^^A +% } +% +% \date{Released 2021-02-18} +% +% \maketitle +% +% \begin{documentation} +% +% \section{\pkg{l3pdf} documentation} +% +% \subsection{Objects} +% +% \begin{function}[added = 2021-02-10]{\pdf_object_new:nn} +% \begin{syntax} +% \cs{pdf_object_new:nn} \Arg{object} \Arg{type} +% \end{syntax} +% Declares \meta{object} as a PDF object of \meta{type}, which should be +% one of +% \begin{itemize} +% \item \texttt{array} +% \item \texttt{dict} +% \item \texttt{fstream} +% \item \texttt{stream} +% \end{itemize} +% The object may be referenced from this point on, and written later +% using \cs{pdf_object_write:nn}. +% \end{function} +% \begin{function}[EXP, pTF, added=2020-05-15]{\pdf_object_if_exist:n} +% \begin{syntax} +% \cs{pdf_object_if_exist_p:n} \Arg{object} +% \cs{pdf_object_if_exist:nTF} \Arg{object} +% \end{syntax} +% Tests whether an object with name \Arg{object} has been defined. +% \end{function} +% \begin{function}[added = 2021-02-10] +% {\pdf_object_write:nn, \pdf_object_write:nx} +% \begin{syntax} +% \cs{pdf_object_write:nn} \Arg{object} \Arg{content} +% \end{syntax} +% Writes the \meta{content} as content of the \meta{object}. Depending on the +% \meta{type} declared for the object, the format required for the +% \meta{data} will vary +% \begin{itemize} +% \item[\texttt{array}] A space-separated list of values +% \item[\texttt{dict}] Key--value pairs in the form +% \texttt{/\meta{key} \meta{value}} +% \item[\texttt{fstream}] Two brace groups: \meta{file name} and +% \meta{file content} +% \item[\texttt{stream}] Two brace groups: \meta{attributes (dictionary)} +% and \meta{stream contents} +% \end{itemize} +% \end{function} +% +% \begin{function}[EXP, added = 2021-02-10]{\pdf_object_ref:n} +% \begin{syntax} +% \cs{pdf_object_ref:n} \Arg{object} +% \end{syntax} +% Inserts the appropriate information to reference the \meta{object} +% in for example page resource allocation +% \end{function} +% +% \begin{function}[added = 2021-02-10] +% {\pdf_object_unnamed_write:nn, \pdf_object_unnamed_write:nx} +% \begin{syntax} +% \cs{pdf_object_unnamed_write:nn} \Arg{type} \Arg{content} +% \end{syntax} +% Writes the \meta{content} as content of an anonymous object. Depending on the +% \meta{type}, the format required for the \meta{data} will vary +% \begin{itemize} +% \item[\texttt{array}] A space-separated list of values +% \item[\texttt{dict}] Key--value pairs in the form +% \texttt{/\meta{key} \meta{value}} +% \item[\texttt{fstream}] Two brace groups: \meta{file name} and +% \meta{file content} +% \item[\texttt{stream}] Two brace groups: \meta{attributes (dictionary)} +% and \meta{stream contents} +% \end{itemize} +% \end{function} +% +% \begin{function}[EXP, added = 2021-02-10]{\pdf_object_ref_last:} +% \begin{syntax} +% \cs{pdf_object_ref_last:} +% \end{syntax} +% Inserts the appropriate information to reference the last \meta{object} +% created. This is particularly useful for anonymous objects. +% \end{function} +% +% \begin{function}[EXP, added = 2021-02-10]{\pdf_pageobject_ref:n} +% \begin{syntax} +% \cs{pdf_pagobject_ref:n} \Arg{pageobject} +% \end{syntax} +% Inserts the appropriate information to reference the \meta{pageobject}. +% \end{function} +% +% \subsection{Version} +% +% \begin{function}[pTF, EXP, added = 2021-02-10]{\pdf_version_compare:Nn} +% \begin{syntax} +% \cs{pdf_version_compare:NnTF} \meta{comparator} \Arg{version} \Arg{true code} \Arg{false code} +% \end{syntax} +% Compares the version of the PDF being created with the \meta{version} +% string specified, using the \meta{comparator}. Either the \meta{true code} +% or \meta{false code} will be left in the output stream. +% \end{function} +% +% \begin{function}[added = 2021-02-10] +% {\pdf_version_gset:n, \pdf_version_min_gset:n} +% \begin{syntax} +% \cs{pdf_version_gset:n} \Arg{version} +% \end{syntax} +% Sets the \meta{version} of the PDF being created. The |min| version will +% not alter the output version unless it is currently lower than the +% \meta{version} requested. +% +% This function may only be used up to the point where the PDF file is +% initialised. +% \end{function} +% +% \begin{function}[EXP, added = 2021-02-10] +% {\pdf_version:, \pdf_version_major:, \pdf_version_minor:} +% \begin{syntax} +% \cs{pdf_version:} +% \end{syntax} +% Expands to the currently-active PDF version. +% \end{function} +% +% \subsection{Compression} +% +% \begin{function}[added = 2021-02-10]{\pdf_uncompress:} +% \begin{syntax} +% \cs{pdf_uncompress:} +% \end{syntax} +% Disables any compression of the PDF, where possible. +% +% This function may only be used up to the point where the PDF file is +% initialised. +% \end{function} +% +% \subsection{Destinations} +% +% Destinations are the places a link jumped too. +% Unlike the name may suggest they don't described +% an exact location in the PDF. Instead a destination contains a reference to +% a page along with an instruction how to display this page. +% The normally used \enquote{XYZ \textit{top left zoom}} for example instructs +% the viewer to show the page with the given \textit{zoom} and +% the top left corner at the \textit{top left} coordinates---which then gives +% the impression that there is an anchor at this position. +% +% If an instruction takes a coordinate, it is calculated by the following +% commands relative to the location the command is issued. +% So to get a specific coordinate one has to move the command to the right place. +% +% \begin{function}[added = 2021-01-03] +% {\pdf_destination:nn} +% \begin{syntax} +% \cs{pdf_destination:nn} \Arg{name} \Arg{type or integer} +% \end{syntax} +% This creates a destination. \Arg{type or integer} can be one of |fit|, |fith|, +% |fitv|, |fitb|, |fitbh|, |fitbv|, |fitr|, |xyz| +% or an integer representing a scale factor in percent. +% |fitr| here gives only a lightweight version of |/FitR|: +% The backend code defines |fitr| so that it will with pdf\LaTeX{} and +% Lua\LaTeX{} use the coordinates of the surrounding box, +% with \texttt{dvips} and \texttt{dvipdfmx} it falls back to |fit|. +% For full control use \cs{pdf_destination:nnnn}. +% +% The keywords match to the PDF names as described in the following tabular. +% +% \medskip +% \noindent\begin{tabular}{ll>{\raggedright\arraybackslash}p{6cm}} +% \toprule +% Keyword & PDF & Remarks \\ \midrule +% |fit| & |/Fit| +% & Fits the page to the window\\ +% |fith| & |/FitH| \textit{top} +% & Fits the width of the page to the window \\ +% |fitv| & |/FitV| \textit{left} +% & Fits the height of the page to the window \\ +% |fitb| & |/FitB| +% & Fits the page bounding box to the window \\ +% |fitbh|& |/FitBH| \textit{top} +% & Fits the width of the page bounding box to the window. \\ +% |fitbv|& |/FitBV| \textit{left} +% & Fits the height of the page bounding box to the window. \\ +% |fitr| & |/FitR| \textit{left bottom right top} +% & Fits the rectangle specified by the four coordinates to the window +% (see above for the restrictions)\\ +% |xyz| & |/XYZ| \textit{left top} null +% & Sets a coordinate but doesn't change the zoom.\\ +% \Arg{integer} & |/XYZ| \textit{left top zoom} +% & Sets a coordinate and a zoom meaning \Arg{integer}\%. +% \\\bottomrule +% \end{tabular} +% +% \end{function} +% +% \begin{function}[added = 2021-01-17] +% {\pdf_destination:nnnn} +% \begin{syntax} +% \cs{pdf_destination:nnnn} \Arg{name} \Arg{width} \Arg{height} \Arg{depth} +% \end{syntax} +% This creates a destination with |/FitR| type with the given dimensions relative +% to the current location. The destination is in a box of size zero, but it doesn't +% switch to horizontal mode. +% \end{function} +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3pdf} implementation} +% +% \begin{macrocode} +%<*package> +% \end{macrocode} +% +% \begin{macrocode} +%<@@=pdf> +% \end{macrocode} +% +% \begin{variable}{\s_@@_stop} +% Internal scan marks. +% \begin{macrocode} +\scan_new:N \s_@@_stop +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\g_@@_init_bool} +% A flag so we have some chance of avoiding setting things we are not +% allowed to. As we are potentially early in the format, we have to work +% a bit harder than ideal. +% \begin{macrocode} +\bool_new:N \g_@@_init_bool +\bool_lazy_and:nnT + { \str_if_eq_p:Vn \fmtname { LaTeX2e } } + { \tl_if_exist_p:N \@expl@finalise@setup@@@@ } + { + \tl_gput_right:Nn \@expl@finalise@setup@@@@ + { + \tl_gput_right:Nn \@kernel@after@begindocument + { \bool_gset_true:N \g_@@_init_bool } + } + } +% \end{macrocode} +% \end{variable} +% +% \subsection{Compression} +% +% \begin{macro}{\pdf_uncompress:} +% Simple to do. +% \begin{macrocode} +\cs_new_protected:Npn \pdf_uncompress: + { + \bool_if:NF \g_@@_init_bool + { + \@@_backend_compresslevel:n { 0 } + \@@_backend_compress_objects:n { \c_false_bool } + } + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Objects} +% +% \begin{macro}{\pdf_object_new:nn, \pdf_object_write:nn, \pdf_object_write:nx} +% \begin{macro}[pTF]{\pdf_object_if_exist:n} +% \begin{macro}{\pdf_object_ref:n} +% \begin{macro}{\pdf_object_unnamed_write:nn, \pdf_object_unnamed_write:nx} +% \begin{macro}{\pdf_object_ref_last:} +% Simple to do. +% \begin{macrocode} +\cs_new_protected:Npn \pdf_object_new:nn #1#2 + { \@@_backend_object_new:nn {#1} {#2} } +\prg_new_conditional:Npnn \pdf_object_if_exist:n #1 { p , T , F , TF } + { + \int_if_exist:cTF { c_@@_backend_object_ \tl_to_str:n {#1} _int } + { \prg_return_true: } + { \prg_return_false:} + } +\cs_new_protected:Npn \pdf_object_write:nn #1#2 + { + \@@_backend_object_write:nn {#1} {#2} + \bool_gset_true:N \g_@@_init_bool + } +\cs_generate_variant:Nn \pdf_object_write:nn { nx } +\cs_new:Npn \pdf_object_ref:n #1 { \@@_backend_object_ref:n {#1} } +\cs_new_protected:Npn \pdf_object_unnamed_write:nn #1#2 + { + \@@_backend_object_now:nn {#1} {#2} + \bool_gset_true:N \g_@@_init_bool + } +\cs_generate_variant:Nn \pdf_object_unnamed_write:nn { nx } +\cs_new:Npn \pdf_object_ref_last: { \@@_backend_object_last: } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\pdf_pageobject_ref:n} +% \begin{macrocode} +\cs_new:Npn \pdf_pageobject_ref:n #1 + { \@@_backend_pageobject_ref:n {#1} } +% \end{macrocode} +% \end{macro} +% +% \subsection{Version} +% +% \begin{macro}{\pdf_version_compare:Nn} +% \begin{macro} +% { +% @@_version_compare_=:w , +% @@_version_compare_<:w , +% @@_version_compare_>:w +% } +% To compare version, we need to split the given value then deal with both +% major and minor version +% \begin{macrocode} +\prg_new_conditional:Npnn \pdf_version_compare:Nn #1#2 { p , T , F , TF } + { \use:c { @@_version_compare_ #1 :w } #2 . . \s_@@_stop } +\cs_new:cpn { @@_version_compare_=:w } #1 . #2 . #3 \s_@@_stop + { + \bool_lazy_and:nnTF + { \int_compare_p:nNn \@@_backend_version_major: = {#1} } + { \int_compare_p:nNn \@@_backend_version_minor: = {#2} } + { \prg_return_true: } + { \prg_return_false: } + } +\cs_new:cpn { @@_version_compare_<:w } #1 . #2 . #3 \s_@@_stop + { + \bool_lazy_or:nnTF + { \int_compare_p:nNn \@@_backend_version_major: < {#1} } + { + \bool_lazy_and_p:nn + { \int_compare_p:nNn \@@_backend_version_major: = {#1} } + { \int_compare_p:nNn \@@_backend_version_minor: < {#2} } + } + { \prg_return_true: } + { \prg_return_false: } + } +\cs_new:cpn { @@_version_compare_>:w } #1 . #2 . #3 \s_@@_stop + { + \bool_lazy_or:nnTF + { \int_compare_p:nNn \@@_backend_version_major: > {#1} } + { + \bool_lazy_and_p:nn + { \int_compare_p:nNn \@@_backend_version_major: = {#1} } + { \int_compare_p:nNn \@@_backend_version_minor: > {#2} } + } + { \prg_return_true: } + { \prg_return_false: } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\pdf_version_gset:n, \pdf_version_min_gset:n} +% \begin{macro}{\@@_version_gset:w} +% Split the version and set. +% \begin{macrocode} +\cs_new_protected:Npn \pdf_version_gset:n #1 + { \@@_version_gset:w #1 . . \s_@@_stop } +\cs_new_protected:Npn \pdf_version_min_gset:n #1 + { + \pdf_version_compare:NnT < {#1} + { \@@_version_gset:w #1 . . \s_@@_stop } + } +\cs_new_protected:Npn \@@_version_gset:w #1 . #2 . #3\s_@@_stop + { + \bool_if:NF \g_@@_init_bool + { + \@@_backend_version_major_gset:n {#1} + \@@_backend_version_minor_gset:n {#2} + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\pdf_version:, \pdf_version_major:, \pdf_version_minor:} +% Wrappers. +% \begin{macrocode} +\cs_new:Npn \pdf_version: + { \@@_backend_version_major: . \@@_backend_version_minor: } +\cs_new:Npn \pdf_version_major: { \@@_backend_version_major: } +\cs_new:Npn \pdf_version_minor: { \@@_backend_version_minor: } +% \end{macrocode} +% \end{macro} +% +% \subsection{Destinations} +% +% \begin{macro}{\pdf_destination:nn} +% \begin{macrocode} +\cs_new_protected:Npn \pdf_destination:nn #1#2 + { \@@_backend_destination:nn {#1} {#2} } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\pdf_destination:nnnn} +% \begin{macrocode} +\cs_new_protected:Npn \pdf_destination:nnnn #1#2#3#4 + { + \hbox_to_zero:n + { \@@_backend_destination:nnnn {#1} {#2} {#3} {#4} } + } +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +% +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx index a8089df0b49..e75ab65899f 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx index fe8ffaf5885..d8c7410aaa8 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx b/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx index 3b7d7ea1c25..8177a2a5899 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx b/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx index c26c8c0dd09..ef7ab6becc5 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % @@ -7033,6 +7033,13 @@ } % \end{macrocode} % +% Some escaped alphanumerics are not allowed everywhere. +% \begin{macrocode} +\__kernel_msg_new:nnnn { kernel } { backwards-quantifier } + { Quantifer~"{#1,#2}"~is~backwards. } + { The~values~given~in~a~quantifier~must~be~in~order. } +% \end{macrocode} +% % Used when showing a regex. % \begin{macrocode} \__kernel_msg_new:nnn { kernel } { show-regex } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx index 134f3c57dc7..046f42b8c5e 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx index fe5be582f59..97eaef163d2 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx b/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx index b55b2223da6..13b94daf67a 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx b/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx index 9ea4c901667..4cc29c2d21e 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % @@ -106,6 +106,8 @@ % \midrule % \texttt{clist} & comma-list of integers \\ % \meta{empty} & native (Unicode) string \\ +% \texttt{default} & like \texttt{utf8} with 8-bit engines, +% and like native with unicode-engines \\ % \bottomrule % \end{tabular} % \end{table} @@ -317,6 +319,17 @@ \prop_gput:Nnn \g_@@_alias_prop { utf32le } { utf32 } \prop_gput:Nnn \g_@@_alias_prop { utf32be } { utf32 } \prop_gput:Nnn \g_@@_alias_prop { hexadecimal } { hex } +\bool_lazy_any:nTF + { + \sys_if_engine_luatex_p: + \sys_if_engine_xetex_p: + } + { + \prop_gput:Nnn \g_@@_alias_prop { default } { } + } + { + \prop_gput:Nnn \g_@@_alias_prop { default } { utf8 } + } % \end{macrocode} % \end{variable} % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3str.dtx b/Master/texmf-dist/source/latex/l3kernel/l3str.dtx index 00c26f5f45b..2a0b175bfee 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3str.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3str.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx index 8761c5f4e7f..9bcbee56a66 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx b/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx index 8ebc6e3ccb5..19f6e85035b 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx b/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx index 2495a89db0e..f939085021c 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3text.dtx b/Master/texmf-dist/source/latex/l3kernel/l3text.dtx index 2634fd0a4ca..046bf686772 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3text.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3text.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % @@ -107,6 +107,7 @@ % function name. The category code of letters are not changed by this % process (at least where they can be represented by the engine as a single % token: $8$-bit engines may require active characters). +% \end{function} % % Upper- and lowercase have the obvious meanings. Titlecasing may be regarded % informally as converting the first character of the \meta{tokens} to @@ -194,7 +195,6 @@ % \cs{l_text_titlecase_check_letter_bool} is \texttt{false}, the first % character is uppercased, and the rest lowercased, irrespective of the nature % of the character. -% \end{function} % % \subsection{Removing formatting from text} % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx index 8bc8bb8652f..51ad05c9952 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx index 5e11227e3c4..c7038b08d12 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3token.dtx b/Master/texmf-dist/source/latex/l3kernel/l3token.dtx index a0027a698bd..31d4d7fcde9 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3token.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3token.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx b/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx index 8d4c2092ae5..a52823c1a2e 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-06} +% \date{Released 2021-02-18} % % \maketitle % diff --git a/Master/texmf-dist/tex/latex/l3backend/l3backend-dvipdfmx.def b/Master/texmf-dist/tex/latex/l3backend/l3backend-dvipdfmx.def index 97821be3cea..b05710c7175 100644 --- a/Master/texmf-dist/tex/latex/l3backend/l3backend-dvipdfmx.def +++ b/Master/texmf-dist/tex/latex/l3backend/l3backend-dvipdfmx.def @@ -26,7 +26,7 @@ %% %% File: l3backend-basics.dtx \ProvidesExplFile - {l3backend-dvipdfmx.def}{2021-02-06}{} + {l3backend-dvipdfmx.def}{2021-02-18}{} {L3 backend support: dvipdfmx} \cs_if_exist:NTF \__kernel_dependency_version_check:nn { @@ -128,7 +128,7 @@ } \int_compare:nNnF \c__kernel_sys_dvipdfmx_version_int < { 20201111 } { - \cs_new_protected:Npn \__color_backend_stack_push:nn #1#2 + \cs_new_protected:Npn \__kernel_color_backend_stack_push:nn #1#2 { \__kernel_backend_literal:x { @@ -137,8 +137,8 @@ push ~ (#2) } } - \cs_generate_variant:Nn \__color_backend_stack_push:nn { nx } - \cs_new_protected:Npn \__color_backend_stack_pop:n #1 + \cs_generate_variant:Nn \__kernel_color_backend_stack_push:nn { nx } + \cs_new_protected:Npn \__kernel_color_backend_stack_pop:n #1 { \__kernel_backend_literal:x { @@ -160,11 +160,11 @@ { \tl_set:Nn \l__color_backend_fill_tl {#1} \tl_set:Nn \l__color_backend_stroke_tl {#2} - \__color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ #2 } + \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ #2 } \group_insert_after:N \__color_backend_reset: } \cs_new_protected:Npn \__color_backend_reset: - { \__color_backend_stack_pop:n \l__color_backend_stack_int } + { \__kernel_color_backend_stack_pop:n \l__color_backend_stack_int } \int_compare:nNnT \c__kernel_sys_dvipdfmx_version_int < { 20201111 } { \cs_gset_protected:Npn \__color_backend_select_cmyk:n #1 @@ -182,7 +182,7 @@ \cs_new_eq:NN \__color_backend_select_devicen:nn \__color_backend_select_separation:nn \cs_new_protected:Npn \__color_backend_separation_init:nnnnn #1#2#3#4#5 { - \pdf_object_now:nx { dict } + \pdf_object_unnamed_write:nx { dict } { /FunctionType ~ 2 /Domain ~ [0 ~ 1] @@ -194,21 +194,22 @@ { /Separation ~ / \str_convert_pdfname:n {#1} ~ #2 ~ - \pdf_object_last: + \pdf_object_ref_last: } - \use:x + \cs_if_exist:NT \pdfmanagement_add:nnn { - \pdfmanagement_add:nnn - { Page / Resources / ColorSpace } - { color \int_use:N \g__color_model_int } - { \pdf_object_last: } + \use:x + { + \pdfmanagement_add:nnn + { Page / Resources / ColorSpace } + { color \int_use:N \g__color_model_int } + { \pdf_object_ref_last: } + } } } -\cs_if_exist:NF \pdf_object_now:nn - { \cs_gset_protected:Npn \__color_backend_separation_init:nnnnn #1#2#3#4#5 { } } \cs_new_protected:Npn \__color_backend_separation_init:n #1 { - \pdf_object_now:nx { array } {#1} + \pdf_object_unnamed_write:nx { array } {#1} } \cs_new_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3 { @@ -232,14 +233,14 @@ { 100 ~ 0 ~ 0 } {#3} } -\cs_if_exist:NF \pdf_object_now:nn +\cs_if_exist:NF \pdf_object_unnamed_write:nn { \cs_gset_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3 { } } \cs_new_protected:Npn \__color_backend_devicen_init:nnn #1#2#3 { - \pdf_object_now:nx { stream } + \pdf_object_unnamed_write:nx { stream } { { /FunctionType ~ 4 ~ @@ -266,18 +267,19 @@ /DeviceN ~ [ ~ #1 ~ ] ~ #2 ~ - \pdf_object_last: + \pdf_object_ref_last: } - \use:x + \cs_if_exist:NT \pdfmanagement_add:nnn { - \pdfmanagement_add:nnn - { Page / Resources / ColorSpace } - { color \int_use:N \g__color_model_int } - { \pdf_object_last: } + \use:x + { + \pdfmanagement_add:nnn + { Page / Resources / ColorSpace } + { color \int_use:N \g__color_model_int } + { \pdf_object_ref_last: } + } } } -\cs_if_exist:NF \pdf_object_now:nn - { \cs_gset_protected:Npn \__color_backend_devicen_init:nnn #1#2#3 { } } \cs_new:Npn \__color_backend_devicen_init:w #1 ~ #2 \s__color_stop { + 1 @@ -300,7 +302,7 @@ \cs_new_protected:Npn \__color_backend_fill:n #1 { \tl_set:Nn \l__color_backend_fill_tl {#1} - \__color_backend_stack_push:nn \l__color_backend_stack_int + \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ \l__color_backend_stroke_tl } \group_insert_after:N \__color_backend_reset: } @@ -313,7 +315,7 @@ \cs_new_protected:Npn \__color_backend_stroke:n #1 { \tl_set:Nn \l__color_backend_stroke_tl {#1} - \__color_backend_stack_push:nn \l__color_backend_stack_int + \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int { \l__color_backend_fill_tl \c_space_tl #1 } \group_insert_after:N \__color_backend_reset: } @@ -902,7 +904,7 @@ \pdfmanagement_add:nnn { Page / Resources / ExtGState } { opacity #1 } { << /ca ~ #1 /CA ~ #1 >> } - \__opacity_backend_stack_push:nn \c__opacity_backend_stack_int + \__kernel_color_backend_stack_push:nn \c__opacity_backend_stack_int { /opacity #1 ~ gs } \group_insert_after:N \__opacity_backend_reset: } @@ -911,7 +913,7 @@ \cs_gset_protected:Npn \__opacity_backend_select_aux:n #1 { } } \cs_new_protected:Npn \__opacity_backend_reset: - { \__opacity_backend_stack_pop:n \c__opacity_backend_stack_int } + { \__kernel_color_backend_stack_pop:n \c__opacity_backend_stack_int } \cs_new_protected:Npn \__opacity_backend_fill:n #1 { \__opacity_backend_fill_stroke:xx @@ -937,7 +939,7 @@ \pdfmanagement_add:nnn { Page / Resources / ExtGState } { opacity.stroke #1 } { << /CA ~ #2 >> } - \__opacity_backend_stack_push:nn \c__opacity_backend_stack_int + \__kernel_color_backend_stack_push:nn \c__opacity_backend_stack_int { /opacity.fill #1 ~ gs /opacity.stroke #2 ~ gs } \group_insert_after:N \__opacity_backend_reset: } diff --git a/Master/texmf-dist/tex/latex/l3backend/l3backend-dvips.def b/Master/texmf-dist/tex/latex/l3backend/l3backend-dvips.def index c5002b58b6a..1e47603f763 100644 --- a/Master/texmf-dist/tex/latex/l3backend/l3backend-dvips.def +++ b/Master/texmf-dist/tex/latex/l3backend/l3backend-dvips.def @@ -26,7 +26,7 @@ %% %% File: l3backend-basics.dtx \ProvidesExplFile - {l3backend-dvips.def}{2021-02-06}{} + {l3backend-dvips.def}{2021-02-18}{} {L3 backend support: dvips} \cs_if_exist:NTF \__kernel_dependency_version_check:nn { diff --git a/Master/texmf-dist/tex/latex/l3backend/l3backend-dvisvgm.def b/Master/texmf-dist/tex/latex/l3backend/l3backend-dvisvgm.def index 759c1531eef..078970ec7c9 100644 --- a/Master/texmf-dist/tex/latex/l3backend/l3backend-dvisvgm.def +++ b/Master/texmf-dist/tex/latex/l3backend/l3backend-dvisvgm.def @@ -26,7 +26,7 @@ %% %% File: l3backend-basics.dtx \ProvidesExplFile - {l3backend-dvisvgm.def}{2021-02-06}{} + {l3backend-dvisvgm.def}{2021-02-18}{} {L3 backend support: dvisvgm} \cs_if_exist:NTF \__kernel_dependency_version_check:nn { diff --git a/Master/texmf-dist/tex/latex/l3backend/l3backend-luatex.def b/Master/texmf-dist/tex/latex/l3backend/l3backend-luatex.def index 049a216db17..235eaa023e3 100644 --- a/Master/texmf-dist/tex/latex/l3backend/l3backend-luatex.def +++ b/Master/texmf-dist/tex/latex/l3backend/l3backend-luatex.def @@ -26,7 +26,7 @@ %% %% File: l3backend-basics.dtx \ProvidesExplFile - {l3backend-luatex.def}{2021-02-06}{} + {l3backend-luatex.def}{2021-02-18}{} {L3 backend support: PDF output (LuaTeX)} \cs_if_exist:NTF \__kernel_dependency_version_check:nn { @@ -114,13 +114,13 @@ {#3} } } -\cs_new_protected:Npn \__color_backend_stack_push:nn #1#2 +\cs_new_protected:Npn \__kernel_color_backend_stack_push:nn #1#2 { \tex_pdfextension:D colorstack ~ \int_eval:n {#1} ~ push ~ {#2} } -\cs_generate_variant:Nn \__color_backend_stack_push:nn { nx } -\cs_new_protected:Npn \__color_backend_stack_pop:n #1 +\cs_generate_variant:Nn \__kernel_color_backend_stack_push:nn { nx } +\cs_new_protected:Npn \__kernel_color_backend_stack_pop:n #1 { \tex_pdfextension:D colorstack ~ \int_eval:n {#1} ~ pop \scan_stop: @@ -137,17 +137,17 @@ { \tl_set:Nn \l__color_backend_fill_tl {#1} \tl_set:Nn \l__color_backend_stroke_tl {#2} - \__color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ #2 } + \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ #2 } \group_insert_after:N \__color_backend_reset: } \cs_new_protected:Npn \__color_backend_reset: - { \__color_backend_stack_pop:n \l__color_backend_stack_int } + { \__kernel_color_backend_stack_pop:n \l__color_backend_stack_int } \cs_new_protected:Npn \__color_backend_select_separation:nn #1#2 { \__color_backend_select:nn { /#1 ~ cs ~ #2 ~ scn } { /#1 ~ CS ~ #2 ~ SCN } } \cs_new_eq:NN \__color_backend_select_devicen:nn \__color_backend_select_separation:nn \cs_new_protected:Npn \__color_backend_separation_init:nnnnn #1#2#3#4#5 { - \pdf_object_now:nx { dict } + \pdf_object_unnamed_write:nx { dict } { /FunctionType ~ 2 /Domain ~ [0 ~ 1] @@ -159,21 +159,22 @@ { /Separation ~ / \str_convert_pdfname:n {#1} ~ #2 ~ - \pdf_object_last: + \pdf_object_ref_last: } - \use:x + \cs_if_exist:NT \pdfmanagement_add:nnn { - \pdfmanagement_add:nnn - { Page / Resources / ColorSpace } - { color \int_use:N \g__color_model_int } - { \pdf_object_last: } + \use:x + { + \pdfmanagement_add:nnn + { Page / Resources / ColorSpace } + { color \int_use:N \g__color_model_int } + { \pdf_object_ref_last: } + } } } -\cs_if_exist:NF \pdf_object_now:nn - { \cs_gset_protected:Npn \__color_backend_separation_init:nnnnn #1#2#3#4#5 { } } \cs_new_protected:Npn \__color_backend_separation_init:n #1 { - \pdf_object_now:nx { array } {#1} + \pdf_object_unnamed_write:nx { array } {#1} } \cs_new_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3 { @@ -197,14 +198,14 @@ { 100 ~ 0 ~ 0 } {#3} } -\cs_if_exist:NF \pdf_object_now:nn +\cs_if_exist:NF \pdf_object_unnamed_write:nn { \cs_gset_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3 { } } \cs_new_protected:Npn \__color_backend_devicen_init:nnn #1#2#3 { - \pdf_object_now:nx { stream } + \pdf_object_unnamed_write:nx { stream } { { /FunctionType ~ 4 ~ @@ -231,18 +232,19 @@ /DeviceN ~ [ ~ #1 ~ ] ~ #2 ~ - \pdf_object_last: + \pdf_object_ref_last: } - \use:x + \cs_if_exist:NT \pdfmanagement_add:nnn { - \pdfmanagement_add:nnn - { Page / Resources / ColorSpace } - { color \int_use:N \g__color_model_int } - { \pdf_object_last: } + \use:x + { + \pdfmanagement_add:nnn + { Page / Resources / ColorSpace } + { color \int_use:N \g__color_model_int } + { \pdf_object_ref_last: } + } } } -\cs_if_exist:NF \pdf_object_now:nn - { \cs_gset_protected:Npn \__color_backend_devicen_init:nnn #1#2#3 { } } \cs_new:Npn \__color_backend_devicen_init:w #1 ~ #2 \s__color_stop { + 1 @@ -259,7 +261,7 @@ \cs_new_protected:Npn \__color_backend_fill:n #1 { \tl_set:Nn \l__color_backend_fill_tl {#1} - \__color_backend_stack_push:nn \l__color_backend_stack_int + \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ \l__color_backend_stroke_tl } \group_insert_after:N \__color_backend_reset: } @@ -272,7 +274,7 @@ \cs_new_protected:Npn \__color_backend_stroke:n #1 { \tl_set:Nn \l__color_backend_stroke_tl {#1} - \__color_backend_stack_push:nn \l__color_backend_stack_int + \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int { \l__color_backend_fill_tl \c_space_tl #1 } \group_insert_after:N \__color_backend_reset: } @@ -773,7 +775,7 @@ \pdfmanagement_add:nnn { Page / Resources / ExtGState } { opacity #1 } { << /ca ~ #1 /CA ~ #1 >> } - \__opacity_backend_stack_push:nn \c__opacity_backend_stack_int + \__kernel_color_backend_stack_push:nn \c__opacity_backend_stack_int { /opacity #1 ~ gs } \group_insert_after:N \__opacity_backend_reset: } @@ -782,7 +784,7 @@ \cs_gset_protected:Npn \__opacity_backend_select_aux:n #1 { } } \cs_new_protected:Npn \__opacity_backend_reset: - { \__opacity_backend_stack_pop:n \c__opacity_backend_stack_int } + { \__kernel_color_backend_stack_pop:n \c__opacity_backend_stack_int } \cs_new_protected:Npn \__opacity_backend_fill:n #1 { \__opacity_backend_fill_stroke:xx @@ -808,7 +810,7 @@ \pdfmanagement_add:nnn { Page / Resources / ExtGState } { opacity.stroke #1 } { << /CA ~ #2 >> } - \__opacity_backend_stack_push:nn \c__opacity_backend_stack_int + \__kernel_color_backend_stack_push:nn \c__opacity_backend_stack_int { /opacity.fill #1 ~ gs /opacity.stroke #2 ~ gs } \group_insert_after:N \__opacity_backend_reset: } diff --git a/Master/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def b/Master/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def index e7f4ad30113..93ba0c8ef3d 100644 --- a/Master/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def +++ b/Master/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def @@ -26,7 +26,7 @@ %% %% File: l3backend-basics.dtx \ProvidesExplFile - {l3backend-pdftex.def}{2021-02-06}{} + {l3backend-pdftex.def}{2021-02-18}{} {L3 backend support: PDF output (pdfTeX)} \cs_if_exist:NTF \__kernel_dependency_version_check:nn { @@ -114,13 +114,13 @@ {#3} } } -\cs_new_protected:Npn \__color_backend_stack_push:nn #1#2 +\cs_new_protected:Npn \__kernel_color_backend_stack_push:nn #1#2 { \tex_pdfcolorstack:D \int_eval:n {#1} ~ push ~ {#2} } -\cs_generate_variant:Nn \__color_backend_stack_push:nn { nx } -\cs_new_protected:Npn \__color_backend_stack_pop:n #1 +\cs_generate_variant:Nn \__kernel_color_backend_stack_push:nn { nx } +\cs_new_protected:Npn \__kernel_color_backend_stack_pop:n #1 { \tex_pdfcolorstack:D \int_eval:n {#1} ~ pop \scan_stop: @@ -137,17 +137,17 @@ { \tl_set:Nn \l__color_backend_fill_tl {#1} \tl_set:Nn \l__color_backend_stroke_tl {#2} - \__color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ #2 } + \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ #2 } \group_insert_after:N \__color_backend_reset: } \cs_new_protected:Npn \__color_backend_reset: - { \__color_backend_stack_pop:n \l__color_backend_stack_int } + { \__kernel_color_backend_stack_pop:n \l__color_backend_stack_int } \cs_new_protected:Npn \__color_backend_select_separation:nn #1#2 { \__color_backend_select:nn { /#1 ~ cs ~ #2 ~ scn } { /#1 ~ CS ~ #2 ~ SCN } } \cs_new_eq:NN \__color_backend_select_devicen:nn \__color_backend_select_separation:nn \cs_new_protected:Npn \__color_backend_separation_init:nnnnn #1#2#3#4#5 { - \pdf_object_now:nx { dict } + \pdf_object_unnamed_write:nx { dict } { /FunctionType ~ 2 /Domain ~ [0 ~ 1] @@ -159,21 +159,22 @@ { /Separation ~ / \str_convert_pdfname:n {#1} ~ #2 ~ - \pdf_object_last: + \pdf_object_ref_last: } - \use:x + \cs_if_exist:NT \pdfmanagement_add:nnn { - \pdfmanagement_add:nnn - { Page / Resources / ColorSpace } - { color \int_use:N \g__color_model_int } - { \pdf_object_last: } + \use:x + { + \pdfmanagement_add:nnn + { Page / Resources / ColorSpace } + { color \int_use:N \g__color_model_int } + { \pdf_object_ref_last: } + } } } -\cs_if_exist:NF \pdf_object_now:nn - { \cs_gset_protected:Npn \__color_backend_separation_init:nnnnn #1#2#3#4#5 { } } \cs_new_protected:Npn \__color_backend_separation_init:n #1 { - \pdf_object_now:nx { array } {#1} + \pdf_object_unnamed_write:nx { array } {#1} } \cs_new_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3 { @@ -197,14 +198,14 @@ { 100 ~ 0 ~ 0 } {#3} } -\cs_if_exist:NF \pdf_object_now:nn +\cs_if_exist:NF \pdf_object_unnamed_write:nn { \cs_gset_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3 { } } \cs_new_protected:Npn \__color_backend_devicen_init:nnn #1#2#3 { - \pdf_object_now:nx { stream } + \pdf_object_unnamed_write:nx { stream } { { /FunctionType ~ 4 ~ @@ -231,18 +232,19 @@ /DeviceN ~ [ ~ #1 ~ ] ~ #2 ~ - \pdf_object_last: + \pdf_object_ref_last: } - \use:x + \cs_if_exist:NT \pdfmanagement_add:nnn { - \pdfmanagement_add:nnn - { Page / Resources / ColorSpace } - { color \int_use:N \g__color_model_int } - { \pdf_object_last: } + \use:x + { + \pdfmanagement_add:nnn + { Page / Resources / ColorSpace } + { color \int_use:N \g__color_model_int } + { \pdf_object_ref_last: } + } } } -\cs_if_exist:NF \pdf_object_now:nn - { \cs_gset_protected:Npn \__color_backend_devicen_init:nnn #1#2#3 { } } \cs_new:Npn \__color_backend_devicen_init:w #1 ~ #2 \s__color_stop { + 1 @@ -259,7 +261,7 @@ \cs_new_protected:Npn \__color_backend_fill:n #1 { \tl_set:Nn \l__color_backend_fill_tl {#1} - \__color_backend_stack_push:nn \l__color_backend_stack_int + \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ \l__color_backend_stroke_tl } \group_insert_after:N \__color_backend_reset: } @@ -272,7 +274,7 @@ \cs_new_protected:Npn \__color_backend_stroke:n #1 { \tl_set:Nn \l__color_backend_stroke_tl {#1} - \__color_backend_stack_push:nn \l__color_backend_stack_int + \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int { \l__color_backend_fill_tl \c_space_tl #1 } \group_insert_after:N \__color_backend_reset: } @@ -773,7 +775,7 @@ \pdfmanagement_add:nnn { Page / Resources / ExtGState } { opacity #1 } { << /ca ~ #1 /CA ~ #1 >> } - \__opacity_backend_stack_push:nn \c__opacity_backend_stack_int + \__kernel_color_backend_stack_push:nn \c__opacity_backend_stack_int { /opacity #1 ~ gs } \group_insert_after:N \__opacity_backend_reset: } @@ -782,7 +784,7 @@ \cs_gset_protected:Npn \__opacity_backend_select_aux:n #1 { } } \cs_new_protected:Npn \__opacity_backend_reset: - { \__opacity_backend_stack_pop:n \c__opacity_backend_stack_int } + { \__kernel_color_backend_stack_pop:n \c__opacity_backend_stack_int } \cs_new_protected:Npn \__opacity_backend_fill:n #1 { \__opacity_backend_fill_stroke:xx @@ -808,7 +810,7 @@ \pdfmanagement_add:nnn { Page / Resources / ExtGState } { opacity.stroke #1 } { << /CA ~ #2 >> } - \__opacity_backend_stack_push:nn \c__opacity_backend_stack_int + \__kernel_color_backend_stack_push:nn \c__opacity_backend_stack_int { /opacity.fill #1 ~ gs /opacity.stroke #2 ~ gs } \group_insert_after:N \__opacity_backend_reset: } diff --git a/Master/texmf-dist/tex/latex/l3backend/l3backend-xetex.def b/Master/texmf-dist/tex/latex/l3backend/l3backend-xetex.def index d236bcfc8a7..b4603d6f1b2 100644 --- a/Master/texmf-dist/tex/latex/l3backend/l3backend-xetex.def +++ b/Master/texmf-dist/tex/latex/l3backend/l3backend-xetex.def @@ -26,7 +26,7 @@ %% %% File: l3backend-basics.dtx \ProvidesExplFile - {l3backend-xetex.def}{2021-02-06}{} + {l3backend-xetex.def}{2021-02-18}{} {L3 backend support: XeTeX} \cs_if_exist:NTF \__kernel_dependency_version_check:nn { @@ -128,7 +128,7 @@ } \int_compare:nNnF \c__kernel_sys_dvipdfmx_version_int < { 20201111 } { - \cs_new_protected:Npn \__color_backend_stack_push:nn #1#2 + \cs_new_protected:Npn \__kernel_color_backend_stack_push:nn #1#2 { \__kernel_backend_literal:x { @@ -137,8 +137,8 @@ push ~ (#2) } } - \cs_generate_variant:Nn \__color_backend_stack_push:nn { nx } - \cs_new_protected:Npn \__color_backend_stack_pop:n #1 + \cs_generate_variant:Nn \__kernel_color_backend_stack_push:nn { nx } + \cs_new_protected:Npn \__kernel_color_backend_stack_pop:n #1 { \__kernel_backend_literal:x { @@ -160,11 +160,11 @@ { \tl_set:Nn \l__color_backend_fill_tl {#1} \tl_set:Nn \l__color_backend_stroke_tl {#2} - \__color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ #2 } + \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ #2 } \group_insert_after:N \__color_backend_reset: } \cs_new_protected:Npn \__color_backend_reset: - { \__color_backend_stack_pop:n \l__color_backend_stack_int } + { \__kernel_color_backend_stack_pop:n \l__color_backend_stack_int } \int_compare:nNnT \c__kernel_sys_dvipdfmx_version_int < { 20201111 } { \cs_gset_protected:Npn \__color_backend_select_cmyk:n #1 @@ -182,7 +182,7 @@ \cs_new_eq:NN \__color_backend_select_devicen:nn \__color_backend_select_separation:nn \cs_new_protected:Npn \__color_backend_separation_init:nnnnn #1#2#3#4#5 { - \pdf_object_now:nx { dict } + \pdf_object_unnamed_write:nx { dict } { /FunctionType ~ 2 /Domain ~ [0 ~ 1] @@ -194,21 +194,22 @@ { /Separation ~ / \str_convert_pdfname:n {#1} ~ #2 ~ - \pdf_object_last: + \pdf_object_ref_last: } - \use:x + \cs_if_exist:NT \pdfmanagement_add:nnn { - \pdfmanagement_add:nnn - { Page / Resources / ColorSpace } - { color \int_use:N \g__color_model_int } - { \pdf_object_last: } + \use:x + { + \pdfmanagement_add:nnn + { Page / Resources / ColorSpace } + { color \int_use:N \g__color_model_int } + { \pdf_object_ref_last: } + } } } -\cs_if_exist:NF \pdf_object_now:nn - { \cs_gset_protected:Npn \__color_backend_separation_init:nnnnn #1#2#3#4#5 { } } \cs_new_protected:Npn \__color_backend_separation_init:n #1 { - \pdf_object_now:nx { array } {#1} + \pdf_object_unnamed_write:nx { array } {#1} } \cs_new_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3 { @@ -232,14 +233,14 @@ { 100 ~ 0 ~ 0 } {#3} } -\cs_if_exist:NF \pdf_object_now:nn +\cs_if_exist:NF \pdf_object_unnamed_write:nn { \cs_gset_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3 { } } \cs_new_protected:Npn \__color_backend_devicen_init:nnn #1#2#3 { - \pdf_object_now:nx { stream } + \pdf_object_unnamed_write:nx { stream } { { /FunctionType ~ 4 ~ @@ -266,18 +267,19 @@ /DeviceN ~ [ ~ #1 ~ ] ~ #2 ~ - \pdf_object_last: + \pdf_object_ref_last: } - \use:x + \cs_if_exist:NT \pdfmanagement_add:nnn { - \pdfmanagement_add:nnn - { Page / Resources / ColorSpace } - { color \int_use:N \g__color_model_int } - { \pdf_object_last: } + \use:x + { + \pdfmanagement_add:nnn + { Page / Resources / ColorSpace } + { color \int_use:N \g__color_model_int } + { \pdf_object_ref_last: } + } } } -\cs_if_exist:NF \pdf_object_now:nn - { \cs_gset_protected:Npn \__color_backend_devicen_init:nnn #1#2#3 { } } \cs_new:Npn \__color_backend_devicen_init:w #1 ~ #2 \s__color_stop { + 1 @@ -300,7 +302,7 @@ \cs_new_protected:Npn \__color_backend_fill:n #1 { \tl_set:Nn \l__color_backend_fill_tl {#1} - \__color_backend_stack_push:nn \l__color_backend_stack_int + \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ \l__color_backend_stroke_tl } \group_insert_after:N \__color_backend_reset: } @@ -313,7 +315,7 @@ \cs_new_protected:Npn \__color_backend_stroke:n #1 { \tl_set:Nn \l__color_backend_stroke_tl {#1} - \__color_backend_stack_push:nn \l__color_backend_stack_int + \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int { \l__color_backend_fill_tl \c_space_tl #1 } \group_insert_after:N \__color_backend_reset: } @@ -948,7 +950,7 @@ \pdfmanagement_add:nnn { Page / Resources / ExtGState } { opacity #1 } { << /ca ~ #1 /CA ~ #1 >> } - \__opacity_backend_stack_push:nn \c__opacity_backend_stack_int + \__kernel_color_backend_stack_push:nn \c__opacity_backend_stack_int { /opacity #1 ~ gs } \group_insert_after:N \__opacity_backend_reset: } @@ -957,7 +959,7 @@ \cs_gset_protected:Npn \__opacity_backend_select_aux:n #1 { } } \cs_new_protected:Npn \__opacity_backend_reset: - { \__opacity_backend_stack_pop:n \c__opacity_backend_stack_int } + { \__kernel_color_backend_stack_pop:n \c__opacity_backend_stack_int } \cs_new_protected:Npn \__opacity_backend_fill:n #1 { \__opacity_backend_fill_stroke:xx @@ -983,7 +985,7 @@ \pdfmanagement_add:nnn { Page / Resources / ExtGState } { opacity.stroke #1 } { << /CA ~ #2 >> } - \__opacity_backend_stack_push:nn \c__opacity_backend_stack_int + \__kernel_color_backend_stack_push:nn \c__opacity_backend_stack_int { /opacity.fill #1 ~ gs /opacity.stroke #2 ~ gs } \group_insert_after:N \__opacity_backend_reset: } diff --git a/Master/texmf-dist/tex/latex/l3experimental/l3benchmark/l3benchmark.sty b/Master/texmf-dist/tex/latex/l3experimental/l3benchmark/l3benchmark.sty index 953430df265..113dfeaf344 100644 --- a/Master/texmf-dist/tex/latex/l3experimental/l3benchmark/l3benchmark.sty +++ b/Master/texmf-dist/tex/latex/l3experimental/l3benchmark/l3benchmark.sty @@ -20,7 +20,7 @@ %% %% File: l3benchmark.dtx \RequirePackage{expl3} -\ProvidesExplPackage{l3benchmark}{2021-02-06}{} +\ProvidesExplPackage{l3benchmark}{2021-02-18}{} {L3 Experimental benchmarking} \sys_if_engine_luatex:TF { diff --git a/Master/texmf-dist/tex/latex/l3experimental/l3bitset/l3bitset.sty b/Master/texmf-dist/tex/latex/l3experimental/l3bitset/l3bitset.sty index 38db17c6827..9d04de5f276 100644 --- a/Master/texmf-dist/tex/latex/l3experimental/l3bitset/l3bitset.sty +++ b/Master/texmf-dist/tex/latex/l3experimental/l3bitset/l3bitset.sty @@ -19,7 +19,7 @@ %% and all files in that bundle must be distributed together. %% %% File: l3bitset.dtx -\ProvidesExplPackage{l3bitset}{2021-02-06}{} +\ProvidesExplPackage{l3bitset}{2021-02-18}{} {L3 Experimental bitset support} \cs_new_protected:Npn \bitset_new:N #1 { diff --git a/Master/texmf-dist/tex/latex/l3experimental/l3color/l3color.sty b/Master/texmf-dist/tex/latex/l3experimental/l3color/l3color.sty deleted file mode 100644 index ad80915625b..00000000000 --- a/Master/texmf-dist/tex/latex/l3experimental/l3color/l3color.sty +++ /dev/null @@ -1,1448 +0,0 @@ -%% -%% This is file `l3color.sty', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% l3color.dtx (with options: `package') -%% -%% Copyright (C) 2017-2021 The LaTeX Project -%% -%% It may be distributed and/or modified under the conditions of -%% the LaTeX Project Public License (LPPL), either version 1.3c of -%% this license or (at your option) any later version. The latest -%% version of this license is in the file: -%% -%% http://www.latex-project.org/lppl.txt -%% -%% This file is part of the "l3experimental bundle" (The Work in LPPL) -%% and all files in that bundle must be distributed together. -%% -%% File: l3color.dtx -\RequirePackage{expl3} -\ProvidesExplPackage{l3color}{2021-02-06}{} - {L3 Experimental color support} -\int_new:N \l__color_internal_int -\tl_new:N \l__color_internal_tl -\scan_new:N \s__color_mark -\prg_new_conditional:Npnn \__color_if_defined:n #1 { T, F, TF } - { - \prop_if_exist:cTF { l__color_named_ #1 _prop } - \prg_return_true: - \prg_return_false: - } -\cs_new:Npn \__color_model:N #1 { \exp_after:wN \use_i:nn #1 } -\cs_new:Npn \__color_values:N #1 { \exp_after:wN \use_ii:nn #1 } -\cs_new_protected:Npn \__color_extract:nNN #1#2#3 - { - \tl_set_eq:Nc #2 { l__color_named_ #1 _tl } - \prop_get:cVN { l__color_named_ #1 _prop } #2 #3 - } -\cs_generate_variant:Nn \__color_extract:nNN { V } -\cs_new_protected:Npn \__color_convert:nnN #1#2#3 - { \__color_convert:nnVN {#1} {#2} #3 #3 } -\cs_generate_variant:Nn \__color_convert:nnN { VV } -\cs_new_protected:Npn \__color_convert:nnnN #1#2#3#4 - { - \tl_set:Nx #4 - { - \cs_if_exist:cTF { __color_convert_ #1 _ #2 :w } - { \use:c { __color_convert_ #1 _ #2 :w } #3 ~ 0 ~ 0 ~ 0 \s__color_stop } - { \use:c { c__color_fallback_ #2 _tl } } - } - } -\cs_generate_variant:Nn \__color_convert:nnnN { nV , nnV } -\cs_new:Npn \__color_convert_gray_rgb:w #1 ~ #2 \s__color_stop - { #1 ~ #1 ~ #1 } -\cs_new:Npn \__color_convert_gray_cmyk:w #1 ~ #2 \s__color_stop - { 0 ~ 0 ~ 0 ~ \fp_eval:n { 1 - #1 } } -\cs_new:Npn \__color_convert_rgb_gray:w #1 ~ #2 ~ #3 ~ #4 \s__color_stop - { \fp_eval:n { 0.3 * #1 + 0.59 * #2 + 0.11 * #3 } } -\cs_new:Npn \__color_convert_rgb_cmyk:w #1 ~ #2 ~ #3 ~ #4 \s__color_stop - { - \exp_args:Nf \__color_convert_rgb_cmyk:nnnn - { \fp_eval:n { min ( 1 - #1 , 1 - #2 , 1 - #3 ) } } {#1} {#2} {#3} - } -\cs_new:Npn \__color_convert_rgb_cmyk:nnnn #1#2#3#4 - { - \fp_eval:n { min ( 1 , max ( 0 , 1 - #2 - #1 ) ) } \c_space_tl - \fp_eval:n { min ( 1 , max ( 0 , 1 - #3 - #1 ) ) } \c_space_tl - \fp_eval:n { min ( 1 , max ( 0 , 1 - #4 - #1 ) ) } \c_space_tl - #1 - } -\cs_new:Npn \__color_convert_cmyk_gray:w #1 ~ #2 ~ #3 ~ #4 ~ #5 \s__color_stop - { \fp_eval:n { 1 - min ( 1 , 0.3 * #1 + 0.59 * #2 + 0.11 * #3 + #4 ) } } -\cs_new:Npn \__color_convert_cmyk_rgb:w #1 ~ #2 ~ #3 ~ #4 ~ #5 \s__color_stop - { - \fp_eval:n { 1 - min ( 1 , #1 + #4 ) } \c_space_tl - \fp_eval:n { 1 - min ( 1 , #2 + #4 ) } \c_space_tl - \fp_eval:n { 1 - min ( 1 , #3 + #4 ) } - } -\tl_new:N \l__color_model_tl -\tl_new:N \l__color_value_tl -\tl_new:N \l__color_next_model_tl -\tl_new:N \l__color_next_value_tl -\cs_new_protected:Npx \__color_parse:nN #1#2 - { - \exp_not:N \__color_backend_pickup:N \exp_not:N \l__color_current_tl - \tl_set:Nx \exp_not:c { l__color_named_ . _tl } - { \exp_not:N \__color_model:N \exp_not:N \l__color_current_tl } - \prop_put:NVx \exp_not:c { l__color_named_ . _prop } - \exp_not:c { l__color_named_ . _tl } - { \exp_not:N \__color_values:N \exp_not:N \l__color_current_tl } - \exp_not:N \exp_args:Ne \exp_not:N \__color_parse_aux:nN - { \exp_not:N \tl_to_str:n {#1} } #2 - } -\cs_new_protected:Npn \__color_parse_aux:nN #1#2 - { - \tl_if_exist:cTF { l__color_named_ #1 _prop } - { \__color_parse_set_eq:Nn #2 {#1} } - { \__color_parse:Nw #2#1 ! \s__color_stop } - \__color_check_model:N #2 - } -\cs_new_protected:Npn \__color_parse_set_eq:Nn #1#2 - { - \tl_if_empty:NTF \l_color_fixed_model_tl - { \exp_args:Nv \__color_parse_set_eq:nNn { l__color_named_ #2 _tl } } - { \exp_args:NV \__color_parse_set_eq:nNn \l_color_fixed_model_tl } - #1 {#2} - } -\cs_new_protected:Npn \__color_parse_set_eq:nNn #1#2#3 - { - \prop_get:cnNTF - { l__color_named_ #3 _prop } {#1} - \l__color_value_tl - { \tl_set:Nx #2 { {#1} { \l__color_value_tl } } } - { - \tl_set_eq:Nc \l__color_model_tl { l__color_named_ #3 _tl } - \prop_get:cVN { l__color_named_ #3 _prop } \l__color_model_tl - \l__color_value_tl - \__color_convert:nnN - \l__color_model_tl {#1} \l__color_value_tl - \tl_set:Nx #2 - { - {#1} - { \l__color_value_tl } - } - } - } -\cs_new_protected:Npn \__color_parse:Nw #1#2 ! #3 \s__color_stop - { - \__color_if_defined:nTF {#2} - { - \tl_if_blank:nTF {#3} - { \__color_parse_set_eq:Nn #1 {#2} } - { \__color_parse_loop_init:Nnn #1 {#2} {#3} } - } - { - \__kernel_msg_error:nnn { color } { unknown-color } {#2} - \tl_set:Nn \l__color_current_tl { { gray } { 0 } } - } - } -\cs_new_protected:Npn \__color_parse_loop_init:Nnn #1#2#3 - { - \group_begin: - \__color_extract:nNN {#2} \l__color_model_tl \l__color_value_tl - \__color_parse_loop:w #3 ! ! ! ! \s__color_stop - \tl_set:Nx \l__color_internal_tl - { { \l__color_model_tl } { \l__color_value_tl } } - \exp_args:NNNV \group_end: - \tl_set:Nn #1 \l__color_internal_tl - } -\cs_new_protected:Npn \__color_parse_loop:w #1 ! #2 ! #3 ! #4 ! #5 \s__color_stop - { - \bool_lazy_or:nnF - { \tl_if_blank_p:n {#1} } - { \int_compare_p:nNn {#1} = { 100 } } - { - \int_compare:nNnTF {#1} = { 0 } - { - \tl_if_blank:nTF {#2} - { \__color_extract:nNN { white } } - { \__color_extract:nNN {#2} } - \l__color_model_tl \l__color_value_tl - } - { - \use:x - { - \__color_parse_loop:nn {#1} - { \tl_if_blank:nTF {#2} { white } {#2} } - } - } - } - \tl_if_blank:nF {#3} - { \__color_parse_loop:w #3 ! #4 ! #5 \s__color_stop } - \__color_parse_end: - } -\cs_new_protected:Npn \__color_parse_loop:nn #1#2 - { - \__color_if_defined:nTF {#2} - { - \__color_extract:nNN {#2} \l__color_next_model_tl \l__color_next_value_tl - \tl_if_eq:NNF \l__color_model_tl \l__color_next_model_tl - { - \str_if_eq:VnTF \l__color_model_tl { gray } - { \__color_parse_gray:n {#2} } - { \__color_parse_std:n {#2} } - } - \tl_set:Nx \l__color_value_tl - { - \__color_parse_mix:NVVn - \l__color_model_tl \l__color_value_tl \l__color_next_value_tl {#1} - } - } - { - \__kernel_msg_error:nnn { color } { unknown-color } {#2} - \__color_extract:nNN { black } \l__color_model_tl \l__color_value_tl - \__color_parse_break:w - } - } -\cs_new_protected:Npn \__color_parse_gray:n #1 - { - \tl_set_eq:NN \l__color_model_tl \l__color_next_model_tl - \tl_set:Nn \l__color_next_model_tl { gray } - \exp_args:NnV \__color_convert:nnN { gray } \l__color_model_tl - \l__color_value_tl - \prop_get:cVN { l__color_named_ #1 _prop } \l__color_model_tl - \l__color_next_value_tl - } -\cs_new_protected:Npn \__color_parse_std:n #1 - { - \prop_get:cVNF { l__color_named_ #1 _prop } - \l__color_model_tl - \l__color_next_value_tl - { - \__color_convert:VVN - \l__color_next_model_tl - \l__color_model_tl - \l__color_next_value_tl - } - } -\cs_new_protected:Npn \__color_parse_break:w #1 \__color_parse_end: { } -\cs_new_protected:Npn \__color_parse_end: { } -\cs_new:Npn \__color_parse_mix:Nnnn #1#2#3#4 - { - \exp_args:Nf \__color_parse_mix:nNnn - { \fp_eval:n { #4 / 100 } } - #1 {#2} {#3} - } -\cs_generate_variant:Nn \__color_parse_mix:Nnnn { NVV } -\cs_new:Npn \__color_parse_mix:nNnn #1#2#3#4 - { - \use:c { __color_parse_mix_ #2 :nw } {#1} - #3 \s__color_mark #4 \s__color_stop - } -\cs_new:Npn \__color_parse_mix_gray:nw #1#2 \s__color_mark #3 \s__color_stop - { \fp_eval:n { #2 * #1 + #3 * ( 1 - #1 ) } } -\cs_new:Npn \__color_parse_mix_rgb:nw - #1#2 ~ #3 ~ #4 \s__color_mark #5 ~ #6 ~ #7 \s__color_stop - { - \fp_eval:n { #2 * #1 + #5 * ( 1 - #1 ) } \c_space_tl - \fp_eval:n { #3 * #1 + #6 * ( 1 - #1 ) } \c_space_tl - \fp_eval:n { #4 * #1 + #7 * ( 1 - #1 ) } - } -\cs_new:Npn \__color_parse_mix_cmyk:nw - #1#2 ~ #3 ~ #4 ~ #5 \s__color_mark #6 ~ #7 ~ #8 ~ #9 \s__color_stop - { - \fp_eval:n { #2 * #1 + #6 * ( 1 - #1 ) } \c_space_tl - \fp_eval:n { #3 * #1 + #7 * ( 1 - #1 ) } \c_space_tl - \fp_eval:n { #4 * #1 + #8 * ( 1 - #1 ) } \c_space_tl - \fp_eval:n { #5 * #1 + #9 * ( 1 - #1 ) } - } -\cs_new:Npn \__color_parse_model_gray:w #1 , #2 \s__color_stop - { { gray } { \__color_parse_number:n {#1} } } -\cs_new:Npn \__color_parse_model_rgb:w #1 , #2 , #3 , #4 \s__color_stop - { - { rgb } - { - \__color_parse_number:n {#1} ~ - \__color_parse_number:n {#2} ~ - \__color_parse_number:n {#3} - } - } -\cs_new:Npn \__color_parse_model_cmyk:w #1 , #2 , #3 , #4 , #5 \s__color_stop - { - { cmyk } - { - \__color_parse_number:n {#1} ~ - \__color_parse_number:n {#2} ~ - \__color_parse_number:n {#3} ~ - \__color_parse_number:n {#4} - } - } -\cs_new:Npn \__color_parse_number:n #1 - { \__color_parse_number:w #1 . 0 . \s__color_stop } -\cs_new:Npn \__color_parse_number:w #1 . #2 . #3 \s__color_stop - { \tl_if_blank:nTF {#1} { 0 } {#1} . #2 } -\cs_new:Npn \__color_parse_model_Gray:w #1 , #2 \s__color_stop - { { gray } { \fp_eval:n { #1 / 15 } } } -\cs_new:Npn \__color_parse_model_hsb:w #1 , #2 , #3 , #4 \s__color_stop - { \__color_parse_model_hsb:nnn {#1} {#2} {#3} } -\cs_new:Npn \__color_parse_model_Hsb:w #1 , #2 , #3 , #4 \s__color_stop - { - \exp_args:Ne \__color_parse_model_hsb:nnn { \fp_eval:n { #1 / 360 } } - {#2} {#3} - } -\cs_new:Npn \__color_parse_model_hsb:nnn #1#2#3 - { - { rgb } - { - \exp_args:Ne \__color_parse_model_hsb_aux:nnn - { \fp_eval:n { 6 * #1 } } {#2} {#3} - } - } -\cs_new:Npn \__color_parse_model_hsb_aux:nnn #1#2#3 - { - \exp_args:Nee \__color_parse_model_hsb_aux:nnnn - { \fp_eval:n { floor(#1) } } { \fp_eval:n { #1 - floor(#1) } } - {#2} {#3} - } -\cs_new:Npn \__color_parse_model_hsb_aux:nnnn #1#2#3#4 - { - \use:e - { - \exp_not:N \__color_parse_model_hsb_aux:nnnnn - { \__color_parse_number:n {#4} } - { \fp_eval:n { round(#4 * (1 - #3) ,5) } } - { \fp_eval:n { round(#4 * ( 1 - #3 * #2 ) ,5) } } - { \fp_eval:n { round(#4 * ( 1 - #3 * (1 - #2) ) ,5) } } - {#1} - } - } -\cs_new:Npn \__color_parse_model_hsb_aux:nnnnn #1#2#3#4#5 - { \use:c { __color_parse_model_hsb_ #5 :nnnn } {#1} {#2} {#3} {#4} } -\cs_new:cpn { __color_parse_model_hsb_0:nnnn } #1#2#3#4 { #1 ~ #4 ~ #2 } -\cs_new:cpn { __color_parse_model_hsb_1:nnnn } #1#2#3#4 { #3 ~ #1 ~ #2 } -\cs_new:cpn { __color_parse_model_hsb_2:nnnn } #1#2#3#4 { #2 ~ #1 ~ #4 } -\cs_new:cpn { __color_parse_model_hsb_3:nnnn } #1#2#3#4 { #2 ~ #3 ~ #1 } -\cs_new:cpn { __color_parse_model_hsb_4:nnnn } #1#2#3#4 { #4 ~ #2 ~ #1 } -\cs_new:cpn { __color_parse_model_hsb_5:nnnn } #1#2#3#4 { #1 ~ #2 ~ #3 } -\cs_new:cpn { __color_parse_model_hsb_6:nnnn } #1#2#3#4 { #1 ~ #2 ~ #2 } -\cs_new:Npn \__color_parse_model_HSB:w #1 , #2 , #3 , #4 \s__color_stop - { - \exp_args:Neee \__color_parse_model_hsb:nnn - { \fp_eval:n {#1 / 240} } - { \fp_eval:n {#2 / 240} } - { \fp_eval:n {#3 / 240} } - } -\cs_new:Npn \__color_parse_model_HTML:w #1 , #2 \s__color_stop - { \__color_parse_model_HTML_aux:w #1 0 0 0 0 0 0 \s__color_stop } -\cs_new:Npn \__color_parse_model_HTML_aux:w #1#2#3#4#5#6#7 \s__color_stop - { - { rgb } - { - \fp_eval:n { round(\int_from_hex:n {#1#2} / 255,5) } ~ - \fp_eval:n { round(\int_from_hex:n {#3#4} / 255,5) } ~ - \fp_eval:n { round(\int_from_hex:n {#5#6} / 255,5) } - } - } -\cs_new:Npn \__color_parse_model_RGB:w #1 , #2 , #3 , #4 \s__color_stop - { - { rgb } - { - \fp_eval:n { round(#1 / 255,5) } ~ - \fp_eval:n { round(#2 / 255,5) } ~ - \fp_eval:n { round(#3 / 255,5) } - } - } -\cs_new:Npn \__color_parse_model_wave:w #1 , #2 \s__color_stop - { - { rgb } - { - \fp_compare:nNnTF {#1} < { 420 } - { \__color_parse_model_wave_auxi:nn {#1} { 0.3 + 0.7 * (#1 - 380) / 40 } - } - { - \fp_compare:nNnTF {#1} > { 700 } - { \__color_parse_model_wave_auxi:nn {#1} { 0.3 + 0.7 * (#1 - 780) / -80 } } - { \__color_parse_model_wave_auxi:nn {#1} { 1 } } - } - } - } -\cs_new:Npn \__color_parse_model_wave_auxi:nn #1#2 - { - \fp_compare:nNnTF {#1} < { 440 } - { - \__color_parse_model_wave_auxii:nn - { 4 + \__color_parse_model_wave_rho:n { (#1 - 440) / -60 } } - {#2} - } - { - \fp_compare:nNnTF {#1} < { 490 } - { - \__color_parse_model_wave_auxii:nn - { 4 - \__color_parse_model_wave_rho:n { (#1 - 440) / 50 } } - {#2} - } - { - \fp_compare:nNnTF {#1} < { 510 } - { - \__color_parse_model_wave_auxii:nn - { 2 + \__color_parse_model_wave_rho:n { (#1 - 510) / -20 } } - {#2} - } - { - \fp_compare:nNnTF {#1} < { 580 } - { - \__color_parse_model_wave_auxii:nn - { 2 - \__color_parse_model_wave_rho:n { (#1 - 510) / 70 } } - {#2} - } - { - \fp_compare:nNnTF {#1} < { 645 } - { - \__color_parse_model_wave_auxii:nn - { \__color_parse_model_wave_rho:n { (#1 - 645) / -65 } } - {#2} - } - { \__color_parse_model_wave_auxii:nn { 0 } {#2} } - } - } - } - } - } -\cs_new:Npn \__color_parse_model_wave_auxii:nn #1#2 - { - \exp_args:Neee \__color_parse_model_hsb_aux:nnn - { \fp_eval:n {#1} } - { 1 } - { \__color_parse_model_wave_rho:n {#2} } - } -\cs_new:Npn \__color_parse_model_wave_rho:n #1 - { \fp_eval:n { min(1, max(0,#1) ) } } -\tl_new:N \l_color_fixed_model_tl -\cs_new_protected:Npn \__color_check_model:N #1 - { - \tl_if_empty:NF \l_color_fixed_model_tl - { - \exp_after:wN \__color_check_model:nn #1 - \tl_if_eq:NNF \l__color_model_tl \l_color_fixed_model_tl - { - \__color_convert:VVN \l__color_model_tl \l_color_fixed_model_tl - \l__color_value_tl - } - \tl_set:Nx #1 - { { \l_color_fixed_model_tl } { \l__color_value_tl } } - } - } -\cs_new_protected:Npn \__color_check_model:nn #1#2 - { - \tl_set:Nn \l__color_model_tl {#1} - \tl_set:Nn \l__color_value_tl {#2} - } -\cs_new_protected:Npx \__color_select: - { - \tl_set:Nx \exp_not:c { l__color_named_ . _tl } - { \exp_not:N \__color_model:N \exp_not:N \l__color_current_tl } - \prop_clear:N \exp_not:c { l__color_named_ . _prop } - \prop_put:NVx \exp_not:c { l__color_named_ . _prop } - \exp_not:c { l__color_named_ . _tl } - { \exp_not:N \__color_values:N \exp_not:N \l__color_current_tl } - \__color_select:N \exp_not:N \l__color_current_tl - } -\cs_new_protected:Npn \color_select:n #1 - { - \__color_parse:nN {#1} \l__color_current_tl - \__color_select: - } -\cs_new_protected:Npn \color_select:nn #1#2 - { - \__color_select_main:Nw \l__color_current_tl - #1 / / \s__color_mark #2 / / \s__color_stop - \__color_select: - } -\cs_new_protected:Npn \__color_select_main:Nw - #1 #2 / #3 / #4 \s__color_mark #5 / #6 / #7 \s__color_stop - { - \__color_select:nnN {#2} {#5} #1 - \bool_lazy_or:nnF - { \tl_if_empty_p:N \l_color_fixed_model_tl } - { \str_if_eq_p:nV {#2} \l_color_fixed_model_tl } - { \__color_select_loop:Nw #1 #3 / #4 \s__color_mark #6 / #7 \s__color_stop } - } -\cs_new_protected:Npn \__color_select_loop:Nw - #1 #2 / #3 \s__color_mark #4 / #5 \s__color_stop - { - \str_if_eq:nVTF {#2} \l_color_fixed_model_tl - { \__color_select:nnN {#2} {#4} #1 } - { - \tl_if_blank:nTF {#2} - { \exp_after:wN \__color_select_swap:Nnn \exp_after:wN #1 #1 } - { \__color_select_loop:Nw #1 #3 \s__color_mark #5 \s__color_stop } - } - } -\cs_new_protected:Npn \__color_select:nnN #1#2#3 - { - \cs_if_exist:cTF { __color_parse_model_ #1 :w } - { - \tl_set:Nx #3 - { \use:c { __color_parse_model_ #1 :w } #2 , 0 , 0 , 0 , 0 \s__color_stop } - } - { \__kernel_msg_error:nnn { color } { unknown-model } {#1} } - } -\cs_new_protected:Npn \__color_select_swap:Nnn #1#2#3 - { - \__color_convert:nVnN {#2} \l_color_fixed_model_tl {#3} \l__color_value_tl - \tl_set:Nx #1 - { { \l_color_fixed_model_tl } { \l__color_value_tl } } - } -\cs_new_protected:Npn \color_fill:n #1 - { - \__color_parse:nN {#1} \l__color_current_tl - \exp_after:wN \__color_draw:nnn \l__color_current_tl { fill } - } -\cs_new_protected:Npn \color_stroke:n #1 - { - \__color_parse:nN {#1} \l__color_current_tl - \exp_after:wN \__color_draw:nnn \l__color_current_tl { stroke } - } -\cs_new_protected:Npn \color_fill:nn #1#2 - { - \__color_select_main:Nw \l__color_current_tl - #1 / / \s__color_mark #2 / / \s__color_stop - \exp_after:wN \__color_draw:nnn \l__color_current_tl { fill } - } -\cs_new_protected:Npn \color_stroke:nn #1#2 - { - \__color_select_main:Nw \l__color_current_tl - #1 / / \s__color_mark #2 / / \s__color_stop - \exp_after:wN \__color_draw:nnn \l__color_current_tl { stroke } - } -\cs_new_protected:Npn \__color_draw:nnn #1#2#3 - { \use:c { __color_backend_ #3 _ #1 :n } {#2} } -\tl_new:N \l__color_named_tl -\cs_new_protected:Npn \color_set:nn #1#2 - { - \exp_args:NV \__color_set:nnn - \l_color_fixed_model_tl {#1} {#2} - } -\cs_new_protected:Npn \__color_set:nnn #1#2#3 - { - \tl_clear:N \l_color_fixed_model_tl - \__color_set:nn {#2} {#3} - \tl_set:Nn \l_color_fixed_model_tl {#1} - } -\cs_new_protected:Npn \__color_set:nn #1#2 - { - \str_if_eq:nnF {#1} { . } - { - \__color_parse:nN {#2} \l__color_named_tl - \tl_clear_new:c { l__color_named_ #1 _tl } - \tl_set:cx { l__color_named_ #1 _tl } - { \__color_model:N \l__color_named_tl } - \prop_clear_new:c { l__color_named_ #1 _prop } - \prop_put:cvx { l__color_named_ #1 _prop } { l__color_named_ #1 _tl } - { \__color_values:N \l__color_named_tl } - \__color_set:nnw {#1} {#2} #2 ! \s__color_stop - } - } -\cs_new_protected:Npn \__color_set:nnw #1#2#3 ! #4 \s__color_stop - { - \clist_map_inline:nn { cmyk , gray , rgb } - { - \prop_get:cnNT { l__color_named_ #3 _prop } {##1} \l__color_internal_tl - { - \prop_if_in:cnF { l__color_named_ #1 _prop } {##1} - { - \group_begin: - \tl_set:cn { l__color_named_ #3 _tl } {##1} - \__color_parse:nN {#2} \l__color_internal_tl - \exp_args:NNNV \group_end: - \tl_set:Nn \l__color_internal_tl \l__color_internal_tl - \prop_put:cxx { l__color_named_ #1 _prop } - { \__color_model:N \l__color_internal_tl } - { \__color_values:N \l__color_internal_tl } - } - } - } - } -\cs_new_protected:Npx \color_set:nnn #1#2#3 - { - \exp_not:N \str_if_eq:nnF {#1} { . } - { - \tl_clear_new:c { l__color_named_ #1 _tl } - \prop_clear_new:c { l__color_named_ #1 _prop } - \exp_not:N \__color_set_colon:nnw {#1} {#3} - #2 \c_colon_str \c_colon_str \exp_not:N \s__color_stop - } - } -\use:x - { - \cs_new_protected:Npn \exp_not:N \__color_set_colon:nnw - ##1##2 ##3 \c_colon_str ##4 \c_colon_str - ##5 \exp_not:N \s__color_stop - } - { - \tl_if_blank:nTF {#4} - { \__color_set_loop:nw {#1} #3 } - { \__color_set_loop:nw {#1} #4 } - / / \s__color_mark #2 / / \s__color_stop - } -\cs_new_protected:Npn \__color_set_loop:nw - #1#2 / #3 \s__color_mark #4 / #5 \s__color_stop - { - \tl_if_blank:nF {#2} - { - \__color_select:nnN {#2} {#4} \l__color_named_tl - \tl_set:Nx \l__color_internal_tl { \__color_model:N \l__color_named_tl } - \tl_if_empty:cT { l__color_named_ #1 _tl } - { \tl_set_eq:cN { l__color_named_ #1 _tl } \l__color_internal_tl } - \prop_put:cVx { l__color_named_ #1 _prop } \l__color_internal_tl - { \__color_values:N \l__color_named_tl } - \__color_set_loop:nw {#1} #3 \s__color_mark #5 \s__color_stop - } - } -\cs_new_protected:Npn \color_set_eq:nn #1#2 - { - \__color_if_defined:nTF {#2} - { - \tl_clear_new:c { l__color_named_ #1 _tl } - \prop_clear_new:c { l__color_named_ #1 _prop } - \str_if_eq:nnTF {#2} { . } - { - \tl_set:cx { l__color_named_ #1 _tl } - { \__color_model:N \l__color_current_tl } - \prop_put:cvx { l__color_named_ #1 _prop } { l__color_named_ #1 _tl } - { \__color_values:N \l__color_current_tl } - } - { - \tl_set_eq:cc { l__color_named_ #1 _tl } { l__color_named_ #2 _tl } - \prop_set_eq:cc { l__color_named_ #1 _prop } { l__color_named_ #2 _prop } - } - } - { - \__kernel_msg_error:nnn { color } { unknown-color } {#2} - } - } -\color_set:nnn { black } { gray } { 0 } -\color_set:nnn { white } { gray } { 1 } -\color_set:nnn { cyan } { cmyk } { 1 , 0 , 0 , 0 } -\color_set:nnn { magenta } { cmyk } { 0 , 1 , 0 , 0 } -\color_set:nnn { yellow } { cmyk } { 0 , 0 , 1 , 0 } -\color_set:nnn { red } { rgb } { 1 , 0 , 0 } -\color_set:nnn { green } { rgb } { 0 , 1 , 0 } -\color_set:nnn { blue } { rgb } { 0 , 0 , 1 } -\prop_new:c { l__color_named_._prop } -\tl_new:c { l__color_named_._tl } -\tl_set:cx { l__color_named_._tl } { \__color_model:N \l__color_current_tl } -\cs_new_protected:Npn \color_export:nnN #1#2#3 - { - \group_begin: - \tl_if_exist:cT { c__color_export_ #2 _tl } - { \tl_set_eq:Nc \l_color_fixed_model_tl { c__color_export_ #2 _tl } } - \__color_parse:nN {#1} #3 - \__color_export:nN {#2} #3 - \exp_args:NNNV \group_end: - \tl_set:Nn #3 #3 - } -\cs_new_protected:Npn \color_export:nnnN #1#2#3#4 - { - \__color_select_main:Nw #4 - #1 / / \s__color_mark #2 / / \s__color_stop - \__color_export:nN {#3} #4 - } -\cs_new_protected:Npn \__color_export:nN #1#2 - { \exp_after:wN \__color_export:nnnN #2 {#1} #2 } -\cs_new:Npn \__color_export:nnnN #1#2#3#4 - { - \cs_if_exist_use:cF { __color_export_format_ #3 :nnN } - { - \__kernel_msg_error:nnn { color } { unknown-export-format } {#3} - \use_none:nnn - } - {#1} {#2} #4 - } -\cs_new_protected:Npn \__color_export_format_backend:nnN #1#2#3 - { \tl_set:Nn #3 { {#1} {#2} } } -\cs_new_protected:Npn \__color_export:nnnNN #1#2#3#4#5 - { - \str_if_eq:nnTF {#2} {#1} - { #5 #4 #3 \s__color_stop } - { - \__color_convert:nnnN {#2} {#1} {#3} #4 - \exp_after:wN #5 \exp_after:wN #4 - #4 \s__color_stop - } - } -\tl_const:Nn \c__color_export_HTML_tl { rgb } -\tl_const:cn { c__color_export_space-sep-cmyk_tl } { cmyk } -\tl_const:cn { c__color_export_space-sep-rgb_tl } { rgb } -\cs_new_protected:cpx { __color_export_format_space-sep-cmyk:nnN } #1#2#3 - { - \exp_not:N \__color_export:nnnNN { cmyk } {#1} {#2} #3 - \exp_not:c { __color_export_space-sep-cmyk:Nw } - } -\cs_new_protected:cpn { __color_export_space-sep-cmyk:Nw } #1#2 \s__color_stop - { \tl_set:Nx #1 {#2} } -\cs_new_protected:Npn \__color_export_format_HTML:nnN #1#2#3 - { \__color_export:nnnNN { rgb } {#1} {#2}#3 \__color_export_HTML:Nw } -\cs_new_protected:cpx { __color_export_format_space-sep-rgb:nnN } #1#2#3 - { - \exp_not:N \__color_export:nnnNN { rgb } {#1} {#2} #3 - \exp_not:c { __color_export_space-sep-rgb:Nw } - } -\cs_new_protected:Npn \__color_export_HTML:Nw #1#2 ~ #3 ~ #4 \s__color_stop - { - \tl_set:Nx #1 - { - \__color_export_HTML:n {#2} - \__color_export_HTML:n {#3} - \__color_export_HTML:n {#4} - } - } -\cs_new:Npn \__color_export_HTML:n #1 - { - \fp_compare:nNnTF {#1} = { 0 } - { 00 } - { \int_to_Hex:n { \fp_to_int:n { #1 * 255 } } } - } -\cs_new_protected:cpn { __color_export_space-sep-rgb:Nw } #1#2 \s__color_stop - { \tl_set:Nx #1 {#2} } -\prop_new:N \l__color_internal_prop -\int_new:N \g__color_model_int -\tl_const:Nn \c__color_fallback_cmyk_tl { 0 ~ 0 ~ 0 ~ 1 } -\tl_const:Nn \c__color_fallback_gray_tl { 1 } -\tl_const:Nn \c__color_fallback_rgb_tl { 1 ~ 1 ~ 1 } -\prop_new:N \g__color_colorants_prop -\prop_gput:Nnn \g__color_colorants_prop { black } { Black } -\prop_gput:Nnn \g__color_colorants_prop { blue } { Blue } -\prop_gput:Nnn \g__color_colorants_prop { cyan } { Cyan } -\prop_gput:Nnn \g__color_colorants_prop { green } { Green } -\prop_gput:Nnn \g__color_colorants_prop { magenta } { Magenta } -\prop_gput:Nnn \g__color_colorants_prop { none } { None } -\prop_gput:Nnn \g__color_colorants_prop { red } { Red } -\prop_gput:Nnn \g__color_colorants_prop { yellow } { Yellow } -\tl_const:Nn \c__color_model_whitepoint_CIELAB_a_tl { 1.0985 ~ 1 ~ 0.3558 } -\tl_const:Nn \c__color_model_whitepoint_CIELAB_b_tl { 0.9807 ~ 1 ~ 1.1822 } -\tl_const:Nn \c__color_model_whitepoint_CIELAB_e_tl { 1 ~ 1 ~ 1 } -\tl_const:cn { c__color_model_whitepoint_CIELAB_d50_tl } { 0.9642 ~ 1 ~ 0.8251 } -\tl_const:cn { c__color_model_whitepoint_CIELAB_d55_tl } { 0.9568 ~ 1 ~ 0.9214 } -\tl_const:cn { c__color_model_whitepoint_CIELAB_d65_tl } { 0.9504 ~ 1 ~ 1.0888 } -\tl_const:cn { c__color_model_whitepoint_CIELAB_d75_tl } { 0.9497 ~ 1 ~ 1.2261 } -\tl_const:Nn \c__color_model_range_CIELAB_tl { 0 ~ 100 ~ -128 ~ 127 ~ -128 ~ 127 } -\prop_new:N \g__color_alternative_model_prop -\clist_map_inline:nn { cyan , magenta , yellow , black } - { \prop_gput:Nnn \g__color_alternative_model_prop {#1} { cmyk } } -\clist_map_inline:nn { red , green , blue } - { \prop_gput:Nnn \g__color_alternative_model_prop {#1} { rgb } } -\prop_new:N \g__color_alternative_values_prop -\prop_gput:Nnn \g__color_alternative_values_prop { cyan } { 1 , 0 , 0 , 0 } -\prop_gput:Nnn \g__color_alternative_values_prop { magenta } { 0 , 1 , 0 , 0 } -\prop_gput:Nnn \g__color_alternative_values_prop { yellow } { 0 , 0 , 1 , 0 } -\prop_gput:Nnn \g__color_alternative_values_prop { black } { 0 , 0 , 0 , 1 } -\prop_gput:Nnn \g__color_alternative_values_prop { red } { 1 , 0 , 0 } -\prop_gput:Nnn \g__color_alternative_values_prop { green } { 0 , 1 , 0 } -\prop_gput:Nnn \g__color_alternative_values_prop { blue } { 0 , 0 , 1 } -\cs_new_protected:Npn \color_model_new:nnn #1#2#3 - { - \exp_args:Nee \__color_model_new:nnn - { \tl_to_str:n {#1} } - { \str_foldcase:n {#2} } {#3} - } -\cs_new_protected:Npn \__color_model_new:nnn #1#2#3 - { - \cs_if_exist:cTF { __color_parse_model_ #1 :w } - { - \__kernel_msg_error:nnn { color } { model-already-defined } {#1} - } - { - \cs_if_exist:cTF { __color_model_ #2 :n } - { - \prop_set_from_keyval:Nn \l__color_internal_prop {#3} - \use:c { __color_model_ #2 :n } {#1} - } - { - \__kernel_msg_error:nnn { color } { unknown-model-type } {#2} - } - } - } -\cs_new_protected:Npn \__color_model_separation:n #1 - { - \prop_get:NnNTF \l__color_internal_prop { name } - \l__color_internal_tl - { - \exp_args:NV \__color_model_separation:nn - \l__color_internal_tl {#1} - } - { - \__kernel_msg_error:nnn { color } - { separation-requires-name } {#1} - } - } -\cs_new_protected:Npn \__color_model_separation:nn #1#2 - { - \prop_get:NnNTF \l__color_internal_prop { alternative-model } - \l__color_internal_tl - { - \exp_args:NV \__color_model_separation:nnn - \l__color_internal_tl {#2} {#1} - } - { - \__kernel_msg_error:nnn { color } - { separation-alternative-model } {#2} - } - } -\cs_new_protected:Npn \__color_model_separation:nnn #1#2#3 - { - \cs_if_exist:cTF { __color_model_separation_ #1 :nnnnnn } - { - \prop_get:NnNTF \l__color_internal_prop { alternative-values } - \l__color_internal_tl - { - \exp_after:wN \__color_model_separation:w \l__color_internal_tl - , 0 , 0 , 0 , 0 \s__color_stop {#2} {#3} {#1} - } - { - \__kernel_msg_error:nnn { color } - { separation-alternative-values } {#2} - } - } - { - \__kernel_msg_error:nnn { color } - { unknown-alternative-model } {#1} - } - } -\cs_new_protected:Npn \__color_model_separation:w - #1 , #2 , #3 , #4 , #5 \s__color_stop #6#7#8 - { - \int_gincr:N \g__color_model_int - \tl_const:cn { c__color_fallback_ #6 _tl } { 1 } - \cs_new_eq:cN { __color_parse_mix_ #6 :nw } \__color_parse_mix_gray:nw - \cs_new:cpn { __color_parse_model_ #6 :w } ##1 , ##2 \s__color_stop - { {#6} { \__color_parse_number:n {##1} } } - \clist_map_inline:nn { fill , stroke , select } - { - \cs_new_protected:cpx { __color_backend_ ##1 _ #6 :n } ####1 - { - \exp_not:c { __color_backend_ ##1 _ separation:nn } - { color \int_use:N \g__color_model_int } {####1} - } - } - \use:c { __color_model_separation_ #8 :nnnnnn } - {#6} {#7} {#1} {#2} {#3} {#4} - \prop_gput:Nnn \g__color_alternative_model_prop {#6} {#8} - \prop_gput:Nnx \g__color_colorants_prop {#6} - { \str_convert_pdfname:n {#7} } - \cs_new_protected:cpx { __color_model_ #6 _white: } - { - \prop_put:Nnn \exp_not:N \l__color_named_white_prop {#6} { 0 } - \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0 - { \group_insert_after:N \exp_not:c { __color_model_ #6 _ white: } } - } - \use:c { __color_model_ #6 _white: } - } -\cs_new_protected:Npn \__color_model_separation_cmyk:nnnnnn #1#2#3#4#5#6 - { - \cs_new:cpn { __color_convert_ #1 _cmyk:w } ##1 ~ ##2 \s__color_stop - { - \fp_eval:n {##1 * #3} ~ - \fp_eval:n {##1 * #4} ~ - \fp_eval:n {##1 * #5} ~ - \fp_eval:n {##1 * #6} - } - \__color_model_convert:nnn {#1} { cmyk } { rgb } - \__color_model_convert:nnn {#1} { cmyk } { gray } - \prop_gput:Nnn \g__color_alternative_values_prop {#1} { #3 , #4 , #5 , #6 } - \__color_backend_separation_init:nnnnn {#2} { /DeviceCMYK } { } - { 0 ~ 0 ~ 0 ~ 0 } { #3 ~ #4 ~ #5 ~ #6 } - } -\cs_new_protected:Npn \__color_model_separation_rgb:nnnnnn #1#2#3#4#5#6 - { - \cs_new:cpn { __color_convert_ #1 _rgb:w } ##1 ~ ##2 \s__color_stop - { - \fp_eval:n {##1 * #3} ~ - \fp_eval:n {##1 * #4} ~ - \fp_eval:n {##1 * #5} - } - \__color_model_convert:nnn {#1} { rgb } { cmyk } - \__color_model_convert:nnn {#1} { rgb } { gray } - \prop_gput:Nnn \g__color_alternative_values_prop {#1} { #3 , #4 , #5 } - \__color_backend_separation_init:nnnnn {#2} { /DeviceRGB } { } - { 0 ~ 0 ~ 0 } { #3 ~ #4 ~ #5 } - } -\cs_new_protected:Npn \__color_model_separation_gray:nnnnnn #1#2#3#4#5#6 - { - \cs_new:cpn { __color_convert_ #1 _cmyk:w } ##1 ~ ##2 \s__color_stop - { - \fp_eval:n {##1 * #3} ~ - \fp_eval:n {##1 * #3} ~ - \fp_eval:n {##1 * #3} ~ - \fp_eval:n {##1 * #3} - } - \cs_new:cpn { __color_convert_ #1 _gray:w } ##1 ~ ##2 \s__color_stop - { \fp_eval:n {##1 * #3} } - \cs_new:cpn { __color_convert_ #1 _rgb:w } ##1 ~ ##2 \s__color_stop - { - \fp_eval:n {##1 * #3} ~ - \fp_eval:n {##1 * #3} ~ - \fp_eval:n {##1 * #3} - } - \prop_gput:Nnn \g__color_alternative_values_prop {#1} {#3} - \__color_backend_separation_init:nnnnn {#2} { /DeviceGray } { } { 0 } {#3} - } -\cs_new_protected:Npn \__color_model_convert:nnn #1#2#3 - { - \cs_new:cpx { __color_convert_ #1 _ #3 :w } ##1 ~ ##2 \s__color_stop - { - \exp_not:N \exp_args:NNe \exp_not:N \use:nn - \exp_not:c { __color_convert_ #2 _ #3 :w } - { \exp_not:c { __color_convert_ #1 _ #2 :w } ##1 ~ ##2 \s__color_stop } - \c_space_tl \exp_not:N \s__color_stop - } - } -\cs_new_protected:Npn \__color_model_separation_CIELAB:nnnnnn #1#2#3#4#5#6 - { - \prop_get:NnNF \l__color_internal_prop { illuminant } - \l__color_internal_tl - { - \__kernel_msg_error:nnn { color } - { CIELAB-requires-illuminant } {#1} - \tl_set:Nn \l__color_internal_tl { d50 } - } - \exp_args:NV \__color_model_separation_CIELAB:nnnnnnn - \l__color_internal_tl {#1} {#2} {#3} {#4} {#5} {#6} - } -\cs_new_protected:Npn \__color_model_separation_CIELAB:nnnnnnn #1#2#3#4#5#6#7 - { - \tl_if_exist:cTF { c__color_model_whitepoint_CIELAB_ #1 _tl } - { - \__color_backend_separation_init_CIELAB:nnn {#1} {#3} { #4 ~ #5 ~ #6 } - \cs_new:cpn { __color_convert_ #2 _cmyk:w } ##1 ~ ##2 \s__color_stop - { 0 ~ 0 ~ 0 ~ 1 } - \cs_new:cpn { __color_convert_ #2 _rgb:w } ##1 ~ ##2 \s__color_stop - { 1 ~ 1 ~ 1 } - \cs_new:cpn { __color_convert_ #2 _gray:w } ##1 ~ ##2 \s__color_stop - { 1 } - } - { - \__kernel_msg_error:nnn { color } - { unknown-CIELAB-illuminant } {#1} - } - } -\cs_new_protected:Npn \__color_model_devicen:n #1 - { - \prop_get:NnNTF \l__color_internal_prop { names } - \l__color_internal_tl - { - \exp_args:NV \__color_model_devicen:nn - \l__color_internal_tl {#1} - } - { - \__kernel_msg_error:nnn { color } - { DeviceN-requires-names } {#1} - } - } -\cs_new_protected:Npn \__color_model_devicen:nn #1#2 - { - \tl_clear:N \l__color_model_tl - \clist_map_inline:nn {#1} - { - \prop_get:NnNTF \g__color_alternative_model_prop {##1} - \l__color_internal_tl - { - \tl_if_empty:NTF \l__color_model_tl - { \tl_set_eq:NN \l__color_model_tl \l__color_internal_tl } - { - \str_if_eq:VVF \l__color_model_tl \l__color_internal_tl - { - \__kernel_msg_error:nnn { color } - { DeviceN-inconsistent-alternative } - {#2} - \clist_map_break:n { \use_none:nnnn } - } - } - } - { - \str_if_eq:nnF {##1} { none } - { - \__kernel_msg_error:nnn { color } - { DeviceN-no-alternative } - {#2} - } - } - } - \tl_if_empty:NTF \l__color_model_tl - { - \__kernel_msg_error:nnn { color } - { DeviceN-no-alternative } {#2} - } - { \exp_args:NV \__color_model_devicen:nnn \l__color_model_tl {#1} {#2} } - } -\cs_new_protected:Npn \__color_model_devicen:nnn #1#2#3 - { - \exp_args:Nx \__color_model_devicen:nnnn - { \clist_count:n {#2} } {#1} {#2} {#3} - } -\cs_new_protected:Npn \__color_model_devicen:nnnn #1#2#3#4 - { - \int_gincr:N \g__color_model_int - \tl_const:cx { c__color_fallback_ #4 _tl } - { \prg_replicate:nn {#1} { 1 ~ } } - \cs_if_exist_use:cF { __color_model_devicen_parse_ #1 :nn } - { \__color_model_devicen_parse_generic:nn } - {#4} {#1} - \clist_map_inline:nn { fill , stroke , select } - { - \cs_new_protected:cpx { __color_backend_ ##1 _ #4 :n } ####1 - { - \exp_not:c { __color_backend_ ##1 _ devicen:nn } - { color \int_use:N \g__color_model_int } {####1} - } - } - \cs_new_protected:cpx { __color_model_ #4 _white: } - { - \prop_put:Nnn \exp_not:N \l__color_named_white_prop {#4} - { \prg_replicate:nn {#1} { 0 ~ } } - \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0 - { \group_insert_after:N \exp_not:c { __color_model_ #4 _ white: } } - } - \use:c { __color_model_ #4 _white: } - \__color_model_devicen_init:nnn {#1} {#2} {#3} - \__color_model_devicen_convert:nnn {#4} {#2} {#3} - } -\cs_new_protected:cpn { __color_model_devicen_parse_1:nn } #1#2 - { - \cs_new:cpn { __color_parse_model_ #1 :w } ##1 , ##2 \s__color_stop - { {#1} { \__color_parse_number:n {##1} } } - \cs_new_eq:cN { __color_parse_mix_ #1 :nw } \__color_parse_mix_gray:nw - } -\cs_new_protected:cpn { __color_model_devicen_parse_2:nn } #1#2 - { - \cs_new:cpn { __color_parse_model_ #1 :w } ##1 , ##2 , ##3 \s__color_stop - { {#1} { \__color_parse_number:n {##1} ~ \__color_parse_number:n {##2} } } - \cs_new:cpn { __color_parse_mix_ #1 :nw } - ##1##2 ~ ##3 \s__color_mark ##4 ~ ##5 \s__color_stop - { - \fp_eval:n { ##2 * ##1 + ##4 * ( 1 - ##1 ) } \c_space_tl - \fp_eval:n { ##3 * ##1 + ##5 * ( 1 - ##1 ) } - } - } -\cs_new_protected:cpn { __color_model_devicen_parse_3:nn } #1#2 - { - \cs_new:cpn { __color_parse_model_ #1 :w } ##1 , ##2 , ##3 , ##4 \s__color_stop - { - {#1} - { - \__color_parse_number:n {##1} ~ - \__color_parse_number:n {##2} ~ - \__color_parse_number:n {##3} - } - } - \cs_new_eq:cN { __color_parse_mix_ #1 :nw } \__color_parse_mix_rgb:nw - } -\cs_new_protected:cpn { __color_model_devicen_parse_4:nn } #1#2 - { - \cs_new:cpn { __color_parse_model_ #1 :w } - ##1 , ##2 , ##3 , ##4 , ##5 \s__color_stop - { - {#1} - { - \__color_parse_number:n {##1} ~ - \__color_parse_number:n {##2} ~ - \__color_parse_number:n {##3} ~ - \__color_parse_number:n {##4} - } - } - \cs_new_eq:cN { __color_parse_mix_ #1 :nw } \__color_parse_mix_cmyk:nw - } -\cs_new_protected:Npn \__color_model_devicen_parse_generic:nn #1#2 - { - \cs_new:cpn { __color_parse_model_ #1 :w } ##1 , ##2 \s__color_stop - { - {#1} - { \__color_model_devicen_parse:nw {#2} ##1 , ##2 , \q_nil , \s__color_stop } - } - \cs_new:cpx { __color_parse_mix_ #1 :nw } - ##1 ##2 \s__color_mark ##3 \s__color_stop - { - \exp_not:N \__color_model_devicen_mix:nw {##1} - ##2 \c_space_tl \exp_not:N \q_nil \c_space_tl \exp_not:N \s__color_mark - ##3 \c_space_tl \exp_not:N \q_nil \c_space_tl \exp_not:N \s__color_stop - } - } -\cs_new:Npn \__color_model_devicen_parse:nw #1#2 , #3 \s__color_stop - { - \int_compare:nNnT {#1} > 0 - { - \quark_if_nil:nTF {#2} - { \prg_replicate:nn {#1} { 0 ~ } } - { - \__color_parse_number:n {#2} - \int_compare:nNnT {#1} > 1 { ~ } - \exp_args:Nf \__color_model_devicen_parse:nw - { \int_eval:n { #1 - 1 } } #3 \s__color_stop - } - } - } -\cs_new:Npn \__color_model_devicen_mix:nw #1#2 ~ #3 \s__color_mark #4 ~ #5 \s__color_stop - { - \fp_eval:n { #2 * #1 + #4 * ( 1 - #1 ) } - \quark_if_nil:oF { \tl_head:w #3 \q_stop } - { - \c_space_tl - \__color_model_devicen_mix:nw {#1} #3 \s__color_mark #5 \s__color_stop - } - } -\cs_new_protected:Npn \__color_model_devicen_init:nnn #1#2#3 - { - \exp_args:Ne \__color_model_devicen_init:nnnn - { - \str_case:nn {#2} - { - { cmyk } { 4 } - { gray } { 1 } - { rgb } { 3 } - } - } - {#1} {#2} {#3} - } -\cs_new_protected:Npn \__color_model_devicen_init:nnnn #1#2#3#4 - { - \tl_set:Nx \l__color_internal_tl - { \prg_replicate:nn {#1} { 1.0 ~ } } - \int_zero:N \l__color_internal_int - \clist_map_inline:nn {#4} - { - \int_incr:N \l__color_internal_int - \prop_get:NnN \g__color_alternative_values_prop {##1} - \l__color_value_tl - \exp_after:wN \__color_model_devicen_transform:w - \l__color_value_tl , 0 , 0 , 0 \s__color_stop {#1} {#2} - } - \tl_put_right:Nx \l__color_internal_tl - { - \prg_replicate:nn {#1} - { neg ~ 1.0 ~ add ~ #1 ~ -1 ~ roll ~ } - \int_eval:n { #2 + 4 } ~ 4 ~ roll - \prg_replicate:nn {#2} { ~ pop } - } - \use:x - { - \__color_backend_devicen_init:nnn - { - \clist_map_function:nN {#4} - \__color_model_devicen_colorant:n - } - { - \str_case:nn {#3} - { - { cmyk } { /DeviceCMYK } - { gray } { /DeviceGray } - { rgb } { /DeviceRGB } - } - } - { \exp_not:V \l__color_internal_tl } - } - } -\cs_new_protected:Npn \__color_model_devicen_transform:w - #1 , #2 , #3 , #4 , #5 \s__color_stop #6#7 - { - \use:c { __color_model_devicen_transform_ #6 :nnnnn } - {#1} {#2} {#3} {#4} {#7} - } -\cs_new_protected:cpn { __color_model_devicen_transform_1:nnnnn } #1#2#3#4#5 - { \__color_model_devicen_transform:nnn {#5} { 1 } {#1} } -\cs_new_protected:cpn { __color_model_devicen_transform_3:nnnnn } #1#2#3#4#5 - { - \clist_map_inline { #1 , #2 , #3 } - { \__color_model_devicen_transform:nnn {#5} { 3 } {##1} } - } -\cs_new_protected:cpn { __color_model_devicen_transform_4:nnnnn } #1#2#3#4#5 - { - \clist_map_inline:nn { #1 , #2 , #3 , #4 } - { \__color_model_devicen_transform:nnn {#5} { 4 } {##1} } - } -\cs_new_protected:Npn \__color_model_devicen_transform:nnn #1#2#3 - { - \tl_put_right:Nx \l__color_internal_tl - { - \fp_compare:nNnF {#3} = \c_zero_fp - { - \int_eval:n { #1 - \l__color_internal_int + #2 } ~ index ~ - #3 ~ neg ~ mul ~ 1.0 ~ add ~ mul ~ - } - #2 ~ -1 ~ roll ~ - } - } -\cs_new:Npn \__color_model_devicen_colorant:n #1 - { - / \prop_item:Nn \g__color_colorants_prop {#1} ~ - } -\cs_new_protected:Npn \__color_model_devicen_convert:nnn #1#2#3 - { - \use:c { __color_model_devicen_convert_ #2 :nn } {#1} {#3} - } -\cs_new_protected:Npn \__color_model_devicen_convert_cmyk:nn #1#2 - { - \__color_model_convert:nnn {#1} { cmyk } { gray } - \__color_model_convert:nnn {#1} { cmyk } { rgb } - \__color_model_devicen_convert:nnnn {#1} { cmyk } { 4 } {#2} - } -\cs_new_protected:Npn \__color_model_devicen_convert_gray:nn #1#2 - { - \__color_model_convert:nnn {#1} { gray } { cmyk } - \__color_model_convert:nnn {#1} { gray } { rgb } - \__color_model_devicen_convert:nnnn {#1} { gray } { 1 } {#2} - } -\cs_new_protected:Npn \__color_model_devicen_convert_rgb:nn #1#2 - { - \__color_model_convert:nnn {#1} { rgb } { cmyk } - \__color_model_convert:nnn {#1} { rgb } { gray } - \__color_model_devicen_convert:nnnn {#1} { rgb } { 3 } {#2} - } -\cs_new_protected:Npn \__color_model_devicen_convert:nnnn #1#2#3#4 - { - \cs_new:cpx { __color_convert_ #1 _ #2 :w } ##1 \s__color_stop - { - \exp_not:c { __color_convert_devicen_ #2 : \prg_replicate:nn {#3} { n } w } - \prg_replicate:nn {#3} { { 1 } } - ##1 \exp_not:N \s__color_mark - \clist_map_function:nN {#4} \__color_model_devicen_convert:n - \exp_not:N \s__color_stop - } - } -\cs_new:Npn \__color_model_devicen_convert:n #1 - { - { - \exp_args:Ne \__color_model_devicen_convert_aux:n - { \prop_item:Nn \g__color_alternative_values_prop {#1} } - } - } -\cs_new:Npn \__color_model_devicen_convert_aux:n #1 - { \__color_model_devicen_convert_aux:w #1 , , , , \s__color_stop } -\cs_new:Npn \__color_model_devicen_convert_aux:w #1 , #2 , #3 , #4 , #5 \s__color_stop - { - {#1} - \tl_if_blank:nF {#2} - { - {#2} - \tl_if_blank:nF {#3} - { - {#3} - \tl_if_blank:nF {#4} { {#4} } - } - } - } -\cs_new:Npn \__color_convert_devicen_cmyk:nnnnw - #1#2#3#4#5 ~ #6 \s__color_mark #7#8 \s__color_stop - { - \__color_convert_devicen_cmyk:nnnnnnnnn {#5} {#1} {#2} {#3} {#4} #7 - #6 \s__color_mark #8 \s__color_stop - } -\cs_new:Npn \__color_convert_devicen_cmyk:nnnnnnnnn #1#2#3#4#5#6#7#8#9 - { - \use:e - { - \exp_not:N \__color_convert_devicen_cmyk_aux:nnnnw - { \fp_eval:n { #2 * (1 - (#1 * #6)) } } - { \fp_eval:n { #3 * (1 - (#1 * #7)) } } - { \fp_eval:n { #4 * (1 - (#1 * #8)) } } - { \fp_eval:n { #5 * (1 - (#1 * #9)) } } - } - } -\cs_new:Npn \__color_convert_devicen_cmyk_aux:nnnnw - #1#2#3#4 #5 \s__color_mark #6 \s__color_stop - { - \tl_if_blank:nTF {#5} - { - \fp_eval:n { 1 - #1 } ~ - \fp_eval:n { 1 - #2 } ~ - \fp_eval:n { 1 - #3 } ~ - \fp_eval:n { 1 - #4 } - } - { - \__color_convert_devicen_cmyk:nnnnw {#1} {#2} {#3} {#4} - #5 \s__color_mark #6 \s__color_stop - } - } -\cs_new:Npn \__color_convert_devicen_gray:nw - #1#2 ~ #3 \s__color_mark #4#5 \s__color_stop - { - \__color_convert_devicen_gray:nnn {#2} {#1} #4 - #3 \s__color_mark #5 \s__color_stop - } -\cs_new:Npn \__color_convert_devicen_gray:nnn #1#2#3 - { - \exp_arsgs:Ne \__color_convert_devicen_gray_aux:nw - { \fp_eval:n { #2 * (1 - (#1 * #3)) } } - } -\cs_new:Npn \__color_convert_devicen_gray_aux:nw - #1 #2 \s__color_mark #3 \s__color_stop - { - \tl_if_blank:nTF {#2} - { \fp_eval:n { 1 - #1 } } - { - \__color_convert_devicen_gray:nw {#1} - #2 \s__color_mark #3 \s__color_stop - } - } -\cs_new:Npn \__color_convert_devicen_rgb:nnnw - #1#2#3#4 ~ #5 \s__color_mark #6#7 \s__color_stop - { - \__color_convert_devicen_cmyk:nnnnnn {#4} {#1} {#2} {#3} #6 - #5 \s__color_mark #7 \s__color_stop - } -\cs_new:Npn \__color_convert_devicen_rgb:nnnnnnn #1#2#3#4#5#6#7 - { - \use:e - { - \exp_not:N \__color_convert_devicen_rgb_aux:nnnw - { \fp_eval:n { #2 * (1 - (#1 * #5)) } } - { \fp_eval:n { #3 * (1 - (#1 * #6)) } } - { \fp_eval:n { #4 * (1 - (#1 * #7)) } } - } - } -\cs_new:Npn \__color_convert_devicen_rgb_aux:nnnw - #1#2#3 #4 \s__color_mark #5 \s__color_stop - { - \tl_if_blank:nTF {#4} - { - \fp_eval:n { 1 - #1 } ~ - \fp_eval:n { 1 - #2 } ~ - \fp_eval:n { 1 - #3 } - } - { - \__color_convert_devicen_rgb:nnnw {#1} {#2} {#3} - #4 \s__color_mark #5 \s__color_stop - } - } -\cs_new_protected:Npn \color_show:n #1 - { - \msg_show:nnxxxx { LaTeX / color } { show } - {#1} - { - \__color_if_defined:nT {#1} - { - \exp_args:Nv \__color_show:n { l__color_named_ #1 _tl } - \prop_map_function:cN - { l__color_named_ #1 _prop } - \msg_show_item_unbraced:nn - } - } - { } - { } - } -\cs_new:Npn \__color_show:n #1 - { - \msg_show_item_unbraced:nn { model } {#1} - } -\__kernel_msg_new:nnnn { color } { CIELAB-requires-illuminant } - { CIELAB~color~space~'#1'~require~an~illuminant. } - { - LaTeX~has~been~asked~to~create~a~separation~color~space~using~ - CIELAB~specifications,~but~no~\\ \\ - \iow_indent:n { illuminant~=~ } - \\ \\ - key~was~given~with~the~correct~information.~LaTeX~will~use~illuminant~ - 'd50'~for~recovery. - } -\__kernel_msg_new:nnnn { color } { conversion-not-available } - { No~model~conversion~available~from~'#1'~to~'#2'. } - { - LaTeX~has~been~asked~to~convert~a~color~from~model~'#1'~ - to~model'#2',~but~there~is~no~method~available~to~do~that. - } -\__kernel_msg_new:nnnn { color } { DeviceN-inconsistent-alternative } - { DeviceN~color~spaces~require~a~single~alternative~space. } - { - LaTeX~has~been~asked~to~create~a~DeviceN~color~space~'#1',~ - but~the~constituent~colors~do~not~have~a~common~alternative~ - color. - } -\__kernel_msg_new:nnnn { color } { DeviceN-no-alternative } - { DeviceN~color~spaces~require~an~alternative~space. } - { - LaTeX~has~been~asked~to~create~a~DeviceN~color~space~'#1',~ - but~the~constituent~colors~do~not~all~have~a~device-based~alternative. - } -\__kernel_msg_new:nnnn { color } { DeviceN-requires-names } - { DeviceN~color~space~'#1'~require~a~list~of~names. } - { - LaTeX~has~been~asked~to~create~a~DeviceN~color~space,~ - but~no~\\ \\ - \iow_indent:n { names~=~ } - \\ \\ - key~was~given~with~the~correct~information. - } -\__kernel_msg_new:nnnn { color } { model-already-defined } - { Color~model~'#1'~already~defined. } - { - LaTeX~was~asked~to~define~a~new~color~model~called~'#1',~but~ - this~color~model~already~exists. - } -\__kernel_msg_new:nnnn { color } { separation-alternative-model } - { Separation~color~space~'#1'~require~an~alternative~model. } - { - LaTeX~has~been~asked~to~create~a~separation~color~space,~ - but~no~\\ \\ - \iow_indent:n { alternative-model~=~ } - \\ \\ - key~was~given~with~the~correct~information. - } -\__kernel_msg_new:nnnn { color } { separation-alternative-values } - { Separation~color~space~'#1'~require~values~for~the~alternative~space. } - { - LaTeX~has~been~asked~to~create~a~separation~color~space,~ - but~no~\\ \\ - \iow_indent:n { alternative-values~=~ } - \\ \\ - key~was~given~with~the~correct~information. - } -\__kernel_msg_new:nnnn { color } { separation-requires-name } - { Separation~color~space~'#1'~require~a~formal~name. } - { - LaTeX~has~been~asked~to~create~a~separation~color~space,~ - but~no~\\ \\ - \iow_indent:n { name~=~ } - \\ \\ - key~was~given~with~the~correct~information. - } -\__kernel_msg_new:nnnn { color } { unknown-color } - { Unknown~color~'#1'. } - { - LaTeX~has~been~asked~to~use~a~color~named~'#1',~ - but~this~has~never~been~defined. - } -\__kernel_msg_new:nnnn { color } { unknown-alternative-model } - { Separation~color~space~'#1'~require~an~valid~alternative~space. } - { - LaTeX~has~been~asked~to~create~a~separation~color~space,~ - but~the~model~given~as\\ \\ - \iow_indent:n { alternative-model~=~ } - \\ \\ - is~unknown. - } -\__kernel_msg_new:nnnn { color } { unknown-export-format } - { Unknown~export~format~'#1'. } - { - LaTeX~has~been~asked~to~export~a~color~in~format~'#1',~ - but~this~has~never~been~defined. - } -\__kernel_msg_new:nnnn { color } { unknown-CIELAB-illuminant } - { Unknown~illuminant~model~'#1'. } - { - LaTeX~has~been~asked~to~use~create~a~color~space~using~CIELAB~ - illuminant~'#1',~but~this~does~not~exist. - } -\__kernel_msg_new:nnnn { color } { unknown-model } - { Unknown~color~model~'#1'. } - { - LaTeX~has~been~asked~to~use~a~color~model~called~'#1',~ - but~this~model~is~not~set~up. - } -\__kernel_msg_new:nnnn { color } { unknown-model-type } - { Unknown~color~model~type~'#1'. } - { - LaTeX~has~been~asked~to~create~a~new~color~model~called~'#1',~ - but~this~type~of~model~was~never~set~up. - } -\__kernel_msg_new:nnn { color } { show } - { - The~color~#1~ - \tl_if_empty:nTF {#2} - { is~undefined. } - { has~the~properties: #2 } - } -%% -%% -%% End of file `l3color.sty'. diff --git a/Master/texmf-dist/tex/latex/l3experimental/l3draw/l3draw.sty b/Master/texmf-dist/tex/latex/l3experimental/l3draw/l3draw.sty index 5b8be0a04c8..a990d35197b 100644 --- a/Master/texmf-dist/tex/latex/l3experimental/l3draw/l3draw.sty +++ b/Master/texmf-dist/tex/latex/l3experimental/l3draw/l3draw.sty @@ -28,9 +28,8 @@ %% %% File: l3draw.dtx \RequirePackage{expl3} -\ProvidesExplPackage{l3draw}{2021-02-06}{} +\ProvidesExplPackage{l3draw}{2021-02-18}{} {L3 Experimental core drawing support} -\RequirePackage { l3color } \scan_new:N \s__draw_mark \scan_new:N \s__draw_stop \quark_new:N \q__draw_recursion_tail diff --git a/Master/texmf-dist/tex/latex/l3experimental/l3graphics/l3graphics.sty b/Master/texmf-dist/tex/latex/l3experimental/l3graphics/l3graphics.sty index 9d8e1512009..01c53319537 100644 --- a/Master/texmf-dist/tex/latex/l3experimental/l3graphics/l3graphics.sty +++ b/Master/texmf-dist/tex/latex/l3experimental/l3graphics/l3graphics.sty @@ -20,7 +20,7 @@ %% %% File: l3graphics.dtx \RequirePackage{expl3} -\ProvidesExplPackage{l3graphics}{2021-02-06}{} +\ProvidesExplPackage{l3graphics}{2021-02-18}{} {L3 Experimental graphics inclusion support} \ior_new:N \l__graphics_tmp_ior \tl_new:N \l__graphics_tmp_tl diff --git a/Master/texmf-dist/tex/latex/l3experimental/l3pdf/l3pdf.sty b/Master/texmf-dist/tex/latex/l3experimental/l3pdf/l3pdf.sty deleted file mode 100644 index 2d34f95aa9a..00000000000 --- a/Master/texmf-dist/tex/latex/l3experimental/l3pdf/l3pdf.sty +++ /dev/null @@ -1,118 +0,0 @@ -%% -%% This is file `l3pdf.sty', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% l3pdf.dtx (with options: `package') -%% -%% Copyright (C) 2019-2021 The LaTeX Project -%% -%% It may be distributed and/or modified under the conditions of -%% the LaTeX Project Public License (LPPL), either version 1.3c of -%% this license or (at your option) any later version. The latest -%% version of this license is in the file: -%% -%% http://www.latex-project.org/lppl.txt -%% -%% This file is part of the "l3pdf bundle" (The Work in LPPL) -%% and all files in that bundle must be distributed together. -%% -%% File: l3pdf.dtx -\RequirePackage{expl3} -\ProvidesExplPackage{l3pdf}{2021-02-06}{} - {L3 Experimental core PDF support} -\scan_new:N \s__pdf_stop -\bool_new:N \g__pdf_init_bool -\cs_if_exist:NT \documentclass - { - \AtBeginDocument - { \bool_gset_true:N \g__pdf_init_bool } - } -\cs_new_protected:Npn \pdf_uncompress: - { - \bool_if:NF \g__pdf_init_bool - { - \__pdf_backend_compresslevel:n { 0 } - \__pdf_backend_compress_objects:n { \c_false_bool } - } - } -\cs_new_protected:Npn \pdf_object_new:nn #1#2 - { \__pdf_backend_object_new:nn {#1} {#2} } -\prg_new_conditional:Npnn \pdf_object_if_exist:n #1 { p , T , F , TF } - { - \int_if_exist:cTF { c__pdf_backend_object_ \tl_to_str:n {#1} _int } - { \prg_return_true: } - { \prg_return_false:} - } -\cs_new_protected:Npn \pdf_object_write:nn #1#2 - { \__pdf_backend_object_write:nn {#1} {#2} } -\cs_generate_variant:Nn \pdf_object_write:nn { nx } -\cs_new:Npn \pdf_object_ref:n #1 { \__pdf_backend_object_ref:n {#1} } -\cs_new_protected:Npn \pdf_object_now:nn #1#2 - { \__pdf_backend_object_now:nn {#1} {#2} } -\cs_generate_variant:Nn \pdf_object_now:nn { nx } -\cs_new:Npn \pdf_object_last: { \__pdf_backend_object_last: } -\prg_new_conditional:Npnn \pdf_version_compare:Nn #1#2 { p , T , F , TF } - { \use:c { __pdf_version_compare_ #1 :w } #2 . . \s__pdf_stop } -\cs_new:cpn { __pdf_version_compare_=:w } #1 . #2 . #3 \s__pdf_stop - { - \bool_lazy_and:nnTF - { \int_compare_p:nNn \__pdf_backend_version_major: = {#1} } - { \int_compare_p:nNn \__pdf_backend_version_minor: = {#2} } - { \prg_return_true: } - { \prg_return_false: } - } -\cs_new:cpn { __pdf_version_compare_<:w } #1 . #2 . #3 \s__pdf_stop - { - \bool_lazy_or:nnTF - { \int_compare_p:nNn \__pdf_backend_version_major: < {#1} } - { - \bool_lazy_and_p:nn - { \int_compare_p:nNn \__pdf_backend_version_major: = {#1} } - { \int_compare_p:nNn \__pdf_backend_version_minor: < {#2} } - } - { \prg_return_true: } - { \prg_return_false: } - } -\cs_new:cpn { __pdf_version_compare_>:w } #1 . #2 . #3 \s__pdf_stop - { - \bool_lazy_or:nnTF - { \int_compare_p:nNn \__pdf_backend_version_major: > {#1} } - { - \bool_lazy_and_p:nn - { \int_compare_p:nNn \__pdf_backend_version_major: = {#1} } - { \int_compare_p:nNn \__pdf_backend_version_minor: > {#2} } - } - { \prg_return_true: } - { \prg_return_false: } - } -\cs_new_protected:Npn \pdf_version_gset:n #1 - { \__pdf_version_gset:w #1 . . \s__pdf_stop } -\cs_new_protected:Npn \pdf_version_min_gset:n #1 - { - \pdf_version_compare:NnT < {#1} - { \__pdf_version_gset:w #1 . . \s__pdf_stop } - } -\cs_new_protected:Npn \__pdf_version_gset:w #1 . #2 . #3\s__pdf_stop - { - \bool_if:NF \g__pdf_init_bool - { - \__pdf_backend_version_major_gset:n {#1} - \__pdf_backend_version_minor_gset:n {#2} - } - } -\cs_new:Npn \pdf_version: - { \__pdf_backend_version_major: . \__pdf_backend_version_minor: } -\cs_new:Npn \pdf_version_major: { \__pdf_backend_version_major: } -\cs_new:Npn \pdf_version_minor: { \__pdf_backend_version_minor: } -\cs_new_protected:Npn \pdf_destination:nn #1 #2 - { \__pdf_backend_destination:nn {#1}{#2} } -\cs_new_protected:Npn \pdf_destination:nnnn #1 #2 #3 #4 - { - \hbox_to_zero:n - { \__pdf_backend_destination:nnnn {#1} {#2} {#3} {#4} } - } -%% -%% -%% End of file `l3pdf.sty'. diff --git a/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str-format.sty b/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str-format.sty index b6bf7d37245..48e81a6f571 100644 --- a/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str-format.sty +++ b/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str-format.sty @@ -20,7 +20,7 @@ %% %% File: l3str-format.dtx \RequirePackage{expl3} -\ProvidesExplPackage{l3str-format}{2021-02-06}{} +\ProvidesExplPackage{l3str-format}{2021-02-18}{} {L3 Experimental string formatting} \cs_generate_variant:Nn \use:nn { nf } \cs_generate_variant:Nn \use:nnn { fnf } diff --git a/Master/texmf-dist/tex/latex/l3experimental/l3sys-shell/l3sys-shell.sty b/Master/texmf-dist/tex/latex/l3experimental/l3sys-shell/l3sys-shell.sty index a898f8c3486..fce658def23 100644 --- a/Master/texmf-dist/tex/latex/l3experimental/l3sys-shell/l3sys-shell.sty +++ b/Master/texmf-dist/tex/latex/l3experimental/l3sys-shell/l3sys-shell.sty @@ -20,7 +20,7 @@ %% %% File: l3sys-shell.dtx \RequirePackage{expl3} -\ProvidesExplPackage{l3sys-shell}{2021-02-06}{} +\ProvidesExplPackage{l3sys-shell}{2021-02-18}{} {L3 Experimental system shell functions} \scan_new:N \s__sys_stop \quark_new:N \q__sys_nil diff --git a/Master/texmf-dist/tex/latex/l3experimental/xcoffins/xcoffins.sty b/Master/texmf-dist/tex/latex/l3experimental/xcoffins/xcoffins.sty index d03ce8a0c48..6b7e5dd3d68 100644 --- a/Master/texmf-dist/tex/latex/l3experimental/xcoffins/xcoffins.sty +++ b/Master/texmf-dist/tex/latex/l3experimental/xcoffins/xcoffins.sty @@ -19,7 +19,7 @@ %% and all files in that bundle must be distributed together. %% %% File: xcoffins.dtx -\ProvidesExplPackage{xcoffins}{2021-02-06}{} +\ProvidesExplPackage{xcoffins}{2021-02-18}{} {L3 Experimental design level coffins} \keys_define:nn { coffin } { diff --git a/Master/texmf-dist/tex/latex/l3experimental/xgalley/l3galley.sty b/Master/texmf-dist/tex/latex/l3experimental/xgalley/l3galley.sty index 00fdfa75051..cb3484818c0 100644 --- a/Master/texmf-dist/tex/latex/l3experimental/xgalley/l3galley.sty +++ b/Master/texmf-dist/tex/latex/l3experimental/xgalley/l3galley.sty @@ -32,7 +32,7 @@ }% \endinput } -\ProvidesExplPackage{l3galley}{2021-02-06}{} +\ProvidesExplPackage{l3galley}{2021-02-18}{} {L3 Experimental galley code} \int_new:N \l__galley_tmp_int \seq_new:N \g__galley_tmpa_seq diff --git a/Master/texmf-dist/tex/latex/l3experimental/xgalley/xgalley.sty b/Master/texmf-dist/tex/latex/l3experimental/xgalley/xgalley.sty index d1f2dd701cb..4fd8c31ac42 100644 --- a/Master/texmf-dist/tex/latex/l3experimental/xgalley/xgalley.sty +++ b/Master/texmf-dist/tex/latex/l3experimental/xgalley/xgalley.sty @@ -19,7 +19,7 @@ %% and all files in that bundle must be distributed together. %% %% File: xgalley.dtx -\ProvidesExplPackage{xgalley}{2021-02-06}{} +\ProvidesExplPackage{xgalley}{2021-02-18}{} {L3 Experimental galley} \RequirePackage{xtemplate,l3galley} \clist_new:N \l__galley_tmpa_clist diff --git a/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex b/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex index 12b32317d6f..52982c3fe50 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex +++ b/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex @@ -45,7 +45,8 @@ %% l3tl-analysis.dtx (with options: `package') %% l3regex.dtx (with options: `package') %% l3box.dtx (with options: `package') -%% l3color-base.dtx (with options: `package') +%% l3color.dtx (with options: `package') +%% l3pdf.dtx (with options: `package') %% l3coffins.dtx (with options: `package') %% l3luatex.dtx (with options: `package,tex') %% l3unicode.dtx (with options: `package') @@ -69,7 +70,7 @@ %% and all files in that bundle must be distributed together. %% %% File: expl3.dtx -\def\ExplFileDate{2021-02-06}% +\def\ExplFileDate{2021-02-18}% \begingroup \def\next{\endgroup}% \expandafter\ifx\csname PackageError\endcsname\relax @@ -21146,6 +21147,17 @@ \prop_gput:Nnn \g__str_alias_prop { utf32le } { utf32 } \prop_gput:Nnn \g__str_alias_prop { utf32be } { utf32 } \prop_gput:Nnn \g__str_alias_prop { hexadecimal } { hex } +\bool_lazy_any:nTF + { + \sys_if_engine_luatex_p: + \sys_if_engine_xetex_p: + } + { + \prop_gput:Nnn \g__str_alias_prop { default } { } + } + { + \prop_gput:Nnn \g__str_alias_prop { default } { utf8 } + } \bool_new:N \g__str_error_bool \flag_new:n { str_byte } \flag_new:n { str_error } @@ -26497,6 +26509,9 @@ missing~right~ \int_compare:nTF { #1 = 1 } { parenthesis } { parentheses } . } +\__kernel_msg_new:nnnn { kernel } { backwards-quantifier } + { Quantifer~"{#1,#2}"~is~backwards. } + { The~values~given~in~a~quantifier~must~be~in~order. } \__kernel_msg_new:nnn { kernel } { show-regex } { >~Compiled~regex~ @@ -27218,7 +27233,7 @@ } } } -%% File: l3color-base.dtx +%% File: l3color.dtx \cs_new_eq:NN \color_group_begin: \group_begin: \cs_new_eq:NN \color_group_end: \group_end: \cs_new_protected:Npn \color_ensure_current: @@ -27233,215 +27248,1742 @@ { \use:c { __color_backend_select_ #1 :n } {#2} } \tl_new:N \l__color_current_tl \tl_set:Nn \l__color_current_tl { { gray } { 0 } } -%% File: l3coffins.dtx -\box_new:N \l__coffin_internal_box -\dim_new:N \l__coffin_internal_dim -\tl_new:N \l__coffin_internal_tl -\prop_const_from_keyval:Nn \c__coffin_corners_prop + +\int_new:N \l__color_internal_int +\tl_new:N \l__color_internal_tl +\scan_new:N \s__color_mark +\prg_new_conditional:Npnn \__color_if_defined:n #1 { T, F, TF } { - tl = { 0pt } { 0pt } , - tr = { 0pt } { 0pt } , - bl = { 0pt } { 0pt } , - br = { 0pt } { 0pt } , + \prop_if_exist:cTF { l__color_named_ #1 _prop } + \prg_return_true: + \prg_return_false: } -\prop_const_from_keyval:Nn \c__coffin_poles_prop +\cs_new:Npn \__color_model:N #1 { \exp_after:wN \use_i:nn #1 } +\cs_new:Npn \__color_values:N #1 { \exp_after:wN \use_ii:nn #1 } +\cs_new_protected:Npn \__color_extract:nNN #1#2#3 { - l = { 0pt } { 0pt } { 0pt } { 1000pt } , - hc = { 0pt } { 0pt } { 0pt } { 1000pt } , - r = { 0pt } { 0pt } { 0pt } { 1000pt } , - b = { 0pt } { 0pt } { 1000pt } { 0pt } , - vc = { 0pt } { 0pt } { 1000pt } { 0pt } , - t = { 0pt } { 0pt } { 1000pt } { 0pt } , - B = { 0pt } { 0pt } { 1000pt } { 0pt } , - H = { 0pt } { 0pt } { 1000pt } { 0pt } , - T = { 0pt } { 0pt } { 1000pt } { 0pt } , + \tl_set_eq:Nc #2 { l__color_named_ #1 _tl } + \prop_get:cVN { l__color_named_ #1 _prop } #2 #3 } -\fp_new:N \l__coffin_slope_A_fp -\fp_new:N \l__coffin_slope_B_fp -\bool_new:N \l__coffin_error_bool -\dim_new:N \l__coffin_offset_x_dim -\dim_new:N \l__coffin_offset_y_dim -\tl_new:N \l__coffin_pole_a_tl -\tl_new:N \l__coffin_pole_b_tl -\dim_new:N \l__coffin_x_dim -\dim_new:N \l__coffin_y_dim -\dim_new:N \l__coffin_x_prime_dim -\dim_new:N \l__coffin_y_prime_dim -\cs_new_eq:NN \__coffin_to_value:N \tex_number:D -\prg_new_conditional:Npnn \coffin_if_exist:N #1 { p , T , F , TF } +\cs_generate_variant:Nn \__color_extract:nNN { V } +\cs_new_protected:Npn \__color_convert:nnN #1#2#3 + { \__color_convert:nnVN {#1} {#2} #3 #3 } +\cs_generate_variant:Nn \__color_convert:nnN { VV } +\cs_new_protected:Npn \__color_convert:nnnN #1#2#3#4 { - \cs_if_exist:NTF #1 + \tl_set:Nx #4 { - \cs_if_exist:cTF { coffin ~ \__coffin_to_value:N #1 ~ poles } - { \prg_return_true: } - { \prg_return_false: } + \cs_if_exist:cTF { __color_convert_ #1 _ #2 :w } + { \use:c { __color_convert_ #1 _ #2 :w } #3 ~ 0 ~ 0 ~ 0 \s__color_stop } + { \use:c { c__color_fallback_ #2 _tl } } } - { \prg_return_false: } } -\prg_generate_conditional_variant:Nnn \coffin_if_exist:N - { c } { p , T , F , TF } -\cs_new_protected:Npn \__coffin_if_exist:NT #1#2 +\cs_generate_variant:Nn \__color_convert:nnnN { nV , nnV } +\cs_new:Npn \__color_convert_gray_rgb:w #1 ~ #2 \s__color_stop + { #1 ~ #1 ~ #1 } +\cs_new:Npn \__color_convert_gray_cmyk:w #1 ~ #2 \s__color_stop + { 0 ~ 0 ~ 0 ~ \fp_eval:n { 1 - #1 } } +\cs_new:Npn \__color_convert_rgb_gray:w #1 ~ #2 ~ #3 ~ #4 \s__color_stop + { \fp_eval:n { 0.3 * #1 + 0.59 * #2 + 0.11 * #3 } } +\cs_new:Npn \__color_convert_rgb_cmyk:w #1 ~ #2 ~ #3 ~ #4 \s__color_stop { - \coffin_if_exist:NTF #1 - { #2 } - { - \__kernel_msg_error:nnx { kernel } { unknown-coffin } - { \token_to_str:N #1 } - } + \exp_args:Nf \__color_convert_rgb_cmyk:nnnn + { \fp_eval:n { min ( 1 - #1 , 1 - #2 , 1 - #3 ) } } {#1} {#2} {#3} } -\cs_new_protected:Npn \coffin_clear:N #1 +\cs_new:Npn \__color_convert_rgb_cmyk:nnnn #1#2#3#4 { - \__coffin_if_exist:NT #1 - { - \box_clear:N #1 - \__coffin_reset_structure:N #1 + \fp_eval:n { min ( 1 , max ( 0 , 1 - #2 - #1 ) ) } \c_space_tl + \fp_eval:n { min ( 1 , max ( 0 , 1 - #3 - #1 ) ) } \c_space_tl + \fp_eval:n { min ( 1 , max ( 0 , 1 - #4 - #1 ) ) } \c_space_tl + #1 + } +\cs_new:Npn \__color_convert_cmyk_gray:w #1 ~ #2 ~ #3 ~ #4 ~ #5 \s__color_stop + { \fp_eval:n { 1 - min ( 1 , 0.3 * #1 + 0.59 * #2 + 0.11 * #3 + #4 ) } } +\cs_new:Npn \__color_convert_cmyk_rgb:w #1 ~ #2 ~ #3 ~ #4 ~ #5 \s__color_stop + { + \fp_eval:n { 1 - min ( 1 , #1 + #4 ) } \c_space_tl + \fp_eval:n { 1 - min ( 1 , #2 + #4 ) } \c_space_tl + \fp_eval:n { 1 - min ( 1 , #3 + #4 ) } + } +\tl_new:N \l__color_model_tl +\tl_new:N \l__color_value_tl +\tl_new:N \l__color_next_model_tl +\tl_new:N \l__color_next_value_tl +\cs_new_protected:Npx \__color_parse:nN #1#2 + { + \exp_not:N \__color_backend_pickup:N \exp_not:N \l__color_current_tl + \tl_set:Nx \exp_not:c { l__color_named_ . _tl } + { \exp_not:N \__color_model:N \exp_not:N \l__color_current_tl } + \prop_put:NVx \exp_not:c { l__color_named_ . _prop } + \exp_not:c { l__color_named_ . _tl } + { \exp_not:N \__color_values:N \exp_not:N \l__color_current_tl } + \exp_not:N \exp_args:Ne \exp_not:N \__color_parse_aux:nN + { \exp_not:N \tl_to_str:n {#1} } #2 + } +\cs_new_protected:Npn \__color_parse_aux:nN #1#2 + { + \tl_if_exist:cTF { l__color_named_ #1 _prop } + { \__color_parse_set_eq:Nn #2 {#1} } + { \__color_parse:Nw #2#1 ! \s__color_stop } + \__color_check_model:N #2 + } +\cs_new_protected:Npn \__color_parse_set_eq:Nn #1#2 + { + \tl_if_empty:NTF \l_color_fixed_model_tl + { \exp_args:Nv \__color_parse_set_eq:nNn { l__color_named_ #2 _tl } } + { \exp_args:NV \__color_parse_set_eq:nNn \l_color_fixed_model_tl } + #1 {#2} + } +\cs_new_protected:Npn \__color_parse_set_eq:nNn #1#2#3 + { + \prop_get:cnNTF + { l__color_named_ #3 _prop } {#1} + \l__color_value_tl + { \tl_set:Nx #2 { {#1} { \l__color_value_tl } } } + { + \tl_set_eq:Nc \l__color_model_tl { l__color_named_ #3 _tl } + \prop_get:cVN { l__color_named_ #3 _prop } \l__color_model_tl + \l__color_value_tl + \__color_convert:nnN + \l__color_model_tl {#1} \l__color_value_tl + \tl_set:Nx #2 + { + {#1} + { \l__color_value_tl } + } } } -\cs_generate_variant:Nn \coffin_clear:N { c } -\cs_new_protected:Npn \coffin_gclear:N #1 +\cs_new_protected:Npn \__color_parse:Nw #1#2 ! #3 \s__color_stop { - \__coffin_if_exist:NT #1 + \__color_if_defined:nTF {#2} { - \box_gclear:N #1 - \__coffin_greset_structure:N #1 + \tl_if_blank:nTF {#3} + { \__color_parse_set_eq:Nn #1 {#2} } + { \__color_parse_loop_init:Nnn #1 {#2} {#3} } + } + { + \__kernel_msg_error:nnn { color } { unknown-color } {#2} + \tl_set:Nn \l__color_current_tl { { gray } { 0 } } } } -\cs_generate_variant:Nn \coffin_gclear:N { c } -\cs_new_protected:Npn \coffin_new:N #1 +\cs_new_protected:Npn \__color_parse_loop_init:Nnn #1#2#3 { - \box_new:N #1 - \debug_suspend: - \prop_gclear_new:c { coffin ~ \__coffin_to_value:N #1 ~ corners } - \prop_gclear_new:c { coffin ~ \__coffin_to_value:N #1 ~ poles } - \prop_gset_eq:cN { coffin ~ \__coffin_to_value:N #1 ~ corners } - \c__coffin_corners_prop - \prop_gset_eq:cN { coffin ~ \__coffin_to_value:N #1 ~ poles } - \c__coffin_poles_prop - \debug_resume: + \group_begin: + \__color_extract:nNN {#2} \l__color_model_tl \l__color_value_tl + \__color_parse_loop:w #3 ! ! ! ! \s__color_stop + \tl_set:Nx \l__color_internal_tl + { { \l__color_model_tl } { \l__color_value_tl } } + \exp_args:NNNV \group_end: + \tl_set:Nn #1 \l__color_internal_tl } -\cs_generate_variant:Nn \coffin_new:N { c } -\cs_new_protected:Npn \hcoffin_set:Nn #1#2 +\cs_new_protected:Npn \__color_parse_loop:w #1 ! #2 ! #3 ! #4 ! #5 \s__color_stop { - \__coffin_if_exist:NT #1 + \bool_lazy_or:nnF + { \tl_if_blank_p:n {#1} } + { \int_compare_p:nNn {#1} = { 100 } } { - \hbox_set:Nn #1 + \int_compare:nNnTF {#1} = { 0 } { - \color_ensure_current: - #2 + \tl_if_blank:nTF {#2} + { \__color_extract:nNN { white } } + { \__color_extract:nNN {#2} } + \l__color_model_tl \l__color_value_tl + } + { + \use:x + { + \__color_parse_loop:nn {#1} + { \tl_if_blank:nTF {#2} { white } {#2} } + } } - \__coffin_update:N #1 } + \tl_if_blank:nF {#3} + { \__color_parse_loop:w #3 ! #4 ! #5 \s__color_stop } + \__color_parse_end: } -\cs_generate_variant:Nn \hcoffin_set:Nn { c } -\cs_new_protected:Npn \hcoffin_gset:Nn #1#2 +\cs_new_protected:Npn \__color_parse_loop:nn #1#2 { - \__coffin_if_exist:NT #1 + \__color_if_defined:nTF {#2} { - \hbox_gset:Nn #1 + \__color_extract:nNN {#2} \l__color_next_model_tl \l__color_next_value_tl + \tl_if_eq:NNF \l__color_model_tl \l__color_next_model_tl { - \color_ensure_current: - #2 + \str_if_eq:VnTF \l__color_model_tl { gray } + { \__color_parse_gray:n {#2} } + { \__color_parse_std:n {#2} } } - \__coffin_gupdate:N #1 + \tl_set:Nx \l__color_value_tl + { + \__color_parse_mix:NVVn + \l__color_model_tl \l__color_value_tl \l__color_next_value_tl {#1} + } + } + { + \__kernel_msg_error:nnn { color } { unknown-color } {#2} + \__color_extract:nNN { black } \l__color_model_tl \l__color_value_tl + \__color_parse_break:w } } -\cs_generate_variant:Nn \hcoffin_gset:Nn { c } -\cs_new_protected:Npn \vcoffin_set:Nnn #1#2#3 +\cs_new_protected:Npn \__color_parse_gray:n #1 { - \__coffin_set_vertical:NnnNN #1 {#2} {#3} - \vbox_set:Nn \__coffin_update:N + \tl_set_eq:NN \l__color_model_tl \l__color_next_model_tl + \tl_set:Nn \l__color_next_model_tl { gray } + \exp_args:NnV \__color_convert:nnN { gray } \l__color_model_tl + \l__color_value_tl + \prop_get:cVN { l__color_named_ #1 _prop } \l__color_model_tl + \l__color_next_value_tl } -\cs_generate_variant:Nn \vcoffin_set:Nnn { c } -\cs_new_protected:Npn \vcoffin_gset:Nnn #1#2#3 +\cs_new_protected:Npn \__color_parse_std:n #1 { - \__coffin_set_vertical:NnnNN #1 {#2} {#3} - \vbox_gset:Nn \__coffin_gupdate:N + \prop_get:cVNF { l__color_named_ #1 _prop } + \l__color_model_tl + \l__color_next_value_tl + { + \__color_convert:VVN + \l__color_next_model_tl + \l__color_model_tl + \l__color_next_value_tl + } } -\cs_generate_variant:Nn \vcoffin_gset:Nnn { c } -\cs_new_protected:Npn \__coffin_set_vertical:NnnNN #1#2#3#4#5 +\cs_new_protected:Npn \__color_parse_break:w #1 \__color_parse_end: { } +\cs_new_protected:Npn \__color_parse_end: { } +\cs_new:Npn \__color_parse_mix:Nnnn #1#2#3#4 { - \__coffin_if_exist:NT #1 + \exp_args:Nf \__color_parse_mix:nNnn + { \fp_eval:n { #4 / 100 } } + #1 {#2} {#3} + } +\cs_generate_variant:Nn \__color_parse_mix:Nnnn { NVV } +\cs_new:Npn \__color_parse_mix:nNnn #1#2#3#4 + { + \use:c { __color_parse_mix_ #2 :nw } {#1} + #3 \s__color_mark #4 \s__color_stop + } +\cs_new:Npn \__color_parse_mix_gray:nw #1#2 \s__color_mark #3 \s__color_stop + { \fp_eval:n { #2 * #1 + #3 * ( 1 - #1 ) } } +\cs_new:Npn \__color_parse_mix_rgb:nw + #1#2 ~ #3 ~ #4 \s__color_mark #5 ~ #6 ~ #7 \s__color_stop + { + \fp_eval:n { #2 * #1 + #5 * ( 1 - #1 ) } \c_space_tl + \fp_eval:n { #3 * #1 + #6 * ( 1 - #1 ) } \c_space_tl + \fp_eval:n { #4 * #1 + #7 * ( 1 - #1 ) } + } +\cs_new:Npn \__color_parse_mix_cmyk:nw + #1#2 ~ #3 ~ #4 ~ #5 \s__color_mark #6 ~ #7 ~ #8 ~ #9 \s__color_stop + { + \fp_eval:n { #2 * #1 + #6 * ( 1 - #1 ) } \c_space_tl + \fp_eval:n { #3 * #1 + #7 * ( 1 - #1 ) } \c_space_tl + \fp_eval:n { #4 * #1 + #8 * ( 1 - #1 ) } \c_space_tl + \fp_eval:n { #5 * #1 + #9 * ( 1 - #1 ) } + } +\cs_new:Npn \__color_parse_model_gray:w #1 , #2 \s__color_stop + { { gray } { \__color_parse_number:n {#1} } } +\cs_new:Npn \__color_parse_model_rgb:w #1 , #2 , #3 , #4 \s__color_stop + { + { rgb } + { + \__color_parse_number:n {#1} ~ + \__color_parse_number:n {#2} ~ + \__color_parse_number:n {#3} + } + } +\cs_new:Npn \__color_parse_model_cmyk:w #1 , #2 , #3 , #4 , #5 \s__color_stop + { + { cmyk } + { + \__color_parse_number:n {#1} ~ + \__color_parse_number:n {#2} ~ + \__color_parse_number:n {#3} ~ + \__color_parse_number:n {#4} + } + } +\cs_new:Npn \__color_parse_number:n #1 + { \__color_parse_number:w #1 . 0 . \s__color_stop } +\cs_new:Npn \__color_parse_number:w #1 . #2 . #3 \s__color_stop + { \tl_if_blank:nTF {#1} { 0 } {#1} . #2 } +\cs_new:Npn \__color_parse_model_Gray:w #1 , #2 \s__color_stop + { { gray } { \fp_eval:n { #1 / 15 } } } +\cs_new:Npn \__color_parse_model_hsb:w #1 , #2 , #3 , #4 \s__color_stop + { \__color_parse_model_hsb:nnn {#1} {#2} {#3} } +\cs_new:Npn \__color_parse_model_Hsb:w #1 , #2 , #3 , #4 \s__color_stop + { + \exp_args:Ne \__color_parse_model_hsb:nnn { \fp_eval:n { #1 / 360 } } + {#2} {#3} + } +\cs_new:Npn \__color_parse_model_hsb:nnn #1#2#3 + { + { rgb } + { + \exp_args:Ne \__color_parse_model_hsb_aux:nnn + { \fp_eval:n { 6 * #1 } } {#2} {#3} + } + } +\cs_new:Npn \__color_parse_model_hsb_aux:nnn #1#2#3 + { + \exp_args:Nee \__color_parse_model_hsb_aux:nnnn + { \fp_eval:n { floor(#1) } } { \fp_eval:n { #1 - floor(#1) } } + {#2} {#3} + } +\cs_new:Npn \__color_parse_model_hsb_aux:nnnn #1#2#3#4 + { + \use:e { - #4 #1 + \exp_not:N \__color_parse_model_hsb_aux:nnnnn + { \__color_parse_number:n {#4} } + { \fp_eval:n { round(#4 * (1 - #3) ,5) } } + { \fp_eval:n { round(#4 * ( 1 - #3 * #2 ) ,5) } } + { \fp_eval:n { round(#4 * ( 1 - #3 * (1 - #2) ) ,5) } } + {#1} + } + } +\cs_new:Npn \__color_parse_model_hsb_aux:nnnnn #1#2#3#4#5 + { \use:c { __color_parse_model_hsb_ #5 :nnnn } {#1} {#2} {#3} {#4} } +\cs_new:cpn { __color_parse_model_hsb_0:nnnn } #1#2#3#4 { #1 ~ #4 ~ #2 } +\cs_new:cpn { __color_parse_model_hsb_1:nnnn } #1#2#3#4 { #3 ~ #1 ~ #2 } +\cs_new:cpn { __color_parse_model_hsb_2:nnnn } #1#2#3#4 { #2 ~ #1 ~ #4 } +\cs_new:cpn { __color_parse_model_hsb_3:nnnn } #1#2#3#4 { #2 ~ #3 ~ #1 } +\cs_new:cpn { __color_parse_model_hsb_4:nnnn } #1#2#3#4 { #4 ~ #2 ~ #1 } +\cs_new:cpn { __color_parse_model_hsb_5:nnnn } #1#2#3#4 { #1 ~ #2 ~ #3 } +\cs_new:cpn { __color_parse_model_hsb_6:nnnn } #1#2#3#4 { #1 ~ #2 ~ #2 } +\cs_new:Npn \__color_parse_model_HSB:w #1 , #2 , #3 , #4 \s__color_stop + { + \exp_args:Neee \__color_parse_model_hsb:nnn + { \fp_eval:n {#1 / 240} } + { \fp_eval:n {#2 / 240} } + { \fp_eval:n {#3 / 240} } + } +\cs_new:Npn \__color_parse_model_HTML:w #1 , #2 \s__color_stop + { \__color_parse_model_HTML_aux:w #1 0 0 0 0 0 0 \s__color_stop } +\cs_new:Npn \__color_parse_model_HTML_aux:w #1#2#3#4#5#6#7 \s__color_stop + { + { rgb } + { + \fp_eval:n { round(\int_from_hex:n {#1#2} / 255,5) } ~ + \fp_eval:n { round(\int_from_hex:n {#3#4} / 255,5) } ~ + \fp_eval:n { round(\int_from_hex:n {#5#6} / 255,5) } + } + } +\cs_new:Npn \__color_parse_model_RGB:w #1 , #2 , #3 , #4 \s__color_stop + { + { rgb } + { + \fp_eval:n { round(#1 / 255,5) } ~ + \fp_eval:n { round(#2 / 255,5) } ~ + \fp_eval:n { round(#3 / 255,5) } + } + } +\cs_new:Npn \__color_parse_model_wave:w #1 , #2 \s__color_stop + { + { rgb } + { + \fp_compare:nNnTF {#1} < { 420 } + { \__color_parse_model_wave_auxi:nn {#1} { 0.3 + 0.7 * (#1 - 380) / 40 } + } + { + \fp_compare:nNnTF {#1} > { 700 } + { \__color_parse_model_wave_auxi:nn {#1} { 0.3 + 0.7 * (#1 - 780) / -80 } } + { \__color_parse_model_wave_auxi:nn {#1} { 1 } } + } + } + } +\cs_new:Npn \__color_parse_model_wave_auxi:nn #1#2 + { + \fp_compare:nNnTF {#1} < { 440 } + { + \__color_parse_model_wave_auxii:nn + { 4 + \__color_parse_model_wave_rho:n { (#1 - 440) / -60 } } + {#2} + } + { + \fp_compare:nNnTF {#1} < { 490 } { - \dim_set:Nn \tex_hsize:D {#2} - \__coffin_set_vertical_aux: - #3 + \__color_parse_model_wave_auxii:nn + { 4 - \__color_parse_model_wave_rho:n { (#1 - 440) / 50 } } + {#2} } - #5 #1 - \vbox_set_top:Nn \l__coffin_internal_box { \vbox_unpack:N #1 } - \__coffin_set_pole:Nnx #1 { T } { - { 0pt } - { - \dim_eval:n - { \box_ht:N #1 - \box_ht:N \l__coffin_internal_box } - } - { 1000pt } - { 0pt } + \fp_compare:nNnTF {#1} < { 510 } + { + \__color_parse_model_wave_auxii:nn + { 2 + \__color_parse_model_wave_rho:n { (#1 - 510) / -20 } } + {#2} + } + { + \fp_compare:nNnTF {#1} < { 580 } + { + \__color_parse_model_wave_auxii:nn + { 2 - \__color_parse_model_wave_rho:n { (#1 - 510) / 70 } } + {#2} + } + { + \fp_compare:nNnTF {#1} < { 645 } + { + \__color_parse_model_wave_auxii:nn + { \__color_parse_model_wave_rho:n { (#1 - 645) / -65 } } + {#2} + } + { \__color_parse_model_wave_auxii:nn { 0 } {#2} } + } + } } - \box_clear:N \l__coffin_internal_box } } -\cs_new_protected:Npx \__coffin_set_vertical_aux: +\cs_new:Npn \__color_parse_model_wave_auxii:nn #1#2 { - \bool_lazy_and:nnT - { \cs_if_exist_p:N \fmtname } - { \str_if_eq_p:Vn \fmtname { LaTeX2e } } + \exp_args:Neee \__color_parse_model_hsb_aux:nnn + { \fp_eval:n {#1} } + { 1 } + { \__color_parse_model_wave_rho:n {#2} } + } +\cs_new:Npn \__color_parse_model_wave_rho:n #1 + { \fp_eval:n { min(1, max(0,#1) ) } } +\tl_new:N \l_color_fixed_model_tl +\cs_new_protected:Npn \__color_check_model:N #1 + { + \tl_if_empty:NF \l_color_fixed_model_tl { - \dim_set_eq:NN \exp_not:N \linewidth \tex_hsize:D - \dim_set_eq:NN \exp_not:N \columnwidth \tex_hsize:D + \exp_after:wN \__color_check_model:nn #1 + \tl_if_eq:NNF \l__color_model_tl \l_color_fixed_model_tl + { + \__color_convert:VVN \l__color_model_tl \l_color_fixed_model_tl + \l__color_value_tl + } + \tl_set:Nx #1 + { { \l_color_fixed_model_tl } { \l__color_value_tl } } } } -\cs_new_protected:Npn \hcoffin_set:Nw #1 +\cs_new_protected:Npn \__color_check_model:nn #1#2 { - \__coffin_if_exist:NT #1 + \tl_set:Nn \l__color_model_tl {#1} + \tl_set:Nn \l__color_value_tl {#2} + } +\cs_new_protected:Npx \__color_select: + { + \tl_set:Nx \exp_not:c { l__color_named_ . _tl } + { \exp_not:N \__color_model:N \exp_not:N \l__color_current_tl } + \prop_clear:N \exp_not:c { l__color_named_ . _prop } + \prop_put:NVx \exp_not:c { l__color_named_ . _prop } + \exp_not:c { l__color_named_ . _tl } + { \exp_not:N \__color_values:N \exp_not:N \l__color_current_tl } + \__color_select:N \exp_not:N \l__color_current_tl + } +\cs_new_protected:Npn \color_select:n #1 + { + \__color_parse:nN {#1} \l__color_current_tl + \__color_select: + } +\cs_new_protected:Npn \color_select:nn #1#2 + { + \__color_select_main:Nw \l__color_current_tl + #1 / / \s__color_mark #2 / / \s__color_stop + \__color_select: + } +\cs_new_protected:Npn \__color_select_main:Nw + #1 #2 / #3 / #4 \s__color_mark #5 / #6 / #7 \s__color_stop + { + \__color_select:nnN {#2} {#5} #1 + \bool_lazy_or:nnF + { \tl_if_empty_p:N \l_color_fixed_model_tl } + { \str_if_eq_p:nV {#2} \l_color_fixed_model_tl } + { \__color_select_loop:Nw #1 #3 / #4 \s__color_mark #6 / #7 \s__color_stop } + } +\cs_new_protected:Npn \__color_select_loop:Nw + #1 #2 / #3 \s__color_mark #4 / #5 \s__color_stop + { + \str_if_eq:nVTF {#2} \l_color_fixed_model_tl + { \__color_select:nnN {#2} {#4} #1 } { - \hbox_set:Nw #1 \color_ensure_current: - \cs_set_protected:Npn \hcoffin_set_end: - { - \hbox_set_end: - \__coffin_update:N #1 - } + \tl_if_blank:nTF {#2} + { \exp_after:wN \__color_select_swap:Nnn \exp_after:wN #1 #1 } + { \__color_select_loop:Nw #1 #3 \s__color_mark #5 \s__color_stop } } } -\cs_generate_variant:Nn \hcoffin_set:Nw { c } -\cs_new_protected:Npn \hcoffin_gset:Nw #1 +\cs_new_protected:Npn \__color_select:nnN #1#2#3 { - \__coffin_if_exist:NT #1 + \cs_if_exist:cTF { __color_parse_model_ #1 :w } { - \hbox_gset:Nw #1 \color_ensure_current: - \cs_set_protected:Npn \hcoffin_gset_end: - { - \hbox_gset_end: - \__coffin_gupdate:N #1 - } + \tl_set:Nx #3 + { \use:c { __color_parse_model_ #1 :w } #2 , 0 , 0 , 0 , 0 \s__color_stop } } + { \__kernel_msg_error:nnn { color } { unknown-model } {#1} } } -\cs_generate_variant:Nn \hcoffin_gset:Nw { c } -\cs_new_protected:Npn \hcoffin_set_end: { } -\cs_new_protected:Npn \hcoffin_gset_end: { } -\cs_new_protected:Npn \vcoffin_set:Nnw #1#2 +\cs_new_protected:Npn \__color_select_swap:Nnn #1#2#3 { - \__coffin_set_vertical:NnNNNNw #1 {#2} \vbox_set:Nw - \vcoffin_set_end: - \vbox_set_end: \__coffin_update:N + \__color_convert:nVnN {#2} \l_color_fixed_model_tl {#3} \l__color_value_tl + \tl_set:Nx #1 + { { \l_color_fixed_model_tl } { \l__color_value_tl } } } -\cs_generate_variant:Nn \vcoffin_set:Nnw { c } -\cs_new_protected:Npn \vcoffin_gset:Nnw #1#2 +\cs_new_protected:Npn \color_fill:n #1 { - \__coffin_set_vertical:NnNNNNw #1 {#2} \vbox_gset:Nw - \vcoffin_gset_end: - \vbox_gset_end: \__coffin_gupdate:N + \__color_parse:nN {#1} \l__color_current_tl + \exp_after:wN \__color_draw:nnn \l__color_current_tl { fill } } -\cs_generate_variant:Nn \vcoffin_gset:Nnw { c } -\cs_new_protected:Npn \__coffin_set_vertical:NnNNNNw #1#2#3#4#5#6 +\cs_new_protected:Npn \color_stroke:n #1 { - \__coffin_if_exist:NT #1 - { - #3 #1 - \dim_set:Nn \tex_hsize:D {#2} - \__coffin_set_vertical_aux: + \__color_parse:nN {#1} \l__color_current_tl + \exp_after:wN \__color_draw:nnn \l__color_current_tl { stroke } + } +\cs_new_protected:Npn \color_fill:nn #1#2 + { + \__color_select_main:Nw \l__color_current_tl + #1 / / \s__color_mark #2 / / \s__color_stop + \exp_after:wN \__color_draw:nnn \l__color_current_tl { fill } + } +\cs_new_protected:Npn \color_stroke:nn #1#2 + { + \__color_select_main:Nw \l__color_current_tl + #1 / / \s__color_mark #2 / / \s__color_stop + \exp_after:wN \__color_draw:nnn \l__color_current_tl { stroke } + } +\cs_new_protected:Npn \__color_draw:nnn #1#2#3 + { \use:c { __color_backend_ #3 _ #1 :n } {#2} } +\tl_new:N \l__color_named_tl +\cs_new_protected:Npn \color_set:nn #1#2 + { + \exp_args:NV \__color_set:nnn + \l_color_fixed_model_tl {#1} {#2} + } +\cs_new_protected:Npn \__color_set:nnn #1#2#3 + { + \tl_clear:N \l_color_fixed_model_tl + \__color_set:nn {#2} {#3} + \tl_set:Nn \l_color_fixed_model_tl {#1} + } +\cs_new_protected:Npn \__color_set:nn #1#2 + { + \str_if_eq:nnF {#1} { . } + { + \__color_parse:nN {#2} \l__color_named_tl + \tl_clear_new:c { l__color_named_ #1 _tl } + \tl_set:cx { l__color_named_ #1 _tl } + { \__color_model:N \l__color_named_tl } + \prop_clear_new:c { l__color_named_ #1 _prop } + \prop_put:cvx { l__color_named_ #1 _prop } { l__color_named_ #1 _tl } + { \__color_values:N \l__color_named_tl } + \__color_set:nnw {#1} {#2} #2 ! \s__color_stop + } + } +\cs_new_protected:Npn \__color_set:nnw #1#2#3 ! #4 \s__color_stop + { + \clist_map_inline:nn { cmyk , gray , rgb } + { + \prop_get:cnNT { l__color_named_ #3 _prop } {##1} \l__color_internal_tl + { + \prop_if_in:cnF { l__color_named_ #1 _prop } {##1} + { + \group_begin: + \tl_set:cn { l__color_named_ #3 _tl } {##1} + \__color_parse:nN {#2} \l__color_internal_tl + \exp_args:NNNV \group_end: + \tl_set:Nn \l__color_internal_tl \l__color_internal_tl + \prop_put:cxx { l__color_named_ #1 _prop } + { \__color_model:N \l__color_internal_tl } + { \__color_values:N \l__color_internal_tl } + } + } + } + } +\cs_new_protected:Npx \color_set:nnn #1#2#3 + { + \exp_not:N \str_if_eq:nnF {#1} { . } + { + \tl_clear_new:c { l__color_named_ #1 _tl } + \prop_clear_new:c { l__color_named_ #1 _prop } + \exp_not:N \__color_set_colon:nnw {#1} {#3} + #2 \c_colon_str \c_colon_str \exp_not:N \s__color_stop + } + } +\use:x + { + \cs_new_protected:Npn \exp_not:N \__color_set_colon:nnw + ##1##2 ##3 \c_colon_str ##4 \c_colon_str + ##5 \exp_not:N \s__color_stop + } + { + \tl_if_blank:nTF {#4} + { \__color_set_loop:nw {#1} #3 } + { \__color_set_loop:nw {#1} #4 } + / / \s__color_mark #2 / / \s__color_stop + } +\cs_new_protected:Npn \__color_set_loop:nw + #1#2 / #3 \s__color_mark #4 / #5 \s__color_stop + { + \tl_if_blank:nF {#2} + { + \__color_select:nnN {#2} {#4} \l__color_named_tl + \tl_set:Nx \l__color_internal_tl { \__color_model:N \l__color_named_tl } + \tl_if_empty:cT { l__color_named_ #1 _tl } + { \tl_set_eq:cN { l__color_named_ #1 _tl } \l__color_internal_tl } + \prop_put:cVx { l__color_named_ #1 _prop } \l__color_internal_tl + { \__color_values:N \l__color_named_tl } + \__color_set_loop:nw {#1} #3 \s__color_mark #5 \s__color_stop + } + } +\cs_new_protected:Npn \color_set_eq:nn #1#2 + { + \__color_if_defined:nTF {#2} + { + \tl_clear_new:c { l__color_named_ #1 _tl } + \prop_clear_new:c { l__color_named_ #1 _prop } + \str_if_eq:nnTF {#2} { . } + { + \tl_set:cx { l__color_named_ #1 _tl } + { \__color_model:N \l__color_current_tl } + \prop_put:cvx { l__color_named_ #1 _prop } { l__color_named_ #1 _tl } + { \__color_values:N \l__color_current_tl } + } + { + \tl_set_eq:cc { l__color_named_ #1 _tl } { l__color_named_ #2 _tl } + \prop_set_eq:cc { l__color_named_ #1 _prop } { l__color_named_ #2 _prop } + } + } + { + \__kernel_msg_error:nnn { color } { unknown-color } {#2} + } + } +\color_set:nnn { black } { gray } { 0 } +\color_set:nnn { white } { gray } { 1 } +\color_set:nnn { cyan } { cmyk } { 1 , 0 , 0 , 0 } +\color_set:nnn { magenta } { cmyk } { 0 , 1 , 0 , 0 } +\color_set:nnn { yellow } { cmyk } { 0 , 0 , 1 , 0 } +\color_set:nnn { red } { rgb } { 1 , 0 , 0 } +\color_set:nnn { green } { rgb } { 0 , 1 , 0 } +\color_set:nnn { blue } { rgb } { 0 , 0 , 1 } +\prop_new:c { l__color_named_._prop } +\tl_new:c { l__color_named_._tl } +\tl_set:cx { l__color_named_._tl } { \__color_model:N \l__color_current_tl } +\cs_new_protected:Npn \color_export:nnN #1#2#3 + { + \group_begin: + \tl_if_exist:cT { c__color_export_ #2 _tl } + { \tl_set_eq:Nc \l_color_fixed_model_tl { c__color_export_ #2 _tl } } + \__color_parse:nN {#1} #3 + \__color_export:nN {#2} #3 + \exp_args:NNNV \group_end: + \tl_set:Nn #3 #3 + } +\cs_new_protected:Npn \color_export:nnnN #1#2#3#4 + { + \__color_select_main:Nw #4 + #1 / / \s__color_mark #2 / / \s__color_stop + \__color_export:nN {#3} #4 + } +\cs_new_protected:Npn \__color_export:nN #1#2 + { \exp_after:wN \__color_export:nnnN #2 {#1} #2 } +\cs_new:Npn \__color_export:nnnN #1#2#3#4 + { + \cs_if_exist_use:cF { __color_export_format_ #3 :nnN } + { + \__kernel_msg_error:nnn { color } { unknown-export-format } {#3} + \use_none:nnn + } + {#1} {#2} #4 + } +\cs_new_protected:Npn \__color_export_format_backend:nnN #1#2#3 + { \tl_set:Nn #3 { {#1} {#2} } } +\cs_new_protected:Npn \__color_export:nnnNN #1#2#3#4#5 + { + \str_if_eq:nnTF {#2} {#1} + { #5 #4 #3 \s__color_stop } + { + \__color_convert:nnnN {#2} {#1} {#3} #4 + \exp_after:wN #5 \exp_after:wN #4 + #4 \s__color_stop + } + } +\tl_const:Nn \c__color_export_HTML_tl { rgb } +\tl_const:cn { c__color_export_space-sep-cmyk_tl } { cmyk } +\tl_const:cn { c__color_export_space-sep-rgb_tl } { rgb } +\cs_new_protected:cpx { __color_export_format_space-sep-cmyk:nnN } #1#2#3 + { + \exp_not:N \__color_export:nnnNN { cmyk } {#1} {#2} #3 + \exp_not:c { __color_export_space-sep-cmyk:Nw } + } +\cs_new_protected:cpn { __color_export_space-sep-cmyk:Nw } #1#2 \s__color_stop + { \tl_set:Nx #1 {#2} } +\cs_new_protected:Npn \__color_export_format_HTML:nnN #1#2#3 + { \__color_export:nnnNN { rgb } {#1} {#2}#3 \__color_export_HTML:Nw } +\cs_new_protected:cpx { __color_export_format_space-sep-rgb:nnN } #1#2#3 + { + \exp_not:N \__color_export:nnnNN { rgb } {#1} {#2} #3 + \exp_not:c { __color_export_space-sep-rgb:Nw } + } +\cs_new_protected:Npn \__color_export_HTML:Nw #1#2 ~ #3 ~ #4 \s__color_stop + { + \tl_set:Nx #1 + { + \__color_export_HTML:n {#2} + \__color_export_HTML:n {#3} + \__color_export_HTML:n {#4} + } + } +\cs_new:Npn \__color_export_HTML:n #1 + { + \fp_compare:nNnTF {#1} = { 0 } + { 00 } + { \int_to_Hex:n { \fp_to_int:n { #1 * 255 } } } + } +\cs_new_protected:cpn { __color_export_space-sep-rgb:Nw } #1#2 \s__color_stop + { \tl_set:Nx #1 {#2} } +\prop_new:N \l__color_internal_prop +\int_new:N \g__color_model_int +\tl_const:Nn \c__color_fallback_cmyk_tl { 0 ~ 0 ~ 0 ~ 1 } +\tl_const:Nn \c__color_fallback_gray_tl { 1 } +\tl_const:Nn \c__color_fallback_rgb_tl { 1 ~ 1 ~ 1 } +\prop_new:N \g__color_colorants_prop +\prop_gput:Nnn \g__color_colorants_prop { black } { Black } +\prop_gput:Nnn \g__color_colorants_prop { blue } { Blue } +\prop_gput:Nnn \g__color_colorants_prop { cyan } { Cyan } +\prop_gput:Nnn \g__color_colorants_prop { green } { Green } +\prop_gput:Nnn \g__color_colorants_prop { magenta } { Magenta } +\prop_gput:Nnn \g__color_colorants_prop { none } { None } +\prop_gput:Nnn \g__color_colorants_prop { red } { Red } +\prop_gput:Nnn \g__color_colorants_prop { yellow } { Yellow } +\tl_const:Nn \c__color_model_whitepoint_CIELAB_a_tl { 1.0985 ~ 1 ~ 0.3558 } +\tl_const:Nn \c__color_model_whitepoint_CIELAB_b_tl { 0.9807 ~ 1 ~ 1.1822 } +\tl_const:Nn \c__color_model_whitepoint_CIELAB_e_tl { 1 ~ 1 ~ 1 } +\tl_const:cn { c__color_model_whitepoint_CIELAB_d50_tl } { 0.9642 ~ 1 ~ 0.8251 } +\tl_const:cn { c__color_model_whitepoint_CIELAB_d55_tl } { 0.9568 ~ 1 ~ 0.9214 } +\tl_const:cn { c__color_model_whitepoint_CIELAB_d65_tl } { 0.9504 ~ 1 ~ 1.0888 } +\tl_const:cn { c__color_model_whitepoint_CIELAB_d75_tl } { 0.9497 ~ 1 ~ 1.2261 } +\tl_const:Nn \c__color_model_range_CIELAB_tl { 0 ~ 100 ~ -128 ~ 127 ~ -128 ~ 127 } +\prop_new:N \g__color_alternative_model_prop +\clist_map_inline:nn { cyan , magenta , yellow , black } + { \prop_gput:Nnn \g__color_alternative_model_prop {#1} { cmyk } } +\clist_map_inline:nn { red , green , blue } + { \prop_gput:Nnn \g__color_alternative_model_prop {#1} { rgb } } +\prop_new:N \g__color_alternative_values_prop +\prop_gput:Nnn \g__color_alternative_values_prop { cyan } { 1 , 0 , 0 , 0 } +\prop_gput:Nnn \g__color_alternative_values_prop { magenta } { 0 , 1 , 0 , 0 } +\prop_gput:Nnn \g__color_alternative_values_prop { yellow } { 0 , 0 , 1 , 0 } +\prop_gput:Nnn \g__color_alternative_values_prop { black } { 0 , 0 , 0 , 1 } +\prop_gput:Nnn \g__color_alternative_values_prop { red } { 1 , 0 , 0 } +\prop_gput:Nnn \g__color_alternative_values_prop { green } { 0 , 1 , 0 } +\prop_gput:Nnn \g__color_alternative_values_prop { blue } { 0 , 0 , 1 } +\cs_new_protected:Npn \color_model_new:nnn #1#2#3 + { + \exp_args:Nee \__color_model_new:nnn + { \tl_to_str:n {#1} } + { \str_foldcase:n {#2} } {#3} + } +\cs_new_protected:Npn \__color_model_new:nnn #1#2#3 + { + \cs_if_exist:cTF { __color_parse_model_ #1 :w } + { + \__kernel_msg_error:nnn { color } { model-already-defined } {#1} + } + { + \cs_if_exist:cTF { __color_model_ #2 :n } + { + \prop_set_from_keyval:Nn \l__color_internal_prop {#3} + \use:c { __color_model_ #2 :n } {#1} + } + { + \__kernel_msg_error:nnn { color } { unknown-model-type } {#2} + } + } + } +\cs_new_protected:Npn \__color_model_separation:n #1 + { + \prop_get:NnNTF \l__color_internal_prop { name } + \l__color_internal_tl + { + \exp_args:NV \__color_model_separation:nn + \l__color_internal_tl {#1} + } + { + \__kernel_msg_error:nnn { color } + { separation-requires-name } {#1} + } + } +\cs_new_protected:Npn \__color_model_separation:nn #1#2 + { + \prop_get:NnNTF \l__color_internal_prop { alternative-model } + \l__color_internal_tl + { + \exp_args:NV \__color_model_separation:nnn + \l__color_internal_tl {#2} {#1} + } + { + \__kernel_msg_error:nnn { color } + { separation-alternative-model } {#2} + } + } +\cs_new_protected:Npn \__color_model_separation:nnn #1#2#3 + { + \cs_if_exist:cTF { __color_model_separation_ #1 :nnnnnn } + { + \prop_get:NnNTF \l__color_internal_prop { alternative-values } + \l__color_internal_tl + { + \exp_after:wN \__color_model_separation:w \l__color_internal_tl + , 0 , 0 , 0 , 0 \s__color_stop {#2} {#3} {#1} + } + { + \__kernel_msg_error:nnn { color } + { separation-alternative-values } {#2} + } + } + { + \__kernel_msg_error:nnn { color } + { unknown-alternative-model } {#1} + } + } +\cs_new_protected:Npn \__color_model_separation:w + #1 , #2 , #3 , #4 , #5 \s__color_stop #6#7#8 + { + \int_gincr:N \g__color_model_int + \tl_const:cn { c__color_fallback_ #6 _tl } { 1 } + \cs_new_eq:cN { __color_parse_mix_ #6 :nw } \__color_parse_mix_gray:nw + \cs_new:cpn { __color_parse_model_ #6 :w } ##1 , ##2 \s__color_stop + { {#6} { \__color_parse_number:n {##1} } } + \clist_map_inline:nn { fill , stroke , select } + { + \cs_new_protected:cpx { __color_backend_ ##1 _ #6 :n } ####1 + { + \exp_not:c { __color_backend_ ##1 _ separation:nn } + { color \int_use:N \g__color_model_int } {####1} + } + } + \use:c { __color_model_separation_ #8 :nnnnnn } + {#6} {#7} {#1} {#2} {#3} {#4} + \prop_gput:Nnn \g__color_alternative_model_prop {#6} {#8} + \prop_gput:Nnx \g__color_colorants_prop {#6} + { \str_convert_pdfname:n {#7} } + \cs_new_protected:cpx { __color_model_ #6 _white: } + { + \prop_put:Nnn \exp_not:N \l__color_named_white_prop {#6} { 0 } + \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0 + { \group_insert_after:N \exp_not:c { __color_model_ #6 _ white: } } + } + \use:c { __color_model_ #6 _white: } + } +\cs_new_protected:Npn \__color_model_separation_cmyk:nnnnnn #1#2#3#4#5#6 + { + \cs_new:cpn { __color_convert_ #1 _cmyk:w } ##1 ~ ##2 \s__color_stop + { + \fp_eval:n {##1 * #3} ~ + \fp_eval:n {##1 * #4} ~ + \fp_eval:n {##1 * #5} ~ + \fp_eval:n {##1 * #6} + } + \__color_model_convert:nnn {#1} { cmyk } { rgb } + \__color_model_convert:nnn {#1} { cmyk } { gray } + \prop_gput:Nnn \g__color_alternative_values_prop {#1} { #3 , #4 , #5 , #6 } + \__color_backend_separation_init:nnnnn {#2} { /DeviceCMYK } { } + { 0 ~ 0 ~ 0 ~ 0 } { #3 ~ #4 ~ #5 ~ #6 } + } +\cs_new_protected:Npn \__color_model_separation_rgb:nnnnnn #1#2#3#4#5#6 + { + \cs_new:cpn { __color_convert_ #1 _rgb:w } ##1 ~ ##2 \s__color_stop + { + \fp_eval:n {##1 * #3} ~ + \fp_eval:n {##1 * #4} ~ + \fp_eval:n {##1 * #5} + } + \__color_model_convert:nnn {#1} { rgb } { cmyk } + \__color_model_convert:nnn {#1} { rgb } { gray } + \prop_gput:Nnn \g__color_alternative_values_prop {#1} { #3 , #4 , #5 } + \__color_backend_separation_init:nnnnn {#2} { /DeviceRGB } { } + { 0 ~ 0 ~ 0 } { #3 ~ #4 ~ #5 } + } +\cs_new_protected:Npn \__color_model_separation_gray:nnnnnn #1#2#3#4#5#6 + { + \cs_new:cpn { __color_convert_ #1 _cmyk:w } ##1 ~ ##2 \s__color_stop + { + \fp_eval:n {##1 * #3} ~ + \fp_eval:n {##1 * #3} ~ + \fp_eval:n {##1 * #3} ~ + \fp_eval:n {##1 * #3} + } + \cs_new:cpn { __color_convert_ #1 _gray:w } ##1 ~ ##2 \s__color_stop + { \fp_eval:n {##1 * #3} } + \cs_new:cpn { __color_convert_ #1 _rgb:w } ##1 ~ ##2 \s__color_stop + { + \fp_eval:n {##1 * #3} ~ + \fp_eval:n {##1 * #3} ~ + \fp_eval:n {##1 * #3} + } + \prop_gput:Nnn \g__color_alternative_values_prop {#1} {#3} + \__color_backend_separation_init:nnnnn {#2} { /DeviceGray } { } { 0 } {#3} + } +\cs_new_protected:Npn \__color_model_convert:nnn #1#2#3 + { + \cs_new:cpx { __color_convert_ #1 _ #3 :w } ##1 ~ ##2 \s__color_stop + { + \exp_not:N \exp_args:NNe \exp_not:N \use:nn + \exp_not:c { __color_convert_ #2 _ #3 :w } + { \exp_not:c { __color_convert_ #1 _ #2 :w } ##1 ~ ##2 \s__color_stop } + \c_space_tl \exp_not:N \s__color_stop + } + } +\cs_new_protected:Npn \__color_model_separation_CIELAB:nnnnnn #1#2#3#4#5#6 + { + \prop_get:NnNF \l__color_internal_prop { illuminant } + \l__color_internal_tl + { + \__kernel_msg_error:nnn { color } + { CIELAB-requires-illuminant } {#1} + \tl_set:Nn \l__color_internal_tl { d50 } + } + \exp_args:NV \__color_model_separation_CIELAB:nnnnnnn + \l__color_internal_tl {#1} {#2} {#3} {#4} {#5} {#6} + } +\cs_new_protected:Npn \__color_model_separation_CIELAB:nnnnnnn #1#2#3#4#5#6#7 + { + \tl_if_exist:cTF { c__color_model_whitepoint_CIELAB_ #1 _tl } + { + \__color_backend_separation_init_CIELAB:nnn {#1} {#3} { #4 ~ #5 ~ #6 } + \cs_new:cpn { __color_convert_ #2 _cmyk:w } ##1 ~ ##2 \s__color_stop + { 0 ~ 0 ~ 0 ~ 1 } + \cs_new:cpn { __color_convert_ #2 _rgb:w } ##1 ~ ##2 \s__color_stop + { 1 ~ 1 ~ 1 } + \cs_new:cpn { __color_convert_ #2 _gray:w } ##1 ~ ##2 \s__color_stop + { 1 } + } + { + \__kernel_msg_error:nnn { color } + { unknown-CIELAB-illuminant } {#1} + } + } +\cs_new_protected:Npn \__color_model_devicen:n #1 + { + \prop_get:NnNTF \l__color_internal_prop { names } + \l__color_internal_tl + { + \exp_args:NV \__color_model_devicen:nn + \l__color_internal_tl {#1} + } + { + \__kernel_msg_error:nnn { color } + { DeviceN-requires-names } {#1} + } + } +\cs_new_protected:Npn \__color_model_devicen:nn #1#2 + { + \tl_clear:N \l__color_model_tl + \clist_map_inline:nn {#1} + { + \prop_get:NnNTF \g__color_alternative_model_prop {##1} + \l__color_internal_tl + { + \tl_if_empty:NTF \l__color_model_tl + { \tl_set_eq:NN \l__color_model_tl \l__color_internal_tl } + { + \str_if_eq:VVF \l__color_model_tl \l__color_internal_tl + { + \__kernel_msg_error:nnn { color } + { DeviceN-inconsistent-alternative } + {#2} + \clist_map_break:n { \use_none:nnnn } + } + } + } + { + \str_if_eq:nnF {##1} { none } + { + \__kernel_msg_error:nnn { color } + { DeviceN-no-alternative } + {#2} + } + } + } + \tl_if_empty:NTF \l__color_model_tl + { + \__kernel_msg_error:nnn { color } + { DeviceN-no-alternative } {#2} + } + { \exp_args:NV \__color_model_devicen:nnn \l__color_model_tl {#1} {#2} } + } +\cs_new_protected:Npn \__color_model_devicen:nnn #1#2#3 + { + \exp_args:Nx \__color_model_devicen:nnnn + { \clist_count:n {#2} } {#1} {#2} {#3} + } +\cs_new_protected:Npn \__color_model_devicen:nnnn #1#2#3#4 + { + \int_gincr:N \g__color_model_int + \tl_const:cx { c__color_fallback_ #4 _tl } + { \prg_replicate:nn {#1} { 1 ~ } } + \cs_if_exist_use:cF { __color_model_devicen_parse_ #1 :nn } + { \__color_model_devicen_parse_generic:nn } + {#4} {#1} + \clist_map_inline:nn { fill , stroke , select } + { + \cs_new_protected:cpx { __color_backend_ ##1 _ #4 :n } ####1 + { + \exp_not:c { __color_backend_ ##1 _ devicen:nn } + { color \int_use:N \g__color_model_int } {####1} + } + } + \cs_new_protected:cpx { __color_model_ #4 _white: } + { + \prop_put:Nnn \exp_not:N \l__color_named_white_prop {#4} + { \prg_replicate:nn {#1} { 0 ~ } } + \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0 + { \group_insert_after:N \exp_not:c { __color_model_ #4 _ white: } } + } + \use:c { __color_model_ #4 _white: } + \__color_model_devicen_init:nnn {#1} {#2} {#3} + \__color_model_devicen_convert:nnn {#4} {#2} {#3} + } +\cs_new_protected:cpn { __color_model_devicen_parse_1:nn } #1#2 + { + \cs_new:cpn { __color_parse_model_ #1 :w } ##1 , ##2 \s__color_stop + { {#1} { \__color_parse_number:n {##1} } } + \cs_new_eq:cN { __color_parse_mix_ #1 :nw } \__color_parse_mix_gray:nw + } +\cs_new_protected:cpn { __color_model_devicen_parse_2:nn } #1#2 + { + \cs_new:cpn { __color_parse_model_ #1 :w } ##1 , ##2 , ##3 \s__color_stop + { {#1} { \__color_parse_number:n {##1} ~ \__color_parse_number:n {##2} } } + \cs_new:cpn { __color_parse_mix_ #1 :nw } + ##1##2 ~ ##3 \s__color_mark ##4 ~ ##5 \s__color_stop + { + \fp_eval:n { ##2 * ##1 + ##4 * ( 1 - ##1 ) } \c_space_tl + \fp_eval:n { ##3 * ##1 + ##5 * ( 1 - ##1 ) } + } + } +\cs_new_protected:cpn { __color_model_devicen_parse_3:nn } #1#2 + { + \cs_new:cpn { __color_parse_model_ #1 :w } ##1 , ##2 , ##3 , ##4 \s__color_stop + { + {#1} + { + \__color_parse_number:n {##1} ~ + \__color_parse_number:n {##2} ~ + \__color_parse_number:n {##3} + } + } + \cs_new_eq:cN { __color_parse_mix_ #1 :nw } \__color_parse_mix_rgb:nw + } +\cs_new_protected:cpn { __color_model_devicen_parse_4:nn } #1#2 + { + \cs_new:cpn { __color_parse_model_ #1 :w } + ##1 , ##2 , ##3 , ##4 , ##5 \s__color_stop + { + {#1} + { + \__color_parse_number:n {##1} ~ + \__color_parse_number:n {##2} ~ + \__color_parse_number:n {##3} ~ + \__color_parse_number:n {##4} + } + } + \cs_new_eq:cN { __color_parse_mix_ #1 :nw } \__color_parse_mix_cmyk:nw + } +\cs_new_protected:Npn \__color_model_devicen_parse_generic:nn #1#2 + { + \cs_new:cpn { __color_parse_model_ #1 :w } ##1 , ##2 \s__color_stop + { + {#1} + { \__color_model_devicen_parse:nw {#2} ##1 , ##2 , \q_nil , \s__color_stop } + } + \cs_new:cpx { __color_parse_mix_ #1 :nw } + ##1 ##2 \s__color_mark ##3 \s__color_stop + { + \exp_not:N \__color_model_devicen_mix:nw {##1} + ##2 \c_space_tl \exp_not:N \q_nil \c_space_tl \exp_not:N \s__color_mark + ##3 \c_space_tl \exp_not:N \q_nil \c_space_tl \exp_not:N \s__color_stop + } + } +\cs_new:Npn \__color_model_devicen_parse:nw #1#2 , #3 \s__color_stop + { + \int_compare:nNnT {#1} > 0 + { + \quark_if_nil:nTF {#2} + { \prg_replicate:nn {#1} { 0 ~ } } + { + \__color_parse_number:n {#2} + \int_compare:nNnT {#1} > 1 { ~ } + \exp_args:Nf \__color_model_devicen_parse:nw + { \int_eval:n { #1 - 1 } } #3 \s__color_stop + } + } + } +\cs_new:Npn \__color_model_devicen_mix:nw #1#2 ~ #3 \s__color_mark #4 ~ #5 \s__color_stop + { + \fp_eval:n { #2 * #1 + #4 * ( 1 - #1 ) } + \quark_if_nil:oF { \tl_head:w #3 \q_stop } + { + \c_space_tl + \__color_model_devicen_mix:nw {#1} #3 \s__color_mark #5 \s__color_stop + } + } +\cs_new_protected:Npn \__color_model_devicen_init:nnn #1#2#3 + { + \exp_args:Ne \__color_model_devicen_init:nnnn + { + \str_case:nn {#2} + { + { cmyk } { 4 } + { gray } { 1 } + { rgb } { 3 } + } + } + {#1} {#2} {#3} + } +\cs_new_protected:Npn \__color_model_devicen_init:nnnn #1#2#3#4 + { + \tl_set:Nx \l__color_internal_tl + { \prg_replicate:nn {#1} { 1.0 ~ } } + \int_zero:N \l__color_internal_int + \clist_map_inline:nn {#4} + { + \int_incr:N \l__color_internal_int + \prop_get:NnN \g__color_alternative_values_prop {##1} + \l__color_value_tl + \exp_after:wN \__color_model_devicen_transform:w + \l__color_value_tl , 0 , 0 , 0 \s__color_stop {#1} {#2} + } + \tl_put_right:Nx \l__color_internal_tl + { + \prg_replicate:nn {#1} + { neg ~ 1.0 ~ add ~ #1 ~ -1 ~ roll ~ } + \int_eval:n { #2 + 4 } ~ 4 ~ roll + \prg_replicate:nn {#2} { ~ pop } + } + \use:x + { + \__color_backend_devicen_init:nnn + { + \clist_map_function:nN {#4} + \__color_model_devicen_colorant:n + } + { + \str_case:nn {#3} + { + { cmyk } { /DeviceCMYK } + { gray } { /DeviceGray } + { rgb } { /DeviceRGB } + } + } + { \exp_not:V \l__color_internal_tl } + } + } +\cs_new_protected:Npn \__color_model_devicen_transform:w + #1 , #2 , #3 , #4 , #5 \s__color_stop #6#7 + { + \use:c { __color_model_devicen_transform_ #6 :nnnnn } + {#1} {#2} {#3} {#4} {#7} + } +\cs_new_protected:cpn { __color_model_devicen_transform_1:nnnnn } #1#2#3#4#5 + { \__color_model_devicen_transform:nnn {#5} { 1 } {#1} } +\cs_new_protected:cpn { __color_model_devicen_transform_3:nnnnn } #1#2#3#4#5 + { + \clist_map_inline { #1 , #2 , #3 } + { \__color_model_devicen_transform:nnn {#5} { 3 } {##1} } + } +\cs_new_protected:cpn { __color_model_devicen_transform_4:nnnnn } #1#2#3#4#5 + { + \clist_map_inline:nn { #1 , #2 , #3 , #4 } + { \__color_model_devicen_transform:nnn {#5} { 4 } {##1} } + } +\cs_new_protected:Npn \__color_model_devicen_transform:nnn #1#2#3 + { + \tl_put_right:Nx \l__color_internal_tl + { + \fp_compare:nNnF {#3} = \c_zero_fp + { + \int_eval:n { #1 - \l__color_internal_int + #2 } ~ index ~ + #3 ~ neg ~ mul ~ 1.0 ~ add ~ mul ~ + } + #2 ~ -1 ~ roll ~ + } + } +\cs_new:Npn \__color_model_devicen_colorant:n #1 + { + / \prop_item:Nn \g__color_colorants_prop {#1} ~ + } +\cs_new_protected:Npn \__color_model_devicen_convert:nnn #1#2#3 + { + \use:c { __color_model_devicen_convert_ #2 :nn } {#1} {#3} + } +\cs_new_protected:Npn \__color_model_devicen_convert_cmyk:nn #1#2 + { + \__color_model_convert:nnn {#1} { cmyk } { gray } + \__color_model_convert:nnn {#1} { cmyk } { rgb } + \__color_model_devicen_convert:nnnn {#1} { cmyk } { 4 } {#2} + } +\cs_new_protected:Npn \__color_model_devicen_convert_gray:nn #1#2 + { + \__color_model_convert:nnn {#1} { gray } { cmyk } + \__color_model_convert:nnn {#1} { gray } { rgb } + \__color_model_devicen_convert:nnnn {#1} { gray } { 1 } {#2} + } +\cs_new_protected:Npn \__color_model_devicen_convert_rgb:nn #1#2 + { + \__color_model_convert:nnn {#1} { rgb } { cmyk } + \__color_model_convert:nnn {#1} { rgb } { gray } + \__color_model_devicen_convert:nnnn {#1} { rgb } { 3 } {#2} + } +\cs_new_protected:Npn \__color_model_devicen_convert:nnnn #1#2#3#4 + { + \cs_new:cpx { __color_convert_ #1 _ #2 :w } ##1 \s__color_stop + { + \exp_not:c { __color_convert_devicen_ #2 : \prg_replicate:nn {#3} { n } w } + \prg_replicate:nn {#3} { { 1 } } + ##1 \exp_not:N \s__color_mark + \clist_map_function:nN {#4} \__color_model_devicen_convert:n + \exp_not:N \s__color_stop + } + } +\cs_new:Npn \__color_model_devicen_convert:n #1 + { + { + \exp_args:Ne \__color_model_devicen_convert_aux:n + { \prop_item:Nn \g__color_alternative_values_prop {#1} } + } + } +\cs_new:Npn \__color_model_devicen_convert_aux:n #1 + { \__color_model_devicen_convert_aux:w #1 , , , , \s__color_stop } +\cs_new:Npn \__color_model_devicen_convert_aux:w #1 , #2 , #3 , #4 , #5 \s__color_stop + { + {#1} + \tl_if_blank:nF {#2} + { + {#2} + \tl_if_blank:nF {#3} + { + {#3} + \tl_if_blank:nF {#4} { {#4} } + } + } + } +\cs_new:Npn \__color_convert_devicen_cmyk:nnnnw + #1#2#3#4#5 ~ #6 \s__color_mark #7#8 \s__color_stop + { + \__color_convert_devicen_cmyk:nnnnnnnnn {#5} {#1} {#2} {#3} {#4} #7 + #6 \s__color_mark #8 \s__color_stop + } +\cs_new:Npn \__color_convert_devicen_cmyk:nnnnnnnnn #1#2#3#4#5#6#7#8#9 + { + \use:e + { + \exp_not:N \__color_convert_devicen_cmyk_aux:nnnnw + { \fp_eval:n { #2 * (1 - (#1 * #6)) } } + { \fp_eval:n { #3 * (1 - (#1 * #7)) } } + { \fp_eval:n { #4 * (1 - (#1 * #8)) } } + { \fp_eval:n { #5 * (1 - (#1 * #9)) } } + } + } +\cs_new:Npn \__color_convert_devicen_cmyk_aux:nnnnw + #1#2#3#4 #5 \s__color_mark #6 \s__color_stop + { + \tl_if_blank:nTF {#5} + { + \fp_eval:n { 1 - #1 } ~ + \fp_eval:n { 1 - #2 } ~ + \fp_eval:n { 1 - #3 } ~ + \fp_eval:n { 1 - #4 } + } + { + \__color_convert_devicen_cmyk:nnnnw {#1} {#2} {#3} {#4} + #5 \s__color_mark #6 \s__color_stop + } + } +\cs_new:Npn \__color_convert_devicen_gray:nw + #1#2 ~ #3 \s__color_mark #4#5 \s__color_stop + { + \__color_convert_devicen_gray:nnn {#2} {#1} #4 + #3 \s__color_mark #5 \s__color_stop + } +\cs_new:Npn \__color_convert_devicen_gray:nnn #1#2#3 + { + \exp_arsgs:Ne \__color_convert_devicen_gray_aux:nw + { \fp_eval:n { #2 * (1 - (#1 * #3)) } } + } +\cs_new:Npn \__color_convert_devicen_gray_aux:nw + #1 #2 \s__color_mark #3 \s__color_stop + { + \tl_if_blank:nTF {#2} + { \fp_eval:n { 1 - #1 } } + { + \__color_convert_devicen_gray:nw {#1} + #2 \s__color_mark #3 \s__color_stop + } + } +\cs_new:Npn \__color_convert_devicen_rgb:nnnw + #1#2#3#4 ~ #5 \s__color_mark #6#7 \s__color_stop + { + \__color_convert_devicen_cmyk:nnnnnn {#4} {#1} {#2} {#3} #6 + #5 \s__color_mark #7 \s__color_stop + } +\cs_new:Npn \__color_convert_devicen_rgb:nnnnnnn #1#2#3#4#5#6#7 + { + \use:e + { + \exp_not:N \__color_convert_devicen_rgb_aux:nnnw + { \fp_eval:n { #2 * (1 - (#1 * #5)) } } + { \fp_eval:n { #3 * (1 - (#1 * #6)) } } + { \fp_eval:n { #4 * (1 - (#1 * #7)) } } + } + } +\cs_new:Npn \__color_convert_devicen_rgb_aux:nnnw + #1#2#3 #4 \s__color_mark #5 \s__color_stop + { + \tl_if_blank:nTF {#4} + { + \fp_eval:n { 1 - #1 } ~ + \fp_eval:n { 1 - #2 } ~ + \fp_eval:n { 1 - #3 } + } + { + \__color_convert_devicen_rgb:nnnw {#1} {#2} {#3} + #4 \s__color_mark #5 \s__color_stop + } + } +\cs_new_protected:Npn \color_show:n #1 + { + \msg_show:nnxxxx { LaTeX / color } { show } + {#1} + { + \__color_if_defined:nT {#1} + { + \exp_args:Nv \__color_show:n { l__color_named_ #1 _tl } + \prop_map_function:cN + { l__color_named_ #1 _prop } + \msg_show_item_unbraced:nn + } + } + { } + { } + } +\cs_new:Npn \__color_show:n #1 + { + \msg_show_item_unbraced:nn { model } {#1} + } +\__kernel_msg_new:nnnn { color } { CIELAB-requires-illuminant } + { CIELAB~color~space~'#1'~require~an~illuminant. } + { + LaTeX~has~been~asked~to~create~a~separation~color~space~using~ + CIELAB~specifications,~but~no~\\ \\ + \iow_indent:n { illuminant~=~ } + \\ \\ + key~was~given~with~the~correct~information.~LaTeX~will~use~illuminant~ + 'd50'~for~recovery. + } +\__kernel_msg_new:nnnn { color } { conversion-not-available } + { No~model~conversion~available~from~'#1'~to~'#2'. } + { + LaTeX~has~been~asked~to~convert~a~color~from~model~'#1'~ + to~model'#2',~but~there~is~no~method~available~to~do~that. + } +\__kernel_msg_new:nnnn { color } { DeviceN-inconsistent-alternative } + { DeviceN~color~spaces~require~a~single~alternative~space. } + { + LaTeX~has~been~asked~to~create~a~DeviceN~color~space~'#1',~ + but~the~constituent~colors~do~not~have~a~common~alternative~ + color. + } +\__kernel_msg_new:nnnn { color } { DeviceN-no-alternative } + { DeviceN~color~spaces~require~an~alternative~space. } + { + LaTeX~has~been~asked~to~create~a~DeviceN~color~space~'#1',~ + but~the~constituent~colors~do~not~all~have~a~device-based~alternative. + } +\__kernel_msg_new:nnnn { color } { DeviceN-requires-names } + { DeviceN~color~space~'#1'~require~a~list~of~names. } + { + LaTeX~has~been~asked~to~create~a~DeviceN~color~space,~ + but~no~\\ \\ + \iow_indent:n { names~=~ } + \\ \\ + key~was~given~with~the~correct~information. + } +\__kernel_msg_new:nnnn { color } { model-already-defined } + { Color~model~'#1'~already~defined. } + { + LaTeX~was~asked~to~define~a~new~color~model~called~'#1',~but~ + this~color~model~already~exists. + } +\__kernel_msg_new:nnnn { color } { separation-alternative-model } + { Separation~color~space~'#1'~require~an~alternative~model. } + { + LaTeX~has~been~asked~to~create~a~separation~color~space,~ + but~no~\\ \\ + \iow_indent:n { alternative-model~=~ } + \\ \\ + key~was~given~with~the~correct~information. + } +\__kernel_msg_new:nnnn { color } { separation-alternative-values } + { Separation~color~space~'#1'~require~values~for~the~alternative~space. } + { + LaTeX~has~been~asked~to~create~a~separation~color~space,~ + but~no~\\ \\ + \iow_indent:n { alternative-values~=~ } + \\ \\ + key~was~given~with~the~correct~information. + } +\__kernel_msg_new:nnnn { color } { separation-requires-name } + { Separation~color~space~'#1'~require~a~formal~name. } + { + LaTeX~has~been~asked~to~create~a~separation~color~space,~ + but~no~\\ \\ + \iow_indent:n { name~=~ } + \\ \\ + key~was~given~with~the~correct~information. + } +\__kernel_msg_new:nnnn { color } { unknown-color } + { Unknown~color~'#1'. } + { + LaTeX~has~been~asked~to~use~a~color~named~'#1',~ + but~this~has~never~been~defined. + } +\__kernel_msg_new:nnnn { color } { unknown-alternative-model } + { Separation~color~space~'#1'~require~an~valid~alternative~space. } + { + LaTeX~has~been~asked~to~create~a~separation~color~space,~ + but~the~model~given~as\\ \\ + \iow_indent:n { alternative-model~=~ } + \\ \\ + is~unknown. + } +\__kernel_msg_new:nnnn { color } { unknown-export-format } + { Unknown~export~format~'#1'. } + { + LaTeX~has~been~asked~to~export~a~color~in~format~'#1',~ + but~this~has~never~been~defined. + } +\__kernel_msg_new:nnnn { color } { unknown-CIELAB-illuminant } + { Unknown~illuminant~model~'#1'. } + { + LaTeX~has~been~asked~to~use~create~a~color~space~using~CIELAB~ + illuminant~'#1',~but~this~does~not~exist. + } +\__kernel_msg_new:nnnn { color } { unknown-model } + { Unknown~color~model~'#1'. } + { + LaTeX~has~been~asked~to~use~a~color~model~called~'#1',~ + but~this~model~is~not~set~up. + } +\__kernel_msg_new:nnnn { color } { unknown-model-type } + { Unknown~color~model~type~'#1'. } + { + LaTeX~has~been~asked~to~create~a~new~color~model~called~'#1',~ + but~this~type~of~model~was~never~set~up. + } +\__kernel_msg_new:nnn { color } { show } + { + The~color~#1~ + \tl_if_empty:nTF {#2} + { is~undefined. } + { has~the~properties: #2 } + } +%% File: l3pdf.dtx +\scan_new:N \s__pdf_stop +\bool_new:N \g__pdf_init_bool +\bool_lazy_and:nnT + { \str_if_eq_p:Vn \fmtname { LaTeX2e } } + { \tl_if_exist_p:N \@expl@finalise@setup@@ } + { + \tl_gput_right:Nn \@expl@finalise@setup@@ + { + \tl_gput_right:Nn \@kernel@after@begindocument + { \bool_gset_true:N \g__pdf_init_bool } + } + } +\cs_new_protected:Npn \pdf_uncompress: + { + \bool_if:NF \g__pdf_init_bool + { + \__pdf_backend_compresslevel:n { 0 } + \__pdf_backend_compress_objects:n { \c_false_bool } + } + } +\cs_new_protected:Npn \pdf_object_new:nn #1#2 + { \__pdf_backend_object_new:nn {#1} {#2} } +\prg_new_conditional:Npnn \pdf_object_if_exist:n #1 { p , T , F , TF } + { + \int_if_exist:cTF { c__pdf_backend_object_ \tl_to_str:n {#1} _int } + { \prg_return_true: } + { \prg_return_false:} + } +\cs_new_protected:Npn \pdf_object_write:nn #1#2 + { + \__pdf_backend_object_write:nn {#1} {#2} + \bool_gset_true:N \g__pdf_init_bool + } +\cs_generate_variant:Nn \pdf_object_write:nn { nx } +\cs_new:Npn \pdf_object_ref:n #1 { \__pdf_backend_object_ref:n {#1} } +\cs_new_protected:Npn \pdf_object_unnamed_write:nn #1#2 + { + \__pdf_backend_object_now:nn {#1} {#2} + \bool_gset_true:N \g__pdf_init_bool + } +\cs_generate_variant:Nn \pdf_object_unnamed_write:nn { nx } +\cs_new:Npn \pdf_object_ref_last: { \__pdf_backend_object_last: } +\cs_new:Npn \pdf_pageobject_ref:n #1 + { \__pdf_backend_pageobject_ref:n {#1} } +\prg_new_conditional:Npnn \pdf_version_compare:Nn #1#2 { p , T , F , TF } + { \use:c { __pdf_version_compare_ #1 :w } #2 . . \s__pdf_stop } +\cs_new:cpn { __pdf_version_compare_=:w } #1 . #2 . #3 \s__pdf_stop + { + \bool_lazy_and:nnTF + { \int_compare_p:nNn \__pdf_backend_version_major: = {#1} } + { \int_compare_p:nNn \__pdf_backend_version_minor: = {#2} } + { \prg_return_true: } + { \prg_return_false: } + } +\cs_new:cpn { __pdf_version_compare_<:w } #1 . #2 . #3 \s__pdf_stop + { + \bool_lazy_or:nnTF + { \int_compare_p:nNn \__pdf_backend_version_major: < {#1} } + { + \bool_lazy_and_p:nn + { \int_compare_p:nNn \__pdf_backend_version_major: = {#1} } + { \int_compare_p:nNn \__pdf_backend_version_minor: < {#2} } + } + { \prg_return_true: } + { \prg_return_false: } + } +\cs_new:cpn { __pdf_version_compare_>:w } #1 . #2 . #3 \s__pdf_stop + { + \bool_lazy_or:nnTF + { \int_compare_p:nNn \__pdf_backend_version_major: > {#1} } + { + \bool_lazy_and_p:nn + { \int_compare_p:nNn \__pdf_backend_version_major: = {#1} } + { \int_compare_p:nNn \__pdf_backend_version_minor: > {#2} } + } + { \prg_return_true: } + { \prg_return_false: } + } +\cs_new_protected:Npn \pdf_version_gset:n #1 + { \__pdf_version_gset:w #1 . . \s__pdf_stop } +\cs_new_protected:Npn \pdf_version_min_gset:n #1 + { + \pdf_version_compare:NnT < {#1} + { \__pdf_version_gset:w #1 . . \s__pdf_stop } + } +\cs_new_protected:Npn \__pdf_version_gset:w #1 . #2 . #3\s__pdf_stop + { + \bool_if:NF \g__pdf_init_bool + { + \__pdf_backend_version_major_gset:n {#1} + \__pdf_backend_version_minor_gset:n {#2} + } + } +\cs_new:Npn \pdf_version: + { \__pdf_backend_version_major: . \__pdf_backend_version_minor: } +\cs_new:Npn \pdf_version_major: { \__pdf_backend_version_major: } +\cs_new:Npn \pdf_version_minor: { \__pdf_backend_version_minor: } +\cs_new_protected:Npn \pdf_destination:nn #1#2 + { \__pdf_backend_destination:nn {#1} {#2} } +\cs_new_protected:Npn \pdf_destination:nnnn #1#2#3#4 + { + \hbox_to_zero:n + { \__pdf_backend_destination:nnnn {#1} {#2} {#3} {#4} } + } +%% File: l3coffins.dtx +\box_new:N \l__coffin_internal_box +\dim_new:N \l__coffin_internal_dim +\tl_new:N \l__coffin_internal_tl +\prop_const_from_keyval:Nn \c__coffin_corners_prop + { + tl = { 0pt } { 0pt } , + tr = { 0pt } { 0pt } , + bl = { 0pt } { 0pt } , + br = { 0pt } { 0pt } , + } +\prop_const_from_keyval:Nn \c__coffin_poles_prop + { + l = { 0pt } { 0pt } { 0pt } { 1000pt } , + hc = { 0pt } { 0pt } { 0pt } { 1000pt } , + r = { 0pt } { 0pt } { 0pt } { 1000pt } , + b = { 0pt } { 0pt } { 1000pt } { 0pt } , + vc = { 0pt } { 0pt } { 1000pt } { 0pt } , + t = { 0pt } { 0pt } { 1000pt } { 0pt } , + B = { 0pt } { 0pt } { 1000pt } { 0pt } , + H = { 0pt } { 0pt } { 1000pt } { 0pt } , + T = { 0pt } { 0pt } { 1000pt } { 0pt } , + } +\fp_new:N \l__coffin_slope_A_fp +\fp_new:N \l__coffin_slope_B_fp +\bool_new:N \l__coffin_error_bool +\dim_new:N \l__coffin_offset_x_dim +\dim_new:N \l__coffin_offset_y_dim +\tl_new:N \l__coffin_pole_a_tl +\tl_new:N \l__coffin_pole_b_tl +\dim_new:N \l__coffin_x_dim +\dim_new:N \l__coffin_y_dim +\dim_new:N \l__coffin_x_prime_dim +\dim_new:N \l__coffin_y_prime_dim +\cs_new_eq:NN \__coffin_to_value:N \tex_number:D +\prg_new_conditional:Npnn \coffin_if_exist:N #1 { p , T , F , TF } + { + \cs_if_exist:NTF #1 + { + \cs_if_exist:cTF { coffin ~ \__coffin_to_value:N #1 ~ poles } + { \prg_return_true: } + { \prg_return_false: } + } + { \prg_return_false: } + } +\prg_generate_conditional_variant:Nnn \coffin_if_exist:N + { c } { p , T , F , TF } +\cs_new_protected:Npn \__coffin_if_exist:NT #1#2 + { + \coffin_if_exist:NTF #1 + { #2 } + { + \__kernel_msg_error:nnx { kernel } { unknown-coffin } + { \token_to_str:N #1 } + } + } +\cs_new_protected:Npn \coffin_clear:N #1 + { + \__coffin_if_exist:NT #1 + { + \box_clear:N #1 + \__coffin_reset_structure:N #1 + } + } +\cs_generate_variant:Nn \coffin_clear:N { c } +\cs_new_protected:Npn \coffin_gclear:N #1 + { + \__coffin_if_exist:NT #1 + { + \box_gclear:N #1 + \__coffin_greset_structure:N #1 + } + } +\cs_generate_variant:Nn \coffin_gclear:N { c } +\cs_new_protected:Npn \coffin_new:N #1 + { + \box_new:N #1 + \debug_suspend: + \prop_gclear_new:c { coffin ~ \__coffin_to_value:N #1 ~ corners } + \prop_gclear_new:c { coffin ~ \__coffin_to_value:N #1 ~ poles } + \prop_gset_eq:cN { coffin ~ \__coffin_to_value:N #1 ~ corners } + \c__coffin_corners_prop + \prop_gset_eq:cN { coffin ~ \__coffin_to_value:N #1 ~ poles } + \c__coffin_poles_prop + \debug_resume: + } +\cs_generate_variant:Nn \coffin_new:N { c } +\cs_new_protected:Npn \hcoffin_set:Nn #1#2 + { + \__coffin_if_exist:NT #1 + { + \hbox_set:Nn #1 + { + \color_ensure_current: + #2 + } + \__coffin_update:N #1 + } + } +\cs_generate_variant:Nn \hcoffin_set:Nn { c } +\cs_new_protected:Npn \hcoffin_gset:Nn #1#2 + { + \__coffin_if_exist:NT #1 + { + \hbox_gset:Nn #1 + { + \color_ensure_current: + #2 + } + \__coffin_gupdate:N #1 + } + } +\cs_generate_variant:Nn \hcoffin_gset:Nn { c } +\cs_new_protected:Npn \vcoffin_set:Nnn #1#2#3 + { + \__coffin_set_vertical:NnnNN #1 {#2} {#3} + \vbox_set:Nn \__coffin_update:N + } +\cs_generate_variant:Nn \vcoffin_set:Nnn { c } +\cs_new_protected:Npn \vcoffin_gset:Nnn #1#2#3 + { + \__coffin_set_vertical:NnnNN #1 {#2} {#3} + \vbox_gset:Nn \__coffin_gupdate:N + } +\cs_generate_variant:Nn \vcoffin_gset:Nnn { c } +\cs_new_protected:Npn \__coffin_set_vertical:NnnNN #1#2#3#4#5 + { + \__coffin_if_exist:NT #1 + { + #4 #1 + { + \dim_set:Nn \tex_hsize:D {#2} + \__coffin_set_vertical_aux: + #3 + } + #5 #1 + \vbox_set_top:Nn \l__coffin_internal_box { \vbox_unpack:N #1 } + \__coffin_set_pole:Nnx #1 { T } + { + { 0pt } + { + \dim_eval:n + { \box_ht:N #1 - \box_ht:N \l__coffin_internal_box } + } + { 1000pt } + { 0pt } + } + \box_clear:N \l__coffin_internal_box + } + } +\cs_new_protected:Npx \__coffin_set_vertical_aux: + { + \bool_lazy_and:nnT + { \cs_if_exist_p:N \fmtname } + { \str_if_eq_p:Vn \fmtname { LaTeX2e } } + { + \dim_set_eq:NN \exp_not:N \linewidth \tex_hsize:D + \dim_set_eq:NN \exp_not:N \columnwidth \tex_hsize:D + } + } +\cs_new_protected:Npn \hcoffin_set:Nw #1 + { + \__coffin_if_exist:NT #1 + { + \hbox_set:Nw #1 \color_ensure_current: + \cs_set_protected:Npn \hcoffin_set_end: + { + \hbox_set_end: + \__coffin_update:N #1 + } + } + } +\cs_generate_variant:Nn \hcoffin_set:Nw { c } +\cs_new_protected:Npn \hcoffin_gset:Nw #1 + { + \__coffin_if_exist:NT #1 + { + \hbox_gset:Nw #1 \color_ensure_current: + \cs_set_protected:Npn \hcoffin_gset_end: + { + \hbox_gset_end: + \__coffin_gupdate:N #1 + } + } + } +\cs_generate_variant:Nn \hcoffin_gset:Nw { c } +\cs_new_protected:Npn \hcoffin_set_end: { } +\cs_new_protected:Npn \hcoffin_gset_end: { } +\cs_new_protected:Npn \vcoffin_set:Nnw #1#2 + { + \__coffin_set_vertical:NnNNNNw #1 {#2} \vbox_set:Nw + \vcoffin_set_end: + \vbox_set_end: \__coffin_update:N + } +\cs_generate_variant:Nn \vcoffin_set:Nnw { c } +\cs_new_protected:Npn \vcoffin_gset:Nnw #1#2 + { + \__coffin_set_vertical:NnNNNNw #1 {#2} \vbox_gset:Nw + \vcoffin_gset_end: + \vbox_gset_end: \__coffin_gupdate:N + } +\cs_generate_variant:Nn \vcoffin_gset:Nnw { c } +\cs_new_protected:Npn \__coffin_set_vertical:NnNNNNw #1#2#3#4#5#6 + { + \__coffin_if_exist:NT #1 + { + #3 #1 + \dim_set:Nn \tex_hsize:D {#2} + \__coffin_set_vertical_aux: \cs_set_protected:Npn #4 { #5 @@ -28276,26 +29818,6 @@ \tl_set:Nn \l__coffin_display_font_tl { \sffamily \tiny } } -\cs_new_protected:Npn \__coffin_color:n #1 {#1} -\bool_lazy_and:nnT - { \cs_if_exist_p:N \fmtname } - { \str_if_eq_p:Vn \fmtname { LaTeX2e } } - { - \cs_gset_protected:Npn \__coffin_color:n - { - \cs_gset_protected:Npx \__coffin_color:n - { - \cs_if_exist:NTF \color_select:n - { \color_select:n } - { - \cs_if_exist:NTF \color - { \exp_not:N \color } - { \exp_not:N \use_none:n } - } - } - \__coffin_color:n - } - } \cs_new_protected:Npn \__coffin_rule:nn #1#2 { \mode_leave_vertical: @@ -28305,14 +29827,14 @@ { \hcoffin_set:Nn \l__coffin_display_pole_coffin { - \__coffin_color:n {#4} + \color_select:n {#4} \__coffin_rule:nn { 1pt } { 1pt } } \__coffin_attach_mark:NnnNnnnn #1 {#2} {#3} \l__coffin_display_pole_coffin { hc } { vc } { 0pt } { 0pt } \hcoffin_set:Nn \l__coffin_display_coord_coffin { - \__coffin_color:n {#4} + \color_select:n {#4} \l__coffin_display_font_tl ( \tl_to_str:n { #2 , #3 } ) } @@ -28350,7 +29872,7 @@ { \hcoffin_set:Nn \l__coffin_display_pole_coffin { - \__coffin_color:n {#2} + \color_select:n {#2} \__coffin_rule:nn { 1pt } { 1pt } } \prop_set_eq:Nc \l__coffin_display_poles_prop @@ -28385,7 +29907,7 @@ { 0pt } { 0pt } \hcoffin_set:Nn \l__coffin_display_coord_coffin { - \__coffin_color:n {#6} + \color_select:n {#6} \l__coffin_display_font_tl ( \tl_to_str:n { #1 , ##1 } ) } diff --git a/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex b/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex index 70187f40fed..2ef8b11ca39 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex +++ b/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex @@ -19,7 +19,7 @@ %% and all files in that bundle must be distributed together. %% %% File: expl3.dtx -\def\ExplFileDate{2021-02-06}% +\def\ExplFileDate{2021-02-18}% \let\ExplLoaderFileDate\ExplFileDate \begingroup \catcode`\_=11 diff --git a/Master/texmf-dist/tex/latex/l3kernel/expl3.ltx b/Master/texmf-dist/tex/latex/l3kernel/expl3.ltx index a48a7176333..e28a59c89d8 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/expl3.ltx +++ b/Master/texmf-dist/tex/latex/l3kernel/expl3.ltx @@ -19,7 +19,7 @@ %% and all files in that bundle must be distributed together. %% %% File: expl3.dtx -\def\ExplFileDate{2021-02-06}% +\def\ExplFileDate{2021-02-18}% \let\ExplLoaderFileDate\ExplFileDate \begingroup \catcode`\_=11 diff --git a/Master/texmf-dist/tex/latex/l3kernel/expl3.sty b/Master/texmf-dist/tex/latex/l3kernel/expl3.sty index a02edb0c28c..01e190e9176 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/expl3.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/expl3.sty @@ -19,7 +19,7 @@ %% and all files in that bundle must be distributed together. %% %% File: expl3.dtx -\def\ExplFileDate{2021-02-06}% +\def\ExplFileDate{2021-02-18}% \let\ExplLoaderFileDate\ExplFileDate \ProvidesPackage{expl3} [% -- cgit v1.2.3