BeginStyle
% compute width of spaces as a distance
(
sp) "width of spaces in screen font" {
screensp
} ScreenRule
(
sp) "width of spaces in printing font" {
printsp
} PrintRule
% provisional Style attributes; must be JaM variables until included in Tioga
(default) (default) .def
% (centered) (centered) .def
% (flushLeft) (flushLeft) .def
% (flushRight) (flushRight) .def
% (justified) (justified) .def
(lastLineFormatting) default StyleParam
% Syntactic sugar
(bp) "big point" {72.0 .div in} StyleRule
(IF) {}.cvx .def
(THEN) {}.cvx .def
(FI) {.cvx .if}.cvx .def
(ELSE) {.cvx}.cvx .def
(FIELSE) {.cvx .ifelse}.cvx .def
(EXITifTRUE) {{.exit} .cvx .if}.cvx .def
(EXITifFALSE) {.not {.exit} .cvx .if}.cvx .def
(DO) {}.cvx .def
(ENDLOOP) {.cvx .loop}.cvx .def
% Page layout control variables
(pageNumbering) .true StyleParam
(firstPageNumber) 1 StyleParam
(firstHeadersAfterPage) 1 StyleParam
(
oneSidedFormat) .true StyleParam
% set false if you wish two-sided headers/footers
(
GalleyWidth) "the width of the text portion of the page" {
the pageWidth the leftMargin .sub the rightMargin .sub the rightIndent .sub
} StyleRule
% Page layout routines
(
PageBuilder) "the routine that packs pages with headers" {
StartPageCounter
DO {
.page EXITifFALSE
HeaderBox
.exchbox
FooterBox
3 .vbox .shipout
IncrPageCounter
} ENDLOOP
} StyleRule
(
StartPageCounter) "Initialize the page counter" {
% sigh... pageCounter might have been a StyleParam but they do not preserve any state
% so we are forced to make it a global JaM variable for now
% this implies only one TSetter may run at a time
% otherwise the page numbers get reset in the middle of subsequent TSetter runs
% In the glorious future, either TSetter or Tioga will provide document counters
(pageCounter) the firstPageNumber .def
} StyleRule
(
GetPageCounter) "return the current value of the page counter" {
(Helvetica) 10 bp .textfont pageCounter .cvi .cvs .textbox 1 .hbox
} StyleRule
(
IncrPageCounter) "increment the page counter" {
(pageCounter) pageCounter 1 .add .def
} StyleRule
(
IsOddPage) "test if this is an odd or recto page" {
% determines which page to format: odd => right (recto) page, even => left (verso) page
pageCounter .dup 2 .div 2 .mul .sub 1 .eq
} StyleRule
(
HeaderBox) "generate a box for the page headers" {
IF the oneSidedFormat
THEN {
GetHeaders
} ELSE {
IF IsOddPage
THEN {
GetRectoHeaders
} ELSE {
GetVersoHeaders
} FIELSE
} FIELSE
.fill
2 the headerMargin .vboxto
} StyleRule
(
GetHeaders) "extract the headers for one-sided pages" {
IF the pageNumbering pageCounter the firstHeadersAfterPage .gt .and
THEN {
(insideHeader) .getmark .fill (centerHeader) .getmark .fill GetPageCounter
5 GalleyWidth .hboxto
} ELSE {
.fill 1 GalleyWidth .hboxto
} FIELSE
} StyleRule
(
GetRectoHeaders) "extract the headers for a recto (right-hand) page" {
IF the pageNumbering pageCounter the firstHeadersAfterPage .gt .and
THEN {
(insideRectoHeader) .getmark .fill (centerRectoHeader) .getmark .fill GetPageCounter
5 GalleyWidth .hboxto
} ELSE {
.fill 1 GalleyWidth .hboxto
} FIELSE
} StyleRule
(
GetVersoHeaders) "extract the headers for a verso (left-hand) page" {
IF the pageNumbering pageCounter the firstHeadersAfterPage .gt .and
THEN {
GetPageCounter .fill (centerVersoHeader) .getmark .fill (insideVersoHeader) .getmark
5 GalleyWidth .hboxto
} ELSE {
(empty) .getmark .fill 2 GalleyWidth .hboxto
} FIELSE
} StyleRule
(
FooterBox) "generate a box for the page footers" {
.fill
IF the oneSidedFormat
THEN {
GetFooters
} ELSE {
IF IsOddPage
THEN {
GetRectoFooters
} ELSE {
GetVersoFooters
} FIELSE
} FIELSE
2 the footerMargin .vboxto
} StyleRule
(
GetFooters) "extract the footers for one-sided pages" {
IF the pageNumbering pageCounter the firstHeadersAfterPage .gt .and
THEN {
(insideFooter) .getmark .fill (centerFooter) .getmark .fill (outsideFooter) .getmark
5 GalleyWidth .hboxto
} ELSE {
(empty) .getmark .fill 2 GalleyWidth .hboxto
} FIELSE
} StyleRule
(
GetRectoFooters) "extract the footers for a recto (right-hand) page" {
IF the pageNumbering pageCounter the firstHeadersAfterPage .gt .and
THEN {
(insideRectoFooter) .getmark .fill (centerRectoFooter) .getmark .fill (outsideRectoFooter) .getmark
5 GalleyWidth .hboxto
} ELSE {
(empty) .getmark .fill 2 GalleyWidth .hboxto
} FIELSE
} StyleRule
(
GetVersoFooters) "extract the footers for a verso (left-hand) page" {
IF the pageNumbering pageCounter the firstHeadersAfterPage .gt .and
THEN {
(outsideVersoFooter) .getmark .fill (centerVersoFooter) .getmark .fill (insideVersoFooter) .getmark
5 GalleyWidth .hboxto
} ELSE {
(empty) .getmark .fill 2 GalleyWidth .hboxto
} FIELSE
} StyleRule
EndStyle
% How to use the various boolean flags:
% pageNumbering: default .true => pages are numbered; set to .false if pages are NOT to be numbered
% firstPageNumber: number of the first page; can be established in a StyleRule or by setting Postfix property to: 32 firstPageNumber
% oneSidedFormat: default .true => pages have same headers and footers on each page; set to .false if alternating even/odd headers and footers are desired
% How to use header/footer mark properties:
% create a Tioga text node with header/footer text
% Set property Mark to have a value of the header or footer kind from one of the kinds: insideHeader, centerHeader, outsideHeader, insideRectoHeader, centerRectoHeader, outsideRectoHeader, insideVersoHeader, centerVersoHeader, outsideVersoHeader, insideFooter, centerFooter, outsideFooter, insideRectoFooter, centerRectoFooter, outsideRectoFooter, insideVersoFooter, centerVersoFooter, outsideVersoFooter (although the default style places the page number when outside*Header would go. Other kinds of marks are permissible but unless the layout JaM code is changed to reference them they will disappear into the void (thus spelling errors are not caught).
% Be cautious with long text for header/footers. The TSetter should not wedge or fault of course, but the results WILL NOT be pleasing with a high probability. Await TiogaII for this to go away.
% How to customize the header/footer layout schemes:
% There should be strong evidence of a pattern to the header/footer layout in existence.
% One-sided pages have the page number in the top-right corner (where outsideHeader would go), and all the other 5 parts of running head/feet coming from Mark properties.
% Two-sided pages have the page number in the top-outside corners (where outside*Header would go), and all the other 11 (count'em!) parts of running head/feet coming from Mark properties.
% GetPageCounter arranges to create a box containing the page number. Modify it to include standard text if you wish.
% For example, (Helvetica) 10 bp .textfont "Page " .textbox pageCounter .cvs .textbox 2 .hbox
% in which the text "Page " has been added and the number of boxes increased from 1 to 2, will generate folios of the form "Page 1".