source: trunk/emx/src/emxdoc/latex.c@ 2446

Last change on this file since 2446 was 18, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 11.0 KB
Line 
1/* latex.c -- LaTeX output
2 Copyright (c) 1993-2000 Eberhard Mattes
3
4This file is part of emxdoc.
5
6emxdoc is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11emxdoc is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with emxdoc; see the file COPYING. If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21
22/* TODO: LaTeX output is work in progress */
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <ctype.h>
28#include "emxdoc.h"
29#include "latex.h"
30
31static const uchar *index_word1;
32static int index_flag;
33
34void latex_output (const uchar *p, int may_break)
35{
36 const uchar *q;
37
38 if (*p == ' ' && output_x >= 60 && may_break)
39 {
40 write_nl ();
41 ++p;
42 }
43 while ((q = strpbrk (p, "\\&#$%_^")) != NULL)
44 {
45 write_nstring (p, q - p);
46 switch (*q)
47 {
48 case '\\':
49 /* TODO: Warning if no such character in current font! */
50 write_string ("\\bs/");
51 break;
52 case '&':
53 write_string ("\\&");
54 break;
55 case '#':
56 write_string ("\\#");
57 break;
58 case '$':
59 write_string ("\\$");
60 break;
61 case '%':
62 write_string ("\\%");
63 break;
64 case '_':
65 /* TODO: Warning if no such character in current font! */
66 write_string ("\\_");
67 break;
68 case '^':
69 /* TODO: Warning if no such character in current font! */
70 write_string ("\\^");
71 break;
72 default:
73 abort ();
74 }
75 p = q + 1;
76 }
77 write_string (p);
78}
79
80
81static void latex_elements (enum style style, int alltt)
82{
83 const struct element *ep, *ep2;
84 enum style style_stack[STYLE_STACK_SIZE];
85 int style_sp, ignore_spaces;
86 size_t len;
87 uchar *p, last;
88
89 if (alltt)
90 write_line ("\\begin{alltt}");
91 style_sp = 0;
92 style_stack[style_sp] = style;
93 ignore_spaces = FALSE;
94 for (ep = elements; ep->el != EL_END; ++ep)
95 switch (ep->el)
96 {
97 case EL_WORD:
98 case EL_PUNCT:
99 p = ep->wp->str;
100 if (strcmp (p, ".") == 0 && ep != elements && ep[-1].el == EL_WORD)
101 {
102 ep2 = ep + 1;
103 while (ep2->el == EL_STYLE || ep2->el == EL_ENDSTYLE)
104 ++ep2;
105 if (ep2->el == EL_SPACE)
106 {
107 len = strlen (ep[-1].wp->str);
108 if (len != 0)
109 {
110 last = ep[-1].wp->str[len-1];
111 if (isupper (last) && ep2->n == 2)
112 {
113 ignore_spaces = TRUE;
114 write_string ("\\@. ");
115 }
116 else if (!isupper (last) && ep2->n == 1)
117 {
118 ignore_spaces = TRUE;
119 write_string (".\\ ");
120 }
121 else
122 write_string (".");
123 break;
124 }
125 }
126 }
127 if (strcmp (p, "--") == 0)
128 p = "---";
129 if (ep->wp->special != NULL && ep->wp->special->latex != NULL)
130 write_string (ep->wp->special->latex);
131 else if (style_sp == 0 || style_stack[style_sp] == STYLE_NORMAL)
132 format_string (p, (ep->wp->style != STYLE_NORMAL
133 ? ep->wp->style : style), FALSE);
134 else
135 format_string (p, style_stack[style_sp], FALSE);
136 break;
137 case EL_SPACE:
138 if (ignore_spaces)
139 ignore_spaces = FALSE;
140 else
141 format_spaces (ep->n, style_stack[style_sp], FALSE);
142 break;
143 case EL_BREAK:
144 if (alltt)
145 write_nl ();
146 else
147 write_line ("\\break");
148 break;
149 case EL_STYLE:
150 if (style_sp + 1 >= STYLE_STACK_SIZE)
151 fatal ("%s:%d: Style stack overflow", input_fname, line_no);
152 style_stack[++style_sp] = ep->n;
153 break;
154 case EL_ENDSTYLE:
155 if (style_sp == 0)
156 fatal ("%s:%d: Style stack underflow", input_fname, line_no);
157 --style_sp;
158 break;
159 default:
160 abort ();
161 }
162 if (alltt)
163 write_line ("\\end{alltt}");
164}
165
166
167void latex_start_hilite (void)
168{
169 if (hl_stack[hl_sp] & HL_TT)
170 write_string ("\\texttt{");
171 else if (hl_stack[hl_sp] & HL_BF)
172 write_string ("\\textbf{");
173 else if (hl_stack[hl_sp] & HL_SL)
174 write_string ("\\textsl{");
175 else if (hl_stack[hl_sp] & HL_EM)
176 write_string ("\\emph{");
177}
178
179
180void latex_end_hilite (void)
181{
182 write_string ("}");
183}
184
185
186void latex_end_env (void)
187{
188 switch (env_stack[env_sp].env)
189 {
190 case ENV_DESCRIPTION:
191 case ENV_LIST:
192 write_break ();
193 write_line ("\\end{description}");
194 break;
195 case ENV_ENUMERATE:
196 write_break ();
197 write_line ("\\end{enumerate}");
198 break;
199 case ENV_ITEMIZE:
200 write_break ();
201 write_line ("\\end{itemize}");
202 break;
203 case ENV_TYPEWRITER:
204 case ENV_INDENT:
205 write_break ();
206 write_line ("\\end{quote}");
207 break;
208 default:
209 abort ();
210 }
211}
212
213
214void latex_heading1 (void)
215{
216 write_nl ();
217}
218
219
220void latex_heading2 (const uchar *s)
221{
222 if (para_flag)
223 write_nl ();
224 switch (tg_level)
225 {
226 case 0:
227 latex_output (s, FALSE);
228 write_line ("\\break");
229 break;
230 case 1:
231 write_string ("\\section{");
232 latex_output (s, FALSE);
233 write_line ("}");
234 break;
235 case 2:
236 write_string ("\\subsection{");
237 latex_output (s, FALSE);
238 write_line ("}");
239 break;
240 case 3:
241 write_string ("\\subsubsection{");
242 latex_output (s, FALSE);
243 write_line ("}");
244 break;
245 default:
246 fatal ("Sorry, LaTeX supports only 3 levels of headings");
247 }
248 write_nl ();
249}
250
251
252void latex_description (void)
253{
254 write_break ();
255 write_line ("\\begin{description}");
256 write_nl ();
257}
258
259
260void latex_enumerate (void)
261{
262 write_break ();
263 write_line ("\\begin{enumerate}");
264 write_nl ();
265}
266
267
268void latex_itemize (void)
269{
270 write_break ();
271 write_line ("\\begin{itemize}");
272 write_nl ();
273}
274
275
276void latex_indent (void)
277{
278 write_break ();
279 write_line ("\\begin{quote}");
280}
281
282
283void latex_list (void)
284{
285 write_break ();
286 write_line ("\\begin{description}");
287}
288
289
290void latex_verbatim_start (enum tag tag_end)
291{
292 write_break ();
293 switch (tag_end)
294 {
295 case TAG_ENDHEADERS:
296 write_nl ();
297 write_line ("\\subsubsection*{Headers}");
298 break;
299 case TAG_ENDSAMPLECODE:
300 write_nl ();
301 write_line ("\\subsubsection*{Example}");
302 break;
303 case TAG_ENDEXAMPLE:
304 write_line ("\\begin{quote}");
305 break;
306 default:
307 break;
308 }
309 write_break ();
310 write_line ("\\begin{verbatim}");
311}
312
313
314void latex_verbatim_end (enum tag tag_end)
315{
316 write_line ("\\end{verbatim}");
317 switch (tag_end)
318 {
319 case TAG_ENDEXAMPLE:
320 write_line ("\\end{quote}");
321 break;
322 default:
323 break;
324 }
325}
326
327
328void latex_description_item (const uchar *s)
329{
330 write_break ();
331 write_string ("\\item[");
332 make_elements (s);
333 latex_elements (STYLE_NORMAL, FALSE);
334 write_line ("]");
335}
336
337
338void latex_enumerate_item (void)
339{
340 write_break ();
341 write_line ("\\item");
342}
343
344
345void latex_itemize_item (void)
346{
347 write_break ();
348 write_line ("\\item");
349}
350
351
352void latex_list_item (const uchar *s)
353{
354 write_break ();
355 write_string ("\\item[");
356 make_elements (s);
357 latex_elements (STYLE_NORMAL, FALSE);
358 write_line ("]");
359}
360
361
362void latex_copy (void)
363{
364 if (para_flag)
365 {
366 write_break ();
367 write_nl ();
368 }
369 switch (env_stack[env_sp].env)
370 {
371 case ENV_TYPEWRITER:
372 latex_elements (STYLE_NORMAL, TRUE);
373 break;
374 default:
375 latex_elements (STYLE_NORMAL, FALSE);
376 break;
377 }
378}
379
380void latex_prototype_start (void)
381{
382 write_break ();
383 write_fmt ("\\subsubsection*{Prototype%s}", function_count == 1 ? "" : "s");
384 write_nl ();
385}
386
387void latex_prototype_end (uchar *compat)
388{
389 latex_elements (STYLE_NORMAL, TRUE);
390 if (compat[0] != 0)
391 {
392 write_break ();
393 write_line ("\\subsubsection*{Compatibility}");
394 format_string (compat, STYLE_NORMAL, TRUE);
395 compat[0] = 0;
396 }
397 write_line ("\\subsubsection*{Description}");
398
399}
400
401void latex_see_also_start (void)
402{
403 write_break ();
404 write_line ("\\subsubsection*{See also}");
405}
406
407void latex_see_also_word (const uchar *word, const uchar *s)
408{
409 latex_output (word, FALSE);
410 if (*s != 0)
411 write_string (", ");
412}
413
414void latex_libref_section (const uchar *s)
415{
416 write_break ();
417 write_fmt ("\\subsubsection*{%s}", s);
418 write_nl ();
419}
420
421void latex_sample_file (const uchar *s)
422{
423 latex_libref_section ("Example");
424 format_string ("See ", STYLE_NORMAL, FALSE);
425 format_string (s, STYLE_TTY, FALSE);
426 para_flag = TRUE;
427}
428
429void latex_function_start (const struct toc *tp)
430{
431 write_break ();
432 write_string ("\\subsection{");
433 latex_output (tp->title, TRUE);
434 write_line ("}");
435}
436
437void latex_function_function (const uchar *s)
438{
439 if (index_word1 != NULL)
440 latex_index (s, 2);
441}
442
443void latex_start (void)
444{
445 write_line ("\\documentclass{article}");
446 write_line ("\\usepackage{emxdoc}");
447 write_line ("\\usepackage{alltt}");
448 if (output_encoding == ENC_CP850)
449 write_line ("\\usepackage[cp850]{inputenc}");
450 else if (output_encoding == ENC_ISO8859_1)
451 write_line ("\\usepackage[latin1]{inputenc}");
452 write_line ("\\usepackage[T1]{fontenc}");
453 if (index_flag)
454 write_line ("\\usepackage{makeidx}");
455 if (title != NULL)
456 {
457 write_string ("\\title{");
458 format_string (title, STYLE_NORMAL, FALSE);
459 write_line ("}");
460 write_line ("\\author{}");
461 }
462 if (index_flag)
463 write_line ("\\makeindex");
464 write_line ("\\begin{document}");
465 if (title != NULL)
466 write_line ("\\maketitle");
467 write_line ("\\tableofcontents");
468 write_line ("\\newpage");
469}
470
471
472void latex_end (void)
473{
474 if (out)
475 {
476 write_nl ();
477 if (index_flag)
478 write_line ("\\printindex");
479 write_line ("\\end{document}");
480 }
481}
482
483void latex_index (const uchar *s, int level)
484{
485 switch (level)
486 {
487 case 0:
488 index_flag = TRUE;
489 if (out)
490 {
491 write_string ("\\index{");
492 latex_output (s, FALSE);
493 write_string ("}");
494 }
495 break;
496 case 1:
497 if (*s == 0)
498 index_word1 = NULL;
499 else
500 {
501 struct word *wp = word_add (s);
502 index_word1 = wp->str;
503 }
504 break;
505 case 2:
506 if (index_word1 == NULL)
507 fatal ("%s:%d: %ci2 without %ci1", input_fname, line_no,
508 escape, escape);
509 index_flag = TRUE;
510 if (out)
511 {
512 write_string ("\\index{");
513 latex_output (index_word1, FALSE);
514 write_string ("!");
515 latex_output (s, FALSE);
516 write_string ("}");
517 }
518 break;
519 default:
520 abort ();
521 }
522}
Note: See TracBrowser for help on using the repository browser.