/*****************************************************************************
*
* PSFanChart.rexx
*
* $VER: PSFanChart 1.01 (22 Aug 1998)
*
* Produces a "fan" Postscript¹ chart showing 4 to 10 generations of ancestors
* of the "base" person. The resulting chart can be sent directly to a
* POSTSCRIPT printer connected to the parallel port or to a file.
*
* TIP: The generated chart file can be imported into FinalWriter² by using the
*      FinalWriter menu "Objects(or Graphics)/Import" option. However, please
*      be warned that the postscript code will always try to display a
*      full-page chart. If you try arbitrary scaling of the image inside
*      FinalWriter then you may get VERY strange results. It is best to leave
*      the image size unchanged.
*
*      If you REALLY need to re-scale the chart in FinalWriter, you could try
*      using the companion program 'PSCircleChart.rexx' instead.
*
* NOTE: Requires 'rexxreqtools.library'
*
* Credits: The postscript code generated by this program borrows heavily
*          from the postscript code generated by the IBM-PC program
*          "GEDCHART.EXE" written by Thomas P. Blumer (blumer@ptltd.com).
*          There have been extensive modifications to handle Amiga "foreign"
*          characters (such as è, ð, ý, etc.) amongst other things. The
*          program GEDCHART³ is an MS-DOS program that prints similar
*          charts from a GEDCOM file on either HP or postscript printers, and
*          version 1.6 is freely available from many genealogy bulletin boards.
*
* Author: Robbie Akins
*
* ¹Postscript is a registered trademark of Adobe Systems Inc.
* ²FinalWriter is a trademark of Softwood Incorporated
* ³GEDCHART is copyright © 1993-1994 by Thomas P. Blumer (blumer@ptltd.com).
*
*****************************************************************************/
/* Tell ARexx we'll be expecting results */
Options Results

/*****************************************************************************
*
* User defined "constants". These may be edited for your own requirements
*
*****************************************************************************/
withborder = 'true'		/* Change to 'false' to suppress border around chart */
body_font  = 'Times-Roman'	/* POSTSCRIPT font name for "body" text */
label_font = 'Helvetica'	/* POSTSCRIPT font name for "label" text */

/*****************************************************************************
*
* End of user defined "constants". There's nothing you should change below!
*
*****************************************************************************/

versionstr = "1.01"	/* Program version */
maxgen = 8		/* Default number of generations */
NL = '0A'x		/* new-line */

/* Enable error handling routins for syntax errors and Rexx errors */
Signal On Error
Signal On Syntax
Signal On Halt
Signal On IOErr

/* Also requires 'rexxreqtools.library' */
if ~show('l','rexxreqtools.library') then do
	if exists('libs:rexxreqtools.library') then do
		call addlib('rexxreqtools.library',0,-30,0)
	end
	else do
		Say "Unable to open rexxreqtools.library - quitting."
		exit
	end
end

/* Setup address of Scion */
MyPort = "SCIONGEN"

if(~Show('P',myport)) then do
	retval = Message("Please start Scion before"||NL||"running this program.")
	exit
end

Address value MyPort

/*****************************************************************************
*
* Postscript header code
*
*****************************************************************************/
header.1 = "%!PS-Adobe-2.0 EPSF-30."
header.2 = "%%BoundingBox:0 0 576 792"
header.3 = "%%Title: PSFanChart"
header.4 = "%%Creator: Robbie J Akins (rakins@bclnz.co.nz)"
header.5 = "%%Creationdate: (9 July 1998)"
header.6 = "%%EndComments"
header.7 = ""			/* Empty string marks end of header */

