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 RB_Generate_Header_Start (dest_doc, cur_header);
73 next_line = cur_header->contents;
74 item_type = RB_Find_Item (&next_line, &item_line);
76 if (item_type != NO_ITEM)
83 if (course_of_action & DO_TELL)
84 printf ("[%s] ", item_names[item_type]);
86 if (!((item_type == SOURCE_ITEM) &&
87 (course_of_action & DO_NOSOURCE)))
88 RB_Generate_Item_Name (dest_doc, item_type);
90 old_next_line = next_line;
91 old_item_type = item_type;
93 item_type = RB_Find_Item (&next_line, &item_line);
95 if (!((old_item_type == SOURCE_ITEM) &&
96 (course_of_action & DO_NOSOURCE)))
97 RB_Generate_Item_Doc (dest_doc, dest_name,
98 old_next_line, item_line,
99 cur_header->function_name,
102 while (item_type != NO_ITEM);
103 if (course_of_action & DO_TELL)
107 printf ("%s: WARNING, header \"%s\" has no items\n",
108 whoami, cur_header->name);
110 RB_Generate_Header_End (dest_doc, cur_header);
114 RB_Generate_Doc_End (dest_doc, dest_name);
117 /***** RB_Generate_Documentation ***/
123 /****f* ROBODoc/RB_Generate_Doc_Start [3.0j]
125 * RB_Generate_Doc_Start -- Generate document header.
127 * RB_Generate_Doc_Start (dest_doc, src_name, name, toc)
129 * RB_Generate_Doc_Start (FILE *, char *, char *, char)
131 * Generates for depending on the output_mode the text that
132 * will be at the start of a document.
133 * Including the table of contents.
135 * dest_doc - pointer to the file to which the output will
137 * src_name - the name of the source file.
138 * name - the name of this file.
139 * output_mode - global variable that indicates the output
141 * toc - generate table of contens
143 * RB_Generate_Doc_End
148 RB_Generate_Doc_Start (
149 FILE * dest_doc, char *src_name, char *name, char toc)
151 struct RB_header *cur_header;
152 int cur_len, max_len, header_nr;
157 if (strstr (name + 1, ".guide") == NULL)
158 fprintf (dest_doc, "@database %s.guide\n", name);
160 fprintf (dest_doc, "@database %s\n", name);
161 fprintf (dest_doc, "@rem Source: %s\n", src_name);
162 fprintf (dest_doc, "@rem " COMMENT_ROBODOC);
163 fprintf (dest_doc, "@rem " COMMENT_COPYRIGHT);
164 fprintf (dest_doc, "@node Main %s\n", name);
165 fprintf (dest_doc, "@{jcenter}\n");
167 "@{fg highlight}@{b}TABLE OF CONTENTS@{ub}@{fg text}\n\n");
170 for (cur_header = first_header;
172 cur_header = cur_header->next_header)
174 if (cur_header->name)
176 cur_len = strlen (cur_header->name);
177 if (cur_len > max_len)
182 for (cur_header = first_header;
184 cur_header = cur_header->next_header)
186 if (cur_header->name && cur_header->function_name)
188 fprintf (dest_doc, "@{\"%s", cur_header->name);
190 for (cur_len = strlen (cur_header->name);
193 fputc (' ', dest_doc);
194 fprintf (dest_doc, "\" Link \"%s\"}\n", cur_header->function_name);
198 fprintf (dest_doc, "@{jleft}\n");
199 fprintf (dest_doc, "@endnode\n");
203 /* Append document type and title */
205 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
206 fprintf (dest_doc, "<HTML><HEAD>\n<TITLE>%s</TITLE>\n", name);
208 /* append SGML-comment with document- and copyright-info. This code
209 * ensures that every line has an own comment to avoid problems with
211 fprintf (dest_doc, "<!-- Source: %s -->\n", src_name);
213 static const char copyright_text[]
214 = COMMENT_ROBODOC COMMENT_COPYRIGHT;
216 char previous_char = '\n';
217 char current_char = copyright_text[i];
221 if (previous_char == '\n')
223 fprintf (dest_doc, "<!-- ");
225 if (current_char == '\n')
227 fprintf (dest_doc, " -->");
229 else if ((current_char == '-') && (previous_char == '-'))
231 /* avoid "--" inside SGML-comment, and use "-_" instead; this
232 * looks a bit strange, but one should still be able to figure
233 * out what is meant when reading the output */
236 fputc (current_char, dest_doc);
238 previous_char = current_char;
239 current_char = copyright_text[i];
243 /* append heading and start list of links to functions */
244 fprintf (dest_doc, "</HEAD><BODY BGCOLOR=\"#FFFFFF\">\n");
246 fprintf (dest_doc, "<A NAME=\"%s\">Generated from %s</A> with ROBODoc v"
250 RB_TimeStamp (dest_doc);
252 fprintf (dest_doc, "<BR>\n");
259 /* do toc if not in fold */
262 "<H3 ALIGN=\"center\">TABLE OF CONTENTS</H3>\n");
264 fprintf (dest_doc, "<OL>\n");
266 /* Generate quick index file, for fast referencing */
267 sprintf(iname, "%s_index.tmpl", doc_base);
268 index = fopen(iname, "w");
270 for (cur_header = first_header;
272 cur_header = cur_header->next_header)
276 sprintf(fname, "%s_%s.html", doc_base,
277 cur_header->function_name);
279 if (cur_header->name && cur_header->function_name)
284 char *next_line, *item_line = NULL;
286 RB_Generate_Header_Start (dest_doc, cur_header);
288 next_line = cur_header->contents;
289 item_type = RB_Find_Item (&next_line, &item_line);
291 if (item_type != NO_ITEM)
298 if (course_of_action & DO_TELL)
299 printf ("[%s] ", item_names[item_type]);
301 if (!((item_type == SOURCE_ITEM) &&
302 (course_of_action & DO_NOSOURCE)))
303 RB_Generate_Item_Name (dest_doc, item_type);
305 old_next_line = next_line;
306 old_item_type = item_type;
308 item_type = RB_Find_Item (&next_line,
311 if (!((old_item_type == SOURCE_ITEM) &&
312 (course_of_action & DO_NOSOURCE)))
313 RB_Generate_Item_Doc(dest_doc, name,
314 old_next_line, item_line,
315 cur_header->function_name,
318 while (item_type != NO_ITEM);
319 if (course_of_action & DO_TELL)
325 fprintf (index, " >> <A HREF=\"%s\">%s</A><BR>\n",
326 name, cur_header->function_name);
333 fprintf (dest_doc, "<LI><A HREF=\"%s\">%s</A>\n",
334 fname, cur_header->name);
336 fprintf (index, " >> <A HREF=\"%s\">%s</A><BR>\n",
337 fname, cur_header->function_name);
342 fprintf (dest_doc, "</OL>\n");
350 fprintf (dest_doc, "%% Document: %s\n", name);
351 fprintf (dest_doc, "%% Source: %s\n", src_name);
352 fprintf (dest_doc, "%% " COMMENT_ROBODOC);
353 fprintf (dest_doc, "%% " COMMENT_COPYRIGHT);
354 if (course_of_action & DO_SINGLEDOC) {
355 fprintf (dest_doc, "\\section{%s}\n", src_name);
357 fprintf (dest_doc, "\\documentclass{article}\n");
358 fprintf (dest_doc, "\\usepackage{makeidx}\n");
359 fprintf (dest_doc, "\\oddsidemargin 0.15 in\n");
360 fprintf (dest_doc, "\\evensidemargin 0.35 in\n");
361 fprintf (dest_doc, "\\marginparwidth 1 in \n");
362 fprintf (dest_doc, "\\oddsidemargin 0.25 in \n");
363 fprintf (dest_doc, "\\evensidemargin 0.25 in\n");
364 fprintf (dest_doc, "\\marginparwidth 0.75 in\n");
365 fprintf (dest_doc, "\\textwidth 5.875 in\n");
367 fprintf (dest_doc, "\\setlength{\\parindent}{0in}\n");
368 fprintf (dest_doc, "\\setlength{\\parskip}{.08in}\n\n");
370 /* changed default header to use boldface (vs slant) */
371 fprintf (dest_doc, "\\pagestyle{headings}\n");
373 if (document_title) {
374 fprintf (dest_doc, "\\title{%s}\n",
377 fprintf (dest_doc, "\\title{API Reference}\n");
379 fprintf (dest_doc, "\\author{%s}\n", COMMENT_ROBODOC);
380 fprintf (dest_doc, "\\makeindex\n");
381 fprintf (dest_doc, "\\begin{document}\n");
382 fprintf (dest_doc, "\\maketitle\n");
383 /* autogenerate table of contents! */
384 fprintf (dest_doc, "\\printindex\n");
385 fprintf (dest_doc, "\\tableofcontents\n");
386 fprintf (dest_doc, "\\newpage\n");
387 /* trick to disable the autogenerated \newpage */
388 fprintf (dest_doc, "\n");
397 fprintf (dest_doc, "{\\rtf1\\ansi \\deff0"
399 "\\f0\\fswiss MS Sans Serif;"
400 "\\f1\\fmodern Courier New;"
401 "\\f2\\ftech Symbol;"
404 "\\red255\\green255\\blue255;"
405 "\\red0\\green0\\blue0;"
406 "\\red0\\green0\\blue255;"
409 /* RTF document info */
410 fprintf (dest_doc, "{\\info"
415 " " COMMENT_COPYRIGHT
417 "}", name, src_name);
419 /* RTF document format */
420 fprintf (dest_doc, "{\\margl1440\\margr1440}\n");
422 /* RTF document section */
423 fprintf (dest_doc, "\\f0\\cb1\\cf3\\fs28\\b1\\qc"
424 "{\\super #{\\footnote{\\super #}%s_TOC}}"
425 "{\\super ${\\footnote{\\super $}Contents}}"
426 "{TABLE OF CONTENTS}\\ql\\b0\\fs20\\cf2\\par\n", src_name);
427 for (cur_header = first_header;
429 cur_header = cur_header->next_header)
431 if (cur_header->name && cur_header->function_name)
433 cook_link = RB_CookStr (cur_header->function_name);
434 fprintf (dest_doc, "{\\uldb %s}{\\v %s}\\line\n",
435 cur_header->name, cook_link);
439 fprintf (dest_doc, "\\par\n");
443 if (course_of_action & DO_TOC)
445 fprintf (dest_doc, "TABLE OF CONTENTS\n");
446 for (cur_header = first_header, header_nr = 1;
448 cur_header = cur_header->next_header, header_nr++)
450 if (cur_header->name && cur_header->function_name)
452 fprintf (dest_doc, "%4.4d %s\n",
453 header_nr, cur_header->name);
456 fputc ('\f', dest_doc);
466 /****f* ROBODoc/RB_Generate_Doc_End [3.0h]
468 * RB_Generate_Doc_End -- generate document trailer.
470 * RB_Generate_Doc_End (dest_doc, name)
472 * RB_Generate_Doc_End (FILE *, char *)
474 * Generates for depending on the output_mode the text that
475 * will be at the end of a document.
477 * dest_doc - pointer to the file to which the output will
479 * name - the name of this file.
480 * output_mode - global variable that indicates the output
483 * Doesn't do anything with its arguments, but that might
484 * change in the future.
490 RB_Generate_Doc_End (FILE * dest_doc, char *name)
495 fputc ('\n', dest_doc);
498 fprintf (dest_doc, "</BODY></HTML>\n");
501 if (!(course_of_action & DO_SINGLEDOC)) {
502 fprintf (dest_doc, "\\end{document}\n");
506 fputc ('}', dest_doc);
516 /****f* ROBODoc/RB_Generate_Header_Start [3.0h]
518 * RB_Generate_Header_Start -- generate header start text.
520 * void RB_Generate_Header_Start (dest_doc, cur_header)
522 * void RB_Generate_Header_Start (FILE *, struct RB_header *)
524 * Generates depending on the output_mode the text that
525 * will be at the end of each header.
527 * dest_doc - pointer to the file to which the output will
529 * cur_header - pointer to a RB_header structure.
531 * RB_Generate_Header_End
536 RB_Generate_Header_Start (FILE * dest_doc, struct RB_header *cur_header)
541 { /* switch by *koessi */
543 if (cur_header->name && cur_header->function_name)
545 fprintf (dest_doc, "@Node \"%s\" \"%s\"\n",
546 cur_header->function_name,
548 fprintf (dest_doc, "%s", att_start_command[MAKE_SHINE][output_mode]);
549 fprintf (dest_doc, "%s", cur_header->name);
550 fprintf (dest_doc, "%s", att_stop_command[MAKE_SHINE][output_mode]);
551 fprintf (dest_doc, "\n\n");
555 if (cur_header->name && cur_header->function_name)
558 fprintf (dest_doc, "<HR>\n");
560 if (cur_header->type == FUNCTION_HEADER)
562 "\n<FONT SIZE=\"+3\" COLOR=\"#000044\"><B>"
563 "Function <A NAME=\"%s\">%s</A>"
564 "</FONT></B><BR><BR>\n\n",
565 cur_header->function_name,
566 cur_header->function_name);
567 else if (cur_header->type == STRUCT_HEADER)
569 "\n<FONT SIZE=\"+3\" COLOR=\"#000044\"><B>"
570 "Structure <A NAME=\"%s\">%s</A>"
571 "</FONT></B><BR><BR>\n\n",
572 cur_header->function_name,
573 cur_header->function_name);
574 else if (cur_header->type == VARIABLE_HEADER)
576 "\n<FONT SIZE=\"+3\" COLOR=\"#000044\"><B>"
577 "Variable <A NAME=\"%s\">%s</A>"
578 "</FONT></B><BR><BR>\n\n",
579 cur_header->function_name,
580 cur_header->function_name);
583 "\n<FONT SIZE=\"+3\" COLOR=\"#000044\"><B>"
584 "<A NAME=\"%s\">%s</A>"
585 "</FONT></B><BR><BR>\n\n",
586 cur_header->function_name,
587 cur_header->function_name);
591 cook_link = RB_CookStr (cur_header->name);
592 if (!(course_of_action & DO_SINGLEDOC)) {
593 fprintf (dest_doc, "\\newpage\n");
595 fprintf (dest_doc, "\\subsection{%s}\n", cook_link);
597 if (cur_header->function_name) {
598 cook_link = RB_CookStr (cur_header->function_name);
599 fprintf (dest_doc, "\\index{unsorted!%s}\\index{%s!%s}\n", cook_link,
600 RB_header_type_names[cur_header->type], cook_link);
605 if (cur_header->name && cur_header->function_name)
607 cook_link = RB_CookStr (cur_header->function_name);
608 fprintf (dest_doc, "\\page"
609 "{\\super #{\\footnote{\\super #}%s}}"
610 "{\\super ${\\footnote{\\super $}%s}}"
611 "\\cf3 %s\\cf2\\line\n",
612 cur_header->function_name,
620 fprintf (dest_doc, "%s", att_start_command[MAKE_SHINE][output_mode]);
621 fprintf (dest_doc, "%s", cur_header->name);
622 fprintf (dest_doc, "%s", att_stop_command[MAKE_SHINE][output_mode]);
623 fprintf (dest_doc, "\n\n");
632 /****f* ROBODoc/RB_Generate_Header_End [3.0h]
634 * RB_Generate_Header_End
636 * void RB_Generate_Header_End (dest_doc, cur_header)
638 * void RB_Generate_Header_End (FILE *, struct RB_header *)
640 * Generates for depending on the output_mode the text that
641 * will be at the end of a header.
643 * dest_doc - pointer to the file to which the output will
645 * cur_header - pointer to a RB_header structure.
647 * RB_Generate_Header_Start
652 RB_Generate_Header_End (FILE * dest_doc, struct RB_header *cur_header)
655 { /* switch by *koessi */
657 if (cur_header->name && cur_header->function_name)
658 fprintf (dest_doc, "@endnode\n");
662 fputc ('\n', dest_doc);
665 fprintf (dest_doc, "\\par\n");
668 fputc ('\f', dest_doc);
677 /****f* ROBODoc/RB_Generate_Header_Name [3.0c]
679 * RB_Generate_Header_Name
681 * RB_Generate_Header_Name (dest_doc, name)
683 * RB_Generate_Header_Name (FILE *, char *)
685 * dest_doc - pointer to the file to which the output will
687 * name - pointer to the header name.
692 RB_Generate_Header_Name (FILE * dest_doc, char *name)
694 char format_str[] = "%s";
696 fprintf (dest_doc, format_str, att_start_command[MAKE_SHINE][output_mode]);
697 fprintf (dest_doc, format_str, name);
698 fprintf (dest_doc, format_str, att_stop_command[MAKE_SHINE][output_mode]);
699 fprintf (dest_doc, "\n\n");
702 /*** RB_Generate_Header_Name ***/
705 /****** ROBODoc/RB_Generate_Item_Name [2.01]
707 * RB_Generate_Item_Name -- fast&easy
709 * void RB_Generate_Item_Name( FILE * dest_doc, int item_type )
711 * write the items name to the doc
713 * FILE * dest_doc -- document in progress
714 * int item_type -- this leads to the name and makes colors
718 * uses globals: output_mode, item_names[]
723 RB_Generate_Item_Name (FILE * dest_doc, int item_type)
725 char format_str[] = "%s";
727 if (item_attributes[item_type] & ITEM_NAME_LARGE_FONT)
729 fprintf (dest_doc, format_str,
730 att_start_command[MAKE_LARGE][output_mode]);
731 fprintf (dest_doc, format_str,
732 att_start_command[MAKE_BOLD][output_mode]);
733 if (output_mode == HTML)
734 fprintf (dest_doc, "\n<FONT COLOR=\"#000044\">");
735 fprintf (dest_doc, format_str, item_names[item_type]);
736 if (output_mode == HTML)
737 fprintf (dest_doc, "\n</FONT>");
738 fprintf (dest_doc, format_str,
739 att_stop_command[MAKE_BOLD][output_mode]);
740 fprintf (dest_doc, format_str,
741 att_stop_command[MAKE_LARGE][output_mode]);
744 fprintf (dest_doc, format_str, item_names[item_type]);
746 fputc ('\n', dest_doc);
753 /****f* ROBODoc/RB_Generate_Item_Doc [3.0j]
755 * RB_Generate_Item_Doc
757 * void RB_Generate_Item_Doc(FILE * dest_doc, char *dest_name,
758 * char *begin_of_item,
760 * char *function_name,
763 * Generates the body text of an item, applying predefined attributes
766 * Body text is always non-proportional for several reasons:
767 * 1) text is rarely written with prop spacing and text wrapping
768 * in mind -- e.g., see SYNOPSIS above
769 * 2) source code looks better
770 * 3) it simplifies LaTeX handling
775 RB_Generate_Item_Doc (FILE * dest_doc, char *dest_name,
781 char format_str[] = "%s";
783 if (begin_of_item == end_of_item)
788 fprintf (dest_doc, "<BR>\n");
791 fprintf (dest_doc, "\\\\\n");
794 fprintf (dest_doc, "\n");
801 /* For text body in HTML, change to non-prop _before_ changing font
802 * style. * To conform to DTD, this avoids <B><PRE> and instead uses
804 if (output_mode == HTML)
806 fprintf (dest_doc, "<PRE>");
808 /* change font style */
809 if (item_attributes[item_type] & TEXT_BODY_LARGE_FONT)
810 fprintf (dest_doc, format_str,
811 att_start_command[MAKE_LARGE][output_mode]);
812 if (item_attributes[item_type] & TEXT_BODY_ITALICS)
813 fprintf (dest_doc, format_str,
814 att_start_command[MAKE_ITALICS][output_mode]);
815 if (item_attributes[item_type] & TEXT_BODY_NON_PROP)
816 fprintf (dest_doc, format_str,
817 att_start_command[MAKE_NON_PROP][output_mode]);
818 if (item_attributes[item_type] & TEXT_BODY_SMALL_FONT)
819 fprintf (dest_doc, format_str,
820 att_start_command[MAKE_SMALL][output_mode]);
821 if (item_attributes[item_type] & TEXT_BODY_BOLD)
822 fprintf (dest_doc, format_str,
823 att_start_command[MAKE_BOLD][output_mode]);
824 if (item_attributes[item_type] & TEXT_BODY_UNDERLINE)
825 fprintf (dest_doc, format_str,
826 att_start_command[MAKE_UNDERLINE][output_mode]);
827 if (item_attributes[item_type] & TEXT_BODY_SHINE)
828 fprintf (dest_doc, format_str,
829 att_start_command[MAKE_SHINE][output_mode]);
832 * For some modes, the text body is always non-prop
837 fprintf (dest_doc, "\\begin{verbatim}\n");
840 fprintf (dest_doc, "{\\f1{}");
846 RB_Generate_Item_Body (dest_doc, dest_name, begin_of_item, end_of_item,
847 function_name, item_type, 0);
852 /* split the text so LaTeX doesn't get confused ;) */
853 fprintf (dest_doc, "\\" "end{verbatim}\n");
856 fputc ('}', dest_doc);
861 /* restore font style */
862 if (item_attributes[item_type] & TEXT_BODY_SHINE)
863 fprintf (dest_doc, format_str,
864 att_stop_command[MAKE_SHINE][output_mode]);
865 if (item_attributes[item_type] & TEXT_BODY_UNDERLINE)
866 fprintf (dest_doc, format_str,
867 att_stop_command[MAKE_UNDERLINE][output_mode]);
868 if (item_attributes[item_type] & TEXT_BODY_BOLD)
869 fprintf (dest_doc, format_str,
870 att_stop_command[MAKE_BOLD][output_mode]);
871 if (item_attributes[item_type] & TEXT_BODY_SMALL_FONT)
872 fprintf (dest_doc, format_str,
873 att_stop_command[MAKE_SMALL][output_mode]);
874 if (item_attributes[item_type] & TEXT_BODY_NON_PROP)
875 fprintf (dest_doc, format_str,
876 att_stop_command[MAKE_NON_PROP][output_mode]);
877 if (item_attributes[item_type] & TEXT_BODY_ITALICS)
878 fprintf (dest_doc, format_str,
879 att_stop_command[MAKE_ITALICS][output_mode]);
880 if (item_attributes[item_type] & TEXT_BODY_LARGE_FONT)
881 fprintf (dest_doc, format_str,
882 att_stop_command[MAKE_LARGE][output_mode]);
884 if (output_mode != HTML)
886 fputc ('\n', dest_doc);
888 /* for HTML, switch back to prop-font after restoring font style */
889 if (output_mode == HTML)
891 fprintf (dest_doc, "</PRE>");
899 /****f* ROBODoc/RB_Generate_Item_Body [3.0h]
901 * RB_Generate_Item_Body
903 * char * RB_Generate_Item_Body(FILE * dest_doc, char *dest_name,
904 * char *begin_of_item, char *end_of_item,
905 * char *function_name,
906 * int item_type, int tabs_to_skip)
909 * Generates body of an item in output-specific form
911 * dest_doc - pointer to the file to which
912 * the output will be written.
913 * dest_name - the name of this file.
918 * tabs_to_skip - how many tabs to skip in this fold.
920 * o Unbalanced fold marks lead to crash.
922 * o Almost completely rewritten by koessi
923 * o Almost completely Re-Rewritten by Slothouber :)
924 * o Folding mode by PetteriK.
925 * o Linking fixed inside folds / PetteriK 08.04.2000
930 RB_Generate_Item_Body (FILE * dest_doc, char *dest_name,
931 char *begin_of_item, char *end_of_item,
933 int item_type, int tabs_to_skip)
935 char *cur_char, old_char, c;
937 char fname[128], foldname[128];
938 static int in_fold = 0; /* PetteriK 08.04.2000 */
940 cur_char = begin_of_item;
942 if (item_type == SOURCE_ITEM)
944 /* skip end_comment_marker */
945 for (; *cur_char && *cur_char != '\n'; cur_char++);
947 /* skip blank lines leading up to source code */
948 while (*cur_char == '\n')
951 /* trim blanks following source code */
956 while (end_of_item > cur_char && isspace (*end_of_item));
957 end_of_item++; /* advance 1 for placement of the NUL */
959 old_char = *end_of_item;
962 for (; *cur_char; cur_char++)
965 int do_search = TRUE;
966 int was_link = FALSE;
969 if (item_type != SOURCE_ITEM)
971 /* Skip empty lines */
972 while (*cur_char == '\n') {
975 cur_char = RB_Skip_Remark_Marker (cur_char);
983 fprintf (dest_doc, "\\tab ");
990 fprintf (dest_doc, " ");
994 while (((c = *cur_char) != '\0') && (c != '\n'))
996 char *label_name, *file_name;
1002 if (!isalnum (c) && (c != '_'))
1009 if (isalpha (c) || (c == '_'))
1011 if (((was_link = RB_Find_Link (cur_char, &label_name,
1012 &file_name)) == FALSE))
1023 switch (output_mode)
1032 for (tb %= tab_size; tb < tab_size; ++tb)
1033 fputc (' ', dest_doc);
1036 fprintf (dest_doc, "\\@");
1040 fprintf (dest_doc, "\\\\");
1044 fputc (c, dest_doc);
1050 /* PetteriK 26.07.1999 */
1051 if (extra_flags & FOLD)
1053 cur_char = RB_Check_Fold_Start (cur_char,
1056 if ((extra_flags & FOLD) && found)
1060 RB_Say ("fold name %s\n", foldname);
1061 RB_Say ("fold begin %d\n", ++fold);
1062 RB_Say ("tabs %d\n", tabs);
1063 sprintf (fname, "%s_fold_%d.html", doc_base, fold);
1064 RB_Say ("opening file %s\n", fname);
1065 fp = fopen (fname, "w");
1066 RB_Generate_Doc_Start (fp, foldname, foldname, 0);
1067 fprintf (fp, "<PRE>\n");
1068 fprintf (dest_doc, "<A HREF=\"%s\">... %s</A>",
1070 in_fold++; /* PetteriK 08.04.2000 */
1071 cur_char = RB_Generate_Item_Body (fp, dest_name,
1072 cur_char, end_of_item,
1075 in_fold--; /* PetteriK 08.04.2000 */
1076 /* skip chars until newline */
1077 while (*cur_char != '\n')
1082 fprintf (fp, "\n</PRE>\n");
1083 RB_Generate_Doc_End (fp, foldname);
1086 else if ((extra_flags & FOLD) && RB_Check_Fold_End (cur_char))
1088 RB_Say ("fold end found\n");
1091 else if ((html_incr = RB_HTML_Extra (dest_doc,
1092 item_type, cur_char)))
1094 cur_char += html_incr;
1104 if (extra_flags & FOLD)
1106 if (tabs >= tabs_to_skip)
1108 for (tb %= tab_size; tb < tab_size; ++tb)
1110 fputc (' ', dest_doc);
1117 for (tb %= tab_size; tb < tab_size; ++tb)
1119 fputc (' ', dest_doc);
1124 fprintf (dest_doc, "<");
1128 fprintf (dest_doc, ">");
1132 fprintf (dest_doc, "&");
1136 fputc (c, dest_doc);
1140 break; /* end case HTML */
1149 for (tb %= tab_size; tb < tab_size; ++tb)
1150 fputc (' ', dest_doc);
1153 /* not used in LaTeX's verbatim environment */
1161 fputc ('\\', dest_doc);
1162 fputc (c, dest_doc);
1166 fprintf (dest_doc, "$\\backslash$");
1170 fprintf (dest_doc, "$\\tilde$");
1174 fprintf (dest_doc, "$\\,\\!^{\\sim}$");
1179 fputc (c, dest_doc);
1191 for (tb %= tab_size; tb < tab_size; ++tb)
1192 fputc (' ', dest_doc);
1197 fputc ('\\', dest_doc);
1198 fputc (c, dest_doc);
1202 fputc (c, dest_doc);
1208 fputc (c, dest_doc);
1215 switch (output_mode)
1218 if (file_name && strcmp (file_name, dest_name))
1219 fprintf (dest_doc, "@{\"%s\" Link \"%s/%s\"}",
1220 label_name, file_name, label_name);
1223 if (strcmp (label_name, function_name))
1224 fprintf (dest_doc, "@{\"%s\" Link \"%s\"}",
1225 label_name, label_name);
1228 fprintf (dest_doc, "%s",
1229 att_start_command[MAKE_BOLD][output_mode]);
1230 fprintf (dest_doc, "%s", label_name);
1231 fprintf (dest_doc, "%s",
1232 att_stop_command[MAKE_BOLD][output_mode]);
1238 /* Include the file name in the link if we are in fold
1239 * PetteriK 08.04.2000
1243 /* We are in fold, always use the file name in the link,
1244 * in file_name == NULL (i.e. the label is in the current file
1245 * that we are processing), refer to value in dest_name.
1246 * This also makes sure that we link correctly if function_name
1247 * is the same as label_name.
1249 fprintf (dest_doc, "<A HREF=\"%s#%s\">%s</A>",
1250 (file_name ? file_name : dest_name),
1251 label_name, label_name);
1253 else if (file_name && strcmp (file_name, dest_name))
1255 fprintf (dest_doc, "<A HREF=\"%s#%s\">%s</A>",
1256 file_name, label_name, label_name);
1260 if (strcmp (label_name, function_name))
1263 fprintf (dest_doc, "<A HREF=\"#%s\">%s</A>",
1264 label_name, label_name);
1266 fprintf (dest_doc, "<A HREF=\"%s_%s.html\">%s</A>",
1267 doc_base, label_name, label_name);
1271 fprintf (dest_doc, "%s",
1272 att_start_command[MAKE_BOLD][output_mode]);
1273 fprintf (dest_doc, "%s", label_name);
1274 fprintf (dest_doc, "%s",
1275 att_stop_command[MAKE_BOLD][output_mode]);
1281 if (strcmp (label_name, function_name))
1285 cook_link = RB_CookStr (label_name);
1286 fprintf (dest_doc, "{\\uldb %s}{\\v %s}",
1287 label_name, cook_link);
1292 fprintf (dest_doc, "%s",
1293 att_start_command[MAKE_BOLD][output_mode]);
1294 fprintf (dest_doc, "%s", label_name);
1295 fprintf (dest_doc, "%s",
1296 att_stop_command[MAKE_BOLD][output_mode]);
1300 fprintf (dest_doc, "%s", label_name);
1302 tmp = strlen (label_name);
1310 if (output_mode == RTF)
1311 fprintf (dest_doc, "\\line");
1312 fputc ('\n', dest_doc);
1316 *end_of_item = old_char;
1324 /****f* ROBODoc/RB_HTML_Extra
1330 * 05/15/2000 Added mailto: support (Guillaume Etorre)
1332 * Check and process embedded hyperlinks.
1333 * RETURN VAL* FUNCTION
1334 * Check and process embedded hyperlinks.
1336 * Number of chars processed from *cur_char
1338 * Flag for C and other grammars.
1340 * As the documentation generated for this functions shows, if
1341 * the C source code contains a string with " / * " in it, this
1347 RB_HTML_Extra (FILE * dest_doc, int item_type, char *cur_char)
1352 if (strncmp ("http://", cur_char, strlen ("http://")) == 0)
1354 sscanf (cur_char, "%s", link);
1355 RB_Say ("found link %s\n", link);
1356 res = (strlen (link) - 1);
1357 fprintf (dest_doc, "<A HREF=\"%s\">%s</A>", link, link);
1359 else if (strncmp ("href:", cur_char, strlen ("href:")) == 0)
1361 /* handy in relative hyperlink paths, e.g. href:../../modulex/ */
1362 sscanf ((cur_char + strlen ("href:")), "%s", link);
1363 RB_Say ("found link %s\n", link);
1364 res = (strlen (link) + strlen ("href:") - 1);
1365 fprintf (dest_doc, "<A HREF=\"%s\">%s</A>", link, link);
1367 else if (strncmp ("mailto:", cur_char, strlen ("mailto:")) == 0)
1369 sscanf ((cur_char + strlen ("mailto:")), "%s", link);
1370 RB_Say ("found mail to %s\n", link);
1371 res = (strlen (link) + strlen ("mailto:") - 1);
1372 fprintf (dest_doc, "<A HREF=\"mailto:%s\">%s</A>", link, link);
1374 else if ((extra_flags & C_MODE) && (item_type == SOURCE_ITEM) &&
1375 (strncmp ("/*", cur_char, 2) == 0))
1377 /* start of C comment */
1378 fprintf (dest_doc, "<FONT COLOR = \"#FF0000\">/*");
1381 else if ((extra_flags & C_MODE) && (item_type == SOURCE_ITEM) &&
1382 (strncmp ("*/", cur_char, 2) == 0))
1384 /* end of C comment */
1385 fprintf (dest_doc, "*/</FONT>");
1394 /****f* ROBODoc/RB_Generate_Index
1396 * RB_Generate_Index -- generate index file based on xref files.
1398 * void RB_Generate_Index(FILE *dest, char *name)
1400 * Create a master index file. It contains pointers to the
1401 * documentation generated for each source file, as well as all
1402 * "objects" found in the source files.
1407 RB_Generate_Index (FILE * dest, char *source)
1409 RB_Slow_Sort_Links ();
1411 switch (output_mode)
1415 if (document_title) {
1416 RB_Generate_Doc_Start (dest, source, document_title, 0);
1417 fprintf (dest, "<H1>%s</H1>\n", document_title);
1419 RB_Generate_Doc_Start (dest, source, "Master Index File", 0);
1420 fprintf (dest, "<H1>Master Index File</H1>\n");
1422 if (RB_Number_Of_Links (MAIN_HEADER, NULL))
1423 RB_Generate_Index_Table (dest, MAIN_HEADER, "Project Modules");
1424 RB_Generate_Index_Table (dest, NO_HEADER, "Source Files");
1425 if (RB_Number_Of_Links (CLASS_HEADER, NULL))
1426 RB_Generate_Index_Table (dest, CLASS_HEADER, "Classes");
1427 if (RB_Number_Of_Links (METHOD_HEADER, NULL))
1428 RB_Generate_Index_Table (dest, METHOD_HEADER, "Methods");
1429 if (RB_Number_Of_Links (STRUCT_HEADER, NULL))
1430 RB_Generate_Index_Table (dest, STRUCT_HEADER, "Structures");
1431 if (RB_Number_Of_Links (FUNCTION_HEADER, NULL))
1432 RB_Generate_Index_Table (dest, FUNCTION_HEADER, "Functions");
1433 if (RB_Number_Of_Links (VARIABLE_HEADER, NULL))
1434 RB_Generate_Index_Table (dest, VARIABLE_HEADER, "Variables");
1435 if (RB_Number_Of_Links (CONSTANT_HEADER, NULL))
1436 RB_Generate_Index_Table (dest, CONSTANT_HEADER, "Constants");
1437 if (RB_Number_Of_Links (GENERIC_HEADER, NULL))
1438 RB_Generate_Index_Table (dest, GENERIC_HEADER, "Generic");
1439 if (RB_Number_Of_Links (INTERNAL_HEADER, NULL))
1440 RB_Generate_Index_Table (dest, INTERNAL_HEADER, "Internal");
1441 RB_Generate_Doc_End (dest, source);
1445 RB_Generate_Doc_Start (dest, source, "Master File", 0);
1446 RB_Generate_LaTeX_Includes (dest);
1447 RB_Generate_Doc_End (dest, source);
1453 /****f* ROBODoc/Generate_LaTeX_Includes
1455 * Generate_LaTeX_Includes -- generate include commands
1457 * void RB_Generate_LaTeX_Includes (FILE *dest)
1459 * Generates a series of \include commands to include the
1460 * documentation generated for each source file into one
1466 RB_Generate_LaTeX_Includes (FILE *dest)
1468 struct RB_link *cur_link;
1469 for (cur_link = first_link;
1471 cur_link = cur_link->next_link) {
1473 if (cur_link->type == NO_HEADER)
1474 fprintf (dest, "\\include{%s}\n", cur_link->label_name);
1479 /****f* ROBODoc/RB_Generate_Index_Table
1481 * RB_Generate_Index --
1483 * void RB_Generate_Index_Table(FILE *, int type, char *title)
1484 * RB_Generate_Index_Table(dest, type, title)
1486 * Creates a table with index items of a particular type.
1487 * If the type is NO_HEADER, then the table is a table of
1488 * source files. In this case no link is added if the
1489 * source file did not contain any documentation.
1491 * dest -- output file
1492 * type -- kind of header index.
1493 * title -- title for the table
1498 RB_Generate_Index_Table (FILE * dest, int type, char *title)
1500 struct RB_link *cur_link;
1501 int number_of_columns;
1504 number_of_columns = 60 / RB_Max_Name_Length (type, NULL);
1506 fprintf (dest, "<H2>%s</H2>\n", title);
1507 fprintf (dest, "<TABLE>\n");
1509 for (cur_link = first_link;
1511 cur_link = cur_link->next_link)
1513 if (cur_link->type == type)
1515 if (cur_column == 0)
1517 fprintf (dest, "<TR>\n");
1519 if (type == NO_HEADER)
1521 if (RB_Number_Of_Links (NO_HEADER, cur_link->file_name) > 1)
1524 "<TD><A HREF=\"%s#%s\"><TT>%s</TT></A></TD>\n",
1525 cur_link->file_name, cur_link->label_name,
1526 cur_link->label_name);
1530 fprintf (dest, "<TD>%s</TD>\n", cur_link->label_name);
1535 fprintf (dest, "<TD><A HREF=\"%s#%s\"><TT>%s</TT></A></TD>\n",
1536 cur_link->file_name, cur_link->label_name,
1537 cur_link->label_name);
1540 if (cur_column > number_of_columns)
1542 fprintf (dest, "</TR>\n");
1547 for (; cur_column <= number_of_columns;)
1549 if (cur_column == 0)
1551 fprintf (dest, "<TR>\n");
1553 fprintf (dest, "<TD></TD>\n");
1556 fprintf (dest, "</TR>\n");
1557 fprintf (dest, "</TABLE>\n");
1560 /******* END RB_Generate_Index_Table *****/
1563 /****f* ROBODoc/RB_Number_Of_Links
1565 * RB_Number_Of_Links -- Count the number of links.
1567 * Counts the number of links that are of a particular type
1568 * and that can be found in a particular file.
1570 * type -- the header type of the header the link is pointing to.
1571 * If NO_HEADER, all header types are counted.
1572 * file_name -- name of the file the link comes from, can be NULL, in
1573 * which case only the type is checked.
1580 RB_Number_Of_Links (int type, char *file_name)
1582 struct RB_link *cur_link;
1585 for (cur_link = first_link;
1587 cur_link = cur_link->next_link)
1589 if (cur_link->type == type || (type == NO_HEADER))
1593 if (strcmp (file_name, cur_link->file_name) == 0)
1609 /****f* ROBODoc/RB_Max_Name_Length
1611 * RB_Max_Name_Length -- find longest label name.
1613 * Find the length of the longest label name in a sub list
1614 * of the list with links. This is used to determine how
1615 * many columns can be displayed in a table.
1616 * The sublist is specified by the type of header the link
1617 * should point to, as well as by the name of the documentation
1620 * RB_Max_Name_Length(CLASS_HEADER, "muppets.c.html")
1621 * longest label name in the list of links to class headers
1622 * in muppets.c.html.
1623 * RB_Max_Name_Length(CLASS_HEADER, NULL)
1624 * longest label name in the list of links to class headers.
1626 * type -- type of header
1627 * file_name -- file the header come from, can be NULL.
1628 * In which links from all files are used.
1633 RB_Max_Name_Length (int type, char *file_name)
1635 struct RB_link *cur_link;
1638 for (cur_link = first_link;
1640 cur_link = cur_link->next_link)
1642 if (cur_link->type == type)
1646 if (strcmp (file_name, cur_link->file_name) == 0)
1648 if (strlen (cur_link->label_name) > n)
1650 n = strlen (cur_link->label_name);
1656 if (strlen (cur_link->label_name) > n)
1658 n = strlen (cur_link->label_name);