IMD 1.16: 1/06/2007 9:40:43 FOGCPM.151 ååååååååååååååå--FOGCPM151ANYCODE DOC€ ANYCODE DOC-01-00 87 ¡ANYCODE ASMCHGCHAR COMCHGCHAR DOC'CHGCHAR AQM !"#DBL COM$%&'DBL DOC(IXMAIN COM€)*+,-./012345678IXMAIN COM9:;-CPM151 DOC¢£¤IXMAIN PAS)<=>?@AIXDIAG PAS BCIXDOIT PASNDEFGHIJKLMIXDONE PASNOPQIXINIT PAS(RSTUVIXSTRG PAS+WXYZ[\IXTEXT PAS]^_`IXTREE PAS%abcdeIXWALK PASfghiINDEXER DOC€jklmnopqrstuvwxyINDEXER DOCEz{|}~€�‚ABSTRACT ƒIXMERGE COMp„…†‡ˆ‰Š‹Œ�Ž��‘IXMERGE PASs’“”•–—˜™š›œ�žŸ åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååThis is the disk name. åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå.pl 88 0 ANYCODE Doug Hurst M IMPORTANÔ  NOTEº  Thå  documentatioî  foò ANYCODÅ ió baseä oî aî articlå submitteä tï thå newlù reviveä "Portablå  Companion¢  magazinå  foò � Osbornå Computeò Owners®  Thå referencå arå Osbornå oriented® Iî reality¬ thå prograí ió morå WordStaò thaî Osbornå oriented¬ anä ió uð anä � runninç  oî  Heatè  anä Zorbá machineó anä ió adaptablå tï alì WordStars¬  Versionó 2.26¬  3.0Ø anä 3.3X®  Bå absolutelù  certaiî  thaô  yoõ � carefullù  makå  ALÌ  substitutionó foò youò versioî oæ WordStar®  Therå arå severaì throughout®  Questions¬  commentó anä bugó  shoulä  bå � reporteä tï må aô 680¸ Estrellá Ave.¬ Twentyninå Palms¬ CÁ 92277¬ eveninç (619© 367-109° (evenings). PLEASE!¡  Givå  thió articlå á looë eveî iæ iô seemó somewhaô complicated®  Iô ió á useful¬  valuablå modificatioî tï WordStaò anä  ió � quitå simplå iæ yoõ wilì takå iô steð bù step® VALUE®  Makeó  WordStaò morå powerfuì anä texô fileó morå flexiblå anä portable®  ANYCODÅ doeó thió withouô enlarginç thå sizå oæ thå  maiî � WordStaò prograí WS.COM®  Thió ió á verù importanô point®  Bù keepinç WS.COÍ confineä tï itó "stock¢ size¬  iô maù installeä oò  reinstalleä � usinç INSTALL.COÍ aô wilì withouô affectinç oò havinç tï reinstalì ANYCODE. INTRODUCTION. Thå EPSOÎ FX¬  MØ (w/Graftrax© anä RØ series¬ aó welì aó manù otheò brandó oæ printers¬ havå manù morå modeó oæ operatioî availablå thaî � caî bå accesseä bù á normallù installeä WordStar¬ eveî iæ onå useó alì thå built-iî anä useò defineä prinô controì codå facilitieó available® � Noô  onlù  caî  theså built-iî anä useò defineä codeó NOÔ keeð pacå witè thå printer'ó capability¬  oncå installed¬  theù arå  noô  alterablå � withouô  usinç  DDT/SID.COÍ  oò WordStar'ó INSTALL.COM®  Therå arå severaì commerciallù availablå programó thaô wilì leô yoõ  senä  alì  thå � controì  codeó á printeò wilì accept®  Theù diffeò froí thå onå presenteä iî thió articlå iî thaô thió onå ió free®  Thió articlå  ió  alsï � designeä tï servå thå duaì purposå oæ displayinç ho÷ mucè untappeä potentiaì therå ió iî standarä WordStar® USINÇ ANYCODE. Beforå gettinç intï thå codinç anä installatioî oæ ANYCODE¬ iô ió importanô tï seå whaô thå outcomå oæ youò effortó wilì be® Thió will¬ � iô  ió hoped¬  piquå youò interesô anä keeð yoõ froí givinç up®  Iæ yoõ regularlù uså á WordStaò witè CHARTECÈ oò similaò prograí installed¬ � yoõ  alreadù possesó thå functioî thaô ANYCODÅ wilì perform®  You'rå welcomå tï continuå anyway®  Aó mentioneä earlier¬  á nicå featurå  oæ � ANYCODÅ ió thaô iô doeó noô enlargå thå sizå oæ WS.COÍ aó manù similaò commerciallù availablå productó do. Oncå installed¬ uså oæ ANYCODÅ codeó haó thå samå functionaì effecô aó WordStar'ó prinô controì codes® Insteaä oæ embeddinç theí iî thå � texô  witè  á prinô controì codå sucè aó ^PS¬  however¬  yoõ enteò ANYCODÅ verù mucè aó thå codeó actuallù appeaò iî  youò  printer'ó  user'ó � manual®  ANYCODÅ codes¬  however¬  arå noô invisiblå tï thå editor®  Iî otheò words¬  wheî yoõ placå ANYCODE'ó codeó iî youò text¬ theù arå � treateä jusô likå normaì texô bù WordStar®  Thió meanó theù wilì bå includeä iî sucè functionó aó wordwrað anä paragrapè reformatting®  Foò � thió reason¬ iô ió suggesteä thaô yoõ enteò alì youò text¬ geô iô formatteä jusô thå waù yoõ want¬ theî gï bacë anä inserô thå ANYCODÅ codes® � Thió  maù forcå yoõ tï uså thå ^OØ (releaså margin© commanä morå thaî yoõ arå useä tï (somå lineó wilì extenä faò beyonä thå  margin)®  Thió � shoulä bå oæ nï concerî tï yoõ thougè becauså ANYCODÅ codeó arå non-printinç jusô likå WordStar'ó prinô controì codes®  Thå actuaì linå wilì � fiô withiî thå marginó iæ iô diä prioò tï codå insertion. ANYCODÅ codeó wilì usuallù takå onå oæ thå threå formó showî below¬ jusô aó mosô printeró accepô codeó iî onå oæ theså threå forms. straighô heø code escapå « heø code escapå « heø codå « traileò codå ± « traileò codå 2....« traileò codå n Belo÷ arå ANYCODÅ exampleó oæ eacè typå foò EPSOÎ printers: `0Æ Woulä transmiô 0Fè (turî condenseä prinô modå on). ~4µ Woulä transmiô ,45è (turî emphasizeä prinô on). ~2D`0± Woulä transmiô ,2Dh,0± (turî oî continuouó underline). Aó á furtheò example¬ á shorô sectioî oæ text¬ firsô withouô codeó anä theî witè ANYCODÅ codeó embedded. Deaò Bob, Jusô wanteä tï leô yoõ kno÷ É waó thrilleä witè thå modifieä BIOÓ yoõ senô me® Iô workeä SUPER. Deaò Bob, Jusô wanteä tï leô yoõ kno÷ É waó ~34thrilled~3µ witè thå modifieä ~2D`01BIOS~2D`0° yoõ senô me® Iô workeä `0ESUPER!`14. Iî thå loweò examplå witè thå embeddeä (agaiî EPSON© codes¬ ~3´ anä ~3µ turî italicó on/off¬ ~2D`0± anä ~2D`0° turnó underlinå on/ofæ anä `0Å � anä `1´ turî expandeä prinô on/off. Noticå ho÷ thå firsô linå no÷ extendó pasô thå normaì margin®  Again¬  iô WILÌ NOÔ wheî thå printinç actuallù takeó placå sincå ANYCODÅ � codå ió non-printing®  Thå twï leaä characteró foò ANYCODÅ codå werå pickeä especiallù foò thå Osbornå computer®  Yoõ wilì noô finä theí oî � youò keyboard® Tï makå á "~"¬ typå ^? (controì ?)® Tï placå á "`¢ oî thå screen¬ typå á ^+ (controì +)® Iæ  yoõ haven'ô seeî thå obviouó advantagå tï sendinç thå printeò codeó iî thå ANYCODÅ formaô oveò WordStar'ó codeó yet¬  herå arå  two® � First¬  yoõ caî senä anù codå tï thå printer® (Okay¬ thå cató ouô oæ thå bag¬ no÷ yoõ kno÷ wherå thå namå oæ thå prograí camå from.© Second¬ � saù  yoõ  takå WordStaò anä á documenô disë witè yoõ somewherå (likå froí homå tï work© anä want/neeä tï prinô á filå usinç anotheò  computeò � (obviouslù  anotheò  Osbornå oò Osbornå disë formaô compatible)®  Yoõ prepareä thå documenô oî youò Osbornå whicè ió  installeä  witè  Prinô � Controló tï senä EPSOÎ codes® Thå computeò aô work¬ however¬ ió drivinç á NEà printer® Witè ANYCODÅ codeó embeddeä iî thå text¬ wouldn'ô iô � bå easù tï uså thå Finä anä Replacå (^QA© commanä tï finä thå EPSOÎ codeó anä substitutå NEà codes¿ Answeò yeó sï wå caî continue. Š Therå arå á fe÷ cautions¬ anä yoõ maù aó welì kno÷ theí now® 1® Uså alì capitaì letteró (`0A¬ NOÔ `0a)(anä that'ó zerï noô o). 2® Eacè heø codå musô bå twï digits® (µ entereä aó 05¬ Å entereä aó 0E¬ etc.) 3® Duå tï spacå limitationó anä á desirå oî thå parô oæ thå authoò tï keeð ANYCODÅ confineä tï thå MORPATº areá (explaineä later)¬ � nï  provisionó werå madå tï bå ablå tï prinô thå lead-iî characteró à anä ~®  Iæ yoõ uså eitheò oæ theså characteró frequentlù iî youò  worä � processinç  operations¬  yoõ shoulä consideò pickinç otheò characteró thaô yoõ dï noô uså often®  Thå commentó tï ANYCODE.ASÍ belo÷ indicatå � wherå tï makå substitutionó tï thå defaulô lead-iî characters. 4®  Thå MORPATº  areá musô bå free®  Lateò iî thå articlå DDT.COÍ ió useä tï makå somå modificationó tï WordStaò anä checë tï seå � thaô thå MORPATº areá ió clear® Iæ iô ió not¬ ABORT¡ 5®  ANYCODÅ aó installeä belo÷ ió foò WordStar'ó installeä tï uså thå CP/Í Primarù Lisô Device® Yoõ caî checë thió wheî yoõ firsô � booô WordStaò anä observå thå sign-oî messagå (Alsï wheî runninç INSTALL.COÍ oî WordStar¬ checë thå labeì CSWTCH:® Iô musô bå 0° foò ANYCODÅ � tï bå guaranteeä tï work)® Herå arå á wrong¬ theî á righô examplå oæ ANYCODÅ syntax. WRONG `FNo÷ ió thå timå foò ......® thå aiä oæ theiò countries.`12 Meaninç tï turî compresseä prinô on/off® Nï zerï ° betweeî thå à anä Æ aô beginninç oæ thå sentence® PROMISE¡ Thió wilì noô work. RIGHT `0FNo÷ ió thå timå foò ......® thå aiä oæ theiò countries.`12 PROMISE¡ Thió wilì work. Follo÷ thå simplå ruleó laiä ouô above¬ anä yoõ wilì havå nï problem® No÷ foò thå work. WHAÔ DÏ WÅ MODIFÙ ANÄ WHERÅ DÏ THÅ MODIFICATIONÓ GO? MicroPrï  and/oò  Osborne¬  iî theiò infinitå wisdom¬  decideä tï includå INSTALL.COÍ witè WordStar¬  buô noô tï  includå  thå  completå � terminaì  anä  printeò  patcè  areas®  (Earlù Osbornå ± user'ó diä receivå thió treaô beforå Osbornå converteä tï  thå  "improved¢  referencå � manuals)®  Luckily¬  thå authoò waó ablå tï finä á completå manuaì foò WordStaò 3.0®  Aô anù rate¬ therå ió aî areá withiî WordStar¬ labeleä � MORPATº  thaô  containó  12¶ emptù byteó anä existó foò thå solå purposå oæ useò defineä sub-routines®  ANYCODÅ wilì bå  installeä  iî  thió � MORPATº  area® (Bù enlarginç thå sizå oæ WS.COM¬ eveî morå areá caî bå madå availablå foò useò supplieä code® Stand-bù tï uså somå oæ iô iî á � lateò article.© Wherå ió thå MORPATº  area¿ Foò threå WordStaò versionó knowî tï havå ANYCODÅ successfullù installed¬ iô resideó aô thå addresseó showî � below: WordStaò Version 2.2¶ 3.° 3.3 02DEè 02DEè 02BBh THÅ CODÅ ANÄ ASSEMBLY. Thå  commentó  tï  thå  codå maù seeí á littlå cryptiã sï thió narrativå explanatioî ió supplieä iî advance®  Wå  wilì  modifù  onå  oæ � WordStar'ó printeò driveró tï diverô alì characteró tï bå senô tï thå CP/Í Primarù Lisô Devicå tï ouò ANYCODÅ subroutine®  Eacè characteò ió � firsô checkeä tï seå iæ iô ió aî ANYCODÅ lead-iî character®  Iæ iô is¬  iô ió stored¬  á flaç ió seô anä thå nexô characteò ió read® Iæ thió � characteò  wasn'ô  á lead-iî character¬  iô ió checkeä tï seå iæ iô ió thå firsô oò seconä characteò followinç á lead-iî  character®  Iæ  iô � wasn't¬  iô ió senô ouô tï thå primarù lisô devicå normally® Iæ thå leaä characteò ió beinç storeä anä thå flaç ió set¬ iô meanó thå currenô � characteò ió thå firsô characteò followinç thå leaä character®  Thå flaç ió lowered¬ anä thå characteò processeä tï becomå halæ oæ thå totaì � follow-oî code®  Theî thå lasô characteò ió read® Iô toï ió checkeä tï seå iæ iô ió á lead-iî characteò oò ió thå firsô oò seconä follow-oî � character®  Iæ  iô ió thå seconä follow-oî character¬  iô ió addeä tï thå firsô follow-oî character¬  anä thå resulô senô tï thå lisô devicå � (printer)® Iæ yoõ didn'ô understanä mosô oæ thaô don'ô worrù abouô it®  Understandinç ió noô á requiremenô foò ANYCODÅ tï work® Herå ió thå � code® Bå surå tï uså thå "N¢ non-documenô modå iæ yoõ uså WordStar. » ANYCODE.ASÍ - Á prograí tï allo÷ printeò codeó tï bå transmitteä tï EPSOÎ oò otheò doô matriø printeò froí withiî WordStaò text. ; » Authorº D® M® Hurst » Dateº Apriì 23¬ 1984 ORÇ XXXXè ;Wherå XXXØ ió 02DEè foò WÓ 2.26/3.0 ;anä 02BBè foò WÓ 3.3 mysubº cpé '`§ ;ió iô á codå character? ;yoõ maù substitutå anotheò ;characteò iæ yoõ uså the ;¢ à ¢ ofteî iî youò texô Š jnú nchecë ;no¬ sï nexô check stá leaä ;yes¬ sï storå temporarily mvé a,± ;geô á ± iî accumulator stá fì ;seô fì flag reô ;geô anotheò character ;withouô printing ncheckº cpé '~§ ;ió iô á codå character¿ ;yoõ maù substitutå another ;characteò iæ yoõ uså thå ;¢ þ ¢ ofteî iî youò texô  jnú hchecë ;no¬ sï checë iæ parô of ;codå sequence stá leaä ;yeó sï storå temporarilù mvé a,± ;geô á ± iî accumulator stá fì ;seô fì flag mvé a,1bè ;þ meanó escapå requireä sï jmð pouô ;senä it. hcheckº moö b,á ;seô inpuô chaò aside ldá leaä ;geô contentó oæ lead cpé '`§ ;arå wå iî á codå seq? ;NOTEº iæ yoõ changeä thió code ;above¬ changå iô herå too® moö a,â ;chaò bacë iî accumulatoò jú flchë ;yes¬ sï checë iæ flaç set moö b,á ;no¬ sï chaò bacë tï b ldá leaä ;checë leaä again cpé '~§ ;arå wå iî á codå seq? ;NOTEº iæ yoõ changeä thió code ;above¬ changå iô herå too® ;chaò bacë iî accumulatoò moö a,â ;chaò bacë iî accumulator jú flchë ;yes¬ sï checë iæ flaç seô jmð pouô ;no¬ sï prinô chaò normally flchkº moö b,á ;seô chaò asidå again ldá fì ;geô fì flag cpé 00è ;± iæ seô set moö a,â ;chaò bacë iî accumulator jú addsnä ;noô set¬ sï lasô chaò iî seq moö b,á ;yes¬ sï seô chaò asidå agaiî mvé a,00è ;no¬ sï placå 00è iî accumulator stá fì ;anä loweò thå flag moö a,â ;chaò bacë iî accumulatoò cpé 39è ;ió codå chaò á letter? jí nolet± ;no¬ sï neveò minä sué 07è ;yes¬ sï makå iô á number nolet1º sué 30è ;no÷ dowî iô forí ASCII rlã ;firsô chaò iî codå sï rlã ;movå ´ lo÷ bitó tï high rlc rlc ané 0f0è ;° ´ loweò bits stá firsô ;storå it reô ;gï geô seconä chaò code addsndº moö b,á ;seô 2nä codå chaò aside mvé a,0° ;° thå accumulator lxé h,leaä ;geô leaä addò pointeò iî hl moö m,á ;° ouô thå lead inø è ;uð thå hl moö m,á ;alsï ° thå flag moö a,â ;geô chaò back cpé 39è ;waó 2nä codå chaò á letter? jí nolet² ;sï sï skið it sué 07è ;yeó sï makå iô á number nolet2º sué 30è ;no÷ dowî eitheò froí ASCII lxé h,firsô ;poinô tï firsô codå chaò addr moö b,í ;movå actuaì chaò tï b adä â ;adä á tï â (resulô iî a) poutº mvé c,µ ;prinô fulì codå char moö e,a calì 5 reô ;bacë foò nexô reaì char ; leaä dó ± ;spacå foò leaä code fì dó ± ;flaç space firsô dó ± ;storå firsô codå while ;waitinç foò 2nä tï pro- ;cess. Š end Havinç entereä ANYCODE.ASÍ above¬  iô musô bå assembled® Placå youò CP/Í systeí disë iî drivå Á anä thå disë containinç ANYCODE.ASÍ iî drivå � B® Enteò thå followinç commanä linå froí thå A¾ prompt: A>ASÍ ANYCODE.BBB Iæ therå arå nï errors¬  anotheò steð complete®  Thå authoò haó successfullù assembleä thió codå exactlù aó iô appearó iî thió article®  Iî � fact¬  thå codå waó reaä intï thå articlå froí ANYCODE.ASÍ usinç WordStar'ó ^KÒ command®  Iæ therå arå erroró iî assembly¬ gï bacë anä checë � youò typing®  Iæ iô diä assemblå withouô error¬  yoõ shoulä bå lefô witè ANYCODE.ASM¬  ANYCODE.HEØ anä ANYCODE.PRÎ oî drivå B®  Dï noô  uså � LOAD.COÍ anä attempô tï loaä ANYCODE.HEØ intï á .COÍ file® Thió ió noô necessarù anä woulä servå nï usefuì purpose. INSTALLATION: Very¬  verù  simple®  Althougè havinç alì theså fileó presenô isn'ô necessary¬  placå  WS.COM¬  WSMSGS.OVR¬  WSOVLY1.OVR¬  MAILMRGE.OVÒ � (MRGEPRIN.OVR)¬  DDT.COÍ anä ANYCODE.HEØ oî á SYSGEN'ä disë iî drivå A®  (Singlå densitù user'ó leavå thå threå .OVÒ programó ofæ foò no÷ anä � adä  theí  afteò  thå  installatioî oæ ANYCODÅ anä thå deletioî oæ DDT.COÍ anä ANYCODE.HEX© (Remembeò ANYCODE.HEØ waó  generateä  durinç  thå � assemblù oæ ANYCODE.ASM)® Wheî yoõ havå performeä thió task¬ enteò thå following: Versioî 2.2¶ Versioî 3.° Versioî 3.30 A>DDÔ WS.COMDDÔ WS.COMDDÔ WS.COM Yoõ shoulä see: A>DDÔ WS.COÍ A>DDÔ WS.COÍ A>DDÔ WS.COÍ DDÔ Veró 2.² DDÔ Veró 2.² DDÔ Veró 2.² NEXÔ Pà NEXÔ Pà NEXÔ PC 400° 010° 3F0° 010° 460° 010° - - - Thå MORPATº areá musô bå clear® So¬ froí thå "-¢ prompô typå thå following: Versioî 2.2¶ Versioî 3.° Versioî 3.30 -d2de -R Now type: -d2bb (WS.COM 2.26 and 3.0 type -d2de) Yoõ shoulä seå somethinç likå thisº (WS.COÍ 2.2¶ anä 3.° wilì starô aô -d2de) 02BB FE 60 C2 23 01 .`.#. 02C0 32 92 01 3E 01 32 93 01 C9 FE 7E C2 35 01 32 92 2..>.2....~.5.2. 02D0 01 3E 01 32 93 01 3E 1B C3 8B 01 47 3A 92 01 FE .>.2..>....G:... 02E° 6° 7¸ CÁ 4à 0± 4· 3Á 9² 0± FÅ 7Å 7¸ CÁ 4à 0± C³ `x.L.G:...~x.L.. 02F0 8B 01 47 3A 93 01 fE 00 78 CA 70 01 47 3E 00 32 ..G:....x.p.G>.2 0300 93 01 78 FE 39 FA 64 01 D6 07 D6 30 07 07 07 07 ..X.9.D....0.... 031° E¶ F° 3² 9´ 0± C¹ 4· 3Å 0° 2± 9² 0± 7· 2³ 7· 7¸ ..2...G>.!..w#wx 0320 FE 39 FA 81 01 D6 07 D6 30 21 94 01 46 80 C3 8B .9......0!..F... 0330 01 0e 05 5F CD 05 00 C9 00 00 00 00 00 00 00 00 ................ 0340 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0350 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0360 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Š- Thå codå foò ANYCODÅ no÷ resideó iî thå MORPATº areá previouslù occupieä bù alì thoså 00's. Thå lasô modificatioî insidå WS.COÍ ió tï alteò thå printeò driveò tï jumð tï ouò sub-routinå ratheò thaî simplù senä eacè  characteò � directlù  tï thå primarù lisô device®  Wå dï thió bù overwritinç thå assemblù languagå startinç aô thå addresó correspondinç tï youò � versioî oæ WS.COM. Version 2.26 Version 3.0 Version 3.30 -a71d -a71d -a71c 071D call 2de 071D call 2de 071C call 2bb 0720 jmp 723 0720 jmp 723 071f jmp 722 0723 0723 0722  - - - To close out, type: -G0 or -^C Then type A>savå XØ WS.COÍ (Wherå XØ ió 6³ foò versioî 2.26¬ 6² foò versioî 3.° anä 6¹ foò versioî 3.30) That'ó it¡ Yoõ maù no÷ eraså ANYCODE.HEØ anä DDT.COÍ froí thå disë containinç thå WS.COÍ yoõ jusô modified® (Singlå densitù user'ó � shoulä PIÐ WSMSGS.OVR¬ WSOVLY1.OVÒ anä MAILMRGE.OVÒ (MRGEPRIN.OVR© bacë ontï thå disë containinç thå modifieä WS.COM. Belo÷  ió á tesô filå foò EPSOÎ printers®  Iæ yoõ havå á differenô printeò type¬  consulô youò user'ó manuaì anä substitutå  similaò � workablå codes. ******************************************************************* `0FCompressed print`12 (All) `0EExpanded print`14 " ~45Emphasized~46 " ~34Italic print mode~35 (MX w/Graftrax ,FX, RX only) ~2D`01Continuous underline~2D`00 " ~53`01Sub~48~54`01script " ~53`00Super~48~54`01script " ******************************************************************* Doug Hurst Hi-Desert Osborne Group (HOGS) 6808 Estrella Ave. 29 Palms, CA 92277 (619) 367-1090 (evenings) ¡ Yoõ maù no÷ eraså ANYCODE.HEØ anä DDT.COÍ froí thå disë containinç thå WS.COÍ yoõ jusô modified® (Singlå densitù user'ó � shoulä PIÐ WSMSGS.OVR¬ WSOVLY1.OVÒ anä MAILMRGE.OVÒ (MRGEPRIN.OVR© bacë ontï thå disë containinç thå modifieä WS.COM. Belo÷  ió á tesô filå foò EPSOÎ printers®  Iæ yoõ havå á differenô printeò type¬  consulô youò user'ó manuaì anä substitutå  similaò � workablå codes. ******************************************************************* `0FCompressed print`12 (All) `0EExpanded print`14 " ~45Emphasized~46 " ~34Italic print mode~35 (MX w/Graftrax ,FX, RX only) ~2D`01Continuous underline~2D`00 " ~53`01Sub~48~54`01script " ~53`00Super~48~54`01sc ; ANYCODE.ASM - A program to allow printer codes to be ; transmitted to EPSON or other dot matrix ; printer from within WordStar text. ; ; Author: D. M. Hurst ; Date: March 3, 1984 ; ORG 02BBh ;WS 2.26/3.0 (02DEh) WS 3.3 (02BBh) ; mysub: cpi '`' ;is it a code character? ;you may sub " ` " if you use the ;" ` " often in your text jnz ncheck ;no, so next check sta lead ;yes, so store temporarily mvi a,1 ;get a 1 in accumulator sta fl ;set fl flag ret ;get another character ;without printing ncheck: cpi '~' ;is it other code character? jnz hcheck ;no, so check if part of ;code sequence sta lead ;yes so store temporarily mvi a,1 ;get a 1 in accumulator sta fl ;set fl flag mvi a,1bh ;~ means escape required so jmp pout ;send it. hcheck: mov b,a ;set input char aside lda lead ;get contents of lead cpi '`' ;are we in a code seq? mov a,b ;char back in accumulator jz flchk ;yes, so check if flag set mov b,a ;no, so char back to b lda lead ;check lead again cpi '~' ;are we in a code seq? mov a,b ;char back in accumulator jz flchk ;yes, so check if flag set jmp pout ;no, so print char normally flchk: mov b,a ;set char aside again lda fl ;get fl flag cpi 00h ;1 if set set mov a,b ;char back in accumulator jz addsnd ;not set, so last char in seq mov b,a ;yes, so set char aside again mvi a,00h ;no, so place 00h in accumulator sta fl ;and lower the flag mov a,b ;char back in accumulator cpi 39h ;is code char a letter? jm nolet1 ;no, so never mind sui 07h ;yes, so make it a number nolet1: sui 30h ;now down it form ASCII rlc ;first char in code so rlc ;move 4 low bits to high rlc rlc ani 0f0h ;0 4 lower bits sta first ;store it ret ;go get second char code addsnd: mov b,a ;set 2nd code char aside mvi a,00 ;0 the accumulator lxi h,lead ;get lead addr pointer in hl mov m,a ;0 out the lead inx h ;up the hl mov m,a ;also 0 the flag mov a,b ;get char back cpi 39h ;was 2nd code char a letter? jm nolet2 ;so so skip it sui 07h ;yes so make it a number nolet2: sui 30h ;now down either from ASCII lxi h,first ;point to first code char addr mov b,m ;move actual char to b add b ;add a to b (result in a) pout: mvi c,5 ;print full code char mov e,a call 5 ret ;back for next real char ; lead ds 1 ;space for lead code fl ds 1 ;flag space first ds 1 ;store first code while ;waiting for 2nd to pro- ;cess. end es, so make it a number nolet1: sui 30h ;now down it form ASCII rlc ;first char in code so rlc ;move 4 low bits to high rlc rlc ani 0f0h ;0 4 lower bits sta first ;store it ret ;go get second char code addsnd: mov b,a ;set 2nd code char aside mvi a,00 ;0 the accumulator lxi h,lead ;get lead addr pointer in hl mov m,a ;0 out the lead inx h ;up the hl mo*%ù!€F>>#¾Êm !€F>##¾Ê&ÂÃÓ+~Ö0úÓþ úBÖþ úÓþòÓå!g¶wáÂ* Êxå!g~!fw!"gá#####Ã(+~2f##~2g>2h\Í<ÊÊ>2}2~2!\Í·ÂÜ!€€:f¾Â³:gw:f#¨"\Í*}#"}Ô%ÍíÃóÍíÃ\ÍKÍíà ÍÉPARAMETERS NOT SPECIFIED OR IMPROPERLY SPECIFIED $NO FILE WITH THAT NAME FOUND ON DISK $FILE SUCCESSFULLY ALTERED $åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå CHGCHAR.COM-CHANGE CHARACTER PROGRAM ------------------------------------ written by Al de la Torre vice-pres. gold coast osborne users group (GCOG) nov 1983 I wrote this assembly language program originally to simplify data transfer between Supercalc 2 and Dbase II. The particular problem I encountered was the fact that Dbase II delimited character strings with single quotes. The SDI (super data interchange) program which comes with Supercalc 2 had no problem converting the data. The problem arose as a result of the single quote delimiters, which when used as the first character of a cell entry in Supercalc, repeated the data following it in every blank cell to the right. The obvious solution to this problem was to use the "find and replace" option in wordstar. This worked but necessitated swapping disks and going through the interminable wordstar "boot". Not to mention the problems encountered when the remaining available disk space is less than the size of the file being modified. I recommend placing the CHGCHAR.COM file on the Supercalc file disk. Its operation is outlined as follows: COMMAND LINE SYNTAX: -------------------- ASCII CHARACTERS: To use the program from the CP/M prompt type: CHGCHAR d:filename.typ A>B where d:filename.typ is any valid CP/M file name, A is the ascii letter you wish changed, > instucts the program to look for ascii characters, and B is the letter which will replace all occurences of A throughout the file. NOTE: there should be NO spaces between the parameters (A and B) and the > NON-ASCII CHARACTERS: I included the capability to find and replace any non-ascii character simply by specifying the two digit hexadecimal equivalent of the character using the following command line syntax: CHGCHAR d:filename.type 00#ff where everthing is the same as above with the exception of the exchange parameters specified, # instructs the program to look for hexadecimal characters, 00 can be any hex character in the range 00 to ff, and ff will be the replacement character (which will replace all occurences of the first parameter 00) it also can be any characterin the range 00 to ff NOTE: there should be NO spaces between the parameters and the # THIS PROGRAM DOES NOT PRODUCE A BACKUP FILE OF THE ORIGINAL!!!! This allows you to modify files of any size without worrying about whether or not there is enough disk space. SAMPLE COMMAND LINES: CHGCHAR SAMPLE.TXT '>" will change all single quotes ' to double quotes " CHGCHAR B:SAMPLE.TXT 0D#8D will change all "hard" carriage returns to "soft" carriage returns. This will allow you to reformat files with the ^B option This program uses only standard CP/M function calls and will therefore work   with both CP/M and CP/M+. (Works on Osborne 1 and Executive) The accompanying file chgchar.asm is the assembly language source code for this program. I heavily commented it to assist other begining assembly programmers like myself. If some area of the code needs clarification I'll try to explain it if you wish. H (305) 653-2871 W (305) 374-2730 ADDITIONAL NOTES: ----------------- Care must be taken when modifying ascii characters in a wordstar file created in "D" document mode. If a soft space has been inserted next to a letter, what has actually happened is that the high bit of that letter has been turned on or "set". For instance the normal hexadecimal representation of the letter A is 41. However if a soft space has been inserted the "A" will still appear normal when viewed with wordstar but will actually be represented by C1 hexadecimal. Therefore if you use the command line syntax CHGCHAR SAMPLE.TXT A>S these "soft space A's" will not be changed. There are two ways around this problem. First is to use the hexadecimal command mode and invoke the chgchar program twice the first time to change all normal letters, in this case: CHGCHAR SAMPLE.TXT 41#53. And the second time to change all high bit occurences of the letter, in this case: CHGCHAR SAMPLE.TXT C1#53. The second way around this problem is to strip every high bit using the Z option and piping the file to itself, then using the normal command line syntax. It should be noted that upper to lower case conversion of a particular character is not possible using the ascii command line syntax. The reason for this is that since the parameters are given from the CP/M command line; the CCP changes all characters to upper case before putting them where the chgchar program can use them. xadecimal. Therefore if you use the command line syntax CHGCHAR SAMPLE.TXT A>S these "soft space A's" will not be changed. TvÿÞBCHGCHAR.ASMO öÿ ßÿšÿ‹ÿ�ÿ–ÿòÿ�ÿõÿ‘ÿžÿÄÿœÿŒÿ›ÿ’ÿ—ÿ“ÿ�ÿ™ÿ !Šÿ�ÿ"#‡ÿ%$&˜ÿ'Óÿ(Ïÿ*)+‰ÿ-,/.0Žÿ•ÿ12Åÿ43”ÿ5678ºÿ;9…ÿ:†ÿÎÿ<Ýÿ>ˆÿÌÿ=Øÿ?¶ÿÍÿB@¾ÿA¬ÿ«ÿÞÿ­ÿDCFE±ÿ°ÿ¹ÿ³ÿG¼ÿÆÿÔÿ¯ÿÇÿH»ÿIJoÿÊÿÁÿ·ÿÖÿKªÿ×ÿÛÿËÿÜÿ²ÿMÐÿNL¦ÿÃÿÒÿÉÿÈÿüÿåÿ¨ÿÿþ´ÿûÿ¸ÿíÝvf�Ú•$îœY 6Í;øwy«‘?•ìÕÍ GVè¡N%›w•ä�5{z 9òßm£ÝÛ¡ï“sÉT²yWI~·½ÛN2ˆäìÜ»M�‰9t�ÆÏœ£]I¬�Ÿó��ØéÝöný –óTwñ<±[ý+|šëÐåÝú××Åyª»X˜Ø­þ>Íùºº¼‹Åœ§º‹Ú»añ‡É%|î݃aIpžê.vFìv0,™ «û.çŽÁyª»¸‰Ý8wœ «;8ֿ§9˜Þ÷É8½û�\½óTw±'vûG®é�滕þ�½óT÷ù"±[¥?d˜h¾Ë¹c8užê>�<±çŽòTÏ%°épÖÏqÞ=É áÔyªû¼öÄn'$'䩞K`Óᬟ㼫¶VöÎSÝç N즶V† yªçØtz ù.玼¢óTwáóÄnœ;ï¿Îú9¾{’AxÅÉSÝ… »�d�Þ+~5œõs|·¯˜óT·ö•Ø­šSÿþt0ú«Öì9Cx7ªí<Õ}b‘Ø-f¿u*Õž#gïÆ¤ÎSÝž'v‹ISr*Ù¼«$¿K{ç©îâ&v£°rúÌ8•lÞU’ß­ì<Õ]ŒÄnu3ÃîæpŠÎk*Ù¼«$¿Ë+rVç©î¾b�wêíÆ{ů†³~Žƒ�“|·½ÛÞõç®Ï‹Äï¶wM �.8±gH™ »jÍñaIò»Ž•Mìö®ÃA¨µÃy{·½Ûº)³C˜cóV)ÉaúÏSÉæ]%y­d¯n¾kŠ‚IùÄ"±ýu ü5¿Ÿú•Ú+¦÷}ò»Vo¬¬ìV¿R{Å‘ th®®�w­ðà]î”Änô­é?OïöÀAh©ß5,ÔÄn°*§Ê%C軮갲ۻî@p®d³ÝÞu¬lÌn1+§Ê%S¿¾ä]w,÷ÀA¨Ýê_KÏ tâ_ùn{·uS†$ 1+¨MçØ¼UJr˜þóT²yWIžD+Ù«›ïš¢`R>±HìFÝÍï§~¥öŠƒé}Ÿü®ÕÇ++»Õ¯Ô^qdš«+ä]+_Œvƒ0 SÀtö®;”wŒòív.CyÂ�aöDè‚ ŽÅ‘?�áôn[_&B¤Yf‡ 04E’Gþ�Dßu=ÀÅMìa@¦ SÜä]w(¯lVv;—á]×|¾Hìa@¦€)öä]w^ÿجìv.ûíÝ£üÒw}è�˜Ø-l|ÎñaIòÈ’èDè‚„wMQ0)Ë·[7evŒœ!Ìïç¬ü³slÞ*%ù]ÞVv;ûùì¬<9º 3ïšiÕ4L«¦aZ5 Óêô24{ä ïZ}¼UyÛíÐeH¢slà�5gåŸ}×Ç?LìÆäsÎñaIò»Ž•�Ùí]w,„q&‰Ú­›2+Q™]�w+»Ú­2ÇžßO„.Hx׎Änë—ßî=ä›·JIkÐJöêæ°¬w}è�˜Ø-l|ÎñaIòÈ’èDè‚„wMQ0)Ë·[¢•ìÕÍ9+ÿììçlÏ_�}×êã½ËÊn`Rîù+»½kõñVåm·wMQ0)‰Ý*ÍÍsVþÙÁvÕùƒ�üßu 4Z¾ÝÞõñ»qùœs|X’ü®a¡C4 ,tˆ¦�…Ñ4°Ð!š:d¦–Œü YÿŠs|à‰Ð ïºCò9ßmï¶ ŸsŽÍ[¥$‡ :Æ_Xùn®ds黎5±[H™ãÃ’ä‘?=p�©dó®’ü®ÕÇ{—•ݺ)2°f¿ë Û=e· Ÿs@Þ5,ÔÄn!eŽK’Gþ¬De*Ù¼«$¿kX¨‰ÝÞµúxï²²[7e@Öl¿ë ÛòíäsÈØï¶wãy× Þåb‘Ø !ùO¢’K¦ÿ<ÿÈ5=М^_Uà¯wd»¯Xçç G»½k…×ò?rõvûG®é�滦(8–ûŠÙí]×Mé‹?Øí]Ãbo»U’UkäOÈè§šsp†\ò®;¼~v{× Þåb‘Ø-¤ ï¿Îú9ÎæÜ#Šï:Èv_±Î;uŠv{×A¶ûŠuÞ ùh·wd»¯Xç�´�v{·½»ÎZú®\Ëœ;òŠnœ;gýß5EÁ±ÜWÌnïºnJ�Åìön{·U’UkúϳER2ò‡sÇ9v�Éß¿ëÏÛÛnÅâÀš=ÐOÐkÍz�çŽïºc!8þ•v{·½ÛŽÍ[¥$O¢•ìÕÍwMQ0)Gµívè2LJ%Ék}× ÆÊç Ÿívè2õëK’Ö`ïšÆíž¿²Û¡ËôÀAæØ¼UJòÀšý.ýÿ(}×UVv«_›sN‚�ÁÎIÎï§šïºc!x%*v{×4nË·çAwÍ9 B&dý+αy«”äw­>Þª¼íö®iÜîù+»qÒ¿ãì9 B¦2Çæ­R’ß]‰J©ß5,ÔÄnÝ”Y‰Ê`ç$ßu¬lÌn1+§Ê%S¿¾$ù]w,Óÿ»Å?ú ÿÊwÛ»-Èçýˆ[2gýߵƒkù$ƒðŠn'$‡³~Ž#"­y×Çr_1»Í»®›Rcñ»½kJh4¯ÈYíÖMÞ+~5œõsìœä¼kX¨‰Ý`UN•Kä]B£yEÎj·C—lW­wÝ¡¯D…³ÚíÝön[z 9AÇøë+ß]¿‡R¿kŠ‚cyõ*C×mýé�æ¨ aws`MÌw]7¥>–Øí`X2 ïºC.»a»j�ü©ÇÕ»íݶþ›·JIž cüu�•ï®lV¥~×Çò±Y©Ðu£ÇQÂîæÈŸƒaÉÀš˜ïºnJ}0,±ÛÁ°d@Þu‡:\$vÃvÕùS�3ªwÛ»ñ¯,õ»Vxp-WúCön•þ�ÓÍwMQp,÷³Û»®›Rcñ»½kŠ‚c9è5ƒÝèßqT†°»9;FÎÖÄ|×uSêƒa‰Ý†%ò®;Ôá"±¶«ÖÈŸzœQ½ÛÞ=–”ú]+<¸–†%Áí`X2AVwz}U�¿ÞuÝ”‹?Øí]sÊ»íÝc³R¡[:s‰´iÖ†,®F\Íb�£áÜ3 !)„[ò Ö<…�=A3âp5#-Èh8÷ÌBH á–<È•xwõ*C·Ô1—@„x�BŠ;%]Hc�£±@m‘6dq b•<ˆMÉ…4œá WâÝ × ¥žˆ¹’BHqGgž‰«A�"-ÈhCªW3nɃ\‰w{þªÔ1É»òK= s‘¼ÛÞu®XRÚáü »½k…×ò?rõvûG®é�滦(8–ûŠÙí]×Mé‹?Øí]Ãbo»U’UkäOÈè§šsp†\ò®;¼~v{× Þåb‘Ø-¤ ï¿Îú9ÎæÜ#Šï:Èv_±Î;uŠv{×A¶ûŠuÞ ùh·wd»¯Xç�´�v{·½»ÎZú®\Ëœ;òŠnœ;gýß5EÁ±ÜWÌnïºnJ�Åìön{·U’UkúϳER2ò‡sÇ9v�Éß¿ëÏÛÛnÅâÀš=ÐOÐkÍz�çŽïºc!8þ•v{·½ÛŽÍ[¥$O¢•ìÕÍwMQ0)Gµívè2LJ%Ék}× ÆÊç Ÿívè2õëK’Ö`ïšÆíž¿²Û¡ËôÀAæØ¼UJòÀšý.ýÿ(}×UVv«_›sN‚�ÁÎIÎï§šïºc!x%*v{×4nË·çAwÍ9 B&dý+αy«”äw­>Þª¼íö®iÜîù+»qÒ¿ãì9 B¦2Çæ­R’ß]‰J©ß5,ÔÄnÝ”Y‰Ê`ç$ßu¬lÌn1+§Ê%S¿¾$ù]w,Óÿ»Å?ú ÿÊwÛ»-Èçýˆ[2gýߵƒkù$ƒðŠn'$‡³~Ž#"­y×Çr_1»Í»®›Rcñ»½kJh4¯ÈYíÖMÞ+~5œõsìœä¼kX¨‰Ý`UN•Kä]B£yEÎj·C—lW­wÝ¡¯D…³ÚíÝön[z 9AÇøë+ß]¿‡R¿kŠ‚cyõ*C×mýé�æ¨ aws`MÌw]7¥>–Øí`X2 ïºC.»a»j�ü©ÇÕ»íݶþ›·JIž cüu�•ï®lV¥~×Çò±Y©Ðu£ÇQÂîæÈŸƒaÉÀš˜ïºnJ}0,±ÛÁ°d@Þu‡:\$vÃvÕùS�3ªwÛ»ñ¯,õ»Vxp-WúCön•þ�ÓÍwMQp,÷³Û»®›Rcñ»½kŠ‚c9è5ƒÝèßqT†°»9;FÎÖÄ|×uSêƒa‰Ý†%ò®;Ôá"±¶«ÖÈŸzœQ½ÛÞ=–”ú]+<¸–†%Áí`X2AVwz}U�¿ÞuÝ”‹?Øí]sÊ»íÝc³R¡[:s‰´iÖ†,®F\Íb�£áÜ3 !)„[ò Ö<…�=A3âp5#-Èh8÷ÌBH á–<È•xwõ*C·Ô1—@„x�BŠ;%]Hc�£±@m‘6dq b•<ˆMÉ…4œá WâÝ × ¥žˆ¹’BHqGgž‰«A�"-ÈhCªW3nɃ\‰w{þªÔ1É»òK=ÃOkidata MicrolineþX‘  þ$Êu @!Ü *ÊÜ Í17.1 CPI, at 6 LPIÍÜæ>UÌ Í �·Ì=¯2ãÍã Í�ÃU ~B‘ 10 CPIp#z³Âà 17!ªÍ9:l2¾:]’Êß!¶Ͱ ¤Ͱ ÊBU17.1 CPI, at 8 LPI`2š!vÍn!›8�§Ê5 Ͱ›ÍŽ›Í“X‘ Teeny Weeny80Ä=Ãä þÌ=hL%9 1 þ$Êu @!Ü„‘  12 CPI at 8 LPIÙ ÍÜæ>UÌ Í 8Ì=¯2ãÍã Í�ÃU ~Ž 0 CPIp#z³Âà 17!ªÍ9:l2¾:]’Êß!¶Ͱ ¤Ͱ ÊBP6.7 CPI, 8 LPIÀÍ`2š!vÍn!›0�§Ê5 Ͱ›ÍŽ›Í“XŽ 1þÍ DBL Version 4.00, setup for a !Íø Í printer !åãã-Â>%Â>Ñ:mþPÂb>2` !nͬ Úb"\ Í+ 1þ!"V "X "Z !Æ 61#6 ÍÆ!^ ÍÄ:]þ!Ú�:T ·>2T  ÍÔ ¯2|\Í!Õ <Ê;:T þ>2T !@Ê2Í+ !@~·ÊðxÆ12ÚÍ 0> Print using åÍø á@ ÂÌÍ YOUR CHOICE: ÍÇ þ¯Ã%þ1Ú þ6Ò =æo&))))))@~·ÊDå> ÍÚ Íø Í$ á  ~# ÂM*\ |µÂÄÍ Start print on page: Í´ Ê�"\ :` þÊÍ Last page to print: Í´ ʾ##"^ ë*\ #z¼ÚqÂÆ{½Úq:` þÊÍ$ !ã ÅÕåÍ$ Íø åÍ (Default = ÕÍx Í ): Ív ÑÚŒÊ:` þÊáãáÑÁ ÂÑÍ+ Í Printing: !\Í— Í Start Page: *\ #ÍŸ Í Finish Page: *^ ÍŸ Í Page Format: !ã Íø ÅÕåÍx Í$ áÑÁ ÂxÍ Press Return when printer is ready ÍÇ þÊÄþ ·Í! Í5 Stop/ResumeÍ Press Ctl-Q to Exit to System *\ |µÌ� 1þÍ! ¯!~#–#–#–æÊ_2c G†ú_2e 7?Þ ú_2g xæÞ++†ú_2f ! :–#–==2d Íç:d 2a G*V "X Íhþ Ò_þʇþ Êzþ Â_Â_*V ~þ ‡#"V : ·Ê–oÍU -Â�*V "Z *X "V ~þÊâ:OÍ> ÍÍÚâ*V "X *Z "V ~þÊÜþ ÊÜ:e O:b ‘/OÍ> ÍÍÍJ ‡ÍJ :a <Ââ:\ 2U :f OÍj :g OÍj ÍU :U ·!#Ì– *X ~þ Â#"X *V ~þ Â'#"V *^ |µÊ8*Z ~þÂR!Ç Íø Íó ÃeÍL Mode out of rangeÍ! ÃÆÍL Page formatÃÆÍL Page number!"\ "^ Ã]ááÑÁ:` þÊÍL Number out of range (0 <= N <= 255)ÃÑ#w:b <2b É!€¯w:c O¯2b Íhþ ÚÍÂÂÚÍh·þÊþ ÊXþ Êþ Âèõ!€~2b W¯wºÊ#~þ Ô\ ÂñÉþÊþ Ê8þ Êþ Êþ ÊXÃÚÕ:b æW>’W> ÍÂÊQÂC¯<ÑÊèÃÚÍ^ÃÒ:b !€¾ØwÉÅÕåÍ´ ·Ê¥þÊí æþÂ¥Í5 ResumeÍ$ ÍÇ þÊí æþ‹Í5 StopÍ! *V Í8 ÌÔ*V ~þÊÀ#þ ÊÀ"V áÑÁÉ6 ÈT]~# ÂËÉ*X .€ÍËÍ8 ÂÜÕÍ\Íá€·Ê 6# ÂüÍ8 Âüà ~æw#  Í8 ëÂç*X |’Ob"X :[ ‘2[ :W ‘2W É:=¼ÉÅ> Í\ Á Â> ÉÍU :a =2a É> Í\ > ÉÅÕå_ÍáÑÁÉ:U ·Âz Í> !¼ Í– ͦ *^ +"^ *\ +"\ +|µÀ¯2\ !~#þÈO~Í\ # œ É!Æ 4~þ:À60+~þAÐþ © 61Éÿ ¯}“o|šgÒ¿ y·Â× °> ÊÚ ¯Æ0GÅÕå_ÍÍ´ þÌï áÑÁÉÍ´ þÂï É~#þÈþ Ê ÍÚ Ãø Å> ÍÚ Â ÁÃø Í$ ãÍø ãÉÍ$ Í É Í! Â- ÉÍ Press "P" to ãÍø ãÍ Print Press [Escape] to Exit to MenuÉo&ÅÕ'ͽ èͽ dͽ  ͽ ÑÁ}Æ0ÃÚ |µÂ{ Í (Default) ÉÿÍþÊí þÊá ·ÉÅÕåÍ´ ÊÊ 2` õ_þ ÔñáÑÁÉ1þÍ- Íó ÃÍó Ãb!"\ :\ ·À!#Í– !0Í– >É2\ É!€å@ÍÄ?áÍÇ þ ÒC þ ÈþÈþ yþ?Ê +6Í  à w#6  ÉÍ! ãÍø ãÍ  - ERROR! ... Please Retry ÉÍ !€åÍ’ ëÑ|þ7ÀµÀæà>É~þ0Øþ:Ðåbk)))æ_ëá#Ã’ ¯/Í| ÷ Ív Èõ}æÂÁ ++}æþoñÉ~#æþaØþ{Ðæ_ÉÍ File to print (D:FILENAME.TYP): !\åh  ÍËáå6#6  ÍÆÍÄÍ :` þÂ2 !h ÑÕ ÍËáåÍ— Ã� !�~+þ:ÂD ~æãwã##ÑÕÍÇ þ!Ú� þ.Êi  ÂI ÍÇ þ!Ú� þ.Â\ ãë! ëãÍÇ þ!Ú�  Âs á#~þ!ÐåÍL Filenameà ~·Ê¦ Æ@ÍÚ >:ÍÚ  #~þ ÄÚ yþ>.ÌÚ Â¨ É Page 1 finished No File Page Height Page Width  Left Margin Right Margin Center Gap Top Margin Bottom Margin  ÍÚ Ãø Å> ÍÚ Â ÁÃø Í$ ãÍø ãÉÍ$ Í É Í! Â- ÉÍ Press "P" to ãÍø ãÍ Print Press [Escape] to Exit to MenuÉo&ÅÕ'ͽ èͽ dͽ  ͽ ÑÁ}Æ0ÃÚ |µÂ{ Í (Default) ÉÿÍþÊí þÊá ·ÉÅÕåÍ´ ÊÊ 2` õ_þ ÔñáÑÁÉ1þÍ- Íó ÃÍó Ãb!"\ :\ ·À!#Í– !0Í– >É2\ É!€å@ÍÄ?áÍÇ þ ÒC þ ÈþÈþ yþ?Ê +6Í  à w#6  ÉÍ! ãÍø ãÍ  - ERROR! ... Please Retry ÉÍ !€åÍ’ ëÑ|þ7ÀµÀæà>É~þ0Øþ:Ðåbk)))æ_ëá#Ã’ ¯/Í| ÷ Ív Èõ}æÂÁ ++}æþoñÉ~#æþaØþ{Ðæ_ÉÍ File to print (D:FILENAME.TYP): !\åh  ÍËáå6#6  ÍÆÍÄÍ :` þÂ2 !h ÑÕ ÍËáåÍ— Ã� !�~+þ:ÂD ~æãwã##ÑÕÍÇ þ!Ú� þ.Êi  ÂI ÍÇ þ!Ú� þ.Â\ ãë! ëãÍÇ þ!Ú�  Âs á#~þ!ÐåÍL Filenameà ~·Ê¦ Æ@ÍÚ >:ÍÚ  #~þ ÄÚ yþ>.ÌÚ Â¨ É Page 1 finished No File Page Height Page Width   THIS PROGRAM PRINTS TEXT IN COLUMN FORM WITH COMPLETE FLEXIBILITY IN ASSIGNING COLUMN AND PRINT SIZE. --------------------- N.T.M PRINTS TEXT IN COLUMN FORM WITH COMPLETE FLEXIBILITY IN ASSIGNING COLUMN AND PRINT SIZE. ----------DBL $$$ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååÃâ Í«Copyright (C) 1985 BORLAND Inc¡BZenithminal selectedPY ELMKqp~·7È#õå~Íèáñ=ÈóÍ ÉoåͦÉþ€ÜkÔ„æîå!îå!è"áãõÅÕ~#·(åÍèáôÑÁñãÉ}´È:$‡‡‡ããããÅÒÁ= ô+èÍÐØ*ÎßõÅÕå!¨Í5!¢ÍÐ*ºÔáÑÁñÉõÅÕå!´éõÅÕå!®àõ:à·(ÅÕå¯2à!ÈÍ5áÑÁñÉõ:àþÿ(öÅÕå>ÿ2à!ÂãõÅÕå!¼ÚõÅÕååð!‹í°Ñ:žO:œ‚ÕÍÜÑ:ŸO:�ƒÍÜ!ðÍÐ* ÍáÑÁñÉ!ð ë!›45(É! +/ –0ü†õyþ0(ñíÉ d!kÃ5!{Ã5Í_æÍ_o&Éô  áÁå:Ý·(ÕÅÍ |µ(Íáþ ÍáþÊÔ ÁÑ*é"Òx2Ýy·( >Ã28!û"9!¥ í°!½¸ í°¯og2Ð"Ô"Ö>~2Ñ2àÉÃà Ã9Ã/Ã4Ã*Ã9à Á‚CÄÅÁÅÕåÝåýåõo&åͦñýáÝááÑÁÉÅÕåÝåýåÍ£}ëÿ í[Òþ (ú!eÍ{ͦþA8þQ0Gþ: xÖ@¯!\w# (Í‚ þ?(þ*( þ.( ÍwÍ^þ. Í^!h6#ûÉ (þ?( þ*( Í‚( w#éÉ>?> w#üÉͦþ 8 åÅ!˜í±ÁáÉ¿É .,;:=?*[]<>{}þaØþ{ÐÖ É|Í´}õͽñæÆ�'Î@'Ãɯ7Ë|À|·}È>ÿÉ2ØÅͯÁ*·íBÚ¨ ëÑùü "Ưog"Î2Ü>Ã2Ù!Þ "Úë"Ìéå*Æ·íB"Æí[Ä·íRëáÚuí°É*Æí°"ÆÙÉ^#V#Õ^#V#N#FáÉÝáëO/o&ÿ9ùëí°ÝéÑO/o&ÿ9ùëí°éÝáë!àÿ9ùëÅ(¯üí°Á> �‘(G¯üÝéÝá!àÿ9ù ¯w#üÝéÝáEͺ¶wÝéÝáÑ}“8÷�Ã' ·íR·íB0 É>‘Ã' ·íRëêqðøÉÕë·íRëáë·íR!È+ÉÍß õͰ ð·íR!À+ÉÍß õͰ ðÍr!Ð+ÉÍß õͰ ðÍr!ÈØ+ÉÍß ôͰ ïÍr!ÈØ#ÉÍß ôͰ ïÍr!Ø+ÉÍß õͰ ðT]KBë!z·> S>)ë)ë0 = öÉ|µÊ |ªõÍ€ëÍ€ëDM¯go>íjíB0 7?ËË= ðëñðHåÍ’Ë<ËÑëÍëËzÈ5ÍaÈ)ýÉÍaÈË<ËúÉëz· {þ0G·É¯goÉë|ª|ú~ºÀ}»ÉÉË|È|/g}/o#É}æo&ÉíKÊí[ÈÅÕxAJSËËËËáëáíJDM!éb"Èë!6íJ"ÊDMÉ'ÍâèÍâdÍâ Íâ} ¯<íR0û= ÈÆ0ÝwÝ#ÉÝ~Ö$O! Ý#Ý~ͦÖ08)þ 8 !Öþ 8þ0T])Ø)Ø T]Ø)Ø_ØËy·È|‡ÉÝááå}&#9N�8wë!DíB9ùëåí°ëá+Oí¸ë#ùÝé>Ã) ÝáÍÈWáÍÝ _áå}“8(º8J`9{‚T]=o`9yí¸ë ¯Ã) Í Ð>Ã' Í� õͬÍ— íÙ}·Ù>Ê' Íõ ßÙËxÙˆ Ù}·ÙÈÙÅÕåÙ}· Ù˸TÅËø¯ÙËø}Ù•(0íD=ÙÍz ,= ù(Ùñæ€ Í’ 0%Í{ ·, 7 ÍÆ ?õ(8Ùͬ Ëx ͆ - öÍr ñ8˸·ÙáÑÁÙÉÙËxÙ Í� Í Ø,-Èxî€GÉÙ}·ÙÊr }·ÈÙ…ÙÍM ÅÕåÝ9Ír Ù.Ù>Ý#ÝnË0Í’ Í{ = ñÙ-Ù åÝnûËx ͇ ,-(-ñññ·ñÙÁáÙÝá˸°G,-Ìr É}·ÈÙ•Ù?ÍM åååÝ9Ù.Ù>ÍÆ 8ͬ ?Ë= ÝuÝ+Ù-Ù(>͆ 0ßͬ ·á͆ 8ÍÆ ?áÑÁËx ͇ š, —7•8Æ€8Æ€8oÝãÙåÅxËøÙ¨æ€õËøÝåÝ!ÉáØ¯oGOW_gÉ·ËËËËËÉ·ËËËËËÉ|Ù„Ùg{Ù‹Ù_zÙŠÙWyÙ‰ÙOxÙˆÙGÉ|Ù”Ùg{Ù›Ù_zÙšÙWyÙ™ÙOxÙ˜ÙGÉxÙ¸ÙÀyÙ¹ÙÀzÙºÙÀ{Ù»ÙÀ|Ù¼ÙÉÙxÙ¨òé xÉËx(Íó È?É}Ù½ÙÀ·ÈÃÆ }Ö�Úr <þ(ÐÙÅÕåÍr 7Í{ = ùÙ|Ù¤Ùg{Ù£Ù_zÙ¢ÙWyÙ¡ÙOxÙ ÙGÃ{ ÙÅÕåÙͬÙÍý ÙÍ� ë}·ÈËx>Â' ͬ}Æ€Ë/Æ€oÖõÙÅÕåÍõ Í -ÅÕåÍ� }áÑÁÙáÑÁã¼ã0ãñÙÉÙÍŽ-Í� ÙÍŽ,Ù}þlØÅ˸Íß Á8 Íõ Í4 Í— Ëx(Í Ù-ÙÍß õ8Í� Ù-ÙÍß 8Ù,Í� }þl8;Ùª*ªª!ªÍ— ÝåÝ! >Í4ÝáͬÍ— Í— ÅÕåÙͬ--Ù-Í ÙáÑÁÙÍ� ,,ñ,-ÈØxî€GÉgª?+2×n¶*ï8t Ð Ðzˆˆˆˆ~«ªªªª,->Ê' ËxÂ' Ù͘Ù}.�•õÍõ Ù͆ÙÍ� ÅÕåÙ,Í ÙáÑÁÍõ ÝåÝ!Œ >Í4Ýá,ÙÍ¢-ÙÍ ñÅÕåo&0%ÍÙ,Í— ÙáÑÁÍ }þgÚr É}Š�؉}颋.:}Žã8Žc~I’$I~ÍÌÌÌL«ªªª*ÙÍ¢Ù·Ëxõ˸Íõ }þˆ0GÅÕå,ÍÐåË<Ë}áõÍ,-(-ÙñáÑÁõÍ� ÝåÝ!>ÍIÝáñ0 õÙ͘ÙÍ— ñ…o8 ñÈÙ͆Ãõ á>Ã' m.`1pF,þåt6|‰„!wS<ÿÃ.zÒ}[•|%¸FXc~üïýu€Ò÷r1}·ÈÝåÙ͆Ù¯Ëx(<˸õÍß 8ÙÍõ ñËÿõÙÏŽé!~JÙÍß 0Í.OÝ!Î>ÙÝÍsÙÍß 8 = ìÙ ÝÙÙÍnËøÍ ÅÕåÍsÍ— Ù͆Í ÙáÑÁÍõ ÝåÍ.ÝáÙÍnÍ ñ0 õÙÍŽ-Í� ñÝáËOÈËøÉçÏÌTöô¢0 jÁ‘ €µžŠoD€‚,:Í€jÁ‘ �€!¢ÚI}袋.º}Žã8Žc~I’$I’~ÍÌÌÌL«ªªªªÝ! >ÅÕåõͬÍ— ñÍIÙáÑÁ× õÙÍnõÙÅÕåÍnÍ ÙáÑÁÙÍ— ñ= éÙ͆à ÝÝnÝfÝ^ÝVÝNÝFÉ!�DLT\ÉI¢Ú!‚!É53ó!�úÉr1÷!€ÒÉÅÕåÙáÑÁÉÍ’!€> Ëx Ë#ËËË-= ðo˸ÉËxÙ͆(Ëø-Í ·Ë}(ËxËø>�½8(Íz ,óÍz `iÈÃ!É>’Ã' |µÊr Ë|Í€>�)=Ë|(úDMboÀ˸ÉÍÈë8þ8ÍÈÙËxÙ(’0¯þ 8> ÕÍ€ÑËx(>-ÍåË{(aËy(ÍãÍÙ ò�z·(>.Íå (Íã ÷ú±ÍÙ÷Ë{È>EÍå>+Ë|(|íDg>-Íå|/Ö 0ûÆ:ÝpÝ# ý~ý#· ý+>0ÝwÝ#Éýå,-  ý60ý#ø¯Ã}Å ˸}ÙÖ€oŸgMÍõ|þÙ <ýwíDÍ@}þ�0ͳý5Ëø>„•.(Íz Ë= øý~õ> xæÆ0ýwý#xæGÅÕåË%͇ Ë%͇ ëãÑãíZëáãíJDMáË%͇ = ÈñÁýáÉýåá_~6þ5Øúœ+~¨¥Ôh¶¿ÉìÅëx-ÐÍÎÂSÞùx9?ë+¨­ÅøÉ{Η@}·ÈËøÅÕ|Íz Íz „gãíZëáãíJDMá0Í{ ,7È}Æo˸ÉÍ?¾ #øyîO!@9ùi&ÝéÍ? ë¶¾ â#÷ÚÍ?¶w#ùëùÝéÍ?/¦w#øïÍ?¦w#ùãýáÝá!9ë! E9ýéÝá!!9~·(¯+Fͺ¦!"9ù!(#Ýé>¯2èýá*ÒÍâ¯á"âýå|· >"2ÐÉ:è·( Ͷ *âwÉÍò*â6 ë!\$í°É!æÅåí[Òþ (úͦ–( áÁã·É#ëÁÁþ:À~ÉCONÁTRMÁKBD‚LSTCAUXÄUSRÅ>¯2èÍi:зÀ*âË®~æÀÍ0:зÀ*â:è·€€(@q##pÉÍZ*â ë:è·( ÕÍÑñÅÍÁ<Àx2ÐÉ*â6#ûÉ"â~æÀËv( >ÍÆÍ Ë~È*âå ëÍá< >ÿ2Ð6Éã"äãå!Â"âáÉã"äã"âË~À>2ÐÉã"äã"âËvÀ>2ÐÉ>¯ã"äãå!Â"âË®õÍèñ·(ÍááÉ!Ñ~þ8>~O6~*Ò"ÔÍáwþ(6þ(2þ(-þ()þ(6þ (8þ 0þ Ù:Ý·(ÓÝ*äà yº(È~#ÍÉÀúý+Í (±ï(« 6Íá6 #6 #"ÖÉ*â:з y~Ëo pæ .##~·ò—åͺá(å.6á¯w4Æ._~þ =*â##55= *Ôí[Ö·íR8ÿÍê*Ô~#"Ô= Í£}== ͯ}͵}*âËî#w+É#~+É>Éå*â~æþ('Íkþ!0þ(Ë®ñ]ÅÕÍkÑÁþ!8Ë®ï¯áÉÝ!]Ý~·Èþ-ÀÝ#É8Ý~·È>2Ð7ÉåÍkË®áwÉ>¯OÅÍðÁÍ$ÈÅåÍ÷ÑÁÍ6Ø̃ës #rëÉÍðÍ$ÈÅåÍ£ÙáÁÍ6ØÙÌ� ÙÃÑåëÅÕÍkÑÁþ ( þ(Ë® êáqÉÍkþ(Ë®þ ( þ ïÍkþ Ë®É*âO:зÀ~æ ##å~Æ._qá4ð(þ(áÅå=ʦ==Ê©=ʬò*è:ê¾È4^qÉ*â##~·È6ͺÈ>ð2ÐÉ}ÃÆÁÑÅÝ*ÒË|(̓ëëË|( ̓Ý6-Ý#ÕÍÆáÍÈí[ÒÝåá·íRMë‘8( Gå> ÅÍÆÁ÷áAÈ~ÅåÍÆáÁ#óÁÑÙáÑÁÙÅÝ*ÒÕÍ'¾ÁÑÅÍÈËC!¡ ¿!¥¸TRUEFALSEÍÈ!9N#ÍYÑùÕÉá~#·( G~ÅåÍÆáÁ#õé> ÍÆ> ÃÆ   "âË~(ÕÍkÑ»(þ( þ!0 (Ë®è!É!É>¯2èíSæÍz:зÀÍ0:зÀ*â6Ð##ww#w$w#wÖÿ:è· å¯Í á##N#F*æ·íBÈ>�2ÐÉå¯w#w#í[æs#rá>à "â~æÀÈÍ®*â-¯w#wÔÿw##>Í Í®Ã�ã"äã"â~æÀÀ>2ÐÉ:зÀåÍZë·íRá0¯Í *â4À#4É>™2ÐÉ:зÀåÍZ·íR> *â4 #4(>áÍ Èá>ò2ÐÉ2éë*âËf(/˦:éËG(##~++· :éËO x· y·úCÅÕ!ͺÑÁ Q*â:éËG(Ëî##~Æ.Õ_ÑÖ.Íší âf<ò\=<Íš*â##æw ÅÕåÍ®áÑÁ Õ+Ñ4 #4x±Â ëÉ>™>ð2ÐÉõ:éËG(ëñÉ"âÍ®Èæ"*âËæËnÈË®*âåÅ0ëÍÁá ëÍ·ÉÁÑíSâÅåÍZÑ·íR8@*â N#F#s#rÍ, 0}æ)ëíjëS\*â##w+ N#Fë·íB ÈÕåÍ®Ñár+sÉ>‘2ÐÉÕÙáÙ!T]>)ëíjëÙ)Ù0 0= ïÉÍ]·íR!À#ÉÍ]ëÉ*â^#V#ÕN#F#^#VáÉ>¯2èͰ:зÀÍ0:зÀ*â6Àå ë#Íá-¯Nw#FwÖÿq#p#6€#w#w#wÉ"â~æÀÈÃ�>">!DM!ð"æÝáÑáÝåÅÍýÁ:зÀ*ðíBÈ:éþ!>™(>ð2ÐÉ>">!"æÝáÁÑáÝå2é"â~æÀʰ*æ¯w#wx±(9ÅÕÍ*â ë:éOÍÑÁ· Õ*â-4 #4Ñ!€ë*æ4 #4 Ã*â-N#FÚÿq#püÿV+^ë·íBÐëq#pÉÁÑíSâÅåÍZÑ·íRÚ&*â s#r$ s#rÉÍLÀ ëÍ<À?ýá*ÒÍâ¯áýåÍLÀåÍòáåë!\ í°á åëÍÑ<( !\$í°É>2ÐÉ>¯2èÍLÀ:Ø·>!(ë*â \$í°\Í<(Ï!3°í°:è· í[1ðÕÍ\ÍÑ!€ë·(é7"â~æÈ> 2ÐÉ"æíSèëá"âNs#Frë·íB(Zë#\:Ü í°¯üå\ÍÑ<(?*æ"}íKèÅÕÍ\!ÍÑÁ· !*}#"}!€ë x± Û\Í*â éÝ*â>ðÃ) ÍÈþÐ2ÜÉ"ðëáã"ò{æü_!Þ"øÝ*ÞÝnÝf}´(HíR0ÝnÝfåÝ"øÝáã Ý^ÝVÝåMDÝnÝfÝåÝÝuÝtÝqÝpÝåÑ*øs#rÑ*òs#rÉÝåá"Ä*ð ÝåÁ ÚuíKÆíB!Ú0>ÿÃ' ëáã~#fo{æü_ë"ð*ÞåÝá·íR0RÝnÝfå·íR0ÝáðáÕýáíKðýqýpýuýtÝsÝrÝåáÝNÝFÍ( Ý^ÝVÕÝáÝåáÝNÝFÝ^ÝV*ÞíSÞÕÝáÝuÝtíKðÝqÝpë ·íRÀÕýá*Ä·íR(ý~Ýwý~Ýwýnýf ÝuÝt¯ÉÝåá"Ä6#ûÉÍK*ôÉÍK*öÉ!"ô"öÝ*ÞÝNÝFy°(*ô "ô*ö·íB0íCöÝnÝfåÝáØ*Æûÿ í[Ä·íRØë*ô"ô*ö·íRÐíSöÉí[Äs#rÉ^#Vë"Ä"Þ6#ûÉ>¯O"è¯w2Ðx2ê*â"í!F"âá"äá Í&Íy*í"â*äé>¯2ì"è*â"í!F"âá"äá"ê!\Íâ¯*ê:ì· ÍNÍr!Ð~6·go(Ýåá\íRë*ès#r£Æí_2ËÉëÝáÁáx±( s x±(T]í°ÝéDMÝáÑáx±(ôíR0í ë ëí¸ÝéU(Í�ÝáO/o&ÿ9ùq#ë (í°Ýé!€>F¸0#( ~þ (þ #ï]( ~þ (þ (#ï}“(  Õi&TÉÑÁÕ-a%â}ͦoÉ*é!Ð~6o&ÉÍ|µÈ:Ýõ¯2ÝÍ ñ2Ý}þÀÝá:зÈÝá_Ýá_ÕÍzѯ2Ý*Î|µÝåáíKÌíB "η ÕÕåÍÙÑz· Í^C User break+= Í I/OÍ Run-timeÍ error {Í´Í, PC=*ÎͯÍNot enough memoryÍ Program aborted :Ø·ÊŽ'ÃáÑÑé1!pÇÿÍd!åJÁÁðÇ>ÍÔüIÿþÿÿþÿÿþÿÿþÿÿþÿÿÿ ÿÃI !,ÅÍ!êÅåÍM INDEX.INPÍo!êÅÍÿ!}29Å!"7Å!"5Å!åÍñÑÍËEÊù!!êÅÍæ}îo}24ÅÃ"!}24Å*4Å&Ù ,ÅÃ" !#ÅÍýáá}2+Åýå*+Å&}29Å #ÅÃ" !ÅÍ*9Å&å!ÑÍ’ËEÊa"*9Å&}2Å!}29ÅÃ/#!êÅÍæËEÊv"!}2ÅÃ/#!êÅÍÜËEÊ£"!êÅÍ©Í«Í ! }2Å!"7Å!"5ÅÃ/#*5Åå!ÑÍÌËEÊÌ"! }2Å*5Åå!Ñë·íR"5ÅÃ/#!êÅÍ©!ÅÍDÍ *Å&}2Å*Å&å! ÑÍ’ËEÊ#*7Åå!Ñ"7ÅÃ/#!å*7Åå!ÑÍEÑë·íR"5Å*7Åå*5ÅÑ"7Å! }2Å*Å&}2"Å*"Å&Ù ÅÃ"!ÅÍ!:ÅåÍM INDEX.OUTÍoÍ !:ÅÍþÍ ÅÃ" !ÅÍýáá}2Åýå*Å&å! ÑÍËEʬ#!:ÅͺÍÍÍ ÃÛ#*Å&å!ÑÍËEÊÊ#!:ÅÍiÍ ÃÛ#!:Åͺ*Å&Í"Í  ÅÃ"Ãï# dè'!÷ÄÍýáá"Åýå*Åå!ÑÍàËEÊ $!-åÍy#*ÅÍ€"Å!}2÷Ä!å!ÑÍvz³Êº$Õ"ûÄ!ç#å*ûÄ+)Ñ^#Vë"ùÄ!0}2øÄ*Åå*ùÄÑÍ¥ËEÊ…$*øÄ&å!Ñ}2øÄ*Åå*ùÄÑë·íR"ÅÃT$*øÄ&å!0ÑÍÌËEÊž$!}2÷Ä*÷Ä&ËEʱ$*øÄ&åÍy#*ûÄ+ÑÃ2$!0å*ÅÑåÍy#÷ÄÃ"!ÚÄÍ!ãÄå!+)Ñå!Íå!}2âÄ!ãÄå!+)Ñ^#V ëå!þëás#rÚÄÃ"!ËÄÍýáá"ÖÄá"ØÄýå!}2ÍÄ!}2ÌÄ*ØÄå*ÍÄ&+Ñn&}2ËÄ*ÍÄ&å!Ñ}2ÍÄ*ËÄ&å!?! Í]ÍOËEÊ�%*ËÄ&å! Ñë·íR}2ËÄ*ÖÄå*ÌÄ&+Ñå*ËÄ&ëás*ÌÄ&å!Ñ}2ÌÄ*ËÄ&å!ÑÍËEÊ6%ËÄÃ"!¹ÄÍýáá"ÇÄá"ÉÄýå!ãÄå*âÄ&+)Ñ^#Vë"½Ä!þå*½Ä^#VëÑë·íR"ºÄ*ºÄå!þÑÍàËEÊ"&*ÇÄå*ºÄå!Ñëás#r!}2¼Ä*ºÄå!þÑÍ¥ËEʦ&*âÄ&å! ÑÍËEÊR&!åÍŸ!*âÄ&å!Ñ}2âÄ!ãÄå*âÄ&+)Ñå!Íå!ãÄå*âÄ&+)Ñ^#Vë"½Ä!"ºÄ*ÇÄå!ëás#r!}2¼Ä*¼Ä&å!Ñ}2¼Ä*ÉÄå*¼Ä&+Ñn&}2¹Ä*ºÄå!Ñ"ºÄ*½Äå*ºÄ+Ñå*¹Ä&ëás*¹Ä&å!ÑÍËEÊ)&*âÄ&ë*ÇÄs!þå*ºÄÑë·íRë*½Äs#r¹ÄÃ"!§ÄÍýáá"µÄá"·Äýå!ãÄå*·Än&+)Ñ^#Vë"«Ä*·Ä^#Vë"¨Ä!}2ªÄ*«Äå*¨Ä+Ñn&}2§Ä*µÄå*ªÄ&+Ñå*§Ä&ëás*§Ä&å!ÑÍ’ËEʹ'*¨Äå!Ñ"¨Ä*ªÄ&å!Ñ}2ªÄ*§Ä&å!ÑÍËEÊb'§ÄÃ"!“ÄÍýáá"¢Äá"¤Äýå!ãÄå*¢Än&+)Ñ^#Vë"˜Ä*¢Ä^#Vëå!Ñë·íR"•Ä!}2—Ä*—Ä&å!Ñ}2—Ä*¤Äå*—Ä&+Ñn&}2”Ä*•Äå!Ñ"•Ä*˜Äå*•Ä+Ñn&}2“Ä*”Ä&å*“Ä&ÑÍ’å*”Ä&å!ÑÍÑ}³oËEÊ(*”Ä&å*“Ä&ÑÍËEÊ£(!}2¦ÄÃÈ(*”Ä&å*“Ä&ÑÍàËEÊÁ(!}2¦ÄÃÈ(!}2¦Ä*¦Ä&Ù“ÄÃ"!ÄÍýáá"ŽÄá"�Äýå!ãÄå*ŽÄn&+)Ñ^#Vë"„Ä*ŽÄ^#Vëå!Ñë·íR"�Ä!}2ƒÄ*ƒÄ&å!Ñ}2ƒÄ*�Äå*ƒÄ&+Ñn&}2€Ä*�Äå!Ñ"�Ä*„Äå*�Ä+Ñn&}2Ä*€Ä&å*Ä&ÑÍ’å*€Ä&å!ÑÍÑ}³oËEÊ)*€Ä&å*Ä&ÑÍå*€Ä&å!ÑÍÑ}³oËEʸ)!}2’ÄÃÝ)*€Ä&å*Ä&ÑÍàËEÊÖ)!}2’ÄÃÝ)!}2’Ä*’Ä&ÙÄÃ"!hÄÍýáá"zÄá"|Äýå!ãÄå*|Än&+)Ñ^#Vë"pÄ*|Ä^#Vëå!Ñë·íR"lÄ!ãÄå*zÄn&+)Ñ^#Vë"nÄ*zÄ^#Vëå!Ñë·íR"jÄ*lÄå!Ñ"lÄ*pÄå*lÄ+Ñn&}2iÄ*jÄå!Ñ"jÄ*nÄå*jÄ+Ñn&}2hÄ*iÄ&å*hÄ&ÑÍ’å*iÄ&å!ÑÍÑ}³oËEÊY**iÄ&å*hÄ&ÑÍËEÊß*!}2~ÄÃ+*iÄ&å*hÄ&ÑÍàËEÊý*!}2~ÄÃ+!}2~Ä*~Ä&ÙhÄÃ"!XÄÍýáá"bÄá"dÄýå!XÄå!Íå*XÄ"ZÄ*ZÄå!)Ñå!ëás#r*ZÄå!)Ñå!ëás#r*ZÄå!Ñå!ëás*ZÄå!Ñå!ëás*ZÄå!ëás#r*dÄå*ZÄåÍÀ%*bÄå*ZÄ åÍÀ%*ZÄå!ëás#r*XÄ"fÄ*fÄÙXÄÃ" !MÄÍýáá"UÄýå*UÄ"MÄ*MÄå!Ñn&å*MÄå!Ñn&ÑÍÌËEÊ5,!å*MÄå!Ñn&Ñ}2WÄÃO,!å*MÄå!Ñn&Ñ}2WÄ*WÄ&Ù MÄÃ"!<ÄÍýáá"GÄá"IÄýå*GÄ"=Ä*=Äå!ÑÍ’ËEÊ-*IÄå*=Ä åÍÔ'}2<Ä*<Ä&·íR¾,*=Äå!)Ñ^#Vë"=ÄÃæ,·íRÂË,Ãæ,·íRÂæ,*=Äå!)Ñ^#Vë"=Ä*<Ä&å!ÑÍå*=Äå!ÑÍÑ}³oËEʉ,*=Ä"KÄ*KÄÙ<ÄÃ"!(ÄÍýáá"6Äá"8Äýå*6Äå!ÑÍËEÊI-*8Ä":Äò.!}2-Ä!}2,Ä*8Ä å*6Ä åÍì)å!ÑÍËEÊ…-!}2-Ä!}2,Ä*6Ä".Ä*.Äå*-Ä&)Ñå*8Äå*.Äå*-Ä&)Ñ^#VëåÍ-ëás#r*.Äå*-Ä&Ñå*.Äå*-Ä&)Ñ^#VëåÍ×+ëás!å*.Äå*-Ä&Ñn&å*.Äå*,Ä&Ñn&Ñë·íRÑÍàå*.Äå*-Ä&)Ñ^#Vëå!Ñn&å*.Äå*-Ä&)Ñ^#Vëå!Ñn&ÑÍ’Ñ}£oËEʦ.*.Äå*-Ä&)Ñ^#Vë"*Ä*.Äå*-Ä&)Ñå!ëás#r*.Äå*-Ä&Ñå!ëás*6Äå**ÄåÍ-"*Äì.*6Ä"*Ä**Ä":Ä*:ÄÙ(ÄÃ"Q!×ÃÍýáá""Äá"$Äýå*$Äå!ÙÃåÍ%!ÙÃå*"Ä^#VëåÍ^,"×Ã*×Ãå!ÑÍËEÊ%/*$Äå!ÙÃåÍ+"×Ã*×Ãå*"Ä^#VëåÍ-ë*"Äs#r*×Ã"&Ä*&ÄÙQ×ÃÃ" !ËÃÍýáá"ÓÃá"ÕÃýå*ÓÃn&å!ÑÍàËEÊŒ/*ÓÃn&å!Ñë*ÓÃs*ÓÃå*ÓÃn&+)Ñå*ÕÃëás#r ËÃÃ" !¿ÃÍýáá"ÇÃýå*ÇÃn&å!ÑÍÌËEÊé/*ÇÃå*ÇÃn&+)Ñ^#Vë"ÉÃ*ÇÃn&å!Ñë·íRë*ÇÃsÃï/!"ÉÃ*ÉÃÙ ¿ÃÃ"!¯ÃÍýáá"¹Ãá"»Ãýå!ë*¹Ãs*»Ã"¯Ã*¯Ãå!ÑÍ’ËEÊN0*¯Ãå*¹ÃåÍ8/*¯Ãå!)Ñ^#Vë"¯ÃÃ0*¹Ãå*¹ÃåÍ•/ëás#r*¹Ã^#Vë"½Ã*½ÃÙ¯ÃÃ" !¢ÃÍýáá"«Ãýå!}2¢Ã*«Ã^#Vëå!ÑÍ’ËEÊ1*«Ã^#Vëå!)Ñ^#Vëå!ÑÍ’ËEÊý0*«Ãå*«Ã^#Vëå!)Ñ^#Vëëás#r!}2¢ÃÃ1*«Ãå*«ÃåÍ•/ëás#r*¢Ã&ËEÊw1*«Ã^#Vëå!)Ñ^#Vëå!ÑÍ’ËEÊw1*«Ã^#Vëå*«ÃåÍ8/*«Ãå*«Ã^#Vëå!)Ñ^#Vëëás#rÃ1*«Ã^#Vë"­Ã*­ÃÙ ¢ÃÃ"!ŽÃÍýáá"šÃá"œÃá"žÃýå*žÃå!ÑÍËEÊÄ1!" Ãù2*žÃ"�Ã*œÃå*�à åÍ×(}2�Ã*�Ã&·íRÂÿ1*�Ãå!)Ñ^#Vë"�ÃÃ'2·íRÂ2*�Ãå!)Ñ^#Vë"�ÃÃ'2·íRÂ'2*�Ã&å!ÑÍå*�Ãå!ÑÍÑ}³oËEÊÊ1*�Ã&å!ÑÍ’ËEÊd2!" Ãù2*�Ãå*šÃåÍü/"�Ã*œÃå*�à åÍ×(}2�Ã*�Ã&å!ÑÍ’ËEÊ¡2*šÃåÍ}0"�Ã*�Ã&å!ÑÍËEÊr2*�Ã" Ã* ÃÙŽÃÃ" !=ÃÍýáá"EÃýåÍ›ÍÍÍ Í›ͺ Error in line*ŒÃå!Í&ͺ of input -- Í *E÷íRÂL3Í›ͺ!term must be printable charactersÍ ÃU4·íRÂ�3Í›ͺterm must shorter than !Aå!Í&ͺ lettersÍ ÃU4·íRÂË3Í›ͺ$found nondigit where number expectedÍ ÃU4·íRÂ÷3Í›ͺpage number too largeÍ ÃU4·íRÂ'4Í›ͺimproper range of numbersÍ ÃU4·íRÂU4Í›ͺsubterms nested too deeplyÍ Í›ÍÍÍ ÃÔ  =ÃÃ"!+ÃÍÍ3"}22Ã!}21Ã*2Ã&å!-ÑÍËEÊ¡4!}21ÃÍ3"}22Ã*2Ã&å!_! Í]ÍO}îoËEÊÃ4!åÍÆ2!Ù!+ÃÍÑ!+ÃÍ,ÅÕå!„ ÙáÑÁÍú ÅÕå*2Ã&å!0Ñë·íRÍÙáÑÁÍé Ù!+ÃÍÑÍ3"}22Ã*2Ã&å!_! Í]ÍO}îoËEÊÓ4*2Ã&åÍ"!+ÃÍ,ÅÕå!�þÙáÑÁÍÖËEÊ^5!åÍÆ2*1Ã&ËEÊy5!+ÃÍ,xî€GÙ!+ÃÍÑ!+ÃÍ,ÍÞ";Ã*;ÃÙ+ÃÃ" !ÃÍ!IÃå!+Ñå!ëás!"GÃ*ŒÃå!Ñ"ŒÃ!"ŠÃÍ3"}2Ã*ŠÃå!Ñ"ŠÃ*Ã&å! ÑÍ’ËEÊÄ5*ŠÃå!Ñë·íR"ŠÃ*Ã&å! ÑÍ’ËEʲ5*Ã&å!ÑÍËEÊ%6!ÿÿ"ŠÃß8*Ã&}/o|/gåÍ�! å!Í›ÍOËEÊM6!åÍÆ2!}2"Ã*"Ã&å!Ñ}2"Ã!IÃå*"Ã&+Ñå*Ã&ëásÍ3"}2Ã*"Ã&å!AÑÍå*Ã&å! ÑÍàÑ}³oå*Ã&å! ÑÍå*Ã&å!IÃå*"Ã&+Ñn&ÑÍÑ}£oÑ}³oËEÊT6*"Ã&å!AÑÍå*Ã&å! ÑÍ’Ñ}£oËEÊþ6!åÍÆ2*Ã&å! ÑÍËEÊ7*"Ã&å!Ñ}2"Ã*"Ã&å!ÑÍÌå!IÃå*"Ã&å!Ñë·íR+Ñn&å!,ÑÍÑ}£oËEÊh7*"Ã&å!Ñë·íR}2"Ã!IÃå*"Ã&+Ñå!ëás*Ã&å! ÑÍËEÊ—7Í3"}2ÃÃ{7*Ã&å! ÑÍ’ËEÊŸ8*GÃå!ÑÍËEÊÌ7!GÃå!Íå*GÃ" ÃÃà7* Ãå!Íå* Ã^#Vë" Ã!ë* Ãs#r*Ã&åÍ"* ÃåÍj4ëás#rÍ3"}2Ã*Ã&å!-ÑÍËEÊ]8* ÃåÍj4ëás#r* Ã^#Vëå* Ã^#VëÑ͸ËEÊS8!åÍÆ2Í3"}2ÃÃu8* Ãå* Ã^#Vëëás#r*Ã&åÍ�!,Í‘! Í‘ÍOËEÊœ8Í3"}2ÃÃu8×7 ÃÃ"!ÃÍýáá"Ãýå!"Ã*ŠÃå*ÃÑÍ¥ËEÊL9*ŠÃå*ÃÑÍËEÊ9!IÃå!ÃåÍ¿."Ã*Ãå*GÃëás#rÍ’5ÃI9*dÇå!Ñ"dÇ*dÇå! ÑÍÌËEÊ&9!åÍÆ2*Ãå*ŠÃåͨ8ëás#r*dÇå!Ñë·íR"dÇÿ8*Ã"Ã*ÃÙÃÃ"!ÃÍ!}2 Æ!"dÇÍÐ$Í¢!ËEÊÜ9Í›ͺ&[reading existing index INDEX.INP ... Í !"ŒÃÍ’5*ŠÃåͨ8"fÇÍ›ͺ finished]ÍÍÍ à :Í›ͺ[no existing index document]ÍÍÍ !"fÇ!}2 ÆÃÃ" !ÒÂÍ!å*dÇÑÍfz³ÊO:Õ"ÒÂÍ›ͺ. . Í *ÒÂ#ÑÃ/: ÒÂÃ" !ÈÂÍ!å!ÿÿëÁÍo&}2ÈÂ*ÈÂ&å!ÑÍ’ËEÊa:*ÈÂ&å!ÑÍÌËEʦ:Í›*ÈÂ&Í"Í *ÈÂ&}2ÑÂ*ÑÂ&Ù ÈÂÃ"!ÀÂÍÍ›!Í"! Í"!Í"Í ÀÂÃ" !·ÂÍýáá}2¿ÂýåÍ›!Í"Í *¿Â&å!ÑÍÌËEÊ;;: ·ÂÃ""!•ÂÍýáá"´Âýå!}2œÂÍ�! Í‘! Í‘!-Í‘!0å!9Í›!£ÂÍÍX:}2«Â*«Â&å!£ÂÍ]ÍO}îoËEÊ’;*«Â&åÍè:ë<*«Â&å!ÑÍËEÊ<;:*œÂ&å!Ñë·íR}2œÂ*œÂ&å!ÑÍËEÊé;!£ÂÍ]Í�!Í‘Í&!£ÂÍ*œÂ&å!ÑÍËEÊ!}2¶Â!ë*´Âs#r*¶Â&Ù"•ÂÃ"!…ÂÍýáá"�Âá"‘Âýå!…Âå!Íå*…Â"‡Â!ë*‡Âs#r*‡Âå*‘Âëás#r*‡Âå*�Âëás#r*…Â"“Â*“ÂÙ…ÂÃ"!pÂÍýáá"Âá"�Âá"ƒÂýå!"uÂ*Â^#Vë"sÂ*sÂå!ÑÍËEÊÒ>*Âå*ƒÂå*�ÂåÍ>ëás#rÃ@!}2pÂ*�Âå!Ñå*sÂ^#VëÑÍàËEÊF?*ƒÂå*�ÂåÍ>"qÂ*uÂå!ÑÍ’ËEÊ"?*qÂë*uÂs#rÃ2?*Âå*qÂëás#r*sÂë*qÂs#r!}2pÂÃú?*ƒÂå!Ñë·íRå*sÂ^#VëÑÍÌËEÊ£?*sÂ"uÂ*sÂ^#Vë"sÂ*sÂå!ÑÍËEÊ ?*ƒÂå*�ÂåÍ>ë*uÂs#r!}2pÂÃú?*ƒÂå*sÂ^#VëÑÍàËEÊË?*sÂå*ƒÂëás#r*�Âå*sÂ^#VëÑÍÌËEÊó?*sÂå*�Âëás#r!}2pÂ*pÂ&ËEÊÙ>pÂÃ"ÃØA!XÂÍ*bÂ&å*cÂ&ÑÍÌËEÊE@;:*bÂ&å!Ñë·íR}2bÂÃ@XÂÃ"!PÂÍ*`Âå!ÑÍ’ËEÊÈ@*`Âå!¡ÆåÍ#'*cÂ&}2bÂ!¡Æå*bÂ&+Ñn&å!ÑÍ’ËEÊÅ@Í›!¡Æå*bÂ&+Ñn&Í"Í *bÂ&å!Ñ}2bÂÃ@ÃÛ@Í›!Í"Í !}2bÂPÂÃ"!HÂÍ*cÂ&å*bÂ&ÑÍàËEÊ2A!#Çå*cÂ&+Ñå!¡Æå*cÂ&+Ñn&ëás*cÂ&å!Ñ}2cÂÃí@!#Çå*cÂ&+Ñå!ëás!}2bÂHÂÃ"!@ÂÍ!#Çå!âÆåÍ%*mÂå!âÆå!ÜÂåÍ’1"`ÂÍN@@ÂÃ"!8ÂÍ!ÜÂåÍ}0"`Â*`Âå!ÑÍ’ËEÊÌA!å!âÆå*` åÍ×(ÑÍ’ËEÊÌA!"`ÂÍN@8ÂÃ"!`ÂÍýáá"mÂýåÍ:Í›ͺterm: Í !}2cÂ!}2bÂ!#Çå*cÂ&+Ñå!ëásÍX:}2dÂ*dÂ&·íRÂ_BÍä@*cÂ&å!ÑÍÌËEÊ\B;:*cÂ&å!Ñë·íR}2cÂÃ=C ·íRÂxBÍä@Í›ÍÍÍ Ã=C ·íR‘BÍä@Í›ÍÍÍ Ã=C·íR¼BÍ@*bÂ&å!ÑÍËEʶBÍUAùB͇AÃ=C·íRÂÓBÍ@!}2bÂÃ=CÍä@*dÂ&å! ÑÍàå*cÂ&å!AÑÍÑ}³oËEÊC*dÂ&åÍè:Ã=C!#Çå*cÂ&+Ñå*dÂ&ëás*cÂ&å!Ñ}2cÂ!#Çå*cÂ&+Ñå!ëás*dÂ&å! ÑÍå*dÂ&å! ÑÍÑ}³oËEÊ B*cÂ&å!ÑÍËEÊzC!}2dÂ*dÂ&}2oÂ*oÂ&Ù`ÂÃ"!'ÂÍýáá"6Âýå*6Â^#VëåÍ @}2'Â*'Â&å!ÑÍ’ËEÊÞD!#Çå*6ÂåÍ¿.",Â*'Â&å! ÑÍËEÊœDÍ:Í›ͺpage: Í !*ÂåÍ$;}2'Â*'Â&å!ÑÍ’ËEʉD*'Â&å! ÑÍËEÊ/D**Â"(ÂÃwDÍ›ͺ..Í !(ÂåÍ$;}2'Â*(Âå**ÂÑÍàËEÊwDÍ›ͺ bad range, redo.ÍÍÍ ÃäC**Âå*(Âå*,ÂåÍz>Ã�D! }2'ÂÍ›ÍÍÍ ÃÞD*dÇå!Ñ"dÇ*dÇå! ÑÍÌËEÊÄD*'Â&åÍè:ÃÏD*,ÂåÍ’C*dÇå!Ñë·íR"dÇ*'Â&å!ÑÍå*dÇå!ÑÍÌÑ}³oËEÊ£C'ÂÃ"!ÂÍýáá"$Âýå*$Â^#Vë"Â*Âå!ÑÍ’ËEÊEE*Â^#Vë"ÂÃKE!"Â*Âå!ÑÍ’ËEÊÝE*Â^#Vëå!Ñå*Â^#VëÑÍ¥ËEÊÊE*Â^#Vëå*Â^#VëÑÍÌËEʹE*Âå*Â^#Vëëás#r*Â^#Vëë*Âs#rÃÐE*Â"Â*Â^#Vë"ÂÃKE*$Â^#Vë"Â*Âå!ÑÍ’ËEÊF!,åÍy#! åÍy#! åÍy#*Âå!ÑÍ’ËEÊìF*Â"Â*Â^#Vëå!ÑÍËEÊ\F*Âå*Â^#Vëå!Ñëás#r*Â^#Vëå*Â^#VëÑ͸ËEÊÁF*Â^#VëåÍä#*Â^#Vëå*Â^#VëÑÍàËEÊÁF!-åÍy#*Â^#VëåÍä#*Â^#Vë"Â*Âå!ÑÍ’ËEÊéF!,åÍy#! åÍy#ÃFÂÃ"! ÂÍýáá"Âýå*Âå!#ÇåÍ#'*dÇå!ÑÍËEʆG!#Çå!+Ñn&}2 Â* Â&å!?! Í]ÍOËEÊ_G* Â&å! Ñë·íR}2 Â* Â&å*&Â&ÑÍ’ËEʃG! åÍy#* Â&}2&ÂûG!å*dÇÑÍfz³Ê»GÕ}2 Â! åÍy#! åÍy#! åÍy#* Â&#ÑÑG!}2 Â!}2 Â!#Çå* Â&+Ñn&å!ÑÍ’ËEÊIH!#Çå* Â&+Ñn&}2 Â* Â&å! ÑÍ’ËEÊH* Â&åÍy#!}2 ÂÃ7H* Â&ËEÊ0H* Â&åÍy#!}2 Â* Â&å!Ñ}2 ÂÃÉG ÂÃ"7!ÓÁÍýáá"Âýå*Âå!ÕÁåÍü/"ÓÁ*ÓÁå!ÑÍ’ËEÊåH*ÓÁåÍõF*ÓÁåÍ E! åÍy#*ÓÁ^#Vëå!ÑÍ’ËEÊØH*dÇå!Ñ"dÇ*ÓÁ^#VëåÍRH*dÇå!Ñë·íR"dÇ!ÕÁåÍ}0"ÓÁÃqH7ÓÁÃ"!ËÁÍÍG#!"dÇ*fÇåÍRH!åÍy#ËÁÃ" !ÁÁÍýáá"ÉÁýåÍ›ÍÍÍ Í›ͺ[Out of string space!]ÍÍÍ * Æ&ËEʰIÍ›ͺ[Trying to write output file.]ÍÍÍ ÍîHÍ›ͺ[Output file complete.]ÍÍÍ ÃÔ  ÁÁÃ"!}2 ÆÍ›ͺ [index aid, revision of 11/3/86]ÍÍÍ Í›ͺ%[copyright (c) 1986 David E. Cortesi]ÍÍÍ Í_9Í›ͺ [initialized]ÍÍÍ Í›ÍÍÍ !fÇåÍ’CÍîHÍ›ÍÍÍ Í=ÍÙ!šÆÍÑ!šÆÍ,ÅÕå!ÍÙáÑÁÍéËEÊ£J!‘ÅÕå!šÆÍ,ÙáÑÁÍé Ù!šÆÍÑÍ›ͺ [normal end,!šÆÍ,ÅÕå!å!Íyͺ storage left.]ÍÍÍ ÃÔ ÍÑ!šÆÍ,ÅÕå!ÍÙáÑÁÍéËEá"Âýå*Âå!#ÇåÍ#'*dÇå!ÑÍËEʆG!#Çå!+Ñn&}2 Â* Â&å!?! Í]ÍOËEÊ_G* Â&å! Ñë·íR}2 Â* Â&å*&Â&ÑÍ’ËEʃG! åÍy#* Â&}2&ÂûG!å*dÇÑÍfz³Ê»GÕ}2 Â! åÍy#! åÍy#! åÍy#* Â&#ÑÑG!}2 Â!}2 Â!#Çå* Â&+Ñn&å!ÑÍ’ËEÊIH!#Çå* Â&+Ñn&}2 Â* Â&å! ÑÍ’ËEÊH* Â&åÍy#!}2 ÂÃ7H* Â&ËEÊ0H* Â&åÍy#!}2 Â* Â&å!Ñ}2 ÂÃÉG ÂÃ"7!ÓÁÍýáá"Âýå*Âå!ÕÁåÍü/"ÓÁ*ÓÁå!ÑÍ’ËEÊåH*ÓÁåÍõF*ÓÁåÍ E! åÍy#*ÓÁ^#Vëå!ÑÍ’ËEÊØH*dÇå!Ñ"dÇ*ÓÁ^#VëåÍRH*dÇå!Ñë·íR"dÇ!ÕÁåÍ}0"ÓÁÃqH7ÓÁÃ"!ËÁÍÍG#!"dÇprogram indexer; {$I+,R-,A-,B-} {==============================================================} { Book Indexing Assistant Program } { Turbo Pascal version of: november 3, 1986 } { Copyright (C) 1986 by, and inquiries by mail to: } { David E. Cortesi } { 2340 Tasso Street } { Palo Alto, CA 94301 } { All rights reserved. Distribution for profit forbidden } { without explicit permission. Distribution by individuals } { and nonprofit organizations permitted provided this notice } { is retained and author credit is given in printed materials. } { } { This program assists you in constructing an index for a book.} { See the accompanying documentation file for further info. } { Note the R- compile switch: the program OUGHT to work with } { R+ (range checking), I pulled off enough errors, but since } { they were mostly trivial I turned off checking so that if any} { are left they won't crash the user.  } { } { Main file. History: } { bugs fixed and merge program added 11/3/86 } { initial writing 5/31 -- 6/6/86 } {==============================================================} const null = 0; { the null, end-of-string } asciibel = 7; { names for ascii characters } asciibs = 8; asciitab = 9; asciilf = 10; asciicr = 13; asciieof = 26; asciiesc = 27; asciiblank = 32; asciidel = 127; alnumset : set of char = ['0'..'9','A'..'Z','a'..'z']; alphset : set of char = ['A'..'Z','a'..'z']; allowset : set of char = ['a'..'z']; digitset : set of char = ['0'..'9']; digsign : set of char = ['0'..'9','-']; maxnests = 9; { allows up to 9 levels of subterms } maxdepth = 20; { max depth of a tree (2^19th nodes) } strmax = 65; { max size of a string, 64 data plus 00} sblksize = 2046; { block size of a string buffer } sblkmax = 10; { allow up to 20K -- use more in MSDOS!} type strindex = 1..strmax; { indices over strings } strlength= 0..strmax; { lengths of strings } relation = (less,equal,more); { result of comparisons } nchar = 0..255; { numeric characters are bytes } str = packed array[strindex] of nchar; { independent string} stref = record { an indirect string is an } nb : 1..sblkmax; { index into SBLKPTRS and an } bo : 1..sblksize { offset into that strblock } end; ppage = ^page; page = record { page reference to a term: } next : ppage; { ..linked in a chain, with } num1, num2 : integer { ..one or a range of nums } end; sides = (left, right); { names of children of tree } tdepth = 0..maxdepth; { range of depths, nil = 0 } tree = ^node; node = record { one node of a binary tree } cnodes : array[sides] of tree; { children of this node } cdepth : array[sides] of tdepth; { ..and their depths } subtree : tree;  { subtree of sub-terms } term, { index term as typed, and } dict : stref; { upcase for dictionary comps } pages : ppage; { head of chain of page-refs } end; walk = record { status of a walk over a tree } top : tdepth; { index of top of stack } curr : tree; { node on which walk now steps } stack : array[1..maxdepth] of tree; {pending nodes } end; var maintree : tree; { root of the term-tree } indlevel : integer; workterm, workdict, scratch : str; initdone : boolean; space : real; procedure disaster(which:integer); forward; {==============================================================} { Sections of code out-of-line to allow compilation in CP/M } {==============================================================} {$I IXTEXT.PAS textfile I/O stuff } {$I IXSTRG.PAS support for string storage } {xI IXDIAG.PAS nullify the "$" when diag not needed} {$I IXTREE.PAS support for tree creation } {$I IXWALK.PAS logic of inorder tree walk } {$I IXINIT.PAS phase 0: initialize, load existing index } {$I IXDOIT.PAS phase 1: keyboard interaction } {$I IXDONE.PAS phase 2: writing the output index document } {------ only one disaster coded just now, running out of -----} {------ string block space in stput --------------------------} procedure disaster; begin writeln; writeln('[Out of string space!]'); if (initdone) then begin writeln('[Trying to write output file.]'); finish; writeln('[Output file complete.]') end; HALT end; {==============================================================} { The main program, at last..... } {==============================================================} begin initdone := false; writeln('[index aid, revision of 11/3/86]'); writeln('[copyright (c) 1986 David E. Cortesi]'); initall; writeln('[initialized]'); writeln; keyinto(maintree); finish; writeln; space := MemAvail; if (space < 0) then space := 65536.0 + space; writeln('[normal end,',space:6:0,' storage left.]'); end.  MemAvail; if (space < 0) then space := on } {$I IXDONE.PAS phase 2: writing the output index document } {------ only one disaster coded just now, running out of -----} {------ string block space in stput --------------------------} procedure disaster; begin writeln; writeln('[Out of string space!]'); if (initdone) then begin writeln('[Trying to write output file.]'); finish; writeln('[Output file complete.]') end; HALT end; {==============================================================} { The main program, at last..... } {==============================================================} begin initdone := false; writeln('[index aid, revision of 11/3/86]'); writeln('[copyright (c) 1986 David E. Cortesi]'); initall; writeln('[initialized]'); writeln; keyinto(maintree); finish; writeln; space := MemAvail; if (space < 0) then space := {==============================================================} { IXDIAG.PAS } {Copyright (C) 1986 David E. Cortesi--see notice in IXMAIN.PAS.} { This include file contains a diagnostic procedure that will } { display a binary tree of index terms. The call "diag(t)" -- } { where t is of type tree as defined in IXMAIN -- can be inser-} { ted temporarily for diagnostic purposes in the code. The } { include-command in IXMAIN should be disabled (by changing } { its dollar-sign to something else) unless a diag() call is } { actually in use. } { History: } { initial code 11/2/86 } {==============================================================} {-- recursive tree display ----} procedure tdiag(t:tree;n:tdepth); var j:strlength; begin if (t <> nil) then tdiag(t^.cnodes[right],n+1); for j := 0 to n-1 do write(' '); write('|-- '); if (t <> nil) then begin stget(t^.term,scratch); j := 1; while(scratch[j] <> null) do begin write(chr(scratch[j])); j := j+1; end end else write('*'); writeln; if (t <> nil) then tdiag(t^.cnodes[left],n+1); end; {--- sets up the recursive display, waits afterward ----} procedure diag(t:tree); var c : char; begin writeln; writeln('DIAGNOSTIC DISPLAY'); tdiag(t,0); writeln('press return'); readln(c) end; char;ostic purposes in the code. The } { include-command in IXMAIN should be disabled (by changing } { its dollar-sign to something else) unless a diag() call is } { actually in use. } { History: } { initial code 11/2/86 } {==============================================================} {-- recursive tree display ----} procedure tdiag(t:tree;n:tdepth); var j:strlength; begin if (t <> nil) then tdiag(t^.cnodes[right],n+1); for j := 0 to n-1 do write(' '); write('|-- '); if (t <> nil) then begin stget(t^.term,scratch); j := 1; while(scratch[j] <> null) do begin{==============================================================} { IXDOIT.PAS } {Copyright (C) 1986 David E. Cortesi--see notice in IXMAIN.PAS.} { This include section contains the user interaction. The user} { is prompted for a term at the current indentation level. } { A null entry terminates this level of the index -- and ends } { the program, at the outermost level. } { When entering a term, pressing ESCape causes us to locate } { the term as typed so far in the tree at this level, and to } { complete the term on the screen from the matching term that } { lexically least. Further presses of ESC bring up successive } { matching terms until the user accepts one (by pressing any } { key except ESC) or until no more matches are found. DEL } { makes us give up trying to match the term and remove the } { letters supplied from the candidate term. After a term is } { ended with either CR or LF, we insert or find it in the } { current tree.  } { Terminating a term with CR causes a prompt for a page } { number reference. We read the number digit by digit and do } { our own conversion to binary so as to avoid crashing with a } { pascal run-time error. Any signed 16-bit integer is allowed } { (previous versions of the program couldn't handle 0). } { Terminating the number with CR ends entry of the number. } { Ending it with LF instead makes us prompt with ".." and take } { another number (must be algebraically greater) to store as } { the end of a range of numbers. } { Terminating term-entry with LF not CR causes us to enter } { a subtree off the completed term. We enter the subtree of } { the entered term and prompt again at a deeper indent level. } { History: } { don't put a page item on a term when no page # given 11/3/86 } { initial code 6/3-5/86 } {==============================================================} var scan: walk; {------ indent the cursor for the current nesting level -------} procedure indent; var i : integer; begin for i := 1 to indlevel do write('. . ') end; {------ get one byte from the keyboard. bypass pascal and go -} {------ straight to DOS. Echo printables, don't echo ctls. ---} function readnc : nchar; var c : nchar; begin repeat c := bdos(6,-1) { CHECK: OK FOR MS-DOS???? } until (c<>0); if (c>31) then write(chr(c)); readnc := c; end; {------ implement destructive backspace -----------------------} procedure backspace; begin write(chr(asciibs),chr(asciiblank),chr(asciibs)) end; {------ reject a user keystroke, blanking if printable --------} procedure reject(c:nchar); begin write(chr(asciibel)); if (c>31) then backspace end; {------ get a valid page number keyed in and set its value in -} {------ PAGE. Return its delimiter as the result: asciieof ---} {------ if no page entered, or asciicr, or asciilf. Since we -} {------ deal direct with the user we give immediate feedback --} {------ when a number is too long or too large or whatever ----} function getpage(var page: integer) : nchar; const hyphen = 45; var c : nchar; { keyed character } s : set of 0..57; { set of currently-valid ones } x : array[0..5] of 0..57; { keys typed so far } j,k : 0..6; { indices over x } w : real; { accumulated value at end } begin j := 0; { nothing typed so far } s := [asciilf,asciicr,hyphen, 48..57]; { bytes we can take } repeat c := readnc; if not(c in s) then reject(c) else if (c = asciibs) then begin backspace; j := j-1; if (j=0) then s := s - [asciibs]; if (j=1) then s := s + [hyphen] end else if (c>asciicr) then begin if (j>5) then reject(c) else begin x[j] := c; j := j+1; s := s - [hyphen]; s := s + [asciibs] end end until ((c=asciicr)or(c=asciilf)); if (j > 0) then begin {nonnull page number} getpage := c; c := x[0]; k := 0; if (c = hyphen) then k := 1; w := 0.0; while (k 32767.0) then w := 32767.0; if (c = hyphen) then w := -w; page := trunc(w) end {of nonnull page} else begin {no page entered} getpage := asciieof; page := 0 end end; {------ make a page record for numbers I and J ----------------} function makepage(i,j:integer):ppage; var p : ppage; begin new(p); with p^ do begin next := nil; num1 := i; num2 := j end; makepage := p end; {------ Add the range of consecutive numbers from I to J to ---} {------ the chain of numbers off treenode T, economizing on ---} {------ PAGE structures. The method used keeps the chain in --} {------ numeric sequence but may produce overlapping values ---} {------ under some entry sequences, e.g. (3,8),(5,5)(12,12) ---} procedure putpage(i,j:integer; t: tree); var p,q,n : ppage; stop : boolean; begin p := nil; q := t^.pages; if (q = nil) then { new entry, no numbers yet } t^.pages := makepage(i,j) else begin stop := false; repeat if ((j+1) < q^.num1) then begin { (i,j) has to follow p^ and precede q^ } n := makepage(i,j); if (p <> nil) then p^.next := n else t^.pages := n; n^.next := q; stop := true end else if ((i-1) > q^.num2) then begin { (i,j) has to follow q^ ... } p := q; q := q^.next; if (q = nil) then begin { (i,j) goes at end of chain } p^.next := makepage(i,j); stop := true end end else begin { (i,j) overlaps or touches q^ } if (i < q^.num1) then q^.num1 := i; if (j > q^.num2) then q^.num2 := j; stop := true end until stop; end end; {------ fill in term string TRM from the keyboard in context --} {------ of tree T. Return a signal, asciieof, -cr, or -lf -----} {------ depending on the outcome, as the result. --------------} function getterm( t : tree) : nchar; var c : nchar; { current input keystroke } j : strindex; { indexes over current term in TERM } k : strlength; { indexes recalled term, or else 0 } p : tree; { ^tree of recalled term } {-- back up the screen to the original term --} procedure backup; begin while (k > j) do begin backspace; k := k-1 end end; {-- common finish of both starting and stepping a scan ----} procedure showtrm; begin if (p <> nil) then begin stget(p^.term,scratch); k := j; while (scratch[k] <> null) do begin write(chr(scratch[k])); k := k+1 end; end else begin write(chr(asciibel)); k := 0 end end; {-- accept the current scanned term for use, if any -------} procedure accept; begin while (j < k) do begin workterm[j] := scratch[j]; j := j+1 end; workterm[j] := null; k := 0 end; {-- set up for a treewalk over all terms that are an ------} {-- initial match to the entry so far. --------------------} procedure startscan; begin stucase(workterm,workdict); p := setscan(t,workdict,scan); showtrm end; {-- scan to the next equal term in the tree and show it ---} procedure stepscan; begin p := wstep(scan); if p<>nil then if (equal<>stbcmpa(workdict,p^.dict)) then p := nil; showtrm end; begin { the main Get Term procedure } indent; write('term: '); j := 1; k := 0; repeat workterm[j] := null; c := readnc; case c of asciibs : begin { destructive backspace } accept; { accept current match if any } if (j > 1) then begin backspace; j := j-1; end end; asciicr : begin { normal completion } accept; writeln end; asciilf : begin { complete, move on to subterm } accept; writeln end; asciiesc : begin { automatic scan for match } backup; { wipe rejected match if any } if (k=0) then startscan else stepscan end; asciidel : begin { cancel search for match } backup; k := 0 { no scan active } end; else begin { ordinary (?) character } accept; if (c asciieof) then begin {nonnull term entered} insnode := insert(workterm,t); if (c = asciicr) then begin {final term} 111: indent; write('page: '); c := getpage(p1); if (c <> asciieof) then begin {nonnull page#} if (c = asciicr) then p2 := p1 else begin {page# then lf entered} write('..'); c := getpage(p2); if (p2 < p1) then begin writeln(' bad range, redo.'); goto 111 end end;{page range} putpage(p1,p2,insnode) end {of entering page for this term} else c := asciicr; {null page #} writeln; end {of term ended in cr} else begin { user hit lf, wants to recurse } indlevel := indlevel+1; if (indlevel > maxnests) then reject(c) else keyinto(insnode^.subtree); indlevel := indlevel-1 end {of recursing to lower-level term on lf} end {of handling nonnull term} until (c = asciieof) or (indlevel>0) end; end {of recursing to lower-level term on lf} end {of handling nonnull term} untf (c <> asciieof) then begin {nonnull term entered} insnode := insert(workterm,t); if (c = asciicr) then begin {final term} 111: indent; write('page: '); c := getpage(p1); if (c <> asciieof) then begin {nonnull page#} if (c = asc{==============================================================} { IXDONE.PAS } {Copyright (C) 1986 David E. Cortesi--see notice in IXMAIN.PAS.} { This include file contains declarations and code related to } { writing the output file, INDEX.OUT in the current directory. } { See IXTEXT.PAS for support functions. } { } { History: } { append comma to term string when page numbers follow 11/3/86 } { initial writing 6/5/86 } {==============================================================} var initial : nchar; {------ Write a list of page-numbers. Since in collecting the -} {------ numbers we might have built overlapping ranges, we ----} {------ must first tidy the list, during which we discard some-} {------ page records forever ----------------------------------} procedure outpages(t : tree); var p, q : ppage; begin p := t^.pages; if (p <> nil) then q := p^.next else q := nil; while(q <> nil) do begin if ((p^.num2+1) >= q^.num1) then begin {range q^ can at most extend the range of p^ up} if (q^.num2 > p^.num2) then p^.num2 := q^.num2; p^.next := q^.next {forget that page record} end else p := q; q := q^.next end; p := t^.pages; if (p <> nil) then begin nextout(ord(',')); nextout(asciiblank); nextout(asciiblank) end; while (p <> nil) do begin with p^ do begin if (num1 = 0) then num1 := num1 + 1; if (num1 <= num2) then begin intwrite(num1); if (num1 < num2) then begin nextout(ord('-')); intwrite(num2) end end end; p := p^.next; if (p <> nil) then begin nextout(ord(',')); nextout(asciiblank) end end end; {------ write one term to the output, inserting a blank line --} {------ if its initial varies from the last and we are at the -} {------ outermost level. Dump extra/leading/trailing blanks. -} procedure outterm(t : tree); var c : nchar; i : tdepth; j : strindex; s : boolean; begin stget(t^.term,workterm); if (indlevel = 0) then begin c := workterm[1]; if (chr(c) in allowset) then c := c-32; if (c <> initial) then begin nextout(asciicr); initial := c end end else for i := 1 to indlevel do begin nextout(asciiblank); nextout(asciiblank); nextout(asciiblank) end; j := 1; s := false; while (workterm[j] <> null) do begin c := workterm[j]; if (c <> asciiblank) then begin nextout(c); s := true; {ok to print next space} end else begin if (s) then nextout(c); s := false {omit further spaces} end; j := j+1 end end; {------ Display all the terms in a (sub)tree to the output ----} {------ by walking all its nodes. Where a term has a subtree -} {------ recurse to write it. ----------------------------------} procedure outtree(t : tree); var position : walk; p : tree; begin p := initwalk(t,position); while (p <> nil) do begin outterm(p); outpages(p); nextout(asciicr); if (p^.subtree <> nil) then begin indlevel := indlevel+1; outtree(p^.subtree); indlevel := indlevel-1 end; p := wstep(position) end end; {------ write the whole tree to the output --------------------} procedure finish; begin initout; indlevel := 0; outtree(maintree); nextout(asciieof) end; -----------} prohile (workterm[j] <> null) do begin c := workterm[j]; if (c <> asciiblank) then begin nextout(c); s := true; {ok to print next space} end else begin if (s) then nextout(c); s := false {omit further spaces} end; j := j+1 end end; {------ Display all the terms in a (sub)tree to the output ----} {------ by walking all its nodes. Where a term has a subtree -} {------ recurse to write it. ----------------------------------} procedure outtree(t : tree); var position : walk; p : tree; begin p := initwalk(t,position); while (p <> nil) do begin outterm(p); outpages(p); n{==============================================================} { IXINIT.PAS } {Copyright (C) 1986 David E. Cortesi--see notice in IXMAIN.PAS.} { This include file directs initializing, primarily reading an } { an existing index document to initialize the trees. } { The output file is, and the input is expected to be, an } { index document as made by this program. Blank lines aside, } { every line of an index document is (must be) composed of: } { * a MARGIN of zero or more spaces } { * a TERM of printable characters } { * two (or more) spaces to mark the end of the term } { * zero or more NUMBERS or ranges 1-9 } { The numbers may be signed, and may have spaces and commas } { between them. } { History: } { minor cleanup 11/4/86 } { drop trailing comma on input term 11/2/86 } { initial code 6/2/86 } {==============================================================} var lineno : integer; { line numbers for diagnostics } margin : integer; { margin of last-in or next-out term } interm : str; { term last-in or next-out } pagref : ppage; { list of "page" structures in/out } {------ diagnose an error in the input file and abort ---------} procedure badfile(e:integer); begin writeln; write('Error in line',lineno:5,' of input -- '); case e of 1 : write('term must be printable characters'); 2 : write('term must shorter than ',strmax,' letters'); 3 : write('found nondigit where number expected'); 4 : write('page number too large'); 5 : write('improper range of numbers'); 6 : write('subterms nested too deeply'); end; writeln; HALT end; {------ read and collect one signed integer, assuming that ----} {------ there should be a number coming next from nextinch ----} function nextpage:integer; var n : nchar; s : boolean; x : real; begin n := nextinch; s := false; if (n = ord('-')) then begin s := true; n := nextinch; end; if (not (chr(n) in digitset)) then badfile(3); x := 0.0; repeat x := (x * 10.0) + (n - ord('0')); n := nextinch until (not (chr(n) in digitset)); pushinch(n); if (x > 32767.0) then badfile(4); if (s) then x := -x; nextpage := trunc(x) end; {------ read and collect one line of input file ---------------} procedure nextline; var j : strlength; p : ppage; n : nchar; begin interm[1] := null; pagref := NIL; repeat lineno := lineno + 1; margin := 0; repeat n := nextinch; margin := margin + 1 until (n <> asciiblank); margin := margin - 1 { note size of margin } until (n <> asciicr); { discard null lines } if (n = asciieof) then margin := -1 { note eof } else begin if (not n in [asciiblank..asciidel]) then badfile(1); j := 0; repeat j := j + 1; interm[j] := n; n := nextinch until ( (j=strmax) or (n < asciiblank) or ((n = asciiblank) and (n = interm[j])) ); if ((j=strmax) and (n<>asciiblank)) then badfile(2); if (n = asciicr) then j := j+1; if ( (j > 1) and (interm[j-1] = ord(',')) ) then j := j-1; interm[j] := null; while (n = asciiblank) do n := nextinch; while (n <> asciicr) do begin if (pagref = nil) then begin new(pagref); p := pagref end else begin new(p^.next); p := p^.next end; p^.next := nil; pushinch(n); p^.num1 := nextpage; n := nextinch; if (n = ord('-')) then begin {range X-Y} p^.num2 := nextpage; if (p^.num2 <= p^.num1) then badfile(5); n := nextinch end else p^.num2 := p^.num1; while (chr(n) in [',',' ']) do n := nextinch; end end end; {------ read consecutive lines of existing index at margin ---} {------ level M and make a binary tree of them. When the ----} {------ margin moves in, recurse to build a subtree. When ---} {------ it moves back out, stop. -----------------------------} function initree(m: integer): tree; var t,p : tree; begin  t := nil; while (margin >= m) do begin if (margin = m) { true first time for sure } then begin p := insert(interm,t); p^.pages := pagref; nextline end else begin indlevel := indlevel + 1; if (indlevel > maxnests) then badfile(6); p^.subtree := initree(margin); indlevel := indlevel - 1; end end; initree := t end; {------ control initialization sequence, calling initializers -} {------ in other "modules" as they exist ----------------------} procedure initall; begin initdone := false; indlevel := 0; initstrg; { set up string storage } if (initinp) then begin write('[reading existing index INDEX.INP ... '); lineno := 0; nextline; maintree := initree(margin); writeln('finished]') end else begin writeln('[no existing index document]'); maintree := nil end; initdone := true end; ) end else begin writeln('[no existing index document]'); maintree := nil end; initdo{==============================================================} { IXSTRG.PAS } {Copyright (C) 1986 David E. Cortesi--see notice in IXMAIN.PAS.} { } { This include-file contains declarations and code related to } { the implementation of dynamically-allocated strings. The } { method chosen uses strictly standard Pascal facilities, and } { was chosen because nonstandard stuff varies between CP/M and } { MSDOS versions of Turbo Pascal, and between Turbo and other } { Pascal systems (yes, Virginia, there are some). It's kinda } { clunky, but it works good enuff for what this program needs. } { } { We define an INDEPENDENT string as a character array of the } { max size in which the string data are kept, left justified } { and bounded by a null (like in C). } { } { A string BLOCK is a 2K block holding a bunch of strings in } { compact form, without padding to the max length for each. } { Blocks are allocated as needed, whenever the current one is } { full, up to a limit set by SBLKMAX. } { } { Once stowed in a block, a string may be referred to using a } { STREF, an index to its block's address plus its offset in } { that block. } { History: } { initial code 6/2/86 } {==============================================================} type strblock = record { string block has count of } free : 0..sblksize; { ..bytes free in block and } data : array[1..sblksize] of nchar { ..space for bytes } end; var sblkptrs : array[1..sblkmax] of ^strblock;{ blocks of bytes} sblkcnt : 0..sblkmax; { how many blocks are active } {------ initialize string storage -----------------------------} procedure initstrg; begin new (sblkptrs[1]); sblkcnt := 1; sblkptrs[1]^.free := sblksize; end; {------ make a copy of a string with alphas forced to upcase --} {------ and punctuation deleted, so it can be compared in -----} {------ "dictionary sequence." --------------------------------} procedure stucase(var a,b:str); var aj, bj : strindex; n: nchar; begin aj := 1; bj := 1; repeat n := a[aj]; aj := aj+1; if (chr(n) in allowset) then n := n-32; b[bj] := n; bj := bj+1; until (n=null) end; {------ stow independent string A in a string block and fill --} {------ in its STREF, allocate new string block as needed -----} procedure stput(var a:str; var b:stref); var bp : ^strblock; j : strlength; k : 0..sblksize; n : nchar; begin bp := sblkptrs[sblkcnt]; { ^latest string buffer } k := sblksize - bp^.free; { index of next free byte -1 } if(k < sblksize) then b.bo := k+1;{ note start in stref } j := 0; { index start of string } repeat { copy bytes from str to block until null copied } if (k >= sblksize) then begin { ooops, off end of block, start over in a new one } if (sblkcnt = sblkmax) then { uh-oh } disaster(1); sblkcnt := sblkcnt + 1; new(sblkptrs[sblkcnt]); bp := sblkptrs[sblkcnt]; k := 0; b.bo := 1; j := 0 end; j := j + 1; n := a[j]; k := k + 1; bp^.data[k] := n; until (n = null); b.nb := sblkcnt; { complete the stref } bp^.free := sblksize - k; end; {------ retrieve stowed string into independent array --------} procedure stget(var b:stref; var a:str); var bp : ^strblock; j : strindex; k : 1..sblksize; n : nchar; begin bp := sblkptrs[b.nb]; { point to the buffer page } k := b.bo; { ..and offset into it } j := 1; repeat { copy bytes until the null } n := bp^.data[k]; a[j] := n; if (n<>null) then begin k := k+1; j := j+1 end until (n=null); end; {------ EXACT compare of string A to stowed string B, so a ----} {------ leading substring is found to be "less" ---------------} function stbcmpx(var a:str; var b:stref) : relation; var bp : ^strblock; j : strlength; k : 0..sblksize; x,y : nchar; begin bp := sblkptrs[b.nb]; k := b.bo - 1; j := 0; repeat j := j + 1; x := a[j]; k := k + 1; y := bp^.data[k]; until ((x<>y) or (x=null)); if (x=y) then stbcmpx := equal else if xy) or (x=null)); if ((x=y) or (x=null)) then stbcmpa := equal else if (xy) or (x=null)); if (x=y) then sbbcmpx := equal else if xy) or (x=null)); if ((x=y) or (x=null)) then stbcmpa := equal else if (x null) then begin n := pushed; pushed := null end else if eof(inpfile) then n := asciieof else if eoln(inpfile) then begin readln(inpfile); n := asciicr; column := 0; blanks := 0 end else if (blanks > 0) then begin n := asciiblank; blanks := blanks - 1; end else begin read(inpfile,c); n := ord(c); if (n <> asciitab) then column := column + 1 else begin blanks := 7 - (column mod 8); column := column + blanks; n := asciiblank end end; nextinch := n end; {------ open the output file ----------------------------------} procedure initout; begin assign(outfile,'INDEX.OUT'); rewrite(outfile); end; {------ write a byte to the output - this is ONLY output ------} procedure nextout(n:nchar); begin if (n = asciicr) then writeln(outfile) else if (n = asciieof) then close(outfile) else write(outfile,chr(n)) end; {------ write an integer without a leading blank --------------} procedure intwrite(x : integer); const czero = 48; powten : array[1..4] of integer = (10,100,1000,10000); var k, p : integer; d : nchar; z : boolean; begin if (x < 0) then begin nextout(ord('-')); x := abs(x) end; z := false; { n.b. integer division is VERY slow in 8-bit turbo } { yes, slower than 5 adds and 5 subtracts } for k := 4 downto 1 do begin p := powten[k]; d := czero; while (x >= p) do begin d := d + 1; x := x - p end; if (d > czero) then z := true; if (z) then nextout(d) end; nextout(czero+x) end;  + 1; x := x - p end; if (d > czero) then z := true; if (z) tUT'); rewrite(outfile); end; {------ write a byte to the output - this is ONLY output ------} procedure nextout(n:nchar); begin if (n = asciicr) then writeln(outfile) else if (n = asciieof) then close(outfile) else write(outfile,chr(n)) end; {------ write an integer without a leading blank --------------} procedure intwrite(x : integer); const czero = 48; powten : array[1..4] of integer = (10,100,1000,10000); var k, p : integer; d : nchar; z : boolean; begin if (x < 0) then begin nextout(ord('-')); x := abs(x) end; z := false; { n.b. integer division {==============================================================} { IXTREE.PAS } {Copyright (C) 1986 David E. Cortesi--see notice in IXMAIN.PAS.} { } { This include-file contains declarations and code related to } { the implementation of nested trees of index terms. A tree } { is a network of dynamically-allocated nodes in the structure } { of a binary tree. Terms are only inserted to the tree, no } { deletions are supported. However, the tree is kept balanced } { under insertions using a recursive method of my own. This } { dynamic rebalancing keeps the tree optimal (time to locate a } { node is never worse than log2 N) regardless of the order in } { which terms are entered. This in turn permits loading of the} { tree directly from a previous index text file, even though } { the terms in an index document are in ascending sequence. } { } { Each tree node represents one index term. The term itself is } { stored two ways, as typed and in dictionary-comparison form, } { a form that compares "Half Way" equal to "halfway". A node } { anchors a sorted chain of page-numbers, and may hold the root} { of an independent sub-tree of sub-terms. The tree is ordered } { so that all terms in cnodes[left] are less than, and all in } { cnodes[right] are greater, than this term. } { History: } { fix bug that caused loop/crash when adding C to tree with } { items A,B,D,E,F -- 11/2/86 } {==============================================================} {------ create a new tree node to hold the term in string A ---} {------ and its dictionary form, string D, returing address ---} function makenode(var a, d : str) : tree; var t : tree; begin new(t); with t^ do begin cnodes[left] := nil; cnodes[right] := nil; cdepth[left] := 0; cdepth[right] := 0; subtree := nil; stput(a,term); stput(d,dict); pages := nil; end; makenode := t end; {------ return the depth of tree T: one more than the larger --} {------ of the depths of its children -------------------------} function depthof(t: tree):tdepth; begin with t^ do if (cdepth[left] > cdepth[right]) then depthof := 1 + cdepth[left] else depthof := 1 + cdepth[right] end; {------ look for the term in string A in the tree T. Return ---} {------ the addr of the found node, or NIL if not found. This--} {------ routine is quick because nonrecursive. ----------------} function lookup(var d: str; {in} t : tree) : tree; var p : tree; r : relation; begin p := t; if (p <> nil) then repeat r := stbcmpx(d,p^.dict); case r of less: p := p^.cnodes[left]; equal: ; more: p := p^.cnodes[right]; end until ((r = equal) or (p = nil)); lookup := p end; {------ insert the tree N into the tree T. this is used when -} {------ a term was not found by lookup and must be put into --} {------ the tree as a node. The result of the function is NOT-} {------ the inserted node, but the NEW TOP NODE of the tree ---} {------ after rebalancing it: either T or its n-side child. ---} function tinsert( n, {into} t : tree) : tree; var s,o : sides; p,q : tree; begin if (t = nil) then tinsert := n else begin s := right; { assume adding in increasing order } o := left; if (sbbcmpx(n^.dict,t^.dict) = less) then begin s := left; o := right end; with t^ do begin cnodes[s] := tinsert(n,cnodes[s]); cdepth[s] := depthof(cnodes[s]); if (1 < (cdepth[s]-cdepth[o])) {tree is unbalanced toward side s but there's no point in } {attempting balance at the current level when subtree s } {is itself in perfect balance -- defer to higher level } {unless subtree s is unbalanced and might improve. } and (cnodes[s]^.cdepth[left] <> cnodes[s]^.cdepth[right]) then begin {rebalance tree by snipping off the parent at this level } {and its side-o subtree and reinserting that tree into its} {former child, subtree s. } p := cnodes[s]; cnodes[s] := nil; cdepth[s] := 0; p := tinsert(t, {into} p) end else p := t end; tinsert := p end end; {------ look for term A in tree T and, if it isn't found, put -} {------ it there, rebalancing the tree as needed. Return -----} {------ the address of the node found or inserted. -----------} function insert(var a: str; {into} var t : tree) : tree; var d: str; p: tree; begin stucase(a,d); p := lookup(d,t); if (p = nil) then begin {insert it} p := makenode(a,d); t := tinsert(p,t) end; insert := p end; kup(d,t); if (p = nil) then begin {insert it} p := {is itself in perfect balance -- defer to higher level } {unless subtree s is unbalanced and might improve. } and (cnodes[s]^.cdepth[left] <> cnodes[s]^.cdepth[right]) then begin {rebalance tree by snipping off the parent at this level } {and its side-o subtree and reinserting that tree into its} {former child, subtree s. } p := cnodes[s];{-------------------------------------------------------------} { IXWALK.PAS } {Copyright (C) 1986 David E. Cortesi--see notice in IXMAIN.PAS.} { } { This include file contains the code for tree-walking. The } { "term recall" feature of the program (see IX.DOC) works by } { finding the lexically-least term matching some argument, } { and performing an in-order walk of the tree from that point.} { During output we walk all nodes of all trees. } { The usual algorithm for a walk is recursive (see J&W 11.5), } { which is not convenient for this program. During output, } { there will be walks going on in main and subtrees, so the } { walk position is remembered in a dynamic record. } { History: } { initial code 6/2/86 } {-------------------------------------------------------------} {------ push node T onto the walk-stack for later use ---------} procedure wpush(t : tree; var w : walk); begin if (w.top < maxdepth) then begin w.top := w.top + 1; w.stack[w.top] := t end end; {------ pop the top node of the walk-stack --------------------} function wpop(var w : walk) : tree; begin if (w.top > 0) then begin wpop := w.stack[w.top]; w.top := w.top - 1 end else wpop := nil end; {------ initialize to walk a tree T by clearing the stack ----} {------ and pointing to the top node, then descending to the -} {------ lowest, leftmost node and returning it --------------} function initwalk(t : tree; var w : walk) : tree; var p : tree; begin w.top := 0; p := t; while (p <> nil) do begin wpush(p,w); p := p^.cnodes[left] end; w.curr := wpop(w); initwalk := w.curr end; {------ step to the next node of a tree in lexical order. ----} {------ return that next node as result, and save it as the --} {------ current step. Return nil at end of tree. ------------} function wstep(var w : walk) : tree; var wleft : boolean; begin wleft := false; { have handled w.curr and its left subtree} if (w.curr <> nil) then begin if (w.curr^.cnodes[right] <> nil) then begin { it has a right subtree, so enter it and.. } w.curr := w.curr^.cnodes[right]; wleft := true { ..then plunge down again } end else { nowhere to go but up } w.curr := wpop(w) end; if (wleft) then { plunge down to the left } while (w.curr^.cnodes[left] <> nil) do begin wpush(w.curr,w); w.curr := w.curr^.cnodes[left] end; wstep := w.curr end; {------ Given a partial term (upcased) in D and a tree T, -----} {------ set up so that a series of WSTEP calls will return all } {------ nodes initially equal to A. Return the first such, or } {------ nil if the tree is null or has no terms matching A. ---} function setscan(t : tree; var d : str; var w : walk) : tree; var p : tree; r : relation; quit : boolean; begin if (t = nil) then setscan := nil { no matches possible } else begin { first, find any part-equal node at all } p := t; repeat r := stbcmpa(d,p^.dict); case r of less : p := p^.cnodes[left]; more : p := p^.cnodes[right]; equal : ; end until (r = equal) or (p = nil); if (r <> equal) then setscan := nil { no match a-tall } else begin {-- node P is the highest match, none above it in the tree match, but there may be lesser and greater matches in its left and right children. Set up to walk the tree of which P is the root. InitWalk will return the least leaf of P and walking from there to the first match to A will give the least match to A (which may be the one in P) --} p := initwalk(p,w); repeat r := stbcmpa(d,p^.dict); if (r <> equal) then p := wstep(w) until (r = equal); setscan := p end end end; := stbcmpa(d,p^.dict); if (r <> equal) then p := wstep(w) until (r = equan if (t = nil) then setscan := nil { no matches possible } else begin { first, find any part-equal node at all }  The INDEXER Program Copyright (C) 1986 David E. Cortesi 2340 Tasso St. Palo Alto CA 94301 Compuserve 72155,450 MCI Mail DCORTESI (rarely checked) GEnie Mail DCORTESI (rarely checked) All rights reserved. Distribution for profit forbidden without explicit permission. Free distribution or distribution by nonprofit organizations permitted provided this notice is retained and author credit is given in printed materials. ====== HISTORICAL INTRODUCTION This program is an aid to indexing a book. The first version I wrote was in Ithaca Intersystem's Pascal/Z and donated to the Pascal/Z user's group, from which in time it reached SIG/M disk number 94 and also the FOG library. IF YOU HAVE THAT VERSION, (source in a single file INDEXER.PAS) GET RID OF IT; IT WILL CRASH ON YOU AND LOSE YOUR WORK!!!! In 1985 I converted that program to compile under Borland's Turbo Pascal for some people in Seattle. At the same time I made a version that would compile under Microsoft Pascal version 3.0 on the PC and gave it to some people at Microsoft. Those versions work pretty well (at least, nobody's complained), but this one supercedes both. This version is much more flexible and the code is a lot simpler and more readable (we all learn as we go along, though slowly). It's for Turbo Pascal and should work on a PC, but has NOT been tested on one by the author. Under CP/M, owing to Borland's peculiar storage management, you must compile the program in your own machine to get maximum benefit. The delivered COM file is set up for a machine with a TPA of only 48K (the CP/M CCP loads at C000h, the program overlays it up to C7F0h). The M)ain source file is IXMAIN; it includes all the others as it compiles. Select O)ptions and C)om file, and set the largest E)nd address your machine allows (the CCP plus 7f0h). ====== THE INDEXING PROBLEM An index is an indispensable part of any non-fiction book. Even a poor index can give better access to a book than a table of contents can, while a good index increases the utility of a book many times. However, indexing a book is a skilled job. The indexer must understand the subject of the book well, so as to know what the important topics are. The indexer must read the book and comprehend it, so as to know when a reference to a topic is important enough to merit an index entry. The indexer must understand the intended use, and users, of the book well, so as to know the terms that they will expect to find in the index. In the traditional, manual method of indexing, the indexer sets up a file of 4x5 (index!) cards, one for each topic to be indexed. Then he/she reads the book and, wherever a topic appears, writes the page number on its card. The sorted cards provide the material for typing the index. An index of sorts can be built automatically by sorting the words of a document file, eliminating duplicates, and appending the page numbers on which the words appeared. However, such an index refers only to words; it does not index topics. It works only to the extent that the topics of the book are fully expressed in single words (and to the extent that the words were used consistently). It is completely unselective, showing every reference no matter how trivial. There can be no provision for sub-entries under a major topic, nor for multiple entries for a topic under different terms. All automatic methods fail if the book is to be typeset, because they assume the numbers of the book as printed by computer. The page numbers of the typeset work will be different, so the machine-made index will have to be heavily edited at least. And of course, automatic methods can't work when the book isn't available in machine-readable form -- as when you want to index a software manual for your own use. The Indexer program is a machine aid for a human indexer. It does the job of the pile of index cards, and it makes the finished index automatically, as a disk file that can be edited or printed. ====== PROGRAM OPERATIONS When it starts operation, the Indexer loads a working document, an index in progress, if it can find one. Whether it does or not, it then prompts you for "terms" and "pages" and stores these until you indicate that you're finished. Then it writes the completed index as a text file to disk and ends. Let's look at this process in detail. The Indexer is a compiled program, and as such is a command of the operating system, CP/M or MSDOS. The name of the command is is IXMAIN, and it takes no parameters, so the command looks like A>ixmain The first thing the command does is to look for an existing file of index data, a file named INDEX.INP in the default disk (current directory, MSDOS). If it does not find that file, you will see these results: A>ixmain [index aid, revision of 11/3/86] [copyright(C) David E. Cortesi 1986] [no existing index document] [initialized] term: If it does find a file -- which would be the saved contents of an index you are working on -- you would see instead A>ixmain [index aid, revision of 11/3/86] [copyright(C) David E. Cortesi 1986] [reading existing index INDEX.INP ... finished] [initialized] term: Depending on the size of the existing index, there'd be a pause of some seconds before that word "... finished]" appeared. Once initialized, the program prompts for a "term." A "term" is a word or phrase you want to index. A term may contain spaces and any printable characters. You may use the backspace key to correct typing errors. You usually signal the end of the term with the Return key. Here's one: term: frammis page: ^---- return pressed there Indexer finds or adds the term to its list in storage, then prompts for a "page." It expects the page number of a reference to the term just entered. It will accept any integer from -32767 to 32767. You may only type a leading minus sign and digits here; if you type anything else the program rejects the keystroke with a beep. If you give it a page number greater than 32767, it will reduce it to 32767 without warning you. Suppose "frammis" is used on page 32: term: frammis page: 32 term: ^----- return ends the number The program has inserted the page number in its numerical list of page numbers entered for this term, "frammis," and it's now ready for another term. Suppose that was all you wanted to do with the index at this time (perhaps the phone rang). Pressing only Return at the main "term:" prompt ends the run: term: ^---- return pressed here [normal end, 27044 storage left.] A> The program has written the complete index as a printable text file to the file INDEX.OUT in the default disk (current direc- tory in MSDOS). You may work on it with the system's usual utilities, or edit it with an editor: A>type index.out frammis, 32 A> In particular, if you want the index as you have it so far to be available next time, you must make it INDEX.INP, using A>pip index.inp=index.out in CP/M, or A>copy index.out index.inp in MSDOS. The file INDEX.INP is the existing index-in-progress that the program will read when next it initializes itself. ====== INDEXING WITH A BATCH FILE You'd probably rather think of the index of a book in terms of that book's name, and keep the file with related ones, rather than calling it INDEX.INP and keeping it with this program. You might even have indexes in progress for more than one book at once. Well, all these things can be done with quite a simple batch command file. In CP/M it looks like this: A>type index.sub pip index.inp=$1.INX ixmain era $1.BAK ren $1.BAK=$1.INX pip $1.INX=index.out[v] ...and a typical use of it might look like A>submit index b:mybook Under MSDOS it might look like this: C:\indexer\>type index.bat copy %1.INX index.inp ixmain erase %1.BAK rename %1.INX %1.BAK copy index.out %1.INX and in use it might look like this: C:\indexer\>index b:\backmatter\mybook In either case, the aim is to keep a book's index file as a file called (name-of-book).INX on some drive or subdirectory with the rest of the book's files. When you want to index, the batch commands make a copy of the index under the name INDEX.INP and afterward, put the updated index back. You should be able to adapt these examples to your disk arrangement and methods. ====== RANGES OF PAGES When Indexer stores a page number, it attempts to economize on storage and document size by packing adjacent line numbers into hyphenated ranges. For example, if you have entered references to "frammis" on pages 9, 11, and later 10, you will find in the output file frammis, 9-11 instead of individual page numbers 9, 10, and 11. You may enter ranges of page numbers yourself. If you know that "frammis" is discussed on pages 193 to 212 inclusive, you need not make all 19 separate entries (as you did in older versions of this program). Instead, enter the first page number, 193, but end it with Linefeed instead of Return. The program will prompt with two dots and await the second number of the range: term: frammis page: 193..212 ^------linefeed pressed there term: The second number of the pair must be equal to or greater than the first one (a range of, say, 6..6 is taken as merely the single number 6). If the second number is less, the program will snap at you and make you enter both numbers over again. ====== USING SUB-TERMS Indexer allows any term to have sub-terms and sub-sub-terms to a depth of nine. Subterms are very useful in indexes; they allow you to group subtopics under a main topic entry. Some readers will look for a topic under its general term; others will look for it under a very specific term. For example, a good index to a Pascal manual might index the CASE statement two or even three ways: ... CASE statement, 27 ELSE allowed, 4, 69 speed of vs. IF, 43 ... ELSE clause, 27 with CASE, 4, 69 ... statement types assignment, 25 BEGIN, 32 CASE, 27 ... To Indexer, each group of subterms is a little index of its own. Its terms are stored and sorted, and their page numbers are collected, just as is done for the main terms. When it prepares the output file, Indexer indents 3 spaces at each subterm level. To enter a subterm, you first enter its main term. But instead of ending the main term by pressing Return, you end it by pressing LineFeed (or Control-J, or Control-Return on the IBM keyboard). Indexer then prompts for a ". . term," indenting one level on the screen. Enter the subterm just as you would a main term. End it, too, with LineFeed if you are entering a sub-subterm. When you eventually end a term with Return, you will be prompted for a page number as usual. That page number will be associated with the subterm, not with its superior term(s). Let's enter a couple: term: frammis <---linefeed used here to enter subterm . . term: purchase price <---return indicates last term . . page: 17 term: frammis <---linefeed here . . term: components of <---linefeed again, sub-subterm . . . . term: stripped screws <---now a return . . . . page: 1432 term: ====== TERM RECALL Typing all these terms is tedious, but Indexer has a feature that can save a lot of the labor. The feature is called Term Recall, and it serves two purposes. You recall a term by typing some of its initial letters, then pressing the Escape key. Indexer searches its list of terms for the alphabetically-lowest one that matches the initial letters you have typed to that point. It then completes the term on the screen by typing the remaining letters of that term. If that is the term you wanted to recall, you may then press Return or LineFeed exactly as if you had typed the whole term yourself. Or you can modify the term as it appears then by backspacing and retyping part of it. If the term is not the one you want, just press Escape again. INDEXER will wipe out the letters it supplied, find the next term in alphabetic order, and show its final letters. If you keep pressing Escape, you will be shown all the terms that match the initial letters you typed. When there are no more, INDEXER beeps the console alarm. If you decide that you don't want any of the recalled terms, press the Delete key. INDEXER will restore the line to just the characters you had typed initially. Term Recall can save a lot of typing. It also provides a way to review the terms you have defined so far. Press Escape without typing any initial letters at all; INDEXER will complete your non-existent entry by showing you the first of all the terms it has, and will step through all the terms as you press Escape. Term Recall may be used at any level of sub-terms. To see what subterms you have under some main term, enter the main term, ending it with Linefeed. Then use Escape to recall the subterms that are stored under that main term. ====== CORRECTING ERRORS -- THE INDEX INPUT FILE The Indexer provides no way to delete a term or a page number, and no way to edit either one after you've entered it. This was a serious problem in older versions of the program. In this version, however, the saved index-in-progress is a text file, and you may correct errors by editing it. As discussed earlier, the program's output is a text file, and when it starts up it reads a copy of its previous output in order to initialize itself for more work. But you are free to edit the program's output file before feeding it back in, and that means you are free to correct index errors, even add new terms, with your regular text editor, between runs of the indexer. You needn't even keep the entries in alphabetical order; the program will put them back in order as it reads in the file at the start of a new session. However, the program is very picky about the format of the lines it reads from its existing index document. Basically it expects the document to be pretty much the way it wrote it as output! It ignores blank lines, but all others must have this form: (margin) (term) (spaces) (number list) Taking those in order: the (margin) is zero or more spaces, and the program takes the number of spaces as its clue to terms and subterms. When the margin gets wider from one term to the next, the program assumes that the more-indented term is a subterm of the term in the previous line. When you add terms to the text file, be sure to align them precisely relative to the terms above and below them, or you may end up with levels of subterm you didn't intend. The (term) is any sequence of printable characters. SINGLE blanks may appear in it as word-spaces. But the program takes the appearance of TWO OR MORE spaces to be (spaces), the signal that marks the end of (term) and the start of (number list). This rule leads to some minor problems we'll discuss below. The (number list) is a list of zero or more numbers in the form the program writes it during output: single integers or pairs of them with a hyphen between, separated by commas and spaces. What this means is that you must treat an index in progress as a "non-document" file for word processing purposes. Nor should you put into it any commentary or text other than index lines until you are quite finished indexing. ====== MERGING INDEX FILES The program can store quite a large index (a few hundred terms), an adequate capacity for small projects. A message at the end of each run gives you some indication of how full storage was; if it drops below 5,000 you may begin to worry about space running out. If you do begin to run out, divide the work. Begin to build a second index for some separable part of the book. You might divide the book by parts or chapters, or you might choose some class of terms (names of people for example, or a class of technical terms such as medical or botanical latinisms or computer words), a class that can be indexed separately. (Choose the division right and you might even be able to divide the work of indexing between two people with separate computers!) After dividing the index work, begin working on two (or more) separate index files, exactly as you previously worked on a single file. When the work is complete, you may merge separate index files with the IXMERGE program. It performs a merger of two index documents to form a single larger one. Since it does this a line at a time, it suffers no storage restrictions. The command (under CP/M) is A>ixmerge addfile where "addfile" is the filename of an index document as prepared by ixmain. The program reads two files: "addfile" and INDEX.INP. It merges them into the single file, INDEX.OUT, which may then be copied to some other name. If there are more files to be merged, simply rename INDEX.OUT to INDEX.INP and repeat the merge for the next file. The only limit to the final size is disk capacity. Suppose you have split the work into three, building separate indexes as PART1.INX, PART2.INX, and NAMES.INX for proper names. Here is a CP/M batch file that would build the full index. A>type mrge.sub pip index.inp=b:part1.inx ixmerge b:part2.inx era index.inp ren index.inp=index.out ixmerge b:names.inx pip b:full.inx=index.out[v] And here is how it might look under MSDOS: C:\indexer\>type index.bat copy b:\backmatter\mybook\part1.inx index.inp ixmerge b:\backmatter\mybook\part2.inx erase index.inp rename index.out index.inp ixmerge b:\backmatter\mybook\names.inx copy index.out b:\backmatter\mybook\full.inx In either case, merger would be the final step before printing. If more entries were needed, you'd use ixmain on the partial files, then merge again. ====== SUGGESTIONS FOR USE The more planning you do beforehand the better your index will be (so what else is new?). But it's true! Start by marking up a copy of the book. Read through it carefully with a pencil and a highlighting pen in hand. Mark every term to be indexed, and note in the margins where a topic should be entered under more than one term. One reason for planning is to avoid inconsistent spellings. The Indexer ignores the case of letters in looking up terms, so that "Indexer" and "indexer" are the same term to it. However, it does compare all punctuation and white space literally, as you typed it -- so "halfway" and "half way" are DIFFERENT terms. Consistency of punctuation is equally important when using IXMERGE. It ignores letter case when comparing terms, but like IXMAIN it compares whitespace and punctuation naively, and minor differences of punctuation can lead to extra entries. Further on the matter of spaces: during input, IXMAIN takes the terms just as you type them, and alphabetizes naively. If you insert multiple spaces, they are stored, so that not only is "half way" not the same as "halfway," the term "half way" is different still. But during output, the program compresses multiple spaces to single ones, so as to ensure that its output file meets its own requirements for input as discussed above. If you must include multiple spaces in a term, enter some other character to stand for them -- the sharp, #, is conventional. An even odder thing affects leading spaces. You ought never to type a leading space on a term, but if you do it, the program will store it as typed. The leading space collates ahead of all other initial letters, so that term will show up first during term recall and out of sequence in the output. But during output, the program strips leading spaces so as to avoid an incorrect margin in the input file. Then, when the working index is read back on the next run, the misplaced term will be stored correctly, and will now show up in its right collating order! Sometimes you want a term to appear without page numbers. This is often true of main terms with many subterms; you use the main term only as a heading and put all the page numbers on its subterms. The way to do this is simply to press return when the program issues the "page:" prompt. The program does not allow for Roman numeral page numbers. If you must index Roman-numeralled pages, I suggest you enter them as their decimal equivalents but with a minus-sign: enter vii as -7. Minus numbers sort ahead of positive ones, and you can find them with a global search on (space)(hyphen) and fix them when the index is done. Sometimes you may want to distinguish one page number among many -- say you want the primary reference to a term to print in bold type, or a reference to an illustration to be italicized. The program doesn't allow for extraneous text with page numbers. One clumsy way to deal with this is to enter distinguished page numbers as large negative numbers, so that, say, -20318 stands for page 318 in bold face, and -30318 means page 318 in italics. Then you fix these by tedious hand labor in the final document. Some books have two-part page numbers, CC-PP where CC is a chapter number. If no chapter has more than 999 pages, and if there aren't more than 31 chapters, just enter these as the chapter number times 1000 plus the page: 2025 for 2-25. These even collate in the right sequence. The program doesn't make specific allowance for "see" entries, as in "Frammis: see Imaginary Implements." But such a string would just be another term, and if you don't enter a page number for it, it'll stand in the output. Alternatively, you could set up another range of phony numbers, with -9991 standing for "see Imaginary Implements," and have yet another job to do in the final edit. Ordinary terms are short, just a word or a very short phrase. After all, indexes are normally printed two columns to a page! Thus the 64-byte limit on terms is no real limit at all. But if you use terms near that length, and also use multiple levels of subterms, you'll find that at the 3rd subterm level, the long indentation of the prompt causes your long term to wrap on an 80-column screen. Indexer doesn't know or care how wide the screen is, and won't be bothered by this if you aren't. ====== TECHNICAL DETAILS Indexer stores terms as character strings. I chose to do my own strings rather than use the compiler's string type, so that the program could be ported to other compilers. Since most term storage is allocated dynamically, and the string type is always allocated for its maximal length, and most terms are much shorter than the 64 bytes allowed, keeping every term as an independent string would waste storage. Except when they are being entered or written, terms are stored compactly in blocks of 2048 bytes, and referenced by a block number and an offset index. If the program tries to allocate a string block and there isn't room, the program will crash with a runtime error, too bad. However, the number of 2K blocks it will try to use in all is set by the constant SBLKMAX in IXMAIN.PAS. If it uses them all up, it will save work in progress and end with a message, so keep SBLKMAX to a size that is less than the available heap space. Terms have to be stored in mixed case for output but compared in all-caps. For speed, every term is stored twice, once as typed and once all-cap. Even so, SBLKMAX = 10, or 20K for strings, allows a BIG index. But by all means allow more in MSDOS if you like. Terms are stored in a binary tree, and subterms under a term are stored in a tree dangling from the superior term's node. When a term is inserted, the tree is rebalanced as needed, so terms may be entered in any sequence and the tree stays optimal. The algorithm for dynamic rebalancing is my own, and is more notable for simplicity than for efficiency. Page numbers are stored in an ordered chain anchored in the term's node. Chain links are allocated only as needed, new numbers being merged into existing ranges when possible. However there is no attempt to compact a chain: entering 3 then 5 then 4 produces the range 3-4 and the lone page 5. Overlaps can develop in some circumstances, so that the chain shows a range of 8-15 and another of 12-16. These are tidied up at output. Term recall and output both depend on an "in-order" tree walk that is implemented with nonrecursive code. During output it is necessary to interrupt the walk over main terms to walk trees of subterms, so the WALK structure holds the record of the present position of a tree-walk. k over main terms to walk trees of subterms, so tode. When a term is inserted, the tree is rebalanced as needed, so terms may be entered in any sequence and the tree stays optimal. The algorithm for dynamic rebalancing is my own, and is more notable for simplicity than for efficiency. Page numbers are stored in an ordered chain anchored in the term's node. Chain links are allocated only as needed, new numbers being mer INDEX AID PACKAGE This is a package of software that aids the preparation of an index for a book. The package supersedes all prior versions of this code that have made their way into the public domain. The documentation is in INDEXER.DOC, and the executable programs are IXMAIN.COM and IXMERGE.COM. The remaining files are the source code, meant to compile under Turbo Pascal on CP/M (although few changes should be needed for use in MSDOS). David E. Cortesi 11/20/86 compile under Turbo IXSTRG PAS+WXYZ[\IXTEXT PAS]^_`IXTREE PAS%abcdeIXWALK PASfghiINDEXER DOC€jklmnopqrstuvwxyINDEXER DOCEz{|}~€�‚ABSTRACT$$$ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååÃâ Í«Copyright (C) 1985 BORLAND Inc¡BZenithminal selectedPY ELMKqp~·7È#õå~Íèáñ=ÈóÍ ÉoåͦÉþ€ÜkÔ„æîå!îå!è"áãõÅÕ~#·(åÍèáôÑÁñãÉ}´È:$‡‡‡ããããÅÒÁ= ô+èÍÐØ*ÎßõÅÕå!¨Í5!¢ÍÐ*ºÔáÑÁñÉõÅÕå!´éõÅÕå!®àõ:à·(ÅÕå¯2à!ÈÍ5áÑÁñÉõ:àþÿ(öÅÕå>ÿ2à!ÂãõÅÕå!¼ÚõÅÕååð!‹í°Ñ:žO:œ‚ÕÍÜÑ:ŸO:�ƒÍÜ!ðÍÐ* ÍáÑÁñÉ!ð ë!›45(É! +/ –0ü†õyþ0(ñíÉ d!kÃ5!{Ã5Í_æÍ_o&Éô  áÁå:Ý·(ÕÅÍ |µ(Íáþ ÍáþÊÔ ÁÑ*é"Òx2Ýy·( >Ã28!û"9!¥ í°!½¸ í°¯og2Ð"Ô"Ö>~2Ñ2àÉÃà Ã9Ã/Ã4Ã*Ã9à Á‚CÄÅÁÅÕåÝåýåõo&åͦñýáÝááÑÁÉÅÕåÝåýåÍ£}ëÿ í[Òþ (ú!eÍ{ͦþA8þQ0Gþ: xÖ@¯!\w# (Í‚ þ?(þ*( þ.( ÍwÍ^þ. Í^!h6#ûÉ (þ?( þ*( Í‚( w#éÉ>?> w#üÉͦþ 8 åÅ!˜í±ÁáÉ¿É .,;:=?*[]<>{}þaØþ{ÐÖ É|Í´}õͽñæÆ�'Î@'Ãɯ7Ë|À|·}È>ÿÉ2ØÅͯÁ*·íBÚ¨ ëÑùü "Ưog"Î2Ü>Ã2Ù!Þ "Úë"Ìéå*Æ·íB"Æí[Ä·íRëáÚuí°É*Æí°"ÆÙÉ^#V#Õ^#V#N#FáÉÝáëO/o&ÿ9ùëí°ÝéÑO/o&ÿ9ùëí°éÝáë!àÿ9ùëÅ(¯üí°Á> �‘(G¯üÝéÝá!àÿ9ù ¯w#üÝéÝáEͺ¶wÝéÝáÑ}“8÷�Ã' ·íR·íB0 É>‘Ã' ·íRëêqðøÉÕë·íRëáë·íR!È+ÉÍß õͰ ð·íR!À+ÉÍß õͰ ðÍr!Ð+ÉÍß õͰ ðÍr!ÈØ+ÉÍß ôͰ ïÍr!ÈØ#ÉÍß ôͰ ïÍr!Ø+ÉÍß õͰ ðT]KBë!z·> S>)ë)ë0 = öÉ|µÊ |ªõÍ€ëÍ€ëDM¯go>íjíB0 7?ËË= ðëñðHåÍ’Ë<ËÑëÍëËzÈ5ÍaÈ)ýÉÍaÈË<ËúÉëz· {þ0G·É¯goÉë|ª|ú~ºÀ}»ÉÉË|È|/g}/o#É}æo&ÉíKÊí[ÈÅÕxAJSËËËËáëáíJDM!éb"Èë!6íJ"ÊDMÉ'ÍâèÍâdÍâ Íâ} ¯<íR0û= ÈÆ0ÝwÝ#ÉÝ~Ö$O! Ý#Ý~ͦÖ08)þ 8 !Öþ 8þ0T])Ø)Ø T]Ø)Ø_ØËy·È|‡ÉÝááå}&#9N�8wë!DíB9ùëåí°ëá+Oí¸ë#ùÝé>Ã) ÝáÍÈWáÍÝ _áå}“8(º8J`9{‚T]=o`9yí¸ë ¯Ã) Í Ð>Ã' Í� õͬÍ— íÙ}·Ù>Ê' Íõ ßÙËxÙˆ Ù}·ÙÈÙÅÕåÙ}· Ù˸TÅËø¯ÙËø}Ù•(0íD=ÙÍz ,= ù(Ùñæ€ Í’ 0%Í{ ·, 7 ÍÆ ?õ(8Ùͬ Ëx ͆ - öÍr ñ8˸·ÙáÑÁÙÉÙËxÙ Í� Í Ø,-Èxî€GÉÙ}·ÙÊr }·ÈÙ…ÙÍM ÅÕåÝ9Ír Ù.Ù>Ý#ÝnË0Í’ Í{ = ñÙ-Ù åÝnûËx ͇ ,-(-ñññ·ñÙÁáÙÝá˸°G,-Ìr É}·ÈÙ•Ù?ÍM åååÝ9Ù.Ù>ÍÆ 8ͬ ?Ë= ÝuÝ+Ù-Ù(>͆ 0ßͬ ·á͆ 8ÍÆ ?áÑÁËx ͇ š, —7•8Æ€8Æ€8oÝãÙåÅxËøÙ¨æ€õËøÝåÝ!ÉáØ¯oGOW_gÉ·ËËËËËÉ·ËËËËËÉ|Ù„Ùg{Ù‹Ù_zÙŠÙWyÙ‰ÙOxÙˆÙGÉ|Ù”Ùg{Ù›Ù_zÙšÙWyÙ™ÙOxÙ˜ÙGÉxÙ¸ÙÀyÙ¹ÙÀzÙºÙÀ{Ù»ÙÀ|Ù¼ÙÉÙxÙ¨òé xÉËx(Íó È?É}Ù½ÙÀ·ÈÃÆ }Ö�Úr <þ(ÐÙÅÕåÍr 7Í{ = ùÙ|Ù¤Ùg{Ù£Ù_zÙ¢ÙWyÙ¡ÙOxÙ ÙGÃ{ ÙÅÕåÙͬÙÍý ÙÍ� ë}·ÈËx>Â' ͬ}Æ€Ë/Æ€oÖõÙÅÕåÍõ Í -ÅÕåÍ� }áÑÁÙáÑÁã¼ã0ãñÙÉÙÍŽ-Í� ÙÍŽ,Ù}þlØÅ˸Íß Á8 Íõ Í4 Í— Ëx(Í Ù-ÙÍß õ8Í� Ù-ÙÍß 8Ù,Í� }þl8;Ùª*ªª!ªÍ— ÝåÝ! >Í4ÝáͬÍ— Í— ÅÕåÙͬ--Ù-Í ÙáÑÁÙÍ� ,,ñ,-ÈØxî€GÉgª?+2×n¶*ï8t Ð Ðzˆˆˆˆ~«ªªªª,->Ê' ËxÂ' Ù͘Ù}.�•õÍõ Ù͆ÙÍ� ÅÕåÙ,Í ÙáÑÁÍõ ÝåÝ!Œ >Í4Ýá,ÙÍ¢-ÙÍ ñÅÕåo&0%ÍÙ,Í— ÙáÑÁÍ }þgÚr É}Š�؉}颋.:}Žã8Žc~I’$I~ÍÌÌÌL«ªªª*ÙÍ¢Ù·Ëxõ˸Íõ }þˆ0GÅÕå,ÍÐåË<Ë}áõÍ,-(-ÙñáÑÁõÍ� ÝåÝ!>ÍIÝáñ0 õÙ͘ÙÍ— ñ…o8 ñÈÙ͆Ãõ á>Ã' m.`1pF,þåt6|‰„!wS<ÿÃ.zÒ}[•|%¸FXc~üïýu€Ò÷r1}·ÈÝåÙ͆Ù¯Ëx(<˸õÍß 8ÙÍõ ñËÿõÙÏŽé!~JÙÍß 0Í.OÝ!Î>ÙÝÍsÙÍß 8 = ìÙ ÝÙÙÍnËøÍ ÅÕåÍsÍ— Ù͆Í ÙáÑÁÍõ ÝåÍ.ÝáÙÍnÍ ñ0 õÙÍŽ-Í� ñÝáËOÈËøÉçÏÌTöô¢0 jÁ‘ €µžŠoD€‚,:Í€jÁ‘ �€!¢ÚI}袋.º}Žã8Žc~I’$I’~ÍÌÌÌL«ªªªªÝ! >ÅÕåõͬÍ— ñÍIÙáÑÁ× õÙÍnõÙÅÕåÍnÍ ÙáÑÁÙÍ— ñ= éÙ͆à ÝÝnÝfÝ^ÝVÝNÝFÉ!�DLT\ÉI¢Ú!‚!É53ó!�úÉr1÷!€ÒÉÅÕåÙáÑÁÉÍ’!€> Ëx Ë#ËËË-= ðo˸ÉËxÙ͆(Ëø-Í ·Ë}(ËxËø>�½8(Íz ,óÍz `iÈÃ!É>’Ã' |µÊr Ë|Í€>�)=Ë|(úDMboÀ˸ÉÍÈë8þ8ÍÈÙËxÙ(’0¯þ 8> ÕÍ€ÑËx(>-ÍåË{(aËy(ÍãÍÙ ò�z·(>.Íå (Íã ÷ú±ÍÙ÷Ë{È>EÍå>+Ë|(|íDg>-Íå|/Ö 0ûÆ:ÝpÝ# ý~ý#· ý+>0ÝwÝ#Éýå,-  ý60ý#ø¯Ã}Å˸}ÙÖ€oŸgMÍõ|þÙ <ýwíDÍ@}þ�0ͳý5Ëø>„•.(Íz Ë= øý~õ> xæÆ0ýwý#xæGÅÕåË%͇ Ë%͇ ëãÑãíZëáãíJDMáË%͇ = ÈñÁýáÉýåá_~6þ5Øúœ+~¨¥Ôh¶¿ÉìÅëx-ÐÍÎÂSÞùx9?ë+¨­ÅøÉ{Η@}·ÈËøÅÕ|Íz Íz „gãíZëáãíJDMá0Í{ ,7È}Æo˸ÉÍ?¾ #øyîO!@9ùi&ÝéÍ? ë¶¾ â#÷ÚÍ?¶w#ùëùÝéÍ?/¦w#øïÍ?¦w#ùãýáÝá!9ë! E9ýéÝá!!9~·(¯+Fͺ¦!"9ù!(#Ýé>¯2èýá*ÒÍâ¯á"âýå|· >"2ÐÉ:è·( Ͷ *âwÉÍò*â6 ë!\$í°É!æÅåí[Òþ (úͦ–( áÁã·É#ëÁÁþ:À~ÉCONÁTRMÁKBD‚LSTCAUXÄUSRÅ>¯2èÍi:зÀ*âË®~æÀÍ0:зÀ*â:è·€€(@q##pÉÍZ*â ë:è·( ÕÍÑñÅÍÁ<Àx2ÐÉ*â6#ûÉ"â~æÀËv( >ÍÆÍ Ë~È*âå ëÍá< >ÿ2Ð6Éã"äãå!Â"âáÉã"äã"âË~À>2ÐÉã"äã"âËvÀ>2ÐÉ>¯ã"äãå!Â"âË®õÍèñ·(ÍááÉ!Ñ~þ8>~O6~*Ò"ÔÍáwþ(6þ(2þ(-þ()þ(6þ (8þ 0þ Ù:Ý·(ÓÝ*äà yº(È~#ÍÉÀúý+Í (±ï(« 6Íá6 #6 #"ÖÉ*â:з y~Ëo pæ .##~·ò—åͺá(å.6á¯w4Æ._~þ =*â##55= *Ôí[Ö·íR8ÿÍê*Ô~#"Ô= Í£}== ͯ}͵}*âËî#w+É#~+É>Éå*â~æþ('Íkþ!0þ(Ë®ñ]ÅÕÍkÑÁþ!8Ë®ï¯áÉÝ!]Ý~·Èþ-ÀÝ#É8Ý~·È>2Ð7ÉåÍkË®áwÉ>¯OÅÍðÁÍ$ÈÅåÍ÷ÑÁÍ6Ø̃ës #rëÉÍðÍ$ÈÅåÍ£ÙáÁÍ6ØÙÌ� ÙÃÑåëÅÕÍkÑÁþ ( þ(Ë® êáqÉÍkþ(Ë®þ ( þ ïÍkþ Ë®É*âO:зÀ~æ ##å~Æ._qá4ð(þ(áÅå=ʦ==Ê©=ʬò*è:ê¾È4^qÉ*â##~·È6ͺÈ>ð2ÐÉ}ÃÆÁÑÅÝ*ÒË|(̓ëëË|( ̓Ý6-Ý#ÕÍÆáÍÈí[ÒÝåá·íRMë‘8( Gå> ÅÍÆÁ÷áAÈ~ÅåÍÆáÁ#óÁÑÙáÑÁÙÅÝ*ÒÕÍ'¾ÁÑÅÍÈËC!¡ ¿!¥¸TRUEFALSEÍÈ!9N#ÍYÑùÕÉá~#·( G~ÅåÍÆáÁ#õé> ÍÆ> ÃÆ   "âË~(ÕÍkÑ»(þ( þ!0 (Ë®è!É!É>¯2èíSæÍz:зÀÍ0:зÀ*â6Ð##ww#w$w#wÖÿ:è· å¯Í á##N#F*æ·íBÈ>�2ÐÉå¯w#w#í[æs#rá>à "â~æÀÈÍ®*â-¯w#wÔÿw##>Í Í®Ã�ã"äã"â~æÀÀ>2ÐÉ:зÀåÍZë·íRá0¯Í *â4À#4É>™2ÐÉ:зÀåÍZ·íR> *â4 #4(>áÍ Èá>ò2ÐÉ2éë*âËf(/˦:éËG(##~++· :éËO x· y·úCÅÕ!ͺÑÁ Q*â:éËG(Ëî##~Æ.Õ_ÑÖ.Íší âf<ò\=<Íš*â##æw ÅÕåÍ®áÑÁ Õ+Ñ4 #4x±Â ëÉ>™>ð2ÐÉõ:éËG(ëñÉ"âÍ®Èæ"*âËæËnÈË®*âåÅ0ëÍÁá ëÍ·ÉÁÑíSâÅåÍZÑ·íR8@*â N#F#s#rÍ, 0}æ)ëíjëS\*â##w+ N#Fë·íB ÈÕåÍ®Ñár+sÉ>‘2ÐÉÕÙáÙ!T]>)ëíjëÙ)Ù0 0= ïÉÍ]·íR!À#ÉÍ]ëÉ*â^#V#ÕN#F#^#VáÉ>¯2èͰ:зÀÍ0:зÀ*â6Àå ë#Íá-¯Nw#FwÖÿq#p#6€#w#w#wÉ"â~æÀÈÃ�>">!DM!ð"æÝáÑáÝåÅÍýÁ:зÀ*ðíBÈ:éþ!>™(>ð2ÐÉ>">!"æÝáÁÑáÝå2é"â~æÀʰ*æ¯w#wx±(9ÅÕÍ*â ë:éOÍÑÁ· Õ*â-4 #4Ñ!€ë*æ4 #4 Ã*â-N#FÚÿq#püÿV+^ë·íBÐëq#pÉÁÑíSâÅåÍZÑ·íRÚ&*â s#r$ s#rÉÍLÀ ëÍ<À?ýá*ÒÍâ¯áýåÍLÀåÍòáåë!\ í°á åëÍÑ<( !\$í°É>2ÐÉ>¯2èÍLÀ:Ø·>!(ë*â \$í°\Í<(Ï!3°í°:è· í[1ðÕÍ\ÍÑ!€ë·(é7"â~æÈ> 2ÐÉ"æíSèëá"âNs#Frë·íB(Zë#\:Ü í°¯üå\ÍÑ<(?*æ"}íKèÅÕÍ\!ÍÑÁ· !*}#"}!€ë x± Û\Í*â éÝ*â>ðÃ) ÍÈþÐ2ÜÉ"ðëáã"ò{æü_!Þ"øÝ*ÞÝnÝf}´(HíR0ÝnÝfåÝ"øÝáã Ý^ÝVÝåMDÝnÝfÝåÝÝuÝtÝqÝpÝåÑ*øs#rÑ*òs#rÉÝåá"Ä*ð ÝåÁ ÚuíKÆíB!Ú0>ÿÃ' ëáã~#fo{æü_ë"ð*ÞåÝá·íR0RÝnÝfå·íR0ÝáðáÕýáíKðýqýpýuýtÝsÝrÝåáÝNÝFÍ( Ý^ÝVÕÝáÝåáÝNÝFÝ^ÝV*ÞíSÞÕÝáÝuÝtíKðÝqÝpë ·íRÀÕýá*Ä·íR(ý~Ýwý~Ýwýnýf ÝuÝt¯ÉÝåá"Ä6#ûÉÍK*ôÉÍK*öÉ!"ô"öÝ*ÞÝNÝFy°(*ô "ô*ö·íB0íCöÝnÝfåÝáØ*Æûÿ í[Ä·íRØë*ô"ô*ö·íRÐíSöÉí[Äs#rÉ^#Vë"Ä"Þ6#ûÉ>¯O"è¯w2Ðx2ê*â"í!F"âá"äá Í&Íy*í"â*äé>¯2ì"è*â"í!F"âá"äá"ê!\Íâ¯*ê:ì· ÍNÍr!Ð~6·go(Ýåá\íRë*ès#r£Æí_2ËÉëÝáÁáx±( s x±(T]í°ÝéDMÝáÑáx±(ôíR0í ë ëí¸ÝéU(Í�ÝáO/o&ÿ9ùq#ë (í°Ýé!€>F¸0#( ~þ (þ #ï]( ~þ (þ (#ï}“(  Õi&TÉÑÁÕ-a%â}ͦoÉ*é!Ð~6o&ÉÍ|µÈ:Ýõ¯2ÝÍ ñ2Ý}þÀÝá:зÈÝá_Ýá_ÕÍzѯ2Ý*Î|µÝåáíKÌíB "η ÕÕåÍÙÑz· Í^C User break+= Í I/OÍ Run-timeÍ error {Í´Í, PC=*ÎͯÍNot enough memoryÍ Program aborted :Ø·ÊŽ'ÃáÑÑé1!ÇÿÍd!å8ÃÿÇ>ÍÔÖ6þÿÿÿ�!½ÃÍýáá"ÅÃ!ÇÃÍâá"GÄýå*GÄå!ÇÃÍ:Ío*GÄÍÿ!åÍñÑÍËEÊŒ!*GÄÍæ}2IÄÓ!!}2IÄ*ÅÃ"½Ã*GÄë*½Ãs#r*½Ãå!ëás*½Ãå!ëás#r*½Ãå!ëás#r*½Ãå!ëás#r*½Ã å!ÇÃÍ:Í*IÄ&Ù�½ÃÃ" !²ÃÍýáá"ºÃá}2¼Ãýå*ºÃå*¼Ã&ëás ²ÃÃ" !¥ÃÍýáá"¯Ãýå*¯Ã"§Ã*§Ãn&å!ÑÍ’ËEÊ"*§Ãn&}2¥Ã*§Ãå!ëásÃÉ#*§Ã^#VëÍæËEʘ"!}2¥ÃÃÉ#*§Ã^#VëÍÜËEÊá"*§Ã^#VëÍ©Í«Í ! }2¥Ã*§Ãå!ëás#r*§Ãå!ëás#rÃÉ#*§Ã^#Vëå!ÑÍÌËEÊ$#! }2¥Ã*§Ãå*§Ã^#Vëå!Ñë·íRëás#rÃÉ#*§Ã^#VëÍ©!¦ÃÍDÍ *¦Ã&}2¥Ã*¥Ã&å! ÑÍ’ËEÊs#*§Ãå*§Ã^#Vëå!Ñëás#rÃÉ#*§Ãå!å*§Ã^#Vëå!ÑÍEÑë·íRëás#r*§Ãå*§Ã^#Vëå*§Ã^#VëÑëás#r! }2¥Ã*¥Ã&}2±Ã*±Ã&Ù ¥ÃÃ"!�ÃÍ!]ÅåÍM INDEX.OUTÍoÍ !]ÅÍþÍ !}2JÄ�ÃÃ" !”ÃÍýáá}2œÃýå*œÃ&å! ÑÍËEÊM$!]ÅͺÍÍÍ Ã|$*œÃ&å!ÑÍËEÊk$!]ÅÍiÍ Ã|$!]Åͺ*œÃ&Í"Í  ”ÃÃ" !ˆÃÍýáá"�Ãá"’ÃýåÍ›ÍÍÍ Í›ͺError in line *�Ã^#Vëå!Í&ͺ of file *�à Í:!ͪÍÍÍ Í›ͺ...Í *’÷íRÂ@%Í›ͺterm must shorter than !cå!Í&ͺ lettersÍ Ãm&·íRÂx%Í›ͺ!term must be printable charactersÍ Ãm&·íR³%Í›ͺ$found nondigit where number expectedÍ Ãm&·íRÂß%Í›ͺpage number too largeÍ Ãm&·íRÂ&Í›ͺimproper range of numbersÍ Ãm&·íRÂ;&Í›ͺtoo many page numbersÍ Ãm&·íRÂm&Í›ͺreading past eof (logic error)Í Í›ͺ"... output file may be incomplete.ÍÍÍ !åÍ$Í›ÍÍÍ ÃÔ  ˆÃÃ"ÃÃ& dè'!xÃÍýáá"†Ãýå*†Ãå!ÑÍàËEÊô&!-åÍ$*†ÃÍ€"†Ã!}2xÃ!å!ÑÍvz³Ê¼'Õ"|Ã!»&å*|Ã+)Ñ^#Vë"zÃ!0}2yÃ*†Ãå!ÑÍÌËEÊY'*yÃ&å!Ñ}2yÃ*†Ãå*zÃÑë·íR"†ÃÃ('*†Ãå!ÑÍàËEʇ'*†Ãå*zÃÑ"†Ã*yÃ&å!Ñë·íR}2yÃ*yÃ&å!0ÑÍÌËEÊ '!}2xÃ*xÃ&ËEʳ'*yÃ&åÍ$*|Ã+ÑÃ'!0å*†ÃÑåÍ$xÃÃ"!jÃÍýáá"tÃá"vÃýå*vÃå!+Ñn&å!ÑÍËEÊ (!å*tÃåÍ…$*vÃå!+Ñn&å! ÑÍ’ËEÊl(*vÃå!+Ñn&å*JÄ&ÑÍ’ËEÊl(*JÄ&å!ÑÍ’ËEÊ[(! åÍ$*vÃå!+Ñn&}2JÄ!}2kÃ*vÃå*kÃ&+Ñn&åÍ$*kÃ&å!Ñ}2kÃ*vÃå*kÃ&+Ñn&å!ÑÍå*kÃ&å!cÑÍÑ}³oËEÊs(*vÃÆ^#Vën&å!ÑÍ’ËEʱ)*vÃÆ^#Vë"lÃ!,åÍ$! åÍ$! åÍ$!å*lÃn&ÑÍfz³Ê±)Õ}2jÃ*jÃ&å!ÑÍÌËEÊ9)!,åÍ$! åÍ$*lÃå*jÃ&+)Ñ^#Vëå͸&*lÃÇå*jÃ&+)Ñ^#Vëå*lÃå*jÃ&+)Ñ^#VëÑÍÌËEʦ)!-åÍ$*lÃÇå*jÃ&+)Ñ^#Vëå͸&*jÃ&#ÑÃ)! åÍ$jÃÃ"!ZÃÍýáá"eÃá"gÃýå!}2\Ã*\Ã&å!Ñ}2\Ã*gÃå*\Ã&+Ñn&}2[Ã*eÃå*\Ã&+Ñn&}2ZÃ*[Ã&å*ZÃ&ÑÍ’å*[Ã&å!ÑÍÑ}³oËEÊÝ)*[Ã&å*ZÃ&ÑÍàËEÊV*!}2iÃÃ{**[Ã&å*ZÃ&ÑÍÌËEÊt*!}2iÃÃ{*!}2iÃ*iÃ&ÙZÃÃ" !PÃÍýáá}2XÃýå*XÃ&å!ÿ  Í]ÍOËEÊÈ**XÃ&å! Ñë·íR}2YÃÃÑ**XÃ&}2YÃ*YÃ&Ù PÃÃ"!<ÃÍýáá"LÃýå*LÃåÍ2"}2CÃ*CÃ&å!-ÑÍ}2BÃ*BÃ&ËEÊ"+*LÃåÍ2"}2CÃ*CÃ&å!! Í]ÍO}îoËEÊH+!å*LÃåÍ…$!Ù!<ÃÍÑ!<ÃÍ,ÅÕå!„ ÙáÑÁÍú ÅÕå*CÃ&å!0Ñë·íRÍÙáÑÁÍé Ù!<ÃÍÑ*LÃåÍ2"}2CÃ*CÃ&å!! Í]ÍO}îoËEÊX+*CÃ&å*LÃåÍ"!<ÃÍ,ÅÕå!�þÙáÑÁÍÖËEÊï+!å*LÃåÍ…$*BÃ&ËEÊ ,!<ÃÍ,xî€GÙ!<ÃÍÑ!<ÃÍ,ÍÞ"NÃ*NÃÙ<ÃÃ"!+ÃÍýáá"8Ãá":Ãýå*8Ãcå!+Ñn&å!ÑÍËEÊa,!å*:ÃåÍ…$*:Ãå*:Ã^#Vëå!Ñëás#r!}2/Ã*:ÃåÍ2"}2-Ã*-Ã&å! ÑÍËEÊà,*/Ã&å!Ñ}2/Ã*8Ãcå*/Ã&+Ñå*-Ã&ëás*8Ãå*/Ã&+Ñå*-Ã&ëás*-Ã&å! ÑÍ’å*/Ã&å!cÑÍÑ}³oËEʆ,*/Ã&å!cÑÍËEÊ!-!å*:ÃåÍ…$*-Ã&å! ÑÍ’ËEÊa,*-Ã&å!ÑÍËEÊÁ-!å!cå!Ñë·íRÑÍfz³Ê˜-Õ}2/Ã*8Ãå*/Ã&+Ñå!ëás*8Ãcå*/Ã&+Ñå!ëás*/Ã&#ÑÃY-*8Ãå!c+Ñå!ëás*8Ãcå!c+Ñå!ëásì0*/Ã&å!Ñ}2/Ã*8Ãå*/Ã&+Ñå*-Ã&ëás*8Ãcå*/Ã&+Ñå*-Ã&åÍŠ*ëás*:ÃåÍ2"}2-Ã*-Ã&å! ÑÍå*8Ãå*/Ã&+Ñn&å! ÑÍÑ}£oå*-Ã&å! ÑÍàÑ}³oå*/Ã&å!cÑÍÑ}³oËEÊÁ-*-Ã&å! ÑÍ’å*-Ã&å! ÑÍ’Ñ}£oËEÊŽ.!å*:ÃåÍ…$*/Ã&å!cÑÍå*-Ã&å! ÑÍ’Ñ}£oËEʽ.!å*:ÃåÍ…$*-Ã&å! ÑÍËEÊÞ.*/Ã&å!Ñ}2/Ã*8Ãå*/Ã&å!Ñë·íR+Ñn&å!,ÑÍËEÊ/*/Ã&å!Ñë·íR}2/Ã*8Ãå*/Ã&+Ñå!ëás*8Ãcå*/Ã&+Ñå!ëás*8ÃÆ^#Vë"0Ã!ë*0Ãs!}2.Ã*-Ã&å! ÑÍËEÊ|/*:ÃåÍ2"}2-ÃÃ\/*-Ã&å! ÑÍ’ËEÊ™0*-Ã&å*:ÃåÍ"*:ÃåÍà*"+Ã*0Ãå*.Ã&+)Ñå*+Ãëás#r*:ÃåÍ2"}2-Ã*-Ã&å!-ÑÍËEÊ0*:ÃåÍà*"+Ã*+Ãå*0Ãå*.Ã&+)Ñ^#VëÑ͸ËEÊ0!å*:ÃåÍ…$*:ÃåÍ2"}2-Ã*0ÃÇå*.Ã&+)Ñå*+Ãëás#r*-Ã&å! ÑÍå*-Ã&å!,ÑÍÑ}³oËEÊj0*:ÃåÍ2"}2-ÃÃ80*.Ã&å!Ñ}2.Ã*.Ã&å!cÑÍËEÊ–0!å*:ÃåÍ…$Ã|/*.Ã&å!Ñë·íRë*0Ãs+ÃÃ"!ÃÍýáá"%Ãá"'Ãá")Ãýå!}2Ã!}2Ã!}2Ã*Ã&å*)Ãn&Ñ͸å*Ã&å*'Ãn&Ñ͸Ñ}£oËEÊÎ3*)Ãå*Ã&+)Ñ^#Vëå*'Ãå*Ã&+)Ñ^#VëÑ͸ËEÊ€2*%Ãå*Ã&+)Ñå*)Ãå*Ã&+)Ñ^#Vëëás#r*)ÃÇå*Ã&+)Ñ^#Vëå*'Ãå*Ã&+)Ñ^#VëÑÍàËEÊÐ1*%ÃÇå*Ã&+)Ñå*)ÃÇå*Ã&+)Ñ^#Vëëás#rÃn2*)ÃÇå*Ã&+)Ñ^#Vëå*'ÃÇå*Ã&+)Ñ^#VëÑÍàËEÊ32*%ÃÇå*Ã&+)Ñå*'ÃÇå*Ã&+)Ñ^#Vëëás#rÃ_2*%ÃÇå*Ã&+)Ñå*)ÃÇå*Ã&+)Ñ^#Vëëás#r*Ã&å!Ñ}2Ã*Ã&å!Ñ}2Ãü3*%Ãå*Ã&+)Ñå*'Ãå*Ã&+)Ñ^#Vëëás#r*'ÃÇå*Ã&+)Ñ^#Vëå*)Ãå*Ã&+)Ñ^#VëÑÍàËEÊ3*%ÃÇå*Ã&+)Ñå*'ÃÇå*Ã&+)Ñ^#Vëëás#rí3*'ÃÇå*Ã&+)Ñ^#Vëå*)ÃÇå*Ã&+)Ñ^#VëÑÍàËEÊr3*%ÃÇå*Ã&+)Ñå*)ÃÇå*Ã&+)Ñ^#Vëëás#rÞ3*%ÃÇå*Ã&+)Ñå*'ÃÇå*Ã&+)Ñ^#Vëëás#r*Ã&å!Ñ}2Ã*Ã&å!Ñ}2Ã*Ã&å!Ñ}2ÃÃã0*Ã&å*)Ãn&Ñ͸ËEÊ\4*%Ãå*Ã&+)Ñå*)Ãå*Ã&+)Ñ^#Vëëás#r*%ÃÇå*Ã&+)Ñå*)ÃÇå*Ã&+)Ñ^#Vëëás#r*Ã&å!Ñ}2Ã*Ã&å!Ñ}2ÃÃÎ3*Ã&å*'Ãn&Ñ͸ËEÊê4*%Ãå*Ã&+)Ñå*'Ãå*Ã&+)Ñ^#Vëëás#r*%ÃÇå*Ã&+)Ñå*'ÃÇå*Ã&+)Ñ^#Vëëás#r*Ã&å!Ñ}2Ã*Ã&å!Ñ}2ÃÃ\4*Ã&å!Ñë·íRë*%Ãs ÃÃ" !ÃÍ!ÔÄå*uÇåÍ#,!KÄå*sÇåÍ#,*uÇå!+Ñn&å!ÑÍàå*sÇå!+Ñn&å!ÑÍàÑ}£oËEÊ'6*uÇcå*sÇcåÍÁ)}2Ã*Ã&·íR—5*uÇå!ÔÄåÍÒ'!ÔÄå*uÇåÍ#,Ã$6·íRÂ6*uÇÆ^#Vëå*sÇÆ^#Vëå*mÇå͵0*uÇÆå*mÇëás#r*uÇå!ÔÄåÍÒ'*uÇÆå*qÇëás#r!ÔÄå*uÇåÍ#,!KÄå*sÇåÍ#,Ã$6·íRÂ$6*sÇå!KÄåÍÒ'!KÄå*sÇåÍ#,Ã%5*uÇå!+Ñn&å!ÑÍàËEÊZ6*uÇå!ÔÄåÍÒ'!ÔÄå*uÇåÍ#,Ã'6*sÇå!+Ñn&å!ÑÍàËEÊ�6*sÇå!KÄåÍÒ'!KÄå*sÇåÍ#,ÃZ6 ÃÃ"Í›ͺ+[index document merge, version of 11/20/86]ÍÍÍ Í›ͺ%[copyright (c) 1986 David E. Cortesi]ÍÍÍ Í›å!ÑÍ’ËEÊ­7Í›ͺ$Command form is: IXMERGE addfilenameÍÍÍ Í›ͺ/Document "addfilename" is merged with INDEX.INPÍÍÍ Í›ͺ to form combined file INDEX.OUT.ÍÍÍ ÃÔ !½ÆåÍM INDEX.INP!ÔÄåÍ?!ËEÊ8Í›ͺ)file INDEX.INP doesn't exist or is empty.ÍÍÍ ÃÔ ! Æå!Í}!KÄåÍ?!ËEÊY8Í›ͺfile !Í}!ͪͺ doesn't exist or is empty.ÍÍÍ ÃÔ Íá#!uÇå!ÈÍå!sÇå!ÈÍå!qÇå!�Íå!oÇå!�Íå!mÇå!�Íå*uÇÆå*qÇëás#r*sÇÆå*oÇëás#r*uÇcå!+Ñå!ëás*sÇcå!+Ñå!ëásÍ5!åÍ$ÃÔ !sÇå!ÈÍå!qÇå!�Íå!oÇå!�program ixmerge; {$I+,R-,A-,B-} {==============================================================} { Book Indexing Assistant, merge utility } {Copyright (C) 1986 David E. Cortesi--see notice in IXMAIN.PAS } { } { This utility merges two index documents as prepared by the } { IXMAIN program -- see it and INDEXER.DOC for further info. } { } { The essential insight that simplifies this program is that it} { doesn't have to make any provision for sub-indexes at any } { level. All it has to do is preserve the initial blanks that } { are used to indent subterms, and include them in comparisons.} { Then subterms always compare "less" versus their own (or any)} { superior terms. Thus once a term-line in a file F has been } { chosen for output because it is less than the current line of} { the other file, any subterms it may have will necessarily } { compare less to the other file as well, and will follow their} { superior to the output automatically. When two lines are } { equal both files are advanced and, if both files had subterms} { for that term, they will be compared and merged. If only one} { file had subterms for that term, they'll all compare "less" } { to the unindented next line of the other file as before. } { } { History: } { insert traps against endless loop & simplify mergem()11/20/86} { fix bug in pagemrg() 11/20/86 } { fix pointer-initialization bugs 11/5/86 } { comments and minor cleanup 11/4/86 } { initial writing 11/3/86 } {==============================================================} const null = 0; { the null, end-of-string } asciibel = 7; { names for ascii characters } asciitab = 9; asciicr = 13; asciieof = 26; asciiblank = 32; asciidel = 127; allowset : set of char = ['a'..'z']; digitset : set of char = ['0'..'9']; maxnests = 9; { allows up to 9 levels of subterms } strmax = 65; { max size of a string, 64 data plus 00} trmmax = 99; {at least strmax+3*maxnests to allow for the indentation spaces, which are retained } maxpages = 99; { most page number (ranges) per term } type relation = (less,equal,more); { result of comparisons } nchar = 0..255; { numeric characters are bytes } trmindex = 1..trmmax; { indices over strings } trmcount = 0..trmmax; { lengths of strings } trm = packed array[trmindex] of nchar; { term as string} pagindex = 1..maxpages; { indices over page numbers } pagcount = 0..maxpages; { counts of page numbers } pages = record { a record of a term's pages } np : pagcount; p1,p2 : array[pagindex] of integer; end; pageptr = ^pages; { pointer to one of those } line = record { record of one file line } t,u : trm; { term as given and uppercase } p : pageptr; { ^list of page numbers } end; lineptr = ^line; filespec = string[127]; filer = record { info about one textfile } pf : ^text; { address of file } pushed : nchar; { pushed-back byte } lineno, { line number for diagnostics } column, { logical column in line } blanks : integer; { blanks owed for last tab seen } fn : filespec; end; var lineA, lineB : lineptr; pageA, pageB, pageM : pageptr; finA, finB, fout : text; { two infiles and an out } frA, frB: filer; {two infiles with associated vars } initial : nchar; {control-break during output } {------ open an input file, return true if any problems ------} function initinp(var f:text; fs:filespec; var fr: filer): boolean; begin {$I- check own I/O results } assign(f,fs); reset(f); if (0 = IOresult) then initinp := eof(f) else initinp := true; with fr do begin pf := Ptr(Addr(f)); pushed := null; lineno := 0; column := 0; blanks := 0; fn := fs; end end; {$I+ back to compiler checks on I/O } {------ push back one byte of input, and damn Borland! for -----} {------ making this necessary by leaving out get/put i/o ------} procedure pushbak(n:nchar; var f:filer); begin f.pushed := n end; {------ return the next byte from the text file inpfile -------} function nextinp(var f: filer) : nchar; var c : char; n : nchar; begin with f do begin if (pushed <> null) then begin n := pushed; pushed := null end else if eof(pf^) then n := asciieof else if eoln(pf^) then begin readln(pf^); n := asciicr; column := 0; blanks := 0 end else if (blanks > 0) then begin n := asciiblank; blanks := blanks - 1; end else begin read(pf^,c); n := ord(c); if (n <> asciitab) then column := column + 1 else begin blanks := 7 - (column mod 8); column := column + blanks; n := asciiblank end end end; {with} nextinp := n end; {------ open the output file ----------------------------------} procedure initout; begin assign(fout,'INDEX.OUT'); rewrite(fout); initial := null; end; {------ write a byte to the output - this is ONLY output ------} procedure nextout(n:nchar); begin if (n = asciicr) then writeln(fout) else if (n = asciieof) then close(fout) else write(fout,chr(n)) end; {------ diagnose an error in the input file and abort ---------} procedure badfile(e:integer; var f: filer); begin writeln; writeln('Error in line ',f.lineno:1,' of file ',f.fn); write('...'); case e of 1 : write('term must shorter than ',trmmax,' letters'); 2 : write('term must be printable characters'); 3 : write('found nondigit where number expected'); 4 : write('page number too large'); 5 : write('improper range of numbers'); 6 : write('too many page numbers'); 7 : write('reading past eof (logic error)'); end; writeln('... output file may be incomplete.'); nextout(asciieof); { close output file } writeln; HALT end; {------ write an integer without a leading blank --------------} procedure intwrite(x : integer); const czero = 48; powten : array[1..4] of integer = (10,100,1000,10000); var k, p : integer; d : nchar; z : boolean; begin if (x < 0) then begin nextout(ord('-')); x := abs(x) end; z := false; { n.b. integer division is VERY slow in 8-bit turbo } { yes, slower than 5 adds and 5 subtracts } for k := 4 downto 1 do begin p := powten[k]; d := czero; while (x > 0) do begin d := d + 1; x := x - p end; if (x < 0) then begin x := x + p; d := d - 1 end; if (d > czero) then z := true; if (z) then nextout(d) end; nextout(czero+x) end; {---- write the contents of one line to the output file, ------} {---- first the term and then the list of numbers if any. -----} {---- Insert a null line if this is a change of initials at ---} {---- the left margin. ----------------------------------------} procedure putline(var l:line; var f:filer); var j : trmindex; n : pagcount; begin if (l.t[1] = asciidel) then badfile(7,f); if (l.t[1] <> asciiblank) then { chk only at level 0 } if (l.t[1] <> initial) then begin { is control brk } if (initial <> null) then { isn't first time } nextout(asciicr); initial := l.t[1] end; j := 1; repeat nextout(l.t[j]); j := j+1 until ((l.t[j] = null) or (j = trmmax)); if (l.p^.np <> 0) then with l.p^ do begin nextout(ord(',')); nextout(asciiblank); nextout(asciiblank); for n := 1 to np do begin if (n > 1) then begin nextout(ord(',')); nextout(asciiblank) end; intwrite(p1[n]); if (p2[n] > p1[n]) then begin nextout(ord('-')); intwrite(p2[n]) end end {for} end; {with} nextout(asciicr) end; {--- compare two terms returning less, equal, or more -------} function trmcomp(var ta,tb: trm) : relation; var j : trmcount; a,b : nchar; begin j := 0; repeat j := j+1; a := ta[j]; b := tb[j] until ((a <> b) or (a = null)); if (a < b) then trmcomp := less else if (a > b) then trmcomp := more else trmcomp := equal end; {--- return uppercase form of a letter ------------------------} function upcase(n:nchar):nchar; begin if (chr(n) in allowset) then upcase := n-32 else upcase := n end; {------ read and collect one signed integer, assuming that ----} {------ there should be a number coming next from nextinch ----} function getpage(var f: filer):integer; var n : nchar; s : boolean; x : real; begin n := nextinp(f); s := n = ord('-'); if (s) then n := nextinp(f); if (not (chr(n) in digitset)) then badfile(3,f); x := 0.0; repeat x := (x * 10.0) + (n - ord('0')); n := nextinp(f); until (not (chr(n) in digitset)); pushbak(n,f); if (x > 32767.0) then badfile(4,f); if (s) then x := -x; getpage := trunc(x) end; {--- get a line of text from the given index document and -----} {--- separate it into a term-string "and series of binary ------} {--- page numbers. store the term in lowercase and uppercase -} {--- forms for quick comparisons. Store eof as a "term" of ---} {--- asciidel so as to compare high to all legitimate terms ---} procedure getline(var f: filer; var l:line); var j: trmcount; k:pagcount; n: nchar; i : integer; begin if (l.u[1] = asciidel) then badfile(7,f); repeat { read and skip null lines. stop on nonnull term or eof } f.lineno := f.lineno + 1; j := 0; repeat {read and store initial blanks up to term, cr, or eof} n := nextinp(f); if (n = asciiblank) then begin j := j+1; l.u[j] := n; l.t[j] := n end until ((n <> asciiblank) or (j = trmmax)); if (j = trmmax) then badfile(1,f); { here n is either cr, eof, or a graphic } until (n <> asciicr); { loop on n=cr case } { here n is either eof or a graphic } if (n = asciieof) then begin { create 'infinity' at eof} for j := 1 to trmmax-1 do begin l.t[j] := asciidel; l.u[j] := asciidel end; l.t[trmmax] := null; l.u[trmmax] := null end else begin { n contains first byte of term, j is count of blanks } repeat j := j+1; l.t[j] := n; l.u[j] := upcase(n); n := nextinp(f) until ( ((n = asciiblank) and (l.t[j] = asciiblank)) or (n < asciiblank) or (j = trmmax)); if ((n <> asciiblank) and (n <> asciicr)) then badfile(2,f); { unknown control character } if ((j = trmmax) and (n <> asciiblank)) then badfile(1,f); { line too long } if (n = asciicr) then j := j+1; if (l.t[j-1] = ord(',')) then j := j-1; l.t[j] := null; {terminate the terms} l.u[j] := null; with l.p^ do begin np := 0; k := 1; while (n = asciiblank) do n := nextinp(f); while (n <> asciicr) do begin { n is neither blank nor cr, s.b. digit } pushbak(n,f); { put it back for getpage } i := getpage(f); p1[k] := i; n := nextinp(f); if (n = ord('-')) then begin i := getpage(f); if (i <= p1[k]) then badfile(5,f); n := nextinp(f) end; p2[k] := i; { n = byte after last digit: cr, comma, or blank } while ( (n = asciiblank) or (n = ord(',')) ) do n := nextinp(f); k := k + 1; if (k = maxpages) then badfile(6,f) end; np := k - 1 end {with} end { else not end of file } end; {--- merge two arrays of page numbers to make a third, allowing } {--- for ranges of page numbers. -------------------------------} procedure pagemrg(var a,b,m: pages); var i,j,k :pagcount; begin i := 1; j := 1; k := 1; while ( (i <= a.np) and (j <= b.np) ) do begin if (a.p1[i] <= b.p1[j]) then begin m.p1[k] := a.p1[i]; if (a.p2[i] < b.p1[j]) then {a less & disjoint} m.p2[k] := a.p2[i] else begin { a less or equal but not disjoint } if (a.p2[i] < b.p2[j]) then m.p2[k] := b.p2[j] else m.p2[k] := a.p2[i]; j := j+1 end; i := i + 1 end else begin { b.p1 < a.p1 } m.p1[k] := b.p1[j]; if (b.p2[j] < a.p1[i]) then { b less & disjoint} m.p2[k] := b.p2[j] else begin { b less but not disjoint } if (b.p2[j] < a.p2[i]) then m.p2[k] := a.p2[i] else m.p2[k] := b.p2[j]; i := i + 1 end; j := j + 1 end; k := k + 1 end; while (i <= a.np) do begin m.p1[k] := a.p1[i]; m.p2[k] := a.p2[i]; k := k + 1; i := i + 1 end; while (j <= b.np) do begin m.p1[k] := b.p1[j]; m.p2[k] := b.p2[j]; k := k + 1; j := j + 1 end; m.np := k-1; end; {-- merge the two input files to the output file --------------} procedure mergem; var r: relation; begin getline(frA,lineA^); getline(frB,lineB^); while ((lineA^.t[1] < asciidel) and (lineB^.t[1] < asciidel)) do begin r := trmcomp(lineA^.u,lineB^.u); case r of less: begin putline(lineA^,frA); getline(frA,lineA^) end; equal: begin pagemrg(lineA^.p^,lineB^.p^,pageM^); lineA^.p := pageM; putline(lineA^,frA); lineA^.p := pageA; getline(frA,lineA^); getline(frB,lineB^) end; more: begin putline(lineB^,frB); getline(frB,lineB^) end end {case} end {while}; while (lineA^.t[1] < asciidel) do begin putline(lineA^,frA); getline(frA,lineA^) end; while (lineB^.t[1] < asciidel) do begin putline(lineB^,frB); getline(frB,lineB^) end end; {==============================================================} { The main program, at last..... } {==============================================================} begin writeln('[index document merge, version of 11/20/86]'); writeln('[copyright (c) 1986 David E. Cortesi]'); if (Paramcount <> 1) then begin writeln('Command form is: IXMERGE addfilename'); writeln('Document "addfilename" is merged with INDEX.INP'); writeln('to form combined file INDEX.OUT.'); Halt end; if (initinp(finA,'INDEX.INP',frA)) then begin writeln('file INDEX.INP doesn''t exist or is empty.'); Halt end; if (initinp(finB,Para#mStr(1),frB)) then begin writeln('file ',ParamStr(1), ' doesn''t exist or is empty.'); Halt end; initout; new(lineA); new(lineB); new(pageA); new(pageB); new(pageM); lineA^.p := pageA; lineB^.p := pageB; lineA^.u[1] := null; lineB^.u[1] := null; mergem; nextout(asciieof); {close output file} end. ===========================} { The main program, at last..... } {==============================================================} begin writeln('[index document merge, version of 11/20/86]'); writeln('[copyright (c) 1986 David E. Cortesi]'); if (Paramcount <> 1) then begin writeln('Command form is: IXMERGE addfilename'); writeln('Document "addfilename" is merged with INDEX.INP'); writeln('to form combined file INDEX.OUT.'); Halt end; if (initinp(finA,'INDEX.INP',frA)) then begin writeln('file INDEX.INP doesn''t exist or is empty.'); Halt end; if (initinp(finB,Para This is the release date of the disk. IXSTRG PAS €W€IXTEXT PAS €]€ IXTREE PAS €a€IXWALK PAS €f€INDEXER DOC Àj€båNDEXER DOC z€"ABSTRACT €ƒIXMERGE COM €„8IXMERGE PAS €’€9ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååIXDIAG .PAS 82 41 1408 11 IXDOIT .PAS 98 22 9984 78 IXDONE .PAS EF 02 3456 27 IXINIT .PAS BA 1D 5120 40 IXSTRG .PAS CC E9 5504 43 IXTEXT .PAS 65 E1 3456 27 IXTREE .PAS CF 6E 4736 37 IXWALK .PAS E0 39 3968 31 INDEXER .DOC 41 96 25216 197 ABSTRACT. 7F 29 512 4 IXMERGE .COM F3 F0 14336 112 IXMERGE .PAS 8C 99 14720 115  Fog Library Disk FOG-CPM.151 Copyright (1987) by Fog International Computer Users Group to the extent not copyrighted by the original author for the exclusive use and enjoyment of its members. Any reproduction or distribution for profit or personal gain is strictly forbidden. For information, contact FOG, P. O. Box 3474, Daly City, CA. 94015-0474. as part of the description of a file indicates that the program is distributed on a "try first, pay if you like it" basis. If you find the program(s) meet your need, please refer to the author's documentation for information on becoming a registered user. Only by registering and paying for the programs you like and use will the authors of such programs continue development. Often, more complete documentation, additional modules, and new releases are available only to registered users. Word processing and WordStar companion utilities. Filename Description -01-00 .87 This is the release date of the disk. -CPM151 .DOC This is the description of the disk contents. ANYCODE .ASM 0A39 3K [ANYCODE 1 of 2] ASseMbler source code for patch which allows you to send any character to your printer from within WordStar. ANYCODE .DOC 932C 20K [ANYCODE 2 of 2] CHGCHAR .COM 8957 1K [Change Character 1 of 3] Will change any character in a file to any other character. Works with ASCII or hexidecimal characters. Squeezed ASseMbler source code is included. CHGCHAR .DOC C2DC 5K [Change Character 2 of 3] CHGCHAR .AQM 13C4 4K [Change Character 3 of 3] DBL .COM D7E3 4K [Double 1 of 2] Prints your text in column format and gives you control over format and print size. DBL .DOC 4385 1K [Double 2 of 2] IXMAIN .COM B29F 19K [Indexer 1 of 14] Program to help you index a book. Includes module which merges two index files and Turbo Pascal source code. IXMAIN .PAS EAEE 6K [Indexer 2 of 14] IXDIAG .PAS 8241 2K [Indexer 3 of 14] IXDOIT .PAS 9822 10K [Indexer 4 of 14] IXDONE .PAS EF02 4K [Indexer 5 of 14] IXINIT .PAS BA1D 5K [Indexer 6 of 14] IXSTRG .PAS CCE9 6K [Indexer 7 of 14] IXTEXT .PAS 65E1 4K [Indexer 8 of 14] IXTREE .PAS CF6E 5K [Indexer 9 of 14] IXWALK .PAS E039 4K [Indexer 10 of 14] INDEXER .DOC 4196 25K [Indexer 11 of 14] ABSTRACT. 7F29 1K [Indexer 12 of 14] IXMERGE .COM F3F0 14K [Indexer 13 of 14] IXMERGE .PAS 8C99 15K [Indexer 14 of 14]  [ANYCODE 2 of 2] CHGCHAR .COM 8957 1K [Change Character 1 of 3] Will change any character in a file to any other character. Works with ASCII or hexidecimal characters$ååååå%ååååå&ååååå'ååååå