[latex3-commits] [git/LaTeX3-latex3-latex3] master: xbox: Include picture mode support (3168cb08e)

Joseph Wright joseph.wright at morningstar2.co.uk
Mon Aug 24 12:49:00 CEST 2020


Repository : https://github.com/latex3/latex3
On branch  : master
Link       : https://github.com/latex3/latex3/commit/3168cb08ea4d7c5d986a9cb92eab59a648093bbc

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

commit 3168cb08ea4d7c5d986a9cb92eab59a648093bbc
Author: Joseph Wright <joseph.wright at morningstar2.co.uk>
Date:   Mon Aug 24 11:49:00 2020 +0100

    xbox: Include picture mode support


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

3168cb08ea4d7c5d986a9cb92eab59a648093bbc
 l3trial/xbox/xbox.dtx | 206 +++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 179 insertions(+), 27 deletions(-)

diff --git a/l3trial/xbox/xbox.dtx b/l3trial/xbox/xbox.dtx
index bee07c76c..d9e2aa21d 100644
--- a/l3trial/xbox/xbox.dtx
+++ b/l3trial/xbox/xbox.dtx
@@ -77,6 +77,7 @@
 % \begin{function}{\makebox}
 %   \begin{syntax}
 %     \cs{makebox}\oarg{width}\oarg{position}\marg{content}
+%     \cs{makebox}\parg{coords}\oarg{position}\marg{content}
 %   \end{syntax}
 %   Typesets the \meta{content} in a horizontal mode inserted at the current
 %   reference point. Line breaks will not occur, and any \cs{par} tokens in
@@ -91,6 +92,17 @@
 %     \item[s] interword space stretched or shrunk to fill the \meta{width}
 %       (if possible),
 %   \end{itemize}
+%
+%   When the \meta{coords} are given as a picture-mode command, the
+%   \meta{contents} are inserted with width and height \cs{unitlength}
+%   times the (integer) \meta{x} and \meta{y} values, respectively. If \meta{x}
+%   or \meta{y} are given with units, they are used as-is. In this case, the
+%   \meta{position} may also take
+%   \begin{itemize}
+%     \item[t] aligned with the top of the content
+%     \item[b] aligned with the bottom of the content
+%   \end{itemize}
+%   and if neither are given is vertically centered.
 % \end{function}
 %
 % \begin{function}{\raisebox}
@@ -137,6 +149,7 @@
 % \begin{function}{\framebox}
 %   \begin{syntax}
 %     \cs{framebox}\oarg{width}\oarg{position}\marg{content}
+%     \cs{framebox}\parg{coords}\oarg{position}\marg{content}
 %   \end{syntax}
 %   Typesets the \meta{content} in a horizontal mode inserted at the current
 %   reference point. Line breaks will not occur, and any \cs{par} tokens in
@@ -156,6 +169,19 @@
 %   \cs{fboxrule}. The final size of the typeset material includes the border
 %   and frame, although calculations using \cs{height}, \emph{etc.}, use only
 %   the natural size of the \meta{content}.
+%
+%   When the \meta{coords} are given as a picture-mode command, the
+%   \meta{contents} are inserted with width and height \cs{unitlength}
+%   times the (integer) \meta{x} and \meta{y} values, respectively. If \meta{x}
+%   or \meta{y} are given with units, they are used as-is. In this case, the
+%   \meta{position} may also take
+%   \begin{itemize}
+%     \item[t] aligned with the top of the content
+%     \item[b] aligned with the bottom of the content
+%   \end{itemize}
+%   and if neither are given is vertically centered. The picture-mode version
+%   uses no \meta{border} and uses the picture-mode linewidth rather than
+%   \cs{fboxrule}.
 % \end{function}
 %
 % \section{Saving material in boxes}
@@ -189,6 +215,7 @@
 % \begin{function}{\savebox}
 %   \begin{syntax}
 %     \cs{savebox}\marg{box}\oarg{width}\oarg{position}\marg{content}
+%     \cs{savebox}\marg{box}\parg{coords}\oarg{position}\marg{content}
 %   \end{syntax}
 %   Works in a manner analogous to \cs{makebox} but saves the result in
 %   a \meta{box} rather than inserting it into the current output.
@@ -244,12 +271,13 @@
 %
 % \section{Code-level interfaces}
 %
