10 REM > DownToCSV
   20 REM Extract data from 1901 Census downloads
   30 :
   40 REM Merges in addresses
   50 REM Inserts vacant and nondomestic properties
   60 REM vacant properties, ED info kept from index file
   70 REM To do:
   80 REM Convert names, Hy-Henry, Wm-William, etc.
   90 REM FNlookup() checks for District%=0 for Workhouse
  100 :
  110 verbose%=TRUE
  120 max%=19:year%=1901:month%=4:REM Actually 31st March
  130 :
  140 A%=0:X%=1:os%=((USR&FFF4)AND&FF00)DIV256
  150 s$=".":fmax%=255:IFos%AND32:d$="\" ELSE IFos%AND8:d$="/" ELSE s$="/":d$=".":fmax%=10
  160 DIM head$(max%),info$(max%),len%(max%),addr$(max%)
  170 FOR A%=0 TO max%:READ head$(A%):NEXT
  180 DATA "HOUSEHOLD NUMBER","SURNAME","NAME","AGE","RELATIONSHIP","SEX","MARITAL STATUS","STREET ADDRESS"
  190 DATA "OCCUPATION","BIRTH YEAR","BIRTH PLACE","BIRTH COUNTY","BIRTH COUNTRY","INDIVIDUAL NUMBER"
  200 DATA "CIVIL PARISH","SUB-REGISTRATION DISTRICT","ENUMERATION DISTRICT","PIECE","PAGE","FOLIO"
  210 :
  220 ON ERROR PRINTTAB(0,max%)':REPORT:PROCClose_All:PRINT" at line ";ERL:IF ERR=17:QUIT ELSE END
  230 out%=OPENOUT(LEFT$("Whitby"+STR$year%+s$+"csv",fmax%))
  240 IF out%=0:PRINT"Couldn't open output file, is it already open?":END
  250 PROCcsv_wr(out%,head$())
  260 IF verbose%:CLS:PRINT:FOR A%=0 TO max%:PRINTFNd0(A%,2);": ";head$(A%);":":NEXT:OFF
  270 :
  280 lookup$="Addrs"+s$+"csv"
  290 lookup%=OPENIN(lookup$):lookptr%=0:looklast%=0
  300 PROCcsv_rd(lookup%,addr$()):FOR A%=0 TO max%
  310   IF addr$(A%)="CIVIL PARISH"        :idxParish%=A%
  320   IF addr$(A%)="ENUMERATION DISTRICT":idxDistrict%=A%
  330   IF LEFT$(addr$(A%),4)="ED, "       :idxDistrict%=A%
  340   IF addr$(A%)="PAGE"                :idxPage%=A%
  350 NEXT A%
  360 RESTORE +0
  370 READ Parish$,Min%,Max%
  380 REPEAT
  390   FOR District%=Min% TO Max%
  400     PROCScan(Parish$,District%)
  410   NEXT:READ Parish$,Min%,Max%
  420 UNTIL Parish$="*"
  430 IF lookup%:CLOSE#lookup%:lookup%=0
  440 CLOSE#out%:out%=0
  450 QUIT
  460 :
  470 REM Must be in numerical order for FNlookup() to work
  480 DATA Whitby,1,7
  490 DATA Ruswarp,8,12
  500 REM DATA Aislaby,13,13
  510 REM DATA Newholm,14,14
  520 DATA Hawsker,15,15
  530 DATA Helredale,16,16
  540 REM DATA Fylingdales,17,19
  550 DATA Whitby,0,0
  560 DATA *,0,0
  570 :
  580 DEFPROCScan(Parish$,District%)
  590 path$=Parish$+d$+Parish$
  600 IF District%:path$=path$+STR$District% ELSE path$=path$+"Workhouse"
  610 Page%=0:Piece$=""
  620 REPEAT
  630   Page%=Page%+1
  640   item$=path$+"-"+STR$Page%+s$+"htm"
  650   in%=OPENIN(item$):found%=in%
  660   IF in%:PROCprocess:CLOSE#in%:in%=0
  670 UNTIL found%=0
  680 ENDPROC
  690 :
  700 DEFPROCprocess
  710 IF verbose%:VDU 30:PRINT SPC4;item$;SPC4
  720 Piece$="":Folio$="":Page$=""
  730 REPEAT
  740   A$=GET$#in%
  750   REPEAT:A%=INSTR(A$,"<"):IF A%:A$=LEFT$(A$,A%-1)+MID$(A$+">",INSTR(A$,">",A%)+1)
  760   UNTIL A%=0
  770   A%=INSTR(A$,"Class:"):IF A%:Piece$=MID$(A$,A%+9,4)
  780   A%=INSTR(A$,"Piece:"):IF A%:Piece$=Piece$+"/"+STR$VALMID$(A$,A%+8)
  790   A%=INSTR(A$,"Folio:"):IF A%:Folio$=STR$VALMID$(A$,A%+8)
  800   A%=INSTR(A$,"Page:") :IF A%:Page$ =STR$VALMID$(A$,A%+7)
  810 UNTIL EOF#in% OR (Piece$<>"" AND Folio$<>"" AND Page$<>""):PTR#in%=0
  820 IF Page$="":Page$=STR$(Page%-1)
  830 :
  840 REPEAT:A$=GET$#in%:UNTIL INSTR(A$,"Ancestry Index"OR EOF#in%:IF EOF#in%:ENDPROC
  850 REPEAT
  860   REM Process entry
  870   PROCentry
  880   REM Look for vacant/nondomestic properties
  890   REPEAT
  900     PROCcsv_rd(lookup%,info$())
  910     IF info$(2)="" AND info$(1)<>"" THEN
  920       IF info$(14)<>"":Parish$=info$(14)
  930       PROCupdate_addresses     :REM Correct and canonicalise addresses
  940       PROCoutput
  950     ENDIF
  960   UNTIL info$(0)<>"" OR EOF#lookup%
  970 UNTIL EOF#in%
  980 ENDPROC
  990 :
 1000 DEFPROCentry
 1010 info$()=""
 1020 REPEAT
 1030   field$=""
 1040   a$=GET$#in%
 1050   REM IF INSTR(a$,"var currentImageId"):A%=INSTR(a$,"="):Piece$=MID$(a$,A%+6,4)+"/"+MID$(a$,A%+11,4)
 1060   A%=INSTR(FNuc(a$),"<TD CLASS=""T_C")
 1070   IF A% THEN
 1080     a$=MID$(a$,A%+11)
 1090     A%=INSTR(a$,""">"):field$=LEFT$(a$,A%-1):a$=MID$(a$,A%+2)
 1100     a$=MID$(a$,INSTR(a$,"<span"))
 1110     a$=MID$(a$,INSTR(a$,">")+1)
 1120     a$=LEFT$(a$,INSTR(a$,"</span")-1)
 1130     REPEAT
 1140       A%=INSTR(a$,"<"):IF A%:a$=LEFT$(a$,A%-1)+MID$(a$,INSTR(a$,">")+1)
 1150     UNTIL A%=0
 1160     REPEAT
 1170       A%=INSTR(a$,"&"):IF A%:a$=LEFT$(a$,A%-1)+"&"+MID$(a$,A%+5)
 1180     UNTIL A%=0
 1190     IF a$="add":a$=""
 1200     IF a$=CHR$160:a$=""
 1210     :
 1220     IF field$="t_c1" :info$(0) =a$:REM Household number
 1230     IF field$="t_c3" :info$(1) =a$:REM Surname
 1240     IF field$="t_c2" :info$(2) =a$:REM Given Name
 1250     IF field$="t_c5" :info$(3) =a$:REM Age
 1260     IF field$="t_c4" :info$(4) =a$:REM Relationship
 1270     IF field$="t_c7" :info$(5) =a$:REM Sex
 1280     IF field$="t_c6" :info$(9) =a$:REM Estimated Birth Year
 1290     IF field$="t_c8" :info$(10)=a$:REM Birth Place
 1300     IF field$="t_c9" :info$(11)=a$:REM Birth County
 1310     IF field$="t_c10":info$(12)=a$:REM Birth Country
 1320     :
 1330   ENDIF
 1340 UNTIL field$="t_c10" OR EOF#in%
 1350 IF info$(0)="":ENDPROC
 1360 :
 1370 REM Find street address
 1380 IF District%<>0:A$=FNlookup(TRUE,7,Parish$,District%,Page%,info$(0),"","","") :REM Street address
 1390 IF District%=0 :A$="Whitby Workhouse, Green Lane":info$(14)="Helredale"       :REM Street address
 1400 IF A$<>"":info$(7)=A$
 1410 :
 1420 PROCupdate_names     :REM Correct and canonicalise names
 1430 PROCupdate_addresses :REM Correct and canonicalise addresses
 1440 :
 1450 REM Find corrections
 1460 A$=FNlookup(FALSE,0,Parish$,District%,Page%,info$(0),info$(1),info$(2),info$(3))
 1470 IF A$<>"" THEN
 1480   IF addr$(8)<>"":info$(8)=addr$(8) :REM Occupation
 1490   :
 1500   REM A$=FNs(FNlookup(FALSE,6,Parish$,District%,Page%,info$(0),info$(1),info$(2),info$(3)))
 1510   A$=FNuc(LEFT$(FNs(addr$(6)),1))   :REM Marital status
 1520   IF A$="S":A$="Single"
 1530   IF A$="M":A$="Married"
 1540   IF A$="W":A$="Widow":IF LEFT$(info$(5),1)="M":A$="Widower"
 1550   IF A$="N":A$="Not known"
 1560   IF A$="U":A$="Unknown"
 1570   IF A$<>"":info$(6)=A$
 1580 ENDIF
 1590 :
 1600 PROCoutput
 1610 ENDPROC
 1620 :
 1630 REM Correct and canonicalise entries
 1640 DEFPROCupdate_names
 1650 REM Spelling mistakes:
 1660 A$=info$(1)
 1670 A$=FNswap(A$,"Brouz","Brown")
 1680 A$=FNswap(A$,"Kepling","Kipling")
 1690 A$=FNswap(A$,"Warsay","Marsay")
 1700 A$=FNswap(A$,"Mc ","Mc")
 1710 A$=FNswap(A$,"Sleighthoha","Sleightholme")
 1720 A$=FNswap(A$,"Slaightholane","Sleightholme")
 1730 info$(1)=A$
 1740 :
 1750 REM Contractions:
 1760 A$=info$(2)
 1770 A$=FNswap(A$,"Hy","Henry")
 1780 A$=FNswap(A$,"Wm","William")
 1790 A$=FNswap(A$,"Thos","Thomas")
 1800 A$=FNswap(A$,"Geo ","George ")
 1810 IF RIGHT$(A$,3)="Geo":A$=A$+"rge"
 1820 info$(2)=A$
 1830 :
 1840 A$=info$(4)
 1850 A$=FNswap(A$,"Wifes ","Wife's ")
 1860 A$=FNswap(A$,"Sons ","Son's ")
 1870 A$=FNswap(A$,"Daughters ","Daughter's ")
 1880 A$=FNswap(A$,"Stop","Step")
 1890 A$=FNswap(A$,"Fother","Father")
 1900 info$(4)=A$
 1910 :
 1920 A$=info$(10)
 1930 A$=FNswap(A$,"Barrowin Frurness","Barrow in Furness")
 1940 A$=FNswap(A$,"Bristish","British")
 1950 A$=FNswap(A$,"Clevrland","Cleveland")
 1960 A$=FNswap(A$,"Copmhager","Copenhagen")
 1970 A$=FNswap(A$,"Eyton ","Egton ")
 1980 A$=FNswap(A$,"Eshdale","Eskdale")
 1990 A$=FNswap(A$,"Falysave Scarbro","Falsgrave, Scarborough")
 2000 A$=FNswap(A$,"Fylindales","Fylingdales")
 2010 A$=FNswap(A$,"Fylingobees","Fylingdales")
 2020 A$=FNswap(A$,"Gromond","Grosmont")
 2030 A$=FNswap(A$,"Gromont","Grosmont")
 2040 A$=FNswap(A$,"Groomont","Grosmont")
 2050 A$=FNswap(A$,"Hpool","Hartlepool")
 2060 A$=FNswap(A$,"Hawsher","Hawsker")
 2070 A$=FNswap(A$,"Hawaker","Hawsker")
 2080 A$=FNswap(A$,"Hausker","Hawsker")
 2090 A$=FNswap(A$,"Hamker","Hawsker")
 2100 A$=FNswap(A$,"Hawkes cum Stainseae","Hawsker cum Stainsacre")
 2110 A$=FNswap(A$,"Stainsacre Hawsker Cum","Hawsker cum Stainsacre")
 2120 A$=FNswap(A$,"Hawsker; Stainsacre","Hawsker cum Stainsacre")
 2130 A$=FNswap(A$,"Helredule","Helredale")
 2140 A$=FNswap(A$,"Kettlencss","Kettleness")
 2150 A$=FNswap(A$,"Herbymooreside","Kirbymooreside")
 2160 A$=FNswap(A$,"Kirby Malzaard","Kirbymooreside")
 2170 A$=FNswap(A$,"Kirby Moorside","Kirbymooreside")
 2180 A$=FNswap(A$,"Kirby Morrside","Kirbymooreside")
 2190 A$=FNswap(A$,"Kirkby Malzeard","Kirbymooreside")
 2200 A$=FNswap(A$,"Kirkby Moorside","Kirbymooreside")
 2210 A$=FNswap(A$,"Lealbolm","Lealholm")
 2220 A$=FNswap(A$,"Leatholm","Lealholm")
 2230 A$=FNswap(A$,"Loftussin Cleveland","Loftus in Cleveland")
 2240 A$=FNswap(A$,"Loftus in Leveland","Loftus in Cleveland")
 2250 A$=FNswap(A$,"Lofhes in Cleveland","Loftus in Cleveland")
 2260 A$=FNswap(A$,"Loythe","Lythe")
 2270 A$=FNswap(A$,"Ualton","Malton")
 2280 A$=FNswap(A$,"Vealton","Malton")
 2290 A$=FNswap(A$,"Matgrave","Mulgrave")
 2300 A$=FNswap(A$,"Merbgrave","Mulgrave")
 2310 A$=FNswap(A$,"Mugrave","Mulgrave")
 2320 A$=FNswap(A$,"Mulynare","Mulgrave")
 2330 A$=FNswap(A$,"Mutgrave","Mulgrave")
 2340 A$=FNswap(A$,"Newhihas","Newholm")
 2350 A$=FNswap(A$,"Newholn","Newholm")
 2360 A$=FNswap(A$,"Newholundanley","Newholm cum Dunsley")
 2370 A$=FNswap(A$,"Newtwton","Newton")
 2380 A$=FNswap(A$,"Ravcuscar","Ravenscar")
 2390 A$=FNswap(A$,"Ravenacar","Ravenscar")
 2400 A$=FNswap(A$,"Robin Hordo Bay","Robin Hood's Bay")
 2410 A$=FNswap(A$,"Robin Woods Bay","Robin Hood's Bay")
 2420 A$=FNswap(A$,"R H Bay","Robin Hood's Bay")
 2430 A$=FNswap(A$,"Robeir Hood Bay","Robin Hood's Bay")
 2440 A$=FNswap(A$,"Robier Hodis Bay","Robin Hood's Bay")
 2450 A$=FNswap(A$,"Robin Hood Bay","Robin Hood's Bay")
 2460 A$=FNswap(A$,"Robin Hooch's Bay","Robin Hood's Bay")
 2470 A$=FNswap(A$,"Robin Hoods Ray","Robin Hood's Bay")
 2480 A$=FNswap(A$,"Robin Hooel's Bing","Robin Hood's Bay")
 2490 A$=FNswap(A$,"Robin Hords Bay","Robin Hood's Bay")
 2500 A$=FNswap(A$,"Robin Hood's Rads","Robin Hood's Bay")
 2510 A$=FNswap(A$,"Rsbin Hoods Bay","Robin Hood's Bay")
 2520 A$=FNswap(A$,"Robin Hood's Boy","Robin Hood's Bay")
 2530 A$=FNswap(A$,"Robin Hoods Bay","Robin Hood's Bay")
 2540 A$=FNswap(A$,"Robin Hood Pary","Robin Hood's Bay")
 2550 A$=FNswap(A$,"Remswick Bay","Runswick Bay")
 2560 A$=FNswap(A$,"Ruswart","Ruswarp")
 2570 A$=FNswap(A$,"Roswarp","Ruswarp")
 2580 A$=FNswap(A$,"Rusworp","Ruswarp")
 2590 A$=FNswap(A$,"Ruswap","Ruswarp")
 2600 A$=FNswap(A$,"Rusward","Ruswarp")
 2610 A$=FNswap(A$,"Ruswark","Ruswarp")
 2620 A$=FNswap(A$,"Ruawarp","Ruswarp")
 2630 A$=FNswap(A$,"Sandsond","Sandsend")
 2640 A$=FNswap(A$,"Sandseard","Sandsend")
 2650 A$=FNswap(A$,"Scorborough","Scarborough")
 2660 A$=FNswap(A$,"Sleighto","Sleights")
 2670 A$=FNswap(A$,"Ipalding","Spalding")
 2680 A$=FNswap(A$,"Sarth Shields","South Shields")
 2690 A$=FNswap(A$,"Stainsene","Stainsacre")
 2700 A$=FNswap(A$,"Stainsaere","Stainsacre")
 2710 A$=FNswap(A$,"Stainsane","Stainsacre")
 2720 A$=FNswap(A$,"Stanasaere","Stainsacre")
 2730 A$=FNswap(A$,"Agglebarnby","Ugglebarnby")
 2740 A$=FNswap(A$,"Uggbtamby","Ugglebarnby")
 2750 A$=FNswap(A$,"Ugglebaruby","Ugglebarnby")
 2760 A$=FNswap(A$,"Eyhitby","Whitby")
 2770 A$=FNswap(A$,"Brit Sub","British Subject")
 2780 A$=FNswap(A$,"B S,","British Subject,")
 2790 A$=FNswap(A$,"Nat ","Naturalised ")
 2800 IFRIGHT$(A$,4)=" B S":A$=LEFT$(A$,LENA$-4)+"British Subject"
 2810 IFRIGHT$(A$,4)="Subj":A$=LEFT$(A$,LENA$-4)+"Subject"
 2820 IFLEFT$(A$,4)="Bel ":A$=MID$(A$,5):info$(12)="Belgium"
 2830 IFLEFT$(A$,4)="Dnk ":A$=MID$(A$,5):info$(12)="Denmark"
 2840 IFLEFT$(A$,4)="Fra ":A$=MID$(A$,5):info$(12)="France"
 2850 IFLEFT$(A$,4)="Ind ":A$=MID$(A$,5):info$(12)="India"
 2860 IFLEFT$(A$,4)="Rus ":A$=MID$(A$,5):info$(12)="Russia"
 2870 IFLEFT$(A$,4)="Swe ":A$=MID$(A$,5):info$(12)="Sweden"
 2880 IFLEFT$(A$,4)="Che ":A$=MID$(A$,5):info$(12)="Switzerland"
 2890 IFMID$(A$,4,1)=" ":IF info$(12)="":info$(12)=LEFT$(A$,3):A$=MID$(A$,5)
 2900 IFinfo$(12)="":IFINSTR(A$,"Cardiff"):info$(12)="Wales"
 2910 IFLEFT$(A$,2)="N ":A$="North"+MID$(A$,2)
 2920 IFLEFT$(A$,2)="S ":A$="South"+MID$(A$,2)
 2930 IFLEFT$(A$,2)="E ":A$="East"+MID$(A$,2)
 2940 IFLEFT$(A$,2)="W ":A$="West"+MID$(A$,2)
 2950 IFA$="Fylingdale":A$="Fylingdales"
 2960 IFA$="B S":A$="British Subject"
 2970 IFA$="Lyth":A$="Lythe"
 2980 info$(10)=A$
 2990 ENDPROC
 3000 :
 3010 REM Canonicalise addresses
 3020 DEFPROCupdate_addresses
 3030 info$(14)=Parish$                       :REM Civil parish
 3040 info$(15)="Whitby"                      :REM Sub-registration district
 3050 IF info$(16)="":info$(16)=STR$District% :REM Enumeration District
 3060 IF info$(17)="":info$(17)=Piece$        :REM Piece
 3070 IF info$(18)="":info$(18)=Page$         :REM Page
 3080 IF info$(19)="":info$(19)=Folio$        :REM Folio
 3090 :
 3100 A$=info$(7)
 3110 LOCAL DATA:RESTORE +0
 3120 READ street$
 3130 REPEAT
 3140   READ yard$
 3150   REPEAT
 3160     A$=FNadd(A$,yard$,street$)
 3170     READ yard$
 3180   UNTILyard$="*"
 3190   READ street$
 3200 UNTILstreet$="*"
 3210 info$(7)=A$
 3220 RESTORE DATA
 3230 REM :
 3240 REM Clarke's Yard on Church Street and Flowergate
 3250 REM Miller's Yard on Church Street, Flowergate and Haggersgate
 3260 REM Andrew's Yard on Church Street and Cliff Street
 3270 REM Lockey's Yard on Church Street and Grape Lane
 3280 REM Dark Entry Yard on Church Street and Baxtergate
 3290 REM Johnson's Yard on Baxtergate and Sandgate
 3300 DATA "Church Street"
 3310 DATA "Ainsley's","Bank's","Brewery Lane","Benson's","Blackburn's","Blacksmith's","Bonson's","Borough","Boulby"
 3320 DATA "Cappleman's","Cockpit","Corner's","Craven's","Elbow","Flintoft's","Frank's","Forester's"
 3330 DATA "Green's","Horse","Hospital","Imperial Yard","Ivy Yard","Kelly's","Kiln","Kirby's","Locker's","Mast Yard"
 3340 DATA "Marshall's","Monkman's","New Way","Outhard's","Primitive Methodist Chapel Yard","Prospect Place","Renwick's"
 3350 DATA "Sayer's","School Yard","Smales' Gallery","St. Hilda's Cottages","Steps","Taylorson's","Turner's"
 3360 DATA "Woodwark's","Well Yard","Timber","Studley","Horner's","Ivy Yard"
 3370 DATA *
 3380 DATA "Sandgate"
 3390 DATA "Nicholson's","Queen Hotel"
 3400 DATA *
 3410 DATA "Grape Lane"
 3420 DATA "Tin Ghaut","Lamb's","Raffled Anchor","Custom House Hotel"
 3430 DATA *
 3440 REM DATA "Baxtergate"
 3450 REM DATA "Belle Hotel","Mead's","Angel Hotel","Vipond's","Goodwill's","Ward's","Plough Inn"
 3460 REM DATA "Brignell's","Tyreman's","Woodhouse","Mackridge's","Albion Hotel","Trueman's"
 3470 REM DATA "Wald's","Leng's","Coffee Bar","Bland's","Dotchson's","Brunswick Chapel"
 3480 REM DATA "Breckon's"
 3490 REM DATA *
 3500 DATA "Flowergate"
 3510 DATA "McLacklin's"
 3520 DATA "Abbey Yard","Duck's","Easterby","Forth's","Gardiner's","Haydock's","Kidd's","Staffordshire"
 3530 DATA "Waterloo"
 3540 DATA *
 3550 DATA "Cliff Street"
 3560 DATA "Andrew's","Bolton's","Cole's"
 3570 DATA *
 3580 DATA "St. Ann's Staith"
 3590 DATA "Wear's","Buck Hotel","Old Post Office","St. Ann's Lane"
 3600 DATA *
 3610 DATA "Haggersgate"
 3620 DATA "Paradise","Whitby Arms","Elephant","Institute","Neptune"
 3630 DATA "Muncaster's","Cuthbert's"
 3640 DATA *
 3650 DATA "Skinner Street"
 3660 DATA "Sandal","Harrison's","Ivy Place","Botham's","Abbey View","Ruth's"
 3670 DATA *
 3680 DATA "Bagdale"
 3690 DATA "Arundel","Broomfield Terrace","Carr's"
 3700 DATA *
 3710 REM DATA "Larpool"
 3720 REM DATA "Cock","Crowdy"
 3730 REM DATA *
 3740 REM DATA "Spital Bridge"
 3750 REM DATA "Whitehall","Kelp"
 3760 DATA *
 3770 DATA *
 3780 ENDPROC
 3790 :
 3800 DEFPROCoutput
 3810 IF verbose%:FOR A%=0 TO max%:PRINTTAB(32,A%+1);LEFT$(info$(A%),48);SPC(len%(A%)-LENLEFT$(info$(A%),48));:len%(A%)=LENLEFT$(info$(A%),48):NEXT
 3820 PROCcsv_wr(out%,info$())
 3830 ENDPROC
 3840 :
 3850 REM Fails when searching Workhouse as D%=0
 3860 DEFFNlookup(Z%,   R%,     P$,     D%,       S%,   H$,F1$,F2$,F3$)
 3870 REM         flag, return, parish, district, page, household
 3880 IF lookup%=0:=""
 3890 REM looklast%=PTR#lookup%
 3900 PTR#lookup%=looklast%
 3910 REPEAT
 3920   match%=FALSE:lookptr%=PTR#lookup%:PROCcsv_rd(lookup%,addr$())
 3930   REM VDU30
 3940   REM PRINT"Lookfor: "H$"/"P$"/";D%"/";S%;"/"F1$"/"F2$"/"F3$"/  "
 3950   REM PRINT"Found:   "addr$(0)"/"addr$(idxParish%)"/"addr$(idxDistrict%)"/"addr$(idxPage%)"/"addr$(1)"/"addr$(2)"/"addr$(3)"/  "
 3960   REM IFGET
 3970   IF F1$="" :IF FNuc(addr$(idxParish%))=FNuc(P$):IF VALaddr$(idxDistrict%)=D%:IF addr$(0)=H$:match%=TRUE
 3980   IF F1$<>"":IF FNuc(addr$(idxParish%))=FNuc(P$):IF VALaddr$(idxDistrict%)=D%:IF addr$(0)=H$:IF addr$(1)=F1$:IF addr$(2)=F2$:IF addr$(3)=F3$:match%=TRUE
 3990 UNTIL match% OR EOF#lookup% OR (VALaddr$(idxDistrict%)*1000+VALaddr$(idxPage%)>D%*1000+S%+1 AND D%>0)
 4000 REM IF Z%:IF match%:PTR#lookup%=lookptr% ELSE PTR#lookup%=looklast%
 4010 IF Z%:IF match%:looklast%=lookptr% ELSE looklast%=looklast%
 4020 IF match%:=addr$(R%)
 4030 =""
 4040 :
 4050 DEFFNadd(addr$,yard$,street$)
 4060 IF INSTR(addr$,yard$+" "):IF INSTR(addr$,street$)=0:=addr$+", "+street$
 4070 IF RIGHT$(addr$,LENyard$)=yard$:IF INSTR(addr$,street$)=0:=addr$+", "+street$
 4080 =addr$
 4090 :
 4100 DEFFNswap(in$,match$,swap$)
 4110 A%=INSTR(in$,match$):IF A%:in$=LEFT$(in$,A%-1)+swap$+MID$(in$,A%+LENmatch$)
 4120 =in$
 4130 :
 4140 DEFPROCClose_All
 4150 lookup%=lookup%:IFlookup%:A%=lookup%:lookup%=0:CLOSE#A%
 4160 out%=out%:IFout%:A%=out%:out%=0:CLOSE#A%
 4170 in%=in%:IFin%:A%=in%:in%=0:CLOSE#A%
 4180 ENDPROC
 4190 :
 4200 DEFPROCcsv_rd(i%,array$())
 4210 LOCAL n%:n%=0:array$()="":A$=GET$#i%:IFA$="":A$=GET$#i%
 4220 A$=A$+","
 4230 REPEAT
 4240   IF LEFT$(A$,2)="=""":A$=MID$(A$,2)
 4250   IF LEFT$(A$,1)="""" THEN
 4260     A%=INSTR(A$,""",",2)+1:array$(n%)=MID$(A$,2,A%-3)
 4270   ELSE
 4280     A%=INSTR(A$,","):array$(n%)=LEFT$(A$,A%-1)
 4290   ENDIF
 4300   A$=MID$(A$,A%+1):n%=n%+1
 4310 UNTILA$=""
 4320 ENDPROC
 4330 :
 4340 DEFPROCcsv_wr(o%,array$())
 4350 LOCAL n%,q%:n%=DIM(array$(),1)
 4360 FOR A%=0 TO n%:A$=array$(A%)
 4370   q%=INSTR(A$,",")
 4380   IF q%=0:q%=(ASCA$=48)AND(INSTR(A$,"/")=0)ANDLENA$>1 :REM leading zeros 00001
 4390   IF q%=0:IFVALLEFT$(A$,1):q%=INSTR(A$,"E")           :REM preserve 1234E5678
 4400   IF q%=0:q%=LENSTR$VALA$>8                           :REM long numbers 12345678901234
 4410   IF q%=0:IFVALA$:q%=INSTR(A$,"/")AND(ASCA$<>48)      :REM fractions 12/34
 4420   IF q%=0:q%=LEFT$(A$,1)="-"                          :REM leading hyphen -
 4430   IF q%=0:q%=MID$(A$,3,1)=" "ANDMID$(A$,7,1)=" "      :REM dates xx XXX xxxx
 4440   IF q%:A$=""""+A$+"""":IFINSTR(A$,",")=0:A$="="+A$
 4450   BPUT#o%,A$;:IF A%<>n%:BPUT#o%,",";
 4460 NEXT A%:BPUT#o%,""
 4470 ENDPROC
 4480 :
 4490 DEFFNd0(A%,N%)=RIGHT$("00000000"+STR$A%,N%)
 4500 DEFFNuc(A$):IFA$="":=""
 4510 FOR A%=1 TO LEN A$:IFMID$(A$,A%,1)>"_":A$=LEFT$(A$,A%-1)+CHR$(ASCMID$(A$,A%,1)AND&DF)+MID$(A$,A%+1)
 4520 NEXT:=A$
 4530 DEFFNs(A$):IFLEFT$(A$,1)=" ":REPEATA$=MID$(A$,2):UNTILLEFT$(A$,1)<>" "
 4540 IFRIGHT$(A$,1)=" ":REPEATA$=LEFT$(A$,LENA$-1):UNTILRIGHT$(A$,1)<>" "
 4550 =A$