÷ƒ’À;è TeX output 1996.03.06:1251‹ÿÿÿÿ ª ýs’¦ÿÿóKñ`y cmr10²1ŽŽ o ýÞ’W-óDÓítG®G®cmr17¹T‘þ¥Vext–7tmerges“in“T‘ý[™Ÿ¸-EŽ›;gX“and“LŸüdú‘úKGóX«Q cmr12ºAŽŽ‘¹”¹T‘ý[™Ÿ¸-EŽ˜XŸùº¯ó!",š cmsy10¾ŽŽŽŸ’âëùºMik¬re‘ê¨Pi ŽŽŽŽŽŸˆ‹’ÕòiMarc¬rh–ê¨6,“1996ŽŸ.’æ!Kót ‰: cmbx9ÆAbstractŽŸ¬Ñ‘oßüóo´‹Ç cmr9ÅIn–Xlthis“article“the“author“explains“ho¾9w“to“do“some“standard“and“notŽ¤ ‘bso–aÉstandard“w¾9ord“prošAÇcessor“text“merges“in“T‘þuAŸïÿEŽ‘˜ŸX“do˜cumen¾9ts,‘tæusing“no“otherŽ¡‘btoAÇols–rthan“T‘þuAŸïÿEŽ‘˜ŸX“itself.‘2ºA‘qÿcommon“application“is“to“the“mail“merge“or“formŽ¡‘bletter,›®‰where–ånames“and“addresses“are“stored“in“a“ le,˜together“with“otherŽ¡‘bbits–m of“information,‘ƒand“a“standard“letter“with“v‘ÿ|rariable“ elds“em¾9bAÇedded“inŽ¡‘bit– ¶is“customized“for“ev¾9ery“name“from“this“ le.‘‘Another“application“is“to“theŽ¡‘bprett•¾9y-prin“ting–Tof“the“con•¾9ten“ts–Tof“a“database.Ž¡‘oßüThe–AAmacros“describšAÇed“in“óߤN cmtt9Çtextmerg.sty“Åw¾9ork“equally“in“b˜oth“plain“T‘þuAŸïÿEŽ‘˜ŸXŽ¡‘band› ²LŸýó5‘ü«‡ó¹Aa¨cmr6ÀAŽŽ‘© ÅT‘þuAŸïÿEŽ‘˜ŸX.‘>‰Ho•¾9w“ev“er,‘#‰this˜has˜mean“t˜hea“vy˜use˜of˜Ç\def˜Åwhere˜Ç\newcommandŽ¡‘bÅw•¾9ould›Tha“v“e˜bAÇeen˜preferable.Ž©!Ä‘Ió ÂÖN ff cmbx12ËCon•ŒÌten“tsŽ¤‘Ió!ò"V cmbx10Ì1Ž‘XIn®9troQÇduction’Øú1ŽŽ¡‘I2Ž‘XA–ÕTsimple“example’ôZq2ŽŽ¡‘I3Ž‘XA–ÕTfew“complications’舯3ŽŽ¡‘I4Ž‘XA–ÕTcomplicated“example’ØwH5ŽŽ¡‘I5Ž‘XIden®9ti cation’ ˜ý7ŽŽ¡‘I6Ž‘XImplemen®9tation–ÕTof“the“simple“case’¡AQ8ŽŽ¡‘I7Ž‘XImplemen®9tation–ÕTof“merged“tables’¡±ª10ŽŽ¡‘I8Ž‘XThe–ÕTdoQÇcumenš®9tation“driv˜er“ le’±©13ŽŽ¦‘IË1Ž‘aLËInŒÌtros3ductionŽŸç‘I²It–`is“often“said“that“although“LŸýó5‘üffóÙ“ Rcmr7±AŽŽ‘͉²T‘þU>Ÿ'EŽ‘ãxX“is“go•Go“d–`at“t¸ãypGesetting“mathematics,‘‘$it“is“whollyŽ¤ ‘Iunsuitable–e»for“common“wš¸ãord“proGcessor“functions“suc˜h“as“mail“merges.‘¢ùThe“latterŽ¡‘Iare–ñêeasy“to“ac•¸ãhiev“e–ñêin“most“ordinary“wš¸ãord“proGcessors,‘Íbut“in“its“ra˜w“state“LŸýó5‘üff±AŽŽ‘͉²T‘þU>Ÿ'EŽ‘ãxX“isŽ¡‘Iincapable–t¨of“doing“a“mail“merge,–|}or,“indeed,“of–t¨generating“the“same“bloGc¸ãk“of“textŽ¡‘Io•¸ãv“er–ùand“o•¸ãv“er–ùagain“but“with“di erenš¸ãt“parameters“in“eac˜h“bloGc˜k,‘ those“parametersŽ‘IŸX-‰ffÿrŸ @‘ ÷ˆŸý-:óq¡% cmsy6ÄŽŽ‘LÜó|{Ycmr8¿This–ÕXarticle“originally“appšŸ'EŽ‘ãxX,‘·9it“is“p˜ossible“to“hide“man¸ãy“details“of“aŽ¡‘Ifacilitš¸ãy–úÿinside“a“subsidiary“st˜yle“ le,‘$jso“that“the“user“is“una˜w˜are“of“what“fearfulŽ¡‘IprošGcesses–‹Œare“going“on“in“the“bac¸ãkground.‘kIt“is“then“p˜ossible“to“presen¸ãt“the“end-Ž¡‘Iuser–7°with“an“extremely“simple“in¸ãterface,‘=žpšGerhaps“simpler“and“more“p˜o•¸ãw“erful‘7°thanŽ¡‘Iis–UUa¸ãv‘ÿqÇailable“in“other“systems.Ž¡‘XIn–Æsearlier“TUGbGoat“articles“[Bel87Ž‘N=,“Gar87Ž‘Š,“Lee86Ž‘ê,“McK87Ž‘#*]“it“wš¸ãas“sho˜wn“ho˜wŽ¡‘Ia–»?standard“letter“could“bGe“customized“b¸ãy“adding“names“and“addresses“from“aŽ¡‘Iseparate–‚ le.‘úI‘‚¶aim“to“shoš¸ãw“that“it“is“pGossible“to“ac˜hiev˜e“far“more“than“this“withŽ¡‘Ia–UUfairly“compact“but“general“set“of“macros.ŽŸ!Ä‘IË2Ž‘aLËA–ffsimple“exampleŽŸç‘I²SuppGose– 0that“wš¸ãe“ha˜v˜e“a“list“of“studen˜t“names“and“examination“grades,‘Rçone“pGerŽ¡‘Istudenš¸ãt,‘.eand–üthat“w˜e“wish“to“send“a“letter“to“eac˜h“studen˜t“giving“his/her“examŽ¡‘Igrade.‘OW‘ÿ*ªe–Iòmš¸ãust“decide“ rst“what“bits“of“information“m˜ust“bGe“prepared“in“ourŽ¡‘Isubsidiary–µQ le,‘ÕRbš¸ãy“loGoking“at“an“example“letter“and“ nding“out“whic˜h“items“c˜hangeŽ¡‘Ifrom–UUletter“to“letter.Ž¡‘XSuppGose–UUthat“one“instance“of“our“letter“is“the“follo¸ãwing,“a“LŸýó5‘üff±AŽŽ‘͉²T‘þU>Ÿ'EŽ‘ãxX“example.Ž©‘IÇ\begin{letter}{Miss–¹–Iusta“Mo\\Ž¤ ‘W,Â34–¹–Winchester“Road\\Ž¡‘W,ÂSheffield\\Ž¡‘W,ÂEngland}Ž¡‘W,Â\opening{Dear–¹–Miss“Mo,}Ž¡‘W,ÂThis–¹–letter“is“to“inform“youŽ¡‘W,Âthat–¹–you“obtained“grade“A“inŽ¡‘W,Âyour–¹–recent“examinations.Ž¡‘W,Â\closing{Yours‘¹–faithfully,}Ž¡‘I\end{letter}ŽŸ‘I²W‘ÿ*ªe–kêcan“see“that“wš¸ãe“need“to“kno˜w“the“studen˜t's“title,–ššforename(s),“surname,“addressŽ¤ ‘Iand–UUgrade“to“compGose“suc¸ãh“a“letter.Ž¡‘XOne–a¦of“the“simplest“w•¸ãa“ys–a¦of“ac¸ãhieving“this“e ect“is“to“prepare“a“ le“with“linesŽ¡‘Iof–UUthe“formŽ¦‘IÇ\MyLetter{Mr}...{C}ŽŸ‘I²for–g®eacš¸ãh“studen˜t“and“then“simply“ó#ßêŸ'EŽ‘ãxX“ le“in“whic˜h“Î\MyLetterŽ¡‘I²has–¬¶bGeen“de ned“as“haš¸ãving“ v˜e“parameters.‘wêA‘¬^problem“with“this“approac˜h“isŽ¡‘Ithat–ºgwš¸ãe“ma˜y“not“bGe“able“to“coax“the“studen˜t“database“in˜to“proGducing“suc˜h“aŽ¡‘I le.‘šþAnother–cproblem“is“that“wš¸ãe“need“something“more“subtle“if“there“are“ ft˜yŽ¡‘Iparameters.‘jðF‘ÿ*ªor–@Ïexample,‘Déwš¸ãe“migh˜t“w˜an˜t“to“prin˜t“out“the“con˜ten˜ts“of“the“studen˜tŽ¡‘Idatabase–}íwith“one“page“pšGer“studen¸ãt,‘©but“it“could“b˜e“that“there“are“ ft¸ãy“informationŽ¡‘I elds–ÒpGer“studen•¸ãt.‘èEv“en›Òw“orse,‘ñDthe˜n“um“b•Ger˜of˜pieces˜of˜information˜p“er˜studen¸ãtŽ¡‘Imighš¸ãt–Ènot“bGe“a“constan˜t“n˜um˜b•Ger,›ä¿b“ecause,˜sa•¸ãy‘ÿ*ª,˜w“e–Èare“prin¸ãting“out“ elds“from“aŽ¡‘Irelated–UU le“in“whic¸ãh“marks“on“individual“examination“papGers“are“held.Ž¡‘XW‘ÿ*ªe–¨shall“tacš¸ãkle“our“simple“example“in“a“w˜a˜y“that“lends“itself“to“more“generalit˜yŽ¡‘Ilater–\òon,‘ŽŸand“in“a“form“that“most“database“programs“should“bGe“capable“of“handling.ŽŽŸ’ø2ŽŽŒ‹ o ª ýs o ý´‘X²W‘ÿ*ªe–'cthš¸ãus“prepare“a“subsidiary“ le“Îresults.dat“²with“records“of“ v˜e“ elds“in“it.Ž© ‘IEac•¸ãh›UUstuden“t˜is˜represen“ted˜b“y˜ v“e˜lines˜of˜this˜ le,ŽŸ‘Lüs±1Ž‘Sª®ó©±Ê cmsy9Éhó$ÒoÇw cmss9ÏresultsŽ‘PLÉiŽ¤ ‘Lüs±2Ž‘Sª®ÇMissŽ¡‘Lüs±3Ž‘Sª®ÇIustaŽ¡‘Lüs±4Ž‘Sª®ÇMoŽ¡‘Lüs±5Ž‘Sª®Ç34–¹–Winchester“Road\\Sheffield\\EnglandŽ¡‘Lüs±6Ž‘Sª®ÇAŽ¡‘Lüs±7Ž‘Sª®ÇMrŽ¡‘Lüs±8Ž‘Sª®ÇArthurŽ¡‘Lüs±9Ž‘Sª®ÇMinitŽ¡‘I±10Ž‘Sª®Ç43–¹–Sheffield“Road\\Winchester\\EnglandŽ¡‘I±11Ž‘Sª®ÇCŽ¡‘I±12Ž‘Sª®Éhó5ùž" cmmi9È=ÏresultsŽ‘PLÉiŽŸ‘I²and–\áthe“studenš¸ãt“records“appGear“one“after“another“in“this“ le.‘ˆjTh˜us“bGoth“the“ eldŽ¦‘Iand–UUrecord“separators“are“carriage“returns.Ž¦‘XT‘þU>Ÿ'EŽ‘ãxX–UUitself“needs“to“kno¸ãw“three“bits“of“information:Ž‘!¦|Ç\MergeŽŽŽŽ¦‘ìæ\FieldsŽŽŽŽ¤‘U8ä²1.ŽŽŽ‘bthe–UUname“of“the“subsidiary“ le,Ž¡‘U8ä2.ŽŽŽ‘bthe–UU elds“to“read,“andŽ¡‘U8ä3.ŽŽŽ‘bthe–UUtemplate“of“the“letter.Ž¡‘IW‘ÿ*ªe–UUpass“it“this“information“in“the“follo¸ãwing“formŽŸ‘I±13Ž‘Sª®ÉhÏexampŽ‘‘·ÉiŽ¤ ‘I±14Ž‘Sª®Ç\documentclass[12pt]{letter}Ž¡‘I±15Ž‘Sª®Ç\usepackage{textmerg}Ž¡‘I±16Ž‘Sª®Ç\begin{document}Ž¡‘I±17Ž‘Sª®Ç\Fields{\Title\Forenames\SurnameŽ¡‘I±18Ž‘a×pÇ\Address\Grade}Ž¡‘I±19Ž‘Sª®Ç\Merge{results.dat}{%Ž¡‘I±20Ž‘Sª®Ç\begin{letter}{\Title\‘¹–\Forenames\Ž¡‘I±21Ž‘a×pÇ\Surname\\\Address}Ž¡‘I±22Ž‘a×pÇ\opening{Dear–¹–\Title\“\Surname,}Ž¡‘I±23Ž‘a×pÇThis–¹–letter“is“to“inform“youŽ¡‘I±24Ž‘a×pÇthat–¹–you“obtained“grade“\Grade\“inŽ¡‘I±25Ž‘a×pÇyour–¹–recent“examinations.Ž¡‘I±26Ž‘a×pÇ\closing{Yours‘¹–faithfully,}Ž¡‘I±27Ž‘Sª®Ç\end{letter}}Ž¡‘I±28Ž‘Sª®Ç\end{document}Ž¡‘I±29Ž‘Sª®ÉhÈ=ÏexampŽ‘‘·ÉiŽŸ‘I²LŸýó5‘üff±AŽŽ‘͉²T‘þU>Ÿ'EŽ‘ãxX–½‘should“opGen“the“subsidiary“ le“and,‘Ûëfor“eacš¸ãh“set“of“ v˜e“parameters,‘ÛëgenerateŽ¦‘Ia–¿[letter“in“the“Îdvi“² le.‘¯ØWhen“it“reac¸ãhes“the“end“of“the“merge“ le,‘ÙÜLŸýó5‘üff±AŽŽ‘͉²T‘þU>Ÿ'EŽ‘ãxX“shouldŽ¦‘Iterminate–£‹execution“of“the“Î\Merge“²command“and“presumably“ nish“the“doGcumen¸ãt.ŽŸ!Ä‘IË3Ž‘aLËA–fffew“complicationsŽŸç‘I²LošGoking–ùat“the“ab˜o•¸ãv“e–ùexample“in“a“bit“more“generalit•¸ãy‘ÿ*ª,‘ èw“e–ùsee“that“w¸ãe“are“readingŽ¦‘Irecords–eŠof“ó  b> cmmi10µn“² elds“from“the“merge“ le“and“placing“them“inš¸ãto“a“T‘þU>Ÿ'EŽ‘ãxX“doGcumen˜tŽ¦‘Iin–£¡sucš¸ãh“a“w˜a˜y“that“they“replace“µn“²preassigned“con˜trol“sequences.‘\«Ho˜w˜ev˜er,‘÷4itŽ¦‘Imaš¸ãy–Z&happGen“that“the“merge“ le“is“prepared“b˜y“h˜umans,‘[[who“migh˜t“pGossibly“ha˜v˜eŽŽŸ’ø3ŽŽŒ‹d ª ýs o ý´‘I²inserted–\Ssome“extra“blank“lines“in¸ãto“the“ le.‘†ÁAgain,‘^it“could“bGe“that“certain“sortsŽ¤ ‘Iof–Qˆ elds“mighš¸ãt“bGe“blank,‘RJwhereas“others“can“nev˜er“bGe“blank.‘pƒP˜erhaps“it“w˜ould“bGeŽ¡‘IbGetter–UUto“build“in“some“degree“of“error“reco•¸ãv“ery‘ÿ*ª.Ž¡‘XW‘ÿ*ªe–#‹shall“makš¸ãe“the“assumption“that“the“ rst“ eld“in“an˜y“record“is“de nitelyŽ‘ìæÇ\FieldsŽŽŽŽ¡‘I²a–ŽÁnon-blank“one“and“that“wš¸ãe“kno˜w“bGeforehand“whether“eac˜h“of“the“others“migh˜tŽ¡‘Iconceiv‘ÿqÇably–hâbšGe“blank.‘¬nW‘ÿ*ªe“mak¸ãe“a“mo˜di cation“to“our“Î\Fields“²statemen¸ãt.‘¬nIt“canŽ¡‘Iconš¸ãtain–;knot“only“the“ eld“name“con˜trol“sequences“but“also“the“tok˜ens“Î+“²and“Î-²,Ž¡‘Iwith–7Õthe“folloš¸ãwing“in˜terpretation.‘gòA‘7ÍÎ+“²indicates“that“all“follo˜wing“ elds“should“bGeŽ¡‘Ire-read–Å0unš¸ãtil“a“non-blank“result“is“obtained.‘A»A‘Å Î-“²indicates“that“an˜y“follo˜wing“ eldsŽ¡‘Icould–[conceiv‘ÿqÇably“bGe“blank,‘1\sub‘Ž8ject“to“the“restriction“that“the“v¸ãery“ rst“ eld“isŽ¡‘Ialw•¸ãa“ys‘UUnon-blank.Ž¡‘XTh¸ãus–UUthe“commandŽ©‘IÇ\Fields{\a+\b\c-\d}ŽŸ‘I²wš¸ãould–indicate“that“only“Î\d“²is“allo˜w˜ed“to“bšGe“blank,‘1b˜ecause“the“Î+“²tok¸ãen“has“noŽ¡‘Ie ect.‘qÇInŽ¦‘IÇ\Fields{-\a\b+-\c+\d}ŽŸ‘I²the–úÿinitial“Î-“²tokš¸ãen“enables“blank“reading“of“data“tok˜ens,‘$jbut“the“v˜ery“ rst“dataŽ¡‘Itok¸ãen–8Œis“not“pšGermitted“to“b˜e“blank“an•¸ãyw“a“y‘ÿ*ª.‘h/Th“us–8ŒÎ\a“²is“read“as“a“non-blank“tok¸ãenŽ¡‘Iand–oEÎ\b“²as“a“pGossibly“blank“tokš¸ãen.‘%The“sequence“Î+-“²no˜w“switc˜hes“non-blank“readingŽ¡‘Ion–UUand“o “again,“so“Î\c“²is“read“as“pGossibly“blank.‘qÇFinally“Î\d“²is“non-blank.Ž¡‘XAnother–/0complication“wš¸ãe“allo˜w“is“that“the“Î\Fields“²command“can“appGear“sev-Ž¡‘Ieral–ô%times“in“our“ le.‘N7The“in¸ãterpretation“is“that“the“last“oGccurrence“of“Î\FieldsŽ¡‘I²bGefore–ãwš¸ãe“encoun˜ter“the“Î\Merge“²command“will“indicate“the“ elds“to“bGe“read“forŽ¡‘Iev•¸ãery›T³record.‘q‘An“y˜oGccurrences˜of˜Î\Fields˜²within˜the˜merged˜text˜indicate˜a˜newŽ¡‘Ilist–[.of“ elds“to“bGe“read“when“that“command“is“encoun¸ãtered.‘ƒRThis“lets“us“do“someŽ¡‘Iconditional–UUproGcessing,“suc¸ãh“asŸü^ÿ±1ŽŽŽ¦‘W,ÂÇ\ifx\Title\MrsŽ¤ ‘eY„\Fields{\MaidenName}Ž¡‘W,Â\fiŽŸ‘I²and–UUalso“givš¸ães“us“some“ exibilit˜y“abGout“the“ eld“order“later“on.Ž¤ ‘XIt–¼should“also“bšGe“stressed“that“the“unde ned“con¸ãtrol“sequences“app˜earing“inŽ¡‘Ithe–ª.template“need“not“correspGond“exactly“to“the“ elds“in“the“subsidiary“ le.‘pSAnŽ¡‘Iexample–UUmighš¸ãt“bGe“that“the“subsidiary“ le“con˜tains“the“textŽ¦‘IÇSpriggs,–¹–Mr“Abraham“LŽŸ‘I²and–¤ûone“ eld“read“is“Î\FullName².‘`ºT‘þU>Ÿ'EŽ‘ãxX“wš¸ãould“then“ha˜v˜e“to“pre-proGcess“this“nameŽ¡‘Ito–‡¥generate“its“sevš¸ãeral“compGonen˜ts“as“used“in“the“template.‘ ¸The“commandŽ¡‘IÎ\PreProcess–UU²could“bGe“included“at“the“start“of“the“template.Ž¦‘IÇ\def\parse#1,–¹–#2“#3\endparse{%Ž¤ ‘W,Â\def\Surname{#1}\def\Title{#2}%Ž¡‘W,Â\def\Forenames{#3}}Ž¡‘I\def\PreProcess{\expandafterŽ¡‘W,Â\parse\FullName\endparse}Ž‘IŸff‰ffÿrŸ J=‘ "5Ÿý-:À1ŽŽŽ‘LÜ¿It–ÕXis“assumed“that“ó*ßCÊscmtt8Õ\Mrs“¿expands“to“ÕMrs¿.ŽŽŸ’ø²4ŽŽŒ‹# ª ýs o ý´‘X²An–4»alternativš¸ãe“and“simpler“loGoking“approac˜h“to“reading“ elds“from“a“ le“Î\filŽ¤ ‘I²mighš¸ãt–UUbGe“to“de ne“eac˜h“suc˜h“ eld“as“follo˜ws.Ž©‘IÇ\def\Field#1{\def#1{\read\fil‘¹–to#1#1}}ŽŸ ‘I\Field\Name–¹–\Field\Address“\Field\MarkŽŸ‘I²The–{ rst“time“Î\Name“²is“encounš¸ãtered,‘ªAit“reads“its“o˜wn“expansion“from“Î\fil“²and“thenŽ¡‘Iexpands–Âitself.›@²Henceforth,‘߉it“has“acquired“its“new“expansion.˜The“disadv‘ÿqÇan¸ãtage“isŽ¡‘Ithat–k7Î\Name“²m¸ãust“appšGear“in“the“text“b˜efore“anš¸ãy“subsidiary“ eld“suc˜h“as“Î\SurnameŽ¡‘I²can–UUbGe“used.Ž¡‘XFinally–ÅÏwš¸ãe“should“consider“the“pGossibilit˜y“that“the“second“parameter“of“Î\MergeŽ¡‘I²migh¸ãt–GbšGe“to˜o“large“to“ t“inš¸ãto“memory–ÿ*ª.‘GW“e–Gcan“clearly“handle“this“problem“b˜yŽ¡‘Iallo¸ãwing–¶the“second“parameter“merely“to“consist“of“the“text“Î\input‘?ýtemplate²,‘( soŽ¡‘Ithat–Ûthe“roGot“ le“handles“t•¸ãw“o–Ûsubsidiary“ les,‘ó‹one“con¸ãtaining“the“template“and“theŽ¡‘Iother–UUcon¸ãtaining“the“ elds.ŽŸ!Ä‘IË4Ž‘aLËA–ffcomplicated“exampleŽŸç‘I²W‘ÿ*ªe–¤÷will“next“loGok“at“an“example“in“whicš¸ãh“the“template“con˜tains“a“table“of“inde-Ž¡‘Iterminate–€:length,‘ŠóalbGeit“ xed“width.‘òvSo“far“our“macros“w¸ãork“in“either“plain“T‘þU>Ÿ'EŽ‘ãxXŽ¡‘Ior–[^in“LŸýó5‘üff±AŽŽ‘͉²T‘þU>Ÿ'EŽ‘ãxX,‘œßbut“the“w•¸ãa“y–[^in“whicš¸ãh“these“t˜w˜o“pac˜k‘ÿqÇages“handle“tables“is“sligh˜tlyŽ¡‘Idi eren•¸ãt.‘acHo“w“ev“er,‘-þthe–$(only“di erence“that“need“concern“us“is“that“LŸýó5‘üff±AŽŽ‘͉²T‘þU>Ÿ'EŽ‘ãxX“uses“Î\\Ž¡‘I²where–UUplain“T‘þU>Ÿ'EŽ‘ãxX“uses“Î\cr².Ž¡‘XThe–?lexample“givš¸ãen“here“is“in“LŸýó5‘üff±AŽŽ‘͉²T‘þU>Ÿ'EŽ‘ãxX,‘yñbut“our“st˜yle“will“w˜ork“equally“w˜ell“inŽ‘À$Ç\MultiReadŽŽŽŽ¡‘I²plain–9¹T‘þU>Ÿ'EŽ‘ãxX.‘òIn“our“studenš¸ãt“letter“w˜e“wish“to“insert“a“table“of“course“coGdes“andŽ¡‘Imarks.‘»åSince–Ã_eacš¸ãh“studen˜t“did“a“di eren˜t“n˜um˜bGer“of“courses,‘Þáw˜e“need“some“w˜a˜yŽ¡‘Iof–¡’recognizing“the“end“of“the“course“list“in“the“merge“ le.‘VThe“default“will“bGe“toŽ¡‘Iinsert–` a“blank“line“at“the“end“of“sucš¸ãh“a“sub-list.‘‘èTh˜us,‘b¸the“follo˜wing“text“appGearsŽ¡‘IbGefore–UUthe“close“of“the“letter“template.Ž¦‘IÇHere–¹–are“your“marks“on“individual“papers.Ž¤ ‘I\begin{center}Ž¡‘W,Â\begin{tabular}{|lr|}\hlineŽ¡‘eY„Code&Mark\\\hlineŽ¡‘eY„\MultiRead{2}\\\hlineŽ¡‘W,Â\end{tabular}Ž¡‘I\end{center}ŽŸ‘I²The–UUmerge“ le“noš¸ãw“has“the“follo˜wing“structure.Ž¦‘IÇTitleŽ¡‘I...Ž¡‘IGradeŽ¡‘ICodeŽ¡‘IMarkŽ¡‘I...Ž¡‘ICodeŽ¡‘IMarkŽŸ‘Ió !",š cmsy10¸hó+ý': cmti10Öblank‘¸iŽ¦‘IÇTitleŽ¡‘I...ŽŽŸ’ø²5ŽŽŒ‹0 ª ýs o ý´‘X²In–·Ÿ'EŽ‘ãxX“that“a“certain“column“has“to“bGeŽ¡‘Itreated–UUin“a“certain“w•¸ãa“y‘ÿ*ª.‘qÇThe‘UUcommandŽ¦‘IÇ\Process{n}{\foo}ŽŸ‘I²will–³replace“evš¸ãery“ eld“¸hµf‘¸i“²read“in˜to“column“µn“²b˜y“Î\foo{¸hµf‘¸iÎ}².‘ŠüIt“is“ev˜en“pGossibleŽ¡‘Ito–UUdo“some“nš¸ãumerical“calculations“b˜y“this“methoGd.Ž¡‘XHere–æ3is“a“LŸýó5‘üff±AŽŽ‘͉²T‘þU>Ÿ'EŽ‘ãxX“example“to“illustrate“the“table“proGcessing“features“ofŽ¡‘IÎtextmerg.sty².Ž©‘I±30Ž‘Sª®ÉhÏexampleŽ‘#ã{ÉiŽ¤ ‘I±31Ž‘Sª®Ç\documentclass[12pt]{article}Ž¡‘I±32Ž‘Sª®Ç\usepackage{textmerg}Ž¡‘I±33Ž‘Sª®Ç\MarkEnd{***}Ž¡‘I±34Ž‘Sª®Ç\Process{2}{\Advance}Ž¡‘I±35Ž‘Sª®Ç\def\Advance#1{#1\addtocounter{page}{#1}}Ž¡‘I±36Ž‘Sª®Ç\Fields{+\Name\Verb}Ž¡‘I±37Ž‘Sª®Ç\begin{document}Ž¡‘I±38Ž‘Sª®Ç\Merge{silly.dat}{%Ž¡‘I±39Ž‘a×pÇDear‘¹–\Name,\parŽ¡‘I±40Ž‘a×pÇHere–¹–is“a“table“to“\Verb\“at:Ž¡‘I±41Ž‘a×pÇ\Fields{\Width}%Ž¡‘I±42Ž‘a×pÇ\begin{tabular}{*{\Width}c}Ž¡‘I±43Ž‘p2Ç\MultiRead\WidthŽ¡‘I±44Ž‘a×pÇ\end{tabular}.\parŽ¡‘I±45Ž‘a×pÇ\Fields{\Adj}%Ž¡‘I±46Ž‘a×pÇThat–¹–was“\Adj!Ž¡‘I±47Ž‘a×pÇ\clearpage}Ž¡‘I±48Ž‘Sª®Ç\end{document}Ž¡‘I±49Ž‘Sª®ÉhÈ=ÏexampleŽ‘#ã{ÉiŽŸ‘I²The–UUe ect“of“this“ le“is“not“apparenš¸ãt“un˜til“w˜e“see“Îsilly.dat².‘qÇIt“is“listed“here.Ž¦‘I±50Ž‘Sª®ÉhÏsillyŽ‘0 ÉiŽ¡‘I±51Ž‘Sª®ÇMikeŽ¡‘I±52Ž‘Sª®ÇlookŽ¡‘I±53Ž‘Sª®Ç3Ž¡‘I±54Ž‘Sª®Ç1Ž¡‘I±55Ž‘Sª®Ç2Ž¡‘I±56Ž‘Sª®Ç3Ž¡‘I±57Ž‘Sª®Ç11Ž¡‘I±58Ž‘Sª®Ç12ŽŽŸ’ø²6ŽŽŒ‹; ª ýs o ý´‘I±59Ž‘Sª®Ç13Ž¤ ‘I±60Ž‘Sª®Ç***Ž¡‘I±61Ž‘Sª®ÇgoodŽ¡‘I±62Ž‘Sª®ÇShelaghŽ¡‘I±63Ž‘Sª®ÇgazeŽ¡‘I±64Ž‘Sª®Ç2Ž¡‘I±65Ž‘Sª®Ç21Ž¡‘I±66Ž‘Sª®Ç22Ž¡‘I±67Ž‘Sª®Ç23Ž¡‘I±68Ž‘Sª®Ç24Ž¡‘I±69Ž‘Sª®Ç***Ž¡‘I±70Ž‘Sª®ÇhorridŽ¡‘I±71Ž‘Sª®ÉhÈ=ÏsillyŽ‘0 ÉiŽŸÖ»‘X²The–UUsame“can“bGe“done“in“plain“T‘þU>Ÿ'EŽ‘ãxX.Ž© Ö»‘I±72Ž‘Sª®ÉhÏplainexampleŽ‘6NÉiŽ¡‘I±73Ž‘Sª®Ç\input‘¹–textmergŽ¡‘I±74Ž‘Sª®Ç\MarkEnd{***}Ž¡‘I±75Ž‘Sª®Ç\Process{2}{\Advance}Ž¡‘I±76Ž‘Sª®Ç\def\Advance#1{#1\global\advance\count0by#1}Ž¡‘I±77Ž‘Sª®Ç\Fields{+\Name\Verb}Ž¡‘I±78Ž‘Sª®Ç\Merge{silly.dat}{%Ž¡‘I±79Ž‘a×pÇDear‘¹–\Name,\parŽ¡‘I±80Ž‘a×pÇHere–¹–is“a“table“to“\Verb\“at:Ž¡‘I±81Ž‘a×pÇ\Fields{\Width}%Ž¡‘I±82Ž‘a×pÇ\vbox{\halign{\hfil{}–¹–##“{}\hfil&&\hfil{}“##“{}\hfil\crŽ¡‘I±83Ž‘p2Ç\MultiRead\Width\crŽ¡‘I±84Ž‘a×pÇ}}.\parŽ¡‘I±85Ž‘a×pÇ\Fields{\Adj}%Ž¡‘I±86Ž‘a×pÇThat–¹–was“\Adj!Ž¡‘I±87Ž‘a×pÇ\vfill\eject}Ž¡‘I±88Ž‘Sª®Ç\endŽ¡‘I±89ŽŽ¡‘I90Ž‘Sª®ÉhÈ=ÏplainexampleŽ‘6NÉiŽŸ î;‘IË5Ž‘aLËIdenŒÌti cationŽŸç‘I²This–ë¹pac¸ãk‘ÿqÇage“can“only“bGe“used“with“LŸýó5‘üff±AŽŽ‘͉²T‘þU>Ÿ'EŽ‘ãxX‘ü2Ÿÿµ"ŽŽ‘)?c²,‘Qso“an“appropriate“message“is“dis-ŽŸ ‘Ipla•¸ãy“ed–UUwhen“another“format“is“usedŸü^ÿ±2ŽŽ‘|s².Ž¦‘I±91Ž‘Sª®ÉhÏtextmergŽ‘' DÉiŽ¡‘I±92Ž‘Sª®Ç\NeedsTeXFormat{LaTeX2e}[1994/01/01]Ž¤Ö»‘X²Announce–UUthe“pacš¸ãk‘ÿqÇage“name“and“its“v˜ersion:Ž¦‘I±93Ž‘Sª®Ç\ProvidesPackage{textmerg}[\filedate]Ž¡‘X²And–UUdispla¸ãy“it“on“the“terminal“(and“the“log“ le):Ž¦‘I±94Ž‘Sª®Ç\typeout{Package–¹–`textmerg'“<\filedate>.}Ž¤ ‘I±95Ž‘Sª®Ç\typeout{\Copyright}Ž¡‘I±96Ž‘Sª®ÉhÈ=ÏtextmergŽ‘' DÉiŽŸÖ»‘X²The––Hplain“T‘þU>Ÿ'EŽ‘ãxX“vš¸ãersion“will“simply“Î\input“²this“pac˜k‘ÿqÇage“ le.‘4¡Th˜us“w˜e“need“toŽŸ ‘Iknoš¸ãw–UUthat“it“will“understand“ev˜erything“in“the“ le.Ž¦‘I±97Ž‘Sª®ÉhÏplainŽ‘ ›ÉiŽ‘IŸS܉ffÿrŸ J=‘ "5Ÿý-:À2ŽŽŽ‘LÜ¿Ho•ÃŽw“ev“er,–ÕXsome“co0Ž¡‘E±182Ž‘p2Ç\SelectCRŽ¡‘E±183Ž‘p2Ç\MakeEmpty{#1}%Ž¡‘E±184Ž‘p2Ç\global\StartOfListtrueŽ¡‘E±185Ž‘p2Ç\glet\NextRead\MReadŽ¡‘E±186Ž‘p2Ç\AllowBlankŽ¡‘E±187Ž‘p2Ç\global\MaxCount=#1ŽŽŸ’õÿ²10ŽŽŒ‹ d ª ýs o ý´‘E±188Ž‘p2Ç\NextReadŽ© ‘E±189Ž‘a×pÇ\fi}ŽŸ‘À$\EmptyctrŽŽŸ ‘Ž\MakeEmptyŽŽŽŽŽ‘I²The–*«command“Î\MakeEmpty“²is“required“bš¸ãy“the“pre-processing“of“eac˜h“ eld.‘ñÈTheŽ¤ ‘Iidea–ð¢is“that“the“command“Î\csname‘?ýprµnnÎ\endcsname²,‘uwhicš¸ãh“w˜e“will“loGosely“callŽ¡‘IÎ\prµnn²,‘ÿ[is–éÜexecuted“on“eacš¸ãh“ eld“in“column“µnn².‘MôHo˜w˜ev˜er,‘ÿ[most“of“these“commandsŽ¡‘Iwill–_bGe“unde ned,‘F¢and“so“wš¸ãe“equate“eac˜h“of“those“that“has“not“bGeen“de ned“toŽ¡‘IÎ\empty².ŽŸ‘E±190Ž‘Sª®Ç\newcount\EmptyctrŽ¦‘E±191Ž‘Sª®Ç\def\MakeEmpty#1{\Emptyctr=0Ž¦‘E±192Ž‘a×pÇ\loopŽ¦‘E±193Ž‘p2Ç\advance\Emptyctr‘¹–by1Ž¦‘E±194Ž‘p2Ç\expandafter\ifx\csnameŽ¦‘E±195Ž‘~0ôÇpr\the\Emptyctr\endcsname\relaxŽ¦‘E±196Ž‘~0ôÇ\expandafter\glet\csnameŽ¦‘E±197Ž’Œ]¶Çpr\the\Emptyctr\endcsname\emptyŽ¦‘E±198Ž‘p2Ç\fiŽ¦‘E±199Ž‘p2Ç\ifnum\Emptyctr<#1Ž¦‘E±200Ž‘a×pÇ\repeat}Ž©‘I²Note–Œ•that,‘´»bGecause“of“the“w•¸ãa“y›Œ•w“e˜are˜accessing˜it˜via˜Î\csname²,‘´»the˜ rst˜time˜Î\prµnnŽ¡‘I²is–UUencoun¸ãtered“it“equates“to“Î\relax².Ž¦‘yºÇ\ProcessŽŽŽ‘I²The–UUcommand“Î\Process#1#2“²de nes“Î\pr#1“²to“mean“Î#2².ŽŸ‘E±201Ž‘Sª®Ç\def\Process#1#2{%Ž¤ ‘E±202Ž‘a×pÇ\expandafter\def\csnameŽ¡‘E±203Ž‘p2Çpr#1\endcsname##1{#2{##1}}}Ž¦‘yº\MarkEndŽŽŽ‘I²W‘ÿ*ªe–©need“to“knoš¸ãw“ho˜w“the“last“ro˜w“is“to“bGe“recognized.‘mThe“default“is“an“empt˜yŽŸ ‘Iline–UUin“the“merge“ le.ŽŸ‘E±204Ž‘Sª®Ç\def\MarkEnd#1{\gdef\EndMarker{#1}}Ž¡‘E±205Ž‘Sª®Ç\MarkEnd{}Ž¦‘À$\NextLineŽŽŸ ‘Ž\NextFieldŽŽŽŽŽ‘I²W‘ÿ*ªe–¤collect“eacš¸ãh“ro˜w“in“a“tok˜en“register.‘]ÈThe“full“ro˜w“is“assem˜bled“in“Î\NextLineŽ¤ ‘I²b•Gefore›yb“eing˜passed˜bac•¸ãk˜to˜T‘þU>Ÿ'EŽ‘ãxX.‘(\Eac“h˜ eld˜is˜read˜in˜Î\TempField˜²and˜then˜placedŽ¡‘ItempGorarily–UUin¸ãto“Î\NextField².ŽŸ‘E±206Ž‘Sª®Ç\newtoks\NextLine‘¹–\newtoks\NextFieldŽ¦‘I²It–I#is“not“necessary“to“do“things“this“w•¸ãa“y;‘à Î\edef–I#²can“bGe“used“instead,‘†but“thatŽ¡‘Iapproac•¸ãh›UUmigh“t˜expand˜tok“ens˜prematurely‘ÿ*ª.Ž¦‘ó­ Ç\AppendNextFieldŽŽŽ‘I²After–UUthe“next“ eld“has“bšGeen“read,“it“is“app˜ended“to“Î\NextLine².ŽŸ‘E±207Ž‘Sª®Ç\def\AppendNextField{%Ž¤ ‘E±208Ž‘a×pÇ\global\advance\MultiCount1Ž¡‘E±209Ž‘a×pÇ\NextField=\expandafter{\TempField}%Ž¡‘E±210Ž‘a×pÇ\edef\Append{\NextLine=Ž¡‘E±211Ž‘p2Ç{\the\NextLine&\csnameŽ¡‘E±212Ž‘~0ôÇpr\the\MultiCount\endcsnameŽ¡‘E±213Ž‘~0ôÇ{\the\NextField}}}%Ž¡‘E±214Ž‘a×pÇ\Append}ŽŽŸ’õÿ²11ŽŽŒ‹ o ª ýs o ý´‘yºÇ\EndLineŽŽŸ ‘ Lø\FinishLineŽŽŽŽŽ‘I²W‘ÿ*ªe–Œneed“to“insert“the“correct“end“markš¸ãer“after“eac˜h“ro˜w“of“the“table.‘&The“tok˜enŽ© ‘IÎ\cr–UU²m¸ãust“bšGe“disguised“a“little“b˜efore“it“is“acceptable“in“a“LŸýó5‘üff±AŽŽ‘͉²T‘þU>Ÿ'EŽ‘ãxX“do˜cumen¸ãt.ŽŸ‘E±215Ž‘Sª®Ç\def\SelectCR{\glet\EndLine\\}%Ž¤ ‘E±216Ž‘Sª®ÉhÈ=ÏtextmergŽ‘' DÉiŽ¡‘E±217Ž‘Sª®ÉhÏplainŽ‘jÉiÇ\def\SelectCR{\gdef\EndLine{\cr}}%Ž¡‘E±218Ž‘Sª®ÉhÏtextmergŽ‘' DÉiŽ¡‘E±219Ž‘Sª®Ç\def\FinishLine{%Ž¡‘E±220Ž‘a×pÇ\ifStartOfListŽ¡‘E±221Ž‘p2Ç\global\StartOfListfalseŽ¡‘E±222Ž‘a×pÇ\else\EndLine\fi}Ž¤‘I²This–UUmakš¸ães“the“assumption“that“if“Î\array“²is“de ned“then“w˜e“m˜ust“bGe“in“LŸýó5‘üff±AŽŽ‘͉²T‘þU>Ÿ'EŽ‘ãxX.Ž¡‘øf Ç\StopProcessingŽŽŽ‘I²W‘ÿ*ªe–{Bneed“a“command“to“ nish“o “a“table.‘ ãŽThis“should“reset“Î\NextRead“²toŽ¦‘IÎ\AllowBlank–È`²to“terminate“the“tail“recursion,‘%#and“also“do“some“error“reco•¸ãv“eryŽ¦‘Iin–UUcase“the“ le“ends“prematurely“in“the“middle“of“a“ro¸ãw.ŽŸ‘E±223Ž‘Sª®Ç\def\StopProcessing{%Ž¤ ‘E±224Ž‘a×pÇ\global\MultiCount\MaxCountŽ¡‘E±225Ž‘a×pÇ\glet\NextRead\AllowBlank}ŽŸ‘"ìæ\MReadŽŽŽ‘I²The–@ìcommand“Î\MRead“²prepares“to“read“a“ro¸ãw“of“a“table.‘jùIt“reads“a“ eld“from“theŽ¦‘Imerge–UU le“and“c•¸ãhec“ks–UUto“see“whether“the“table“has“bGeen“exhausted.ŽŸ‘E±226Ž‘Sª®Ç\def\MRead{%Ž¡‘E±227Ž‘a×pÇ\global\MultiCount=1Ž¡‘E±228Ž‘a×pÇ\ReadIn\TempFieldŽ¡‘E±229Ž‘a×pÇ\ifx\TempField\EndMarkerŽ¡‘E±230Ž‘p2Ç\StopProcessingŽ¡‘E±231Ž‘a×pÇ\elseŽ¡‘E±232Ž‘p2Ç\FinishLineŽ¡‘E±233Ž‘p2Ç\NextField=\expandafter{\TempField}%Ž¡‘E±234Ž‘p2Ç\edef\StartLine{\NextLine={\csnameŽ¡‘E±235Ž‘~0ôÇpr1\endcsname{\the\NextField}}}%Ž¡‘E±236Ž‘p2Ç\StartLineŽ¡‘E±237Ž‘p2Ç\ConstructNextRowŽ¡‘E±238Ž‘a×pÇ\fiŽ¡‘E±239Ž‘a×pÇ\NextRead}ŽŸ‘îót\ConstructNextRowŽŽŽ‘I²Command–GµÎ\ConstructNextRow“²doGes“most“of“the“wš¸ãork“of“assem˜bling“a“ro˜w“of“theŽ¦‘Itable.‘eIt–¦hassemš¸ãbles“Î\MaxCount“² elds“at“a“time“in˜to“Î\NextLine“²unless“an“error“isŽ¦‘Iencoun¸ãtered.ŽŸ‘E±240Ž‘Sª®Ç\def\ConstructNextRow{%Ž¡‘E±241Ž‘a×pÇ\ifnum\MultiCount<\MaxCountŽ¡‘E±242Ž‘p2Ç\loopŽ¡‘E±243Ž‘~0ôÇ\ReadIn\TempFieldŽ¡‘E±244Ž‘~0ôÇ\ifx\TempField\EndMarkerŽ¡‘E±245Ž’Œ]¶Ç\glet\TempField\emptyŽ¡‘E±246Ž’Œ]¶Ç\StopProcessingŽ¡‘E±247Ž’Œ]¶Ç\MissingFieldŽ¡‘E±248Ž‘~0ôÇ\elseŽ¡‘E±249Ž’Œ]¶Ç\ifeof\MergeFileŽ¡‘E±250Ž’šŠxÇ\glet\TempField\emptyŽ¡‘E±251Ž’šŠxÇ\StopProcessingŽ¡‘E±252Ž’šŠxÇ\MissingFieldŽŽŸ’õÿ²12ŽŽŒ‹ yX ª ýs o ý´‘E±253Ž’Œ]¶Ç\fiŽ¤ ‘E±254Ž‘~0ôÇ\fiŽ¡‘E±255Ž‘~0ôÇ\AppendNextFieldŽ¡‘E±256Ž‘~0ôÇ\ifnum\MultiCount<\MaxCountŽ¡‘E±257Ž‘p2Ç\repeatŽ¡‘E±258Ž‘f‘Ç\fiŽ¡‘E±259Ž‘a×pÇ\the\NextLine}Ž¡‘E±260Ž‘Sª®ÉhÈ=ÏtextmergŽ‘' DÉiŽ©!Ä‘IË8Ž‘aLËThe–ffdos3cumenšŒÌtation“driv˜er“ leŽŸç‘I²This– ¨is“the“driv¸ãer“ le“that“prošGduces“this“do˜cumen¸ãtation.‘‘¿W‘ÿ*ªe“use“the“do˜cumen¸ãtŽŸ ‘Iclass–UUproš¸ãvided“b˜y“the“LŸýó5‘üff±AŽŽ‘͉²T‘þU>Ÿ'EŽ‘ãxX‘ü2Ÿÿµ"ŽŽ‘+þT²distribution“for“prošGducing“the“do˜cumen¸ãtation.ŽŸ‘E±261Ž‘Sª®ÉhÏdriverŽ‘oÉiŽ¡‘E±262Ž‘Sª®Ç\documentclass{ltxdoc}Ž¡‘E±263Ž‘Sª®Ç\RecordChangesŽ¡‘E±264Ž‘Sª®Ç\begin{document}Ž¡‘E±265Ž‘]ÚÇ\DocInput{textmerg.dtx}Ž¡‘E±266Ž‘]ÚÇ\PrintIndexŽ¡‘E±267Ž‘]ÚÇ\PrintChangesŽ¡‘E±268Ž‘Sª®Ç\end{document}Ž¡‘E±269Ž‘Sª®ÉhÈ=ÏdriverŽ‘oÉiŽ¦‘IËReferencesŽŸç‘I²[Bel87]ŽŽ’u]Edwin–\¸V.“Bell,‘^‘IšGI.‘„òAutoLetter:‘€A‘\¶T‘þU>Ÿ'EŽ‘ãxX“form“letter“pro˜cedure.‘„òÖTUG-ŽŸ ’u]Bo‘ÿ}'at²,–UU8(1):54,“April“1987.Ž¤‘I[Gar87]ŽŽ’u]John–pWS.“Gara•¸ãv“elli.›ùªF‘ÿ*ªorm–pWletter“macros.˜ÖTUGBo‘ÿ}'at²,–ž$8(1):53,“April‘pW1987.Ž¡‘I[Lee86]ŽŽ’u]John–UULee.›nïF‘ÿ*ªorm“letters.˜ÖTUGBo‘ÿ}'at²,“7(3):187,“OctobGer“1986.Ž¡‘I[McK87]ŽŽ’u]Graeme›UUMcKinstry–ÿ*ª.‘nïF“orm˜letters.‘nïÖTUGBo‘ÿ}'at²,˜8(1):60,˜April˜1987.ŽŽŸ’õÿ13ŽŽŒøƒ¼ƒ’À;説 ó+ý': cmti10ó*ßCÊscmtt8ó$ÒoÇw cmss9ó#ßê cmmi10óKñ`y cmr10óÙ“ Rcmr7ù‰wßßßßßß