% \iffalse^^A meta-comment
% ======================================================================
% makelabels.dtx
% Copyright (c) Markus Kohm, 2009-2021
%
% This file is part of the LaTeX2e package `makelabels'.
%
% This work may be distributed and/or modified under the conditions of
% the LaTeX Project Public License, version 1.3c of the license.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions of LaTeX
% version 2005/12/01 and of this work.
%
% This work has the LPPL maintenance status "author-maintained".
%
% The Current Maintainer and author of this work is Markus Kohm.
%
% This work consists of the files `makelabels.dtx' and `README.md'.
% ======================================================================
%
%<*dtx>
\ifx\ProvidesFile\undefined\def\ProvidesFile#1[#2]{}\fi
\ProvidesFile{makelabels.dtx}
%</dtx>
%<lco>\ProvidesFile{makelabels.lco}
%<exmpl&simple>\ProvidesFile{makelabels-example.tex}
%<exmpl&envlab>\ProvidesFile{makelabels-envlab-example.tex}
  [2021/08/14 v1.0 provide labels with scrlttr2 and scrletter]
%<*dtx>
\ifx\documentclass\undefined
  \input l3docstrip.tex
  \generate{%
    \usedir{tex/latex/makelabels}
    \file{makelabels.lco}{\from{makelabels.dtx}{lco}}
    \usedir{doc/latex/makelabels}
    \file{makelabels-example.tex}{\from{makelabels.dtx}{exmpl,simple}}
    \file{makelabels-envlab-example.tex}{\from{makelabels.dtx}{exmpl,envlab}}
  }
\else
  \let\endbatchfile\relax
\fi
\endbatchfile
\documentclass{l3doc}
\usepackage{booktabs}
\usepackage{scrlogo}
\usepackage{graphicx}
\GetFileInfo{makelabels.dtx}
\begin{document}
\title{Adding label functionality to
  \texorpdfstring{\file{scrlttr2}}{scrlttr2} and
  \texorpdfstring{\file{scrletter}}{scrletter} using
  \texorpdfstring{\file{makelabels.lco}}{makelabels.lco}}
