
Estoy tratando de crear lo que parece un fragmento de papel de cuaderno dentro de un tcolorbox
entorno dibujando líneas horizontales y una línea vertical. El problema que tengo es que no sé cómo definir el límite superior del número de líneas a menos que las codifique. Esto causa un problema cuando el cuadro de color se divide en una página y los cuadros tienen diferentes alturas. Las líneas se dibujan desde la parte inferior del cuadro. Si el cuadro tiene dos longitudes diferentes, entonces es difícil hacer que las líneas parezcan haber sido espaciadas uniformemente desde la parte superior.
¿Cómo puedo obtener la altura del tcolorbox? He intentado\tcbtextheightpero usar eso para la línea vertical ni siquiera funciona. Además, no sabría cómo escribir el bucle con divisiones de eventos. Preferiblemente, me gustaría que las líneas tuvieran el tamaño del interlineado del documento, pero eso no es necesario. Después de obtener la altura, necesitaría que el dibujo lineal comenzara desde la parte superior del cuadro y no desde la 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}
Respuesta1
Propongo hacer esto con una tcolorbox
subpiel de enhanced
(que es adecuada para cajas rompibles). En el código que se proporciona a continuación, definimos un aspecto paper
cuyo nombre se deriva de enhanced
y hacemos que el tcolorbox
estilo paper
funcione skin=paper
(entre otras cosas, como configurar el marco y los colores de fondo deseados). También definimos tres submáscaras paperfirst
, papermiddle
y paperlast
respectivamente derivadas de enhancedfirst
, enhancedmiddle
y enhancedlast
; éstas nos permiten darle a la caja el aspecto deseado en todos los casos (integra, rota arriba y no abajo, rota abajo y no arriba, rota tanto arriba como abajo).
Como el enhanced
skin se fija /tcb/geometry nodes=true
, define nodos llamados frame
, interior
, segmentation
, y title
que nos permiten acceder a puntos interesantes del tcolorbox
. Aquí, se puede usar frame
o para calcular la altura de interior
la caja (estos no dan exactamente el mismo resultado que /tcb/leftrule
, y pertenecen a pero no a ). En el aspecto definido a continuación, usamos el nodo para calcular el número de reglas horizontales a dibujar y combinaciones adecuadas de y para la extensión de la regla vertical, dependiendo de si el cuadro está roto en la parte superior y si está roto en la parte superior. abajo. El cálculo del número de reglas horizontales a dibujar se puede hacer con , por ejemplo (también se puede hacer dentro de una llamada)./tcb/toprule
/tcb/rightrule
/tcb/bottomrule
frame
interior
paper
interior
frame
interior
\pgfmathtruncatemacro
int()
\pgfmathsetmacro
Nota: hice un pequeño cambio en tu normal lines
estilo. El line width
es más grande, pero las reglas se dibujan con opacity=...
, como lo define /tcb/paper/rule opacity
. Este dibujo se realiza dentro de un transparency group
cuyo propósito es garantizar que los cruces de reglas no sean más oscuros que otros lugares de las reglas.
\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}
Caja intacta:
first
parte de la caja rota:
last
parte de la caja rota:
Una middle
parte (rota en la parte superior)yen la parte inferior) también se dibujaría bien, con la regla vertical extendiéndose tanto como se desee:
Nota: la siguiente parte de mi 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
También se puede escribir de esta manera:
\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}
pero la primera forma parece mucho más fácil de leer, por eso esta es la que decidí mantener en el ejemplo completo.
Respuesta2
En lugar de una cuadrícula dibujada a mano, puedes usar una TikZ
cuadrícula con un tamaño grande xstep
. El siguiente código muestra una posible solución (inspirada en el ejemplo de tcolorbox
la documentación, página 131). No soluciona el problema de las cajas rotas y del ajuste de la posición 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}