在我的书中,我得到了许多不同类型的盒子,所以我制作了一些宏,根据它们的参数自动放置盒子。
这是其中之一。到目前为止,我制作了一些里面有大“+”和“-”的盒子,还有一些里面有小“+”和“-”的盒子。如果我能设法根据盒子的高度调整标志的大小,那就太好了。
\documentclass{book}
\usepackage{xstring}
\usepackage[many]{tcolorbox}
\usepackage{calc}
\usetikzlibrary{calc}
\definecolor{mp}{RGB}{240,240,240}
\newcommand{\bround}{
\draw[rounded corners=15pt,color=mp,line width=1pt,fill=white]
(frame.south west) --
(frame.north west) --
(frame.north east) --
(frame.south east) -- cycle;
}
\newcommand{\sep}{
\draw[color=mp,line width=1pt]
([yshift=10pt]segmentation.south) -- ([yshift=-10pt]segmentation.north);
}
\newcommand{\ds}[1]{
\IfEqCase{#1}{%
{bpl}{\dosign{0.25}{x}{y}{0}{0}{20}{-50}{50}{-60}}%
{bmr}{\dosign{0.75}{x}{x}{0}{0}{20}{-50}{50}{-60}}%
}[\PackageError{ds}{Undefined option to ds: #1}{}]%
}
\newcommand{\dosign}[9]{
\coordinate (xl) at ($ (frame.west)!#1!(frame.east) $ );
\coordinate (yl) at ([yshift=#9pt] $ (frame.north)$ );
\draw[line width=#6pt,mp]
([#2shift=#7pt,yshift=#4pt]xl|-yl) -- ([#2shift=#8pt,yshift=#4pt]xl|-yl);
\draw[line width=#6pt,mp]
([#3shift=#7pt,yshift=#5pt]xl|-yl) -- ([#3shift=#8pt,yshift=#5pt]xl|-yl);
}
\newcommand{\doibs}[4]{\scantokens{%
\begin{tcolorbox}[
colback=white,
arc=10pt,
colframe=black,
freelance,
sidebyside,
sidebyside align=top,
frame code=\bround,
segmentation code=\sep,
interior code=\ds{#3}\ds{#4}
]
\raggedright #1 \tcblower \raggedright #2
\end{tcolorbox}}}
\begin{document}
\doibs{A\\A\\A\\A}{B}{bpl}{bmr}
\end{document}
由于我有各种类型的组合(+-、++、--、+=、==、..),我编写这些宏时尽量减少源代码(根据我的技能)。如果我可以在宏中获取高度\ds
,我可以通过重新计算符号的尺寸、坐标等来调整符号。
有人有线索吗?
答案1
更新后的版本:
第一个版本的代码(见下文)有一个问题:如果框高度太大,那么标志将超出其对应的框;这可以通过选择标志长度的最大值来解决。以下代码显示了这样一种可能性;长度(大约)是框高度与其宽度的一半之间的最小值:
\documentclass{book}
\usepackage[paperheight=30cm,textheight=25cm]{geometry}% just for the example
\usepackage{xstring}
\usepackage[many]{tcolorbox}
\usetikzlibrary{calc}
\definecolor{mp}{RGB}{240,240,240}
% To control the line width for the signs
\def\RuleFactor{0.15}
\newcommand{\bround}{
\draw[rounded corners=15pt,color=mp,line width=1pt,fill=white]
(frame.south west) --
(frame.north west) --
(frame.north east) --
(frame.south east) -- cycle;
}
\newcommand{\sep}{
\draw[color=mp,line width=1pt]
([yshift=10pt]segmentation.south) -- ([yshift=-10pt]segmentation.north);
}
\newcommand{\ds}[1]{
\IfEqCase{#1}{%
{pp}{\dosign{0.25}{plus}\dosign{0.75}{plus}}%
{pm}{\dosign{0.25}{plus}\dosign{0.75}{minus}}%
{pe}{\dosign{0.25}{plus}\dosign{0.75}{equal}}%
{mp}{\dosign{0.25}{minus}\dosign{0.75}{plus}}%
{mm}{\dosign{0.25}{minus}\dosign{0.75}{minus}}%
{me}{\dosign{0.25}{minus}\dosign{0.75}{equal}}%
{ep}{\dosign{0.25}{equal}\dosign{0.75}{plus}}%
{em}{\dosign{0.25}{equal}\dosign{0.75}{minus}}%
{ee}{\dosign{0.25}{equal}\dosign{0.75}{equal}}%
}[\PackageError{ds}{Undefined option to ds: #1}{}]%
}
\newcommand{\dosign}[2]{
\coordinate (xl) at ($ (frame.west)!#1!(frame.east) $ );
\IfEq{#2}{plus}{%
\path[mp,draw]
let \p1 = ( $ ([yshift=-5pt]xl|-frame.north) - ([yshift=5pt]xl|-frame.south) $ ),
\p2 = ( $ ([xshift=10pt]frame.west) - ([xshift=-10pt]segmentation.center) $ )
in
([yshift=-{0.5*min(veclen(\x1,\y1),veclen(\x2,\y2))}]xl)
edge[line width={\RuleFactor*min(veclen(\x1,\y1),veclen(\x2,\y2))}]
([yshift={0.5*min(veclen(\x1,\y1),veclen(\x2,\y2))}]xl)
([xshift=-{0.5*min(veclen(\x1,\y1),veclen(\x2,\y2))}]xl)
edge[line width={\RuleFactor*min(veclen(\x1,\y1),veclen(\x2,\y2))}]
([xshift={0.5*min(veclen(\x1,\y1),veclen(\x2,\y2))}]xl)
;
}{}
\IfEq{#2}{minus}{%
\path[line width=6pt,mp,draw]
let \p1 = ( $ ([yshift=-5pt]xl|-frame.north) - ([yshift=5pt]xl|-frame.south) $ ),
\p2 = ( $ ([xshift=10pt]frame.west) - ([xshift=-10pt]segmentation.center) $ )
in
([xshift=-{0.5*min(veclen(\x1,\y1),veclen(\x2,\y2))}]xl)
edge[line width={\RuleFactor*min(veclen(\x1,\y1),veclen(\x2,\y2))}]
([xshift={0.5*min(veclen(\x1,\y1),veclen(\x2,\y2))}]xl)
;
}{}
\IfEq{#2}{equal}{%
\path[line width=6pt,mp,draw]
let \p1 = ( $ ([yshift=-5pt]xl|-frame.north) - ([yshift=5pt]xl|-frame.south) $ ),
\p2 = ( $ ([xshift=10pt]frame.west) - ([xshift=-10pt]segmentation.center) $ )
in
([xshift=-{0.5*min(veclen(\x1,\y1),veclen(\x2,\y2))},yshift={0.12*min(veclen(\x1,\y1),veclen(\x2,\y2))}]xl)
edge[line width={\RuleFactor*min(veclen(\x1,\y1),veclen(\x2,\y2))}]
([xshift={0.5*min(veclen(\x1,\y1),veclen(\x2,\y2))},yshift={0.12*min(veclen(\x1,\y1),veclen(\x2,\y2))}]xl)
([xshift=-{0.5*min(veclen(\x1,\y1),veclen(\x2,\y2))},yshift=-{0.12*min(veclen(\x1,\y1),veclen(\x2,\y2))}]xl)
edge[line width={\RuleFactor*min(veclen(\x1,\y1),veclen(\x2,\y2))}]
([xshift={0.5*min(veclen(\x1,\y1),veclen(\x2,\y2))},yshift=-{0.12*min(veclen(\x1,\y1),veclen(\x2,\y2))}]xl)
;
}{}
}
\newcommand{\doibs}[3]{\scantokens{%
\begin{tcolorbox}[
colback=white,
arc=10pt,
colframe=black,
freelance,
sidebyside,
sidebyside align=top,
frame code=\bround,
segmentation code=\sep,
interior code=\ds{#3}
]
\raggedright #1 \tcblower \raggedright #2
\end{tcolorbox}}}
\begin{document}
\doibs{A\\A\\A\\A}{B}{pm}
\doibs{A\\A\\A\\A}{B}{me}
\doibs{A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A}{B}{pe}
\doibs{A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A}{B}{ep}
\end{document}
第一个版本:
有一种可能性(见下文注释):
\documentclass{book}
\usepackage{xstring}
\usepackage[many]{tcolorbox}
\usetikzlibrary{calc}
\definecolor{mp}{RGB}{240,240,240}
\newcommand{\bround}{
\draw[rounded corners=15pt,color=mp,line width=1pt,fill=white]
(frame.south west) --
(frame.north west) --
(frame.north east) --
(frame.south east) -- cycle;
}
\newcommand{\sep}{
\draw[color=mp,line width=1pt]
([yshift=10pt]segmentation.south) -- ([yshift=-10pt]segmentation.north);
}
\newcommand{\ds}[1]{
\IfEqCase{#1}{%
{pp}{\dosign{0.25}{plus}\dosign{0.75}{plus}}%
{pm}{\dosign{0.25}{plus}\dosign{0.75}{minus}}%
{pe}{\dosign{0.25}{plus}\dosign{0.75}{equal}}%
{mp}{\dosign{0.25}{minus}\dosign{0.75}{plus}}%
{mm}{\dosign{0.25}{minus}\dosign{0.75}{minus}}%
{me}{\dosign{0.25}{minus}\dosign{0.75}{equal}}%
{ep}{\dosign{0.25}{equal}\dosign{0.75}{plus}}%
{em}{\dosign{0.25}{equal}\dosign{0.75}{minus}}%
{ee}{\dosign{0.25}{equal}\dosign{0.75}{equal}}%
}[\PackageError{ds}{Undefined option to ds: #1}{}]%
}
\newcommand{\dosign}[2]{aaa
\coordinate (xl) at ($ (frame.west)!#1!(frame.east) $ );
\IfEq{#2}{plus}{%
\path[mp,draw]
let \p1 = ( $ ([yshift=-5pt]xl|-frame.north) - ([yshift=5pt]xl|-frame.south) $ )
in
([yshift=-5pt]xl|-frame.north)
edge[line width={0.12*veclen(\x1,\y1)}]
([yshift=5pt]xl|-frame.south)
([xshift=-{0.5*veclen(\x1,\y1)}]xl)
edge[line width={0.12*veclen(\x1,\y1)}]
([xshift={0.5*veclen(\x1,\y1)}]xl)
;
}{}
\IfEq{#2}{minus}{%
\path[line width=6pt,mp,draw]
let \p1 = ( $ ([yshift=-5pt]xl|-frame.north) - ([yshift=5pt]xl|-frame.south) $ )
in
([xshift=-{0.5*veclen(\x1,\y1)}]xl)
edge[line width={0.12*veclen(\x1,\y1)}]
([xshift={0.5*veclen(\x1,\y1)}]xl)
;
}{}
\IfEq{#2}{equal}{%
\path[line width=6pt,mp,draw]
let \p1 = ( $ ([yshift=-5pt]xl|-frame.north) - ([yshift=5pt]xl|-frame.south) $ )
in
([xshift=-{0.5*veclen(\x1,\y1)},yshift={0.1*veclen(\x1,\y1)}]xl)
edge[line width={0.12*veclen(\x1,\y1)}]
([xshift={0.5*veclen(\x1,\y1)},yshift={0.1*veclen(\x1,\y1)}]xl)
([xshift=-{0.5*veclen(\x1,\y1)},yshift=-{0.1*veclen(\x1,\y1)}]xl)
edge[line width={0.12*veclen(\x1,\y1)}]
([xshift={0.5*veclen(\x1,\y1)},yshift=-{0.1*veclen(\x1,\y1)}]xl)
;
}{}
}
\newcommand{\doibs}[3]{\scantokens{%
\begin{tcolorbox}[
colback=white,
arc=10pt,
colframe=black,
freelance,
sidebyside,
sidebyside align=top,
frame code=\bround,
segmentation code=\sep,
interior code=\ds{#3}
]
\raggedright #1 \tcblower \raggedright #2
\end{tcolorbox}}}
\begin{document}
\doibs{A\\A\\A\\A}{B}{pp}
\doibs{A}{B}{me}
\doibs{A\\A\\A\\A\\A\\A\\A\\A}{B}{pe}
\doibs{A\\A\\A}{B}{ep}
\doibs{A\\A}{B}{ee}
\end{document}
评论
形状的大小和线宽将根据框的高度自动调整。
请注意,现在
\dosign
只有两个强制参数(而不是原来的九个参数),并且\doibs
只有三个参数。的第三个参数
\doibs
用于决定绘制哪些符号;我为“加号”(p
)、“减号”(m
) 和“等号”(e
) 实现了九种组合。例如,me
在第三个参数中使用表示在左侧绘制“减号”,在右侧绘制“等号”;pm
在第三个参数中使用表示在左侧绘制“加号”,在右侧绘制“减号”。