Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I've looked at the demo of Beeline reader and would like to test it out on a physical version of my books, which are done in LaTeX. I'm wondering if it would even be possible.

Beeline reader takes online test a puts a slight gradient on the letters for a single line of text. On the next line it reverses the direction of the gradient. The idea being that it helps tracking text and improves speed of reading.

Any hints or suggestions as to how to do this in LaTeX?

What follows is an example taken from http://www.beelinereader.com/

enter image description here

share|improve this question
Could you post an image of the effect that you want to see. The demo does not load for me. –  Aditya Sep 6 '13 at 15:17
add comment

2 Answers

with thanks to

How to put color gradient to "Desired Text Only"

enter image description here



    \node [text=white] {#1};
      \node [text=white,inner sep=0pt,outer sep=0pt] (textnode) {#1};
      \shade[path fading=tikzsection,fit fading=false,left color=\lcolor,right color=\rcolor]
      (textnode.south west) rectangle (textnode.north east);



\section{Grr dasadsa}

% at this point we are at the end of box 2 now
% loop backwards up the vertical list copying glue and penalties
% but modifying boxesto add the prefix.
% an e-tex primitive that reports the last item in the vertical list.
% type 1 is a box, so remove the box (a lien of text) and then
% put into box 1 a box that is this box together with the prefix which
% was saved in box 0
% type 11 is glue so remove it from this list and add
% equivalent glue to box 1
% same for penalty
\global\setbox1\vbox{\penalty\count0 \unvbox1}%
% other node types are not handled here: either they won't happen
% or they can't be removed anyway so would break the loop \special
% for example would be bad.
% -1 means the vertical list is empty: we have reached the top of the box.

% Tip the modified box back onto the main list for the page, unbox
% it so that page breaking may still happen (if it could happen in the
% original context).

share|improve this answer
That's great, David. However, beeline seems to use three colours. I think the rationale may be that, if only two colours are used, there is a greater risk of skipping a line when reading the middle of a block of text (because the colour of two successive lines is the same in the middle). That risk is somewhat reduced with three colours. –  Jubobs Sep 6 '13 at 16:30
@Jubobs ah you mean each row just has two colours but you cycle a-b b-c c-a ? that is easily done just modify the \ifx block in the niddle to cycle the two colour macros. –  David Carlisle Sep 6 '13 at 16:37
@Jubobs oh no the image added to the question goes black-red red-black black-blue blue-black but again it's just how you switch lcolor and rcolor macros –  David Carlisle Sep 6 '13 at 16:41
Thanks for your answer, I tried to apply this to my book and pegged the CPU for a couple hours before I killed it... –  matt harrison Sep 11 '13 at 4:11
@mattharrison It might take a fraction longer than normal but if it takes a lot longer then it is in an infinite loop almost certainly because there is a non-removable item such as a \special or a write on the main vertical list. (Note I disabled \write in the above) You can apply the system more locally on a per-paragraph basis, and also put in a test to check for non-removable items (you could not recover cleanly but at least you could abort the loop) or to avoid the restriction on not being able to remove unremovable items you need to leave tex, hence the luatex version in the other answer. –  David Carlisle Sep 11 '13 at 8:17
show 1 more comment

That’s a wonderful use case for Luatex! (In fact, when I read the about the bee colors yesterday I was hoping for this question to pop up on TeX-SE.) So, without further ado, here is the necessary code. This requires Luaotfload, which Latex users do not have to load explicitly if they are using the fontspec package.

The beecolors code is split into a TeX and a Lua file. The Lua part (beegradients.lua) implements a node processor for the post_linebreak_filter callback. The principle is quite simple: It scans the horizontal lists that constitute a paragraph for glyphs and ligatures which it surrounds with the appropriate PDF color whatsits, recursing into any vlists an hlists it encounters along the way.

The second file (beegradients.tex) contains wrapper macros for defining gradients and toggling the callback. A gradient group is a list of color expressions and can be defined like this:

\definegradientgroup [<name>][<col1>,<col2>, ... ,<coln>]


\definegradientgroup [blackwhite][0x000000, 0xFFFFFF]

installs a gradient list consisting of two colors, black and white. Likewise,

\definegradientgroup [red-green-blue][255*0*0, 0*255*0, 0*0*255]

defines a list of three colors, red, green and blue.

These gradient groups can afterwards be referred to by their names. The callback can be activated by means of an environment beegradients:

\startbeegradients [<name>]
  ... ... ...

Where <name> refers to a previously defined gradient group. E.g., in order to use the groups blackwhite and red-green-blue we defined above:

\startbeegradients [blackwhite]
  \input knuth

\startbeegradients [red-green-blue]
  \input knuth

Without the optional argument, \startbeegradients will choose the last active group.

\startbeegradients [blackwhite]
  \input knuth

foo bar baz       %% <- no gradient

  \input knuth    %% <- black and white again

Here is a complete example for the Plain format that shows a couple definitions:

\input luaotfload.sty
\input beegradients.tex

\font \mainfont = file:Iwona-Regular.otf at 10pt

\definegradientgroup [mygradients][
  42*11*242,        %% decimal notation, separated by “*”
  0xf00ba7,         %% hex notation
  g:23*b:42*r:133,  %% rgb notation, also separated by “*”

\definegradientgroup     [blackwhite][0x000000, 0xFFFFFF]
\definegradientgroup [red-green-blue][255*0*0, 0*255*0, 0*0*255]
\definegradientgroup            [red][255*0*0, 0*0*0]
\definegradientgroup          [green][0*100*0, 0*255*0]
\definegradientgroup           [blue][0*0*20, 0*0*210]

\input knuth

\startbeegradients [mygradients]    \input knuth \stopbeegradients
\startbeegradients [blackwhite]     \input knuth \stopbeegradients
\startbeegradients [red-green-blue] \input knuth \stopbeegradients
\startbeegradients [red]            \input knuth \stopbeegradients
\startbeegradients [green]          \input knuth \stopbeegradients
\startbeegradients [blue]           \input knuth \stopbeegradients



Colorful Plain TeX document

Of course the code is compatible with Latex, you can load it directly:

\documentclass {scrartcl}
\usepackage {fontspec} %% this loads luaotfload as well
\setmainfont {Antykwa Poltawskiego}
\input beegradients.tex

\definegradientgroup [red-green-blue][255*0*0, 0*255*0, 0*0*255]

\begin {document}
  \startbeegradients [red-green-blue]
    \input knuth
\end {document}

Which leads to this colorful document:

Colorful Latex document

share|improve this answer
Thanks for your answer. I'm a LuaTex newbie, but am getting the following error:! LuaTeX error ./beegradients.lua:32: attempt to index local 'nodecodes' (a nil value) stack traceback: ./beegradients.lua:32: in main chunk [C]: in function 'require' ...exlive/texmf-dist/tex/luatex/luatexbase/modutils.lua:52: in function 'requi re_module' <\directlua >:1: in main chunk. \lltxb@requirelua ...xluaescapestring {#2}" \fi )} l.2 I'm at a loss on how to deal with this... –  matt harrison Sep 7 '13 at 21:13
@mattharrison your Luaotfload is probably too old. What TeX distribution are you using? –  phg Sep 7 '13 at 21:18
luatex --version This is LuaTeX, Version beta-0.70.2-2012091206 (TeX Live 2012/Debian) –  matt harrison Sep 7 '13 at 21:27
@mattharrison Yes, definitely too old. You need at least texlive 2013 (you cannot update only luaotfload since it won’t work with Luatex < 0.75). –  phg Sep 7 '13 at 21:35
There's no way to write the code for older versions? –  matt harrison Sep 7 '13 at 21:43
show 1 more comment

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.