summaryrefslogtreecommitdiff
path: root/web/nuweb/msdos/latex.c
diff options
context:
space:
mode:
Diffstat (limited to 'web/nuweb/msdos/latex.c')
-rw-r--r--web/nuweb/msdos/latex.c361
1 files changed, 361 insertions, 0 deletions
diff --git a/web/nuweb/msdos/latex.c b/web/nuweb/msdos/latex.c
new file mode 100644
index 0000000000..05cdd4de65
--- /dev/null
+++ b/web/nuweb/msdos/latex.c
@@ -0,0 +1,361 @@
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE (!0)
+#endif
+typedef struct scrap_node {
+ struct scrap_node *next;
+ int scrap;
+} Scrap_Node;
+typedef struct name {
+ char *spelling;
+ struct name *llink;
+ struct name *rlink;
+ Scrap_Node *defs;
+ Scrap_Node *uses;
+ int mark;
+ char tab_flag;
+ char indent_flag;
+ char debug_flag;
+} Name;
+
+int tex_flag; /* if FALSE, don't emit the .tex file */
+int output_flag; /* if FALSE, don't emit the output files */
+int compare_flag; /* if FALSE, overwrite without comparison */
+char *command_name;
+char *source_name; /* name of the current file */
+int source_line; /* current line in the source file */
+Name *file_names;
+Name *macro_names;
+Name *user_names;
+
+void pass1();
+void write_tex();
+void write_files();
+void source_open(); /* pass in the name of the source file */
+int source_get(); /* no args; returns the next char or EOF */
+void init_scraps();
+int collect_scrap();
+int write_scraps();
+Name *collect_file_name();
+Name *collect_macro_name();
+Name *collect_scrap_name();
+Name *name_add();
+Name *prefix_add();
+char *save_string();
+void reverse_lists();
+void *arena_getmem();
+void arena_free();
+
+
+static void copy_scrap(); /* formats the body of a scrap */
+static void print_scrap_numbers(); /* formats a list of scrap numbers */
+static void format_entry(); /* formats an index entry */
+static void format_user_entry();
+void write_tex(file_name, tex_name)
+ char *file_name;
+ char *tex_name;
+{
+ FILE *tex_file = fopen(tex_name, "w");
+ if (tex_file) {
+ source_open(file_name);
+ {
+ int scraps = 1;
+ int c = source_get();
+ while (c != EOF) {
+ if (c == '@')
+ {
+ int big_definition = FALSE;
+ c = source_get();
+ switch (c) {
+ case 'O': big_definition = TRUE;
+ case 'o': {
+ Name *name = collect_file_name();
+ {
+ fputs("\\begin{flushleft}\n", tex_file);
+ if (!big_definition)
+ fputs("\\begin{minipage}{\\linewidth}\n", tex_file);
+ }
+ fprintf(tex_file, "\\verb@\"%s\"@", name->spelling);
+ fprintf(tex_file, " {\\footnotesize %d }$\\equiv$\n", scraps++);
+ {
+ fputs("\\vspace{-1.5ex}\n\\begin{quote}\n", tex_file);
+ copy_scrap(tex_file);
+ fputs("$\\Diamond$\n\\end{quote}\n\\vspace{-2ex}\n", tex_file);
+ }
+ {
+ if (name->defs->next) {
+ fputs("{\\footnotesize File defined by scraps ", tex_file);
+ print_scrap_numbers(tex_file, name->defs);
+ fputs("}\n", tex_file);
+ }
+ }
+ {
+ if (!big_definition)
+ fputs("\\end{minipage}\\\\[4ex]\n", tex_file);
+ fputs("\\end{flushleft}\n", tex_file);
+ do
+ c = source_get();
+ while (isspace(c));
+ }
+ }
+ break;
+ case 'D': big_definition = TRUE;
+ case 'd': {
+ Name *name = collect_macro_name();
+ {
+ fputs("\\begin{flushleft}\n", tex_file);
+ if (!big_definition)
+ fputs("\\begin{minipage}{\\linewidth}\n", tex_file);
+ }
+ fprintf(tex_file, "$\\langle$%s", name->spelling);
+ fprintf(tex_file, " {\\footnotesize %d}$\\rangle\\equiv$\n", scraps++);
+ {
+ fputs("\\vspace{-1.5ex}\n\\begin{quote}\n", tex_file);
+ copy_scrap(tex_file);
+ fputs("$\\Diamond$\n\\end{quote}\n\\vspace{-2ex}\n", tex_file);
+ }
+ {
+ fputs("{\\footnotesize ", tex_file);
+ if (name->defs->next) {
+ fputs("Macro defined by scraps ", tex_file);
+ print_scrap_numbers(tex_file, name->defs);
+ fputs("\\\\[-1ex]\n", tex_file);
+ }
+ }
+ {
+ if (name->uses) {
+ if (name->uses->next) {
+ fputs("Macro referenced in scraps ", tex_file);
+ print_scrap_numbers(tex_file, name->uses);
+ fputs("}\n", tex_file);
+ }
+ else
+ fprintf(tex_file, "Macro referenced in scrap %d.}\n", name->uses->scrap);
+ }
+ else {
+ fputs("Macro never referenced.}\n", tex_file);
+ fprintf(stderr, "%s: <%s> never referenced.\n",
+ command_name, name->spelling);
+ }
+ }
+ {
+ if (!big_definition)
+ fputs("\\end{minipage}\\\\[4ex]\n", tex_file);
+ fputs("\\end{flushleft}\n", tex_file);
+ do
+ c = source_get();
+ while (isspace(c));
+ }
+ }
+ break;
+ case 'f': {
+ if (file_names) {
+ fputs("\n\\begin{list}{}{\\setlength{\\itemsep}{-\\parsep}}\n", tex_file);
+ format_entry(file_names, tex_file, TRUE);
+ fputs("\\end{list}", tex_file);
+ }
+ c = source_get();
+ }
+ break;
+ case 'm': {
+ if (macro_names) {
+ fputs("\n\\begin{list}{}{\\setlength{\\itemsep}{-\\parsep}}\n", tex_file);
+ format_entry(macro_names, tex_file, FALSE);
+ fputs("\\end{list}", tex_file);
+ }
+ c = source_get();
+ }
+ break;
+ case 'u': {
+ if (user_names) {
+ fputs("\n\\begin{list}{}{\\setlength{\\itemsep}{-\\parsep}}\n", tex_file);
+ format_user_entry(user_names, tex_file);
+ fputs("\\end{list}", tex_file);
+ }
+ c = source_get();
+ }
+ break;
+ case '@': putc(c, tex_file);
+ default: c = source_get();
+ break;
+ }
+ }
+ else {
+ putc(c, tex_file);
+ c = source_get();
+ }
+ }
+ }
+ fclose(tex_file);
+ }
+ else
+ fprintf(stderr, "%s: can't open %s\n", command_name, tex_name);
+}
+static void print_scrap_numbers(tex_file, scraps)
+ FILE *tex_file;
+ Scrap_Node *scraps;
+{
+ fprintf(tex_file, "%d", scraps->scrap);
+ scraps = scraps->next;
+ while (scraps->next) {
+ fprintf(tex_file, ", %d", scraps->scrap);
+ scraps = scraps->next;
+ }
+ fprintf(tex_file, " and~%d.", scraps->scrap);
+}
+static void copy_scrap(file)
+ FILE *file;
+{
+ int indent = 0;
+ int c = source_get();
+ fputs("\\verb@", file);
+ while (1) {
+ switch (c) {
+ case '@': {
+ c = source_get();
+ switch (c) {
+ case '@': fputs("@{\\tt @}\\verb@", file);
+ break;
+ case '|': {
+ do {
+ do
+ c = source_get();
+ while (c != '@');
+ c = source_get();
+ } while (c != '}');
+ }
+ case '}': putc('@', file);
+ return;
+ case '<': {
+ Name *name = collect_scrap_name();
+ fprintf(file, "@$\\langle$%s {\\footnotesize ", name->spelling);
+ if (name->defs)
+ fprintf(file, "%d", name->defs->scrap);
+ else {
+ putc('?', file);
+ fprintf(stderr, "%s: scrap never defined <%s>\n",
+ command_name, name->spelling);
+ }
+ fputs("}$\\rangle$\\verb@", file);
+ }
+ break;
+ default: /* ignore these since pass1 will have warned about them */
+ break;
+ }
+ }
+ break;
+ case '\n': fputs("@\\\\\n\\verb@", file);
+ indent = 0;
+ break;
+ case '\t': {
+ int delta = 8 - (indent % 8);
+ indent += delta;
+ while (delta > 0) {
+ putc(' ', file);
+ delta--;
+ }
+ }
+ break;
+ default: putc(c, file);
+ indent++;
+ break;
+ }
+ c = source_get();
+ }
+}
+static void format_entry(name, tex_file, file_flag)
+ Name *name;
+ FILE *tex_file;
+ int file_flag;
+{
+ while (name) {
+ format_entry(name->llink, tex_file, file_flag);
+ {
+ fputs("\\item \\hspace{-\\leftmargin}", tex_file);
+ if (file_flag) {
+ fprintf(tex_file, "\\verb@\"%s\"@ ", name->spelling);
+ {
+ Scrap_Node *p = name->defs;
+ fputs("{\\footnotesize Defined by scrap", tex_file);
+ if (p->next) {
+ fputs("s ", tex_file);
+ print_scrap_numbers(tex_file, p);
+ }
+ else
+ fprintf(tex_file, " %d.", p->scrap);
+ putc('}', tex_file);
+ }
+ }
+ else {
+ fprintf(tex_file, "$\\langle$%s {\\footnotesize ", name->spelling);
+ {
+ Scrap_Node *p = name->defs;
+ if (p) {
+ while (1) {
+ fprintf(tex_file, "%d", p->scrap);
+ p = p->next;
+ if (!p) break;
+ fputs(", ", tex_file);
+ }
+ }
+ else
+ putc('?', tex_file);
+ }
+ fputs("}$\\rangle$ ", tex_file);
+ {
+ Scrap_Node *p = name->uses;
+ fputs("{\\footnotesize ", tex_file);
+ if (p) {
+ fputs("Referenced in scrap", tex_file);
+ if (p->next) {
+ fputs("s ", tex_file);
+ print_scrap_numbers(tex_file, p);
+ }
+ else
+ fprintf(tex_file, " %d.", p->scrap);
+ }
+ else
+ fputs("Not referenced.", tex_file);
+ putc('}', tex_file);
+ }
+ }
+ putc('\n', tex_file);
+ }
+ name = name->rlink;
+ }
+}
+static void format_user_entry(name, tex_file)
+ Name *name;
+ FILE *tex_file;
+{
+ while (name) {
+ format_user_entry(name->llink, tex_file);
+ {
+ Scrap_Node *uses = name->uses;
+ Scrap_Node *defs = name->defs;
+ fprintf(tex_file, "\\item \\hspace{-\\leftmargin}\\verb@%s@: ",
+ name->spelling);
+ do {
+ if (uses && (!defs || uses->scrap < defs->scrap)) {
+ fprintf(tex_file, "%d", uses->scrap);
+ uses = uses->next;
+ }
+ else if (defs && (!uses || defs->scrap <= uses->scrap)) {
+ if (uses && defs->scrap == uses->scrap)
+ uses = uses->next;
+ fprintf(tex_file, "\\underline{%d}", defs->scrap);
+ defs = defs->next;
+ }
+ if (uses || defs) fputs(", ", tex_file);
+ } while (uses || defs);
+ fputs(".\n", tex_file);
+ }
+ name = name->rlink;
+ }
+}