2 Copyright (C) 1994-2007 Frans Slothouber, Jacco van Weert, Petteri Kettunen,
3 Bernd Koesling, Thomas Aglassinger, Anthon Pang, Stefan Kost, David Druffner,
4 Sasha Vasko, Kai Hofmann, Thierry Pierron, Friedrich Haase, and Gergely Budai.
6 This file is part of ROBODoc
8 ROBODoc is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 /****h* ROBODoc/HTML_Generator
26 * The generator for HTML output.
28 * The generator supports sections upto 7 levels deep. It supports
29 * a Table of Contents based on all headers. A masterindex for
30 * all headertypes and seperate masterindexes for each headertype.
32 * MODIFICATION HISTORY
33 * 2003-02-03 Frans Slothouber Refactoring
34 * ????-??-?? Frans Slothouber V1.0
36 * $Id: html_generator.c,v 1.91 2007/07/10 19:13:51 gumpu Exp $
46 #include "html_generator.h"
52 #include "headertypes.h"
53 #include "generator.h"
57 #include "directory.h"
60 #include "roboconfig.h"
66 static char *css_name = NULL;
67 static int in_linecomment = 0; // are we in a line comment?
69 static void RB_HTML_Generate_String(
71 const char *a_string );
75 /* TODO Documentation */
76 static void HTML_Generate_Div(
81 fprintf( dest_doc, "<div id=\"%s\">\n", id );
85 /* TODO Documentation */
86 static void HTML_Generate_Div_End(
90 fprintf( dest_doc, "</div> <!-- %s -->\n", id );
94 /* TODO Documentation */
96 char *HTML_TOC_Index_Filename(
97 struct RB_Document *document )
99 char *toc_index_path = NULL;
100 char *toc_index_name = "toc_index.html";
102 assert( document->docroot->name );
105 calloc( strlen( toc_index_name ) + 2 +
106 strlen( document->docroot->name ), 1 );
107 strcpy( toc_index_path, document->docroot->name );
108 strcat( toc_index_path, toc_index_name );
110 return toc_index_path;
115 /* TODO Documentation */
116 static void RB_HTML_Generate_Source_Tree_Entry(
119 struct RB_Path *parent_path,
120 struct RB_Directory *srctree,
121 struct RB_Document *document )
123 struct RB_Path *cur_path;
124 struct RB_Filename *cur_filename;
126 fprintf( dest_doc, "<ul>\n" );
128 for ( cur_filename = srctree->first;
129 cur_filename; cur_filename = cur_filename->next )
131 if ( cur_filename->path == parent_path )
135 if ( cur_filename->link )
137 if ( document->actions.do_one_file_per_header )
139 fprintf( dest_doc, "<li><tt>\n" );
140 RB_HTML_Generate_String( dest_doc, cur_filename->name );
141 fprintf( dest_doc, "</tt></li>\n" );
145 r = RB_HTML_RelativeAddress( dest_name,
148 fprintf( dest_doc, "<li>\n" );
149 fprintf( dest_doc, "<a href=\"%s#%s\"><tt>\n", r,
150 cur_filename->link->label_name );
151 RB_HTML_Generate_String( dest_doc, cur_filename->name );
152 fprintf( dest_doc, "</tt></a></li>\n" );
157 for ( cur_path = srctree->first_path;
158 cur_path; cur_path = cur_path->next )
160 if ( cur_path->parent == parent_path )
162 fprintf( dest_doc, "<li>\n" );
163 RB_HTML_Generate_String( dest_doc, cur_path->name );
164 RB_HTML_Generate_Source_Tree_Entry( dest_doc, dest_name, cur_path,
166 fprintf( dest_doc, "</li>\n" );
169 fprintf( dest_doc, "</ul>\n" );
172 /* TODO Documentation */
173 void RB_HTML_Generate_Source_Tree(
176 struct RB_Document *document )
178 struct RB_Directory *srctree;
180 srctree = document->srctree;
181 RB_HTML_Generate_Source_Tree_Entry( dest_doc, dest_name, NULL, srctree,
186 /****if* HTML_Generator/RB_HTML_Generate_String
188 * Write a string to the destination document, escaping
189 * characters where necessary.
192 static void RB_HTML_Generate_String(
194 const char *a_string )
197 * o dest_doc -- the file the characters are written too
198 * o a_string -- a nul terminated string.
200 * RB_HTML_Generate_Char()
205 int l = strlen( a_string );
208 for ( i = 0; i < l; ++i )
211 RB_HTML_Generate_Char( dest_doc, c );
218 /****if* HTML_Generator/RB_HTML_Generate_False_Link
220 * Create a representation for a link that links an word in
221 * a header to the header itself.
224 void RB_HTML_Generate_False_Link(
229 * * dest_doc -- the file the representation is written to.
230 * * name -- the word.
234 fprintf( dest_doc, "<strong>" );
235 RB_HTML_Generate_String( dest_doc, name );
236 fprintf( dest_doc, "</strong>" );
243 /****f* HTML_Generator/RB_HTML_Color_String
245 * Generates various colored strings
249 static void RB_HTML_Color_String(
259 RB_HTML_Generate_String( dest_doc, string );
260 fprintf( dest_doc, "</span>" );
265 fprintf( dest_doc, "<span class=\"%s\">", class );
266 RB_HTML_Generate_String( dest_doc, string );
269 // opening, string, closing
271 fprintf( dest_doc, "<span class=\"%s\">", class );
272 RB_HTML_Generate_String( dest_doc, string );
273 fprintf( dest_doc, "</span>" );
276 // opening, char, closing
278 fprintf( dest_doc, "<span class=\"%s\">", class );
279 RB_HTML_Generate_Char( dest_doc, *string );
280 fprintf( dest_doc, "</span>" );
292 /****f* HTML_Generator/RB_HTML_Generate_Line_Comment_End
294 * Check if a line comment is active and generate ending sequence for it.
295 * Should be called at the end of each SOURCE line.
298 void RB_HTML_Generate_Line_Comment_End(
301 // Check if we are in a line comment
302 if ( in_linecomment )
304 // and end the line comment
306 RB_HTML_Color_String( dest_doc, in_linecomment, COMMENT_CLASS, "" );
313 /****f* HTML_Generator/RB_HTML_Generate_Extra
315 * Do some additional processing to detect HTML extra's like
316 * file references and other kind of links for the documentation
320 int RB_HTML_Generate_Extra(
322 enum ItemType item_type,
327 * o dest_doc -- the file to write to.
328 * o item_type -- the kind of item the body belongs to.
329 * o cur_char -- pointer to a substring of the item's body
330 * o prev_char -- the character just before cur char (zero if none)
332 * Number of characters produced.
336 char link[1024], *str;
339 static int incomment = 0; /* are we in comment? */
340 static int quote = 0; /* double quote */
341 static int squote = 0; /* single quote */
343 // Reset comment and quote state machine if not source item
344 if ( !Works_Like_SourceItem( item_type ) )
351 // else check for quotations and string literals
352 else if ( !( incomment || in_linecomment ) )
356 // Check for quoted string literals ("string")
358 if ( !squote && course_of_action.do_quotes )
360 if ( prev_char != '\\' )
363 RB_HTML_Color_String( dest_doc, quote,
367 else if ( quote && *( ( char * ) ( cur_char - 2 ) ) == '\\' )
369 quote = !quote; /* case "... \\" */
370 RB_HTML_Color_String( dest_doc, quote,
377 // Check for single quoted string literals ('string')
379 if ( !quote && course_of_action.do_squotes )
381 if ( prev_char != '\\' )
384 RB_HTML_Color_String( dest_doc, squote,
385 SQUOTE_CLASS, "\'" );
388 else if ( squote && *( ( char * ) ( cur_char - 2 ) ) == '\\' )
390 squote = !squote; /* case '\\' */
391 RB_HTML_Color_String( dest_doc, squote,
392 SQUOTE_CLASS, "\'" );
403 // Recognise line comments
404 if ( Works_Like_SourceItem( item_type ) && !incomment && !quote
405 && !squote && course_of_action.do_line_comments )
407 // check for line comment start
408 if ( !in_linecomment )
411 Find_Parameter_Partial( &
413 source_line_comments ), cur_char );
417 RB_HTML_Color_String( dest_doc, in_linecomment,
418 COMMENT_CLASS, str );
419 // We found it, so exit
420 return strlen( str ) - 1;
423 // The end of line comments are generated in
424 // RB_HTML_Generate_Line_Comment_End()
427 // Recognise block comments
428 if ( Works_Like_SourceItem( item_type ) && !in_linecomment && !quote
429 && !squote && course_of_action.do_block_comments )
431 // Check for block comment start
435 Find_Parameter_Partial( &
437 remark_begin_markers ), cur_char );
441 RB_HTML_Color_String( dest_doc, incomment,
442 COMMENT_CLASS, str );
443 // We found it, so exit
444 return strlen( str ) - 1;
447 // Check for block comment end
451 Find_Parameter_Partial( &( configuration.remark_end_markers ),
456 RB_HTML_Color_String( dest_doc, incomment,
457 COMMENT_CLASS, str );
458 // We found it, so exit
459 return strlen( str ) - 1;
464 // Do further source formating
465 if ( Works_Like_SourceItem( item_type ) &&
466 !in_linecomment && !incomment && !quote && !squote )
468 // Check for keywords
469 if ( configuration.keywords.number && course_of_action.do_keywords )
473 // Check if we are at the beginning of a word
474 if ( !utf8_isalnum( prev_char ) && ( prev_char != '_' ) )
477 for ( i = 1; // A word should have at least one character...
478 utf8_isalnum( cur_char[i] ) || ( cur_char[i] == '_' );
480 // Check if it is a keyword
481 if ( ( keyword = Find_Keyword( cur_char, i ) ) )
483 RB_HTML_Color_String( dest_doc, 2, KEYWORD_CLASS,
491 // Do some fancy coloration for non-alphanumeric chars
492 if ( !utf8_isalnum( *cur_char ) && *cur_char != '_'
493 && *cur_char != ' ' && course_of_action.do_non_alpha )
495 RB_HTML_Color_String( dest_doc, 3, SIGN_CLASS, cur_char );
500 // Check for links, etc...
501 if ( incomment || in_linecomment || !Works_Like_SourceItem( item_type ) )
503 if ( strncmp( "http://", cur_char, 7 ) == 0 )
505 sscanf( cur_char, "%s", link );
506 RB_Say( "found link %s\n", SAY_DEBUG, link );
507 res = ( strlen( link ) - 1 );
508 /* [ 697247 ] http://body. does not skip the '.' */
509 if ( link[( strlen( link ) - 1 )] == '.' )
511 link[( strlen( link ) - 1 )] = '\0';
512 fprintf( dest_doc, "<a href=\"%s\">%s</a>.", link, link );
516 fprintf( dest_doc, "<a href=\"%s\">%s</a>", link, link );
519 else if ( strncmp( "href:", cur_char, 5 ) == 0 )
522 * handy in relative hyperlink paths, e.g.
523 * href:../../modulex/
525 sscanf( ( cur_char + 5 ), "%s", link );
526 RB_Say( "found link %s\n", SAY_DEBUG, link );
527 res = ( strlen( link ) + 4 );
528 fprintf( dest_doc, "<a href=\"%s\">%s</a>", link, link );
530 else if ( strncmp( "file:/", cur_char, strlen( "file:/" ) ) == 0 )
532 sscanf( cur_char, "%s", link );
533 RB_Say( "found link %s\n", SAY_DEBUG, link );
534 res = ( strlen( link ) - 1 );
535 fprintf( dest_doc, "<a href=\"%s\">%s</a>", link, link );
537 else if ( strncmp( "mailto:", cur_char, 7 ) == 0 )
539 sscanf( ( cur_char + 7 ), "%s", link );
540 RB_Say( "found mail to %s\n", SAY_DEBUG, link );
541 res = ( strlen( link ) + 6 );
542 fprintf( dest_doc, "<a href=\"mailto:%s\">%s</a>", link, link );
544 else if ( strncmp( "image:", cur_char, 6 ) == 0 )
546 sscanf( ( cur_char + 6 ), "%s", link );
547 RB_Say( "found image %s\n", SAY_DEBUG, link );
548 res = ( strlen( link ) + 5 );
549 fprintf( dest_doc, "<img src=\"%s\">", link );
560 void RB_HTML_Generate_Item_Name(
564 fprintf( dest_doc, "<p class=\"item_name\">" );
565 RB_HTML_Generate_String( dest_doc, name );
566 fprintf( dest_doc, "</p>\n" );
569 void RB_HTML_Generate_Item_Begin(
578 void RB_HTML_Generate_Item_End(
588 int sectiontoc_counters[MAX_SECTION_DEPTH];
590 /****f* HTML_Generator/RB_HTML_Generate_TOC_Section
592 * Create a table of contents based on the hierarchy of
593 * the headers starting for a particular point in this
594 * hierarchy (the parent).
597 void RB_HTML_Generate_TOC_Section(
600 struct RB_header *parent,
601 struct RB_header **headers,
606 * o dest_doc -- the file to write to.
607 * o dest_name -- the name of this file.
608 * o parent -- the parent of the headers for which the the
609 * current level(depth) of TOC is created.
610 * o headers -- an array of headers for which the TOC is created
611 * o count -- the number of headers in this array
612 * o depth -- the current depth of the TOC
614 * This is a recursive function and tricky stuff.
618 struct RB_header *header;
621 ++sectiontoc_counters[depth];
623 for ( i = depth + 1; i < MAX_SECTION_DEPTH; ++i )
625 sectiontoc_counters[i] = 0;
629 fprintf( dest_doc, "<li>" );
631 // Do not generate section numbers if sectionnameonly
632 if ( !( course_of_action.do_sectionnameonly ) )
634 for ( i = 1; i <= depth; ++i )
636 fprintf( dest_doc, "%d.", sectiontoc_counters[i] );
638 fprintf( dest_doc, " " );
642 // Generate Link to first reference name
643 RB_HTML_Generate_Link( dest_doc, dest_name, parent->file_name,
645 // only generate function name if sectionnameonly
646 ( course_of_action.do_sectionnameonly ) ?
647 parent->function_name : parent->name, 0 );
649 // Generate links to further reference names
650 for ( n = 1; n < parent->no_names; n++ )
652 RB_HTML_Generate_String( dest_doc, ", " );
653 RB_HTML_Generate_Link( dest_doc, dest_name, parent->file_name,
654 parent->unique_name, parent->names[n], 0 );
658 fprintf( dest_doc, "</li>\n" );
660 for ( i = 0; i < count; ++i )
663 if ( header->parent == parent )
665 // Generate better TOC level hiearchy (Thuffir)
666 // We only generate <ul> once for a level
670 fprintf( dest_doc, "<ul>\n" );
672 RB_HTML_Generate_TOC_Section( dest_doc, dest_name, header,
673 headers, count, depth + 1 );
680 // If we have generated an <ul> before, generate the closing one too.
682 fprintf( dest_doc, "</ul>\n" );
688 void RB_HTML_Generate_TOC_2(
690 struct RB_header **headers,
692 struct RB_Part *owner,
695 struct RB_header *header;
699 for ( i = 0; i < MAX_SECTION_DEPTH; ++i )
701 sectiontoc_counters[i] = 0;
703 fprintf( dest_doc, "<h3>TABLE OF CONTENTS</h3>\n" );
704 if ( course_of_action.do_sections )
706 /* --sections was specified, create a TOC based on the
707 * hierarchy of the headers.
709 fprintf( dest_doc, "<ul>\n" );
710 for ( i = 0; i < count; ++i )
715 if ( header->parent )
717 /* Will be done in the subfunction */
721 RB_HTML_Generate_TOC_Section( dest_doc, dest_name, header,
722 headers, count, depth );
727 /* This is the TOC for a specific RB_Part (MultiDoc
728 * documentation). We only include the headers that
729 * are part of the subtree. That is, headers that are
730 * parth the RB_Part, or that are childern of the
731 * headers in the RB_Part.
733 if ( header->owner == owner )
736 /* Any of the parents of this header should not
737 * have the same owner as this header, otherwise
738 * this header will be part of the TOC multiple times.
740 int no_bad_parent = TRUE;
741 struct RB_header *parent = header->parent;
743 for ( ; parent; parent = parent->parent )
745 if ( parent->owner == owner )
747 no_bad_parent = FALSE;
753 RB_HTML_Generate_TOC_Section( dest_doc, dest_name,
754 header, headers, count,
760 fprintf( dest_doc, "</ul>\n" );
764 /* No --section option, generate a plain, one-level
767 fprintf( dest_doc, "<ul>\n" );
769 for ( i = 0; i < count; ++i )
772 if ( header->name && header->function_name &&
773 ( ( owner == NULL ) || ( header->owner == owner ) ) )
775 for ( j = 0; j < header->no_names; j++ )
777 fprintf( dest_doc, "<li>" );
779 RB_HTML_Generate_Link( dest_doc, dest_name,
782 header->names[j], 0 );
783 fprintf( dest_doc, "</li>\n" );
787 fprintf( dest_doc, "</ul>\n" );
793 /****f* HTML_Generator/RB_HTML_Generate_Label
795 * Generate a label (name) that can be refered too.
796 * A label should consist of only alphanumeric characters so
797 * all 'odd' characters are replaced with their ASCII code in
801 void RB_HTML_Generate_Label(
806 * o dest_doc -- the file to write it to.
807 * o name -- the name of the label.
812 int l = strlen( name );
815 fprintf( dest_doc, "<a name=\"" );
816 for ( i = 0; i < l; ++i )
819 if ( utf8_isalnum( c ) )
821 RB_HTML_Generate_Char( dest_doc, c );
827 sprintf( buf, "%02x", c );
828 RB_HTML_Generate_Char( dest_doc, buf[0] );
829 RB_HTML_Generate_Char( dest_doc, buf[1] );
832 fprintf( dest_doc, "\">\n" );
839 static int section_counters[MAX_SECTION_DEPTH];
842 /* TODO Documentation */
844 void RB_HTML_Generate_BeginSection(
848 struct RB_header *header )
852 ++section_counters[depth];
853 for ( i = depth + 1; i < MAX_SECTION_DEPTH; ++i )
855 section_counters[i] = 0;
866 fprintf( dest_doc, "<h%d>", depth );
867 // Only generate section numbers if no sectionnameonly
868 if ( !( course_of_action.do_sectionnameonly ) )
870 for ( i = 1; i <= depth; ++i )
872 fprintf( dest_doc, "%d.", section_counters[i] );
874 fprintf( dest_doc, " " );
877 // Print Header "first" name
878 RB_HTML_Generate_String( dest_doc, name );
880 // Print further names
881 for ( i = 1; i < header->no_names; i++ )
883 fprintf( dest_doc, ( i % header_breaks ) ? ", " : ",<br />" );
884 RB_HTML_Generate_String( dest_doc, header->names[i] );
887 // Include module name if not sectionnameonly
888 if ( !( course_of_action.do_sectionnameonly ) )
890 fprintf( dest_doc, " [ " );
891 RB_HTML_Generate_String( dest_doc, header->htype->indexName );
892 fprintf( dest_doc, " ]" );
895 fprintf( dest_doc, " </h%d>\n", depth );
898 /* too deep, don't do anything. */
903 void RB_HTML_Generate_EndSection(
915 char *RB_HTML_Get_Default_Extension(
921 /****f* HTML_Generator/RB_HTML_Generate_Doc_Start
923 * RB_HTML_Generate_Doc_Start --
925 * Generate the first part of a HTML document.
926 * As far as ROBODoc is concerned a HTML document
927 * consists of three parts:
928 * * The start of a document
929 * * The body of a document
930 * * The end of a document
933 void RB_HTML_Generate_Doc_Start(
941 * o dest_doc -- the output file.
942 * o src_name -- The file or directoryname from which
943 * this document is generated.
944 * o name -- The title for this document
945 * o dest_name -- the name of the output file.
946 * o charset -- the charset to be used for the file.
951 if ( course_of_action.do_headless )
953 /* The user wants a headless document, so we skip everything
954 * upto and until <BODY>
959 /* Append document type and title */
960 fprintf( dest_doc, "<?xml version=\"1.0\" encoding=\"%s\"?>\n",
961 charset ? charset : DEFAULT_CHARSET );
963 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n" );
965 " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" );
968 "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" );
969 fprintf( dest_doc, "<head>\n" );
971 "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\" />\n" );
972 /* TODO is charset still needed?? */
974 "<meta http-equiv=\"Content-type\" content=\"text/html; charset=%s\" />\n",
975 charset ? charset : DEFAULT_CHARSET );
976 RB_InsertCSS( dest_doc, dest_name );
977 fprintf( dest_doc, "<title>%s</title>\n", name );
979 /* append SGML-comment with document- and copyright-info. This code
980 * ensures that every line has an own comment to avoid problems with
982 fprintf( dest_doc, "<!-- Source: %s -->\n", src_name );
983 if ( course_of_action.do_nogenwith )
989 static const char copyright_text[]
990 = COMMENT_ROBODOC /* COMMENT_COPYRIGHT */ ;
992 char previous_char = '\n';
993 char current_char = copyright_text[i];
995 while ( current_char )
997 if ( previous_char == '\n' )
999 fprintf( dest_doc, "<!-- " );
1001 if ( current_char == '\n' )
1003 fprintf( dest_doc, " -->" );
1005 else if ( ( current_char == '-' )
1006 && ( previous_char == '-' ) )
1008 /* avoid "--" inside SGML-comment, and use "-_" instead; this
1009 * looks a bit strange, but one should still be able to figure
1010 * out what is meant when reading the output */
1013 fputc( current_char, dest_doc );
1015 previous_char = current_char;
1016 current_char = copyright_text[i];
1020 /* append heading and start list of links to functions */
1021 fprintf( dest_doc, "</head>\n" );
1022 fprintf( dest_doc, "<body>\n" );
1025 // HTML_Generate_Div( dest_doc, "container" );
1027 /* Generate document title if available (Thuffir) */
1028 HTML_Generate_Div( dest_doc, "logo" );
1029 fprintf( dest_doc, "<a name=\"robo_top_of_doc\">" );
1030 if ( document_title )
1031 RB_HTML_Generate_String( dest_doc, document_title );
1032 fprintf( dest_doc, "</a>\n" );
1033 HTML_Generate_Div_End( dest_doc, "logo" );
1043 /*x**if* HTML_Generator/RB_HTML_Generate_Doc_End
1045 * RB_HTML_Generate_Doc_End --
1047 * Close of the document with the proper end tags.
1051 void RB_HTML_Generate_Doc_End(
1060 HTML_Generate_Div( dest_doc, "footer" );
1061 /* TODO This should be done with
1062 * RB_Generate_Label()
1064 if ( course_of_action.do_nogenwith )
1066 fprintf( dest_doc, "<p>Generated from %s on ", src_name );
1067 RB_TimeStamp( dest_doc );
1068 fprintf( dest_doc, "</p>\n" );
1073 "<p>Generated from %s with <a href=\"http://www.xs4all.nl/~rfsber/Robo/robodoc.html\">ROBODoc</a> V%s on ",
1074 src_name, VERSION );
1075 RB_TimeStamp( dest_doc );
1076 fprintf( dest_doc, "</p>\n" );
1078 HTML_Generate_Div_End( dest_doc, "footer" );
1080 // HTML_Generate_Div_End( dest_doc, "container" );
1082 if ( course_of_action.do_footless )
1084 /* The user does not want the foot of the
1090 fprintf( dest_doc, "</body>\n</html>\n" );
1095 void RB_HTML_Generate_Nav_Bar(
1096 struct RB_Document *document,
1098 struct RB_header *current_header )
1100 char *current_filename = NULL;
1101 char *target_filename = NULL;
1103 char *label_name = NULL;
1105 current_filename = RB_Get_FullDocname( current_header->owner->filename );
1106 target_filename = RB_Get_FullDocname( current_header->owner->filename );
1107 label = Get_Fullname( current_header->owner->filename );
1108 /* The navigation bar */
1109 fprintf( current_doc, "<p>" );
1112 fprintf( current_doc, "[ " );
1113 RB_HTML_Generate_Link( current_doc, current_filename, NULL,
1114 "robo_top_of_doc", "Top", 0 );
1115 fprintf( current_doc, " ] " );
1118 if ( current_header->parent )
1120 fprintf( current_doc, "[ " );
1122 RB_Get_FullDocname( current_header->parent->owner->filename );
1123 label = current_header->parent->unique_name;
1124 label_name = current_header->parent->function_name;
1125 RB_HTML_Generate_Link( current_doc, current_filename, target_filename,
1126 label, label_name, 0 );
1127 fprintf( current_doc, " ] " );
1131 fprintf( current_doc, "[ " );
1132 label_name = current_header->htype->indexName;
1133 if ( ( course_of_action.do_index ) && ( course_of_action.do_multidoc ) )
1135 target_filename = RB_Get_SubIndex_FileName( document->docroot->name,
1136 document->extension,
1137 current_header->htype );
1138 RB_HTML_Generate_Link( current_doc, current_filename, target_filename,
1139 "robo_top_of_doc", label_name, 0 );
1140 free( target_filename );
1144 RB_HTML_Generate_String( current_doc, label_name );
1146 fprintf( current_doc, " ]</p>\n" );
1151 /* TODO Documentation */
1153 void RB_HTML_Generate_Nav_Bar_One_File_Per_Header(
1154 struct RB_Document *document,
1156 struct RB_header *current_header )
1158 char *current_filename = NULL;
1159 char *target_filename = NULL;
1161 char *label_name = NULL;
1163 current_filename = RB_Get_FullDocname( current_header->owner->filename );
1164 target_filename = RB_Get_FullDocname( current_header->owner->filename );
1165 label = Get_Fullname( current_header->owner->filename );
1166 /* The navigation bar */
1167 if ( current_header->parent )
1170 RB_Get_FullDocname( current_header->parent->owner->filename );
1171 label = current_header->parent->unique_name;
1172 label_name = current_header->parent->function_name;
1173 RB_HTML_Generate_Link( current_doc, current_filename, target_filename,
1174 label, label_name, "menuitem" );
1176 /* FS TODO one_file_per_header without index is not logical */
1177 if ( ( course_of_action.do_index ) && ( course_of_action.do_multidoc ) )
1179 target_filename = RB_Get_SubIndex_FileName( document->docroot->name,
1180 document->extension,
1181 current_header->htype );
1182 label_name = current_header->htype->indexName;
1183 RB_HTML_Generate_Link( current_doc, current_filename, target_filename,
1184 "robo_top_of_doc", label_name, "menuitem" );
1185 free( target_filename );
1193 /* TODO Documentation */
1194 /*x**if* HTML_Generator/RB_HTML_Generate_Header_Start
1196 * RB_HTML_Generate_Header_Start --
1200 void RB_HTML_Generate_Header_Start(
1202 struct RB_header *cur_header )
1204 struct RB_HeaderType *header_type;
1207 if ( cur_header->name && cur_header->function_name )
1209 fprintf( dest_doc, "<hr />\n" );
1210 RB_HTML_Generate_Label( dest_doc, cur_header->name );
1211 fprintf( dest_doc, "</a><a name=\"%s\"></a><h2>",
1212 cur_header->unique_name );
1214 header_type = RB_FindHeaderType( cur_header->htype->typeCharacter );
1216 for ( i = 1; i <= cur_header->no_names; i++ )
1218 // If Section names only, do not print module name
1219 if ( i == 1 && ( course_of_action.do_sectionnameonly ) )
1220 RB_HTML_Generate_String( dest_doc,
1221 cur_header->function_name );
1223 RB_HTML_Generate_String( dest_doc, cur_header->names[i - 1] );
1225 // Break lines after a predefined number of header names
1226 if ( i < cur_header->no_names )
1227 fprintf( dest_doc, ( i % header_breaks ) ? ", " : ",<br />" );
1230 // Print header type (if available and not Section names only)
1231 if ( header_type && !( course_of_action.do_sectionnameonly ) )
1233 fprintf( dest_doc, " [ " );
1234 RB_HTML_Generate_String( dest_doc, header_type->indexName );
1235 fprintf( dest_doc, " ]" );
1238 fprintf( dest_doc, "</h2>\n\n" );
1243 /*x**f* HTML_Generator/RB_HTML_Generate_Header_End
1245 * RB_HTML_Generate_Header_End --
1249 void RB_HTML_Generate_Header_End(
1251 struct RB_header *cur_header )
1254 fprintf( dest_doc, "\n" );
1258 /****f* HTML_Generator/RB_HTML_Generate_IndexMenu
1260 * Generates a menu to jump to the various master index files for
1261 * the various header types. The menu is generated for each of the
1262 * master index files. The current header type is highlighted.
1265 void RB_HTML_Generate_IndexMenu(
1268 struct RB_Document *document,
1269 struct RB_HeaderType *cur_type )
1270 /* TODO Use cur_type */
1273 * * dest_doc -- the output file.
1274 * * filename -- the name of the output file
1275 * * document -- the gathered documention.
1276 * * cur_headertype -- the header type that is to be highlighted.
1280 unsigned char type_char;
1281 char *toc_index_path = NULL;
1283 USE( cur_type ); /* TODO FS make use of this */
1288 toc_index_path = HTML_TOC_Index_Filename( document );
1289 RB_HTML_Generate_Link( dest_doc,
1292 "top", "Table of Contents", "menuitem" );
1293 free( toc_index_path );
1294 fprintf( dest_doc, "\n" );
1296 for ( type_char = MIN_HEADER_TYPE;
1297 type_char < MAX_HEADER_TYPE; ++type_char )
1299 struct RB_HeaderType *header_type;
1302 header_type = RB_FindHeaderType( type_char );
1305 n = RB_Number_Of_Links( header_type, NULL, FALSE ) +
1306 RB_Number_Of_Links( header_type, NULL, TRUE );
1310 char *targetfilename = 0;
1313 RB_Get_SubIndex_FileName( document->docroot->name,
1314 document->extension,
1316 assert( targetfilename );
1318 RB_HTML_Generate_Link( dest_doc,
1322 header_type->indexName, "menuitem" );
1323 free( targetfilename );
1324 fprintf( dest_doc, "\n" );
1330 /****f* HTML_Generator/RB_HTML_Generate_Index_Page
1332 * Generate a single file with a index table for headers
1333 * of one specific type of headers
1336 void RB_HTML_Generate_Index_Page(
1337 struct RB_Document *document,
1338 struct RB_HeaderType *header_type )
1341 * o document -- the document
1342 * o header_type -- the type for which the table is to
1351 assert( header_type );
1353 filename = RB_Get_SubIndex_FileName( document->docroot->name,
1354 document->extension, header_type );
1357 file = fopen( filename, "w" );
1360 RB_Panic( "can't open (%s)!\n", filename );
1364 /* File opened, now we generate an index
1365 * for the specified header type
1367 RB_HTML_Generate_Doc_Start( file,
1368 document->srcroot->name,
1369 header_type->indexName,
1370 filename, document->charset );
1372 /* breadcrumbtrail */
1373 HTML_Generate_Begin_Extra( file );
1374 /* No content for extra section yet... */
1375 HTML_Generate_End_Extra( file );
1377 /* Menu for navigation */
1378 HTML_Generate_Begin_Navigation( file );
1379 RB_HTML_Generate_IndexMenu( file, filename, document, header_type );
1380 HTML_Generate_End_Navigation( file );
1383 HTML_Generate_Begin_Content( file );
1384 if ( RB_CompareHeaderTypes
1385 ( header_type, RB_FindHeaderType( HT_SOURCEHEADERTYPE ) )
1386 && ( header_type->typeCharacter != HT_MASTERINDEXTYPE ) )
1388 RB_HTML_Generate_Source_Tree( file, filename, document );
1392 RB_HTML_Generate_Index_Table( file,
1395 header_type->indexName );
1397 HTML_Generate_End_Content( file );
1398 RB_HTML_Generate_Doc_End( file, filename, document->srcroot->name );
1406 /* Create an index page that contains only the table of content */
1408 void HTML_Generate_TOC_Index_Page(
1409 struct RB_Document *document )
1412 char *toc_index_path = HTML_TOC_Index_Filename( document );
1414 file = fopen( toc_index_path, "w" );
1417 RB_Panic( "can't open (%s)!\n", toc_index_path );
1421 RB_HTML_Generate_Doc_Start( file, document->srcroot->name,
1422 "Table of Contents",
1423 toc_index_path, document->charset );
1425 /* breadcrumbtrail */
1426 HTML_Generate_Begin_Extra( file );
1427 /* No content for extra section yet... */
1428 HTML_Generate_End_Extra( file );
1430 /* Menu for navigation */
1431 HTML_Generate_Begin_Navigation( file );
1432 RB_HTML_Generate_IndexMenu( file, toc_index_path, document, NULL );
1433 HTML_Generate_End_Navigation( file );
1436 HTML_Generate_Begin_Content( file );
1437 RB_Generate_TOC_2( file, document->headers,
1438 document->no_headers, NULL, toc_index_path );
1439 HTML_Generate_End_Content( file );
1442 RB_HTML_Generate_Doc_End( file, toc_index_path,
1443 document->srcroot->name );
1447 free( toc_index_path );
1455 /*x**if* HTML_Generator/RB_HTML_Generate_Index
1457 * RB_HTML_Generate_Index --
1462 /* Should be called indexes */
1463 void RB_HTML_Generate_Index(
1464 struct RB_Document *document )
1466 unsigned char type_char = 0;
1470 for ( type_char = MIN_HEADER_TYPE;
1471 type_char < MAX_HEADER_TYPE; ++type_char )
1473 struct RB_HeaderType *header_type;
1476 header_type = RB_FindHeaderType( type_char );
1479 n = RB_Number_Of_Links( header_type, NULL, FALSE ) +
1480 RB_Number_Of_Links( header_type, NULL, TRUE );
1483 /* There are headers of this type, so create an index page
1486 RB_HTML_Generate_Index_Page( document, header_type );
1491 RB_HTML_Generate_Index_Page( document,
1492 RB_FindHeaderType( HT_MASTERINDEXTYPE ) );
1494 HTML_Generate_TOC_Index_Page( document );
1502 void RB_HTML_Generate_Table_Body(
1505 struct RB_HeaderType *type,
1508 struct RB_link *cur_link;
1510 char first_char = ' ';
1513 /* Compute the number of columns we need for
1514 * this type of header.
1516 for ( i = 0; i < link_index_size; ++i )
1518 cur_link = link_index[i];
1519 if ( cur_link->htype &&
1520 RB_CompareHeaderTypes( cur_link->htype, type ) &&
1521 ( ( cur_link->is_internal && internal ) ||
1522 ( !cur_link->is_internal && !internal ) ) )
1526 r = RB_HTML_RelativeAddress( dest_name, cur_link->file_name );
1527 if ( toupper( cur_link->object_name[0] ) != first_char )
1529 first_char = toupper( cur_link->object_name[0] );
1532 // fprintf( dest, "</div>\n" );
1534 fprintf( dest, "<h2><a name=\"%c\"></a>", first_char );
1535 RB_HTML_Generate_Char( dest, first_char );
1536 fprintf( dest, "</h2>" );
1537 // fprintf( dest, "<div class=\"indexitem\">\n" );
1540 fprintf( dest, "<a href=\"%s#%s\" class=\"indexitem\" >", r,
1541 cur_link->label_name );
1542 RB_HTML_Generate_String( dest, cur_link->object_name );
1543 fprintf( dest, "</a>\n" );
1548 // fprintf( dest, "</div>\n" );
1553 /****if* HTML_Generator/RB_HTML_Generate_Index_Shortcuts
1555 * RB_HTML_Generate_Index_Shortcuts
1557 * Generates alphabetic shortcuts to index entries.
1560 static void RB_HTML_Generate_Index_Shortcuts(
1564 * o dest -- the file to write to
1566 * - Only list used letters.
1567 * - List all letters (accented, signs, etc), not just the common ones.
1568 * - Should be better to implement it as a <div> ?
1574 fprintf( dest, "<h2>" );
1577 for ( c = 'A'; c <= 'Z'; c++ )
1579 fprintf( dest, "<a href=\"#%c\">", c );
1580 RB_HTML_Generate_Char( dest, c );
1581 fprintf( dest, "</a> - " );
1585 for ( c = '0'; c <= '9'; c++ )
1587 fprintf( dest, "<a href=\"#%c\">", c );
1588 RB_HTML_Generate_Char( dest, c );
1589 fprintf( dest, "</a>" );
1591 // Do not generate separator for the last char
1594 fprintf( dest, " - " );
1598 fprintf( dest, "</h2>\n" );
1603 /****if* HTML_Generator/RB_HTML_Generate_Index_Table
1605 * RB_HTML_Generate_Index_Table --
1607 * Create a HTML TABLE containing links to headers of a particular
1608 * type. This creates two tables, a table for normal headers as
1609 * well as one for internal headers.
1612 void RB_HTML_Generate_Index_Table(
1615 struct RB_HeaderType *type,
1619 * o dest -- the file in which to write the table
1620 * o dest_name -- the name of this file
1621 * o type -- the type of header for which to generate
1623 * o title -- the title of the table.
1627 /* Compute the number of columns we need for
1628 * this type of header.
1631 // Generate Index Title
1632 fprintf( dest, "<h1>" );
1633 RB_HTML_Generate_String( dest, title );
1634 fprintf( dest, "</h1>\n" );
1636 // Generate Shortcuts at the begining
1637 RB_HTML_Generate_Index_Shortcuts( dest );
1639 if ( RB_Number_Of_Links( type, NULL, FALSE ) )
1641 if ( RB_Number_Of_Links( type, NULL, TRUE ) )
1643 /* only print a title if there are two tables. */
1644 fprintf( dest, "<h2>Normal</h2>" );
1646 RB_HTML_Generate_Table_Body( dest, dest_name, type, FALSE );
1649 if ( RB_Number_Of_Links( type, NULL, TRUE ) )
1651 /* Always print the Internal title, since
1652 * these headers are special and the user should know
1653 * he is looking at something special.
1655 fprintf( dest, "<h2>Internal</h2>" );
1656 RB_HTML_Generate_Table_Body( dest, dest_name, type, TRUE );
1659 // Generate Shortcuts at the end
1660 RB_HTML_Generate_Index_Shortcuts( dest );
1668 /*x**if* HTML_Generator/RB_HTML_Generate_Empty_Item
1670 * RB_HTML_Generate_Empty_Item --
1674 void RB_HTML_Generate_Empty_Item(
1677 fprintf( dest_doc, "<br>\n" );
1683 /****f* HTML_Generator/RB_HTML_Generate_Link
1685 * RB_HTML_Generate_Link --
1688 void RB_HTML_Generate_Link(
1697 * cur_doc -- the file to which the text is written
1698 * cur_name -- the name of the destination file
1699 * (the file from which we link)
1700 * filename -- the name of the file that contains the link
1701 * (the file we link to)
1702 * labelname-- the name of the unique label of the link.
1703 * linkname -- the name of the link as shown to the user.
1709 fprintf( cur_doc, "<a class=\"%s\" ", classname );
1713 fprintf( cur_doc, "<a " );
1715 if ( filename && strcmp( filename, cur_name ) )
1717 char *r = RB_HTML_RelativeAddress( cur_name, filename );
1719 fprintf( cur_doc, "href=\"%s#%s\">", r, labelname );
1720 RB_HTML_Generate_String( cur_doc, linkname );
1721 fprintf( cur_doc, "</a>" );
1726 fprintf( cur_doc, "href=\"#%s\">", labelname );
1727 RB_HTML_Generate_String( cur_doc, linkname );
1728 fprintf( cur_doc, "</a>" );
1735 /****f* HTML_Generator/RB_HTML_RelativeAddress
1737 * Link to 'that' from 'this' computing the relative path. Here
1738 * 'this' and 'that' are both paths. This function is used to
1739 * create links from one document to another document that might be
1740 * in a completely different directory.
1743 char *RB_HTML_RelativeAddress(
1749 * this /sub1/sub2/sub3/f.html
1750 * that /sub1/sub2/g.html
1755 * that /sub1/sub2/g.html
1764 * this /sub1/doc3/doc1/tt.html
1765 * that /sub1/doc5/doc2/qq.html
1767 * ../../doc5/doc2/qq.html
1770 * Notice the execelent docmentation.
1773 #define MAX_RELATIVE_SIZE 1024
1775 static char relative[MAX_RELATIVE_SIZE + 1];
1778 char *i_this_slash = NULL;
1779 char *i_that_slash = NULL;
1786 for ( i_this = thisname, i_that = thatname;
1787 ( *i_this && *i_that ) && ( *i_this == *i_that );
1788 ++i_this, ++i_that )
1790 if ( *i_this == '/' )
1792 i_this_slash = i_this;
1794 if ( *i_that == '/' )
1796 i_that_slash = i_that;
1800 if ( i_this_slash && i_that_slash )
1802 int this_slashes_left = 0;
1803 int that_slashes_left = 0;
1806 for ( i_c = i_this_slash + 1; *i_c; ++i_c )
1810 ++this_slashes_left;
1814 for ( i_c = i_that_slash + 1; *i_c; ++i_c )
1818 ++that_slashes_left;
1822 if ( this_slashes_left )
1826 for ( i = 0; i < this_slashes_left; ++i )
1828 strcat( relative, "../" );
1830 strcat( relative, i_that_slash + 1 );
1832 else if ( that_slashes_left )
1834 /* !this_slashes_left && that_slashes_left */
1835 strcat( relative, "./" );
1836 strcat( relative, i_that_slash + 1 );
1840 /* !this_slashes_left && !that_slashes_left */
1841 strcat( relative, "./" );
1842 strcat( relative, i_that_slash + 1 );
1852 /****f* HTML_Generator/RB_HTML_Generate_Char
1854 * RB_HTML_Generate_Char -- generate a single character for an item.
1857 void RB_HTML_Generate_Char(
1862 * This function is called for every character that goes
1863 * into an item's body. This escapes all the reserved
1864 * HTML characters such as '&', '<', '>', '"'.
1877 fprintf( dest_doc, "<" );
1880 fprintf( dest_doc, ">" );
1883 fprintf( dest_doc, "&" );
1886 // All others are printed literally
1887 fputc( c, dest_doc );
1894 void HTML_Generate_Begin_Content(
1897 HTML_Generate_Div( dest_doc, "content" );
1900 void HTML_Generate_End_Content(
1903 HTML_Generate_Div_End( dest_doc, "content" );
1906 void HTML_Generate_Begin_Navigation(
1909 HTML_Generate_Div( dest_doc, "navigation" );
1912 void HTML_Generate_End_Navigation(
1916 HTML_Generate_Div_End( dest_doc, "navigation" );
1919 void HTML_Generate_Begin_Extra(
1922 HTML_Generate_Div( dest_doc, "extra" );
1925 void HTML_Generate_End_Extra(
1928 HTML_Generate_Div_End( dest_doc, "extra" );
1934 /****f* HTML_Generator/RB_Create_CSS
1936 * Create the .css file. Unless the user specified it's own css
1937 * file robodoc creates a default one.
1939 * For multidoc mode the name of the .css file is
1941 * For singledoc mode the name of the .css file is equal
1942 * to the name of the documentation file.
1946 struct RB_Document *document )
1949 * o document -- the document for which to create the file.
1956 /* compute the complete path to the css file */
1957 if ( ( document->actions.do_singledoc ) ||
1958 ( document->actions.do_singlefile ) )
1960 char *extension = ".css";
1962 l += strlen( document->singledoc_name );
1963 l += strlen( extension );
1965 css_name = malloc( l );
1966 strcpy( css_name, document->singledoc_name );
1967 strcat( css_name, extension );
1971 struct RB_Path *docroot = document->docroot;
1972 char *docrootname = docroot->name;
1973 char *filename = "robodoc.css";
1975 l = strlen( filename );
1976 l += strlen( docrootname );
1978 css_name = malloc( l );
1979 strcpy( css_name, docrootname );
1980 strcat( css_name, filename );
1983 RB_Say( "Creating CSS file %s\n", SAY_DEBUG, css_name );
1984 if ( document->css )
1986 /* The user specified its own css file,
1987 * so we use the content of that.
1989 RB_CopyFile( document->css, css_name );
1993 css_file = fopen( css_name, "w" );
1996 /** BEGIN BEGIN BEGIN Don't remove */
1998 "/****h* ROBODoc/ROBODoc Cascading Style Sheet\n"
2000 " * This is the default cascading style sheet for documentation\n"
2001 " * generated with ROBODoc.\n"
2002 " * You can edit this file to your own liking and then use\n"
2003 " * it with the option\n"
2004 " * --css <filename>\n"
2006 " * This style-sheet defines the following layout\n"
2007 " * +----------------------------------------+\n"
2009 " * +----------------------------------------+\n"
2011 " * +----------------------------------------+\n"
2014 " * | content | |\n"
2016 " * +----------------------------------------+\n"
2018 " * +----------------------------------------+\n"
2020 " * This style-sheet is based on a style-sheet that was automatically\n"
2021 " * generated with the Strange Banana stylesheet generator.\n"
2022 " * See http://www.strangebanana.com/generator.aspx\n"
2025 " * $Id: html_generator.c,v 1.91 2007/07/10 19:13:51 gumpu Exp $\n"
2030 " background-color: rgb(255,255,255);\n"
2031 " color: rgb(98,84,55);\n"
2032 " font-family: Arial, serif;\n"
2033 " border-color: rgb(226,199,143);\n"
2038 " font-family: monospace;\n"
2041 " white-space: pre;\n"
2047 " background-color: #ffe;\n"
2048 " border: dashed #aa9 1px;\n"
2058 " font-weight: bolder;\n"
2060 " font-size: 120%%;\n"
2063 "#content\n" "{\n" " font-size: 100%%;\n" );
2065 " color: rgb(0,0,0);\n"
2066 " background-color: rgb(255,255,255);\n"
2067 " border-left-width: 0px; \n"
2068 " border-right-width: 0px; \n"
2069 " border-top-width: 0px; \n"
2070 " border-bottom-width: 0px;\n"
2071 " border-left-style: none; \n"
2072 " border-right-style: none; \n"
2073 " border-top-style: none; \n"
2074 " border-bottom-style: none;\n"
2075 " padding: 40px 31px 14px 17px;\n"
2076 " border-color: rgb(0,0,0);\n"
2077 " text-align: justify;\n"
2082 " background-color: rgb(98,84,55);\n"
2083 " color: rgb(230,221,202);\n"
2084 " font-family: \"Times New Roman\", serif;\n"
2085 " font-style: normal;\n"
2086 " border-color: rgb(0,0,0);\n"
2091 " font-size: 120%%;\n"
2092 " background-color: rgb(0,0,0);\n"
2093 " color: rgb(195,165,100);\n"
2094 " font-variant: normal;\n"
2095 " text-transform: none;\n"
2096 " font-weight: normal;\n"
2097 " padding: 1px 8px 3px 1px;\n"
2098 " margin-left: 5px; \n"
2099 " margin-right: 5px; \n"
2100 " margin-top: 5px; \n"
2101 " margin-bottom: 5px;\n"
2102 " border-color: rgb(159,126,57);\n"
2103 " text-align: right;\n"
2108 " font-size: 130%%;\n"
2109 " background-color: rgb(198,178,135);\n"
2110 " color: rgb(98,84,55);\n"
2111 " font-family: Georgia, serif;\n"
2112 " font-style: normal;\n"
2113 " font-variant: normal;\n"
2114 " text-transform: none;\n"
2115 " font-weight: bold;\n"
2116 " padding: 20px 18px 20px 18px;\n"
2117 " border-color: rgb(255,255,255);\n"
2118 " text-align: right;\n"
2121 "#extra, #extra a\n"
2123 " font-size: 128%%;\n"
2124 " background-color: rgb(0,0,0);\n"
2125 " color: rgb(230,221,202);\n"
2126 " font-style: normal;\n"
2127 " font-variant: normal;\n"
2128 " text-transform: none;\n"
2129 " font-weight: normal;\n" );
2131 " border-left-width: 0px; \n"
2132 " border-right-width: 0px; \n"
2133 " border-top-width: 0px; \n"
2134 " border-bottom-width: 0px;\n"
2135 " border-left-style: none; \n"
2136 " border-right-style: none; \n"
2137 " border-top-style: none; \n"
2138 " border-bottom-style: none;\n"
2139 " padding: 12px 12px 12px 12px;\n"
2140 " border-color: rgb(195,165,100);\n"
2141 " text-align: center;\n"
2146 " color: rgb(159,126,57);\n"
2147 " text-decoration: none;\n"
2150 "#content a:hover, #content a:active\n"
2152 " color: rgb(255,255,255);\n"
2153 " background-color: rgb(159,126,57);\n"
2158 " display: block;\n"
2161 "h1, h2, h3, h4, h5, h6\n"
2163 " background-color: rgb(221,221,221);\n"
2164 " font-family: Arial, serif;\n"
2165 " font-style: normal;\n"
2166 " font-variant: normal;\n"
2167 " text-transform: none;\n"
2168 " font-weight: normal;\n"
2173 " font-size: 151%%;\n"
2178 " font-size: 142%%;\n"
2183 " font-size: 133%%;\n"
2188 " font-size: 124%%;\n"
2193 " font-size: 115%%;\n"
2198 " font-size: 106%%;\n"
2203 " text-decoration: none;\n"
2208 " background-color: rgb(195,165,100);\n"
2209 " color: rgb(0,0,0);\n"
2214 " text-decoration: none;\n"
2219 " text-decoration: none;\n"
2230 " position: relative; \n"
2234 " text-align: center;\n"
2235 " margin-left: 10px;\n"
2238 ".menuitem {width: auto;}\n"
2239 "#content {width: auto;}\n"
2240 ".menuitem {display: block;}\n" "\n" "\n" );
2244 " background-color: rgb(198,178,135);\n"
2245 " color: rgb(98,84,55);\n"
2248 " font-size: 71%%;\n"
2253 " background-color: rgb(198,178,135);\n"
2254 " color: rgb(98,84,55);\n"
2260 " padding:5px 10px\n"
2285 " color: #008B8B;\n"
2291 " #navigation {display: none;}\n"
2292 " #content {padding: 0px;}\n"
2293 " #content a {text-decoration: underline;}\n"
2295 /** END END END Don't remove */
2300 RB_Panic( "Can't open %s for writing\n", css_name );
2314 char *r = RB_HTML_RelativeAddress( filename, css_name );
2317 assert( strlen( r ) );
2319 "<link rel=\"stylesheet\" href=\"%s\" type=\"text/css\" />\n",
2326 void HTML_Generate_Begin_Paragraph(
2329 fprintf( dest_doc, "<p>" );
2332 void HTML_Generate_End_Paragraph(
2335 fprintf( dest_doc, "</p>\n" );
2339 void HTML_Generate_Begin_Preformatted(
2343 // Check if we are preformatting a SOURCE item
2346 // SOURCE items have their own class in the CSS
2347 fprintf( dest_doc, "<pre class=\"%s\">", SOURCE_CLASS );
2351 fprintf( dest_doc, "<pre>" );
2355 void HTML_Generate_End_Preformatted(
2358 fprintf( dest_doc, "</pre>\n" );
2362 void HTML_Generate_Begin_List(
2365 fprintf( dest_doc, "<ul>" );
2368 void HTML_Generate_End_List(
2371 fprintf( dest_doc, "</ul>\n" );
2374 void HTML_Generate_Begin_List_Item(
2377 fprintf( dest_doc, "<li>" );
2380 void HTML_Generate_End_List_Item(
2383 fprintf( dest_doc, "</li>\n" );