11 #include "generator.h"
15 /****f* ROBODoc/RB_Generate_Documentation [3.0h]
17 * RB_Generate_Documentation
19 * RB_Generate_Documentation (dest_doc, name, name)
21 * RB_Generate_Documentation (FILE *, char *, char *)
23 * Generates the autodoc documentation from the list of
24 * function headers that has been created by
25 * RB_Analyse_Document.
27 * dest_doc - Pointer to the file to which the output will be written.
28 * src_name - The name of the source file.
29 * dest_name - The name of this file.
31 * There might be plenty.
33 * RB_Generate_Doc_Start,
34 * RB_Generate_Doc_End,
35 * RB_Generate_Header_Start,
36 * RB_Generate_Header_End,
37 * RB_Generate_Header_Name,
38 * RB_Generate_Item_Name,
39 * RB_Generate_Item_Doc,
40 * RB_Generate_Item_Body .
45 RB_Generate_Documentation (
46 FILE * dest_doc, char *src_name, char *dest_name)
48 struct RB_header *cur_header;
50 FILE *orig_doc = dest_doc;
52 RB_Make_Index_Tables ();
54 RB_Generate_Doc_Start (dest_doc, src_name, dest_name, 1);
56 for (cur_header = first_header;
58 cur_header = cur_header->next_header)
61 char *next_line, *item_line = NULL;
63 RB_Say ("generating documentation for \"%s\"\n", cur_header->name);
65 if (output_mode == HTML)
67 sprintf(fname, "%s-%s.html", doc_base, cur_header->function_name);
68 dest_doc = fopen(fname, "w");
71 fprintf(stderr, "%s\n", strerror(errno));
76 RB_Generate_Header_Start (dest_doc, cur_header, src_name);
78 next_line = cur_header->contents;
79 item_type = RB_Find_Item (&next_line, &item_line);
81 if (item_type != NO_ITEM)
88 if (course_of_action & DO_TELL)
89 printf ("[%s] ", item_names[item_type]);
91 if (!((item_type == SOURCE_ITEM) &&
92 (course_of_action & DO_NOSOURCE)))
93 RB_Generate_Item_Name (dest_doc, item_type);
95 old_next_line = next_line;
96 old_item_type = item_type;
98 item_type = RB_Find_Item (&next_line, &item_line);
100 if (!((old_item_type == SOURCE_ITEM) &&
101 (course_of_action & DO_NOSOURCE)))
102 RB_Generate_Item_Doc (dest_doc, dest_name,
103 old_next_line, item_line,
104 cur_header->function_name,
107 while (item_type != NO_ITEM);
108 if (course_of_action & DO_TELL)
112 printf ("%s: WARNING, header \"%s\" has no items\n",
113 whoami, cur_header->name);
115 RB_Generate_Header_End (dest_doc, cur_header);
117 if (output_mode == HTML)
122 RB_Generate_Doc_End (dest_doc, dest_name);
125 /***** RB_Generate_Documentation ***/
131 /****f* ROBODoc/RB_Generate_Doc_Start [3.0j]
133 * RB_Generate_Doc_Start -- Generate document header.
135 * RB_Generate_Doc_Start (dest_doc, src_name, name, toc)
137 * RB_Generate_Doc_Start (FILE *, char *, char *, char)
139 * Generates for depending on the output_mode the text that
140 * will be at the start of a document.
141 * Including the table of contents.
143 * dest_doc - pointer to the file to which the output will
145 * src_name - the name of the source file.
146 * name - the name of this file.
147 * output_mode - global variable that indicates the output
149 * toc - generate table of contens
151 * RB_Generate_Doc_End
156 RB_Generate_Doc_Start (
157 FILE * dest_doc, char *src_name, char *name, char toc)
159 struct RB_header *cur_header;
160 int cur_len, max_len, header_nr;
165 if (strstr (name + 1, ".guide") == NULL)
166 fprintf (dest_doc, "@database %s.guide\n", name);
168 fprintf (dest_doc, "@database %s\n", name);
169 fprintf (dest_doc, "@rem Source: %s\n", src_name);
170 /* fprintf (dest_doc, "@rem " COMMENT_ROBODOC); */
171 fprintf (dest_doc, "@rem " COMMENT_COPYRIGHT);
172 fprintf (dest_doc, "@node Main %s\n", name);
173 fprintf (dest_doc, "@{jcenter}\n");
175 "@{fg highlight}@{b}TABLE OF CONTENTS@{ub}@{fg text}\n\n");
178 for (cur_header = first_header;
180 cur_header = cur_header->next_header)
182 if (cur_header->name)
184 cur_len = strlen (cur_header->name);
185 if (cur_len > max_len)
190 for (cur_header = first_header;
192 cur_header = cur_header->next_header)
194 if (cur_header->name && cur_header->function_name)
196 fprintf (dest_doc, "@{\"%s", cur_header->name);
198 for (cur_len = strlen (cur_header->name);
201 fputc (' ', dest_doc);
202 fprintf (dest_doc, "\" Link \"%s\"}\n", cur_header->function_name);
206 fprintf (dest_doc, "@{jleft}\n");
207 fprintf (dest_doc, "@endnode\n");
211 /* Append document type and title */
213 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
214 fprintf (dest_doc, "<HTML><HEAD>\n<TITLE>%s</TITLE>\n", name);
216 /* append SGML-comment with document- and copyright-info. This code
217 * ensures that every line has an own comment to avoid problems with
219 fprintf (dest_doc, "<!-- Source: %s -->\n", src_name);
221 static const char copyright_text[]
222 = COMMENT_ROBODOC COMMENT_COPYRIGHT;
224 char previous_char = '\n';
225 char current_char = copyright_text[i];
229 if (previous_char == '\n')
231 fprintf (dest_doc, "<!-- ");
233 if (current_char == '\n')
235 fprintf (dest_doc, " -->");
237 else if ((current_char == '-') && (previous_char == '-'))
239 /* avoid "--" inside SGML-comment, and use "-_" instead; this
240 * looks a bit strange, but one should still be able to figure
241 * out what is meant when reading the output */
244 fputc (current_char, dest_doc);
246 previous_char = current_char;
247 current_char = copyright_text[i];
251 /* append heading and start list of links to functions */
252 fprintf (dest_doc, "</HEAD><BODY BGCOLOR=\"#FFFFFF\">\n");
254 fprintf (dest_doc, "<A NAME=\"%s\">Generated from %s</A> with ROBODoc v"
258 RB_TimeStamp (dest_doc);
260 fprintf (dest_doc, "<BR>\n");
267 /* do toc if not in fold */
270 "<H3 ALIGN=\"center\">TABLE OF CONTENTS</H3>\n");
271 fprintf (dest_doc, "<OL>\n");
274 /* Generate quick index file, for fast referencing */
275 sprintf(iname, "%s-index.tmpl", doc_base);
276 index = fopen(iname, "w");
279 fprintf(stderr, "%s\n", strerror(errno));
283 for (cur_header = first_header;
285 cur_header = cur_header->next_header)
289 sprintf(fname, "%s-%s.html", RB_FilePart(doc_base),
290 cur_header->function_name);
292 if (cur_header->name && cur_header->function_name)
297 char *next_line, *item_line = NULL;
299 RB_Generate_Header_Start (dest_doc, cur_header,
302 next_line = cur_header->contents;
303 item_type = RB_Find_Item (&next_line, &item_line);
305 if (item_type != NO_ITEM)
312 if (course_of_action & DO_TELL)
313 printf ("[%s] ", item_names[item_type]);
315 if (!((item_type == SOURCE_ITEM) &&
316 (course_of_action & DO_NOSOURCE)))
317 RB_Generate_Item_Name (dest_doc, item_type);
319 old_next_line = next_line;
320 old_item_type = item_type;
322 item_type = RB_Find_Item (&next_line,
325 if (!((old_item_type == SOURCE_ITEM) &&
326 (course_of_action & DO_NOSOURCE)))
327 RB_Generate_Item_Doc(dest_doc, name,
328 old_next_line, item_line,
329 cur_header->function_name,
332 while (item_type != NO_ITEM);
333 if (course_of_action & DO_TELL)
339 fprintf (index, "<A HREF=\"%s\"><IMG SRC=\"index_pic.gif\" BORDER=\"0\" ALT=\"\">%s</A><BR>\n",
340 name, cur_header->function_name);
347 fprintf (dest_doc, "<LI><A HREF=\"%s\">%s</A>\n",
348 fname, cur_header->function_name);
350 fprintf (index, "<A HREF=\"%s\"><IMG SRC=\"index_pic.gif\" BORDER=\"0\" ALT=\"\">%s</A><BR>\n",
351 fname, cur_header->function_name);
357 fprintf (dest_doc, "</OL>\n");
366 fprintf (dest_doc, "%% Document: %s\n", name);
367 fprintf (dest_doc, "%% Source: %s\n", src_name);
368 /* fprintf (dest_doc, "%% " COMMENT_ROBODOC);*/
369 fprintf (dest_doc, "%% " COMMENT_COPYRIGHT);
370 if (course_of_action & DO_SINGLEDOC) {
371 if (!strchr(src_name, '_')) {
372 fprintf (dest_doc, "\\section{%s}\n", src_name);
374 char *tmp = calloc(strlen(src_name) + 2, sizeof(*tmp));
375 *strchr(src_name, '_') = '\\';
376 strncat(tmp, src_name, strcspn(src_name, "\\") + 1);
377 strncat(tmp, "_", 1);
378 strncat(tmp, src_name + strcspn(src_name, "\\") + 1,
379 strlen(src_name) - strcspn(src_name, "\\") - 1);
380 fprintf (dest_doc, "\\section{%s}\n", tmp);
384 fprintf (dest_doc, "\\documentclass{article}\n");
385 fprintf (dest_doc, "\\usepackage{makeidx}\n");
386 fprintf (dest_doc, "\\oddsidemargin 0.15 in\n");
387 fprintf (dest_doc, "\\evensidemargin 0.35 in\n");
388 fprintf (dest_doc, "\\marginparwidth 1 in \n");
389 fprintf (dest_doc, "\\oddsidemargin 0.25 in \n");
390 fprintf (dest_doc, "\\evensidemargin 0.25 in\n");
391 fprintf (dest_doc, "\\marginparwidth 0.75 in\n");
392 fprintf (dest_doc, "\\textwidth 5.875 in\n");
394 fprintf (dest_doc, "\\setlength{\\parindent}{0in}\n");
395 fprintf (dest_doc, "\\setlength{\\parskip}{.08in}\n\n");
397 /* changed default header to use boldface (vs slant) */
398 fprintf (dest_doc, "\\pagestyle{headings}\n");
400 if (document_title) {
401 fprintf (dest_doc, "\\title{%s}\n",
404 fprintf (dest_doc, "\\title{API Reference}\n");
406 /* fprintf (dest_doc, "\\author{%s}\n", COMMENT_ROBODOC); */
407 fprintf (dest_doc, "\\makeindex\n");
408 fprintf (dest_doc, "\\begin{document}\n");
409 fprintf (dest_doc, "\\maketitle\n");
410 /* autogenerate table of contents! */
411 fprintf (dest_doc, "\\printindex\n");
412 fprintf (dest_doc, "\\tableofcontents\n");
413 fprintf (dest_doc, "\\newpage\n");
414 /* trick to disable the autogenerated \newpage */
415 fprintf (dest_doc, "\n");
424 fprintf (dest_doc, "{\\rtf1\\ansi \\deff0"
426 "\\f0\\fswiss MS Sans Serif;"
427 "\\f1\\fmodern Courier New;"
428 "\\f2\\ftech Symbol;"
431 "\\red255\\green255\\blue255;"
432 "\\red0\\green0\\blue0;"
433 "\\red0\\green0\\blue255;"
436 /* RTF document info */
437 fprintf (dest_doc, "{\\info"
441 " " COMMENT_COPYRIGHT
443 "}", name, src_name);
445 /* RTF document format */
446 fprintf (dest_doc, "{\\margl1440\\margr1440}\n");
448 /* RTF document section */
449 fprintf (dest_doc, "\\f0\\cb1\\cf3\\fs28\\b1\\qc"
450 "{\\super #{\\footnote{\\super #}%s_TOC}}"
451 "{\\super ${\\footnote{\\super $}Contents}}"
452 "{TABLE OF CONTENTS}\\ql\\b0\\fs20\\cf2\\par\n", src_name);
453 for (cur_header = first_header;
455 cur_header = cur_header->next_header)
457 if (cur_header->name && cur_header->function_name)
459 cook_link = RB_CookStr (cur_header->function_name);
460 fprintf (dest_doc, "{\\uldb %s}{\\v %s}\\line\n",
461 cur_header->name, cook_link);
465 fprintf (dest_doc, "\\par\n");
469 if (course_of_action & DO_TOC)
471 fprintf (dest_doc, "TABLE OF CONTENTS\n");
472 for (cur_header = first_header, header_nr = 1;
474 cur_header = cur_header->next_header, header_nr++)
476 if (cur_header->name && cur_header->function_name)
478 fprintf (dest_doc, "%4.4d %s\n",
479 header_nr, cur_header->name);
482 fputc ('\f', dest_doc);
492 /****f* ROBODoc/RB_Generate_Doc_End [3.0h]
494 * RB_Generate_Doc_End -- generate document trailer.
496 * RB_Generate_Doc_End (dest_doc, name)
498 * RB_Generate_Doc_End (FILE *, char *)
500 * Generates for depending on the output_mode the text that
501 * will be at the end of a document.
503 * dest_doc - pointer to the file to which the output will
505 * name - the name of this file.
506 * output_mode - global variable that indicates the output
509 * Doesn't do anything with its arguments, but that might
510 * change in the future.
516 RB_Generate_Doc_End (FILE * dest_doc, char *name)
521 fputc ('\n', dest_doc);
524 fprintf (dest_doc, "</BODY></HTML>\n");
527 if (!(course_of_action & DO_SINGLEDOC)) {
528 fprintf (dest_doc, "\\end{document}\n");
532 fputc ('}', dest_doc);
542 /****f* ROBODoc/RB_Generate_Header_Start [3.0h]
544 * RB_Generate_Header_Start -- generate header start text.
546 * void RB_Generate_Header_Start (dest_doc, cur_header)
548 * void RB_Generate_Header_Start (FILE *, struct RB_header *)
550 * Generates depending on the output_mode the text that
551 * will be at the end of each header.
553 * dest_doc - pointer to the file to which the output will
555 * cur_header - pointer to a RB_header structure.
557 * RB_Generate_Header_End
562 RB_Generate_Header_Start (FILE * dest_doc, struct RB_header *cur_header,
563 const char *src_name)
568 { /* switch by *koessi */
570 if (cur_header->name && cur_header->function_name)
572 fprintf (dest_doc, "@Node \"%s\" \"%s\"\n",
573 cur_header->function_name,
575 fprintf (dest_doc, "%s", att_start_command[MAKE_SHINE][output_mode]);
576 fprintf (dest_doc, "%s", cur_header->name);
577 fprintf (dest_doc, "%s", att_stop_command[MAKE_SHINE][output_mode]);
578 fprintf (dest_doc, "\n\n");
582 if (cur_header->name && cur_header->function_name)
585 fprintf (dest_doc, "<HR>\n");
587 if (cur_header->type == FUNCTION_HEADER)
589 "\n<FONT SIZE=\"+2\" COLOR=\"#000055\"><B>"
590 "Function <A NAME=\"%s\">%s</A>"
591 "</FONT></B><BR><BR>\n\n",
592 cur_header->function_name,
593 cur_header->function_name);
594 else if (cur_header->type == STRUCT_HEADER)
596 "\n<FONT SIZE=\"+2\" COLOR=\"#000055\"><B>"
597 "Structure <A NAME=\"%s\">%s</A>"
598 "</FONT></B><BR><BR>\n\n",
599 cur_header->function_name,
600 cur_header->function_name);
601 else if (cur_header->type == VARIABLE_HEADER)
603 "\n<FONT SIZE=\"+2\" COLOR=\"#000055\"><B>"
604 "Variable <A NAME=\"%s\">%s</A>"
605 "</FONT></B><BR><BR>\n\n",
606 cur_header->function_name,
607 cur_header->function_name);
608 else if (cur_header->type == MAIN_HEADER)
610 "\n<FONT SIZE=\"+2\" COLOR=\"#000055\"><B>"
611 "<A NAME=\"%s\">%s</A>"
612 "</FONT></B><BR><SMALL>Header: %s</SMALL><BR><BR>\n\n",
613 cur_header->function_name,
614 cur_header->function_name, src_name);
617 "\n<FONT SIZE=\"+2\" COLOR=\"#000055\"><B>"
618 "<A NAME=\"%s\">%s</A>"
619 "</FONT></B><BR><BR>\n\n",
620 cur_header->function_name,
621 cur_header->function_name);
625 cook_link = RB_CookStr (cur_header->name);
626 if (!(course_of_action & DO_SINGLEDOC)) {
627 fprintf (dest_doc, "\\newpage\n");
629 fprintf (dest_doc, "\\subsection{%s}\n", cook_link);
631 if (cur_header->function_name) {
632 cook_link = RB_CookStr (cur_header->function_name);
633 fprintf (dest_doc, "\\index{unsorted!%s}\\index{%s!%s}\n", cook_link,
634 RB_header_type_names[cur_header->type], cook_link);
639 if (cur_header->name && cur_header->function_name)
641 cook_link = RB_CookStr (cur_header->function_name);
642 fprintf (dest_doc, "\\page"
643 "{\\super #{\\footnote{\\super #}%s}}"
644 "{\\super ${\\footnote{\\super $}%s}}"
645 "\\cf3 %s\\cf2\\line\n",
646 cur_header->function_name,
654 fprintf (dest_doc, "%s", att_start_command[MAKE_SHINE][output_mode]);
655 fprintf (dest_doc, "%s", cur_header->name);
656 fprintf (dest_doc, "%s", att_stop_command[MAKE_SHINE][output_mode]);
657 fprintf (dest_doc, "\n\n");
666 /****f* ROBODoc/RB_Generate_Header_End [3.0h]
668 * RB_Generate_Header_End
670 * void RB_Generate_Header_End (dest_doc, cur_header)
672 * void RB_Generate_Header_End (FILE *, struct RB_header *)
674 * Generates for depending on the output_mode the text that
675 * will be at the end of a header.
677 * dest_doc - pointer to the file to which the output will
679 * cur_header - pointer to a RB_header structure.
681 * RB_Generate_Header_Start
686 RB_Generate_Header_End (FILE * dest_doc, struct RB_header *cur_header)
689 { /* switch by *koessi */
691 if (cur_header->name && cur_header->function_name)
692 fprintf (dest_doc, "@endnode\n");
696 fputc ('\n', dest_doc);
699 fprintf (dest_doc, "\\par\n");
702 fputc ('\f', dest_doc);
711 /****f* ROBODoc/RB_Generate_Header_Name [3.0c]
713 * RB_Generate_Header_Name
715 * RB_Generate_Header_Name (dest_doc, name)
717 * RB_Generate_Header_Name (FILE *, char *)
719 * dest_doc - pointer to the file to which the output will
721 * name - pointer to the header name.
726 RB_Generate_Header_Name (FILE * dest_doc, char *name)
728 char format_str[] = "%s";
730 fprintf (dest_doc, format_str, att_start_command[MAKE_SHINE][output_mode]);
731 fprintf (dest_doc, format_str, name);
732 fprintf (dest_doc, format_str, att_stop_command[MAKE_SHINE][output_mode]);
733 fprintf (dest_doc, "\n\n");
736 /*** RB_Generate_Header_Name ***/
739 /****** ROBODoc/RB_Generate_Item_Name [2.01]
741 * RB_Generate_Item_Name -- fast&easy
743 * void RB_Generate_Item_Name( FILE * dest_doc, int item_type )
745 * write the items name to the doc
747 * FILE * dest_doc -- document in progress
748 * int item_type -- this leads to the name and makes colors
752 * uses globals: output_mode, item_names[]
757 RB_Generate_Item_Name (FILE * dest_doc, int item_type)
759 char format_str[] = "%s";
761 if (item_attributes[item_type] & ITEM_NAME_LARGE_FONT)
763 fprintf (dest_doc, format_str,
764 att_start_command[MAKE_LARGE][output_mode]);
765 fprintf (dest_doc, format_str,
766 att_start_command[MAKE_BOLD][output_mode]);
767 if (output_mode == HTML)
768 fprintf (dest_doc, "\n<FONT COLOR=\"#000055\">");
769 fprintf (dest_doc, format_str, item_names[item_type]);
770 if (output_mode == HTML)
771 fprintf (dest_doc, "\n</FONT>");
772 fprintf (dest_doc, format_str,
773 att_stop_command[MAKE_BOLD][output_mode]);
774 fprintf (dest_doc, format_str,
775 att_stop_command[MAKE_LARGE][output_mode]);
778 fprintf (dest_doc, format_str, item_names[item_type]);
780 fputc ('\n', dest_doc);
787 /****f* ROBODoc/RB_Generate_Item_Doc [3.0j]
789 * RB_Generate_Item_Doc
791 * void RB_Generate_Item_Doc(FILE * dest_doc, char *dest_name,
792 * char *begin_of_item,
794 * char *function_name,
797 * Generates the body text of an item, applying predefined attributes
800 * Body text is always non-proportional for several reasons:
801 * 1) text is rarely written with prop spacing and text wrapping
802 * in mind -- e.g., see SYNOPSIS above
803 * 2) source code looks better
804 * 3) it simplifies LaTeX handling
809 RB_Generate_Item_Doc (FILE * dest_doc, char *dest_name,
815 char format_str[] = "%s";
817 if (begin_of_item == end_of_item)
822 fprintf (dest_doc, "<BR>\n");
825 fprintf (dest_doc, "\\\\\n");
828 fprintf (dest_doc, "\n");
835 /* For text body in HTML, change to non-prop _before_ changing font
836 * style. * To conform to DTD, this avoids <B><PRE> and instead uses
838 if (output_mode == HTML)
840 fprintf (dest_doc, "<PRE>");
842 /* change font style */
843 if (item_attributes[item_type] & TEXT_BODY_LARGE_FONT)
844 fprintf (dest_doc, format_str,
845 att_start_command[MAKE_LARGE][output_mode]);
846 if (item_attributes[item_type] & TEXT_BODY_ITALICS)
847 fprintf (dest_doc, format_str,
848 att_start_command[MAKE_ITALICS][output_mode]);
849 if (item_attributes[item_type] & TEXT_BODY_NON_PROP)
850 fprintf (dest_doc, format_str,
851 att_start_command[MAKE_NON_PROP][output_mode]);
852 if (item_attributes[item_type] & TEXT_BODY_SMALL_FONT)
853 fprintf (dest_doc, format_str,
854 att_start_command[MAKE_SMALL][output_mode]);
855 if (item_attributes[item_type] & TEXT_BODY_BOLD)
856 fprintf (dest_doc, format_str,
857 att_start_command[MAKE_BOLD][output_mode]);
858 if (item_attributes[item_type] & TEXT_BODY_UNDERLINE)
859 fprintf (dest_doc, format_str,
860 att_start_command[MAKE_UNDERLINE][output_mode]);
861 if (item_attributes[item_type] & TEXT_BODY_SHINE)
862 fprintf (dest_doc, format_str,
863 att_start_command[MAKE_SHINE][output_mode]);
864 if (item_attributes[item_type] & TEXT_BODY_DEFAULT)
865 fprintf (dest_doc, format_str,
866 att_start_command[MAKE_DEFAULT][output_mode]);
869 * For some modes, the text body is always non-prop
874 fprintf (dest_doc, "\\begin{verbatim}\n");
877 fprintf (dest_doc, "{\\f1{}");
883 RB_Generate_Item_Body (dest_doc, dest_name, begin_of_item, end_of_item,
884 function_name, item_type, 0);
889 /* split the text so LaTeX doesn't get confused ;) */
890 fprintf (dest_doc, "\\" "end{verbatim}\n");
893 fputc ('}', dest_doc);
898 /* restore font style */
899 if (item_attributes[item_type] & TEXT_BODY_SHINE)
900 fprintf (dest_doc, format_str,
901 att_stop_command[MAKE_SHINE][output_mode]);
902 if (item_attributes[item_type] & TEXT_BODY_UNDERLINE)
903 fprintf (dest_doc, format_str,
904 att_stop_command[MAKE_UNDERLINE][output_mode]);
905 if (item_attributes[item_type] & TEXT_BODY_BOLD)
906 fprintf (dest_doc, format_str,
907 att_stop_command[MAKE_BOLD][output_mode]);
908 if (item_attributes[item_type] & TEXT_BODY_SMALL_FONT)
909 fprintf (dest_doc, format_str,
910 att_stop_command[MAKE_SMALL][output_mode]);
911 if (item_attributes[item_type] & TEXT_BODY_NON_PROP)
912 fprintf (dest_doc, format_str,
913 att_stop_command[MAKE_NON_PROP][output_mode]);
914 if (item_attributes[item_type] & TEXT_BODY_ITALICS)
915 fprintf (dest_doc, format_str,
916 att_stop_command[MAKE_ITALICS][output_mode]);
917 if (item_attributes[item_type] & TEXT_BODY_LARGE_FONT)
918 fprintf (dest_doc, format_str,
919 att_stop_command[MAKE_LARGE][output_mode]);
920 if (item_attributes[item_type] & TEXT_BODY_DEFAULT)
921 fprintf (dest_doc, format_str,
922 att_stop_command[MAKE_DEFAULT][output_mode]);
924 if (output_mode != HTML)
926 fputc ('\n', dest_doc);
928 /* for HTML, switch back to prop-font after restoring font style */
929 if (output_mode == HTML)
931 fprintf (dest_doc, "</PRE>");
939 /****f* ROBODoc/RB_Generate_Item_Body [3.0h]
941 * RB_Generate_Item_Body
943 * char * RB_Generate_Item_Body(FILE * dest_doc, char *dest_name,
944 * char *begin_of_item, char *end_of_item,
945 * char *function_name,
946 * int item_type, int tabs_to_skip)
949 * Generates body of an item in output-specific form
951 * dest_doc - pointer to the file to which
952 * the output will be written.
953 * dest_name - the name of this file.
958 * tabs_to_skip - how many tabs to skip in this fold.
960 * o Unbalanced fold marks lead to crash.
962 * o Almost completely rewritten by koessi
963 * o Almost completely Re-Rewritten by Slothouber :)
964 * o Folding mode by PetteriK.
965 * o Linking fixed inside folds / PetteriK 08.04.2000
970 RB_Generate_Item_Body (FILE * dest_doc, char *dest_name,
971 char *begin_of_item, char *end_of_item,
973 int item_type, int tabs_to_skip)
975 char *cur_char, old_char, c;
977 char fname[128], foldname[128];
978 static int in_fold = 0; /* PetteriK 08.04.2000 */
980 cur_char = begin_of_item;
982 if (item_type == SOURCE_ITEM)
984 /* skip end_comment_marker */
985 for (; *cur_char && *cur_char != '\n'; cur_char++);
987 /* skip blank lines leading up to source code */
988 while (*cur_char == '\n')
991 /* trim blanks following source code */
996 while (end_of_item > cur_char && isspace (*end_of_item));
997 end_of_item++; /* advance 1 for placement of the NUL */
999 old_char = *end_of_item;
1000 *end_of_item = '\0';
1002 for (; *cur_char; cur_char++)
1005 int do_search = TRUE;
1006 int was_link = FALSE;
1009 if (item_type != SOURCE_ITEM)
1011 /* Skip empty lines */
1012 while (*cur_char == '\n') {
1015 cur_char = RB_Skip_Remark_Marker (cur_char);
1020 switch (output_mode)
1023 fprintf (dest_doc, "\\tab ");
1030 fprintf (dest_doc, " ");
1034 while (((c = *cur_char) != '\0') && (c != '\n'))
1036 char *label_name, *file_name;
1042 if (!isalnum (c) && (c != '_'))
1049 if (isalpha (c) || (c == '_'))
1051 if (((was_link = RB_Find_Link (cur_char, &label_name,
1052 &file_name)) == FALSE))
1063 switch (output_mode)
1072 for (tb %= tab_size; tb < tab_size; ++tb)
1073 fputc (' ', dest_doc);
1076 fprintf (dest_doc, "\\@");
1080 fprintf (dest_doc, "\\\\");
1084 fputc (c, dest_doc);
1090 /* PetteriK 26.07.1999 */
1091 if (extra_flags & FOLD)
1093 cur_char = RB_Check_Fold_Start (cur_char,
1096 if ((extra_flags & FOLD) && found)
1100 RB_Say ("fold name %s\n", foldname);
1101 RB_Say ("fold begin %d\n", ++fold);
1102 RB_Say ("tabs %d\n", tabs);
1103 sprintf (fname, "%s_fold_%d.html", doc_base, fold);
1104 RB_Say ("opening file %s\n", fname);
1105 fp = fopen (fname, "w");
1106 RB_Generate_Doc_Start (fp, foldname, foldname, 0);
1107 fprintf (fp, "<PRE>\n");
1108 fprintf (dest_doc, "<A HREF=\"%s\">... %s</A>",
1110 in_fold++; /* PetteriK 08.04.2000 */
1111 cur_char = RB_Generate_Item_Body (fp, dest_name,
1112 cur_char, end_of_item,
1115 in_fold--; /* PetteriK 08.04.2000 */
1116 /* skip chars until newline */
1117 while (*cur_char != '\n')
1122 fprintf (fp, "\n</PRE>\n");
1123 RB_Generate_Doc_End (fp, foldname);
1126 else if ((extra_flags & FOLD) && RB_Check_Fold_End (cur_char))
1128 RB_Say ("fold end found\n");
1131 else if ((html_incr = RB_HTML_Extra (dest_doc,
1132 item_type, cur_char)))
1134 cur_char += html_incr;
1144 if (extra_flags & FOLD)
1146 if (tabs >= tabs_to_skip)
1148 for (tb %= tab_size; tb < tab_size; ++tb)
1150 fputc (' ', dest_doc);
1157 for (tb %= tab_size; tb < tab_size; ++tb)
1159 fputc (' ', dest_doc);
1164 fprintf (dest_doc, "<");
1168 fprintf (dest_doc, ">");
1172 fprintf (dest_doc, "&");
1176 fputc (c, dest_doc);
1180 break; /* end case HTML */
1189 for (tb %= tab_size; tb < tab_size; ++tb)
1190 fputc (' ', dest_doc);
1193 /* not used in LaTeX's verbatim environment */
1201 fputc ('\\', dest_doc);
1202 fputc (c, dest_doc);
1206 fprintf (dest_doc, "$\\backslash$");
1210 fprintf (dest_doc, "$\\tilde$");
1214 fprintf (dest_doc, "$\\,\\!^{\\sim}$");
1219 fputc (c, dest_doc);
1231 for (tb %= tab_size; tb < tab_size; ++tb)
1232 fputc (' ', dest_doc);
1237 fputc ('\\', dest_doc);
1238 fputc (c, dest_doc);
1242 fputc (c, dest_doc);
1248 fputc (c, dest_doc);
1255 switch (output_mode)
1258 if (file_name && strcmp (file_name, dest_name))
1259 fprintf (dest_doc, "@{\"%s\" Link \"%s/%s\"}",
1260 label_name, file_name, label_name);
1263 if (strcmp (label_name, function_name))
1264 fprintf (dest_doc, "@{\"%s\" Link \"%s\"}",
1265 label_name, label_name);
1268 fprintf (dest_doc, "%s",
1269 att_start_command[MAKE_BOLD][output_mode]);
1270 fprintf (dest_doc, "%s", label_name);
1271 fprintf (dest_doc, "%s",
1272 att_stop_command[MAKE_BOLD][output_mode]);
1278 /* Include the file name in the link if we are in fold
1279 * PetteriK 08.04.2000
1283 /* We are in fold, always use the file name in the link,
1284 * in file_name == NULL (i.e. the label is in the current file
1285 * that we are processing), refer to value in dest_name.
1286 * This also makes sure that we link correctly if function_name
1287 * is the same as label_name.
1289 fprintf (dest_doc, "<A HREF=\"%s#%s\">%s</A>",
1290 (file_name ? file_name : dest_name),
1291 label_name, label_name);
1293 else if (file_name && strcmp (file_name, dest_name))
1296 fprintf (dest_doc, "<A HREF=\"%s#%s\">%s</A>",
1297 file_name, label_name, label_name);
1299 fprintf (dest_doc, "<A HREF=\"%s-%s.html\">%s</A>",
1300 RB_FilePartStart(file_name), label_name,
1305 if (strcmp (label_name, function_name))
1308 fprintf (dest_doc, "<A HREF=\"#%s\">%s</A>",
1309 label_name, label_name);
1311 fprintf (dest_doc, "<A HREF=\"%s-%s.html\">%s</A>",
1312 RB_FilePart(doc_base), label_name,
1317 fprintf (dest_doc, "%s",
1318 att_start_command[MAKE_BOLD][output_mode]);
1319 fprintf (dest_doc, "%s", label_name);
1320 fprintf (dest_doc, "%s",
1321 att_stop_command[MAKE_BOLD][output_mode]);
1327 if (strcmp (label_name, function_name))
1331 cook_link = RB_CookStr (label_name);
1332 fprintf (dest_doc, "{\\uldb %s}{\\v %s}",
1333 label_name, cook_link);
1338 fprintf (dest_doc, "%s",
1339 att_start_command[MAKE_BOLD][output_mode]);
1340 fprintf (dest_doc, "%s", label_name);
1341 fprintf (dest_doc, "%s",
1342 att_stop_command[MAKE_BOLD][output_mode]);
1346 fprintf (dest_doc, "%s", label_name);
1348 tmp = strlen (label_name);
1356 if (output_mode == RTF)
1357 fprintf (dest_doc, "\\line");
1358 fputc ('\n', dest_doc);
1362 *end_of_item = old_char;
1370 /****f* ROBODoc/RB_HTML_Extra
1376 * 05/15/2000 Added mailto: support (Guillaume Etorre)
1378 * Check and process embedded hyperlinks.
1379 * RETURN VAL* FUNCTION
1380 * Check and process embedded hyperlinks.
1382 * Number of chars processed from *cur_char
1384 * Flag for C and other grammars.
1386 * As the documentation generated for this functions shows, if
1387 * the C source code contains a string with " / * " in it, this
1393 RB_HTML_Extra (FILE * dest_doc, int item_type, char *cur_char)
1398 if (strncmp ("http://", cur_char, strlen ("http://")) == 0)
1400 sscanf (cur_char, "%s", link);
1401 RB_Say ("found link %s\n", link);
1402 res = (strlen (link) - 1);
1403 fprintf (dest_doc, "<A HREF=\"%s\">%s</A>", link, link);
1405 else if (strncmp ("href:", cur_char, strlen ("href:")) == 0)
1407 /* handy in relative hyperlink paths, e.g. href:../../modulex/ */
1408 sscanf ((cur_char + strlen ("href:")), "%s", link);
1409 RB_Say ("found link %s\n", link);
1410 res = (strlen (link) + strlen ("href:") - 1);
1411 fprintf (dest_doc, "<A HREF=\"%s\">%s</A>", link, link);
1413 else if (strncmp ("mailto:", cur_char, strlen ("mailto:")) == 0)
1415 sscanf ((cur_char + strlen ("mailto:")), "%s", link);
1416 RB_Say ("found mail to %s\n", link);
1417 res = (strlen (link) + strlen ("mailto:") - 1);
1418 fprintf (dest_doc, "<A HREF=\"mailto:%s\">%s</A>", link, link);
1420 else if ((extra_flags & C_MODE) && (item_type == SOURCE_ITEM) &&
1421 (strncmp ("/*", cur_char, 2) == 0))
1423 /* start of C comment */
1424 fprintf (dest_doc, "<FONT COLOR = \"#FF0000\">/*");
1427 else if ((extra_flags & C_MODE) && (item_type == SOURCE_ITEM) &&
1428 (strncmp ("*/", cur_char, 2) == 0))
1430 /* end of C comment */
1431 fprintf (dest_doc, "*/</FONT>");
1440 /****f* ROBODoc/RB_Generate_Index
1442 * RB_Generate_Index -- generate index file based on xref files.
1444 * void RB_Generate_Index(FILE *dest, char *name)
1446 * Create a master index file. It contains pointers to the
1447 * documentation generated for each source file, as well as all
1448 * "objects" found in the source files.
1453 RB_Generate_Index (FILE * dest, char *source)
1455 RB_Slow_Sort_Links ();
1457 switch (output_mode)
1461 if (document_title) {
1462 RB_Generate_Doc_Start (dest, source, document_title, 0);
1463 fprintf (dest, "<H1>%s</H1>\n", document_title);
1465 RB_Generate_Doc_Start (dest, source, "Master Index File", 0);
1466 fprintf (dest, "<H1>Master Index File</H1>\n");
1468 if (RB_Number_Of_Links (MAIN_HEADER, NULL))
1469 RB_Generate_Index_Table (dest, MAIN_HEADER, "Modules");
1470 // RB_Generate_Index_Table (dest, NO_HEADER, "Source Files");
1471 if (RB_Number_Of_Links (CLASS_HEADER, NULL))
1472 RB_Generate_Index_Table (dest, CLASS_HEADER, "Classes");
1473 if (RB_Number_Of_Links (METHOD_HEADER, NULL))
1474 RB_Generate_Index_Table (dest, METHOD_HEADER, "Methods");
1475 if (RB_Number_Of_Links (STRUCT_HEADER, NULL))
1476 RB_Generate_Index_Table (dest, STRUCT_HEADER, "Structures");
1477 if (RB_Number_Of_Links (FUNCTION_HEADER, NULL))
1478 RB_Generate_Index_Table (dest, FUNCTION_HEADER, "Functions");
1479 if (RB_Number_Of_Links (VARIABLE_HEADER, NULL))
1480 RB_Generate_Index_Table (dest, VARIABLE_HEADER, "Global Variables");
1481 if (RB_Number_Of_Links (CONSTANT_HEADER, NULL))
1482 RB_Generate_Index_Table (dest, CONSTANT_HEADER, "Constants");
1483 if (RB_Number_Of_Links (GENERIC_HEADER, NULL))
1484 RB_Generate_Index_Table (dest, GENERIC_HEADER, "Generic");
1485 if (RB_Number_Of_Links (INTERNAL_HEADER, NULL))
1486 RB_Generate_Index_Table (dest, INTERNAL_HEADER, "Internal");
1487 RB_Generate_Doc_End (dest, source);
1491 RB_Generate_Doc_Start (dest, source, "Master File", 0);
1492 RB_Generate_LaTeX_Includes (dest);
1493 RB_Generate_Doc_End (dest, source);
1499 /****f* ROBODoc/Generate_LaTeX_Includes
1501 * Generate_LaTeX_Includes -- generate include commands
1503 * void RB_Generate_LaTeX_Includes (FILE *dest)
1505 * Generates a series of \include commands to include the
1506 * documentation generated for each source file into one
1512 RB_Generate_LaTeX_Includes (FILE *dest)
1514 struct RB_link *cur_link;
1515 for (cur_link = first_link;
1517 cur_link = cur_link->next_link) {
1519 if (cur_link->type == NO_HEADER)
1520 fprintf (dest, "\\include{%s}\n", cur_link->label_name);
1525 /****f* ROBODoc/RB_Generate_Index_Table
1527 * RB_Generate_Index --
1529 * void RB_Generate_Index_Table(FILE *, int type, char *title)
1530 * RB_Generate_Index_Table(dest, type, title)
1532 * Creates a table with index items of a particular type.
1533 * If the type is NO_HEADER, then the table is a table of
1534 * source files. In this case no link is added if the
1535 * source file did not contain any documentation.
1537 * dest -- output file
1538 * type -- kind of header index.
1539 * title -- title for the table
1544 RB_Generate_Index_Table (FILE * dest, int type, char *title)
1546 struct RB_link *cur_link;
1547 int number_of_columns;
1550 number_of_columns = 60 / RB_Max_Name_Length (type, NULL);
1552 fprintf (dest, "<H2>%s</H2>\n", title);
1553 fprintf (dest, "<TABLE>\n");
1555 for (cur_link = first_link;
1557 cur_link = cur_link->next_link)
1559 if (cur_link->type == type)
1561 if (cur_column == 0)
1563 fprintf (dest, "<TR>\n");
1565 if (type == NO_HEADER)
1567 if (RB_Number_Of_Links (NO_HEADER, cur_link->file_name) > 1)
1570 "<TD><A HREF=\"%s-%s.html\"><TT>%s</TT></A></TD>\n",
1571 RB_FilePartStart(cur_link->file_name),
1572 cur_link->label_name,
1573 cur_link->label_name);
1577 fprintf (dest, "<TD>%s</TD>\n", cur_link->label_name);
1582 if (type == MAIN_HEADER)
1584 fprintf (dest, "<TD><A HREF=\"%s.html\"><TT>%s</TT></A></TD>\n",
1585 RB_FilePartStart(cur_link->file_name),
1586 cur_link->label_name);
1590 fprintf (dest, "<TD><A HREF=\"%s-%s.html\"><TT>%s</TT></A></TD>\n",
1591 RB_FilePartStart(cur_link->file_name),
1592 cur_link->label_name,
1593 cur_link->label_name);
1597 if (cur_column > number_of_columns)
1599 fprintf (dest, "</TR>\n");
1604 for (; cur_column <= number_of_columns;)
1606 if (cur_column == 0)
1608 fprintf (dest, "<TR>\n");
1610 fprintf (dest, "<TD></TD>\n");
1613 fprintf (dest, "</TR>\n");
1614 fprintf (dest, "</TABLE>\n");
1617 /******* END RB_Generate_Index_Table *****/
1620 /****f* ROBODoc/RB_Number_Of_Links
1622 * RB_Number_Of_Links -- Count the number of links.
1624 * Counts the number of links that are of a particular type
1625 * and that can be found in a particular file.
1627 * type -- the header type of the header the link is pointing to.
1628 * If NO_HEADER, all header types are counted.
1629 * file_name -- name of the file the link comes from, can be NULL, in
1630 * which case only the type is checked.
1637 RB_Number_Of_Links (int type, char *file_name)
1639 struct RB_link *cur_link;
1642 for (cur_link = first_link;
1644 cur_link = cur_link->next_link)
1646 if (cur_link->type == type || (type == NO_HEADER))
1650 if (strcmp (file_name, cur_link->file_name) == 0)
1666 /****f* ROBODoc/RB_Max_Name_Length
1668 * RB_Max_Name_Length -- find longest label name.
1670 * Find the length of the longest label name in a sub list
1671 * of the list with links. This is used to determine how
1672 * many columns can be displayed in a table.
1673 * The sublist is specified by the type of header the link
1674 * should point to, as well as by the name of the documentation
1677 * RB_Max_Name_Length(CLASS_HEADER, "muppets.c.html")
1678 * longest label name in the list of links to class headers
1679 * in muppets.c.html.
1680 * RB_Max_Name_Length(CLASS_HEADER, NULL)
1681 * longest label name in the list of links to class headers.
1683 * type -- type of header
1684 * file_name -- file the header come from, can be NULL.
1685 * In which links from all files are used.
1690 RB_Max_Name_Length (int type, char *file_name)
1692 struct RB_link *cur_link;
1695 for (cur_link = first_link;
1697 cur_link = cur_link->next_link)
1699 if (cur_link->type == type)
1703 if (strcmp (file_name, cur_link->file_name) == 0)
1705 if (strlen (cur_link->label_name) > n)
1707 n = strlen (cur_link->label_name);
1713 if (strlen (cur_link->label_name) > n)
1715 n = strlen (cur_link->label_name);