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);
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");
272 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);
301 next_line = cur_header->contents;
302 item_type = RB_Find_Item (&next_line, &item_line);
304 if (item_type != NO_ITEM)
311 if (course_of_action & DO_TELL)
312 printf ("[%s] ", item_names[item_type]);
314 if (!((item_type == SOURCE_ITEM) &&
315 (course_of_action & DO_NOSOURCE)))
316 RB_Generate_Item_Name (dest_doc, item_type);
318 old_next_line = next_line;
319 old_item_type = item_type;
321 item_type = RB_Find_Item (&next_line,
324 if (!((old_item_type == SOURCE_ITEM) &&
325 (course_of_action & DO_NOSOURCE)))
326 RB_Generate_Item_Doc(dest_doc, name,
327 old_next_line, item_line,
328 cur_header->function_name,
331 while (item_type != NO_ITEM);
332 if (course_of_action & DO_TELL)
338 fprintf (index, " >> <A HREF=\"%s\">%s</A><BR>\n",
339 name, cur_header->function_name);
346 fprintf (dest_doc, "<LI><A HREF=\"%s\">%s</A>\n",
347 fname, cur_header->name);
349 fprintf (index, " >> <A HREF=\"%s\">%s</A><BR>\n",
350 fname, cur_header->function_name);
355 fprintf (dest_doc, "</OL>\n");
363 fprintf (dest_doc, "%% Document: %s\n", name);
364 fprintf (dest_doc, "%% Source: %s\n", src_name);
365 fprintf (dest_doc, "%% " COMMENT_ROBODOC);
366 fprintf (dest_doc, "%% " COMMENT_COPYRIGHT);
367 if (course_of_action & DO_SINGLEDOC) {
368 fprintf (dest_doc, "\\section{%s}\n", src_name);
370 fprintf (dest_doc, "\\documentclass{article}\n");
371 fprintf (dest_doc, "\\usepackage{makeidx}\n");
372 fprintf (dest_doc, "\\oddsidemargin 0.15 in\n");
373 fprintf (dest_doc, "\\evensidemargin 0.35 in\n");
374 fprintf (dest_doc, "\\marginparwidth 1 in \n");
375 fprintf (dest_doc, "\\oddsidemargin 0.25 in \n");
376 fprintf (dest_doc, "\\evensidemargin 0.25 in\n");
377 fprintf (dest_doc, "\\marginparwidth 0.75 in\n");
378 fprintf (dest_doc, "\\textwidth 5.875 in\n");
380 fprintf (dest_doc, "\\setlength{\\parindent}{0in}\n");
381 fprintf (dest_doc, "\\setlength{\\parskip}{.08in}\n\n");
383 /* changed default header to use boldface (vs slant) */
384 fprintf (dest_doc, "\\pagestyle{headings}\n");
386 if (document_title) {
387 fprintf (dest_doc, "\\title{%s}\n",
390 fprintf (dest_doc, "\\title{API Reference}\n");
392 fprintf (dest_doc, "\\author{%s}\n", COMMENT_ROBODOC);
393 fprintf (dest_doc, "\\makeindex\n");
394 fprintf (dest_doc, "\\begin{document}\n");
395 fprintf (dest_doc, "\\maketitle\n");
396 /* autogenerate table of contents! */
397 fprintf (dest_doc, "\\printindex\n");
398 fprintf (dest_doc, "\\tableofcontents\n");
399 fprintf (dest_doc, "\\newpage\n");
400 /* trick to disable the autogenerated \newpage */
401 fprintf (dest_doc, "\n");
410 fprintf (dest_doc, "{\\rtf1\\ansi \\deff0"
412 "\\f0\\fswiss MS Sans Serif;"
413 "\\f1\\fmodern Courier New;"
414 "\\f2\\ftech Symbol;"
417 "\\red255\\green255\\blue255;"
418 "\\red0\\green0\\blue0;"
419 "\\red0\\green0\\blue255;"
422 /* RTF document info */
423 fprintf (dest_doc, "{\\info"
428 " " COMMENT_COPYRIGHT
430 "}", name, src_name);
432 /* RTF document format */
433 fprintf (dest_doc, "{\\margl1440\\margr1440}\n");
435 /* RTF document section */
436 fprintf (dest_doc, "\\f0\\cb1\\cf3\\fs28\\b1\\qc"
437 "{\\super #{\\footnote{\\super #}%s_TOC}}"
438 "{\\super ${\\footnote{\\super $}Contents}}"
439 "{TABLE OF CONTENTS}\\ql\\b0\\fs20\\cf2\\par\n", src_name);
440 for (cur_header = first_header;
442 cur_header = cur_header->next_header)
444 if (cur_header->name && cur_header->function_name)
446 cook_link = RB_CookStr (cur_header->function_name);
447 fprintf (dest_doc, "{\\uldb %s}{\\v %s}\\line\n",
448 cur_header->name, cook_link);
452 fprintf (dest_doc, "\\par\n");
456 if (course_of_action & DO_TOC)
458 fprintf (dest_doc, "TABLE OF CONTENTS\n");
459 for (cur_header = first_header, header_nr = 1;
461 cur_header = cur_header->next_header, header_nr++)
463 if (cur_header->name && cur_header->function_name)
465 fprintf (dest_doc, "%4.4d %s\n",
466 header_nr, cur_header->name);
469 fputc ('\f', dest_doc);
479 /****f* ROBODoc/RB_Generate_Doc_End [3.0h]
481 * RB_Generate_Doc_End -- generate document trailer.
483 * RB_Generate_Doc_End (dest_doc, name)
485 * RB_Generate_Doc_End (FILE *, char *)
487 * Generates for depending on the output_mode the text that
488 * will be at the end of a document.
490 * dest_doc - pointer to the file to which the output will
492 * name - the name of this file.
493 * output_mode - global variable that indicates the output
496 * Doesn't do anything with its arguments, but that might
497 * change in the future.
503 RB_Generate_Doc_End (FILE * dest_doc, char *name)
508 fputc ('\n', dest_doc);
511 fprintf (dest_doc, "</BODY></HTML>\n");
514 if (!(course_of_action & DO_SINGLEDOC)) {
515 fprintf (dest_doc, "\\end{document}\n");
519 fputc ('}', dest_doc);
529 /****f* ROBODoc/RB_Generate_Header_Start [3.0h]
531 * RB_Generate_Header_Start -- generate header start text.
533 * void RB_Generate_Header_Start (dest_doc, cur_header)
535 * void RB_Generate_Header_Start (FILE *, struct RB_header *)
537 * Generates depending on the output_mode the text that
538 * will be at the end of each header.
540 * dest_doc - pointer to the file to which the output will
542 * cur_header - pointer to a RB_header structure.
544 * RB_Generate_Header_End
549 RB_Generate_Header_Start (FILE * dest_doc, struct RB_header *cur_header)
554 { /* switch by *koessi */
556 if (cur_header->name && cur_header->function_name)
558 fprintf (dest_doc, "@Node \"%s\" \"%s\"\n",
559 cur_header->function_name,
561 fprintf (dest_doc, "%s", att_start_command[MAKE_SHINE][output_mode]);
562 fprintf (dest_doc, "%s", cur_header->name);
563 fprintf (dest_doc, "%s", att_stop_command[MAKE_SHINE][output_mode]);
564 fprintf (dest_doc, "\n\n");
568 if (cur_header->name && cur_header->function_name)
571 fprintf (dest_doc, "<HR>\n");
573 if (cur_header->type == FUNCTION_HEADER)
575 "\n<FONT SIZE=\"+3\" COLOR=\"#000044\"><B>"
576 "Function <A NAME=\"%s\">%s</A>"
577 "</FONT></B><BR><BR>\n\n",
578 cur_header->function_name,
579 cur_header->function_name);
580 else if (cur_header->type == STRUCT_HEADER)
582 "\n<FONT SIZE=\"+3\" COLOR=\"#000044\"><B>"
583 "Structure <A NAME=\"%s\">%s</A>"
584 "</FONT></B><BR><BR>\n\n",
585 cur_header->function_name,
586 cur_header->function_name);
587 else if (cur_header->type == VARIABLE_HEADER)
589 "\n<FONT SIZE=\"+3\" COLOR=\"#000044\"><B>"
590 "Variable <A NAME=\"%s\">%s</A>"
591 "</FONT></B><BR><BR>\n\n",
592 cur_header->function_name,
593 cur_header->function_name);
596 "\n<FONT SIZE=\"+3\" COLOR=\"#000044\"><B>"
597 "<A NAME=\"%s\">%s</A>"
598 "</FONT></B><BR><BR>\n\n",
599 cur_header->function_name,
600 cur_header->function_name);
604 cook_link = RB_CookStr (cur_header->name);
605 if (!(course_of_action & DO_SINGLEDOC)) {
606 fprintf (dest_doc, "\\newpage\n");
608 fprintf (dest_doc, "\\subsection{%s}\n", cook_link);
610 if (cur_header->function_name) {
611 cook_link = RB_CookStr (cur_header->function_name);
612 fprintf (dest_doc, "\\index{unsorted!%s}\\index{%s!%s}\n", cook_link,
613 RB_header_type_names[cur_header->type], cook_link);
618 if (cur_header->name && cur_header->function_name)
620 cook_link = RB_CookStr (cur_header->function_name);
621 fprintf (dest_doc, "\\page"
622 "{\\super #{\\footnote{\\super #}%s}}"
623 "{\\super ${\\footnote{\\super $}%s}}"
624 "\\cf3 %s\\cf2\\line\n",
625 cur_header->function_name,
633 fprintf (dest_doc, "%s", att_start_command[MAKE_SHINE][output_mode]);
634 fprintf (dest_doc, "%s", cur_header->name);
635 fprintf (dest_doc, "%s", att_stop_command[MAKE_SHINE][output_mode]);
636 fprintf (dest_doc, "\n\n");
645 /****f* ROBODoc/RB_Generate_Header_End [3.0h]
647 * RB_Generate_Header_End
649 * void RB_Generate_Header_End (dest_doc, cur_header)
651 * void RB_Generate_Header_End (FILE *, struct RB_header *)
653 * Generates for depending on the output_mode the text that
654 * will be at the end of a header.
656 * dest_doc - pointer to the file to which the output will
658 * cur_header - pointer to a RB_header structure.
660 * RB_Generate_Header_Start
665 RB_Generate_Header_End (FILE * dest_doc, struct RB_header *cur_header)
668 { /* switch by *koessi */
670 if (cur_header->name && cur_header->function_name)
671 fprintf (dest_doc, "@endnode\n");
675 fputc ('\n', dest_doc);
678 fprintf (dest_doc, "\\par\n");
681 fputc ('\f', dest_doc);
690 /****f* ROBODoc/RB_Generate_Header_Name [3.0c]
692 * RB_Generate_Header_Name
694 * RB_Generate_Header_Name (dest_doc, name)
696 * RB_Generate_Header_Name (FILE *, char *)
698 * dest_doc - pointer to the file to which the output will
700 * name - pointer to the header name.
705 RB_Generate_Header_Name (FILE * dest_doc, char *name)
707 char format_str[] = "%s";
709 fprintf (dest_doc, format_str, att_start_command[MAKE_SHINE][output_mode]);
710 fprintf (dest_doc, format_str, name);
711 fprintf (dest_doc, format_str, att_stop_command[MAKE_SHINE][output_mode]);
712 fprintf (dest_doc, "\n\n");
715 /*** RB_Generate_Header_Name ***/
718 /****** ROBODoc/RB_Generate_Item_Name [2.01]
720 * RB_Generate_Item_Name -- fast&easy
722 * void RB_Generate_Item_Name( FILE * dest_doc, int item_type )
724 * write the items name to the doc
726 * FILE * dest_doc -- document in progress
727 * int item_type -- this leads to the name and makes colors
731 * uses globals: output_mode, item_names[]
736 RB_Generate_Item_Name (FILE * dest_doc, int item_type)
738 char format_str[] = "%s";
740 if (item_attributes[item_type] & ITEM_NAME_LARGE_FONT)
742 fprintf (dest_doc, format_str,
743 att_start_command[MAKE_LARGE][output_mode]);
744 fprintf (dest_doc, format_str,
745 att_start_command[MAKE_BOLD][output_mode]);
746 if (output_mode == HTML)
747 fprintf (dest_doc, "\n<FONT COLOR=\"#000044\">");
748 fprintf (dest_doc, format_str, item_names[item_type]);
749 if (output_mode == HTML)
750 fprintf (dest_doc, "\n</FONT>");
751 fprintf (dest_doc, format_str,
752 att_stop_command[MAKE_BOLD][output_mode]);
753 fprintf (dest_doc, format_str,
754 att_stop_command[MAKE_LARGE][output_mode]);
757 fprintf (dest_doc, format_str, item_names[item_type]);
759 fputc ('\n', dest_doc);
766 /****f* ROBODoc/RB_Generate_Item_Doc [3.0j]
768 * RB_Generate_Item_Doc
770 * void RB_Generate_Item_Doc(FILE * dest_doc, char *dest_name,
771 * char *begin_of_item,
773 * char *function_name,
776 * Generates the body text of an item, applying predefined attributes
779 * Body text is always non-proportional for several reasons:
780 * 1) text is rarely written with prop spacing and text wrapping
781 * in mind -- e.g., see SYNOPSIS above
782 * 2) source code looks better
783 * 3) it simplifies LaTeX handling
788 RB_Generate_Item_Doc (FILE * dest_doc, char *dest_name,
794 char format_str[] = "%s";
796 if (begin_of_item == end_of_item)
801 fprintf (dest_doc, "<BR>\n");
804 fprintf (dest_doc, "\\\\\n");
807 fprintf (dest_doc, "\n");
814 /* For text body in HTML, change to non-prop _before_ changing font
815 * style. * To conform to DTD, this avoids <B><PRE> and instead uses
817 if (output_mode == HTML)
819 fprintf (dest_doc, "<PRE>");
821 /* change font style */
822 if (item_attributes[item_type] & TEXT_BODY_LARGE_FONT)
823 fprintf (dest_doc, format_str,
824 att_start_command[MAKE_LARGE][output_mode]);
825 if (item_attributes[item_type] & TEXT_BODY_ITALICS)
826 fprintf (dest_doc, format_str,
827 att_start_command[MAKE_ITALICS][output_mode]);
828 if (item_attributes[item_type] & TEXT_BODY_NON_PROP)
829 fprintf (dest_doc, format_str,
830 att_start_command[MAKE_NON_PROP][output_mode]);
831 if (item_attributes[item_type] & TEXT_BODY_SMALL_FONT)
832 fprintf (dest_doc, format_str,
833 att_start_command[MAKE_SMALL][output_mode]);
834 if (item_attributes[item_type] & TEXT_BODY_BOLD)
835 fprintf (dest_doc, format_str,
836 att_start_command[MAKE_BOLD][output_mode]);
837 if (item_attributes[item_type] & TEXT_BODY_UNDERLINE)
838 fprintf (dest_doc, format_str,
839 att_start_command[MAKE_UNDERLINE][output_mode]);
840 if (item_attributes[item_type] & TEXT_BODY_SHINE)
841 fprintf (dest_doc, format_str,
842 att_start_command[MAKE_SHINE][output_mode]);
843 if (item_attributes[item_type] & TEXT_BODY_DEFAULT)
844 fprintf (dest_doc, format_str,
845 att_start_command[MAKE_DEFAULT][output_mode]);
848 * For some modes, the text body is always non-prop
853 fprintf (dest_doc, "\\begin{verbatim}\n");
856 fprintf (dest_doc, "{\\f1{}");
862 RB_Generate_Item_Body (dest_doc, dest_name, begin_of_item, end_of_item,
863 function_name, item_type, 0);
868 /* split the text so LaTeX doesn't get confused ;) */
869 fprintf (dest_doc, "\\" "end{verbatim}\n");
872 fputc ('}', dest_doc);
877 /* restore font style */
878 if (item_attributes[item_type] & TEXT_BODY_SHINE)
879 fprintf (dest_doc, format_str,
880 att_stop_command[MAKE_SHINE][output_mode]);
881 if (item_attributes[item_type] & TEXT_BODY_UNDERLINE)
882 fprintf (dest_doc, format_str,
883 att_stop_command[MAKE_UNDERLINE][output_mode]);
884 if (item_attributes[item_type] & TEXT_BODY_BOLD)
885 fprintf (dest_doc, format_str,
886 att_stop_command[MAKE_BOLD][output_mode]);
887 if (item_attributes[item_type] & TEXT_BODY_SMALL_FONT)
888 fprintf (dest_doc, format_str,
889 att_stop_command[MAKE_SMALL][output_mode]);
890 if (item_attributes[item_type] & TEXT_BODY_NON_PROP)
891 fprintf (dest_doc, format_str,
892 att_stop_command[MAKE_NON_PROP][output_mode]);
893 if (item_attributes[item_type] & TEXT_BODY_ITALICS)
894 fprintf (dest_doc, format_str,
895 att_stop_command[MAKE_ITALICS][output_mode]);
896 if (item_attributes[item_type] & TEXT_BODY_LARGE_FONT)
897 fprintf (dest_doc, format_str,
898 att_stop_command[MAKE_LARGE][output_mode]);
899 if (item_attributes[item_type] & TEXT_BODY_DEFAULT)
900 fprintf (dest_doc, format_str,
901 att_stop_command[MAKE_DEFAULT][output_mode]);
903 if (output_mode != HTML)
905 fputc ('\n', dest_doc);
907 /* for HTML, switch back to prop-font after restoring font style */
908 if (output_mode == HTML)
910 fprintf (dest_doc, "</PRE>");
918 /****f* ROBODoc/RB_Generate_Item_Body [3.0h]
920 * RB_Generate_Item_Body
922 * char * RB_Generate_Item_Body(FILE * dest_doc, char *dest_name,
923 * char *begin_of_item, char *end_of_item,
924 * char *function_name,
925 * int item_type, int tabs_to_skip)
928 * Generates body of an item in output-specific form
930 * dest_doc - pointer to the file to which
931 * the output will be written.
932 * dest_name - the name of this file.
937 * tabs_to_skip - how many tabs to skip in this fold.
939 * o Unbalanced fold marks lead to crash.
941 * o Almost completely rewritten by koessi
942 * o Almost completely Re-Rewritten by Slothouber :)
943 * o Folding mode by PetteriK.
944 * o Linking fixed inside folds / PetteriK 08.04.2000
949 RB_Generate_Item_Body (FILE * dest_doc, char *dest_name,
950 char *begin_of_item, char *end_of_item,
952 int item_type, int tabs_to_skip)
954 char *cur_char, old_char, c;
956 char fname[128], foldname[128];
957 static int in_fold = 0; /* PetteriK 08.04.2000 */
959 cur_char = begin_of_item;
961 if (item_type == SOURCE_ITEM)
963 /* skip end_comment_marker */
964 for (; *cur_char && *cur_char != '\n'; cur_char++);
966 /* skip blank lines leading up to source code */
967 while (*cur_char == '\n')
970 /* trim blanks following source code */
975 while (end_of_item > cur_char && isspace (*end_of_item));
976 end_of_item++; /* advance 1 for placement of the NUL */
978 old_char = *end_of_item;
981 for (; *cur_char; cur_char++)
984 int do_search = TRUE;
985 int was_link = FALSE;
988 if (item_type != SOURCE_ITEM)
990 /* Skip empty lines */
991 while (*cur_char == '\n') {
994 cur_char = RB_Skip_Remark_Marker (cur_char);
1002 fprintf (dest_doc, "\\tab ");
1009 fprintf (dest_doc, " ");
1013 while (((c = *cur_char) != '\0') && (c != '\n'))
1015 char *label_name, *file_name;
1021 if (!isalnum (c) && (c != '_'))
1028 if (isalpha (c) || (c == '_'))
1030 if (((was_link = RB_Find_Link (cur_char, &label_name,
1031 &file_name)) == FALSE))
1042 switch (output_mode)
1051 for (tb %= tab_size; tb < tab_size; ++tb)
1052 fputc (' ', dest_doc);
1055 fprintf (dest_doc, "\\@");
1059 fprintf (dest_doc, "\\\\");
1063 fputc (c, dest_doc);
1069 /* PetteriK 26.07.1999 */
1070 if (extra_flags & FOLD)
1072 cur_char = RB_Check_Fold_Start (cur_char,
1075 if ((extra_flags & FOLD) && found)
1079 RB_Say ("fold name %s\n", foldname);
1080 RB_Say ("fold begin %d\n", ++fold);
1081 RB_Say ("tabs %d\n", tabs);
1082 sprintf (fname, "%s_fold_%d.html", doc_base, fold);
1083 RB_Say ("opening file %s\n", fname);
1084 fp = fopen (fname, "w");
1085 RB_Generate_Doc_Start (fp, foldname, foldname, 0);
1086 fprintf (fp, "<PRE>\n");
1087 fprintf (dest_doc, "<A HREF=\"%s\">... %s</A>",
1089 in_fold++; /* PetteriK 08.04.2000 */
1090 cur_char = RB_Generate_Item_Body (fp, dest_name,
1091 cur_char, end_of_item,
1094 in_fold--; /* PetteriK 08.04.2000 */
1095 /* skip chars until newline */
1096 while (*cur_char != '\n')
1101 fprintf (fp, "\n</PRE>\n");
1102 RB_Generate_Doc_End (fp, foldname);
1105 else if ((extra_flags & FOLD) && RB_Check_Fold_End (cur_char))
1107 RB_Say ("fold end found\n");
1110 else if ((html_incr = RB_HTML_Extra (dest_doc,
1111 item_type, cur_char)))
1113 cur_char += html_incr;
1123 if (extra_flags & FOLD)
1125 if (tabs >= tabs_to_skip)
1127 for (tb %= tab_size; tb < tab_size; ++tb)
1129 fputc (' ', dest_doc);
1136 for (tb %= tab_size; tb < tab_size; ++tb)
1138 fputc (' ', dest_doc);
1143 fprintf (dest_doc, "<");
1147 fprintf (dest_doc, ">");
1151 fprintf (dest_doc, "&");
1155 fputc (c, dest_doc);
1159 break; /* end case HTML */
1168 for (tb %= tab_size; tb < tab_size; ++tb)
1169 fputc (' ', dest_doc);
1172 /* not used in LaTeX's verbatim environment */
1180 fputc ('\\', dest_doc);
1181 fputc (c, dest_doc);
1185 fprintf (dest_doc, "$\\backslash$");
1189 fprintf (dest_doc, "$\\tilde$");
1193 fprintf (dest_doc, "$\\,\\!^{\\sim}$");
1198 fputc (c, dest_doc);
1210 for (tb %= tab_size; tb < tab_size; ++tb)
1211 fputc (' ', dest_doc);
1216 fputc ('\\', dest_doc);
1217 fputc (c, dest_doc);
1221 fputc (c, dest_doc);
1227 fputc (c, dest_doc);
1234 switch (output_mode)
1237 if (file_name && strcmp (file_name, dest_name))
1238 fprintf (dest_doc, "@{\"%s\" Link \"%s/%s\"}",
1239 label_name, file_name, label_name);
1242 if (strcmp (label_name, function_name))
1243 fprintf (dest_doc, "@{\"%s\" Link \"%s\"}",
1244 label_name, label_name);
1247 fprintf (dest_doc, "%s",
1248 att_start_command[MAKE_BOLD][output_mode]);
1249 fprintf (dest_doc, "%s", label_name);
1250 fprintf (dest_doc, "%s",
1251 att_stop_command[MAKE_BOLD][output_mode]);
1257 /* Include the file name in the link if we are in fold
1258 * PetteriK 08.04.2000
1262 /* We are in fold, always use the file name in the link,
1263 * in file_name == NULL (i.e. the label is in the current file
1264 * that we are processing), refer to value in dest_name.
1265 * This also makes sure that we link correctly if function_name
1266 * is the same as label_name.
1268 fprintf (dest_doc, "<A HREF=\"%s#%s\">%s</A>",
1269 (file_name ? file_name : dest_name),
1270 label_name, label_name);
1272 else if (file_name && strcmp (file_name, dest_name))
1274 fprintf (dest_doc, "<A HREF=\"%s#%s\">%s</A>",
1275 file_name, label_name, label_name);
1279 if (strcmp (label_name, function_name))
1282 fprintf (dest_doc, "<A HREF=\"#%s\">%s</A>",
1283 label_name, label_name);
1285 fprintf (dest_doc, "<A HREF=\"%s_%s.html\">%s</A>",
1286 RB_FilePart(doc_base), label_name,
1291 fprintf (dest_doc, "%s",
1292 att_start_command[MAKE_BOLD][output_mode]);
1293 fprintf (dest_doc, "%s", label_name);
1294 fprintf (dest_doc, "%s",
1295 att_stop_command[MAKE_BOLD][output_mode]);
1301 if (strcmp (label_name, function_name))
1305 cook_link = RB_CookStr (label_name);
1306 fprintf (dest_doc, "{\\uldb %s}{\\v %s}",
1307 label_name, cook_link);
1312 fprintf (dest_doc, "%s",
1313 att_start_command[MAKE_BOLD][output_mode]);
1314 fprintf (dest_doc, "%s", label_name);
1315 fprintf (dest_doc, "%s",
1316 att_stop_command[MAKE_BOLD][output_mode]);
1320 fprintf (dest_doc, "%s", label_name);
1322 tmp = strlen (label_name);
1330 if (output_mode == RTF)
1331 fprintf (dest_doc, "\\line");
1332 fputc ('\n', dest_doc);
1336 *end_of_item = old_char;
1344 /****f* ROBODoc/RB_HTML_Extra
1350 * 05/15/2000 Added mailto: support (Guillaume Etorre)
1352 * Check and process embedded hyperlinks.
1353 * RETURN VAL* FUNCTION
1354 * Check and process embedded hyperlinks.
1356 * Number of chars processed from *cur_char
1358 * Flag for C and other grammars.
1360 * As the documentation generated for this functions shows, if
1361 * the C source code contains a string with " / * " in it, this
1367 RB_HTML_Extra (FILE * dest_doc, int item_type, char *cur_char)
1372 if (strncmp ("http://", cur_char, strlen ("http://")) == 0)
1374 sscanf (cur_char, "%s", link);
1375 RB_Say ("found link %s\n", link);
1376 res = (strlen (link) - 1);
1377 fprintf (dest_doc, "<A HREF=\"%s\">%s</A>", link, link);
1379 else if (strncmp ("href:", cur_char, strlen ("href:")) == 0)
1381 /* handy in relative hyperlink paths, e.g. href:../../modulex/ */
1382 sscanf ((cur_char + strlen ("href:")), "%s", link);
1383 RB_Say ("found link %s\n", link);
1384 res = (strlen (link) + strlen ("href:") - 1);
1385 fprintf (dest_doc, "<A HREF=\"%s\">%s</A>", link, link);
1387 else if (strncmp ("mailto:", cur_char, strlen ("mailto:")) == 0)
1389 sscanf ((cur_char + strlen ("mailto:")), "%s", link);
1390 RB_Say ("found mail to %s\n", link);
1391 res = (strlen (link) + strlen ("mailto:") - 1);
1392 fprintf (dest_doc, "<A HREF=\"mailto:%s\">%s</A>", link, link);
1394 else if ((extra_flags & C_MODE) && (item_type == SOURCE_ITEM) &&
1395 (strncmp ("/*", cur_char, 2) == 0))
1397 /* start of C comment */
1398 fprintf (dest_doc, "<FONT COLOR = \"#FF0000\">/*");
1401 else if ((extra_flags & C_MODE) && (item_type == SOURCE_ITEM) &&
1402 (strncmp ("*/", cur_char, 2) == 0))
1404 /* end of C comment */
1405 fprintf (dest_doc, "*/</FONT>");
1414 /****f* ROBODoc/RB_Generate_Index
1416 * RB_Generate_Index -- generate index file based on xref files.
1418 * void RB_Generate_Index(FILE *dest, char *name)
1420 * Create a master index file. It contains pointers to the
1421 * documentation generated for each source file, as well as all
1422 * "objects" found in the source files.
1427 RB_Generate_Index (FILE * dest, char *source)
1429 RB_Slow_Sort_Links ();
1431 switch (output_mode)
1435 if (document_title) {
1436 RB_Generate_Doc_Start (dest, source, document_title, 0);
1437 fprintf (dest, "<H1>%s</H1>\n", document_title);
1439 RB_Generate_Doc_Start (dest, source, "Master Index File", 0);
1440 fprintf (dest, "<H1>Master Index File</H1>\n");
1442 if (RB_Number_Of_Links (MAIN_HEADER, NULL))
1443 RB_Generate_Index_Table (dest, MAIN_HEADER, "Project Modules");
1444 RB_Generate_Index_Table (dest, NO_HEADER, "Source Files");
1445 if (RB_Number_Of_Links (CLASS_HEADER, NULL))
1446 RB_Generate_Index_Table (dest, CLASS_HEADER, "Classes");
1447 if (RB_Number_Of_Links (METHOD_HEADER, NULL))
1448 RB_Generate_Index_Table (dest, METHOD_HEADER, "Methods");
1449 if (RB_Number_Of_Links (STRUCT_HEADER, NULL))
1450 RB_Generate_Index_Table (dest, STRUCT_HEADER, "Structures");
1451 if (RB_Number_Of_Links (FUNCTION_HEADER, NULL))
1452 RB_Generate_Index_Table (dest, FUNCTION_HEADER, "Functions");
1453 if (RB_Number_Of_Links (VARIABLE_HEADER, NULL))
1454 RB_Generate_Index_Table (dest, VARIABLE_HEADER, "Variables");
1455 if (RB_Number_Of_Links (CONSTANT_HEADER, NULL))
1456 RB_Generate_Index_Table (dest, CONSTANT_HEADER, "Constants");
1457 if (RB_Number_Of_Links (GENERIC_HEADER, NULL))
1458 RB_Generate_Index_Table (dest, GENERIC_HEADER, "Generic");
1459 if (RB_Number_Of_Links (INTERNAL_HEADER, NULL))
1460 RB_Generate_Index_Table (dest, INTERNAL_HEADER, "Internal");
1461 RB_Generate_Doc_End (dest, source);
1465 RB_Generate_Doc_Start (dest, source, "Master File", 0);
1466 RB_Generate_LaTeX_Includes (dest);
1467 RB_Generate_Doc_End (dest, source);
1473 /****f* ROBODoc/Generate_LaTeX_Includes
1475 * Generate_LaTeX_Includes -- generate include commands
1477 * void RB_Generate_LaTeX_Includes (FILE *dest)
1479 * Generates a series of \include commands to include the
1480 * documentation generated for each source file into one
1486 RB_Generate_LaTeX_Includes (FILE *dest)
1488 struct RB_link *cur_link;
1489 for (cur_link = first_link;
1491 cur_link = cur_link->next_link) {
1493 if (cur_link->type == NO_HEADER)
1494 fprintf (dest, "\\include{%s}\n", cur_link->label_name);
1499 /****f* ROBODoc/RB_Generate_Index_Table
1501 * RB_Generate_Index --
1503 * void RB_Generate_Index_Table(FILE *, int type, char *title)
1504 * RB_Generate_Index_Table(dest, type, title)
1506 * Creates a table with index items of a particular type.
1507 * If the type is NO_HEADER, then the table is a table of
1508 * source files. In this case no link is added if the
1509 * source file did not contain any documentation.
1511 * dest -- output file
1512 * type -- kind of header index.
1513 * title -- title for the table
1518 RB_Generate_Index_Table (FILE * dest, int type, char *title)
1520 struct RB_link *cur_link;
1521 int number_of_columns;
1524 number_of_columns = 60 / RB_Max_Name_Length (type, NULL);
1526 fprintf (dest, "<H2>%s</H2>\n", title);
1527 fprintf (dest, "<TABLE>\n");
1529 for (cur_link = first_link;
1531 cur_link = cur_link->next_link)
1533 if (cur_link->type == type)
1535 if (cur_column == 0)
1537 fprintf (dest, "<TR>\n");
1539 if (type == NO_HEADER)
1541 if (RB_Number_Of_Links (NO_HEADER, cur_link->file_name) > 1)
1544 "<TD><A HREF=\"%s#%s\"><TT>%s</TT></A></TD>\n",
1545 cur_link->file_name, cur_link->label_name,
1546 cur_link->label_name);
1550 fprintf (dest, "<TD>%s</TD>\n", cur_link->label_name);
1555 fprintf (dest, "<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);
1560 if (cur_column > number_of_columns)
1562 fprintf (dest, "</TR>\n");
1567 for (; cur_column <= number_of_columns;)
1569 if (cur_column == 0)
1571 fprintf (dest, "<TR>\n");
1573 fprintf (dest, "<TD></TD>\n");
1576 fprintf (dest, "</TR>\n");
1577 fprintf (dest, "</TABLE>\n");
1580 /******* END RB_Generate_Index_Table *****/
1583 /****f* ROBODoc/RB_Number_Of_Links
1585 * RB_Number_Of_Links -- Count the number of links.
1587 * Counts the number of links that are of a particular type
1588 * and that can be found in a particular file.
1590 * type -- the header type of the header the link is pointing to.
1591 * If NO_HEADER, all header types are counted.
1592 * file_name -- name of the file the link comes from, can be NULL, in
1593 * which case only the type is checked.
1600 RB_Number_Of_Links (int type, char *file_name)
1602 struct RB_link *cur_link;
1605 for (cur_link = first_link;
1607 cur_link = cur_link->next_link)
1609 if (cur_link->type == type || (type == NO_HEADER))
1613 if (strcmp (file_name, cur_link->file_name) == 0)
1629 /****f* ROBODoc/RB_Max_Name_Length
1631 * RB_Max_Name_Length -- find longest label name.
1633 * Find the length of the longest label name in a sub list
1634 * of the list with links. This is used to determine how
1635 * many columns can be displayed in a table.
1636 * The sublist is specified by the type of header the link
1637 * should point to, as well as by the name of the documentation
1640 * RB_Max_Name_Length(CLASS_HEADER, "muppets.c.html")
1641 * longest label name in the list of links to class headers
1642 * in muppets.c.html.
1643 * RB_Max_Name_Length(CLASS_HEADER, NULL)
1644 * longest label name in the list of links to class headers.
1646 * type -- type of header
1647 * file_name -- file the header come from, can be NULL.
1648 * In which links from all files are used.
1653 RB_Max_Name_Length (int type, char *file_name)
1655 struct RB_link *cur_link;
1658 for (cur_link = first_link;
1660 cur_link = cur_link->next_link)
1662 if (cur_link->type == type)
1666 if (strcmp (file_name, cur_link->file_name) == 0)
1668 if (strlen (cur_link->label_name) > n)
1670 n = strlen (cur_link->label_name);
1676 if (strlen (cur_link->label_name) > n)
1678 n = strlen (cur_link->label_name);