ebnf2ps.el 183 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398
  1. ;;; ebnf2ps.el --- translate an EBNF to a syntactic chart on PostScript
  2. ;; Copyright (C) 1999-2012 Free Software Foundation, Inc.
  3. ;; Author: Vinicius Jose Latorre <viniciusjl@ig.com.br>
  4. ;; Maintainer: Vinicius Jose Latorre <viniciusjl@ig.com.br>
  5. ;; Keywords: wp, ebnf, PostScript
  6. ;; Version: 4.4
  7. ;; X-URL: http://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
  8. ;; This file is part of GNU Emacs.
  9. ;; GNU Emacs is free software: you can redistribute it and/or modify
  10. ;; it under the terms of the GNU General Public License as published by
  11. ;; the Free Software Foundation, either version 3 of the License, or
  12. ;; (at your option) any later version.
  13. ;; GNU Emacs is distributed in the hope that it will be useful,
  14. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. ;; GNU General Public License for more details.
  17. ;; You should have received a copy of the GNU General Public License
  18. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  19. (defconst ebnf-version "4.4"
  20. "ebnf2ps.el, v 4.4 <2007/02/12 vinicius>
  21. Vinicius's last change version. When reporting bugs, please also
  22. report the version of Emacs, if any, that ebnf2ps was running with.
  23. Please send all bug fixes and enhancements to
  24. Vinicius Jose Latorre <viniciusjl@ig.com.br>.
  25. ")
  26. ;;; Commentary:
  27. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  28. ;;
  29. ;; Introduction
  30. ;; ------------
  31. ;;
  32. ;; This package translates an EBNF to a syntactic chart on PostScript.
  33. ;;
  34. ;; To use ebnf2ps, insert in your ~/.emacs:
  35. ;;
  36. ;; (require 'ebnf2ps)
  37. ;;
  38. ;; ebnf2ps uses ps-print package (version 5.2.3 or later), so see ps-print to
  39. ;; know how to set options like landscape printing, page headings, margins,
  40. ;; etc.
  41. ;;
  42. ;; NOTE: ps-print zebra stripes and line number options doesn't have effect on
  43. ;; ebnf2ps, they behave as it's turned off.
  44. ;;
  45. ;; For good performance, be sure to byte-compile ebnf2ps.el, e.g.
  46. ;;
  47. ;; M-x byte-compile-file <give the path to ebnf2ps.el when prompted>
  48. ;;
  49. ;; This will generate ebnf2ps.elc, which will be loaded instead of ebnf2ps.el.
  50. ;;
  51. ;; ebnf2ps was tested with GNU Emacs 20.4.1.
  52. ;;
  53. ;;
  54. ;; Using ebnf2ps
  55. ;; -------------
  56. ;;
  57. ;; ebnf2ps provides the following commands for generating PostScript syntactic
  58. ;; chart images of Emacs buffers:
  59. ;;
  60. ;; ebnf-print-directory
  61. ;; ebnf-print-file
  62. ;; ebnf-print-buffer
  63. ;; ebnf-print-region
  64. ;; ebnf-spool-directory
  65. ;; ebnf-spool-file
  66. ;; ebnf-spool-buffer
  67. ;; ebnf-spool-region
  68. ;; ebnf-eps-directory
  69. ;; ebnf-eps-file
  70. ;; ebnf-eps-buffer
  71. ;; ebnf-eps-region
  72. ;;
  73. ;; These commands all perform essentially the same function: they generate
  74. ;; PostScript syntactic chart images suitable for printing on a PostScript
  75. ;; printer or displaying with GhostScript. These commands are collectively
  76. ;; referred to as "ebnf- commands".
  77. ;;
  78. ;; The word "print", "spool" and "eps" in the command name determines when the
  79. ;; PostScript image is sent to the printer (or file):
  80. ;;
  81. ;; print - The PostScript image is immediately sent to the printer;
  82. ;;
  83. ;; spool - The PostScript image is saved temporarily in an Emacs buffer.
  84. ;; Many images may be spooled locally before printing them. To
  85. ;; send the spooled images to the printer, use the command
  86. ;; `ebnf-despool'.
  87. ;;
  88. ;; eps - The PostScript image is immediately sent to an EPS file.
  89. ;;
  90. ;; The spooling mechanism is the same as used by ps-print and was designed for
  91. ;; printing lots of small files to save paper that would otherwise be wasted on
  92. ;; banner pages, and to make it easier to find your output at the printer (it's
  93. ;; easier to pick up one 50-page printout than to find 50 single-page
  94. ;; printouts). As ebnf2ps and ps-print use the same Emacs buffer to spool
  95. ;; images, you can intermix the spooling of ebnf2ps and ps-print images.
  96. ;;
  97. ;; ebnf2ps use the same hook of ps-print in the `kill-emacs-hook' so that you
  98. ;; won't accidentally quit from Emacs while you have unprinted PostScript
  99. ;; waiting in the spool buffer. If you do attempt to exit with spooled
  100. ;; PostScript, you'll be asked if you want to print it, and if you decline,
  101. ;; you'll be asked to confirm the exit; this is modeled on the confirmation
  102. ;; that Emacs uses for modified buffers.
  103. ;;
  104. ;; The word "directory", "file", "buffer" or "region" in the command name
  105. ;; determines how much of the buffer is printed:
  106. ;;
  107. ;; directory - Read files in the directory and print them.
  108. ;;
  109. ;; file - Read file and print it.
  110. ;;
  111. ;; buffer - Print the entire buffer.
  112. ;;
  113. ;; region - Print just the current region.
  114. ;;
  115. ;; Two ebnf- command examples:
  116. ;;
  117. ;; ebnf-print-buffer - translate and print the entire buffer, and send it
  118. ;; immediately to the printer.
  119. ;;
  120. ;; ebnf-spool-region - translate and print just the current region, and
  121. ;; spool the image in Emacs to send to the printer
  122. ;; later.
  123. ;;
  124. ;; Note that `ebnf-eps-directory', `ebnf-eps-file', `ebnf-eps-buffer' and
  125. ;; `ebnf-eps-region' never spool the EPS image, so they don't use the ps-print
  126. ;; spooling mechanism. See section "Actions in Comments" for an explanation
  127. ;; about EPS file generation.
  128. ;;
  129. ;;
  130. ;; Invoking Ebnf2ps
  131. ;; ----------------
  132. ;;
  133. ;; To translate and print your buffer, type
  134. ;;
  135. ;; M-x ebnf-print-buffer
  136. ;;
  137. ;; or substitute one of the other four ebnf- commands. The command will
  138. ;; generate the PostScript image and print or spool it as specified. By giving
  139. ;; the command a prefix argument
  140. ;;
  141. ;; C-u M-x ebnf-print-buffer
  142. ;;
  143. ;; it will save the PostScript image to a file instead of sending it to the
  144. ;; printer; you will be prompted for the name of the file to save the image to.
  145. ;; The prefix argument is ignored by the commands that spool their images, but
  146. ;; you may save the spooled images to a file by giving a prefix argument to
  147. ;; `ebnf-despool':
  148. ;;
  149. ;; C-u M-x ebnf-despool
  150. ;;
  151. ;; When invoked this way, `ebnf-despool' will prompt you for the name of the
  152. ;; file to save to.
  153. ;;
  154. ;; The prefix argument is also ignored by `ebnf-eps-buffer' and
  155. ;; `ebnf-eps-region'.
  156. ;;
  157. ;; Any of the `ebnf-' commands can be bound to keys. Here are some examples:
  158. ;;
  159. ;; (global-set-key 'f22 'ebnf-print-buffer) ;f22 is prsc
  160. ;; (global-set-key '(shift f22) 'ebnf-print-region)
  161. ;; (global-set-key '(control f22) 'ebnf-despool)
  162. ;;
  163. ;;
  164. ;; Invoking Ebnf2ps in Batch
  165. ;; -------------------------
  166. ;;
  167. ;; It's possible also to run ebnf2ps in batch, this is useful when, for
  168. ;; example, you have a directory with a lot of files containing the EBNF to be
  169. ;; translated to PostScript.
  170. ;;
  171. ;; To run ebnf2ps in batch type, for example:
  172. ;;
  173. ;; emacs -batch -l setup-ebnf2ps.el -f ebnf-eps-directory
  174. ;;
  175. ;; Where setup-ebnf2ps.el should be a file containing:
  176. ;;
  177. ;; ;; set load-path if ebnf2ps isn't installed in your Emacs environment
  178. ;; (setq load-path (append (list "/dir/of/ebnf2ps") load-path))
  179. ;; (require 'ebnf2ps)
  180. ;; ;; insert here your ebnf2ps settings
  181. ;; (setq ebnf-terminal-shape 'bevel)
  182. ;; ;; etc.
  183. ;;
  184. ;;
  185. ;; EBNF Syntax
  186. ;; -----------
  187. ;;
  188. ;; BNF (Backus Naur Form) notation is defined like languages, and like
  189. ;; languages there are rules about name formation and syntax. In this section
  190. ;; it's defined a BNF syntax that it's called simply EBNF (Extended BNF).
  191. ;; ebnf2ps package also deal with other BNF notation. Please, see the variable
  192. ;; `ebnf-syntax' documentation below in this section.
  193. ;;
  194. ;; The current EBNF that ebnf2ps accepts has the following constructions:
  195. ;;
  196. ;; ; comment (until end of line)
  197. ;; A non-terminal
  198. ;; "C" terminal
  199. ;; ?C? special
  200. ;; $A default non-terminal (see text below)
  201. ;; $"C" default terminal (see text below)
  202. ;; $?C? default special (see text below)
  203. ;; A = B. production (A is the header and B the body)
  204. ;; C D sequence (C occurs before D)
  205. ;; C | D alternative (C or D occurs)
  206. ;; A - B exception (A excluding B, B without any non-terminal)
  207. ;; n * A repetition (A repeats at least n (integer) times)
  208. ;; n * n A repetition (A repeats exactly n (integer) times)
  209. ;; n * m A repetition (A repeats at least n (integer) and at most
  210. ;; m (integer) times)
  211. ;; (C) group (expression C is grouped together)
  212. ;; [C] optional (C may or not occurs)
  213. ;; C+ one or more occurrences of C
  214. ;; {C}+ one or more occurrences of C
  215. ;; {C}* zero or more occurrences of C
  216. ;; {C} zero or more occurrences of C
  217. ;; C / D equivalent to: C {D C}*
  218. ;; {C || D}+ equivalent to: C {D C}*
  219. ;; {C || D}* equivalent to: [C {D C}*]
  220. ;; {C || D} equivalent to: [C {D C}*]
  221. ;;
  222. ;; The EBNF syntax written using the notation above is:
  223. ;;
  224. ;; EBNF = {production}+.
  225. ;;
  226. ;; production = non_terminal "=" body ".". ;; production
  227. ;;
  228. ;; body = {sequence || "|"}*. ;; alternative
  229. ;;
  230. ;; sequence = {exception}*. ;; sequence
  231. ;;
  232. ;; exception = repeat [ "-" repeat]. ;; exception
  233. ;;
  234. ;; repeat = [ integer "*" [ integer ]] term. ;; repetition
  235. ;;
  236. ;; term = factor
  237. ;; | [factor] "+" ;; one-or-more
  238. ;; | [factor] "/" [factor] ;; one-or-more
  239. ;; .
  240. ;;
  241. ;; factor = [ "$" ] "\"" terminal "\"" ;; terminal
  242. ;; | [ "$" ] non_terminal ;; non-terminal
  243. ;; | [ "$" ] "?" special "?" ;; special
  244. ;; | "(" body ")" ;; group
  245. ;; | "[" body "]" ;; zero-or-one
  246. ;; | "{" body [ "||" body ] "}+" ;; one-or-more
  247. ;; | "{" body [ "||" body ] "}*" ;; zero-or-more
  248. ;; | "{" body [ "||" body ] "}" ;; zero-or-more
  249. ;; .
  250. ;;
  251. ;; non_terminal = "[!#%&'*-,0-:<>@-Z\\\\^-z~\\240-\\377]+".
  252. ;; ;; that is, a valid non_terminal accepts decimal digits, letters (upper
  253. ;; ;; and lower), 8-bit accentuated characters,
  254. ;; ;; "!", "#", "%", "&", "'", "*", "+", ",", ":",
  255. ;; ;; "<", ">", "@", "\", "^", "_", "`" and "~".
  256. ;;
  257. ;; terminal = "\\([^\"\\]\\|\\\\[ -~\\240-\\377]\\)+".
  258. ;; ;; that is, a valid terminal accepts any printable character (including
  259. ;; ;; 8-bit accentuated characters) except `"', as `"' is used to delimit a
  260. ;; ;; terminal. Also, accepts escaped characters, that is, a character
  261. ;; ;; pair starting with `\' followed by a printable character, for
  262. ;; ;; example: \", \\.
  263. ;;
  264. ;; special = "[^?\\000-\\010\\012-\\037\\177-\\237]*".
  265. ;; ;; that is, a valid special accepts any printable character (including
  266. ;; ;; 8-bit accentuated characters) and tabs except `?', as `?' is used to
  267. ;; ;; delimit a special.
  268. ;;
  269. ;; integer = "[0-9]+".
  270. ;; ;; that is, an integer is a sequence of one or more decimal digits.
  271. ;;
  272. ;; comment = ";" "[^\\n\\000-\\010\\016-\\037\\177-\\237]*" "\\n".
  273. ;; ;; that is, a comment starts with the character `;' and terminates at end
  274. ;; ;; of line. Also, it only accepts printable characters (including 8-bit
  275. ;; ;; accentuated characters) and tabs.
  276. ;;
  277. ;; Try to use the above EBNF to test ebnf2ps.
  278. ;;
  279. ;; The `default' terminal, non-terminal and special is a way to indicate a
  280. ;; default path in a production. For example, the production:
  281. ;;
  282. ;; X = [ $A ( B | $C ) | D ].
  283. ;;
  284. ;; Indicates that the default meaning for "X" is "A C" if "X" is empty.
  285. ;;
  286. ;; The terminal name is controlled by `ebnf-terminal-regexp' and
  287. ;; `ebnf-case-fold-search', so it's possible to match other kind of terminal
  288. ;; name besides that enclosed by `"'.
  289. ;;
  290. ;; Let's see an example:
  291. ;;
  292. ;; (setq ebnf-terminal-regexp "[A-Z][_A-Z]*") ; upper case name
  293. ;; (setq ebnf-case-fold-search nil) ; exact matching
  294. ;;
  295. ;; If you have the production:
  296. ;;
  297. ;; Logical = "(" Expression ( OR | AND | "XOR" ) Expression ")".
  298. ;;
  299. ;; The names are classified as:
  300. ;;
  301. ;; Logical Expression non-terminal
  302. ;; "(" OR AND "XOR" ")" terminal
  303. ;;
  304. ;; The line comment is controlled by `ebnf-lex-comment-char'. The default
  305. ;; value is ?\; (character `;').
  306. ;;
  307. ;; The end of production is controlled by `ebnf-lex-eop-char'. The default
  308. ;; value is ?. (character `.').
  309. ;;
  310. ;; The variable `ebnf-syntax' specifies which syntax to recognize:
  311. ;;
  312. ;; `ebnf' ebnf2ps recognizes the syntax described above.
  313. ;; The following variables *ONLY* have effect with this
  314. ;; setting:
  315. ;; `ebnf-terminal-regexp', `ebnf-case-fold-search',
  316. ;; `ebnf-lex-comment-char' and `ebnf-lex-eop-char'.
  317. ;;
  318. ;; `abnf' ebnf2ps recognizes the syntax described in the URL:
  319. ;; `http://www.ietf.org/rfc/rfc2234.txt'
  320. ;; ("Augmented BNF for Syntax Specifications: ABNF").
  321. ;;
  322. ;; `iso-ebnf' ebnf2ps recognizes the syntax described in the URL:
  323. ;; `http://www.cl.cam.ac.uk/~mgk25/iso-ebnf.html'
  324. ;; ("International Standard of the ISO EBNF Notation").
  325. ;; The following variables *ONLY* have effect with this
  326. ;; setting:
  327. ;; `ebnf-iso-alternative-p' and `ebnf-iso-normalize-p'.
  328. ;;
  329. ;; `yacc' ebnf2ps recognizes the Yacc/Bison syntax.
  330. ;; The following variable *ONLY* has effect with this
  331. ;; setting:
  332. ;; `ebnf-yac-ignore-error-recovery'.
  333. ;;
  334. ;; `ebnfx' ebnf2ps recognizes the syntax described in the URL:
  335. ;; `http://www.w3.org/TR/2004/REC-xml-20040204/#sec-notation'
  336. ;; ("Extensible Markup Language (XML) 1.0 (Third Edition)")
  337. ;;
  338. ;; `dtd' ebnf2ps recognizes the syntax described in the URL:
  339. ;; `http://www.w3.org/TR/2004/REC-xml-20040204/'
  340. ;; ("Extensible Markup Language (XML) 1.0 (Third Edition)")
  341. ;;
  342. ;; Any other value is treated as `ebnf'.
  343. ;;
  344. ;; The default value is `ebnf'.
  345. ;;
  346. ;;
  347. ;; Optimizations
  348. ;; -------------
  349. ;;
  350. ;; The following EBNF optimizations are done:
  351. ;;
  352. ;; [ { A }* ] ==> { A }*
  353. ;; [ { A }+ ] ==> { A }*
  354. ;; [ A ] + ==> { A }*
  355. ;; { A }* + ==> { A }*
  356. ;; { A }+ + ==> { A }+
  357. ;; { A }- ==> { A }+
  358. ;; [ A ]- ==> A
  359. ;; ( A | EMPTY )- ==> A
  360. ;; ( A | B | EMPTY )- ==> A | B
  361. ;; [ A | B ] ==> A | B | EMPTY
  362. ;; n * EMPTY ==> EMPTY
  363. ;; EMPTY + ==> EMPTY
  364. ;; EMPTY / EMPTY ==> EMPTY
  365. ;; EMPTY - A ==> EMPTY
  366. ;;
  367. ;; The following optimizations are done when `ebnf-optimize' is non-nil:
  368. ;;
  369. ;; left recursion:
  370. ;; 1. A = B | A C. ==> A = B {C}*.
  371. ;; 2. A = B | A B. ==> A = {B}+.
  372. ;; 3. A = | A B. ==> A = {B}*.
  373. ;; 4. A = B | A C B. ==> A = {B || C}+.
  374. ;; 5. A = B | D | A C | A E. ==> A = ( B | D ) { C | E }*.
  375. ;;
  376. ;; optional:
  377. ;; 6. A = B | . ==> A = [B].
  378. ;; 7. A = | B . ==> A = [B].
  379. ;;
  380. ;; factorization:
  381. ;; 8. A = B C | B D. ==> A = B (C | D).
  382. ;; 9. A = C B | D B. ==> A = (C | D) B.
  383. ;; 10. A = B C E | B D E. ==> A = B (C | D) E.
  384. ;;
  385. ;; The above optimizations are specially useful when `ebnf-syntax' is `yacc'.
  386. ;;
  387. ;;
  388. ;; Form Feed
  389. ;; ---------
  390. ;;
  391. ;; You may use form feed (^L \014) to force a production to start on a new
  392. ;; page, for example:
  393. ;;
  394. ;; a) A = B | C.
  395. ;; ^L
  396. ;; X = Y | Z.
  397. ;;
  398. ;; b) A = B ^L | C.
  399. ;; X = Y | Z.
  400. ;;
  401. ;; c) A = B ^L^L^L | C.^L
  402. ;; ^L
  403. ;; X = Y | Z.
  404. ;;
  405. ;; In all examples above, only the production X will start on a new page.
  406. ;;
  407. ;;
  408. ;; Actions in Comments
  409. ;; -------------------
  410. ;;
  411. ;; ebnf2ps accepts the following actions in comments:
  412. ;;
  413. ;; ;^ same as form feed. See section Form Feed above.
  414. ;;
  415. ;; ;> the next production starts in the same line as the current one.
  416. ;; It is useful when `ebnf-horizontal-orientation' is nil.
  417. ;;
  418. ;; ;< the next production starts in the next line.
  419. ;; It is useful when `ebnf-horizontal-orientation' is non-nil.
  420. ;;
  421. ;; ;[EPS open a new EPS file. The EPS file name has the form:
  422. ;; <PREFIX><NAME>.eps
  423. ;; where <PREFIX> is given by variable `ebnf-eps-prefix' and
  424. ;; <NAME> is the string given by ;[ action comment, this string is
  425. ;; mapped to form a valid file name (see documentation for
  426. ;; `ebnf-eps-buffer' or `ebnf-eps-region').
  427. ;; It has effect only during `ebnf-eps-buffer' or
  428. ;; `ebnf-eps-region' execution.
  429. ;; It's an error to try to open an already opened EPS file.
  430. ;;
  431. ;; ;]EPS close an opened EPS file.
  432. ;; It has effect only during `ebnf-eps-buffer' or
  433. ;; `ebnf-eps-region' execution.
  434. ;; It's an error to try to close a not opened EPS file.
  435. ;;
  436. ;; ;Hheader generate a header in current EPS file. The header string can
  437. ;; have the following formats:
  438. ;;
  439. ;; %% prints a % character.
  440. ;;
  441. ;; %H prints the `ebnf-eps-header' (which see) value.
  442. ;;
  443. ;; %F prints the `ebnf-eps-footer' (which see) value.
  444. ;;
  445. ;; Any other format is ignored, that is, if, for example, it's
  446. ;; used %s then %s characters are stripped out from the header.
  447. ;; If header is an empty string, no header is generated until a
  448. ;; non-empty header is specified or `ebnf-eps-header' has a
  449. ;; non-empty string value.
  450. ;;
  451. ;; ;Ffooter generate a footer in current EPS file. Similar to ;H action
  452. ;; comment.
  453. ;;
  454. ;; So if you have:
  455. ;;
  456. ;; (setq ebnf-horizontal-orientation nil)
  457. ;;
  458. ;; A = t.
  459. ;; C = x.
  460. ;; ;> C and B are drawn in the same line
  461. ;; B = y.
  462. ;; W = v.
  463. ;;
  464. ;; The graphical result is:
  465. ;;
  466. ;; +---+
  467. ;; | A |
  468. ;; +---+
  469. ;;
  470. ;; +---------+ +-----+
  471. ;; | | | |
  472. ;; | C | | |
  473. ;; | | | B |
  474. ;; +---------+ | |
  475. ;; | |
  476. ;; +-----+
  477. ;;
  478. ;; +-----------+
  479. ;; | W |
  480. ;; +-----------+
  481. ;;
  482. ;; Note that if ascending production sort is used, the productions A and B will
  483. ;; be drawn in the same line instead of C and B.
  484. ;;
  485. ;; If consecutive actions occur, only the last one takes effect, so if you
  486. ;; have:
  487. ;;
  488. ;; A = X.
  489. ;; ;<
  490. ;; ^L
  491. ;; ;>
  492. ;; B = Y.
  493. ;;
  494. ;; Only the ;> will take effect, that is, A and B will be drawn in the same
  495. ;; line.
  496. ;;
  497. ;; In ISO EBNF the above actions are specified as (*^*), (*>*), (*<*), (*[EPS*)
  498. ;; and (*]EPS*). The first example above should be written:
  499. ;;
  500. ;; A = t;
  501. ;; C = x;
  502. ;; (*> C and B are drawn in the same line *)
  503. ;; B = y;
  504. ;; W = v;
  505. ;;
  506. ;; For an example of EPS action when executing `ebnf-eps-buffer' or
  507. ;; `ebnf-eps-region':
  508. ;;
  509. ;; Z = B0.
  510. ;; ;[CC
  511. ;; ;[AA
  512. ;; A = B1.
  513. ;; ;[BB
  514. ;; C = B2.
  515. ;; ;]AA
  516. ;; B = B3.
  517. ;; ;]BB
  518. ;; ;]CC
  519. ;; D = B4.
  520. ;; E = B5.
  521. ;; ;[CC
  522. ;; F = B6.
  523. ;; ;]CC
  524. ;; G = B7.
  525. ;;
  526. ;; The following table summarizes the results:
  527. ;;
  528. ;; EPS FILE NAME NO SORT ASCENDING SORT DESCENDING SORT
  529. ;; ebnf--AA.eps A C A C C A
  530. ;; ebnf--BB.eps C B B C C B
  531. ;; ebnf--CC.eps A C B F A B C F F C B A
  532. ;; ebnf--D.eps D D D
  533. ;; ebnf--E.eps E E E
  534. ;; ebnf--G.eps G G G
  535. ;; ebnf--Z.eps Z Z Z
  536. ;;
  537. ;; As you can see if EPS actions is not used, each single production is
  538. ;; generated per EPS file. To avoid overriding EPS files, use names in ;[ that
  539. ;; it's not an existing production name.
  540. ;;
  541. ;; In the following case:
  542. ;;
  543. ;; A = B0.
  544. ;; ;[AA
  545. ;; A = B1.
  546. ;; ;[BB
  547. ;; A = B2.
  548. ;;
  549. ;; The production A is generated in both files ebnf--AA.eps and ebnf--BB.eps.
  550. ;;
  551. ;;
  552. ;; Log Messages
  553. ;; ------------
  554. ;;
  555. ;; The buffer *Ebnf2ps Log* is where the ebnf2ps log messages are inserted.
  556. ;; These messages are intended to help debugging ebnf2ps.
  557. ;;
  558. ;; The log messages are enabled by `ebnf-log' option (which see). The default
  559. ;; value is nil, that is, no log messages are generated.
  560. ;;
  561. ;;
  562. ;; Utilities
  563. ;; ---------
  564. ;;
  565. ;; Some tools are provided to help you.
  566. ;;
  567. ;; `ebnf-setup' returns the current setup.
  568. ;;
  569. ;; `ebnf-syntax-directory' does a syntactic analysis of your EBNF files in the
  570. ;; given directory.
  571. ;;
  572. ;; `ebnf-syntax-file' does a syntactic analysis of your EBNF in the given
  573. ;; file.
  574. ;;
  575. ;; `ebnf-syntax-buffer' does a syntactic analysis of your EBNF in the current
  576. ;; buffer.
  577. ;;
  578. ;; `ebnf-syntax-region' does a syntactic analysis of your EBNF in the current
  579. ;; region.
  580. ;;
  581. ;; `ebnf-customize' activates a customization buffer for ebnf2ps options.
  582. ;;
  583. ;; `ebnf-syntax-directory', `ebnf-syntax-file', `ebnf-syntax-buffer',
  584. ;; `ebnf-syntax-region' and `ebnf-customize' can be bound to keys in the same
  585. ;; way as `ebnf-' commands.
  586. ;;
  587. ;;
  588. ;; Hooks
  589. ;; -----
  590. ;;
  591. ;; ebn2ps has the following hook variables:
  592. ;;
  593. ;; `ebnf-hook'
  594. ;; It is evaluated once before any ebnf2ps process.
  595. ;;
  596. ;; `ebnf-production-hook'
  597. ;; It is evaluated on each beginning of production.
  598. ;;
  599. ;; `ebnf-page-hook'
  600. ;; It is evaluated on each beginning of page.
  601. ;;
  602. ;;
  603. ;; Options
  604. ;; -------
  605. ;;
  606. ;; Below it's shown a brief description of ebnf2ps options, please, see the
  607. ;; options declaration in the code for a long documentation.
  608. ;;
  609. ;; `ebnf-horizontal-orientation' Non-nil means productions are drawn
  610. ;; horizontally.
  611. ;;
  612. ;; `ebnf-horizontal-max-height' Non-nil means to use maximum production
  613. ;; height in horizontal orientation.
  614. ;;
  615. ;; `ebnf-production-horizontal-space' Specify horizontal space in points
  616. ;; between productions.
  617. ;;
  618. ;; `ebnf-production-vertical-space' Specify vertical space in points
  619. ;; between productions.
  620. ;;
  621. ;; `ebnf-justify-sequence' Specify justification of terms in a
  622. ;; sequence inside alternatives.
  623. ;;
  624. ;; `ebnf-terminal-regexp' Specify how it's a terminal name.
  625. ;;
  626. ;; `ebnf-case-fold-search' Non-nil means ignore case on matching.
  627. ;;
  628. ;; `ebnf-terminal-font' Specify terminal font.
  629. ;;
  630. ;; `ebnf-terminal-shape' Specify terminal box shape.
  631. ;;
  632. ;; `ebnf-terminal-shadow' Non-nil means terminal box will have a
  633. ;; shadow.
  634. ;;
  635. ;; `ebnf-terminal-border-width' Specify border width for terminal box.
  636. ;;
  637. ;; `ebnf-terminal-border-color' Specify border color for terminal box.
  638. ;;
  639. ;; `ebnf-production-name-p' Non-nil means production name will be
  640. ;; printed.
  641. ;;
  642. ;; `ebnf-sort-production' Specify how productions are sorted.
  643. ;;
  644. ;; `ebnf-production-font' Specify production font.
  645. ;;
  646. ;; `ebnf-non-terminal-font' Specify non-terminal font.
  647. ;;
  648. ;; `ebnf-non-terminal-shape' Specify non-terminal box shape.
  649. ;;
  650. ;; `ebnf-non-terminal-shadow' Non-nil means non-terminal box will
  651. ;; have a shadow.
  652. ;;
  653. ;; `ebnf-non-terminal-border-width' Specify border width for non-terminal
  654. ;; box.
  655. ;;
  656. ;; `ebnf-non-terminal-border-color' Specify border color for non-terminal
  657. ;; box.
  658. ;;
  659. ;; `ebnf-special-show-delimiter' Non-nil means special delimiter
  660. ;; (character `?') is shown.
  661. ;;
  662. ;; `ebnf-special-font' Specify special font.
  663. ;;
  664. ;; `ebnf-special-shape' Specify special box shape.
  665. ;;
  666. ;; `ebnf-special-shadow' Non-nil means special box will have a
  667. ;; shadow.
  668. ;;
  669. ;; `ebnf-special-border-width' Specify border width for special box.
  670. ;;
  671. ;; `ebnf-special-border-color' Specify border color for special box.
  672. ;;
  673. ;; `ebnf-except-font' Specify except font.
  674. ;;
  675. ;; `ebnf-except-shape' Specify except box shape.
  676. ;;
  677. ;; `ebnf-except-shadow' Non-nil means except box will have a
  678. ;; shadow.
  679. ;;
  680. ;; `ebnf-except-border-width' Specify border width for except box.
  681. ;;
  682. ;; `ebnf-except-border-color' Specify border color for except box.
  683. ;;
  684. ;; `ebnf-repeat-font' Specify repeat font.
  685. ;;
  686. ;; `ebnf-repeat-shape' Specify repeat box shape.
  687. ;;
  688. ;; `ebnf-repeat-shadow' Non-nil means repeat box will have a
  689. ;; shadow.
  690. ;;
  691. ;; `ebnf-repeat-border-width' Specify border width for repeat box.
  692. ;;
  693. ;; `ebnf-repeat-border-color' Specify border color for repeat box.
  694. ;;
  695. ;; `ebnf-entry-percentage' Specify entry height on alternatives.
  696. ;;
  697. ;; `ebnf-arrow-shape' Specify the arrow shape.
  698. ;;
  699. ;; `ebnf-chart-shape' Specify chart flow shape.
  700. ;;
  701. ;; `ebnf-color-p' Non-nil means use color.
  702. ;;
  703. ;; `ebnf-line-width' Specify flow line width.
  704. ;;
  705. ;; `ebnf-line-color' Specify flow line color.
  706. ;;
  707. ;; `ebnf-arrow-extra-width' Specify extra width for arrow shape
  708. ;; drawing.
  709. ;;
  710. ;; `ebnf-arrow-scale' Specify the arrow scale.
  711. ;;
  712. ;; `ebnf-user-arrow' Specify a sexp for user arrow shape (a
  713. ;; PostScript code).
  714. ;;
  715. ;; `ebnf-debug-ps' Non-nil means to generate PostScript
  716. ;; debug procedures.
  717. ;;
  718. ;; `ebnf-lex-comment-char' Specify the line comment character.
  719. ;;
  720. ;; `ebnf-lex-eop-char' Specify the end of production
  721. ;; character.
  722. ;;
  723. ;; `ebnf-syntax' Specify syntax to be recognized.
  724. ;;
  725. ;; `ebnf-iso-alternative-p' Non-nil means use alternative ISO EBNF.
  726. ;;
  727. ;; `ebnf-iso-normalize-p' Non-nil means normalize ISO EBNF syntax
  728. ;; names.
  729. ;;
  730. ;; `ebnf-default-width' Specify additional border width over
  731. ;; default terminal, non-terminal or
  732. ;; special.
  733. ;;
  734. ;; `ebnf-file-suffix-regexp' Specify file name suffix that contains
  735. ;; EBNF.
  736. ;;
  737. ;; `ebnf-eps-prefix' Specify EPS prefix file name.
  738. ;;
  739. ;; `ebnf-eps-header-font' Specify EPS header font.
  740. ;;
  741. ;; `ebnf-eps-header' Specify EPS header.
  742. ;;
  743. ;; `ebnf-eps-footer-font' Specify EPS footer font.
  744. ;;
  745. ;; `ebnf-eps-footer' Specify EPS footer.
  746. ;;
  747. ;; `ebnf-use-float-format' Non-nil means use `%f' float format.
  748. ;;
  749. ;; `ebnf-stop-on-error' Non-nil means signal error and stop.
  750. ;; Nil means signal error and continue.
  751. ;;
  752. ;; `ebnf-yac-ignore-error-recovery' Non-nil means ignore error recovery.
  753. ;;
  754. ;; `ebnf-ignore-empty-rule' Non-nil means ignore empty rules.
  755. ;;
  756. ;; `ebnf-optimize' Non-nil means optimize syntactic chart
  757. ;; of rules.
  758. ;;
  759. ;; `ebnf-log' Non-nil means generate log messages.
  760. ;;
  761. ;; To set the above options you may:
  762. ;;
  763. ;; a) insert the code in your ~/.emacs, like:
  764. ;;
  765. ;; (setq ebnf-terminal-shape 'bevel)
  766. ;;
  767. ;; This way always keep your default settings when you enter a new Emacs
  768. ;; session.
  769. ;;
  770. ;; b) or use `set-variable' in your Emacs session, like:
  771. ;;
  772. ;; M-x set-variable RET ebnf-terminal-shape RET bevel RET
  773. ;;
  774. ;; This way keep your settings only during the current Emacs session.
  775. ;;
  776. ;; c) or use customization, for example:
  777. ;; click on menu-bar *Help* option,
  778. ;; then click on *Customize*,
  779. ;; then click on *Browse Customization Groups*,
  780. ;; expand *PostScript* group,
  781. ;; expand *Ebnf2ps* group
  782. ;; and then customize ebnf2ps options.
  783. ;; Through this way, you may choose if the settings are kept or not when
  784. ;; you leave out the current Emacs session.
  785. ;;
  786. ;; d) or see the option value:
  787. ;;
  788. ;; C-h v ebnf-terminal-shape RET
  789. ;;
  790. ;; and click the *customize* hypertext button.
  791. ;; Through this way, you may choose if the settings are kept or not when
  792. ;; you leave out the current Emacs session.
  793. ;;
  794. ;; e) or invoke:
  795. ;;
  796. ;; M-x ebnf-customize RET
  797. ;;
  798. ;; and then customize ebnf2ps options.
  799. ;; Through this way, you may choose if the settings are kept or not when
  800. ;; you leave out the current Emacs session.
  801. ;;
  802. ;;
  803. ;; Styles
  804. ;; ------
  805. ;;
  806. ;; Sometimes you need to change the EBNF style you are using, for example,
  807. ;; change the shapes and colors. These changes may force you to set some
  808. ;; variables and after use, set back the variables to the old values.
  809. ;;
  810. ;; To help to handle this situation, ebnf2ps has the following commands to
  811. ;; handle styles:
  812. ;;
  813. ;; `ebnf-find-style' Return style definition if NAME is already defined;
  814. ;; otherwise, return nil.
  815. ;;
  816. ;; `ebnf-insert-style' Insert a new style NAME with inheritance INHERITS and
  817. ;; values VALUES.
  818. ;;
  819. ;; `ebnf-delete-style' Delete style NAME.
  820. ;;
  821. ;; `ebnf-merge-style' Merge values of style NAME with style VALUES.
  822. ;;
  823. ;; `ebnf-apply-style' Set STYLE as the current style.
  824. ;;
  825. ;; `ebnf-reset-style' Reset current style.
  826. ;;
  827. ;; `ebnf-push-style' Push the current style and set STYLE as the current
  828. ;; style.
  829. ;;
  830. ;; `ebnf-pop-style' Pop a style and set it as the current style.
  831. ;;
  832. ;; These commands help to put together a lot of variable settings in a group
  833. ;; and name this group. So when you wish to apply these settings it's only
  834. ;; needed to give the name.
  835. ;;
  836. ;; There is also a notion of simple inheritance of style: if you declare that
  837. ;; style A inherits from style B, all settings of B are applied first and then
  838. ;; the settings of A are applied. This is useful when you wish to modify some
  839. ;; aspects of an existing style, but at same time wish to keep it unmodified.
  840. ;;
  841. ;; See documentation for `ebnf-style-database'.
  842. ;;
  843. ;;
  844. ;; Layout
  845. ;; ------
  846. ;;
  847. ;; Below it is the layout of minimum area to draw each element, and it's used
  848. ;; the following terms:
  849. ;;
  850. ;; font height is given by:
  851. ;; (terminal font height + non-terminal font height) / 2
  852. ;;
  853. ;; entry is the vertical position used to know where it should
  854. ;; be drawn the flow line in the current element.
  855. ;;
  856. ;; extra is given by `ebnf-arrow-extra-width'.
  857. ;;
  858. ;;
  859. ;; * SPECIAL, TERMINAL and NON-TERMINAL
  860. ;;
  861. ;; +==============+...................................
  862. ;; | | } font height / 2 } entry }
  863. ;; | XXXXXXXX...|....... } }
  864. ;; ====+ XXXXXXXX +==== } text height ...... } height
  865. ;; : | XXXXXXXX...|...:... }
  866. ;; : | : : | : } font height / 2 }
  867. ;; : +==============+...:...............................
  868. ;; : : : : : :
  869. ;; : : : : : :.........................
  870. ;; : : : : : } font height }
  871. ;; : : : : :....... }
  872. ;; : : : : } font height / 2 }
  873. ;; : : : :........... }
  874. ;; : : : } text width } width
  875. ;; : : :.................. }
  876. ;; : : } font height / 2 }
  877. ;; : :...................... }
  878. ;; : } font height + extra }
  879. ;; :.................................................
  880. ;;
  881. ;;
  882. ;; * OPTIONAL
  883. ;;
  884. ;; +==========+.....................................
  885. ;; | | } } }
  886. ;; | | } entry } }
  887. ;; | | } } }
  888. ;; ===+===+ +===+===... } element height } height
  889. ;; : \ | | / : } }
  890. ;; : + | | + : } }
  891. ;; : | +==========+.|................. }
  892. ;; : | : : | : } font height }
  893. ;; : +==============+...................................
  894. ;; : : : :
  895. ;; : : : :......................
  896. ;; : : : } font height * 2 }
  897. ;; : : :.......... }
  898. ;; : : } element width } width
  899. ;; : :..................... }
  900. ;; : } font height * 2 }
  901. ;; :...............................................
  902. ;;
  903. ;;
  904. ;; * ALTERNATIVE
  905. ;;
  906. ;; +===+...................................
  907. ;; +==+ A +==+ } A height } }
  908. ;; | +===+..|........ } entry }
  909. ;; + + } font height } }
  910. ;; / +===+...\....... } }
  911. ;; ===+====+ B +====+=== } B height ..... } height
  912. ;; : \ +===+.../....... }
  913. ;; : + + : } font height }
  914. ;; : | +===+..|........ }
  915. ;; : +==+ C +==+ : } C height }
  916. ;; : : +===+...................................
  917. ;; : : : :
  918. ;; : : : :......................
  919. ;; : : : } font height * 2 }
  920. ;; : : :......... }
  921. ;; : : } max width } width
  922. ;; : :................. }
  923. ;; : } font height * 2 }
  924. ;; :..........................................
  925. ;;
  926. ;; NOTES:
  927. ;; 1. An empty alternative has zero of height.
  928. ;;
  929. ;; 2. The variable `ebnf-entry-percentage' is used to determine the
  930. ;; entry point.
  931. ;;
  932. ;;
  933. ;; * ZERO OR MORE
  934. ;;
  935. ;; +===========+...............................
  936. ;; +=+ separator +=+ } separator height }
  937. ;; / +===========+..\........ }
  938. ;; + + } }
  939. ;; | | } font height }
  940. ;; + + } }
  941. ;; \ +===========+../........ } height = entry
  942. ;; +=+ element +=+ } element height }
  943. ;; /: +===========+..\........ }
  944. ;; + : : + } }
  945. ;; + : : + } font height }
  946. ;; / : : \ } }
  947. ;; ==+=======================+==.......................
  948. ;; : : : :
  949. ;; : : : :.......................
  950. ;; : : : } font height * 2 }
  951. ;; : : :......... }
  952. ;; : : } max width } width
  953. ;; : :......................... }
  954. ;; : } font height * 2 }
  955. ;; :...................................................
  956. ;;
  957. ;;
  958. ;; * ONE OR MORE
  959. ;;
  960. ;; +===========+......................................
  961. ;; +=+ separator +=+ } separator height } }
  962. ;; / +===========+..\...... } }
  963. ;; + + } } entry }
  964. ;; | | } font height } } height
  965. ;; + + } } }
  966. ;; \ +===========+../...... } }
  967. ;; ===+=+ element +=+=== } element height .... }
  968. ;; : : +===========+......................................
  969. ;; : : : :
  970. ;; : : : :........................
  971. ;; : : : } font height * 2 }
  972. ;; : : :....... }
  973. ;; : : } max width } width
  974. ;; : :....................... }
  975. ;; : } font height * 2 }
  976. ;; :..............................................
  977. ;;
  978. ;;
  979. ;; * PRODUCTION
  980. ;;
  981. ;; XXXXXX:......................................
  982. ;; XXXXXX: } production font height }
  983. ;; XXXXXX:............ }
  984. ;; } font height }
  985. ;; +======+....... } height = entry
  986. ;; | | } }
  987. ;; ====+ +==== } element height }
  988. ;; : | | : } }
  989. ;; : +======+.................................
  990. ;; : : : :
  991. ;; : : : :......................
  992. ;; : : : } font height * 2 }
  993. ;; : : :....... }
  994. ;; : : } element width } width
  995. ;; : :.............. }
  996. ;; : } font height * 2 }
  997. ;; :.....................................
  998. ;;
  999. ;;
  1000. ;; * REPEAT
  1001. ;;
  1002. ;; +================+...................................
  1003. ;; | | } font height / 2 } entry }
  1004. ;; | +===+...|....... } }
  1005. ;; ====+ N * | X | +==== } X height ......... } height
  1006. ;; : | : : +===+...|...:... }
  1007. ;; : | : : : : | : } font height / 2 }
  1008. ;; : +================+...:...............................
  1009. ;; : : : : : : : :
  1010. ;; : : : : : : : :..........................
  1011. ;; : : : : : : : } font height }
  1012. ;; : : : : : : :....... }
  1013. ;; : : : : : : } font height / 2 }
  1014. ;; : : : : : :........... }
  1015. ;; : : : : : } X width }
  1016. ;; : : : : :............... }
  1017. ;; : : : : } font height / 2 } width
  1018. ;; : : : :.................. }
  1019. ;; : : : } text width }
  1020. ;; : : :..................... }
  1021. ;; : : } font height / 2 }
  1022. ;; : :........................ }
  1023. ;; : } font height + extra }
  1024. ;; :...................................................
  1025. ;;
  1026. ;;
  1027. ;; * EXCEPT
  1028. ;;
  1029. ;; +==================+...................................
  1030. ;; | | } font height / 2 } entry }
  1031. ;; | +===+ +===+...|....... } }
  1032. ;; ====+ | X | - | y | +==== } max height ....... } height
  1033. ;; : | +===+ +===+...|...:... }
  1034. ;; : | : : : : | : } font height / 2 }
  1035. ;; : +==================+...:...............................
  1036. ;; : : : : : : : :
  1037. ;; : : : : : : : :..........................
  1038. ;; : : : : : : : } font height }
  1039. ;; : : : : : : :....... }
  1040. ;; : : : : : : } font height / 2 }
  1041. ;; : : : : : :........... }
  1042. ;; : : : : : } Y width }
  1043. ;; : : : : :............... }
  1044. ;; : : : : } font height } width
  1045. ;; : : : :................... }
  1046. ;; : : : } X width }
  1047. ;; : : :....................... }
  1048. ;; : : } font height / 2 }
  1049. ;; : :.......................... }
  1050. ;; : } font height + extra }
  1051. ;; :.....................................................
  1052. ;;
  1053. ;; NOTE: If Y element is empty, it's draw nothing at Y place.
  1054. ;;
  1055. ;;
  1056. ;; Internal Structures
  1057. ;; -------------------
  1058. ;;
  1059. ;; ebnf2ps has two passes. The first pass does a lexical and syntactic analysis
  1060. ;; of current buffer and generates an intermediate representation. The second
  1061. ;; pass uses the intermediate representation to generate the PostScript
  1062. ;; syntactic chart.
  1063. ;;
  1064. ;; The intermediate representation is a list of vectors, the vector element
  1065. ;; represents a syntactic chart element. Below is a vector representation for
  1066. ;; each syntactic chart element.
  1067. ;;
  1068. ;; [production WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH NAME PRODUCTION ACTION]
  1069. ;; [alternative WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH LIST]
  1070. ;; [sequence WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH LIST]
  1071. ;; [terminal WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH NAME DEFAULT]
  1072. ;; [non-terminal WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH NAME DEFAULT]
  1073. ;; [special WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH NAME DEFAULT]
  1074. ;; [empty WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH]
  1075. ;; [optional WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH ELEMENT]
  1076. ;; [one-or-more WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH ELEMENT SEPARATOR]
  1077. ;; [zero-or-more WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH ELEMENT SEPARATOR]
  1078. ;; [repeat WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH TIMES ELEMENT]
  1079. ;; [except WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH ELEMENT ELEMENT]
  1080. ;;
  1081. ;; The first vector position is a function symbol used to generate PostScript
  1082. ;; for this element.
  1083. ;; WIDTH-FUN is a function symbol called to adjust the element width.
  1084. ;; DIM-FUN is a function symbol called to set the element dimensions.
  1085. ;; ENTRY is the element entry point.
  1086. ;; HEIGHT and WIDTH are the element height and width, respectively.
  1087. ;; NAME is a string that it's the element name.
  1088. ;; DEFAULT is a boolean that indicates if it's a `default' element.
  1089. ;; PRODUCTION and ELEMENT are vectors that represents sub-elements of current
  1090. ;; one.
  1091. ;; LIST is a list of vector that represents the list part for alternatives and
  1092. ;; sequences.
  1093. ;; SEPARATOR is a vector that represents the sub-element used to separate the
  1094. ;; list elements.
  1095. ;; TIMES is a string representing the number of times that ELEMENT is repeated
  1096. ;; on a repeat construction.
  1097. ;; ACTION indicates some action that should be done before production is
  1098. ;; generated. The current actions are:
  1099. ;;
  1100. ;; nil no action.
  1101. ;;
  1102. ;; form-feed current production starts on a new page.
  1103. ;;
  1104. ;; newline current production starts on next line, this is useful
  1105. ;; when `ebnf-horizontal-orientation' is non-nil.
  1106. ;;
  1107. ;; keep-line current production continues on the current line, this
  1108. ;; is useful when `ebnf-horizontal-orientation' is nil.
  1109. ;;
  1110. ;;
  1111. ;; Things To Change
  1112. ;; ----------------
  1113. ;;
  1114. ;; . Handle situations when syntactic chart is out of paper.
  1115. ;; . Use other alphabet than ascii.
  1116. ;; . Optimizations...
  1117. ;;
  1118. ;;
  1119. ;; Acknowledgements
  1120. ;; ----------------
  1121. ;;
  1122. ;; Thanks to Eli Zaretskii <eliz@gnu.org> for some doc fixes.
  1123. ;;
  1124. ;; Thanks to Drew Adams <drew.adams@oracle.com> for suggestions:
  1125. ;; - `ebnf-arrow-extra-width', `ebnf-arrow-scale',
  1126. ;; `ebnf-production-name-p', `ebnf-stop-on-error',
  1127. ;; `ebnf-file-suffix-regexp'and `ebnf-special-show-delimiter' variables.
  1128. ;; - `ebnf-delete-style', `ebnf-eps-file' and `ebnf-eps-directory'
  1129. ;; commands.
  1130. ;; - some docs fix.
  1131. ;;
  1132. ;; Thanks to Matthew K. Junker <junker@alum.mit.edu> for the suggestion to deal
  1133. ;; with some Bison features (%right, %left and %prec pragmas). His suggestion
  1134. ;; was extended to deal with %nonassoc pragma too.
  1135. ;;
  1136. ;; Thanks to all who emailed comments.
  1137. ;;
  1138. ;;
  1139. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1140. ;;; Code:
  1141. (require 'ps-print)
  1142. (and (string< ps-print-version "5.2.3")
  1143. (error "`ebnf2ps' requires `ps-print' package version 5.2.3 or later"))
  1144. ;; to avoid gripes with Emacs 20
  1145. (or (fboundp 'assq-delete-all)
  1146. (defun assq-delete-all (key alist)
  1147. "Delete from ALIST all elements whose car is KEY.
  1148. Return the modified alist.
  1149. Elements of ALIST that are not conses are ignored."
  1150. (let ((tail alist))
  1151. (while tail
  1152. (if (and (consp (car tail))
  1153. (eq (car (car tail)) key))
  1154. (setq alist (delq (car tail) alist)))
  1155. (setq tail (cdr tail)))
  1156. alist)))
  1157. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1158. ;; User Variables:
  1159. ;;; Interface to the command system
  1160. (defgroup postscript nil
  1161. "PostScript Group."
  1162. :tag "PostScript"
  1163. :version "20"
  1164. :group 'emacs)
  1165. (defgroup ebnf2ps nil
  1166. "Translate an EBNF to a syntactic chart on PostScript."
  1167. :prefix "ebnf-"
  1168. :version "20"
  1169. :group 'wp
  1170. :group 'postscript)
  1171. (defgroup ebnf-special nil
  1172. "Special customization."
  1173. :prefix "ebnf-"
  1174. :tag "Special"
  1175. :version "20"
  1176. :group 'ebnf2ps)
  1177. (defgroup ebnf-except nil
  1178. "Except customization."
  1179. :prefix "ebnf-"
  1180. :tag "Except"
  1181. :version "20"
  1182. :group 'ebnf2ps)
  1183. (defgroup ebnf-repeat nil
  1184. "Repeat customization."
  1185. :prefix "ebnf-"
  1186. :tag "Repeat"
  1187. :version "20"
  1188. :group 'ebnf2ps)
  1189. (defgroup ebnf-terminal nil
  1190. "Terminal customization."
  1191. :prefix "ebnf-"
  1192. :tag "Terminal"
  1193. :version "20"
  1194. :group 'ebnf2ps)
  1195. (defgroup ebnf-non-terminal nil
  1196. "Non-Terminal customization."
  1197. :prefix "ebnf-"
  1198. :tag "Non-Terminal"
  1199. :version "20"
  1200. :group 'ebnf2ps)
  1201. (defgroup ebnf-production nil
  1202. "Production customization."
  1203. :prefix "ebnf-"
  1204. :tag "Production"
  1205. :version "20"
  1206. :group 'ebnf2ps)
  1207. (defgroup ebnf-shape nil
  1208. "Shapes customization."
  1209. :prefix "ebnf-"
  1210. :tag "Shape"
  1211. :version "20"
  1212. :group 'ebnf2ps)
  1213. (defgroup ebnf-displacement nil
  1214. "Displacement customization."
  1215. :prefix "ebnf-"
  1216. :tag "Displacement"
  1217. :version "20"
  1218. :group 'ebnf2ps)
  1219. (defgroup ebnf-syntactic nil
  1220. "Syntactic customization."
  1221. :prefix "ebnf-"
  1222. :tag "Syntactic"
  1223. :version "20"
  1224. :group 'ebnf2ps)
  1225. (defgroup ebnf-optimization nil
  1226. "Optimization customization."
  1227. :prefix "ebnf-"
  1228. :tag "Optimization"
  1229. :version "20"
  1230. :group 'ebnf2ps)
  1231. (defcustom ebnf-horizontal-orientation nil
  1232. "*Non-nil means productions are drawn horizontally."
  1233. :type 'boolean
  1234. :version "20"
  1235. :group 'ebnf-displacement)
  1236. (defcustom ebnf-horizontal-max-height nil
  1237. "*Non-nil means to use maximum production height in horizontal orientation.
  1238. It is only used when `ebnf-horizontal-orientation' is non-nil."
  1239. :type 'boolean
  1240. :version "20"
  1241. :group 'ebnf-displacement)
  1242. (defcustom ebnf-production-horizontal-space 0.0 ; use ebnf2ps default value
  1243. "*Specify horizontal space in points between productions.
  1244. Value less or equal to zero forces ebnf2ps to set a proper default value."
  1245. :type 'number
  1246. :version "20"
  1247. :group 'ebnf-displacement)
  1248. (defcustom ebnf-production-vertical-space 0.0 ; use ebnf2ps default value
  1249. "*Specify vertical space in points between productions.
  1250. Value less or equal to zero forces ebnf2ps to set a proper default value."
  1251. :type 'number
  1252. :version "20"
  1253. :group 'ebnf-displacement)
  1254. (defcustom ebnf-justify-sequence 'center
  1255. "*Specify justification of terms in a sequence inside alternatives.
  1256. Valid values are:
  1257. `left' left justification
  1258. `right' right justification
  1259. any other value centralize"
  1260. :type '(radio :tag "Sequence Justification"
  1261. (const left) (const right) (other :tag "center" center))
  1262. :version "20"
  1263. :group 'ebnf-displacement)
  1264. (defcustom ebnf-special-show-delimiter t
  1265. "*Non-nil means special delimiter (character `?') is shown."
  1266. :type 'boolean
  1267. :version "20"
  1268. :group 'ebnf-special)
  1269. (defcustom ebnf-special-font '(7 Courier "Black" "Gray95" bold italic)
  1270. "*Specify special font.
  1271. See documentation for `ebnf-production-font'."
  1272. :type '(list :tag "Special Font"
  1273. (number :tag "Font Size")
  1274. (symbol :tag "Font Name")
  1275. (choice :tag "Foreground Color"
  1276. (string :tag "Name")
  1277. (other :tag "Default" nil))
  1278. (choice :tag "Background Color"
  1279. (string :tag "Name")
  1280. (other :tag "Default" nil))
  1281. (repeat :tag "Font Attributes" :inline t
  1282. (choice (const bold) (const italic)
  1283. (const underline) (const strikeout)
  1284. (const overline) (const shadow)
  1285. (const box) (const outline))))
  1286. :version "20"
  1287. :group 'ebnf-special)
  1288. (defcustom ebnf-special-shape 'bevel
  1289. "*Specify special box shape.
  1290. See documentation for `ebnf-non-terminal-shape'."
  1291. :type '(radio :tag "Special Shape"
  1292. (const miter) (const round) (const bevel))
  1293. :version "20"
  1294. :group 'ebnf-special)
  1295. (defcustom ebnf-special-shadow nil
  1296. "*Non-nil means special box will have a shadow."
  1297. :type 'boolean
  1298. :version "20"
  1299. :group 'ebnf-special)
  1300. (defcustom ebnf-special-border-width 0.5
  1301. "*Specify border width for special box."
  1302. :type 'number
  1303. :version "20"
  1304. :group 'ebnf-special)
  1305. (defcustom ebnf-special-border-color "Black"
  1306. "*Specify border color for special box."
  1307. :type 'string
  1308. :version "20"
  1309. :group 'ebnf-special)
  1310. (defcustom ebnf-except-font '(7 Courier "Black" "Gray90" bold italic)
  1311. "*Specify except font.
  1312. See documentation for `ebnf-production-font'."
  1313. :type '(list :tag "Except Font"
  1314. (number :tag "Font Size")
  1315. (symbol :tag "Font Name")
  1316. (choice :tag "Foreground Color"
  1317. (string :tag "Name")
  1318. (other :tag "Default" nil))
  1319. (choice :tag "Background Color"
  1320. (string :tag "Name")
  1321. (other :tag "Default" nil))
  1322. (repeat :tag "Font Attributes" :inline t
  1323. (choice (const bold) (const italic)
  1324. (const underline) (const strikeout)
  1325. (const overline) (const shadow)
  1326. (const box) (const outline))))
  1327. :version "20"
  1328. :group 'ebnf-except)
  1329. (defcustom ebnf-except-shape 'bevel
  1330. "*Specify except box shape.
  1331. See documentation for `ebnf-non-terminal-shape'."
  1332. :type '(radio :tag "Except Shape"
  1333. (const miter) (const round) (const bevel))
  1334. :version "20"
  1335. :group 'ebnf-except)
  1336. (defcustom ebnf-except-shadow nil
  1337. "*Non-nil means except box will have a shadow."
  1338. :type 'boolean
  1339. :version "20"
  1340. :group 'ebnf-except)
  1341. (defcustom ebnf-except-border-width 0.25
  1342. "*Specify border width for except box."
  1343. :type 'number
  1344. :version "20"
  1345. :group 'ebnf-except)
  1346. (defcustom ebnf-except-border-color "Black"
  1347. "*Specify border color for except box."
  1348. :type 'string
  1349. :version "20"
  1350. :group 'ebnf-except)
  1351. (defcustom ebnf-repeat-font '(7 Courier "Black" "Gray85" bold italic)
  1352. "*Specify repeat font.
  1353. See documentation for `ebnf-production-font'."
  1354. :type '(list :tag "Repeat Font"
  1355. (number :tag "Font Size")
  1356. (symbol :tag "Font Name")
  1357. (choice :tag "Foreground Color"
  1358. (string :tag "Name")
  1359. (other :tag "Default" nil))
  1360. (choice :tag "Background Color"
  1361. (string :tag "Name")
  1362. (other :tag "Default" nil))
  1363. (repeat :tag "Font Attributes" :inline t
  1364. (choice (const bold) (const italic)
  1365. (const underline) (const strikeout)
  1366. (const overline) (const shadow)
  1367. (const box) (const outline))))
  1368. :version "20"
  1369. :group 'ebnf-repeat)
  1370. (defcustom ebnf-repeat-shape 'bevel
  1371. "*Specify repeat box shape.
  1372. See documentation for `ebnf-non-terminal-shape'."
  1373. :type '(radio :tag "Repeat Shape"
  1374. (const miter) (const round) (const bevel))
  1375. :version "20"
  1376. :group 'ebnf-repeat)
  1377. (defcustom ebnf-repeat-shadow nil
  1378. "*Non-nil means repeat box will have a shadow."
  1379. :type 'boolean
  1380. :version "20"
  1381. :group 'ebnf-repeat)
  1382. (defcustom ebnf-repeat-border-width 0.0
  1383. "*Specify border width for repeat box."
  1384. :type 'number
  1385. :version "20"
  1386. :group 'ebnf-repeat)
  1387. (defcustom ebnf-repeat-border-color "Black"
  1388. "*Specify border color for repeat box."
  1389. :type 'string
  1390. :version "20"
  1391. :group 'ebnf-repeat)
  1392. (defcustom ebnf-terminal-font '(7 Courier "Black" "White")
  1393. "*Specify terminal font.
  1394. See documentation for `ebnf-production-font'."
  1395. :type '(list :tag "Terminal Font"
  1396. (number :tag "Font Size")
  1397. (symbol :tag "Font Name")
  1398. (choice :tag "Foreground Color"
  1399. (string :tag "Name")
  1400. (other :tag "Default" nil))
  1401. (choice :tag "Background Color"
  1402. (string :tag "Name")
  1403. (other :tag "Default" nil))
  1404. (repeat :tag "Font Attributes" :inline t
  1405. (choice (const bold) (const italic)
  1406. (const underline) (const strikeout)
  1407. (const overline) (const shadow)
  1408. (const box) (const outline))))
  1409. :version "20"
  1410. :group 'ebnf-terminal)
  1411. (defcustom ebnf-terminal-shape 'miter
  1412. "*Specify terminal box shape.
  1413. See documentation for `ebnf-non-terminal-shape'."
  1414. :type '(radio :tag "Terminal Shape"
  1415. (const miter) (const round) (const bevel))
  1416. :version "20"
  1417. :group 'ebnf-terminal)
  1418. (defcustom ebnf-terminal-shadow nil
  1419. "*Non-nil means terminal box will have a shadow."
  1420. :type 'boolean
  1421. :version "20"
  1422. :group 'ebnf-terminal)
  1423. (defcustom ebnf-terminal-border-width 1.0
  1424. "*Specify border width for terminal box."
  1425. :type 'number
  1426. :version "20"
  1427. :group 'ebnf-terminal)
  1428. (defcustom ebnf-terminal-border-color "Black"
  1429. "*Specify border color for terminal box."
  1430. :type 'string
  1431. :version "20"
  1432. :group 'ebnf-terminal)
  1433. (defcustom ebnf-production-name-p t
  1434. "*Non-nil means production name will be printed."
  1435. :type 'boolean
  1436. :version "20"
  1437. :group 'ebnf-production)
  1438. (defcustom ebnf-sort-production nil
  1439. "*Specify how productions are sorted.
  1440. Valid values are:
  1441. nil don't sort productions.
  1442. `ascending' ascending sort.
  1443. any other value descending sort."
  1444. :type '(radio :tag "Production Sort"
  1445. (const :tag "Ascending" ascending)
  1446. (const :tag "Descending" descending)
  1447. (other :tag "No Sort" nil))
  1448. :version "20"
  1449. :group 'ebnf-production)
  1450. (defcustom ebnf-production-font '(10 Helvetica "Black" "White" bold)
  1451. "*Specify production header font.
  1452. It is a list with the following form:
  1453. (SIZE NAME FOREGROUND BACKGROUND ATTRIBUTE...)
  1454. Where:
  1455. SIZE is the font size.
  1456. NAME is the font name symbol.
  1457. ATTRIBUTE is one of the following symbols:
  1458. bold - use bold font.
  1459. italic - use italic font.
  1460. underline - put a line under text.
  1461. strikeout - like underline, but the line is in middle of text.
  1462. overline - like underline, but the line is over the text.
  1463. shadow - text will have a shadow.
  1464. box - text will be surrounded by a box.
  1465. outline - print characters as hollow outlines.
  1466. FOREGROUND is a foreground string color name; if it's nil, the default color is
  1467. \"Black\".
  1468. BACKGROUND is a background string color name; if it's nil, the default color is
  1469. \"White\".
  1470. See `ps-font-info-database' for valid font name."
  1471. :type '(list :tag "Production Font"
  1472. (number :tag "Font Size")
  1473. (symbol :tag "Font Name")
  1474. (choice :tag "Foreground Color"
  1475. (string :tag "Name")
  1476. (other :tag "Default" nil))
  1477. (choice :tag "Background Color"
  1478. (string :tag "Name")
  1479. (other :tag "Default" nil))
  1480. (repeat :tag "Font Attributes" :inline t
  1481. (choice (const bold) (const italic)
  1482. (const underline) (const strikeout)
  1483. (const overline) (const shadow)
  1484. (const box) (const outline))))
  1485. :version "20"
  1486. :group 'ebnf-production)
  1487. (defcustom ebnf-non-terminal-font '(7 Helvetica "Black" "White")
  1488. "*Specify non-terminal font.
  1489. See documentation for `ebnf-production-font'."
  1490. :type '(list :tag "Non-Terminal Font"
  1491. (number :tag "Font Size")
  1492. (symbol :tag "Font Name")
  1493. (choice :tag "Foreground Color"
  1494. (string :tag "Name")
  1495. (other :tag "Default" nil))
  1496. (choice :tag "Background Color"
  1497. (string :tag "Name")
  1498. (other :tag "Default" nil))
  1499. (repeat :tag "Font Attributes" :inline t
  1500. (choice (const bold) (const italic)
  1501. (const underline) (const strikeout)
  1502. (const overline) (const shadow)
  1503. (const box) (const outline))))
  1504. :version "20"
  1505. :group 'ebnf-non-terminal)
  1506. (defcustom ebnf-non-terminal-shape 'round
  1507. "*Specify non-terminal box shape.
  1508. Valid values are:
  1509. `miter' +-------+
  1510. | |
  1511. +-------+
  1512. `round' -------
  1513. ( )
  1514. -------
  1515. `bevel' /-------\\
  1516. | |
  1517. \\-------/
  1518. Any other value is treated as `miter'."
  1519. :type '(radio :tag "Non-Terminal Shape"
  1520. (const miter) (const round) (const bevel))
  1521. :version "20"
  1522. :group 'ebnf-non-terminal)
  1523. (defcustom ebnf-non-terminal-shadow nil
  1524. "*Non-nil means non-terminal box will have a shadow."
  1525. :type 'boolean
  1526. :version "20"
  1527. :group 'ebnf-non-terminal)
  1528. (defcustom ebnf-non-terminal-border-width 1.0
  1529. "*Specify border width for non-terminal box."
  1530. :type 'number
  1531. :version "20"
  1532. :group 'ebnf-non-terminal)
  1533. (defcustom ebnf-non-terminal-border-color "Black"
  1534. "*Specify border color for non-terminal box."
  1535. :type 'string
  1536. :version "20"
  1537. :group 'ebnf-non-terminal)
  1538. (defcustom ebnf-arrow-shape 'hollow
  1539. "*Specify the arrow shape.
  1540. Valid values are:
  1541. `none' ======
  1542. `semi-up' * `transparent' *
  1543. * |*
  1544. =====* | *
  1545. ==+==*
  1546. | *
  1547. |*
  1548. *
  1549. `semi-down' =====* `hollow' *
  1550. * |*
  1551. * | *
  1552. ==+ *
  1553. | *
  1554. |*
  1555. *
  1556. `simple' * `full' *
  1557. * |*
  1558. =====* |X*
  1559. * ==+XX*
  1560. * |X*
  1561. |*
  1562. *
  1563. `semi-up-hollow' `semi-up-full'
  1564. * *
  1565. |* |*
  1566. | * |X*
  1567. ==+==* ==+==*
  1568. `semi-down-hollow' `semi-down-full'
  1569. ==+==* ==+==*
  1570. | * |X*
  1571. |* |*
  1572. * *
  1573. `user' See also documentation for variable `ebnf-user-arrow'.
  1574. Any other value is treated as `none'."
  1575. :type '(radio :tag "Arrow Shape"
  1576. (const none) (const semi-up)
  1577. (const semi-down) (const simple)
  1578. (const transparent) (const hollow)
  1579. (const full) (const semi-up-hollow)
  1580. (const semi-down-hollow) (const semi-up-full)
  1581. (const semi-down-full) (const user))
  1582. :version "20"
  1583. :group 'ebnf-shape)
  1584. (defcustom ebnf-chart-shape 'round
  1585. "*Specify chart flow shape.
  1586. See documentation for `ebnf-non-terminal-shape'."
  1587. :type '(radio :tag "Chart Flow Shape"
  1588. (const miter) (const round) (const bevel))
  1589. :version "20"
  1590. :group 'ebnf-shape)
  1591. (defcustom ebnf-user-arrow nil
  1592. "*Specify a sexp for user arrow shape (a PostScript code).
  1593. When evaluated, the sexp should return nil or a string containing PostScript
  1594. code. PostScript code should draw a right arrow.
  1595. The anatomy of a right arrow is:
  1596. ...... Initial position
  1597. :
  1598. : *.................
  1599. : | * } }
  1600. : | * } hT4 }
  1601. v | * } }
  1602. ======+======*... } hT2
  1603. : | *: } }
  1604. : | * : } hT4 }
  1605. : | * : } }
  1606. : *.................
  1607. : : :
  1608. : : :..........
  1609. : : } hT2 }
  1610. : :.......... } hT
  1611. : } hT2 }
  1612. :.......................
  1613. Where `hT', `hT2' and `hT4' are predefined PostScript variable names that can
  1614. be used to generate your own arrow. As these variables are used along
  1615. PostScript execution, *DON'T* modify the values of them. Instead, copy the
  1616. values, if you need to modify them.
  1617. The relation between these variables is: hT = 2 * hT2 = 4 * hT4.
  1618. The variable `ebnf-user-arrow' is only used when `ebnf-arrow-shape' is set to
  1619. symbol `user'."
  1620. :type '(sexp :tag "User Arrow Shape")
  1621. :version "20"
  1622. :group 'ebnf-shape)
  1623. (defcustom ebnf-syntax 'ebnf
  1624. "*Specify syntax to be recognized.
  1625. Valid values are:
  1626. `ebnf' ebnf2ps recognizes the syntax described in ebnf2ps
  1627. documentation.
  1628. The following variables *ONLY* have effect with this
  1629. setting:
  1630. `ebnf-terminal-regexp', `ebnf-case-fold-search',
  1631. `ebnf-lex-comment-char' and `ebnf-lex-eop-char'.
  1632. `abnf' ebnf2ps recognizes the syntax described in the URL:
  1633. `http://www.ietf.org/rfc/rfc2234.txt'
  1634. (\"Augmented BNF for Syntax Specifications: ABNF\").
  1635. `iso-ebnf' ebnf2ps recognizes the syntax described in the URL:
  1636. `http://www.cl.cam.ac.uk/~mgk25/iso-ebnf.html'
  1637. (\"International Standard of the ISO EBNF Notation\").
  1638. The following variables *ONLY* have effect with this
  1639. setting:
  1640. `ebnf-iso-alternative-p' and `ebnf-iso-normalize-p'.
  1641. `yacc' ebnf2ps recognizes the Yacc/Bison syntax.
  1642. The following variable *ONLY* has effect with this
  1643. setting:
  1644. `ebnf-yac-ignore-error-recovery'.
  1645. `ebnfx' ebnf2ps recognizes the syntax described in the URL:
  1646. `http://www.w3.org/TR/2004/REC-xml-20040204/#sec-notation'
  1647. (\"Extensible Markup Language (XML) 1.0 (Third Edition)\")
  1648. `dtd' ebnf2ps recognizes the syntax described in the URL:
  1649. `http://www.w3.org/TR/2004/REC-xml-20040204/'
  1650. (\"Extensible Markup Language (XML) 1.0 (Third Edition)\")
  1651. Any other value is treated as `ebnf'."
  1652. :type '(radio :tag "Syntax"
  1653. (const ebnf) (const abnf) (const iso-ebnf)
  1654. (const yacc) (const ebnfx) (const dtd))
  1655. :version "20"
  1656. :group 'ebnf-syntactic)
  1657. (defcustom ebnf-lex-comment-char ?\;
  1658. "*Specify the line comment character.
  1659. It's used only when `ebnf-syntax' is `ebnf'."
  1660. :type 'character
  1661. :version "20"
  1662. :group 'ebnf-syntactic)
  1663. (defcustom ebnf-lex-eop-char ?.
  1664. "*Specify the end of production character.
  1665. It's used only when `ebnf-syntax' is `ebnf'."
  1666. :type 'character
  1667. :version "20"
  1668. :group 'ebnf-syntactic)
  1669. (defcustom ebnf-terminal-regexp nil
  1670. "*Specify how it's a terminal name.
  1671. If it's nil, the terminal name must be enclosed by `\"'.
  1672. If it's a string, it should be a regexp that it'll be used to determine a
  1673. terminal name; terminal name may also be enclosed by `\"'.
  1674. It's used only when `ebnf-syntax' is `ebnf'."
  1675. :type '(radio :tag "Terminal Name"
  1676. (const nil) regexp)
  1677. :version "20"
  1678. :group 'ebnf-syntactic)
  1679. (defcustom ebnf-case-fold-search nil
  1680. "*Non-nil means ignore case on matching.
  1681. It's only used when `ebnf-terminal-regexp' is non-nil and when `ebnf-syntax' is
  1682. `ebnf'."
  1683. :type 'boolean
  1684. :version "20"
  1685. :group 'ebnf-syntactic)
  1686. (defcustom ebnf-iso-alternative-p nil
  1687. "*Non-nil means use alternative ISO EBNF.
  1688. It's only used when `ebnf-syntax' is `iso-ebnf'.
  1689. This variable affects the following symbol set:
  1690. STANDARD ALTERNATIVE
  1691. | ==> / or !
  1692. [ ==> (/
  1693. ] ==> /)
  1694. { ==> (:
  1695. } ==> :)
  1696. ; ==> ."
  1697. :type 'boolean
  1698. :version "20"
  1699. :group 'ebnf-syntactic)
  1700. (defcustom ebnf-iso-normalize-p nil
  1701. "*Non-nil means normalize ISO EBNF syntax names.
  1702. Normalize a name means that several contiguous spaces inside name become a
  1703. single space, so \"A B C\" is normalized to \"A B C\".
  1704. It's only used when `ebnf-syntax' is `iso-ebnf'."
  1705. :type 'boolean
  1706. :version "20"
  1707. :group 'ebnf-syntactic)
  1708. (defcustom ebnf-file-suffix-regexp "\.[Bb][Nn][Ff]$"
  1709. "*Specify file name suffix that contains EBNF.
  1710. See `ebnf-eps-directory' command."
  1711. :type 'regexp
  1712. :version "20"
  1713. :group 'ebnf2ps)
  1714. (defcustom ebnf-eps-prefix "ebnf--"
  1715. "*Specify EPS prefix file name.
  1716. See `ebnf-eps-buffer' and `ebnf-eps-region' commands."
  1717. :type 'string
  1718. :version "20"
  1719. :group 'ebnf2ps)
  1720. (defcustom ebnf-eps-header-font '(11 Helvetica "Black" "White" bold)
  1721. "*Specify EPS header font.
  1722. See documentation for `ebnf-production-font'.
  1723. See `ebnf-eps-buffer' and `ebnf-eps-region' commands."
  1724. :type '(list :tag "EPS Header Font"
  1725. (number :tag "Font Size")
  1726. (symbol :tag "Font Name")
  1727. (choice :tag "Foreground Color"
  1728. (string :tag "Name")
  1729. (other :tag "Default" nil))
  1730. (choice :tag "Background Color"
  1731. (string :tag "Name")
  1732. (other :tag "Default" nil))
  1733. (repeat :tag "Font Attributes" :inline t
  1734. (choice (const bold) (const italic)
  1735. (const underline) (const strikeout)
  1736. (const overline) (const shadow)
  1737. (const box) (const outline))))
  1738. :version "22"
  1739. :group 'ebnf2ps)
  1740. (defcustom ebnf-eps-header nil
  1741. "*Specify EPS header.
  1742. The value should be a string, a symbol or nil.
  1743. String is inserted unchanged.
  1744. For symbol bounded to a function, the function is called and should return a
  1745. string. For symbol bounded to a value, the value should be a string.
  1746. If symbol is unbounded, it is silently ignored.
  1747. Empty string or nil mean that no header will be generated.
  1748. Note that when the header action comment (;H in EBNF syntax) is specified, the
  1749. string in the header action comment is processed and, if it returns a non-empty
  1750. string, it's used to generate the header. The header action comment accepts
  1751. the following formats:
  1752. %% prints a % character.
  1753. %H prints the `ebnf-eps-header' value.
  1754. %F prints the `ebnf-eps-footer' (which see) value.
  1755. Any other format is ignored, that is, if, for example, it's used %s then %s
  1756. characters are stripped out from the header. If header action comment is an
  1757. empty string, no header is generated until a non-empty header is specified or
  1758. `ebnf-eps-header' has a non-empty string value."
  1759. :type '(repeat (choice :menu-tag "EPS Header"
  1760. :tag "EPS Header"
  1761. string symbol (const :tag "No Header" nil )))
  1762. :version "22"
  1763. :group 'ebnf2ps)
  1764. (defcustom ebnf-eps-footer-font '(7 Helvetica "Black" "White" bold)
  1765. "*Specify EPS footer font.
  1766. See documentation for `ebnf-production-font'.
  1767. See `ebnf-eps-buffer' and `ebnf-eps-region' commands."
  1768. :type '(list :tag "EPS Footer Font"
  1769. (number :tag "Font Size")
  1770. (symbol :tag "Font Name")
  1771. (choice :tag "Foreground Color"
  1772. (string :tag "Name")
  1773. (other :tag "Default" nil))
  1774. (choice :tag "Background Color"
  1775. (string :tag "Name")
  1776. (other :tag "Default" nil))
  1777. (repeat :tag "Font Attributes" :inline t
  1778. (choice (const bold) (const italic)
  1779. (const underline) (const strikeout)
  1780. (const overline) (const shadow)
  1781. (const box) (const outline))))
  1782. :version "22"
  1783. :group 'ebnf2ps)
  1784. (defcustom ebnf-eps-footer nil
  1785. "*Specify EPS footer.
  1786. The value should be a string, a symbol or nil.
  1787. String is inserted unchanged.
  1788. For symbol bounded to a function, the function is called and should return a
  1789. string. For symbol bounded to a value, the value should be a string.
  1790. If symbol is unbounded, it is silently ignored.
  1791. Empty string or nil mean that no footer will be generated.
  1792. Note that when the footer action comment (;F in EBNF syntax) is specified, the
  1793. string in the footer action comment is processed and, if it returns a non-empty
  1794. string, it's used to generate the footer. The footer action comment accepts
  1795. the following formats:
  1796. %% prints a % character.
  1797. %H prints the `ebnf-eps-header' (which see) value.
  1798. %F prints the `ebnf-eps-footer' value.
  1799. Any other format is ignored, that is, if, for example, it's used %s then %s
  1800. characters are stripped out from the footer. If footer action comment is an
  1801. empty string, no footer is generated until a non-empty footer is specified or
  1802. `ebnf-eps-footer' has a non-empty string value."
  1803. :type '(repeat (choice :menu-tag "EPS Footer"
  1804. :tag "EPS Footer"
  1805. string symbol (const :tag "No Footer" nil )))
  1806. :version "22"
  1807. :group 'ebnf2ps)
  1808. (defcustom ebnf-entry-percentage 0.5 ; middle
  1809. "*Specify entry height on alternatives.
  1810. It must be a float between 0.0 (top) and 1.0 (bottom)."
  1811. :type 'number
  1812. :version "20"
  1813. :group 'ebnf2ps)
  1814. (defcustom ebnf-default-width 0.6
  1815. "*Specify additional border width over default terminal, non-terminal or
  1816. special."
  1817. :type 'number
  1818. :version "20"
  1819. :group 'ebnf2ps)
  1820. ;; Printing color requires x-color-values.
  1821. (defcustom ebnf-color-p (or (fboundp 'x-color-values) ; Emacs
  1822. (fboundp 'color-instance-rgb-components)) ; XEmacs
  1823. "*Non-nil means use color."
  1824. :type 'boolean
  1825. :version "20"
  1826. :group 'ebnf2ps)
  1827. (defcustom ebnf-line-width 1.0
  1828. "*Specify flow line width."
  1829. :type 'number
  1830. :version "20"
  1831. :group 'ebnf2ps)
  1832. (defcustom ebnf-line-color "Black"
  1833. "*Specify flow line color."
  1834. :type 'string
  1835. :version "20"
  1836. :group 'ebnf2ps)
  1837. (defcustom ebnf-arrow-extra-width
  1838. (if (eq ebnf-arrow-shape 'none)
  1839. 0.0
  1840. (* (sqrt 5.0) 0.65 ebnf-line-width))
  1841. "*Specify extra width for arrow shape drawing.
  1842. The extra width is used to avoid that the arrowhead and the terminal border
  1843. overlap. It depends on `ebnf-arrow-shape' and `ebnf-line-width'."
  1844. :type 'number
  1845. :version "22"
  1846. :group 'ebnf-shape)
  1847. (defcustom ebnf-arrow-scale 1.0
  1848. "*Specify the arrow scale.
  1849. Values lower than 1.0, shrink the arrow.
  1850. Values greater than 1.0, expand the arrow."
  1851. :type 'number
  1852. :version "22"
  1853. :group 'ebnf-shape)
  1854. (defcustom ebnf-debug-ps nil
  1855. "*Non-nil means to generate PostScript debug procedures.
  1856. It is intended to help PostScript programmers in debugging."
  1857. :type 'boolean
  1858. :version "20"
  1859. :group 'ebnf2ps)
  1860. (defcustom ebnf-use-float-format t
  1861. "*Non-nil means use `%f' float format.
  1862. The advantage of using float format is that ebnf2ps generates a little short
  1863. PostScript file.
  1864. If it occurs the error message:
  1865. Invalid format operation %f
  1866. when executing ebnf2ps, set `ebnf-use-float-format' to nil."
  1867. :type 'boolean
  1868. :version "20"
  1869. :group 'ebnf2ps)
  1870. (defcustom ebnf-stop-on-error nil
  1871. "*Non-nil means signal error and stop. Otherwise, signal error and continue."
  1872. :type 'boolean
  1873. :version "20"
  1874. :group 'ebnf2ps)
  1875. (defcustom ebnf-yac-ignore-error-recovery nil
  1876. "*Non-nil means ignore error recovery.
  1877. It's only used when `ebnf-syntax' is `yacc'."
  1878. :type 'boolean
  1879. :version "20"
  1880. :group 'ebnf-syntactic)
  1881. (defcustom ebnf-ignore-empty-rule nil
  1882. "*Non-nil means ignore empty rules.
  1883. It's interesting to set this variable if your Yacc/Bison grammar has a lot of
  1884. middle action rule."
  1885. :type 'boolean
  1886. :version "20"
  1887. :group 'ebnf-optimization)
  1888. (defcustom ebnf-optimize nil
  1889. "*Non-nil means optimize syntactic chart of rules.
  1890. The following optimizations are done:
  1891. left recursion:
  1892. 1. A = B | A C. ==> A = B {C}*.
  1893. 2. A = B | A B. ==> A = {B}+.
  1894. 3. A = | A B. ==> A = {B}*.
  1895. 4. A = B | A C B. ==> A = {B || C}+.
  1896. 5. A = B | D | A C | A E. ==> A = ( B | D ) { C | E }*.
  1897. optional:
  1898. 6. A = B | . ==> A = [B].
  1899. 7. A = | B . ==> A = [B].
  1900. factorization:
  1901. 8. A = B C | B D. ==> A = B (C | D).
  1902. 9. A = C B | D B. ==> A = (C | D) B.
  1903. 10. A = B C E | B D E. ==> A = B (C | D) E.
  1904. The above optimizations are specially useful when `ebnf-syntax' is `yacc'."
  1905. :type 'boolean
  1906. :version "20"
  1907. :group 'ebnf-optimization)
  1908. (defcustom ebnf-log nil
  1909. "*Non-nil means generate log messages.
  1910. The log messages are generated into the buffer *Ebnf2ps Log*.
  1911. These messages are intended to help debugging ebnf2ps."
  1912. :type 'boolean
  1913. :version "22"
  1914. :group 'ebnf2ps)
  1915. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1916. ;; To make this file smaller, some commands go in a separate file.
  1917. ;; But autoload them here to make the separation invisible.
  1918. ;; Autoload is here to avoid compilation gripes.
  1919. (autoload 'ebnf-eliminate-empty-rules "ebnf-otz"
  1920. "Eliminate empty rules.")
  1921. (autoload 'ebnf-optimize "ebnf-otz"
  1922. "Syntactic chart optimizer.")
  1923. (autoload 'ebnf-otz-initialize "ebnf-otz"
  1924. "Initialize optimizer.")
  1925. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1926. ;; Customization
  1927. ;;;###autoload
  1928. (defun ebnf-customize ()
  1929. "Customization for ebnf group."
  1930. (interactive)
  1931. (customize-group 'ebnf2ps))
  1932. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1933. ;; User commands
  1934. ;;;###autoload
  1935. (defun ebnf-print-directory (&optional directory)
  1936. "Generate and print a PostScript syntactic chart image of DIRECTORY.
  1937. If DIRECTORY is nil, it's used `default-directory'.
  1938. The files in DIRECTORY that matches `ebnf-file-suffix-regexp' (which see) are
  1939. processed.
  1940. See also `ebnf-print-buffer'."
  1941. (interactive
  1942. (list (read-directory-name "Directory containing EBNF files (print): "
  1943. nil default-directory)))
  1944. (ebnf-log-header "(ebnf-print-directory %S)" directory)
  1945. (ebnf-directory 'ebnf-print-buffer directory))
  1946. ;;;###autoload
  1947. (defun ebnf-print-file (file &optional do-not-kill-buffer-when-done)
  1948. "Generate and print a PostScript syntactic chart image of the file FILE.
  1949. If optional arg DO-NOT-KILL-BUFFER-WHEN-DONE is non-nil, the buffer isn't
  1950. killed after process termination.
  1951. See also `ebnf-print-buffer'."
  1952. (interactive "fEBNF file to generate PostScript and print from: ")
  1953. (ebnf-log-header "(ebnf-print-file %S %S)" file do-not-kill-buffer-when-done)
  1954. (ebnf-file 'ebnf-print-buffer file do-not-kill-buffer-when-done))
  1955. ;;;###autoload
  1956. (defun ebnf-print-buffer (&optional filename)
  1957. "Generate and print a PostScript syntactic chart image of the buffer.
  1958. When called with a numeric prefix argument (C-u), prompts the user for
  1959. the name of a file to save the PostScript image in, instead of sending
  1960. it to the printer.
  1961. More specifically, the FILENAME argument is treated as follows: if it
  1962. is nil, send the image to the printer. If FILENAME is a string, save
  1963. the PostScript image in a file with that name. If FILENAME is a
  1964. number, prompt the user for the name of the file to save in."
  1965. (interactive (list (ps-print-preprint current-prefix-arg)))
  1966. (ebnf-log-header "(ebnf-print-buffer %S)" filename)
  1967. (ebnf-print-region (point-min) (point-max) filename))
  1968. ;;;###autoload
  1969. (defun ebnf-print-region (from to &optional filename)
  1970. "Generate and print a PostScript syntactic chart image of the region.
  1971. Like `ebnf-print-buffer', but prints just the current region."
  1972. (interactive (list (point) (mark) (ps-print-preprint current-prefix-arg)))
  1973. (ebnf-log-header "(ebnf-print-region %S %S %S)" from to filename)
  1974. (run-hooks 'ebnf-hook)
  1975. (or (ebnf-spool-region from to)
  1976. (ps-do-despool filename)))
  1977. ;;;###autoload
  1978. (defun ebnf-spool-directory (&optional directory)
  1979. "Generate and spool a PostScript syntactic chart image of DIRECTORY.
  1980. If DIRECTORY is nil, it's used `default-directory'.
  1981. The files in DIRECTORY that matches `ebnf-file-suffix-regexp' (which see) are
  1982. processed.
  1983. See also `ebnf-spool-buffer'."
  1984. (interactive
  1985. (list (read-directory-name "Directory containing EBNF files (spool): "
  1986. nil default-directory)))
  1987. (ebnf-log-header "(ebnf-spool-directory %S)" directory)
  1988. (ebnf-directory 'ebnf-spool-buffer directory))
  1989. ;;;###autoload
  1990. (defun ebnf-spool-file (file &optional do-not-kill-buffer-when-done)
  1991. "Generate and spool a PostScript syntactic chart image of the file FILE.
  1992. If optional arg DO-NOT-KILL-BUFFER-WHEN-DONE is non-nil, the buffer isn't
  1993. killed after process termination.
  1994. See also `ebnf-spool-buffer'."
  1995. (interactive "fEBNF file to generate PostScript and spool from: ")
  1996. (ebnf-log-header "(ebnf-spool-file %S %S)" file do-not-kill-buffer-when-done)
  1997. (ebnf-file 'ebnf-spool-buffer file do-not-kill-buffer-when-done))
  1998. ;;;###autoload
  1999. (defun ebnf-spool-buffer ()
  2000. "Generate and spool a PostScript syntactic chart image of the buffer.
  2001. Like `ebnf-print-buffer' except that the PostScript image is saved in a
  2002. local buffer to be sent to the printer later.
  2003. Use the command `ebnf-despool' to send the spooled images to the printer."
  2004. (interactive)
  2005. (ebnf-log-header "(ebnf-spool-buffer)")
  2006. (ebnf-spool-region (point-min) (point-max)))
  2007. ;;;###autoload
  2008. (defun ebnf-spool-region (from to)
  2009. "Generate a PostScript syntactic chart image of the region and spool locally.
  2010. Like `ebnf-spool-buffer', but spools just the current region.
  2011. Use the command `ebnf-despool' to send the spooled images to the printer."
  2012. (interactive "r")
  2013. (ebnf-log-header "(ebnf-spool-region %S)" from to)
  2014. (ebnf-generate-region from to 'ebnf-generate))
  2015. ;;;###autoload
  2016. (defun ebnf-eps-directory (&optional directory)
  2017. "Generate EPS files from EBNF files in DIRECTORY.
  2018. If DIRECTORY is nil, it's used `default-directory'.
  2019. The files in DIRECTORY that matches `ebnf-file-suffix-regexp' (which see) are
  2020. processed.
  2021. See also `ebnf-eps-buffer'."
  2022. (interactive
  2023. (list (read-directory-name "Directory containing EBNF files (EPS): "
  2024. nil default-directory)))
  2025. (ebnf-log-header "(ebnf-eps-directory %S)" directory)
  2026. (ebnf-directory 'ebnf-eps-buffer directory))
  2027. ;;;###autoload
  2028. (defun ebnf-eps-file (file &optional do-not-kill-buffer-when-done)
  2029. "Generate an EPS file from EBNF file FILE.
  2030. If optional arg DO-NOT-KILL-BUFFER-WHEN-DONE is non-nil, the buffer isn't
  2031. killed after EPS generation.
  2032. See also `ebnf-eps-buffer'."
  2033. (interactive "fEBNF file to generate EPS file from: ")
  2034. (ebnf-log-header "(ebnf-eps-file %S %S)" file do-not-kill-buffer-when-done)
  2035. (ebnf-file 'ebnf-eps-buffer file do-not-kill-buffer-when-done))
  2036. ;;;###autoload
  2037. (defun ebnf-eps-buffer ()
  2038. "Generate a PostScript syntactic chart image of the buffer in an EPS file.
  2039. Generate an EPS file for each production in the buffer.
  2040. The EPS file name has the following form:
  2041. <PREFIX><PRODUCTION>.eps
  2042. <PREFIX> is given by variable `ebnf-eps-prefix'.
  2043. The default value is \"ebnf--\".
  2044. <PRODUCTION> is the production name.
  2045. Some characters in the production file name are replaced to
  2046. produce a valid file name. For example, the production name
  2047. \"A/B + C\" is modified to produce \"A_B_+_C\", and the EPS
  2048. file name used in this case will be \"ebnf--A_B_+_C.eps\".
  2049. WARNING: This function does *NOT* ask any confirmation to override existing
  2050. files."
  2051. (interactive)
  2052. (ebnf-log-header "(ebnf-eps-buffer)")
  2053. (ebnf-eps-region (point-min) (point-max)))
  2054. ;;;###autoload
  2055. (defun ebnf-eps-region (from to)
  2056. "Generate a PostScript syntactic chart image of the region in an EPS file.
  2057. Generate an EPS file for each production in the region.
  2058. The EPS file name has the following form:
  2059. <PREFIX><PRODUCTION>.eps
  2060. <PREFIX> is given by variable `ebnf-eps-prefix'.
  2061. The default value is \"ebnf--\".
  2062. <PRODUCTION> is the production name.
  2063. Some characters in the production file name are replaced to
  2064. produce a valid file name. For example, the production name
  2065. \"A/B + C\" is modified to produce \"A_B_+_C\", and the EPS
  2066. file name used in this case will be \"ebnf--A_B_+_C.eps\".
  2067. WARNING: This function does *NOT* ask any confirmation to override existing
  2068. files."
  2069. (interactive "r")
  2070. (ebnf-log-header "(ebnf-eps-region %S %S)" from to)
  2071. (let ((ebnf-eps-executing t))
  2072. (ebnf-generate-region from to 'ebnf-generate-eps)))
  2073. ;;;###autoload
  2074. (defalias 'ebnf-despool 'ps-despool)
  2075. ;;;###autoload
  2076. (defun ebnf-syntax-directory (&optional directory)
  2077. "Do a syntactic analysis of the files in DIRECTORY.
  2078. If DIRECTORY is nil, use `default-directory'.
  2079. Only the files in DIRECTORY that match `ebnf-file-suffix-regexp' (which see)
  2080. are processed.
  2081. See also `ebnf-syntax-buffer'."
  2082. (interactive
  2083. (list (read-directory-name "Directory containing EBNF files (syntax): "
  2084. nil default-directory)))
  2085. (ebnf-log-header "(ebnf-syntax-directory %S)" directory)
  2086. (ebnf-directory 'ebnf-syntax-buffer directory))
  2087. ;;;###autoload
  2088. (defun ebnf-syntax-file (file &optional do-not-kill-buffer-when-done)
  2089. "Do a syntactic analysis of the named FILE.
  2090. If optional arg DO-NOT-KILL-BUFFER-WHEN-DONE is non-nil, the buffer isn't
  2091. killed after syntax checking.
  2092. See also `ebnf-syntax-buffer'."
  2093. (interactive "fEBNF file to check syntax: ")
  2094. (ebnf-log-header "(ebnf-syntax-file %S %S)" file do-not-kill-buffer-when-done)
  2095. (ebnf-file 'ebnf-syntax-buffer file do-not-kill-buffer-when-done))
  2096. ;;;###autoload
  2097. (defun ebnf-syntax-buffer ()
  2098. "Do a syntactic analysis of the current buffer."
  2099. (interactive)
  2100. (ebnf-log-header "(ebnf-syntax-buffer)")
  2101. (ebnf-syntax-region (point-min) (point-max)))
  2102. ;;;###autoload
  2103. (defun ebnf-syntax-region (from to)
  2104. "Do a syntactic analysis of a region."
  2105. (interactive "r")
  2106. (ebnf-log-header "(ebnf-syntax-region %S %S)" from to)
  2107. (ebnf-generate-region from to nil))
  2108. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2109. ;; Utilities
  2110. ;;;###autoload
  2111. (defun ebnf-setup ()
  2112. "Return the current ebnf2ps setup."
  2113. (format
  2114. "
  2115. ;;; ebnf2ps.el version %s
  2116. ;;; Emacs version %S
  2117. \(setq ebnf-special-show-delimiter %S
  2118. ebnf-special-font %s
  2119. ebnf-special-shape %s
  2120. ebnf-special-shadow %S
  2121. ebnf-special-border-width %S
  2122. ebnf-special-border-color %S
  2123. ebnf-except-font %s
  2124. ebnf-except-shape %s
  2125. ebnf-except-shadow %S
  2126. ebnf-except-border-width %S
  2127. ebnf-except-border-color %S
  2128. ebnf-repeat-font %s
  2129. ebnf-repeat-shape %s
  2130. ebnf-repeat-shadow %S
  2131. ebnf-repeat-border-width %S
  2132. ebnf-repeat-border-color %S
  2133. ebnf-terminal-regexp %S
  2134. ebnf-case-fold-search %S
  2135. ebnf-terminal-font %s
  2136. ebnf-terminal-shape %s
  2137. ebnf-terminal-shadow %S
  2138. ebnf-terminal-border-width %S
  2139. ebnf-terminal-border-color %S
  2140. ebnf-non-terminal-font %s
  2141. ebnf-non-terminal-shape %s
  2142. ebnf-non-terminal-shadow %S
  2143. ebnf-non-terminal-border-width %S
  2144. ebnf-non-terminal-border-color %S
  2145. ebnf-production-name-p %S
  2146. ebnf-sort-production %s
  2147. ebnf-production-font %s
  2148. ebnf-arrow-shape %s
  2149. ebnf-chart-shape %s
  2150. ebnf-user-arrow %s
  2151. ebnf-horizontal-orientation %S
  2152. ebnf-horizontal-max-height %S
  2153. ebnf-production-horizontal-space %S
  2154. ebnf-production-vertical-space %S
  2155. ebnf-justify-sequence %s
  2156. ebnf-lex-comment-char ?\\%03o
  2157. ebnf-lex-eop-char ?\\%03o
  2158. ebnf-syntax %s
  2159. ebnf-iso-alternative-p %S
  2160. ebnf-iso-normalize-p %S
  2161. ebnf-file-suffix-regexp %S
  2162. ebnf-eps-prefix %S
  2163. ebnf-eps-header-font %s
  2164. ebnf-eps-header %s
  2165. ebnf-eps-footer-font %s
  2166. ebnf-eps-footer %s
  2167. ebnf-entry-percentage %S
  2168. ebnf-color-p %S
  2169. ebnf-line-width %S
  2170. ebnf-line-color %S
  2171. ebnf-arrow-extra-width %S
  2172. ebnf-arrow-scale %S
  2173. ebnf-debug-ps %S
  2174. ebnf-use-float-format %S
  2175. ebnf-stop-on-error %S
  2176. ebnf-yac-ignore-error-recovery %S
  2177. ebnf-ignore-empty-rule %S
  2178. ebnf-optimize %S
  2179. ebnf-log %S)
  2180. ;;; ebnf2ps.el - end of settings
  2181. "
  2182. ebnf-version
  2183. emacs-version
  2184. ebnf-special-show-delimiter
  2185. (ps-print-quote ebnf-special-font)
  2186. (ps-print-quote ebnf-special-shape)
  2187. ebnf-special-shadow
  2188. ebnf-special-border-width
  2189. ebnf-special-border-color
  2190. (ps-print-quote ebnf-except-font)
  2191. (ps-print-quote ebnf-except-shape)
  2192. ebnf-except-shadow
  2193. ebnf-except-border-width
  2194. ebnf-except-border-color
  2195. (ps-print-quote ebnf-repeat-font)
  2196. (ps-print-quote ebnf-repeat-shape)
  2197. ebnf-repeat-shadow
  2198. ebnf-repeat-border-width
  2199. ebnf-repeat-border-color
  2200. ebnf-terminal-regexp
  2201. ebnf-case-fold-search
  2202. (ps-print-quote ebnf-terminal-font)
  2203. (ps-print-quote ebnf-terminal-shape)
  2204. ebnf-terminal-shadow
  2205. ebnf-terminal-border-width
  2206. ebnf-terminal-border-color
  2207. (ps-print-quote ebnf-non-terminal-font)
  2208. (ps-print-quote ebnf-non-terminal-shape)
  2209. ebnf-non-terminal-shadow
  2210. ebnf-non-terminal-border-width
  2211. ebnf-non-terminal-border-color
  2212. ebnf-production-name-p
  2213. (ps-print-quote ebnf-sort-production)
  2214. (ps-print-quote ebnf-production-font)
  2215. (ps-print-quote ebnf-arrow-shape)
  2216. (ps-print-quote ebnf-chart-shape)
  2217. (ps-print-quote ebnf-user-arrow)
  2218. ebnf-horizontal-orientation
  2219. ebnf-horizontal-max-height
  2220. ebnf-production-horizontal-space
  2221. ebnf-production-vertical-space
  2222. (ps-print-quote ebnf-justify-sequence)
  2223. ebnf-lex-comment-char
  2224. ebnf-lex-eop-char
  2225. (ps-print-quote ebnf-syntax)
  2226. ebnf-iso-alternative-p
  2227. ebnf-iso-normalize-p
  2228. ebnf-file-suffix-regexp
  2229. ebnf-eps-prefix
  2230. (ps-print-quote ebnf-eps-header-font)
  2231. (ps-print-quote ebnf-eps-header)
  2232. (ps-print-quote ebnf-eps-footer-font)
  2233. (ps-print-quote ebnf-eps-footer)
  2234. ebnf-entry-percentage
  2235. ebnf-color-p
  2236. ebnf-line-width
  2237. ebnf-line-color
  2238. ebnf-arrow-extra-width
  2239. ebnf-arrow-scale
  2240. ebnf-debug-ps
  2241. ebnf-use-float-format
  2242. ebnf-stop-on-error
  2243. ebnf-yac-ignore-error-recovery
  2244. ebnf-ignore-empty-rule
  2245. ebnf-optimize
  2246. ebnf-log))
  2247. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2248. ;; Style variables
  2249. (defvar ebnf-stack-style nil
  2250. "Used in functions `ebnf-reset-style', `ebnf-push-style' and
  2251. `ebnf-pop-style'.")
  2252. (defvar ebnf-current-style 'default
  2253. "Used in functions `ebnf-apply-style' and `ebnf-push-style'.")
  2254. (defconst ebnf-style-custom-list
  2255. '(ebnf-special-show-delimiter
  2256. ebnf-special-font
  2257. ebnf-special-shape
  2258. ebnf-special-shadow
  2259. ebnf-special-border-width
  2260. ebnf-special-border-color
  2261. ebnf-except-font
  2262. ebnf-except-shape
  2263. ebnf-except-shadow
  2264. ebnf-except-border-width
  2265. ebnf-except-border-color
  2266. ebnf-repeat-font
  2267. ebnf-repeat-shape
  2268. ebnf-repeat-shadow
  2269. ebnf-repeat-border-width
  2270. ebnf-repeat-border-color
  2271. ebnf-terminal-regexp
  2272. ebnf-case-fold-search
  2273. ebnf-terminal-font
  2274. ebnf-terminal-shape
  2275. ebnf-terminal-shadow
  2276. ebnf-terminal-border-width
  2277. ebnf-terminal-border-color
  2278. ebnf-non-terminal-font
  2279. ebnf-non-terminal-shape
  2280. ebnf-non-terminal-shadow
  2281. ebnf-non-terminal-border-width
  2282. ebnf-non-terminal-border-color
  2283. ebnf-production-name-p
  2284. ebnf-sort-production
  2285. ebnf-production-font
  2286. ebnf-arrow-shape
  2287. ebnf-chart-shape
  2288. ebnf-user-arrow
  2289. ebnf-horizontal-orientation
  2290. ebnf-horizontal-max-height
  2291. ebnf-production-horizontal-space
  2292. ebnf-production-vertical-space
  2293. ebnf-justify-sequence
  2294. ebnf-lex-comment-char
  2295. ebnf-lex-eop-char
  2296. ebnf-syntax
  2297. ebnf-iso-alternative-p
  2298. ebnf-iso-normalize-p
  2299. ebnf-file-suffix-regexp
  2300. ebnf-eps-prefix
  2301. ebnf-eps-header-font
  2302. ebnf-eps-header
  2303. ebnf-eps-footer-font
  2304. ebnf-eps-footer
  2305. ebnf-entry-percentage
  2306. ebnf-color-p
  2307. ebnf-line-width
  2308. ebnf-line-color
  2309. ebnf-debug-ps
  2310. ebnf-use-float-format
  2311. ebnf-stop-on-error
  2312. ebnf-yac-ignore-error-recovery
  2313. ebnf-ignore-empty-rule
  2314. ebnf-optimize)
  2315. "List of valid symbol custom variable.")
  2316. (defvar ebnf-style-database
  2317. '(;; EBNF default
  2318. (default
  2319. nil
  2320. (ebnf-special-show-delimiter . t)
  2321. (ebnf-special-font . '(7 Courier "Black" "Gray95" bold italic))
  2322. (ebnf-special-shape . 'bevel)
  2323. (ebnf-special-shadow . nil)
  2324. (ebnf-special-border-width . 0.5)
  2325. (ebnf-special-border-color . "Black")
  2326. (ebnf-except-font . '(7 Courier "Black" "Gray90" bold italic))
  2327. (ebnf-except-shape . 'bevel)
  2328. (ebnf-except-shadow . nil)
  2329. (ebnf-except-border-width . 0.25)
  2330. (ebnf-except-border-color . "Black")
  2331. (ebnf-repeat-font . '(7 Courier "Black" "Gray85" bold italic))
  2332. (ebnf-repeat-shape . 'bevel)
  2333. (ebnf-repeat-shadow . nil)
  2334. (ebnf-repeat-border-width . 0.0)
  2335. (ebnf-repeat-border-color . "Black")
  2336. (ebnf-terminal-regexp . nil)
  2337. (ebnf-case-fold-search . nil)
  2338. (ebnf-terminal-font . '(7 Courier "Black" "White"))
  2339. (ebnf-terminal-shape . 'miter)
  2340. (ebnf-terminal-shadow . nil)
  2341. (ebnf-terminal-border-width . 1.0)
  2342. (ebnf-terminal-border-color . "Black")
  2343. (ebnf-non-terminal-font . '(7 Helvetica "Black" "White"))
  2344. (ebnf-non-terminal-shape . 'round)
  2345. (ebnf-non-terminal-shadow . nil)
  2346. (ebnf-non-terminal-border-width . 1.0)
  2347. (ebnf-non-terminal-border-color . "Black")
  2348. (ebnf-production-name-p . t)
  2349. (ebnf-sort-production . nil)
  2350. (ebnf-production-font . '(10 Helvetica "Black" "White" bold))
  2351. (ebnf-arrow-shape . 'hollow)
  2352. (ebnf-chart-shape . 'round)
  2353. (ebnf-user-arrow . nil)
  2354. (ebnf-horizontal-orientation . nil)
  2355. (ebnf-horizontal-max-height . nil)
  2356. (ebnf-production-horizontal-space . 0.0)
  2357. (ebnf-production-vertical-space . 0.0)
  2358. (ebnf-justify-sequence . 'center)
  2359. (ebnf-lex-comment-char . ?\;)
  2360. (ebnf-lex-eop-char . ?.)
  2361. (ebnf-syntax . 'ebnf)
  2362. (ebnf-iso-alternative-p . nil)
  2363. (ebnf-iso-normalize-p . nil)
  2364. (ebnf-file-suffix-regexp . "\.[Bb][Nn][Ff]$")
  2365. (ebnf-eps-prefix . "ebnf--")
  2366. (ebnf-eps-header-font . '(11 Helvetica "Black" "White" bold))
  2367. (ebnf-eps-header . nil)
  2368. (ebnf-eps-footer-font . '(7 Helvetica "Black" "White" bold))
  2369. (ebnf-eps-footer . nil)
  2370. (ebnf-entry-percentage . 0.5)
  2371. (ebnf-color-p . (or (fboundp 'x-color-values) ; Emacs
  2372. (fboundp 'color-instance-rgb-components))) ; XEmacs
  2373. (ebnf-line-width . 1.0)
  2374. (ebnf-line-color . "Black")
  2375. (ebnf-debug-ps . nil)
  2376. (ebnf-use-float-format . t)
  2377. (ebnf-stop-on-error . nil)
  2378. (ebnf-yac-ignore-error-recovery . nil)
  2379. (ebnf-ignore-empty-rule . nil)
  2380. (ebnf-optimize . nil))
  2381. ;; Happy EBNF default
  2382. (happy
  2383. default
  2384. (ebnf-justify-sequence . 'left)
  2385. (ebnf-lex-comment-char . ?\#)
  2386. (ebnf-lex-eop-char . ?\;))
  2387. ;; ABNF default
  2388. (abnf
  2389. default
  2390. (ebnf-syntax . 'abnf))
  2391. ;; ISO EBNF default
  2392. (iso-ebnf
  2393. default
  2394. (ebnf-syntax . 'iso-ebnf))
  2395. ;; Yacc/Bison default
  2396. (yacc
  2397. default
  2398. (ebnf-syntax . 'yacc))
  2399. ;; ebnfx default
  2400. (ebnfx
  2401. default
  2402. (ebnf-syntax . 'ebnfx))
  2403. ;; dtd default
  2404. (dtd
  2405. default
  2406. (ebnf-syntax . 'dtd))
  2407. )
  2408. "Style database.
  2409. Each element has the following form:
  2410. (NAME INHERITS (VAR . VALUE)...)
  2411. Where:
  2412. NAME is a symbol name style.
  2413. INHERITS is a symbol name style from which the current style inherits
  2414. the context. If INHERITS is nil, then there is no inheritance.
  2415. This is a simple inheritance of style: if you declare that
  2416. style A inherits from style B, all settings of B are applied
  2417. first, and then the settings of A are applied. This is useful
  2418. when you wish to modify some aspects of an existing style, but
  2419. at the same time wish to keep it unmodified.
  2420. VAR is a valid ebnf2ps symbol custom variable.
  2421. See `ebnf-style-custom-list' for valid symbol variables.
  2422. VALUE is a sexp which will be evaluated to set the value of VAR.
  2423. Don't forget to quote symbols and constant lists.
  2424. See `default' style for an example.
  2425. Don't use this variable directly. Use functions `ebnf-insert-style',
  2426. `ebnf-delete-style' and `ebnf-merge-style'.")
  2427. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2428. ;; Style commands
  2429. ;;;###autoload
  2430. (defun ebnf-find-style (name)
  2431. "Return style definition if NAME is already defined; otherwise, return nil.
  2432. See `ebnf-style-database' documentation."
  2433. (interactive "SStyle name: ")
  2434. (assoc name ebnf-style-database))
  2435. ;;;###autoload
  2436. (defun ebnf-insert-style (name inherits &rest values)
  2437. "Insert a new style NAME with inheritance INHERITS and values VALUES.
  2438. See `ebnf-style-database' documentation."
  2439. (interactive "SStyle name: \nSStyle inherits from: \nXStyle values: ")
  2440. (and (assoc name ebnf-style-database)
  2441. (error "Style name already exists: %s" name))
  2442. (or (assoc inherits ebnf-style-database)
  2443. (error "Style inheritance name doesn't exist: %s" inherits))
  2444. (setq ebnf-style-database
  2445. (cons (cons name (cons inherits (ebnf-check-style-values values)))
  2446. ebnf-style-database)))
  2447. ;;;###autoload
  2448. (defun ebnf-delete-style (name)
  2449. "Delete style NAME.
  2450. See `ebnf-style-database' documentation."
  2451. (interactive "SDelete style name: ")
  2452. (or (assoc name ebnf-style-database)
  2453. (error "Style name doesn't exist: %s" name))
  2454. (let ((db ebnf-style-database))
  2455. (while db
  2456. (and (eq (nth 1 (car db)) name)
  2457. (error "Style name `%s' is inherited by `%s' style"
  2458. name (nth 0 (car db))))
  2459. (setq db (cdr db))))
  2460. (setq ebnf-style-database (assq-delete-all name ebnf-style-database)))
  2461. ;;;###autoload
  2462. (defun ebnf-merge-style (name &rest values)
  2463. "Merge values of style NAME with style VALUES.
  2464. See `ebnf-style-database' documentation."
  2465. (interactive "SStyle name: \nXStyle values: ")
  2466. (let ((style (or (assoc name ebnf-style-database)
  2467. (error "Style name doesn't exist: %s" name)))
  2468. (merge (ebnf-check-style-values values))
  2469. val elt new check)
  2470. ;; modify value of existing variables
  2471. (setq val (nthcdr 2 style))
  2472. (while merge
  2473. (setq check (car merge)
  2474. merge (cdr merge)
  2475. elt (assoc (car check) val))
  2476. (if elt
  2477. (setcdr elt (cdr check))
  2478. (setq new (cons check new))))
  2479. ;; insert new variables
  2480. (nconc style (nreverse new))))
  2481. ;;;###autoload
  2482. (defun ebnf-apply-style (style)
  2483. "Set STYLE as the current style.
  2484. Returns the old style symbol.
  2485. See `ebnf-style-database' documentation."
  2486. (interactive "SApply style: ")
  2487. (prog1
  2488. ebnf-current-style
  2489. (and (ebnf-apply-style1 style)
  2490. (setq ebnf-current-style style))))
  2491. ;;;###autoload
  2492. (defun ebnf-reset-style (&optional style)
  2493. "Reset current style.
  2494. Returns the old style symbol.
  2495. See `ebnf-style-database' documentation."
  2496. (interactive "SReset style: ")
  2497. (setq ebnf-stack-style nil)
  2498. (ebnf-apply-style (or style 'default)))
  2499. ;;;###autoload
  2500. (defun ebnf-push-style (&optional style)
  2501. "Push the current style onto a stack and set STYLE as the current style.
  2502. Returns the old style symbol.
  2503. See also `ebnf-pop-style'.
  2504. See `ebnf-style-database' documentation."
  2505. (interactive "SPush style: ")
  2506. (prog1
  2507. ebnf-current-style
  2508. (setq ebnf-stack-style (cons ebnf-current-style ebnf-stack-style))
  2509. (and style
  2510. (ebnf-apply-style style))))
  2511. ;;;###autoload
  2512. (defun ebnf-pop-style ()
  2513. "Pop a style from the stack of pushed styles and set it as the current style.
  2514. Returns the old style symbol.
  2515. See also `ebnf-push-style'.
  2516. See `ebnf-style-database' documentation."
  2517. (interactive)
  2518. (prog1
  2519. (ebnf-apply-style (car ebnf-stack-style))
  2520. (setq ebnf-stack-style (cdr ebnf-stack-style))))
  2521. (defun ebnf-apply-style1 (style)
  2522. (let ((value (cdr (assoc style ebnf-style-database))))
  2523. (prog1
  2524. value
  2525. (and (car value) (ebnf-apply-style1 (car value)))
  2526. (while (setq value (cdr value))
  2527. (set (caar value) (eval (cdar value)))))))
  2528. (defun ebnf-check-style-values (values)
  2529. (let (style)
  2530. (while values
  2531. (and (memq (caar values) ebnf-style-custom-list)
  2532. (setq style (cons (car values) style)))
  2533. (setq values (cdr values)))
  2534. (nreverse style)))
  2535. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2536. ;; Internal variables
  2537. (defvar ebnf-eps-buffer-name " *EPS*")
  2538. (defvar ebnf-parser-func nil)
  2539. (defvar ebnf-eps-executing nil)
  2540. (defvar ebnf-eps-header-comment nil)
  2541. (defvar ebnf-eps-footer-comment nil)
  2542. (defvar ebnf-eps-upper-x 0.0)
  2543. (make-variable-buffer-local 'ebnf-eps-upper-x)
  2544. (defvar ebnf-eps-upper-y 0.0)
  2545. (make-variable-buffer-local 'ebnf-eps-upper-y)
  2546. (defvar ebnf-eps-prod-width 0.0)
  2547. (make-variable-buffer-local 'ebnf-eps-prod-width)
  2548. (defvar ebnf-eps-max-height 0.0)
  2549. (make-variable-buffer-local 'ebnf-eps-max-height)
  2550. (defvar ebnf-eps-max-width 0.0)
  2551. (make-variable-buffer-local 'ebnf-eps-max-width)
  2552. (defvar ebnf-eps-context nil
  2553. "List of EPS file name during parsing.
  2554. See section \"Actions in Comments\" in ebnf2ps documentation.")
  2555. (defvar ebnf-eps-file-alist nil
  2556. "Alist associating file name with EPS header and footer.
  2557. Each element has the following form:
  2558. (EPS-FILENAME HEADER FOOTER)
  2559. EPS-FILENAME is the EPS file name.
  2560. HEADER is the header string or nil.
  2561. FOOTER is the footer string or nil.
  2562. It's generated during parsing and used during EPS generation.
  2563. See `ebnf-eps-context' and section \"Actions in Comments\" in ebnf2ps
  2564. documentation.")
  2565. (defvar ebnf-eps-production-list nil
  2566. "Alist associating production name with EPS file name list.
  2567. Each element has the following form:
  2568. (PRODUCTION EPS-FILENAME...)
  2569. PRODUCTION is the production name.
  2570. EPS-FILENAME is the EPS file name.
  2571. This is generated during parsing and used during EPS generation.
  2572. See `ebnf-eps-context' and section \"Actions in Comments\" in ebnf2ps
  2573. documentation.")
  2574. (defconst ebnf-arrow-shape-alist
  2575. '((none . 0)
  2576. (semi-up . 1)
  2577. (semi-down . 2)
  2578. (simple . 3)
  2579. (transparent . 4)
  2580. (hollow . 5)
  2581. (full . 6)
  2582. (semi-up-hollow . 7)
  2583. (semi-up-full . 8)
  2584. (semi-down-hollow . 9)
  2585. (semi-down-full . 10)
  2586. (user . 11))
  2587. "Alist associating values for `ebnf-arrow-shape'.
  2588. See documentation for `ebnf-arrow-shape'.")
  2589. (defconst ebnf-terminal-shape-alist
  2590. '((miter . 0)
  2591. (round . 1)
  2592. (bevel . 2))
  2593. "Alist associating values from `ebnf-terminal-shape' to a bit vector.
  2594. See documentation for `ebnf-terminal-shape', `ebnf-non-terminal-shape' and
  2595. `ebnf-chart-shape'.")
  2596. (defvar ebnf-limit nil)
  2597. (defvar ebnf-action nil)
  2598. (defvar ebnf-action-list nil)
  2599. (defvar ebnf-default-p nil)
  2600. (defvar ebnf-font-height-P 0)
  2601. (defvar ebnf-font-height-T 0)
  2602. (defvar ebnf-font-height-NT 0)
  2603. (defvar ebnf-font-height-S 0)
  2604. (defvar ebnf-font-height-E 0)
  2605. (defvar ebnf-font-height-R 0)
  2606. (defvar ebnf-font-width-P 0)
  2607. (defvar ebnf-font-width-T 0)
  2608. (defvar ebnf-font-width-NT 0)
  2609. (defvar ebnf-font-width-S 0)
  2610. (defvar ebnf-font-width-E 0)
  2611. (defvar ebnf-font-width-R 0)
  2612. (defvar ebnf-space-T 0)
  2613. (defvar ebnf-space-NT 0)
  2614. (defvar ebnf-space-S 0)
  2615. (defvar ebnf-space-E 0)
  2616. (defvar ebnf-space-R 0)
  2617. (defvar ebnf-basic-width-extra 0)
  2618. (defvar ebnf-basic-width 0)
  2619. (defvar ebnf-basic-height 0)
  2620. (defvar ebnf-basic-empty-height 0)
  2621. (defvar ebnf-vertical-space 0)
  2622. (defvar ebnf-horizontal-space 0)
  2623. (defvar ebnf-settings nil)
  2624. (defvar ebnf-fonts-required nil)
  2625. (defconst ebnf-debug
  2626. "
  2627. % === begin EBNF procedures to help debugging
  2628. % Mark visually current point: string debug
  2629. /debug
  2630. {/-s- exch def
  2631. currentpoint
  2632. gsave -s- show grestore
  2633. gsave
  2634. 20 20 rlineto
  2635. 0 -40 rlineto
  2636. -40 40 rlineto
  2637. 0 -40 rlineto
  2638. 20 20 rlineto
  2639. stroke
  2640. grestore
  2641. moveto
  2642. }def
  2643. % Show number value: number string debug-number
  2644. /debug-number
  2645. {gsave
  2646. 20 0 rmoveto show ([) show 60 string cvs show (]) show
  2647. grestore
  2648. }def
  2649. % === end EBNF procedures to help debugging
  2650. "
  2651. "This is intended to help debugging PostScript programming.")
  2652. (defconst ebnf-prologue
  2653. "
  2654. % === begin EBNF engine
  2655. % --- Basic Definitions
  2656. /fS F
  2657. /SpaceS FontHeight 0.5 mul def
  2658. /HeightS FontHeight FontHeight add def
  2659. /fE F
  2660. /SpaceE FontHeight 0.5 mul def
  2661. /HeightE FontHeight FontHeight add def
  2662. /fR F
  2663. /SpaceR FontHeight 0.5 mul def
  2664. /HeightR FontHeight FontHeight add def
  2665. /fT F
  2666. /SpaceT FontHeight 0.5 mul def
  2667. /HeightT FontHeight FontHeight add def
  2668. /fNT F
  2669. /SpaceNT FontHeight 0.5 mul def
  2670. /HeightNT FontHeight FontHeight add def
  2671. /T HeightT HeightNT add 0.5 mul def
  2672. /hT T 0.5 mul def
  2673. /hT2 hT 0.5 mul ArrowScale mul def
  2674. /hT4 hT 0.25 mul ArrowScale mul def
  2675. /Er 0.1 def % Error factor
  2676. /c{currentpoint}bind def
  2677. /xyi{/xi c /yi exch def def}bind def
  2678. /xyo{/xo c /yo exch def def}bind def
  2679. /xyp{/xp c /yp exch def def}bind def
  2680. /xyt{/xt c /yt exch def def}bind def
  2681. % vertical movement: x y height vm
  2682. /vm{add moveto}bind def
  2683. % horizontal movement: x y width hm
  2684. /hm{3 -1 roll exch add exch moveto}bind def
  2685. % set color: [R G B] SetRGB
  2686. /SetRGB{aload pop setrgbcolor}bind def
  2687. % filling gray area: gray-scale FillGray
  2688. /FillGray{gsave setgray fill grestore}bind def
  2689. % filling color area: [R G B] FillRGB
  2690. /FillRGB{gsave SetRGB fill grestore}bind def
  2691. /Stroke{LineWidth setlinewidth LineColor SetRGB stroke}bind def
  2692. /StrokeShape{borderwidth setlinewidth bordercolor SetRGB stroke}bind def
  2693. /Gstroke{gsave Stroke grestore}bind def
  2694. % Empty Line: width EL
  2695. /EL{0 rlineto Gstroke}bind def
  2696. % --- Arrows
  2697. /Down{hT2 neg hT4 neg rlineto}bind def
  2698. /Arrow
  2699. {hT2 neg hT4 rmoveto
  2700. hT2 hT4 neg rlineto
  2701. Down
  2702. }bind def
  2703. /ArrowPath{c newpath moveto Arrow closepath}bind def
  2704. /UpPath
  2705. {c newpath moveto
  2706. hT2 neg 0 rmoveto
  2707. 0 hT4 rlineto
  2708. hT2 hT4 neg rlineto
  2709. closepath
  2710. }bind def
  2711. /DownPath
  2712. {c newpath moveto
  2713. hT2 neg 0 rmoveto
  2714. 0 hT4 neg rlineto
  2715. hT2 hT4 rlineto
  2716. closepath
  2717. }bind def
  2718. %>Right Arrow: RA
  2719. % \\
  2720. % *---+
  2721. % /
  2722. /RA-vector
  2723. [{} % 0 - none
  2724. {hT2 neg hT4 rlineto} % 1 - semi-up
  2725. {Down} % 2 - semi-down
  2726. {Arrow} % 3 - simple
  2727. {Gstroke ArrowPath} % 4 - transparent
  2728. {Gstroke ArrowPath 1 FillGray} % 5 - hollow
  2729. {Gstroke ArrowPath LineColor FillRGB} % 6 - full
  2730. {Gstroke UpPath 1 FillGray} % 7 - semi-up-hollow
  2731. {Gstroke UpPath LineColor FillRGB} % 8 - semi-up-full
  2732. {Gstroke DownPath 1 FillGray} % 9 - semi-down-hollow
  2733. {Gstroke DownPath LineColor FillRGB} % 10 - semi-down-full
  2734. {Gstroke gsave UserArrow grestore} % 11 - user
  2735. ]def
  2736. /RA
  2737. {hT 0 rlineto
  2738. c
  2739. RA-vector ArrowShape get exec
  2740. Gstroke
  2741. moveto
  2742. ExtraWidth 0 rmoveto
  2743. }def
  2744. % rotation DrawArrow
  2745. /DrawArrow
  2746. {gsave
  2747. 0 0 translate
  2748. rotate
  2749. RA
  2750. c
  2751. grestore
  2752. rmoveto
  2753. }def
  2754. %>Left Arrow: LA
  2755. % /
  2756. % +---*
  2757. % \\
  2758. /LA{180 DrawArrow}def
  2759. %>Up Arrow: UA
  2760. % +
  2761. % /|\\
  2762. % |
  2763. % *
  2764. /UA{90 DrawArrow}def
  2765. %>Down Arrow: DA
  2766. % *
  2767. % |
  2768. % \\|/
  2769. % +
  2770. /DA{270 DrawArrow}def
  2771. % --- Corners
  2772. %>corner Right Descendant: height arrow corner_RD
  2773. % _ | arrow
  2774. % / height > 0 | 0 - none
  2775. % | | 1 - right
  2776. % * ---------- | 2 - left
  2777. % | | 3 - vertical
  2778. % \\ height < 0 |
  2779. % - |
  2780. /cRD0-vector
  2781. [% 0 - none
  2782. {0 h rlineto
  2783. hT 0 rlineto}
  2784. % 1 - right
  2785. {0 h rlineto
  2786. RA}
  2787. % 2 - left
  2788. {hT 0 rmoveto xyi
  2789. LA
  2790. 0 h neg rlineto
  2791. xi yi moveto}
  2792. % 3 - vertical
  2793. {hT h rmoveto xyi
  2794. hT neg 0 rlineto
  2795. h 0 gt{DA}{UA}ifelse
  2796. xi yi moveto}
  2797. ]def
  2798. /cRD-vector
  2799. [{cRD0-vector arrow get exec} % 0 - miter
  2800. {0 0 0 h hT h rcurveto} % 1 - rounded
  2801. {hT h rlineto} % 2 - bevel
  2802. ]def
  2803. /corner_RD
  2804. {/arrow exch def /h exch def
  2805. cRD-vector ChartShape get exec
  2806. Gstroke
  2807. }def
  2808. %>corner Right Ascendant: height arrow corner_RA
  2809. % | arrow
  2810. % | height > 0 | 0 - none
  2811. % / | 1 - right
  2812. % *- ---------- | 2 - left
  2813. % \\ | 3 - vertical
  2814. % | height < 0 |
  2815. % |
  2816. /cRA0-vector
  2817. [% 0 - none
  2818. {hT 0 rlineto
  2819. 0 h rlineto}
  2820. % 1 - right
  2821. {RA
  2822. 0 h rlineto}
  2823. % 2 - left
  2824. {hT h rmoveto xyi
  2825. 0 h neg rlineto
  2826. LA
  2827. xi yi moveto}
  2828. % 3 - vertical
  2829. {hT h rmoveto xyi
  2830. h 0 gt{DA}{UA}ifelse
  2831. hT neg 0 rlineto
  2832. xi yi moveto}
  2833. ]def
  2834. /cRA-vector
  2835. [{cRA0-vector arrow get exec} % 0 - miter
  2836. {0 0 hT 0 hT h rcurveto} % 1 - rounded
  2837. {hT h rlineto} % 2 - bevel
  2838. ]def
  2839. /corner_RA
  2840. {/arrow exch def /h exch def
  2841. cRA-vector ChartShape get exec
  2842. Gstroke
  2843. }def
  2844. %>corner Left Descendant: height arrow corner_LD
  2845. % _ | arrow
  2846. % \\ height > 0 | 0 - none
  2847. % | | 1 - right
  2848. % * ---------- | 2 - left
  2849. % | | 3 - vertical
  2850. % / height < 0 |
  2851. % - |
  2852. /cLD0-vector
  2853. [% 0 - none
  2854. {0 h rlineto
  2855. hT neg 0 rlineto}
  2856. % 1 - right
  2857. {hT neg h rmoveto xyi
  2858. RA
  2859. 0 h neg rlineto
  2860. xi yi moveto}
  2861. % 2 - left
  2862. {0 h rlineto
  2863. LA}
  2864. % 3 - vertical
  2865. {hT neg h rmoveto xyi
  2866. hT 0 rlineto
  2867. h 0 gt{DA}{UA}ifelse
  2868. xi yi moveto}
  2869. ]def
  2870. /cLD-vector
  2871. [{cLD0-vector arrow get exec} % 0 - miter
  2872. {0 0 0 h hT neg h rcurveto} % 1 - rounded
  2873. {hT neg h rlineto} % 2 - bevel
  2874. ]def
  2875. /corner_LD
  2876. {/arrow exch def /h exch def
  2877. cLD-vector ChartShape get exec
  2878. Gstroke
  2879. }def
  2880. %>corner Left Ascendant: height arrow corner_LA
  2881. % | arrow
  2882. % | height > 0 | 0 - none
  2883. % \\ | 1 - right
  2884. % -* ---------- | 2 - left
  2885. % / | 3 - vertical
  2886. % | height < 0 |
  2887. % |
  2888. /cLA0-vector
  2889. [% 0 - none
  2890. {hT neg 0 rlineto
  2891. 0 h rlineto}
  2892. % 1 - right
  2893. {hT neg h rmoveto xyi
  2894. 0 h neg rlineto
  2895. RA
  2896. xi yi moveto}
  2897. % 2 - left
  2898. {LA
  2899. 0 h rlineto}
  2900. % 3 - vertical
  2901. {hT neg h rmoveto xyi
  2902. h 0 gt{DA}{UA}ifelse
  2903. hT 0 rlineto
  2904. xi yi moveto}
  2905. ]def
  2906. /cLA-vector
  2907. [{cLA0-vector arrow get exec} % 0 - miter
  2908. {0 0 hT neg 0 hT neg h rcurveto} % 1 - rounded
  2909. {hT neg h rlineto} % 2 - bevel
  2910. ]def
  2911. /corner_LA
  2912. {/arrow exch def /h exch def
  2913. cLA-vector ChartShape get exec
  2914. Gstroke
  2915. }def
  2916. % --- Flow Stuff
  2917. % height prepare-height |- line_height corner_height corner_height
  2918. /prepare-height
  2919. {dup 0 gt
  2920. {T sub hT}
  2921. {T add hT neg}ifelse
  2922. dup
  2923. }def
  2924. %>Left Alternative: height LAlt
  2925. % _
  2926. % /
  2927. % | height > 0
  2928. % |
  2929. % /
  2930. % *- ----------
  2931. % \\
  2932. % |
  2933. % | height < 0
  2934. % \\
  2935. % -
  2936. /LAlt
  2937. {dup 0 eq
  2938. {T exch rlineto}
  2939. {dup abs T lt
  2940. {0.5 mul dup
  2941. 1 corner_RA
  2942. 0 corner_RD}
  2943. {prepare-height
  2944. 1 corner_RA
  2945. exch 0 exch rlineto
  2946. 0 corner_RD
  2947. }ifelse
  2948. }ifelse
  2949. }def
  2950. %>Left Loop: height LLoop
  2951. % _
  2952. % /
  2953. % | height > 0
  2954. % |
  2955. % \\
  2956. % -* ----------
  2957. % /
  2958. % |
  2959. % | height < 0
  2960. % \\
  2961. % -
  2962. /LLoop
  2963. {prepare-height
  2964. 3 corner_LA
  2965. exch 0 exch rlineto
  2966. 0 corner_RD
  2967. }def
  2968. %>Right Alternative: height RAlt
  2969. % _
  2970. % \\
  2971. % | height > 0
  2972. % |
  2973. % \\
  2974. % -* ----------
  2975. % /
  2976. % |
  2977. % | height < 0
  2978. % /
  2979. % -
  2980. /RAlt
  2981. {dup 0 eq
  2982. {T neg exch rlineto}
  2983. {dup abs T lt
  2984. {0.5 mul dup
  2985. 1 corner_LA
  2986. 0 corner_LD}
  2987. {prepare-height
  2988. 1 corner_LA
  2989. exch 0 exch rlineto
  2990. 0 corner_LD
  2991. }ifelse
  2992. }ifelse
  2993. }def
  2994. %>Right Loop: height RLoop
  2995. % _
  2996. % \\
  2997. % | height > 0
  2998. % |
  2999. % /
  3000. % *- ----------
  3001. % \\
  3002. % |
  3003. % | height < 0
  3004. % /
  3005. % -
  3006. /RLoop
  3007. {prepare-height
  3008. 1 corner_RA
  3009. exch 0 exch rlineto
  3010. 0 corner_LD
  3011. }def
  3012. % --- Terminal, Non-terminal and Special Basics
  3013. % string width prepare-width |- string
  3014. /prepare-width
  3015. {/width exch def
  3016. dup stringwidth pop space add space add width exch sub ExtraWidth sub 0.5 mul
  3017. /w exch def
  3018. }def
  3019. % string width begin-right
  3020. /begin-right
  3021. {xyo
  3022. prepare-width
  3023. w hT sub EL
  3024. RA
  3025. }def
  3026. % end-right
  3027. /end-right
  3028. {xo width add Er add yo moveto
  3029. w Er add neg EL
  3030. xo yo moveto
  3031. }def
  3032. % string width begin-left
  3033. /begin-left
  3034. {xyo
  3035. prepare-width
  3036. w EL
  3037. }def
  3038. % end-left
  3039. /end-left
  3040. {xo width add Er add yo moveto
  3041. hT w sub Er add EL
  3042. LA
  3043. xo yo moveto
  3044. }def
  3045. /ShapePath-vector
  3046. [% 0 - miter
  3047. {xx yy moveto
  3048. xx YY lineto
  3049. XX YY lineto
  3050. XX yy lineto}
  3051. % 1 - rounded
  3052. {/half YY yy sub 0.5 mul abs def
  3053. xx half add YY moveto
  3054. 0 0 half neg 0 half neg half neg rcurveto
  3055. 0 0 0 half neg half half neg rcurveto
  3056. XX xx sub abs half sub half sub 0 rlineto
  3057. 0 0 half 0 half half rcurveto
  3058. 0 0 0 half half neg half rcurveto}
  3059. % 2 - bevel
  3060. {/quarter YY yy sub 0.25 mul abs def
  3061. xx quarter add YY moveto
  3062. quarter neg quarter neg rlineto
  3063. 0 quarter quarter add neg rlineto
  3064. quarter quarter neg rlineto
  3065. XX xx sub abs quarter sub quarter sub 0 rlineto
  3066. quarter quarter rlineto
  3067. 0 quarter quarter add rlineto
  3068. quarter neg quarter rlineto}
  3069. ]def
  3070. /doShapePath
  3071. {newpath
  3072. ShapePath-vector shape get exec
  3073. closepath
  3074. }def
  3075. /doShapeShadow
  3076. {gsave
  3077. Xshadow Xshadow add Xshadow add
  3078. Yshadow Yshadow add Yshadow add translate
  3079. doShapePath
  3080. 0.9 FillGray
  3081. grestore
  3082. }def
  3083. /doShape
  3084. {gsave
  3085. doShapePath
  3086. shapecolor FillRGB
  3087. StrokeShape
  3088. grestore
  3089. }def
  3090. % string SBound |- string
  3091. /SBound
  3092. {/xx c dup /yy exch def
  3093. FontHeight add /YY exch def def
  3094. dup stringwidth pop xx add /XX exch def
  3095. Effect 8 and 0 ne
  3096. {/yy yy YShadow add def
  3097. /XX XX XShadow add def
  3098. }if
  3099. }def
  3100. % string SBox
  3101. /SBox
  3102. {gsave
  3103. c space sub moveto
  3104. SBound
  3105. /XX XX space add space add def
  3106. /YY YY space add def
  3107. /yy yy space sub def
  3108. shadow{doShapeShadow}if
  3109. doShape
  3110. space Descent abs rmoveto
  3111. foreground SetRGB S
  3112. grestore
  3113. }def
  3114. % --- Terminal
  3115. % TeRminal: string TR
  3116. /TR
  3117. {/Effect EffectT def
  3118. /shape ShapeT def
  3119. /shapecolor BackgroundT def
  3120. /borderwidth BorderWidthT def
  3121. /bordercolor BorderColorT def
  3122. /foreground ForegroundT def
  3123. /shadow ShadowT def
  3124. SBox
  3125. }def
  3126. %>Right Terminal: string width RT |- x y
  3127. /RT
  3128. {xyt
  3129. /fT F
  3130. /space SpaceT def
  3131. begin-right
  3132. TR
  3133. end-right
  3134. xt yt
  3135. }def
  3136. %>Left Terminal: string width LT |- x y
  3137. /LT
  3138. {xyt
  3139. /fT F
  3140. /space SpaceT def
  3141. begin-left
  3142. TR
  3143. end-left
  3144. xt yt
  3145. }def
  3146. %>Right Terminal Default: string width RTD |- x y
  3147. /RTD
  3148. {/-save- BorderWidthT def
  3149. /BorderWidthT BorderWidthT DefaultWidth add def
  3150. RT
  3151. /BorderWidthT -save- def
  3152. }def
  3153. %>Left Terminal Default: string width LTD |- x y
  3154. /LTD
  3155. {/-save- BorderWidthT def
  3156. /BorderWidthT BorderWidthT DefaultWidth add def
  3157. LT
  3158. /BorderWidthT -save- def
  3159. }def
  3160. % --- Non-Terminal
  3161. % Non-Terminal: string NT
  3162. /NT
  3163. {/Effect EffectNT def
  3164. /shape ShapeNT def
  3165. /shapecolor BackgroundNT def
  3166. /borderwidth BorderWidthNT def
  3167. /bordercolor BorderColorNT def
  3168. /foreground ForegroundNT def
  3169. /shadow ShadowNT def
  3170. SBox
  3171. }def
  3172. %>Right Non-Terminal: string width RNT |- x y
  3173. /RNT
  3174. {xyt
  3175. /fNT F
  3176. /space SpaceNT def
  3177. begin-right
  3178. NT
  3179. end-right
  3180. xt yt
  3181. }def
  3182. %>Left Non-Terminal: string width LNT |- x y
  3183. /LNT
  3184. {xyt
  3185. /fNT F
  3186. /space SpaceNT def
  3187. begin-left
  3188. NT
  3189. end-left
  3190. xt yt
  3191. }def
  3192. %>Right Non-Terminal Default: string width RNTD |- x y
  3193. /RNTD
  3194. {/-save- BorderWidthNT def
  3195. /BorderWidthNT BorderWidthNT DefaultWidth add def
  3196. RNT
  3197. /BorderWidthNT -save- def
  3198. }def
  3199. %>Left Non-Terminal Default: string width LNTD |- x y
  3200. /LNTD
  3201. {/-save- BorderWidthNT def
  3202. /BorderWidthNT BorderWidthNT DefaultWidth add def
  3203. LNT
  3204. /BorderWidthNT -save- def
  3205. }def
  3206. % --- Special
  3207. % SPecial: string SP
  3208. /SP
  3209. {/Effect EffectS def
  3210. /shape ShapeS def
  3211. /shapecolor BackgroundS def
  3212. /borderwidth BorderWidthS def
  3213. /bordercolor BorderColorS def
  3214. /foreground ForegroundS def
  3215. /shadow ShadowS def
  3216. SBox
  3217. }def
  3218. %>Right SPecial: string width RSP |- x y
  3219. /RSP
  3220. {xyt
  3221. /fS F
  3222. /space SpaceS def
  3223. begin-right
  3224. SP
  3225. end-right
  3226. xt yt
  3227. }def
  3228. %>Left SPecial: string width LSP |- x y
  3229. /LSP
  3230. {xyt
  3231. /fS F
  3232. /space SpaceS def
  3233. begin-left
  3234. SP
  3235. end-left
  3236. xt yt
  3237. }def
  3238. %>Right SPecial Default: string width RSPD |- x y
  3239. /RSPD
  3240. {/-save- BorderWidthS def
  3241. /BorderWidthS BorderWidthS DefaultWidth add def
  3242. RSP
  3243. /BorderWidthS -save- def
  3244. }def
  3245. %>Left SPecial Default: string width LSPD |- x y
  3246. /LSPD
  3247. {/-save- BorderWidthS def
  3248. /BorderWidthS BorderWidthS DefaultWidth add def
  3249. LSP
  3250. /BorderWidthS -save- def
  3251. }def
  3252. % --- Repeat and Except basics
  3253. /begin-direction
  3254. {/w width rwidth sub 0.5 mul def
  3255. width 0 rmoveto}def
  3256. /end-direction
  3257. {gsave
  3258. /xx c entry add /YY exch def def
  3259. /yy YY height sub def
  3260. /XX xx rwidth add def
  3261. shadow{doShapeShadow}if
  3262. doShape
  3263. grestore
  3264. }def
  3265. /right-direction
  3266. {begin-direction
  3267. w neg EL
  3268. xt yt moveto
  3269. w hT sub EL RA
  3270. end-direction
  3271. }def
  3272. /left-direction
  3273. {begin-direction
  3274. hT w sub EL LA
  3275. xt yt moveto
  3276. w EL
  3277. end-direction
  3278. }def
  3279. % --- Repeat
  3280. % entry height width rwidth begin-repeat
  3281. /begin-repeat
  3282. {/rwidth exch def
  3283. /width exch def
  3284. /height exch def
  3285. /entry exch def
  3286. /fR F
  3287. /space SpaceR def
  3288. /Effect EffectR def
  3289. /shape ShapeR def
  3290. /shapecolor BackgroundR def
  3291. /borderwidth BorderWidthR def
  3292. /bordercolor BorderColorR def
  3293. /foreground ForegroundR def
  3294. /shadow ShadowR def
  3295. xyt
  3296. }def
  3297. % string end-repeat |- x y
  3298. /end-repeat
  3299. {gsave
  3300. space Descent rmoveto
  3301. foreground SetRGB S
  3302. c Descent sub
  3303. grestore
  3304. exch space add exch moveto
  3305. xt yt
  3306. }def
  3307. %>Right RePeat: string entry height width rwidth RRP |- x y
  3308. /RRP{begin-repeat right-direction end-repeat}def
  3309. %>Left RePeat: string entry height width rwidth LRP |- x y
  3310. /LRP{begin-repeat left-direction end-repeat}def
  3311. % --- Except
  3312. % entry height width rwidth begin-except
  3313. /begin-except
  3314. {/rwidth exch def
  3315. /width exch def
  3316. /height exch def
  3317. /entry exch def
  3318. /fE F
  3319. /space SpaceE def
  3320. /Effect EffectE def
  3321. /shape ShapeE def
  3322. /shapecolor BackgroundE def
  3323. /borderwidth BorderWidthE def
  3324. /bordercolor BorderColorE def
  3325. /foreground ForegroundE def
  3326. /shadow ShadowE def
  3327. xyt
  3328. }def
  3329. % x-width end-except |- x y
  3330. /end-except
  3331. {gsave
  3332. space space add add Descent rmoveto
  3333. (-) foreground SetRGB S
  3334. grestore
  3335. space 0 rmoveto
  3336. xt yt
  3337. }def
  3338. %>Right EXcept: x-width entry height width rwidth REX |- x y
  3339. /REX{begin-except right-direction end-except}def
  3340. %>Left EXcept: x-width entry height width rwidth LEX |- x y
  3341. /LEX{begin-except left-direction end-except}def
  3342. % --- Sequence
  3343. %>Beginning Of Sequence: BOS |- x y
  3344. /BOS{currentpoint}bind def
  3345. %>End Of Sequence: x y x1 y1 EOS |- x y
  3346. /EOS{pop pop}bind def
  3347. % --- Production
  3348. %>Beginning Of Production: string width height BOP |- y x
  3349. /BOP
  3350. {xyp
  3351. neg yp add /yw exch def
  3352. xp add T sub /xw exch def
  3353. dup length 0 gt % empty string ==> no production name
  3354. {/Effect EffectP def
  3355. /fP F ForegroundP SetRGB BackgroundP aload pop true BG S
  3356. /Effect 0 def
  3357. ( :) S false BG}if
  3358. xw yw moveto
  3359. hT EL RA
  3360. xp yw moveto
  3361. T EL
  3362. yp xp
  3363. }def
  3364. %>End Of Production: y x delta EOP
  3365. /EOPH{add exch moveto}bind def % horizontal
  3366. /EOPV{exch pop sub 0 exch moveto}bind def % vertical
  3367. % --- Empty Alternative
  3368. %>Empty Alternative: width EA |- x y
  3369. /EA
  3370. {gsave
  3371. Er add 0 rlineto
  3372. Stroke
  3373. grestore
  3374. c
  3375. }def
  3376. % --- Alternative
  3377. %>AlTernative: h1 h2 ... hn n width AT |- x y
  3378. /AT
  3379. {xyo xo add /xw exch def
  3380. xw yo moveto
  3381. Er EL
  3382. {xw yo moveto
  3383. dup RAlt
  3384. xo yo moveto
  3385. LAlt}repeat
  3386. xo yo
  3387. }def
  3388. % --- Optional
  3389. %>OPtional: height width OP |- x y
  3390. /OP
  3391. {xyo
  3392. T sub /ow exch def
  3393. ow Er sub 0 rmoveto
  3394. T Er add EL
  3395. neg dup RAlt
  3396. ow T sub neg EL
  3397. xo yo moveto
  3398. LAlt
  3399. xo yo moveto
  3400. T EL
  3401. xo yo
  3402. }def
  3403. % --- List Flow
  3404. %>One or More: height width OM |- x y
  3405. /OM
  3406. {xyo
  3407. /ow exch def
  3408. ow Er add 0 rmoveto
  3409. T Er add neg EL
  3410. dup RLoop
  3411. xo T add yo moveto
  3412. LLoop
  3413. xo yo moveto
  3414. T EL
  3415. xo yo
  3416. }def
  3417. %>Zero or More: h2 h1 width ZM |- x y
  3418. /ZM
  3419. {xyo
  3420. Er add EL
  3421. Er neg 0 rmoveto
  3422. dup RAlt
  3423. exch dup RLoop
  3424. xo yo moveto
  3425. exch dup LAlt
  3426. exch LLoop
  3427. yo add xo T add exch moveto
  3428. xo yo
  3429. }def
  3430. % === end EBNF engine
  3431. "
  3432. "EBNF PostScript prologue")
  3433. (defconst ebnf-eps-prologue
  3434. "
  3435. /#ebnf2ps#dict 230 dict def
  3436. #ebnf2ps#dict begin
  3437. % Initialize variables to avoid name-conflicting with document variables.
  3438. % This is the case when using `bind' operator.
  3439. /-fillp- 0 def /h 0 def
  3440. /-ox- 0 def /half 0 def
  3441. /-oy- 0 def /height 0 def
  3442. /-save- 0 def /ow 0 def
  3443. /Ascent 0 def /quarter 0 def
  3444. /Descent 0 def /rXX 0 def
  3445. /Effect 0 def /rYY 0 def
  3446. /FontHeight 0 def /rwidth 0 def
  3447. /LineThickness 0 def /rxx 0 def
  3448. /OverlinePosition 0 def /ryy 0 def
  3449. /SpaceBackground 0 def /shadow 0 def
  3450. /StrikeoutPosition 0 def /shape 0 def
  3451. /UnderlinePosition 0 def /shapecolor 0 def
  3452. /XBox 0 def /space 0 def
  3453. /XX 0 def /st 1 string def
  3454. /Xshadow 0 def /w 0 def
  3455. /YBox 0 def /width 0 def
  3456. /YY 0 def /xi 0 def
  3457. /Yshadow 0 def /xo 0 def
  3458. /arrow 0 def /xp 0 def
  3459. /bg false def /xt 0 def
  3460. /bgcolor 0 def /xw 0 def
  3461. /bordercolor 0 def /xx 0 def
  3462. /borderwidth 0 def /yi 0 def
  3463. /dd 0 def /yo 0 def
  3464. /entry 0 def /yp 0 def
  3465. /foreground 0 def /yt 0 def
  3466. /yy 0 def
  3467. % ISOLatin1Encoding stolen from ps_init.ps in GhostScript 2.6.1.4:
  3468. /ISOLatin1Encoding where
  3469. {pop}
  3470. {% -- The ISO Latin-1 encoding vector isn't known, so define it.
  3471. % -- The first half is the same as the standard encoding,
  3472. % -- except for minus instead of hyphen at code 055.
  3473. /ISOLatin1Encoding
  3474. StandardEncoding 0 45 getinterval aload pop
  3475. /minus
  3476. StandardEncoding 46 82 getinterval aload pop
  3477. %*** NOTE: the following are missing in the Adobe documentation,
  3478. %*** but appear in the displayed table:
  3479. %*** macron at 0225, dieresis at 0230, cedilla at 0233, space at 0240.
  3480. % 0200 (128)
  3481. /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
  3482. /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
  3483. /dotlessi /grave /acute /circumflex /tilde /macron /breve /dotaccent
  3484. /dieresis /.notdef /ring /cedilla /.notdef /hungarumlaut /ogonek /caron
  3485. % 0240 (160)
  3486. /space /exclamdown /cent /sterling
  3487. /currency /yen /brokenbar /section
  3488. /dieresis /copyright /ordfeminine /guillemotleft
  3489. /logicalnot /hyphen /registered /macron
  3490. /degree /plusminus /twosuperior /threesuperior
  3491. /acute /mu /paragraph /periodcentered
  3492. /cedilla /onesuperior /ordmasculine /guillemotright
  3493. /onequarter /onehalf /threequarters /questiondown
  3494. % 0300 (192)
  3495. /Agrave /Aacute /Acircumflex /Atilde
  3496. /Adieresis /Aring /AE /Ccedilla
  3497. /Egrave /Eacute /Ecircumflex /Edieresis
  3498. /Igrave /Iacute /Icircumflex /Idieresis
  3499. /Eth /Ntilde /Ograve /Oacute
  3500. /Ocircumflex /Otilde /Odieresis /multiply
  3501. /Oslash /Ugrave /Uacute /Ucircumflex
  3502. /Udieresis /Yacute /Thorn /germandbls
  3503. % 0340 (224)
  3504. /agrave /aacute /acircumflex /atilde
  3505. /adieresis /aring /ae /ccedilla
  3506. /egrave /eacute /ecircumflex /edieresis
  3507. /igrave /iacute /icircumflex /idieresis
  3508. /eth /ntilde /ograve /oacute
  3509. /ocircumflex /otilde /odieresis /divide
  3510. /oslash /ugrave /uacute /ucircumflex
  3511. /udieresis /yacute /thorn /ydieresis
  3512. 256 packedarray def
  3513. }ifelse
  3514. /reencodeFontISO %def
  3515. {dup
  3516. length 12 add dict % Make a new font (a new dict the same size
  3517. % as the old one) with room for our new symbols.
  3518. begin % Make the new font the current dictionary.
  3519. {1 index /FID ne
  3520. {def}{pop pop}ifelse
  3521. }forall % Copy each of the symbols from the old dictionary
  3522. % to the new one except for the font ID.
  3523. currentdict /FontType get 0 ne
  3524. {/Encoding ISOLatin1Encoding def}if % Override the encoding with
  3525. % the ISOLatin1 encoding.
  3526. % Use the font's bounding box to determine the ascent, descent,
  3527. % and overall height; don't forget that these values have to be
  3528. % transformed using the font's matrix.
  3529. % ^ (x2 y2)
  3530. % | |
  3531. % | v
  3532. % | +----+ - -
  3533. % | | | ^
  3534. % | | | | Ascent (usually > 0)
  3535. % | | | |
  3536. % (0 0) -> +--+----+-------->
  3537. % | | |
  3538. % | | v Descent (usually < 0)
  3539. % (x1 y1) --> +----+ - -
  3540. currentdict /FontType get 0 ne
  3541. {/FontBBox load aload pop % -- x1 y1 x2 y2
  3542. FontMatrix transform /Ascent exch def pop
  3543. FontMatrix transform /Descent exch def pop}
  3544. {/PrimaryFont FDepVector 0 get def
  3545. PrimaryFont /FontBBox get aload pop
  3546. PrimaryFont /FontMatrix get transform /Ascent exch def pop
  3547. PrimaryFont /FontMatrix get transform /Descent exch def pop
  3548. }ifelse
  3549. /FontHeight Ascent Descent sub def % use `sub' because descent < 0
  3550. % Define these in case they're not in the FontInfo
  3551. % (also, here they're easier to get to).
  3552. /UnderlinePosition Descent 0.70 mul def
  3553. /OverlinePosition Descent UnderlinePosition sub Ascent add def
  3554. /StrikeoutPosition Ascent 0.30 mul def
  3555. /LineThickness FontHeight 0.05 mul def
  3556. /Xshadow FontHeight 0.08 mul def
  3557. /Yshadow FontHeight -0.09 mul def
  3558. /SpaceBackground Descent neg UnderlinePosition add def
  3559. /XBox Descent neg def
  3560. /YBox LineThickness 0.7 mul def
  3561. currentdict % Leave the new font on the stack
  3562. end % Stop using the font as the current dictionary
  3563. definefont % Put the font into the font dictionary
  3564. pop % Discard the returned font
  3565. }bind def
  3566. % Font definition
  3567. /DefFont{findfont exch scalefont reencodeFontISO}def
  3568. % Font selection
  3569. /F
  3570. {findfont
  3571. dup /Ascent get /Ascent exch def
  3572. dup /Descent get /Descent exch def
  3573. dup /FontHeight get /FontHeight exch def
  3574. dup /UnderlinePosition get /UnderlinePosition exch def
  3575. dup /OverlinePosition get /OverlinePosition exch def
  3576. dup /StrikeoutPosition get /StrikeoutPosition exch def
  3577. dup /LineThickness get /LineThickness exch def
  3578. dup /Xshadow get /Xshadow exch def
  3579. dup /Yshadow get /Yshadow exch def
  3580. dup /SpaceBackground get /SpaceBackground exch def
  3581. dup /XBox get /XBox exch def
  3582. dup /YBox get /YBox exch def
  3583. setfont
  3584. }def
  3585. /BG
  3586. {dup /bg exch def
  3587. {mark 4 1 roll ]}
  3588. {[ 1.0 1.0 1.0 ]}
  3589. ifelse
  3590. /bgcolor exch def
  3591. }def
  3592. % stack: --
  3593. /FillBgColor{bgcolor aload pop setrgbcolor fill}bind def
  3594. % stack: fill-or-not lower-x lower-y upper-x upper-y |- --
  3595. /doRect
  3596. {/rYY exch def
  3597. /rXX exch def
  3598. /ryy exch def
  3599. /rxx exch def
  3600. gsave
  3601. newpath
  3602. rXX rYY moveto
  3603. rxx rYY lineto
  3604. rxx ryy lineto
  3605. rXX ryy lineto
  3606. closepath
  3607. % top of stack: fill-or-not
  3608. {FillBgColor}
  3609. {LineThickness setlinewidth stroke}
  3610. ifelse
  3611. grestore
  3612. }bind def
  3613. % stack: string fill-or-not |- --
  3614. /doOutline
  3615. {/-fillp- exch def
  3616. /-ox- currentpoint /-oy- exch def def
  3617. gsave
  3618. LineThickness setlinewidth
  3619. {st 0 3 -1 roll put
  3620. st dup true charpath
  3621. -fillp- {gsave FillBgColor grestore}if
  3622. stroke stringwidth
  3623. -oy- add /-oy- exch def
  3624. -ox- add /-ox- exch def
  3625. -ox- -oy- moveto
  3626. }forall
  3627. grestore
  3628. -ox- -oy- moveto
  3629. }bind def
  3630. % stack: fill-or-not delta |- --
  3631. /doBox
  3632. {/dd exch def
  3633. xx XBox sub dd sub yy YBox sub dd sub
  3634. XX XBox add dd add YY YBox add dd add
  3635. doRect
  3636. }bind def
  3637. % stack: string |- --
  3638. /doShadow
  3639. {gsave
  3640. Xshadow Yshadow rmoveto
  3641. false doOutline
  3642. grestore
  3643. }bind def
  3644. % stack: position |- --
  3645. /Hline
  3646. {currentpoint exch pop add dup
  3647. gsave
  3648. newpath
  3649. xx exch moveto
  3650. XX exch lineto
  3651. closepath
  3652. LineThickness setlinewidth stroke
  3653. grestore
  3654. }bind def
  3655. % stack: string |- --
  3656. % effect: 1 - underline 2 - strikeout 4 - overline
  3657. % 8 - shadow 16 - box 32 - outline
  3658. /S
  3659. {/xx currentpoint dup Descent add /yy exch def
  3660. Ascent add /YY exch def def
  3661. dup stringwidth pop xx add /XX exch def
  3662. Effect 8 and 0 ne
  3663. {/yy yy Yshadow add def
  3664. /XX XX Xshadow add def
  3665. }if
  3666. bg
  3667. {true
  3668. Effect 16 and 0 ne
  3669. {SpaceBackground doBox}
  3670. {xx yy XX YY doRect}
  3671. ifelse
  3672. }if % background
  3673. Effect 16 and 0 ne{false 0 doBox}if % box
  3674. Effect 8 and 0 ne{dup doShadow}if % shadow
  3675. Effect 32 and 0 ne
  3676. {true doOutline} % outline
  3677. {show} % normal text
  3678. ifelse
  3679. Effect 1 and 0 ne{UnderlinePosition Hline}if % underline
  3680. Effect 2 and 0 ne{StrikeoutPosition Hline}if % strikeout
  3681. Effect 4 and 0 ne{OverlinePosition Hline}if % overline
  3682. }bind def
  3683. "
  3684. "EBNF EPS prologue")
  3685. (defconst ebnf-eps-begin
  3686. "
  3687. end
  3688. % x y #ebnf2ps#begin
  3689. /#ebnf2ps#begin
  3690. {#ebnf2ps#dict begin /#ebnf2ps#save save def
  3691. moveto false BG 0.0 0.0 0.0 setrgbcolor}def
  3692. /#ebnf2ps#end{showpage #ebnf2ps#save restore end}def
  3693. %%EndProlog
  3694. "
  3695. "EBNF EPS begin")
  3696. (defconst ebnf-eps-end
  3697. "#ebnf2ps#end
  3698. %%EOF
  3699. "
  3700. "EBNF EPS end")
  3701. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3702. ;; Header & Footer
  3703. (defun ebnf-eps-header-footer (value)
  3704. ;; evaluate header/footer value
  3705. ;; return a string or nil
  3706. (let ((tmp (if (symbolp value)
  3707. (cond ((fboundp value) (funcall value))
  3708. ((boundp value) (symbol-value value))
  3709. (t nil))
  3710. value)))
  3711. (and (stringp tmp) tmp)))
  3712. (defun ebnf-eps-header ()
  3713. ;; evaluate header value
  3714. (ebnf-eps-header-footer ebnf-eps-header))
  3715. (defun ebnf-eps-footer ()
  3716. ;; evaluate footer value
  3717. (ebnf-eps-header-footer ebnf-eps-footer))
  3718. ;; hacked fom `ps-output-string-prim' (ps-print.el)
  3719. (defun ebnf-eps-string (string)
  3720. (let* ((str (string-as-unibyte string))
  3721. (len (length str))
  3722. (index 0)
  3723. (new "(") ; insert start-string delimiter
  3724. start special)
  3725. ;; Find and quote special characters as necessary for PS
  3726. ;; This skips everything except control chars, non-ASCII chars, (, ) and \.
  3727. (while (setq start (string-match "[^]-~ -'*-[]" str index))
  3728. (setq special (aref str start)
  3729. new (concat new
  3730. (substring str index start)
  3731. (if (and (<= 0 special) (<= special 255))
  3732. (aref ps-string-escape-codes special)
  3733. ;; insert hexadecimal representation if character
  3734. ;; code is out of range
  3735. (format "\\%04X" special)))
  3736. index (1+ start)))
  3737. (concat new
  3738. (and (< index len)
  3739. (substring str index len))
  3740. ")"))) ; insert end-string delimiter
  3741. (defun ebnf-eps-header-footer-comment (str)
  3742. ;; parse header/footer comment string
  3743. (let ((len (1- (length str)))
  3744. (index 0)
  3745. new start fmt)
  3746. (while (setq start (string-match "%" str index))
  3747. (setq fmt (if (< start len) (aref str (1+ start)) ?\?)
  3748. new (concat new
  3749. (substring str index start)
  3750. (cond ((= fmt ?%) "%")
  3751. ((= fmt ?H) (ebnf-eps-header))
  3752. ((= fmt ?F) (ebnf-eps-footer))
  3753. (t nil)
  3754. ))
  3755. index (+ start 2)))
  3756. (ebnf-eps-string (concat new
  3757. (and (<= index len)
  3758. (substring str index (1+ len)))))))
  3759. (defun ebnf-eps-header-footer-p (value)
  3760. ;; return t if value is non-nil and is not an empty string
  3761. (not (or (null value)
  3762. (and (stringp value) (string= value "")))))
  3763. (defun ebnf-eps-header-comment (str)
  3764. ;; set header comment if header is on
  3765. (when (ebnf-eps-header-footer-p ebnf-eps-header)
  3766. (setq ebnf-eps-header-comment (ebnf-eps-header-footer-comment str))))
  3767. (defun ebnf-eps-footer-comment (str)
  3768. ;; set footer comment if footer is on
  3769. (when (ebnf-eps-header-footer-p ebnf-eps-footer)
  3770. (setq ebnf-eps-footer-comment (ebnf-eps-header-footer-comment str))))
  3771. (defun ebnf-eps-header-footer-file (filename)
  3772. ;; associate header and footer with a filename
  3773. (let ((filehf (assoc filename ebnf-eps-file-alist))
  3774. (header (or ebnf-eps-header-comment (ebnf-eps-header)))
  3775. (footer (or ebnf-eps-footer-comment (ebnf-eps-footer))))
  3776. (if (null filehf)
  3777. (setq ebnf-eps-file-alist (cons (list filename header footer)
  3778. ebnf-eps-file-alist))
  3779. (setcar (nthcdr 1 filehf) header)
  3780. (setcar (nthcdr 2 filehf) footer))))
  3781. (defun ebnf-eps-header-footer-set (filename)
  3782. ;; set header and footer from a filename
  3783. (let ((header-footer (assoc filename ebnf-eps-file-alist)))
  3784. (setq ebnf-eps-header-comment (nth 1 header-footer)
  3785. ebnf-eps-footer-comment (nth 2 header-footer))))
  3786. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3787. ;; Formatting
  3788. (defvar ebnf-format-float "%1.3f")
  3789. (defun ebnf-format-float (&rest floats)
  3790. (mapconcat
  3791. #'(lambda (float)
  3792. (format ebnf-format-float float))
  3793. floats
  3794. " "))
  3795. (defun ebnf-format-color (format-str color default)
  3796. (let* ((the-color (or color default))
  3797. (rgb (ps-color-scale the-color)))
  3798. (format format-str
  3799. (concat "["
  3800. (ebnf-format-float (nth 0 rgb) (nth 1 rgb) (nth 2 rgb))
  3801. "]")
  3802. the-color)))
  3803. (defvar ebnf-message-float "%3.2f")
  3804. (defsubst ebnf-message-float (format-str value)
  3805. (message format-str
  3806. (format ebnf-message-float value)))
  3807. (defvar ebnf-total 0)
  3808. (defvar ebnf-nprod 0)
  3809. (defsubst ebnf-message-info (messag)
  3810. (message "%s...%3d%%"
  3811. messag
  3812. (round (/ (* (setq ebnf-nprod (1+ ebnf-nprod)) 100.0) ebnf-total))))
  3813. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3814. ;; Macros
  3815. (defmacro ebnf-node-kind (vec &optional value)
  3816. (if value
  3817. `(aset ,vec 0 ,value)
  3818. `(aref ,vec 0)))
  3819. (defmacro ebnf-node-width-func (node width)
  3820. `(funcall (aref ,node 1) ,node ,width))
  3821. (defmacro ebnf-node-dimension-func (node &optional value)
  3822. (if value
  3823. `(aset ,node 2 ,value)
  3824. `(funcall (aref ,node 2) ,node)))
  3825. (defmacro ebnf-node-entry (vec &optional value)
  3826. (if value
  3827. `(aset ,vec 3 ,value)
  3828. `(aref ,vec 3)))
  3829. (defmacro ebnf-node-height (vec &optional value)
  3830. (if value
  3831. `(aset ,vec 4 ,value)
  3832. `(aref ,vec 4)))
  3833. (defmacro ebnf-node-width (vec &optional value)
  3834. (if value
  3835. `(aset ,vec 5 ,value)
  3836. `(aref ,vec 5)))
  3837. (defmacro ebnf-node-name (vec)
  3838. `(aref ,vec 6))
  3839. (defmacro ebnf-node-list (vec &optional value)
  3840. (if value
  3841. `(aset ,vec 6 ,value)
  3842. `(aref ,vec 6)))
  3843. (defmacro ebnf-node-default (vec)
  3844. `(aref ,vec 7))
  3845. (defmacro ebnf-node-production (vec &optional value)
  3846. (if value
  3847. `(aset ,vec 7 ,value)
  3848. `(aref ,vec 7)))
  3849. (defmacro ebnf-node-separator (vec &optional value)
  3850. (if value
  3851. `(aset ,vec 7 ,value)
  3852. `(aref ,vec 7)))
  3853. (defmacro ebnf-node-action (vec &optional value)
  3854. (if value
  3855. `(aset ,vec 8 ,value)
  3856. `(aref ,vec 8)))
  3857. (defmacro ebnf-node-generation (node)
  3858. `(funcall (ebnf-node-kind ,node) ,node))
  3859. (defmacro ebnf-max-width (prod)
  3860. `(max (ebnf-node-width ,prod)
  3861. (+ (* (length (ebnf-node-name ,prod))
  3862. ebnf-font-width-P)
  3863. ebnf-production-horizontal-space)))
  3864. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3865. ;; PostScript generation
  3866. (defun ebnf-generate-eps (ebnf-tree)
  3867. (let* ((ps-color-p (and ebnf-color-p (ps-color-device)))
  3868. (ps-print-color-scale (if ps-color-p
  3869. (float (car (ps-color-values "white")))
  3870. 1.0))
  3871. (ebnf-total (length ebnf-tree))
  3872. (ebnf-nprod 0)
  3873. (old-ps-output (symbol-function 'ps-output))
  3874. (old-ps-output-string (symbol-function 'ps-output-string))
  3875. (eps-buffer (get-buffer-create ebnf-eps-buffer-name))
  3876. ebnf-debug-ps error-msg horizontal
  3877. prod prod-name prod-width prod-height prod-list file-list)
  3878. ;; redefines `ps-output' and `ps-output-string'
  3879. (defalias 'ps-output 'ebnf-eps-output)
  3880. (defalias 'ps-output-string 'ps-output-string-prim)
  3881. ;; generate EPS file
  3882. (save-excursion
  3883. (condition-case data
  3884. (progn
  3885. (while ebnf-tree
  3886. (setq prod (car ebnf-tree)
  3887. prod-name (ebnf-node-name prod)
  3888. prod-width (ebnf-max-width prod)
  3889. prod-height (ebnf-node-height prod)
  3890. horizontal (memq (ebnf-node-action prod)
  3891. ebnf-action-list))
  3892. ;; generate production in EPS buffer
  3893. (with-current-buffer eps-buffer
  3894. (setq ebnf-eps-upper-x 0.0
  3895. ebnf-eps-upper-y 0.0
  3896. ebnf-eps-max-width prod-width
  3897. ebnf-eps-max-height prod-height)
  3898. (ebnf-generate-production prod))
  3899. (if (setq prod-list (cdr (assoc prod-name
  3900. ebnf-eps-production-list)))
  3901. ;; insert EPS buffer in all buffer associated with production
  3902. (ebnf-eps-production-list prod-list 'file-list horizontal
  3903. prod-width prod-height eps-buffer)
  3904. ;; write EPS file for production
  3905. (ebnf-eps-finish-and-write eps-buffer
  3906. (ebnf-eps-filename prod-name)))
  3907. ;; prepare for next loop
  3908. (with-current-buffer eps-buffer
  3909. (erase-buffer))
  3910. (setq ebnf-tree (cdr ebnf-tree)))
  3911. ;; write and kill temporary buffers
  3912. (ebnf-eps-write-kill-temp file-list t)
  3913. (setq file-list nil))
  3914. ;; handler
  3915. ((quit error)
  3916. (setq error-msg (error-message-string data)))))
  3917. ;; restore `ps-output' and `ps-output-string'
  3918. (defalias 'ps-output old-ps-output)
  3919. (defalias 'ps-output-string old-ps-output-string)
  3920. ;; kill temporary buffers
  3921. (kill-buffer eps-buffer)
  3922. (ebnf-eps-write-kill-temp file-list nil)
  3923. (and error-msg (error error-msg))
  3924. (message " ")))
  3925. ;; write and kill temporary buffers
  3926. (defun ebnf-eps-write-kill-temp (file-list write-p)
  3927. (while file-list
  3928. (let ((buffer (get-buffer (concat " *" (car file-list) "*"))))
  3929. (when buffer
  3930. (and write-p
  3931. (ebnf-eps-finish-and-write buffer (car file-list)))
  3932. (kill-buffer buffer)))
  3933. (setq file-list (cdr file-list))))
  3934. ;; insert EPS buffer in all buffer associated with production
  3935. (defun ebnf-eps-production-list (prod-list file-list-sym horizontal
  3936. prod-width prod-height eps-buffer)
  3937. (while prod-list
  3938. (add-to-list file-list-sym (car prod-list))
  3939. (with-current-buffer (get-buffer-create (concat " *" (car prod-list) "*"))
  3940. (goto-char (point-max))
  3941. (cond
  3942. ;; first production
  3943. ((zerop (buffer-size))
  3944. (setq ebnf-eps-upper-x 0.0
  3945. ebnf-eps-upper-y 0.0
  3946. ebnf-eps-max-width prod-width
  3947. ebnf-eps-max-height prod-height))
  3948. ;; horizontal
  3949. (horizontal
  3950. (ebnf-eop-horizontal ebnf-eps-prod-width)
  3951. (setq ebnf-eps-max-width (+ ebnf-eps-max-width
  3952. ebnf-production-horizontal-space
  3953. prod-width)
  3954. ebnf-eps-max-height (max ebnf-eps-max-height prod-height)))
  3955. ;; vertical
  3956. (t
  3957. (ebnf-eop-vertical ebnf-eps-max-height)
  3958. (setq ebnf-eps-upper-x (max ebnf-eps-upper-x ebnf-eps-max-width)
  3959. ebnf-eps-upper-y (if (zerop ebnf-eps-upper-y)
  3960. ebnf-eps-max-height
  3961. (+ ebnf-eps-upper-y
  3962. ebnf-production-vertical-space
  3963. ebnf-eps-max-height))
  3964. ebnf-eps-max-width prod-width
  3965. ebnf-eps-max-height prod-height))
  3966. )
  3967. (setq ebnf-eps-prod-width prod-width)
  3968. (insert-buffer-substring eps-buffer))
  3969. (setq prod-list (cdr prod-list))))
  3970. (defun ebnf-generate (ebnf-tree)
  3971. (let* ((ps-color-p (and ebnf-color-p (ps-color-device)))
  3972. (ps-print-color-scale (if ps-color-p
  3973. (float (car (ps-color-values "white")))
  3974. 1.0))
  3975. ps-zebra-stripes ps-line-number ps-razzle-dazzle
  3976. ps-print-hook
  3977. ps-print-begin-sheet-hook
  3978. ps-print-begin-page-hook
  3979. ps-print-begin-column-hook)
  3980. (ps-generate (current-buffer) (point-min) (point-max)
  3981. 'ebnf-generate-postscript)))
  3982. (defvar ebnf-tree nil)
  3983. (defvar ebnf-direction "R")
  3984. (defun ebnf-generate-postscript (from to)
  3985. (ebnf-begin-file)
  3986. (if ebnf-horizontal-max-height
  3987. (ebnf-generate-with-max-height)
  3988. (ebnf-generate-without-max-height))
  3989. (message " "))
  3990. (defun ebnf-generate-with-max-height ()
  3991. (let ((ebnf-total (length ebnf-tree))
  3992. (ebnf-nprod 0)
  3993. next-line max-height prod the-width)
  3994. (while ebnf-tree
  3995. ;; find next line point
  3996. (setq next-line ebnf-tree
  3997. prod (car ebnf-tree)
  3998. max-height (ebnf-node-height prod))
  3999. (ebnf-begin-line prod (ebnf-max-width prod))
  4000. (while (and (setq next-line (cdr next-line))
  4001. (setq prod (car next-line))
  4002. (memq (ebnf-node-action prod) ebnf-action-list)
  4003. (setq the-width (ebnf-max-width prod))
  4004. (<= the-width ps-width-remaining))
  4005. (setq max-height (max max-height (ebnf-node-height prod))
  4006. ps-width-remaining (- ps-width-remaining
  4007. (+ the-width
  4008. ebnf-production-horizontal-space))))
  4009. ;; generate current line
  4010. (ebnf-newline max-height)
  4011. (setq prod (car ebnf-tree))
  4012. (ebnf-generate-production prod)
  4013. (while (not (eq (setq ebnf-tree (cdr ebnf-tree)) next-line))
  4014. (ebnf-eop-horizontal (ebnf-max-width prod))
  4015. (setq prod (car ebnf-tree))
  4016. (ebnf-generate-production prod))
  4017. (ebnf-eop-vertical max-height))))
  4018. (defun ebnf-generate-without-max-height ()
  4019. (let ((ebnf-total (length ebnf-tree))
  4020. (ebnf-nprod 0)
  4021. max-height prod bef-width cur-width)
  4022. (while ebnf-tree
  4023. ;; generate current line
  4024. (setq prod (car ebnf-tree)
  4025. max-height (ebnf-node-height prod)
  4026. bef-width (ebnf-max-width prod))
  4027. (ebnf-begin-line prod bef-width)
  4028. (ebnf-generate-production prod)
  4029. (while (and (setq ebnf-tree (cdr ebnf-tree))
  4030. (setq prod (car ebnf-tree))
  4031. (memq (ebnf-node-action prod) ebnf-action-list)
  4032. (setq cur-width (ebnf-max-width prod))
  4033. (<= cur-width ps-width-remaining)
  4034. (<= (ebnf-node-height prod) ps-height-remaining))
  4035. (ebnf-eop-horizontal bef-width)
  4036. (ebnf-generate-production prod)
  4037. (setq bef-width cur-width
  4038. max-height (max max-height (ebnf-node-height prod))
  4039. ps-width-remaining (- ps-width-remaining
  4040. (+ cur-width
  4041. ebnf-production-horizontal-space))))
  4042. (ebnf-eop-vertical max-height)
  4043. ;; prepare next line
  4044. (ebnf-newline max-height))))
  4045. (defun ebnf-begin-line (prod width)
  4046. (and (or (eq (ebnf-node-action prod) 'form-feed)
  4047. (> (ebnf-node-height prod) ps-height-remaining))
  4048. (ebnf-new-page))
  4049. (setq ps-width-remaining (- ps-width-remaining
  4050. (+ width
  4051. ebnf-production-horizontal-space))))
  4052. (defun ebnf-newline (height)
  4053. (and (> height ps-height-remaining)
  4054. (ebnf-new-page))
  4055. (setq ps-width-remaining ps-print-width
  4056. ps-height-remaining (- ps-height-remaining
  4057. (+ height
  4058. ebnf-production-vertical-space))))
  4059. ;; [production width-fun dim-fun entry height width name production action]
  4060. (defun ebnf-generate-production (production)
  4061. (ebnf-message-info "Generating")
  4062. (run-hooks 'ebnf-production-hook)
  4063. (ps-output-string (if ebnf-production-name-p
  4064. (ebnf-node-name production)
  4065. ""))
  4066. (ps-output " "
  4067. (ebnf-format-float
  4068. (ebnf-node-width production)
  4069. (+ (if ebnf-production-name-p
  4070. ebnf-basic-height
  4071. 0.0)
  4072. (ebnf-node-entry (ebnf-node-production production))))
  4073. " BOP\n")
  4074. (ebnf-node-generation (ebnf-node-production production))
  4075. (ps-output "EOS\n"))
  4076. ;; [alternative width-fun dim-fun entry height width list]
  4077. (defun ebnf-generate-alternative (alternative)
  4078. (let ((alt (ebnf-node-list alternative))
  4079. (entry (ebnf-node-entry alternative))
  4080. (nlist 0)
  4081. alt-height alt-entry)
  4082. (while alt
  4083. (ps-output (ebnf-format-float (- entry (ebnf-node-entry (car alt))))
  4084. " ")
  4085. (setq entry (- entry (ebnf-node-height (car alt)) ebnf-vertical-space)
  4086. nlist (1+ nlist)
  4087. alt (cdr alt)))
  4088. (ps-output (format "%d " nlist)
  4089. (ebnf-format-float (ebnf-node-width alternative))
  4090. " AT\n")
  4091. (setq alt (ebnf-node-list alternative))
  4092. (when alt
  4093. (ebnf-node-generation (car alt))
  4094. (setq alt-height (- (ebnf-node-height (car alt))
  4095. (ebnf-node-entry (car alt)))))
  4096. (while (setq alt (cdr alt))
  4097. (setq alt-entry (ebnf-node-entry (car alt)))
  4098. (ebnf-vertical-movement
  4099. (- (+ alt-height ebnf-vertical-space alt-entry)))
  4100. (ebnf-node-generation (car alt))
  4101. (setq alt-height (- (ebnf-node-height (car alt)) alt-entry))))
  4102. (ps-output "EOS\n"))
  4103. ;; [sequence width-fun dim-fun entry height width list]
  4104. (defun ebnf-generate-sequence (sequence)
  4105. (ps-output "BOS\n")
  4106. (let ((seq (ebnf-node-list sequence))
  4107. seq-width)
  4108. (when seq
  4109. (ebnf-node-generation (car seq))
  4110. (setq seq-width (ebnf-node-width (car seq))))
  4111. (while (setq seq (cdr seq))
  4112. (ebnf-horizontal-movement seq-width)
  4113. (ebnf-node-generation (car seq))
  4114. (setq seq-width (ebnf-node-width (car seq)))))
  4115. (ps-output "EOS\n"))
  4116. ;; [terminal width-fun dim-fun entry height width name]
  4117. (defun ebnf-generate-terminal (terminal)
  4118. (ebnf-gen-terminal terminal "T"))
  4119. ;; [non-terminal width-fun dim-fun entry height width name]
  4120. (defun ebnf-generate-non-terminal (non-terminal)
  4121. (ebnf-gen-terminal non-terminal "NT"))
  4122. ;; [empty width-fun dim-fun entry height width]
  4123. (defun ebnf-generate-empty (empty)
  4124. (ebnf-empty-alternative (ebnf-node-width empty)))
  4125. ;; [optional width-fun dim-fun entry height width element]
  4126. (defun ebnf-generate-optional (optional)
  4127. (let ((the-optional (ebnf-node-list optional)))
  4128. (ps-output (ebnf-format-float
  4129. (+ (- (ebnf-node-height the-optional)
  4130. (ebnf-node-entry optional))
  4131. ebnf-vertical-space)
  4132. (ebnf-node-width optional))
  4133. " OP\n")
  4134. (ebnf-node-generation the-optional)
  4135. (ps-output "EOS\n")))
  4136. ;; [one-or-more width-fun dim-fun entry height width element separator]
  4137. (defun ebnf-generate-one-or-more (one-or-more)
  4138. (let* ((width (ebnf-node-width one-or-more))
  4139. (sep (ebnf-node-separator one-or-more))
  4140. (entry (- (ebnf-node-entry one-or-more)
  4141. (if sep
  4142. (ebnf-node-entry sep)
  4143. 0))))
  4144. (ps-output (ebnf-format-float entry width)
  4145. " OM\n")
  4146. (ebnf-node-generation (ebnf-node-list one-or-more))
  4147. (ebnf-vertical-movement entry)
  4148. (if sep
  4149. (let ((ebnf-direction "L"))
  4150. (ebnf-node-generation sep))
  4151. (ebnf-empty-alternative (- width
  4152. ebnf-horizontal-space
  4153. ebnf-basic-width-extra))))
  4154. (ps-output "EOS\n"))
  4155. ;; [zero-or-more width-fun dim-fun entry height width element separator]
  4156. (defun ebnf-generate-zero-or-more (zero-or-more)
  4157. (let* ((width (ebnf-node-width zero-or-more))
  4158. (node-list (ebnf-node-list zero-or-more))
  4159. (list-entry (ebnf-node-entry node-list))
  4160. (node-sep (ebnf-node-separator zero-or-more))
  4161. (entry (+ list-entry
  4162. ebnf-vertical-space
  4163. (if node-sep
  4164. (- (ebnf-node-height node-sep)
  4165. (ebnf-node-entry node-sep))
  4166. ebnf-basic-empty-height))))
  4167. (ps-output (ebnf-format-float entry
  4168. (+ (- (ebnf-node-height node-list)
  4169. list-entry)
  4170. ebnf-vertical-space)
  4171. width)
  4172. " ZM\n")
  4173. (ebnf-node-generation (ebnf-node-list zero-or-more))
  4174. (ebnf-vertical-movement entry)
  4175. (if (ebnf-node-separator zero-or-more)
  4176. (let ((ebnf-direction "L"))
  4177. (ebnf-node-generation (ebnf-node-separator zero-or-more)))
  4178. (ebnf-empty-alternative (- width
  4179. ebnf-horizontal-space
  4180. ebnf-basic-width-extra))))
  4181. (ps-output "EOS\n"))
  4182. ;; [special width-fun dim-fun entry height width name]
  4183. (defun ebnf-generate-special (special)
  4184. (ebnf-gen-terminal special "SP"))
  4185. ;; [repeat width-fun dim-fun entry height width times element]
  4186. (defun ebnf-generate-repeat (repeat)
  4187. (let ((times (ebnf-node-name repeat))
  4188. (element (ebnf-node-separator repeat)))
  4189. (ps-output-string times)
  4190. (ps-output " "
  4191. (ebnf-format-float
  4192. (ebnf-node-entry repeat)
  4193. (ebnf-node-height repeat)
  4194. (ebnf-node-width repeat)
  4195. (if element
  4196. (+ (ebnf-node-width element)
  4197. ebnf-space-R ebnf-space-R ebnf-space-R
  4198. (* (length times) ebnf-font-width-R))
  4199. 0.0))
  4200. " " ebnf-direction "RP\n")
  4201. (and element
  4202. (ebnf-node-generation element)))
  4203. (ps-output "EOS\n"))
  4204. ;; [except width-fun dim-fun entry height width element element]
  4205. (defun ebnf-generate-except (except)
  4206. (let* ((element (ebnf-node-list except))
  4207. (exception (ebnf-node-separator except))
  4208. (width (ebnf-node-width element)))
  4209. (ps-output (ebnf-format-float
  4210. width
  4211. (ebnf-node-entry except)
  4212. (ebnf-node-height except)
  4213. (ebnf-node-width except)
  4214. (+ width
  4215. ebnf-space-E ebnf-space-E ebnf-space-E
  4216. ebnf-font-width-E
  4217. (if exception
  4218. (+ (ebnf-node-width exception) ebnf-space-E)
  4219. 0.0)))
  4220. " " ebnf-direction "EX\n")
  4221. (ebnf-node-generation (ebnf-node-list except))
  4222. (when exception
  4223. (ebnf-horizontal-movement (+ width ebnf-space-E
  4224. ebnf-font-width-E ebnf-space-E))
  4225. (ebnf-node-generation exception)))
  4226. (ps-output "EOS\n"))
  4227. (defun ebnf-gen-terminal (node code)
  4228. (ps-output-string (ebnf-node-name node))
  4229. (ps-output " " (ebnf-format-float (ebnf-node-width node))
  4230. " " ebnf-direction code
  4231. (if (ebnf-node-default node)
  4232. "D\n"
  4233. "\n")))
  4234. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  4235. ;; Internal functions
  4236. (defun ebnf-directory (fun &optional directory)
  4237. "Process files in DIRECTORY applying function FUN on each file.
  4238. If DIRECTORY is nil, use `default-directory'.
  4239. Only files in DIRECTORY that match `ebnf-file-suffix-regexp' (which see) are
  4240. processed."
  4241. (let ((files (directory-files (or directory default-directory)
  4242. t ebnf-file-suffix-regexp)))
  4243. (while files
  4244. (set-buffer (find-file-noselect (car files)))
  4245. (funcall fun)
  4246. (setq buffer-backed-up t) ; Do not back it up.
  4247. (save-buffer) ; Just save new version.
  4248. (kill-buffer (current-buffer))
  4249. (setq files (cdr files)))))
  4250. (defun ebnf-file (fun file &optional do-not-kill-buffer-when-done)
  4251. "Process the named FILE applying function FUN.
  4252. If optional arg DO-NOT-KILL-BUFFER-WHEN-DONE is non-nil, the buffer isn't
  4253. killed after process termination."
  4254. (set-buffer (find-file-noselect file))
  4255. (funcall fun)
  4256. (or do-not-kill-buffer-when-done
  4257. (kill-buffer (current-buffer))))
  4258. ;; function `ebnf-range-regexp' is used to avoid a bug of `skip-chars-forward'
  4259. ;; on version 20.4.1, that is, it doesn't accept ranges like "\240-\377" (or
  4260. ;; "\177-\237"), but it accepts the character sequence from \240 to \377 (or
  4261. ;; from \177 to \237). It seems that version 20.7 has the same problem.
  4262. (defun ebnf-range-regexp (prefix from to)
  4263. (let (str)
  4264. (while (<= from to)
  4265. (setq str (concat str (char-to-string from))
  4266. from (1+ from)))
  4267. (concat prefix str)))
  4268. (defvar ebnf-map-name
  4269. (let ((map (make-vector 256 ?\_)))
  4270. (mapc #'(lambda (char)
  4271. (aset map char char))
  4272. (concat "#$%&+-.0123456789=?@~"
  4273. "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  4274. "abcdefghijklmnopqrstuvwxyz"))
  4275. map))
  4276. (defun ebnf-eps-filename (str)
  4277. (let* ((len (length str))
  4278. (stri 0)
  4279. ;; to keep compatibility with Emacs 20 & 21:
  4280. ;; DO NOT REPLACE `?\ ' BY `?\s'
  4281. (new (make-string len ?\ )))
  4282. (while (< stri len)
  4283. (aset new stri (aref ebnf-map-name (aref str stri)))
  4284. (setq stri (1+ stri)))
  4285. (concat ebnf-eps-prefix new ".eps")))
  4286. (defun ebnf-eps-output (&rest args)
  4287. (while args
  4288. (insert (car args))
  4289. (setq args (cdr args))))
  4290. (defun ebnf-generate-region (from to gen-func)
  4291. (run-hooks 'ebnf-hook)
  4292. (let ((ebnf-limit (max from to))
  4293. (error-msg "SYNTAX")
  4294. the-point)
  4295. (save-excursion
  4296. (save-restriction
  4297. (save-match-data
  4298. (condition-case data
  4299. (let ((tree (ebnf-parse-and-sort (min from to))))
  4300. (when gen-func
  4301. (setq error-msg "EMPTY RULES"
  4302. tree (ebnf-eliminate-empty-rules tree))
  4303. (setq error-msg "OPTIMIZE"
  4304. tree (ebnf-optimize tree))
  4305. (setq error-msg "DIMENSIONS"
  4306. tree (ebnf-dimensions tree))
  4307. (setq error-msg "GENERATION")
  4308. (funcall gen-func tree))
  4309. (setq error-msg nil)) ; here it's ok
  4310. ;; handler
  4311. ((quit error)
  4312. (ding)
  4313. (setq the-point (max (1- (point)) (point-min))
  4314. error-msg (concat error-msg ": "
  4315. (error-message-string data)
  4316. ", "
  4317. (and (string= error-msg "SYNTAX")
  4318. (format "at position %d "
  4319. the-point))
  4320. (format "in buffer \"%s\"."
  4321. (buffer-name)))))))))
  4322. (cond
  4323. ;; error occurred
  4324. (error-msg
  4325. (goto-char the-point)
  4326. (if ebnf-stop-on-error
  4327. (error error-msg)
  4328. (message "%s" error-msg)))
  4329. ;; generated output OK
  4330. (gen-func
  4331. nil)
  4332. ;; syntax checked OK
  4333. (t
  4334. (message "EBNF syntactic analysis: NO ERRORS.")))))
  4335. (defun ebnf-parse-and-sort (start)
  4336. (ebnf-log "(ebnf-parse-and-sort %S)" start)
  4337. (ebnf-begin-job)
  4338. (let ((tree (funcall ebnf-parser-func start)))
  4339. (if ebnf-sort-production
  4340. (progn
  4341. (message "Sorting...")
  4342. (sort tree
  4343. (if (eq ebnf-sort-production 'ascending)
  4344. 'ebnf-sorter-ascending
  4345. 'ebnf-sorter-descending)))
  4346. (nreverse tree))))
  4347. (defun ebnf-sorter-ascending (first second)
  4348. (string< (ebnf-node-name first)
  4349. (ebnf-node-name second)))
  4350. (defun ebnf-sorter-descending (first second)
  4351. (string< (ebnf-node-name second)
  4352. (ebnf-node-name first)))
  4353. (defun ebnf-empty-alternative (width)
  4354. (ps-output (ebnf-format-float width) " EA\n"))
  4355. (defun ebnf-vertical-movement (height)
  4356. (ps-output (ebnf-format-float height) " vm\n"))
  4357. (defun ebnf-horizontal-movement (width)
  4358. (ps-output (ebnf-format-float width) " hm\n"))
  4359. (defun ebnf-entry (height)
  4360. (* height ebnf-entry-percentage))
  4361. (defun ebnf-eop-vertical (height)
  4362. (ps-output (ebnf-format-float (+ height ebnf-production-vertical-space))
  4363. " EOPV\n\n"))
  4364. (defun ebnf-eop-horizontal (width)
  4365. (ps-output (ebnf-format-float (+ width ebnf-production-horizontal-space))
  4366. " EOPH\n\n"))
  4367. (defun ebnf-new-page ()
  4368. (when (< ps-height-remaining ps-print-height)
  4369. (run-hooks 'ebnf-page-hook)
  4370. (ps-next-page)
  4371. (ps-output "\n")))
  4372. (defsubst ebnf-font-size (font) (nth 0 font))
  4373. (defsubst ebnf-font-name (font) (nth 1 font))
  4374. (defsubst ebnf-font-foreground (font) (nth 2 font))
  4375. (defsubst ebnf-font-background (font) (nth 3 font))
  4376. (defsubst ebnf-font-list (font) (nthcdr 4 font))
  4377. (defsubst ebnf-font-attributes (font)
  4378. (lsh (ps-extension-bit (cdr font)) -2))
  4379. (defconst ebnf-font-name-select
  4380. (vector 'normal 'bold 'italic 'bold-italic))
  4381. (defun ebnf-font-name-select (font)
  4382. (let* ((font-list (ebnf-font-list font))
  4383. (font-index (+ (if (memq 'bold font-list) 1 0)
  4384. (if (memq 'italic font-list) 2 0)))
  4385. (name (ebnf-font-name font))
  4386. (database (cdr (assoc name ps-font-info-database)))
  4387. (info-list (or (cdr (assoc 'fonts database))
  4388. (error "Invalid font: %s" name))))
  4389. (or (cdr (assoc (aref ebnf-font-name-select font-index)
  4390. info-list))
  4391. (error "Invalid attributes for font %s" name))))
  4392. (defun ebnf-font-select (font select)
  4393. (let* ((name (ebnf-font-name font))
  4394. (database (cdr (assoc name ps-font-info-database)))
  4395. (size (cdr (assoc 'size database)))
  4396. (base (cdr (assoc select database))))
  4397. (if (and size base)
  4398. (/ (* (ebnf-font-size font) base)
  4399. size)
  4400. (error "Invalid font: %s" name))))
  4401. (defsubst ebnf-font-width (font)
  4402. (ebnf-font-select font 'avg-char-width))
  4403. (defsubst ebnf-font-height (font)
  4404. (ebnf-font-select font 'line-height))
  4405. (defconst ebnf-syntax-alist
  4406. ;; 0.syntax 1.parser 2.initializer
  4407. '((iso-ebnf ebnf-iso-parser ebnf-iso-initialize)
  4408. (yacc ebnf-yac-parser ebnf-yac-initialize)
  4409. (abnf ebnf-abn-parser ebnf-abn-initialize)
  4410. (ebnf ebnf-bnf-parser ebnf-bnf-initialize)
  4411. (ebnfx ebnf-ebx-parser ebnf-ebx-initialize)
  4412. (dtd ebnf-dtd-parser ebnf-dtd-initialize))
  4413. "Alist associating EBNF syntax with a parser and an initializer.")
  4414. (defun ebnf-begin-job ()
  4415. (ps-printing-region nil nil nil)
  4416. (if ebnf-use-float-format
  4417. (setq ebnf-format-float "%1.3f"
  4418. ebnf-message-float "%3.2f")
  4419. (setq ebnf-format-float "%s"
  4420. ebnf-message-float "%s"))
  4421. (ebnf-otz-initialize)
  4422. ;; to avoid compilation gripes when calling autoloaded functions
  4423. (let ((init (or (assoc ebnf-syntax ebnf-syntax-alist)
  4424. (assoc 'ebnf ebnf-syntax-alist))))
  4425. (setq ebnf-parser-func (nth 1 init))
  4426. (funcall (nth 2 init)))
  4427. (and ebnf-terminal-regexp ; ensures that it's a string or nil
  4428. (not (stringp ebnf-terminal-regexp))
  4429. (setq ebnf-terminal-regexp nil))
  4430. (or (and ebnf-eps-prefix ; ensures that it's a string
  4431. (stringp ebnf-eps-prefix))
  4432. (setq ebnf-eps-prefix "ebnf--"))
  4433. (setq ebnf-entry-percentage ; ensures value between 0.0 and 1.0
  4434. (min (max ebnf-entry-percentage 0.0) 1.0)
  4435. ebnf-action-list (if ebnf-horizontal-orientation
  4436. '(nil keep-line)
  4437. '(keep-line))
  4438. ebnf-settings nil
  4439. ebnf-fonts-required nil
  4440. ebnf-action nil
  4441. ebnf-default-p nil
  4442. ebnf-eps-context nil
  4443. ebnf-eps-file-alist nil
  4444. ebnf-eps-production-list nil
  4445. ebnf-eps-header-comment nil
  4446. ebnf-eps-footer-comment nil
  4447. ebnf-eps-upper-x 0.0
  4448. ebnf-eps-upper-y 0.0
  4449. ebnf-font-height-P (ebnf-font-height ebnf-production-font)
  4450. ebnf-font-height-T (ebnf-font-height ebnf-terminal-font)
  4451. ebnf-font-height-NT (ebnf-font-height ebnf-non-terminal-font)
  4452. ebnf-font-height-S (ebnf-font-height ebnf-special-font)
  4453. ebnf-font-height-E (ebnf-font-height ebnf-except-font)
  4454. ebnf-font-height-R (ebnf-font-height ebnf-repeat-font)
  4455. ebnf-font-width-P (ebnf-font-width ebnf-production-font)
  4456. ebnf-font-width-T (ebnf-font-width ebnf-terminal-font)
  4457. ebnf-font-width-NT (ebnf-font-width ebnf-non-terminal-font)
  4458. ebnf-font-width-S (ebnf-font-width ebnf-special-font)
  4459. ebnf-font-width-E (ebnf-font-width ebnf-except-font)
  4460. ebnf-font-width-R (ebnf-font-width ebnf-repeat-font)
  4461. ebnf-space-T (* ebnf-font-height-T 0.5)
  4462. ebnf-space-NT (* ebnf-font-height-NT 0.5)
  4463. ebnf-space-S (* ebnf-font-height-S 0.5)
  4464. ebnf-space-E (* ebnf-font-height-E 0.5)
  4465. ebnf-space-R (* ebnf-font-height-R 0.5))
  4466. (let ((basic (+ ebnf-font-height-T ebnf-font-height-NT)))
  4467. (setq ebnf-basic-width (* basic 0.5)
  4468. ebnf-horizontal-space (+ basic basic)
  4469. ebnf-basic-empty-height (* ebnf-basic-width 0.5)
  4470. ebnf-basic-height ebnf-basic-width
  4471. ebnf-vertical-space ebnf-basic-width
  4472. ebnf-basic-width-extra (- ebnf-basic-width
  4473. ebnf-arrow-extra-width
  4474. 0.1)) ; error factor
  4475. ;; ensures value is greater than zero
  4476. (or (and (numberp ebnf-production-horizontal-space)
  4477. (> ebnf-production-horizontal-space 0.0))
  4478. (setq ebnf-production-horizontal-space basic))
  4479. ;; ensures value is greater than zero
  4480. (or (and (numberp ebnf-production-vertical-space)
  4481. (> ebnf-production-vertical-space 0.0))
  4482. (setq ebnf-production-vertical-space basic)))
  4483. (ebnf-log "(ebnf-begin-job)")
  4484. (ebnf-log " ebnf-arrow-extra-width ............ : %7.3f" ebnf-arrow-extra-width)
  4485. (ebnf-log " ebnf-arrow-scale .................. : %7.3f" ebnf-arrow-scale)
  4486. (ebnf-log " ebnf-basic-width-extra ............ : %7.3f" ebnf-basic-width-extra)
  4487. (ebnf-log " ebnf-basic-width .................. : %7.3f (T)" ebnf-basic-width)
  4488. (ebnf-log " ebnf-horizontal-space ............. : %7.3f (4T)" ebnf-horizontal-space)
  4489. (ebnf-log " ebnf-basic-empty-height ........... : %7.3f (hT)" ebnf-basic-empty-height)
  4490. (ebnf-log " ebnf-basic-height ................. : %7.3f (T)" ebnf-basic-height)
  4491. (ebnf-log " ebnf-vertical-space ............... : %7.3f (T)" ebnf-vertical-space)
  4492. (ebnf-log " ebnf-production-horizontal-space .. : %7.3f (2T)" ebnf-production-horizontal-space)
  4493. (ebnf-log " ebnf-production-vertical-space .... : %7.3f (2T)" ebnf-production-vertical-space))
  4494. (defsubst ebnf-shape-value (sym alist)
  4495. (or (cdr (assq sym alist)) 0))
  4496. (defsubst ebnf-boolean (value)
  4497. (if value "true" "false"))
  4498. (defun ebnf-begin-file ()
  4499. (ps-flush-output)
  4500. (with-current-buffer ps-spool-buffer
  4501. (goto-char (point-min))
  4502. (and (search-forward "%%Creator: " nil t)
  4503. (not (search-forward "& ebnf2ps v"
  4504. (line-end-position)
  4505. t))
  4506. (progn
  4507. ;; adjust creator comment
  4508. (end-of-line)
  4509. ;; (backward-char)
  4510. (insert " & ebnf2ps v" ebnf-version)
  4511. ;; insert ebnf settings & engine
  4512. (goto-char (point-max))
  4513. (search-backward "\n%%EndProlog\n")
  4514. (ebnf-insert-ebnf-prologue)
  4515. (ps-output "\n")))))
  4516. (defun ebnf-eps-finish-and-write (buffer filename)
  4517. (when (buffer-modified-p buffer)
  4518. (with-current-buffer buffer
  4519. (ebnf-eps-header-footer-set filename)
  4520. (setq ebnf-eps-upper-x (max ebnf-eps-upper-x ebnf-eps-max-width)
  4521. ebnf-eps-upper-y (if (zerop ebnf-eps-upper-y)
  4522. ebnf-eps-max-height
  4523. (+ ebnf-eps-upper-y
  4524. ebnf-production-vertical-space
  4525. ebnf-eps-max-height)))
  4526. ;; prologue
  4527. (goto-char (point-min))
  4528. (insert
  4529. "%!PS-Adobe-3.0 EPSF-3.0"
  4530. "\n%%BoundingBox: 0 0 "
  4531. (format "%d %d" (1+ ebnf-eps-upper-x) (1+ ebnf-eps-upper-y))
  4532. "\n%%Title: " filename
  4533. "\n%%CreationDate: " (format-time-string "%T %b %d %Y")
  4534. "\n%%Creator: " (user-full-name) " (using ebnf2ps v" ebnf-version ")"
  4535. "\n%%DocumentNeededResources: font "
  4536. (or ebnf-fonts-required
  4537. (setq ebnf-fonts-required
  4538. (mapconcat 'identity
  4539. (ps-remove-duplicates
  4540. (mapcar 'ebnf-font-name-select
  4541. (list ebnf-production-font
  4542. ebnf-terminal-font
  4543. ebnf-non-terminal-font
  4544. ebnf-special-font
  4545. ebnf-except-font
  4546. ebnf-repeat-font
  4547. ebnf-eps-header-font
  4548. ebnf-eps-footer-font)))
  4549. "\n%%+ font ")))
  4550. "\n%%Pages: 0\n%%EndComments\n\n%%BeginProlog\n"
  4551. ebnf-eps-prologue)
  4552. (ebnf-insert-ebnf-prologue)
  4553. (insert ebnf-eps-begin
  4554. "\n0 " (ebnf-format-float
  4555. (- ebnf-eps-upper-y (* ebnf-font-height-P 0.7)))
  4556. " #ebnf2ps#begin\n")
  4557. ;; epilogue
  4558. (goto-char (point-max))
  4559. (insert ebnf-eps-end)
  4560. ;; write file
  4561. (message "Saving...")
  4562. (setq filename (expand-file-name filename))
  4563. (let ((coding-system-for-write 'raw-text-unix))
  4564. (write-region (point-min) (point-max) filename))
  4565. (message "Wrote %s" filename))))
  4566. (defun ebnf-insert-ebnf-prologue ()
  4567. (insert
  4568. (or ebnf-settings
  4569. (setq ebnf-settings
  4570. (concat
  4571. "\n\n% === begin EBNF settings\n\n"
  4572. (format "/Header %s def\n"
  4573. (or ebnf-eps-header-comment "()"))
  4574. (format "/Footer %s def\n"
  4575. (or ebnf-eps-footer-comment "()"))
  4576. ;; header
  4577. (format "/ShowHeader %s def\n"
  4578. (ebnf-boolean
  4579. (ebnf-eps-header-footer-p ebnf-eps-header)))
  4580. (format "/fH %s /%s DefFont\n"
  4581. (ebnf-format-float
  4582. (ebnf-font-size ebnf-eps-header-font))
  4583. (ebnf-font-name-select ebnf-eps-header-font))
  4584. (ebnf-format-color "/ForegroundH %s def %% %s\n"
  4585. (ebnf-font-foreground ebnf-eps-header-font)
  4586. "Black")
  4587. (ebnf-format-color "/BackgroundH %s def %% %s\n"
  4588. (ebnf-font-background ebnf-eps-header-font)
  4589. "White")
  4590. (format "/EffectH %d def\n"
  4591. (ebnf-font-attributes ebnf-eps-header-font))
  4592. ;; footer
  4593. (format "/ShowFooter %s def\n"
  4594. (ebnf-boolean
  4595. (ebnf-eps-header-footer-p ebnf-eps-footer)))
  4596. (format "/fF %s /%s DefFont\n"
  4597. (ebnf-format-float
  4598. (ebnf-font-size ebnf-eps-footer-font))
  4599. (ebnf-font-name-select ebnf-eps-footer-font))
  4600. (ebnf-format-color "/ForegroundF %s def %% %s\n"
  4601. (ebnf-font-foreground ebnf-eps-footer-font)
  4602. "Black")
  4603. (ebnf-format-color "/BackgroundF %s def %% %s\n"
  4604. (ebnf-font-background ebnf-eps-footer-font)
  4605. "White")
  4606. (format "/EffectF %d def\n"
  4607. (ebnf-font-attributes ebnf-eps-footer-font))
  4608. ;; production
  4609. (format "/fP %s /%s DefFont\n"
  4610. (ebnf-format-float (ebnf-font-size ebnf-production-font))
  4611. (ebnf-font-name-select ebnf-production-font))
  4612. (ebnf-format-color "/ForegroundP %s def %% %s\n"
  4613. (ebnf-font-foreground ebnf-production-font)
  4614. "Black")
  4615. (ebnf-format-color "/BackgroundP %s def %% %s\n"
  4616. (ebnf-font-background ebnf-production-font)
  4617. "White")
  4618. (format "/EffectP %d def\n"
  4619. (ebnf-font-attributes ebnf-production-font))
  4620. ;; terminal
  4621. (format "/fT %s /%s DefFont\n"
  4622. (ebnf-format-float (ebnf-font-size ebnf-terminal-font))
  4623. (ebnf-font-name-select ebnf-terminal-font))
  4624. (ebnf-format-color "/ForegroundT %s def %% %s\n"
  4625. (ebnf-font-foreground ebnf-terminal-font)
  4626. "Black")
  4627. (ebnf-format-color "/BackgroundT %s def %% %s\n"
  4628. (ebnf-font-background ebnf-terminal-font)
  4629. "White")
  4630. (format "/EffectT %d def\n"
  4631. (ebnf-font-attributes ebnf-terminal-font))
  4632. (format "/BorderWidthT %s def\n"
  4633. (ebnf-format-float ebnf-terminal-border-width))
  4634. (ebnf-format-color "/BorderColorT %s def %% %s\n"
  4635. ebnf-terminal-border-color
  4636. "Black")
  4637. (format "/ShapeT %d def\n"
  4638. (ebnf-shape-value ebnf-terminal-shape
  4639. ebnf-terminal-shape-alist))
  4640. (format "/ShadowT %s def\n"
  4641. (ebnf-boolean ebnf-terminal-shadow))
  4642. ;; non-terminal
  4643. (format "/fNT %s /%s DefFont\n"
  4644. (ebnf-format-float
  4645. (ebnf-font-size ebnf-non-terminal-font))
  4646. (ebnf-font-name-select ebnf-non-terminal-font))
  4647. (ebnf-format-color "/ForegroundNT %s def %% %s\n"
  4648. (ebnf-font-foreground ebnf-non-terminal-font)
  4649. "Black")
  4650. (ebnf-format-color "/BackgroundNT %s def %% %s\n"
  4651. (ebnf-font-background ebnf-non-terminal-font)
  4652. "White")
  4653. (format "/EffectNT %d def\n"
  4654. (ebnf-font-attributes ebnf-non-terminal-font))
  4655. (format "/BorderWidthNT %s def\n"
  4656. (ebnf-format-float ebnf-non-terminal-border-width))
  4657. (ebnf-format-color "/BorderColorNT %s def %% %s\n"
  4658. ebnf-non-terminal-border-color
  4659. "Black")
  4660. (format "/ShapeNT %d def\n"
  4661. (ebnf-shape-value ebnf-non-terminal-shape
  4662. ebnf-terminal-shape-alist))
  4663. (format "/ShadowNT %s def\n"
  4664. (ebnf-boolean ebnf-non-terminal-shadow))
  4665. ;; special
  4666. (format "/fS %s /%s DefFont\n"
  4667. (ebnf-format-float (ebnf-font-size ebnf-special-font))
  4668. (ebnf-font-name-select ebnf-special-font))
  4669. (ebnf-format-color "/ForegroundS %s def %% %s\n"
  4670. (ebnf-font-foreground ebnf-special-font)
  4671. "Black")
  4672. (ebnf-format-color "/BackgroundS %s def %% %s\n"
  4673. (ebnf-font-background ebnf-special-font)
  4674. "Gray95")
  4675. (format "/EffectS %d def\n"
  4676. (ebnf-font-attributes ebnf-special-font))
  4677. (format "/BorderWidthS %s def\n"
  4678. (ebnf-format-float ebnf-special-border-width))
  4679. (ebnf-format-color "/BorderColorS %s def %% %s\n"
  4680. ebnf-special-border-color
  4681. "Black")
  4682. (format "/ShapeS %d def\n"
  4683. (ebnf-shape-value ebnf-special-shape
  4684. ebnf-terminal-shape-alist))
  4685. (format "/ShadowS %s def\n"
  4686. (ebnf-boolean ebnf-special-shadow))
  4687. ;; except
  4688. (format "/fE %s /%s DefFont\n"
  4689. (ebnf-format-float (ebnf-font-size ebnf-except-font))
  4690. (ebnf-font-name-select ebnf-except-font))
  4691. (ebnf-format-color "/ForegroundE %s def %% %s\n"
  4692. (ebnf-font-foreground ebnf-except-font)
  4693. "Black")
  4694. (ebnf-format-color "/BackgroundE %s def %% %s\n"
  4695. (ebnf-font-background ebnf-except-font)
  4696. "Gray90")
  4697. (format "/EffectE %d def\n"
  4698. (ebnf-font-attributes ebnf-except-font))
  4699. (format "/BorderWidthE %s def\n"
  4700. (ebnf-format-float ebnf-except-border-width))
  4701. (ebnf-format-color "/BorderColorE %s def %% %s\n"
  4702. ebnf-except-border-color
  4703. "Black")
  4704. (format "/ShapeE %d def\n"
  4705. (ebnf-shape-value ebnf-except-shape
  4706. ebnf-terminal-shape-alist))
  4707. (format "/ShadowE %s def\n"
  4708. (ebnf-boolean ebnf-except-shadow))
  4709. ;; repeat
  4710. (format "/fR %s /%s DefFont\n"
  4711. (ebnf-format-float (ebnf-font-size ebnf-repeat-font))
  4712. (ebnf-font-name-select ebnf-repeat-font))
  4713. (ebnf-format-color "/ForegroundR %s def %% %s\n"
  4714. (ebnf-font-foreground ebnf-repeat-font)
  4715. "Black")
  4716. (ebnf-format-color "/BackgroundR %s def %% %s\n"
  4717. (ebnf-font-background ebnf-repeat-font)
  4718. "Gray85")
  4719. (format "/EffectR %d def\n"
  4720. (ebnf-font-attributes ebnf-repeat-font))
  4721. (format "/BorderWidthR %s def\n"
  4722. (ebnf-format-float ebnf-repeat-border-width))
  4723. (ebnf-format-color "/BorderColorR %s def %% %s\n"
  4724. ebnf-repeat-border-color
  4725. "Black")
  4726. (format "/ShapeR %d def\n"
  4727. (ebnf-shape-value ebnf-repeat-shape
  4728. ebnf-terminal-shape-alist))
  4729. (format "/ShadowR %s def\n"
  4730. (ebnf-boolean ebnf-repeat-shadow))
  4731. ;; miscellaneous
  4732. (format "/ExtraWidth %s def\n"
  4733. (ebnf-format-float ebnf-arrow-extra-width))
  4734. (format "/ArrowScale %s def\n"
  4735. (ebnf-format-float ebnf-arrow-scale))
  4736. (format "/DefaultWidth %s def\n"
  4737. (ebnf-format-float ebnf-default-width))
  4738. (format "/LineWidth %s def\n"
  4739. (ebnf-format-float ebnf-line-width))
  4740. (ebnf-format-color "/LineColor %s def %% %s\n"
  4741. ebnf-line-color
  4742. "Black")
  4743. (format "/ArrowShape %d def\n"
  4744. (ebnf-shape-value ebnf-arrow-shape
  4745. ebnf-arrow-shape-alist))
  4746. (format "/ChartShape %d def\n"
  4747. (ebnf-shape-value ebnf-chart-shape
  4748. ebnf-terminal-shape-alist))
  4749. (format "/UserArrow{%s}def\n"
  4750. (let ((arrow (eval ebnf-user-arrow)))
  4751. (if (stringp arrow)
  4752. arrow
  4753. "")))
  4754. "\n% === end EBNF settings\n\n"
  4755. (and ebnf-debug-ps ebnf-debug))))
  4756. ebnf-prologue))
  4757. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  4758. ;; Adjusting dimensions
  4759. (defun ebnf-dimensions (tree)
  4760. (ebnf-log "(ebnf-dimensions tree)")
  4761. (let ((ebnf-total (length tree))
  4762. (ebnf-nprod 0))
  4763. (mapc 'ebnf-production-dimension tree))
  4764. tree)
  4765. ;; [empty width-fun dim-fun entry height width]
  4766. ;;(defun ebnf-empty-dimension (empty)
  4767. ;; )
  4768. ;; [production width-fun dim-fun entry height width name production action]
  4769. (defun ebnf-production-dimension (production)
  4770. (ebnf-log "(ebnf-production-dimension production)")
  4771. (ebnf-message-info "Calculating dimensions")
  4772. (ebnf-node-dimension-func (ebnf-node-production production))
  4773. (let* ((prod (ebnf-node-production production))
  4774. (height (+ (if ebnf-production-name-p
  4775. ebnf-font-height-P
  4776. 0.0)
  4777. ebnf-line-width ebnf-line-width
  4778. ebnf-basic-height
  4779. (ebnf-node-height prod))))
  4780. (ebnf-node-entry production height)
  4781. (ebnf-node-height production height)
  4782. (ebnf-node-width production (+ (ebnf-node-width prod)
  4783. ebnf-line-width
  4784. ebnf-horizontal-space
  4785. ebnf-basic-width-extra)))
  4786. (ebnf-log " production name : %S" (ebnf-node-name production))
  4787. (ebnf-log " production entry : %7.3f" (ebnf-node-entry production))
  4788. (ebnf-log " production height : %7.3f" (ebnf-node-height production))
  4789. (ebnf-log " production width : %7.3f" (ebnf-node-width production)))
  4790. ;; [terminal width-fun dim-fun entry height width name]
  4791. (defun ebnf-terminal-dimension (terminal)
  4792. (ebnf-log "(ebnf-terminal-dimension terminal)")
  4793. (ebnf-terminal-dimension1 terminal
  4794. ebnf-font-height-T
  4795. ebnf-font-width-T
  4796. ebnf-space-T))
  4797. ;; [non-terminal width-fun dim-fun entry height width name]
  4798. (defun ebnf-non-terminal-dimension (non-terminal)
  4799. (ebnf-log "(ebnf-non-terminal-dimension non-terminal)")
  4800. (ebnf-terminal-dimension1 non-terminal
  4801. ebnf-font-height-NT
  4802. ebnf-font-width-NT
  4803. ebnf-space-NT))
  4804. ;; [special width-fun dim-fun entry height width name]
  4805. (defun ebnf-special-dimension (special)
  4806. (ebnf-log "(ebnf-special-dimension special)")
  4807. (ebnf-terminal-dimension1 special
  4808. ebnf-font-height-S
  4809. ebnf-font-width-S
  4810. ebnf-space-S))
  4811. (defun ebnf-terminal-dimension1 (node font-height font-width space)
  4812. (let ((height (+ space font-height space))
  4813. (len (length (ebnf-node-name node))))
  4814. (ebnf-node-entry node (* height 0.5))
  4815. (ebnf-node-height node height)
  4816. (ebnf-node-width node (+ ebnf-basic-width
  4817. ebnf-arrow-extra-width
  4818. space
  4819. (* len font-width)
  4820. space
  4821. ebnf-basic-width)))
  4822. (ebnf-log " name : %S" (ebnf-node-name node))
  4823. (ebnf-log " entry : %7.3f" (ebnf-node-entry node))
  4824. (ebnf-log " height : %7.3f" (ebnf-node-height node))
  4825. (ebnf-log " width : %7.3f" (ebnf-node-width node)))
  4826. (defconst ebnf-null-vector (vector t t t 0.0 0.0 0.0))
  4827. ;; [repeat width-fun dim-fun entry height width times element]
  4828. (defun ebnf-repeat-dimension (repeat)
  4829. (ebnf-log "(ebnf-repeat-dimension repeat)")
  4830. (let ((times (ebnf-node-name repeat))
  4831. (element (ebnf-node-separator repeat)))
  4832. (if element
  4833. (ebnf-node-dimension-func element)
  4834. (setq element ebnf-null-vector))
  4835. (ebnf-node-entry repeat (+ (ebnf-node-entry element)
  4836. ebnf-space-R))
  4837. (ebnf-node-height repeat (+ (max (ebnf-node-height element)
  4838. ebnf-font-height-S)
  4839. ebnf-space-R ebnf-space-R))
  4840. (ebnf-node-width repeat (+ (ebnf-node-width element)
  4841. ebnf-arrow-extra-width
  4842. ebnf-space-R ebnf-space-R ebnf-space-R
  4843. ebnf-horizontal-space
  4844. (* (length times) ebnf-font-width-R))))
  4845. (ebnf-log " repeat entry : %7.3f" (ebnf-node-entry repeat))
  4846. (ebnf-log " repeat height : %7.3f" (ebnf-node-height repeat))
  4847. (ebnf-log " repeat width : %7.3f" (ebnf-node-width repeat)))
  4848. ;; [except width-fun dim-fun entry height width element element]
  4849. (defun ebnf-except-dimension (except)
  4850. (ebnf-log "(ebnf-except-dimension except)")
  4851. (let ((factor (ebnf-node-list except))
  4852. (element (ebnf-node-separator except)))
  4853. (ebnf-node-dimension-func factor)
  4854. (if element
  4855. (ebnf-node-dimension-func element)
  4856. (setq element ebnf-null-vector))
  4857. (ebnf-node-entry except (+ (max (ebnf-node-entry factor)
  4858. (ebnf-node-entry element))
  4859. ebnf-space-E))
  4860. (ebnf-node-height except (+ (max (ebnf-node-height factor)
  4861. (ebnf-node-height element))
  4862. ebnf-space-E ebnf-space-E))
  4863. (ebnf-node-width except (+ (ebnf-node-width factor)
  4864. (ebnf-node-width element)
  4865. ebnf-arrow-extra-width
  4866. ebnf-space-E ebnf-space-E
  4867. ebnf-space-E ebnf-space-E
  4868. ebnf-font-width-E
  4869. ebnf-horizontal-space)))
  4870. (ebnf-log " except entry : %7.3f" (ebnf-node-entry except))
  4871. (ebnf-log " except height : %7.3f" (ebnf-node-height except))
  4872. (ebnf-log " except width : %7.3f" (ebnf-node-width except)))
  4873. ;; [alternative width-fun dim-fun entry height width list]
  4874. (defun ebnf-alternative-dimension (alternative)
  4875. (ebnf-log "(ebnf-alternative-dimension alternative)")
  4876. (let ((body (ebnf-node-list alternative))
  4877. (lis (ebnf-node-list alternative)))
  4878. (while lis
  4879. (ebnf-node-dimension-func (car lis))
  4880. (setq lis (cdr lis)))
  4881. (let ((height 0.0)
  4882. (width 0.0)
  4883. (alt body)
  4884. (tail (car (last body)))
  4885. (entry (ebnf-node-entry (car body)))
  4886. node)
  4887. (while alt
  4888. (setq node (car alt)
  4889. alt (cdr alt)
  4890. height (+ (ebnf-node-height node) height)
  4891. width (max (ebnf-node-width node) width)))
  4892. (ebnf-adjust-width body width)
  4893. (setq height (+ height (* (1- (length body)) ebnf-vertical-space)))
  4894. (ebnf-node-entry alternative (+ entry
  4895. (ebnf-entry
  4896. (- height entry
  4897. (- (ebnf-node-height tail)
  4898. (ebnf-node-entry tail))))))
  4899. (ebnf-node-height alternative height)
  4900. (ebnf-node-width alternative (+ width
  4901. ebnf-horizontal-space
  4902. ebnf-basic-width-extra))
  4903. (ebnf-node-list alternative body)))
  4904. (ebnf-log " alternative entry : %7.3f" (ebnf-node-entry alternative))
  4905. (ebnf-log " alternative height : %7.3f" (ebnf-node-height alternative))
  4906. (ebnf-log " alternative width : %7.3f" (ebnf-node-width alternative)))
  4907. ;; [optional width-fun dim-fun entry height width element]
  4908. (defun ebnf-optional-dimension (optional)
  4909. (ebnf-log "(ebnf-optional-dimension optional)")
  4910. (let ((body (ebnf-node-list optional)))
  4911. (ebnf-node-dimension-func body)
  4912. (ebnf-node-entry optional (ebnf-node-entry body))
  4913. (ebnf-node-height optional (+ (ebnf-node-height body)
  4914. ebnf-vertical-space))
  4915. (ebnf-node-width optional (+ (ebnf-node-width body)
  4916. ebnf-horizontal-space)))
  4917. (ebnf-log " optional entry : %7.3f" (ebnf-node-entry optional))
  4918. (ebnf-log " optional height : %7.3f" (ebnf-node-height optional))
  4919. (ebnf-log " optional width : %7.3f" (ebnf-node-width optional)))
  4920. ;; [one-or-more width-fun dim-fun entry height width element separator]
  4921. (defun ebnf-one-or-more-dimension (or-more)
  4922. (ebnf-log "(ebnf-one-or-more-dimension or-more)")
  4923. (let ((list-part (ebnf-node-list or-more))
  4924. (sep-part (ebnf-node-separator or-more)))
  4925. (ebnf-node-dimension-func list-part)
  4926. (and sep-part
  4927. (ebnf-node-dimension-func sep-part))
  4928. (let ((height (+ (if sep-part
  4929. (ebnf-node-height sep-part)
  4930. ebnf-basic-empty-height)
  4931. ebnf-vertical-space
  4932. (ebnf-node-height list-part)))
  4933. (width (max (if sep-part
  4934. (ebnf-node-width sep-part)
  4935. 0.0)
  4936. (ebnf-node-width list-part))))
  4937. (when sep-part
  4938. (ebnf-adjust-width list-part width)
  4939. (ebnf-adjust-width sep-part width))
  4940. (ebnf-node-entry or-more (+ (- height
  4941. (ebnf-node-height list-part))
  4942. (ebnf-node-entry list-part)))
  4943. (ebnf-node-height or-more height)
  4944. (ebnf-node-width or-more (+ width
  4945. ebnf-horizontal-space
  4946. ebnf-basic-width-extra))))
  4947. (ebnf-log " one-or-more entry : %7.3f" (ebnf-node-entry or-more))
  4948. (ebnf-log " one-or-more height : %7.3f" (ebnf-node-height or-more))
  4949. (ebnf-log " one-or-more width : %7.3f" (ebnf-node-width or-more)))
  4950. ;; [zero-or-more width-fun dim-fun entry height width element separator]
  4951. (defun ebnf-zero-or-more-dimension (or-more)
  4952. (ebnf-log "(ebnf-zero-or-more-dimension or-more)")
  4953. (let ((list-part (ebnf-node-list or-more))
  4954. (sep-part (ebnf-node-separator or-more)))
  4955. (ebnf-node-dimension-func list-part)
  4956. (and sep-part
  4957. (ebnf-node-dimension-func sep-part))
  4958. (let ((height (+ (if sep-part
  4959. (ebnf-node-height sep-part)
  4960. ebnf-basic-empty-height)
  4961. ebnf-vertical-space
  4962. (ebnf-node-height list-part)
  4963. ebnf-vertical-space))
  4964. (width (max (if sep-part
  4965. (ebnf-node-width sep-part)
  4966. 0.0)
  4967. (ebnf-node-width list-part))))
  4968. (when sep-part
  4969. (ebnf-adjust-width list-part width)
  4970. (ebnf-adjust-width sep-part width))
  4971. (ebnf-node-entry or-more height)
  4972. (ebnf-node-height or-more height)
  4973. (ebnf-node-width or-more (+ width
  4974. ebnf-horizontal-space
  4975. ebnf-basic-width-extra))))
  4976. (ebnf-log " zero-or-more entry : %7.3f" (ebnf-node-entry or-more))
  4977. (ebnf-log " zero-or-more height : %7.3f" (ebnf-node-height or-more))
  4978. (ebnf-log " zero-or-more width : %7.3f" (ebnf-node-width or-more)))
  4979. ;; [sequence width-fun dim-fun entry height width list]
  4980. (defun ebnf-sequence-dimension (sequence)
  4981. (ebnf-log "(ebnf-sequence-dimension sequence)")
  4982. (let ((above 0.0)
  4983. (below 0.0)
  4984. (width 0.0)
  4985. (lis (ebnf-node-list sequence))
  4986. entry node)
  4987. (while lis
  4988. (setq node (car lis)
  4989. lis (cdr lis))
  4990. (ebnf-node-dimension-func node)
  4991. (setq entry (ebnf-node-entry node)
  4992. above (max above entry)
  4993. below (max below (- (ebnf-node-height node) entry))
  4994. width (+ width (ebnf-node-width node))))
  4995. (ebnf-node-entry sequence above)
  4996. (ebnf-node-height sequence (+ above below))
  4997. (ebnf-node-width sequence width))
  4998. (ebnf-log " sequence entry : %7.3f" (ebnf-node-entry sequence))
  4999. (ebnf-log " sequence height : %7.3f" (ebnf-node-height sequence))
  5000. (ebnf-log " sequence width : %7.3f" (ebnf-node-width sequence)))
  5001. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  5002. ;; Adjusting width
  5003. (defun ebnf-adjust-width (node width)
  5004. (cond
  5005. ((listp node)
  5006. (prog1
  5007. node
  5008. (while node
  5009. (setcar node (ebnf-adjust-width (car node) width))
  5010. (setq node (cdr node)))))
  5011. ((vectorp node)
  5012. (cond
  5013. ;; nothing to be done
  5014. ((= width (ebnf-node-width node))
  5015. node)
  5016. ;; left justify term
  5017. ((eq ebnf-justify-sequence 'left)
  5018. (ebnf-adjust-empty node width nil))
  5019. ;; right justify terms
  5020. ((eq ebnf-justify-sequence 'right)
  5021. (ebnf-adjust-empty node width t))
  5022. ;; centralize terms
  5023. (t
  5024. (ebnf-node-width-func node width)
  5025. (ebnf-node-width node width)
  5026. node)
  5027. ))
  5028. (t
  5029. node)
  5030. ))
  5031. (defun ebnf-adjust-empty (node width last-p)
  5032. (if (eq (ebnf-node-kind node) 'ebnf-generate-empty)
  5033. (progn
  5034. (ebnf-node-width node width)
  5035. node)
  5036. (let ((empty (ebnf-make-empty (- width (ebnf-node-width node)))))
  5037. (ebnf-make-dup-sequence node
  5038. (if last-p
  5039. (list empty node)
  5040. (list node empty))))))
  5041. ;; [terminal width-fun dim-fun entry height width name]
  5042. ;; [non-terminal width-fun dim-fun entry height width name]
  5043. ;; [empty width-fun dim-fun entry height width]
  5044. ;; [special width-fun dim-fun entry height width name]
  5045. ;; [repeat width-fun dim-fun entry height width times element]
  5046. ;; [except width-fun dim-fun entry height width element element]
  5047. ;;(defun ebnf-terminal-width (terminal width)
  5048. ;; )
  5049. ;; [alternative width-fun dim-fun entry height width list]
  5050. ;; [optional width-fun dim-fun entry height width element]
  5051. (defun ebnf-alternative-width (alternative width)
  5052. (ebnf-adjust-width (ebnf-node-list alternative)
  5053. (- width ebnf-horizontal-space)))
  5054. ;; [one-or-more width-fun dim-fun entry height width element separator]
  5055. ;; [zero-or-more width-fun dim-fun entry height width element separator]
  5056. (defun ebnf-element-width (or-more width)
  5057. (setq width (- width ebnf-horizontal-space))
  5058. (ebnf-node-list or-more
  5059. (ebnf-justify-list or-more
  5060. (ebnf-node-list or-more)
  5061. width))
  5062. (ebnf-node-separator or-more
  5063. (ebnf-justify-list or-more
  5064. (ebnf-node-separator or-more)
  5065. width)))
  5066. ;; [sequence width-fun dim-fun entry height width list]
  5067. (defun ebnf-sequence-width (sequence width)
  5068. (ebnf-node-list sequence
  5069. (ebnf-justify-list sequence
  5070. (ebnf-node-list sequence)
  5071. width)))
  5072. (defun ebnf-justify-list (node seq width)
  5073. (let ((seq-width (ebnf-node-width node)))
  5074. (if (= width seq-width)
  5075. seq
  5076. (cond
  5077. ;; left justify terms
  5078. ((eq ebnf-justify-sequence 'left)
  5079. (ebnf-justify node seq seq-width width t))
  5080. ;; right justify terms
  5081. ((eq ebnf-justify-sequence 'right)
  5082. (ebnf-justify node seq seq-width width nil))
  5083. ;; centralize terms -- element
  5084. ((vectorp seq)
  5085. (ebnf-adjust-width seq width))
  5086. ;; centralize terms -- list
  5087. (t
  5088. (let ((the-width (/ (- width seq-width) (length seq)))
  5089. (lis seq))
  5090. (while lis
  5091. (ebnf-adjust-width (car lis)
  5092. (+ (ebnf-node-width (car lis))
  5093. the-width))
  5094. (setq lis (cdr lis)))
  5095. seq))
  5096. ))))
  5097. (defun ebnf-justify (node seq seq-width width last-p)
  5098. (let ((term (car (if last-p (last seq) seq))))
  5099. (cond
  5100. ;; adjust empty term
  5101. ((eq (ebnf-node-kind term) 'ebnf-generate-empty)
  5102. (ebnf-node-width term (+ (- width seq-width)
  5103. (ebnf-node-width term)))
  5104. seq)
  5105. ;; insert empty at end ==> left justify
  5106. (last-p
  5107. (nconc seq
  5108. (list (ebnf-make-empty (- width seq-width)))))
  5109. ;; insert empty at beginning ==> right justify
  5110. (t
  5111. (cons (ebnf-make-empty (- width seq-width))
  5112. seq))
  5113. )))
  5114. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  5115. ;; Functions used by parsers
  5116. (defun ebnf-eps-add-context (name)
  5117. (let ((filename (ebnf-eps-filename name)))
  5118. (if (member filename ebnf-eps-context)
  5119. (error "Try to open an already opened EPS file: %s" filename)
  5120. (setq ebnf-eps-context (cons filename ebnf-eps-context)))
  5121. (ebnf-eps-header-footer-file filename)))
  5122. (defun ebnf-eps-remove-context (name)
  5123. (let ((filename (ebnf-eps-filename name)))
  5124. (if (member filename ebnf-eps-context)
  5125. (setq ebnf-eps-context (delete filename ebnf-eps-context))
  5126. (error "Try to close a not opened EPS file: %s" filename))))
  5127. (defun ebnf-eps-add-production (header)
  5128. (when ebnf-eps-executing
  5129. (if ebnf-eps-context
  5130. (let ((prod (assoc header ebnf-eps-production-list)))
  5131. (if prod
  5132. (setcdr prod (ebnf-dup-list
  5133. (append ebnf-eps-context (cdr prod))))
  5134. (setq ebnf-eps-production-list
  5135. (cons (cons header (ebnf-dup-list ebnf-eps-context))
  5136. ebnf-eps-production-list))))
  5137. (ebnf-eps-header-footer-file (ebnf-eps-filename header)))))
  5138. (defun ebnf-dup-list (old)
  5139. (let (new)
  5140. (while old
  5141. (setq new (cons (car old) new)
  5142. old (cdr old)))
  5143. (nreverse new)))
  5144. (defun ebnf-buffer-substring (chars)
  5145. (buffer-substring-no-properties
  5146. (point)
  5147. (progn
  5148. (skip-chars-forward chars ebnf-limit)
  5149. (point))))
  5150. ;; replace the range "\240-\377" (see `ebnf-range-regexp').
  5151. (defconst ebnf-8-bit-chars (ebnf-range-regexp "" ?\240 ?\377))
  5152. (defun ebnf-string (chars eos-char kind)
  5153. (forward-char)
  5154. (buffer-substring-no-properties
  5155. (point)
  5156. (progn
  5157. ;;(skip-chars-forward (concat chars "\240-\377") ebnf-limit)
  5158. (skip-chars-forward (concat chars ebnf-8-bit-chars) ebnf-limit)
  5159. (if (or (eobp) (/= (following-char) eos-char))
  5160. (error "Invalid %s: missing `%c'" kind eos-char)
  5161. (forward-char)
  5162. (1- (point))))))
  5163. (defun ebnf-get-string ()
  5164. (forward-char)
  5165. (buffer-substring-no-properties (point) (ebnf-end-of-string)))
  5166. (defun ebnf-end-of-string ()
  5167. (let ((n 1))
  5168. (while (> (logand n 1) 0)
  5169. (skip-chars-forward "^\"" ebnf-limit)
  5170. (setq n (- (skip-chars-backward "\\\\")))
  5171. (goto-char (+ (point) n 1))))
  5172. (if (= (preceding-char) ?\")
  5173. (1- (point))
  5174. (error "Missing `\"'")))
  5175. (defun ebnf-trim-right (str)
  5176. (let* ((len (1- (length str)))
  5177. (index len))
  5178. ;; to keep compatibility with Emacs 20 & 21:
  5179. ;; DO NOT REPLACE `?\ ' BY `?\s'
  5180. (while (and (> index 0) (= (aref str index) ?\ ))
  5181. (setq index (1- index)))
  5182. (if (= index len)
  5183. str
  5184. (substring str 0 (1+ index)))))
  5185. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  5186. ;; Vector creation
  5187. (defun ebnf-make-empty (&optional width)
  5188. (vector 'ebnf-generate-empty ; 0 generator
  5189. 'ignore ; 1 width fun
  5190. 'ignore ; 2 dimension fun
  5191. 0.0 ; 3 entry
  5192. 0.0 ; 4 height
  5193. (or width ebnf-horizontal-space))) ; 5 width
  5194. (defun ebnf-make-terminal (name)
  5195. (ebnf-make-terminal1 name
  5196. 'ebnf-generate-terminal
  5197. 'ebnf-terminal-dimension))
  5198. (defun ebnf-make-non-terminal (name)
  5199. (ebnf-make-terminal1 name
  5200. 'ebnf-generate-non-terminal
  5201. 'ebnf-non-terminal-dimension))
  5202. (defun ebnf-make-special (name)
  5203. (ebnf-make-terminal1 name
  5204. 'ebnf-generate-special
  5205. 'ebnf-special-dimension))
  5206. (defun ebnf-make-terminal1 (name gen-func dim-func)
  5207. (vector gen-func ; 0 generator
  5208. 'ignore ; 1 width fun
  5209. dim-func ; 2 dimension fun
  5210. 0.0 ; 3 entry
  5211. 0.0 ; 4 height
  5212. 0.0 ; 5 width
  5213. (let ((len (length name))) ; 6 name
  5214. (cond ((> len 3) name)
  5215. ((= len 3) (concat name " "))
  5216. ((= len 2) (concat " " name " "))
  5217. ((= len 1) (concat " " name " "))
  5218. (t " ")))
  5219. ebnf-default-p)) ; 7 is default?
  5220. (defun ebnf-make-one-or-more (list-part &optional sep-part)
  5221. (ebnf-make-or-more1 'ebnf-generate-one-or-more
  5222. 'ebnf-one-or-more-dimension
  5223. list-part
  5224. sep-part))
  5225. (defun ebnf-make-zero-or-more (list-part &optional sep-part)
  5226. (ebnf-make-or-more1 'ebnf-generate-zero-or-more
  5227. 'ebnf-zero-or-more-dimension
  5228. list-part
  5229. sep-part))
  5230. (defun ebnf-make-or-more1 (gen-func dim-func list-part sep-part)
  5231. (vector gen-func ; 0 generator
  5232. 'ebnf-element-width ; 1 width fun
  5233. dim-func ; 2 dimension fun
  5234. 0.0 ; 3 entry
  5235. 0.0 ; 4 height
  5236. 0.0 ; 5 width
  5237. (if (listp list-part) ; 6 element
  5238. (ebnf-make-sequence list-part)
  5239. list-part)
  5240. (if (and sep-part (listp sep-part)) ; 7 separator
  5241. (ebnf-make-sequence sep-part)
  5242. sep-part)))
  5243. (defun ebnf-make-production (name prod action)
  5244. (vector 'ebnf-generate-production ; 0 generator
  5245. 'ignore ; 1 width fun
  5246. 'ebnf-production-dimension ; 2 dimension fun
  5247. 0.0 ; 3 entry
  5248. 0.0 ; 4 height
  5249. 0.0 ; 5 width
  5250. name ; 6 production name
  5251. prod ; 7 production body
  5252. action)) ; 8 production action
  5253. (defun ebnf-make-alternative (body)
  5254. (vector 'ebnf-generate-alternative ; 0 generator
  5255. 'ebnf-alternative-width ; 1 width fun
  5256. 'ebnf-alternative-dimension ; 2 dimension fun
  5257. 0.0 ; 3 entry
  5258. 0.0 ; 4 height
  5259. 0.0 ; 5 width
  5260. body)) ; 6 alternative list
  5261. (defun ebnf-make-optional (body)
  5262. (vector 'ebnf-generate-optional ; 0 generator
  5263. 'ebnf-alternative-width ; 1 width fun
  5264. 'ebnf-optional-dimension ; 2 dimension fun
  5265. 0.0 ; 3 entry
  5266. 0.0 ; 4 height
  5267. 0.0 ; 5 width
  5268. body)) ; 6 optional element
  5269. (defun ebnf-make-except (factor exception)
  5270. (vector 'ebnf-generate-except ; 0 generator
  5271. 'ignore ; 1 width fun
  5272. 'ebnf-except-dimension ; 2 dimension fun
  5273. 0.0 ; 3 entry
  5274. 0.0 ; 4 height
  5275. 0.0 ; 5 width
  5276. factor ; 6 base element
  5277. exception)) ; 7 exception element
  5278. (defun ebnf-make-repeat (times primary &optional upper)
  5279. (vector 'ebnf-generate-repeat ; 0 generator
  5280. 'ignore ; 1 width fun
  5281. 'ebnf-repeat-dimension ; 2 dimension fun
  5282. 0.0 ; 3 entry
  5283. 0.0 ; 4 height
  5284. 0.0 ; 5 width
  5285. ; 6 times
  5286. (cond ((and times upper) ; L * U, L * L
  5287. (if (string= times upper)
  5288. (if (string= times "")
  5289. " * "
  5290. times)
  5291. (concat times " * " upper)))
  5292. (times ; L *
  5293. (concat times " *"))
  5294. (upper ; * U
  5295. (concat "* " upper))
  5296. (t ; *
  5297. " * "))
  5298. primary)) ; 7 element
  5299. (defun ebnf-make-sequence (seq)
  5300. (vector 'ebnf-generate-sequence ; 0 generator
  5301. 'ebnf-sequence-width ; 1 width fun
  5302. 'ebnf-sequence-dimension ; 2 dimension fun
  5303. 0.0 ; 3 entry
  5304. 0.0 ; 4 height
  5305. 0.0 ; 5 width
  5306. seq)) ; 6 sequence
  5307. (defun ebnf-make-dup-sequence (node seq)
  5308. (vector 'ebnf-generate-sequence ; 0 generator
  5309. 'ebnf-sequence-width ; 1 width fun
  5310. 'ebnf-sequence-dimension ; 2 dimension fun
  5311. (ebnf-node-entry node) ; 3 entry
  5312. (ebnf-node-height node) ; 4 height
  5313. (ebnf-node-width node) ; 5 width
  5314. seq)) ; 6 sequence
  5315. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  5316. ;; Optimizers used by parsers
  5317. (defun ebnf-token-except (element exception)
  5318. (cons (prog1
  5319. (car exception)
  5320. (setq exception (cdr exception)))
  5321. (and element ; EMPTY - A ==> EMPTY
  5322. (let ((kind (ebnf-node-kind element)))
  5323. (cond
  5324. ;; [ A ]- ==> A
  5325. ((and (null exception)
  5326. (eq kind 'ebnf-generate-optional))
  5327. (ebnf-node-list element))
  5328. ;; { A }- ==> { A }+
  5329. ((and (null exception)
  5330. (eq kind 'ebnf-generate-zero-or-more))
  5331. (ebnf-node-kind element 'ebnf-generate-one-or-more)
  5332. (ebnf-node-dimension-func element 'ebnf-one-or-more-dimension)
  5333. element)
  5334. ;; ( A | EMPTY )- ==> A
  5335. ;; ( A | B | EMPTY )- ==> A | B
  5336. ((and (null exception)
  5337. (eq kind 'ebnf-generate-alternative)
  5338. (eq (ebnf-node-kind
  5339. (car (last (ebnf-node-list element))))
  5340. 'ebnf-generate-empty))
  5341. (let ((elt (ebnf-node-list element))
  5342. bef)
  5343. (while (cdr elt)
  5344. (setq bef elt
  5345. elt (cdr elt)))
  5346. (if (null bef)
  5347. ;; this should not happen!!?!
  5348. (setq element (ebnf-make-empty
  5349. (ebnf-node-width element)))
  5350. (setcdr bef nil)
  5351. (setq elt (ebnf-node-list element))
  5352. (and (= (length elt) 1)
  5353. (setq element (car elt))))
  5354. element))
  5355. ;; A - B
  5356. (t
  5357. (ebnf-make-except element exception))
  5358. )))))
  5359. (defun ebnf-token-repeat (times repeat &optional upper)
  5360. (if (null (cdr repeat))
  5361. ;; n * EMPTY ==> EMPTY
  5362. repeat
  5363. ;; n * term
  5364. (cons (car repeat)
  5365. (ebnf-make-repeat times (cdr repeat) upper))))
  5366. (defun ebnf-token-optional (body)
  5367. (let ((kind (ebnf-node-kind body)))
  5368. (cond
  5369. ;; [ EMPTY ] ==> EMPTY
  5370. ((eq kind 'ebnf-generate-empty)
  5371. nil)
  5372. ;; [ { A }* ] ==> { A }*
  5373. ((eq kind 'ebnf-generate-zero-or-more)
  5374. body)
  5375. ;; [ { A }+ ] ==> { A }*
  5376. ((eq kind 'ebnf-generate-one-or-more)
  5377. (ebnf-node-kind body 'ebnf-generate-zero-or-more)
  5378. body)
  5379. ;; [ A | B ] ==> A | B | EMPTY
  5380. ((eq kind 'ebnf-generate-alternative)
  5381. (ebnf-node-list body (nconc (ebnf-node-list body)
  5382. (list (ebnf-make-empty))))
  5383. body)
  5384. ;; [ A ]
  5385. (t
  5386. (ebnf-make-optional body))
  5387. )))
  5388. (defun ebnf-token-alternative (body sequence)
  5389. (if (null body)
  5390. (if (cdr sequence)
  5391. ;; no alternative
  5392. sequence
  5393. ;; empty element
  5394. (cons (car sequence) ; token
  5395. (ebnf-make-empty)))
  5396. (cons (car sequence) ; token
  5397. (let ((seq (cdr sequence)))
  5398. (if (and (= (length body) 1) (null seq))
  5399. ;; alternative with one element
  5400. (car body)
  5401. ;; a real alternative
  5402. (ebnf-make-alternative (nreverse (if seq
  5403. (cons seq body)
  5404. body))))))))
  5405. (defun ebnf-token-sequence (sequence)
  5406. (cond
  5407. ;; null sequence
  5408. ((null sequence)
  5409. (ebnf-make-empty))
  5410. ;; sequence with only one element
  5411. ((= (length sequence) 1)
  5412. (car sequence))
  5413. ;; a real sequence
  5414. (t
  5415. (ebnf-make-sequence (nreverse sequence)))
  5416. ))
  5417. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  5418. ;; Variables used by parsers
  5419. (defconst ebnf-comment-table
  5420. (let ((table (make-vector 256 nil)))
  5421. ;; Override special comment character:
  5422. (aset table ?< 'newline)
  5423. (aset table ?> 'keep-line)
  5424. (aset table ?^ 'form-feed)
  5425. table)
  5426. "Vector used to map characters to a special comment token.")
  5427. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  5428. ;; Log message
  5429. (defun ebnf-log-header (format-str &rest args)
  5430. (when ebnf-log
  5431. (apply
  5432. 'ebnf-log
  5433. (concat
  5434. "\n\n===============================================================\n\n"
  5435. format-str)
  5436. args)))
  5437. (defun ebnf-log (format-str &rest args)
  5438. (when ebnf-log
  5439. (with-current-buffer (get-buffer-create "*Ebnf2ps Log*")
  5440. (goto-char (point-max))
  5441. (insert (apply 'format format-str args) "\n"))))
  5442. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  5443. ;; To make this file smaller, some commands go in a separate file.
  5444. ;; But autoload them here to make the separation invisible.
  5445. (autoload 'ebnf-abn-parser "ebnf-abn"
  5446. "ABNF parser.")
  5447. (autoload 'ebnf-abn-initialize "ebnf-abn"
  5448. "Initialize ABNF token table.")
  5449. (autoload 'ebnf-bnf-parser "ebnf-bnf"
  5450. "EBNF parser.")
  5451. (autoload 'ebnf-bnf-initialize "ebnf-bnf"
  5452. "Initialize EBNF token table.")
  5453. (autoload 'ebnf-iso-parser "ebnf-iso"
  5454. "ISO EBNF parser.")
  5455. (autoload 'ebnf-iso-initialize "ebnf-iso"
  5456. "Initialize ISO EBNF token table.")
  5457. (autoload 'ebnf-yac-parser "ebnf-yac"
  5458. "Yacc/Bison parser.")
  5459. (autoload 'ebnf-yac-initialize "ebnf-yac"
  5460. "Initializations for Yacc/Bison parser.")
  5461. (autoload 'ebnf-ebx-parser "ebnf-ebx"
  5462. "EBNFX parser.")
  5463. (autoload 'ebnf-ebx-initialize "ebnf-ebx"
  5464. "Initializations for EBNFX parser.")
  5465. (autoload 'ebnf-dtd-parser "ebnf-dtd"
  5466. "DTD parser.")
  5467. (autoload 'ebnf-dtd-initialize "ebnf-dtd"
  5468. "Initializations for DTD parser.")
  5469. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  5470. (provide 'ebnf2ps)
  5471. ;;; ebnf2ps.el ends here