/*****************************************************************************
*
* Postscript prologue code
*
* Contrary to appearances, the 'prolog' string below is actually pure ASCII!
* It is the postscript code to send to the output before any of the
* genealogy information is output in postscript form. In order to preserve
* the new-lines at the end of each line of postscript code, it has been
* necessary to "embed" the postscript code in hexadecimal form.
*
* To generate the hex code -
*	(1) convert the postscript ASCII prolog code to hex using the
*	    command "type >ram:pshex postscript_ascii_file opt h"
*	(2) using a text editor that supports rectangular block marking
*	    (such as TurboText) delete all the "surplus" output, retaining
*	    ONLY the hex code
*	(3) Enclose the hex code with " at the start and "X at the end. This
*	    marks the hex code as a hex string as far as ARexx is concerned.
*	(4) Copy the resulting "hex string" file into the section below
*	    such that 'prolog = "hex string generated"X'
*
* NOTE: To re-generate the ASCII postscript code for re-editing, simply
*       send the output of this ARexx progarmme to a file. This file will
*       contain the postscript code in ASCII. It will be obvious where the
*       'prolog' section of the code ends - it's labelled with a comment!
*
*****************************************************************************/
prolog = "
25202D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D206669727374206C696E65206F662070726F6C6F67202D2D
2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D0A2520536F6D6520636F6E7374616E74730A2F787061
6765732031206465660A2F7970616765732031206465660A2F78706167652031206465660A2F79706167652031206465
660A2F6C696E7769646620312E303030206465660A2F666F6E745F61646A75737420312E303030206465660A2F6F6666
7365745F6E616D6520302E303030206465660A2F7478746C696E657320322E303030206465660A2F696E6368207B3732
206D756C7D206465660A2F6C72203020646566202F6C67203020646566202F6C622030206465660A2F4C722030206465
66202F4C67203020646566202F4C622030206465660A2F7472203020646566202F7467203020646566202F7462203020
6465660A2F5472203020646566202F5467203020646566202F54622030206465660A2F6C6D72203020646566202F6C6D
67203120646566202F6C6D622031206465660A2F4C6D72203020646566202F4C6D67203120646566202F4C6D62203120
6465660A2F746D72203120646566202F746D67203020646566202F746D622031206465660A2F546D7220302064656620
2F546D67203020646566202F546D622030206465660A0A25203D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D
3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D
3D3D0A252049534F2063686172616374657220656E636F64696E672073747566662022626F72726F776564222066726F
6D2074686520416D69676120706F7374736372697074206472697665722E0A2520526F6262696520416B696E73202832
36204A756C792031393937292E20446566696E6520746865205265456E636F64696E672050726F6375647572652E2E2E
0A2F656E63766563205B0A202F2E6E6F74646566202F2E6E6F74646566202F2E6E6F74646566202F2E6E6F7464656620
2F2E6E6F74646566202F2E6E6F74646566202F2E6E6F74646566202F2E6E6F746465660A202F2E6E6F74646566202F2E
6E6F74646566202F2E6E6F74646566202F2E6E6F74646566202F2E6E6F74646566202F2E6E6F74646566202F2E6E6F74
646566202F2E6E6F746465660A202F2E6E6F74646566202F2E6E6F74646566202F2E6E6F74646566202F2E6E6F746465
66202F2E6E6F74646566202F2E6E6F74646566202F2E6E6F74646566202F2E6E6F746465660A202F2E6E6F7464656620
2F2E6E6F74646566202F2E6E6F74646566202F2E6E6F74646566202F2E6E6F74646566202F2E6E6F74646566202F2E6E
6F74646566202F2E6E6F746465660A202F7370616365202F6578636C616D202F71756F746564626C202F6E756D626572
7369676E202F646F6C6C6172202F70657263656E74202F616D70657273616E640A202F71756F74657269676874202F70
6172656E6C656674202F706172656E7269676874202F617374657269736B202F706C7573202F636F6D6D61202F6D696E
7573202F706572696F640A202F736C617368202F7A65726F202F6F6E65202F74776F202F7468726565202F666F757220
2F66697665202F736978202F736576656E202F6569676874202F6E696E65202F636F6C6F6E0A202F73656D69636F6C6F
6E202F6C657373202F657175616C202F67726561746572202F7175657374696F6E202F6174202F41202F42202F43202F
44202F45202F46202F47202F480A202F49202F4A202F4B202F4C202F4D202F4E202F4F202F50202F51202F52202F5320
2F54202F55202F56202F57202F58202F59202F5A202F627261636B65746C6566740A202F6261636B736C617368202F62
7261636B65747269676874202F617363696963697263756D202F756E64657273636F7265202F71756F74656C65667420
2F61202F62202F630A202F64202F65202F66202F67202F68202F69202F6A202F6B202F6C202F6D202F6E202F6F202F70
202F71202F72202F73202F74202F75202F76202F77202F78202F79202F7A0A202F62726163656C656674202F62617220
2F62726163657269676874202F617363696974696C6465202F2E6E6F74646566202F2E6E6F74646566202F2E6E6F7464
65660A202F2E6E6F74646566202F2E6E6F74646566202F2E6E6F74646566202F2E6E6F74646566202F2E6E6F74646566
202F2E6E6F74646566202F2E6E6F74646566202F2E6E6F746465660A202F2E6E6F74646566202F2E6E6F74646566202F
2E6E6F74646566202F2E6E6F74646566202F2E6E6F74646566202F2E6E6F74646566202F646F746C65737369202F6772
6176650A202F6163757465202F63697263756D666C6578202F74696C6465202F6D6163726F6E202F6272657665202F64
6F74616363656E74202F6469657265736973202F2E6E6F746465660A202F72696E67202F636564696C6C61202F2E6E6F
74646566202F68756E676172756D6C617574202F6F676F6E656B202F6361726F6E202F7370616365202F6578636C616D
646F776E0A202F63656E74202F737465726C696E67202F63757272656E6379202F79656E202F62726F6B656E62617220
2F73656374696F6E202F6469657265736973202F636F707972696768740A202F6F726466656D696E696E65202F677569
6C6C656D6F746C656674202F6C6F676963616C6E6F74202F68797068656E202F72656769737465726564202F6D616372
6F6E0A202F646567726565202F706C75736D696E7573202F74776F7375706572696F72202F7468726565737570657269
6F72202F6163757465202F6D75202F7061726167726170680A202F706572696F6463656E7465726564202F636564696C
6C61202F6F6E657375706572696F72202F6F72646D617363756C696E65202F6775696C6C656D6F7472696768740A202F
6F6E6571756172746572202F6F6E6568616C66202F74687265657175617274657273202F7175657374696F6E646F776E
202F416772617665202F4161637574650A202F4163697263756D666C6578202F4174696C6465202F4164696572657369
73202F4172696E67202F4145202F43636564696C6C61202F456772617665202F4561637574650A202F4563697263756D
666C6578202F456469657265736973202F496772617665202F496163757465202F4963697263756D666C6578202F4964
69657265736973202F4574680A202F4E74696C6465202F4F6772617665202F4F6163757465202F4F63697263756D666C
6578202F4F74696C6465202F4F6469657265736973202F6D756C7469706C790A202F4F736C617368202F556772617665
202F556163757465202F5563697263756D666C6578202F556469657265736973202F596163757465202F54686F726E0A
202F6765726D616E64626C73202F616772617665202F616163757465202F6163697263756D666C6578202F6174696C64
65202F616469657265736973202F6172696E67202F61650A202F63636564696C6C61202F656772617665202F65616375
7465202F6563697263756D666C6578202F656469657265736973202F696772617665202F6961637574650A202F696369
7263756D666C6578202F696469657265736973202F657468202F6E74696C6465202F6F6772617665202F6F6163757465
202F6F63697263756D666C65780A202F6F74696C6465202F6F6469657265736973202F646976696465202F6F736C6173
68202F756772617665202F756163757465202F7563697263756D666C65780A202F756469657265736973202F79616375
7465202F74686F726E202F7964696572657369730A5D206465660A0A2F656E636469637420352064696374206465660A
2F7265656E630A7B0A20202020656E636469637420626567696E0A092F6E6577656E636F64696E672065786368206465
660A092F6E6577666F6E746E616D652065786368206465660A092F62617365666F6E746E616D65206578636820646566
0A0A092F62617365666F6E74646963742062617365666F6E746E616D652066696E64666F6E74206465660A0A092F6E65
77666F6E742062617365666F6E7464696374206D61786C656E6774682064696374206465660A0A0962617365666F6E74
646963740A097B20657863682064757020647570202F464944206E652065786368202F456E636F64696E67206E652061
6E640A09097B2065786368206E6577666F6E742033203120726F6C6C20707574207D0A09097B20706F7020706F70207D
0A09096966656C73650A097D20666F72616C6C0A096E6577666F6E74202F466F6E744E616D65206E6577666F6E746E61
6D65207075740A096E6577666F6E74202F456E636F64696E67206E6577656E636F64696E67207075740A096E6577666F
6E746E616D65206E6577666F6E7420646566696E65666F6E7420706F700A09656E640A7D206465660A2520456E64206F
662049534F20737570706F727420636F646520616464656420627920526F6262696520416B696E730A25203D3D3D3D3D
3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D
3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D0A0A2F74657874636F6C7230207B7D2062696E64206465660A2F6C69
6E636F6C7230207B7D2062696E64206465660A2F74657874636F6C72306D207B7D2062696E64206465660A2F6C696E63
6F6C72306D207B7D2062696E64206465660A0A2520676574207072696E7461626C6520617265610A636C697070617468
207061746862626F78206E6577706174680A2F757279206578636820646566202F7572782065786368206465660A2F6C
6C79206578636820646566202F6C6C782065786368206465660A0A2F25204D616B6520612062696E64696E67206F6666
7365740A2F6C6C78206C6C78202E323520696E636820616464206465660A2F75727820757278202E323520696E636820
737562206465660A0A252061646A75737420666F72205061636966696350616765206361727472696467650A73746174
757364696374202F70726F64756374206B6E6F776E207B0A097374617475736469637420626567696E2070726F647563
7420656E6420285061636966696350616765292065710A0976657273696F6E2028342E30362920657120616E64207B0A
09092F6C6C79206C6C79203520616464206465660A09092F7572792075727920313020737562206465660A097D206966
0A7D2069660A0A2520736574206C616E647363617065206D6F64652C2067657420776964746820616E64206865696768
740A2F7720757279206C6C7920737562206465660A2F6820757278206C6C7820737562206465660A772068206C74207B
0A0925207374617920696E20706F727472616974206D6F64650A096C6C78206C6C79207472616E736C6174650A092F74
6D702068206465660A092F682077206465660A092F7720746D70206465660A7D207B0A092520736574206C616E647363
617065206D6F64650A09757278206C6C79207472616E736C61746520393020726F746174650A7D206966656C73650A0A
25206D756C74692070616765206F75747075740A7870616765732031206E65207970616765732031206E65206F72207B
0A0931207870616765207375622077206D756C202031207970616765207375622068206D756C20207472616E736C6174
650A0978706167657320797061676573207363616C650A7D2069660A0A25206465636F72617469766520626F72646572
0A626F72646572207B0A092F627769643120322E35206465660A092F67617077696420312E35206465660A092F627769
643220302E37206465660A092F72656374207B0A09092F72682065786368206465660A09092F72772065786368206465
660A09096D6F7665746F0A09097277203020726C696E65746F0A09093020726820726C696E65746F0A09097277206E65
67203020726C696E65746F0A0909636C6F736570617468207374726F6B650A097D206465660A0A096277696431207365
746C696E6577696474680A096C696E636F6C72300A096277696431203220646976202064757020207720627769643120
737562202068206277696431207375622020726563740A0A096277696432207365746C696E6577696474680A09627769
643120676170776964206277696432203220646976206164642061646420206475700A09772062776964312032206D75
6C20737562206761707769642032206D756C2073756220627769643220737562200A09682062776964312032206D756C
20737562206761707769642032206D756C207375622062776964322073756220726563740A0A09252063757420746865
20626F72646572206F7574206F662074686520696D61676561626C6520617265610A092F746D70206277696431206761
7077696420627769643220676170776964206164642061646420616464206465660A09746D7020746D70207472616E73
6C6174650A092F77207720746D702032206D756C20737562206465660A092F68206820746D702032206D756C20737562
206465660A7D2069660A0A2520666F6E74207265656E636F64696E670A6C6162656C666F6E74202F676564666F6E7420
656E63766563207265656E630A2F6C6162656C666F6E74202F676564666F6E74206465660A6C6162656C666F6E742066
696E64666F6E742039207363616C65666F6E7420736574666F6E740A0A2520666F72206D756C746920706167653A206E
6F206C6162656C0A2F63686172745F6C6162656C20776865726520787061676573203120657120797061676573203120
657120616E6420616E64207B0A09706F700A0967736176650A09252073657420757020636F6F7264696E617465207379
7374656D20666F7220637573746F6D206368617274206C6162656C0A092520666F722066616E206368617274206F6E6C
792C20736574206F726967696E20617420323525206265747765656E206C727820616E64207572780A09636C69707061
7468207061746862626F78206E65777061746820706F700A092F747572782065786368206465662065786368202E3735
206D756C2074757278202E3235206D756C206164642065786368207472616E736C6174650A0963686172745F6C616265
6C0A0967726573746F72650A7D2069660A0A2520666F6E74207265656E636F64696E670A666F6E746E616D65202F6765
64666F6E7420656E63766563207265656E630A2F666F6E746E616D65202F676564666F6E74206465660A0A2520636C65
617220706174680A6E6577706174680A0A252067657420726164697573206F662063697263756C61722063686172740A
2F722077203220646976206465660A2F64792068207220737562206465660A2F647820722072206D756C206479206479
206D756C207375622073717274206465660A2F61206479206478206174616E206465660A0A25206765742063656E7465
72206F6620636972636C652C206D616B65206974206F726967696E0A2F63782072206465660A2F637920647920646566
0A6378206379207472616E736C6174650A0A2520616E6731203D20656E6420616E676C6520666F722063686172740A25
20616E6732203D20626567696E20616E676C6520666F722063686172740A2F616E673120612031383020616464206465
660A2F616E67322061206E6567206465660A2F616E6720616E673120616E673220737562206465660A0A2520666F7220
636F6E76657273696F6E2066726F6D206465677265657320746F2072616469616E730A2F504920332E31343135393236
35206465660A0A252064726177206F75746C696E65206F662063686172740A25302030206D6F7665746F203020302072
20616E673220616E67312061726320636C6F736570617468207374726F6B650A0A252072656C61746976652072616469
7573206C656E67746820666F7220656163682067656E65726174696F6E0A2520726C67656E5B305D206E6F7420757365
642C206A75737420746865726520736F20726C67656E5B5D20616E6420726C73756D5B5D206C696E652075700A252072
6C67656E5B315D203D206C656E677468206F662067656E65726174696F6E20312C206574630A25206C6173742076616C
756520697320726570656174656420666F7220667572746865722067656E65726174696F6E730A2F726C67656E205B30
2E302020302E333320312E3020312E3020312E302020312E3020312E3020312E3020312E302020312E3420312E342032
2E385D206465660A2F726C67656E6D617820726C67656E206C656E677468203120737562206465660A0A2520726C7375
6D2061727261792069732072756E6E696E672073756D206F6620726C67656E2061727261790A25207374617274206F66
2067656E65726174696F6E2069203D20726C73756D5B695D0A25202020656E64206F662067656E65726174696F6E2069
203D20726C73756D5B692B315D0A2F726C73756D206D61786C6576656C203120616464206172726179206465660A2F73
756D2030206465660A312031206D61786C6576656C207B0A092F692065786368206465660A092F6A2069206465660A09
6A20726C67656E6D6178206774207B2F6A20726C67656E6D6178206465667D2069660A092F73756D2073756D20726C67
656E206A2067657420616464206465660A09726C73756D20692073756D207075740A7D20666F720A0A25206C656E6774
68206F66206F6E6520726164697573207365676D656E740A2F726C207220726C73756D206D61786C6576656C20676574
20646976206465660A0A252063616C63756C617465206261736520666F6E742073697A652066726F6D207365676D656E
74206C656E6774680A2F666E7473697A6520726C20392E3020646976206465660A0A2520666F6E742061646A7573746D
656E740A2F666E7473697A6520666E7473697A6520666F6E745F61646A757374206D756C206465660A0A666F6E746E61
6D652066696E64666F6E7420666E7473697A65207363616C65666F6E7420736574666F6E740A2F737061636520282029
20737472696E67776964746820706F70206465660A0A252063616C63206C696E652077696474682066726F6D20736567
6D656E74206C656E677468202D202E323420707473203D203120706978656C0A2F6C696E77696420666E7473697A6520
2E31206D756C202E36206D756C206465660A2F6C696E776964206C696E776964206C696E77696466206D756C20646566
0A6C696E776964207365746C696E6577696474680A2F6E616D6579206C696E7769642032206D756C206465660A0A3220
7365746C696E656361700A0A25206E616D6520737472696E67206C656E67746820666F7220302067656E65726174696F
6E0A2F6C656E3020726C206465660A0A252073656C65637420666F6E742073697A6520736F207468617420737472696E
67206669747320696E20617661696C61626C65206C656E6774680A2F77666F6E7473697A65207B0A092F732065786368
206465660A092F6C656E2065786368206465660A0A0925207374617274696E672076616C756520666F7220666F6E7420
73697A650A092F6673697A6520666E7473697A65206465660A0A092520706F737369626C65206C696D6974206F6E2066
6F6E742073697A650A096D6178666E7473697A652030206774207B0A09096673697A65206D6178666E7473697A652067
74207B0A0909092F6673697A65206D6178666E7473697A65206465660A09097D2069660A097D2069660A0A09666F6E74
6E616D652066696E64666F6E74206673697A65207363616C65666F6E7420736574666F6E740A097320737472696E6777
6964746820706F7020647570206C656E206C74207B0A0909706F700A097D207B0A09092520636F6D70757465206E6577
20666F6E742073697A6520666F72206578616374206669740A09096C656E206578636820646976206673697A65206D75
6C202F6673697A652065786368206465660A0909666F6E746E616D652066696E64666F6E74206673697A65207363616C
65666F6E7420736574666F6E740A097D206966656C73650A092F746D70666E7473697A65206673697A65206465660A7D
2062696E64206465660A0A252073686F772074686520737472696E6720617267756D656E742077697468207468652063
757272656E7420666F6E740A2F7773686F77207B0A0973686F770A7D2062696E64206465660A0A25207374617274696E
67207920666F7220726F6F74206368696C6472656E0A2F7369627920666E7473697A65202D32206D756C206465660A0A
25204472617720616C6C20746865206C696E6573206F66207468652066616E2063686172740A25205468697320697320
6120737562736574206F6620746865206F726967696E616C20636F64652066726F6D2070726F63656475726520692062
656C6F770A312031206D61786C6576656C203120737562207B0A092F6C6576656C2065786368206465660A0930203120
31206C6576656C206269747368696674203120737562207B0A09092F6C6561662065786368206465660A0A0909252078
31203D20696E6E6572207261646975732C207832203D206F75746572207261646975730A09092F783120726C73756D20
6C6576656C2067657420726C206D756C206465660A09092F783220726C73756D206C6576656C20312061646420676574
20726C206D756C206465660A0A09092F786C6576322032206C6576656C206269747368696674206465660A09092F786C
656166206C6561662032206D756C203120616464206465660A0A0909252061742067656E65726174696F6E203131206F
722061626F76652C20707574206661746865722F6D6F74686572206F6E2073616D65206C696E650A09096C6576656C20
3130206765207B0A0909092F783173617665207831206465660A0909096C656166203120616E642030206571207B0A09
09090925206661746865720A090909092F783220783120783220616464203220646976206465660A0909097D207B0A09
09090925206D6F746865720A090909092F783120783120783220616464203220646976206465660A0909097D20696665
6C73650A0A090909252070726574656E6420746F206265206174206368696C642773206C6576656C20616E64206C6561
660A0909092520746F206765742074686520636F727265637420616E676C650A0909092F786C6576322032206C657665
6C203120737562206269747368696674206465660A0909092F786C656166206C656166203220696469762032206D756C
203120616464206465660A09097D2069660A09092520656E64207370656369616C20636F646520666F722067656E2031
3120616E642061626F76650A0A090925206177203D20616E676C65206F6620776564676520666F72206F6E6520696E64
6976696475616C20696E20746869732067656E65726174696F6E0A09092F617720616E6720786C657632206469762064
65660A0A0909252061203D20616E67756C617220706F736974696F6E206F66207468697320696E646976696475616C0A
09092F6120616E673120617720786C656166206D756C20737562206465660A0A09096C656166203120616E6420302065
71207B0A09090925206661746865720A0909096C696E636F6C72300A09097D207B0A09090925206D6F746865720A0909
096C696E636F6C72306D0A09097D206966656C73650A0A09092520726F7461746520636F6F72642073797374656D2073
6F207468697320696E646976696475616C206973206F6E207820617869730A090967736176650A090961203930206C74
207B0A0909096120726F746174650A09090978312030206D6F7665746F2078322030206C696E65746F207374726F6B65
0A09097D207B0A09090961203138302073756220726F746174650A0909097832206E65672030206D6F7665746F207831
206E65672030206C696E65746F207374726F6B650A09097D206966656C73650A090967726573746F72650A0A09096C65
76656C203130206765207B0A0909092520726573746F7265206E6F726D616C2076616C75657320746F2064726177206A
6F696E20617263730A0909092F786C6576322032206C6576656C206269747368696674206465660A0909092F786C6561
66206C6561662032206D756C203120616464206465660A0909092F617720616E6720786C65763220646976206465660A
0909092F6120616E673120617720786C656166206D756C20737562206465660A0909092F783120783173617665206465
660A09097D2069660A0A09092520647261772061726320636F6E6E656374696E67207468697320696E64697669647561
6C20746F206869732F686572206368696C640A09096C656166203120616E642030206571207B0A090909252066617468
65720A0909096C696E636F6C723020302030207831206120617720737562206120617263207374726F6B650A09097D20
7B0A09090925206D6F746865720A0909096C696E636F6C72306D20302030207831206120612061772061646420617263
207374726F6B650A09097D206966656C73650A097D20666F720A7D20666F720A2520656E64206F66206472617720616C
6C20746865206C696E6573206F66207468652066616E2063686172740A0A252063616C6C6564206F6E636520666F7220
6561636820696E646976696475616C206F6E2063686172740A2F696E646976207B0A092F6C6561662065786368206465
660A092F6C6576656C2065786368206465660A092F626972746864656174682065786368206465660A092F6E616D6520
65786368206465660A0A092F6D6178666E7473697A65202D31206465660A096C6576656C206D61786C6576656C206C74
207B0A09202020206C6576656C2030206571207B0A090925207072696E74206E616D652C206269727468202620646561
74682064617465730A090967736176650A090974657874636F6C72300A09096C656E30202D3220646976207369627920
7472616E736C6174650A09092F782030206465660A090978206E616D6579206D6F7665746F0A09096C656E30206E616D
652077666F6E7473697A650A09096E616D65207773686F770A09092F73696279207369627920666E7473697A65203220
6D756C20737562206465660A0A090962697274686465617468206C656E6774682030206774207B0A0909097820666E74
73697A65206E6567206D6F7665746F0A0909096C656E3020626972746864656174682077666F6E7473697A650A090909
62697274686465617468207773686F770A0909092F73696279207369627920666E7473697A6520737562206465660A09
097D2069660A090967726573746F72650A09202020207D207B0A09092520616C6C2067656E65726174696F6E73206578
636570742074686520666972737420286C6576656C203E2030290A0A090925207831203D20696E6E6572207261646975
732C207832203D206F75746572207261646975730A09092F783120726C73756D206C6576656C2067657420726C206D75
6C206465660A09092F783220726C73756D206C6576656C2031206164642067657420726C206D756C206465660A0A0909
2F786C6576322032206C6576656C206269747368696674206465660A09092F786C656166206C6561662032206D756C20
3120616464206465660A0A0909252061742067656E65726174696F6E203131206F722061626F76652C20707574206661
746865722F6D6F74686572206F6E2073616D65206C696E650A09096C6576656C203130206765207B0A0909096C656166
203120616E642030206571207B0A0909090925206661746865720A090909092F78322078312078322061646420322064
6976206465660A0909097D207B0A0909090925206D6F746865720A090909092F78312078312078322061646420322064
6976206465660A0909097D206966656C73650A0A090909252070726574656E6420746F206265206174206368696C6427
73206C6576656C20616E64206C6561660A0909092520746F206765742074686520636F727265637420616E676C650A09
09092F786C6576322032206C6576656C203120737562206269747368696674206465660A0909092F786C656166206C65
6166203220696469762032206D756C203120616464206465660A09097D2069660A09092520656E64207370656369616C
20636F646520666F722067656E20313120616E642061626F76650A0A090925206177203D20616E676C65206F66207765
64676520666F72206F6E6520696E646976696475616C20696E20746869732067656E65726174696F6E0A09092F617720
616E6720786C65763220646976206465660A0A0909252061203D20616E67756C617220706F736974696F6E206F662074
68697320696E646976696475616C0A09092F6120616E673120617720786C656166206D756C20737562206465660A0A09
09252063616C63206D617820666F6E742073697A6520676976656E20616E676C65206F662077656467650A09092F6D61
78666E7473697A652032206177206D756C205049206D756C2031383020646976207831206D756C207478746C696E6573
20646976206465660A0A09092520726F7461746520636F6F72642073797374656D20736F207468697320696E64697669
6475616C206973206F6E207820617869730A09092520646973706C6179206E616D6520616E64206F7468657220696E66
6F0A090967736176650A090961203930206C74207B0A0909096120726F746174650A09090925206C696E636F6C723020
78312030206D6F7665746F2078322030206C696E65746F207374726F6B650A0909092F78207831207370616365206164
64206465660A09097D207B0A09090961203138302073756220726F746174650A09090925206C696E636F6C7230207832
206E65672030206D6F7665746F207831206E65672030206C696E65746F207374726F6B650A0909092F78207832206E65
6720737061636520616464206465660A09097D206966656C73650A0A09092F6C656E3120783220783120737562207370
6163652032206D756C20737562206465660A0A09096C656166203120616E642030206571207B0A090909252066617468
65720A09090974657874636F6C72300A09097D207B0A09090925206D6F746865720A09090974657874636F6C72306D0A
09097D206966656C73650A0A090925207072696E74206E616D652C206269727468202620646561746820646174650A09
0978206E616D6579206D6F7665746F0A09096C656E31206E616D652077666F6E7473697A650A09096E616D6520777368
6F770A0A090962697274686465617468206C656E6774682030206774207B0A0909096C656E3120626972746864656174
682077666F6E7473697A650A0909097820746D70666E7473697A65206E6567206D6F7665746F0A090909626972746864
65617468207773686F770A09097D2069660A090967726573746F72650A0A09092F6D6178666E7473697A65202D312064
65660A09202020207D206966656C73650A097D2069660A7D2062696E64206465660A25202D2D2D2D2D2D2D2D2D2D2D2D
2D2D2D2D2D2D2D2D2D2D206C617374206C696E65206F662070726F6C6F67202D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D
2D2D2D2D2D2D2D2D2D2D2D0A"X

