/* $Id: latex.c,v 2.0.1.16 2000/02/25 04:15:38 greyham Exp greyham $
* functions for LaTeX style output.
*/
#include "c2man.h"
#include "manpage.h"
#include "output.h"
#include <ctype.h>
static boolean verbatim = FALSE; /* skip quoting in verbatim section */
void latex_char(c)
const int c;
{
int i;
switch (c)
{
case '$':
case '#':
case '&':
case '^':
case '_':
if (!verbatim)
putchar('\\');
putchar(c);
break;
case '>':
case '<':
if (!verbatim)
putchar('$');
putchar(c);
if (!verbatim)
putchar('$');
break;
case '\t':
for (i = 0; i < NUM_TAB_SPACES; i++)
putchar(' ');
break;
case '\\':
if (!verbatim) {
put_string("$\\backslash$");
} else
putchar(c);
break;
default:
putchar(c);
break;
}
}
void latex_text(text)
const char *text;
{
while(*text)
latex_char(*text++);
}
void latex_comment() { put_string("% "); }
void latex_header(firstpage, input_files, grouped, name, terse, section)
ManualPage *firstpage;
int input_files;
boolean grouped;
const char *name;
const char *terse;
const char *section;
{
if (make_embeddable) return;
put_string("\\documentstyle{article}\n");
output_warning();
put_string("\\begin{document}\n");
put_string("\\setlength{\\parindent}{0pt}\n");
}
void latex_dash() { put_string("---"); }
void latex_section(name)
const char *name;
{
put_string("\\section*{");
latex_text(name);
put_string("}\n");
}
void latex_sub_section(name)
const char *name;
{
put_string("\\subsection*{");
latex_text(name);
put_string("}\n");
}
void latex_break_line() { /* put_string("\\\n"); */}
void latex_blank_line() { put_string("\n"); }
void latex_code_start() { put_string("\\begin{verbatim}\n"); verbatim = TRUE; }
void latex_code_end() { put_string("\\end{verbatim}\n"); verbatim = FALSE; }
void latex_code(text)
const char *text;
{
put_string("\\verb`");
put_string(text);
put_string("`");
}
void latex_tag_list_start() { put_string("\\begin{description}\n"); }
void latex_tag_entry_start() { put_string("\\item["); }
void latex_tag_entry_end() { put_string("]\\hfill\\newline\n"); }
void latex_tag_entry_end_extra(text)
const char *text;
{
put_string("(");
latex_text(text);
put_string(")");
latex_tag_entry_end();
}
void latex_tag_list_end() { put_string("\\end{description}\n"); }
void latex_table_start(longestag)
const char *longestag;
{ put_string("\\begin{description}\n"); }
void latex_table_entry(name, description)
const char *name;
const char *description;
{
put_string("\\item[");
latex_text(name);
put_string("]\n");
if (description)
output_comment(description);
else
latex_char('\n');
}
void latex_table_end() { put_string("\\end{description}\n"); }
void latex_list_entry(text)
const char *text;
{
latex_text(text);
}
void latex_list_separator() { put_string(",\n"); }
void latex_list_end() { latex_char('\n'); }
void latex_include(filename)
const char *filename;
{
put_string("\\include{");
latex_text(filename);
put_string("}\n");
}
void latex_file_end() { put_string("\\end{document}\n"); }
void latex_name(name)
const char *name;
{
if (name) latex_text(name);
else latex_section("NAME");
}
void latex_terse_sep()
{
latex_char(' ');
latex_dash();
latex_char(' ');
}
void latex_reference(text)
const char *text;
{
latex_text(text);
latex_char('(');
latex_text(manual_section);
latex_char(')');
}
/* ideally, this should be made aware of embedded latex commands */
void latex_description(text)
const char *text;
{
enum { TEXT, PERIOD, CAPITALISE } state = CAPITALISE;
boolean new_line = TRUE;
/* correct punctuation a bit as it goes out */
for (;*text;text++) {
int c = *text;
if (new_line && verbatim && c != '\t') {
latex_code_end(); /* \end{verbatim}; verbatim=FALSE; */
}
if (new_line && c == '\t') {
if (!verbatim) {
latex_code_start(); /* \begin{verbatim}; verbatim=TRUE; */
}
} else if (new_line && (c == '-' || c == '*')) {
/* latex output-> break_line() does nothing
* output->break_line();
*/
put_string("\\\\\n");
state = CAPITALISE;
}
else if (c == '.')
state = PERIOD;
else if (isspace(c) && state == PERIOD)
state = CAPITALISE;
else if (isalnum(c) || ispunct(c)) {
if (islower(c) && state == CAPITALISE && !verbatim) c = toupper(c);
state = TEXT;
}
output->character(c);
new_line = c == '\n';
}
if ( verbatim ) { /* end verbatim section at end of comments */
latex_code_end();
} else /* no extra point after verbatim section */
/* do a full stop if there wasn't one */
if (state == TEXT) output->character('.');
}
/* ideally, this should be made aware of embedded latex commands */
void
latex_returns(comment)
const char *comment;
{
enum { TEXT, PERIOD, CAPITALISE } state = CAPITALISE;
char lastchar = '\n';
boolean tag_list_started = FALSE;
/* for each line... */
while (*comment)
{
boolean tagged = FALSE;
{
const char *c = comment;
/* search along until the end of a word */
while (*c && *c != ':' && !isspace(*c))
c++;
/* skip all spaces or tabs after the first word */
while (*c && *c != '\n')
{
if (*c == '\t' || *c == ':')
{
tagged = TRUE;
break;
}
else if (!isspace(*c))
break;
c++;
}
}
/* is it tagged?; explicitly reject dot commands */
if (tagged)
{
/* output lingering newline if necessary */
if (lastchar != '\n')
{
if (state == TEXT && !ispunct(lastchar)) output->character('.');
output->character(lastchar = '\n');
}
if (!tag_list_started)
{
output->tag_list_start();
tag_list_started = TRUE;
}
/* output the taggy bit */
output->tag_entry_start();
while (*comment && *comment != ':' && !isspace(*comment))
output->character(*comment++);
output->tag_entry_end();
/* skip any extra tabs or spaces */
while (*comment == ':' || (isspace(*comment) && *comment != '\n'))
comment++;
state = CAPITALISE;
}
/* terminate the previous line if necessary */
if (lastchar != '\n') output->character(lastchar = '\n');
/* correct punctuation a bit as the line goes out */
for (;*comment && *comment != '\n'; comment++)
{
char c = *comment;
if (c == '.')
state = PERIOD;
else if (isspace(c) && state == PERIOD)
state = CAPITALISE;
else if (isalnum(c))
{
if (islower(c) && state == CAPITALISE && fixup_comments)
c = toupper(c);
state = TEXT;
}
output->character(lastchar = c);
}
/* if it ended in punctuation, just output the nl straight away. */
if (ispunct(lastchar))
{
if (lastchar == '.') state = CAPITALISE;
output->character(lastchar = '\n');
}
if (*comment) comment++;
}
/* output lingering newline if necessary */
if (lastchar != '\n')
{
if (state == TEXT && !ispunct(lastchar) && fixup_comments)
output->character('.');
output->character('\n');
}
if (tag_list_started)
output->tag_list_end();
}
struct Output latex_output =
{
latex_comment,
latex_header,
latex_dash,
latex_section,
latex_sub_section,
latex_break_line,
latex_blank_line,
latex_code_start,
latex_code_end,
latex_code,
latex_tag_list_start,
latex_tag_list_end,
latex_tag_entry_start,
latex_tag_entry_start, /* entry_start_extra */
latex_tag_entry_end,
latex_tag_entry_end_extra,
latex_table_start,
latex_table_entry,
latex_table_end,
dummy, /* latex_indent */
dummy, /* latex_list_start */
latex_list_entry,
latex_list_separator,
latex_list_end,
latex_include,
latex_file_end,
latex_text,
latex_char,
NULL, /* latex_parse_option */
dummy, /* latex_print_option */
latex_name,
latex_terse_sep,
latex_reference,
latex_text,
latex_description,
latex_returns
};
syntax highlighted by Code2HTML, v. 0.9.1