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_Entries(
690 struct RB_header **headers,
692 struct RB_Part *owner,
695 struct RB_header *header;
696 char *object_name, *label_name, *file_name;
699 // fprintf( dest_doc, "<h3>Table of Contents</h3>\n" );
700 fprintf( dest_doc, "<p class=\"item_name\">TABLE OF CONTENTS</p>\n" );
701 fprintf( dest_doc, "<ul class=\"toc_entries\">\n" );
703 for ( i = count - 1; i >= 0; i-- )
707 if ( header->htype->typeCharacter != 'h' &&
708 !strcmp( owner->filename->name, header->owner->filename->name ) &&
709 Find_Link( header->function_name,
710 &object_name, &label_name,
713 for ( j = 0; j < header->no_names; j++ )
715 fprintf( dest_doc, "<li class=\"toc_entries\">" );
716 RB_HTML_Generate_Link( dest_doc,
721 fprintf( dest_doc, "</li>\n" );
726 fprintf( dest_doc, "</ul>\n" );
730 void RB_HTML_Generate_TOC_2(
732 struct RB_header **headers,
734 struct RB_Part *owner,
737 struct RB_header *header;
741 for ( i = 0; i < MAX_SECTION_DEPTH; ++i )
743 sectiontoc_counters[i] = 0;
745 fprintf( dest_doc, "<h3>TABLE OF CONTENTS</h3>\n" );
746 if ( course_of_action.do_sections )
748 /* --sections was specified, create a TOC based on the
749 * hierarchy of the headers.
751 fprintf( dest_doc, "<ul>\n" );
752 for ( i = 0; i < count; ++i )
757 if ( header->parent )
759 /* Will be done in the subfunction */
763 RB_HTML_Generate_TOC_Section( dest_doc, dest_name, header,
764 headers, count, depth );
769 /* This is the TOC for a specific RB_Part (MultiDoc
770 * documentation). We only include the headers that
771 * are part of the subtree. That is, headers that are
772 * parth the RB_Part, or that are childern of the
773 * headers in the RB_Part.
775 if ( header->owner == owner )
778 /* Any of the parents of this header should not
779 * have the same owner as this header, otherwise
780 * this header will be part of the TOC multiple times.
782 int no_bad_parent = TRUE;
783 struct RB_header *parent = header->parent;
785 for ( ; parent; parent = parent->parent )
787 if ( parent->owner == owner )
789 no_bad_parent = FALSE;
795 RB_HTML_Generate_TOC_Section( dest_doc, dest_name,
796 header, headers, count,
802 fprintf( dest_doc, "</ul>\n" );
806 /* No --section option, generate a plain, one-level
809 fprintf( dest_doc, "<ul>\n" );
811 for ( i = 0; i < count; ++i )
814 if ( header->name && header->function_name &&
815 ( ( owner == NULL ) || ( header->owner == owner ) ) )
817 for ( j = 0; j < header->no_names; j++ )
819 fprintf( dest_doc, "<li>" );
821 RB_HTML_Generate_Link( dest_doc, dest_name,
824 header->names[j], 0 );
825 fprintf( dest_doc, "</li>\n" );
829 fprintf( dest_doc, "</ul>\n" );
835 /****f* HTML_Generator/RB_HTML_Generate_Label
837 * Generate a label (name) that can be refered too.
838 * A label should consist of only alphanumeric characters so
839 * all 'odd' characters are replaced with their ASCII code in
843 void RB_HTML_Generate_Label(
848 * o dest_doc -- the file to write it to.
849 * o name -- the name of the label.
854 int l = strlen( name );
857 fprintf( dest_doc, "<a name=\"" );
858 for ( i = 0; i < l; ++i )
861 if ( utf8_isalnum( c ) )
863 RB_HTML_Generate_Char( dest_doc, c );
869 sprintf( buf, "%02x", c );
870 RB_HTML_Generate_Char( dest_doc, buf[0] );
871 RB_HTML_Generate_Char( dest_doc, buf[1] );
874 fprintf( dest_doc, "\">\n" );
881 static int section_counters[MAX_SECTION_DEPTH];
884 /* TODO Documentation */
886 void RB_HTML_Generate_BeginSection(
890 struct RB_header *header )
894 ++section_counters[depth];
895 for ( i = depth + 1; i < MAX_SECTION_DEPTH; ++i )
897 section_counters[i] = 0;
908 fprintf( dest_doc, "<h%d>", depth );
909 // Only generate section numbers if no sectionnameonly
910 if ( !( course_of_action.do_sectionnameonly ) )
912 for ( i = 1; i <= depth; ++i )
914 fprintf( dest_doc, "%d.", section_counters[i] );
916 fprintf( dest_doc, " " );
919 // Print Header "first" name
920 RB_HTML_Generate_String( dest_doc, name );
922 // Print further names
923 for ( i = 1; i < header->no_names; i++ )
925 fprintf( dest_doc, ( i % header_breaks ) ? ", " : ",<br />" );
926 RB_HTML_Generate_String( dest_doc, header->names[i] );
929 // Include module name if not sectionnameonly
930 if ( !( course_of_action.do_sectionnameonly ) )
932 fprintf( dest_doc, " [ " );
933 RB_HTML_Generate_String( dest_doc, header->htype->indexName );
934 fprintf( dest_doc, " ]" );
937 fprintf( dest_doc, " </h%d>\n", depth );
940 /* too deep, don't do anything. */
945 void RB_HTML_Generate_EndSection(
957 char *RB_HTML_Get_Default_Extension(
963 /****f* HTML_Generator/RB_HTML_Generate_Doc_Start
965 * RB_HTML_Generate_Doc_Start --
967 * Generate the first part of a HTML document.
968 * As far as ROBODoc is concerned a HTML document
969 * consists of three parts:
970 * * The start of a document
971 * * The body of a document
972 * * The end of a document
975 void RB_HTML_Generate_Doc_Start(
983 * o dest_doc -- the output file.
984 * o src_name -- The file or directoryname from which
985 * this document is generated.
986 * o name -- The title for this document
987 * o dest_name -- the name of the output file.
988 * o charset -- the charset to be used for the file.
993 if ( course_of_action.do_headless )
995 /* The user wants a headless document, so we skip everything
996 * upto and until <BODY>
1001 /* Append document type and title */
1002 fprintf( dest_doc, "<?xml version=\"1.0\" encoding=\"%s\"?>\n",
1003 charset ? charset : DEFAULT_CHARSET );
1005 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n" );
1007 " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" );
1010 "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" );
1011 fprintf( dest_doc, "<head>\n" );
1013 "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\" />\n" );
1014 /* TODO is charset still needed?? */
1016 "<meta http-equiv=\"Content-type\" content=\"text/html; charset=%s\" />\n",
1017 charset ? charset : DEFAULT_CHARSET );
1018 RB_InsertCSS( dest_doc, dest_name );
1019 fprintf( dest_doc, "<title>%s</title>\n", name );
1021 /* append SGML-comment with document- and copyright-info. This code
1022 * ensures that every line has an own comment to avoid problems with
1024 fprintf( dest_doc, "<!-- Source: %s -->\n", src_name );
1025 if ( course_of_action.do_nogenwith )
1031 static const char copyright_text[]
1032 = COMMENT_ROBODOC /* COMMENT_COPYRIGHT */ ;
1034 char previous_char = '\n';
1035 char current_char = copyright_text[i];
1037 while ( current_char )
1039 if ( previous_char == '\n' )
1041 fprintf( dest_doc, "<!-- " );
1043 if ( current_char == '\n' )
1045 fprintf( dest_doc, " -->" );
1047 else if ( ( current_char == '-' )
1048 && ( previous_char == '-' ) )
1050 /* avoid "--" inside SGML-comment, and use "-_" instead; this
1051 * looks a bit strange, but one should still be able to figure
1052 * out what is meant when reading the output */
1055 fputc( current_char, dest_doc );
1057 previous_char = current_char;
1058 current_char = copyright_text[i];
1062 /* append heading and start list of links to functions */
1063 fprintf( dest_doc, "</head>\n" );
1064 fprintf( dest_doc, "<body>\n" );
1067 // HTML_Generate_Div( dest_doc, "container" );
1069 /* Use user specified header if present */
1070 if ( document_header )
1072 fprintf ( dest_doc, document_header );
1076 /* Generate document title if available (Thuffir) */
1077 HTML_Generate_Div( dest_doc, "logo" );
1078 fprintf( dest_doc, "<a name=\"robo_top_of_doc\">" );
1079 if ( document_title )
1080 RB_HTML_Generate_String( dest_doc, document_title );
1081 fprintf( dest_doc, "</a>\n" );
1082 HTML_Generate_Div_End( dest_doc, "logo" );
1090 /*x**if* HTML_Generator/RB_HTML_Generate_Doc_End
1092 * RB_HTML_Generate_Doc_End --
1094 * Close of the document with the proper end tags.
1098 void RB_HTML_Generate_Doc_End(
1106 /* Use user specified footer if present */
1107 if ( document_footer )
1109 fprintf ( dest_doc, document_footer );
1113 HTML_Generate_Div( dest_doc, "footer" );
1115 /* TODO This should be done with
1116 * RB_Generate_Label()
1118 if ( course_of_action.do_nogenwith )
1120 fprintf( dest_doc, "<p>Generated from %s on ", src_name );
1121 RB_TimeStamp( dest_doc );
1122 fprintf( dest_doc, "</p>\n" );
1127 "<p>Generated from %s with <a href=\"http://www.xs4all.nl/~rfsber/Robo/robodoc.html\">ROBODoc</a> V%s on ",
1128 src_name, VERSION );
1129 RB_TimeStamp( dest_doc );
1130 fprintf( dest_doc, "</p>\n" );
1133 HTML_Generate_Div_End( dest_doc, "footer" );
1136 // HTML_Generate_Div_End( dest_doc, "container" );
1138 if ( course_of_action.do_footless )
1140 /* The user does not want the foot of the
1146 fprintf( dest_doc, "</body>\n</html>\n" );
1151 void RB_HTML_Generate_Nav_Bar(
1152 struct RB_Document *document,
1154 struct RB_header *current_header )
1156 char *current_filename = NULL;
1157 char *target_filename = NULL;
1159 char *label_name = NULL;
1161 current_filename = RB_Get_FullDocname( current_header->owner->filename );
1162 target_filename = RB_Get_FullDocname( current_header->owner->filename );
1163 label = Get_Fullname( current_header->owner->filename );
1164 /* The navigation bar */
1165 fprintf( current_doc, "<p>" );
1168 fprintf( current_doc, "[ " );
1169 RB_HTML_Generate_Link( current_doc, current_filename, NULL,
1170 "robo_top_of_doc", "Top", 0 );
1171 fprintf( current_doc, " ] " );
1174 if ( current_header->parent )
1176 fprintf( current_doc, "[ " );
1178 RB_Get_FullDocname( current_header->parent->owner->filename );
1179 label = current_header->parent->unique_name;
1180 label_name = current_header->parent->function_name;
1181 RB_HTML_Generate_Link( current_doc, current_filename, target_filename,
1182 label, label_name, 0 );
1183 fprintf( current_doc, " ] " );
1187 fprintf( current_doc, "[ " );
1188 label_name = current_header->htype->indexName;
1189 if ( ( course_of_action.do_index ) && ( course_of_action.do_multidoc ) )
1191 target_filename = RB_Get_SubIndex_FileName( document->docroot->name,
1192 document->extension,
1193 current_header->htype );
1194 RB_HTML_Generate_Link( current_doc, current_filename, target_filename,
1195 "robo_top_of_doc", label_name, 0 );
1196 free( target_filename );
1200 RB_HTML_Generate_String( current_doc, label_name );
1202 fprintf( current_doc, " ]</p>\n" );
1207 /* TODO Documentation */
1209 void RB_HTML_Generate_Nav_Bar_One_File_Per_Header(
1210 struct RB_Document *document,
1212 struct RB_header *current_header )
1214 char *current_filename = NULL;
1215 char *target_filename = NULL;
1217 char *label_name = NULL;
1219 current_filename = RB_Get_FullDocname( current_header->owner->filename );
1220 target_filename = RB_Get_FullDocname( current_header->owner->filename );
1221 label = Get_Fullname( current_header->owner->filename );
1222 /* The navigation bar */
1223 if ( current_header->parent )
1226 RB_Get_FullDocname( current_header->parent->owner->filename );
1227 label = current_header->parent->unique_name;
1228 label_name = current_header->parent->function_name;
1229 RB_HTML_Generate_Link( current_doc, current_filename, target_filename,
1230 label, label_name, "menuitem" );
1232 /* FS TODO one_file_per_header without index is not logical */
1233 if ( ( course_of_action.do_index ) && ( course_of_action.do_multidoc ) )
1235 target_filename = RB_Get_SubIndex_FileName( document->docroot->name,
1236 document->extension,
1237 current_header->htype );
1238 label_name = current_header->htype->indexName;
1239 RB_HTML_Generate_Link( current_doc, current_filename, target_filename,
1240 "robo_top_of_doc", label_name, "menuitem" );
1241 free( target_filename );
1249 /* TODO Documentation */
1250 /*x**if* HTML_Generator/RB_HTML_Generate_Header_Start
1252 * RB_HTML_Generate_Header_Start --
1256 void RB_HTML_Generate_Header_Start(
1258 struct RB_header *cur_header )
1260 struct RB_HeaderType *header_type;
1263 if ( cur_header->name && cur_header->function_name )
1265 /* fprintf( dest_doc, "<hr />\n" ); */
1266 RB_HTML_Generate_Label( dest_doc, cur_header->name );
1267 fprintf( dest_doc, "</a><a name=\"%s\"></a><h2>",
1268 cur_header->unique_name );
1270 header_type = RB_FindHeaderType( cur_header->htype->typeCharacter );
1272 for ( i = 1; i <= cur_header->no_names; i++ )
1274 // If Section names only, do not print module name
1275 if ( i == 1 && ( course_of_action.do_sectionnameonly ) )
1276 RB_HTML_Generate_String( dest_doc,
1277 cur_header->function_name );
1279 RB_HTML_Generate_String( dest_doc, cur_header->names[i - 1] );
1281 // Break lines after a predefined number of header names
1282 if ( i < cur_header->no_names )
1283 fprintf( dest_doc, ( i % header_breaks ) ? ", " : ",<br />" );
1286 // Print header type (if available and not Section names only)
1287 if ( header_type && !( course_of_action.do_sectionnameonly ) )
1289 fprintf( dest_doc, " [ " );
1290 RB_HTML_Generate_String( dest_doc, header_type->indexName );
1291 fprintf( dest_doc, " ]" );
1294 fprintf( dest_doc, "</h2>\n\n" );
1299 /*x**f* HTML_Generator/RB_HTML_Generate_Header_End
1301 * RB_HTML_Generate_Header_End --
1305 void RB_HTML_Generate_Header_End(
1307 struct RB_header *cur_header )
1310 fprintf( dest_doc, "\n" );
1314 /****f* HTML_Generator/RB_HTML_Generate_IndexMenu
1316 * Generates a menu to jump to the various master index files for
1317 * the various header types. The menu is generated for each of the
1318 * master index files. The current header type is highlighted.
1321 void RB_HTML_Generate_IndexMenu(
1324 struct RB_Document *document,
1325 struct RB_HeaderType *cur_type )
1326 /* TODO Use cur_type */
1329 * * dest_doc -- the output file.
1330 * * filename -- the name of the output file
1331 * * document -- the gathered documention.
1332 * * cur_headertype -- the header type that is to be highlighted.
1336 unsigned char type_char;
1337 char *toc_index_path = NULL;
1339 USE( cur_type ); /* TODO FS make use of this */
1344 toc_index_path = HTML_TOC_Index_Filename( document );
1345 RB_HTML_Generate_Link( dest_doc,
1348 "top", "Table of Contents", "menuitem" );
1349 free( toc_index_path );
1350 fprintf( dest_doc, "\n" );
1352 for ( type_char = MIN_HEADER_TYPE;
1353 type_char < MAX_HEADER_TYPE; ++type_char )
1355 struct RB_HeaderType *header_type;
1358 header_type = RB_FindHeaderType( type_char );
1361 n = RB_Number_Of_Links( header_type, NULL, FALSE ) +
1362 RB_Number_Of_Links( header_type, NULL, TRUE );
1366 char *targetfilename = 0;
1369 RB_Get_SubIndex_FileName( document->docroot->name,
1370 document->extension,
1372 assert( targetfilename );
1374 RB_HTML_Generate_Link( dest_doc,
1378 header_type->indexName, "menuitem" );
1379 free( targetfilename );
1380 fprintf( dest_doc, "\n" );
1386 /****f* HTML_Generator/RB_HTML_Generate_Header_IndexMenu
1388 * Generates a menu to jump to the header's entries. The menu is
1389 * generated for each entry file.
1392 void RB_HTML_Generate_Header_IndexMenu(
1395 struct RB_Document *document,
1396 struct RB_Part *owner,
1397 struct RB_HeaderType *cur_type )
1398 /* TODO Use cur_type */
1401 * * dest_doc -- the output file.
1402 * * filename -- the name of the output file
1403 * * document -- the gathered documention.
1404 * * cur_headertype -- the header type that is to be highlighted.
1408 struct RB_header *header;
1409 char *object_name, *label_name, *file_name;
1412 for ( i = document->no_headers - 1; i >= 0; i-- )
1414 header = document->headers[i];
1416 if ( !strcmp( owner->filename->name, header->owner->filename->name ) &&
1417 ( header->htype->typeCharacter == 'h' ||
1418 Find_Link( header->function_name,
1419 &object_name, &label_name,
1422 for ( j = 0; j < header->no_names; j++ )
1424 if ( header->htype->typeCharacter == 'h' )
1426 RB_HTML_Generate_Link( dest_doc,
1428 header->owner->filename->docname,
1430 header->function_name,
1432 fprintf( dest_doc, "\n" );
1436 RB_HTML_Generate_Link( dest_doc,
1442 fprintf( dest_doc, "\n" );
1449 /****f* HTML_Generator/RB_HTML_Generate_Module_IndexMenu
1451 * Generates a menu to jump to the different modules. The menu is
1452 * generated for each header file.
1455 void RB_HTML_Generate_Module_IndexMenu(
1458 struct RB_Document *document,
1459 struct RB_HeaderType *cur_type )
1460 /* TODO Use cur_type */
1463 * * dest_doc -- the output file.
1464 * * filename -- the name of the output file
1465 * * document -- the gathered documention.
1466 * * cur_headertype -- the header type that is to be highlighted.
1470 struct RB_Part *i_part;
1472 for ( i_part = document->parts; i_part != NULL; i_part = i_part->next )
1474 if ( !i_part->headers ||
1475 i_part->headers[0].htype->typeCharacter != 'h' ||
1476 !strcmp(i_part->headers[0].function_name,
1477 "ROBODoc Cascading Style Sheet") )
1479 RB_HTML_Generate_Link( dest_doc,
1481 i_part->filename->docname,
1483 i_part->headers[0].function_name,
1485 fprintf( dest_doc, "\n" );
1490 /****f* HTML_Generator/RB_HTML_Generate_Index_Page
1492 * Generate a single file with a index table for headers
1493 * of one specific type of headers
1496 void RB_HTML_Generate_Index_Page(
1497 struct RB_Document *document,
1498 struct RB_HeaderType *header_type )
1501 * o document -- the document
1502 * o header_type -- the type for which the table is to
1511 assert( header_type );
1513 filename = RB_Get_SubIndex_FileName( document->docroot->name,
1514 document->extension, header_type );
1517 file = fopen( filename, "w" );
1520 RB_Panic( "can't open (%s)!\n", filename );
1524 /* File opened, now we generate an index
1525 * for the specified header type
1527 RB_HTML_Generate_Doc_Start( file,
1528 document->srcroot->name,
1529 header_type->indexName,
1530 filename, document->charset );
1532 /* breadcrumbtrail */
1533 HTML_Generate_Begin_Extra( file );
1534 /* No content for extra section yet... */
1535 HTML_Generate_End_Extra( file );
1537 /* Menu for navigation */
1538 HTML_Generate_Begin_Navigation( file );
1539 RB_HTML_Generate_IndexMenu( file, filename, document, header_type );
1540 HTML_Generate_End_Navigation( file );
1543 HTML_Generate_Begin_Content( file );
1544 if ( RB_CompareHeaderTypes
1545 ( header_type, RB_FindHeaderType( HT_SOURCEHEADERTYPE ) )
1546 && ( header_type->typeCharacter != HT_MASTERINDEXTYPE ) )
1548 RB_HTML_Generate_Source_Tree( file, filename, document );
1552 RB_HTML_Generate_Index_Table( file,
1555 header_type->indexName );
1557 HTML_Generate_End_Content( file );
1558 RB_HTML_Generate_Doc_End( file, filename, document->srcroot->name );
1566 /* Create an index page that contains only the table of content */
1568 void HTML_Generate_TOC_Index_Page(
1569 struct RB_Document *document )
1572 char *toc_index_path = HTML_TOC_Index_Filename( document );
1574 file = fopen( toc_index_path, "w" );
1577 RB_Panic( "can't open (%s)!\n", toc_index_path );
1581 RB_HTML_Generate_Doc_Start( file, document->srcroot->name,
1582 "Table of Contents",
1583 toc_index_path, document->charset );
1585 /* breadcrumbtrail */
1586 HTML_Generate_Begin_Extra( file );
1587 /* No content for extra section yet... */
1588 HTML_Generate_End_Extra( file );
1590 /* Menu for navigation */
1591 HTML_Generate_Begin_Navigation( file );
1592 RB_HTML_Generate_IndexMenu( file, toc_index_path, document, NULL );
1593 HTML_Generate_End_Navigation( file );
1596 HTML_Generate_Begin_Content( file );
1597 RB_Generate_TOC_2( file, document->headers,
1598 document->no_headers, NULL, toc_index_path );
1599 HTML_Generate_End_Content( file );
1602 RB_HTML_Generate_Doc_End( file, toc_index_path,
1603 document->srcroot->name );
1607 free( toc_index_path );
1615 /*x**if* HTML_Generator/RB_HTML_Generate_Index
1617 * RB_HTML_Generate_Index --
1622 /* Should be called indexes */
1623 void RB_HTML_Generate_Index(
1624 struct RB_Document *document )
1626 unsigned char type_char = 0;
1630 for ( type_char = MIN_HEADER_TYPE;
1631 type_char < MAX_HEADER_TYPE; ++type_char )
1633 struct RB_HeaderType *header_type;
1636 header_type = RB_FindHeaderType( type_char );
1639 n = RB_Number_Of_Links( header_type, NULL, FALSE ) +
1640 RB_Number_Of_Links( header_type, NULL, TRUE );
1643 /* There are headers of this type, so create an index page
1646 RB_HTML_Generate_Index_Page( document, header_type );
1651 RB_HTML_Generate_Index_Page( document,
1652 RB_FindHeaderType( HT_MASTERINDEXTYPE ) );
1654 HTML_Generate_TOC_Index_Page( document );
1662 void RB_HTML_Generate_Table_Body(
1665 struct RB_HeaderType *type,
1668 struct RB_link *cur_link;
1670 char first_char = ' ';
1673 /* Compute the number of columns we need for
1674 * this type of header.
1676 for ( i = 0; i < link_index_size; ++i )
1678 cur_link = link_index[i];
1679 if ( cur_link->htype &&
1680 RB_CompareHeaderTypes( cur_link->htype, type ) &&
1681 ( ( cur_link->is_internal && internal ) ||
1682 ( !cur_link->is_internal && !internal ) ) )
1686 r = RB_HTML_RelativeAddress( dest_name, cur_link->file_name );
1687 if ( toupper( cur_link->object_name[0] ) != first_char )
1689 first_char = toupper( cur_link->object_name[0] );
1692 // fprintf( dest, "</div>\n" );
1694 fprintf( dest, "<h2><a name=\"%c\"></a>", first_char );
1695 RB_HTML_Generate_Char( dest, first_char );
1696 fprintf( dest, "</h2>" );
1697 // fprintf( dest, "<div class=\"indexitem\">\n" );
1700 fprintf( dest, "<a href=\"%s#%s\" class=\"indexitem\" >", r,
1701 cur_link->label_name );
1702 RB_HTML_Generate_String( dest, cur_link->object_name );
1703 fprintf( dest, "</a>\n" );
1708 // fprintf( dest, "</div>\n" );
1713 /****if* HTML_Generator/RB_HTML_Generate_Index_Shortcuts
1715 * RB_HTML_Generate_Index_Shortcuts
1717 * Generates alphabetic shortcuts to index entries.
1720 static void RB_HTML_Generate_Index_Shortcuts(
1724 * o dest -- the file to write to
1726 * - Only list used letters.
1727 * - List all letters (accented, signs, etc), not just the common ones.
1728 * - Should be better to implement it as a <div> ?
1734 fprintf( dest, "<h2>" );
1737 for ( c = 'A'; c <= 'Z'; c++ )
1739 fprintf( dest, "<a href=\"#%c\">", c );
1740 RB_HTML_Generate_Char( dest, c );
1741 fprintf( dest, "</a> - " );
1745 for ( c = '0'; c <= '9'; c++ )
1747 fprintf( dest, "<a href=\"#%c\">", c );
1748 RB_HTML_Generate_Char( dest, c );
1749 fprintf( dest, "</a>" );
1751 // Do not generate separator for the last char
1754 fprintf( dest, " - " );
1758 fprintf( dest, "</h2>\n" );
1763 /****if* HTML_Generator/RB_HTML_Generate_Index_Table
1765 * RB_HTML_Generate_Index_Table --
1767 * Create a HTML TABLE containing links to headers of a particular
1768 * type. This creates two tables, a table for normal headers as
1769 * well as one for internal headers.
1772 void RB_HTML_Generate_Index_Table(
1775 struct RB_HeaderType *type,
1779 * o dest -- the file in which to write the table
1780 * o dest_name -- the name of this file
1781 * o type -- the type of header for which to generate
1783 * o title -- the title of the table.
1787 /* Compute the number of columns we need for
1788 * this type of header.
1791 // Generate Index Title
1792 fprintf( dest, "<h1>" );
1793 RB_HTML_Generate_String( dest, title );
1794 fprintf( dest, "</h1>\n" );
1796 // Generate Shortcuts at the begining
1797 RB_HTML_Generate_Index_Shortcuts( dest );
1799 if ( RB_Number_Of_Links( type, NULL, FALSE ) )
1801 if ( RB_Number_Of_Links( type, NULL, TRUE ) )
1803 /* only print a title if there are two tables. */
1804 fprintf( dest, "<h2>Normal</h2>" );
1806 RB_HTML_Generate_Table_Body( dest, dest_name, type, FALSE );
1809 if ( RB_Number_Of_Links( type, NULL, TRUE ) )
1811 /* Always print the Internal title, since
1812 * these headers are special and the user should know
1813 * he is looking at something special.
1815 fprintf( dest, "<h2>Internal</h2>" );
1816 RB_HTML_Generate_Table_Body( dest, dest_name, type, TRUE );
1819 // Generate Shortcuts at the end
1820 RB_HTML_Generate_Index_Shortcuts( dest );
1828 /*x**if* HTML_Generator/RB_HTML_Generate_Empty_Item
1830 * RB_HTML_Generate_Empty_Item --
1834 void RB_HTML_Generate_Empty_Item(
1837 fprintf( dest_doc, "<br>\n" );
1843 /****f* HTML_Generator/RB_HTML_Generate_Link
1845 * RB_HTML_Generate_Link --
1848 void RB_HTML_Generate_Link(
1857 * cur_doc -- the file to which the text is written
1858 * cur_name -- the name of the destination file
1859 * (the file from which we link)
1860 * filename -- the name of the file that contains the link
1861 * (the file we link to)
1862 * labelname-- the name of the unique label of the link.
1863 * linkname -- the name of the link as shown to the user.
1869 fprintf( cur_doc, "<a class=\"%s\" ", classname );
1873 fprintf( cur_doc, "<a " );
1875 if ( filename && strcmp( filename, cur_name ) && labelname)
1877 char *r = RB_HTML_RelativeAddress( cur_name, filename );
1879 fprintf( cur_doc, "href=\"%s#%s\">", r, labelname );
1880 RB_HTML_Generate_String( cur_doc, linkname );
1881 fprintf( cur_doc, "</a>" );
1885 fprintf( cur_doc, "href=\"#%s\">", labelname );
1886 RB_HTML_Generate_String( cur_doc, linkname );
1887 fprintf( cur_doc, "</a>" );
1891 fprintf( cur_doc, "href=\"%s\">", filename);
1892 RB_HTML_Generate_String( cur_doc, linkname );
1893 fprintf( cur_doc, "</a>" );
1900 /****f* HTML_Generator/RB_HTML_RelativeAddress
1902 * Link to 'that' from 'this' computing the relative path. Here
1903 * 'this' and 'that' are both paths. This function is used to
1904 * create links from one document to another document that might be
1905 * in a completely different directory.
1908 char *RB_HTML_RelativeAddress(
1914 * this /sub1/sub2/sub3/f.html
1915 * that /sub1/sub2/g.html
1920 * that /sub1/sub2/g.html
1929 * this /sub1/doc3/doc1/tt.html
1930 * that /sub1/doc5/doc2/qq.html
1932 * ../../doc5/doc2/qq.html
1935 * Notice the execelent docmentation.
1938 #define MAX_RELATIVE_SIZE 1024
1940 static char relative[MAX_RELATIVE_SIZE + 1];
1943 char *i_this_slash = NULL;
1944 char *i_that_slash = NULL;
1951 for ( i_this = thisname, i_that = thatname;
1952 ( *i_this && *i_that ) && ( *i_this == *i_that );
1953 ++i_this, ++i_that )
1955 if ( *i_this == '/' )
1957 i_this_slash = i_this;
1959 if ( *i_that == '/' )
1961 i_that_slash = i_that;
1965 if ( i_this_slash && i_that_slash )
1967 int this_slashes_left = 0;
1968 int that_slashes_left = 0;
1971 for ( i_c = i_this_slash + 1; *i_c; ++i_c )
1975 ++this_slashes_left;
1979 for ( i_c = i_that_slash + 1; *i_c; ++i_c )
1983 ++that_slashes_left;
1987 if ( this_slashes_left )
1991 for ( i = 0; i < this_slashes_left; ++i )
1993 strcat( relative, "../" );
1995 strcat( relative, i_that_slash + 1 );
1997 else if ( that_slashes_left )
1999 /* !this_slashes_left && that_slashes_left */
2000 strcat( relative, "./" );
2001 strcat( relative, i_that_slash + 1 );
2005 /* !this_slashes_left && !that_slashes_left */
2006 strcat( relative, "./" );
2007 strcat( relative, i_that_slash + 1 );
2017 /****f* HTML_Generator/RB_HTML_Generate_Char
2019 * RB_HTML_Generate_Char -- generate a single character for an item.
2022 void RB_HTML_Generate_Char(
2027 * This function is called for every character that goes
2028 * into an item's body. This escapes all the reserved
2029 * HTML characters such as '&', '<', '>', '"'.
2042 fprintf( dest_doc, "<" );
2045 fprintf( dest_doc, ">" );
2048 fprintf( dest_doc, "&" );
2051 // All others are printed literally
2052 fputc( c, dest_doc );
2059 void HTML_Generate_Begin_Content(
2062 HTML_Generate_Div( dest_doc, "content" );
2065 void HTML_Generate_End_Content(
2068 HTML_Generate_Div_End( dest_doc, "content" );
2071 void HTML_Generate_Begin_Navigation(
2074 HTML_Generate_Div( dest_doc, "navigation" );
2077 void HTML_Generate_End_Navigation(
2081 HTML_Generate_Div_End( dest_doc, "navigation" );
2084 void HTML_Generate_Begin_Extra(
2087 HTML_Generate_Div( dest_doc, "extra" );
2090 void HTML_Generate_End_Extra(
2093 HTML_Generate_Div_End( dest_doc, "extra" );
2099 /****f* HTML_Generator/RB_Create_CSS
2101 * Create the .css file. Unless the user specified it's own css
2102 * file robodoc creates a default one.
2104 * For multidoc mode the name of the .css file is
2106 * For singledoc mode the name of the .css file is equal
2107 * to the name of the documentation file.
2111 struct RB_Document *document )
2114 * o document -- the document for which to create the file.
2121 /* compute the complete path to the css file */
2122 if ( ( document->actions.do_singledoc ) ||
2123 ( document->actions.do_singlefile ) )
2125 char *extension = ".css";
2127 l += strlen( document->singledoc_name );
2128 l += strlen( extension );
2130 css_name = malloc( l );
2131 strcpy( css_name, document->singledoc_name );
2132 strcat( css_name, extension );
2136 struct RB_Path *docroot = document->docroot;
2137 char *docrootname = docroot->name;
2138 char *filename = "robodoc.css";
2140 l = strlen( filename );
2141 l += strlen( docrootname );
2143 css_name = malloc( l );
2144 strcpy( css_name, docrootname );
2145 strcat( css_name, filename );
2148 RB_Say( "Creating CSS file %s\n", SAY_DEBUG, css_name );
2149 if ( document->css )
2151 /* The user specified its own css file,
2152 * so we use the content of that.
2154 RB_CopyFile( document->css, css_name );
2158 css_file = fopen( css_name, "w" );
2161 /** BEGIN BEGIN BEGIN Don't remove */
2163 "/****h* ROBODoc/ROBODoc Cascading Style Sheet\n"
2165 " * This is the default cascading style sheet for documentation\n"
2166 " * generated with ROBODoc.\n"
2167 " * You can edit this file to your own liking and then use\n"
2168 " * it with the option\n"
2169 " * --css <filename>\n"
2171 " * This style-sheet defines the following layout\n"
2172 " * +----------------------------------------+\n"
2174 " * +----------------------------------------+\n"
2176 " * +----------------------------------------+\n"
2179 " * | content | |\n"
2181 " * +----------------------------------------+\n"
2183 " * +----------------------------------------+\n"
2185 " * This style-sheet is based on a style-sheet that was automatically\n"
2186 " * generated with the Strange Banana stylesheet generator.\n"
2187 " * See http://www.strangebanana.com/generator.aspx\n"
2190 " * $Id: html_generator.c,v 1.91 2007/07/10 19:13:51 gumpu Exp $\n"
2195 " background-color: rgb(255,255,255);\n"
2196 " color: rgb(98,84,55);\n"
2197 " font-family: Arial, serif;\n"
2198 " border-color: rgb(226,199,143);\n"
2203 " font-family: monospace;\n"
2206 " white-space: pre;\n"
2212 " background-color: #ffe;\n"
2213 " border: dashed #aa9 1px;\n"
2223 " font-weight: bolder;\n"
2225 " font-size: 120%%;\n"
2228 "#content\n" "{\n" " font-size: 100%%;\n" );
2230 " color: rgb(0,0,0);\n"
2231 " background-color: rgb(255,255,255);\n"
2232 " border-left-width: 0px; \n"
2233 " border-right-width: 0px; \n"
2234 " border-top-width: 0px; \n"
2235 " border-bottom-width: 0px;\n"
2236 " border-left-style: none; \n"
2237 " border-right-style: none; \n"
2238 " border-top-style: none; \n"
2239 " border-bottom-style: none;\n"
2240 " padding: 40px 31px 14px 17px;\n"
2241 " border-color: rgb(0,0,0);\n"
2242 " text-align: justify;\n"
2247 " background-color: rgb(98,84,55);\n"
2248 " color: rgb(230,221,202);\n"
2249 " font-family: \"Times New Roman\", serif;\n"
2250 " font-style: normal;\n"
2251 " border-color: rgb(0,0,0);\n"
2256 " font-size: 120%%;\n"
2257 " background-color: rgb(0,0,0);\n"
2258 " color: rgb(195,165,100);\n"
2259 " font-variant: normal;\n"
2260 " text-transform: none;\n"
2261 " font-weight: normal;\n"
2262 " padding: 1px 8px 3px 1px;\n"
2263 " margin-left: 5px; \n"
2264 " margin-right: 5px; \n"
2265 " margin-top: 5px; \n"
2266 " margin-bottom: 5px;\n"
2267 " border-color: rgb(159,126,57);\n"
2268 " text-align: right;\n"
2273 " font-size: 130%%;\n"
2274 " background-color: rgb(198,178,135);\n"
2275 " color: rgb(98,84,55);\n"
2276 " font-family: Georgia, serif;\n"
2277 " font-style: normal;\n"
2278 " font-variant: normal;\n"
2279 " text-transform: none;\n"
2280 " font-weight: bold;\n"
2281 " padding: 20px 18px 20px 18px;\n"
2282 " border-color: rgb(255,255,255);\n"
2283 " text-align: right;\n"
2286 "#extra, #extra a\n"
2288 " font-size: 128%%;\n"
2289 " background-color: rgb(0,0,0);\n"
2290 " color: rgb(230,221,202);\n"
2291 " font-style: normal;\n"
2292 " font-variant: normal;\n"
2293 " text-transform: none;\n"
2294 " font-weight: normal;\n" );
2296 " border-left-width: 0px; \n"
2297 " border-right-width: 0px; \n"
2298 " border-top-width: 0px; \n"
2299 " border-bottom-width: 0px;\n"
2300 " border-left-style: none; \n"
2301 " border-right-style: none; \n"
2302 " border-top-style: none; \n"
2303 " border-bottom-style: none;\n"
2304 " padding: 12px 12px 12px 12px;\n"
2305 " border-color: rgb(195,165,100);\n"
2306 " text-align: center;\n"
2311 " color: rgb(159,126,57);\n"
2312 " text-decoration: none;\n"
2315 "#content a:hover, #content a:active\n"
2317 " color: rgb(255,255,255);\n"
2318 " background-color: rgb(159,126,57);\n"
2323 " display: block;\n"
2326 "h1, h2, h3, h4, h5, h6\n"
2328 " background-color: rgb(221,221,221);\n"
2329 " font-family: Arial, serif;\n"
2330 " font-style: normal;\n"
2331 " font-variant: normal;\n"
2332 " text-transform: none;\n"
2333 " font-weight: normal;\n"
2338 " font-size: 151%%;\n"
2343 " font-size: 142%%;\n"
2348 " font-size: 133%%;\n"
2353 " font-size: 124%%;\n"
2358 " font-size: 115%%;\n"
2363 " font-size: 106%%;\n"
2368 " text-decoration: none;\n"
2373 " background-color: rgb(195,165,100);\n"
2374 " color: rgb(0,0,0);\n"
2379 " text-decoration: none;\n"
2384 " text-decoration: none;\n"
2395 " position: relative; \n"
2399 " text-align: center;\n"
2400 " margin-left: 10px;\n"
2403 ".menuitem {width: auto;}\n"
2404 "#content {width: auto;}\n"
2405 ".menuitem {display: block;}\n" "\n" "\n" );
2409 " background-color: rgb(198,178,135);\n"
2410 " color: rgb(98,84,55);\n"
2413 " font-size: 71%%;\n"
2418 " background-color: rgb(198,178,135);\n"
2419 " color: rgb(98,84,55);\n"
2425 " padding:5px 10px\n"
2450 " color: #008B8B;\n"
2456 " #navigation {display: none;}\n"
2457 " #content {padding: 0px;}\n"
2458 " #content a {text-decoration: underline;}\n"
2460 /** END END END Don't remove */
2465 RB_Panic( "Can't open %s for writing\n", css_name );
2479 char *r = RB_HTML_RelativeAddress( filename, css_name );
2482 assert( strlen( r ) );
2484 "<link rel=\"stylesheet\" href=\"%s\" type=\"text/css\" />\n",
2491 void HTML_Generate_Begin_Paragraph(
2494 fprintf( dest_doc, "<p>" );
2497 void HTML_Generate_End_Paragraph(
2500 fprintf( dest_doc, "</p>\n" );
2504 void HTML_Generate_Begin_Preformatted(
2508 // Check if we are preformatting a SOURCE item
2511 // SOURCE items have their own class in the CSS
2512 fprintf( dest_doc, "<pre class=\"%s\">", SOURCE_CLASS );
2516 fprintf( dest_doc, "<pre>" );
2520 void HTML_Generate_End_Preformatted(
2523 fprintf( dest_doc, "</pre>\n" );
2527 void HTML_Generate_Begin_List(
2530 fprintf( dest_doc, "<ul>" );
2533 void HTML_Generate_End_List(
2536 fprintf( dest_doc, "</ul>\n" );
2539 void HTML_Generate_Begin_List_Item(
2542 fprintf( dest_doc, "<li>" );
2545 void HTML_Generate_End_List_Item(
2548 fprintf( dest_doc, "</li>\n" );