/*****************************************************************************
*
* Start of program proper
*
*****************************************************************************/

GETPROGVERSION
version = RESULT
if(version < 5.00) then do
	retval = Message("This program requires Scion"||NL||"Version 5.00 or later.")
	Exit
end

GETTOTALIRN
p = RESULT
GETTOTALFGRN
f = RESULT
if (p = 0) | (f = 0) then do
	retval = Message("Insufficient data in database"||NL||"to produce a chart.")
	Exit
end

/* Use Scion public screen */
PSCR = "SCIONGEN"

/* Startup message */
thanks = rtezrequest('This program produces a Postscript'||NL||,
	'ancestor fan chart from a Scion database.'||NL||NL||,
	'Select the person whose ancestors you'||NL|| 'want printed from the next requester.','Okay','PSFanChart v'||versionstr' by R J Akins','rt_pubscrname = '||PSCR)

/* Select "base" person of chart */
REQUESTPERSON
BasePerson = RESULT
if BasePerson = 0 then exit	/* User cancelled */

/* Build selected name to display in requesters */
GETLASTNAME BasePerson
lastname = RESULT
GETFIRSTNAME BasePerson
firstname = RESULT
TRIMFIRST()
basename = firstname' 'lastname

/* Get database name to display in requesters */
GETDBNAME
dbname = upper(RESULT)