-% \begin{function}{\xbox_to_wd:nnn}
+% \begin{function}{\xbox_to_wd:nnn, \xbox_to_wd_and_ht:nnnn}
 %   \begin{syntax}
 %     \cs{xbox_to_wd:nnn} \Arg{width} \Arg{position} \Arg{content}
+%     \cs{xbox_to_wd_and_ht:nnnn} \Arg{width} \Arg{height} \Arg{position} \Arg{content}
 %   \end{syntax}
 %   Typesets the \meta{content} in horizontal mode such that it is treated as
-%   having nominal \meta{width}. The \meta{content} is placed within this
+%   having nominal \meta{width} and \meta{height}. The \meta{content} is placed within this
 %   \meta{width} according to the \meta{position}, interpreted
 %   \begin{itemize}
 %     \item[c] horizontal centered (the standard setting),
@@ -258,14 +286,22 @@
 %     \item[s] interword space stretched or shrunk to fill the \meta{width}
 %       (if possible).
 %   \end{itemize}
-%   Within the \meta{width} (a dimension expression), the terms
+%   and when given within the \meta{height} with alignment
+%   \begin{itemize}
+%     \item[t] top of the content
+%     \item[b] bottom of the content
+%   \end{itemize}
+%   and otherwise vertically centered.
+%
+%   Within the \meta{width} and \meta{height} (dimension expressions), the terms
 %   \cs{height}, \cs{depth}, \cs{width} and \cs{totalheight} may be used to
 %   refer to the \enquote{natural} size of the typeset \meta{content}.
 % \end{function}
 %
-% \begin{function}{\xbox_frame_to_wd:nnnnn}
+% \begin{function}{\xbox_frame_to_wd:nnnnn, \xbox_frame_to_wd_and_ht:nnnnnn}
 %   \begin{syntax}
 %     \cs{xbox_frame_to_wd:nnnnn} \Arg{width} \Arg{position} \Arg{content} \Arg{thickness} \Arg{border}
+%     \cs{xbox_frame_to_wd_and_ht:nnnnnn} \Arg{width} \Arg{height} \Arg{position} \Arg{content} \Arg{thickness} \Arg{border}
 %   \end{syntax}
 %   Typesets the \meta{content} in horizontal mode such that it is treated as
 %   having nominal \meta{width}. The \meta{content} is placed within this
@@ -277,6 +313,13 @@
 %     \item[s] interword space stretched or shrunk to fill the \meta{width}
 %       (if possible).
 %   \end{itemize}
+%   and when given within the \meta{height} with alignment
+%   \begin{itemize}
+%     \item[t] top of the content
+%     \item[b] bottom of the content
+%   \end{itemize}
+%   and otherwise vertically centered.
+%
 %   Within the \meta{width} (a dimension expression), the terms
 %   \cs{height}, \cs{depth}, \cs{width} and \cs{totalheight} may be used to
 %   refer to the \enquote{natural} size of the typeset \meta{content}.
@@ -483,20 +526,20 @@
 % material inside a box of non-natural width. These conversions are tied to
 % the document syntax and as such are linked to this implementation.
 %
-% \begin{macro}{\@@_hposition:nn}
-% \begin{macro}{\@@_hposition:Nn}
-% \begin{macro}{\@@_hposition:n}
+% \begin{macro}{\@@_set_position:n}
+% \begin{macro}{\@@_position:n}
+% \begin{macro}{\@@_hposition:n, \@@_vposition:n}
 %   Converts |#1| into a horizontal position within a box. This is set up as
 %   a mapping so that it can be used when both horizontal and vertical
 %   positioning is needed.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_hposition:nn #1#2
