l3维问题

l3维问题

背景:我正在尝试排版双面文档,其中两个可见页面的间距应相同。因此,我实现了一个自定义辅助文件来存储高度(保存不会显示在 MWE 中)。

问题:虽然保存工作正常,但读取和评估似乎相当困难。下面的宏\sfkatalog_getdim在用于排版长度时工作正常,但当我使用它时它不起作用(我用\vbox_to_ht:nn替换硬编码值)。我得到的错误是:1.75cm\sfkatalog_getdim:nV { 1 } \l_tmpb_dim

! Missing number, treated as zero.
<to be read again> 
\cs_set_nopar:Npx 
l.71    \sftitle{Test}

问题:我怎样才能让我的宏被评估为长度\vbox_to_ht\dim_set(我目前不知道从哪里开始调试)?

\documentclass{article}
\usepackage{xparse}
\begin{filecontents*}{\jobname.sfc}
1;1.75cm,1.25cm
2;5cm,3cm
\end{filecontents*}

\ExplSyntaxOn
\prop_new:N \g_sfkatalog_ior_prop
\cs_generate_variant:Nn \prop_gput:Nnn { Nxx }
\ior_open:Nn \g_tmpa_ior { \jobname.sfc }
\ior_str_map_inline:Nn \g_tmpa_ior
    {
        \seq_set_split:Nnn \l_tmpa_seq { ; } { #1 }
        \seq_remove_all:Nn \l_tmpa_seq { }
        \prop_gput:Nxx \g_sfkatalog_ior_prop { \seq_item:Nn \l_tmpa_seq { 1 } }
            { \seq_item:Nn \l_tmpa_seq { 2 } }
    }
\ior_close:N \g_tmpa_ior

% getdim #1 -> which one, #2 -> default (as dimension)
\cs_generate_variant:Nn \prop_get:NnN { Nx }
\cs_new_nopar:Npn \sfkatalog_getdim:nn #1#2
{
    \prop_get:NxN \g_sfkatalog_ior_prop { \int_div_truncate:nn { \thepage + 1 } { 2 } } \l_tmpa_tl
    \quark_if_no_value:NTF \l_tmpa_tl
        {
            \dim_eval:n { #2 }
        }
        {
            \prop_get:NxN \g_sfkatalog_ior_prop { \int_div_truncate:nn { \thepage + 1 } { 2 } } \l_tmpa_tl
            \seq_set_split:NnV \l_tmpa_seq { , } \l_tmpa_tl
            \seq_remove_all:Nn \l_tmpa_seq { }
            \dim_set:Nn \l_tmpa_dim { \seq_item:Nn \l_tmpa_seq { #1 } }
            \dim_use:N \l_tmpa_dim
        }
}
\cs_generate_variant:Nn \sfkatalog_getdim:nn { nV }

\NewDocumentCommand { \sftitle } { m }
    {
        \clearpage
        \coffin_clear:N \l_tmpa_coffin
        \hcoffin_set:Nn \l_tmpb_coffin
            {
                \vbox:n
                    {
                        \group_begin:
                            \bfseries\Large
                            #1
                            \par
                        \group_end:
                    }
            }
        \coffin_join:NnnNnnnn \l_tmpa_coffin { l } { b }
            \l_tmpb_coffin                     { l } { b }
            { 0pt } { 0pt }
        \dim_set:Nn \l_tmpb_dim { \coffin_ht:N \l_tmpa_coffin + \coffin_dp:N \l_tmpa_coffin }
        % this will print the correct value, but does not expand right:
        % \sfkatalog_getdim:nV { 1 } \l_tmpb_dim
        % and this is the hard-coded value I'd like to replace:
        \vbox_to_ht:nn { 1.75cm }
            {
                \coffin_typeset:Nnnnn \l_tmpa_coffin { l } { b } { 0pt } { 0pt }
            }
        \par
        \bigskip
    }
\ExplSyntaxOff

\begin{document}
    \sftitle{Test}
    This is a test.

    \sftitle{A very long test without subheading which will span more than one line}
    This is a test.

    \sftitle{Test}
    This is a test.

    \sftitle{A very long test without subheading which will span more than one line}
    This is a test.
\end{document}

答案1

为了在 的第一个参数中使用\vbox_to_ht:nn,该函数\sfkatalog_getdim:nn(或其变体\sfkatalog_getdim:nV)应该是完全可扩展的,但你的 不是。

输入的拆分应该提前完成;在这里我将两部分存储为单独的属性,以便能够使用\prop_item:Nn可扩展的(或其变体)。

\documentclass{article}
\usepackage{xparse}
\begin{filecontents*}{\jobname.sfc}
1;1.75cm,1.25cm
2;5cm,3cm
\end{filecontents*}

\ExplSyntaxOn
% kernel variants
\cs_generate_variant:Nn \prop_gput:Nnn { Nxx }
\cs_generate_variant:Nn \prop_item:Nn { Nf }
\cs_generate_variant:Nn \seq_set_split:Nnn { Nnx }
\prg_generate_conditional_variant:Nnn \prop_if_in:Nn { Nf } { p, T, F, TF }

% variables
\prop_new:N \g_sfkatalog_ior_prop

% initialize
\ior_open:Nn \g_tmpa_ior { \jobname.sfc }
\ior_str_map_inline:Nn \g_tmpa_ior
 {
  \seq_set_split:Nnn \l_tmpa_seq { ; } { #1 }
  \seq_set_split:Nnx \l_tmpb_seq { , } { \seq_item:Nn \l_tmpa_seq { 2 } }
  \prop_gput:Nxx \g_sfkatalog_ior_prop
   { \seq_item:Nn \l_tmpa_seq { 1 } }
   { \seq_item:Nn \l_tmpa_seq { 2 }}
  \prop_gput:Nxx \g_sfkatalog_ior_prop
   { \seq_item:Nn \l_tmpa_seq { 1 } | 1 }
   { \seq_item:Nn \l_tmpb_seq { 1 } }
  \prop_gput:Nxx \g_sfkatalog_ior_prop
   { \seq_item:Nn \l_tmpa_seq { 1 } | 2 }
   { \seq_item:Nn \l_tmpb_seq { 2 } }
 }
\ior_close:N \g_tmpa_ior

\prop_show:N \g_sfkatalog_ior_prop % for debugging

% getdim #1 -> which one, #2 -> default (as dimension)
\cs_new:Npn \sfkatalog_getdim:nn #1 #2
 {
  \prop_if_in:NfTF \g_sfkatalog_ior_prop
   { \int_div_truncate:nn { \value{page} + 1 } { 2 } }
   {% the property exists
    \prop_item:Nf \g_sfkatalog_ior_prop
     { \int_div_truncate:nn { \value{page} + 1 } { 2 } | #1 }
   }
   {% the property does not exist
    \dim_eval:n { #2 }
   }
 }
\cs_generate_variant:Nn \sfkatalog_getdim:nn { nV }

\NewDocumentCommand { \sftitle } { m }
    {
        \clearpage
        \coffin_clear:N \l_tmpa_coffin
        \hcoffin_set:Nn \l_tmpb_coffin
            {
                \vbox:n
                    {
                        \group_begin:
                            \bfseries\Large
                            #1
                            \par
                        \group_end:
                    }
            }
        \coffin_join:NnnNnnnn \l_tmpa_coffin { l } { b }
            \l_tmpb_coffin                     { l } { b }
            { 0pt } { 0pt }
        \dim_set:Nn \l_tmpb_dim { \coffin_ht:N \l_tmpa_coffin + \coffin_dp:N \l_tmpa_coffin }
        % this will print the correct value, but does not expand right:
        % \sfkatalog_getdim:nV { 1 } \l_tmpb_dim
        % and this is the hard-coded value I'd like to replace:
        \vbox_to_ht:nn { \sfkatalog_getdim:nV { 1 } \l_tmpb_dim }
            {
                \coffin_typeset:Nnnnn \l_tmpa_coffin { l } { b } { 0pt } { 0pt }
            }
        \par
        \bigskip
    }
\ExplSyntaxOff

\begin{document}

\sftitle{Test}
This is a test.

\sftitle{A very long test without subheading which will span more than one line}
This is a test.

\sftitle{Test}
This is a test.

\sftitle{A very long test without subheading which will span more than one line}
This is a test.

\end{document}

控制台将显示

The property list \g_sfkatalog_ior_prop contains the pairs (without outer braces):
>  {1}  =>  {1.75cm,1.25cm}
>  {1|1}  =>  {1.75cm}
>  {1|2}  =>  {1.25cm}
>  {2}  =>  {5cm,3cm}
>  {2|1}  =>  {5cm}
>  {2|2}  =>  {3cm}.

笔记。我变成\thepage\value{page}。永远不要相信\thepage会扩展为数值。

初始化可以更简单,因为数据应该采用受控格式。

% initialize
\cs_new_protected:Npn \__sfkatalog_store_item:w #1 ; #2 , #3 \q_stop
 {
  \prop_gput:Nnn \g_sfkatalog_ior_prop { #1 } { #2, #3 }
  \prop_gput:Nnn \g_sfkatalog_ior_prop { #1 | 1 } { #2 }
  \prop_gput:Nnn \g_sfkatalog_ior_prop { #1 | 2 } { #3 }
 }
\ior_open:Nn \g_tmpa_ior { \jobname.sfc }
\ior_str_map_inline:Nn \g_tmpa_ior
 {
  \__sfkatalog_store_item:w #1 \q_stop
 }
\ior_close:N \g_tmpa_ior

\prop_show:N \g_sfkatalog_ior_prop % for debugging

相关内容