[latex3-commits] [git/LaTeX3-latex3-latex3] color-export: Add \color_export:nn(n)N (f95844e7f)

Joseph Wright joseph.wright at morningstar2.co.uk
Thu Jul 16 12:15:52 CEST 2020


Repository : https://github.com/latex3/latex3
On branch  : color-export
Link       : https://github.com/latex3/latex3/commit/f95844e7fa7835bf23186054e9d0fd7b4179ccdc

>---------------------------------------------------------------

commit f95844e7fa7835bf23186054e9d0fd7b4179ccdc
Author: Joseph Wright <joseph.wright at morningstar2.co.uk>
Date:   Thu Jul 16 11:15:45 2020 +0100

    Add \color_export:nn(n)N


>---------------------------------------------------------------

f95844e7fa7835bf23186054e9d0fd7b4179ccdc
 l3experimental/CHANGELOG.md                     |   3 +
 l3experimental/l3color/l3color.dtx              | 178 +++++++++++++++++++++---
 l3experimental/l3color/testfiles/m3color002.lvt |  24 ++++
 l3experimental/l3color/testfiles/m3color002.tlg |  62 +++++++++
 l3experimental/l3draw/l3draw-state.dtx          |   2 +-
 5 files changed, 250 insertions(+), 19 deletions(-)

diff --git a/l3experimental/CHANGELOG.md b/l3experimental/CHANGELOG.md
index e2a9f4e14..7f3d5d432 100644
--- a/l3experimental/CHANGELOG.md
+++ b/l3experimental/CHANGELOG.md
@@ -7,6 +7,9 @@ this project uses date-based 'snapshot' version identifiers.
 
 ## [Unreleased]
 
+### Added
+- `\color_export:nn(n)N` (see #742)
+
 ### Removed
 
 - `l3cctab`: moved to `l3kernel`
diff --git a/l3experimental/l3color/l3color.dtx b/l3experimental/l3color/l3color.dtx
index 8a87d390b..af83ad02b 100644
--- a/l3experimental/l3color/l3color.dtx
+++ b/l3experimental/l3color/l3color.dtx
@@ -237,23 +237,44 @@
 %   and similar are not influenced by this setting.
 % \end{variable}
 %
-% \section{Core color representation}
+% \section{Exporting color specifications}
 %
-% To allow data to be handled internally, \pkg{l3color} uses a simple
-% representation of color, comprising two \meta{balanced text} entries, the first
-% the \meta{model} and the second the \meta{values} given
-% \emph{separated by spaces}.
+% 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.
 %
-% This core representation is produced when parsing color expressions.
+% 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_parse:nN}
+% \begin{function}{\color_export:nnN}
 %   \begin{syntax}
-%     \cs{color_parse:nN} \Arg{color expression} \Arg{tl}
+%     \cs{color_export:nnnN} \Arg{model} \Arg{value(s)} \Arg{format} \Arg{tl}
 %   \end{syntax}
-%   Parses the \meta{color expression} as described above, and sets the
-%   \meta{tl} to the equivalent \meta{core color representation}
-%   (used at the backend level and based on \texttt{dvips} color
-%   representation).
+%   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{Spot colors}
@@ -442,8 +463,8 @@
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{macro}{\color_parse:nN}
 % \begin{macro}{\@@_parse:nN}
+% \begin{macro}{\@@_parse_aux:nN}
 % \begin{macro}{\@@_parse:Nw}
 % \begin{macro}{\@@_parse_loop_init:Nnn}
 % \begin{macro}{\@@_parse_loop:w}
@@ -462,20 +483,20 @@
 %   otherwise expands, then starts working through the expression itself.
 %   At the end, we apply the payload.
 %    \begin{macrocode}
-\cs_new_protected:Npn \color_parse:nN #1#2
+\cs_new_protected:Npn \@@_parse:nN #1#2
   {
 %<*package>
     \@@_backend_pickup:N \l_@@_current_tl
     \tl_set_eq:cN { l_@@_named_ . _tl } \l_@@_current_tl
 %</package>
-    \exp_args:Ne \@@_parse:nN { \tl_to_str:n {#1} } #2
+    \exp_args:Ne \@@_parse_aux:nN { \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:nN #1#2
+\cs_new_protected:Npn \@@_parse_aux:nN #1#2
   {
     \tl_if_exist:cTF { l_@@_named_ #1 _tl }
       { \tl_set_eq:Nc #2 { l_@@_named_ #1 _tl } }
@@ -829,7 +850,7 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \color_select:n #1
   {
-    \color_parse:nN {#1} \l_@@_current_tl
+    \@@_parse:nN {#1} \l_@@_current_tl
     \@@_select:
   }
 \cs_new_protected:Npn \color_select:nn #1#2
@@ -892,7 +913,7 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \color_set:nn #1#2
   {
-    \color_parse:nN {#2} \l_@@_named_tl
+    \@@_parse:nN {#2} \l_@@_named_tl
     \@@_store:Nn \l_@@_named_tl {#1}
   }
 \cs_new_protected:Npn \color_set:nnn #1#2#3
@@ -942,6 +963,121 @@
 %    \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
+  {
+    \@@_parse:nN {#1} #3
+    \@@_export:nN {#2} #3
+  }
+\cs_new_protected:Npn \color_export:nnnN #1#2#3#4
+  {
+    \@@_direct:nnN {#1} {#2} #4
+    \@@_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{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{Diagnostics}
 %
 % \begin{macro}{\color_show:n}
@@ -979,6 +1115,12 @@
     LaTeX~has~been~asked~to~use~a~color~named~'#1',~
     but~this~has~never~been~defined.
   }
+\__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-model }
   { Unknown~color~model~'#1'. }
   {
diff --git a/l3experimental/l3color/testfiles/m3color002.lvt b/l3experimental/l3color/testfiles/m3color002.lvt
index 3dec4335b..a2ad42cf5 100644
--- a/l3experimental/l3color/testfiles/m3color002.lvt
+++ b/l3experimental/l3color/testfiles/m3color002.lvt
@@ -48,4 +48,28 @@
     \color_show:n { foo2 }
   }
 
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\TEST { Exporting~colors }
+  {
+    \clist_map_inline:nn
+      { backend , HTML , space-sep-cmyk , space-sep-rgb }
+      {
+        \color_export:nnN { blue } {#1} \l_tmpa_tl
+        \tl_show:N \l_tmpa_tl
+        \color_export:nnN { blue!50!red } {#1} \l_tmpa_tl
+        \tl_show:N \l_tmpa_tl
+        \color_export:nnN { cyan } {#1} \l_tmpa_tl
+        \tl_show:N \l_tmpa_tl
+        \color_export:nnnN { gray } { 0.6 } {#1} \l_tmpa_tl
+        \tl_show:N \l_tmpa_tl
+      }
+  }
+
+\TEST { Exporting~color:~errors }
+  {
+    \color_export:nnnN { gray } { 0.6 } { mumble } \l_tmpa_tl
+  }
+
 \END
diff --git a/l3experimental/l3color/testfiles/m3color002.tlg b/l3experimental/l3color/testfiles/m3color002.tlg
index 186c4b163..cd750a052 100644
--- a/l3experimental/l3color/testfiles/m3color002.tlg
+++ b/l3experimental/l3color/testfiles/m3color002.tlg
@@ -66,3 +66,65 @@ The color foo2 has the properties:
 <recently read> }
 l. ...  }
 ============================================================
+============================================================
+TEST 3: Exporting colors
+============================================================
+> \l_tmpa_tl={rgb}{0.0 0.0 1.0}.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl={rgb}{0.5 0 0.5}.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl={cmyk}{1.0 0.0 0.0 0.0}.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl={gray}{0.6}.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl=0000FF.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl=800080.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl=00FFFF.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl=999999.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl=1 1 0 0.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl=0 0.5 0 0.5.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl=1.0 0.0 0.0 0.0.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl=0 0 0 0.4.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl=0.0 0.0 1.0.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl=0.5 0 0.5.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl=0 1 1.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl=0.6 0.6 0.6.
+<recently read> }
+l. ...  }
+============================================================
+============================================================
+TEST 4: Exporting color: errors
+============================================================
+! LaTeX3 Error: Unknown export format 'mumble'.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+LaTeX has been asked to export a color in format 'mumble', but this has never
+been defined.
+============================================================
diff --git a/l3experimental/l3draw/l3draw-state.dtx b/l3experimental/l3draw/l3draw-state.dtx
index 4f434d924..ca0dcd90c 100644
--- a/l3experimental/l3draw/l3draw-state.dtx
+++ b/l3experimental/l3draw/l3draw-state.dtx
@@ -167,7 +167,7 @@
   { \@@_color:nn { stroke } {#1} }
 \cs_new_protected:Npn \@@_color:nn #1#2
   {
-    \color_parse:nN {#2} \l_@@_color_tmp_tl
+    \color_export:nnN {#2} { backend } \l_@@_color_tmp_tl
     \exp_after:wN \@@_color:nnn \l_@@_color_tmp_tl {#1}
   }
 \cs_new_protected:Npn \@@_color:nnn #1#2#3





More information about the latex3-commits mailing list.