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