\date{\fileversion{} \filedate\footnote{For support and/or bug reports see
    \href{https://github.com/komascript/makelabels}{the project pages}.}}
\author{Markus Kohm}
\maketitle
\begin{abstract}
  In opposite to the standard letter class, the \KOMAScript{} letter class
  \file{scrlttr2} and the \KOMAScript{} letter package \file{scrletter} do not
  provide generation of a label page using \cs[no-index]{makelabels}. But
  \KOMAScript{} provides the option to add new letter features using LCO
  files. \file{makelabels.lco} is such a LCO file. It provides
  \cs[no-index]{makelabels} similar to the standard letter class. The new
  \cs[no-index]{makelabels} has a yet very rudimentary configurability but
  much more than the standard letter class provides. However, it is also as
  much compatible as needed that packages like
  \href{https://www.ctan.org/pkg/enlab}{\file{envlab}} can be used. From
  version 1.0 \file{makelabels.lco} is implemented using
  \href{https://www.ctan.org/pkg/l3kernel}{\file{expl3}}.
\end{abstract}
\tableofcontents
\DocInput{\filename}
\end{document}
%</dtx>
% \fi^^A meta-comment
%
% \changes{v0.5}{2008/01/11}{First version released as \file{mlabel.lco} at
%   \url{https://komascript.de/mlabel.lco}}
% \changes{v1.0}{2021/08/11}{Reimplementation using \file{expl3} syntax}
%
% \DoNotIndex{\@ifundefined,\@mainaux,\@onlypreamble,\@spaces,\@texttop}
% \DoNotIndex{\activateareas,\AtEndLetter}
% \DoNotIndex{\begin,\blindtext,\boxmaxdepth}
% \DoNotIndex{\c_empty_tl,\c_max_dim,\c_one_int,\c_zero_dim}
% \DoNotIndex{\clearpage,\closing,\columnsep}
% \DoNotIndex{\cs:w,\cs_end:}
% \DoNotIndex{\cs_if_exist:cTF,\cs_if_exist:NTF,\cs_new:Nn,\cs_new:Npn}
% \DoNotIndex{\cs_new_nopar:Nn}
% \DoNotIndex{\cs_set:Npn,\cs_set_eq:NN,\dim_new:N,\dim_set:Nn,\dim_set_eq:NN}
% \DoNotIndex{\dim_sub:Nn,\documentclass}
% \DoNotIndex{\else:,\end,\endinput,\evensidemargin}
% \DoNotIndex{\exp_args:Nc,\ExplSyntaxOff,\ExplSyntaxOn}
% \DoNotIndex{\fi,\fi:,\fontsize,\frame,\FromAddressLeftMargin}
% \DoNotIndex{\FromAddressTopMargin}
% \DoNotIndex{\GenericError,\group_begin:,\group_end:}
% \DoNotIndex{\headheight,\headsep,\hook_gput_code:nnn}
% \DoNotIndex{\if@atdocument,\if@filesw,\if@twocolumn}
% \DoNotIndex{\if_cs_exist:N,\if_int_compare:w,\if_meaning:w}
% \DoNotIndex{\IfBooleanTF,\IfFormatAtLeastTF,\IfValueTF,\ignorespaces}
% \DoNotIndex{\int_incr:N,\int_new:N,\int_set:Nn,\int_set_eq:NN}
% \DoNotIndex{\int_step_inline:nnn}
% \DoNotIndex{\iow_char:N,\iow_now:Nn,\iow_now:Nx}
% \DoNotIndex{\l_tmpa_tl,\lineskip,\LoadLetterOptions}
% \DoNotIndex{\msg_error:nnn,\msg_fatal:nnn,\msg_new:nnn,\msg_warning:nnnn}
% \DoNotIndex{\newcommand,\NewExpandableDocumentCommand}
% \DoNotIndex{\oddsidemargin,\onecolumn,\opening}
% \DoNotIndex{\pagestyle,\paperheight,\paperwidth,\par,\parbox}
% \DoNotIndex{\prop_new:c,\prop_new:N,\prg_new_conditional:Nnn}
% \DoNotIndex{\prg_return_false:,\prg_return_true:}
% \DoNotIndex{\prop_get:cnNTF,\prop_get:NnNTF,\prop_new:N}
% \DoNotIndex{\prop_set_from_keyval:cn,\prop_set_from_keyval:Nn}
% \DoNotIndex{\providecommand}
% \DoNotIndex{\raggedright,\relax,\selectfont,\setkomavar,\setlength}
% \DoNotIndex{\skip_horizontal:N,\skip_vertical:N,\str_new:N,\str_set:Nn}
% \DoNotIndex{\textheight,\textwidth,\token_to_str:N,\topmargin}
% \DoNotIndex{\use:e,\use:n,\usepackage}
%
% \section{Installation}
%
% It is recommended to use the package installer of the \TeX{}
% distribution. If you don't use a \TeX{} distribution with package installer,
% that provides \file{makelabels.lco}, please see the advanced installation
% information in the
% \href{https://github.com/komascript/makelabels/blob/main/README.md}%
% {\file{README.md}}.
%
% \section{Basic Usage}
%
% First of all please note, that \file{makelabels.lco} needs \LaTeX{} from
% version 2020/10/01. It is recommended to use at least \LaTeX{} 2021/06/01,
% because this is the \LaTeX{} version used for development of
% \file{makelabels.lco}. Also \KOMAScript{} version 3.34 or newer is
% recommended. If you would use an older \KOMAScript{} version you would do
% this on your own risk. Please do not expect any support in this
% case.
%
% To use the \file{makelabels.lco} you have to use either \KOMAScript{}
% letter class \file{scrlttr2} or \file{scrletter} or the \KOMAScript{}
% letter package \file{scrletter}. After loading the class resp. package you
% have to load \file{makelabels.lco} using:
% \begin{verbatim}
% \LoadLetterOption{makelabels}
% \end{verbatim}
% in your document preamble. Note: This LCO cannot be loaded after
% |\begin{document}|.
%
% Loading the LCO file already activates generation of label information
% inside the \file{aux}-file of your document. Nothing else.
%
% \DescribeMacro\makelabels
% To activate the label generation you have to add
% \begin{verbatim}
% \makelabels
% \end{verbatim}
% to your document preamble after loading \file{makelabels.lco} (see
% above). Now at the end of the document, after printing all letters
% \file{makelabels} generates one or more additional sheets with address
% labels. The default label sheet is of type Avery~5162. This is a label sheet
% with seven rows and two columns of labels. It is compatible with several
% other Avery label types.
%
% \DescribeMacro\selectlabeltype
% If you need more than one label per letter or another label type you can use:
% \begin{syntax}
% \cs{selectlabeltype}\oarg{integer}\marg{string}
% \end{syntax}
% This selects \meta{integer} labels of type \meta{string} for each following
% letter (inclusive the current letter, if used between |\begin{letter}| and
% |\end{letter}|. See \autoref{tab:labeltypes} for the allowed \meta{string}
% arguments and the corresponding label types.
%
% \begin{table}
%   \begin{minipage}{\linewidth}
%   \centering
%   \begin{tabular}{llr}
%     \toprule
%     \textbf{\meta{string}} & \multicolumn2l{\textbf{Specification}} \\
%                            & Measure & {Value} \\
%     \midrule
%       \texttt{avery\_5162}\footnote{\url{https://www.avery.com/products/labels/5162}}
%                            & sheet height              & 11\,in\\
%                            & sheet width               & 8.5\,in\\
%                            & sheet top margin          & 0.845\,in\\
%                            & sheet bottom margin       & 0.845\,in\\
%                            & sheet left margin         & 0.167\,in\\
%                            & sheet right margin        & 0.167\,in\\
%                            & label height              & 1.330\,in\\
%                            & label width               & 4\,in\\
%                            & horizontal distance       & 0.166\,in\\
%                            & vertical distance         & 0\,pt\\
%                            & label left margin         & 5\,pt\\
%                            & label right margin        & 5\,pt\\
%                            & label top margin          & 0\,pt\\
%                            & label bottom margin       & 0\,pt\\
%                            & rows                      & 7\hphantom{\,pt}\\
%                            & columns                   & 2\hphantom{\,pt}\\
%     \bottomrule
%   \end{tabular}
%   \caption{Known Label Types}
%   \label{tab:labeltypes}
%   \end{minipage}
% \end{table}
%
% \section{Advanced Usage}
%
% \DescribeMacro\makelabels_add_label_type:nn
% Advanced users can add their own label sheet definitions. But currently
% there is only an \file{expl3} interface for this. If you do not know
% \file{expl3}, please stop reading. There is no support for this feature,
% currently.
% \begin{syntax}
%   \cs{makelabels_add_label_type:nn} \meta{string}
%   \{
%     sheet height        = \meta{dim_1},
%     sheet width         = \meta{dim_2},
%     sheet top margin    = \meta{dim_3},
%     sheet bottom margin = \meta{dim_4},
%     sheet left margin   = \meta{dim_5},
%     sheet right margin  = \meta{dim_6},
%     vertical distance   = \meta{dim_7},
%     horizontal distance = \meta{dim_8},
%     label height        = \meta{dim_9},
%     label width         = \meta{dim_{10}},
%     label top margin    = \meta{dim_{11}},
%     label bottom margin = \meta{dim_{12}},
%     rows                = \meta{int_{1}},
%     columns             = \meta{int_{2}}
%   \}
% \end{syntax}
% Currently all \meta{dim_x}, which are not specified, will be 0\,pt and all
% \meta{int_x}, which are not specified, will be 1.
%
% The names of the properties should be self-explaining. If not, don't use it!
%
% Note: You can participate in the development of \file{makelabels.lco} by
% posting and explaining your own label specifications.
%
% \section{Simple Example}
% \label{sec:simpleexample}
%
% A very simple example for using \file{makelabels.lco} would be:
% \iffalse^^A meta-comment
%<*exmpl&simple>
% \fi
%    \begin{macrocode}
\documentclass[paper=letter]{scrletter}
\LoadLetterOptions{UScommercial9,makelabels}
\usepackage[english]{babel}
\usepackage{blindtext}
\setkomavar{fromname}{John Doe}
\setkomavar{fromaddress}{1 Lambda Street\\Anyplace, NY 12345}
\makelabels
\begin{document}
\begin{letter}{Jane Doe\\2 Alpha Street\\Otherplace, NY 12346}
\opening{Dear Jane,}
\blindtext
\closing{With love}
\end{letter}
\end{document}
%    \end{macrocode}
% \iffalse^^A meta-comment
%</exmpl&simple>
% \fi
% It would produce the two pages shown in \autoref{fig:example}.
%
% \begin{figure}
%   \centering
%   \begin{tabular}{|l|l|}
%     \hline
%     \includegraphics[page=1,width=.45\linewidth]{makelabels-example.pdf} &
%     \includegraphics[page=2,width=.45\linewidth]{makelabels-example.pdf} \\
%     \hline
%   \end{tabular}
%   \caption{The letter and the label sheet of the simple example of
%     \protect\autoref{sec:simpleexample}.}
%   \label{fig:example}
% \end{figure}
%
% If you like, you could add an additional
% \begin{verbatim}
% \selectlabeltype[14]{avery_5162}
% \end{verbatim}
% after |\begin{document}|. In this case, you would get a whole sheet of 14
% labels (7 rows by 2 columns).
%
% \section{Example using additional label packages}
% \label{sec:envlabexample}
% As already mentioned in the abstract you can use \file{makelabels.lco}
% together with package \href{https://ctan.org/pkg/envlab}{\file{envlab}}. In
% this case, it is important to load \file{makelabels.lco} before package
% \file{envlab}:
% \iffalse^^A meta-comment
%<*exmpl&envlab>
% \fi
%    \begin{macrocode}
\documentclass[paper=letter]{scrletter}
\LoadLetterOptions{UScommercial9,makelabels}
\usepackage[english]{babel}
\usepackage{blindtext}
\setkomavar{fromname}{John Doe}
\setkomavar{fromaddress}{1 Lambda Street\\Anyplace, NY 12345}

\usepackage[centerenvelopes,businessenvelope]{envlab}
\setlength{\FromAddressTopMargin}{0.25in}                                
\setlength{\FromAddressLeftMargin}{0.25in}                               
\makelabels

\begin{document}

\begin{letter}{Jane Doe\\2 Alpha Street\\Otherplace, NY 12346}
\opening{Dear Jane,}
\blindtext
\closing{With love}
\end{letter}
\end{document}
%    \end{macrocode}
% \iffalse^^A meta-comment
%</exmpl&envlab>
% \fi
% It would produce the two pages shown in \autoref{fig:envlabexample}.
%
% \begin{figure}
%   \centering
%   \begin{tabular}{|l|l|}
%     \hline
%     \includegraphics[page=1,width=.45\linewidth]{makelabels-envlab-example.pdf} &
%     \includegraphics[page=2,width=.45\linewidth]{makelabels-envlab-example.pdf} \\
%     \hline
%   \end{tabular}
%   \caption{The letter and the envelope sheet of the \protect\file{envlab}
%     example of \protect\autoref{sec:envlabexample}.}
%   \label{fig:envlabexample}
% \end{figure}
%
% Please note: package \file{envlab} redefines macro |\@toaddressfont|, which
% is also an internal macro of \file{scrlttr2} or \file{scrletter}. The
% \KOMAScript{} classes resp. the \KOMAScript{} package uses this to store the
% font of the recipient's address. So loading \file{envlab} will change the
% font of the recipient's address. To avoid this you could use additional
% preamble code:
% \begin{verbatim}
% \makeatletter
% \AtBeginDocument{%
%   \immediate\write\@auxout{%
%     \string\def\string\@toaddressfont{%
%       \expandafter\detokenize\expandafter{\@toaddressfont}}}%
%   \setkomafont{toaddress}{}% set the recepient's address font
% }
% \makeatother
% \end{verbatim}
% This delays the \file{envlab}'s redefinition of |\@toaddressfont| until the
% \emph{labels} are generated.
%
% \StopEventually{\PrintChanges\PrintIndex}
%
% \section{Implementation}
%
%    \begin{macrocode}
%<*lco>
%<@@=makelabels>
%    \end{macrocode}
%
% \subsection*{Load time actions}
%
% We need at least \LaTeX{} 2020/10/01.
%    \begin{macrocode}
\newcommand*{\makelabels@fatal@format@error}{%
  \GenericError{(makelabels)\@spaces\@spaces\@spaces\@spaces}%
               {Fatal makelabels.lco error: LaTeX too old.}%
               {See the makelabels.lco documentation for explanation.}%
               {At least LaTeX 2020/10/01 is needed}%
  \endinput
}
\@ifundefined{IfFormatAtLeastTF}{%
  \makelabels@fatal@format@error
}{%
  \IfFormatAtLeastTF{2020/10/01}{}{\makelabels@fatal@format@error}%
}
%    \end{macrocode}
%
% With this version of \LaTeX{}, we do not need to load \file{expl3}
% explicitly but can just switch to the syntax.
%    \begin{macrocode}
\ExplSyntaxOn
%    \end{macrocode}
%
% This LCO file can be used in the document preamble only. If we are already
% have begun the document, this would be fatal.
%    \begin{macrocode}
\msg_new:nnn { makelabels } { onlypreamble }
  { Sorry,~but~`makelabels.lco'~can~be~used~in~the~document~preamble~only. }
\if@atdocument
  \msg_fatal:nnn { makelabels } { onlypreamble }
\fi
%    \end{macrocode}
%
% \begin{macro}{\makelabels_add_label_type:nn}
% Labels have only a width and height. They are placed in a number of rows and
% columns at a label sheet. The sheet has also a width and height.  There is a
% margin left of the first label, above the first label, right of the first
% label and below the last label. And there may be a horizontal and a vertical
% distance between the labels. See the definition of Avery 5162 labels for
% all properties.
%
% Note: currently all properties have to be setup correctly.
%    \begin{macrocode}
\cs_new_nopar:Nn \makelabels_add_label_type:nn
  {
    \prop_new:c { g_@@_label_type_#1_prop }
    \prop_set_from_keyval:cn { g_@@_label_type_#1_prop } { #2 }
  }
%    \end{macrocode}
% \end{macro}
%
% The first label type we define is \texttt{avery_5162}:
%    \begin{macrocode}
\makelabels_add_label_type:nn { avery_5162 }
  {
    sheet height              = 11 in,
    sheet width               = 8.5 in,
    sheet top margin          = 0.845 in,
    sheet bottom margin       = 0.845 in,
    sheet left margin         = 0.167 in,
    sheet right margin        = 0.167 in,
    label height              = 1.330 in,
    label width               = 4 in,
    horizontal distance       = 0.166 in,
    vertical distance         = 0 pt,
    label left margin         = 5 pt,
    label right margin        = 5 pt,
    label top margin          = 0 pt,
    label bottom margin       = 0 pt,
    rows                      = 7,
    columns                   = 2,
  }
%    \end{macrocode}
%
% We also have to take care that at the end of each letter the label is written
% to the \file{aux}-file.
% \begin{function}[EXP]{\@@_Ifkomavarempty}
% To be able to write to the \file{aux}-file, we need an expandable verion
% of \KOMAScript's \cs{Ifkomavarempty}. To make simple wrapping possible, we
% define it as an internal document command.
%    \begin{macrocode}
\NewExpandableDocumentCommand \@@_Ifkomavarempty { s m m m }
  {
    \IfBooleanTF { #1 }
      {
        \exp_args:Nc \@@_if_empty_var_or_name:NTF{scr@#2@name}{#3}{#4}
      }
      {
        \exp_args:Nc \@@_if_empty_var_or_name:NTF{scr@#2@var}{#3}{#4}
      }
  }
%    \end{macrocode}
% \end{function}
% \begin{function}[pTF]{\@@_if_empty_var_or_name:N}
% This is the real internal command. Now, the first argument is not the
% variable any longer, but the macro storing the variable or name.
%    \begin{macrocode}
\prg_new_conditional:Nnn \@@_if_empty_var_or_name:N { p, T, F, TF }
  {
    \if_cs_exist:N #1 
      \if_meaning:w #1 \c_empty_tl
        \prg_return_true: \else: \prg_return_false: \fi:
    \else:
      \prg_return_false:
    \fi:
  }
%    \end{macrocode}
% \end{function}
%
% \begin{function}[EXP]{\@@_usekomavar}
% To be able to write to the \file{aux}-file, we need an expandable version
% of \KOMAScript's \cs{usekomavar}. To make simple wrapping possible, we
% define it as an internal document command.
%    \begin{macrocode}
\NewExpandableDocumentCommand \@@_usekomavar { s o m }
  {
    \IfValueTF{#2}{#2}{\use:e}{\cs:w scr@#3@\IfBooleanTF{#1}{name}{var}\cs_end:}
  }
%    \end{macrocode}
% \end{function}
%
% Now, after defining new, expandable versions of most of the usually needed
% not expandable \KOMAScript{} user command, we can write to the
% \file{aux}-file at the end of every letter. Note, we have to write
% immediately (using \cs[no-index]{iow_now:Nx}), to use the current definition
% of the commands redefined in the local group.
%    \begin{macrocode}
\AtEndLetter
  {
    \if@filesw
      \group_begin:
        \cs_set:Npn \Ifkomavarempty { \@@_Ifkomavarempty }
        \cs_set:Npn \usekomavar { \@@_usekomavar }
        \iow_now:Nx \@mainaux
          {
            \token_to_str:N \@mlabel
            \iow_char:N \{ \usekomavar{backaddress} \iow_char:N \}
            \iow_char:N \{ \usekomavar{toname} \iow_char:N \\ \iow_char:N \\
                           \usekomavar{toaddress} \iow_char:N \}
          }
      \group_end:
    \fi
  }
%    \end{macrocode}
%
% \subsection*{The preamble commands}
%
% \begin{macro}{\makelabels}
% Preamble only command to activate the label generation via the
% \file{aux}-file.
%    \begin{macrocode}
\cs_new:Npn \makelabels
  {
    \hook_gput_code:nnn { begindocument } { makelabels.lco }
      {
        \cs_set_eq:NN \@startlabels \startlabels
        \cs_set_eq:NN \@mlabel \mlabel
        \cs_set_eq:NN \@mlabeltype \mlabeltype
        \if@filesw
          \iow_now:Nn \@mainaux { \@startlabels }%
        \fi
      }
    \hook_gput_code:nnn { enddocument / afterlastpage } { makelabels.lco }
      {
        \if@filesw
          \iow_now:Nn \@mainaux { \clearpage } %
        \fi
      }  
  }
\@onlypreamble \makelabels  
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\selectlabeltype}
% Used in the document preamble or inside the document to select another label
% type.
%    \begin{macrocode}
\newcommand*{\selectlabeltype}[2][1]{
  \cs_if_exist:cTF { g_@@_label_type_#2_prop }
    {
      \if@filesw
        \iow_now:Nn \@mainaux
          {
            \@mlabeltype { #1 } { #2 }
          }
      \fi
    }
    {
      \msg_error:nnn { makelabels } { unkown label type } { #1 }
    }
}
%    \end{macrocode}
% \end{macro}
%
% \subsection*{The \file{aux}-file commands}
%
% \begin{macro}{\@startlabels}
% \begin{macro}{\@mlabel}
% \begin{macro}{\@mlabeltype}
% All these are dummies until \cs{makelabels} has been used.
%    \begin{macrocode}
\hook_gput_code:nnn { begindocument } { makelabels.lco }
  {
    \if@filesw
      \iow_now:Nn \@mainaux { \providecommand* { \@startlabels } { } }
      \iow_now:Nn \@mainaux { \providecommand* { \@mlabel }[2] { } }
      \iow_now:Nn \@mainaux { \providecommand* { \@mlabeltype } [ 2 ] { } }
    \fi
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\mlabeltype}
% Select generating \#1 labels of type \#2.
%    \begin{macrocode}
\int_new:N \g_@@_label_repeat_int
\int_set_eq:NN \g_@@_label_repeat_int \c_one_int
\str_new:N \g_@@_label_type_str
\str_set:Nn \g_@@_label_type_str { avery_5162 }
\cs_new:Npn \mlabeltype #1#2
  {
    \int_set:Nn \g_@@_label_repeat_int { #1 }
    \str_set:Nn \g_@@_label_type_str { #2 }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\startlabels}
% Start a new label page. We have to setup several page layout parameter
% depending on the current label type \cs{g_@@_label_type_str}.
%    \begin{macrocode}
\cs_new:Npn \startlabels
  {
    \clearpage
    \if@twocolumn \onecolumn \fi
    \pagestyle{empty}
    \cs_set_eq:NN \@texttop \relax
    \dim_set_eq:NN \headheight \c_zero_dim
    \dim_set_eq:NN \headsep \c_zero_dim
    \dim_set_eq:NN \lineskip \c_zero_dim
    \@@_prop_get_dim:nN { sheet height } \paperheight
    \@@_prop_get_dim:nN { sheet top margin } \topmargin
    \dim_sub:Nn \topmargin { 1in }
    \@@_prop_get_dim:nN { sheet width } \paperwidth
    \@@_prop_get_dim:nN { sheet left margin } \oddsidemargin
    \dim_sub:Nn \oddsidemargin { 1in }
    \dim_set_eq:NN \evensidemargin \oddsidemargin
    \@@_prop_get_int:nN { rows } \g_@@_rows_int
    \@@_prop_get_int:nN { columns } \g_@@_columns_int
    \@@_prop_get_dim:nN { label height } \g_@@_label_height_dim
    \@@_prop_get_dim:nN { label width } \g_@@_label_width_dim
    \@@_prop_get_dim:nN { vertical distance } \g_@@_vertical_skip_dim
    \@@_prop_get_dim:nN { horizontal distance } \columnsep
    \dim_set:Nn \textheight
      {
        ( \g_@@_label_height_dim + \g_@@_vertical_skip_dim ) * \g_@@_rows_int
        - \g_@@_vertical_skip_dim
      }
    \dim_set:Nn \textwidth
      {
        ( \g_@@_label_width_dim + \columnsep ) * \g_@@_columns_int
        - \columnsep
      }
    \@@_prop_get_dim:nN { label top margin } \g_@@_label_top_margin_dim
    \@@_prop_get_dim:nN { label bottom margin } \g_@@_label_bottom_margin_dim
    \@@_prop_get_dim:nN { label left margin } \g_@@_label_left_margin_dim
    \@@_prop_get_dim:nN { label right margin } \g_@@_label_right_margin_dim
    \activateareas
    \fontsize{10pt}{12pt}\selectfont
    \dim_set_eq:NN \boxmaxdepth \c_max_dim
    \int_set_eq:NN \g_@@_row_int \c_one_int
    \int_set_eq:NN \g_@@_column_int \c_one_int
    \dim_set:Nn \g_@@_label_height_effective_dim
      {
        \g_@@_label_height_dim
        - \g_@@_label_top_margin_dim
        - \g_@@_label_bottom_margin_dim
      }
    \dim_set:Nn \g_@@_label_width_effective_dim
      {
        \g_@@_label_width_dim
        - \g_@@_label_left_margin_dim
        - \g_@@_label_right_margin_dim
      }
    \raggedright
  }

\int_new:N \g_@@_rows_int
\int_new:N \g_@@_columns_int
\int_new:N \g_@@_row_int
\int_new:N \g_@@_column_int
\dim_new:N \g_@@_label_height_dim
\dim_new:N \g_@@_label_width_dim
\dim_new:N \g_@@_label_top_margin_dim
\dim_new:N \g_@@_label_bottom_margin_dim
\dim_new:N \g_@@_label_left_margin_dim
\dim_new:N \g_@@_label_right_margin_dim
\dim_new:N \g_@@_label_height_effective_dim
\dim_new:N \g_@@_label_width_effective_dim
\dim_new:N \g_@@_vertical_skip_dim
%    \end{macrocode}
% \end{macro}
%
% \begin{function}{\@@_prop_get_dim:nN,\@@_prop_get_int:nN}
%   \begin{syntax}
%     \cs{@@_prop_get_dim:nN} \Arg{property string} \Arg{dimension variable}
%     \cs{@@_prop_get_int:nN} \Arg{property string} \Arg{integer variable}
%   \end{syntax}
% Get a property from the property list of the current label type
% \cs{g_@@_label_type_str} and store it as a dimension resp. integer. Unkown
% properties result in a warning message. Unkown dimenionss are assumed to be
% zero, unkown integers are assumed to be one.
%    \begin{macrocode}
\msg_new:nnn { makelabels } { undefined property }
  { Property~`#1'~undefined~for~label~type~`\g_@@_label_type_str'.~
    Value~#2~assumed. }

\cs_new:Nn \@@_prop_get_dim:nN
  {
    \prop_get:cnNTF { g_@@_label_type_ \g_@@_label_type_str _prop } { #1 } \l_tmpa_tl
      { \dim_set:Nn #2 \l_tmpa_tl }
      {
        \msg_warning:nnnn { makelabels } { undefined property } { #1 } { zero }
        \dim_set_eq:NN #2 \c_zero_dim
      }
  }

\cs_new:Nn \@@_prop_get_int:nN
  {
    \prop_get:cnNTF { g_@@_label_type_ \g_@@_label_type_str _prop } { #1 } \l_tmpa_tl
      { \int_set:Nn #2 \l_tmpa_tl }
      {
        \msg_warning:nnnn { makelabels } { undefined property } { #1 } { one }
        \int_set_eq:NN #2 \c_one_int
      }
  }
%    \end{macrocode}
% \end{function}
%
% \begin{macro}{\@@_print_one_label:}
% Currently we do not support different output routines for different label
% types. So this command is always the same.
%    \begin{macrocode}
\cs_new:Nn \@@_print_one_label:nn
  {
%    \frame{
    \parbox[b][\g_@@_label_height_dim]{\g_@@_label_width_dim}{
      \skip_vertical:N \g_@@_label_top_margin_dim
      \skip_horizontal:N \g_@@_label_left_margin_dim
      \parbox[c][\g_@@_label_height_effective_dim]{\g_@@_label_width_effective_dim}{
        \ignorespaces #2
      }
      \skip_vertical:N \g_@@_label_bottom_margin_dim
    }
%    }
    \int_incr:N \g_@@_column_int
    \if_int_compare:w \g_@@_column_int > \g_@@_columns_int
      \par
      \skip_vertical:N \g_@@_vertical_skip_dim
      \int_set_eq:NN \g_@@_column_int \c_one_int
      \int_incr:N \g_@@_row_int
      \if_int_compare:w \g_@@_row_int > \g_@@_rows_int
        \clearpage
        \int_set_eq:NN \g_@@_row_int \c_one_int
      \fi:
    \else:
      \skip_horizontal:N \columnsep
    \fi:
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\mlabel}
% Output the configurated number of labels.
%    \begin{macrocode}
\cs_new:Npn \mlabel #1#2
  {
    \int_step_inline:nnn { 1 } { \g_@@_label_repeat_int }
      {
        \@@_print_one_label:nn { #1 } { #2 }
      }
  }
%    \end{macrocode}
% \end{macro}
%
% We need to not forget to switch of \file{expl3} syntax, because this is not
% a package but a LCO.
%    \begin{macrocode}
\ExplSyntaxOff
%</lco>
%    \end{macrocode}
% \Finale
%
\endinput
%
% Local Variables:
% mode: doctex
% TeX-master: t
% End: