% address book macros
% copyright 1993 Victor Eijkhout
% copyright 2014--2016 Vafa Khalighi
%
%
%    This program is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    This program is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with this program.  If not, see <http://www.gnu.org/licenses/>.
%
%
% These macros are based on the Lollipop macro package,
% copyright 1992/3 Victor Eijkhout
% copyright 2014--2016 Vafa Khalighi
%
% Format this file twice to get external files right.
%

% Some general options.
% Please use another typeface if you have it!
%
\Distance:whitebefore=0pt \Distance:whiteafter=0pt
\AlwaysIndent:no \FlushRight:no
\TypeFace:ComputerSans \PointSize:8 \Style:roman
\def\\{,\Spaces:1 }

% The page is four columns, no footers etc
%
\DefinePageGrid:ThePage width:page=6.5in height:page=5in
 textband:start text white:10pt text white:10pt
   text white:10pt text textband:stop Stop

% The main macro is the text block \Entity, representing one item
% in the address book.
%
\DefineTextBlock:Entity HasTitle:short	
 whitebefore:{6pt plus 6pt minus 3pt} whiteafter:whitebefore
 line:start rule:v={height 7pt width7pt depth0pt} Spaces:2
      Style:italic title line:stop Stop

% Data in an entity is formatted as a number of headings.
% We declare all headings to be embedded, ie, they form a paragraph.
% The 'nomarks' option is to prevent memory overflow.
%
\OptionsMacro:embed=embedded:yes nomarks
 whitebefore:0pt whiteafter:0pt Stop
\DefineHeading:phone HasTitle:short macro:embed 
 literal:phone : Spaces:1.5 title , Spaces:2 Stop
\DefineHeading:fax HasTitle:short macro:embed
 literal:fax : Spaces:1.5 title , Spaces:2 Stop
\DefineHeading:Address HasTitle:short macro:embed
 title , Spaces:2 Stop
\DefineHeading:Note HasTitle:short macro:embed 
 ( title ) Spaces:2 Stop

% Here's an example of non-standard handling of the title:
% email addresses are set in \tt, and can be broken differently
%
\def\breakemail{\hyphenchar\font=`. }
\DefineHeading:email HasTitle:short macro:embed
 begingroup tt breakemail title endgroup , Spaces:2 Stop

% This is invisible information; maybe later we'll do something
% with it.
\DefineHeading:Route HasTitle:short Stop

% Here is the first really cute application.
% If a person is declared to be \At a certain company, then
% that fact is written out to an external file, which can be loaded
% later.
%
\DefineExternalFile:companies=ats
\def\WorksAt{Works at: }
\DefineHeading:At macro:embed 
 HasTitle:short WorksAt title Spaces:2
 external:companies title unhskip title:Entity unhskip external:stop Stop
% When the 'companies' file gets loaded the title only gets
% parsed by the macro \CompNam, and nothing else happens.
% The title is split into company and person; #1 becomes the name
% of a list to which #2 is added.
%
\def\CompNam#1\unhskip#2\unhskip{
  \if\UndefinedCS{#1}\NewList:{#1} \fi
  \AppendToList:#1={#2\unhskip, } }
\DefineExternalItem:At file:companies 
  expandafter CompNam title Stop
% The company lists are later simply loaded; see below.

% Even more complicated: birthdays.
% All birthdays are written to an external file.
%
\DefineExternalFile:births=brt
\DefineHeading:birthday HasTitle:short macro:embed 
  literal:Born : title Spaces:2 
 external:births title unhskip title:Entity unhskip external:stop Stop
% Later every month becomes something like an entity;
% here is how we generate a token list for each month.
%
\def\month#1{\ifcase#1\or jan\or feb\or mar\or apr\or may\or jun\or
  jul\or aug\or sep\or oct\or nov\or dec\fi}
\tempcounta=1 \loop\ifnum\tempcounta<13
  \xp\NewList\xp:\xp{\month\tempcounta}
  \advance\tempcounta1 \repeat
% Formatting the caboodle means:
% -- loading the 'births' file
% -- formatting each month separately by \OneMonth
%   which is essentially a call to the text block \Month
%
\def\AllBirths{\LoadExternalFile:births
  \tempcounta=1 \loop\ifnum\tempcounta<13
  \OneMonth \advance\tempcounta1 \repeat}
\def\OneMonth{\xp\Month\month\tempcounta\par
  \TheList:{\month\tempcounta} \>}
% Month is much like \Entity, just a bit different visually.
%
\DefineTextBlock:Month
 whitebefore:{6pt plus 6pt minus 3pt} whiteafter:whitebefore
 line:start rule:v={height 7pt width7pt depth0pt} Spaces:2
      Style:italic title Spaces:2
      fillup rule:v={height 7pt width7pt depth0pt} line:stop
 Stop
% When the external file is loaded, every birthday is processed
% by \BirNam which splits it into #1 year #2 month #3 day and
% #4 person's name. This is then written to the list for the
% appropriate month.
%
\def\BirNam#1 #2 #3\unhskip #4\unhskip
 {\tempcounta#2\relax
  \AppendToList:{\month\tempcounta}={\JollyFellow #3 #4 (#1)\par}
  }
\DefineExternalItem:birthday file:births
  expandafter BirNam title Stop
\DefineHeading:JollyFellow title nomarks Stop

% Phooeew! Now we can get down to business!

\WriteExtern:yes
\Start
\LoadExternalFile:companies

\Entity Adam Aardvark
\Address Page~1, English Language Dictionary
\>

\Entity Barbara Beeton
\At Tugbt
\Note Editor in chief
\>

\Entity Jane Doe
\email doe@re.mi.sol
\>

\Entity John Doe
\phone +1 212 555 4141
\>

\Entity Victor Eijkhout
\Address Department of Computer Science, University of Tennessee
\phone +1 615 974 8298
\At Tugbt
\Note merely associate editor
\email eijkhout@cs.utk.edu
\birthday 1959 11 29
\>

\Entity Elvis Presley
\birthday 1938(?) 01 08
\>

\Entity Tugboat
\TheList:Tugbt
\>

\AllBirths

\Stop