+\cs_new_protected:Npn \@@_set_position:n #1
   {
     \cs_set_eq:NN \@@_hposition:n \xbox_position_hcenter:n
-    \tl_map_function:nN {#1} \@@_hposition:Nn
-    \@@_hposition:n {#2}
+    \cs_set_eq:NN \@@_vposition:n \xbox_position_vcenter:n
+    \tl_map_function:nN {#1} \@@_position:n
   }
-\cs_new_protected:Npn \@@_hposition:Nn #1
+\cs_new_protected:Npn \@@_position:n #1
   {
     \str_case:nn {#1}
       {
@@ -504,9 +547,12 @@
         { c } { \cs_set_eq:NN \@@_hposition:n \xbox_position_hcenter:n }
         { r } { \cs_set_eq:NN \@@_hposition:n \xbox_position_right:n }
         { s } { \cs_set_eq:NN \@@_hposition:n \use:n }
+        { t } { \cs_set_eq:NN \@@_vposition:n \xbox_position_top:n }
+        { b } { \cs_set_eq:NN \@@_vposition:n \xbox_position_bottom:n }
       }
   }
 \cs_new_protected:Npn \@@_hposition:n #1 {#1}
+\cs_new_protected:Npn \@@_vposition:n #1 {#1}
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -524,6 +570,74 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}
+%   {\xbox_position_bottom:n, \xbox_position_top:n, \xbox_position_vcenter:n}
+%  We have a lot less setup for vertical alignment, so these likely have no
+%  better names at present.
+%    \begin{macrocode}
+\cs_new_protected:Npn \xbox_position_bottom:n  #1 { \tex_vss:D #1 }
+\cs_new_protected:Npn \xbox_position_top:n     #1 { #1 \tex_vss:D }
+\cs_new_protected:Npn \xbox_position_vcenter:n #1 { \tex_vss:D #1 \tex_vss:D }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Converting \texttt{picture} mode co-ordinates}
+%
+% \LaTeXe{}'s \texttt{picture} mode takes co-ordinates which are not quite
+% the same as \texttt{fp} tuples as they have a unit length. There's no
+% good way to handle that other than keeping the \LaTeXe{} interface, which is
+% what we do here.
+%
+% \begin{variable}{\l_@@_x_dim, \l_@@_y_dim}
+%   Scratch space.
+%    \begin{macrocode}
+\dim_new:N \l_@@_x_dim
+\dim_new:N \l_@@_y_dim
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_coord_convert:n}
+% \begin{macro}{\@@_coord_convert:nn}
+% \begin{macro}{\@@_coord_convert:nN}
+% \begin{macro}{\CoordsToLengths}
+%   Split the co-ordinates, then use the \LaTeXe{} conversion written
+%   out as an auxiliary.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_coord_convert:n #1
+  {
+    \@@_coord_convert:w #1 , , \s_@@_stop
+  }
+\cs_new_protected:Npn \@@_coord_convert:w #1 , #2 , #3 \s_@@_stop
+  {
+    \tl_if_blank:nTF {#2}
+      { \msg_error:nn { xbox } { missing-coordinate-pair } }
+      { \@@_coord_convert:nn {#1} {#2} }
+  }
+\cs_new_protected:Npn \@@_coord_convert:nn #1#2
+  {
+    \group_begin:
+      \@@_coord_convert:nN {#1} \l_@@_x_dim
+      \@@_coord_convert:nN {#2} \l_@@_y_dim
+      \tl_set:Nx \ProcessedArgument
+        {
+          { \dim_use:N \l_@@_x_dim }
+          { \dim_use:N \l_@@_y_dim }
+        }
+    \exp_args:NNNV \group_end:
+    \tl_set:Nn \ProcessedArgument \ProcessedArgument
+  }
+\cs_new_protected:Npn \@@_coord_convert:nN #1#2
+  {
+    \tex_afterassignment:D \use_none_delimit_by_q_nil:w
+    #2 \tex_dimexpr:D #1 \unitlength \scan_stop: \scan_stop: \q_nil
+  }
+\cs_new_eq:NN \CoordsToLengths \@@_coord_convert:n
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
 % \subsection{Functions for making boxes}
 %
 % These functions all involve boxing up material, then allowing adjustment
@@ -538,13 +652,42 @@
     \@@_via_internal_box:nn {#3}
       {
         \hbox_to_wd:nn {#1}
-          { \@@_hposition:nn {#2} { \hbox_unpack_drop:N \l_@@_internal_box } }
+          {
+            \@@_set_position:n {#2}
+            \@@_hposition:n { \hbox_unpack_drop:N \l_@@_internal_box }
+          }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xbox_to_wd_and_ht:nnnn}
+%   Much the same but with a height. The terminal kern is there to ensure the
+%   box aligns to the bottom not the baseline (see comments in the \LaTeXe{}
+%   source \texttt{ltboxes.dtx}): this one is done directly for performance
+%   reasons.
+%    \begin{macrocode}
+\cs_new_protected:Npn \xbox_to_wd_and_ht:nnnn #1#2#3#4
+  {
+    \@@_via_internal_box:nn {#4}
+      {
+        \vbox_to_ht:nn {#2}
+          {
+            \@@_set_position:n {#3}
+            \@@_vposition:n
+              {
+                \hbox_to_wd:nn {#1}
+                  { \@@_hposition:n { \hbox_unpack_drop:N \l_@@_internal_box } }
+              }
+            \tex_kern:D 0pt \scan_stop:
+          }
       }
   }
 %    \end{macrocode}
 % \end{macro}
 %
 % \begin{macro}{\xbox_frame_to_wd:nnnnn}
+% \begin{macro}{\xbox_frame_to_wd_and_ht:nnnnnn}
 %   Wrappers to place a frame around material adjusted to the requested box
 %   dimensions.
 %    \begin{macrocode}
@@ -554,8 +697,20 @@
       { \xbox_to_wd:nnn { #1 - ( #4 + #5 ) * 2 } {#2} {#3} }
       {#4} {#5}
   }
+\cs_new_protected:Npn \xbox_frame_to_wd_and_ht:nnnnnn #1#2#3#4#5#6
+  {
+    \hbox_frame:nnn
+      {
+        \xbox_to_wd_and_ht:nnnn
+          { #1 - ( #5 + #6 ) * 2 }
+          { #2 - ( #5 + #6 ) * 2 }
+          {#3} {#4}
+      }
+      {#5} {#6}
+  }
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\xbox_raise:nn}
 % \begin{macro}{\xbox_raise_with_ht:nnn}
@@ -792,7 +947,7 @@
 %   into dimensions here before handing off to the internal code.
 %    \begin{macrocode}
 \RenewDocumentCommand \makebox
-  { o > { \SplitArgument { 1 } { , } } d ( ) O { c } +m }
+  { o > { \CoordsToLengths } d ( ) O { c } +m }
   {
     \mode_leave_vertical:
     \IfNoValueTF {#2}
@@ -801,10 +956,7 @@
           { \hbox:n {#4} }
           { \xbox_to_wd:nnn {#1} {#3} {#4} }
       }
-      {
-        \msg_error:nnx { xbox } { picture-mode-unavailable }
-          { \token_to_str:N \makebox }
-      }
+      { \xbox_to_wd_and_ht:nnnn #2 {#3} {#4} }
    }
 %    \end{macrocode}
 % \end{macro}
@@ -832,7 +984,7 @@
 %   command does exactly the same as \cs{fbox}.
 %    \begin{macrocode}
 \RenewDocumentCommand \framebox
-  { o > { \SplitArgument { 1 } { , } } d ( ) O { c } +m }
+  { o > { \CoordsToLengths } d ( ) O { c } +m }
   {
     \mode_leave_vertical:
     \IfNoValueTF {#2}
@@ -842,8 +994,8 @@
           { \xbox_frame_to_wd:nnnnn {#1} {#3} {#4} { \fboxrule } { \fboxsep } }
       }
       {
-        \msg_error:nnx { xbox } { picture-mode-unavailable }
-          { \token_to_str:N \framebox }
+        \xbox_frame_to_wd_and_ht:nnnnnn #2 {#3} {#4}
+          { \@wholewidth } { 0pt }
       }
    }
 %    \end{macrocode}
@@ -892,7 +1044,7 @@
 %   take place inside or outside of the coffin setting stage?
 %    \begin{macrocode}
 \RenewDocumentCommand \savebox
-  { m o > { \SplitArgument { 1 } { , } } d ( ) O { c } +m }
+  { m o > { \CoordsToLengths } d ( ) O { c } +m }
   {
     \IfNoValueTF {#3}
       {
@@ -902,8 +1054,8 @@
       }
       }
       {
-        \msg_error:nnx { xbox } { picture-mode-unavailable }
-          { \token_to_str:N \savebox }
+        \hcoffin_set:Nn #1
+          { \xbox_to_wd_and_ht:nnnn #3 {#4} {#5} }
       }
    }
 %    \end{macrocode}
@@ -1021,11 +1173,11 @@
 % \subsection{Messages}
 %
 %    \begin{macrocode}
-\msg_new:nnnn { xbox } { picture-mode-unavailable }
-  { Picture~mode~syntax~not~available~for~#1~command. }
+\msg_new:nnnn { xbox } { missing-coordinate-pair }
+  { Missing~co-ordinate~pair~in~picture-mode~argument. }
   {
-    The~xbox~implementation~of~LaTeX~box~commands~does~not~support~LaTeX2e's~
-    picture~mode~syntax.
+    A~picture-mode~co-ordinate~was~given,~but~LaTeX~could~not~
+    find~a~comma~separating~the~two~values.
   }
 %    \end{macrocode}
 %





More information about the latex3-commits mailing list.