6

Overview

Looking to create a page that has a random (and non-consecutively repeating) background colour with titles that are also random.

Problem

The code has two problems. First, generating a complementary random colour based on the current page's background colour is ineffective. Second, the code to assign a unique complementary colour to each word in the chapter title is ineffective.

Code

A relatively short example:

\ctxlua{math.randomseed( 101 )}
\setupcolors[state=start]

\definecolor[ThemeColourGreen][h=8DC366]
\definecolor[ThemeColourBlue][h=79C9EF]
\definecolor[ThemeColourYellow][h=FFD631]

\startMPinclusions
  color colours[];
  colours[0] := \MPcolor{ThemeColourGreen};
  colours[1] := \MPcolor{ThemeColourBlue};
  colours[2] := \MPcolor{ThemeColourYellow};
  max_colours := 3;

  color base_colour;
  color old_base_colour;

  vardef ThemeBase( expr colour ) =
    fill Page withcolor transparent(1, .85, colour );
  enddef;

  vardef RandomColour =
    colours[ round( uniformdeviate( max_colours - 1 ) ) ]
  enddef;

  vardef GenerateRandomColour( expr colour ) =
    color random_colour;

    forever:
      random_colour := RandomColour;
      exitunless random_colour = colour;
    endfor;

    random_colour
  enddef;

  base_colour := RandomColour;
  old_base_colour := base_colour;
\stopMPinclusions

\startuseMPgraphic{page:ThemeBackground}
  base_colour := GenerateRandomColour( old_base_colour );
  ThemeBase( base_colour );
  old_base_colour := base_colour;
\stopuseMPgraphic

\startuseMPgraphic{heading:ThemeTitleStyle}
  color complementary_colour;
  complementary_colour := GenerateRandomColour( base_colour );
  draw textext( \MPstring{heading:title} ) rotated 30
    withcolor complementary_colour;
\stopuseMPgraphic

\defineoverlay[page:ThemeBackground][\uniqueMPgraphic{page:ThemeBackground}]
\defineoverlay[page:ThemeStyle][\uniqueMPgraphic{page:ThemeStyle}]

\defineframed[ThemeTitleStyle][
  background=\useMPgraphic{ThemeTitleStyle},
]

% Called by processwords
\def\processword#1{%
  \setMPtext{heading:title}{#1}%
  \useMPgraphic{heading:ThemeTitleStyle}
}

