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