/* Let user select number of generations to print */
choice = rtezrequest('Current Scion database: '||dbname||NL||'Selected person: '||basename||NL||NL||,
'How many generations would you like printed?'||NL||'(The more the slower!)',
	'','_4|_6|_8|_10|_Cancel','PSFanChart v'||versionstr||' by R J Akins','rt_pubscrname = '||PSCR)

select
	when choice = 1 then do
		maxgen = 4
		end
	when choice = 2 then do
		maxgen = 6
		end
	when choice = 3 then do
		maxgen = 8
		end
	when choice = 4 then do
		maxgen = 10
		end
	otherwise exit	/* Aborted */
end

/* Let user select output destination */
dest = rtezrequest('Current Scion database: '||dbname||NL||'Selected person: '||basename||NL||NL||,
'Where should the postscript'||NL||'output be sent to?'||,
	'','_File|_PAR:|_Cancel','PSFanChart v'||versionstr||' by R J Akins','rt_pubscrname = '||PSCR)

select
	when dest = 1 then do
		/* We need a file requester for further data */
		outname = rtfilerequest(,dbname||'.ps','Output filename',,'rt_pubscrname = '||PSCR||'   rtfi_initialpath = RAM:',)
		if outname = '' then
			outname = dbname||'.ps'
		end
	when dest = 2 then
		outname = 'PAR:'
	otherwise exit	/* Aborted */
