根据 tcolorbox 的高度调整 tcolorbox 中 tikzfigure 的大小

根据 tcolorbox 的高度调整 tcolorbox 中 tikzfigure 的大小

在我的书中,我得到了许多不同类型的盒子,所以我制作了一些宏,根据它们的参数自动放置盒子。在此处输入图片描述

这是其中之一。到目前为止,我制作了一些里面有大“+”和“-”的盒子,还有一些里面有小“+”和“-”的盒子。如果我能设法根据盒子的高度调整标志的大小,那就太好了。

\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}

在此处输入图片描述

评论

  1. 形状的大小和线宽将根据框的高度自动调整。

  2. 请注意,现在\dosign只有两个强制参数(而不是原来的九个参数),并且\doibs只有三个参数。

  3. 的第三个参数\doibs用于决定绘制哪些符号;我为“加号”( p)、“减号”( m) 和“等号”( e) 实现了九种组合。例如,me在第三个参数中使用表示在左侧绘制“减号”,在右侧绘制“等号”;pm在第三个参数中使用表示在左侧绘制“加号”,在右侧绘制“减号”。

相关内容