\define[1]\ThemeChapterTitle{\processwords{#1}}
\setuphead[chapter][deeptextcommand={\ThemeChapterTitle}]

\starttext
  \setupbackgrounds[page][background={page:ThemeBackground}]
  \startchapter[title=One is 1st] \input knuth \stopchapter
  \startchapter[title=Two is 2nd] \input zapf \stopchapter
  \startchapter[title=Three is 3rd] \input knuth \stopchapter
  \startchapter[title=Four is 4th] \input zapf \stopchapter
  \startchapter[title=Five is 5th] \input knuth \stopchapter
  \startchapter[title=Six is 6th] \input zapf \stopchapter
\stoptext

Algorithm

I thought that the algorithm would be:

  1. Start MetaPost inclusions.
  2. Define a global 'colours' array to store the available colours.
  3. Generate a random initial colour, and initialized the "previous" colour.
  4. Create a new page.
  5. Generate a new random colour for the page background.
  6. If the new random colour is the same as the previous, repeat the previous step.
  7. Create the title for the page.
  8. For each word in the title, generate a complementary colour that does not conflict with the page background.

However, while testing it appears that:

  • the chapter title is being drawn before the page background; and
  • the \processwords command is not calling \processword for each word in the title.

Related

This is related to the following question:

The difference is that I need to generate a random colour such that it does not conflict with a given colour.

Question

How would you pick random colours for each word in a chapter title such that the selected colour does not conflict with the page background colour?

Note: I am using MetaPost (instead of only ConTeXt) because I'd like to (1) track the page colour; and (2) produce outlined fonts using the graphictext command.

  • 1
    To call processword for each word in the title use: \define[1]\ThemeChapterTitle{\applytosplitstringword\processword{#1}} – Marco Oct 10 '13 at 21:40
  • 1
    You need a current context version, no older than 2013.10.10 14:36. – Marco Oct 11 '13 at 0:11
5

Thanks to Marco's comment and the realization that the titles are written prior to the page background:

\ctxlua{math.randomseed( os.time() )}
%\ctxlua{math.randomseed( 105 )}

\setupcolors[state=start]

\definecolor[ThemeColourGreen][h=8DC366]
\definecolor[ThemeColourBlue][h=79C9EF]
\definecolor[ThemeColourYellow][h=FFD631]

\startMPinclusions
  color colours[];
  colours[0] := \MPcolor{ThemeColourGreen};
  colours[1] := \MPcolor{ThemeColourBlue};
  colours[2] := \MPcolor{ThemeColourYellow};

  % Determine the maximum colour index.
  max_colours := 0;
  forever:
    exitunless known(colours[max_colours+1]);
    max_colours := max_colours + 1;
  endfor;   

  numeric base_index;
  boolean new_page;

  base_index := 0;
  new_page := true;

  vardef ThemeBase( expr colour ) =
    fill Page withcolor transparent(1, .85, colour );
  enddef;

  % Return a random number up to max_colours - 1.
  vardef RandomColourIndex =
    (round( uniformdeviate( max_colours - 1 ) ))
  enddef;

  % Return a random number that is not equal to the given number,
  % using modulus math and the maximum number of available colours.
  vardef DiscontinuousRandomIndex( expr index ) =
    ((index + 1 + RandomColourIndex) mod (max_colours + 1))
  enddef;
\stopMPinclusions

\startuseMPgraphic{page:ThemeBackground}
  ThemeBase( colours[ base_index ] );

  % Force the ThemeTitleStyle to pick a new background colour. This is
  % required because ThemeTitleStyle is executed before ThemeBackround.
  new_page := true;
\stopuseMPgraphic

\startuseMPgraphic{heading:ThemeTitleStyle}
  % On each new page, pick a unique base colour for the background.
  if new_page:
    new_page := false;
    base_index := DiscontinuousRandomIndex( base_index );
  fi

  % Pick a colour that differs from the page background.
  complementary_index := DiscontinuousRandomIndex( base_index );

  % Draw each word in the title using one of the complementary colours.
  draw textext( \MPstring{heading:title} ) rotated 30
    withcolor colours[ complementary_index ];
\stopuseMPgraphic

\defineoverlay[page:ThemeBackground][\uniqueMPgraphic{page:ThemeBackground}]
\defineoverlay[page:ThemeStyle][\uniqueMPgraphic{page:ThemeStyle}]

\defineframed[ThemeTitleStyle][
  background=\useMPgraphic{ThemeTitleStyle},
]

% Called by applytosplitstringword for each word in the title.
\def\processword#1{%
  \setMPtext{heading:title}{#1}%
  \useMPgraphic{heading:ThemeTitleStyle}
}

\define[1]\ThemeChapterTitle{\applytosplitstringword\processword{#1}}
\setuphead[chapter][deeptextcommand={\ThemeChapterTitle}]

\starttext
  \setupbackgrounds[page][background={page:ThemeBackground}]
  \startchapter[title={One is 1st}] \input knuth \stopchapter
  \startchapter[title={Two is 2nd}] \input zapf \stopchapter
  \startchapter[title={Three is 3rd}] \input knuth \stopchapter
  \startchapter[title={Four is 4th}] \input zapf \stopchapter
  \startchapter[title={Five is 5th}] \input knuth \stopchapter
  \startchapter[title={Six is 6th}] \input zapf \stopchapter
\stoptext

This then applies a random colour to each word in the title such that the colour never collides with the page background colour.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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