# Background

Looking to draw a horizontal "progress bar" along the bottom of each page. The first page should have no line above the page number (or very, very short) and the last page should have a line \textwidth in length.

# Code

The following code works in some but not all situations:

% Calculate the percentage complete for a progress meter.
\define\PercentComplete{\the\dimexpr\textwidth*\currentpage/\lastpage\relax}

%
\define\PageNumber{%
\inframed[
frame=off,
bottomframe=on,
width=\PercentComplete,
framecolor=ProgressBar,
]{\currentpage\ of \lastpage}
}

\startsetups[FooterLeft]
\midaligned{\FontFooter \PageNumber}
\stopsetups

\startsetups[FooterRight]
\midaligned{\FontFooter \PageNumber}
\stopsetups


# Example Output

Here are some examples that work using the above code:

Other documents, unfortunately, fail with an arithmetic error (probably divide by zero).

# Question

What is the correct way to calculate the percentage complete so that if \lastpage isn't valid (i.e., first pass of multiple passes), then the calculation is postponed until \lastpage has a known value?

• \ifnum\lastpage=0 \else .. \fi? – Manuel Apr 17 '17 at 6:13
• If you want much fancier "progress bars", see my visualcounter module. – Aditya Apr 20 '17 at 1:14

The macro \lastpage is 0 during the first pass because the document's last page is unknown. This allows setting the percentage to 0pt for the first pass and to the desired dimension for all other passes. Also, measures provide a higher-level interface to adaptive dimensions.

\doifelse{\lastpage}{0}{
\definemeasure
[percent complete]
[0pt]
}{
\definemeasure
[percent complete]
[\textwidth*\currentpage/\lastpage]
}

\define\PageNumber{%
\inframed[
frame=off,
bottomframe=on,
width=\measure{percent complete},
framecolor=ProgressBar,
]{\currentpage\ of \lastpage}
}

\def\FontFooter{\ss}

\startsetups[FooterLeft]
\midaligned{\FontFooter \PageNumber}
\stopsetups

\startsetups[FooterRight]
\midaligned{\FontFooter \PageNumber}
\stopsetups

\setupfootertexts[\setups{FooterLeft}][\setups{FooterRight}]

\starttext

\dorecurse{10}{\input knuth\relax}

\stoptext

• For some reason, this only works if the .tuc file is deleted prior to running context. If the .tuc file remains, the measure is only set once: to \zeropoint. – Dave Jarvis Apr 19 '17 at 5:56
• @DaveJarvis You are right. Apparently, the mode *first is always active when you run ConTeXt and is only disabled when ConTeXt itself decides to run multiple passes. – Henri Menke Apr 20 '17 at 1:09