
Estou tentando criar o que parece ser um pedaço de papel de caderno dentro de um tcolorbox
ambiente desenhando linhas horizontais e uma linha vertical. O problema que estou tendo é que não sei como definir o limite superior do número de linhas, a menos que eu as codifique. Isso causa um problema quando a caixa de cores quebra em uma página e as caixas têm alturas diferentes. As linhas são desenhadas na parte inferior da caixa. Se a caixa tiver dois comprimentos diferentes, será difícil fazer com que as linhas pareçam ter sido desenhadas uniformemente a partir do topo.
Como posso obter a altura do tcolorbox? eu tentei\tcbtextheightmas usar isso para a linha vertical nem funciona. Além disso, eu não saberia como escrever o loop com divisões de eventos. De preferência, gostaria que as linhas tivessem o tamanho do espaçamento entre linhas do documento, mas isso não é obrigatório. Depois de obter a altura, eu precisaria que o desenho da linha começasse na parte superior da caixa e não na parte inferior.
\documentclass[letterpaper, 10pt]{article}
\usepackage[skins, raster, breakable]{tcolorbox}
\usepackage{tikz}
\usetikzlibrary{decorations,decorations.markings,optics}
\usepackage[english]{babel}
\usepackage{blindtext}
\begin{document}
\pagestyle{empty}
\tikzset{normal lines/.style={gray, very thin}}
\tcbset{paper/.style={enhanced,colback=green!10,colframe=green!65!black,width=\textwidth,breakable,left=1.3in,
overlay={
\begin{tcbclipframe}
\foreach \y in {0.25, 0.5,...,10.25}
\draw[style=normal lines](0,\y in) -- (8.5in, \y in);
\draw[style=normal lines] (1.25in,0)--(1.25in, 3in);
\end{tcbclipframe}
}
}
}
\blindtext[5]
\begin{tcolorbox}[paper]
\blindtext[2]
\end{tcolorbox}
\end{document}
Responder1
Proponho fazer isso com uma tcolorbox
subpele enhanced
(que é adequada para caixas quebráveis). No código fornecido a seguir, definimos um skin nomeado paper
que é derivado de enhanced
e fazemos o tcolorbox
estilo paper
funcionar skin=paper
(entre outras coisas, como definir a moldura desejada e as cores de fundo). Também definimos três subskins e paperfirst
, respectivamente , derivados de e ; estes permitem-nos dar à caixa o aspecto desejado em todos os casos (ininterrupta, quebrada em cima e não em baixo, quebrada em baixo e não em cima, quebrada em cima e em baixo).papermiddle
paperlast
enhancedfirst
enhancedmiddle
enhancedlast
Como o enhanced
skin define /tcb/geometry nodes=true
, ele define nós nomeados frame
, interior
, segmentation
, e title
que nos permitem acessar pontos interessantes do tcolorbox
. Aqui, pode-se usar frame
ou interior
para calcular a altura da caixa (eles não fornecem exatamente o mesmo resultado que /tcb/leftrule
, /tcb/toprule
, /tcb/rightrule
e /tcb/bottomrule
pertencem a, frame
mas não a interior
). No paper
skin definido abaixo, usamos o interior
nó para calcular o número de réguas horizontais a serem desenhadas e combinações adequadas de frame
e interior
para a extensão da régua vertical, dependendo se a caixa está quebrada no topo e se está quebrada no fundo. O cálculo do número de regras horizontais a serem desenhadas pode ser feito com \pgfmathtruncatemacro
, por exemplo (também pode ser feito int()
dentro de uma \pgfmathsetmacro
chamada).
Nota: fiz uma pequena alteração no seu normal lines
estilo. O line width
é maior, mas as regras são desenhadas com opacity=...
, conforme definido por /tcb/paper/rule opacity
. Este desenho é feito dentro de um transparency group
cujo objetivo é garantir que os cruzamentos de regras não sejam mais escuros do que outros locais das regras.
\documentclass{article}
\usepackage{tcolorbox}
\tcbuselibrary{breakable, skins}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{lipsum}
\makeatletter
\tikzset{normal lines/.style={gray, thin}}
\tcbset{paper/left margin/.initial=1.25in,
paper/line spacing/.initial=1cm,
paper/rule opacity/.initial=0.4,
paper/.style={
skin=paper, colback=green!10, colframe=green!65!black,
breakable, left=1.3in,
}
}
\newif\if@paper@broken@top
\newif\if@paper@broken@bottom
\pgfkeys{/tcb/paper/broken top/.is if=@paper@broken@top,
/tcb/paper/broken bottom/.is if=@paper@broken@bottom
}
% The various parts don't have the same skin when a box is broken. This also
% influences where we want the vertical rule to extend to.
\tcbsubskin{paperfirst}{enhancedfirst}{
paper/broken top=false, paper/broken bottom=true
}
\tcbsubskin{papermiddle}{enhancedmiddle}{
paper/broken top=true, paper/broken bottom=true
}
\tcbsubskin{paperlast}{enhancedlast}{
paper/broken top=true, paper/broken bottom=false
}
\tcbsubskin{paper}{enhanced}{
skin first=paperfirst, skin middle=papermiddle, skin last=paperlast,
paper/broken top=false, paper/broken bottom=false,
overlay={
\begin{tcbclipinterior}
\begin{scope}[opacity=\pgfkeysvalueof{/tcb/paper/rule opacity},
transparency group]
% Make sure the vertical rule extends exactly as far as we want, depending
% on where the box is broken.
\if@paper@broken@top
\coordinate (top for vert rule) at (frame.north west);
\else
\coordinate (top for vert rule) at (interior.north west);
\fi
%
\if@paper@broken@bottom
\coordinate (bottom for vert rule) at (frame.south west);
\else
\coordinate (bottom for vert rule) at (interior.south west);
\fi
%
\draw[transform canvas={xshift=\pgfkeysvalueof{/tcb/paper/left margin}},
style=normal lines] (top for vert rule) -- (bottom for vert rule);
%
\path let \p1=($(interior.north)-(interior.south)$) in
\pgfextra{%
\pgfmathtruncatemacro{\tmp}{veclen(\p1) /
\pgfkeysvalueof{/tcb/paper/line spacing}}%
\xdef\paperskin@nblines{\tmp}};
\foreach \i in {1,..., \paperskin@nblines} {
\pgfmathsetlengthmacro{\paperskin@shift}{
-\i*\pgfkeysvalueof{/tcb/paper/line spacing}}
\draw[style=normal lines]
([yshift=\paperskin@shift]interior.north west) --
([yshift=\paperskin@shift]interior.north east);
}
\end{scope}
\end{tcbclipinterior}
},
}
\makeatother
\pagestyle{empty}
\begin{document}
\lipsum[1]
\begin{tcolorbox}[paper]
\lipsum[2]
\end{tcolorbox}
\lipsum[3]
\begin{tcolorbox}[paper]
\lipsum[4-5]
\end{tcolorbox}
\end{document}
Caixa intacta:
first
parte da caixa quebrada:
last
parte da caixa quebrada:
Uma middle
parte (quebrada no topoena parte inferior) também seria desenhado corretamente, com a regra vertical estendendo-se até onde desejado:
Nota: a seguinte parte do meu código:
\tcbsubskin{paper}{enhanced}{
...
overlay={
...
% Make sure the vertical rule extends exactly as far as we want, depending
% on where the box is broken.
\if@paper@broken@top
\coordinate (top for vert rule) at (frame.north west);
\else
\coordinate (top for vert rule) at (interior.north west);
\fi
%
\if@paper@broken@bottom
\coordinate (bottom for vert rule) at (frame.south west);
\else
\coordinate (bottom for vert rule) at (interior.south west);
\fi
pode ser escrito desta forma também:
\newcommand*{\paper@defcoord}[3]{
\coordinate (#2 for vert rule) at (#1.#3 west);
}
\tcbsubskin{paper}{enhanced}{
...
overlay={
...
% Make sure the vertical rule extends exactly as far as we want, depending
% on where the box is broken.
\edef\tmp{\if@paper@broken@top frame\else interior\fi}
\expandafter\paper@defcoord\expandafter{\tmp}{top}{north}
\edef\tmp{\if@paper@broken@bottom frame\else interior\fi}
\expandafter\paper@defcoord\expandafter{\tmp}{bottom}{south}
mas a primeira forma parece muito mais fácil de ler, portanto foi esta que decidi manter no exemplo completo.
Responder2
Em vez de uma grade desenhada à mão, você pode usar uma TikZ
grade com um formato grande xstep
. O código a seguir mostra uma possível solução (inspirada no exemplo da tcolorbox
documentação, página 131). Não resolve o problema de caixas quebradas e ajuste da posição vertical.
\documentclass{article}
\usepackage[most]{tcolorbox}
\usepackage{lmodern}
\usepackage{blindtext}
\newtcolorbox{notebook}{
enhanced,
breakable,
colback=green!10,
colframe=green!65!black,
left=1.3in,
underlay={%
\begin{tcbclipinterior}
\draw[help lines, ystep=\baselineskip, xstep=\linewidth,
shift={(interior.north west)}](interior.south west) grid (interior.north east);
\draw[help lines] ([xshift=1.25in]interior.north west)--
([xshift=1.25in]interior.south west);
\end{tcbclipinterior}}
}
\begin{document}
\blindtext[1]
\begin{notebook}
\blindtext[3]
\end{notebook}
\end{document}