pgw.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. /* thanks to Caerwyn Jones <caerwyn@comcast.net> for this module */
  10. #include <u.h>
  11. #include <libc.h>
  12. #include <bio.h>
  13. #include "dict.h"
  14. enum {
  15. Buflen=1000,
  16. Maxaux=5,
  17. };
  18. /* Possible tags */
  19. enum {
  20. B, /* Bold */
  21. Blockquote, /* Block quote */
  22. Br, /* Break line */
  23. Cd, /* ? coloquial data */
  24. Col, /* ? Coloquial */
  25. Def, /* Definition */
  26. Hw, /* Head Word */
  27. I, /* Italics */
  28. P, /* Paragraph */
  29. Pos, /* Part of Speach */
  30. Sn, /* Sense */
  31. U, /* ? cross reference*/
  32. Wf, /* ? word form */
  33. Ntag /* end of tags */
  34. };
  35. /* Assoc tables must be sorted on first field */
  36. static Assoc tagtab[] = {
  37. {"b", B},
  38. {"blockquote", Blockquote},
  39. {"BR", Br},
  40. {"cd", Cd},
  41. {"col", Col},
  42. {"def", Def},
  43. {"hw", Hw},
  44. {"i", I},
  45. {"p", P},
  46. {"pos", Pos},
  47. {"sn", Sn},
  48. {"u", U},
  49. {"wf", Wf},
  50. };
  51. /* Possible tag auxilliary info */
  52. enum {
  53. Cols, /* number of columns in a table */
  54. Num, /* letter or number, for a sense */
  55. St, /* status (e.g., obs) */
  56. Naux
  57. };
  58. static Assoc auxtab[] = {
  59. {"cols", Cols},
  60. {"num", Num},
  61. {"st", St}
  62. };
  63. static Assoc spectab[] = {
  64. {"3on4", L'¾'},
  65. {"AElig", L'Æ'},
  66. {"Aacute", L'Á'},
  67. {"Aang", L'Å'},
  68. {"Abarab", L'Ā'},
  69. {"Acirc", L'Â'},
  70. {"Agrave", L'À'},
  71. {"Alpha", L'Α'},
  72. {"Amacr", L'Ā'},
  73. {"Asg", L'Ʒ'}, /* Unicyle. Cf "Sake" */
  74. {"Auml", L'Ä'},
  75. {"Beta", L'Β'},
  76. {"Cced", L'Ç'},
  77. {"Chacek", L'Č'},
  78. {"Chi", L'Χ'},
  79. {"Chirho", L'☧'}, /* Chi Rho U+2627 */
  80. {"Csigma", L'Ϛ'},
  81. {"Delta", L'Δ'},
  82. {"Eacute", L'É'},
  83. {"Ecirc", L'Ê'},
  84. {"Edh", L'Ð'},
  85. {"Epsilon", L'Ε'},
  86. {"Eta", L'Η'},
  87. {"Gamma", L'Γ'},
  88. {"Iacute", L'Í'},
  89. {"Icirc", L'Î'},
  90. {"Imacr", L'Ī'},
  91. {"Integ", L'∫'},
  92. {"Iota", L'Ι'},
  93. {"Kappa", L'Κ'},
  94. {"Koppa", L'Ϟ'},
  95. {"Lambda", L'Λ'},
  96. {"Lbar", L'Ł'},
  97. {"Mu", L'Μ'},
  98. {"Naira", L'N'}, /* should have bar through */
  99. {"Nplus", L'N'}, /* should have plus above */
  100. {"Ntilde", L'Ñ'},
  101. {"Nu", L'Ν'},
  102. {"Oacute", L'Ó'},
  103. {"Obar", L'Ø'},
  104. {"Ocirc", L'Ô'},
  105. {"Oe", L'Œ'},
  106. {"Omega", L'Ω'},
  107. {"Omicron", L'Ο'},
  108. {"Ouml", L'Ö'},
  109. {"Phi", L'Φ'},
  110. {"Pi", L'Π'},
  111. {"Psi", L'Ψ'},
  112. {"Rho", L'Ρ'},
  113. {"Sacute", L'Ś'},
  114. {"Sigma", L'Σ'},
  115. {"Summ", L'∑'},
  116. {"Tau", L'Τ'},
  117. {"Th", L'Þ'},
  118. {"Theta", L'Θ'},
  119. {"Tse", L'Ц'},
  120. {"Uacute", L'Ú'},
  121. {"Ucirc", L'Û'},
  122. {"Upsilon", L'Υ'},
  123. {"Uuml", L'Ü'},
  124. {"Wyn", L'ƿ'}, /* wynn U+01BF */
  125. {"Xi", L'Ξ'},
  126. {"Ygh", L'Ʒ'}, /* Yogh U+01B7 */
  127. {"Zeta", L'Ζ'},
  128. {"Zh", L'Ʒ'}, /* looks like Yogh. Cf "Sake" */
  129. {"a", L'a'}, /* ante */
  130. {"aacute", L'á'},
  131. {"aang", L'å'},
  132. {"aasper", MAAS},
  133. {"abreve", L'ă'},
  134. {"acirc", L'â'},
  135. {"acute", LACU},
  136. {"aelig", L'æ'},
  137. {"agrave", L'à'},
  138. {"ahook", L'ą'},
  139. {"alenis", MALN},
  140. {"alpha", L'α'},
  141. {"amacr", L'ā'},
  142. {"amp", L'&'},
  143. {"and", MAND},
  144. {"ang", LRNG},
  145. {"angle", L'∠'},
  146. {"ankh", L'☥'}, /* ankh U+2625 */
  147. {"ante", L'a'}, /* before (year) */
  148. {"aonq", MAOQ},
  149. {"appreq", L'≃'},
  150. {"aquar", L'♒'},
  151. {"arDadfull", L'ض'}, /* Dad U+0636 */
  152. {"arHa", L'ح'}, /* haa U+062D */
  153. {"arTa", L'ت'}, /* taa U+062A */
  154. {"arain", L'ع'}, /* ain U+0639 */
  155. {"arainfull", L'ع'}, /* ain U+0639 */
  156. {"aralif", L'ا'}, /* alef U+0627 */
  157. {"arba", L'ب'}, /* baa U+0628 */
  158. {"arha", L'ه'}, /* ha U+0647 */
  159. {"aries", L'♈'},
  160. {"arnun", L'ن'}, /* noon U+0646 */
  161. {"arnunfull", L'ن'}, /* noon U+0646 */
  162. {"arpa", L'ه'}, /* ha U+0647 */
  163. {"arqoph", L'ق'}, /* qaf U+0642 */
  164. {"arshinfull", L'ش'}, /* sheen U+0634 */
  165. {"arta", L'ت'}, /* taa U+062A */
  166. {"artafull", L'ت'}, /* taa U+062A */
  167. {"artha", L'ث'}, /* thaa U+062B */
  168. {"arwaw", L'و'}, /* waw U+0648 */
  169. {"arya", L'ي'}, /* ya U+064A */
  170. {"aryafull", L'ي'}, /* ya U+064A */
  171. {"arzero", L'٠'}, /* indic zero U+0660 */
  172. {"asg", L'ʒ'}, /* unicycle character. Cf "hallow" */
  173. {"asper", LASP},
  174. {"assert", L'⊢'},
  175. {"astm", L'⁂'}, /* asterism: should be upside down */
  176. {"at", L'@'},
  177. {"atilde", L'ã'},
  178. {"auml", L'ä'},
  179. {"ayin", L'ع'}, /* arabic ain U+0639 */
  180. {"b1", L'-'}, /* single bond */
  181. {"b2", L'='}, /* double bond */
  182. {"b3", L'≡'}, /* triple bond */
  183. {"bbar", L'ƀ'}, /* b with bar U+0180 */
  184. {"beta", L'β'},
  185. {"bigobl", L'/'},
  186. {"blC", L'C'}, /* should be black letter */
  187. {"blJ", L'J'}, /* should be black letter */
  188. {"blU", L'U'}, /* should be black letter */
  189. {"blb", L'b'}, /* should be black letter */
  190. {"blozenge", L'◊'}, /* U+25CA; should be black */
  191. {"bly", L'y'}, /* should be black letter */
  192. {"bra", MBRA},
  193. {"brbl", LBRB},
  194. {"breve", LBRV},
  195. {"bslash", L'\\'},
  196. {"bsquare", L'■'}, /* black square U+25A0 */
  197. {"btril", L'◀'}, /* U+25C0 */
  198. {"btrir", L'▶'}, /* U+25B6 */
  199. {"c", L'c'}, /* circa */
  200. {"cab", L'〉'},
  201. {"cacute", L'ć'},
  202. {"canc", L'♋'},
  203. {"capr", L'♑'},
  204. {"caret", L'^'},
  205. {"cb", L'}'},
  206. {"cbigb", L'}'},
  207. {"cbigpren", L')'},
  208. {"cbigsb", L']'},
  209. {"cced", L'ç'},
  210. {"cdil", LCED},
  211. {"cdsb", L'〛'}, /* ]] U+301b */
  212. {"cent", L'¢'},
  213. {"chacek", L'č'},
  214. {"chi", L'χ'},
  215. {"circ", LRNG},
  216. {"circa", L'c'}, /* about (year) */
  217. {"circbl", L'̥'}, /* ring below accent U+0325 */
  218. {"circle", L'○'}, /* U+25CB */
  219. {"circledot", L'⊙'},
  220. {"click", L'ʖ'},
  221. {"club", L'♣'},
  222. {"comtime", L'C'},
  223. {"conj", L'☌'},
  224. {"cprt", L'©'},
  225. {"cq", L'\''},
  226. {"cqq", L'”'},
  227. {"cross", L'✠'}, /* maltese cross U+2720 */
  228. {"crotchet", L'♩'},
  229. {"csb", L']'},
  230. {"ctilde", L'c'}, /* +tilde */
  231. {"ctlig", MLCT},
  232. {"cyra", L'а'},
  233. {"cyre", L'е'},
  234. {"cyrhard", L'ъ'},
  235. {"cyrjat", L'ѣ'},
  236. {"cyrm", L'м'},
  237. {"cyrn", L'н'},
  238. {"cyrr", L'р'},
  239. {"cyrsoft", L'ь'},
  240. {"cyrt", L'т'},
  241. {"cyry", L'ы'},
  242. {"dag", L'†'},
  243. {"dbar", L'đ'},
  244. {"dblar", L'⇋'},
  245. {"dblgt", L'≫'},
  246. {"dbllt", L'≪'},
  247. {"dced", L'd'}, /* +cedilla */
  248. {"dd", MDD},
  249. {"ddag", L'‡'},
  250. {"ddd", MDDD},
  251. {"decr", L'↓'},
  252. {"deg", L'°'},
  253. {"dele", L'd'}, /* should be dele */
  254. {"delta", L'δ'},
  255. {"descnode", L'☋'}, /* descending node U+260B */
  256. {"diamond", L'♢'},
  257. {"digamma", L'ϝ'},
  258. {"div", L'÷'},
  259. {"dlessi", L'ı'},
  260. {"dlessj1", L'j'}, /* should be dotless */
  261. {"dlessj2", L'j'}, /* should be dotless */
  262. {"dlessj3", L'j'}, /* should be dotless */
  263. {"dollar", L'$'},
  264. {"dotab", LDOT},
  265. {"dotbl", LDTB},
  266. {"drachm", L'ʒ'},
  267. {"dubh", L'-'},
  268. {"eacute", L'é'},
  269. {"earth", L'♁'},
  270. {"easper", MEAS},
  271. {"ebreve", L'ĕ'},
  272. {"ecirc", L'ê'},
  273. {"edh", L'ð'},
  274. {"egrave", L'è'},
  275. {"ehacek", L'ě'},
  276. {"ehook", L'ę'},
  277. {"elem", L'∊'},
  278. {"elenis", MELN},
  279. {"em", L'—'},
  280. {"emacr", L'ē'},
  281. {"emem", MEMM},
  282. {"en", L'–'},
  283. {"epsilon", L'ε'},
  284. {"equil", L'⇋'},
  285. {"ergo", L'∴'},
  286. {"es", MES},
  287. {"eszett", L'ß'},
  288. {"eta", L'η'},
  289. {"eth", L'ð'},
  290. {"euml", L'ë'},
  291. {"expon", L'↑'},
  292. {"fact", L'!'},
  293. {"fata", L'ɑ'},
  294. {"fatpara", L'¶'}, /* should have fatter, filled in bowl */
  295. {"female", L'♀'},
  296. {"ffilig", MLFFI},
  297. {"fflig", MLFF},
  298. {"ffllig", MLFFL},
  299. {"filig", MLFI},
  300. {"flat", L'♭'},
  301. {"fllig", MLFL},
  302. {"frE", L'E'}, /* should be curly */
  303. {"frL", L'L'}, /* should be curly */
  304. {"frR", L'R'}, /* should be curly */
  305. {"frakB", L'B'}, /* should have fraktur style */
  306. {"frakG", L'G'},
  307. {"frakH", L'H'},
  308. {"frakI", L'I'},
  309. {"frakM", L'M'},
  310. {"frakU", L'U'},
  311. {"frakX", L'X'},
  312. {"frakY", L'Y'},
  313. {"frakh", L'h'},
  314. {"frbl", LFRB},
  315. {"frown", LFRN},
  316. {"fs", L' '},
  317. {"fsigma", L'ς'},
  318. {"gAacute", L'Á'}, /* should be Α+acute */
  319. {"gaacute", L'α'}, /* +acute */
  320. {"gabreve", L'α'}, /* +breve */
  321. {"gafrown", L'α'}, /* +frown */
  322. {"gagrave", L'α'}, /* +grave */
  323. {"gamacr", L'α'}, /* +macron */
  324. {"gamma", L'γ'},
  325. {"gauml", L'α'}, /* +umlaut */
  326. {"ge", L'≧'},
  327. {"geacute", L'ε'}, /* +acute */
  328. {"gegrave", L'ε'}, /* +grave */
  329. {"ghacute", L'η'}, /* +acute */
  330. {"ghfrown", L'η'}, /* +frown */
  331. {"ghgrave", L'η'}, /* +grave */
  332. {"ghmacr", L'η'}, /* +macron */
  333. {"giacute", L'ι'}, /* +acute */
  334. {"gibreve", L'ι'}, /* +breve */
  335. {"gifrown", L'ι'}, /* +frown */
  336. {"gigrave", L'ι'}, /* +grave */
  337. {"gimacr", L'ι'}, /* +macron */
  338. {"giuml", L'ι'}, /* +umlaut */
  339. {"glagjat", L'ѧ'},
  340. {"glots", L'ˀ'},
  341. {"goacute", L'ο'}, /* +acute */
  342. {"gobreve", L'ο'}, /* +breve */
  343. {"grave", LGRV},
  344. {"gt", L'>'},
  345. {"guacute", L'υ'}, /* +acute */
  346. {"gufrown", L'υ'}, /* +frown */
  347. {"gugrave", L'υ'}, /* +grave */
  348. {"gumacr", L'υ'}, /* +macron */
  349. {"guuml", L'υ'}, /* +umlaut */
  350. {"gwacute", L'ω'}, /* +acute */
  351. {"gwfrown", L'ω'}, /* +frown */
  352. {"gwgrave", L'ω'}, /* +grave */
  353. {"hacek", LHCK},
  354. {"halft", L'⌈'},
  355. {"hash", L'#'},
  356. {"hasper", MHAS},
  357. {"hatpath", L'ֲ'}, /* hataf patah U+05B2 */
  358. {"hatqam", L'ֳ'}, /* hataf qamats U+05B3 */
  359. {"hatseg", L'ֱ'}, /* hataf segol U+05B1 */
  360. {"hbar", L'ħ'},
  361. {"heart", L'♡'},
  362. {"hebaleph", L'א'}, /* aleph U+05D0 */
  363. {"hebayin", L'ע'}, /* ayin U+05E2 */
  364. {"hebbet", L'ב'}, /* bet U+05D1 */
  365. {"hebbeth", L'ב'}, /* bet U+05D1 */
  366. {"hebcheth", L'ח'}, /* bet U+05D7 */
  367. {"hebdaleth", L'ד'}, /* dalet U+05D3 */
  368. {"hebgimel", L'ג'}, /* gimel U+05D2 */
  369. {"hebhe", L'ה'}, /* he U+05D4 */
  370. {"hebkaph", L'כ'}, /* kaf U+05DB */
  371. {"heblamed", L'ל'}, /* lamed U+05DC */
  372. {"hebmem", L'מ'}, /* mem U+05DE */
  373. {"hebnun", L'נ'}, /* nun U+05E0 */
  374. {"hebnunfin", L'ן'}, /* final nun U+05DF */
  375. {"hebpe", L'פ'}, /* pe U+05E4 */
  376. {"hebpedag", L'ף'}, /* final pe? U+05E3 */
  377. {"hebqoph", L'ק'}, /* qof U+05E7 */
  378. {"hebresh", L'ר'}, /* resh U+05E8 */
  379. {"hebshin", L'ש'}, /* shin U+05E9 */
  380. {"hebtav", L'ת'}, /* tav U+05EA */
  381. {"hebtsade", L'צ'}, /* tsadi U+05E6 */
  382. {"hebwaw", L'ו'}, /* vav? U+05D5 */
  383. {"hebyod", L'י'}, /* yod U+05D9 */
  384. {"hebzayin", L'ז'}, /* zayin U+05D6 */
  385. {"hgz", L'ʒ'}, /* ??? Cf "alet" */
  386. {"hireq", L'ִ'}, /* U+05B4 */
  387. {"hlenis", MHLN},
  388. {"hook", LOGO},
  389. {"horizE", L'E'}, /* should be on side */
  390. {"horizP", L'P'}, /* should be on side */
  391. {"horizS", L'∽'},
  392. {"horizT", L'⊣'},
  393. {"horizb", L'{'}, /* should be underbrace */
  394. {"ia", L'α'},
  395. {"iacute", L'í'},
  396. {"iasper", MIAS},
  397. {"ib", L'β'},
  398. {"ibar", L'ɨ'},
  399. {"ibreve", L'ĭ'},
  400. {"icirc", L'î'},
  401. {"id", L'δ'},
  402. {"ident", L'≡'},
  403. {"ie", L'ε'},
  404. {"ifilig", MLFI},
  405. {"ifflig", MLFF},
  406. {"ig", L'γ'},
  407. {"igrave", L'ì'},
  408. {"ih", L'η'},
  409. {"ii", L'ι'},
  410. {"ik", L'κ'},
  411. {"ilenis", MILN},
  412. {"imacr", L'ī'},
  413. {"implies", L'⇒'},
  414. {"index", L'☞'},
  415. {"infin", L'∞'},
  416. {"integ", L'∫'},
  417. {"intsec", L'∩'},
  418. {"invpri", L'ˏ'},
  419. {"iota", L'ι'},
  420. {"iq", L'ψ'},
  421. {"istlig", MLST},
  422. {"isub", L'ϵ'}, /* iota below accent */
  423. {"iuml", L'ï'},
  424. {"iz", L'ζ'},
  425. {"jup", L'♃'},
  426. {"kappa", L'κ'},
  427. {"koppa", L'ϟ'},
  428. {"lambda", L'λ'},
  429. {"lar", L'←'},
  430. {"lbar", L'ł'},
  431. {"le", L'≦'},
  432. {"lenis", LLEN},
  433. {"leo", L'♌'},
  434. {"lhalfbr", L'⌈'},
  435. {"lhshoe", L'⊃'},
  436. {"libra", L'♎'},
  437. {"llswing", MLLS},
  438. {"lm", L'ː'},
  439. {"logicand", L'∧'},
  440. {"logicor", L'∨'},
  441. {"longs", L'ʃ'},
  442. {"lrar", L'↔'},
  443. {"lt", L'<'},
  444. {"ltappr", L'≾'},
  445. {"ltflat", L'∠'},
  446. {"lumlbl", L'l'}, /* +umlaut below */
  447. {"mac", LMAC},
  448. {"male", L'♂'},
  449. {"mc", L'c'}, /* should be raised */
  450. {"merc", L'☿'}, /* mercury U+263F */
  451. {"min", L'−'},
  452. {"moonfq", L'☽'}, /* first quarter moon U+263D */
  453. {"moonlq", L'☾'}, /* last quarter moon U+263E */
  454. {"msylab", L'm'}, /* +sylab (ˌ) */
  455. {"mu", L'μ'},
  456. {"nacute", L'ń'},
  457. {"natural", L'♮'},
  458. {"neq", L'≠'},
  459. {"nfacute", L'′'},
  460. {"nfasper", L'ʽ'},
  461. {"nfbreve", L'˘'},
  462. {"nfced", L'¸'},
  463. {"nfcirc", L'ˆ'},
  464. {"nffrown", L'⌢'},
  465. {"nfgra", L'ˋ'},
  466. {"nfhacek", L'ˇ'},
  467. {"nfmac", L'¯'},
  468. {"nftilde", L'˜'},
  469. {"nfuml", L'¨'},
  470. {"ng", L'ŋ'},
  471. {"not", L'¬'},
  472. {"notelem", L'∉'},
  473. {"ntilde", L'ñ'},
  474. {"nu", L'ν'},
  475. {"oab", L'〈'},
  476. {"oacute", L'ó'},
  477. {"oasper", MOAS},
  478. {"ob", L'{'},
  479. {"obar", L'ø'},
  480. {"obigb", L'{'}, /* should be big */
  481. {"obigpren", L'('},
  482. {"obigsb", L'['}, /* should be big */
  483. {"obreve", L'ŏ'},
  484. {"ocirc", L'ô'},
  485. {"odsb", L'〚'}, /* [[ U+301A */
  486. {"oelig", L'œ'},
  487. {"oeamp", L'&'},
  488. {"ograve", L'ò'},
  489. {"ohook", L'o'}, /* +hook */
  490. {"olenis", MOLN},
  491. {"omacr", L'ō'},
  492. {"omega", L'ω'},
  493. {"omicron", L'ο'},
  494. {"ope", L'ɛ'},
  495. {"opp", L'☍'},
  496. {"oq", L'`'},
  497. {"oqq", L'“'},
  498. {"or", MOR},
  499. {"osb", L'['},
  500. {"otilde", L'õ'},
  501. {"ouml", L'ö'},
  502. {"ounce", L'℥'}, /* ounce U+2125 */
  503. {"ovparen", L'⌢'}, /* should be sideways ( */
  504. {"p", L'′'},
  505. {"pa", L'∂'},
  506. {"page", L'P'},
  507. {"pall", L'ʎ'},
  508. {"paln", L'ɲ'},
  509. {"par", PAR},
  510. {"para", L'¶'},
  511. {"pbar", L'p'}, /* +bar */
  512. {"per", L'℘'}, /* per U+2118 */
  513. {"phi", L'φ'},
  514. {"phi2", L'ϕ'},
  515. {"pi", L'π'},
  516. {"pisces", L'♓'},
  517. {"planck", L'ħ'},
  518. {"plantinJ", L'J'}, /* should be script */
  519. {"pm", L'±'},
  520. {"pmil", L'‰'},
  521. {"pp", L'″'},
  522. {"ppp", L'‴'},
  523. {"prop", L'∝'},
  524. {"psi", L'ψ'},
  525. {"pstlg", L'£'},
  526. {"q", L'?'}, /* should be raised */
  527. {"qamets", L'ֳ'}, /* U+05B3 */
  528. {"quaver", L'♪'},
  529. {"rar", L'→'},
  530. {"rasper", MRAS},
  531. {"rdot", L'·'},
  532. {"recipe", L'℞'}, /* U+211E */
  533. {"reg", L'®'},
  534. {"revC", L'Ɔ'}, /* open O U+0186 */
  535. {"reva", L'ɒ'},
  536. {"revc", L'ɔ'},
  537. {"revope", L'ɜ'},
  538. {"revr", L'ɹ'},
  539. {"revsc", L'˒'}, /* upside-down semicolon */
  540. {"revv", L'ʌ'},
  541. {"rfa", L'o'}, /* +hook (Cf "goal") */
  542. {"rhacek", L'ř'},
  543. {"rhalfbr", L'⌉'},
  544. {"rho", L'ρ'},
  545. {"rhshoe", L'⊂'},
  546. {"rlenis", MRLN},
  547. {"rsylab", L'r'}, /* +sylab */
  548. {"runash", L'F'}, /* should be runic 'ash' */
  549. {"rvow", L'˔'},
  550. {"sacute", L'ś'},
  551. {"sagit", L'♐'},
  552. {"sampi", L'ϡ'},
  553. {"saturn", L'♄'},
  554. {"sced", L'ş'},
  555. {"schwa", L'ə'},
  556. {"scorpio", L'♏'},
  557. {"scrA", L'A'}, /* should be script */
  558. {"scrC", L'C'},
  559. {"scrE", L'E'},
  560. {"scrF", L'F'},
  561. {"scrI", L'I'},
  562. {"scrJ", L'J'},
  563. {"scrL", L'L'},
  564. {"scrO", L'O'},
  565. {"scrP", L'P'},
  566. {"scrQ", L'Q'},
  567. {"scrS", L'S'},
  568. {"scrT", L'T'},
  569. {"scrb", L'b'},
  570. {"scrd", L'd'},
  571. {"scrh", L'h'},
  572. {"scrl", L'l'},
  573. {"scruple", L'℈'}, /* U+2108 */
  574. {"sdd", L'ː'},
  575. {"sect", L'§'},
  576. {"semE", L'∃'},
  577. {"sh", L'ʃ'},
  578. {"shacek", L'š'},
  579. {"sharp", L'♯'},
  580. {"sheva", L'ְ'}, /* U+05B0 */
  581. {"shti", L'ɪ'},
  582. {"shtsyll", L'∪'},
  583. {"shtu", L'ʊ'},
  584. {"sidetri", L'⊲'},
  585. {"sigma", L'σ'},
  586. {"since", L'∵'},
  587. {"slge", L'≥'}, /* should have slanted line under */
  588. {"slle", L'≤'}, /* should have slanted line under */
  589. {"sm", L'ˈ'},
  590. {"smm", L'ˌ'},
  591. {"spade", L'♠'},
  592. {"sqrt", L'√'},
  593. {"square", L'□'}, /* U+25A1 */
  594. {"ssChi", L'Χ'}, /* should be sans serif */
  595. {"ssIota", L'Ι'},
  596. {"ssOmicron", L'Ο'},
  597. {"ssPi", L'Π'},
  598. {"ssRho", L'Ρ'},
  599. {"ssSigma", L'Σ'},
  600. {"ssTau", L'Τ'},
  601. {"star", L'*'},
  602. {"stlig", MLST},
  603. {"sup2", L'⁲'},
  604. {"supgt", L'˃'},
  605. {"suplt", L'˂'},
  606. {"sur", L'ʳ'},
  607. {"swing", L'∼'},
  608. {"tau", L'τ'},
  609. {"taur", L'♉'},
  610. {"th", L'þ'},
  611. {"thbar", L'þ'}, /* +bar */
  612. {"theta", L'θ'},
  613. {"thinqm", L'?'}, /* should be thinner */
  614. {"tilde", LTIL},
  615. {"times", L'×'},
  616. {"tri", L'∆'},
  617. {"trli", L'‖'},
  618. {"ts", L' '},
  619. {"uacute", L'ú'},
  620. {"uasper", MUAS},
  621. {"ubar", L'u'}, /* +bar */
  622. {"ubreve", L'ŭ'},
  623. {"ucirc", L'û'},
  624. {"udA", L'∀'},
  625. {"udT", L'⊥'},
  626. {"uda", L'ɐ'},
  627. {"udh", L'ɥ'},
  628. {"udqm", L'¿'},
  629. {"udpsi", L'⋔'},
  630. {"udtr", L'∇'},
  631. {"ugrave", L'ù'},
  632. {"ulenis", MULN},
  633. {"umacr", L'ū'},
  634. {"uml", LUML},
  635. {"undl", L'ˍ'}, /* underline accent */
  636. {"union", L'∪'},
  637. {"upsilon", L'υ'},
  638. {"uuml", L'ü'},
  639. {"vavpath", L'ו'}, /* vav U+05D5 (+patah) */
  640. {"vavsheva", L'ו'}, /* vav U+05D5 (+sheva) */
  641. {"vb", L'|'},
  642. {"vddd", L'⋮'},
  643. {"versicle2", L'℣'}, /* U+2123 */
  644. {"vinc", L'¯'},
  645. {"virgo", L'♍'},
  646. {"vpal", L'ɟ'},
  647. {"vvf", L'ɣ'},
  648. {"wasper", MWAS},
  649. {"wavyeq", L'≈'},
  650. {"wlenis", MWLN},
  651. {"wyn", L'ƿ'}, /* wynn U+01BF */
  652. {"xi", L'ξ'},
  653. {"yacute", L'ý'},
  654. {"ycirc", L'ŷ'},
  655. {"ygh", L'ʒ'},
  656. {"ymacr", L'y'}, /* +macron */
  657. {"yuml", L'ÿ'},
  658. {"zced", L'z'}, /* +cedilla */
  659. {"zeta", L'ζ'},
  660. {"zh", L'ʒ'},
  661. {"zhacek", L'ž'},
  662. };
  663. /*
  664. The following special characters don't have close enough
  665. equivalents in Unicode, so aren't in the above table.
  666. 22n 2^(2^n) Cf Fermat
  667. 2on4 2/4
  668. 3on8 3/8
  669. Bantuo Bantu O. Cf Otshi-herero
  670. Car C with circular arrow on top
  671. albrtime cut-time: C with vertical line
  672. ardal Cf dental
  673. bantuo Bantu o. Cf Otshi-herero
  674. bbc1 single chem bond below
  675. bbc2 double chem bond below
  676. bbl1 chem bond like /
  677. bbl2 chem bond like //
  678. bbr1 chem bond like \
  679. bbr2 chem bond \\
  680. bcop1 copper symbol. Cf copper
  681. bcop2 copper symbol. Cf copper
  682. benchm Cf benchmark
  683. btc1 single chem bond above
  684. btc2 double chem bond above
  685. btl1 chem bond like \
  686. btl2 chem bond like \\
  687. btr1 chem bond like /
  688. btr2 chem bond line //
  689. burman Cf Burman
  690. devph sanskrit letter. Cf ph
  691. devrfls sanskrit letter. Cf cerebral
  692. duplong[12] musical note
  693. egchi early form of chi
  694. eggamma[12] early form of gamma
  695. egiota early form of iota
  696. egkappa early form of kappa
  697. eglambda early form of lambda
  698. egmu[12] early form of mu
  699. egnu[12] early form of nu
  700. egpi[123] early form of pi
  701. egrho[12] early form of rho
  702. egsampi early form of sampi
  703. egsan early form of san
  704. egsigma[12] early form of sigma
  705. egxi[123] early form of xi
  706. elatS early form of S
  707. elatc[12] early form of C
  708. elatg[12] early form of G
  709. glagjeri Slavonic Glagolitic jeri
  710. glagjeru Slavonic Glagolitic jeru
  711. hypolem hypolemisk (line with underdot)
  712. lhrbr lower half }
  713. longmord long mordent
  714. mbwvow backwards scretched C. Cf retract.
  715. mord music symbol. Cf mordent
  716. mostra Cf direct
  717. ohgcirc old form of circumflex
  718. oldbeta old form of β. Cf perturbate
  719. oldsemibr[12] old forms of semibreve. Cf prolation
  720. ormg old form of g. Cf G
  721. para[12345] form of ¶
  722. pauseo musical pause sign
  723. pauseu musical pause sign
  724. pharyng Cf pharyngal
  725. ragr Black letter ragged r
  726. repetn musical repeat. Cf retort
  727. segno musical segno sign
  728. semain[12] semitic ain
  729. semhe semitic he
  730. semheth semitic heth
  731. semkaph semitic kaph
  732. semlamed[12] semitic lamed
  733. semmem semitic mem
  734. semnum semitic nun
  735. sempe semitic pe
  736. semqoph[123] semitic qoph
  737. semresh semitic resh
  738. semtav[1234] semitic tav
  739. semyod semitic yod
  740. semzayin[123] semitic zayin
  741. shtlong[12] U with underbar. Cf glyconic
  742. sigmatau σ,τ combination
  743. squaver sixteenth note
  744. sqbreve square musical breve note
  745. swast swastika
  746. uhrbr upper half of big }
  747. versicle1 Cf versicle
  748. */
  749. static Rune normtab[128] = {
  750. /*0*/ /*1*/ /*2*/ /*3*/ /*4*/ /*5*/ /*6*/ /*7*/
  751. /*00*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
  752. NONE, NONE, ' ', NONE, NONE, NONE, NONE, NONE,
  753. /*10*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
  754. NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
  755. /*20*/ L' ', L'!', L'"', L'#', L'$', L'%', SPCS, L'\'',
  756. L'(', L')', L'*', L'+', L',', L'-', L'.', L'/',
  757. /*30*/ L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
  758. L'8', L'9', L':', L';', TAGS, L'=', TAGE, L'?',
  759. /*40*/ L'@', L'A', L'B', L'C', L'D', L'E', L'F', L'G',
  760. L'H', L'I', L'J', L'K', L'L', L'M', L'N', L'O',
  761. /*50*/ L'P', L'Q', L'R', L'S', L'T', L'U', L'V', L'W',
  762. L'X', L'Y', L'Z', L'[', L'\\', L']', L'^', L'_',
  763. /*60*/ L'`', L'a', L'b', L'c', L'd', L'e', L'f', L'g',
  764. L'h', L'i', L'j', L'k', L'l', L'm', L'n', L'o',
  765. /*70*/ L'p', L'q', L'r', L's', L't', L'u', L'v', L'w',
  766. L'x', L'y', L'z', L'{', L'|', L'}', L'~', NONE,
  767. };
  768. static Rune phtab[128] = {
  769. /*0*/ /*1*/ /*2*/ /*3*/ /*4*/ /*5*/ /*6*/ /*7*/
  770. /*00*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
  771. NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
  772. /*10*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
  773. NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
  774. /*20*/ L' ', L'!', L'ˈ', L'#', L'$', L'ˌ', L'æ', L'\'',
  775. L'(', L')', L'*', L'+', L',', L'-', L'.', L'/',
  776. /*30*/ L'0', L'1', L'2', L'ɜ', L'4', L'5', L'6', L'7',
  777. L'8', L'ø', L'ː', L';', TAGS, L'=', TAGE, L'?',
  778. /*40*/ L'ə', L'ɑ', L'B', L'C', L'ð', L'ɛ', L'F', L'G',
  779. L'H', L'ɪ', L'J', L'K', L'L', L'M', L'ŋ', L'ɔ',
  780. /*50*/ L'P', L'ɒ', L'R', L'ʃ', L'θ', L'ʊ', L'ʌ', L'W',
  781. L'X', L'Y', L'ʒ', L'[', L'\\', L']', L'^', L'_',
  782. /*60*/ L'`', L'a', L'b', L'c', L'd', L'e', L'f', L'g',
  783. L'h', L'i', L'j', L'k', L'l', L'm', L'n', L'o',
  784. /*70*/ L'p', L'q', L'r', L's', L't', L'u', L'v', L'w',
  785. L'x', L'y', L'z', L'{', L'|', L'}', L'~', NONE,
  786. };
  787. static Rune grtab[128] = {
  788. /*0*/ /*1*/ /*2*/ /*3*/ /*4*/ /*5*/ /*6*/ /*7*/
  789. /*00*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
  790. NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
  791. /*10*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
  792. NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
  793. /*20*/ L' ', L'!', L'"', L'#', L'$', L'%', SPCS, L'\'',
  794. L'(', L')', L'*', L'+', L',', L'-', L'.', L'/',
  795. /*30*/ L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
  796. L'8', L'9', L':', L';', TAGS, L'=', TAGE, L'?',
  797. /*40*/ L'@', L'Α', L'Β', L'Ξ', L'Δ', L'Ε', L'Φ', L'Γ',
  798. L'Η', L'Ι', L'Ϛ', L'Κ', L'Λ', L'Μ', L'Ν', L'Ο',
  799. /*50*/ L'Π', L'Θ', L'Ρ', L'Σ', L'Τ', L'Υ', L'V', L'Ω',
  800. L'Χ', L'Ψ', L'Ζ', L'[', L'\\', L']', L'^', L'_',
  801. /*60*/ L'`', L'α', L'β', L'ξ', L'δ', L'ε', L'φ', L'γ',
  802. L'η', L'ι', L'ς', L'κ', L'λ', L'μ', L'ν', L'ο',
  803. /*70*/ L'π', L'θ', L'ρ', L'σ', L'τ', L'υ', L'v', L'ω',
  804. L'χ', L'ψ', L'ζ', L'{', L'|', L'}', L'~', NONE,
  805. };
  806. static Rune subtab[128] = {
  807. /*0*/ /*1*/ /*2*/ /*3*/ /*4*/ /*5*/ /*6*/ /*7*/
  808. /*00*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
  809. NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
  810. /*10*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
  811. NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
  812. /*20*/ L' ', L'!', L'"', L'#', L'$', L'%', SPCS, L'\'',
  813. L'₍', L'₎', L'*', L'₊', L',', L'₋', L'.', L'/',
  814. /*30*/ L'₀', L'₁', L'₂', L'₃', L'₄', L'₅', L'₆', L'₇',
  815. L'₈', L'₉', L':', L';', TAGS, L'₌', TAGE, L'?',
  816. /*40*/ L'@', L'A', L'B', L'C', L'D', L'E', L'F', L'G',
  817. L'H', L'I', L'J', L'K', L'L', L'M', L'N', L'O',
  818. /*50*/ L'P', L'Q', L'R', L'S', L'T', L'U', L'V', L'W',
  819. L'X', L'Y', L'Z', L'[', L'\\', L']', L'^', L'_',
  820. /*60*/ L'`', L'a', L'b', L'c', L'd', L'e', L'f', L'g',
  821. L'h', L'i', L'j', L'k', L'l', L'm', L'n', L'o',
  822. /*70*/ L'p', L'q', L'r', L's', L't', L'u', L'v', L'w',
  823. L'x', L'y', L'z', L'{', L'|', L'}', L'~', NONE,
  824. };
  825. static Rune suptab[128] = {
  826. /*0*/ /*1*/ /*2*/ /*3*/ /*4*/ /*5*/ /*6*/ /*7*/
  827. /*00*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
  828. NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
  829. /*10*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
  830. NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
  831. /*20*/ L' ', L'!', L'"', L'#', L'$', L'%', SPCS, L'\'',
  832. L'⁽', L'⁾', L'*', L'⁺', L',', L'⁻', L'.', L'/',
  833. /*30*/ L'⁰', L'ⁱ', L'⁲', L'⁳', L'⁴', L'⁵', L'⁶', L'⁷',
  834. L'⁸', L'⁹', L':', L';', TAGS, L'⁼', TAGE, L'?',
  835. /*40*/ L'@', L'A', L'B', L'C', L'D', L'E', L'F', L'G',
  836. L'H', L'I', L'J', L'K', L'L', L'M', L'N', L'O',
  837. /*50*/ L'P', L'Q', L'R', L'S', L'T', L'U', L'V', L'W',
  838. L'X', L'Y', L'Z', L'[', L'\\', L']', L'^', L'_',
  839. /*60*/ L'`', L'a', L'b', L'c', L'd', L'e', L'f', L'g',
  840. L'h', L'i', L'j', L'k', L'l', L'm', L'n', L'o',
  841. /*70*/ L'p', L'q', L'r', L's', L't', L'u', L'v', L'w',
  842. L'x', L'y', L'z', L'{', L'|', L'}', L'~', NONE,
  843. };
  844. static int tagstarts;
  845. static char tag[Buflen];
  846. static char spec[Buflen];
  847. static Entry curentry;
  848. #define cursize (curentry.end-curentry.start)
  849. static char *getspec(char *, char *);
  850. static char *gettag(char *, char *);
  851. /*
  852. * cmd is one of:
  853. * 'p': normal print
  854. * 'h': just print headwords
  855. * 'P': print raw
  856. */
  857. void
  858. pgwprintentry(Entry e, int cmd)
  859. {
  860. char *p, *pe;
  861. int t;
  862. int32_t r, rprev, rlig;
  863. Rune *transtab;
  864. p = e.start;
  865. pe = e.end;
  866. transtab = normtab;
  867. rprev = NONE;
  868. changett(0, 0, 0);
  869. curentry = e;
  870. if(cmd == 'h')
  871. outinhibit = 1;
  872. while(p < pe) {
  873. if(cmd == 'r') {
  874. outchar(*p++);
  875. continue;
  876. }
  877. r = transtab[(*p++)&0x7F];
  878. if(r < NONE) {
  879. /* Emit the rune, but buffer in case of ligature */
  880. if(rprev != NONE)
  881. outrune(rprev);
  882. rprev = r;
  883. } else if(r == SPCS) {
  884. /* Start of special character name */
  885. p = getspec(p, pe);
  886. r = lookassoc(spectab, asize(spectab), spec);
  887. if(r == -1) {
  888. if(debug)
  889. err("spec %ld %d %s",
  890. e.doff, cursize, spec);
  891. r = L'�';
  892. }
  893. if(r >= LIGS && r < LIGE) {
  894. /* handle possible ligature */
  895. rlig = liglookup(r, rprev);
  896. if(rlig != NONE)
  897. rprev = rlig; /* overwrite rprev */
  898. else {
  899. /* could print accent, but let's not */
  900. if(rprev != NONE) outrune(rprev);
  901. rprev = NONE;
  902. }
  903. } else if(r >= MULTI && r < MULTIE) {
  904. if(rprev != NONE) {
  905. outrune(rprev);
  906. rprev = NONE;
  907. }
  908. outrunes(multitab[r-MULTI]);
  909. } else if(r == PAR) {
  910. if(rprev != NONE) {
  911. outrune(rprev);
  912. rprev = NONE;
  913. }
  914. outnl(1);
  915. } else {
  916. if(rprev != NONE) outrune(rprev);
  917. rprev = r;
  918. }
  919. } else if(r == TAGS) {
  920. /* Start of tag name */
  921. if(rprev != NONE) {
  922. outrune(rprev);
  923. rprev = NONE;
  924. }
  925. p = gettag(p, pe);
  926. t = lookassoc(tagtab, asize(tagtab), tag);
  927. if(t == -1) {
  928. if(debug)
  929. err("tag %ld %d %s",
  930. e.doff, cursize, tag);
  931. continue;
  932. }
  933. switch(t){
  934. case Hw:
  935. if(cmd == 'h') {
  936. if(!tagstarts)
  937. outchar(' ');
  938. outinhibit = !tagstarts;
  939. }
  940. break;
  941. case Sn:
  942. if(tagstarts) {
  943. outnl(2);
  944. }
  945. break;
  946. case P:
  947. outnl(tagstarts);
  948. break;
  949. case Col:
  950. case Br:
  951. case Blockquote:
  952. if(tagstarts)
  953. outnl(1);
  954. break;
  955. case U:
  956. outchar('/');
  957. }
  958. }
  959. }
  960. if(cmd == 'h') {
  961. outinhibit = 0;
  962. outnl(0);
  963. }
  964. }
  965. /*
  966. * Return offset into bdict where next webster entry after fromoff starts.
  967. * Webster entries start with <p><hw>
  968. */
  969. int32_t
  970. pgwnextoff(int32_t fromoff)
  971. {
  972. int32_t a, n;
  973. int c;
  974. a = Bseek(bdict, fromoff, 0);
  975. if(a != fromoff)
  976. return -1;
  977. n = 0;
  978. for(;;) {
  979. c = Bgetc(bdict);
  980. if(c < 0)
  981. break;
  982. if(c == '<' && Bgetc(bdict) == 'p' && Bgetc(bdict) == '>') {
  983. c = Bgetc(bdict);
  984. if(c == '<') {
  985. if (Bgetc(bdict) == 'h' && Bgetc(bdict) == 'w'
  986. && Bgetc(bdict) == '>')
  987. n = 7;
  988. }else if (c == '{')
  989. n = 4;
  990. if(n)
  991. break;
  992. }
  993. }
  994. return (Boffset(bdict)-n);
  995. }
  996. static char *prkey =
  997. "KEY TO THE PRONUNCIATION\n"
  998. "\n"
  999. "I. CONSONANTS\n"
  1000. "b, d, f, k, l, m, n, p, t, v, z: usual English values\n"
  1001. "\n"
  1002. "g as in go (gəʊ)\n"
  1003. "h ... ho! (həʊ)\n"
  1004. "r ... run (rʌn), terrier (ˈtɛriə(r))\n"
  1005. "(r)... her (hɜː(r))\n"
  1006. "s ... see (siː), success (səkˈsɜs)\n"
  1007. "w ... wear (wɛə(r))\n"
  1008. "hw ... when (hwɛn)\n"
  1009. "j ... yes (jɛs)\n"
  1010. "θ ... thin (θin), bath (bɑːθ)\n"
  1011. "ð ... then (ðɛn), bathe (beɪð)\n"
  1012. "ʃ ... shop (ʃɒp), dish (dɪʃ)\n"
  1013. "tʃ ... chop (tʃɒp), ditch (dɪtʃ)\n"
  1014. "ʒ ... vision (ˈvɪʒən), déjeuner (deʒøne)\n"
  1015. "dʒ ... judge (dʒʌdʒ)\n"
  1016. "ŋ ... singing (ˈsɪŋɪŋ), think (θiŋk)\n"
  1017. "ŋg ... finger (ˈfiŋgə(r))\n"
  1018. "\n"
  1019. "Foreign\n"
  1020. "ʎ as in It. seraglio (serˈraʎo)\n"
  1021. "ɲ ... Fr. cognac (kɔɲak)\n"
  1022. "x ... Ger. ach (ax), Sc. loch (lɒx)\n"
  1023. "ç ... Ger. ich (ɪç), Sc. nicht (nɪçt)\n"
  1024. "ɣ ... North Ger. sagen (ˈzaːɣən)\n"
  1025. "c ... Afrikaans baardmannetjie (ˈbaːrtmanəci)\n"
  1026. "ɥ ... Fr. cuisine (kɥizin)\n"
  1027. "\n"
  1028. "II. VOWELS AND DIPTHONGS\n"
  1029. "\n"
  1030. "Short\n"
  1031. "ɪ as in pit (pɪt), -ness (-nɪs)\n"
  1032. "ɛ ... pet (pɛt), Fr. sept (sɛt)\n"
  1033. "æ ... pat (pæt)\n"
  1034. "ʌ ... putt (pʌt)\n"
  1035. "ɒ ... pot (pɒt)\n"
  1036. "ʊ ... put (pʊt)\n"
  1037. "ə ... another (əˈnʌðə(r))\n"
  1038. "(ə)... beaten (ˈbiːt(ə)n)\n"
  1039. "i ... Fr. si (si)\n"
  1040. "e ... Fr. bébé (bebe)\n"
  1041. "a ... Fr. mari (mari)\n"
  1042. "ɑ ... Fr. bâtiment (bɑtimã)\n"
  1043. "ɔ ... Fr. homme (ɔm)\n"
  1044. "o ... Fr. eau (o)\n"
  1045. "ø ... Fr. peu (pø)\n"
  1046. "œ ... Fr. boeuf (bœf), coeur (kœr)\n"
  1047. "u ... Fr. douce (dus)\n"
  1048. "ʏ ... Ger. Müller (ˈmʏlər)\n"
  1049. "y ... Fr. du (dy)\n"
  1050. "\n"
  1051. "Long\n"
  1052. "iː as in bean (biːn)\n"
  1053. "ɑː ... barn (bɑːn)\n"
  1054. "ɔː ... born (bɔːn)\n"
  1055. "uː ... boon (buːn)\n"
  1056. "ɜː ... burn (bɜːn)\n"
  1057. "eː ... Ger. Schnee (ʃneː)\n"
  1058. "ɛː ... Ger. Fähre (ˈfɛːrə)\n"
  1059. "aː ... Ger. Tag (taːk)\n"
  1060. "oː ... Ger. Sohn (zoːn)\n"
  1061. "øː ... Ger. Goethe (gøːtə)\n"
  1062. "yː ... Ger. grün (gryːn)\n"
  1063. "\n"
  1064. "Nasal\n"
  1065. "ɛ˜, æ˜ as in Fr. fin (fɛ˜, fæ˜)\n"
  1066. "ã ... Fr. franc (frã)\n"
  1067. "ɔ˜ ... Fr. bon (bɔ˜n)\n"
  1068. "œ˜ ... Fr. un (œ˜)\n"
  1069. "\n"
  1070. "Dipthongs, etc.\n"
  1071. "eɪ as in bay (beɪ)\n"
  1072. "aɪ ... buy (baɪ)\n"
  1073. "ɔɪ ... boy (bɔɪ)\n"
  1074. "əʊ ... no (nəʊ)\n"
  1075. "aʊ ... now (naʊ)\n"
  1076. "ɪə ... peer (pɪə(r))\n"
  1077. "ɛə ... pair (pɛə(r))\n"
  1078. "ʊə ... tour (tʊə(r))\n"
  1079. "ɔə ... boar (bɔə(r))\n"
  1080. "\n"
  1081. "III. STRESS\n"
  1082. "\n"
  1083. "Main stress: ˈ preceding stressed syllable\n"
  1084. "Secondary stress: ˌ preceding stressed syllable\n"
  1085. "\n"
  1086. "E.g.: pronunciation (prəˌnʌnsɪˈeɪʃ(ə)n)\n";
  1087. /* TODO: find transcriptions of foreign consonents, œ, ʏ, nasals */
  1088. void
  1089. pgwprintkey(void)
  1090. {
  1091. Bprint(bout, "%s", prkey);
  1092. }
  1093. /*
  1094. * f points just after a '&', fe points at end of entry.
  1095. * Accumulate the special name, starting after the &
  1096. * and continuing until the next ';', in spec[].
  1097. * Return pointer to char after ';'.
  1098. */
  1099. static char *
  1100. getspec(char *f, char *fe)
  1101. {
  1102. char *t;
  1103. int c, i;
  1104. t = spec;
  1105. i = sizeof spec;
  1106. while(--i > 0) {
  1107. c = *f++;
  1108. if(c == ';' || f == fe)
  1109. break;
  1110. *t++ = c;
  1111. }
  1112. *t = 0;
  1113. return f;
  1114. }
  1115. /*
  1116. * f points just after '<'; fe points at end of entry.
  1117. * Expect next characters from bin to match:
  1118. * [/][^ >]+( [^>=]+=[^ >]+)*>
  1119. * tag auxname auxval
  1120. * Accumulate the tag and its auxilliary information in
  1121. * tag[], auxname[][] and auxval[][].
  1122. * Set tagstarts=1 if the tag is 'starting' (has no '/'), else 0.
  1123. * Set naux to the number of aux pairs found.
  1124. * Return pointer to after final '>'.
  1125. */
  1126. static char *
  1127. gettag(char *f, char *fe)
  1128. {
  1129. char *t;
  1130. int c, i;
  1131. t = tag;
  1132. c = *f++;
  1133. if(c == '/')
  1134. tagstarts = 0;
  1135. else {
  1136. tagstarts = 1;
  1137. *t++ = c;
  1138. }
  1139. i = Buflen;
  1140. while(--i > 0) {
  1141. c = *f++;
  1142. if(c == '>' || f == fe)
  1143. break;
  1144. *t++ = c;
  1145. }
  1146. *t = 0;
  1147. return f;
  1148. }