![switch case 中的 Ifoddpage 语句](https://linux22.com/image/398750/switch%20case%20%E4%B8%AD%E7%9A%84%20Ifoddpage%20%E8%AF%AD%E5%8F%A5.png)
继续讨论主题 tcolorbox:奇数页和偶数页的特定宽度和高度设置和前页或后页的距离可变。
我想根据宏的扩展(\C
这里,由我的代码设置datatool
)以及我们是在奇数页还是偶数页有条件地设置长度:
\C = 1 & ifoddpage = true => \xLength = 2cm, \yLength = 1.5cm
\C = 1 & ifoddpage = false => \xLength = 4cm, \yLength = 2cm
\C = 2 & ifoddpage = true => \xLength = 3cm, \yLength = 2cm
\C = 2 & ifoddpage = false => \xLength = 5cm, \yLength = 3cm
\C = 3 & ifoddpage = true => \xLength = 4cm, \yLength = 3cm
\C = 3 & ifoddpage = false => \xLength = 4cm, \yLength = 1.5cm
…
\C = 10...
以下是基于以上链接代码的最少代码:
\documentclass{article}
\usepackage{datatool}
\usepackage[strict]{changepage}
\usepackage{filecontents}
\usepackage{tcolorbox}
\usepackage[absolute,overlay]{textpos}
\usepackage{xcolor}
\begin{filecontents*}{test1.csv}
Acol, Bcol,Ccol
Ax,Bx,1
Ay,By,3
A1,B22,1
A2,B44,2
A3,B11,3
A4,B55,4
\end{filecontents*}
\DTLloaddb{mydata1}{test1.csv}
\newlength{\xlengthForOddPages}
\newlength{\xlengthForEvenPages}
\newlength{\ylengthForOddPages}
\newlength{\ylengthForEvenPages}
\setlength{\xlengthForOddPages}{2cm}
\setlength{\xlengthForEvenPages}{10cm}
\setlength{\ylengthForOddPages}{1.5cm}
\setlength{\ylengthForEvenPages}{5cm}
\newif\ifmyoddpage % always set globally, contrary to \ifoddpage
\newcommand*{\xpageDependent}{%
\ifmyoddpage
\expandafter
\xlengthForOddPages
\else
\expandafter
\xlengthForEvenPages
\fi
}
\newcommand*{\ypageDependent}{%
\ifmyoddpage
\expandafter
\ylengthForOddPages
\else
\expandafter
\ylengthForEvenPages
\fi
}
\newcommand*{\mycheckoddpage}{%
\checkoddpage
\global\let\ifmyoddpage=\ifoddpage
}
\newlength{\xLength}
\newlength{\yLength}
\begin{document}
\DTLforeach*{mydata1}{\A=Acol,\B=Bcol,\C=Ccol}%
{%
\begin{tcolorbox}[phantom={\mycheckoddpage},
width=\xpageDependent,height=\ypageDependent,
title={Title}]
\C
\end{tcolorbox}
% --> Here, \xLength and \yLength should be set according
% to the conditions described above. <--
\begin{textblock*}{5cm}(\xLength,\yLength)
\color{red} text abc
\end{textblock*}
\newpage
}
\end{document}
提前致谢。
答案1
如果我正确理解了您的需求,那么以下内容应该可以满足您的要求:
\documentclass{article}
\usepackage{datatool}
\usepackage[strict]{changepage}
\usepackage{filecontents}
\usepackage{tcolorbox}
\usepackage[absolute,overlay]{textpos}
\usepackage{xcolor}
\usepackage{xparse}
\begin{filecontents*}{test1.csv}
Acol, Bcol,Ccol
Ax,Bx,1
Ay,By,3
A1,B22,1
A2,B44,2
A3,B11,3
\end{filecontents*}
% If you include a line such as 'A4,B55,4' without saying how \xLength and
% \yLength should be set in this case, you'll get the error message:
%
% Package lforti Error: Encountered value '4', but no case was written for it.
\DTLloaddb{mydata1}{test1.csv}
\newlength{\xlengthForOddPages}
\newlength{\xlengthForEvenPages}
\newlength{\ylengthForOddPages}
\newlength{\ylengthForEvenPages}
\setlength{\xlengthForOddPages}{2cm}
\setlength{\xlengthForEvenPages}{10cm}
\setlength{\ylengthForOddPages}{1.5cm}
\setlength{\ylengthForEvenPages}{5cm}
\newif\ifmyoddpage % always set globally, contrary to \ifoddpage
\newcommand*{\xpageDependent}{%
\ifmyoddpage
\expandafter
\xlengthForOddPages
\else
\expandafter
\xlengthForEvenPages
\fi
}
\newcommand*{\ypageDependent}{%
\ifmyoddpage
\expandafter
\ylengthForOddPages
\else
\expandafter
\ylengthForEvenPages
\fi
}
\newcommand*{\mycheckoddpage}{%
\checkoddpage
\global\let\ifmyoddpage=\ifoddpage
}
\ExplSyntaxOn
\msg_new:nnn { lforti } { unhandled-value }
{ Encountered~value~'\exp_not:n~{#1}',~but~no~case~was~written~for~it. }
\tl_new:N \l__lforti_cond_length_setup_conds_tl
\seq_new:N \l__lforti_cond_length_setup_tmpa_seq
\seq_new:N \l__lforti_cond_length_setup_tmpb_seq
% Flexible length setup that may depend on whether it is called on an odd page
% or on an even page.
%
% #1: a LaTeX length command (or a TeX \skipdef token) to set according to
% #2 and #3
% #2: the value to test against
% #3: a comma list describing the different cases:
%
% {
% {value_1, length-for-odd-pages, length-for-even-pages},
% {value_2, length-for-odd-pages, length-for-even-pages},
% ...
% {value_n, length-for-odd-pages, length-for-even-pages},
% }
%
% #2 is compared against value_1, value_2, ..., value_n to determine a
% matching “line”, then length command #1 is set to the length-for-odd-pages or
% length-for-even-pages of the matching line, depending on whether the label set
% by \checkoddpage (used at the beginning of the function) is located on an
% odd page or on an even page.
\cs_new_protected:Npn \lforti_cond_length_setup:Nnn #1#2#3
{
\checkoddpage % make sure it is used on the relevant page
\seq_set_from_clist:Nn \l__lforti_cond_length_setup_tmpa_seq {#3}
\tl_clear:N \l__lforti_cond_length_setup_conds_tl
\seq_map_inline:Nn \l__lforti_cond_length_setup_tmpa_seq
{
\seq_set_from_clist:Nn \l__lforti_cond_length_setup_tmpb_seq {##1}
\tl_put_right:Nx \l__lforti_cond_length_setup_conds_tl
{
% Value to check against
{ \seq_item:Nn \l__lforti_cond_length_setup_tmpb_seq { 1 } }
{ % Corresponding setup code for #1
\exp_not:n { \skip_set:Nn #1 }
{
\seq_item:Nn
\l__lforti_cond_length_setup_tmpb_seq
{ \ifoddpage 2 \else 3 \fi }
}
}
}
}
% Handle value #2 according to the cases described by
% \l__lforti_cond_length_setup_conds_tl, which was assembled from #3
\str_case:nVF {#2} \l__lforti_cond_length_setup_conds_tl
{ \msg_error:nnn { lforti } { unhandled-value } {#2} }
}
\cs_generate_variant:Nn \lforti_cond_length_setup:Nnn { Nx }
% Same as \lforti_cond_length_setup:Nnn (see above), except that the second
% argument will be fully expanded (\lforti_cond_length_setup:Nnn will only see
% the *result* of this expansion in its #2).
\NewDocumentCommand \lforticondlengthsetup { m m m }
{
\lforti_cond_length_setup:Nxn #1 {#2} {#3}
}
\ExplSyntaxOff
\newlength{\xLength}
\newlength{\yLength}
\begin{document}
\DTLforeach*{mydata1}{\A=Acol,\B=Bcol,\C=Ccol}%
{%
\lforticondlengthsetup{\xLength}{\C}{%
{1, 2cm, 4cm}, % When \C expands to 1, use 2cm on odd pages, 4cm on even pages
{2, 3cm, 5cm}, % When \C expands to 2, use 3cm on odd pages, 5cm on even pages
{3, 4cm, 4cm}, % When \C expands to 3, use 4cm on all pages
}%
\lforticondlengthsetup{\yLength}{\C}{% analogous setup for \yLength
{1, 1.5cm, 2cm},
{2, 2cm, 3cm},
{3, 3cm, 1.5cm},
}%
\begin{textblock*}{5cm}(\xLength,\yLength)
\color{blue!50!black}%
\noindent
\texttt{\string\xLength} = \the\xLength\\
\texttt{\string\yLength} = \the\yLength
\end{textblock*}
\begin{tcolorbox}[phantom={\mycheckoddpage},
width=\xpageDependent,height=\ypageDependent,
title={Title}]
\C
\end{tcolorbox}
\newpage
}
\end{document}
以下是每个页面的顶部:
我的代码依赖于我调用的灵活长度设置命令\lforticondlengthsetup
。此命令要求其第一个参数是 LaTeX 长度命令(或 TeX\skipdef
标记)。它完全展开其第二个参数,并将结果与第三个参数中指定的每个子列表的第一个元素进行比较。例如,\xLength
和\yLength
按以下方式设置以遵循您问题中的规范:
\lforticondlengthsetup{\xLength}{\C}{%
{1, 2cm, 4cm}, % When \C expands to 1, use 2cm on odd pages, 4cm on even pages
{2, 3cm, 5cm}, % When \C expands to 2, use 3cm on odd pages, 5cm on even pages
{3, 4cm, 4cm}, % When \C expands to 3, use 4cm on all pages
}%
\lforticondlengthsetup{\yLength}{\C}{% analogous setup for \yLength
{1, 1.5cm, 2cm},
{2, 2cm, 3cm},
{3, 3cm, 1.5cm},
您必须确保此类长度设置命令在使用\xLength
和的同一页面上发出\yLength
。我上面提供的完整文档中应该是这种情况。
长度值( 的第三个参数中每个子列表的第二个和第三个元素\lforticondlengthsetup
)可以是任何有效的 LaTeX3 〈skip 表达式〉。例如,只要满足以下条件,以下代码就是有效的:
\xLength
并\yLength
已声明\newlength
;\someMacro
递归扩展为1
,或foo
,或(在您的示例中,此角色由扩展到位于文件第三列的值的宏bar baz
扮演)。\C
.csv
\lforticondlengthsetup{\yLength}{\someMacro}{
{1, 0.7\xLength, 2cm plus 0.1cm minus 0.2cm},
{foo, 2cm plus 1fill, 0pt plus 3fill},
{bar baz, 3cm plus 1fil minus 0.2fill, 1.5cm},
}
最后,由于\checkoddpage
使用标签/引用机制,请不要忘记您需要编译几次(通常只需两次)才能获得可靠的结果!