tex.go 1.0 MB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453244542445524456244572445824459244602446124462244632446424465244662446724468244692447024471244722447324474244752447624477244782447924480244812448224483244842448524486244872448824489244902449124492244932449424495244962449724498244992450024501245022450324504245052450624507245082450924510245112451224513245142451524516245172451824519245202452124522245232452424525245262452724528245292453024531245322453324534245352453624537245382453924540245412454224543245442454524546245472454824549245502455124552245532455424555245562455724558245592456024561245622456324564245652456624567245682456924570245712457224573245742457524576245772457824579245802458124582245832458424585245862458724588245892459024591245922459324594245952459624597245982459924600246012460224603246042460524606246072460824609246102461124612246132461424615246162461724618246192462024621246222462324624246252462624627246282462924630246312463224633246342463524636246372463824639246402464124642246432464424645246462464724648246492465024651246522465324654246552465624657246582465924660246612466224663246642466524666246672466824669246702467124672246732467424675246762467724678246792468024681246822468324684246852468624687246882468924690246912469224693246942469524696246972469824699247002470124702247032470424705247062470724708247092471024711247122471324714247152471624717247182471924720247212472224723247242472524726247272472824729247302473124732247332473424735247362473724738247392474024741247422474324744247452474624747247482474924750247512475224753247542475524756247572475824759247602476124762247632476424765247662476724768247692477024771247722477324774247752477624777247782477924780247812478224783247842478524786247872478824789247902479124792247932479424795247962479724798247992480024801248022480324804248052480624807248082480924810248112481224813248142481524816248172481824819248202482124822248232482424825248262482724828248292483024831248322483324834248352483624837248382483924840248412484224843248442484524846248472484824849248502485124852248532485424855248562485724858248592486024861248622486324864248652486624867248682486924870248712487224873248742487524876248772487824879248802488124882248832488424885248862488724888248892489024891248922489324894248952489624897248982489924900249012490224903249042490524906249072490824909249102491124912249132491424915249162491724918249192492024921249222492324924249252492624927249282492924930249312493224933249342493524936249372493824939249402494124942249432494424945249462494724948249492495024951249522495324954249552495624957249582495924960249612496224963249642496524966249672496824969249702497124972249732497424975249762497724978249792498024981249822498324984249852498624987249882498924990249912499224993249942499524996249972499824999250002500125002250032500425005250062500725008250092501025011250122501325014250152501625017250182501925020250212502225023250242502525026250272502825029250302503125032250332503425035250362503725038250392504025041250422504325044250452504625047250482504925050250512505225053250542505525056250572505825059250602506125062250632506425065250662506725068250692507025071250722507325074250752507625077250782507925080250812508225083250842508525086250872508825089250902509125092250932509425095250962509725098250992510025101251022510325104251052510625107251082510925110251112511225113251142511525116251172511825119251202512125122251232512425125251262512725128251292513025131251322513325134251352513625137251382513925140251412514225143251442514525146251472514825149251502515125152251532515425155251562515725158251592516025161251622516325164251652516625167251682516925170251712517225173251742517525176251772517825179251802518125182251832518425185251862518725188251892519025191251922519325194251952519625197251982519925200252012520225203252042520525206252072520825209252102521125212252132521425215252162521725218252192522025221252222522325224252252522625227252282522925230252312523225233252342523525236252372523825239252402524125242252432524425245252462524725248252492525025251252522525325254252552525625257252582525925260252612526225263252642526525266252672526825269252702527125272252732527425275252762527725278252792528025281252822528325284252852528625287252882528925290252912529225293252942529525296252972529825299253002530125302253032530425305253062530725308253092531025311253122531325314253152531625317253182531925320253212532225323253242532525326253272532825329253302533125332253332533425335253362533725338253392534025341253422534325344253452534625347253482534925350253512535225353253542535525356253572535825359253602536125362253632536425365253662536725368253692537025371253722537325374253752537625377253782537925380253812538225383253842538525386253872538825389253902539125392253932539425395253962539725398253992540025401254022540325404254052540625407254082540925410254112541225413254142541525416254172541825419254202542125422254232542425425254262542725428254292543025431254322543325434254352543625437254382543925440254412544225443254442544525446254472544825449254502545125452254532545425455254562545725458254592546025461254622546325464254652546625467254682546925470254712547225473254742547525476254772547825479254802548125482254832548425485254862548725488254892549025491254922549325494254952549625497254982549925500255012550225503255042550525506255072550825509255102551125512255132551425515255162551725518255192552025521255222552325524255252552625527255282552925530255312553225533255342553525536255372553825539255402554125542255432554425545255462554725548255492555025551255522555325554255552555625557255582555925560255612556225563255642556525566255672556825569255702557125572255732557425575255762557725578255792558025581255822558325584255852558625587255882558925590255912559225593255942559525596255972559825599256002560125602256032560425605256062560725608256092561025611256122561325614256152561625617256182561925620256212562225623256242562525626256272562825629256302563125632256332563425635256362563725638256392564025641256422564325644256452564625647256482564925650256512565225653256542565525656256572565825659256602566125662256632566425665256662566725668256692567025671256722567325674256752567625677256782567925680256812568225683256842568525686256872568825689256902569125692256932569425695256962569725698256992570025701257022570325704257052570625707257082570925710257112571225713257142571525716257172571825719257202572125722257232572425725257262572725728257292573025731257322573325734257352573625737257382573925740257412574225743257442574525746257472574825749257502575125752257532575425755257562575725758257592576025761257622576325764257652576625767257682576925770257712577225773257742577525776257772577825779257802578125782257832578425785257862578725788257892579025791257922579325794257952579625797257982579925800258012580225803258042580525806258072580825809258102581125812258132581425815258162581725818258192582025821258222582325824258252582625827258282582925830258312583225833258342583525836258372583825839258402584125842258432584425845258462584725848258492585025851258522585325854258552585625857258582585925860258612586225863258642586525866258672586825869258702587125872258732587425875258762587725878258792588025881258822588325884258852588625887258882588925890258912589225893258942589525896258972589825899259002590125902259032590425905259062590725908259092591025911259122591325914259152591625917259182591925920259212592225923259242592525926259272592825929259302593125932259332593425935259362593725938259392594025941259422594325944259452594625947259482594925950259512595225953259542595525956259572595825959259602596125962259632596425965259662596725968259692597025971259722597325974259752597625977259782597925980259812598225983259842598525986259872598825989259902599125992259932599425995259962599725998259992600026001260022600326004260052600626007260082600926010260112601226013260142601526016260172601826019260202602126022260232602426025260262602726028260292603026031260322603326034260352603626037260382603926040260412604226043260442604526046260472604826049260502605126052260532605426055260562605726058260592606026061260622606326064260652606626067260682606926070260712607226073260742607526076260772607826079260802608126082260832608426085260862608726088260892609026091260922609326094260952609626097260982609926100261012610226103261042610526106261072610826109261102611126112261132611426115261162611726118261192612026121261222612326124261252612626127261282612926130261312613226133261342613526136261372613826139261402614126142261432614426145261462614726148261492615026151261522615326154261552615626157261582615926160261612616226163261642616526166261672616826169261702617126172261732617426175261762617726178261792618026181261822618326184261852618626187261882618926190261912619226193261942619526196261972619826199262002620126202262032620426205262062620726208262092621026211262122621326214262152621626217262182621926220262212622226223262242622526226262272622826229262302623126232262332623426235262362623726238262392624026241262422624326244262452624626247262482624926250262512625226253262542625526256262572625826259262602626126262262632626426265262662626726268262692627026271262722627326274262752627626277262782627926280262812628226283262842628526286262872628826289262902629126292262932629426295262962629726298262992630026301263022630326304263052630626307263082630926310263112631226313263142631526316263172631826319263202632126322263232632426325263262632726328263292633026331263322633326334263352633626337263382633926340263412634226343263442634526346263472634826349263502635126352263532635426355263562635726358263592636026361263622636326364263652636626367263682636926370263712637226373263742637526376263772637826379263802638126382263832638426385263862638726388263892639026391263922639326394263952639626397263982639926400264012640226403264042640526406264072640826409264102641126412264132641426415264162641726418264192642026421264222642326424264252642626427264282642926430264312643226433264342643526436264372643826439264402644126442264432644426445264462644726448264492645026451264522645326454264552645626457264582645926460264612646226463264642646526466264672646826469264702647126472264732647426475264762647726478264792648026481264822648326484264852648626487264882648926490264912649226493264942649526496264972649826499265002650126502265032650426505265062650726508265092651026511265122651326514265152651626517265182651926520265212652226523265242652526526265272652826529265302653126532265332653426535265362653726538265392654026541265422654326544265452654626547265482654926550265512655226553265542655526556265572655826559265602656126562265632656426565265662656726568265692657026571265722657326574265752657626577265782657926580265812658226583265842658526586265872658826589265902659126592265932659426595265962659726598265992660026601266022660326604266052660626607266082660926610266112661226613266142661526616266172661826619266202662126622266232662426625266262662726628266292663026631266322663326634266352663626637266382663926640266412664226643266442664526646266472664826649266502665126652266532665426655266562665726658266592666026661266622666326664266652666626667266682666926670266712667226673266742667526676266772667826679266802668126682266832668426685266862668726688266892669026691266922669326694266952669626697266982669926700267012670226703267042670526706267072670826709267102671126712267132671426715267162671726718267192672026721267222672326724267252672626727267282672926730267312673226733267342673526736267372673826739267402674126742267432674426745267462674726748267492675026751267522675326754267552675626757267582675926760267612676226763267642676526766267672676826769267702677126772267732677426775267762677726778267792678026781267822678326784267852678626787267882678926790267912679226793267942679526796267972679826799268002680126802268032680426805268062680726808268092681026811268122681326814268152681626817268182681926820268212682226823268242682526826268272682826829268302683126832268332683426835268362683726838268392684026841268422684326844268452684626847268482684926850268512685226853268542685526856268572685826859268602686126862268632686426865268662686726868268692687026871268722687326874268752687626877268782687926880268812688226883268842688526886268872688826889268902689126892268932689426895268962689726898268992690026901269022690326904269052690626907269082690926910269112691226913269142691526916269172691826919269202692126922269232692426925269262692726928269292693026931269322693326934269352693626937269382693926940269412694226943269442694526946269472694826949269502695126952269532695426955269562695726958269592696026961269622696326964269652696626967269682696926970269712697226973269742697526976269772697826979269802698126982269832698426985269862698726988269892699026991269922699326994269952699626997269982699927000270012700227003270042700527006270072700827009270102701127012270132701427015270162701727018270192702027021270222702327024270252702627027270282702927030270312703227033270342703527036270372703827039270402704127042270432704427045270462704727048270492705027051270522705327054270552705627057270582705927060270612706227063270642706527066270672706827069270702707127072270732707427075270762707727078270792708027081270822708327084270852708627087270882708927090270912709227093270942709527096270972709827099271002710127102271032710427105271062710727108271092711027111271122711327114271152711627117271182711927120271212712227123271242712527126271272712827129271302713127132271332713427135271362713727138271392714027141271422714327144271452714627147271482714927150271512715227153271542715527156271572715827159271602716127162271632716427165271662716727168271692717027171271722717327174271752717627177271782717927180271812718227183271842718527186271872718827189271902719127192271932719427195271962719727198271992720027201272022720327204272052720627207272082720927210272112721227213272142721527216272172721827219272202722127222272232722427225272262722727228272292723027231272322723327234272352723627237272382723927240272412724227243272442724527246272472724827249272502725127252272532725427255272562725727258272592726027261272622726327264272652726627267272682726927270272712727227273272742727527276272772727827279272802728127282272832728427285272862728727288272892729027291272922729327294272952729627297272982729927300273012730227303273042730527306273072730827309273102731127312273132731427315273162731727318273192732027321273222732327324273252732627327273282732927330273312733227333273342733527336273372733827339273402734127342273432734427345273462734727348273492735027351273522735327354273552735627357273582735927360273612736227363273642736527366273672736827369273702737127372273732737427375273762737727378273792738027381273822738327384273852738627387273882738927390273912739227393273942739527396273972739827399274002740127402274032740427405274062740727408274092741027411274122741327414274152741627417274182741927420274212742227423274242742527426274272742827429274302743127432274332743427435274362743727438274392744027441274422744327444274452744627447274482744927450274512745227453274542745527456274572745827459274602746127462274632746427465274662746727468274692747027471274722747327474274752747627477274782747927480274812748227483274842748527486274872748827489274902749127492274932749427495274962749727498274992750027501275022750327504275052750627507275082750927510275112751227513275142751527516275172751827519275202752127522275232752427525275262752727528275292753027531275322753327534275352753627537275382753927540275412754227543275442754527546275472754827549275502755127552275532755427555275562755727558275592756027561275622756327564275652756627567275682756927570275712757227573275742757527576275772757827579275802758127582275832758427585275862758727588275892759027591275922759327594275952759627597275982759927600276012760227603276042760527606276072760827609276102761127612276132761427615276162761727618276192762027621276222762327624276252762627627276282762927630276312763227633276342763527636276372763827639276402764127642276432764427645276462764727648276492765027651276522765327654276552765627657276582765927660276612766227663276642766527666276672766827669276702767127672276732767427675276762767727678276792768027681276822768327684276852768627687276882768927690276912769227693276942769527696276972769827699277002770127702277032770427705277062770727708277092771027711277122771327714277152771627717277182771927720277212772227723277242772527726277272772827729277302773127732277332773427735277362773727738277392774027741277422774327744277452774627747277482774927750277512775227753277542775527756277572775827759277602776127762277632776427765277662776727768277692777027771277722777327774277752777627777277782777927780277812778227783277842778527786277872778827789277902779127792277932779427795277962779727798277992780027801278022780327804278052780627807278082780927810278112781227813278142781527816278172781827819278202782127822278232782427825278262782727828278292783027831278322783327834278352783627837278382783927840278412784227843278442784527846278472784827849278502785127852278532785427855278562785727858278592786027861278622786327864278652786627867278682786927870278712787227873278742787527876278772787827879278802788127882278832788427885278862788727888278892789027891278922789327894278952789627897278982789927900279012790227903279042790527906279072790827909279102791127912279132791427915279162791727918279192792027921279222792327924279252792627927279282792927930279312793227933279342793527936279372793827939279402794127942279432794427945279462794727948279492795027951279522795327954279552795627957279582795927960279612796227963279642796527966279672796827969279702797127972279732797427975279762797727978279792798027981279822798327984279852798627987279882798927990279912799227993279942799527996279972799827999280002800128002280032800428005280062800728008280092801028011280122801328014280152801628017280182801928020280212802228023280242802528026280272802828029280302803128032280332803428035280362803728038280392804028041280422804328044280452804628047280482804928050280512805228053280542805528056280572805828059280602806128062280632806428065280662806728068280692807028071280722807328074280752807628077280782807928080280812808228083280842808528086280872808828089280902809128092280932809428095280962809728098280992810028101281022810328104281052810628107281082810928110281112811228113281142811528116281172811828119281202812128122281232812428125281262812728128281292813028131281322813328134281352813628137281382813928140281412814228143281442814528146281472814828149281502815128152281532815428155281562815728158281592816028161281622816328164281652816628167281682816928170281712817228173281742817528176281772817828179281802818128182281832818428185281862818728188281892819028191281922819328194281952819628197281982819928200282012820228203282042820528206282072820828209282102821128212282132821428215282162821728218282192822028221282222822328224282252822628227282282822928230282312823228233282342823528236282372823828239282402824128242282432824428245282462824728248282492825028251282522825328254282552825628257282582825928260282612826228263282642826528266282672826828269282702827128272282732827428275282762827728278282792828028281282822828328284282852828628287282882828928290282912829228293282942829528296282972829828299283002830128302283032830428305283062830728308283092831028311283122831328314283152831628317283182831928320283212832228323283242832528326283272832828329283302833128332283332833428335283362833728338283392834028341283422834328344283452834628347283482834928350283512835228353283542835528356283572835828359283602836128362283632836428365283662836728368283692837028371283722837328374283752837628377283782837928380283812838228383283842838528386283872838828389283902839128392283932839428395283962839728398283992840028401284022840328404284052840628407284082840928410284112841228413284142841528416284172841828419284202842128422284232842428425284262842728428284292843028431284322843328434284352843628437284382843928440284412844228443284442844528446284472844828449284502845128452284532845428455284562845728458284592846028461284622846328464284652846628467284682846928470284712847228473284742847528476284772847828479284802848128482284832848428485284862848728488284892849028491284922849328494284952849628497284982849928500285012850228503285042850528506285072850828509285102851128512285132851428515285162851728518285192852028521285222852328524285252852628527285282852928530285312853228533285342853528536285372853828539285402854128542285432854428545285462854728548285492855028551285522855328554285552855628557285582855928560285612856228563285642856528566285672856828569285702857128572285732857428575285762857728578285792858028581285822858328584285852858628587285882858928590285912859228593285942859528596285972859828599286002860128602286032860428605286062860728608286092861028611286122861328614286152861628617286182861928620286212862228623286242862528626286272862828629286302863128632286332863428635286362863728638286392864028641286422864328644286452864628647286482864928650286512865228653286542865528656286572865828659286602866128662286632866428665286662866728668286692867028671286722867328674286752867628677286782867928680286812868228683286842868528686286872868828689286902869128692286932869428695286962869728698286992870028701287022870328704287052870628707287082870928710287112871228713287142871528716287172871828719287202872128722287232872428725287262872728728287292873028731287322873328734287352873628737287382873928740287412874228743287442874528746287472874828749287502875128752287532875428755287562875728758287592876028761287622876328764287652876628767287682876928770287712877228773287742877528776287772877828779287802878128782287832878428785287862878728788287892879028791287922879328794287952879628797287982879928800288012880228803288042880528806288072880828809288102881128812288132881428815288162881728818288192882028821288222882328824288252882628827288282882928830288312883228833288342883528836288372883828839288402884128842288432884428845288462884728848288492885028851288522885328854288552885628857288582885928860288612886228863288642886528866288672886828869288702887128872288732887428875288762887728878288792888028881288822888328884288852888628887288882888928890288912889228893288942889528896288972889828899289002890128902289032890428905289062890728908289092891028911289122891328914289152891628917289182891928920289212892228923289242892528926289272892828929289302893128932289332893428935289362893728938289392894028941289422894328944289452894628947289482894928950289512895228953289542895528956289572895828959289602896128962289632896428965289662896728968289692897028971289722897328974289752897628977289782897928980289812898228983289842898528986289872898828989289902899128992289932899428995289962899728998289992900029001290022900329004290052900629007290082900929010290112901229013290142901529016290172901829019290202902129022290232902429025290262902729028290292903029031290322903329034290352903629037290382903929040290412904229043290442904529046290472904829049290502905129052290532905429055290562905729058290592906029061290622906329064290652906629067290682906929070290712907229073290742907529076290772907829079290802908129082290832908429085290862908729088290892909029091290922909329094290952909629097290982909929100291012910229103291042910529106291072910829109291102911129112291132911429115291162911729118291192912029121291222912329124291252912629127291282912929130291312913229133291342913529136291372913829139291402914129142291432914429145291462914729148291492915029151291522915329154291552915629157291582915929160291612916229163291642916529166291672916829169291702917129172291732917429175291762917729178291792918029181291822918329184291852918629187291882918929190291912919229193291942919529196291972919829199292002920129202292032920429205292062920729208292092921029211292122921329214292152921629217292182921929220292212922229223292242922529226292272922829229292302923129232292332923429235292362923729238292392924029241292422924329244292452924629247292482924929250292512925229253292542925529256292572925829259292602926129262292632926429265292662926729268292692927029271292722927329274292752927629277292782927929280292812928229283292842928529286292872928829289292902929129292292932929429295292962929729298292992930029301293022930329304293052930629307293082930929310293112931229313293142931529316293172931829319293202932129322293232932429325293262932729328293292933029331293322933329334293352933629337293382933929340293412934229343293442934529346293472934829349293502935129352293532935429355293562935729358293592936029361293622936329364293652936629367293682936929370293712937229373293742937529376293772937829379293802938129382293832938429385293862938729388293892939029391293922939329394293952939629397293982939929400294012940229403294042940529406294072940829409294102941129412294132941429415294162941729418294192942029421294222942329424294252942629427294282942929430294312943229433294342943529436294372943829439294402944129442294432944429445294462944729448294492945029451294522945329454294552945629457294582945929460294612946229463294642946529466294672946829469294702947129472294732947429475294762947729478294792948029481294822948329484294852948629487294882948929490294912949229493294942949529496294972949829499295002950129502295032950429505295062950729508295092951029511295122951329514295152951629517295182951929520295212952229523295242952529526295272952829529295302953129532295332953429535295362953729538295392954029541295422954329544295452954629547295482954929550295512955229553295542955529556295572955829559295602956129562295632956429565295662956729568295692957029571295722957329574295752957629577295782957929580295812958229583295842958529586295872958829589295902959129592295932959429595295962959729598295992960029601296022960329604296052960629607296082960929610296112961229613296142961529616296172961829619296202962129622296232962429625296262962729628296292963029631296322963329634296352963629637296382963929640296412964229643296442964529646296472964829649296502965129652296532965429655296562965729658296592966029661296622966329664296652966629667296682966929670296712967229673296742967529676296772967829679296802968129682296832968429685296862968729688296892969029691296922969329694296952969629697296982969929700297012970229703297042970529706297072970829709297102971129712297132971429715297162971729718297192972029721297222972329724297252972629727297282972929730297312973229733297342973529736297372973829739297402974129742297432974429745297462974729748297492975029751297522975329754297552975629757297582975929760297612976229763297642976529766297672976829769297702977129772297732977429775297762977729778297792978029781297822978329784297852978629787297882978929790297912979229793297942979529796297972979829799298002980129802298032980429805298062980729808298092981029811298122981329814298152981629817298182981929820298212982229823298242982529826298272982829829298302983129832298332983429835298362983729838298392984029841298422984329844298452984629847298482984929850298512985229853298542985529856298572985829859298602986129862298632986429865298662986729868298692987029871298722987329874298752987629877298782987929880298812988229883298842988529886298872988829889298902989129892298932989429895298962989729898298992990029901299022990329904299052990629907299082990929910299112991229913299142991529916299172991829919299202992129922299232992429925299262992729928299292993029931299322993329934299352993629937299382993929940299412994229943299442994529946299472994829949299502995129952299532995429955299562995729958299592996029961299622996329964299652996629967299682996929970299712997229973299742997529976299772997829979299802998129982299832998429985299862998729988299892999029991299922999329994299952999629997299982999930000300013000230003300043000530006300073000830009300103001130012300133001430015300163001730018300193002030021300223002330024300253002630027300283002930030300313003230033300343003530036300373003830039300403004130042300433004430045300463004730048300493005030051300523005330054300553005630057300583005930060300613006230063300643006530066300673006830069300703007130072300733007430075300763007730078300793008030081300823008330084300853008630087300883008930090300913009230093300943009530096300973009830099301003010130102301033010430105301063010730108301093011030111301123011330114301153011630117301183011930120301213012230123301243012530126301273012830129301303013130132301333013430135301363013730138301393014030141301423014330144301453014630147301483014930150301513015230153301543015530156301573015830159301603016130162301633016430165301663016730168301693017030171301723017330174301753017630177301783017930180301813018230183301843018530186301873018830189301903019130192301933019430195301963019730198301993020030201302023020330204302053020630207302083020930210302113021230213302143021530216302173021830219302203022130222302233022430225302263022730228302293023030231302323023330234302353023630237302383023930240302413024230243302443024530246302473024830249302503025130252302533025430255302563025730258302593026030261302623026330264302653026630267302683026930270302713027230273
  1. // Code generated by '[/tmp/go-build3521972418/b001/exe/generate]', DO NOT EDIT.
  2. // % This program is copyright (C) 1982 by D. E. Knuth; all rights are reserved.
  3. // % Unlimited copying and redistribution of this file are permitted as long
  4. // % as this file is not modified. Modifications are permitted, but only if
  5. // % the resulting file is not named tex.web. (The WEB system provides
  6. // % for alterations via an auxiliary file; the master file should stay intact.)
  7. // % See Appendix H of the WEB manual for hints on how to install this program.
  8. // % And see Appendix A of the TRIP manual for details about how to validate it.
  9. //
  10. // % TeX is a trademark of the American Mathematical Society.
  11. // % METAFONT is a trademark of Addison-Wesley Publishing Company.
  12. //
  13. // % Version 0 was released in September 1982 after it passed a variety of tests.
  14. // % Version 1 was released in November 1983 after thorough testing.
  15. // % Version 1.1 fixed ``disappearing font identifiers'' et alia (July 1984).
  16. // % Version 1.2 allowed `0' in response to an error, et alia (October 1984).
  17. // % Version 1.3 made memory allocation more flexible and local (November 1984).
  18. // % Version 1.4 fixed accents right after line breaks, et alia (April 1985).
  19. // % Version 1.5 fixed \the\toks after other expansion in \edefs (August 1985).
  20. // % Version 2.0 (almost identical to 1.5) corresponds to "Volume B" (April 1986).
  21. // % Version 2.1 corrected anomalies in discretionary breaks (January 1987).
  22. // % Version 2.2 corrected "(Please type...)" with null \endlinechar (April 1987).
  23. // % Version 2.3 avoided incomplete page in premature termination (August 1987).
  24. // % Version 2.4 fixed \noaligned rules in indented displays (August 1987).
  25. // % Version 2.5 saved cur_order when expanding tokens (September 1987).
  26. // % Version 2.6 added 10sp slop when shipping leaders (November 1987).
  27. // % Version 2.7 improved rounding of negative-width characters (November 1987).
  28. // % Version 2.8 fixed weird bug if no \patterns are used (December 1987).
  29. // % Version 2.9 made \csname\endcsname's "relax" local (December 1987).
  30. // % Version 2.91 fixed \outer\def\a0[]\a\a bug (April 1988).
  31. // % Version 2.92 fixed \patterns, also file names with complex macros (May 1988).
  32. // % Version 2.93 fixed negative halving in allocator when mem_min<0 (June 1988).
  33. // % Version 2.94 kept open_log_file from calling fatal_error (November 1988).
  34. // % Version 2.95 solved that problem a better way (December 1988).
  35. // % Version 2.96 corrected bug in "Infinite shrinkage" recovery (January 1989).
  36. // % Version 2.97 corrected blunder in creating 2.95 (February 1989).
  37. // % Version 2.98 omitted save_for_after at outer level (March 1989).
  38. // % Version 2.99 caught $$\begingroup\halign..$$ (June 1989).
  39. // % Version 2.991 caught .5\ifdim.6... (June 1989).
  40. // % Version 2.992 introduced major changes for 8-bit extensions (September 1989).
  41. // % Version 2.993 fixed a save_stack synchronization bug et alia (December 1989).
  42. // % Version 3.0 fixed unusual displays; was more \output robust (March 1990).
  43. // % Version 3.1 fixed nullfont, disabled \write[\the\prevgraf] (September 1990).
  44. // % Version 3.14 fixed unprintable font names and corrected typos (March 1991).
  45. // % Version 3.141 more of same; reconstituted ligatures better (March 1992).
  46. // % Version 3.1415 preserved nonexplicit kerns, tidied up (February 1993).
  47. // % Version 3.14159 allowed fontmemsize to change; bulletproofing (March 1995).
  48. // % Version 3.141592 fixed \xleaders, glueset, weird alignments (December 2002).
  49. // % Version 3.1415926 was a general cleanup with minor fixes (February 2008).
  50. // % Version 3.14159265 was similar (January 2014).
  51. // % Version 3.141592653 was similar but more extensive (January 2021).
  52. //
  53. // % A reward of $327.68 will be paid to the first finder of any remaining bug.
  54. //
  55. // % Although considerable effort has been expended to make the TeX program
  56. // % correct and reliable, no warranty is implied; the author disclaims any
  57. // % obligation or liability for damages, including but not limited to
  58. // % special, indirect, or consequential damages arising out of or in
  59. // % connection with the use or performance of this software. This work has
  60. // % been a ``labor of love'' and the author hopes that users enjoy it.
  61. //
  62. // % Here is TeX material that gets inserted after \input webmac
  63. // \def\hang[\hangindent 3em\noindent\ignorespaces]
  64. // \def\hangg#1 [\hang\hbox[#1 ]]
  65. // \def\textindent#1[\hangindent2.5em\noindent\hbox to2.5em[\hss#1 ]\ignorespaces]
  66. // \font\ninerm=cmr9
  67. // \let\mc=\ninerm % medium caps for names like SAIL
  68. // \def\PASCAL[Pascal]
  69. // \def\ph[\hbox[Pascal-H]]
  70. // \def\pct![[\char`\%]] % percent sign in ordinary text
  71. // \font\logo=logo10 % font used for the METAFONT logo
  72. // \def\MF[[\logo META]\-[\logo FONT]]
  73. // \def\<#1>[$\langle#1\rangle$]
  74. // \def\section[\mathhexbox278]
  75. //
  76. // \def\(#1)[] % this is used to make section names sort themselves better
  77. // \def\9#1[] % this is used for sort keys in the index via @:sort key][entry@>
  78. //
  79. // \outer\def\N#1. \[#2]#3.[\MN#1.\vfil\eject % begin starred section
  80. // \def\rhead[PART #2:\uppercase[#3]] % define running headline
  81. // \message[*\modno] % progress report
  82. // \edef\next[\write\cont[\Z[\?#2]#3][\modno][\the\pageno]]]\next
  83. // \ifon\startsection[\bf\ignorespaces#3.\quad]\ignorespaces]
  84. // \let\?=\relax % we want to be able to \write a \?
  85. //
  86. // \def\title[\TeX82]
  87. // \def\topofcontents[\hsize 5.5in
  88. // \vglue 0pt plus 1fil minus 1.5in
  89. // \def\?##1][\hbox to 1in[\hfil##1.\ ]]
  90. // ]
  91. // \def\botofcontents[\vskip 0pt plus 1fil minus 1.5in]
  92. // \pageno=3
  93. // \def\glob[13] % this should be the section number of "<Global...>"
  94. // \def\gglob[20, 26] % this should be the next two sections of "<Global...>"
  95. //
  96. //
  97. // 1. \[1] Introduction
  98. // tangle:pos tex.web:95:22:
  99. // This is \TeX, a document compiler intended to produce typesetting of high
  100. // quality.
  101. // The \PASCAL\ program that follows is the definition of \TeX82, a standard
  102. // \xref[PASCAL][\PASCAL]
  103. // \xref[TeX82][\TeX82]
  104. // version of \TeX\ that is designed to be highly portable so that identical output
  105. // will be obtainable on a great variety of computers.
  106. //
  107. // The main purpose of the following program is to explain the algorithms of \TeX\
  108. // as clearly as possible. As a result, the program will not necessarily be very
  109. // efficient when a particular \PASCAL\ compiler has translated it into a
  110. // particular machine language. However, the program has been written so that it
  111. // can be tuned to run efficiently in a wide variety of operating environments
  112. // by making comparatively few changes. Such flexibility is possible because
  113. // the documentation that follows is written in the \.[WEB] language, which is
  114. // at a higher level than \PASCAL; the preprocessing step that converts \.[WEB]
  115. // to \PASCAL\ is able to introduce most of the necessary refinements.
  116. // Semi-automatic translation to other languages is also feasible, because the
  117. // program below does not make extensive use of features that are peculiar to
  118. // \PASCAL.
  119. //
  120. // A large piece of software like \TeX\ has inherent complexity that cannot
  121. // be reduced below a certain level of difficulty, although each individual
  122. // part is fairly simple by itself. The \.[WEB] language is intended to make
  123. // the algorithms as readable as possible, by reflecting the way the
  124. // individual program pieces fit together and by providing the
  125. // cross-references that connect different parts. Detailed comments about
  126. // what is going on, and about why things were done in certain ways, have
  127. // been liberally sprinkled throughout the program. These comments explain
  128. // features of the implementation, but they rarely attempt to explain the
  129. // \TeX\ language itself, since the reader is supposed to be familiar with
  130. // [\sl The \TeX book].
  131. // \xref[WEB]
  132. // \xref[TeXbook][\sl The \TeX book]
  133. // 2.
  134. // tangle:pos tex.web:131:3:
  135. // The present implementation has a long ancestry, beginning in the summer
  136. // of~1977, when Michael~F. Plass and Frank~M. Liang designed and coded
  137. // a prototype
  138. // \xref[Plass, Michael Frederick]
  139. // \xref[Liang, Franklin Mark]
  140. // \xref[Knuth, Donald Ervin]
  141. // based on some specifications that the author had made in May of that year.
  142. // This original proto\TeX\ included macro definitions and elementary
  143. // manipulations on boxes and glue, but it did not have line-breaking,
  144. // page-breaking, mathematical formulas, alignment routines, error recovery,
  145. // or the present semantic nest; furthermore,
  146. // it used character lists instead of token lists, so that a control sequence
  147. // like \.[\\halign] was represented by a list of seven characters. A
  148. // complete version of \TeX\ was designed and coded by the author in late
  149. // 1977 and early 1978; that program, like its prototype, was written in the
  150. // [\mc SAIL] language, for which an excellent debugging system was
  151. // available. Preliminary plans to convert the [\mc SAIL] code into a form
  152. // somewhat like the present ``web'' were developed by Luis Trabb~Pardo and
  153. // \xref[Trabb Pardo, Luis Isidoro]
  154. // the author at the beginning of 1979, and a complete implementation was
  155. // created by Ignacio~A. Zabala in 1979 and 1980. The \TeX82 program, which
  156. // \xref[Zabala Salelles, Ignacio Andr\'es]
  157. // was written by the author during the latter part of 1981 and the early
  158. // part of 1982, also incorporates ideas from the 1979 implementation of
  159. // \xref[Guibas, Leonidas Ioannis]
  160. // \xref[Sedgewick, Robert]
  161. // \xref[Wyatt, Douglas Kirk]
  162. // \TeX\ in [\mc MESA] that was written by Leonidas Guibas, Robert Sedgewick,
  163. // and Douglas Wyatt at the Xerox Palo Alto Research Center. Several hundred
  164. // refinements were introduced into \TeX82 based on the experiences gained with
  165. // the original implementations, so that essentially every part of the system
  166. // has been substantially improved. After the appearance of ``Version 0'' in
  167. // September 1982, this program benefited greatly from the comments of
  168. // many other people, notably David~R. Fuchs and Howard~W. Trickey.
  169. // A final revision in September 1989 extended the input character set to
  170. // eight-bit codes and introduced the ability to hyphenate words from
  171. // different languages, based on some ideas of Michael~J. Ferguson.
  172. // \xref[Fuchs, David Raymond]
  173. // \xref[Trickey, Howard Wellington]
  174. // \xref[Ferguson, Michael John]
  175. //
  176. // No doubt there still is plenty of room for improvement, but the author
  177. // is firmly committed to keeping \TeX82 ``frozen'' from now on; stability
  178. // and reliability are to be its main virtues.
  179. //
  180. // On the other hand, the \.[WEB] description can be extended without changing
  181. // the core of \TeX82 itself, and the program has been designed so that such
  182. // extensions are not extremely difficult to make.
  183. // The |banner| string defined here should be changed whenever \TeX\
  184. // undergoes any modifications, so that it will be clear which version of
  185. // \TeX\ might be the guilty party when a problem arises.
  186. // \xref[extensions to \TeX]
  187. // \xref[system dependencies]
  188. //
  189. // If this program is changed, the resulting system should not be called
  190. // `\TeX'; the official name `\TeX' by itself is reserved
  191. // for software systems that are fully compatible with each other.
  192. // A special test suite called the ``\.[TRIP] test'' is available for
  193. // helping to determine whether a particular implementation deserves to be
  194. // known as `\TeX' [cf.~Stanford Computer Science report CS1027,
  195. // November 1984].
  196. // 3.
  197. // tangle:pos tex.web:195:3:
  198. // Different \PASCAL s have slightly different conventions, and the present
  199. // \xref[PASCAL H][\ph]
  200. // program expresses \TeX\ in terms of the \PASCAL\ that was
  201. // available to the author in 1982. Constructions that apply to
  202. // this particular compiler, which we shall call \ph, should help the
  203. // reader see how to make an appropriate interface for other systems
  204. // if necessary. (\ph\ is Charles Hedrick's modification of a compiler
  205. // \xref[Hedrick, Charles Locke]
  206. // for the DECsystem-10 that was originally developed at the University of
  207. // Hamburg; cf.\ [\sl Software---Practice and Experience \bf6] (1976),
  208. // 29--42. The \TeX\ program below is intended to be adaptable, without
  209. // extensive changes, to most other versions of \PASCAL, so it does not fully
  210. // use the admirable features of \ph. Indeed, a conscious effort has been
  211. // made here to avoid using several idiosyncratic features of standard
  212. // \PASCAL\ itself, so that most of the code can be translated mechanically
  213. // into other high-level languages. For example, the `\&[with]' and `\\[new]'
  214. // features are not used, nor are pointer types, set types, or enumerated
  215. // scalar types; there are no `\&[var]' parameters, except in the case of files;
  216. // there are no tag fields on variant records; there are no assignments
  217. // |real:=integer|; no procedures are declared local to other procedures.)
  218. //
  219. // The portions of this program that involve system-dependent code, where
  220. // changes might be necessary because of differences between \PASCAL\ compilers
  221. // and/or differences between
  222. // operating systems, can be identified by looking at the sections whose
  223. // numbers are listed under `system dependencies' in the index. Furthermore,
  224. // the index entries for `dirty \PASCAL' list all places where the restrictions
  225. // of \PASCAL\ have not been followed perfectly, for one reason or another.
  226. // \xref[system dependencies]
  227. // \xref[dirty \PASCAL]
  228. //
  229. // Incidentally, \PASCAL's standard |round| function can be problematical,
  230. // because it disagrees with the IEEE floating-point standard.
  231. // Many implementors have
  232. // therefore chosen to substitute their own home-grown rounding procedure.
  233. // 4.
  234. // tangle:pos tex.web:231:3:
  235. // The program begins with a normal \PASCAL\ program heading, whose
  236. // components will be filled in later, using the conventions of \.[WEB].
  237. // \xref[WEB]
  238. // For example, the portion of the program called `\X\glob:Global
  239. // variables\X' below will be replaced by a sequence of variable declarations
  240. // that starts in $\section\glob$ of this documentation. In this way, we are able
  241. // to define each individual global variable when we are prepared to
  242. // understand what it means; we do not have to define all of the globals at
  243. // once. Cross references in $\section\glob$, where it says ``See also
  244. // sections \gglob, \dots,'' also make it possible to look at the set of
  245. // all global variables, if desired. Similar remarks apply to the other
  246. // portions of the program heading.
  247. //
  248. // Actually the heading shown here is not quite normal: The |program| line
  249. // does not mention any |output| file, because \ph\ would ask the \TeX\ user
  250. // to specify a file name if |output| were specified here.
  251. // \xref[PASCAL H][\ph]
  252. // \xref[system dependencies]
  253. // \4
  254. // Compiler directives
  255. // $C-,A+,D-
  256. // no range check, catch arithmetic overflow, no debug overhead
  257. // [$C+,D+] [ ]
  258. // but turn everything on when debugging
  259. package tex
  260. import (
  261. "math"
  262. "unsafe"
  263. "modernc.org/knuth"
  264. )
  265. var (
  266. _ = math.MaxInt32
  267. _ unsafe.Pointer
  268. )
  269. type (
  270. char = byte
  271. signal int
  272. )
  273. func strcopy(dst []char, src string) {
  274. for i := 0; i < len(dst) && i < len(src); i++ {
  275. dst[i] = src[i]
  276. }
  277. }
  278. func arraystr(a []char) string {
  279. b := make([]byte, len(a))
  280. for i, c := range a {
  281. b[i] = c
  282. }
  283. return string(b)
  284. }
  285. func abs(n int32) int32 {
  286. if n >= 0 {
  287. return n
  288. }
  289. return -n
  290. }
  291. func fabs(f float64) float64 {
  292. if f >= 0 {
  293. return f
  294. }
  295. return -f
  296. }
  297. func round(f float64) int32 {
  298. if f >= 0 {
  299. return int32(f + 0.5)
  300. }
  301. return int32(f - 0.5)
  302. }
  303. // key control points
  304. const (
  305. startOfTex = 1 /* go here when \TeX's variables are initialized */
  306. endOfTex = 9998 /* go here to close files and terminate gracefully */
  307. finalEnd = 9999 /* this label marks the ending of the program */
  308. memBot = 0 // smallest index in the |mem| array dumped by \.[INITEX];
  309. // must not be less than |mem_min|
  310. fontBase = 0 // smallest internal font number; must not be less
  311. // than |min_quarterword|
  312. hashSize = 2100 // maximum number of control sequences; it should be at most
  313. // about |(mem_max-mem_min)/10|
  314. hashPrime = 1777 /* a prime number equal to about 85\pct! of |hash_size| */
  315. hyphSize = 307 // another prime; the number of \.[\\hyphenation] exceptions
  316. // \xref[system dependencies]
  317. exit = 10 /* go here to leave a procedure */
  318. restart = 20 /* go here to start a procedure again */
  319. reswitch = 21 /* go here to start a case statement again */
  320. continue1 = 22 /* go here to resume a loop */
  321. done = 30 /* go here to exit a loop */
  322. done1 = 31 /* like |done|, when there is more than one loop */
  323. done2 = 32 /* for exiting the second loop in a long block */
  324. done3 = 33 /* for exiting the third loop in a very long block */
  325. done4 = 34 /* for exiting the fourth loop in an extremely long block */
  326. done5 = 35 /* for exiting the fifth loop in an immense block */
  327. done6 = 36 /* for exiting the sixth loop in a block */
  328. found = 40 /* go here when you've found it */
  329. found1 = 41 /* like |found|, when there's more than one per routine */
  330. found2 = 42 /* like |found|, when there's more than two per routine */
  331. notFound = 45 /* go here when you've found nothing */
  332. commonEnding = 50 /* go here when you want to merge with another branch */
  333. empty = 0 /* symbolic name for a null constant */
  334. firstTextChar = 0 /* ordinal number of the smallest element of |text_char| */
  335. lastTextChar = 255 /* ordinal number of the largest element of |text_char| */
  336. nullCode = 0 /* ASCII code that might disappear */
  337. carriageReturn = 015 /* ASCII code used at end of line */
  338. invalidCode = 0177 /* ASCII code that many systems prohibit in text files */
  339. noPrint = 16 /* |selector| setting that makes data disappear */
  340. termOnly = 17 /* printing is destined for the terminal only */
  341. logOnly = 18 /* printing is destined for the transcript file only */
  342. termAndLog = 19 /* normal |selector| setting */
  343. pseudo = 20 /* special |selector| setting for |show_context| */
  344. newString = 21 /* printing is deflected to the string pool */
  345. maxSelector = 21 /* highest selector setting */
  346. batchMode = 0 /* omits all stops and omits terminal output */
  347. nonstopMode = 1 /* omits all stops */
  348. scrollMode = 2 /* omits error stops */
  349. errorStopMode = 3 /* stops at every opportunity to interact */
  350. spotless = 0 /* |history| value when nothing has been amiss yet */
  351. warningIssued = 1 /* |history| value when |begin_diagnostic| has been called */
  352. errorMessageIssued = 2 /* |history| value when |error| has been called */
  353. fatalErrorStop = 3 /* |history| value when termination was premature */
  354. infBad = 10000 /* infinitely bad value */
  355. minQuarterword = 0 /* smallest allowable value in a |quarterword| */
  356. maxQuarterword = 255 /* largest allowable value in a |quarterword| */
  357. hlistNode = 0 /* |type| of hlist nodes */
  358. boxNodeSize = 7 /* number of words to allocate for a box node */
  359. widthOffset = 1 /* position of |width| field in a box node */
  360. depthOffset = 2 /* position of |depth| field in a box node */
  361. heightOffset = 3 /* position of |height| field in a box node */
  362. listOffset = 5 /* position of |list_ptr| field in a box node */
  363. normal = 0 /* the most common case when several cases are named */
  364. stretching = 1 /* glue setting applies to the stretch components */
  365. shrinking = 2 /* glue setting applies to the shrink components */
  366. glueOffset = 6 /* position of |glue_set| in a box node */
  367. vlistNode = 1 /* |type| of vlist nodes */
  368. ruleNode = 2 /* |type| of rule nodes */
  369. ruleNodeSize = 4 /* number of words to allocate for a rule node */
  370. insNode = 3 /* |type| of insertion nodes */
  371. insNodeSize = 5 /* number of words to allocate for an insertion */
  372. markNode = 4 /* |type| of a mark node */
  373. smallNodeSize = 2 /* number of words to allocate for most node types */
  374. adjustNode = 5 /* |type| of an adjust node */
  375. ligatureNode = 6 /* |type| of a ligature node */
  376. discNode = 7 /* |type| of a discretionary node */
  377. whatsitNode = 8 /* |type| of special extension nodes */
  378. mathNode = 9 /* |type| of a math node */
  379. before = 0 /* |subtype| for math node that introduces a formula */
  380. after = 1 /* |subtype| for math node that winds up a formula */
  381. glueNode = 10 /* |type| of node that points to a glue specification */
  382. condMathGlue = 98 /* special |subtype| to suppress glue in the next node */
  383. muGlue = 99 /* |subtype| for math glue */
  384. aLeaders = 100 /* |subtype| for aligned leaders */
  385. cLeaders = 101 /* |subtype| for centered leaders */
  386. xLeaders = 102 /* |subtype| for expanded leaders */
  387. glueSpecSize = 4 /* number of words to allocate for a glue specification */
  388. fil = 1 /* first-order infinity */
  389. fill = 2 /* second-order infinity */
  390. filll = 3 /* third-order infinity */
  391. kernNode = 11 /* |type| of a kern node */
  392. explicit = 1 /* |subtype| of kern nodes from \.[\\kern] and \.[\\/] */
  393. accKern = 2 /* |subtype| of kern nodes from accents */
  394. penaltyNode = 12 /* |type| of a penalty node */
  395. infPenalty = infBad /* ``infinite'' penalty value */
  396. ejectPenalty = -infPenalty /* ``negatively infinite'' penalty value */
  397. unsetNode = 13 /* |type| for an unset node */
  398. hiMemStatUsage = 14 /* the number of one-word nodes always present */
  399. escape = 0 // escape delimiter (called \.\\ in [\sl The \TeX book\/])
  400. // \xref[TeXbook][\sl The \TeX book]
  401. relax = 0 /* do nothing ( \.[\\relax] ) */
  402. leftBrace = 1 /* beginning of a group ( \.\[ ) */
  403. rightBrace = 2 /* ending of a group ( \.\] ) */
  404. mathShift = 3 /* mathematics shift character ( \.\$ ) */
  405. tabMark = 4 /* alignment delimiter ( \.\&, \.[\\span] ) */
  406. carRet = 5 /* end of line ( |carriage_return|, \.[\\cr], \.[\\crcr] ) */
  407. outParam = 5 /* output a macro parameter */
  408. macParam = 6 /* macro parameter symbol ( \.\# ) */
  409. supMark = 7 /* superscript ( \.[\char'136] ) */
  410. subMark = 8 /* subscript ( \.[\char'137] ) */
  411. ignore = 9 /* characters to ignore ( \.[\^\^@] ) */
  412. endv = 9 /* end of \<v_j> list in alignment template */
  413. spacer = 10 /* characters equivalent to blank space ( \.[\ ] ) */
  414. letter = 11 /* characters regarded as letters ( \.[A..Z], \.[a..z] ) */
  415. otherChar = 12 /* none of the special character types */
  416. activeChar = 13 /* characters that invoke macros ( \.[\char`\~] ) */
  417. parEnd = 13 /* end of paragraph ( \.[\\par] ) */
  418. match = 13 /* match a macro parameter */
  419. comment = 14 /* characters that introduce comments ( \.\% ) */
  420. endMatch = 14 /* end of parameters to macro */
  421. stop = 14 /* end of job ( \.[\\end], \.[\\dump] ) */
  422. invalidChar = 15 /* characters that shouldn't appear ( \.[\^\^?] ) */
  423. delimNum = 15 /* specify delimiter numerically ( \.[\\delimiter] ) */
  424. maxCharCode = 15 /* largest catcode for individual characters */
  425. charNum = 16 /* character specified numerically ( \.[\\char] ) */
  426. mathCharNum = 17 /* explicit math code ( \.[\\mathchar] ) */
  427. mark = 18 /* mark definition ( \.[\\mark] ) */
  428. xray = 19 /* peek inside of \TeX\ ( \.[\\show], \.[\\showbox], etc.~) */
  429. makeBox = 20 /* make a box ( \.[\\box], \.[\\copy], \.[\\hbox], etc.~) */
  430. hmove = 21 /* horizontal motion ( \.[\\moveleft], \.[\\moveright] ) */
  431. vmove = 22 /* vertical motion ( \.[\\raise], \.[\\lower] ) */
  432. unHbox = 23 /* unglue a box ( \.[\\unhbox], \.[\\unhcopy] ) */
  433. unVbox = 24 /* unglue a box ( \.[\\unvbox], \.[\\unvcopy] ) */
  434. removeItem = 25 // nullify last item ( \.[\\unpenalty],
  435. // \.[\\unkern], \.[\\unskip] )
  436. hskip = 26 /* horizontal glue ( \.[\\hskip], \.[\\hfil], etc.~) */
  437. vskip = 27 /* vertical glue ( \.[\\vskip], \.[\\vfil], etc.~) */
  438. mskip = 28 /* math glue ( \.[\\mskip] ) */
  439. kern = 29 /* fixed space ( \.[\\kern] ) */
  440. mkern = 30 /* math kern ( \.[\\mkern] ) */
  441. leaderShip = 31 /* use a box ( \.[\\shipout], \.[\\leaders], etc.~) */
  442. halign = 32 /* horizontal table alignment ( \.[\\halign] ) */
  443. valign = 33 /* vertical table alignment ( \.[\\valign] ) */
  444. noAlign = 34 /* temporary escape from alignment ( \.[\\noalign] ) */
  445. vrule = 35 /* vertical rule ( \.[\\vrule] ) */
  446. hrule = 36 /* horizontal rule ( \.[\\hrule] ) */
  447. insert = 37 /* vlist inserted in box ( \.[\\insert] ) */
  448. vadjust = 38 /* vlist inserted in enclosing paragraph ( \.[\\vadjust] ) */
  449. ignoreSpaces = 39 /* gobble |spacer| tokens ( \.[\\ignorespaces] ) */
  450. afterAssignment = 40 /* save till assignment is done ( \.[\\afterassignment] ) */
  451. afterGroup = 41 /* save till group is done ( \.[\\aftergroup] ) */
  452. breakPenalty = 42 /* additional badness ( \.[\\penalty] ) */
  453. startPar = 43 /* begin paragraph ( \.[\\indent], \.[\\noindent] ) */
  454. italCorr = 44 /* italic correction ( \.[\\/] ) */
  455. accent = 45 /* attach accent in text ( \.[\\accent] ) */
  456. mathAccent = 46 /* attach accent in math ( \.[\\mathaccent] ) */
  457. discretionary = 47 /* discretionary texts ( \.[\\-], \.[\\discretionary] ) */
  458. eqNo = 48 /* equation number ( \.[\\eqno], \.[\\leqno] ) */
  459. leftRight = 49 /* variable delimiter ( \.[\\left], \.[\\right] ) */
  460. mathComp = 50 /* component of formula ( \.[\\mathbin], etc.~) */
  461. limitSwitch = 51 /* diddle limit conventions ( \.[\\displaylimits], etc.~) */
  462. above = 52 /* generalized fraction ( \.[\\above], \.[\\atop], etc.~) */
  463. mathStyle = 53 /* style specification ( \.[\\displaystyle], etc.~) */
  464. mathChoice = 54 /* choice specification ( \.[\\mathchoice] ) */
  465. nonScript = 55 /* conditional math glue ( \.[\\nonscript] ) */
  466. vcenter = 56 /* vertically center a vbox ( \.[\\vcenter] ) */
  467. caseShift = 57 /* force specific case ( \.[\\lowercase], \.[\\uppercase]~) */
  468. message = 58 /* send to user ( \.[\\message], \.[\\errmessage] ) */
  469. extension = 59 /* extensions to \TeX\ ( \.[\\write], \.[\\special], etc.~) */
  470. inStream = 60 /* files for reading ( \.[\\openin], \.[\\closein] ) */
  471. beginGroup = 61 /* begin local grouping ( \.[\\begingroup] ) */
  472. endGroup = 62 /* end local grouping ( \.[\\endgroup] ) */
  473. omit = 63 /* omit alignment template ( \.[\\omit] ) */
  474. exSpace = 64 /* explicit space ( \.[\\\ ] ) */
  475. noBoundary = 65 /* suppress boundary ligatures ( \.[\\noboundary] ) */
  476. radical = 66 /* square root and similar signs ( \.[\\radical] ) */
  477. endCsName = 67 /* end control sequence ( \.[\\endcsname] ) */
  478. minInternal = 68 /* the smallest code that can follow \.[\\the] */
  479. charGiven = 68 /* character code defined by \.[\\chardef] */
  480. mathGiven = 69 /* math code defined by \.[\\mathchardef] */
  481. lastItem = 70 // most recent item ( \.[\\lastpenalty],
  482. // \.[\\lastkern], \.[\\lastskip] )
  483. maxNonPrefixedCommand = 70 /* largest command code that can't be \.[\\global] */
  484. toksRegister = 71 /* token list register ( \.[\\toks] ) */
  485. assignToks = 72 /* special token list ( \.[\\output], \.[\\everypar], etc.~) */
  486. assignInt = 73 /* user-defined integer ( \.[\\tolerance], \.[\\day], etc.~) */
  487. assignDimen = 74 /* user-defined length ( \.[\\hsize], etc.~) */
  488. assignGlue = 75 /* user-defined glue ( \.[\\baselineskip], etc.~) */
  489. assignMuGlue = 76 /* user-defined muglue ( \.[\\thinmuskip], etc.~) */
  490. assignFontDimen = 77 /* user-defined font dimension ( \.[\\fontdimen] ) */
  491. assignFontInt = 78 // user-defined font integer ( \.[\\hyphenchar],
  492. // \.[\\skewchar] )
  493. setAux = 79 /* specify state info ( \.[\\spacefactor], \.[\\prevdepth] ) */
  494. setPrevGraf = 80 /* specify state info ( \.[\\prevgraf] ) */
  495. setPageDimen = 81 /* specify state info ( \.[\\pagegoal], etc.~) */
  496. setPageInt = 82 // specify state info ( \.[\\deadcycles],
  497. // \.[\\insertpenalties] )
  498. setBoxDimen = 83 /* change dimension of box ( \.[\\wd], \.[\\ht], \.[\\dp] ) */
  499. setShape = 84 /* specify fancy paragraph shape ( \.[\\parshape] ) */
  500. defCode = 85 /* define a character code ( \.[\\catcode], etc.~) */
  501. defFamily = 86 /* declare math fonts ( \.[\\textfont], etc.~) */
  502. setFont = 87 /* set current font ( font identifiers ) */
  503. defFont = 88 /* define a font file ( \.[\\font] ) */
  504. register = 89 /* internal register ( \.[\\count], \.[\\dimen], etc.~) */
  505. maxInternal = 89 /* the largest code that can follow \.[\\the] */
  506. advance = 90 /* advance a register or parameter ( \.[\\advance] ) */
  507. multiply = 91 /* multiply a register or parameter ( \.[\\multiply] ) */
  508. divide = 92 /* divide a register or parameter ( \.[\\divide] ) */
  509. prefix = 93 /* qualify a definition ( \.[\\global], \.[\\long], \.[\\outer] ) */
  510. let = 94 /* assign a command code ( \.[\\let], \.[\\futurelet] ) */
  511. shorthandDef = 95 /* code definition ( \.[\\chardef], \.[\\countdef], etc.~) */
  512. readToCs = 96 /* read into a control sequence ( \.[\\read] ) */
  513. def = 97 /* macro definition ( \.[\\def], \.[\\gdef], \.[\\xdef], \.[\\edef] ) */
  514. setBox = 98 /* set a box ( \.[\\setbox] ) */
  515. hyphData = 99 /* hyphenation data ( \.[\\hyphenation], \.[\\patterns] ) */
  516. setInteraction = 100 /* define level of interaction ( \.[\\batchmode], etc.~) */
  517. maxCommand = 100 /* the largest command code seen at |big_switch| */
  518. undefinedCs = maxCommand + 1 /* initial state of most |eq_type| fields */
  519. expandAfter = maxCommand + 2 /* special expansion ( \.[\\expandafter] ) */
  520. noExpand = maxCommand + 3 /* special nonexpansion ( \.[\\noexpand] ) */
  521. input = maxCommand + 4 /* input a source file ( \.[\\input], \.[\\endinput] ) */
  522. ifTest = maxCommand + 5 /* conditional text ( \.[\\if], \.[\\ifcase], etc.~) */
  523. fiOrElse = maxCommand + 6 /* delimiters for conditionals ( \.[\\else], etc.~) */
  524. csName = maxCommand + 7 /* make a control sequence from tokens ( \.[\\csname] ) */
  525. convert = maxCommand + 8 /* convert to text ( \.[\\number], \.[\\string], etc.~) */
  526. the = maxCommand + 9 /* expand an internal quantity ( \.[\\the] ) */
  527. topBotMark = maxCommand + 10 /* inserted mark ( \.[\\topmark], etc.~) */
  528. call = maxCommand + 11 /* non-long, non-outer control sequence */
  529. longCall = maxCommand + 12 /* long, non-outer control sequence */
  530. outerCall = maxCommand + 13 /* non-long, outer control sequence */
  531. longOuterCall = maxCommand + 14 /* long, outer control sequence */
  532. endTemplate = maxCommand + 15 /* end of an alignment template */
  533. dontExpand = maxCommand + 16 /* the following token was marked by \.[\\noexpand] */
  534. glueRef = maxCommand + 17 /* the equivalent points to a glue specification */
  535. shapeRef = maxCommand + 18 /* the equivalent points to a parshape specification */
  536. boxRef = maxCommand + 19 /* the equivalent points to a box node, or is |null| */
  537. data = maxCommand + 20 /* the equivalent is simply a halfword number */
  538. vmode = 1 /* vertical mode */
  539. hmode = vmode + maxCommand + 1 /* horizontal mode */
  540. mmode = hmode + maxCommand + 1 /* math mode */
  541. levelZero = minQuarterword /* level for undefined quantities */
  542. levelOne = levelZero + 1 /* outermost level for defined quantities */
  543. activeBase = 1 /* beginning of region 1, for active character equivalents */
  544. singleBase = activeBase + 256 /* equivalents of one-character control sequences */
  545. nullCs = singleBase + 256 /* equivalent of \.[\\csname\\endcsname] */
  546. hashBase = nullCs + 1 /* beginning of region 2, for the hash table */
  547. frozenControlSequence = hashBase + hashSize /* for error recovery */
  548. frozenProtection = frozenControlSequence /* inaccessible but definable */
  549. frozenCr = frozenControlSequence + 1 /* permanent `\.[\\cr]' */
  550. frozenEndGroup = frozenControlSequence + 2 /* permanent `\.[\\endgroup]' */
  551. frozenRight = frozenControlSequence + 3 /* permanent `\.[\\right]' */
  552. frozenFi = frozenControlSequence + 4 /* permanent `\.[\\fi]' */
  553. frozenEndTemplate = frozenControlSequence + 5 /* permanent `\.[\\endtemplate]' */
  554. frozenEndv = frozenControlSequence + 6 /* second permanent `\.[\\endtemplate]' */
  555. frozenRelax = frozenControlSequence + 7 /* permanent `\.[\\relax]' */
  556. endWrite = frozenControlSequence + 8 /* permanent `\.[\\endwrite]' */
  557. frozenDontExpand = frozenControlSequence + 9
  558. /* permanent `\.[\\notexpanded:]' */
  559. frozenNullFont = frozenControlSequence + 10
  560. /* permanent `\.[\\nullfont]' */
  561. fontIdBase = frozenNullFont - fontBase
  562. /* begins table of 257 permanent font identifiers */
  563. undefinedControlSequence = frozenNullFont + 257 /* dummy location */
  564. glueBase = undefinedControlSequence + 1 /* beginning of region 3 */
  565. lineSkipCode = 0 /* interline glue if |baseline_skip| is infeasible */
  566. baselineSkipCode = 1 /* desired glue between baselines */
  567. parSkipCode = 2 /* extra glue just above a paragraph */
  568. aboveDisplaySkipCode = 3 /* extra glue just above displayed math */
  569. belowDisplaySkipCode = 4 /* extra glue just below displayed math */
  570. aboveDisplayShortSkipCode = 5
  571. /* glue above displayed math following short lines */
  572. belowDisplayShortSkipCode = 6
  573. /* glue below displayed math following short lines */
  574. leftSkipCode = 7 /* glue at left of justified lines */
  575. rightSkipCode = 8 /* glue at right of justified lines */
  576. topSkipCode = 9 /* glue at top of main pages */
  577. splitTopSkipCode = 10 /* glue at top of split pages */
  578. tabSkipCode = 11 /* glue between aligned entries */
  579. spaceSkipCode = 12 /* glue between words (if not |zero_glue|) */
  580. xspaceSkipCode = 13 /* glue after sentences (if not |zero_glue|) */
  581. parFillSkipCode = 14 /* glue on last line of paragraph */
  582. thinMuSkipCode = 15 /* thin space in math formula */
  583. medMuSkipCode = 16 /* medium space in math formula */
  584. thickMuSkipCode = 17 /* thick space in math formula */
  585. gluePars = 18 /* total number of glue parameters */
  586. skipBase = glueBase + gluePars /* table of 256 ``skip'' registers */
  587. muSkipBase = skipBase + 256 /* table of 256 ``muskip'' registers */
  588. localBase = muSkipBase + 256 /* beginning of region 4 */
  589. parShapeLoc = localBase /* specifies paragraph shape */
  590. outputRoutineLoc = localBase + 1 /* points to token list for \.[\\output] */
  591. everyParLoc = localBase + 2 /* points to token list for \.[\\everypar] */
  592. everyMathLoc = localBase + 3 /* points to token list for \.[\\everymath] */
  593. everyDisplayLoc = localBase + 4 /* points to token list for \.[\\everydisplay] */
  594. everyHboxLoc = localBase + 5 /* points to token list for \.[\\everyhbox] */
  595. everyVboxLoc = localBase + 6 /* points to token list for \.[\\everyvbox] */
  596. everyJobLoc = localBase + 7 /* points to token list for \.[\\everyjob] */
  597. everyCrLoc = localBase + 8 /* points to token list for \.[\\everycr] */
  598. errHelpLoc = localBase + 9 /* points to token list for \.[\\errhelp] */
  599. toksBase = localBase + 10 /* table of 256 token list registers */
  600. boxBase = toksBase + 256 /* table of 256 box registers */
  601. curFontLoc = boxBase + 256 /* internal font number outside math mode */
  602. mathFontBase = curFontLoc + 1 /* table of 48 math font numbers */
  603. catCodeBase = mathFontBase + 48
  604. /* table of 256 command codes (the ``catcodes'') */
  605. lcCodeBase = catCodeBase + 256 /* table of 256 lowercase mappings */
  606. ucCodeBase = lcCodeBase + 256 /* table of 256 uppercase mappings */
  607. sfCodeBase = ucCodeBase + 256 /* table of 256 spacefactor mappings */
  608. mathCodeBase = sfCodeBase + 256 /* table of 256 math mode mappings */
  609. intBase = mathCodeBase + 256 /* beginning of region 5 */
  610. pretoleranceCode = 0 /* badness tolerance before hyphenation */
  611. toleranceCode = 1 /* badness tolerance after hyphenation */
  612. linePenaltyCode = 2 /* added to the badness of every line */
  613. hyphenPenaltyCode = 3 /* penalty for break after discretionary hyphen */
  614. exHyphenPenaltyCode = 4 /* penalty for break after explicit hyphen */
  615. clubPenaltyCode = 5 /* penalty for creating a club line */
  616. widowPenaltyCode = 6 /* penalty for creating a widow line */
  617. displayWidowPenaltyCode = 7 /* ditto, just before a display */
  618. brokenPenaltyCode = 8 /* penalty for breaking a page at a broken line */
  619. binOpPenaltyCode = 9 /* penalty for breaking after a binary operation */
  620. relPenaltyCode = 10 /* penalty for breaking after a relation */
  621. preDisplayPenaltyCode = 11
  622. /* penalty for breaking just before a displayed formula */
  623. postDisplayPenaltyCode = 12
  624. /* penalty for breaking just after a displayed formula */
  625. interLinePenaltyCode = 13 /* additional penalty between lines */
  626. doubleHyphenDemeritsCode = 14 /* demerits for double hyphen break */
  627. finalHyphenDemeritsCode = 15 /* demerits for final hyphen break */
  628. adjDemeritsCode = 16 /* demerits for adjacent incompatible lines */
  629. magCode = 17 /* magnification ratio */
  630. delimiterFactorCode = 18 /* ratio for variable-size delimiters */
  631. loosenessCode = 19 /* change in number of lines for a paragraph */
  632. timeCode = 20 /* current time of day */
  633. dayCode = 21 /* current day of the month */
  634. monthCode = 22 /* current month of the year */
  635. yearCode = 23 /* current year of our Lord */
  636. showBoxBreadthCode = 24 /* nodes per level in |show_box| */
  637. showBoxDepthCode = 25 /* maximum level in |show_box| */
  638. hbadnessCode = 26 /* hboxes exceeding this badness will be shown by |hpack| */
  639. vbadnessCode = 27 /* vboxes exceeding this badness will be shown by |vpack| */
  640. pausingCode = 28 /* pause after each line is read from a file */
  641. tracingOnlineCode = 29 /* show diagnostic output on terminal */
  642. tracingMacrosCode = 30 /* show macros as they are being expanded */
  643. tracingStatsCode = 31 /* show memory usage if \TeX\ knows it */
  644. tracingParagraphsCode = 32 /* show line-break calculations */
  645. tracingPagesCode = 33 /* show page-break calculations */
  646. tracingOutputCode = 34 /* show boxes when they are shipped out */
  647. tracingLostCharsCode = 35 /* show characters that aren't in the font */
  648. tracingCommandsCode = 36 /* show command codes at |big_switch| */
  649. tracingRestoresCode = 37 /* show equivalents when they are restored */
  650. ucHyphCode = 38 /* hyphenate words beginning with a capital letter */
  651. outputPenaltyCode = 39 /* penalty found at current page break */
  652. maxDeadCyclesCode = 40 /* bound on consecutive dead cycles of output */
  653. hangAfterCode = 41 /* hanging indentation changes after this many lines */
  654. floatingPenaltyCode = 42 /* penalty for insertions held over after a split */
  655. globalDefsCode = 43 /* override \.[\\global] specifications */
  656. curFamCode = 44 /* current family */
  657. escapeCharCode = 45 /* escape character for token output */
  658. defaultHyphenCharCode = 46 /* value of \.[\\hyphenchar] when a font is loaded */
  659. defaultSkewCharCode = 47 /* value of \.[\\skewchar] when a font is loaded */
  660. endLineCharCode = 48 /* character placed at the right end of the buffer */
  661. newLineCharCode = 49 /* character that prints as |print_ln| */
  662. languageCode = 50 /* current hyphenation table */
  663. leftHyphenMinCode = 51 /* minimum left hyphenation fragment size */
  664. rightHyphenMinCode = 52 /* minimum right hyphenation fragment size */
  665. holdingInsertsCode = 53 /* do not remove insertion nodes from \.[\\box255] */
  666. errorContextLinesCode = 54 /* maximum intermediate line pairs shown */
  667. intPars = 55 /* total number of integer parameters */
  668. countBase = intBase + intPars /* 256 user \.[\\count] registers */
  669. delCodeBase = countBase + 256 /* 256 delimiter code mappings */
  670. dimenBase = delCodeBase + 256 /* beginning of region 6 */
  671. parIndentCode = 0 /* indentation of paragraphs */
  672. mathSurroundCode = 1 /* space around math in text */
  673. lineSkipLimitCode = 2 /* threshold for |line_skip| instead of |baseline_skip| */
  674. hsizeCode = 3 /* line width in horizontal mode */
  675. vsizeCode = 4 /* page height in vertical mode */
  676. maxDepthCode = 5 /* maximum depth of boxes on main pages */
  677. splitMaxDepthCode = 6 /* maximum depth of boxes on split pages */
  678. boxMaxDepthCode = 7 /* maximum depth of explicit vboxes */
  679. hfuzzCode = 8 /* tolerance for overfull hbox messages */
  680. vfuzzCode = 9 /* tolerance for overfull vbox messages */
  681. delimiterShortfallCode = 10 /* maximum amount uncovered by variable delimiters */
  682. nullDelimiterSpaceCode = 11 /* blank space in null delimiters */
  683. scriptSpaceCode = 12 /* extra space after subscript or superscript */
  684. preDisplaySizeCode = 13 /* length of text preceding a display */
  685. displayWidthCode = 14 /* length of line for displayed equation */
  686. displayIndentCode = 15 /* indentation of line for displayed equation */
  687. overfullRuleCode = 16 /* width of rule that identifies overfull hboxes */
  688. hangIndentCode = 17 /* amount of hanging indentation */
  689. hOffsetCode = 18 /* amount of horizontal offset when shipping pages out */
  690. vOffsetCode = 19 /* amount of vertical offset when shipping pages out */
  691. emergencyStretchCode = 20 /* reduces badnesses on final pass of line-breaking */
  692. dimenPars = 21 /* total number of dimension parameters */
  693. scaledBase = dimenBase + dimenPars
  694. /* table of 256 user-defined \.[\\dimen] registers */
  695. eqtbSize = scaledBase + 255 /* largest subscript of |eqtb| */
  696. restoreOldValue = 0 /* |save_type| when a value should be restored later */
  697. restoreZero = 1 /* |save_type| when an undefined entry should be restored */
  698. insertToken = 2 /* |save_type| when a token is being saved for later use */
  699. levelBoundary = 3 /* |save_type| corresponding to beginning of group */
  700. bottomLevel = 0 /* group code for the outside world */
  701. simpleGroup = 1 /* group code for local structure only */
  702. hboxGroup = 2 /* code for `\.[\\hbox]\grp' */
  703. adjustedHboxGroup = 3 /* code for `\.[\\hbox]\grp' in vertical mode */
  704. vboxGroup = 4 /* code for `\.[\\vbox]\grp' */
  705. vtopGroup = 5 /* code for `\.[\\vtop]\grp' */
  706. alignGroup = 6 /* code for `\.[\\halign]\grp', `\.[\\valign]\grp' */
  707. noAlignGroup = 7 /* code for `\.[\\noalign]\grp' */
  708. outputGroup = 8 /* code for output routine */
  709. mathGroup = 9 /* code for, e.g., `\.[\char'136]\grp' */
  710. discGroup = 10 /* code for `\.[\\discretionary]\grp\grp\grp' */
  711. insertGroup = 11 /* code for `\.[\\insert]\grp', `\.[\\vadjust]\grp' */
  712. vcenterGroup = 12 /* code for `\.[\\vcenter]\grp' */
  713. mathChoiceGroup = 13 /* code for `\.[\\mathchoice]\grp\grp\grp\grp' */
  714. semiSimpleGroup = 14 /* code for `\.[\\begingroup...\\endgroup]' */
  715. mathShiftGroup = 15 /* code for `\.[\$...\$]' */
  716. mathLeftGroup = 16 /* code for `\.[\\left...\\right]' */
  717. maxGroupCode = 16
  718. leftBraceToken = 0400 /* $2^8\cdot|left_brace|$ */
  719. leftBraceLimit = 01000 /* $2^8\cdot(|left_brace|+1)$ */
  720. rightBraceToken = 01000 /* $2^8\cdot|right_brace|$ */
  721. rightBraceLimit = 01400 /* $2^8\cdot(|right_brace|+1)$ */
  722. mathShiftToken = 01400 /* $2^8\cdot|math_shift|$ */
  723. tabToken = 02000 /* $2^8\cdot|tab_mark|$ */
  724. outParamToken = 02400 /* $2^8\cdot|out_param|$ */
  725. spaceToken = 05040 /* $2^8\cdot|spacer|+|" "|$ */
  726. letterToken = 05400 /* $2^8\cdot|letter|$ */
  727. otherToken = 06000 /* $2^8\cdot|other_char|$ */
  728. matchToken = 06400 /* $2^8\cdot|match|$ */
  729. endMatchToken = 07000 /* $2^8\cdot|end_match|$ */
  730. midLine = 1 /* |state| code when scanning a line of characters */
  731. skipBlanks = 2 + maxCharCode /* |state| code when ignoring blanks */
  732. newLine = 3 + maxCharCode + maxCharCode /* |state| code at start of line */
  733. skipping = 1 /* |scanner_status| when passing conditional text */
  734. defining = 2 /* |scanner_status| when reading a macro definition */
  735. matching = 3 /* |scanner_status| when reading macro arguments */
  736. aligning = 4 /* |scanner_status| when reading an alignment preamble */
  737. absorbing = 5 /* |scanner_status| when reading a balanced text */
  738. tokenList = 0 /* |state| code when scanning a token list */
  739. parameter = 0 /* |token_type| code for parameter */
  740. uTemplate = 1 /* |token_type| code for \<u_j> template */
  741. vTemplate = 2 /* |token_type| code for \<v_j> template */
  742. backedUp = 3 /* |token_type| code for text to be reread */
  743. inserted = 4 /* |token_type| code for inserted texts */
  744. macro = 5 /* |token_type| code for defined control sequences */
  745. outputText = 6 /* |token_type| code for output routines */
  746. everyParText = 7 /* |token_type| code for \.[\\everypar] */
  747. everyMathText = 8 /* |token_type| code for \.[\\everymath] */
  748. everyDisplayText = 9 /* |token_type| code for \.[\\everydisplay] */
  749. everyHboxText = 10 /* |token_type| code for \.[\\everyhbox] */
  750. everyVboxText = 11 /* |token_type| code for \.[\\everyvbox] */
  751. everyJobText = 12 /* |token_type| code for \.[\\everyjob] */
  752. everyCrText = 13 /* |token_type| code for \.[\\everycr] */
  753. markText = 14 /* |token_type| code for \.[\\topmark], etc. */
  754. writeText = 15 /* |token_type| code for \.[\\write] */
  755. switch1 = 25 /* a label in |get_next| */
  756. startCs = 26 /* another */
  757. noExpandFlag = 257 /* this characterizes a special variant of |relax| */
  758. topMarkCode = 0 /* the mark in effect at the previous page break */
  759. firstMarkCode = 1 /* the first mark between |top_mark| and |bot_mark| */
  760. botMarkCode = 2 /* the mark in effect at the current page break */
  761. splitFirstMarkCode = 3 /* the first mark found by \.[\\vsplit] */
  762. splitBotMarkCode = 4 /* the last mark found by \.[\\vsplit] */
  763. intVal = 0 /* integer values */
  764. dimenVal = 1 /* dimension values */
  765. glueVal = 2 /* glue specifications */
  766. muVal = 3 /* math glue specifications */
  767. identVal = 4 /* font identifier */
  768. tokVal = 5 /* token lists */
  769. inputLineNoCode = glueVal + 1 /* code for \.[\\inputlineno] */
  770. badnessCode = glueVal + 2 /* code for \.[\\badness] */
  771. octalToken = otherToken + '\'' /* apostrophe, indicates an octal constant */
  772. hexToken = otherToken + '"' /* double quote, indicates a hex constant */
  773. alphaToken = otherToken + '`' /* reverse apostrophe, precedes alpha constants */
  774. pointToken = otherToken + '.' /* decimal point */
  775. continentalPointToken = otherToken + ',' /* decimal point, Eurostyle */
  776. zeroToken = otherToken + '0' /* zero, the smallest digit */
  777. aToken = letterToken + 'A' /* the smallest special hex digit */
  778. otherAToken = otherToken + 'A' /* special hex digit of type |other_char| */
  779. attachFraction = 88 /* go here to pack |cur_val| and |f| into |cur_val| */
  780. attachSign = 89 /* go here when |cur_val| is correct except perhaps for sign */
  781. defaultRule = 26214 /* 0.4\thinspace pt */
  782. numberCode = 0 /* command code for \.[\\number] */
  783. romanNumeralCode = 1 /* command code for \.[\\romannumeral] */
  784. stringCode = 2 /* command code for \.[\\string] */
  785. meaningCode = 3 /* command code for \.[\\meaning] */
  786. fontNameCode = 4 /* command code for \.[\\fontname] */
  787. jobNameCode = 5 /* command code for \.[\\jobname] */
  788. closed = 2 /* not open, or at end of file */
  789. justOpen = 1 /* newly opened, first line not yet read */
  790. ifCharCode = 0 /* `\.[\\if]' */
  791. ifCatCode = 1 /* `\.[\\ifcat]' */
  792. ifIntCode = 2 /* `\.[\\ifnum]' */
  793. ifDimCode = 3 /* `\.[\\ifdim]' */
  794. ifOddCode = 4 /* `\.[\\ifodd]' */
  795. ifVmodeCode = 5 /* `\.[\\ifvmode]' */
  796. ifHmodeCode = 6 /* `\.[\\ifhmode]' */
  797. ifMmodeCode = 7 /* `\.[\\ifmmode]' */
  798. ifInnerCode = 8 /* `\.[\\ifinner]' */
  799. ifVoidCode = 9 /* `\.[\\ifvoid]' */
  800. ifHboxCode = 10 /* `\.[\\ifhbox]' */
  801. ifVboxCode = 11 /* `\.[\\ifvbox]' */
  802. ifxCode = 12 /* `\.[\\ifx]' */
  803. ifEofCode = 13 /* `\.[\\ifeof]' */
  804. ifTrueCode = 14 /* `\.[\\iftrue]' */
  805. ifFalseCode = 15 /* `\.[\\iffalse]' */
  806. ifCaseCode = 16 /* `\.[\\ifcase]' */
  807. ifNodeSize = 2 /* number of words in stack entry for conditionals */
  808. ifCode = 1 /* code for \.[\\if...] being evaluated */
  809. fiCode = 2 /* code for \.[\\fi] */
  810. elseCode = 3 /* code for \.[\\else] */
  811. orCode = 4 /* code for \.[\\or] */
  812. formatDefaultLength = 20 /* length of the |TEX_format_default| string */
  813. formatAreaLength = 11 /* length of its area part */
  814. formatExtLength = 4 /* length of its `\.[.fmt]' part */
  815. formatExtension = /* ".fmt" */ 786 /* the extension, as a \.[WEB] constant */
  816. noTag = 0 /* vanilla character */
  817. ligTag = 1 /* character has a ligature/kerning program */
  818. listTag = 2 /* character has a successor in a charlist */
  819. extTag = 3 /* character is extensible */
  820. slantCode = 1
  821. spaceCode = 2
  822. spaceStretchCode = 3
  823. spaceShrinkCode = 4
  824. xHeightCode = 5
  825. quadCode = 6
  826. extraSpaceCode = 7
  827. nonAddress = 0 /* a spurious |bchar_label| */
  828. badTfm = 11 /* label for |read_font_info| */
  829. setChar0 = 0 /* typeset character 0 and move right */
  830. set1 = 128 /* typeset a character and move right */
  831. setRule = 132 /* typeset a rule and move right */
  832. putRule = 137 /* typeset a rule */
  833. nop = 138 /* no operation */
  834. bop = 139 /* beginning of page */
  835. eop = 140 /* ending of page */
  836. push = 141 /* save the current positions */
  837. pop = 142 /* restore previous positions */
  838. right1 = 143 /* move right */
  839. w0 = 147 /* move right by |w| */
  840. w1 = 148 /* move right and set |w| */
  841. x0 = 152 /* move right by |x| */
  842. x1 = 153 /* move right and set |x| */
  843. down1 = 157 /* move down */
  844. y0 = 161 /* move down by |y| */
  845. y1 = 162 /* move down and set |y| */
  846. z0 = 166 /* move down by |z| */
  847. z1 = 167 /* move down and set |z| */
  848. fntNum0 = 171 /* set current font to 0 */
  849. fnt1 = 235 /* set current font */
  850. xxx1 = 239 /* extension to \.[DVI] primitives */
  851. xxx4 = 242 /* potentially long extension to \.[DVI] primitives */
  852. fntDef1 = 243 /* define the meaning of a font number */
  853. pre = 247 /* preamble */
  854. post = 248 /* postamble beginning */
  855. postPost = 249 /* postamble ending */
  856. idByte = 2 /* identifies the kind of \.[DVI] files described here */
  857. movementNodeSize = 3 /* number of words per entry in the down and right stacks */
  858. yHere = 1 /* |info| when the movement entry points to a |y| command */
  859. zHere = 2 /* |info| when the movement entry points to a |z| command */
  860. yzOk = 3 /* |info| corresponding to an unconstrained \\[down] command */
  861. yOk = 4 /* |info| corresponding to a \\[down] that can't become a |z| */
  862. zOk = 5 /* |info| corresponding to a \\[down] that can't become a |y| */
  863. dFixed = 6 /* |info| corresponding to a \\[down] that can't change */
  864. noneSeen = 0 /* no |y_here| or |z_here| nodes have been encountered yet */
  865. ySeen = 6 /* we have seen |y_here| but not |z_here| */
  866. zSeen = 12 /* we have seen |z_here| but not |y_here| */
  867. movePast = 13 /* go to this label when advancing past glue or a rule */
  868. finRule = 14 /* go to this label to finish processing a rule */
  869. nextP = 15 /* go to this label when finished with node |p| */
  870. exactly = 0 /* a box dimension is pre-specified */
  871. additional = 1 /* a box dimension is increased from the natural one */
  872. noadSize = 4 /* number of words in a normal noad */
  873. mathChar = 1 /* |math_type| when the attribute is simple */
  874. subBox = 2 /* |math_type| when the attribute is a box */
  875. subMlist = 3 /* |math_type| when the attribute is a formula */
  876. mathTextChar = 4 /* |math_type| when italic correction is dubious */
  877. ordNoad = unsetNode + 3 /* |type| of a noad classified Ord */
  878. opNoad = ordNoad + 1 /* |type| of a noad classified Op */
  879. binNoad = ordNoad + 2 /* |type| of a noad classified Bin */
  880. relNoad = ordNoad + 3 /* |type| of a noad classified Rel */
  881. openNoad = ordNoad + 4 /* |type| of a noad classified Open */
  882. closeNoad = ordNoad + 5 /* |type| of a noad classified Close */
  883. punctNoad = ordNoad + 6 /* |type| of a noad classified Punct */
  884. innerNoad = ordNoad + 7 /* |type| of a noad classified Inner */
  885. limits = 1 /* |subtype| of |op_noad| whose scripts are to be above, below */
  886. noLimits = 2 /* |subtype| of |op_noad| whose scripts are to be normal */
  887. radicalNoad = innerNoad + 1 /* |type| of a noad for square roots */
  888. radicalNoadSize = 5 /* number of |mem| words in a radical noad */
  889. fractionNoad = radicalNoad + 1 /* |type| of a noad for generalized fractions */
  890. fractionNoadSize = 6 /* number of |mem| words in a fraction noad */
  891. underNoad = fractionNoad + 1 /* |type| of a noad for underlining */
  892. overNoad = underNoad + 1 /* |type| of a noad for overlining */
  893. accentNoad = overNoad + 1 /* |type| of a noad for accented subformulas */
  894. accentNoadSize = 5 /* number of |mem| words in an accent noad */
  895. vcenterNoad = accentNoad + 1 /* |type| of a noad for \.[\\vcenter] */
  896. leftNoad = vcenterNoad + 1 /* |type| of a noad for \.[\\left] */
  897. rightNoad = leftNoad + 1 /* |type| of a noad for \.[\\right] */
  898. styleNode = unsetNode + 1 /* |type| of a style node */
  899. styleNodeSize = 3 /* number of words in a style node */
  900. displayStyle = 0 /* |subtype| for \.[\\displaystyle] */
  901. textStyle = 2 /* |subtype| for \.[\\textstyle] */
  902. scriptStyle = 4 /* |subtype| for \.[\\scriptstyle] */
  903. scriptScriptStyle = 6 /* |subtype| for \.[\\scriptscriptstyle] */
  904. cramped = 1 /* add this to an uncramped style if you want to cramp it */
  905. choiceNode = unsetNode + 2 /* |type| of a choice node */
  906. textSize = 0 /* size code for the largest size in a family */
  907. scriptSize = 16 /* size code for the medium size in a family */
  908. scriptScriptSize = 32 /* size code for the smallest size in a family */
  909. totalMathsyParams = 22
  910. totalMathexParams = 13
  911. doneWithNoad = 80 /* go here when a noad has been fully translated */
  912. doneWithNode = 81 /* go here when a node has been fully converted */
  913. checkDimensions = 82 /* go here to update |max_h| and |max_d| */
  914. deleteQ = 83 /* go here to delete |q| and move to the next node */
  915. mathSpacing =
  916. // \hskip-35pt
  917. /* "0234000122*4000133**3**344*0400400*000000234000111*1111112341011" */ 892
  918. /* $ \hskip-35pt$ */
  919. alignStackNodeSize = 5 /* number of |mem| words to save alignment states */
  920. spanCode = 256 /* distinct from any character */
  921. crCode = 257 /* distinct from |span_code| and from any character */
  922. crCrCode = crCode + 1 /* this distinguishes \.[\\crcr] from \.[\\cr] */
  923. spanNodeSize = 2 /* number of |mem| words for a span node */
  924. tightFit = 3 // fitness classification for lines shrinking 0.5 to 1.0 of their
  925. // shrinkability
  926. looseFit = 1 // fitness classification for lines stretching 0.5 to 1.0 of their
  927. // stretchability
  928. veryLooseFit = 0 // fitness classification for lines stretching more than
  929. // their stretchability
  930. decentFit = 2 /* fitness classification for all other lines */
  931. activeNodeSize = 3 /* number of words in active nodes */
  932. unhyphenated = 0 /* the |type| of a normal active break node */
  933. hyphenated = 1 /* the |type| of an active node that breaks at a |disc_node| */
  934. passiveNodeSize = 2 /* number of words in passive nodes */
  935. deltaNodeSize = 7 /* number of words in a delta node */
  936. deltaNode = 2 /* |type| field in a delta node */
  937. deactivate = 60 /* go here when node |r| should be deactivated */
  938. updateHeights = 90 /* go here to record glue in the |active_height| table */
  939. insertsOnly = 1
  940. /* |page_contents| when an insert node has been contributed, but no boxes */
  941. boxThere = 2 /* |page_contents| when a box or rule has been contributed */
  942. pageInsNodeSize = 4 /* number of words for a page insertion node */
  943. inserting = 0 /* an insertion class that has not yet overflowed */
  944. splitUp = 1 /* an overflowed insertion class */
  945. contribute = 80 /* go here to link a node into the current page */
  946. bigSwitch = 60 /* go here to branch on the next token of input */
  947. mainLoop = 70 /* go here to typeset a string of consecutive characters */
  948. mainLoopWrapup = 80 /* go here to finish a character or ligature */
  949. mainLoopMove = 90 /* go here to advance the ligature cursor */
  950. mainLoopMoveLig = 95 /* same, when advancing past a generated ligature */
  951. mainLoopLookahead = 100 /* go here to bring in another character, if any */
  952. mainLigLoop = 110 /* go here to check for ligatures or kerning */
  953. appendNormalSpace = 120 /* go here to append a normal space between words */
  954. filCode = 0 /* identifies \.[\\hfil] and \.[\\vfil] */
  955. fillCode = 1 /* identifies \.[\\hfill] and \.[\\vfill] */
  956. ssCode = 2 /* identifies \.[\\hss] and \.[\\vss] */
  957. filNegCode = 3 /* identifies \.[\\hfilneg] and \.[\\vfilneg] */
  958. skipCode = 4 /* identifies \.[\\hskip] and \.[\\vskip] */
  959. mskipCode = 5 /* identifies \.[\\mskip] */
  960. boxCode = 0 /* |chr_code| for `\.[\\box]' */
  961. copyCode = 1 /* |chr_code| for `\.[\\copy]' */
  962. lastBoxCode = 2 /* |chr_code| for `\.[\\lastbox]' */
  963. vsplitCode = 3 /* |chr_code| for `\.[\\vsplit]' */
  964. vtopCode = 4 /* |chr_code| for `\.[\\vtop]' */
  965. aboveCode = 0 /* `\.[\\above]' */
  966. overCode = 1 /* `\.[\\over]' */
  967. atopCode = 2 /* `\.[\\atop]' */
  968. delimitedCode = 3 /* `\.[\\abovewithdelims]', etc. */
  969. charDefCode = 0 /* |shorthand_def| for \.[\\chardef] */
  970. mathCharDefCode = 1 /* |shorthand_def| for \.[\\mathchardef] */
  971. countDefCode = 2 /* |shorthand_def| for \.[\\countdef] */
  972. dimenDefCode = 3 /* |shorthand_def| for \.[\\dimendef] */
  973. skipDefCode = 4 /* |shorthand_def| for \.[\\skipdef] */
  974. muSkipDefCode = 5 /* |shorthand_def| for \.[\\muskipdef] */
  975. toksDefCode = 6 /* |shorthand_def| for \.[\\toksdef] */
  976. showCode = 0 /* \.[\\show] */
  977. showBoxCode = 1 /* \.[\\showbox] */
  978. showTheCode = 2 /* \.[\\showthe] */
  979. showListsCode = 3 /* \.[\\showlists] */
  980. badFmt = 6666 /* go here if the format file is unacceptable */
  981. breakpoint = 888 /* place where a breakpoint is desirable */
  982. writeNodeSize = 2 /* number of words in a write/whatsit node */
  983. openNodeSize = 3 /* number of words in an open/whatsit node */
  984. openNode = 0 /* |subtype| in whatsits that represent files to \.[\\openout] */
  985. writeNode = 1 /* |subtype| in whatsits that represent things to \.[\\write] */
  986. closeNode = 2 /* |subtype| in whatsits that represent streams to \.[\\closeout] */
  987. specialNode = 3 /* |subtype| in whatsits that represent \.[\\special] things */
  988. languageNode = 4 /* |subtype| in whatsits that change the current language */
  989. immediateCode = 4 /* command modifier for \.[\\immediate] */
  990. setLanguageCode = 5 /* command modifier for \.[\\setlanguage] */
  991. // Constants in the outer block
  992. memMax = 30000 // greatest index in \TeX's internal |mem| array;
  993. // must be strictly less than |max_halfword|;
  994. // must be equal to |mem_top| in \.[INITEX], otherwise |>=mem_top|
  995. memMin = 0 // smallest index in \TeX's internal |mem| array;
  996. // must be |min_halfword| or more;
  997. // must be equal to |mem_bot| in \.[INITEX], otherwise |<=mem_bot|
  998. bufSize = 500 // maximum number of characters simultaneously present in
  999. // current lines of open files and in control sequences between
  1000. // \.[\\csname] and \.[\\endcsname]; must not exceed |max_halfword|
  1001. errorLine = 72 // width of context lines on terminal error messages
  1002. halfErrorLine = 42 // width of first lines of contexts in terminal
  1003. // error messages; should be between 30 and |error_line-15|
  1004. maxPrintLine = 79 // width of longest text lines output; should be at least 60
  1005. stackSize = 200 // maximum number of simultaneous input sources
  1006. maxInOpen = 6 // maximum number of input files and error insertions that
  1007. // can be going on simultaneously
  1008. fontMax = 75 // maximum internal font number; must not exceed |max_quarterword|
  1009. // and must be at most |font_base+256|
  1010. fontMemSize = 20000 // number of words of |font_info| for all fonts
  1011. paramSize = 60 // maximum number of simultaneous macro parameters
  1012. nestSize = 40 // maximum number of semantic levels simultaneously active
  1013. maxStrings = 3000 // maximum number of strings; must not exceed |max_halfword|
  1014. stringVacancies = 8000 // the minimum number of characters that should be
  1015. // available for the user's control sequences and font names,
  1016. // after \TeX's own error messages are stored
  1017. poolSize = 32000 // maximum number of characters in strings, including all
  1018. // error messages and help texts, and the names of all fonts and
  1019. // control sequences; must exceed |string_vacancies| by the total
  1020. // length of \TeX's own strings, which is currently about 23000
  1021. saveSize = 600 // space for saving values outside of current group; must be
  1022. // at most |max_halfword|
  1023. trieSize = 8000 // space for hyphenation patterns; should be larger for
  1024. // \.[INITEX] than it is in production versions of \TeX
  1025. trieOpSize = 500 // space for ``opcodes'' in the hyphenation patterns
  1026. dviBufSize = 800 // size of the output buffer; must be a multiple of 8
  1027. fileNameSize = 40 // file names shouldn't be longer than this
  1028. poolName = "TeXformats:TEX.POOL "
  1029. // string of length |file_name_size|; tells where the string pool appears
  1030. // \xref[TeXformats]
  1031. )
  1032. type (
  1033. // Types in the outer block
  1034. asciiCode = /* 0..255 */ byte // eight-bit numbers
  1035. eightBits = /* 0..255 */ byte // unsigned one-byte quantity
  1036. alphaFile = knuth.File // files that contain textual data
  1037. byteFile = knuth.File // files that contain binary data
  1038. poolPointer = /* 0..poolSize */ uint16 // for variables that point into |str_pool|
  1039. strNumber = /* 0..maxStrings */ uint16 // for variables that point into |str_start|
  1040. packedAsciiCode = /* 0..255 */ byte // elements of |str_pool| array
  1041. scaled = int32 // this type is used for scaled integers
  1042. nonnegativeInteger = /* 0..017777777777 */ uint32 // $0\L x<2^[31]$
  1043. smallNumber = /* 0..63 */ byte // this type is self-explanatory
  1044. glueRatio = float64 // one-word representation of a glue expansion factor
  1045. quarterword = /* minQuarterword..maxQuarterword */ byte // 1/4 of a word
  1046. halfword = /* 0..65535 */ uint16 // 1/2 of a word
  1047. twoChoices = /* 1..2 */ byte // used when there are two variants in a record
  1048. fourChoices = /* 1..4 */ byte // used when there are four variants in a record
  1049. twoHalves struct{ data uint32 }
  1050. fourQuarters = struct {
  1051. b0 quarterword
  1052. b1 quarterword
  1053. b2 quarterword
  1054. b3 quarterword
  1055. }
  1056. memoryWord struct{ data uint32 }
  1057. wordFile = knuth.File
  1058. glueOrd = /* normal..filll */ byte // infinity to the 0, 1, 2, or 3 power
  1059. listStateRecord = struct {
  1060. modeField int16
  1061. headField, tailField halfword
  1062. pgField, mlField int32
  1063. auxField memoryWord
  1064. }
  1065. groupCode = /* 0..maxGroupCode */ byte // |save_level| for a level boundary
  1066. inStateRecord = struct {
  1067. stateField, indexField quarterword
  1068. startField, locField, limitField, nameField halfword
  1069. }
  1070. internalFontNumber = /* fontBase..fontMax */ byte // |font| in a |char_node|
  1071. fontIndex = /* 0..fontMemSize */ uint16 // index into |font_info|
  1072. dviIndex = /* 0..dviBufSize */ uint16 // an index into the output buffer
  1073. triePointer = /* 0..trieSize */ uint16 // an index into |trie|
  1074. hyphPointer = /* 0..hyphSize */ uint16 // an index into the ordered hash table
  1075. )
  1076. func (r *memoryWord) gr() *float32 {
  1077. return (*float32)(unsafe.Add(unsafe.Pointer(&r.data), 0))
  1078. }
  1079. func (r *memoryWord) hh() *twoHalves {
  1080. return (*twoHalves)(unsafe.Add(unsafe.Pointer(&r.data), 0))
  1081. }
  1082. func (r *memoryWord) int() *int32 {
  1083. return (*int32)(unsafe.Add(unsafe.Pointer(&r.data), 0))
  1084. }
  1085. func (r *memoryWord) qqqq() *fourQuarters {
  1086. return (*fourQuarters)(unsafe.Add(unsafe.Pointer(&r.data), 0))
  1087. }
  1088. func (r *twoHalves) b0() *quarterword {
  1089. return (*quarterword)(unsafe.Add(unsafe.Pointer(&r.data), 2))
  1090. }
  1091. func (r *twoHalves) b1() *quarterword {
  1092. return (*quarterword)(unsafe.Add(unsafe.Pointer(&r.data), 3))
  1093. }
  1094. func (r *twoHalves) lh() *halfword {
  1095. return (*halfword)(unsafe.Add(unsafe.Pointer(&r.data), 2))
  1096. }
  1097. func (r *twoHalves) rh() *halfword {
  1098. return (*halfword)(unsafe.Add(unsafe.Pointer(&r.data), 0))
  1099. }
  1100. type prg struct {
  1101. stdin, stdout, stderr knuth.File
  1102. // Global variables
  1103. bad int32 // is some ``constant'' wrong?
  1104. xord [256]asciiCode
  1105. // specifies conversion of input characters
  1106. xchr [256]char
  1107. // specifies conversion of output characters
  1108. nameOfFile [40]char
  1109. // on some systems this may be a \&[record] variable
  1110. nameLength/* 0..fileNameSize */ byte
  1111. // this many characters are actually
  1112. // relevant in |name_of_file| (the rest are blank)
  1113. buffer [501]asciiCode // lines of characters being read
  1114. first/* 0..bufSize */ uint16 // the first unused position in |buffer|
  1115. last/* 0..bufSize */ uint16 // end of the line just input to |buffer|
  1116. maxBufStack/* 0..bufSize */ uint16 // largest index used in |buffer|
  1117. termIn alphaFile // the terminal as an input file
  1118. termOut alphaFile // the terminal as an output file
  1119. strPool [32001]packedAsciiCode // the characters
  1120. strStart [3001]poolPointer // the starting pointers
  1121. poolPtr poolPointer // first unused position in |str_pool|
  1122. strPtr strNumber // number of the current string being created
  1123. initPoolPtr poolPointer // the starting value of |pool_ptr|
  1124. initStrPtr strNumber // the starting value of |str_ptr|
  1125. poolFile alphaFile // the string-pool file output by \.[TANGLE]
  1126. logFile alphaFile // transcript of \TeX\ session
  1127. selector/* 0..maxSelector */ byte // where to print a message
  1128. dig [23] /* 0..15 */ byte // digits in a number being output
  1129. tally int32 // the number of characters recently printed
  1130. termOffset/* 0..maxPrintLine */ byte
  1131. // the number of characters on the current terminal line
  1132. fileOffset/* 0..maxPrintLine */ byte
  1133. // the number of characters on the current file line
  1134. trickBuf [73]asciiCode // circular buffer for
  1135. // pseudoprinting
  1136. trickCount int32 // threshold for pseudoprinting, explained later
  1137. firstCount int32 // another variable for pseudoprinting
  1138. interaction/* batchMode..errorStopMode */ byte // current level of interaction
  1139. deletionsAllowed bool // is it safe for |error| to call |get_token|?
  1140. setBoxAllowed bool // is it safe to do a \.[\\setbox] assignment?
  1141. history/* spotless..fatalErrorStop */ byte // has the source input been clean so far?
  1142. errorCount/* -1..100 */ int8 // the number of scrolled errors since the
  1143. // last paragraph ended
  1144. helpLine [6]strNumber // helps for the next |error|
  1145. helpPtr/* 0..6 */ byte // the number of help lines present
  1146. useErrHelp bool // should the |err_help| list be shown?
  1147. interrupt int32 // should \TeX\ pause for instructions?
  1148. okToInterrupt bool // should interrupts be observed?
  1149. arithError bool // has arithmetic overflow occurred recently?
  1150. remainder scaled // amount subtracted to get an exact division
  1151. tempPtr halfword // a pointer variable for occasional emergency use
  1152. mem [30001]memoryWord // the big dynamic storage area
  1153. loMemMax halfword // the largest location of variable-size memory in use
  1154. hiMemMin halfword // the smallest location of one-word memory in use
  1155. varUsed, dynUsed int32 // how much memory is in use
  1156. avail halfword // head of the list of available one-word nodes
  1157. memEnd halfword // the last one-word node used in |mem|
  1158. rover halfword // points to some node in the list of empties
  1159. // free: packed array [mem_min..mem_max] of boolean; [free cells]
  1160. // [ \hskip10pt ] was_free: packed array [mem_min..mem_max] of boolean;
  1161. // [previously free cells]
  1162. // [ \hskip10pt ] was_mem_end, was_lo_max, was_hi_min: halfword ;
  1163. // [previous |mem_end|, |lo_mem_max|, and |hi_mem_min|]
  1164. // [ \hskip10pt ] panicking:boolean; [do we want to check memory constantly?]
  1165. // [ ]
  1166. fontInShortDisplay int32 // an internal font number
  1167. depthThreshold int32 // maximum nesting depth in box displays
  1168. breadthMax int32 // maximum number of items shown at the same list level
  1169. nest [41]listStateRecord
  1170. nestPtr/* 0..nestSize */ byte // first unused location of |nest|
  1171. maxNestStack/* 0..nestSize */ byte // maximum of |nest_ptr| when pushing
  1172. curList listStateRecord // the ``top'' semantic state
  1173. shownMode/* -mmode..mmode */ int16 // most recent mode shown by \.[\\tracingcommands]
  1174. oldSetting/* 0..maxSelector */ byte
  1175. sysTime, sysDay, sysMonth, sysYear int32
  1176. // date and time supplied by external system
  1177. eqtb [6106]memoryWord
  1178. xeqLevel [844]quarterword
  1179. hash [2367]twoHalves
  1180. // the hash table
  1181. hashUsed halfword // allocation pointer for |hash|
  1182. noNewControlSequence bool // are new identifiers legal?
  1183. csCount int32 // total number of known identifiers
  1184. saveStack [601]memoryWord
  1185. savePtr/* 0..saveSize */ uint16 // first unused entry on |save_stack|
  1186. maxSaveStack/* 0..saveSize */ uint16 // maximum usage of save stack
  1187. curLevel quarterword // current nesting level for groups
  1188. curGroup groupCode // current group type
  1189. curBoundary/* 0..saveSize */ uint16 // where the current level begins
  1190. magSet int32 // if nonzero, this magnification should be used henceforth
  1191. curCmd eightBits // current command set by |get_next|
  1192. curChr halfword // operand of current command
  1193. curCs halfword // control sequence found here, zero if none found
  1194. curTok halfword // packed representative of |cur_cmd| and |cur_chr|
  1195. inputStack [201]inStateRecord
  1196. inputPtr/* 0..stackSize */ byte // first unused location of |input_stack|
  1197. maxInStack/* 0..stackSize */ byte // largest value of |input_ptr| when pushing
  1198. curInput inStateRecord
  1199. // the ``top'' input state, according to convention (1)
  1200. inOpen/* 0..maxInOpen */ byte // the number of lines in the buffer, less one
  1201. openParens/* 0..maxInOpen */ byte // the number of open text files
  1202. inputFile [6]alphaFile
  1203. line int32 // current line number in the current source file
  1204. lineStack [6]int32
  1205. scannerStatus/* normal..absorbing */ byte // can a subfile end now?
  1206. warningIndex halfword // identifier relevant to non-|normal| scanner status
  1207. defRef halfword // reference count of token list being defined
  1208. paramStack [61]halfword
  1209. // token list pointers for parameters
  1210. paramPtr/* 0..paramSize */ byte // first unused entry in |param_stack|
  1211. maxParamStack int32
  1212. // largest value of |param_ptr|, will be |<=param_size+9|
  1213. alignState int32 // group level with respect to current alignment
  1214. basePtr/* 0..stackSize */ byte // shallowest level shown by |show_context|
  1215. parLoc halfword // location of `\.[\\par]' in |eqtb|
  1216. parToken halfword // token representing `\.[\\par]'
  1217. forceEof bool // should the next \.[\\input] be aborted early?
  1218. curMark [5]halfword
  1219. // token lists for marks
  1220. longState/* call..longOuterCall */ byte // governs the acceptance of \.[\\par]
  1221. pstack [9]halfword // arguments supplied to a macro
  1222. curVal int32 // value returned by numeric scanners
  1223. curValLevel/* intVal..tokVal */ byte // the ``level'' of this value
  1224. radix smallNumber // |scan_int| sets this to 8, 10, 16, or zero
  1225. curOrder glueOrd // order of infinity found by |scan_dimen|
  1226. readFile [16]alphaFile // used for \.[\\read]
  1227. readOpen [17] /* normal..closed */ byte // state of |read_file[n]|
  1228. condPtr halfword // top of the condition stack
  1229. ifLimit/* normal..orCode */ byte // upper bound on |fi_or_else| codes
  1230. curIf smallNumber // type of conditional being worked on
  1231. ifLine int32 // line where that conditional began
  1232. skipLine int32 // skipping began here
  1233. curName strNumber // name of file just scanned
  1234. curArea strNumber // file area just scanned, or \.[""]
  1235. curExt strNumber // file extension just scanned, or \.[""]
  1236. areaDelimiter poolPointer // the most recent `\.>' or `\.:', if any
  1237. extDelimiter poolPointer // the relevant `\..', if any
  1238. texFormatDefault [20]char
  1239. nameInProgress bool // is a file name being scanned?
  1240. jobName strNumber // principal file name
  1241. logOpened bool // has the transcript file been opened?
  1242. dviFile byteFile // the device-independent output goes here
  1243. outputFileName strNumber // full name of the output file
  1244. logName strNumber // full name of the log file
  1245. tfmFile byteFile
  1246. buf eightBits
  1247. fontInfo [20001]memoryWord
  1248. // the big collection of font data
  1249. fmemPtr fontIndex // first unused word of |font_info|
  1250. fontPtr internalFontNumber // largest internal font number in use
  1251. fontCheck [76]fourQuarters // check sum
  1252. fontSize [76]scaled // ``at'' size
  1253. fontDsize [76]scaled // ``design'' size
  1254. fontParams [76]fontIndex // how many font
  1255. // parameters are present
  1256. fontName [76]strNumber // name of the font
  1257. fontArea [76]strNumber // area of the font
  1258. fontBc [76]eightBits
  1259. // beginning (smallest) character code
  1260. fontEc [76]eightBits
  1261. // ending (largest) character code
  1262. fontGlue [76]halfword
  1263. // glue specification for interword space, |null| if not allocated
  1264. fontUsed [76]bool
  1265. // has a character from this font actually appeared in the output?
  1266. hyphenChar [76]int32
  1267. // current \.[\\hyphenchar] values
  1268. skewChar [76]int32
  1269. // current \.[\\skewchar] values
  1270. bcharLabel [76]fontIndex
  1271. // start of |lig_kern| program for left boundary character,
  1272. // |non_address| if there is none
  1273. fontBchar [76] /* minQuarterword..256+minQuarterword */ uint16
  1274. // boundary character, |non_char| if there is none
  1275. fontFalseBchar [76] /* minQuarterword..256+minQuarterword */ uint16
  1276. // |font_bchar| if it doesn't exist in the font, otherwise |non_char|
  1277. charBase [76]int32
  1278. // base addresses for |char_info|
  1279. widthBase [76]int32
  1280. // base addresses for widths
  1281. heightBase [76]int32
  1282. // base addresses for heights
  1283. depthBase [76]int32
  1284. // base addresses for depths
  1285. italicBase [76]int32
  1286. // base addresses for italic corrections
  1287. ligKernBase [76]int32
  1288. // base addresses for ligature/kerning programs
  1289. kernBase [76]int32
  1290. // base addresses for kerns
  1291. extenBase [76]int32
  1292. // base addresses for extensible recipes
  1293. paramBase [76]int32
  1294. // base addresses for font parameters
  1295. nullCharacter fourQuarters // nonexistent character information
  1296. totalPages int32 // the number of pages that have been shipped out
  1297. maxV scaled // maximum height-plus-depth of pages shipped so far
  1298. maxH scaled // maximum width of pages shipped so far
  1299. maxPush int32 // deepest nesting of |push| commands encountered so far
  1300. lastBop int32 // location of previous |bop| in the \.[DVI] output
  1301. deadCycles int32 // recent outputs that didn't ship anything out
  1302. doingLeaders bool // are we inside a leader box?
  1303. c, f quarterword // character and font in current |char_node|
  1304. ruleHt, ruleDp, ruleWd scaled // size of current rule being output
  1305. g halfword // current glue specification
  1306. lq, lr int32 // quantities used in calculations for leaders
  1307. dviBuf [801]eightBits // buffer for \.[DVI] output
  1308. halfBuf dviIndex // half of |dvi_buf_size|
  1309. dviLimit dviIndex // end of the current half buffer
  1310. dviPtr dviIndex // the next available buffer address
  1311. dviOffset int32 // |dvi_buf_size| times the number of times the
  1312. // output buffer has been fully emptied
  1313. dviGone int32 // the number of bytes already output to |dvi_file|
  1314. downPtr, rightPtr halfword // heads of the down and right stacks
  1315. dviH, dviV scaled // a \.[DVI] reader program thinks we are here
  1316. curH, curV scaled // \TeX\ thinks we are here
  1317. dviF internalFontNumber // the current font
  1318. curS int32 // current depth of output box nesting, initially $-1$
  1319. totalStretch, totalShrink [4]scaled
  1320. // glue found by |hpack| or |vpack|
  1321. lastBadness int32 // badness of the most recently packaged box
  1322. adjustTail halfword // tail of adjustment list
  1323. packBeginLine int32 // source file line where the current paragraph
  1324. // or alignment began; a negative value denotes alignment
  1325. emptyField twoHalves
  1326. nullDelimiter fourQuarters
  1327. curMlist halfword // beginning of mlist to be translated
  1328. curStyle smallNumber // style code at current place in the list
  1329. curSize smallNumber // size code corresponding to |cur_style|
  1330. curMu scaled // the math unit width corresponding to |cur_size|
  1331. mlistPenalties bool // should |mlist_to_hlist| insert penalties?
  1332. curF internalFontNumber // the |font| field of a |math_char|
  1333. curC quarterword // the |character| field of a |math_char|
  1334. curI fourQuarters // the |char_info| of a |math_char|,
  1335. // or a lig/kern instruction
  1336. magicOffset int32 // used to find inter-element spacing
  1337. curAlign halfword // current position in preamble list
  1338. curSpan halfword // start of currently spanned columns in preamble list
  1339. curLoop halfword // place to copy when extending a periodic preamble
  1340. alignPtr halfword // most recently pushed-down alignment stack node
  1341. curHead, curTail halfword // adjustment list pointers
  1342. justBox halfword // the |hlist_node| for the last line of the new paragraph
  1343. passive halfword // most recent node on passive list
  1344. printedNode halfword // most recent node that has been printed
  1345. passNumber halfword // the number of passive nodes allocated on this pass
  1346. activeWidth [6]scaled
  1347. // distance from first active node to~|cur_p|
  1348. curActiveWidth [6]scaled // distance from current active node
  1349. background [6]scaled // length of an ``empty'' line
  1350. breakWidth [6]scaled // length being computed after current break
  1351. noShrinkErrorYet bool // have we complained about infinite shrinkage?
  1352. curP halfword // the current breakpoint under consideration
  1353. secondPass bool // is this our second attempt to break this paragraph?
  1354. finalPass bool // is this our final attempt to break this paragraph?
  1355. threshold int32 // maximum badness on feasible lines
  1356. minimalDemerits [4]int32 // best total
  1357. // demerits known for current line class and position, given the fitness
  1358. minimumDemerits int32 // best total demerits known for current line class
  1359. // and position
  1360. bestPlace [4]halfword // how to achieve
  1361. // |minimal_demerits|
  1362. bestPlLine [4]halfword // corresponding
  1363. // line number
  1364. discWidth scaled // the length of discretionary material preceding a break
  1365. easyLine halfword // line numbers |>easy_line| are equivalent in break nodes
  1366. lastSpecialLine halfword // line numbers |>last_special_line| all have
  1367. // the same width
  1368. firstWidth scaled // the width of all lines |<=last_special_line|, if
  1369. // no \.[\\parshape] has been specified
  1370. secondWidth scaled // the width of all lines |>last_special_line|
  1371. firstIndent scaled // left margin to go with |first_width|
  1372. secondIndent scaled // left margin to go with |second_width|
  1373. bestBet halfword // use this passive node and its predecessors
  1374. fewestDemerits int32 // the demerits associated with |best_bet|
  1375. bestLine halfword // line number following the last line of the new paragraph
  1376. actualLooseness int32 // the difference between |line_number(best_bet)|
  1377. // and the optimum |best_line|
  1378. lineDiff int32 // the difference between the current line number and
  1379. // the optimum |best_line|
  1380. hc [66] /* 0..256 */ uint16 // word to be hyphenated
  1381. hn/* 0..64 */ byte // the number of positions occupied in |hc|;
  1382. // not always a |small_number|
  1383. ha, hb halfword // nodes |ha..hb| should be replaced by the hyphenated result
  1384. hf internalFontNumber // font number of the letters in |hc|
  1385. hu [64] /* 0..256 */ uint16 // like |hc|, before conversion to lowercase
  1386. hyfChar int32 // hyphen character of the relevant font
  1387. curLang, initCurLang asciiCode // current hyphenation table of interest
  1388. lHyf, rHyf, initLHyf, initRHyf int32 // limits on fragment sizes
  1389. hyfBchar halfword // boundary character after $c_n$
  1390. hyf [65] /* 0..9 */ byte // odd values indicate discretionary hyphens
  1391. initList halfword // list of punctuation characters preceding the word
  1392. initLig bool // does |init_list| represent a ligature?
  1393. initLft bool // if so, did the ligature involve a left boundary?
  1394. hyphenPassed smallNumber // first hyphen in a ligature, if any
  1395. curL, curR halfword // characters before and after the cursor
  1396. curQ halfword // where a ligature should be detached
  1397. ligStack halfword // unfinished business to the right of the cursor
  1398. ligaturePresent bool // should a ligature node be made for |cur_l|?
  1399. lftHit, rtHit bool // did we hit a ligature with a boundary character?
  1400. trie [8001]twoHalves // |trie_link|, |trie_char|, |trie_op|
  1401. hyfDistance [500]smallNumber // position |k-j| of $n_j$
  1402. hyfNum [500]smallNumber // value of $n_j$
  1403. hyfNext [500]quarterword // continuation code
  1404. opStart [256] /* 0..trieOpSize */ uint16 // offset for current language
  1405. hyphWord [308]strNumber // exception words
  1406. hyphList [308]halfword // lists of hyphen positions
  1407. hyphCount hyphPointer // the number of words in the exception dictionary
  1408. trieOpHash [1001] /* 0..trieOpSize */ uint16
  1409. // trie op codes for quadruples
  1410. trieUsed [256]quarterword
  1411. // largest opcode used so far for this language
  1412. trieOpLang [500]asciiCode
  1413. // language part of a hashed quadruple
  1414. trieOpVal [500]quarterword
  1415. // opcode corresponding to a hashed quadruple
  1416. trieOpPtr/* 0..trieOpSize */ uint16 // number of stored ops so far
  1417. trieC [8001]packedAsciiCode
  1418. // characters to match
  1419. // \hskip10pt
  1420. trieO [8001]quarterword
  1421. // operations to perform
  1422. // \hskip10pt
  1423. trieL [8001]triePointer
  1424. // left subtrie links
  1425. // \hskip10pt
  1426. trieR [8001]triePointer
  1427. // right subtrie links
  1428. // \hskip10pt
  1429. triePtr triePointer // the number of nodes in the trie
  1430. // \hskip10pt
  1431. trieHash [8001]triePointer
  1432. // used to identify equivalent subtries
  1433. trieTaken [8000]bool
  1434. // does a family start here?
  1435. // \hskip10pt
  1436. trieMin [256]triePointer
  1437. // the first possible slot for each character
  1438. // \hskip10pt
  1439. trieMax triePointer // largest location used in |trie|
  1440. // \hskip10pt
  1441. trieNotReady bool // is the trie still in linked form?
  1442. bestHeightPlusDepth scaled // height of the best box, without stretching or
  1443. // shrinking
  1444. pageTail halfword // the final node on the current page
  1445. pageContents/* empty..boxThere */ byte // what is on the current page so far?
  1446. pageMaxDepth scaled // maximum box depth on page being built
  1447. bestPageBreak halfword // break here to get the best page known so far
  1448. leastPageCost int32 // the score for this currently best page
  1449. bestSize scaled // its |page_goal|
  1450. pageSoFar [8]scaled // height and glue of the current page
  1451. lastGlue halfword // used to implement \.[\\lastskip]
  1452. lastPenalty int32 // used to implement \.[\\lastpenalty]
  1453. lastKern scaled // used to implement \.[\\lastkern]
  1454. insertPenalties int32 // sum of the penalties for insertions
  1455. // that were held over
  1456. outputActive bool // are we in the midst of an output routine?
  1457. mainF internalFontNumber // the current font
  1458. mainI fourQuarters // character information bytes for |cur_l|
  1459. mainJ fourQuarters // ligature/kern command
  1460. mainK fontIndex // index into |font_info|
  1461. mainP halfword // temporary register for list manipulation
  1462. mainS int32 // space factor value
  1463. bchar halfword // boundary character of current font, or |non_char|
  1464. falseBchar halfword // nonexistent character matching |bchar|, or |non_char|
  1465. cancelBoundary bool // should the left boundary be ignored?
  1466. insDisc bool // should we insert a discretionary node?
  1467. curBox halfword // box to be placed into its context
  1468. afterToken halfword // zero, or a saved token
  1469. longHelpSeen bool // has the long \.[\\errmessage] help been used?
  1470. formatIdent strNumber
  1471. fmtFile wordFile // for input or output of format information
  1472. readyAlready int32 // a sacrifice of purity for economy
  1473. writeFile [16]alphaFile
  1474. writeOpen [18]bool
  1475. writeLoc halfword // |eqtb| address of \.[\\write]
  1476. }
  1477. func (prg *prg) initialize() { // this procedure gets things started properly
  1478. var (
  1479. // Local variables for initialization
  1480. i int32
  1481. k int32 // index into |mem|, |eqtb|, etc.
  1482. z hyphPointer // runs through the exception dictionary
  1483. )
  1484. prg.xchr[040] = ' '
  1485. prg.xchr[041] = '!'
  1486. prg.xchr[042] = '"'
  1487. prg.xchr[043] = '#'
  1488. prg.xchr[044] = '$'
  1489. prg.xchr[045] = '%'
  1490. prg.xchr[046] = '&'
  1491. prg.xchr[047] = '\''
  1492. prg.xchr[050] = '('
  1493. prg.xchr[051] = ')'
  1494. prg.xchr[052] = '*'
  1495. prg.xchr[053] = '+'
  1496. prg.xchr[054] = ','
  1497. prg.xchr[055] = '-'
  1498. prg.xchr[056] = '.'
  1499. prg.xchr[057] = '/'
  1500. prg.xchr[060] = '0'
  1501. prg.xchr[061] = '1'
  1502. prg.xchr[062] = '2'
  1503. prg.xchr[063] = '3'
  1504. prg.xchr[064] = '4'
  1505. prg.xchr[065] = '5'
  1506. prg.xchr[066] = '6'
  1507. prg.xchr[067] = '7'
  1508. prg.xchr[070] = '8'
  1509. prg.xchr[071] = '9'
  1510. prg.xchr[072] = ':'
  1511. prg.xchr[073] = ';'
  1512. prg.xchr[074] = '<'
  1513. prg.xchr[075] = '='
  1514. prg.xchr[076] = '>'
  1515. prg.xchr[077] = '?'
  1516. prg.xchr[0100] = '@'
  1517. prg.xchr[0101] = 'A'
  1518. prg.xchr[0102] = 'B'
  1519. prg.xchr[0103] = 'C'
  1520. prg.xchr[0104] = 'D'
  1521. prg.xchr[0105] = 'E'
  1522. prg.xchr[0106] = 'F'
  1523. prg.xchr[0107] = 'G'
  1524. prg.xchr[0110] = 'H'
  1525. prg.xchr[0111] = 'I'
  1526. prg.xchr[0112] = 'J'
  1527. prg.xchr[0113] = 'K'
  1528. prg.xchr[0114] = 'L'
  1529. prg.xchr[0115] = 'M'
  1530. prg.xchr[0116] = 'N'
  1531. prg.xchr[0117] = 'O'
  1532. prg.xchr[0120] = 'P'
  1533. prg.xchr[0121] = 'Q'
  1534. prg.xchr[0122] = 'R'
  1535. prg.xchr[0123] = 'S'
  1536. prg.xchr[0124] = 'T'
  1537. prg.xchr[0125] = 'U'
  1538. prg.xchr[0126] = 'V'
  1539. prg.xchr[0127] = 'W'
  1540. prg.xchr[0130] = 'X'
  1541. prg.xchr[0131] = 'Y'
  1542. prg.xchr[0132] = 'Z'
  1543. prg.xchr[0133] = '['
  1544. prg.xchr[0134] = '\\'
  1545. prg.xchr[0135] = ']'
  1546. prg.xchr[0136] = '^'
  1547. prg.xchr[0137] = '_'
  1548. prg.xchr[0140] = '`'
  1549. prg.xchr[0141] = 'a'
  1550. prg.xchr[0142] = 'b'
  1551. prg.xchr[0143] = 'c'
  1552. prg.xchr[0144] = 'd'
  1553. prg.xchr[0145] = 'e'
  1554. prg.xchr[0146] = 'f'
  1555. prg.xchr[0147] = 'g'
  1556. prg.xchr[0150] = 'h'
  1557. prg.xchr[0151] = 'i'
  1558. prg.xchr[0152] = 'j'
  1559. prg.xchr[0153] = 'k'
  1560. prg.xchr[0154] = 'l'
  1561. prg.xchr[0155] = 'm'
  1562. prg.xchr[0156] = 'n'
  1563. prg.xchr[0157] = 'o'
  1564. prg.xchr[0160] = 'p'
  1565. prg.xchr[0161] = 'q'
  1566. prg.xchr[0162] = 'r'
  1567. prg.xchr[0163] = 's'
  1568. prg.xchr[0164] = 't'
  1569. prg.xchr[0165] = 'u'
  1570. prg.xchr[0166] = 'v'
  1571. prg.xchr[0167] = 'w'
  1572. prg.xchr[0170] = 'x'
  1573. prg.xchr[0171] = 'y'
  1574. prg.xchr[0172] = 'z'
  1575. prg.xchr[0173] = '{'
  1576. prg.xchr[0174] = '|'
  1577. prg.xchr[0175] = '}'
  1578. prg.xchr[0176] = '~'
  1579. for ii := int32(0); ii <= 037; ii++ {
  1580. i = ii
  1581. _ = i
  1582. prg.xchr[i] = ' '
  1583. }
  1584. for ii := int32(0177); ii <= 0377; ii++ {
  1585. i = ii
  1586. _ = i
  1587. prg.xchr[i] = ' '
  1588. }
  1589. for ii := int32(firstTextChar); ii <= lastTextChar; ii++ {
  1590. i = ii
  1591. _ = i
  1592. prg.xord[char(i)] = byte(invalidCode)
  1593. }
  1594. for ii := int32(0200); ii <= 0377; ii++ {
  1595. i = ii
  1596. _ = i
  1597. prg.xord[prg.xchr[i]] = byte(i)
  1598. }
  1599. for ii := int32(0); ii <= 0176; ii++ {
  1600. i = ii
  1601. _ = i
  1602. prg.xord[prg.xchr[i]] = byte(i)
  1603. }
  1604. prg.interaction = byte(errorStopMode)
  1605. prg.deletionsAllowed = true
  1606. prg.setBoxAllowed = true
  1607. prg.errorCount = 0 // |history| is initialized elsewhere
  1608. prg.helpPtr = 0
  1609. prg.useErrHelp = false
  1610. prg.interrupt = 0
  1611. prg.okToInterrupt = true
  1612. // was_mem_end:=mem_min; [indicate that everything was previously free]
  1613. // was_lo_max:=mem_min; was_hi_min:=mem_max;
  1614. // panicking:=false;
  1615. // [ ]
  1616. prg.nestPtr = 0
  1617. prg.maxNestStack = 0
  1618. prg.curList.modeField = int16(vmode)
  1619. prg.curList.headField = uint16(30000 - 1)
  1620. prg.curList.tailField = uint16(30000 - 1)
  1621. *prg.curList.auxField.int() = -65536000
  1622. prg.curList.mlField = 0
  1623. prg.curList.pgField = 0
  1624. prg.shownMode = 0
  1625. // Start a new current page
  1626. prg.pageContents = byte(empty)
  1627. prg.pageTail = uint16(30000 - 2)
  1628. *(*prg.mem[30000-2].hh()).rh() = 0
  1629. prg.lastGlue = 65535
  1630. prg.lastPenalty = 0
  1631. prg.lastKern = 0
  1632. prg.pageSoFar[7] = 0
  1633. prg.pageMaxDepth = 0
  1634. for ii := int32(intBase); ii <= eqtbSize; ii++ {
  1635. k = ii
  1636. _ = k
  1637. prg.xeqLevel[k-5263] = byte(levelOne)
  1638. }
  1639. prg.noNewControlSequence = true // new identifiers are usually forbidden
  1640. *prg.hash[hashBase-514].lh() = 0
  1641. *prg.hash[hashBase-514].rh() = 0
  1642. for ii := int32(hashBase + 1); ii <= undefinedControlSequence-1; ii++ {
  1643. k = ii
  1644. _ = k
  1645. prg.hash[k-514] = prg.hash[hashBase-514]
  1646. }
  1647. prg.savePtr = 0
  1648. prg.curLevel = byte(levelOne)
  1649. prg.curGroup = byte(bottomLevel)
  1650. prg.curBoundary = 0
  1651. prg.maxSaveStack = 0
  1652. prg.magSet = 0
  1653. prg.curMark[topMarkCode] = 0
  1654. prg.curMark[firstMarkCode] = 0
  1655. prg.curMark[botMarkCode] = 0
  1656. prg.curMark[splitFirstMarkCode] = 0
  1657. prg.curMark[splitBotMarkCode] = 0
  1658. prg.curVal = 0
  1659. prg.curValLevel = byte(intVal)
  1660. prg.radix = 0
  1661. prg.curOrder = byte(normal)
  1662. for ii := int32(0); ii <= 16; ii++ {
  1663. k = ii
  1664. _ = k
  1665. prg.readOpen[k] = byte(closed)
  1666. }
  1667. prg.condPtr = 0
  1668. prg.ifLimit = byte(normal)
  1669. prg.curIf = 0
  1670. prg.ifLine = 0
  1671. strcopy(prg.texFormatDefault[:], "TeXformats:plain.fmt")
  1672. // \xref[TeXformats]
  1673. // \xref[plain]
  1674. // \xref[system dependencies]
  1675. for ii := int32(fontBase); ii <= fontMax; ii++ {
  1676. k = ii
  1677. _ = k
  1678. prg.fontUsed[k] = false
  1679. }
  1680. prg.nullCharacter.b0 = byte(minQuarterword)
  1681. prg.nullCharacter.b1 = byte(minQuarterword)
  1682. prg.nullCharacter.b2 = byte(minQuarterword)
  1683. prg.nullCharacter.b3 = byte(minQuarterword)
  1684. prg.totalPages = 0
  1685. prg.maxV = 0
  1686. prg.maxH = 0
  1687. prg.maxPush = 0
  1688. prg.lastBop = -1
  1689. prg.doingLeaders = false
  1690. prg.deadCycles = 0
  1691. prg.curS = -1
  1692. prg.halfBuf = uint16(dviBufSize / 2)
  1693. prg.dviLimit = uint16(dviBufSize)
  1694. prg.dviPtr = 0
  1695. prg.dviOffset = 0
  1696. prg.dviGone = 0
  1697. prg.downPtr = 0
  1698. prg.rightPtr = 0
  1699. prg.adjustTail = 0
  1700. prg.lastBadness = 0
  1701. prg.packBeginLine = 0
  1702. *prg.emptyField.rh() = uint16(empty)
  1703. *prg.emptyField.lh() = 0
  1704. prg.nullDelimiter.b0 = 0
  1705. prg.nullDelimiter.b1 = byte(minQuarterword)
  1706. prg.nullDelimiter.b2 = 0
  1707. prg.nullDelimiter.b3 = byte(minQuarterword)
  1708. prg.alignPtr = 0
  1709. prg.curAlign = 0
  1710. prg.curSpan = 0
  1711. prg.curLoop = 0
  1712. prg.curHead = 0
  1713. prg.curTail = 0
  1714. for ii := int32(0); ii <= hyphSize; ii++ {
  1715. z = hyphPointer(ii)
  1716. _ = z
  1717. prg.hyphWord[z] = 0
  1718. prg.hyphList[z] = 0
  1719. }
  1720. prg.hyphCount = 0
  1721. prg.outputActive = false
  1722. prg.insertPenalties = 0
  1723. prg.ligaturePresent = false
  1724. prg.cancelBoundary = false
  1725. prg.lftHit = false
  1726. prg.rtHit = false
  1727. prg.insDisc = false
  1728. prg.afterToken = 0
  1729. prg.longHelpSeen = false
  1730. prg.formatIdent = 0
  1731. for ii := int32(0); ii <= 17; ii++ {
  1732. k = ii
  1733. _ = k
  1734. prg.writeOpen[k] = false
  1735. }
  1736. // Initialize table entries (done by \.[INITEX] only)
  1737. for ii := int32(memBot + 1); ii <= memBot+glueSpecSize+glueSpecSize+glueSpecSize+glueSpecSize+glueSpecSize-1; ii++ {
  1738. k = ii
  1739. _ = k
  1740. *prg.mem[k].int() = 0
  1741. }
  1742. // all glue dimensions are zeroed
  1743. // \xref[data structure assumptions]
  1744. k = memBot
  1745. for k <= memBot+glueSpecSize+glueSpecSize+glueSpecSize+glueSpecSize+glueSpecSize-1 {
  1746. // set first words of glue specifications
  1747. *(*prg.mem[k].hh()).rh() = uint16(0 + 1)
  1748. *(*prg.mem[k].hh()).b0() = byte(normal)
  1749. *(*prg.mem[k].hh()).b1() = byte(normal)
  1750. k = k + glueSpecSize
  1751. }
  1752. *prg.mem[memBot+glueSpecSize+2].int() = 0200000
  1753. *(*prg.mem[memBot+glueSpecSize].hh()).b0() = byte(fil)
  1754. *prg.mem[memBot+glueSpecSize+glueSpecSize+2].int() = 0200000
  1755. *(*prg.mem[memBot+glueSpecSize+glueSpecSize].hh()).b0() = byte(fill)
  1756. *prg.mem[memBot+glueSpecSize+glueSpecSize+glueSpecSize+2].int() = 0200000
  1757. *(*prg.mem[memBot+glueSpecSize+glueSpecSize+glueSpecSize].hh()).b0() = byte(fil)
  1758. *prg.mem[memBot+glueSpecSize+glueSpecSize+glueSpecSize+3].int() = 0200000
  1759. *(*prg.mem[memBot+glueSpecSize+glueSpecSize+glueSpecSize].hh()).b1() = byte(fil)
  1760. *prg.mem[memBot+glueSpecSize+glueSpecSize+glueSpecSize+glueSpecSize+2].int() = -0200000
  1761. *(*prg.mem[memBot+glueSpecSize+glueSpecSize+glueSpecSize+glueSpecSize].hh()).b0() = byte(fil)
  1762. prg.rover = uint16(memBot + glueSpecSize + glueSpecSize + glueSpecSize + glueSpecSize + glueSpecSize - 1 + 1)
  1763. *(*prg.mem[prg.rover].hh()).rh() = 65535 // now initialize the dynamic memory
  1764. *(*prg.mem[prg.rover].hh()).lh() = 1000 // which is a 1000-word available node
  1765. *(*prg.mem[int32(prg.rover)+1].hh()).lh() = prg.rover
  1766. *(*prg.mem[int32(prg.rover)+1].hh()).rh() = prg.rover
  1767. prg.loMemMax = uint16(int32(prg.rover) + 1000)
  1768. *(*prg.mem[prg.loMemMax].hh()).rh() = 0
  1769. *(*prg.mem[prg.loMemMax].hh()).lh() = 0
  1770. for ii := int32(30000 - 13); ii <= 30000; ii++ {
  1771. k = ii
  1772. _ = k
  1773. prg.mem[k] = prg.mem[prg.loMemMax]
  1774. } // clear list heads
  1775. // Initialize the special list heads and constant nodes
  1776. *(*prg.mem[30000-10].hh()).lh() = uint16(07777 + frozenEndTemplate) // |link(omit_template)=null|
  1777. *(*prg.mem[30000-9].hh()).rh() = uint16(maxQuarterword + 1)
  1778. *(*prg.mem[30000-9].hh()).lh() = 0
  1779. *(*prg.mem[30000-7].hh()).b0() = byte(hyphenated)
  1780. *(*prg.mem[30000-7+1].hh()).lh() = 65535
  1781. *(*prg.mem[30000-7].hh()).b1() = 0 // the |subtype| is never examined by the algorithm
  1782. *(*prg.mem[30000].hh()).b1() = byte(255 + minQuarterword)
  1783. *(*prg.mem[30000].hh()).b0() = byte(splitUp)
  1784. *(*prg.mem[30000].hh()).rh() = 30000
  1785. *(*prg.mem[30000-2].hh()).b0() = byte(glueNode)
  1786. *(*prg.mem[30000-2].hh()).b1() = byte(normal)
  1787. prg.avail = 0
  1788. prg.memEnd = 30000
  1789. prg.hiMemMin = uint16(30000 - 13) // initialize the one-word memory
  1790. prg.varUsed = memBot + glueSpecSize + glueSpecSize + glueSpecSize + glueSpecSize + glueSpecSize - 1 + 1 - memBot
  1791. prg.dynUsed = hiMemStatUsage
  1792. // initialize statistics
  1793. *(*prg.eqtb[undefinedControlSequence-1].hh()).b0() = byte(undefinedCs)
  1794. *(*prg.eqtb[undefinedControlSequence-1].hh()).rh() = 0
  1795. *(*prg.eqtb[undefinedControlSequence-1].hh()).b1() = byte(levelZero)
  1796. for ii := int32(activeBase); ii <= undefinedControlSequence-1; ii++ {
  1797. k = ii
  1798. _ = k
  1799. prg.eqtb[k-1] = prg.eqtb[undefinedControlSequence-1]
  1800. }
  1801. *(*prg.eqtb[glueBase-1].hh()).rh() = uint16(memBot)
  1802. *(*prg.eqtb[glueBase-1].hh()).b1() = byte(levelOne)
  1803. *(*prg.eqtb[glueBase-1].hh()).b0() = byte(glueRef)
  1804. for ii := int32(glueBase + 1); ii <= localBase-1; ii++ {
  1805. k = ii
  1806. _ = k
  1807. prg.eqtb[k-1] = prg.eqtb[glueBase-1]
  1808. }
  1809. *(*prg.mem[memBot].hh()).rh() = uint16(int32(*(*prg.mem[memBot].hh()).rh()) + localBase - glueBase)
  1810. *(*prg.eqtb[parShapeLoc-1].hh()).rh() = 0
  1811. *(*prg.eqtb[parShapeLoc-1].hh()).b0() = byte(shapeRef)
  1812. *(*prg.eqtb[parShapeLoc-1].hh()).b1() = byte(levelOne)
  1813. for ii := int32(outputRoutineLoc); ii <= toksBase+255; ii++ {
  1814. k = ii
  1815. _ = k
  1816. prg.eqtb[k-1] = prg.eqtb[undefinedControlSequence-1]
  1817. }
  1818. *(*prg.eqtb[boxBase+0-1].hh()).rh() = 0
  1819. *(*prg.eqtb[boxBase-1].hh()).b0() = byte(boxRef)
  1820. *(*prg.eqtb[boxBase-1].hh()).b1() = byte(levelOne)
  1821. for ii := int32(boxBase + 1); ii <= boxBase+255; ii++ {
  1822. k = ii
  1823. _ = k
  1824. prg.eqtb[k-1] = prg.eqtb[boxBase-1]
  1825. }
  1826. *(*prg.eqtb[curFontLoc-1].hh()).rh() = uint16(fontBase)
  1827. *(*prg.eqtb[curFontLoc-1].hh()).b0() = byte(data)
  1828. *(*prg.eqtb[curFontLoc-1].hh()).b1() = byte(levelOne)
  1829. for ii := int32(mathFontBase); ii <= mathFontBase+47; ii++ {
  1830. k = ii
  1831. _ = k
  1832. prg.eqtb[k-1] = prg.eqtb[curFontLoc-1]
  1833. }
  1834. *(*prg.eqtb[catCodeBase-1].hh()).rh() = 0
  1835. *(*prg.eqtb[catCodeBase-1].hh()).b0() = byte(data)
  1836. *(*prg.eqtb[catCodeBase-1].hh()).b1() = byte(levelOne)
  1837. for ii := int32(catCodeBase + 1); ii <= intBase-1; ii++ {
  1838. k = ii
  1839. _ = k
  1840. prg.eqtb[k-1] = prg.eqtb[catCodeBase-1]
  1841. }
  1842. for ii := int32(0); ii <= 255; ii++ {
  1843. k = ii
  1844. _ = k
  1845. *(*prg.eqtb[catCodeBase+k-1].hh()).rh() = uint16(otherChar)
  1846. *(*prg.eqtb[mathCodeBase+k-1].hh()).rh() = uint16(k + 0)
  1847. *(*prg.eqtb[sfCodeBase+k-1].hh()).rh() = 1000
  1848. }
  1849. *(*prg.eqtb[catCodeBase+carriageReturn-1].hh()).rh() = uint16(carRet)
  1850. *(*prg.eqtb[catCodeBase+' '-1].hh()).rh() = uint16(spacer)
  1851. *(*prg.eqtb[catCodeBase+'\\'-1].hh()).rh() = uint16(escape)
  1852. *(*prg.eqtb[catCodeBase+'%'-1].hh()).rh() = uint16(comment)
  1853. *(*prg.eqtb[catCodeBase+invalidCode-1].hh()).rh() = uint16(invalidChar)
  1854. *(*prg.eqtb[catCodeBase+nullCode-1].hh()).rh() = uint16(ignore)
  1855. for ii := int32('0'); ii <= '9'; ii++ {
  1856. k = ii
  1857. _ = k
  1858. *(*prg.eqtb[mathCodeBase+k-1].hh()).rh() = uint16(k + 070000 + 0)
  1859. }
  1860. for ii := int32('A'); ii <= 'Z'; ii++ {
  1861. k = ii
  1862. _ = k
  1863. *(*prg.eqtb[catCodeBase+k-1].hh()).rh() = uint16(letter)
  1864. *(*prg.eqtb[catCodeBase+k+'a'-'A'-1].hh()).rh() = uint16(letter)
  1865. *(*prg.eqtb[mathCodeBase+k-1].hh()).rh() = uint16(k + 070000 + 0400 + 0)
  1866. *(*prg.eqtb[mathCodeBase+k+'a'-'A'-1].hh()).rh() = uint16(k + 'a' - 'A' + 070000 + 0400 + 0)
  1867. *(*prg.eqtb[lcCodeBase+k-1].hh()).rh() = uint16(k + 'a' - 'A')
  1868. *(*prg.eqtb[lcCodeBase+k+'a'-'A'-1].hh()).rh() = uint16(k + 'a' - 'A')
  1869. *(*prg.eqtb[ucCodeBase+k-1].hh()).rh() = uint16(k)
  1870. *(*prg.eqtb[ucCodeBase+k+'a'-'A'-1].hh()).rh() = uint16(k)
  1871. *(*prg.eqtb[sfCodeBase+k-1].hh()).rh() = 999
  1872. }
  1873. for ii := int32(intBase); ii <= delCodeBase-1; ii++ {
  1874. k = ii
  1875. _ = k
  1876. *prg.eqtb[k-1].int() = 0
  1877. }
  1878. *prg.eqtb[intBase+magCode-1].int() = 1000
  1879. *prg.eqtb[intBase+toleranceCode-1].int() = 10000
  1880. *prg.eqtb[intBase+hangAfterCode-1].int() = 1
  1881. *prg.eqtb[intBase+maxDeadCyclesCode-1].int() = 25
  1882. *prg.eqtb[intBase+escapeCharCode-1].int() = '\\'
  1883. *prg.eqtb[intBase+endLineCharCode-1].int() = carriageReturn
  1884. for ii := int32(0); ii <= 255; ii++ {
  1885. k = ii
  1886. _ = k
  1887. *prg.eqtb[delCodeBase+k-1].int() = -1
  1888. }
  1889. *prg.eqtb[delCodeBase+'.'-1].int() = 0 // this null delimiter is used in error recovery
  1890. for ii := int32(dimenBase); ii <= eqtbSize; ii++ {
  1891. k = ii
  1892. _ = k
  1893. *prg.eqtb[k-1].int() = 0
  1894. }
  1895. prg.hashUsed = uint16(frozenControlSequence) // nothing is used
  1896. prg.csCount = 0
  1897. *(*prg.eqtb[frozenDontExpand-1].hh()).b0() = byte(dontExpand)
  1898. *prg.hash[frozenDontExpand-514].rh() = 502
  1899. // \xref[notexpanded:]
  1900. prg.fontPtr = byte(fontBase)
  1901. prg.fmemPtr = 7
  1902. prg.fontName[fontBase] = /* "nullfont" */ 801
  1903. prg.fontArea[fontBase] = /* "" */ 338
  1904. prg.hyphenChar[fontBase] = '-'
  1905. prg.skewChar[fontBase] = -1
  1906. prg.bcharLabel[fontBase] = uint16(nonAddress)
  1907. prg.fontBchar[fontBase] = uint16(256 + minQuarterword)
  1908. prg.fontFalseBchar[fontBase] = uint16(256 + minQuarterword)
  1909. prg.fontBc[fontBase] = 1
  1910. prg.fontEc[fontBase] = 0
  1911. prg.fontSize[fontBase] = 0
  1912. prg.fontDsize[fontBase] = 0
  1913. prg.charBase[fontBase] = 0
  1914. prg.widthBase[fontBase] = 0
  1915. prg.heightBase[fontBase] = 0
  1916. prg.depthBase[fontBase] = 0
  1917. prg.italicBase[fontBase] = 0
  1918. prg.ligKernBase[fontBase] = 0
  1919. prg.kernBase[fontBase] = 0
  1920. prg.extenBase[fontBase] = 0
  1921. prg.fontGlue[fontBase] = 0
  1922. prg.fontParams[fontBase] = 7
  1923. prg.paramBase[fontBase] = -1
  1924. for ii := int32(0); ii <= 6; ii++ {
  1925. k = ii
  1926. _ = k
  1927. *prg.fontInfo[k].int() = 0
  1928. }
  1929. for ii := int32(-trieOpSize); ii <= trieOpSize; ii++ {
  1930. k = ii
  1931. _ = k
  1932. prg.trieOpHash[k+500] = 0
  1933. }
  1934. for ii := int32(0); ii <= 255; ii++ {
  1935. k = ii
  1936. _ = k
  1937. prg.trieUsed[k] = byte(minQuarterword)
  1938. }
  1939. prg.trieOpPtr = 0
  1940. prg.trieNotReady = true
  1941. prg.trieL[0] = 0
  1942. prg.trieC[0] = 0
  1943. prg.triePtr = 0
  1944. *prg.hash[frozenProtection-514].rh() = 1190
  1945. // \xref[inaccessible]
  1946. prg.formatIdent = /* " (INITEX)" */ 1257
  1947. *prg.hash[endWrite-514].rh() = 1296
  1948. *(*prg.eqtb[endWrite-1].hh()).b1() = byte(levelOne)
  1949. *(*prg.eqtb[endWrite-1].hh()).b0() = byte(outerCall)
  1950. *(*prg.eqtb[endWrite-1].hh()).rh() = 0
  1951. }
  1952. // \4
  1953. // Basic printing procedures
  1954. func (prg *prg) printLn() {
  1955. switch prg.selector {
  1956. case termAndLog:
  1957. prg.termOut.Writeln()
  1958. prg.logFile.Writeln()
  1959. prg.termOffset = 0
  1960. prg.fileOffset = 0
  1961. case logOnly:
  1962. prg.logFile.Writeln()
  1963. prg.fileOffset = 0
  1964. case termOnly:
  1965. prg.termOut.Writeln()
  1966. prg.termOffset = 0
  1967. case noPrint, pseudo, newString:
  1968. default:
  1969. prg.writeFile[prg.selector].Writeln()
  1970. }
  1971. } // |tally| is not affected
  1972. func (prg *prg) printChar(s asciiCode) {
  1973. if int32(s) == *prg.eqtb[intBase+newLineCharCode-1].int() {
  1974. // Character |s| is the current new-line character
  1975. if int32(prg.selector) < pseudo {
  1976. prg.printLn()
  1977. goto exit
  1978. }
  1979. }
  1980. switch prg.selector {
  1981. case termAndLog:
  1982. prg.termOut.Write(string(rune(prg.xchr[s])))
  1983. prg.logFile.Write(string(rune(prg.xchr[s])))
  1984. prg.termOffset = byte(int32(prg.termOffset) + 1)
  1985. prg.fileOffset = byte(int32(prg.fileOffset) + 1)
  1986. if int32(prg.termOffset) == maxPrintLine {
  1987. prg.termOut.Writeln()
  1988. prg.termOffset = 0
  1989. }
  1990. if int32(prg.fileOffset) == maxPrintLine {
  1991. prg.logFile.Writeln()
  1992. prg.fileOffset = 0
  1993. }
  1994. case logOnly:
  1995. prg.logFile.Write(string(rune(prg.xchr[s])))
  1996. prg.fileOffset = byte(int32(prg.fileOffset) + 1)
  1997. if int32(prg.fileOffset) == maxPrintLine {
  1998. prg.printLn()
  1999. }
  2000. case termOnly:
  2001. prg.termOut.Write(string(rune(prg.xchr[s])))
  2002. prg.termOffset = byte(int32(prg.termOffset) + 1)
  2003. if int32(prg.termOffset) == maxPrintLine {
  2004. prg.printLn()
  2005. }
  2006. case noPrint:
  2007. case pseudo:
  2008. if prg.tally < prg.trickCount {
  2009. prg.trickBuf[prg.tally%errorLine] = s
  2010. }
  2011. case newString:
  2012. if int32(prg.poolPtr) < poolSize {
  2013. prg.strPool[prg.poolPtr] = s
  2014. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  2015. }
  2016. // we drop characters if the string space is full
  2017. default:
  2018. prg.writeFile[prg.selector].Write(string(rune(prg.xchr[s])))
  2019. }
  2020. prg.tally = prg.tally + 1
  2021. exit:
  2022. }
  2023. func (prg *prg) print(s int32) {
  2024. var (
  2025. j poolPointer // current character code position
  2026. nl int32 // new-line character to restore
  2027. )
  2028. if s >= int32(prg.strPtr) {
  2029. s = /* "???" */ 259
  2030. } else if s < 256 {
  2031. if s < 0 {
  2032. s = /* "???" */ 259
  2033. } else {
  2034. if int32(prg.selector) > pseudo {
  2035. prg.printChar(asciiCode(s))
  2036. goto exit // internal strings are not expanded
  2037. }
  2038. if s == *prg.eqtb[intBase+newLineCharCode-1].int() {
  2039. if int32(prg.selector) < pseudo {
  2040. prg.printLn()
  2041. goto exit
  2042. }
  2043. }
  2044. nl = *prg.eqtb[intBase+newLineCharCode-1].int()
  2045. *prg.eqtb[intBase+newLineCharCode-1].int() = -1
  2046. // temporarily disable new-line character
  2047. j = prg.strStart[s]
  2048. for int32(j) < int32(prg.strStart[s+1]) {
  2049. prg.printChar(prg.strPool[j])
  2050. j = uint16(int32(j) + 1)
  2051. }
  2052. *prg.eqtb[intBase+newLineCharCode-1].int() = nl
  2053. goto exit
  2054. }
  2055. }
  2056. j = prg.strStart[s]
  2057. for int32(j) < int32(prg.strStart[s+1]) {
  2058. prg.printChar(prg.strPool[j])
  2059. j = uint16(int32(j) + 1)
  2060. }
  2061. exit:
  2062. }
  2063. func (prg *prg) slowPrint(s int32) { // prints string |s|
  2064. var (
  2065. j poolPointer // current character code position
  2066. )
  2067. if s >= int32(prg.strPtr) || s < 256 {
  2068. prg.print(s)
  2069. } else {
  2070. j = prg.strStart[s]
  2071. for int32(j) < int32(prg.strStart[s+1]) {
  2072. prg.print(int32(prg.strPool[j]))
  2073. j = uint16(int32(j) + 1)
  2074. }
  2075. }
  2076. }
  2077. func (prg *prg) printNl(s strNumber) {
  2078. if int32(prg.termOffset) > 0 && prg.selector&1 != 0 || int32(prg.fileOffset) > 0 && int32(prg.selector) >= logOnly {
  2079. prg.printLn()
  2080. }
  2081. prg.print(int32(s))
  2082. }
  2083. func (prg *prg) printEsc(s strNumber) { // prints escape character, then |s|
  2084. var (
  2085. c int32 // the escape character code
  2086. )
  2087. c = *prg.eqtb[intBase+escapeCharCode-1].int()
  2088. if c >= 0 {
  2089. if c < 256 {
  2090. prg.print(c)
  2091. }
  2092. }
  2093. prg.slowPrint(int32(s))
  2094. }
  2095. func (prg *prg) printTheDigs(k eightBits) {
  2096. for int32(k) > 0 {
  2097. k = byte(int32(k) - 1)
  2098. if int32(prg.dig[k]) < 10 {
  2099. prg.printChar(asciiCode('0' + int32(prg.dig[k])))
  2100. } else {
  2101. prg.printChar(asciiCode('A' - 10 + int32(prg.dig[k])))
  2102. }
  2103. }
  2104. }
  2105. func (prg *prg) printInt(n int32) { // prints an integer in decimal form
  2106. var (
  2107. k/* 0..23 */ byte // index to current digit; we assume that $\vert n\vert<10^[23]$
  2108. m int32 // used to negate |n| in possibly dangerous cases
  2109. )
  2110. k = 0
  2111. if n < 0 {
  2112. prg.printChar(asciiCode('-'))
  2113. if n > -100000000 {
  2114. n = -n
  2115. } else {
  2116. m = -1 - n
  2117. n = m / 10
  2118. m = m%10 + 1
  2119. k = 1
  2120. if m < 10 {
  2121. prg.dig[0] = byte(m)
  2122. } else {
  2123. prg.dig[0] = 0
  2124. n = n + 1
  2125. }
  2126. }
  2127. }
  2128. for {
  2129. prg.dig[k] = byte(n % 10)
  2130. n = n / 10
  2131. k = byte(int32(k) + 1)
  2132. if n == 0 {
  2133. break
  2134. }
  2135. }
  2136. prg.printTheDigs(k)
  2137. }
  2138. func (prg *prg) printCs(p int32) {
  2139. if p < hashBase {
  2140. if p >= singleBase {
  2141. if p == nullCs {
  2142. prg.printEsc(strNumber( /* "csname" */ 504))
  2143. prg.printEsc(strNumber( /* "endcsname" */ 505))
  2144. prg.printChar(asciiCode(' '))
  2145. } else {
  2146. prg.printEsc(strNumber(p - singleBase))
  2147. if int32(*(*prg.eqtb[catCodeBase+p-singleBase-1].hh()).rh()) == letter {
  2148. prg.printChar(asciiCode(' '))
  2149. }
  2150. }
  2151. } else if p < activeBase {
  2152. prg.printEsc(strNumber( /* "IMPOSSIBLE." */ 506))
  2153. } else {
  2154. prg.print(p - activeBase)
  2155. }
  2156. } else if p >= undefinedControlSequence {
  2157. prg.printEsc(strNumber( /* "IMPOSSIBLE." */ 506))
  2158. } else if int32(*prg.hash[p-514].rh()) < 0 || int32(*prg.hash[p-514].rh()) >= int32(prg.strPtr) {
  2159. prg.printEsc(strNumber( /* "NONEXISTENT." */ 507))
  2160. } else {
  2161. prg.printEsc(*prg.hash[p-514].rh())
  2162. prg.printChar(asciiCode(' '))
  2163. }
  2164. }
  2165. func (prg *prg) sprintCs(p halfword) {
  2166. if int32(p) < hashBase {
  2167. if int32(p) < singleBase {
  2168. prg.print(int32(p) - activeBase)
  2169. } else if int32(p) < nullCs {
  2170. prg.printEsc(strNumber(int32(p) - singleBase))
  2171. } else {
  2172. prg.printEsc(strNumber( /* "csname" */ 504))
  2173. prg.printEsc(strNumber( /* "endcsname" */ 505))
  2174. }
  2175. } else {
  2176. prg.printEsc(*prg.hash[p-514].rh())
  2177. }
  2178. }
  2179. func (prg *prg) printFileName(n, a, e int32) {
  2180. prg.slowPrint(a)
  2181. prg.slowPrint(n)
  2182. prg.slowPrint(e)
  2183. }
  2184. func (prg *prg) printSize(s int32) {
  2185. if s == textSize {
  2186. prg.printEsc(strNumber( /* "textfont" */ 412))
  2187. } else if s == scriptSize {
  2188. prg.printEsc(strNumber( /* "scriptfont" */ 413))
  2189. } else {
  2190. prg.printEsc(strNumber( /* "scriptscriptfont" */ 414))
  2191. }
  2192. }
  2193. func (prg *prg) printWriteWhatsit(s strNumber, p halfword) {
  2194. prg.printEsc(s)
  2195. if int32(*(*prg.mem[int32(p)+1].hh()).lh()) < 16 {
  2196. prg.printInt(int32(*(*prg.mem[int32(p)+1].hh()).lh()))
  2197. } else if int32(*(*prg.mem[int32(p)+1].hh()).lh()) == 16 {
  2198. prg.printChar(asciiCode('*'))
  2199. } else {
  2200. prg.printChar(asciiCode('-'))
  2201. }
  2202. } // \2
  2203. // \4\hskip-\fontdimen2\font
  2204. // procedure debug_help;
  2205. // forward; [ ]
  2206. func (prg *prg) jumpOut() {
  2207. panic(signal(endOfTex))
  2208. }
  2209. func (prg *prg) error1() {
  2210. var (
  2211. c asciiCode // what the user types
  2212. s1, s2, s3, s4 int32
  2213. // used to save global variables when deleting tokens
  2214. )
  2215. if int32(prg.history) < errorMessageIssued {
  2216. prg.history = byte(errorMessageIssued)
  2217. }
  2218. prg.printChar(asciiCode('.'))
  2219. prg.showContext()
  2220. if int32(prg.interaction) == errorStopMode {
  2221. for true {
  2222. continue1:
  2223. if int32(prg.interaction) != errorStopMode {
  2224. goto exit
  2225. }
  2226. prg.clearForErrorPrompt()
  2227. {
  2228. prg.print( /* "? " */ 264)
  2229. prg.termInput()
  2230. }
  2231. // \xref[?\relax]
  2232. if int32(prg.last) == int32(prg.first) {
  2233. goto exit
  2234. }
  2235. c = prg.buffer[prg.first]
  2236. if int32(c) >= 'a' {
  2237. c = byte(int32(c) + 'A' - 'a')
  2238. } // convert to uppercase
  2239. // Interpret code |c| and |return| if done
  2240. switch c {
  2241. case '0', '1', '2', '3',
  2242. '4', '5', '6', '7',
  2243. '8', '9':
  2244. if prg.deletionsAllowed {
  2245. s1 = int32(prg.curTok)
  2246. s2 = int32(prg.curCmd)
  2247. s3 = int32(prg.curChr)
  2248. s4 = prg.alignState
  2249. prg.alignState = 1000000
  2250. prg.okToInterrupt = false
  2251. if int32(prg.last) > int32(prg.first)+1 && int32(prg.buffer[int32(prg.first)+1]) >= '0' && int32(prg.buffer[int32(prg.first)+1]) <= '9' {
  2252. c = byte(int32(c)*10 + int32(prg.buffer[int32(prg.first)+1]) - '0'*11)
  2253. } else {
  2254. c = byte(int32(c) - '0')
  2255. }
  2256. for int32(c) > 0 {
  2257. prg.getToken() // one-level recursive call of |error| is possible
  2258. c = byte(int32(c) - 1)
  2259. }
  2260. prg.curTok = uint16(s1)
  2261. prg.curCmd = byte(s2)
  2262. prg.curChr = uint16(s3)
  2263. prg.alignState = s4
  2264. prg.okToInterrupt = true
  2265. {
  2266. prg.helpPtr = 2
  2267. prg.helpLine[1] = /* "I have just deleted some text, as you asked." */ 279
  2268. prg.helpLine[0] = /* "You can now delete more, or insert, or whatever." */ 280
  2269. }
  2270. prg.showContext()
  2271. goto continue1
  2272. }
  2273. // \4\4
  2274. // ["D"=]68: begin debug_help; goto continue; end; [ ]
  2275. // "E"=
  2276. case 'E':
  2277. if int32(prg.basePtr) > 0 {
  2278. if int32(prg.inputStack[prg.basePtr].nameField) >= 256 {
  2279. prg.printNl(strNumber( /* "You want to edit file " */ 265))
  2280. // \xref[You want to edit file x]
  2281. prg.slowPrint(int32(prg.inputStack[prg.basePtr].nameField))
  2282. prg.print( /* " at line " */ 266)
  2283. prg.printInt(prg.line)
  2284. prg.interaction = byte(scrollMode)
  2285. prg.jumpOut()
  2286. }
  2287. }
  2288. // "H"=
  2289. case 'H':
  2290. // Print the help information and |goto continue|
  2291. if prg.useErrHelp {
  2292. prg.giveErrHelp()
  2293. prg.useErrHelp = false
  2294. } else {
  2295. if int32(prg.helpPtr) == 0 {
  2296. prg.helpPtr = 2
  2297. prg.helpLine[1] = /* "Sorry, I don't know how to help in this situation." */ 281
  2298. prg.helpLine[0] = /* "Maybe you should try asking a human?" */ 282
  2299. }
  2300. for {
  2301. prg.helpPtr = byte(int32(prg.helpPtr) - 1)
  2302. prg.print(int32(prg.helpLine[prg.helpPtr]))
  2303. prg.printLn()
  2304. if int32(prg.helpPtr) == 0 {
  2305. break
  2306. }
  2307. }
  2308. }
  2309. {
  2310. prg.helpPtr = 4
  2311. prg.helpLine[3] = /* "Sorry, I already gave what help I could..." */ 283
  2312. prg.helpLine[2] = /* "Maybe you should try asking a human?" */ 282
  2313. prg.helpLine[1] = /* "An error might have occurred before I noticed any problems." */ 284
  2314. prg.helpLine[0] = /* "``If all else fails, read the instructions.''" */ 285
  2315. }
  2316. goto continue1
  2317. // "I"=
  2318. case 'I':
  2319. // Introduce new material from the terminal and |return|
  2320. prg.beginFileReading() // enter a new syntactic level for terminal input
  2321. // now |state=mid_line|, so an initial blank space will count as a blank
  2322. if int32(prg.last) > int32(prg.first)+1 {
  2323. prg.curInput.locField = uint16(int32(prg.first) + 1)
  2324. prg.buffer[prg.first] = ' '
  2325. } else {
  2326. {
  2327. prg.print( /* "insert>" */ 278)
  2328. prg.termInput()
  2329. }
  2330. prg.curInput.locField = prg.first
  2331. // \xref[insert>]
  2332. }
  2333. prg.first = prg.last
  2334. prg.curInput.limitField = uint16(int32(prg.last) - 1) // no |end_line_char| ends this line
  2335. // no |end_line_char| ends this line
  2336. goto exit
  2337. // "Q"=
  2338. case 'Q', 'R', 'S':
  2339. // Change the interaction level and |return|
  2340. prg.errorCount = 0
  2341. prg.interaction = byte(batchMode + int32(c) - 'Q')
  2342. prg.print( /* "OK, entering " */ 273)
  2343. switch c {
  2344. case 'Q':
  2345. prg.printEsc(strNumber( /* "batchmode" */ 274))
  2346. prg.selector = byte(int32(prg.selector) - 1)
  2347. // "R"=
  2348. case 'R':
  2349. prg.printEsc(strNumber( /* "nonstopmode" */ 275))
  2350. // "S"=
  2351. case 'S':
  2352. prg.printEsc(strNumber( /* "scrollmode" */ 276))
  2353. } // there are no other cases
  2354. prg.print( /* "..." */ 277)
  2355. prg.printLn()
  2356. goto exit
  2357. // "X"=
  2358. case 'X':
  2359. prg.interaction = byte(scrollMode)
  2360. prg.jumpOut()
  2361. default:
  2362. }
  2363. // Print the menu of available options
  2364. {
  2365. prg.print( /* "Type <return> to proceed, S to scroll future error messages," */ 267)
  2366. // \xref[Type <return> to proceed...]
  2367. prg.printNl(strNumber( /* "R to run without stopping, Q to run quietly," */ 268))
  2368. prg.printNl(strNumber( /* "I to insert something, " */ 269))
  2369. if int32(prg.basePtr) > 0 {
  2370. if int32(prg.inputStack[prg.basePtr].nameField) >= 256 {
  2371. prg.print( /* "E to edit your file," */ 270)
  2372. }
  2373. }
  2374. if prg.deletionsAllowed {
  2375. prg.printNl(strNumber( /* "1 or ... or 9 to ignore the next 1 to 9 tokens of input," */ 271))
  2376. }
  2377. prg.printNl(strNumber( /* "H for help, X to quit." */ 272))
  2378. }
  2379. }
  2380. }
  2381. prg.errorCount = int8(int32(prg.errorCount) + 1)
  2382. if int32(prg.errorCount) == 100 {
  2383. prg.printNl(strNumber( /* "(That makes 100 errors; please try again.)" */ 263))
  2384. // \xref[That makes 100 errors...]
  2385. prg.history = byte(fatalErrorStop)
  2386. prg.jumpOut()
  2387. }
  2388. // Put help message on the transcript file
  2389. if int32(prg.interaction) > batchMode {
  2390. prg.selector = byte(int32(prg.selector) - 1)
  2391. } // avoid terminal output
  2392. if prg.useErrHelp {
  2393. prg.printLn()
  2394. prg.giveErrHelp()
  2395. } else {
  2396. for int32(prg.helpPtr) > 0 {
  2397. prg.helpPtr = byte(int32(prg.helpPtr) - 1)
  2398. prg.printNl(prg.helpLine[prg.helpPtr])
  2399. }
  2400. }
  2401. prg.printLn()
  2402. if int32(prg.interaction) > batchMode {
  2403. prg.selector = byte(int32(prg.selector) + 1)
  2404. } // re-enable terminal output
  2405. prg.printLn()
  2406. exit:
  2407. }
  2408. func (prg *prg) fatalError(s strNumber) {
  2409. prg.normalizeSelector()
  2410. {
  2411. if int32(prg.interaction) == errorStopMode {
  2412. }
  2413. prg.printNl(strNumber( /* "! " */ 262))
  2414. prg.print( /* "Emergency stop" */ 287)
  2415. }
  2416. {
  2417. prg.helpPtr = 1
  2418. prg.helpLine[0] = s
  2419. }
  2420. {
  2421. if int32(prg.interaction) == errorStopMode {
  2422. prg.interaction = byte(scrollMode)
  2423. }
  2424. if prg.logOpened {
  2425. prg.error1()
  2426. } /* if interaction>batch_mode then debug_help; [ ] */
  2427. prg.history = byte(fatalErrorStop)
  2428. prg.jumpOut()
  2429. }
  2430. // \xref[Emergency stop]
  2431. }
  2432. func (prg *prg) overflow(s strNumber, n int32) {
  2433. prg.normalizeSelector()
  2434. {
  2435. if int32(prg.interaction) == errorStopMode {
  2436. }
  2437. prg.printNl(strNumber( /* "! " */ 262))
  2438. prg.print( /* "TeX capacity exceeded, sorry [" */ 288)
  2439. }
  2440. // \xref[TeX capacity exceeded ...]
  2441. prg.print(int32(s))
  2442. prg.printChar(asciiCode('='))
  2443. prg.printInt(n)
  2444. prg.printChar(asciiCode(']'))
  2445. {
  2446. prg.helpPtr = 2
  2447. prg.helpLine[1] = /* "If you really absolutely need more capacity," */ 289
  2448. prg.helpLine[0] = /* "you can ask a wizard to enlarge me." */ 290
  2449. }
  2450. {
  2451. if int32(prg.interaction) == errorStopMode {
  2452. prg.interaction = byte(scrollMode)
  2453. }
  2454. if prg.logOpened {
  2455. prg.error1()
  2456. } /* if interaction>batch_mode then debug_help; [ ] */
  2457. prg.history = byte(fatalErrorStop)
  2458. prg.jumpOut()
  2459. }
  2460. }
  2461. func (prg *prg) confusion(s strNumber) {
  2462. prg.normalizeSelector()
  2463. if int32(prg.history) < errorMessageIssued {
  2464. {
  2465. if int32(prg.interaction) == errorStopMode {
  2466. }
  2467. prg.printNl(strNumber( /* "! " */ 262))
  2468. prg.print( /* "This can't happen (" */ 291)
  2469. }
  2470. prg.print(int32(s))
  2471. prg.printChar(asciiCode(')'))
  2472. // \xref[This can't happen]
  2473. {
  2474. prg.helpPtr = 1
  2475. prg.helpLine[0] = /* "I'm broken. Please show this to someone who can fix can fix" */ 292
  2476. }
  2477. } else {
  2478. {
  2479. if int32(prg.interaction) == errorStopMode {
  2480. }
  2481. prg.printNl(strNumber( /* "! " */ 262))
  2482. prg.print( /* "I can't go on meeting you like this" */ 293)
  2483. }
  2484. // \xref[I can't go on...]
  2485. {
  2486. prg.helpPtr = 2
  2487. prg.helpLine[1] = /* "One of your faux pas seems to have wounded me deeply..." */ 294
  2488. prg.helpLine[0] = /* "in fact, I'm barely conscious. Please fix it and try again." */ 295
  2489. }
  2490. }
  2491. {
  2492. if int32(prg.interaction) == errorStopMode {
  2493. prg.interaction = byte(scrollMode)
  2494. }
  2495. if prg.logOpened {
  2496. prg.error1()
  2497. } /* if interaction>batch_mode then debug_help; [ ] */
  2498. prg.history = byte(fatalErrorStop)
  2499. prg.jumpOut()
  2500. }
  2501. }
  2502. // 5.
  2503. // tangle:pos tex.web:268:3:
  2504. // The overall \TeX\ program begins with the heading just shown, after which
  2505. // comes a bunch of procedure declarations and function declarations.
  2506. // Finally we will get to the main program, which begins with the
  2507. // comment `|start_here|'. If you want to skip down to the
  2508. // main program now, you can look up `|start_here|' in the index.
  2509. // But the author suggests that the best way to understand this program
  2510. // is to follow pretty much the order of \TeX's components as they appear in the
  2511. // \.[WEB] description you are now reading, since the present ordering is
  2512. // intended to combine the advantages of the ``bottom up'' and ``top down''
  2513. // approaches to the problem of understanding a somewhat complicated system.
  2514. // 7.
  2515. // tangle:pos tex.web:290:3:
  2516. // Some of the code below is intended to be used only when diagnosing the
  2517. // strange behavior that sometimes occurs when \TeX\ is being installed or
  2518. // when system wizards are fooling around with \TeX\ without quite knowing
  2519. // what they are doing. Such code will not normally be compiled; it is
  2520. // delimited by the codewords `$|debug|\ldots|gubed|$', with apologies
  2521. // to people who wish to preserve the purity of English.
  2522. //
  2523. // Similarly, there is some conditional code delimited by
  2524. // `$|stat|\ldots|tats|$' that is intended for use when statistics are to be
  2525. // kept about \TeX's memory usage. The |stat| $\ldots$ |tats| code also
  2526. // implements diagnostic information for \.[\\tracingparagraphs],
  2527. // \.[\\tracingpages], and \.[\\tracingrestores].
  2528. // \xref[debugging]
  2529. // 10.
  2530. // tangle:pos tex.web:348:3:
  2531. // This \TeX\ implementation conforms to the rules of the [\sl Pascal User
  2532. // \xref[PASCAL][\PASCAL]
  2533. // \xref[system dependencies]
  2534. // Manual] published by Jensen and Wirth in 1975, except where system-dependent
  2535. // \xref[Wirth, Niklaus]
  2536. // \xref[Jensen, Kathleen]
  2537. // code is necessary to make a useful system program, and except in another
  2538. // respect where such conformity would unnecessarily obscure the meaning
  2539. // and clutter up the code: We assume that |case| statements may include a
  2540. // default case that applies if no matching label is found. Thus, we shall use
  2541. // constructions like
  2542. // $$\vbox[\halign[\ignorespaces#\hfil\cr
  2543. // |case x of|\cr
  2544. // 1: $\langle\,$code for $x=1\,\rangle$;\cr
  2545. // 3: $\langle\,$code for $x=3\,\rangle$;\cr
  2546. // |othercases| $\langle\,$code for |x<>1| and |x<>3|$\,\rangle$\cr
  2547. // |endcases|\cr]]$$
  2548. // since most \PASCAL\ compilers have plugged this hole in the language by
  2549. // incorporating some sort of default mechanism. For example, the \ph\
  2550. // compiler allows `|others|:' as a default label, and other \PASCAL s allow
  2551. // syntaxes like `\&[else]' or `\&[otherwise]' or `\\[otherwise]:', etc. The
  2552. // definitions of |othercases| and |endcases| should be changed to agree with
  2553. // local conventions. Note that no semicolon appears before |endcases| in
  2554. // this program, so the definition of |endcases| should include a semicolon
  2555. // if the compiler wants one. (Of course, if no default mechanism is
  2556. // available, the |case| statements of \TeX\ will have to be laboriously
  2557. // extended by listing all remaining cases. People who are stuck with such
  2558. // \PASCAL s have, in fact, done this, successfully but not happily!)
  2559. // \xref[PASCAL H][\ph]
  2560. // 12.
  2561. // tangle:pos tex.web:430:3:
  2562. // Like the preceding parameters, the following quantities can be changed
  2563. // at compile time to extend or reduce \TeX's capacity. But if they are changed,
  2564. // it is necessary to rerun the initialization program \.[INITEX]
  2565. // \xref[INITEX]
  2566. // to generate new tables for the production \TeX\ program.
  2567. // One can't simply make helter-skelter changes to the following constants,
  2568. // since certain rather complex initialization
  2569. // numbers are computed from them. They are defined here using
  2570. // \.[WEB] macros, instead of being put into \PASCAL's |const| list, in order to
  2571. // emphasize this distinction.
  2572. // 15.
  2573. // tangle:pos tex.web:476:3:
  2574. // Labels are given symbolic names by the following definitions, so that
  2575. // occasional |goto| statements will be meaningful. We insert the label
  2576. // `|exit|' just before the `\ignorespaces|end|\unskip' of a procedure in
  2577. // which we have used the `|return|' statement defined below; the label
  2578. // `|restart|' is occasionally used at the very beginning of a procedure; and
  2579. // the label `|reswitch|' is occasionally used just prior to a |case|
  2580. // statement in which some cases change the conditions and we wish to branch
  2581. // to the newly applicable case. Loops that are set up with the |loop|
  2582. // construction defined below are commonly exited by going to `|done|' or to
  2583. // `|found|' or to `|not_found|', and they are sometimes repeated by going to
  2584. // `|continue|'. If two or more parts of a subroutine start differently but
  2585. // end up the same, the shared code may be gathered together at
  2586. // `|common_ending|'.
  2587. //
  2588. // Incidentally, this program never declares a label that isn't actually used,
  2589. // because some fussy \PASCAL\ compilers will complain about redundant labels.
  2590. // 16.
  2591. // tangle:pos tex.web:510:3:
  2592. // Here are some macros for common programming idioms.
  2593. // 17. \[2] The character set
  2594. // tangle:pos tex.web:523:27:
  2595. // In order to make \TeX\ readily portable to a wide variety of
  2596. // computers, all of its input text is converted to an internal eight-bit
  2597. // code that includes standard ASCII, the ``American Standard Code for
  2598. // Information Interchange.'' This conversion is done immediately when each
  2599. // character is read in. Conversely, characters are converted from ASCII to
  2600. // the user's external representation just before they are output to a
  2601. // text file.
  2602. //
  2603. // Such an internal code is relevant to users of \TeX\ primarily because it
  2604. // governs the positions of characters in the fonts. For example, the
  2605. // character `\.A' has ASCII code $65=@'101$, and when \TeX\ typesets
  2606. // this letter it specifies character number 65 in the current font.
  2607. // If that font actually has `\.A' in a different position, \TeX\ doesn't
  2608. // know what the real position is; the program that does the actual printing from
  2609. // \TeX's device-independent files is responsible for converting from ASCII to
  2610. // a particular font encoding.
  2611. // \xref[ASCII code]
  2612. //
  2613. // \TeX's internal code also defines the value of constants
  2614. // that begin with a reverse apostrophe; and it provides an index to the
  2615. // \.[\\catcode], \.[\\mathcode], \.[\\uccode], \.[\\lccode], and \.[\\delcode]
  2616. // tables.
  2617. // 22.
  2618. // tangle:pos tex.web:702:3:
  2619. // Some of the ASCII codes without visible characters have been given symbolic
  2620. // names in this program because they are used with a special meaning.
  2621. // 27.
  2622. // tangle:pos tex.web:808:3:
  2623. // The \ph\ compiler with which the present version of \TeX\ was prepared has
  2624. // extended the rules of \PASCAL\ in a very convenient way. To open file~|f|,
  2625. // we can write
  2626. // $$\vbox[\halign[#\hfil\qquad&#\hfil\cr
  2627. // |reset(f,\\[name],'/O')|&for input;\cr
  2628. // |rewrite(f,\\[name],'/O')|&for output.\cr]]$$
  2629. // The `\\[name]' parameter, which is of type `[\bf packed array
  2630. // $[\langle\\[any]\rangle]$ of \\[char]]', stands for the name of
  2631. // the external file that is being opened for input or output.
  2632. // Blank spaces that might appear in \\[name] are ignored.
  2633. //
  2634. // The `\.[/O]' parameter tells the operating system not to issue its own
  2635. // error messages if something goes wrong. If a file of the specified name
  2636. // cannot be found, or if such a file cannot be opened for some other reason
  2637. // (e.g., someone may already be trying to write the same file), we will have
  2638. // | erstat(f)<>0| after an unsuccessful |reset| or |rewrite|. This allows
  2639. // \TeX\ to undertake appropriate corrective action.
  2640. // \xref[PASCAL H][\ph]
  2641. // \xref[system dependencies]
  2642. //
  2643. // \TeX's file-opening procedures return |false| if no file identified by
  2644. // |name_of_file| could be opened.
  2645. func (prg *prg) aOpenIn(f alphaFile) (r bool) {
  2646. f.Reset(arraystr(prg.nameOfFile[:]), "/O")
  2647. r = f.ErStat() == 0
  2648. return r
  2649. }
  2650. func (prg *prg) aOpenOut(f alphaFile) (r bool) {
  2651. f.Rewrite(arraystr(prg.nameOfFile[:]), "/O")
  2652. r = f.ErStat() == 0
  2653. return r
  2654. }
  2655. func (prg *prg) bOpenIn(f byteFile) (r bool) {
  2656. f.Reset(arraystr(prg.nameOfFile[:]), "/O")
  2657. r = f.ErStat() == 0
  2658. return r
  2659. }
  2660. func (prg *prg) bOpenOut(f byteFile) (r bool) {
  2661. f.Rewrite(arraystr(prg.nameOfFile[:]), "/O")
  2662. r = f.ErStat() == 0
  2663. return r
  2664. }
  2665. func (prg *prg) wOpenIn(f wordFile) (r bool) {
  2666. f.Reset(arraystr(prg.nameOfFile[:]), "/O")
  2667. r = f.ErStat() == 0
  2668. return r
  2669. }
  2670. func (prg *prg) wOpenOut(f wordFile) (r bool) {
  2671. f.Rewrite(arraystr(prg.nameOfFile[:]), "/O")
  2672. r = f.ErStat() == 0
  2673. return r
  2674. }
  2675. // 28.
  2676. // tangle:pos tex.web:864:3:
  2677. // Files can be closed with the \ph\ routine `|close(f)|', which
  2678. // \xref[PASCAL H][\ph]
  2679. // \xref[system dependencies]
  2680. // should be used when all input or output with respect to |f| has been completed.
  2681. // This makes |f| available to be opened again, if desired; and if |f| was used for
  2682. // output, the |close| operation makes the corresponding external file appear
  2683. // on the user's area, ready to be read.
  2684. //
  2685. // These procedures should not generate error messages if a file is
  2686. // being closed before it has been successfully opened.
  2687. func (prg *prg) aClose(f alphaFile) {
  2688. f.Close()
  2689. }
  2690. func (prg *prg) bClose(f byteFile) {
  2691. f.Close()
  2692. }
  2693. func (prg *prg) wClose(f wordFile) {
  2694. f.Close()
  2695. }
  2696. // 29.
  2697. // tangle:pos tex.web:887:3:
  2698. // Binary input and output are done with \PASCAL's ordinary |get| and |put|
  2699. // procedures, so we don't have to make any other special arrangements for
  2700. // binary~I/O. Text output is also easy to do with standard \PASCAL\ routines.
  2701. // The treatment of text input is more difficult, however, because
  2702. // of the necessary translation to |ASCII_code| values.
  2703. // \TeX's conventions should be efficient, and they should
  2704. // blend nicely with the user's operating environment.
  2705. // 31.
  2706. // tangle:pos tex.web:908:3:
  2707. // The |input_ln| function brings the next line of input from the specified
  2708. // file into available positions of the buffer array and returns the value
  2709. // |true|, unless the file has already been entirely read, in which case it
  2710. // returns |false| and sets |last:=first|. In general, the |ASCII_code|
  2711. // numbers that represent the next line of the file are input into
  2712. // |buffer[first]|, |buffer[first+1]|, \dots, |buffer[last-1]|; and the
  2713. // global variable |last| is set equal to |first| plus the length of the
  2714. // line. Trailing blanks are removed from the line; thus, either |last=first|
  2715. // (in which case the line was entirely blank) or |buffer[last-1]<>" "|.
  2716. //
  2717. // An overflow error is given, however, if the normal actions of |input_ln|
  2718. // would make |last>=buf_size|; this is done so that other parts of \TeX\
  2719. // can safely look at the contents of |buffer[last+1]| without overstepping
  2720. // the bounds of the |buffer| array. Upon entry to |input_ln|, the condition
  2721. // |first<buf_size| will always hold, so that there is always room for an
  2722. // “empty” line.
  2723. //
  2724. // The variable |max_buf_stack|, which is used to keep track of how large
  2725. // the |buf_size| parameter must be to accommodate the present job, is
  2726. // also kept up to date by |input_ln|.
  2727. //
  2728. // If the |bypass_eoln| parameter is |true|, |input_ln| will do a |get|
  2729. // before looking at the first character of the line; this skips over
  2730. // an |eoln| that was in |f^|. The procedure does not do a |get| when it
  2731. // reaches the end of the line; therefore it can be used to acquire input
  2732. // from the user's terminal as well as from ordinary text files.
  2733. //
  2734. // Standard \PASCAL\ says that a file should have |eoln| immediately
  2735. // before |eof|, but \TeX\ needs only a weaker restriction: If |eof|
  2736. // occurs in the middle of a line, the system function |eoln| should return
  2737. // a |true| result (even though |f^| will be undefined).
  2738. //
  2739. // Since the inner loop of |input_ln| is part of \TeX's “inner loop”---each
  2740. // character of input comes in at this place---it is wise to reduce system
  2741. // overhead by making use of special routines that read in an entire array
  2742. // of characters at once, if such routines are available. The following
  2743. // code uses standard \PASCAL\ to illustrate what needs to be done, but
  2744. // finer tuning is often possible at well-developed \PASCAL\ sites.
  2745. // \xref[inner loop]
  2746. func (prg *prg) inputLn(f alphaFile, bypassEoln bool) (r bool) {
  2747. // inputs the next line or returns |false|
  2748. var (
  2749. lastNonblank /* 0..bufSize */ uint16 // |last| with trailing blanks removed
  2750. )
  2751. if bypassEoln {
  2752. if !f.EOF() && f.EOLN() {
  2753. f.Get()
  2754. }
  2755. }
  2756. // input the first character of the line into |f^|
  2757. prg.last = prg.first // cf.\ Matthew 19\thinspace:\thinspace30
  2758. if f.EOF() {
  2759. r = false
  2760. } else {
  2761. lastNonblank = prg.first
  2762. for !f.EOLN() {
  2763. if int32(prg.last) >= int32(prg.maxBufStack) {
  2764. prg.maxBufStack = uint16(int32(prg.last) + 1)
  2765. if int32(prg.maxBufStack) == bufSize {
  2766. if int32(prg.formatIdent) == 0 {
  2767. prg.termOut.Writeln("Buffer size exceeded!")
  2768. panic(signal(finalEnd))
  2769. // \xref[Buffer size exceeded]
  2770. } else {
  2771. prg.curInput.locField = prg.first
  2772. prg.curInput.limitField = uint16(int32(prg.last) - 1)
  2773. prg.overflow(strNumber( /* "buffer size" */ 256), bufSize)
  2774. // \xref[TeX capacity exceeded buffer size][\quad buffer size]
  2775. }
  2776. }
  2777. }
  2778. prg.buffer[prg.last] = prg.xord[*f.ByteP()]
  2779. f.Get()
  2780. prg.last = uint16(int32(prg.last) + 1)
  2781. if int32(prg.buffer[int32(prg.last)-1]) != ' ' {
  2782. lastNonblank = prg.last
  2783. }
  2784. }
  2785. prg.last = lastNonblank
  2786. r = true
  2787. }
  2788. return r
  2789. }
  2790. // 33.
  2791. // tangle:pos tex.web:979:3:
  2792. // Here is how to open the terminal files
  2793. // in \ph. The `\.[/I]' switch suppresses the first |get|.
  2794. // \xref[PASCAL H][\ph]
  2795. // \xref[system dependencies]
  2796. // 34.
  2797. // tangle:pos tex.web:987:3:
  2798. // Sometimes it is necessary to synchronize the input/output mixture that
  2799. // happens on the user's terminal, and three system-dependent
  2800. // procedures are used for this
  2801. // purpose. The first of these, |update_terminal|, is called when we want
  2802. // to make sure that everything we have output to the terminal so far has
  2803. // actually left the computer's internal buffers and been sent.
  2804. // The second, |clear_terminal|, is called when we wish to cancel any
  2805. // input that the user may have typed ahead (since we are about to
  2806. // issue an unexpected error message). The third, |wake_up_terminal|,
  2807. // is supposed to revive the terminal if the user has disabled it by
  2808. // some instruction to the operating system. The following macros show how
  2809. // these operations can be specified in \ph:
  2810. // \xref[PASCAL H][\ph]
  2811. // \xref[system dependencies]
  2812. // 36.
  2813. // tangle:pos tex.web:1044:3:
  2814. // Different systems have different ways to get started. But regardless of
  2815. // what conventions are adopted, the routine that initializes the terminal
  2816. // should satisfy the following specifications:
  2817. //
  2818. // \yskip\textindent[1)]It should open file |term_in| for input from the
  2819. // terminal. (The file |term_out| will already be open for output to the
  2820. // terminal.)
  2821. //
  2822. // \textindent[2)]If the user has given a command line, this line should be
  2823. // considered the first line of terminal input. Otherwise the
  2824. // user should be prompted with `\.[**]', and the first line of input
  2825. // should be whatever is typed in response.
  2826. //
  2827. // \textindent[3)]The first line of input, which might or might not be a
  2828. // command line, should appear in locations |first| to |last-1| of the
  2829. // |buffer| array.
  2830. //
  2831. // \textindent[4)]The global variable |loc| should be set so that the
  2832. // character to be read next by \TeX\ is in |buffer[loc]|. This
  2833. // character should not be blank, and we should have |loc<last|.
  2834. //
  2835. // \yskip\noindent(It may be necessary to prompt the user several times
  2836. // before a non-blank line comes in. The prompt is `\.[**]' instead of the
  2837. // later `\.*' because the meaning is slightly different: `\.[\\input]' need
  2838. // not be typed immediately after~`\.[**]'.)
  2839. // 37.
  2840. // tangle:pos tex.web:1072:3:
  2841. // The following program does the required initialization
  2842. // without retrieving a possible command line.
  2843. // It should be clear how to modify this routine to deal with command lines,
  2844. // if the system permits them.
  2845. // \xref[system dependencies]
  2846. func (prg *prg) initTerminal() (r bool) {
  2847. prg.termIn.Reset("TTY:", "/O/I")
  2848. for true {
  2849. prg.termOut.Write("**")
  2850. // \xref[**]
  2851. if !prg.inputLn(prg.termIn, true) {
  2852. prg.termOut.Writeln()
  2853. prg.termOut.Writeln("! End of file on the terminal... why?")
  2854. // \xref[End of file on the terminal]
  2855. r = false
  2856. goto exit
  2857. }
  2858. prg.curInput.locField = prg.first
  2859. for int32(prg.curInput.locField) < int32(prg.last) && int32(prg.buffer[prg.curInput.locField]) == ' ' {
  2860. prg.curInput.locField = uint16(int32(prg.curInput.locField) + 1)
  2861. }
  2862. if int32(prg.curInput.locField) < int32(prg.last) {
  2863. r = true
  2864. goto exit // return unless the line was all blank
  2865. }
  2866. prg.termOut.Writeln("Please type the name of your input file.")
  2867. }
  2868. exit:
  2869. ;
  2870. return r
  2871. }
  2872. // 40.
  2873. // tangle:pos tex.web:1156:3:
  2874. // Several of the elementary string operations are performed using \.[WEB]
  2875. // macros instead of \PASCAL\ procedures, because many of the
  2876. // operations are done quite frequently and we want to avoid the
  2877. // overhead of procedure calls. For example, here is
  2878. // a simple macro that computes the length of a string.
  2879. // \xref[WEB]
  2880. // 41.
  2881. // tangle:pos tex.web:1166:3:
  2882. // The length of the current string is called |cur_length|:
  2883. // 42.
  2884. // tangle:pos tex.web:1170:3:
  2885. // Strings are created by appending character codes to |str_pool|.
  2886. // The |append_char| macro, defined here, does not check to see if the
  2887. // value of |pool_ptr| has gotten too high; this test is supposed to be
  2888. // made before |append_char| is used. There is also a |flush_char|
  2889. // macro, which erases the last character appended.
  2890. //
  2891. // To test if there is room to append |l| more characters to |str_pool|,
  2892. // we shall write |str_room(l)|, which aborts \TeX\ and gives an
  2893. // apologetic error message if there isn't enough room.
  2894. // 43.
  2895. // tangle:pos tex.web:1190:3:
  2896. // Once a sequence of characters has been appended to |str_pool|, it
  2897. // officially becomes a string when the function |make_string| is called.
  2898. // This function returns the identification number of the new string as its
  2899. // value.
  2900. func (prg *prg) makeString() (r strNumber) {
  2901. if int32(prg.strPtr) == maxStrings {
  2902. prg.overflow(strNumber( /* "number of strings" */ 258), maxStrings-int32(prg.initStrPtr))
  2903. }
  2904. // \xref[TeX capacity exceeded number of strings][\quad number of strings]
  2905. prg.strPtr = uint16(int32(prg.strPtr) + 1)
  2906. prg.strStart[prg.strPtr] = prg.poolPtr
  2907. r = uint16(int32(prg.strPtr) - 1)
  2908. return r
  2909. }
  2910. // 44.
  2911. // tangle:pos tex.web:1203:3:
  2912. // To destroy the most recently made string, we say |flush_string|.
  2913. // 45.
  2914. // tangle:pos tex.web:1208:3:
  2915. // The following subroutine compares string |s| with another string of the
  2916. // same length that appears in |buffer| starting at position |k|;
  2917. // the result is |true| if and only if the strings are equal.
  2918. // Empirical tests indicate that |str_eq_buf| is used in such a way that
  2919. // it tends to return |true| about 80 percent of the time.
  2920. func (prg *prg) strEqBuf(s strNumber, k int32) (r bool) { // loop exit
  2921. var (
  2922. j poolPointer // running index
  2923. result bool // result of comparison
  2924. )
  2925. j = prg.strStart[s]
  2926. for int32(j) < int32(prg.strStart[int32(s)+1]) {
  2927. if int32(prg.strPool[j]) != int32(prg.buffer[k]) {
  2928. result = false
  2929. goto notFound
  2930. }
  2931. j = uint16(int32(j) + 1)
  2932. k = k + 1
  2933. }
  2934. result = true
  2935. notFound:
  2936. r = result
  2937. return r
  2938. }
  2939. // 46.
  2940. // tangle:pos tex.web:1230:3:
  2941. // Here is a similar routine, but it compares two strings in the string pool,
  2942. // and it does not assume that they have the same length.
  2943. func (prg *prg) strEqStr(s, t strNumber) (r bool) { // loop exit
  2944. var (
  2945. j, k poolPointer // running indices
  2946. result bool // result of comparison
  2947. )
  2948. result = false
  2949. if int32(prg.strStart[int32(s)+1])-int32(prg.strStart[s]) != int32(prg.strStart[int32(t)+1])-int32(prg.strStart[t]) {
  2950. goto notFound
  2951. }
  2952. j = prg.strStart[s]
  2953. k = prg.strStart[t]
  2954. for int32(j) < int32(prg.strStart[int32(s)+1]) {
  2955. if int32(prg.strPool[j]) != int32(prg.strPool[k]) {
  2956. goto notFound
  2957. }
  2958. j = uint16(int32(j) + 1)
  2959. k = uint16(int32(k) + 1)
  2960. }
  2961. result = true
  2962. notFound:
  2963. r = result
  2964. return r
  2965. }
  2966. // 47.
  2967. // tangle:pos tex.web:1249:3:
  2968. // The initial values of |str_pool|, |str_start|, |pool_ptr|,
  2969. // and |str_ptr| are computed by the \.[INITEX] program, based in part
  2970. // on the information that \.[WEB] has output while processing \TeX.
  2971. // \xref[INITEX]
  2972. // \xref[string pool]
  2973. func (prg *prg) getStringsStarted() (r bool) {
  2974. var (
  2975. k, l/* 0..255 */ byte // small indices or counters
  2976. m, n char // characters input from |pool_file|
  2977. g strNumber // garbage
  2978. a int32 // accumulator for check sum
  2979. c bool // check sum has been checked
  2980. )
  2981. if int32(g) == 0 {
  2982. }
  2983. prg.poolPtr = 0
  2984. prg.strPtr = 0
  2985. prg.strStart[0] = 0
  2986. // Make the first 256 strings
  2987. for ii := int32(0); ii <= 255; ii++ {
  2988. k = byte(ii)
  2989. _ = k
  2990. if int32(k) < ' ' || int32(k) > '~' {
  2991. {
  2992. prg.strPool[prg.poolPtr] = '^'
  2993. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  2994. }
  2995. {
  2996. prg.strPool[prg.poolPtr] = '^'
  2997. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  2998. }
  2999. if int32(k) < 0100 {
  3000. prg.strPool[prg.poolPtr] = byte(int32(k) + 0100)
  3001. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  3002. } else if int32(k) < 0200 {
  3003. prg.strPool[prg.poolPtr] = byte(int32(k) - 0100)
  3004. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  3005. } else {
  3006. l = byte(int32(k) / 16)
  3007. if int32(l) < 10 {
  3008. prg.strPool[prg.poolPtr] = byte(int32(l) + '0')
  3009. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  3010. } else {
  3011. prg.strPool[prg.poolPtr] = byte(int32(l) - 10 + 'a')
  3012. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  3013. }
  3014. l = byte(int32(k) % 16)
  3015. if int32(l) < 10 {
  3016. prg.strPool[prg.poolPtr] = byte(int32(l) + '0')
  3017. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  3018. } else {
  3019. prg.strPool[prg.poolPtr] = byte(int32(l) - 10 + 'a')
  3020. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  3021. }
  3022. }
  3023. } else {
  3024. prg.strPool[prg.poolPtr] = k
  3025. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  3026. }
  3027. g = prg.makeString()
  3028. }
  3029. // Read the other strings from the \.[TEX.POOL] file and return |true|, or give an error message and return |false|
  3030. strcopy(prg.nameOfFile[:], "TeXformats:TEX.POOL ") // we needn't set |name_length|
  3031. if prg.aOpenIn(prg.poolFile) {
  3032. c = false
  3033. for {
  3034. // Read one string, but return |false| if the string memory space is getting too tight for comfort
  3035. {
  3036. if prg.poolFile.EOF() {
  3037. prg.termOut.Writeln("! TEX.POOL has no check sum.")
  3038. prg.aClose(prg.poolFile)
  3039. r = false
  3040. goto exit
  3041. }
  3042. // \xref[TEX.POOL has no check sum]
  3043. prg.poolFile.Read(&m, &n) // read two digits of string length
  3044. if int32(m) == '*' {
  3045. a = 0
  3046. k = 1
  3047. for true {
  3048. if int32(prg.xord[n]) < '0' || int32(prg.xord[n]) > '9' {
  3049. prg.termOut.Writeln("! TEX.POOL check sum doesn't have nine digits.")
  3050. prg.aClose(prg.poolFile)
  3051. r = false
  3052. goto exit
  3053. }
  3054. // \xref[TEX.POOL check sum...]
  3055. a = 10*a + int32(prg.xord[n]) - '0'
  3056. if int32(k) == 9 {
  3057. goto done
  3058. }
  3059. k = byte(int32(k) + 1)
  3060. prg.poolFile.Read(&n)
  3061. }
  3062. done:
  3063. if a != 504454778 {
  3064. prg.termOut.Writeln("! TEX.POOL doesn't match; TANGLE me again.")
  3065. prg.aClose(prg.poolFile)
  3066. r = false
  3067. goto exit
  3068. }
  3069. // \xref[TEX.POOL doesn't match]
  3070. c = true
  3071. } else {
  3072. if int32(prg.xord[m]) < '0' || int32(prg.xord[m]) > '9' || int32(prg.xord[n]) < '0' || int32(prg.xord[n]) > '9' {
  3073. prg.termOut.Writeln("! TEX.POOL line doesn't begin with two digits.")
  3074. prg.aClose(prg.poolFile)
  3075. r = false
  3076. goto exit
  3077. }
  3078. // \xref[TEX.POOL line doesn't...]
  3079. l = byte(int32(prg.xord[m])*10 + int32(prg.xord[n]) - '0'*11) // compute the length
  3080. if int32(prg.poolPtr)+int32(l)+stringVacancies > poolSize {
  3081. prg.termOut.Writeln("! You have to increase POOLSIZE.")
  3082. prg.aClose(prg.poolFile)
  3083. r = false
  3084. goto exit
  3085. }
  3086. // \xref[You have to increase POOLSIZE]
  3087. for ii := int32(1); ii <= int32(l); ii++ {
  3088. k = byte(ii)
  3089. _ = k
  3090. if prg.poolFile.EOLN() {
  3091. m = ' '
  3092. } else {
  3093. prg.poolFile.Read(&m)
  3094. }
  3095. {
  3096. prg.strPool[prg.poolPtr] = prg.xord[m]
  3097. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  3098. }
  3099. }
  3100. prg.poolFile.Readln()
  3101. g = prg.makeString()
  3102. }
  3103. }
  3104. if c {
  3105. break
  3106. }
  3107. }
  3108. prg.aClose(prg.poolFile)
  3109. r = true
  3110. } else {
  3111. prg.termOut.Writeln("! I can't read TEX.POOL.")
  3112. prg.aClose(prg.poolFile)
  3113. r = false
  3114. goto exit
  3115. }
  3116. exit:
  3117. ;
  3118. return r
  3119. }
  3120. // 56.
  3121. // tangle:pos tex.web:1448:3:
  3122. // Macro abbreviations for output to the terminal and to the log file are
  3123. // defined here for convenience. Some systems need special conventions
  3124. // for terminal output, and it is possible to adhere to those conventions
  3125. // by changing |wterm|, |wterm_ln|, and |wterm_cr| in this section.
  3126. // \xref[system dependencies]
  3127. // 66.
  3128. // tangle:pos tex.web:1638:3:
  3129. // Here is a trivial procedure to print two digits; it is usually called with
  3130. // a parameter in the range |0<=n<=99|.
  3131. func (prg *prg) printTwo(n int32) {
  3132. n = abs(n) % 100
  3133. prg.printChar(asciiCode('0' + n/10))
  3134. prg.printChar(asciiCode('0' + n%10))
  3135. }
  3136. // 67.
  3137. // tangle:pos tex.web:1646:3:
  3138. // Hexadecimal printing of nonnegative integers is accomplished by |print_hex|.
  3139. func (prg *prg) printHex(n int32) {
  3140. // prints a positive integer in hexadecimal form
  3141. var (
  3142. k /* 0..22 */ byte // index to current digit; we assume that $0\L n<16^[22]$
  3143. )
  3144. k = 0
  3145. prg.printChar(asciiCode('"'))
  3146. for {
  3147. prg.dig[k] = byte(n % 16)
  3148. n = n / 16
  3149. k = byte(int32(k) + 1)
  3150. if n == 0 {
  3151. break
  3152. }
  3153. }
  3154. prg.printTheDigs(k)
  3155. }
  3156. // 68.
  3157. // tangle:pos tex.web:1657:3:
  3158. // Old versions of \TeX\ needed a procedure called |print_ASCII| whose function
  3159. // is now subsumed by |print|. We retain the old name here as a possible aid to
  3160. // future software arch\ae ologists.
  3161. // 69.
  3162. // tangle:pos tex.web:1663:3:
  3163. // Roman numerals are produced by the |print_roman_int| routine. Readers
  3164. // who like puzzles might enjoy trying to figure out how this tricky code
  3165. // works; therefore no explanation will be given. Notice that 1990 yields
  3166. // \.[mcmxc], not \.[mxm].
  3167. func (prg *prg) printRomanInt(n int32) {
  3168. var (
  3169. j, k poolPointer // mysterious indices into |str_pool|
  3170. u, v nonnegativeInteger // mysterious numbers
  3171. )
  3172. j = prg.strStart[ /* "m2d5c2l5x2v5i" */ 260]
  3173. v = 1000
  3174. for true {
  3175. for n >= int32(v) {
  3176. prg.printChar(prg.strPool[j])
  3177. n = n - int32(v)
  3178. }
  3179. if n <= 0 {
  3180. goto exit
  3181. } // nonpositive input produces no output
  3182. k = uint16(int32(j) + 2)
  3183. u = uint32(int32(v) / (int32(prg.strPool[int32(k)-1]) - '0'))
  3184. if int32(prg.strPool[int32(k)-1]) == '2' {
  3185. k = uint16(int32(k) + 2)
  3186. u = uint32(int32(u) / (int32(prg.strPool[int32(k)-1]) - '0'))
  3187. }
  3188. if n+int32(u) >= int32(v) {
  3189. prg.printChar(prg.strPool[k])
  3190. n = n + int32(u)
  3191. } else {
  3192. j = uint16(int32(j) + 2)
  3193. v = uint32(int32(v) / (int32(prg.strPool[int32(j)-1]) - '0'))
  3194. }
  3195. }
  3196. exit:
  3197. }
  3198. // 70.
  3199. // tangle:pos tex.web:1689:3:
  3200. // The |print| subroutine will not print a string that is still being
  3201. // created. The following procedure will.
  3202. func (prg *prg) printCurrentString() { // prints a yet-unmade string
  3203. var (
  3204. j poolPointer // points to current character code
  3205. )
  3206. j = prg.strStart[prg.strPtr]
  3207. for int32(j) < int32(prg.poolPtr) {
  3208. prg.printChar(prg.strPool[j])
  3209. j = uint16(int32(j) + 1)
  3210. }
  3211. } // \2
  3212. func (prg *prg) termInput() { // gets a line from the terminal
  3213. var (
  3214. k /* 0..bufSize */ uint16 // index into |buffer|
  3215. ) // now the user sees the prompt for sure
  3216. if !prg.inputLn(prg.termIn, true) {
  3217. prg.fatalError(strNumber( /* "End of file on the terminal!" */ 261))
  3218. }
  3219. // \xref[End of file on the terminal]
  3220. prg.termOffset = 0 // the user's line ended with \<\rm return>
  3221. prg.selector = byte(int32(prg.selector) - 1) // prepare to echo the input
  3222. if int32(prg.last) != int32(prg.first) {
  3223. for ii := int32(prg.first); ii <= int32(prg.last)-1; ii++ {
  3224. k = uint16(ii)
  3225. _ = k
  3226. prg.print(int32(prg.buffer[k]))
  3227. }
  3228. }
  3229. prg.printLn()
  3230. prg.selector = byte(int32(prg.selector) + 1) // restore previous status
  3231. }
  3232. // 72. \[6] Reporting errors
  3233. // tangle:pos tex.web:1721:26:
  3234. // When something anomalous is detected, \TeX\ typically does something like this:
  3235. // $$\vbox[\halign[#\hfil\cr
  3236. // |print_err("Something anomalous has been detected");|\cr
  3237. // |help3("This is the first line of my offer to help.")|\cr
  3238. // |("This is the second line. I'm trying to")|\cr
  3239. // |("explain the best way for you to proceed.");|\cr
  3240. // |error;|\cr]]$$
  3241. // A two-line help message would be given using |help2|, etc.; these informal
  3242. // helps should use simple vocabulary that complements the words used in the
  3243. // official error message that was printed. (Outside the U.S.A., the help
  3244. // messages should preferably be translated into the local vernacular. Each
  3245. // line of help is at most 60 characters long, in the present implementation,
  3246. // so that |max_print_line| will not be exceeded.)
  3247. //
  3248. // The |print_err| procedure supplies a `\.!' before the official message,
  3249. // and makes sure that the terminal is awake if a stop is going to occur.
  3250. // The |error| procedure supplies a `\..' after the official message, then it
  3251. // shows the location of the error; and if |interaction=error_stop_mode|,
  3252. // it also enters into a dialog with the user, during which time the help
  3253. // message may be printed.
  3254. // \xref[system dependencies]
  3255. // 91.
  3256. // tangle:pos tex.web:2034:3:
  3257. // A dozen or so error messages end with a parenthesized integer, so we
  3258. // save a teeny bit of program space by declaring the following procedure:
  3259. func (prg *prg) intError(n int32) {
  3260. prg.print( /* " (" */ 286)
  3261. prg.printInt(n)
  3262. prg.printChar(asciiCode(')'))
  3263. prg.error1()
  3264. }
  3265. // \4
  3266. // Error handling procedures
  3267. func (prg *prg) normalizeSelector() {
  3268. if prg.logOpened {
  3269. prg.selector = byte(termAndLog)
  3270. } else {
  3271. prg.selector = byte(termOnly)
  3272. }
  3273. if int32(prg.jobName) == 0 {
  3274. prg.openLogFile()
  3275. }
  3276. if int32(prg.interaction) == batchMode {
  3277. prg.selector = byte(int32(prg.selector) - 1)
  3278. }
  3279. }
  3280. // 98.
  3281. // tangle:pos tex.web:2124:3:
  3282. // When an interrupt has been detected, the program goes into its
  3283. // highest interaction level and lets the user have nearly the full flexibility of
  3284. // the |error| routine. \TeX\ checks for interrupts only at times when it is
  3285. // safe to do this.
  3286. func (prg *prg) pauseForInstructions() {
  3287. if prg.okToInterrupt {
  3288. prg.interaction = byte(errorStopMode)
  3289. if int32(prg.selector) == logOnly || int32(prg.selector) == noPrint {
  3290. prg.selector = byte(int32(prg.selector) + 1)
  3291. }
  3292. {
  3293. if int32(prg.interaction) == errorStopMode {
  3294. }
  3295. prg.printNl(strNumber( /* "! " */ 262))
  3296. prg.print( /* "Interruption" */ 296)
  3297. }
  3298. // \xref[Interruption]
  3299. {
  3300. prg.helpPtr = 3
  3301. prg.helpLine[2] = /* "You rang?" */ 297
  3302. prg.helpLine[1] = /* "Try to insert an instruction for me (e.g., `I\\showlists')," */ 298
  3303. prg.helpLine[0] = /* "unless you just want to quit by typing `X'." */ 299
  3304. }
  3305. prg.deletionsAllowed = false
  3306. prg.error1()
  3307. prg.deletionsAllowed = true
  3308. prg.interrupt = 0
  3309. }
  3310. }
  3311. // 99. \[7] Arithmetic with scaled dimensions
  3312. // tangle:pos tex.web:2144:43:
  3313. // The principal computations performed by \TeX\ are done entirely in terms of
  3314. // integers less than $2^[31]$ in magnitude; and divisions are done only when both
  3315. // dividend and divisor are nonnegative. Thus, the arithmetic specified in this
  3316. // program can be carried out in exactly the same way on a wide variety of
  3317. // computers, including some small ones. Why? Because the arithmetic
  3318. // calculations need to be spelled out precisely in order to guarantee that
  3319. // \TeX\ will produce identical output on different machines. If some
  3320. // quantities were rounded differently in different implementations, we would
  3321. // find that line breaks and even page breaks might occur in different places.
  3322. // Hence the arithmetic of \TeX\ has been designed with care, and systems that
  3323. // claim to be implementations of \TeX82 should follow precisely the
  3324. // \xref[TeX82][\TeX82]
  3325. // calculations as they appear in the present program.
  3326. //
  3327. // (Actually there are three places where \TeX\ uses |div| with a possibly negative
  3328. // numerator. These are harmless; see |div| in the index. Also if the user
  3329. // sets the \.[\\time] or the \.[\\year] to a negative value, some diagnostic
  3330. // information will involve negative-numerator division. The same remarks
  3331. // apply for |mod| as well as for |div|.)
  3332. // 100.
  3333. // tangle:pos tex.web:2165:3:
  3334. // Here is a routine that calculates half of an integer, using an
  3335. // unambiguous convention with respect to signed odd numbers.
  3336. func (prg *prg) half(x int32) (r int32) {
  3337. if x&1 != 0 {
  3338. r = (x + 1) / 2
  3339. } else {
  3340. r = x / 2
  3341. }
  3342. return r
  3343. }
  3344. // 102.
  3345. // tangle:pos tex.web:2185:3:
  3346. // The following function is used to create a scaled integer from a given decimal
  3347. // fraction $(.d_0d_1\ldots d_[k-1])$, where |0<=k<=17|. The digit $d_i$ is
  3348. // given in |dig[i]|, and the calculation produces a correctly rounded result.
  3349. func (prg *prg) roundDecimals(k smallNumber) (r scaled) {
  3350. // converts a decimal fraction
  3351. var (
  3352. a int32 // the accumulator
  3353. )
  3354. a = 0
  3355. for int32(k) > 0 {
  3356. k = byte(int32(k) - 1)
  3357. a = (a + int32(prg.dig[k])*0400000) / 10
  3358. }
  3359. r = (a + 1) / 2
  3360. return r
  3361. }
  3362. // 103.
  3363. // tangle:pos tex.web:2199:3:
  3364. // Conversely, here is a procedure analogous to |print_int|. If the output
  3365. // of this procedure is subsequently read by \TeX\ and converted by the
  3366. // |round_decimals| routine above, it turns out that the original value will
  3367. // be reproduced exactly; the “simplest” such decimal number is output,
  3368. // but there is always at least one digit following the decimal point.
  3369. //
  3370. // The invariant relation in the \&[repeat] loop is that a sequence of
  3371. // decimal digits yet to be printed will yield the original number if and only if
  3372. // they form a fraction~$f$ in the range $s-\delta\L10\cdot2^[16]f<s$.
  3373. // We can stop if and only if $f=0$ satisfies this condition; the loop will
  3374. // terminate before $s$ can possibly become zero.
  3375. func (prg *prg) printScaled(s scaled) { // prints scaled real, rounded to five
  3376. // digits
  3377. var (
  3378. delta scaled // amount of allowable inaccuracy
  3379. )
  3380. if s < 0 {
  3381. prg.printChar(asciiCode('-'))
  3382. s = -s // print the sign, if negative
  3383. }
  3384. prg.printInt(s / 0200000) // print the integer part
  3385. prg.printChar(asciiCode('.'))
  3386. s = 10*(s%0200000) + 5
  3387. delta = 10
  3388. for {
  3389. if delta > 0200000 {
  3390. s = s + 0100000 - 50000
  3391. } // round the last digit
  3392. prg.printChar(asciiCode('0' + s/0200000))
  3393. s = 10 * (s % 0200000)
  3394. delta = delta * 10
  3395. if s <= delta {
  3396. break
  3397. }
  3398. }
  3399. }
  3400. // 105.
  3401. // tangle:pos tex.web:2254:3:
  3402. // The first arithmetical subroutine we need computes $nx+y$, where |x|
  3403. // and~|y| are |scaled| and |n| is an integer. We will also use it to
  3404. // multiply integers.
  3405. func (prg *prg) multAndAdd(n int32, x, y, maxAnswer scaled) (r scaled) {
  3406. if n < 0 {
  3407. x = -x
  3408. n = -n
  3409. }
  3410. if n == 0 {
  3411. r = y
  3412. } else if x <= (maxAnswer-y)/n && -x <= (maxAnswer+y)/n {
  3413. r = n*x + y
  3414. } else {
  3415. prg.arithError = true
  3416. r = 0
  3417. }
  3418. return r
  3419. }
  3420. // 106.
  3421. // tangle:pos tex.web:2272:3:
  3422. // We also need to divide scaled dimensions by integers.
  3423. func (prg *prg) xOverN(x scaled, n int32) (r scaled) {
  3424. var (
  3425. negative bool // should |remainder| be negated?
  3426. )
  3427. negative = false
  3428. if n == 0 {
  3429. prg.arithError = true
  3430. r = 0
  3431. prg.remainder = x
  3432. } else {
  3433. if n < 0 {
  3434. x = -x
  3435. n = -n
  3436. negative = true
  3437. }
  3438. if x >= 0 {
  3439. r = x / n
  3440. prg.remainder = x % n
  3441. } else {
  3442. r = -(-x / n)
  3443. prg.remainder = -(-x % n)
  3444. }
  3445. }
  3446. if negative {
  3447. prg.remainder = -prg.remainder
  3448. }
  3449. return r
  3450. }
  3451. // 107.
  3452. // tangle:pos tex.web:2292:3:
  3453. // Then comes the multiplication of a scaled number by a fraction |n/d|,
  3454. // where |n| and |d| are nonnegative integers |<=$2^[16]$| and |d| is
  3455. // positive. It would be too dangerous to multiply by~|n| and then divide
  3456. // by~|d|, in separate operations, since overflow might well occur; and it
  3457. // would be too inaccurate to divide by |d| and then multiply by |n|. Hence
  3458. // this subroutine simulates 1.5-precision arithmetic.
  3459. func (prg *prg) xnOverD(x scaled, n, d int32) (r scaled) {
  3460. var (
  3461. positive bool // was |x>=0|?
  3462. t, u, v nonnegativeInteger // intermediate quantities
  3463. )
  3464. if x >= 0 {
  3465. positive = true
  3466. } else {
  3467. x = -x
  3468. positive = false
  3469. }
  3470. t = uint32(x % 0100000 * n)
  3471. u = uint32(x/0100000*n + int32(t)/0100000)
  3472. v = uint32(int32(u)%d*0100000 + int32(t)%0100000)
  3473. if int32(u)/d >= 0100000 {
  3474. prg.arithError = true
  3475. } else {
  3476. u = uint32(0100000*(int32(u)/d) + int32(v)/d)
  3477. }
  3478. if positive {
  3479. r = int32(u)
  3480. prg.remainder = int32(v) % d
  3481. } else {
  3482. r = -int32(u)
  3483. prg.remainder = -(int32(v) % d)
  3484. }
  3485. return r
  3486. }
  3487. // 108.
  3488. // tangle:pos tex.web:2317:3:
  3489. // The next subroutine is used to compute the “badness” of glue, when a
  3490. // total~|t| is supposed to be made from amounts that sum to~|s|. According
  3491. // to [\sl The \TeX book], the badness of this situation is $100(t/s)^3$;
  3492. // however, badness is simply a heuristic, so we need not squeeze out the
  3493. // last drop of accuracy when computing it. All we really want is an
  3494. // approximation that has similar properties.
  3495. // \xref[TeXbook][\sl The \TeX book]
  3496. //
  3497. // The actual method used to compute the badness is easier to read from the
  3498. // program than to describe in words. It produces an integer value that is a
  3499. // reasonably close approximation to $100(t/s)^3$, and all implementations
  3500. // of \TeX\ should use precisely this method. Any badness of $2^[13]$ or more is
  3501. // treated as infinitely bad, and represented by 10000.
  3502. //
  3503. // It is not difficult to prove that $$\hbox[|badness(t+1,s)>=badness(t,s)
  3504. // >=badness(t,s+1)|].$$ The badness function defined here is capable of
  3505. // computing at most 1095 distinct values, but that is plenty.
  3506. func (prg *prg) badness(t, s scaled) (r halfword) { // compute badness, given |t>=0|
  3507. var (
  3508. r1 int32 // approximation to $\alpha t/s$, where $\alpha^3\approx
  3509. // 100\cdot2^[18]$
  3510. )
  3511. if t == 0 {
  3512. r = 0
  3513. } else if s <= 0 {
  3514. r = uint16(infBad)
  3515. } else {
  3516. if t <= 7230584 {
  3517. r1 = t * 297 / s
  3518. } else if s >= 1663497 {
  3519. r1 = t / (s / 297)
  3520. } else {
  3521. r1 = t
  3522. }
  3523. if r1 > 1290 {
  3524. r = uint16(infBad)
  3525. } else {
  3526. r = uint16((r1*r1*r1 + 0400000) / 01000000)
  3527. }
  3528. } // that was $r^3/2^[18]$, rounded to the nearest integer
  3529. return r
  3530. }
  3531. // 110. \[8] Packed data
  3532. // tangle:pos tex.web:2375:21:
  3533. // In order to make efficient use of storage space, \TeX\ bases its major data
  3534. // structures on a |memory_word|, which contains either a (signed) integer,
  3535. // possibly scaled, or a (signed) |glue_ratio|, or a small number of
  3536. // fields that are one half or one quarter of the size used for storing
  3537. // integers.
  3538. //
  3539. // If |x| is a variable of type |memory_word|, it contains up to four
  3540. // fields that can be referred to as follows:
  3541. // $$\vbox[\halign[\hfil#&#\hfil&#\hfil\cr
  3542. // |x|&.|int|&(an |integer|)\cr
  3543. // |x|&.|sc|\qquad&(a |scaled| integer)\cr
  3544. // |x|&.|gr|&(a |glue_ratio|)\cr
  3545. // |x.hh.lh|, |x.hh|&.|rh|&(two halfword fields)\cr
  3546. // |x.hh.b0|, |x.hh.b1|, |x.hh|&.|rh|&(two quarterword fields, one halfword
  3547. // field)\cr
  3548. // |x.qqqq.b0|, |x.qqqq.b1|, |x.qqqq|&.|b2|, |x.qqqq.b3|\hskip-100pt
  3549. // &\qquad\qquad\qquad(four quarterword fields)\cr]]$$
  3550. // This is somewhat cumbersome to write, and not very readable either, but
  3551. // macros will be used to make the notation shorter and more transparent.
  3552. // The \PASCAL\ code below gives a formal definition of |memory_word| and
  3553. // its subsidiary types, using packed variant records. \TeX\ makes no
  3554. // assumptions about the relative positions of the fields within a word.
  3555. //
  3556. // Since we are assuming 32-bit integers, a halfword must contain at least
  3557. // 16 bits, and a quarterword must contain at least 8 bits.
  3558. // \xref[system dependencies]
  3559. // But it doesn't hurt to have more bits; for example, with enough 36-bit
  3560. // words you might be able to have |mem_max| as large as 262142, which is
  3561. // eight times as much memory as anybody had during the first four years of
  3562. // \TeX's existence.
  3563. //
  3564. // N.B.: Valuable memory space will be dreadfully wasted unless \TeX\ is compiled
  3565. // by a \PASCAL\ that packs all of the |memory_word| variants into
  3566. // the space of a single integer. This means, for example, that |glue_ratio|
  3567. // words should be |short_real| instead of |real| on some computers. Some
  3568. // \PASCAL\ compilers will pack an integer whose subrange is `|0..255|' into
  3569. // an eight-bit field, but others insist on allocating space for an additional
  3570. // sign bit; on such systems you can get 256 values into a quarterword only
  3571. // if the subrange is `|-128..127|'.
  3572. //
  3573. // The present implementation tries to accommodate as many variations as possible,
  3574. // so it makes few assumptions. If integers having the subrange
  3575. // `|min_quarterword..max_quarterword|' can be packed into a quarterword,
  3576. // and if integers having the subrange `|min_halfword..max_halfword|'
  3577. // can be packed into a halfword, everything should work satisfactorily.
  3578. //
  3579. // It is usually most efficient to have |min_quarterword=min_halfword=0|,
  3580. // so one should try to achieve this unless it causes a severe problem.
  3581. // The values defined here are recommended for most 32-bit computers.
  3582. // 112.
  3583. // tangle:pos tex.web:2449:3:
  3584. // The operation of adding or subtracting |min_quarterword| occurs quite
  3585. // frequently in \TeX, so it is convenient to abbreviate this operation
  3586. // by using the macros |qi| and |qo| for input and output to and from
  3587. // quarterword format.
  3588. //
  3589. // The inner loop of \TeX\ will run faster with respect to compilers
  3590. // that don't optimize expressions like `|x+0|' and `|x-0|', if these
  3591. // macros are simplified in the obvious way when |min_quarterword=0|.
  3592. // \xref[inner loop]\xref[system dependencies]
  3593. // 114.
  3594. // tangle:pos tex.web:2499:3:
  3595. // When debugging, we may want to print a |memory_word| without knowing
  3596. // what type it is; so we print it in all modes.
  3597. // \xref[dirty \PASCAL]\xref[debugging]
  3598. // procedure print_word( w:memory_word);
  3599. // [prints |w| in all ways]
  3600. // begin print_int(w.int); print_char([" "=]32);
  3601. //
  3602. // print_scaled(w.int ); print_char([" "=]32);
  3603. //
  3604. // print_scaled(round( [0200000=]65536 * w. gr )); print_ln;
  3605. //
  3606. // [ \xref[real multiplication] ]
  3607. // print_int(w.hh.lh); print_char(["="=]61); print_int(w.hh.b0); print_char([":"=]58);
  3608. // print_int(w.hh.b1); print_char([";"=]59); print_int(w.hh.rh); print_char([" "=]32);
  3609. //
  3610. // print_int(w.qqqq.b0); print_char([":"=]58); print_int(w.qqqq.b1); print_char([":"=]58);
  3611. // print_int(w.qqqq.b2); print_char([":"=]58); print_int(w.qqqq.b3);
  3612. // end;
  3613. // [ ]
  3614. // 119.
  3615. // tangle:pos tex.web:2596:3:
  3616. // If memory is exhausted, it might mean that the user has forgotten
  3617. // a right brace. We will define some procedures later that try to help
  3618. // pinpoint the trouble.
  3619. // Declare the procedure called |show_token_list|
  3620. func (prg *prg) showTokenList(p, q int32, l int32) {
  3621. var (
  3622. m, c int32 // pieces of a token
  3623. matchChr asciiCode // character used in a `|match|'
  3624. n asciiCode // the highest parameter number, as an ASCII digit
  3625. )
  3626. matchChr = '#'
  3627. n = '0'
  3628. prg.tally = 0
  3629. for p != 0 && prg.tally < l {
  3630. if p == q {
  3631. prg.firstCount = prg.tally
  3632. prg.trickCount = prg.tally + 1 + errorLine - halfErrorLine
  3633. if prg.trickCount < errorLine {
  3634. prg.trickCount = errorLine
  3635. }
  3636. }
  3637. // Display token |p|, and |return| if there are problems
  3638. if p < int32(prg.hiMemMin) || p > int32(prg.memEnd) {
  3639. prg.printEsc(strNumber( /* "CLOBBERED." */ 309))
  3640. goto exit
  3641. // \xref[CLOBBERED]
  3642. }
  3643. if int32(*(*prg.mem[p].hh()).lh()) >= 07777 {
  3644. prg.printCs(int32(*(*prg.mem[p].hh()).lh()) - 07777)
  3645. } else {
  3646. m = int32(*(*prg.mem[p].hh()).lh()) / 0400
  3647. c = int32(*(*prg.mem[p].hh()).lh()) % 0400
  3648. if int32(*(*prg.mem[p].hh()).lh()) < 0 {
  3649. prg.printEsc(strNumber( /* "BAD." */ 555))
  3650. } else {
  3651. // Display the token $(|m|,|c|)$
  3652. switch m {
  3653. case leftBrace, rightBrace, mathShift, tabMark,
  3654. supMark, subMark, spacer, letter,
  3655. otherChar:
  3656. prg.print(c)
  3657. case macParam:
  3658. prg.print(c)
  3659. prg.print(c)
  3660. case outParam:
  3661. prg.print(int32(matchChr))
  3662. if c <= 9 {
  3663. prg.printChar(asciiCode(c + '0'))
  3664. } else {
  3665. prg.printChar(asciiCode('!'))
  3666. goto exit
  3667. }
  3668. case match:
  3669. matchChr = byte(c)
  3670. prg.print(c)
  3671. n = byte(int32(n) + 1)
  3672. prg.printChar(n)
  3673. if int32(n) > '9' {
  3674. goto exit
  3675. }
  3676. case endMatch:
  3677. prg.print( /* "->" */ 556)
  3678. // \xref[->]
  3679. default:
  3680. prg.printEsc(strNumber( /* "BAD." */ 555))
  3681. // \xref[BAD]
  3682. }
  3683. }
  3684. }
  3685. p = int32(*(*prg.mem[p].hh()).rh())
  3686. }
  3687. if p != 0 {
  3688. prg.printEsc(strNumber( /* "ETC." */ 554))
  3689. }
  3690. // \xref[ETC]
  3691. // \xref[ETC]
  3692. exit:
  3693. }
  3694. // Declare the procedure called |runaway|
  3695. func (prg *prg) runaway() {
  3696. var (
  3697. p halfword // head of runaway list
  3698. )
  3699. if int32(prg.scannerStatus) > skipping {
  3700. prg.printNl(strNumber( /* "Runaway " */ 569))
  3701. // \xref[Runaway...]
  3702. switch prg.scannerStatus {
  3703. case defining:
  3704. prg.print( /* "definition" */ 570)
  3705. p = prg.defRef
  3706. case matching:
  3707. prg.print( /* "argument" */ 571)
  3708. p = uint16(30000 - 3)
  3709. case aligning:
  3710. prg.print( /* "preamble" */ 572)
  3711. p = uint16(30000 - 4)
  3712. case absorbing:
  3713. prg.print( /* "text" */ 573)
  3714. p = prg.defRef
  3715. } // there are no other cases
  3716. prg.printChar(asciiCode('?'))
  3717. prg.printLn()
  3718. prg.showTokenList(int32(*(*prg.mem[p].hh()).rh()), 0, errorLine-10)
  3719. }
  3720. }
  3721. // 120.
  3722. // tangle:pos tex.web:2603:3:
  3723. // The function |get_avail| returns a pointer to a new one-word node whose
  3724. // |link| field is null. However, \TeX\ will halt if there is no more room left.
  3725. // \xref[inner loop]
  3726. //
  3727. // If the available-space list is empty, i.e., if |avail=null|,
  3728. // we try first to increase |mem_end|. If that cannot be done, i.e., if
  3729. // |mem_end=mem_max|, we try to decrease |hi_mem_min|. If that cannot be
  3730. // done, i.e., if |hi_mem_min=lo_mem_max+1|, we have to quit.
  3731. func (prg *prg) getAvail() (r halfword) { // single-word node allocation
  3732. var (
  3733. p halfword // the new node being got
  3734. )
  3735. p = prg.avail // get top location in the |avail| stack
  3736. if int32(p) != 0 {
  3737. prg.avail = *(*prg.mem[prg.avail].hh()).rh()
  3738. } else if int32(prg.memEnd) < memMax {
  3739. prg.memEnd = uint16(int32(prg.memEnd) + 1)
  3740. p = prg.memEnd
  3741. } else {
  3742. prg.hiMemMin = uint16(int32(prg.hiMemMin) - 1)
  3743. p = prg.hiMemMin
  3744. if int32(prg.hiMemMin) <= int32(prg.loMemMax) {
  3745. prg.runaway() // if memory is exhausted, display possible runaway text
  3746. prg.overflow(strNumber( /* "main memory size" */ 300), memMax+1-memMin)
  3747. // quit; all one-word nodes are busy
  3748. // \xref[TeX capacity exceeded main memory size][\quad main memory size]
  3749. }
  3750. }
  3751. *(*prg.mem[p].hh()).rh() = 0 // provide an oft-desired initialization of the new node
  3752. // dyn_used:= dyn_used+1 ; [ ]
  3753. //
  3754. // maintain statistics
  3755. r = p
  3756. return r
  3757. }
  3758. // 121.
  3759. // tangle:pos tex.web:2632:3:
  3760. // Conversely, a one-word node is recycled by calling |free_avail|.
  3761. // This routine is part of \TeX's ``inner loop,'' so we want it to be fast.
  3762. // \xref[inner loop]
  3763. // 122.
  3764. // tangle:pos tex.web:2641:3:
  3765. // There's also a |fast_get_avail| routine, which saves the procedure-call
  3766. // overhead at the expense of extra programming. This routine is used in
  3767. // the places that would otherwise account for the most calls of |get_avail|.
  3768. // \xref[inner loop]
  3769. // 123.
  3770. // tangle:pos tex.web:2654:3:
  3771. // The procedure |flush_list(p)| frees an entire linked list of
  3772. // one-word nodes that starts at position |p|.
  3773. // \xref[inner loop]
  3774. func (prg *prg) flushList(p halfword) { // makes list of single-word nodes
  3775. // available
  3776. var (
  3777. q, r1 halfword // list traversers
  3778. )
  3779. if int32(p) != 0 {
  3780. r1 = p
  3781. for {
  3782. q = r1
  3783. r1 = *(*prg.mem[r1].hh()).rh() // dyn_used:= dyn_used-1 ; [ ]
  3784. if int32(r1) == 0 {
  3785. break
  3786. }
  3787. } // now |q| is the last node on the list
  3788. *(*prg.mem[q].hh()).rh() = prg.avail
  3789. prg.avail = p
  3790. }
  3791. }
  3792. // 125.
  3793. // tangle:pos tex.web:2694:3:
  3794. // A call to |get_node| with argument |s| returns a pointer to a new node
  3795. // of size~|s|, which must be 2~or more. The |link| field of the first word
  3796. // of this new node is set to null. An overflow stop occurs if no suitable
  3797. // space exists.
  3798. //
  3799. // If |get_node| is called with $s=2^[30]$, it simply merges adjacent free
  3800. // areas and returns the value |max_halfword|.
  3801. func (prg *prg) getNode(s int32) (r halfword) {
  3802. var (
  3803. p halfword // the node currently under inspection
  3804. q halfword // the node physically after node |p|
  3805. r1 int32 // the newly allocated node, or a candidate for this honor
  3806. t int32 // temporary register
  3807. )
  3808. restart:
  3809. p = prg.rover // start at some free node in the ring
  3810. for {
  3811. // Try to allocate within node |p| and its physical successors, and |goto found| if allocation was possible
  3812. q = uint16(int32(p) + int32(*(*prg.mem[p].hh()).lh())) // find the physical successor
  3813. // \xref[inner loop]
  3814. for int32(*(*prg.mem[q].hh()).rh()) == 65535 { // merge node |p| with node |q|
  3815. t = int32(*(*prg.mem[int32(q)+1].hh()).rh())
  3816. if int32(q) == int32(prg.rover) {
  3817. prg.rover = uint16(t)
  3818. }
  3819. *(*prg.mem[t+1].hh()).lh() = *(*prg.mem[int32(q)+1].hh()).lh()
  3820. *(*prg.mem[int32(*(*prg.mem[int32(q)+1].hh()).lh())+1].hh()).rh() = uint16(t)
  3821. q = uint16(int32(q) + int32(*(*prg.mem[q].hh()).lh()))
  3822. }
  3823. r1 = int32(q) - s
  3824. if r1 > int32(p)+1 {
  3825. *(*prg.mem[p].hh()).lh() = uint16(r1 - int32(p)) // store the remaining size
  3826. // \xref[inner loop]
  3827. prg.rover = p // start searching here next time
  3828. // start searching here next time
  3829. goto found
  3830. }
  3831. if r1 == int32(p) {
  3832. if int32(*(*prg.mem[int32(p)+1].hh()).rh()) != int32(p) {
  3833. prg.rover = *(*prg.mem[int32(p)+1].hh()).rh()
  3834. t = int32(*(*prg.mem[int32(p)+1].hh()).lh())
  3835. *(*prg.mem[int32(prg.rover)+1].hh()).lh() = uint16(t)
  3836. *(*prg.mem[t+1].hh()).rh() = prg.rover
  3837. goto found
  3838. }
  3839. }
  3840. *(*prg.mem[p].hh()).lh() = uint16(int32(q) - int32(p))
  3841. // \xref[inner loop]
  3842. p = *(*prg.mem[int32(p)+1].hh()).rh() // move to the next node in the ring
  3843. if int32(p) == int32(prg.rover) {
  3844. break
  3845. }
  3846. } // repeat until the whole list has been traversed
  3847. if s == 010000000000 {
  3848. r = 65535
  3849. goto exit
  3850. }
  3851. if int32(prg.loMemMax)+2 < int32(prg.hiMemMin) {
  3852. if int32(prg.loMemMax)+2 <= memBot+65535 {
  3853. if int32(prg.hiMemMin)-int32(prg.loMemMax) >= 1998 {
  3854. t = int32(prg.loMemMax) + 1000
  3855. } else {
  3856. t = int32(prg.loMemMax) + 1 + (int32(prg.hiMemMin)-int32(prg.loMemMax))/2
  3857. }
  3858. // |lo_mem_max+2<=t<hi_mem_min|
  3859. p = *(*prg.mem[int32(prg.rover)+1].hh()).lh()
  3860. q = prg.loMemMax
  3861. *(*prg.mem[int32(p)+1].hh()).rh() = q
  3862. *(*prg.mem[int32(prg.rover)+1].hh()).lh() = q
  3863. if t > memBot+65535 {
  3864. t = memBot + 65535
  3865. }
  3866. *(*prg.mem[int32(q)+1].hh()).rh() = prg.rover
  3867. *(*prg.mem[int32(q)+1].hh()).lh() = p
  3868. *(*prg.mem[q].hh()).rh() = 65535
  3869. *(*prg.mem[q].hh()).lh() = uint16(t - int32(prg.loMemMax))
  3870. prg.loMemMax = uint16(t)
  3871. *(*prg.mem[prg.loMemMax].hh()).rh() = 0
  3872. *(*prg.mem[prg.loMemMax].hh()).lh() = 0
  3873. prg.rover = q
  3874. goto restart
  3875. }
  3876. }
  3877. prg.overflow(strNumber( /* "main memory size" */ 300), memMax+1-memMin)
  3878. // sorry, nothing satisfactory is left
  3879. // \xref[TeX capacity exceeded main memory size][\quad main memory size]
  3880. // sorry, nothing satisfactory is left
  3881. // \xref[TeX capacity exceeded main memory size][\quad main memory size]
  3882. found:
  3883. *(*prg.mem[r1].hh()).rh() = 0 // this node is now nonempty
  3884. // var_used:=var_used+s; [maintain usage statistics]
  3885. // [ ]
  3886. r = uint16(r1)
  3887. exit:
  3888. ;
  3889. return r
  3890. }
  3891. // 130.
  3892. // tangle:pos tex.web:2780:3:
  3893. // Conversely, when some variable-size node |p| of size |s| is no longer needed,
  3894. // the operation |free_node(p,s)| will make its words available, by inserting
  3895. // |p| as a new empty node just before where |rover| now points.
  3896. // \xref[inner loop]
  3897. func (prg *prg) freeNode(p halfword, s halfword) { // variable-size node
  3898. // liberation
  3899. var (
  3900. q halfword // |llink(rover)|
  3901. )
  3902. *(*prg.mem[p].hh()).lh() = s
  3903. *(*prg.mem[p].hh()).rh() = 65535
  3904. q = *(*prg.mem[int32(prg.rover)+1].hh()).lh()
  3905. *(*prg.mem[int32(p)+1].hh()).lh() = q
  3906. *(*prg.mem[int32(p)+1].hh()).rh() = prg.rover // set both links
  3907. *(*prg.mem[int32(prg.rover)+1].hh()).lh() = p
  3908. *(*prg.mem[int32(q)+1].hh()).rh() = p // insert |p| into the ring
  3909. // var_used:=var_used-s; [ ]
  3910. // maintain statistics
  3911. }
  3912. // 131.
  3913. // tangle:pos tex.web:2794:3:
  3914. // Just before \.[INITEX] writes out the memory, it sorts the doubly linked
  3915. // available space list. The list is probably very short at such times, so a
  3916. // simple insertion sort is used. The smallest available location will be
  3917. // pointed to by |rover|, the next-smallest by |rlink(rover)|, etc.
  3918. func (prg *prg) sortAvail() { // sorts the available variable-size nodes
  3919. // by location
  3920. var (
  3921. p, q, r1 halfword // indices into |mem|
  3922. oldRover halfword // initial |rover| setting
  3923. )
  3924. p = prg.getNode(010000000000) // merge adjacent free areas
  3925. p = *(*prg.mem[int32(prg.rover)+1].hh()).rh()
  3926. *(*prg.mem[int32(prg.rover)+1].hh()).rh() = 65535
  3927. oldRover = prg.rover
  3928. for int32(p) != int32(oldRover) {
  3929. // Sort \(p)|p| into the list starting at |rover| and advance |p| to |rlink(p)|
  3930. if int32(p) < int32(prg.rover) {
  3931. q = p
  3932. p = *(*prg.mem[int32(q)+1].hh()).rh()
  3933. *(*prg.mem[int32(q)+1].hh()).rh() = prg.rover
  3934. prg.rover = q
  3935. } else {
  3936. q = prg.rover
  3937. for int32(*(*prg.mem[int32(q)+1].hh()).rh()) < int32(p) {
  3938. q = *(*prg.mem[int32(q)+1].hh()).rh()
  3939. }
  3940. r1 = *(*prg.mem[int32(p)+1].hh()).rh()
  3941. *(*prg.mem[int32(p)+1].hh()).rh() = *(*prg.mem[int32(q)+1].hh()).rh()
  3942. *(*prg.mem[int32(q)+1].hh()).rh() = p
  3943. p = r1
  3944. }
  3945. }
  3946. p = prg.rover
  3947. for int32(*(*prg.mem[int32(p)+1].hh()).rh()) != 65535 {
  3948. *(*prg.mem[int32(*(*prg.mem[int32(p)+1].hh()).rh())+1].hh()).lh() = p
  3949. p = *(*prg.mem[int32(p)+1].hh()).rh()
  3950. }
  3951. *(*prg.mem[int32(p)+1].hh()).rh() = prg.rover
  3952. *(*prg.mem[int32(prg.rover)+1].hh()).lh() = p
  3953. }
  3954. // 133. \[10] Data structures for boxes and their friends
  3955. // tangle:pos tex.web:2828:54:
  3956. // From the computer's standpoint, \TeX's chief mission is to create
  3957. // horizontal and vertical lists. We shall now investigate how the elements
  3958. // of these lists are represented internally as nodes in the dynamic memory.
  3959. //
  3960. // A horizontal or vertical list is linked together by |link| fields in
  3961. // the first word of each node. Individual nodes represent boxes, glue,
  3962. // penalties, or special things like discretionary hyphens; because of this
  3963. // variety, some nodes are longer than others, and we must distinguish different
  3964. // kinds of nodes. We do this by putting a `|type|' field in the first word,
  3965. // together with the link and an optional `|subtype|'.
  3966. // 134.
  3967. // tangle:pos tex.web:2843:3:
  3968. // A | char_node|, which represents a single character, is the most important
  3969. // kind of node because it accounts for the vast majority of all boxes.
  3970. // Special precautions are therefore taken to ensure that a |char_node| does
  3971. // not take up much memory space. Every such node is one word long, and in fact
  3972. // it is identifiable by this property, since other kinds of nodes have at least
  3973. // two words, and they appear in |mem| locations less than |hi_mem_min|.
  3974. // This makes it possible to omit the |type| field in a |char_node|, leaving
  3975. // us room for two bytes that identify a |font| and a |character| within
  3976. // that font.
  3977. //
  3978. // Note that the format of a |char_node| allows for up to 256 different
  3979. // fonts and up to 256 characters per font; but most implementations will
  3980. // probably limit the total number of fonts to fewer than 75 per job,
  3981. // and most fonts will stick to characters whose codes are
  3982. // less than 128 (since higher codes
  3983. // are more difficult to access on most keyboards).
  3984. //
  3985. // Extensions of \TeX\ intended for oriental languages will need even more
  3986. // than $256\times256$ possible characters, when we consider different sizes
  3987. // \xref[oriental characters]\xref[Chinese characters]\xref[Japanese characters]
  3988. // and styles of type. It is suggested that Chinese and Japanese fonts be
  3989. // handled by representing such characters in two consecutive |char_node|
  3990. // entries: The first of these has |font=font_base|, and its |link| points
  3991. // to the second;
  3992. // the second identifies the font and the character dimensions.
  3993. // The saving feature about oriental characters is that most of them have
  3994. // the same box dimensions. The |character| field of the first |char_node|
  3995. // is a ``\\[charext]'' that distinguishes between graphic symbols whose
  3996. // dimensions are identical for typesetting purposes. (See the \MF\ manual.)
  3997. // Such an extension of \TeX\ would not be difficult; further details are
  3998. // left to the reader.
  3999. //
  4000. // In order to make sure that the |character| code fits in a quarterword,
  4001. // \TeX\ adds the quantity |min_quarterword| to the actual code.
  4002. //
  4003. // Character nodes appear only in horizontal lists, never in vertical lists.
  4004. // 135.
  4005. // tangle:pos tex.web:2885:3:
  4006. // An |hlist_node| stands for a box that was made from a horizontal list.
  4007. // Each |hlist_node| is seven words long, and contains the following fields
  4008. // (in addition to the mandatory |type| and |link|, which we shall not
  4009. // mention explicitly when discussing the other node types): The |height| and
  4010. // |width| and |depth| are scaled integers denoting the dimensions of the
  4011. // box. There is also a |shift_amount| field, a scaled integer indicating
  4012. // how much this box should be lowered (if it appears in a horizontal list),
  4013. // or how much it should be moved to the right (if it appears in a vertical
  4014. // list). There is a |list_ptr| field, which points to the beginning of the
  4015. // list from which this box was fabricated; if |list_ptr| is |null|, the box
  4016. // is empty. Finally, there are three fields that represent the setting of
  4017. // the glue: |glue_set(p)| is a word of type |glue_ratio| that represents
  4018. // the proportionality constant for glue setting; |glue_sign(p)| is
  4019. // |stretching| or |shrinking| or |normal| depending on whether or not the
  4020. // glue should stretch or shrink or remain rigid; and |glue_order(p)|
  4021. // specifies the order of infinity to which glue setting applies (|normal|,
  4022. // |fil|, |fill|, or |filll|). The |subtype| field is not used.
  4023. // 136.
  4024. // tangle:pos tex.web:2923:3:
  4025. // The |new_null_box| function returns a pointer to an |hlist_node| in
  4026. // which all subfields have the values corresponding to `\.[\\hbox\[\]]'.
  4027. // (The |subtype| field is set to |min_quarterword|, for historic reasons
  4028. // that are no longer relevant.)
  4029. func (prg *prg) newNullBox() (r halfword) { // creates a new box node
  4030. var (
  4031. p halfword // the new node
  4032. )
  4033. p = prg.getNode(boxNodeSize)
  4034. *(*prg.mem[p].hh()).b0() = byte(hlistNode)
  4035. *(*prg.mem[p].hh()).b1() = byte(minQuarterword)
  4036. *prg.mem[int32(p)+widthOffset].int() = 0
  4037. *prg.mem[int32(p)+depthOffset].int() = 0
  4038. *prg.mem[int32(p)+heightOffset].int() = 0
  4039. *prg.mem[int32(p)+4].int() = 0
  4040. *(*prg.mem[int32(p)+listOffset].hh()).rh() = 0
  4041. *(*prg.mem[int32(p)+listOffset].hh()).b0() = byte(normal)
  4042. *(*prg.mem[int32(p)+listOffset].hh()).b1() = byte(normal)
  4043. *prg.mem[int32(p)+glueOffset].gr() = float32(0.0)
  4044. r = p
  4045. return r
  4046. }
  4047. // 137.
  4048. // tangle:pos tex.web:2937:3:
  4049. // A |vlist_node| is like an |hlist_node| in all respects except that it
  4050. // contains a vertical list.
  4051. // 138.
  4052. // tangle:pos tex.web:2942:3:
  4053. // A |rule_node| stands for a solid black rectangle; it has |width|,
  4054. // |depth|, and |height| fields just as in an |hlist_node|. However, if
  4055. // any of these dimensions is $-2^[30]$, the actual value will be determined
  4056. // by running the rule up to the boundary of the innermost enclosing box.
  4057. // This is called a ``running dimension.'' The |width| is never running in
  4058. // an hlist; the |height| and |depth| are never running in a~vlist.
  4059. // 139.
  4060. // tangle:pos tex.web:2954:3:
  4061. // A new rule node is delivered by the |new_rule| function. It
  4062. // makes all the dimensions “running,” so you have to change the
  4063. // ones that are not allowed to run.
  4064. func (prg *prg) newRule() (r halfword) {
  4065. var (
  4066. p halfword // the new node
  4067. )
  4068. p = prg.getNode(ruleNodeSize)
  4069. *(*prg.mem[p].hh()).b0() = byte(ruleNode)
  4070. *(*prg.mem[p].hh()).b1() = 0 // the |subtype| is not used
  4071. *prg.mem[int32(p)+widthOffset].int() = -010000000000
  4072. *prg.mem[int32(p)+depthOffset].int() = -010000000000
  4073. *prg.mem[int32(p)+heightOffset].int() = -010000000000
  4074. r = p
  4075. return r
  4076. }
  4077. // 140.
  4078. // tangle:pos tex.web:2966:3:
  4079. // Insertions are represented by |ins_node| records, where the |subtype|
  4080. // indicates the corresponding box number. For example, `\.[\\insert 250]'
  4081. // leads to an |ins_node| whose |subtype| is |250+min_quarterword|.
  4082. // The |height| field of an |ins_node| is slightly misnamed; it actually holds
  4083. // the natural height plus depth of the vertical list being inserted.
  4084. // The |depth| field holds the |split_max_depth| to be used in case this
  4085. // insertion is split, and the |split_top_ptr| points to the corresponding
  4086. // |split_top_skip|. The |float_cost| field holds the |floating_penalty| that
  4087. // will be used if this insertion floats to a subsequent page after a
  4088. // split insertion of the same class. There is one more field, the
  4089. // |ins_ptr|, which points to the beginning of the vlist for the insertion.
  4090. // 141.
  4091. // tangle:pos tex.web:2984:3:
  4092. // A |mark_node| has a |mark_ptr| field that points to the reference count
  4093. // of a token list that contains the user's \.[\\mark] text.
  4094. // This field occupies a full word instead of a halfword, because
  4095. // there's nothing to put in the other halfword; it is easier in \PASCAL\ to
  4096. // use the full word than to risk leaving garbage in the unused half.
  4097. // 142.
  4098. // tangle:pos tex.web:2994:3:
  4099. // An |adjust_node|, which occurs only in horizontal lists,
  4100. // specifies material that will be moved out into the surrounding
  4101. // vertical list; i.e., it is used to implement \TeX's `\.[\\vadjust]'
  4102. // operation. The |adjust_ptr| field points to the vlist containing this
  4103. // material.
  4104. // 143.
  4105. // tangle:pos tex.web:3003:3:
  4106. // A |ligature_node|, which occurs only in horizontal lists, specifies
  4107. // a character that was fabricated from the interaction of two or more
  4108. // actual characters. The second word of the node, which is called the
  4109. // |lig_char| word, contains |font| and |character| fields just as in a
  4110. // |char_node|. The characters that generated the ligature have not been
  4111. // forgotten, since they are needed for diagnostic messages and for
  4112. // hyphenation; the |lig_ptr| field points to a linked list of character
  4113. // nodes for all original characters that have been deleted. (This list
  4114. // might be empty if the characters that generated the ligature were
  4115. // retained in other nodes.)
  4116. //
  4117. // The |subtype| field is 0, plus 2 and/or 1 if the original source of the
  4118. // ligature included implicit left and/or right boundaries.
  4119. // 144.
  4120. // tangle:pos tex.web:3021:3:
  4121. // The |new_ligature| function creates a ligature node having given
  4122. // contents of the |font|, |character|, and |lig_ptr| fields. We also have
  4123. // a |new_lig_item| function, which returns a two-word node having a given
  4124. // |character| field. Such nodes are used for temporary processing as ligatures
  4125. // are being created.
  4126. func (prg *prg) newLigature(f, c quarterword, q halfword) (r halfword) {
  4127. var (
  4128. p halfword // the new node
  4129. )
  4130. p = prg.getNode(smallNodeSize)
  4131. *(*prg.mem[p].hh()).b0() = byte(ligatureNode)
  4132. *(*prg.mem[int32(p)+1].hh()).b0() = f
  4133. *(*prg.mem[int32(p)+1].hh()).b1() = c
  4134. *(*prg.mem[int32(p)+1].hh()).rh() = q
  4135. *(*prg.mem[p].hh()).b1() = 0
  4136. r = p
  4137. return r
  4138. }
  4139. func (prg *prg) newLigItem(c quarterword) (r halfword) {
  4140. var (
  4141. p halfword // the new node
  4142. )
  4143. p = prg.getNode(smallNodeSize)
  4144. *(*prg.mem[p].hh()).b1() = c
  4145. *(*prg.mem[int32(p)+1].hh()).rh() = 0
  4146. r = p
  4147. return r
  4148. }
  4149. // 145.
  4150. // tangle:pos tex.web:3040:3:
  4151. // A |disc_node|, which occurs only in horizontal lists, specifies a
  4152. // “dis\-cretion\-ary” line break. If such a break occurs at node |p|, the text
  4153. // that starts at |pre_break(p)| will precede the break, the text that starts at
  4154. // |post_break(p)| will follow the break, and text that appears in the next
  4155. // |replace_count(p)| nodes will be ignored. For example, an ordinary
  4156. // discretionary hyphen, indicated by `\.[\\-]', yields a |disc_node| with
  4157. // |pre_break| pointing to a |char_node| containing a hyphen, |post_break=null|,
  4158. // and |replace_count=0|. All three of the discretionary texts must be
  4159. // lists that consist entirely of character, kern, box, rule, and ligature nodes.
  4160. //
  4161. // If |pre_break(p)=null|, the |ex_hyphen_penalty| will be charged for this
  4162. // break. Otherwise the |hyphen_penalty| will be charged. The texts will
  4163. // actually be substituted into the list by the line-breaking algorithm if it
  4164. // decides to make the break, and the discretionary node will disappear at
  4165. // that time; thus, the output routine sees only discretionaries that were
  4166. // not chosen.
  4167. func (prg *prg) newDisc() (r halfword) { // creates an empty |disc_node|
  4168. var (
  4169. p halfword // the new node
  4170. )
  4171. p = prg.getNode(smallNodeSize)
  4172. *(*prg.mem[p].hh()).b0() = byte(discNode)
  4173. *(*prg.mem[p].hh()).b1() = 0
  4174. *(*prg.mem[int32(p)+1].hh()).lh() = 0
  4175. *(*prg.mem[int32(p)+1].hh()).rh() = 0
  4176. r = p
  4177. return r
  4178. }
  4179. // 146.
  4180. // tangle:pos tex.web:3069:3:
  4181. // A |whatsit_node| is a wild card reserved for extensions to \TeX. The
  4182. // |subtype| field in its first word says what `\\[whatsit]' it is, and
  4183. // implicitly determines the node size (which must be 2 or more) and the
  4184. // format of the remaining words. When a |whatsit_node| is encountered
  4185. // in a list, special actions are invoked; knowledgeable people who are
  4186. // careful not to mess up the rest of \TeX\ are able to make \TeX\ do new
  4187. // things by adding code at the end of the program. For example, there
  4188. // might be a `\TeX nicolor' extension to specify different colors of ink,
  4189. // \xref[extensions to \TeX]
  4190. // and the whatsit node might contain the desired parameters.
  4191. //
  4192. // The present implementation of \TeX\ treats the features associated with
  4193. // `\.[\\write]' and `\.[\\special]' as if they were extensions, in order to
  4194. // illustrate how such routines might be coded. We shall defer further
  4195. // discussion of extensions until the end of this program.
  4196. // 147.
  4197. // tangle:pos tex.web:3087:3:
  4198. // A |math_node|, which occurs only in horizontal lists, appears before and
  4199. // after mathematical formulas. The |subtype| field is |before| before the
  4200. // formula and |after| after it. There is a |width| field, which represents
  4201. // the amount of surrounding space inserted by \.[\\mathsurround].
  4202. func (prg *prg) newMath(w scaled, s smallNumber) (r halfword) {
  4203. var (
  4204. p halfword // the new node
  4205. )
  4206. p = prg.getNode(smallNodeSize)
  4207. *(*prg.mem[p].hh()).b0() = byte(mathNode)
  4208. *(*prg.mem[p].hh()).b1() = s
  4209. *prg.mem[int32(p)+widthOffset].int() = w
  4210. r = p
  4211. return r
  4212. }
  4213. // 148.
  4214. // tangle:pos tex.web:3102:3:
  4215. // \TeX\ makes use of the fact that |hlist_node|, |vlist_node|,
  4216. // |rule_node|, |ins_node|, |mark_node|, |adjust_node|, |ligature_node|,
  4217. // |disc_node|, |whatsit_node|, and |math_node| are at the low end of the
  4218. // type codes, by permitting a break at glue in a list if and only if the
  4219. // |type| of the previous node is less than |math_node|. Furthermore, a
  4220. // node is discarded after a break if its type is |math_node| or~more.
  4221. // 149.
  4222. // tangle:pos tex.web:3112:3:
  4223. // A |glue_node| represents glue in a list. However, it is really only
  4224. // a pointer to a separate glue specification, since \TeX\ makes use of the
  4225. // fact that many essentially identical nodes of glue are usually present.
  4226. // If |p| points to a |glue_node|, |glue_ptr(p)| points to
  4227. // another packet of words that specify the stretch and shrink components, etc.
  4228. //
  4229. // Glue nodes also serve to represent leaders; the |subtype| is used to
  4230. // distinguish between ordinary glue (which is called |normal|) and the three
  4231. // kinds of leaders (which are called |a_leaders|, |c_leaders|, and |x_leaders|).
  4232. // The |leader_ptr| field points to a rule node or to a box node containing the
  4233. // leaders; it is set to |null| in ordinary glue nodes.
  4234. //
  4235. // Many kinds of glue are computed from \TeX's ``skip'' parameters, and
  4236. // it is helpful to know which parameter has led to a particular glue node.
  4237. // Therefore the |subtype| is set to indicate the source of glue, whenever
  4238. // it originated as a parameter. We will be defining symbolic names for the
  4239. // parameter numbers later (e.g., |line_skip_code=0|, |baseline_skip_code=1|,
  4240. // etc.); it suffices for now to say that the |subtype| of parametric glue
  4241. // will be the same as the parameter number, plus~one.
  4242. //
  4243. // In math formulas there are two more possibilities for the |subtype| in a
  4244. // glue node: |mu_glue| denotes an \.[\\mskip] (where the units are scaled \.[mu]
  4245. // instead of scaled \.[pt]); and |cond_math_glue| denotes the `\.[\\nonscript]'
  4246. // feature that cancels the glue node immediately following if it appears
  4247. // in a subscript.
  4248. // 151.
  4249. // tangle:pos tex.web:3174:3:
  4250. // Here is a function that returns a pointer to a copy of a glue spec.
  4251. // The reference count in the copy is |null|, because there is assumed
  4252. // to be exactly one reference to the new specification.
  4253. func (prg *prg) newSpec(p halfword) (r halfword) { // duplicates a glue specification
  4254. var (
  4255. q halfword // the new spec
  4256. )
  4257. q = prg.getNode(glueSpecSize)
  4258. prg.mem[q] = prg.mem[p]
  4259. *(*prg.mem[q].hh()).rh() = 0
  4260. *prg.mem[int32(q)+widthOffset].int() = *prg.mem[int32(p)+widthOffset].int()
  4261. *prg.mem[int32(q)+2].int() = *prg.mem[int32(p)+2].int()
  4262. *prg.mem[int32(q)+3].int() = *prg.mem[int32(p)+3].int()
  4263. r = q
  4264. return r
  4265. }
  4266. // 152.
  4267. // tangle:pos tex.web:3186:3:
  4268. // And here's a function that creates a glue node for a given parameter
  4269. // identified by its code number; for example,
  4270. // |new_param_glue(line_skip_code)| returns a pointer to a glue node for the
  4271. // current \.[\\lineskip].
  4272. func (prg *prg) newParamGlue(n smallNumber) (r halfword) {
  4273. var (
  4274. p halfword // the new node
  4275. q halfword // the glue specification
  4276. )
  4277. p = prg.getNode(smallNodeSize)
  4278. *(*prg.mem[p].hh()).b0() = byte(glueNode)
  4279. *(*prg.mem[p].hh()).b1() = byte(int32(n) + 1)
  4280. *(*prg.mem[int32(p)+1].hh()).rh() = 0
  4281. q = *(*prg.eqtb[glueBase+int32(n)-1].hh()).rh()
  4282. *(*prg.mem[int32(p)+1].hh()).lh() = q
  4283. *(*prg.mem[q].hh()).rh() = uint16(int32(*(*prg.mem[q].hh()).rh()) + 1)
  4284. r = p
  4285. return r
  4286. }
  4287. // 153.
  4288. // tangle:pos tex.web:3201:3:
  4289. // Glue nodes that are more or less anonymous are created by |new_glue|,
  4290. // whose argument points to a glue specification.
  4291. func (prg *prg) newGlue(q halfword) (r halfword) {
  4292. var (
  4293. p halfword // the new node
  4294. )
  4295. p = prg.getNode(smallNodeSize)
  4296. *(*prg.mem[p].hh()).b0() = byte(glueNode)
  4297. *(*prg.mem[p].hh()).b1() = byte(normal)
  4298. *(*prg.mem[int32(p)+1].hh()).rh() = 0
  4299. *(*prg.mem[int32(p)+1].hh()).lh() = q
  4300. *(*prg.mem[q].hh()).rh() = uint16(int32(*(*prg.mem[q].hh()).rh()) + 1)
  4301. r = p
  4302. return r
  4303. }
  4304. // 154.
  4305. // tangle:pos tex.web:3211:3:
  4306. // Still another subroutine is needed: This one is sort of a combination
  4307. // of |new_param_glue| and |new_glue|. It creates a glue node for one of
  4308. // the current glue parameters, but it makes a fresh copy of the glue
  4309. // specification, since that specification will probably be subject to change,
  4310. // while the parameter will stay put. The global variable |temp_ptr| is
  4311. // set to the address of the new spec.
  4312. func (prg *prg) newSkipParam(n smallNumber) (r halfword) {
  4313. var (
  4314. p halfword // the new node
  4315. )
  4316. prg.tempPtr = prg.newSpec(*(*prg.eqtb[glueBase+int32(n)-1].hh()).rh())
  4317. p = prg.newGlue(prg.tempPtr)
  4318. *(*prg.mem[prg.tempPtr].hh()).rh() = 0
  4319. *(*prg.mem[p].hh()).b1() = byte(int32(n) + 1)
  4320. r = p
  4321. return r
  4322. }
  4323. // 155.
  4324. // tangle:pos tex.web:3225:3:
  4325. // A |kern_node| has a |width| field to specify a (normally negative)
  4326. // amount of spacing. This spacing correction appears in horizontal lists
  4327. // between letters like A and V when the font designer said that it looks
  4328. // better to move them closer together or further apart. A kern node can
  4329. // also appear in a vertical list, when its `|width|' denotes additional
  4330. // spacing in the vertical direction. The |subtype| is either |normal| (for
  4331. // kerns inserted from font information or math mode calculations) or |explicit|
  4332. // (for kerns inserted from \.[\\kern] and \.[\\/] commands) or |acc_kern|
  4333. // (for kerns inserted from non-math accents) or |mu_glue| (for kerns
  4334. // inserted from \.[\\mkern] specifications in math formulas).
  4335. // 156.
  4336. // tangle:pos tex.web:3240:3:
  4337. // The |new_kern| function creates a kern node having a given width.
  4338. func (prg *prg) newKern(w scaled) (r halfword) {
  4339. var (
  4340. p halfword // the new node
  4341. )
  4342. p = prg.getNode(smallNodeSize)
  4343. *(*prg.mem[p].hh()).b0() = byte(kernNode)
  4344. *(*prg.mem[p].hh()).b1() = byte(normal)
  4345. *prg.mem[int32(p)+widthOffset].int() = w
  4346. r = p
  4347. return r
  4348. }
  4349. // 157.
  4350. // tangle:pos tex.web:3250:3:
  4351. // A |penalty_node| specifies the penalty associated with line or page
  4352. // breaking, in its |penalty| field. This field is a fullword integer, but
  4353. // the full range of integer values is not used: Any penalty |>=10000| is
  4354. // treated as infinity, and no break will be allowed for such high values.
  4355. // Similarly, any penalty |<=-10000| is treated as negative infinity, and a
  4356. // break will be forced.
  4357. // 158.
  4358. // tangle:pos tex.web:3262:3:
  4359. // Anyone who has been reading the last few sections of the program will
  4360. // be able to guess what comes next.
  4361. func (prg *prg) newPenalty(m int32) (r halfword) {
  4362. var (
  4363. p halfword // the new node
  4364. )
  4365. p = prg.getNode(smallNodeSize)
  4366. *(*prg.mem[p].hh()).b0() = byte(penaltyNode)
  4367. *(*prg.mem[p].hh()).b1() = 0 // the |subtype| is not used
  4368. *prg.mem[int32(p)+1].int() = m
  4369. r = p
  4370. return r
  4371. }
  4372. // 159.
  4373. // tangle:pos tex.web:3272:3:
  4374. // You might think that we have introduced enough node types by now. Well,
  4375. // almost, but there is one more: An |unset_node| has nearly the same format
  4376. // as an |hlist_node| or |vlist_node|; it is used for entries in \.[\\halign]
  4377. // or \.[\\valign] that are not yet in their final form, since the box
  4378. // dimensions are their ``natural'' sizes before any glue adjustment has been
  4379. // made. The |glue_set| word is not present; instead, we have a |glue_stretch|
  4380. // field, which contains the total stretch of order |glue_order| that is
  4381. // present in the hlist or vlist being boxed.
  4382. // Similarly, the |shift_amount| field is replaced by a |glue_shrink| field,
  4383. // containing the total shrink of order |glue_sign| that is present.
  4384. // The |subtype| field is called |span_count|; an unset box typically
  4385. // contains the data for |qo(span_count)+1| columns.
  4386. // Unset nodes will be changed to box nodes when alignment is completed.
  4387. // 160.
  4388. // tangle:pos tex.web:3291:3:
  4389. // In fact, there are still more types coming. When we get to math formula
  4390. // processing we will see that a |style_node| has |type=14|; and a number
  4391. // of larger type codes will also be defined, for use in math mode only.
  4392. // 161.
  4393. // tangle:pos tex.web:3295:3:
  4394. // Warning: If any changes are made to these data structure layouts, such as
  4395. // changing any of the node sizes or even reordering the words of nodes,
  4396. // the |copy_node_list| procedure and the memory initialization code
  4397. // below may have to be changed. Such potentially dangerous parts of the
  4398. // program are listed in the index under `data structure assumptions'.
  4399. // \xref[data structure assumptions]
  4400. // However, other references to the nodes are made symbolically in terms of
  4401. // the \.[WEB] macro definitions above, so that format changes will leave
  4402. // \TeX's other algorithms intact.
  4403. // \xref[system dependencies]
  4404. // 162. \[11] Memory layout
  4405. // tangle:pos tex.web:3306:24:
  4406. // Some areas of |mem| are dedicated to fixed usage, since static allocation is
  4407. // more efficient than dynamic allocation when we can get away with it. For
  4408. // example, locations |mem_bot| to |mem_bot+3| are always used to store the
  4409. // specification for glue that is `\.[0pt plus 0pt minus 0pt]'. The
  4410. // following macro definitions accomplish the static allocation by giving
  4411. // symbolic names to the fixed positions. Static variable-size nodes appear
  4412. // in locations |mem_bot| through |lo_mem_stat_max|, and static single-word nodes
  4413. // appear in locations |hi_mem_stat_min| through |mem_top|, inclusive. It is
  4414. // harmless to let |lig_trick| and |garbage| share the same location of |mem|.
  4415. // 167.
  4416. // tangle:pos tex.web:3402:3:
  4417. // Procedure |check_mem| makes sure that the available space lists of
  4418. // |mem| are well formed, and it optionally prints out all locations
  4419. // that are reserved now but were free the last time this procedure was called.
  4420. // procedure check_mem( print_locs : boolean);
  4421. // label done1,done2; [loop exits]
  4422. // var p, q:halfword ; [current locations of interest in |mem|]
  4423. // clobbered:boolean; [is something amiss?]
  4424. // begin for p:=mem_min to lo_mem_max do free[p]:=false; [you can probably
  4425. // do this faster]
  4426. // for p:=hi_mem_min to mem_end do free[p]:=false; [ditto]
  4427. //
  4428. // [ Check single-word |avail| list ]
  4429. // p:=avail; q:=0 ; clobbered:=false;
  4430. // while p<>0 do
  4431. // begin if (p>mem_end)or(p<hi_mem_min) then clobbered:=true
  4432. // else if free[p] then clobbered:=true;
  4433. // if clobbered then
  4434. // begin print_nl(["AVAIL list clobbered at "=]301);
  4435. // [ \xref[AVAIL list clobbered...] ]
  4436. // print_int(q); goto done1;
  4437. // end;
  4438. // free[p]:=true; q:=p; p:= mem[ q].hh.rh ;
  4439. // end;
  4440. // done1:
  4441. //
  4442. // ;
  4443. //
  4444. // [ Check variable-size |avail| list ]
  4445. // p:=rover; q:=0 ; clobbered:=false;
  4446. // repeat if (p>=lo_mem_max)or(p<mem_min) then clobbered:=true
  4447. // else if ( mem[ p+ 1].hh.rh >=lo_mem_max)or( mem[ p+ 1].hh.rh <mem_min) then clobbered:=true
  4448. // else if not( ( mem[ p].hh.rh = 65535 ) )or( mem[ p].hh.lh <2)or
  4449. // (p+ mem[ p].hh.lh >lo_mem_max)or ( mem[ mem[ p+ 1].hh.rh + 1].hh.lh <>p) then clobbered:=true;
  4450. // if clobbered then
  4451. // begin print_nl(["Double-AVAIL list clobbered at "=]302);
  4452. // print_int(q); goto done2;
  4453. // end;
  4454. // for q:=p to p+ mem[ p].hh.lh -1 do [mark all locations free]
  4455. // begin if free[q] then
  4456. // begin print_nl(["Doubly free location at "=]303);
  4457. // [ \xref[Doubly free location...] ]
  4458. // print_int(q); goto done2;
  4459. // end;
  4460. // free[q]:=true;
  4461. // end;
  4462. // q:=p; p:= mem[ p+ 1].hh.rh ;
  4463. // until p=rover;
  4464. // done2:
  4465. //
  4466. // ;
  4467. //
  4468. // [ Check flags of unavailable nodes ]
  4469. // p:=mem_min;
  4470. // while p<=lo_mem_max do [node |p| should not be empty]
  4471. // begin if ( mem[ p].hh.rh = 65535 ) then
  4472. // begin print_nl(["Bad flag at "=]304); print_int(p);
  4473. // [ \xref[Bad flag...] ]
  4474. // end;
  4475. // while (p<=lo_mem_max) and not free[p] do p:= p+1 ;
  4476. // while (p<=lo_mem_max) and free[p] do p:= p+1 ;
  4477. // end
  4478. //
  4479. // ;
  4480. // if print_locs then
  4481. // [ Print newly busy locations ]
  4482. // begin print_nl(["New busy locs:"=]305);
  4483. // for p:=mem_min to lo_mem_max do
  4484. // if not free[p] and ((p>was_lo_max) or was_free[p]) then
  4485. // begin print_char([" "=]32); print_int(p);
  4486. // end;
  4487. // for p:=hi_mem_min to mem_end do
  4488. // if not free[p] and
  4489. // ((p<was_hi_min) or (p>was_mem_end) or was_free[p]) then
  4490. // begin print_char([" "=]32); print_int(p);
  4491. // end;
  4492. // end
  4493. //
  4494. // ;
  4495. // for p:=mem_min to lo_mem_max do was_free[p]:=free[p];
  4496. // for p:=hi_mem_min to mem_end do was_free[p]:=free[p];
  4497. // [|was_free:=free| might be faster]
  4498. // was_mem_end:=mem_end; was_lo_max:=lo_mem_max; was_hi_min:=hi_mem_min;
  4499. // end;
  4500. // [ ]
  4501. // 172.
  4502. // tangle:pos tex.web:3484:3:
  4503. // The |search_mem| procedure attempts to answer the question ``Who points
  4504. // to node~|p|?'' In doing so, it fetches |link| and |info| fields of |mem|
  4505. // that might not be of type |two_halves|. Strictly speaking, this is
  4506. // \xref[dirty \PASCAL]
  4507. // undefined in \PASCAL, and it can lead to ``false drops'' (words that seem to
  4508. // point to |p| purely by coincidence). But for debugging purposes, we want
  4509. // to rule out the places that do [\sl not\/] point to |p|, so a few false
  4510. // drops are tolerable.
  4511. // procedure search_mem( p:halfword ); [look for pointers to |p|]
  4512. // var q:integer; [current position being searched]
  4513. // begin for q:=mem_min to lo_mem_max do
  4514. // begin if mem[ q].hh.rh =p then
  4515. // begin print_nl(["LINK("=]306); print_int(q); print_char([")"=]41);
  4516. // end;
  4517. // if mem[ q].hh.lh =p then
  4518. // begin print_nl(["INFO("=]307); print_int(q); print_char([")"=]41);
  4519. // end;
  4520. // end;
  4521. // for q:=hi_mem_min to mem_end do
  4522. // begin if mem[ q].hh.rh =p then
  4523. // begin print_nl(["LINK("=]306); print_int(q); print_char([")"=]41);
  4524. // end;
  4525. // if mem[ q].hh.lh =p then
  4526. // begin print_nl(["INFO("=]307); print_int(q); print_char([")"=]41);
  4527. // end;
  4528. // end;
  4529. //
  4530. // [ Search |eqtb| for equivalents equal to |p| ]
  4531. // for q:=active_base to box_base+255 do
  4532. // begin if eqtb[ q].hh.rh =p then
  4533. // begin print_nl(["EQUIV("=]501); print_int(q); print_char([")"=]41);
  4534. // end;
  4535. // end
  4536. //
  4537. // ;
  4538. //
  4539. // [ Search |save_stack| for equivalents that point to |p| ]
  4540. // if save_ptr>0 then for q:=0 to save_ptr-1 do
  4541. // begin if save_stack[ q].hh.rh =p then
  4542. // begin print_nl(["SAVE("=]546); print_int(q); print_char([")"=]41);
  4543. // end;
  4544. // end
  4545. //
  4546. // ;
  4547. //
  4548. // [ Search |hyph_list| for pointers to |p| ]
  4549. // for q:=0 to hyph_size do
  4550. // begin if hyph_list[q]=p then
  4551. // begin print_nl(["HYPH("=]940); print_int(q); print_char([")"=]41);
  4552. // end;
  4553. // end
  4554. //
  4555. // ;
  4556. // end;
  4557. // [ ]
  4558. // 174.
  4559. // tangle:pos tex.web:3538:3:
  4560. // Boxes, rules, inserts, whatsits, marks, and things in general that are
  4561. // sort of “complicated” are indicated only by printing `\.[[]]'.
  4562. func (prg *prg) shortDisplay(p int32) { // prints highlights of list |p|
  4563. var (
  4564. n int32 // for replacement counts
  4565. )
  4566. for p > memMin {
  4567. if p >= int32(prg.hiMemMin) {
  4568. if p <= int32(prg.memEnd) {
  4569. if int32(*(*prg.mem[p].hh()).b0()) != prg.fontInShortDisplay {
  4570. if int32(*(*prg.mem[p].hh()).b0()) < fontBase || int32(*(*prg.mem[p].hh()).b0()) > fontMax {
  4571. prg.printChar(asciiCode('*'))
  4572. } else {
  4573. // Print the font identifier for |font(p)|
  4574. prg.printEsc(*prg.hash[fontIdBase+int32(*(*prg.mem[p].hh()).b0())-514].rh())
  4575. }
  4576. prg.printChar(asciiCode(' '))
  4577. prg.fontInShortDisplay = int32(*(*prg.mem[p].hh()).b0())
  4578. }
  4579. prg.print(int32(*(*prg.mem[p].hh()).b1()) - minQuarterword)
  4580. }
  4581. } else {
  4582. // Print a short indication of the contents of node |p|
  4583. switch *(*prg.mem[p].hh()).b0() {
  4584. case hlistNode, vlistNode, insNode, whatsitNode,
  4585. markNode, adjustNode, unsetNode:
  4586. prg.print( /* "[]" */ 308)
  4587. case ruleNode:
  4588. prg.printChar(asciiCode('|'))
  4589. case glueNode:
  4590. if int32(*(*prg.mem[p+1].hh()).lh()) != memBot {
  4591. prg.printChar(asciiCode(' '))
  4592. }
  4593. case mathNode:
  4594. prg.printChar(asciiCode('$'))
  4595. case ligatureNode:
  4596. prg.shortDisplay(int32(*(*prg.mem[p+1].hh()).rh()))
  4597. case discNode:
  4598. prg.shortDisplay(int32(*(*prg.mem[p+1].hh()).lh()))
  4599. prg.shortDisplay(int32(*(*prg.mem[p+1].hh()).rh()))
  4600. n = int32(*(*prg.mem[p].hh()).b1())
  4601. for n > 0 {
  4602. if int32(*(*prg.mem[p].hh()).rh()) != 0 {
  4603. p = int32(*(*prg.mem[p].hh()).rh())
  4604. }
  4605. n = n - 1
  4606. }
  4607. default:
  4608. }
  4609. }
  4610. p = int32(*(*prg.mem[p].hh()).rh())
  4611. }
  4612. }
  4613. // 176.
  4614. // tangle:pos tex.web:3580:3:
  4615. // The |show_node_list| routine requires some auxiliary subroutines: one to
  4616. // print a font-and-character combination, one to print a token list without
  4617. // its reference count, and one to print a rule dimension.
  4618. func (prg *prg) printFontAndChar(p int32) {
  4619. if p > int32(prg.memEnd) {
  4620. prg.printEsc(strNumber( /* "CLOBBERED." */ 309))
  4621. } else {
  4622. if int32(*(*prg.mem[p].hh()).b0()) < fontBase || int32(*(*prg.mem[p].hh()).b0()) > fontMax {
  4623. prg.printChar(asciiCode('*'))
  4624. } else {
  4625. // Print the font identifier for |font(p)|
  4626. prg.printEsc(*prg.hash[fontIdBase+int32(*(*prg.mem[p].hh()).b0())-514].rh())
  4627. }
  4628. prg.printChar(asciiCode(' '))
  4629. prg.print(int32(*(*prg.mem[p].hh()).b1()) - minQuarterword)
  4630. }
  4631. }
  4632. func (prg *prg) printMark(p int32) {
  4633. prg.printChar(asciiCode('{'))
  4634. if p < int32(prg.hiMemMin) || p > int32(prg.memEnd) {
  4635. prg.printEsc(strNumber( /* "CLOBBERED." */ 309))
  4636. } else {
  4637. prg.showTokenList(int32(*(*prg.mem[p].hh()).rh()), 0, maxPrintLine-10)
  4638. }
  4639. prg.printChar(asciiCode('}'))
  4640. }
  4641. func (prg *prg) printRuleDimen(d scaled) {
  4642. if d == -010000000000 {
  4643. prg.printChar(asciiCode('*'))
  4644. } else {
  4645. prg.printScaled(d)
  4646. }
  4647. // \xref[*\relax]
  4648. }
  4649. // 177.
  4650. // tangle:pos tex.web:3605:3:
  4651. // Then there is a subroutine that prints glue stretch and shrink, possibly
  4652. // followed by the name of finite units:
  4653. func (prg *prg) printGlue(d scaled, order int32, s strNumber) {
  4654. prg.printScaled(d)
  4655. if order < normal || order > filll {
  4656. prg.print( /* "foul" */ 310)
  4657. } else if order > normal {
  4658. prg.print( /* "fil" */ 311)
  4659. for order > fil {
  4660. prg.printChar(asciiCode('l'))
  4661. order = order - 1
  4662. }
  4663. } else if int32(s) != 0 {
  4664. prg.print(int32(s))
  4665. }
  4666. }
  4667. // 178.
  4668. // tangle:pos tex.web:3621:3:
  4669. // The next subroutine prints a whole glue specification.
  4670. func (prg *prg) printSpec(p int32, s strNumber) {
  4671. if p < memMin || p >= int32(prg.loMemMax) {
  4672. prg.printChar(asciiCode('*'))
  4673. } else {
  4674. prg.printScaled(*prg.mem[p+widthOffset].int())
  4675. if int32(s) != 0 {
  4676. prg.print(int32(s))
  4677. }
  4678. if *prg.mem[p+2].int() != 0 {
  4679. prg.print( /* " plus " */ 312)
  4680. prg.printGlue(*prg.mem[p+2].int(), int32(*(*prg.mem[p].hh()).b0()), s)
  4681. }
  4682. if *prg.mem[p+3].int() != 0 {
  4683. prg.print( /* " minus " */ 313)
  4684. prg.printGlue(*prg.mem[p+3].int(), int32(*(*prg.mem[p].hh()).b1()), s)
  4685. }
  4686. }
  4687. }
  4688. // 179.
  4689. // tangle:pos tex.web:3638:3:
  4690. // We also need to declare some procedures that appear later in this
  4691. // documentation.
  4692. // Declare procedures needed for displaying the elements of mlists
  4693. func (prg *prg) printFamAndChar(p halfword) {
  4694. prg.printEsc(strNumber( /* "fam" */ 464))
  4695. prg.printInt(int32(*(*prg.mem[p].hh()).b0()))
  4696. prg.printChar(asciiCode(' '))
  4697. prg.print(int32(*(*prg.mem[p].hh()).b1()) - minQuarterword)
  4698. }
  4699. func (prg *prg) printDelimiter(p halfword) { // prints a delimiter as 24-bit hex value
  4700. var (
  4701. a int32 // accumulator
  4702. )
  4703. a = int32((*prg.mem[p].qqqq()).b0)*256 + int32((*prg.mem[p].qqqq()).b1) - minQuarterword
  4704. a = a*010000 + int32((*prg.mem[p].qqqq()).b2)*256 + int32((*prg.mem[p].qqqq()).b3) - minQuarterword
  4705. if a < 0 {
  4706. prg.printInt(a)
  4707. } else {
  4708. prg.printHex(a)
  4709. }
  4710. } // \2
  4711. // |show_node_list(info(temp_ptr))|
  4712. func (prg *prg) printSubsidiaryData(p halfword, c asciiCode) {
  4713. if int32(prg.poolPtr)-int32(prg.strStart[prg.strPtr]) >= prg.depthThreshold {
  4714. if int32(*(*prg.mem[p].hh()).rh()) != empty {
  4715. prg.print( /* " []" */ 314)
  4716. }
  4717. } else {
  4718. {
  4719. prg.strPool[prg.poolPtr] = c
  4720. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  4721. } // include |c| in the recursion history
  4722. prg.tempPtr = p // prepare for |show_info| if recursion is needed
  4723. switch *(*prg.mem[p].hh()).rh() {
  4724. case mathChar:
  4725. prg.printLn()
  4726. prg.printCurrentString()
  4727. prg.printFamAndChar(p)
  4728. case subBox:
  4729. prg.showInfo() // recursive call
  4730. case subMlist:
  4731. if int32(*(*prg.mem[p].hh()).lh()) == 0 {
  4732. prg.printLn()
  4733. prg.printCurrentString()
  4734. prg.print( /* "[]" */ 860)
  4735. } else {
  4736. prg.showInfo()
  4737. }
  4738. // recursive call
  4739. default: // |empty|
  4740. }
  4741. prg.poolPtr = uint16(int32(prg.poolPtr) - 1) // remove |c| from the recursion history
  4742. }
  4743. }
  4744. func (prg *prg) printStyle(c int32) {
  4745. switch c / 2 {
  4746. case 0:
  4747. prg.printEsc(strNumber( /* "displaystyle" */ 861)) // |display_style=0|
  4748. case 1:
  4749. prg.printEsc(strNumber( /* "textstyle" */ 862)) // |text_style=2|
  4750. case 2:
  4751. prg.printEsc(strNumber( /* "scriptstyle" */ 863)) // |script_style=4|
  4752. case 3:
  4753. prg.printEsc(strNumber( /* "scriptscriptstyle" */ 864))
  4754. // |script_script_style=6|
  4755. default:
  4756. prg.print( /* "Unknown style!" */ 865)
  4757. }
  4758. }
  4759. // Declare the procedure called |print_skip_param|
  4760. func (prg *prg) printSkipParam(n int32) {
  4761. switch n {
  4762. case lineSkipCode:
  4763. prg.printEsc(strNumber( /* "lineskip" */ 376))
  4764. case baselineSkipCode:
  4765. prg.printEsc(strNumber( /* "baselineskip" */ 377))
  4766. case parSkipCode:
  4767. prg.printEsc(strNumber( /* "parskip" */ 378))
  4768. case aboveDisplaySkipCode:
  4769. prg.printEsc(strNumber( /* "abovedisplayskip" */ 379))
  4770. case belowDisplaySkipCode:
  4771. prg.printEsc(strNumber( /* "belowdisplayskip" */ 380))
  4772. case aboveDisplayShortSkipCode:
  4773. prg.printEsc(strNumber( /* "abovedisplayshortskip" */ 381))
  4774. case belowDisplayShortSkipCode:
  4775. prg.printEsc(strNumber( /* "belowdisplayshortskip" */ 382))
  4776. case leftSkipCode:
  4777. prg.printEsc(strNumber( /* "leftskip" */ 383))
  4778. case rightSkipCode:
  4779. prg.printEsc(strNumber( /* "rightskip" */ 384))
  4780. case topSkipCode:
  4781. prg.printEsc(strNumber( /* "topskip" */ 385))
  4782. case splitTopSkipCode:
  4783. prg.printEsc(strNumber( /* "splittopskip" */ 386))
  4784. case tabSkipCode:
  4785. prg.printEsc(strNumber( /* "tabskip" */ 387))
  4786. case spaceSkipCode:
  4787. prg.printEsc(strNumber( /* "spaceskip" */ 388))
  4788. case xspaceSkipCode:
  4789. prg.printEsc(strNumber( /* "xspaceskip" */ 389))
  4790. case parFillSkipCode:
  4791. prg.printEsc(strNumber( /* "parfillskip" */ 390))
  4792. case thinMuSkipCode:
  4793. prg.printEsc(strNumber( /* "thinmuskip" */ 391))
  4794. case medMuSkipCode:
  4795. prg.printEsc(strNumber( /* "medmuskip" */ 392))
  4796. case thickMuSkipCode:
  4797. prg.printEsc(strNumber( /* "thickmuskip" */ 393))
  4798. default:
  4799. prg.print( /* "[unknown glue parameter!]" */ 394)
  4800. }
  4801. }
  4802. // 180.
  4803. // tangle:pos tex.web:3644:3:
  4804. // Since boxes can be inside of boxes, |show_node_list| is inherently recursive,
  4805. // \xref[recursion]
  4806. // up to a given maximum number of levels. The history of nesting is indicated
  4807. // by the current string, which will be printed at the beginning of each line;
  4808. // the length of this string, namely |cur_length|, is the depth of nesting.
  4809. //
  4810. // Recursive calls on |show_node_list| therefore use the following pattern:
  4811. // 182.
  4812. // tangle:pos tex.web:3667:3:
  4813. // Now we are ready for |show_node_list| itself. This procedure has been
  4814. // written to be “extra robust” in the sense that it should not crash or get
  4815. // into a loop even if the data structures have been messed up by bugs in
  4816. // the rest of the program. You can safely call its parent routine
  4817. // |show_box(p)| for arbitrary values of |p| when you are debugging \TeX.
  4818. // However, in the presence of bad data, the procedure may
  4819. // \xref[dirty \PASCAL]\xref[debugging]
  4820. // fetch a |memory_word| whose variant is different from the way it was stored;
  4821. // for example, it might try to read |mem[p].hh| when |mem[p]|
  4822. // contains a scaled integer, if |p| is a pointer that has been
  4823. // clobbered or chosen at random.
  4824. func (prg *prg) showNodeList(p int32) {
  4825. var (
  4826. n int32 // the number of items already printed at this level
  4827. g float64 // a glue ratio, as a floating point number
  4828. )
  4829. if int32(prg.poolPtr)-int32(prg.strStart[prg.strPtr]) > prg.depthThreshold {
  4830. if p > 0 {
  4831. prg.print( /* " []" */ 314)
  4832. }
  4833. // indicate that there's been some truncation
  4834. // indicate that there's been some truncation
  4835. goto exit
  4836. }
  4837. n = 0
  4838. for p > memMin {
  4839. prg.printLn()
  4840. prg.printCurrentString() // display the nesting history
  4841. if p > int32(prg.memEnd) {
  4842. prg.print( /* "Bad link, display aborted." */ 315)
  4843. goto exit
  4844. // \xref[Bad link...]
  4845. }
  4846. n = n + 1
  4847. if n > prg.breadthMax {
  4848. prg.print( /* "etc." */ 316)
  4849. goto exit
  4850. // \xref[etc]
  4851. }
  4852. // Display node |p|
  4853. if p >= int32(prg.hiMemMin) {
  4854. prg.printFontAndChar(p)
  4855. } else {
  4856. switch *(*prg.mem[p].hh()).b0() {
  4857. case hlistNode, vlistNode, unsetNode:
  4858. // Display box |p|
  4859. if int32(*(*prg.mem[p].hh()).b0()) == hlistNode {
  4860. prg.printEsc(strNumber('h'))
  4861. } else if int32(*(*prg.mem[p].hh()).b0()) == vlistNode {
  4862. prg.printEsc(strNumber('v'))
  4863. } else {
  4864. prg.printEsc(strNumber( /* "unset" */ 318))
  4865. }
  4866. prg.print( /* "box(" */ 319)
  4867. prg.printScaled(*prg.mem[p+heightOffset].int())
  4868. prg.printChar(asciiCode('+'))
  4869. prg.printScaled(*prg.mem[p+depthOffset].int())
  4870. prg.print( /* ")x" */ 320)
  4871. prg.printScaled(*prg.mem[p+widthOffset].int())
  4872. if int32(*(*prg.mem[p].hh()).b0()) == unsetNode {
  4873. if int32(*(*prg.mem[p].hh()).b1()) != minQuarterword {
  4874. prg.print( /* " (" */ 286)
  4875. prg.printInt(int32(*(*prg.mem[p].hh()).b1()) - minQuarterword + 1)
  4876. prg.print( /* " columns)" */ 322)
  4877. }
  4878. if *prg.mem[p+glueOffset].int() != 0 {
  4879. prg.print( /* ", stretch " */ 323)
  4880. prg.printGlue(*prg.mem[p+glueOffset].int(), int32(*(*prg.mem[p+listOffset].hh()).b1()), strNumber(0))
  4881. }
  4882. if *prg.mem[p+4].int() != 0 {
  4883. prg.print( /* ", shrink " */ 324)
  4884. prg.printGlue(*prg.mem[p+4].int(), int32(*(*prg.mem[p+listOffset].hh()).b0()), strNumber(0))
  4885. }
  4886. } else {
  4887. g = float64(*prg.mem[p+glueOffset].gr())
  4888. if g != 0.0 && int32(*(*prg.mem[p+listOffset].hh()).b0()) != normal {
  4889. prg.print( /* ", glue set " */ 325)
  4890. if int32(*(*prg.mem[p+listOffset].hh()).b0()) == shrinking {
  4891. prg.print( /* "- " */ 326)
  4892. }
  4893. if abs(*prg.mem[p+glueOffset].int()) < 04000000 {
  4894. prg.print( /* "?.?" */ 327)
  4895. } else if fabs(g) > 20000.0 {
  4896. if g > 0.0 {
  4897. prg.printChar(asciiCode('>'))
  4898. } else {
  4899. prg.print( /* "< -" */ 328)
  4900. }
  4901. prg.printGlue(20000*0200000, int32(*(*prg.mem[p+listOffset].hh()).b1()), strNumber(0))
  4902. } else {
  4903. prg.printGlue(round(float64(0200000)*g), int32(*(*prg.mem[p+listOffset].hh()).b1()), strNumber(0))
  4904. }
  4905. // \xref[real multiplication]
  4906. }
  4907. if *prg.mem[p+4].int() != 0 {
  4908. prg.print( /* ", shifted " */ 321)
  4909. prg.printScaled(*prg.mem[p+4].int())
  4910. }
  4911. }
  4912. {
  4913. {
  4914. prg.strPool[prg.poolPtr] = '.'
  4915. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  4916. }
  4917. prg.showNodeList(int32(*(*prg.mem[p+listOffset].hh()).rh()))
  4918. prg.poolPtr = uint16(int32(prg.poolPtr) - 1)
  4919. } // recursive call
  4920. case ruleNode:
  4921. // Display rule |p|
  4922. prg.printEsc(strNumber( /* "rule(" */ 329))
  4923. prg.printRuleDimen(*prg.mem[p+heightOffset].int())
  4924. prg.printChar(asciiCode('+'))
  4925. prg.printRuleDimen(*prg.mem[p+depthOffset].int())
  4926. prg.print( /* ")x" */ 320)
  4927. prg.printRuleDimen(*prg.mem[p+widthOffset].int())
  4928. case insNode:
  4929. // Display insertion |p|
  4930. prg.printEsc(strNumber( /* "insert" */ 330))
  4931. prg.printInt(int32(*(*prg.mem[p].hh()).b1()) - minQuarterword)
  4932. prg.print( /* ", natural size " */ 331)
  4933. prg.printScaled(*prg.mem[p+heightOffset].int())
  4934. prg.print( /* "; split(" */ 332)
  4935. prg.printSpec(int32(*(*prg.mem[p+4].hh()).rh()), strNumber(0))
  4936. prg.printChar(asciiCode(','))
  4937. prg.printScaled(*prg.mem[p+depthOffset].int())
  4938. prg.print( /* "); float cost " */ 333)
  4939. prg.printInt(*prg.mem[p+1].int())
  4940. {
  4941. {
  4942. prg.strPool[prg.poolPtr] = '.'
  4943. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  4944. }
  4945. prg.showNodeList(int32(*(*prg.mem[p+4].hh()).lh()))
  4946. prg.poolPtr = uint16(int32(prg.poolPtr) - 1)
  4947. } // recursive call
  4948. case whatsitNode:
  4949. // Display the whatsit node |p|
  4950. switch *(*prg.mem[p].hh()).b1() {
  4951. case openNode:
  4952. prg.printWriteWhatsit(strNumber( /* "openout" */ 1285), halfword(p))
  4953. prg.printChar(asciiCode('='))
  4954. prg.printFileName(int32(*(*prg.mem[p+1].hh()).rh()), int32(*(*prg.mem[p+2].hh()).lh()), int32(*(*prg.mem[p+2].hh()).rh()))
  4955. case writeNode:
  4956. prg.printWriteWhatsit(strNumber( /* "write" */ 594), halfword(p))
  4957. prg.printMark(int32(*(*prg.mem[p+1].hh()).rh()))
  4958. case closeNode:
  4959. prg.printWriteWhatsit(strNumber( /* "closeout" */ 1286), halfword(p))
  4960. case specialNode:
  4961. prg.printEsc(strNumber( /* "special" */ 1287))
  4962. prg.printMark(int32(*(*prg.mem[p+1].hh()).rh()))
  4963. case languageNode:
  4964. prg.printEsc(strNumber( /* "setlanguage" */ 1289))
  4965. prg.printInt(int32(*(*prg.mem[p+1].hh()).rh()))
  4966. prg.print( /* " (hyphenmin " */ 1292)
  4967. prg.printInt(int32(*(*prg.mem[p+1].hh()).b0()))
  4968. prg.printChar(asciiCode(','))
  4969. prg.printInt(int32(*(*prg.mem[p+1].hh()).b1()))
  4970. prg.printChar(asciiCode(')'))
  4971. default:
  4972. prg.print( /* "whatsit?" */ 1293)
  4973. }
  4974. case glueNode:
  4975. // Display glue |p|
  4976. if int32(*(*prg.mem[p].hh()).b1()) >= aLeaders {
  4977. prg.printEsc(strNumber( /* "" */ 338))
  4978. if int32(*(*prg.mem[p].hh()).b1()) == cLeaders {
  4979. prg.printChar(asciiCode('c'))
  4980. } else if int32(*(*prg.mem[p].hh()).b1()) == xLeaders {
  4981. prg.printChar(asciiCode('x'))
  4982. }
  4983. prg.print( /* "leaders " */ 339)
  4984. prg.printSpec(int32(*(*prg.mem[p+1].hh()).lh()), strNumber(0))
  4985. {
  4986. {
  4987. prg.strPool[prg.poolPtr] = '.'
  4988. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  4989. }
  4990. prg.showNodeList(int32(*(*prg.mem[p+1].hh()).rh()))
  4991. prg.poolPtr = uint16(int32(prg.poolPtr) - 1)
  4992. } // recursive call
  4993. } else {
  4994. prg.printEsc(strNumber( /* "glue" */ 334))
  4995. if int32(*(*prg.mem[p].hh()).b1()) != normal {
  4996. prg.printChar(asciiCode('('))
  4997. if int32(*(*prg.mem[p].hh()).b1()) < condMathGlue {
  4998. prg.printSkipParam(int32(*(*prg.mem[p].hh()).b1()) - 1)
  4999. } else if int32(*(*prg.mem[p].hh()).b1()) == condMathGlue {
  5000. prg.printEsc(strNumber( /* "nonscript" */ 335))
  5001. } else {
  5002. prg.printEsc(strNumber( /* "mskip" */ 336))
  5003. }
  5004. prg.printChar(asciiCode(')'))
  5005. }
  5006. if int32(*(*prg.mem[p].hh()).b1()) != condMathGlue {
  5007. prg.printChar(asciiCode(' '))
  5008. if int32(*(*prg.mem[p].hh()).b1()) < condMathGlue {
  5009. prg.printSpec(int32(*(*prg.mem[p+1].hh()).lh()), strNumber(0))
  5010. } else {
  5011. prg.printSpec(int32(*(*prg.mem[p+1].hh()).lh()), strNumber( /* "mu" */ 337))
  5012. }
  5013. }
  5014. }
  5015. case kernNode:
  5016. // Display kern |p|
  5017. if int32(*(*prg.mem[p].hh()).b1()) != muGlue {
  5018. prg.printEsc(strNumber( /* "kern" */ 340))
  5019. if int32(*(*prg.mem[p].hh()).b1()) != normal {
  5020. prg.printChar(asciiCode(' '))
  5021. }
  5022. prg.printScaled(*prg.mem[p+widthOffset].int())
  5023. if int32(*(*prg.mem[p].hh()).b1()) == accKern {
  5024. prg.print( /* " (for accent)" */ 341)
  5025. }
  5026. // \xref[for accent]
  5027. } else {
  5028. prg.printEsc(strNumber( /* "mkern" */ 342))
  5029. prg.printScaled(*prg.mem[p+widthOffset].int())
  5030. prg.print( /* "mu" */ 337)
  5031. }
  5032. case mathNode:
  5033. // Display math node |p|
  5034. prg.printEsc(strNumber( /* "math" */ 343))
  5035. if int32(*(*prg.mem[p].hh()).b1()) == before {
  5036. prg.print( /* "on" */ 344)
  5037. } else {
  5038. prg.print( /* "off" */ 345)
  5039. }
  5040. if *prg.mem[p+widthOffset].int() != 0 {
  5041. prg.print( /* ", surrounded " */ 346)
  5042. prg.printScaled(*prg.mem[p+widthOffset].int())
  5043. }
  5044. case ligatureNode:
  5045. // Display ligature |p|
  5046. prg.printFontAndChar(p + 1)
  5047. prg.print( /* " (ligature " */ 347)
  5048. if int32(*(*prg.mem[p].hh()).b1()) > 1 {
  5049. prg.printChar(asciiCode('|'))
  5050. }
  5051. prg.fontInShortDisplay = int32(*(*prg.mem[p+1].hh()).b0())
  5052. prg.shortDisplay(int32(*(*prg.mem[p+1].hh()).rh()))
  5053. if *(*prg.mem[p].hh()).b1()&1 != 0 {
  5054. prg.printChar(asciiCode('|'))
  5055. }
  5056. prg.printChar(asciiCode(')'))
  5057. case penaltyNode:
  5058. // Display penalty |p|
  5059. prg.printEsc(strNumber( /* "penalty " */ 348))
  5060. prg.printInt(*prg.mem[p+1].int())
  5061. case discNode:
  5062. // Display discretionary |p|
  5063. prg.printEsc(strNumber( /* "discretionary" */ 349))
  5064. if int32(*(*prg.mem[p].hh()).b1()) > 0 {
  5065. prg.print( /* " replacing " */ 350)
  5066. prg.printInt(int32(*(*prg.mem[p].hh()).b1()))
  5067. }
  5068. {
  5069. {
  5070. prg.strPool[prg.poolPtr] = '.'
  5071. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  5072. }
  5073. prg.showNodeList(int32(*(*prg.mem[p+1].hh()).lh()))
  5074. prg.poolPtr = uint16(int32(prg.poolPtr) - 1)
  5075. } // recursive call
  5076. {
  5077. prg.strPool[prg.poolPtr] = '|'
  5078. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  5079. }
  5080. prg.showNodeList(int32(*(*prg.mem[p+1].hh()).rh()))
  5081. prg.poolPtr = uint16(int32(prg.poolPtr) - 1) // recursive call
  5082. case markNode:
  5083. // Display mark |p|
  5084. prg.printEsc(strNumber( /* "mark" */ 351))
  5085. prg.printMark(*prg.mem[p+1].int())
  5086. case adjustNode:
  5087. // Display adjustment |p|
  5088. prg.printEsc(strNumber( /* "vadjust" */ 352))
  5089. {
  5090. {
  5091. prg.strPool[prg.poolPtr] = '.'
  5092. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  5093. }
  5094. prg.showNodeList(*prg.mem[p+1].int())
  5095. prg.poolPtr = uint16(int32(prg.poolPtr) - 1)
  5096. } // recursive call
  5097. // \4
  5098. // Cases of |show_node_list| that arise in mlists only
  5099. case styleNode:
  5100. prg.printStyle(int32(*(*prg.mem[p].hh()).b1()))
  5101. case choiceNode:
  5102. // Display choice node |p|
  5103. prg.printEsc(strNumber( /* "mathchoice" */ 525))
  5104. {
  5105. prg.strPool[prg.poolPtr] = 'D'
  5106. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  5107. }
  5108. prg.showNodeList(int32(*(*prg.mem[p+1].hh()).lh()))
  5109. prg.poolPtr = uint16(int32(prg.poolPtr) - 1)
  5110. {
  5111. prg.strPool[prg.poolPtr] = 'T'
  5112. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  5113. }
  5114. prg.showNodeList(int32(*(*prg.mem[p+1].hh()).rh()))
  5115. prg.poolPtr = uint16(int32(prg.poolPtr) - 1)
  5116. {
  5117. prg.strPool[prg.poolPtr] = 'S'
  5118. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  5119. }
  5120. prg.showNodeList(int32(*(*prg.mem[p+2].hh()).lh()))
  5121. prg.poolPtr = uint16(int32(prg.poolPtr) - 1)
  5122. {
  5123. prg.strPool[prg.poolPtr] = 's'
  5124. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  5125. }
  5126. prg.showNodeList(int32(*(*prg.mem[p+2].hh()).rh()))
  5127. prg.poolPtr = uint16(int32(prg.poolPtr) - 1)
  5128. case ordNoad, opNoad, binNoad, relNoad,
  5129. openNoad, closeNoad, punctNoad, innerNoad,
  5130. radicalNoad, overNoad, underNoad, vcenterNoad,
  5131. accentNoad, leftNoad, rightNoad:
  5132. // Display normal noad |p|
  5133. switch *(*prg.mem[p].hh()).b0() {
  5134. case ordNoad:
  5135. prg.printEsc(strNumber( /* "mathord" */ 866))
  5136. case opNoad:
  5137. prg.printEsc(strNumber( /* "mathop" */ 867))
  5138. case binNoad:
  5139. prg.printEsc(strNumber( /* "mathbin" */ 868))
  5140. case relNoad:
  5141. prg.printEsc(strNumber( /* "mathrel" */ 869))
  5142. case openNoad:
  5143. prg.printEsc(strNumber( /* "mathopen" */ 870))
  5144. case closeNoad:
  5145. prg.printEsc(strNumber( /* "mathclose" */ 871))
  5146. case punctNoad:
  5147. prg.printEsc(strNumber( /* "mathpunct" */ 872))
  5148. case innerNoad:
  5149. prg.printEsc(strNumber( /* "mathinner" */ 873))
  5150. case overNoad:
  5151. prg.printEsc(strNumber( /* "overline" */ 874))
  5152. case underNoad:
  5153. prg.printEsc(strNumber( /* "underline" */ 875))
  5154. case vcenterNoad:
  5155. prg.printEsc(strNumber( /* "vcenter" */ 539))
  5156. case radicalNoad:
  5157. prg.printEsc(strNumber( /* "radical" */ 533))
  5158. prg.printDelimiter(halfword(p + 4))
  5159. case accentNoad:
  5160. prg.printEsc(strNumber( /* "accent" */ 508))
  5161. prg.printFamAndChar(halfword(p + 4))
  5162. case leftNoad:
  5163. prg.printEsc(strNumber( /* "left" */ 876))
  5164. prg.printDelimiter(halfword(p + 1))
  5165. case rightNoad:
  5166. prg.printEsc(strNumber( /* "right" */ 877))
  5167. prg.printDelimiter(halfword(p + 1))
  5168. }
  5169. if int32(*(*prg.mem[p].hh()).b1()) != normal {
  5170. if int32(*(*prg.mem[p].hh()).b1()) == limits {
  5171. prg.printEsc(strNumber( /* "limits" */ 878))
  5172. } else {
  5173. prg.printEsc(strNumber( /* "nolimits" */ 879))
  5174. }
  5175. }
  5176. if int32(*(*prg.mem[p].hh()).b0()) < leftNoad {
  5177. prg.printSubsidiaryData(halfword(p+1), asciiCode('.'))
  5178. }
  5179. prg.printSubsidiaryData(halfword(p+2), asciiCode('^'))
  5180. prg.printSubsidiaryData(halfword(p+3), asciiCode('_'))
  5181. case fractionNoad:
  5182. // Display fraction noad |p|
  5183. prg.printEsc(strNumber( /* "fraction, thickness " */ 880))
  5184. if *prg.mem[p+widthOffset].int() == 010000000000 {
  5185. prg.print( /* "= default" */ 881)
  5186. } else {
  5187. prg.printScaled(*prg.mem[p+widthOffset].int())
  5188. }
  5189. if int32((*prg.mem[p+4].qqqq()).b0) != 0 || int32((*prg.mem[p+4].qqqq()).b1) != minQuarterword || int32((*prg.mem[p+4].qqqq()).b2) != 0 || int32((*prg.mem[p+4].qqqq()).b3) != minQuarterword {
  5190. prg.print( /* ", left-delimiter " */ 882)
  5191. prg.printDelimiter(halfword(p + 4))
  5192. }
  5193. if int32((*prg.mem[p+5].qqqq()).b0) != 0 || int32((*prg.mem[p+5].qqqq()).b1) != minQuarterword || int32((*prg.mem[p+5].qqqq()).b2) != 0 || int32((*prg.mem[p+5].qqqq()).b3) != minQuarterword {
  5194. prg.print( /* ", right-delimiter " */ 883)
  5195. prg.printDelimiter(halfword(p + 5))
  5196. }
  5197. prg.printSubsidiaryData(halfword(p+2), asciiCode('\\'))
  5198. prg.printSubsidiaryData(halfword(p+3), asciiCode('/'))
  5199. default:
  5200. prg.print( /* "Unknown node type!" */ 317)
  5201. }
  5202. }
  5203. p = int32(*(*prg.mem[p].hh()).rh())
  5204. }
  5205. exit:
  5206. }
  5207. // 198.
  5208. // tangle:pos tex.web:3872:3:
  5209. // The recursive machinery is started by calling |show_box|.
  5210. // \xref[recursion]
  5211. func (prg *prg) showBox(p halfword) {
  5212. prg.depthThreshold = *prg.eqtb[intBase+showBoxDepthCode-1].int()
  5213. prg.breadthMax = *prg.eqtb[intBase+showBoxBreadthCode-1].int()
  5214. if prg.breadthMax <= 0 {
  5215. prg.breadthMax = 5
  5216. }
  5217. if int32(prg.poolPtr)+prg.depthThreshold >= poolSize {
  5218. prg.depthThreshold = poolSize - int32(prg.poolPtr) - 1
  5219. }
  5220. // now there's enough room for prefix string
  5221. prg.showNodeList(int32(p)) // the show starts at |p|
  5222. prg.printLn()
  5223. }
  5224. // 199. \[13] Destroying boxes
  5225. // tangle:pos tex.web:3886:27:
  5226. // When we are done with a node list, we are obliged to return it to free
  5227. // storage, including all of its sublists. The recursive procedure
  5228. // |flush_node_list| does this for us.
  5229. // 200.
  5230. // tangle:pos tex.web:3891:3:
  5231. // First, however, we shall consider two non-recursive procedures that do
  5232. // simpler tasks. The first of these, |delete_token_ref|, is called when
  5233. // a pointer to a token list's reference count is being removed. This means
  5234. // that the token list should disappear if the reference count was |null|,
  5235. // otherwise the count should be decreased by one.
  5236. // \xref[reference counts]
  5237. func (prg *prg) deleteTokenRef(p halfword) {
  5238. if int32(*(*prg.mem[p].hh()).lh()) == 0 {
  5239. prg.flushList(p)
  5240. } else {
  5241. *(*prg.mem[p].hh()).lh() = uint16(int32(*(*prg.mem[p].hh()).lh()) - 1)
  5242. }
  5243. }
  5244. // 201.
  5245. // tangle:pos tex.web:3906:3:
  5246. // Similarly, |delete_glue_ref| is called when a pointer to a glue
  5247. // specification is being withdrawn.
  5248. // \xref[reference counts]
  5249. func (prg *prg) deleteGlueRef(p halfword) {
  5250. if int32(*(*prg.mem[p].hh()).rh()) == 0 {
  5251. prg.freeNode(p, halfword(glueSpecSize))
  5252. } else {
  5253. *(*prg.mem[p].hh()).rh() = uint16(int32(*(*prg.mem[p].hh()).rh()) - 1)
  5254. }
  5255. }
  5256. // 202.
  5257. // tangle:pos tex.web:3917:3:
  5258. // Now we are ready to delete any node list, recursively.
  5259. // In practice, the nodes deleted are usually charnodes (about 2/3 of the time),
  5260. // and they are glue nodes in about half of the remaining cases.
  5261. // \xref[recursion]
  5262. func (prg *prg) flushNodeList(p halfword) { // go here when node |p| has been freed
  5263. var (
  5264. q halfword // successor to node |p|
  5265. )
  5266. for int32(p) != 0 {
  5267. // \xref[inner loop]
  5268. q = *(*prg.mem[p].hh()).rh()
  5269. if int32(p) >= int32(prg.hiMemMin) {
  5270. *(*prg.mem[p].hh()).rh() = prg.avail
  5271. prg.avail = p /* dyn_used:= dyn_used-1 ; [ ] */
  5272. } else {
  5273. switch *(*prg.mem[p].hh()).b0() {
  5274. case hlistNode, vlistNode, unsetNode:
  5275. prg.flushNodeList(*(*prg.mem[int32(p)+listOffset].hh()).rh())
  5276. prg.freeNode(p, halfword(boxNodeSize))
  5277. goto done
  5278. case ruleNode:
  5279. prg.freeNode(p, halfword(ruleNodeSize))
  5280. goto done
  5281. case insNode:
  5282. prg.flushNodeList(*(*prg.mem[int32(p)+4].hh()).lh())
  5283. prg.deleteGlueRef(*(*prg.mem[int32(p)+4].hh()).rh())
  5284. prg.freeNode(p, halfword(insNodeSize))
  5285. goto done
  5286. case whatsitNode:
  5287. // Wipe out the whatsit node |p| and |goto done|
  5288. switch *(*prg.mem[p].hh()).b1() {
  5289. case openNode:
  5290. prg.freeNode(p, halfword(openNodeSize))
  5291. case writeNode, specialNode:
  5292. prg.deleteTokenRef(*(*prg.mem[int32(p)+1].hh()).rh())
  5293. prg.freeNode(p, halfword(writeNodeSize))
  5294. goto done
  5295. case closeNode, languageNode:
  5296. prg.freeNode(p, halfword(smallNodeSize))
  5297. default:
  5298. prg.confusion(strNumber( /* "ext3" */ 1295))
  5299. // \xref[this can't happen ext3][\quad ext3]
  5300. }
  5301. goto done
  5302. case glueNode:
  5303. {
  5304. if int32(*(*prg.mem[*(*prg.mem[int32(p)+1].hh()).lh()].hh()).rh()) == 0 {
  5305. prg.freeNode(*(*prg.mem[int32(p)+1].hh()).lh(), halfword(glueSpecSize))
  5306. } else {
  5307. *(*prg.mem[*(*prg.mem[int32(p)+1].hh()).lh()].hh()).rh() = uint16(int32(*(*prg.mem[*(*prg.mem[int32(p)+1].hh()).lh()].hh()).rh()) - 1)
  5308. }
  5309. }
  5310. if int32(*(*prg.mem[int32(p)+1].hh()).rh()) != 0 {
  5311. prg.flushNodeList(*(*prg.mem[int32(p)+1].hh()).rh())
  5312. }
  5313. case kernNode, mathNode, penaltyNode:
  5314. case ligatureNode:
  5315. prg.flushNodeList(*(*prg.mem[int32(p)+1].hh()).rh())
  5316. case markNode:
  5317. prg.deleteTokenRef(halfword(*prg.mem[int32(p)+1].int()))
  5318. case discNode:
  5319. prg.flushNodeList(*(*prg.mem[int32(p)+1].hh()).lh())
  5320. prg.flushNodeList(*(*prg.mem[int32(p)+1].hh()).rh())
  5321. case adjustNode:
  5322. prg.flushNodeList(halfword(*prg.mem[int32(p)+1].int()))
  5323. // \4
  5324. // Cases of |flush_node_list| that arise in mlists only
  5325. case styleNode:
  5326. prg.freeNode(p, halfword(styleNodeSize))
  5327. goto done
  5328. case choiceNode:
  5329. prg.flushNodeList(*(*prg.mem[int32(p)+1].hh()).lh())
  5330. prg.flushNodeList(*(*prg.mem[int32(p)+1].hh()).rh())
  5331. prg.flushNodeList(*(*prg.mem[int32(p)+2].hh()).lh())
  5332. prg.flushNodeList(*(*prg.mem[int32(p)+2].hh()).rh())
  5333. prg.freeNode(p, halfword(styleNodeSize))
  5334. goto done
  5335. case ordNoad, opNoad, binNoad, relNoad,
  5336. openNoad, closeNoad, punctNoad, innerNoad,
  5337. radicalNoad, overNoad, underNoad, vcenterNoad,
  5338. accentNoad: //
  5339. if int32(*(*prg.mem[int32(p)+1].hh()).rh()) >= subBox {
  5340. prg.flushNodeList(*(*prg.mem[int32(p)+1].hh()).lh())
  5341. }
  5342. if int32(*(*prg.mem[int32(p)+2].hh()).rh()) >= subBox {
  5343. prg.flushNodeList(*(*prg.mem[int32(p)+2].hh()).lh())
  5344. }
  5345. if int32(*(*prg.mem[int32(p)+3].hh()).rh()) >= subBox {
  5346. prg.flushNodeList(*(*prg.mem[int32(p)+3].hh()).lh())
  5347. }
  5348. if int32(*(*prg.mem[p].hh()).b0()) == radicalNoad {
  5349. prg.freeNode(p, halfword(radicalNoadSize))
  5350. } else if int32(*(*prg.mem[p].hh()).b0()) == accentNoad {
  5351. prg.freeNode(p, halfword(accentNoadSize))
  5352. } else {
  5353. prg.freeNode(p, halfword(noadSize))
  5354. }
  5355. goto done
  5356. case leftNoad, rightNoad:
  5357. prg.freeNode(p, halfword(noadSize))
  5358. goto done
  5359. case fractionNoad:
  5360. prg.flushNodeList(*(*prg.mem[int32(p)+2].hh()).lh())
  5361. prg.flushNodeList(*(*prg.mem[int32(p)+3].hh()).lh())
  5362. prg.freeNode(p, halfword(fractionNoadSize))
  5363. goto done
  5364. default:
  5365. prg.confusion(strNumber( /* "flushing" */ 353))
  5366. // \xref[this can't happen flushing][\quad flushing]
  5367. }
  5368. prg.freeNode(p, halfword(smallNodeSize))
  5369. done:
  5370. }
  5371. p = q
  5372. }
  5373. }
  5374. // 203. \[14] Copying boxes
  5375. // tangle:pos tex.web:3960:24:
  5376. // Another recursive operation that acts on boxes is sometimes needed: The
  5377. // procedure |copy_node_list| returns a pointer to another node list that has
  5378. // the same structure and meaning as the original. Note that since glue
  5379. // specifications and token lists have reference counts, we need not make
  5380. // copies of them. Reference counts can never get too large to fit in a
  5381. // halfword, since each pointer to a node is in a different memory address,
  5382. // and the total number of memory addresses fits in a halfword.
  5383. // \xref[recursion]
  5384. // \xref[reference counts]
  5385. //
  5386. // (Well, there actually are also references from outside |mem|; if the
  5387. // |save_stack| is made arbitrarily large, it would theoretically be possible
  5388. // to break \TeX\ by overflowing a reference count. But who would want to do that?)
  5389. // 204.
  5390. // tangle:pos tex.web:3978:3:
  5391. // The copying procedure copies words en masse without bothering
  5392. // to look at their individual fields. If the node format changes---for
  5393. // example, if the size is altered, or if some link field is moved to another
  5394. // relative position---then this code may need to be changed too.
  5395. // \xref[data structure assumptions]
  5396. func (prg *prg) copyNodeList(p halfword) (r halfword) { // makes a duplicate of the
  5397. // node list that starts at |p| and returns a pointer to the new list
  5398. var (
  5399. h halfword // temporary head of copied list
  5400. q halfword // previous position in new list
  5401. r1 halfword // current node being fabricated for new list
  5402. words/* 0..5 */ byte // number of words remaining to be copied
  5403. )
  5404. h = prg.getAvail()
  5405. q = h
  5406. for int32(p) != 0 {
  5407. words = 1 // this setting occurs in more branches than any other
  5408. if int32(p) >= int32(prg.hiMemMin) {
  5409. r1 = prg.getAvail()
  5410. } else {
  5411. // Case statement to copy different types and set |words| to the number of initial words not yet copied
  5412. switch *(*prg.mem[p].hh()).b0() {
  5413. case hlistNode, vlistNode, unsetNode:
  5414. r1 = prg.getNode(boxNodeSize)
  5415. prg.mem[int32(r1)+6] = prg.mem[int32(p)+6]
  5416. prg.mem[int32(r1)+5] = prg.mem[int32(p)+5] // copy the last two words
  5417. *(*prg.mem[int32(r1)+listOffset].hh()).rh() = prg.copyNodeList(*(*prg.mem[int32(p)+listOffset].hh()).rh()) // this affects |mem[r+5]|
  5418. words = 5
  5419. case ruleNode:
  5420. r1 = prg.getNode(ruleNodeSize)
  5421. words = byte(ruleNodeSize)
  5422. case insNode:
  5423. r1 = prg.getNode(insNodeSize)
  5424. prg.mem[int32(r1)+4] = prg.mem[int32(p)+4]
  5425. *(*prg.mem[*(*prg.mem[int32(p)+4].hh()).rh()].hh()).rh() = uint16(int32(*(*prg.mem[*(*prg.mem[int32(p)+4].hh()).rh()].hh()).rh()) + 1)
  5426. *(*prg.mem[int32(r1)+4].hh()).lh() = prg.copyNodeList(*(*prg.mem[int32(p)+4].hh()).lh()) // this affects |mem[r+4]|
  5427. words = byte(insNodeSize - 1)
  5428. case whatsitNode:
  5429. // Make a partial copy of the whatsit node |p| and make |r| point to it; set |words| to the number of initial words not yet copied
  5430. switch *(*prg.mem[p].hh()).b1() {
  5431. case openNode:
  5432. r1 = prg.getNode(openNodeSize)
  5433. words = byte(openNodeSize)
  5434. case writeNode, specialNode:
  5435. r1 = prg.getNode(writeNodeSize)
  5436. *(*prg.mem[*(*prg.mem[int32(p)+1].hh()).rh()].hh()).lh() = uint16(int32(*(*prg.mem[*(*prg.mem[int32(p)+1].hh()).rh()].hh()).lh()) + 1)
  5437. words = byte(writeNodeSize)
  5438. case closeNode, languageNode:
  5439. r1 = prg.getNode(smallNodeSize)
  5440. words = byte(smallNodeSize)
  5441. default:
  5442. prg.confusion(strNumber( /* "ext2" */ 1294))
  5443. // \xref[this can't happen ext2][\quad ext2]
  5444. }
  5445. case glueNode:
  5446. r1 = prg.getNode(smallNodeSize)
  5447. *(*prg.mem[*(*prg.mem[int32(p)+1].hh()).lh()].hh()).rh() = uint16(int32(*(*prg.mem[*(*prg.mem[int32(p)+1].hh()).lh()].hh()).rh()) + 1)
  5448. *(*prg.mem[int32(r1)+1].hh()).lh() = *(*prg.mem[int32(p)+1].hh()).lh()
  5449. *(*prg.mem[int32(r1)+1].hh()).rh() = prg.copyNodeList(*(*prg.mem[int32(p)+1].hh()).rh())
  5450. case kernNode, mathNode, penaltyNode:
  5451. r1 = prg.getNode(smallNodeSize)
  5452. words = byte(smallNodeSize)
  5453. case ligatureNode:
  5454. r1 = prg.getNode(smallNodeSize)
  5455. prg.mem[int32(r1)+1] = prg.mem[int32(p)+1] // copy |font| and |character|
  5456. *(*prg.mem[int32(r1)+1].hh()).rh() = prg.copyNodeList(*(*prg.mem[int32(p)+1].hh()).rh())
  5457. case discNode:
  5458. r1 = prg.getNode(smallNodeSize)
  5459. *(*prg.mem[int32(r1)+1].hh()).lh() = prg.copyNodeList(*(*prg.mem[int32(p)+1].hh()).lh())
  5460. *(*prg.mem[int32(r1)+1].hh()).rh() = prg.copyNodeList(*(*prg.mem[int32(p)+1].hh()).rh())
  5461. case markNode:
  5462. r1 = prg.getNode(smallNodeSize)
  5463. *(*prg.mem[*prg.mem[int32(p)+1].int()].hh()).lh() = uint16(int32(*(*prg.mem[*prg.mem[int32(p)+1].int()].hh()).lh()) + 1)
  5464. words = byte(smallNodeSize)
  5465. case adjustNode:
  5466. r1 = prg.getNode(smallNodeSize)
  5467. *prg.mem[int32(r1)+1].int() = int32(prg.copyNodeList(halfword(*prg.mem[int32(p)+1].int())))
  5468. // |words=1=small_node_size-1|
  5469. default:
  5470. prg.confusion(strNumber( /* "copying" */ 354))
  5471. // \xref[this can't happen copying][\quad copying]
  5472. }
  5473. }
  5474. for int32(words) > 0 {
  5475. words = byte(int32(words) - 1)
  5476. prg.mem[int32(r1)+int32(words)] = prg.mem[int32(p)+int32(words)]
  5477. }
  5478. *(*prg.mem[q].hh()).rh() = r1
  5479. q = r1
  5480. p = *(*prg.mem[p].hh()).rh()
  5481. }
  5482. *(*prg.mem[q].hh()).rh() = 0
  5483. q = *(*prg.mem[h].hh()).rh()
  5484. {
  5485. *(*prg.mem[h].hh()).rh() = prg.avail
  5486. prg.avail = h /* dyn_used:= dyn_used-1 ; [ ] */
  5487. }
  5488. r = q
  5489. return r
  5490. }
  5491. // 207. \[15] The command codes
  5492. // tangle:pos tex.web:4048:28:
  5493. // Before we can go any further, we need to define symbolic names for the internal
  5494. // code numbers that represent the various commands obeyed by \TeX. These codes
  5495. // are somewhat arbitrary, but not completely so. For example, the command
  5496. // codes for character types are fixed by the language, since a user says,
  5497. // e.g., `\.[\\catcode \`\\\$[] = 3]' to make \.[\char'44] a math delimiter,
  5498. // and the command code |math_shift| is equal to~3. Some other codes have
  5499. // been made adjacent so that |case| statements in the program need not consider
  5500. // cases that are widely spaced, or so that |case| statements can be replaced
  5501. // by |if| statements.
  5502. //
  5503. // At any rate, here is the list, for future reference. First come the
  5504. // ``catcode'' commands, several of which share their numeric codes with
  5505. // ordinary commands when the catcode cannot emerge from \TeX's scanning routine.
  5506. // 208.
  5507. // tangle:pos tex.web:4090:3:
  5508. // Next are the ordinary run-of-the-mill command codes. Codes that are
  5509. // |min_internal| or more represent internal quantities that might be
  5510. // expanded by `\.[\\the]'.
  5511. // 209.
  5512. // tangle:pos tex.web:4154:3:
  5513. // The next codes are special; they all relate to mode-independent
  5514. // assignment of values to \TeX's internal registers or tables.
  5515. // Codes that are |max_internal| or less represent internal quantities
  5516. // that might be expanded by `\.[\\the]'.
  5517. // 210.
  5518. // tangle:pos tex.web:4194:3:
  5519. // The remaining command codes are extra special, since they cannot get through
  5520. // \TeX's scanner to the main control routine. They have been given values higher
  5521. // than |max_command| so that their special nature is easily discernible.
  5522. // The ``expandable'' commands come first.
  5523. // 211. \[16] The semantic nest
  5524. // tangle:pos tex.web:4220:28:
  5525. // \TeX\ is typically in the midst of building many lists at once. For example,
  5526. // when a math formula is being processed, \TeX\ is in math mode and
  5527. // working on an mlist; this formula has temporarily interrupted \TeX\ from
  5528. // being in horizontal mode and building the hlist of a paragraph; and this
  5529. // paragraph has temporarily interrupted \TeX\ from being in vertical mode
  5530. // and building the vlist for the next page of a document. Similarly, when a
  5531. // \.[\\vbox] occurs inside of an \.[\\hbox], \TeX\ is temporarily
  5532. // interrupted from working in restricted horizontal mode, and it enters
  5533. // internal vertical mode. The “semantic nest” is a stack that
  5534. // keeps track of what lists and modes are currently suspended.
  5535. //
  5536. // At each level of processing we are in one of six modes:
  5537. //
  5538. // \yskip\hang|vmode| stands for vertical mode (the page builder);
  5539. //
  5540. // \hang|hmode| stands for horizontal mode (the paragraph builder);
  5541. //
  5542. // \hang|mmode| stands for displayed formula mode;
  5543. //
  5544. // \hang|-vmode| stands for internal vertical mode (e.g., in a \.[\\vbox]);
  5545. //
  5546. // \hang|-hmode| stands for restricted horizontal mode (e.g., in an \.[\\hbox]);
  5547. //
  5548. // \hang|-mmode| stands for math formula mode (not displayed).
  5549. //
  5550. // \yskip\noindent The mode is temporarily set to zero while processing \.[\\write]
  5551. // texts.
  5552. //
  5553. // Numeric values are assigned to |vmode|, |hmode|, and |mmode| so that
  5554. // \TeX's “big semantic switch” can select the appropriate thing to
  5555. // do by computing the value |abs(mode)+cur_cmd|, where |mode| is the current
  5556. // mode and |cur_cmd| is the current command code.
  5557. func (prg *prg) printMode(m int32) {
  5558. if m > 0 {
  5559. switch m / (maxCommand + 1) {
  5560. case 0:
  5561. prg.print( /* "vertical" */ 355)
  5562. case 1:
  5563. prg.print( /* "horizontal" */ 356)
  5564. case 2:
  5565. prg.print( /* "display math" */ 357)
  5566. }
  5567. } else if m == 0 {
  5568. prg.print( /* "no" */ 358)
  5569. } else {
  5570. switch -m / (maxCommand + 1) {
  5571. case 0:
  5572. prg.print( /* "internal vertical" */ 359)
  5573. case 1:
  5574. prg.print( /* "restricted horizontal" */ 360)
  5575. case 2:
  5576. prg.print( /* "math" */ 343)
  5577. }
  5578. }
  5579. prg.print( /* " mode" */ 361)
  5580. }
  5581. // 214.
  5582. // tangle:pos tex.web:4348:3:
  5583. // Here is a common way to make the current list grow:
  5584. // 216.
  5585. // tangle:pos tex.web:4368:3:
  5586. // When \TeX's work on one level is interrupted, the state is saved by
  5587. // calling |push_nest|. This routine changes |head| and |tail| so that
  5588. // a new (empty) list is begun; it does not change |mode| or |aux|.
  5589. func (prg *prg) pushNest() {
  5590. if int32(prg.nestPtr) > int32(prg.maxNestStack) {
  5591. prg.maxNestStack = prg.nestPtr
  5592. if int32(prg.nestPtr) == nestSize {
  5593. prg.overflow(strNumber( /* "semantic nest size" */ 362), nestSize)
  5594. }
  5595. // \xref[TeX capacity exceeded semantic nest size][\quad semantic nest size]
  5596. }
  5597. prg.nest[prg.nestPtr] = prg.curList // stack the record
  5598. prg.nestPtr = byte(int32(prg.nestPtr) + 1)
  5599. prg.curList.headField = prg.getAvail()
  5600. prg.curList.tailField = prg.curList.headField
  5601. prg.curList.pgField = 0
  5602. prg.curList.mlField = prg.line
  5603. }
  5604. // 217.
  5605. // tangle:pos tex.web:4382:3:
  5606. // Conversely, when \TeX\ is finished on the current level, the former
  5607. // state is restored by calling |pop_nest|. This routine will never be
  5608. // called at the lowest semantic level, nor will it be called unless |head|
  5609. // is a node that should be returned to free memory.
  5610. func (prg *prg) popNest() {
  5611. {
  5612. *(*prg.mem[prg.curList.headField].hh()).rh() = prg.avail
  5613. prg.avail = prg.curList.headField /* dyn_used:= dyn_used-1 ; [ ] */
  5614. }
  5615. prg.nestPtr = byte(int32(prg.nestPtr) - 1)
  5616. prg.curList = prg.nest[prg.nestPtr]
  5617. } // \2
  5618. func (prg *prg) showActivities() {
  5619. var (
  5620. p/* 0..nestSize */ byte // index into |nest|
  5621. m/* -mmode..mmode */ int16 // mode
  5622. a memoryWord // auxiliary
  5623. q, r1 halfword // for showing the current page
  5624. t int32 // ditto
  5625. )
  5626. prg.nest[prg.nestPtr] = prg.curList // put the top level into the array
  5627. prg.printNl(strNumber( /* "" */ 338))
  5628. prg.printLn()
  5629. for ii := int32(prg.nestPtr); ii >= 0; ii-- {
  5630. p = byte(ii)
  5631. _ = p
  5632. m = prg.nest[p].modeField
  5633. a = prg.nest[p].auxField
  5634. prg.printNl(strNumber( /* "### " */ 363))
  5635. prg.printMode(int32(m))
  5636. prg.print( /* " entered at line " */ 364)
  5637. prg.printInt(abs(prg.nest[p].mlField))
  5638. if int32(m) == hmode {
  5639. if prg.nest[p].pgField != 040600000 {
  5640. prg.print( /* " (language" */ 365)
  5641. prg.printInt(prg.nest[p].pgField % 0200000)
  5642. prg.print( /* ":hyphenmin" */ 366)
  5643. prg.printInt(prg.nest[p].pgField / 020000000)
  5644. prg.printChar(asciiCode(','))
  5645. prg.printInt(prg.nest[p].pgField / 0200000 % 0100)
  5646. prg.printChar(asciiCode(')'))
  5647. }
  5648. }
  5649. if prg.nest[p].mlField < 0 {
  5650. prg.print( /* " (\\output routine)" */ 367)
  5651. }
  5652. if int32(p) == 0 {
  5653. if 30000-2 != int32(prg.pageTail) {
  5654. prg.printNl(strNumber( /* "### current page:" */ 980))
  5655. if prg.outputActive {
  5656. prg.print( /* " (held over for next output)" */ 981)
  5657. }
  5658. // \xref[held over for next output]
  5659. prg.showBox(*(*prg.mem[30000-2].hh()).rh())
  5660. if int32(prg.pageContents) > empty {
  5661. prg.printNl(strNumber( /* "total height " */ 982))
  5662. prg.printTotals()
  5663. // \xref[total_height][\.[total height]]
  5664. prg.printNl(strNumber( /* " goal height " */ 983))
  5665. prg.printScaled(prg.pageSoFar[0])
  5666. // \xref[goal height]
  5667. r1 = *(*prg.mem[30000].hh()).rh()
  5668. for int32(r1) != 30000 {
  5669. prg.printLn()
  5670. prg.printEsc(strNumber( /* "insert" */ 330))
  5671. t = int32(*(*prg.mem[r1].hh()).b1()) - minQuarterword
  5672. prg.printInt(t)
  5673. prg.print( /* " adds " */ 984)
  5674. if *prg.eqtb[countBase+t-1].int() == 1000 {
  5675. t = *prg.mem[int32(r1)+heightOffset].int()
  5676. } else {
  5677. t = prg.xOverN(*prg.mem[int32(r1)+heightOffset].int(), 1000) * *prg.eqtb[countBase+t-1].int()
  5678. }
  5679. prg.printScaled(t)
  5680. if int32(*(*prg.mem[r1].hh()).b0()) == splitUp {
  5681. q = uint16(30000 - 2)
  5682. t = 0
  5683. for {
  5684. q = *(*prg.mem[q].hh()).rh()
  5685. if int32(*(*prg.mem[q].hh()).b0()) == insNode && int32(*(*prg.mem[q].hh()).b1()) == int32(*(*prg.mem[r1].hh()).b1()) {
  5686. t = t + 1
  5687. }
  5688. if int32(q) == int32(*(*prg.mem[int32(r1)+1].hh()).lh()) {
  5689. break
  5690. }
  5691. }
  5692. prg.print( /* ", #" */ 985)
  5693. prg.printInt(t)
  5694. prg.print( /* " might split" */ 986)
  5695. }
  5696. r1 = *(*prg.mem[r1].hh()).rh()
  5697. }
  5698. }
  5699. }
  5700. if int32(*(*prg.mem[30000-1].hh()).rh()) != 0 {
  5701. prg.printNl(strNumber( /* "### recent contributions:" */ 368))
  5702. }
  5703. }
  5704. prg.showBox(*(*prg.mem[prg.nest[p].headField].hh()).rh())
  5705. // Show the auxiliary field, |a|
  5706. switch abs(int32(m)) / (maxCommand + 1) {
  5707. case 0:
  5708. prg.printNl(strNumber( /* "prevdepth " */ 369))
  5709. if *a.int() <= -65536000 {
  5710. prg.print( /* "ignored" */ 370)
  5711. } else {
  5712. prg.printScaled(*a.int())
  5713. }
  5714. if prg.nest[p].pgField != 0 {
  5715. prg.print( /* ", prevgraf " */ 371)
  5716. prg.printInt(prg.nest[p].pgField)
  5717. prg.print( /* " line" */ 372)
  5718. if prg.nest[p].pgField != 1 {
  5719. prg.printChar(asciiCode('s'))
  5720. }
  5721. }
  5722. case 1:
  5723. prg.printNl(strNumber( /* "spacefactor " */ 373))
  5724. prg.printInt(int32(*(*a.hh()).lh()))
  5725. if int32(m) > 0 {
  5726. if int32(*(*a.hh()).rh()) > 0 {
  5727. prg.print( /* ", current language " */ 374)
  5728. prg.printInt(int32(*(*a.hh()).rh()))
  5729. }
  5730. }
  5731. case 2:
  5732. if *a.int() != 0 {
  5733. prg.print( /* "this will begin denominator of:" */ 375)
  5734. prg.showBox(halfword(*a.int()))
  5735. }
  5736. }
  5737. }
  5738. }
  5739. // 220. \[17] The table of equivalents
  5740. // tangle:pos tex.web:4444:35:
  5741. // Now that we have studied the data structures for \TeX's semantic routines,
  5742. // we ought to consider the data structures used by its syntactic routines. In
  5743. // other words, our next concern will be
  5744. // the tables that \TeX\ looks at when it is scanning
  5745. // what the user has written.
  5746. //
  5747. // The biggest and most important such table is called |eqtb|. It holds the
  5748. // current ``equivalents'' of things; i.e., it explains what things mean
  5749. // or what their current values are, for all quantities that are subject to
  5750. // the nesting structure provided by \TeX's grouping mechanism. There are six
  5751. // parts to |eqtb|:
  5752. //
  5753. // \yskip\hangg 1) |eqtb[active_base..(hash_base-1)]| holds the current
  5754. // equivalents of single-character control sequences.
  5755. //
  5756. // \yskip\hangg 2) |eqtb[hash_base..(glue_base-1)]| holds the current
  5757. // equivalents of multiletter control sequences.
  5758. //
  5759. // \yskip\hangg 3) |eqtb[glue_base..(local_base-1)]| holds the current
  5760. // equivalents of glue parameters like the current baselineskip.
  5761. //
  5762. // \yskip\hangg 4) |eqtb[local_base..(int_base-1)]| holds the current
  5763. // equivalents of local halfword quantities like the current box registers,
  5764. // the current ``catcodes,'' the current font, and a pointer to the current
  5765. // paragraph shape.
  5766. //
  5767. // \yskip\hangg 5) |eqtb[int_base..(dimen_base-1)]| holds the current
  5768. // equivalents of fullword integer parameters like the current hyphenation
  5769. // penalty.
  5770. //
  5771. // \yskip\hangg 6) |eqtb[dimen_base..eqtb_size]| holds the current equivalents
  5772. // of fullword dimension parameters like the current hsize or amount of
  5773. // hanging indentation.
  5774. //
  5775. // \yskip\noindent Note that, for example, the current amount of
  5776. // baselineskip glue is determined by the setting of a particular location
  5777. // in region~3 of |eqtb|, while the current meaning of the control sequence
  5778. // `\.[\\baselineskip]' (which might have been changed by \.[\\def] or
  5779. // \.[\\let]) appears in region~2.
  5780. // 221.
  5781. // tangle:pos tex.web:4485:3:
  5782. // Each entry in |eqtb| is a |memory_word|. Most of these words are of type
  5783. // |two_halves|, and subdivided into three fields:
  5784. //
  5785. // \yskip\hangg 1) The |eq_level| (a quarterword) is the level of grouping at
  5786. // which this equivalent was defined. If the level is |level_zero|, the
  5787. // equivalent has never been defined; |level_one| refers to the outer level
  5788. // (outside of all groups), and this level is also used for global
  5789. // definitions that never go away. Higher levels are for equivalents that
  5790. // will disappear at the end of their group. \xref[global definitions]
  5791. //
  5792. // \yskip\hangg 2) The |eq_type| (another quarterword) specifies what kind of
  5793. // entry this is. There are many types, since each \TeX\ primitive like
  5794. // \.[\\hbox], \.[\\def], etc., has its own special code. The list of
  5795. // command codes above includes all possible settings of the |eq_type| field.
  5796. //
  5797. // \yskip\hangg 3) The |equiv| (a halfword) is the current equivalent value.
  5798. // This may be a font number, a pointer into |mem|, or a variety of other
  5799. // things.
  5800. // 237.
  5801. // tangle:pos tex.web:5043:3:
  5802. // We can print the symbolic name of an integer parameter as follows.
  5803. func (prg *prg) printParam(n int32) {
  5804. switch n {
  5805. case pretoleranceCode:
  5806. prg.printEsc(strNumber( /* "pretolerance" */ 420))
  5807. case toleranceCode:
  5808. prg.printEsc(strNumber( /* "tolerance" */ 421))
  5809. case linePenaltyCode:
  5810. prg.printEsc(strNumber( /* "linepenalty" */ 422))
  5811. case hyphenPenaltyCode:
  5812. prg.printEsc(strNumber( /* "hyphenpenalty" */ 423))
  5813. case exHyphenPenaltyCode:
  5814. prg.printEsc(strNumber( /* "exhyphenpenalty" */ 424))
  5815. case clubPenaltyCode:
  5816. prg.printEsc(strNumber( /* "clubpenalty" */ 425))
  5817. case widowPenaltyCode:
  5818. prg.printEsc(strNumber( /* "widowpenalty" */ 426))
  5819. case displayWidowPenaltyCode:
  5820. prg.printEsc(strNumber( /* "displaywidowpenalty" */ 427))
  5821. case brokenPenaltyCode:
  5822. prg.printEsc(strNumber( /* "brokenpenalty" */ 428))
  5823. case binOpPenaltyCode:
  5824. prg.printEsc(strNumber( /* "binoppenalty" */ 429))
  5825. case relPenaltyCode:
  5826. prg.printEsc(strNumber( /* "relpenalty" */ 430))
  5827. case preDisplayPenaltyCode:
  5828. prg.printEsc(strNumber( /* "predisplaypenalty" */ 431))
  5829. case postDisplayPenaltyCode:
  5830. prg.printEsc(strNumber( /* "postdisplaypenalty" */ 432))
  5831. case interLinePenaltyCode:
  5832. prg.printEsc(strNumber( /* "interlinepenalty" */ 433))
  5833. case doubleHyphenDemeritsCode:
  5834. prg.printEsc(strNumber( /* "doublehyphendemerits" */ 434))
  5835. case finalHyphenDemeritsCode:
  5836. prg.printEsc(strNumber( /* "finalhyphendemerits" */ 435))
  5837. case adjDemeritsCode:
  5838. prg.printEsc(strNumber( /* "adjdemerits" */ 436))
  5839. case magCode:
  5840. prg.printEsc(strNumber( /* "mag" */ 437))
  5841. case delimiterFactorCode:
  5842. prg.printEsc(strNumber( /* "delimiterfactor" */ 438))
  5843. case loosenessCode:
  5844. prg.printEsc(strNumber( /* "looseness" */ 439))
  5845. case timeCode:
  5846. prg.printEsc(strNumber( /* "time" */ 440))
  5847. case dayCode:
  5848. prg.printEsc(strNumber( /* "day" */ 441))
  5849. case monthCode:
  5850. prg.printEsc(strNumber( /* "month" */ 442))
  5851. case yearCode:
  5852. prg.printEsc(strNumber( /* "year" */ 443))
  5853. case showBoxBreadthCode:
  5854. prg.printEsc(strNumber( /* "showboxbreadth" */ 444))
  5855. case showBoxDepthCode:
  5856. prg.printEsc(strNumber( /* "showboxdepth" */ 445))
  5857. case hbadnessCode:
  5858. prg.printEsc(strNumber( /* "hbadness" */ 446))
  5859. case vbadnessCode:
  5860. prg.printEsc(strNumber( /* "vbadness" */ 447))
  5861. case pausingCode:
  5862. prg.printEsc(strNumber( /* "pausing" */ 448))
  5863. case tracingOnlineCode:
  5864. prg.printEsc(strNumber( /* "tracingonline" */ 449))
  5865. case tracingMacrosCode:
  5866. prg.printEsc(strNumber( /* "tracingmacros" */ 450))
  5867. case tracingStatsCode:
  5868. prg.printEsc(strNumber( /* "tracingstats" */ 451))
  5869. case tracingParagraphsCode:
  5870. prg.printEsc(strNumber( /* "tracingparagraphs" */ 452))
  5871. case tracingPagesCode:
  5872. prg.printEsc(strNumber( /* "tracingpages" */ 453))
  5873. case tracingOutputCode:
  5874. prg.printEsc(strNumber( /* "tracingoutput" */ 454))
  5875. case tracingLostCharsCode:
  5876. prg.printEsc(strNumber( /* "tracinglostchars" */ 455))
  5877. case tracingCommandsCode:
  5878. prg.printEsc(strNumber( /* "tracingcommands" */ 456))
  5879. case tracingRestoresCode:
  5880. prg.printEsc(strNumber( /* "tracingrestores" */ 457))
  5881. case ucHyphCode:
  5882. prg.printEsc(strNumber( /* "uchyph" */ 458))
  5883. case outputPenaltyCode:
  5884. prg.printEsc(strNumber( /* "outputpenalty" */ 459))
  5885. case maxDeadCyclesCode:
  5886. prg.printEsc(strNumber( /* "maxdeadcycles" */ 460))
  5887. case hangAfterCode:
  5888. prg.printEsc(strNumber( /* "hangafter" */ 461))
  5889. case floatingPenaltyCode:
  5890. prg.printEsc(strNumber( /* "floatingpenalty" */ 462))
  5891. case globalDefsCode:
  5892. prg.printEsc(strNumber( /* "globaldefs" */ 463))
  5893. case curFamCode:
  5894. prg.printEsc(strNumber( /* "fam" */ 464))
  5895. case escapeCharCode:
  5896. prg.printEsc(strNumber( /* "escapechar" */ 465))
  5897. case defaultHyphenCharCode:
  5898. prg.printEsc(strNumber( /* "defaulthyphenchar" */ 466))
  5899. case defaultSkewCharCode:
  5900. prg.printEsc(strNumber( /* "defaultskewchar" */ 467))
  5901. case endLineCharCode:
  5902. prg.printEsc(strNumber( /* "endlinechar" */ 468))
  5903. case newLineCharCode:
  5904. prg.printEsc(strNumber( /* "newlinechar" */ 469))
  5905. case languageCode:
  5906. prg.printEsc(strNumber( /* "language" */ 470))
  5907. case leftHyphenMinCode:
  5908. prg.printEsc(strNumber( /* "lefthyphenmin" */ 471))
  5909. case rightHyphenMinCode:
  5910. prg.printEsc(strNumber( /* "righthyphenmin" */ 472))
  5911. case holdingInsertsCode:
  5912. prg.printEsc(strNumber( /* "holdinginserts" */ 473))
  5913. case errorContextLinesCode:
  5914. prg.printEsc(strNumber( /* "errorcontextlines" */ 474))
  5915. default:
  5916. prg.print( /* "[unknown integer parameter!]" */ 475)
  5917. }
  5918. }
  5919. // 241.
  5920. // tangle:pos tex.web:5240:3:
  5921. // The following procedure, which is called just before \TeX\ initializes its
  5922. // input and output, establishes the initial values of the date and time.
  5923. // \xref[system dependencies]
  5924. // Since standard \PASCAL\ cannot provide such information, something special
  5925. // is needed. The program here simply assumes that suitable values appear in
  5926. // the global variables \\[sys\_time], \\[sys\_day], \\[sys\_month], and
  5927. // \\[sys\_year] (which are initialized to noon on 4 July 1776,
  5928. // in case the implementor is careless).
  5929. func (prg *prg) fixDateAndTime() {
  5930. prg.sysTime = 12 * 60
  5931. prg.sysDay = 4
  5932. prg.sysMonth = 7
  5933. prg.sysYear = 1776 // self-evident truths
  5934. *prg.eqtb[intBase+timeCode-1].int() = prg.sysTime // minutes since midnight
  5935. *prg.eqtb[intBase+dayCode-1].int() = prg.sysDay // day of the month
  5936. *prg.eqtb[intBase+monthCode-1].int() = prg.sysMonth // month of the year
  5937. *prg.eqtb[intBase+yearCode-1].int() = prg.sysYear // Anno Domini
  5938. }
  5939. // 245.
  5940. // tangle:pos tex.web:5272:3:
  5941. // \TeX\ is occasionally supposed to print diagnostic information that
  5942. // goes only into the transcript file, unless |tracing_online| is positive.
  5943. // Here are two routines that adjust the destination of print commands:
  5944. func (prg *prg) beginDiagnostic() {
  5945. prg.oldSetting = prg.selector
  5946. if *prg.eqtb[intBase+tracingOnlineCode-1].int() <= 0 && int32(prg.selector) == termAndLog {
  5947. prg.selector = byte(int32(prg.selector) - 1)
  5948. if int32(prg.history) == spotless {
  5949. prg.history = byte(warningIssued)
  5950. }
  5951. }
  5952. }
  5953. func (prg *prg) endDiagnostic(blankLine bool) {
  5954. prg.printNl(strNumber( /* "" */ 338))
  5955. if blankLine {
  5956. prg.printLn()
  5957. }
  5958. prg.selector = prg.oldSetting
  5959. }
  5960. // 247.
  5961. // tangle:pos tex.web:5299:3:
  5962. // The final region of |eqtb| contains the dimension parameters defined
  5963. // here, and the 256 \.[\\dimen] registers.
  5964. func (prg *prg) printLengthParam(n int32) {
  5965. switch n {
  5966. case parIndentCode:
  5967. prg.printEsc(strNumber( /* "parindent" */ 478))
  5968. case mathSurroundCode:
  5969. prg.printEsc(strNumber( /* "mathsurround" */ 479))
  5970. case lineSkipLimitCode:
  5971. prg.printEsc(strNumber( /* "lineskiplimit" */ 480))
  5972. case hsizeCode:
  5973. prg.printEsc(strNumber( /* "hsize" */ 481))
  5974. case vsizeCode:
  5975. prg.printEsc(strNumber( /* "vsize" */ 482))
  5976. case maxDepthCode:
  5977. prg.printEsc(strNumber( /* "maxdepth" */ 483))
  5978. case splitMaxDepthCode:
  5979. prg.printEsc(strNumber( /* "splitmaxdepth" */ 484))
  5980. case boxMaxDepthCode:
  5981. prg.printEsc(strNumber( /* "boxmaxdepth" */ 485))
  5982. case hfuzzCode:
  5983. prg.printEsc(strNumber( /* "hfuzz" */ 486))
  5984. case vfuzzCode:
  5985. prg.printEsc(strNumber( /* "vfuzz" */ 487))
  5986. case delimiterShortfallCode:
  5987. prg.printEsc(strNumber( /* "delimitershortfall" */ 488))
  5988. case nullDelimiterSpaceCode:
  5989. prg.printEsc(strNumber( /* "nulldelimiterspace" */ 489))
  5990. case scriptSpaceCode:
  5991. prg.printEsc(strNumber( /* "scriptspace" */ 490))
  5992. case preDisplaySizeCode:
  5993. prg.printEsc(strNumber( /* "predisplaysize" */ 491))
  5994. case displayWidthCode:
  5995. prg.printEsc(strNumber( /* "displaywidth" */ 492))
  5996. case displayIndentCode:
  5997. prg.printEsc(strNumber( /* "displayindent" */ 493))
  5998. case overfullRuleCode:
  5999. prg.printEsc(strNumber( /* "overfullrule" */ 494))
  6000. case hangIndentCode:
  6001. prg.printEsc(strNumber( /* "hangindent" */ 495))
  6002. case hOffsetCode:
  6003. prg.printEsc(strNumber( /* "hoffset" */ 496))
  6004. case vOffsetCode:
  6005. prg.printEsc(strNumber( /* "voffset" */ 497))
  6006. case emergencyStretchCode:
  6007. prg.printEsc(strNumber( /* "emergencystretch" */ 498))
  6008. default:
  6009. prg.print( /* "[unknown dimen parameter!]" */ 499)
  6010. }
  6011. }
  6012. // 252.
  6013. // tangle:pos tex.web:5441:3:
  6014. // Here is a procedure that displays the contents of |eqtb[n]|
  6015. // symbolically.
  6016. // \4
  6017. // Declare the procedure called |print_cmd_chr|
  6018. func (prg *prg) printCmdChr(cmd quarterword, chrCode halfword) {
  6019. switch cmd {
  6020. case leftBrace:
  6021. prg.print( /* "begin-group character " */ 557)
  6022. prg.print(int32(chrCode))
  6023. case rightBrace:
  6024. prg.print( /* "end-group character " */ 558)
  6025. prg.print(int32(chrCode))
  6026. case mathShift:
  6027. prg.print( /* "math shift character " */ 559)
  6028. prg.print(int32(chrCode))
  6029. case macParam:
  6030. prg.print( /* "macro parameter character " */ 560)
  6031. prg.print(int32(chrCode))
  6032. case supMark:
  6033. prg.print( /* "superscript character " */ 561)
  6034. prg.print(int32(chrCode))
  6035. case subMark:
  6036. prg.print( /* "subscript character " */ 562)
  6037. prg.print(int32(chrCode))
  6038. case endv:
  6039. prg.print( /* "end of alignment template" */ 563)
  6040. case spacer:
  6041. prg.print( /* "blank space " */ 564)
  6042. prg.print(int32(chrCode))
  6043. case letter:
  6044. prg.print( /* "the letter " */ 565)
  6045. prg.print(int32(chrCode))
  6046. case otherChar:
  6047. prg.print( /* "the character " */ 566)
  6048. prg.print(int32(chrCode))
  6049. // \4
  6050. // Cases of |print_cmd_chr| for symbolic printing of primitives
  6051. case assignGlue, assignMuGlue:
  6052. if int32(chrCode) < skipBase {
  6053. prg.printSkipParam(int32(chrCode) - glueBase)
  6054. } else if int32(chrCode) < muSkipBase {
  6055. prg.printEsc(strNumber( /* "skip" */ 395))
  6056. prg.printInt(int32(chrCode) - skipBase)
  6057. } else {
  6058. prg.printEsc(strNumber( /* "muskip" */ 396))
  6059. prg.printInt(int32(chrCode) - muSkipBase)
  6060. }
  6061. case assignToks:
  6062. if int32(chrCode) >= toksBase {
  6063. prg.printEsc(strNumber( /* "toks" */ 407))
  6064. prg.printInt(int32(chrCode) - toksBase)
  6065. } else {
  6066. switch chrCode {
  6067. case outputRoutineLoc:
  6068. prg.printEsc(strNumber( /* "output" */ 398))
  6069. case everyParLoc:
  6070. prg.printEsc(strNumber( /* "everypar" */ 399))
  6071. case everyMathLoc:
  6072. prg.printEsc(strNumber( /* "everymath" */ 400))
  6073. case everyDisplayLoc:
  6074. prg.printEsc(strNumber( /* "everydisplay" */ 401))
  6075. case everyHboxLoc:
  6076. prg.printEsc(strNumber( /* "everyhbox" */ 402))
  6077. case everyVboxLoc:
  6078. prg.printEsc(strNumber( /* "everyvbox" */ 403))
  6079. case everyJobLoc:
  6080. prg.printEsc(strNumber( /* "everyjob" */ 404))
  6081. case everyCrLoc:
  6082. prg.printEsc(strNumber( /* "everycr" */ 405))
  6083. default:
  6084. prg.printEsc(strNumber( /* "errhelp" */ 406))
  6085. }
  6086. }
  6087. case assignInt:
  6088. if int32(chrCode) < countBase {
  6089. prg.printParam(int32(chrCode) - intBase)
  6090. } else {
  6091. prg.printEsc(strNumber( /* "count" */ 476))
  6092. prg.printInt(int32(chrCode) - countBase)
  6093. }
  6094. case assignDimen:
  6095. if int32(chrCode) < scaledBase {
  6096. prg.printLengthParam(int32(chrCode) - dimenBase)
  6097. } else {
  6098. prg.printEsc(strNumber( /* "dimen" */ 500))
  6099. prg.printInt(int32(chrCode) - scaledBase)
  6100. }
  6101. case accent:
  6102. prg.printEsc(strNumber( /* "accent" */ 508))
  6103. case advance:
  6104. prg.printEsc(strNumber( /* "advance" */ 509))
  6105. case afterAssignment:
  6106. prg.printEsc(strNumber( /* "afterassignment" */ 510))
  6107. case afterGroup:
  6108. prg.printEsc(strNumber( /* "aftergroup" */ 511))
  6109. case assignFontDimen:
  6110. prg.printEsc(strNumber( /* "fontdimen" */ 519))
  6111. case beginGroup:
  6112. prg.printEsc(strNumber( /* "begingroup" */ 512))
  6113. case breakPenalty:
  6114. prg.printEsc(strNumber( /* "penalty" */ 531))
  6115. case charNum:
  6116. prg.printEsc(strNumber( /* "char" */ 513))
  6117. case csName:
  6118. prg.printEsc(strNumber( /* "csname" */ 504))
  6119. case defFont:
  6120. prg.printEsc(strNumber( /* "font" */ 518))
  6121. case delimNum:
  6122. prg.printEsc(strNumber( /* "delimiter" */ 514))
  6123. case divide:
  6124. prg.printEsc(strNumber( /* "divide" */ 515))
  6125. case endCsName:
  6126. prg.printEsc(strNumber( /* "endcsname" */ 505))
  6127. case endGroup:
  6128. prg.printEsc(strNumber( /* "endgroup" */ 516))
  6129. case exSpace:
  6130. prg.printEsc(strNumber(' '))
  6131. case expandAfter:
  6132. prg.printEsc(strNumber( /* "expandafter" */ 517))
  6133. case halign:
  6134. prg.printEsc(strNumber( /* "halign" */ 520))
  6135. case hrule:
  6136. prg.printEsc(strNumber( /* "hrule" */ 521))
  6137. case ignoreSpaces:
  6138. prg.printEsc(strNumber( /* "ignorespaces" */ 522))
  6139. case insert:
  6140. prg.printEsc(strNumber( /* "insert" */ 330))
  6141. case italCorr:
  6142. prg.printEsc(strNumber('/'))
  6143. case mark:
  6144. prg.printEsc(strNumber( /* "mark" */ 351))
  6145. case mathAccent:
  6146. prg.printEsc(strNumber( /* "mathaccent" */ 523))
  6147. case mathCharNum:
  6148. prg.printEsc(strNumber( /* "mathchar" */ 524))
  6149. case mathChoice:
  6150. prg.printEsc(strNumber( /* "mathchoice" */ 525))
  6151. case multiply:
  6152. prg.printEsc(strNumber( /* "multiply" */ 526))
  6153. case noAlign:
  6154. prg.printEsc(strNumber( /* "noalign" */ 527))
  6155. case noBoundary:
  6156. prg.printEsc(strNumber( /* "noboundary" */ 528))
  6157. case noExpand:
  6158. prg.printEsc(strNumber( /* "noexpand" */ 529))
  6159. case nonScript:
  6160. prg.printEsc(strNumber( /* "nonscript" */ 335))
  6161. case omit:
  6162. prg.printEsc(strNumber( /* "omit" */ 530))
  6163. case radical:
  6164. prg.printEsc(strNumber( /* "radical" */ 533))
  6165. case readToCs:
  6166. prg.printEsc(strNumber( /* "read" */ 534))
  6167. case relax:
  6168. prg.printEsc(strNumber( /* "relax" */ 535))
  6169. case setBox:
  6170. prg.printEsc(strNumber( /* "setbox" */ 536))
  6171. case setPrevGraf:
  6172. prg.printEsc(strNumber( /* "prevgraf" */ 532))
  6173. case setShape:
  6174. prg.printEsc(strNumber( /* "parshape" */ 408))
  6175. case the:
  6176. prg.printEsc(strNumber( /* "the" */ 537))
  6177. case toksRegister:
  6178. prg.printEsc(strNumber( /* "toks" */ 407))
  6179. case vadjust:
  6180. prg.printEsc(strNumber( /* "vadjust" */ 352))
  6181. case valign:
  6182. prg.printEsc(strNumber( /* "valign" */ 538))
  6183. case vcenter:
  6184. prg.printEsc(strNumber( /* "vcenter" */ 539))
  6185. case vrule:
  6186. prg.printEsc(strNumber( /* "vrule" */ 540))
  6187. case parEnd:
  6188. prg.printEsc(strNumber( /* "par" */ 597))
  6189. case input:
  6190. if int32(chrCode) == 0 {
  6191. prg.printEsc(strNumber( /* "input" */ 629))
  6192. } else {
  6193. prg.printEsc(strNumber( /* "endinput" */ 630))
  6194. }
  6195. case topBotMark:
  6196. switch chrCode {
  6197. case firstMarkCode:
  6198. prg.printEsc(strNumber( /* "firstmark" */ 632))
  6199. case botMarkCode:
  6200. prg.printEsc(strNumber( /* "botmark" */ 633))
  6201. case splitFirstMarkCode:
  6202. prg.printEsc(strNumber( /* "splitfirstmark" */ 634))
  6203. case splitBotMarkCode:
  6204. prg.printEsc(strNumber( /* "splitbotmark" */ 635))
  6205. default:
  6206. prg.printEsc(strNumber( /* "topmark" */ 631))
  6207. }
  6208. case register:
  6209. if int32(chrCode) == intVal {
  6210. prg.printEsc(strNumber( /* "count" */ 476))
  6211. } else if int32(chrCode) == dimenVal {
  6212. prg.printEsc(strNumber( /* "dimen" */ 500))
  6213. } else if int32(chrCode) == glueVal {
  6214. prg.printEsc(strNumber( /* "skip" */ 395))
  6215. } else {
  6216. prg.printEsc(strNumber( /* "muskip" */ 396))
  6217. }
  6218. case setAux:
  6219. if int32(chrCode) == vmode {
  6220. prg.printEsc(strNumber( /* "prevdepth" */ 669))
  6221. } else {
  6222. prg.printEsc(strNumber( /* "spacefactor" */ 668))
  6223. }
  6224. case setPageInt:
  6225. if int32(chrCode) == 0 {
  6226. prg.printEsc(strNumber( /* "deadcycles" */ 670))
  6227. } else {
  6228. prg.printEsc(strNumber( /* "insertpenalties" */ 671))
  6229. }
  6230. case setBoxDimen:
  6231. if int32(chrCode) == widthOffset {
  6232. prg.printEsc(strNumber( /* "wd" */ 672))
  6233. } else if int32(chrCode) == heightOffset {
  6234. prg.printEsc(strNumber( /* "ht" */ 673))
  6235. } else {
  6236. prg.printEsc(strNumber( /* "dp" */ 674))
  6237. }
  6238. case lastItem:
  6239. switch chrCode {
  6240. case intVal:
  6241. prg.printEsc(strNumber( /* "lastpenalty" */ 675))
  6242. case dimenVal:
  6243. prg.printEsc(strNumber( /* "lastkern" */ 676))
  6244. case glueVal:
  6245. prg.printEsc(strNumber( /* "lastskip" */ 677))
  6246. case inputLineNoCode:
  6247. prg.printEsc(strNumber( /* "inputlineno" */ 678))
  6248. default:
  6249. prg.printEsc(strNumber( /* "badness" */ 679))
  6250. }
  6251. case convert:
  6252. switch chrCode {
  6253. case numberCode:
  6254. prg.printEsc(strNumber( /* "number" */ 735))
  6255. case romanNumeralCode:
  6256. prg.printEsc(strNumber( /* "romannumeral" */ 736))
  6257. case stringCode:
  6258. prg.printEsc(strNumber( /* "string" */ 737))
  6259. case meaningCode:
  6260. prg.printEsc(strNumber( /* "meaning" */ 738))
  6261. case fontNameCode:
  6262. prg.printEsc(strNumber( /* "fontname" */ 739))
  6263. default:
  6264. prg.printEsc(strNumber( /* "jobname" */ 740))
  6265. }
  6266. case ifTest:
  6267. switch chrCode {
  6268. case ifCatCode:
  6269. prg.printEsc(strNumber( /* "ifcat" */ 758))
  6270. case ifIntCode:
  6271. prg.printEsc(strNumber( /* "ifnum" */ 759))
  6272. case ifDimCode:
  6273. prg.printEsc(strNumber( /* "ifdim" */ 760))
  6274. case ifOddCode:
  6275. prg.printEsc(strNumber( /* "ifodd" */ 761))
  6276. case ifVmodeCode:
  6277. prg.printEsc(strNumber( /* "ifvmode" */ 762))
  6278. case ifHmodeCode:
  6279. prg.printEsc(strNumber( /* "ifhmode" */ 763))
  6280. case ifMmodeCode:
  6281. prg.printEsc(strNumber( /* "ifmmode" */ 764))
  6282. case ifInnerCode:
  6283. prg.printEsc(strNumber( /* "ifinner" */ 765))
  6284. case ifVoidCode:
  6285. prg.printEsc(strNumber( /* "ifvoid" */ 766))
  6286. case ifHboxCode:
  6287. prg.printEsc(strNumber( /* "ifhbox" */ 767))
  6288. case ifVboxCode:
  6289. prg.printEsc(strNumber( /* "ifvbox" */ 768))
  6290. case ifxCode:
  6291. prg.printEsc(strNumber( /* "ifx" */ 769))
  6292. case ifEofCode:
  6293. prg.printEsc(strNumber( /* "ifeof" */ 770))
  6294. case ifTrueCode:
  6295. prg.printEsc(strNumber( /* "iftrue" */ 771))
  6296. case ifFalseCode:
  6297. prg.printEsc(strNumber( /* "iffalse" */ 772))
  6298. case ifCaseCode:
  6299. prg.printEsc(strNumber( /* "ifcase" */ 773))
  6300. default:
  6301. prg.printEsc(strNumber( /* "if" */ 757))
  6302. }
  6303. case fiOrElse:
  6304. if int32(chrCode) == fiCode {
  6305. prg.printEsc(strNumber( /* "fi" */ 774))
  6306. } else if int32(chrCode) == orCode {
  6307. prg.printEsc(strNumber( /* "or" */ 775))
  6308. } else {
  6309. prg.printEsc(strNumber( /* "else" */ 776))
  6310. }
  6311. case tabMark:
  6312. if int32(chrCode) == spanCode {
  6313. prg.printEsc(strNumber( /* "span" */ 898))
  6314. } else {
  6315. prg.print( /* "alignment tab character " */ 902)
  6316. prg.print(int32(chrCode))
  6317. }
  6318. case carRet:
  6319. if int32(chrCode) == crCode {
  6320. prg.printEsc(strNumber( /* "cr" */ 899))
  6321. } else {
  6322. prg.printEsc(strNumber( /* "crcr" */ 900))
  6323. }
  6324. case setPageDimen:
  6325. switch chrCode {
  6326. case 0:
  6327. prg.printEsc(strNumber( /* "pagegoal" */ 970))
  6328. case 1:
  6329. prg.printEsc(strNumber( /* "pagetotal" */ 971))
  6330. case 2:
  6331. prg.printEsc(strNumber( /* "pagestretch" */ 972))
  6332. case 3:
  6333. prg.printEsc(strNumber( /* "pagefilstretch" */ 973))
  6334. case 4:
  6335. prg.printEsc(strNumber( /* "pagefillstretch" */ 974))
  6336. case 5:
  6337. prg.printEsc(strNumber( /* "pagefilllstretch" */ 975))
  6338. case 6:
  6339. prg.printEsc(strNumber( /* "pageshrink" */ 976))
  6340. default:
  6341. prg.printEsc(strNumber( /* "pagedepth" */ 977))
  6342. }
  6343. case stop:
  6344. if int32(chrCode) == 1 {
  6345. prg.printEsc(strNumber( /* "dump" */ 1026))
  6346. } else {
  6347. prg.printEsc(strNumber( /* "end" */ 1025))
  6348. }
  6349. case hskip:
  6350. switch chrCode {
  6351. case skipCode:
  6352. prg.printEsc(strNumber( /* "hskip" */ 1027))
  6353. case filCode:
  6354. prg.printEsc(strNumber( /* "hfil" */ 1028))
  6355. case fillCode:
  6356. prg.printEsc(strNumber( /* "hfill" */ 1029))
  6357. case ssCode:
  6358. prg.printEsc(strNumber( /* "hss" */ 1030))
  6359. default:
  6360. prg.printEsc(strNumber( /* "hfilneg" */ 1031))
  6361. }
  6362. case vskip:
  6363. switch chrCode {
  6364. case skipCode:
  6365. prg.printEsc(strNumber( /* "vskip" */ 1032))
  6366. case filCode:
  6367. prg.printEsc(strNumber( /* "vfil" */ 1033))
  6368. case fillCode:
  6369. prg.printEsc(strNumber( /* "vfill" */ 1034))
  6370. case ssCode:
  6371. prg.printEsc(strNumber( /* "vss" */ 1035))
  6372. default:
  6373. prg.printEsc(strNumber( /* "vfilneg" */ 1036))
  6374. }
  6375. case mskip:
  6376. prg.printEsc(strNumber( /* "mskip" */ 336))
  6377. case kern:
  6378. prg.printEsc(strNumber( /* "kern" */ 340))
  6379. case mkern:
  6380. prg.printEsc(strNumber( /* "mkern" */ 342))
  6381. case hmove:
  6382. if int32(chrCode) == 1 {
  6383. prg.printEsc(strNumber( /* "moveleft" */ 1054))
  6384. } else {
  6385. prg.printEsc(strNumber( /* "moveright" */ 1055))
  6386. }
  6387. case vmove:
  6388. if int32(chrCode) == 1 {
  6389. prg.printEsc(strNumber( /* "raise" */ 1056))
  6390. } else {
  6391. prg.printEsc(strNumber( /* "lower" */ 1057))
  6392. }
  6393. case makeBox:
  6394. switch chrCode {
  6395. case boxCode:
  6396. prg.printEsc(strNumber( /* "box" */ 409))
  6397. case copyCode:
  6398. prg.printEsc(strNumber( /* "copy" */ 1058))
  6399. case lastBoxCode:
  6400. prg.printEsc(strNumber( /* "lastbox" */ 1059))
  6401. case vsplitCode:
  6402. prg.printEsc(strNumber( /* "vsplit" */ 965))
  6403. case vtopCode:
  6404. prg.printEsc(strNumber( /* "vtop" */ 1060))
  6405. case vtopCode + 1:
  6406. prg.printEsc(strNumber( /* "vbox" */ 967))
  6407. default:
  6408. prg.printEsc(strNumber( /* "hbox" */ 1061))
  6409. }
  6410. case leaderShip:
  6411. if int32(chrCode) == aLeaders {
  6412. prg.printEsc(strNumber( /* "leaders" */ 1063))
  6413. } else if int32(chrCode) == cLeaders {
  6414. prg.printEsc(strNumber( /* "cleaders" */ 1064))
  6415. } else if int32(chrCode) == xLeaders {
  6416. prg.printEsc(strNumber( /* "xleaders" */ 1065))
  6417. } else {
  6418. prg.printEsc(strNumber( /* "shipout" */ 1062))
  6419. }
  6420. case startPar:
  6421. if int32(chrCode) == 0 {
  6422. prg.printEsc(strNumber( /* "noindent" */ 1081))
  6423. } else {
  6424. prg.printEsc(strNumber( /* "indent" */ 1080))
  6425. }
  6426. case removeItem:
  6427. if int32(chrCode) == glueNode {
  6428. prg.printEsc(strNumber( /* "unskip" */ 1092))
  6429. } else if int32(chrCode) == kernNode {
  6430. prg.printEsc(strNumber( /* "unkern" */ 1091))
  6431. } else {
  6432. prg.printEsc(strNumber( /* "unpenalty" */ 1090))
  6433. }
  6434. case unHbox:
  6435. if int32(chrCode) == copyCode {
  6436. prg.printEsc(strNumber( /* "unhcopy" */ 1094))
  6437. } else {
  6438. prg.printEsc(strNumber( /* "unhbox" */ 1093))
  6439. }
  6440. case unVbox:
  6441. if int32(chrCode) == copyCode {
  6442. prg.printEsc(strNumber( /* "unvcopy" */ 1096))
  6443. } else {
  6444. prg.printEsc(strNumber( /* "unvbox" */ 1095))
  6445. }
  6446. case discretionary:
  6447. if int32(chrCode) == 1 {
  6448. prg.printEsc(strNumber('-'))
  6449. } else {
  6450. prg.printEsc(strNumber( /* "discretionary" */ 349))
  6451. }
  6452. case eqNo:
  6453. if int32(chrCode) == 1 {
  6454. prg.printEsc(strNumber( /* "leqno" */ 1128))
  6455. } else {
  6456. prg.printEsc(strNumber( /* "eqno" */ 1127))
  6457. }
  6458. case mathComp:
  6459. switch chrCode {
  6460. case ordNoad:
  6461. prg.printEsc(strNumber( /* "mathord" */ 866))
  6462. case opNoad:
  6463. prg.printEsc(strNumber( /* "mathop" */ 867))
  6464. case binNoad:
  6465. prg.printEsc(strNumber( /* "mathbin" */ 868))
  6466. case relNoad:
  6467. prg.printEsc(strNumber( /* "mathrel" */ 869))
  6468. case openNoad:
  6469. prg.printEsc(strNumber( /* "mathopen" */ 870))
  6470. case closeNoad:
  6471. prg.printEsc(strNumber( /* "mathclose" */ 871))
  6472. case punctNoad:
  6473. prg.printEsc(strNumber( /* "mathpunct" */ 872))
  6474. case innerNoad:
  6475. prg.printEsc(strNumber( /* "mathinner" */ 873))
  6476. case underNoad:
  6477. prg.printEsc(strNumber( /* "underline" */ 875))
  6478. default:
  6479. prg.printEsc(strNumber( /* "overline" */ 874))
  6480. }
  6481. case limitSwitch:
  6482. if int32(chrCode) == limits {
  6483. prg.printEsc(strNumber( /* "limits" */ 878))
  6484. } else if int32(chrCode) == noLimits {
  6485. prg.printEsc(strNumber( /* "nolimits" */ 879))
  6486. } else {
  6487. prg.printEsc(strNumber( /* "displaylimits" */ 1129))
  6488. }
  6489. case mathStyle:
  6490. prg.printStyle(int32(chrCode))
  6491. case above:
  6492. switch chrCode {
  6493. case overCode:
  6494. prg.printEsc(strNumber( /* "over" */ 1148))
  6495. case atopCode:
  6496. prg.printEsc(strNumber( /* "atop" */ 1149))
  6497. case delimitedCode + 0:
  6498. prg.printEsc(strNumber( /* "abovewithdelims" */ 1150))
  6499. case delimitedCode + 1:
  6500. prg.printEsc(strNumber( /* "overwithdelims" */ 1151))
  6501. case delimitedCode + 2:
  6502. prg.printEsc(strNumber( /* "atopwithdelims" */ 1152))
  6503. default:
  6504. prg.printEsc(strNumber( /* "above" */ 1147))
  6505. }
  6506. case leftRight:
  6507. if int32(chrCode) == leftNoad {
  6508. prg.printEsc(strNumber( /* "left" */ 876))
  6509. } else {
  6510. prg.printEsc(strNumber( /* "right" */ 877))
  6511. }
  6512. case prefix:
  6513. if int32(chrCode) == 1 {
  6514. prg.printEsc(strNumber( /* "long" */ 1171))
  6515. } else if int32(chrCode) == 2 {
  6516. prg.printEsc(strNumber( /* "outer" */ 1172))
  6517. } else {
  6518. prg.printEsc(strNumber( /* "global" */ 1173))
  6519. }
  6520. case def:
  6521. if int32(chrCode) == 0 {
  6522. prg.printEsc(strNumber( /* "def" */ 1174))
  6523. } else if int32(chrCode) == 1 {
  6524. prg.printEsc(strNumber( /* "gdef" */ 1175))
  6525. } else if int32(chrCode) == 2 {
  6526. prg.printEsc(strNumber( /* "edef" */ 1176))
  6527. } else {
  6528. prg.printEsc(strNumber( /* "xdef" */ 1177))
  6529. }
  6530. case let:
  6531. if int32(chrCode) != normal {
  6532. prg.printEsc(strNumber( /* "futurelet" */ 1192))
  6533. } else {
  6534. prg.printEsc(strNumber( /* "let" */ 1191))
  6535. }
  6536. case shorthandDef:
  6537. switch chrCode {
  6538. case charDefCode:
  6539. prg.printEsc(strNumber( /* "chardef" */ 1193))
  6540. case mathCharDefCode:
  6541. prg.printEsc(strNumber( /* "mathchardef" */ 1194))
  6542. case countDefCode:
  6543. prg.printEsc(strNumber( /* "countdef" */ 1195))
  6544. case dimenDefCode:
  6545. prg.printEsc(strNumber( /* "dimendef" */ 1196))
  6546. case skipDefCode:
  6547. prg.printEsc(strNumber( /* "skipdef" */ 1197))
  6548. case muSkipDefCode:
  6549. prg.printEsc(strNumber( /* "muskipdef" */ 1198))
  6550. default:
  6551. prg.printEsc(strNumber( /* "toksdef" */ 1199))
  6552. }
  6553. case charGiven:
  6554. prg.printEsc(strNumber( /* "char" */ 513))
  6555. prg.printHex(int32(chrCode))
  6556. case mathGiven:
  6557. prg.printEsc(strNumber( /* "mathchar" */ 524))
  6558. prg.printHex(int32(chrCode))
  6559. case defCode:
  6560. if int32(chrCode) == catCodeBase {
  6561. prg.printEsc(strNumber( /* "catcode" */ 415))
  6562. } else if int32(chrCode) == mathCodeBase {
  6563. prg.printEsc(strNumber( /* "mathcode" */ 419))
  6564. } else if int32(chrCode) == lcCodeBase {
  6565. prg.printEsc(strNumber( /* "lccode" */ 416))
  6566. } else if int32(chrCode) == ucCodeBase {
  6567. prg.printEsc(strNumber( /* "uccode" */ 417))
  6568. } else if int32(chrCode) == sfCodeBase {
  6569. prg.printEsc(strNumber( /* "sfcode" */ 418))
  6570. } else {
  6571. prg.printEsc(strNumber( /* "delcode" */ 477))
  6572. }
  6573. case defFamily:
  6574. prg.printSize(int32(chrCode) - mathFontBase)
  6575. case hyphData:
  6576. if int32(chrCode) == 1 {
  6577. prg.printEsc(strNumber( /* "patterns" */ 953))
  6578. } else {
  6579. prg.printEsc(strNumber( /* "hyphenation" */ 941))
  6580. }
  6581. case assignFontInt:
  6582. if int32(chrCode) == 0 {
  6583. prg.printEsc(strNumber( /* "hyphenchar" */ 1217))
  6584. } else {
  6585. prg.printEsc(strNumber( /* "skewchar" */ 1218))
  6586. }
  6587. case setFont:
  6588. prg.print( /* "select font " */ 1226)
  6589. prg.slowPrint(int32(prg.fontName[chrCode]))
  6590. if prg.fontSize[chrCode] != prg.fontDsize[chrCode] {
  6591. prg.print( /* " at " */ 741)
  6592. prg.printScaled(prg.fontSize[chrCode])
  6593. prg.print( /* "pt" */ 397)
  6594. }
  6595. case setInteraction:
  6596. switch chrCode {
  6597. case batchMode:
  6598. prg.printEsc(strNumber( /* "batchmode" */ 274))
  6599. case nonstopMode:
  6600. prg.printEsc(strNumber( /* "nonstopmode" */ 275))
  6601. case scrollMode:
  6602. prg.printEsc(strNumber( /* "scrollmode" */ 276))
  6603. default:
  6604. prg.printEsc(strNumber( /* "errorstopmode" */ 1227))
  6605. }
  6606. case inStream:
  6607. if int32(chrCode) == 0 {
  6608. prg.printEsc(strNumber( /* "closein" */ 1229))
  6609. } else {
  6610. prg.printEsc(strNumber( /* "openin" */ 1228))
  6611. }
  6612. case message:
  6613. if int32(chrCode) == 0 {
  6614. prg.printEsc(strNumber( /* "message" */ 1230))
  6615. } else {
  6616. prg.printEsc(strNumber( /* "errmessage" */ 1231))
  6617. }
  6618. case caseShift:
  6619. if int32(chrCode) == lcCodeBase {
  6620. prg.printEsc(strNumber( /* "lowercase" */ 1237))
  6621. } else {
  6622. prg.printEsc(strNumber( /* "uppercase" */ 1238))
  6623. }
  6624. case xray:
  6625. switch chrCode {
  6626. case showBoxCode:
  6627. prg.printEsc(strNumber( /* "showbox" */ 1240))
  6628. case showTheCode:
  6629. prg.printEsc(strNumber( /* "showthe" */ 1241))
  6630. case showListsCode:
  6631. prg.printEsc(strNumber( /* "showlists" */ 1242))
  6632. default:
  6633. prg.printEsc(strNumber( /* "show" */ 1239))
  6634. }
  6635. case undefinedCs:
  6636. prg.print( /* "undefined" */ 1249)
  6637. case call:
  6638. prg.print( /* "macro" */ 1250)
  6639. case longCall:
  6640. prg.printEsc(strNumber( /* "long macro" */ 1251))
  6641. case outerCall:
  6642. prg.printEsc(strNumber( /* "outer macro" */ 1252))
  6643. case longOuterCall:
  6644. prg.printEsc(strNumber( /* "long" */ 1171))
  6645. prg.printEsc(strNumber( /* "outer macro" */ 1252))
  6646. case endTemplate:
  6647. prg.printEsc(strNumber( /* "outer endtemplate" */ 1253))
  6648. case extension:
  6649. switch chrCode {
  6650. case openNode:
  6651. prg.printEsc(strNumber( /* "openout" */ 1285))
  6652. case writeNode:
  6653. prg.printEsc(strNumber( /* "write" */ 594))
  6654. case closeNode:
  6655. prg.printEsc(strNumber( /* "closeout" */ 1286))
  6656. case specialNode:
  6657. prg.printEsc(strNumber( /* "special" */ 1287))
  6658. case immediateCode:
  6659. prg.printEsc(strNumber( /* "immediate" */ 1288))
  6660. case setLanguageCode:
  6661. prg.printEsc(strNumber( /* "setlanguage" */ 1289))
  6662. default:
  6663. prg.print( /* "[unknown extension!]" */ 1290)
  6664. }
  6665. default:
  6666. prg.print( /* "[unknown command code!]" */ 567)
  6667. }
  6668. }
  6669. // procedure show_eqtb( n:halfword );
  6670. // begin if n<active_base then print_char(["?"=]63) [this can't happen]
  6671. // else if n<glue_base then
  6672. // [ Show equivalent |n|, in region 1 or 2 ]
  6673. // begin sprint_cs(n); print_char(["="=]61); print_cmd_chr( eqtb[ n].hh.b0 , eqtb[ n].hh.rh );
  6674. // if eqtb[ n].hh.b0 >=call then
  6675. // begin print_char([":"=]58); show_token_list( mem[ eqtb[ n].hh.rh ].hh.rh ,0 ,32);
  6676. // end;
  6677. // end
  6678. //
  6679. // else if n<local_base then
  6680. // [ Show equivalent |n|, in region 3 ]
  6681. // if n<skip_base then
  6682. // begin print_skip_param(n-glue_base); print_char(["="=]61);
  6683. // if n<glue_base+thin_mu_skip_code then print_spec( eqtb[ n].hh.rh ,["pt"=]397)
  6684. // else print_spec( eqtb[ n].hh.rh ,["mu"=]337);
  6685. // end
  6686. // else if n<mu_skip_base then
  6687. // begin print_esc(["skip"=]395); print_int(n-skip_base); print_char(["="=]61);
  6688. // print_spec( eqtb[ n].hh.rh ,["pt"=]397);
  6689. // end
  6690. // else begin print_esc(["muskip"=]396); print_int(n-mu_skip_base); print_char(["="=]61);
  6691. // print_spec( eqtb[ n].hh.rh ,["mu"=]337);
  6692. // end
  6693. //
  6694. // else if n<int_base then
  6695. // [ Show equivalent |n|, in region 4 ]
  6696. // if n=par_shape_loc then
  6697. // begin print_esc(["parshape"=]408); print_char(["="=]61);
  6698. // if eqtb[ par_shape_loc].hh.rh =0 then print_char(["0"=]48)
  6699. // else print_int( mem[ eqtb[ par_shape_loc].hh.rh ].hh.lh );
  6700. // end
  6701. // else if n<toks_base then
  6702. // begin print_cmd_chr(assign_toks,n); print_char(["="=]61);
  6703. // if eqtb[ n].hh.rh <>0 then show_token_list( mem[ eqtb[ n].hh.rh ].hh.rh ,0 ,32);
  6704. // end
  6705. // else if n<box_base then
  6706. // begin print_esc(["toks"=]407); print_int(n-toks_base); print_char(["="=]61);
  6707. // if eqtb[ n].hh.rh <>0 then show_token_list( mem[ eqtb[ n].hh.rh ].hh.rh ,0 ,32);
  6708. // end
  6709. // else if n<cur_font_loc then
  6710. // begin print_esc(["box"=]409); print_int(n-box_base); print_char(["="=]61);
  6711. // if eqtb[ n].hh.rh =0 then print(["void"=]410)
  6712. // else begin depth_threshold:=0; breadth_max:=1; show_node_list( eqtb[ n].hh.rh );
  6713. // end;
  6714. // end
  6715. // else if n<cat_code_base then
  6716. // [ Show the font identifier in |eqtb[n]| ]
  6717. // begin if n=cur_font_loc then print(["current font"=]411)
  6718. // else if n<math_font_base+16 then
  6719. // begin print_esc(["textfont"=]412); print_int(n-math_font_base);
  6720. // end
  6721. // else if n<math_font_base+32 then
  6722. // begin print_esc(["scriptfont"=]413); print_int(n-math_font_base-16);
  6723. // end
  6724. // else begin print_esc(["scriptscriptfont"=]414); print_int(n-math_font_base-32);
  6725. // end;
  6726. // print_char(["="=]61);
  6727. //
  6728. // print_esc(hash[font_id_base+ eqtb[ n].hh.rh ].rh);
  6729. // [that's |font_id_text(equiv(n))|]
  6730. // end
  6731. //
  6732. // else
  6733. // [ Show the halfword code in |eqtb[n]| ]
  6734. // if n<math_code_base then
  6735. // begin if n<lc_code_base then
  6736. // begin print_esc(["catcode"=]415); print_int(n-cat_code_base);
  6737. // end
  6738. // else if n<uc_code_base then
  6739. // begin print_esc(["lccode"=]416); print_int(n-lc_code_base);
  6740. // end
  6741. // else if n<sf_code_base then
  6742. // begin print_esc(["uccode"=]417); print_int(n-uc_code_base);
  6743. // end
  6744. // else begin print_esc(["sfcode"=]418); print_int(n-sf_code_base);
  6745. // end;
  6746. // print_char(["="=]61); print_int( eqtb[ n].hh.rh );
  6747. // end
  6748. // else begin print_esc(["mathcode"=]419); print_int(n-math_code_base);
  6749. // print_char(["="=]61); print_int( eqtb[ n].hh.rh -0 );
  6750. // end
  6751. //
  6752. // else if n<dimen_base then
  6753. // [ Show equivalent |n|, in region 5 ]
  6754. // begin if n<count_base then print_param(n-int_base)
  6755. // else if n<del_code_base then
  6756. // begin print_esc(["count"=]476); print_int(n-count_base);
  6757. // end
  6758. // else begin print_esc(["delcode"=]477); print_int(n-del_code_base);
  6759. // end;
  6760. // print_char(["="=]61); print_int(eqtb[n].int);
  6761. // end
  6762. //
  6763. // else if n<=eqtb_size then
  6764. // [ Show equivalent |n|, in region 6 ]
  6765. // begin if n<scaled_base then print_length_param(n-dimen_base)
  6766. // else begin print_esc(["dimen"=]500); print_int(n-scaled_base);
  6767. // end;
  6768. // print_char(["="=]61); print_scaled(eqtb[n].int ); print(["pt"=]397);
  6769. // end
  6770. //
  6771. // else print_char(["?"=]63); [this can't happen either]
  6772. // end;
  6773. // [ ]
  6774. // 259.
  6775. // tangle:pos tex.web:5528:3:
  6776. // Here is the subroutine that searches the hash table for an identifier
  6777. // that matches a given string of length |l>1| appearing in |buffer[j..
  6778. // (j+l-1)]|. If the identifier is found, the corresponding hash table address
  6779. // is returned. Otherwise, if the global variable |no_new_control_sequence|
  6780. // is |true|, the dummy address |undefined_control_sequence| is returned.
  6781. // Otherwise the identifier is inserted into the hash table and its location
  6782. // is returned.
  6783. func (prg *prg) idLookup(j, l int32) (r halfword) { // go here if you found it
  6784. var (
  6785. h int32 // hash code
  6786. d int32 // number of characters in incomplete current string
  6787. p halfword // index in |hash| array
  6788. k halfword // index in |buffer| array
  6789. )
  6790. h = int32(prg.buffer[j])
  6791. for ii := j + 1; ii <= j+l-1; ii++ {
  6792. k = halfword(ii)
  6793. _ = k
  6794. h = h + h + int32(prg.buffer[k])
  6795. for h >= hashPrime {
  6796. h = h - hashPrime
  6797. }
  6798. }
  6799. p = uint16(h + hashBase) // we start searching here; note that |0<=h<hash_prime|
  6800. for true {
  6801. if int32(*prg.hash[p-514].rh()) > 0 {
  6802. if int32(prg.strStart[int32(*prg.hash[p-514].rh())+1])-int32(prg.strStart[*prg.hash[p-514].rh()]) == l {
  6803. if prg.strEqBuf(*prg.hash[p-514].rh(), j) {
  6804. goto found
  6805. }
  6806. }
  6807. }
  6808. if int32(*prg.hash[p-514].lh()) == 0 {
  6809. if prg.noNewControlSequence {
  6810. p = uint16(undefinedControlSequence)
  6811. } else {
  6812. // Insert a new control sequence after |p|, then make |p| point to it
  6813. if int32(*prg.hash[p-514].rh()) > 0 {
  6814. for {
  6815. if int32(prg.hashUsed) == hashBase {
  6816. prg.overflow(strNumber( /* "hash size" */ 503), hashSize)
  6817. }
  6818. // \xref[TeX capacity exceeded hash size][\quad hash size]
  6819. prg.hashUsed = uint16(int32(prg.hashUsed) - 1)
  6820. if int32(*prg.hash[prg.hashUsed-514].rh()) == 0 {
  6821. break
  6822. }
  6823. } // search for an empty location in |hash|
  6824. *prg.hash[p-514].lh() = prg.hashUsed
  6825. p = prg.hashUsed
  6826. }
  6827. {
  6828. if int32(prg.poolPtr)+l > poolSize {
  6829. prg.overflow(strNumber( /* "pool size" */ 257), poolSize-int32(prg.initPoolPtr))
  6830. } /* \xref[TeX capacity exceeded pool size][\quad pool size] */
  6831. }
  6832. d = int32(prg.poolPtr) - int32(prg.strStart[prg.strPtr])
  6833. for int32(prg.poolPtr) > int32(prg.strStart[prg.strPtr]) {
  6834. prg.poolPtr = uint16(int32(prg.poolPtr) - 1)
  6835. prg.strPool[int32(prg.poolPtr)+l] = prg.strPool[prg.poolPtr]
  6836. } // move current string up to make room for another
  6837. for ii := j; ii <= j+l-1; ii++ {
  6838. k = halfword(ii)
  6839. _ = k
  6840. prg.strPool[prg.poolPtr] = prg.buffer[k]
  6841. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  6842. }
  6843. *prg.hash[p-514].rh() = prg.makeString()
  6844. prg.poolPtr = uint16(int32(prg.poolPtr) + d)
  6845. // cs_count:= cs_count+1 ; [ ]
  6846. }
  6847. goto found
  6848. }
  6849. p = *prg.hash[p-514].lh()
  6850. }
  6851. found:
  6852. r = p
  6853. return r
  6854. }
  6855. // 264.
  6856. // tangle:pos tex.web:5631:3:
  6857. // We need to put \TeX's “primitive” control sequences into the hash
  6858. // table, together with their command code (which will be the |eq_type|)
  6859. // and an operand (which will be the |equiv|). The |primitive| procedure
  6860. // does this, in a way that no \TeX\ user can. The global value |cur_val|
  6861. // contains the new |eqtb| pointer after |primitive| has acted.
  6862. func (prg *prg) primitive(s strNumber, c quarterword, o halfword) {
  6863. var (
  6864. k poolPointer // index into |str_pool|
  6865. j smallNumber // index into |buffer|
  6866. l smallNumber // length of the string
  6867. )
  6868. if int32(s) < 256 {
  6869. prg.curVal = int32(s) + singleBase
  6870. } else {
  6871. k = prg.strStart[s]
  6872. l = byte(int32(prg.strStart[int32(s)+1]) - int32(k))
  6873. // we will move |s| into the (empty) |buffer|
  6874. for ii := int32(0); ii <= int32(l)-1; ii++ {
  6875. j = smallNumber(ii)
  6876. _ = j
  6877. prg.buffer[j] = prg.strPool[int32(k)+int32(j)]
  6878. }
  6879. prg.curVal = int32(prg.idLookup(0, int32(l))) // |no_new_control_sequence| is |false|
  6880. {
  6881. prg.strPtr = uint16(int32(prg.strPtr) - 1)
  6882. prg.poolPtr = prg.strStart[prg.strPtr]
  6883. }
  6884. *prg.hash[prg.curVal-514].rh() = s // we don't want to have the string twice
  6885. }
  6886. *(*prg.eqtb[prg.curVal-1].hh()).b1() = byte(levelOne)
  6887. *(*prg.eqtb[prg.curVal-1].hh()).b0() = c
  6888. *(*prg.eqtb[prg.curVal-1].hh()).rh() = o
  6889. }
  6890. // 268. \[19] Saving and restoring equivalents
  6891. // tangle:pos tex.web:5813:43:
  6892. // The nested structure provided by `$\.[\char'173]\ldots\.[\char'175]$' groups
  6893. // in \TeX\ means that |eqtb| entries valid in outer groups should be saved
  6894. // and restored later if they are overridden inside the braces. When a new |eqtb|
  6895. // value is being assigned, the program therefore checks to see if the previous
  6896. // entry belongs to an outer level. In such a case, the old value is placed
  6897. // on the |save_stack| just before the new value enters |eqtb|. At the
  6898. // end of a grouping level, i.e., when the right brace is sensed, the
  6899. // |save_stack| is used to restore the outer values, and the inner ones are
  6900. // destroyed.
  6901. //
  6902. // Entries on the |save_stack| are of type |memory_word|. The top item on
  6903. // this stack is |save_stack[p]|, where |p=save_ptr-1|; it contains three
  6904. // fields called |save_type|, |save_level|, and |save_index|, and it is
  6905. // interpreted in one of four ways:
  6906. //
  6907. // \yskip\hangg 1) If |save_type(p)=restore_old_value|, then
  6908. // |save_index(p)| is a location in |eqtb| whose current value should
  6909. // be destroyed at the end of the current group and replaced by |save_stack[p-1]|.
  6910. // Furthermore if |save_index(p)>=int_base|, then |save_level(p)|
  6911. // should replace the corresponding entry in |xeq_level|.
  6912. //
  6913. // \yskip\hangg 2) If |save_type(p)=restore_zero|, then |save_index(p)|
  6914. // is a location in |eqtb| whose current value should be destroyed at the end
  6915. // of the current group, when it should be
  6916. // replaced by the value of |eqtb[undefined_control_sequence]|.
  6917. //
  6918. // \yskip\hangg 3) If |save_type(p)=insert_token|, then |save_index(p)|
  6919. // is a token that should be inserted into \TeX's input when the current
  6920. // group ends.
  6921. //
  6922. // \yskip\hangg 4) If |save_type(p)=level_boundary|, then |save_level(p)|
  6923. // is a code explaining what kind of group we were previously in, and
  6924. // |save_index(p)| points to the level boundary word at the bottom of
  6925. // the entries for that group.
  6926. // 270.
  6927. // tangle:pos tex.web:5892:3:
  6928. // The global variable |cur_group| keeps track of what sort of group we are
  6929. // currently in. Another global variable, |cur_boundary|, points to the
  6930. // topmost |level_boundary| word. And |cur_level| is the current depth of
  6931. // nesting. The routines are designed to preserve the condition that no entry
  6932. // in the |save_stack| or in |eqtb| ever has a level greater than |cur_level|.
  6933. // 273.
  6934. // tangle:pos tex.web:5915:3:
  6935. // The following macro is used to test if there is room for up to six more
  6936. // entries on |save_stack|. By making a conservative test like this, we can
  6937. // get by with testing for overflow in only a few places.
  6938. // 274.
  6939. // tangle:pos tex.web:5925:3:
  6940. // Procedure |new_save_level| is called when a group begins. The
  6941. // argument is a group identification code like `|hbox_group|'. After
  6942. // calling this routine, it is safe to put five more entries on |save_stack|.
  6943. //
  6944. // In some cases integer-valued items are placed onto the
  6945. // |save_stack| just below a |level_boundary| word, because this is a
  6946. // convenient place to keep information that is supposed to “pop up” just
  6947. // when the group has finished.
  6948. // For example, when `\.[\\hbox to 100pt]\grp' is being treated, the 100pt
  6949. // dimension is stored on |save_stack| just before |new_save_level| is
  6950. // called.
  6951. //
  6952. // We use the notation |saved(k)| to stand for an integer item that
  6953. // appears in location |save_ptr+k| of the save stack.
  6954. func (prg *prg) newSaveLevel(c groupCode) {
  6955. if int32(prg.savePtr) > int32(prg.maxSaveStack) {
  6956. prg.maxSaveStack = prg.savePtr
  6957. if int32(prg.maxSaveStack) > saveSize-6 {
  6958. prg.overflow(strNumber( /* "save size" */ 541), saveSize)
  6959. } /* \xref[TeX capacity exceeded save size][\quad save size] */
  6960. }
  6961. *(*prg.saveStack[prg.savePtr].hh()).b0() = byte(levelBoundary)
  6962. *(*prg.saveStack[prg.savePtr].hh()).b1() = prg.curGroup
  6963. *(*prg.saveStack[prg.savePtr].hh()).rh() = prg.curBoundary
  6964. if int32(prg.curLevel) == maxQuarterword {
  6965. prg.overflow(strNumber( /* "grouping levels" */ 542), maxQuarterword-minQuarterword)
  6966. }
  6967. // quit if |(cur_level+1)| is too big to be stored in |eqtb|
  6968. prg.curBoundary = prg.savePtr
  6969. prg.curLevel = byte(int32(prg.curLevel) + 1)
  6970. prg.savePtr = uint16(int32(prg.savePtr) + 1)
  6971. prg.curGroup = c
  6972. }
  6973. // 275.
  6974. // tangle:pos tex.web:5953:3:
  6975. // Just before an entry of |eqtb| is changed, the following procedure should
  6976. // be called to update the other data structures properly. It is important
  6977. // to keep in mind that reference counts in |mem| include references from
  6978. // within |save_stack|, so these counts must be handled carefully.
  6979. // \xref[reference counts]
  6980. func (prg *prg) eqDestroy(w memoryWord) { // gets ready to forget |w|
  6981. var (
  6982. q halfword // |equiv| field of |w|
  6983. )
  6984. switch *(*w.hh()).b0() {
  6985. case call, longCall, outerCall, longOuterCall:
  6986. prg.deleteTokenRef(*(*w.hh()).rh())
  6987. case glueRef:
  6988. prg.deleteGlueRef(*(*w.hh()).rh())
  6989. case shapeRef:
  6990. q = *(*w.hh()).rh() // we need to free a \.[\\parshape] block
  6991. if int32(q) != 0 {
  6992. prg.freeNode(q, halfword(int32(*(*prg.mem[q].hh()).lh())+int32(*(*prg.mem[q].hh()).lh())+1))
  6993. }
  6994. // such a block is |2n+1| words long, where |n=info(q)|
  6995. case boxRef:
  6996. prg.flushNodeList(*(*w.hh()).rh())
  6997. default:
  6998. }
  6999. }
  7000. // 276.
  7001. // tangle:pos tex.web:5972:3:
  7002. // To save a value of |eqtb[p]| that was established at level |l|, we
  7003. // can use the following subroutine.
  7004. func (prg *prg) eqSave(p halfword, l quarterword) {
  7005. if int32(prg.savePtr) > int32(prg.maxSaveStack) {
  7006. prg.maxSaveStack = prg.savePtr
  7007. if int32(prg.maxSaveStack) > saveSize-6 {
  7008. prg.overflow(strNumber( /* "save size" */ 541), saveSize)
  7009. } /* \xref[TeX capacity exceeded save size][\quad save size] */
  7010. }
  7011. if int32(l) == levelZero {
  7012. *(*prg.saveStack[prg.savePtr].hh()).b0() = byte(restoreZero)
  7013. } else {
  7014. prg.saveStack[prg.savePtr] = prg.eqtb[p-1]
  7015. prg.savePtr = uint16(int32(prg.savePtr) + 1)
  7016. *(*prg.saveStack[prg.savePtr].hh()).b0() = byte(restoreOldValue)
  7017. }
  7018. *(*prg.saveStack[prg.savePtr].hh()).b1() = l
  7019. *(*prg.saveStack[prg.savePtr].hh()).rh() = p
  7020. prg.savePtr = uint16(int32(prg.savePtr) + 1)
  7021. }
  7022. // 277.
  7023. // tangle:pos tex.web:5984:3:
  7024. // The procedure |eq_define| defines an |eqtb| entry having specified
  7025. // |eq_type| and |equiv| fields, and saves the former value if appropriate.
  7026. // This procedure is used only for entries in the first four regions of |eqtb|,
  7027. // i.e., only for entries that have |eq_type| and |equiv| fields.
  7028. // After calling this routine, it is safe to put four more entries on
  7029. // |save_stack|, provided that there was room for four more entries before
  7030. // the call, since |eq_save| makes the necessary test.
  7031. func (prg *prg) eqDefine(p halfword, t quarterword, e halfword) {
  7032. if int32(*(*prg.eqtb[p-1].hh()).b1()) == int32(prg.curLevel) {
  7033. prg.eqDestroy(prg.eqtb[p-1])
  7034. } else if int32(prg.curLevel) > levelOne {
  7035. prg.eqSave(p, *(*prg.eqtb[p-1].hh()).b1())
  7036. }
  7037. *(*prg.eqtb[p-1].hh()).b1() = prg.curLevel
  7038. *(*prg.eqtb[p-1].hh()).b0() = t
  7039. *(*prg.eqtb[p-1].hh()).rh() = e
  7040. }
  7041. // 278.
  7042. // tangle:pos tex.web:5999:3:
  7043. // The counterpart of |eq_define| for the remaining (fullword) positions in
  7044. // |eqtb| is called |eq_word_define|. Since |xeq_level[p]>=level_one| for all
  7045. // |p|, a `|restore_zero|' will never be used in this case.
  7046. func (prg *prg) eqWordDefine(p halfword, w int32) {
  7047. if int32(prg.xeqLevel[p-5263]) != int32(prg.curLevel) {
  7048. prg.eqSave(p, prg.xeqLevel[p-5263])
  7049. prg.xeqLevel[p-5263] = prg.curLevel
  7050. }
  7051. *prg.eqtb[p-1].int() = w
  7052. }
  7053. // 279.
  7054. // tangle:pos tex.web:6010:3:
  7055. // The |eq_define| and |eq_word_define| routines take care of local definitions.
  7056. // \xref[global definitions]
  7057. // Global definitions are done in almost the same way, but there is no need
  7058. // to save old values, and the new value is associated with |level_one|.
  7059. func (prg *prg) geqDefine(p halfword, t quarterword, e halfword) {
  7060. prg.eqDestroy(prg.eqtb[p-1])
  7061. *(*prg.eqtb[p-1].hh()).b1() = byte(levelOne)
  7062. *(*prg.eqtb[p-1].hh()).b0() = t
  7063. *(*prg.eqtb[p-1].hh()).rh() = e
  7064. }
  7065. func (prg *prg) geqWordDefine(p halfword, w int32) {
  7066. *prg.eqtb[p-1].int() = w
  7067. prg.xeqLevel[p-5263] = byte(levelOne)
  7068. }
  7069. // 280.
  7070. // tangle:pos tex.web:6025:3:
  7071. // Subroutine |save_for_after| puts a token on the stack for save-keeping.
  7072. func (prg *prg) saveForAfter(t halfword) {
  7073. if int32(prg.curLevel) > levelOne {
  7074. if int32(prg.savePtr) > int32(prg.maxSaveStack) {
  7075. prg.maxSaveStack = prg.savePtr
  7076. if int32(prg.maxSaveStack) > saveSize-6 {
  7077. prg.overflow(strNumber( /* "save size" */ 541), saveSize)
  7078. } /* \xref[TeX capacity exceeded save size][\quad save size] */
  7079. }
  7080. *(*prg.saveStack[prg.savePtr].hh()).b0() = byte(insertToken)
  7081. *(*prg.saveStack[prg.savePtr].hh()).b1() = byte(levelZero)
  7082. *(*prg.saveStack[prg.savePtr].hh()).rh() = t
  7083. prg.savePtr = uint16(int32(prg.savePtr) + 1)
  7084. }
  7085. } // \2
  7086. func (prg *prg) unsave() {
  7087. var (
  7088. p halfword // position to be restored
  7089. l quarterword // saved level, if in fullword regions of |eqtb|
  7090. t halfword // saved value of |cur_tok|
  7091. )
  7092. if int32(prg.curLevel) > levelOne {
  7093. prg.curLevel = byte(int32(prg.curLevel) - 1)
  7094. // Clear off top level from |save_stack|
  7095. for true {
  7096. prg.savePtr = uint16(int32(prg.savePtr) - 1)
  7097. if int32(*(*prg.saveStack[prg.savePtr].hh()).b0()) == levelBoundary {
  7098. goto done
  7099. }
  7100. p = *(*prg.saveStack[prg.savePtr].hh()).rh()
  7101. if int32(*(*prg.saveStack[prg.savePtr].hh()).b0()) == insertToken {
  7102. t = prg.curTok
  7103. prg.curTok = p
  7104. prg.backInput()
  7105. prg.curTok = t
  7106. } else {
  7107. if int32(*(*prg.saveStack[prg.savePtr].hh()).b0()) == restoreOldValue {
  7108. l = *(*prg.saveStack[prg.savePtr].hh()).b1()
  7109. prg.savePtr = uint16(int32(prg.savePtr) - 1)
  7110. } else {
  7111. prg.saveStack[prg.savePtr] = prg.eqtb[undefinedControlSequence-1]
  7112. }
  7113. // Store \(s)|save_stack[save_ptr]| in |eqtb[p]|, unless |eqtb[p]| holds a global value
  7114. if int32(p) < intBase {
  7115. if int32(*(*prg.eqtb[p-1].hh()).b1()) == levelOne {
  7116. prg.eqDestroy(prg.saveStack[prg.savePtr]) // destroy the saved value
  7117. // if eqtb[int_base+ tracing_restores_code].int >0 then restore_trace(p,["retaining"=]544); [ ]
  7118. } else {
  7119. prg.eqDestroy(prg.eqtb[p-1]) // destroy the current value
  7120. prg.eqtb[p-1] = prg.saveStack[prg.savePtr] // restore the saved value
  7121. // if eqtb[int_base+ tracing_restores_code].int >0 then restore_trace(p,["restoring"=]545); [ ]
  7122. }
  7123. } else if int32(prg.xeqLevel[p-5263]) != levelOne {
  7124. prg.eqtb[p-1] = prg.saveStack[prg.savePtr]
  7125. prg.xeqLevel[p-5263] = l
  7126. // if eqtb[int_base+ tracing_restores_code].int >0 then restore_trace(p,["restoring"=]545); [ ]
  7127. } else {
  7128. }
  7129. }
  7130. }
  7131. done:
  7132. prg.curGroup = *(*prg.saveStack[prg.savePtr].hh()).b1()
  7133. prg.curBoundary = *(*prg.saveStack[prg.savePtr].hh()).rh()
  7134. } else {
  7135. prg.confusion(strNumber( /* "curlevel" */ 543))
  7136. } // |unsave| is not used when |cur_group=bottom_level|
  7137. // \xref[this can't happen curlevel][\quad curlevel]
  7138. }
  7139. // 288.
  7140. // tangle:pos tex.web:6129:3:
  7141. // The |prepare_mag| subroutine is called whenever \TeX\ wants to use |mag|
  7142. // for magnification.
  7143. func (prg *prg) prepareMag() {
  7144. if prg.magSet > 0 && *prg.eqtb[intBase+magCode-1].int() != prg.magSet {
  7145. {
  7146. if int32(prg.interaction) == errorStopMode {
  7147. }
  7148. prg.printNl(strNumber( /* "! " */ 262))
  7149. prg.print( /* "Incompatible magnification (" */ 547)
  7150. }
  7151. prg.printInt(*prg.eqtb[intBase+magCode-1].int())
  7152. // \xref[Incompatible magnification]
  7153. prg.print( /* ");" */ 548)
  7154. prg.printNl(strNumber( /* " the previous value will be retained" */ 549))
  7155. {
  7156. prg.helpPtr = 2
  7157. prg.helpLine[1] = /* "I can handle only one magnification ratio per job. So I've" */ 550
  7158. prg.helpLine[0] = /* "reverted to the magnification you used earlier on this run." */ 551
  7159. }
  7160. prg.intError(prg.magSet)
  7161. prg.geqWordDefine(halfword(intBase+magCode), prg.magSet) // |mag:=mag_set|
  7162. }
  7163. if *prg.eqtb[intBase+magCode-1].int() <= 0 || *prg.eqtb[intBase+magCode-1].int() > 32768 {
  7164. {
  7165. if int32(prg.interaction) == errorStopMode {
  7166. }
  7167. prg.printNl(strNumber( /* "! " */ 262))
  7168. prg.print( /* "Illegal magnification has been changed to 1000" */ 552)
  7169. }
  7170. // \xref[Illegal magnification...]
  7171. {
  7172. prg.helpPtr = 1
  7173. prg.helpLine[0] = /* "The magnification ratio must be between 1 and 32768." */ 553
  7174. }
  7175. prg.intError(*prg.eqtb[intBase+magCode-1].int())
  7176. prg.geqWordDefine(halfword(intBase+magCode), 1000)
  7177. }
  7178. prg.magSet = *prg.eqtb[intBase+magCode-1].int()
  7179. }
  7180. // 289. \[20] Token lists
  7181. // tangle:pos tex.web:6151:22:
  7182. // A \TeX\ token is either a character or a control sequence, and it is
  7183. // \xref[token]
  7184. // represented internally in one of two ways: (1)~A character whose ASCII
  7185. // code number is |c| and whose command code is |m| is represented as the
  7186. // number $2^8m+c$; the command code is in the range |1<=m<=14|. (2)~A control
  7187. // sequence whose |eqtb| address is |p| is represented as the number
  7188. // |cs_token_flag+p|. Here |cs_token_flag=$2^[12]-1$| is larger than
  7189. // $2^8m+c$, yet it is small enough that |cs_token_flag+p< max_halfword|;
  7190. // thus, a token fits comfortably in a halfword.
  7191. //
  7192. // A token |t| represents a |left_brace| command if and only if
  7193. // |t<left_brace_limit|; it represents a |right_brace| command if and only if
  7194. // we have |left_brace_limit<=t<right_brace_limit|; and it represents a |match| or
  7195. // |end_match| command if and only if |match_token<=t<=end_match_token|.
  7196. // The following definitions take care of these token-oriented constants
  7197. // and a few others.
  7198. // 291.
  7199. // tangle:pos tex.web:6187:3:
  7200. // A token list is a singly linked list of one-word nodes in |mem|, where
  7201. // each word contains a token and a link. Macro definitions, output-routine
  7202. // definitions, marks, \.[\\write] texts, and a few other things
  7203. // are remembered by \TeX\ in the form
  7204. // of token lists, usually preceded by a node with a reference count in its
  7205. // |token_ref_count| field. The token stored in location |p| is called
  7206. // |info(p)|.
  7207. //
  7208. // Three special commands appear in the token lists of macro definitions.
  7209. // When |m=match|, it means that \TeX\ should scan a parameter
  7210. // for the current macro; when |m=end_match|, it means that parameter
  7211. // matching should end and \TeX\ should start reading the macro text; and
  7212. // when |m=out_param|, it means that \TeX\ should insert parameter
  7213. // number |c| into the text at this point.
  7214. //
  7215. // The enclosing \.[\char'173] and \.[\char'175] characters of a macro
  7216. // definition are omitted, but an output routine
  7217. // will be enclosed in braces.
  7218. //
  7219. // Here is an example macro definition that illustrates these conventions.
  7220. // After \TeX\ processes the text
  7221. // $$\.[\\def\\mac a\#1\#2 \\b \[\#1\\-a \#\#1\#2 \#2\]]$$
  7222. // the definition of \.[\\mac] is represented as a token list containing
  7223. // $$\def\,[\hskip2pt]
  7224. // \vbox[\halign[\hfil#\hfil\cr
  7225. // (reference count), |letter|\,\.a, |match|\,\#, |match|\,\#, |spacer|\,\.\ ,
  7226. // \.[\\b], |end_match|,\cr
  7227. // |out_param|\,1, \.[\\-], |letter|\,\.a, |spacer|\,\.\ , |mac_param|\,\#,
  7228. // |other_char|\,\.1,\cr
  7229. // |out_param|\,2, |spacer|\,\.\ , |out_param|\,2.\cr]]$$
  7230. // The procedure |scan_toks| builds such token lists, and |macro_call|
  7231. // does the parameter matching.
  7232. // \xref[reference counts]
  7233. //
  7234. // Examples such as
  7235. // $$\.[\\def\\m\[\\def\\m\[a\]\ b\]]$$
  7236. // explain why reference counts would be needed even if \TeX\ had no \.[\\let]
  7237. // operation: When the token list for \.[\\m] is being read, the redefinition of
  7238. // \.[\\m] changes the |eqtb| entry before the token list has been fully
  7239. // consumed, so we dare not simply destroy a token list when its
  7240. // control sequence is being redefined.
  7241. //
  7242. // If the parameter-matching part of a definition ends with `\.[\#\[]',
  7243. // the corresponding token list will have `\.\[' just before the `|end_match|'
  7244. // and also at the very end. The first `\.\[' is used to delimit the parameter; the
  7245. // second one keeps the first from disappearing.
  7246. // 295.
  7247. // tangle:pos tex.web:6313:3:
  7248. // Here's the way we sometimes want to display a token list, given a pointer
  7249. // to its reference count; the pointer may be null.
  7250. func (prg *prg) tokenShow(p halfword) {
  7251. if int32(p) != 0 {
  7252. prg.showTokenList(int32(*(*prg.mem[p].hh()).rh()), 0, 10000000)
  7253. }
  7254. }
  7255. // 296.
  7256. // tangle:pos tex.web:6320:3:
  7257. // The |print_meaning| subroutine displays |cur_cmd| and |cur_chr| in
  7258. // symbolic form, including the expansion of a macro or mark.
  7259. func (prg *prg) printMeaning() {
  7260. prg.printCmdChr(prg.curCmd, prg.curChr)
  7261. if int32(prg.curCmd) >= call {
  7262. prg.printChar(asciiCode(':'))
  7263. prg.printLn()
  7264. prg.tokenShow(prg.curChr)
  7265. } else if int32(prg.curCmd) == topBotMark {
  7266. prg.printChar(asciiCode(':'))
  7267. prg.printLn()
  7268. prg.tokenShow(prg.curMark[prg.curChr])
  7269. }
  7270. }
  7271. // 299.
  7272. // tangle:pos tex.web:6419:3:
  7273. // Here is a procedure that displays the current command.
  7274. func (prg *prg) showCurCmdChr() {
  7275. prg.beginDiagnostic()
  7276. prg.printNl(strNumber('{'))
  7277. if int32(prg.curList.modeField) != int32(prg.shownMode) {
  7278. prg.printMode(int32(prg.curList.modeField))
  7279. prg.print( /* ": " */ 568)
  7280. prg.shownMode = prg.curList.modeField
  7281. }
  7282. prg.printCmdChr(prg.curCmd, prg.curChr)
  7283. prg.printChar(asciiCode('}'))
  7284. prg.endDiagnostic(false)
  7285. } // \2
  7286. func (prg *prg) showContext() {
  7287. var (
  7288. oldSetting/* 0..maxSelector */ byte // saved |selector| setting
  7289. nn int32 // number of contexts shown so far, less one
  7290. bottomLine bool // have we reached the final context to be shown?
  7291. // Local variables for formatting calculations
  7292. i/* 0..bufSize */ uint16 // index into |buffer|
  7293. j/* 0..bufSize */ uint16 // end of current line in |buffer|
  7294. l/* 0..halfErrorLine */ byte // length of descriptive information on line 1
  7295. m int32 // context information gathered for line 2
  7296. n/* 0..errorLine */ byte // length of line 1
  7297. p int32 // starting or ending place in |trick_buf|
  7298. q int32 // temporary index
  7299. )
  7300. prg.basePtr = prg.inputPtr
  7301. prg.inputStack[prg.basePtr] = prg.curInput
  7302. // store current state
  7303. nn = -1
  7304. bottomLine = false
  7305. for true {
  7306. prg.curInput = prg.inputStack[prg.basePtr] // enter into the context
  7307. if int32(prg.curInput.stateField) != tokenList {
  7308. if int32(prg.curInput.nameField) > 17 || int32(prg.basePtr) == 0 {
  7309. bottomLine = true
  7310. }
  7311. }
  7312. if int32(prg.basePtr) == int32(prg.inputPtr) || bottomLine || nn < *prg.eqtb[intBase+errorContextLinesCode-1].int() {
  7313. if int32(prg.basePtr) == int32(prg.inputPtr) || int32(prg.curInput.stateField) != tokenList || int32(prg.curInput.indexField) != backedUp || int32(prg.curInput.locField) != 0 {
  7314. prg.tally = 0 // get ready to count characters
  7315. oldSetting = prg.selector
  7316. if int32(prg.curInput.stateField) != tokenList {
  7317. if int32(prg.curInput.nameField) <= 17 {
  7318. if int32(prg.curInput.nameField) == 0 {
  7319. if int32(prg.basePtr) == 0 {
  7320. prg.printNl(strNumber( /* "<*>" */ 574))
  7321. } else {
  7322. prg.printNl(strNumber( /* "<insert> " */ 575))
  7323. }
  7324. } else {
  7325. prg.printNl(strNumber( /* "<read " */ 576))
  7326. if int32(prg.curInput.nameField) == 17 {
  7327. prg.printChar(asciiCode('*'))
  7328. } else {
  7329. prg.printInt(int32(prg.curInput.nameField) - 1)
  7330. }
  7331. // \xref[*\relax]
  7332. prg.printChar(asciiCode('>'))
  7333. }
  7334. } else {
  7335. prg.printNl(strNumber( /* "l." */ 577))
  7336. prg.printInt(prg.line)
  7337. }
  7338. prg.printChar(asciiCode(' '))
  7339. // Pseudoprint the line
  7340. {
  7341. l = byte(prg.tally)
  7342. prg.tally = 0
  7343. prg.selector = byte(pseudo)
  7344. prg.trickCount = 1000000
  7345. }
  7346. if int32(prg.buffer[prg.curInput.limitField]) == *prg.eqtb[intBase+endLineCharCode-1].int() {
  7347. j = prg.curInput.limitField
  7348. } else {
  7349. j = uint16(int32(prg.curInput.limitField) + 1)
  7350. } // determine the effective end of the line
  7351. if int32(j) > 0 {
  7352. for ii := int32(prg.curInput.startField); ii <= int32(j)-1; ii++ {
  7353. i = uint16(ii)
  7354. _ = i
  7355. if int32(i) == int32(prg.curInput.locField) {
  7356. prg.firstCount = prg.tally
  7357. prg.trickCount = prg.tally + 1 + errorLine - halfErrorLine
  7358. if prg.trickCount < errorLine {
  7359. prg.trickCount = errorLine
  7360. }
  7361. }
  7362. prg.print(int32(prg.buffer[i]))
  7363. }
  7364. }
  7365. } else {
  7366. switch prg.curInput.indexField {
  7367. case parameter:
  7368. prg.printNl(strNumber( /* "<argument> " */ 578))
  7369. case uTemplate, vTemplate:
  7370. prg.printNl(strNumber( /* "<template> " */ 579))
  7371. case backedUp:
  7372. if int32(prg.curInput.locField) == 0 {
  7373. prg.printNl(strNumber( /* "<recently read> " */ 580))
  7374. } else {
  7375. prg.printNl(strNumber( /* "<to be read again> " */ 581))
  7376. }
  7377. case inserted:
  7378. prg.printNl(strNumber( /* "<inserted text> " */ 582))
  7379. case macro:
  7380. prg.printLn()
  7381. prg.printCs(int32(prg.curInput.nameField))
  7382. case outputText:
  7383. prg.printNl(strNumber( /* "<output> " */ 583))
  7384. case everyParText:
  7385. prg.printNl(strNumber( /* "<everypar> " */ 584))
  7386. case everyMathText:
  7387. prg.printNl(strNumber( /* "<everymath> " */ 585))
  7388. case everyDisplayText:
  7389. prg.printNl(strNumber( /* "<everydisplay> " */ 586))
  7390. case everyHboxText:
  7391. prg.printNl(strNumber( /* "<everyhbox> " */ 587))
  7392. case everyVboxText:
  7393. prg.printNl(strNumber( /* "<everyvbox> " */ 588))
  7394. case everyJobText:
  7395. prg.printNl(strNumber( /* "<everyjob> " */ 589))
  7396. case everyCrText:
  7397. prg.printNl(strNumber( /* "<everycr> " */ 590))
  7398. case markText:
  7399. prg.printNl(strNumber( /* "<mark> " */ 591))
  7400. case writeText:
  7401. prg.printNl(strNumber( /* "<write> " */ 592))
  7402. default:
  7403. prg.printNl(strNumber('?')) // this should never happen
  7404. }
  7405. // Pseudoprint the token list
  7406. {
  7407. l = byte(prg.tally)
  7408. prg.tally = 0
  7409. prg.selector = byte(pseudo)
  7410. prg.trickCount = 1000000
  7411. }
  7412. if int32(prg.curInput.indexField) < macro {
  7413. prg.showTokenList(int32(prg.curInput.startField), int32(prg.curInput.locField), 100000)
  7414. } else {
  7415. prg.showTokenList(int32(*(*prg.mem[prg.curInput.startField].hh()).rh()), int32(prg.curInput.locField), 100000)
  7416. }
  7417. }
  7418. prg.selector = oldSetting // stop pseudoprinting
  7419. // Print two lines using the tricky pseudoprinted information
  7420. if prg.trickCount == 1000000 {
  7421. prg.firstCount = prg.tally
  7422. prg.trickCount = prg.tally + 1 + errorLine - halfErrorLine
  7423. if prg.trickCount < errorLine {
  7424. prg.trickCount = errorLine
  7425. }
  7426. }
  7427. // |set_trick_count| must be performed
  7428. if prg.tally < prg.trickCount {
  7429. m = prg.tally - prg.firstCount
  7430. } else {
  7431. m = prg.trickCount - prg.firstCount
  7432. } // context on line 2
  7433. if int32(l)+prg.firstCount <= halfErrorLine {
  7434. p = 0
  7435. n = byte(int32(l) + prg.firstCount)
  7436. } else {
  7437. prg.print( /* "..." */ 277)
  7438. p = int32(l) + prg.firstCount - halfErrorLine + 3
  7439. n = byte(halfErrorLine)
  7440. }
  7441. for ii := p; ii <= prg.firstCount-1; ii++ {
  7442. q = ii
  7443. _ = q
  7444. prg.printChar(prg.trickBuf[q%errorLine])
  7445. }
  7446. prg.printLn()
  7447. for ii := int32(1); ii <= int32(n); ii++ {
  7448. q = ii
  7449. _ = q
  7450. prg.printChar(asciiCode(' '))
  7451. } // print |n| spaces to begin line~2
  7452. if m+int32(n) <= errorLine {
  7453. p = prg.firstCount + m
  7454. } else {
  7455. p = prg.firstCount + (errorLine - int32(n) - 3)
  7456. }
  7457. for ii := prg.firstCount; ii <= p-1; ii++ {
  7458. q = ii
  7459. _ = q
  7460. prg.printChar(prg.trickBuf[q%errorLine])
  7461. }
  7462. if m+int32(n) > errorLine {
  7463. prg.print( /* "..." */ 277)
  7464. }
  7465. nn = nn + 1
  7466. }
  7467. } else if nn == *prg.eqtb[intBase+errorContextLinesCode-1].int() {
  7468. prg.printNl(strNumber( /* "..." */ 277))
  7469. nn = nn + 1 // omitted if |error_context_lines<0|
  7470. }
  7471. if bottomLine {
  7472. goto done
  7473. }
  7474. prg.basePtr = byte(int32(prg.basePtr) - 1)
  7475. }
  7476. done:
  7477. prg.curInput = prg.inputStack[prg.inputPtr] // restore original state
  7478. }
  7479. // 316.
  7480. // tangle:pos tex.web:6886:3:
  7481. // The following code sets up the print routines so that they will gather
  7482. // the desired information.
  7483. // 321. \[23] Maintaining the input stacks
  7484. // tangle:pos tex.web:6942:39:
  7485. // The following subroutines change the input status in commonly needed ways.
  7486. //
  7487. // First comes |push_input|, which stores the current state and creates a
  7488. // new level (having, initially, the same properties as the old).
  7489. // 322.
  7490. // tangle:pos tex.web:6958:3:
  7491. // And of course what goes up must come down.
  7492. // 323.
  7493. // tangle:pos tex.web:6964:3:
  7494. // Here is a procedure that starts a new level of token-list input, given
  7495. // a token list |p| and its type |t|. If |t=macro|, the calling routine should
  7496. // set |name| and |loc|.
  7497. func (prg *prg) beginTokenList(p halfword, t quarterword) {
  7498. {
  7499. if int32(prg.inputPtr) > int32(prg.maxInStack) {
  7500. prg.maxInStack = prg.inputPtr
  7501. if int32(prg.inputPtr) == stackSize {
  7502. prg.overflow(strNumber( /* "input stack size" */ 593), stackSize)
  7503. } /* \xref[TeX capacity exceeded input stack size][\quad input stack size] */
  7504. }
  7505. prg.inputStack[prg.inputPtr] = prg.curInput
  7506. prg.inputPtr = byte(int32(prg.inputPtr) + 1)
  7507. }
  7508. prg.curInput.stateField = byte(tokenList)
  7509. prg.curInput.startField = p
  7510. prg.curInput.indexField = t
  7511. if int32(t) >= macro {
  7512. *(*prg.mem[p].hh()).lh() = uint16(int32(*(*prg.mem[p].hh()).lh()) + 1)
  7513. if int32(t) == macro {
  7514. prg.curInput.limitField = uint16(prg.paramPtr)
  7515. } else {
  7516. prg.curInput.locField = *(*prg.mem[p].hh()).rh()
  7517. if *prg.eqtb[intBase+tracingMacrosCode-1].int() > 1 {
  7518. prg.beginDiagnostic()
  7519. prg.printNl(strNumber( /* "" */ 338))
  7520. switch t {
  7521. case markText:
  7522. prg.printEsc(strNumber( /* "mark" */ 351))
  7523. case writeText:
  7524. prg.printEsc(strNumber( /* "write" */ 594))
  7525. default:
  7526. prg.printCmdChr(quarterword(assignToks), halfword(int32(t)-outputText+outputRoutineLoc))
  7527. }
  7528. prg.print( /* "->" */ 556)
  7529. prg.tokenShow(p)
  7530. prg.endDiagnostic(false)
  7531. }
  7532. }
  7533. } else {
  7534. prg.curInput.locField = p
  7535. }
  7536. }
  7537. // 324.
  7538. // tangle:pos tex.web:6991:3:
  7539. // When a token list has been fully scanned, the following computations
  7540. // should be done as we leave that level of input. The |token_type| tends
  7541. // to be equal to either |backed_up| or |inserted| about 2/3 of the time.
  7542. // \xref[inner loop]
  7543. func (prg *prg) endTokenList() {
  7544. if int32(prg.curInput.indexField) >= backedUp {
  7545. if int32(prg.curInput.indexField) <= inserted {
  7546. prg.flushList(prg.curInput.startField)
  7547. } else {
  7548. prg.deleteTokenRef(prg.curInput.startField) // update reference count
  7549. if int32(prg.curInput.indexField) == macro {
  7550. for int32(prg.paramPtr) > int32(prg.curInput.limitField) {
  7551. prg.paramPtr = byte(int32(prg.paramPtr) - 1)
  7552. prg.flushList(prg.paramStack[prg.paramPtr])
  7553. }
  7554. }
  7555. }
  7556. } else if int32(prg.curInput.indexField) == uTemplate {
  7557. if prg.alignState > 500000 {
  7558. prg.alignState = 0
  7559. } else {
  7560. prg.fatalError(strNumber( /* "(interwoven alignment preambles are not allowed)" */ 595))
  7561. }
  7562. }
  7563. // \xref[interwoven alignment preambles...]
  7564. //
  7565. {
  7566. prg.inputPtr = byte(int32(prg.inputPtr) - 1)
  7567. prg.curInput = prg.inputStack[prg.inputPtr]
  7568. }
  7569. {
  7570. if prg.interrupt != 0 {
  7571. prg.pauseForInstructions()
  7572. }
  7573. }
  7574. }
  7575. // 281.
  7576. // tangle:pos tex.web:6035:3:
  7577. // The |unsave| routine goes the other way, taking items off of |save_stack|.
  7578. // This routine takes care of restoration when a level ends; everything
  7579. // belonging to the topmost group is cleared off of the save stack.
  7580. // \4
  7581. // Declare the procedure called |restore_trace|
  7582. // procedure restore_trace( p:halfword ; s:str_number);
  7583. // [|eqtb[p]| has just been restored or retained]
  7584. // begin begin_diagnostic; print_char(["["=]123); print(s); print_char([" "=]32);
  7585. // show_eqtb(p); print_char(["]"=]125);
  7586. // end_diagnostic(false);
  7587. // end;
  7588. // [ ]
  7589. func (prg *prg) backInput() { // undoes one token of input
  7590. var (
  7591. p halfword // a token list of length one
  7592. )
  7593. for int32(prg.curInput.stateField) == tokenList && int32(prg.curInput.locField) == 0 && int32(prg.curInput.indexField) != vTemplate {
  7594. prg.endTokenList()
  7595. } // conserve stack space
  7596. p = prg.getAvail()
  7597. *(*prg.mem[p].hh()).lh() = prg.curTok
  7598. if int32(prg.curTok) < rightBraceLimit {
  7599. if int32(prg.curTok) < leftBraceLimit {
  7600. prg.alignState = prg.alignState - 1
  7601. } else {
  7602. prg.alignState = prg.alignState + 1
  7603. }
  7604. }
  7605. /* */ {
  7606. if int32(prg.inputPtr) > int32(prg.maxInStack) {
  7607. prg.maxInStack = prg.inputPtr
  7608. if int32(prg.inputPtr) == stackSize {
  7609. prg.overflow(strNumber( /* "input stack size" */ 593), stackSize)
  7610. } /* \xref[TeX capacity exceeded input stack size][\quad input stack size] */
  7611. }
  7612. prg.inputStack[prg.inputPtr] = prg.curInput
  7613. prg.inputPtr = byte(int32(prg.inputPtr) + 1)
  7614. }
  7615. prg.curInput.stateField = byte(tokenList)
  7616. prg.curInput.startField = p
  7617. prg.curInput.indexField = byte(backedUp)
  7618. prg.curInput.locField = p // that was |back_list(p)|, without procedure overhead
  7619. }
  7620. // 327.
  7621. // tangle:pos tex.web:7039:3:
  7622. // The |back_error| routine is used when we want to replace an offending token
  7623. // just before issuing an error message. This routine, like |back_input|,
  7624. // requires that |cur_tok| has been set. We disable interrupts during the
  7625. // call of |back_input| so that the help message won't be lost.
  7626. func (prg *prg) backError() {
  7627. prg.okToInterrupt = false
  7628. prg.backInput()
  7629. prg.okToInterrupt = true
  7630. prg.error1()
  7631. }
  7632. func (prg *prg) insError() {
  7633. prg.okToInterrupt = false
  7634. prg.backInput()
  7635. prg.curInput.indexField = byte(inserted)
  7636. prg.okToInterrupt = true
  7637. prg.error1()
  7638. } // \2
  7639. func (prg *prg) beginFileReading() {
  7640. if int32(prg.inOpen) == maxInOpen {
  7641. prg.overflow(strNumber( /* "text input levels" */ 596), maxInOpen)
  7642. }
  7643. // \xref[TeX capacity exceeded text input levels][\quad text input levels]
  7644. if int32(prg.first) == bufSize {
  7645. prg.overflow(strNumber( /* "buffer size" */ 256), bufSize)
  7646. }
  7647. // \xref[TeX capacity exceeded buffer size][\quad buffer size]
  7648. prg.inOpen = byte(int32(prg.inOpen) + 1) /* */
  7649. {
  7650. if int32(prg.inputPtr) > int32(prg.maxInStack) {
  7651. prg.maxInStack = prg.inputPtr
  7652. if int32(prg.inputPtr) == stackSize {
  7653. prg.overflow(strNumber( /* "input stack size" */ 593), stackSize)
  7654. } /* \xref[TeX capacity exceeded input stack size][\quad input stack size] */
  7655. }
  7656. prg.inputStack[prg.inputPtr] = prg.curInput
  7657. prg.inputPtr = byte(int32(prg.inputPtr) + 1)
  7658. }
  7659. prg.curInput.indexField = prg.inOpen
  7660. prg.lineStack[prg.curInput.indexField-1] = prg.line
  7661. prg.curInput.startField = prg.first
  7662. prg.curInput.stateField = byte(midLine)
  7663. prg.curInput.nameField = 0 // |terminal_input| is now |true|
  7664. }
  7665. // 329.
  7666. // tangle:pos tex.web:7069:3:
  7667. // Conversely, the variables must be downdated when such a level of input
  7668. // is finished:
  7669. func (prg *prg) endFileReading() {
  7670. prg.first = prg.curInput.startField
  7671. prg.line = prg.lineStack[prg.curInput.indexField-1]
  7672. if int32(prg.curInput.nameField) > 17 {
  7673. prg.aClose(prg.inputFile[prg.curInput.indexField-1])
  7674. } // forget it
  7675. //
  7676. {
  7677. prg.inputPtr = byte(int32(prg.inputPtr) - 1)
  7678. prg.curInput = prg.inputStack[prg.inputPtr]
  7679. }
  7680. prg.inOpen = byte(int32(prg.inOpen) - 1)
  7681. } // \2
  7682. func (prg *prg) clearForErrorPrompt() {
  7683. for int32(prg.curInput.stateField) != tokenList && int32(prg.curInput.nameField) == 0 && int32(prg.inputPtr) > 0 && int32(prg.curInput.locField) > int32(prg.curInput.limitField) {
  7684. prg.endFileReading()
  7685. }
  7686. prg.printLn()
  7687. }
  7688. // 332. \[24] Getting the next token
  7689. // tangle:pos tex.web:7104:33:
  7690. // The heart of \TeX's input mechanism is the |get_next| procedure, which
  7691. // we shall develop in the next few sections of the program. Perhaps we
  7692. // shouldn't actually call it the ``heart,'' however, because it really acts
  7693. // as \TeX's eyes and mouth, reading the source files and gobbling them up.
  7694. // And it also helps \TeX\ to regurgitate stored token lists that are to be
  7695. // processed again.
  7696. // \xref[eyes and mouth]
  7697. //
  7698. // The main duty of |get_next| is to input one token and to set |cur_cmd|
  7699. // and |cur_chr| to that token's command code and modifier. Furthermore, if
  7700. // the input token is a control sequence, the |eqtb| location of that control
  7701. // sequence is stored in |cur_cs|; otherwise |cur_cs| is set to zero.
  7702. //
  7703. // Underlying this simple description is a certain amount of complexity
  7704. // because of all the cases that need to be handled.
  7705. // However, the inner loop of |get_next| is reasonably short and fast.
  7706. //
  7707. // When |get_next| is asked to get the next token of a \.[\\read] line,
  7708. // it sets |cur_cmd=cur_chr=cur_cs=0| in the case that no more tokens
  7709. // appear on that line. (There might not be any tokens at all, if the
  7710. // |end_line_char| has |ignore| as its catcode.)
  7711. // 336.
  7712. // tangle:pos tex.web:7144:3:
  7713. // Before getting into |get_next|, let's consider the subroutine that
  7714. // is called when an `\.[\\outer]' control sequence has been scanned or
  7715. // when the end of a file has been reached. These two cases are distinguished
  7716. // by |cur_cs|, which is zero at the end of a file.
  7717. func (prg *prg) checkOuterValidity() {
  7718. var (
  7719. p halfword // points to inserted token list
  7720. q halfword // auxiliary pointer
  7721. )
  7722. if int32(prg.scannerStatus) != normal {
  7723. prg.deletionsAllowed = false
  7724. // Back up an outer control sequence so that it can be reread
  7725. if int32(prg.curCs) != 0 {
  7726. if int32(prg.curInput.stateField) == tokenList || int32(prg.curInput.nameField) < 1 || int32(prg.curInput.nameField) > 17 {
  7727. p = prg.getAvail()
  7728. *(*prg.mem[p].hh()).lh() = uint16(07777 + int32(prg.curCs))
  7729. prg.beginTokenList(p, quarterword(backedUp)) // prepare to read the control sequence again
  7730. }
  7731. prg.curCmd = byte(spacer)
  7732. prg.curChr = ' ' // replace it by a space
  7733. }
  7734. if int32(prg.scannerStatus) > skipping {
  7735. prg.runaway() // print a definition, argument, or preamble
  7736. if int32(prg.curCs) == 0 {
  7737. if int32(prg.interaction) == errorStopMode {
  7738. }
  7739. prg.printNl(strNumber( /* "! " */ 262))
  7740. prg.print( /* "File ended" */ 604)
  7741. } else {
  7742. prg.curCs = 0
  7743. {
  7744. if int32(prg.interaction) == errorStopMode {
  7745. }
  7746. prg.printNl(strNumber( /* "! " */ 262))
  7747. prg.print( /* "Forbidden control sequence found" */ 605)
  7748. }
  7749. // \xref[Forbidden control sequence...]
  7750. }
  7751. prg.print( /* " while scanning " */ 606)
  7752. // Print either `\.[definition]' or `\.[use]' or `\.[preamble]' or `\.[text]', and insert tokens that should lead to recovery
  7753. p = prg.getAvail()
  7754. switch prg.scannerStatus {
  7755. case defining:
  7756. prg.print( /* "definition" */ 570)
  7757. *(*prg.mem[p].hh()).lh() = uint16(rightBraceToken + '}')
  7758. case matching:
  7759. prg.print( /* "use" */ 612)
  7760. *(*prg.mem[p].hh()).lh() = prg.parToken
  7761. prg.longState = byte(outerCall)
  7762. case aligning:
  7763. prg.print( /* "preamble" */ 572)
  7764. *(*prg.mem[p].hh()).lh() = uint16(rightBraceToken + '}')
  7765. q = p
  7766. p = prg.getAvail()
  7767. *(*prg.mem[p].hh()).rh() = q
  7768. *(*prg.mem[p].hh()).lh() = uint16(07777 + frozenCr)
  7769. prg.alignState = -1000000
  7770. case absorbing:
  7771. prg.print( /* "text" */ 573)
  7772. *(*prg.mem[p].hh()).lh() = uint16(rightBraceToken + '}')
  7773. } // there are no other cases
  7774. prg.beginTokenList(p, quarterword(inserted))
  7775. prg.print( /* " of " */ 607)
  7776. prg.sprintCs(prg.warningIndex)
  7777. {
  7778. prg.helpPtr = 4
  7779. prg.helpLine[3] = /* "I suspect you have forgotten a `]', causing me" */ 608
  7780. prg.helpLine[2] = /* "to read past where you wanted me to stop." */ 609
  7781. prg.helpLine[1] = /* "I'll try to recover; but if the error is serious," */ 610
  7782. prg.helpLine[0] = /* "you'd better type `E' or `X' now and fix your file." */ 611
  7783. }
  7784. prg.error1()
  7785. } else {
  7786. {
  7787. if int32(prg.interaction) == errorStopMode {
  7788. }
  7789. prg.printNl(strNumber( /* "! " */ 262))
  7790. prg.print( /* "Incomplete " */ 598)
  7791. }
  7792. prg.printCmdChr(quarterword(ifTest), halfword(prg.curIf))
  7793. // \xref[Incomplete \\if...]
  7794. prg.print( /* "; all text was ignored after line " */ 599)
  7795. prg.printInt(prg.skipLine)
  7796. {
  7797. prg.helpPtr = 3
  7798. prg.helpLine[2] = /* "A forbidden control sequence occurred in skipped text." */ 600
  7799. prg.helpLine[1] = /* "This kind of error happens when you say `\\if...' and forget" */ 601
  7800. prg.helpLine[0] = /* "the matching `\\fi'. I've inserted a `\\fi'; this might work." */ 602
  7801. }
  7802. if int32(prg.curCs) != 0 {
  7803. prg.curCs = 0
  7804. } else {
  7805. prg.helpLine[2] =
  7806. /* "The file ended while I was skipping conditional text." */ 603
  7807. }
  7808. prg.curTok = uint16(07777 + frozenFi)
  7809. prg.insError()
  7810. }
  7811. prg.deletionsAllowed = true
  7812. }
  7813. }
  7814. // 341.
  7815. // tangle:pos tex.web:7230:3:
  7816. // Now we're ready to take the plunge into |get_next| itself. Parts of
  7817. // this routine are executed more often than any other instructions of \TeX.
  7818. // \xref[mastication]\xref[inner loop]
  7819. func (prg *prg) getNext() { // go here when the next input token has been got
  7820. var (
  7821. k/* 0..bufSize */ uint16 // an index into |buffer|
  7822. t halfword // a token
  7823. cat/* 0..maxCharCode */ byte // |cat_code(cur_chr)|, usually
  7824. c, cc asciiCode // constituents of a possible expanded code
  7825. d/* 2..3 */ byte // number of excess characters in an expanded code
  7826. )
  7827. restart:
  7828. prg.curCs = 0
  7829. if int32(prg.curInput.stateField) != tokenList {
  7830. switch1:
  7831. if int32(prg.curInput.locField) <= int32(prg.curInput.limitField) {
  7832. prg.curChr = uint16(prg.buffer[prg.curInput.locField])
  7833. prg.curInput.locField = uint16(int32(prg.curInput.locField) + 1)
  7834. reswitch:
  7835. prg.curCmd = byte(*(*prg.eqtb[catCodeBase+int32(prg.curChr)-1].hh()).rh())
  7836. // Change state if necessary, and |goto switch| if the current character should be ignored, or |goto reswitch| if the current character changes to another
  7837. switch int32(prg.curInput.stateField) + int32(prg.curCmd) {
  7838. case midLine + 9, skipBlanks + 9, newLine + 9, skipBlanks + 10,
  7839. newLine + 10:
  7840. goto switch1
  7841. case midLine + 0, skipBlanks + 0, newLine + 0:
  7842. // Scan a control sequence and set |state:=skip_blanks| or |mid_line|
  7843. if int32(prg.curInput.locField) > int32(prg.curInput.limitField) {
  7844. prg.curCs = uint16(nullCs)
  7845. } else {
  7846. startCs:
  7847. k = prg.curInput.locField
  7848. prg.curChr = uint16(prg.buffer[k])
  7849. cat = byte(*(*prg.eqtb[catCodeBase+int32(prg.curChr)-1].hh()).rh())
  7850. k = uint16(int32(k) + 1)
  7851. if int32(cat) == letter {
  7852. prg.curInput.stateField = byte(skipBlanks)
  7853. } else if int32(cat) == spacer {
  7854. prg.curInput.stateField = byte(skipBlanks)
  7855. } else {
  7856. prg.curInput.stateField = byte(midLine)
  7857. }
  7858. if int32(cat) == letter && int32(k) <= int32(prg.curInput.limitField) {
  7859. for {
  7860. prg.curChr = uint16(prg.buffer[k])
  7861. cat = byte(*(*prg.eqtb[catCodeBase+int32(prg.curChr)-1].hh()).rh())
  7862. k = uint16(int32(k) + 1)
  7863. if int32(cat) != letter || int32(k) > int32(prg.curInput.limitField) {
  7864. break
  7865. }
  7866. }
  7867. // If an expanded...
  7868. {
  7869. if int32(prg.buffer[k]) == int32(prg.curChr) {
  7870. if int32(cat) == supMark {
  7871. if int32(k) < int32(prg.curInput.limitField) {
  7872. c = prg.buffer[int32(k)+1]
  7873. if int32(c) < 0200 {
  7874. d = 2
  7875. if int32(c) >= '0' && int32(c) <= '9' || int32(c) >= 'a' && int32(c) <= 'f' {
  7876. if int32(k)+2 <= int32(prg.curInput.limitField) {
  7877. cc = prg.buffer[int32(k)+2]
  7878. if int32(cc) >= '0' && int32(cc) <= '9' || int32(cc) >= 'a' && int32(cc) <= 'f' {
  7879. d = byte(int32(d) + 1)
  7880. }
  7881. }
  7882. }
  7883. if int32(d) > 2 {
  7884. if int32(c) <= '9' {
  7885. prg.curChr = uint16(int32(c) - '0')
  7886. } else {
  7887. prg.curChr = uint16(int32(c) - 'a' + 10)
  7888. }
  7889. if int32(cc) <= '9' {
  7890. prg.curChr = uint16(16*int32(prg.curChr) + int32(cc) - '0')
  7891. } else {
  7892. prg.curChr = uint16(16*int32(prg.curChr) + int32(cc) - 'a' + 10)
  7893. }
  7894. prg.buffer[int32(k)-1] = byte(prg.curChr)
  7895. } else if int32(c) < 0100 {
  7896. prg.buffer[int32(k)-1] = byte(int32(c) + 0100)
  7897. } else {
  7898. prg.buffer[int32(k)-1] = byte(int32(c) - 0100)
  7899. }
  7900. prg.curInput.limitField = uint16(int32(prg.curInput.limitField) - int32(d))
  7901. prg.first = uint16(int32(prg.first) - int32(d))
  7902. for int32(k) <= int32(prg.curInput.limitField) {
  7903. prg.buffer[k] = prg.buffer[int32(k)+int32(d)]
  7904. k = uint16(int32(k) + 1)
  7905. }
  7906. goto startCs
  7907. }
  7908. }
  7909. }
  7910. }
  7911. }
  7912. if int32(cat) != letter {
  7913. k = uint16(int32(k) - 1)
  7914. }
  7915. // now |k| points to first nonletter
  7916. if int32(k) > int32(prg.curInput.locField)+1 {
  7917. prg.curCs = prg.idLookup(int32(prg.curInput.locField), int32(k)-int32(prg.curInput.locField))
  7918. prg.curInput.locField = k
  7919. goto found
  7920. }
  7921. } else {
  7922. // If an expanded code is present, reduce it and |goto start_cs|
  7923. if int32(prg.buffer[k]) == int32(prg.curChr) {
  7924. if int32(cat) == supMark {
  7925. if int32(k) < int32(prg.curInput.limitField) {
  7926. c = prg.buffer[int32(k)+1]
  7927. if int32(c) < 0200 {
  7928. d = 2
  7929. if int32(c) >= '0' && int32(c) <= '9' || int32(c) >= 'a' && int32(c) <= 'f' {
  7930. if int32(k)+2 <= int32(prg.curInput.limitField) {
  7931. cc = prg.buffer[int32(k)+2]
  7932. if int32(cc) >= '0' && int32(cc) <= '9' || int32(cc) >= 'a' && int32(cc) <= 'f' {
  7933. d = byte(int32(d) + 1)
  7934. }
  7935. }
  7936. }
  7937. if int32(d) > 2 {
  7938. if int32(c) <= '9' {
  7939. prg.curChr = uint16(int32(c) - '0')
  7940. } else {
  7941. prg.curChr = uint16(int32(c) - 'a' + 10)
  7942. }
  7943. if int32(cc) <= '9' {
  7944. prg.curChr = uint16(16*int32(prg.curChr) + int32(cc) - '0')
  7945. } else {
  7946. prg.curChr = uint16(16*int32(prg.curChr) + int32(cc) - 'a' + 10)
  7947. }
  7948. prg.buffer[int32(k)-1] = byte(prg.curChr)
  7949. } else if int32(c) < 0100 {
  7950. prg.buffer[int32(k)-1] = byte(int32(c) + 0100)
  7951. } else {
  7952. prg.buffer[int32(k)-1] = byte(int32(c) - 0100)
  7953. }
  7954. prg.curInput.limitField = uint16(int32(prg.curInput.limitField) - int32(d))
  7955. prg.first = uint16(int32(prg.first) - int32(d))
  7956. for int32(k) <= int32(prg.curInput.limitField) {
  7957. prg.buffer[k] = prg.buffer[int32(k)+int32(d)]
  7958. k = uint16(int32(k) + 1)
  7959. }
  7960. goto startCs
  7961. }
  7962. }
  7963. }
  7964. }
  7965. }
  7966. prg.curCs = uint16(singleBase + int32(prg.buffer[prg.curInput.locField]))
  7967. prg.curInput.locField = uint16(int32(prg.curInput.locField) + 1)
  7968. }
  7969. found:
  7970. prg.curCmd = *(*prg.eqtb[prg.curCs-1].hh()).b0()
  7971. prg.curChr = *(*prg.eqtb[prg.curCs-1].hh()).rh()
  7972. if int32(prg.curCmd) >= outerCall {
  7973. prg.checkOuterValidity()
  7974. }
  7975. case midLine + 13, skipBlanks + 13, newLine + 13:
  7976. // Process an active-character control sequence and set |state:=mid_line|
  7977. prg.curCs = uint16(int32(prg.curChr) + activeBase)
  7978. prg.curCmd = *(*prg.eqtb[prg.curCs-1].hh()).b0()
  7979. prg.curChr = *(*prg.eqtb[prg.curCs-1].hh()).rh()
  7980. prg.curInput.stateField = byte(midLine)
  7981. if int32(prg.curCmd) >= outerCall {
  7982. prg.checkOuterValidity()
  7983. }
  7984. case midLine + 7, skipBlanks + 7, newLine + 7:
  7985. // If this |sup_mark| starts an expanded character like~\.[\^\^A] or~\.[\^\^df], then |goto reswitch|, otherwise set |state:=mid_line|
  7986. if int32(prg.curChr) == int32(prg.buffer[prg.curInput.locField]) {
  7987. if int32(prg.curInput.locField) < int32(prg.curInput.limitField) {
  7988. c = prg.buffer[int32(prg.curInput.locField)+1]
  7989. if int32(c) < 0200 {
  7990. prg.curInput.locField = uint16(int32(prg.curInput.locField) + 2)
  7991. if int32(c) >= '0' && int32(c) <= '9' || int32(c) >= 'a' && int32(c) <= 'f' {
  7992. if int32(prg.curInput.locField) <= int32(prg.curInput.limitField) {
  7993. cc = prg.buffer[prg.curInput.locField]
  7994. if int32(cc) >= '0' && int32(cc) <= '9' || int32(cc) >= 'a' && int32(cc) <= 'f' {
  7995. prg.curInput.locField = uint16(int32(prg.curInput.locField) + 1)
  7996. if int32(c) <= '9' {
  7997. prg.curChr = uint16(int32(c) - '0')
  7998. } else {
  7999. prg.curChr = uint16(int32(c) - 'a' + 10)
  8000. }
  8001. if int32(cc) <= '9' {
  8002. prg.curChr = uint16(16*int32(prg.curChr) + int32(cc) - '0')
  8003. } else {
  8004. prg.curChr = uint16(16*int32(prg.curChr) + int32(cc) - 'a' + 10)
  8005. }
  8006. goto reswitch
  8007. }
  8008. }
  8009. }
  8010. if int32(c) < 0100 {
  8011. prg.curChr = uint16(int32(c) + 0100)
  8012. } else {
  8013. prg.curChr = uint16(int32(c) - 0100)
  8014. }
  8015. goto reswitch
  8016. }
  8017. }
  8018. }
  8019. prg.curInput.stateField = byte(midLine)
  8020. case midLine + 15, skipBlanks + 15, newLine + 15:
  8021. // Decry the invalid character and |goto restart|
  8022. {
  8023. if int32(prg.interaction) == errorStopMode {
  8024. }
  8025. prg.printNl(strNumber( /* "! " */ 262))
  8026. prg.print( /* "Text line contains an invalid character" */ 613)
  8027. }
  8028. // \xref[Text line contains...]
  8029. {
  8030. prg.helpPtr = 2
  8031. prg.helpLine[1] = /* "A funny symbol that I can't read has just been input." */ 614
  8032. prg.helpLine[0] = /* "Continue, and I'll forget that it ever happened." */ 615
  8033. }
  8034. prg.deletionsAllowed = false
  8035. prg.error1()
  8036. prg.deletionsAllowed = true
  8037. goto restart
  8038. // \4
  8039. // Handle situations involving spaces, braces, changes of state
  8040. case midLine + 10:
  8041. // Enter |skip_blanks| state, emit a space
  8042. prg.curInput.stateField = byte(skipBlanks)
  8043. prg.curChr = ' '
  8044. case midLine + 5:
  8045. // Finish line, emit a space
  8046. prg.curInput.locField = uint16(int32(prg.curInput.limitField) + 1)
  8047. prg.curCmd = byte(spacer)
  8048. prg.curChr = ' '
  8049. case skipBlanks + 5, midLine + 14, skipBlanks + 14, newLine + 14:
  8050. // Finish line, |goto switch|
  8051. prg.curInput.locField = uint16(int32(prg.curInput.limitField) + 1)
  8052. goto switch1
  8053. case newLine + 5:
  8054. // Finish line, emit a \.[\\par]
  8055. prg.curInput.locField = uint16(int32(prg.curInput.limitField) + 1)
  8056. prg.curCs = prg.parLoc
  8057. prg.curCmd = *(*prg.eqtb[prg.curCs-1].hh()).b0()
  8058. prg.curChr = *(*prg.eqtb[prg.curCs-1].hh()).rh()
  8059. if int32(prg.curCmd) >= outerCall {
  8060. prg.checkOuterValidity()
  8061. }
  8062. case midLine + 1:
  8063. prg.alignState = prg.alignState + 1
  8064. case skipBlanks + 1, newLine + 1:
  8065. prg.curInput.stateField = byte(midLine)
  8066. prg.alignState = prg.alignState + 1
  8067. case midLine + 2:
  8068. prg.alignState = prg.alignState - 1
  8069. case skipBlanks + 2, newLine + 2:
  8070. prg.curInput.stateField = byte(midLine)
  8071. prg.alignState = prg.alignState - 1
  8072. case skipBlanks + 3, skipBlanks + 4, skipBlanks + 6, skipBlanks + 8,
  8073. skipBlanks + 11, skipBlanks + 12, newLine + 3, newLine + 4,
  8074. newLine + 6, newLine + 8, newLine + 11, newLine + 12:
  8075. prg.curInput.stateField = byte(midLine)
  8076. default:
  8077. }
  8078. } else {
  8079. prg.curInput.stateField = byte(newLine)
  8080. // Move to next line of file, or |goto restart| if there is no next line, or |return| if a \.[\\read] line has finished
  8081. if int32(prg.curInput.nameField) > 17 {
  8082. prg.line = prg.line + 1
  8083. prg.first = prg.curInput.startField
  8084. if !prg.forceEof {
  8085. if prg.inputLn(prg.inputFile[prg.curInput.indexField-1], true) {
  8086. prg.firmUpTheLine()
  8087. } else {
  8088. prg.forceEof = true
  8089. }
  8090. }
  8091. if prg.forceEof {
  8092. prg.printChar(asciiCode(')'))
  8093. prg.openParens = byte(int32(prg.openParens) - 1)
  8094. // show user that file has been read
  8095. prg.forceEof = false
  8096. prg.endFileReading() // resume previous level
  8097. prg.checkOuterValidity()
  8098. goto restart
  8099. }
  8100. if *prg.eqtb[intBase+endLineCharCode-1].int() < 0 || *prg.eqtb[intBase+endLineCharCode-1].int() > 255 {
  8101. prg.curInput.limitField = uint16(int32(prg.curInput.limitField) - 1)
  8102. } else {
  8103. prg.buffer[prg.curInput.limitField] = byte(*prg.eqtb[intBase+endLineCharCode-1].int())
  8104. }
  8105. prg.first = uint16(int32(prg.curInput.limitField) + 1)
  8106. prg.curInput.locField = prg.curInput.startField // ready to read
  8107. } else {
  8108. if !(int32(prg.curInput.nameField) == 0) {
  8109. prg.curCmd = 0
  8110. prg.curChr = 0
  8111. goto exit
  8112. }
  8113. if int32(prg.inputPtr) > 0 {
  8114. prg.endFileReading()
  8115. goto restart // resume previous level
  8116. }
  8117. if int32(prg.selector) < logOnly {
  8118. prg.openLogFile()
  8119. }
  8120. if int32(prg.interaction) > nonstopMode {
  8121. if *prg.eqtb[intBase+endLineCharCode-1].int() < 0 || *prg.eqtb[intBase+endLineCharCode-1].int() > 255 {
  8122. prg.curInput.limitField = uint16(int32(prg.curInput.limitField) + 1)
  8123. }
  8124. if int32(prg.curInput.limitField) == int32(prg.curInput.startField) {
  8125. prg.printNl(strNumber( /* "(Please type a command or say `\\end')" */ 616))
  8126. }
  8127. // \xref[Please type...]
  8128. prg.printLn()
  8129. prg.first = prg.curInput.startField
  8130. {
  8131. prg.print('*')
  8132. prg.termInput()
  8133. } // input on-line into |buffer|
  8134. // \xref[*\relax]
  8135. prg.curInput.limitField = prg.last
  8136. if *prg.eqtb[intBase+endLineCharCode-1].int() < 0 || *prg.eqtb[intBase+endLineCharCode-1].int() > 255 {
  8137. prg.curInput.limitField = uint16(int32(prg.curInput.limitField) - 1)
  8138. } else {
  8139. prg.buffer[prg.curInput.limitField] = byte(*prg.eqtb[intBase+endLineCharCode-1].int())
  8140. }
  8141. prg.first = uint16(int32(prg.curInput.limitField) + 1)
  8142. prg.curInput.locField = prg.curInput.startField
  8143. } else {
  8144. prg.fatalError(strNumber( /* "*** (job aborted, no legal \\end found)" */ 617))
  8145. }
  8146. // \xref[job aborted]
  8147. // nonstop mode, which is intended for overnight batch processing,
  8148. // never waits for on-line input
  8149. }
  8150. {
  8151. if prg.interrupt != 0 {
  8152. prg.pauseForInstructions()
  8153. }
  8154. }
  8155. goto switch1
  8156. }
  8157. } else if int32(prg.curInput.locField) != 0 {
  8158. t = *(*prg.mem[prg.curInput.locField].hh()).lh()
  8159. prg.curInput.locField = *(*prg.mem[prg.curInput.locField].hh()).rh() // move to next
  8160. if int32(t) >= 07777 {
  8161. prg.curCs = uint16(int32(t) - 07777)
  8162. prg.curCmd = *(*prg.eqtb[prg.curCs-1].hh()).b0()
  8163. prg.curChr = *(*prg.eqtb[prg.curCs-1].hh()).rh()
  8164. if int32(prg.curCmd) >= outerCall {
  8165. if int32(prg.curCmd) == dontExpand {
  8166. prg.curCs = uint16(int32(*(*prg.mem[prg.curInput.locField].hh()).lh()) - 07777)
  8167. prg.curInput.locField = 0
  8168. prg.curCmd = *(*prg.eqtb[prg.curCs-1].hh()).b0()
  8169. prg.curChr = *(*prg.eqtb[prg.curCs-1].hh()).rh()
  8170. if int32(prg.curCmd) > maxCommand {
  8171. prg.curCmd = byte(relax)
  8172. prg.curChr = uint16(noExpandFlag)
  8173. }
  8174. } else {
  8175. prg.checkOuterValidity()
  8176. }
  8177. }
  8178. } else {
  8179. prg.curCmd = byte(int32(t) / 0400)
  8180. prg.curChr = uint16(int32(t) % 0400)
  8181. switch prg.curCmd {
  8182. case leftBrace:
  8183. prg.alignState = prg.alignState + 1
  8184. case rightBrace:
  8185. prg.alignState = prg.alignState - 1
  8186. case outParam:
  8187. // Insert macro parameter and |goto restart|
  8188. prg.beginTokenList(prg.paramStack[int32(prg.curInput.limitField)+int32(prg.curChr)-1], quarterword(parameter))
  8189. goto restart
  8190. default:
  8191. }
  8192. }
  8193. } else {
  8194. prg.endTokenList()
  8195. goto restart // resume previous level
  8196. }
  8197. // If an alignment entry has just ended, take appropriate action
  8198. if int32(prg.curCmd) <= carRet {
  8199. if int32(prg.curCmd) >= tabMark {
  8200. if prg.alignState == 0 {
  8201. if int32(prg.scannerStatus) == aligning || int32(prg.curAlign) == 0 {
  8202. prg.fatalError(strNumber( /* "(interwoven alignment preambles are not allowed)" */ 595))
  8203. }
  8204. // \xref[interwoven alignment preambles...]
  8205. prg.curCmd = byte(*(*prg.mem[int32(prg.curAlign)+listOffset].hh()).lh())
  8206. *(*prg.mem[int32(prg.curAlign)+listOffset].hh()).lh() = prg.curChr
  8207. if int32(prg.curCmd) == omit {
  8208. prg.beginTokenList(halfword(30000-10), quarterword(vTemplate))
  8209. } else {
  8210. prg.beginTokenList(halfword(*prg.mem[int32(prg.curAlign)+depthOffset].int()), quarterword(vTemplate))
  8211. }
  8212. prg.alignState = 1000000
  8213. goto restart
  8214. }
  8215. }
  8216. }
  8217. exit:
  8218. }
  8219. // 340.
  8220. // tangle:pos tex.web:7226:3:
  8221. // We need to mention a procedure here that may be called by |get_next|.
  8222. func (prg *prg) firmUpTheLine() {
  8223. var (
  8224. k /* 0..bufSize */ uint16 // an index into |buffer|
  8225. )
  8226. prg.curInput.limitField = prg.last
  8227. if *prg.eqtb[intBase+pausingCode-1].int() > 0 {
  8228. if int32(prg.interaction) > nonstopMode {
  8229. prg.printLn()
  8230. if int32(prg.curInput.startField) < int32(prg.curInput.limitField) {
  8231. for ii := int32(prg.curInput.startField); ii <= int32(prg.curInput.limitField)-1; ii++ {
  8232. k = uint16(ii)
  8233. _ = k
  8234. prg.print(int32(prg.buffer[k]))
  8235. }
  8236. }
  8237. prg.first = prg.curInput.limitField
  8238. {
  8239. prg.print( /* "=>" */ 618)
  8240. prg.termInput()
  8241. } // wait for user response
  8242. // \xref[=>]
  8243. if int32(prg.last) > int32(prg.first) {
  8244. for ii := int32(prg.first); ii <= int32(prg.last)-1; ii++ {
  8245. k = uint16(ii)
  8246. _ = k // move line down in buffer
  8247. prg.buffer[int32(k)+int32(prg.curInput.startField)-int32(prg.first)] = prg.buffer[k]
  8248. }
  8249. prg.curInput.limitField = uint16(int32(prg.curInput.startField) + int32(prg.last) - int32(prg.first))
  8250. }
  8251. }
  8252. }
  8253. } // \2
  8254. func (prg *prg) getToken() {
  8255. prg.noNewControlSequence = false
  8256. prg.getNext()
  8257. prg.noNewControlSequence = true
  8258. // \xref[inner loop]
  8259. if int32(prg.curCs) == 0 {
  8260. prg.curTok = uint16(int32(prg.curCmd)*0400 + int32(prg.curChr))
  8261. } else {
  8262. prg.curTok = uint16(07777 + int32(prg.curCs))
  8263. }
  8264. }
  8265. // 366. \[25] Expanding the next token
  8266. // tangle:pos tex.web:7636:33:
  8267. // Only a dozen or so command codes |>max_command| can possibly be returned by
  8268. // |get_next|; in increasing order, they are |undefined_cs|, |expand_after|,
  8269. // |no_expand|, |input|, |if_test|, |fi_or_else|, |cs_name|, |convert|, |the|,
  8270. // |top_bot_mark|, |call|, |long_call|, |outer_call|, |long_outer_call|, and
  8271. // |end_template|.[\emergencystretch=40pt\par]
  8272. //
  8273. // The |expand| subroutine is used when |cur_cmd>max_command|. It removes a
  8274. // “call” or a conditional or one of the other special operations just
  8275. // listed. It follows that |expand| might invoke itself recursively. In all
  8276. // cases, |expand| destroys the current token, but it sets things up so that
  8277. // the next |get_next| will deliver the appropriate next token. The value of
  8278. // |cur_tok| need not be known when |expand| is called.
  8279. //
  8280. // Since several of the basic scanning routines communicate via global variables,
  8281. // their values are saved as local variables of |expand| so that
  8282. // recursive calls don't invalidate them.
  8283. // \xref[recursion]
  8284. // \4
  8285. // Declare the procedure called |macro_call|
  8286. func (prg *prg) macroCall() {
  8287. var (
  8288. r1 halfword // current node in the macro's token list
  8289. p halfword // current node in parameter token list being built
  8290. q halfword // new node being put into the token list
  8291. s halfword // backup pointer for parameter matching
  8292. t halfword // cycle pointer for backup recovery
  8293. u, v halfword // auxiliary pointers for backup recovery
  8294. rbracePtr halfword // one step before the last |right_brace| token
  8295. n smallNumber // the number of parameters scanned
  8296. unbalance halfword // unmatched left braces in current parameter
  8297. m halfword // the number of tokens or groups (usually)
  8298. refCount halfword // start of the token list
  8299. saveScannerStatus smallNumber // |scanner_status| upon entry
  8300. saveWarningIndex halfword // |warning_index| upon entry
  8301. matchChr asciiCode // character used in parameter
  8302. )
  8303. saveScannerStatus = prg.scannerStatus
  8304. saveWarningIndex = prg.warningIndex
  8305. prg.warningIndex = prg.curCs
  8306. refCount = prg.curChr
  8307. r1 = *(*prg.mem[refCount].hh()).rh()
  8308. n = 0
  8309. if *prg.eqtb[intBase+tracingMacrosCode-1].int() > 0 {
  8310. prg.beginDiagnostic()
  8311. prg.printLn()
  8312. prg.printCs(int32(prg.warningIndex))
  8313. prg.tokenShow(refCount)
  8314. prg.endDiagnostic(false)
  8315. }
  8316. if int32(*(*prg.mem[r1].hh()).lh()) != endMatchToken {
  8317. prg.scannerStatus = byte(matching)
  8318. unbalance = 0
  8319. prg.longState = *(*prg.eqtb[prg.curCs-1].hh()).b0()
  8320. if int32(prg.longState) >= outerCall {
  8321. prg.longState = byte(int32(prg.longState) - 2)
  8322. }
  8323. for {
  8324. *(*prg.mem[30000-3].hh()).rh() = 0
  8325. if int32(*(*prg.mem[r1].hh()).lh()) > matchToken+255 || int32(*(*prg.mem[r1].hh()).lh()) < matchToken {
  8326. s = 0
  8327. } else {
  8328. matchChr = byte(int32(*(*prg.mem[r1].hh()).lh()) - matchToken)
  8329. s = *(*prg.mem[r1].hh()).rh()
  8330. r1 = s
  8331. p = uint16(30000 - 3)
  8332. m = 0
  8333. }
  8334. // Scan a parameter until its delimiter string has been found; or, if |s=null|, simply scan the delimiter string
  8335. // Scan a parameter until its delimiter string has been found; or, if |s=null|, simply scan the delimiter string
  8336. continue1:
  8337. prg.getToken() // set |cur_tok| to the next token of input
  8338. if int32(prg.curTok) == int32(*(*prg.mem[r1].hh()).lh()) {
  8339. r1 = *(*prg.mem[r1].hh()).rh()
  8340. if int32(*(*prg.mem[r1].hh()).lh()) >= matchToken && int32(*(*prg.mem[r1].hh()).lh()) <= endMatchToken {
  8341. if int32(prg.curTok) < leftBraceLimit {
  8342. prg.alignState = prg.alignState - 1
  8343. }
  8344. goto found
  8345. } else {
  8346. goto continue1
  8347. }
  8348. }
  8349. // Contribute the recently matched tokens to the current parameter, and |goto continue| if a partial match is still in effect; but abort if |s=null|
  8350. if int32(s) != int32(r1) {
  8351. if int32(s) == 0 {
  8352. {
  8353. if int32(prg.interaction) == errorStopMode {
  8354. }
  8355. prg.printNl(strNumber( /* "! " */ 262))
  8356. prg.print( /* "Use of " */ 650)
  8357. }
  8358. prg.sprintCs(prg.warningIndex)
  8359. // \xref[Use of x doesn't match...]
  8360. prg.print( /* " doesn't match its definition" */ 651)
  8361. {
  8362. prg.helpPtr = 4
  8363. prg.helpLine[3] = /* "If you say, e.g., `\\def\\a1[...]', then you must always" */ 652
  8364. prg.helpLine[2] = /* "put `1' after `\\a', since control sequence names are" */ 653
  8365. prg.helpLine[1] = /* "made up of letters only. The macro here has not been" */ 654
  8366. prg.helpLine[0] = /* "followed by the required stuff, so I'm ignoring it." */ 655
  8367. }
  8368. prg.error1()
  8369. goto exit
  8370. } else {
  8371. t = s
  8372. for {
  8373. {
  8374. q = prg.getAvail()
  8375. *(*prg.mem[p].hh()).rh() = q
  8376. *(*prg.mem[q].hh()).lh() = *(*prg.mem[t].hh()).lh()
  8377. p = q
  8378. }
  8379. m = uint16(int32(m) + 1)
  8380. u = *(*prg.mem[t].hh()).rh()
  8381. v = s
  8382. for true {
  8383. if int32(u) == int32(r1) {
  8384. if int32(prg.curTok) != int32(*(*prg.mem[v].hh()).lh()) {
  8385. goto done
  8386. } else {
  8387. r1 = *(*prg.mem[v].hh()).rh()
  8388. goto continue1
  8389. }
  8390. }
  8391. if int32(*(*prg.mem[u].hh()).lh()) != int32(*(*prg.mem[v].hh()).lh()) {
  8392. goto done
  8393. }
  8394. u = *(*prg.mem[u].hh()).rh()
  8395. v = *(*prg.mem[v].hh()).rh()
  8396. }
  8397. done:
  8398. t = *(*prg.mem[t].hh()).rh()
  8399. if int32(t) == int32(r1) {
  8400. break
  8401. }
  8402. }
  8403. r1 = s // at this point, no tokens are recently matched
  8404. }
  8405. }
  8406. if int32(prg.curTok) == int32(prg.parToken) {
  8407. if int32(prg.longState) != longCall {
  8408. if int32(prg.longState) == call {
  8409. prg.runaway()
  8410. {
  8411. if int32(prg.interaction) == errorStopMode {
  8412. }
  8413. prg.printNl(strNumber( /* "! " */ 262))
  8414. prg.print( /* "Paragraph ended before " */ 645)
  8415. }
  8416. // \xref[Paragraph ended before...]
  8417. prg.sprintCs(prg.warningIndex)
  8418. prg.print( /* " was complete" */ 646)
  8419. {
  8420. prg.helpPtr = 3
  8421. prg.helpLine[2] = /* "I suspect you've forgotten a `]', causing me to apply this" */ 647
  8422. prg.helpLine[1] = /* "control sequence to too much text. How can we recover?" */ 648
  8423. prg.helpLine[0] = /* "My plan is to forget the whole thing and hope for the best." */ 649
  8424. }
  8425. prg.backError()
  8426. }
  8427. prg.pstack[n] = *(*prg.mem[30000-3].hh()).rh()
  8428. prg.alignState = prg.alignState - int32(unbalance)
  8429. for ii := int32(0); ii <= int32(n); ii++ {
  8430. m = halfword(ii)
  8431. _ = m
  8432. prg.flushList(prg.pstack[m])
  8433. }
  8434. goto exit
  8435. }
  8436. }
  8437. if int32(prg.curTok) < rightBraceLimit {
  8438. if int32(prg.curTok) < leftBraceLimit {
  8439. unbalance = 1
  8440. // \xref[inner loop]
  8441. for true {
  8442. {
  8443. {
  8444. q = prg.avail
  8445. if int32(q) == 0 {
  8446. q = prg.getAvail()
  8447. } else {
  8448. prg.avail = *(*prg.mem[q].hh()).rh()
  8449. *(*prg.mem[q].hh()).rh() = 0 /* dyn_used:= dyn_used+1 ; [ ] */
  8450. }
  8451. }
  8452. *(*prg.mem[p].hh()).rh() = q
  8453. *(*prg.mem[q].hh()).lh() = prg.curTok
  8454. p = q
  8455. }
  8456. prg.getToken()
  8457. if int32(prg.curTok) == int32(prg.parToken) {
  8458. if int32(prg.longState) != longCall {
  8459. if int32(prg.longState) == call {
  8460. prg.runaway()
  8461. {
  8462. if int32(prg.interaction) == errorStopMode {
  8463. }
  8464. prg.printNl(strNumber( /* "! " */ 262))
  8465. prg.print( /* "Paragraph ended before " */ 645)
  8466. }
  8467. // \xref[Paragraph ended before...]
  8468. prg.sprintCs(prg.warningIndex)
  8469. prg.print( /* " was complete" */ 646)
  8470. {
  8471. prg.helpPtr = 3
  8472. prg.helpLine[2] = /* "I suspect you've forgotten a `]', causing me to apply this" */ 647
  8473. prg.helpLine[1] = /* "control sequence to too much text. How can we recover?" */ 648
  8474. prg.helpLine[0] = /* "My plan is to forget the whole thing and hope for the best." */ 649
  8475. }
  8476. prg.backError()
  8477. }
  8478. prg.pstack[n] = *(*prg.mem[30000-3].hh()).rh()
  8479. prg.alignState = prg.alignState - int32(unbalance)
  8480. for ii := int32(0); ii <= int32(n); ii++ {
  8481. m = halfword(ii)
  8482. _ = m
  8483. prg.flushList(prg.pstack[m])
  8484. }
  8485. goto exit
  8486. }
  8487. }
  8488. if int32(prg.curTok) < rightBraceLimit {
  8489. if int32(prg.curTok) < leftBraceLimit {
  8490. unbalance = uint16(int32(unbalance) + 1)
  8491. } else {
  8492. unbalance = uint16(int32(unbalance) - 1)
  8493. if int32(unbalance) == 0 {
  8494. goto done1
  8495. }
  8496. }
  8497. }
  8498. }
  8499. done1:
  8500. rbracePtr = p
  8501. {
  8502. q = prg.getAvail()
  8503. *(*prg.mem[p].hh()).rh() = q
  8504. *(*prg.mem[q].hh()).lh() = prg.curTok
  8505. p = q
  8506. }
  8507. } else {
  8508. // Report an extra right brace and |goto continue|
  8509. prg.backInput()
  8510. {
  8511. if int32(prg.interaction) == errorStopMode {
  8512. }
  8513. prg.printNl(strNumber( /* "! " */ 262))
  8514. prg.print( /* "Argument of " */ 637)
  8515. }
  8516. prg.sprintCs(prg.warningIndex)
  8517. // \xref[Argument of \\x has...]
  8518. prg.print( /* " has an extra ]" */ 638)
  8519. {
  8520. prg.helpPtr = 6
  8521. prg.helpLine[5] = /* "I've run across a `]' that doesn't seem to match anything." */ 639
  8522. prg.helpLine[4] = /* "For example, `\\def\\a#1[...]' and `\\a]' would produce" */ 640
  8523. prg.helpLine[3] = /* "this error. If you simply proceed now, the `\\par' that" */ 641
  8524. prg.helpLine[2] = /* "I've just inserted will cause me to report a runaway" */ 642
  8525. prg.helpLine[1] = /* "argument that might be the root of the problem. But if" */ 643
  8526. prg.helpLine[0] = /* "your `]' was spurious, just type `2' and it will go away." */ 644
  8527. }
  8528. prg.alignState = prg.alignState + 1
  8529. prg.longState = byte(call)
  8530. prg.curTok = prg.parToken
  8531. prg.insError()
  8532. goto continue1
  8533. }
  8534. } else {
  8535. // Store the current token, but |goto continue| if it is a blank space that would become an undelimited parameter
  8536. if int32(prg.curTok) == spaceToken {
  8537. if int32(*(*prg.mem[r1].hh()).lh()) <= endMatchToken {
  8538. if int32(*(*prg.mem[r1].hh()).lh()) >= matchToken {
  8539. goto continue1
  8540. }
  8541. }
  8542. }
  8543. {
  8544. q = prg.getAvail()
  8545. *(*prg.mem[p].hh()).rh() = q
  8546. *(*prg.mem[q].hh()).lh() = prg.curTok
  8547. p = q
  8548. }
  8549. }
  8550. m = uint16(int32(m) + 1)
  8551. if int32(*(*prg.mem[r1].hh()).lh()) > endMatchToken {
  8552. goto continue1
  8553. }
  8554. if int32(*(*prg.mem[r1].hh()).lh()) < matchToken {
  8555. goto continue1
  8556. }
  8557. found:
  8558. if int32(s) != 0 {
  8559. if int32(m) == 1 && int32(*(*prg.mem[p].hh()).lh()) < rightBraceLimit {
  8560. *(*prg.mem[rbracePtr].hh()).rh() = 0
  8561. {
  8562. *(*prg.mem[p].hh()).rh() = prg.avail
  8563. prg.avail = p /* dyn_used:= dyn_used-1 ; [ ] */
  8564. }
  8565. p = *(*prg.mem[30000-3].hh()).rh()
  8566. prg.pstack[n] = *(*prg.mem[p].hh()).rh()
  8567. {
  8568. *(*prg.mem[p].hh()).rh() = prg.avail
  8569. prg.avail = p /* dyn_used:= dyn_used-1 ; [ ] */
  8570. }
  8571. } else {
  8572. prg.pstack[n] = *(*prg.mem[30000-3].hh()).rh()
  8573. }
  8574. n = byte(int32(n) + 1)
  8575. if *prg.eqtb[intBase+tracingMacrosCode-1].int() > 0 {
  8576. prg.beginDiagnostic()
  8577. prg.printNl(strNumber(matchChr))
  8578. prg.printInt(int32(n))
  8579. prg.print( /* "<-" */ 656)
  8580. prg.showTokenList(int32(prg.pstack[int32(n)-1]), 0, 1000)
  8581. prg.endDiagnostic(false)
  8582. }
  8583. }
  8584. // now |info(r)| is a token whose command code is either |match| or |end_match|
  8585. if int32(*(*prg.mem[r1].hh()).lh()) == endMatchToken {
  8586. break
  8587. }
  8588. }
  8589. }
  8590. // Feed the macro body and its parameters to the scanner
  8591. for int32(prg.curInput.stateField) == tokenList && int32(prg.curInput.locField) == 0 && int32(prg.curInput.indexField) != vTemplate {
  8592. prg.endTokenList()
  8593. } // conserve stack space
  8594. prg.beginTokenList(refCount, quarterword(macro))
  8595. prg.curInput.nameField = prg.warningIndex
  8596. prg.curInput.locField = *(*prg.mem[r1].hh()).rh()
  8597. if int32(n) > 0 {
  8598. if int32(prg.paramPtr)+int32(n) > prg.maxParamStack {
  8599. prg.maxParamStack = int32(prg.paramPtr) + int32(n)
  8600. if prg.maxParamStack > paramSize {
  8601. prg.overflow(strNumber( /* "parameter stack size" */ 636), paramSize)
  8602. }
  8603. // \xref[TeX capacity exceeded parameter stack size][\quad parameter stack size]
  8604. }
  8605. for ii := int32(0); ii <= int32(n)-1; ii++ {
  8606. m = halfword(ii)
  8607. _ = m
  8608. prg.paramStack[int32(prg.paramPtr)+int32(m)] = prg.pstack[m]
  8609. }
  8610. prg.paramPtr = byte(int32(prg.paramPtr) + int32(n))
  8611. }
  8612. exit:
  8613. prg.scannerStatus = saveScannerStatus
  8614. prg.warningIndex = saveWarningIndex
  8615. }
  8616. // \4
  8617. // Declare the procedure called |insert_relax|
  8618. func (prg *prg) insertRelax() {
  8619. prg.curTok = uint16(07777 + int32(prg.curCs))
  8620. prg.backInput()
  8621. prg.curTok = uint16(07777 + frozenRelax)
  8622. prg.backInput()
  8623. prg.curInput.indexField = byte(inserted)
  8624. } // \2
  8625. func (prg *prg) expand() {
  8626. var (
  8627. t halfword // token that is being ``expanded after''
  8628. p, q, r1 halfword // for list manipulation
  8629. j/* 0..bufSize */ uint16 // index into |buffer|
  8630. cvBackup int32 // to save the global quantity |cur_val|
  8631. cvlBackup, radixBackup, coBackup smallNumber
  8632. // to save |cur_val_level|, etc.
  8633. backupBackup halfword // to save |link(backup_head)|
  8634. saveScannerStatus smallNumber // temporary storage of |scanner_status|
  8635. )
  8636. cvBackup = prg.curVal
  8637. cvlBackup = prg.curValLevel
  8638. radixBackup = prg.radix
  8639. coBackup = prg.curOrder
  8640. backupBackup = *(*prg.mem[30000-13].hh()).rh()
  8641. if int32(prg.curCmd) < call {
  8642. if *prg.eqtb[intBase+tracingCommandsCode-1].int() > 1 {
  8643. prg.showCurCmdChr()
  8644. }
  8645. switch prg.curCmd {
  8646. case topBotMark:
  8647. // Insert the \(a)appropriate mark text into the scanner
  8648. if int32(prg.curMark[prg.curChr]) != 0 {
  8649. prg.beginTokenList(prg.curMark[prg.curChr], quarterword(markText))
  8650. }
  8651. case expandAfter:
  8652. // Expand the token after the next token
  8653. prg.getToken()
  8654. t = prg.curTok
  8655. prg.getToken()
  8656. if int32(prg.curCmd) > maxCommand {
  8657. prg.expand()
  8658. } else {
  8659. prg.backInput()
  8660. }
  8661. prg.curTok = t
  8662. prg.backInput()
  8663. case noExpand:
  8664. // Suppress expansion of the next token
  8665. saveScannerStatus = prg.scannerStatus
  8666. prg.scannerStatus = byte(normal)
  8667. prg.getToken()
  8668. prg.scannerStatus = saveScannerStatus
  8669. t = prg.curTok
  8670. prg.backInput() // now |start| and |loc| point to the backed-up token |t|
  8671. if int32(t) >= 07777 {
  8672. p = prg.getAvail()
  8673. *(*prg.mem[p].hh()).lh() = uint16(07777 + frozenDontExpand)
  8674. *(*prg.mem[p].hh()).rh() = prg.curInput.locField
  8675. prg.curInput.startField = p
  8676. prg.curInput.locField = p
  8677. }
  8678. case csName:
  8679. // Manufacture a control sequence name
  8680. r1 = prg.getAvail()
  8681. p = r1 // head of the list of characters
  8682. for {
  8683. prg.getXToken()
  8684. if int32(prg.curCs) == 0 {
  8685. q = prg.getAvail()
  8686. *(*prg.mem[p].hh()).rh() = q
  8687. *(*prg.mem[q].hh()).lh() = prg.curTok
  8688. p = q
  8689. }
  8690. if int32(prg.curCs) != 0 {
  8691. break
  8692. }
  8693. }
  8694. if int32(prg.curCmd) != endCsName {
  8695. {
  8696. if int32(prg.interaction) == errorStopMode {
  8697. }
  8698. prg.printNl(strNumber( /* "! " */ 262))
  8699. prg.print( /* "Missing " */ 625)
  8700. }
  8701. prg.printEsc(strNumber( /* "endcsname" */ 505))
  8702. prg.print( /* " inserted" */ 626)
  8703. // \xref[Missing \\endcsname...]
  8704. {
  8705. prg.helpPtr = 2
  8706. prg.helpLine[1] = /* "The control sequence marked <to be read again> should" */ 627
  8707. prg.helpLine[0] = /* "not appear between \\csname and \\endcsname." */ 628
  8708. }
  8709. prg.backError()
  8710. }
  8711. // Look up the characters of list |r| in the hash table, and set |cur_cs|
  8712. j = prg.first
  8713. p = *(*prg.mem[r1].hh()).rh()
  8714. for int32(p) != 0 {
  8715. if int32(j) >= int32(prg.maxBufStack) {
  8716. prg.maxBufStack = uint16(int32(j) + 1)
  8717. if int32(prg.maxBufStack) == bufSize {
  8718. prg.overflow(strNumber( /* "buffer size" */ 256), bufSize)
  8719. }
  8720. // \xref[TeX capacity exceeded buffer size][\quad buffer size]
  8721. }
  8722. prg.buffer[j] = byte(int32(*(*prg.mem[p].hh()).lh()) % 0400)
  8723. j = uint16(int32(j) + 1)
  8724. p = *(*prg.mem[p].hh()).rh()
  8725. }
  8726. if int32(j) > int32(prg.first)+1 {
  8727. prg.noNewControlSequence = false
  8728. prg.curCs = prg.idLookup(int32(prg.first), int32(j)-int32(prg.first))
  8729. prg.noNewControlSequence = true
  8730. } else if int32(j) == int32(prg.first) {
  8731. prg.curCs = uint16(nullCs)
  8732. } else {
  8733. prg.curCs = uint16(singleBase + int32(prg.buffer[prg.first]))
  8734. }
  8735. prg.flushList(r1)
  8736. if int32(*(*prg.eqtb[prg.curCs-1].hh()).b0()) == undefinedCs {
  8737. prg.eqDefine(prg.curCs, quarterword(relax), halfword(256)) // N.B.: The |save_stack| might change
  8738. } // the control sequence will now match `\.[\\relax]'
  8739. prg.curTok = uint16(int32(prg.curCs) + 07777)
  8740. prg.backInput()
  8741. case convert:
  8742. prg.convToks() // this procedure is discussed in Part 27 below
  8743. case the:
  8744. prg.insTheToks() // this procedure is discussed in Part 27 below
  8745. case ifTest:
  8746. prg.conditional() // this procedure is discussed in Part 28 below
  8747. case fiOrElse:
  8748. // Terminate the current conditional and skip to \.[\\fi]
  8749. if int32(prg.curChr) > int32(prg.ifLimit) {
  8750. if int32(prg.ifLimit) == ifCode {
  8751. prg.insertRelax()
  8752. } else {
  8753. {
  8754. if int32(prg.interaction) == errorStopMode {
  8755. }
  8756. prg.printNl(strNumber( /* "! " */ 262))
  8757. prg.print( /* "Extra " */ 777)
  8758. }
  8759. prg.printCmdChr(quarterword(fiOrElse), prg.curChr)
  8760. // \xref[Extra \\or]
  8761. // \xref[Extra \\else]
  8762. // \xref[Extra \\fi]
  8763. {
  8764. prg.helpPtr = 1
  8765. prg.helpLine[0] = /* "I'm ignoring this; it doesn't match any \\if." */ 778
  8766. }
  8767. prg.error1()
  8768. }
  8769. } else {
  8770. for int32(prg.curChr) != fiCode {
  8771. prg.passText()
  8772. } // skip to \.[\\fi]
  8773. // Pop the condition stack
  8774. {
  8775. p = prg.condPtr
  8776. prg.ifLine = *prg.mem[int32(p)+1].int()
  8777. prg.curIf = *(*prg.mem[p].hh()).b1()
  8778. prg.ifLimit = *(*prg.mem[p].hh()).b0()
  8779. prg.condPtr = *(*prg.mem[p].hh()).rh()
  8780. prg.freeNode(p, halfword(ifNodeSize))
  8781. }
  8782. }
  8783. case input:
  8784. // Initiate or terminate input from a file
  8785. if int32(prg.curChr) > 0 {
  8786. prg.forceEof = true
  8787. } else if prg.nameInProgress {
  8788. prg.insertRelax()
  8789. } else {
  8790. prg.startInput()
  8791. }
  8792. default:
  8793. {
  8794. if int32(prg.interaction) == errorStopMode {
  8795. }
  8796. prg.printNl(strNumber( /* "! " */ 262))
  8797. prg.print( /* "Undefined control sequence" */ 619)
  8798. }
  8799. // \xref[Undefined control sequence]
  8800. {
  8801. prg.helpPtr = 5
  8802. prg.helpLine[4] = /* "The control sequence at the end of the top line" */ 620
  8803. prg.helpLine[3] = /* "of your error message was never \\def'ed. If you have" */ 621
  8804. prg.helpLine[2] = /* "misspelled it (e.g., `\\hobx'), type `I' and the correct" */ 622
  8805. prg.helpLine[1] = /* "spelling (e.g., `I\\hbox'). Otherwise just continue," */ 623
  8806. prg.helpLine[0] = /* "and I'll forget about whatever was undefined." */ 624
  8807. }
  8808. prg.error1()
  8809. }
  8810. } else if int32(prg.curCmd) < endTemplate {
  8811. prg.macroCall()
  8812. } else {
  8813. // Insert a token containing |frozen_endv|
  8814. prg.curTok = uint16(07777 + frozenEndv)
  8815. prg.backInput()
  8816. }
  8817. prg.curVal = cvBackup
  8818. prg.curValLevel = cvlBackup
  8819. prg.radix = radixBackup
  8820. prg.curOrder = coBackup
  8821. *(*prg.mem[30000-13].hh()).rh() = backupBackup
  8822. } // \2
  8823. func (prg *prg) getXToken() {
  8824. restart:
  8825. prg.getNext()
  8826. // \xref[inner loop]
  8827. if int32(prg.curCmd) <= maxCommand {
  8828. goto done
  8829. }
  8830. if int32(prg.curCmd) >= call {
  8831. if int32(prg.curCmd) < endTemplate {
  8832. prg.macroCall()
  8833. } else {
  8834. prg.curCs = uint16(frozenEndv)
  8835. prg.curCmd = byte(endv)
  8836. goto done // |cur_chr=null_list|
  8837. }
  8838. } else {
  8839. prg.expand()
  8840. }
  8841. goto restart
  8842. done:
  8843. if int32(prg.curCs) == 0 {
  8844. prg.curTok = uint16(int32(prg.curCmd)*0400 + int32(prg.curChr))
  8845. } else {
  8846. prg.curTok = uint16(07777 + int32(prg.curCs))
  8847. }
  8848. }
  8849. // 381.
  8850. // tangle:pos tex.web:7842:1:
  8851. // The |get_x_token| procedure is essentially equivalent to two consecutive
  8852. // procedure calls: |get_next; x_token|.
  8853. func (prg *prg) xToken() {
  8854. for int32(prg.curCmd) > maxCommand {
  8855. prg.expand()
  8856. prg.getNext()
  8857. }
  8858. if int32(prg.curCs) == 0 {
  8859. prg.curTok = uint16(int32(prg.curCmd)*0400 + int32(prg.curChr))
  8860. } else {
  8861. prg.curTok = uint16(07777 + int32(prg.curCs))
  8862. }
  8863. }
  8864. // 402. \[26] Basic scanning subroutines
  8865. // tangle:pos tex.web:8181:35:
  8866. // Let's turn now to some procedures that \TeX\ calls upon frequently to digest
  8867. // certain kinds of patterns in the input. Most of these are quite simple;
  8868. // some are quite elaborate. Almost all of the routines call |get_x_token|,
  8869. // which can cause them to be invoked recursively.
  8870. // \xref[stomach]
  8871. // \xref[recursion]
  8872. // 403.
  8873. // tangle:pos tex.web:8189:1:
  8874. // The |scan_left_brace| routine is called when a left brace is supposed to be
  8875. // the next non-blank token. (The term “left brace” means, more precisely,
  8876. // a character whose catcode is |left_brace|.) \TeX\ allows \.[\\relax] to
  8877. // appear before the |left_brace|.
  8878. func (prg *prg) scanLeftBrace() {
  8879. for {
  8880. prg.getXToken()
  8881. if int32(prg.curCmd) != spacer && int32(prg.curCmd) != relax {
  8882. break
  8883. }
  8884. }
  8885. if int32(prg.curCmd) != leftBrace {
  8886. {
  8887. if int32(prg.interaction) == errorStopMode {
  8888. }
  8889. prg.printNl(strNumber( /* "! " */ 262))
  8890. prg.print( /* "Missing [ inserted" */ 657)
  8891. }
  8892. // \xref[Missing \[ inserted]
  8893. {
  8894. prg.helpPtr = 4
  8895. prg.helpLine[3] = /* "A left brace was mandatory here, so I've put one in." */ 658
  8896. prg.helpLine[2] = /* "You might want to delete and/or insert some corrections" */ 659
  8897. prg.helpLine[1] = /* "so that I will find a matching right brace soon." */ 660
  8898. prg.helpLine[0] = /* "(If you're confused by all this, try typing `I]' now.)" */ 661
  8899. }
  8900. prg.backError()
  8901. prg.curTok = uint16(leftBraceToken + '{')
  8902. prg.curCmd = byte(leftBrace)
  8903. prg.curChr = '{'
  8904. prg.alignState = prg.alignState + 1
  8905. }
  8906. }
  8907. // 405.
  8908. // tangle:pos tex.web:8212:1:
  8909. // The |scan_optional_equals| routine looks for an optional `\.=' sign preceded
  8910. // by optional spaces; `\.[\\relax]' is not ignored here.
  8911. func (prg *prg) scanOptionalEquals() {
  8912. for {
  8913. prg.getXToken()
  8914. if int32(prg.curCmd) != spacer {
  8915. break
  8916. }
  8917. }
  8918. if int32(prg.curTok) != otherToken+'=' {
  8919. prg.backInput()
  8920. }
  8921. }
  8922. // 407.
  8923. // tangle:pos tex.web:8224:1:
  8924. // In case you are getting bored, here is a slightly less trivial routine:
  8925. // Given a string of lowercase letters, like `\.[pt]' or `\.[plus]' or
  8926. // `\.[width]', the |scan_keyword| routine checks to see whether the next
  8927. // tokens of input match this string. The match must be exact, except that
  8928. // uppercase letters will match their lowercase counterparts; uppercase
  8929. // equivalents are determined by subtracting |"a"-"A"|, rather than using the
  8930. // |uc_code| table, since \TeX\ uses this routine only for its own limited
  8931. // set of keywords.
  8932. //
  8933. // If a match is found, the characters are effectively removed from the input
  8934. // and |true| is returned. Otherwise |false| is returned, and the input
  8935. // is left essentially unchanged (except for the fact that some macros
  8936. // may have been expanded, etc.).
  8937. // \xref[inner loop]
  8938. func (prg *prg) scanKeyword(s strNumber) (r bool) {
  8939. var (
  8940. p halfword // tail of the backup list
  8941. q halfword // new node being added to the token list via |store_new_token|
  8942. k poolPointer // index into |str_pool|
  8943. )
  8944. p = uint16(30000 - 13)
  8945. *(*prg.mem[p].hh()).rh() = 0
  8946. k = prg.strStart[s]
  8947. for int32(k) < int32(prg.strStart[int32(s)+1]) {
  8948. prg.getXToken() // recursion is possible here
  8949. // \xref[recursion]
  8950. if int32(prg.curCs) == 0 && (int32(prg.curChr) == int32(prg.strPool[k]) || int32(prg.curChr) == int32(prg.strPool[k])-'a'+'A') {
  8951. {
  8952. q = prg.getAvail()
  8953. *(*prg.mem[p].hh()).rh() = q
  8954. *(*prg.mem[q].hh()).lh() = prg.curTok
  8955. p = q
  8956. }
  8957. k = uint16(int32(k) + 1)
  8958. } else if int32(prg.curCmd) != spacer || int32(p) != 30000-13 {
  8959. prg.backInput()
  8960. if int32(p) != 30000-13 {
  8961. prg.beginTokenList(*(*prg.mem[30000-13].hh()).rh(), quarterword(backedUp))
  8962. }
  8963. r = false
  8964. goto exit
  8965. }
  8966. }
  8967. prg.flushList(*(*prg.mem[30000-13].hh()).rh())
  8968. r = true
  8969. exit:
  8970. ;
  8971. return r
  8972. }
  8973. // 408.
  8974. // tangle:pos tex.web:8261:1:
  8975. // Here is a procedure that sounds an alarm when mu and non-mu units
  8976. // are being switched.
  8977. func (prg *prg) muError() {
  8978. {
  8979. if int32(prg.interaction) == errorStopMode {
  8980. }
  8981. prg.printNl(strNumber( /* "! " */ 262))
  8982. prg.print( /* "Incompatible glue units" */ 662)
  8983. }
  8984. // \xref[Incompatible glue units]
  8985. {
  8986. prg.helpPtr = 1
  8987. prg.helpLine[0] = /* "I'm going to assume that 1mu=1pt when they're mixed." */ 663
  8988. }
  8989. prg.error1()
  8990. } // scans an integer value
  8991. // \4\4
  8992. // Declare procedures that scan restricted classes of integers
  8993. func (prg *prg) scanEightBitInt() {
  8994. prg.scanInt()
  8995. if prg.curVal < 0 || prg.curVal > 255 {
  8996. {
  8997. if int32(prg.interaction) == errorStopMode {
  8998. }
  8999. prg.printNl(strNumber( /* "! " */ 262))
  9000. prg.print( /* "Bad register code" */ 687)
  9001. }
  9002. // \xref[Bad register code]
  9003. {
  9004. prg.helpPtr = 2
  9005. prg.helpLine[1] = /* "A register number must be between 0 and 255." */ 688
  9006. prg.helpLine[0] = /* "I changed this one to zero." */ 689
  9007. }
  9008. prg.intError(prg.curVal)
  9009. prg.curVal = 0
  9010. }
  9011. }
  9012. func (prg *prg) scanCharNum() {
  9013. prg.scanInt()
  9014. if prg.curVal < 0 || prg.curVal > 255 {
  9015. {
  9016. if int32(prg.interaction) == errorStopMode {
  9017. }
  9018. prg.printNl(strNumber( /* "! " */ 262))
  9019. prg.print( /* "Bad character code" */ 690)
  9020. }
  9021. // \xref[Bad character code]
  9022. {
  9023. prg.helpPtr = 2
  9024. prg.helpLine[1] = /* "A character number must be between 0 and 255." */ 691
  9025. prg.helpLine[0] = /* "I changed this one to zero." */ 689
  9026. }
  9027. prg.intError(prg.curVal)
  9028. prg.curVal = 0
  9029. }
  9030. }
  9031. func (prg *prg) scanFourBitInt() {
  9032. prg.scanInt()
  9033. if prg.curVal < 0 || prg.curVal > 15 {
  9034. {
  9035. if int32(prg.interaction) == errorStopMode {
  9036. }
  9037. prg.printNl(strNumber( /* "! " */ 262))
  9038. prg.print( /* "Bad number" */ 692)
  9039. }
  9040. // \xref[Bad number]
  9041. {
  9042. prg.helpPtr = 2
  9043. prg.helpLine[1] = /* "Since I expected to read a number between 0 and 15," */ 693
  9044. prg.helpLine[0] = /* "I changed this one to zero." */ 689
  9045. }
  9046. prg.intError(prg.curVal)
  9047. prg.curVal = 0
  9048. }
  9049. }
  9050. func (prg *prg) scanFifteenBitInt() {
  9051. prg.scanInt()
  9052. if prg.curVal < 0 || prg.curVal > 077777 {
  9053. {
  9054. if int32(prg.interaction) == errorStopMode {
  9055. }
  9056. prg.printNl(strNumber( /* "! " */ 262))
  9057. prg.print( /* "Bad mathchar" */ 694)
  9058. }
  9059. // \xref[Bad mathchar]
  9060. {
  9061. prg.helpPtr = 2
  9062. prg.helpLine[1] = /* "A mathchar number must be between 0 and 32767." */ 695
  9063. prg.helpLine[0] = /* "I changed this one to zero." */ 689
  9064. }
  9065. prg.intError(prg.curVal)
  9066. prg.curVal = 0
  9067. }
  9068. }
  9069. func (prg *prg) scanTwentySevenBitInt() {
  9070. prg.scanInt()
  9071. if prg.curVal < 0 || prg.curVal > 0777777777 {
  9072. {
  9073. if int32(prg.interaction) == errorStopMode {
  9074. }
  9075. prg.printNl(strNumber( /* "! " */ 262))
  9076. prg.print( /* "Bad delimiter code" */ 696)
  9077. }
  9078. // \xref[Bad delimiter code]
  9079. {
  9080. prg.helpPtr = 2
  9081. prg.helpLine[1] = /* "A numeric delimiter code must be between 0 and 2^[27]-1." */ 697
  9082. prg.helpLine[0] = /* "I changed this one to zero." */ 689
  9083. }
  9084. prg.intError(prg.curVal)
  9085. prg.curVal = 0
  9086. }
  9087. }
  9088. // \4\4
  9089. // Declare procedures that scan font-related stuff
  9090. func (prg *prg) scanFontIdent() {
  9091. var (
  9092. f internalFontNumber
  9093. m halfword
  9094. )
  9095. for {
  9096. prg.getXToken()
  9097. if int32(prg.curCmd) != spacer {
  9098. break
  9099. }
  9100. }
  9101. if int32(prg.curCmd) == defFont {
  9102. f = byte(*(*prg.eqtb[curFontLoc-1].hh()).rh())
  9103. } else if int32(prg.curCmd) == setFont {
  9104. f = byte(prg.curChr)
  9105. } else if int32(prg.curCmd) == defFamily {
  9106. m = prg.curChr
  9107. prg.scanFourBitInt()
  9108. f = byte(*(*prg.eqtb[int32(m)+prg.curVal-1].hh()).rh())
  9109. } else {
  9110. {
  9111. if int32(prg.interaction) == errorStopMode {
  9112. }
  9113. prg.printNl(strNumber( /* "! " */ 262))
  9114. prg.print( /* "Missing font identifier" */ 817)
  9115. }
  9116. // \xref[Missing font identifier]
  9117. {
  9118. prg.helpPtr = 2
  9119. prg.helpLine[1] = /* "I was looking for a control sequence whose" */ 818
  9120. prg.helpLine[0] = /* "current meaning has been defined by \\font." */ 819
  9121. }
  9122. prg.backError()
  9123. f = byte(fontBase)
  9124. }
  9125. prg.curVal = int32(f)
  9126. }
  9127. func (prg *prg) findFontDimen(writing bool) {
  9128. // sets |cur_val| to |font_info| location
  9129. var (
  9130. f internalFontNumber
  9131. n int32 // the parameter number
  9132. )
  9133. prg.scanInt()
  9134. n = prg.curVal
  9135. prg.scanFontIdent()
  9136. f = byte(prg.curVal)
  9137. if n <= 0 {
  9138. prg.curVal = int32(prg.fmemPtr)
  9139. } else {
  9140. if writing && n <= spaceShrinkCode && n >= spaceCode && int32(prg.fontGlue[f]) != 0 {
  9141. prg.deleteGlueRef(prg.fontGlue[f])
  9142. prg.fontGlue[f] = 0
  9143. }
  9144. if n > int32(prg.fontParams[f]) {
  9145. if int32(f) < int32(prg.fontPtr) {
  9146. prg.curVal = int32(prg.fmemPtr)
  9147. } else {
  9148. // Increase the number of parameters in the last font
  9149. for {
  9150. if int32(prg.fmemPtr) == fontMemSize {
  9151. prg.overflow(strNumber( /* "font memory" */ 824), fontMemSize)
  9152. }
  9153. // \xref[TeX capacity exceeded font memory][\quad font memory]
  9154. *prg.fontInfo[prg.fmemPtr].int() = 0
  9155. prg.fmemPtr = uint16(int32(prg.fmemPtr) + 1)
  9156. prg.fontParams[f] = uint16(int32(prg.fontParams[f]) + 1)
  9157. if n == int32(prg.fontParams[f]) {
  9158. break
  9159. }
  9160. }
  9161. prg.curVal = int32(prg.fmemPtr) - 1 // this equals |param_base[f]+font_params[f]|
  9162. }
  9163. } else {
  9164. prg.curVal = n + prg.paramBase[f]
  9165. }
  9166. }
  9167. // Issue an error message if |cur_val=fmem_ptr|
  9168. if prg.curVal == int32(prg.fmemPtr) {
  9169. {
  9170. if int32(prg.interaction) == errorStopMode {
  9171. }
  9172. prg.printNl(strNumber( /* "! " */ 262))
  9173. prg.print( /* "Font " */ 802)
  9174. }
  9175. prg.printEsc(*prg.hash[fontIdBase+int32(f)-514].rh())
  9176. prg.print( /* " has only " */ 820)
  9177. prg.printInt(int32(prg.fontParams[f]))
  9178. prg.print( /* " fontdimen parameters" */ 821)
  9179. // \xref[Font x has only...]
  9180. {
  9181. prg.helpPtr = 2
  9182. prg.helpLine[1] = /* "To increase the number of font parameters, you must" */ 822
  9183. prg.helpLine[0] = /* "use \\fontdimen immediately after the \\font is loaded." */ 823
  9184. }
  9185. prg.error1()
  9186. }
  9187. }
  9188. // 413.
  9189. // tangle:pos tex.web:8345:1:
  9190. // OK, we're ready for |scan_something_internal| itself. A second parameter,
  9191. // |negative|, is set |true| if the value that is found should be negated.
  9192. // It is assumed that |cur_cmd| and |cur_chr| represent the first token of
  9193. // the internal quantity to be scanned; an error will be signalled if
  9194. // |cur_cmd<min_internal| or |cur_cmd>max_internal|.
  9195. func (prg *prg) scanSomethingInternal(level smallNumber, negative bool) {
  9196. // fetch an internal parameter
  9197. var (
  9198. m halfword // |chr_code| part of the operand token
  9199. p/* 0..nestSize */ byte // index into |nest|
  9200. )
  9201. m = prg.curChr
  9202. switch prg.curCmd {
  9203. case defCode:
  9204. // Fetch a character code from some table
  9205. prg.scanCharNum()
  9206. if int32(m) == mathCodeBase {
  9207. prg.curVal = int32(*(*prg.eqtb[mathCodeBase+prg.curVal-1].hh()).rh()) - 0
  9208. prg.curValLevel = byte(intVal)
  9209. } else if int32(m) < mathCodeBase {
  9210. prg.curVal = int32(*(*prg.eqtb[int32(m)+prg.curVal-1].hh()).rh())
  9211. prg.curValLevel = byte(intVal)
  9212. } else {
  9213. prg.curVal = *prg.eqtb[int32(m)+prg.curVal-1].int()
  9214. prg.curValLevel = byte(intVal)
  9215. }
  9216. case toksRegister, assignToks, defFamily, setFont,
  9217. defFont:
  9218. // Fetch a token list or font identifier, provided that |level=tok_val|
  9219. if int32(level) != tokVal {
  9220. {
  9221. if int32(prg.interaction) == errorStopMode {
  9222. }
  9223. prg.printNl(strNumber( /* "! " */ 262))
  9224. prg.print( /* "Missing number, treated as zero" */ 664)
  9225. }
  9226. // \xref[Missing number...]
  9227. {
  9228. prg.helpPtr = 3
  9229. prg.helpLine[2] = /* "A number should have been here; I inserted `0'." */ 665
  9230. prg.helpLine[1] = /* "(If you can't figure out why I needed to see a number," */ 666
  9231. prg.helpLine[0] = /* "look up `weird error' in the index to The TeXbook.)" */ 667
  9232. }
  9233. // \xref[TeXbook][\sl The \TeX book]
  9234. prg.backError()
  9235. {
  9236. prg.curVal = 0
  9237. prg.curValLevel = byte(dimenVal)
  9238. }
  9239. } else if int32(prg.curCmd) <= assignToks {
  9240. if int32(prg.curCmd) < assignToks {
  9241. prg.scanEightBitInt()
  9242. m = uint16(toksBase + prg.curVal)
  9243. }
  9244. {
  9245. prg.curVal = int32(*(*prg.eqtb[m-1].hh()).rh())
  9246. prg.curValLevel = byte(tokVal)
  9247. }
  9248. } else {
  9249. prg.backInput()
  9250. prg.scanFontIdent()
  9251. {
  9252. prg.curVal = fontIdBase + prg.curVal
  9253. prg.curValLevel = byte(identVal)
  9254. }
  9255. }
  9256. case assignInt:
  9257. prg.curVal = *prg.eqtb[m-1].int()
  9258. prg.curValLevel = byte(intVal)
  9259. case assignDimen:
  9260. prg.curVal = *prg.eqtb[m-1].int()
  9261. prg.curValLevel = byte(dimenVal)
  9262. case assignGlue:
  9263. prg.curVal = int32(*(*prg.eqtb[m-1].hh()).rh())
  9264. prg.curValLevel = byte(glueVal)
  9265. case assignMuGlue:
  9266. prg.curVal = int32(*(*prg.eqtb[m-1].hh()).rh())
  9267. prg.curValLevel = byte(muVal)
  9268. case setAux:
  9269. // Fetch the |space_factor| or the |prev_depth|
  9270. if abs(int32(prg.curList.modeField)) != int32(m) {
  9271. {
  9272. if int32(prg.interaction) == errorStopMode {
  9273. }
  9274. prg.printNl(strNumber( /* "! " */ 262))
  9275. prg.print( /* "Improper " */ 680)
  9276. }
  9277. prg.printCmdChr(quarterword(setAux), m)
  9278. // \xref[Improper \\spacefactor]
  9279. // \xref[Improper \\prevdepth]
  9280. {
  9281. prg.helpPtr = 4
  9282. prg.helpLine[3] = /* "You can refer to \\spacefactor only in horizontal mode;" */ 681
  9283. prg.helpLine[2] = /* "you can refer to \\prevdepth only in vertical mode; and" */ 682
  9284. prg.helpLine[1] = /* "neither of these is meaningful inside \\write. So" */ 683
  9285. prg.helpLine[0] = /* "I'm forgetting what you said and using zero instead." */ 684
  9286. }
  9287. prg.error1()
  9288. if int32(level) != tokVal {
  9289. prg.curVal = 0
  9290. prg.curValLevel = byte(dimenVal)
  9291. } else {
  9292. prg.curVal = 0
  9293. prg.curValLevel = byte(intVal)
  9294. }
  9295. } else if int32(m) == vmode {
  9296. prg.curVal = *prg.curList.auxField.int()
  9297. prg.curValLevel = byte(dimenVal)
  9298. } else {
  9299. prg.curVal = int32(*(*prg.curList.auxField.hh()).lh())
  9300. prg.curValLevel = byte(intVal)
  9301. }
  9302. case setPrevGraf:
  9303. // Fetch the |prev_graf|
  9304. if int32(prg.curList.modeField) == 0 {
  9305. prg.curVal = 0
  9306. prg.curValLevel = byte(intVal)
  9307. } else {
  9308. prg.nest[prg.nestPtr] = prg.curList
  9309. p = prg.nestPtr
  9310. for abs(int32(prg.nest[p].modeField)) != vmode {
  9311. p = byte(int32(p) - 1)
  9312. }
  9313. {
  9314. prg.curVal = prg.nest[p].pgField
  9315. prg.curValLevel = byte(intVal)
  9316. }
  9317. }
  9318. case setPageInt:
  9319. // Fetch the |dead_cycles| or the |insert_penalties|
  9320. if int32(m) == 0 {
  9321. prg.curVal = prg.deadCycles
  9322. } else {
  9323. prg.curVal = prg.insertPenalties
  9324. }
  9325. prg.curValLevel = byte(intVal)
  9326. case setPageDimen:
  9327. // Fetch something on the |page_so_far|
  9328. if int32(prg.pageContents) == empty && !prg.outputActive {
  9329. if int32(m) == 0 {
  9330. prg.curVal = 07777777777
  9331. } else {
  9332. prg.curVal = 0
  9333. }
  9334. } else {
  9335. prg.curVal = prg.pageSoFar[m]
  9336. }
  9337. prg.curValLevel = byte(dimenVal)
  9338. case setShape:
  9339. // Fetch the |par_shape| size
  9340. if int32(*(*prg.eqtb[parShapeLoc-1].hh()).rh()) == 0 {
  9341. prg.curVal = 0
  9342. } else {
  9343. prg.curVal = int32(*(*prg.mem[*(*prg.eqtb[parShapeLoc-1].hh()).rh()].hh()).lh())
  9344. }
  9345. prg.curValLevel = byte(intVal)
  9346. case setBoxDimen:
  9347. // Fetch a box dimension
  9348. prg.scanEightBitInt()
  9349. if int32(*(*prg.eqtb[boxBase+prg.curVal-1].hh()).rh()) == 0 {
  9350. prg.curVal = 0
  9351. } else {
  9352. prg.curVal = *prg.mem[int32(*(*prg.eqtb[boxBase+prg.curVal-1].hh()).rh())+int32(m)].int()
  9353. }
  9354. prg.curValLevel = byte(dimenVal)
  9355. case charGiven, mathGiven:
  9356. prg.curVal = int32(prg.curChr)
  9357. prg.curValLevel = byte(intVal)
  9358. case assignFontDimen:
  9359. // Fetch a font dimension
  9360. prg.findFontDimen(false)
  9361. *prg.fontInfo[prg.fmemPtr].int() = 0
  9362. {
  9363. prg.curVal = *prg.fontInfo[prg.curVal].int()
  9364. prg.curValLevel = byte(dimenVal)
  9365. }
  9366. case assignFontInt:
  9367. // Fetch a font integer
  9368. prg.scanFontIdent()
  9369. if int32(m) == 0 {
  9370. prg.curVal = prg.hyphenChar[prg.curVal]
  9371. prg.curValLevel = byte(intVal)
  9372. } else {
  9373. prg.curVal = prg.skewChar[prg.curVal]
  9374. prg.curValLevel = byte(intVal)
  9375. }
  9376. case register:
  9377. // Fetch a register
  9378. prg.scanEightBitInt()
  9379. switch m {
  9380. case intVal:
  9381. prg.curVal = *prg.eqtb[countBase+prg.curVal-1].int()
  9382. case dimenVal:
  9383. prg.curVal = *prg.eqtb[scaledBase+prg.curVal-1].int()
  9384. case glueVal:
  9385. prg.curVal = int32(*(*prg.eqtb[skipBase+prg.curVal-1].hh()).rh())
  9386. case muVal:
  9387. prg.curVal = int32(*(*prg.eqtb[muSkipBase+prg.curVal-1].hh()).rh())
  9388. } // there are no other cases
  9389. prg.curValLevel = byte(m)
  9390. case lastItem:
  9391. // Fetch an item in the current node, if appropriate
  9392. if int32(prg.curChr) > glueVal {
  9393. if int32(prg.curChr) == inputLineNoCode {
  9394. prg.curVal = prg.line
  9395. } else {
  9396. prg.curVal = prg.lastBadness
  9397. } // |cur_chr=badness_code|
  9398. prg.curValLevel = byte(intVal)
  9399. } else {
  9400. if int32(prg.curChr) == glueVal {
  9401. prg.curVal = memBot
  9402. } else {
  9403. prg.curVal = 0
  9404. }
  9405. prg.curValLevel = byte(prg.curChr)
  9406. if !(int32(prg.curList.tailField) >= int32(prg.hiMemMin)) && int32(prg.curList.modeField) != 0 {
  9407. switch prg.curChr {
  9408. case intVal:
  9409. if int32(*(*prg.mem[prg.curList.tailField].hh()).b0()) == penaltyNode {
  9410. prg.curVal = *prg.mem[int32(prg.curList.tailField)+1].int()
  9411. }
  9412. case dimenVal:
  9413. if int32(*(*prg.mem[prg.curList.tailField].hh()).b0()) == kernNode {
  9414. prg.curVal = *prg.mem[int32(prg.curList.tailField)+widthOffset].int()
  9415. }
  9416. case glueVal:
  9417. if int32(*(*prg.mem[prg.curList.tailField].hh()).b0()) == glueNode {
  9418. prg.curVal = int32(*(*prg.mem[int32(prg.curList.tailField)+1].hh()).lh())
  9419. if int32(*(*prg.mem[prg.curList.tailField].hh()).b1()) == muGlue {
  9420. prg.curValLevel = byte(muVal)
  9421. }
  9422. }
  9423. }
  9424. } else if int32(prg.curList.modeField) == vmode && int32(prg.curList.tailField) == int32(prg.curList.headField) {
  9425. switch prg.curChr {
  9426. case intVal:
  9427. prg.curVal = prg.lastPenalty
  9428. case dimenVal:
  9429. prg.curVal = prg.lastKern
  9430. case glueVal:
  9431. if int32(prg.lastGlue) != 65535 {
  9432. prg.curVal = int32(prg.lastGlue)
  9433. }
  9434. }
  9435. } // there are no other cases
  9436. }
  9437. default:
  9438. {
  9439. if int32(prg.interaction) == errorStopMode {
  9440. }
  9441. prg.printNl(strNumber( /* "! " */ 262))
  9442. prg.print( /* "You can't use `" */ 685)
  9443. }
  9444. prg.printCmdChr(prg.curCmd, prg.curChr)
  9445. // \xref[You can't use x after ...]
  9446. prg.print( /* "' after " */ 686)
  9447. prg.printEsc(strNumber( /* "the" */ 537))
  9448. {
  9449. prg.helpPtr = 1
  9450. prg.helpLine[0] = /* "I'm forgetting what you said and using zero instead." */ 684
  9451. }
  9452. prg.error1()
  9453. if int32(level) != tokVal {
  9454. prg.curVal = 0
  9455. prg.curValLevel = byte(dimenVal)
  9456. } else {
  9457. prg.curVal = 0
  9458. prg.curValLevel = byte(intVal)
  9459. }
  9460. }
  9461. for int32(prg.curValLevel) > int32(level) {
  9462. // Convert \(c)|cur_val| to a lower level
  9463. if int32(prg.curValLevel) == glueVal {
  9464. prg.curVal = *prg.mem[prg.curVal+widthOffset].int()
  9465. } else if int32(prg.curValLevel) == muVal {
  9466. prg.muError()
  9467. }
  9468. prg.curValLevel = byte(int32(prg.curValLevel) - 1)
  9469. }
  9470. // Fix the reference count, if any, and negate |cur_val| if |negative|
  9471. if negative {
  9472. if int32(prg.curValLevel) >= glueVal {
  9473. prg.curVal = int32(prg.newSpec(halfword(prg.curVal)))
  9474. // Negate all three glue components of |cur_val|
  9475. {
  9476. *prg.mem[prg.curVal+widthOffset].int() = -*prg.mem[prg.curVal+widthOffset].int()
  9477. *prg.mem[prg.curVal+2].int() = -*prg.mem[prg.curVal+2].int()
  9478. *prg.mem[prg.curVal+3].int() = -*prg.mem[prg.curVal+3].int()
  9479. }
  9480. } else {
  9481. prg.curVal = -prg.curVal
  9482. }
  9483. } else if int32(prg.curValLevel) >= glueVal && int32(prg.curValLevel) <= muVal {
  9484. *(*prg.mem[prg.curVal].hh()).rh() = uint16(int32(*(*prg.mem[prg.curVal].hh()).rh()) + 1)
  9485. }
  9486. }
  9487. // 409.
  9488. // tangle:pos tex.web:8271:1:
  9489. // The next routine `|scan_something_internal|' is used to fetch internal
  9490. // numeric quantities like `\.[\\hsize]', and also to handle the `\.[\\the]'
  9491. // when expanding constructions like `\.[\\the\\toks0]' and
  9492. // `\.[\\the\\baselineskip]'. Soon we will be considering the |scan_int|
  9493. // procedure, which calls |scan_something_internal|; on the other hand,
  9494. // |scan_something_internal| also calls |scan_int|, for constructions like
  9495. // `\.[\\catcode\`\\\$]' or `\.[\\fontdimen] \.3 \.[\\ff]'. So we
  9496. // have to declare |scan_int| as a |forward| procedure. A few other
  9497. // procedures are also declared at this point.
  9498. func (prg *prg) scanInt() {
  9499. var (
  9500. negative bool // should the answer be negated?
  9501. m int32 // |$2^[31]$ div radix|, the threshold of danger
  9502. d smallNumber // the digit just scanned
  9503. vacuous bool // have no digits appeared?
  9504. okSoFar bool // has an error message been issued?
  9505. )
  9506. prg.radix = 0
  9507. okSoFar = true
  9508. // Get the next non-blank non-sign token; set |negative| appropriately
  9509. negative = false
  9510. for {
  9511. // Get the next non-blank non-call token
  9512. for {
  9513. prg.getXToken()
  9514. if int32(prg.curCmd) != spacer {
  9515. break
  9516. }
  9517. }
  9518. if int32(prg.curTok) == otherToken+'-' {
  9519. negative = !negative
  9520. prg.curTok = uint16(otherToken + '+')
  9521. }
  9522. if int32(prg.curTok) != otherToken+'+' {
  9523. break
  9524. }
  9525. }
  9526. if int32(prg.curTok) == alphaToken {
  9527. prg.getToken() // suppress macro expansion
  9528. if int32(prg.curTok) < 07777 {
  9529. prg.curVal = int32(prg.curChr)
  9530. if int32(prg.curCmd) <= rightBrace {
  9531. if int32(prg.curCmd) == rightBrace {
  9532. prg.alignState = prg.alignState + 1
  9533. } else {
  9534. prg.alignState = prg.alignState - 1
  9535. }
  9536. }
  9537. } else if int32(prg.curTok) < 07777+singleBase {
  9538. prg.curVal = int32(prg.curTok) - 07777 - activeBase
  9539. } else {
  9540. prg.curVal = int32(prg.curTok) - 07777 - singleBase
  9541. }
  9542. if prg.curVal > 255 {
  9543. {
  9544. if int32(prg.interaction) == errorStopMode {
  9545. }
  9546. prg.printNl(strNumber( /* "! " */ 262))
  9547. prg.print( /* "Improper alphabetic constant" */ 698)
  9548. }
  9549. // \xref[Improper alphabetic constant]
  9550. {
  9551. prg.helpPtr = 2
  9552. prg.helpLine[1] = /* "A one-character control sequence belongs after a ` mark." */ 699
  9553. prg.helpLine[0] = /* "So I'm essentially inserting \\0 here." */ 700
  9554. }
  9555. prg.curVal = '0'
  9556. prg.backError()
  9557. } else {
  9558. // Scan an optional space
  9559. prg.getXToken()
  9560. if int32(prg.curCmd) != spacer {
  9561. prg.backInput()
  9562. }
  9563. }
  9564. } else if int32(prg.curCmd) >= minInternal && int32(prg.curCmd) <= maxInternal {
  9565. prg.scanSomethingInternal(smallNumber(intVal), false)
  9566. } else {
  9567. // Scan a numeric constant
  9568. prg.radix = 10
  9569. m = 214748364
  9570. if int32(prg.curTok) == octalToken {
  9571. prg.radix = 8
  9572. m = 02000000000
  9573. prg.getXToken()
  9574. } else if int32(prg.curTok) == hexToken {
  9575. prg.radix = 16
  9576. m = 01000000000
  9577. prg.getXToken()
  9578. }
  9579. vacuous = true
  9580. prg.curVal = 0
  9581. // Accumulate the constant until |cur_tok| is not a suitable digit
  9582. for true {
  9583. if int32(prg.curTok) < zeroToken+int32(prg.radix) && int32(prg.curTok) >= zeroToken && int32(prg.curTok) <= zeroToken+9 {
  9584. d = byte(int32(prg.curTok) - zeroToken)
  9585. } else if int32(prg.radix) == 16 {
  9586. if int32(prg.curTok) <= aToken+5 && int32(prg.curTok) >= aToken {
  9587. d = byte(int32(prg.curTok) - aToken + 10)
  9588. } else if int32(prg.curTok) <= otherAToken+5 && int32(prg.curTok) >= otherAToken {
  9589. d = byte(int32(prg.curTok) - otherAToken + 10)
  9590. } else {
  9591. goto done
  9592. }
  9593. } else {
  9594. goto done
  9595. }
  9596. vacuous = false
  9597. if prg.curVal >= m && (prg.curVal > m || int32(d) > 7 || int32(prg.radix) != 10) {
  9598. if okSoFar {
  9599. {
  9600. if int32(prg.interaction) == errorStopMode {
  9601. }
  9602. prg.printNl(strNumber( /* "! " */ 262))
  9603. prg.print( /* "Number too big" */ 701)
  9604. }
  9605. // \xref[Number too big]
  9606. {
  9607. prg.helpPtr = 2
  9608. prg.helpLine[1] = /* "I can only go up to 2147483647='17777777777=\"7FFFFFFF," */ 702
  9609. prg.helpLine[0] = /* "so I'm using that number instead of yours." */ 703
  9610. }
  9611. prg.error1()
  9612. prg.curVal = 017777777777
  9613. okSoFar = false
  9614. }
  9615. } else {
  9616. prg.curVal = prg.curVal*int32(prg.radix) + int32(d)
  9617. }
  9618. prg.getXToken()
  9619. }
  9620. done:
  9621. ;
  9622. if vacuous {
  9623. {
  9624. if int32(prg.interaction) == errorStopMode {
  9625. }
  9626. prg.printNl(strNumber( /* "! " */ 262))
  9627. prg.print( /* "Missing number, treated as zero" */ 664)
  9628. }
  9629. // \xref[Missing number...]
  9630. {
  9631. prg.helpPtr = 3
  9632. prg.helpLine[2] = /* "A number should have been here; I inserted `0'." */ 665
  9633. prg.helpLine[1] = /* "(If you can't figure out why I needed to see a number," */ 666
  9634. prg.helpLine[0] = /* "look up `weird error' in the index to The TeXbook.)" */ 667
  9635. }
  9636. // \xref[TeXbook][\sl The \TeX book]
  9637. prg.backError()
  9638. } else if int32(prg.curCmd) != spacer {
  9639. prg.backInput()
  9640. }
  9641. }
  9642. if negative {
  9643. prg.curVal = -prg.curVal
  9644. }
  9645. }
  9646. // 448.
  9647. // tangle:pos tex.web:8829:1:
  9648. // Constructions like `\.[-\'77 pt]' are legal dimensions, so |scan_dimen|
  9649. // may begin with |scan_int|. This explains why it is convenient to use
  9650. // |scan_int| also for the integer part of a decimal fraction.
  9651. //
  9652. // Several branches of |scan_dimen| work with |cur_val| as an integer and
  9653. // with an auxiliary fraction |f|, so that the actual quantity of interest is
  9654. // $|cur_val|+|f|/2^[16]$. At the end of the routine, this “unpacked”
  9655. // representation is put into the single word |cur_val|, which suddenly
  9656. // switches significance from |integer| to |scaled|.
  9657. func (prg *prg) scanDimen(mu, inf, shortcut bool) {
  9658. var (
  9659. negative bool // should the answer be negated?
  9660. f int32 // numerator of a fraction whose denominator is $2^[16]$
  9661. // Local variables for dimension calculations
  9662. num, denom/* 1..65536 */ uint32 // conversion ratio for the scanned units
  9663. k, kk smallNumber // number of digits in a decimal fraction
  9664. p, q halfword // top of decimal digit stack
  9665. v scaled // an internal dimension
  9666. saveCurVal int32 // temporary storage of |cur_val|
  9667. )
  9668. f = 0
  9669. prg.arithError = false
  9670. prg.curOrder = byte(normal)
  9671. negative = false
  9672. if !shortcut {
  9673. negative = false
  9674. for {
  9675. // Get the next non-blank non-call token
  9676. for {
  9677. prg.getXToken()
  9678. if int32(prg.curCmd) != spacer {
  9679. break
  9680. }
  9681. }
  9682. if int32(prg.curTok) == otherToken+'-' {
  9683. negative = !negative
  9684. prg.curTok = uint16(otherToken + '+')
  9685. }
  9686. if int32(prg.curTok) != otherToken+'+' {
  9687. break
  9688. }
  9689. }
  9690. if int32(prg.curCmd) >= minInternal && int32(prg.curCmd) <= maxInternal {
  9691. if mu {
  9692. prg.scanSomethingInternal(smallNumber(muVal), false)
  9693. // Coerce glue to a dimension
  9694. if int32(prg.curValLevel) >= glueVal {
  9695. v = *prg.mem[prg.curVal+widthOffset].int()
  9696. prg.deleteGlueRef(halfword(prg.curVal))
  9697. prg.curVal = v
  9698. }
  9699. if int32(prg.curValLevel) == muVal {
  9700. goto attachSign
  9701. }
  9702. if int32(prg.curValLevel) != intVal {
  9703. prg.muError()
  9704. }
  9705. } else {
  9706. prg.scanSomethingInternal(smallNumber(dimenVal), false)
  9707. if int32(prg.curValLevel) == dimenVal {
  9708. goto attachSign
  9709. }
  9710. }
  9711. } else {
  9712. prg.backInput()
  9713. if int32(prg.curTok) == continentalPointToken {
  9714. prg.curTok = uint16(pointToken)
  9715. }
  9716. if int32(prg.curTok) != pointToken {
  9717. prg.scanInt()
  9718. } else {
  9719. prg.radix = 10
  9720. prg.curVal = 0
  9721. }
  9722. if int32(prg.curTok) == continentalPointToken {
  9723. prg.curTok = uint16(pointToken)
  9724. }
  9725. if int32(prg.radix) == 10 && int32(prg.curTok) == pointToken {
  9726. k = 0
  9727. p = 0
  9728. prg.getToken() // |point_token| is being re-scanned
  9729. for true {
  9730. prg.getXToken()
  9731. if int32(prg.curTok) > zeroToken+9 || int32(prg.curTok) < zeroToken {
  9732. goto done1
  9733. }
  9734. if int32(k) < 17 {
  9735. q = prg.getAvail()
  9736. *(*prg.mem[q].hh()).rh() = p
  9737. *(*prg.mem[q].hh()).lh() = uint16(int32(prg.curTok) - zeroToken)
  9738. p = q
  9739. k = byte(int32(k) + 1)
  9740. }
  9741. }
  9742. done1:
  9743. for ii := int32(k); ii >= 1; ii-- {
  9744. kk = smallNumber(ii)
  9745. _ = kk
  9746. prg.dig[int32(kk)-1] = byte(*(*prg.mem[p].hh()).lh())
  9747. q = p
  9748. p = *(*prg.mem[p].hh()).rh()
  9749. {
  9750. *(*prg.mem[q].hh()).rh() = prg.avail
  9751. prg.avail = q /* dyn_used:= dyn_used-1 ; [ ] */
  9752. }
  9753. }
  9754. f = prg.roundDecimals(k)
  9755. if int32(prg.curCmd) != spacer {
  9756. prg.backInput()
  9757. }
  9758. }
  9759. }
  9760. }
  9761. if prg.curVal < 0 {
  9762. negative = !negative
  9763. prg.curVal = -prg.curVal
  9764. }
  9765. // Scan units and set |cur_val| to $x\cdot(|cur_val|+f/2^[16])$, where there are |x| sp per unit; |goto attach_sign| if the units are internal
  9766. if inf {
  9767. if prg.scanKeyword(strNumber( /* "fil" */ 311)) {
  9768. prg.curOrder = byte(fil)
  9769. for prg.scanKeyword(strNumber('l')) {
  9770. if int32(prg.curOrder) == filll {
  9771. {
  9772. if int32(prg.interaction) == errorStopMode {
  9773. }
  9774. prg.printNl(strNumber( /* "! " */ 262))
  9775. prg.print( /* "Illegal unit of measure (" */ 705)
  9776. }
  9777. // \xref[Illegal unit of measure]
  9778. prg.print( /* "replaced by filll)" */ 706)
  9779. {
  9780. prg.helpPtr = 1
  9781. prg.helpLine[0] = /* "I dddon't go any higher than filll." */ 707
  9782. }
  9783. prg.error1()
  9784. } else {
  9785. prg.curOrder = byte(int32(prg.curOrder) + 1)
  9786. }
  9787. }
  9788. goto attachFraction
  9789. }
  9790. }
  9791. // Scan for \(u)units that are internal dimensions; |goto attach_sign| with |cur_val| set if found
  9792. saveCurVal = prg.curVal
  9793. // Get the next non-blank non-call...
  9794. for {
  9795. prg.getXToken()
  9796. if int32(prg.curCmd) != spacer {
  9797. break
  9798. }
  9799. }
  9800. if int32(prg.curCmd) < minInternal || int32(prg.curCmd) > maxInternal {
  9801. prg.backInput()
  9802. } else {
  9803. if mu {
  9804. prg.scanSomethingInternal(smallNumber(muVal), false)
  9805. // Coerce glue...
  9806. if int32(prg.curValLevel) >= glueVal {
  9807. v = *prg.mem[prg.curVal+widthOffset].int()
  9808. prg.deleteGlueRef(halfword(prg.curVal))
  9809. prg.curVal = v
  9810. }
  9811. if int32(prg.curValLevel) != muVal {
  9812. prg.muError()
  9813. }
  9814. } else {
  9815. prg.scanSomethingInternal(smallNumber(dimenVal), false)
  9816. }
  9817. v = prg.curVal
  9818. goto found
  9819. }
  9820. if mu {
  9821. goto notFound
  9822. }
  9823. if prg.scanKeyword(strNumber( /* "em" */ 708)) {
  9824. v = *prg.fontInfo[quadCode+prg.paramBase[*(*prg.eqtb[curFontLoc-1].hh()).rh()]].int()
  9825. } else if prg.scanKeyword(strNumber( /* "ex" */ 709)) {
  9826. v = *prg.fontInfo[xHeightCode+prg.paramBase[*(*prg.eqtb[curFontLoc-1].hh()).rh()]].int()
  9827. } else {
  9828. goto notFound
  9829. }
  9830. // Scan an optional space
  9831. {
  9832. prg.getXToken()
  9833. if int32(prg.curCmd) != spacer {
  9834. prg.backInput()
  9835. }
  9836. }
  9837. found:
  9838. prg.curVal = prg.multAndAdd(saveCurVal, v, prg.xnOverD(v, f, 0200000), scaled(07777777777))
  9839. goto attachSign
  9840. notFound:
  9841. ;
  9842. if mu {
  9843. if prg.scanKeyword(strNumber( /* "mu" */ 337)) {
  9844. goto attachFraction
  9845. } else {
  9846. {
  9847. if int32(prg.interaction) == errorStopMode {
  9848. }
  9849. prg.printNl(strNumber( /* "! " */ 262))
  9850. prg.print( /* "Illegal unit of measure (" */ 705)
  9851. }
  9852. prg.print( /* "mu inserted)" */ 710)
  9853. // \xref[Illegal unit of measure]
  9854. {
  9855. prg.helpPtr = 4
  9856. prg.helpLine[3] = /* "The unit of measurement in math glue must be mu." */ 711
  9857. prg.helpLine[2] = /* "To recover gracefully from this error, it's best to" */ 712
  9858. prg.helpLine[1] = /* "delete the erroneous units; e.g., type `2' to delete" */ 713
  9859. prg.helpLine[0] = /* "two letters. (See Chapter 27 of The TeXbook.)" */ 714
  9860. }
  9861. // \xref[TeXbook][\sl The \TeX book]
  9862. prg.error1()
  9863. goto attachFraction
  9864. }
  9865. }
  9866. if prg.scanKeyword(strNumber( /* "true" */ 704)) {
  9867. prg.prepareMag()
  9868. if *prg.eqtb[intBase+magCode-1].int() != 1000 {
  9869. prg.curVal = prg.xnOverD(prg.curVal, 1000, *prg.eqtb[intBase+magCode-1].int())
  9870. f = (1000*f + 0200000*prg.remainder) / *prg.eqtb[intBase+magCode-1].int()
  9871. prg.curVal = prg.curVal + f/0200000
  9872. f = f % 0200000
  9873. }
  9874. }
  9875. // \xref[true]
  9876. if prg.scanKeyword(strNumber( /* "pt" */ 397)) {
  9877. goto attachFraction
  9878. } // the easy case
  9879. // \xref[pt]
  9880. // Scan for \(a)all other units and adjust |cur_val| and |f| accordingly; |goto done| in the case of scaled points
  9881. if prg.scanKeyword(strNumber( /* "in" */ 715)) {
  9882. num = 7227
  9883. denom = 100
  9884. } else if prg.scanKeyword(strNumber( /* "pc" */ 716)) {
  9885. num = 12
  9886. denom = 1
  9887. } else if prg.scanKeyword(strNumber( /* "cm" */ 717)) {
  9888. num = 7227
  9889. denom = 254
  9890. } else if prg.scanKeyword(strNumber( /* "mm" */ 718)) {
  9891. num = 7227
  9892. denom = 2540
  9893. } else if prg.scanKeyword(strNumber( /* "bp" */ 719)) {
  9894. num = 7227
  9895. denom = 7200
  9896. } else if prg.scanKeyword(strNumber( /* "dd" */ 720)) {
  9897. num = 1238
  9898. denom = 1157
  9899. } else if prg.scanKeyword(strNumber( /* "cc" */ 721)) {
  9900. num = 14856
  9901. denom = 1157
  9902. } else if prg.scanKeyword(strNumber( /* "sp" */ 722)) {
  9903. goto done
  9904. } else {
  9905. // Complain about unknown unit and |goto done2|
  9906. {
  9907. if int32(prg.interaction) == errorStopMode {
  9908. }
  9909. prg.printNl(strNumber( /* "! " */ 262))
  9910. prg.print( /* "Illegal unit of measure (" */ 705)
  9911. }
  9912. prg.print( /* "pt inserted)" */ 723)
  9913. // \xref[Illegal unit of measure]
  9914. {
  9915. prg.helpPtr = 6
  9916. prg.helpLine[5] = /* "Dimensions can be in units of em, ex, in, pt, pc," */ 724
  9917. prg.helpLine[4] = /* "cm, mm, dd, cc, bp, or sp; but yours is a new one!" */ 725
  9918. prg.helpLine[3] = /* "I'll assume that you meant to say pt, for printer's points." */ 726
  9919. prg.helpLine[2] = /* "To recover gracefully from this error, it's best to" */ 712
  9920. prg.helpLine[1] = /* "delete the erroneous units; e.g., type `2' to delete" */ 713
  9921. prg.helpLine[0] = /* "two letters. (See Chapter 27 of The TeXbook.)" */ 714
  9922. }
  9923. // \xref[TeXbook][\sl The \TeX book]
  9924. prg.error1()
  9925. goto done2
  9926. }
  9927. prg.curVal = prg.xnOverD(prg.curVal, int32(num), int32(denom))
  9928. f = (int32(num)*f + 0200000*prg.remainder) / int32(denom)
  9929. prg.curVal = prg.curVal + f/0200000
  9930. f = f % 0200000
  9931. done2:
  9932. ;
  9933. attachFraction:
  9934. if prg.curVal >= 040000 {
  9935. prg.arithError = true
  9936. } else {
  9937. prg.curVal = prg.curVal*0200000 + f
  9938. }
  9939. done:
  9940. ;
  9941. // Scan an optional space
  9942. {
  9943. prg.getXToken()
  9944. if int32(prg.curCmd) != spacer {
  9945. prg.backInput()
  9946. }
  9947. }
  9948. attachSign:
  9949. if prg.arithError || abs(prg.curVal) >= 010000000000 {
  9950. {
  9951. if int32(prg.interaction) == errorStopMode {
  9952. }
  9953. prg.printNl(strNumber( /* "! " */ 262))
  9954. prg.print( /* "Dimension too large" */ 727)
  9955. }
  9956. // \xref[Dimension too large]
  9957. {
  9958. prg.helpPtr = 2
  9959. prg.helpLine[1] = /* "I can't work with sizes bigger than about 19 feet." */ 728
  9960. prg.helpLine[0] = /* "Continue and I'll use the largest value I can." */ 729
  9961. }
  9962. prg.error1()
  9963. prg.curVal = 07777777777
  9964. prg.arithError = false
  9965. }
  9966. if negative {
  9967. prg.curVal = -prg.curVal
  9968. }
  9969. }
  9970. // 461.
  9971. // tangle:pos tex.web:9064:1:
  9972. // The final member of \TeX's value-scanning trio is |scan_glue|, which
  9973. // makes |cur_val| point to a glue specification. The reference count of that
  9974. // glue spec will take account of the fact that |cur_val| is pointing to~it.
  9975. //
  9976. // The |level| parameter should be either |glue_val| or |mu_val|.
  9977. //
  9978. // Since |scan_dimen| was so much more complex than |scan_int|, we might expect
  9979. // |scan_glue| to be even worse. But fortunately, it is very simple, since
  9980. // most of the work has already been done.
  9981. func (prg *prg) scanGlue(level smallNumber) {
  9982. var (
  9983. negative bool // should the answer be negated?
  9984. q halfword // new glue specification
  9985. mu bool // does |level=mu_val|?
  9986. )
  9987. mu = int32(level) == muVal
  9988. // Get the next non-blank non-sign...
  9989. negative = false
  9990. for {
  9991. // Get the next non-blank non-call token
  9992. for {
  9993. prg.getXToken()
  9994. if int32(prg.curCmd) != spacer {
  9995. break
  9996. }
  9997. }
  9998. if int32(prg.curTok) == otherToken+'-' {
  9999. negative = !negative
  10000. prg.curTok = uint16(otherToken + '+')
  10001. }
  10002. if int32(prg.curTok) != otherToken+'+' {
  10003. break
  10004. }
  10005. }
  10006. if int32(prg.curCmd) >= minInternal && int32(prg.curCmd) <= maxInternal {
  10007. prg.scanSomethingInternal(level, negative)
  10008. if int32(prg.curValLevel) >= glueVal {
  10009. if int32(prg.curValLevel) != int32(level) {
  10010. prg.muError()
  10011. }
  10012. goto exit
  10013. }
  10014. if int32(prg.curValLevel) == intVal {
  10015. prg.scanDimen(mu, false, true)
  10016. } else if int32(level) == muVal {
  10017. prg.muError()
  10018. }
  10019. } else {
  10020. prg.backInput()
  10021. prg.scanDimen(mu, false, false)
  10022. if negative {
  10023. prg.curVal = -prg.curVal
  10024. }
  10025. }
  10026. // Create a new glue specification whose width is |cur_val|; scan for its stretch and shrink components
  10027. q = prg.newSpec(halfword(memBot))
  10028. *prg.mem[int32(q)+widthOffset].int() = prg.curVal
  10029. if prg.scanKeyword(strNumber( /* "plus" */ 730)) {
  10030. prg.scanDimen(mu, true, false)
  10031. *prg.mem[int32(q)+2].int() = prg.curVal
  10032. *(*prg.mem[q].hh()).b0() = prg.curOrder
  10033. }
  10034. if prg.scanKeyword(strNumber( /* "minus" */ 731)) {
  10035. prg.scanDimen(mu, true, false)
  10036. *prg.mem[int32(q)+3].int() = prg.curVal
  10037. *(*prg.mem[q].hh()).b1() = prg.curOrder
  10038. }
  10039. prg.curVal = int32(q)
  10040. exit:
  10041. }
  10042. // 463.
  10043. // tangle:pos tex.web:9111:1:
  10044. // Here's a similar procedure that returns a pointer to a rule node. This
  10045. // routine is called just after \TeX\ has seen \.[\\hrule] or \.[\\vrule];
  10046. // therefore |cur_cmd| will be either |hrule| or |vrule|. The idea is to store
  10047. // the default rule dimensions in the node, then to override them if
  10048. // `\.[height]' or `\.[width]' or `\.[depth]' specifications are
  10049. // found (in any order).
  10050. func (prg *prg) scanRuleSpec() (r halfword) {
  10051. var (
  10052. q halfword // the rule node being created
  10053. )
  10054. q = prg.newRule() // |width|, |depth|, and |height| all equal |null_flag| now
  10055. if int32(prg.curCmd) == vrule {
  10056. *prg.mem[int32(q)+widthOffset].int() = defaultRule
  10057. } else {
  10058. *prg.mem[int32(q)+heightOffset].int() = defaultRule
  10059. *prg.mem[int32(q)+depthOffset].int() = 0
  10060. }
  10061. reswitch:
  10062. if prg.scanKeyword(strNumber( /* "width" */ 732)) {
  10063. prg.scanDimen(false, false, false)
  10064. *prg.mem[int32(q)+widthOffset].int() = prg.curVal
  10065. goto reswitch
  10066. }
  10067. if prg.scanKeyword(strNumber( /* "height" */ 733)) {
  10068. prg.scanDimen(false, false, false)
  10069. *prg.mem[int32(q)+heightOffset].int() = prg.curVal
  10070. goto reswitch
  10071. }
  10072. if prg.scanKeyword(strNumber( /* "depth" */ 734)) {
  10073. prg.scanDimen(false, false, false)
  10074. *prg.mem[int32(q)+depthOffset].int() = prg.curVal
  10075. goto reswitch
  10076. }
  10077. r = q
  10078. return r
  10079. }
  10080. // 464. \[27] Building token lists
  10081. // tangle:pos tex.web:9142:29:
  10082. // The token lists for macros and for other things like \.[\\mark] and \.[\\output]
  10083. // and \.[\\write] are produced by a procedure called |scan_toks|.
  10084. //
  10085. // Before we get into the details of |scan_toks|, let's consider a much
  10086. // simpler task, that of converting the current string into a token list.
  10087. // The |str_toks| function does this; it classifies spaces as type |spacer|
  10088. // and everything else as type |other_char|.
  10089. //
  10090. // The token list created by |str_toks| begins at |link(temp_head)| and ends
  10091. // at the value |p| that is returned. (If |p=temp_head|, the list is empty.)
  10092. func (prg *prg) strToks(b poolPointer) (r halfword) {
  10093. // converts |str_pool[b..pool_ptr-1]| to a token list
  10094. var (
  10095. p halfword // tail of the token list
  10096. q halfword // new node being added to the token list via |store_new_token|
  10097. t halfword // token being appended
  10098. k poolPointer // index into |str_pool|
  10099. )
  10100. {
  10101. if int32(prg.poolPtr)+1 > poolSize {
  10102. prg.overflow(strNumber( /* "pool size" */ 257), poolSize-int32(prg.initPoolPtr))
  10103. } /* \xref[TeX capacity exceeded pool size][\quad pool size] */
  10104. }
  10105. p = uint16(30000 - 3)
  10106. *(*prg.mem[p].hh()).rh() = 0
  10107. k = b
  10108. for int32(k) < int32(prg.poolPtr) {
  10109. t = uint16(prg.strPool[k])
  10110. if int32(t) == ' ' {
  10111. t = uint16(spaceToken)
  10112. } else {
  10113. t = uint16(otherToken + int32(t))
  10114. }
  10115. {
  10116. {
  10117. q = prg.avail
  10118. if int32(q) == 0 {
  10119. q = prg.getAvail()
  10120. } else {
  10121. prg.avail = *(*prg.mem[q].hh()).rh()
  10122. *(*prg.mem[q].hh()).rh() = 0 /* dyn_used:= dyn_used+1 ; [ ] */
  10123. }
  10124. }
  10125. *(*prg.mem[p].hh()).rh() = q
  10126. *(*prg.mem[q].hh()).lh() = t
  10127. p = q
  10128. }
  10129. k = uint16(int32(k) + 1)
  10130. }
  10131. prg.poolPtr = b
  10132. r = p
  10133. return r
  10134. }
  10135. // 465.
  10136. // tangle:pos tex.web:9172:1:
  10137. // The main reason for wanting |str_toks| is the next function,
  10138. // |the_toks|, which has similar input/output characteristics.
  10139. //
  10140. // This procedure is supposed to scan something like `\.[\\skip\\count12]',
  10141. // i.e., whatever can follow `\.[\\the]', and it constructs a token list
  10142. // containing something like `\.[-3.0pt minus 0.5fill]'.
  10143. func (prg *prg) theToks() (r halfword) {
  10144. var (
  10145. oldSetting/* 0..maxSelector */ byte // holds |selector| setting
  10146. p, q, r1 halfword // used for copying a token list
  10147. b poolPointer // base of temporary string
  10148. )
  10149. prg.getXToken()
  10150. prg.scanSomethingInternal(smallNumber(tokVal), false)
  10151. if int32(prg.curValLevel) >= identVal {
  10152. p = uint16(30000 - 3)
  10153. *(*prg.mem[p].hh()).rh() = 0
  10154. if int32(prg.curValLevel) == identVal {
  10155. q = prg.getAvail()
  10156. *(*prg.mem[p].hh()).rh() = q
  10157. *(*prg.mem[q].hh()).lh() = uint16(07777 + prg.curVal)
  10158. p = q
  10159. } else if prg.curVal != 0 {
  10160. r1 = *(*prg.mem[prg.curVal].hh()).rh() // do not copy the reference count
  10161. for int32(r1) != 0 {
  10162. {
  10163. {
  10164. q = prg.avail
  10165. if int32(q) == 0 {
  10166. q = prg.getAvail()
  10167. } else {
  10168. prg.avail = *(*prg.mem[q].hh()).rh()
  10169. *(*prg.mem[q].hh()).rh() = 0 /* dyn_used:= dyn_used+1 ; [ ] */
  10170. }
  10171. }
  10172. *(*prg.mem[p].hh()).rh() = q
  10173. *(*prg.mem[q].hh()).lh() = *(*prg.mem[r1].hh()).lh()
  10174. p = q
  10175. }
  10176. r1 = *(*prg.mem[r1].hh()).rh()
  10177. }
  10178. }
  10179. r = p
  10180. } else {
  10181. oldSetting = prg.selector
  10182. prg.selector = byte(newString)
  10183. b = prg.poolPtr
  10184. switch prg.curValLevel {
  10185. case intVal:
  10186. prg.printInt(prg.curVal)
  10187. case dimenVal:
  10188. prg.printScaled(prg.curVal)
  10189. prg.print( /* "pt" */ 397)
  10190. case glueVal:
  10191. prg.printSpec(prg.curVal, strNumber( /* "pt" */ 397))
  10192. prg.deleteGlueRef(halfword(prg.curVal))
  10193. case muVal:
  10194. prg.printSpec(prg.curVal, strNumber( /* "mu" */ 337))
  10195. prg.deleteGlueRef(halfword(prg.curVal))
  10196. } // there are no other cases
  10197. prg.selector = oldSetting
  10198. r = prg.strToks(b)
  10199. }
  10200. return r
  10201. } // \2
  10202. func (prg *prg) insTheToks() {
  10203. *(*prg.mem[30000-12].hh()).rh() = prg.theToks()
  10204. prg.beginTokenList(*(*prg.mem[30000-3].hh()).rh(), quarterword(inserted))
  10205. } // \2
  10206. func (prg *prg) convToks() {
  10207. var (
  10208. oldSetting/* 0..maxSelector */ byte // holds |selector| setting
  10209. c/* numberCode..jobNameCode */ byte // desired type of conversion
  10210. saveScannerStatus smallNumber // |scanner_status| upon entry
  10211. b poolPointer // base of temporary string
  10212. )
  10213. c = byte(prg.curChr)
  10214. // Scan the argument for command |c|
  10215. switch c {
  10216. case numberCode, romanNumeralCode:
  10217. prg.scanInt()
  10218. case stringCode, meaningCode:
  10219. saveScannerStatus = prg.scannerStatus
  10220. prg.scannerStatus = byte(normal)
  10221. prg.getToken()
  10222. prg.scannerStatus = saveScannerStatus
  10223. case fontNameCode:
  10224. prg.scanFontIdent()
  10225. case jobNameCode:
  10226. if int32(prg.jobName) == 0 {
  10227. prg.openLogFile()
  10228. }
  10229. }
  10230. oldSetting = prg.selector
  10231. prg.selector = byte(newString)
  10232. b = prg.poolPtr
  10233. // Print the result of command |c|
  10234. switch c {
  10235. case numberCode:
  10236. prg.printInt(prg.curVal)
  10237. case romanNumeralCode:
  10238. prg.printRomanInt(prg.curVal)
  10239. case stringCode:
  10240. if int32(prg.curCs) != 0 {
  10241. prg.sprintCs(prg.curCs)
  10242. } else {
  10243. prg.printChar(asciiCode(prg.curChr))
  10244. }
  10245. case meaningCode:
  10246. prg.printMeaning()
  10247. case fontNameCode:
  10248. prg.print(int32(prg.fontName[prg.curVal]))
  10249. if prg.fontSize[prg.curVal] != prg.fontDsize[prg.curVal] {
  10250. prg.print( /* " at " */ 741)
  10251. prg.printScaled(prg.fontSize[prg.curVal])
  10252. prg.print( /* "pt" */ 397)
  10253. }
  10254. case jobNameCode:
  10255. prg.print(int32(prg.jobName))
  10256. }
  10257. prg.selector = oldSetting
  10258. *(*prg.mem[30000-12].hh()).rh() = prg.strToks(b)
  10259. prg.beginTokenList(*(*prg.mem[30000-3].hh()).rh(), quarterword(inserted))
  10260. }
  10261. // 473.
  10262. // tangle:pos tex.web:9292:1:
  10263. // Now we can't postpone the difficulties any longer; we must bravely tackle
  10264. // |scan_toks|. This function returns a pointer to the tail of a new token
  10265. // list, and it also makes |def_ref| point to the reference count at the
  10266. // head of that list.
  10267. //
  10268. // There are two boolean parameters, |macro_def| and |xpand|. If |macro_def|
  10269. // is true, the goal is to create the token list for a macro definition;
  10270. // otherwise the goal is to create the token list for some other \TeX\
  10271. // primitive: \.[\\mark], \.[\\output], \.[\\everypar], \.[\\lowercase],
  10272. // \.[\\uppercase], \.[\\message], \.[\\errmessage], \.[\\write], or
  10273. // \.[\\special]. In the latter cases a left brace must be scanned next; this
  10274. // left brace will not be part of the token list, nor will the matching right
  10275. // brace that comes at the end. If |xpand| is false, the token list will
  10276. // simply be copied from the input using |get_token|. Otherwise all expandable
  10277. // tokens will be expanded until unexpandable tokens are left, except that
  10278. // the results of expanding `\.[\\the]' are not expanded further.
  10279. // If both |macro_def| and |xpand| are true, the expansion applies
  10280. // only to the macro body (i.e., to the material following the first
  10281. // |left_brace| character).
  10282. //
  10283. // The value of |cur_cs| when |scan_toks| begins should be the |eqtb|
  10284. // address of the control sequence to display in “runaway” error
  10285. // messages.
  10286. func (prg *prg) scanToks(macroDef, xpand bool) (r halfword) {
  10287. var (
  10288. t halfword // token representing the highest parameter number
  10289. s halfword // saved token
  10290. p halfword // tail of the token list being built
  10291. q halfword // new node being added to the token list via |store_new_token|
  10292. unbalance halfword // number of unmatched left braces
  10293. hashBrace halfword // possible `\.[\#\[]' token
  10294. )
  10295. if macroDef {
  10296. prg.scannerStatus = byte(defining)
  10297. } else {
  10298. prg.scannerStatus = byte(absorbing)
  10299. }
  10300. prg.warningIndex = prg.curCs
  10301. prg.defRef = prg.getAvail()
  10302. *(*prg.mem[prg.defRef].hh()).lh() = 0
  10303. p = prg.defRef
  10304. hashBrace = 0
  10305. t = uint16(zeroToken)
  10306. if macroDef {
  10307. for true {
  10308. continue1:
  10309. prg.getToken() // set |cur_cmd|, |cur_chr|, |cur_tok|
  10310. if int32(prg.curTok) < rightBraceLimit {
  10311. goto done1
  10312. }
  10313. if int32(prg.curCmd) == macParam {
  10314. s = uint16(matchToken + int32(prg.curChr))
  10315. prg.getToken()
  10316. if int32(prg.curTok) < leftBraceLimit {
  10317. hashBrace = prg.curTok
  10318. {
  10319. q = prg.getAvail()
  10320. *(*prg.mem[p].hh()).rh() = q
  10321. *(*prg.mem[q].hh()).lh() = prg.curTok
  10322. p = q
  10323. }
  10324. {
  10325. q = prg.getAvail()
  10326. *(*prg.mem[p].hh()).rh() = q
  10327. *(*prg.mem[q].hh()).lh() = uint16(endMatchToken)
  10328. p = q
  10329. }
  10330. goto done
  10331. }
  10332. if int32(t) == zeroToken+9 {
  10333. {
  10334. if int32(prg.interaction) == errorStopMode {
  10335. }
  10336. prg.printNl(strNumber( /* "! " */ 262))
  10337. prg.print( /* "You already have nine parameters" */ 744)
  10338. }
  10339. // \xref[You already have nine...]
  10340. {
  10341. prg.helpPtr = 2
  10342. prg.helpLine[1] = /* "I'm going to ignore the # sign you just used," */ 745
  10343. prg.helpLine[0] = /* "as well as the token that followed it." */ 746
  10344. }
  10345. prg.error1()
  10346. goto continue1
  10347. } else {
  10348. t = uint16(int32(t) + 1)
  10349. if int32(prg.curTok) != int32(t) {
  10350. {
  10351. if int32(prg.interaction) == errorStopMode {
  10352. }
  10353. prg.printNl(strNumber( /* "! " */ 262))
  10354. prg.print( /* "Parameters must be numbered consecutively" */ 747)
  10355. }
  10356. // \xref[Parameters...consecutively]
  10357. {
  10358. prg.helpPtr = 2
  10359. prg.helpLine[1] = /* "I've inserted the digit you should have used after the #." */ 748
  10360. prg.helpLine[0] = /* "Type `1' to delete what you did use." */ 749
  10361. }
  10362. prg.backError()
  10363. }
  10364. prg.curTok = s
  10365. }
  10366. }
  10367. {
  10368. q = prg.getAvail()
  10369. *(*prg.mem[p].hh()).rh() = q
  10370. *(*prg.mem[q].hh()).lh() = prg.curTok
  10371. p = q
  10372. }
  10373. }
  10374. done1:
  10375. {
  10376. q = prg.getAvail()
  10377. *(*prg.mem[p].hh()).rh() = q
  10378. *(*prg.mem[q].hh()).lh() = uint16(endMatchToken)
  10379. p = q
  10380. }
  10381. if int32(prg.curCmd) == rightBrace {
  10382. {
  10383. if int32(prg.interaction) == errorStopMode {
  10384. }
  10385. prg.printNl(strNumber( /* "! " */ 262))
  10386. prg.print( /* "Missing [ inserted" */ 657)
  10387. }
  10388. prg.alignState = prg.alignState + 1
  10389. // \xref[Missing \[ inserted]
  10390. {
  10391. prg.helpPtr = 2
  10392. prg.helpLine[1] = /* "Where was the left brace? You said something like `\\def\\a]'," */ 742
  10393. prg.helpLine[0] = /* "which I'm going to interpret as `\\def\\a[]'." */ 743
  10394. }
  10395. prg.error1()
  10396. goto found
  10397. }
  10398. done:
  10399. } else {
  10400. prg.scanLeftBrace()
  10401. } // remove the compulsory left brace
  10402. // Scan and build the body of the token list; |goto found| when finished
  10403. unbalance = 1
  10404. for true {
  10405. if xpand {
  10406. for true {
  10407. prg.getNext()
  10408. if int32(prg.curCmd) <= maxCommand {
  10409. goto done2
  10410. }
  10411. if int32(prg.curCmd) != the {
  10412. prg.expand()
  10413. } else {
  10414. q = prg.theToks()
  10415. if int32(*(*prg.mem[30000-3].hh()).rh()) != 0 {
  10416. *(*prg.mem[p].hh()).rh() = *(*prg.mem[30000-3].hh()).rh()
  10417. p = q
  10418. }
  10419. }
  10420. }
  10421. done2:
  10422. prg.xToken()
  10423. } else {
  10424. prg.getToken()
  10425. }
  10426. if int32(prg.curTok) < rightBraceLimit {
  10427. if int32(prg.curCmd) < rightBrace {
  10428. unbalance = uint16(int32(unbalance) + 1)
  10429. } else {
  10430. unbalance = uint16(int32(unbalance) - 1)
  10431. if int32(unbalance) == 0 {
  10432. goto found
  10433. }
  10434. }
  10435. } else if int32(prg.curCmd) == macParam {
  10436. if macroDef {
  10437. s = prg.curTok
  10438. if xpand {
  10439. prg.getXToken()
  10440. } else {
  10441. prg.getToken()
  10442. }
  10443. if int32(prg.curCmd) != macParam {
  10444. if int32(prg.curTok) <= zeroToken || int32(prg.curTok) > int32(t) {
  10445. {
  10446. if int32(prg.interaction) == errorStopMode {
  10447. }
  10448. prg.printNl(strNumber( /* "! " */ 262))
  10449. prg.print( /* "Illegal parameter number in definition of " */ 750)
  10450. }
  10451. // \xref[Illegal parameter number...]
  10452. prg.sprintCs(prg.warningIndex)
  10453. {
  10454. prg.helpPtr = 3
  10455. prg.helpLine[2] = /* "You meant to type ## instead of #, right?" */ 751
  10456. prg.helpLine[1] = /* "Or maybe a ] was forgotten somewhere earlier, and things" */ 752
  10457. prg.helpLine[0] = /* "are all screwed up? I'm going to assume that you meant ##." */ 753
  10458. }
  10459. prg.backError()
  10460. prg.curTok = s
  10461. } else {
  10462. prg.curTok = uint16(outParamToken - '0' + int32(prg.curChr))
  10463. }
  10464. }
  10465. }
  10466. }
  10467. {
  10468. q = prg.getAvail()
  10469. *(*prg.mem[p].hh()).rh() = q
  10470. *(*prg.mem[q].hh()).lh() = prg.curTok
  10471. p = q
  10472. }
  10473. }
  10474. found:
  10475. prg.scannerStatus = byte(normal)
  10476. if int32(hashBrace) != 0 {
  10477. q = prg.getAvail()
  10478. *(*prg.mem[p].hh()).rh() = q
  10479. *(*prg.mem[q].hh()).lh() = hashBrace
  10480. p = q
  10481. }
  10482. r = p
  10483. return r
  10484. }
  10485. // 482.
  10486. // tangle:pos tex.web:9444:1:
  10487. // The |read_toks| procedure constructs a token list like that for any
  10488. // macro definition, and makes |cur_val| point to it. Parameter |r| points
  10489. // to the control sequence that will receive this token list.
  10490. func (prg *prg) readToks(n int32, r1 halfword) {
  10491. var (
  10492. p halfword // tail of the token list
  10493. q halfword // new node being added to the token list via |store_new_token|
  10494. s int32 // saved value of |align_state|
  10495. m smallNumber // stream number
  10496. )
  10497. prg.scannerStatus = byte(defining)
  10498. prg.warningIndex = r1
  10499. prg.defRef = prg.getAvail()
  10500. *(*prg.mem[prg.defRef].hh()).lh() = 0
  10501. p = prg.defRef // the reference count
  10502. {
  10503. q = prg.getAvail()
  10504. *(*prg.mem[p].hh()).rh() = q
  10505. *(*prg.mem[q].hh()).lh() = uint16(endMatchToken)
  10506. p = q
  10507. }
  10508. if n < 0 || n > 15 {
  10509. m = 16
  10510. } else {
  10511. m = byte(n)
  10512. }
  10513. s = prg.alignState
  10514. prg.alignState = 1000000 // disable tab marks, etc.
  10515. for {
  10516. // Input and store tokens from the next line of the file
  10517. prg.beginFileReading()
  10518. prg.curInput.nameField = uint16(int32(m) + 1)
  10519. if int32(prg.readOpen[m]) == closed {
  10520. if int32(prg.interaction) > nonstopMode {
  10521. if n < 0 {
  10522. prg.print( /* "" */ 338)
  10523. prg.termInput()
  10524. } else {
  10525. prg.printLn()
  10526. prg.sprintCs(r1)
  10527. {
  10528. prg.print('=')
  10529. prg.termInput()
  10530. }
  10531. n = -1
  10532. }
  10533. } else {
  10534. prg.fatalError(strNumber( /* "*** (cannot \\read from terminal in nonstop modes)" */ 754))
  10535. }
  10536. } else if int32(prg.readOpen[m]) == justOpen {
  10537. if prg.inputLn(prg.readFile[m], false) {
  10538. prg.readOpen[m] = byte(normal)
  10539. } else {
  10540. prg.aClose(prg.readFile[m])
  10541. prg.readOpen[m] = byte(closed)
  10542. }
  10543. } else {
  10544. // Input the next line of |read_file[m]|
  10545. if !prg.inputLn(prg.readFile[m], true) {
  10546. prg.aClose(prg.readFile[m])
  10547. prg.readOpen[m] = byte(closed)
  10548. if prg.alignState != 1000000 {
  10549. prg.runaway()
  10550. {
  10551. if int32(prg.interaction) == errorStopMode {
  10552. }
  10553. prg.printNl(strNumber( /* "! " */ 262))
  10554. prg.print( /* "File ended within " */ 755)
  10555. }
  10556. prg.printEsc(strNumber( /* "read" */ 534))
  10557. // \xref[File ended within \\read]
  10558. {
  10559. prg.helpPtr = 1
  10560. prg.helpLine[0] = /* "This \\read has unbalanced braces." */ 756
  10561. }
  10562. prg.alignState = 1000000
  10563. prg.curInput.limitField = 0
  10564. prg.error1()
  10565. }
  10566. }
  10567. }
  10568. prg.curInput.limitField = prg.last
  10569. if *prg.eqtb[intBase+endLineCharCode-1].int() < 0 || *prg.eqtb[intBase+endLineCharCode-1].int() > 255 {
  10570. prg.curInput.limitField = uint16(int32(prg.curInput.limitField) - 1)
  10571. } else {
  10572. prg.buffer[prg.curInput.limitField] = byte(*prg.eqtb[intBase+endLineCharCode-1].int())
  10573. }
  10574. prg.first = uint16(int32(prg.curInput.limitField) + 1)
  10575. prg.curInput.locField = prg.curInput.startField
  10576. prg.curInput.stateField = byte(newLine)
  10577. for true {
  10578. prg.getToken()
  10579. if int32(prg.curTok) == 0 {
  10580. goto done
  10581. }
  10582. // |cur_cmd=cur_chr=0| will occur at the end of the line
  10583. if prg.alignState < 1000000 {
  10584. for {
  10585. prg.getToken()
  10586. if int32(prg.curTok) == 0 {
  10587. break
  10588. }
  10589. }
  10590. prg.alignState = 1000000
  10591. goto done
  10592. }
  10593. {
  10594. q = prg.getAvail()
  10595. *(*prg.mem[p].hh()).rh() = q
  10596. *(*prg.mem[q].hh()).lh() = prg.curTok
  10597. p = q
  10598. }
  10599. }
  10600. done:
  10601. prg.endFileReading()
  10602. if prg.alignState == 1000000 {
  10603. break
  10604. }
  10605. }
  10606. prg.curVal = int32(prg.defRef)
  10607. prg.scannerStatus = byte(normal)
  10608. prg.alignState = s
  10609. }
  10610. func (prg *prg) passText() {
  10611. var (
  10612. l int32 // level of $\.[\\if]\ldots\.[\\fi]$ nesting
  10613. saveScannerStatus smallNumber // |scanner_status| upon entry
  10614. )
  10615. saveScannerStatus = prg.scannerStatus
  10616. prg.scannerStatus = byte(skipping)
  10617. l = 0
  10618. prg.skipLine = prg.line
  10619. for true {
  10620. prg.getNext()
  10621. if int32(prg.curCmd) == fiOrElse {
  10622. if l == 0 {
  10623. goto done
  10624. }
  10625. if int32(prg.curChr) == fiCode {
  10626. l = l - 1
  10627. }
  10628. } else if int32(prg.curCmd) == ifTest {
  10629. l = l + 1
  10630. }
  10631. }
  10632. done:
  10633. prg.scannerStatus = saveScannerStatus
  10634. }
  10635. // 497.
  10636. // tangle:pos tex.web:9693:1:
  10637. // Here's a procedure that changes the |if_limit| code corresponding to
  10638. // a given value of |cond_ptr|.
  10639. func (prg *prg) changeIfLimit(l smallNumber, p halfword) {
  10640. var (
  10641. q halfword
  10642. )
  10643. if int32(p) == int32(prg.condPtr) {
  10644. prg.ifLimit = l
  10645. } else {
  10646. q = prg.condPtr
  10647. for true {
  10648. if int32(q) == 0 {
  10649. prg.confusion(strNumber( /* "if" */ 757))
  10650. }
  10651. // \xref[this can't happen if][\quad if]
  10652. if int32(*(*prg.mem[q].hh()).rh()) == int32(p) {
  10653. *(*prg.mem[q].hh()).b0() = l
  10654. goto exit
  10655. }
  10656. q = *(*prg.mem[q].hh()).rh()
  10657. }
  10658. }
  10659. exit:
  10660. } // \2
  10661. func (prg *prg) conditional() {
  10662. var (
  10663. b bool // is the condition true?
  10664. r1/* '<'..'>' */ byte // relation to be evaluated
  10665. m, n int32 // to be tested against the second operand
  10666. p, q halfword // for traversing token lists in \.[\\ifx] tests
  10667. saveScannerStatus smallNumber // |scanner_status| upon entry
  10668. saveCondPtr halfword // |cond_ptr| corresponding to this conditional
  10669. thisIf smallNumber // type of this conditional
  10670. )
  10671. {
  10672. p = prg.getNode(ifNodeSize)
  10673. *(*prg.mem[p].hh()).rh() = prg.condPtr
  10674. *(*prg.mem[p].hh()).b0() = prg.ifLimit
  10675. *(*prg.mem[p].hh()).b1() = prg.curIf
  10676. *prg.mem[int32(p)+1].int() = prg.ifLine
  10677. prg.condPtr = p
  10678. prg.curIf = byte(prg.curChr)
  10679. prg.ifLimit = byte(ifCode)
  10680. prg.ifLine = prg.line
  10681. }
  10682. saveCondPtr = prg.condPtr
  10683. thisIf = byte(prg.curChr)
  10684. // Either process \.[\\ifcase] or set |b| to the value of a boolean condition
  10685. switch thisIf {
  10686. case ifCharCode, ifCatCode:
  10687. // Test if two characters match
  10688. {
  10689. prg.getXToken()
  10690. if int32(prg.curCmd) == relax {
  10691. if int32(prg.curChr) == noExpandFlag {
  10692. prg.curCmd = byte(activeChar)
  10693. prg.curChr = uint16(int32(prg.curTok) - 07777 - activeBase)
  10694. }
  10695. }
  10696. }
  10697. if int32(prg.curCmd) > activeChar || int32(prg.curChr) > 255 {
  10698. m = relax
  10699. n = 256
  10700. } else {
  10701. m = int32(prg.curCmd)
  10702. n = int32(prg.curChr)
  10703. }
  10704. /* */ {
  10705. prg.getXToken()
  10706. if int32(prg.curCmd) == relax {
  10707. if int32(prg.curChr) == noExpandFlag {
  10708. prg.curCmd = byte(activeChar)
  10709. prg.curChr = uint16(int32(prg.curTok) - 07777 - activeBase)
  10710. }
  10711. }
  10712. }
  10713. if int32(prg.curCmd) > activeChar || int32(prg.curChr) > 255 {
  10714. prg.curCmd = byte(relax)
  10715. prg.curChr = 256
  10716. }
  10717. if int32(thisIf) == ifCharCode {
  10718. b = n == int32(prg.curChr)
  10719. } else {
  10720. b = m == int32(prg.curCmd)
  10721. }
  10722. case ifIntCode, ifDimCode:
  10723. // Test relation between integers or dimensions
  10724. if int32(thisIf) == ifIntCode {
  10725. prg.scanInt()
  10726. } else {
  10727. prg.scanDimen(false, false, false)
  10728. }
  10729. n = prg.curVal
  10730. // Get the next non-blank non-call...
  10731. for {
  10732. prg.getXToken()
  10733. if int32(prg.curCmd) != spacer {
  10734. break
  10735. }
  10736. }
  10737. if int32(prg.curTok) >= otherToken+'<' && int32(prg.curTok) <= otherToken+'>' {
  10738. r1 = byte(int32(prg.curTok) - otherToken)
  10739. } else {
  10740. {
  10741. if int32(prg.interaction) == errorStopMode {
  10742. }
  10743. prg.printNl(strNumber( /* "! " */ 262))
  10744. prg.print( /* "Missing = inserted for " */ 781)
  10745. }
  10746. // \xref[Missing = inserted]
  10747. prg.printCmdChr(quarterword(ifTest), halfword(thisIf))
  10748. {
  10749. prg.helpPtr = 1
  10750. prg.helpLine[0] = /* "I was expecting to see `<', `=', or `>'. Didn't." */ 782
  10751. }
  10752. prg.backError()
  10753. r1 = '='
  10754. }
  10755. if int32(thisIf) == ifIntCode {
  10756. prg.scanInt()
  10757. } else {
  10758. prg.scanDimen(false, false, false)
  10759. }
  10760. switch r1 {
  10761. case '<':
  10762. b = n < prg.curVal
  10763. // "="=
  10764. case '=':
  10765. b = n == prg.curVal
  10766. // ">"=
  10767. case '>':
  10768. b = n > prg.curVal
  10769. }
  10770. case ifOddCode:
  10771. // Test if an integer is odd
  10772. prg.scanInt()
  10773. b = prg.curVal&1 != 0
  10774. case ifVmodeCode:
  10775. b = abs(int32(prg.curList.modeField)) == vmode
  10776. case ifHmodeCode:
  10777. b = abs(int32(prg.curList.modeField)) == hmode
  10778. case ifMmodeCode:
  10779. b = abs(int32(prg.curList.modeField)) == mmode
  10780. case ifInnerCode:
  10781. b = int32(prg.curList.modeField) < 0
  10782. case ifVoidCode, ifHboxCode, ifVboxCode:
  10783. // Test box register status
  10784. prg.scanEightBitInt()
  10785. p = *(*prg.eqtb[boxBase+prg.curVal-1].hh()).rh()
  10786. if int32(thisIf) == ifVoidCode {
  10787. b = int32(p) == 0
  10788. } else if int32(p) == 0 {
  10789. b = false
  10790. } else if int32(thisIf) == ifHboxCode {
  10791. b = int32(*(*prg.mem[p].hh()).b0()) == hlistNode
  10792. } else {
  10793. b = int32(*(*prg.mem[p].hh()).b0()) == vlistNode
  10794. }
  10795. case ifxCode:
  10796. // Test if two tokens match
  10797. saveScannerStatus = prg.scannerStatus
  10798. prg.scannerStatus = byte(normal)
  10799. prg.getNext()
  10800. n = int32(prg.curCs)
  10801. p = uint16(prg.curCmd)
  10802. q = prg.curChr
  10803. prg.getNext()
  10804. if int32(prg.curCmd) != int32(p) {
  10805. b = false
  10806. } else if int32(prg.curCmd) < call {
  10807. b = int32(prg.curChr) == int32(q)
  10808. } else {
  10809. // Test if two macro texts match
  10810. p = *(*prg.mem[prg.curChr].hh()).rh()
  10811. q = *(*prg.mem[*(*prg.eqtb[n-1].hh()).rh()].hh()).rh() // omit reference counts
  10812. if int32(p) == int32(q) {
  10813. b = true
  10814. } else {
  10815. for int32(p) != 0 && int32(q) != 0 {
  10816. if int32(*(*prg.mem[p].hh()).lh()) != int32(*(*prg.mem[q].hh()).lh()) {
  10817. p = 0
  10818. } else {
  10819. p = *(*prg.mem[p].hh()).rh()
  10820. q = *(*prg.mem[q].hh()).rh()
  10821. }
  10822. }
  10823. b = int32(p) == 0 && int32(q) == 0
  10824. }
  10825. }
  10826. prg.scannerStatus = saveScannerStatus
  10827. case ifEofCode:
  10828. prg.scanFourBitInt()
  10829. b = int32(prg.readOpen[prg.curVal]) == closed
  10830. case ifTrueCode:
  10831. b = true
  10832. case ifFalseCode:
  10833. b = false
  10834. case ifCaseCode:
  10835. // Select the appropriate case and |return| or |goto common_ending|
  10836. prg.scanInt()
  10837. n = prg.curVal // |n| is the number of cases to pass
  10838. if *prg.eqtb[intBase+tracingCommandsCode-1].int() > 1 {
  10839. prg.beginDiagnostic()
  10840. prg.print( /* "[case " */ 783)
  10841. prg.printInt(n)
  10842. prg.printChar(asciiCode('}'))
  10843. prg.endDiagnostic(false)
  10844. }
  10845. for n != 0 {
  10846. prg.passText()
  10847. if int32(prg.condPtr) == int32(saveCondPtr) {
  10848. if int32(prg.curChr) == orCode {
  10849. n = n - 1
  10850. } else {
  10851. goto commonEnding
  10852. }
  10853. } else if int32(prg.curChr) == fiCode {
  10854. p = prg.condPtr
  10855. prg.ifLine = *prg.mem[int32(p)+1].int()
  10856. prg.curIf = *(*prg.mem[p].hh()).b1()
  10857. prg.ifLimit = *(*prg.mem[p].hh()).b0()
  10858. prg.condPtr = *(*prg.mem[p].hh()).rh()
  10859. prg.freeNode(p, halfword(ifNodeSize))
  10860. }
  10861. }
  10862. prg.changeIfLimit(smallNumber(orCode), saveCondPtr)
  10863. goto exit // wait for \.[\\or], \.[\\else], or \.[\\fi]
  10864. }
  10865. if *prg.eqtb[intBase+tracingCommandsCode-1].int() > 1 {
  10866. prg.beginDiagnostic()
  10867. if b {
  10868. prg.print( /* "[true]" */ 779)
  10869. } else {
  10870. prg.print( /* "[false]" */ 780)
  10871. }
  10872. prg.endDiagnostic(false)
  10873. }
  10874. if b {
  10875. prg.changeIfLimit(smallNumber(elseCode), saveCondPtr)
  10876. goto exit // wait for \.[\\else] or \.[\\fi]
  10877. }
  10878. // Skip to \.[\\else] or \.[\\fi], then |goto common_ending|
  10879. for true {
  10880. prg.passText()
  10881. if int32(prg.condPtr) == int32(saveCondPtr) {
  10882. if int32(prg.curChr) != orCode {
  10883. goto commonEnding
  10884. }
  10885. {
  10886. if int32(prg.interaction) == errorStopMode {
  10887. }
  10888. prg.printNl(strNumber( /* "! " */ 262))
  10889. prg.print( /* "Extra " */ 777)
  10890. }
  10891. prg.printEsc(strNumber( /* "or" */ 775))
  10892. // \xref[Extra \\or]
  10893. {
  10894. prg.helpPtr = 1
  10895. prg.helpLine[0] = /* "I'm ignoring this; it doesn't match any \\if." */ 778
  10896. }
  10897. prg.error1()
  10898. } else if int32(prg.curChr) == fiCode {
  10899. p = prg.condPtr
  10900. prg.ifLine = *prg.mem[int32(p)+1].int()
  10901. prg.curIf = *(*prg.mem[p].hh()).b1()
  10902. prg.ifLimit = *(*prg.mem[p].hh()).b0()
  10903. prg.condPtr = *(*prg.mem[p].hh()).rh()
  10904. prg.freeNode(p, halfword(ifNodeSize))
  10905. }
  10906. }
  10907. commonEnding:
  10908. if int32(prg.curChr) == fiCode {
  10909. p = prg.condPtr
  10910. prg.ifLine = *prg.mem[int32(p)+1].int()
  10911. prg.curIf = *(*prg.mem[p].hh()).b1()
  10912. prg.ifLimit = *(*prg.mem[p].hh()).b0()
  10913. prg.condPtr = *(*prg.mem[p].hh()).rh()
  10914. prg.freeNode(p, halfword(ifNodeSize))
  10915. } else {
  10916. prg.ifLimit = byte(fiCode)
  10917. } // wait for \.[\\fi]
  10918. // wait for \.[\\fi]
  10919. exit:
  10920. }
  10921. // 499.
  10922. // tangle:pos tex.web:9737:1:
  10923. // In a construction like `\.[\\if\\iftrue abc\\else d\\fi]', the first
  10924. // \.[\\else] that we come to after learning that the \.[\\if] is false is
  10925. // not the \.[\\else] we're looking for. Hence the following curious
  10926. // logic is needed.
  10927. // 511. \[29] File names
  10928. // tangle:pos tex.web:9910:19:
  10929. // It's time now to fret about file names. Besides the fact that different
  10930. // operating systems treat files in different ways, we must cope with the
  10931. // fact that completely different naming conventions are used by different
  10932. // groups of people. The following programs show what is required for one
  10933. // particular operating system; similar routines for other systems are not
  10934. // difficult to devise.
  10935. // \xref[fingers]
  10936. // \xref[system dependencies]
  10937. //
  10938. // \TeX\ assumes that a file name has three parts: the name proper; its
  10939. // ``extension''; and a ``file area'' where it is found in an external file
  10940. // system. The extension of an input file or a write file is assumed to be
  10941. // `\.[.tex]' unless otherwise specified; it is `\.[.log]' on the
  10942. // transcript file that records each run of \TeX; it is `\.[.tfm]' on the font
  10943. // metric files that describe characters in the fonts \TeX\ uses; it is
  10944. // `\.[.dvi]' on the output files that specify typesetting information; and it
  10945. // is `\.[.fmt]' on the format files written by \.[INITEX] to initialize \TeX.
  10946. // The file area can be arbitrary on input files, but files are usually
  10947. // output to the user's current area. If an input file cannot be
  10948. // found on the specified area, \TeX\ will look for it on a special system
  10949. // area; this special area is intended for commonly used input files like
  10950. // \.[webmac.tex].
  10951. //
  10952. // Simple uses of \TeX\ refer only to file names that have no explicit
  10953. // extension or area. For example, a person usually says `\.[\\input] \.[paper]'
  10954. // or `\.[\\font\\tenrm] \.= \.[helvetica]' instead of `\.[\\input]
  10955. // \.[paper.new]' or `\.[\\font\\tenrm] \.= \.[<csd.knuth>test]'. Simple file
  10956. // names are best, because they make the \TeX\ source files portable;
  10957. // whenever a file name consists entirely of letters and digits, it should be
  10958. // treated in the same way by all implementations of \TeX. However, users
  10959. // need the ability to refer to other files in their environment, especially
  10960. // when responding to error messages concerning unopenable files; therefore
  10961. // we want to let them use the syntax that appears in their favorite
  10962. // operating system.
  10963. //
  10964. // The following procedures don't allow spaces to be part of
  10965. // file names; but some users seem to like names that are spaced-out.
  10966. // System-dependent changes to allow such things should probably
  10967. // be made with reluctance, and only when an entire file name that
  10968. // includes spaces is ``quoted'' somehow.
  10969. // 514.
  10970. // tangle:pos tex.web:9998:1:
  10971. // Input files that can't be found in the user's area may appear in a standard
  10972. // system area called |TEX_area|. Font metric files whose areas are not given
  10973. // explicitly are assumed to appear in a standard system area called
  10974. // |TEX_font_area|. These system area names will, of course, vary from place
  10975. // to place.
  10976. // \xref[system dependencies]
  10977. // 515.
  10978. // tangle:pos tex.web:10010:1:
  10979. // Here now is the first of the system-dependent routines for file name scanning.
  10980. // \xref[system dependencies]
  10981. func (prg *prg) beginName() {
  10982. prg.areaDelimiter = 0
  10983. prg.extDelimiter = 0
  10984. }
  10985. // 516.
  10986. // tangle:pos tex.web:10017:1:
  10987. // And here's the second. The string pool might change as the file name is
  10988. // being scanned, since a new \.[\\csname] might be entered; therefore we keep
  10989. // |area_delimiter| and |ext_delimiter| relative to the beginning of the current
  10990. // string, instead of assigning an absolute address like |pool_ptr| to them.
  10991. // \xref[system dependencies]
  10992. func (prg *prg) moreName(c asciiCode) (r bool) {
  10993. if int32(c) == ' ' {
  10994. r = false
  10995. } else {
  10996. {
  10997. if int32(prg.poolPtr)+1 > poolSize {
  10998. prg.overflow(strNumber( /* "pool size" */ 257), poolSize-int32(prg.initPoolPtr))
  10999. } /* \xref[TeX capacity exceeded pool size][\quad pool size] */
  11000. }
  11001. {
  11002. prg.strPool[prg.poolPtr] = c
  11003. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  11004. } // contribute |c| to the current string
  11005. if int32(c) == '>' || int32(c) == ':' {
  11006. prg.areaDelimiter = uint16(int32(prg.poolPtr) - int32(prg.strStart[prg.strPtr]))
  11007. prg.extDelimiter = 0
  11008. } else if int32(c) == '.' && int32(prg.extDelimiter) == 0 {
  11009. prg.extDelimiter = uint16(int32(prg.poolPtr) - int32(prg.strStart[prg.strPtr]))
  11010. }
  11011. r = true
  11012. }
  11013. return r
  11014. }
  11015. // 517.
  11016. // tangle:pos tex.web:10034:1:
  11017. // The third.
  11018. // \xref[system dependencies]
  11019. func (prg *prg) endName() {
  11020. if int32(prg.strPtr)+3 > maxStrings {
  11021. prg.overflow(strNumber( /* "number of strings" */ 258), maxStrings-int32(prg.initStrPtr))
  11022. }
  11023. // \xref[TeX capacity exceeded number of strings][\quad number of strings]
  11024. if int32(prg.areaDelimiter) == 0 {
  11025. prg.curArea = /* "" */ 338
  11026. } else {
  11027. prg.curArea = prg.strPtr
  11028. prg.strStart[int32(prg.strPtr)+1] = uint16(int32(prg.strStart[prg.strPtr]) + int32(prg.areaDelimiter))
  11029. prg.strPtr = uint16(int32(prg.strPtr) + 1)
  11030. }
  11031. if int32(prg.extDelimiter) == 0 {
  11032. prg.curExt = /* "" */ 338
  11033. prg.curName = prg.makeString()
  11034. } else {
  11035. prg.curName = prg.strPtr
  11036. prg.strStart[int32(prg.strPtr)+1] = uint16(int32(prg.strStart[prg.strPtr]) + int32(prg.extDelimiter) - int32(prg.areaDelimiter) - 1)
  11037. prg.strPtr = uint16(int32(prg.strPtr) + 1)
  11038. prg.curExt = prg.makeString()
  11039. }
  11040. }
  11041. // 519.
  11042. // tangle:pos tex.web:10064:1:
  11043. // Another system-dependent routine is needed to convert three internal
  11044. // \TeX\ strings
  11045. // into the |name_of_file| value that is used to open files. The present code
  11046. // allows both lowercase and uppercase letters in the file name.
  11047. // \xref[system dependencies]
  11048. func (prg *prg) packFileName(n, a, e strNumber) {
  11049. var (
  11050. k int32 // number of positions filled in |name_of_file|
  11051. c asciiCode // character being packed
  11052. j poolPointer // index into |str_pool|
  11053. )
  11054. k = 0
  11055. for ii := int32(prg.strStart[a]); ii <= int32(prg.strStart[int32(a)+1])-1; ii++ {
  11056. j = poolPointer(ii)
  11057. _ = j
  11058. c = prg.strPool[j]
  11059. k = k + 1
  11060. if k <= fileNameSize {
  11061. prg.nameOfFile[k-1] = prg.xchr[c]
  11062. }
  11063. }
  11064. for ii := int32(prg.strStart[n]); ii <= int32(prg.strStart[int32(n)+1])-1; ii++ {
  11065. j = poolPointer(ii)
  11066. _ = j
  11067. c = prg.strPool[j]
  11068. k = k + 1
  11069. if k <= fileNameSize {
  11070. prg.nameOfFile[k-1] = prg.xchr[c]
  11071. }
  11072. }
  11073. for ii := int32(prg.strStart[e]); ii <= int32(prg.strStart[int32(e)+1])-1; ii++ {
  11074. j = poolPointer(ii)
  11075. _ = j
  11076. c = prg.strPool[j]
  11077. k = k + 1
  11078. if k <= fileNameSize {
  11079. prg.nameOfFile[k-1] = prg.xchr[c]
  11080. }
  11081. }
  11082. if k <= fileNameSize {
  11083. prg.nameLength = byte(k)
  11084. } else {
  11085. prg.nameLength = byte(fileNameSize)
  11086. }
  11087. for ii := int32(prg.nameLength) + 1; ii <= fileNameSize; ii++ {
  11088. k = ii
  11089. _ = k
  11090. prg.nameOfFile[k-1] = ' '
  11091. }
  11092. }
  11093. // 523.
  11094. // tangle:pos tex.web:10109:1:
  11095. // Here is the messy routine that was just mentioned. It sets |name_of_file|
  11096. // from the first |n| characters of |TEX_format_default|, followed by
  11097. // |buffer[a..b]|, followed by the last |format_ext_length| characters of
  11098. // |TEX_format_default|.
  11099. //
  11100. // We dare not give error messages here, since \TeX\ calls this routine before
  11101. // the |error| routine is ready to roll. Instead, we simply drop excess characters,
  11102. // since the error will be detected in another way when a strange file name
  11103. // isn't found.
  11104. // \xref[system dependencies]
  11105. func (prg *prg) packBufferedName(n smallNumber, a, b int32) {
  11106. var (
  11107. k int32 // number of positions filled in |name_of_file|
  11108. c asciiCode // character being packed
  11109. j int32 // index into |buffer| or |TEX_format_default|
  11110. )
  11111. if int32(n)+b-a+1+formatExtLength > fileNameSize {
  11112. b = a + fileNameSize - int32(n) - 1 - formatExtLength
  11113. }
  11114. k = 0
  11115. for ii := int32(1); ii <= int32(n); ii++ {
  11116. j = ii
  11117. _ = j
  11118. c = prg.xord[prg.texFormatDefault[j-1]]
  11119. k = k + 1
  11120. if k <= fileNameSize {
  11121. prg.nameOfFile[k-1] = prg.xchr[c]
  11122. }
  11123. }
  11124. for ii := a; ii <= b; ii++ {
  11125. j = ii
  11126. _ = j
  11127. c = prg.buffer[j]
  11128. k = k + 1
  11129. if k <= fileNameSize {
  11130. prg.nameOfFile[k-1] = prg.xchr[c]
  11131. }
  11132. }
  11133. for ii := int32(formatDefaultLength - formatExtLength + 1); ii <= formatDefaultLength; ii++ {
  11134. j = ii
  11135. _ = j
  11136. c = prg.xord[prg.texFormatDefault[j-1]]
  11137. k = k + 1
  11138. if k <= fileNameSize {
  11139. prg.nameOfFile[k-1] = prg.xchr[c]
  11140. }
  11141. }
  11142. if k <= fileNameSize {
  11143. prg.nameLength = byte(k)
  11144. } else {
  11145. prg.nameLength = byte(fileNameSize)
  11146. }
  11147. for ii := int32(prg.nameLength) + 1; ii <= fileNameSize; ii++ {
  11148. k = ii
  11149. _ = k
  11150. prg.nameOfFile[k-1] = ' '
  11151. }
  11152. }
  11153. // 525.
  11154. // tangle:pos tex.web:10172:1:
  11155. // Operating systems often make it possible to determine the exact name (and
  11156. // possible version number) of a file that has been opened. The following routine,
  11157. // which simply makes a \TeX\ string from the value of |name_of_file|, should
  11158. // ideally be changed to deduce the full name of file~|f|, which is the file
  11159. // most recently opened, if it is possible to do this in a \PASCAL\ program.
  11160. // \xref[system dependencies]
  11161. //
  11162. // This routine might be called after string memory has overflowed, hence
  11163. // we dare not use `|str_room|'.
  11164. func (prg *prg) makeNameString() (r strNumber) {
  11165. var (
  11166. k /* 1..fileNameSize */ byte // index into |name_of_file|
  11167. )
  11168. if int32(prg.poolPtr)+int32(prg.nameLength) > poolSize || int32(prg.strPtr) == maxStrings || int32(prg.poolPtr)-int32(prg.strStart[prg.strPtr]) > 0 {
  11169. r = '?'
  11170. } else {
  11171. for ii := int32(1); ii <= int32(prg.nameLength); ii++ {
  11172. k = byte(ii)
  11173. _ = k
  11174. prg.strPool[prg.poolPtr] = prg.xord[prg.nameOfFile[k-1]]
  11175. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  11176. }
  11177. r = prg.makeString()
  11178. }
  11179. return r
  11180. }
  11181. func (prg *prg) aMakeNameString(f alphaFile) (r strNumber) {
  11182. r = prg.makeNameString()
  11183. return r
  11184. }
  11185. func (prg *prg) bMakeNameString(f byteFile) (r strNumber) {
  11186. r = prg.makeNameString()
  11187. return r
  11188. }
  11189. func (prg *prg) wMakeNameString(f wordFile) (r strNumber) {
  11190. r = prg.makeNameString()
  11191. return r
  11192. }
  11193. // 526.
  11194. // tangle:pos tex.web:10201:1:
  11195. // Now let's consider the “driver”
  11196. // routines by which \TeX\ deals with file names
  11197. // in a system-independent manner. First comes a procedure that looks for a
  11198. // file name in the input by calling |get_x_token| for the information.
  11199. func (prg *prg) scanFileName() {
  11200. prg.nameInProgress = true
  11201. prg.beginName()
  11202. // Get the next non-blank non-call...
  11203. for {
  11204. prg.getXToken()
  11205. if int32(prg.curCmd) != spacer {
  11206. break
  11207. }
  11208. }
  11209. for true {
  11210. if int32(prg.curCmd) > otherChar || int32(prg.curChr) > 255 {
  11211. prg.backInput()
  11212. goto done
  11213. }
  11214. if !prg.moreName(asciiCode(prg.curChr)) {
  11215. goto done
  11216. }
  11217. prg.getXToken()
  11218. }
  11219. done:
  11220. prg.endName()
  11221. prg.nameInProgress = false
  11222. }
  11223. // 529.
  11224. // tangle:pos tex.web:10243:1:
  11225. // Here is a routine that manufactures the output file names, assuming that
  11226. // |job_name<>0|. It ignores and changes the current settings of |cur_area|
  11227. // and |cur_ext|.
  11228. func (prg *prg) packJobName(s strNumber) {
  11229. prg.curArea = /* "" */ 338
  11230. prg.curExt = s
  11231. prg.curName = prg.jobName
  11232. prg.packFileName(prg.curName, prg.curArea, prg.curExt)
  11233. }
  11234. // 530.
  11235. // tangle:pos tex.web:10255:1:
  11236. // If some trouble arises when \TeX\ tries to open a file, the following
  11237. // routine calls upon the user to supply another file name. Parameter~|s|
  11238. // is used in the error message to identify the type of file; parameter~|e|
  11239. // is the default extension if none is given. Upon exit from the routine,
  11240. // variables |cur_name|, |cur_area|, |cur_ext|, and |name_of_file| are
  11241. // ready for another attempt at file opening.
  11242. func (prg *prg) promptFileName(s, e strNumber) {
  11243. var (
  11244. k /* 0..bufSize */ uint16 // index into |buffer|
  11245. )
  11246. if int32(prg.interaction) == scrollMode {
  11247. }
  11248. if int32(s) == 787 {
  11249. if int32(prg.interaction) == errorStopMode {
  11250. }
  11251. prg.printNl(strNumber( /* "! " */ 262))
  11252. prg.print( /* "I can't find file `" */ 788)
  11253. } else {
  11254. if int32(prg.interaction) == errorStopMode {
  11255. }
  11256. prg.printNl(strNumber( /* "! " */ 262))
  11257. prg.print( /* "I can't write on file `" */ 789)
  11258. }
  11259. // \xref[I can't write on file x]
  11260. prg.printFileName(int32(prg.curName), int32(prg.curArea), int32(prg.curExt))
  11261. prg.print( /* "'." */ 790)
  11262. if int32(e) == 791 {
  11263. prg.showContext()
  11264. }
  11265. prg.printNl(strNumber( /* "Please type another " */ 792))
  11266. prg.print(int32(s))
  11267. // \xref[Please type...]
  11268. if int32(prg.interaction) < scrollMode {
  11269. prg.fatalError(strNumber( /* "*** (job aborted, file error in nonstop mode)" */ 793))
  11270. }
  11271. // \xref[job aborted, file error...]
  11272. {
  11273. prg.print( /* ": " */ 568)
  11274. prg.termInput()
  11275. }
  11276. // Scan file name in the buffer
  11277. {
  11278. prg.beginName()
  11279. k = prg.first
  11280. for int32(prg.buffer[k]) == ' ' && int32(k) < int32(prg.last) {
  11281. k = uint16(int32(k) + 1)
  11282. }
  11283. for true {
  11284. if int32(k) == int32(prg.last) {
  11285. goto done
  11286. }
  11287. if !prg.moreName(prg.buffer[k]) {
  11288. goto done
  11289. }
  11290. k = uint16(int32(k) + 1)
  11291. }
  11292. done:
  11293. prg.endName()
  11294. }
  11295. if int32(prg.curExt) == 338 {
  11296. prg.curExt = e
  11297. }
  11298. prg.packFileName(prg.curName, prg.curArea, prg.curExt)
  11299. } // \2
  11300. func (prg *prg) openLogFile() {
  11301. var (
  11302. oldSetting/* 0..maxSelector */ byte // previous |selector| setting
  11303. k/* 0..bufSize */ uint16 // index into |months| and |buffer|
  11304. l/* 0..bufSize */ uint16 // end of first input line
  11305. months [36]char // abbreviations of month names
  11306. )
  11307. oldSetting = prg.selector
  11308. if int32(prg.jobName) == 0 {
  11309. prg.jobName = /* "texput" */ 796
  11310. }
  11311. // \xref[texput]
  11312. prg.packJobName(strNumber( /* ".log" */ 797))
  11313. for !prg.aOpenOut(prg.logFile) {
  11314. // Try to get a different log file name
  11315. prg.selector = byte(termOnly)
  11316. prg.promptFileName(strNumber( /* "transcript file name" */ 799), strNumber( /* ".log" */ 797))
  11317. }
  11318. prg.logName = prg.aMakeNameString(prg.logFile)
  11319. prg.selector = byte(logOnly)
  11320. prg.logOpened = true
  11321. // Print the banner line, including the date and time
  11322. {
  11323. prg.logFile.Write("This is TeX, Version 3.141592653 (gotex v0.0-prerelease)")
  11324. prg.slowPrint(int32(prg.formatIdent))
  11325. prg.print( /* " " */ 800)
  11326. prg.printInt(prg.sysDay)
  11327. prg.printChar(asciiCode(' '))
  11328. strcopy(months[:], "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC")
  11329. for ii := 3*prg.sysMonth - 2; ii <= 3*prg.sysMonth; ii++ {
  11330. k = uint16(ii)
  11331. _ = k
  11332. prg.logFile.Write(string(rune(months[k-1])))
  11333. }
  11334. prg.printChar(asciiCode(' '))
  11335. prg.printInt(prg.sysYear)
  11336. prg.printChar(asciiCode(' '))
  11337. prg.printTwo(prg.sysTime / 60)
  11338. prg.printChar(asciiCode(':'))
  11339. prg.printTwo(prg.sysTime % 60)
  11340. }
  11341. prg.inputStack[prg.inputPtr] = prg.curInput // make sure bottom level is in memory
  11342. prg.printNl(strNumber( /* "**" */ 798))
  11343. // \xref[**]
  11344. l = prg.inputStack[0].limitField // last position of first line
  11345. if int32(prg.buffer[l]) == *prg.eqtb[intBase+endLineCharCode-1].int() {
  11346. l = uint16(int32(l) - 1)
  11347. }
  11348. for ii := int32(1); ii <= int32(l); ii++ {
  11349. k = uint16(ii)
  11350. _ = k
  11351. prg.print(int32(prg.buffer[k]))
  11352. }
  11353. prg.printLn() // now the transcript file contains the first line of input
  11354. prg.selector = byte(int32(oldSetting) + 2) // |log_only| or |term_and_log|
  11355. } // \2
  11356. func (prg *prg) startInput() {
  11357. prg.scanFileName() // set |cur_name| to desired file name
  11358. if int32(prg.curExt) == 338 {
  11359. prg.curExt = /* ".tex" */ 791
  11360. }
  11361. prg.packFileName(prg.curName, prg.curArea, prg.curExt)
  11362. for true {
  11363. prg.beginFileReading() // set up |cur_file| and new level of input
  11364. if prg.aOpenIn(prg.inputFile[prg.curInput.indexField-1]) {
  11365. goto done
  11366. }
  11367. if int32(prg.curArea) == 338 {
  11368. prg.packFileName(prg.curName, strNumber( /* "TeXinputs:" */ 784), prg.curExt)
  11369. if prg.aOpenIn(prg.inputFile[prg.curInput.indexField-1]) {
  11370. goto done
  11371. }
  11372. }
  11373. prg.endFileReading() // remove the level that didn't work
  11374. prg.promptFileName(strNumber( /* "input file name" */ 787), strNumber( /* ".tex" */ 791))
  11375. }
  11376. done:
  11377. prg.curInput.nameField = prg.aMakeNameString(prg.inputFile[prg.curInput.indexField-1])
  11378. if int32(prg.jobName) == 0 {
  11379. prg.jobName = prg.curName
  11380. prg.openLogFile()
  11381. } // |open_log_file| doesn't |show_context|, so |limit|
  11382. // and |loc| needn't be set to meaningful values yet
  11383. if int32(prg.termOffset)+(int32(prg.strStart[int32(prg.curInput.nameField)+1])-int32(prg.strStart[prg.curInput.nameField])) > maxPrintLine-2 {
  11384. prg.printLn()
  11385. } else if int32(prg.termOffset) > 0 || int32(prg.fileOffset) > 0 {
  11386. prg.printChar(asciiCode(' '))
  11387. }
  11388. prg.printChar(asciiCode('('))
  11389. prg.openParens = byte(int32(prg.openParens) + 1)
  11390. prg.slowPrint(int32(prg.curInput.nameField))
  11391. prg.curInput.stateField = byte(newLine)
  11392. if int32(prg.curInput.nameField) == int32(prg.strPtr)-1 {
  11393. {
  11394. prg.strPtr = uint16(int32(prg.strPtr) - 1)
  11395. prg.poolPtr = prg.strStart[prg.strPtr]
  11396. }
  11397. prg.curInput.nameField = prg.curName
  11398. }
  11399. // Read the first line of the new file
  11400. {
  11401. prg.line = 1
  11402. if prg.inputLn(prg.inputFile[prg.curInput.indexField-1], false) {
  11403. }
  11404. prg.firmUpTheLine()
  11405. if *prg.eqtb[intBase+endLineCharCode-1].int() < 0 || *prg.eqtb[intBase+endLineCharCode-1].int() > 255 {
  11406. prg.curInput.limitField = uint16(int32(prg.curInput.limitField) - 1)
  11407. } else {
  11408. prg.buffer[prg.curInput.limitField] = byte(*prg.eqtb[intBase+endLineCharCode-1].int())
  11409. }
  11410. prg.first = uint16(int32(prg.curInput.limitField) + 1)
  11411. prg.curInput.locField = prg.curInput.startField
  11412. }
  11413. }
  11414. // 540.
  11415. // tangle:pos tex.web:10433:1:
  11416. // The first 24 bytes (6 words) of a \.[TFM] file contain twelve 16-bit
  11417. // integers that give the lengths of the various subsequent portions
  11418. // of the file. These twelve integers are, in order:
  11419. // $$\vbox[\halign[\hfil#&$\null=\null$#\hfil\cr
  11420. // |lf|&length of the entire file, in words;\cr
  11421. // |lh|&length of the header data, in words;\cr
  11422. // |bc|&smallest character code in the font;\cr
  11423. // |ec|&largest character code in the font;\cr
  11424. // |nw|&number of words in the width table;\cr
  11425. // |nh|&number of words in the height table;\cr
  11426. // |nd|&number of words in the depth table;\cr
  11427. // |ni|&number of words in the italic correction table;\cr
  11428. // |nl|&number of words in the lig/kern table;\cr
  11429. // |nk|&number of words in the kern table;\cr
  11430. // |ne|&number of words in the extensible character table;\cr
  11431. // |np|&number of font parameter words.\cr]]$$
  11432. // They are all nonnegative and less than $2^[15]$. We must have |bc-1<=ec<=255|,
  11433. // and
  11434. // $$\hbox[|lf=6+lh+(ec-bc+1)+nw+nh+nd+ni+nl+nk+ne+np|.]$$
  11435. // Note that a font may contain as many as 256 characters (if |bc=0| and |ec=255|),
  11436. // and as few as 0 characters (if |bc=ec+1|).
  11437. //
  11438. // Incidentally, when two or more 8-bit bytes are combined to form an integer of
  11439. // 16 or more bits, the most significant bytes appear first in the file.
  11440. // This is called BigEndian order.
  11441. // \xref[BigEndian order]
  11442. // 541.
  11443. // tangle:pos tex.web:10460:1:
  11444. // The rest of the \.[TFM] file may be regarded as a sequence of ten data
  11445. // arrays having the informal specification
  11446. // $$\def\arr$[#1]#2$[\&[array] $[#1]$ \&[of] #2]
  11447. // \vbox[\halign[\hfil\\[#]&$\,:\,$\arr#\hfil\cr
  11448. // header&|[0..lh-1]\\[stuff]|\cr
  11449. // char\_info&|[bc..ec]char_info_word|\cr
  11450. // width&|[0..nw-1]fix_word|\cr
  11451. // height&|[0..nh-1]fix_word|\cr
  11452. // depth&|[0..nd-1]fix_word|\cr
  11453. // italic&|[0..ni-1]fix_word|\cr
  11454. // lig\_kern&|[0..nl-1]lig_kern_command|\cr
  11455. // kern&|[0..nk-1]fix_word|\cr
  11456. // exten&|[0..ne-1]extensible_recipe|\cr
  11457. // param&|[1..np]fix_word|\cr]]$$
  11458. // The most important data type used here is a | fix_word|, which is
  11459. // a 32-bit representation of a binary fraction. A |fix_word| is a signed
  11460. // quantity, with the two's complement of the entire word used to represent
  11461. // negation. Of the 32 bits in a |fix_word|, exactly 12 are to the left of the
  11462. // binary point; thus, the largest |fix_word| value is $2048-2^[-20]$, and
  11463. // the smallest is $-2048$. We will see below, however, that all but two of
  11464. // the |fix_word| values must lie between $-16$ and $+16$.
  11465. // 542.
  11466. // tangle:pos tex.web:10482:1:
  11467. // The first data array is a block of header information, which contains
  11468. // general facts about the font. The header must contain at least two words,
  11469. // |header[0]| and |header[1]|, whose meaning is explained below.
  11470. // Additional header information of use to other software routines might
  11471. // also be included, but \TeX82 does not need to know about such details.
  11472. // For example, 16 more words of header information are in use at the Xerox
  11473. // Palo Alto Research Center; the first ten specify the character coding
  11474. // scheme used (e.g., `\.[XEROX text]' or `\.[TeX math symbols]'), the next five
  11475. // give the font identifier (e.g., `\.[HELVETICA]' or `\.[CMSY]'), and the
  11476. // last gives the ``face byte.'' The program that converts \.[DVI] files
  11477. // to Xerox printing format gets this information by looking at the \.[TFM]
  11478. // file, which it needs to read anyway because of other information that
  11479. // is not explicitly repeated in \.[DVI]~format.
  11480. //
  11481. // \yskip\hang|header[0]| is a 32-bit check sum that \TeX\ will copy into
  11482. // the \.[DVI] output file. Later on when the \.[DVI] file is printed,
  11483. // possibly on another computer, the actual font that gets used is supposed
  11484. // to have a check sum that agrees with the one in the \.[TFM] file used by
  11485. // \TeX. In this way, users will be warned about potential incompatibilities.
  11486. // (However, if the check sum is zero in either the font file or the \.[TFM]
  11487. // file, no check is made.) The actual relation between this check sum and
  11488. // the rest of the \.[TFM] file is not important; the check sum is simply an
  11489. // identification number with the property that incompatible fonts almost
  11490. // always have distinct check sums.
  11491. // \xref[check sum]
  11492. //
  11493. // \yskip\hang|header[1]| is a |fix_word| containing the design size of
  11494. // the font, in units of \TeX\ points. This number must be at least 1.0; it is
  11495. // fairly arbitrary, but usually the design size is 10.0 for a ``10 point''
  11496. // font, i.e., a font that was designed to look best at a 10-point size,
  11497. // whatever that really means. When a \TeX\ user asks for a font
  11498. // `\.[at] $\delta$ \.[pt]', the effect is to override the design size
  11499. // and replace it by $\delta$, and to multiply the $x$ and~$y$ coordinates
  11500. // of the points in the font image by a factor of $\delta$ divided by the
  11501. // design size. [\sl All other dimensions in the\/ \.[TFM] file are
  11502. // |fix_word|\kern-1pt\ numbers in design-size units], with the exception of
  11503. // |param[1]| (which denotes the slant ratio). Thus, for example, the value
  11504. // of |param[6]|, which defines the \.[em] unit, is often the |fix_word| value
  11505. // $2^[20]=1.0$, since many fonts have a design size equal to one em.
  11506. // The other dimensions must be less than 16 design-size units in absolute
  11507. // value; thus, |header[1]| and |param[1]| are the only |fix_word|
  11508. // entries in the whole \.[TFM] file whose first byte might be something
  11509. // besides 0 or 255.
  11510. // 543.
  11511. // tangle:pos tex.web:10526:1:
  11512. // Next comes the |char_info| array, which contains one | char_info_word|
  11513. // per character. Each word in this part of the file contains six fields
  11514. // packed into four bytes as follows.
  11515. //
  11516. // \yskip\hang first byte: | width_index| (8 bits)\par
  11517. // \hang second byte: | height_index| (4 bits) times 16, plus | depth_index|
  11518. // (4~bits)\par
  11519. // \hang third byte: | italic_index| (6 bits) times 4, plus | tag|
  11520. // (2~bits)\par
  11521. // \hang fourth byte: | remainder| (8 bits)\par
  11522. // \yskip\noindent
  11523. // The actual width of a character is \\[width]|[width_index]|, in design-size
  11524. // units; this is a device for compressing information, since many characters
  11525. // have the same width. Since it is quite common for many characters
  11526. // to have the same height, depth, or italic correction, the \.[TFM] format
  11527. // imposes a limit of 16 different heights, 16 different depths, and
  11528. // 64 different italic corrections.
  11529. //
  11530. // \xref[italic correction]
  11531. // The italic correction of a character has two different uses.
  11532. // (a)~In ordinary text, the italic correction is added to the width only if
  11533. // the \TeX\ user specifies `\.[\\/]' after the character.
  11534. // (b)~In math formulas, the italic correction is always added to the width,
  11535. // except with respect to the positioning of subscripts.
  11536. //
  11537. // Incidentally, the relation $\\[width][0]=\\[height][0]=\\[depth][0]=
  11538. // \\[italic][0]=0$ should always hold, so that an index of zero implies a
  11539. // value of zero. The |width_index| should never be zero unless the
  11540. // character does not exist in the font, since a character is valid if and
  11541. // only if it lies between |bc| and |ec| and has a nonzero |width_index|.
  11542. // 544.
  11543. // tangle:pos tex.web:10557:1:
  11544. // The |tag| field in a |char_info_word| has four values that explain how to
  11545. // interpret the |remainder| field.
  11546. //
  11547. // \yskip\hangg|tag=0| (|no_tag|) means that |remainder| is unused.\par
  11548. // \hangg|tag=1| (|lig_tag|) means that this character has a ligature/kerning
  11549. // program starting at position |remainder| in the |lig_kern| array.\par
  11550. // \hangg|tag=2| (|list_tag|) means that this character is part of a chain of
  11551. // characters of ascending sizes, and not the largest in the chain. The
  11552. // |remainder| field gives the character code of the next larger character.\par
  11553. // \hangg|tag=3| (|ext_tag|) means that this character code represents an
  11554. // extensible character, i.e., a character that is built up of smaller pieces
  11555. // so that it can be made arbitrarily large. The pieces are specified in
  11556. // | exten[remainder]|.\par
  11557. // \yskip\noindent
  11558. // Characters with |tag=2| and |tag=3| are treated as characters with |tag=0|
  11559. // unless they are used in special circumstances in math formulas. For example,
  11560. // the \.[\\sum] operation looks for a |list_tag|, and the \.[\\left]
  11561. // operation looks for both |list_tag| and |ext_tag|.
  11562. // 545.
  11563. // tangle:pos tex.web:10581:1:
  11564. // The |lig_kern| array contains instructions in a simple programming language
  11565. // that explains what to do for special letter pairs. Each word in this array is a
  11566. // | lig_kern_command| of four bytes.
  11567. //
  11568. // \yskip\hang first byte: |skip_byte|, indicates that this is the final program
  11569. // step if the byte is 128 or more, otherwise the next step is obtained by
  11570. // skipping this number of intervening steps.\par
  11571. // \hang second byte: |next_char|, ``if |next_char| follows the current character,
  11572. // then perform the operation and stop, otherwise continue.''\par
  11573. // \hang third byte: |op_byte|, indicates a ligature step if less than~128,
  11574. // a kern step otherwise.\par
  11575. // \hang fourth byte: |remainder|.\par
  11576. // \yskip\noindent
  11577. // In a kern step, an
  11578. // additional space equal to |kern[256*(op_byte-128)+remainder]| is inserted
  11579. // between the current character and |next_char|. This amount is
  11580. // often negative, so that the characters are brought closer together
  11581. // by kerning; but it might be positive.
  11582. //
  11583. // There are eight kinds of ligature steps, having |op_byte| codes $4a+2b+c$ where
  11584. // $0\le a\le b+c$ and $0\le b,c\le1$. The character whose code is
  11585. // |remainder| is inserted between the current character and |next_char|;
  11586. // then the current character is deleted if $b=0$, and |next_char| is
  11587. // deleted if $c=0$; then we pass over $a$~characters to reach the next
  11588. // current character (which may have a ligature/kerning program of its own).
  11589. //
  11590. // If the very first instruction of the |lig_kern| array has |skip_byte=255|,
  11591. // the |next_char| byte is the so-called boundary character of this font;
  11592. // the value of |next_char| need not lie between |bc| and~|ec|.
  11593. // If the very last instruction of the |lig_kern| array has |skip_byte=255|,
  11594. // there is a special ligature/kerning program for a boundary character at the
  11595. // left, beginning at location |256*op_byte+remainder|.
  11596. // The interpretation is that \TeX\ puts implicit boundary characters
  11597. // before and after each consecutive string of characters from the same font.
  11598. // These implicit characters do not appear in the output, but they can affect
  11599. // ligatures and kerning.
  11600. //
  11601. // If the very first instruction of a character's |lig_kern| program has
  11602. // |skip_byte>128|, the program actually begins in location
  11603. // |256*op_byte+remainder|. This feature allows access to large |lig_kern|
  11604. // arrays, because the first instruction must otherwise
  11605. // appear in a location |<=255|.
  11606. //
  11607. // Any instruction with |skip_byte>128| in the |lig_kern| array must satisfy
  11608. // the condition
  11609. // $$\hbox[|256*op_byte+remainder<nl|.]$$
  11610. // If such an instruction is encountered during
  11611. // normal program execution, it denotes an unconditional halt; no ligature
  11612. // or kerning command is performed.
  11613. // 546.
  11614. // tangle:pos tex.web:10638:1:
  11615. // Extensible characters are specified by an | extensible_recipe|, which
  11616. // consists of four bytes called | top|, | mid|, | bot|, and | rep| (in this
  11617. // order). These bytes are the character codes of individual pieces used to
  11618. // build up a large symbol. If |top|, |mid|, or |bot| are zero, they are not
  11619. // present in the built-up result. For example, an extensible vertical line is
  11620. // like an extensible bracket, except that the top and bottom pieces are missing.
  11621. //
  11622. // Let $T$, $M$, $B$, and $R$ denote the respective pieces, or an empty box
  11623. // if the piece isn't present. Then the extensible characters have the form
  11624. // $TR^kMR^kB$ from top to bottom, for some |k>=0|, unless $M$ is absent;
  11625. // in the latter case we can have $TR^kB$ for both even and odd values of~|k|.
  11626. // The width of the extensible character is the width of $R$; and the
  11627. // height-plus-depth is the sum of the individual height-plus-depths of the
  11628. // components used, since the pieces are butted together in a vertical list.
  11629. // 547.
  11630. // tangle:pos tex.web:10658:1:
  11631. // The final portion of a \.[TFM] file is the |param| array, which is another
  11632. // sequence of |fix_word| values.
  11633. //
  11634. // \yskip\hang|param[1]=slant| is the amount of italic slant, which is used
  11635. // to help position accents. For example, |slant=.25| means that when you go
  11636. // up one unit, you also go .25 units to the right. The |slant| is a pure
  11637. // number; it's the only |fix_word| other than the design size itself that is
  11638. // not scaled by the design size.
  11639. //
  11640. // \hang|param[2]=space| is the normal spacing between words in text.
  11641. // Note that character |" "| in the font need not have anything to do with
  11642. // blank spaces.
  11643. //
  11644. // \hang|param[3]=space_stretch| is the amount of glue stretching between words.
  11645. //
  11646. // \hang|param[4]=space_shrink| is the amount of glue shrinking between words.
  11647. //
  11648. // \hang|param[5]=x_height| is the size of one ex in the font; it is also
  11649. // the height of letters for which accents don't have to be raised or lowered.
  11650. //
  11651. // \hang|param[6]=quad| is the size of one em in the font.
  11652. //
  11653. // \hang|param[7]=extra_space| is the amount added to |param[2]| at the
  11654. // ends of sentences.
  11655. //
  11656. // \yskip\noindent
  11657. // If fewer than seven parameters are present, \TeX\ sets the missing parameters
  11658. // to zero. Fonts used for math symbols are required to have
  11659. // additional parameter information, which is explained later.
  11660. // 554.
  11661. // tangle:pos tex.web:10804:1:
  11662. // Of course we want to define macros that suppress the detail of how font
  11663. // information is actually packed, so that we don't have to write things like
  11664. // $$\hbox[|font_info[width_base[f]+font_info[char_base[f]+c].qqqq.b0].sc|]$$
  11665. // too often. The \.[WEB] definitions here make |char_info(f)(c)| the
  11666. // |four_quarters| word of font information corresponding to character
  11667. // |c| of font |f|. If |q| is such a word, |char_width(f)(q)| will be
  11668. // the character's width; hence the long formula above is at least
  11669. // abbreviated to
  11670. // $$\hbox[|char_width(f)(char_info(f)(c))|.]$$
  11671. // Usually, of course, we will fetch |q| first and look at several of its
  11672. // fields at the same time.
  11673. //
  11674. // The italic correction of a character will be denoted by
  11675. // |char_italic(f)(q)|, so it is analogous to |char_width|. But we will get
  11676. // at the height and depth in a slightly different way, since we usually want
  11677. // to compute both height and depth if we want either one. The value of
  11678. // |height_depth(q)| will be the 8-bit quantity
  11679. // $$b=|height_index|\times16+|depth_index|,$$ and if |b| is such a byte we
  11680. // will write |char_height(f)(b)| and |char_depth(f)(b)| for the height and
  11681. // depth of the character |c| for which |q=char_info(f)(c)|. Got that?
  11682. //
  11683. // The tag field will be called |char_tag(q)|; the remainder byte will be
  11684. // called |rem_byte(q)|, using a macro that we have already defined above.
  11685. //
  11686. // Access to a character's |width|, |height|, |depth|, and |tag| fields is
  11687. // part of \TeX's inner loop, so we want these macros to produce code that is
  11688. // as fast as possible under the circumstances.
  11689. // \xref[inner loop]
  11690. // 557.
  11691. // tangle:pos tex.web:10858:1:
  11692. // Here are some macros that help process ligatures and kerns.
  11693. // We write |char_kern(f)(j)| to find the amount of kerning specified by
  11694. // kerning command~|j| in font~|f|. If |j| is the |char_info| for a character
  11695. // with a ligature/kern program, the first instruction of that program is either
  11696. // |i=font_info[lig_kern_start(f)(j)]| or |font_info[lig_kern_restart(f)(i)]|,
  11697. // depending on whether or not |skip_byte(i)<=stop_flag|.
  11698. //
  11699. // The constant |kern_base_offset| should be simplified, for \PASCAL\ compilers
  11700. // that do not do local optimization.
  11701. // \xref[system dependencies]
  11702. // 560.
  11703. // tangle:pos tex.web:10892:1:
  11704. // \TeX\ checks the information of a \.[TFM] file for validity as the
  11705. // file is being read in, so that no further checks will be needed when
  11706. // typesetting is going on. The somewhat tedious subroutine that does this
  11707. // is called |read_font_info|. It has four parameters: the user font
  11708. // identifier~|u|, the file name and area strings |nom| and |aire|, and the
  11709. // “at” size~|s|. If |s|~is negative, it's the negative of a scale factor
  11710. // to be applied to the design size; |s=-1000| is the normal case.
  11711. // Otherwise |s| will be substituted for the design size; in this
  11712. // case, |s| must be positive and less than $2048\rm\,pt$
  11713. // (i.e., it must be less than $2^[27]$ when considered as an integer).
  11714. //
  11715. // The subroutine opens and closes a global file variable called |tfm_file|.
  11716. // It returns the value of the internal font number that was just loaded.
  11717. // If an error is detected, an error message is issued and no font
  11718. // information is stored; |null_font| is returned in this case.
  11719. func (prg *prg) readFontInfo(u halfword, nom, aire strNumber,
  11720. s scaled) (r internalFontNumber) {
  11721. var (
  11722. k fontIndex // index into |font_info|
  11723. fileOpened bool // was |tfm_file| successfully opened?
  11724. lf, lh, bc, ec, nw, nh, nd, ni, nl, nk, ne, np halfword
  11725. // sizes of subfiles
  11726. f internalFontNumber // the new font's number
  11727. g internalFontNumber // the number to return
  11728. a, b, c, d eightBits // byte variables
  11729. qw fourQuarters
  11730. sw scaled // accumulators
  11731. bchLabel int32 // left boundary start location, or infinity
  11732. bchar/* 0..256 */ uint16 // boundary character, or 256
  11733. z scaled // the design size or the ``at'' size
  11734. alpha int32
  11735. beta/* 1..16 */ byte
  11736. // auxiliary quantities used in fixed-point multiplication
  11737. )
  11738. g = byte(fontBase)
  11739. // Read and check the font data; |abort| if the \.[TFM] file is malformed; if there's no room for this font, say so and |goto done|; otherwise |incr(font_ptr)| and |goto done|
  11740. // Open |tfm_file| for input
  11741. fileOpened = false
  11742. if int32(aire) == 338 {
  11743. prg.packFileName(nom, strNumber( /* "TeXfonts:" */ 785), strNumber( /* ".tfm" */ 811))
  11744. } else {
  11745. prg.packFileName(nom, aire, strNumber( /* ".tfm" */ 811))
  11746. }
  11747. if !prg.bOpenIn(prg.tfmFile) {
  11748. goto badTfm
  11749. }
  11750. fileOpened = true
  11751. // Read the [\.[TFM]] size fields
  11752. {
  11753. {
  11754. lf = uint16(*prg.tfmFile.ByteP())
  11755. if int32(lf) > 127 {
  11756. goto badTfm
  11757. }
  11758. prg.tfmFile.Get()
  11759. lf = uint16(int32(lf)*0400 + int32(*prg.tfmFile.ByteP()))
  11760. }
  11761. prg.tfmFile.Get()
  11762. {
  11763. lh = uint16(*prg.tfmFile.ByteP())
  11764. if int32(lh) > 127 {
  11765. goto badTfm
  11766. }
  11767. prg.tfmFile.Get()
  11768. lh = uint16(int32(lh)*0400 + int32(*prg.tfmFile.ByteP()))
  11769. }
  11770. prg.tfmFile.Get()
  11771. {
  11772. bc = uint16(*prg.tfmFile.ByteP())
  11773. if int32(bc) > 127 {
  11774. goto badTfm
  11775. }
  11776. prg.tfmFile.Get()
  11777. bc = uint16(int32(bc)*0400 + int32(*prg.tfmFile.ByteP()))
  11778. }
  11779. prg.tfmFile.Get()
  11780. {
  11781. ec = uint16(*prg.tfmFile.ByteP())
  11782. if int32(ec) > 127 {
  11783. goto badTfm
  11784. }
  11785. prg.tfmFile.Get()
  11786. ec = uint16(int32(ec)*0400 + int32(*prg.tfmFile.ByteP()))
  11787. }
  11788. if int32(bc) > int32(ec)+1 || int32(ec) > 255 {
  11789. goto badTfm
  11790. }
  11791. if int32(bc) > 255 {
  11792. bc = 1
  11793. ec = 0
  11794. }
  11795. prg.tfmFile.Get()
  11796. {
  11797. nw = uint16(*prg.tfmFile.ByteP())
  11798. if int32(nw) > 127 {
  11799. goto badTfm
  11800. }
  11801. prg.tfmFile.Get()
  11802. nw = uint16(int32(nw)*0400 + int32(*prg.tfmFile.ByteP()))
  11803. }
  11804. prg.tfmFile.Get()
  11805. {
  11806. nh = uint16(*prg.tfmFile.ByteP())
  11807. if int32(nh) > 127 {
  11808. goto badTfm
  11809. }
  11810. prg.tfmFile.Get()
  11811. nh = uint16(int32(nh)*0400 + int32(*prg.tfmFile.ByteP()))
  11812. }
  11813. prg.tfmFile.Get()
  11814. {
  11815. nd = uint16(*prg.tfmFile.ByteP())
  11816. if int32(nd) > 127 {
  11817. goto badTfm
  11818. }
  11819. prg.tfmFile.Get()
  11820. nd = uint16(int32(nd)*0400 + int32(*prg.tfmFile.ByteP()))
  11821. }
  11822. prg.tfmFile.Get()
  11823. {
  11824. ni = uint16(*prg.tfmFile.ByteP())
  11825. if int32(ni) > 127 {
  11826. goto badTfm
  11827. }
  11828. prg.tfmFile.Get()
  11829. ni = uint16(int32(ni)*0400 + int32(*prg.tfmFile.ByteP()))
  11830. }
  11831. prg.tfmFile.Get()
  11832. {
  11833. nl = uint16(*prg.tfmFile.ByteP())
  11834. if int32(nl) > 127 {
  11835. goto badTfm
  11836. }
  11837. prg.tfmFile.Get()
  11838. nl = uint16(int32(nl)*0400 + int32(*prg.tfmFile.ByteP()))
  11839. }
  11840. prg.tfmFile.Get()
  11841. {
  11842. nk = uint16(*prg.tfmFile.ByteP())
  11843. if int32(nk) > 127 {
  11844. goto badTfm
  11845. }
  11846. prg.tfmFile.Get()
  11847. nk = uint16(int32(nk)*0400 + int32(*prg.tfmFile.ByteP()))
  11848. }
  11849. prg.tfmFile.Get()
  11850. {
  11851. ne = uint16(*prg.tfmFile.ByteP())
  11852. if int32(ne) > 127 {
  11853. goto badTfm
  11854. }
  11855. prg.tfmFile.Get()
  11856. ne = uint16(int32(ne)*0400 + int32(*prg.tfmFile.ByteP()))
  11857. }
  11858. prg.tfmFile.Get()
  11859. {
  11860. np = uint16(*prg.tfmFile.ByteP())
  11861. if int32(np) > 127 {
  11862. goto badTfm
  11863. }
  11864. prg.tfmFile.Get()
  11865. np = uint16(int32(np)*0400 + int32(*prg.tfmFile.ByteP()))
  11866. }
  11867. if int32(lf) != 6+int32(lh)+(int32(ec)-int32(bc)+1)+int32(nw)+int32(nh)+int32(nd)+int32(ni)+int32(nl)+int32(nk)+int32(ne)+int32(np) {
  11868. goto badTfm
  11869. }
  11870. if int32(nw) == 0 || int32(nh) == 0 || int32(nd) == 0 || int32(ni) == 0 {
  11871. goto badTfm
  11872. }
  11873. }
  11874. // Use size fields to allocate font information
  11875. lf = uint16(int32(lf) - 6 - int32(lh)) // |lf| words should be loaded into |font_info|
  11876. if int32(np) < 7 {
  11877. lf = uint16(int32(lf) + 7 - int32(np))
  11878. } // at least seven parameters will appear
  11879. if int32(prg.fontPtr) == fontMax || int32(prg.fmemPtr)+int32(lf) > fontMemSize {
  11880. {
  11881. if int32(prg.interaction) == errorStopMode {
  11882. }
  11883. prg.printNl(strNumber( /* "! " */ 262))
  11884. prg.print( /* "Font " */ 802)
  11885. }
  11886. prg.sprintCs(u)
  11887. prg.printChar(asciiCode('='))
  11888. prg.printFileName(int32(nom), int32(aire) /* "" */, 338)
  11889. if s >= 0 {
  11890. prg.print( /* " at " */ 741)
  11891. prg.printScaled(s)
  11892. prg.print( /* "pt" */ 397)
  11893. } else if s != -1000 {
  11894. prg.print( /* " scaled " */ 803)
  11895. prg.printInt(-s)
  11896. }
  11897. prg.print( /* " not loaded: Not enough room left" */ 812)
  11898. // \xref[Font x=xx not loaded...]
  11899. {
  11900. prg.helpPtr = 4
  11901. prg.helpLine[3] = /* "I'm afraid I won't be able to make use of this font," */ 813
  11902. prg.helpLine[2] = /* "because my memory for character-size data is too small." */ 814
  11903. prg.helpLine[1] = /* "If you're really stuck, ask a wizard to enlarge me." */ 815
  11904. prg.helpLine[0] = /* "Or maybe try `I\\font<same font id>=<name of loaded font>'." */ 816
  11905. }
  11906. prg.error1()
  11907. goto done
  11908. }
  11909. f = byte(int32(prg.fontPtr) + 1)
  11910. prg.charBase[f] = int32(prg.fmemPtr) - int32(bc)
  11911. prg.widthBase[f] = prg.charBase[f] + int32(ec) + 1
  11912. prg.heightBase[f] = prg.widthBase[f] + int32(nw)
  11913. prg.depthBase[f] = prg.heightBase[f] + int32(nh)
  11914. prg.italicBase[f] = prg.depthBase[f] + int32(nd)
  11915. prg.ligKernBase[f] = prg.italicBase[f] + int32(ni)
  11916. prg.kernBase[f] = prg.ligKernBase[f] + int32(nl) - 256*(128+minQuarterword)
  11917. prg.extenBase[f] = prg.kernBase[f] + 256*(128+minQuarterword) + int32(nk)
  11918. prg.paramBase[f] = prg.extenBase[f] + int32(ne)
  11919. // Read the [\.[TFM]] header
  11920. {
  11921. if int32(lh) < 2 {
  11922. goto badTfm
  11923. }
  11924. {
  11925. prg.tfmFile.Get()
  11926. a = *prg.tfmFile.ByteP()
  11927. qw.b0 = byte(int32(a) + minQuarterword)
  11928. prg.tfmFile.Get()
  11929. b = *prg.tfmFile.ByteP()
  11930. qw.b1 = byte(int32(b) + minQuarterword)
  11931. prg.tfmFile.Get()
  11932. c = *prg.tfmFile.ByteP()
  11933. qw.b2 = byte(int32(c) + minQuarterword)
  11934. prg.tfmFile.Get()
  11935. d = *prg.tfmFile.ByteP()
  11936. qw.b3 = byte(int32(d) + minQuarterword)
  11937. prg.fontCheck[f] = qw
  11938. }
  11939. prg.tfmFile.Get()
  11940. {
  11941. z = int32(*prg.tfmFile.ByteP())
  11942. if z > 127 {
  11943. goto badTfm
  11944. }
  11945. prg.tfmFile.Get()
  11946. z = z*0400 + int32(*prg.tfmFile.ByteP())
  11947. } // this rejects a negative design size
  11948. prg.tfmFile.Get()
  11949. z = z*0400 + int32(*prg.tfmFile.ByteP())
  11950. prg.tfmFile.Get()
  11951. z = z*020 + int32(*prg.tfmFile.ByteP())/020
  11952. if z < 0200000 {
  11953. goto badTfm
  11954. }
  11955. for int32(lh) > 2 {
  11956. prg.tfmFile.Get()
  11957. prg.tfmFile.Get()
  11958. prg.tfmFile.Get()
  11959. prg.tfmFile.Get()
  11960. lh = uint16(int32(lh) - 1) // ignore the rest of the header
  11961. }
  11962. prg.fontDsize[f] = z
  11963. if s != -1000 {
  11964. if s >= 0 {
  11965. z = s
  11966. } else {
  11967. z = prg.xnOverD(z, -s, 1000)
  11968. }
  11969. }
  11970. prg.fontSize[f] = z
  11971. }
  11972. // Read character data
  11973. for ii := int32(prg.fmemPtr); ii <= prg.widthBase[f]-1; ii++ {
  11974. k = fontIndex(ii)
  11975. _ = k
  11976. {
  11977. prg.tfmFile.Get()
  11978. a = *prg.tfmFile.ByteP()
  11979. qw.b0 = byte(int32(a) + minQuarterword)
  11980. prg.tfmFile.Get()
  11981. b = *prg.tfmFile.ByteP()
  11982. qw.b1 = byte(int32(b) + minQuarterword)
  11983. prg.tfmFile.Get()
  11984. c = *prg.tfmFile.ByteP()
  11985. qw.b2 = byte(int32(c) + minQuarterword)
  11986. prg.tfmFile.Get()
  11987. d = *prg.tfmFile.ByteP()
  11988. qw.b3 = byte(int32(d) + minQuarterword)
  11989. *prg.fontInfo[k].qqqq() = qw
  11990. }
  11991. if int32(a) >= int32(nw) || int32(b)/020 >= int32(nh) || int32(b)%020 >= int32(nd) || int32(c)/4 >= int32(ni) {
  11992. goto badTfm
  11993. }
  11994. switch int32(c) % 4 {
  11995. case ligTag:
  11996. if int32(d) >= int32(nl) {
  11997. goto badTfm
  11998. }
  11999. case extTag:
  12000. if int32(d) >= int32(ne) {
  12001. goto badTfm
  12002. }
  12003. case listTag:
  12004. // Check for charlist cycle
  12005. {
  12006. if int32(d) < int32(bc) || int32(d) > int32(ec) {
  12007. goto badTfm
  12008. }
  12009. }
  12010. for int32(d) < int32(k)+int32(bc)-int32(prg.fmemPtr) {
  12011. qw = *prg.fontInfo[prg.charBase[f]+int32(d)].qqqq()
  12012. // N.B.: not |qi(d)|, since |char_base[f]| hasn't been adjusted yet
  12013. if (int32(qw.b2)-minQuarterword)%4 != listTag {
  12014. goto notFound
  12015. }
  12016. d = byte(int32(qw.b3) - minQuarterword) // next character on the list
  12017. }
  12018. if int32(d) == int32(k)+int32(bc)-int32(prg.fmemPtr) {
  12019. goto badTfm
  12020. } // yes, there's a cycle
  12021. // yes, there's a cycle
  12022. notFound:
  12023. ;
  12024. default: // |no_tag|
  12025. }
  12026. }
  12027. // Read box dimensions
  12028. {
  12029. {
  12030. alpha = 16
  12031. for z >= 040000000 {
  12032. z = z / 2
  12033. alpha = alpha + alpha
  12034. }
  12035. beta = byte(256 / alpha)
  12036. alpha = alpha * z
  12037. }
  12038. for ii := prg.widthBase[f]; ii <= prg.ligKernBase[f]-1; ii++ {
  12039. k = fontIndex(ii)
  12040. _ = k
  12041. prg.tfmFile.Get()
  12042. a = *prg.tfmFile.ByteP()
  12043. prg.tfmFile.Get()
  12044. b = *prg.tfmFile.ByteP()
  12045. prg.tfmFile.Get()
  12046. c = *prg.tfmFile.ByteP()
  12047. prg.tfmFile.Get()
  12048. d = *prg.tfmFile.ByteP()
  12049. sw = ((int32(d)*z/0400+int32(c)*z)/0400 + int32(b)*z) / int32(beta)
  12050. if int32(a) == 0 {
  12051. *prg.fontInfo[k].int() = sw
  12052. } else if int32(a) == 255 {
  12053. *prg.fontInfo[k].int() = sw - alpha
  12054. } else {
  12055. goto badTfm
  12056. }
  12057. }
  12058. if *prg.fontInfo[prg.widthBase[f]].int() != 0 {
  12059. goto badTfm
  12060. } // \\[width][0] must be zero
  12061. if *prg.fontInfo[prg.heightBase[f]].int() != 0 {
  12062. goto badTfm
  12063. } // \\[height][0] must be zero
  12064. if *prg.fontInfo[prg.depthBase[f]].int() != 0 {
  12065. goto badTfm
  12066. } // \\[depth][0] must be zero
  12067. if *prg.fontInfo[prg.italicBase[f]].int() != 0 {
  12068. goto badTfm
  12069. } // \\[italic][0] must be zero
  12070. }
  12071. // Read ligature/kern program
  12072. bchLabel = 077777
  12073. bchar = 256
  12074. if int32(nl) > 0 {
  12075. for ii := prg.ligKernBase[f]; ii <= prg.kernBase[f]+256*(128+minQuarterword)-1; ii++ {
  12076. k = fontIndex(ii)
  12077. _ = k
  12078. {
  12079. prg.tfmFile.Get()
  12080. a = *prg.tfmFile.ByteP()
  12081. qw.b0 = byte(int32(a) + minQuarterword)
  12082. prg.tfmFile.Get()
  12083. b = *prg.tfmFile.ByteP()
  12084. qw.b1 = byte(int32(b) + minQuarterword)
  12085. prg.tfmFile.Get()
  12086. c = *prg.tfmFile.ByteP()
  12087. qw.b2 = byte(int32(c) + minQuarterword)
  12088. prg.tfmFile.Get()
  12089. d = *prg.tfmFile.ByteP()
  12090. qw.b3 = byte(int32(d) + minQuarterword)
  12091. *prg.fontInfo[k].qqqq() = qw
  12092. }
  12093. if int32(a) > 128 {
  12094. if 256*int32(c)+int32(d) >= int32(nl) {
  12095. goto badTfm
  12096. }
  12097. if int32(a) == 255 {
  12098. if int32(k) == prg.ligKernBase[f] {
  12099. bchar = uint16(b)
  12100. }
  12101. }
  12102. } else {
  12103. if int32(b) != int32(bchar) {
  12104. {
  12105. if int32(b) < int32(bc) || int32(b) > int32(ec) {
  12106. goto badTfm
  12107. }
  12108. }
  12109. qw = *prg.fontInfo[prg.charBase[f]+int32(b)].qqqq()
  12110. if !(int32(qw.b0) > minQuarterword) {
  12111. goto badTfm
  12112. }
  12113. }
  12114. if int32(c) < 128 {
  12115. {
  12116. if int32(d) < int32(bc) || int32(d) > int32(ec) {
  12117. goto badTfm
  12118. }
  12119. }
  12120. qw = *prg.fontInfo[prg.charBase[f]+int32(d)].qqqq()
  12121. if !(int32(qw.b0) > minQuarterword) {
  12122. goto badTfm
  12123. }
  12124. } else if 256*(int32(c)-128)+int32(d) >= int32(nk) {
  12125. goto badTfm
  12126. } // check kern
  12127. if int32(a) < 128 {
  12128. if int32(k)-prg.ligKernBase[f]+int32(a)+1 >= int32(nl) {
  12129. goto badTfm
  12130. }
  12131. }
  12132. }
  12133. }
  12134. if int32(a) == 255 {
  12135. bchLabel = 256*int32(c) + int32(d)
  12136. }
  12137. }
  12138. for ii := prg.kernBase[f] + 256*(128+minQuarterword); ii <= prg.extenBase[f]-1; ii++ {
  12139. k = fontIndex(ii)
  12140. _ = k
  12141. prg.tfmFile.Get()
  12142. a = *prg.tfmFile.ByteP()
  12143. prg.tfmFile.Get()
  12144. b = *prg.tfmFile.ByteP()
  12145. prg.tfmFile.Get()
  12146. c = *prg.tfmFile.ByteP()
  12147. prg.tfmFile.Get()
  12148. d = *prg.tfmFile.ByteP()
  12149. sw = ((int32(d)*z/0400+int32(c)*z)/0400 + int32(b)*z) / int32(beta)
  12150. if int32(a) == 0 {
  12151. *prg.fontInfo[k].int() = sw
  12152. } else if int32(a) == 255 {
  12153. *prg.fontInfo[k].int() = sw - alpha
  12154. } else {
  12155. goto badTfm
  12156. }
  12157. }
  12158. // Read extensible character recipes
  12159. for ii := prg.extenBase[f]; ii <= prg.paramBase[f]-1; ii++ {
  12160. k = fontIndex(ii)
  12161. _ = k
  12162. {
  12163. prg.tfmFile.Get()
  12164. a = *prg.tfmFile.ByteP()
  12165. qw.b0 = byte(int32(a) + minQuarterword)
  12166. prg.tfmFile.Get()
  12167. b = *prg.tfmFile.ByteP()
  12168. qw.b1 = byte(int32(b) + minQuarterword)
  12169. prg.tfmFile.Get()
  12170. c = *prg.tfmFile.ByteP()
  12171. qw.b2 = byte(int32(c) + minQuarterword)
  12172. prg.tfmFile.Get()
  12173. d = *prg.tfmFile.ByteP()
  12174. qw.b3 = byte(int32(d) + minQuarterword)
  12175. *prg.fontInfo[k].qqqq() = qw
  12176. }
  12177. if int32(a) != 0 {
  12178. {
  12179. if int32(a) < int32(bc) || int32(a) > int32(ec) {
  12180. goto badTfm
  12181. }
  12182. }
  12183. qw = *prg.fontInfo[prg.charBase[f]+int32(a)].qqqq()
  12184. if !(int32(qw.b0) > minQuarterword) {
  12185. goto badTfm
  12186. }
  12187. }
  12188. if int32(b) != 0 {
  12189. {
  12190. if int32(b) < int32(bc) || int32(b) > int32(ec) {
  12191. goto badTfm
  12192. }
  12193. }
  12194. qw = *prg.fontInfo[prg.charBase[f]+int32(b)].qqqq()
  12195. if !(int32(qw.b0) > minQuarterword) {
  12196. goto badTfm
  12197. }
  12198. }
  12199. if int32(c) != 0 {
  12200. {
  12201. if int32(c) < int32(bc) || int32(c) > int32(ec) {
  12202. goto badTfm
  12203. }
  12204. }
  12205. qw = *prg.fontInfo[prg.charBase[f]+int32(c)].qqqq()
  12206. if !(int32(qw.b0) > minQuarterword) {
  12207. goto badTfm
  12208. }
  12209. }
  12210. /* */ {
  12211. {
  12212. if int32(d) < int32(bc) || int32(d) > int32(ec) {
  12213. goto badTfm
  12214. }
  12215. }
  12216. qw = *prg.fontInfo[prg.charBase[f]+int32(d)].qqqq()
  12217. if !(int32(qw.b0) > minQuarterword) {
  12218. goto badTfm
  12219. }
  12220. }
  12221. }
  12222. // Read font parameters
  12223. {
  12224. for ii := int32(1); ii <= int32(np); ii++ {
  12225. k = fontIndex(ii)
  12226. _ = k
  12227. if int32(k) == 1 {
  12228. prg.tfmFile.Get()
  12229. sw = int32(*prg.tfmFile.ByteP())
  12230. if sw > 127 {
  12231. sw = sw - 256
  12232. }
  12233. prg.tfmFile.Get()
  12234. sw = sw*0400 + int32(*prg.tfmFile.ByteP())
  12235. prg.tfmFile.Get()
  12236. sw = sw*0400 + int32(*prg.tfmFile.ByteP())
  12237. prg.tfmFile.Get()
  12238. *prg.fontInfo[prg.paramBase[f]].int() = sw*020 + int32(*prg.tfmFile.ByteP())/020
  12239. } else {
  12240. prg.tfmFile.Get()
  12241. a = *prg.tfmFile.ByteP()
  12242. prg.tfmFile.Get()
  12243. b = *prg.tfmFile.ByteP()
  12244. prg.tfmFile.Get()
  12245. c = *prg.tfmFile.ByteP()
  12246. prg.tfmFile.Get()
  12247. d = *prg.tfmFile.ByteP()
  12248. sw = ((int32(d)*z/0400+int32(c)*z)/0400 + int32(b)*z) / int32(beta)
  12249. if int32(a) == 0 {
  12250. *prg.fontInfo[prg.paramBase[f]+int32(k)-1].int() = sw
  12251. } else if int32(a) == 255 {
  12252. *prg.fontInfo[prg.paramBase[f]+int32(k)-1].int() = sw - alpha
  12253. } else {
  12254. goto badTfm
  12255. }
  12256. }
  12257. }
  12258. if prg.tfmFile.EOF() {
  12259. goto badTfm
  12260. }
  12261. for ii := int32(np) + 1; ii <= 7; ii++ {
  12262. k = fontIndex(ii)
  12263. _ = k
  12264. *prg.fontInfo[prg.paramBase[f]+int32(k)-1].int() = 0
  12265. }
  12266. }
  12267. // Make final adjustments and |goto done|
  12268. if int32(np) >= 7 {
  12269. prg.fontParams[f] = np
  12270. } else {
  12271. prg.fontParams[f] = 7
  12272. }
  12273. prg.hyphenChar[f] = *prg.eqtb[intBase+defaultHyphenCharCode-1].int()
  12274. prg.skewChar[f] = *prg.eqtb[intBase+defaultSkewCharCode-1].int()
  12275. if bchLabel < int32(nl) {
  12276. prg.bcharLabel[f] = uint16(bchLabel + prg.ligKernBase[f])
  12277. } else {
  12278. prg.bcharLabel[f] = uint16(nonAddress)
  12279. }
  12280. prg.fontBchar[f] = uint16(int32(bchar) + minQuarterword)
  12281. prg.fontFalseBchar[f] = uint16(int32(bchar) + minQuarterword)
  12282. if int32(bchar) <= int32(ec) {
  12283. if int32(bchar) >= int32(bc) {
  12284. qw = *prg.fontInfo[prg.charBase[f]+int32(bchar)].qqqq() // N.B.: not |qi(bchar)|
  12285. if int32(qw.b0) > minQuarterword {
  12286. prg.fontFalseBchar[f] = uint16(256 + minQuarterword)
  12287. }
  12288. }
  12289. }
  12290. prg.fontName[f] = nom
  12291. prg.fontArea[f] = aire
  12292. prg.fontBc[f] = byte(bc)
  12293. prg.fontEc[f] = byte(ec)
  12294. prg.fontGlue[f] = 0
  12295. prg.charBase[f] = prg.charBase[f] - minQuarterword
  12296. prg.widthBase[f] = prg.widthBase[f] - minQuarterword
  12297. prg.ligKernBase[f] = prg.ligKernBase[f] - minQuarterword
  12298. prg.kernBase[f] = prg.kernBase[f] - minQuarterword
  12299. prg.extenBase[f] = prg.extenBase[f] - minQuarterword
  12300. prg.paramBase[f] = prg.paramBase[f] - 1
  12301. prg.fmemPtr = uint16(int32(prg.fmemPtr) + int32(lf))
  12302. prg.fontPtr = f
  12303. g = f
  12304. goto done
  12305. badTfm:
  12306. {
  12307. if int32(prg.interaction) == errorStopMode {
  12308. }
  12309. prg.printNl(strNumber( /* "! " */ 262))
  12310. prg.print( /* "Font " */ 802)
  12311. }
  12312. prg.sprintCs(u)
  12313. prg.printChar(asciiCode('='))
  12314. prg.printFileName(int32(nom), int32(aire) /* "" */, 338)
  12315. if s >= 0 {
  12316. prg.print( /* " at " */ 741)
  12317. prg.printScaled(s)
  12318. prg.print( /* "pt" */ 397)
  12319. } else if s != -1000 {
  12320. prg.print( /* " scaled " */ 803)
  12321. prg.printInt(-s)
  12322. }
  12323. // \xref[Font x=xx not loadable...]
  12324. if fileOpened {
  12325. prg.print( /* " not loadable: Bad metric (TFM) file" */ 804)
  12326. } else {
  12327. prg.print( /* " not loadable: Metric (TFM) file not found" */ 805)
  12328. }
  12329. {
  12330. prg.helpPtr = 5
  12331. prg.helpLine[4] = /* "I wasn't able to read the size data for this font," */ 806
  12332. prg.helpLine[3] = /* "so I will ignore the font specification." */ 807
  12333. prg.helpLine[2] = /* "[Wizards can fix TFM files using TFtoPL/PLtoTF.]" */ 808
  12334. prg.helpLine[1] = /* "You might try inserting a different font spec;" */ 809
  12335. prg.helpLine[0] = /* "e.g., type `I\\font<same font id>=<substitute font name>'." */ 810
  12336. }
  12337. prg.error1()
  12338. done:
  12339. if fileOpened {
  12340. prg.bClose(prg.tfmFile)
  12341. }
  12342. r = g
  12343. return r
  12344. }
  12345. // 564.
  12346. // tangle:pos tex.web:10983:1:
  12347. // Note: A malformed \.[TFM] file might be shorter than it claims to be;
  12348. // thus |eof(tfm_file)| might be true when |read_font_info| refers to
  12349. // |tfm_file^| or when it says |get(tfm_file)|. If such circumstances
  12350. // cause system error messages, you will have to defeat them somehow,
  12351. // for example by defining |fget| to be `\ignorespaces|begin get(tfm_file);|
  12352. // |if eof(tfm_file) then abort; end|\unskip'.
  12353. // \xref[system dependencies]
  12354. // 581.
  12355. // tangle:pos tex.web:11293:1:
  12356. // When \TeX\ wants to typeset a character that doesn't exist, the
  12357. // character node is not created; thus the output routine can assume
  12358. // that characters exist when it sees them. The following procedure
  12359. // prints a warning message unless the user has suppressed it.
  12360. func (prg *prg) charWarning(f internalFontNumber, c eightBits) {
  12361. if *prg.eqtb[intBase+tracingLostCharsCode-1].int() > 0 {
  12362. prg.beginDiagnostic()
  12363. prg.printNl(strNumber( /* "Missing character: There is no " */ 825))
  12364. // \xref[Missing character]
  12365. prg.print(int32(c))
  12366. prg.print( /* " in font " */ 826)
  12367. prg.slowPrint(int32(prg.fontName[f]))
  12368. prg.printChar(asciiCode('!'))
  12369. prg.endDiagnostic(false)
  12370. }
  12371. }
  12372. // 582.
  12373. // tangle:pos tex.web:11308:1:
  12374. // Here is a function that returns a pointer to a character node for a
  12375. // given character in a given font. If that character doesn't exist,
  12376. // |null| is returned instead.
  12377. func (prg *prg) newCharacter(f internalFontNumber, c eightBits) (r halfword) {
  12378. var (
  12379. p halfword // newly allocated node
  12380. )
  12381. if int32(prg.fontBc[f]) <= int32(c) {
  12382. if int32(prg.fontEc[f]) >= int32(c) {
  12383. if int32((*prg.fontInfo[prg.charBase[f]+int32(c)+minQuarterword].qqqq()).b0) > minQuarterword {
  12384. p = prg.getAvail()
  12385. *(*prg.mem[p].hh()).b0() = f
  12386. *(*prg.mem[p].hh()).b1() = byte(int32(c) + minQuarterword)
  12387. r = p
  12388. goto exit
  12389. }
  12390. }
  12391. }
  12392. prg.charWarning(f, c)
  12393. r = 0
  12394. exit:
  12395. ;
  12396. return r
  12397. }
  12398. // 583. \[31] Device-independent file format
  12399. // tangle:pos tex.web:11324:39:
  12400. // The most important output produced by a run of \TeX\ is the ``device
  12401. // independent'' (\.[DVI]) file that specifies where characters and rules
  12402. // are to appear on printed pages. The form of these files was designed by
  12403. // David R. Fuchs in 1979. Almost any reasonable typesetting device can be
  12404. // \xref[Fuchs, David Raymond]
  12405. // \xref[DVI_files][\.[DVI] files]
  12406. // driven by a program that takes \.[DVI] files as input, and dozens of such
  12407. // \.[DVI]-to-whatever programs have been written. Thus, it is possible to
  12408. // print the output of \TeX\ on many different kinds of equipment, using \TeX\
  12409. // as a device-independent ``front end.''
  12410. //
  12411. // A \.[DVI] file is a stream of 8-bit bytes, which may be regarded as a
  12412. // series of commands in a machine-like language. The first byte of each command
  12413. // is the operation code, and this code is followed by zero or more bytes
  12414. // that provide parameters to the command. The parameters themselves may consist
  12415. // of several consecutive bytes; for example, the `|set_rule|' command has two
  12416. // parameters, each of which is four bytes long. Parameters are usually
  12417. // regarded as nonnegative integers; but four-byte-long parameters,
  12418. // and shorter parameters that denote distances, can be
  12419. // either positive or negative. Such parameters are given in two's complement
  12420. // notation. For example, a two-byte-long distance parameter has a value between
  12421. // $-2^[15]$ and $2^[15]-1$. As in \.[TFM] files, numbers that occupy
  12422. // more than one byte position appear in BigEndian order.
  12423. //
  12424. // A \.[DVI] file consists of a ``preamble,'' followed by a sequence of one
  12425. // or more ``pages,'' followed by a ``postamble.'' The preamble is simply a
  12426. // |pre| command, with its parameters that define the dimensions used in the
  12427. // file; this must come first. Each ``page'' consists of a |bop| command,
  12428. // followed by any number of other commands that tell where characters are to
  12429. // be placed on a physical page, followed by an |eop| command. The pages
  12430. // appear in the order that \TeX\ generated them. If we ignore |nop| commands
  12431. // and \\[fnt\_def] commands (which are allowed between any two commands in
  12432. // the file), each |eop| command is immediately followed by a |bop| command,
  12433. // or by a |post| command; in the latter case, there are no more pages in the
  12434. // file, and the remaining bytes form the postamble. Further details about
  12435. // the postamble will be explained later.
  12436. //
  12437. // Some parameters in \.[DVI] commands are ``pointers.'' These are four-byte
  12438. // quantities that give the location number of some other byte in the file;
  12439. // the first byte is number~0, then comes number~1, and so on. For example,
  12440. // one of the parameters of a |bop| command points to the previous |bop|;
  12441. // this makes it feasible to read the pages in backwards order, in case the
  12442. // results are being directed to a device that stacks its output face up.
  12443. // Suppose the preamble of a \.[DVI] file occupies bytes 0 to 99. Now if the
  12444. // first page occupies bytes 100 to 999, say, and if the second
  12445. // page occupies bytes 1000 to 1999, then the |bop| that starts in byte 1000
  12446. // points to 100 and the |bop| that starts in byte 2000 points to 1000. (The
  12447. // very first |bop|, i.e., the one starting in byte 100, has a pointer of~$-1$.)
  12448. // 584.
  12449. // tangle:pos tex.web:11374:1:
  12450. // The \.[DVI] format is intended to be both compact and easily interpreted
  12451. // by a machine. Compactness is achieved by making most of the information
  12452. // implicit instead of explicit. When a \.[DVI]-reading program reads the
  12453. // commands for a page, it keeps track of several quantities: (a)~The current
  12454. // font |f| is an integer; this value is changed only
  12455. // by \\[fnt] and \\[fnt\_num] commands. (b)~The current position on the page
  12456. // is given by two numbers called the horizontal and vertical coordinates,
  12457. // |h| and |v|. Both coordinates are zero at the upper left corner of the page;
  12458. // moving to the right corresponds to increasing the horizontal coordinate, and
  12459. // moving down corresponds to increasing the vertical coordinate. Thus, the
  12460. // coordinates are essentially Cartesian, except that vertical directions are
  12461. // flipped; the Cartesian version of |(h,v)| would be |(h,-v)|. (c)~The
  12462. // current spacing amounts are given by four numbers |w|, |x|, |y|, and |z|,
  12463. // where |w| and~|x| are used for horizontal spacing and where |y| and~|z|
  12464. // are used for vertical spacing. (d)~There is a stack containing
  12465. // |(h,v,w,x,y,z)| values; the \.[DVI] commands |push| and |pop| are used to
  12466. // change the current level of operation. Note that the current font~|f| is
  12467. // not pushed and popped; the stack contains only information about
  12468. // positioning.
  12469. //
  12470. // The values of |h|, |v|, |w|, |x|, |y|, and |z| are signed integers having up
  12471. // to 32 bits, including the sign. Since they represent physical distances,
  12472. // there is a small unit of measurement such that increasing |h| by~1 means
  12473. // moving a certain tiny distance to the right. The actual unit of
  12474. // measurement is variable, as explained below; \TeX\ sets things up so that
  12475. // its \.[DVI] output is in sp units, i.e., scaled points, in agreement with
  12476. // all the |scaled| dimensions in \TeX's data structures.
  12477. // 585.
  12478. // tangle:pos tex.web:11402:1:
  12479. // Here is a list of all the commands that may appear in a \.[DVI] file. Each
  12480. // command is specified by its symbolic name (e.g., |bop|), its opcode byte
  12481. // (e.g., 139), and its parameters (if any). The parameters are followed
  12482. // by a bracketed number telling how many bytes they occupy; for example,
  12483. // `|p[4]|' means that parameter |p| is four bytes long.
  12484. //
  12485. // \yskip\hang|set_char_0| 0. Typeset character number~0 from font~|f|
  12486. // such that the reference point of the character is at |(h,v)|. Then
  12487. // increase |h| by the width of that character. Note that a character may
  12488. // have zero or negative width, so one cannot be sure that |h| will advance
  12489. // after this command; but |h| usually does increase.
  12490. //
  12491. // \yskip\hang\\[set\_char\_1] through \\[set\_char\_127] (opcodes 1 to 127).
  12492. // Do the operations of |set_char_0|; but use the character whose number
  12493. // matches the opcode, instead of character~0.
  12494. //
  12495. // \yskip\hang|set1| 128 |c[1]|. Same as |set_char_0|, except that character
  12496. // number~|c| is typeset. \TeX82 uses this command for characters in the
  12497. // range |128<=c<256|.
  12498. //
  12499. // \yskip\hang| set2| 129 |c[2]|. Same as |set1|, except that |c|~is two
  12500. // bytes long, so it is in the range |0<=c<65536|. \TeX82 never uses this
  12501. // command, but it should come in handy for extensions of \TeX\ that deal
  12502. // with oriental languages.
  12503. // \xref[oriental characters]\xref[Chinese characters]\xref[Japanese characters]
  12504. //
  12505. // \yskip\hang| set3| 130 |c[3]|. Same as |set1|, except that |c|~is three
  12506. // bytes long, so it can be as large as $2^[24]-1$. Not even the Chinese
  12507. // language has this many characters, but this command might prove useful
  12508. // in some yet unforeseen extension.
  12509. //
  12510. // \yskip\hang| set4| 131 |c[4]|. Same as |set1|, except that |c|~is four
  12511. // bytes long. Imagine that.
  12512. //
  12513. // \yskip\hang|set_rule| 132 |a[4]| |b[4]|. Typeset a solid black rectangle
  12514. // of height~|a| and width~|b|, with its bottom left corner at |(h,v)|. Then
  12515. // set |h:=h+b|. If either |a<=0| or |b<=0|, nothing should be typeset. Note
  12516. // that if |b<0|, the value of |h| will decrease even though nothing else happens.
  12517. // See below for details about how to typeset rules so that consistency with
  12518. // \MF\ is guaranteed.
  12519. //
  12520. // \yskip\hang| put1| 133 |c[1]|. Typeset character number~|c| from font~|f|
  12521. // such that the reference point of the character is at |(h,v)|. (The `put'
  12522. // commands are exactly like the `set' commands, except that they simply put out a
  12523. // character or a rule without moving the reference point afterwards.)
  12524. //
  12525. // \yskip\hang| put2| 134 |c[2]|. Same as |set2|, except that |h| is not changed.
  12526. //
  12527. // \yskip\hang| put3| 135 |c[3]|. Same as |set3|, except that |h| is not changed.
  12528. //
  12529. // \yskip\hang| put4| 136 |c[4]|. Same as |set4|, except that |h| is not changed.
  12530. //
  12531. // \yskip\hang|put_rule| 137 |a[4]| |b[4]|. Same as |set_rule|, except that
  12532. // |h| is not changed.
  12533. //
  12534. // \yskip\hang|nop| 138. No operation, do nothing. Any number of |nop|'s
  12535. // may occur between \.[DVI] commands, but a |nop| cannot be inserted between
  12536. // a command and its parameters or between two parameters.
  12537. //
  12538. // \yskip\hang|bop| 139 $c_0[4]$ $c_1[4]$ $\ldots$ $c_9[4]$ $p[4]$. Beginning
  12539. // of a page: Set |(h,v,w,x,y,z):=(0,0,0,0,0,0)| and set the stack empty. Set
  12540. // the current font |f| to an undefined value. The ten $c_i$ parameters hold
  12541. // the values of \.[\\count0] $\ldots$ \.[\\count9] in \TeX\ at the time
  12542. // \.[\\shipout] was invoked for this page; they can be used to identify
  12543. // pages, if a user wants to print only part of a \.[DVI] file. The parameter
  12544. // |p| points to the previous |bop| in the file; the first
  12545. // |bop| has $p=-1$.
  12546. //
  12547. // \yskip\hang|eop| 140. End of page: Print what you have read since the
  12548. // previous |bop|. At this point the stack should be empty. (The \.[DVI]-reading
  12549. // programs that drive most output devices will have kept a buffer of the
  12550. // material that appears on the page that has just ended. This material is
  12551. // largely, but not entirely, in order by |v| coordinate and (for fixed |v|) by
  12552. // |h|~coordinate; so it usually needs to be sorted into some order that is
  12553. // appropriate for the device in question.)
  12554. //
  12555. // \yskip\hang|push| 141. Push the current values of |(h,v,w,x,y,z)| onto the
  12556. // top of the stack; do not change any of these values. Note that |f| is
  12557. // not pushed.
  12558. //
  12559. // \yskip\hang|pop| 142. Pop the top six values off of the stack and assign
  12560. // them respectively to |(h,v,w,x,y,z)|. The number of pops should never
  12561. // exceed the number of pushes, since it would be highly embarrassing if the
  12562. // stack were empty at the time of a |pop| command.
  12563. //
  12564. // \yskip\hang|right1| 143 |b[1]|. Set |h:=h+b|, i.e., move right |b| units.
  12565. // The parameter is a signed number in two's complement notation, |-128<=b<128|;
  12566. // if |b<0|, the reference point moves left.
  12567. //
  12568. // \yskip\hang| right2| 144 |b[2]|. Same as |right1|, except that |b| is a
  12569. // two-byte quantity in the range |-32768<=b<32768|.
  12570. //
  12571. // \yskip\hang| right3| 145 |b[3]|. Same as |right1|, except that |b| is a
  12572. // three-byte quantity in the range |$-2^[23]$<=b<$2^[23]$|.
  12573. //
  12574. // \yskip\hang| right4| 146 |b[4]|. Same as |right1|, except that |b| is a
  12575. // four-byte quantity in the range |$-2^[31]$<=b<$2^[31]$|.
  12576. //
  12577. // \yskip\hang|w0| 147. Set |h:=h+w|; i.e., move right |w| units. With luck,
  12578. // this parameterless command will usually suffice, because the same kind of motion
  12579. // will occur several times in succession; the following commands explain how
  12580. // |w| gets particular values.
  12581. //
  12582. // \yskip\hang|w1| 148 |b[1]|. Set |w:=b| and |h:=h+b|. The value of |b| is a
  12583. // signed quantity in two's complement notation, |-128<=b<128|. This command
  12584. // changes the current |w|~spacing and moves right by |b|.
  12585. //
  12586. // \yskip\hang| w2| 149 |b[2]|. Same as |w1|, but |b| is two bytes long,
  12587. // |-32768<=b<32768|.
  12588. //
  12589. // \yskip\hang| w3| 150 |b[3]|. Same as |w1|, but |b| is three bytes long,
  12590. // |$-2^[23]$<=b<$2^[23]$|.
  12591. //
  12592. // \yskip\hang| w4| 151 |b[4]|. Same as |w1|, but |b| is four bytes long,
  12593. // |$-2^[31]$<=b<$2^[31]$|.
  12594. //
  12595. // \yskip\hang|x0| 152. Set |h:=h+x|; i.e., move right |x| units. The `|x|'
  12596. // commands are like the `|w|' commands except that they involve |x| instead
  12597. // of |w|.
  12598. //
  12599. // \yskip\hang|x1| 153 |b[1]|. Set |x:=b| and |h:=h+b|. The value of |b| is a
  12600. // signed quantity in two's complement notation, |-128<=b<128|. This command
  12601. // changes the current |x|~spacing and moves right by |b|.
  12602. //
  12603. // \yskip\hang| x2| 154 |b[2]|. Same as |x1|, but |b| is two bytes long,
  12604. // |-32768<=b<32768|.
  12605. //
  12606. // \yskip\hang| x3| 155 |b[3]|. Same as |x1|, but |b| is three bytes long,
  12607. // |$-2^[23]$<=b<$2^[23]$|.
  12608. //
  12609. // \yskip\hang| x4| 156 |b[4]|. Same as |x1|, but |b| is four bytes long,
  12610. // |$-2^[31]$<=b<$2^[31]$|.
  12611. //
  12612. // \yskip\hang|down1| 157 |a[1]|. Set |v:=v+a|, i.e., move down |a| units.
  12613. // The parameter is a signed number in two's complement notation, |-128<=a<128|;
  12614. // if |a<0|, the reference point moves up.
  12615. //
  12616. // \yskip\hang| down2| 158 |a[2]|. Same as |down1|, except that |a| is a
  12617. // two-byte quantity in the range |-32768<=a<32768|.
  12618. //
  12619. // \yskip\hang| down3| 159 |a[3]|. Same as |down1|, except that |a| is a
  12620. // three-byte quantity in the range |$-2^[23]$<=a<$2^[23]$|.
  12621. //
  12622. // \yskip\hang| down4| 160 |a[4]|. Same as |down1|, except that |a| is a
  12623. // four-byte quantity in the range |$-2^[31]$<=a<$2^[31]$|.
  12624. //
  12625. // \yskip\hang|y0| 161. Set |v:=v+y|; i.e., move down |y| units. With luck,
  12626. // this parameterless command will usually suffice, because the same kind of motion
  12627. // will occur several times in succession; the following commands explain how
  12628. // |y| gets particular values.
  12629. //
  12630. // \yskip\hang|y1| 162 |a[1]|. Set |y:=a| and |v:=v+a|. The value of |a| is a
  12631. // signed quantity in two's complement notation, |-128<=a<128|. This command
  12632. // changes the current |y|~spacing and moves down by |a|.
  12633. //
  12634. // \yskip\hang| y2| 163 |a[2]|. Same as |y1|, but |a| is two bytes long,
  12635. // |-32768<=a<32768|.
  12636. //
  12637. // \yskip\hang| y3| 164 |a[3]|. Same as |y1|, but |a| is three bytes long,
  12638. // |$-2^[23]$<=a<$2^[23]$|.
  12639. //
  12640. // \yskip\hang| y4| 165 |a[4]|. Same as |y1|, but |a| is four bytes long,
  12641. // |$-2^[31]$<=a<$2^[31]$|.
  12642. //
  12643. // \yskip\hang|z0| 166. Set |v:=v+z|; i.e., move down |z| units. The `|z|' commands
  12644. // are like the `|y|' commands except that they involve |z| instead of |y|.
  12645. //
  12646. // \yskip\hang|z1| 167 |a[1]|. Set |z:=a| and |v:=v+a|. The value of |a| is a
  12647. // signed quantity in two's complement notation, |-128<=a<128|. This command
  12648. // changes the current |z|~spacing and moves down by |a|.
  12649. //
  12650. // \yskip\hang| z2| 168 |a[2]|. Same as |z1|, but |a| is two bytes long,
  12651. // |-32768<=a<32768|.
  12652. //
  12653. // \yskip\hang| z3| 169 |a[3]|. Same as |z1|, but |a| is three bytes long,
  12654. // |$-2^[23]$<=a<$2^[23]$|.
  12655. //
  12656. // \yskip\hang| z4| 170 |a[4]|. Same as |z1|, but |a| is four bytes long,
  12657. // |$-2^[31]$<=a<$2^[31]$|.
  12658. //
  12659. // \yskip\hang|fnt_num_0| 171. Set |f:=0|. Font 0 must previously have been
  12660. // defined by a \\[fnt\_def] instruction, as explained below.
  12661. //
  12662. // \yskip\hang\\[fnt\_num\_1] through \\[fnt\_num\_63] (opcodes 172 to 234). Set
  12663. // |f:=1|, \dots, \hbox[|f:=63|], respectively.
  12664. //
  12665. // \yskip\hang|fnt1| 235 |k[1]|. Set |f:=k|. \TeX82 uses this command for font
  12666. // numbers in the range |64<=k<256|.
  12667. //
  12668. // \yskip\hang| fnt2| 236 |k[2]|. Same as |fnt1|, except that |k|~is two
  12669. // bytes long, so it is in the range |0<=k<65536|. \TeX82 never generates this
  12670. // command, but large font numbers may prove useful for specifications of
  12671. // color or texture, or they may be used for special fonts that have fixed
  12672. // numbers in some external coding scheme.
  12673. //
  12674. // \yskip\hang| fnt3| 237 |k[3]|. Same as |fnt1|, except that |k|~is three
  12675. // bytes long, so it can be as large as $2^[24]-1$.
  12676. //
  12677. // \yskip\hang| fnt4| 238 |k[4]|. Same as |fnt1|, except that |k|~is four
  12678. // bytes long; this is for the really big font numbers (and for the negative ones).
  12679. //
  12680. // \yskip\hang|xxx1| 239 |k[1]| |x[k]|. This command is undefined in
  12681. // general; it functions as a $(k+2)$-byte |nop| unless special \.[DVI]-reading
  12682. // programs are being used. \TeX82 generates |xxx1| when a short enough
  12683. // \.[\\special] appears, setting |k| to the number of bytes being sent. It
  12684. // is recommended that |x| be a string having the form of a keyword followed
  12685. // by possible parameters relevant to that keyword.
  12686. //
  12687. // \yskip\hang| xxx2| 240 |k[2]| |x[k]|. Like |xxx1|, but |0<=k<65536|.
  12688. //
  12689. // \yskip\hang| xxx3| 241 |k[3]| |x[k]|. Like |xxx1|, but |0<=k<$2^[24]$|.
  12690. //
  12691. // \yskip\hang|xxx4| 242 |k[4]| |x[k]|. Like |xxx1|, but |k| can be ridiculously
  12692. // large. \TeX82 uses |xxx4| when sending a string of length 256 or more.
  12693. //
  12694. // \yskip\hang|fnt_def1| 243 |k[1]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
  12695. // Define font |k|, where |0<=k<256|; font definitions will be explained shortly.
  12696. //
  12697. // \yskip\hang| fnt_def2| 244 |k[2]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
  12698. // Define font |k|, where |0<=k<65536|.
  12699. //
  12700. // \yskip\hang| fnt_def3| 245 |k[3]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
  12701. // Define font |k|, where |0<=k<$2^[24]$|.
  12702. //
  12703. // \yskip\hang| fnt_def4| 246 |k[4]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
  12704. // Define font |k|, where |$-2^[31]$<=k<$2^[31]$|.
  12705. //
  12706. // \yskip\hang|pre| 247 |i[1]| |num[4]| |den[4]| |mag[4]| |k[1]| |x[k]|.
  12707. // Beginning of the preamble; this must come at the very beginning of the
  12708. // file. Parameters |i|, |num|, |den|, |mag|, |k|, and |x| are explained below.
  12709. //
  12710. // \yskip\hang|post| 248. Beginning of the postamble, see below.
  12711. //
  12712. // \yskip\hang|post_post| 249. Ending of the postamble, see below.
  12713. //
  12714. // \yskip\noindent Commands 250--255 are undefined at the present time.
  12715. // 586.
  12716. // 587.
  12717. // tangle:pos tex.web:11667:1:
  12718. // The preamble contains basic information about the file as a whole. As
  12719. // stated above, there are six parameters:
  12720. // $$\hbox[| i[1]| | num[4]| | den[4]| | mag[4]| | k[1]| | x[k]|.]$$
  12721. // The |i| byte identifies \.[DVI] format; currently this byte is always set
  12722. // to~2. (The value |i=3| is currently used for an extended format that
  12723. // allows a mixture of right-to-left and left-to-right typesetting.
  12724. // Some day we will set |i=4|, when \.[DVI] format makes another
  12725. // incompatible change---perhaps in the year 2048.)
  12726. //
  12727. // The next two parameters, |num| and |den|, are positive integers that define
  12728. // the units of measurement; they are the numerator and denominator of a
  12729. // fraction by which all dimensions in the \.[DVI] file could be multiplied
  12730. // in order to get lengths in units of $10^[-7]$ meters. Since $\rm 7227[pt] =
  12731. // 254[cm]$, and since \TeX\ works with scaled points where there are $2^[16]$
  12732. // sp in a point, \TeX\ sets
  12733. // $|num|/|den|=(254\cdot10^5)/(7227\cdot2^[16])=25400000/473628672$.
  12734. // \xref[sp]
  12735. //
  12736. // The |mag| parameter is what \TeX\ calls \.[\\mag], i.e., 1000 times the
  12737. // desired magnification. The actual fraction by which dimensions are
  12738. // multiplied is therefore $|mag|\cdot|num|/1000|den|$. Note that if a \TeX\
  12739. // source document does not call for any `\.[true]' dimensions, and if you
  12740. // change it only by specifying a different \.[\\mag] setting, the \.[DVI]
  12741. // file that \TeX\ creates will be completely unchanged except for the value
  12742. // of |mag| in the preamble and postamble. (Fancy \.[DVI]-reading programs allow
  12743. // users to override the |mag|~setting when a \.[DVI] file is being printed.)
  12744. //
  12745. // Finally, |k| and |x| allow the \.[DVI] writer to include a comment, which is not
  12746. // interpreted further. The length of comment |x| is |k|, where |0<=k<256|.
  12747. // 588.
  12748. // tangle:pos tex.web:11699:1:
  12749. // Font definitions for a given font number |k| contain further parameters
  12750. // $$\hbox[|c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.]$$
  12751. // The four-byte value |c| is the check sum that \TeX\ found in the \.[TFM]
  12752. // file for this font; |c| should match the check sum of the font found by
  12753. // programs that read this \.[DVI] file.
  12754. // \xref[check sum]
  12755. //
  12756. // Parameter |s| contains a fixed-point scale factor that is applied to
  12757. // the character widths in font |k|; font dimensions in \.[TFM] files and
  12758. // other font files are relative to this quantity, which is called the
  12759. // ``at size'' elsewhere in this documentation. The value of |s| is
  12760. // always positive and less than $2^[27]$. It is given in the same units
  12761. // as the other \.[DVI] dimensions, i.e., in sp when \TeX82 has made the
  12762. // file. Parameter |d| is similar to |s|; it is the ``design size,'' and
  12763. // (like~|s|) it is given in \.[DVI] units. Thus, font |k| is to be used
  12764. // at $|mag|\cdot s/1000d$ times its normal size.
  12765. //
  12766. // The remaining part of a font definition gives the external name of the font,
  12767. // which is an ASCII string of length |a+l|. The number |a| is the length
  12768. // of the ``area'' or directory, and |l| is the length of the font name itself;
  12769. // the standard local system font area is supposed to be used when |a=0|.
  12770. // The |n| field contains the area in its first |a| bytes.
  12771. //
  12772. // Font definitions must appear before the first use of a particular font number.
  12773. // Once font |k| is defined, it must not be defined again; however, we
  12774. // shall see below that font definitions appear in the postamble as well as
  12775. // in the pages, so in this sense each font number is defined exactly twice,
  12776. // if at all. Like |nop| commands, font definitions can
  12777. // appear before the first |bop|, or between an |eop| and a |bop|.
  12778. // 589.
  12779. // tangle:pos tex.web:11729:1:
  12780. // Sometimes it is desirable to make horizontal or vertical rules line up
  12781. // precisely with certain features in characters of a font. It is possible to
  12782. // guarantee the correct matching between \.[DVI] output and the characters
  12783. // generated by \MF\ by adhering to the following principles: (1)~The \MF\
  12784. // characters should be positioned so that a bottom edge or left edge that is
  12785. // supposed to line up with the bottom or left edge of a rule appears at the
  12786. // reference point, i.e., in row~0 and column~0 of the \MF\ raster. This
  12787. // ensures that the position of the rule will not be rounded differently when
  12788. // the pixel size is not a perfect multiple of the units of measurement in
  12789. // the \.[DVI] file. (2)~A typeset rule of height $a>0$ and width $b>0$
  12790. // should be equivalent to a \MF-generated character having black pixels in
  12791. // precisely those raster positions whose \MF\ coordinates satisfy
  12792. // |0<=x<$\alpha$b| and |0<=y<$\alpha$a|, where $\alpha$ is the number
  12793. // of pixels per \.[DVI] unit.
  12794. // \xref[METAFONT][\MF]
  12795. // \xref[alignment of rules with characters]
  12796. // \xref[rules aligning with characters]
  12797. // 590.
  12798. // tangle:pos tex.web:11747:1:
  12799. // The last page in a \.[DVI] file is followed by `|post|'; this command
  12800. // introduces the postamble, which summarizes important facts that \TeX\ has
  12801. // accumulated about the file, making it possible to print subsets of the data
  12802. // with reasonable efficiency. The postamble has the form
  12803. // $$\vbox[\halign[\hbox[#\hfil]\cr
  12804. // |post| |p[4]| |num[4]| |den[4]| |mag[4]| |l[4]| |u[4]| |s[2]| |t[2]|\cr
  12805. // $\langle\,$font definitions$\,\rangle$\cr
  12806. // |post_post| |q[4]| |i[1]| 223's$[[\G]4]$\cr]]$$
  12807. // Here |p| is a pointer to the final |bop| in the file. The next three
  12808. // parameters, |num|, |den|, and |mag|, are duplicates of the quantities that
  12809. // appeared in the preamble.
  12810. //
  12811. // Parameters |l| and |u| give respectively the height-plus-depth of the tallest
  12812. // page and the width of the widest page, in the same units as other dimensions
  12813. // of the file. These numbers might be used by a \.[DVI]-reading program to
  12814. // position individual ``pages'' on large sheets of film or paper; however,
  12815. // the standard convention for output on normal size paper is to position each
  12816. // page so that the upper left-hand corner is exactly one inch from the left
  12817. // and the top. Experience has shown that it is unwise to design \.[DVI]-to-printer
  12818. // software that attempts cleverly to center the output; a fixed position of
  12819. // the upper left corner is easiest for users to understand and to work with.
  12820. // Therefore |l| and~|u| are often ignored.
  12821. //
  12822. // Parameter |s| is the maximum stack depth (i.e., the largest excess of
  12823. // |push| commands over |pop| commands) needed to process this file. Then
  12824. // comes |t|, the total number of pages (|bop| commands) present.
  12825. //
  12826. // The postamble continues with font definitions, which are any number of
  12827. // \\[fnt\_def] commands as described above, possibly interspersed with |nop|
  12828. // commands. Each font number that is used in the \.[DVI] file must be defined
  12829. // exactly twice: Once before it is first selected by a \\[fnt] command, and once
  12830. // in the postamble.
  12831. // 591.
  12832. // tangle:pos tex.web:11780:1:
  12833. // The last part of the postamble, following the |post_post| byte that
  12834. // signifies the end of the font definitions, contains |q|, a pointer to the
  12835. // |post| command that started the postamble. An identification byte, |i|,
  12836. // comes next; this currently equals~2, as in the preamble.
  12837. //
  12838. // The |i| byte is followed by four or more bytes that are all equal to
  12839. // the decimal number 223 (i.e., @'337 in octal). \TeX\ puts out four to seven of
  12840. // these trailing bytes, until the total length of the file is a multiple of
  12841. // four bytes, since this works out best on machines that pack four bytes per
  12842. // word; but any number of 223's is allowed, as long as there are at least four
  12843. // of them. In effect, 223 is a sort of signature that is added at the very end.
  12844. // \xref[Fuchs, David Raymond]
  12845. //
  12846. // This curious way to finish off a \.[DVI] file makes it feasible for
  12847. // \.[DVI]-reading programs to find the postamble first, on most computers,
  12848. // even though \TeX\ wants to write the postamble last. Most operating
  12849. // systems permit random access to individual words or bytes of a file, so
  12850. // the \.[DVI] reader can start at the end and skip backwards over the 223's
  12851. // until finding the identification byte. Then it can back up four bytes, read
  12852. // |q|, and move to byte |q| of the file. This byte should, of course,
  12853. // contain the value 248 (|post|); now the postamble can be read, so the
  12854. // \.[DVI] reader can discover all the information needed for typesetting the
  12855. // pages. Note that it is also possible to skip through the \.[DVI] file at
  12856. // reasonably high speed to locate a particular page, if that proves
  12857. // desirable. This saves a lot of time, since \.[DVI] files used in production
  12858. // jobs tend to be large.
  12859. //
  12860. // Unfortunately, however, standard \PASCAL\ does not include the ability to
  12861. // \xref[system dependencies]
  12862. // access a random position in a file, or even to determine the length of a file.
  12863. // Almost all systems nowadays provide the necessary capabilities, so \.[DVI]
  12864. // format has been designed to work most efficiently with modern operating systems.
  12865. // But if \.[DVI] files have to be processed under the restrictions of standard
  12866. // \PASCAL, one can simply read them from front to back, since the necessary
  12867. // header information is present in the preamble and in the font definitions.
  12868. // (The |l| and |u| and |s| and |t| parameters, which appear only in the
  12869. // postamble, are ``frills'' that are handy but not absolutely necessary.)
  12870. // 597.
  12871. // tangle:pos tex.web:11911:1:
  12872. // The actual output of |dvi_buf[a..b]| to |dvi_file| is performed by calling
  12873. // |write_dvi(a,b)|. For best results, this procedure should be optimized to
  12874. // run as fast as possible on each particular system, since it is part of
  12875. // \TeX's inner loop. It is safe to assume that |a| and |b+1| will both be
  12876. // multiples of 4 when |write_dvi(a,b)| is called; therefore it is possible on
  12877. // many machines to use efficient methods to pack four bytes per word and to
  12878. // output an array of words with one system call.
  12879. // \xref[system dependencies]
  12880. // \xref[inner loop]
  12881. // \xref[defecation]
  12882. func (prg *prg) writeDvi(a, b dviIndex) {
  12883. var (
  12884. k dviIndex
  12885. )
  12886. for ii := int32(a); ii <= int32(b); ii++ {
  12887. k = dviIndex(ii)
  12888. _ = k
  12889. prg.dviFile.Write(prg.dviBuf[k])
  12890. }
  12891. }
  12892. // 598.
  12893. // tangle:pos tex.web:11927:1:
  12894. // To put a byte in the buffer without paying the cost of invoking a procedure
  12895. // each time, we use the macro |dvi_out|.
  12896. func (prg *prg) dviSwap() {
  12897. if int32(prg.dviLimit) == dviBufSize {
  12898. prg.writeDvi(dviIndex(0), dviIndex(int32(prg.halfBuf)-1))
  12899. prg.dviLimit = prg.halfBuf
  12900. prg.dviOffset = prg.dviOffset + dviBufSize
  12901. prg.dviPtr = 0
  12902. } else {
  12903. prg.writeDvi(prg.halfBuf, dviIndex(dviBufSize-1))
  12904. prg.dviLimit = uint16(dviBufSize)
  12905. }
  12906. prg.dviGone = prg.dviGone + int32(prg.halfBuf)
  12907. }
  12908. // 600.
  12909. // tangle:pos tex.web:11951:1:
  12910. // The |dvi_four| procedure outputs four bytes in two's complement notation,
  12911. // without risking arithmetic overflow.
  12912. func (prg *prg) dviFour(x int32) {
  12913. if x >= 0 {
  12914. prg.dviBuf[prg.dviPtr] = byte(x / 0100000000)
  12915. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  12916. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  12917. prg.dviSwap()
  12918. }
  12919. } else {
  12920. x = x + 010000000000
  12921. x = x + 010000000000
  12922. {
  12923. prg.dviBuf[prg.dviPtr] = byte(x/0100000000 + 128)
  12924. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  12925. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  12926. prg.dviSwap()
  12927. }
  12928. }
  12929. }
  12930. x = x % 0100000000
  12931. {
  12932. prg.dviBuf[prg.dviPtr] = byte(x / 0200000)
  12933. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  12934. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  12935. prg.dviSwap()
  12936. }
  12937. }
  12938. x = x % 0200000
  12939. {
  12940. prg.dviBuf[prg.dviPtr] = byte(x / 0400)
  12941. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  12942. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  12943. prg.dviSwap()
  12944. }
  12945. }
  12946. {
  12947. prg.dviBuf[prg.dviPtr] = byte(x % 0400)
  12948. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  12949. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  12950. prg.dviSwap()
  12951. }
  12952. }
  12953. }
  12954. // 601.
  12955. // tangle:pos tex.web:11965:1:
  12956. // A mild optimization of the output is performed by the |dvi_pop|
  12957. // routine, which issues a |pop| unless it is possible to cancel a
  12958. // `|push| |pop|' pair. The parameter to |dvi_pop| is the byte address
  12959. // following the old |push| that matches the new |pop|.
  12960. func (prg *prg) dviPop(l int32) {
  12961. if l == prg.dviOffset+int32(prg.dviPtr) && int32(prg.dviPtr) > 0 {
  12962. prg.dviPtr = uint16(int32(prg.dviPtr) - 1)
  12963. } else {
  12964. prg.dviBuf[prg.dviPtr] = byte(pop)
  12965. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  12966. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  12967. prg.dviSwap()
  12968. }
  12969. }
  12970. }
  12971. // 602.
  12972. // tangle:pos tex.web:11975:1:
  12973. // Here's a procedure that outputs a font definition. Since \TeX82 uses at
  12974. // most 256 different fonts per job, |fnt_def1| is always used as the command code.
  12975. func (prg *prg) dviFontDef(f internalFontNumber) {
  12976. var (
  12977. k poolPointer // index into |str_pool|
  12978. )
  12979. {
  12980. prg.dviBuf[prg.dviPtr] = byte(fntDef1)
  12981. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  12982. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  12983. prg.dviSwap()
  12984. }
  12985. }
  12986. {
  12987. prg.dviBuf[prg.dviPtr] = byte(int32(f) - fontBase - 1)
  12988. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  12989. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  12990. prg.dviSwap()
  12991. }
  12992. }
  12993. {
  12994. prg.dviBuf[prg.dviPtr] = byte(int32(prg.fontCheck[f].b0) - minQuarterword)
  12995. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  12996. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  12997. prg.dviSwap()
  12998. }
  12999. }
  13000. {
  13001. prg.dviBuf[prg.dviPtr] = byte(int32(prg.fontCheck[f].b1) - minQuarterword)
  13002. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13003. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13004. prg.dviSwap()
  13005. }
  13006. }
  13007. {
  13008. prg.dviBuf[prg.dviPtr] = byte(int32(prg.fontCheck[f].b2) - minQuarterword)
  13009. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13010. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13011. prg.dviSwap()
  13012. }
  13013. }
  13014. {
  13015. prg.dviBuf[prg.dviPtr] = byte(int32(prg.fontCheck[f].b3) - minQuarterword)
  13016. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13017. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13018. prg.dviSwap()
  13019. }
  13020. }
  13021. prg.dviFour(prg.fontSize[f])
  13022. prg.dviFour(prg.fontDsize[f])
  13023. {
  13024. prg.dviBuf[prg.dviPtr] = byte(int32(prg.strStart[int32(prg.fontArea[f])+1]) - int32(prg.strStart[prg.fontArea[f]]))
  13025. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13026. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13027. prg.dviSwap()
  13028. }
  13029. }
  13030. {
  13031. prg.dviBuf[prg.dviPtr] = byte(int32(prg.strStart[int32(prg.fontName[f])+1]) - int32(prg.strStart[prg.fontName[f]]))
  13032. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13033. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13034. prg.dviSwap()
  13035. }
  13036. }
  13037. // Output the font name whose internal number is |f|
  13038. for ii := int32(prg.strStart[prg.fontArea[f]]); ii <= int32(prg.strStart[int32(prg.fontArea[f])+1])-1; ii++ {
  13039. k = poolPointer(ii)
  13040. _ = k
  13041. prg.dviBuf[prg.dviPtr] = prg.strPool[k]
  13042. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13043. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13044. prg.dviSwap()
  13045. }
  13046. }
  13047. for ii := int32(prg.strStart[prg.fontName[f]]); ii <= int32(prg.strStart[int32(prg.fontName[f])+1])-1; ii++ {
  13048. k = poolPointer(ii)
  13049. _ = k
  13050. prg.dviBuf[prg.dviPtr] = prg.strPool[k]
  13051. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13052. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13053. prg.dviSwap()
  13054. }
  13055. }
  13056. }
  13057. // 604.
  13058. // tangle:pos tex.web:11999:1:
  13059. // Versions of \TeX\ intended for small computers might well choose to omit
  13060. // the ideas in the next few parts of this program, since it is not really
  13061. // necessary to optimize the \.[DVI] code by making use of the |w0|, |x0|,
  13062. // |y0|, and |z0| commands. Furthermore, the algorithm that we are about to
  13063. // describe does not pretend to give an optimum reduction in the length
  13064. // of the \.[DVI] code; after all, speed is more important than compactness.
  13065. // But the method is surprisingly effective, and it takes comparatively little
  13066. // time.
  13067. //
  13068. // We can best understand the basic idea by first considering a simpler problem
  13069. // that has the same essential characteristics. Given a sequence of digits,
  13070. // say $3\,1\,4\,1\,5\,9\,2\,6\,5\,3\,5\,8\,9$, we want to assign subscripts
  13071. // $d$, $y$, or $z$ to each digit so as to maximize the number of ``$y$-hits''
  13072. // and ``$z$-hits''; a $y$-hit is an instance of two appearances of the same
  13073. // digit with the subscript $y$, where no $y$'s intervene between the two
  13074. // appearances, and a $z$-hit is defined similarly. For example, the sequence
  13075. // above could be decorated with subscripts as follows:
  13076. // $$3_z\,1_y\,4_d\,1_y\,5_y\,9_d\,2_d\,6_d\,5_y\,3_z\,5_y\,8_d\,9_d.$$
  13077. // There are three $y$-hits ($1_y\ldots1_y$ and $5_y\ldots5_y\ldots5_y$) and
  13078. // one $z$-hit ($3_z\ldots3_z$); there are no $d$-hits, since the two appearances
  13079. // of $9_d$ have $d$'s between them, but we don't count $d$-hits so it doesn't
  13080. // matter how many there are. These subscripts are analogous to the \.[DVI]
  13081. // commands called \\[down], $y$, and $z$, and the digits are analogous to
  13082. // different amounts of vertical motion; a $y$-hit or $z$-hit corresponds to
  13083. // the opportunity to use the one-byte commands |y0| or |z0| in a \.[DVI] file.
  13084. //
  13085. // \TeX's method of assigning subscripts works like this: Append a new digit,
  13086. // say $\delta$, to the right of the sequence. Now look back through the
  13087. // sequence until one of the following things happens: (a)~You see
  13088. // $\delta_y$ or $\delta_z$, and this was the first time you encountered a
  13089. // $y$ or $z$ subscript, respectively. Then assign $y$ or $z$ to the new
  13090. // $\delta$; you have scored a hit. (b)~You see $\delta_d$, and no $y$
  13091. // subscripts have been encountered so far during this search. Then change
  13092. // the previous $\delta_d$ to $\delta_y$ (this corresponds to changing a
  13093. // command in the output buffer), and assign $y$ to the new $\delta$; it's
  13094. // another hit. (c)~You see $\delta_d$, and a $y$ subscript has been seen
  13095. // but not a $z$. Change the previous $\delta_d$ to $\delta_z$ and assign
  13096. // $z$ to the new $\delta$. (d)~You encounter both $y$ and $z$ subscripts
  13097. // before encountering a suitable $\delta$, or you scan all the way to the
  13098. // front of the sequence. Assign $d$ to the new $\delta$; this assignment may
  13099. // be changed later.
  13100. //
  13101. // The subscripts $3_z\,1_y\,4_d\ldots\,$ in the example above were, in fact,
  13102. // produced by this procedure, as the reader can verify. (Go ahead and try it.)
  13103. // 607.
  13104. // tangle:pos tex.web:12066:1:
  13105. // Here is a subroutine that produces a \.[DVI] command for some specified
  13106. // downward or rightward motion. It has two parameters: |w| is the amount
  13107. // of motion, and |o| is either |down1| or |right1|. We use the fact that
  13108. // the command codes have convenient arithmetic properties: |y1-down1=w1-right1|
  13109. // and |z1-down1=x1-right1|.
  13110. func (prg *prg) movement(w scaled, o eightBits) {
  13111. var (
  13112. mstate smallNumber // have we seen a |y| or |z|?
  13113. p, q halfword // current and top nodes on the stack
  13114. k int32 // index into |dvi_buf|, modulo |dvi_buf_size|
  13115. )
  13116. q = prg.getNode(movementNodeSize) // new node for the top of the stack
  13117. *prg.mem[int32(q)+widthOffset].int() = w
  13118. *prg.mem[int32(q)+2].int() = prg.dviOffset + int32(prg.dviPtr)
  13119. if int32(o) == down1 {
  13120. *(*prg.mem[q].hh()).rh() = prg.downPtr
  13121. prg.downPtr = q
  13122. } else {
  13123. *(*prg.mem[q].hh()).rh() = prg.rightPtr
  13124. prg.rightPtr = q
  13125. }
  13126. // Look at the other stack entries until deciding what sort of \.[DVI] command to generate; |goto found| if node |p| is a “hit”
  13127. p = *(*prg.mem[q].hh()).rh()
  13128. mstate = byte(noneSeen)
  13129. for int32(p) != 0 {
  13130. if *prg.mem[int32(p)+widthOffset].int() == w {
  13131. switch int32(mstate) + int32(*(*prg.mem[p].hh()).lh()) {
  13132. case noneSeen + 3, noneSeen + 4, zSeen + 3, zSeen + 4: //
  13133. if *prg.mem[int32(p)+2].int() < prg.dviGone {
  13134. goto notFound
  13135. } else {
  13136. // Change buffered instruction to |y| or |w| and |goto found|
  13137. k = *prg.mem[int32(p)+2].int() - prg.dviOffset
  13138. if k < 0 {
  13139. k = k + dviBufSize
  13140. }
  13141. prg.dviBuf[k] = byte(int32(prg.dviBuf[k]) + y1 - down1)
  13142. *(*prg.mem[p].hh()).lh() = uint16(yHere)
  13143. goto found
  13144. }
  13145. case noneSeen + 5, ySeen + 3, ySeen + 5: //
  13146. if *prg.mem[int32(p)+2].int() < prg.dviGone {
  13147. goto notFound
  13148. } else {
  13149. // Change buffered instruction to |z| or |x| and |goto found|
  13150. k = *prg.mem[int32(p)+2].int() - prg.dviOffset
  13151. if k < 0 {
  13152. k = k + dviBufSize
  13153. }
  13154. prg.dviBuf[k] = byte(int32(prg.dviBuf[k]) + z1 - down1)
  13155. *(*prg.mem[p].hh()).lh() = uint16(zHere)
  13156. goto found
  13157. }
  13158. case noneSeen + 1, noneSeen + 2, ySeen + 2, zSeen + 1:
  13159. goto found
  13160. default:
  13161. }
  13162. } else {
  13163. switch int32(mstate) + int32(*(*prg.mem[p].hh()).lh()) {
  13164. case noneSeen + 1:
  13165. mstate = byte(ySeen)
  13166. case noneSeen + 2:
  13167. mstate = byte(zSeen)
  13168. case ySeen + 2, zSeen + 1:
  13169. goto notFound
  13170. default:
  13171. }
  13172. }
  13173. p = *(*prg.mem[p].hh()).rh()
  13174. }
  13175. notFound:
  13176. ;
  13177. // Generate a |down| or |right| command for |w| and |return|
  13178. *(*prg.mem[q].hh()).lh() = uint16(yzOk)
  13179. if abs(w) >= 040000000 {
  13180. {
  13181. prg.dviBuf[prg.dviPtr] = byte(int32(o) + 3)
  13182. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13183. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13184. prg.dviSwap()
  13185. }
  13186. } // |down4| or |right4|
  13187. prg.dviFour(w)
  13188. goto exit
  13189. }
  13190. if abs(w) >= 0100000 {
  13191. {
  13192. prg.dviBuf[prg.dviPtr] = byte(int32(o) + 2)
  13193. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13194. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13195. prg.dviSwap()
  13196. }
  13197. } // |down3| or |right3|
  13198. if w < 0 {
  13199. w = w + 0100000000
  13200. }
  13201. {
  13202. prg.dviBuf[prg.dviPtr] = byte(w / 0200000)
  13203. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13204. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13205. prg.dviSwap()
  13206. }
  13207. }
  13208. w = w % 0200000
  13209. goto _2
  13210. }
  13211. if abs(w) >= 0200 {
  13212. {
  13213. prg.dviBuf[prg.dviPtr] = byte(int32(o) + 1)
  13214. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13215. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13216. prg.dviSwap()
  13217. }
  13218. } // |down2| or |right2|
  13219. if w < 0 {
  13220. w = w + 0200000
  13221. }
  13222. goto _2
  13223. }
  13224. {
  13225. prg.dviBuf[prg.dviPtr] = o
  13226. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13227. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13228. prg.dviSwap()
  13229. }
  13230. } // |down1| or |right1|
  13231. if w < 0 {
  13232. w = w + 0400
  13233. }
  13234. goto _1
  13235. _2:
  13236. {
  13237. prg.dviBuf[prg.dviPtr] = byte(w / 0400)
  13238. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13239. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13240. prg.dviSwap()
  13241. }
  13242. }
  13243. _1:
  13244. {
  13245. prg.dviBuf[prg.dviPtr] = byte(w % 0400)
  13246. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13247. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13248. prg.dviSwap()
  13249. }
  13250. }
  13251. goto exit
  13252. found:
  13253. *(*prg.mem[q].hh()).lh() = *(*prg.mem[p].hh()).lh()
  13254. if int32(*(*prg.mem[q].hh()).lh()) == yHere {
  13255. {
  13256. prg.dviBuf[prg.dviPtr] = byte(int32(o) + y0 - down1)
  13257. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13258. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13259. prg.dviSwap()
  13260. }
  13261. } // |y0| or |w0|
  13262. for int32(*(*prg.mem[q].hh()).rh()) != int32(p) {
  13263. q = *(*prg.mem[q].hh()).rh()
  13264. switch *(*prg.mem[q].hh()).lh() {
  13265. case yzOk:
  13266. *(*prg.mem[q].hh()).lh() = uint16(zOk)
  13267. case yOk:
  13268. *(*prg.mem[q].hh()).lh() = uint16(dFixed)
  13269. default:
  13270. }
  13271. }
  13272. } else {
  13273. {
  13274. prg.dviBuf[prg.dviPtr] = byte(int32(o) + z0 - down1)
  13275. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13276. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13277. prg.dviSwap()
  13278. }
  13279. } // |z0| or |x0|
  13280. for int32(*(*prg.mem[q].hh()).rh()) != int32(p) {
  13281. q = *(*prg.mem[q].hh()).rh()
  13282. switch *(*prg.mem[q].hh()).lh() {
  13283. case yzOk:
  13284. *(*prg.mem[q].hh()).lh() = uint16(yOk)
  13285. case zOk:
  13286. *(*prg.mem[q].hh()).lh() = uint16(dFixed)
  13287. default:
  13288. }
  13289. }
  13290. }
  13291. exit:
  13292. }
  13293. // 608.
  13294. // tangle:pos tex.web:12091:1:
  13295. // The |info| fields in the entries of the down stack or the right stack
  13296. // have six possible settings: |y_here| or |z_here| mean that the \.[DVI]
  13297. // command refers to |y| or |z|, respectively (or to |w| or |x|, in the
  13298. // case of horizontal motion); |yz_OK| means that the \.[DVI] command is
  13299. // \\[down] (or \\[right]) but can be changed to either |y| or |z| (or
  13300. // to either |w| or |x|); |y_OK| means that it is \\[down] and can be changed
  13301. // to |y| but not |z|; |z_OK| is similar; and |d_fixed| means it must stay
  13302. // \\[down].
  13303. //
  13304. // The four settings |yz_OK|, |y_OK|, |z_OK|, |d_fixed| would not need to
  13305. // be distinguished from each other if we were simply solving the
  13306. // digit-subscripting problem mentioned above. But in \TeX's case there is
  13307. // a complication because of the nested structure of |push| and |pop|
  13308. // commands. Suppose we add parentheses to the digit-subscripting problem,
  13309. // redefining hits so that $\delta_y\ldots \delta_y$ is a hit if all $y$'s between
  13310. // the $\delta$'s are enclosed in properly nested parentheses, and if the
  13311. // parenthesis level of the right-hand $\delta_y$ is deeper than or equal to
  13312. // that of the left-hand one. Thus, `(' and `)' correspond to `|push|'
  13313. // and `|pop|'. Now if we want to assign a subscript to the final 1 in the
  13314. // sequence
  13315. // $$2_y\,7_d\,1_d\,(\,8_z\,2_y\,8_z\,)\,1$$
  13316. // we cannot change the previous $1_d$ to $1_y$, since that would invalidate
  13317. // the $2_y\ldots2_y$ hit. But we can change it to $1_z$, scoring a hit
  13318. // since the intervening $8_z$'s are enclosed in parentheses.
  13319. //
  13320. // The program below removes movement nodes that are introduced after a |push|,
  13321. // before it outputs the corresponding |pop|.
  13322. // 615.
  13323. // tangle:pos tex.web:12233:1:
  13324. // In case you are wondering when all the movement nodes are removed from
  13325. // \TeX's memory, the answer is that they are recycled just before
  13326. // |hlist_out| and |vlist_out| finish outputting a box. This restores the
  13327. // down and right stacks to the state they were in before the box was output,
  13328. // except that some |info|'s may have become more restrictive.
  13329. func (prg *prg) pruneMovements(l int32) {
  13330. var (
  13331. p halfword // node being deleted
  13332. )
  13333. for int32(prg.downPtr) != 0 {
  13334. if *prg.mem[int32(prg.downPtr)+2].int() < l {
  13335. goto done
  13336. }
  13337. p = prg.downPtr
  13338. prg.downPtr = *(*prg.mem[p].hh()).rh()
  13339. prg.freeNode(p, halfword(movementNodeSize))
  13340. }
  13341. done:
  13342. for int32(prg.rightPtr) != 0 {
  13343. if *prg.mem[int32(prg.rightPtr)+2].int() < l {
  13344. goto exit
  13345. }
  13346. p = prg.rightPtr
  13347. prg.rightPtr = *(*prg.mem[p].hh()).rh()
  13348. prg.freeNode(p, halfword(movementNodeSize))
  13349. }
  13350. exit:
  13351. } // |hlist_out| and |vlist_out| are mutually
  13352. // recursive
  13353. // 619.
  13354. // tangle:pos tex.web:12319:1:
  13355. // The recursive procedures |hlist_out| and |vlist_out| each have local variables
  13356. // |save_h| and |save_v| to hold the values of |dvi_h| and |dvi_v| just before
  13357. // entering a new level of recursion. In effect, the values of |save_h| and
  13358. // |save_v| on \TeX's run-time stack correspond to the values of |h| and |v|
  13359. // that a \.[DVI]-reading program will push onto its coordinate stack.
  13360. // \4
  13361. // Declare procedures needed in |hlist_out|, |vlist_out|
  13362. func (prg *prg) specialOut(p halfword) {
  13363. var (
  13364. oldSetting/* 0..maxSelector */ byte // holds print |selector|
  13365. k poolPointer // index into |str_pool|
  13366. )
  13367. if prg.curH != prg.dviH {
  13368. prg.movement(prg.curH-prg.dviH, eightBits(right1))
  13369. prg.dviH = prg.curH
  13370. }
  13371. if prg.curV != prg.dviV {
  13372. prg.movement(prg.curV-prg.dviV, eightBits(down1))
  13373. prg.dviV = prg.curV
  13374. }
  13375. oldSetting = prg.selector
  13376. prg.selector = byte(newString)
  13377. prg.showTokenList(int32(*(*prg.mem[*(*prg.mem[int32(p)+1].hh()).rh()].hh()).rh()), 0, poolSize-int32(prg.poolPtr))
  13378. prg.selector = oldSetting
  13379. {
  13380. if int32(prg.poolPtr)+1 > poolSize {
  13381. prg.overflow(strNumber( /* "pool size" */ 257), poolSize-int32(prg.initPoolPtr))
  13382. } /* \xref[TeX capacity exceeded pool size][\quad pool size] */
  13383. }
  13384. if int32(prg.poolPtr)-int32(prg.strStart[prg.strPtr]) < 256 {
  13385. {
  13386. prg.dviBuf[prg.dviPtr] = byte(xxx1)
  13387. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13388. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13389. prg.dviSwap()
  13390. }
  13391. }
  13392. {
  13393. prg.dviBuf[prg.dviPtr] = byte(int32(prg.poolPtr) - int32(prg.strStart[prg.strPtr]))
  13394. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13395. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13396. prg.dviSwap()
  13397. }
  13398. }
  13399. } else {
  13400. {
  13401. prg.dviBuf[prg.dviPtr] = byte(xxx4)
  13402. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13403. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13404. prg.dviSwap()
  13405. }
  13406. }
  13407. prg.dviFour(int32(prg.poolPtr) - int32(prg.strStart[prg.strPtr]))
  13408. }
  13409. for ii := int32(prg.strStart[prg.strPtr]); ii <= int32(prg.poolPtr)-1; ii++ {
  13410. k = poolPointer(ii)
  13411. _ = k
  13412. prg.dviBuf[prg.dviPtr] = prg.strPool[k]
  13413. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13414. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13415. prg.dviSwap()
  13416. }
  13417. }
  13418. prg.poolPtr = prg.strStart[prg.strPtr] // erase the string
  13419. }
  13420. func (prg *prg) writeOut(p halfword) {
  13421. var (
  13422. oldSetting/* 0..maxSelector */ byte // holds print |selector|
  13423. oldMode int32 // saved |mode|
  13424. j smallNumber // write stream number
  13425. q, r1 halfword // temporary variables for list manipulation
  13426. )
  13427. q = prg.getAvail()
  13428. *(*prg.mem[q].hh()).lh() = uint16(rightBraceToken + '}')
  13429. r1 = prg.getAvail()
  13430. *(*prg.mem[q].hh()).rh() = r1
  13431. *(*prg.mem[r1].hh()).lh() = uint16(07777 + endWrite)
  13432. prg.beginTokenList(q, quarterword(inserted))
  13433. prg.beginTokenList(*(*prg.mem[int32(p)+1].hh()).rh(), quarterword(writeText))
  13434. q = prg.getAvail()
  13435. *(*prg.mem[q].hh()).lh() = uint16(leftBraceToken + '{')
  13436. prg.beginTokenList(q, quarterword(inserted))
  13437. // now we're ready to scan
  13438. // `\.\[$\langle\,$token list$\,\rangle$\.[\] \\endwrite]'
  13439. oldMode = int32(prg.curList.modeField)
  13440. prg.curList.modeField = 0
  13441. // disable \.[\\prevdepth], \.[\\spacefactor], \.[\\lastskip], \.[\\prevgraf]
  13442. prg.curCs = prg.writeLoc
  13443. q = prg.scanToks(false, true) // expand macros, etc.
  13444. prg.getToken()
  13445. if int32(prg.curTok) != 07777+endWrite {
  13446. {
  13447. if int32(prg.interaction) == errorStopMode {
  13448. }
  13449. prg.printNl(strNumber( /* "! " */ 262))
  13450. prg.print( /* "Unbalanced write command" */ 1297)
  13451. }
  13452. // \xref[Unbalanced write...]
  13453. {
  13454. prg.helpPtr = 2
  13455. prg.helpLine[1] = /* "On this page there's a \\write with fewer real ['s than ]'s." */ 1298
  13456. prg.helpLine[0] = /* "I can't handle that very well; good luck." */ 1012
  13457. }
  13458. prg.error1()
  13459. for {
  13460. prg.getToken()
  13461. if int32(prg.curTok) == 07777+endWrite {
  13462. break
  13463. }
  13464. }
  13465. }
  13466. prg.curList.modeField = int16(oldMode)
  13467. prg.endTokenList()
  13468. oldSetting = prg.selector
  13469. j = byte(*(*prg.mem[int32(p)+1].hh()).lh())
  13470. if prg.writeOpen[j] {
  13471. prg.selector = j
  13472. } else {
  13473. if int32(j) == 17 && int32(prg.selector) == termAndLog {
  13474. prg.selector = byte(logOnly)
  13475. }
  13476. prg.printNl(strNumber( /* "" */ 338))
  13477. }
  13478. prg.tokenShow(prg.defRef)
  13479. prg.printLn()
  13480. prg.flushList(prg.defRef)
  13481. prg.selector = oldSetting
  13482. }
  13483. func (prg *prg) outWhat(p halfword) {
  13484. var (
  13485. j smallNumber // write stream number
  13486. )
  13487. switch *(*prg.mem[p].hh()).b1() {
  13488. case openNode, writeNode, closeNode:
  13489. // Do some work that has been queued up for \.[\\write]
  13490. if !prg.doingLeaders {
  13491. j = byte(*(*prg.mem[int32(p)+1].hh()).lh())
  13492. if int32(*(*prg.mem[p].hh()).b1()) == writeNode {
  13493. prg.writeOut(p)
  13494. } else {
  13495. if prg.writeOpen[j] {
  13496. prg.aClose(prg.writeFile[j])
  13497. }
  13498. if int32(*(*prg.mem[p].hh()).b1()) == closeNode {
  13499. prg.writeOpen[j] = false
  13500. } else if int32(j) < 16 {
  13501. prg.curName = *(*prg.mem[int32(p)+1].hh()).rh()
  13502. prg.curArea = *(*prg.mem[int32(p)+2].hh()).lh()
  13503. prg.curExt = *(*prg.mem[int32(p)+2].hh()).rh()
  13504. if int32(prg.curExt) == 338 {
  13505. prg.curExt = /* ".tex" */ 791
  13506. }
  13507. prg.packFileName(prg.curName, prg.curArea, prg.curExt)
  13508. for !prg.aOpenOut(prg.writeFile[j]) {
  13509. prg.promptFileName(strNumber( /* "output file name" */ 1300), strNumber( /* ".tex" */ 791))
  13510. }
  13511. prg.writeOpen[j] = true
  13512. }
  13513. }
  13514. }
  13515. case specialNode:
  13516. prg.specialOut(p)
  13517. case languageNode:
  13518. default:
  13519. prg.confusion(strNumber( /* "ext4" */ 1299))
  13520. // \xref[this can't happen ext4][\quad ext4]
  13521. }
  13522. }
  13523. //
  13524. func (prg *prg) hlistOut() {
  13525. var (
  13526. baseLine scaled // the baseline coordinate for this box
  13527. leftEdge scaled // the left coordinate for this box
  13528. saveH, saveV scaled // what |dvi_h| and |dvi_v| should pop to
  13529. thisBox halfword // pointer to containing box
  13530. gOrder glueOrd // applicable order of infinity for glue
  13531. gSign/* normal..shrinking */ byte // selects type of glue
  13532. p halfword // current position in the hlist
  13533. saveLoc int32 // \.[DVI] byte location upon entry
  13534. leaderBox halfword // the leader box being replicated
  13535. leaderWd scaled // width of leader box being replicated
  13536. lx scaled // extra space between leader boxes
  13537. outerDoingLeaders bool // were we doing leaders?
  13538. edge scaled // left edge of sub-box, or right edge of leader space
  13539. glueTemp float64 // glue value before rounding
  13540. curGlue float64 // glue seen so far
  13541. curG scaled // rounded equivalent of |cur_glue| times the glue ratio
  13542. )
  13543. curG = 0
  13544. curGlue = 0.0
  13545. thisBox = prg.tempPtr
  13546. gOrder = *(*prg.mem[int32(thisBox)+listOffset].hh()).b1()
  13547. gSign = *(*prg.mem[int32(thisBox)+listOffset].hh()).b0()
  13548. p = *(*prg.mem[int32(thisBox)+listOffset].hh()).rh()
  13549. prg.curS = prg.curS + 1
  13550. if prg.curS > 0 {
  13551. prg.dviBuf[prg.dviPtr] = byte(push)
  13552. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13553. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13554. prg.dviSwap()
  13555. }
  13556. }
  13557. if prg.curS > prg.maxPush {
  13558. prg.maxPush = prg.curS
  13559. }
  13560. saveLoc = prg.dviOffset + int32(prg.dviPtr)
  13561. baseLine = prg.curV
  13562. leftEdge = prg.curH
  13563. for int32(p) != 0 {
  13564. // Output node |p| for |hlist_out| and move to the next node, maintaining the condition |cur_v=base_line|
  13565. // Output node |p| for |hlist_out| and move to the next node, maintaining the condition |cur_v=base_line|
  13566. reswitch:
  13567. if int32(p) >= int32(prg.hiMemMin) {
  13568. if prg.curH != prg.dviH {
  13569. prg.movement(prg.curH-prg.dviH, eightBits(right1))
  13570. prg.dviH = prg.curH
  13571. }
  13572. if prg.curV != prg.dviV {
  13573. prg.movement(prg.curV-prg.dviV, eightBits(down1))
  13574. prg.dviV = prg.curV
  13575. }
  13576. for {
  13577. prg.f = *(*prg.mem[p].hh()).b0()
  13578. prg.c = *(*prg.mem[p].hh()).b1()
  13579. if int32(prg.f) != int32(prg.dviF) {
  13580. if !prg.fontUsed[prg.f] {
  13581. prg.dviFontDef(prg.f)
  13582. prg.fontUsed[prg.f] = true
  13583. }
  13584. if int32(prg.f) <= 64+fontBase {
  13585. prg.dviBuf[prg.dviPtr] = byte(int32(prg.f) - fontBase - 1 + fntNum0)
  13586. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13587. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13588. prg.dviSwap()
  13589. }
  13590. } else {
  13591. {
  13592. prg.dviBuf[prg.dviPtr] = byte(fnt1)
  13593. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13594. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13595. prg.dviSwap()
  13596. }
  13597. }
  13598. {
  13599. prg.dviBuf[prg.dviPtr] = byte(int32(prg.f) - fontBase - 1)
  13600. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13601. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13602. prg.dviSwap()
  13603. }
  13604. }
  13605. }
  13606. prg.dviF = prg.f
  13607. }
  13608. if int32(prg.c) >= 128+minQuarterword {
  13609. prg.dviBuf[prg.dviPtr] = byte(set1)
  13610. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13611. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13612. prg.dviSwap()
  13613. }
  13614. }
  13615. {
  13616. prg.dviBuf[prg.dviPtr] = byte(int32(prg.c) - minQuarterword)
  13617. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13618. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13619. prg.dviSwap()
  13620. }
  13621. }
  13622. prg.curH = prg.curH + *prg.fontInfo[prg.widthBase[prg.f]+int32((*prg.fontInfo[prg.charBase[prg.f]+int32(prg.c)].qqqq()).b0)].int()
  13623. p = *(*prg.mem[p].hh()).rh()
  13624. if !(int32(p) >= int32(prg.hiMemMin)) {
  13625. break
  13626. }
  13627. }
  13628. prg.dviH = prg.curH
  13629. } else {
  13630. // Output the non-|char_node| |p| for |hlist_out| and move to the next node
  13631. switch *(*prg.mem[p].hh()).b0() {
  13632. case hlistNode, vlistNode:
  13633. // Output a box in an hlist
  13634. if int32(*(*prg.mem[int32(p)+listOffset].hh()).rh()) == 0 {
  13635. prg.curH = prg.curH + *prg.mem[int32(p)+widthOffset].int()
  13636. } else {
  13637. saveH = prg.dviH
  13638. saveV = prg.dviV
  13639. prg.curV = baseLine + *prg.mem[int32(p)+4].int() // shift the box down
  13640. prg.tempPtr = p
  13641. edge = prg.curH
  13642. if int32(*(*prg.mem[p].hh()).b0()) == vlistNode {
  13643. prg.vlistOut()
  13644. } else {
  13645. prg.hlistOut()
  13646. }
  13647. prg.dviH = saveH
  13648. prg.dviV = saveV
  13649. prg.curH = edge + *prg.mem[int32(p)+widthOffset].int()
  13650. prg.curV = baseLine
  13651. }
  13652. case ruleNode:
  13653. prg.ruleHt = *prg.mem[int32(p)+heightOffset].int()
  13654. prg.ruleDp = *prg.mem[int32(p)+depthOffset].int()
  13655. prg.ruleWd = *prg.mem[int32(p)+widthOffset].int()
  13656. goto finRule
  13657. case whatsitNode:
  13658. // Output the whatsit node |p| in an hlist
  13659. prg.outWhat(p)
  13660. case glueNode:
  13661. // Move right or output leaders
  13662. prg.g = *(*prg.mem[int32(p)+1].hh()).lh()
  13663. prg.ruleWd = *prg.mem[int32(prg.g)+widthOffset].int() - curG
  13664. if int32(gSign) != normal {
  13665. if int32(gSign) == stretching {
  13666. if int32(*(*prg.mem[prg.g].hh()).b0()) == int32(gOrder) {
  13667. curGlue = curGlue + float64(*prg.mem[int32(prg.g)+2].int())
  13668. glueTemp = float64(*prg.mem[int32(thisBox)+glueOffset].gr()) * curGlue
  13669. if glueTemp > 1000000000.0 {
  13670. glueTemp = 1000000000.0
  13671. } else if glueTemp < -1000000000.0 {
  13672. glueTemp = -1000000000.0
  13673. }
  13674. // \xref[real multiplication]
  13675. curG = round(glueTemp)
  13676. }
  13677. } else if int32(*(*prg.mem[prg.g].hh()).b1()) == int32(gOrder) {
  13678. curGlue = curGlue - float64(*prg.mem[int32(prg.g)+3].int())
  13679. glueTemp = float64(*prg.mem[int32(thisBox)+glueOffset].gr()) * curGlue
  13680. if glueTemp > 1000000000.0 {
  13681. glueTemp = 1000000000.0
  13682. } else if glueTemp < -1000000000.0 {
  13683. glueTemp = -1000000000.0
  13684. }
  13685. curG = round(glueTemp)
  13686. }
  13687. }
  13688. prg.ruleWd = prg.ruleWd + curG
  13689. if int32(*(*prg.mem[p].hh()).b1()) >= aLeaders {
  13690. leaderBox = *(*prg.mem[int32(p)+1].hh()).rh()
  13691. if int32(*(*prg.mem[leaderBox].hh()).b0()) == ruleNode {
  13692. prg.ruleHt = *prg.mem[int32(leaderBox)+heightOffset].int()
  13693. prg.ruleDp = *prg.mem[int32(leaderBox)+depthOffset].int()
  13694. goto finRule
  13695. }
  13696. leaderWd = *prg.mem[int32(leaderBox)+widthOffset].int()
  13697. if leaderWd > 0 && prg.ruleWd > 0 {
  13698. prg.ruleWd = prg.ruleWd + 10 // compensate for floating-point rounding
  13699. edge = prg.curH + prg.ruleWd
  13700. lx = 0
  13701. // Let |cur_h| be the position of the first box, and set |leader_wd+lx| to the spacing between corresponding parts of boxes
  13702. if int32(*(*prg.mem[p].hh()).b1()) == aLeaders {
  13703. saveH = prg.curH
  13704. prg.curH = leftEdge + leaderWd*((prg.curH-leftEdge)/leaderWd)
  13705. if prg.curH < saveH {
  13706. prg.curH = prg.curH + leaderWd
  13707. }
  13708. } else {
  13709. prg.lq = prg.ruleWd / leaderWd // the number of box copies
  13710. prg.lr = prg.ruleWd % leaderWd // the remaining space
  13711. if int32(*(*prg.mem[p].hh()).b1()) == cLeaders {
  13712. prg.curH = prg.curH + prg.lr/2
  13713. } else {
  13714. lx = prg.lr / (prg.lq + 1)
  13715. prg.curH = prg.curH + (prg.lr-(prg.lq-1)*lx)/2
  13716. }
  13717. }
  13718. for prg.curH+leaderWd <= edge {
  13719. // Output a leader box at |cur_h|, then advance |cur_h| by |leader_wd+lx|
  13720. prg.curV = baseLine + *prg.mem[int32(leaderBox)+4].int()
  13721. if prg.curV != prg.dviV {
  13722. prg.movement(prg.curV-prg.dviV, eightBits(down1))
  13723. prg.dviV = prg.curV
  13724. }
  13725. saveV = prg.dviV
  13726. if prg.curH != prg.dviH {
  13727. prg.movement(prg.curH-prg.dviH, eightBits(right1))
  13728. prg.dviH = prg.curH
  13729. }
  13730. saveH = prg.dviH
  13731. prg.tempPtr = leaderBox
  13732. outerDoingLeaders = prg.doingLeaders
  13733. prg.doingLeaders = true
  13734. if int32(*(*prg.mem[leaderBox].hh()).b0()) == vlistNode {
  13735. prg.vlistOut()
  13736. } else {
  13737. prg.hlistOut()
  13738. }
  13739. prg.doingLeaders = outerDoingLeaders
  13740. prg.dviV = saveV
  13741. prg.dviH = saveH
  13742. prg.curV = baseLine
  13743. prg.curH = saveH + leaderWd + lx
  13744. }
  13745. prg.curH = edge - 10
  13746. goto nextP
  13747. }
  13748. }
  13749. goto movePast
  13750. case kernNode, mathNode:
  13751. prg.curH = prg.curH + *prg.mem[int32(p)+widthOffset].int()
  13752. case ligatureNode:
  13753. // Make node |p| look like a |char_node| and |goto reswitch|
  13754. prg.mem[30000-12] = prg.mem[int32(p)+1]
  13755. *(*prg.mem[30000-12].hh()).rh() = *(*prg.mem[p].hh()).rh()
  13756. p = uint16(30000 - 12)
  13757. goto reswitch
  13758. default:
  13759. }
  13760. goto nextP
  13761. finRule:
  13762. if prg.ruleHt == -010000000000 {
  13763. prg.ruleHt = *prg.mem[int32(thisBox)+heightOffset].int()
  13764. }
  13765. if prg.ruleDp == -010000000000 {
  13766. prg.ruleDp = *prg.mem[int32(thisBox)+depthOffset].int()
  13767. }
  13768. prg.ruleHt = prg.ruleHt + prg.ruleDp // this is the rule thickness
  13769. if prg.ruleHt > 0 && prg.ruleWd > 0 {
  13770. if prg.curH != prg.dviH {
  13771. prg.movement(prg.curH-prg.dviH, eightBits(right1))
  13772. prg.dviH = prg.curH
  13773. }
  13774. prg.curV = baseLine + prg.ruleDp
  13775. if prg.curV != prg.dviV {
  13776. prg.movement(prg.curV-prg.dviV, eightBits(down1))
  13777. prg.dviV = prg.curV
  13778. }
  13779. {
  13780. prg.dviBuf[prg.dviPtr] = byte(setRule)
  13781. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13782. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13783. prg.dviSwap()
  13784. }
  13785. }
  13786. prg.dviFour(prg.ruleHt)
  13787. prg.dviFour(prg.ruleWd)
  13788. prg.curV = baseLine
  13789. prg.dviH = prg.dviH + prg.ruleWd
  13790. }
  13791. movePast:
  13792. prg.curH = prg.curH + prg.ruleWd
  13793. nextP:
  13794. p = *(*prg.mem[p].hh()).rh()
  13795. }
  13796. }
  13797. prg.pruneMovements(saveLoc)
  13798. if prg.curS > 0 {
  13799. prg.dviPop(saveLoc)
  13800. }
  13801. prg.curS = prg.curS - 1
  13802. }
  13803. // 618.
  13804. // tangle:pos tex.web:12307:1:
  13805. // When |hlist_out| is called, its duty is to output the box represented
  13806. // by the |hlist_node| pointed to by |temp_ptr|. The reference point of that
  13807. // box has coordinates |(cur_h,cur_v)|.
  13808. //
  13809. // Similarly, when |vlist_out| is called, its duty is to output the box represented
  13810. // by the |vlist_node| pointed to by |temp_ptr|. The reference point of that
  13811. // box has coordinates |(cur_h,cur_v)|.
  13812. // \xref[recursion]
  13813. func (prg *prg) vlistOut() {
  13814. var (
  13815. leftEdge scaled // the left coordinate for this box
  13816. topEdge scaled // the top coordinate for this box
  13817. saveH, saveV scaled // what |dvi_h| and |dvi_v| should pop to
  13818. thisBox halfword // pointer to containing box
  13819. gOrder glueOrd // applicable order of infinity for glue
  13820. gSign/* normal..shrinking */ byte // selects type of glue
  13821. p halfword // current position in the vlist
  13822. saveLoc int32 // \.[DVI] byte location upon entry
  13823. leaderBox halfword // the leader box being replicated
  13824. leaderHt scaled // height of leader box being replicated
  13825. lx scaled // extra space between leader boxes
  13826. outerDoingLeaders bool // were we doing leaders?
  13827. edge scaled // bottom boundary of leader space
  13828. glueTemp float64 // glue value before rounding
  13829. curGlue float64 // glue seen so far
  13830. curG scaled // rounded equivalent of |cur_glue| times the glue ratio
  13831. )
  13832. curG = 0
  13833. curGlue = 0.0
  13834. thisBox = prg.tempPtr
  13835. gOrder = *(*prg.mem[int32(thisBox)+listOffset].hh()).b1()
  13836. gSign = *(*prg.mem[int32(thisBox)+listOffset].hh()).b0()
  13837. p = *(*prg.mem[int32(thisBox)+listOffset].hh()).rh()
  13838. prg.curS = prg.curS + 1
  13839. if prg.curS > 0 {
  13840. prg.dviBuf[prg.dviPtr] = byte(push)
  13841. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  13842. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  13843. prg.dviSwap()
  13844. }
  13845. }
  13846. if prg.curS > prg.maxPush {
  13847. prg.maxPush = prg.curS
  13848. }
  13849. saveLoc = prg.dviOffset + int32(prg.dviPtr)
  13850. leftEdge = prg.curH
  13851. prg.curV = prg.curV - *prg.mem[int32(thisBox)+heightOffset].int()
  13852. topEdge = prg.curV
  13853. for int32(p) != 0 {
  13854. // Output node |p| for |vlist_out| and move to the next node, maintaining the condition |cur_h=left_edge|
  13855. if int32(p) >= int32(prg.hiMemMin) {
  13856. prg.confusion(strNumber( /* "vlistout" */ 828))
  13857. } else {
  13858. // Output the non-|char_node| |p| for |vlist_out|
  13859. switch *(*prg.mem[p].hh()).b0() {
  13860. case hlistNode, vlistNode:
  13861. // Output a box in a vlist
  13862. if int32(*(*prg.mem[int32(p)+listOffset].hh()).rh()) == 0 {
  13863. prg.curV = prg.curV + *prg.mem[int32(p)+heightOffset].int() + *prg.mem[int32(p)+depthOffset].int()
  13864. } else {
  13865. prg.curV = prg.curV + *prg.mem[int32(p)+heightOffset].int()
  13866. if prg.curV != prg.dviV {
  13867. prg.movement(prg.curV-prg.dviV, eightBits(down1))
  13868. prg.dviV = prg.curV
  13869. }
  13870. saveH = prg.dviH
  13871. saveV = prg.dviV
  13872. prg.curH = leftEdge + *prg.mem[int32(p)+4].int() // shift the box right
  13873. prg.tempPtr = p
  13874. if int32(*(*prg.mem[p].hh()).b0()) == vlistNode {
  13875. prg.vlistOut()
  13876. } else {
  13877. prg.hlistOut()
  13878. }
  13879. prg.dviH = saveH
  13880. prg.dviV = saveV
  13881. prg.curV = saveV + *prg.mem[int32(p)+depthOffset].int()
  13882. prg.curH = leftEdge
  13883. }
  13884. case ruleNode:
  13885. prg.ruleHt = *prg.mem[int32(p)+heightOffset].int()
  13886. prg.ruleDp = *prg.mem[int32(p)+depthOffset].int()
  13887. prg.ruleWd = *prg.mem[int32(p)+widthOffset].int()
  13888. goto finRule
  13889. case whatsitNode:
  13890. // Output the whatsit node |p| in a vlist
  13891. prg.outWhat(p)
  13892. case glueNode:
  13893. // Move down or output leaders
  13894. prg.g = *(*prg.mem[int32(p)+1].hh()).lh()
  13895. prg.ruleHt = *prg.mem[int32(prg.g)+widthOffset].int() - curG
  13896. if int32(gSign) != normal {
  13897. if int32(gSign) == stretching {
  13898. if int32(*(*prg.mem[prg.g].hh()).b0()) == int32(gOrder) {
  13899. curGlue = curGlue + float64(*prg.mem[int32(prg.g)+2].int())
  13900. glueTemp = float64(*prg.mem[int32(thisBox)+glueOffset].gr()) * curGlue
  13901. if glueTemp > 1000000000.0 {
  13902. glueTemp = 1000000000.0
  13903. } else if glueTemp < -1000000000.0 {
  13904. glueTemp = -1000000000.0
  13905. }
  13906. // \xref[real multiplication]
  13907. curG = round(glueTemp)
  13908. }
  13909. } else if int32(*(*prg.mem[prg.g].hh()).b1()) == int32(gOrder) {
  13910. curGlue = curGlue - float64(*prg.mem[int32(prg.g)+3].int())
  13911. glueTemp = float64(*prg.mem[int32(thisBox)+glueOffset].gr()) * curGlue
  13912. if glueTemp > 1000000000.0 {
  13913. glueTemp = 1000000000.0
  13914. } else if glueTemp < -1000000000.0 {
  13915. glueTemp = -1000000000.0
  13916. }
  13917. curG = round(glueTemp)
  13918. }
  13919. }
  13920. prg.ruleHt = prg.ruleHt + curG
  13921. if int32(*(*prg.mem[p].hh()).b1()) >= aLeaders {
  13922. leaderBox = *(*prg.mem[int32(p)+1].hh()).rh()
  13923. if int32(*(*prg.mem[leaderBox].hh()).b0()) == ruleNode {
  13924. prg.ruleWd = *prg.mem[int32(leaderBox)+widthOffset].int()
  13925. prg.ruleDp = 0
  13926. goto finRule
  13927. }
  13928. leaderHt = *prg.mem[int32(leaderBox)+heightOffset].int() + *prg.mem[int32(leaderBox)+depthOffset].int()
  13929. if leaderHt > 0 && prg.ruleHt > 0 {
  13930. prg.ruleHt = prg.ruleHt + 10 // compensate for floating-point rounding
  13931. edge = prg.curV + prg.ruleHt
  13932. lx = 0
  13933. // Let |cur_v| be the position of the first box, and set |leader_ht+lx| to the spacing between corresponding parts of boxes
  13934. if int32(*(*prg.mem[p].hh()).b1()) == aLeaders {
  13935. saveV = prg.curV
  13936. prg.curV = topEdge + leaderHt*((prg.curV-topEdge)/leaderHt)
  13937. if prg.curV < saveV {
  13938. prg.curV = prg.curV + leaderHt
  13939. }
  13940. } else {
  13941. prg.lq = prg.ruleHt / leaderHt // the number of box copies
  13942. prg.lr = prg.ruleHt % leaderHt // the remaining space
  13943. if int32(*(*prg.mem[p].hh()).b1()) == cLeaders {
  13944. prg.curV = prg.curV + prg.lr/2
  13945. } else {
  13946. lx = prg.lr / (prg.lq + 1)
  13947. prg.curV = prg.curV + (prg.lr-(prg.lq-1)*lx)/2
  13948. }
  13949. }
  13950. for prg.curV+leaderHt <= edge {
  13951. // Output a leader box at |cur_v|, then advance |cur_v| by |leader_ht+lx|
  13952. prg.curH = leftEdge + *prg.mem[int32(leaderBox)+4].int()
  13953. if prg.curH != prg.dviH {
  13954. prg.movement(prg.curH-prg.dviH, eightBits(right1))
  13955. prg.dviH = prg.curH
  13956. }
  13957. saveH = prg.dviH
  13958. prg.curV = prg.curV + *prg.mem[int32(leaderBox)+heightOffset].int()
  13959. if prg.curV != prg.dviV {
  13960. prg.movement(prg.curV-prg.dviV, eightBits(down1))
  13961. prg.dviV = prg.curV
  13962. }
  13963. saveV = prg.dviV
  13964. prg.tempPtr = leaderBox
  13965. outerDoingLeaders = prg.doingLeaders
  13966. prg.doingLeaders = true
  13967. if int32(*(*prg.mem[leaderBox].hh()).b0()) == vlistNode {
  13968. prg.vlistOut()
  13969. } else {
  13970. prg.hlistOut()
  13971. }
  13972. prg.doingLeaders = outerDoingLeaders
  13973. prg.dviV = saveV
  13974. prg.dviH = saveH
  13975. prg.curH = leftEdge
  13976. prg.curV = saveV - *prg.mem[int32(leaderBox)+heightOffset].int() + leaderHt + lx
  13977. }
  13978. prg.curV = edge - 10
  13979. goto nextP
  13980. }
  13981. }
  13982. goto movePast
  13983. case kernNode:
  13984. prg.curV = prg.curV + *prg.mem[int32(p)+widthOffset].int()
  13985. default:
  13986. }
  13987. goto nextP
  13988. finRule:
  13989. if prg.ruleWd == -010000000000 {
  13990. prg.ruleWd = *prg.mem[int32(thisBox)+widthOffset].int()
  13991. }
  13992. prg.ruleHt = prg.ruleHt + prg.ruleDp // this is the rule thickness
  13993. prg.curV = prg.curV + prg.ruleHt
  13994. if prg.ruleHt > 0 && prg.ruleWd > 0 {
  13995. if prg.curH != prg.dviH {
  13996. prg.movement(prg.curH-prg.dviH, eightBits(right1))
  13997. prg.dviH = prg.curH
  13998. }
  13999. if prg.curV != prg.dviV {
  14000. prg.movement(prg.curV-prg.dviV, eightBits(down1))
  14001. prg.dviV = prg.curV
  14002. }
  14003. {
  14004. prg.dviBuf[prg.dviPtr] = byte(putRule)
  14005. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  14006. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  14007. prg.dviSwap()
  14008. }
  14009. }
  14010. prg.dviFour(prg.ruleHt)
  14011. prg.dviFour(prg.ruleWd)
  14012. }
  14013. goto nextP
  14014. movePast:
  14015. prg.curV = prg.curV + prg.ruleHt
  14016. }
  14017. nextP:
  14018. p = *(*prg.mem[p].hh()).rh()
  14019. }
  14020. prg.pruneMovements(saveLoc)
  14021. if prg.curS > 0 {
  14022. prg.dviPop(saveLoc)
  14023. }
  14024. prg.curS = prg.curS - 1
  14025. }
  14026. // 638.
  14027. // tangle:pos tex.web:12678:1:
  14028. // The |hlist_out| and |vlist_out| procedures are now complete, so we are
  14029. // ready for the |ship_out| routine that gets them started in the first place.
  14030. func (prg *prg) shipOut(p halfword) {
  14031. var (
  14032. pageLoc int32 // location of the current |bop|
  14033. j, k/* 0..9 */ byte // indices to first ten count registers
  14034. s poolPointer // index into |str_pool|
  14035. oldSetting/* 0..maxSelector */ byte // saved |selector| setting
  14036. )
  14037. if *prg.eqtb[intBase+tracingOutputCode-1].int() > 0 {
  14038. prg.printNl(strNumber( /* "" */ 338))
  14039. prg.printLn()
  14040. prg.print( /* "Completed box being shipped out" */ 829)
  14041. // \xref[Completed box...]
  14042. }
  14043. if int32(prg.termOffset) > maxPrintLine-9 {
  14044. prg.printLn()
  14045. } else if int32(prg.termOffset) > 0 || int32(prg.fileOffset) > 0 {
  14046. prg.printChar(asciiCode(' '))
  14047. }
  14048. prg.printChar(asciiCode('['))
  14049. j = 9
  14050. for *prg.eqtb[countBase+int32(j)-1].int() == 0 && int32(j) > 0 {
  14051. j = byte(int32(j) - 1)
  14052. }
  14053. for ii := int32(0); ii <= int32(j); ii++ {
  14054. k = byte(ii)
  14055. _ = k
  14056. prg.printInt(*prg.eqtb[countBase+int32(k)-1].int())
  14057. if int32(k) < int32(j) {
  14058. prg.printChar(asciiCode('.'))
  14059. }
  14060. }
  14061. if *prg.eqtb[intBase+tracingOutputCode-1].int() > 0 {
  14062. prg.printChar(asciiCode(']'))
  14063. prg.beginDiagnostic()
  14064. prg.showBox(p)
  14065. prg.endDiagnostic(true)
  14066. }
  14067. // Ship box |p| out
  14068. // Update the values of |max_h| and |max_v|; but if the page is too large, |goto done|
  14069. if *prg.mem[int32(p)+heightOffset].int() > 07777777777 || *prg.mem[int32(p)+depthOffset].int() > 07777777777 || *prg.mem[int32(p)+heightOffset].int()+*prg.mem[int32(p)+depthOffset].int()+*prg.eqtb[dimenBase+vOffsetCode-1].int() > 07777777777 || *prg.mem[int32(p)+widthOffset].int()+*prg.eqtb[dimenBase+hOffsetCode-1].int() > 07777777777 {
  14070. {
  14071. if int32(prg.interaction) == errorStopMode {
  14072. }
  14073. prg.printNl(strNumber( /* "! " */ 262))
  14074. prg.print( /* "Huge page cannot be shipped out" */ 833)
  14075. }
  14076. // \xref[Huge page...]
  14077. {
  14078. prg.helpPtr = 2
  14079. prg.helpLine[1] = /* "The page just created is more than 18 feet tall or" */ 834
  14080. prg.helpLine[0] = /* "more than 18 feet wide, so I suspect something went wrong." */ 835
  14081. }
  14082. prg.error1()
  14083. if *prg.eqtb[intBase+tracingOutputCode-1].int() <= 0 {
  14084. prg.beginDiagnostic()
  14085. prg.printNl(strNumber( /* "The following box has been deleted:" */ 836))
  14086. // \xref[The following...deleted]
  14087. prg.showBox(p)
  14088. prg.endDiagnostic(true)
  14089. }
  14090. goto done
  14091. }
  14092. if *prg.mem[int32(p)+heightOffset].int()+*prg.mem[int32(p)+depthOffset].int()+*prg.eqtb[dimenBase+vOffsetCode-1].int() > prg.maxV {
  14093. prg.maxV = *prg.mem[int32(p)+heightOffset].int() + *prg.mem[int32(p)+depthOffset].int() + *prg.eqtb[dimenBase+vOffsetCode-1].int()
  14094. }
  14095. if *prg.mem[int32(p)+widthOffset].int()+*prg.eqtb[dimenBase+hOffsetCode-1].int() > prg.maxH {
  14096. prg.maxH = *prg.mem[int32(p)+widthOffset].int() + *prg.eqtb[dimenBase+hOffsetCode-1].int()
  14097. }
  14098. // Initialize variables as |ship_out| begins
  14099. prg.dviH = 0
  14100. prg.dviV = 0
  14101. prg.curH = *prg.eqtb[dimenBase+hOffsetCode-1].int()
  14102. prg.dviF = byte(fontBase)
  14103. if int32(prg.outputFileName) == 0 {
  14104. if int32(prg.jobName) == 0 {
  14105. prg.openLogFile()
  14106. }
  14107. prg.packJobName(strNumber( /* ".dvi" */ 794))
  14108. for !prg.bOpenOut(prg.dviFile) {
  14109. prg.promptFileName(strNumber( /* "file name for output" */ 795), strNumber( /* ".dvi" */ 794))
  14110. }
  14111. prg.outputFileName = prg.bMakeNameString(prg.dviFile)
  14112. }
  14113. if prg.totalPages == 0 {
  14114. {
  14115. prg.dviBuf[prg.dviPtr] = byte(pre)
  14116. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  14117. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  14118. prg.dviSwap()
  14119. }
  14120. }
  14121. {
  14122. prg.dviBuf[prg.dviPtr] = byte(idByte)
  14123. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  14124. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  14125. prg.dviSwap()
  14126. }
  14127. } // output the preamble
  14128. // \xref[preamble of \.[DVI] file]
  14129. prg.dviFour(25400000)
  14130. prg.dviFour(473628672) // conversion ratio for sp
  14131. prg.prepareMag()
  14132. prg.dviFour(*prg.eqtb[intBase+magCode-1].int()) // magnification factor is frozen
  14133. oldSetting = prg.selector
  14134. prg.selector = byte(newString)
  14135. prg.print( /* " TeX output " */ 827)
  14136. prg.printInt(*prg.eqtb[intBase+yearCode-1].int())
  14137. prg.printChar(asciiCode('.'))
  14138. prg.printTwo(*prg.eqtb[intBase+monthCode-1].int())
  14139. prg.printChar(asciiCode('.'))
  14140. prg.printTwo(*prg.eqtb[intBase+dayCode-1].int())
  14141. prg.printChar(asciiCode(':'))
  14142. prg.printTwo(*prg.eqtb[intBase+timeCode-1].int() / 60)
  14143. prg.printTwo(*prg.eqtb[intBase+timeCode-1].int() % 60)
  14144. prg.selector = oldSetting
  14145. {
  14146. prg.dviBuf[prg.dviPtr] = byte(int32(prg.poolPtr) - int32(prg.strStart[prg.strPtr]))
  14147. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  14148. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  14149. prg.dviSwap()
  14150. }
  14151. }
  14152. for ii := int32(prg.strStart[prg.strPtr]); ii <= int32(prg.poolPtr)-1; ii++ {
  14153. s = poolPointer(ii)
  14154. _ = s
  14155. prg.dviBuf[prg.dviPtr] = prg.strPool[s]
  14156. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  14157. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  14158. prg.dviSwap()
  14159. }
  14160. }
  14161. prg.poolPtr = prg.strStart[prg.strPtr] // flush the current string
  14162. }
  14163. pageLoc = prg.dviOffset + int32(prg.dviPtr)
  14164. {
  14165. prg.dviBuf[prg.dviPtr] = byte(bop)
  14166. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  14167. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  14168. prg.dviSwap()
  14169. }
  14170. }
  14171. for ii := int32(0); ii <= 9; ii++ {
  14172. k = byte(ii)
  14173. _ = k
  14174. prg.dviFour(*prg.eqtb[countBase+int32(k)-1].int())
  14175. }
  14176. prg.dviFour(prg.lastBop)
  14177. prg.lastBop = pageLoc
  14178. prg.curV = *prg.mem[int32(p)+heightOffset].int() + *prg.eqtb[dimenBase+vOffsetCode-1].int()
  14179. prg.tempPtr = p
  14180. if int32(*(*prg.mem[p].hh()).b0()) == vlistNode {
  14181. prg.vlistOut()
  14182. } else {
  14183. prg.hlistOut()
  14184. }
  14185. {
  14186. prg.dviBuf[prg.dviPtr] = byte(eop)
  14187. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  14188. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  14189. prg.dviSwap()
  14190. }
  14191. }
  14192. prg.totalPages = prg.totalPages + 1
  14193. prg.curS = -1
  14194. done:
  14195. ;
  14196. if *prg.eqtb[intBase+tracingOutputCode-1].int() <= 0 {
  14197. prg.printChar(asciiCode(']'))
  14198. }
  14199. prg.deadCycles = 0
  14200. // progress report
  14201. // Flush the box from memory, showing statistics if requested
  14202. // if eqtb[int_base+ tracing_stats_code].int >1 then
  14203. // begin print_nl(["Memory usage before: "=]830);
  14204. // [ \xref[Memory usage...] ]
  14205. // print_int(var_used); print_char(["&"=]38);
  14206. // print_int(dyn_used); print_char([";"=]59);
  14207. // end;
  14208. // [ ]
  14209. prg.flushNodeList(p)
  14210. // if eqtb[int_base+ tracing_stats_code].int >1 then
  14211. // begin print([" after: "=]831);
  14212. // print_int(var_used); print_char(["&"=]38);
  14213. // print_int(dyn_used); print(["; still untouched: "=]832);
  14214. // print_int(hi_mem_min-lo_mem_max-1); print_ln;
  14215. // end;
  14216. // [ ]
  14217. }
  14218. // 644. \[33] Packaging
  14219. // tangle:pos tex.web:12811:18:
  14220. // We're essentially done with the parts of \TeX\ that are concerned with
  14221. // the input (|get_next|) and the output (|ship_out|). So it's time to
  14222. // get heavily into the remaining part, which does the real work of typesetting.
  14223. //
  14224. // After lists are constructed, \TeX\ wraps them up and puts them into boxes.
  14225. // Two major subroutines are given the responsibility for this task: |hpack|
  14226. // applies to horizontal lists (hlists) and |vpack| applies to vertical lists
  14227. // (vlists). The main duty of |hpack| and |vpack| is to compute the dimensions
  14228. // of the resulting boxes, and to adjust the glue if one of those dimensions
  14229. // is pre-specified. The computed sizes normally enclose all of the material
  14230. // inside the new box; but some items may stick out if negative glue is used,
  14231. // if the box is overfull, or if a \.[\\vbox] includes other boxes that have
  14232. // been shifted left.
  14233. //
  14234. // The subroutine call |hpack(p,w,m)| returns a pointer to an |hlist_node|
  14235. // for a box containing the hlist that starts at |p|. Parameter |w| specifies
  14236. // a width; and parameter |m| is either `|exactly|' or `|additional|'. Thus,
  14237. // |hpack(p,w,exactly)| produces a box whose width is exactly |w|, while
  14238. // |hpack(p,w,additional)| yields a box whose width is the natural width plus
  14239. // |w|. It is convenient to define a macro called `|natural|' to cover the
  14240. // most common case, so that we can say |hpack(p,natural)| to get a box that
  14241. // has the natural width of list |p|.
  14242. //
  14243. // Similarly, |vpack(p,w,m)| returns a pointer to a |vlist_node| for a
  14244. // box containing the vlist that starts at |p|. In this case |w| represents
  14245. // a height instead of a width; the parameter |m| is interpreted as in |hpack|.
  14246. // 645.
  14247. // tangle:pos tex.web:12843:1:
  14248. // The parameters to |hpack| and |vpack| correspond to \TeX's primitives
  14249. // like `\.[\\hbox] \.[to] \.[300pt]', `\.[\\hbox] \.[spread] \.[10pt]'; note
  14250. // that `\.[\\hbox]' with no dimension following it is equivalent to
  14251. // `\.[\\hbox] \.[spread] \.[0pt]'. The |scan_spec| subroutine scans such
  14252. // constructions in the user's input, including the mandatory left brace that
  14253. // follows them, and it puts the specification onto |save_stack| so that the
  14254. // desired box can later be obtained by executing the following code:
  14255. // $$\vbox[\halign[#\hfil\cr
  14256. // |save_ptr:=save_ptr-2;|\cr
  14257. // |hpack(p,saved(1),saved(0)).|\cr]]$$
  14258. // Special care is necessary to ensure that the special |save_stack| codes
  14259. // are placed just below the new group code, because scanning can change
  14260. // |save_stack| when \.[\\csname] appears.
  14261. func (prg *prg) scanSpec(c groupCode, threeCodes bool) {
  14262. var (
  14263. s int32 // temporarily saved value
  14264. specCode/* exactly..additional */ byte
  14265. )
  14266. if threeCodes {
  14267. s = *prg.saveStack[int32(prg.savePtr)+0].int()
  14268. }
  14269. if prg.scanKeyword(strNumber( /* "to" */ 842)) {
  14270. specCode = byte(exactly)
  14271. } else if prg.scanKeyword(strNumber( /* "spread" */ 843)) {
  14272. specCode = byte(additional)
  14273. } else {
  14274. specCode = byte(additional)
  14275. prg.curVal = 0
  14276. goto found
  14277. }
  14278. prg.scanDimen(false, false, false)
  14279. found:
  14280. if threeCodes {
  14281. *prg.saveStack[int32(prg.savePtr)+0].int() = s
  14282. prg.savePtr = uint16(int32(prg.savePtr) + 1)
  14283. }
  14284. *prg.saveStack[int32(prg.savePtr)+0].int() = int32(specCode)
  14285. *prg.saveStack[int32(prg.savePtr)+1].int() = prg.curVal
  14286. prg.savePtr = uint16(int32(prg.savePtr) + 2)
  14287. prg.newSaveLevel(c)
  14288. prg.scanLeftBrace()
  14289. }
  14290. // 649.
  14291. // tangle:pos tex.web:12910:1:
  14292. // Here now is |hpack|, which contains few if any surprises.
  14293. func (prg *prg) hpack(p halfword, w scaled, m smallNumber) (r halfword) {
  14294. var (
  14295. r1 halfword // the box node that will be returned
  14296. q halfword // trails behind |p|
  14297. h, d, x scaled // height, depth, and natural width
  14298. s scaled // shift amount
  14299. g halfword // points to a glue specification
  14300. o glueOrd // order of infinity
  14301. f internalFontNumber // the font in a |char_node|
  14302. i fourQuarters // font information about a |char_node|
  14303. hd eightBits // height and depth indices for a character
  14304. )
  14305. prg.lastBadness = 0
  14306. r1 = prg.getNode(boxNodeSize)
  14307. *(*prg.mem[r1].hh()).b0() = byte(hlistNode)
  14308. *(*prg.mem[r1].hh()).b1() = byte(minQuarterword)
  14309. *prg.mem[int32(r1)+4].int() = 0
  14310. q = uint16(int32(r1) + listOffset)
  14311. *(*prg.mem[q].hh()).rh() = p
  14312. h = 0
  14313. // Clear dimensions to zero
  14314. d = 0
  14315. x = 0
  14316. prg.totalStretch[normal] = 0
  14317. prg.totalShrink[normal] = 0
  14318. prg.totalStretch[fil] = 0
  14319. prg.totalShrink[fil] = 0
  14320. prg.totalStretch[fill] = 0
  14321. prg.totalShrink[fill] = 0
  14322. prg.totalStretch[filll] = 0
  14323. prg.totalShrink[filll] = 0
  14324. for int32(p) != 0 {
  14325. // Examine node |p| in the hlist, taking account of its effect on the dimensions of the new box, or moving it to the adjustment list; then advance |p| to the next node
  14326. // \xref[inner loop]
  14327. reswitch:
  14328. for int32(p) >= int32(prg.hiMemMin) {
  14329. // Incorporate character dimensions into the dimensions of the hbox that will contain~it, then move to the next node
  14330. f = *(*prg.mem[p].hh()).b0()
  14331. i = *prg.fontInfo[prg.charBase[f]+int32(*(*prg.mem[p].hh()).b1())].qqqq()
  14332. hd = byte(int32(i.b1) - minQuarterword)
  14333. x = x + *prg.fontInfo[prg.widthBase[f]+int32(i.b0)].int()
  14334. s = *prg.fontInfo[prg.heightBase[f]+int32(hd)/16].int()
  14335. if s > h {
  14336. h = s
  14337. }
  14338. s = *prg.fontInfo[prg.depthBase[f]+int32(hd)%16].int()
  14339. if s > d {
  14340. d = s
  14341. }
  14342. p = *(*prg.mem[p].hh()).rh()
  14343. }
  14344. if int32(p) != 0 {
  14345. switch *(*prg.mem[p].hh()).b0() {
  14346. case hlistNode, vlistNode, ruleNode, unsetNode:
  14347. // Incorporate box dimensions into the dimensions of the hbox that will contain~it
  14348. x = x + *prg.mem[int32(p)+widthOffset].int()
  14349. if int32(*(*prg.mem[p].hh()).b0()) >= ruleNode {
  14350. s = 0
  14351. } else {
  14352. s = *prg.mem[int32(p)+4].int()
  14353. }
  14354. if *prg.mem[int32(p)+heightOffset].int()-s > h {
  14355. h = *prg.mem[int32(p)+heightOffset].int() - s
  14356. }
  14357. if *prg.mem[int32(p)+depthOffset].int()+s > d {
  14358. d = *prg.mem[int32(p)+depthOffset].int() + s
  14359. }
  14360. case insNode, markNode, adjustNode:
  14361. if int32(prg.adjustTail) != 0 {
  14362. for int32(*(*prg.mem[q].hh()).rh()) != int32(p) {
  14363. q = *(*prg.mem[q].hh()).rh()
  14364. }
  14365. if int32(*(*prg.mem[p].hh()).b0()) == adjustNode {
  14366. *(*prg.mem[prg.adjustTail].hh()).rh() = uint16(*prg.mem[int32(p)+1].int())
  14367. for int32(*(*prg.mem[prg.adjustTail].hh()).rh()) != 0 {
  14368. prg.adjustTail = *(*prg.mem[prg.adjustTail].hh()).rh()
  14369. }
  14370. p = *(*prg.mem[p].hh()).rh()
  14371. prg.freeNode(*(*prg.mem[q].hh()).rh(), halfword(smallNodeSize))
  14372. } else {
  14373. *(*prg.mem[prg.adjustTail].hh()).rh() = p
  14374. prg.adjustTail = p
  14375. p = *(*prg.mem[p].hh()).rh()
  14376. }
  14377. *(*prg.mem[q].hh()).rh() = p
  14378. p = q
  14379. }
  14380. case whatsitNode:
  14381. // Incorporate a whatsit node into an hbox
  14382. // Incorporate a whatsit node into an hbox
  14383. case glueNode:
  14384. // Incorporate glue into the horizontal totals
  14385. g = *(*prg.mem[int32(p)+1].hh()).lh()
  14386. x = x + *prg.mem[int32(g)+widthOffset].int()
  14387. o = *(*prg.mem[g].hh()).b0()
  14388. prg.totalStretch[o] = prg.totalStretch[o] + *prg.mem[int32(g)+2].int()
  14389. o = *(*prg.mem[g].hh()).b1()
  14390. prg.totalShrink[o] = prg.totalShrink[o] + *prg.mem[int32(g)+3].int()
  14391. if int32(*(*prg.mem[p].hh()).b1()) >= aLeaders {
  14392. g = *(*prg.mem[int32(p)+1].hh()).rh()
  14393. if *prg.mem[int32(g)+heightOffset].int() > h {
  14394. h = *prg.mem[int32(g)+heightOffset].int()
  14395. }
  14396. if *prg.mem[int32(g)+depthOffset].int() > d {
  14397. d = *prg.mem[int32(g)+depthOffset].int()
  14398. }
  14399. }
  14400. case kernNode, mathNode:
  14401. x = x + *prg.mem[int32(p)+widthOffset].int()
  14402. case ligatureNode:
  14403. // Make node |p| look like a |char_node| and |goto reswitch|
  14404. prg.mem[30000-12] = prg.mem[int32(p)+1]
  14405. *(*prg.mem[30000-12].hh()).rh() = *(*prg.mem[p].hh()).rh()
  14406. p = uint16(30000 - 12)
  14407. goto reswitch
  14408. default:
  14409. }
  14410. p = *(*prg.mem[p].hh()).rh()
  14411. }
  14412. }
  14413. if int32(prg.adjustTail) != 0 {
  14414. *(*prg.mem[prg.adjustTail].hh()).rh() = 0
  14415. }
  14416. *prg.mem[int32(r1)+heightOffset].int() = h
  14417. *prg.mem[int32(r1)+depthOffset].int() = d
  14418. // Determine the value of |width(r)| and the appropriate glue setting; then |return| or |goto common_ending|
  14419. if int32(m) == additional {
  14420. w = x + w
  14421. }
  14422. *prg.mem[int32(r1)+widthOffset].int() = w
  14423. x = w - x // now |x| is the excess to be made up
  14424. if x == 0 {
  14425. *(*prg.mem[int32(r1)+listOffset].hh()).b0() = byte(normal)
  14426. *(*prg.mem[int32(r1)+listOffset].hh()).b1() = byte(normal)
  14427. *prg.mem[int32(r1)+glueOffset].gr() = float32(0.0)
  14428. goto exit
  14429. } else if x > 0 {
  14430. if prg.totalStretch[filll] != 0 {
  14431. o = byte(filll)
  14432. } else if prg.totalStretch[fill] != 0 {
  14433. o = byte(fill)
  14434. } else if prg.totalStretch[fil] != 0 {
  14435. o = byte(fil)
  14436. } else {
  14437. o = byte(normal)
  14438. }
  14439. *(*prg.mem[int32(r1)+listOffset].hh()).b1() = o
  14440. *(*prg.mem[int32(r1)+listOffset].hh()).b0() = byte(stretching)
  14441. if prg.totalStretch[o] != 0 {
  14442. *prg.mem[int32(r1)+glueOffset].gr() = float32(float64(x) / float64(prg.totalStretch[o]))
  14443. } else {
  14444. *(*prg.mem[int32(r1)+listOffset].hh()).b0() = byte(normal)
  14445. *prg.mem[int32(r1)+glueOffset].gr() = float32(0.0) // there's nothing to stretch
  14446. }
  14447. if int32(o) == normal {
  14448. if int32(*(*prg.mem[int32(r1)+listOffset].hh()).rh()) != 0 {
  14449. prg.lastBadness = int32(prg.badness(x, prg.totalStretch[normal]))
  14450. if prg.lastBadness > *prg.eqtb[intBase+hbadnessCode-1].int() {
  14451. prg.printLn()
  14452. if prg.lastBadness > 100 {
  14453. prg.printNl(strNumber( /* "Underfull" */ 844))
  14454. } else {
  14455. prg.printNl(strNumber( /* "Loose" */ 845))
  14456. }
  14457. prg.print( /* " \\hbox (badness " */ 846)
  14458. prg.printInt(prg.lastBadness)
  14459. // \xref[Underfull \\hbox...]
  14460. // \xref[Loose \\hbox...]
  14461. // \xref[Underfull \\hbox...]
  14462. // \xref[Loose \\hbox...]
  14463. goto commonEnding
  14464. }
  14465. }
  14466. }
  14467. goto exit
  14468. } else {
  14469. // Determine horizontal glue shrink setting, then |return| or \hbox[|goto common_ending|]
  14470. if prg.totalShrink[filll] != 0 {
  14471. o = byte(filll)
  14472. } else if prg.totalShrink[fill] != 0 {
  14473. o = byte(fill)
  14474. } else if prg.totalShrink[fil] != 0 {
  14475. o = byte(fil)
  14476. } else {
  14477. o = byte(normal)
  14478. }
  14479. *(*prg.mem[int32(r1)+listOffset].hh()).b1() = o
  14480. *(*prg.mem[int32(r1)+listOffset].hh()).b0() = byte(shrinking)
  14481. if prg.totalShrink[o] != 0 {
  14482. *prg.mem[int32(r1)+glueOffset].gr() = float32(float64(-x) / float64(prg.totalShrink[o]))
  14483. } else {
  14484. *(*prg.mem[int32(r1)+listOffset].hh()).b0() = byte(normal)
  14485. *prg.mem[int32(r1)+glueOffset].gr() = float32(0.0) // there's nothing to shrink
  14486. }
  14487. if prg.totalShrink[o] < -x && int32(o) == normal && int32(*(*prg.mem[int32(r1)+listOffset].hh()).rh()) != 0 {
  14488. prg.lastBadness = 1000000
  14489. *prg.mem[int32(r1)+glueOffset].gr() = float32(1.0) // use the maximum shrinkage
  14490. // Report an overfull hbox and |goto common_ending|, if this box is sufficiently bad
  14491. if -x-prg.totalShrink[normal] > *prg.eqtb[dimenBase+hfuzzCode-1].int() || *prg.eqtb[intBase+hbadnessCode-1].int() < 100 {
  14492. if *prg.eqtb[dimenBase+overfullRuleCode-1].int() > 0 && -x-prg.totalShrink[normal] > *prg.eqtb[dimenBase+hfuzzCode-1].int() {
  14493. for int32(*(*prg.mem[q].hh()).rh()) != 0 {
  14494. q = *(*prg.mem[q].hh()).rh()
  14495. }
  14496. *(*prg.mem[q].hh()).rh() = prg.newRule()
  14497. *prg.mem[int32(*(*prg.mem[q].hh()).rh())+widthOffset].int() = *prg.eqtb[dimenBase+overfullRuleCode-1].int()
  14498. }
  14499. prg.printLn()
  14500. prg.printNl(strNumber( /* "Overfull \\hbox (" */ 852))
  14501. // \xref[Overfull \\hbox...]
  14502. prg.printScaled(-x - prg.totalShrink[normal])
  14503. prg.print( /* "pt too wide" */ 853)
  14504. goto commonEnding
  14505. }
  14506. } else if int32(o) == normal {
  14507. if int32(*(*prg.mem[int32(r1)+listOffset].hh()).rh()) != 0 {
  14508. prg.lastBadness = int32(prg.badness(-x, prg.totalShrink[normal]))
  14509. if prg.lastBadness > *prg.eqtb[intBase+hbadnessCode-1].int() {
  14510. prg.printLn()
  14511. prg.printNl(strNumber( /* "Tight \\hbox (badness " */ 854))
  14512. prg.printInt(prg.lastBadness)
  14513. // \xref[Tight \\hbox...]
  14514. // \xref[Tight \\hbox...]
  14515. goto commonEnding
  14516. }
  14517. }
  14518. }
  14519. goto exit
  14520. }
  14521. commonEnding:
  14522. if prg.outputActive {
  14523. prg.print( /* ") has occurred while \\output is active" */ 847)
  14524. } else {
  14525. if prg.packBeginLine != 0 {
  14526. if prg.packBeginLine > 0 {
  14527. prg.print( /* ") in paragraph at lines " */ 848)
  14528. } else {
  14529. prg.print( /* ") in alignment at lines " */ 849)
  14530. }
  14531. prg.printInt(abs(prg.packBeginLine))
  14532. prg.print( /* "--" */ 850)
  14533. } else {
  14534. prg.print( /* ") detected at line " */ 851)
  14535. }
  14536. prg.printInt(prg.line)
  14537. }
  14538. prg.printLn()
  14539. prg.fontInShortDisplay = fontBase
  14540. prg.shortDisplay(int32(*(*prg.mem[int32(r1)+listOffset].hh()).rh()))
  14541. prg.printLn()
  14542. prg.beginDiagnostic()
  14543. prg.showBox(r1)
  14544. prg.endDiagnostic(true)
  14545. exit:
  14546. r = r1
  14547. return r
  14548. }
  14549. // 668.
  14550. // tangle:pos tex.web:13152:1:
  14551. // The |vpack| subroutine is actually a special case of a slightly more
  14552. // general routine called |vpackage|, which has four parameters. The fourth
  14553. // parameter, which is |max_dimen| in the case of |vpack|, specifies the
  14554. // maximum depth of the page box that is constructed. The depth is first
  14555. // computed by the normal rules; if it exceeds this limit, the reference
  14556. // point is simply moved down until the limiting depth is attained.
  14557. func (prg *prg) vpackage(p halfword, h scaled, m smallNumber, l scaled) (r halfword) {
  14558. var (
  14559. r1 halfword // the box node that will be returned
  14560. w, d, x scaled // width, depth, and natural height
  14561. s scaled // shift amount
  14562. g halfword // points to a glue specification
  14563. o glueOrd // order of infinity
  14564. )
  14565. prg.lastBadness = 0
  14566. r1 = prg.getNode(boxNodeSize)
  14567. *(*prg.mem[r1].hh()).b0() = byte(vlistNode)
  14568. *(*prg.mem[r1].hh()).b1() = byte(minQuarterword)
  14569. *prg.mem[int32(r1)+4].int() = 0
  14570. *(*prg.mem[int32(r1)+listOffset].hh()).rh() = p
  14571. w = 0
  14572. // Clear dimensions to zero
  14573. d = 0
  14574. x = 0
  14575. prg.totalStretch[normal] = 0
  14576. prg.totalShrink[normal] = 0
  14577. prg.totalStretch[fil] = 0
  14578. prg.totalShrink[fil] = 0
  14579. prg.totalStretch[fill] = 0
  14580. prg.totalShrink[fill] = 0
  14581. prg.totalStretch[filll] = 0
  14582. prg.totalShrink[filll] = 0
  14583. for int32(p) != 0 {
  14584. // Examine node |p| in the vlist, taking account of its effect on the dimensions of the new box; then advance |p| to the next node
  14585. if int32(p) >= int32(prg.hiMemMin) {
  14586. prg.confusion(strNumber( /* "vpack" */ 855))
  14587. } else {
  14588. switch *(*prg.mem[p].hh()).b0() {
  14589. case hlistNode, vlistNode, ruleNode, unsetNode:
  14590. // Incorporate box dimensions into the dimensions of the vbox that will contain~it
  14591. x = x + d + *prg.mem[int32(p)+heightOffset].int()
  14592. d = *prg.mem[int32(p)+depthOffset].int()
  14593. if int32(*(*prg.mem[p].hh()).b0()) >= ruleNode {
  14594. s = 0
  14595. } else {
  14596. s = *prg.mem[int32(p)+4].int()
  14597. }
  14598. if *prg.mem[int32(p)+widthOffset].int()+s > w {
  14599. w = *prg.mem[int32(p)+widthOffset].int() + s
  14600. }
  14601. case whatsitNode:
  14602. // Incorporate a whatsit node into a vbox
  14603. // Incorporate a whatsit node into a vbox
  14604. case glueNode:
  14605. // Incorporate glue into the vertical totals
  14606. x = x + d
  14607. d = 0
  14608. g = *(*prg.mem[int32(p)+1].hh()).lh()
  14609. x = x + *prg.mem[int32(g)+widthOffset].int()
  14610. o = *(*prg.mem[g].hh()).b0()
  14611. prg.totalStretch[o] = prg.totalStretch[o] + *prg.mem[int32(g)+2].int()
  14612. o = *(*prg.mem[g].hh()).b1()
  14613. prg.totalShrink[o] = prg.totalShrink[o] + *prg.mem[int32(g)+3].int()
  14614. if int32(*(*prg.mem[p].hh()).b1()) >= aLeaders {
  14615. g = *(*prg.mem[int32(p)+1].hh()).rh()
  14616. if *prg.mem[int32(g)+widthOffset].int() > w {
  14617. w = *prg.mem[int32(g)+widthOffset].int()
  14618. }
  14619. }
  14620. case kernNode:
  14621. x = x + d + *prg.mem[int32(p)+widthOffset].int()
  14622. d = 0
  14623. default:
  14624. }
  14625. }
  14626. p = *(*prg.mem[p].hh()).rh()
  14627. }
  14628. *prg.mem[int32(r1)+widthOffset].int() = w
  14629. if d > l {
  14630. x = x + d - l
  14631. *prg.mem[int32(r1)+depthOffset].int() = l
  14632. } else {
  14633. *prg.mem[int32(r1)+depthOffset].int() = d
  14634. }
  14635. // Determine the value of |height(r)| and the appropriate glue setting; then |return| or |goto common_ending|
  14636. if int32(m) == additional {
  14637. h = x + h
  14638. }
  14639. *prg.mem[int32(r1)+heightOffset].int() = h
  14640. x = h - x // now |x| is the excess to be made up
  14641. if x == 0 {
  14642. *(*prg.mem[int32(r1)+listOffset].hh()).b0() = byte(normal)
  14643. *(*prg.mem[int32(r1)+listOffset].hh()).b1() = byte(normal)
  14644. *prg.mem[int32(r1)+glueOffset].gr() = float32(0.0)
  14645. goto exit
  14646. } else if x > 0 {
  14647. if prg.totalStretch[filll] != 0 {
  14648. o = byte(filll)
  14649. } else if prg.totalStretch[fill] != 0 {
  14650. o = byte(fill)
  14651. } else if prg.totalStretch[fil] != 0 {
  14652. o = byte(fil)
  14653. } else {
  14654. o = byte(normal)
  14655. }
  14656. *(*prg.mem[int32(r1)+listOffset].hh()).b1() = o
  14657. *(*prg.mem[int32(r1)+listOffset].hh()).b0() = byte(stretching)
  14658. if prg.totalStretch[o] != 0 {
  14659. *prg.mem[int32(r1)+glueOffset].gr() = float32(float64(x) / float64(prg.totalStretch[o]))
  14660. } else {
  14661. *(*prg.mem[int32(r1)+listOffset].hh()).b0() = byte(normal)
  14662. *prg.mem[int32(r1)+glueOffset].gr() = float32(0.0) // there's nothing to stretch
  14663. }
  14664. if int32(o) == normal {
  14665. if int32(*(*prg.mem[int32(r1)+listOffset].hh()).rh()) != 0 {
  14666. prg.lastBadness = int32(prg.badness(x, prg.totalStretch[normal]))
  14667. if prg.lastBadness > *prg.eqtb[intBase+vbadnessCode-1].int() {
  14668. prg.printLn()
  14669. if prg.lastBadness > 100 {
  14670. prg.printNl(strNumber( /* "Underfull" */ 844))
  14671. } else {
  14672. prg.printNl(strNumber( /* "Loose" */ 845))
  14673. }
  14674. prg.print( /* " \\vbox (badness " */ 856)
  14675. prg.printInt(prg.lastBadness)
  14676. // \xref[Underfull \\vbox...]
  14677. // \xref[Loose \\vbox...]
  14678. // \xref[Underfull \\vbox...]
  14679. // \xref[Loose \\vbox...]
  14680. goto commonEnding
  14681. }
  14682. }
  14683. }
  14684. goto exit
  14685. } else {
  14686. // Determine vertical glue shrink setting, then |return| or \hbox[|goto common_ending|]
  14687. if prg.totalShrink[filll] != 0 {
  14688. o = byte(filll)
  14689. } else if prg.totalShrink[fill] != 0 {
  14690. o = byte(fill)
  14691. } else if prg.totalShrink[fil] != 0 {
  14692. o = byte(fil)
  14693. } else {
  14694. o = byte(normal)
  14695. }
  14696. *(*prg.mem[int32(r1)+listOffset].hh()).b1() = o
  14697. *(*prg.mem[int32(r1)+listOffset].hh()).b0() = byte(shrinking)
  14698. if prg.totalShrink[o] != 0 {
  14699. *prg.mem[int32(r1)+glueOffset].gr() = float32(float64(-x) / float64(prg.totalShrink[o]))
  14700. } else {
  14701. *(*prg.mem[int32(r1)+listOffset].hh()).b0() = byte(normal)
  14702. *prg.mem[int32(r1)+glueOffset].gr() = float32(0.0) // there's nothing to shrink
  14703. }
  14704. if prg.totalShrink[o] < -x && int32(o) == normal && int32(*(*prg.mem[int32(r1)+listOffset].hh()).rh()) != 0 {
  14705. prg.lastBadness = 1000000
  14706. *prg.mem[int32(r1)+glueOffset].gr() = float32(1.0) // use the maximum shrinkage
  14707. // Report an overfull vbox and |goto common_ending|, if this box is sufficiently bad
  14708. if -x-prg.totalShrink[normal] > *prg.eqtb[dimenBase+vfuzzCode-1].int() || *prg.eqtb[intBase+vbadnessCode-1].int() < 100 {
  14709. prg.printLn()
  14710. prg.printNl(strNumber( /* "Overfull \\vbox (" */ 857))
  14711. // \xref[Overfull \\vbox...]
  14712. prg.printScaled(-x - prg.totalShrink[normal])
  14713. prg.print( /* "pt too high" */ 858)
  14714. goto commonEnding
  14715. }
  14716. } else if int32(o) == normal {
  14717. if int32(*(*prg.mem[int32(r1)+listOffset].hh()).rh()) != 0 {
  14718. prg.lastBadness = int32(prg.badness(-x, prg.totalShrink[normal]))
  14719. if prg.lastBadness > *prg.eqtb[intBase+vbadnessCode-1].int() {
  14720. prg.printLn()
  14721. prg.printNl(strNumber( /* "Tight \\vbox (badness " */ 859))
  14722. prg.printInt(prg.lastBadness)
  14723. // \xref[Tight \\vbox...]
  14724. // \xref[Tight \\vbox...]
  14725. goto commonEnding
  14726. }
  14727. }
  14728. }
  14729. goto exit
  14730. }
  14731. commonEnding:
  14732. if prg.outputActive {
  14733. prg.print( /* ") has occurred while \\output is active" */ 847)
  14734. } else {
  14735. if prg.packBeginLine != 0 {
  14736. prg.print( /* ") in alignment at lines " */ 849)
  14737. prg.printInt(abs(prg.packBeginLine))
  14738. prg.print( /* "--" */ 850)
  14739. } else {
  14740. prg.print( /* ") detected at line " */ 851)
  14741. }
  14742. prg.printInt(prg.line)
  14743. prg.printLn()
  14744. }
  14745. prg.beginDiagnostic()
  14746. prg.showBox(r1)
  14747. prg.endDiagnostic(true)
  14748. exit:
  14749. r = r1
  14750. return r
  14751. }
  14752. // 679.
  14753. // tangle:pos tex.web:13312:1:
  14754. // When a box is being appended to the current vertical list, the
  14755. // baselineskip calculation is handled by the |append_to_vlist| routine.
  14756. func (prg *prg) appendToVlist(b halfword) {
  14757. var (
  14758. d scaled // deficiency of space between baselines
  14759. p halfword // a new glue node
  14760. )
  14761. if *prg.curList.auxField.int() > -65536000 {
  14762. d = *prg.mem[int32(*(*prg.eqtb[glueBase+baselineSkipCode-1].hh()).rh())+widthOffset].int() - *prg.curList.auxField.int() - *prg.mem[int32(b)+heightOffset].int()
  14763. if d < *prg.eqtb[dimenBase+lineSkipLimitCode-1].int() {
  14764. p = prg.newParamGlue(smallNumber(lineSkipCode))
  14765. } else {
  14766. p = prg.newSkipParam(smallNumber(baselineSkipCode))
  14767. *prg.mem[int32(prg.tempPtr)+widthOffset].int() = d // |temp_ptr=glue_ptr(p)|
  14768. }
  14769. *(*prg.mem[prg.curList.tailField].hh()).rh() = p
  14770. prg.curList.tailField = p
  14771. }
  14772. *(*prg.mem[prg.curList.tailField].hh()).rh() = b
  14773. prg.curList.tailField = b
  14774. *prg.curList.auxField.int() = *prg.mem[int32(b)+depthOffset].int()
  14775. }
  14776. // 680. \[34] Data structures for math mode
  14777. // tangle:pos tex.web:13329:38:
  14778. // When \TeX\ reads a formula that is enclosed between \.\$'s, it constructs an
  14779. // [\sl mlist], which is essentially a tree structure representing that
  14780. // formula. An mlist is a linear sequence of items, but we can regard it as
  14781. // a tree structure because mlists can appear within mlists. For example, many
  14782. // of the entries can be subscripted or superscripted, and such ``scripts''
  14783. // are mlists in their own right.
  14784. //
  14785. // An entire formula is parsed into such a tree before any of the actual
  14786. // typesetting is done, because the current style of type is usually not
  14787. // known until the formula has been fully scanned. For example, when the
  14788. // formula `\.[\$a+b \\over c+d\$]' is being read, there is no way to tell
  14789. // that `\.[a+b]' will be in script size until `\.[\\over]' has appeared.
  14790. //
  14791. // During the scanning process, each element of the mlist being built is
  14792. // classified as a relation, a binary operator, an open parenthesis, etc.,
  14793. // or as a construct like `\.[\\sqrt]' that must be built up. This classification
  14794. // appears in the mlist data structure.
  14795. //
  14796. // After a formula has been fully scanned, the mlist is converted to an hlist
  14797. // so that it can be incorporated into the surrounding text. This conversion is
  14798. // controlled by a recursive procedure that decides all of the appropriate
  14799. // styles by a ``top-down'' process starting at the outermost level and working
  14800. // in towards the subformulas. The formula is ultimately pasted together using
  14801. // combinations of horizontal and vertical boxes, with glue and penalty nodes
  14802. // inserted as necessary.
  14803. //
  14804. // An mlist is represented internally as a linked list consisting chiefly
  14805. // of ``noads'' (pronounced ``no-adds''), to distinguish them from the somewhat
  14806. // similar ``nodes'' in hlists and vlists. Certain kinds of ordinary nodes are
  14807. // allowed to appear in mlists together with the noads; \TeX\ tells the difference
  14808. // by means of the |type| field, since a noad's |type| is always greater than
  14809. // that of a node. An mlist does not contain character nodes, hlist nodes, vlist
  14810. // nodes, math nodes, ligature nodes,
  14811. // or unset nodes; in particular, each mlist item appears in the
  14812. // variable-size part of |mem|, so the |type| field is always present.
  14813. // 681.
  14814. // tangle:pos tex.web:13366:1:
  14815. // Each noad is four or more words long. The first word contains the |type|
  14816. // and |subtype| and |link| fields that are already so familiar to us; the
  14817. // second, third, and fourth words are called the noad's |nucleus|, |subscr|,
  14818. // and |supscr| fields.
  14819. //
  14820. // Consider, for example, the simple formula `\.[\$x\^2\$]', which would be
  14821. // parsed into an mlist containing a single element called an |ord_noad|.
  14822. // The |nucleus| of this noad is a representation of `\.x', the |subscr| is
  14823. // empty, and the |supscr| is a representation of `\.2'.
  14824. //
  14825. // The |nucleus|, |subscr|, and |supscr| fields are further broken into
  14826. // subfields. If |p| points to a noad, and if |q| is one of its principal
  14827. // fields (e.g., |q=subscr(p)|), there are several possibilities for the
  14828. // subfields, depending on the |math_type| of |q|.
  14829. //
  14830. // \yskip\hang|math_type(q)=math_char| means that |fam(q)| refers to one of
  14831. // the sixteen font families, and |character(q)| is the number of a character
  14832. // within a font of that family, as in a character node.
  14833. //
  14834. // \yskip\hang|math_type(q)=math_text_char| is similar, but the character is
  14835. // unsubscripted and unsuperscripted and it is followed immediately by another
  14836. // character from the same font. (This |math_type| setting appears only
  14837. // briefly during the processing; it is used to suppress unwanted italic
  14838. // corrections.)
  14839. //
  14840. // \yskip\hang|math_type(q)=empty| indicates a field with no value (the
  14841. // corresponding attribute of noad |p| is not present).
  14842. //
  14843. // \yskip\hang|math_type(q)=sub_box| means that |info(q)| points to a box
  14844. // node (either an |hlist_node| or a |vlist_node|) that should be used as the
  14845. // value of the field. The |shift_amount| in the subsidiary box node is the
  14846. // amount by which that box will be shifted downward.
  14847. //
  14848. // \yskip\hang|math_type(q)=sub_mlist| means that |info(q)| points to
  14849. // an mlist; the mlist must be converted to an hlist in order to obtain
  14850. // the value of this field.
  14851. //
  14852. // \yskip\noindent In the latter case, we might have |info(q)=null|. This
  14853. // is not the same as |math_type(q)=empty|; for example, `\.[\$P\_\[\]\$]'
  14854. // and `\.[\$P\$]' produce different results (the former will not have the
  14855. // ``italic correction'' added to the width of |P|, but the ``script skip''
  14856. // will be added).
  14857. //
  14858. // The definitions of subfields given here are evidently wasteful of space,
  14859. // since a halfword is being used for the |math_type| although only three
  14860. // bits would be needed. However, there are hardly ever many noads present at
  14861. // once, since they are soon converted to nodes that take up even more space,
  14862. // so we can afford to represent them in whatever way simplifies the
  14863. // programming.
  14864. // 682.
  14865. // tangle:pos tex.web:13427:1:
  14866. // Each portion of a formula is classified as Ord, Op, Bin, Rel, Open,
  14867. // Close, Punct, or Inner, for purposes of spacing and line breaking. An
  14868. // |ord_noad|, |op_noad|, |bin_noad|, |rel_noad|, |open_noad|, |close_noad|,
  14869. // |punct_noad|, or |inner_noad| is used to represent portions of the various
  14870. // types. For example, an `\.=' sign in a formula leads to the creation of a
  14871. // |rel_noad| whose |nucleus| field is a representation of an equals sign
  14872. // (usually |fam=0|, |character=@'75|). A formula preceded by \.[\\mathrel]
  14873. // also results in a |rel_noad|. When a |rel_noad| is followed by an
  14874. // |op_noad|, say, and possibly separated by one or more ordinary nodes (not
  14875. // noads), \TeX\ will insert a penalty node (with the current |rel_penalty|)
  14876. // just after the formula that corresponds to the |rel_noad|, unless there
  14877. // already was a penalty immediately following; and a ``thick space'' will be
  14878. // inserted just before the formula that corresponds to the |op_noad|.
  14879. //
  14880. // A noad of type |ord_noad|, |op_noad|, \dots, |inner_noad| usually
  14881. // has a |subtype=normal|. The only exception is that an |op_noad| might
  14882. // have |subtype=limits| or |no_limits|, if the normal positioning of
  14883. // limits has been overridden for this operator.
  14884. // 683.
  14885. // tangle:pos tex.web:13457:1:
  14886. // A |radical_noad| is five words long; the fifth word is the |left_delimiter|
  14887. // field, which usually represents a square root sign.
  14888. //
  14889. // A |fraction_noad| is six words long; it has a |right_delimiter| field
  14890. // as well as a |left_delimiter|.
  14891. //
  14892. // Delimiter fields are of type |four_quarters|, and they have four subfields
  14893. // called |small_fam|, |small_char|, |large_fam|, |large_char|. These subfields
  14894. // represent variable-size delimiters by giving the ``small'' and ``large''
  14895. // starting characters, as explained in Chapter~17 of [\sl The \TeX book].
  14896. // \xref[TeXbook][\sl The \TeX book]
  14897. //
  14898. // A |fraction_noad| is actually quite different from all other noads. Not
  14899. // only does it have six words, it has |thickness|, |denominator|, and
  14900. // |numerator| fields instead of |nucleus|, |subscr|, and |supscr|. The
  14901. // |thickness| is a scaled value that tells how thick to make a fraction
  14902. // rule; however, the special value |default_code| is used to stand for the
  14903. // |default_rule_thickness| of the current size. The |numerator| and
  14904. // |denominator| point to mlists that define a fraction; we always have
  14905. // $$\hbox[|math_type(numerator)=math_type(denominator)=sub_mlist|].$$ The
  14906. // |left_delimiter| and |right_delimiter| fields specify delimiters that will
  14907. // be placed at the left and right of the fraction. In this way, a
  14908. // |fraction_noad| is able to represent all of \TeX's operators \.[\\over],
  14909. // \.[\\atop], \.[\\above], \.[\\overwithdelims], \.[\\atopwithdelims], and
  14910. // \.[\\abovewithdelims].
  14911. // 686.
  14912. // tangle:pos tex.web:13511:1:
  14913. // The |new_noad| function creates an |ord_noad| that is completely null.
  14914. func (prg *prg) newNoad() (r halfword) {
  14915. var (
  14916. p halfword
  14917. )
  14918. p = prg.getNode(noadSize)
  14919. *(*prg.mem[p].hh()).b0() = byte(ordNoad)
  14920. *(*prg.mem[p].hh()).b1() = byte(normal)
  14921. *prg.mem[int32(p)+1].hh() = prg.emptyField
  14922. *prg.mem[int32(p)+3].hh() = prg.emptyField
  14923. *prg.mem[int32(p)+2].hh() = prg.emptyField
  14924. r = p
  14925. return r
  14926. }
  14927. // 687.
  14928. // tangle:pos tex.web:13523:1:
  14929. // A few more kinds of noads will complete the set: An |under_noad| has its
  14930. // nucleus underlined; an |over_noad| has it overlined. An |accent_noad| places
  14931. // an accent over its nucleus; the accent character appears as
  14932. // |fam(accent_chr(p))| and |character(accent_chr(p))|. A |vcenter_noad|
  14933. // centers its nucleus vertically with respect to the axis of the formula;
  14934. // in such noads we always have |math_type(nucleus(p))=sub_box|.
  14935. //
  14936. // And finally, we have |left_noad| and |right_noad| types, to implement
  14937. // \TeX's \.[\\left] and \.[\\right]. The |nucleus| of such noads is
  14938. // replaced by a |delimiter| field; thus, for example, `\.[\\left(]' produces
  14939. // a |left_noad| such that |delimiter(p)| holds the family and character
  14940. // codes for all left parentheses. A |left_noad| never appears in an mlist
  14941. // except as the first element, and a |right_noad| never appears in an mlist
  14942. // except as the last element; furthermore, we either have both a |left_noad|
  14943. // and a |right_noad|, or neither one is present. The |subscr| and |supscr|
  14944. // fields are always |empty| in a |left_noad| and a |right_noad|.
  14945. // 688.
  14946. // tangle:pos tex.web:13551:1:
  14947. // Math formulas can also contain instructions like \.[\\textstyle] that
  14948. // override \TeX's normal style rules. A |style_node| is inserted into the
  14949. // data structure to record such instructions; it is three words long, so it
  14950. // is considered a node instead of a noad. The |subtype| is either |display_style|
  14951. // or |text_style| or |script_style| or |script_script_style|. The
  14952. // second and third words of a |style_node| are not used, but they are
  14953. // present because a |choice_node| is converted to a |style_node|.
  14954. //
  14955. // \TeX\ uses even numbers 0, 2, 4, 6 to encode the basic styles
  14956. // |display_style|, \dots, |script_script_style|, and adds~1 to get the
  14957. // “cramped” versions of these styles. This gives a numerical order that
  14958. // is backwards from the convention of Appendix~G in [\sl The \TeX book\/];
  14959. // i.e., a smaller style has a larger numerical value.
  14960. // \xref[TeXbook][\sl The \TeX book]
  14961. func (prg *prg) newStyle(s smallNumber) (r halfword) { // create a style node
  14962. var (
  14963. p halfword // the new node
  14964. )
  14965. p = prg.getNode(styleNodeSize)
  14966. *(*prg.mem[p].hh()).b0() = byte(styleNode)
  14967. *(*prg.mem[p].hh()).b1() = s
  14968. *prg.mem[int32(p)+widthOffset].int() = 0
  14969. *prg.mem[int32(p)+depthOffset].int() = 0 // the |width| and |depth| are not used
  14970. r = p
  14971. return r
  14972. }
  14973. // 689.
  14974. // tangle:pos tex.web:13581:1:
  14975. // Finally, the \.[\\mathchoice] primitive creates a |choice_node|, which
  14976. // has special subfields |display_mlist|, |text_mlist|, |script_mlist|,
  14977. // and |script_script_mlist| pointing to the mlists for each style.
  14978. func (prg *prg) newChoice() (r halfword) { // create a choice node
  14979. var (
  14980. p halfword // the new node
  14981. )
  14982. p = prg.getNode(styleNodeSize)
  14983. *(*prg.mem[p].hh()).b0() = byte(choiceNode)
  14984. *(*prg.mem[p].hh()).b1() = 0 // the |subtype| is not used
  14985. *(*prg.mem[int32(p)+1].hh()).lh() = 0
  14986. *(*prg.mem[int32(p)+1].hh()).rh() = 0
  14987. *(*prg.mem[int32(p)+2].hh()).lh() = 0
  14988. *(*prg.mem[int32(p)+2].hh()).rh() = 0
  14989. r = p
  14990. return r
  14991. }
  14992. func (prg *prg) showInfo() {
  14993. prg.showNodeList(int32(*(*prg.mem[prg.tempPtr].hh()).lh()))
  14994. }
  14995. // 700.
  14996. // tangle:pos tex.web:13804:1:
  14997. // Before an mlist is converted to an hlist, \TeX\ makes sure that
  14998. // the fonts in family~2 have enough parameters to be math-symbol
  14999. // fonts, and that the fonts in family~3 have enough parameters to be
  15000. // math-extension fonts. The math-symbol parameters are referred to by using the
  15001. // following macros, which take a size code as their parameter; for example,
  15002. // |num1(cur_size)| gives the value of the |num1| parameter for the current size.
  15003. // \xref[parameters for symbols]
  15004. // \xref[font parameters]
  15005. // 701.
  15006. // tangle:pos tex.web:13835:1:
  15007. // The math-extension parameters have similar macros, but the size code is
  15008. // omitted (since it is always |cur_size| when we refer to such parameters).
  15009. // \xref[parameters for symbols]
  15010. // \xref[font parameters]
  15011. // 702.
  15012. // tangle:pos tex.web:13849:1:
  15013. // We also need to compute the change in style between mlists and their
  15014. // subsidiaries. The following macros define the subsidiary style for
  15015. // an overlined nucleus (|cramped_style|), for a subscript or a superscript
  15016. // (|sub_style| or |sup_style|), or for a numerator or denominator (|num_style|
  15017. // or |denom_style|).
  15018. // 704.
  15019. // tangle:pos tex.web:13870:1:
  15020. // Here is a function that returns a pointer to a rule node having a given
  15021. // thickness |t|. The rule will extend horizontally to the boundary of the vlist
  15022. // that eventually contains it.
  15023. func (prg *prg) fractionRule(t scaled) (r halfword) {
  15024. // construct the bar for a fraction
  15025. var (
  15026. p halfword // the new node
  15027. )
  15028. p = prg.newRule()
  15029. *prg.mem[int32(p)+heightOffset].int() = t
  15030. *prg.mem[int32(p)+depthOffset].int() = 0
  15031. r = p
  15032. return r
  15033. }
  15034. // 705.
  15035. // tangle:pos tex.web:13880:1:
  15036. // The |overbar| function returns a pointer to a vlist box that consists of
  15037. // a given box |b|, above which has been placed a kern of height |k| under a
  15038. // fraction rule of thickness |t| under additional space of height |t|.
  15039. func (prg *prg) overbar(b halfword, k, t scaled) (r halfword) {
  15040. var (
  15041. p, q halfword // nodes being constructed
  15042. )
  15043. p = prg.newKern(k)
  15044. *(*prg.mem[p].hh()).rh() = b
  15045. q = prg.fractionRule(t)
  15046. *(*prg.mem[q].hh()).rh() = p
  15047. p = prg.newKern(t)
  15048. *(*prg.mem[p].hh()).rh() = q
  15049. r = prg.vpackage(p, scaled(0), smallNumber(additional), scaled(07777777777))
  15050. return r
  15051. }
  15052. // 706.
  15053. // tangle:pos tex.web:13890:1:
  15054. // The |var_delimiter| function, which finds or constructs a sufficiently
  15055. // large delimiter, is the most interesting of the auxiliary functions that
  15056. // currently concern us. Given a pointer |d| to a delimiter field in some noad,
  15057. // together with a size code |s| and a vertical distance |v|, this function
  15058. // returns a pointer to a box that contains the smallest variant of |d| whose
  15059. // height plus depth is |v| or more. (And if no variant is large enough, it
  15060. // returns the largest available variant.) In particular, this routine will
  15061. // construct arbitrarily large delimiters from extensible components, if
  15062. // |d| leads to such characters.
  15063. //
  15064. // The value returned is a box whose |shift_amount| has been set so that
  15065. // the box is vertically centered with respect to the axis in the given size.
  15066. // If a built-up symbol is returned, the height of the box before shifting
  15067. // will be the height of its topmost component.
  15068. // \4
  15069. // Declare subprocedures for |var_delimiter|
  15070. func (prg *prg) charBox(f internalFontNumber, c quarterword) (r halfword) {
  15071. var (
  15072. q fourQuarters
  15073. hd eightBits // |height_depth| byte
  15074. b, p halfword // the new box and its character node
  15075. )
  15076. q = *prg.fontInfo[prg.charBase[f]+int32(c)].qqqq()
  15077. hd = byte(int32(q.b1) - minQuarterword)
  15078. b = prg.newNullBox()
  15079. *prg.mem[int32(b)+widthOffset].int() = *prg.fontInfo[prg.widthBase[f]+int32(q.b0)].int() + *prg.fontInfo[prg.italicBase[f]+(int32(q.b2)-minQuarterword)/4].int()
  15080. *prg.mem[int32(b)+heightOffset].int() = *prg.fontInfo[prg.heightBase[f]+int32(hd)/16].int()
  15081. *prg.mem[int32(b)+depthOffset].int() = *prg.fontInfo[prg.depthBase[f]+int32(hd)%16].int()
  15082. p = prg.getAvail()
  15083. *(*prg.mem[p].hh()).b1() = c
  15084. *(*prg.mem[p].hh()).b0() = f
  15085. *(*prg.mem[int32(b)+listOffset].hh()).rh() = p
  15086. r = b
  15087. return r
  15088. }
  15089. func (prg *prg) stackIntoBox(b halfword, f internalFontNumber,
  15090. c quarterword) {
  15091. var (
  15092. p halfword // new node placed into |b|
  15093. )
  15094. p = prg.charBox(f, c)
  15095. *(*prg.mem[p].hh()).rh() = *(*prg.mem[int32(b)+listOffset].hh()).rh()
  15096. *(*prg.mem[int32(b)+listOffset].hh()).rh() = p
  15097. *prg.mem[int32(b)+heightOffset].int() = *prg.mem[int32(p)+heightOffset].int()
  15098. }
  15099. func (prg *prg) heightPlusDepth(f internalFontNumber, c quarterword) (r scaled) {
  15100. var (
  15101. q fourQuarters
  15102. hd eightBits // |height_depth| byte
  15103. )
  15104. q = *prg.fontInfo[prg.charBase[f]+int32(c)].qqqq()
  15105. hd = byte(int32(q.b1) - minQuarterword)
  15106. r = *prg.fontInfo[prg.heightBase[f]+int32(hd)/16].int() + *prg.fontInfo[prg.depthBase[f]+int32(hd)%16].int()
  15107. return r
  15108. }
  15109. func (prg *prg) varDelimiter(d halfword, s smallNumber, v scaled) (r halfword) {
  15110. var (
  15111. b halfword // the box that will be constructed
  15112. f, g internalFontNumber // best-so-far and tentative font codes
  15113. c, x, y quarterword // best-so-far and tentative character codes
  15114. m, n int32 // the number of extensible pieces
  15115. u scaled // height-plus-depth of a tentative character
  15116. w scaled // largest height-plus-depth so far
  15117. q fourQuarters // character info
  15118. hd eightBits // height-depth byte
  15119. r1 fourQuarters // extensible pieces
  15120. z smallNumber // runs through font family members
  15121. largeAttempt bool // are we trying the ``large'' variant?
  15122. )
  15123. f = byte(fontBase)
  15124. w = 0
  15125. largeAttempt = false
  15126. z = (*prg.mem[d].qqqq()).b0
  15127. x = (*prg.mem[d].qqqq()).b1
  15128. for true {
  15129. if int32(z) != 0 || int32(x) != minQuarterword {
  15130. z = byte(int32(z) + int32(s) + 16)
  15131. for {
  15132. z = byte(int32(z) - 16)
  15133. g = byte(*(*prg.eqtb[mathFontBase+int32(z)-1].hh()).rh())
  15134. if int32(g) != fontBase {
  15135. y = x
  15136. if int32(y)-minQuarterword >= int32(prg.fontBc[g]) && int32(y)-minQuarterword <= int32(prg.fontEc[g]) {
  15137. continue1:
  15138. q = *prg.fontInfo[prg.charBase[g]+int32(y)].qqqq()
  15139. if int32(q.b0) > minQuarterword {
  15140. if (int32(q.b2)-minQuarterword)%4 == extTag {
  15141. f = g
  15142. c = y
  15143. goto found
  15144. }
  15145. hd = byte(int32(q.b1) - minQuarterword)
  15146. u = *prg.fontInfo[prg.heightBase[g]+int32(hd)/16].int() + *prg.fontInfo[prg.depthBase[g]+int32(hd)%16].int()
  15147. if u > w {
  15148. f = g
  15149. c = y
  15150. w = u
  15151. if u >= v {
  15152. goto found
  15153. }
  15154. }
  15155. if (int32(q.b2)-minQuarterword)%4 == listTag {
  15156. y = q.b3
  15157. goto continue1
  15158. }
  15159. }
  15160. }
  15161. }
  15162. if int32(z) < 16 {
  15163. break
  15164. }
  15165. }
  15166. }
  15167. if largeAttempt {
  15168. goto found
  15169. } // there were none large enough
  15170. largeAttempt = true
  15171. z = (*prg.mem[d].qqqq()).b2
  15172. x = (*prg.mem[d].qqqq()).b3
  15173. }
  15174. found:
  15175. if int32(f) != fontBase {
  15176. if (int32(q.b2)-minQuarterword)%4 == extTag {
  15177. b = prg.newNullBox()
  15178. *(*prg.mem[b].hh()).b0() = byte(vlistNode)
  15179. r1 = *prg.fontInfo[prg.extenBase[f]+int32(q.b3)].qqqq()
  15180. // Compute the minimum suitable height, |w|, and the corresponding number of extension steps, |n|; also set |width(b)|
  15181. c = r1.b3
  15182. u = prg.heightPlusDepth(f, c)
  15183. w = 0
  15184. q = *prg.fontInfo[prg.charBase[f]+int32(c)].qqqq()
  15185. *prg.mem[int32(b)+widthOffset].int() = *prg.fontInfo[prg.widthBase[f]+int32(q.b0)].int() + *prg.fontInfo[prg.italicBase[f]+(int32(q.b2)-minQuarterword)/4].int()
  15186. c = r1.b2
  15187. if int32(c) != minQuarterword {
  15188. w = w + prg.heightPlusDepth(f, c)
  15189. }
  15190. c = r1.b1
  15191. if int32(c) != minQuarterword {
  15192. w = w + prg.heightPlusDepth(f, c)
  15193. }
  15194. c = r1.b0
  15195. if int32(c) != minQuarterword {
  15196. w = w + prg.heightPlusDepth(f, c)
  15197. }
  15198. n = 0
  15199. if u > 0 {
  15200. for w < v {
  15201. w = w + u
  15202. n = n + 1
  15203. if int32(r1.b1) != minQuarterword {
  15204. w = w + u
  15205. }
  15206. }
  15207. }
  15208. c = r1.b2
  15209. if int32(c) != minQuarterword {
  15210. prg.stackIntoBox(b, f, c)
  15211. }
  15212. c = r1.b3
  15213. for ii := int32(1); ii <= n; ii++ {
  15214. m = ii
  15215. _ = m
  15216. prg.stackIntoBox(b, f, c)
  15217. }
  15218. c = r1.b1
  15219. if int32(c) != minQuarterword {
  15220. prg.stackIntoBox(b, f, c)
  15221. c = r1.b3
  15222. for ii := int32(1); ii <= n; ii++ {
  15223. m = ii
  15224. _ = m
  15225. prg.stackIntoBox(b, f, c)
  15226. }
  15227. }
  15228. c = r1.b0
  15229. if int32(c) != minQuarterword {
  15230. prg.stackIntoBox(b, f, c)
  15231. }
  15232. *prg.mem[int32(b)+depthOffset].int() = w - *prg.mem[int32(b)+heightOffset].int()
  15233. } else {
  15234. b = prg.charBox(f, c)
  15235. }
  15236. } else {
  15237. b = prg.newNullBox()
  15238. *prg.mem[int32(b)+widthOffset].int() = *prg.eqtb[dimenBase+nullDelimiterSpaceCode-1].int() // use this width if no delimiter was found
  15239. }
  15240. *prg.mem[int32(b)+4].int() = prg.half(*prg.mem[int32(b)+heightOffset].int()-*prg.mem[int32(b)+depthOffset].int()) - *prg.fontInfo[22+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(s)-1].hh()).rh()]].int()
  15241. r = b
  15242. return r
  15243. }
  15244. // 715.
  15245. // tangle:pos tex.web:14059:1:
  15246. // The next subroutine is much simpler; it is used for numerators and
  15247. // denominators of fractions as well as for displayed operators and
  15248. // their limits above and below. It takes a given box~|b| and
  15249. // changes it so that the new box is centered in a box of width~|w|.
  15250. // The centering is done by putting \.[\\hss] glue at the left and right
  15251. // of the list inside |b|, then packaging the new box; thus, the
  15252. // actual box might not really be centered, if it already contains
  15253. // infinite glue.
  15254. //
  15255. // The given box might contain a single character whose italic correction
  15256. // has been added to the width of the box; in this case a compensating
  15257. // kern is inserted.
  15258. func (prg *prg) rebox(b halfword, w scaled) (r halfword) {
  15259. var (
  15260. p halfword // temporary register for list manipulation
  15261. f internalFontNumber // font in a one-character box
  15262. v scaled // width of a character without italic correction
  15263. )
  15264. if *prg.mem[int32(b)+widthOffset].int() != w && int32(*(*prg.mem[int32(b)+listOffset].hh()).rh()) != 0 {
  15265. if int32(*(*prg.mem[b].hh()).b0()) == vlistNode {
  15266. b = prg.hpack(b, scaled(0), smallNumber(additional))
  15267. }
  15268. p = *(*prg.mem[int32(b)+listOffset].hh()).rh()
  15269. if int32(p) >= int32(prg.hiMemMin) && int32(*(*prg.mem[p].hh()).rh()) == 0 {
  15270. f = *(*prg.mem[p].hh()).b0()
  15271. v = *prg.fontInfo[prg.widthBase[f]+int32((*prg.fontInfo[prg.charBase[f]+int32(*(*prg.mem[p].hh()).b1())].qqqq()).b0)].int()
  15272. if v != *prg.mem[int32(b)+widthOffset].int() {
  15273. *(*prg.mem[p].hh()).rh() = prg.newKern(*prg.mem[int32(b)+widthOffset].int() - v)
  15274. }
  15275. }
  15276. prg.freeNode(b, halfword(boxNodeSize))
  15277. b = prg.newGlue(halfword(memBot + glueSpecSize + glueSpecSize + glueSpecSize))
  15278. *(*prg.mem[b].hh()).rh() = p
  15279. for int32(*(*prg.mem[p].hh()).rh()) != 0 {
  15280. p = *(*prg.mem[p].hh()).rh()
  15281. }
  15282. *(*prg.mem[p].hh()).rh() = prg.newGlue(halfword(memBot + glueSpecSize + glueSpecSize + glueSpecSize))
  15283. r = prg.hpack(b, w, smallNumber(exactly))
  15284. } else {
  15285. *prg.mem[int32(b)+widthOffset].int() = w
  15286. r = b
  15287. }
  15288. return r
  15289. }
  15290. // 716.
  15291. // tangle:pos tex.web:14093:1:
  15292. // Here is a subroutine that creates a new glue specification from another
  15293. // one that is expressed in `\.[mu]', given the value of the math unit.
  15294. func (prg *prg) mathGlue(g halfword, m scaled) (r halfword) {
  15295. var (
  15296. p halfword // the new glue specification
  15297. n int32 // integer part of |m|
  15298. f scaled // fraction part of |m|
  15299. )
  15300. n = prg.xOverN(m, 0200000)
  15301. f = prg.remainder
  15302. if f < 0 {
  15303. n = n - 1
  15304. f = f + 0200000
  15305. }
  15306. p = prg.getNode(glueSpecSize)
  15307. *prg.mem[int32(p)+widthOffset].int() = prg.multAndAdd(n, *prg.mem[int32(g)+widthOffset].int(), prg.xnOverD(*prg.mem[int32(g)+widthOffset].int(), f, 0200000), scaled(07777777777)) // convert \.[mu] to \.[pt]
  15308. *(*prg.mem[p].hh()).b0() = *(*prg.mem[g].hh()).b0()
  15309. if int32(*(*prg.mem[p].hh()).b0()) == normal {
  15310. *prg.mem[int32(p)+2].int() = prg.multAndAdd(n, *prg.mem[int32(g)+2].int(), prg.xnOverD(*prg.mem[int32(g)+2].int(), f, 0200000), scaled(07777777777))
  15311. } else {
  15312. *prg.mem[int32(p)+2].int() = *prg.mem[int32(g)+2].int()
  15313. }
  15314. *(*prg.mem[p].hh()).b1() = *(*prg.mem[g].hh()).b1()
  15315. if int32(*(*prg.mem[p].hh()).b1()) == normal {
  15316. *prg.mem[int32(p)+3].int() = prg.multAndAdd(n, *prg.mem[int32(g)+3].int(), prg.xnOverD(*prg.mem[int32(g)+3].int(), f, 0200000), scaled(07777777777))
  15317. } else {
  15318. *prg.mem[int32(p)+3].int() = *prg.mem[int32(g)+3].int()
  15319. }
  15320. r = p
  15321. return r
  15322. }
  15323. // 717.
  15324. // tangle:pos tex.web:14117:1:
  15325. // The |math_kern| subroutine removes |mu_glue| from a kern node, given
  15326. // the value of the math unit.
  15327. func (prg *prg) mathKern(p halfword, m scaled) {
  15328. var (
  15329. n int32 // integer part of |m|
  15330. f scaled // fraction part of |m|
  15331. )
  15332. if int32(*(*prg.mem[p].hh()).b1()) == muGlue {
  15333. n = prg.xOverN(m, 0200000)
  15334. f = prg.remainder
  15335. if f < 0 {
  15336. n = n - 1
  15337. f = f + 0200000
  15338. }
  15339. *prg.mem[int32(p)+widthOffset].int() = prg.multAndAdd(n, *prg.mem[int32(p)+widthOffset].int(), prg.xnOverD(*prg.mem[int32(p)+widthOffset].int(), f, 0200000), scaled(07777777777))
  15340. *(*prg.mem[p].hh()).b1() = byte(explicit)
  15341. }
  15342. }
  15343. // 718.
  15344. // tangle:pos tex.web:14132:1:
  15345. // Sometimes it is necessary to destroy an mlist. The following
  15346. // subroutine empties the current list, assuming that |abs(mode)=mmode|.
  15347. func (prg *prg) flushMath() {
  15348. prg.flushNodeList(*(*prg.mem[prg.curList.headField].hh()).rh())
  15349. prg.flushNodeList(halfword(*prg.curList.auxField.int()))
  15350. *(*prg.mem[prg.curList.headField].hh()).rh() = 0
  15351. prg.curList.tailField = prg.curList.headField
  15352. *prg.curList.auxField.int() = 0
  15353. } // \2
  15354. func (prg *prg) cleanBox(p halfword, s smallNumber) (r halfword) {
  15355. var (
  15356. q halfword // beginning of a list to be boxed
  15357. saveStyle smallNumber // |cur_style| to be restored
  15358. x halfword // box to be returned
  15359. r1 halfword // temporary pointer
  15360. )
  15361. switch *(*prg.mem[p].hh()).rh() {
  15362. case mathChar:
  15363. prg.curMlist = prg.newNoad()
  15364. prg.mem[int32(prg.curMlist)+1] = prg.mem[p]
  15365. case subBox:
  15366. q = *(*prg.mem[p].hh()).lh()
  15367. goto found
  15368. case subMlist:
  15369. prg.curMlist = *(*prg.mem[p].hh()).lh()
  15370. default:
  15371. q = prg.newNullBox()
  15372. goto found
  15373. }
  15374. saveStyle = prg.curStyle
  15375. prg.curStyle = s
  15376. prg.mlistPenalties = false
  15377. prg.mlistToHlist()
  15378. q = *(*prg.mem[30000-3].hh()).rh() // recursive call
  15379. prg.curStyle = saveStyle // restore the style
  15380. // Set up the values of |cur_size| and |cur_mu|, based on |cur_style|
  15381. {
  15382. if int32(prg.curStyle) < scriptStyle {
  15383. prg.curSize = byte(textSize)
  15384. } else {
  15385. prg.curSize = byte(16 * ((int32(prg.curStyle) - textStyle) / 2))
  15386. }
  15387. prg.curMu = prg.xOverN(*prg.fontInfo[6+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int(), 18)
  15388. }
  15389. found:
  15390. if int32(q) >= int32(prg.hiMemMin) || int32(q) == 0 {
  15391. x = prg.hpack(q, scaled(0), smallNumber(additional))
  15392. } else if int32(*(*prg.mem[q].hh()).rh()) == 0 && int32(*(*prg.mem[q].hh()).b0()) <= vlistNode && *prg.mem[int32(q)+4].int() == 0 {
  15393. x = q
  15394. } else {
  15395. x = prg.hpack(q, scaled(0), smallNumber(additional))
  15396. }
  15397. // Simplify a trivial box
  15398. q = *(*prg.mem[int32(x)+listOffset].hh()).rh()
  15399. if int32(q) >= int32(prg.hiMemMin) {
  15400. r1 = *(*prg.mem[q].hh()).rh()
  15401. if int32(r1) != 0 {
  15402. if int32(*(*prg.mem[r1].hh()).rh()) == 0 {
  15403. if !(int32(r1) >= int32(prg.hiMemMin)) {
  15404. if int32(*(*prg.mem[r1].hh()).b0()) == kernNode {
  15405. prg.freeNode(r1, halfword(smallNodeSize))
  15406. *(*prg.mem[q].hh()).rh() = 0
  15407. }
  15408. }
  15409. }
  15410. }
  15411. }
  15412. r = x
  15413. return r
  15414. }
  15415. // 722.
  15416. // tangle:pos tex.web:14212:1:
  15417. // It is convenient to have a procedure that converts a |math_char|
  15418. // field to an “unpacked” form. The |fetch| routine sets |cur_f|, |cur_c|,
  15419. // and |cur_i| to the font code, character code, and character information bytes of
  15420. // a given noad field. It also takes care of issuing error messages for
  15421. // nonexistent characters; in such cases, |char_exists(cur_i)| will be |false|
  15422. // after |fetch| has acted, and the field will also have been reset to |empty|.
  15423. func (prg *prg) fetch(a halfword) {
  15424. prg.curC = *(*prg.mem[a].hh()).b1()
  15425. prg.curF = byte(*(*prg.eqtb[mathFontBase+int32(*(*prg.mem[a].hh()).b0())+int32(prg.curSize)-1].hh()).rh())
  15426. if int32(prg.curF) == fontBase {
  15427. {
  15428. if int32(prg.interaction) == errorStopMode {
  15429. }
  15430. prg.printNl(strNumber( /* "! " */ 262))
  15431. prg.print( /* "" */ 338)
  15432. }
  15433. prg.printSize(int32(prg.curSize))
  15434. prg.printChar(asciiCode(' '))
  15435. prg.printInt(int32(*(*prg.mem[a].hh()).b0()))
  15436. prg.print( /* " is undefined (character " */ 884)
  15437. prg.print(int32(prg.curC) - minQuarterword)
  15438. prg.printChar(asciiCode(')'))
  15439. {
  15440. prg.helpPtr = 4
  15441. prg.helpLine[3] = /* "Somewhere in the math formula just ended, you used the" */ 885
  15442. prg.helpLine[2] = /* "stated character from an undefined font family. For example," */ 886
  15443. prg.helpLine[1] = /* "plain TeX doesn't allow \\it or \\sl in subscripts. Proceed," */ 887
  15444. prg.helpLine[0] = /* "and I'll try to forget that I needed that character." */ 888
  15445. }
  15446. prg.error1()
  15447. prg.curI = prg.nullCharacter
  15448. *(*prg.mem[a].hh()).rh() = uint16(empty)
  15449. } else {
  15450. if int32(prg.curC)-minQuarterword >= int32(prg.fontBc[prg.curF]) && int32(prg.curC)-minQuarterword <= int32(prg.fontEc[prg.curF]) {
  15451. prg.curI = *prg.fontInfo[prg.charBase[prg.curF]+int32(prg.curC)].qqqq()
  15452. } else {
  15453. prg.curI = prg.nullCharacter
  15454. }
  15455. if !(int32(prg.curI.b0) > minQuarterword) {
  15456. prg.charWarning(prg.curF, eightBits(int32(prg.curC)-minQuarterword))
  15457. *(*prg.mem[a].hh()).rh() = uint16(empty)
  15458. prg.curI = prg.nullCharacter
  15459. }
  15460. }
  15461. }
  15462. // 725.
  15463. // tangle:pos tex.web:14252:1:
  15464. // We need to do a lot of different things, so |mlist_to_hlist| makes two
  15465. // passes over the given mlist.
  15466. //
  15467. // The first pass does most of the processing: It removes ``mu'' spacing from
  15468. // glue, it recursively evaluates all subsidiary mlists so that only the
  15469. // top-level mlist remains to be handled, it puts fractions and square roots
  15470. // and such things into boxes, it attaches subscripts and superscripts, and
  15471. // it computes the overall height and depth of the top-level mlist so that
  15472. // the size of delimiters for a |left_noad| and a |right_noad| will be known.
  15473. // The hlist resulting from each noad is recorded in that noad's |new_hlist|
  15474. // field, an integer field that replaces the |nucleus| or |thickness|.
  15475. // \xref[recursion]
  15476. //
  15477. // The second pass eliminates all noads and inserts the correct glue and
  15478. // penalties between nodes.
  15479. // 726.
  15480. // tangle:pos tex.web:14270:1:
  15481. // Here is the overall plan of |mlist_to_hlist|, and the list of its
  15482. // local variables.
  15483. // \4
  15484. // Declare math construction procedures
  15485. func (prg *prg) makeOver(q halfword) {
  15486. *(*prg.mem[int32(q)+1].hh()).lh() = prg.overbar(prg.cleanBox(halfword(int32(q)+1), smallNumber(2*(int32(prg.curStyle)/2)+cramped)),
  15487. 3**prg.fontInfo[8+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int(), *prg.fontInfo[8+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int())
  15488. *(*prg.mem[int32(q)+1].hh()).rh() = uint16(subBox)
  15489. }
  15490. func (prg *prg) makeUnder(q halfword) {
  15491. var (
  15492. p, x, y halfword // temporary registers for box construction
  15493. delta scaled // overall height plus depth
  15494. )
  15495. x = prg.cleanBox(halfword(int32(q)+1), prg.curStyle)
  15496. p = prg.newKern(3 * *prg.fontInfo[8+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int())
  15497. *(*prg.mem[x].hh()).rh() = p
  15498. *(*prg.mem[p].hh()).rh() = prg.fractionRule(*prg.fontInfo[8+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int())
  15499. y = prg.vpackage(x, scaled(0), smallNumber(additional), scaled(07777777777))
  15500. delta = *prg.mem[int32(y)+heightOffset].int() + *prg.mem[int32(y)+depthOffset].int() + *prg.fontInfo[8+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int()
  15501. *prg.mem[int32(y)+heightOffset].int() = *prg.mem[int32(x)+heightOffset].int()
  15502. *prg.mem[int32(y)+depthOffset].int() = delta - *prg.mem[int32(y)+heightOffset].int()
  15503. *(*prg.mem[int32(q)+1].hh()).lh() = y
  15504. *(*prg.mem[int32(q)+1].hh()).rh() = uint16(subBox)
  15505. }
  15506. func (prg *prg) makeVcenter(q halfword) {
  15507. var (
  15508. v halfword // the box that should be centered vertically
  15509. delta scaled // its height plus depth
  15510. )
  15511. v = *(*prg.mem[int32(q)+1].hh()).lh()
  15512. if int32(*(*prg.mem[v].hh()).b0()) != vlistNode {
  15513. prg.confusion(strNumber( /* "vcenter" */ 539))
  15514. }
  15515. // \xref[this can't happen vcenter][\quad vcenter]
  15516. delta = *prg.mem[int32(v)+heightOffset].int() + *prg.mem[int32(v)+depthOffset].int()
  15517. *prg.mem[int32(v)+heightOffset].int() = *prg.fontInfo[22+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int() + prg.half(delta)
  15518. *prg.mem[int32(v)+depthOffset].int() = delta - *prg.mem[int32(v)+heightOffset].int()
  15519. }
  15520. func (prg *prg) makeRadical(q halfword) {
  15521. var (
  15522. x, y halfword // temporary registers for box construction
  15523. delta, clr scaled // dimensions involved in the calculation
  15524. )
  15525. x = prg.cleanBox(halfword(int32(q)+1), smallNumber(2*(int32(prg.curStyle)/2)+cramped))
  15526. if int32(prg.curStyle) < textStyle {
  15527. clr = *prg.fontInfo[8+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int() + abs(*prg.fontInfo[5+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int())/4
  15528. } else {
  15529. clr = *prg.fontInfo[8+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int()
  15530. clr = clr + abs(clr)/4
  15531. }
  15532. y = prg.varDelimiter(halfword(int32(q)+4), prg.curSize, *prg.mem[int32(x)+heightOffset].int()+*prg.mem[int32(x)+depthOffset].int()+clr+*prg.fontInfo[8+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int())
  15533. delta = *prg.mem[int32(y)+depthOffset].int() - (*prg.mem[int32(x)+heightOffset].int() + *prg.mem[int32(x)+depthOffset].int() + clr)
  15534. if delta > 0 {
  15535. clr = clr + prg.half(delta)
  15536. } // increase the actual clearance
  15537. *prg.mem[int32(y)+4].int() = -(*prg.mem[int32(x)+heightOffset].int() + clr)
  15538. *(*prg.mem[y].hh()).rh() = prg.overbar(x, clr, *prg.mem[int32(y)+heightOffset].int())
  15539. *(*prg.mem[int32(q)+1].hh()).lh() = prg.hpack(y, scaled(0), smallNumber(additional))
  15540. *(*prg.mem[int32(q)+1].hh()).rh() = uint16(subBox)
  15541. }
  15542. func (prg *prg) makeMathAccent(q halfword) {
  15543. var (
  15544. p, x, y halfword // temporary registers for box construction
  15545. a int32 // address of lig/kern instruction
  15546. c quarterword // accent character
  15547. f internalFontNumber // its font
  15548. i fourQuarters // its |char_info|
  15549. s scaled // amount to skew the accent to the right
  15550. h scaled // height of character being accented
  15551. delta scaled // space to remove between accent and accentee
  15552. w scaled // width of the accentee, not including sub/superscripts
  15553. )
  15554. prg.fetch(halfword(int32(q) + 4))
  15555. if int32(prg.curI.b0) > minQuarterword {
  15556. i = prg.curI
  15557. c = prg.curC
  15558. f = prg.curF
  15559. // Compute the amount of skew
  15560. s = 0
  15561. if int32(*(*prg.mem[int32(q)+1].hh()).rh()) == mathChar {
  15562. prg.fetch(halfword(int32(q) + 1))
  15563. if (int32(prg.curI.b2)-minQuarterword)%4 == ligTag {
  15564. a = prg.ligKernBase[prg.curF] + int32(prg.curI.b3)
  15565. prg.curI = *prg.fontInfo[a].qqqq()
  15566. if int32(prg.curI.b0) > 128+minQuarterword {
  15567. a = prg.ligKernBase[prg.curF] + 256*int32(prg.curI.b2) + int32(prg.curI.b3) + 32768 - 256*(128+minQuarterword)
  15568. prg.curI = *prg.fontInfo[a].qqqq()
  15569. }
  15570. for true {
  15571. if int32(prg.curI.b1)-minQuarterword == prg.skewChar[prg.curF] {
  15572. if int32(prg.curI.b2) >= 128+minQuarterword {
  15573. if int32(prg.curI.b0) <= 128+minQuarterword {
  15574. s = *prg.fontInfo[prg.kernBase[prg.curF]+256*int32(prg.curI.b2)+int32(prg.curI.b3)].int()
  15575. }
  15576. }
  15577. goto done1
  15578. }
  15579. if int32(prg.curI.b0) >= 128+minQuarterword {
  15580. goto done1
  15581. }
  15582. a = a + int32(prg.curI.b0) - minQuarterword + 1
  15583. prg.curI = *prg.fontInfo[a].qqqq()
  15584. }
  15585. }
  15586. }
  15587. done1:
  15588. ;
  15589. x = prg.cleanBox(halfword(int32(q)+1), smallNumber(2*(int32(prg.curStyle)/2)+cramped))
  15590. w = *prg.mem[int32(x)+widthOffset].int()
  15591. h = *prg.mem[int32(x)+heightOffset].int()
  15592. // Switch to a larger accent if available and appropriate
  15593. for true {
  15594. if (int32(i.b2)-minQuarterword)%4 != listTag {
  15595. goto done
  15596. }
  15597. y = uint16(i.b3)
  15598. i = *prg.fontInfo[prg.charBase[f]+int32(y)].qqqq()
  15599. if !(int32(i.b0) > minQuarterword) {
  15600. goto done
  15601. }
  15602. if *prg.fontInfo[prg.widthBase[f]+int32(i.b0)].int() > w {
  15603. goto done
  15604. }
  15605. c = byte(y)
  15606. }
  15607. done:
  15608. ;
  15609. if h < *prg.fontInfo[xHeightCode+prg.paramBase[f]].int() {
  15610. delta = h
  15611. } else {
  15612. delta = *prg.fontInfo[xHeightCode+prg.paramBase[f]].int()
  15613. }
  15614. if int32(*(*prg.mem[int32(q)+2].hh()).rh()) != empty || int32(*(*prg.mem[int32(q)+3].hh()).rh()) != empty {
  15615. if int32(*(*prg.mem[int32(q)+1].hh()).rh()) == mathChar {
  15616. prg.flushNodeList(x)
  15617. x = prg.newNoad()
  15618. prg.mem[int32(x)+1] = prg.mem[int32(q)+1]
  15619. prg.mem[int32(x)+2] = prg.mem[int32(q)+2]
  15620. prg.mem[int32(x)+3] = prg.mem[int32(q)+3]
  15621. *prg.mem[int32(q)+2].hh() = prg.emptyField
  15622. *prg.mem[int32(q)+3].hh() = prg.emptyField
  15623. *(*prg.mem[int32(q)+1].hh()).rh() = uint16(subMlist)
  15624. *(*prg.mem[int32(q)+1].hh()).lh() = x
  15625. x = prg.cleanBox(halfword(int32(q)+1), prg.curStyle)
  15626. delta = delta + *prg.mem[int32(x)+heightOffset].int() - h
  15627. h = *prg.mem[int32(x)+heightOffset].int()
  15628. }
  15629. }
  15630. y = prg.charBox(f, c)
  15631. *prg.mem[int32(y)+4].int() = s + prg.half(w-*prg.mem[int32(y)+widthOffset].int())
  15632. *prg.mem[int32(y)+widthOffset].int() = 0
  15633. p = prg.newKern(-delta)
  15634. *(*prg.mem[p].hh()).rh() = x
  15635. *(*prg.mem[y].hh()).rh() = p
  15636. y = prg.vpackage(y, scaled(0), smallNumber(additional), scaled(07777777777))
  15637. *prg.mem[int32(y)+widthOffset].int() = *prg.mem[int32(x)+widthOffset].int()
  15638. if *prg.mem[int32(y)+heightOffset].int() < h {
  15639. p = prg.newKern(h - *prg.mem[int32(y)+heightOffset].int())
  15640. *(*prg.mem[p].hh()).rh() = *(*prg.mem[int32(y)+listOffset].hh()).rh()
  15641. *(*prg.mem[int32(y)+listOffset].hh()).rh() = p
  15642. *prg.mem[int32(y)+heightOffset].int() = h
  15643. }
  15644. *(*prg.mem[int32(q)+1].hh()).lh() = y
  15645. *(*prg.mem[int32(q)+1].hh()).rh() = uint16(subBox)
  15646. }
  15647. }
  15648. func (prg *prg) makeFraction(q halfword) {
  15649. var (
  15650. p, v, x, y, z halfword // temporary registers for box construction
  15651. delta, delta1, delta2, shiftUp, shiftDown, clr scaled
  15652. // dimensions for box calculations
  15653. )
  15654. if *prg.mem[int32(q)+widthOffset].int() == 010000000000 {
  15655. *prg.mem[int32(q)+widthOffset].int() = *prg.fontInfo[8+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int()
  15656. }
  15657. // Create equal-width boxes |x| and |z| for the numerator and denominator, and compute the default amounts |shift_up| and |shift_down| by which they are displaced from the baseline
  15658. x = prg.cleanBox(halfword(int32(q)+2), smallNumber(int32(prg.curStyle)+2-2*(int32(prg.curStyle)/6)))
  15659. z = prg.cleanBox(halfword(int32(q)+3), smallNumber(2*(int32(prg.curStyle)/2)+cramped+2-2*(int32(prg.curStyle)/6)))
  15660. if *prg.mem[int32(x)+widthOffset].int() < *prg.mem[int32(z)+widthOffset].int() {
  15661. x = prg.rebox(x, *prg.mem[int32(z)+widthOffset].int())
  15662. } else {
  15663. z = prg.rebox(z, *prg.mem[int32(x)+widthOffset].int())
  15664. }
  15665. if int32(prg.curStyle) < textStyle {
  15666. shiftUp = *prg.fontInfo[8+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int()
  15667. shiftDown = *prg.fontInfo[11+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int()
  15668. } else {
  15669. shiftDown = *prg.fontInfo[12+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int()
  15670. if *prg.mem[int32(q)+widthOffset].int() != 0 {
  15671. shiftUp = *prg.fontInfo[9+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int()
  15672. } else {
  15673. shiftUp = *prg.fontInfo[10+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int()
  15674. }
  15675. }
  15676. if *prg.mem[int32(q)+widthOffset].int() == 0 {
  15677. if int32(prg.curStyle) < textStyle {
  15678. clr = 7 * *prg.fontInfo[8+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int()
  15679. } else {
  15680. clr = 3 * *prg.fontInfo[8+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int()
  15681. }
  15682. delta = prg.half(clr - (shiftUp - *prg.mem[int32(x)+depthOffset].int() - (*prg.mem[int32(z)+heightOffset].int() - shiftDown)))
  15683. if delta > 0 {
  15684. shiftUp = shiftUp + delta
  15685. shiftDown = shiftDown + delta
  15686. }
  15687. } else {
  15688. // Adjust \(s)|shift_up| and |shift_down| for the case of a fraction line
  15689. if int32(prg.curStyle) < textStyle {
  15690. clr = 3 * *prg.mem[int32(q)+widthOffset].int()
  15691. } else {
  15692. clr = *prg.mem[int32(q)+widthOffset].int()
  15693. }
  15694. delta = prg.half(*prg.mem[int32(q)+widthOffset].int())
  15695. delta1 = clr - (shiftUp - *prg.mem[int32(x)+depthOffset].int() - (*prg.fontInfo[22+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int() + delta))
  15696. delta2 = clr - (*prg.fontInfo[22+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int() - delta - (*prg.mem[int32(z)+heightOffset].int() - shiftDown))
  15697. if delta1 > 0 {
  15698. shiftUp = shiftUp + delta1
  15699. }
  15700. if delta2 > 0 {
  15701. shiftDown = shiftDown + delta2
  15702. }
  15703. }
  15704. // Construct a vlist box for the fraction, according to |shift_up| and |shift_down|
  15705. v = prg.newNullBox()
  15706. *(*prg.mem[v].hh()).b0() = byte(vlistNode)
  15707. *prg.mem[int32(v)+heightOffset].int() = shiftUp + *prg.mem[int32(x)+heightOffset].int()
  15708. *prg.mem[int32(v)+depthOffset].int() = *prg.mem[int32(z)+depthOffset].int() + shiftDown
  15709. *prg.mem[int32(v)+widthOffset].int() = *prg.mem[int32(x)+widthOffset].int() // this also equals |width(z)|
  15710. if *prg.mem[int32(q)+widthOffset].int() == 0 {
  15711. p = prg.newKern(shiftUp - *prg.mem[int32(x)+depthOffset].int() - (*prg.mem[int32(z)+heightOffset].int() - shiftDown))
  15712. *(*prg.mem[p].hh()).rh() = z
  15713. } else {
  15714. y = prg.fractionRule(*prg.mem[int32(q)+widthOffset].int())
  15715. p = prg.newKern(*prg.fontInfo[22+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int() - delta - (*prg.mem[int32(z)+heightOffset].int() - shiftDown))
  15716. *(*prg.mem[y].hh()).rh() = p
  15717. *(*prg.mem[p].hh()).rh() = z
  15718. p = prg.newKern(shiftUp - *prg.mem[int32(x)+depthOffset].int() - (*prg.fontInfo[22+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int() + delta))
  15719. *(*prg.mem[p].hh()).rh() = y
  15720. }
  15721. *(*prg.mem[x].hh()).rh() = p
  15722. *(*prg.mem[int32(v)+listOffset].hh()).rh() = x
  15723. // Put the \(f)fraction into a box with its delimiters, and make |new_hlist(q)| point to it
  15724. if int32(prg.curStyle) < textStyle {
  15725. delta = *prg.fontInfo[20+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int()
  15726. } else {
  15727. delta = *prg.fontInfo[21+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int()
  15728. }
  15729. x = prg.varDelimiter(halfword(int32(q)+4), prg.curSize, delta)
  15730. *(*prg.mem[x].hh()).rh() = v
  15731. z = prg.varDelimiter(halfword(int32(q)+5), prg.curSize, delta)
  15732. *(*prg.mem[v].hh()).rh() = z
  15733. *prg.mem[int32(q)+1].int() = int32(prg.hpack(x, scaled(0), smallNumber(additional)))
  15734. }
  15735. func (prg *prg) makeOp(q halfword) (r scaled) {
  15736. var (
  15737. delta scaled // offset between subscript and superscript
  15738. p, v, x, y, z halfword // temporary registers for box construction
  15739. c quarterword
  15740. i fourQuarters // registers for character examination
  15741. shiftUp, shiftDown scaled // dimensions for box calculation
  15742. )
  15743. if int32(*(*prg.mem[q].hh()).b1()) == normal && int32(prg.curStyle) < textStyle {
  15744. *(*prg.mem[q].hh()).b1() = byte(limits)
  15745. }
  15746. if int32(*(*prg.mem[int32(q)+1].hh()).rh()) == mathChar {
  15747. prg.fetch(halfword(int32(q) + 1))
  15748. if int32(prg.curStyle) < textStyle && (int32(prg.curI.b2)-minQuarterword)%4 == listTag {
  15749. c = prg.curI.b3
  15750. i = *prg.fontInfo[prg.charBase[prg.curF]+int32(c)].qqqq()
  15751. if int32(i.b0) > minQuarterword {
  15752. prg.curC = c
  15753. prg.curI = i
  15754. *(*prg.mem[int32(q)+1].hh()).b1() = c
  15755. }
  15756. }
  15757. delta = *prg.fontInfo[prg.italicBase[prg.curF]+(int32(prg.curI.b2)-minQuarterword)/4].int()
  15758. x = prg.cleanBox(halfword(int32(q)+1), prg.curStyle)
  15759. if int32(*(*prg.mem[int32(q)+3].hh()).rh()) != empty && int32(*(*prg.mem[q].hh()).b1()) != limits {
  15760. *prg.mem[int32(x)+widthOffset].int() = *prg.mem[int32(x)+widthOffset].int() - delta
  15761. } // remove italic correction
  15762. *prg.mem[int32(x)+4].int() = prg.half(*prg.mem[int32(x)+heightOffset].int()-*prg.mem[int32(x)+depthOffset].int()) - *prg.fontInfo[22+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int()
  15763. // center vertically
  15764. *(*prg.mem[int32(q)+1].hh()).rh() = uint16(subBox)
  15765. *(*prg.mem[int32(q)+1].hh()).lh() = x
  15766. } else {
  15767. delta = 0
  15768. }
  15769. if int32(*(*prg.mem[q].hh()).b1()) == limits {
  15770. x = prg.cleanBox(halfword(int32(q)+2), smallNumber(2*(int32(prg.curStyle)/4)+scriptStyle+int32(prg.curStyle)%2))
  15771. y = prg.cleanBox(halfword(int32(q)+1), prg.curStyle)
  15772. z = prg.cleanBox(halfword(int32(q)+3), smallNumber(2*(int32(prg.curStyle)/4)+scriptStyle+cramped))
  15773. v = prg.newNullBox()
  15774. *(*prg.mem[v].hh()).b0() = byte(vlistNode)
  15775. *prg.mem[int32(v)+widthOffset].int() = *prg.mem[int32(y)+widthOffset].int()
  15776. if *prg.mem[int32(x)+widthOffset].int() > *prg.mem[int32(v)+widthOffset].int() {
  15777. *prg.mem[int32(v)+widthOffset].int() = *prg.mem[int32(x)+widthOffset].int()
  15778. }
  15779. if *prg.mem[int32(z)+widthOffset].int() > *prg.mem[int32(v)+widthOffset].int() {
  15780. *prg.mem[int32(v)+widthOffset].int() = *prg.mem[int32(z)+widthOffset].int()
  15781. }
  15782. x = prg.rebox(x, *prg.mem[int32(v)+widthOffset].int())
  15783. y = prg.rebox(y, *prg.mem[int32(v)+widthOffset].int())
  15784. z = prg.rebox(z, *prg.mem[int32(v)+widthOffset].int())
  15785. *prg.mem[int32(x)+4].int() = prg.half(delta)
  15786. *prg.mem[int32(z)+4].int() = -*prg.mem[int32(x)+4].int()
  15787. *prg.mem[int32(v)+heightOffset].int() = *prg.mem[int32(y)+heightOffset].int()
  15788. *prg.mem[int32(v)+depthOffset].int() = *prg.mem[int32(y)+depthOffset].int()
  15789. // Attach the limits to |y| and adjust |height(v)|, |depth(v)| to account for their presence
  15790. if int32(*(*prg.mem[int32(q)+2].hh()).rh()) == empty {
  15791. prg.freeNode(x, halfword(boxNodeSize))
  15792. *(*prg.mem[int32(v)+listOffset].hh()).rh() = y
  15793. } else {
  15794. shiftUp = *prg.fontInfo[11+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int() - *prg.mem[int32(x)+depthOffset].int()
  15795. if shiftUp < *prg.fontInfo[9+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int() {
  15796. shiftUp = *prg.fontInfo[9+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int()
  15797. }
  15798. p = prg.newKern(shiftUp)
  15799. *(*prg.mem[p].hh()).rh() = y
  15800. *(*prg.mem[x].hh()).rh() = p
  15801. p = prg.newKern(*prg.fontInfo[13+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int())
  15802. *(*prg.mem[p].hh()).rh() = x
  15803. *(*prg.mem[int32(v)+listOffset].hh()).rh() = p
  15804. *prg.mem[int32(v)+heightOffset].int() = *prg.mem[int32(v)+heightOffset].int() + *prg.fontInfo[13+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int() + *prg.mem[int32(x)+heightOffset].int() + *prg.mem[int32(x)+depthOffset].int() + shiftUp
  15805. }
  15806. if int32(*(*prg.mem[int32(q)+3].hh()).rh()) == empty {
  15807. prg.freeNode(z, halfword(boxNodeSize))
  15808. } else {
  15809. shiftDown = *prg.fontInfo[12+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int() - *prg.mem[int32(z)+heightOffset].int()
  15810. if shiftDown < *prg.fontInfo[10+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int() {
  15811. shiftDown = *prg.fontInfo[10+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int()
  15812. }
  15813. p = prg.newKern(shiftDown)
  15814. *(*prg.mem[y].hh()).rh() = p
  15815. *(*prg.mem[p].hh()).rh() = z
  15816. p = prg.newKern(*prg.fontInfo[13+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int())
  15817. *(*prg.mem[z].hh()).rh() = p
  15818. *prg.mem[int32(v)+depthOffset].int() = *prg.mem[int32(v)+depthOffset].int() + *prg.fontInfo[13+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int() + *prg.mem[int32(z)+heightOffset].int() + *prg.mem[int32(z)+depthOffset].int() + shiftDown
  15819. }
  15820. *prg.mem[int32(q)+1].int() = int32(v)
  15821. }
  15822. r = delta
  15823. return r
  15824. }
  15825. func (prg *prg) makeOrd(q halfword) {
  15826. var (
  15827. a int32 // address of lig/kern instruction
  15828. p, r1 halfword // temporary registers for list manipulation
  15829. )
  15830. restart:
  15831. if int32(*(*prg.mem[int32(q)+3].hh()).rh()) == empty {
  15832. if int32(*(*prg.mem[int32(q)+2].hh()).rh()) == empty {
  15833. if int32(*(*prg.mem[int32(q)+1].hh()).rh()) == mathChar {
  15834. p = *(*prg.mem[q].hh()).rh()
  15835. if int32(p) != 0 {
  15836. if int32(*(*prg.mem[p].hh()).b0()) >= ordNoad && int32(*(*prg.mem[p].hh()).b0()) <= punctNoad {
  15837. if int32(*(*prg.mem[int32(p)+1].hh()).rh()) == mathChar {
  15838. if int32(*(*prg.mem[int32(p)+1].hh()).b0()) == int32(*(*prg.mem[int32(q)+1].hh()).b0()) {
  15839. *(*prg.mem[int32(q)+1].hh()).rh() = uint16(mathTextChar)
  15840. prg.fetch(halfword(int32(q) + 1))
  15841. if (int32(prg.curI.b2)-minQuarterword)%4 == ligTag {
  15842. a = prg.ligKernBase[prg.curF] + int32(prg.curI.b3)
  15843. prg.curC = *(*prg.mem[int32(p)+1].hh()).b1()
  15844. prg.curI = *prg.fontInfo[a].qqqq()
  15845. if int32(prg.curI.b0) > 128+minQuarterword {
  15846. a = prg.ligKernBase[prg.curF] + 256*int32(prg.curI.b2) + int32(prg.curI.b3) + 32768 - 256*(128+minQuarterword)
  15847. prg.curI = *prg.fontInfo[a].qqqq()
  15848. }
  15849. for true {
  15850. if int32(prg.curI.b1) == int32(prg.curC) {
  15851. if int32(prg.curI.b0) <= 128+minQuarterword {
  15852. if int32(prg.curI.b2) >= 128+minQuarterword {
  15853. p = prg.newKern(*prg.fontInfo[prg.kernBase[prg.curF]+256*int32(prg.curI.b2)+int32(prg.curI.b3)].int())
  15854. *(*prg.mem[p].hh()).rh() = *(*prg.mem[q].hh()).rh()
  15855. *(*prg.mem[q].hh()).rh() = p
  15856. goto exit
  15857. } else {
  15858. {
  15859. if prg.interrupt != 0 {
  15860. prg.pauseForInstructions()
  15861. }
  15862. } // allow a way out of infinite ligature loop
  15863. switch prg.curI.b2 {
  15864. case 1 + minQuarterword, 5 + minQuarterword:
  15865. *(*prg.mem[int32(q)+1].hh()).b1() = prg.curI.b3 // \.[=:\?], \.[=:\?>]
  15866. case 2 + minQuarterword, 6 + minQuarterword:
  15867. *(*prg.mem[int32(p)+1].hh()).b1() = prg.curI.b3 // \.[\?=:], \.[\?=:>]
  15868. case 3 + minQuarterword, 7 + minQuarterword, 11 + minQuarterword:
  15869. r1 = prg.newNoad() // \.[\?=:\?], \.[\?=:\?>], \.[\?=:\?>>]
  15870. *(*prg.mem[int32(r1)+1].hh()).b1() = prg.curI.b3
  15871. *(*prg.mem[int32(r1)+1].hh()).b0() = *(*prg.mem[int32(q)+1].hh()).b0()
  15872. *(*prg.mem[q].hh()).rh() = r1
  15873. *(*prg.mem[r1].hh()).rh() = p
  15874. if int32(prg.curI.b2) < 11+minQuarterword {
  15875. *(*prg.mem[int32(r1)+1].hh()).rh() = uint16(mathChar)
  15876. } else {
  15877. *(*prg.mem[int32(r1)+1].hh()).rh() = uint16(mathTextChar)
  15878. } // prevent combination
  15879. default:
  15880. *(*prg.mem[q].hh()).rh() = *(*prg.mem[p].hh()).rh()
  15881. *(*prg.mem[int32(q)+1].hh()).b1() = prg.curI.b3 // \.[=:]
  15882. prg.mem[int32(q)+3] = prg.mem[int32(p)+3]
  15883. prg.mem[int32(q)+2] = prg.mem[int32(p)+2]
  15884. prg.freeNode(p, halfword(noadSize))
  15885. }
  15886. if int32(prg.curI.b2) > 3+minQuarterword {
  15887. goto exit
  15888. }
  15889. *(*prg.mem[int32(q)+1].hh()).rh() = uint16(mathChar)
  15890. goto restart
  15891. }
  15892. }
  15893. }
  15894. if int32(prg.curI.b0) >= 128+minQuarterword {
  15895. goto exit
  15896. }
  15897. a = a + int32(prg.curI.b0) - minQuarterword + 1
  15898. prg.curI = *prg.fontInfo[a].qqqq()
  15899. }
  15900. }
  15901. }
  15902. }
  15903. }
  15904. }
  15905. }
  15906. }
  15907. }
  15908. exit:
  15909. }
  15910. func (prg *prg) makeScripts(q halfword, delta scaled) {
  15911. var (
  15912. p, x, y, z halfword // temporary registers for box construction
  15913. shiftUp, shiftDown, clr scaled // dimensions in the calculation
  15914. t smallNumber // subsidiary size code
  15915. )
  15916. p = uint16(*prg.mem[int32(q)+1].int())
  15917. if int32(p) >= int32(prg.hiMemMin) {
  15918. shiftUp = 0
  15919. shiftDown = 0
  15920. } else {
  15921. z = prg.hpack(p, scaled(0), smallNumber(additional))
  15922. if int32(prg.curStyle) < scriptStyle {
  15923. t = byte(scriptSize)
  15924. } else {
  15925. t = byte(scriptScriptSize)
  15926. }
  15927. shiftUp = *prg.mem[int32(z)+heightOffset].int() - *prg.fontInfo[18+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(t)-1].hh()).rh()]].int()
  15928. shiftDown = *prg.mem[int32(z)+depthOffset].int() + *prg.fontInfo[19+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(t)-1].hh()).rh()]].int()
  15929. prg.freeNode(z, halfword(boxNodeSize))
  15930. }
  15931. if int32(*(*prg.mem[int32(q)+2].hh()).rh()) == empty {
  15932. x = prg.cleanBox(halfword(int32(q)+3), smallNumber(2*(int32(prg.curStyle)/4)+scriptStyle+cramped))
  15933. *prg.mem[int32(x)+widthOffset].int() = *prg.mem[int32(x)+widthOffset].int() + *prg.eqtb[dimenBase+scriptSpaceCode-1].int()
  15934. if shiftDown < *prg.fontInfo[16+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int() {
  15935. shiftDown = *prg.fontInfo[16+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int()
  15936. }
  15937. clr = *prg.mem[int32(x)+heightOffset].int() - abs(*prg.fontInfo[5+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int()*4)/5
  15938. if shiftDown < clr {
  15939. shiftDown = clr
  15940. }
  15941. *prg.mem[int32(x)+4].int() = shiftDown
  15942. } else {
  15943. {
  15944. x = prg.cleanBox(halfword(int32(q)+2), smallNumber(2*(int32(prg.curStyle)/4)+scriptStyle+int32(prg.curStyle)%2))
  15945. *prg.mem[int32(x)+widthOffset].int() = *prg.mem[int32(x)+widthOffset].int() + *prg.eqtb[dimenBase+scriptSpaceCode-1].int()
  15946. if prg.curStyle&1 != 0 {
  15947. clr = *prg.fontInfo[15+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int()
  15948. } else if int32(prg.curStyle) < textStyle {
  15949. clr = *prg.fontInfo[13+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int()
  15950. } else {
  15951. clr = *prg.fontInfo[14+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int()
  15952. }
  15953. if shiftUp < clr {
  15954. shiftUp = clr
  15955. }
  15956. clr = *prg.mem[int32(x)+depthOffset].int() + abs(*prg.fontInfo[5+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int())/4
  15957. if shiftUp < clr {
  15958. shiftUp = clr
  15959. }
  15960. }
  15961. if int32(*(*prg.mem[int32(q)+3].hh()).rh()) == empty {
  15962. *prg.mem[int32(x)+4].int() = -shiftUp
  15963. } else {
  15964. // Construct a sub/superscript combination box |x|, with the superscript offset by |delta|
  15965. y = prg.cleanBox(halfword(int32(q)+3), smallNumber(2*(int32(prg.curStyle)/4)+scriptStyle+cramped))
  15966. *prg.mem[int32(y)+widthOffset].int() = *prg.mem[int32(y)+widthOffset].int() + *prg.eqtb[dimenBase+scriptSpaceCode-1].int()
  15967. if shiftDown < *prg.fontInfo[17+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int() {
  15968. shiftDown = *prg.fontInfo[17+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int()
  15969. }
  15970. clr = 4**prg.fontInfo[8+prg.paramBase[*(*prg.eqtb[mathFontBase+3+int32(prg.curSize)-1].hh()).rh()]].int() - (shiftUp - *prg.mem[int32(x)+depthOffset].int() - (*prg.mem[int32(y)+heightOffset].int() - shiftDown))
  15971. if clr > 0 {
  15972. shiftDown = shiftDown + clr
  15973. clr = abs(*prg.fontInfo[5+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int()*4)/5 - (shiftUp - *prg.mem[int32(x)+depthOffset].int())
  15974. if clr > 0 {
  15975. shiftUp = shiftUp + clr
  15976. shiftDown = shiftDown - clr
  15977. }
  15978. }
  15979. *prg.mem[int32(x)+4].int() = delta // superscript is |delta| to the right of the subscript
  15980. p = prg.newKern(shiftUp - *prg.mem[int32(x)+depthOffset].int() - (*prg.mem[int32(y)+heightOffset].int() - shiftDown))
  15981. *(*prg.mem[x].hh()).rh() = p
  15982. *(*prg.mem[p].hh()).rh() = y
  15983. x = prg.vpackage(x, scaled(0), smallNumber(additional), scaled(07777777777))
  15984. *prg.mem[int32(x)+4].int() = shiftDown
  15985. }
  15986. }
  15987. if *prg.mem[int32(q)+1].int() == 0 {
  15988. *prg.mem[int32(q)+1].int() = int32(x)
  15989. } else {
  15990. p = uint16(*prg.mem[int32(q)+1].int())
  15991. for int32(*(*prg.mem[p].hh()).rh()) != 0 {
  15992. p = *(*prg.mem[p].hh()).rh()
  15993. }
  15994. *(*prg.mem[p].hh()).rh() = x
  15995. }
  15996. }
  15997. func (prg *prg) makeLeftRight(q halfword, style smallNumber,
  15998. maxD, maxH scaled) (r smallNumber) {
  15999. var (
  16000. delta, delta1, delta2 scaled // dimensions used in the calculation
  16001. )
  16002. if int32(style) < scriptStyle {
  16003. prg.curSize = byte(textSize)
  16004. } else {
  16005. prg.curSize = byte(16 * ((int32(style) - textStyle) / 2))
  16006. }
  16007. delta2 = maxD + *prg.fontInfo[22+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int()
  16008. delta1 = maxH + maxD - delta2
  16009. if delta2 > delta1 {
  16010. delta1 = delta2
  16011. } // |delta1| is max distance from axis
  16012. delta = delta1 / 500 * *prg.eqtb[intBase+delimiterFactorCode-1].int()
  16013. delta2 = delta1 + delta1 - *prg.eqtb[dimenBase+delimiterShortfallCode-1].int()
  16014. if delta < delta2 {
  16015. delta = delta2
  16016. }
  16017. *prg.mem[int32(q)+1].int() = int32(prg.varDelimiter(halfword(int32(q)+1), prg.curSize, delta))
  16018. r = byte(int32(*(*prg.mem[q].hh()).b0()) - (leftNoad - openNoad)) // |open_noad| or |close_noad|
  16019. return r
  16020. }
  16021. // 720.
  16022. // tangle:pos tex.web:14163:1:
  16023. // The recursion in |mlist_to_hlist| is due primarily to a subroutine
  16024. // called |clean_box| that puts a given noad field into a box using a given
  16025. // math style; |mlist_to_hlist| can call |clean_box|, which can call
  16026. // |mlist_to_hlist|.
  16027. // \xref[recursion]
  16028. //
  16029. // The box returned by |clean_box| is “clean” in the
  16030. // sense that its |shift_amount| is zero.
  16031. func (prg *prg) mlistToHlist() {
  16032. var (
  16033. mlist halfword // beginning of the given list
  16034. penalties bool // should penalty nodes be inserted?
  16035. style smallNumber // the given style
  16036. saveStyle smallNumber // holds |cur_style| during recursion
  16037. q halfword // runs through the mlist
  16038. r1 halfword // the most recent noad preceding |q|
  16039. rType smallNumber // the |type| of noad |r|, or |op_noad| if |r=null|
  16040. t smallNumber // the effective |type| of noad |q| during the second pass
  16041. p, x, y, z halfword // temporary registers for list construction
  16042. pen int32 // a penalty to be inserted
  16043. s smallNumber // the size of a noad to be deleted
  16044. maxH, maxD scaled // maximum height and depth of the list translated so far
  16045. delta scaled // offset between subscript and superscript
  16046. )
  16047. mlist = prg.curMlist
  16048. penalties = prg.mlistPenalties
  16049. style = prg.curStyle // tuck global parameters away as local variables
  16050. q = mlist
  16051. r1 = 0
  16052. rType = byte(opNoad)
  16053. maxH = 0
  16054. maxD = 0
  16055. // Set up the values of |cur_size| and |cur_mu|, based on |cur_style|
  16056. {
  16057. if int32(prg.curStyle) < scriptStyle {
  16058. prg.curSize = byte(textSize)
  16059. } else {
  16060. prg.curSize = byte(16 * ((int32(prg.curStyle) - textStyle) / 2))
  16061. }
  16062. prg.curMu = prg.xOverN(*prg.fontInfo[6+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int(), 18)
  16063. }
  16064. for int32(q) != 0 {
  16065. // Process node-or-noad |q| as much as possible in preparation for the second pass of |mlist_to_hlist|, then move to the next item in the mlist
  16066. // Do first-pass processing based on |type(q)|; |goto done_with_noad| if a noad has been fully processed, |goto check_dimensions| if it has been translated into |new_hlist(q)|, or |goto done_with_node| if a node has been fully processed
  16067. reswitch:
  16068. delta = 0
  16069. switch *(*prg.mem[q].hh()).b0() {
  16070. case binNoad:
  16071. switch rType {
  16072. case binNoad, opNoad, relNoad, openNoad,
  16073. punctNoad, leftNoad:
  16074. *(*prg.mem[q].hh()).b0() = byte(ordNoad)
  16075. goto reswitch
  16076. default:
  16077. }
  16078. case relNoad, closeNoad, punctNoad, rightNoad:
  16079. if int32(rType) == binNoad {
  16080. *(*prg.mem[r1].hh()).b0() = byte(ordNoad)
  16081. }
  16082. if int32(*(*prg.mem[q].hh()).b0()) == rightNoad {
  16083. goto doneWithNoad
  16084. }
  16085. // \4
  16086. // Cases for noads that can follow a |bin_noad|
  16087. case leftNoad:
  16088. goto doneWithNoad
  16089. case fractionNoad:
  16090. prg.makeFraction(q)
  16091. goto checkDimensions
  16092. case opNoad:
  16093. delta = prg.makeOp(q)
  16094. if int32(*(*prg.mem[q].hh()).b1()) == limits {
  16095. goto checkDimensions
  16096. }
  16097. case ordNoad:
  16098. prg.makeOrd(q)
  16099. case openNoad, innerNoad:
  16100. case radicalNoad:
  16101. prg.makeRadical(q)
  16102. case overNoad:
  16103. prg.makeOver(q)
  16104. case underNoad:
  16105. prg.makeUnder(q)
  16106. case accentNoad:
  16107. prg.makeMathAccent(q)
  16108. case vcenterNoad:
  16109. prg.makeVcenter(q)
  16110. // \4
  16111. // Cases for nodes that can appear in an mlist, after which we |goto done_with_node|
  16112. case styleNode:
  16113. prg.curStyle = *(*prg.mem[q].hh()).b1()
  16114. // Set up the values of |cur_size| and |cur_mu|, based on |cur_style|
  16115. {
  16116. if int32(prg.curStyle) < scriptStyle {
  16117. prg.curSize = byte(textSize)
  16118. } else {
  16119. prg.curSize = byte(16 * ((int32(prg.curStyle) - textStyle) / 2))
  16120. }
  16121. prg.curMu = prg.xOverN(*prg.fontInfo[6+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int(), 18)
  16122. }
  16123. goto doneWithNode
  16124. case choiceNode:
  16125. // Change this node to a style node followed by the correct choice, then |goto done_with_node|
  16126. switch int32(prg.curStyle) / 2 {
  16127. case 0:
  16128. p = *(*prg.mem[int32(q)+1].hh()).lh()
  16129. *(*prg.mem[int32(q)+1].hh()).lh() = 0 // |display_style=0|
  16130. case 1:
  16131. p = *(*prg.mem[int32(q)+1].hh()).rh()
  16132. *(*prg.mem[int32(q)+1].hh()).rh() = 0 // |text_style=2|
  16133. case 2:
  16134. p = *(*prg.mem[int32(q)+2].hh()).lh()
  16135. *(*prg.mem[int32(q)+2].hh()).lh() = 0 // |script_style=4|
  16136. case 3:
  16137. p = *(*prg.mem[int32(q)+2].hh()).rh()
  16138. *(*prg.mem[int32(q)+2].hh()).rh() = 0 // |script_script_style=6|
  16139. } // there are no other cases
  16140. prg.flushNodeList(*(*prg.mem[int32(q)+1].hh()).lh())
  16141. prg.flushNodeList(*(*prg.mem[int32(q)+1].hh()).rh())
  16142. prg.flushNodeList(*(*prg.mem[int32(q)+2].hh()).lh())
  16143. prg.flushNodeList(*(*prg.mem[int32(q)+2].hh()).rh())
  16144. *(*prg.mem[q].hh()).b0() = byte(styleNode)
  16145. *(*prg.mem[q].hh()).b1() = prg.curStyle
  16146. *prg.mem[int32(q)+widthOffset].int() = 0
  16147. *prg.mem[int32(q)+depthOffset].int() = 0
  16148. if int32(p) != 0 {
  16149. z = *(*prg.mem[q].hh()).rh()
  16150. *(*prg.mem[q].hh()).rh() = p
  16151. for int32(*(*prg.mem[p].hh()).rh()) != 0 {
  16152. p = *(*prg.mem[p].hh()).rh()
  16153. }
  16154. *(*prg.mem[p].hh()).rh() = z
  16155. }
  16156. goto doneWithNode
  16157. case insNode, markNode, adjustNode, whatsitNode,
  16158. penaltyNode, discNode:
  16159. goto doneWithNode
  16160. case ruleNode:
  16161. if *prg.mem[int32(q)+heightOffset].int() > maxH {
  16162. maxH = *prg.mem[int32(q)+heightOffset].int()
  16163. }
  16164. if *prg.mem[int32(q)+depthOffset].int() > maxD {
  16165. maxD = *prg.mem[int32(q)+depthOffset].int()
  16166. }
  16167. goto doneWithNode
  16168. case glueNode:
  16169. if int32(*(*prg.mem[q].hh()).b1()) == muGlue {
  16170. x = *(*prg.mem[int32(q)+1].hh()).lh()
  16171. y = prg.mathGlue(x, prg.curMu)
  16172. prg.deleteGlueRef(x)
  16173. *(*prg.mem[int32(q)+1].hh()).lh() = y
  16174. *(*prg.mem[q].hh()).b1() = byte(normal)
  16175. } else if int32(prg.curSize) != textSize && int32(*(*prg.mem[q].hh()).b1()) == condMathGlue {
  16176. p = *(*prg.mem[q].hh()).rh()
  16177. if int32(p) != 0 {
  16178. if int32(*(*prg.mem[p].hh()).b0()) == glueNode || int32(*(*prg.mem[p].hh()).b0()) == kernNode {
  16179. *(*prg.mem[q].hh()).rh() = *(*prg.mem[p].hh()).rh()
  16180. *(*prg.mem[p].hh()).rh() = 0
  16181. prg.flushNodeList(p)
  16182. }
  16183. }
  16184. }
  16185. goto doneWithNode
  16186. case kernNode:
  16187. prg.mathKern(q, prg.curMu)
  16188. goto doneWithNode
  16189. default:
  16190. prg.confusion(strNumber( /* "mlist1" */ 889))
  16191. // \xref[this can't happen mlist1][\quad mlist1]
  16192. }
  16193. // Convert \(n)|nucleus(q)| to an hlist and attach the sub/superscripts
  16194. switch *(*prg.mem[int32(q)+1].hh()).rh() {
  16195. case mathChar, mathTextChar:
  16196. // Create a character node |p| for |nucleus(q)|, possibly followed by a kern node for the italic correction, and set |delta| to the italic correction if a subscript is present
  16197. prg.fetch(halfword(int32(q) + 1))
  16198. if int32(prg.curI.b0) > minQuarterword {
  16199. delta = *prg.fontInfo[prg.italicBase[prg.curF]+(int32(prg.curI.b2)-minQuarterword)/4].int()
  16200. p = prg.newCharacter(prg.curF, eightBits(int32(prg.curC)-minQuarterword))
  16201. if int32(*(*prg.mem[int32(q)+1].hh()).rh()) == mathTextChar && *prg.fontInfo[spaceCode+prg.paramBase[prg.curF]].int() != 0 {
  16202. delta = 0
  16203. } // no italic correction in mid-word of text font
  16204. if int32(*(*prg.mem[int32(q)+3].hh()).rh()) == empty && delta != 0 {
  16205. *(*prg.mem[p].hh()).rh() = prg.newKern(delta)
  16206. delta = 0
  16207. }
  16208. } else {
  16209. p = 0
  16210. }
  16211. case empty:
  16212. p = 0
  16213. case subBox:
  16214. p = *(*prg.mem[int32(q)+1].hh()).lh()
  16215. case subMlist:
  16216. prg.curMlist = *(*prg.mem[int32(q)+1].hh()).lh()
  16217. saveStyle = prg.curStyle
  16218. prg.mlistPenalties = false
  16219. prg.mlistToHlist() // recursive call
  16220. // \xref[recursion]
  16221. prg.curStyle = saveStyle
  16222. // Set up the values...
  16223. {
  16224. if int32(prg.curStyle) < scriptStyle {
  16225. prg.curSize = byte(textSize)
  16226. } else {
  16227. prg.curSize = byte(16 * ((int32(prg.curStyle) - textStyle) / 2))
  16228. }
  16229. prg.curMu = prg.xOverN(*prg.fontInfo[6+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int(), 18)
  16230. }
  16231. p = prg.hpack(*(*prg.mem[30000-3].hh()).rh(), scaled(0), smallNumber(additional))
  16232. default:
  16233. prg.confusion(strNumber( /* "mlist2" */ 890))
  16234. // \xref[this can't happen mlist2][\quad mlist2]
  16235. }
  16236. *prg.mem[int32(q)+1].int() = int32(p)
  16237. if int32(*(*prg.mem[int32(q)+3].hh()).rh()) == empty && int32(*(*prg.mem[int32(q)+2].hh()).rh()) == empty {
  16238. goto checkDimensions
  16239. }
  16240. prg.makeScripts(q, delta)
  16241. checkDimensions:
  16242. z = prg.hpack(halfword(*prg.mem[int32(q)+1].int()), scaled(0), smallNumber(additional))
  16243. if *prg.mem[int32(z)+heightOffset].int() > maxH {
  16244. maxH = *prg.mem[int32(z)+heightOffset].int()
  16245. }
  16246. if *prg.mem[int32(z)+depthOffset].int() > maxD {
  16247. maxD = *prg.mem[int32(z)+depthOffset].int()
  16248. }
  16249. prg.freeNode(z, halfword(boxNodeSize))
  16250. doneWithNoad:
  16251. r1 = q
  16252. rType = *(*prg.mem[r1].hh()).b0()
  16253. doneWithNode:
  16254. q = *(*prg.mem[q].hh()).rh()
  16255. }
  16256. // Convert \(a)a final |bin_noad| to an |ord_noad|
  16257. if int32(rType) == binNoad {
  16258. *(*prg.mem[r1].hh()).b0() = byte(ordNoad)
  16259. }
  16260. // Make a second pass over the mlist, removing all noads and inserting the proper spacing and penalties
  16261. p = uint16(30000 - 3)
  16262. *(*prg.mem[p].hh()).rh() = 0
  16263. q = mlist
  16264. rType = 0
  16265. prg.curStyle = style
  16266. // Set up the values of |cur_size| and |cur_mu|, based on |cur_style|
  16267. {
  16268. if int32(prg.curStyle) < scriptStyle {
  16269. prg.curSize = byte(textSize)
  16270. } else {
  16271. prg.curSize = byte(16 * ((int32(prg.curStyle) - textStyle) / 2))
  16272. }
  16273. prg.curMu = prg.xOverN(*prg.fontInfo[6+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int(), 18)
  16274. }
  16275. for int32(q) != 0 {
  16276. t = byte(ordNoad)
  16277. s = byte(noadSize)
  16278. pen = infPenalty
  16279. switch *(*prg.mem[q].hh()).b0() {
  16280. case opNoad, openNoad, closeNoad, punctNoad,
  16281. innerNoad:
  16282. t = *(*prg.mem[q].hh()).b0()
  16283. case binNoad:
  16284. t = byte(binNoad)
  16285. pen = *prg.eqtb[intBase+binOpPenaltyCode-1].int()
  16286. case relNoad:
  16287. t = byte(relNoad)
  16288. pen = *prg.eqtb[intBase+relPenaltyCode-1].int()
  16289. case ordNoad, vcenterNoad, overNoad, underNoad:
  16290. case radicalNoad:
  16291. s = byte(radicalNoadSize)
  16292. case accentNoad:
  16293. s = byte(accentNoadSize)
  16294. case fractionNoad:
  16295. s = byte(fractionNoadSize)
  16296. case leftNoad, rightNoad:
  16297. t = prg.makeLeftRight(q, style, maxD, maxH)
  16298. case styleNode:
  16299. // Change the current style and |goto delete_q|
  16300. prg.curStyle = *(*prg.mem[q].hh()).b1()
  16301. s = byte(styleNodeSize)
  16302. // Set up the values of |cur_size| and |cur_mu|, based on |cur_style|
  16303. {
  16304. if int32(prg.curStyle) < scriptStyle {
  16305. prg.curSize = byte(textSize)
  16306. } else {
  16307. prg.curSize = byte(16 * ((int32(prg.curStyle) - textStyle) / 2))
  16308. }
  16309. prg.curMu = prg.xOverN(*prg.fontInfo[6+prg.paramBase[*(*prg.eqtb[mathFontBase+2+int32(prg.curSize)-1].hh()).rh()]].int(), 18)
  16310. }
  16311. goto deleteQ
  16312. case whatsitNode, penaltyNode, ruleNode, discNode,
  16313. adjustNode, insNode, markNode, glueNode,
  16314. kernNode: //
  16315. *(*prg.mem[p].hh()).rh() = q
  16316. p = q
  16317. q = *(*prg.mem[q].hh()).rh()
  16318. *(*prg.mem[p].hh()).rh() = 0
  16319. goto done
  16320. default:
  16321. prg.confusion(strNumber( /* "mlist3" */ 891))
  16322. // \xref[this can't happen mlist3][\quad mlist3]
  16323. }
  16324. // Append inter-element spacing based on |r_type| and |t|
  16325. if int32(rType) > 0 {
  16326. switch prg.strPool[int32(rType)*8+int32(t)+prg.magicOffset] {
  16327. case '0':
  16328. x = 0
  16329. // "1"=
  16330. case '1':
  16331. if int32(prg.curStyle) < scriptStyle {
  16332. x = uint16(thinMuSkipCode)
  16333. } else {
  16334. x = 0
  16335. }
  16336. // "2"=
  16337. case '2':
  16338. x = uint16(thinMuSkipCode)
  16339. // "3"=
  16340. case '3':
  16341. if int32(prg.curStyle) < scriptStyle {
  16342. x = uint16(medMuSkipCode)
  16343. } else {
  16344. x = 0
  16345. }
  16346. // "4"=
  16347. case '4':
  16348. if int32(prg.curStyle) < scriptStyle {
  16349. x = uint16(thickMuSkipCode)
  16350. } else {
  16351. x = 0
  16352. }
  16353. default:
  16354. prg.confusion(strNumber( /* "mlist4" */ 893))
  16355. // \xref[this can't happen mlist4][\quad mlist4]
  16356. }
  16357. if int32(x) != 0 {
  16358. y = prg.mathGlue(*(*prg.eqtb[glueBase+int32(x)-1].hh()).rh(), prg.curMu)
  16359. z = prg.newGlue(y)
  16360. *(*prg.mem[y].hh()).rh() = 0
  16361. *(*prg.mem[p].hh()).rh() = z
  16362. p = z
  16363. *(*prg.mem[z].hh()).b1() = byte(int32(x) + 1) // store a symbolic subtype
  16364. }
  16365. }
  16366. // Append any |new_hlist| entries for |q|, and any appropriate penalties
  16367. if *prg.mem[int32(q)+1].int() != 0 {
  16368. *(*prg.mem[p].hh()).rh() = uint16(*prg.mem[int32(q)+1].int())
  16369. for {
  16370. p = *(*prg.mem[p].hh()).rh()
  16371. if int32(*(*prg.mem[p].hh()).rh()) == 0 {
  16372. break
  16373. }
  16374. }
  16375. }
  16376. if penalties {
  16377. if int32(*(*prg.mem[q].hh()).rh()) != 0 {
  16378. if pen < infPenalty {
  16379. rType = *(*prg.mem[*(*prg.mem[q].hh()).rh()].hh()).b0()
  16380. if int32(rType) != penaltyNode {
  16381. if int32(rType) != relNoad {
  16382. z = prg.newPenalty(pen)
  16383. *(*prg.mem[p].hh()).rh() = z
  16384. p = z
  16385. }
  16386. }
  16387. }
  16388. }
  16389. }
  16390. rType = t
  16391. deleteQ:
  16392. r1 = q
  16393. q = *(*prg.mem[q].hh()).rh()
  16394. prg.freeNode(r1, halfword(s))
  16395. done:
  16396. }
  16397. }
  16398. // 768. \[37] Alignment
  16399. // tangle:pos tex.web:15108:18:
  16400. // It's sort of a miracle whenever \.[\\halign] and \.[\\valign] work, because
  16401. // they cut across so many of the control structures of \TeX.
  16402. //
  16403. // Therefore the
  16404. // present page is probably not the best place for a beginner to start reading
  16405. // this program; it is better to master everything else first.
  16406. //
  16407. // Let us focus our thoughts on an example of what the input might be, in order
  16408. // to get some idea about how the alignment miracle happens. The example doesn't
  16409. // do anything useful, but it is sufficiently general to indicate all of the
  16410. // special cases that must be dealt with; please do not be disturbed by its
  16411. // apparent complexity and meaninglessness.
  16412. // $$\vbox[\halign[\.[#]\hfil\cr
  16413. // []\\tabskip 2pt plus 3pt\cr
  16414. // []\\halign to 300pt\[u1\#v1\&\cr
  16415. // \hskip 50pt\\tabskip 1pt plus 1fil u2\#v2\&\cr
  16416. // \hskip 50pt u3\#v3\\cr\cr
  16417. // \hskip 25pt a1\&\\omit a2\&\\vrule\\cr\cr
  16418. // \hskip 25pt \\noalign\[\\vskip 3pt\]\cr
  16419. // \hskip 25pt b1\\span b2\\cr\cr
  16420. // \hskip 25pt \\omit\&c2\\span\\omit\\cr\]\cr]]$$
  16421. // Here's what happens:
  16422. //
  16423. // \yskip
  16424. // (0) When `\.[\\halign to 300pt\[]' is scanned, the |scan_spec| routine
  16425. // places the 300pt dimension onto the |save_stack|, and an |align_group|
  16426. // code is placed above it. This will make it possible to complete the alignment
  16427. // when the matching `\.\]' is found.
  16428. //
  16429. // (1) The preamble is scanned next. Macros in the preamble are not expanded,
  16430. // \xref[preamble]
  16431. // except as part of a tabskip specification. For example, if \.[u2] had been
  16432. // a macro in the preamble above, it would have been expanded, since \TeX\
  16433. // must look for `\.[minus...]' as part of the tabskip glue. A ``preamble list''
  16434. // is constructed based on the user's preamble; in our case it contains the
  16435. // following seven items:
  16436. // $$\vbox[\halign[\.[#]\hfil\qquad&(#)\hfil\cr
  16437. // []\\glue 2pt plus 3pt&the tabskip preceding column 1\cr
  16438. // []\\alignrecord, width $-\infty$&preamble info for column 1\cr
  16439. // []\\glue 2pt plus 3pt&the tabskip between columns 1 and 2\cr
  16440. // []\\alignrecord, width $-\infty$&preamble info for column 2\cr
  16441. // []\\glue 1pt plus 1fil&the tabskip between columns 2 and 3\cr
  16442. // []\\alignrecord, width $-\infty$&preamble info for column 3\cr
  16443. // []\\glue 1pt plus 1fil&the tabskip following column 3\cr]]$$
  16444. // These ``alignrecord'' entries have the same size as an |unset_node|,
  16445. // since they will later be converted into such nodes. However, at the
  16446. // moment they have no |type| or |subtype| fields; they have |info| fields
  16447. // instead, and these |info| fields are initially set to the value |end_span|,
  16448. // for reasons explained below. Furthermore, the alignrecord nodes have no
  16449. // |height| or |depth| fields; these are renamed |u_part| and |v_part|,
  16450. // and they point to token lists for the templates of the alignment.
  16451. // For example, the |u_part| field in the first alignrecord points to the
  16452. // token list `\.[u1]', i.e., the template preceding the `\.\#' for column~1.
  16453. //
  16454. // (2) \TeX\ now looks at what follows the \.[\\cr] that ended the preamble.
  16455. // It is not `\.[\\noalign]' or `\.[\\omit]', so this input is put back to
  16456. // be read again, and the template `\.[u1]' is fed to the scanner. Just
  16457. // before reading `\.[u1]', \TeX\ goes into restricted horizontal mode.
  16458. // Just after reading `\.[u1]', \TeX\ will see `\.[a1]', and then (when the
  16459. // [\.\&] is sensed) \TeX\ will see `\.[v1]'. Then \TeX\ scans an |endv|
  16460. // token, indicating the end of a column. At this point an |unset_node| is
  16461. // created, containing the contents of the current hlist (i.e., `\.[u1a1v1]').
  16462. // The natural width of this unset node replaces the |width| field of the
  16463. // alignrecord for column~1; in general, the alignrecords will record the
  16464. // maximum natural width that has occurred so far in a given column.
  16465. //
  16466. // (3) Since `\.[\\omit]' follows the `\.\&', the templates for column~2
  16467. // are now bypassed. Again \TeX\ goes into restricted horizontal mode and
  16468. // makes an |unset_node| from the resulting hlist; but this time the
  16469. // hlist contains simply `\.[a2]'. The natural width of the new unset box
  16470. // is remembered in the |width| field of the alignrecord for column~2.
  16471. //
  16472. // (4) A third |unset_node| is created for column 3, using essentially the
  16473. // mechanism that worked for column~1; this unset box contains `\.[u3\\vrule
  16474. // v3]'. The vertical rule in this case has running dimensions that will later
  16475. // extend to the height and depth of the whole first row, since each |unset_node|
  16476. // in a row will eventually inherit the height and depth of its enclosing box.
  16477. //
  16478. // (5) The first row has now ended; it is made into a single unset box
  16479. // comprising the following seven items:
  16480. // $$\vbox[\halign[\hbox to 325pt[\qquad\.[#]\hfil]\cr
  16481. // []\\glue 2pt plus 3pt\cr
  16482. // []\\unsetbox for 1 column: u1a1v1\cr
  16483. // []\\glue 2pt plus 3pt\cr
  16484. // []\\unsetbox for 1 column: a2\cr
  16485. // []\\glue 1pt plus 1fil\cr
  16486. // []\\unsetbox for 1 column: u3\\vrule v3\cr
  16487. // []\\glue 1pt plus 1fil\cr]]$$
  16488. // The width of this unset row is unimportant, but it has the correct height
  16489. // and depth, so the correct baselineskip glue will be computed as the row
  16490. // is inserted into a vertical list.
  16491. //
  16492. // (6) Since `\.[\\noalign]' follows the current \.[\\cr], \TeX\ appends
  16493. // additional material (in this case \.[\\vskip 3pt]) to the vertical list.
  16494. // While processing this material, \TeX\ will be in internal vertical
  16495. // mode, and |no_align_group| will be on |save_stack|.
  16496. //
  16497. // (7) The next row produces an unset box that looks like this:
  16498. // $$\vbox[\halign[\hbox to 325pt[\qquad\.[#]\hfil]\cr
  16499. // []\\glue 2pt plus 3pt\cr
  16500. // []\\unsetbox for 2 columns: u1b1v1u2b2v2\cr
  16501. // []\\glue 1pt plus 1fil\cr
  16502. // []\\unsetbox for 1 column: [\rm(empty)]\cr
  16503. // []\\glue 1pt plus 1fil\cr]]$$
  16504. // The natural width of the unset box that spans columns 1~and~2 is stored
  16505. // in a ``span node,'' which we will explain later; the |info| field of the
  16506. // alignrecord for column~1 now points to the new span node, and the |info|
  16507. // of the span node points to |end_span|.
  16508. //
  16509. // (8) The final row produces the unset box
  16510. // $$\vbox[\halign[\hbox to 325pt[\qquad\.[#]\hfil]\cr
  16511. // []\\glue 2pt plus 3pt\cr
  16512. // []\\unsetbox for 1 column: [\rm(empty)]\cr
  16513. // []\\glue 2pt plus 3pt\cr
  16514. // []\\unsetbox for 2 columns: u2c2v2\cr
  16515. // []\\glue 1pt plus 1fil\cr]]$$
  16516. // A new span node is attached to the alignrecord for column 2.
  16517. //
  16518. // (9) The last step is to compute the true column widths and to change all the
  16519. // unset boxes to hboxes, appending the whole works to the vertical list that
  16520. // encloses the \.[\\halign]. The rules for deciding on the final widths of
  16521. // each unset column box will be explained below.
  16522. //
  16523. // \yskip\noindent
  16524. // Note that as \.[\\halign] is being processed, we fearlessly give up control
  16525. // to the rest of \TeX. At critical junctures, an alignment routine is
  16526. // called upon to step in and do some little action, but most of the time
  16527. // these routines just lurk in the background. It's something like
  16528. // post-hypnotic suggestion.
  16529. // 769.
  16530. // tangle:pos tex.web:15239:1:
  16531. // We have mentioned that alignrecords contain no |height| or |depth| fields.
  16532. // Their |glue_sign| and |glue_order| are pre-empted as well, since it
  16533. // is necessary to store information about what to do when a template ends.
  16534. // This information is called the |extra_info| field.
  16535. // 772.
  16536. // tangle:pos tex.web:15281:1:
  16537. // Alignment stack maintenance is handled by a pair of trivial routines
  16538. // called |push_alignment| and |pop_alignment|.
  16539. func (prg *prg) pushAlignment() {
  16540. var (
  16541. p halfword // the new alignment stack node
  16542. )
  16543. p = prg.getNode(alignStackNodeSize)
  16544. *(*prg.mem[p].hh()).rh() = prg.alignPtr
  16545. *(*prg.mem[p].hh()).lh() = prg.curAlign
  16546. *(*prg.mem[int32(p)+1].hh()).lh() = *(*prg.mem[30000-8].hh()).rh()
  16547. *(*prg.mem[int32(p)+1].hh()).rh() = prg.curSpan
  16548. *prg.mem[int32(p)+2].int() = int32(prg.curLoop)
  16549. *prg.mem[int32(p)+3].int() = prg.alignState
  16550. *(*prg.mem[int32(p)+4].hh()).lh() = prg.curHead
  16551. *(*prg.mem[int32(p)+4].hh()).rh() = prg.curTail
  16552. prg.alignPtr = p
  16553. prg.curHead = prg.getAvail()
  16554. }
  16555. func (prg *prg) popAlignment() {
  16556. var (
  16557. p halfword // the top alignment stack node
  16558. )
  16559. {
  16560. *(*prg.mem[prg.curHead].hh()).rh() = prg.avail
  16561. prg.avail = prg.curHead /* dyn_used:= dyn_used-1 ; [ ] */
  16562. }
  16563. p = prg.alignPtr
  16564. prg.curTail = *(*prg.mem[int32(p)+4].hh()).rh()
  16565. prg.curHead = *(*prg.mem[int32(p)+4].hh()).lh()
  16566. prg.alignState = *prg.mem[int32(p)+3].int()
  16567. prg.curLoop = uint16(*prg.mem[int32(p)+2].int())
  16568. prg.curSpan = *(*prg.mem[int32(p)+1].hh()).rh()
  16569. *(*prg.mem[30000-8].hh()).rh() = *(*prg.mem[int32(p)+1].hh()).lh()
  16570. prg.curAlign = *(*prg.mem[p].hh()).lh()
  16571. prg.alignPtr = *(*prg.mem[p].hh()).rh()
  16572. prg.freeNode(p, halfword(alignStackNodeSize))
  16573. }
  16574. // 773.
  16575. // tangle:pos tex.web:15306:1:
  16576. // \TeX\ has eight procedures that govern alignments: |init_align| and
  16577. // |fin_align| are used at the very beginning and the very end; |init_row| and
  16578. // |fin_row| are used at the beginning and end of individual rows; |init_span|
  16579. // is used at the beginning of a sequence of spanned columns (possibly involving
  16580. // only one column); |init_col| and |fin_col| are used at the beginning and
  16581. // end of individual columns; and |align_peek| is used after \.[\\cr] to see
  16582. // whether the next item is \.[\\noalign].
  16583. //
  16584. // We shall consider these routines in the order they are first used during
  16585. // the course of a complete \.[\\halign], namely |init_align|, |align_peek|,
  16586. // |init_row|, |init_span|, |init_col|, |fin_col|, |fin_row|, |fin_align|.
  16587. // 774.
  16588. // tangle:pos tex.web:15318:1:
  16589. // When \.[\\halign] or \.[\\valign] has been scanned in an appropriate
  16590. // mode, \TeX\ calls |init_align|, whose task is to get everything off to a
  16591. // good start. This mostly involves scanning the preamble and putting its
  16592. // information into the preamble list.
  16593. // \xref[preamble]
  16594. // \4
  16595. // Declare the procedure called |get_preamble_token|
  16596. func (prg *prg) getPreambleToken() {
  16597. restart:
  16598. prg.getToken()
  16599. for int32(prg.curChr) == spanCode && int32(prg.curCmd) == tabMark {
  16600. prg.getToken() // this token will be expanded once
  16601. if int32(prg.curCmd) > maxCommand {
  16602. prg.expand()
  16603. prg.getToken()
  16604. }
  16605. }
  16606. if int32(prg.curCmd) == endv {
  16607. prg.fatalError(strNumber( /* "(interwoven alignment preambles are not allowed)" */ 595))
  16608. }
  16609. // \xref[interwoven alignment preambles...]
  16610. if int32(prg.curCmd) == assignGlue && int32(prg.curChr) == glueBase+tabSkipCode {
  16611. prg.scanOptionalEquals()
  16612. prg.scanGlue(smallNumber(glueVal))
  16613. if *prg.eqtb[intBase+globalDefsCode-1].int() > 0 {
  16614. prg.geqDefine(halfword(glueBase+tabSkipCode), quarterword(glueRef), halfword(prg.curVal))
  16615. } else {
  16616. prg.eqDefine(halfword(glueBase+tabSkipCode), quarterword(glueRef), halfword(prg.curVal))
  16617. }
  16618. goto restart
  16619. }
  16620. } // \2
  16621. func (prg *prg) initAlign() {
  16622. var (
  16623. saveCsPtr halfword // |warning_index| value for error messages
  16624. p halfword // for short-term temporary use
  16625. )
  16626. saveCsPtr = prg.curCs // \.[\\halign] or \.[\\valign], usually
  16627. prg.pushAlignment()
  16628. prg.alignState = -1000000 // enter a new alignment level
  16629. // Check for improper alignment in displayed math
  16630. if int32(prg.curList.modeField) == mmode && (int32(prg.curList.tailField) != int32(prg.curList.headField) || *prg.curList.auxField.int() != 0) {
  16631. {
  16632. if int32(prg.interaction) == errorStopMode {
  16633. }
  16634. prg.printNl(strNumber( /* "! " */ 262))
  16635. prg.print( /* "Improper " */ 680)
  16636. }
  16637. prg.printEsc(strNumber( /* "halign" */ 520))
  16638. prg.print( /* " inside $$'s" */ 894)
  16639. // \xref[Improper \\halign...]
  16640. {
  16641. prg.helpPtr = 3
  16642. prg.helpLine[2] = /* "Displays can use special alignments (like \\eqalignno)" */ 895
  16643. prg.helpLine[1] = /* "only if nothing but the alignment itself is between $$'s." */ 896
  16644. prg.helpLine[0] = /* "So I've deleted the formulas that preceded this alignment." */ 897
  16645. }
  16646. prg.error1()
  16647. prg.flushMath()
  16648. }
  16649. prg.pushNest() // enter a new semantic level
  16650. // Change current mode to |-vmode| for \.[\\halign], |-hmode| for \.[\\valign]
  16651. if int32(prg.curList.modeField) == mmode {
  16652. prg.curList.modeField = int16(-vmode)
  16653. *prg.curList.auxField.int() = *prg.nest[int32(prg.nestPtr)-2].auxField.int()
  16654. } else if int32(prg.curList.modeField) > 0 {
  16655. prg.curList.modeField = -prg.curList.modeField
  16656. }
  16657. prg.scanSpec(groupCode(alignGroup), false)
  16658. // Scan the preamble and record it in the |preamble| list
  16659. *(*prg.mem[30000-8].hh()).rh() = 0
  16660. prg.curAlign = uint16(30000 - 8)
  16661. prg.curLoop = 0
  16662. prg.scannerStatus = byte(aligning)
  16663. prg.warningIndex = saveCsPtr
  16664. prg.alignState = -1000000
  16665. // at this point, |cur_cmd=left_brace|
  16666. for true {
  16667. *(*prg.mem[prg.curAlign].hh()).rh() = prg.newParamGlue(smallNumber(tabSkipCode))
  16668. prg.curAlign = *(*prg.mem[prg.curAlign].hh()).rh()
  16669. if int32(prg.curCmd) == carRet {
  16670. goto done
  16671. } // \.[\\cr] ends the preamble
  16672. // Scan preamble text until |cur_cmd| is |tab_mark| or |car_ret|, looking for changes in the tabskip glue; append an alignrecord to the preamble list
  16673. // Scan the template \<u_j>, putting the resulting token list in |hold_head|
  16674. p = uint16(30000 - 4)
  16675. *(*prg.mem[p].hh()).rh() = 0
  16676. for true {
  16677. prg.getPreambleToken()
  16678. if int32(prg.curCmd) == macParam {
  16679. goto done1
  16680. }
  16681. if int32(prg.curCmd) <= carRet && int32(prg.curCmd) >= tabMark && prg.alignState == -1000000 {
  16682. if int32(p) == 30000-4 && int32(prg.curLoop) == 0 && int32(prg.curCmd) == tabMark {
  16683. prg.curLoop = prg.curAlign
  16684. } else {
  16685. {
  16686. if int32(prg.interaction) == errorStopMode {
  16687. }
  16688. prg.printNl(strNumber( /* "! " */ 262))
  16689. prg.print( /* "Missing # inserted in alignment preamble" */ 903)
  16690. }
  16691. // \xref[Missing \# inserted...]
  16692. {
  16693. prg.helpPtr = 3
  16694. prg.helpLine[2] = /* "There should be exactly one # between &'s, when an" */ 904
  16695. prg.helpLine[1] = /* "\\halign or \\valign is being set up. In this case you had" */ 905
  16696. prg.helpLine[0] = /* "none, so I've put one in; maybe that will work." */ 906
  16697. }
  16698. prg.backError()
  16699. goto done1
  16700. }
  16701. } else if int32(prg.curCmd) != spacer || int32(p) != 30000-4 {
  16702. *(*prg.mem[p].hh()).rh() = prg.getAvail()
  16703. p = *(*prg.mem[p].hh()).rh()
  16704. *(*prg.mem[p].hh()).lh() = prg.curTok
  16705. }
  16706. }
  16707. done1:
  16708. ;
  16709. *(*prg.mem[prg.curAlign].hh()).rh() = prg.newNullBox()
  16710. prg.curAlign = *(*prg.mem[prg.curAlign].hh()).rh() // a new alignrecord
  16711. *(*prg.mem[prg.curAlign].hh()).lh() = uint16(30000 - 9)
  16712. *prg.mem[int32(prg.curAlign)+widthOffset].int() = -010000000000
  16713. *prg.mem[int32(prg.curAlign)+heightOffset].int() = int32(*(*prg.mem[30000-4].hh()).rh())
  16714. // Scan the template \<v_j>, putting the resulting token list in |hold_head|
  16715. p = uint16(30000 - 4)
  16716. *(*prg.mem[p].hh()).rh() = 0
  16717. for true {
  16718. continue1:
  16719. prg.getPreambleToken()
  16720. if int32(prg.curCmd) <= carRet && int32(prg.curCmd) >= tabMark && prg.alignState == -1000000 {
  16721. goto done2
  16722. }
  16723. if int32(prg.curCmd) == macParam {
  16724. {
  16725. if int32(prg.interaction) == errorStopMode {
  16726. }
  16727. prg.printNl(strNumber( /* "! " */ 262))
  16728. prg.print( /* "Only one # is allowed per tab" */ 907)
  16729. }
  16730. // \xref[Only one \# is allowed...]
  16731. {
  16732. prg.helpPtr = 3
  16733. prg.helpLine[2] = /* "There should be exactly one # between &'s, when an" */ 904
  16734. prg.helpLine[1] = /* "\\halign or \\valign is being set up. In this case you had" */ 905
  16735. prg.helpLine[0] = /* "more than one, so I'm ignoring all but the first." */ 908
  16736. }
  16737. prg.error1()
  16738. goto continue1
  16739. }
  16740. *(*prg.mem[p].hh()).rh() = prg.getAvail()
  16741. p = *(*prg.mem[p].hh()).rh()
  16742. *(*prg.mem[p].hh()).lh() = prg.curTok
  16743. }
  16744. done2:
  16745. *(*prg.mem[p].hh()).rh() = prg.getAvail()
  16746. p = *(*prg.mem[p].hh()).rh()
  16747. *(*prg.mem[p].hh()).lh() = uint16(07777 + frozenEndTemplate)
  16748. *prg.mem[int32(prg.curAlign)+depthOffset].int() = int32(*(*prg.mem[30000-4].hh()).rh())
  16749. }
  16750. done:
  16751. prg.scannerStatus = byte(normal)
  16752. prg.newSaveLevel(groupCode(alignGroup))
  16753. if int32(*(*prg.eqtb[everyCrLoc-1].hh()).rh()) != 0 {
  16754. prg.beginTokenList(*(*prg.eqtb[everyCrLoc-1].hh()).rh(), quarterword(everyCrText))
  16755. }
  16756. prg.alignPeek() // look for \.[\\noalign] or \.[\\omit]
  16757. }
  16758. // 786.
  16759. // tangle:pos tex.web:15525:1:
  16760. // To start a row (i.e., a `row' that rhymes with `dough' but not with `bough'),
  16761. // we enter a new semantic level, copy the first tabskip glue, and change
  16762. // from internal vertical mode to restricted horizontal mode or vice versa.
  16763. // The |space_factor| and |prev_depth| are not used on this semantic level,
  16764. // but we clear them to zero just to be tidy.
  16765. // \4
  16766. // Declare the procedure called |init_span|
  16767. func (prg *prg) initSpan(p halfword) {
  16768. prg.pushNest()
  16769. if int32(prg.curList.modeField) == -hmode {
  16770. *(*prg.curList.auxField.hh()).lh() = 1000
  16771. } else {
  16772. *prg.curList.auxField.int() = -65536000
  16773. prg.normalParagraph()
  16774. }
  16775. prg.curSpan = p
  16776. }
  16777. //
  16778. func (prg *prg) initRow() {
  16779. prg.pushNest()
  16780. prg.curList.modeField = int16(-hmode - vmode - int32(prg.curList.modeField))
  16781. if int32(prg.curList.modeField) == -hmode {
  16782. *(*prg.curList.auxField.hh()).lh() = 0
  16783. } else {
  16784. *prg.curList.auxField.int() = 0
  16785. }
  16786. {
  16787. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newGlue(*(*prg.mem[int32(*(*prg.mem[30000-8].hh()).rh())+1].hh()).lh())
  16788. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  16789. }
  16790. *(*prg.mem[prg.curList.tailField].hh()).b1() = byte(tabSkipCode + 1)
  16791. prg.curAlign = *(*prg.mem[*(*prg.mem[30000-8].hh()).rh()].hh()).rh()
  16792. prg.curTail = prg.curHead
  16793. prg.initSpan(prg.curAlign)
  16794. }
  16795. // 788.
  16796. // tangle:pos tex.web:15553:1:
  16797. // When a column begins, we assume that |cur_cmd| is either |omit| or else
  16798. // the current token should be put back into the input until the \<u_j>
  16799. // template has been scanned. (Note that |cur_cmd| might be |tab_mark| or
  16800. // |car_ret|.) We also assume that |align_state| is approximately 1000000 at
  16801. // this time. We remain in the same mode, and start the template if it is
  16802. // called for.
  16803. func (prg *prg) initCol() {
  16804. *(*prg.mem[int32(prg.curAlign)+listOffset].hh()).lh() = uint16(prg.curCmd)
  16805. if int32(prg.curCmd) == omit {
  16806. prg.alignState = 0
  16807. } else {
  16808. prg.backInput()
  16809. prg.beginTokenList(halfword(*prg.mem[int32(prg.curAlign)+heightOffset].int()), quarterword(uTemplate))
  16810. } // now |align_state=1000000|
  16811. }
  16812. // 791.
  16813. // tangle:pos tex.web:15592:1:
  16814. // When the |endv| command at the end of a \<v_j> template comes through the
  16815. // scanner, things really start to happen; and it is the |fin_col| routine
  16816. // that makes them happen. This routine returns |true| if a row as well as a
  16817. // column has been finished.
  16818. func (prg *prg) finCol() (r bool) {
  16819. var (
  16820. p halfword // the alignrecord after the current one
  16821. q, r1 halfword // temporary pointers for list manipulation
  16822. s halfword // a new span node
  16823. u halfword // a new unset box
  16824. w scaled // natural width
  16825. o glueOrd // order of infinity
  16826. n halfword // span counter
  16827. )
  16828. if int32(prg.curAlign) == 0 {
  16829. prg.confusion(strNumber( /* "endv" */ 909))
  16830. }
  16831. q = *(*prg.mem[prg.curAlign].hh()).rh()
  16832. if int32(q) == 0 {
  16833. prg.confusion(strNumber( /* "endv" */ 909))
  16834. }
  16835. // \xref[this can't happen endv][\quad endv]
  16836. if prg.alignState < 500000 {
  16837. prg.fatalError(strNumber( /* "(interwoven alignment preambles are not allowed)" */ 595))
  16838. }
  16839. // \xref[interwoven alignment preambles...]
  16840. p = *(*prg.mem[q].hh()).rh()
  16841. // If the preamble list has been traversed, check that the row has ended
  16842. if int32(p) == 0 && int32(*(*prg.mem[int32(prg.curAlign)+listOffset].hh()).lh()) < crCode {
  16843. if int32(prg.curLoop) != 0 {
  16844. *(*prg.mem[q].hh()).rh() = prg.newNullBox()
  16845. p = *(*prg.mem[q].hh()).rh() // a new alignrecord
  16846. *(*prg.mem[p].hh()).lh() = uint16(30000 - 9)
  16847. *prg.mem[int32(p)+widthOffset].int() = -010000000000
  16848. prg.curLoop = *(*prg.mem[prg.curLoop].hh()).rh()
  16849. // Copy the templates from node |cur_loop| into node |p|
  16850. q = uint16(30000 - 4)
  16851. r1 = uint16(*prg.mem[int32(prg.curLoop)+heightOffset].int())
  16852. for int32(r1) != 0 {
  16853. *(*prg.mem[q].hh()).rh() = prg.getAvail()
  16854. q = *(*prg.mem[q].hh()).rh()
  16855. *(*prg.mem[q].hh()).lh() = *(*prg.mem[r1].hh()).lh()
  16856. r1 = *(*prg.mem[r1].hh()).rh()
  16857. }
  16858. *(*prg.mem[q].hh()).rh() = 0
  16859. *prg.mem[int32(p)+heightOffset].int() = int32(*(*prg.mem[30000-4].hh()).rh())
  16860. q = uint16(30000 - 4)
  16861. r1 = uint16(*prg.mem[int32(prg.curLoop)+depthOffset].int())
  16862. for int32(r1) != 0 {
  16863. *(*prg.mem[q].hh()).rh() = prg.getAvail()
  16864. q = *(*prg.mem[q].hh()).rh()
  16865. *(*prg.mem[q].hh()).lh() = *(*prg.mem[r1].hh()).lh()
  16866. r1 = *(*prg.mem[r1].hh()).rh()
  16867. }
  16868. *(*prg.mem[q].hh()).rh() = 0
  16869. *prg.mem[int32(p)+depthOffset].int() = int32(*(*prg.mem[30000-4].hh()).rh())
  16870. prg.curLoop = *(*prg.mem[prg.curLoop].hh()).rh()
  16871. *(*prg.mem[p].hh()).rh() = prg.newGlue(*(*prg.mem[int32(prg.curLoop)+1].hh()).lh())
  16872. *(*prg.mem[*(*prg.mem[p].hh()).rh()].hh()).b1() = byte(tabSkipCode + 1)
  16873. } else {
  16874. {
  16875. if int32(prg.interaction) == errorStopMode {
  16876. }
  16877. prg.printNl(strNumber( /* "! " */ 262))
  16878. prg.print( /* "Extra alignment tab has been changed to " */ 910)
  16879. }
  16880. // \xref[Extra alignment tab...]
  16881. prg.printEsc(strNumber( /* "cr" */ 899))
  16882. {
  16883. prg.helpPtr = 3
  16884. prg.helpLine[2] = /* "You have given more \\span or & marks than there were" */ 911
  16885. prg.helpLine[1] = /* "in the preamble to the \\halign or \\valign now in progress." */ 912
  16886. prg.helpLine[0] = /* "So I'll assume that you meant to type \\cr instead." */ 913
  16887. }
  16888. *(*prg.mem[int32(prg.curAlign)+listOffset].hh()).lh() = uint16(crCode)
  16889. prg.error1()
  16890. }
  16891. }
  16892. if int32(*(*prg.mem[int32(prg.curAlign)+listOffset].hh()).lh()) != spanCode {
  16893. prg.unsave()
  16894. prg.newSaveLevel(groupCode(alignGroup))
  16895. // Package an unset box for the current column and record its width
  16896. {
  16897. if int32(prg.curList.modeField) == -hmode {
  16898. prg.adjustTail = prg.curTail
  16899. u = prg.hpack(*(*prg.mem[prg.curList.headField].hh()).rh(), scaled(0), smallNumber(additional))
  16900. w = *prg.mem[int32(u)+widthOffset].int()
  16901. prg.curTail = prg.adjustTail
  16902. prg.adjustTail = 0
  16903. } else {
  16904. u = prg.vpackage(*(*prg.mem[prg.curList.headField].hh()).rh(), scaled(0), smallNumber(additional), scaled(0))
  16905. w = *prg.mem[int32(u)+heightOffset].int()
  16906. }
  16907. n = uint16(minQuarterword) // this represents a span count of 1
  16908. if int32(prg.curSpan) != int32(prg.curAlign) {
  16909. q = prg.curSpan
  16910. for {
  16911. n = uint16(int32(n) + 1)
  16912. q = *(*prg.mem[*(*prg.mem[q].hh()).rh()].hh()).rh()
  16913. if int32(q) == int32(prg.curAlign) {
  16914. break
  16915. }
  16916. }
  16917. if int32(n) > maxQuarterword {
  16918. prg.confusion(strNumber( /* "256 spans" */ 914))
  16919. } // this can happen, but won't
  16920. // \xref[system dependencies]
  16921. // \xref[this can't happen 256 spans][\quad 256 spans]
  16922. q = prg.curSpan
  16923. for int32(*(*prg.mem[*(*prg.mem[q].hh()).lh()].hh()).rh()) < int32(n) {
  16924. q = *(*prg.mem[q].hh()).lh()
  16925. }
  16926. if int32(*(*prg.mem[*(*prg.mem[q].hh()).lh()].hh()).rh()) > int32(n) {
  16927. s = prg.getNode(spanNodeSize)
  16928. *(*prg.mem[s].hh()).lh() = *(*prg.mem[q].hh()).lh()
  16929. *(*prg.mem[s].hh()).rh() = n
  16930. *(*prg.mem[q].hh()).lh() = s
  16931. *prg.mem[int32(s)+widthOffset].int() = w
  16932. } else if *prg.mem[int32(*(*prg.mem[q].hh()).lh())+widthOffset].int() < w {
  16933. *prg.mem[int32(*(*prg.mem[q].hh()).lh())+widthOffset].int() = w
  16934. }
  16935. } else if w > *prg.mem[int32(prg.curAlign)+widthOffset].int() {
  16936. *prg.mem[int32(prg.curAlign)+widthOffset].int() = w
  16937. }
  16938. *(*prg.mem[u].hh()).b0() = byte(unsetNode)
  16939. *(*prg.mem[u].hh()).b1() = byte(n)
  16940. // Determine the stretch order
  16941. if prg.totalStretch[filll] != 0 {
  16942. o = byte(filll)
  16943. } else if prg.totalStretch[fill] != 0 {
  16944. o = byte(fill)
  16945. } else if prg.totalStretch[fil] != 0 {
  16946. o = byte(fil)
  16947. } else {
  16948. o = byte(normal)
  16949. }
  16950. *(*prg.mem[int32(u)+listOffset].hh()).b1() = o
  16951. *prg.mem[int32(u)+glueOffset].int() = prg.totalStretch[o]
  16952. // Determine the shrink order
  16953. if prg.totalShrink[filll] != 0 {
  16954. o = byte(filll)
  16955. } else if prg.totalShrink[fill] != 0 {
  16956. o = byte(fill)
  16957. } else if prg.totalShrink[fil] != 0 {
  16958. o = byte(fil)
  16959. } else {
  16960. o = byte(normal)
  16961. }
  16962. *(*prg.mem[int32(u)+listOffset].hh()).b0() = o
  16963. *prg.mem[int32(u)+4].int() = prg.totalShrink[o]
  16964. prg.popNest()
  16965. *(*prg.mem[prg.curList.tailField].hh()).rh() = u
  16966. prg.curList.tailField = u
  16967. }
  16968. // Copy the tabskip glue between columns
  16969. {
  16970. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newGlue(*(*prg.mem[int32(*(*prg.mem[prg.curAlign].hh()).rh())+1].hh()).lh())
  16971. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  16972. }
  16973. *(*prg.mem[prg.curList.tailField].hh()).b1() = byte(tabSkipCode + 1)
  16974. if int32(*(*prg.mem[int32(prg.curAlign)+listOffset].hh()).lh()) >= crCode {
  16975. r = true
  16976. goto exit
  16977. }
  16978. prg.initSpan(p)
  16979. }
  16980. prg.alignState = 1000000
  16981. // Get the next non-blank non-call token
  16982. for {
  16983. prg.getXToken()
  16984. if int32(prg.curCmd) != spacer {
  16985. break
  16986. }
  16987. }
  16988. prg.curAlign = p
  16989. prg.initCol()
  16990. r = false
  16991. exit:
  16992. ;
  16993. return r
  16994. }
  16995. // 799.
  16996. // tangle:pos tex.web:15714:1:
  16997. // At the end of a row, we append an unset box to the current vlist (for
  16998. // \.[\\halign]) or the current hlist (for \.[\\valign]). This unset box
  16999. // contains the unset boxes for the columns, separated by the tabskip glue.
  17000. // Everything will be set later.
  17001. func (prg *prg) finRow() {
  17002. var (
  17003. p halfword // the new unset box
  17004. )
  17005. if int32(prg.curList.modeField) == -hmode {
  17006. p = prg.hpack(*(*prg.mem[prg.curList.headField].hh()).rh(), scaled(0), smallNumber(additional))
  17007. prg.popNest()
  17008. prg.appendToVlist(p)
  17009. if int32(prg.curHead) != int32(prg.curTail) {
  17010. *(*prg.mem[prg.curList.tailField].hh()).rh() = *(*prg.mem[prg.curHead].hh()).rh()
  17011. prg.curList.tailField = prg.curTail
  17012. }
  17013. } else {
  17014. p = prg.vpackage(*(*prg.mem[prg.curList.headField].hh()).rh(), scaled(0), smallNumber(additional), scaled(07777777777))
  17015. prg.popNest()
  17016. *(*prg.mem[prg.curList.tailField].hh()).rh() = p
  17017. prg.curList.tailField = p
  17018. *(*prg.curList.auxField.hh()).lh() = 1000
  17019. }
  17020. *(*prg.mem[p].hh()).b0() = byte(unsetNode)
  17021. *prg.mem[int32(p)+glueOffset].int() = 0
  17022. if int32(*(*prg.eqtb[everyCrLoc-1].hh()).rh()) != 0 {
  17023. prg.beginTokenList(*(*prg.eqtb[everyCrLoc-1].hh()).rh(), quarterword(everyCrText))
  17024. }
  17025. prg.alignPeek()
  17026. } // \2
  17027. func (prg *prg) finAlign() {
  17028. var (
  17029. p, q, r1, s, u, v halfword // registers for the list operations
  17030. t, w scaled // width of column
  17031. o scaled // shift offset for unset boxes
  17032. n halfword // matching span amount
  17033. ruleSave scaled // temporary storage for |overfull_rule|
  17034. auxSave memoryWord // temporary storage for |aux|
  17035. )
  17036. if int32(prg.curGroup) != alignGroup {
  17037. prg.confusion(strNumber( /* "align1" */ 915))
  17038. }
  17039. // \xref[this can't happen align][\quad align]
  17040. prg.unsave() // that |align_group| was for individual entries
  17041. if int32(prg.curGroup) != alignGroup {
  17042. prg.confusion(strNumber( /* "align0" */ 916))
  17043. }
  17044. prg.unsave() // that |align_group| was for the whole alignment
  17045. if int32(prg.nest[int32(prg.nestPtr)-1].modeField) == mmode {
  17046. o = *prg.eqtb[dimenBase+displayIndentCode-1].int()
  17047. } else {
  17048. o = 0
  17049. }
  17050. // Go through the preamble list, determining the column widths and changing the alignrecords to dummy unset boxes
  17051. q = *(*prg.mem[*(*prg.mem[30000-8].hh()).rh()].hh()).rh()
  17052. for {
  17053. prg.flushList(halfword(*prg.mem[int32(q)+heightOffset].int()))
  17054. prg.flushList(halfword(*prg.mem[int32(q)+depthOffset].int()))
  17055. p = *(*prg.mem[*(*prg.mem[q].hh()).rh()].hh()).rh()
  17056. if *prg.mem[int32(q)+widthOffset].int() == -010000000000 {
  17057. *prg.mem[int32(q)+widthOffset].int() = 0
  17058. r1 = *(*prg.mem[q].hh()).rh()
  17059. s = *(*prg.mem[int32(r1)+1].hh()).lh()
  17060. if int32(s) != memBot {
  17061. *(*prg.mem[memBot].hh()).rh() = uint16(int32(*(*prg.mem[memBot].hh()).rh()) + 1)
  17062. prg.deleteGlueRef(s)
  17063. *(*prg.mem[int32(r1)+1].hh()).lh() = uint16(memBot)
  17064. }
  17065. }
  17066. if int32(*(*prg.mem[q].hh()).lh()) != 30000-9 {
  17067. t = *prg.mem[int32(q)+widthOffset].int() + *prg.mem[int32(*(*prg.mem[int32(*(*prg.mem[q].hh()).rh())+1].hh()).lh())+widthOffset].int()
  17068. r1 = *(*prg.mem[q].hh()).lh()
  17069. s = uint16(30000 - 9)
  17070. *(*prg.mem[s].hh()).lh() = p
  17071. n = uint16(minQuarterword + 1)
  17072. for {
  17073. *prg.mem[int32(r1)+widthOffset].int() = *prg.mem[int32(r1)+widthOffset].int() - t
  17074. u = *(*prg.mem[r1].hh()).lh()
  17075. for int32(*(*prg.mem[r1].hh()).rh()) > int32(n) {
  17076. s = *(*prg.mem[s].hh()).lh()
  17077. n = uint16(int32(*(*prg.mem[*(*prg.mem[s].hh()).lh()].hh()).rh()) + 1)
  17078. }
  17079. if int32(*(*prg.mem[r1].hh()).rh()) < int32(n) {
  17080. *(*prg.mem[r1].hh()).lh() = *(*prg.mem[s].hh()).lh()
  17081. *(*prg.mem[s].hh()).lh() = r1
  17082. *(*prg.mem[r1].hh()).rh() = uint16(int32(*(*prg.mem[r1].hh()).rh()) - 1)
  17083. s = r1
  17084. } else {
  17085. if *prg.mem[int32(r1)+widthOffset].int() > *prg.mem[int32(*(*prg.mem[s].hh()).lh())+widthOffset].int() {
  17086. *prg.mem[int32(*(*prg.mem[s].hh()).lh())+widthOffset].int() = *prg.mem[int32(r1)+widthOffset].int()
  17087. }
  17088. prg.freeNode(r1, halfword(spanNodeSize))
  17089. }
  17090. r1 = u
  17091. if int32(r1) == 30000-9 {
  17092. break
  17093. }
  17094. }
  17095. }
  17096. *(*prg.mem[q].hh()).b0() = byte(unsetNode)
  17097. *(*prg.mem[q].hh()).b1() = byte(minQuarterword)
  17098. *prg.mem[int32(q)+heightOffset].int() = 0
  17099. *prg.mem[int32(q)+depthOffset].int() = 0
  17100. *(*prg.mem[int32(q)+listOffset].hh()).b1() = byte(normal)
  17101. *(*prg.mem[int32(q)+listOffset].hh()).b0() = byte(normal)
  17102. *prg.mem[int32(q)+glueOffset].int() = 0
  17103. *prg.mem[int32(q)+4].int() = 0
  17104. q = p
  17105. if int32(q) == 0 {
  17106. break
  17107. }
  17108. }
  17109. // Package the preamble list, to determine the actual tabskip glue amounts, and let |p| point to this prototype box
  17110. prg.savePtr = uint16(int32(prg.savePtr) - 2)
  17111. prg.packBeginLine = -prg.curList.mlField
  17112. if int32(prg.curList.modeField) == -vmode {
  17113. ruleSave = *prg.eqtb[dimenBase+overfullRuleCode-1].int()
  17114. *prg.eqtb[dimenBase+overfullRuleCode-1].int() = 0 // prevent rule from being packaged
  17115. p = prg.hpack(*(*prg.mem[30000-8].hh()).rh(), *prg.saveStack[int32(prg.savePtr)+1].int(), smallNumber(*prg.saveStack[int32(prg.savePtr)+0].int()))
  17116. *prg.eqtb[dimenBase+overfullRuleCode-1].int() = ruleSave
  17117. } else {
  17118. q = *(*prg.mem[*(*prg.mem[30000-8].hh()).rh()].hh()).rh()
  17119. for {
  17120. *prg.mem[int32(q)+heightOffset].int() = *prg.mem[int32(q)+widthOffset].int()
  17121. *prg.mem[int32(q)+widthOffset].int() = 0
  17122. q = *(*prg.mem[*(*prg.mem[q].hh()).rh()].hh()).rh()
  17123. if int32(q) == 0 {
  17124. break
  17125. }
  17126. }
  17127. p = prg.vpackage(*(*prg.mem[30000-8].hh()).rh(), *prg.saveStack[int32(prg.savePtr)+1].int(), smallNumber(*prg.saveStack[int32(prg.savePtr)+0].int()), scaled(07777777777))
  17128. q = *(*prg.mem[*(*prg.mem[30000-8].hh()).rh()].hh()).rh()
  17129. for {
  17130. *prg.mem[int32(q)+widthOffset].int() = *prg.mem[int32(q)+heightOffset].int()
  17131. *prg.mem[int32(q)+heightOffset].int() = 0
  17132. q = *(*prg.mem[*(*prg.mem[q].hh()).rh()].hh()).rh()
  17133. if int32(q) == 0 {
  17134. break
  17135. }
  17136. }
  17137. }
  17138. prg.packBeginLine = 0
  17139. // Set the glue in all the unset boxes of the current list
  17140. q = *(*prg.mem[prg.curList.headField].hh()).rh()
  17141. s = prg.curList.headField
  17142. for int32(q) != 0 {
  17143. if !(int32(q) >= int32(prg.hiMemMin)) {
  17144. if int32(*(*prg.mem[q].hh()).b0()) == unsetNode {
  17145. if int32(prg.curList.modeField) == -vmode {
  17146. *(*prg.mem[q].hh()).b0() = byte(hlistNode)
  17147. *prg.mem[int32(q)+widthOffset].int() = *prg.mem[int32(p)+widthOffset].int()
  17148. } else {
  17149. *(*prg.mem[q].hh()).b0() = byte(vlistNode)
  17150. *prg.mem[int32(q)+heightOffset].int() = *prg.mem[int32(p)+heightOffset].int()
  17151. }
  17152. *(*prg.mem[int32(q)+listOffset].hh()).b1() = *(*prg.mem[int32(p)+listOffset].hh()).b1()
  17153. *(*prg.mem[int32(q)+listOffset].hh()).b0() = *(*prg.mem[int32(p)+listOffset].hh()).b0()
  17154. *prg.mem[int32(q)+glueOffset].gr() = *prg.mem[int32(p)+glueOffset].gr()
  17155. *prg.mem[int32(q)+4].int() = o
  17156. r1 = *(*prg.mem[*(*prg.mem[int32(q)+listOffset].hh()).rh()].hh()).rh()
  17157. s = *(*prg.mem[*(*prg.mem[int32(p)+listOffset].hh()).rh()].hh()).rh()
  17158. for {
  17159. // Set the glue in node |r| and change it from an unset node
  17160. n = uint16(*(*prg.mem[r1].hh()).b1())
  17161. t = *prg.mem[int32(s)+widthOffset].int()
  17162. w = t
  17163. u = uint16(30000 - 4)
  17164. for int32(n) > minQuarterword {
  17165. n = uint16(int32(n) - 1)
  17166. // Append tabskip glue and an empty box to list |u|, and update |s| and |t| as the prototype nodes are passed
  17167. s = *(*prg.mem[s].hh()).rh()
  17168. v = *(*prg.mem[int32(s)+1].hh()).lh()
  17169. *(*prg.mem[u].hh()).rh() = prg.newGlue(v)
  17170. u = *(*prg.mem[u].hh()).rh()
  17171. *(*prg.mem[u].hh()).b1() = byte(tabSkipCode + 1)
  17172. t = t + *prg.mem[int32(v)+widthOffset].int()
  17173. if int32(*(*prg.mem[int32(p)+listOffset].hh()).b0()) == stretching {
  17174. if int32(*(*prg.mem[v].hh()).b0()) == int32(*(*prg.mem[int32(p)+listOffset].hh()).b1()) {
  17175. t = t + round(float64(*prg.mem[int32(p)+glueOffset].gr())*float64(*prg.mem[int32(v)+2].int()))
  17176. }
  17177. // \xref[real multiplication]
  17178. } else if int32(*(*prg.mem[int32(p)+listOffset].hh()).b0()) == shrinking {
  17179. if int32(*(*prg.mem[v].hh()).b1()) == int32(*(*prg.mem[int32(p)+listOffset].hh()).b1()) {
  17180. t = t - round(float64(*prg.mem[int32(p)+glueOffset].gr())*float64(*prg.mem[int32(v)+3].int()))
  17181. }
  17182. }
  17183. s = *(*prg.mem[s].hh()).rh()
  17184. *(*prg.mem[u].hh()).rh() = prg.newNullBox()
  17185. u = *(*prg.mem[u].hh()).rh()
  17186. t = t + *prg.mem[int32(s)+widthOffset].int()
  17187. if int32(prg.curList.modeField) == -vmode {
  17188. *prg.mem[int32(u)+widthOffset].int() = *prg.mem[int32(s)+widthOffset].int()
  17189. } else {
  17190. *(*prg.mem[u].hh()).b0() = byte(vlistNode)
  17191. *prg.mem[int32(u)+heightOffset].int() = *prg.mem[int32(s)+widthOffset].int()
  17192. }
  17193. }
  17194. if int32(prg.curList.modeField) == -vmode {
  17195. *prg.mem[int32(r1)+heightOffset].int() = *prg.mem[int32(q)+heightOffset].int()
  17196. *prg.mem[int32(r1)+depthOffset].int() = *prg.mem[int32(q)+depthOffset].int()
  17197. if t == *prg.mem[int32(r1)+widthOffset].int() {
  17198. *(*prg.mem[int32(r1)+listOffset].hh()).b0() = byte(normal)
  17199. *(*prg.mem[int32(r1)+listOffset].hh()).b1() = byte(normal)
  17200. *prg.mem[int32(r1)+glueOffset].gr() = float32(0.0)
  17201. } else if t > *prg.mem[int32(r1)+widthOffset].int() {
  17202. *(*prg.mem[int32(r1)+listOffset].hh()).b0() = byte(stretching)
  17203. if *prg.mem[int32(r1)+glueOffset].int() == 0 {
  17204. *prg.mem[int32(r1)+glueOffset].gr() = float32(0.0)
  17205. } else {
  17206. *prg.mem[int32(r1)+glueOffset].gr() = float32(float64(t-*prg.mem[int32(r1)+widthOffset].int()) / float64(*prg.mem[int32(r1)+glueOffset].int()))
  17207. }
  17208. // \xref[real division]
  17209. } else {
  17210. *(*prg.mem[int32(r1)+listOffset].hh()).b1() = *(*prg.mem[int32(r1)+listOffset].hh()).b0()
  17211. *(*prg.mem[int32(r1)+listOffset].hh()).b0() = byte(shrinking)
  17212. if *prg.mem[int32(r1)+4].int() == 0 {
  17213. *prg.mem[int32(r1)+glueOffset].gr() = float32(0.0)
  17214. } else if int32(*(*prg.mem[int32(r1)+listOffset].hh()).b1()) == normal && *prg.mem[int32(r1)+widthOffset].int()-t > *prg.mem[int32(r1)+4].int() {
  17215. *prg.mem[int32(r1)+glueOffset].gr() = float32(1.0)
  17216. } else {
  17217. *prg.mem[int32(r1)+glueOffset].gr() = float32(float64(*prg.mem[int32(r1)+widthOffset].int()-t) / float64(*prg.mem[int32(r1)+4].int()))
  17218. }
  17219. }
  17220. *prg.mem[int32(r1)+widthOffset].int() = w
  17221. *(*prg.mem[r1].hh()).b0() = byte(hlistNode)
  17222. } else {
  17223. // Make the unset node |r| into a |vlist_node| of height |w|, setting the glue as if the height were |t|
  17224. *prg.mem[int32(r1)+widthOffset].int() = *prg.mem[int32(q)+widthOffset].int()
  17225. if t == *prg.mem[int32(r1)+heightOffset].int() {
  17226. *(*prg.mem[int32(r1)+listOffset].hh()).b0() = byte(normal)
  17227. *(*prg.mem[int32(r1)+listOffset].hh()).b1() = byte(normal)
  17228. *prg.mem[int32(r1)+glueOffset].gr() = float32(0.0)
  17229. } else if t > *prg.mem[int32(r1)+heightOffset].int() {
  17230. *(*prg.mem[int32(r1)+listOffset].hh()).b0() = byte(stretching)
  17231. if *prg.mem[int32(r1)+glueOffset].int() == 0 {
  17232. *prg.mem[int32(r1)+glueOffset].gr() = float32(0.0)
  17233. } else {
  17234. *prg.mem[int32(r1)+glueOffset].gr() = float32(float64(t-*prg.mem[int32(r1)+heightOffset].int()) / float64(*prg.mem[int32(r1)+glueOffset].int()))
  17235. }
  17236. // \xref[real division]
  17237. } else {
  17238. *(*prg.mem[int32(r1)+listOffset].hh()).b1() = *(*prg.mem[int32(r1)+listOffset].hh()).b0()
  17239. *(*prg.mem[int32(r1)+listOffset].hh()).b0() = byte(shrinking)
  17240. if *prg.mem[int32(r1)+4].int() == 0 {
  17241. *prg.mem[int32(r1)+glueOffset].gr() = float32(0.0)
  17242. } else if int32(*(*prg.mem[int32(r1)+listOffset].hh()).b1()) == normal && *prg.mem[int32(r1)+heightOffset].int()-t > *prg.mem[int32(r1)+4].int() {
  17243. *prg.mem[int32(r1)+glueOffset].gr() = float32(1.0)
  17244. } else {
  17245. *prg.mem[int32(r1)+glueOffset].gr() = float32(float64(*prg.mem[int32(r1)+heightOffset].int()-t) / float64(*prg.mem[int32(r1)+4].int()))
  17246. }
  17247. }
  17248. *prg.mem[int32(r1)+heightOffset].int() = w
  17249. *(*prg.mem[r1].hh()).b0() = byte(vlistNode)
  17250. }
  17251. *prg.mem[int32(r1)+4].int() = 0
  17252. if int32(u) != 30000-4 {
  17253. *(*prg.mem[u].hh()).rh() = *(*prg.mem[r1].hh()).rh()
  17254. *(*prg.mem[r1].hh()).rh() = *(*prg.mem[30000-4].hh()).rh()
  17255. r1 = u
  17256. }
  17257. r1 = *(*prg.mem[*(*prg.mem[r1].hh()).rh()].hh()).rh()
  17258. s = *(*prg.mem[*(*prg.mem[s].hh()).rh()].hh()).rh()
  17259. if int32(r1) == 0 {
  17260. break
  17261. }
  17262. }
  17263. } else if int32(*(*prg.mem[q].hh()).b0()) == ruleNode {
  17264. if *prg.mem[int32(q)+widthOffset].int() == -010000000000 {
  17265. *prg.mem[int32(q)+widthOffset].int() = *prg.mem[int32(p)+widthOffset].int()
  17266. }
  17267. if *prg.mem[int32(q)+heightOffset].int() == -010000000000 {
  17268. *prg.mem[int32(q)+heightOffset].int() = *prg.mem[int32(p)+heightOffset].int()
  17269. }
  17270. if *prg.mem[int32(q)+depthOffset].int() == -010000000000 {
  17271. *prg.mem[int32(q)+depthOffset].int() = *prg.mem[int32(p)+depthOffset].int()
  17272. }
  17273. if o != 0 {
  17274. r1 = *(*prg.mem[q].hh()).rh()
  17275. *(*prg.mem[q].hh()).rh() = 0
  17276. q = prg.hpack(q, scaled(0), smallNumber(additional))
  17277. *prg.mem[int32(q)+4].int() = o
  17278. *(*prg.mem[q].hh()).rh() = r1
  17279. *(*prg.mem[s].hh()).rh() = q
  17280. }
  17281. }
  17282. }
  17283. s = q
  17284. q = *(*prg.mem[q].hh()).rh()
  17285. }
  17286. prg.flushNodeList(p)
  17287. prg.popAlignment()
  17288. // Insert the \(c)current list into its environment
  17289. auxSave = prg.curList.auxField
  17290. p = *(*prg.mem[prg.curList.headField].hh()).rh()
  17291. q = prg.curList.tailField
  17292. prg.popNest()
  17293. if int32(prg.curList.modeField) == mmode {
  17294. prg.doAssignments()
  17295. if int32(prg.curCmd) != mathShift {
  17296. {
  17297. if int32(prg.interaction) == errorStopMode {
  17298. }
  17299. prg.printNl(strNumber( /* "! " */ 262))
  17300. prg.print( /* "Missing $$ inserted" */ 1170)
  17301. }
  17302. // \xref[Missing [\$\$] inserted]
  17303. {
  17304. prg.helpPtr = 2
  17305. prg.helpLine[1] = /* "Displays can use special alignments (like \\eqalignno)" */ 895
  17306. prg.helpLine[0] = /* "only if nothing but the alignment itself is between $$'s." */ 896
  17307. }
  17308. prg.backError()
  17309. } else {
  17310. // Check that another \.\$ follows
  17311. prg.getXToken()
  17312. if int32(prg.curCmd) != mathShift {
  17313. {
  17314. if int32(prg.interaction) == errorStopMode {
  17315. }
  17316. prg.printNl(strNumber( /* "! " */ 262))
  17317. prg.print( /* "Display math should end with $$" */ 1166)
  17318. }
  17319. // \xref[Display math...with \$\$]
  17320. {
  17321. prg.helpPtr = 2
  17322. prg.helpLine[1] = /* "The `$' that I just saw supposedly matches a previous `$$'." */ 1167
  17323. prg.helpLine[0] = /* "So I shall assume that you typed `$$' both times." */ 1168
  17324. }
  17325. prg.backError()
  17326. }
  17327. }
  17328. prg.popNest()
  17329. {
  17330. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newPenalty(*prg.eqtb[intBase+preDisplayPenaltyCode-1].int())
  17331. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  17332. }
  17333. {
  17334. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newParamGlue(smallNumber(aboveDisplaySkipCode))
  17335. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  17336. }
  17337. *(*prg.mem[prg.curList.tailField].hh()).rh() = p
  17338. if int32(p) != 0 {
  17339. prg.curList.tailField = q
  17340. }
  17341. {
  17342. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newPenalty(*prg.eqtb[intBase+postDisplayPenaltyCode-1].int())
  17343. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  17344. }
  17345. {
  17346. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newParamGlue(smallNumber(belowDisplaySkipCode))
  17347. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  17348. }
  17349. *prg.curList.auxField.int() = *auxSave.int()
  17350. prg.resumeAfterDisplay()
  17351. } else {
  17352. prg.curList.auxField = auxSave
  17353. *(*prg.mem[prg.curList.tailField].hh()).rh() = p
  17354. if int32(p) != 0 {
  17355. prg.curList.tailField = q
  17356. }
  17357. if int32(prg.curList.modeField) == vmode {
  17358. prg.buildPage()
  17359. }
  17360. }
  17361. }
  17362. //
  17363. func (prg *prg) alignPeek() {
  17364. restart:
  17365. prg.alignState = 1000000
  17366. // Get the next non-blank non-call token
  17367. for {
  17368. prg.getXToken()
  17369. if int32(prg.curCmd) != spacer {
  17370. break
  17371. }
  17372. }
  17373. if int32(prg.curCmd) == noAlign {
  17374. prg.scanLeftBrace()
  17375. prg.newSaveLevel(groupCode(noAlignGroup))
  17376. if int32(prg.curList.modeField) == -vmode {
  17377. prg.normalParagraph()
  17378. }
  17379. } else if int32(prg.curCmd) == rightBrace {
  17380. prg.finAlign()
  17381. } else if int32(prg.curCmd) == carRet && int32(prg.curChr) == crCrCode {
  17382. goto restart
  17383. } else {
  17384. prg.initRow() // start a new row
  17385. prg.initCol() // start a new column and replace what we peeked at
  17386. }
  17387. }
  17388. // 813. \[38] Breaking paragraphs into lines
  17389. // tangle:pos tex.web:15997:39:
  17390. // We come now to what is probably the most interesting algorithm of \TeX:
  17391. // the mechanism for choosing the ``best possible'' breakpoints that yield
  17392. // the individual lines of a paragraph. \TeX's line-breaking algorithm takes
  17393. // a given horizontal list and converts it to a sequence of boxes that are
  17394. // appended to the current vertical list. In the course of doing this, it
  17395. // creates a special data structure containing three kinds of records that are
  17396. // not used elsewhere in \TeX. Such nodes are created while a paragraph is
  17397. // being processed, and they are destroyed afterwards; thus, the other parts
  17398. // of \TeX\ do not need to know anything about how line-breaking is done.
  17399. //
  17400. // The method used here is based on an approach devised by Michael F. Plass and
  17401. // \xref[Plass, Michael Frederick]
  17402. // \xref[Knuth, Donald Ervin]
  17403. // the author in 1977, subsequently generalized and improved by the same two
  17404. // people in 1980. A detailed discussion appears in [\sl Software---Practice
  17405. // and Experience \bf11] (1981), 1119--1184, where it is shown that the
  17406. // line-breaking problem can be regarded as a special case of the problem of
  17407. // computing the shortest path in an acyclic network. The cited paper includes
  17408. // numerous examples and describes the history of line breaking as it has been
  17409. // practiced by printers through the ages. The present implementation adds two
  17410. // new ideas to the algorithm of 1980: Memory space requirements are considerably
  17411. // reduced by using smaller records for inactive nodes than for active ones,
  17412. // and arithmetic overflow is avoided by using ``delta distances'' instead of
  17413. // keeping track of the total distance from the beginning of the paragraph to the
  17414. // current point.
  17415. // 815.
  17416. // tangle:pos tex.web:16048:1:
  17417. // Since |line_break| is a rather lengthy procedure---sort of a small world unto
  17418. // itself---we must build it up little by little, somewhat more cautiously
  17419. // than we have done with the simpler procedures of \TeX. Here is the
  17420. // general outline.
  17421. // \4
  17422. // Declare subprocedures for |line_break|
  17423. func (prg *prg) finiteShrink(p halfword) (r halfword) { // recovers from infinite shrinkage
  17424. var (
  17425. q halfword // new glue specification
  17426. )
  17427. if prg.noShrinkErrorYet {
  17428. prg.noShrinkErrorYet = false
  17429. // if eqtb[int_base+ tracing_paragraphs_code].int >0 then end_diagnostic(true); [ ]
  17430. {
  17431. if int32(prg.interaction) == errorStopMode {
  17432. }
  17433. prg.printNl(strNumber( /* "! " */ 262))
  17434. prg.print( /* "Infinite glue shrinkage found in a paragraph" */ 917)
  17435. }
  17436. // \xref[Infinite glue shrinkage...]
  17437. {
  17438. prg.helpPtr = 5
  17439. prg.helpLine[4] = /* "The paragraph just ended includes some glue that has" */ 918
  17440. prg.helpLine[3] = /* "infinite shrinkability, e.g., `\\hskip 0pt minus 1fil'." */ 919
  17441. prg.helpLine[2] = /* "Such glue doesn't belong there---it allows a paragraph" */ 920
  17442. prg.helpLine[1] = /* "of any length to fit on one line. But it's safe to proceed," */ 921
  17443. prg.helpLine[0] = /* "since the offensive shrinkability has been made finite." */ 922
  17444. }
  17445. prg.error1()
  17446. // if eqtb[int_base+ tracing_paragraphs_code].int >0 then begin_diagnostic; [ ]
  17447. }
  17448. q = prg.newSpec(p)
  17449. *(*prg.mem[q].hh()).b1() = byte(normal)
  17450. prg.deleteGlueRef(p)
  17451. r = q
  17452. return r
  17453. }
  17454. func (prg *prg) tryBreak(pi int32, breakType smallNumber) {
  17455. var (
  17456. r1 halfword // runs through the active list
  17457. prevR halfword // stays a step behind |r|
  17458. oldL halfword // maximum line number in current equivalence class of lines
  17459. noBreakYet bool // have we found a feasible break at |cur_p|?
  17460. // Other local variables for |try_break|
  17461. prevPrevR halfword // a step behind |prev_r|, if |type(prev_r)=delta_node|
  17462. s halfword // runs through nodes ahead of |cur_p|
  17463. q halfword // points to a new node being created
  17464. v halfword // points to a glue specification or a node ahead of |cur_p|
  17465. t int32 // node count, if |cur_p| is a discretionary node
  17466. f internalFontNumber // used in character width calculation
  17467. l halfword // line number of current active node
  17468. nodeRStaysActive bool // should node |r| remain in the active list?
  17469. lineWidth scaled // the current line will be justified to this width
  17470. fitClass/* veryLooseFit..tightFit */ byte // possible fitness class of test line
  17471. b halfword // badness of test line
  17472. d int32 // demerits of test line
  17473. artificialDemerits bool // has |d| been forced to zero?
  17474. shortfall scaled // used in badness calculations
  17475. )
  17476. if abs(pi) >= infPenalty {
  17477. if pi > 0 {
  17478. goto exit
  17479. } else {
  17480. pi = ejectPenalty
  17481. }
  17482. }
  17483. noBreakYet = true
  17484. prevR = uint16(30000 - 7)
  17485. oldL = 0
  17486. prg.curActiveWidth[1-1] = prg.activeWidth[1-1]
  17487. prg.curActiveWidth[2-1] = prg.activeWidth[2-1]
  17488. prg.curActiveWidth[3-1] = prg.activeWidth[3-1]
  17489. prg.curActiveWidth[4-1] = prg.activeWidth[4-1]
  17490. prg.curActiveWidth[5-1] = prg.activeWidth[5-1]
  17491. prg.curActiveWidth[6-1] = prg.activeWidth[6-1]
  17492. for true {
  17493. continue1:
  17494. r1 = *(*prg.mem[prevR].hh()).rh()
  17495. // If node |r| is of type |delta_node|, update |cur_active_width|, set |prev_r| and |prev_prev_r|, then |goto continue|
  17496. // \xref[inner loop]
  17497. if int32(*(*prg.mem[r1].hh()).b0()) == deltaNode {
  17498. prg.curActiveWidth[1-1] = prg.curActiveWidth[1-1] + *prg.mem[int32(r1)+1].int()
  17499. prg.curActiveWidth[2-1] = prg.curActiveWidth[2-1] + *prg.mem[int32(r1)+2].int()
  17500. prg.curActiveWidth[3-1] = prg.curActiveWidth[3-1] + *prg.mem[int32(r1)+3].int()
  17501. prg.curActiveWidth[4-1] = prg.curActiveWidth[4-1] + *prg.mem[int32(r1)+4].int()
  17502. prg.curActiveWidth[5-1] = prg.curActiveWidth[5-1] + *prg.mem[int32(r1)+5].int()
  17503. prg.curActiveWidth[6-1] = prg.curActiveWidth[6-1] + *prg.mem[int32(r1)+6].int()
  17504. prevPrevR = prevR
  17505. prevR = r1
  17506. goto continue1
  17507. }
  17508. // If a line number class has ended, create new active nodes for the best feasible breaks in that class; then |return| if |r=last_active|, otherwise compute the new |line_width|
  17509. {
  17510. l = *(*prg.mem[int32(r1)+1].hh()).lh()
  17511. if int32(l) > int32(oldL) {
  17512. if prg.minimumDemerits < 07777777777 && (int32(oldL) != int32(prg.easyLine) || int32(r1) == 30000-7) {
  17513. if noBreakYet {
  17514. noBreakYet = false
  17515. prg.breakWidth[1-1] = prg.background[1-1]
  17516. prg.breakWidth[2-1] = prg.background[2-1]
  17517. prg.breakWidth[3-1] = prg.background[3-1]
  17518. prg.breakWidth[4-1] = prg.background[4-1]
  17519. prg.breakWidth[5-1] = prg.background[5-1]
  17520. prg.breakWidth[6-1] = prg.background[6-1]
  17521. s = prg.curP
  17522. if int32(breakType) > unhyphenated {
  17523. if int32(prg.curP) != 0 {
  17524. t = int32(*(*prg.mem[prg.curP].hh()).b1())
  17525. v = prg.curP
  17526. s = *(*prg.mem[int32(prg.curP)+1].hh()).rh()
  17527. for t > 0 {
  17528. t = t - 1
  17529. v = *(*prg.mem[v].hh()).rh()
  17530. // Subtract the width of node |v| from |break_width|
  17531. if int32(v) >= int32(prg.hiMemMin) {
  17532. f = *(*prg.mem[v].hh()).b0()
  17533. prg.breakWidth[1-1] = prg.breakWidth[1-1] - *prg.fontInfo[prg.widthBase[f]+int32((*prg.fontInfo[prg.charBase[f]+int32(*(*prg.mem[v].hh()).b1())].qqqq()).b0)].int()
  17534. } else {
  17535. switch *(*prg.mem[v].hh()).b0() {
  17536. case ligatureNode:
  17537. f = *(*prg.mem[int32(v)+1].hh()).b0()
  17538. prg.breakWidth[1-1] = prg.breakWidth[1-1] - *prg.fontInfo[prg.widthBase[f]+int32((*prg.fontInfo[prg.charBase[f]+int32(*(*prg.mem[int32(v)+1].hh()).b1())].qqqq()).b0)].int()
  17539. case hlistNode, vlistNode, ruleNode, kernNode:
  17540. prg.breakWidth[1-1] = prg.breakWidth[1-1] - *prg.mem[int32(v)+widthOffset].int()
  17541. default:
  17542. prg.confusion(strNumber( /* "disc1" */ 923))
  17543. // \xref[this can't happen disc1][\quad disc1]
  17544. }
  17545. }
  17546. }
  17547. for int32(s) != 0 {
  17548. if int32(s) >= int32(prg.hiMemMin) {
  17549. f = *(*prg.mem[s].hh()).b0()
  17550. prg.breakWidth[1-1] = prg.breakWidth[1-1] + *prg.fontInfo[prg.widthBase[f]+int32((*prg.fontInfo[prg.charBase[f]+int32(*(*prg.mem[s].hh()).b1())].qqqq()).b0)].int()
  17551. } else {
  17552. switch *(*prg.mem[s].hh()).b0() {
  17553. case ligatureNode:
  17554. f = *(*prg.mem[int32(s)+1].hh()).b0()
  17555. prg.breakWidth[1-1] = prg.breakWidth[1-1] + *prg.fontInfo[prg.widthBase[f]+int32((*prg.fontInfo[prg.charBase[f]+int32(*(*prg.mem[int32(s)+1].hh()).b1())].qqqq()).b0)].int()
  17556. case hlistNode, vlistNode, ruleNode, kernNode:
  17557. prg.breakWidth[1-1] = prg.breakWidth[1-1] + *prg.mem[int32(s)+widthOffset].int()
  17558. default:
  17559. prg.confusion(strNumber( /* "disc2" */ 924))
  17560. // \xref[this can't happen disc2][\quad disc2]
  17561. }
  17562. }
  17563. s = *(*prg.mem[s].hh()).rh()
  17564. }
  17565. prg.breakWidth[1-1] = prg.breakWidth[1-1] + prg.discWidth
  17566. if int32(*(*prg.mem[int32(prg.curP)+1].hh()).rh()) == 0 {
  17567. s = *(*prg.mem[v].hh()).rh()
  17568. }
  17569. // nodes may be discardable after the break
  17570. }
  17571. }
  17572. for int32(s) != 0 {
  17573. if int32(s) >= int32(prg.hiMemMin) {
  17574. goto done
  17575. }
  17576. switch *(*prg.mem[s].hh()).b0() {
  17577. case glueNode:
  17578. // Subtract glue from |break_width|
  17579. v = *(*prg.mem[int32(s)+1].hh()).lh()
  17580. prg.breakWidth[1-1] = prg.breakWidth[1-1] - *prg.mem[int32(v)+widthOffset].int()
  17581. prg.breakWidth[2+int32(*(*prg.mem[v].hh()).b0())-1] = prg.breakWidth[2+int32(*(*prg.mem[v].hh()).b0())-1] - *prg.mem[int32(v)+2].int()
  17582. prg.breakWidth[6-1] = prg.breakWidth[6-1] - *prg.mem[int32(v)+3].int()
  17583. case penaltyNode:
  17584. case mathNode:
  17585. prg.breakWidth[1-1] = prg.breakWidth[1-1] - *prg.mem[int32(s)+widthOffset].int()
  17586. case kernNode:
  17587. if int32(*(*prg.mem[s].hh()).b1()) != explicit {
  17588. goto done
  17589. } else {
  17590. prg.breakWidth[1-1] = prg.breakWidth[1-1] - *prg.mem[int32(s)+widthOffset].int()
  17591. }
  17592. default:
  17593. goto done
  17594. }
  17595. s = *(*prg.mem[s].hh()).rh()
  17596. }
  17597. done:
  17598. }
  17599. // Insert a delta node to prepare for breaks at |cur_p|
  17600. if int32(*(*prg.mem[prevR].hh()).b0()) == deltaNode {
  17601. *prg.mem[int32(prevR)+1].int() = *prg.mem[int32(prevR)+1].int() - prg.curActiveWidth[1-1] + prg.breakWidth[1-1]
  17602. *prg.mem[int32(prevR)+2].int() = *prg.mem[int32(prevR)+2].int() - prg.curActiveWidth[2-1] + prg.breakWidth[2-1]
  17603. *prg.mem[int32(prevR)+3].int() = *prg.mem[int32(prevR)+3].int() - prg.curActiveWidth[3-1] + prg.breakWidth[3-1]
  17604. *prg.mem[int32(prevR)+4].int() = *prg.mem[int32(prevR)+4].int() - prg.curActiveWidth[4-1] + prg.breakWidth[4-1]
  17605. *prg.mem[int32(prevR)+5].int() = *prg.mem[int32(prevR)+5].int() - prg.curActiveWidth[5-1] + prg.breakWidth[5-1]
  17606. *prg.mem[int32(prevR)+6].int() = *prg.mem[int32(prevR)+6].int() - prg.curActiveWidth[6-1] + prg.breakWidth[6-1]
  17607. } else if int32(prevR) == 30000-7 {
  17608. prg.activeWidth[1-1] = prg.breakWidth[1-1]
  17609. prg.activeWidth[2-1] = prg.breakWidth[2-1]
  17610. prg.activeWidth[3-1] = prg.breakWidth[3-1]
  17611. prg.activeWidth[4-1] = prg.breakWidth[4-1]
  17612. prg.activeWidth[5-1] = prg.breakWidth[5-1]
  17613. prg.activeWidth[6-1] = prg.breakWidth[6-1]
  17614. } else {
  17615. q = prg.getNode(deltaNodeSize)
  17616. *(*prg.mem[q].hh()).rh() = r1
  17617. *(*prg.mem[q].hh()).b0() = byte(deltaNode)
  17618. *(*prg.mem[q].hh()).b1() = 0 // the |subtype| is not used
  17619. *prg.mem[int32(q)+1].int() = prg.breakWidth[1-1] - prg.curActiveWidth[1-1]
  17620. *prg.mem[int32(q)+2].int() = prg.breakWidth[2-1] - prg.curActiveWidth[2-1]
  17621. *prg.mem[int32(q)+3].int() = prg.breakWidth[3-1] - prg.curActiveWidth[3-1]
  17622. *prg.mem[int32(q)+4].int() = prg.breakWidth[4-1] - prg.curActiveWidth[4-1]
  17623. *prg.mem[int32(q)+5].int() = prg.breakWidth[5-1] - prg.curActiveWidth[5-1]
  17624. *prg.mem[int32(q)+6].int() = prg.breakWidth[6-1] - prg.curActiveWidth[6-1]
  17625. *(*prg.mem[prevR].hh()).rh() = q
  17626. prevPrevR = prevR
  17627. prevR = q
  17628. }
  17629. if abs(*prg.eqtb[intBase+adjDemeritsCode-1].int()) >= 07777777777-prg.minimumDemerits {
  17630. prg.minimumDemerits = 07777777777 - 1
  17631. } else {
  17632. prg.minimumDemerits = prg.minimumDemerits + abs(*prg.eqtb[intBase+adjDemeritsCode-1].int())
  17633. }
  17634. for ii := int32(veryLooseFit); ii <= tightFit; ii++ {
  17635. fitClass = byte(ii)
  17636. _ = fitClass
  17637. if prg.minimalDemerits[fitClass] <= prg.minimumDemerits {
  17638. q = prg.getNode(passiveNodeSize)
  17639. *(*prg.mem[q].hh()).rh() = prg.passive
  17640. prg.passive = q
  17641. *(*prg.mem[int32(q)+1].hh()).rh() = prg.curP
  17642. // pass_number:= pass_number+1 ; mem[ q].hh.lh :=pass_number; [ ]
  17643. *(*prg.mem[int32(q)+1].hh()).lh() = prg.bestPlace[fitClass]
  17644. q = prg.getNode(activeNodeSize)
  17645. *(*prg.mem[int32(q)+1].hh()).rh() = prg.passive
  17646. *(*prg.mem[int32(q)+1].hh()).lh() = uint16(int32(prg.bestPlLine[fitClass]) + 1)
  17647. *(*prg.mem[q].hh()).b1() = fitClass
  17648. *(*prg.mem[q].hh()).b0() = breakType
  17649. *prg.mem[int32(q)+2].int() = prg.minimalDemerits[fitClass]
  17650. *(*prg.mem[q].hh()).rh() = r1
  17651. *(*prg.mem[prevR].hh()).rh() = q
  17652. prevR = q
  17653. // if eqtb[int_base+ tracing_paragraphs_code].int >0 then
  17654. //
  17655. // [ Print a symbolic description of the new break node ]
  17656. // begin print_nl(["@@"=]925); print_int( mem[ passive].hh.lh );
  17657. // [ \xref[\AT!\AT!] ]
  17658. // print([": line "=]926); print_int( mem[ q+ 1].hh.lh -1);
  17659. // print_char(["."=]46); print_int(fit_class);
  17660. // if break_type=hyphenated then print_char(["-"=]45);
  17661. // print([" t="=]927); print_int(mem[ q+2].int );
  17662. // print([" -> @@"=]928);
  17663. // if mem[ passive+ 1].hh.lh =0 then print_char(["0"=]48)
  17664. // else print_int( mem[ mem[ passive+ 1].hh.lh ].hh.lh );
  17665. // end
  17666. //
  17667. // ;
  17668. // [ ]
  17669. }
  17670. prg.minimalDemerits[fitClass] = 07777777777
  17671. }
  17672. prg.minimumDemerits = 07777777777
  17673. // Insert a delta node to prepare for the next active node
  17674. if int32(r1) != 30000-7 {
  17675. q = prg.getNode(deltaNodeSize)
  17676. *(*prg.mem[q].hh()).rh() = r1
  17677. *(*prg.mem[q].hh()).b0() = byte(deltaNode)
  17678. *(*prg.mem[q].hh()).b1() = 0 // the |subtype| is not used
  17679. *prg.mem[int32(q)+1].int() = prg.curActiveWidth[1-1] - prg.breakWidth[1-1]
  17680. *prg.mem[int32(q)+2].int() = prg.curActiveWidth[2-1] - prg.breakWidth[2-1]
  17681. *prg.mem[int32(q)+3].int() = prg.curActiveWidth[3-1] - prg.breakWidth[3-1]
  17682. *prg.mem[int32(q)+4].int() = prg.curActiveWidth[4-1] - prg.breakWidth[4-1]
  17683. *prg.mem[int32(q)+5].int() = prg.curActiveWidth[5-1] - prg.breakWidth[5-1]
  17684. *prg.mem[int32(q)+6].int() = prg.curActiveWidth[6-1] - prg.breakWidth[6-1]
  17685. *(*prg.mem[prevR].hh()).rh() = q
  17686. prevPrevR = prevR
  17687. prevR = q
  17688. }
  17689. }
  17690. if int32(r1) == 30000-7 {
  17691. goto exit
  17692. }
  17693. // Compute the new line width
  17694. if int32(l) > int32(prg.easyLine) {
  17695. lineWidth = prg.secondWidth
  17696. oldL = uint16(65535 - 1)
  17697. } else {
  17698. oldL = l
  17699. if int32(l) > int32(prg.lastSpecialLine) {
  17700. lineWidth = prg.secondWidth
  17701. } else if int32(*(*prg.eqtb[parShapeLoc-1].hh()).rh()) == 0 {
  17702. lineWidth = prg.firstWidth
  17703. } else {
  17704. lineWidth = *prg.mem[int32(*(*prg.eqtb[parShapeLoc-1].hh()).rh())+2*int32(l)].int()
  17705. }
  17706. }
  17707. }
  17708. }
  17709. // Consider the demerits for a line from |r| to |cur_p|; deactivate node |r| if it should no longer be active; then |goto continue| if a line from |r| to |cur_p| is infeasible, otherwise record a new feasible break
  17710. {
  17711. artificialDemerits = false
  17712. // \xref[inner loop]
  17713. shortfall = lineWidth - prg.curActiveWidth[1-1] // we're this much too short
  17714. if shortfall > 0 {
  17715. if prg.curActiveWidth[3-1] != 0 || prg.curActiveWidth[4-1] != 0 || prg.curActiveWidth[5-1] != 0 {
  17716. b = 0
  17717. fitClass = byte(decentFit) // infinite stretch
  17718. } else {
  17719. if shortfall > 7230584 {
  17720. if prg.curActiveWidth[2-1] < 1663497 {
  17721. b = uint16(infBad)
  17722. fitClass = byte(veryLooseFit)
  17723. goto done1
  17724. }
  17725. }
  17726. b = prg.badness(shortfall, prg.curActiveWidth[2-1])
  17727. if int32(b) > 12 {
  17728. if int32(b) > 99 {
  17729. fitClass = byte(veryLooseFit)
  17730. } else {
  17731. fitClass = byte(looseFit)
  17732. }
  17733. } else {
  17734. fitClass = byte(decentFit)
  17735. }
  17736. done1:
  17737. }
  17738. } else {
  17739. // Set the value of |b| to the badness for shrinking the line, and compute the corresponding |fit_class|
  17740. if -shortfall > prg.curActiveWidth[6-1] {
  17741. b = uint16(infBad + 1)
  17742. } else {
  17743. b = prg.badness(-shortfall, prg.curActiveWidth[6-1])
  17744. }
  17745. if int32(b) > 12 {
  17746. fitClass = byte(tightFit)
  17747. } else {
  17748. fitClass = byte(decentFit)
  17749. }
  17750. }
  17751. if int32(b) > infBad || pi == ejectPenalty {
  17752. if prg.finalPass && prg.minimumDemerits == 07777777777 && int32(*(*prg.mem[r1].hh()).rh()) == 30000-7 && int32(prevR) == 30000-7 {
  17753. artificialDemerits = true
  17754. } else if int32(b) > prg.threshold {
  17755. goto deactivate
  17756. }
  17757. nodeRStaysActive = false
  17758. } else {
  17759. prevR = r1
  17760. if int32(b) > prg.threshold {
  17761. goto continue1
  17762. }
  17763. nodeRStaysActive = true
  17764. }
  17765. // Record a new feasible break
  17766. if artificialDemerits {
  17767. d = 0
  17768. } else {
  17769. // Compute the demerits, |d|, from |r| to |cur_p|
  17770. d = *prg.eqtb[intBase+linePenaltyCode-1].int() + int32(b)
  17771. if abs(d) >= 10000 {
  17772. d = 100000000
  17773. } else {
  17774. d = d * d
  17775. }
  17776. if pi != 0 {
  17777. if pi > 0 {
  17778. d = d + pi*pi
  17779. } else if pi > ejectPenalty {
  17780. d = d - pi*pi
  17781. }
  17782. }
  17783. if int32(breakType) == hyphenated && int32(*(*prg.mem[r1].hh()).b0()) == hyphenated {
  17784. if int32(prg.curP) != 0 {
  17785. d = d + *prg.eqtb[intBase+doubleHyphenDemeritsCode-1].int()
  17786. } else {
  17787. d = d + *prg.eqtb[intBase+finalHyphenDemeritsCode-1].int()
  17788. }
  17789. }
  17790. if abs(int32(fitClass)-int32(*(*prg.mem[r1].hh()).b1())) > 1 {
  17791. d = d + *prg.eqtb[intBase+adjDemeritsCode-1].int()
  17792. }
  17793. }
  17794. // if eqtb[int_base+ tracing_paragraphs_code].int >0 then
  17795. //
  17796. // [ Print a symbolic description of this feasible break ]
  17797. // begin if printed_node<>cur_p then
  17798. //
  17799. // [ Print the list between |printed_node| and |cur_p|, then set |printed_node:=cur_p| ]
  17800. // begin print_nl([""=]338);
  17801. // if cur_p=0 then short_display( mem[ printed_node].hh.rh )
  17802. // else begin save_link:= mem[ cur_p].hh.rh ;
  17803. // mem[ cur_p].hh.rh :=0 ; print_nl([""=]338); short_display( mem[ printed_node].hh.rh );
  17804. // mem[ cur_p].hh.rh :=save_link;
  17805. // end;
  17806. // printed_node:=cur_p;
  17807. // end
  17808. //
  17809. // ;
  17810. // print_nl(["@"=]64);
  17811. // [ \xref[\AT!] ]
  17812. // if cur_p=0 then print_esc(["par"=]597)
  17813. // else if mem[ cur_p].hh.b0 <>glue_node then
  17814. // begin if mem[ cur_p].hh.b0 =penalty_node then print_esc(["penalty"=]531)
  17815. // else if mem[ cur_p].hh.b0 =disc_node then print_esc(["discretionary"=]349)
  17816. // else if mem[ cur_p].hh.b0 =kern_node then print_esc(["kern"=]340)
  17817. // else print_esc(["math"=]343);
  17818. // end;
  17819. // print([" via @@"=]929);
  17820. // if mem[ r+ 1].hh.rh =0 then print_char(["0"=]48)
  17821. // else print_int( mem[ mem[ r+ 1].hh.rh ].hh.lh );
  17822. // print([" b="=]930);
  17823. // if b>inf_bad then print_char(["*"=]42) else print_int(b);
  17824. // [ \xref[*\relax] ]
  17825. // print([" p="=]931); print_int(pi); print([" d="=]932);
  17826. // if artificial_demerits then print_char(["*"=]42) else print_int(d);
  17827. // end
  17828. //
  17829. // ;
  17830. // [ ]
  17831. d = d + *prg.mem[int32(r1)+2].int() // this is the minimum total demerits
  17832. // from the beginning to |cur_p| via |r|
  17833. if d <= prg.minimalDemerits[fitClass] {
  17834. prg.minimalDemerits[fitClass] = d
  17835. prg.bestPlace[fitClass] = *(*prg.mem[int32(r1)+1].hh()).rh()
  17836. prg.bestPlLine[fitClass] = l
  17837. if d < prg.minimumDemerits {
  17838. prg.minimumDemerits = d
  17839. }
  17840. }
  17841. if nodeRStaysActive {
  17842. goto continue1
  17843. } // |prev_r| has been set to |r|
  17844. // |prev_r| has been set to |r|
  17845. deactivate:
  17846. *(*prg.mem[prevR].hh()).rh() = *(*prg.mem[r1].hh()).rh()
  17847. prg.freeNode(r1, halfword(activeNodeSize))
  17848. if int32(prevR) == 30000-7 {
  17849. r1 = *(*prg.mem[30000-7].hh()).rh()
  17850. if int32(*(*prg.mem[r1].hh()).b0()) == deltaNode {
  17851. prg.activeWidth[1-1] = prg.activeWidth[1-1] + *prg.mem[int32(r1)+1].int()
  17852. prg.activeWidth[2-1] = prg.activeWidth[2-1] + *prg.mem[int32(r1)+2].int()
  17853. prg.activeWidth[3-1] = prg.activeWidth[3-1] + *prg.mem[int32(r1)+3].int()
  17854. prg.activeWidth[4-1] = prg.activeWidth[4-1] + *prg.mem[int32(r1)+4].int()
  17855. prg.activeWidth[5-1] = prg.activeWidth[5-1] + *prg.mem[int32(r1)+5].int()
  17856. prg.activeWidth[6-1] = prg.activeWidth[6-1] + *prg.mem[int32(r1)+6].int()
  17857. prg.curActiveWidth[1-1] = prg.activeWidth[1-1]
  17858. prg.curActiveWidth[2-1] = prg.activeWidth[2-1]
  17859. prg.curActiveWidth[3-1] = prg.activeWidth[3-1]
  17860. prg.curActiveWidth[4-1] = prg.activeWidth[4-1]
  17861. prg.curActiveWidth[5-1] = prg.activeWidth[5-1]
  17862. prg.curActiveWidth[6-1] = prg.activeWidth[6-1]
  17863. *(*prg.mem[30000-7].hh()).rh() = *(*prg.mem[r1].hh()).rh()
  17864. prg.freeNode(r1, halfword(deltaNodeSize))
  17865. }
  17866. } else if int32(*(*prg.mem[prevR].hh()).b0()) == deltaNode {
  17867. r1 = *(*prg.mem[prevR].hh()).rh()
  17868. if int32(r1) == 30000-7 {
  17869. prg.curActiveWidth[1-1] = prg.curActiveWidth[1-1] - *prg.mem[int32(prevR)+1].int()
  17870. prg.curActiveWidth[2-1] = prg.curActiveWidth[2-1] - *prg.mem[int32(prevR)+2].int()
  17871. prg.curActiveWidth[3-1] = prg.curActiveWidth[3-1] - *prg.mem[int32(prevR)+3].int()
  17872. prg.curActiveWidth[4-1] = prg.curActiveWidth[4-1] - *prg.mem[int32(prevR)+4].int()
  17873. prg.curActiveWidth[5-1] = prg.curActiveWidth[5-1] - *prg.mem[int32(prevR)+5].int()
  17874. prg.curActiveWidth[6-1] = prg.curActiveWidth[6-1] - *prg.mem[int32(prevR)+6].int()
  17875. *(*prg.mem[prevPrevR].hh()).rh() = uint16(30000 - 7)
  17876. prg.freeNode(prevR, halfword(deltaNodeSize))
  17877. prevR = prevPrevR
  17878. } else if int32(*(*prg.mem[r1].hh()).b0()) == deltaNode {
  17879. prg.curActiveWidth[1-1] = prg.curActiveWidth[1-1] + *prg.mem[int32(r1)+1].int()
  17880. prg.curActiveWidth[2-1] = prg.curActiveWidth[2-1] + *prg.mem[int32(r1)+2].int()
  17881. prg.curActiveWidth[3-1] = prg.curActiveWidth[3-1] + *prg.mem[int32(r1)+3].int()
  17882. prg.curActiveWidth[4-1] = prg.curActiveWidth[4-1] + *prg.mem[int32(r1)+4].int()
  17883. prg.curActiveWidth[5-1] = prg.curActiveWidth[5-1] + *prg.mem[int32(r1)+5].int()
  17884. prg.curActiveWidth[6-1] = prg.curActiveWidth[6-1] + *prg.mem[int32(r1)+6].int()
  17885. *prg.mem[int32(prevR)+1].int() = *prg.mem[int32(prevR)+1].int() + *prg.mem[int32(r1)+1].int()
  17886. *prg.mem[int32(prevR)+2].int() = *prg.mem[int32(prevR)+2].int() + *prg.mem[int32(r1)+2].int()
  17887. *prg.mem[int32(prevR)+3].int() = *prg.mem[int32(prevR)+3].int() + *prg.mem[int32(r1)+3].int()
  17888. *prg.mem[int32(prevR)+4].int() = *prg.mem[int32(prevR)+4].int() + *prg.mem[int32(r1)+4].int()
  17889. *prg.mem[int32(prevR)+5].int() = *prg.mem[int32(prevR)+5].int() + *prg.mem[int32(r1)+5].int()
  17890. *prg.mem[int32(prevR)+6].int() = *prg.mem[int32(prevR)+6].int() + *prg.mem[int32(r1)+6].int()
  17891. *(*prg.mem[prevR].hh()).rh() = *(*prg.mem[r1].hh()).rh()
  17892. prg.freeNode(r1, halfword(deltaNodeSize))
  17893. }
  17894. }
  17895. }
  17896. }
  17897. exit:
  17898. }
  17899. func (prg *prg) postLineBreak(finalWidowPenalty int32) {
  17900. var (
  17901. q, r1, s halfword // temporary registers for list manipulation
  17902. discBreak bool // was the current break at a discretionary node?
  17903. postDiscBreak bool // and did it have a nonempty post-break part?
  17904. curWidth scaled // width of line number |cur_line|
  17905. curIndent scaled // left margin of line number |cur_line|
  17906. t quarterword // used for replacement counts in discretionary nodes
  17907. pen int32 // use when calculating penalties between lines
  17908. curLine halfword // the current line number being justified
  17909. )
  17910. q = *(*prg.mem[int32(prg.bestBet)+1].hh()).rh()
  17911. prg.curP = 0
  17912. for {
  17913. r1 = q
  17914. q = *(*prg.mem[int32(q)+1].hh()).lh()
  17915. *(*prg.mem[int32(r1)+1].hh()).lh() = prg.curP
  17916. prg.curP = r1
  17917. if int32(q) == 0 {
  17918. break
  17919. }
  17920. }
  17921. curLine = uint16(prg.curList.pgField + 1)
  17922. for {
  17923. // Justify the line ending at breakpoint |cur_p|, and append it to the current vertical list, together with associated penalties and other insertions
  17924. // Modify the end of the line to reflect the nature of the break and to include \.[\\rightskip]; also set the proper value of |disc_break|
  17925. q = *(*prg.mem[int32(prg.curP)+1].hh()).rh()
  17926. discBreak = false
  17927. postDiscBreak = false
  17928. if int32(q) != 0 {
  17929. if int32(*(*prg.mem[q].hh()).b0()) == glueNode {
  17930. prg.deleteGlueRef(*(*prg.mem[int32(q)+1].hh()).lh())
  17931. *(*prg.mem[int32(q)+1].hh()).lh() = *(*prg.eqtb[glueBase+rightSkipCode-1].hh()).rh()
  17932. *(*prg.mem[q].hh()).b1() = byte(rightSkipCode + 1)
  17933. *(*prg.mem[*(*prg.eqtb[glueBase+rightSkipCode-1].hh()).rh()].hh()).rh() = uint16(int32(*(*prg.mem[*(*prg.eqtb[glueBase+rightSkipCode-1].hh()).rh()].hh()).rh()) + 1)
  17934. goto done
  17935. } else {
  17936. if int32(*(*prg.mem[q].hh()).b0()) == discNode {
  17937. t = *(*prg.mem[q].hh()).b1()
  17938. // Destroy the |t| nodes following |q|, and make |r| point to the following node
  17939. if int32(t) == 0 {
  17940. r1 = *(*prg.mem[q].hh()).rh()
  17941. } else {
  17942. r1 = q
  17943. for int32(t) > 1 {
  17944. r1 = *(*prg.mem[r1].hh()).rh()
  17945. t = byte(int32(t) - 1)
  17946. }
  17947. s = *(*prg.mem[r1].hh()).rh()
  17948. r1 = *(*prg.mem[s].hh()).rh()
  17949. *(*prg.mem[s].hh()).rh() = 0
  17950. prg.flushNodeList(*(*prg.mem[q].hh()).rh())
  17951. *(*prg.mem[q].hh()).b1() = 0
  17952. }
  17953. if int32(*(*prg.mem[int32(q)+1].hh()).rh()) != 0 {
  17954. s = *(*prg.mem[int32(q)+1].hh()).rh()
  17955. for int32(*(*prg.mem[s].hh()).rh()) != 0 {
  17956. s = *(*prg.mem[s].hh()).rh()
  17957. }
  17958. *(*prg.mem[s].hh()).rh() = r1
  17959. r1 = *(*prg.mem[int32(q)+1].hh()).rh()
  17960. *(*prg.mem[int32(q)+1].hh()).rh() = 0
  17961. postDiscBreak = true
  17962. }
  17963. if int32(*(*prg.mem[int32(q)+1].hh()).lh()) != 0 {
  17964. s = *(*prg.mem[int32(q)+1].hh()).lh()
  17965. *(*prg.mem[q].hh()).rh() = s
  17966. for int32(*(*prg.mem[s].hh()).rh()) != 0 {
  17967. s = *(*prg.mem[s].hh()).rh()
  17968. }
  17969. *(*prg.mem[int32(q)+1].hh()).lh() = 0
  17970. q = s
  17971. }
  17972. *(*prg.mem[q].hh()).rh() = r1
  17973. discBreak = true
  17974. } else if int32(*(*prg.mem[q].hh()).b0()) == mathNode || int32(*(*prg.mem[q].hh()).b0()) == kernNode {
  17975. *prg.mem[int32(q)+widthOffset].int() = 0
  17976. }
  17977. }
  17978. } else {
  17979. q = uint16(30000 - 3)
  17980. for int32(*(*prg.mem[q].hh()).rh()) != 0 {
  17981. q = *(*prg.mem[q].hh()).rh()
  17982. }
  17983. }
  17984. // Put the \(r)\.[\\rightskip] glue after node |q|
  17985. r1 = prg.newParamGlue(smallNumber(rightSkipCode))
  17986. *(*prg.mem[r1].hh()).rh() = *(*prg.mem[q].hh()).rh()
  17987. *(*prg.mem[q].hh()).rh() = r1
  17988. q = r1
  17989. done:
  17990. ;
  17991. // Put the \(l)\.[\\leftskip] glue at the left and detach this line
  17992. r1 = *(*prg.mem[q].hh()).rh()
  17993. *(*prg.mem[q].hh()).rh() = 0
  17994. q = *(*prg.mem[30000-3].hh()).rh()
  17995. *(*prg.mem[30000-3].hh()).rh() = r1
  17996. if int32(*(*prg.eqtb[glueBase+leftSkipCode-1].hh()).rh()) != memBot {
  17997. r1 = prg.newParamGlue(smallNumber(leftSkipCode))
  17998. *(*prg.mem[r1].hh()).rh() = q
  17999. q = r1
  18000. }
  18001. // Call the packaging subroutine, setting |just_box| to the justified box
  18002. if int32(curLine) > int32(prg.lastSpecialLine) {
  18003. curWidth = prg.secondWidth
  18004. curIndent = prg.secondIndent
  18005. } else if int32(*(*prg.eqtb[parShapeLoc-1].hh()).rh()) == 0 {
  18006. curWidth = prg.firstWidth
  18007. curIndent = prg.firstIndent
  18008. } else {
  18009. curWidth = *prg.mem[int32(*(*prg.eqtb[parShapeLoc-1].hh()).rh())+2*int32(curLine)].int()
  18010. curIndent = *prg.mem[int32(*(*prg.eqtb[parShapeLoc-1].hh()).rh())+2*int32(curLine)-1].int()
  18011. }
  18012. prg.adjustTail = uint16(30000 - 5)
  18013. prg.justBox = prg.hpack(q, curWidth, smallNumber(exactly))
  18014. *prg.mem[int32(prg.justBox)+4].int() = curIndent
  18015. // Append the new box to the current vertical list, followed by the list of special nodes taken out of the box by the packager
  18016. prg.appendToVlist(prg.justBox)
  18017. if 30000-5 != int32(prg.adjustTail) {
  18018. *(*prg.mem[prg.curList.tailField].hh()).rh() = *(*prg.mem[30000-5].hh()).rh()
  18019. prg.curList.tailField = prg.adjustTail
  18020. }
  18021. prg.adjustTail = 0
  18022. // Append a penalty node, if a nonzero penalty is appropriate
  18023. if int32(curLine)+1 != int32(prg.bestLine) {
  18024. pen = *prg.eqtb[intBase+interLinePenaltyCode-1].int()
  18025. if int32(curLine) == prg.curList.pgField+1 {
  18026. pen = pen + *prg.eqtb[intBase+clubPenaltyCode-1].int()
  18027. }
  18028. if int32(curLine)+2 == int32(prg.bestLine) {
  18029. pen = pen + finalWidowPenalty
  18030. }
  18031. if discBreak {
  18032. pen = pen + *prg.eqtb[intBase+brokenPenaltyCode-1].int()
  18033. }
  18034. if pen != 0 {
  18035. r1 = prg.newPenalty(pen)
  18036. *(*prg.mem[prg.curList.tailField].hh()).rh() = r1
  18037. prg.curList.tailField = r1
  18038. }
  18039. }
  18040. curLine = uint16(int32(curLine) + 1)
  18041. prg.curP = *(*prg.mem[int32(prg.curP)+1].hh()).lh()
  18042. if int32(prg.curP) != 0 {
  18043. if !postDiscBreak {
  18044. r1 = uint16(30000 - 3)
  18045. for true {
  18046. q = *(*prg.mem[r1].hh()).rh()
  18047. if int32(q) == int32(*(*prg.mem[int32(prg.curP)+1].hh()).rh()) {
  18048. goto done1
  18049. }
  18050. // |cur_break(cur_p)| is the next breakpoint
  18051. // now |q| cannot be |null|
  18052. if int32(q) >= int32(prg.hiMemMin) {
  18053. goto done1
  18054. }
  18055. if int32(*(*prg.mem[q].hh()).b0()) < mathNode {
  18056. goto done1
  18057. }
  18058. if int32(*(*prg.mem[q].hh()).b0()) == kernNode {
  18059. if int32(*(*prg.mem[q].hh()).b1()) != explicit {
  18060. goto done1
  18061. }
  18062. }
  18063. r1 = q // now |type(q)=glue_node|, |kern_node|, |math_node|, or |penalty_node|
  18064. }
  18065. done1:
  18066. if int32(r1) != 30000-3 {
  18067. *(*prg.mem[r1].hh()).rh() = 0
  18068. prg.flushNodeList(*(*prg.mem[30000-3].hh()).rh())
  18069. *(*prg.mem[30000-3].hh()).rh() = q
  18070. }
  18071. }
  18072. }
  18073. if int32(prg.curP) == 0 {
  18074. break
  18075. }
  18076. }
  18077. if int32(curLine) != int32(prg.bestLine) || int32(*(*prg.mem[30000-3].hh()).rh()) != 0 {
  18078. prg.confusion(strNumber( /* "line breaking" */ 939))
  18079. }
  18080. // \xref[this can't happen line breaking][\quad line breaking]
  18081. prg.curList.pgField = int32(prg.bestLine) - 1
  18082. }
  18083. // \4
  18084. // Declare the function called |reconstitute|
  18085. func (prg *prg) reconstitute(j, n smallNumber, bchar, hchar halfword) (r smallNumber) {
  18086. var (
  18087. p halfword // temporary register for list manipulation
  18088. t halfword // a node being appended to
  18089. q fourQuarters // character information or a lig/kern instruction
  18090. curRh halfword // hyphen character for ligature testing
  18091. testChar halfword // hyphen or other character for ligature testing
  18092. w scaled // amount of kerning
  18093. k fontIndex // position of current lig/kern instruction
  18094. )
  18095. prg.hyphenPassed = 0
  18096. t = uint16(30000 - 4)
  18097. w = 0
  18098. *(*prg.mem[30000-4].hh()).rh() = 0
  18099. // at this point |ligature_present=lft_hit=rt_hit=false|
  18100. // Set up data structures with the cursor following position |j|
  18101. prg.curL = uint16(int32(prg.hu[j]) + minQuarterword)
  18102. prg.curQ = t
  18103. if int32(j) == 0 {
  18104. prg.ligaturePresent = prg.initLig
  18105. p = prg.initList
  18106. if prg.ligaturePresent {
  18107. prg.lftHit = prg.initLft
  18108. }
  18109. for int32(p) > 0 {
  18110. {
  18111. *(*prg.mem[t].hh()).rh() = prg.getAvail()
  18112. t = *(*prg.mem[t].hh()).rh()
  18113. *(*prg.mem[t].hh()).b0() = prg.hf
  18114. *(*prg.mem[t].hh()).b1() = *(*prg.mem[p].hh()).b1()
  18115. }
  18116. p = *(*prg.mem[p].hh()).rh()
  18117. }
  18118. } else if int32(prg.curL) < 256+minQuarterword {
  18119. *(*prg.mem[t].hh()).rh() = prg.getAvail()
  18120. t = *(*prg.mem[t].hh()).rh()
  18121. *(*prg.mem[t].hh()).b0() = prg.hf
  18122. *(*prg.mem[t].hh()).b1() = byte(prg.curL)
  18123. }
  18124. prg.ligStack = 0
  18125. {
  18126. if int32(j) < int32(n) {
  18127. prg.curR = uint16(int32(prg.hu[int32(j)+1]) + minQuarterword)
  18128. } else {
  18129. prg.curR = bchar
  18130. }
  18131. if prg.hyf[j]&1 != 0 {
  18132. curRh = hchar
  18133. } else {
  18134. curRh = uint16(256 + minQuarterword)
  18135. }
  18136. }
  18137. continue1:
  18138. if int32(prg.curL) == 256+minQuarterword {
  18139. k = prg.bcharLabel[prg.hf]
  18140. if int32(k) == nonAddress {
  18141. goto done
  18142. } else {
  18143. q = *prg.fontInfo[k].qqqq()
  18144. }
  18145. } else {
  18146. q = *prg.fontInfo[prg.charBase[prg.hf]+int32(prg.curL)].qqqq()
  18147. if (int32(q.b2)-minQuarterword)%4 != ligTag {
  18148. goto done
  18149. }
  18150. k = uint16(prg.ligKernBase[prg.hf] + int32(q.b3))
  18151. q = *prg.fontInfo[k].qqqq()
  18152. if int32(q.b0) > 128+minQuarterword {
  18153. k = uint16(prg.ligKernBase[prg.hf] + 256*int32(q.b2) + int32(q.b3) + 32768 - 256*(128+minQuarterword))
  18154. q = *prg.fontInfo[k].qqqq()
  18155. }
  18156. } // now |k| is the starting address of the lig/kern program
  18157. if int32(curRh) < 256+minQuarterword {
  18158. testChar = curRh
  18159. } else {
  18160. testChar = prg.curR
  18161. }
  18162. for true {
  18163. if int32(q.b1) == int32(testChar) {
  18164. if int32(q.b0) <= 128+minQuarterword {
  18165. if int32(curRh) < 256+minQuarterword {
  18166. prg.hyphenPassed = j
  18167. hchar = uint16(256 + minQuarterword)
  18168. curRh = uint16(256 + minQuarterword)
  18169. goto continue1
  18170. } else {
  18171. if int32(hchar) < 256+minQuarterword {
  18172. if prg.hyf[j]&1 != 0 {
  18173. prg.hyphenPassed = j
  18174. hchar = uint16(256 + minQuarterword)
  18175. }
  18176. }
  18177. if int32(q.b2) < 128+minQuarterword {
  18178. if int32(prg.curL) == 256+minQuarterword {
  18179. prg.lftHit = true
  18180. }
  18181. if int32(j) == int32(n) {
  18182. if int32(prg.ligStack) == 0 {
  18183. prg.rtHit = true
  18184. }
  18185. }
  18186. {
  18187. if prg.interrupt != 0 {
  18188. prg.pauseForInstructions()
  18189. }
  18190. } // allow a way out in case there's an infinite ligature loop
  18191. switch q.b2 {
  18192. case 1 + minQuarterword, 5 + minQuarterword:
  18193. prg.curL = uint16(q.b3) // \.[=:\?], \.[=:\?>]
  18194. prg.ligaturePresent = true
  18195. case 2 + minQuarterword, 6 + minQuarterword:
  18196. prg.curR = uint16(q.b3) // \.[\?=:], \.[\?=:>]
  18197. if int32(prg.ligStack) > 0 {
  18198. *(*prg.mem[prg.ligStack].hh()).b1() = byte(prg.curR)
  18199. } else {
  18200. prg.ligStack = prg.newLigItem(quarterword(prg.curR))
  18201. if int32(j) == int32(n) {
  18202. bchar = uint16(256 + minQuarterword)
  18203. } else {
  18204. p = prg.getAvail()
  18205. *(*prg.mem[int32(prg.ligStack)+1].hh()).rh() = p
  18206. *(*prg.mem[p].hh()).b1() = byte(int32(prg.hu[int32(j)+1]) + minQuarterword)
  18207. *(*prg.mem[p].hh()).b0() = prg.hf
  18208. }
  18209. }
  18210. case 3 + minQuarterword:
  18211. prg.curR = uint16(q.b3) // \.[\?=:\?]
  18212. p = prg.ligStack
  18213. prg.ligStack = prg.newLigItem(quarterword(prg.curR))
  18214. *(*prg.mem[prg.ligStack].hh()).rh() = p
  18215. case 7 + minQuarterword, 11 + minQuarterword:
  18216. if prg.ligaturePresent {
  18217. p = prg.newLigature(prg.hf, quarterword(prg.curL), *(*prg.mem[prg.curQ].hh()).rh())
  18218. if prg.lftHit {
  18219. *(*prg.mem[p].hh()).b1() = 2
  18220. prg.lftHit = false
  18221. }
  18222. if false {
  18223. if int32(prg.ligStack) == 0 {
  18224. *(*prg.mem[p].hh()).b1() = byte(int32(*(*prg.mem[p].hh()).b1()) + 1)
  18225. prg.rtHit = false
  18226. }
  18227. }
  18228. *(*prg.mem[prg.curQ].hh()).rh() = p
  18229. t = p
  18230. prg.ligaturePresent = false
  18231. } // \.[\?=:\?>], \.[\?=:\?>>]
  18232. prg.curQ = t
  18233. prg.curL = uint16(q.b3)
  18234. prg.ligaturePresent = true
  18235. default:
  18236. prg.curL = uint16(q.b3)
  18237. prg.ligaturePresent = true // \.[=:]
  18238. if int32(prg.ligStack) > 0 {
  18239. if int32(*(*prg.mem[int32(prg.ligStack)+1].hh()).rh()) > 0 {
  18240. *(*prg.mem[t].hh()).rh() = *(*prg.mem[int32(prg.ligStack)+1].hh()).rh()
  18241. t = *(*prg.mem[t].hh()).rh()
  18242. j = byte(int32(j) + 1)
  18243. }
  18244. p = prg.ligStack
  18245. prg.ligStack = *(*prg.mem[p].hh()).rh()
  18246. prg.freeNode(p, halfword(smallNodeSize))
  18247. if int32(prg.ligStack) == 0 {
  18248. if int32(j) < int32(n) {
  18249. prg.curR = uint16(int32(prg.hu[int32(j)+1]) + minQuarterword)
  18250. } else {
  18251. prg.curR = bchar
  18252. }
  18253. if prg.hyf[j]&1 != 0 {
  18254. curRh = hchar
  18255. } else {
  18256. curRh = uint16(256 + minQuarterword)
  18257. }
  18258. } else {
  18259. prg.curR = uint16(*(*prg.mem[prg.ligStack].hh()).b1())
  18260. }
  18261. } else if int32(j) == int32(n) {
  18262. goto done
  18263. } else {
  18264. {
  18265. *(*prg.mem[t].hh()).rh() = prg.getAvail()
  18266. t = *(*prg.mem[t].hh()).rh()
  18267. *(*prg.mem[t].hh()).b0() = prg.hf
  18268. *(*prg.mem[t].hh()).b1() = byte(prg.curR)
  18269. }
  18270. j = byte(int32(j) + 1)
  18271. {
  18272. if int32(j) < int32(n) {
  18273. prg.curR = uint16(int32(prg.hu[int32(j)+1]) + minQuarterword)
  18274. } else {
  18275. prg.curR = bchar
  18276. }
  18277. if prg.hyf[j]&1 != 0 {
  18278. curRh = hchar
  18279. } else {
  18280. curRh = uint16(256 + minQuarterword)
  18281. }
  18282. }
  18283. }
  18284. }
  18285. if int32(q.b2) > 4+minQuarterword {
  18286. if int32(q.b2) != 7+minQuarterword {
  18287. goto done
  18288. }
  18289. }
  18290. goto continue1
  18291. }
  18292. w = *prg.fontInfo[prg.kernBase[prg.hf]+256*int32(q.b2)+int32(q.b3)].int()
  18293. goto done // this kern will be inserted below
  18294. }
  18295. }
  18296. }
  18297. if int32(q.b0) >= 128+minQuarterword {
  18298. if int32(curRh) == 256+minQuarterword {
  18299. goto done
  18300. } else {
  18301. curRh = uint16(256 + minQuarterword)
  18302. goto continue1
  18303. }
  18304. }
  18305. k = uint16(int32(k) + int32(q.b0) - minQuarterword + 1)
  18306. q = *prg.fontInfo[k].qqqq()
  18307. }
  18308. done:
  18309. ;
  18310. // Append a ligature and/or kern to the translation; |goto continue| if the stack of inserted ligatures is nonempty
  18311. if prg.ligaturePresent {
  18312. p = prg.newLigature(prg.hf, quarterword(prg.curL), *(*prg.mem[prg.curQ].hh()).rh())
  18313. if prg.lftHit {
  18314. *(*prg.mem[p].hh()).b1() = 2
  18315. prg.lftHit = false
  18316. }
  18317. if prg.rtHit {
  18318. if int32(prg.ligStack) == 0 {
  18319. *(*prg.mem[p].hh()).b1() = byte(int32(*(*prg.mem[p].hh()).b1()) + 1)
  18320. prg.rtHit = false
  18321. }
  18322. }
  18323. *(*prg.mem[prg.curQ].hh()).rh() = p
  18324. t = p
  18325. prg.ligaturePresent = false
  18326. }
  18327. if w != 0 {
  18328. *(*prg.mem[t].hh()).rh() = prg.newKern(w)
  18329. t = *(*prg.mem[t].hh()).rh()
  18330. w = 0
  18331. }
  18332. if int32(prg.ligStack) > 0 {
  18333. prg.curQ = t
  18334. prg.curL = uint16(*(*prg.mem[prg.ligStack].hh()).b1())
  18335. prg.ligaturePresent = true
  18336. {
  18337. if int32(*(*prg.mem[int32(prg.ligStack)+1].hh()).rh()) > 0 {
  18338. *(*prg.mem[t].hh()).rh() = *(*prg.mem[int32(prg.ligStack)+1].hh()).rh()
  18339. t = *(*prg.mem[t].hh()).rh()
  18340. j = byte(int32(j) + 1)
  18341. }
  18342. p = prg.ligStack
  18343. prg.ligStack = *(*prg.mem[p].hh()).rh()
  18344. prg.freeNode(p, halfword(smallNodeSize))
  18345. if int32(prg.ligStack) == 0 {
  18346. if int32(j) < int32(n) {
  18347. prg.curR = uint16(int32(prg.hu[int32(j)+1]) + minQuarterword)
  18348. } else {
  18349. prg.curR = bchar
  18350. }
  18351. if prg.hyf[j]&1 != 0 {
  18352. curRh = hchar
  18353. } else {
  18354. curRh = uint16(256 + minQuarterword)
  18355. }
  18356. } else {
  18357. prg.curR = uint16(*(*prg.mem[prg.ligStack].hh()).b1())
  18358. }
  18359. }
  18360. goto continue1
  18361. }
  18362. r = j
  18363. return r
  18364. }
  18365. func (prg *prg) hyphenate() {
  18366. var (
  18367. // Local variables for hyphenation
  18368. i, j, l/* 0..65 */ byte // indices into |hc| or |hu|
  18369. q, r1, s halfword // temporary registers for list manipulation
  18370. bchar halfword // boundary character of hyphenated word, or |non_char|
  18371. majorTail, minorTail halfword // the end of lists in the main and
  18372. // discretionary branches being reconstructed
  18373. c asciiCode // character temporarily replaced by a hyphen
  18374. cLoc/* 0..63 */ byte // where that character came from
  18375. rCount int32 // replacement count for discretionary
  18376. hyfNode halfword // the hyphen, if it exists
  18377. z triePointer // an index into |trie|
  18378. v int32 // an index into |hyf_distance|, etc.
  18379. h hyphPointer // an index into |hyph_word| and |hyph_list|
  18380. k strNumber // an index into |str_start|
  18381. u poolPointer // an index into |str_pool|
  18382. )
  18383. for ii := int32(0); ii <= int32(prg.hn); ii++ {
  18384. j = byte(ii)
  18385. _ = j
  18386. prg.hyf[j] = 0
  18387. }
  18388. // Look for the word |hc[1..hn]| in the exception table, and |goto found| (with |hyf| containing the hyphens) if an entry is found
  18389. h = prg.hc[1]
  18390. prg.hn = byte(int32(prg.hn) + 1)
  18391. prg.hc[prg.hn] = uint16(prg.curLang)
  18392. for ii := int32(2); ii <= int32(prg.hn); ii++ {
  18393. j = byte(ii)
  18394. _ = j
  18395. h = uint16((int32(h) + int32(h) + int32(prg.hc[j])) % hyphSize)
  18396. }
  18397. for true {
  18398. k = prg.hyphWord[h]
  18399. if int32(k) == 0 {
  18400. goto notFound
  18401. }
  18402. if int32(prg.strStart[int32(k)+1])-int32(prg.strStart[k]) < int32(prg.hn) {
  18403. goto notFound
  18404. }
  18405. if int32(prg.strStart[int32(k)+1])-int32(prg.strStart[k]) == int32(prg.hn) {
  18406. j = 1
  18407. u = prg.strStart[k]
  18408. for {
  18409. if int32(prg.strPool[u]) < int32(prg.hc[j]) {
  18410. goto notFound
  18411. }
  18412. if int32(prg.strPool[u]) > int32(prg.hc[j]) {
  18413. goto done
  18414. }
  18415. j = byte(int32(j) + 1)
  18416. u = uint16(int32(u) + 1)
  18417. if int32(j) > int32(prg.hn) {
  18418. break
  18419. }
  18420. }
  18421. // Insert hyphens as specified in |hyph_list[h]|
  18422. s = prg.hyphList[h]
  18423. for int32(s) != 0 {
  18424. prg.hyf[*(*prg.mem[s].hh()).lh()] = 1
  18425. s = *(*prg.mem[s].hh()).rh()
  18426. }
  18427. prg.hn = byte(int32(prg.hn) - 1)
  18428. goto found
  18429. }
  18430. done:
  18431. ;
  18432. if int32(h) > 0 {
  18433. h = uint16(int32(h) - 1)
  18434. } else {
  18435. h = uint16(hyphSize)
  18436. }
  18437. }
  18438. notFound:
  18439. prg.hn = byte(int32(prg.hn) - 1)
  18440. if int32(*prg.trie[int32(prg.curLang)+1].b1()) != int32(prg.curLang)+minQuarterword {
  18441. goto exit
  18442. } // no patterns for |cur_lang|
  18443. prg.hc[0] = 0
  18444. prg.hc[int32(prg.hn)+1] = 0
  18445. prg.hc[int32(prg.hn)+2] = 256 // insert delimiters
  18446. for ii := int32(0); ii <= int32(prg.hn)-prg.rHyf+1; ii++ {
  18447. j = byte(ii)
  18448. _ = j
  18449. z = uint16(int32(*prg.trie[int32(prg.curLang)+1].rh()) + int32(prg.hc[j]))
  18450. l = j
  18451. for int32(prg.hc[l]) == int32(*prg.trie[z].b1())-minQuarterword {
  18452. if int32(*prg.trie[z].b0()) != minQuarterword {
  18453. v = int32(*prg.trie[z].b0())
  18454. for {
  18455. v = v + int32(prg.opStart[prg.curLang])
  18456. i = byte(int32(l) - int32(prg.hyfDistance[v-1]))
  18457. if int32(prg.hyfNum[v-1]) > int32(prg.hyf[i]) {
  18458. prg.hyf[i] = prg.hyfNum[v-1]
  18459. }
  18460. v = int32(prg.hyfNext[v-1])
  18461. if v == minQuarterword {
  18462. break
  18463. }
  18464. }
  18465. }
  18466. l = byte(int32(l) + 1)
  18467. z = uint16(int32(*prg.trie[z].rh()) + int32(prg.hc[l]))
  18468. }
  18469. }
  18470. found:
  18471. for ii := int32(0); ii <= prg.lHyf-1; ii++ {
  18472. j = byte(ii)
  18473. _ = j
  18474. prg.hyf[j] = 0
  18475. }
  18476. for ii := int32(0); ii <= prg.rHyf-1; ii++ {
  18477. j = byte(ii)
  18478. _ = j
  18479. prg.hyf[int32(prg.hn)-int32(j)] = 0
  18480. }
  18481. // If no hyphens were found, |return|
  18482. for ii := prg.lHyf; ii <= int32(prg.hn)-prg.rHyf; ii++ {
  18483. j = byte(ii)
  18484. _ = j
  18485. if prg.hyf[j]&1 != 0 {
  18486. goto found1
  18487. }
  18488. }
  18489. goto exit
  18490. found1:
  18491. ;
  18492. // Replace nodes |ha..hb| by a sequence of nodes that includes the discretionary hyphens
  18493. q = *(*prg.mem[prg.hb].hh()).rh()
  18494. *(*prg.mem[prg.hb].hh()).rh() = 0
  18495. r1 = *(*prg.mem[prg.ha].hh()).rh()
  18496. *(*prg.mem[prg.ha].hh()).rh() = 0
  18497. bchar = prg.hyfBchar
  18498. if int32(prg.ha) >= int32(prg.hiMemMin) {
  18499. if int32(*(*prg.mem[prg.ha].hh()).b0()) != int32(prg.hf) {
  18500. goto found2
  18501. } else {
  18502. prg.initList = prg.ha
  18503. prg.initLig = false
  18504. prg.hu[0] = uint16(int32(*(*prg.mem[prg.ha].hh()).b1()) - minQuarterword)
  18505. }
  18506. } else if int32(*(*prg.mem[prg.ha].hh()).b0()) == ligatureNode {
  18507. if int32(*(*prg.mem[int32(prg.ha)+1].hh()).b0()) != int32(prg.hf) {
  18508. goto found2
  18509. } else {
  18510. prg.initList = *(*prg.mem[int32(prg.ha)+1].hh()).rh()
  18511. prg.initLig = true
  18512. prg.initLft = int32(*(*prg.mem[prg.ha].hh()).b1()) > 1
  18513. prg.hu[0] = uint16(int32(*(*prg.mem[int32(prg.ha)+1].hh()).b1()) - minQuarterword)
  18514. if int32(prg.initList) == 0 {
  18515. if prg.initLft {
  18516. prg.hu[0] = 256
  18517. prg.initLig = false
  18518. }
  18519. } // in this case a ligature will be reconstructed from scratch
  18520. prg.freeNode(prg.ha, halfword(smallNodeSize))
  18521. }
  18522. } else {
  18523. if !(int32(r1) >= int32(prg.hiMemMin)) {
  18524. if int32(*(*prg.mem[r1].hh()).b0()) == ligatureNode {
  18525. if int32(*(*prg.mem[r1].hh()).b1()) > 1 {
  18526. goto found2
  18527. }
  18528. }
  18529. }
  18530. j = 1
  18531. s = prg.ha
  18532. prg.initList = 0
  18533. goto commonEnding
  18534. }
  18535. s = prg.curP // we have |cur_p<>ha| because |type(cur_p)=glue_node|
  18536. for int32(*(*prg.mem[s].hh()).rh()) != int32(prg.ha) {
  18537. s = *(*prg.mem[s].hh()).rh()
  18538. }
  18539. j = 0
  18540. goto commonEnding
  18541. found2:
  18542. s = prg.ha
  18543. j = 0
  18544. prg.hu[0] = 256
  18545. prg.initLig = false
  18546. prg.initList = 0
  18547. commonEnding:
  18548. prg.flushNodeList(r1)
  18549. // Reconstitute nodes for the hyphenated word, inserting discretionary hyphens
  18550. for {
  18551. l = j
  18552. j = byte(int32(prg.reconstitute(j, prg.hn, bchar, halfword(prg.hyfChar+minQuarterword))) + 1)
  18553. if int32(prg.hyphenPassed) == 0 {
  18554. *(*prg.mem[s].hh()).rh() = *(*prg.mem[30000-4].hh()).rh()
  18555. for int32(*(*prg.mem[s].hh()).rh()) > 0 {
  18556. s = *(*prg.mem[s].hh()).rh()
  18557. }
  18558. if prg.hyf[int32(j)-1]&1 != 0 {
  18559. l = j
  18560. prg.hyphenPassed = byte(int32(j) - 1)
  18561. *(*prg.mem[30000-4].hh()).rh() = 0
  18562. }
  18563. }
  18564. if int32(prg.hyphenPassed) > 0 {
  18565. for {
  18566. r1 = prg.getNode(smallNodeSize)
  18567. *(*prg.mem[r1].hh()).rh() = *(*prg.mem[30000-4].hh()).rh()
  18568. *(*prg.mem[r1].hh()).b0() = byte(discNode)
  18569. majorTail = r1
  18570. rCount = 0
  18571. for int32(*(*prg.mem[majorTail].hh()).rh()) > 0 {
  18572. majorTail = *(*prg.mem[majorTail].hh()).rh()
  18573. rCount = rCount + 1
  18574. }
  18575. i = prg.hyphenPassed
  18576. prg.hyf[i] = 0
  18577. // Put the \(c)characters |hu[l..i]| and a hyphen into |pre_break(r)|
  18578. minorTail = 0
  18579. *(*prg.mem[int32(r1)+1].hh()).lh() = 0
  18580. hyfNode = prg.newCharacter(prg.hf, eightBits(prg.hyfChar))
  18581. if int32(hyfNode) != 0 {
  18582. i = byte(int32(i) + 1)
  18583. c = byte(prg.hu[i])
  18584. prg.hu[i] = uint16(prg.hyfChar)
  18585. {
  18586. *(*prg.mem[hyfNode].hh()).rh() = prg.avail
  18587. prg.avail = hyfNode /* dyn_used:= dyn_used-1 ; [ ] */
  18588. }
  18589. }
  18590. for int32(l) <= int32(i) {
  18591. l = byte(int32(prg.reconstitute(l, i, prg.fontBchar[prg.hf], halfword(256+minQuarterword))) + 1)
  18592. if int32(*(*prg.mem[30000-4].hh()).rh()) > 0 {
  18593. if int32(minorTail) == 0 {
  18594. *(*prg.mem[int32(r1)+1].hh()).lh() = *(*prg.mem[30000-4].hh()).rh()
  18595. } else {
  18596. *(*prg.mem[minorTail].hh()).rh() = *(*prg.mem[30000-4].hh()).rh()
  18597. }
  18598. minorTail = *(*prg.mem[30000-4].hh()).rh()
  18599. for int32(*(*prg.mem[minorTail].hh()).rh()) > 0 {
  18600. minorTail = *(*prg.mem[minorTail].hh()).rh()
  18601. }
  18602. }
  18603. }
  18604. if int32(hyfNode) != 0 {
  18605. prg.hu[i] = uint16(c) // restore the character in the hyphen position
  18606. l = i
  18607. i = byte(int32(i) - 1)
  18608. }
  18609. // Put the \(c)characters |hu[i+1..@,]| into |post_break(r)|, appending to this list and to |major_tail| until synchronization has been achieved
  18610. minorTail = 0
  18611. *(*prg.mem[int32(r1)+1].hh()).rh() = 0
  18612. cLoc = 0
  18613. if int32(prg.bcharLabel[prg.hf]) != nonAddress {
  18614. l = byte(int32(l) - 1)
  18615. c = byte(prg.hu[l])
  18616. cLoc = l
  18617. prg.hu[l] = 256
  18618. }
  18619. for int32(l) < int32(j) {
  18620. for {
  18621. l = byte(int32(prg.reconstitute(l, prg.hn, bchar, halfword(256+minQuarterword))) + 1)
  18622. if int32(cLoc) > 0 {
  18623. prg.hu[cLoc] = uint16(c)
  18624. cLoc = 0
  18625. }
  18626. if int32(*(*prg.mem[30000-4].hh()).rh()) > 0 {
  18627. if int32(minorTail) == 0 {
  18628. *(*prg.mem[int32(r1)+1].hh()).rh() = *(*prg.mem[30000-4].hh()).rh()
  18629. } else {
  18630. *(*prg.mem[minorTail].hh()).rh() = *(*prg.mem[30000-4].hh()).rh()
  18631. }
  18632. minorTail = *(*prg.mem[30000-4].hh()).rh()
  18633. for int32(*(*prg.mem[minorTail].hh()).rh()) > 0 {
  18634. minorTail = *(*prg.mem[minorTail].hh()).rh()
  18635. }
  18636. }
  18637. if int32(l) >= int32(j) {
  18638. break
  18639. }
  18640. }
  18641. for int32(l) > int32(j) {
  18642. // Append characters of |hu[j..@,]| to |major_tail|, advancing~|j|
  18643. j = byte(int32(prg.reconstitute(j, prg.hn, bchar, halfword(256+minQuarterword))) + 1)
  18644. *(*prg.mem[majorTail].hh()).rh() = *(*prg.mem[30000-4].hh()).rh()
  18645. for int32(*(*prg.mem[majorTail].hh()).rh()) > 0 {
  18646. majorTail = *(*prg.mem[majorTail].hh()).rh()
  18647. rCount = rCount + 1
  18648. }
  18649. }
  18650. }
  18651. // Move pointer |s| to the end of the current list, and set |replace_count(r)| appropriately
  18652. if rCount > 127 {
  18653. *(*prg.mem[s].hh()).rh() = *(*prg.mem[r1].hh()).rh()
  18654. *(*prg.mem[r1].hh()).rh() = 0
  18655. prg.flushNodeList(r1)
  18656. } else {
  18657. *(*prg.mem[s].hh()).rh() = r1
  18658. *(*prg.mem[r1].hh()).b1() = byte(rCount)
  18659. }
  18660. s = majorTail
  18661. prg.hyphenPassed = byte(int32(j) - 1)
  18662. *(*prg.mem[30000-4].hh()).rh() = 0
  18663. if !(prg.hyf[int32(j)-1]&1 != 0) {
  18664. break
  18665. }
  18666. }
  18667. }
  18668. if int32(j) > int32(prg.hn) {
  18669. break
  18670. }
  18671. }
  18672. *(*prg.mem[s].hh()).rh() = q
  18673. prg.flushList(prg.initList)
  18674. exit:
  18675. }
  18676. // Declare procedures for preprocessing hyphenation patterns
  18677. func (prg *prg) newTrieOp(d, n smallNumber, v quarterword) (r quarterword) {
  18678. var (
  18679. h/* -trieOpSize..trieOpSize */ int16 // trial hash location
  18680. u quarterword // trial op code
  18681. l/* 0..trieOpSize */ uint16 // pointer to stored data
  18682. )
  18683. h = int16(abs(int32(n)+313*int32(d)+361*int32(v)+1009*int32(prg.curLang))%(trieOpSize+trieOpSize) - trieOpSize)
  18684. for true {
  18685. l = prg.trieOpHash[h+500]
  18686. if int32(l) == 0 {
  18687. if int32(prg.trieOpPtr) == trieOpSize {
  18688. prg.overflow(strNumber( /* "pattern memory ops" */ 949), trieOpSize)
  18689. }
  18690. u = prg.trieUsed[prg.curLang]
  18691. if int32(u) == maxQuarterword {
  18692. prg.overflow(strNumber( /* "pattern memory ops per language" */ 950), maxQuarterword-minQuarterword)
  18693. }
  18694. prg.trieOpPtr = uint16(int32(prg.trieOpPtr) + 1)
  18695. u = byte(int32(u) + 1)
  18696. prg.trieUsed[prg.curLang] = u
  18697. prg.hyfDistance[prg.trieOpPtr-1] = d
  18698. prg.hyfNum[prg.trieOpPtr-1] = n
  18699. prg.hyfNext[prg.trieOpPtr-1] = v
  18700. prg.trieOpLang[prg.trieOpPtr-1] = prg.curLang
  18701. prg.trieOpHash[h+500] = prg.trieOpPtr
  18702. prg.trieOpVal[prg.trieOpPtr-1] = u
  18703. r = u
  18704. goto exit
  18705. }
  18706. if int32(prg.hyfDistance[l-1]) == int32(d) && int32(prg.hyfNum[l-1]) == int32(n) && int32(prg.hyfNext[l-1]) == int32(v) && int32(prg.trieOpLang[l-1]) == int32(prg.curLang) {
  18707. r = prg.trieOpVal[l-1]
  18708. goto exit
  18709. }
  18710. if int32(h) > -trieOpSize {
  18711. h = int16(int32(h) - 1)
  18712. } else {
  18713. h = int16(trieOpSize)
  18714. }
  18715. }
  18716. exit:
  18717. ;
  18718. return r
  18719. }
  18720. func (prg *prg) trieNode(p triePointer) (r triePointer) {
  18721. var (
  18722. h triePointer // trial hash location
  18723. q triePointer // trial trie node
  18724. )
  18725. h = uint16(abs(int32(prg.trieC[p])+1009*int32(prg.trieO[p])+
  18726. 2718*int32(prg.trieL[p])+3142*int32(prg.trieR[p])) % trieSize)
  18727. for true {
  18728. q = prg.trieHash[h]
  18729. if int32(q) == 0 {
  18730. prg.trieHash[h] = p
  18731. r = p
  18732. goto exit
  18733. }
  18734. if int32(prg.trieC[q]) == int32(prg.trieC[p]) && int32(prg.trieO[q]) == int32(prg.trieO[p]) && int32(prg.trieL[q]) == int32(prg.trieL[p]) && int32(prg.trieR[q]) == int32(prg.trieR[p]) {
  18735. r = q
  18736. goto exit
  18737. }
  18738. if int32(h) > 0 {
  18739. h = uint16(int32(h) - 1)
  18740. } else {
  18741. h = uint16(trieSize)
  18742. }
  18743. }
  18744. exit:
  18745. ;
  18746. return r
  18747. }
  18748. func (prg *prg) compressTrie(p triePointer) (r triePointer) {
  18749. if int32(p) == 0 {
  18750. r = 0
  18751. } else {
  18752. prg.trieL[p] = prg.compressTrie(prg.trieL[p])
  18753. prg.trieR[p] = prg.compressTrie(prg.trieR[p])
  18754. r = prg.trieNode(p)
  18755. }
  18756. return r
  18757. }
  18758. func (prg *prg) firstFit(p triePointer) {
  18759. var (
  18760. h triePointer // candidate for |trie_ref[p]|
  18761. z triePointer // runs through holes
  18762. q triePointer // runs through the family starting at |p|
  18763. c asciiCode // smallest character in the family
  18764. l, r1 triePointer // left and right neighbors
  18765. ll/* 1..256 */ uint16 // upper limit of |trie_min| updating
  18766. )
  18767. c = prg.trieC[p]
  18768. z = prg.trieMin[c] // get the first conceivably good hole
  18769. for true {
  18770. h = uint16(int32(z) - int32(c))
  18771. // Ensure that |trie_max>=h+256|
  18772. if int32(prg.trieMax) < int32(h)+256 {
  18773. if trieSize <= int32(h)+256 {
  18774. prg.overflow(strNumber( /* "pattern memory" */ 951), trieSize)
  18775. }
  18776. // \xref[TeX capacity exceeded pattern memory][\quad pattern memory]
  18777. for {
  18778. prg.trieMax = uint16(int32(prg.trieMax) + 1)
  18779. prg.trieTaken[prg.trieMax-1] = false
  18780. *prg.trie[prg.trieMax].rh() = uint16(int32(prg.trieMax) + 1)
  18781. *prg.trie[prg.trieMax].lh() = uint16(int32(prg.trieMax) - 1)
  18782. if int32(prg.trieMax) == int32(h)+256 {
  18783. break
  18784. }
  18785. }
  18786. }
  18787. if prg.trieTaken[h-1] {
  18788. goto notFound
  18789. }
  18790. // If all characters of the family fit relative to |h|, then |goto found|,\30\ otherwise |goto not_found|
  18791. q = prg.trieR[p]
  18792. for int32(q) > 0 {
  18793. if int32(*prg.trie[int32(h)+int32(prg.trieC[q])].rh()) == 0 {
  18794. goto notFound
  18795. }
  18796. q = prg.trieR[q]
  18797. }
  18798. goto found
  18799. notFound:
  18800. z = *prg.trie[z].rh() // move to the next hole
  18801. }
  18802. found:
  18803. prg.trieTaken[h-1] = true
  18804. prg.trieHash[p] = h
  18805. q = p
  18806. for {
  18807. z = uint16(int32(h) + int32(prg.trieC[q]))
  18808. l = *prg.trie[z].lh()
  18809. r1 = *prg.trie[z].rh()
  18810. *prg.trie[r1].lh() = l
  18811. *prg.trie[l].rh() = r1
  18812. *prg.trie[z].rh() = 0
  18813. if int32(l) < 256 {
  18814. if int32(z) < 256 {
  18815. ll = z
  18816. } else {
  18817. ll = 256
  18818. }
  18819. for {
  18820. prg.trieMin[l] = r1
  18821. l = uint16(int32(l) + 1)
  18822. if int32(l) == int32(ll) {
  18823. break
  18824. }
  18825. }
  18826. }
  18827. q = prg.trieR[q]
  18828. if int32(q) == 0 {
  18829. break
  18830. }
  18831. }
  18832. }
  18833. func (prg *prg) triePack(p triePointer) { // pack subtries of a family
  18834. var (
  18835. q triePointer // a local variable that need not be saved on recursive calls
  18836. )
  18837. for {
  18838. q = prg.trieL[p]
  18839. if int32(q) > 0 && int32(prg.trieHash[q]) == 0 {
  18840. prg.firstFit(q)
  18841. prg.triePack(q)
  18842. }
  18843. p = prg.trieR[p]
  18844. if int32(p) == 0 {
  18845. break
  18846. }
  18847. }
  18848. }
  18849. func (prg *prg) trieFix(p triePointer) { // moves |p| and its siblings into |trie|
  18850. var (
  18851. q triePointer // a local variable that need not be saved on recursive calls
  18852. c asciiCode // another one that need not be saved
  18853. z triePointer // |trie| reference; this local variable must be saved
  18854. )
  18855. z = prg.trieHash[p]
  18856. for {
  18857. q = prg.trieL[p]
  18858. c = prg.trieC[p]
  18859. *prg.trie[int32(z)+int32(c)].rh() = prg.trieHash[q]
  18860. *prg.trie[int32(z)+int32(c)].b1() = byte(int32(c) + minQuarterword)
  18861. *prg.trie[int32(z)+int32(c)].b0() = prg.trieO[p]
  18862. if int32(q) > 0 {
  18863. prg.trieFix(q)
  18864. }
  18865. p = prg.trieR[p]
  18866. if int32(p) == 0 {
  18867. break
  18868. }
  18869. }
  18870. }
  18871. func (prg *prg) newPatterns() {
  18872. var (
  18873. k, l/* 0..64 */ byte // indices into |hc| and |hyf|;
  18874. // not always in |small_number| range
  18875. digitSensed bool // should the next digit be treated as a letter?
  18876. v quarterword // trie op code
  18877. p, q triePointer // nodes of trie traversed during insertion
  18878. firstChild bool // is |p=trie_l[q]|?
  18879. c asciiCode // character being inserted
  18880. )
  18881. if prg.trieNotReady {
  18882. if *prg.eqtb[intBase+languageCode-1].int() <= 0 {
  18883. prg.curLang = 0
  18884. } else if *prg.eqtb[intBase+languageCode-1].int() > 255 {
  18885. prg.curLang = 0
  18886. } else {
  18887. prg.curLang = byte(*prg.eqtb[intBase+languageCode-1].int())
  18888. }
  18889. prg.scanLeftBrace() // a left brace must follow \.[\\patterns]
  18890. // Enter all of the patterns into a linked trie, until coming to a right brace
  18891. k = 0
  18892. prg.hyf[0] = 0
  18893. digitSensed = false
  18894. for true {
  18895. prg.getXToken()
  18896. switch prg.curCmd {
  18897. case letter, otherChar:
  18898. // Append a new letter or a hyphen level
  18899. if digitSensed || int32(prg.curChr) < '0' || int32(prg.curChr) > '9' {
  18900. if int32(prg.curChr) == '.' {
  18901. prg.curChr = 0
  18902. } else {
  18903. prg.curChr = *(*prg.eqtb[lcCodeBase+int32(prg.curChr)-1].hh()).rh()
  18904. if int32(prg.curChr) == 0 {
  18905. {
  18906. if int32(prg.interaction) == errorStopMode {
  18907. }
  18908. prg.printNl(strNumber( /* "! " */ 262))
  18909. prg.print( /* "Nonletter" */ 957)
  18910. }
  18911. // \xref[Nonletter]
  18912. {
  18913. prg.helpPtr = 1
  18914. prg.helpLine[0] = /* "(See Appendix H.)" */ 956
  18915. }
  18916. prg.error1()
  18917. }
  18918. }
  18919. if int32(k) < 63 {
  18920. k = byte(int32(k) + 1)
  18921. prg.hc[k] = prg.curChr
  18922. prg.hyf[k] = 0
  18923. digitSensed = false
  18924. }
  18925. } else if int32(k) < 63 {
  18926. prg.hyf[k] = byte(int32(prg.curChr) - '0')
  18927. digitSensed = true
  18928. }
  18929. case spacer, rightBrace:
  18930. if int32(k) > 0 {
  18931. if int32(prg.hc[1]) == 0 {
  18932. prg.hyf[0] = 0
  18933. }
  18934. if int32(prg.hc[k]) == 0 {
  18935. prg.hyf[k] = 0
  18936. }
  18937. l = k
  18938. v = byte(minQuarterword)
  18939. for true {
  18940. if int32(prg.hyf[l]) != 0 {
  18941. v = prg.newTrieOp(smallNumber(int32(k)-int32(l)), prg.hyf[l], v)
  18942. }
  18943. if int32(l) > 0 {
  18944. l = byte(int32(l) - 1)
  18945. } else {
  18946. goto done1
  18947. }
  18948. }
  18949. done1:
  18950. ;
  18951. q = 0
  18952. prg.hc[0] = uint16(prg.curLang)
  18953. for int32(l) <= int32(k) {
  18954. c = byte(prg.hc[l])
  18955. l = byte(int32(l) + 1)
  18956. p = prg.trieL[q]
  18957. firstChild = true
  18958. for int32(p) > 0 && int32(c) > int32(prg.trieC[p]) {
  18959. q = p
  18960. p = prg.trieR[q]
  18961. firstChild = false
  18962. }
  18963. if int32(p) == 0 || int32(c) < int32(prg.trieC[p]) {
  18964. if int32(prg.triePtr) == trieSize {
  18965. prg.overflow(strNumber( /* "pattern memory" */ 951), trieSize)
  18966. }
  18967. // \xref[TeX capacity exceeded pattern memory][\quad pattern memory]
  18968. prg.triePtr = uint16(int32(prg.triePtr) + 1)
  18969. prg.trieR[prg.triePtr] = p
  18970. p = prg.triePtr
  18971. prg.trieL[p] = 0
  18972. if firstChild {
  18973. prg.trieL[q] = p
  18974. } else {
  18975. prg.trieR[q] = p
  18976. }
  18977. prg.trieC[p] = c
  18978. prg.trieO[p] = byte(minQuarterword)
  18979. }
  18980. q = p // now node |q| represents $p_1\ldots p_[l-1]$
  18981. }
  18982. if int32(prg.trieO[q]) != minQuarterword {
  18983. {
  18984. if int32(prg.interaction) == errorStopMode {
  18985. }
  18986. prg.printNl(strNumber( /* "! " */ 262))
  18987. prg.print( /* "Duplicate pattern" */ 958)
  18988. }
  18989. // \xref[Duplicate pattern]
  18990. {
  18991. prg.helpPtr = 1
  18992. prg.helpLine[0] = /* "(See Appendix H.)" */ 956
  18993. }
  18994. prg.error1()
  18995. }
  18996. prg.trieO[q] = v
  18997. }
  18998. if int32(prg.curCmd) == rightBrace {
  18999. goto done
  19000. }
  19001. k = 0
  19002. prg.hyf[0] = 0
  19003. digitSensed = false
  19004. default:
  19005. {
  19006. if int32(prg.interaction) == errorStopMode {
  19007. }
  19008. prg.printNl(strNumber( /* "! " */ 262))
  19009. prg.print( /* "Bad " */ 955)
  19010. }
  19011. prg.printEsc(strNumber( /* "patterns" */ 953))
  19012. // \xref[Bad \\patterns]
  19013. {
  19014. prg.helpPtr = 1
  19015. prg.helpLine[0] = /* "(See Appendix H.)" */ 956
  19016. }
  19017. prg.error1()
  19018. }
  19019. }
  19020. done:
  19021. } else {
  19022. {
  19023. if int32(prg.interaction) == errorStopMode {
  19024. }
  19025. prg.printNl(strNumber( /* "! " */ 262))
  19026. prg.print( /* "Too late for " */ 952)
  19027. }
  19028. prg.printEsc(strNumber( /* "patterns" */ 953))
  19029. {
  19030. prg.helpPtr = 1
  19031. prg.helpLine[0] = /* "All patterns must be given before typesetting begins." */ 954
  19032. }
  19033. prg.error1()
  19034. *(*prg.mem[30000-12].hh()).rh() = prg.scanToks(false, false)
  19035. prg.flushList(prg.defRef)
  19036. }
  19037. }
  19038. func (prg *prg) initTrie() {
  19039. var (
  19040. p triePointer // pointer for initialization
  19041. j, k, t int32 // all-purpose registers for initialization
  19042. r1, s triePointer // used to clean up the packed |trie|
  19043. h twoHalves // template used to zero out |trie|'s holes
  19044. )
  19045. prg.opStart[0] = uint16(-minQuarterword)
  19046. for ii := int32(1); ii <= 255; ii++ {
  19047. j = ii
  19048. _ = j
  19049. prg.opStart[j] = uint16(int32(prg.opStart[j-1]) + int32(prg.trieUsed[j-1]) - minQuarterword)
  19050. }
  19051. for ii := int32(1); ii <= int32(prg.trieOpPtr); ii++ {
  19052. j = ii
  19053. _ = j
  19054. prg.trieOpHash[j+500] = uint16(int32(prg.opStart[prg.trieOpLang[j-1]]) + int32(prg.trieOpVal[j-1]))
  19055. } // destination
  19056. for ii := int32(1); ii <= int32(prg.trieOpPtr); ii++ {
  19057. j = ii
  19058. _ = j
  19059. for int32(prg.trieOpHash[j+500]) > j {
  19060. k = int32(prg.trieOpHash[j+500])
  19061. t = int32(prg.hyfDistance[k-1])
  19062. prg.hyfDistance[k-1] = prg.hyfDistance[j-1]
  19063. prg.hyfDistance[j-1] = byte(t)
  19064. t = int32(prg.hyfNum[k-1])
  19065. prg.hyfNum[k-1] = prg.hyfNum[j-1]
  19066. prg.hyfNum[j-1] = byte(t)
  19067. t = int32(prg.hyfNext[k-1])
  19068. prg.hyfNext[k-1] = prg.hyfNext[j-1]
  19069. prg.hyfNext[j-1] = byte(t)
  19070. prg.trieOpHash[j+500] = prg.trieOpHash[k+500]
  19071. prg.trieOpHash[k+500] = uint16(k)
  19072. }
  19073. }
  19074. for ii := int32(0); ii <= trieSize; ii++ {
  19075. p = triePointer(ii)
  19076. _ = p
  19077. prg.trieHash[p] = 0
  19078. }
  19079. prg.trieL[0] = prg.compressTrie(prg.trieL[0]) // identify equivalent subtries
  19080. for ii := int32(0); ii <= int32(prg.triePtr); ii++ {
  19081. p = triePointer(ii)
  19082. _ = p
  19083. prg.trieHash[p] = 0
  19084. }
  19085. for ii := int32(0); ii <= 255; ii++ {
  19086. p = triePointer(ii)
  19087. _ = p
  19088. prg.trieMin[p] = uint16(int32(p) + 1)
  19089. }
  19090. *prg.trie[0].rh() = 1
  19091. prg.trieMax = 0
  19092. if int32(prg.trieL[0]) != 0 {
  19093. prg.firstFit(prg.trieL[0])
  19094. prg.triePack(prg.trieL[0])
  19095. }
  19096. // Move the data into |trie|
  19097. *h.rh() = 0
  19098. *h.b0() = byte(minQuarterword)
  19099. *h.b1() = byte(minQuarterword) // |trie_link:=0|,
  19100. // |trie_op:=min_quarterword|, |trie_char:=qi(0)|
  19101. if int32(prg.trieL[0]) == 0 {
  19102. for ii := int32(0); ii <= 256; ii++ {
  19103. r1 = triePointer(ii)
  19104. _ = r1
  19105. prg.trie[r1] = h
  19106. }
  19107. prg.trieMax = 256
  19108. } else {
  19109. prg.trieFix(prg.trieL[0]) // this fixes the non-holes in |trie|
  19110. r1 = 0 // now we will zero out all the holes
  19111. for {
  19112. s = *prg.trie[r1].rh()
  19113. prg.trie[r1] = h
  19114. r1 = s
  19115. if int32(r1) > int32(prg.trieMax) {
  19116. break
  19117. }
  19118. }
  19119. }
  19120. *prg.trie[0].b1() = byte('?' + minQuarterword) // make |trie_char(c)<>c| for all |c|
  19121. prg.trieNotReady = false
  19122. }
  19123. func (prg *prg) lineBreak(finalWidowPenalty int32) {
  19124. var (
  19125. // Local variables for line breaking
  19126. autoBreaking bool // is node |cur_p| outside a formula?
  19127. prevP halfword // helps to determine when glue nodes are breakpoints
  19128. q, r1, s, prevS halfword // miscellaneous nodes of temporary interest
  19129. f internalFontNumber // used when calculating character widths
  19130. j smallNumber // an index into |hc| or |hu|
  19131. c/* 0..255 */ byte // character being considered for hyphenation
  19132. )
  19133. prg.packBeginLine = prg.curList.mlField // this is for over/underfull box messages
  19134. // Get ready to start line breaking
  19135. *(*prg.mem[30000-3].hh()).rh() = *(*prg.mem[prg.curList.headField].hh()).rh()
  19136. if int32(prg.curList.tailField) >= int32(prg.hiMemMin) {
  19137. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newPenalty(infPenalty)
  19138. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  19139. } else if int32(*(*prg.mem[prg.curList.tailField].hh()).b0()) != glueNode {
  19140. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newPenalty(infPenalty)
  19141. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  19142. } else {
  19143. *(*prg.mem[prg.curList.tailField].hh()).b0() = byte(penaltyNode)
  19144. prg.deleteGlueRef(*(*prg.mem[int32(prg.curList.tailField)+1].hh()).lh())
  19145. prg.flushNodeList(*(*prg.mem[int32(prg.curList.tailField)+1].hh()).rh())
  19146. *prg.mem[int32(prg.curList.tailField)+1].int() = infPenalty
  19147. }
  19148. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newParamGlue(smallNumber(parFillSkipCode))
  19149. prg.initCurLang = byte(prg.curList.pgField % 0200000)
  19150. prg.initLHyf = prg.curList.pgField / 020000000
  19151. prg.initRHyf = prg.curList.pgField / 0200000 % 0100
  19152. prg.popNest()
  19153. prg.noShrinkErrorYet = true
  19154. if int32(*(*prg.mem[*(*prg.eqtb[glueBase+leftSkipCode-1].hh()).rh()].hh()).b1()) != normal && *prg.mem[int32(*(*prg.eqtb[glueBase+leftSkipCode-1].hh()).rh())+3].int() != 0 {
  19155. *(*prg.eqtb[glueBase+leftSkipCode-1].hh()).rh() = prg.finiteShrink(*(*prg.eqtb[glueBase+leftSkipCode-1].hh()).rh())
  19156. }
  19157. if int32(*(*prg.mem[*(*prg.eqtb[glueBase+rightSkipCode-1].hh()).rh()].hh()).b1()) != normal && *prg.mem[int32(*(*prg.eqtb[glueBase+rightSkipCode-1].hh()).rh())+3].int() != 0 {
  19158. *(*prg.eqtb[glueBase+rightSkipCode-1].hh()).rh() = prg.finiteShrink(*(*prg.eqtb[glueBase+rightSkipCode-1].hh()).rh())
  19159. }
  19160. q = *(*prg.eqtb[glueBase+leftSkipCode-1].hh()).rh()
  19161. r1 = *(*prg.eqtb[glueBase+rightSkipCode-1].hh()).rh()
  19162. prg.background[1-1] = *prg.mem[int32(q)+widthOffset].int() + *prg.mem[int32(r1)+widthOffset].int()
  19163. prg.background[2-1] = 0
  19164. prg.background[3-1] = 0
  19165. prg.background[4-1] = 0
  19166. prg.background[5-1] = 0
  19167. prg.background[2+int32(*(*prg.mem[q].hh()).b0())-1] = *prg.mem[int32(q)+2].int()
  19168. prg.background[2+int32(*(*prg.mem[r1].hh()).b0())-1] = prg.background[2+int32(*(*prg.mem[r1].hh()).b0())-1] + *prg.mem[int32(r1)+2].int()
  19169. prg.background[6-1] = *prg.mem[int32(q)+3].int() + *prg.mem[int32(r1)+3].int()
  19170. prg.minimumDemerits = 07777777777
  19171. prg.minimalDemerits[tightFit] = 07777777777
  19172. prg.minimalDemerits[decentFit] = 07777777777
  19173. prg.minimalDemerits[looseFit] = 07777777777
  19174. prg.minimalDemerits[veryLooseFit] = 07777777777
  19175. if int32(*(*prg.eqtb[parShapeLoc-1].hh()).rh()) == 0 {
  19176. if *prg.eqtb[dimenBase+hangIndentCode-1].int() == 0 {
  19177. prg.lastSpecialLine = 0
  19178. prg.secondWidth = *prg.eqtb[dimenBase+hsizeCode-1].int()
  19179. prg.secondIndent = 0
  19180. } else {
  19181. // Set line length parameters in preparation for hanging indentation
  19182. prg.lastSpecialLine = uint16(abs(*prg.eqtb[intBase+hangAfterCode-1].int()))
  19183. if *prg.eqtb[intBase+hangAfterCode-1].int() < 0 {
  19184. prg.firstWidth = *prg.eqtb[dimenBase+hsizeCode-1].int() - abs(*prg.eqtb[dimenBase+hangIndentCode-1].int())
  19185. if *prg.eqtb[dimenBase+hangIndentCode-1].int() >= 0 {
  19186. prg.firstIndent = *prg.eqtb[dimenBase+hangIndentCode-1].int()
  19187. } else {
  19188. prg.firstIndent = 0
  19189. }
  19190. prg.secondWidth = *prg.eqtb[dimenBase+hsizeCode-1].int()
  19191. prg.secondIndent = 0
  19192. } else {
  19193. prg.firstWidth = *prg.eqtb[dimenBase+hsizeCode-1].int()
  19194. prg.firstIndent = 0
  19195. prg.secondWidth = *prg.eqtb[dimenBase+hsizeCode-1].int() - abs(*prg.eqtb[dimenBase+hangIndentCode-1].int())
  19196. if *prg.eqtb[dimenBase+hangIndentCode-1].int() >= 0 {
  19197. prg.secondIndent = *prg.eqtb[dimenBase+hangIndentCode-1].int()
  19198. } else {
  19199. prg.secondIndent = 0
  19200. }
  19201. }
  19202. }
  19203. } else {
  19204. prg.lastSpecialLine = uint16(int32(*(*prg.mem[*(*prg.eqtb[parShapeLoc-1].hh()).rh()].hh()).lh()) - 1)
  19205. prg.secondWidth = *prg.mem[int32(*(*prg.eqtb[parShapeLoc-1].hh()).rh())+2*(int32(prg.lastSpecialLine)+1)].int()
  19206. prg.secondIndent = *prg.mem[int32(*(*prg.eqtb[parShapeLoc-1].hh()).rh())+2*int32(prg.lastSpecialLine)+1].int()
  19207. }
  19208. if *prg.eqtb[intBase+loosenessCode-1].int() == 0 {
  19209. prg.easyLine = prg.lastSpecialLine
  19210. } else {
  19211. prg.easyLine = 65535
  19212. }
  19213. // Find optimal breakpoints
  19214. prg.threshold = *prg.eqtb[intBase+pretoleranceCode-1].int()
  19215. if prg.threshold >= 0 {
  19216. prg.secondPass = false
  19217. prg.finalPass = false
  19218. } else {
  19219. prg.threshold = *prg.eqtb[intBase+toleranceCode-1].int()
  19220. prg.secondPass = true
  19221. prg.finalPass = *prg.eqtb[dimenBase+emergencyStretchCode-1].int() <= 0
  19222. // if eqtb[int_base+ tracing_paragraphs_code].int >0 then begin_diagnostic; [ ]
  19223. }
  19224. for true {
  19225. if prg.threshold > infBad {
  19226. prg.threshold = infBad
  19227. }
  19228. if prg.secondPass {
  19229. if prg.trieNotReady {
  19230. prg.initTrie()
  19231. }
  19232. prg.curLang = prg.initCurLang
  19233. prg.lHyf = prg.initLHyf
  19234. prg.rHyf = prg.initRHyf
  19235. }
  19236. // Create an active breakpoint representing the beginning of the paragraph
  19237. q = prg.getNode(activeNodeSize)
  19238. *(*prg.mem[q].hh()).b0() = byte(unhyphenated)
  19239. *(*prg.mem[q].hh()).b1() = byte(decentFit)
  19240. *(*prg.mem[q].hh()).rh() = uint16(30000 - 7)
  19241. *(*prg.mem[int32(q)+1].hh()).rh() = 0
  19242. *(*prg.mem[int32(q)+1].hh()).lh() = uint16(prg.curList.pgField + 1)
  19243. *prg.mem[int32(q)+2].int() = 0
  19244. *(*prg.mem[30000-7].hh()).rh() = q
  19245. prg.activeWidth[1-1] = prg.background[1-1]
  19246. prg.activeWidth[2-1] = prg.background[2-1]
  19247. prg.activeWidth[3-1] = prg.background[3-1]
  19248. prg.activeWidth[4-1] = prg.background[4-1]
  19249. prg.activeWidth[5-1] = prg.background[5-1]
  19250. prg.activeWidth[6-1] = prg.background[6-1]
  19251. prg.passive = 0
  19252. prg.printedNode = uint16(30000 - 3)
  19253. prg.passNumber = 0
  19254. prg.fontInShortDisplay = fontBase
  19255. prg.curP = *(*prg.mem[30000-3].hh()).rh()
  19256. autoBreaking = true
  19257. prevP = prg.curP // glue at beginning is not a legal breakpoint
  19258. for int32(prg.curP) != 0 && int32(*(*prg.mem[30000-7].hh()).rh()) != 30000-7 {
  19259. // Call |try_break| if |cur_p| is a legal breakpoint; on the second pass, also try to hyphenate the next word, if |cur_p| is a glue node; then advance |cur_p| to the next node of the paragraph that could possibly be a legal breakpoint
  19260. if int32(prg.curP) >= int32(prg.hiMemMin) {
  19261. prevP = prg.curP
  19262. for {
  19263. f = *(*prg.mem[prg.curP].hh()).b0()
  19264. prg.activeWidth[1-1] = prg.activeWidth[1-1] + *prg.fontInfo[prg.widthBase[f]+int32((*prg.fontInfo[prg.charBase[f]+int32(*(*prg.mem[prg.curP].hh()).b1())].qqqq()).b0)].int()
  19265. prg.curP = *(*prg.mem[prg.curP].hh()).rh()
  19266. if !(int32(prg.curP) >= int32(prg.hiMemMin)) {
  19267. break
  19268. }
  19269. }
  19270. }
  19271. switch *(*prg.mem[prg.curP].hh()).b0() {
  19272. case hlistNode, vlistNode, ruleNode:
  19273. prg.activeWidth[1-1] = prg.activeWidth[1-1] + *prg.mem[int32(prg.curP)+widthOffset].int()
  19274. case whatsitNode:
  19275. // Advance \(p)past a whatsit node in the \(l)|line_break| loop
  19276. if int32(*(*prg.mem[prg.curP].hh()).b1()) == languageNode {
  19277. prg.curLang = byte(*(*prg.mem[int32(prg.curP)+1].hh()).rh())
  19278. prg.lHyf = int32(*(*prg.mem[int32(prg.curP)+1].hh()).b0())
  19279. prg.rHyf = int32(*(*prg.mem[int32(prg.curP)+1].hh()).b1())
  19280. }
  19281. case glueNode:
  19282. if autoBreaking {
  19283. if int32(prevP) >= int32(prg.hiMemMin) {
  19284. prg.tryBreak(0, smallNumber(unhyphenated))
  19285. } else if int32(*(*prg.mem[prevP].hh()).b0()) < mathNode {
  19286. prg.tryBreak(0, smallNumber(unhyphenated))
  19287. } else if int32(*(*prg.mem[prevP].hh()).b0()) == kernNode && int32(*(*prg.mem[prevP].hh()).b1()) != explicit {
  19288. prg.tryBreak(0, smallNumber(unhyphenated))
  19289. }
  19290. }
  19291. if int32(*(*prg.mem[*(*prg.mem[int32(prg.curP)+1].hh()).lh()].hh()).b1()) != normal && *prg.mem[int32(*(*prg.mem[int32(prg.curP)+1].hh()).lh())+3].int() != 0 {
  19292. *(*prg.mem[int32(prg.curP)+1].hh()).lh() = prg.finiteShrink(*(*prg.mem[int32(prg.curP)+1].hh()).lh())
  19293. }
  19294. q = *(*prg.mem[int32(prg.curP)+1].hh()).lh()
  19295. prg.activeWidth[1-1] = prg.activeWidth[1-1] + *prg.mem[int32(q)+widthOffset].int()
  19296. prg.activeWidth[2+int32(*(*prg.mem[q].hh()).b0())-1] = prg.activeWidth[2+int32(*(*prg.mem[q].hh()).b0())-1] + *prg.mem[int32(q)+2].int()
  19297. prg.activeWidth[6-1] = prg.activeWidth[6-1] + *prg.mem[int32(q)+3].int()
  19298. if prg.secondPass && autoBreaking {
  19299. prevS = prg.curP
  19300. s = *(*prg.mem[prevS].hh()).rh()
  19301. if int32(s) != 0 {
  19302. for true {
  19303. if int32(s) >= int32(prg.hiMemMin) {
  19304. c = byte(int32(*(*prg.mem[s].hh()).b1()) - minQuarterword)
  19305. prg.hf = *(*prg.mem[s].hh()).b0()
  19306. } else if int32(*(*prg.mem[s].hh()).b0()) == ligatureNode {
  19307. if int32(*(*prg.mem[int32(s)+1].hh()).rh()) == 0 {
  19308. goto continue1
  19309. } else {
  19310. q = *(*prg.mem[int32(s)+1].hh()).rh()
  19311. c = byte(int32(*(*prg.mem[q].hh()).b1()) - minQuarterword)
  19312. prg.hf = *(*prg.mem[q].hh()).b0()
  19313. }
  19314. } else if int32(*(*prg.mem[s].hh()).b0()) == kernNode && int32(*(*prg.mem[s].hh()).b1()) == normal {
  19315. goto continue1
  19316. } else if int32(*(*prg.mem[s].hh()).b0()) == whatsitNode {
  19317. if int32(*(*prg.mem[s].hh()).b1()) == languageNode {
  19318. prg.curLang = byte(*(*prg.mem[int32(s)+1].hh()).rh())
  19319. prg.lHyf = int32(*(*prg.mem[int32(s)+1].hh()).b0())
  19320. prg.rHyf = int32(*(*prg.mem[int32(s)+1].hh()).b1())
  19321. }
  19322. goto continue1
  19323. } else {
  19324. goto done1
  19325. }
  19326. if int32(*(*prg.eqtb[lcCodeBase+int32(c)-1].hh()).rh()) != 0 {
  19327. if int32(*(*prg.eqtb[lcCodeBase+int32(c)-1].hh()).rh()) == int32(c) || *prg.eqtb[intBase+ucHyphCode-1].int() > 0 {
  19328. goto done2
  19329. } else {
  19330. goto done1
  19331. }
  19332. }
  19333. continue1:
  19334. prevS = s
  19335. s = *(*prg.mem[prevS].hh()).rh()
  19336. }
  19337. done2:
  19338. prg.hyfChar = prg.hyphenChar[prg.hf]
  19339. if prg.hyfChar < 0 {
  19340. goto done1
  19341. }
  19342. if prg.hyfChar > 255 {
  19343. goto done1
  19344. }
  19345. prg.ha = prevS
  19346. if prg.lHyf+prg.rHyf > 63 {
  19347. goto done1
  19348. }
  19349. // Skip to node |hb|, putting letters into |hu| and |hc|
  19350. prg.hn = 0
  19351. for true {
  19352. if int32(s) >= int32(prg.hiMemMin) {
  19353. if int32(*(*prg.mem[s].hh()).b0()) != int32(prg.hf) {
  19354. goto done3
  19355. }
  19356. prg.hyfBchar = uint16(*(*prg.mem[s].hh()).b1())
  19357. c = byte(int32(prg.hyfBchar) - minQuarterword)
  19358. if int32(*(*prg.eqtb[lcCodeBase+int32(c)-1].hh()).rh()) == 0 {
  19359. goto done3
  19360. }
  19361. if int32(prg.hn) == 63 {
  19362. goto done3
  19363. }
  19364. prg.hb = s
  19365. prg.hn = byte(int32(prg.hn) + 1)
  19366. prg.hu[prg.hn] = uint16(c)
  19367. prg.hc[prg.hn] = *(*prg.eqtb[lcCodeBase+int32(c)-1].hh()).rh()
  19368. prg.hyfBchar = uint16(256 + minQuarterword)
  19369. } else if int32(*(*prg.mem[s].hh()).b0()) == ligatureNode {
  19370. if int32(*(*prg.mem[int32(s)+1].hh()).b0()) != int32(prg.hf) {
  19371. goto done3
  19372. }
  19373. j = prg.hn
  19374. q = *(*prg.mem[int32(s)+1].hh()).rh()
  19375. if int32(q) > 0 {
  19376. prg.hyfBchar = uint16(*(*prg.mem[q].hh()).b1())
  19377. }
  19378. for int32(q) > 0 {
  19379. c = byte(int32(*(*prg.mem[q].hh()).b1()) - minQuarterword)
  19380. if int32(*(*prg.eqtb[lcCodeBase+int32(c)-1].hh()).rh()) == 0 {
  19381. goto done3
  19382. }
  19383. if int32(j) == 63 {
  19384. goto done3
  19385. }
  19386. j = byte(int32(j) + 1)
  19387. prg.hu[j] = uint16(c)
  19388. prg.hc[j] = *(*prg.eqtb[lcCodeBase+int32(c)-1].hh()).rh()
  19389. q = *(*prg.mem[q].hh()).rh()
  19390. }
  19391. prg.hb = s
  19392. prg.hn = j
  19393. if *(*prg.mem[s].hh()).b1()&1 != 0 {
  19394. prg.hyfBchar = prg.fontBchar[prg.hf]
  19395. } else {
  19396. prg.hyfBchar = uint16(256 + minQuarterword)
  19397. }
  19398. } else if int32(*(*prg.mem[s].hh()).b0()) == kernNode && int32(*(*prg.mem[s].hh()).b1()) == normal {
  19399. prg.hb = s
  19400. prg.hyfBchar = prg.fontBchar[prg.hf]
  19401. } else {
  19402. goto done3
  19403. }
  19404. s = *(*prg.mem[s].hh()).rh()
  19405. }
  19406. done3:
  19407. ;
  19408. // Check that the nodes following |hb| permit hyphenation and that at least |l_hyf+r_hyf| letters have been found, otherwise |goto done1|
  19409. if int32(prg.hn) < prg.lHyf+prg.rHyf {
  19410. goto done1
  19411. } // |l_hyf| and |r_hyf| are |>=1|
  19412. for true {
  19413. if !(int32(s) >= int32(prg.hiMemMin)) {
  19414. switch *(*prg.mem[s].hh()).b0() {
  19415. case ligatureNode:
  19416. case kernNode:
  19417. if int32(*(*prg.mem[s].hh()).b1()) != normal {
  19418. goto done4
  19419. }
  19420. case whatsitNode, glueNode, penaltyNode, insNode,
  19421. adjustNode, markNode:
  19422. goto done4
  19423. default:
  19424. goto done1
  19425. }
  19426. }
  19427. s = *(*prg.mem[s].hh()).rh()
  19428. }
  19429. done4:
  19430. ;
  19431. prg.hyphenate()
  19432. }
  19433. done1:
  19434. }
  19435. case kernNode:
  19436. if int32(*(*prg.mem[prg.curP].hh()).b1()) == explicit {
  19437. if !(int32(*(*prg.mem[prg.curP].hh()).rh()) >= int32(prg.hiMemMin)) && autoBreaking {
  19438. if int32(*(*prg.mem[*(*prg.mem[prg.curP].hh()).rh()].hh()).b0()) == glueNode {
  19439. prg.tryBreak(0, smallNumber(unhyphenated))
  19440. }
  19441. }
  19442. prg.activeWidth[1-1] = prg.activeWidth[1-1] + *prg.mem[int32(prg.curP)+widthOffset].int()
  19443. } else {
  19444. prg.activeWidth[1-1] = prg.activeWidth[1-1] + *prg.mem[int32(prg.curP)+widthOffset].int()
  19445. }
  19446. case ligatureNode:
  19447. f = *(*prg.mem[int32(prg.curP)+1].hh()).b0()
  19448. prg.activeWidth[1-1] = prg.activeWidth[1-1] + *prg.fontInfo[prg.widthBase[f]+int32((*prg.fontInfo[prg.charBase[f]+int32(*(*prg.mem[int32(prg.curP)+1].hh()).b1())].qqqq()).b0)].int()
  19449. case discNode:
  19450. // Try to break after a discretionary fragment, then |goto done5|
  19451. s = *(*prg.mem[int32(prg.curP)+1].hh()).lh()
  19452. prg.discWidth = 0
  19453. if int32(s) == 0 {
  19454. prg.tryBreak(*prg.eqtb[intBase+exHyphenPenaltyCode-1].int(), smallNumber(hyphenated))
  19455. } else {
  19456. for {
  19457. // Add the width of node |s| to |disc_width|
  19458. if int32(s) >= int32(prg.hiMemMin) {
  19459. f = *(*prg.mem[s].hh()).b0()
  19460. prg.discWidth = prg.discWidth + *prg.fontInfo[prg.widthBase[f]+int32((*prg.fontInfo[prg.charBase[f]+int32(*(*prg.mem[s].hh()).b1())].qqqq()).b0)].int()
  19461. } else {
  19462. switch *(*prg.mem[s].hh()).b0() {
  19463. case ligatureNode:
  19464. f = *(*prg.mem[int32(s)+1].hh()).b0()
  19465. prg.discWidth = prg.discWidth + *prg.fontInfo[prg.widthBase[f]+int32((*prg.fontInfo[prg.charBase[f]+int32(*(*prg.mem[int32(s)+1].hh()).b1())].qqqq()).b0)].int()
  19466. case hlistNode, vlistNode, ruleNode, kernNode:
  19467. prg.discWidth = prg.discWidth + *prg.mem[int32(s)+widthOffset].int()
  19468. default:
  19469. prg.confusion(strNumber( /* "disc3" */ 937))
  19470. // \xref[this can't happen disc3][\quad disc3]
  19471. }
  19472. }
  19473. s = *(*prg.mem[s].hh()).rh()
  19474. if int32(s) == 0 {
  19475. break
  19476. }
  19477. }
  19478. prg.activeWidth[1-1] = prg.activeWidth[1-1] + prg.discWidth
  19479. prg.tryBreak(*prg.eqtb[intBase+hyphenPenaltyCode-1].int(), smallNumber(hyphenated))
  19480. prg.activeWidth[1-1] = prg.activeWidth[1-1] - prg.discWidth
  19481. }
  19482. r1 = uint16(*(*prg.mem[prg.curP].hh()).b1())
  19483. s = *(*prg.mem[prg.curP].hh()).rh()
  19484. for int32(r1) > 0 {
  19485. if int32(s) >= int32(prg.hiMemMin) {
  19486. f = *(*prg.mem[s].hh()).b0()
  19487. prg.activeWidth[1-1] = prg.activeWidth[1-1] + *prg.fontInfo[prg.widthBase[f]+int32((*prg.fontInfo[prg.charBase[f]+int32(*(*prg.mem[s].hh()).b1())].qqqq()).b0)].int()
  19488. } else {
  19489. switch *(*prg.mem[s].hh()).b0() {
  19490. case ligatureNode:
  19491. f = *(*prg.mem[int32(s)+1].hh()).b0()
  19492. prg.activeWidth[1-1] = prg.activeWidth[1-1] + *prg.fontInfo[prg.widthBase[f]+int32((*prg.fontInfo[prg.charBase[f]+int32(*(*prg.mem[int32(s)+1].hh()).b1())].qqqq()).b0)].int()
  19493. case hlistNode, vlistNode, ruleNode, kernNode:
  19494. prg.activeWidth[1-1] = prg.activeWidth[1-1] + *prg.mem[int32(s)+widthOffset].int()
  19495. default:
  19496. prg.confusion(strNumber( /* "disc4" */ 938))
  19497. // \xref[this can't happen disc4][\quad disc4]
  19498. }
  19499. }
  19500. r1 = uint16(int32(r1) - 1)
  19501. s = *(*prg.mem[s].hh()).rh()
  19502. }
  19503. prevP = prg.curP
  19504. prg.curP = s
  19505. goto done5
  19506. case mathNode:
  19507. autoBreaking = int32(*(*prg.mem[prg.curP].hh()).b1()) == after
  19508. {
  19509. if !(int32(*(*prg.mem[prg.curP].hh()).rh()) >= int32(prg.hiMemMin)) && autoBreaking {
  19510. if int32(*(*prg.mem[*(*prg.mem[prg.curP].hh()).rh()].hh()).b0()) == glueNode {
  19511. prg.tryBreak(0, smallNumber(unhyphenated))
  19512. }
  19513. }
  19514. prg.activeWidth[1-1] = prg.activeWidth[1-1] + *prg.mem[int32(prg.curP)+widthOffset].int()
  19515. }
  19516. case penaltyNode:
  19517. prg.tryBreak(*prg.mem[int32(prg.curP)+1].int(), smallNumber(unhyphenated))
  19518. case markNode, insNode, adjustNode:
  19519. default:
  19520. prg.confusion(strNumber( /* "paragraph" */ 936))
  19521. // \xref[this can't happen paragraph][\quad paragraph]
  19522. }
  19523. prevP = prg.curP
  19524. prg.curP = *(*prg.mem[prg.curP].hh()).rh()
  19525. done5:
  19526. }
  19527. if int32(prg.curP) == 0 {
  19528. prg.tryBreak(ejectPenalty, smallNumber(hyphenated))
  19529. if int32(*(*prg.mem[30000-7].hh()).rh()) != 30000-7 {
  19530. r1 = *(*prg.mem[30000-7].hh()).rh()
  19531. prg.fewestDemerits = 07777777777
  19532. for {
  19533. if int32(*(*prg.mem[r1].hh()).b0()) != deltaNode {
  19534. if *prg.mem[int32(r1)+2].int() < prg.fewestDemerits {
  19535. prg.fewestDemerits = *prg.mem[int32(r1)+2].int()
  19536. prg.bestBet = r1
  19537. }
  19538. }
  19539. r1 = *(*prg.mem[r1].hh()).rh()
  19540. if int32(r1) == 30000-7 {
  19541. break
  19542. }
  19543. }
  19544. prg.bestLine = *(*prg.mem[int32(prg.bestBet)+1].hh()).lh()
  19545. if *prg.eqtb[intBase+loosenessCode-1].int() == 0 {
  19546. goto done
  19547. }
  19548. // Find the best active node for the desired looseness
  19549. {
  19550. r1 = *(*prg.mem[30000-7].hh()).rh()
  19551. prg.actualLooseness = 0
  19552. for {
  19553. if int32(*(*prg.mem[r1].hh()).b0()) != deltaNode {
  19554. prg.lineDiff = int32(*(*prg.mem[int32(r1)+1].hh()).lh()) - int32(prg.bestLine)
  19555. if prg.lineDiff < prg.actualLooseness && *prg.eqtb[intBase+loosenessCode-1].int() <= prg.lineDiff || prg.lineDiff > prg.actualLooseness && *prg.eqtb[intBase+loosenessCode-1].int() >= prg.lineDiff {
  19556. prg.bestBet = r1
  19557. prg.actualLooseness = prg.lineDiff
  19558. prg.fewestDemerits = *prg.mem[int32(r1)+2].int()
  19559. } else if prg.lineDiff == prg.actualLooseness && *prg.mem[int32(r1)+2].int() < prg.fewestDemerits {
  19560. prg.bestBet = r1
  19561. prg.fewestDemerits = *prg.mem[int32(r1)+2].int()
  19562. }
  19563. }
  19564. r1 = *(*prg.mem[r1].hh()).rh()
  19565. if int32(r1) == 30000-7 {
  19566. break
  19567. }
  19568. }
  19569. prg.bestLine = *(*prg.mem[int32(prg.bestBet)+1].hh()).lh()
  19570. }
  19571. if prg.actualLooseness == *prg.eqtb[intBase+loosenessCode-1].int() || prg.finalPass {
  19572. goto done
  19573. }
  19574. }
  19575. }
  19576. // Clean up the memory by removing the break nodes
  19577. q = *(*prg.mem[30000-7].hh()).rh()
  19578. for int32(q) != 30000-7 {
  19579. prg.curP = *(*prg.mem[q].hh()).rh()
  19580. if int32(*(*prg.mem[q].hh()).b0()) == deltaNode {
  19581. prg.freeNode(q, halfword(deltaNodeSize))
  19582. } else {
  19583. prg.freeNode(q, halfword(activeNodeSize))
  19584. }
  19585. q = prg.curP
  19586. }
  19587. q = prg.passive
  19588. for int32(q) != 0 {
  19589. prg.curP = *(*prg.mem[q].hh()).rh()
  19590. prg.freeNode(q, halfword(passiveNodeSize))
  19591. q = prg.curP
  19592. }
  19593. if !prg.secondPass {
  19594. prg.threshold = *prg.eqtb[intBase+toleranceCode-1].int()
  19595. prg.secondPass = true
  19596. prg.finalPass = *prg.eqtb[dimenBase+emergencyStretchCode-1].int() <= 0
  19597. } else {
  19598. prg.background[2-1] = prg.background[2-1] + *prg.eqtb[dimenBase+emergencyStretchCode-1].int()
  19599. prg.finalPass = true
  19600. }
  19601. }
  19602. done:
  19603. ;
  19604. // Break the paragraph at the chosen breakpoints, justify the resulting lines to the correct widths, and append them to the current vertical list
  19605. prg.postLineBreak(finalWidowPenalty)
  19606. // Clean up the memory by removing the break nodes
  19607. q = *(*prg.mem[30000-7].hh()).rh()
  19608. for int32(q) != 30000-7 {
  19609. prg.curP = *(*prg.mem[q].hh()).rh()
  19610. if int32(*(*prg.mem[q].hh()).b0()) == deltaNode {
  19611. prg.freeNode(q, halfword(deltaNodeSize))
  19612. } else {
  19613. prg.freeNode(q, halfword(activeNodeSize))
  19614. }
  19615. q = prg.curP
  19616. }
  19617. q = prg.passive
  19618. for int32(q) != 0 {
  19619. prg.curP = *(*prg.mem[q].hh()).rh()
  19620. prg.freeNode(q, halfword(passiveNodeSize))
  19621. q = prg.curP
  19622. }
  19623. prg.packBeginLine = 0
  19624. }
  19625. // 817.
  19626. // tangle:pos tex.web:16090:1:
  19627. // When looking for optimal line breaks, \TeX\ creates a ``break node'' for
  19628. // each break that is [\sl feasible], in the sense that there is a way to end
  19629. // a line at the given place without requiring any line to stretch more than
  19630. // a given tolerance. A break node is characterized by three things: the position
  19631. // of the break (which is a pointer to a |glue_node|, |math_node|, |penalty_node|,
  19632. // or |disc_node|); the ordinal number of the line that will follow this
  19633. // breakpoint; and the fitness classification of the line that has just
  19634. // ended, i.e., |tight_fit|, |decent_fit|, |loose_fit|, or |very_loose_fit|.
  19635. // 818.
  19636. // tangle:pos tex.web:16107:1:
  19637. // The algorithm essentially determines the best possible way to achieve
  19638. // each feasible combination of position, line, and fitness. Thus, it answers
  19639. // questions like, ``What is the best way to break the opening part of the
  19640. // paragraph so that the fourth line is a tight line ending at such-and-such
  19641. // a place?'' However, the fact that all lines are to be the same length
  19642. // after a certain point makes it possible to regard all sufficiently large
  19643. // line numbers as equivalent, when the looseness parameter is zero, and this
  19644. // makes it possible for the algorithm to save space and time.
  19645. //
  19646. // An ``active node'' and a ``passive node'' are created in |mem| for each
  19647. // feasible breakpoint that needs to be considered. Active nodes are three
  19648. // words long and passive nodes are two words long. We need active nodes only
  19649. // for breakpoints near the place in the paragraph that is currently being
  19650. // examined, so they are recycled within a comparatively short time after
  19651. // they are created.
  19652. // 819.
  19653. // tangle:pos tex.web:16123:1:
  19654. // An active node for a given breakpoint contains six fields:
  19655. //
  19656. // \yskip\hang|link| points to the next node in the list of active nodes; the
  19657. // last active node has |link=last_active|.
  19658. //
  19659. // \yskip\hang|break_node| points to the passive node associated with this
  19660. // breakpoint.
  19661. //
  19662. // \yskip\hang|line_number| is the number of the line that follows this
  19663. // breakpoint.
  19664. //
  19665. // \yskip\hang|fitness| is the fitness classification of the line ending at this
  19666. // breakpoint.
  19667. //
  19668. // \yskip\hang|type| is either |hyphenated| or |unhyphenated|, depending on
  19669. // whether this breakpoint is a |disc_node|.
  19670. //
  19671. // \yskip\hang|total_demerits| is the minimum possible sum of demerits over all
  19672. // lines leading from the beginning of the paragraph to this breakpoint.
  19673. //
  19674. // \yskip\noindent
  19675. // The value of |link(active)| points to the first active node on a linked list
  19676. // of all currently active nodes. This list is in order by |line_number|,
  19677. // except that nodes with |line_number>easy_line| may be in any order relative
  19678. // to each other.
  19679. // 822.
  19680. // tangle:pos tex.web:16193:1:
  19681. // The active list also contains ``delta'' nodes that help the algorithm
  19682. // compute the badness of individual lines. Such nodes appear only between two
  19683. // active nodes, and they have |type=delta_node|. If |p| and |r| are active nodes
  19684. // and if |q| is a delta node between them, so that |link(p)=q| and |link(q)=r|,
  19685. // then |q| tells the space difference between lines in the horizontal list that
  19686. // start after breakpoint |p| and lines that start after breakpoint |r|. In
  19687. // other words, if we know the length of the line that starts after |p| and
  19688. // ends at our current position, then the corresponding length of the line that
  19689. // starts after |r| is obtained by adding the amounts in node~|q|. A delta node
  19690. // contains six scaled numbers, since it must record the net change in glue
  19691. // stretchability with respect to all orders of infinity. The natural width
  19692. // difference appears in |mem[q+1].sc|; the stretch differences in units of
  19693. // pt, fil, fill, and filll appear in |mem[q+2..q+5].sc|; and the shrink difference
  19694. // appears in |mem[q+6].sc|. The |subtype| field of a delta node is not used.
  19695. // 824.
  19696. // tangle:pos tex.web:16234:1:
  19697. // Let's state the principles of the delta nodes more precisely and concisely,
  19698. // so that the following programs will be less obscure. For each legal
  19699. // breakpoint~|p| in the paragraph, we define two quantities $\alpha(p)$ and
  19700. // $\beta(p)$ such that the length of material in a line from breakpoint~|p|
  19701. // to breakpoint~|q| is $\gamma+\beta(q)-\alpha(p)$, for some fixed $\gamma$.
  19702. // Intuitively, $\alpha(p)$ and $\beta(q)$ are the total length of material from
  19703. // the beginning of the paragraph to a point ``after'' a break at |p| and to a
  19704. // point ``before'' a break at |q|; and $\gamma$ is the width of an empty line,
  19705. // namely the length contributed by \.[\\leftskip] and \.[\\rightskip].
  19706. //
  19707. // Suppose, for example, that the paragraph consists entirely of alternating
  19708. // boxes and glue skips; let the boxes have widths $x_1\ldots x_n$ and
  19709. // let the skips have widths $y_1\ldots y_n$, so that the paragraph can be
  19710. // represented by $x_1y_1\ldots x_ny_n$. Let $p_i$ be the legal breakpoint
  19711. // at $y_i$; then $\alpha(p_i)=x_1+y_1+\cdots+x_i+y_i$, and $\beta(p_i)=
  19712. // x_1+y_1+\cdots+x_i$. To check this, note that the length of material from
  19713. // $p_2$ to $p_5$, say, is $\gamma+x_3+y_3+x_4+y_4+x_5=\gamma+\beta(p_5)
  19714. // -\alpha(p_2)$.
  19715. //
  19716. // The quantities $\alpha$, $\beta$, $\gamma$ involve glue stretchability and
  19717. // shrinkability as well as a natural width. If we were to compute $\alpha(p)$
  19718. // and $\beta(p)$ for each |p|, we would need multiple precision arithmetic, and
  19719. // the multiprecise numbers would have to be kept in the active nodes.
  19720. // \TeX\ avoids this problem by working entirely with relative differences
  19721. // or ``deltas.'' Suppose, for example, that the active list contains
  19722. // $a_1\,\delta_1\,a_2\,\delta_2\,a_3$, where the |a|'s are active breakpoints
  19723. // and the $\delta$'s are delta nodes. Then $\delta_1=\alpha(a_1)-\alpha(a_2)$
  19724. // and $\delta_2=\alpha(a_2)-\alpha(a_3)$. If the line breaking algorithm is
  19725. // currently positioned at some other breakpoint |p|, the |active_width| array
  19726. // contains the value $\gamma+\beta(p)-\alpha(a_1)$. If we are scanning through
  19727. // the list of active nodes and considering a tentative line that runs from
  19728. // $a_2$ to~|p|, say, the |cur_active_width| array will contain the value
  19729. // $\gamma+\beta(p)-\alpha(a_2)$. Thus, when we move from $a_2$ to $a_3$,
  19730. // we want to add $\alpha(a_2)-\alpha(a_3)$ to |cur_active_width|; and this
  19731. // is just $\delta_2$, which appears in the active list between $a_2$ and
  19732. // $a_3$. The |background| array contains $\gamma$. The |break_width| array
  19733. // will be used to calculate values of new delta nodes when the active
  19734. // list is being updated.
  19735. // 904.
  19736. // tangle:pos tex.web:17720:1:
  19737. // We must now face the fact that the battle is not over, even though the
  19738. // [\def\![\kern-1pt]%
  19739. // hyphens have been found: The process of reconstituting a word can be nontrivial
  19740. // because ligatures might change when a hyphen is present. [\sl The \TeX book\/]
  19741. // discusses the difficulties of the word ``difficult'', and
  19742. // the discretionary material surrounding a
  19743. // hyphen can be considerably more complex than that. Suppose
  19744. // \.[abcdef] is a word in a font for which the only ligatures are \.[b\!c],
  19745. // \.[c\!d], \.[d\!e], and \.[e\!f]. If this word permits hyphenation
  19746. // between \.b and \.c, the two patterns with and without hyphenation are
  19747. // $\.a\,\.b\,\.-\,\.[c\!d]\,\.[e\!f]$ and $\.a\,\.[b\!c]\,\.[d\!e]\,\.f$.
  19748. // Thus the insertion of a hyphen might cause effects to ripple arbitrarily
  19749. // far into the rest of the word. A further complication arises if additional
  19750. // hyphens appear together with such rippling, e.g., if the word in the
  19751. // example just given could also be hyphenated between \.c and \.d; \TeX\
  19752. // avoids this by simply ignoring the additional hyphens in such weird cases.]
  19753. //
  19754. // Still further complications arise in the presence of ligatures that do not
  19755. // delete the original characters. When punctuation precedes the word being
  19756. // hyphenated, \TeX's method is not perfect under all possible scenarios,
  19757. // because punctuation marks and letters can propagate information back and forth.
  19758. // For example, suppose the original pre-hyphenation pair
  19759. // \.[*a] changes to \.[*y] via a \.[\?=:] ligature, which changes to \.[xy]
  19760. // via a \.[=:\?] ligature; if $p_[a-1]=\.x$ and $p_a=\.y$, the reconstitution
  19761. // procedure isn't smart enough to obtain \.[xy] again. In such cases the
  19762. // font designer should include a ligature that goes from \.[xa] to \.[xy].
  19763. // 919. \[42] Hyphenation
  19764. // tangle:pos tex.web:18072:19:
  19765. // When a word |hc[1..hn]| has been set up to contain a candidate for hyphenation,
  19766. // \TeX\ first looks to see if it is in the user's exception dictionary. If not,
  19767. // hyphens are inserted based on patterns that appear within the given word,
  19768. // using an algorithm due to Frank~M. Liang.
  19769. // \xref[Liang, Franklin Mark]
  19770. //
  19771. // Let's consider Liang's method first, since it is much more interesting than the
  19772. // exception-lookup routine. The algorithm begins by setting |hyf[j]| to zero
  19773. // for all |j|, and invalid characters are inserted into |hc[0]|
  19774. // and |hc[hn+1]| to serve as delimiters. Then a reasonably fast method is
  19775. // used to see which of a given set of patterns occurs in the word
  19776. // |hc[0..(hn+1)]|. Each pattern $p_1\ldots p_k$ of length |k| has an associated
  19777. // sequence of |k+1| numbers $n_0\ldots n_k$; and if the pattern occurs in
  19778. // |hc[(j+1)..(j+k)]|, \TeX\ will set |hyf[j+i]:=max(hyf[j+i],$n_i$)| for
  19779. // |0<=i<=k|. After this has been done for each pattern that occurs, a
  19780. // discretionary hyphen will be inserted between |hc[j]| and |hc[j+1]| when
  19781. // |hyf[j]| is odd, as we have already seen.
  19782. //
  19783. // The set of patterns $p_1\ldots p_k$ and associated numbers $n_0\ldots n_k$
  19784. // depends, of course, on the language whose words are being hyphenated, and
  19785. // on the degree of hyphenation that is desired. A method for finding
  19786. // appropriate |p|'s and |n|'s, from a given dictionary of words and acceptable
  19787. // hyphenations, is discussed in Liang's Ph.D. thesis (Stanford University,
  19788. // 1983); \TeX\ simply starts with the patterns and works from there.
  19789. // 934.
  19790. // tangle:pos tex.web:18253:1:
  19791. // We have now completed the hyphenation routine, so the |line_break| procedure
  19792. // is finished at last. Since the hyphenation exception table is fresh in our
  19793. // minds, it's a good time to deal with the routine that adds new entries to it.
  19794. //
  19795. // When \TeX\ has scanned `\.[\\hyphenation]', it calls on a procedure named
  19796. // |new_hyph_exceptions| to do the right thing.
  19797. func (prg *prg) newHyphExceptions() {
  19798. var (
  19799. n/* 0..64 */ byte // length of current word; not always a |small_number|
  19800. j/* 0..64 */ byte // an index into |hc|
  19801. h hyphPointer // an index into |hyph_word| and |hyph_list|
  19802. k strNumber // an index into |str_start|
  19803. p halfword // head of a list of hyphen positions
  19804. q halfword // used when creating a new node for list |p|
  19805. s, t strNumber // strings being compared or stored
  19806. u, v poolPointer // indices into |str_pool|
  19807. )
  19808. prg.scanLeftBrace() // a left brace must follow \.[\\hyphenation]
  19809. if *prg.eqtb[intBase+languageCode-1].int() <= 0 {
  19810. prg.curLang = 0
  19811. } else if *prg.eqtb[intBase+languageCode-1].int() > 255 {
  19812. prg.curLang = 0
  19813. } else {
  19814. prg.curLang = byte(*prg.eqtb[intBase+languageCode-1].int())
  19815. }
  19816. // Enter as many hyphenation exceptions as are listed, until coming to a right brace; then |return|
  19817. n = 0
  19818. p = 0
  19819. for true {
  19820. prg.getXToken()
  19821. reswitch:
  19822. switch prg.curCmd {
  19823. case letter, otherChar, charGiven:
  19824. // Append a new letter or hyphen
  19825. if int32(prg.curChr) == '-' {
  19826. if int32(n) < 63 {
  19827. q = prg.getAvail()
  19828. *(*prg.mem[q].hh()).rh() = p
  19829. *(*prg.mem[q].hh()).lh() = uint16(n)
  19830. p = q
  19831. }
  19832. } else {
  19833. if int32(*(*prg.eqtb[lcCodeBase+int32(prg.curChr)-1].hh()).rh()) == 0 {
  19834. {
  19835. if int32(prg.interaction) == errorStopMode {
  19836. }
  19837. prg.printNl(strNumber( /* "! " */ 262))
  19838. prg.print( /* "Not a letter" */ 945)
  19839. }
  19840. // \xref[Not a letter]
  19841. {
  19842. prg.helpPtr = 2
  19843. prg.helpLine[1] = /* "Letters in \\hyphenation words must have \\lccode>0." */ 946
  19844. prg.helpLine[0] = /* "Proceed; I'll ignore the character I just read." */ 947
  19845. }
  19846. prg.error1()
  19847. } else if int32(n) < 63 {
  19848. n = byte(int32(n) + 1)
  19849. prg.hc[n] = *(*prg.eqtb[lcCodeBase+int32(prg.curChr)-1].hh()).rh()
  19850. }
  19851. }
  19852. case charNum:
  19853. prg.scanCharNum()
  19854. prg.curChr = uint16(prg.curVal)
  19855. prg.curCmd = byte(charGiven)
  19856. goto reswitch
  19857. case spacer, rightBrace:
  19858. if int32(n) > 1 {
  19859. n = byte(int32(n) + 1)
  19860. prg.hc[n] = uint16(prg.curLang)
  19861. {
  19862. if int32(prg.poolPtr)+int32(n) > poolSize {
  19863. prg.overflow(strNumber( /* "pool size" */ 257), poolSize-int32(prg.initPoolPtr))
  19864. } /* \xref[TeX capacity exceeded pool size][\quad pool size] */
  19865. }
  19866. h = 0
  19867. for ii := int32(1); ii <= int32(n); ii++ {
  19868. j = byte(ii)
  19869. _ = j
  19870. h = uint16((int32(h) + int32(h) + int32(prg.hc[j])) % hyphSize)
  19871. {
  19872. prg.strPool[prg.poolPtr] = byte(prg.hc[j])
  19873. prg.poolPtr = uint16(int32(prg.poolPtr) + 1)
  19874. }
  19875. }
  19876. s = prg.makeString()
  19877. // Insert the \(p)pair |(s,p)| into the exception table
  19878. if int32(prg.hyphCount) == hyphSize {
  19879. prg.overflow(strNumber( /* "exception dictionary" */ 948), hyphSize)
  19880. }
  19881. // \xref[TeX capacity exceeded exception dictionary][\quad exception dictionary]
  19882. prg.hyphCount = uint16(int32(prg.hyphCount) + 1)
  19883. for int32(prg.hyphWord[h]) != 0 {
  19884. k = prg.hyphWord[h]
  19885. if int32(prg.strStart[int32(k)+1])-int32(prg.strStart[k]) < int32(prg.strStart[int32(s)+1])-int32(prg.strStart[s]) {
  19886. goto found
  19887. }
  19888. if int32(prg.strStart[int32(k)+1])-int32(prg.strStart[k]) > int32(prg.strStart[int32(s)+1])-int32(prg.strStart[s]) {
  19889. goto notFound
  19890. }
  19891. u = prg.strStart[k]
  19892. v = prg.strStart[s]
  19893. for {
  19894. if int32(prg.strPool[u]) < int32(prg.strPool[v]) {
  19895. goto found
  19896. }
  19897. if int32(prg.strPool[u]) > int32(prg.strPool[v]) {
  19898. goto notFound
  19899. }
  19900. u = uint16(int32(u) + 1)
  19901. v = uint16(int32(v) + 1)
  19902. if int32(u) == int32(prg.strStart[int32(k)+1]) {
  19903. break
  19904. }
  19905. }
  19906. found:
  19907. q = prg.hyphList[h]
  19908. prg.hyphList[h] = p
  19909. p = q
  19910. t = prg.hyphWord[h]
  19911. prg.hyphWord[h] = s
  19912. s = t
  19913. notFound:
  19914. ;
  19915. if int32(h) > 0 {
  19916. h = uint16(int32(h) - 1)
  19917. } else {
  19918. h = uint16(hyphSize)
  19919. }
  19920. }
  19921. prg.hyphWord[h] = s
  19922. prg.hyphList[h] = p
  19923. }
  19924. if int32(prg.curCmd) == rightBrace {
  19925. goto exit
  19926. }
  19927. n = 0
  19928. p = 0
  19929. default:
  19930. {
  19931. if int32(prg.interaction) == errorStopMode {
  19932. }
  19933. prg.printNl(strNumber( /* "! " */ 262))
  19934. prg.print( /* "Improper " */ 680)
  19935. }
  19936. prg.printEsc(strNumber( /* "hyphenation" */ 941))
  19937. // \xref[Improper \\hyphenation...]
  19938. prg.print( /* " will be flushed" */ 942)
  19939. {
  19940. prg.helpPtr = 2
  19941. prg.helpLine[1] = /* "Hyphenation exceptions must contain only letters" */ 943
  19942. prg.helpLine[0] = /* "and hyphens. But continue; I'll forgive and forget." */ 944
  19943. }
  19944. prg.error1()
  19945. }
  19946. }
  19947. exit:
  19948. }
  19949. // 967. \[44] Breaking vertical lists into pages
  19950. // tangle:pos tex.web:18850:42:
  19951. // The |vsplit| procedure, which implements \TeX's \.[\\vsplit] operation,
  19952. // is considerably simpler than |line_break| because it doesn't have to
  19953. // worry about hyphenation, and because its mission is to discover a single
  19954. // break instead of an optimum sequence of breakpoints. But before we get
  19955. // into the details of |vsplit|, we need to consider a few more basic things.
  19956. // 968.
  19957. // tangle:pos tex.web:18856:1:
  19958. // A subroutine called |prune_page_top| takes a pointer to a vlist and
  19959. // returns a pointer to a modified vlist in which all glue, kern, and penalty nodes
  19960. // have been deleted before the first box or rule node. However, the first
  19961. // box or rule is actually preceded by a newly created glue node designed so that
  19962. // the topmost baseline will be at distance |split_top_skip| from the top,
  19963. // whenever this is possible without backspacing.
  19964. //
  19965. // In this routine and those that follow, we make use of the fact that a
  19966. // vertical list contains no character nodes, hence the |type| field exists
  19967. // for each node in the list.
  19968. // \xref[data structure assumptions]
  19969. func (prg *prg) prunePageTop(p halfword) (r halfword) { // adjust top after page break
  19970. var (
  19971. prevP halfword // lags one step behind |p|
  19972. q halfword // temporary variable for list manipulation
  19973. )
  19974. prevP = uint16(30000 - 3)
  19975. *(*prg.mem[30000-3].hh()).rh() = p
  19976. for int32(p) != 0 {
  19977. switch *(*prg.mem[p].hh()).b0() {
  19978. case hlistNode, vlistNode, ruleNode:
  19979. // Insert glue for |split_top_skip| and set~|p:=null|
  19980. q = prg.newSkipParam(smallNumber(splitTopSkipCode))
  19981. *(*prg.mem[prevP].hh()).rh() = q
  19982. *(*prg.mem[q].hh()).rh() = p
  19983. // now |temp_ptr=glue_ptr(q)|
  19984. if *prg.mem[int32(prg.tempPtr)+widthOffset].int() > *prg.mem[int32(p)+heightOffset].int() {
  19985. *prg.mem[int32(prg.tempPtr)+widthOffset].int() = *prg.mem[int32(prg.tempPtr)+widthOffset].int() - *prg.mem[int32(p)+heightOffset].int()
  19986. } else {
  19987. *prg.mem[int32(prg.tempPtr)+widthOffset].int() = 0
  19988. }
  19989. p = 0
  19990. case whatsitNode, markNode, insNode:
  19991. prevP = p
  19992. p = *(*prg.mem[prevP].hh()).rh()
  19993. case glueNode, kernNode, penaltyNode:
  19994. q = p
  19995. p = *(*prg.mem[q].hh()).rh()
  19996. *(*prg.mem[q].hh()).rh() = 0
  19997. *(*prg.mem[prevP].hh()).rh() = p
  19998. prg.flushNodeList(q)
  19999. default:
  20000. prg.confusion(strNumber( /* "pruning" */ 959))
  20001. // \xref[this can't happen pruning][\quad pruning]
  20002. }
  20003. }
  20004. r = *(*prg.mem[30000-3].hh()).rh()
  20005. return r
  20006. }
  20007. // 970.
  20008. // tangle:pos tex.web:18895:1:
  20009. // The next subroutine finds the best place to break a given vertical list
  20010. // so as to obtain a box of height~|h|, with maximum depth~|d|.
  20011. // A pointer to the beginning of the vertical list is given,
  20012. // and a pointer to the optimum breakpoint is returned. The list is effectively
  20013. // followed by a forced break, i.e., a penalty node with the |eject_penalty|;
  20014. // if the best break occurs at this artificial node, the value |null| is returned.
  20015. //
  20016. // An array of six |scaled| distances is used to keep track of the height
  20017. // from the beginning of the list to the current place, just as in |line_break|.
  20018. // In fact, we use one of the same arrays, only changing its name to reflect
  20019. // its new significance.
  20020. func (prg *prg) vertBreak(p halfword, h, d scaled) (r halfword) {
  20021. var (
  20022. prevP halfword // if |p| is a glue node, |type(prev_p)| determines
  20023. // whether |p| is a legal breakpoint
  20024. q, r1 halfword // glue specifications
  20025. pi int32 // penalty value
  20026. b int32 // badness at a trial breakpoint
  20027. leastCost int32 // the smallest badness plus penalties found so far
  20028. bestPlace halfword // the most recent break that leads to |least_cost|
  20029. prevDp scaled // depth of previous box in the list
  20030. t smallNumber // |type| of the node following a kern
  20031. )
  20032. prevP = p // an initial glue node is not a legal breakpoint
  20033. leastCost = 07777777777
  20034. prg.activeWidth[1-1] = 0
  20035. prg.activeWidth[2-1] = 0
  20036. prg.activeWidth[3-1] = 0
  20037. prg.activeWidth[4-1] = 0
  20038. prg.activeWidth[5-1] = 0
  20039. prg.activeWidth[6-1] = 0
  20040. prevDp = 0
  20041. for true {
  20042. if int32(p) == 0 {
  20043. pi = ejectPenalty
  20044. } else {
  20045. // Use node |p| to update the current height and depth measurements; if this node is not a legal breakpoint, |goto not_found| or |update_heights|, otherwise set |pi| to the associated penalty at the break
  20046. switch *(*prg.mem[p].hh()).b0() {
  20047. case hlistNode, vlistNode, ruleNode:
  20048. prg.activeWidth[1-1] = prg.activeWidth[1-1] + prevDp + *prg.mem[int32(p)+heightOffset].int()
  20049. prevDp = *prg.mem[int32(p)+depthOffset].int()
  20050. goto notFound
  20051. case whatsitNode:
  20052. // Process whatsit |p| in |vert_break| loop, |goto not_found|
  20053. // Process whatsit |p| in |vert_break| loop, |goto not_found|
  20054. goto notFound
  20055. case glueNode:
  20056. if int32(*(*prg.mem[prevP].hh()).b0()) < mathNode {
  20057. pi = 0
  20058. } else {
  20059. goto updateHeights
  20060. }
  20061. case kernNode:
  20062. if int32(*(*prg.mem[p].hh()).rh()) == 0 {
  20063. t = byte(penaltyNode)
  20064. } else {
  20065. t = *(*prg.mem[*(*prg.mem[p].hh()).rh()].hh()).b0()
  20066. }
  20067. if int32(t) == glueNode {
  20068. pi = 0
  20069. } else {
  20070. goto updateHeights
  20071. }
  20072. case penaltyNode:
  20073. pi = *prg.mem[int32(p)+1].int()
  20074. case markNode, insNode:
  20075. goto notFound
  20076. default:
  20077. prg.confusion(strNumber( /* "vertbreak" */ 960))
  20078. // \xref[this can't happen vertbreak][\quad vertbreak]
  20079. }
  20080. }
  20081. // Check if node |p| is a new champion breakpoint; then \(go)|goto done| if |p| is a forced break or if the page-so-far is already too full
  20082. if pi < infPenalty {
  20083. if prg.activeWidth[1-1] < h {
  20084. if prg.activeWidth[3-1] != 0 || prg.activeWidth[4-1] != 0 || prg.activeWidth[5-1] != 0 {
  20085. b = 0
  20086. } else {
  20087. b = int32(prg.badness(h-prg.activeWidth[1-1], prg.activeWidth[2-1]))
  20088. }
  20089. } else if prg.activeWidth[1-1]-h > prg.activeWidth[6-1] {
  20090. b = 07777777777
  20091. } else {
  20092. b = int32(prg.badness(prg.activeWidth[1-1]-h, prg.activeWidth[6-1]))
  20093. }
  20094. if b < 07777777777 {
  20095. if pi <= ejectPenalty {
  20096. b = pi
  20097. } else if b < infBad {
  20098. b = b + pi
  20099. } else {
  20100. b = 100000
  20101. }
  20102. }
  20103. if b <= leastCost {
  20104. bestPlace = p
  20105. leastCost = b
  20106. prg.bestHeightPlusDepth = prg.activeWidth[1-1] + prevDp
  20107. }
  20108. if b == 07777777777 || pi <= ejectPenalty {
  20109. goto done
  20110. }
  20111. }
  20112. if int32(*(*prg.mem[p].hh()).b0()) < glueNode || int32(*(*prg.mem[p].hh()).b0()) > kernNode {
  20113. goto notFound
  20114. }
  20115. updateHeights:
  20116. if int32(*(*prg.mem[p].hh()).b0()) == kernNode {
  20117. q = p
  20118. } else {
  20119. q = *(*prg.mem[int32(p)+1].hh()).lh()
  20120. prg.activeWidth[2+int32(*(*prg.mem[q].hh()).b0())-1] = prg.activeWidth[2+int32(*(*prg.mem[q].hh()).b0())-1] + *prg.mem[int32(q)+2].int()
  20121. prg.activeWidth[6-1] = prg.activeWidth[6-1] + *prg.mem[int32(q)+3].int()
  20122. if int32(*(*prg.mem[q].hh()).b1()) != normal && *prg.mem[int32(q)+3].int() != 0 {
  20123. {
  20124. if int32(prg.interaction) == errorStopMode {
  20125. }
  20126. prg.printNl(strNumber( /* "! " */ 262))
  20127. prg.print( /* "Infinite glue shrinkage found in box being split" */ 961)
  20128. }
  20129. // \xref[Infinite glue shrinkage...]
  20130. {
  20131. prg.helpPtr = 4
  20132. prg.helpLine[3] = /* "The box you are \\vsplitting contains some infinitely" */ 962
  20133. prg.helpLine[2] = /* "shrinkable glue, e.g., `\\vss' or `\\vskip 0pt minus 1fil'." */ 963
  20134. prg.helpLine[1] = /* "Such glue doesn't belong there; but you can safely proceed," */ 964
  20135. prg.helpLine[0] = /* "since the offensive shrinkability has been made finite." */ 922
  20136. }
  20137. prg.error1()
  20138. r1 = prg.newSpec(q)
  20139. *(*prg.mem[r1].hh()).b1() = byte(normal)
  20140. prg.deleteGlueRef(q)
  20141. *(*prg.mem[int32(p)+1].hh()).lh() = r1
  20142. q = r1
  20143. }
  20144. }
  20145. prg.activeWidth[1-1] = prg.activeWidth[1-1] + prevDp + *prg.mem[int32(q)+widthOffset].int()
  20146. prevDp = 0
  20147. notFound:
  20148. if prevDp > d {
  20149. prg.activeWidth[1-1] = prg.activeWidth[1-1] + prevDp - d
  20150. prevDp = d
  20151. }
  20152. prevP = p
  20153. p = *(*prg.mem[prevP].hh()).rh()
  20154. }
  20155. done:
  20156. r = bestPlace
  20157. return r
  20158. }
  20159. // 977.
  20160. // tangle:pos tex.web:19031:1:
  20161. // Now we are ready to consider |vsplit| itself. Most of
  20162. // its work is accomplished by the two subroutines that we have just considered.
  20163. //
  20164. // Given the number of a vlist box |n|, and given a desired page height |h|,
  20165. // the |vsplit| function finds the best initial segment of the vlist and
  20166. // returns a box for a page of height~|h|. The remainder of the vlist, if
  20167. // any, replaces the original box, after removing glue and penalties and
  20168. // adjusting for |split_top_skip|. Mark nodes in the split-off box are used to
  20169. // set the values of |split_first_mark| and |split_bot_mark|; we use the
  20170. // fact that |split_first_mark=null| if and only if |split_bot_mark=null|.
  20171. //
  20172. // The original box becomes “void” if and only if it has been entirely
  20173. // extracted. The extracted box is “void” if and only if the original
  20174. // box was void (or if it was, erroneously, an hlist box).
  20175. func (prg *prg) vsplit(n eightBits, h scaled) (r halfword) {
  20176. var (
  20177. v halfword // the box to be split
  20178. p halfword // runs through the vlist
  20179. q halfword // points to where the break occurs
  20180. )
  20181. v = *(*prg.eqtb[boxBase+int32(n)-1].hh()).rh()
  20182. if int32(prg.curMark[splitFirstMarkCode]) != 0 {
  20183. prg.deleteTokenRef(prg.curMark[splitFirstMarkCode])
  20184. prg.curMark[splitFirstMarkCode] = 0
  20185. prg.deleteTokenRef(prg.curMark[splitBotMarkCode])
  20186. prg.curMark[splitBotMarkCode] = 0
  20187. }
  20188. // Dispense with trivial cases of void or bad boxes
  20189. if int32(v) == 0 {
  20190. r = 0
  20191. goto exit
  20192. }
  20193. if int32(*(*prg.mem[v].hh()).b0()) != vlistNode {
  20194. {
  20195. if int32(prg.interaction) == errorStopMode {
  20196. }
  20197. prg.printNl(strNumber( /* "! " */ 262))
  20198. prg.print( /* "" */ 338)
  20199. }
  20200. prg.printEsc(strNumber( /* "vsplit" */ 965))
  20201. prg.print( /* " needs a " */ 966)
  20202. prg.printEsc(strNumber( /* "vbox" */ 967))
  20203. // \xref[vsplit_][\.[\\vsplit needs a \\vbox]]
  20204. {
  20205. prg.helpPtr = 2
  20206. prg.helpLine[1] = /* "The box you are trying to split is an \\hbox." */ 968
  20207. prg.helpLine[0] = /* "I can't split such a box, so I'll leave it alone." */ 969
  20208. }
  20209. prg.error1()
  20210. r = 0
  20211. goto exit
  20212. }
  20213. q = prg.vertBreak(*(*prg.mem[int32(v)+listOffset].hh()).rh(), h, *prg.eqtb[dimenBase+splitMaxDepthCode-1].int())
  20214. // Look at all the marks in nodes before the break, and set the final link to |null| at the break
  20215. p = *(*prg.mem[int32(v)+listOffset].hh()).rh()
  20216. if int32(p) == int32(q) {
  20217. *(*prg.mem[int32(v)+listOffset].hh()).rh() = 0
  20218. } else {
  20219. for true {
  20220. if int32(*(*prg.mem[p].hh()).b0()) == markNode {
  20221. if int32(prg.curMark[splitFirstMarkCode]) == 0 {
  20222. prg.curMark[splitFirstMarkCode] = uint16(*prg.mem[int32(p)+1].int())
  20223. prg.curMark[splitBotMarkCode] = prg.curMark[splitFirstMarkCode]
  20224. *(*prg.mem[prg.curMark[splitFirstMarkCode]].hh()).lh() = uint16(int32(*(*prg.mem[prg.curMark[splitFirstMarkCode]].hh()).lh()) + 2)
  20225. } else {
  20226. prg.deleteTokenRef(prg.curMark[splitBotMarkCode])
  20227. prg.curMark[splitBotMarkCode] = uint16(*prg.mem[int32(p)+1].int())
  20228. *(*prg.mem[prg.curMark[splitBotMarkCode]].hh()).lh() = uint16(int32(*(*prg.mem[prg.curMark[splitBotMarkCode]].hh()).lh()) + 1)
  20229. }
  20230. }
  20231. if int32(*(*prg.mem[p].hh()).rh()) == int32(q) {
  20232. *(*prg.mem[p].hh()).rh() = 0
  20233. goto done
  20234. }
  20235. p = *(*prg.mem[p].hh()).rh()
  20236. }
  20237. }
  20238. done:
  20239. ;
  20240. q = prg.prunePageTop(q)
  20241. p = *(*prg.mem[int32(v)+listOffset].hh()).rh()
  20242. prg.freeNode(v, halfword(boxNodeSize))
  20243. if int32(q) == 0 {
  20244. *(*prg.eqtb[boxBase+int32(n)-1].hh()).rh() = 0
  20245. } else {
  20246. *(*prg.eqtb[boxBase+int32(n)-1].hh()).rh() = prg.vpackage(q, scaled(0), smallNumber(additional), scaled(07777777777))
  20247. }
  20248. r = prg.vpackage(p, h, smallNumber(exactly), *prg.eqtb[dimenBase+splitMaxDepthCode-1].int())
  20249. exit:
  20250. ;
  20251. return r
  20252. }
  20253. // 218.
  20254. // tangle:pos tex.web:4391:3:
  20255. // Here is a procedure that displays what \TeX\ is working on, at all levels.
  20256. func (prg *prg) printTotals() {
  20257. prg.printScaled(prg.pageSoFar[1])
  20258. if prg.pageSoFar[2] != 0 {
  20259. prg.print( /* " plus " */ 312)
  20260. prg.printScaled(prg.pageSoFar[2])
  20261. prg.print( /* "" */ 338)
  20262. }
  20263. if prg.pageSoFar[3] != 0 {
  20264. prg.print( /* " plus " */ 312)
  20265. prg.printScaled(prg.pageSoFar[3])
  20266. prg.print( /* "fil" */ 311)
  20267. }
  20268. if prg.pageSoFar[4] != 0 {
  20269. prg.print( /* " plus " */ 312)
  20270. prg.printScaled(prg.pageSoFar[4])
  20271. prg.print( /* "fill" */ 978)
  20272. }
  20273. if prg.pageSoFar[5] != 0 {
  20274. prg.print( /* " plus " */ 312)
  20275. prg.printScaled(prg.pageSoFar[5])
  20276. prg.print( /* "filll" */ 979)
  20277. }
  20278. if prg.pageSoFar[6] != 0 {
  20279. prg.print( /* " minus " */ 313)
  20280. prg.printScaled(prg.pageSoFar[6])
  20281. }
  20282. }
  20283. // 987.
  20284. // tangle:pos tex.web:19313:1:
  20285. // Here is a procedure that is called when the |page_contents| is changing
  20286. // from |empty| to |inserts_only| or |box_there|.
  20287. func (prg *prg) freezePageSpecs(s smallNumber) {
  20288. prg.pageContents = s
  20289. prg.pageSoFar[0] = *prg.eqtb[dimenBase+vsizeCode-1].int()
  20290. prg.pageMaxDepth = *prg.eqtb[dimenBase+maxDepthCode-1].int()
  20291. prg.pageSoFar[7] = 0
  20292. prg.pageSoFar[1] = 0
  20293. prg.pageSoFar[2] = 0
  20294. prg.pageSoFar[3] = 0
  20295. prg.pageSoFar[4] = 0
  20296. prg.pageSoFar[5] = 0
  20297. prg.pageSoFar[6] = 0
  20298. prg.leastPageCost = 07777777777
  20299. // if eqtb[int_base+ tracing_pages_code].int >0 then
  20300. // begin begin_diagnostic;
  20301. // print_nl(["%% goal height="=]987); print_scaled(page_so_far[0] );
  20302. // [ \xref[goal height] ]
  20303. // print([", max depth="=]988); print_scaled(page_max_depth);
  20304. // end_diagnostic(false);
  20305. // end; [ ]
  20306. }
  20307. // 992.
  20308. // tangle:pos tex.web:19377:1:
  20309. // At certain times box 255 is supposed to be void (i.e., |null|),
  20310. // or an insertion box is supposed to be ready to accept a vertical list.
  20311. // If not, an error message is printed, and the following subroutine
  20312. // flushes the unwanted contents, reporting them to the user.
  20313. func (prg *prg) boxError(n eightBits) {
  20314. prg.error1()
  20315. prg.beginDiagnostic()
  20316. prg.printNl(strNumber( /* "The following box has been deleted:" */ 836))
  20317. // \xref[The following...deleted]
  20318. prg.showBox(*(*prg.eqtb[boxBase+int32(n)-1].hh()).rh())
  20319. prg.endDiagnostic(true)
  20320. prg.flushNodeList(*(*prg.eqtb[boxBase+int32(n)-1].hh()).rh())
  20321. *(*prg.eqtb[boxBase+int32(n)-1].hh()).rh() = 0
  20322. }
  20323. // 993.
  20324. // tangle:pos tex.web:19390:1:
  20325. // The following procedure guarantees that a given box register
  20326. // does not contain an \.[\\hbox].
  20327. func (prg *prg) ensureVbox(n eightBits) {
  20328. var (
  20329. p halfword // the box register contents
  20330. )
  20331. p = *(*prg.eqtb[boxBase+int32(n)-1].hh()).rh()
  20332. if int32(p) != 0 {
  20333. if int32(*(*prg.mem[p].hh()).b0()) == hlistNode {
  20334. {
  20335. if int32(prg.interaction) == errorStopMode {
  20336. }
  20337. prg.printNl(strNumber( /* "! " */ 262))
  20338. prg.print( /* "Insertions can only be added to a vbox" */ 989)
  20339. }
  20340. // \xref[Insertions can only...]
  20341. {
  20342. prg.helpPtr = 3
  20343. prg.helpLine[2] = /* "Tut tut: You're trying to \\insert into a" */ 990
  20344. prg.helpLine[1] = /* "\\box register that now contains an \\hbox." */ 991
  20345. prg.helpLine[0] = /* "Proceed, and I'll discard its present contents." */ 992
  20346. }
  20347. prg.boxError(n)
  20348. }
  20349. }
  20350. }
  20351. // 994.
  20352. // tangle:pos tex.web:19406:1:
  20353. // \TeX\ is not always in vertical mode at the time |build_page|
  20354. // is called; the current mode reflects what \TeX\ should return to, after
  20355. // the contribution list has been emptied. A call on |build_page| should
  20356. // be immediately followed by `|goto big_switch|', which is \TeX's central
  20357. // control point.
  20358. // \4
  20359. // Declare the procedure called |fire_up|
  20360. func (prg *prg) fireUp(c halfword) {
  20361. var (
  20362. p, q, r1, s halfword // nodes being examined and/or changed
  20363. prevP halfword // predecessor of |p|
  20364. n/* minQuarterword..255 */ byte // insertion box number
  20365. wait bool // should the present insertion be held over?
  20366. saveVbadness int32 // saved value of |vbadness|
  20367. saveVfuzz scaled // saved value of |vfuzz|
  20368. saveSplitTopSkip halfword // saved value of |split_top_skip|
  20369. )
  20370. if int32(*(*prg.mem[prg.bestPageBreak].hh()).b0()) == penaltyNode {
  20371. prg.geqWordDefine(halfword(intBase+outputPenaltyCode), *prg.mem[int32(prg.bestPageBreak)+1].int())
  20372. *prg.mem[int32(prg.bestPageBreak)+1].int() = infPenalty
  20373. } else {
  20374. prg.geqWordDefine(halfword(intBase+outputPenaltyCode), infPenalty)
  20375. }
  20376. if int32(prg.curMark[botMarkCode]) != 0 {
  20377. if int32(prg.curMark[topMarkCode]) != 0 {
  20378. prg.deleteTokenRef(prg.curMark[topMarkCode])
  20379. }
  20380. prg.curMark[topMarkCode] = prg.curMark[botMarkCode]
  20381. *(*prg.mem[prg.curMark[topMarkCode]].hh()).lh() = uint16(int32(*(*prg.mem[prg.curMark[topMarkCode]].hh()).lh()) + 1)
  20382. prg.deleteTokenRef(prg.curMark[firstMarkCode])
  20383. prg.curMark[firstMarkCode] = 0
  20384. }
  20385. // Put the \(o)optimal current page into box 255, update |first_mark| and |bot_mark|, append insertions to their boxes, and put the remaining nodes back on the contribution list
  20386. if int32(c) == int32(prg.bestPageBreak) {
  20387. prg.bestPageBreak = 0
  20388. } // |c| not yet linked in
  20389. // Ensure that box 255 is empty before output
  20390. if int32(*(*prg.eqtb[boxBase+255-1].hh()).rh()) != 0 {
  20391. {
  20392. if int32(prg.interaction) == errorStopMode {
  20393. }
  20394. prg.printNl(strNumber( /* "! " */ 262))
  20395. prg.print( /* "" */ 338)
  20396. }
  20397. prg.printEsc(strNumber( /* "box" */ 409))
  20398. prg.print( /* "255 is not void" */ 1003)
  20399. // \xref[box255][\.[\\box255 is not void]]
  20400. {
  20401. prg.helpPtr = 2
  20402. prg.helpLine[1] = /* "You shouldn't use \\box255 except in \\output routines." */ 1004
  20403. prg.helpLine[0] = /* "Proceed, and I'll discard its present contents." */ 992
  20404. }
  20405. prg.boxError(eightBits(255))
  20406. }
  20407. prg.insertPenalties = 0 // this will count the number of insertions held over
  20408. saveSplitTopSkip = *(*prg.eqtb[glueBase+splitTopSkipCode-1].hh()).rh()
  20409. if *prg.eqtb[intBase+holdingInsertsCode-1].int() <= 0 {
  20410. r1 = *(*prg.mem[30000].hh()).rh()
  20411. for int32(r1) != 30000 {
  20412. if int32(*(*prg.mem[int32(r1)+2].hh()).lh()) != 0 {
  20413. n = byte(int32(*(*prg.mem[r1].hh()).b1()) - minQuarterword)
  20414. prg.ensureVbox(n)
  20415. if int32(*(*prg.eqtb[boxBase+int32(n)-1].hh()).rh()) == 0 {
  20416. *(*prg.eqtb[boxBase+int32(n)-1].hh()).rh() = prg.newNullBox()
  20417. }
  20418. p = uint16(int32(*(*prg.eqtb[boxBase+int32(n)-1].hh()).rh()) + listOffset)
  20419. for int32(*(*prg.mem[p].hh()).rh()) != 0 {
  20420. p = *(*prg.mem[p].hh()).rh()
  20421. }
  20422. *(*prg.mem[int32(r1)+2].hh()).rh() = p
  20423. }
  20424. r1 = *(*prg.mem[r1].hh()).rh()
  20425. }
  20426. }
  20427. q = uint16(30000 - 4)
  20428. *(*prg.mem[q].hh()).rh() = 0
  20429. prevP = uint16(30000 - 2)
  20430. p = *(*prg.mem[prevP].hh()).rh()
  20431. for int32(p) != int32(prg.bestPageBreak) {
  20432. if int32(*(*prg.mem[p].hh()).b0()) == insNode {
  20433. if *prg.eqtb[intBase+holdingInsertsCode-1].int() <= 0 {
  20434. r1 = *(*prg.mem[30000].hh()).rh()
  20435. for int32(*(*prg.mem[r1].hh()).b1()) != int32(*(*prg.mem[p].hh()).b1()) {
  20436. r1 = *(*prg.mem[r1].hh()).rh()
  20437. }
  20438. if int32(*(*prg.mem[int32(r1)+2].hh()).lh()) == 0 {
  20439. wait = true
  20440. } else {
  20441. wait = false
  20442. s = *(*prg.mem[int32(r1)+2].hh()).rh()
  20443. *(*prg.mem[s].hh()).rh() = *(*prg.mem[int32(p)+4].hh()).lh()
  20444. if int32(*(*prg.mem[int32(r1)+2].hh()).lh()) == int32(p) {
  20445. if int32(*(*prg.mem[r1].hh()).b0()) == splitUp {
  20446. if int32(*(*prg.mem[int32(r1)+1].hh()).lh()) == int32(p) && int32(*(*prg.mem[int32(r1)+1].hh()).rh()) != 0 {
  20447. for int32(*(*prg.mem[s].hh()).rh()) != int32(*(*prg.mem[int32(r1)+1].hh()).rh()) {
  20448. s = *(*prg.mem[s].hh()).rh()
  20449. }
  20450. *(*prg.mem[s].hh()).rh() = 0
  20451. *(*prg.eqtb[glueBase+splitTopSkipCode-1].hh()).rh() = *(*prg.mem[int32(p)+4].hh()).rh()
  20452. *(*prg.mem[int32(p)+4].hh()).lh() = prg.prunePageTop(*(*prg.mem[int32(r1)+1].hh()).rh())
  20453. if int32(*(*prg.mem[int32(p)+4].hh()).lh()) != 0 {
  20454. prg.tempPtr = prg.vpackage(*(*prg.mem[int32(p)+4].hh()).lh(), scaled(0), smallNumber(additional), scaled(07777777777))
  20455. *prg.mem[int32(p)+heightOffset].int() = *prg.mem[int32(prg.tempPtr)+heightOffset].int() + *prg.mem[int32(prg.tempPtr)+depthOffset].int()
  20456. prg.freeNode(prg.tempPtr, halfword(boxNodeSize))
  20457. wait = true
  20458. }
  20459. }
  20460. }
  20461. *(*prg.mem[int32(r1)+2].hh()).lh() = 0
  20462. n = byte(int32(*(*prg.mem[r1].hh()).b1()) - minQuarterword)
  20463. prg.tempPtr = *(*prg.mem[int32(*(*prg.eqtb[boxBase+int32(n)-1].hh()).rh())+listOffset].hh()).rh()
  20464. prg.freeNode(*(*prg.eqtb[boxBase+int32(n)-1].hh()).rh(), halfword(boxNodeSize))
  20465. *(*prg.eqtb[boxBase+int32(n)-1].hh()).rh() = prg.vpackage(prg.tempPtr, scaled(0), smallNumber(additional), scaled(07777777777))
  20466. } else {
  20467. for int32(*(*prg.mem[s].hh()).rh()) != 0 {
  20468. s = *(*prg.mem[s].hh()).rh()
  20469. }
  20470. *(*prg.mem[int32(r1)+2].hh()).rh() = s
  20471. }
  20472. }
  20473. // Either append the insertion node |p| after node |q|, and remove it from the current page, or delete |node(p)|
  20474. *(*prg.mem[prevP].hh()).rh() = *(*prg.mem[p].hh()).rh()
  20475. *(*prg.mem[p].hh()).rh() = 0
  20476. if wait {
  20477. *(*prg.mem[q].hh()).rh() = p
  20478. q = p
  20479. prg.insertPenalties = prg.insertPenalties + 1
  20480. } else {
  20481. prg.deleteGlueRef(*(*prg.mem[int32(p)+4].hh()).rh())
  20482. prg.freeNode(p, halfword(insNodeSize))
  20483. }
  20484. p = prevP
  20485. }
  20486. } else if int32(*(*prg.mem[p].hh()).b0()) == markNode {
  20487. if int32(prg.curMark[firstMarkCode]) == 0 {
  20488. prg.curMark[firstMarkCode] = uint16(*prg.mem[int32(p)+1].int())
  20489. *(*prg.mem[prg.curMark[firstMarkCode]].hh()).lh() = uint16(int32(*(*prg.mem[prg.curMark[firstMarkCode]].hh()).lh()) + 1)
  20490. }
  20491. if int32(prg.curMark[botMarkCode]) != 0 {
  20492. prg.deleteTokenRef(prg.curMark[botMarkCode])
  20493. }
  20494. prg.curMark[botMarkCode] = uint16(*prg.mem[int32(p)+1].int())
  20495. *(*prg.mem[prg.curMark[botMarkCode]].hh()).lh() = uint16(int32(*(*prg.mem[prg.curMark[botMarkCode]].hh()).lh()) + 1)
  20496. }
  20497. prevP = p
  20498. p = *(*prg.mem[prevP].hh()).rh()
  20499. }
  20500. *(*prg.eqtb[glueBase+splitTopSkipCode-1].hh()).rh() = saveSplitTopSkip
  20501. // Break the current page at node |p|, put it in box~255, and put the remaining nodes on the contribution list
  20502. if int32(p) != 0 {
  20503. if int32(*(*prg.mem[30000-1].hh()).rh()) == 0 {
  20504. if int32(prg.nestPtr) == 0 {
  20505. prg.curList.tailField = prg.pageTail
  20506. } else {
  20507. prg.nest[0].tailField = prg.pageTail
  20508. }
  20509. }
  20510. *(*prg.mem[prg.pageTail].hh()).rh() = *(*prg.mem[30000-1].hh()).rh()
  20511. *(*prg.mem[30000-1].hh()).rh() = p
  20512. *(*prg.mem[prevP].hh()).rh() = 0
  20513. }
  20514. saveVbadness = *prg.eqtb[intBase+vbadnessCode-1].int()
  20515. *prg.eqtb[intBase+vbadnessCode-1].int() = infBad
  20516. saveVfuzz = *prg.eqtb[dimenBase+vfuzzCode-1].int()
  20517. *prg.eqtb[dimenBase+vfuzzCode-1].int() = 07777777777 // inhibit error messages
  20518. *(*prg.eqtb[boxBase+255-1].hh()).rh() = prg.vpackage(*(*prg.mem[30000-2].hh()).rh(), prg.bestSize, smallNumber(exactly), prg.pageMaxDepth)
  20519. *prg.eqtb[intBase+vbadnessCode-1].int() = saveVbadness
  20520. *prg.eqtb[dimenBase+vfuzzCode-1].int() = saveVfuzz
  20521. if int32(prg.lastGlue) != 65535 {
  20522. prg.deleteGlueRef(prg.lastGlue)
  20523. }
  20524. // Start a new current page
  20525. prg.pageContents = byte(empty)
  20526. prg.pageTail = uint16(30000 - 2)
  20527. *(*prg.mem[30000-2].hh()).rh() = 0
  20528. prg.lastGlue = 65535
  20529. prg.lastPenalty = 0
  20530. prg.lastKern = 0
  20531. prg.pageSoFar[7] = 0
  20532. prg.pageMaxDepth = 0 // this sets |last_glue:=max_halfword|
  20533. if int32(q) != 30000-4 {
  20534. *(*prg.mem[30000-2].hh()).rh() = *(*prg.mem[30000-4].hh()).rh()
  20535. prg.pageTail = q
  20536. }
  20537. // Delete \(t)the page-insertion nodes
  20538. r1 = *(*prg.mem[30000].hh()).rh()
  20539. for int32(r1) != 30000 {
  20540. q = *(*prg.mem[r1].hh()).rh()
  20541. prg.freeNode(r1, halfword(pageInsNodeSize))
  20542. r1 = q
  20543. }
  20544. *(*prg.mem[30000].hh()).rh() = 30000
  20545. if int32(prg.curMark[topMarkCode]) != 0 && int32(prg.curMark[firstMarkCode]) == 0 {
  20546. prg.curMark[firstMarkCode] = prg.curMark[topMarkCode]
  20547. *(*prg.mem[prg.curMark[topMarkCode]].hh()).lh() = uint16(int32(*(*prg.mem[prg.curMark[topMarkCode]].hh()).lh()) + 1)
  20548. }
  20549. if int32(*(*prg.eqtb[outputRoutineLoc-1].hh()).rh()) != 0 {
  20550. if prg.deadCycles >= *prg.eqtb[intBase+maxDeadCyclesCode-1].int() {
  20551. {
  20552. if int32(prg.interaction) == errorStopMode {
  20553. }
  20554. prg.printNl(strNumber( /* "! " */ 262))
  20555. prg.print( /* "Output loop---" */ 1005)
  20556. }
  20557. prg.printInt(prg.deadCycles)
  20558. // \xref[Output loop...]
  20559. prg.print( /* " consecutive dead cycles" */ 1006)
  20560. {
  20561. prg.helpPtr = 3
  20562. prg.helpLine[2] = /* "I've concluded that your \\output is awry; it never does a" */ 1007
  20563. prg.helpLine[1] = /* "\\shipout, so I'm shipping \\box255 out myself. Next time" */ 1008
  20564. prg.helpLine[0] = /* "increase \\maxdeadcycles if you want me to be more patient!" */ 1009
  20565. }
  20566. prg.error1()
  20567. } else {
  20568. // Fire up the user's output routine and |return|
  20569. prg.outputActive = true
  20570. prg.deadCycles = prg.deadCycles + 1
  20571. prg.pushNest()
  20572. prg.curList.modeField = int16(-vmode)
  20573. *prg.curList.auxField.int() = -65536000
  20574. prg.curList.mlField = -prg.line
  20575. prg.beginTokenList(*(*prg.eqtb[outputRoutineLoc-1].hh()).rh(), quarterword(outputText))
  20576. prg.newSaveLevel(groupCode(outputGroup))
  20577. prg.normalParagraph()
  20578. prg.scanLeftBrace()
  20579. goto exit
  20580. }
  20581. }
  20582. // Perform the default output routine
  20583. {
  20584. if int32(*(*prg.mem[30000-2].hh()).rh()) != 0 {
  20585. if int32(*(*prg.mem[30000-1].hh()).rh()) == 0 {
  20586. if int32(prg.nestPtr) == 0 {
  20587. prg.curList.tailField = prg.pageTail
  20588. } else {
  20589. prg.nest[0].tailField = prg.pageTail
  20590. }
  20591. } else {
  20592. *(*prg.mem[prg.pageTail].hh()).rh() = *(*prg.mem[30000-1].hh()).rh()
  20593. }
  20594. *(*prg.mem[30000-1].hh()).rh() = *(*prg.mem[30000-2].hh()).rh()
  20595. *(*prg.mem[30000-2].hh()).rh() = 0
  20596. prg.pageTail = uint16(30000 - 2)
  20597. }
  20598. prg.shipOut(*(*prg.eqtb[boxBase+255-1].hh()).rh())
  20599. *(*prg.eqtb[boxBase+255-1].hh()).rh() = 0
  20600. }
  20601. exit:
  20602. } // \2
  20603. func (prg *prg) buildPage() {
  20604. var (
  20605. p halfword // the node being appended
  20606. q, r1 halfword // nodes being examined
  20607. b, c int32 // badness and cost of current page
  20608. pi int32 // penalty to be added to the badness
  20609. n/* minQuarterword..255 */ byte // insertion box number
  20610. delta, h, w scaled // sizes used for insertion calculations
  20611. )
  20612. if int32(*(*prg.mem[30000-1].hh()).rh()) == 0 || prg.outputActive {
  20613. goto exit
  20614. }
  20615. for {
  20616. continue1:
  20617. p = *(*prg.mem[30000-1].hh()).rh()
  20618. // Update the values of |last_glue|, |last_penalty|, and |last_kern|
  20619. if int32(prg.lastGlue) != 65535 {
  20620. prg.deleteGlueRef(prg.lastGlue)
  20621. }
  20622. prg.lastPenalty = 0
  20623. prg.lastKern = 0
  20624. if int32(*(*prg.mem[p].hh()).b0()) == glueNode {
  20625. prg.lastGlue = *(*prg.mem[int32(p)+1].hh()).lh()
  20626. *(*prg.mem[prg.lastGlue].hh()).rh() = uint16(int32(*(*prg.mem[prg.lastGlue].hh()).rh()) + 1)
  20627. } else {
  20628. prg.lastGlue = 65535
  20629. if int32(*(*prg.mem[p].hh()).b0()) == penaltyNode {
  20630. prg.lastPenalty = *prg.mem[int32(p)+1].int()
  20631. } else if int32(*(*prg.mem[p].hh()).b0()) == kernNode {
  20632. prg.lastKern = *prg.mem[int32(p)+widthOffset].int()
  20633. }
  20634. }
  20635. // Move node |p| to the current page; if it is time for a page break, put the nodes following the break back onto the contribution list, and |return| to the user's output routine if there is one
  20636. // If the current page is empty and node |p| is to be deleted, |goto done1|; otherwise use node |p| to update the state of the current page; if this node is an insertion, |goto contribute|; otherwise if this node is not a legal breakpoint, |goto contribute| or |update_heights|; otherwise set |pi| to the penalty associated with this breakpoint
  20637. switch *(*prg.mem[p].hh()).b0() {
  20638. case hlistNode, vlistNode, ruleNode:
  20639. if int32(prg.pageContents) < boxThere {
  20640. if int32(prg.pageContents) == empty {
  20641. prg.freezePageSpecs(smallNumber(boxThere))
  20642. } else {
  20643. prg.pageContents = byte(boxThere)
  20644. }
  20645. q = prg.newSkipParam(smallNumber(topSkipCode)) // now |temp_ptr=glue_ptr(q)|
  20646. if *prg.mem[int32(prg.tempPtr)+widthOffset].int() > *prg.mem[int32(p)+heightOffset].int() {
  20647. *prg.mem[int32(prg.tempPtr)+widthOffset].int() = *prg.mem[int32(prg.tempPtr)+widthOffset].int() - *prg.mem[int32(p)+heightOffset].int()
  20648. } else {
  20649. *prg.mem[int32(prg.tempPtr)+widthOffset].int() = 0
  20650. }
  20651. *(*prg.mem[q].hh()).rh() = p
  20652. *(*prg.mem[30000-1].hh()).rh() = q
  20653. goto continue1
  20654. } else {
  20655. // Prepare to move a box or rule node to the current page, then |goto contribute|
  20656. prg.pageSoFar[1] = prg.pageSoFar[1] + prg.pageSoFar[7] + *prg.mem[int32(p)+heightOffset].int()
  20657. prg.pageSoFar[7] = *prg.mem[int32(p)+depthOffset].int()
  20658. goto contribute
  20659. }
  20660. case whatsitNode:
  20661. // Prepare to move whatsit |p| to the current page, then |goto contribute|
  20662. // Prepare to move whatsit |p| to the current page, then |goto contribute|
  20663. goto contribute
  20664. case glueNode:
  20665. if int32(prg.pageContents) < boxThere {
  20666. goto done1
  20667. } else if int32(*(*prg.mem[prg.pageTail].hh()).b0()) < mathNode {
  20668. pi = 0
  20669. } else {
  20670. goto updateHeights
  20671. }
  20672. case kernNode:
  20673. if int32(prg.pageContents) < boxThere {
  20674. goto done1
  20675. } else if int32(*(*prg.mem[p].hh()).rh()) == 0 {
  20676. goto exit
  20677. } else if int32(*(*prg.mem[*(*prg.mem[p].hh()).rh()].hh()).b0()) == glueNode {
  20678. pi = 0
  20679. } else {
  20680. goto updateHeights
  20681. }
  20682. case penaltyNode:
  20683. if int32(prg.pageContents) < boxThere {
  20684. goto done1
  20685. } else {
  20686. pi = *prg.mem[int32(p)+1].int()
  20687. }
  20688. case markNode:
  20689. goto contribute
  20690. case insNode:
  20691. // Append an insertion to the current page and |goto contribute|
  20692. if int32(prg.pageContents) == empty {
  20693. prg.freezePageSpecs(smallNumber(insertsOnly))
  20694. }
  20695. n = *(*prg.mem[p].hh()).b1()
  20696. r1 = 30000
  20697. for int32(n) >= int32(*(*prg.mem[*(*prg.mem[r1].hh()).rh()].hh()).b1()) {
  20698. r1 = *(*prg.mem[r1].hh()).rh()
  20699. }
  20700. n = byte(int32(n) - minQuarterword)
  20701. if int32(*(*prg.mem[r1].hh()).b1()) != int32(n)+minQuarterword {
  20702. q = prg.getNode(pageInsNodeSize)
  20703. *(*prg.mem[q].hh()).rh() = *(*prg.mem[r1].hh()).rh()
  20704. *(*prg.mem[r1].hh()).rh() = q
  20705. r1 = q
  20706. *(*prg.mem[r1].hh()).b1() = byte(int32(n) + minQuarterword)
  20707. *(*prg.mem[r1].hh()).b0() = byte(inserting)
  20708. prg.ensureVbox(n)
  20709. if int32(*(*prg.eqtb[boxBase+int32(n)-1].hh()).rh()) == 0 {
  20710. *prg.mem[int32(r1)+heightOffset].int() = 0
  20711. } else {
  20712. *prg.mem[int32(r1)+heightOffset].int() = *prg.mem[int32(*(*prg.eqtb[boxBase+int32(n)-1].hh()).rh())+heightOffset].int() + *prg.mem[int32(*(*prg.eqtb[boxBase+int32(n)-1].hh()).rh())+depthOffset].int()
  20713. }
  20714. *(*prg.mem[int32(r1)+2].hh()).lh() = 0
  20715. q = *(*prg.eqtb[skipBase+int32(n)-1].hh()).rh()
  20716. if *prg.eqtb[countBase+int32(n)-1].int() == 1000 {
  20717. h = *prg.mem[int32(r1)+heightOffset].int()
  20718. } else {
  20719. h = prg.xOverN(*prg.mem[int32(r1)+heightOffset].int(), 1000) * *prg.eqtb[countBase+int32(n)-1].int()
  20720. }
  20721. prg.pageSoFar[0] = prg.pageSoFar[0] - h - *prg.mem[int32(q)+widthOffset].int()
  20722. prg.pageSoFar[2+int32(*(*prg.mem[q].hh()).b0())] = prg.pageSoFar[2+int32(*(*prg.mem[q].hh()).b0())] + *prg.mem[int32(q)+2].int()
  20723. prg.pageSoFar[6] = prg.pageSoFar[6] + *prg.mem[int32(q)+3].int()
  20724. if int32(*(*prg.mem[q].hh()).b1()) != normal && *prg.mem[int32(q)+3].int() != 0 {
  20725. {
  20726. if int32(prg.interaction) == errorStopMode {
  20727. }
  20728. prg.printNl(strNumber( /* "! " */ 262))
  20729. prg.print( /* "Infinite glue shrinkage inserted from " */ 998)
  20730. }
  20731. prg.printEsc(strNumber( /* "skip" */ 395))
  20732. // \xref[Infinite glue shrinkage...]
  20733. prg.printInt(int32(n))
  20734. {
  20735. prg.helpPtr = 3
  20736. prg.helpLine[2] = /* "The correction glue for page breaking with insertions" */ 999
  20737. prg.helpLine[1] = /* "must have finite shrinkability. But you may proceed," */ 1000
  20738. prg.helpLine[0] = /* "since the offensive shrinkability has been made finite." */ 922
  20739. }
  20740. prg.error1()
  20741. }
  20742. }
  20743. if int32(*(*prg.mem[r1].hh()).b0()) == splitUp {
  20744. prg.insertPenalties = prg.insertPenalties + *prg.mem[int32(p)+1].int()
  20745. } else {
  20746. *(*prg.mem[int32(r1)+2].hh()).rh() = p
  20747. delta = prg.pageSoFar[0] - prg.pageSoFar[1] - prg.pageSoFar[7] + prg.pageSoFar[6]
  20748. // this much room is left if we shrink the maximum
  20749. if *prg.eqtb[countBase+int32(n)-1].int() == 1000 {
  20750. h = *prg.mem[int32(p)+heightOffset].int()
  20751. } else {
  20752. h = prg.xOverN(*prg.mem[int32(p)+heightOffset].int(), 1000) * *prg.eqtb[countBase+int32(n)-1].int()
  20753. } // this much room is needed
  20754. if (h <= 0 || h <= delta) && *prg.mem[int32(p)+heightOffset].int()+*prg.mem[int32(r1)+heightOffset].int() <= *prg.eqtb[scaledBase+int32(n)-1].int() {
  20755. prg.pageSoFar[0] = prg.pageSoFar[0] - h
  20756. *prg.mem[int32(r1)+heightOffset].int() = *prg.mem[int32(r1)+heightOffset].int() + *prg.mem[int32(p)+heightOffset].int()
  20757. } else {
  20758. // Find the best way to split the insertion, and change |type(r)| to |split_up|
  20759. if *prg.eqtb[countBase+int32(n)-1].int() <= 0 {
  20760. w = 07777777777
  20761. } else {
  20762. w = prg.pageSoFar[0] - prg.pageSoFar[1] - prg.pageSoFar[7]
  20763. if *prg.eqtb[countBase+int32(n)-1].int() != 1000 {
  20764. w = prg.xOverN(w, *prg.eqtb[countBase+int32(n)-1].int()) * 1000
  20765. }
  20766. }
  20767. if w > *prg.eqtb[scaledBase+int32(n)-1].int()-*prg.mem[int32(r1)+heightOffset].int() {
  20768. w = *prg.eqtb[scaledBase+int32(n)-1].int() - *prg.mem[int32(r1)+heightOffset].int()
  20769. }
  20770. q = prg.vertBreak(*(*prg.mem[int32(p)+4].hh()).lh(), w, *prg.mem[int32(p)+depthOffset].int())
  20771. *prg.mem[int32(r1)+heightOffset].int() = *prg.mem[int32(r1)+heightOffset].int() + prg.bestHeightPlusDepth
  20772. // if eqtb[int_base+ tracing_pages_code].int >0 then
  20773. // [ Display the insertion split cost ]
  20774. // begin begin_diagnostic; print_nl(["% split"=]1001); print_int(n);
  20775. // [ \xref[split] ]
  20776. // print([" to "=]1002); print_scaled(w);
  20777. // print_char([","=]44); print_scaled(best_height_plus_depth);
  20778. //
  20779. // print([" p="=]931);
  20780. // if q=0 then print_int(eject_penalty)
  20781. // else if mem[ q].hh.b0 =penalty_node then print_int( mem[ q+1].int )
  20782. // else print_char(["0"=]48);
  20783. // end_diagnostic(false);
  20784. // end
  20785. //
  20786. // ; [ ]
  20787. if *prg.eqtb[countBase+int32(n)-1].int() != 1000 {
  20788. prg.bestHeightPlusDepth = prg.xOverN(prg.bestHeightPlusDepth, 1000) * *prg.eqtb[countBase+int32(n)-1].int()
  20789. }
  20790. prg.pageSoFar[0] = prg.pageSoFar[0] - prg.bestHeightPlusDepth
  20791. *(*prg.mem[r1].hh()).b0() = byte(splitUp)
  20792. *(*prg.mem[int32(r1)+1].hh()).rh() = q
  20793. *(*prg.mem[int32(r1)+1].hh()).lh() = p
  20794. if int32(q) == 0 {
  20795. prg.insertPenalties = prg.insertPenalties + ejectPenalty
  20796. } else if int32(*(*prg.mem[q].hh()).b0()) == penaltyNode {
  20797. prg.insertPenalties = prg.insertPenalties + *prg.mem[int32(q)+1].int()
  20798. }
  20799. }
  20800. }
  20801. goto contribute
  20802. default:
  20803. prg.confusion(strNumber( /* "page" */ 993))
  20804. // \xref[this can't happen page][\quad page]
  20805. }
  20806. // Check if node |p| is a new champion breakpoint; then \(if)if it is time for a page break, prepare for output, and either fire up the user's output routine and |return| or ship out the page and |goto done|
  20807. if pi < infPenalty {
  20808. if prg.pageSoFar[1] < prg.pageSoFar[0] {
  20809. if prg.pageSoFar[3] != 0 || prg.pageSoFar[4] != 0 || prg.pageSoFar[5] != 0 {
  20810. b = 0
  20811. } else {
  20812. b = int32(prg.badness(prg.pageSoFar[0]-prg.pageSoFar[1], prg.pageSoFar[2]))
  20813. }
  20814. } else if prg.pageSoFar[1]-prg.pageSoFar[0] > prg.pageSoFar[6] {
  20815. b = 07777777777
  20816. } else {
  20817. b = int32(prg.badness(prg.pageSoFar[1]-prg.pageSoFar[0], prg.pageSoFar[6]))
  20818. }
  20819. if b < 07777777777 {
  20820. if pi <= ejectPenalty {
  20821. c = pi
  20822. } else if b < infBad {
  20823. c = b + pi + prg.insertPenalties
  20824. } else {
  20825. c = 100000
  20826. }
  20827. } else {
  20828. c = b
  20829. }
  20830. if prg.insertPenalties >= 10000 {
  20831. c = 07777777777
  20832. }
  20833. // if eqtb[int_base+ tracing_pages_code].int >0 then
  20834. // [ Display the page break cost ]
  20835. // begin begin_diagnostic; print_nl(["%"=]37);
  20836. // print([" t="=]927); print_totals;
  20837. //
  20838. // print([" g="=]996); print_scaled(page_so_far[0] );
  20839. //
  20840. // print([" b="=]930);
  20841. // if b=[07777777777=]1073741823 then print_char(["*"=]42) else print_int(b);
  20842. // [ \xref[*\relax] ]
  20843. // print([" p="=]931); print_int(pi);
  20844. // print([" c="=]997);
  20845. // if c=[07777777777=]1073741823 then print_char(["*"=]42) else print_int(c);
  20846. // if c<=least_page_cost then print_char(["#"=]35);
  20847. // end_diagnostic(false);
  20848. // end
  20849. //
  20850. // ; [ ]
  20851. if c <= prg.leastPageCost {
  20852. prg.bestPageBreak = p
  20853. prg.bestSize = prg.pageSoFar[0]
  20854. prg.leastPageCost = c
  20855. r1 = *(*prg.mem[30000].hh()).rh()
  20856. for int32(r1) != 30000 {
  20857. *(*prg.mem[int32(r1)+2].hh()).lh() = *(*prg.mem[int32(r1)+2].hh()).rh()
  20858. r1 = *(*prg.mem[r1].hh()).rh()
  20859. }
  20860. }
  20861. if c == 07777777777 || pi <= ejectPenalty {
  20862. prg.fireUp(p) // output the current page at the best place
  20863. if prg.outputActive {
  20864. goto exit
  20865. } // user's output routine will act
  20866. // user's output routine will act
  20867. goto done // the page has been shipped out by default output routine
  20868. }
  20869. }
  20870. if int32(*(*prg.mem[p].hh()).b0()) < glueNode || int32(*(*prg.mem[p].hh()).b0()) > kernNode {
  20871. goto contribute
  20872. }
  20873. updateHeights:
  20874. if int32(*(*prg.mem[p].hh()).b0()) == kernNode {
  20875. q = p
  20876. } else {
  20877. q = *(*prg.mem[int32(p)+1].hh()).lh()
  20878. prg.pageSoFar[2+int32(*(*prg.mem[q].hh()).b0())] = prg.pageSoFar[2+int32(*(*prg.mem[q].hh()).b0())] + *prg.mem[int32(q)+2].int()
  20879. prg.pageSoFar[6] = prg.pageSoFar[6] + *prg.mem[int32(q)+3].int()
  20880. if int32(*(*prg.mem[q].hh()).b1()) != normal && *prg.mem[int32(q)+3].int() != 0 {
  20881. {
  20882. if int32(prg.interaction) == errorStopMode {
  20883. }
  20884. prg.printNl(strNumber( /* "! " */ 262))
  20885. prg.print( /* "Infinite glue shrinkage found on current page" */ 994)
  20886. }
  20887. // \xref[Infinite glue shrinkage...]
  20888. {
  20889. prg.helpPtr = 4
  20890. prg.helpLine[3] = /* "The page about to be output contains some infinitely" */ 995
  20891. prg.helpLine[2] = /* "shrinkable glue, e.g., `\\vss' or `\\vskip 0pt minus 1fil'." */ 963
  20892. prg.helpLine[1] = /* "Such glue doesn't belong there; but you can safely proceed," */ 964
  20893. prg.helpLine[0] = /* "since the offensive shrinkability has been made finite." */ 922
  20894. }
  20895. prg.error1()
  20896. r1 = prg.newSpec(q)
  20897. *(*prg.mem[r1].hh()).b1() = byte(normal)
  20898. prg.deleteGlueRef(q)
  20899. *(*prg.mem[int32(p)+1].hh()).lh() = r1
  20900. q = r1
  20901. }
  20902. }
  20903. prg.pageSoFar[1] = prg.pageSoFar[1] + prg.pageSoFar[7] + *prg.mem[int32(q)+widthOffset].int()
  20904. prg.pageSoFar[7] = 0
  20905. contribute:
  20906. if prg.pageSoFar[7] > prg.pageMaxDepth {
  20907. prg.pageSoFar[1] = prg.pageSoFar[1] + prg.pageSoFar[7] - prg.pageMaxDepth
  20908. prg.pageSoFar[7] = prg.pageMaxDepth
  20909. }
  20910. // Link node |p| into the current page and |goto done|
  20911. *(*prg.mem[prg.pageTail].hh()).rh() = p
  20912. prg.pageTail = p
  20913. *(*prg.mem[30000-1].hh()).rh() = *(*prg.mem[p].hh()).rh()
  20914. *(*prg.mem[p].hh()).rh() = 0
  20915. goto done
  20916. done1:
  20917. *(*prg.mem[30000-1].hh()).rh() = *(*prg.mem[p].hh()).rh()
  20918. *(*prg.mem[p].hh()).rh() = 0
  20919. prg.flushNodeList(p)
  20920. done:
  20921. ;
  20922. if int32(*(*prg.mem[30000-1].hh()).rh()) == 0 {
  20923. break
  20924. }
  20925. }
  20926. // Make the contribution list empty by setting its tail to |contrib_head|
  20927. if int32(prg.nestPtr) == 0 {
  20928. prg.curList.tailField = uint16(30000 - 1)
  20929. } else {
  20930. prg.nest[0].tailField = uint16(30000 - 1)
  20931. }
  20932. exit:
  20933. }
  20934. // 1029. \[46] The chief executive
  20935. // tangle:pos tex.web:19977:26:
  20936. // We come now to the |main_control| routine, which contains the master
  20937. // switch that causes all the various pieces of \TeX\ to do their things,
  20938. // in the right order.
  20939. //
  20940. // In a sense, this is the grand climax of the program: It applies all the
  20941. // tools that we have worked so hard to construct. In another sense, this is
  20942. // the messiest part of the program: It necessarily refers to other pieces
  20943. // of code all over the place, so that a person can't fully understand what is
  20944. // going on without paging back and forth to be reminded of conventions that
  20945. // are defined elsewhere. We are now at the hub of the web, the central nervous
  20946. // system that touches most of the other parts and ties them together.
  20947. // \xref[brain]
  20948. //
  20949. // The structure of |main_control| itself is quite simple. There's a label
  20950. // called |big_switch|, at which point the next token of input is fetched
  20951. // using |get_x_token|. Then the program branches at high speed into one of
  20952. // about 100 possible directions, based on the value of the current
  20953. // mode and the newly fetched command code; the sum |abs(mode)+cur_cmd|
  20954. // indicates what to do next. For example, the case `|vmode+letter|' arises
  20955. // when a letter occurs in vertical mode (or internal vertical mode); this
  20956. // case leads to instructions that initialize a new paragraph and enter
  20957. // horizontal mode.
  20958. //
  20959. // The big |case| statement that contains this multiway switch has been labeled
  20960. // |reswitch|, so that the program can |goto reswitch| when the next token
  20961. // has already been fetched. Most of the cases are quite short; they call
  20962. // an ``action procedure'' that does the work for that case, and then they
  20963. // either |goto reswitch| or they ``fall through'' to the end of the |case|
  20964. // statement, which returns control back to |big_switch|. Thus, |main_control|
  20965. // is not an extremely large procedure, in spite of the multiplicity of things
  20966. // it must do; it is small enough to be handled by \PASCAL\ compilers that put
  20967. // severe restrictions on procedure size.
  20968. // \xref[action procedure]
  20969. //
  20970. // One case is singled out for special treatment, because it accounts for most
  20971. // of \TeX's activities in typical applications. The process of reading simple
  20972. // text and converting it into |char_node| records, while looking for ligatures
  20973. // and kerns, is part of \TeX's ``inner loop''; the whole program runs
  20974. // efficiently when its inner loop is fast, so this part has been written
  20975. // with particular care.
  20976. // 1030.
  20977. // tangle:pos tex.web:20017:22:
  20978. // We shall concentrate first on the inner loop of |main_control|, deferring
  20979. // consideration of the other cases until later.
  20980. // \xref[inner loop]
  20981. // \4
  20982. // Declare action procedures for use by |main_control|
  20983. func (prg *prg) appSpace() { // handle spaces when |space_factor<>1000|
  20984. var (
  20985. q halfword // glue node
  20986. )
  20987. if int32(*(*prg.curList.auxField.hh()).lh()) >= 2000 && int32(*(*prg.eqtb[glueBase+xspaceSkipCode-1].hh()).rh()) != memBot {
  20988. q = prg.newParamGlue(smallNumber(xspaceSkipCode))
  20989. } else {
  20990. if int32(*(*prg.eqtb[glueBase+spaceSkipCode-1].hh()).rh()) != memBot {
  20991. prg.mainP = *(*prg.eqtb[glueBase+spaceSkipCode-1].hh()).rh()
  20992. } else {
  20993. // Find the glue specification...
  20994. prg.mainP = prg.fontGlue[*(*prg.eqtb[curFontLoc-1].hh()).rh()]
  20995. if int32(prg.mainP) == 0 {
  20996. prg.mainP = prg.newSpec(halfword(memBot))
  20997. prg.mainK = uint16(prg.paramBase[*(*prg.eqtb[curFontLoc-1].hh()).rh()] + spaceCode)
  20998. *prg.mem[int32(prg.mainP)+widthOffset].int() = *prg.fontInfo[prg.mainK].int() // that's |space(cur_font)|
  20999. *prg.mem[int32(prg.mainP)+2].int() = *prg.fontInfo[int32(prg.mainK)+1].int() // and |space_stretch(cur_font)|
  21000. *prg.mem[int32(prg.mainP)+3].int() = *prg.fontInfo[int32(prg.mainK)+2].int() // and |space_shrink(cur_font)|
  21001. prg.fontGlue[*(*prg.eqtb[curFontLoc-1].hh()).rh()] = prg.mainP
  21002. }
  21003. }
  21004. prg.mainP = prg.newSpec(prg.mainP)
  21005. // Modify the glue specification in |main_p| according to the space factor
  21006. if int32(*(*prg.curList.auxField.hh()).lh()) >= 2000 {
  21007. *prg.mem[int32(prg.mainP)+widthOffset].int() = *prg.mem[int32(prg.mainP)+widthOffset].int() + *prg.fontInfo[extraSpaceCode+prg.paramBase[*(*prg.eqtb[curFontLoc-1].hh()).rh()]].int()
  21008. }
  21009. *prg.mem[int32(prg.mainP)+2].int() = prg.xnOverD(*prg.mem[int32(prg.mainP)+2].int(), int32(*(*prg.curList.auxField.hh()).lh()), 1000)
  21010. *prg.mem[int32(prg.mainP)+3].int() = prg.xnOverD(*prg.mem[int32(prg.mainP)+3].int(), 1000, int32(*(*prg.curList.auxField.hh()).lh()))
  21011. q = prg.newGlue(prg.mainP)
  21012. *(*prg.mem[prg.mainP].hh()).rh() = 0
  21013. }
  21014. *(*prg.mem[prg.curList.tailField].hh()).rh() = q
  21015. prg.curList.tailField = q
  21016. }
  21017. func (prg *prg) insertDollarSign() {
  21018. prg.backInput()
  21019. prg.curTok = uint16(mathShiftToken + '$')
  21020. {
  21021. if int32(prg.interaction) == errorStopMode {
  21022. }
  21023. prg.printNl(strNumber( /* "! " */ 262))
  21024. prg.print( /* "Missing $ inserted" */ 1017)
  21025. }
  21026. // \xref[Missing \$ inserted]
  21027. {
  21028. prg.helpPtr = 2
  21029. prg.helpLine[1] = /* "I've inserted a begin-math/end-math symbol since I think" */ 1018
  21030. prg.helpLine[0] = /* "you left one out. Proceed, with fingers crossed." */ 1019
  21031. }
  21032. prg.insError()
  21033. }
  21034. func (prg *prg) youCant() {
  21035. {
  21036. if int32(prg.interaction) == errorStopMode {
  21037. }
  21038. prg.printNl(strNumber( /* "! " */ 262))
  21039. prg.print( /* "You can't use `" */ 685)
  21040. }
  21041. // \xref[You can't use x in y mode]
  21042. prg.printCmdChr(prg.curCmd, prg.curChr)
  21043. prg.print( /* "' in " */ 1020)
  21044. prg.printMode(int32(prg.curList.modeField))
  21045. }
  21046. func (prg *prg) reportIllegalCase() {
  21047. prg.youCant()
  21048. {
  21049. prg.helpPtr = 4
  21050. prg.helpLine[3] = /* "Sorry, but I'm not programmed to handle this case;" */ 1021
  21051. prg.helpLine[2] = /* "I'll just pretend that you didn't ask for it." */ 1022
  21052. prg.helpLine[1] = /* "If you're in the wrong mode, you might be able to" */ 1023
  21053. prg.helpLine[0] = /* "return to the right one by typing `I]' or `I$' or `I\\par'." */ 1024
  21054. }
  21055. prg.error1()
  21056. }
  21057. func (prg *prg) privileged() (r bool) {
  21058. if int32(prg.curList.modeField) > 0 {
  21059. r = true
  21060. } else {
  21061. prg.reportIllegalCase()
  21062. r = false
  21063. }
  21064. return r
  21065. }
  21066. func (prg *prg) itsAllOver() (r bool) {
  21067. if prg.privileged() {
  21068. if 30000-2 == int32(prg.pageTail) && int32(prg.curList.headField) == int32(prg.curList.tailField) && prg.deadCycles == 0 {
  21069. r = true
  21070. goto exit
  21071. }
  21072. prg.backInput() // we will try to end again after ejecting residual material
  21073. {
  21074. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newNullBox()
  21075. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  21076. }
  21077. *prg.mem[int32(prg.curList.tailField)+widthOffset].int() = *prg.eqtb[dimenBase+hsizeCode-1].int()
  21078. {
  21079. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newGlue(halfword(memBot + glueSpecSize + glueSpecSize))
  21080. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  21081. }
  21082. {
  21083. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newPenalty(-010000000000)
  21084. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  21085. }
  21086. prg.buildPage() // append \.[\\hbox to \\hsize\[\]\\vfill\\penalty-'10000000000]
  21087. }
  21088. r = false
  21089. exit:
  21090. ;
  21091. return r
  21092. }
  21093. func (prg *prg) appendGlue() {
  21094. var (
  21095. s smallNumber // modifier of skip command
  21096. )
  21097. s = byte(prg.curChr)
  21098. switch s {
  21099. case filCode:
  21100. prg.curVal = memBot + glueSpecSize
  21101. case fillCode:
  21102. prg.curVal = memBot + glueSpecSize + glueSpecSize
  21103. case ssCode:
  21104. prg.curVal = memBot + glueSpecSize + glueSpecSize + glueSpecSize
  21105. case filNegCode:
  21106. prg.curVal = memBot + glueSpecSize + glueSpecSize + glueSpecSize + glueSpecSize
  21107. case skipCode:
  21108. prg.scanGlue(smallNumber(glueVal))
  21109. case mskipCode:
  21110. prg.scanGlue(smallNumber(muVal))
  21111. } // now |cur_val| points to the glue specification
  21112. {
  21113. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newGlue(halfword(prg.curVal))
  21114. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  21115. }
  21116. if int32(s) >= skipCode {
  21117. *(*prg.mem[prg.curVal].hh()).rh() = uint16(int32(*(*prg.mem[prg.curVal].hh()).rh()) - 1)
  21118. if int32(s) > skipCode {
  21119. *(*prg.mem[prg.curList.tailField].hh()).b1() = byte(muGlue)
  21120. }
  21121. }
  21122. }
  21123. func (prg *prg) appendKern() {
  21124. var (
  21125. s quarterword // |subtype| of the kern node
  21126. )
  21127. s = byte(prg.curChr)
  21128. prg.scanDimen(int32(s) == muGlue, false, false)
  21129. {
  21130. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newKern(prg.curVal)
  21131. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  21132. }
  21133. *(*prg.mem[prg.curList.tailField].hh()).b1() = s
  21134. }
  21135. func (prg *prg) offSave() {
  21136. var (
  21137. p halfword // inserted token
  21138. )
  21139. if int32(prg.curGroup) == bottomLevel {
  21140. {
  21141. if int32(prg.interaction) == errorStopMode {
  21142. }
  21143. prg.printNl(strNumber( /* "! " */ 262))
  21144. prg.print( /* "Extra " */ 777)
  21145. }
  21146. prg.printCmdChr(prg.curCmd, prg.curChr)
  21147. // \xref[Extra x]
  21148. {
  21149. prg.helpPtr = 1
  21150. prg.helpLine[0] = /* "Things are pretty mixed up, but I think the worst is over." */ 1043
  21151. }
  21152. prg.error1()
  21153. } else {
  21154. prg.backInput()
  21155. p = prg.getAvail()
  21156. *(*prg.mem[30000-3].hh()).rh() = p
  21157. {
  21158. if int32(prg.interaction) == errorStopMode {
  21159. }
  21160. prg.printNl(strNumber( /* "! " */ 262))
  21161. prg.print( /* "Missing " */ 625)
  21162. }
  21163. // Prepare to insert a token that matches |cur_group|, and print what it is
  21164. switch prg.curGroup {
  21165. case semiSimpleGroup:
  21166. *(*prg.mem[p].hh()).lh() = uint16(07777 + frozenEndGroup)
  21167. prg.printEsc(strNumber( /* "endgroup" */ 516))
  21168. // \xref[Missing \\endgroup inserted]
  21169. case mathShiftGroup:
  21170. *(*prg.mem[p].hh()).lh() = uint16(mathShiftToken + '$')
  21171. prg.printChar(asciiCode('$'))
  21172. // \xref[Missing \$ inserted]
  21173. case mathLeftGroup:
  21174. *(*prg.mem[p].hh()).lh() = uint16(07777 + frozenRight)
  21175. *(*prg.mem[p].hh()).rh() = prg.getAvail()
  21176. p = *(*prg.mem[p].hh()).rh()
  21177. *(*prg.mem[p].hh()).lh() = uint16(otherToken + '.')
  21178. prg.printEsc(strNumber( /* "right." */ 1042))
  21179. // \xref[Missing \\right\hbox[.] inserted]
  21180. // \xref[null delimiter]
  21181. default:
  21182. *(*prg.mem[p].hh()).lh() = uint16(rightBraceToken + '}')
  21183. prg.printChar(asciiCode('}'))
  21184. // \xref[Missing \] inserted]
  21185. }
  21186. prg.print( /* " inserted" */ 626)
  21187. prg.beginTokenList(*(*prg.mem[30000-3].hh()).rh(), quarterword(inserted))
  21188. {
  21189. prg.helpPtr = 5
  21190. prg.helpLine[4] = /* "I've inserted something that you may have forgotten." */ 1037
  21191. prg.helpLine[3] = /* "(See the <inserted text> above.)" */ 1038
  21192. prg.helpLine[2] = /* "With luck, this will get me unwedged. But if you" */ 1039
  21193. prg.helpLine[1] = /* "really didn't forget anything, try typing `2' now; then" */ 1040
  21194. prg.helpLine[0] = /* "my insertion and my current dilemma will both disappear." */ 1041
  21195. }
  21196. prg.error1()
  21197. }
  21198. }
  21199. func (prg *prg) extraRightBrace() {
  21200. {
  21201. if int32(prg.interaction) == errorStopMode {
  21202. }
  21203. prg.printNl(strNumber( /* "! " */ 262))
  21204. prg.print( /* "Extra ], or forgotten " */ 1048)
  21205. }
  21206. // \xref[Extra \], or forgotten x]
  21207. switch prg.curGroup {
  21208. case semiSimpleGroup:
  21209. prg.printEsc(strNumber( /* "endgroup" */ 516))
  21210. case mathShiftGroup:
  21211. prg.printChar(asciiCode('$'))
  21212. case mathLeftGroup:
  21213. prg.printEsc(strNumber( /* "right" */ 877))
  21214. }
  21215. {
  21216. prg.helpPtr = 5
  21217. prg.helpLine[4] = /* "I've deleted a group-closing symbol because it seems to be" */ 1049
  21218. prg.helpLine[3] = /* "spurious, as in `$x]$'. But perhaps the ] is legitimate and" */ 1050
  21219. prg.helpLine[2] = /* "you forgot something else, as in `\\hbox[$x]'. In such cases" */ 1051
  21220. prg.helpLine[1] = /* "the way to recover is to insert both the forgotten and the" */ 1052
  21221. prg.helpLine[0] = /* "deleted material, e.g., by typing `I$]'." */ 1053
  21222. }
  21223. prg.error1()
  21224. prg.alignState = prg.alignState + 1
  21225. } // \2
  21226. func (prg *prg) normalParagraph() {
  21227. if *prg.eqtb[intBase+loosenessCode-1].int() != 0 {
  21228. prg.eqWordDefine(halfword(intBase+loosenessCode), 0)
  21229. }
  21230. if *prg.eqtb[dimenBase+hangIndentCode-1].int() != 0 {
  21231. prg.eqWordDefine(halfword(dimenBase+hangIndentCode), 0)
  21232. }
  21233. if *prg.eqtb[intBase+hangAfterCode-1].int() != 1 {
  21234. prg.eqWordDefine(halfword(intBase+hangAfterCode), 1)
  21235. }
  21236. if int32(*(*prg.eqtb[parShapeLoc-1].hh()).rh()) != 0 {
  21237. prg.eqDefine(halfword(parShapeLoc), quarterword(shapeRef), halfword(0))
  21238. }
  21239. }
  21240. func (prg *prg) boxEnd(boxContext int32) {
  21241. var (
  21242. p halfword // |ord_noad| for new box in math mode
  21243. )
  21244. if boxContext < 010000000000 {
  21245. if int32(prg.curBox) != 0 {
  21246. *prg.mem[int32(prg.curBox)+4].int() = boxContext
  21247. if abs(int32(prg.curList.modeField)) == vmode {
  21248. prg.appendToVlist(prg.curBox)
  21249. if int32(prg.adjustTail) != 0 {
  21250. if 30000-5 != int32(prg.adjustTail) {
  21251. *(*prg.mem[prg.curList.tailField].hh()).rh() = *(*prg.mem[30000-5].hh()).rh()
  21252. prg.curList.tailField = prg.adjustTail
  21253. }
  21254. prg.adjustTail = 0
  21255. }
  21256. if int32(prg.curList.modeField) > 0 {
  21257. prg.buildPage()
  21258. }
  21259. } else {
  21260. if abs(int32(prg.curList.modeField)) == hmode {
  21261. *(*prg.curList.auxField.hh()).lh() = 1000
  21262. } else {
  21263. p = prg.newNoad()
  21264. *(*prg.mem[int32(p)+1].hh()).rh() = uint16(subBox)
  21265. *(*prg.mem[int32(p)+1].hh()).lh() = prg.curBox
  21266. prg.curBox = p
  21267. }
  21268. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.curBox
  21269. prg.curList.tailField = prg.curBox
  21270. }
  21271. }
  21272. } else if boxContext < 010000000000+512 {
  21273. if boxContext < 010000000000+256 {
  21274. prg.eqDefine(halfword(boxBase-010000000000+boxContext), quarterword(boxRef), prg.curBox)
  21275. } else {
  21276. prg.geqDefine(halfword(boxBase-010000000000-256+boxContext), quarterword(boxRef), prg.curBox)
  21277. }
  21278. } else if int32(prg.curBox) != 0 {
  21279. if boxContext > 010000000000+512 {
  21280. for {
  21281. prg.getXToken()
  21282. if int32(prg.curCmd) != spacer && int32(prg.curCmd) != relax {
  21283. break
  21284. }
  21285. }
  21286. if int32(prg.curCmd) == hskip && abs(int32(prg.curList.modeField)) != vmode || int32(prg.curCmd) == vskip && abs(int32(prg.curList.modeField)) == vmode {
  21287. prg.appendGlue()
  21288. *(*prg.mem[prg.curList.tailField].hh()).b1() = byte(boxContext - (010000000000 + 513 - aLeaders))
  21289. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).rh() = prg.curBox
  21290. } else {
  21291. {
  21292. if int32(prg.interaction) == errorStopMode {
  21293. }
  21294. prg.printNl(strNumber( /* "! " */ 262))
  21295. prg.print( /* "Leaders not followed by proper glue" */ 1066)
  21296. }
  21297. // \xref[Leaders not followed by...]
  21298. {
  21299. prg.helpPtr = 3
  21300. prg.helpLine[2] = /* "You should say `\\leaders <box or rule><hskip or vskip>'." */ 1067
  21301. prg.helpLine[1] = /* "I found the <box or rule>, but there's no suitable" */ 1068
  21302. prg.helpLine[0] = /* "<hskip or vskip>, so I'm ignoring these leaders." */ 1069
  21303. }
  21304. prg.backError()
  21305. prg.flushNodeList(prg.curBox)
  21306. }
  21307. } else {
  21308. prg.shipOut(prg.curBox)
  21309. }
  21310. }
  21311. }
  21312. func (prg *prg) beginBox(boxContext int32) {
  21313. var (
  21314. p, q halfword // run through the current list
  21315. m quarterword // the length of a replacement list
  21316. k halfword // 0 or |vmode| or |hmode|
  21317. n eightBits // a box number
  21318. )
  21319. switch prg.curChr {
  21320. case boxCode:
  21321. prg.scanEightBitInt()
  21322. prg.curBox = *(*prg.eqtb[boxBase+prg.curVal-1].hh()).rh()
  21323. *(*prg.eqtb[boxBase+prg.curVal-1].hh()).rh() = 0 // the box becomes void, at the same level
  21324. case copyCode:
  21325. prg.scanEightBitInt()
  21326. prg.curBox = prg.copyNodeList(*(*prg.eqtb[boxBase+prg.curVal-1].hh()).rh())
  21327. case lastBoxCode:
  21328. // If the current list ends with a box node, delete it from the list and make |cur_box| point to it; otherwise set |cur_box:=null|
  21329. prg.curBox = 0
  21330. if abs(int32(prg.curList.modeField)) == mmode {
  21331. prg.youCant()
  21332. {
  21333. prg.helpPtr = 1
  21334. prg.helpLine[0] = /* "Sorry; this \\lastbox will be void." */ 1070
  21335. }
  21336. prg.error1()
  21337. } else if int32(prg.curList.modeField) == vmode && int32(prg.curList.headField) == int32(prg.curList.tailField) {
  21338. prg.youCant()
  21339. {
  21340. prg.helpPtr = 2
  21341. prg.helpLine[1] = /* "Sorry...I usually can't take things from the current page." */ 1071
  21342. prg.helpLine[0] = /* "This \\lastbox will therefore be void." */ 1072
  21343. }
  21344. prg.error1()
  21345. } else {
  21346. if !(int32(prg.curList.tailField) >= int32(prg.hiMemMin)) {
  21347. if int32(*(*prg.mem[prg.curList.tailField].hh()).b0()) == hlistNode || int32(*(*prg.mem[prg.curList.tailField].hh()).b0()) == vlistNode {
  21348. q = prg.curList.headField
  21349. for {
  21350. p = q
  21351. if !(int32(q) >= int32(prg.hiMemMin)) {
  21352. if int32(*(*prg.mem[q].hh()).b0()) == discNode {
  21353. for ii := int32(1); ii <= int32(*(*prg.mem[q].hh()).b1()); ii++ {
  21354. m = quarterword(ii)
  21355. _ = m
  21356. p = *(*prg.mem[p].hh()).rh()
  21357. }
  21358. if int32(p) == int32(prg.curList.tailField) {
  21359. goto done
  21360. }
  21361. }
  21362. }
  21363. q = *(*prg.mem[p].hh()).rh()
  21364. if int32(q) == int32(prg.curList.tailField) {
  21365. break
  21366. }
  21367. }
  21368. prg.curBox = prg.curList.tailField
  21369. *prg.mem[int32(prg.curBox)+4].int() = 0
  21370. prg.curList.tailField = p
  21371. *(*prg.mem[p].hh()).rh() = 0
  21372. done:
  21373. }
  21374. }
  21375. }
  21376. case vsplitCode:
  21377. // Split off part of a vertical box, make |cur_box| point to it
  21378. prg.scanEightBitInt()
  21379. n = byte(prg.curVal)
  21380. if !prg.scanKeyword(strNumber(842)) {
  21381. {
  21382. if int32(prg.interaction) == errorStopMode {
  21383. }
  21384. prg.printNl(strNumber( /* "! " */ 262))
  21385. prg.print( /* "Missing `to' inserted" */ 1073)
  21386. }
  21387. // \xref[Missing `to' inserted]
  21388. {
  21389. prg.helpPtr = 2
  21390. prg.helpLine[1] = /* "I'm working on `\\vsplit<box number> to <dimen>';" */ 1074
  21391. prg.helpLine[0] = /* "will look for the <dimen> next." */ 1075
  21392. }
  21393. prg.error1()
  21394. }
  21395. prg.scanDimen(false, false, false)
  21396. prg.curBox = prg.vsplit(n, prg.curVal)
  21397. default:
  21398. k = uint16(int32(prg.curChr) - vtopCode)
  21399. *prg.saveStack[int32(prg.savePtr)+0].int() = boxContext
  21400. if int32(k) == hmode {
  21401. if boxContext < 010000000000 && abs(int32(prg.curList.modeField)) == vmode {
  21402. prg.scanSpec(groupCode(adjustedHboxGroup), true)
  21403. } else {
  21404. prg.scanSpec(groupCode(hboxGroup), true)
  21405. }
  21406. } else {
  21407. if int32(k) == vmode {
  21408. prg.scanSpec(groupCode(vboxGroup), true)
  21409. } else {
  21410. prg.scanSpec(groupCode(vtopGroup), true)
  21411. k = uint16(vmode)
  21412. }
  21413. prg.normalParagraph()
  21414. }
  21415. prg.pushNest()
  21416. prg.curList.modeField = int16(-int32(k))
  21417. if int32(k) == vmode {
  21418. *prg.curList.auxField.int() = -65536000
  21419. if int32(*(*prg.eqtb[everyVboxLoc-1].hh()).rh()) != 0 {
  21420. prg.beginTokenList(*(*prg.eqtb[everyVboxLoc-1].hh()).rh(), quarterword(everyVboxText))
  21421. }
  21422. } else {
  21423. *(*prg.curList.auxField.hh()).lh() = 1000
  21424. if int32(*(*prg.eqtb[everyHboxLoc-1].hh()).rh()) != 0 {
  21425. prg.beginTokenList(*(*prg.eqtb[everyHboxLoc-1].hh()).rh(), quarterword(everyHboxText))
  21426. }
  21427. }
  21428. goto exit
  21429. }
  21430. prg.boxEnd(boxContext) // in simple cases, we use the box immediately
  21431. // in simple cases, we use the box immediately
  21432. exit:
  21433. }
  21434. func (prg *prg) scanBox(boxContext int32) {
  21435. for {
  21436. prg.getXToken()
  21437. if int32(prg.curCmd) != spacer && int32(prg.curCmd) != relax {
  21438. break
  21439. }
  21440. }
  21441. if int32(prg.curCmd) == makeBox {
  21442. prg.beginBox(boxContext)
  21443. } else if boxContext >= 010000000000+513 && (int32(prg.curCmd) == hrule || int32(prg.curCmd) == vrule) {
  21444. prg.curBox = prg.scanRuleSpec()
  21445. prg.boxEnd(boxContext)
  21446. } else {
  21447. {
  21448. if int32(prg.interaction) == errorStopMode {
  21449. }
  21450. prg.printNl(strNumber( /* "! " */ 262))
  21451. prg.print( /* "A <box> was supposed to be here" */ 1076)
  21452. }
  21453. // \xref[A <box> was supposed to...]
  21454. {
  21455. prg.helpPtr = 3
  21456. prg.helpLine[2] = /* "I was expecting to see \\hbox or \\vbox or \\copy or \\box or" */ 1077
  21457. prg.helpLine[1] = /* "something like that. So you might find something missing in" */ 1078
  21458. prg.helpLine[0] = /* "your output. But keep trying; you can fix this later." */ 1079
  21459. }
  21460. prg.backError()
  21461. }
  21462. }
  21463. func (prg *prg) package1(c smallNumber) {
  21464. var (
  21465. h scaled // height of box
  21466. p halfword // first node in a box
  21467. d scaled // max depth
  21468. )
  21469. d = *prg.eqtb[dimenBase+boxMaxDepthCode-1].int()
  21470. prg.unsave()
  21471. prg.savePtr = uint16(int32(prg.savePtr) - 3)
  21472. if int32(prg.curList.modeField) == -hmode {
  21473. prg.curBox = prg.hpack(*(*prg.mem[prg.curList.headField].hh()).rh(), *prg.saveStack[int32(prg.savePtr)+2].int(), smallNumber(*prg.saveStack[int32(prg.savePtr)+1].int()))
  21474. } else {
  21475. prg.curBox = prg.vpackage(*(*prg.mem[prg.curList.headField].hh()).rh(), *prg.saveStack[int32(prg.savePtr)+2].int(), smallNumber(*prg.saveStack[int32(prg.savePtr)+1].int()), d)
  21476. if int32(c) == vtopCode {
  21477. h = 0
  21478. p = *(*prg.mem[int32(prg.curBox)+listOffset].hh()).rh()
  21479. if int32(p) != 0 {
  21480. if int32(*(*prg.mem[p].hh()).b0()) <= ruleNode {
  21481. h = *prg.mem[int32(p)+heightOffset].int()
  21482. }
  21483. }
  21484. *prg.mem[int32(prg.curBox)+depthOffset].int() = *prg.mem[int32(prg.curBox)+depthOffset].int() - h + *prg.mem[int32(prg.curBox)+heightOffset].int()
  21485. *prg.mem[int32(prg.curBox)+heightOffset].int() = h
  21486. }
  21487. }
  21488. prg.popNest()
  21489. prg.boxEnd(*prg.saveStack[int32(prg.savePtr)+0].int())
  21490. }
  21491. func (prg *prg) normMin(h int32) (r smallNumber) {
  21492. if h <= 0 {
  21493. r = 1
  21494. } else if h >= 63 {
  21495. r = 63
  21496. } else {
  21497. r = byte(h)
  21498. }
  21499. return r
  21500. }
  21501. func (prg *prg) newGraf(indented bool) {
  21502. prg.curList.pgField = 0
  21503. if int32(prg.curList.modeField) == vmode || int32(prg.curList.headField) != int32(prg.curList.tailField) {
  21504. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newParamGlue(smallNumber(parSkipCode))
  21505. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  21506. }
  21507. prg.pushNest()
  21508. prg.curList.modeField = int16(hmode)
  21509. *(*prg.curList.auxField.hh()).lh() = 1000
  21510. if *prg.eqtb[intBase+languageCode-1].int() <= 0 {
  21511. prg.curLang = 0
  21512. } else if *prg.eqtb[intBase+languageCode-1].int() > 255 {
  21513. prg.curLang = 0
  21514. } else {
  21515. prg.curLang = byte(*prg.eqtb[intBase+languageCode-1].int())
  21516. }
  21517. *(*prg.curList.auxField.hh()).rh() = uint16(prg.curLang)
  21518. prg.curList.pgField = (int32(prg.normMin(*prg.eqtb[intBase+leftHyphenMinCode-1].int()))*0100+int32(prg.normMin(*prg.eqtb[intBase+rightHyphenMinCode-1].int())))*0200000 + int32(prg.curLang)
  21519. if indented {
  21520. prg.curList.tailField = prg.newNullBox()
  21521. *(*prg.mem[prg.curList.headField].hh()).rh() = prg.curList.tailField
  21522. *prg.mem[int32(prg.curList.tailField)+widthOffset].int() = *prg.eqtb[dimenBase+parIndentCode-1].int()
  21523. }
  21524. if int32(*(*prg.eqtb[everyParLoc-1].hh()).rh()) != 0 {
  21525. prg.beginTokenList(*(*prg.eqtb[everyParLoc-1].hh()).rh(), quarterword(everyParText))
  21526. }
  21527. if int32(prg.nestPtr) == 1 {
  21528. prg.buildPage()
  21529. } // put |par_skip| glue on current page
  21530. }
  21531. func (prg *prg) indentInHmode() {
  21532. var (
  21533. p, q halfword
  21534. )
  21535. if int32(prg.curChr) > 0 {
  21536. p = prg.newNullBox()
  21537. *prg.mem[int32(p)+widthOffset].int() = *prg.eqtb[dimenBase+parIndentCode-1].int()
  21538. if abs(int32(prg.curList.modeField)) == hmode {
  21539. *(*prg.curList.auxField.hh()).lh() = 1000
  21540. } else {
  21541. q = prg.newNoad()
  21542. *(*prg.mem[int32(q)+1].hh()).rh() = uint16(subBox)
  21543. *(*prg.mem[int32(q)+1].hh()).lh() = p
  21544. p = q
  21545. }
  21546. {
  21547. *(*prg.mem[prg.curList.tailField].hh()).rh() = p
  21548. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  21549. }
  21550. }
  21551. }
  21552. func (prg *prg) headForVmode() {
  21553. if int32(prg.curList.modeField) < 0 {
  21554. if int32(prg.curCmd) != hrule {
  21555. prg.offSave()
  21556. } else {
  21557. {
  21558. if int32(prg.interaction) == errorStopMode {
  21559. }
  21560. prg.printNl(strNumber( /* "! " */ 262))
  21561. prg.print( /* "You can't use `" */ 685)
  21562. }
  21563. prg.printEsc(strNumber( /* "hrule" */ 521))
  21564. prg.print( /* "' here except with leaders" */ 1082)
  21565. // \xref[You can't use \\hrule...]
  21566. {
  21567. prg.helpPtr = 2
  21568. prg.helpLine[1] = /* "To put a horizontal rule in an hbox or an alignment," */ 1083
  21569. prg.helpLine[0] = /* "you should use \\leaders or \\hrulefill (see The TeXbook)." */ 1084
  21570. }
  21571. prg.error1()
  21572. }
  21573. } else {
  21574. prg.backInput()
  21575. prg.curTok = prg.parToken
  21576. prg.backInput()
  21577. prg.curInput.indexField = byte(inserted)
  21578. }
  21579. }
  21580. func (prg *prg) endGraf() {
  21581. if int32(prg.curList.modeField) == hmode {
  21582. if int32(prg.curList.headField) == int32(prg.curList.tailField) {
  21583. prg.popNest()
  21584. } else {
  21585. prg.lineBreak(*prg.eqtb[intBase+widowPenaltyCode-1].int())
  21586. }
  21587. prg.normalParagraph()
  21588. prg.errorCount = 0
  21589. }
  21590. }
  21591. func (prg *prg) beginInsertOrAdjust() {
  21592. if int32(prg.curCmd) == vadjust {
  21593. prg.curVal = 255
  21594. } else {
  21595. prg.scanEightBitInt()
  21596. if prg.curVal == 255 {
  21597. {
  21598. if int32(prg.interaction) == errorStopMode {
  21599. }
  21600. prg.printNl(strNumber( /* "! " */ 262))
  21601. prg.print( /* "You can't " */ 1085)
  21602. }
  21603. prg.printEsc(strNumber( /* "insert" */ 330))
  21604. prg.printInt(255)
  21605. // \xref[You can't \\insert255]
  21606. {
  21607. prg.helpPtr = 1
  21608. prg.helpLine[0] = /* "I'm changing to \\insert0; box 255 is special." */ 1086
  21609. }
  21610. prg.error1()
  21611. prg.curVal = 0
  21612. }
  21613. }
  21614. *prg.saveStack[int32(prg.savePtr)+0].int() = prg.curVal
  21615. prg.savePtr = uint16(int32(prg.savePtr) + 1)
  21616. prg.newSaveLevel(groupCode(insertGroup))
  21617. prg.scanLeftBrace()
  21618. prg.normalParagraph()
  21619. prg.pushNest()
  21620. prg.curList.modeField = int16(-vmode)
  21621. *prg.curList.auxField.int() = -65536000
  21622. }
  21623. func (prg *prg) makeMark() {
  21624. var (
  21625. p halfword // new node
  21626. )
  21627. p = prg.scanToks(false, true)
  21628. p = prg.getNode(smallNodeSize)
  21629. *(*prg.mem[p].hh()).b0() = byte(markNode)
  21630. *(*prg.mem[p].hh()).b1() = 0 // the |subtype| is not used
  21631. *prg.mem[int32(p)+1].int() = int32(prg.defRef)
  21632. *(*prg.mem[prg.curList.tailField].hh()).rh() = p
  21633. prg.curList.tailField = p
  21634. }
  21635. func (prg *prg) appendPenalty() {
  21636. prg.scanInt()
  21637. {
  21638. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newPenalty(prg.curVal)
  21639. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  21640. }
  21641. if int32(prg.curList.modeField) == vmode {
  21642. prg.buildPage()
  21643. }
  21644. }
  21645. func (prg *prg) deleteLast() {
  21646. var (
  21647. p, q halfword // run through the current list
  21648. m quarterword // the length of a replacement list
  21649. )
  21650. if int32(prg.curList.modeField) == vmode && int32(prg.curList.tailField) == int32(prg.curList.headField) {
  21651. if int32(prg.curChr) != glueNode || int32(prg.lastGlue) != 65535 {
  21652. prg.youCant()
  21653. {
  21654. prg.helpPtr = 2
  21655. prg.helpLine[1] = /* "Sorry...I usually can't take things from the current page." */ 1071
  21656. prg.helpLine[0] = /* "Try `I\\vskip-\\lastskip' instead." */ 1087
  21657. }
  21658. if int32(prg.curChr) == kernNode {
  21659. prg.helpLine[0] = uint16(1088)
  21660. } else if int32(prg.curChr) != glueNode {
  21661. prg.helpLine[0] = uint16(1089)
  21662. }
  21663. prg.error1()
  21664. }
  21665. } else {
  21666. if !(int32(prg.curList.tailField) >= int32(prg.hiMemMin)) {
  21667. if int32(*(*prg.mem[prg.curList.tailField].hh()).b0()) == int32(prg.curChr) {
  21668. q = prg.curList.headField
  21669. for {
  21670. p = q
  21671. if !(int32(q) >= int32(prg.hiMemMin)) {
  21672. if int32(*(*prg.mem[q].hh()).b0()) == discNode {
  21673. for ii := int32(1); ii <= int32(*(*prg.mem[q].hh()).b1()); ii++ {
  21674. m = quarterword(ii)
  21675. _ = m
  21676. p = *(*prg.mem[p].hh()).rh()
  21677. }
  21678. if int32(p) == int32(prg.curList.tailField) {
  21679. goto exit
  21680. }
  21681. }
  21682. }
  21683. q = *(*prg.mem[p].hh()).rh()
  21684. if int32(q) == int32(prg.curList.tailField) {
  21685. break
  21686. }
  21687. }
  21688. *(*prg.mem[p].hh()).rh() = 0
  21689. prg.flushNodeList(prg.curList.tailField)
  21690. prg.curList.tailField = p
  21691. }
  21692. }
  21693. }
  21694. exit:
  21695. }
  21696. func (prg *prg) unpackage() {
  21697. var (
  21698. p halfword // the box
  21699. c/* boxCode..copyCode */ byte // should we copy?
  21700. )
  21701. c = byte(prg.curChr)
  21702. prg.scanEightBitInt()
  21703. p = *(*prg.eqtb[boxBase+prg.curVal-1].hh()).rh()
  21704. if int32(p) == 0 {
  21705. goto exit
  21706. }
  21707. if abs(int32(prg.curList.modeField)) == mmode || abs(int32(prg.curList.modeField)) == vmode && int32(*(*prg.mem[p].hh()).b0()) != vlistNode || abs(int32(prg.curList.modeField)) == hmode && int32(*(*prg.mem[p].hh()).b0()) != hlistNode {
  21708. {
  21709. if int32(prg.interaction) == errorStopMode {
  21710. }
  21711. prg.printNl(strNumber( /* "! " */ 262))
  21712. prg.print( /* "Incompatible list can't be unboxed" */ 1097)
  21713. }
  21714. // \xref[Incompatible list...]
  21715. {
  21716. prg.helpPtr = 3
  21717. prg.helpLine[2] = /* "Sorry, Pandora. (You sneaky devil.)" */ 1098
  21718. prg.helpLine[1] = /* "I refuse to unbox an \\hbox in vertical mode or vice versa." */ 1099
  21719. prg.helpLine[0] = /* "And I can't open any boxes in math mode." */ 1100
  21720. }
  21721. prg.error1()
  21722. goto exit
  21723. }
  21724. if int32(c) == copyCode {
  21725. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.copyNodeList(*(*prg.mem[int32(p)+listOffset].hh()).rh())
  21726. } else {
  21727. *(*prg.mem[prg.curList.tailField].hh()).rh() = *(*prg.mem[int32(p)+listOffset].hh()).rh()
  21728. *(*prg.eqtb[boxBase+prg.curVal-1].hh()).rh() = 0
  21729. prg.freeNode(p, halfword(boxNodeSize))
  21730. }
  21731. for int32(*(*prg.mem[prg.curList.tailField].hh()).rh()) != 0 {
  21732. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  21733. }
  21734. exit:
  21735. }
  21736. func (prg *prg) appendItalicCorrection() {
  21737. var (
  21738. p halfword // |char_node| at the tail of the current list
  21739. f internalFontNumber // the font in the |char_node|
  21740. )
  21741. if int32(prg.curList.tailField) != int32(prg.curList.headField) {
  21742. if int32(prg.curList.tailField) >= int32(prg.hiMemMin) {
  21743. p = prg.curList.tailField
  21744. } else if int32(*(*prg.mem[prg.curList.tailField].hh()).b0()) == ligatureNode {
  21745. p = uint16(int32(prg.curList.tailField) + 1)
  21746. } else {
  21747. goto exit
  21748. }
  21749. f = *(*prg.mem[p].hh()).b0()
  21750. {
  21751. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newKern(*prg.fontInfo[prg.italicBase[f]+(int32((*prg.fontInfo[prg.charBase[f]+int32(*(*prg.mem[p].hh()).b1())].qqqq()).b2)-minQuarterword)/4].int())
  21752. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  21753. }
  21754. *(*prg.mem[prg.curList.tailField].hh()).b1() = byte(explicit)
  21755. }
  21756. exit:
  21757. }
  21758. func (prg *prg) appendDiscretionary() {
  21759. var (
  21760. c int32 // hyphen character
  21761. )
  21762. {
  21763. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newDisc()
  21764. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  21765. }
  21766. if int32(prg.curChr) == 1 {
  21767. c = prg.hyphenChar[*(*prg.eqtb[curFontLoc-1].hh()).rh()]
  21768. if c >= 0 {
  21769. if c < 256 {
  21770. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).lh() = prg.newCharacter(internalFontNumber(*(*prg.eqtb[curFontLoc-1].hh()).rh()), eightBits(c))
  21771. }
  21772. }
  21773. } else {
  21774. prg.savePtr = uint16(int32(prg.savePtr) + 1)
  21775. *prg.saveStack[int32(prg.savePtr)+-1].int() = 0
  21776. prg.newSaveLevel(groupCode(discGroup))
  21777. prg.scanLeftBrace()
  21778. prg.pushNest()
  21779. prg.curList.modeField = int16(-hmode)
  21780. *(*prg.curList.auxField.hh()).lh() = 1000
  21781. }
  21782. }
  21783. func (prg *prg) buildDiscretionary() {
  21784. var (
  21785. p, q halfword // for link manipulation
  21786. n int32 // length of discretionary list
  21787. )
  21788. prg.unsave()
  21789. // Prune the current list, if necessary, until it contains only |char_node|, |kern_node|, |hlist_node|, |vlist_node|, |rule_node|, and |ligature_node| items; set |n| to the length of the list, and set |q| to the list's tail
  21790. q = prg.curList.headField
  21791. p = *(*prg.mem[q].hh()).rh()
  21792. n = 0
  21793. for int32(p) != 0 {
  21794. if !(int32(p) >= int32(prg.hiMemMin)) {
  21795. if int32(*(*prg.mem[p].hh()).b0()) > ruleNode {
  21796. if int32(*(*prg.mem[p].hh()).b0()) != kernNode {
  21797. if int32(*(*prg.mem[p].hh()).b0()) != ligatureNode {
  21798. {
  21799. if int32(prg.interaction) == errorStopMode {
  21800. }
  21801. prg.printNl(strNumber( /* "! " */ 262))
  21802. prg.print( /* "Improper discretionary list" */ 1107)
  21803. }
  21804. // \xref[Improper discretionary list]
  21805. {
  21806. prg.helpPtr = 1
  21807. prg.helpLine[0] = /* "Discretionary lists must contain only boxes and kerns." */ 1108
  21808. }
  21809. prg.error1()
  21810. prg.beginDiagnostic()
  21811. prg.printNl(strNumber( /* "The following discretionary sublist has been deleted:" */ 1109))
  21812. // \xref[The following...deleted]
  21813. prg.showBox(p)
  21814. prg.endDiagnostic(true)
  21815. prg.flushNodeList(p)
  21816. *(*prg.mem[q].hh()).rh() = 0
  21817. goto done
  21818. }
  21819. }
  21820. }
  21821. }
  21822. q = p
  21823. p = *(*prg.mem[q].hh()).rh()
  21824. n = n + 1
  21825. }
  21826. done:
  21827. ;
  21828. p = *(*prg.mem[prg.curList.headField].hh()).rh()
  21829. prg.popNest()
  21830. switch *prg.saveStack[int32(prg.savePtr)+-1].int() {
  21831. case 0:
  21832. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).lh() = p
  21833. case 1:
  21834. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).rh() = p
  21835. case 2:
  21836. // Attach list |p| to the current list, and record its length; then finish up and |return|
  21837. if n > 0 && abs(int32(prg.curList.modeField)) == mmode {
  21838. {
  21839. if int32(prg.interaction) == errorStopMode {
  21840. }
  21841. prg.printNl(strNumber( /* "! " */ 262))
  21842. prg.print( /* "Illegal math " */ 1101)
  21843. }
  21844. prg.printEsc(strNumber( /* "discretionary" */ 349))
  21845. // \xref[Illegal math \\disc...]
  21846. {
  21847. prg.helpPtr = 2
  21848. prg.helpLine[1] = /* "Sorry: The third part of a discretionary break must be" */ 1102
  21849. prg.helpLine[0] = /* "empty, in math formulas. I had to delete your third part." */ 1103
  21850. }
  21851. prg.flushNodeList(p)
  21852. n = 0
  21853. prg.error1()
  21854. } else {
  21855. *(*prg.mem[prg.curList.tailField].hh()).rh() = p
  21856. }
  21857. if n <= maxQuarterword {
  21858. *(*prg.mem[prg.curList.tailField].hh()).b1() = byte(n)
  21859. } else {
  21860. {
  21861. if int32(prg.interaction) == errorStopMode {
  21862. }
  21863. prg.printNl(strNumber( /* "! " */ 262))
  21864. prg.print( /* "Discretionary list is too long" */ 1104)
  21865. }
  21866. // \xref[Discretionary list is too long]
  21867. {
  21868. prg.helpPtr = 2
  21869. prg.helpLine[1] = /* "Wow---I never thought anybody would tweak me here." */ 1105
  21870. prg.helpLine[0] = /* "You can't seriously need such a huge discretionary list?" */ 1106
  21871. }
  21872. prg.error1()
  21873. }
  21874. if n > 0 {
  21875. prg.curList.tailField = q
  21876. }
  21877. prg.savePtr = uint16(int32(prg.savePtr) - 1)
  21878. goto exit
  21879. } // there are no other cases
  21880. *prg.saveStack[int32(prg.savePtr)+-1].int() = *prg.saveStack[int32(prg.savePtr)+-1].int() + 1
  21881. prg.newSaveLevel(groupCode(discGroup))
  21882. prg.scanLeftBrace()
  21883. prg.pushNest()
  21884. prg.curList.modeField = int16(-hmode)
  21885. *(*prg.curList.auxField.hh()).lh() = 1000
  21886. exit:
  21887. }
  21888. func (prg *prg) makeAccent() {
  21889. var (
  21890. s, t float64 // amount of slant
  21891. p, q, r1 halfword // character, box, and kern nodes
  21892. f internalFontNumber // relevant font
  21893. a, h, x, w, delta scaled // heights and widths, as explained above
  21894. i fourQuarters // character information
  21895. )
  21896. prg.scanCharNum()
  21897. f = byte(*(*prg.eqtb[curFontLoc-1].hh()).rh())
  21898. p = prg.newCharacter(f, eightBits(prg.curVal))
  21899. if int32(p) != 0 {
  21900. x = *prg.fontInfo[xHeightCode+prg.paramBase[f]].int()
  21901. s = float64(*prg.fontInfo[slantCode+prg.paramBase[f]].int()) / 65536.0
  21902. // \xref[real division]
  21903. a = *prg.fontInfo[prg.widthBase[f]+int32((*prg.fontInfo[prg.charBase[f]+int32(*(*prg.mem[p].hh()).b1())].qqqq()).b0)].int()
  21904. prg.doAssignments()
  21905. // Create a character node |q| for the next character, but set |q:=null| if problems arise
  21906. q = 0
  21907. f = byte(*(*prg.eqtb[curFontLoc-1].hh()).rh())
  21908. if int32(prg.curCmd) == letter || int32(prg.curCmd) == otherChar || int32(prg.curCmd) == charGiven {
  21909. q = prg.newCharacter(f, eightBits(prg.curChr))
  21910. } else if int32(prg.curCmd) == charNum {
  21911. prg.scanCharNum()
  21912. q = prg.newCharacter(f, eightBits(prg.curVal))
  21913. } else {
  21914. prg.backInput()
  21915. }
  21916. if int32(q) != 0 {
  21917. t = float64(*prg.fontInfo[slantCode+prg.paramBase[f]].int()) / 65536.0
  21918. // \xref[real division]
  21919. i = *prg.fontInfo[prg.charBase[f]+int32(*(*prg.mem[q].hh()).b1())].qqqq()
  21920. w = *prg.fontInfo[prg.widthBase[f]+int32(i.b0)].int()
  21921. h = *prg.fontInfo[prg.heightBase[f]+(int32(i.b1)-minQuarterword)/16].int()
  21922. if h != x {
  21923. p = prg.hpack(p, scaled(0), smallNumber(additional))
  21924. *prg.mem[int32(p)+4].int() = x - h
  21925. }
  21926. delta = round(float64(w-a)/2.0 + float64(h)*t - float64(x)*s)
  21927. // \xref[real multiplication]
  21928. // \xref[real addition]
  21929. r1 = prg.newKern(delta)
  21930. *(*prg.mem[r1].hh()).b1() = byte(accKern)
  21931. *(*prg.mem[prg.curList.tailField].hh()).rh() = r1
  21932. *(*prg.mem[r1].hh()).rh() = p
  21933. prg.curList.tailField = prg.newKern(-a - delta)
  21934. *(*prg.mem[prg.curList.tailField].hh()).b1() = byte(accKern)
  21935. *(*prg.mem[p].hh()).rh() = prg.curList.tailField
  21936. p = q
  21937. }
  21938. *(*prg.mem[prg.curList.tailField].hh()).rh() = p
  21939. prg.curList.tailField = p
  21940. *(*prg.curList.auxField.hh()).lh() = 1000
  21941. }
  21942. }
  21943. func (prg *prg) alignError() {
  21944. if abs(prg.alignState) > 2 {
  21945. {
  21946. if int32(prg.interaction) == errorStopMode {
  21947. }
  21948. prg.printNl(strNumber( /* "! " */ 262))
  21949. prg.print( /* "Misplaced " */ 1114)
  21950. }
  21951. prg.printCmdChr(prg.curCmd, prg.curChr)
  21952. // \xref[Misplaced \&]
  21953. // \xref[Misplaced \\span]
  21954. // \xref[Misplaced \\cr]
  21955. if int32(prg.curTok) == tabToken+'&' {
  21956. {
  21957. prg.helpPtr = 6
  21958. prg.helpLine[5] = /* "I can't figure out why you would want to use a tab mark" */ 1115
  21959. prg.helpLine[4] = /* "here. If you just want an ampersand, the remedy is" */ 1116
  21960. prg.helpLine[3] = /* "simple: Just type `I\\&' now. But if some right brace" */ 1117
  21961. prg.helpLine[2] = /* "up above has ended a previous alignment prematurely," */ 1118
  21962. prg.helpLine[1] = /* "you're probably due for more error messages, and you" */ 1119
  21963. prg.helpLine[0] = /* "might try typing `S' now just to see what is salvageable." */ 1120
  21964. }
  21965. } else {
  21966. {
  21967. prg.helpPtr = 5
  21968. prg.helpLine[4] = /* "I can't figure out why you would want to use a tab mark" */ 1115
  21969. prg.helpLine[3] = /* "or \\cr or \\span just now. If something like a right brace" */ 1121
  21970. prg.helpLine[2] = /* "up above has ended a previous alignment prematurely," */ 1118
  21971. prg.helpLine[1] = /* "you're probably due for more error messages, and you" */ 1119
  21972. prg.helpLine[0] = /* "might try typing `S' now just to see what is salvageable." */ 1120
  21973. }
  21974. }
  21975. prg.error1()
  21976. } else {
  21977. prg.backInput()
  21978. if prg.alignState < 0 {
  21979. {
  21980. if int32(prg.interaction) == errorStopMode {
  21981. }
  21982. prg.printNl(strNumber( /* "! " */ 262))
  21983. prg.print( /* "Missing [ inserted" */ 657)
  21984. }
  21985. // \xref[Missing \[ inserted]
  21986. prg.alignState = prg.alignState + 1
  21987. prg.curTok = uint16(leftBraceToken + '{')
  21988. } else {
  21989. {
  21990. if int32(prg.interaction) == errorStopMode {
  21991. }
  21992. prg.printNl(strNumber( /* "! " */ 262))
  21993. prg.print( /* "Missing ] inserted" */ 1110)
  21994. }
  21995. // \xref[Missing \] inserted]
  21996. prg.alignState = prg.alignState - 1
  21997. prg.curTok = uint16(rightBraceToken + '}')
  21998. }
  21999. {
  22000. prg.helpPtr = 3
  22001. prg.helpLine[2] = /* "I've put in what seems to be necessary to fix" */ 1111
  22002. prg.helpLine[1] = /* "the current column of the current alignment." */ 1112
  22003. prg.helpLine[0] = /* "Try to go on, since this might almost work." */ 1113
  22004. }
  22005. prg.insError()
  22006. }
  22007. }
  22008. func (prg *prg) noAlignError() {
  22009. {
  22010. if int32(prg.interaction) == errorStopMode {
  22011. }
  22012. prg.printNl(strNumber( /* "! " */ 262))
  22013. prg.print( /* "Misplaced " */ 1114)
  22014. }
  22015. prg.printEsc(strNumber( /* "noalign" */ 527))
  22016. // \xref[Misplaced \\noalign]
  22017. {
  22018. prg.helpPtr = 2
  22019. prg.helpLine[1] = /* "I expect to see \\noalign only after the \\cr of" */ 1122
  22020. prg.helpLine[0] = /* "an alignment. Proceed, and I'll ignore this case." */ 1123
  22021. }
  22022. prg.error1()
  22023. }
  22024. func (prg *prg) omitError() {
  22025. {
  22026. if int32(prg.interaction) == errorStopMode {
  22027. }
  22028. prg.printNl(strNumber( /* "! " */ 262))
  22029. prg.print( /* "Misplaced " */ 1114)
  22030. }
  22031. prg.printEsc(strNumber( /* "omit" */ 530))
  22032. // \xref[Misplaced \\omit]
  22033. {
  22034. prg.helpPtr = 2
  22035. prg.helpLine[1] = /* "I expect to see \\omit only after tab marks or the \\cr of" */ 1124
  22036. prg.helpLine[0] = /* "an alignment. Proceed, and I'll ignore this case." */ 1123
  22037. }
  22038. prg.error1()
  22039. }
  22040. func (prg *prg) doEndv() {
  22041. prg.basePtr = prg.inputPtr
  22042. prg.inputStack[prg.basePtr] = prg.curInput
  22043. for int32(prg.inputStack[prg.basePtr].indexField) != vTemplate && int32(prg.inputStack[prg.basePtr].locField) == 0 && int32(prg.inputStack[prg.basePtr].stateField) == tokenList {
  22044. prg.basePtr = byte(int32(prg.basePtr) - 1)
  22045. }
  22046. if int32(prg.inputStack[prg.basePtr].indexField) != vTemplate || int32(prg.inputStack[prg.basePtr].locField) != 0 || int32(prg.inputStack[prg.basePtr].stateField) != tokenList {
  22047. prg.fatalError(strNumber( /* "(interwoven alignment preambles are not allowed)" */ 595))
  22048. }
  22049. // \xref[interwoven alignment preambles...]
  22050. if int32(prg.curGroup) == alignGroup {
  22051. prg.endGraf()
  22052. if prg.finCol() {
  22053. prg.finRow()
  22054. }
  22055. } else {
  22056. prg.offSave()
  22057. }
  22058. }
  22059. func (prg *prg) csError() {
  22060. {
  22061. if int32(prg.interaction) == errorStopMode {
  22062. }
  22063. prg.printNl(strNumber( /* "! " */ 262))
  22064. prg.print( /* "Extra " */ 777)
  22065. }
  22066. prg.printEsc(strNumber( /* "endcsname" */ 505))
  22067. // \xref[Extra \\endcsname]
  22068. {
  22069. prg.helpPtr = 1
  22070. prg.helpLine[0] = /* "I'm ignoring this, since I wasn't doing a \\csname." */ 1126
  22071. }
  22072. prg.error1()
  22073. }
  22074. func (prg *prg) pushMath(c groupCode) {
  22075. prg.pushNest()
  22076. prg.curList.modeField = int16(-mmode)
  22077. *prg.curList.auxField.int() = 0
  22078. prg.newSaveLevel(c)
  22079. }
  22080. func (prg *prg) initMath() {
  22081. var (
  22082. w scaled // new or partial |pre_display_size|
  22083. l scaled // new |display_width|
  22084. s scaled // new |display_indent|
  22085. p halfword // current node when calculating |pre_display_size|
  22086. q halfword // glue specification when calculating |pre_display_size|
  22087. f internalFontNumber // font in current |char_node|
  22088. n int32 // scope of paragraph shape specification
  22089. v scaled // |w| plus possible glue amount
  22090. d scaled // increment to |v|
  22091. )
  22092. prg.getToken() // |get_x_token| would fail on \.[\\ifmmode]\thinspace!
  22093. if int32(prg.curCmd) == mathShift && int32(prg.curList.modeField) > 0 {
  22094. if int32(prg.curList.headField) == int32(prg.curList.tailField) {
  22095. prg.popNest()
  22096. w = -07777777777
  22097. } else {
  22098. prg.lineBreak(*prg.eqtb[intBase+displayWidowPenaltyCode-1].int())
  22099. // Calculate the natural width, |w|, by which the characters of the final line extend to the right of the reference point, plus two ems; or set |w:=max_dimen| if the non-blank information on that line is affected by stretching or shrinking
  22100. v = *prg.mem[int32(prg.justBox)+4].int() + 2**prg.fontInfo[quadCode+prg.paramBase[*(*prg.eqtb[curFontLoc-1].hh()).rh()]].int()
  22101. w = -07777777777
  22102. p = *(*prg.mem[int32(prg.justBox)+listOffset].hh()).rh()
  22103. for int32(p) != 0 {
  22104. // Let |d| be the natural width of node |p|; if the node is “visible,” |goto found|; if the node is glue that stretches or shrinks, set |v:=max_dimen|
  22105. reswitch:
  22106. if int32(p) >= int32(prg.hiMemMin) {
  22107. f = *(*prg.mem[p].hh()).b0()
  22108. d = *prg.fontInfo[prg.widthBase[f]+int32((*prg.fontInfo[prg.charBase[f]+int32(*(*prg.mem[p].hh()).b1())].qqqq()).b0)].int()
  22109. goto found
  22110. }
  22111. switch *(*prg.mem[p].hh()).b0() {
  22112. case hlistNode, vlistNode, ruleNode:
  22113. d = *prg.mem[int32(p)+widthOffset].int()
  22114. goto found
  22115. case ligatureNode:
  22116. // Make node |p| look like a |char_node|...
  22117. prg.mem[30000-12] = prg.mem[int32(p)+1]
  22118. *(*prg.mem[30000-12].hh()).rh() = *(*prg.mem[p].hh()).rh()
  22119. p = uint16(30000 - 12)
  22120. goto reswitch
  22121. case kernNode, mathNode:
  22122. d = *prg.mem[int32(p)+widthOffset].int()
  22123. case glueNode:
  22124. // Let |d| be the natural width of this glue; if stretching or shrinking, set |v:=max_dimen|; |goto found| in the case of leaders
  22125. q = *(*prg.mem[int32(p)+1].hh()).lh()
  22126. d = *prg.mem[int32(q)+widthOffset].int()
  22127. if int32(*(*prg.mem[int32(prg.justBox)+listOffset].hh()).b0()) == stretching {
  22128. if int32(*(*prg.mem[int32(prg.justBox)+listOffset].hh()).b1()) == int32(*(*prg.mem[q].hh()).b0()) && *prg.mem[int32(q)+2].int() != 0 {
  22129. v = 07777777777
  22130. }
  22131. } else if int32(*(*prg.mem[int32(prg.justBox)+listOffset].hh()).b0()) == shrinking {
  22132. if int32(*(*prg.mem[int32(prg.justBox)+listOffset].hh()).b1()) == int32(*(*prg.mem[q].hh()).b1()) && *prg.mem[int32(q)+3].int() != 0 {
  22133. v = 07777777777
  22134. }
  22135. }
  22136. if int32(*(*prg.mem[p].hh()).b1()) >= aLeaders {
  22137. goto found
  22138. }
  22139. case whatsitNode:
  22140. // Let |d| be the width of the whatsit |p|
  22141. d = 0
  22142. default:
  22143. d = 0
  22144. }
  22145. if v < 07777777777 {
  22146. v = v + d
  22147. }
  22148. goto notFound
  22149. found:
  22150. if v < 07777777777 {
  22151. v = v + d
  22152. w = v
  22153. } else {
  22154. w = 07777777777
  22155. goto done
  22156. }
  22157. notFound:
  22158. p = *(*prg.mem[p].hh()).rh()
  22159. }
  22160. done:
  22161. }
  22162. // now we are in vertical mode, working on the list that will contain the display
  22163. // Calculate the length, |l|, and the shift amount, |s|, of the display lines
  22164. if int32(*(*prg.eqtb[parShapeLoc-1].hh()).rh()) == 0 {
  22165. if *prg.eqtb[dimenBase+hangIndentCode-1].int() != 0 && (*prg.eqtb[intBase+hangAfterCode-1].int() >= 0 && prg.curList.pgField+2 > *prg.eqtb[intBase+hangAfterCode-1].int() || prg.curList.pgField+1 < -*prg.eqtb[intBase+hangAfterCode-1].int()) {
  22166. l = *prg.eqtb[dimenBase+hsizeCode-1].int() - abs(*prg.eqtb[dimenBase+hangIndentCode-1].int())
  22167. if *prg.eqtb[dimenBase+hangIndentCode-1].int() > 0 {
  22168. s = *prg.eqtb[dimenBase+hangIndentCode-1].int()
  22169. } else {
  22170. s = 0
  22171. }
  22172. } else {
  22173. l = *prg.eqtb[dimenBase+hsizeCode-1].int()
  22174. s = 0
  22175. }
  22176. } else {
  22177. n = int32(*(*prg.mem[*(*prg.eqtb[parShapeLoc-1].hh()).rh()].hh()).lh())
  22178. if prg.curList.pgField+2 >= n {
  22179. p = uint16(int32(*(*prg.eqtb[parShapeLoc-1].hh()).rh()) + 2*n)
  22180. } else {
  22181. p = uint16(int32(*(*prg.eqtb[parShapeLoc-1].hh()).rh()) + 2*(prg.curList.pgField+2))
  22182. }
  22183. s = *prg.mem[int32(p)-1].int()
  22184. l = *prg.mem[p].int()
  22185. }
  22186. prg.pushMath(groupCode(mathShiftGroup))
  22187. prg.curList.modeField = int16(mmode)
  22188. prg.eqWordDefine(halfword(intBase+curFamCode), -1)
  22189. prg.eqWordDefine(halfword(dimenBase+preDisplaySizeCode), w)
  22190. prg.eqWordDefine(halfword(dimenBase+displayWidthCode), l)
  22191. prg.eqWordDefine(halfword(dimenBase+displayIndentCode), s)
  22192. if int32(*(*prg.eqtb[everyDisplayLoc-1].hh()).rh()) != 0 {
  22193. prg.beginTokenList(*(*prg.eqtb[everyDisplayLoc-1].hh()).rh(), quarterword(everyDisplayText))
  22194. }
  22195. if int32(prg.nestPtr) == 1 {
  22196. prg.buildPage()
  22197. }
  22198. } else {
  22199. prg.backInput()
  22200. // Go into ordinary math mode
  22201. {
  22202. prg.pushMath(groupCode(mathShiftGroup))
  22203. prg.eqWordDefine(halfword(intBase+curFamCode), -1)
  22204. if int32(*(*prg.eqtb[everyMathLoc-1].hh()).rh()) != 0 {
  22205. prg.beginTokenList(*(*prg.eqtb[everyMathLoc-1].hh()).rh(), quarterword(everyMathText))
  22206. }
  22207. }
  22208. }
  22209. }
  22210. func (prg *prg) startEqNo() {
  22211. *prg.saveStack[int32(prg.savePtr)+0].int() = int32(prg.curChr)
  22212. prg.savePtr = uint16(int32(prg.savePtr) + 1)
  22213. // Go into ordinary math mode
  22214. {
  22215. prg.pushMath(groupCode(mathShiftGroup))
  22216. prg.eqWordDefine(halfword(intBase+curFamCode), -1)
  22217. if int32(*(*prg.eqtb[everyMathLoc-1].hh()).rh()) != 0 {
  22218. prg.beginTokenList(*(*prg.eqtb[everyMathLoc-1].hh()).rh(), quarterword(everyMathText))
  22219. }
  22220. }
  22221. }
  22222. func (prg *prg) scanMath(p halfword) {
  22223. var (
  22224. c int32 // math character code
  22225. )
  22226. restart:
  22227. for {
  22228. prg.getXToken()
  22229. if int32(prg.curCmd) != spacer && int32(prg.curCmd) != relax {
  22230. break
  22231. }
  22232. }
  22233. reswitch:
  22234. switch prg.curCmd {
  22235. case letter, otherChar, charGiven:
  22236. c = int32(*(*prg.eqtb[mathCodeBase+int32(prg.curChr)-1].hh()).rh()) - 0
  22237. if c == 0100000 {
  22238. {
  22239. prg.curCs = uint16(int32(prg.curChr) + activeBase)
  22240. prg.curCmd = *(*prg.eqtb[prg.curCs-1].hh()).b0()
  22241. prg.curChr = *(*prg.eqtb[prg.curCs-1].hh()).rh()
  22242. prg.xToken()
  22243. prg.backInput()
  22244. }
  22245. goto restart
  22246. }
  22247. case charNum:
  22248. prg.scanCharNum()
  22249. prg.curChr = uint16(prg.curVal)
  22250. prg.curCmd = byte(charGiven)
  22251. goto reswitch
  22252. case mathCharNum:
  22253. prg.scanFifteenBitInt()
  22254. c = prg.curVal
  22255. case mathGiven:
  22256. c = int32(prg.curChr)
  22257. case delimNum:
  22258. prg.scanTwentySevenBitInt()
  22259. c = prg.curVal / 010000
  22260. default:
  22261. prg.backInput()
  22262. prg.scanLeftBrace()
  22263. *prg.saveStack[int32(prg.savePtr)+0].int() = int32(p)
  22264. prg.savePtr = uint16(int32(prg.savePtr) + 1)
  22265. prg.pushMath(groupCode(mathGroup))
  22266. goto exit
  22267. }
  22268. *(*prg.mem[p].hh()).rh() = uint16(mathChar)
  22269. *(*prg.mem[p].hh()).b1() = byte(c%256 + minQuarterword)
  22270. if c >= 070000 && (*prg.eqtb[intBase+curFamCode-1].int() >= 0 && *prg.eqtb[intBase+curFamCode-1].int() < 16) {
  22271. *(*prg.mem[p].hh()).b0() = byte(*prg.eqtb[intBase+curFamCode-1].int())
  22272. } else {
  22273. *(*prg.mem[p].hh()).b0() = byte(c / 256 % 16)
  22274. }
  22275. exit:
  22276. }
  22277. func (prg *prg) setMathChar(c int32) {
  22278. var (
  22279. p halfword // the new noad
  22280. )
  22281. if c >= 0100000 {
  22282. prg.curCs = uint16(int32(prg.curChr) + activeBase)
  22283. prg.curCmd = *(*prg.eqtb[prg.curCs-1].hh()).b0()
  22284. prg.curChr = *(*prg.eqtb[prg.curCs-1].hh()).rh()
  22285. prg.xToken()
  22286. prg.backInput()
  22287. } else {
  22288. p = prg.newNoad()
  22289. *(*prg.mem[int32(p)+1].hh()).rh() = uint16(mathChar)
  22290. *(*prg.mem[int32(p)+1].hh()).b1() = byte(c%256 + minQuarterword)
  22291. *(*prg.mem[int32(p)+1].hh()).b0() = byte(c / 256 % 16)
  22292. if c >= 070000 {
  22293. if *prg.eqtb[intBase+curFamCode-1].int() >= 0 && *prg.eqtb[intBase+curFamCode-1].int() < 16 {
  22294. *(*prg.mem[int32(p)+1].hh()).b0() = byte(*prg.eqtb[intBase+curFamCode-1].int())
  22295. }
  22296. *(*prg.mem[p].hh()).b0() = byte(ordNoad)
  22297. } else {
  22298. *(*prg.mem[p].hh()).b0() = byte(ordNoad + c/010000)
  22299. }
  22300. *(*prg.mem[prg.curList.tailField].hh()).rh() = p
  22301. prg.curList.tailField = p
  22302. }
  22303. }
  22304. func (prg *prg) mathLimitSwitch() {
  22305. if int32(prg.curList.headField) != int32(prg.curList.tailField) {
  22306. if int32(*(*prg.mem[prg.curList.tailField].hh()).b0()) == opNoad {
  22307. *(*prg.mem[prg.curList.tailField].hh()).b1() = byte(prg.curChr)
  22308. goto exit
  22309. }
  22310. }
  22311. {
  22312. if int32(prg.interaction) == errorStopMode {
  22313. }
  22314. prg.printNl(strNumber( /* "! " */ 262))
  22315. prg.print( /* "Limit controls must follow a math operator" */ 1130)
  22316. }
  22317. // \xref[Limit controls must follow...]
  22318. {
  22319. prg.helpPtr = 1
  22320. prg.helpLine[0] = /* "I'm ignoring this misplaced \\limits or \\nolimits command." */ 1131
  22321. }
  22322. prg.error1()
  22323. exit:
  22324. }
  22325. func (prg *prg) scanDelimiter(p halfword, r1 bool) {
  22326. if r1 {
  22327. prg.scanTwentySevenBitInt()
  22328. } else {
  22329. for {
  22330. prg.getXToken()
  22331. if int32(prg.curCmd) != spacer && int32(prg.curCmd) != relax {
  22332. break
  22333. }
  22334. }
  22335. switch prg.curCmd {
  22336. case letter, otherChar:
  22337. prg.curVal = *prg.eqtb[delCodeBase+int32(prg.curChr)-1].int()
  22338. case delimNum:
  22339. prg.scanTwentySevenBitInt()
  22340. default:
  22341. prg.curVal = -1
  22342. }
  22343. }
  22344. if prg.curVal < 0 {
  22345. {
  22346. if int32(prg.interaction) == errorStopMode {
  22347. }
  22348. prg.printNl(strNumber( /* "! " */ 262))
  22349. prg.print( /* "Missing delimiter (. inserted)" */ 1132)
  22350. }
  22351. // \xref[Missing delimiter...]
  22352. {
  22353. prg.helpPtr = 6
  22354. prg.helpLine[5] = /* "I was expecting to see something like `(' or `\\[' or" */ 1133
  22355. prg.helpLine[4] = /* "`\\]' here. If you typed, e.g., `[' instead of `\\[', you" */ 1134
  22356. prg.helpLine[3] = /* "should probably delete the `[' by typing `1' now, so that" */ 1135
  22357. prg.helpLine[2] = /* "braces don't get unbalanced. Otherwise just proceed." */ 1136
  22358. prg.helpLine[1] = /* "Acceptable delimiters are characters whose \\delcode is" */ 1137
  22359. prg.helpLine[0] = /* "nonnegative, or you can use `\\delimiter <delimiter code>'." */ 1138
  22360. }
  22361. prg.backError()
  22362. prg.curVal = 0
  22363. }
  22364. (*prg.mem[p].qqqq()).b0 = byte(prg.curVal / 04000000 % 16)
  22365. (*prg.mem[p].qqqq()).b1 = byte(prg.curVal/010000%256 + minQuarterword)
  22366. (*prg.mem[p].qqqq()).b2 = byte(prg.curVal / 256 % 16)
  22367. (*prg.mem[p].qqqq()).b3 = byte(prg.curVal%256 + minQuarterword)
  22368. }
  22369. func (prg *prg) mathRadical() {
  22370. {
  22371. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.getNode(radicalNoadSize)
  22372. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  22373. }
  22374. *(*prg.mem[prg.curList.tailField].hh()).b0() = byte(radicalNoad)
  22375. *(*prg.mem[prg.curList.tailField].hh()).b1() = byte(normal)
  22376. *prg.mem[int32(prg.curList.tailField)+1].hh() = prg.emptyField
  22377. *prg.mem[int32(prg.curList.tailField)+3].hh() = prg.emptyField
  22378. *prg.mem[int32(prg.curList.tailField)+2].hh() = prg.emptyField
  22379. prg.scanDelimiter(halfword(int32(prg.curList.tailField)+4), true)
  22380. prg.scanMath(halfword(int32(prg.curList.tailField) + 1))
  22381. }
  22382. func (prg *prg) mathAc() {
  22383. if int32(prg.curCmd) == accent {
  22384. {
  22385. if int32(prg.interaction) == errorStopMode {
  22386. }
  22387. prg.printNl(strNumber( /* "! " */ 262))
  22388. prg.print( /* "Please use " */ 1139)
  22389. }
  22390. prg.printEsc(strNumber( /* "mathaccent" */ 523))
  22391. prg.print( /* " for accents in math mode" */ 1140)
  22392. // \xref[Please use \\mathaccent...]
  22393. {
  22394. prg.helpPtr = 2
  22395. prg.helpLine[1] = /* "I'm changing \\accent to \\mathaccent here; wish me luck." */ 1141
  22396. prg.helpLine[0] = /* "(Accents are not the same in formulas as they are in text.)" */ 1142
  22397. }
  22398. prg.error1()
  22399. }
  22400. {
  22401. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.getNode(accentNoadSize)
  22402. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  22403. }
  22404. *(*prg.mem[prg.curList.tailField].hh()).b0() = byte(accentNoad)
  22405. *(*prg.mem[prg.curList.tailField].hh()).b1() = byte(normal)
  22406. *prg.mem[int32(prg.curList.tailField)+1].hh() = prg.emptyField
  22407. *prg.mem[int32(prg.curList.tailField)+3].hh() = prg.emptyField
  22408. *prg.mem[int32(prg.curList.tailField)+2].hh() = prg.emptyField
  22409. *(*prg.mem[int32(prg.curList.tailField)+4].hh()).rh() = uint16(mathChar)
  22410. prg.scanFifteenBitInt()
  22411. *(*prg.mem[int32(prg.curList.tailField)+4].hh()).b1() = byte(prg.curVal%256 + minQuarterword)
  22412. if prg.curVal >= 070000 && (*prg.eqtb[intBase+curFamCode-1].int() >= 0 && *prg.eqtb[intBase+curFamCode-1].int() < 16) {
  22413. *(*prg.mem[int32(prg.curList.tailField)+4].hh()).b0() = byte(*prg.eqtb[intBase+curFamCode-1].int())
  22414. } else {
  22415. *(*prg.mem[int32(prg.curList.tailField)+4].hh()).b0() = byte(prg.curVal / 256 % 16)
  22416. }
  22417. prg.scanMath(halfword(int32(prg.curList.tailField) + 1))
  22418. }
  22419. func (prg *prg) appendChoices() {
  22420. {
  22421. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newChoice()
  22422. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  22423. }
  22424. prg.savePtr = uint16(int32(prg.savePtr) + 1)
  22425. *prg.saveStack[int32(prg.savePtr)+-1].int() = 0
  22426. prg.pushMath(groupCode(mathChoiceGroup))
  22427. prg.scanLeftBrace()
  22428. }
  22429. // \4
  22430. // Declare the function called |fin_mlist|
  22431. func (prg *prg) finMlist(p halfword) (r halfword) {
  22432. var (
  22433. q halfword // the mlist to return
  22434. )
  22435. if *prg.curList.auxField.int() != 0 {
  22436. *(*prg.mem[*prg.curList.auxField.int()+3].hh()).rh() = uint16(subMlist)
  22437. *(*prg.mem[*prg.curList.auxField.int()+3].hh()).lh() = *(*prg.mem[prg.curList.headField].hh()).rh()
  22438. if int32(p) == 0 {
  22439. q = uint16(*prg.curList.auxField.int())
  22440. } else {
  22441. q = *(*prg.mem[*prg.curList.auxField.int()+2].hh()).lh()
  22442. if int32(*(*prg.mem[q].hh()).b0()) != leftNoad {
  22443. prg.confusion(strNumber( /* "right" */ 877))
  22444. }
  22445. // \xref[this can't happen right][\quad right]
  22446. *(*prg.mem[*prg.curList.auxField.int()+2].hh()).lh() = *(*prg.mem[q].hh()).rh()
  22447. *(*prg.mem[q].hh()).rh() = uint16(*prg.curList.auxField.int())
  22448. *(*prg.mem[*prg.curList.auxField.int()].hh()).rh() = p
  22449. }
  22450. } else {
  22451. *(*prg.mem[prg.curList.tailField].hh()).rh() = p
  22452. q = *(*prg.mem[prg.curList.headField].hh()).rh()
  22453. }
  22454. prg.popNest()
  22455. r = q
  22456. return r
  22457. }
  22458. //
  22459. func (prg *prg) buildChoices() {
  22460. var (
  22461. p halfword // the current mlist
  22462. )
  22463. prg.unsave()
  22464. p = prg.finMlist(halfword(0))
  22465. switch *prg.saveStack[int32(prg.savePtr)+-1].int() {
  22466. case 0:
  22467. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).lh() = p
  22468. case 1:
  22469. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).rh() = p
  22470. case 2:
  22471. *(*prg.mem[int32(prg.curList.tailField)+2].hh()).lh() = p
  22472. case 3:
  22473. *(*prg.mem[int32(prg.curList.tailField)+2].hh()).rh() = p
  22474. prg.savePtr = uint16(int32(prg.savePtr) - 1)
  22475. goto exit
  22476. } // there are no other cases
  22477. *prg.saveStack[int32(prg.savePtr)+-1].int() = *prg.saveStack[int32(prg.savePtr)+-1].int() + 1
  22478. prg.pushMath(groupCode(mathChoiceGroup))
  22479. prg.scanLeftBrace()
  22480. exit:
  22481. }
  22482. func (prg *prg) subSup() {
  22483. var (
  22484. t smallNumber // type of previous sub/superscript
  22485. p halfword // field to be filled by |scan_math|
  22486. )
  22487. t = byte(empty)
  22488. p = 0
  22489. if int32(prg.curList.tailField) != int32(prg.curList.headField) {
  22490. if int32(*(*prg.mem[prg.curList.tailField].hh()).b0()) >= ordNoad && int32(*(*prg.mem[prg.curList.tailField].hh()).b0()) < leftNoad {
  22491. p = uint16(int32(prg.curList.tailField) + 2 + int32(prg.curCmd) - supMark) // |supscr| or |subscr|
  22492. t = byte(*(*prg.mem[p].hh()).rh())
  22493. }
  22494. }
  22495. if int32(p) == 0 || int32(t) != empty {
  22496. {
  22497. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newNoad()
  22498. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  22499. }
  22500. p = uint16(int32(prg.curList.tailField) + 2 + int32(prg.curCmd) - supMark) // |supscr| or |subscr|
  22501. if int32(t) != empty {
  22502. if int32(prg.curCmd) == supMark {
  22503. {
  22504. if int32(prg.interaction) == errorStopMode {
  22505. }
  22506. prg.printNl(strNumber( /* "! " */ 262))
  22507. prg.print( /* "Double superscript" */ 1143)
  22508. }
  22509. // \xref[Double superscript]
  22510. {
  22511. prg.helpPtr = 1
  22512. prg.helpLine[0] = /* "I treat `x^1^2' essentially like `x^1[]^2'." */ 1144
  22513. }
  22514. } else {
  22515. {
  22516. if int32(prg.interaction) == errorStopMode {
  22517. }
  22518. prg.printNl(strNumber( /* "! " */ 262))
  22519. prg.print( /* "Double subscript" */ 1145)
  22520. }
  22521. // \xref[Double subscript]
  22522. {
  22523. prg.helpPtr = 1
  22524. prg.helpLine[0] = /* "I treat `x_1_2' essentially like `x_1[]_2'." */ 1146
  22525. }
  22526. }
  22527. prg.error1()
  22528. }
  22529. }
  22530. prg.scanMath(p)
  22531. }
  22532. func (prg *prg) mathFraction() {
  22533. var (
  22534. c smallNumber // the type of generalized fraction we are scanning
  22535. )
  22536. c = byte(prg.curChr)
  22537. if *prg.curList.auxField.int() != 0 {
  22538. if int32(c) >= delimitedCode {
  22539. prg.scanDelimiter(halfword(30000-12), false)
  22540. prg.scanDelimiter(halfword(30000-12), false)
  22541. }
  22542. if int32(c)%delimitedCode == aboveCode {
  22543. prg.scanDimen(false, false, false)
  22544. }
  22545. {
  22546. if int32(prg.interaction) == errorStopMode {
  22547. }
  22548. prg.printNl(strNumber( /* "! " */ 262))
  22549. prg.print( /* "Ambiguous; you need another [ and ]" */ 1153)
  22550. }
  22551. // \xref[Ambiguous...]
  22552. {
  22553. prg.helpPtr = 3
  22554. prg.helpLine[2] = /* "I'm ignoring this fraction specification, since I don't" */ 1154
  22555. prg.helpLine[1] = /* "know whether a construction like `x \\over y \\over z'" */ 1155
  22556. prg.helpLine[0] = /* "means `[x \\over y] \\over z' or `x \\over [y \\over z]'." */ 1156
  22557. }
  22558. prg.error1()
  22559. } else {
  22560. *prg.curList.auxField.int() = int32(prg.getNode(fractionNoadSize))
  22561. *(*prg.mem[*prg.curList.auxField.int()].hh()).b0() = byte(fractionNoad)
  22562. *(*prg.mem[*prg.curList.auxField.int()].hh()).b1() = byte(normal)
  22563. *(*prg.mem[*prg.curList.auxField.int()+2].hh()).rh() = uint16(subMlist)
  22564. *(*prg.mem[*prg.curList.auxField.int()+2].hh()).lh() = *(*prg.mem[prg.curList.headField].hh()).rh()
  22565. *prg.mem[*prg.curList.auxField.int()+3].hh() = prg.emptyField
  22566. *prg.mem[*prg.curList.auxField.int()+4].qqqq() = prg.nullDelimiter
  22567. *prg.mem[*prg.curList.auxField.int()+5].qqqq() = prg.nullDelimiter
  22568. *(*prg.mem[prg.curList.headField].hh()).rh() = 0
  22569. prg.curList.tailField = prg.curList.headField
  22570. // Use code |c| to distinguish between generalized fractions
  22571. if int32(c) >= delimitedCode {
  22572. prg.scanDelimiter(halfword(*prg.curList.auxField.int()+4), false)
  22573. prg.scanDelimiter(halfword(*prg.curList.auxField.int()+5), false)
  22574. }
  22575. switch int32(c) % delimitedCode {
  22576. case aboveCode:
  22577. prg.scanDimen(false, false, false)
  22578. *prg.mem[*prg.curList.auxField.int()+widthOffset].int() = prg.curVal
  22579. case overCode:
  22580. *prg.mem[*prg.curList.auxField.int()+widthOffset].int() = 010000000000
  22581. case atopCode:
  22582. *prg.mem[*prg.curList.auxField.int()+widthOffset].int() = 0
  22583. }
  22584. }
  22585. }
  22586. func (prg *prg) mathLeftRight() {
  22587. var (
  22588. t smallNumber // |left_noad| or |right_noad|
  22589. p halfword // new noad
  22590. )
  22591. t = byte(prg.curChr)
  22592. if int32(t) == rightNoad && int32(prg.curGroup) != mathLeftGroup {
  22593. if int32(prg.curGroup) == mathShiftGroup {
  22594. prg.scanDelimiter(halfword(30000-12), false)
  22595. {
  22596. if int32(prg.interaction) == errorStopMode {
  22597. }
  22598. prg.printNl(strNumber( /* "! " */ 262))
  22599. prg.print( /* "Extra " */ 777)
  22600. }
  22601. prg.printEsc(strNumber( /* "right" */ 877))
  22602. // \xref[Extra \\right.]
  22603. {
  22604. prg.helpPtr = 1
  22605. prg.helpLine[0] = /* "I'm ignoring a \\right that had no matching \\left." */ 1157
  22606. }
  22607. prg.error1()
  22608. } else {
  22609. prg.offSave()
  22610. }
  22611. } else {
  22612. p = prg.newNoad()
  22613. *(*prg.mem[p].hh()).b0() = t
  22614. prg.scanDelimiter(halfword(int32(p)+1), false)
  22615. if int32(t) == leftNoad {
  22616. prg.pushMath(groupCode(mathLeftGroup))
  22617. *(*prg.mem[prg.curList.headField].hh()).rh() = p
  22618. prg.curList.tailField = p
  22619. } else {
  22620. p = prg.finMlist(p)
  22621. prg.unsave() // end of |math_left_group|
  22622. {
  22623. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newNoad()
  22624. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  22625. }
  22626. *(*prg.mem[prg.curList.tailField].hh()).b0() = byte(innerNoad)
  22627. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).rh() = uint16(subMlist)
  22628. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).lh() = p
  22629. }
  22630. }
  22631. }
  22632. func (prg *prg) afterMath() {
  22633. var (
  22634. l bool // `\.[\\leqno]' instead of `\.[\\eqno]'
  22635. danger bool // not enough symbol fonts are present
  22636. m int32 // |mmode| or |-mmode|
  22637. p halfword // the formula
  22638. a halfword // box containing equation number
  22639. // Local variables for finishing a displayed formula
  22640. b halfword // box containing the equation
  22641. w scaled // width of the equation
  22642. z scaled // width of the line
  22643. e scaled // width of equation number
  22644. q scaled // width of equation number plus space to separate from equation
  22645. d scaled // displacement of equation in the line
  22646. s scaled // move the line right this much
  22647. g1, g2 smallNumber // glue parameter codes for before and after
  22648. r1 halfword // kern node used to position the display
  22649. t halfword // tail of adjustment list
  22650. )
  22651. danger = false
  22652. // Check that the necessary fonts for math symbols are present; if not, flush the current math lists and set |danger:=true|
  22653. if int32(prg.fontParams[*(*prg.eqtb[mathFontBase+2+textSize-1].hh()).rh()]) < totalMathsyParams || int32(prg.fontParams[*(*prg.eqtb[mathFontBase+2+scriptSize-1].hh()).rh()]) < totalMathsyParams || int32(prg.fontParams[*(*prg.eqtb[mathFontBase+2+scriptScriptSize-1].hh()).rh()]) < totalMathsyParams {
  22654. {
  22655. if int32(prg.interaction) == errorStopMode {
  22656. }
  22657. prg.printNl(strNumber( /* "! " */ 262))
  22658. prg.print( /* "Math formula deleted: Insufficient symbol fonts" */ 1158)
  22659. }
  22660. // \xref[Math formula deleted...]
  22661. {
  22662. prg.helpPtr = 3
  22663. prg.helpLine[2] = /* "Sorry, but I can't typeset math unless \\textfont 2" */ 1159
  22664. prg.helpLine[1] = /* "and \\scriptfont 2 and \\scriptscriptfont 2 have all" */ 1160
  22665. prg.helpLine[0] = /* "the \\fontdimen values needed in math symbol fonts." */ 1161
  22666. }
  22667. prg.error1()
  22668. prg.flushMath()
  22669. danger = true
  22670. } else if int32(prg.fontParams[*(*prg.eqtb[mathFontBase+3+textSize-1].hh()).rh()]) < totalMathexParams || int32(prg.fontParams[*(*prg.eqtb[mathFontBase+3+scriptSize-1].hh()).rh()]) < totalMathexParams || int32(prg.fontParams[*(*prg.eqtb[mathFontBase+3+scriptScriptSize-1].hh()).rh()]) < totalMathexParams {
  22671. {
  22672. if int32(prg.interaction) == errorStopMode {
  22673. }
  22674. prg.printNl(strNumber( /* "! " */ 262))
  22675. prg.print( /* "Math formula deleted: Insufficient extension fonts" */ 1162)
  22676. }
  22677. {
  22678. prg.helpPtr = 3
  22679. prg.helpLine[2] = /* "Sorry, but I can't typeset math unless \\textfont 3" */ 1163
  22680. prg.helpLine[1] = /* "and \\scriptfont 3 and \\scriptscriptfont 3 have all" */ 1164
  22681. prg.helpLine[0] = /* "the \\fontdimen values needed in math extension fonts." */ 1165
  22682. }
  22683. prg.error1()
  22684. prg.flushMath()
  22685. danger = true
  22686. }
  22687. m = int32(prg.curList.modeField)
  22688. l = false
  22689. p = prg.finMlist(halfword(0)) // this pops the nest
  22690. if int32(prg.curList.modeField) == -m {
  22691. {
  22692. prg.getXToken()
  22693. if int32(prg.curCmd) != mathShift {
  22694. {
  22695. if int32(prg.interaction) == errorStopMode {
  22696. }
  22697. prg.printNl(strNumber( /* "! " */ 262))
  22698. prg.print( /* "Display math should end with $$" */ 1166)
  22699. }
  22700. // \xref[Display math...with \$\$]
  22701. {
  22702. prg.helpPtr = 2
  22703. prg.helpLine[1] = /* "The `$' that I just saw supposedly matches a previous `$$'." */ 1167
  22704. prg.helpLine[0] = /* "So I shall assume that you typed `$$' both times." */ 1168
  22705. }
  22706. prg.backError()
  22707. }
  22708. }
  22709. prg.curMlist = p
  22710. prg.curStyle = byte(textStyle)
  22711. prg.mlistPenalties = false
  22712. prg.mlistToHlist()
  22713. a = prg.hpack(*(*prg.mem[30000-3].hh()).rh(), scaled(0), smallNumber(additional))
  22714. prg.unsave()
  22715. prg.savePtr = uint16(int32(prg.savePtr) - 1) // now |cur_group=math_shift_group|
  22716. if *prg.saveStack[int32(prg.savePtr)+0].int() == 1 {
  22717. l = true
  22718. }
  22719. danger = false
  22720. // Check that the necessary fonts for math symbols are present; if not, flush the current math lists and set |danger:=true|
  22721. if int32(prg.fontParams[*(*prg.eqtb[mathFontBase+2+textSize-1].hh()).rh()]) < totalMathsyParams || int32(prg.fontParams[*(*prg.eqtb[mathFontBase+2+scriptSize-1].hh()).rh()]) < totalMathsyParams || int32(prg.fontParams[*(*prg.eqtb[mathFontBase+2+scriptScriptSize-1].hh()).rh()]) < totalMathsyParams {
  22722. {
  22723. if int32(prg.interaction) == errorStopMode {
  22724. }
  22725. prg.printNl(strNumber( /* "! " */ 262))
  22726. prg.print( /* "Math formula deleted: Insufficient symbol fonts" */ 1158)
  22727. }
  22728. // \xref[Math formula deleted...]
  22729. {
  22730. prg.helpPtr = 3
  22731. prg.helpLine[2] = /* "Sorry, but I can't typeset math unless \\textfont 2" */ 1159
  22732. prg.helpLine[1] = /* "and \\scriptfont 2 and \\scriptscriptfont 2 have all" */ 1160
  22733. prg.helpLine[0] = /* "the \\fontdimen values needed in math symbol fonts." */ 1161
  22734. }
  22735. prg.error1()
  22736. prg.flushMath()
  22737. danger = true
  22738. } else if int32(prg.fontParams[*(*prg.eqtb[mathFontBase+3+textSize-1].hh()).rh()]) < totalMathexParams || int32(prg.fontParams[*(*prg.eqtb[mathFontBase+3+scriptSize-1].hh()).rh()]) < totalMathexParams || int32(prg.fontParams[*(*prg.eqtb[mathFontBase+3+scriptScriptSize-1].hh()).rh()]) < totalMathexParams {
  22739. {
  22740. if int32(prg.interaction) == errorStopMode {
  22741. }
  22742. prg.printNl(strNumber( /* "! " */ 262))
  22743. prg.print( /* "Math formula deleted: Insufficient extension fonts" */ 1162)
  22744. }
  22745. {
  22746. prg.helpPtr = 3
  22747. prg.helpLine[2] = /* "Sorry, but I can't typeset math unless \\textfont 3" */ 1163
  22748. prg.helpLine[1] = /* "and \\scriptfont 3 and \\scriptscriptfont 3 have all" */ 1164
  22749. prg.helpLine[0] = /* "the \\fontdimen values needed in math extension fonts." */ 1165
  22750. }
  22751. prg.error1()
  22752. prg.flushMath()
  22753. danger = true
  22754. }
  22755. m = int32(prg.curList.modeField)
  22756. p = prg.finMlist(halfword(0))
  22757. } else {
  22758. a = 0
  22759. }
  22760. if m < 0 {
  22761. {
  22762. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newMath(*prg.eqtb[dimenBase+mathSurroundCode-1].int(), smallNumber(before))
  22763. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  22764. }
  22765. prg.curMlist = p
  22766. prg.curStyle = byte(textStyle)
  22767. prg.mlistPenalties = int32(prg.curList.modeField) > 0
  22768. prg.mlistToHlist()
  22769. *(*prg.mem[prg.curList.tailField].hh()).rh() = *(*prg.mem[30000-3].hh()).rh()
  22770. for int32(*(*prg.mem[prg.curList.tailField].hh()).rh()) != 0 {
  22771. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  22772. }
  22773. {
  22774. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newMath(*prg.eqtb[dimenBase+mathSurroundCode-1].int(), smallNumber(after))
  22775. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  22776. }
  22777. *(*prg.curList.auxField.hh()).lh() = 1000
  22778. prg.unsave()
  22779. } else {
  22780. if int32(a) == 0 {
  22781. prg.getXToken()
  22782. if int32(prg.curCmd) != mathShift {
  22783. {
  22784. if int32(prg.interaction) == errorStopMode {
  22785. }
  22786. prg.printNl(strNumber( /* "! " */ 262))
  22787. prg.print( /* "Display math should end with $$" */ 1166)
  22788. }
  22789. // \xref[Display math...with \$\$]
  22790. {
  22791. prg.helpPtr = 2
  22792. prg.helpLine[1] = /* "The `$' that I just saw supposedly matches a previous `$$'." */ 1167
  22793. prg.helpLine[0] = /* "So I shall assume that you typed `$$' both times." */ 1168
  22794. }
  22795. prg.backError()
  22796. }
  22797. }
  22798. // Finish displayed math
  22799. prg.curMlist = p
  22800. prg.curStyle = byte(displayStyle)
  22801. prg.mlistPenalties = false
  22802. prg.mlistToHlist()
  22803. p = *(*prg.mem[30000-3].hh()).rh()
  22804. prg.adjustTail = uint16(30000 - 5)
  22805. b = prg.hpack(p, scaled(0), smallNumber(additional))
  22806. p = *(*prg.mem[int32(b)+listOffset].hh()).rh()
  22807. t = prg.adjustTail
  22808. prg.adjustTail = 0
  22809. w = *prg.mem[int32(b)+widthOffset].int()
  22810. z = *prg.eqtb[dimenBase+displayWidthCode-1].int()
  22811. s = *prg.eqtb[dimenBase+displayIndentCode-1].int()
  22812. if int32(a) == 0 || danger {
  22813. e = 0
  22814. q = 0
  22815. } else {
  22816. e = *prg.mem[int32(a)+widthOffset].int()
  22817. q = e + *prg.fontInfo[6+prg.paramBase[*(*prg.eqtb[mathFontBase+2+textSize-1].hh()).rh()]].int()
  22818. }
  22819. if w+q > z {
  22820. if e != 0 && (w-prg.totalShrink[normal]+q <= z || prg.totalShrink[fil] != 0 || prg.totalShrink[fill] != 0 || prg.totalShrink[filll] != 0) {
  22821. prg.freeNode(b, halfword(boxNodeSize))
  22822. b = prg.hpack(p, z-q, smallNumber(exactly))
  22823. } else {
  22824. e = 0
  22825. if w > z {
  22826. prg.freeNode(b, halfword(boxNodeSize))
  22827. b = prg.hpack(p, z, smallNumber(exactly))
  22828. }
  22829. }
  22830. w = *prg.mem[int32(b)+widthOffset].int()
  22831. }
  22832. // Determine the displacement, |d|, of the left edge of the equation, with respect to the line size |z|, assuming that |l=false|
  22833. d = prg.half(z - w)
  22834. if e > 0 && d < 2*e {
  22835. d = prg.half(z - w - e)
  22836. if int32(p) != 0 {
  22837. if !(int32(p) >= int32(prg.hiMemMin)) {
  22838. if int32(*(*prg.mem[p].hh()).b0()) == glueNode {
  22839. d = 0
  22840. }
  22841. }
  22842. }
  22843. }
  22844. // Append the glue or equation number preceding the display
  22845. {
  22846. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newPenalty(*prg.eqtb[intBase+preDisplayPenaltyCode-1].int())
  22847. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  22848. }
  22849. if d+s <= *prg.eqtb[dimenBase+preDisplaySizeCode-1].int() || l {
  22850. g1 = byte(aboveDisplaySkipCode)
  22851. g2 = byte(belowDisplaySkipCode)
  22852. } else {
  22853. g1 = byte(aboveDisplayShortSkipCode)
  22854. g2 = byte(belowDisplayShortSkipCode)
  22855. }
  22856. if l && e == 0 {
  22857. *prg.mem[int32(a)+4].int() = s
  22858. prg.appendToVlist(a)
  22859. {
  22860. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newPenalty(infPenalty)
  22861. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  22862. }
  22863. } else {
  22864. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newParamGlue(g1)
  22865. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  22866. }
  22867. // Append the display and perhaps also the equation number
  22868. if e != 0 {
  22869. r1 = prg.newKern(z - w - e - d)
  22870. if l {
  22871. *(*prg.mem[a].hh()).rh() = r1
  22872. *(*prg.mem[r1].hh()).rh() = b
  22873. b = a
  22874. d = 0
  22875. } else {
  22876. *(*prg.mem[b].hh()).rh() = r1
  22877. *(*prg.mem[r1].hh()).rh() = a
  22878. }
  22879. b = prg.hpack(b, scaled(0), smallNumber(additional))
  22880. }
  22881. *prg.mem[int32(b)+4].int() = s + d
  22882. prg.appendToVlist(b)
  22883. // Append the glue or equation number following the display
  22884. if int32(a) != 0 && e == 0 && !l {
  22885. {
  22886. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newPenalty(infPenalty)
  22887. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  22888. }
  22889. *prg.mem[int32(a)+4].int() = s + z - *prg.mem[int32(a)+widthOffset].int()
  22890. prg.appendToVlist(a)
  22891. g2 = 0
  22892. }
  22893. if int32(t) != 30000-5 {
  22894. *(*prg.mem[prg.curList.tailField].hh()).rh() = *(*prg.mem[30000-5].hh()).rh()
  22895. prg.curList.tailField = t
  22896. }
  22897. {
  22898. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newPenalty(*prg.eqtb[intBase+postDisplayPenaltyCode-1].int())
  22899. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  22900. }
  22901. if int32(g2) > 0 {
  22902. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newParamGlue(g2)
  22903. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  22904. }
  22905. prg.resumeAfterDisplay()
  22906. }
  22907. } // \2
  22908. func (prg *prg) resumeAfterDisplay() {
  22909. if int32(prg.curGroup) != mathShiftGroup {
  22910. prg.confusion(strNumber( /* "display" */ 1169))
  22911. }
  22912. // \xref[this can't happen display][\quad display]
  22913. prg.unsave()
  22914. prg.curList.pgField = prg.curList.pgField + 3
  22915. prg.pushNest()
  22916. prg.curList.modeField = int16(hmode)
  22917. *(*prg.curList.auxField.hh()).lh() = 1000
  22918. if *prg.eqtb[intBase+languageCode-1].int() <= 0 {
  22919. prg.curLang = 0
  22920. } else if *prg.eqtb[intBase+languageCode-1].int() > 255 {
  22921. prg.curLang = 0
  22922. } else {
  22923. prg.curLang = byte(*prg.eqtb[intBase+languageCode-1].int())
  22924. }
  22925. *(*prg.curList.auxField.hh()).rh() = uint16(prg.curLang)
  22926. prg.curList.pgField = (int32(prg.normMin(*prg.eqtb[intBase+leftHyphenMinCode-1].int()))*0100+int32(prg.normMin(*prg.eqtb[intBase+rightHyphenMinCode-1].int())))*0200000 + int32(prg.curLang)
  22927. // Scan an optional space
  22928. {
  22929. prg.getXToken()
  22930. if int32(prg.curCmd) != spacer {
  22931. prg.backInput()
  22932. }
  22933. }
  22934. if int32(prg.nestPtr) == 1 {
  22935. prg.buildPage()
  22936. }
  22937. }
  22938. // \4
  22939. // Declare subprocedures for |prefixed_command|
  22940. func (prg *prg) getRToken() {
  22941. restart:
  22942. for {
  22943. prg.getToken()
  22944. if int32(prg.curTok) != spaceToken {
  22945. break
  22946. }
  22947. }
  22948. if int32(prg.curCs) == 0 || int32(prg.curCs) > frozenControlSequence {
  22949. {
  22950. if int32(prg.interaction) == errorStopMode {
  22951. }
  22952. prg.printNl(strNumber( /* "! " */ 262))
  22953. prg.print( /* "Missing control sequence inserted" */ 1184)
  22954. }
  22955. // \xref[Missing control...]
  22956. {
  22957. prg.helpPtr = 5
  22958. prg.helpLine[4] = /* "Please don't say `\\def cs[...]', say `\\def\\cs[...]'." */ 1185
  22959. prg.helpLine[3] = /* "I've inserted an inaccessible control sequence so that your" */ 1186
  22960. prg.helpLine[2] = /* "definition will be completed without mixing me up too badly." */ 1187
  22961. prg.helpLine[1] = /* "You can recover graciously from this error, if you're" */ 1188
  22962. prg.helpLine[0] = /* "careful; see exercise 27.2 in The TeXbook." */ 1189
  22963. }
  22964. // \xref[TeXbook][\sl The \TeX book]
  22965. if int32(prg.curCs) == 0 {
  22966. prg.backInput()
  22967. }
  22968. prg.curTok = uint16(07777 + frozenProtection)
  22969. prg.insError()
  22970. goto restart
  22971. }
  22972. }
  22973. func (prg *prg) trapZeroGlue() {
  22974. if *prg.mem[prg.curVal+widthOffset].int() == 0 && *prg.mem[prg.curVal+2].int() == 0 && *prg.mem[prg.curVal+3].int() == 0 {
  22975. *(*prg.mem[memBot].hh()).rh() = uint16(int32(*(*prg.mem[memBot].hh()).rh()) + 1)
  22976. prg.deleteGlueRef(halfword(prg.curVal))
  22977. prg.curVal = memBot
  22978. }
  22979. }
  22980. func (prg *prg) doRegisterCommand(a smallNumber) {
  22981. var (
  22982. l, q, r1, s halfword // for list manipulation
  22983. p/* intVal..muVal */ byte // type of register involved
  22984. )
  22985. q = uint16(prg.curCmd)
  22986. // Compute the register location |l| and its type |p|; but |return| if invalid
  22987. {
  22988. if int32(q) != register {
  22989. prg.getXToken()
  22990. if int32(prg.curCmd) >= assignInt && int32(prg.curCmd) <= assignMuGlue {
  22991. l = prg.curChr
  22992. p = byte(int32(prg.curCmd) - assignInt)
  22993. goto found
  22994. }
  22995. if int32(prg.curCmd) != register {
  22996. {
  22997. if int32(prg.interaction) == errorStopMode {
  22998. }
  22999. prg.printNl(strNumber( /* "! " */ 262))
  23000. prg.print( /* "You can't use `" */ 685)
  23001. }
  23002. prg.printCmdChr(prg.curCmd, prg.curChr)
  23003. // \xref[You can't use x after ...]
  23004. prg.print( /* "' after " */ 686)
  23005. prg.printCmdChr(quarterword(q), halfword(0))
  23006. {
  23007. prg.helpPtr = 1
  23008. prg.helpLine[0] = /* "I'm forgetting what you said and not changing anything." */ 1210
  23009. }
  23010. prg.error1()
  23011. goto exit
  23012. }
  23013. }
  23014. p = byte(prg.curChr)
  23015. prg.scanEightBitInt()
  23016. switch p {
  23017. case intVal:
  23018. l = uint16(prg.curVal + countBase)
  23019. case dimenVal:
  23020. l = uint16(prg.curVal + scaledBase)
  23021. case glueVal:
  23022. l = uint16(prg.curVal + skipBase)
  23023. case muVal:
  23024. l = uint16(prg.curVal + muSkipBase)
  23025. } // there are no other cases
  23026. }
  23027. found:
  23028. ;
  23029. if int32(q) == register {
  23030. prg.scanOptionalEquals()
  23031. } else if prg.scanKeyword(strNumber( /* "by" */ 1206)) {
  23032. } // optional `\.[by]'
  23033. // \xref[by]
  23034. prg.arithError = false
  23035. if int32(q) < multiply {
  23036. if int32(p) < glueVal {
  23037. if int32(p) == intVal {
  23038. prg.scanInt()
  23039. } else {
  23040. prg.scanDimen(false, false, false)
  23041. }
  23042. if int32(q) == advance {
  23043. prg.curVal = prg.curVal + *prg.eqtb[l-1].int()
  23044. }
  23045. } else {
  23046. prg.scanGlue(p)
  23047. if int32(q) == advance {
  23048. q = prg.newSpec(halfword(prg.curVal))
  23049. r1 = *(*prg.eqtb[l-1].hh()).rh()
  23050. prg.deleteGlueRef(halfword(prg.curVal))
  23051. *prg.mem[int32(q)+widthOffset].int() = *prg.mem[int32(q)+widthOffset].int() + *prg.mem[int32(r1)+widthOffset].int()
  23052. if *prg.mem[int32(q)+2].int() == 0 {
  23053. *(*prg.mem[q].hh()).b0() = byte(normal)
  23054. }
  23055. if int32(*(*prg.mem[q].hh()).b0()) == int32(*(*prg.mem[r1].hh()).b0()) {
  23056. *prg.mem[int32(q)+2].int() = *prg.mem[int32(q)+2].int() + *prg.mem[int32(r1)+2].int()
  23057. } else if int32(*(*prg.mem[q].hh()).b0()) < int32(*(*prg.mem[r1].hh()).b0()) && *prg.mem[int32(r1)+2].int() != 0 {
  23058. *prg.mem[int32(q)+2].int() = *prg.mem[int32(r1)+2].int()
  23059. *(*prg.mem[q].hh()).b0() = *(*prg.mem[r1].hh()).b0()
  23060. }
  23061. if *prg.mem[int32(q)+3].int() == 0 {
  23062. *(*prg.mem[q].hh()).b1() = byte(normal)
  23063. }
  23064. if int32(*(*prg.mem[q].hh()).b1()) == int32(*(*prg.mem[r1].hh()).b1()) {
  23065. *prg.mem[int32(q)+3].int() = *prg.mem[int32(q)+3].int() + *prg.mem[int32(r1)+3].int()
  23066. } else if int32(*(*prg.mem[q].hh()).b1()) < int32(*(*prg.mem[r1].hh()).b1()) && *prg.mem[int32(r1)+3].int() != 0 {
  23067. *prg.mem[int32(q)+3].int() = *prg.mem[int32(r1)+3].int()
  23068. *(*prg.mem[q].hh()).b1() = *(*prg.mem[r1].hh()).b1()
  23069. }
  23070. prg.curVal = int32(q)
  23071. }
  23072. }
  23073. } else {
  23074. // Compute result of |multiply| or |divide|, put it in |cur_val|
  23075. prg.scanInt()
  23076. if int32(p) < glueVal {
  23077. if int32(q) == multiply {
  23078. if int32(p) == intVal {
  23079. prg.curVal = prg.multAndAdd(*prg.eqtb[l-1].int(), prg.curVal, scaled(0), scaled(017777777777))
  23080. } else {
  23081. prg.curVal = prg.multAndAdd(*prg.eqtb[l-1].int(), prg.curVal, scaled(0), scaled(07777777777))
  23082. }
  23083. } else {
  23084. prg.curVal = prg.xOverN(*prg.eqtb[l-1].int(), prg.curVal)
  23085. }
  23086. } else {
  23087. s = *(*prg.eqtb[l-1].hh()).rh()
  23088. r1 = prg.newSpec(s)
  23089. if int32(q) == multiply {
  23090. *prg.mem[int32(r1)+widthOffset].int() = prg.multAndAdd(*prg.mem[int32(s)+widthOffset].int(), prg.curVal, scaled(0), scaled(07777777777))
  23091. *prg.mem[int32(r1)+2].int() = prg.multAndAdd(*prg.mem[int32(s)+2].int(), prg.curVal, scaled(0), scaled(07777777777))
  23092. *prg.mem[int32(r1)+3].int() = prg.multAndAdd(*prg.mem[int32(s)+3].int(), prg.curVal, scaled(0), scaled(07777777777))
  23093. } else {
  23094. *prg.mem[int32(r1)+widthOffset].int() = prg.xOverN(*prg.mem[int32(s)+widthOffset].int(), prg.curVal)
  23095. *prg.mem[int32(r1)+2].int() = prg.xOverN(*prg.mem[int32(s)+2].int(), prg.curVal)
  23096. *prg.mem[int32(r1)+3].int() = prg.xOverN(*prg.mem[int32(s)+3].int(), prg.curVal)
  23097. }
  23098. prg.curVal = int32(r1)
  23099. }
  23100. }
  23101. if prg.arithError {
  23102. {
  23103. if int32(prg.interaction) == errorStopMode {
  23104. }
  23105. prg.printNl(strNumber( /* "! " */ 262))
  23106. prg.print( /* "Arithmetic overflow" */ 1207)
  23107. }
  23108. // \xref[Arithmetic overflow]
  23109. {
  23110. prg.helpPtr = 2
  23111. prg.helpLine[1] = /* "I can't carry out that multiplication or division," */ 1208
  23112. prg.helpLine[0] = /* "since the result is out of range." */ 1209
  23113. }
  23114. if int32(p) >= glueVal {
  23115. prg.deleteGlueRef(halfword(prg.curVal))
  23116. }
  23117. prg.error1()
  23118. goto exit
  23119. }
  23120. if int32(p) < glueVal {
  23121. if int32(a) >= 4 {
  23122. prg.geqWordDefine(l, prg.curVal)
  23123. } else {
  23124. prg.eqWordDefine(l, prg.curVal)
  23125. }
  23126. } else {
  23127. prg.trapZeroGlue()
  23128. if int32(a) >= 4 {
  23129. prg.geqDefine(l, quarterword(glueRef), halfword(prg.curVal))
  23130. } else {
  23131. prg.eqDefine(l, quarterword(glueRef), halfword(prg.curVal))
  23132. }
  23133. }
  23134. exit:
  23135. }
  23136. func (prg *prg) alterAux() {
  23137. var (
  23138. c halfword // |hmode| or |vmode|
  23139. )
  23140. if int32(prg.curChr) != abs(int32(prg.curList.modeField)) {
  23141. prg.reportIllegalCase()
  23142. } else {
  23143. c = prg.curChr
  23144. prg.scanOptionalEquals()
  23145. if int32(c) == vmode {
  23146. prg.scanDimen(false, false, false)
  23147. *prg.curList.auxField.int() = prg.curVal
  23148. } else {
  23149. prg.scanInt()
  23150. if prg.curVal <= 0 || prg.curVal > 32767 {
  23151. {
  23152. if int32(prg.interaction) == errorStopMode {
  23153. }
  23154. prg.printNl(strNumber( /* "! " */ 262))
  23155. prg.print( /* "Bad space factor" */ 1213)
  23156. }
  23157. // \xref[Bad space factor]
  23158. {
  23159. prg.helpPtr = 1
  23160. prg.helpLine[0] = /* "I allow only values in the range 1..32767 here." */ 1214
  23161. }
  23162. prg.intError(prg.curVal)
  23163. } else {
  23164. *(*prg.curList.auxField.hh()).lh() = uint16(prg.curVal)
  23165. }
  23166. }
  23167. }
  23168. }
  23169. func (prg *prg) alterPrevGraf() {
  23170. var (
  23171. p /* 0..nestSize */ byte // index into |nest|
  23172. )
  23173. prg.nest[prg.nestPtr] = prg.curList
  23174. p = prg.nestPtr
  23175. for abs(int32(prg.nest[p].modeField)) != vmode {
  23176. p = byte(int32(p) - 1)
  23177. }
  23178. prg.scanOptionalEquals()
  23179. prg.scanInt()
  23180. if prg.curVal < 0 {
  23181. {
  23182. if int32(prg.interaction) == errorStopMode {
  23183. }
  23184. prg.printNl(strNumber( /* "! " */ 262))
  23185. prg.print( /* "Bad " */ 955)
  23186. }
  23187. prg.printEsc(strNumber( /* "prevgraf" */ 532))
  23188. // \xref[Bad \\prevgraf]
  23189. {
  23190. prg.helpPtr = 1
  23191. prg.helpLine[0] = /* "I allow only nonnegative values here." */ 1215
  23192. }
  23193. prg.intError(prg.curVal)
  23194. } else {
  23195. prg.nest[p].pgField = prg.curVal
  23196. prg.curList = prg.nest[prg.nestPtr]
  23197. }
  23198. }
  23199. func (prg *prg) alterPageSoFar() {
  23200. var (
  23201. c /* 0..7 */ byte // index into |page_so_far|
  23202. )
  23203. c = byte(prg.curChr)
  23204. prg.scanOptionalEquals()
  23205. prg.scanDimen(false, false, false)
  23206. prg.pageSoFar[c] = prg.curVal
  23207. }
  23208. func (prg *prg) alterInteger() {
  23209. var (
  23210. c /* 0..1 */ byte // 0 for \.[\\deadcycles], 1 for \.[\\insertpenalties]
  23211. )
  23212. c = byte(prg.curChr)
  23213. prg.scanOptionalEquals()
  23214. prg.scanInt()
  23215. if int32(c) == 0 {
  23216. prg.deadCycles = prg.curVal
  23217. } else {
  23218. prg.insertPenalties = prg.curVal
  23219. }
  23220. }
  23221. func (prg *prg) alterBoxDimen() {
  23222. var (
  23223. c smallNumber // |width_offset| or |height_offset| or |depth_offset|
  23224. b eightBits // box number
  23225. )
  23226. c = byte(prg.curChr)
  23227. prg.scanEightBitInt()
  23228. b = byte(prg.curVal)
  23229. prg.scanOptionalEquals()
  23230. prg.scanDimen(false, false, false)
  23231. if int32(*(*prg.eqtb[boxBase+int32(b)-1].hh()).rh()) != 0 {
  23232. *prg.mem[int32(*(*prg.eqtb[boxBase+int32(b)-1].hh()).rh())+int32(c)].int() = prg.curVal
  23233. }
  23234. }
  23235. func (prg *prg) newFont(a smallNumber) {
  23236. var (
  23237. u halfword // user's font identifier
  23238. s scaled // stated ``at'' size, or negative of scaled magnification
  23239. f internalFontNumber // runs through existing fonts
  23240. t strNumber // name for the frozen font identifier
  23241. oldSetting/* 0..maxSelector */ byte // holds |selector| setting
  23242. flushableString strNumber // string not yet referenced
  23243. )
  23244. if int32(prg.jobName) == 0 {
  23245. prg.openLogFile()
  23246. }
  23247. // avoid confusing \.[texput] with the font name
  23248. // \xref[texput]
  23249. prg.getRToken()
  23250. u = prg.curCs
  23251. if int32(u) >= hashBase {
  23252. t = *prg.hash[u-514].rh()
  23253. } else if int32(u) >= singleBase {
  23254. if int32(u) == nullCs {
  23255. t = /* "FONT" */ 1219
  23256. } else {
  23257. t = uint16(int32(u) - singleBase)
  23258. }
  23259. } else {
  23260. oldSetting = prg.selector
  23261. prg.selector = byte(newString)
  23262. prg.print( /* "FONT" */ 1219)
  23263. prg.print(int32(u) - activeBase)
  23264. prg.selector = oldSetting
  23265. // \xref[FONTx]
  23266. {
  23267. if int32(prg.poolPtr)+1 > poolSize {
  23268. prg.overflow(strNumber( /* "pool size" */ 257), poolSize-int32(prg.initPoolPtr))
  23269. } /* \xref[TeX capacity exceeded pool size][\quad pool size] */
  23270. }
  23271. t = prg.makeString()
  23272. }
  23273. if int32(a) >= 4 {
  23274. prg.geqDefine(u, quarterword(setFont), halfword(fontBase))
  23275. } else {
  23276. prg.eqDefine(u, quarterword(setFont), halfword(fontBase))
  23277. }
  23278. prg.scanOptionalEquals()
  23279. prg.scanFileName()
  23280. // Scan the font size specification
  23281. prg.nameInProgress = true // this keeps |cur_name| from being changed
  23282. if prg.scanKeyword(strNumber( /* "at" */ 1220)) {
  23283. prg.scanDimen(false, false, false)
  23284. s = prg.curVal
  23285. if s <= 0 || s >= 01000000000 {
  23286. {
  23287. if int32(prg.interaction) == errorStopMode {
  23288. }
  23289. prg.printNl(strNumber( /* "! " */ 262))
  23290. prg.print( /* "Improper `at' size (" */ 1222)
  23291. }
  23292. prg.printScaled(s)
  23293. prg.print( /* "pt), replaced by 10pt" */ 1223)
  23294. // \xref[Improper `at' size...]
  23295. {
  23296. prg.helpPtr = 2
  23297. prg.helpLine[1] = /* "I can only handle fonts at positive sizes that are" */ 1224
  23298. prg.helpLine[0] = /* "less than 2048pt, so I've changed what you said to 10pt." */ 1225
  23299. }
  23300. prg.error1()
  23301. s = 10 * 0200000
  23302. }
  23303. } else if prg.scanKeyword(strNumber( /* "scaled" */ 1221)) {
  23304. prg.scanInt()
  23305. s = -prg.curVal
  23306. if prg.curVal <= 0 || prg.curVal > 32768 {
  23307. {
  23308. if int32(prg.interaction) == errorStopMode {
  23309. }
  23310. prg.printNl(strNumber( /* "! " */ 262))
  23311. prg.print( /* "Illegal magnification has been changed to 1000" */ 552)
  23312. }
  23313. // \xref[Illegal magnification...]
  23314. {
  23315. prg.helpPtr = 1
  23316. prg.helpLine[0] = /* "The magnification ratio must be between 1 and 32768." */ 553
  23317. }
  23318. prg.intError(prg.curVal)
  23319. s = -1000
  23320. }
  23321. } else {
  23322. s = -1000
  23323. }
  23324. prg.nameInProgress = false
  23325. // If this font has already been loaded, set |f| to the internal font number and |goto common_ending|
  23326. flushableString = uint16(int32(prg.strPtr) - 1)
  23327. for ii := int32(fontBase + 1); ii <= int32(prg.fontPtr); ii++ {
  23328. f = internalFontNumber(ii)
  23329. _ = f
  23330. if prg.strEqStr(prg.fontName[f], prg.curName) && prg.strEqStr(prg.fontArea[f], prg.curArea) {
  23331. if int32(prg.curName) == int32(flushableString) {
  23332. {
  23333. prg.strPtr = uint16(int32(prg.strPtr) - 1)
  23334. prg.poolPtr = prg.strStart[prg.strPtr]
  23335. }
  23336. prg.curName = prg.fontName[f]
  23337. }
  23338. if s > 0 {
  23339. if s == prg.fontSize[f] {
  23340. goto commonEnding
  23341. }
  23342. } else if prg.fontSize[f] == prg.xnOverD(prg.fontDsize[f], -s, 1000) {
  23343. goto commonEnding
  23344. }
  23345. }
  23346. }
  23347. f = prg.readFontInfo(u, prg.curName, prg.curArea, s)
  23348. commonEnding:
  23349. *(*prg.eqtb[u-1].hh()).rh() = uint16(f)
  23350. prg.eqtb[fontIdBase+int32(f)-1] = prg.eqtb[u-1]
  23351. *prg.hash[fontIdBase+int32(f)-514].rh() = t
  23352. }
  23353. func (prg *prg) newInteraction() {
  23354. prg.printLn()
  23355. prg.interaction = byte(prg.curChr)
  23356. // Initialize the print |selector| based on |interaction|
  23357. if int32(prg.interaction) == batchMode {
  23358. prg.selector = byte(noPrint)
  23359. } else {
  23360. prg.selector = byte(termOnly)
  23361. }
  23362. if prg.logOpened {
  23363. prg.selector = byte(int32(prg.selector) + 2)
  23364. }
  23365. }
  23366. //
  23367. func (prg *prg) prefixedCommand() {
  23368. var (
  23369. a smallNumber // accumulated prefix codes so far
  23370. f internalFontNumber // identifies a font
  23371. j halfword // index into a \.[\\parshape] specification
  23372. k fontIndex // index into |font_info|
  23373. p, q halfword // for temporary short-term use
  23374. n int32 // ditto
  23375. e bool // should a definition be expanded? or was \.[\\let] not done?
  23376. )
  23377. a = 0
  23378. for int32(prg.curCmd) == prefix {
  23379. if !(int32(a)/int32(prg.curChr)&1 != 0) {
  23380. a = byte(int32(a) + int32(prg.curChr))
  23381. }
  23382. // Get the next non-blank non-relax...
  23383. for {
  23384. prg.getXToken()
  23385. if int32(prg.curCmd) != spacer && int32(prg.curCmd) != relax {
  23386. break
  23387. }
  23388. }
  23389. if int32(prg.curCmd) <= maxNonPrefixedCommand {
  23390. {
  23391. if int32(prg.interaction) == errorStopMode {
  23392. }
  23393. prg.printNl(strNumber( /* "! " */ 262))
  23394. prg.print( /* "You can't use a prefix with `" */ 1179)
  23395. }
  23396. // \xref[You can't use a prefix with x]
  23397. prg.printCmdChr(prg.curCmd, prg.curChr)
  23398. prg.printChar(asciiCode('\''))
  23399. {
  23400. prg.helpPtr = 1
  23401. prg.helpLine[0] = /* "I'll pretend you didn't say \\long or \\outer or \\global." */ 1180
  23402. }
  23403. prg.backError()
  23404. goto exit
  23405. }
  23406. }
  23407. // Discard the prefixes \.[\\long] and \.[\\outer] if they are irrelevant
  23408. if int32(prg.curCmd) != def && int32(a)%4 != 0 {
  23409. {
  23410. if int32(prg.interaction) == errorStopMode {
  23411. }
  23412. prg.printNl(strNumber( /* "! " */ 262))
  23413. prg.print( /* "You can't use `" */ 685)
  23414. }
  23415. prg.printEsc(strNumber( /* "long" */ 1171))
  23416. prg.print( /* "' or `" */ 1181)
  23417. prg.printEsc(strNumber( /* "outer" */ 1172))
  23418. prg.print( /* "' with `" */ 1182)
  23419. // \xref[You can't use \\long...]
  23420. prg.printCmdChr(prg.curCmd, prg.curChr)
  23421. prg.printChar(asciiCode('\''))
  23422. {
  23423. prg.helpPtr = 1
  23424. prg.helpLine[0] = /* "I'll pretend you didn't say \\long or \\outer here." */ 1183
  23425. }
  23426. prg.error1()
  23427. }
  23428. // Adjust \(f)for the setting of \.[\\globaldefs]
  23429. if *prg.eqtb[intBase+globalDefsCode-1].int() != 0 {
  23430. if *prg.eqtb[intBase+globalDefsCode-1].int() < 0 {
  23431. if int32(a) >= 4 {
  23432. a = byte(int32(a) - 4)
  23433. }
  23434. } else {
  23435. if !(int32(a) >= 4) {
  23436. a = byte(int32(a) + 4)
  23437. }
  23438. }
  23439. }
  23440. switch prg.curCmd {
  23441. case setFont:
  23442. if int32(a) >= 4 {
  23443. prg.geqDefine(halfword(curFontLoc), quarterword(data), prg.curChr)
  23444. } else {
  23445. prg.eqDefine(halfword(curFontLoc), quarterword(data), prg.curChr)
  23446. }
  23447. case def:
  23448. if prg.curChr&1 != 0 && !(int32(a) >= 4) && *prg.eqtb[intBase+globalDefsCode-1].int() >= 0 {
  23449. a = byte(int32(a) + 4)
  23450. }
  23451. e = int32(prg.curChr) >= 2
  23452. prg.getRToken()
  23453. p = prg.curCs
  23454. q = prg.scanToks(true, e)
  23455. if int32(a) >= 4 {
  23456. prg.geqDefine(p, quarterword(call+int32(a)%4), prg.defRef)
  23457. } else {
  23458. prg.eqDefine(p, quarterword(call+int32(a)%4), prg.defRef)
  23459. }
  23460. case let:
  23461. n = int32(prg.curChr)
  23462. prg.getRToken()
  23463. p = prg.curCs
  23464. if n == normal {
  23465. for {
  23466. prg.getToken()
  23467. if int32(prg.curCmd) != spacer {
  23468. break
  23469. }
  23470. }
  23471. if int32(prg.curTok) == otherToken+'=' {
  23472. prg.getToken()
  23473. if int32(prg.curCmd) == spacer {
  23474. prg.getToken()
  23475. }
  23476. }
  23477. } else {
  23478. prg.getToken()
  23479. q = prg.curTok
  23480. prg.getToken()
  23481. prg.backInput()
  23482. prg.curTok = q
  23483. prg.backInput() // look ahead, then back up
  23484. } // note that |back_input| doesn't affect |cur_cmd|, |cur_chr|
  23485. if int32(prg.curCmd) >= call {
  23486. *(*prg.mem[prg.curChr].hh()).lh() = uint16(int32(*(*prg.mem[prg.curChr].hh()).lh()) + 1)
  23487. }
  23488. if int32(a) >= 4 {
  23489. prg.geqDefine(p, prg.curCmd, prg.curChr)
  23490. } else {
  23491. prg.eqDefine(p, prg.curCmd, prg.curChr)
  23492. }
  23493. case shorthandDef:
  23494. n = int32(prg.curChr)
  23495. prg.getRToken()
  23496. p = prg.curCs
  23497. if int32(a) >= 4 {
  23498. prg.geqDefine(p, quarterword(relax), halfword(256))
  23499. } else {
  23500. prg.eqDefine(p, quarterword(relax), halfword(256))
  23501. }
  23502. prg.scanOptionalEquals()
  23503. switch n {
  23504. case charDefCode:
  23505. prg.scanCharNum()
  23506. if int32(a) >= 4 {
  23507. prg.geqDefine(p, quarterword(charGiven), halfword(prg.curVal))
  23508. } else {
  23509. prg.eqDefine(p, quarterword(charGiven), halfword(prg.curVal))
  23510. }
  23511. case mathCharDefCode:
  23512. prg.scanFifteenBitInt()
  23513. if int32(a) >= 4 {
  23514. prg.geqDefine(p, quarterword(mathGiven), halfword(prg.curVal))
  23515. } else {
  23516. prg.eqDefine(p, quarterword(mathGiven), halfword(prg.curVal))
  23517. }
  23518. default:
  23519. prg.scanEightBitInt()
  23520. switch n {
  23521. case countDefCode:
  23522. if int32(a) >= 4 {
  23523. prg.geqDefine(p, quarterword(assignInt), halfword(countBase+prg.curVal))
  23524. } else {
  23525. prg.eqDefine(p, quarterword(assignInt), halfword(countBase+prg.curVal))
  23526. }
  23527. case dimenDefCode:
  23528. if int32(a) >= 4 {
  23529. prg.geqDefine(p, quarterword(assignDimen), halfword(scaledBase+prg.curVal))
  23530. } else {
  23531. prg.eqDefine(p, quarterword(assignDimen), halfword(scaledBase+prg.curVal))
  23532. }
  23533. case skipDefCode:
  23534. if int32(a) >= 4 {
  23535. prg.geqDefine(p, quarterword(assignGlue), halfword(skipBase+prg.curVal))
  23536. } else {
  23537. prg.eqDefine(p, quarterword(assignGlue), halfword(skipBase+prg.curVal))
  23538. }
  23539. case muSkipDefCode:
  23540. if int32(a) >= 4 {
  23541. prg.geqDefine(p, quarterword(assignMuGlue), halfword(muSkipBase+prg.curVal))
  23542. } else {
  23543. prg.eqDefine(p, quarterword(assignMuGlue), halfword(muSkipBase+prg.curVal))
  23544. }
  23545. case toksDefCode:
  23546. if int32(a) >= 4 {
  23547. prg.geqDefine(p, quarterword(assignToks), halfword(toksBase+prg.curVal))
  23548. } else {
  23549. prg.eqDefine(p, quarterword(assignToks), halfword(toksBase+prg.curVal))
  23550. }
  23551. } // there are no other cases
  23552. }
  23553. case readToCs:
  23554. prg.scanInt()
  23555. n = prg.curVal
  23556. if !prg.scanKeyword(strNumber(842)) {
  23557. {
  23558. if int32(prg.interaction) == errorStopMode {
  23559. }
  23560. prg.printNl(strNumber( /* "! " */ 262))
  23561. prg.print( /* "Missing `to' inserted" */ 1073)
  23562. }
  23563. // \xref[Missing `to'...]
  23564. {
  23565. prg.helpPtr = 2
  23566. prg.helpLine[1] = /* "You should have said `\\read<number> to \\cs'." */ 1200
  23567. prg.helpLine[0] = /* "I'm going to look for the \\cs now." */ 1201
  23568. }
  23569. prg.error1()
  23570. }
  23571. prg.getRToken()
  23572. p = prg.curCs
  23573. prg.readToks(n, p)
  23574. if int32(a) >= 4 {
  23575. prg.geqDefine(p, quarterword(call), halfword(prg.curVal))
  23576. } else {
  23577. prg.eqDefine(p, quarterword(call), halfword(prg.curVal))
  23578. }
  23579. case toksRegister, assignToks:
  23580. q = prg.curCs
  23581. if int32(prg.curCmd) == toksRegister {
  23582. prg.scanEightBitInt()
  23583. p = uint16(toksBase + prg.curVal)
  23584. } else {
  23585. p = prg.curChr
  23586. } // |p=every_par_loc| or |output_routine_loc| or \dots
  23587. prg.scanOptionalEquals()
  23588. // Get the next non-blank non-relax non-call token
  23589. for {
  23590. prg.getXToken()
  23591. if int32(prg.curCmd) != spacer && int32(prg.curCmd) != relax {
  23592. break
  23593. }
  23594. }
  23595. if int32(prg.curCmd) != leftBrace {
  23596. if int32(prg.curCmd) == toksRegister {
  23597. prg.scanEightBitInt()
  23598. prg.curCmd = byte(assignToks)
  23599. prg.curChr = uint16(toksBase + prg.curVal)
  23600. }
  23601. if int32(prg.curCmd) == assignToks {
  23602. q = *(*prg.eqtb[prg.curChr-1].hh()).rh()
  23603. if int32(q) == 0 {
  23604. if int32(a) >= 4 {
  23605. prg.geqDefine(p, quarterword(undefinedCs), halfword(0))
  23606. } else {
  23607. prg.eqDefine(p, quarterword(undefinedCs), halfword(0))
  23608. }
  23609. } else {
  23610. *(*prg.mem[q].hh()).lh() = uint16(int32(*(*prg.mem[q].hh()).lh()) + 1)
  23611. if int32(a) >= 4 {
  23612. prg.geqDefine(p, quarterword(call), q)
  23613. } else {
  23614. prg.eqDefine(p, quarterword(call), q)
  23615. }
  23616. }
  23617. goto done
  23618. }
  23619. }
  23620. prg.backInput()
  23621. prg.curCs = q
  23622. q = prg.scanToks(false, false)
  23623. if int32(*(*prg.mem[prg.defRef].hh()).rh()) == 0 {
  23624. if int32(a) >= 4 {
  23625. prg.geqDefine(p, quarterword(undefinedCs), halfword(0))
  23626. } else {
  23627. prg.eqDefine(p, quarterword(undefinedCs), halfword(0))
  23628. }
  23629. {
  23630. *(*prg.mem[prg.defRef].hh()).rh() = prg.avail
  23631. prg.avail = prg.defRef /* dyn_used:= dyn_used-1 ; [ ] */
  23632. }
  23633. } else {
  23634. if int32(p) == outputRoutineLoc {
  23635. *(*prg.mem[q].hh()).rh() = prg.getAvail()
  23636. q = *(*prg.mem[q].hh()).rh()
  23637. *(*prg.mem[q].hh()).lh() = uint16(rightBraceToken + '}')
  23638. q = prg.getAvail()
  23639. *(*prg.mem[q].hh()).lh() = uint16(leftBraceToken + '{')
  23640. *(*prg.mem[q].hh()).rh() = *(*prg.mem[prg.defRef].hh()).rh()
  23641. *(*prg.mem[prg.defRef].hh()).rh() = q
  23642. }
  23643. if int32(a) >= 4 {
  23644. prg.geqDefine(p, quarterword(call), prg.defRef)
  23645. } else {
  23646. prg.eqDefine(p, quarterword(call), prg.defRef)
  23647. }
  23648. }
  23649. case assignInt:
  23650. p = prg.curChr
  23651. prg.scanOptionalEquals()
  23652. prg.scanInt()
  23653. if int32(a) >= 4 {
  23654. prg.geqWordDefine(p, prg.curVal)
  23655. } else {
  23656. prg.eqWordDefine(p, prg.curVal)
  23657. }
  23658. case assignDimen:
  23659. p = prg.curChr
  23660. prg.scanOptionalEquals()
  23661. prg.scanDimen(false, false, false)
  23662. if int32(a) >= 4 {
  23663. prg.geqWordDefine(p, prg.curVal)
  23664. } else {
  23665. prg.eqWordDefine(p, prg.curVal)
  23666. }
  23667. case assignGlue, assignMuGlue:
  23668. p = prg.curChr
  23669. n = int32(prg.curCmd)
  23670. prg.scanOptionalEquals()
  23671. if n == assignMuGlue {
  23672. prg.scanGlue(smallNumber(muVal))
  23673. } else {
  23674. prg.scanGlue(smallNumber(glueVal))
  23675. }
  23676. prg.trapZeroGlue()
  23677. if int32(a) >= 4 {
  23678. prg.geqDefine(p, quarterword(glueRef), halfword(prg.curVal))
  23679. } else {
  23680. prg.eqDefine(p, quarterword(glueRef), halfword(prg.curVal))
  23681. }
  23682. case defCode:
  23683. if int32(prg.curChr) == catCodeBase {
  23684. n = maxCharCode
  23685. } else if int32(prg.curChr) == mathCodeBase {
  23686. n = 0100000
  23687. } else if int32(prg.curChr) == sfCodeBase {
  23688. n = 077777
  23689. } else if int32(prg.curChr) == delCodeBase {
  23690. n = 077777777
  23691. } else {
  23692. n = 255
  23693. }
  23694. p = prg.curChr
  23695. prg.scanCharNum()
  23696. p = uint16(int32(p) + prg.curVal)
  23697. prg.scanOptionalEquals()
  23698. prg.scanInt()
  23699. if prg.curVal < 0 && int32(p) < delCodeBase || prg.curVal > n {
  23700. {
  23701. if int32(prg.interaction) == errorStopMode {
  23702. }
  23703. prg.printNl(strNumber( /* "! " */ 262))
  23704. prg.print( /* "Invalid code (" */ 1202)
  23705. }
  23706. prg.printInt(prg.curVal)
  23707. // \xref[Invalid code]
  23708. if int32(p) < delCodeBase {
  23709. prg.print( /* "), should be in the range 0.." */ 1203)
  23710. } else {
  23711. prg.print( /* "), should be at most " */ 1204)
  23712. }
  23713. prg.printInt(n)
  23714. {
  23715. prg.helpPtr = 1
  23716. prg.helpLine[0] = /* "I'm going to use 0 instead of that illegal code value." */ 1205
  23717. }
  23718. prg.error1()
  23719. prg.curVal = 0
  23720. }
  23721. if int32(p) < mathCodeBase {
  23722. if int32(a) >= 4 {
  23723. prg.geqDefine(p, quarterword(data), halfword(prg.curVal))
  23724. } else {
  23725. prg.eqDefine(p, quarterword(data), halfword(prg.curVal))
  23726. }
  23727. } else if int32(p) < delCodeBase {
  23728. if int32(a) >= 4 {
  23729. prg.geqDefine(p, quarterword(data), halfword(prg.curVal+0))
  23730. } else {
  23731. prg.eqDefine(p, quarterword(data), halfword(prg.curVal+0))
  23732. }
  23733. } else if int32(a) >= 4 {
  23734. prg.geqWordDefine(p, prg.curVal)
  23735. } else {
  23736. prg.eqWordDefine(p, prg.curVal)
  23737. }
  23738. case defFamily:
  23739. p = prg.curChr
  23740. prg.scanFourBitInt()
  23741. p = uint16(int32(p) + prg.curVal)
  23742. prg.scanOptionalEquals()
  23743. prg.scanFontIdent()
  23744. if int32(a) >= 4 {
  23745. prg.geqDefine(p, quarterword(data), halfword(prg.curVal))
  23746. } else {
  23747. prg.eqDefine(p, quarterword(data), halfword(prg.curVal))
  23748. }
  23749. case register, advance, multiply, divide:
  23750. prg.doRegisterCommand(a)
  23751. case setBox:
  23752. prg.scanEightBitInt()
  23753. if int32(a) >= 4 {
  23754. n = 256 + prg.curVal
  23755. } else {
  23756. n = prg.curVal
  23757. }
  23758. prg.scanOptionalEquals()
  23759. if prg.setBoxAllowed {
  23760. prg.scanBox(010000000000 + n)
  23761. } else {
  23762. {
  23763. if int32(prg.interaction) == errorStopMode {
  23764. }
  23765. prg.printNl(strNumber( /* "! " */ 262))
  23766. prg.print( /* "Improper " */ 680)
  23767. }
  23768. prg.printEsc(strNumber( /* "setbox" */ 536))
  23769. // \xref[Improper \\setbox]
  23770. {
  23771. prg.helpPtr = 2
  23772. prg.helpLine[1] = /* "Sorry, \\setbox is not allowed after \\halign in a display," */ 1211
  23773. prg.helpLine[0] = /* "or between \\accent and an accented character." */ 1212
  23774. }
  23775. prg.error1()
  23776. }
  23777. case setAux:
  23778. prg.alterAux()
  23779. case setPrevGraf:
  23780. prg.alterPrevGraf()
  23781. case setPageDimen:
  23782. prg.alterPageSoFar()
  23783. case setPageInt:
  23784. prg.alterInteger()
  23785. case setBoxDimen:
  23786. prg.alterBoxDimen()
  23787. case setShape:
  23788. prg.scanOptionalEquals()
  23789. prg.scanInt()
  23790. n = prg.curVal
  23791. if n <= 0 {
  23792. p = 0
  23793. } else {
  23794. p = prg.getNode(2*n + 1)
  23795. *(*prg.mem[p].hh()).lh() = uint16(n)
  23796. for ii := int32(1); ii <= n; ii++ {
  23797. j = halfword(ii)
  23798. _ = j
  23799. prg.scanDimen(false, false, false)
  23800. *prg.mem[int32(p)+2*int32(j)-1].int() = prg.curVal // indentation
  23801. prg.scanDimen(false, false, false)
  23802. *prg.mem[int32(p)+2*int32(j)].int() = prg.curVal // width
  23803. }
  23804. }
  23805. if int32(a) >= 4 {
  23806. prg.geqDefine(halfword(parShapeLoc), quarterword(shapeRef), p)
  23807. } else {
  23808. prg.eqDefine(halfword(parShapeLoc), quarterword(shapeRef), p)
  23809. }
  23810. case hyphData:
  23811. if int32(prg.curChr) == 1 {
  23812. prg.newPatterns()
  23813. goto done
  23814. {
  23815. if int32(prg.interaction) == errorStopMode {
  23816. }
  23817. prg.printNl(strNumber( /* "! " */ 262))
  23818. prg.print( /* "Patterns can be loaded only by INITEX" */ 1216)
  23819. }
  23820. // \xref[Patterns can be...]
  23821. prg.helpPtr = 0
  23822. prg.error1()
  23823. for {
  23824. prg.getToken()
  23825. if int32(prg.curCmd) == rightBrace {
  23826. break
  23827. }
  23828. } // flush the patterns
  23829. // flush the patterns
  23830. goto exit
  23831. } else {
  23832. prg.newHyphExceptions()
  23833. goto done
  23834. }
  23835. case assignFontDimen:
  23836. prg.findFontDimen(true)
  23837. k = uint16(prg.curVal)
  23838. prg.scanOptionalEquals()
  23839. prg.scanDimen(false, false, false)
  23840. *prg.fontInfo[k].int() = prg.curVal
  23841. case assignFontInt:
  23842. n = int32(prg.curChr)
  23843. prg.scanFontIdent()
  23844. f = byte(prg.curVal)
  23845. prg.scanOptionalEquals()
  23846. prg.scanInt()
  23847. if n == 0 {
  23848. prg.hyphenChar[f] = prg.curVal
  23849. } else {
  23850. prg.skewChar[f] = prg.curVal
  23851. }
  23852. case defFont:
  23853. prg.newFont(a)
  23854. case setInteraction:
  23855. prg.newInteraction()
  23856. default:
  23857. prg.confusion(strNumber( /* "prefix" */ 1178))
  23858. // \xref[this can't happen prefix][\quad prefix]
  23859. }
  23860. done:
  23861. if int32(prg.afterToken) != 0 {
  23862. prg.curTok = prg.afterToken
  23863. prg.backInput()
  23864. prg.afterToken = 0
  23865. }
  23866. exit:
  23867. } // note that |glue_shrink(p)=0| since |glue_shrink==shift_amount|
  23868. // 800.
  23869. // tangle:pos tex.web:15736:1:
  23870. // Finally, we will reach the end of the alignment, and we can breathe a
  23871. // sigh of relief that memory hasn't overflowed. All the unset boxes will now be
  23872. // set so that the columns line up, taking due account of spanned columns.
  23873. func (prg *prg) doAssignments() {
  23874. for true {
  23875. for {
  23876. prg.getXToken()
  23877. if int32(prg.curCmd) != spacer && int32(prg.curCmd) != relax {
  23878. break
  23879. }
  23880. }
  23881. if int32(prg.curCmd) <= maxNonPrefixedCommand {
  23882. goto exit
  23883. }
  23884. prg.setBoxAllowed = false
  23885. prg.prefixedCommand()
  23886. prg.setBoxAllowed = true
  23887. }
  23888. exit:
  23889. }
  23890. func (prg *prg) openOrCloseIn() {
  23891. var (
  23892. c/* 0..1 */ byte // 1 for \.[\\openin], 0 for \.[\\closein]
  23893. n/* 0..15 */ byte // stream number
  23894. )
  23895. c = byte(prg.curChr)
  23896. prg.scanFourBitInt()
  23897. n = byte(prg.curVal)
  23898. if int32(prg.readOpen[n]) != closed {
  23899. prg.aClose(prg.readFile[n])
  23900. prg.readOpen[n] = byte(closed)
  23901. }
  23902. if int32(c) != 0 {
  23903. prg.scanOptionalEquals()
  23904. prg.scanFileName()
  23905. if int32(prg.curExt) == 338 {
  23906. prg.curExt = /* ".tex" */ 791
  23907. }
  23908. prg.packFileName(prg.curName, prg.curArea, prg.curExt)
  23909. if prg.aOpenIn(prg.readFile[n]) {
  23910. prg.readOpen[n] = byte(justOpen)
  23911. }
  23912. }
  23913. }
  23914. func (prg *prg) issueMessage() {
  23915. var (
  23916. oldSetting/* 0..maxSelector */ byte // holds |selector| setting
  23917. c/* 0..1 */ byte // identifies \.[\\message] and \.[\\errmessage]
  23918. s strNumber // the message
  23919. )
  23920. c = byte(prg.curChr)
  23921. *(*prg.mem[30000-12].hh()).rh() = prg.scanToks(false, true)
  23922. oldSetting = prg.selector
  23923. prg.selector = byte(newString)
  23924. prg.tokenShow(prg.defRef)
  23925. prg.selector = oldSetting
  23926. prg.flushList(prg.defRef)
  23927. {
  23928. if int32(prg.poolPtr)+1 > poolSize {
  23929. prg.overflow(strNumber( /* "pool size" */ 257), poolSize-int32(prg.initPoolPtr))
  23930. } /* \xref[TeX capacity exceeded pool size][\quad pool size] */
  23931. }
  23932. s = prg.makeString()
  23933. if int32(c) == 0 {
  23934. if int32(prg.termOffset)+(int32(prg.strStart[int32(s)+1])-int32(prg.strStart[s])) > maxPrintLine-2 {
  23935. prg.printLn()
  23936. } else if int32(prg.termOffset) > 0 || int32(prg.fileOffset) > 0 {
  23937. prg.printChar(asciiCode(' '))
  23938. }
  23939. prg.slowPrint(int32(s))
  23940. } else {
  23941. // Print string |s| as an error message
  23942. {
  23943. if int32(prg.interaction) == errorStopMode {
  23944. }
  23945. prg.printNl(strNumber( /* "! " */ 262))
  23946. prg.print( /* "" */ 338)
  23947. }
  23948. prg.slowPrint(int32(s))
  23949. if int32(*(*prg.eqtb[errHelpLoc-1].hh()).rh()) != 0 {
  23950. prg.useErrHelp = true
  23951. } else if prg.longHelpSeen {
  23952. prg.helpPtr = 1
  23953. prg.helpLine[0] = /* "(That was another \\errmessage.)" */ 1232
  23954. } else {
  23955. if int32(prg.interaction) < errorStopMode {
  23956. prg.longHelpSeen = true
  23957. }
  23958. {
  23959. prg.helpPtr = 4
  23960. prg.helpLine[3] = /* "This error message was generated by an \\errmessage" */ 1233
  23961. prg.helpLine[2] = /* "command, so I can't give any explicit help." */ 1234
  23962. prg.helpLine[1] = /* "Pretend that you're Hercule Poirot: Examine all clues," */ 1235
  23963. prg.helpLine[0] = /* "and deduce the truth by order and method." */ 1236
  23964. }
  23965. }
  23966. prg.error1()
  23967. prg.useErrHelp = false
  23968. }
  23969. {
  23970. prg.strPtr = uint16(int32(prg.strPtr) - 1)
  23971. prg.poolPtr = prg.strStart[prg.strPtr]
  23972. }
  23973. }
  23974. func (prg *prg) shiftCase() {
  23975. var (
  23976. b halfword // |lc_code_base| or |uc_code_base|
  23977. p halfword // runs through the token list
  23978. t halfword // token
  23979. c eightBits // character code
  23980. )
  23981. b = prg.curChr
  23982. p = prg.scanToks(false, false)
  23983. p = *(*prg.mem[prg.defRef].hh()).rh()
  23984. for int32(p) != 0 {
  23985. t = *(*prg.mem[p].hh()).lh()
  23986. if int32(t) < 07777+singleBase {
  23987. c = byte(int32(t) % 256)
  23988. if int32(*(*prg.eqtb[int32(b)+int32(c)-1].hh()).rh()) != 0 {
  23989. *(*prg.mem[p].hh()).lh() = uint16(int32(t) - int32(c) + int32(*(*prg.eqtb[int32(b)+int32(c)-1].hh()).rh()))
  23990. }
  23991. }
  23992. p = *(*prg.mem[p].hh()).rh()
  23993. }
  23994. prg.beginTokenList(*(*prg.mem[prg.defRef].hh()).rh(), quarterword(backedUp))
  23995. {
  23996. *(*prg.mem[prg.defRef].hh()).rh() = prg.avail
  23997. prg.avail = prg.defRef /* dyn_used:= dyn_used-1 ; [ ] */
  23998. } // omit reference count
  23999. }
  24000. func (prg *prg) showWhatever() {
  24001. var (
  24002. p halfword // tail of a token list to show
  24003. )
  24004. if int32(p) == 0 {
  24005. }
  24006. switch prg.curChr {
  24007. case showListsCode:
  24008. prg.beginDiagnostic()
  24009. prg.showActivities()
  24010. case showBoxCode:
  24011. // Show the current contents of a box
  24012. prg.scanEightBitInt()
  24013. prg.beginDiagnostic()
  24014. prg.printNl(strNumber( /* "> \\box" */ 1254))
  24015. prg.printInt(prg.curVal)
  24016. prg.printChar(asciiCode('='))
  24017. if int32(*(*prg.eqtb[boxBase+prg.curVal-1].hh()).rh()) == 0 {
  24018. prg.print( /* "void" */ 410)
  24019. } else {
  24020. prg.showBox(*(*prg.eqtb[boxBase+prg.curVal-1].hh()).rh())
  24021. }
  24022. case showCode:
  24023. // Show the current meaning of a token, then |goto common_ending|
  24024. prg.getToken()
  24025. if int32(prg.interaction) == errorStopMode {
  24026. }
  24027. prg.printNl(strNumber( /* "> " */ 1248))
  24028. if int32(prg.curCs) != 0 {
  24029. prg.sprintCs(prg.curCs)
  24030. prg.printChar(asciiCode('='))
  24031. }
  24032. prg.printMeaning()
  24033. goto commonEnding
  24034. default:
  24035. p = prg.theToks()
  24036. if int32(prg.interaction) == errorStopMode {
  24037. }
  24038. prg.printNl(strNumber( /* "> " */ 1248))
  24039. prg.tokenShow(halfword(30000 - 3))
  24040. prg.flushList(*(*prg.mem[30000-3].hh()).rh())
  24041. goto commonEnding
  24042. }
  24043. // Complete a potentially long \.[\\show] command
  24044. prg.endDiagnostic(true)
  24045. {
  24046. if int32(prg.interaction) == errorStopMode {
  24047. }
  24048. prg.printNl(strNumber( /* "! " */ 262))
  24049. prg.print( /* "OK" */ 1255)
  24050. }
  24051. // \xref[OK]
  24052. if int32(prg.selector) == termAndLog {
  24053. if *prg.eqtb[intBase+tracingOnlineCode-1].int() <= 0 {
  24054. prg.selector = byte(termOnly)
  24055. prg.print( /* " (see the transcript file)" */ 1256)
  24056. prg.selector = byte(termAndLog)
  24057. }
  24058. }
  24059. commonEnding:
  24060. if int32(prg.interaction) < errorStopMode {
  24061. prg.helpPtr = 0
  24062. prg.errorCount = int8(int32(prg.errorCount) - 1)
  24063. } else if *prg.eqtb[intBase+tracingOnlineCode-1].int() > 0 {
  24064. {
  24065. prg.helpPtr = 3
  24066. prg.helpLine[2] = /* "This isn't an error message; I'm just \\showing something." */ 1243
  24067. prg.helpLine[1] = /* "Type `I\\show...' to show more (e.g., \\show\\cs," */ 1244
  24068. prg.helpLine[0] = /* "\\showthe\\count10, \\showbox255, \\showlists)." */ 1245
  24069. }
  24070. } else {
  24071. {
  24072. prg.helpPtr = 5
  24073. prg.helpLine[4] = /* "This isn't an error message; I'm just \\showing something." */ 1243
  24074. prg.helpLine[3] = /* "Type `I\\show...' to show more (e.g., \\show\\cs," */ 1244
  24075. prg.helpLine[2] = /* "\\showthe\\count10, \\showbox255, \\showlists)." */ 1245
  24076. prg.helpLine[1] = /* "And type `I\\tracingonline=1\\show...' to show boxes and" */ 1246
  24077. prg.helpLine[0] = /* "lists on your terminal as well as in the transcript file." */ 1247
  24078. }
  24079. }
  24080. prg.error1()
  24081. }
  24082. func (prg *prg) storeFmtFile() {
  24083. var (
  24084. j, k, l int32 // all-purpose indices
  24085. p, q halfword // all-purpose pointers
  24086. x int32 // something to dump
  24087. w fourQuarters // four ASCII codes
  24088. )
  24089. if int32(prg.savePtr) != 0 {
  24090. {
  24091. if int32(prg.interaction) == errorStopMode {
  24092. }
  24093. prg.printNl(strNumber( /* "! " */ 262))
  24094. prg.print( /* "You can't dump inside a group" */ 1258)
  24095. }
  24096. // \xref[You can't dump...]
  24097. {
  24098. prg.helpPtr = 1
  24099. prg.helpLine[0] = /* "`[...\\dump]' is a no-no." */ 1259
  24100. }
  24101. {
  24102. if int32(prg.interaction) == errorStopMode {
  24103. prg.interaction = byte(scrollMode)
  24104. }
  24105. if prg.logOpened {
  24106. prg.error1()
  24107. } /* if interaction>batch_mode then debug_help; [ ] */
  24108. prg.history = byte(fatalErrorStop)
  24109. prg.jumpOut()
  24110. }
  24111. }
  24112. // Create the |format_ident|, open the format file, and inform the user that dumping has begun
  24113. prg.selector = byte(newString)
  24114. prg.print( /* " (preloaded format=" */ 1272)
  24115. prg.print(int32(prg.jobName))
  24116. prg.printChar(asciiCode(' '))
  24117. prg.printInt(*prg.eqtb[intBase+yearCode-1].int())
  24118. prg.printChar(asciiCode('.'))
  24119. prg.printInt(*prg.eqtb[intBase+monthCode-1].int())
  24120. prg.printChar(asciiCode('.'))
  24121. prg.printInt(*prg.eqtb[intBase+dayCode-1].int())
  24122. prg.printChar(asciiCode(')'))
  24123. if int32(prg.interaction) == batchMode {
  24124. prg.selector = byte(logOnly)
  24125. } else {
  24126. prg.selector = byte(termAndLog)
  24127. }
  24128. {
  24129. if int32(prg.poolPtr)+1 > poolSize {
  24130. prg.overflow(strNumber( /* "pool size" */ 257), poolSize-int32(prg.initPoolPtr))
  24131. } /* \xref[TeX capacity exceeded pool size][\quad pool size] */
  24132. }
  24133. prg.formatIdent = prg.makeString()
  24134. prg.packJobName(strNumber(formatExtension))
  24135. for !prg.wOpenOut(prg.fmtFile) {
  24136. prg.promptFileName(strNumber( /* "format file name" */ 1273), strNumber(formatExtension))
  24137. }
  24138. prg.printNl(strNumber( /* "Beginning to dump on file " */ 1274))
  24139. // \xref[Beginning to dump...]
  24140. prg.slowPrint(int32(prg.wMakeNameString(prg.fmtFile)))
  24141. {
  24142. prg.strPtr = uint16(int32(prg.strPtr) - 1)
  24143. prg.poolPtr = prg.strStart[prg.strPtr]
  24144. }
  24145. prg.printNl(strNumber( /* "" */ 338))
  24146. prg.slowPrint(int32(prg.formatIdent))
  24147. // Dump constants for consistency check
  24148. {
  24149. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = 504454778
  24150. prg.fmtFile.Put()
  24151. }
  24152. {
  24153. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = memBot
  24154. prg.fmtFile.Put()
  24155. }
  24156. {
  24157. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = 30000
  24158. prg.fmtFile.Put()
  24159. }
  24160. {
  24161. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = eqtbSize
  24162. prg.fmtFile.Put()
  24163. }
  24164. {
  24165. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = hashPrime
  24166. prg.fmtFile.Put()
  24167. }
  24168. {
  24169. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = hyphSize
  24170. prg.fmtFile.Put()
  24171. }
  24172. // Dump the string pool
  24173. {
  24174. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.poolPtr)
  24175. prg.fmtFile.Put()
  24176. }
  24177. {
  24178. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.strPtr)
  24179. prg.fmtFile.Put()
  24180. }
  24181. for ii := int32(0); ii <= int32(prg.strPtr); ii++ {
  24182. k = ii
  24183. _ = k
  24184. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.strStart[k])
  24185. prg.fmtFile.Put()
  24186. }
  24187. k = 0
  24188. for k+4 < int32(prg.poolPtr) {
  24189. w.b0 = byte(int32(prg.strPool[k]) + minQuarterword)
  24190. w.b1 = byte(int32(prg.strPool[k+1]) + minQuarterword)
  24191. w.b2 = byte(int32(prg.strPool[k+2]) + minQuarterword)
  24192. w.b3 = byte(int32(prg.strPool[k+3]) + minQuarterword)
  24193. {
  24194. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).qqqq() = w
  24195. prg.fmtFile.Put()
  24196. }
  24197. k = k + 4
  24198. }
  24199. k = int32(prg.poolPtr) - 4
  24200. w.b0 = byte(int32(prg.strPool[k]) + minQuarterword)
  24201. w.b1 = byte(int32(prg.strPool[k+1]) + minQuarterword)
  24202. w.b2 = byte(int32(prg.strPool[k+2]) + minQuarterword)
  24203. w.b3 = byte(int32(prg.strPool[k+3]) + minQuarterword)
  24204. {
  24205. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).qqqq() = w
  24206. prg.fmtFile.Put()
  24207. }
  24208. prg.printLn()
  24209. prg.printInt(int32(prg.strPtr))
  24210. prg.print( /* " strings of total length " */ 1260)
  24211. prg.printInt(int32(prg.poolPtr))
  24212. // Dump the dynamic memory
  24213. prg.sortAvail()
  24214. prg.varUsed = 0
  24215. {
  24216. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.loMemMax)
  24217. prg.fmtFile.Put()
  24218. }
  24219. {
  24220. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.rover)
  24221. prg.fmtFile.Put()
  24222. }
  24223. p = uint16(memBot)
  24224. q = prg.rover
  24225. x = 0
  24226. for {
  24227. for ii := int32(p); ii <= int32(q)+1; ii++ {
  24228. k = ii
  24229. _ = k
  24230. *(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P())) = prg.mem[k]
  24231. prg.fmtFile.Put()
  24232. }
  24233. x = x + int32(q) + 2 - int32(p)
  24234. prg.varUsed = prg.varUsed + int32(q) - int32(p)
  24235. p = uint16(int32(q) + int32(*(*prg.mem[q].hh()).lh()))
  24236. q = *(*prg.mem[int32(q)+1].hh()).rh()
  24237. if int32(q) == int32(prg.rover) {
  24238. break
  24239. }
  24240. }
  24241. prg.varUsed = prg.varUsed + int32(prg.loMemMax) - int32(p)
  24242. prg.dynUsed = int32(prg.memEnd) + 1 - int32(prg.hiMemMin)
  24243. for ii := int32(p); ii <= int32(prg.loMemMax); ii++ {
  24244. k = ii
  24245. _ = k
  24246. *(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P())) = prg.mem[k]
  24247. prg.fmtFile.Put()
  24248. }
  24249. x = x + int32(prg.loMemMax) + 1 - int32(p)
  24250. {
  24251. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.hiMemMin)
  24252. prg.fmtFile.Put()
  24253. }
  24254. {
  24255. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.avail)
  24256. prg.fmtFile.Put()
  24257. }
  24258. for ii := int32(prg.hiMemMin); ii <= int32(prg.memEnd); ii++ {
  24259. k = ii
  24260. _ = k
  24261. *(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P())) = prg.mem[k]
  24262. prg.fmtFile.Put()
  24263. }
  24264. x = x + int32(prg.memEnd) + 1 - int32(prg.hiMemMin)
  24265. p = prg.avail
  24266. for int32(p) != 0 {
  24267. prg.dynUsed = prg.dynUsed - 1
  24268. p = *(*prg.mem[p].hh()).rh()
  24269. }
  24270. {
  24271. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = prg.varUsed
  24272. prg.fmtFile.Put()
  24273. }
  24274. {
  24275. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = prg.dynUsed
  24276. prg.fmtFile.Put()
  24277. }
  24278. prg.printLn()
  24279. prg.printInt(x)
  24280. prg.print( /* " memory locations dumped; current usage is " */ 1261)
  24281. prg.printInt(prg.varUsed)
  24282. prg.printChar(asciiCode('&'))
  24283. prg.printInt(prg.dynUsed)
  24284. // Dump the table of equivalents
  24285. // Dump regions 1 to 4 of |eqtb|
  24286. k = activeBase
  24287. for {
  24288. j = k
  24289. for j < intBase-1 {
  24290. if int32(*(*prg.eqtb[j-1].hh()).rh()) == int32(*(*prg.eqtb[j+1-1].hh()).rh()) && int32(*(*prg.eqtb[j-1].hh()).b0()) == int32(*(*prg.eqtb[j+1-1].hh()).b0()) && int32(*(*prg.eqtb[j-1].hh()).b1()) == int32(*(*prg.eqtb[j+1-1].hh()).b1()) {
  24291. goto found1
  24292. }
  24293. j = j + 1
  24294. }
  24295. l = intBase
  24296. goto done1 // |j=int_base-1|
  24297. // |j=int_base-1|
  24298. found1:
  24299. j = j + 1
  24300. l = j
  24301. for j < intBase-1 {
  24302. if int32(*(*prg.eqtb[j-1].hh()).rh()) != int32(*(*prg.eqtb[j+1-1].hh()).rh()) || int32(*(*prg.eqtb[j-1].hh()).b0()) != int32(*(*prg.eqtb[j+1-1].hh()).b0()) || int32(*(*prg.eqtb[j-1].hh()).b1()) != int32(*(*prg.eqtb[j+1-1].hh()).b1()) {
  24303. goto done1
  24304. }
  24305. j = j + 1
  24306. }
  24307. done1:
  24308. {
  24309. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = l - k
  24310. prg.fmtFile.Put()
  24311. }
  24312. for k < l {
  24313. {
  24314. *(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P())) = prg.eqtb[k-1]
  24315. prg.fmtFile.Put()
  24316. }
  24317. k = k + 1
  24318. }
  24319. k = j + 1
  24320. {
  24321. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = k - l
  24322. prg.fmtFile.Put()
  24323. }
  24324. if k == intBase {
  24325. break
  24326. }
  24327. }
  24328. // Dump regions 5 and 6 of |eqtb|
  24329. for {
  24330. j = k
  24331. for j < eqtbSize {
  24332. if *prg.eqtb[j-1].int() == *prg.eqtb[j+1-1].int() {
  24333. goto found2
  24334. }
  24335. j = j + 1
  24336. }
  24337. l = eqtbSize + 1
  24338. goto done2 // |j=eqtb_size|
  24339. // |j=eqtb_size|
  24340. found2:
  24341. j = j + 1
  24342. l = j
  24343. for j < eqtbSize {
  24344. if *prg.eqtb[j-1].int() != *prg.eqtb[j+1-1].int() {
  24345. goto done2
  24346. }
  24347. j = j + 1
  24348. }
  24349. done2:
  24350. {
  24351. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = l - k
  24352. prg.fmtFile.Put()
  24353. }
  24354. for k < l {
  24355. {
  24356. *(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P())) = prg.eqtb[k-1]
  24357. prg.fmtFile.Put()
  24358. }
  24359. k = k + 1
  24360. }
  24361. k = j + 1
  24362. {
  24363. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = k - l
  24364. prg.fmtFile.Put()
  24365. }
  24366. if k > eqtbSize {
  24367. break
  24368. }
  24369. }
  24370. {
  24371. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.parLoc)
  24372. prg.fmtFile.Put()
  24373. }
  24374. {
  24375. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.writeLoc)
  24376. prg.fmtFile.Put()
  24377. }
  24378. // Dump the hash table
  24379. {
  24380. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.hashUsed)
  24381. prg.fmtFile.Put()
  24382. }
  24383. prg.csCount = frozenControlSequence - 1 - int32(prg.hashUsed)
  24384. for ii := int32(hashBase); ii <= int32(prg.hashUsed); ii++ {
  24385. p = halfword(ii)
  24386. _ = p
  24387. if int32(*prg.hash[p-514].rh()) != 0 {
  24388. {
  24389. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(p)
  24390. prg.fmtFile.Put()
  24391. }
  24392. {
  24393. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).hh() = prg.hash[p-514]
  24394. prg.fmtFile.Put()
  24395. }
  24396. prg.csCount = prg.csCount + 1
  24397. }
  24398. }
  24399. for ii := int32(prg.hashUsed) + 1; ii <= undefinedControlSequence-1; ii++ {
  24400. p = halfword(ii)
  24401. _ = p
  24402. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).hh() = prg.hash[p-514]
  24403. prg.fmtFile.Put()
  24404. }
  24405. {
  24406. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = prg.csCount
  24407. prg.fmtFile.Put()
  24408. }
  24409. prg.printLn()
  24410. prg.printInt(prg.csCount)
  24411. prg.print( /* " multiletter control sequences" */ 1262)
  24412. // Dump the font information
  24413. {
  24414. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.fmemPtr)
  24415. prg.fmtFile.Put()
  24416. }
  24417. for ii := int32(0); ii <= int32(prg.fmemPtr)-1; ii++ {
  24418. k = ii
  24419. _ = k
  24420. *(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P())) = prg.fontInfo[k]
  24421. prg.fmtFile.Put()
  24422. }
  24423. {
  24424. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.fontPtr)
  24425. prg.fmtFile.Put()
  24426. }
  24427. for ii := int32(fontBase); ii <= int32(prg.fontPtr); ii++ {
  24428. k = ii
  24429. _ = k
  24430. // Dump the array info for internal font number |k|
  24431. {
  24432. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).qqqq() = prg.fontCheck[k]
  24433. prg.fmtFile.Put()
  24434. }
  24435. {
  24436. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = prg.fontSize[k]
  24437. prg.fmtFile.Put()
  24438. }
  24439. {
  24440. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = prg.fontDsize[k]
  24441. prg.fmtFile.Put()
  24442. }
  24443. {
  24444. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.fontParams[k])
  24445. prg.fmtFile.Put()
  24446. }
  24447. {
  24448. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = prg.hyphenChar[k]
  24449. prg.fmtFile.Put()
  24450. }
  24451. {
  24452. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = prg.skewChar[k]
  24453. prg.fmtFile.Put()
  24454. }
  24455. {
  24456. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.fontName[k])
  24457. prg.fmtFile.Put()
  24458. }
  24459. {
  24460. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.fontArea[k])
  24461. prg.fmtFile.Put()
  24462. }
  24463. {
  24464. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.fontBc[k])
  24465. prg.fmtFile.Put()
  24466. }
  24467. {
  24468. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.fontEc[k])
  24469. prg.fmtFile.Put()
  24470. }
  24471. {
  24472. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = prg.charBase[k]
  24473. prg.fmtFile.Put()
  24474. }
  24475. {
  24476. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = prg.widthBase[k]
  24477. prg.fmtFile.Put()
  24478. }
  24479. {
  24480. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = prg.heightBase[k]
  24481. prg.fmtFile.Put()
  24482. }
  24483. {
  24484. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = prg.depthBase[k]
  24485. prg.fmtFile.Put()
  24486. }
  24487. {
  24488. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = prg.italicBase[k]
  24489. prg.fmtFile.Put()
  24490. }
  24491. {
  24492. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = prg.ligKernBase[k]
  24493. prg.fmtFile.Put()
  24494. }
  24495. {
  24496. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = prg.kernBase[k]
  24497. prg.fmtFile.Put()
  24498. }
  24499. {
  24500. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = prg.extenBase[k]
  24501. prg.fmtFile.Put()
  24502. }
  24503. {
  24504. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = prg.paramBase[k]
  24505. prg.fmtFile.Put()
  24506. }
  24507. {
  24508. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.fontGlue[k])
  24509. prg.fmtFile.Put()
  24510. }
  24511. {
  24512. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.bcharLabel[k])
  24513. prg.fmtFile.Put()
  24514. }
  24515. {
  24516. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.fontBchar[k])
  24517. prg.fmtFile.Put()
  24518. }
  24519. {
  24520. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.fontFalseBchar[k])
  24521. prg.fmtFile.Put()
  24522. }
  24523. prg.printNl(strNumber( /* "\\font" */ 1265))
  24524. prg.printEsc(*prg.hash[fontIdBase+k-514].rh())
  24525. prg.printChar(asciiCode('='))
  24526. prg.printFileName(int32(prg.fontName[k]), int32(prg.fontArea[k]) /* "" */, 338)
  24527. if prg.fontSize[k] != prg.fontDsize[k] {
  24528. prg.print( /* " at " */ 741)
  24529. prg.printScaled(prg.fontSize[k])
  24530. prg.print( /* "pt" */ 397)
  24531. }
  24532. }
  24533. prg.printLn()
  24534. prg.printInt(int32(prg.fmemPtr) - 7)
  24535. prg.print( /* " words of font info for " */ 1263)
  24536. prg.printInt(int32(prg.fontPtr) - fontBase)
  24537. prg.print( /* " preloaded font" */ 1264)
  24538. if int32(prg.fontPtr) != fontBase+1 {
  24539. prg.printChar(asciiCode('s'))
  24540. }
  24541. // Dump the hyphenation tables
  24542. {
  24543. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.hyphCount)
  24544. prg.fmtFile.Put()
  24545. }
  24546. for ii := int32(0); ii <= hyphSize; ii++ {
  24547. k = ii
  24548. _ = k
  24549. if int32(prg.hyphWord[k]) != 0 {
  24550. {
  24551. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = k
  24552. prg.fmtFile.Put()
  24553. }
  24554. {
  24555. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.hyphWord[k])
  24556. prg.fmtFile.Put()
  24557. }
  24558. {
  24559. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.hyphList[k])
  24560. prg.fmtFile.Put()
  24561. }
  24562. }
  24563. }
  24564. prg.printLn()
  24565. prg.printInt(int32(prg.hyphCount))
  24566. prg.print( /* " hyphenation exception" */ 1266)
  24567. if int32(prg.hyphCount) != 1 {
  24568. prg.printChar(asciiCode('s'))
  24569. }
  24570. if prg.trieNotReady {
  24571. prg.initTrie()
  24572. }
  24573. {
  24574. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.trieMax)
  24575. prg.fmtFile.Put()
  24576. }
  24577. for ii := int32(0); ii <= int32(prg.trieMax); ii++ {
  24578. k = ii
  24579. _ = k
  24580. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).hh() = prg.trie[k]
  24581. prg.fmtFile.Put()
  24582. }
  24583. {
  24584. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.trieOpPtr)
  24585. prg.fmtFile.Put()
  24586. }
  24587. for ii := int32(1); ii <= int32(prg.trieOpPtr); ii++ {
  24588. k = ii
  24589. _ = k
  24590. {
  24591. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.hyfDistance[k-1])
  24592. prg.fmtFile.Put()
  24593. }
  24594. {
  24595. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.hyfNum[k-1])
  24596. prg.fmtFile.Put()
  24597. }
  24598. {
  24599. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.hyfNext[k-1])
  24600. prg.fmtFile.Put()
  24601. }
  24602. }
  24603. prg.printNl(strNumber( /* "Hyphenation trie of length " */ 1267))
  24604. prg.printInt(int32(prg.trieMax))
  24605. // \xref[Hyphenation trie...]
  24606. prg.print( /* " has " */ 1268)
  24607. prg.printInt(int32(prg.trieOpPtr))
  24608. prg.print( /* " op" */ 1269)
  24609. if int32(prg.trieOpPtr) != 1 {
  24610. prg.printChar(asciiCode('s'))
  24611. }
  24612. prg.print( /* " out of " */ 1270)
  24613. prg.printInt(trieOpSize)
  24614. for ii := int32(255); ii >= 0; ii-- {
  24615. k = ii
  24616. _ = k
  24617. if int32(prg.trieUsed[k]) > minQuarterword {
  24618. prg.printNl(strNumber( /* " " */ 800))
  24619. prg.printInt(int32(prg.trieUsed[k]) - minQuarterword)
  24620. prg.print( /* " for language " */ 1271)
  24621. prg.printInt(k)
  24622. {
  24623. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = k
  24624. prg.fmtFile.Put()
  24625. }
  24626. {
  24627. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.trieUsed[k]) - minQuarterword
  24628. prg.fmtFile.Put()
  24629. }
  24630. }
  24631. }
  24632. // Dump a couple more things and the closing check word
  24633. {
  24634. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.interaction)
  24635. prg.fmtFile.Put()
  24636. }
  24637. {
  24638. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = int32(prg.formatIdent)
  24639. prg.fmtFile.Put()
  24640. }
  24641. {
  24642. *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int() = 69069
  24643. prg.fmtFile.Put()
  24644. }
  24645. *prg.eqtb[intBase+tracingStatsCode-1].int() = 0
  24646. // Close the format file
  24647. prg.wClose(prg.fmtFile)
  24648. }
  24649. // \4
  24650. // Declare procedures needed in |do_extension|
  24651. func (prg *prg) newWhatsit(s smallNumber, w smallNumber) {
  24652. var (
  24653. p halfword // the new node
  24654. )
  24655. p = prg.getNode(int32(w))
  24656. *(*prg.mem[p].hh()).b0() = byte(whatsitNode)
  24657. *(*prg.mem[p].hh()).b1() = s
  24658. *(*prg.mem[prg.curList.tailField].hh()).rh() = p
  24659. prg.curList.tailField = p
  24660. }
  24661. func (prg *prg) newWriteWhatsit(w smallNumber) {
  24662. prg.newWhatsit(smallNumber(prg.curChr), w)
  24663. if int32(w) != writeNodeSize {
  24664. prg.scanFourBitInt()
  24665. } else {
  24666. prg.scanInt()
  24667. if prg.curVal < 0 {
  24668. prg.curVal = 17
  24669. } else if prg.curVal > 15 {
  24670. prg.curVal = 16
  24671. }
  24672. }
  24673. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).lh() = uint16(prg.curVal)
  24674. }
  24675. func (prg *prg) doExtension() {
  24676. var (
  24677. k int32 // all-purpose integers
  24678. p halfword // all-purpose pointers
  24679. )
  24680. switch prg.curChr {
  24681. case openNode:
  24682. // Implement \.[\\openout]
  24683. prg.newWriteWhatsit(smallNumber(openNodeSize))
  24684. prg.scanOptionalEquals()
  24685. prg.scanFileName()
  24686. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).rh() = prg.curName
  24687. *(*prg.mem[int32(prg.curList.tailField)+2].hh()).lh() = prg.curArea
  24688. *(*prg.mem[int32(prg.curList.tailField)+2].hh()).rh() = prg.curExt
  24689. case writeNode:
  24690. // Implement \.[\\write]
  24691. k = int32(prg.curCs)
  24692. prg.newWriteWhatsit(smallNumber(writeNodeSize))
  24693. prg.curCs = uint16(k)
  24694. p = prg.scanToks(false, false)
  24695. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).rh() = prg.defRef
  24696. case closeNode:
  24697. // Implement \.[\\closeout]
  24698. prg.newWriteWhatsit(smallNumber(writeNodeSize))
  24699. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).rh() = 0
  24700. case specialNode:
  24701. // Implement \.[\\special]
  24702. prg.newWhatsit(smallNumber(specialNode), smallNumber(writeNodeSize))
  24703. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).lh() = 0
  24704. p = prg.scanToks(false, true)
  24705. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).rh() = prg.defRef
  24706. case immediateCode:
  24707. // Implement \.[\\immediate]
  24708. prg.getXToken()
  24709. if int32(prg.curCmd) == extension && int32(prg.curChr) <= closeNode {
  24710. p = prg.curList.tailField
  24711. prg.doExtension() // append a whatsit node
  24712. prg.outWhat(prg.curList.tailField) // do the action immediately
  24713. prg.flushNodeList(prg.curList.tailField)
  24714. prg.curList.tailField = p
  24715. *(*prg.mem[p].hh()).rh() = 0
  24716. } else {
  24717. prg.backInput()
  24718. }
  24719. case setLanguageCode:
  24720. // Implement \.[\\setlanguage]
  24721. if abs(int32(prg.curList.modeField)) != hmode {
  24722. prg.reportIllegalCase()
  24723. } else {
  24724. prg.newWhatsit(smallNumber(languageNode), smallNumber(smallNodeSize))
  24725. prg.scanInt()
  24726. if prg.curVal <= 0 {
  24727. *(*prg.curList.auxField.hh()).rh() = 0
  24728. } else if prg.curVal > 255 {
  24729. *(*prg.curList.auxField.hh()).rh() = 0
  24730. } else {
  24731. *(*prg.curList.auxField.hh()).rh() = uint16(prg.curVal)
  24732. }
  24733. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).rh() = *(*prg.curList.auxField.hh()).rh()
  24734. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).b0() = prg.normMin(*prg.eqtb[intBase+leftHyphenMinCode-1].int())
  24735. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).b1() = prg.normMin(*prg.eqtb[intBase+rightHyphenMinCode-1].int())
  24736. }
  24737. default:
  24738. prg.confusion(strNumber( /* "ext1" */ 1291))
  24739. // \xref[this can't happen ext1][\quad ext1]
  24740. }
  24741. }
  24742. func (prg *prg) fixLanguage() {
  24743. var (
  24744. l asciiCode // the new current language
  24745. )
  24746. if *prg.eqtb[intBase+languageCode-1].int() <= 0 {
  24747. l = 0
  24748. } else if *prg.eqtb[intBase+languageCode-1].int() > 255 {
  24749. l = 0
  24750. } else {
  24751. l = byte(*prg.eqtb[intBase+languageCode-1].int())
  24752. }
  24753. if int32(l) != int32(*(*prg.curList.auxField.hh()).rh()) {
  24754. prg.newWhatsit(smallNumber(languageNode), smallNumber(smallNodeSize))
  24755. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).rh() = uint16(l)
  24756. *(*prg.curList.auxField.hh()).rh() = uint16(l)
  24757. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).b0() = prg.normMin(*prg.eqtb[intBase+leftHyphenMinCode-1].int())
  24758. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).b1() = prg.normMin(*prg.eqtb[intBase+rightHyphenMinCode-1].int())
  24759. }
  24760. }
  24761. // \4
  24762. // Declare the procedure called |handle_right_brace|
  24763. func (prg *prg) handleRightBrace() {
  24764. var (
  24765. p, q halfword // for short-term use
  24766. d scaled // holds |split_max_depth| in |insert_group|
  24767. f int32 // holds |floating_penalty| in |insert_group|
  24768. )
  24769. switch prg.curGroup {
  24770. case simpleGroup:
  24771. prg.unsave()
  24772. case bottomLevel:
  24773. {
  24774. if int32(prg.interaction) == errorStopMode {
  24775. }
  24776. prg.printNl(strNumber( /* "! " */ 262))
  24777. prg.print( /* "Too many ]'s" */ 1044)
  24778. }
  24779. // \xref[Too many \]'s]
  24780. {
  24781. prg.helpPtr = 2
  24782. prg.helpLine[1] = /* "You've closed more groups than you opened." */ 1045
  24783. prg.helpLine[0] = /* "Such booboos are generally harmless, so keep going." */ 1046
  24784. }
  24785. prg.error1()
  24786. case semiSimpleGroup, mathShiftGroup, mathLeftGroup:
  24787. prg.extraRightBrace()
  24788. // \4
  24789. // Cases of |handle_right_brace| where a |right_brace| triggers a delayed action
  24790. case hboxGroup:
  24791. prg.package1(smallNumber(0))
  24792. case adjustedHboxGroup:
  24793. prg.adjustTail = uint16(30000 - 5)
  24794. prg.package1(smallNumber(0))
  24795. case vboxGroup:
  24796. prg.endGraf()
  24797. prg.package1(smallNumber(0))
  24798. case vtopGroup:
  24799. prg.endGraf()
  24800. prg.package1(smallNumber(vtopCode))
  24801. case insertGroup:
  24802. prg.endGraf()
  24803. q = *(*prg.eqtb[glueBase+splitTopSkipCode-1].hh()).rh()
  24804. *(*prg.mem[q].hh()).rh() = uint16(int32(*(*prg.mem[q].hh()).rh()) + 1)
  24805. d = *prg.eqtb[dimenBase+splitMaxDepthCode-1].int()
  24806. f = *prg.eqtb[intBase+floatingPenaltyCode-1].int()
  24807. prg.unsave()
  24808. prg.savePtr = uint16(int32(prg.savePtr) - 1)
  24809. // now |saved(0)| is the insertion number, or 255 for |vadjust|
  24810. p = prg.vpackage(*(*prg.mem[prg.curList.headField].hh()).rh(), scaled(0), smallNumber(additional), scaled(07777777777))
  24811. prg.popNest()
  24812. if *prg.saveStack[int32(prg.savePtr)+0].int() < 255 {
  24813. {
  24814. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.getNode(insNodeSize)
  24815. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  24816. }
  24817. *(*prg.mem[prg.curList.tailField].hh()).b0() = byte(insNode)
  24818. *(*prg.mem[prg.curList.tailField].hh()).b1() = byte(*prg.saveStack[int32(prg.savePtr)+0].int() + minQuarterword)
  24819. *prg.mem[int32(prg.curList.tailField)+heightOffset].int() = *prg.mem[int32(p)+heightOffset].int() + *prg.mem[int32(p)+depthOffset].int()
  24820. *(*prg.mem[int32(prg.curList.tailField)+4].hh()).lh() = *(*prg.mem[int32(p)+listOffset].hh()).rh()
  24821. *(*prg.mem[int32(prg.curList.tailField)+4].hh()).rh() = q
  24822. *prg.mem[int32(prg.curList.tailField)+depthOffset].int() = d
  24823. *prg.mem[int32(prg.curList.tailField)+1].int() = f
  24824. } else {
  24825. {
  24826. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.getNode(smallNodeSize)
  24827. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  24828. }
  24829. *(*prg.mem[prg.curList.tailField].hh()).b0() = byte(adjustNode)
  24830. *(*prg.mem[prg.curList.tailField].hh()).b1() = 0 // the |subtype| is not used
  24831. *prg.mem[int32(prg.curList.tailField)+1].int() = int32(*(*prg.mem[int32(p)+listOffset].hh()).rh())
  24832. prg.deleteGlueRef(q)
  24833. }
  24834. prg.freeNode(p, halfword(boxNodeSize))
  24835. if int32(prg.nestPtr) == 0 {
  24836. prg.buildPage()
  24837. }
  24838. case outputGroup:
  24839. // Resume the page builder...
  24840. if int32(prg.curInput.locField) != 0 || int32(prg.curInput.indexField) != outputText && int32(prg.curInput.indexField) != backedUp {
  24841. {
  24842. if int32(prg.interaction) == errorStopMode {
  24843. }
  24844. prg.printNl(strNumber( /* "! " */ 262))
  24845. prg.print( /* "Unbalanced output routine" */ 1010)
  24846. }
  24847. // \xref[Unbalanced output routine]
  24848. {
  24849. prg.helpPtr = 2
  24850. prg.helpLine[1] = /* "Your sneaky output routine has problematic ['s and/or ]'s." */ 1011
  24851. prg.helpLine[0] = /* "I can't handle that very well; good luck." */ 1012
  24852. }
  24853. prg.error1()
  24854. for {
  24855. prg.getToken()
  24856. if int32(prg.curInput.locField) == 0 {
  24857. break
  24858. }
  24859. }
  24860. }
  24861. prg.endTokenList() // conserve stack space in case more outputs are triggered
  24862. prg.endGraf()
  24863. prg.unsave()
  24864. prg.outputActive = false
  24865. prg.insertPenalties = 0
  24866. // Ensure that box 255 is empty after output
  24867. if int32(*(*prg.eqtb[boxBase+255-1].hh()).rh()) != 0 {
  24868. {
  24869. if int32(prg.interaction) == errorStopMode {
  24870. }
  24871. prg.printNl(strNumber( /* "! " */ 262))
  24872. prg.print( /* "Output routine didn't use all of " */ 1013)
  24873. }
  24874. prg.printEsc(strNumber( /* "box" */ 409))
  24875. prg.printInt(255)
  24876. // \xref[Output routine didn't use...]
  24877. {
  24878. prg.helpPtr = 3
  24879. prg.helpLine[2] = /* "Your \\output commands should empty \\box255," */ 1014
  24880. prg.helpLine[1] = /* "e.g., by saying `\\shipout\\box255'." */ 1015
  24881. prg.helpLine[0] = /* "Proceed; I'll discard its present contents." */ 1016
  24882. }
  24883. prg.boxError(eightBits(255))
  24884. }
  24885. if int32(prg.curList.tailField) != int32(prg.curList.headField) {
  24886. *(*prg.mem[prg.pageTail].hh()).rh() = *(*prg.mem[prg.curList.headField].hh()).rh()
  24887. prg.pageTail = prg.curList.tailField
  24888. }
  24889. if int32(*(*prg.mem[30000-2].hh()).rh()) != 0 {
  24890. if int32(*(*prg.mem[30000-1].hh()).rh()) == 0 {
  24891. prg.nest[0].tailField = prg.pageTail
  24892. }
  24893. *(*prg.mem[prg.pageTail].hh()).rh() = *(*prg.mem[30000-1].hh()).rh()
  24894. *(*prg.mem[30000-1].hh()).rh() = *(*prg.mem[30000-2].hh()).rh()
  24895. *(*prg.mem[30000-2].hh()).rh() = 0
  24896. prg.pageTail = uint16(30000 - 2)
  24897. }
  24898. prg.popNest()
  24899. prg.buildPage()
  24900. case discGroup:
  24901. prg.buildDiscretionary()
  24902. case alignGroup:
  24903. prg.backInput()
  24904. prg.curTok = uint16(07777 + frozenCr)
  24905. {
  24906. if int32(prg.interaction) == errorStopMode {
  24907. }
  24908. prg.printNl(strNumber( /* "! " */ 262))
  24909. prg.print( /* "Missing " */ 625)
  24910. }
  24911. prg.printEsc(strNumber( /* "cr" */ 899))
  24912. prg.print( /* " inserted" */ 626)
  24913. // \xref[Missing \\cr inserted]
  24914. {
  24915. prg.helpPtr = 1
  24916. prg.helpLine[0] = /* "I'm guessing that you meant to end an alignment here." */ 1125
  24917. }
  24918. prg.insError()
  24919. case noAlignGroup:
  24920. prg.endGraf()
  24921. prg.unsave()
  24922. prg.alignPeek()
  24923. case vcenterGroup:
  24924. prg.endGraf()
  24925. prg.unsave()
  24926. prg.savePtr = uint16(int32(prg.savePtr) - 2)
  24927. p = prg.vpackage(*(*prg.mem[prg.curList.headField].hh()).rh(), *prg.saveStack[int32(prg.savePtr)+1].int(), smallNumber(*prg.saveStack[int32(prg.savePtr)+0].int()), scaled(07777777777))
  24928. prg.popNest()
  24929. {
  24930. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newNoad()
  24931. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  24932. }
  24933. *(*prg.mem[prg.curList.tailField].hh()).b0() = byte(vcenterNoad)
  24934. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).rh() = uint16(subBox)
  24935. *(*prg.mem[int32(prg.curList.tailField)+1].hh()).lh() = p
  24936. case mathChoiceGroup:
  24937. prg.buildChoices()
  24938. case mathGroup:
  24939. prg.unsave()
  24940. prg.savePtr = uint16(int32(prg.savePtr) - 1)
  24941. *(*prg.mem[*prg.saveStack[int32(prg.savePtr)+0].int()].hh()).rh() = uint16(subMlist)
  24942. p = prg.finMlist(halfword(0))
  24943. *(*prg.mem[*prg.saveStack[int32(prg.savePtr)+0].int()].hh()).lh() = p
  24944. if int32(p) != 0 {
  24945. if int32(*(*prg.mem[p].hh()).rh()) == 0 {
  24946. if int32(*(*prg.mem[p].hh()).b0()) == ordNoad {
  24947. if int32(*(*prg.mem[int32(p)+3].hh()).rh()) == empty {
  24948. if int32(*(*prg.mem[int32(p)+2].hh()).rh()) == empty {
  24949. *prg.mem[*prg.saveStack[int32(prg.savePtr)+0].int()].hh() = *prg.mem[int32(p)+1].hh()
  24950. prg.freeNode(p, halfword(noadSize))
  24951. }
  24952. }
  24953. } else if int32(*(*prg.mem[p].hh()).b0()) == accentNoad {
  24954. if *prg.saveStack[int32(prg.savePtr)+0].int() == int32(prg.curList.tailField)+1 {
  24955. if int32(*(*prg.mem[prg.curList.tailField].hh()).b0()) == ordNoad {
  24956. q = prg.curList.headField
  24957. for int32(*(*prg.mem[q].hh()).rh()) != int32(prg.curList.tailField) {
  24958. q = *(*prg.mem[q].hh()).rh()
  24959. }
  24960. *(*prg.mem[q].hh()).rh() = p
  24961. prg.freeNode(prg.curList.tailField, halfword(noadSize))
  24962. prg.curList.tailField = p
  24963. }
  24964. }
  24965. }
  24966. }
  24967. }
  24968. default:
  24969. prg.confusion(strNumber( /* "rightbrace" */ 1047))
  24970. // \xref[this can't happen rightbrace][\quad rightbrace]
  24971. }
  24972. }
  24973. func (prg *prg) mainControl() {
  24974. var (
  24975. t int32 // general-purpose temporary variable
  24976. )
  24977. if int32(*(*prg.eqtb[everyJobLoc-1].hh()).rh()) != 0 {
  24978. prg.beginTokenList(*(*prg.eqtb[everyJobLoc-1].hh()).rh(), quarterword(everyJobText))
  24979. }
  24980. bigSwitch:
  24981. prg.getXToken()
  24982. reswitch:
  24983. if prg.interrupt != 0 {
  24984. if prg.okToInterrupt {
  24985. prg.backInput()
  24986. {
  24987. if prg.interrupt != 0 {
  24988. prg.pauseForInstructions()
  24989. }
  24990. }
  24991. goto bigSwitch
  24992. }
  24993. }
  24994. // if panicking then check_mem(false); [ ]
  24995. if *prg.eqtb[intBase+tracingCommandsCode-1].int() > 0 {
  24996. prg.showCurCmdChr()
  24997. }
  24998. switch abs(int32(prg.curList.modeField)) + int32(prg.curCmd) {
  24999. case hmode + 11, hmode + 12, hmode + 68:
  25000. goto mainLoop
  25001. case hmode + 16:
  25002. prg.scanCharNum()
  25003. prg.curChr = uint16(prg.curVal)
  25004. goto mainLoop
  25005. case hmode + 65:
  25006. prg.getXToken()
  25007. if int32(prg.curCmd) == letter || int32(prg.curCmd) == otherChar || int32(prg.curCmd) == charGiven || int32(prg.curCmd) == charNum {
  25008. prg.cancelBoundary = true
  25009. }
  25010. goto reswitch
  25011. case hmode + 10:
  25012. if int32(*(*prg.curList.auxField.hh()).lh()) == 1000 {
  25013. goto appendNormalSpace
  25014. } else {
  25015. prg.appSpace()
  25016. }
  25017. case hmode + 64, mmode + 64:
  25018. goto appendNormalSpace
  25019. // \4
  25020. // Cases of |main_control| that are not part of the inner loop
  25021. case vmode + 0, hmode + 0, mmode + 0, vmode + 10,
  25022. mmode + 10, mmode + 65:
  25023. case vmode + 39, hmode + 39, mmode + 39:
  25024. for {
  25025. prg.getXToken()
  25026. if int32(prg.curCmd) != spacer {
  25027. break
  25028. }
  25029. }
  25030. goto reswitch
  25031. case vmode + 14:
  25032. if prg.itsAllOver() {
  25033. goto exit
  25034. } // this is the only way out
  25035. // \4
  25036. // Forbidden cases detected in |main_control|
  25037. case vmode + 22, hmode + 21, mmode + 21, vmode + 70,
  25038. hmode + 70, mmode + 70, vmode + 38, vmode + 44,
  25039. vmode + 48, hmode + 48, vmode + 6, hmode + 6,
  25040. mmode + 6:
  25041. prg.reportIllegalCase()
  25042. // Math-only cases in non-math modes, or vice versa
  25043. case vmode + 7, hmode + 7, vmode + 8, hmode + 8,
  25044. vmode + 17, hmode + 17, vmode + 69, hmode + 69,
  25045. vmode + 50, hmode + 50, vmode + 15, hmode + 15,
  25046. vmode + 49, hmode + 49, vmode + 52, hmode + 52,
  25047. vmode + 66, hmode + 66, vmode + 53, hmode + 53,
  25048. vmode + 54, hmode + 54, vmode + 56, hmode + 56,
  25049. vmode + 55, hmode + 55, vmode + 30, hmode + 30,
  25050. vmode + 51, hmode + 51, vmode + 28, hmode + 28,
  25051. vmode + 46, hmode + 46, mmode + 9, mmode + 13,
  25052. mmode + 14, mmode + 27, mmode + 24, mmode + 33,
  25053. mmode + 36:
  25054. prg.insertDollarSign()
  25055. // \4
  25056. // Cases of |main_control| that build boxes and lists
  25057. case vmode + 36, hmode + 35, mmode + 35:
  25058. {
  25059. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.scanRuleSpec()
  25060. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  25061. }
  25062. if abs(int32(prg.curList.modeField)) == vmode {
  25063. *prg.curList.auxField.int() = -65536000
  25064. } else if abs(int32(prg.curList.modeField)) == hmode {
  25065. *(*prg.curList.auxField.hh()).lh() = 1000
  25066. }
  25067. case vmode + 27, hmode + 26, mmode + 26, mmode + 28:
  25068. prg.appendGlue()
  25069. case vmode + 29, hmode + 29, mmode + 29, mmode + 30:
  25070. prg.appendKern()
  25071. case vmode + 1, hmode + 1:
  25072. prg.newSaveLevel(groupCode(simpleGroup))
  25073. case vmode + 61, hmode + 61, mmode + 61:
  25074. prg.newSaveLevel(groupCode(semiSimpleGroup))
  25075. case vmode + 62, hmode + 62, mmode + 62:
  25076. if int32(prg.curGroup) == semiSimpleGroup {
  25077. prg.unsave()
  25078. } else {
  25079. prg.offSave()
  25080. }
  25081. case vmode + 2, hmode + 2, mmode + 2:
  25082. prg.handleRightBrace()
  25083. case vmode + 21, hmode + 22, mmode + 22:
  25084. t = int32(prg.curChr)
  25085. prg.scanDimen(false, false, false)
  25086. if t == 0 {
  25087. prg.scanBox(prg.curVal)
  25088. } else {
  25089. prg.scanBox(-prg.curVal)
  25090. }
  25091. case vmode + 31, hmode + 31, mmode + 31:
  25092. prg.scanBox(010000000000 + 513 - aLeaders + int32(prg.curChr))
  25093. case vmode + 20, hmode + 20, mmode + 20:
  25094. prg.beginBox(0)
  25095. case vmode + 43:
  25096. prg.newGraf(int32(prg.curChr) > 0)
  25097. case vmode + 11, vmode + 12, vmode + 16, vmode + 68,
  25098. vmode + 3, vmode + 23, vmode + 35, vmode + 45,
  25099. vmode + 47, vmode + 26, vmode + 33, vmode + 64,
  25100. vmode + 65: //
  25101. prg.backInput()
  25102. prg.newGraf(true)
  25103. case hmode + 43, mmode + 43:
  25104. prg.indentInHmode()
  25105. case vmode + 13:
  25106. prg.normalParagraph()
  25107. if int32(prg.curList.modeField) > 0 {
  25108. prg.buildPage()
  25109. }
  25110. case hmode + 13:
  25111. if prg.alignState < 0 {
  25112. prg.offSave()
  25113. } // this tries to
  25114. // recover from an alignment that didn't end properly
  25115. prg.endGraf() // this takes us to the enclosing mode, if |mode>0|
  25116. if int32(prg.curList.modeField) == vmode {
  25117. prg.buildPage()
  25118. }
  25119. case hmode + 14, hmode + 27, hmode + 36, hmode + 24,
  25120. hmode + 32:
  25121. prg.headForVmode()
  25122. case vmode + 37, hmode + 37, mmode + 37, hmode + 38,
  25123. mmode + 38:
  25124. prg.beginInsertOrAdjust()
  25125. case vmode + 18, hmode + 18, mmode + 18:
  25126. prg.makeMark()
  25127. case vmode + 42, hmode + 42, mmode + 42:
  25128. prg.appendPenalty()
  25129. case vmode + 25, hmode + 25, mmode + 25:
  25130. prg.deleteLast()
  25131. case vmode + 24, hmode + 23, mmode + 23:
  25132. prg.unpackage()
  25133. case hmode + 44:
  25134. prg.appendItalicCorrection()
  25135. case mmode + 44:
  25136. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newKern(scaled(0))
  25137. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  25138. case hmode + 47, mmode + 47:
  25139. prg.appendDiscretionary()
  25140. case hmode + 45:
  25141. prg.makeAccent()
  25142. case vmode + 5, hmode + 5, mmode + 5, vmode + 4,
  25143. hmode + 4, mmode + 4:
  25144. prg.alignError()
  25145. case vmode + 34, hmode + 34, mmode + 34:
  25146. prg.noAlignError()
  25147. case vmode + 63, hmode + 63, mmode + 63:
  25148. prg.omitError()
  25149. case vmode + 32, hmode + 33:
  25150. prg.initAlign()
  25151. case mmode + 32:
  25152. if prg.privileged() {
  25153. if int32(prg.curGroup) == mathShiftGroup {
  25154. prg.initAlign()
  25155. } else {
  25156. prg.offSave()
  25157. }
  25158. }
  25159. case vmode + 9, hmode + 9:
  25160. prg.doEndv()
  25161. case vmode + 67, hmode + 67, mmode + 67:
  25162. prg.csError()
  25163. case hmode + 3:
  25164. prg.initMath()
  25165. case mmode + 48:
  25166. if prg.privileged() {
  25167. if int32(prg.curGroup) == mathShiftGroup {
  25168. prg.startEqNo()
  25169. } else {
  25170. prg.offSave()
  25171. }
  25172. }
  25173. case mmode + 1:
  25174. {
  25175. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newNoad()
  25176. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  25177. }
  25178. prg.backInput()
  25179. prg.scanMath(halfword(int32(prg.curList.tailField) + 1))
  25180. case mmode + 11, mmode + 12, mmode + 68:
  25181. prg.setMathChar(int32(*(*prg.eqtb[mathCodeBase+int32(prg.curChr)-1].hh()).rh()) - 0)
  25182. case mmode + 16:
  25183. prg.scanCharNum()
  25184. prg.curChr = uint16(prg.curVal)
  25185. prg.setMathChar(int32(*(*prg.eqtb[mathCodeBase+int32(prg.curChr)-1].hh()).rh()) - 0)
  25186. case mmode + 17:
  25187. prg.scanFifteenBitInt()
  25188. prg.setMathChar(prg.curVal)
  25189. case mmode + 69:
  25190. prg.setMathChar(int32(prg.curChr))
  25191. case mmode + 15:
  25192. prg.scanTwentySevenBitInt()
  25193. prg.setMathChar(prg.curVal / 010000)
  25194. case mmode + 50:
  25195. {
  25196. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newNoad()
  25197. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  25198. }
  25199. *(*prg.mem[prg.curList.tailField].hh()).b0() = byte(prg.curChr)
  25200. prg.scanMath(halfword(int32(prg.curList.tailField) + 1))
  25201. case mmode + 51:
  25202. prg.mathLimitSwitch()
  25203. case mmode + 66:
  25204. prg.mathRadical()
  25205. case mmode + 45, mmode + 46:
  25206. prg.mathAc()
  25207. case mmode + 56:
  25208. prg.scanSpec(groupCode(vcenterGroup), false)
  25209. prg.normalParagraph()
  25210. prg.pushNest()
  25211. prg.curList.modeField = int16(-vmode)
  25212. *prg.curList.auxField.int() = -65536000
  25213. if int32(*(*prg.eqtb[everyVboxLoc-1].hh()).rh()) != 0 {
  25214. prg.beginTokenList(*(*prg.eqtb[everyVboxLoc-1].hh()).rh(), quarterword(everyVboxText))
  25215. }
  25216. case mmode + 53:
  25217. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newStyle(smallNumber(prg.curChr))
  25218. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  25219. case mmode + 55:
  25220. {
  25221. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newGlue(halfword(memBot))
  25222. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  25223. }
  25224. *(*prg.mem[prg.curList.tailField].hh()).b1() = byte(condMathGlue)
  25225. case mmode + 54:
  25226. prg.appendChoices()
  25227. case mmode + 8, mmode + 7:
  25228. prg.subSup()
  25229. case mmode + 52:
  25230. prg.mathFraction()
  25231. case mmode + 49:
  25232. prg.mathLeftRight()
  25233. case mmode + 3:
  25234. if int32(prg.curGroup) == mathShiftGroup {
  25235. prg.afterMath()
  25236. } else {
  25237. prg.offSave()
  25238. }
  25239. // \4
  25240. // Cases of |main_control| that don't depend on |mode|
  25241. case vmode + 71, hmode + 71, mmode + 71, vmode + 72,
  25242. hmode + 72, mmode + 72, vmode + 73, hmode + 73,
  25243. mmode + 73, vmode + 74, hmode + 74, mmode + 74,
  25244. vmode + 75, hmode + 75, mmode + 75, vmode + 76,
  25245. hmode + 76, mmode + 76, vmode + 77, hmode + 77,
  25246. mmode + 77, vmode + 78, hmode + 78, mmode + 78,
  25247. vmode + 79, hmode + 79, mmode + 79, vmode + 80,
  25248. hmode + 80, mmode + 80, vmode + 81, hmode + 81,
  25249. mmode + 81, vmode + 82, hmode + 82, mmode + 82,
  25250. vmode + 83, hmode + 83, mmode + 83, vmode + 84,
  25251. hmode + 84, mmode + 84, vmode + 85, hmode + 85,
  25252. mmode + 85, vmode + 86, hmode + 86, mmode + 86,
  25253. vmode + 87, hmode + 87, mmode + 87, vmode + 88,
  25254. hmode + 88, mmode + 88, vmode + 89, hmode + 89,
  25255. mmode + 89, vmode + 90, hmode + 90, mmode + 90,
  25256. vmode + 91, hmode + 91, mmode + 91, vmode + 92,
  25257. hmode + 92, mmode + 92, vmode + 93, hmode + 93,
  25258. mmode + 93, vmode + 94, hmode + 94, mmode + 94,
  25259. vmode + 95, hmode + 95, mmode + 95, vmode + 96,
  25260. hmode + 96, mmode + 96, vmode + 97, hmode + 97,
  25261. mmode + 97, vmode + 98, hmode + 98, mmode + 98,
  25262. vmode + 99, hmode + 99, mmode + 99, vmode + 100,
  25263. hmode + 100, mmode + 100:
  25264. prg.prefixedCommand()
  25265. case vmode + 40, hmode + 40, mmode + 40:
  25266. prg.getToken()
  25267. prg.afterToken = prg.curTok
  25268. case vmode + 41, hmode + 41, mmode + 41:
  25269. prg.getToken()
  25270. prg.saveForAfter(prg.curTok)
  25271. case vmode + 60, hmode + 60, mmode + 60:
  25272. prg.openOrCloseIn()
  25273. case vmode + 58, hmode + 58, mmode + 58:
  25274. prg.issueMessage()
  25275. case vmode + 57, hmode + 57, mmode + 57:
  25276. prg.shiftCase()
  25277. case vmode + 19, hmode + 19, mmode + 19:
  25278. prg.showWhatever()
  25279. // \4
  25280. // Cases of |main_control| that are for extensions to \TeX
  25281. case vmode + 59, hmode + 59, mmode + 59:
  25282. prg.doExtension()
  25283. } // of the big |case| statement
  25284. // of the big |case| statement
  25285. goto bigSwitch
  25286. mainLoop:
  25287. prg.mainS = int32(*(*prg.eqtb[sfCodeBase+int32(prg.curChr)-1].hh()).rh())
  25288. if prg.mainS == 1000 {
  25289. *(*prg.curList.auxField.hh()).lh() = 1000
  25290. } else if prg.mainS < 1000 {
  25291. if prg.mainS > 0 {
  25292. *(*prg.curList.auxField.hh()).lh() = uint16(prg.mainS)
  25293. }
  25294. } else if int32(*(*prg.curList.auxField.hh()).lh()) < 1000 {
  25295. *(*prg.curList.auxField.hh()).lh() = 1000
  25296. } else {
  25297. *(*prg.curList.auxField.hh()).lh() = uint16(prg.mainS)
  25298. }
  25299. prg.mainF = byte(*(*prg.eqtb[curFontLoc-1].hh()).rh())
  25300. prg.bchar = prg.fontBchar[prg.mainF]
  25301. prg.falseBchar = prg.fontFalseBchar[prg.mainF]
  25302. if int32(prg.curList.modeField) > 0 {
  25303. if *prg.eqtb[intBase+languageCode-1].int() != int32(*(*prg.curList.auxField.hh()).rh()) {
  25304. prg.fixLanguage()
  25305. }
  25306. }
  25307. /* */ {
  25308. prg.ligStack = prg.avail
  25309. if int32(prg.ligStack) == 0 {
  25310. prg.ligStack = prg.getAvail()
  25311. } else {
  25312. prg.avail = *(*prg.mem[prg.ligStack].hh()).rh()
  25313. *(*prg.mem[prg.ligStack].hh()).rh() = 0 /* dyn_used:= dyn_used+1 ; [ ] */
  25314. }
  25315. }
  25316. *(*prg.mem[prg.ligStack].hh()).b0() = prg.mainF
  25317. prg.curL = uint16(int32(prg.curChr) + minQuarterword)
  25318. *(*prg.mem[prg.ligStack].hh()).b1() = byte(prg.curL)
  25319. prg.curQ = prg.curList.tailField
  25320. if prg.cancelBoundary {
  25321. prg.cancelBoundary = false
  25322. prg.mainK = uint16(nonAddress)
  25323. } else {
  25324. prg.mainK = prg.bcharLabel[prg.mainF]
  25325. }
  25326. if int32(prg.mainK) == nonAddress {
  25327. goto mainLoopMove_plus_2
  25328. } // no left boundary processing
  25329. prg.curR = prg.curL
  25330. prg.curL = uint16(256 + minQuarterword)
  25331. goto mainLigLoop_plus_1 // begin with cursor after left boundary
  25332. // begin with cursor after left boundary
  25333. mainLoopWrapup:
  25334. if int32(prg.curL) < 256+minQuarterword {
  25335. if int32(*(*prg.mem[prg.curQ].hh()).rh()) > 0 {
  25336. if int32(*(*prg.mem[prg.curList.tailField].hh()).b1()) == prg.hyphenChar[prg.mainF]+minQuarterword {
  25337. prg.insDisc = true
  25338. }
  25339. }
  25340. if prg.ligaturePresent {
  25341. prg.mainP = prg.newLigature(prg.mainF, quarterword(prg.curL), *(*prg.mem[prg.curQ].hh()).rh())
  25342. if prg.lftHit {
  25343. *(*prg.mem[prg.mainP].hh()).b1() = 2
  25344. prg.lftHit = false
  25345. }
  25346. if prg.rtHit {
  25347. if int32(prg.ligStack) == 0 {
  25348. *(*prg.mem[prg.mainP].hh()).b1() = byte(int32(*(*prg.mem[prg.mainP].hh()).b1()) + 1)
  25349. prg.rtHit = false
  25350. }
  25351. }
  25352. *(*prg.mem[prg.curQ].hh()).rh() = prg.mainP
  25353. prg.curList.tailField = prg.mainP
  25354. prg.ligaturePresent = false
  25355. }
  25356. if prg.insDisc {
  25357. prg.insDisc = false
  25358. if int32(prg.curList.modeField) > 0 {
  25359. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newDisc()
  25360. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  25361. }
  25362. }
  25363. }
  25364. mainLoopMove:
  25365. if int32(prg.ligStack) == 0 {
  25366. goto reswitch
  25367. }
  25368. prg.curQ = prg.curList.tailField
  25369. prg.curL = uint16(*(*prg.mem[prg.ligStack].hh()).b1())
  25370. mainLoopMove_plus_1:
  25371. if !(int32(prg.ligStack) >= int32(prg.hiMemMin)) {
  25372. goto mainLoopMoveLig
  25373. }
  25374. mainLoopMove_plus_2:
  25375. if int32(prg.curChr) < int32(prg.fontBc[prg.mainF]) || int32(prg.curChr) > int32(prg.fontEc[prg.mainF]) {
  25376. prg.charWarning(prg.mainF, eightBits(prg.curChr))
  25377. {
  25378. *(*prg.mem[prg.ligStack].hh()).rh() = prg.avail
  25379. prg.avail = prg.ligStack /* dyn_used:= dyn_used-1 ; [ ] */
  25380. }
  25381. goto bigSwitch
  25382. }
  25383. prg.mainI = *prg.fontInfo[prg.charBase[prg.mainF]+int32(prg.curL)].qqqq()
  25384. if !(int32(prg.mainI.b0) > minQuarterword) {
  25385. prg.charWarning(prg.mainF, eightBits(prg.curChr))
  25386. {
  25387. *(*prg.mem[prg.ligStack].hh()).rh() = prg.avail
  25388. prg.avail = prg.ligStack /* dyn_used:= dyn_used-1 ; [ ] */
  25389. }
  25390. goto bigSwitch
  25391. }
  25392. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.ligStack
  25393. prg.curList.tailField = prg.ligStack
  25394. mainLoopLookahead:
  25395. prg.getNext() // set only |cur_cmd| and |cur_chr|, for speed
  25396. if int32(prg.curCmd) == letter {
  25397. goto mainLoopLookahead_plus_1
  25398. }
  25399. if int32(prg.curCmd) == otherChar {
  25400. goto mainLoopLookahead_plus_1
  25401. }
  25402. if int32(prg.curCmd) == charGiven {
  25403. goto mainLoopLookahead_plus_1
  25404. }
  25405. prg.xToken() // now expand and set |cur_cmd|, |cur_chr|, |cur_tok|
  25406. if int32(prg.curCmd) == letter {
  25407. goto mainLoopLookahead_plus_1
  25408. }
  25409. if int32(prg.curCmd) == otherChar {
  25410. goto mainLoopLookahead_plus_1
  25411. }
  25412. if int32(prg.curCmd) == charGiven {
  25413. goto mainLoopLookahead_plus_1
  25414. }
  25415. if int32(prg.curCmd) == charNum {
  25416. prg.scanCharNum()
  25417. prg.curChr = uint16(prg.curVal)
  25418. goto mainLoopLookahead_plus_1
  25419. }
  25420. if int32(prg.curCmd) == noBoundary {
  25421. prg.bchar = uint16(256 + minQuarterword)
  25422. }
  25423. prg.curR = prg.bchar
  25424. prg.ligStack = 0
  25425. goto mainLigLoop
  25426. mainLoopLookahead_plus_1:
  25427. prg.mainS = int32(*(*prg.eqtb[sfCodeBase+int32(prg.curChr)-1].hh()).rh())
  25428. if prg.mainS == 1000 {
  25429. *(*prg.curList.auxField.hh()).lh() = 1000
  25430. } else if prg.mainS < 1000 {
  25431. if prg.mainS > 0 {
  25432. *(*prg.curList.auxField.hh()).lh() = uint16(prg.mainS)
  25433. }
  25434. } else if int32(*(*prg.curList.auxField.hh()).lh()) < 1000 {
  25435. *(*prg.curList.auxField.hh()).lh() = 1000
  25436. } else {
  25437. *(*prg.curList.auxField.hh()).lh() = uint16(prg.mainS)
  25438. }
  25439. /* */ {
  25440. prg.ligStack = prg.avail
  25441. if int32(prg.ligStack) == 0 {
  25442. prg.ligStack = prg.getAvail()
  25443. } else {
  25444. prg.avail = *(*prg.mem[prg.ligStack].hh()).rh()
  25445. *(*prg.mem[prg.ligStack].hh()).rh() = 0 /* dyn_used:= dyn_used+1 ; [ ] */
  25446. }
  25447. }
  25448. *(*prg.mem[prg.ligStack].hh()).b0() = prg.mainF
  25449. prg.curR = uint16(int32(prg.curChr) + minQuarterword)
  25450. *(*prg.mem[prg.ligStack].hh()).b1() = byte(prg.curR)
  25451. if int32(prg.curR) == int32(prg.falseBchar) {
  25452. prg.curR = uint16(256 + minQuarterword)
  25453. }
  25454. mainLigLoop:
  25455. if (int32(prg.mainI.b2)-minQuarterword)%4 != ligTag {
  25456. goto mainLoopWrapup
  25457. }
  25458. if int32(prg.curR) == 256+minQuarterword {
  25459. goto mainLoopWrapup
  25460. }
  25461. prg.mainK = uint16(prg.ligKernBase[prg.mainF] + int32(prg.mainI.b3))
  25462. prg.mainJ = *prg.fontInfo[prg.mainK].qqqq()
  25463. if int32(prg.mainJ.b0) <= 128+minQuarterword {
  25464. goto mainLigLoop_plus_2
  25465. }
  25466. prg.mainK = uint16(prg.ligKernBase[prg.mainF] + 256*int32(prg.mainJ.b2) + int32(prg.mainJ.b3) + 32768 - 256*(128+minQuarterword))
  25467. mainLigLoop_plus_1:
  25468. prg.mainJ = *prg.fontInfo[prg.mainK].qqqq()
  25469. mainLigLoop_plus_2:
  25470. if int32(prg.mainJ.b1) == int32(prg.curR) {
  25471. if int32(prg.mainJ.b0) <= 128+minQuarterword {
  25472. if int32(prg.mainJ.b2) >= 128+minQuarterword {
  25473. if int32(prg.curL) < 256+minQuarterword {
  25474. if int32(*(*prg.mem[prg.curQ].hh()).rh()) > 0 {
  25475. if int32(*(*prg.mem[prg.curList.tailField].hh()).b1()) == prg.hyphenChar[prg.mainF]+minQuarterword {
  25476. prg.insDisc = true
  25477. }
  25478. }
  25479. if prg.ligaturePresent {
  25480. prg.mainP = prg.newLigature(prg.mainF, quarterword(prg.curL), *(*prg.mem[prg.curQ].hh()).rh())
  25481. if prg.lftHit {
  25482. *(*prg.mem[prg.mainP].hh()).b1() = 2
  25483. prg.lftHit = false
  25484. }
  25485. if prg.rtHit {
  25486. if int32(prg.ligStack) == 0 {
  25487. *(*prg.mem[prg.mainP].hh()).b1() = byte(int32(*(*prg.mem[prg.mainP].hh()).b1()) + 1)
  25488. prg.rtHit = false
  25489. }
  25490. }
  25491. *(*prg.mem[prg.curQ].hh()).rh() = prg.mainP
  25492. prg.curList.tailField = prg.mainP
  25493. prg.ligaturePresent = false
  25494. }
  25495. if prg.insDisc {
  25496. prg.insDisc = false
  25497. if int32(prg.curList.modeField) > 0 {
  25498. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newDisc()
  25499. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  25500. }
  25501. }
  25502. }
  25503. {
  25504. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newKern(*prg.fontInfo[prg.kernBase[prg.mainF]+256*int32(prg.mainJ.b2)+int32(prg.mainJ.b3)].int())
  25505. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  25506. }
  25507. goto mainLoopMove
  25508. }
  25509. if int32(prg.curL) == 256+minQuarterword {
  25510. prg.lftHit = true
  25511. } else if int32(prg.ligStack) == 0 {
  25512. prg.rtHit = true
  25513. }
  25514. {
  25515. if prg.interrupt != 0 {
  25516. prg.pauseForInstructions()
  25517. }
  25518. } // allow a way out in case there's an infinite ligature loop
  25519. switch prg.mainJ.b2 {
  25520. case 1 + minQuarterword, 5 + minQuarterword:
  25521. prg.curL = uint16(prg.mainJ.b3) // \.[=:\?], \.[=:\?>]
  25522. prg.mainI = *prg.fontInfo[prg.charBase[prg.mainF]+int32(prg.curL)].qqqq()
  25523. prg.ligaturePresent = true
  25524. case 2 + minQuarterword, 6 + minQuarterword:
  25525. prg.curR = uint16(prg.mainJ.b3) // \.[\?=:], \.[\?=:>]
  25526. if int32(prg.ligStack) == 0 {
  25527. prg.ligStack = prg.newLigItem(quarterword(prg.curR))
  25528. prg.bchar = uint16(256 + minQuarterword)
  25529. } else if int32(prg.ligStack) >= int32(prg.hiMemMin) {
  25530. prg.mainP = prg.ligStack
  25531. prg.ligStack = prg.newLigItem(quarterword(prg.curR))
  25532. *(*prg.mem[int32(prg.ligStack)+1].hh()).rh() = prg.mainP
  25533. } else {
  25534. *(*prg.mem[prg.ligStack].hh()).b1() = byte(prg.curR)
  25535. }
  25536. case 3 + minQuarterword:
  25537. prg.curR = uint16(prg.mainJ.b3) // \.[\?=:\?]
  25538. prg.mainP = prg.ligStack
  25539. prg.ligStack = prg.newLigItem(quarterword(prg.curR))
  25540. *(*prg.mem[prg.ligStack].hh()).rh() = prg.mainP
  25541. case 7 + minQuarterword, 11 + minQuarterword:
  25542. if int32(prg.curL) < 256+minQuarterword {
  25543. if int32(*(*prg.mem[prg.curQ].hh()).rh()) > 0 {
  25544. if int32(*(*prg.mem[prg.curList.tailField].hh()).b1()) == prg.hyphenChar[prg.mainF]+minQuarterword {
  25545. prg.insDisc = true
  25546. }
  25547. }
  25548. if prg.ligaturePresent {
  25549. prg.mainP = prg.newLigature(prg.mainF, quarterword(prg.curL), *(*prg.mem[prg.curQ].hh()).rh())
  25550. if prg.lftHit {
  25551. *(*prg.mem[prg.mainP].hh()).b1() = 2
  25552. prg.lftHit = false
  25553. }
  25554. if false {
  25555. if int32(prg.ligStack) == 0 {
  25556. *(*prg.mem[prg.mainP].hh()).b1() = byte(int32(*(*prg.mem[prg.mainP].hh()).b1()) + 1)
  25557. prg.rtHit = false
  25558. }
  25559. }
  25560. *(*prg.mem[prg.curQ].hh()).rh() = prg.mainP
  25561. prg.curList.tailField = prg.mainP
  25562. prg.ligaturePresent = false
  25563. }
  25564. if prg.insDisc {
  25565. prg.insDisc = false
  25566. if int32(prg.curList.modeField) > 0 {
  25567. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.newDisc()
  25568. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  25569. }
  25570. }
  25571. } // \.[\?=:\?>], \.[\?=:\?>>]
  25572. prg.curQ = prg.curList.tailField
  25573. prg.curL = uint16(prg.mainJ.b3)
  25574. prg.mainI = *prg.fontInfo[prg.charBase[prg.mainF]+int32(prg.curL)].qqqq()
  25575. prg.ligaturePresent = true
  25576. default:
  25577. prg.curL = uint16(prg.mainJ.b3)
  25578. prg.ligaturePresent = true // \.[=:]
  25579. if int32(prg.ligStack) == 0 {
  25580. goto mainLoopWrapup
  25581. } else {
  25582. goto mainLoopMove_plus_1
  25583. }
  25584. }
  25585. if int32(prg.mainJ.b2) > 4+minQuarterword {
  25586. if int32(prg.mainJ.b2) != 7+minQuarterword {
  25587. goto mainLoopWrapup
  25588. }
  25589. }
  25590. if int32(prg.curL) < 256+minQuarterword {
  25591. goto mainLigLoop
  25592. }
  25593. prg.mainK = prg.bcharLabel[prg.mainF]
  25594. goto mainLigLoop_plus_1
  25595. }
  25596. }
  25597. if int32(prg.mainJ.b0) == 0+minQuarterword {
  25598. prg.mainK = uint16(int32(prg.mainK) + 1)
  25599. } else {
  25600. if int32(prg.mainJ.b0) >= 128+minQuarterword {
  25601. goto mainLoopWrapup
  25602. }
  25603. prg.mainK = uint16(int32(prg.mainK) + int32(prg.mainJ.b0) - minQuarterword + 1)
  25604. }
  25605. goto mainLigLoop_plus_1
  25606. mainLoopMoveLig:
  25607. prg.mainP = *(*prg.mem[int32(prg.ligStack)+1].hh()).rh()
  25608. if int32(prg.mainP) > 0 {
  25609. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.mainP
  25610. prg.curList.tailField = *(*prg.mem[prg.curList.tailField].hh()).rh()
  25611. } // append a single character
  25612. prg.tempPtr = prg.ligStack
  25613. prg.ligStack = *(*prg.mem[prg.tempPtr].hh()).rh()
  25614. prg.freeNode(prg.tempPtr, halfword(smallNodeSize))
  25615. prg.mainI = *prg.fontInfo[prg.charBase[prg.mainF]+int32(prg.curL)].qqqq()
  25616. prg.ligaturePresent = true
  25617. if int32(prg.ligStack) == 0 {
  25618. if int32(prg.mainP) > 0 {
  25619. goto mainLoopLookahead
  25620. } else {
  25621. prg.curR = prg.bchar
  25622. }
  25623. } else {
  25624. prg.curR = uint16(*(*prg.mem[prg.ligStack].hh()).b1())
  25625. }
  25626. goto mainLigLoop
  25627. appendNormalSpace:
  25628. if int32(*(*prg.eqtb[glueBase+spaceSkipCode-1].hh()).rh()) == memBot {
  25629. {
  25630. prg.mainP = prg.fontGlue[*(*prg.eqtb[curFontLoc-1].hh()).rh()]
  25631. if int32(prg.mainP) == 0 {
  25632. prg.mainP = prg.newSpec(halfword(memBot))
  25633. prg.mainK = uint16(prg.paramBase[*(*prg.eqtb[curFontLoc-1].hh()).rh()] + spaceCode)
  25634. *prg.mem[int32(prg.mainP)+widthOffset].int() = *prg.fontInfo[prg.mainK].int() // that's |space(cur_font)|
  25635. *prg.mem[int32(prg.mainP)+2].int() = *prg.fontInfo[int32(prg.mainK)+1].int() // and |space_stretch(cur_font)|
  25636. *prg.mem[int32(prg.mainP)+3].int() = *prg.fontInfo[int32(prg.mainK)+2].int() // and |space_shrink(cur_font)|
  25637. prg.fontGlue[*(*prg.eqtb[curFontLoc-1].hh()).rh()] = prg.mainP
  25638. }
  25639. }
  25640. prg.tempPtr = prg.newGlue(prg.mainP)
  25641. } else {
  25642. prg.tempPtr = prg.newParamGlue(smallNumber(spaceSkipCode))
  25643. }
  25644. *(*prg.mem[prg.curList.tailField].hh()).rh() = prg.tempPtr
  25645. prg.curList.tailField = prg.tempPtr
  25646. goto bigSwitch
  25647. exit:
  25648. } // \2
  25649. func (prg *prg) giveErrHelp() {
  25650. prg.tokenShow(*(*prg.eqtb[errHelpLoc-1].hh()).rh())
  25651. }
  25652. // 1303.
  25653. // tangle:pos tex.web:23781:5:
  25654. // Corresponding to the procedure that dumps a format file, we have a function
  25655. // that reads one in. The function returns |false| if the dumped format is
  25656. // incompatible with the present \TeX\ table sizes, etc.
  25657. // \4
  25658. // Declare the function called |open_fmt_file|
  25659. func (prg *prg) openFmtFile() (r bool) {
  25660. var (
  25661. j /* 0..bufSize */ uint16 // the first space after the format file name
  25662. )
  25663. j = prg.curInput.locField
  25664. if int32(prg.buffer[prg.curInput.locField]) == '&' {
  25665. prg.curInput.locField = uint16(int32(prg.curInput.locField) + 1)
  25666. j = prg.curInput.locField
  25667. prg.buffer[prg.last] = ' '
  25668. for int32(prg.buffer[j]) != ' ' {
  25669. j = uint16(int32(j) + 1)
  25670. }
  25671. prg.packBufferedName(smallNumber(0), int32(prg.curInput.locField), int32(j)-1) // try first without the system file area
  25672. if prg.wOpenIn(prg.fmtFile) {
  25673. goto found
  25674. }
  25675. prg.packBufferedName(smallNumber(formatAreaLength), int32(prg.curInput.locField), int32(j)-1)
  25676. // now try the system format file area
  25677. if prg.wOpenIn(prg.fmtFile) {
  25678. goto found
  25679. }
  25680. prg.termOut.Writeln("Sorry, I can't find that format;", " will try PLAIN.")
  25681. // \xref[Sorry, I can't find...]
  25682. }
  25683. // now pull out all the stops: try for the system \.[plain] file
  25684. prg.packBufferedName(smallNumber(formatDefaultLength-formatExtLength), 1, 0)
  25685. if !prg.wOpenIn(prg.fmtFile) {
  25686. prg.termOut.Writeln("I can't find the PLAIN format file!")
  25687. // \xref[I can't find PLAIN...]
  25688. // \xref[plain]
  25689. r = false
  25690. goto exit
  25691. }
  25692. found:
  25693. prg.curInput.locField = j
  25694. r = true
  25695. exit:
  25696. ;
  25697. return r
  25698. }
  25699. func (prg *prg) loadFmtFile() (r bool) {
  25700. var (
  25701. j, k int32 // all-purpose indices
  25702. p, q halfword // all-purpose pointers
  25703. x int32 // something undumped
  25704. w fourQuarters // four ASCII codes
  25705. )
  25706. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  25707. if x != 504454778 {
  25708. goto badFmt
  25709. } // check that strings are the same
  25710. {
  25711. prg.fmtFile.Get()
  25712. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  25713. }
  25714. if x != memBot {
  25715. goto badFmt
  25716. }
  25717. {
  25718. prg.fmtFile.Get()
  25719. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  25720. }
  25721. if x != 30000 {
  25722. goto badFmt
  25723. }
  25724. {
  25725. prg.fmtFile.Get()
  25726. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  25727. }
  25728. if x != eqtbSize {
  25729. goto badFmt
  25730. }
  25731. {
  25732. prg.fmtFile.Get()
  25733. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  25734. }
  25735. if x != hashPrime {
  25736. goto badFmt
  25737. }
  25738. {
  25739. prg.fmtFile.Get()
  25740. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  25741. }
  25742. if x != hyphSize {
  25743. goto badFmt
  25744. }
  25745. // Undump the string pool
  25746. {
  25747. {
  25748. prg.fmtFile.Get()
  25749. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  25750. }
  25751. if x < 0 {
  25752. goto badFmt
  25753. }
  25754. if x > poolSize {
  25755. prg.termOut.Writeln("---! Must increase the ", "string pool size") /* \xref[Must increase the x] */ /* \xref[Must increase the x] */
  25756. goto badFmt
  25757. } else {
  25758. prg.poolPtr = uint16(x)
  25759. }
  25760. }
  25761. {
  25762. {
  25763. prg.fmtFile.Get()
  25764. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  25765. }
  25766. if x < 0 {
  25767. goto badFmt
  25768. }
  25769. if x > maxStrings {
  25770. prg.termOut.Writeln("---! Must increase the ", "max strings") /* \xref[Must increase the x] */ /* \xref[Must increase the x] */
  25771. goto badFmt
  25772. } else {
  25773. prg.strPtr = uint16(x)
  25774. }
  25775. }
  25776. for ii := int32(0); ii <= int32(prg.strPtr); ii++ {
  25777. k = ii
  25778. _ = k
  25779. {
  25780. prg.fmtFile.Get()
  25781. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  25782. }
  25783. if x < 0 || x > int32(prg.poolPtr) {
  25784. goto badFmt
  25785. } else {
  25786. prg.strStart[k] = uint16(x)
  25787. }
  25788. }
  25789. k = 0
  25790. for k+4 < int32(prg.poolPtr) {
  25791. {
  25792. prg.fmtFile.Get()
  25793. w = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).qqqq()
  25794. }
  25795. prg.strPool[k] = byte(int32(w.b0) - minQuarterword)
  25796. prg.strPool[k+1] = byte(int32(w.b1) - minQuarterword)
  25797. prg.strPool[k+2] = byte(int32(w.b2) - minQuarterword)
  25798. prg.strPool[k+3] = byte(int32(w.b3) - minQuarterword)
  25799. k = k + 4
  25800. }
  25801. k = int32(prg.poolPtr) - 4
  25802. {
  25803. prg.fmtFile.Get()
  25804. w = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).qqqq()
  25805. }
  25806. prg.strPool[k] = byte(int32(w.b0) - minQuarterword)
  25807. prg.strPool[k+1] = byte(int32(w.b1) - minQuarterword)
  25808. prg.strPool[k+2] = byte(int32(w.b2) - minQuarterword)
  25809. prg.strPool[k+3] = byte(int32(w.b3) - minQuarterword)
  25810. prg.initStrPtr = prg.strPtr
  25811. prg.initPoolPtr = prg.poolPtr
  25812. // Undump the dynamic memory
  25813. {
  25814. {
  25815. prg.fmtFile.Get()
  25816. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  25817. }
  25818. if x < memBot+glueSpecSize+glueSpecSize+glueSpecSize+glueSpecSize+glueSpecSize-1+1000 || x > 30000-13-1 {
  25819. goto badFmt
  25820. } else {
  25821. prg.loMemMax = uint16(x)
  25822. }
  25823. }
  25824. {
  25825. {
  25826. prg.fmtFile.Get()
  25827. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  25828. }
  25829. if x < memBot+glueSpecSize+glueSpecSize+glueSpecSize+glueSpecSize+glueSpecSize-1+1 || x > int32(prg.loMemMax) {
  25830. goto badFmt
  25831. } else {
  25832. prg.rover = uint16(x)
  25833. }
  25834. }
  25835. p = uint16(memBot)
  25836. q = prg.rover
  25837. for {
  25838. for ii := int32(p); ii <= int32(q)+1; ii++ {
  25839. k = ii
  25840. _ = k
  25841. prg.fmtFile.Get()
  25842. prg.mem[k] = *(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))
  25843. }
  25844. p = uint16(int32(q) + int32(*(*prg.mem[q].hh()).lh()))
  25845. if int32(p) > int32(prg.loMemMax) || int32(q) >= int32(*(*prg.mem[int32(q)+1].hh()).rh()) && int32(*(*prg.mem[int32(q)+1].hh()).rh()) != int32(prg.rover) {
  25846. goto badFmt
  25847. }
  25848. q = *(*prg.mem[int32(q)+1].hh()).rh()
  25849. if int32(q) == int32(prg.rover) {
  25850. break
  25851. }
  25852. }
  25853. for ii := int32(p); ii <= int32(prg.loMemMax); ii++ {
  25854. k = ii
  25855. _ = k
  25856. prg.fmtFile.Get()
  25857. prg.mem[k] = *(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))
  25858. }
  25859. if memMin < memBot-2 {
  25860. p = *(*prg.mem[int32(prg.rover)+1].hh()).lh()
  25861. q = uint16(memMin + 1)
  25862. *(*prg.mem[memMin].hh()).rh() = 0
  25863. *(*prg.mem[memMin].hh()).lh() = 0 // we don't use the bottom word
  25864. *(*prg.mem[int32(p)+1].hh()).rh() = q
  25865. *(*prg.mem[int32(prg.rover)+1].hh()).lh() = q
  25866. *(*prg.mem[int32(q)+1].hh()).rh() = prg.rover
  25867. *(*prg.mem[int32(q)+1].hh()).lh() = p
  25868. *(*prg.mem[q].hh()).rh() = 65535
  25869. *(*prg.mem[q].hh()).lh() = uint16(memBot - int32(q))
  25870. }
  25871. {
  25872. {
  25873. prg.fmtFile.Get()
  25874. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  25875. }
  25876. if x < int32(prg.loMemMax)+1 || x > 30000-13 {
  25877. goto badFmt
  25878. } else {
  25879. prg.hiMemMin = uint16(x)
  25880. }
  25881. }
  25882. {
  25883. {
  25884. prg.fmtFile.Get()
  25885. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  25886. }
  25887. if x < 0 || x > 30000 {
  25888. goto badFmt
  25889. } else {
  25890. prg.avail = uint16(x)
  25891. }
  25892. }
  25893. prg.memEnd = 30000
  25894. for ii := int32(prg.hiMemMin); ii <= int32(prg.memEnd); ii++ {
  25895. k = ii
  25896. _ = k
  25897. prg.fmtFile.Get()
  25898. prg.mem[k] = *(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))
  25899. }
  25900. {
  25901. prg.fmtFile.Get()
  25902. prg.varUsed = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  25903. }
  25904. {
  25905. prg.fmtFile.Get()
  25906. prg.dynUsed = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  25907. }
  25908. // Undump the table of equivalents
  25909. // Undump regions 1 to 6 of |eqtb|
  25910. k = activeBase
  25911. for {
  25912. {
  25913. prg.fmtFile.Get()
  25914. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  25915. }
  25916. if x < 1 || k+x > eqtbSize+1 {
  25917. goto badFmt
  25918. }
  25919. for ii := k; ii <= k+x-1; ii++ {
  25920. j = ii
  25921. _ = j
  25922. prg.fmtFile.Get()
  25923. prg.eqtb[j-1] = *(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))
  25924. }
  25925. k = k + x
  25926. {
  25927. prg.fmtFile.Get()
  25928. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  25929. }
  25930. if x < 0 || k+x > eqtbSize+1 {
  25931. goto badFmt
  25932. }
  25933. for ii := k; ii <= k+x-1; ii++ {
  25934. j = ii
  25935. _ = j
  25936. prg.eqtb[j-1] = prg.eqtb[k-1-1]
  25937. }
  25938. k = k + x
  25939. if k > eqtbSize {
  25940. break
  25941. }
  25942. }
  25943. {
  25944. {
  25945. prg.fmtFile.Get()
  25946. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  25947. }
  25948. if x < hashBase || x > frozenControlSequence {
  25949. goto badFmt
  25950. } else {
  25951. prg.parLoc = uint16(x)
  25952. }
  25953. }
  25954. prg.parToken = uint16(07777 + int32(prg.parLoc))
  25955. {
  25956. {
  25957. prg.fmtFile.Get()
  25958. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  25959. }
  25960. if x < hashBase || x > frozenControlSequence {
  25961. goto badFmt
  25962. } else {
  25963. prg.writeLoc = uint16(x)
  25964. }
  25965. }
  25966. // Undump the hash table
  25967. {
  25968. {
  25969. prg.fmtFile.Get()
  25970. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  25971. }
  25972. if x < hashBase || x > frozenControlSequence {
  25973. goto badFmt
  25974. } else {
  25975. prg.hashUsed = uint16(x)
  25976. }
  25977. }
  25978. p = uint16(hashBase - 1)
  25979. for {
  25980. {
  25981. {
  25982. prg.fmtFile.Get()
  25983. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  25984. }
  25985. if x < int32(p)+1 || x > int32(prg.hashUsed) {
  25986. goto badFmt
  25987. } else {
  25988. p = uint16(x)
  25989. }
  25990. }
  25991. {
  25992. prg.fmtFile.Get()
  25993. prg.hash[p-514] = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).hh()
  25994. }
  25995. if int32(p) == int32(prg.hashUsed) {
  25996. break
  25997. }
  25998. }
  25999. for ii := int32(prg.hashUsed) + 1; ii <= undefinedControlSequence-1; ii++ {
  26000. p = halfword(ii)
  26001. _ = p
  26002. prg.fmtFile.Get()
  26003. prg.hash[p-514] = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).hh()
  26004. }
  26005. {
  26006. prg.fmtFile.Get()
  26007. prg.csCount = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26008. }
  26009. // Undump the font information
  26010. {
  26011. {
  26012. prg.fmtFile.Get()
  26013. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26014. }
  26015. if x < 7 {
  26016. goto badFmt
  26017. }
  26018. if x > fontMemSize {
  26019. prg.termOut.Writeln("---! Must increase the ", "font mem size") /* \xref[Must increase the x] */ /* \xref[Must increase the x] */
  26020. goto badFmt
  26021. } else {
  26022. prg.fmemPtr = uint16(x)
  26023. }
  26024. }
  26025. for ii := int32(0); ii <= int32(prg.fmemPtr)-1; ii++ {
  26026. k = ii
  26027. _ = k
  26028. prg.fmtFile.Get()
  26029. prg.fontInfo[k] = *(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))
  26030. }
  26031. {
  26032. {
  26033. prg.fmtFile.Get()
  26034. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26035. }
  26036. if x < fontBase {
  26037. goto badFmt
  26038. }
  26039. if x > fontMax {
  26040. prg.termOut.Writeln("---! Must increase the ", "font max") /* \xref[Must increase the x] */ /* \xref[Must increase the x] */
  26041. goto badFmt
  26042. } else {
  26043. prg.fontPtr = byte(x)
  26044. }
  26045. }
  26046. for ii := int32(fontBase); ii <= int32(prg.fontPtr); ii++ {
  26047. k = ii
  26048. _ = k
  26049. // Undump the array info for internal font number |k|
  26050. {
  26051. prg.fmtFile.Get()
  26052. prg.fontCheck[k] = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).qqqq()
  26053. }
  26054. {
  26055. prg.fmtFile.Get()
  26056. prg.fontSize[k] = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26057. }
  26058. {
  26059. prg.fmtFile.Get()
  26060. prg.fontDsize[k] = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26061. }
  26062. {
  26063. {
  26064. prg.fmtFile.Get()
  26065. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26066. }
  26067. if x < 0 || x > 65535 {
  26068. goto badFmt
  26069. } else {
  26070. prg.fontParams[k] = uint16(x)
  26071. }
  26072. }
  26073. {
  26074. prg.fmtFile.Get()
  26075. prg.hyphenChar[k] = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26076. }
  26077. {
  26078. prg.fmtFile.Get()
  26079. prg.skewChar[k] = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26080. }
  26081. {
  26082. {
  26083. prg.fmtFile.Get()
  26084. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26085. }
  26086. if x < 0 || x > int32(prg.strPtr) {
  26087. goto badFmt
  26088. } else {
  26089. prg.fontName[k] = uint16(x)
  26090. }
  26091. }
  26092. {
  26093. {
  26094. prg.fmtFile.Get()
  26095. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26096. }
  26097. if x < 0 || x > int32(prg.strPtr) {
  26098. goto badFmt
  26099. } else {
  26100. prg.fontArea[k] = uint16(x)
  26101. }
  26102. }
  26103. {
  26104. {
  26105. prg.fmtFile.Get()
  26106. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26107. }
  26108. if x < 0 || x > 255 {
  26109. goto badFmt
  26110. } else {
  26111. prg.fontBc[k] = byte(x)
  26112. }
  26113. }
  26114. {
  26115. {
  26116. prg.fmtFile.Get()
  26117. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26118. }
  26119. if x < 0 || x > 255 {
  26120. goto badFmt
  26121. } else {
  26122. prg.fontEc[k] = byte(x)
  26123. }
  26124. }
  26125. {
  26126. prg.fmtFile.Get()
  26127. prg.charBase[k] = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26128. }
  26129. {
  26130. prg.fmtFile.Get()
  26131. prg.widthBase[k] = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26132. }
  26133. {
  26134. prg.fmtFile.Get()
  26135. prg.heightBase[k] = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26136. }
  26137. {
  26138. prg.fmtFile.Get()
  26139. prg.depthBase[k] = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26140. }
  26141. {
  26142. prg.fmtFile.Get()
  26143. prg.italicBase[k] = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26144. }
  26145. {
  26146. prg.fmtFile.Get()
  26147. prg.ligKernBase[k] = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26148. }
  26149. {
  26150. prg.fmtFile.Get()
  26151. prg.kernBase[k] = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26152. }
  26153. {
  26154. prg.fmtFile.Get()
  26155. prg.extenBase[k] = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26156. }
  26157. {
  26158. prg.fmtFile.Get()
  26159. prg.paramBase[k] = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26160. }
  26161. {
  26162. {
  26163. prg.fmtFile.Get()
  26164. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26165. }
  26166. if x < 0 || x > int32(prg.loMemMax) {
  26167. goto badFmt
  26168. } else {
  26169. prg.fontGlue[k] = uint16(x)
  26170. }
  26171. }
  26172. {
  26173. {
  26174. prg.fmtFile.Get()
  26175. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26176. }
  26177. if x < 0 || x > int32(prg.fmemPtr)-1 {
  26178. goto badFmt
  26179. } else {
  26180. prg.bcharLabel[k] = uint16(x)
  26181. }
  26182. }
  26183. {
  26184. {
  26185. prg.fmtFile.Get()
  26186. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26187. }
  26188. if x < minQuarterword || x > 256+minQuarterword {
  26189. goto badFmt
  26190. } else {
  26191. prg.fontBchar[k] = uint16(x)
  26192. }
  26193. }
  26194. {
  26195. {
  26196. prg.fmtFile.Get()
  26197. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26198. }
  26199. if x < minQuarterword || x > 256+minQuarterword {
  26200. goto badFmt
  26201. } else {
  26202. prg.fontFalseBchar[k] = uint16(x)
  26203. }
  26204. }
  26205. }
  26206. // Undump the hyphenation tables
  26207. {
  26208. {
  26209. prg.fmtFile.Get()
  26210. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26211. }
  26212. if x < 0 || x > hyphSize {
  26213. goto badFmt
  26214. } else {
  26215. prg.hyphCount = uint16(x)
  26216. }
  26217. }
  26218. for ii := int32(1); ii <= int32(prg.hyphCount); ii++ {
  26219. k = ii
  26220. _ = k
  26221. {
  26222. {
  26223. prg.fmtFile.Get()
  26224. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26225. }
  26226. if x < 0 || x > hyphSize {
  26227. goto badFmt
  26228. } else {
  26229. j = x
  26230. }
  26231. }
  26232. {
  26233. {
  26234. prg.fmtFile.Get()
  26235. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26236. }
  26237. if x < 0 || x > int32(prg.strPtr) {
  26238. goto badFmt
  26239. } else {
  26240. prg.hyphWord[j] = uint16(x)
  26241. }
  26242. }
  26243. {
  26244. {
  26245. prg.fmtFile.Get()
  26246. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26247. }
  26248. if x < 0 || x > 65535 {
  26249. goto badFmt
  26250. } else {
  26251. prg.hyphList[j] = uint16(x)
  26252. }
  26253. }
  26254. }
  26255. {
  26256. {
  26257. prg.fmtFile.Get()
  26258. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26259. }
  26260. if x < 0 {
  26261. goto badFmt
  26262. }
  26263. if x > trieSize {
  26264. prg.termOut.Writeln("---! Must increase the ", "trie size") /* \xref[Must increase the x] */ /* \xref[Must increase the x] */
  26265. goto badFmt
  26266. } else {
  26267. j = x
  26268. }
  26269. }
  26270. prg.trieMax = uint16(j)
  26271. for ii := int32(0); ii <= j; ii++ {
  26272. k = ii
  26273. _ = k
  26274. prg.fmtFile.Get()
  26275. prg.trie[k] = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).hh()
  26276. }
  26277. {
  26278. {
  26279. prg.fmtFile.Get()
  26280. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26281. }
  26282. if x < 0 {
  26283. goto badFmt
  26284. }
  26285. if x > trieOpSize {
  26286. prg.termOut.Writeln("---! Must increase the ", "trie op size") /* \xref[Must increase the x] */ /* \xref[Must increase the x] */
  26287. goto badFmt
  26288. } else {
  26289. j = x
  26290. }
  26291. }
  26292. prg.trieOpPtr = uint16(j)
  26293. for ii := int32(1); ii <= j; ii++ {
  26294. k = ii
  26295. _ = k
  26296. {
  26297. {
  26298. prg.fmtFile.Get()
  26299. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26300. }
  26301. if x < 0 || x > 63 {
  26302. goto badFmt
  26303. } else {
  26304. prg.hyfDistance[k-1] = byte(x)
  26305. }
  26306. } // a |small_number|
  26307. {
  26308. {
  26309. prg.fmtFile.Get()
  26310. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26311. }
  26312. if x < 0 || x > 63 {
  26313. goto badFmt
  26314. } else {
  26315. prg.hyfNum[k-1] = byte(x)
  26316. }
  26317. }
  26318. {
  26319. {
  26320. prg.fmtFile.Get()
  26321. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26322. }
  26323. if x < minQuarterword || x > maxQuarterword {
  26324. goto badFmt
  26325. } else {
  26326. prg.hyfNext[k-1] = byte(x)
  26327. }
  26328. }
  26329. }
  26330. for ii := int32(0); ii <= 255; ii++ {
  26331. k = ii
  26332. _ = k
  26333. prg.trieUsed[k] = byte(minQuarterword)
  26334. }
  26335. k = 256
  26336. for j > 0 {
  26337. {
  26338. {
  26339. prg.fmtFile.Get()
  26340. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26341. }
  26342. if x < 0 || x > k-1 {
  26343. goto badFmt
  26344. } else {
  26345. k = x
  26346. }
  26347. }
  26348. {
  26349. {
  26350. prg.fmtFile.Get()
  26351. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26352. }
  26353. if x < 1 || x > j {
  26354. goto badFmt
  26355. } else {
  26356. x = x
  26357. }
  26358. }
  26359. prg.trieUsed[k] = byte(x + minQuarterword)
  26360. j = j - x
  26361. prg.opStart[k] = uint16(j - minQuarterword)
  26362. }
  26363. prg.trieNotReady = false
  26364. // Undump a couple more things and the closing check word
  26365. {
  26366. {
  26367. prg.fmtFile.Get()
  26368. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26369. }
  26370. if x < batchMode || x > errorStopMode {
  26371. goto badFmt
  26372. } else {
  26373. prg.interaction = byte(x)
  26374. }
  26375. }
  26376. {
  26377. {
  26378. prg.fmtFile.Get()
  26379. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26380. }
  26381. if x < 0 || x > int32(prg.strPtr) {
  26382. goto badFmt
  26383. } else {
  26384. prg.formatIdent = uint16(x)
  26385. }
  26386. }
  26387. {
  26388. prg.fmtFile.Get()
  26389. x = *(*(*memoryWord)(unsafe.Pointer(prg.fmtFile.Data4P()))).int()
  26390. }
  26391. if x != 69069 || prg.fmtFile.EOF() {
  26392. goto badFmt
  26393. }
  26394. r = true
  26395. goto exit // it worked!
  26396. // it worked!
  26397. badFmt:
  26398. ;
  26399. prg.termOut.Writeln("(Fatal format file error; I'm stymied)")
  26400. // \xref[Fatal format file error]
  26401. r = false
  26402. exit:
  26403. ;
  26404. return r
  26405. } // \2
  26406. func (prg *prg) closeFilesAndTerminate() {
  26407. var (
  26408. k int32 // all-purpose index
  26409. )
  26410. for ii := int32(0); ii <= 15; ii++ {
  26411. k = ii
  26412. _ = k
  26413. if prg.writeOpen[k] {
  26414. prg.aClose(prg.writeFile[k])
  26415. }
  26416. }
  26417. *prg.eqtb[intBase+newLineCharCode-1].int() = -1
  26418. // if eqtb[int_base+ tracing_stats_code].int >0 then
  26419. // [ Output statistics about this job ]
  26420. // if log_opened then
  26421. // begin writeln( log_file,' ') ;
  26422. // writeln( log_file,'Here is how much of TeX''s memory',' you used:') ;
  26423. // [ \xref[Here is how much...] ]
  26424. // write(log_file,' ', str_ptr- init_str_ptr: 1,' string') ;
  26425. // if str_ptr<>init_str_ptr+1 then write(log_file,'s') ;
  26426. // writeln( log_file,' out of ', max_strings- init_str_ptr: 1) ;
  26427. //
  26428. // writeln( log_file,' ', pool_ptr- init_pool_ptr: 1,' string characters out of ',
  26429. // pool_size- init_pool_ptr: 1) ;
  26430. //
  26431. // writeln( log_file,' ', lo_mem_max- mem_min+ mem_end- hi_mem_min+ 2: 1,
  26432. // ' words of memory out of ', mem_end+ 1- mem_min: 1) ;
  26433. //
  26434. // writeln( log_file,' ', cs_count: 1,' multiletter control sequences out of ',
  26435. // hash_size: 1) ;
  26436. //
  26437. // write(log_file,' ', fmem_ptr: 1,' words of font info for ',
  26438. // font_ptr- font_base: 1,' font') ;
  26439. // if font_ptr<>font_base+1 then write(log_file,'s') ;
  26440. // writeln( log_file,', out of ', font_mem_size: 1,' for ', font_max- font_base: 1) ;
  26441. //
  26442. // write(log_file,' ', hyph_count: 1,' hyphenation exception') ;
  26443. // if hyph_count<>1 then write(log_file,'s') ;
  26444. // writeln( log_file,' out of ', hyph_size: 1) ;
  26445. //
  26446. // writeln( log_file,' ', max_in_stack: 1,'i,', max_nest_stack: 1,'n,',
  26447. // max_param_stack: 1,'p,',
  26448. // max_buf_stack+ 1: 1,'b,',
  26449. // max_save_stack+ 6: 1,'s stack positions out of ',
  26450. // stack_size: 1,'i,',
  26451. // nest_size: 1,'n,',
  26452. // param_size: 1,'p,',
  26453. // buf_size: 1,'b,',
  26454. // save_size: 1,'s') ;
  26455. // end
  26456. //
  26457. // ; [ ]
  26458. // Finish the \.[DVI] file
  26459. for prg.curS > -1 {
  26460. if prg.curS > 0 {
  26461. prg.dviBuf[prg.dviPtr] = byte(pop)
  26462. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  26463. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  26464. prg.dviSwap()
  26465. }
  26466. } else {
  26467. {
  26468. prg.dviBuf[prg.dviPtr] = byte(eop)
  26469. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  26470. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  26471. prg.dviSwap()
  26472. }
  26473. }
  26474. prg.totalPages = prg.totalPages + 1
  26475. }
  26476. prg.curS = prg.curS - 1
  26477. }
  26478. if prg.totalPages == 0 {
  26479. prg.printNl(strNumber( /* "No pages of output." */ 837))
  26480. } else {
  26481. {
  26482. prg.dviBuf[prg.dviPtr] = byte(post)
  26483. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  26484. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  26485. prg.dviSwap()
  26486. }
  26487. } // beginning of the postamble
  26488. prg.dviFour(prg.lastBop)
  26489. prg.lastBop = prg.dviOffset + int32(prg.dviPtr) - 5 // |post| location
  26490. prg.dviFour(25400000)
  26491. prg.dviFour(473628672) // conversion ratio for sp
  26492. prg.prepareMag()
  26493. prg.dviFour(*prg.eqtb[intBase+magCode-1].int()) // magnification factor
  26494. prg.dviFour(prg.maxV)
  26495. prg.dviFour(prg.maxH)
  26496. {
  26497. prg.dviBuf[prg.dviPtr] = byte(prg.maxPush / 256)
  26498. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  26499. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  26500. prg.dviSwap()
  26501. }
  26502. }
  26503. {
  26504. prg.dviBuf[prg.dviPtr] = byte(prg.maxPush % 256)
  26505. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  26506. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  26507. prg.dviSwap()
  26508. }
  26509. }
  26510. {
  26511. prg.dviBuf[prg.dviPtr] = byte(prg.totalPages / 256 % 256)
  26512. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  26513. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  26514. prg.dviSwap()
  26515. }
  26516. }
  26517. {
  26518. prg.dviBuf[prg.dviPtr] = byte(prg.totalPages % 256)
  26519. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  26520. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  26521. prg.dviSwap()
  26522. }
  26523. }
  26524. // Output the font definitions for all fonts that were used
  26525. for int32(prg.fontPtr) > fontBase {
  26526. if prg.fontUsed[prg.fontPtr] {
  26527. prg.dviFontDef(prg.fontPtr)
  26528. }
  26529. prg.fontPtr = byte(int32(prg.fontPtr) - 1)
  26530. }
  26531. {
  26532. prg.dviBuf[prg.dviPtr] = byte(postPost)
  26533. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  26534. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  26535. prg.dviSwap()
  26536. }
  26537. }
  26538. prg.dviFour(prg.lastBop)
  26539. {
  26540. prg.dviBuf[prg.dviPtr] = byte(idByte)
  26541. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  26542. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  26543. prg.dviSwap()
  26544. }
  26545. }
  26546. k = 4 + (dviBufSize-int32(prg.dviPtr))%4 // the number of 223's
  26547. for k > 0 {
  26548. {
  26549. prg.dviBuf[prg.dviPtr] = 223
  26550. prg.dviPtr = uint16(int32(prg.dviPtr) + 1)
  26551. if int32(prg.dviPtr) == int32(prg.dviLimit) {
  26552. prg.dviSwap()
  26553. }
  26554. }
  26555. k = k - 1
  26556. }
  26557. // Empty the last bytes out of |dvi_buf|
  26558. if int32(prg.dviLimit) == int32(prg.halfBuf) {
  26559. prg.writeDvi(prg.halfBuf, dviIndex(dviBufSize-1))
  26560. }
  26561. if int32(prg.dviPtr) > 0 {
  26562. prg.writeDvi(dviIndex(0), dviIndex(int32(prg.dviPtr)-1))
  26563. }
  26564. prg.printNl(strNumber( /* "Output written on " */ 838))
  26565. prg.slowPrint(int32(prg.outputFileName))
  26566. // \xref[Output written on x]
  26567. prg.print( /* " (" */ 286)
  26568. prg.printInt(prg.totalPages)
  26569. prg.print( /* " page" */ 839)
  26570. if prg.totalPages != 1 {
  26571. prg.printChar(asciiCode('s'))
  26572. }
  26573. prg.print( /* ", " */ 840)
  26574. prg.printInt(prg.dviOffset + int32(prg.dviPtr))
  26575. prg.print( /* " bytes)." */ 841)
  26576. prg.bClose(prg.dviFile)
  26577. }
  26578. if prg.logOpened {
  26579. prg.logFile.Writeln()
  26580. prg.aClose(prg.logFile)
  26581. prg.selector = byte(int32(prg.selector) - 2)
  26582. if int32(prg.selector) == termOnly {
  26583. prg.printNl(strNumber( /* "Transcript written on " */ 1275))
  26584. // \xref[Transcript written...]
  26585. prg.slowPrint(int32(prg.logName))
  26586. prg.printChar(asciiCode('.'))
  26587. }
  26588. }
  26589. prg.termOut.Writeln()
  26590. }
  26591. func (prg *prg) finalCleanup() {
  26592. var (
  26593. c smallNumber // 0 for \.[\\end], 1 for \.[\\dump]
  26594. )
  26595. c = byte(prg.curChr)
  26596. if int32(c) != 1 {
  26597. *prg.eqtb[intBase+newLineCharCode-1].int() = -1
  26598. }
  26599. if int32(prg.jobName) == 0 {
  26600. prg.openLogFile()
  26601. }
  26602. for int32(prg.inputPtr) > 0 {
  26603. if int32(prg.curInput.stateField) == tokenList {
  26604. prg.endTokenList()
  26605. } else {
  26606. prg.endFileReading()
  26607. }
  26608. }
  26609. for int32(prg.openParens) > 0 {
  26610. prg.print( /* " )" */ 1276)
  26611. prg.openParens = byte(int32(prg.openParens) - 1)
  26612. }
  26613. if int32(prg.curLevel) > levelOne {
  26614. prg.printNl(strNumber('('))
  26615. prg.printEsc(strNumber( /* "end occurred " */ 1277))
  26616. prg.print( /* "inside a group at level " */ 1278)
  26617. // \xref[end_][\.[(\\end occurred...)]]
  26618. prg.printInt(int32(prg.curLevel) - levelOne)
  26619. prg.printChar(asciiCode(')'))
  26620. }
  26621. for int32(prg.condPtr) != 0 {
  26622. prg.printNl(strNumber('('))
  26623. prg.printEsc(strNumber( /* "end occurred " */ 1277))
  26624. prg.print( /* "when " */ 1279)
  26625. prg.printCmdChr(quarterword(ifTest), halfword(prg.curIf))
  26626. if prg.ifLine != 0 {
  26627. prg.print( /* " on line " */ 1280)
  26628. prg.printInt(prg.ifLine)
  26629. }
  26630. prg.print( /* " was incomplete)" */ 1281)
  26631. prg.ifLine = *prg.mem[int32(prg.condPtr)+1].int()
  26632. prg.curIf = *(*prg.mem[prg.condPtr].hh()).b1()
  26633. prg.tempPtr = prg.condPtr
  26634. prg.condPtr = *(*prg.mem[prg.condPtr].hh()).rh()
  26635. prg.freeNode(prg.tempPtr, halfword(ifNodeSize))
  26636. }
  26637. if int32(prg.history) != spotless {
  26638. if int32(prg.history) == warningIssued || int32(prg.interaction) < errorStopMode {
  26639. if int32(prg.selector) == termAndLog {
  26640. prg.selector = byte(termOnly)
  26641. prg.printNl(strNumber( /* "(see the transcript file for additional information)" */ 1282))
  26642. // \xref[see the transcript file...]
  26643. prg.selector = byte(termAndLog)
  26644. }
  26645. }
  26646. }
  26647. if int32(c) == 1 {
  26648. for ii := int32(topMarkCode); ii <= splitBotMarkCode; ii++ {
  26649. c = smallNumber(ii)
  26650. _ = c
  26651. if int32(prg.curMark[c]) != 0 {
  26652. prg.deleteTokenRef(prg.curMark[c])
  26653. }
  26654. }
  26655. if int32(prg.lastGlue) != 65535 {
  26656. prg.deleteGlueRef(prg.lastGlue)
  26657. }
  26658. prg.storeFmtFile()
  26659. goto exit
  26660. prg.printNl(strNumber( /* "(\\dump is performed only by INITEX)" */ 1283))
  26661. goto exit
  26662. // \xref[dump_][\.[\\dump...only by INITEX]]
  26663. }
  26664. exit:
  26665. }
  26666. func (prg *prg) initPrim() {
  26667. prg.noNewControlSequence = false
  26668. // Put each...
  26669. prg.primitive(strNumber( /* "lineskip" */ 376), quarterword(assignGlue), halfword(glueBase+lineSkipCode))
  26670. // \xref[line_skip_][\.[\\lineskip] primitive]
  26671. prg.primitive(strNumber( /* "baselineskip" */ 377), quarterword(assignGlue), halfword(glueBase+baselineSkipCode))
  26672. // \xref[baseline_skip_][\.[\\baselineskip] primitive]
  26673. prg.primitive(strNumber( /* "parskip" */ 378), quarterword(assignGlue), halfword(glueBase+parSkipCode))
  26674. // \xref[par_skip_][\.[\\parskip] primitive]
  26675. prg.primitive(strNumber( /* "abovedisplayskip" */ 379), quarterword(assignGlue), halfword(glueBase+aboveDisplaySkipCode))
  26676. // \xref[above_display_skip_][\.[\\abovedisplayskip] primitive]
  26677. prg.primitive(strNumber( /* "belowdisplayskip" */ 380), quarterword(assignGlue), halfword(glueBase+belowDisplaySkipCode))
  26678. // \xref[below_display_skip_][\.[\\belowdisplayskip] primitive]
  26679. prg.primitive(strNumber( /* "abovedisplayshortskip" */ 381), quarterword(assignGlue), halfword(glueBase+aboveDisplayShortSkipCode))
  26680. // \xref[above_display_short_skip_][\.[\\abovedisplayshortskip] primitive]
  26681. prg.primitive(strNumber( /* "belowdisplayshortskip" */ 382), quarterword(assignGlue), halfword(glueBase+belowDisplayShortSkipCode))
  26682. // \xref[below_display_short_skip_][\.[\\belowdisplayshortskip] primitive]
  26683. prg.primitive(strNumber( /* "leftskip" */ 383), quarterword(assignGlue), halfword(glueBase+leftSkipCode))
  26684. // \xref[left_skip_][\.[\\leftskip] primitive]
  26685. prg.primitive(strNumber( /* "rightskip" */ 384), quarterword(assignGlue), halfword(glueBase+rightSkipCode))
  26686. // \xref[right_skip_][\.[\\rightskip] primitive]
  26687. prg.primitive(strNumber( /* "topskip" */ 385), quarterword(assignGlue), halfword(glueBase+topSkipCode))
  26688. // \xref[top_skip_][\.[\\topskip] primitive]
  26689. prg.primitive(strNumber( /* "splittopskip" */ 386), quarterword(assignGlue), halfword(glueBase+splitTopSkipCode))
  26690. // \xref[split_top_skip_][\.[\\splittopskip] primitive]
  26691. prg.primitive(strNumber( /* "tabskip" */ 387), quarterword(assignGlue), halfword(glueBase+tabSkipCode))
  26692. // \xref[tab_skip_][\.[\\tabskip] primitive]
  26693. prg.primitive(strNumber( /* "spaceskip" */ 388), quarterword(assignGlue), halfword(glueBase+spaceSkipCode))
  26694. // \xref[space_skip_][\.[\\spaceskip] primitive]
  26695. prg.primitive(strNumber( /* "xspaceskip" */ 389), quarterword(assignGlue), halfword(glueBase+xspaceSkipCode))
  26696. // \xref[xspace_skip_][\.[\\xspaceskip] primitive]
  26697. prg.primitive(strNumber( /* "parfillskip" */ 390), quarterword(assignGlue), halfword(glueBase+parFillSkipCode))
  26698. // \xref[par_fill_skip_][\.[\\parfillskip] primitive]
  26699. prg.primitive(strNumber( /* "thinmuskip" */ 391), quarterword(assignMuGlue), halfword(glueBase+thinMuSkipCode))
  26700. // \xref[thin_mu_skip_][\.[\\thinmuskip] primitive]
  26701. prg.primitive(strNumber( /* "medmuskip" */ 392), quarterword(assignMuGlue), halfword(glueBase+medMuSkipCode))
  26702. // \xref[med_mu_skip_][\.[\\medmuskip] primitive]
  26703. prg.primitive(strNumber( /* "thickmuskip" */ 393), quarterword(assignMuGlue), halfword(glueBase+thickMuSkipCode))
  26704. // \xref[thick_mu_skip_][\.[\\thickmuskip] primitive]
  26705. prg.primitive(strNumber( /* "output" */ 398), quarterword(assignToks), halfword(outputRoutineLoc))
  26706. // \xref[output_][\.[\\output] primitive]
  26707. prg.primitive(strNumber( /* "everypar" */ 399), quarterword(assignToks), halfword(everyParLoc))
  26708. // \xref[every_par_][\.[\\everypar] primitive]
  26709. prg.primitive(strNumber( /* "everymath" */ 400), quarterword(assignToks), halfword(everyMathLoc))
  26710. // \xref[every_math_][\.[\\everymath] primitive]
  26711. prg.primitive(strNumber( /* "everydisplay" */ 401), quarterword(assignToks), halfword(everyDisplayLoc))
  26712. // \xref[every_display_][\.[\\everydisplay] primitive]
  26713. prg.primitive(strNumber( /* "everyhbox" */ 402), quarterword(assignToks), halfword(everyHboxLoc))
  26714. // \xref[every_hbox_][\.[\\everyhbox] primitive]
  26715. prg.primitive(strNumber( /* "everyvbox" */ 403), quarterword(assignToks), halfword(everyVboxLoc))
  26716. // \xref[every_vbox_][\.[\\everyvbox] primitive]
  26717. prg.primitive(strNumber( /* "everyjob" */ 404), quarterword(assignToks), halfword(everyJobLoc))
  26718. // \xref[every_job_][\.[\\everyjob] primitive]
  26719. prg.primitive(strNumber( /* "everycr" */ 405), quarterword(assignToks), halfword(everyCrLoc))
  26720. // \xref[every_cr_][\.[\\everycr] primitive]
  26721. prg.primitive(strNumber( /* "errhelp" */ 406), quarterword(assignToks), halfword(errHelpLoc))
  26722. // \xref[err_help_][\.[\\errhelp] primitive]
  26723. prg.primitive(strNumber( /* "pretolerance" */ 420), quarterword(assignInt), halfword(intBase+pretoleranceCode))
  26724. // \xref[pretolerance_][\.[\\pretolerance] primitive]
  26725. prg.primitive(strNumber( /* "tolerance" */ 421), quarterword(assignInt), halfword(intBase+toleranceCode))
  26726. // \xref[tolerance_][\.[\\tolerance] primitive]
  26727. prg.primitive(strNumber( /* "linepenalty" */ 422), quarterword(assignInt), halfword(intBase+linePenaltyCode))
  26728. // \xref[line_penalty_][\.[\\linepenalty] primitive]
  26729. prg.primitive(strNumber( /* "hyphenpenalty" */ 423), quarterword(assignInt), halfword(intBase+hyphenPenaltyCode))
  26730. // \xref[hyphen_penalty_][\.[\\hyphenpenalty] primitive]
  26731. prg.primitive(strNumber( /* "exhyphenpenalty" */ 424), quarterword(assignInt), halfword(intBase+exHyphenPenaltyCode))
  26732. // \xref[ex_hyphen_penalty_][\.[\\exhyphenpenalty] primitive]
  26733. prg.primitive(strNumber( /* "clubpenalty" */ 425), quarterword(assignInt), halfword(intBase+clubPenaltyCode))
  26734. // \xref[club_penalty_][\.[\\clubpenalty] primitive]
  26735. prg.primitive(strNumber( /* "widowpenalty" */ 426), quarterword(assignInt), halfword(intBase+widowPenaltyCode))
  26736. // \xref[widow_penalty_][\.[\\widowpenalty] primitive]
  26737. prg.primitive(strNumber( /* "displaywidowpenalty" */ 427), quarterword(assignInt), halfword(intBase+displayWidowPenaltyCode))
  26738. // \xref[display_widow_penalty_][\.[\\displaywidowpenalty] primitive]
  26739. prg.primitive(strNumber( /* "brokenpenalty" */ 428), quarterword(assignInt), halfword(intBase+brokenPenaltyCode))
  26740. // \xref[broken_penalty_][\.[\\brokenpenalty] primitive]
  26741. prg.primitive(strNumber( /* "binoppenalty" */ 429), quarterword(assignInt), halfword(intBase+binOpPenaltyCode))
  26742. // \xref[bin_op_penalty_][\.[\\binoppenalty] primitive]
  26743. prg.primitive(strNumber( /* "relpenalty" */ 430), quarterword(assignInt), halfword(intBase+relPenaltyCode))
  26744. // \xref[rel_penalty_][\.[\\relpenalty] primitive]
  26745. prg.primitive(strNumber( /* "predisplaypenalty" */ 431), quarterword(assignInt), halfword(intBase+preDisplayPenaltyCode))
  26746. // \xref[pre_display_penalty_][\.[\\predisplaypenalty] primitive]
  26747. prg.primitive(strNumber( /* "postdisplaypenalty" */ 432), quarterword(assignInt), halfword(intBase+postDisplayPenaltyCode))
  26748. // \xref[post_display_penalty_][\.[\\postdisplaypenalty] primitive]
  26749. prg.primitive(strNumber( /* "interlinepenalty" */ 433), quarterword(assignInt), halfword(intBase+interLinePenaltyCode))
  26750. // \xref[inter_line_penalty_][\.[\\interlinepenalty] primitive]
  26751. prg.primitive(strNumber( /* "doublehyphendemerits" */ 434), quarterword(assignInt), halfword(intBase+doubleHyphenDemeritsCode))
  26752. // \xref[double_hyphen_demerits_][\.[\\doublehyphendemerits] primitive]
  26753. prg.primitive(strNumber( /* "finalhyphendemerits" */ 435), quarterword(assignInt), halfword(intBase+finalHyphenDemeritsCode))
  26754. // \xref[final_hyphen_demerits_][\.[\\finalhyphendemerits] primitive]
  26755. prg.primitive(strNumber( /* "adjdemerits" */ 436), quarterword(assignInt), halfword(intBase+adjDemeritsCode))
  26756. // \xref[adj_demerits_][\.[\\adjdemerits] primitive]
  26757. prg.primitive(strNumber( /* "mag" */ 437), quarterword(assignInt), halfword(intBase+magCode))
  26758. // \xref[mag_][\.[\\mag] primitive]
  26759. prg.primitive(strNumber( /* "delimiterfactor" */ 438), quarterword(assignInt), halfword(intBase+delimiterFactorCode))
  26760. // \xref[delimiter_factor_][\.[\\delimiterfactor] primitive]
  26761. prg.primitive(strNumber( /* "looseness" */ 439), quarterword(assignInt), halfword(intBase+loosenessCode))
  26762. // \xref[looseness_][\.[\\looseness] primitive]
  26763. prg.primitive(strNumber( /* "time" */ 440), quarterword(assignInt), halfword(intBase+timeCode))
  26764. // \xref[time_][\.[\\time] primitive]
  26765. prg.primitive(strNumber( /* "day" */ 441), quarterword(assignInt), halfword(intBase+dayCode))
  26766. // \xref[day_][\.[\\day] primitive]
  26767. prg.primitive(strNumber( /* "month" */ 442), quarterword(assignInt), halfword(intBase+monthCode))
  26768. // \xref[month_][\.[\\month] primitive]
  26769. prg.primitive(strNumber( /* "year" */ 443), quarterword(assignInt), halfword(intBase+yearCode))
  26770. // \xref[year_][\.[\\year] primitive]
  26771. prg.primitive(strNumber( /* "showboxbreadth" */ 444), quarterword(assignInt), halfword(intBase+showBoxBreadthCode))
  26772. // \xref[show_box_breadth_][\.[\\showboxbreadth] primitive]
  26773. prg.primitive(strNumber( /* "showboxdepth" */ 445), quarterword(assignInt), halfword(intBase+showBoxDepthCode))
  26774. // \xref[show_box_depth_][\.[\\showboxdepth] primitive]
  26775. prg.primitive(strNumber( /* "hbadness" */ 446), quarterword(assignInt), halfword(intBase+hbadnessCode))
  26776. // \xref[hbadness_][\.[\\hbadness] primitive]
  26777. prg.primitive(strNumber( /* "vbadness" */ 447), quarterword(assignInt), halfword(intBase+vbadnessCode))
  26778. // \xref[vbadness_][\.[\\vbadness] primitive]
  26779. prg.primitive(strNumber( /* "pausing" */ 448), quarterword(assignInt), halfword(intBase+pausingCode))
  26780. // \xref[pausing_][\.[\\pausing] primitive]
  26781. prg.primitive(strNumber( /* "tracingonline" */ 449), quarterword(assignInt), halfword(intBase+tracingOnlineCode))
  26782. // \xref[tracing_online_][\.[\\tracingonline] primitive]
  26783. prg.primitive(strNumber( /* "tracingmacros" */ 450), quarterword(assignInt), halfword(intBase+tracingMacrosCode))
  26784. // \xref[tracing_macros_][\.[\\tracingmacros] primitive]
  26785. prg.primitive(strNumber( /* "tracingstats" */ 451), quarterword(assignInt), halfword(intBase+tracingStatsCode))
  26786. // \xref[tracing_stats_][\.[\\tracingstats] primitive]
  26787. prg.primitive(strNumber( /* "tracingparagraphs" */ 452), quarterword(assignInt), halfword(intBase+tracingParagraphsCode))
  26788. // \xref[tracing_paragraphs_][\.[\\tracingparagraphs] primitive]
  26789. prg.primitive(strNumber( /* "tracingpages" */ 453), quarterword(assignInt), halfword(intBase+tracingPagesCode))
  26790. // \xref[tracing_pages_][\.[\\tracingpages] primitive]
  26791. prg.primitive(strNumber( /* "tracingoutput" */ 454), quarterword(assignInt), halfword(intBase+tracingOutputCode))
  26792. // \xref[tracing_output_][\.[\\tracingoutput] primitive]
  26793. prg.primitive(strNumber( /* "tracinglostchars" */ 455), quarterword(assignInt), halfword(intBase+tracingLostCharsCode))
  26794. // \xref[tracing_lost_chars_][\.[\\tracinglostchars] primitive]
  26795. prg.primitive(strNumber( /* "tracingcommands" */ 456), quarterword(assignInt), halfword(intBase+tracingCommandsCode))
  26796. // \xref[tracing_commands_][\.[\\tracingcommands] primitive]
  26797. prg.primitive(strNumber( /* "tracingrestores" */ 457), quarterword(assignInt), halfword(intBase+tracingRestoresCode))
  26798. // \xref[tracing_restores_][\.[\\tracingrestores] primitive]
  26799. prg.primitive(strNumber( /* "uchyph" */ 458), quarterword(assignInt), halfword(intBase+ucHyphCode))
  26800. // \xref[uc_hyph_][\.[\\uchyph] primitive]
  26801. prg.primitive(strNumber( /* "outputpenalty" */ 459), quarterword(assignInt), halfword(intBase+outputPenaltyCode))
  26802. // \xref[output_penalty_][\.[\\outputpenalty] primitive]
  26803. prg.primitive(strNumber( /* "maxdeadcycles" */ 460), quarterword(assignInt), halfword(intBase+maxDeadCyclesCode))
  26804. // \xref[max_dead_cycles_][\.[\\maxdeadcycles] primitive]
  26805. prg.primitive(strNumber( /* "hangafter" */ 461), quarterword(assignInt), halfword(intBase+hangAfterCode))
  26806. // \xref[hang_after_][\.[\\hangafter] primitive]
  26807. prg.primitive(strNumber( /* "floatingpenalty" */ 462), quarterword(assignInt), halfword(intBase+floatingPenaltyCode))
  26808. // \xref[floating_penalty_][\.[\\floatingpenalty] primitive]
  26809. prg.primitive(strNumber( /* "globaldefs" */ 463), quarterword(assignInt), halfword(intBase+globalDefsCode))
  26810. // \xref[global_defs_][\.[\\globaldefs] primitive]
  26811. prg.primitive(strNumber( /* "fam" */ 464), quarterword(assignInt), halfword(intBase+curFamCode))
  26812. // \xref[fam_][\.[\\fam] primitive]
  26813. prg.primitive(strNumber( /* "escapechar" */ 465), quarterword(assignInt), halfword(intBase+escapeCharCode))
  26814. // \xref[escape_char_][\.[\\escapechar] primitive]
  26815. prg.primitive(strNumber( /* "defaulthyphenchar" */ 466), quarterword(assignInt), halfword(intBase+defaultHyphenCharCode))
  26816. // \xref[default_hyphen_char_][\.[\\defaulthyphenchar] primitive]
  26817. prg.primitive(strNumber( /* "defaultskewchar" */ 467), quarterword(assignInt), halfword(intBase+defaultSkewCharCode))
  26818. // \xref[default_skew_char_][\.[\\defaultskewchar] primitive]
  26819. prg.primitive(strNumber( /* "endlinechar" */ 468), quarterword(assignInt), halfword(intBase+endLineCharCode))
  26820. // \xref[end_line_char_][\.[\\endlinechar] primitive]
  26821. prg.primitive(strNumber( /* "newlinechar" */ 469), quarterword(assignInt), halfword(intBase+newLineCharCode))
  26822. // \xref[new_line_char_][\.[\\newlinechar] primitive]
  26823. prg.primitive(strNumber( /* "language" */ 470), quarterword(assignInt), halfword(intBase+languageCode))
  26824. // \xref[language_][\.[\\language] primitive]
  26825. prg.primitive(strNumber( /* "lefthyphenmin" */ 471), quarterword(assignInt), halfword(intBase+leftHyphenMinCode))
  26826. // \xref[left_hyphen_min_][\.[\\lefthyphenmin] primitive]
  26827. prg.primitive(strNumber( /* "righthyphenmin" */ 472), quarterword(assignInt), halfword(intBase+rightHyphenMinCode))
  26828. // \xref[right_hyphen_min_][\.[\\righthyphenmin] primitive]
  26829. prg.primitive(strNumber( /* "holdinginserts" */ 473), quarterword(assignInt), halfword(intBase+holdingInsertsCode))
  26830. // \xref[holding_inserts_][\.[\\holdinginserts] primitive]
  26831. prg.primitive(strNumber( /* "errorcontextlines" */ 474), quarterword(assignInt), halfword(intBase+errorContextLinesCode))
  26832. // \xref[error_context_lines_][\.[\\errorcontextlines] primitive]
  26833. prg.primitive(strNumber( /* "parindent" */ 478), quarterword(assignDimen), halfword(dimenBase+parIndentCode))
  26834. // \xref[par_indent_][\.[\\parindent] primitive]
  26835. prg.primitive(strNumber( /* "mathsurround" */ 479), quarterword(assignDimen), halfword(dimenBase+mathSurroundCode))
  26836. // \xref[math_surround_][\.[\\mathsurround] primitive]
  26837. prg.primitive(strNumber( /* "lineskiplimit" */ 480), quarterword(assignDimen), halfword(dimenBase+lineSkipLimitCode))
  26838. // \xref[line_skip_limit_][\.[\\lineskiplimit] primitive]
  26839. prg.primitive(strNumber( /* "hsize" */ 481), quarterword(assignDimen), halfword(dimenBase+hsizeCode))
  26840. // \xref[hsize_][\.[\\hsize] primitive]
  26841. prg.primitive(strNumber( /* "vsize" */ 482), quarterword(assignDimen), halfword(dimenBase+vsizeCode))
  26842. // \xref[vsize_][\.[\\vsize] primitive]
  26843. prg.primitive(strNumber( /* "maxdepth" */ 483), quarterword(assignDimen), halfword(dimenBase+maxDepthCode))
  26844. // \xref[max_depth_][\.[\\maxdepth] primitive]
  26845. prg.primitive(strNumber( /* "splitmaxdepth" */ 484), quarterword(assignDimen), halfword(dimenBase+splitMaxDepthCode))
  26846. // \xref[split_max_depth_][\.[\\splitmaxdepth] primitive]
  26847. prg.primitive(strNumber( /* "boxmaxdepth" */ 485), quarterword(assignDimen), halfword(dimenBase+boxMaxDepthCode))
  26848. // \xref[box_max_depth_][\.[\\boxmaxdepth] primitive]
  26849. prg.primitive(strNumber( /* "hfuzz" */ 486), quarterword(assignDimen), halfword(dimenBase+hfuzzCode))
  26850. // \xref[hfuzz_][\.[\\hfuzz] primitive]
  26851. prg.primitive(strNumber( /* "vfuzz" */ 487), quarterword(assignDimen), halfword(dimenBase+vfuzzCode))
  26852. // \xref[vfuzz_][\.[\\vfuzz] primitive]
  26853. prg.primitive(strNumber( /* "delimitershortfall" */ 488), quarterword(assignDimen), halfword(dimenBase+delimiterShortfallCode))
  26854. // \xref[delimiter_shortfall_][\.[\\delimitershortfall] primitive]
  26855. prg.primitive(strNumber( /* "nulldelimiterspace" */ 489), quarterword(assignDimen), halfword(dimenBase+nullDelimiterSpaceCode))
  26856. // \xref[null_delimiter_space_][\.[\\nulldelimiterspace] primitive]
  26857. prg.primitive(strNumber( /* "scriptspace" */ 490), quarterword(assignDimen), halfword(dimenBase+scriptSpaceCode))
  26858. // \xref[script_space_][\.[\\scriptspace] primitive]
  26859. prg.primitive(strNumber( /* "predisplaysize" */ 491), quarterword(assignDimen), halfword(dimenBase+preDisplaySizeCode))
  26860. // \xref[pre_display_size_][\.[\\predisplaysize] primitive]
  26861. prg.primitive(strNumber( /* "displaywidth" */ 492), quarterword(assignDimen), halfword(dimenBase+displayWidthCode))
  26862. // \xref[display_width_][\.[\\displaywidth] primitive]
  26863. prg.primitive(strNumber( /* "displayindent" */ 493), quarterword(assignDimen), halfword(dimenBase+displayIndentCode))
  26864. // \xref[display_indent_][\.[\\displayindent] primitive]
  26865. prg.primitive(strNumber( /* "overfullrule" */ 494), quarterword(assignDimen), halfword(dimenBase+overfullRuleCode))
  26866. // \xref[overfull_rule_][\.[\\overfullrule] primitive]
  26867. prg.primitive(strNumber( /* "hangindent" */ 495), quarterword(assignDimen), halfword(dimenBase+hangIndentCode))
  26868. // \xref[hang_indent_][\.[\\hangindent] primitive]
  26869. prg.primitive(strNumber( /* "hoffset" */ 496), quarterword(assignDimen), halfword(dimenBase+hOffsetCode))
  26870. // \xref[h_offset_][\.[\\hoffset] primitive]
  26871. prg.primitive(strNumber( /* "voffset" */ 497), quarterword(assignDimen), halfword(dimenBase+vOffsetCode))
  26872. // \xref[v_offset_][\.[\\voffset] primitive]
  26873. prg.primitive(strNumber( /* "emergencystretch" */ 498), quarterword(assignDimen), halfword(dimenBase+emergencyStretchCode))
  26874. // \xref[emergency_stretch_][\.[\\emergencystretch] primitive]
  26875. prg.primitive(strNumber(' '), quarterword(exSpace), halfword(0))
  26876. // \xref[Single-character primitives /][\quad\.[\\\ ]]
  26877. prg.primitive(strNumber('/'), quarterword(italCorr), halfword(0))
  26878. // \xref[Single-character primitives /][\quad\.[\\/]]
  26879. prg.primitive(strNumber( /* "accent" */ 508), quarterword(accent), halfword(0))
  26880. // \xref[accent_][\.[\\accent] primitive]
  26881. prg.primitive(strNumber( /* "advance" */ 509), quarterword(advance), halfword(0))
  26882. // \xref[advance_][\.[\\advance] primitive]
  26883. prg.primitive(strNumber( /* "afterassignment" */ 510), quarterword(afterAssignment), halfword(0))
  26884. // \xref[after_assignment_][\.[\\afterassignment] primitive]
  26885. prg.primitive(strNumber( /* "aftergroup" */ 511), quarterword(afterGroup), halfword(0))
  26886. // \xref[after_group_][\.[\\aftergroup] primitive]
  26887. prg.primitive(strNumber( /* "begingroup" */ 512), quarterword(beginGroup), halfword(0))
  26888. // \xref[begin_group_][\.[\\begingroup] primitive]
  26889. prg.primitive(strNumber( /* "char" */ 513), quarterword(charNum), halfword(0))
  26890. // \xref[char_][\.[\\char] primitive]
  26891. prg.primitive(strNumber( /* "csname" */ 504), quarterword(csName), halfword(0))
  26892. // \xref[cs_name_][\.[\\csname] primitive]
  26893. prg.primitive(strNumber( /* "delimiter" */ 514), quarterword(delimNum), halfword(0))
  26894. // \xref[delimiter_][\.[\\delimiter] primitive]
  26895. prg.primitive(strNumber( /* "divide" */ 515), quarterword(divide), halfword(0))
  26896. // \xref[divide_][\.[\\divide] primitive]
  26897. prg.primitive(strNumber( /* "endcsname" */ 505), quarterword(endCsName), halfword(0))
  26898. // \xref[end_cs_name_][\.[\\endcsname] primitive]
  26899. prg.primitive(strNumber( /* "endgroup" */ 516), quarterword(endGroup), halfword(0))
  26900. // \xref[end_group_][\.[\\endgroup] primitive]
  26901. *prg.hash[frozenEndGroup-514].rh() = 516
  26902. prg.eqtb[frozenEndGroup-1] = prg.eqtb[prg.curVal-1]
  26903. prg.primitive(strNumber( /* "expandafter" */ 517), quarterword(expandAfter), halfword(0))
  26904. // \xref[expand_after_][\.[\\expandafter] primitive]
  26905. prg.primitive(strNumber( /* "font" */ 518), quarterword(defFont), halfword(0))
  26906. // \xref[font_][\.[\\font] primitive]
  26907. prg.primitive(strNumber( /* "fontdimen" */ 519), quarterword(assignFontDimen), halfword(0))
  26908. // \xref[font_dimen_][\.[\\fontdimen] primitive]
  26909. prg.primitive(strNumber( /* "halign" */ 520), quarterword(halign), halfword(0))
  26910. // \xref[halign_][\.[\\halign] primitive]
  26911. prg.primitive(strNumber( /* "hrule" */ 521), quarterword(hrule), halfword(0))
  26912. // \xref[hrule_][\.[\\hrule] primitive]
  26913. prg.primitive(strNumber( /* "ignorespaces" */ 522), quarterword(ignoreSpaces), halfword(0))
  26914. // \xref[ignore_spaces_][\.[\\ignorespaces] primitive]
  26915. prg.primitive(strNumber( /* "insert" */ 330), quarterword(insert), halfword(0))
  26916. // \xref[insert_][\.[\\insert] primitive]
  26917. prg.primitive(strNumber( /* "mark" */ 351), quarterword(mark), halfword(0))
  26918. // \xref[mark_][\.[\\mark] primitive]
  26919. prg.primitive(strNumber( /* "mathaccent" */ 523), quarterword(mathAccent), halfword(0))
  26920. // \xref[math_accent_][\.[\\mathaccent] primitive]
  26921. prg.primitive(strNumber( /* "mathchar" */ 524), quarterword(mathCharNum), halfword(0))
  26922. // \xref[math_char_][\.[\\mathchar] primitive]
  26923. prg.primitive(strNumber( /* "mathchoice" */ 525), quarterword(mathChoice), halfword(0))
  26924. // \xref[math_choice_][\.[\\mathchoice] primitive]
  26925. prg.primitive(strNumber( /* "multiply" */ 526), quarterword(multiply), halfword(0))
  26926. // \xref[multiply_][\.[\\multiply] primitive]
  26927. prg.primitive(strNumber( /* "noalign" */ 527), quarterword(noAlign), halfword(0))
  26928. // \xref[no_align_][\.[\\noalign] primitive]
  26929. prg.primitive(strNumber( /* "noboundary" */ 528), quarterword(noBoundary), halfword(0))
  26930. // \xref[no_boundary_][\.[\\noboundary] primitive]
  26931. prg.primitive(strNumber( /* "noexpand" */ 529), quarterword(noExpand), halfword(0))
  26932. // \xref[no_expand_][\.[\\noexpand] primitive]
  26933. prg.primitive(strNumber( /* "nonscript" */ 335), quarterword(nonScript), halfword(0))
  26934. // \xref[non_script_][\.[\\nonscript] primitive]
  26935. prg.primitive(strNumber( /* "omit" */ 530), quarterword(omit), halfword(0))
  26936. // \xref[omit_][\.[\\omit] primitive]
  26937. prg.primitive(strNumber( /* "parshape" */ 408), quarterword(setShape), halfword(0))
  26938. // \xref[par_shape_][\.[\\parshape] primitive]
  26939. prg.primitive(strNumber( /* "penalty" */ 531), quarterword(breakPenalty), halfword(0))
  26940. // \xref[penalty_][\.[\\penalty] primitive]
  26941. prg.primitive(strNumber( /* "prevgraf" */ 532), quarterword(setPrevGraf), halfword(0))
  26942. // \xref[prev_graf_][\.[\\prevgraf] primitive]
  26943. prg.primitive(strNumber( /* "radical" */ 533), quarterword(radical), halfword(0))
  26944. // \xref[radical_][\.[\\radical] primitive]
  26945. prg.primitive(strNumber( /* "read" */ 534), quarterword(readToCs), halfword(0))
  26946. // \xref[read_][\.[\\read] primitive]
  26947. prg.primitive(strNumber( /* "relax" */ 535), quarterword(relax), halfword(256)) // cf.\ |scan_file_name|
  26948. // \xref[relax_][\.[\\relax] primitive]
  26949. *prg.hash[frozenRelax-514].rh() = 535
  26950. prg.eqtb[frozenRelax-1] = prg.eqtb[prg.curVal-1]
  26951. prg.primitive(strNumber( /* "setbox" */ 536), quarterword(setBox), halfword(0))
  26952. // \xref[set_box_][\.[\\setbox] primitive]
  26953. prg.primitive(strNumber( /* "the" */ 537), quarterword(the), halfword(0))
  26954. // \xref[the_][\.[\\the] primitive]
  26955. prg.primitive(strNumber( /* "toks" */ 407), quarterword(toksRegister), halfword(0))
  26956. // \xref[toks_][\.[\\toks] primitive]
  26957. prg.primitive(strNumber( /* "vadjust" */ 352), quarterword(vadjust), halfword(0))
  26958. // \xref[vadjust_][\.[\\vadjust] primitive]
  26959. prg.primitive(strNumber( /* "valign" */ 538), quarterword(valign), halfword(0))
  26960. // \xref[valign_][\.[\\valign] primitive]
  26961. prg.primitive(strNumber( /* "vcenter" */ 539), quarterword(vcenter), halfword(0))
  26962. // \xref[vcenter_][\.[\\vcenter] primitive]
  26963. prg.primitive(strNumber( /* "vrule" */ 540), quarterword(vrule), halfword(0))
  26964. // \xref[vrule_][\.[\\vrule] primitive]
  26965. prg.primitive(strNumber( /* "par" */ 597), quarterword(parEnd), halfword(256)) // cf.\ |scan_file_name|
  26966. // \xref[par_][\.[\\par] primitive]
  26967. prg.parLoc = uint16(prg.curVal)
  26968. prg.parToken = uint16(07777 + int32(prg.parLoc))
  26969. prg.primitive(strNumber( /* "input" */ 629), quarterword(input), halfword(0))
  26970. // \xref[input_][\.[\\input] primitive]
  26971. prg.primitive(strNumber( /* "endinput" */ 630), quarterword(input), halfword(1))
  26972. // \xref[end_input_][\.[\\endinput] primitive]
  26973. prg.primitive(strNumber( /* "topmark" */ 631), quarterword(topBotMark), halfword(topMarkCode))
  26974. // \xref[top_mark_][\.[\\topmark] primitive]
  26975. prg.primitive(strNumber( /* "firstmark" */ 632), quarterword(topBotMark), halfword(firstMarkCode))
  26976. // \xref[first_mark_][\.[\\firstmark] primitive]
  26977. prg.primitive(strNumber( /* "botmark" */ 633), quarterword(topBotMark), halfword(botMarkCode))
  26978. // \xref[bot_mark_][\.[\\botmark] primitive]
  26979. prg.primitive(strNumber( /* "splitfirstmark" */ 634), quarterword(topBotMark), halfword(splitFirstMarkCode))
  26980. // \xref[split_first_mark_][\.[\\splitfirstmark] primitive]
  26981. prg.primitive(strNumber( /* "splitbotmark" */ 635), quarterword(topBotMark), halfword(splitBotMarkCode))
  26982. // \xref[split_bot_mark_][\.[\\splitbotmark] primitive]
  26983. prg.primitive(strNumber( /* "count" */ 476), quarterword(register), halfword(intVal))
  26984. // \xref[count_][\.[\\count] primitive]
  26985. prg.primitive(strNumber( /* "dimen" */ 500), quarterword(register), halfword(dimenVal))
  26986. // \xref[dimen_][\.[\\dimen] primitive]
  26987. prg.primitive(strNumber( /* "skip" */ 395), quarterword(register), halfword(glueVal))
  26988. // \xref[skip_][\.[\\skip] primitive]
  26989. prg.primitive(strNumber( /* "muskip" */ 396), quarterword(register), halfword(muVal))
  26990. // \xref[mu_skip_][\.[\\muskip] primitive]
  26991. prg.primitive(strNumber( /* "spacefactor" */ 668), quarterword(setAux), halfword(hmode))
  26992. // \xref[space_factor_][\.[\\spacefactor] primitive]
  26993. prg.primitive(strNumber( /* "prevdepth" */ 669), quarterword(setAux), halfword(vmode))
  26994. // \xref[prev_depth_][\.[\\prevdepth] primitive]
  26995. prg.primitive(strNumber( /* "deadcycles" */ 670), quarterword(setPageInt), halfword(0))
  26996. // \xref[dead_cycles_][\.[\\deadcycles] primitive]
  26997. prg.primitive(strNumber( /* "insertpenalties" */ 671), quarterword(setPageInt), halfword(1))
  26998. // \xref[insert_penalties_][\.[\\insertpenalties] primitive]
  26999. prg.primitive(strNumber( /* "wd" */ 672), quarterword(setBoxDimen), halfword(widthOffset))
  27000. // \xref[wd_][\.[\\wd] primitive]
  27001. prg.primitive(strNumber( /* "ht" */ 673), quarterword(setBoxDimen), halfword(heightOffset))
  27002. // \xref[ht_][\.[\\ht] primitive]
  27003. prg.primitive(strNumber( /* "dp" */ 674), quarterword(setBoxDimen), halfword(depthOffset))
  27004. // \xref[dp_][\.[\\dp] primitive]
  27005. prg.primitive(strNumber( /* "lastpenalty" */ 675), quarterword(lastItem), halfword(intVal))
  27006. // \xref[last_penalty_][\.[\\lastpenalty] primitive]
  27007. prg.primitive(strNumber( /* "lastkern" */ 676), quarterword(lastItem), halfword(dimenVal))
  27008. // \xref[last_kern_][\.[\\lastkern] primitive]
  27009. prg.primitive(strNumber( /* "lastskip" */ 677), quarterword(lastItem), halfword(glueVal))
  27010. // \xref[last_skip_][\.[\\lastskip] primitive]
  27011. prg.primitive(strNumber( /* "inputlineno" */ 678), quarterword(lastItem), halfword(inputLineNoCode))
  27012. // \xref[input_line_no_][\.[\\inputlineno] primitive]
  27013. prg.primitive(strNumber( /* "badness" */ 679), quarterword(lastItem), halfword(badnessCode))
  27014. // \xref[badness_][\.[\\badness] primitive]
  27015. prg.primitive(strNumber( /* "number" */ 735), quarterword(convert), halfword(numberCode))
  27016. // \xref[number_][\.[\\number] primitive]
  27017. prg.primitive(strNumber( /* "romannumeral" */ 736), quarterword(convert), halfword(romanNumeralCode))
  27018. // \xref[roman_numeral_][\.[\\romannumeral] primitive]
  27019. prg.primitive(strNumber( /* "string" */ 737), quarterword(convert), halfword(stringCode))
  27020. // \xref[string_][\.[\\string] primitive]
  27021. prg.primitive(strNumber( /* "meaning" */ 738), quarterword(convert), halfword(meaningCode))
  27022. // \xref[meaning_][\.[\\meaning] primitive]
  27023. prg.primitive(strNumber( /* "fontname" */ 739), quarterword(convert), halfword(fontNameCode))
  27024. // \xref[font_name_][\.[\\fontname] primitive]
  27025. prg.primitive(strNumber( /* "jobname" */ 740), quarterword(convert), halfword(jobNameCode))
  27026. // \xref[job_name_][\.[\\jobname] primitive]
  27027. prg.primitive(strNumber( /* "if" */ 757), quarterword(ifTest), halfword(ifCharCode))
  27028. // \xref[if_char_][\.[\\if] primitive]
  27029. prg.primitive(strNumber( /* "ifcat" */ 758), quarterword(ifTest), halfword(ifCatCode))
  27030. // \xref[if_cat_code_][\.[\\ifcat] primitive]
  27031. prg.primitive(strNumber( /* "ifnum" */ 759), quarterword(ifTest), halfword(ifIntCode))
  27032. // \xref[if_int_][\.[\\ifnum] primitive]
  27033. prg.primitive(strNumber( /* "ifdim" */ 760), quarterword(ifTest), halfword(ifDimCode))
  27034. // \xref[if_dim_][\.[\\ifdim] primitive]
  27035. prg.primitive(strNumber( /* "ifodd" */ 761), quarterword(ifTest), halfword(ifOddCode))
  27036. // \xref[if_odd_][\.[\\ifodd] primitive]
  27037. prg.primitive(strNumber( /* "ifvmode" */ 762), quarterword(ifTest), halfword(ifVmodeCode))
  27038. // \xref[if_vmode_][\.[\\ifvmode] primitive]
  27039. prg.primitive(strNumber( /* "ifhmode" */ 763), quarterword(ifTest), halfword(ifHmodeCode))
  27040. // \xref[if_hmode_][\.[\\ifhmode] primitive]
  27041. prg.primitive(strNumber( /* "ifmmode" */ 764), quarterword(ifTest), halfword(ifMmodeCode))
  27042. // \xref[if_mmode_][\.[\\ifmmode] primitive]
  27043. prg.primitive(strNumber( /* "ifinner" */ 765), quarterword(ifTest), halfword(ifInnerCode))
  27044. // \xref[if_inner_][\.[\\ifinner] primitive]
  27045. prg.primitive(strNumber( /* "ifvoid" */ 766), quarterword(ifTest), halfword(ifVoidCode))
  27046. // \xref[if_void_][\.[\\ifvoid] primitive]
  27047. prg.primitive(strNumber( /* "ifhbox" */ 767), quarterword(ifTest), halfword(ifHboxCode))
  27048. // \xref[if_hbox_][\.[\\ifhbox] primitive]
  27049. prg.primitive(strNumber( /* "ifvbox" */ 768), quarterword(ifTest), halfword(ifVboxCode))
  27050. // \xref[if_vbox_][\.[\\ifvbox] primitive]
  27051. prg.primitive(strNumber( /* "ifx" */ 769), quarterword(ifTest), halfword(ifxCode))
  27052. // \xref[ifx_][\.[\\ifx] primitive]
  27053. prg.primitive(strNumber( /* "ifeof" */ 770), quarterword(ifTest), halfword(ifEofCode))
  27054. // \xref[if_eof_][\.[\\ifeof] primitive]
  27055. prg.primitive(strNumber( /* "iftrue" */ 771), quarterword(ifTest), halfword(ifTrueCode))
  27056. // \xref[if_true_][\.[\\iftrue] primitive]
  27057. prg.primitive(strNumber( /* "iffalse" */ 772), quarterword(ifTest), halfword(ifFalseCode))
  27058. // \xref[if_false_][\.[\\iffalse] primitive]
  27059. prg.primitive(strNumber( /* "ifcase" */ 773), quarterword(ifTest), halfword(ifCaseCode))
  27060. // \xref[if_case_][\.[\\ifcase] primitive]
  27061. prg.primitive(strNumber( /* "fi" */ 774), quarterword(fiOrElse), halfword(fiCode))
  27062. // \xref[fi_][\.[\\fi] primitive]
  27063. *prg.hash[frozenFi-514].rh() = 774
  27064. prg.eqtb[frozenFi-1] = prg.eqtb[prg.curVal-1]
  27065. prg.primitive(strNumber( /* "or" */ 775), quarterword(fiOrElse), halfword(orCode))
  27066. // \xref[or_][\.[\\or] primitive]
  27067. prg.primitive(strNumber( /* "else" */ 776), quarterword(fiOrElse), halfword(elseCode))
  27068. // \xref[else_][\.[\\else] primitive]
  27069. prg.primitive(strNumber( /* "nullfont" */ 801), quarterword(setFont), halfword(fontBase))
  27070. // \xref[null_font_][\.[\\nullfont] primitive]
  27071. *prg.hash[frozenNullFont-514].rh() = 801
  27072. prg.eqtb[frozenNullFont-1] = prg.eqtb[prg.curVal-1]
  27073. prg.primitive(strNumber( /* "span" */ 898), quarterword(tabMark), halfword(spanCode))
  27074. // \xref[span_][\.[\\span] primitive]
  27075. prg.primitive(strNumber( /* "cr" */ 899), quarterword(carRet), halfword(crCode))
  27076. // \xref[cr_][\.[\\cr] primitive]
  27077. *prg.hash[frozenCr-514].rh() = 899
  27078. prg.eqtb[frozenCr-1] = prg.eqtb[prg.curVal-1]
  27079. prg.primitive(strNumber( /* "crcr" */ 900), quarterword(carRet), halfword(crCrCode))
  27080. // \xref[cr_cr_][\.[\\crcr] primitive]
  27081. *prg.hash[frozenEndTemplate-514].rh() = 901
  27082. *prg.hash[frozenEndv-514].rh() = 901
  27083. // \xref[endtemplate]
  27084. *(*prg.eqtb[frozenEndv-1].hh()).b0() = byte(endv)
  27085. *(*prg.eqtb[frozenEndv-1].hh()).rh() = uint16(30000 - 11)
  27086. *(*prg.eqtb[frozenEndv-1].hh()).b1() = byte(levelOne)
  27087. prg.eqtb[frozenEndTemplate-1] = prg.eqtb[frozenEndv-1]
  27088. *(*prg.eqtb[frozenEndTemplate-1].hh()).b0() = byte(endTemplate)
  27089. prg.primitive(strNumber( /* "pagegoal" */ 970), quarterword(setPageDimen), halfword(0))
  27090. // \xref[page_goal_][\.[\\pagegoal] primitive]
  27091. prg.primitive(strNumber( /* "pagetotal" */ 971), quarterword(setPageDimen), halfword(1))
  27092. // \xref[page_total_][\.[\\pagetotal] primitive]
  27093. prg.primitive(strNumber( /* "pagestretch" */ 972), quarterword(setPageDimen), halfword(2))
  27094. // \xref[page_stretch_][\.[\\pagestretch] primitive]
  27095. prg.primitive(strNumber( /* "pagefilstretch" */ 973), quarterword(setPageDimen), halfword(3))
  27096. // \xref[page_fil_stretch_][\.[\\pagefilstretch] primitive]
  27097. prg.primitive(strNumber( /* "pagefillstretch" */ 974), quarterword(setPageDimen), halfword(4))
  27098. // \xref[page_fill_stretch_][\.[\\pagefillstretch] primitive]
  27099. prg.primitive(strNumber( /* "pagefilllstretch" */ 975), quarterword(setPageDimen), halfword(5))
  27100. // \xref[page_filll_stretch_][\.[\\pagefilllstretch] primitive]
  27101. prg.primitive(strNumber( /* "pageshrink" */ 976), quarterword(setPageDimen), halfword(6))
  27102. // \xref[page_shrink_][\.[\\pageshrink] primitive]
  27103. prg.primitive(strNumber( /* "pagedepth" */ 977), quarterword(setPageDimen), halfword(7))
  27104. // \xref[page_depth_][\.[\\pagedepth] primitive]
  27105. prg.primitive(strNumber( /* "end" */ 1025), quarterword(stop), halfword(0))
  27106. // \xref[end_][\.[\\end] primitive]
  27107. prg.primitive(strNumber( /* "dump" */ 1026), quarterword(stop), halfword(1))
  27108. // \xref[dump_][\.[\\dump] primitive]
  27109. prg.primitive(strNumber( /* "hskip" */ 1027), quarterword(hskip), halfword(skipCode))
  27110. // \xref[hskip_][\.[\\hskip] primitive]
  27111. prg.primitive(strNumber( /* "hfil" */ 1028), quarterword(hskip), halfword(filCode))
  27112. // \xref[hfil_][\.[\\hfil] primitive]
  27113. prg.primitive(strNumber( /* "hfill" */ 1029), quarterword(hskip), halfword(fillCode))
  27114. // \xref[hfill_][\.[\\hfill] primitive]
  27115. prg.primitive(strNumber( /* "hss" */ 1030), quarterword(hskip), halfword(ssCode))
  27116. // \xref[hss_][\.[\\hss] primitive]
  27117. prg.primitive(strNumber( /* "hfilneg" */ 1031), quarterword(hskip), halfword(filNegCode))
  27118. // \xref[hfil_neg_][\.[\\hfilneg] primitive]
  27119. prg.primitive(strNumber( /* "vskip" */ 1032), quarterword(vskip), halfword(skipCode))
  27120. // \xref[vskip_][\.[\\vskip] primitive]
  27121. prg.primitive(strNumber( /* "vfil" */ 1033), quarterword(vskip), halfword(filCode))
  27122. // \xref[vfil_][\.[\\vfil] primitive]
  27123. prg.primitive(strNumber( /* "vfill" */ 1034), quarterword(vskip), halfword(fillCode))
  27124. // \xref[vfill_][\.[\\vfill] primitive]
  27125. prg.primitive(strNumber( /* "vss" */ 1035), quarterword(vskip), halfword(ssCode))
  27126. // \xref[vss_][\.[\\vss] primitive]
  27127. prg.primitive(strNumber( /* "vfilneg" */ 1036), quarterword(vskip), halfword(filNegCode))
  27128. // \xref[vfil_neg_][\.[\\vfilneg] primitive]
  27129. prg.primitive(strNumber( /* "mskip" */ 336), quarterword(mskip), halfword(mskipCode))
  27130. // \xref[mskip_][\.[\\mskip] primitive]
  27131. prg.primitive(strNumber( /* "kern" */ 340), quarterword(kern), halfword(explicit))
  27132. // \xref[kern_][\.[\\kern] primitive]
  27133. prg.primitive(strNumber( /* "mkern" */ 342), quarterword(mkern), halfword(muGlue))
  27134. // \xref[mkern_][\.[\\mkern] primitive]
  27135. prg.primitive(strNumber( /* "moveleft" */ 1054), quarterword(hmove), halfword(1))
  27136. // \xref[move_left_][\.[\\moveleft] primitive]
  27137. prg.primitive(strNumber( /* "moveright" */ 1055), quarterword(hmove), halfword(0))
  27138. // \xref[move_right_][\.[\\moveright] primitive]
  27139. prg.primitive(strNumber( /* "raise" */ 1056), quarterword(vmove), halfword(1))
  27140. // \xref[raise_][\.[\\raise] primitive]
  27141. prg.primitive(strNumber( /* "lower" */ 1057), quarterword(vmove), halfword(0))
  27142. // \xref[lower_][\.[\\lower] primitive]
  27143. prg.primitive(strNumber( /* "box" */ 409), quarterword(makeBox), halfword(boxCode))
  27144. // \xref[box_][\.[\\box] primitive]
  27145. prg.primitive(strNumber( /* "copy" */ 1058), quarterword(makeBox), halfword(copyCode))
  27146. // \xref[copy_][\.[\\copy] primitive]
  27147. prg.primitive(strNumber( /* "lastbox" */ 1059), quarterword(makeBox), halfword(lastBoxCode))
  27148. // \xref[last_box_][\.[\\lastbox] primitive]
  27149. prg.primitive(strNumber( /* "vsplit" */ 965), quarterword(makeBox), halfword(vsplitCode))
  27150. // \xref[vsplit_][\.[\\vsplit] primitive]
  27151. prg.primitive(strNumber( /* "vtop" */ 1060), quarterword(makeBox), halfword(vtopCode))
  27152. // \xref[vtop_][\.[\\vtop] primitive]
  27153. prg.primitive(strNumber( /* "vbox" */ 967), quarterword(makeBox), halfword(vtopCode+vmode))
  27154. // \xref[vbox_][\.[\\vbox] primitive]
  27155. prg.primitive(strNumber( /* "hbox" */ 1061), quarterword(makeBox), halfword(vtopCode+hmode))
  27156. // \xref[hbox_][\.[\\hbox] primitive]
  27157. prg.primitive(strNumber( /* "shipout" */ 1062), quarterword(leaderShip), halfword(aLeaders-1)) // |ship_out_flag=leader_flag-1|
  27158. // \xref[ship_out_][\.[\\shipout] primitive]
  27159. prg.primitive(strNumber( /* "leaders" */ 1063), quarterword(leaderShip), halfword(aLeaders))
  27160. // \xref[leaders_][\.[\\leaders] primitive]
  27161. prg.primitive(strNumber( /* "cleaders" */ 1064), quarterword(leaderShip), halfword(cLeaders))
  27162. // \xref[c_leaders_][\.[\\cleaders] primitive]
  27163. prg.primitive(strNumber( /* "xleaders" */ 1065), quarterword(leaderShip), halfword(xLeaders))
  27164. // \xref[x_leaders_][\.[\\xleaders] primitive]
  27165. prg.primitive(strNumber( /* "indent" */ 1080), quarterword(startPar), halfword(1))
  27166. // \xref[indent_][\.[\\indent] primitive]
  27167. prg.primitive(strNumber( /* "noindent" */ 1081), quarterword(startPar), halfword(0))
  27168. // \xref[no_indent_][\.[\\noindent] primitive]
  27169. prg.primitive(strNumber( /* "unpenalty" */ 1090), quarterword(removeItem), halfword(penaltyNode))
  27170. // \xref[un_penalty_][\.[\\unpenalty] primitive]
  27171. prg.primitive(strNumber( /* "unkern" */ 1091), quarterword(removeItem), halfword(kernNode))
  27172. // \xref[un_kern_][\.[\\unkern] primitive]
  27173. prg.primitive(strNumber( /* "unskip" */ 1092), quarterword(removeItem), halfword(glueNode))
  27174. // \xref[un_skip_][\.[\\unskip] primitive]
  27175. prg.primitive(strNumber( /* "unhbox" */ 1093), quarterword(unHbox), halfword(boxCode))
  27176. // \xref[un_hbox_][\.[\\unhbox] primitive]
  27177. prg.primitive(strNumber( /* "unhcopy" */ 1094), quarterword(unHbox), halfword(copyCode))
  27178. // \xref[un_hcopy_][\.[\\unhcopy] primitive]
  27179. prg.primitive(strNumber( /* "unvbox" */ 1095), quarterword(unVbox), halfword(boxCode))
  27180. // \xref[un_vbox_][\.[\\unvbox] primitive]
  27181. prg.primitive(strNumber( /* "unvcopy" */ 1096), quarterword(unVbox), halfword(copyCode))
  27182. // \xref[un_vcopy_][\.[\\unvcopy] primitive]
  27183. prg.primitive(strNumber('-'), quarterword(discretionary), halfword(1))
  27184. // \xref[Single-character primitives -][\quad\.[\\-]]
  27185. prg.primitive(strNumber( /* "discretionary" */ 349), quarterword(discretionary), halfword(0))
  27186. // \xref[discretionary_][\.[\\discretionary] primitive]
  27187. prg.primitive(strNumber( /* "eqno" */ 1127), quarterword(eqNo), halfword(0))
  27188. // \xref[eq_no_][\.[\\eqno] primitive]
  27189. prg.primitive(strNumber( /* "leqno" */ 1128), quarterword(eqNo), halfword(1))
  27190. // \xref[leq_no_][\.[\\leqno] primitive]
  27191. prg.primitive(strNumber( /* "mathord" */ 866), quarterword(mathComp), halfword(ordNoad))
  27192. // \xref[math_ord_][\.[\\mathord] primitive]
  27193. prg.primitive(strNumber( /* "mathop" */ 867), quarterword(mathComp), halfword(opNoad))
  27194. // \xref[math_op_][\.[\\mathop] primitive]
  27195. prg.primitive(strNumber( /* "mathbin" */ 868), quarterword(mathComp), halfword(binNoad))
  27196. // \xref[math_bin_][\.[\\mathbin] primitive]
  27197. prg.primitive(strNumber( /* "mathrel" */ 869), quarterword(mathComp), halfword(relNoad))
  27198. // \xref[math_rel_][\.[\\mathrel] primitive]
  27199. prg.primitive(strNumber( /* "mathopen" */ 870), quarterword(mathComp), halfword(openNoad))
  27200. // \xref[math_open_][\.[\\mathopen] primitive]
  27201. prg.primitive(strNumber( /* "mathclose" */ 871), quarterword(mathComp), halfword(closeNoad))
  27202. // \xref[math_close_][\.[\\mathclose] primitive]
  27203. prg.primitive(strNumber( /* "mathpunct" */ 872), quarterword(mathComp), halfword(punctNoad))
  27204. // \xref[math_punct_][\.[\\mathpunct] primitive]
  27205. prg.primitive(strNumber( /* "mathinner" */ 873), quarterword(mathComp), halfword(innerNoad))
  27206. // \xref[math_inner_][\.[\\mathinner] primitive]
  27207. prg.primitive(strNumber( /* "underline" */ 875), quarterword(mathComp), halfword(underNoad))
  27208. // \xref[underline_][\.[\\underline] primitive]
  27209. prg.primitive(strNumber( /* "overline" */ 874), quarterword(mathComp), halfword(overNoad))
  27210. // \xref[overline_][\.[\\overline] primitive]
  27211. prg.primitive(strNumber( /* "displaylimits" */ 1129), quarterword(limitSwitch), halfword(normal))
  27212. // \xref[display_limits_][\.[\\displaylimits] primitive]
  27213. prg.primitive(strNumber( /* "limits" */ 878), quarterword(limitSwitch), halfword(limits))
  27214. // \xref[limits_][\.[\\limits] primitive]
  27215. prg.primitive(strNumber( /* "nolimits" */ 879), quarterword(limitSwitch), halfword(noLimits))
  27216. // \xref[no_limits_][\.[\\nolimits] primitive]
  27217. prg.primitive(strNumber( /* "displaystyle" */ 861), quarterword(mathStyle), halfword(displayStyle))
  27218. // \xref[display_style_][\.[\\displaystyle] primitive]
  27219. prg.primitive(strNumber( /* "textstyle" */ 862), quarterword(mathStyle), halfword(textStyle))
  27220. // \xref[text_style_][\.[\\textstyle] primitive]
  27221. prg.primitive(strNumber( /* "scriptstyle" */ 863), quarterword(mathStyle), halfword(scriptStyle))
  27222. // \xref[script_style_][\.[\\scriptstyle] primitive]
  27223. prg.primitive(strNumber( /* "scriptscriptstyle" */ 864), quarterword(mathStyle), halfword(scriptScriptStyle))
  27224. // \xref[script_script_style_][\.[\\scriptscriptstyle] primitive]
  27225. prg.primitive(strNumber( /* "above" */ 1147), quarterword(above), halfword(aboveCode))
  27226. // \xref[above_][\.[\\above] primitive]
  27227. prg.primitive(strNumber( /* "over" */ 1148), quarterword(above), halfword(overCode))
  27228. // \xref[over_][\.[\\over] primitive]
  27229. prg.primitive(strNumber( /* "atop" */ 1149), quarterword(above), halfword(atopCode))
  27230. // \xref[atop_][\.[\\atop] primitive]
  27231. prg.primitive(strNumber( /* "abovewithdelims" */ 1150), quarterword(above), halfword(delimitedCode+aboveCode))
  27232. // \xref[above_with_delims_][\.[\\abovewithdelims] primitive]
  27233. prg.primitive(strNumber( /* "overwithdelims" */ 1151), quarterword(above), halfword(delimitedCode+overCode))
  27234. // \xref[over_with_delims_][\.[\\overwithdelims] primitive]
  27235. prg.primitive(strNumber( /* "atopwithdelims" */ 1152), quarterword(above), halfword(delimitedCode+atopCode))
  27236. // \xref[atop_with_delims_][\.[\\atopwithdelims] primitive]
  27237. prg.primitive(strNumber( /* "left" */ 876), quarterword(leftRight), halfword(leftNoad))
  27238. // \xref[left_][\.[\\left] primitive]
  27239. prg.primitive(strNumber( /* "right" */ 877), quarterword(leftRight), halfword(rightNoad))
  27240. // \xref[right_][\.[\\right] primitive]
  27241. *prg.hash[frozenRight-514].rh() = 877
  27242. prg.eqtb[frozenRight-1] = prg.eqtb[prg.curVal-1]
  27243. prg.primitive(strNumber( /* "long" */ 1171), quarterword(prefix), halfword(1))
  27244. // \xref[long_][\.[\\long] primitive]
  27245. prg.primitive(strNumber( /* "outer" */ 1172), quarterword(prefix), halfword(2))
  27246. // \xref[outer_][\.[\\outer] primitive]
  27247. prg.primitive(strNumber( /* "global" */ 1173), quarterword(prefix), halfword(4))
  27248. // \xref[global_][\.[\\global] primitive]
  27249. prg.primitive(strNumber( /* "def" */ 1174), quarterword(def), halfword(0))
  27250. // \xref[def_][\.[\\def] primitive]
  27251. prg.primitive(strNumber( /* "gdef" */ 1175), quarterword(def), halfword(1))
  27252. // \xref[gdef_][\.[\\gdef] primitive]
  27253. prg.primitive(strNumber( /* "edef" */ 1176), quarterword(def), halfword(2))
  27254. // \xref[edef_][\.[\\edef] primitive]
  27255. prg.primitive(strNumber( /* "xdef" */ 1177), quarterword(def), halfword(3))
  27256. // \xref[xdef_][\.[\\xdef] primitive]
  27257. prg.primitive(strNumber( /* "let" */ 1191), quarterword(let), halfword(normal))
  27258. // \xref[let_][\.[\\let] primitive]
  27259. prg.primitive(strNumber( /* "futurelet" */ 1192), quarterword(let), halfword(normal+1))
  27260. // \xref[future_let_][\.[\\futurelet] primitive]
  27261. prg.primitive(strNumber( /* "chardef" */ 1193), quarterword(shorthandDef), halfword(charDefCode))
  27262. // \xref[char_def_][\.[\\chardef] primitive]
  27263. prg.primitive(strNumber( /* "mathchardef" */ 1194), quarterword(shorthandDef), halfword(mathCharDefCode))
  27264. // \xref[math_char_def_][\.[\\mathchardef] primitive]
  27265. prg.primitive(strNumber( /* "countdef" */ 1195), quarterword(shorthandDef), halfword(countDefCode))
  27266. // \xref[count_def_][\.[\\countdef] primitive]
  27267. prg.primitive(strNumber( /* "dimendef" */ 1196), quarterword(shorthandDef), halfword(dimenDefCode))
  27268. // \xref[dimen_def_][\.[\\dimendef] primitive]
  27269. prg.primitive(strNumber( /* "skipdef" */ 1197), quarterword(shorthandDef), halfword(skipDefCode))
  27270. // \xref[skip_def_][\.[\\skipdef] primitive]
  27271. prg.primitive(strNumber( /* "muskipdef" */ 1198), quarterword(shorthandDef), halfword(muSkipDefCode))
  27272. // \xref[mu_skip_def_][\.[\\muskipdef] primitive]
  27273. prg.primitive(strNumber( /* "toksdef" */ 1199), quarterword(shorthandDef), halfword(toksDefCode))
  27274. // \xref[toks_def_][\.[\\toksdef] primitive]
  27275. prg.primitive(strNumber( /* "catcode" */ 415), quarterword(defCode), halfword(catCodeBase))
  27276. // \xref[cat_code_][\.[\\catcode] primitive]
  27277. prg.primitive(strNumber( /* "mathcode" */ 419), quarterword(defCode), halfword(mathCodeBase))
  27278. // \xref[math_code_][\.[\\mathcode] primitive]
  27279. prg.primitive(strNumber( /* "lccode" */ 416), quarterword(defCode), halfword(lcCodeBase))
  27280. // \xref[lc_code_][\.[\\lccode] primitive]
  27281. prg.primitive(strNumber( /* "uccode" */ 417), quarterword(defCode), halfword(ucCodeBase))
  27282. // \xref[uc_code_][\.[\\uccode] primitive]
  27283. prg.primitive(strNumber( /* "sfcode" */ 418), quarterword(defCode), halfword(sfCodeBase))
  27284. // \xref[sf_code_][\.[\\sfcode] primitive]
  27285. prg.primitive(strNumber( /* "delcode" */ 477), quarterword(defCode), halfword(delCodeBase))
  27286. // \xref[del_code_][\.[\\delcode] primitive]
  27287. prg.primitive(strNumber( /* "textfont" */ 412), quarterword(defFamily), halfword(mathFontBase))
  27288. // \xref[text_font_][\.[\\textfont] primitive]
  27289. prg.primitive(strNumber( /* "scriptfont" */ 413), quarterword(defFamily), halfword(mathFontBase+scriptSize))
  27290. // \xref[script_font_][\.[\\scriptfont] primitive]
  27291. prg.primitive(strNumber( /* "scriptscriptfont" */ 414), quarterword(defFamily), halfword(mathFontBase+scriptScriptSize))
  27292. // \xref[script_script_font_][\.[\\scriptscriptfont] primitive]
  27293. prg.primitive(strNumber( /* "hyphenation" */ 941), quarterword(hyphData), halfword(0))
  27294. // \xref[hyphenation_][\.[\\hyphenation] primitive]
  27295. prg.primitive(strNumber( /* "patterns" */ 953), quarterword(hyphData), halfword(1))
  27296. // \xref[patterns_][\.[\\patterns] primitive]
  27297. prg.primitive(strNumber( /* "hyphenchar" */ 1217), quarterword(assignFontInt), halfword(0))
  27298. // \xref[hyphen_char_][\.[\\hyphenchar] primitive]
  27299. prg.primitive(strNumber( /* "skewchar" */ 1218), quarterword(assignFontInt), halfword(1))
  27300. // \xref[skew_char_][\.[\\skewchar] primitive]
  27301. prg.primitive(strNumber( /* "batchmode" */ 274), quarterword(setInteraction), halfword(batchMode))
  27302. // \xref[batch_mode_][\.[\\batchmode] primitive]
  27303. prg.primitive(strNumber( /* "nonstopmode" */ 275), quarterword(setInteraction), halfword(nonstopMode))
  27304. // \xref[nonstop_mode_][\.[\\nonstopmode] primitive]
  27305. prg.primitive(strNumber( /* "scrollmode" */ 276), quarterword(setInteraction), halfword(scrollMode))
  27306. // \xref[scroll_mode_][\.[\\scrollmode] primitive]
  27307. prg.primitive(strNumber( /* "errorstopmode" */ 1227), quarterword(setInteraction), halfword(errorStopMode))
  27308. // \xref[error_stop_mode_][\.[\\errorstopmode] primitive]
  27309. prg.primitive(strNumber( /* "openin" */ 1228), quarterword(inStream), halfword(1))
  27310. // \xref[open_in_][\.[\\openin] primitive]
  27311. prg.primitive(strNumber( /* "closein" */ 1229), quarterword(inStream), halfword(0))
  27312. // \xref[close_in_][\.[\\closein] primitive]
  27313. prg.primitive(strNumber( /* "message" */ 1230), quarterword(message), halfword(0))
  27314. // \xref[message_][\.[\\message] primitive]
  27315. prg.primitive(strNumber( /* "errmessage" */ 1231), quarterword(message), halfword(1))
  27316. // \xref[err_message_][\.[\\errmessage] primitive]
  27317. prg.primitive(strNumber( /* "lowercase" */ 1237), quarterword(caseShift), halfword(lcCodeBase))
  27318. // \xref[lowercase_][\.[\\lowercase] primitive]
  27319. prg.primitive(strNumber( /* "uppercase" */ 1238), quarterword(caseShift), halfword(ucCodeBase))
  27320. // \xref[uppercase_][\.[\\uppercase] primitive]
  27321. prg.primitive(strNumber( /* "show" */ 1239), quarterword(xray), halfword(showCode))
  27322. // \xref[show_][\.[\\show] primitive]
  27323. prg.primitive(strNumber( /* "showbox" */ 1240), quarterword(xray), halfword(showBoxCode))
  27324. // \xref[show_box_][\.[\\showbox] primitive]
  27325. prg.primitive(strNumber( /* "showthe" */ 1241), quarterword(xray), halfword(showTheCode))
  27326. // \xref[show_the_][\.[\\showthe] primitive]
  27327. prg.primitive(strNumber( /* "showlists" */ 1242), quarterword(xray), halfword(showListsCode))
  27328. // \xref[show_lists_code_][\.[\\showlists] primitive]
  27329. prg.primitive(strNumber( /* "openout" */ 1285), quarterword(extension), halfword(openNode))
  27330. // \xref[open_out_][\.[\\openout] primitive]
  27331. prg.primitive(strNumber( /* "write" */ 594), quarterword(extension), halfword(writeNode))
  27332. prg.writeLoc = uint16(prg.curVal)
  27333. // \xref[write_][\.[\\write] primitive]
  27334. prg.primitive(strNumber( /* "closeout" */ 1286), quarterword(extension), halfword(closeNode))
  27335. // \xref[close_out_][\.[\\closeout] primitive]
  27336. prg.primitive(strNumber( /* "special" */ 1287), quarterword(extension), halfword(specialNode))
  27337. // \xref[special_][\.[\\special] primitive]
  27338. prg.primitive(strNumber( /* "immediate" */ 1288), quarterword(extension), halfword(immediateCode))
  27339. // \xref[immediate_][\.[\\immediate] primitive]
  27340. prg.primitive(strNumber( /* "setlanguage" */ 1289), quarterword(extension), halfword(setLanguageCode))
  27341. // \xref[set_language_][\.[\\setlanguage] primitive]
  27342. prg.noNewControlSequence = true
  27343. }
  27344. // procedure debug_help; [routine to display various things]
  27345. // label breakpoint,exit;
  27346. // var k, l, m, n:integer;
  27347. // begin ;
  27348. // while true do begin ;
  27349. // print_nl(["debug # (-1 to exit):"=]1284); ;
  27350. // [ \xref[debug \#] ]
  27351. // read(term_in,m);
  27352. // if m<0 then goto exit
  27353. // else if m=0 then
  27354. // begin goto breakpoint;
  27355. // [go to every declared label at least once]
  27356. // breakpoint: m:=0; ['BREAKPOINT']
  27357. //
  27358. // end
  27359. // else begin read(term_in,n);
  27360. // case m of
  27361. // [ \4 ]
  27362. // [ Numbered cases for |debug_help| ]
  27363. // 1: print_word(mem[n]); [display |mem[n]| in all forms]
  27364. // 2: print_int( mem[ n].hh.lh );
  27365. // 3: print_int( mem[ n].hh.rh );
  27366. // 4: print_word(eqtb[n]);
  27367. // 5: print_word(font_info[n]);
  27368. // 6: print_word(save_stack[n]);
  27369. // 7: show_box(n);
  27370. // [show a box, abbreviated by |show_box_depth| and |show_box_breadth|]
  27371. // 8: begin breadth_max:=10000; depth_threshold:=pool_size-pool_ptr-10;
  27372. // show_node_list(n); [show a box in its entirety]
  27373. // end;
  27374. // 9: show_token_list(n,0 ,1000);
  27375. // 10: slow_print(n);
  27376. // 11: check_mem(n>0); [check wellformedness; print new busy locations if |n>0|]
  27377. // 12: search_mem(n); [look for pointers to |n|]
  27378. // 13: begin read(term_in,l); print_cmd_chr(n,l);
  27379. // end;
  27380. // 14: for k:=0 to n do print(buffer[k]);
  27381. // 15: begin font_in_short_display:=font_base ; short_display(n);
  27382. // end;
  27383. // 16: panicking:=not panicking;
  27384. //
  27385. //
  27386. // else print(["?"=]63)
  27387. // end ;
  27388. // end;
  27389. // end;
  27390. // exit:end;
  27391. // [ ]
  27392. // 1332.
  27393. // tangle:pos tex.web:24275:61:
  27394. // Now this is really it: \TeX\ starts and ends here.
  27395. //
  27396. // The initial test involving |ready_already| should be deleted if the
  27397. // \PASCAL\ runtime system is smart enough to detect such a “mistake.”
  27398. // \xref[system dependencies]
  27399. func (prg *prg) main() {
  27400. defer func() {
  27401. if prg.dviFile != nil {
  27402. prg.dviFile.Close()
  27403. }
  27404. if prg.fmtFile != nil {
  27405. prg.fmtFile.Close()
  27406. }
  27407. if prg.logFile != nil {
  27408. prg.logFile.Close()
  27409. }
  27410. if prg.poolFile != nil {
  27411. prg.poolFile.Close()
  27412. }
  27413. if prg.stderr != nil {
  27414. prg.stderr.Close()
  27415. }
  27416. if prg.stdin != nil {
  27417. prg.stdin.Close()
  27418. }
  27419. if prg.stdout != nil {
  27420. prg.stdout.Close()
  27421. }
  27422. if prg.termIn != nil {
  27423. prg.termIn.Close()
  27424. }
  27425. if prg.termOut != nil {
  27426. prg.termOut.Close()
  27427. }
  27428. if prg.tfmFile != nil {
  27429. prg.tfmFile.Close()
  27430. }
  27431. }()
  27432. prg.history = byte(fatalErrorStop) // in case we quit during initialization
  27433. prg.termOut.Rewrite("TTY:", "/O") // open the terminal for output
  27434. if prg.readyAlready == 314159 {
  27435. goto startOfTex
  27436. }
  27437. // Check the “constant” values...
  27438. prg.bad = 0
  27439. if halfErrorLine < 30 || halfErrorLine > errorLine-15 {
  27440. prg.bad = 1
  27441. }
  27442. if maxPrintLine < 60 {
  27443. prg.bad = 2
  27444. }
  27445. if dviBufSize%8 != 0 {
  27446. prg.bad = 3
  27447. }
  27448. if memBot+1100 > 30000 {
  27449. prg.bad = 4
  27450. }
  27451. if hashPrime > hashSize {
  27452. prg.bad = 5
  27453. }
  27454. if maxInOpen >= 128 {
  27455. prg.bad = 6
  27456. }
  27457. if 30000 < 256+11 {
  27458. prg.bad = 7
  27459. } // we will want |null_list>255|
  27460. if memMin != memBot || memMax != 30000 {
  27461. prg.bad = 10
  27462. }
  27463. if memMin > memBot || memMax < 30000 {
  27464. prg.bad = 10
  27465. }
  27466. if minQuarterword > 0 || maxQuarterword < 127 {
  27467. prg.bad = 11
  27468. }
  27469. if 0 > 0 || 65535 < 32767 {
  27470. prg.bad = 12
  27471. }
  27472. if minQuarterword < 0 || maxQuarterword > 65535 {
  27473. prg.bad = 13
  27474. }
  27475. if memMin < 0 || memMax >= 65535 || memBot-memMin > 65535+1 {
  27476. prg.bad = 14
  27477. }
  27478. if fontBase < minQuarterword || fontMax > maxQuarterword {
  27479. prg.bad = 15
  27480. }
  27481. if fontMax > fontBase+256 {
  27482. prg.bad = 16
  27483. }
  27484. if saveSize > 65535 || maxStrings > 65535 {
  27485. prg.bad = 17
  27486. }
  27487. if bufSize > 65535 {
  27488. prg.bad = 18
  27489. }
  27490. if maxQuarterword-minQuarterword < 255 {
  27491. prg.bad = 19
  27492. }
  27493. if 07777+undefinedControlSequence > 65535 { // 07777=
  27494. prg.bad = 21
  27495. }
  27496. if formatDefaultLength > fileNameSize {
  27497. prg.bad = 31
  27498. }
  27499. if 2*65535 < 30000-memMin {
  27500. prg.bad = 41
  27501. }
  27502. if prg.bad > 0 {
  27503. prg.termOut.Writeln("Ouch---my internal constants have been clobbered!",
  27504. "---case ", prg.bad, knuth.WriteWidth(1))
  27505. // \xref[Ouch...clobbered]
  27506. // \xref[Ouch...clobbered]
  27507. goto finalEnd
  27508. }
  27509. prg.initialize() // set global variables to their starting values
  27510. if !prg.getStringsStarted() {
  27511. goto finalEnd
  27512. }
  27513. prg.initPrim() // call |primitive| for each primitive
  27514. prg.initStrPtr = prg.strPtr
  27515. prg.initPoolPtr = prg.poolPtr
  27516. prg.fixDateAndTime()
  27517. prg.readyAlready = 314159
  27518. startOfTex:
  27519. prg.selector = byte(termOnly)
  27520. prg.tally = 0
  27521. prg.termOffset = 0
  27522. prg.fileOffset = 0
  27523. prg.termOut.Write("This is TeX, Version 3.141592653 (gotex v0.0-prerelease)")
  27524. if int32(prg.formatIdent) == 0 {
  27525. prg.termOut.Writeln(" (no format preloaded)")
  27526. } else {
  27527. prg.slowPrint(int32(prg.formatIdent))
  27528. prg.printLn()
  27529. }
  27530. prg.jobName = 0
  27531. prg.nameInProgress = false
  27532. prg.logOpened = false
  27533. prg.outputFileName = 0
  27534. // Get the first line of input and prepare to start
  27535. {
  27536. {
  27537. prg.inputPtr = 0
  27538. prg.maxInStack = 0
  27539. prg.inOpen = 0
  27540. prg.openParens = 0
  27541. prg.maxBufStack = 0
  27542. prg.paramPtr = 0
  27543. prg.maxParamStack = 0
  27544. prg.first = uint16(bufSize)
  27545. for {
  27546. prg.buffer[prg.first] = 0
  27547. prg.first = uint16(int32(prg.first) - 1)
  27548. if int32(prg.first) == 0 {
  27549. break
  27550. }
  27551. }
  27552. prg.scannerStatus = byte(normal)
  27553. prg.warningIndex = 0
  27554. prg.first = 1
  27555. prg.curInput.stateField = byte(newLine)
  27556. prg.curInput.startField = 1
  27557. prg.curInput.indexField = 0
  27558. prg.line = 0
  27559. prg.curInput.nameField = 0
  27560. prg.forceEof = false
  27561. prg.alignState = 1000000
  27562. if !prg.initTerminal() {
  27563. goto finalEnd
  27564. }
  27565. prg.curInput.limitField = prg.last
  27566. prg.first = uint16(int32(prg.last) + 1) // |init_terminal| has set |loc| and |last|
  27567. }
  27568. if int32(prg.formatIdent) == 0 || int32(prg.buffer[prg.curInput.locField]) == '&' {
  27569. if int32(prg.formatIdent) != 0 {
  27570. prg.initialize()
  27571. } // erase preloaded format
  27572. if !prg.openFmtFile() {
  27573. goto finalEnd
  27574. }
  27575. if !prg.loadFmtFile() {
  27576. prg.wClose(prg.fmtFile)
  27577. goto finalEnd
  27578. }
  27579. prg.wClose(prg.fmtFile)
  27580. for int32(prg.curInput.locField) < int32(prg.curInput.limitField) && int32(prg.buffer[prg.curInput.locField]) == ' ' {
  27581. prg.curInput.locField = uint16(int32(prg.curInput.locField) + 1)
  27582. }
  27583. }
  27584. if *prg.eqtb[intBase+endLineCharCode-1].int() < 0 || *prg.eqtb[intBase+endLineCharCode-1].int() > 255 {
  27585. prg.curInput.limitField = uint16(int32(prg.curInput.limitField) - 1)
  27586. } else {
  27587. prg.buffer[prg.curInput.limitField] = byte(*prg.eqtb[intBase+endLineCharCode-1].int())
  27588. }
  27589. prg.fixDateAndTime()
  27590. // Compute the magic offset
  27591. prg.magicOffset = int32(prg.strStart[mathSpacing]) - 9*ordNoad
  27592. // Initialize the print |selector|...
  27593. if int32(prg.interaction) == batchMode {
  27594. prg.selector = byte(noPrint)
  27595. } else {
  27596. prg.selector = byte(termOnly)
  27597. }
  27598. if int32(prg.curInput.locField) < int32(prg.curInput.limitField) && int32(*(*prg.eqtb[catCodeBase+int32(prg.buffer[prg.curInput.locField])-1].hh()).rh()) != escape {
  27599. prg.startInput()
  27600. }
  27601. // \.[\\input] assumed
  27602. }
  27603. prg.history = byte(spotless) // ready to go!
  27604. prg.mainControl() // come to life
  27605. prg.finalCleanup() // prepare for death
  27606. prg.closeFilesAndTerminate()
  27607. finalEnd:
  27608. prg.readyAlready = 0
  27609. }
  27610. // 1340. \[53] Extensions
  27611. // tangle:pos tex.web:24529:17:
  27612. // The program above includes a bunch of ``hooks'' that allow further
  27613. // capabilities to be added without upsetting \TeX's basic structure.
  27614. // Most of these hooks are concerned with ``whatsit'' nodes, which are
  27615. // intended to be used for special purposes; whenever a new extension to
  27616. // \TeX\ involves a new kind of whatsit node, a corresponding change needs
  27617. // to be made to the routines below that deal with such nodes,
  27618. // but it will usually be unnecessary to make many changes to the
  27619. // other parts of this program.
  27620. //
  27621. // In order to demonstrate how extensions can be made, we shall treat
  27622. // `\.[\\write]', `\.[\\openout]', `\.[\\closeout]', `\.[\\immediate]',
  27623. // `\.[\\special]', and `\.[\\setlanguage]' as if they were extensions.
  27624. // These commands are actually primitives of \TeX, and they should
  27625. // appear in all implementations of the system; but let's try to imagine
  27626. // that they aren't. Then the program below illustrates how a person
  27627. // could add them.
  27628. //
  27629. // Sometimes, of course, an extension will require changes to \TeX\ itself;
  27630. // no system of hooks could be complete enough for all conceivable extensions.
  27631. // The features associated with `\.[\\write]' are almost all confined to the
  27632. // following paragraphs, but there are small parts of the |print_ln| and
  27633. // |print_char| procedures that were introduced specifically to \.[\\write]
  27634. // characters. Furthermore one of the token lists recognized by the scanner
  27635. // is a |write_text|; and there are a few other miscellaneous places where we
  27636. // have already provided for some aspect of \.[\\write]. The goal of a \TeX\
  27637. // extender should be to minimize alterations to the standard parts of the
  27638. // program, and to avoid them completely if possible. He or she should also
  27639. // be quite sure that there's no easy way to accomplish the desired goals
  27640. // with the standard features that \TeX\ already has. ``Think thrice before
  27641. // extending,'' because that may save a lot of work, and it will also keep
  27642. // incompatible extensions of \TeX\ from proliferating.
  27643. // \xref[system dependencies]
  27644. // \xref[extensions to \TeX]
  27645. // 1341.
  27646. // tangle:pos tex.web:24562:23:
  27647. // First let's consider the format of whatsit nodes that are used to represent
  27648. // the data associated with \.[\\write] and its relatives. Recall that a whatsit
  27649. // has |type=whatsit_node|, and the |subtype| is supposed to distinguish
  27650. // different kinds of whatsits. Each node occupies two or more words; the
  27651. // exact number is immaterial, as long as it is readily determined from the
  27652. // |subtype| or other data.
  27653. //
  27654. // We shall introduce five |subtype| values here, corresponding to the
  27655. // control sequences \.[\\openout], \.[\\write], \.[\\closeout], \.[\\special], and
  27656. // \.[\\setlanguage]. The second word of I/O whatsits has a |write_stream| field
  27657. // that identifies the write-stream number (0 to 15, or 16 for out-of-range and
  27658. // positive, or 17 for out-of-range and negative).
  27659. // In the case of \.[\\write] and \.[\\special], there is also a field that
  27660. // points to the reference count of a token list that should be sent. In the
  27661. // case of \.[\\openout], we need three words and three auxiliary subfields
  27662. // to hold the string numbers for name, area, and extension.
  27663. // 1379. \[54] System-dependent changes
  27664. // tangle:pos tex.web:24985:31:
  27665. // This section should be replaced, if necessary, by any special
  27666. // modifications of the program
  27667. // that are necessary to make \TeX\ work at a particular installation.
  27668. // It is usually best to design your change file so that all changes to
  27669. // previous sections preserve the section numbering; then everybody's version
  27670. // will be consistent with the published program. More extensive changes,
  27671. // which introduce new sections, can be inserted here; then only the index
  27672. // itself will get a new section number.
  27673. // \xref[system dependencies]
  27674. // 1380. \[55] Index
  27675. // tangle:pos tex.web:24996:12:
  27676. // Here is where you can find all uses of each identifier in the program,
  27677. // with underlined entries pointing to where the identifier was defined.
  27678. // If the identifier is only one letter long, however, you get to see only
  27679. // the underlined entries. [\sl All references are to section numbers instead of
  27680. // page numbers.]
  27681. //
  27682. // This index also lists error messages and other aspects of the program
  27683. // that you might want to look up some day. For example, the entry
  27684. // for ``system dependencies'' lists all sections that should receive
  27685. // special attention from people who are installing \TeX\ in a new
  27686. // operating environment. A list of various things that can't happen appears
  27687. // under ``this can't happen''. Approximately 40 sections are listed under
  27688. // ``inner loop''; these account for about 60\pct! of \TeX's running time,
  27689. // exclusive of input and output.