PageRenderTime 60ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/docs/src/makedoc/makertf.c

https://github.com/dodamn/pkg-allegro4.2
C | 514 lines | 396 code | 35 blank | 83 comment | 146 complexity | 0679258cd6d220273179a12d1f97fe27 MD5 | raw file
Possible License(s): LGPL-2.0
  1. /* ______ ___ ___
  2. * /\ _ \ /\_ \ /\_ \
  3. * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
  4. * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
  5. * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
  6. * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
  7. * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
  8. * /\____/
  9. * \_/__/
  10. *
  11. * Makedoc's rtf output routines.
  12. *
  13. * By Shawn Hargreaves.
  14. *
  15. * See readme.txt for copyright information.
  16. *
  17. * See allegro/docs/src/makedoc/format.txt for a brief description of
  18. * the source of _tx files.
  19. */
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include "makertf.h"
  23. #include "makedoc.h"
  24. #include "makemisc.h"
  25. char rtfheader[256] = "";
  26. char *rtf_language_header;
  27. /* write_rtf:
  28. */
  29. int write_rtf(char *filename)
  30. {
  31. LINE *line = head;
  32. LINE *l;
  33. char *p, *last = 0;
  34. FILE *f;
  35. int preformat = 0;
  36. int prevhead = 0;
  37. int prevdef = 0;
  38. int multidef = 0;
  39. int pardebt = 0;
  40. int parloan = 0;
  41. int indent = 0;
  42. int indef = 0;
  43. int weakdef = 0;
  44. int bullet = 0;
  45. int inbullet = 0;
  46. int tallbullets = 0;
  47. #define PAR() \
  48. { \
  49. if (pardebt > 0) \
  50. pardebt--; \
  51. else \
  52. fputs("\\par ", f); \
  53. \
  54. while (inbullet > 0) { \
  55. fputs("\\pard ", f); \
  56. fprintf(f, "\\li%d ", indent*INDENT_SIZE); \
  57. inbullet--; \
  58. } \
  59. }
  60. /*printf("writing %s\n", filename);*/
  61. f = fopen(filename, "w");
  62. if (!f)
  63. return 1;
  64. /* Fonts:
  65. * 0 - Times New Roman
  66. * 1 - Courier New
  67. * 2 - Symbol
  68. *
  69. * Colors:
  70. * 1 - Black
  71. * 2 - Red
  72. * 3 - Green
  73. * 4 - Blue
  74. *
  75. * Styles:
  76. * 0 - Normal
  77. * 1 - Quotation
  78. * 2 - Heading 1
  79. * 3 - Heading 2
  80. * 4 - Header
  81. * 5 - TOC 1
  82. * 6 - Index 1
  83. */
  84. #define NORMAL_STYLE "\\f0\\fs20 "
  85. #define QUOTATION_STYLE "\\f1\\fs18 "
  86. #define HEADING_STYLE "\\f0\\fs48\\sa600\\pagebb\\keepn\\ul "
  87. #define DEFINITION_STYLE "\\f0\\fs24\\sb200\\keepn\\sa200\\b "
  88. #define HEADER_STYLE "\\f0\\fs20\\tqc\\tx4153\\tqr\\tx8306 "
  89. #define TOC_STYLE "\\f0\\fs24\\tqr\\tldot\\tx8640 "
  90. #define INDEX_STYLE "\\f0\\fs20\\tqr\\tldot\\tx8640 "
  91. #define INDENT_SIZE 400
  92. #define BULLET_INDENT 250
  93. fputs("{\\rtf\\ansi\\deff0\\widowctrl " NORMAL_STYLE "\n", f);
  94. fputs("{\\colortbl;\\red0\\green0\\blue0;\\red255\\green0\\blue0;\\red0\\green255\\blue0;\\red0\\green0\\blue255;}\n", f);
  95. if(rtf_language_header)
  96. fputs(rtf_language_header, f);
  97. else {
  98. fputs("{\\fonttbl{\\f0\\froman\\fcharset0\\fprq2 Times New Roman;}\n", f);
  99. fputs("{\\f1\\fmodern\\fcharset0\\fprq1 Courier New;}\n", f);
  100. fputs("{\\f2\\froman\\fcharset2\\fprq2 Symbol;}}\n", f);
  101. }
  102. fputs("{\\stylesheet {\\widctlpar " NORMAL_STYLE "\\snext0 Normal;}\n", f);
  103. fputs("{\\s1\\widctlpar " QUOTATION_STYLE "\\sbasedon0\\snext1 Quotation;}\n", f);
  104. fputs("{\\s2\\widctlpar " HEADING_STYLE "\\sbasedon0\\snext2 Heading 1;}\n", f);
  105. fputs("{\\s3\\widctlpar " DEFINITION_STYLE "\\sbasedon0\\snext3 Heading 2;}\n", f);
  106. fputs("{\\s4\\widctlpar " HEADER_STYLE "\\sbasedon0\\snext4 Header;}\n", f);
  107. fputs("{\\s5\\widctlpar " TOC_STYLE "\\sbasedon0\\snext0 TOC 1;}\n", f);
  108. fputs("{\\s6\\widctlpar " INDEX_STYLE "\\sbasedon0\\snext0 Index 1;}}\n", f);
  109. if (rtfheader[0]) {
  110. fputs("{\\header \\pard\\plain \\s4 " HEADER_STYLE "\\pvpara\\phmrg\\posxr\\posy0 page {\\field{\\*\\fldinst PAGE}{\\fldrslt 2}}\n", f);
  111. fputs("\\par \\pard \\s4\\ri360 " HEADER_STYLE "{\\i ", f);
  112. fputs(rtfheader, f);
  113. fputs("} \\pard}\n", f);
  114. }
  115. while (line) {
  116. if (line->flags & RTF_FLAG) {
  117. p = line->text;
  118. if (indef) {
  119. /* end the indentation from the previous definition? */
  120. if (weakdef) {
  121. if (is_empty(strip_html(line->text))) {
  122. fputs("\\par}", f);
  123. pardebt++;
  124. indent--;
  125. indef = 0;
  126. weakdef = 0;
  127. }
  128. }
  129. else {
  130. l = line;
  131. while ((l->next) && l->text && (is_empty(strip_html(l->text))))
  132. l = l->next;
  133. if (l->flags & (HEADING_FLAG | DEFINITION_FLAG | NODE_FLAG)) {
  134. fputs("\\par}", f);
  135. pardebt++;
  136. indent--;
  137. indef = 0;
  138. }
  139. }
  140. }
  141. if (line->flags & HEADING_FLAG) {
  142. /* start a section heading */
  143. fputs("{\\s2 " HEADING_STYLE, f);
  144. }
  145. else if (line->flags & DEFINITION_FLAG) {
  146. /* start a function definition */
  147. if (prevdef) {
  148. if (multidef) {
  149. /* continued from previous line */
  150. while ((p[1]) && (myisspace(p[1])))
  151. p++;
  152. }
  153. else {
  154. /* new definition, but flush with previous one */
  155. fputs("{\\s3 " DEFINITION_STYLE "\\sb0 ", f);
  156. }
  157. }
  158. else {
  159. /* new function definition */
  160. fputs("{\\s3 " DEFINITION_STYLE, f);
  161. }
  162. if (line->flags & CONTINUE_FLAG) {
  163. /* this definition continues onto the next line */
  164. multidef = 1;
  165. }
  166. else {
  167. /* this paragraph should be flush with the next */
  168. multidef = 0;
  169. if ((line->next) && (line->next->flags & DEFINITION_FLAG))
  170. fputs("\\sa0 ", f);
  171. }
  172. prevdef = 1;
  173. }
  174. else {
  175. prevdef = 0;
  176. multidef = 0;
  177. if (!preformat) {
  178. /* skip leading spaces */
  179. while ((*p) && (myisspace(*p)))
  180. p++;
  181. }
  182. }
  183. while (*p) {
  184. last = 0;
  185. if (strincmp(p, "<p>") == 0) {
  186. /* paragraph breaks */
  187. PAR();
  188. p += 3;
  189. }
  190. else if (strincmp(p, "<br>") == 0) {
  191. /* line breaks */
  192. PAR();
  193. p += 4;
  194. }
  195. else if (strincmp(p, "<pre>") == 0) {
  196. /* start preformatted text */
  197. fputs("\\par {\\s1 " QUOTATION_STYLE, f);
  198. while (inbullet > 0) {
  199. fputs("\\pard ", f);
  200. fprintf(f, "\\li%d ", indent*INDENT_SIZE);
  201. inbullet--;
  202. }
  203. preformat = 1;
  204. p += 5;
  205. }
  206. else if (strincmp(p, "</pre>") == 0) {
  207. /* end preformatted text */
  208. if (strincmp(line->text, "</pre>") == 0) {
  209. fputs("}", f);
  210. if (indent > (indef ? 1 : 0)) {
  211. fputs("\\pard ", f);
  212. fprintf(f, "\\li%d ", indent*INDENT_SIZE);
  213. }
  214. }
  215. else {
  216. fputs("\\par}", f);
  217. pardebt++;
  218. if (indent > (indef ? 1 : 0))
  219. inbullet++;
  220. }
  221. preformat = 0;
  222. p += 6;
  223. }
  224. else if (strincmp(p, "<title>") == 0) {
  225. /* start document title */
  226. fputs("{\\info{\\title ", f);
  227. p += 7;
  228. }
  229. else if (strincmp(p, "</title>") == 0) {
  230. /* end document title */
  231. fputs("}{\\author Allegro makedoc utility}}\n", f);
  232. p += 8;
  233. }
  234. else if (strincmp(p, "<hr>") == 0) {
  235. /* section division */
  236. if (strincmp(line->text, "</pre>"))
  237. PAR();
  238. fputs("\\brdrb\\brdrs\\brdrw15\\brsp20 \\par \\pard \\par ", f);
  239. p += 4;
  240. }
  241. else if (strincmp(p, "<b>") == 0) {
  242. /* start bold text */
  243. fputs("{\\b ", f);
  244. p += 3;
  245. }
  246. else if (strincmp(p, "</b>") == 0) {
  247. /* end bold text */
  248. fputs("\\par}", f);
  249. pardebt++;
  250. p += 4;
  251. }
  252. else if (strincmp(p, "<i>") == 0) {
  253. /* start italic text */
  254. fputs("{\\i ", f);
  255. p += 3;
  256. }
  257. else if (strincmp(p, "</i>") == 0) {
  258. /* end italic text */
  259. fputs("\\par}", f);
  260. pardebt++;
  261. p += 4;
  262. }
  263. else if (strincmp(p, "<h1>") == 0) {
  264. /* start heading text */
  265. fputs("{\\f0\\fs48 ", f);
  266. p += 4;
  267. }
  268. else if (strincmp(p, "</h1>") == 0) {
  269. /* end heading text */
  270. fputs("\\par}", f);
  271. pardebt++;
  272. p += 5;
  273. }
  274. else if (strincmp(p, "<h4>") == 0) {
  275. /* start subheading text */
  276. fputs("{\\f0\\fs24\\b ", f);
  277. p += 4;
  278. }
  279. else if (strincmp(p, "</h4>") == 0) {
  280. /* end subheading text */
  281. fputs("\\par}", f);
  282. pardebt++;
  283. p += 5;
  284. }
  285. else if (strincmp(p, "<center>") == 0) {
  286. /* start centered text */
  287. fputs("\\par {\\qc ", f);
  288. pardebt++;
  289. p += 8;
  290. }
  291. else if (strincmp(p, "</center>") == 0) {
  292. /* end centered text */
  293. fputs("\\par}", f);
  294. pardebt++;
  295. p += 9;
  296. }
  297. else if (strincmp(p, "<a name=\"") == 0) {
  298. /* begin index entry */
  299. fputs("{\\xe\\v ", f);
  300. p += 9;
  301. while ((*p) && (*p != '"')) {
  302. fputc((unsigned char)*p, f);
  303. p++;
  304. }
  305. fputs("}", f);
  306. if (*p)
  307. p += 2;
  308. }
  309. else if (strincmp(p, "<ul>") == 0) {
  310. /* start bullet list */
  311. indent++;
  312. fprintf(f, "\\par {\\li%d ", indent*INDENT_SIZE);
  313. pardebt++;
  314. p += 4;
  315. }
  316. else if (strincmp(p, "</ul>") == 0) {
  317. /* end bullet list */
  318. indent--;
  319. if (indent == (indef ? 1 : 0))
  320. tallbullets = 0;
  321. else
  322. inbullet++;
  323. fputs("\\par}", f);
  324. pardebt++;
  325. p += 5;
  326. }
  327. else if (strincmp(p, "<li>") == 0) {
  328. /* bullet item */
  329. bullet = 1;
  330. p += 4;
  331. }
  332. else if (*p == '<') {
  333. /* skip unknown HTML tokens */
  334. while ((*p) && (*p != '>'))
  335. p++;
  336. if (*p)
  337. p++;
  338. }
  339. else if (strincmp(p, "&lt") == 0) {
  340. /* less-than HTML tokens */
  341. fputs("<", f);
  342. p += 3;
  343. }
  344. else if (strincmp(p, "&gt") == 0) {
  345. /* greater-than HTML tokens */
  346. fputs(">", f);
  347. p += 3;
  348. }
  349. else if (*p == '\\') {
  350. /* backslash escape */
  351. fputs("\\\\", f);
  352. p++;
  353. }
  354. else if (*p == '{') {
  355. /* open brace escape */
  356. fputs("\\{", f);
  357. p++;
  358. }
  359. else if (*p == '}') {
  360. /* close brace escape */
  361. fputs("\\}", f);
  362. p++;
  363. }
  364. else {
  365. while (pardebt > 0) {
  366. fputs("\\par ", f);
  367. pardebt--;
  368. }
  369. if (bullet) {
  370. /* precede this paragraph with a bullet symbol */
  371. fputs("{\\pntext\\f2\\fs16 \\'b7\\tab}\n", f);
  372. fprintf(f, "{\\*\\pn \\pnlvlblt\\pnf2\\pnfs16\\pnindent%d{\\pntxtb \\'b7}}\n", BULLET_INDENT);
  373. fprintf(f, "\\fi%d\\li%d ", -BULLET_INDENT, indent*INDENT_SIZE);
  374. if (tallbullets)
  375. fputs("\\sa80 ", f);
  376. bullet = 0;
  377. inbullet++;
  378. }
  379. /* normal character */
  380. fputc((unsigned char)*p, f);
  381. last = p++;
  382. }
  383. }
  384. if (line->flags & HEADING_FLAG) {
  385. /* end a section heading */
  386. fputs("\\par }\n", f);
  387. }
  388. else if (prevdef) {
  389. /* end a function definition */
  390. if (!multidef) {
  391. fputs("\\par }\n", f);
  392. if ((!indef) && (line->next) && (!(line->next->flags & DEFINITION_FLAG))) {
  393. /* indent the definition body text */
  394. indent++;
  395. fprintf(f, "{\\li%d ", indent*INDENT_SIZE);
  396. indef = 1;
  397. if (line->flags & NONODE_FLAG)
  398. weakdef = 1;
  399. }
  400. }
  401. }
  402. else if (preformat) {
  403. /* hard CR for preformatted blocks */
  404. fputs("\n", f);
  405. parloan++;
  406. }
  407. else if (!(line->flags & NO_EOL_FLAG)) {
  408. if ((is_empty(strip_html(line->text))) &&
  409. (!strstr(line->text, "<hr>"))) {
  410. /* output an empty line */
  411. if (!prevhead) {
  412. parloan++;
  413. if (!strstr(line->text, "</pre>"))
  414. parloan++;
  415. }
  416. }
  417. else {
  418. if (last && *last != 32)
  419. fputs(" ", f); /* add artificial space */
  420. fputs("\n", f); /* normal EOL */
  421. }
  422. }
  423. }
  424. else if (line->flags & NODE_FLAG) {
  425. /* index node */
  426. if (line->flags & HTML_FLAG) {
  427. fputs("\\brdrb\\brdrs\\brdrw15\\brsp20 \\par \\pard \\par \\par ", f);
  428. }
  429. fputs("{\\xe\\v ", f);
  430. fputs(line->text, f);
  431. fputs("}\n", f);
  432. }
  433. else if (line->flags & TOC_FLAG) {
  434. /* table of contents */
  435. PAR();
  436. fputs("\n{\\field{\\*\\fldinst TOC \\\\t \"Heading 1\" }{\\fldrslt {\\b\\i\\ul\\fs24\\cf2 Update this field to generate the table of contents.}}}\n", f);
  437. }
  438. else if (line->flags & INDEX_FLAG) {
  439. /* index */
  440. PAR();
  441. fputs("\n{\\field{\\*\\fldinst INDEX \\\\e \"\\tab \" \\c \"1\" }{\\fldrslt {\\b\\i\\ul\\fs24\\cf2 Update this field to generate the document index.}}}\n", f);
  442. }
  443. else if (line->flags & TALLBULLET_FLAG) {
  444. /* larger spacing after bulleted paragraphs */
  445. tallbullets = 1;
  446. }
  447. prevhead = (line->flags & HEADING_FLAG);
  448. /* advance to the next line */
  449. l = line->next;
  450. if (l) {
  451. while ((l->next) && l->text && (is_empty(l->text)) && (l->next->flags == l->flags)) {
  452. l = l->next;
  453. }
  454. if ((l->next) && (l->next->flags & HEADING_FLAG)) {
  455. if (indef) {
  456. fputs("\\par}", f);
  457. pardebt++;
  458. indent--;
  459. indef = 0;
  460. }
  461. PAR();
  462. line = l->next;
  463. parloan = 0;
  464. pardebt = 0;
  465. }
  466. else
  467. line = line->next;
  468. }
  469. else
  470. line = NULL;
  471. while (parloan > 0) {
  472. PAR();
  473. parloan--;
  474. }
  475. }
  476. fputs("}\n", f);
  477. fclose(f);
  478. return 0;
  479. }