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");
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);
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->function_name);
349 fprintf (index, " >> <A HREF=\"%s\">%s</A><BR>\n",
350 fname, cur_header->function_name);
356 fprintf (dest_doc, "</OL>\n");
365 fprintf (dest_doc, "%% Document: %s\n", name);
366 fprintf (dest_doc, "%% Source: %s\n", src_name);
367 fprintf (dest_doc, "%% " COMMENT_ROBODOC);
368 fprintf (dest_doc, "%% " COMMENT_COPYRIGHT);
369 if (course_of_action & DO_SINGLEDOC) {
370 fprintf (dest_doc, "\\section{%s}\n", src_name);
372 fprintf (dest_doc, "\\documentclass{article}\n");
373 fprintf (dest_doc, "\\usepackage{makeidx}\n");
374 fprintf (dest_doc, "\\oddsidemargin 0.15 in\n");
375 fprintf (dest_doc, "\\evensidemargin 0.35 in\n");
376 fprintf (dest_doc, "\\marginparwidth 1 in \n");
377 fprintf (dest_doc, "\\oddsidemargin 0.25 in \n");
378 fprintf (dest_doc, "\\evensidemargin 0.25 in\n");
379 fprintf (dest_doc, "\\marginparwidth 0.75 in\n");
380 fprintf (dest_doc, "\\textwidth 5.875 in\n");
382 fprintf (dest_doc, "\\setlength{\\parindent}{0in}\n");
383 fprintf (dest_doc, "\\setlength{\\parskip}{.08in}\n\n");
385 /* changed default header to use boldface (vs slant) */
386 fprintf (dest_doc, "\\pagestyle{headings}\n");
388 if (document_title) {
389 fprintf (dest_doc, "\\title{%s}\n",
392 fprintf (dest_doc, "\\title{API Reference}\n");
394 fprintf (dest_doc, "\\author{%s}\n", COMMENT_ROBODOC);
395 fprintf (dest_doc, "\\makeindex\n");
396 fprintf (dest_doc, "\\begin{document}\n");
397 fprintf (dest_doc, "\\maketitle\n");
398 /* autogenerate table of contents! */
399 fprintf (dest_doc, "\\printindex\n");
400 fprintf (dest_doc, "\\tableofcontents\n");
401 fprintf (dest_doc, "\\newpage\n");
402 /* trick to disable the autogenerated \newpage */
403 fprintf (dest_doc, "\n");
412 fprintf (dest_doc, "{\\rtf1\\ansi \\deff0"
414 "\\f0\\fswiss MS Sans Serif;"
415 "\\f1\\fmodern Courier New;"
416 "\\f2\\ftech Symbol;"
419 "\\red255\\green255\\blue255;"
420 "\\red0\\green0\\blue0;"
421 "\\red0\\green0\\blue255;"
424 /* RTF document info */
425 fprintf (dest_doc, "{\\info"
430 " " COMMENT_COPYRIGHT
432 "}", name, src_name);
434 /* RTF document format */
435 fprintf (dest_doc, "{\\margl1440\\margr1440}\n");
437 /* RTF document section */
438 fprintf (dest_doc, "\\f0\\cb1\\cf3\\fs28\\b1\\qc"
439 "{\\super #{\\footnote{\\super #}%s_TOC}}"
440 "{\\super ${\\footnote{\\super $}Contents}}"
441 "{TABLE OF CONTENTS}\\ql\\b0\\fs20\\cf2\\par\n", src_name);
442 for (cur_header = first_header;
444 cur_header = cur_header->next_header)
446 if (cur_header->name && cur_header->function_name)
448 cook_link = RB_CookStr (cur_header->function_name);
449 fprintf (dest_doc, "{\\uldb %s}{\\v %s}\\line\n",
450 cur_header->name, cook_link);
454 fprintf (dest_doc, "\\par\n");
458 if (course_of_action & DO_TOC)
460 fprintf (dest_doc, "TABLE OF CONTENTS\n");
461 for (cur_header = first_header, header_nr = 1;
463 cur_header = cur_header->next_header, header_nr++)
465 if (cur_header->name && cur_header->function_name)
467 fprintf (dest_doc, "%4.4d %s\n",
468 header_nr, cur_header->name);
471 fputc ('\f', dest_doc);
481 /****f* ROBODoc/RB_Generate_Doc_End [3.0h]
483 * RB_Generate_Doc_End -- generate document trailer.
485 * RB_Generate_Doc_End (dest_doc, name)
487 * RB_Generate_Doc_End (FILE *, char *)
489 * Generates for depending on the output_mode the text that
490 * will be at the end of a document.
492 * dest_doc - pointer to the file to which the output will
494 * name - the name of this file.
495 * output_mode - global variable that indicates the output
498 * Doesn't do anything with its arguments, but that might
499 * change in the future.
505 RB_Generate_Doc_End (FILE * dest_doc, char *name)
510 fputc ('\n', dest_doc);
513 fprintf (dest_doc, "</BODY></HTML>\n");
516 if (!(course_of_action & DO_SINGLEDOC)) {
517 fprintf (dest_doc, "\\end{document}\n");
521 fputc ('}', dest_doc);
531 /****f* ROBODoc/RB_Generate_Header_Start [3.0h]
533 * RB_Generate_Header_Start -- generate header start text.
535 * void RB_Generate_Header_Start (dest_doc, cur_header)
537 * void RB_Generate_Header_Start (FILE *, struct RB_header *)
539 * Generates depending on the output_mode the text that
540 * will be at the end of each header.
542 * dest_doc - pointer to the file to which the output will
544 * cur_header - pointer to a RB_header structure.
546 * RB_Generate_Header_End
551 RB_Generate_Header_Start (FILE * dest_doc, struct RB_header *cur_header)
556 { /* switch by *koessi */
558 if (cur_header->name && cur_header->function_name)
560 fprintf (dest_doc, "@Node \"%s\" \"%s\"\n",
561 cur_header->function_name,
563 fprintf (dest_doc, "%s", att_start_command[MAKE_SHINE][output_mode]);
564 fprintf (dest_doc, "%s", cur_header->name);
565 fprintf (dest_doc, "%s", att_stop_command[MAKE_SHINE][output_mode]);
566 fprintf (dest_doc, "\n\n");
570 if (cur_header->name && cur_header->function_name)
573 fprintf (dest_doc, "<HR>\n");
575 if (cur_header->type == FUNCTION_HEADER)
577 "\n<FONT SIZE=\"+3\" COLOR=\"#000044\"><B>"
578 "Function <A NAME=\"%s\">%s</A>"
579 "</FONT></B><BR><BR>\n\n",
580 cur_header->function_name,
581 cur_header->function_name);
582 else if (cur_header->type == STRUCT_HEADER)
584 "\n<FONT SIZE=\"+3\" COLOR=\"#000044\"><B>"
585 "Structure <A NAME=\"%s\">%s</A>"
586 "</FONT></B><BR><BR>\n\n",
587 cur_header->function_name,
588 cur_header->function_name);
589 else if (cur_header->type == VARIABLE_HEADER)
591 "\n<FONT SIZE=\"+3\" COLOR=\"#000044\"><B>"
592 "Variable <A NAME=\"%s\">%s</A>"
593 "</FONT></B><BR><BR>\n\n",
594 cur_header->function_name,
595 cur_header->function_name);
598 "\n<FONT SIZE=\"+3\" COLOR=\"#000044\"><B>"
599 "<A NAME=\"%s\">%s</A>"
600 "</FONT></B><BR><BR>\n\n",
601 cur_header->function_name,
602 cur_header->function_name);
606 cook_link = RB_CookStr (cur_header->name);
607 if (!(course_of_action & DO_SINGLEDOC)) {
608 fprintf (dest_doc, "\\newpage\n");
610 fprintf (dest_doc, "\\subsection{%s}\n", cook_link);
612 if (cur_header->function_name) {
613 cook_link = RB_CookStr (cur_header->function_name);
614 fprintf (dest_doc, "\\index{unsorted!%s}\\index{%s!%s}\n", cook_link,
615 RB_header_type_names[cur_header->type], cook_link);
620 if (cur_header->name && cur_header->function_name)
622 cook_link = RB_CookStr (cur_header->function_name);
623 fprintf (dest_doc, "\\page"
624 "{\\super #{\\footnote{\\super #}%s}}"
625 "{\\super ${\\footnote{\\super $}%s}}"
626 "\\cf3 %s\\cf2\\line\n",
627 cur_header->function_name,
635 fprintf (dest_doc, "%s", att_start_command[MAKE_SHINE][output_mode]);
636 fprintf (dest_doc, "%s", cur_header->name);
637 fprintf (dest_doc, "%s", att_stop_command[MAKE_SHINE][output_mode]);
638 fprintf (dest_doc, "\n\n");
647 /****f* ROBODoc/RB_Generate_Header_End [3.0h]
649 * RB_Generate_Header_End
651 * void RB_Generate_Header_End (dest_doc, cur_header)
653 * void RB_Generate_Header_End (FILE *, struct RB_header *)
655 * Generates for depending on the output_mode the text that
656 * will be at the end of a header.
658 * dest_doc - pointer to the file to which the output will
660 * cur_header - pointer to a RB_header structure.
662 * RB_Generate_Header_Start
667 RB_Generate_Header_End (FILE * dest_doc, struct RB_header *cur_header)
670 { /* switch by *koessi */
672 if (cur_header->name && cur_header->function_name)
673 fprintf (dest_doc, "@endnode\n");
677 fputc ('\n', dest_doc);
680 fprintf (dest_doc, "\\par\n");
683 fputc ('\f', dest_doc);
692 /****f* ROBODoc/RB_Generate_Header_Name [3.0c]
694 * RB_Generate_Header_Name
696 * RB_Generate_Header_Name (dest_doc, name)
698 * RB_Generate_Header_Name (FILE *, char *)
700 * dest_doc - pointer to the file to which the output will
702 * name - pointer to the header name.
707 RB_Generate_Header_Name (FILE * dest_doc, char *name)
709 char format_str[] = "%s";
711 fprintf (dest_doc, format_str, att_start_command[MAKE_SHINE][output_mode]);
712 fprintf (dest_doc, format_str, name);
713 fprintf (dest_doc, format_str, att_stop_command[MAKE_SHINE][output_mode]);
714 fprintf (dest_doc, "\n\n");
717 /*** RB_Generate_Header_Name ***/
720 /****** ROBODoc/RB_Generate_Item_Name [2.01]
722 * RB_Generate_Item_Name -- fast&easy
724 * void RB_Generate_Item_Name( FILE * dest_doc, int item_type )
726 * write the items name to the doc
728 * FILE * dest_doc -- document in progress
729 * int item_type -- this leads to the name and makes colors
733 * uses globals: output_mode, item_names[]
738 RB_Generate_Item_Name (FILE * dest_doc, int item_type)
740 char format_str[] = "%s";
742 if (item_attributes[item_type] & ITEM_NAME_LARGE_FONT)
744 fprintf (dest_doc, format_str,
745 att_start_command[MAKE_LARGE][output_mode]);
746 fprintf (dest_doc, format_str,
747 att_start_command[MAKE_BOLD][output_mode]);
748 if (output_mode == HTML)
749 fprintf (dest_doc, "\n<FONT COLOR=\"#000044\">");
750 fprintf (dest_doc, format_str, item_names[item_type]);
751 if (output_mode == HTML)
752 fprintf (dest_doc, "\n</FONT>");
753 fprintf (dest_doc, format_str,
754 att_stop_command[MAKE_BOLD][output_mode]);
755 fprintf (dest_doc, format_str,
756 att_stop_command[MAKE_LARGE][output_mode]);
759 fprintf (dest_doc, format_str, item_names[item_type]);
761 fputc ('\n', dest_doc);
768 /****f* ROBODoc/RB_Generate_Item_Doc [3.0j]
770 * RB_Generate_Item_Doc
772 * void RB_Generate_Item_Doc(FILE * dest_doc, char *dest_name,
773 * char *begin_of_item,
775 * char *function_name,
778 * Generates the body text of an item, applying predefined attributes
781 * Body text is always non-proportional for several reasons:
782 * 1) text is rarely written with prop spacing and text wrapping
783 * in mind -- e.g., see SYNOPSIS above
784 * 2) source code looks better
785 * 3) it simplifies LaTeX handling
790 RB_Generate_Item_Doc (FILE * dest_doc, char *dest_name,
796 char format_str[] = "%s";
798 if (begin_of_item == end_of_item)
803 fprintf (dest_doc, "<BR>\n");
806 fprintf (dest_doc, "\\\\\n");
809 fprintf (dest_doc, "\n");
816 /* For text body in HTML, change to non-prop _before_ changing font
817 * style. * To conform to DTD, this avoids <B><PRE> and instead uses
819 if (output_mode == HTML)
821 fprintf (dest_doc, "<PRE>");
823 /* change font style */
824 if (item_attributes[item_type] & TEXT_BODY_LARGE_FONT)
825 fprintf (dest_doc, format_str,
826 att_start_command[MAKE_LARGE][output_mode]);
827 if (item_attributes[item_type] & TEXT_BODY_ITALICS)
828 fprintf (dest_doc, format_str,
829 att_start_command[MAKE_ITALICS][output_mode]);
830 if (item_attributes[item_type] & TEXT_BODY_NON_PROP)
831 fprintf (dest_doc, format_str,
832 att_start_command[MAKE_NON_PROP][output_mode]);
833 if (item_attributes[item_type] & TEXT_BODY_SMALL_FONT)
834 fprintf (dest_doc, format_str,
835 att_start_command[MAKE_SMALL][output_mode]);
836 if (item_attributes[item_type] & TEXT_BODY_BOLD)
837 fprintf (dest_doc, format_str,
838 att_start_command[MAKE_BOLD][output_mode]);
839 if (item_attributes[item_type] & TEXT_BODY_UNDERLINE)
840 fprintf (dest_doc, format_str,
841 att_start_command[MAKE_UNDERLINE][output_mode]);
842 if (item_attributes[item_type] & TEXT_BODY_SHINE)
843 fprintf (dest_doc, format_str,
844 att_start_command[MAKE_SHINE][output_mode]);
845 if (item_attributes[item_type] & TEXT_BODY_DEFAULT)
846 fprintf (dest_doc, format_str,
847 att_start_command[MAKE_DEFAULT][output_mode]);
850 * For some modes, the text body is always non-prop
855 fprintf (dest_doc, "\\begin{verbatim}\n");
858 fprintf (dest_doc, "{\\f1{}");
864 RB_Generate_Item_Body (dest_doc, dest_name, begin_of_item, end_of_item,
865 function_name, item_type, 0);
870 /* split the text so LaTeX doesn't get confused ;) */
871 fprintf (dest_doc, "\\" "end{verbatim}\n");
874 fputc ('}', dest_doc);
879 /* restore font style */
880 if (item_attributes[item_type] & TEXT_BODY_SHINE)
881 fprintf (dest_doc, format_str,
882 att_stop_command[MAKE_SHINE][output_mode]);
883 if (item_attributes[item_type] & TEXT_BODY_UNDERLINE)
884 fprintf (dest_doc, format_str,
885 att_stop_command[MAKE_UNDERLINE][output_mode]);
886 if (item_attributes[item_type] & TEXT_BODY_BOLD)
887 fprintf (dest_doc, format_str,
888 att_stop_command[MAKE_BOLD][output_mode]);
889 if (item_attributes[item_type] & TEXT_BODY_SMALL_FONT)
890 fprintf (dest_doc, format_str,
891 att_stop_command[MAKE_SMALL][output_mode]);
892 if (item_attributes[item_type] & TEXT_BODY_NON_PROP)
893 fprintf (dest_doc, format_str,
894 att_stop_command[MAKE_NON_PROP][output_mode]);
895 if (item_attributes[item_type] & TEXT_BODY_ITALICS)
896 fprintf (dest_doc, format_str,
897 att_stop_command[MAKE_ITALICS][output_mode]);
898 if (item_attributes[item_type] & TEXT_BODY_LARGE_FONT)
899 fprintf (dest_doc, format_str,
900 att_stop_command[MAKE_LARGE][output_mode]);
901 if (item_attributes[item_type] & TEXT_BODY_DEFAULT)
902 fprintf (dest_doc, format_str,
903 att_stop_command[MAKE_DEFAULT][output_mode]);
905 if (output_mode != HTML)
907 fputc ('\n', dest_doc);
909 /* for HTML, switch back to prop-font after restoring font style */
910 if (output_mode == HTML)
912 fprintf (dest_doc, "</PRE>");
920 /****f* ROBODoc/RB_Generate_Item_Body [3.0h]
922 * RB_Generate_Item_Body
924 * char * RB_Generate_Item_Body(FILE * dest_doc, char *dest_name,
925 * char *begin_of_item, char *end_of_item,
926 * char *function_name,
927 * int item_type, int tabs_to_skip)
930 * Generates body of an item in output-specific form
932 * dest_doc - pointer to the file to which
933 * the output will be written.
934 * dest_name - the name of this file.
939 * tabs_to_skip - how many tabs to skip in this fold.
941 * o Unbalanced fold marks lead to crash.
943 * o Almost completely rewritten by koessi
944 * o Almost completely Re-Rewritten by Slothouber :)
945 * o Folding mode by PetteriK.
946 * o Linking fixed inside folds / PetteriK 08.04.2000
951 RB_Generate_Item_Body (FILE * dest_doc, char *dest_name,
952 char *begin_of_item, char *end_of_item,
954 int item_type, int tabs_to_skip)
956 char *cur_char, old_char, c;
958 char fname[128], foldname[128];
959 static int in_fold = 0; /* PetteriK 08.04.2000 */
961 cur_char = begin_of_item;
963 if (item_type == SOURCE_ITEM)
965 /* skip end_comment_marker */
966 for (; *cur_char && *cur_char != '\n'; cur_char++);
968 /* skip blank lines leading up to source code */
969 while (*cur_char == '\n')
972 /* trim blanks following source code */
977 while (end_of_item > cur_char && isspace (*end_of_item));
978 end_of_item++; /* advance 1 for placement of the NUL */
980 old_char = *end_of_item;
983 for (; *cur_char; cur_char++)
986 int do_search = TRUE;
987 int was_link = FALSE;
990 if (item_type != SOURCE_ITEM)
992 /* Skip empty lines */
993 while (*cur_char == '\n') {
996 cur_char = RB_Skip_Remark_Marker (cur_char);
1001 switch (output_mode)
1004 fprintf (dest_doc, "\\tab ");
1011 fprintf (dest_doc, " ");
1015 while (((c = *cur_char) != '\0') && (c != '\n'))
1017 char *label_name, *file_name;
1023 if (!isalnum (c) && (c != '_'))
1030 if (isalpha (c) || (c == '_'))
1032 if (((was_link = RB_Find_Link (cur_char, &label_name,
1033 &file_name)) == FALSE))
1044 switch (output_mode)
1053 for (tb %= tab_size; tb < tab_size; ++tb)
1054 fputc (' ', dest_doc);
1057 fprintf (dest_doc, "\\@");
1061 fprintf (dest_doc, "\\\\");
1065 fputc (c, dest_doc);
1071 /* PetteriK 26.07.1999 */
1072 if (extra_flags & FOLD)
1074 cur_char = RB_Check_Fold_Start (cur_char,
1077 if ((extra_flags & FOLD) && found)
1081 RB_Say ("fold name %s\n", foldname);
1082 RB_Say ("fold begin %d\n", ++fold);
1083 RB_Say ("tabs %d\n", tabs);
1084 sprintf (fname, "%s_fold_%d.html", doc_base, fold);
1085 RB_Say ("opening file %s\n", fname);
1086 fp = fopen (fname, "w");
1087 RB_Generate_Doc_Start (fp, foldname, foldname, 0);
1088 fprintf (fp, "<PRE>\n");
1089 fprintf (dest_doc, "<A HREF=\"%s\">... %s</A>",
1091 in_fold++; /* PetteriK 08.04.2000 */
1092 cur_char = RB_Generate_Item_Body (fp, dest_name,
1093 cur_char, end_of_item,
1096 in_fold--; /* PetteriK 08.04.2000 */
1097 /* skip chars until newline */
1098 while (*cur_char != '\n')
1103 fprintf (fp, "\n</PRE>\n");
1104 RB_Generate_Doc_End (fp, foldname);
1107 else if ((extra_flags & FOLD) && RB_Check_Fold_End (cur_char))
1109 RB_Say ("fold end found\n");
1112 else if ((html_incr = RB_HTML_Extra (dest_doc,
1113 item_type, cur_char)))
1115 cur_char += html_incr;
1125 if (extra_flags & FOLD)
1127 if (tabs >= tabs_to_skip)
1129 for (tb %= tab_size; tb < tab_size; ++tb)
1131 fputc (' ', dest_doc);
1138 for (tb %= tab_size; tb < tab_size; ++tb)
1140 fputc (' ', dest_doc);
1145 fprintf (dest_doc, "<");
1149 fprintf (dest_doc, ">");
1153 fprintf (dest_doc, "&");
1157 fputc (c, dest_doc);
1161 break; /* end case HTML */
1170 for (tb %= tab_size; tb < tab_size; ++tb)
1171 fputc (' ', dest_doc);
1174 /* not used in LaTeX's verbatim environment */
1182 fputc ('\\', dest_doc);
1183 fputc (c, dest_doc);
1187 fprintf (dest_doc, "$\\backslash$");
1191 fprintf (dest_doc, "$\\tilde$");
1195 fprintf (dest_doc, "$\\,\\!^{\\sim}$");
1200 fputc (c, dest_doc);
1212 for (tb %= tab_size; tb < tab_size; ++tb)
1213 fputc (' ', dest_doc);
1218 fputc ('\\', dest_doc);
1219 fputc (c, dest_doc);
1223 fputc (c, dest_doc);
1229 fputc (c, dest_doc);
1236 switch (output_mode)
1239 if (file_name && strcmp (file_name, dest_name))
1240 fprintf (dest_doc, "@{\"%s\" Link \"%s/%s\"}",
1241 label_name, file_name, label_name);
1244 if (strcmp (label_name, function_name))
1245 fprintf (dest_doc, "@{\"%s\" Link \"%s\"}",
1246 label_name, label_name);
1249 fprintf (dest_doc, "%s",
1250 att_start_command[MAKE_BOLD][output_mode]);
1251 fprintf (dest_doc, "%s", label_name);
1252 fprintf (dest_doc, "%s",
1253 att_stop_command[MAKE_BOLD][output_mode]);
1259 /* Include the file name in the link if we are in fold
1260 * PetteriK 08.04.2000
1264 /* We are in fold, always use the file name in the link,
1265 * in file_name == NULL (i.e. the label is in the current file
1266 * that we are processing), refer to value in dest_name.
1267 * This also makes sure that we link correctly if function_name
1268 * is the same as label_name.
1270 fprintf (dest_doc, "<A HREF=\"%s#%s\">%s</A>",
1271 (file_name ? file_name : dest_name),
1272 label_name, label_name);
1274 else if (file_name && strcmp (file_name, dest_name))
1276 fprintf (dest_doc, "<A HREF=\"%s#%s\">%s</A>",
1277 file_name, label_name, label_name);
1281 if (strcmp (label_name, function_name))
1284 fprintf (dest_doc, "<A HREF=\"#%s\">%s</A>",
1285 label_name, label_name);
1287 fprintf (dest_doc, "<A HREF=\"%s_%s.html\">%s</A>",
1288 RB_FilePart(doc_base), label_name,
1293 fprintf (dest_doc, "%s",
1294 att_start_command[MAKE_BOLD][output_mode]);
1295 fprintf (dest_doc, "%s", label_name);
1296 fprintf (dest_doc, "%s",
1297 att_stop_command[MAKE_BOLD][output_mode]);
1303 if (strcmp (label_name, function_name))
1307 cook_link = RB_CookStr (label_name);
1308 fprintf (dest_doc, "{\\uldb %s}{\\v %s}",
1309 label_name, cook_link);
1314 fprintf (dest_doc, "%s",
1315 att_start_command[MAKE_BOLD][output_mode]);
1316 fprintf (dest_doc, "%s", label_name);
1317 fprintf (dest_doc, "%s",
1318 att_stop_command[MAKE_BOLD][output_mode]);
1322 fprintf (dest_doc, "%s", label_name);
1324 tmp = strlen (label_name);
1332 if (output_mode == RTF)
1333 fprintf (dest_doc, "\\line");
1334 fputc ('\n', dest_doc);
1338 *end_of_item = old_char;
1346 /****f* ROBODoc/RB_HTML_Extra
1352 * 05/15/2000 Added mailto: support (Guillaume Etorre)
1354 * Check and process embedded hyperlinks.
1355 * RETURN VAL* FUNCTION
1356 * Check and process embedded hyperlinks.
1358 * Number of chars processed from *cur_char
1360 * Flag for C and other grammars.
1362 * As the documentation generated for this functions shows, if
1363 * the C source code contains a string with " / * " in it, this
1369 RB_HTML_Extra (FILE * dest_doc, int item_type, char *cur_char)
1374 if (strncmp ("http://", cur_char, strlen ("http://")) == 0)
1376 sscanf (cur_char, "%s", link);
1377 RB_Say ("found link %s\n", link);
1378 res = (strlen (link) - 1);
1379 fprintf (dest_doc, "<A HREF=\"%s\">%s</A>", link, link);
1381 else if (strncmp ("href:", cur_char, strlen ("href:")) == 0)
1383 /* handy in relative hyperlink paths, e.g. href:../../modulex/ */
1384 sscanf ((cur_char + strlen ("href:")), "%s", link);
1385 RB_Say ("found link %s\n", link);
1386 res = (strlen (link) + strlen ("href:") - 1);
1387 fprintf (dest_doc, "<A HREF=\"%s\">%s</A>", link, link);
1389 else if (strncmp ("mailto:", cur_char, strlen ("mailto:")) == 0)
1391 sscanf ((cur_char + strlen ("mailto:")), "%s", link);
1392 RB_Say ("found mail to %s\n", link);
1393 res = (strlen (link) + strlen ("mailto:") - 1);
1394 fprintf (dest_doc, "<A HREF=\"mailto:%s\">%s</A>", link, link);
1396 else if ((extra_flags & C_MODE) && (item_type == SOURCE_ITEM) &&
1397 (strncmp ("/*", cur_char, 2) == 0))
1399 /* start of C comment */
1400 fprintf (dest_doc, "<FONT COLOR = \"#FF0000\">/*");
1403 else if ((extra_flags & C_MODE) && (item_type == SOURCE_ITEM) &&
1404 (strncmp ("*/", cur_char, 2) == 0))
1406 /* end of C comment */
1407 fprintf (dest_doc, "*/</FONT>");
1416 /****f* ROBODoc/RB_Generate_Index
1418 * RB_Generate_Index -- generate index file based on xref files.
1420 * void RB_Generate_Index(FILE *dest, char *name)
1422 * Create a master index file. It contains pointers to the
1423 * documentation generated for each source file, as well as all
1424 * "objects" found in the source files.
1429 RB_Generate_Index (FILE * dest, char *source)
1431 RB_Slow_Sort_Links ();
1433 switch (output_mode)
1437 if (document_title) {
1438 RB_Generate_Doc_Start (dest, source, document_title, 0);
1439 fprintf (dest, "<H1>%s</H1>\n", document_title);
1441 RB_Generate_Doc_Start (dest, source, "Master Index File", 0);
1442 fprintf (dest, "<H1>Master Index File</H1>\n");
1444 if (RB_Number_Of_Links (MAIN_HEADER, NULL))
1445 RB_Generate_Index_Table (dest, MAIN_HEADER, "Project Modules");
1446 RB_Generate_Index_Table (dest, NO_HEADER, "Source Files");
1447 if (RB_Number_Of_Links (CLASS_HEADER, NULL))
1448 RB_Generate_Index_Table (dest, CLASS_HEADER, "Classes");
1449 if (RB_Number_Of_Links (METHOD_HEADER, NULL))
1450 RB_Generate_Index_Table (dest, METHOD_HEADER, "Methods");
1451 if (RB_Number_Of_Links (STRUCT_HEADER, NULL))
1452 RB_Generate_Index_Table (dest, STRUCT_HEADER, "Structures");
1453 if (RB_Number_Of_Links (FUNCTION_HEADER, NULL))
1454 RB_Generate_Index_Table (dest, FUNCTION_HEADER, "Functions");
1455 if (RB_Number_Of_Links (VARIABLE_HEADER, NULL))
1456 RB_Generate_Index_Table (dest, VARIABLE_HEADER, "Variables");
1457 if (RB_Number_Of_Links (CONSTANT_HEADER, NULL))
1458 RB_Generate_Index_Table (dest, CONSTANT_HEADER, "Constants");
1459 if (RB_Number_Of_Links (GENERIC_HEADER, NULL))
1460 RB_Generate_Index_Table (dest, GENERIC_HEADER, "Generic");
1461 if (RB_Number_Of_Links (INTERNAL_HEADER, NULL))
1462 RB_Generate_Index_Table (dest, INTERNAL_HEADER, "Internal");
1463 RB_Generate_Doc_End (dest, source);
1467 RB_Generate_Doc_Start (dest, source, "Master File", 0);
1468 RB_Generate_LaTeX_Includes (dest);
1469 RB_Generate_Doc_End (dest, source);
1475 /****f* ROBODoc/Generate_LaTeX_Includes
1477 * Generate_LaTeX_Includes -- generate include commands
1479 * void RB_Generate_LaTeX_Includes (FILE *dest)
1481 * Generates a series of \include commands to include the
1482 * documentation generated for each source file into one
1488 RB_Generate_LaTeX_Includes (FILE *dest)
1490 struct RB_link *cur_link;
1491 for (cur_link = first_link;
1493 cur_link = cur_link->next_link) {
1495 if (cur_link->type == NO_HEADER)
1496 fprintf (dest, "\\include{%s}\n", cur_link->label_name);
1501 /****f* ROBODoc/RB_Generate_Index_Table
1503 * RB_Generate_Index --
1505 * void RB_Generate_Index_Table(FILE *, int type, char *title)
1506 * RB_Generate_Index_Table(dest, type, title)
1508 * Creates a table with index items of a particular type.
1509 * If the type is NO_HEADER, then the table is a table of
1510 * source files. In this case no link is added if the
1511 * source file did not contain any documentation.
1513 * dest -- output file
1514 * type -- kind of header index.
1515 * title -- title for the table
1520 RB_Generate_Index_Table (FILE * dest, int type, char *title)
1522 struct RB_link *cur_link;
1523 int number_of_columns;
1526 number_of_columns = 60 / RB_Max_Name_Length (type, NULL);
1528 fprintf (dest, "<H2>%s</H2>\n", title);
1529 fprintf (dest, "<TABLE>\n");
1531 for (cur_link = first_link;
1533 cur_link = cur_link->next_link)
1535 if (cur_link->type == type)
1537 if (cur_column == 0)
1539 fprintf (dest, "<TR>\n");
1541 if (type == NO_HEADER)
1543 if (RB_Number_Of_Links (NO_HEADER, cur_link->file_name) > 1)
1546 "<TD><A HREF=\"%s#%s\"><TT>%s</TT></A></TD>\n",
1547 cur_link->file_name, cur_link->label_name,
1548 cur_link->label_name);
1552 fprintf (dest, "<TD>%s</TD>\n", cur_link->label_name);
1557 fprintf (dest, "<TD><A HREF=\"%s#%s\"><TT>%s</TT></A></TD>\n",
1558 cur_link->file_name, cur_link->label_name,
1559 cur_link->label_name);
1562 if (cur_column > number_of_columns)
1564 fprintf (dest, "</TR>\n");
1569 for (; cur_column <= number_of_columns;)
1571 if (cur_column == 0)
1573 fprintf (dest, "<TR>\n");
1575 fprintf (dest, "<TD></TD>\n");
1578 fprintf (dest, "</TR>\n");
1579 fprintf (dest, "</TABLE>\n");
1582 /******* END RB_Generate_Index_Table *****/
1585 /****f* ROBODoc/RB_Number_Of_Links
1587 * RB_Number_Of_Links -- Count the number of links.
1589 * Counts the number of links that are of a particular type
1590 * and that can be found in a particular file.
1592 * type -- the header type of the header the link is pointing to.
1593 * If NO_HEADER, all header types are counted.
1594 * file_name -- name of the file the link comes from, can be NULL, in
1595 * which case only the type is checked.
1602 RB_Number_Of_Links (int type, char *file_name)
1604 struct RB_link *cur_link;
1607 for (cur_link = first_link;
1609 cur_link = cur_link->next_link)
1611 if (cur_link->type == type || (type == NO_HEADER))
1615 if (strcmp (file_name, cur_link->file_name) == 0)
1631 /****f* ROBODoc/RB_Max_Name_Length
1633 * RB_Max_Name_Length -- find longest label name.
1635 * Find the length of the longest label name in a sub list
1636 * of the list with links. This is used to determine how
1637 * many columns can be displayed in a table.
1638 * The sublist is specified by the type of header the link
1639 * should point to, as well as by the name of the documentation
1642 * RB_Max_Name_Length(CLASS_HEADER, "muppets.c.html")
1643 * longest label name in the list of links to class headers
1644 * in muppets.c.html.
1645 * RB_Max_Name_Length(CLASS_HEADER, NULL)
1646 * longest label name in the list of links to class headers.
1648 * type -- type of header
1649 * file_name -- file the header come from, can be NULL.
1650 * In which links from all files are used.
1655 RB_Max_Name_Length (int type, char *file_name)
1657 struct RB_link *cur_link;
1660 for (cur_link = first_link;
1662 cur_link = cur_link->next_link)
1664 if (cur_link->type == type)
1668 if (strcmp (file_name, cur_link->file_name) == 0)
1670 if (strlen (cur_link->label_name) > n)
1672 n = strlen (cur_link->label_name);
1678 if (strlen (cur_link->label_name) > n)
1680 n = strlen (cur_link->label_name);