11 #include "generator.h"
15 /****f* ROBODoc/RB_Generate_Documentation [3.0h]
17 * RB_Generate_Documentation
19 * RB_Generate_Documentation (dest_doc, name, name)
21 * RB_Generate_Documentation (FILE *, char *, char *)
23 * Generates the autodoc documentation from the list of
24 * function headers that has been created by
25 * RB_Analyse_Document.
27 * dest_doc - Pointer to the file to which the output will be written.
28 * src_name - The name of the source file.
29 * dest_name - The name of this file.
31 * There might be plenty.
33 * RB_Generate_Doc_Start,
34 * RB_Generate_Doc_End,
35 * RB_Generate_Header_Start,
36 * RB_Generate_Header_End,
37 * RB_Generate_Header_Name,
38 * RB_Generate_Item_Name,
39 * RB_Generate_Item_Doc,
40 * RB_Generate_Item_Body .
45 RB_Generate_Documentation (
46 FILE * dest_doc, char *src_name, char *dest_name)
48 struct RB_header *cur_header;
50 FILE *orig_doc = dest_doc;
52 RB_Make_Index_Tables ();
54 RB_Generate_Doc_Start (dest_doc, src_name, dest_name, 1);
56 for (cur_header = first_header;
58 cur_header = cur_header->next_header)
61 char *next_line, *item_line = NULL;
63 RB_Say ("generating documentation for \"%s\"\n", cur_header->name);
65 if (output_mode == HTML)
67 sprintf(fname, "%s-%s.html", doc_base, cur_header->function_name);
68 dest_doc = fopen(fname, "w");
71 fprintf(stderr, "%s\n", strerror(errno));
76 RB_Generate_Header_Start (dest_doc, cur_header, src_name);
78 next_line = cur_header->contents;
79 item_type = RB_Find_Item (&next_line, &item_line);
81 if (item_type != NO_ITEM)
88 if (course_of_action & DO_TELL)
89 printf ("[%s] ", item_names[item_type]);
91 if (!((item_type == SOURCE_ITEM) &&
92 (course_of_action & DO_NOSOURCE)))
93 RB_Generate_Item_Name (dest_doc, item_type);
95 old_next_line = next_line;
96 old_item_type = item_type;
98 item_type = RB_Find_Item (&next_line, &item_line);
100 if (!((old_item_type == SOURCE_ITEM) &&
101 (course_of_action & DO_NOSOURCE)))
102 RB_Generate_Item_Doc (dest_doc, dest_name,
103 old_next_line, item_line,
104 cur_header->function_name,
107 while (item_type != NO_ITEM);
108 if (course_of_action & DO_TELL)
112 printf ("%s: WARNING, header \"%s\" has no items\n",
113 whoami, cur_header->name);
115 RB_Generate_Header_End (dest_doc, cur_header);
117 if (output_mode == HTML)
122 RB_Generate_Doc_End (dest_doc, dest_name);
125 /***** RB_Generate_Documentation ***/
131 /****f* ROBODoc/RB_Generate_Doc_Start [3.0j]
133 * RB_Generate_Doc_Start -- Generate document header.
135 * RB_Generate_Doc_Start (dest_doc, src_name, name, toc)
137 * RB_Generate_Doc_Start (FILE *, char *, char *, char)
139 * Generates for depending on the output_mode the text that
140 * will be at the start of a document.
141 * Including the table of contents.
143 * dest_doc - pointer to the file to which the output will
145 * src_name - the name of the source file.
146 * name - the name of this file.
147 * output_mode - global variable that indicates the output
149 * toc - generate table of contens
151 * RB_Generate_Doc_End
156 RB_Generate_Doc_Start (
157 FILE * dest_doc, char *src_name, char *name, char toc)
159 struct RB_header *cur_header;
160 int cur_len, max_len, header_nr;
165 if (strstr (name + 1, ".guide") == NULL)
166 fprintf (dest_doc, "@database %s.guide\n", name);
168 fprintf (dest_doc, "@database %s\n", name);
169 fprintf (dest_doc, "@rem Source: %s\n", src_name);
170 fprintf (dest_doc, "@rem " COMMENT_ROBODOC);
171 fprintf (dest_doc, "@rem " COMMENT_COPYRIGHT);
172 fprintf (dest_doc, "@node Main %s\n", name);
173 fprintf (dest_doc, "@{jcenter}\n");
175 "@{fg highlight}@{b}TABLE OF CONTENTS@{ub}@{fg text}\n\n");
178 for (cur_header = first_header;
180 cur_header = cur_header->next_header)
182 if (cur_header->name)
184 cur_len = strlen (cur_header->name);
185 if (cur_len > max_len)
190 for (cur_header = first_header;
192 cur_header = cur_header->next_header)
194 if (cur_header->name && cur_header->function_name)
196 fprintf (dest_doc, "@{\"%s", cur_header->name);
198 for (cur_len = strlen (cur_header->name);
201 fputc (' ', dest_doc);
202 fprintf (dest_doc, "\" Link \"%s\"}\n", cur_header->function_name);
206 fprintf (dest_doc, "@{jleft}\n");
207 fprintf (dest_doc, "@endnode\n");
211 /* Append document type and title */
213 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
214 fprintf (dest_doc, "<HTML><HEAD>\n<TITLE>%s</TITLE>\n", name);
216 /* append SGML-comment with document- and copyright-info. This code
217 * ensures that every line has an own comment to avoid problems with
219 fprintf (dest_doc, "<!-- Source: %s -->\n", src_name);
221 static const char copyright_text[]
222 = COMMENT_ROBODOC COMMENT_COPYRIGHT;
224 char previous_char = '\n';
225 char current_char = copyright_text[i];
229 if (previous_char == '\n')
231 fprintf (dest_doc, "<!-- ");
233 if (current_char == '\n')
235 fprintf (dest_doc, " -->");
237 else if ((current_char == '-') && (previous_char == '-'))
239 /* avoid "--" inside SGML-comment, and use "-_" instead; this
240 * looks a bit strange, but one should still be able to figure
241 * out what is meant when reading the output */
244 fputc (current_char, dest_doc);
246 previous_char = current_char;
247 current_char = copyright_text[i];
251 /* append heading and start list of links to functions */
252 fprintf (dest_doc, "</HEAD><BODY BGCOLOR=\"#FFFFFF\">\n");
254 fprintf (dest_doc, "<A NAME=\"%s\">Generated from %s</A> with ROBODoc v"
258 RB_TimeStamp (dest_doc);
260 fprintf (dest_doc, "<BR>\n");
267 /* do toc if not in fold */
270 "<H3 ALIGN=\"center\">TABLE OF CONTENTS</H3>\n");
271 fprintf (dest_doc, "<OL>\n");
274 /* Generate quick index file, for fast referencing */
275 sprintf(iname, "%s-index.tmpl", doc_base);
276 index = fopen(iname, "w");
279 fprintf(stderr, "%s\n", strerror(errno));
283 for (cur_header = first_header;
285 cur_header = cur_header->next_header)
289 sprintf(fname, "%s-%s.html", RB_FilePart(doc_base),
290 cur_header->function_name);
292 if (cur_header->name && cur_header->function_name)
297 char *next_line, *item_line = NULL;
299 RB_Generate_Header_Start (dest_doc, cur_header,
302 next_line = cur_header->contents;
303 item_type = RB_Find_Item (&next_line, &item_line);
305 if (item_type != NO_ITEM)
312 if (course_of_action & DO_TELL)
313 printf ("[%s] ", item_names[item_type]);
315 if (!((item_type == SOURCE_ITEM) &&
316 (course_of_action & DO_NOSOURCE)))
317 RB_Generate_Item_Name (dest_doc, item_type);
319 old_next_line = next_line;
320 old_item_type = item_type;
322 item_type = RB_Find_Item (&next_line,
325 if (!((old_item_type == SOURCE_ITEM) &&
326 (course_of_action & DO_NOSOURCE)))
327 RB_Generate_Item_Doc(dest_doc, name,
328 old_next_line, item_line,
329 cur_header->function_name,
332 while (item_type != NO_ITEM);
333 if (course_of_action & DO_TELL)
339 fprintf (index, "<A HREF=\"%s\"><IMG SRC=\"index_pic.gif\" BORDER=\"0\" ALT=\"\">%s</A><BR>\n",
340 name, cur_header->function_name);
347 fprintf (dest_doc, "<LI><A HREF=\"%s\">%s</A>\n",
348 fname, cur_header->function_name);
350 fprintf (index, "<A HREF=\"%s\"><IMG SRC=\"index_pic.gif\" BORDER=\"0\" ALT=\"\">%s</A><BR>\n",
351 fname, cur_header->function_name);
357 fprintf (dest_doc, "</OL>\n");
366 fprintf (dest_doc, "%% Document: %s\n", name);
367 fprintf (dest_doc, "%% Source: %s\n", src_name);
368 fprintf (dest_doc, "%% " COMMENT_ROBODOC);
369 fprintf (dest_doc, "%% " COMMENT_COPYRIGHT);
370 if (course_of_action & DO_SINGLEDOC) {
371 fprintf (dest_doc, "\\section{%s}\n", src_name);
373 fprintf (dest_doc, "\\documentclass{article}\n");
374 fprintf (dest_doc, "\\usepackage{makeidx}\n");
375 fprintf (dest_doc, "\\oddsidemargin 0.15 in\n");
376 fprintf (dest_doc, "\\evensidemargin 0.35 in\n");
377 fprintf (dest_doc, "\\marginparwidth 1 in \n");
378 fprintf (dest_doc, "\\oddsidemargin 0.25 in \n");
379 fprintf (dest_doc, "\\evensidemargin 0.25 in\n");
380 fprintf (dest_doc, "\\marginparwidth 0.75 in\n");
381 fprintf (dest_doc, "\\textwidth 5.875 in\n");
383 fprintf (dest_doc, "\\setlength{\\parindent}{0in}\n");
384 fprintf (dest_doc, "\\setlength{\\parskip}{.08in}\n\n");
386 /* changed default header to use boldface (vs slant) */
387 fprintf (dest_doc, "\\pagestyle{headings}\n");
389 if (document_title) {
390 fprintf (dest_doc, "\\title{%s}\n",
393 fprintf (dest_doc, "\\title{API Reference}\n");
395 fprintf (dest_doc, "\\author{%s}\n", COMMENT_ROBODOC);
396 fprintf (dest_doc, "\\makeindex\n");
397 fprintf (dest_doc, "\\begin{document}\n");
398 fprintf (dest_doc, "\\maketitle\n");
399 /* autogenerate table of contents! */
400 fprintf (dest_doc, "\\printindex\n");
401 fprintf (dest_doc, "\\tableofcontents\n");
402 fprintf (dest_doc, "\\newpage\n");
403 /* trick to disable the autogenerated \newpage */
404 fprintf (dest_doc, "\n");
413 fprintf (dest_doc, "{\\rtf1\\ansi \\deff0"
415 "\\f0\\fswiss MS Sans Serif;"
416 "\\f1\\fmodern Courier New;"
417 "\\f2\\ftech Symbol;"
420 "\\red255\\green255\\blue255;"
421 "\\red0\\green0\\blue0;"
422 "\\red0\\green0\\blue255;"
425 /* RTF document info */
426 fprintf (dest_doc, "{\\info"
431 " " COMMENT_COPYRIGHT
433 "}", name, src_name);
435 /* RTF document format */
436 fprintf (dest_doc, "{\\margl1440\\margr1440}\n");
438 /* RTF document section */
439 fprintf (dest_doc, "\\f0\\cb1\\cf3\\fs28\\b1\\qc"
440 "{\\super #{\\footnote{\\super #}%s_TOC}}"
441 "{\\super ${\\footnote{\\super $}Contents}}"
442 "{TABLE OF CONTENTS}\\ql\\b0\\fs20\\cf2\\par\n", src_name);
443 for (cur_header = first_header;
445 cur_header = cur_header->next_header)
447 if (cur_header->name && cur_header->function_name)
449 cook_link = RB_CookStr (cur_header->function_name);
450 fprintf (dest_doc, "{\\uldb %s}{\\v %s}\\line\n",
451 cur_header->name, cook_link);
455 fprintf (dest_doc, "\\par\n");
459 if (course_of_action & DO_TOC)
461 fprintf (dest_doc, "TABLE OF CONTENTS\n");
462 for (cur_header = first_header, header_nr = 1;
464 cur_header = cur_header->next_header, header_nr++)
466 if (cur_header->name && cur_header->function_name)
468 fprintf (dest_doc, "%4.4d %s\n",
469 header_nr, cur_header->name);
472 fputc ('\f', dest_doc);
482 /****f* ROBODoc/RB_Generate_Doc_End [3.0h]
484 * RB_Generate_Doc_End -- generate document trailer.
486 * RB_Generate_Doc_End (dest_doc, name)
488 * RB_Generate_Doc_End (FILE *, char *)
490 * Generates for depending on the output_mode the text that
491 * will be at the end of a document.
493 * dest_doc - pointer to the file to which the output will
495 * name - the name of this file.
496 * output_mode - global variable that indicates the output
499 * Doesn't do anything with its arguments, but that might
500 * change in the future.
506 RB_Generate_Doc_End (FILE * dest_doc, char *name)
511 fputc ('\n', dest_doc);
514 fprintf (dest_doc, "</BODY></HTML>\n");
517 if (!(course_of_action & DO_SINGLEDOC)) {
518 fprintf (dest_doc, "\\end{document}\n");
522 fputc ('}', dest_doc);
532 /****f* ROBODoc/RB_Generate_Header_Start [3.0h]
534 * RB_Generate_Header_Start -- generate header start text.
536 * void RB_Generate_Header_Start (dest_doc, cur_header)
538 * void RB_Generate_Header_Start (FILE *, struct RB_header *)
540 * Generates depending on the output_mode the text that
541 * will be at the end of each header.
543 * dest_doc - pointer to the file to which the output will
545 * cur_header - pointer to a RB_header structure.
547 * RB_Generate_Header_End
552 RB_Generate_Header_Start (FILE * dest_doc, struct RB_header *cur_header,
553 const char *src_name)
558 { /* switch by *koessi */
560 if (cur_header->name && cur_header->function_name)
562 fprintf (dest_doc, "@Node \"%s\" \"%s\"\n",
563 cur_header->function_name,
565 fprintf (dest_doc, "%s", att_start_command[MAKE_SHINE][output_mode]);
566 fprintf (dest_doc, "%s", cur_header->name);
567 fprintf (dest_doc, "%s", att_stop_command[MAKE_SHINE][output_mode]);
568 fprintf (dest_doc, "\n\n");
572 if (cur_header->name && cur_header->function_name)
575 fprintf (dest_doc, "<HR>\n");
577 if (cur_header->type == FUNCTION_HEADER)
579 "\n<FONT SIZE=\"+2\" COLOR=\"#000055\"><B>"
580 "Function <A NAME=\"%s\">%s</A>"
581 "</FONT></B><BR><BR>\n\n",
582 cur_header->function_name,
583 cur_header->function_name);
584 else if (cur_header->type == STRUCT_HEADER)
586 "\n<FONT SIZE=\"+2\" COLOR=\"#000055\"><B>"
587 "Structure <A NAME=\"%s\">%s</A>"
588 "</FONT></B><BR><BR>\n\n",
589 cur_header->function_name,
590 cur_header->function_name);
591 else if (cur_header->type == VARIABLE_HEADER)
593 "\n<FONT SIZE=\"+2\" COLOR=\"#000055\"><B>"
594 "Variable <A NAME=\"%s\">%s</A>"
595 "</FONT></B><BR><BR>\n\n",
596 cur_header->function_name,
597 cur_header->function_name);
598 else if (cur_header->type == MAIN_HEADER)
600 "\n<FONT SIZE=\"+2\" COLOR=\"#000055\"><B>"
601 "<A NAME=\"%s\">%s</A>"
602 "</FONT></B><BR><SMALL>Header: %s</SMALL><BR><BR>\n\n",
603 cur_header->function_name,
604 cur_header->function_name, src_name);
607 "\n<FONT SIZE=\"+2\" COLOR=\"#000055\"><B>"
608 "<A NAME=\"%s\">%s</A>"
609 "</FONT></B><BR><BR>\n\n",
610 cur_header->function_name,
611 cur_header->function_name);
615 cook_link = RB_CookStr (cur_header->name);
616 if (!(course_of_action & DO_SINGLEDOC)) {
617 fprintf (dest_doc, "\\newpage\n");
619 fprintf (dest_doc, "\\subsection{%s}\n", cook_link);
621 if (cur_header->function_name) {
622 cook_link = RB_CookStr (cur_header->function_name);
623 fprintf (dest_doc, "\\index{unsorted!%s}\\index{%s!%s}\n", cook_link,
624 RB_header_type_names[cur_header->type], cook_link);
629 if (cur_header->name && cur_header->function_name)
631 cook_link = RB_CookStr (cur_header->function_name);
632 fprintf (dest_doc, "\\page"
633 "{\\super #{\\footnote{\\super #}%s}}"
634 "{\\super ${\\footnote{\\super $}%s}}"
635 "\\cf3 %s\\cf2\\line\n",
636 cur_header->function_name,
644 fprintf (dest_doc, "%s", att_start_command[MAKE_SHINE][output_mode]);
645 fprintf (dest_doc, "%s", cur_header->name);
646 fprintf (dest_doc, "%s", att_stop_command[MAKE_SHINE][output_mode]);
647 fprintf (dest_doc, "\n\n");
656 /****f* ROBODoc/RB_Generate_Header_End [3.0h]
658 * RB_Generate_Header_End
660 * void RB_Generate_Header_End (dest_doc, cur_header)
662 * void RB_Generate_Header_End (FILE *, struct RB_header *)
664 * Generates for depending on the output_mode the text that
665 * will be at the end of a header.
667 * dest_doc - pointer to the file to which the output will
669 * cur_header - pointer to a RB_header structure.
671 * RB_Generate_Header_Start
676 RB_Generate_Header_End (FILE * dest_doc, struct RB_header *cur_header)
679 { /* switch by *koessi */
681 if (cur_header->name && cur_header->function_name)
682 fprintf (dest_doc, "@endnode\n");
686 fputc ('\n', dest_doc);
689 fprintf (dest_doc, "\\par\n");
692 fputc ('\f', dest_doc);
701 /****f* ROBODoc/RB_Generate_Header_Name [3.0c]
703 * RB_Generate_Header_Name
705 * RB_Generate_Header_Name (dest_doc, name)
707 * RB_Generate_Header_Name (FILE *, char *)
709 * dest_doc - pointer to the file to which the output will
711 * name - pointer to the header name.
716 RB_Generate_Header_Name (FILE * dest_doc, char *name)
718 char format_str[] = "%s";
720 fprintf (dest_doc, format_str, att_start_command[MAKE_SHINE][output_mode]);
721 fprintf (dest_doc, format_str, name);
722 fprintf (dest_doc, format_str, att_stop_command[MAKE_SHINE][output_mode]);
723 fprintf (dest_doc, "\n\n");
726 /*** RB_Generate_Header_Name ***/
729 /****** ROBODoc/RB_Generate_Item_Name [2.01]
731 * RB_Generate_Item_Name -- fast&easy
733 * void RB_Generate_Item_Name( FILE * dest_doc, int item_type )
735 * write the items name to the doc
737 * FILE * dest_doc -- document in progress
738 * int item_type -- this leads to the name and makes colors
742 * uses globals: output_mode, item_names[]
747 RB_Generate_Item_Name (FILE * dest_doc, int item_type)
749 char format_str[] = "%s";
751 if (item_attributes[item_type] & ITEM_NAME_LARGE_FONT)
753 fprintf (dest_doc, format_str,
754 att_start_command[MAKE_LARGE][output_mode]);
755 fprintf (dest_doc, format_str,
756 att_start_command[MAKE_BOLD][output_mode]);
757 if (output_mode == HTML)
758 fprintf (dest_doc, "\n<FONT COLOR=\"#000055\">");
759 fprintf (dest_doc, format_str, item_names[item_type]);
760 if (output_mode == HTML)
761 fprintf (dest_doc, "\n</FONT>");
762 fprintf (dest_doc, format_str,
763 att_stop_command[MAKE_BOLD][output_mode]);
764 fprintf (dest_doc, format_str,
765 att_stop_command[MAKE_LARGE][output_mode]);
768 fprintf (dest_doc, format_str, item_names[item_type]);
770 fputc ('\n', dest_doc);
777 /****f* ROBODoc/RB_Generate_Item_Doc [3.0j]
779 * RB_Generate_Item_Doc
781 * void RB_Generate_Item_Doc(FILE * dest_doc, char *dest_name,
782 * char *begin_of_item,
784 * char *function_name,
787 * Generates the body text of an item, applying predefined attributes
790 * Body text is always non-proportional for several reasons:
791 * 1) text is rarely written with prop spacing and text wrapping
792 * in mind -- e.g., see SYNOPSIS above
793 * 2) source code looks better
794 * 3) it simplifies LaTeX handling
799 RB_Generate_Item_Doc (FILE * dest_doc, char *dest_name,
805 char format_str[] = "%s";
807 if (begin_of_item == end_of_item)
812 fprintf (dest_doc, "<BR>\n");
815 fprintf (dest_doc, "\\\\\n");
818 fprintf (dest_doc, "\n");
825 /* For text body in HTML, change to non-prop _before_ changing font
826 * style. * To conform to DTD, this avoids <B><PRE> and instead uses
828 if (output_mode == HTML)
830 fprintf (dest_doc, "<PRE>");
832 /* change font style */
833 if (item_attributes[item_type] & TEXT_BODY_LARGE_FONT)
834 fprintf (dest_doc, format_str,
835 att_start_command[MAKE_LARGE][output_mode]);
836 if (item_attributes[item_type] & TEXT_BODY_ITALICS)
837 fprintf (dest_doc, format_str,
838 att_start_command[MAKE_ITALICS][output_mode]);
839 if (item_attributes[item_type] & TEXT_BODY_NON_PROP)
840 fprintf (dest_doc, format_str,
841 att_start_command[MAKE_NON_PROP][output_mode]);
842 if (item_attributes[item_type] & TEXT_BODY_SMALL_FONT)
843 fprintf (dest_doc, format_str,
844 att_start_command[MAKE_SMALL][output_mode]);
845 if (item_attributes[item_type] & TEXT_BODY_BOLD)
846 fprintf (dest_doc, format_str,
847 att_start_command[MAKE_BOLD][output_mode]);
848 if (item_attributes[item_type] & TEXT_BODY_UNDERLINE)
849 fprintf (dest_doc, format_str,
850 att_start_command[MAKE_UNDERLINE][output_mode]);
851 if (item_attributes[item_type] & TEXT_BODY_SHINE)
852 fprintf (dest_doc, format_str,
853 att_start_command[MAKE_SHINE][output_mode]);
854 if (item_attributes[item_type] & TEXT_BODY_DEFAULT)
855 fprintf (dest_doc, format_str,
856 att_start_command[MAKE_DEFAULT][output_mode]);
859 * For some modes, the text body is always non-prop
864 fprintf (dest_doc, "\\begin{verbatim}\n");
867 fprintf (dest_doc, "{\\f1{}");
873 RB_Generate_Item_Body (dest_doc, dest_name, begin_of_item, end_of_item,
874 function_name, item_type, 0);
879 /* split the text so LaTeX doesn't get confused ;) */
880 fprintf (dest_doc, "\\" "end{verbatim}\n");
883 fputc ('}', dest_doc);
888 /* restore font style */
889 if (item_attributes[item_type] & TEXT_BODY_SHINE)
890 fprintf (dest_doc, format_str,
891 att_stop_command[MAKE_SHINE][output_mode]);
892 if (item_attributes[item_type] & TEXT_BODY_UNDERLINE)
893 fprintf (dest_doc, format_str,
894 att_stop_command[MAKE_UNDERLINE][output_mode]);
895 if (item_attributes[item_type] & TEXT_BODY_BOLD)
896 fprintf (dest_doc, format_str,
897 att_stop_command[MAKE_BOLD][output_mode]);
898 if (item_attributes[item_type] & TEXT_BODY_SMALL_FONT)
899 fprintf (dest_doc, format_str,
900 att_stop_command[MAKE_SMALL][output_mode]);
901 if (item_attributes[item_type] & TEXT_BODY_NON_PROP)
902 fprintf (dest_doc, format_str,
903 att_stop_command[MAKE_NON_PROP][output_mode]);
904 if (item_attributes[item_type] & TEXT_BODY_ITALICS)
905 fprintf (dest_doc, format_str,
906 att_stop_command[MAKE_ITALICS][output_mode]);
907 if (item_attributes[item_type] & TEXT_BODY_LARGE_FONT)
908 fprintf (dest_doc, format_str,
909 att_stop_command[MAKE_LARGE][output_mode]);
910 if (item_attributes[item_type] & TEXT_BODY_DEFAULT)
911 fprintf (dest_doc, format_str,
912 att_stop_command[MAKE_DEFAULT][output_mode]);
914 if (output_mode != HTML)
916 fputc ('\n', dest_doc);
918 /* for HTML, switch back to prop-font after restoring font style */
919 if (output_mode == HTML)
921 fprintf (dest_doc, "</PRE>");
929 /****f* ROBODoc/RB_Generate_Item_Body [3.0h]
931 * RB_Generate_Item_Body
933 * char * RB_Generate_Item_Body(FILE * dest_doc, char *dest_name,
934 * char *begin_of_item, char *end_of_item,
935 * char *function_name,
936 * int item_type, int tabs_to_skip)
939 * Generates body of an item in output-specific form
941 * dest_doc - pointer to the file to which
942 * the output will be written.
943 * dest_name - the name of this file.
948 * tabs_to_skip - how many tabs to skip in this fold.
950 * o Unbalanced fold marks lead to crash.
952 * o Almost completely rewritten by koessi
953 * o Almost completely Re-Rewritten by Slothouber :)
954 * o Folding mode by PetteriK.
955 * o Linking fixed inside folds / PetteriK 08.04.2000
960 RB_Generate_Item_Body (FILE * dest_doc, char *dest_name,
961 char *begin_of_item, char *end_of_item,
963 int item_type, int tabs_to_skip)
965 char *cur_char, old_char, c;
967 char fname[128], foldname[128];
968 static int in_fold = 0; /* PetteriK 08.04.2000 */
970 cur_char = begin_of_item;
972 if (item_type == SOURCE_ITEM)
974 /* skip end_comment_marker */
975 for (; *cur_char && *cur_char != '\n'; cur_char++);
977 /* skip blank lines leading up to source code */
978 while (*cur_char == '\n')
981 /* trim blanks following source code */
986 while (end_of_item > cur_char && isspace (*end_of_item));
987 end_of_item++; /* advance 1 for placement of the NUL */
989 old_char = *end_of_item;
992 for (; *cur_char; cur_char++)
995 int do_search = TRUE;
996 int was_link = FALSE;
999 if (item_type != SOURCE_ITEM)
1001 /* Skip empty lines */
1002 while (*cur_char == '\n') {
1005 cur_char = RB_Skip_Remark_Marker (cur_char);
1010 switch (output_mode)
1013 fprintf (dest_doc, "\\tab ");
1020 fprintf (dest_doc, " ");
1024 while (((c = *cur_char) != '\0') && (c != '\n'))
1026 char *label_name, *file_name;
1032 if (!isalnum (c) && (c != '_'))
1039 if (isalpha (c) || (c == '_'))
1041 if (((was_link = RB_Find_Link (cur_char, &label_name,
1042 &file_name)) == FALSE))
1053 switch (output_mode)
1062 for (tb %= tab_size; tb < tab_size; ++tb)
1063 fputc (' ', dest_doc);
1066 fprintf (dest_doc, "\\@");
1070 fprintf (dest_doc, "\\\\");
1074 fputc (c, dest_doc);
1080 /* PetteriK 26.07.1999 */
1081 if (extra_flags & FOLD)
1083 cur_char = RB_Check_Fold_Start (cur_char,
1086 if ((extra_flags & FOLD) && found)
1090 RB_Say ("fold name %s\n", foldname);
1091 RB_Say ("fold begin %d\n", ++fold);
1092 RB_Say ("tabs %d\n", tabs);
1093 sprintf (fname, "%s_fold_%d.html", doc_base, fold);
1094 RB_Say ("opening file %s\n", fname);
1095 fp = fopen (fname, "w");
1096 RB_Generate_Doc_Start (fp, foldname, foldname, 0);
1097 fprintf (fp, "<PRE>\n");
1098 fprintf (dest_doc, "<A HREF=\"%s\">... %s</A>",
1100 in_fold++; /* PetteriK 08.04.2000 */
1101 cur_char = RB_Generate_Item_Body (fp, dest_name,
1102 cur_char, end_of_item,
1105 in_fold--; /* PetteriK 08.04.2000 */
1106 /* skip chars until newline */
1107 while (*cur_char != '\n')
1112 fprintf (fp, "\n</PRE>\n");
1113 RB_Generate_Doc_End (fp, foldname);
1116 else if ((extra_flags & FOLD) && RB_Check_Fold_End (cur_char))
1118 RB_Say ("fold end found\n");
1121 else if ((html_incr = RB_HTML_Extra (dest_doc,
1122 item_type, cur_char)))
1124 cur_char += html_incr;
1134 if (extra_flags & FOLD)
1136 if (tabs >= tabs_to_skip)
1138 for (tb %= tab_size; tb < tab_size; ++tb)
1140 fputc (' ', dest_doc);
1147 for (tb %= tab_size; tb < tab_size; ++tb)
1149 fputc (' ', dest_doc);
1154 fprintf (dest_doc, "<");
1158 fprintf (dest_doc, ">");
1162 fprintf (dest_doc, "&");
1166 fputc (c, dest_doc);
1170 break; /* end case HTML */
1179 for (tb %= tab_size; tb < tab_size; ++tb)
1180 fputc (' ', dest_doc);
1183 /* not used in LaTeX's verbatim environment */
1191 fputc ('\\', dest_doc);
1192 fputc (c, dest_doc);
1196 fprintf (dest_doc, "$\\backslash$");
1200 fprintf (dest_doc, "$\\tilde$");
1204 fprintf (dest_doc, "$\\,\\!^{\\sim}$");
1209 fputc (c, dest_doc);
1221 for (tb %= tab_size; tb < tab_size; ++tb)
1222 fputc (' ', dest_doc);
1227 fputc ('\\', dest_doc);
1228 fputc (c, dest_doc);
1232 fputc (c, dest_doc);
1238 fputc (c, dest_doc);
1245 switch (output_mode)
1248 if (file_name && strcmp (file_name, dest_name))
1249 fprintf (dest_doc, "@{\"%s\" Link \"%s/%s\"}",
1250 label_name, file_name, label_name);
1253 if (strcmp (label_name, function_name))
1254 fprintf (dest_doc, "@{\"%s\" Link \"%s\"}",
1255 label_name, label_name);
1258 fprintf (dest_doc, "%s",
1259 att_start_command[MAKE_BOLD][output_mode]);
1260 fprintf (dest_doc, "%s", label_name);
1261 fprintf (dest_doc, "%s",
1262 att_stop_command[MAKE_BOLD][output_mode]);
1268 /* Include the file name in the link if we are in fold
1269 * PetteriK 08.04.2000
1273 /* We are in fold, always use the file name in the link,
1274 * in file_name == NULL (i.e. the label is in the current file
1275 * that we are processing), refer to value in dest_name.
1276 * This also makes sure that we link correctly if function_name
1277 * is the same as label_name.
1279 fprintf (dest_doc, "<A HREF=\"%s#%s\">%s</A>",
1280 (file_name ? file_name : dest_name),
1281 label_name, label_name);
1283 else if (file_name && strcmp (file_name, dest_name))
1285 fprintf (dest_doc, "<A HREF=\"%s#%s\">%s</A>",
1286 file_name, label_name, label_name);
1290 if (strcmp (label_name, function_name))
1293 fprintf (dest_doc, "<A HREF=\"#%s\">%s</A>",
1294 label_name, label_name);
1296 fprintf (dest_doc, "<A HREF=\"%s-%s.html\">%s</A>",
1297 RB_FilePart(doc_base), label_name,
1302 fprintf (dest_doc, "%s",
1303 att_start_command[MAKE_BOLD][output_mode]);
1304 fprintf (dest_doc, "%s", label_name);
1305 fprintf (dest_doc, "%s",
1306 att_stop_command[MAKE_BOLD][output_mode]);
1312 if (strcmp (label_name, function_name))
1316 cook_link = RB_CookStr (label_name);
1317 fprintf (dest_doc, "{\\uldb %s}{\\v %s}",
1318 label_name, cook_link);
1323 fprintf (dest_doc, "%s",
1324 att_start_command[MAKE_BOLD][output_mode]);
1325 fprintf (dest_doc, "%s", label_name);
1326 fprintf (dest_doc, "%s",
1327 att_stop_command[MAKE_BOLD][output_mode]);
1331 fprintf (dest_doc, "%s", label_name);
1333 tmp = strlen (label_name);
1341 if (output_mode == RTF)
1342 fprintf (dest_doc, "\\line");
1343 fputc ('\n', dest_doc);
1347 *end_of_item = old_char;
1355 /****f* ROBODoc/RB_HTML_Extra
1361 * 05/15/2000 Added mailto: support (Guillaume Etorre)
1363 * Check and process embedded hyperlinks.
1364 * RETURN VAL* FUNCTION
1365 * Check and process embedded hyperlinks.
1367 * Number of chars processed from *cur_char
1369 * Flag for C and other grammars.
1371 * As the documentation generated for this functions shows, if
1372 * the C source code contains a string with " / * " in it, this
1378 RB_HTML_Extra (FILE * dest_doc, int item_type, char *cur_char)
1383 if (strncmp ("http://", cur_char, strlen ("http://")) == 0)
1385 sscanf (cur_char, "%s", link);
1386 RB_Say ("found link %s\n", link);
1387 res = (strlen (link) - 1);
1388 fprintf (dest_doc, "<A HREF=\"%s\">%s</A>", link, link);
1390 else if (strncmp ("href:", cur_char, strlen ("href:")) == 0)
1392 /* handy in relative hyperlink paths, e.g. href:../../modulex/ */
1393 sscanf ((cur_char + strlen ("href:")), "%s", link);
1394 RB_Say ("found link %s\n", link);
1395 res = (strlen (link) + strlen ("href:") - 1);
1396 fprintf (dest_doc, "<A HREF=\"%s\">%s</A>", link, link);
1398 else if (strncmp ("mailto:", cur_char, strlen ("mailto:")) == 0)
1400 sscanf ((cur_char + strlen ("mailto:")), "%s", link);
1401 RB_Say ("found mail to %s\n", link);
1402 res = (strlen (link) + strlen ("mailto:") - 1);
1403 fprintf (dest_doc, "<A HREF=\"mailto:%s\">%s</A>", link, link);
1405 else if ((extra_flags & C_MODE) && (item_type == SOURCE_ITEM) &&
1406 (strncmp ("/*", cur_char, 2) == 0))
1408 /* start of C comment */
1409 fprintf (dest_doc, "<FONT COLOR = \"#FF0000\">/*");
1412 else if ((extra_flags & C_MODE) && (item_type == SOURCE_ITEM) &&
1413 (strncmp ("*/", cur_char, 2) == 0))
1415 /* end of C comment */
1416 fprintf (dest_doc, "*/</FONT>");
1425 /****f* ROBODoc/RB_Generate_Index
1427 * RB_Generate_Index -- generate index file based on xref files.
1429 * void RB_Generate_Index(FILE *dest, char *name)
1431 * Create a master index file. It contains pointers to the
1432 * documentation generated for each source file, as well as all
1433 * "objects" found in the source files.
1438 RB_Generate_Index (FILE * dest, char *source)
1440 RB_Slow_Sort_Links ();
1442 switch (output_mode)
1446 if (document_title) {
1447 RB_Generate_Doc_Start (dest, source, document_title, 0);
1448 fprintf (dest, "<H1>%s</H1>\n", document_title);
1450 RB_Generate_Doc_Start (dest, source, "Master Index File", 0);
1451 fprintf (dest, "<H1>Master Index File</H1>\n");
1453 if (RB_Number_Of_Links (MAIN_HEADER, NULL))
1454 RB_Generate_Index_Table (dest, MAIN_HEADER, "Project Modules");
1455 RB_Generate_Index_Table (dest, NO_HEADER, "Source Files");
1456 if (RB_Number_Of_Links (CLASS_HEADER, NULL))
1457 RB_Generate_Index_Table (dest, CLASS_HEADER, "Classes");
1458 if (RB_Number_Of_Links (METHOD_HEADER, NULL))
1459 RB_Generate_Index_Table (dest, METHOD_HEADER, "Methods");
1460 if (RB_Number_Of_Links (STRUCT_HEADER, NULL))
1461 RB_Generate_Index_Table (dest, STRUCT_HEADER, "Structures");
1462 if (RB_Number_Of_Links (FUNCTION_HEADER, NULL))
1463 RB_Generate_Index_Table (dest, FUNCTION_HEADER, "Functions");
1464 if (RB_Number_Of_Links (VARIABLE_HEADER, NULL))
1465 RB_Generate_Index_Table (dest, VARIABLE_HEADER, "Variables");
1466 if (RB_Number_Of_Links (CONSTANT_HEADER, NULL))
1467 RB_Generate_Index_Table (dest, CONSTANT_HEADER, "Constants");
1468 if (RB_Number_Of_Links (GENERIC_HEADER, NULL))
1469 RB_Generate_Index_Table (dest, GENERIC_HEADER, "Generic");
1470 if (RB_Number_Of_Links (INTERNAL_HEADER, NULL))
1471 RB_Generate_Index_Table (dest, INTERNAL_HEADER, "Internal");
1472 RB_Generate_Doc_End (dest, source);
1476 RB_Generate_Doc_Start (dest, source, "Master File", 0);
1477 RB_Generate_LaTeX_Includes (dest);
1478 RB_Generate_Doc_End (dest, source);
1484 /****f* ROBODoc/Generate_LaTeX_Includes
1486 * Generate_LaTeX_Includes -- generate include commands
1488 * void RB_Generate_LaTeX_Includes (FILE *dest)
1490 * Generates a series of \include commands to include the
1491 * documentation generated for each source file into one
1497 RB_Generate_LaTeX_Includes (FILE *dest)
1499 struct RB_link *cur_link;
1500 for (cur_link = first_link;
1502 cur_link = cur_link->next_link) {
1504 if (cur_link->type == NO_HEADER)
1505 fprintf (dest, "\\include{%s}\n", cur_link->label_name);
1510 /****f* ROBODoc/RB_Generate_Index_Table
1512 * RB_Generate_Index --
1514 * void RB_Generate_Index_Table(FILE *, int type, char *title)
1515 * RB_Generate_Index_Table(dest, type, title)
1517 * Creates a table with index items of a particular type.
1518 * If the type is NO_HEADER, then the table is a table of
1519 * source files. In this case no link is added if the
1520 * source file did not contain any documentation.
1522 * dest -- output file
1523 * type -- kind of header index.
1524 * title -- title for the table
1529 RB_Generate_Index_Table (FILE * dest, int type, char *title)
1531 struct RB_link *cur_link;
1532 int number_of_columns;
1535 number_of_columns = 60 / RB_Max_Name_Length (type, NULL);
1537 fprintf (dest, "<H2>%s</H2>\n", title);
1538 fprintf (dest, "<TABLE>\n");
1540 for (cur_link = first_link;
1542 cur_link = cur_link->next_link)
1544 if (cur_link->type == type)
1546 if (cur_column == 0)
1548 fprintf (dest, "<TR>\n");
1550 if (type == NO_HEADER)
1552 if (RB_Number_Of_Links (NO_HEADER, cur_link->file_name) > 1)
1555 "<TD><A HREF=\"%s#%s\"><TT>%s</TT></A></TD>\n",
1556 cur_link->file_name, cur_link->label_name,
1557 cur_link->label_name);
1561 fprintf (dest, "<TD>%s</TD>\n", cur_link->label_name);
1566 fprintf (dest, "<TD><A HREF=\"%s#%s\"><TT>%s</TT></A></TD>\n",
1567 cur_link->file_name, cur_link->label_name,
1568 cur_link->label_name);
1571 if (cur_column > number_of_columns)
1573 fprintf (dest, "</TR>\n");
1578 for (; cur_column <= number_of_columns;)
1580 if (cur_column == 0)
1582 fprintf (dest, "<TR>\n");
1584 fprintf (dest, "<TD></TD>\n");
1587 fprintf (dest, "</TR>\n");
1588 fprintf (dest, "</TABLE>\n");
1591 /******* END RB_Generate_Index_Table *****/
1594 /****f* ROBODoc/RB_Number_Of_Links
1596 * RB_Number_Of_Links -- Count the number of links.
1598 * Counts the number of links that are of a particular type
1599 * and that can be found in a particular file.
1601 * type -- the header type of the header the link is pointing to.
1602 * If NO_HEADER, all header types are counted.
1603 * file_name -- name of the file the link comes from, can be NULL, in
1604 * which case only the type is checked.
1611 RB_Number_Of_Links (int type, char *file_name)
1613 struct RB_link *cur_link;
1616 for (cur_link = first_link;
1618 cur_link = cur_link->next_link)
1620 if (cur_link->type == type || (type == NO_HEADER))
1624 if (strcmp (file_name, cur_link->file_name) == 0)
1640 /****f* ROBODoc/RB_Max_Name_Length
1642 * RB_Max_Name_Length -- find longest label name.
1644 * Find the length of the longest label name in a sub list
1645 * of the list with links. This is used to determine how
1646 * many columns can be displayed in a table.
1647 * The sublist is specified by the type of header the link
1648 * should point to, as well as by the name of the documentation
1651 * RB_Max_Name_Length(CLASS_HEADER, "muppets.c.html")
1652 * longest label name in the list of links to class headers
1653 * in muppets.c.html.
1654 * RB_Max_Name_Length(CLASS_HEADER, NULL)
1655 * longest label name in the list of links to class headers.
1657 * type -- type of header
1658 * file_name -- file the header come from, can be NULL.
1659 * In which links from all files are used.
1664 RB_Max_Name_Length (int type, char *file_name)
1666 struct RB_link *cur_link;
1669 for (cur_link = first_link;
1671 cur_link = cur_link->next_link)
1673 if (cur_link->type == type)
1677 if (strcmp (file_name, cur_link->file_name) == 0)
1679 if (strlen (cur_link->label_name) > n)
1681 n = strlen (cur_link->label_name);
1687 if (strlen (cur_link->label_name) > n)
1689 n = strlen (cur_link->label_name);