123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640 |
- #include <u.h>
- #include <libc.h>
- #include <ctype.h>
- #include <bio.h>
- enum
- {
- SSIZE = 10,
- Maxnh= 8, /* highest NH level */
- HH= 4, /* heading level used for SH and NH */
- Maxmstack= 10, /* deepest macro/string nesting */
- Narg= 20, /* max args to a macro */
- Maxsstack= 5, /* deepest nesting of .so's */
- Nline= 1024,
- Maxget= 10,
- Maxif = 20,
- Maxfsp = 100,
- /* list types */
- Lordered = 1,
- Lunordered,
- Ldef,
- Lother,
- };
- char *delim = "$$";
- char *basename;
- char *title;
- int eqnmode;
- int quiet;
- float indent; /* from .in */
- Biobuf bout;
- int isup;
- int isdown;
- int debug;
- int nh[Maxnh];
- int ifwastrue[Maxif];
- int list, listnum, example;
- int hangingau, hangingdt, hanginghead, hangingcenter;
- int indirective, paragraph, sol, titleseen, ignore_nl, weBref;
- void dohangingcenter(void);
- typedef struct Goobie Goobie;
- typedef struct Goobieif Goobieif;
- struct Goobie
- {
- char *name;
- void (*f)(int, char**);
- };
- typedef void F(int, char**);
- typedef void Fif(char*, char*);
- struct Goobieif
- {
- char *name;
- Fif *f;
- };
- /* if, ie */
- Fif g_as, g_ds, g_el, g_ie, g_if;
- Goobieif gtabif[] = {
- { "as", g_as },
- { "ds", g_ds },
- { "if", g_if },
- { "ie", g_ie },
- { "el", g_el },
- { nil, nil },
- };
- /* pseudo ops */
- F g_notyet, g_ignore, g_hrule, g_startgif;
- /* ms macros */
- F g_AU, g_B, g_BI, g_CW, g_I, g_IP, g_LP, g_PP, g_SH, g_NH;
- F g_P1, g_P2, g_TL, g_R, g_AB, g_AE, g_EQ, g_TS, g_TE, g_FS, g_FE;
- F g_PY, g_IH, g_MH, g_HO, g_BX, g_QS, g_QE, g_RS, g_RE;
- /* pictures macro */
- F g_BP;
- /* real troff */
- F g_br, g_ft, g_sp, g_de, g_lf, g_so, g_rm, g_in;
- F g_nr, g_ig, g_RT, g_BS, g_BE, g_LB, g_ta;
- /* macros to include ML in output */
- F g__H, g__T;
- Goobie gtab[] =
- {
- { "_T", g__T, },
- { "_H", g__H, },
- { "1C", g_ignore, },
- { "2C", g_ignore, },
- { "AB", g_AB, },
- { "AE", g_AE, },
- { "AI", g_ignore, },
- { "AU", g_AU, },
- { "B", g_B, },
- { "B1", g_hrule, },
- { "B2", g_hrule, },
- { "BI", g_BI, },
- { "BP", g_BP, },
- { "BT", g_ignore, },
- { "BX", g_BX, },
- { "CW", g_CW, },
- { "CT", g_ignore, },
- { "DA", g_ignore, },
- { "DE", g_P2, },
- { "DS", g_P1, },
- { "EG", g_ignore, },
- { "EN", g_ignore, },
- { "EQ", g_startgif, },
- { "FE", g_FE, },
- { "FP", g_ignore, },
- { "FS", g_FS, },
- { "HO", g_HO, },
- { "I", g_I, },
- { "IH", g_IH, },
- { "IM", g_ignore, },
- { "IP", g_IP, },
- { "KE", g_ignore, },
- { "KF", g_ignore, },
- { "KS", g_ignore, },
- { "LG", g_ignore, },
- { "LP", g_LP, },
- { "LT", g_ignore, },
- { "MF", g_ignore, },
- { "MH", g_MH, },
- { "MR", g_ignore, },
- { "ND", g_ignore, },
- { "NH", g_NH, },
- { "NL", g_ignore, },
- { "P1", g_P1, },
- { "P2", g_P2, },
- { "PE", g_ignore, },
- { "PF", g_ignore, },
- { "PP", g_PP, },
- { "PS", g_startgif, },
- { "PY", g_PY, },
- { "QE", g_QE, },
- { "QP", g_QS, },
- { "QS", g_QS, },
- { "R", g_R, },
- { "RE", g_RE, },
- { "RP", g_ignore, },
- { "RS", g_RS, },
- { "SG", g_ignore, },
- { "SH", g_SH, },
- { "SM", g_ignore, },
- { "TA", g_ignore, },
- { "TE", g_ignore, },
- { "TH", g_TL, },
- { "TL", g_TL, },
- { "TM", g_ignore, },
- { "TR", g_ignore, },
- { "TS", g_startgif, },
- { "UL", g_I, },
- { "UX", g_ignore, },
- { "WH", g_ignore, },
- { "RT", g_RT, },
- { "br", g_br, },
- { "ti", g_br, },
- { "nf", g_P1, },
- { "fi", g_P2, },
- { "ft", g_ft, },
- { "sp", g_sp, },
- { "rm", g_rm, },
- { "de", g_de, },
- { "am", g_de, },
- { "lf", g_lf, },
- { "so", g_so, },
- { "ps", g_ignore },
- { "vs", g_ignore },
- { "nr", g_nr },
- { "in", g_in },
- { "ne", g_ignore },
- { "ig", g_ig },
- { "BS", g_BS },
- { "BE", g_BE },
- { "LB", g_LB },
- { nil, nil },
- };
- typedef struct Entity Entity;
- struct Entity
- {
- char *name;
- int value;
- };
- Entity entity[] =
- {
- { "&#SPACE;", L' ', },
- { "&#RS;", L'\n', },
- { "&#RE;", L'\r', },
- { """, L'"', },
- { "Æ", L'Æ', },
- { "Á", L'Á', },
- { "Â", L'Â', },
- { "À", L'À', },
- { "Å", L'Å', },
- { "Ã", L'Ã', },
- { "Ä", L'Ä', },
- { "Ç", L'Ç', },
- { "Ð", L'Ð', },
- { "É", L'É', },
- { "Ê", L'Ê', },
- { "È", L'È', },
- { "Ë", L'Ë', },
- { "Í", L'Í', },
- { "Î", L'Î', },
- { "Ì", L'Ì', },
- { "Ï", L'Ï', },
- { "Ñ", L'Ñ', },
- { "Ó", L'Ó', },
- { "Ô", L'Ô', },
- { "Ò", L'Ò', },
- { "Ø", L'Ø', },
- { "Õ", L'Õ', },
- { "Ö", L'Ö', },
- { "Þ", L'Þ', },
- { "Ú", L'Ú', },
- { "Û", L'Û', },
- { "Ù", L'Ù', },
- { "Ü", L'Ü', },
- { "Ý", L'Ý', },
- { "á", L'á', },
- { "â", L'â', },
- { "æ", L'æ', },
- { "à", L'à', },
- { "&", L'&', },
- { "å", L'å', },
- { "ã", L'ã', },
- { "ä", L'ä', },
- { "ç", L'ç', },
- { "é", L'é', },
- { "ê", L'ê', },
- { "è", L'è', },
- { "ð", L'ð', },
- { "ë", L'ë', },
- { ">", L'>', },
- { "í", L'í', },
- { "î", L'î', },
- { "ì", L'ì', },
- { "ï", L'ï', },
- { "<", L'<', },
- { "ñ", L'ñ', },
- { "ó", L'ó', },
- { "ô", L'ô', },
- { "ò", L'ò', },
- { "ø", L'ø', },
- { "õ", L'õ', },
- { "ö", L'ö', },
- { "ß", L'ß', },
- { "þ", L'þ', },
- { "ú", L'ú', },
- { "û", L'û', },
- { "ù", L'ù', },
- { "ü", L'ü', },
- { "ý", L'ý', },
- { "ÿ", L'ÿ', },
- { "¡", L'¡', },
- { "¢", L'¢', },
- { "£", L'£', },
- { "¤", L'¤', },
- { "¥", L'¥', },
- { "¦", L'¦', },
- { "§", L'§', },
- { "¨", L'¨', },
- { "©", L'©', },
- { "ª", L'ª', },
- { "«", L'«', },
- { "¬", L'¬', },
- { "­", L'', },
- { "®", L'®', },
- { "¯", L'¯', },
- { "°", L'°', },
- { "±", L'±', },
- { "²", L'²', },
- { "³", L'³', },
- { "´", L'´', },
- { "µ", L'µ', },
- { "¶", L'¶', },
- { "·", L'·', },
- { "¸", L'¸', },
- { "¹", L'¹', },
- { "º", L'º', },
- { "»", L'»', },
- { "¼", L'¼', },
- { "½", L'½', },
- { "¾", L'¾', },
- { "¿", L'¿', },
- { "*", L'•', },
- { "¤", L'□', },
- { "º", L'◊', },
- { "(tm)", L'™', },
- {"Α", L'Α',},
- {"Β", L'Β',},
- {"Γ", L'Γ',},
- {"Δ", L'Δ',},
- {"Ε", L'Ε',},
- {"Ζ", L'Ζ',},
- {"Η", L'Η',},
- {"Θ", L'Θ',},
- {"Ι", L'Ι',},
- {"Κ", L'Κ',},
- {"Λ", L'Λ',},
- {"Μ", L'Μ',},
- {"Ν", L'Ν',},
- {"Ξ", L'Ξ',},
- {"Ο", L'Ο',},
- {"Π", L'Π',},
- {"Ρ", L'Ρ',},
- {"΢", L'',},
- {"Σ", L'Σ',},
- {"Τ", L'Τ',},
- {"Υ", L'Υ',},
- {"Φ", L'Φ',},
- {"Χ", L'Χ',},
- {"Ψ", L'Ψ',},
- {"Ω", L'Ω',},
- {"α", L'α',},
- {"β", L'β',},
- {"γ", L'γ',},
- {"δ", L'δ',},
- {"ε", L'ε',},
- {"ζ", L'ζ',},
- {"η", L'η',},
- {"θ", L'θ',},
- {"ι", L'ι',},
- {"κ", L'κ',},
- {"λ", L'λ',},
- {"μ", L'μ',},
- {"ν", L'ν',},
- {"ξ", L'ξ',},
- {"ο", L'ο',},
- {"π", L'π',},
- {"ρ", L'ρ',},
- {"ς", L'ς',},
- {"σ", L'σ',},
- {"τ", L'τ',},
- {"υ", L'υ',},
- {"φ", L'φ',},
- {"χ", L'χ',},
- {"ψ", L'ψ',},
- {"ω", L'ω',},
- { "<-", L'←', },
- { "^", L'↑', },
- { "->", L'→', },
- { "v", L'↓', },
- { "!=", L'≠', },
- { "<=", L'≤', },
- { "...", L'⋯', },
- {"∈", L'∈', },
- {"–", L'–', },
- {"—", L'—', },
- { "CYRILLIC XYZZY", L'й', },
- { "CYRILLIC XYZZY", L'ъ', },
- { "CYRILLIC Y", L'ь', },
- { "CYRILLIC YA", L'я', },
- { "CYRILLIC YA", L'ё', },
- { "¿", L'ℱ', },
- { nil, 0 },
- };
- typedef struct Troffspec Troffspec;
- struct Troffspec
- {
- char *name;
- char *value;
- };
- Troffspec tspec[] =
- {
- { "A*", "Å", },
- { "o\"", "ö", },
- { "ff", "ff", },
- { "fi", "fi", },
- { "fl", "fl", },
- { "Fi", "ffi", },
- { "ru", "_", },
- { "em", "­", },
- { "14", "¼", },
- { "12", "½", },
- { "co", "©", },
- { "de", "°", },
- { "dg", "¡", },
- { "fm", "´", },
- { "rg", "®", },
- { "bu", "*", },
- { "sq", "¤", },
- { "hy", "-", },
- { "pl", "+", },
- { "mi", "-", },
- { "mu", "×", },
- { "di", "÷", },
- { "eq", "=", },
- { "==", "==", },
- { ">=", ">=", },
- { "<=", "<=", },
- { "!=", "!=", },
- { "+-", "±", },
- { "no", "¬", },
- { "sl", "/", },
- { "ap", "&", },
- { "~=", "~=", },
- { "pt", "oc", },
- { "gr", "GRAD", },
- { "->", "->", },
- { "<-", "<-", },
- { "ua", "^", },
- { "da", "v", },
- { "is", "Integral", },
- { "pd", "DIV", },
- { "if", "oo", },
- { "sr", "-/", },
- { "sb", "(~", },
- { "sp", "~)", },
- { "cu", "U", },
- { "ca", "(^)", },
- { "ib", "(=", },
- { "ip", "=)", },
- { "mo", "C", },
- { "es", "Ø", },
- { "aa", "´", },
- { "ga", "`", },
- { "ci", "O", },
- { "L1", "DEATHSTAR", },
- { "sc", "§", },
- { "dd", "++", },
- { "lh", "<=", },
- { "rh", "=>", },
- { "lt", "(", },
- { "rt", ")", },
- { "lc", "|", },
- { "rc", "|", },
- { "lb", "(", },
- { "rb", ")", },
- { "lf", "|", },
- { "rf", "|", },
- { "lk", "|", },
- { "rk", "|", },
- { "bv", "|", },
- { "ts", "s", },
- { "br", "|", },
- { "or", "|", },
- { "ul", "_", },
- { "rn", " ", },
- { "**", "*", },
- { "tm", "™", },
- { nil, nil, },
- };
- typedef struct Font Font;
- struct Font
- {
- char *start;
- char *end;
- };
- Font bfont = { "<B>", "</B>" };
- Font ifont = { "<I>", "</I>" };
- Font bifont = { "<B><I>", "</I></B>" };
- Font cwfont = { "<TT>", "</TT>" };
- Font *fstack[Maxfsp];
- int fsp = -1;
- typedef struct String String;
- struct String
- {
- String *next;
- char *name;
- char *val;
- };
- String *numregs, *strings;
- char *strstack[Maxmstack];
- char *mustfree[Maxmstack];
- int strsp = -1;
- int elsetop = -1;
- typedef struct Mstack Mstack;
- struct Mstack
- {
- char *ptr;
- char *argv[Narg+1];
- };
- String *macros;
- Mstack mstack[Maxmstack];
- int msp = -1;
- typedef struct Srcstack Srcstack;
- struct Srcstack
- {
- char filename[256];
- int fd;
- int lno;
- int rlno;
- Biobuf in;
- };
- Srcstack sstack[Maxsstack];
- Srcstack *ssp = &sstack[-1];
- char token[128];
- void closel(void);
- void closefont(void);
- void*
- emalloc(uint n)
- {
- void *p;
- p = mallocz(n, 1);
- if(p == nil){
- fprint(2, "ms2html: malloc failed: %r\n");
- exits("malloc");
- }
- return p;
- }
- /* define a string variable */
- void
- dsnr(char *name, char *val, String **l)
- {
- String *s;
- for(s = *l; s != nil; s = *l){
- if(strcmp(s->name, name) == 0)
- break;
- l = &s->next;
- }
- if(s == nil){
- s = emalloc(sizeof(String));
- *l = s;
- s->name = strdup(name);
- } else
- free(s->val);
- s->val = strdup(val);
- }
- void
- ds(char *name, char *val)
- {
- dsnr(name, val, &strings);
- }
- /* look up a defined string */
- char*
- getds(char *name)
- {
- String *s;
- for(s = strings; s != nil; s = s->next)
- if(strcmp(name, s->name) == 0)
- break;
- if(s != nil)
- return s->val;
- return "";
- }
- char *
- getnr(char *name)
- {
- String *s;
- for(s = numregs; s != nil; s = s->next)
- if(strcmp(name, s->name) == 0)
- break;
- if(s != nil)
- return s->val;
- return "0";
- }
- void
- pushstr(char *p)
- {
- if(p == nil)
- return;
- if(strsp >= Maxmstack - 1)
- return;
- strstack[++strsp] = p;
- }
- /* lookup a defined macro */
- char*
- getmacro(char *name)
- {
- String *s;
- for(s = macros; s != nil; s = s->next)
- if(strcmp(name, s->name) == 0)
- return s->val;
- return nil;
- }
- enum
- {
- Dstring,
- Macro,
- Input,
- };
- int lastsrc;
- void
- pushsrc(char *name)
- {
- Dir *d;
- int fd;
- if(ssp == &sstack[Maxsstack-1]){
- fprint(2, "ms2html: .so's too deep\n");
- return;
- }
- d = nil;
- if(name == nil){
- d = dirfstat(0);
- if(d == nil){
- fprint(2, "ms2html: can't stat %s: %r\n", name);
- return;
- }
- name = d->name;
- fd = 0;
- } else {
- fd = open(name, OREAD);
- if(fd < 0){
- fprint(2, "ms2html: can't open %s: %r\n", name);
- return;
- }
- }
- ssp++;
- ssp->fd = fd;
- Binit(&ssp->in, fd, OREAD);
- snprint(ssp->filename, sizeof(ssp->filename), "%s", name);
- ssp->lno = ssp->rlno = 1;
- free(d);
- }
- /* get next logical byte. from stdin or a defined string */
- int
- getrune(void)
- {
- int i;
- Rune r;
- int c;
- Mstack *m;
- while(strsp >= 0){
- i = chartorune(&r, strstack[strsp]);
- if(r != 0){
- strstack[strsp] += i;
- lastsrc = Dstring;
- return r;
- }
- if (mustfree[strsp]) {
- free(mustfree[strsp]);
- mustfree[strsp] = nil;
- }
- strsp--;
- }
- while(msp >= 0){
- m = &mstack[msp];
- i = chartorune(&r, m->ptr);
- if(r != 0){
- m->ptr += i;
- lastsrc = Macro;
- return r;
- }
- for(i = 0; m->argv[i] != nil; i++)
- free(m->argv[i]);
- msp--;
- }
- lastsrc = Input;
- do {
- if(ssp < sstack)
- return -1;
- c = Bgetrune(&ssp->in);
- if(c >= 0){
- r = c;
- break;
- }
- close(ssp->fd);
- ssp--;
- } while(r < 0);
- return r;
- }
- void
- ungetrune(void)
- {
- switch(lastsrc){
- case Dstring:
- if(strsp >= 0)
- strstack[strsp]--;
- break;
- case Macro:
- if(msp >= 0)
- mstack[msp].ptr--;
- break;
- case Input:
- if(ssp >= sstack)
- Bungetrune(&ssp->in);
- break;
- }
- }
- int vert;
- char*
- changefont(Font *f)
- {
- token[0] = 0;
- if(fsp == Maxfsp)
- return token;
- if(fsp >= 0 && fstack[fsp])
- strcpy(token, fstack[fsp]->end);
- if(f != nil)
- strcat(token, f->start);
- fstack[++fsp] = f;
- return token;
- }
- char*
- changebackfont(void)
- {
- token[0] = 0;
- if(fsp >= 0){
- if(fstack[fsp])
- strcpy(token, fstack[fsp]->end);
- fsp--;
- }
- if(fsp >= 0 && fstack[fsp])
- strcat(token, fstack[fsp]->start);
- return token;
- }
- char*
- changesize(int amount)
- {
- static int curamount;
- static char buf[200];
- int i;
- buf[0] = 0;
- if (curamount >= 0)
- for (i = 0; i < curamount; i++)
- strcat(buf, "</big>");
- else
- for (i = 0; i < -curamount; i++)
- strcat(buf, "</small>");
- curamount = 0;
- if (amount >= 0)
- for (i = 0; i < amount; i++)
- strcat(buf, "<big>");
- else
- for (i = 0; i < -amount; i++)
- strcat(buf, "<small>");
- curamount = amount;
- return buf;
- }
- /* get next logical character. expand it with escapes */
- char*
- getnext(void)
- {
- int r;
- Entity *e;
- Troffspec *t;
- Rune R;
- char str[4];
- static char buf[8];
- r = getrune();
- if(r < 0)
- return nil;
- if(r > 128 || r == '<' || r == '>'){
- for(e = entity; e->name; e++)
- if(e->value == r)
- return e->name;
- sprint(buf, "&#%d;", r);
- return buf;
- }
- if (r == delim[eqnmode]){
- if (eqnmode == 0){
- eqnmode = 1;
- return changefont(&ifont);
- }
- eqnmode = 0;
- return changebackfont();
- }
- switch(r){
- case '\\':
- r = getrune();
- if(r < 0)
- return nil;
- switch(r){
- case ' ':
- return " ";
- /* chars to ignore */
- case '&':
- case '|':
- case '%':
- return "";
- /* small space in troff, nothing in nroff */
- case '^':
- return getnext();
- /* ignore arg */
- case 'k':
- getrune();
- return getnext();
- /* comment */
- case '"':
- while(getrune() != '\n')
- ;
- return "\n";
- /* ignore line */
- case '!':
- while(getrune() != '\n')
- ;
- ungetrune();
- return getnext();
- /* defined strings */
- case '*':
- r = getrune();
- if(r == '('){
- str[0] = getrune();
- str[1] = getrune();
- str[2] = 0;
- } else {
- str[0] = r;
- str[1] = 0;
- }
- pushstr(getds(str));
- return getnext();
- /* macro args */
- case '$':
- r = getrune();
- if(r < '1' || r > '9'){
- token[0] = '\\';
- token[1] = '$';
- token[2] = r;
- token[3] = 0;
- return token;
- }
- r -= '0';
- if(msp >= 0)
- pushstr(mstack[msp].argv[r]);
- return getnext();
- /* special chars */
- case '(':
- token[0] = getrune();
- token[1] = getrune();
- token[2] = 0;
- for(t = tspec; t->name; t++)
- if(strcmp(token, t->name) == 0)
- return t->value;
- return "¿";
- /* ignore immediately following newline */
- case 'c':
- r = getrune();
- if (r == '\n') {
- sol = ignore_nl = 1;
- if (indirective)
- break;
- }
- else
- ungetrune();
- return getnext();
- /* escape backslash */
- case 'e':
- return "\\";
- break;
- /* font change */
- case 'f':
- r = getrune();
- switch(r){
- case '(':
- str[0] = getrune();
- str[1] = getrune();
- str[2] = 0;
- token[0] = 0;
- if(strcmp("BI", str) == 0)
- return changefont(&bifont);
- else if(strcmp("CW", str) == 0)
- return changefont(&cwfont);
- else
- return changefont(nil);
- case '3':
- case 'B':
- return changefont(&bfont);
- case '2':
- case 'I':
- return changefont(&ifont);
- case '4':
- return changefont(&bifont);
- case '5':
- return changefont(&cwfont);
- case 'P':
- return changebackfont();
- case 'R':
- default:
- return changefont(nil);
- }
- /* number register */
- case 'n':
- r = getrune();
- if (r == '(') /*)*/ {
- r = getrune();
- if (r < 0)
- return nil;
- str[0] = r;
- r = getrune();
- if (r < 0)
- return nil;
- str[1] = r;
- str[2] = 0;
- }
- else {
- str[0] = r;
- str[1] = 0;
- }
- pushstr(getnr(str));
- return getnext();
- /* font size */
- case 's':
- r = getrune();
- switch(r){
- case '0':
- return changesize(0);
- case '-':
- r = getrune();
- if (!isdigit(r))
- return getnext();
- return changesize(-(r - '0'));
- case '+':
- r = getrune();
- if (!isdigit(r))
- return getnext();
- return changesize(r - '0');
- }
- return getnext();
- /* vertical movement */
- case 'v':
- r = getrune();
- if(r != '\''){
- ungetrune();
- return getnext();
- }
- r = getrune();
- if(r != '-')
- vert--;
- else
- vert++;
- while(r != '\'' && r != '\n')
- r = getrune();
- if(r != '\'')
- ungetrune();
-
- if(vert > 0)
- return "^";
- return getnext();
-
- /* horizontal line */
- case 'l':
- r = getrune();
- if(r != '\''){
- ungetrune();
- return "<HR>";
- }
- while(getrune() != '\'')
- ;
- return "<HR>";
- /* character height and slant */
- case 'S':
- case 'H':
- r = getrune();
- if(r != '\''){
- ungetrune();
- return "<HR>";
- }
- while(getrune() != '\'')
- ;
- return getnext();
- /* digit-width space */
- case '0':
- return " ";
- /*for .if, .ie, .el */
- case '{':
- return "\\{"; /*}*/
- case '}':
- return "";
- /* up and down */
- case 'u':
- if (isdown) {
- isdown = 0;
- return "</sub>";
- }
- isup = 1;
- return "<sup>";
- case 'd':
- if (isup) {
- isup = 0;
- return "</sup>";
- }
- isdown = 1;
- return "<sub>";
- }
- break;
- case '&':
- if(msp >= 0 || strsp >= 0)
- return "&";
- return "&";
- case '<':
- if(msp >= 0 || strsp >= 0)
- return "<";
- return "<";
- case '>':
- if(msp >= 0 || strsp >= 0)
- return ">";
- return ">";
- }
- if (r < Runeself) {
- token[0] = r;
- token[1] = 0;
- }
- else {
- R = r;
- token[runetochar(token,&R)] = 0;
- }
- return token;
- }
- /* if arg0 is set, read up to (and expand) to the next whitespace, else to the end of line */
- char*
- copyline(char *p, char *e, int arg0)
- {
- int c;
- Rune r;
- char *p1;
- while((c = getrune()) == ' ' || c == '\t')
- ;
- for(indirective = 1; p < e; c = getrune()) {
- if (c < 0)
- goto done;
- switch(c) {
- case '\\':
- break;
- case '\n':
- if (arg0)
- ungetrune();
- goto done;
- case ' ':
- case '\t':
- if (arg0)
- goto done;
- default:
- r = c;
- p += runetochar(p,&r);
- continue;
- }
- ungetrune();
- p1 = getnext();
- if (p1 == nil)
- goto done;
- if (*p1 == '\n') {
- if (arg0)
- ungetrune();
- break;
- }
- while((*p = *p1++) && p < e)
- p++;
- }
- done:
- indirective = 0;
- *p++ = 0;
- return p;
- }
- char*
- copyarg(char *p, char *e, int *nullarg)
- {
- int c, quoted, last;
- Rune r;
- *nullarg = 0;
- quoted = 0;
- do{
- c = getrune();
- } while(c == ' ' || c == '\t');
- if(c == '"'){
- quoted = 1;
- *nullarg = 1;
- c = getrune();
- }
- if(c == '\n')
- goto done;
- last = 0;
- for(; p < e; c = getrune()) {
- if (c < 0)
- break;
- switch(c) {
- case '\n':
- ungetrune();
- goto done;
- case '\\':
- r = c;
- p += runetochar(p,&r);
- if(last == '\\')
- r = 0;
- break;
- case ' ':
- case '\t':
- if(!quoted && last != '\\')
- goto done;
- r = c;
- p += runetochar(p,&r);
- break;
- case '"':
- if(quoted && last != '\\')
- goto done;
- r = c;
- p += runetochar(p,&r);
- break;
- default:
- r = c;
- p += runetochar(p,&r);
- break;
- }
- last = r;
- }
- done:
- *p++ = 0;
- return p;
- }
- int
- parseargs(char *p, char *e, char **argv)
- {
- int argc;
- char *np;
- int nullarg;
- indirective = 1;
- *p++ = 0;
- for(argc = 1; argc < Narg; argc++){
- np = copyarg(p, e, &nullarg);
- if(nullarg==0 && np == p+1)
- break;
- argv[argc] = p;
- p = np;
- }
- argv[argc] = nil;
- indirective = 0;
- return argc;
- }
- void
- dodirective(void)
- {
- char *p, *e;
- Goobie *g;
- Goobieif *gif;
- char line[Nline], *line1;
- int i, argc;
- char *argv[Narg];
- Mstack *m;
- /* read line, translate special bytes */
- e = line + sizeof(line) - UTFmax - 1;
- line1 = copyline(line, e, 1);
- if (!line[0])
- return;
- argv[0] = line;
- /* first look through user defined macros */
- p = getmacro(argv[0]);
- if(p != nil){
- if(msp == Maxmstack-1){
- fprint(2, "ms2html: macro stack overflow\n");
- return;
- }
- argc = parseargs(line1, e, argv);
- m = &mstack[++msp];
- m->ptr = p;
- memset(m->argv, 0, sizeof(m->argv));
- for(i = 0; i < argc; i++)
- m->argv[i] = strdup(argv[i]);
- return;
- }
- /* check for .if or .ie */
- for(gif = gtabif; gif->name; gif++)
- if(strcmp(gif->name, argv[0]) == 0){
- (*gif->f)(line1, e);
- return;
- }
- argc = parseargs(line1, e, argv);
- /* try standard ms macros */
- for(g = gtab; g->name; g++)
- if(strcmp(g->name, argv[0]) == 0){
- (*g->f)(argc, argv);
- return;
- }
- if(debug)
- fprint(2, "stdin %d(%s:%d): unknown directive %s\n",
- ssp->lno, ssp->filename, ssp->rlno, line);
- }
- void
- printarg(char *a)
- {
- char *e, *p;
-
- e = a + strlen(a);
- pushstr(a);
- while(strsp >= 0 && strstack[strsp] >= a && strstack[strsp] < e){
- p = getnext();
- if(p == nil)
- return;
- Bprint(&bout, "%s", p);
- }
- }
- void
- printargs(int argc, char **argv)
- {
- argc--;
- argv++;
- while(--argc > 0){
- printarg(*argv++);
- Bprint(&bout, " ");
- }
- if(argc == 0)
- printarg(*argv);
- }
- void
- dohangingdt(void)
- {
- switch(hangingdt){
- case 3:
- hangingdt--;
- break;
- case 2:
- Bprint(&bout, "<dd>");
- hangingdt = 0;
- break;
- }
- }
- void
- dohangingau(void)
- {
- if(hangingau == 0)
- return;
- Bprint(&bout, "</I></DL>\n");
- hangingau = 0;
- }
- void
- dohanginghead(void)
- {
- if(hanginghead == 0)
- return;
- Bprint(&bout, "</H%d>\n", hanginghead);
- hanginghead = 0;
- }
- /*
- * convert a man page to html and output
- */
- void
- doconvert(void)
- {
- char c, *p;
- Tm *t;
- pushsrc(nil);
- sol = 1;
- Bprint(&bout, "<html>\n");
- Bflush(&bout);
- for(;;){
- p = getnext();
- if(p == nil)
- break;
- c = *p;
- if(c == '.' && sol){
- dodirective();
- dohangingdt();
- ssp->lno++;
- ssp->rlno++;
- sol = 1;
- } else if(c == '\n'){
- if (ignore_nl)
- ignore_nl = 0;
- else {
- if(hangingau)
- Bprint(&bout, "<br>\n");
- else
- Bprint(&bout, "%s", p);
- dohangingdt();
- }
- ssp->lno++;
- ssp->rlno++;
- sol = 1;
- } else{
- Bprint(&bout, "%s", p);
- ignore_nl = sol = 0;
- }
- }
- dohanginghead();
- dohangingdt();
- closel();
- if(fsp >= 0 && fstack[fsp])
- Bprint(&bout, "%s", fstack[fsp]->end);
- Bprint(&bout, "<br> <br>\n");
- Bprint(&bout, "<A href=http://www.lucent.com/copyright.html>\n");
- t = localtime(time(nil));
- Bprint(&bout, "Copyright</A> © %d Lucent Technologies Inc. All rights reserved.\n",
- t->year+1900);
- Bprint(&bout, "</body></html>\n");
- }
- static void
- usage(void)
- {
- sysfatal("usage: ms2html [-q] [-b basename] [-d '$$'] [-t title]\n");
- }
- void
- main(int argc, char **argv)
- {
- quiet = 1;
- ARGBEGIN {
- case 't':
- title = EARGF(usage());
- break;
- case 'b':
- basename = EARGF(usage());
- break;
- case 'q':
- quiet = 0;
- break;
- case 'd':
- delim = EARGF(usage());
- break;
- case '?':
- default:
- usage();
- } ARGEND;
- Binit(&bout, 1, OWRITE);
- ds("R", "®");
- doconvert();
- exits(nil);
- }
- void
- g_notyet(int, char **argv)
- {
- fprint(2, "ms2html: .%s not yet supported\n", argv[0]);
- }
- void
- g_ignore(int, char **argv)
- {
- if(quiet)
- return;
- fprint(2, "ms2html: line %d: ignoring .%s\n", ssp->lno, argv[0]);
- }
- void
- g_PP(int, char**)
- {
- dohanginghead();
- closel();
- closefont();
- Bprint(&bout, "<P>\n");
- paragraph = 1;
- }
- void
- g_LP(int, char**)
- {
- dohanginghead();
- closel();
- closefont();
- Bprint(&bout, "<br> <br>\n");
- }
- /* close a list */
- void
- closel(void)
- {
- g_P2(1, nil);
- dohangingau();
- if(paragraph){
- Bprint(&bout, "</P>\n");
- paragraph = 0;
- }
- switch(list){
- case Lordered:
- Bprint(&bout, "</ol>\n");
- break;
- case Lunordered:
- Bprint(&bout, "</ul>\n");
- break;
- case Lother:
- case Ldef:
- Bprint(&bout, "</dl>\n");
- break;
- }
- list = 0;
-
- }
- void
- g_IP(int argc, char **argv)
- {
- switch(list){
- default:
- closel();
- if(argc > 1){
- if(strcmp(argv[1], "1") == 0){
- list = Lordered;
- listnum = 1;
- Bprint(&bout, "<OL>\n");
- } else if(strcmp(argv[1], "\\(bu") == 0){
- list = Lunordered;
- Bprint(&bout, "<UL>\n");
- } else {
- list = Lother;
- Bprint(&bout, "<DL COMPACT>\n");
- }
- } else {
- list = Lother;
- Bprint(&bout, "<DL>\n");
- }
- break;
- case Lother:
- case Lordered:
- case Lunordered:
- break;
- }
- switch(list){
- case Lother:
- Bprint(&bout, "<DT>");
- if(argc > 1)
- printarg(argv[1]);
- else
- Bprint(&bout, "<DT> ");
- Bprint(&bout, "<DD>\n");
- break;
- case Lordered:
- case Lunordered:
- Bprint(&bout, "<LI>\n");
- break;
- }
- }
- /*
- * .5i is one <DL><DT><DD>
- */
- void
- g_in(int argc, char **argv)
- {
- float f;
- int delta, x;
- char *p;
- f = indent/0.5;
- delta = f;
- if(argc <= 1){
- indent = 0.0;
- } else {
- f = strtod(argv[1], &p);
- switch(*p){
- case 'i':
- break;
- case 'c':
- f = f / 2.54;
- break;
- case 'P':
- f = f / 6;
- break;
- default:
- case 'u':
- case 'm':
- f = f * (12 / 72);
- break;
- case 'n':
- f = f * (6 / 72);
- break;
- case 'p':
- f = f / 72.0;
- break;
- }
- switch(argv[1][0]){
- case '+':
- case '-':
- indent += f;
- break;
- default:
- indent = f;
- break;
- }
- }
- if(indent < 0.0)
- indent = 0.0;
- f = (indent/0.5);
- x = f;
- delta = x - delta;
- while(delta < 0){
- Bprint(&bout, "</DL>\n");
- delta++;
- }
- while(delta > 0){
- Bprint(&bout, "<DL><DT><DD>\n");
- delta--;
- }
- }
- void
- g_HP(int, char**)
- {
- switch(list){
- default:
- closel();
- list = Ldef;
- hangingdt = 1;
- Bprint(&bout, "<DL><DT>\n");
- break;
- case Ldef:
- if(hangingdt)
- Bprint(&bout, "<DD>");
- Bprint(&bout, "<DT>");
- hangingdt = 1;
- break;
- }
- }
- void
- g_SH(int, char**)
- {
- dohanginghead();
- dohangingcenter();
- closel();
- closefont();
- Bprint(&bout, "<H%d>", HH);
- hanginghead = HH;
- }
- void
- g_NH(int argc, char **argv)
- {
- int i, level;
- closel();
- closefont();
- dohangingcenter();
- if(argc == 1)
- level = 0;
- else {
- level = atoi(argv[1])-1;
- if(level < 0 || level >= Maxnh)
- level = Maxnh - 1;
- }
- nh[level]++;
- Bprint(&bout, "<H%d>", HH);
- hanginghead = HH;
- Bprint(&bout, "%d", nh[0]);
- for(i = 1; i <= level; i++)
- Bprint(&bout, ".%d", nh[i]);
- Bprint(&bout, " ");
- for(i = level+1; i < Maxnh; i++)
- nh[i] = 0;
- }
- void
- g_TL(int, char**)
- {
- char *p, *np;
- char name[128];
- closefont();
- if(!titleseen){
- if(!title){
- /* get base part of filename */
- p = strrchr(ssp->filename, '/');
- if(p == nil)
- p = ssp->filename;
- else
- p++;
- strncpy(name, p, sizeof(name));
- name[sizeof(name)-1] = 0;
-
- /* dump any extensions */
- np = strchr(name, '.');
- if(np)
- *np = 0;
- title = p;
- }
- Bprint(&bout, "<title>\n");
- Bprint(&bout, "%s\n", title);
- Bprint(&bout, "</title>\n");
- Bprint(&bout, "<body BGCOLOR=\"#FFFFFF\" TEXT=\"#000000\" LINK=\"#0000FF\" VLINK=\"#330088\" ALINK=\"#FF0044\">\n");
- titleseen = 1;
- }
- Bprint(&bout, "<center>");
- hangingcenter = 1;
- Bprint(&bout, "<H%d>", 1);
- hanginghead = 1;
- }
- void
- dohangingcenter(void)
- {
- if(hangingcenter){
- Bprint(&bout, "</center>");
- hangingcenter = 1;
- }
- }
- void
- g_AU(int, char**)
- {
- closel();
- dohanginghead();
- Bprint(&bout, "<DL><DD><I>");
- hangingau = 1;
- }
- void
- pushfont(Font *f)
- {
- if(fsp == Maxfsp)
- return;
- if(fsp >= 0 && fstack[fsp])
- Bprint(&bout, "%s", fstack[fsp]->end);
- if(f != nil)
- Bprint(&bout, "%s", f->start);
- fstack[++fsp] = f;
- }
- void
- popfont(void)
- {
- if(fsp >= 0){
- if(fstack[fsp])
- Bprint(&bout, "%s", fstack[fsp]->end);
- fsp--;
- }
- }
- /*
- * for 3 args print arg3 \fxarg1\fP arg2
- * for 2 args print arg1 \fxarg2\fP
- * for 1 args print \fxarg1\fP
- */
- void
- font(Font *f, int argc, char **argv)
- {
- if(argc == 1){
- pushfont(nil);
- return;
- }
- if(argc > 3)
- printarg(argv[3]);
- pushfont(f);
- printarg(argv[1]);
- popfont();
- if(argc > 2)
- printarg(argv[2]);
- Bprint(&bout, "\n");
- }
- void
- closefont(void)
- {
- if(fsp >= 0 && fstack[fsp])
- Bprint(&bout, "%s", fstack[fsp]->end);
- fsp = -1;
- }
- void
- g_B(int argc, char **argv)
- {
- font(&bfont, argc, argv);
- }
- void
- g_R(int argc, char **argv)
- {
- font(nil, argc, argv);
- }
- void
- g_BI(int argc, char **argv)
- {
- font(&bifont, argc, argv);
- }
- void
- g_CW(int argc, char **argv)
- {
- font(&cwfont, argc, argv);
- }
- char*
- lower(char *p)
- {
- char *x;
- for(x = p; *x; x++)
- if(*x >= 'A' && *x <= 'Z')
- *x -= 'A' - 'a';
- return p;
- }
- void
- g_I(int argc, char **argv)
- {
- int anchor;
- char *p;
- anchor = 0;
- if(argc > 2){
- p = argv[2];
- if(p[0] == '(')
- if(p[1] >= '0' && p[1] <= '9')
- if(p[2] == ')'){
- anchor = 1;
- Bprint(&bout, "<A href=\"/magic/man2html/%c/%s\">",
- p[1], lower(argv[1]));
- }
- }
- font(&ifont, argc, argv);
- if(anchor)
- Bprint(&bout, "</A>");
- }
- void
- g_br(int, char**)
- {
- if(hangingdt){
- Bprint(&bout, "<dd>");
- hangingdt = 0;
- }else
- Bprint(&bout, "<br>\n");
- }
- void
- g_P1(int, char**)
- {
- if(example == 0){
- example = 1;
- Bprint(&bout, "<DL><DT><DD><TT><PRE>\n");
- }
- }
- void
- g_P2(int, char**)
- {
- if(example){
- example = 0;
- Bprint(&bout, "</PRE></TT></DL>\n");
- }
- }
- void
- g_SM(int, char **argv)
- {
- Bprint(&bout, "%s", argv[1]);
- }
- void
- g_ft(int argc, char **argv)
- {
- if(argc < 2){
- pushfont(nil);
- return;
- }
- switch(argv[1][0]){
- case '3':
- case 'B':
- pushfont(&bfont);
- break;
- case '2':
- case 'I':
- pushfont(&ifont);
- break;
- case '4':
- pushfont(&bifont);
- break;
- case '5':
- pushfont(&cwfont);
- break;
- case 'P':
- popfont();
- break;
- case 'R':
- default:
- pushfont(nil);
- break;
- }
- }
- void
- g_sp(int argc, char **argv)
- {
- int n;
- n = 1;
- if(argc > 1){
- n = atoi(argv[1]);
- if(n < 1)
- n = 1;
- if(argv[1][strlen(argv[1])-1] == 'i')
- n *= 4;
- }
- if(n > 5){
- Bprint(&bout, "<br> <br>\n");
- Bprint(&bout, "<HR>\n");
- Bprint(&bout, "<br> <br>\n");
- } else
- for(; n > 0; n--)
- Bprint(&bout, "<br> <br>\n");
- }
- void
- rm_loop(char *name, String **l)
- {
- String *s;
- for(s = *l; s != nil; s = *l){
- if(strcmp(name, s->name) == 0){
- *l = s->next;
- free(s->name);
- free(s->val);
- free(s);
- break;
- }
- l = &s->next;
- }
- }
- void
- g_rm(int argc, char **argv)
- {
- Goobie *g;
- char *name;
- int i;
- for(i = 1; i < argc; i++) {
- name = argv[i];
- rm_loop(name, &strings);
- rm_loop(name, ¯os);
- for(g = gtab; g->name; g++)
- if (strcmp(g->name, name) == 0) {
- g->f = g_ignore;
- break;
- }
- }
- }
- void
- g_AB(int, char**)
- {
- closel();
- dohangingcenter();
- Bprint(&bout, "<center><H4>ABSTRACT</H4></center><DL><DD>\n");
- }
- void
- g_AE(int, char**)
- {
- Bprint(&bout, "</DL>\n");
- }
- void
- g_FS(int, char **)
- {
- char *argv[3];
- argv[0] = "IP";
- argv[1] = nil;
- argv[2] = nil;
- g_IP(1, argv);
- Bprint(&bout, "NOTE:<I> ");
- }
- void
- g_FE(int, char **)
- {
- Bprint(&bout, "</I><DT> <DD>");
- closel();
- Bprint(&bout, "<br>\n");
- }
- void
- g_de(int argc, char **argv)
- {
- int r;
- char *p, *cp;
- String *m;
- int len;
- if(argc < 2)
- return;
- m = nil;
- len = 0;
- if(strcmp(argv[0], "am") == 0){
- for(m = macros; m != nil; m = m->next)
- if(strcmp(argv[1], m->name) == 0){
- len = strlen(m->val);
- break;
- }
- if(m == nil){
- /* nothing to append to */
- for(;;){
- p = Brdline(&ssp->in, '\n');
- if(p == nil)
- break;
- p[Blinelen(&ssp->in)-1] = 0;
- if(strcmp(p, "..") == 0)
- break;
- }
- return;
- }
- }
- if(m == nil){
- m = emalloc(sizeof(*m));
- m->next = macros;
- macros = m;
- m->name = strdup(argv[1]);
- m->val = nil;
- len = 0;
- }
- /* read up to a .. removing double backslashes */
- for(;;){
- p = Brdline(&ssp->in, '\n');
- if(p == nil)
- break;
- p[Blinelen(&ssp->in)-1] = 0;
- if(strcmp(p, "..") == 0)
- break;
- m->val = realloc(m->val, len + Blinelen(&ssp->in)+1);
- cp = m->val + len;
- while(*p){
- r = *p++;
- if(r == '\\' && *p == '\\')
- p++;
- *cp++ = r;
- }
- *cp++ = '\n';
- len = cp - m->val;
- *cp = 0;
- }
- }
- void
- g_hrule(int, char**)
- {
- Bprint(&bout, "<HR>\n");
- }
- void
- g_BX(int argc, char **argv)
- {
- Bprint(&bout, "<HR>\n");
- printargs(argc, argv);
- Bprint(&bout, "<HR>\n");
- }
- void
- g_IH(int, char**)
- {
- Bprint(&bout, "Bell Laboratories, Naperville, Illinois, 60540\n");
- }
- void
- g_MH(int, char**)
- {
- Bprint(&bout, "Bell Laboratories, Murray Hill, NJ, 07974\n");
- }
- void
- g_PY(int, char**)
- {
- Bprint(&bout, "Bell Laboratories, Piscataway, NJ, 08854\n");
- }
- void
- g_HO(int, char**)
- {
- Bprint(&bout, "Bell Laboratories, Holmdel, NJ, 07733\n");
- }
- void
- g_QS(int, char**)
- {
- Bprint(&bout, "<BLOCKQUOTE>\n");
- }
- void
- g_QE(int, char**)
- {
- Bprint(&bout, "</BLOCKQUOTE>\n");
- }
- void
- g_RS(int, char**)
- {
- Bprint(&bout, "<DL><DD>\n");
- }
- void
- g_RE(int, char**)
- {
- Bprint(&bout, "</DL>\n");
- }
- int gif;
- void
- g_startgif(int, char **argv)
- {
- int fd;
- int pfd[2];
- char *e, *p;
- char name[32];
- Dir *d;
- if(strcmp(argv[0], "EQ") == 0)
- e = ".EN";
- else if(strcmp(argv[0], "TS") == 0)
- e = ".TE";
- else if(strcmp(argv[0], "PS") == 0)
- e = ".PE";
- else
- return;
- if(basename)
- p = basename;
- else{
- p = strrchr(sstack[0].filename, '/');
- if(p != nil)
- p++;
- else
- p = sstack[0].filename;
- }
- snprint(name, sizeof(name), "%s.%d.gif", p, gif++);
- fd = create(name, OWRITE, 0664);
- if(fd < 0){
- fprint(2, "ms2html: can't create %s: %r\n", name);
- return;
- }
- if(pipe(pfd) < 0){
- fprint(2, "ms2html: can't create pipe: %r\n");
- close(fd);
- return;
- }
- switch(rfork(RFFDG|RFPROC)){
- case -1:
- fprint(2, "ms2html: can't fork: %r\n");
- close(fd);
- return;
- case 0:
- dup(fd, 1);
- close(fd);
- dup(pfd[0], 0);
- close(pfd[0]);
- close(pfd[1]);
- execl("/bin/troff2gif", "troff2gif", nil);
- fprint(2, "ms2html: couldn't exec troff2gif: %r\n");
- _exits(nil);
- default:
- close(fd);
- close(pfd[0]);
- fprint(pfd[1], ".ll 7i\n");
- /* fprint(pfd[1], ".EQ\ndelim %s\n.EN\n", delim); */
- /* fprint(pfd[1], ".%s\n", argv[0]); */
- for(;;){
- p = Brdline(&ssp->in, '\n');
- if(p == nil)
- break;
- ssp->lno++;
- ssp->rlno++;
- if(write(pfd[1], p, Blinelen(&ssp->in)) < 0)
- break;
- if(strncmp(p, e, 3) == 0)
- break;
- }
- close(pfd[1]);
- waitpid();
- d = dirstat(name);
- if(d == nil)
- break;
- if(d->length == 0){
- remove(name);
- free(d);
- break;
- }
- free(d);
- fprint(2, "ms2html: created auxiliary file %s\n", name);
- Bprint(&bout, "<br><img src=\"%s\"><br>\n", name);
- break;
- }
- }
- void
- g_lf(int argc, char **argv)
- {
- if(argc > 2)
- snprint(ssp->filename, sizeof(ssp->filename), argv[2]);
- if(argc > 1)
- ssp->rlno = atoi(argv[1]);
- }
- void
- g_so(int argc, char **argv)
- {
- ssp->lno++;
- ssp->rlno++;
- if(argc > 1)
- pushsrc(argv[1]);
- }
- void
- g_BP(int argc, char **argv)
- {
- int fd;
- char *p, *ext;
- char name[32];
- Dir *d;
- if(argc < 2)
- return;
- p = strrchr(argv[1], '/');
- if(p != nil)
- p++;
- else
- p = argv[1];
- ext = strrchr(p, '.');
- if(ext){
- if(strcmp(ext, ".jpeg") == 0
- || strcmp(ext, ".gif") == 0){
- Bprint(&bout, "<br><img src=\"%s\"><br>\n", argv[1]);
- return;
- }
- }
- snprint(name, sizeof(name), "%s.%d%d.gif", p, getpid(), gif++);
- fd = create(name, OWRITE, 0664);
- if(fd < 0){
- fprint(2, "ms2html: can't create %s: %r\n", name);
- return;
- }
- switch(rfork(RFFDG|RFPROC)){
- case -1:
- fprint(2, "ms2html: can't fork: %r\n");
- close(fd);
- return;
- case 0:
- dup(fd, 1);
- close(fd);
- execl("/bin/ps2gif", "ps2gif", argv[1], nil);
- fprint(2, "ms2html: couldn't exec ps2gif: %r\n");
- _exits(nil);
- default:
- close(fd);
- waitpid();
- d = dirstat(name);
- if(d == nil)
- break;
- if(d->length == 0){
- remove(name);
- free(d);
- break;
- }
- free(d);
- fprint(2, "ms2html: created auxiliary file %s\n", name);
- Bprint(&bout, "<br><img src=\"%s\"><br>\n", name);
- break;
- }
- }
- /* insert straight HTML into output */
- void
- g__H(int argc, char **argv)
- {
- int i;
- for(i = 1; i < argc; i++)
- Bprint(&bout, "%s ", argv[i]);
- Bprint(&bout, "\n");
- }
- /* HTML page title */
- void
- g__T(int argc, char **argv)
- {
- if(titleseen)
- return;
- Bprint(&bout, "<title>\n");
- printargs(argc, argv);
- Bprint(&bout, "</title></head><body>\n");
- titleseen = 1;
- }
- void
- g_nr(int argc, char **argv)
- {
- char *val;
- if (argc > 1) {
- if (argc == 2)
- val = "0";
- else
- val = argv[2];
- dsnr(argv[1], val, &numregs);
- }
- }
- void
- zerodivide(void)
- {
- fprint(2, "stdin %d(%s:%d): division by 0\n",
- ssp->lno, ssp->filename, ssp->rlno);
- }
- int
- numval(char **pline, int recur)
- {
- char *p;
- int neg, x, y;
- x = neg = 0;
- p = *pline;
- while(*p == '-') {
- neg = 1 - neg;
- p++;
- }
- if (*p == '(') {
- p++;
- x = numval(&p, 1);
- if (*p != ')')
- goto done;
- p++;
- }
- else while(*p >= '0' && *p <= '9')
- x = 10*x + *p++ - '0';
- if (neg)
- x = -x;
- if (recur)
- for(;;) {
- switch(*p++) {
- case '+':
- x += numval(&p, 0);
- continue;
- case '-':
- x -= numval(&p, 0);
- continue;
- case '*':
- x *= numval(&p, 0);
- continue;
- case '/':
- y = numval(&p, 0);
- if (y == 0) {
- zerodivide();
- x = 0;
- goto done;
- }
- x /= y;
- continue;
- case '<':
- if (*p == '=') {
- p++;
- x = x <= numval(&p, 0);
- continue;
- }
- x = x < numval(&p, 0);
- continue;
- case '>':
- if (*p == '=') {
- p++;
- x = x >= numval(&p, 0);
- continue;
- }
- x = x > numval(&p, 0);
- continue;
- case '=':
- if (*p == '=')
- p++;
- x = x == numval(&p, 0);
- continue;
- case '&':
- x &= numval(&p, 0);
- continue;
- case ':':
- x |= numval(&p, 0);
- continue;
- case '%':
- y = numval(&p, 0);
- if (!y) {
- zerodivide();
- goto done;
- }
- x %= y;
- continue;
- }
- --p;
- break;
- }
- done:
- *pline = p;
- return x;
- }
- int
- iftest(char *p, char **bp)
- {
- char *p1;
- int c, neg, rv;
- rv = neg = 0;
- if (*p == '!') {
- neg = 1;
- p++;
- }
- c = *p;
- if (c >= '0' && c <= '9' || c == '+' || c == '-' || c == '('/*)*/) {
- if (numval(&p,1) >= 1)
- rv = 1;
- goto done;
- }
- switch(c) {
- case 't':
- case 'o':
- rv = 1;
- case 'n':
- case 'e':
- p++;
- goto done;
- }
- for(p1 = ++p; *p != c; p++)
- if (!*p)
- goto done;
- for(p++;;) {
- if (*p != *p1++) {
- while(*p && *p++ != c);
- goto done;
- }
- if (*p++ == c)
- break;
- }
- rv = 1;
- done:
- if (neg)
- rv = 1 - rv;
- while(*p == ' ' || *p == '\t')
- p++;
- *bp = p;
- return rv;
- }
- void
- scanline(char *p, char *e, int wantnl)
- {
- int c;
- Rune r;
- while((c = getrune()) == ' ' || c == '\t') ;
- while(p < e) {
- if (c < 0)
- break;
- if (c < Runeself) {
- if (c == '\n') {
- if (wantnl)
- *p++ = c;
- break;
- }
- *p++ = c;
- }
- else {
- r = c;
- p += runetochar(p, &r);
- }
- c = getrune();
- }
- *p = 0;
- }
- void
- pushbody(char *line)
- {
- char *b;
- if (line[0] == '\\' && line[1] == '{' /*}*/ )
- line += 2;
- if (strsp < Maxmstack - 1) {
- pushstr(b = strdup(line));
- mustfree[strsp] = b;
- }
- }
- void
- skipbody(char *line)
- {
- int c, n;
- if (line[0] != '\\' || line[1] != '{' /*}*/ )
- return;
- for(n = 1;;) {
- while((c = getrune()) != '\\')
- if (c < 0)
- return;
- c = getrune();
- if (c == '{')
- n++;
- else if ((c == '}' && (c = getrune()) == '\n' && !--n)
- || c < 0)
- return;
- }
- }
- int
- ifstart(char *line, char *e, char **bp)
- {
- int it;
- char *b;
- b = copyline(line, e, 1);
- ungetrune();
- b[-1] = getrune();
- scanline(b, e, 1);
- it = iftest(line, bp);
- return it;
- }
- void
- g_ie(char *line, char *e)
- {
- char *b;
- if (elsetop >= Maxif-1) {
- fprint(2, "ms2html: .ie's too deep\n");
- return;
- }
- if (ifwastrue[++elsetop] = ifstart(line, e, &b))
- pushbody(b);
- else
- skipbody(b);
- }
- void
- g_if(char *line, char *e)
- {
- char *b;
- if (ifstart(line, e, &b))
- pushbody(b);
- else
- skipbody(b);
- }
- void
- g_el(char *line, char *e)
- {
- if (elsetop < 0)
- return;
- scanline(line, e, 1);
- if (ifwastrue[elsetop--])
- skipbody(line);
- else
- pushbody(line);
- }
- void
- g_ig(int argc, char **argv)
- {
- char *p, *s;
- s = "..";
- if (argc > 1)
- s = argv[1];
- for(;;) {
- p = Brdline(&ssp->in, '\n');
- if(p == nil)
- break;
- p[Blinelen(&ssp->in)-1] = 0;
- if(strcmp(p, s) == 0)
- break;
- }
- }
- void
- g_ds(char *line, char *e)
- {
- char *b;
- b = copyline(line, e, 1);
- if (b > line) {
- copyline(b, e, 0);
- if (*b == '"')
- b++;
- ds(line, b);
- }
- }
- void
- g_as(char *line, char *e)
- {
- String *s;
- char *b;
- b = copyline(line, e, 1);
- if (b == line)
- return;
- copyline(b, e, 0);
- if (*b == '"')
- b++;
- for(s = strings; s != nil; s = s->next)
- if(strcmp(line, s->name) == 0)
- break;
- if(s == nil){
- ds(line, b);
- return;
- }
- s->val = realloc(s->val, strlen(s->val) + strlen(b) + 1);
- strcat(s->val, b);
- }
- void
- g_BS(int argc, char **argv)
- {
- int i;
- if (argc > 1 && !weBref) {
- Bprint(&bout, "<a href=\"%s\"", argv[1]);
- for(i = 2; i < argc; i++)
- Bprint(&bout, " %s", argv[i]);
- Bprint(&bout, ">");
- weBref = 1;
- }
- }
- void
- g_BE(int, char**)
- {
- if (weBref) {
- Bprint(&bout, "</a>");
- weBref = 0;
- }
- }
- void
- g_LB(int argc, char **argv)
- {
- if (argc > 1) {
- if (weBref)
- g_BE(0,nil);
- Bprint(&bout, "<a name=\"%s\"></a>", argv[1]);
- }
- }
- void
- g_RT(int, char**)
- {
- g_BE(0,nil);
- dohanginghead();
- closel();
- closefont();
- }
|