Skip to content

Layout templates ​

A template lays out the bar line: literal text, and fields in braces.

fortran
call bar%initialize(template='march [{bar:30}] {percent:yellow} {count:cyan} ETA {eta:blue} {message}', &
                    max_value=real(steps, R8P))

Without a template, the keywords of initialize describe the line, in the fixed order of The line. The two are equivalent: forbear builds the same internal layout from either, and the keywords draw exactly what they drew before templates existed.

Syntax ​

template := { text | field }
text     := any characters but braces; {{ and }} write a brace
field    := { name [ : spec ] }
spec     := item { , item }
item     := width (bar only) | colour | on_colour | style

Fields ​

FieldShowsWidth
{bar}the bar body: done part, partial block, remaining partwidth keyword, or {bar:n}
{percent}the progress, nnn%4
{count}the current value and max_value, 25/50; what is done, 25, if indeterminatethat of max_value, twice, and the slash; growing, if indeterminate
{speed}the smoothed speed, in percent per second, nnn.nn; what is done per second, if indeterminate6
{eta}the estimated time to the end, hh:mm:ss, --:--:-- until known8
{elapsed}the time since the start, hh:mm:ss8
{spinner}the current frame of the spinner of spinner_stringthat of its frames
{message}the message of the last updatevariable
{prefix}, {suffix}the strings of prefix_string, suffix_string, or what the program assigned to bar%prefix%string, bar%suffix%string while the bar runsas given
{name}a field of the program, added with add_fieldits own

A field takes the colours of its keywords (progress_percent_color_fg, ...) unless its spec gives others.

Spec ​

ItemExampleMeaning
an integer{bar:30}the width of the bar; {bar} only
a colour{percent:yellow}foreground colour
on_ + a colour{eta:on_blue}background colour
a style{prefix:bold_on}style

Items combine, separated by commas: {eta:white,on_blue,bold_on}. The names are those of Colours and styles. The bar has no colours in its spec: its done and remaining parts are coloured by the filled_char_* and empty_char_* keywords.

Errors ​

A wrong template stops the program, with a message on standard error that names the mistake and the template:

MistakeFound by
{ not closed, } not openedinitialize
an unknown colour or style in a specinitialize
a width for a field other than {bar}, two {bar}initialize
{spinner} without spinner_stringinitialize
{percent} or {eta} in an indeterminate barinitialize
a field neither of forbear nor added with add_fieldstart

Fields of the program ​

A program adds fields of its own: a type that extends field_object, with a render function.

fortran
use forbear, only : field_object, progress_object

type, extends(field_object) :: residual_field
   real(R8P), pointer :: value => null()
   contains
      procedure, pass(self) :: render
endtype residual_field
fortran
function render(self, progress) result(text)
class(residual_field), intent(in) :: self
type(progress_object), intent(in) :: progress
character(len=:), allocatable     :: text

render is called at every drawing. progress holds what the bar knows:

ComponentTypeMeaning
currentreal(real64)current value, clamped to the range
min_value, max_valuereal(real64)the range
fractionreal(real64)fraction of the range done, in [0, 1]
percentinteger(int32)progress in percent, truncated
ratereal(real64)smoothed rate, fraction of the range per second; 0 until known
elapsedreal(real64)seconds since the start
etareal(real64)seconds to the end; negative until known
indeterminatelogicalthe total is unknown: current is not clamped, rate is what is done per second, fraction and percent are 0, eta negative
fortran
call bar%initialize(template='... {residual} ...', ...)
call bar%add_field('residual', field)   ! after initialize, before start
call bar%start

add_field stores a copy of the field; a pointer in it still points where it did. initialize removes the fields; adding a field with the name of an existing one replaces it; a name of a field of forbear stops the program. The complete program is chapter 9 of the tutorial.

The other lines ​

The template is the bar line. The scale, the start and end time and the summary keep their switches (add_scale_bar, add_date_time, add_summary); with a template the scale is drawn right above the bar body, and the summary counts in the units of the range when the template has {count}.

Released under the GPL v3, BSD 2-Clause, BSD 3-Clause or MIT License.