[Tex/LaTex] Apply gradient (shading) background to algorithm listing

boxescolorgradientgraphicslyx

Background

A number of source files are included within floating algorithm boxes. The source files are PNG images with a transparent background. The document is edited using LyX.

Problem

The source code listings (algorithms) are applied to the document as follows:

% Change the background colour of algorithm boxes.
\let\oldalgorithm\algorithm
\let\endoldalgorithm\endalgorithm
\renewenvironment{algorithm}[1][htbp]{
  \let\graphicsformat\justifiedandcolored
  \oldalgorithm[#1]
}%
  {\endoldalgorithm}

% Change the background colour of the algorithm floats.
\def\justifiedandcolored#1{%
  \setlength\fboxrule{0pt}%
  \setlength\fboxsep{0pt}%
  \kern-1.35pt
  \colorbox{sourcecolour}{%
    \hbox to\linewidth{#1}%
  }%
  \par
  \kern-1.5pt
}

I would like to change the colorbox to a gradient (rather than a solid colour), using the pst-grad package or perhaps the tikz package.

All the examples I could find for pst-grad show how to apply a gradient to a box with known dimensions. In this situation, the width and height are unknown. The dimensions depend on:

  1. The resolution of the image.
  2. The scaling of the image (large images are scaled down to the page margins).

Example

Here is a small source document:

% Preview source code

%% LyX 1.6.7 created this file.  For more info, see http://www.lyx.org/.
%% Do not edit unless you really know what you are doing.
\documentclass[letterpaper,oneside,english,twoside,pointlessnumbers,obeyspaces,plainpages=false,pdfpagelabels ]{scrbook}
\usepackage{lmodern}
\usepackage{helvet}
\usepackage{courier}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\setcounter{secnumdepth}{3}
\setcounter{tocdepth}{3}
\usepackage{babel}

\usepackage{pifont}
\usepackage{float}
\usepackage{amsmath}
\usepackage{graphicx}
\usepackage{amssymb}
\usepackage[unicode=true, pdfusetitle,
 bookmarks=true,bookmarksnumbered=false,bookmarksopen=false,
 breaklinks=false,pdfborder={0 0 1},backref=false,colorlinks=false]
 {hyperref}

\makeatletter

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LyX specific LaTeX commands.
\special{papersize=\the\paperwidth,\the\paperheight}

%% A simple dot to overcome graphicx limitations
\newcommand{\lyxdot}{.}

\floatstyle{ruled}
\newfloat{algorithm}{tbp}{loa}[chapter]
\floatname{algorithm}{Algorithm}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% User specified LaTeX commands.
\input{example-preamble.tex}

\AtBeginDocument{
  \def\labelitemi{\ding{233}}
  \def\labelitemii{\ding{219}}
  \def\labelitemiii{\normalfont\bfseries{--}}
}

\makeatother

\begin{document}
\input{chapter.tex}


\chapter{Chapter}

%
\begin{algorithm}[H]
\includegraphics{source/sql/beautify-after\lyxdot sql}

\caption{\label{alg:After-Beautification}After Beautification}

\end{algorithm}

\end{document}

Here is the example-preamble.tex:

\usepackage{algorithm}
\usepackage{caption}
\usepackage{float}
\usepackage{graphicx}
\usepackage[T1]{fontenc}
\usepackage{mathptmx}
\usepackage[automark,nouppercase]{scrpage2}
\usepackage[dvipsnames,svgnames,x11names,table]{xcolor}

% Use a hyphen for captions, and make links give a bit of space.
\captionsetup{hypcapspace=0.5\baselineskip}
\captionsetup{labelfont=bf,labelsep=endash}
\captionsetup[ruled]{labelfont=bf,labelsep=endash}

% Change algorithm to "Listing".
\floatname{algorithm}{Listing}
\newcommand{\algorithmname}{Listing}

% Colour definitions.
\input{colours.tex}

% Determine if the image is too wide for the page.
\makeatletter
\def\ScaleIfNeeded{%
  \ifdim\Gin@nat@width>\linewidth
    \linewidth
  \else
    \Gin@nat@width
  \fi
}
\makeatother

% Resize figures that are too wide for the page.
\let\oldincludegraphics\includegraphics
\renewcommand\includegraphics[2][]{%
  \graphicsformat{%
    \oldincludegraphics[width=\ScaleIfNeeded]{#2}%
  }%
}

% Centre graphics within non-Algorithm floats.
\let\graphicsformat\centering

% Change the background colour of algorithm boxes.
\let\oldalgorithm\algorithm
\let\endoldalgorithm\endalgorithm
\renewenvironment{algorithm}[1][htbp]{
  \let\graphicsformat\justifiedandcolored
  \oldalgorithm[#1]
}%
  {\endoldalgorithm}

% Change the background colour of the algorithm floats.
\def\justifiedandcolored#1{%
  \setlength\fboxrule{0pt}%
  \setlength\fboxsep{0pt}%
  \kern-1.35pt
  \colorbox{sourcecolour}{%
    \hbox to\linewidth{#1}%
  }%
  \par
  \kern-1.5pt
}

% Required by LyX...
\makeatletter

Example image:

enter image description here

Example PDF:

enter image description here

Question

What is the best way to replace colorbox with a gradient?

Ideas

One idea I had was to use ImageMagick on the image and add a gradient that way. If I decide to change the gradient colours, I'd have to regenerate dozens of source files. This solution would work, but is not ideal.

Thank you!

Best Answer

You can use tikz with the backgrounds library for this. You need to load tikz and the backgrounds library after the xcolor package, so this would have to be placed in your example-preamble.tex

\usepackage{tikz}
\usetikzlibrary{backgrounds}

In your example-preamble.tex, change the definition of \justifiedandcolored to this:

\def\justifiedandcolored#1{%
  \setlength\fboxrule{0pt}%
  \setlength\fboxsep{0pt}%
  \tikz[background rectangle/.style={top color=red!20,bottom color=white},
  tight background,
  show background rectangle] 
  \node [inner sep=0pt] (0,0) {#1};%
}

Which will yield the following output:

enter image description here