end

/* Open output destination */
if ~open(output, outname, "w") then do
	retval = Message("ERROR: Unable to open output file"||NL||"or device. Aborting.")
	exit
end

/* Output postscript header code */
i = 1
do while header.i ~= ''
	PSOutput(dest, header.i)
	i = i+1
end

/* Get information for chart label and later use */
GETFULLNAME BasePerson
bp_full = RESULT
bp_full = TRANSLATE(bp_full, "{}/", "()\")	/* Replace '(', ')' and '\' with '{', '}' and '/' */
GETBIRTHDATE BasePerson
bp_birth = RESULT
GETDEATHDATE BasePerson
bp_death = RESULT

/* Output chart label postscript code */
PSOutput(dest, "/chart_label {")
PSOutput(dest, "	10 30 moveto")
db_date = date()
ps_string = "	(Fan Chart for "bp_full". Report printed on "db_date") show"
PSOutput(dest, ps_string)
PSOutput(dest, "} def")

/* Output postscript user options */
ps_string = "/maxlevel "maxgen" def"
PSOutput(dest, ps_string)

ps_string = "/border "withborder" def"
PSOutput(dest, ps_string)

ps_string =  "/labelfont /"label_font" def"
PSOutput(dest, ps_string)

ps_string = "/fontname /"body_font" def"
PSOutput(dest, ps_string)

/* Output postscript prolog */
PSOutput(dest, prolog)

/****************************
*                           *
* Do bases's part of chart  *
*                           *
****************************/
if bp_birth ~= '' then born = "b. "bp_birth
else born = ""
if bp_death ~= '' then died = "d. "bp_death
else died = ""

ps_string = '('bp_full') ('born' 'died') 0 0 indiv'
PSOutput(dest, ps_string)

/****************************
*                           *
* Do father's part of chart *
*                           *
****************************/
GETFATHER BasePerson
Ancestor.1 = RESULT

/* Output father's postscript code */
AncestorDetails(1, 1)	/* ahnen = 1, section = 1 */

/* Collect father's ancestors and output postscript code (left half of chart) */
section = 1	/* left half */
CollectAncestors(section)

/****************************
*                           *
* Do mother's part of chart *
*                           *
****************************/
GETMOTHER BasePerson
Ancestor.1 = RESULT

/* Output mother's postscript code */
AncestorDetails(1, 2)	/* ahnen = 1, section = 2 */

/* Collect mother's ancestors and output postscript code (right half of chart) */
section = 2	/* right half */
CollectAncestors(section)

/* Output final section of postscript code */
PSOutput(dest, "showpage")
if dest = 2 then PSOutput(dest, "04"X)	/* Ctrl-D: Not to file - only printer */

close(output)

/* Notify user that program has finished */
rtezrequest('PSFanChart finished','Okay','PSFanChart v'||versionstr,'rt_pubscrname = '||PSCR)

exit	/* All done */


/*****************************************************************************
*
* Procedure to collect ancestors and output details
*
*****************************************************************************/
CollectAncestors: PROCEDURE EXPOSE Ancestor. maxgen
parse arg sector

do i = 1 to 2**(maxgen-1)
	j = 2*i
	k = 2*i+1
	GETFATHER Ancestor.i
	Ancestor.j = RESULT
	GETMOTHER Ancestor.i
	Ancestor.k = RESULT

	/* Collect and output postscript code for male ancestors */
	AncestorDetails(j, sector)

	/* Collect and output postscript code for female ancestors */
	AncestorDetails(k, sector)
end

return 0

/*****************************************************************************
*
* Procedure to output ancestor details
*
*****************************************************************************/
AncestorDetails: PROCEDURE EXPOSE Ancestor. dest
parse arg ahnen, sector

/* Build and output postscript code */
EXISTPERSON Ancestor.ahnen
if RESULT = 'YES' then do
	/* Collect required information */
	GETLASTNAME Ancestor.ahnen
	lastname = RESULT
	TRIMLAST()		/* Trim last name, if needed */

	GETFIRSTNAME Ancestor.ahnen
	firstname = RESULT
	TRIMFIRST()		 /* Trim first name, if needed */

	fullname = firstname" "lastname
	
	GETBIRTHDATE Ancestor.ahnen
	birthdate = RESULT

	GETDEATHDATE Ancestor.ahnen
	deathdate = RESULT

	if birthdate ~= '' then born = "b. "birthdate
	else born = ""
	if deathdate ~= '' then died = "d. "deathdate
	else died = ""

	/* Convert ahnen, sector to generation, leaf */
	Ahnen2Leaf(ahnen, sector)

	ps_string = "("fullname") ("born"  "died")" generation leaf "indiv"
	PSOutput(dest, ps_string)
end

return 0

/*****************************************************************************
*
* Procedure to convert an ahnen/sector reference to a generation/leaf
*
*****************************************************************************/
Ahnen2Leaf: PROCEDURE EXPOSE generation leaf
parse arg ahnen, sector

aa = ahnen
gen = 0
do while aa ~= 0
	aa = aa%2
	gen = gen + 1
end
generation = gen

leaf = ahnen - 2**(gen-1)
if sector = 2 then leaf = 2**(gen-1) + leaf

return 0

/*****************************************************************************
*
* Procedure to trim first names replacing "illegal" postscript characters
*
*****************************************************************************/
TrimFirst: PROCEDURE EXPOSE firstname

/* First, replace '(', ')' and '\' with '{', '}' and '/' */
firstname = TRANSLATE(firstname, "{}/", "()\")

/* Reduce first name to "sensible" length */
maxlen = 20
len = LENGTH(firstname)
if (len > maxlen) then do
	/* Too long - trim */
	firstname = LEFT(firstname, maxlen-3)
	firstname = firstname"..."
end

return 0

/*****************************************************************************
*
* Procedure to trim last name replacing "illegal" postscript characters
*
*****************************************************************************/
TrimLast: PROCEDURE EXPOSE lastname

/* First, replace '(', ')' and '\' with '{', '}' and '/' */
lastname = TRANSLATE(lastname, "{}/", "()\")

/* No length trimming done */

return 0

/*****************************************************************************
*
* Output string procedure
*
*****************************************************************************/
PSOutput: PROCEDURE EXPOSE output
parse arg mode, string

if mode ~= 0 then do
	writeln(output, string)
end
else say string

return 0

/*****************************************************************************
*
* Procedure to display a message using rexxreqtools.library
*
*****************************************************************************/
Message: PROCEDURE EXPOSE NL PSCR versionstr
parse arg string

retval = rtezrequest(string,'Okay','PSFanChart v'||versionstr' by R J Akins','rt_pubscrname = '||PSCR)

return retval

/*****************************************************************************
*
* Error handling
*
*****************************************************************************/
Error:
	Parse Source Type Num Script Prog Port
	say 'ERROR: Function failure. Return level 'RC' on line 'SIGL' **'
	exit

Syntax:
	Parse Source Type Num MacroName Script Prog Port
	say 'SYNTAX: Macro "'MacroName'", Error: #'RC' ("'ErrorText(RC)'") on line 'SIGL' **'
	exit

Halt:
	Parse Source Type Num MacroName Script Prog Port
	say 'HALT: Macro "'MacroName'", Error: #'RC' on line 'SIGL' **'
	exit

IOErr:
	Parse Source Type Num MacroName Script Prog Port
	say 'IOERR: Macro "'MacroName'", Error: #'RC' on line 'SIGL' **'
	exit
