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);
66 /* If MAIN_HEADER, do not create file */
67 if (cur_header->type == MAIN_HEADER)
71 if (output_mode == HTML)
73 sprintf(fname, "%s-%s.html", doc_base, cur_header->function_name);
74 dest_doc = fopen(fname, "w");
77 fprintf(stderr, "%s\n", strerror(errno));
82 RB_Generate_Header_Start (dest_doc, cur_header, src_name);
84 next_line = cur_header->contents;
85 item_type = RB_Find_Item (&next_line, &item_line);
87 if (item_type != NO_ITEM)
94 if (course_of_action & DO_TELL)
95 printf ("[%s] ", item_names[item_type]);
97 if (!((item_type == SOURCE_ITEM) &&
98 (course_of_action & DO_NOSOURCE)))
99 RB_Generate_Item_Name (dest_doc, item_type);
101 old_next_line = next_line;
102 old_item_type = item_type;
104 item_type = RB_Find_Item (&next_line, &item_line);
106 if (!((old_item_type == SOURCE_ITEM) &&
107 (course_of_action & DO_NOSOURCE)))
108 RB_Generate_Item_Doc (dest_doc, dest_name,
109 old_next_line, item_line,
110 cur_header->function_name,
113 while (item_type != NO_ITEM);
114 if (course_of_action & DO_TELL)
118 printf ("%s: WARNING, header \"%s\" has no items\n",
119 whoami, cur_header->name);
121 RB_Generate_Header_End (dest_doc, cur_header);
123 if (output_mode == HTML)
128 RB_Generate_Doc_End (dest_doc, dest_name);
131 /***** RB_Generate_Documentation ***/
137 /****f* ROBODoc/RB_Generate_Doc_Start [3.0j]
139 * RB_Generate_Doc_Start -- Generate document header.
141 * RB_Generate_Doc_Start (dest_doc, src_name, name, toc)
143 * RB_Generate_Doc_Start (FILE *, char *, char *, char)
145 * Generates for depending on the output_mode the text that
146 * will be at the start of a document.
147 * Including the table of contents.
149 * dest_doc - pointer to the file to which the output will
151 * src_name - the name of the source file.
152 * name - the name of this file.
153 * output_mode - global variable that indicates the output
155 * toc - generate table of contens
157 * RB_Generate_Doc_End
162 RB_Generate_Doc_Start (
163 FILE * dest_doc, char *src_name, char *name, char toc)
165 struct RB_header *cur_header;
166 int cur_len, max_len, header_nr;
171 if (strstr (name + 1, ".guide") == NULL)
172 fprintf (dest_doc, "@database %s.guide\n", name);
174 fprintf (dest_doc, "@database %s\n", name);
175 fprintf (dest_doc, "@rem Source: %s\n", src_name);
176 /* fprintf (dest_doc, "@rem " COMMENT_ROBODOC); */
177 fprintf (dest_doc, "@rem " COMMENT_COPYRIGHT);
178 fprintf (dest_doc, "@node Main %s\n", name);
179 fprintf (dest_doc, "@{jcenter}\n");
181 "@{fg highlight}@{b}TABLE OF CONTENTS@{ub}@{fg text}\n\n");
184 for (cur_header = first_header;
186 cur_header = cur_header->next_header)
188 if (cur_header->name)
190 cur_len = strlen (cur_header->name);
191 if (cur_len > max_len)
196 for (cur_header = first_header;
198 cur_header = cur_header->next_header)
200 if (cur_header->name && cur_header->function_name)
202 fprintf (dest_doc, "@{\"%s", cur_header->name);
204 for (cur_len = strlen (cur_header->name);
207 fputc (' ', dest_doc);
208 fprintf (dest_doc, "\" Link \"%s\"}\n", cur_header->function_name);
212 fprintf (dest_doc, "@{jleft}\n");
213 fprintf (dest_doc, "@endnode\n");
217 /* Append document type and title */
219 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
220 fprintf (dest_doc, "<HTML><HEAD>\n<TITLE>%s</TITLE>\n", name);
222 /* append SGML-comment with document- and copyright-info. This code
223 * ensures that every line has an own comment to avoid problems with
225 fprintf (dest_doc, "<!-- Source: %s -->\n", src_name);
227 static const char copyright_text[]
228 = COMMENT_ROBODOC COMMENT_COPYRIGHT;
230 char previous_char = '\n';
231 char current_char = copyright_text[i];
235 if (previous_char == '\n')
237 fprintf (dest_doc, "<!-- ");
239 if (current_char == '\n')
241 fprintf (dest_doc, " -->");
243 else if ((current_char == '-') && (previous_char == '-'))
245 /* avoid "--" inside SGML-comment, and use "-_" instead; this
246 * looks a bit strange, but one should still be able to figure
247 * out what is meant when reading the output */
250 fputc (current_char, dest_doc);
252 previous_char = current_char;
253 current_char = copyright_text[i];
257 /* append heading and start list of links to functions */
258 fprintf (dest_doc, "</HEAD><BODY BGCOLOR=\"#FFFFFF\">\n");
260 fprintf (dest_doc, "<A NAME=\"%s\">Generated from %s</A> with ROBODoc v"
264 RB_TimeStamp (dest_doc);
266 fprintf (dest_doc, "<BR>\n");
273 /* do toc if not in fold */
276 "<H3 ALIGN=\"center\">TABLE OF CONTENTS</H3>\n");
277 fprintf (dest_doc, "<OL>\n");
280 /* Generate quick index file, for fast referencing */
281 sprintf(iname, "%s-index.tmpl", doc_base);
282 index = fopen(iname, "w");
285 fprintf(stderr, "%s\n", strerror(errno));
289 for (cur_header = first_header;
291 cur_header = cur_header->next_header)
295 sprintf(fname, "%s-%s.html", RB_FilePart(doc_base),
296 cur_header->function_name);
298 if (cur_header->name && cur_header->function_name)
303 char *next_line, *item_line = NULL;
305 RB_Generate_Header_Start (dest_doc, cur_header,
308 next_line = cur_header->contents;
309 item_type = RB_Find_Item (&next_line, &item_line);
311 if (item_type != NO_ITEM)
318 if (course_of_action & DO_TELL)
319 printf ("[%s] ", item_names[item_type]);
321 if (!((item_type == SOURCE_ITEM) &&
322 (course_of_action & DO_NOSOURCE)))
323 RB_Generate_Item_Name (dest_doc, item_type);
325 old_next_line = next_line;
326 old_item_type = item_type;
328 item_type = RB_Find_Item (&next_line,
331 if (!((old_item_type == SOURCE_ITEM) &&
332 (course_of_action & DO_NOSOURCE)))
333 RB_Generate_Item_Doc(dest_doc, name,
334 old_next_line, item_line,
335 cur_header->function_name,
338 while (item_type != NO_ITEM);
339 if (course_of_action & DO_TELL)
345 fprintf (index, "<A HREF=\"%s\"><IMG SRC=\"index_pic.gif\" BORDER=\"0\" ALT=\"\">%s</A><BR>\n",
346 name, cur_header->function_name);
353 fprintf (dest_doc, "<LI><A HREF=\"%s\">%s</A>\n",
354 fname, cur_header->function_name);
356 fprintf (index, "<A HREF=\"%s\"><IMG SRC=\"index_pic.gif\" BORDER=\"0\" ALT=\"\">%s</A><BR>\n",
357 fname, cur_header->function_name);
363 fprintf (dest_doc, "</OL>\n");
372 fprintf (dest_doc, "%% Document: %s\n", name);
373 fprintf (dest_doc, "%% Source: %s\n", src_name);
374 /* fprintf (dest_doc, "%% " COMMENT_ROBODOC);*/
375 fprintf (dest_doc, "%% " COMMENT_COPYRIGHT);
376 if (course_of_action & DO_SINGLEDOC) {
377 if (!strchr(src_name, '_')) {
378 fprintf (dest_doc, "\\section{%s}\n", src_name);
380 char *tmp = calloc(strlen(src_name) + 2, sizeof(*tmp));
381 *strchr(src_name, '_') = '\\';
382 strncat(tmp, src_name, strcspn(src_name, "\\") + 1);
383 strncat(tmp, "_", 1);
384 strncat(tmp, src_name + strcspn(src_name, "\\") + 1,
385 strlen(src_name) - strcspn(src_name, "\\") - 1);
386 fprintf (dest_doc, "\\section{%s}\n", tmp);
390 fprintf (dest_doc, "\\documentclass{article}\n");
391 fprintf (dest_doc, "\\usepackage{makeidx}\n");
392 fprintf (dest_doc, "\\oddsidemargin 0.15 in\n");
393 fprintf (dest_doc, "\\evensidemargin 0.35 in\n");
394 fprintf (dest_doc, "\\marginparwidth 1 in \n");
395 fprintf (dest_doc, "\\oddsidemargin 0.25 in \n");
396 fprintf (dest_doc, "\\evensidemargin 0.25 in\n");
397 fprintf (dest_doc, "\\marginparwidth 0.75 in\n");
398 fprintf (dest_doc, "\\textwidth 5.875 in\n");
400 fprintf (dest_doc, "\\setlength{\\parindent}{0in}\n");
401 fprintf (dest_doc, "\\setlength{\\parskip}{.08in}\n\n");
403 /* changed default header to use boldface (vs slant) */
404 fprintf (dest_doc, "\\pagestyle{headings}\n");
406 if (document_title) {
407 fprintf (dest_doc, "\\title{%s}\n",
410 fprintf (dest_doc, "\\title{API Reference}\n");
412 /* fprintf (dest_doc, "\\author{%s}\n", COMMENT_ROBODOC); */
413 fprintf (dest_doc, "\\makeindex\n");
414 fprintf (dest_doc, "\\begin{document}\n");
415 fprintf (dest_doc, "\\maketitle\n");
416 /* autogenerate table of contents! */
417 fprintf (dest_doc, "\\printindex\n");
418 fprintf (dest_doc, "\\tableofcontents\n");
419 fprintf (dest_doc, "\\newpage\n");
420 /* trick to disable the autogenerated \newpage */
421 fprintf (dest_doc, "\n");
430 fprintf (dest_doc, "{\\rtf1\\ansi \\deff0"
432 "\\f0\\fswiss MS Sans Serif;"
433 "\\f1\\fmodern Courier New;"
434 "\\f2\\ftech Symbol;"
437 "\\red255\\green255\\blue255;"
438 "\\red0\\green0\\blue0;"
439 "\\red0\\green0\\blue255;"
442 /* RTF document info */
443 fprintf (dest_doc, "{\\info"
447 " " COMMENT_COPYRIGHT
449 "}", name, src_name);
451 /* RTF document format */
452 fprintf (dest_doc, "{\\margl1440\\margr1440}\n");
454 /* RTF document section */
455 fprintf (dest_doc, "\\f0\\cb1\\cf3\\fs28\\b1\\qc"
456 "{\\super #{\\footnote{\\super #}%s_TOC}}"
457 "{\\super ${\\footnote{\\super $}Contents}}"
458 "{TABLE OF CONTENTS}\\ql\\b0\\fs20\\cf2\\par\n", src_name);
459 for (cur_header = first_header;
461 cur_header = cur_header->next_header)
463 if (cur_header->name && cur_header->function_name)
465 cook_link = RB_CookStr (cur_header->function_name);
466 fprintf (dest_doc, "{\\uldb %s}{\\v %s}\\line\n",
467 cur_header->name, cook_link);
471 fprintf (dest_doc, "\\par\n");
475 if (course_of_action & DO_TOC)
477 fprintf (dest_doc, "TABLE OF CONTENTS\n");
478 for (cur_header = first_header, header_nr = 1;
480 cur_header = cur_header->next_header, header_nr++)
482 if (cur_header->name && cur_header->function_name)
484 fprintf (dest_doc, "%4.4d %s\n",
485 header_nr, cur_header->name);
488 fputc ('\f', dest_doc);
498 /****f* ROBODoc/RB_Generate_Doc_End [3.0h]
500 * RB_Generate_Doc_End -- generate document trailer.
502 * RB_Generate_Doc_End (dest_doc, name)
504 * RB_Generate_Doc_End (FILE *, char *)
506 * Generates for depending on the output_mode the text that
507 * will be at the end of a document.
509 * dest_doc - pointer to the file to which the output will
511 * name - the name of this file.
512 * output_mode - global variable that indicates the output
515 * Doesn't do anything with its arguments, but that might
516 * change in the future.
522 RB_Generate_Doc_End (FILE * dest_doc, char *name)
527 fputc ('\n', dest_doc);
530 fprintf (dest_doc, "</BODY></HTML>\n");
533 if (!(course_of_action & DO_SINGLEDOC)) {
534 fprintf (dest_doc, "\\end{document}\n");
538 fputc ('}', dest_doc);
548 /****f* ROBODoc/RB_Generate_Header_Start [3.0h]
550 * RB_Generate_Header_Start -- generate header start text.
552 * void RB_Generate_Header_Start (dest_doc, cur_header)
554 * void RB_Generate_Header_Start (FILE *, struct RB_header *)
556 * Generates depending on the output_mode the text that
557 * will be at the end of each header.
559 * dest_doc - pointer to the file to which the output will
561 * cur_header - pointer to a RB_header structure.
563 * RB_Generate_Header_End
568 RB_Generate_Header_Start (FILE * dest_doc, struct RB_header *cur_header,
569 const char *src_name)
574 { /* switch by *koessi */
576 if (cur_header->name && cur_header->function_name)
578 fprintf (dest_doc, "@Node \"%s\" \"%s\"\n",
579 cur_header->function_name,
581 fprintf (dest_doc, "%s", att_start_command[MAKE_SHINE][output_mode]);
582 fprintf (dest_doc, "%s", cur_header->name);
583 fprintf (dest_doc, "%s", att_stop_command[MAKE_SHINE][output_mode]);
584 fprintf (dest_doc, "\n\n");
588 if (cur_header->name && cur_header->function_name)
591 fprintf (dest_doc, "<HR>\n");
593 if (cur_header->type == FUNCTION_HEADER)
595 "\n<FONT SIZE=\"+2\" COLOR=\"#000055\"><B>"
596 "Function <A NAME=\"%s\">%s</A>"
597 "</FONT></B><BR><BR>\n\n",
598 cur_header->function_name,
599 cur_header->function_name);
600 else if (cur_header->type == STRUCT_HEADER)
602 "\n<FONT SIZE=\"+2\" COLOR=\"#000055\"><B>"
603 "Structure <A NAME=\"%s\">%s</A>"
604 "</FONT></B><BR><BR>\n\n",
605 cur_header->function_name,
606 cur_header->function_name);
607 else if (cur_header->type == VARIABLE_HEADER)
609 "\n<FONT SIZE=\"+2\" COLOR=\"#000055\"><B>"
610 "Variable <A NAME=\"%s\">%s</A>"
611 "</FONT></B><BR><BR>\n\n",
612 cur_header->function_name,
613 cur_header->function_name);
614 else if (cur_header->type == MAIN_HEADER)
616 "\n<FONT SIZE=\"+2\" COLOR=\"#000055\"><B>"
617 "<A NAME=\"%s\">%s</A>"
618 "</FONT></B><BR><SMALL>Header: %s</SMALL><BR><BR>\n\n",
619 cur_header->function_name,
620 cur_header->function_name, src_name);
623 "\n<FONT SIZE=\"+2\" COLOR=\"#000055\"><B>"
624 "<A NAME=\"%s\">%s</A>"
625 "</FONT></B><BR><BR>\n\n",
626 cur_header->function_name,
627 cur_header->function_name);
631 cook_link = RB_CookStr (cur_header->name);
632 if (!(course_of_action & DO_SINGLEDOC)) {
633 fprintf (dest_doc, "\\newpage\n");
635 fprintf (dest_doc, "\\subsection{%s}\n", cook_link);
637 if (cur_header->function_name) {
638 cook_link = RB_CookStr (cur_header->function_name);
639 fprintf (dest_doc, "\\index{unsorted!%s}\\index{%s!%s}\n", cook_link,
640 RB_header_type_names[cur_header->type], cook_link);
645 if (cur_header->name && cur_header->function_name)
647 cook_link = RB_CookStr (cur_header->function_name);
648 fprintf (dest_doc, "\\page"
649 "{\\super #{\\footnote{\\super #}%s}}"
650 "{\\super ${\\footnote{\\super $}%s}}"
651 "\\cf3 %s\\cf2\\line\n",
652 cur_header->function_name,
660 fprintf (dest_doc, "%s", att_start_command[MAKE_SHINE][output_mode]);
661 fprintf (dest_doc, "%s", cur_header->name);
662 fprintf (dest_doc, "%s", att_stop_command[MAKE_SHINE][output_mode]);
663 fprintf (dest_doc, "\n\n");
672 /****f* ROBODoc/RB_Generate_Header_End [3.0h]
674 * RB_Generate_Header_End
676 * void RB_Generate_Header_End (dest_doc, cur_header)
678 * void RB_Generate_Header_End (FILE *, struct RB_header *)
680 * Generates for depending on the output_mode the text that
681 * will be at the end of a header.
683 * dest_doc - pointer to the file to which the output will
685 * cur_header - pointer to a RB_header structure.
687 * RB_Generate_Header_Start
692 RB_Generate_Header_End (FILE * dest_doc, struct RB_header *cur_header)
695 { /* switch by *koessi */
697 if (cur_header->name && cur_header->function_name)
698 fprintf (dest_doc, "@endnode\n");
702 fputc ('\n', dest_doc);
705 fprintf (dest_doc, "\\par\n");
708 fputc ('\f', dest_doc);
717 /****f* ROBODoc/RB_Generate_Header_Name [3.0c]
719 * RB_Generate_Header_Name
721 * RB_Generate_Header_Name (dest_doc, name)
723 * RB_Generate_Header_Name (FILE *, char *)
725 * dest_doc - pointer to the file to which the output will
727 * name - pointer to the header name.
732 RB_Generate_Header_Name (FILE * dest_doc, char *name)
734 char format_str[] = "%s";
736 fprintf (dest_doc, format_str, att_start_command[MAKE_SHINE][output_mode]);
737 fprintf (dest_doc, format_str, name);
738 fprintf (dest_doc, format_str, att_stop_command[MAKE_SHINE][output_mode]);
739 fprintf (dest_doc, "\n\n");
742 /*** RB_Generate_Header_Name ***/
745 /****** ROBODoc/RB_Generate_Item_Name [2.01]
747 * RB_Generate_Item_Name -- fast&easy
749 * void RB_Generate_Item_Name( FILE * dest_doc, int item_type )
751 * write the items name to the doc
753 * FILE * dest_doc -- document in progress
754 * int item_type -- this leads to the name and makes colors
758 * uses globals: output_mode, item_names[]
763 RB_Generate_Item_Name (FILE * dest_doc, int item_type)
765 char format_str[] = "%s";
767 if (item_attributes[item_type] & ITEM_NAME_LARGE_FONT)
769 fprintf (dest_doc, format_str,
770 att_start_command[MAKE_LARGE][output_mode]);
771 fprintf (dest_doc, format_str,
772 att_start_command[MAKE_BOLD][output_mode]);
773 if (output_mode == HTML)
774 fprintf (dest_doc, "\n<FONT COLOR=\"#000055\">");
775 fprintf (dest_doc, format_str, item_names[item_type]);
776 if (output_mode == HTML)
777 fprintf (dest_doc, "\n</FONT>");
778 fprintf (dest_doc, format_str,
779 att_stop_command[MAKE_BOLD][output_mode]);
780 fprintf (dest_doc, format_str,
781 att_stop_command[MAKE_LARGE][output_mode]);
784 fprintf (dest_doc, format_str, item_names[item_type]);
786 fputc ('\n', dest_doc);
793 /****f* ROBODoc/RB_Generate_Item_Doc [3.0j]
795 * RB_Generate_Item_Doc
797 * void RB_Generate_Item_Doc(FILE * dest_doc, char *dest_name,
798 * char *begin_of_item,
800 * char *function_name,
803 * Generates the body text of an item, applying predefined attributes
806 * Body text is always non-proportional for several reasons:
807 * 1) text is rarely written with prop spacing and text wrapping
808 * in mind -- e.g., see SYNOPSIS above
809 * 2) source code looks better
810 * 3) it simplifies LaTeX handling
815 RB_Generate_Item_Doc (FILE * dest_doc, char *dest_name,
821 char format_str[] = "%s";
823 if (begin_of_item == end_of_item)
828 fprintf (dest_doc, "<BR>\n");
831 fprintf (dest_doc, "\\\\\n");
834 fprintf (dest_doc, "\n");
841 /* For text body in HTML, change to non-prop _before_ changing font
842 * style. * To conform to DTD, this avoids <B><PRE> and instead uses
844 if (output_mode == HTML)
846 fprintf (dest_doc, "<PRE>");
848 /* change font style */
849 if (item_attributes[item_type] & TEXT_BODY_LARGE_FONT)
850 fprintf (dest_doc, format_str,
851 att_start_command[MAKE_LARGE][output_mode]);
852 if (item_attributes[item_type] & TEXT_BODY_ITALICS)
853 fprintf (dest_doc, format_str,
854 att_start_command[MAKE_ITALICS][output_mode]);
855 if (item_attributes[item_type] & TEXT_BODY_NON_PROP)
856 fprintf (dest_doc, format_str,
857 att_start_command[MAKE_NON_PROP][output_mode]);
858 if (item_attributes[item_type] & TEXT_BODY_SMALL_FONT)
859 fprintf (dest_doc, format_str,
860 att_start_command[MAKE_SMALL][output_mode]);
861 if (item_attributes[item_type] & TEXT_BODY_BOLD)
862 fprintf (dest_doc, format_str,
863 att_start_command[MAKE_BOLD][output_mode]);
864 if (item_attributes[item_type] & TEXT_BODY_UNDERLINE)
865 fprintf (dest_doc, format_str,
866 att_start_command[MAKE_UNDERLINE][output_mode]);
867 if (item_attributes[item_type] & TEXT_BODY_SHINE)
868 fprintf (dest_doc, format_str,
869 att_start_command[MAKE_SHINE][output_mode]);
870 if (item_attributes[item_type] & TEXT_BODY_DEFAULT)
871 fprintf (dest_doc, format_str,
872 att_start_command[MAKE_DEFAULT][output_mode]);
875 * For some modes, the text body is always non-prop
880 fprintf (dest_doc, "\\begin{verbatim}\n");
883 fprintf (dest_doc, "{\\f1{}");
889 RB_Generate_Item_Body (dest_doc, dest_name, begin_of_item, end_of_item,
890 function_name, item_type, 0);
895 /* split the text so LaTeX doesn't get confused ;) */
896 fprintf (dest_doc, "\\" "end{verbatim}\n");
899 fputc ('}', dest_doc);
904 /* restore font style */
905 if (item_attributes[item_type] & TEXT_BODY_SHINE)
906 fprintf (dest_doc, format_str,
907 att_stop_command[MAKE_SHINE][output_mode]);
908 if (item_attributes[item_type] & TEXT_BODY_UNDERLINE)
909 fprintf (dest_doc, format_str,
910 att_stop_command[MAKE_UNDERLINE][output_mode]);
911 if (item_attributes[item_type] & TEXT_BODY_BOLD)
912 fprintf (dest_doc, format_str,
913 att_stop_command[MAKE_BOLD][output_mode]);
914 if (item_attributes[item_type] & TEXT_BODY_SMALL_FONT)
915 fprintf (dest_doc, format_str,
916 att_stop_command[MAKE_SMALL][output_mode]);
917 if (item_attributes[item_type] & TEXT_BODY_NON_PROP)
918 fprintf (dest_doc, format_str,
919 att_stop_command[MAKE_NON_PROP][output_mode]);
920 if (item_attributes[item_type] & TEXT_BODY_ITALICS)
921 fprintf (dest_doc, format_str,
922 att_stop_command[MAKE_ITALICS][output_mode]);
923 if (item_attributes[item_type] & TEXT_BODY_LARGE_FONT)
924 fprintf (dest_doc, format_str,
925 att_stop_command[MAKE_LARGE][output_mode]);
926 if (item_attributes[item_type] & TEXT_BODY_DEFAULT)
927 fprintf (dest_doc, format_str,
928 att_stop_command[MAKE_DEFAULT][output_mode]);
930 if (output_mode != HTML)
932 fputc ('\n', dest_doc);
934 /* for HTML, switch back to prop-font after restoring font style */
935 if (output_mode == HTML)
937 fprintf (dest_doc, "</PRE>");
945 /****f* ROBODoc/RB_Generate_Item_Body [3.0h]
947 * RB_Generate_Item_Body
949 * char * RB_Generate_Item_Body(FILE * dest_doc, char *dest_name,
950 * char *begin_of_item, char *end_of_item,
951 * char *function_name,
952 * int item_type, int tabs_to_skip)
955 * Generates body of an item in output-specific form
957 * dest_doc - pointer to the file to which
958 * the output will be written.
959 * dest_name - the name of this file.
964 * tabs_to_skip - how many tabs to skip in this fold.
966 * o Unbalanced fold marks lead to crash.
968 * o Almost completely rewritten by koessi
969 * o Almost completely Re-Rewritten by Slothouber :)
970 * o Folding mode by PetteriK.
971 * o Linking fixed inside folds / PetteriK 08.04.2000
976 RB_Generate_Item_Body (FILE * dest_doc, char *dest_name,
977 char *begin_of_item, char *end_of_item,
979 int item_type, int tabs_to_skip)
981 char *cur_char, old_char, c;
983 char fname[128], foldname[128];
984 static int in_fold = 0; /* PetteriK 08.04.2000 */
986 cur_char = begin_of_item;
988 if (item_type == SOURCE_ITEM)
990 /* skip end_comment_marker */
991 for (; *cur_char && *cur_char != '\n'; cur_char++);
993 /* skip blank lines leading up to source code */
994 while (*cur_char == '\n')
997 /* trim blanks following source code */
1002 while (end_of_item > cur_char && isspace (*end_of_item));
1003 end_of_item++; /* advance 1 for placement of the NUL */
1005 old_char = *end_of_item;
1006 *end_of_item = '\0';
1008 for (; *cur_char; cur_char++)
1011 int do_search = TRUE;
1012 int was_link = FALSE;
1015 if (item_type != SOURCE_ITEM)
1017 /* Skip empty lines */
1018 while (*cur_char == '\n') {
1021 cur_char = RB_Skip_Remark_Marker (cur_char);
1026 switch (output_mode)
1029 fprintf (dest_doc, "\\tab ");
1036 fprintf (dest_doc, " ");
1040 while (((c = *cur_char) != '\0') && (c != '\n'))
1042 char *label_name, *file_name;
1048 if (!isalnum (c) && (c != '_'))
1055 if (isalpha (c) || (c == '_'))
1057 if (((was_link = RB_Find_Link (cur_char, &label_name,
1058 &file_name)) == FALSE))
1069 switch (output_mode)
1078 for (tb %= tab_size; tb < tab_size; ++tb)
1079 fputc (' ', dest_doc);
1082 fprintf (dest_doc, "\\@");
1086 fprintf (dest_doc, "\\\\");
1090 fputc (c, dest_doc);
1096 /* PetteriK 26.07.1999 */
1097 if (extra_flags & FOLD)
1099 cur_char = RB_Check_Fold_Start (cur_char,
1102 if ((extra_flags & FOLD) && found)
1106 RB_Say ("fold name %s\n", foldname);
1107 RB_Say ("fold begin %d\n", ++fold);
1108 RB_Say ("tabs %d\n", tabs);
1109 sprintf (fname, "%s_fold_%d.html", doc_base, fold);
1110 RB_Say ("opening file %s\n", fname);
1111 fp = fopen (fname, "w");
1112 RB_Generate_Doc_Start (fp, foldname, foldname, 0);
1113 fprintf (fp, "<PRE>\n");
1114 fprintf (dest_doc, "<A HREF=\"%s\">... %s</A>",
1116 in_fold++; /* PetteriK 08.04.2000 */
1117 cur_char = RB_Generate_Item_Body (fp, dest_name,
1118 cur_char, end_of_item,
1121 in_fold--; /* PetteriK 08.04.2000 */
1122 /* skip chars until newline */
1123 while (*cur_char != '\n')
1128 fprintf (fp, "\n</PRE>\n");
1129 RB_Generate_Doc_End (fp, foldname);
1132 else if ((extra_flags & FOLD) && RB_Check_Fold_End (cur_char))
1134 RB_Say ("fold end found\n");
1137 else if ((html_incr = RB_HTML_Extra (dest_doc,
1138 item_type, cur_char)))
1140 cur_char += html_incr;
1150 if (extra_flags & FOLD)
1152 if (tabs >= tabs_to_skip)
1154 for (tb %= tab_size; tb < tab_size; ++tb)
1156 fputc (' ', dest_doc);
1163 for (tb %= tab_size; tb < tab_size; ++tb)
1165 fputc (' ', dest_doc);
1170 fprintf (dest_doc, "<");
1174 fprintf (dest_doc, ">");
1178 fprintf (dest_doc, "&");
1182 fputc (c, dest_doc);
1186 break; /* end case HTML */
1195 for (tb %= tab_size; tb < tab_size; ++tb)
1196 fputc (' ', dest_doc);
1199 /* not used in LaTeX's verbatim environment */
1207 fputc ('\\', dest_doc);
1208 fputc (c, dest_doc);
1212 fprintf (dest_doc, "$\\backslash$");
1216 fprintf (dest_doc, "$\\tilde$");
1220 fprintf (dest_doc, "$\\,\\!^{\\sim}$");
1225 fputc (c, dest_doc);
1237 for (tb %= tab_size; tb < tab_size; ++tb)
1238 fputc (' ', dest_doc);
1243 fputc ('\\', dest_doc);
1244 fputc (c, dest_doc);
1248 fputc (c, dest_doc);
1254 fputc (c, dest_doc);
1261 switch (output_mode)
1264 if (file_name && strcmp (file_name, dest_name))
1265 fprintf (dest_doc, "@{\"%s\" Link \"%s/%s\"}",
1266 label_name, file_name, label_name);
1269 if (strcmp (label_name, function_name))
1270 fprintf (dest_doc, "@{\"%s\" Link \"%s\"}",
1271 label_name, label_name);
1274 fprintf (dest_doc, "%s",
1275 att_start_command[MAKE_BOLD][output_mode]);
1276 fprintf (dest_doc, "%s", label_name);
1277 fprintf (dest_doc, "%s",
1278 att_stop_command[MAKE_BOLD][output_mode]);
1284 /* Include the file name in the link if we are in fold
1285 * PetteriK 08.04.2000
1289 /* We are in fold, always use the file name in the link,
1290 * in file_name == NULL (i.e. the label is in the current file
1291 * that we are processing), refer to value in dest_name.
1292 * This also makes sure that we link correctly if function_name
1293 * is the same as label_name.
1295 fprintf (dest_doc, "<A HREF=\"%s#%s\">%s</A>",
1296 (file_name ? file_name : dest_name),
1297 label_name, label_name);
1299 else if (file_name && strcmp (file_name, dest_name))
1302 fprintf (dest_doc, "<A HREF=\"%s#%s\">%s</A>",
1303 file_name, label_name, label_name);
1305 fprintf (dest_doc, "<A HREF=\"%s-%s.html\">%s</A>",
1306 RB_FilePartStart(file_name), label_name,
1311 if (strcmp (label_name, function_name))
1314 fprintf (dest_doc, "<A HREF=\"#%s\">%s</A>",
1315 label_name, label_name);
1317 fprintf (dest_doc, "<A HREF=\"%s-%s.html\">%s</A>",
1318 RB_FilePart(doc_base), label_name,
1323 fprintf (dest_doc, "%s",
1324 att_start_command[MAKE_BOLD][output_mode]);
1325 fprintf (dest_doc, "%s", label_name);
1326 fprintf (dest_doc, "%s",
1327 att_stop_command[MAKE_BOLD][output_mode]);
1333 if (strcmp (label_name, function_name))
1337 cook_link = RB_CookStr (label_name);
1338 fprintf (dest_doc, "{\\uldb %s}{\\v %s}",
1339 label_name, cook_link);
1344 fprintf (dest_doc, "%s",
1345 att_start_command[MAKE_BOLD][output_mode]);
1346 fprintf (dest_doc, "%s", label_name);
1347 fprintf (dest_doc, "%s",
1348 att_stop_command[MAKE_BOLD][output_mode]);
1352 fprintf (dest_doc, "%s", label_name);
1354 tmp = strlen (label_name);
1362 if (output_mode == RTF)
1363 fprintf (dest_doc, "\\line");
1364 fputc ('\n', dest_doc);
1368 *end_of_item = old_char;
1376 /****f* ROBODoc/RB_HTML_Extra
1382 * 05/15/2000 Added mailto: support (Guillaume Etorre)
1384 * Check and process embedded hyperlinks.
1385 * RETURN VAL* FUNCTION
1386 * Check and process embedded hyperlinks.
1388 * Number of chars processed from *cur_char
1390 * Flag for C and other grammars.
1392 * As the documentation generated for this functions shows, if
1393 * the C source code contains a string with " / * " in it, this
1399 RB_HTML_Extra (FILE * dest_doc, int item_type, char *cur_char)
1404 if (strncmp ("http://", cur_char, strlen ("http://")) == 0)
1406 sscanf (cur_char, "%s", link);
1407 RB_Say ("found link %s\n", link);
1408 res = (strlen (link) - 1);
1409 fprintf (dest_doc, "<A HREF=\"%s\">%s</A>", link, link);
1411 else if (strncmp ("href:", cur_char, strlen ("href:")) == 0)
1413 /* handy in relative hyperlink paths, e.g. href:../../modulex/ */
1414 sscanf ((cur_char + strlen ("href:")), "%s", link);
1415 RB_Say ("found link %s\n", link);
1416 res = (strlen (link) + strlen ("href:") - 1);
1417 fprintf (dest_doc, "<A HREF=\"%s\">%s</A>", link, link);
1419 else if (strncmp ("mailto:", cur_char, strlen ("mailto:")) == 0)
1421 sscanf ((cur_char + strlen ("mailto:")), "%s", link);
1422 RB_Say ("found mail to %s\n", link);
1423 res = (strlen (link) + strlen ("mailto:") - 1);
1424 fprintf (dest_doc, "<A HREF=\"mailto:%s\">%s</A>", link, link);
1426 else if ((extra_flags & C_MODE) && (item_type == SOURCE_ITEM) &&
1427 (strncmp ("/*", cur_char, 2) == 0))
1429 /* start of C comment */
1430 fprintf (dest_doc, "<FONT COLOR = \"#FF0000\">/*");
1433 else if ((extra_flags & C_MODE) && (item_type == SOURCE_ITEM) &&
1434 (strncmp ("*/", cur_char, 2) == 0))
1436 /* end of C comment */
1437 fprintf (dest_doc, "*/</FONT>");
1446 /****f* ROBODoc/RB_Generate_Index
1448 * RB_Generate_Index -- generate index file based on xref files.
1450 * void RB_Generate_Index(FILE *dest, char *name)
1452 * Create a master index file. It contains pointers to the
1453 * documentation generated for each source file, as well as all
1454 * "objects" found in the source files.
1459 RB_Generate_Index (FILE * dest, char *source)
1461 RB_Slow_Sort_Links ();
1463 switch (output_mode)
1467 if (document_title) {
1468 RB_Generate_Doc_Start (dest, source, document_title, 0);
1469 fprintf (dest, "<H1>%s</H1>\n", document_title);
1471 RB_Generate_Doc_Start (dest, source, "Master Index File", 0);
1472 fprintf (dest, "<H1>Master Index File</H1>\n");
1474 if (RB_Number_Of_Links (MAIN_HEADER, NULL))
1475 RB_Generate_Index_Table (dest, MAIN_HEADER, "Modules");
1476 // RB_Generate_Index_Table (dest, NO_HEADER, "Source Files");
1477 if (RB_Number_Of_Links (CLASS_HEADER, NULL))
1478 RB_Generate_Index_Table (dest, CLASS_HEADER, "Classes");
1479 if (RB_Number_Of_Links (METHOD_HEADER, NULL))
1480 RB_Generate_Index_Table (dest, METHOD_HEADER, "Methods");
1481 if (RB_Number_Of_Links (STRUCT_HEADER, NULL))
1482 RB_Generate_Index_Table (dest, STRUCT_HEADER, "Structures");
1483 if (RB_Number_Of_Links (FUNCTION_HEADER, NULL))
1484 RB_Generate_Index_Table (dest, FUNCTION_HEADER, "Functions");
1485 if (RB_Number_Of_Links (VARIABLE_HEADER, NULL))
1486 RB_Generate_Index_Table (dest, VARIABLE_HEADER, "Global Variables");
1487 if (RB_Number_Of_Links (CONSTANT_HEADER, NULL))
1488 RB_Generate_Index_Table (dest, CONSTANT_HEADER, "Constants");
1489 if (RB_Number_Of_Links (GENERIC_HEADER, NULL))
1490 RB_Generate_Index_Table (dest, GENERIC_HEADER, "Generic");
1491 if (RB_Number_Of_Links (INTERNAL_HEADER, NULL))
1492 RB_Generate_Index_Table (dest, INTERNAL_HEADER, "Internal");
1493 RB_Generate_Doc_End (dest, source);
1497 RB_Generate_Doc_Start (dest, source, "Master File", 0);
1498 RB_Generate_LaTeX_Includes (dest);
1499 RB_Generate_Doc_End (dest, source);
1505 /****f* ROBODoc/Generate_LaTeX_Includes
1507 * Generate_LaTeX_Includes -- generate include commands
1509 * void RB_Generate_LaTeX_Includes (FILE *dest)
1511 * Generates a series of \include commands to include the
1512 * documentation generated for each source file into one
1518 RB_Generate_LaTeX_Includes (FILE *dest)
1520 struct RB_link *cur_link;
1521 for (cur_link = first_link;
1523 cur_link = cur_link->next_link) {
1525 if (cur_link->type == NO_HEADER)
1526 fprintf (dest, "\\include{%s}\n", cur_link->label_name);
1531 /****f* ROBODoc/RB_Generate_Index_Table
1533 * RB_Generate_Index --
1535 * void RB_Generate_Index_Table(FILE *, int type, char *title)
1536 * RB_Generate_Index_Table(dest, type, title)
1538 * Creates a table with index items of a particular type.
1539 * If the type is NO_HEADER, then the table is a table of
1540 * source files. In this case no link is added if the
1541 * source file did not contain any documentation.
1543 * dest -- output file
1544 * type -- kind of header index.
1545 * title -- title for the table
1550 RB_Generate_Index_Table (FILE * dest, int type, char *title)
1552 struct RB_link *cur_link;
1553 int number_of_columns;
1556 number_of_columns = 60 / RB_Max_Name_Length (type, NULL);
1558 fprintf (dest, "<H2>%s</H2>\n", title);
1559 fprintf (dest, "<TABLE>\n");
1561 for (cur_link = first_link;
1563 cur_link = cur_link->next_link)
1565 if (cur_link->type == type)
1567 if (cur_column == 0)
1569 fprintf (dest, "<TR>\n");
1571 if (type == NO_HEADER)
1573 if (RB_Number_Of_Links (NO_HEADER, cur_link->file_name) > 1)
1576 "<TD><A HREF=\"%s-%s.html\"><TT>%s</TT></A></TD>\n",
1577 RB_FilePartStart(cur_link->file_name),
1578 cur_link->label_name,
1579 cur_link->label_name);
1583 fprintf (dest, "<TD>%s</TD>\n", cur_link->label_name);
1588 if (type == MAIN_HEADER)
1590 fprintf (dest, "<TD><A HREF=\"%s.html\"><TT>%s</TT></A></TD>\n",
1591 RB_FilePartStart(cur_link->file_name),
1592 cur_link->label_name);
1596 fprintf (dest, "<TD><A HREF=\"%s-%s.html\"><TT>%s</TT></A></TD>\n",
1597 RB_FilePartStart(cur_link->file_name),
1598 cur_link->label_name,
1599 cur_link->label_name);
1603 if (cur_column > number_of_columns)
1605 fprintf (dest, "</TR>\n");
1610 for (; cur_column <= number_of_columns;)
1612 if (cur_column == 0)
1614 fprintf (dest, "<TR>\n");
1616 fprintf (dest, "<TD></TD>\n");
1619 fprintf (dest, "</TR>\n");
1620 fprintf (dest, "</TABLE>\n");
1623 /******* END RB_Generate_Index_Table *****/
1626 /****f* ROBODoc/RB_Number_Of_Links
1628 * RB_Number_Of_Links -- Count the number of links.
1630 * Counts the number of links that are of a particular type
1631 * and that can be found in a particular file.
1633 * type -- the header type of the header the link is pointing to.
1634 * If NO_HEADER, all header types are counted.
1635 * file_name -- name of the file the link comes from, can be NULL, in
1636 * which case only the type is checked.
1643 RB_Number_Of_Links (int type, char *file_name)
1645 struct RB_link *cur_link;
1648 for (cur_link = first_link;
1650 cur_link = cur_link->next_link)
1652 if (cur_link->type == type || (type == NO_HEADER))
1656 if (strcmp (file_name, cur_link->file_name) == 0)
1672 /****f* ROBODoc/RB_Max_Name_Length
1674 * RB_Max_Name_Length -- find longest label name.
1676 * Find the length of the longest label name in a sub list
1677 * of the list with links. This is used to determine how
1678 * many columns can be displayed in a table.
1679 * The sublist is specified by the type of header the link
1680 * should point to, as well as by the name of the documentation
1683 * RB_Max_Name_Length(CLASS_HEADER, "muppets.c.html")
1684 * longest label name in the list of links to class headers
1685 * in muppets.c.html.
1686 * RB_Max_Name_Length(CLASS_HEADER, NULL)
1687 * longest label name in the list of links to class headers.
1689 * type -- type of header
1690 * file_name -- file the header come from, can be NULL.
1691 * In which links from all files are used.
1696 RB_Max_Name_Length (int type, char *file_name)
1698 struct RB_link *cur_link;
1701 for (cur_link = first_link;
1703 cur_link = cur_link->next_link)
1705 if (cur_link->type == type)
1709 if (strcmp (file_name, cur_link->file_name) == 0)
1711 if (strlen (cur_link->label_name) > n)
1713 n = strlen (cur_link->label_name);
1719 if (strlen (cur_link->label_name) > n)
1721 n = strlen (cur_link->label_name);