Example: Nice shaded/framed paragraphs using tikz and framed

Published 2012-01-04 | Author: Jose Luis Diaz

The ‘framed’ package implements not only environments to add a frame/shade to any paragraph, allowing page breaks in the contents. It also provides mechanisms for designing your own frames.

In this example, I show how tikz can be combined with framed to draw arbitrary shapes around framed paragraphs, even with different style for the borders which happen at page boundaries.

In this case, a ``parchment’’ environment is created which adds a shadow to the paragraph, whose borders are not straigh, but slightly random, simulating the irregular edges of a parchment. If the paragraph is broken across pages, the ``broken’’ edge is slightly more random and pale, as if the paper was torn.

Download as: [PDF] [TEX]

Nice shaded/framed paragraphs using tikz and framed

Do you have a question regarding this example, TikZ or LaTeX in general? Just ask in the LaTeX Forum.
Oder frag auf Deutsch auf TeXwelt.de. En français: TeXnique.fr.

% Nice shaded/framed paragraphs using tikz and framed
% Author: Jose Luis Diaz
\documentclass[a5paper]{article}
\usepackage{lipsum}   % To generate test text 
\usepackage{framed}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing,calc}
\pgfmathsetseed{1} % To have predictable results
% Define a background layer, in which the parchment shape is drawn
\pgfdeclarelayer{background}
\pgfsetlayers{background,main}

% define styles for the normal border and the torn border
\tikzset{
  normal border/.style={orange!30!black!10, decorate, 
     decoration={random steps, segment length=2.5cm, amplitude=.7mm}},
  torn border/.style={orange!30!black!5, decorate, 
     decoration={random steps, segment length=.5cm, amplitude=1.7mm}}}

% Macro to draw the shape behind the text, when it fits completly in the
% page
\def\parchmentframe#1{
\tikz{
  \node[inner sep=2em] (A) {#1};  % Draw the text of the node
  \begin{pgfonlayer}{background}  % Draw the shape behind
  \fill[normal border] 
        (A.south east) -- (A.south west) -- 
        (A.north west) -- (A.north east) -- cycle;
  \end{pgfonlayer}}}

% Macro to draw the shape, when the text will continue in next page
\def\parchmentframetop#1{
\tikz{
  \node[inner sep=2em] (A) {#1};    % Draw the text of the node
  \begin{pgfonlayer}{background}    
  \fill[normal border]              % Draw the ``complete shape'' behind
        (A.south east) -- (A.south west) -- 
        (A.north west) -- (A.north east) -- cycle;
  \fill[torn border]                % Add the torn lower border
        ($(A.south east)-(0,.2)$) -- ($(A.south west)-(0,.2)$) -- 
        ($(A.south west)+(0,.2)$) -- ($(A.south east)+(0,.2)$) -- cycle;
  \end{pgfonlayer}}}

% Macro to draw the shape, when the text continues from previous page
\def\parchmentframebottom#1{
\tikz{
  \node[inner sep=2em] (A) {#1};   % Draw the text of the node
  \begin{pgfonlayer}{background}   
  \fill[normal border]             % Draw the ``complete shape'' behind
        (A.south east) -- (A.south west) -- 
        (A.north west) -- (A.north east) -- cycle;
  \fill[torn border]               % Add the torn upper border
        ($(A.north east)-(0,.2)$) -- ($(A.north west)-(0,.2)$) -- 
        ($(A.north west)+(0,.2)$) -- ($(A.north east)+(0,.2)$) -- cycle;
  \end{pgfonlayer}}}

% Macro to draw the shape, when both the text continues from previous page
% and it will continue in next page
\def\parchmentframemiddle#1{
\tikz{
  \node[inner sep=2em] (A) {#1};   % Draw the text of the node
  \begin{pgfonlayer}{background}   
  \fill[normal border]             % Draw the ``complete shape'' behind
        (A.south east) -- (A.south west) -- 
        (A.north west) -- (A.north east) -- cycle;
  \fill[torn border]               % Add the torn lower border
        ($(A.south east)-(0,.2)$) -- ($(A.south west)-(0,.2)$) -- 
        ($(A.south west)+(0,.2)$) -- ($(A.south east)+(0,.2)$) -- cycle;
  \fill[torn border]               % Add the torn upper border
        ($(A.north east)-(0,.2)$) -- ($(A.north west)-(0,.2)$) -- 
        ($(A.north west)+(0,.2)$) -- ($(A.north east)+(0,.2)$) -- cycle;
  \end{pgfonlayer}}}

% Define the environment which puts the frame
% In this case, the environment also accepts an argument with an optional
% title (which defaults to ``Example'', which is typeset in a box overlaid
% on the top border
\newenvironment{parchment}[1][Example]{%
  \def\FrameCommand{\parchmentframe}%
  \def\FirstFrameCommand{\parchmentframetop}%
  \def\LastFrameCommand{\parchmentframebottom}%
  \def\MidFrameCommand{\parchmentframemiddle}%
  \vskip\baselineskip
  \MakeFramed {\FrameRestore}
  \noindent\tikz\node[inner sep=1ex, draw=black!20,fill=white, 
          anchor=west, overlay] at (0em, 2em) {\sffamily#1};\par}%
{\endMakeFramed}

% Main document, example of usage
\pagestyle{empty}
\begin{document}
\begin{parchment}[Short text]
  \lipsum[11]
\end{parchment}
\lipsum[11]
\begin{parchment}[Long text spanning over pages]
\lipsum[11]
  \begin{itemize}
    \item \lipsum[14]
  \end{itemize}
\lipsum
\end{parchment}
\end{document}

Comments

  • #1 Chris, January 4, 2012 at 6:01 p.m.

    It would be nice, if the continuing frame has exactly the same border as the continued.

  • #2 Clemens, January 5, 2012 at 1:55 p.m.

    Nice one!

  • #3 Charlie, January 5, 2012 at 11:55 p.m.

    Very nice! I happen to be working on this exact problem this afternoon. This example will provide an excellent place to start.

  • #4 Constantine Tsardounis, January 31, 2013 at 12:56 a.m.

    ...regarding my previous comment, it can safely be deleted, there was an accidental typo after copy/pasting your code. Well done, and thank you !!!

  • #5 Horsen, April 30, 2013 at 3:50 p.m.

    How to remove the optional title (which defaults to ``Example'', which is typeset in a box overlaid on the top border

  • #6 Xan, July 4, 2013 at 6:15 p.m.

    How to do this with ConTeXt instead of LaTeX?

Adding comments is currently not enabled.