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 >
Wrap
C/C++ Source or Header
|
1996-05-16
|
9KB
|
389 lines
/* latex.c -- LaTeX output
Copyright (c) 1993-1996 Eberhard Mattes
This file is part of emxdoc.
emxdoc is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
emxdoc is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with emxdoc; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* TODO: LaTeX output is work in progress */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "emxdoc.h"
#include "latex.h"
void latex_output (const uchar *p, int may_break)
{
const uchar *q;
if (*p == ' ' && output_x >= 60 && may_break)
{
write_nl ();
++p;
}
while ((q = strpbrk (p, "\\$_^")) != NULL)
{
write_nstring (p, q - p);
switch (*q)
{
case '\\':
/* TODO: Warning if no such character in current font! */
write_string ("\\bs/");
break;
case '&':
write_string ("\\&");
break;
case '#':
write_string ("\\#");
break;
case '$':
write_string ("\\$");
break;
case '_':
/* TODO: Warning if no such character in current font! */
write_string ("\\_");
break;
case '^':
/* TODO: Warning if no such character in current font! */
write_string ("\\^");
break;
default:
abort ();
}
p = q + 1;
}
write_string (p);
}
void latex_elements (enum style style)
{
const struct element *ep, *ep2;
enum style style_stack[STYLE_STACK_SIZE];
int style_sp, ignore_spaces;
size_t len;
uchar *p, last;
style_sp = 0;
style_stack[style_sp] = style;
ignore_spaces = FALSE;
for (ep = elements; ep->el != EL_END; ++ep)
switch (ep->el)
{
case EL_WORD:
case EL_PUNCT:
p = ep->wp->str;
if (strcmp (p, ".") == 0 && ep != elements && ep[-1].el == EL_WORD)
{
ep2 = ep + 1;
while (ep2->el == EL_STYLE || ep2->el == EL_ENDSTYLE)
++ep2;
if (ep2->el == EL_SPACE)
{
len = strlen (ep[-1].wp->str);
if (len != 0)
{
last = ep[-1].wp->str[len-1];
if (isupper (last) && ep2->n == 2)
{
ignore_spaces = TRUE;
write_string ("\\@. ");
}
else if (!isupper (last) && ep2->n == 1)
{
ignore_spaces = TRUE;
write_string (".\\ ");
}
else
write_string (".");
break;
}
}
}
if (strcmp (p, "--") == 0)
p = "---";
if (ep->wp->special != NULL && ep->wp->special->latex != NULL)
write_string (ep->wp->special->latex);
else if (style_sp == 0 || style_stack[style_sp] == STYLE_NORMAL)
format_string (p, (ep->wp->style != STYLE_NORMAL
? ep->wp->style : style), FALSE);
else
format_string (p, style_stack[style_sp], FALSE);
break;
case EL_SPACE:
if (ignore_spaces)
ignore_spaces = FALSE;
else
format_spaces (ep->n, style_stack[style_sp]);
break;
case EL_BREAK:
write_line ("\\break");
break;
case EL_STYLE:
if (style_sp + 1 >= STYLE_STACK_SIZE)
fatal ("%s:%d: Style stack overflow", input_fname, line_no);
style_stack[++style_sp] = ep->n;
break;
case EL_ENDSTYLE:
if (style_sp == 0)
fatal ("%s:%d: Style stack underflow", input_fname, line_no);
--style_sp;
break;
default:
abort ();
}
}
void latex_start_hilite (void)
{
write_string ("{");
if (hl_stack[hl_sp] & HL_TT)
write_string ("\\tt ");
else if (hl_stack[hl_sp] & HL_BF)
write_string ("\\bf ");
else if (hl_stack[hl_sp] & HL_SL)
write_string ("\\sl ");
else if (hl_stack[hl_sp] & HL_EM)
write_string ("\\em ");
}
void latex_end_hilite (void)
{
write_string ("}");
}
void latex_end_env (void)
{
switch (env_stack[env_sp].env)
{
case ENV_DESCRIPTION:
case ENV_LIST:
write_break ();
write_line ("\\end{description}");
break;
case ENV_ENUMERATE:
write_break ();
write_line ("\\end{enumerate}");
break;
case ENV_ITEMIZE:
write_break ();
write_line ("\\end{itemize}");
break;
case ENV_TYPEWRITER:
case ENV_INDENT:
write_break ();
write_line ("\\end{quote}");
break;
default:
abort ();
}
}
void latex_heading1 (void)
{
write_nl ();
}
void latex_heading2 (const uchar *s)
{
if (para_flag)
write_nl ();
switch (tg_level)
{
case 0:
write_string (s);
write_line ("\\break");
break;
case 1:
write_fmt ("\\section{%s}", s);
write_nl ();
break;
case 2:
write_fmt ("\\subsection{%s}", s);
write_nl ();
break;
case 3:
write_fmt ("\\subsubsection{%s}", s);
write_nl ();
break;
default:
fatal ("Sorry, LaTeX supports only 3 levels of headings");
}
write_nl ();
}
void latex_description (void)
{
write_break ();
write_line ("\\begin{description}");
write_nl ();
}
void latex_enumerate (void)
{
write_break ();
write_line ("\\begin{enumerate}");
write_nl ();
}
void latex_itemize (void)
{
write_break ();
write_line ("\\begin{itemize}");
write_nl ();
}
void latex_indent (void)
{
write_break ();
write_line ("\\begin{quote}");
}
void latex_list (void)
{
write_break ();
write_line ("\\begin{description}");
}
void latex_verbatim_start (enum tag tag_end)
{
write_break ();
switch (tag_end)
{
case TAG_ENDHEADERS:
write_nl ();
write_line ("Headers:");
break;
case TAG_ENDSAMPLECODE:
write_nl ();
write_line ("Example:");
break;
case TAG_ENDEXAMPLE:
write_line ("\\begin{quote}");
break;
default:
break;
}
write_break ();
write_line ("\\begin{verbatim}");
}
void latex_verbatim_end (enum tag tag_end)
{
write_line ("\\end{verbatim}");
switch (tag_end)
{
case TAG_ENDEXAMPLE:
write_line ("\\end{quote}");
break;
default:
break;
}
}
void latex_description_item (const uchar *s)
{
write_break ();
write_string ("\\item[");
make_elements (s);
latex_elements (STYLE_NORMAL);
write_line ("]");
}
void latex_enumerate_item (void)
{
write_break ();
write_line ("\\item");
}
void latex_itemize_item (void)
{
write_break ();
write_line ("\\item");
}
void latex_list_item (const uchar *s)
{
write_break ();
write_string ("\\item[");
make_elements (s);
latex_elements (STYLE_NORMAL);
write_line ("]");
}
void latex_copy (void)
{
if (para_flag)
{
write_break ();
write_nl ();
}
switch (env_stack[env_sp].env)
{
case ENV_TYPEWRITER:
latex_elements (STYLE_TTY);
break;
default:
latex_elements (STYLE_NORMAL);
break;
}
}
void latex_start (void)
{
write_line ("\\documentstyle[emxdoc]{article}");
if (title != NULL)
{
write_string ("\\title{");
format_string (title, STYLE_NORMAL, FALSE);
write_line ("}");
write_line ("\\author{}");
}
write_line ("\\begin{document}");
if (title != NULL)
write_line ("\\maketitle");
write_line ("\\tableofcontents");
write_line ("\\newpage");
}
void latex_end (void)
{
write_nl ();
write_line ("\\end{document}");
}