% \iffalse meta-comment
%
% File: ltx-talk-frame-structure.dtx Copyright (C) 2025 Joseph Wright
%
% 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 "ltx-talk 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/josephwright/ltx-talk
%
% for those people who are interested.
%
% -----------------------------------------------------------------------
%
%<*driver>
\documentclass{l3doc}
% Additional commands needed in this source
\NewDocumentCommand\email{m}{\href{mailto:#1}{\nolinkurl{#1}}}
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% ^^A As we are dealing with a class, this has to be done manually
% \def\filedate{2025-07-28}
% \def\fileversion{v0.1.5}
%
% \title{^^A
%   \pkg{ltx-talk-frame} -- The structure of frames^^A
%   \thanks{This file describes \fileversion,
%     last revised \filedate.}^^A
% }
%
% \author{^^A
%  Joseph Wright^^A
%  \thanks{^^A
%    E-mail: \email{joseph@texdev.net}^^A
%   }^^A
% }
%
% \date{Released \filedate}
%
% \maketitle
%
% \begin{documentation}
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{ltx-talk-frame-structure} implementation}
%
% Start the \pkg{DocStrip} guards.
%    \begin{macrocode}
%<*class>
%    \end{macrocode}
%
% Identify the internal prefix.
%    \begin{macrocode}
%<@@=talk>
%    \end{macrocode}
%
%    \begin{macrocode}
\keys_define:nn { talk }
  { columns .inherit:n = talk / column }
%    \end{macrocode}
%
% \begin{variable}{\l_@@_columns_wd_tl}
%   We store the requested width for columns in a \texttt{tl} as this means
%   that the key value will make sense even if it depends on the current
%   \cs{textwidth}.
%    \begin{macrocode}
\keys_define:nn { talk / columns }
  { width .tl_set:N = \l_@@_columns_wd_tl }
\keys_set:nn { talk / columns }
  { width = \textwidth }
%    \end{macrocode}
% \end{variable}
%
% \begin{environment}{columns}
%   Columns are block-like environments so we start and end with a \cs{par} to
%   ensure correct tagging.
%    \begin{macrocode}
\NewDocumentEnvironment { columns } { D <> { all } O { } }
  {
    \@@_action_begin:n {#1}
    \par
    \keys_set:nn { talk / columns } {#2}
    \hbox_set_to_wd:Nnw \l_@@_tmp_box { \l_@@_columns_wd_tl }
      \dim_set:Nn \textwidth { \l_@@_columns_wd_tl }
      \dim_set_eq:NN \columnwidth \textwidth
      \hfil
      \ignorespaces
  }
  {
      \unskip
      \hfil
    \hbox_set_end:
    \box_use_drop:N \l_@@_tmp_box
    \par
    \@@_action_end:
  }
%    \end{macrocode}
% \end{environment}
%
% \begin{variable}{\l_@@_column_alignment_tl}
%    \begin{macrocode}
\keys_define:nn { talk / column }
  {
    b .meta:n =
      { vertical-alignment = bottom } ,
    b .value_forbidden:n = true ,
    c .meta:n =
      { vertical-alignment = center } ,
    c .value_forbidden:n = true ,
    t .meta:n =
      { vertical-alignment = top } ,
    t .value_forbidden:n = true ,
    vertical-alignment .choices:nn =
      { bottom , center , top }
      {
        \tl_set_eq:NN \l_@@_column_alignment_tl
          \l_keys_value_tl
      }
  }
\keys_set:nn { talk / column }
  {
    vertical-alignment = center
  }
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}
%   {
%     \@@_column_align_bottom:n  ,
%     \@@_column_align_center:n  ,
%     \@@_column_align_top:n
%   }
%   Based on ideas in the highly experimental \pkg{xbox}.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_column_align_bottom:n #1
  { \vbox:n {#1} }
\cs_new_protected:Npn \@@_column_align_center:n #1
  {
    \vbox:n
      {
        \hbox:n
          {
            \box_move_down:nn
              {
                  0.5 \box_ht:N \l_@@_tmp_box
                - \tex_fontdimen:D 22 ~ \tex_textfont:D 2 ~
              }
              { \vbox:n {#1} }
          }
      }
  }
\cs_new_protected:Npn \@@_column_align_top:n #1
  { \vbox_top:n {#1} }
%    \end{macrocode}
% \end{macro}
%
% \begin{environment}{column}
%   A cut-down version of a minipage: we want to be clear on the semantic
%   meaning.
%    \begin{macrocode}
\NewDocumentEnvironment { column } { D <> { all } O { } m }
  {
    \@@_action_begin:n {#1}
    \par
    \keys_set:nn { talk / column } {#2}
    \vbox_set_to_wd:Nnw \l_@@_tmp_box {#3}
      \dim_set:Nn \textwidth {#3}
      \dim_set_eq:NN \columnwidth \textwidth
      \@parboxrestore
      \leavevmode
      \raggedright
      \ignorespaces
  }
%    \end{macrocode}
%   The \cs{@ignore} here means that any spaces after |\end{column}| are
%   suppressed by a \tn{ignorespaces} inserted by the kernel.
%    \begin{macrocode}
  {
    \vbox_set_end:
    \use:c { @@_column_align_ \l_@@_column_alignment_tl :n }
      { \vbox_unpack_drop:N \l_@@_tmp_box }
    \hfil
    \par
    \@@_action_end:
    \@ignoretrue
  }
%    \end{macrocode}
% \end{environment}
%
%    \begin{macrocode}
%</class>
%    \end{macrocode}
%
% \end{implementation}
%
% \PrintIndex
