home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / emxtutor.zip / emxsrcd1.zip / emx / src / emxdoc / latex.c < prev    next >
C/C++ Source or Header  |  1996-05-16  |  9KB  |  389 lines

  1. /* latex.c -- LaTeX output
  2.    Copyright (c) 1993-1996 Eberhard Mattes
  3.  
  4. This file is part of emxdoc.
  5.  
  6. emxdoc is free software; you can redistribute it and/or modify it
  7. under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. emxdoc is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with emxdoc; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 59 Temple Place - Suite 330,
  19. Boston, 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.  
  31. void latex_output (const uchar *p, int may_break)
  32. {
  33.   const uchar *q;
  34.  
  35.   if (*p == ' ' && output_x >= 60 && may_break)
  36.     {
  37.       write_nl ();
  38.       ++p;
  39.     }
  40.   while ((q = strpbrk (p, "\\&#$_^")) != NULL)
  41.     {
  42.       write_nstring (p, q - p);
  43.       switch (*q)
  44.         {
  45.         case '\\':
  46.           /* TODO: Warning if no such character in current font! */
  47.           write_string ("\\bs/");
  48.           break;
  49.         case '&':
  50.           write_string ("\\&");
  51.           break;
  52.         case '#':
  53.           write_string ("\\#");
  54.           break;
  55.         case '$':
  56.           write_string ("\\$");
  57.           break;
  58.         case '_':
  59.           /* TODO: Warning if no such character in current font! */
  60.           write_string ("\\_");
  61.           break;
  62.         case '^':
  63.           /* TODO: Warning if no such character in current font! */
  64.           write_string ("\\^");
  65.           break;
  66.         default:
  67.           abort ();
  68.         }
  69.       p = q + 1;
  70.     }
  71.   write_string (p);
  72. }
  73.  
  74.  
  75. void latex_elements (enum style style)
  76. {
  77.   const struct element *ep, *ep2;
  78.   enum style style_stack[STYLE_STACK_SIZE];
  79.   int style_sp, ignore_spaces;
  80.   size_t len;
  81.   uchar *p, last;
  82.  
  83.   style_sp = 0;
  84.   style_stack[style_sp] = style;
  85.   ignore_spaces = FALSE;
  86.   for (ep = elements; ep->el != EL_END; ++ep)
  87.     switch (ep->el)
  88.       {
  89.       case EL_WORD:
  90.       case EL_PUNCT:
  91.         p = ep->wp->str;
  92.         if (strcmp (p, ".") == 0 && ep != elements && ep[-1].el == EL_WORD)
  93.           {
  94.             ep2 = ep + 1;
  95.             while (ep2->el == EL_STYLE || ep2->el == EL_ENDSTYLE)
  96.               ++ep2;
  97.             if (ep2->el == EL_SPACE)
  98.               {
  99.                 len = strlen (ep[-1].wp->str);
  100.                 if (len != 0)
  101.                   {
  102.                     last = ep[-1].wp->str[len-1];
  103.                     if (isupper (last) && ep2->n == 2)
  104.                       {
  105.                         ignore_spaces = TRUE;
  106.                         write_string ("\\@. ");
  107.                       }
  108.                     else if (!isupper (last) && ep2->n == 1)
  109.                       {
  110.                         ignore_spaces = TRUE;
  111.                         write_string (".\\ ");
  112.                       }
  113.                     else
  114.                       write_string (".");
  115.                     break;
  116.                   }
  117.               }
  118.           }
  119.         if (strcmp (p, "--") == 0)
  120.           p = "---";
  121.         if (ep->wp->special != NULL && ep->wp->special->latex != NULL)
  122.           write_string (ep->wp->special->latex);
  123.         else if (style_sp == 0 || style_stack[style_sp] == STYLE_NORMAL)
  124.           format_string (p, (ep->wp->style != STYLE_NORMAL
  125.                              ? ep->wp->style : style), FALSE);
  126.         else
  127.           format_string (p, style_stack[style_sp], FALSE);
  128.         break;
  129.       case EL_SPACE:
  130.         if (ignore_spaces)
  131.           ignore_spaces = FALSE;
  132.         else
  133.           format_spaces (ep->n, style_stack[style_sp]);
  134.         break;
  135.       case EL_BREAK:
  136.         write_line ("\\break");
  137.         break;
  138.       case EL_STYLE:
  139.         if (style_sp + 1 >= STYLE_STACK_SIZE)
  140.           fatal ("%s:%d: Style stack overflow", input_fname, line_no);
  141.         style_stack[++style_sp] = ep->n;
  142.         break;
  143.       case EL_ENDSTYLE:
  144.         if (style_sp == 0)
  145.           fatal ("%s:%d: Style stack underflow", input_fname, line_no);
  146.         --style_sp;
  147.         break;
  148.       default:
  149.         abort ();
  150.       }
  151. }
  152.  
  153.  
  154. void latex_start_hilite (void)
  155. {
  156.   write_string ("{");
  157.   if (hl_stack[hl_sp] & HL_TT)
  158.     write_string ("\\tt ");
  159.   else if (hl_stack[hl_sp] & HL_BF)
  160.     write_string ("\\bf ");
  161.   else if (hl_stack[hl_sp] & HL_SL)
  162.     write_string ("\\sl ");
  163.   else if (hl_stack[hl_sp] & HL_EM)
  164.     write_string ("\\em ");
  165. }
  166.  
  167.  
  168. void latex_end_hilite (void)
  169. {
  170.   write_string ("}");
  171. }
  172.  
  173.  
  174. void latex_end_env (void)
  175. {
  176.   switch (env_stack[env_sp].env)
  177.     {
  178.     case ENV_DESCRIPTION:
  179.     case ENV_LIST:
  180.       write_break ();
  181.       write_line ("\\end{description}");
  182.       break;
  183.     case ENV_ENUMERATE:
  184.       write_break ();
  185.       write_line ("\\end{enumerate}");
  186.       break;
  187.     case ENV_ITEMIZE:
  188.       write_break ();
  189.       write_line ("\\end{itemize}");
  190.       break;
  191.     case ENV_TYPEWRITER:
  192.     case ENV_INDENT:
  193.       write_break ();
  194.       write_line ("\\end{quote}");
  195.       break;
  196.     default:
  197.       abort ();
  198.     }
  199. }
  200.  
  201.  
  202. void latex_heading1 (void)
  203. {
  204.   write_nl ();
  205. }
  206.  
  207.  
  208. void latex_heading2 (const uchar *s)
  209. {
  210.   if (para_flag)
  211.     write_nl ();
  212.   switch (tg_level)
  213.     {
  214.     case 0:
  215.       write_string (s);
  216.       write_line ("\\break");
  217.       break;
  218.     case 1:
  219.       write_fmt ("\\section{%s}", s);
  220.       write_nl ();
  221.       break;
  222.     case 2:
  223.       write_fmt ("\\subsection{%s}", s);
  224.       write_nl ();
  225.       break;
  226.     case 3:
  227.       write_fmt ("\\subsubsection{%s}", s);
  228.       write_nl ();
  229.       break;
  230.     default:
  231.       fatal ("Sorry, LaTeX supports only 3 levels of headings");
  232.     }
  233.   write_nl ();
  234. }
  235.  
  236.  
  237. void latex_description (void)
  238. {
  239.   write_break ();
  240.   write_line ("\\begin{description}");
  241.   write_nl ();
  242. }
  243.  
  244.  
  245. void latex_enumerate (void)
  246. {
  247.   write_break ();
  248.   write_line ("\\begin{enumerate}");
  249.   write_nl ();
  250. }
  251.  
  252.  
  253. void latex_itemize (void)
  254. {
  255.   write_break ();
  256.   write_line ("\\begin{itemize}");
  257.   write_nl ();
  258. }
  259.  
  260.  
  261. void latex_indent (void)
  262. {
  263.   write_break ();
  264.   write_line ("\\begin{quote}");
  265. }
  266.  
  267.  
  268. void latex_list (void)
  269. {
  270.   write_break ();
  271.   write_line ("\\begin{description}");
  272. }
  273.  
  274.  
  275. void latex_verbatim_start (enum tag tag_end)
  276. {
  277.   write_break ();
  278.   switch (tag_end)
  279.     {
  280.     case TAG_ENDHEADERS:
  281.       write_nl ();
  282.       write_line ("Headers:");
  283.       break;
  284.     case TAG_ENDSAMPLECODE:
  285.       write_nl ();
  286.       write_line ("Example:");
  287.       break;
  288.     case TAG_ENDEXAMPLE:
  289.       write_line ("\\begin{quote}");
  290.       break;
  291.     default:
  292.       break;
  293.     }
  294.   write_break ();
  295.   write_line ("\\begin{verbatim}");
  296. }
  297.  
  298.  
  299. void latex_verbatim_end (enum tag tag_end)
  300. {
  301.   write_line ("\\end{verbatim}");
  302.   switch (tag_end)
  303.     {
  304.     case TAG_ENDEXAMPLE:
  305.       write_line ("\\end{quote}");
  306.       break;
  307.     default:
  308.       break;
  309.     }
  310. }
  311.  
  312.  
  313. void latex_description_item (const uchar *s)
  314. {
  315.   write_break ();
  316.   write_string ("\\item[");
  317.   make_elements (s);
  318.   latex_elements (STYLE_NORMAL);
  319.   write_line ("]");
  320. }
  321.  
  322.  
  323. void latex_enumerate_item (void)
  324. {
  325.   write_break ();
  326.   write_line ("\\item");
  327. }
  328.  
  329.  
  330. void latex_itemize_item (void)
  331. {
  332.   write_break ();
  333.   write_line ("\\item");
  334. }
  335.  
  336.  
  337. void latex_list_item (const uchar *s)
  338. {
  339.   write_break ();
  340.   write_string ("\\item[");
  341.   make_elements (s);
  342.   latex_elements (STYLE_NORMAL);
  343.   write_line ("]");
  344. }
  345.  
  346.  
  347. void latex_copy (void)
  348. {
  349.   if (para_flag)
  350.     {
  351.       write_break ();
  352.       write_nl ();
  353.     }
  354.   switch (env_stack[env_sp].env)
  355.     {
  356.     case ENV_TYPEWRITER:
  357.       latex_elements (STYLE_TTY);
  358.       break;
  359.     default:
  360.       latex_elements (STYLE_NORMAL);
  361.       break;
  362.     }
  363. }
  364.  
  365.  
  366. void latex_start (void)
  367. {
  368.   write_line ("\\documentstyle[emxdoc]{article}");
  369.   if (title != NULL)
  370.     {
  371.       write_string ("\\title{");
  372.       format_string (title, STYLE_NORMAL, FALSE);
  373.       write_line ("}");
  374.       write_line ("\\author{}");
  375.     }
  376.   write_line ("\\begin{document}");
  377.   if (title != NULL)
  378.     write_line ("\\maketitle");
  379.   write_line ("\\tableofcontents");
  380.   write_line ("\\newpage");
  381. }
  382.  
  383.  
  384. void latex_end (void)
  385. {
  386.   write_nl ();
  387.   write_line ("\\end{document}");
  388. }
  389.