\n" );
}
/* TODO Documentation */
void RB_HTML_Generate_Source_Tree(
FILE *dest_doc,
char *dest_name,
struct RB_Document *document )
{
struct RB_Directory *srctree;
srctree = document->srctree;
RB_HTML_Generate_Source_Tree_Entry( dest_doc, dest_name, NULL, srctree,
document );
}
/****if* HTML_Generator/RB_HTML_Generate_String
* FUNCTION
* Write a string to the destination document, escaping
* characters where necessary.
* SYNOPSIS
*/
static void RB_HTML_Generate_String(
FILE *dest_doc,
const char *a_string )
/*
* INPUTS
* o dest_doc -- the file the characters are written too
* o a_string -- a nul terminated string.
* SEE ALSO
* RB_HTML_Generate_Char()
* SOURCE
*/
{
int i;
int l = strlen( a_string );
unsigned char c;
for ( i = 0; i < l; ++i )
{
c = a_string[i];
RB_HTML_Generate_Char( dest_doc, c );
}
}
/*******/
/****if* HTML_Generator/RB_HTML_Generate_False_Link
* FUNCTION
* Create a representation for a link that links an word in
* a header to the header itself.
* SYNOPSIS
*/
void RB_HTML_Generate_False_Link(
FILE *dest_doc,
char *name )
/*
* INPUTS
* * dest_doc -- the file the representation is written to.
* * name -- the word.
* SOURCE
*/
{
fprintf( dest_doc, "" );
RB_HTML_Generate_String( dest_doc, name );
fprintf( dest_doc, "" );
}
/*******/
/****f* HTML_Generator/RB_HTML_Color_String
* FUNCTION
* Generates various colored strings
* SOURCE
*/
static void RB_HTML_Color_String(
FILE *dest_doc,
int open,
const char *class,
const char *string )
{
switch ( open )
{
// string, closing
case 0:
RB_HTML_Generate_String( dest_doc, string );
fprintf( dest_doc, "" );
break;
// opening, string
case 1:
fprintf( dest_doc, "", class );
RB_HTML_Generate_String( dest_doc, string );
break;
// opening, string, closing
case 2:
fprintf( dest_doc, "", class );
RB_HTML_Generate_String( dest_doc, string );
fprintf( dest_doc, "" );
break;
// opening, char, closing
case 3:
fprintf( dest_doc, "", class );
RB_HTML_Generate_Char( dest_doc, *string );
fprintf( dest_doc, "" );
break;
// Bug
default:
assert( 0 );
}
}
/*******/
/****f* HTML_Generator/RB_HTML_Generate_Line_Comment_End
* FUNCTION
* Check if a line comment is active and generate ending sequence for it.
* Should be called at the end of each SOURCE line.
* SYNOPSIS
*/
void RB_HTML_Generate_Line_Comment_End(
FILE *dest_doc )
{
// Check if we are in a line comment
if ( in_linecomment )
{
// and end the line comment
in_linecomment = 0;
RB_HTML_Color_String( dest_doc, in_linecomment, COMMENT_CLASS, "" );
}
}
/*******/
/****f* HTML_Generator/RB_HTML_Generate_Extra
* FUNCTION
* Do some additional processing to detect HTML extra's like
* file references and other kind of links for the documentation
* body of an item.
* SYNOPSIS
*/
int RB_HTML_Generate_Extra(
FILE *dest_doc,
enum ItemType item_type,
char *cur_char,
char prev_char )
/*
* INPUTS
* o dest_doc -- the file to write to.
* o item_type -- the kind of item the body belongs to.
* o cur_char -- pointer to a substring of the item's body
* o prev_char -- the character just before cur char (zero if none)
* RESULTS
* Number of characters produced.
* SOURCE
*/
{
char link[1024], *str;
int res = -1;
unsigned int i;
static int incomment = 0; /* are we in comment? */
static int quote = 0; /* double quote */
static int squote = 0; /* single quote */
// Reset comment and quote state machine if not source item
if ( !Works_Like_SourceItem( item_type ) )
{
quote = 0;
squote = 0;
incomment = 0;
in_linecomment = 0;
}
// else check for quotations and string literals
else if ( !( incomment || in_linecomment ) )
{
switch ( *cur_char )
{
// Check for quoted string literals ("string")
case '\"':
if ( !squote && course_of_action.do_quotes )
{
if ( prev_char != '\\' )
{
quote = !quote;
RB_HTML_Color_String( dest_doc, quote,
QUOTE_CLASS, "\"" );
return 0;
}
else if ( quote && *( ( char * ) ( cur_char - 2 ) ) == '\\' )
{
quote = !quote; /* case "... \\" */
RB_HTML_Color_String( dest_doc, quote,
QUOTE_CLASS, "\"" );
return 0;
}
}
break;
// Check for single quoted string literals ('string')
case '\'':
if ( !quote && course_of_action.do_squotes )
{
if ( prev_char != '\\' )
{
squote = !squote;
RB_HTML_Color_String( dest_doc, squote,
SQUOTE_CLASS, "\'" );
return 0;
}
else if ( squote && *( ( char * ) ( cur_char - 2 ) ) == '\\' )
{
squote = !squote; /* case '\\' */
RB_HTML_Color_String( dest_doc, squote,
SQUOTE_CLASS, "\'" );
return 0;
}
}
break;
default:
break;
}
}
// Recognise line comments
if ( Works_Like_SourceItem( item_type ) && !incomment && !quote
&& !squote && course_of_action.do_line_comments )
{
// check for line comment start
if ( !in_linecomment )
{
str =
Find_Parameter_Partial( &
( configuration.
source_line_comments ), cur_char );
if ( str )
{
in_linecomment = 1;
RB_HTML_Color_String( dest_doc, in_linecomment,
COMMENT_CLASS, str );
// We found it, so exit
return strlen( str ) - 1;
}
}
// The end of line comments are generated in
// RB_HTML_Generate_Line_Comment_End()
}
// Recognise block comments
if ( Works_Like_SourceItem( item_type ) && !in_linecomment && !quote
&& !squote && course_of_action.do_block_comments )
{
// Check for block comment start
if ( !incomment )
{
str =
Find_Parameter_Partial( &
( configuration.
remark_begin_markers ), cur_char );
if ( str )
{
incomment = 1;
RB_HTML_Color_String( dest_doc, incomment,
COMMENT_CLASS, str );
// We found it, so exit
return strlen( str ) - 1;
}
}
// Check for block comment end
else
{
str =
Find_Parameter_Partial( &( configuration.remark_end_markers ),
cur_char );
if ( str )
{
incomment = 0;
RB_HTML_Color_String( dest_doc, incomment,
COMMENT_CLASS, str );
// We found it, so exit
return strlen( str ) - 1;
}
}
}
// Do further source formating
if ( Works_Like_SourceItem( item_type ) &&
!in_linecomment && !incomment && !quote && !squote )
{
// Check for keywords
if ( configuration.keywords.number && course_of_action.do_keywords )
{
char *keyword;
// Check if we are at the beginning of a word
if ( !utf8_isalnum( prev_char ) && ( prev_char != '_' ) )
{
// Count word length
for ( i = 1; // A word should have at least one character...
utf8_isalnum( cur_char[i] ) || ( cur_char[i] == '_' );
i++ );
// Check if it is a keyword
if ( ( keyword = Find_Keyword( cur_char, i ) ) )
{
RB_HTML_Color_String( dest_doc, 2, KEYWORD_CLASS,
keyword );
// Exit function
return i - 1;
}
}
}
// Do some fancy coloration for non-alphanumeric chars
if ( !utf8_isalnum( *cur_char ) && *cur_char != '_'
&& *cur_char != ' ' && course_of_action.do_non_alpha )
{
RB_HTML_Color_String( dest_doc, 3, SIGN_CLASS, cur_char );
return 0;
}
}
// Check for links, etc...
if ( incomment || in_linecomment || !Works_Like_SourceItem( item_type ) )
{
if ( strncmp( "http://", cur_char, 7 ) == 0 )
{
sscanf( cur_char, "%s", link );
RB_Say( "found link %s\n", SAY_DEBUG, link );
res = ( strlen( link ) - 1 );
/* [ 697247 ] http://body. does not skip the '.' */
if ( link[( strlen( link ) - 1 )] == '.' )
{
link[( strlen( link ) - 1 )] = '\0';
fprintf( dest_doc, "%s.", link, link );
}
else
{
fprintf( dest_doc, "%s", link, link );
}
}
else if ( strncmp( "href:", cur_char, 5 ) == 0 )
{
/*
* handy in relative hyperlink paths, e.g.
* href:../../modulex/
*/
sscanf( ( cur_char + 5 ), "%s", link );
RB_Say( "found link %s\n", SAY_DEBUG, link );
res = ( strlen( link ) + 4 );
fprintf( dest_doc, "%s", link, link );
}
else if ( strncmp( "file:/", cur_char, strlen( "file:/" ) ) == 0 )
{
sscanf( cur_char, "%s", link );
RB_Say( "found link %s\n", SAY_DEBUG, link );
res = ( strlen( link ) - 1 );
fprintf( dest_doc, "%s", link, link );
}
else if ( strncmp( "mailto:", cur_char, 7 ) == 0 )
{
sscanf( ( cur_char + 7 ), "%s", link );
RB_Say( "found mail to %s\n", SAY_DEBUG, link );
res = ( strlen( link ) + 6 );
fprintf( dest_doc, "%s", link, link );
}
else if ( strncmp( "image:", cur_char, 6 ) == 0 )
{
sscanf( ( cur_char + 6 ), "%s", link );
RB_Say( "found image %s\n", SAY_DEBUG, link );
res = ( strlen( link ) + 5 );
fprintf( dest_doc, "", link );
}
}
return res;
}
/******/
void RB_HTML_Generate_Item_Name(
FILE *dest_doc,
char *name )
{
fprintf( dest_doc, "
" );
RB_HTML_Generate_String( dest_doc, name );
fprintf( dest_doc, "
\n" );
}
void RB_HTML_Generate_Item_Begin(
FILE *dest_doc,
char *name )
{
USE( dest_doc );
USE( name );
/* empty */
}
void RB_HTML_Generate_Item_End(
FILE *dest_doc,
char *name )
{
USE( dest_doc );
USE( name );
/* empty */
}
int sectiontoc_counters[MAX_SECTION_DEPTH];
/****f* HTML_Generator/RB_HTML_Generate_TOC_Section
* FUNCTION
* Create a table of contents based on the hierarchy of
* the headers starting for a particular point in this
* hierarchy (the parent).
* SYNOPSIS
*/
void RB_HTML_Generate_TOC_Section(
FILE *dest_doc,
char *dest_name,
struct RB_header *parent,
struct RB_header **headers,
int count,
int depth )
/*
* INPUTS
* o dest_doc -- the file to write to.
* o dest_name -- the name of this file.
* o parent -- the parent of the headers for which the the
* current level(depth) of TOC is created.
* o headers -- an array of headers for which the TOC is created
* o count -- the number of headers in this array
* o depth -- the current depth of the TOC
* NOTES
* This is a recursive function and tricky stuff.
* SOURCE
*/
{
struct RB_header *header;
int i, n, once = 0;
++sectiontoc_counters[depth];
for ( i = depth + 1; i < MAX_SECTION_DEPTH; ++i )
{
sectiontoc_counters[i] = 0;
}
// List item start
fprintf( dest_doc, "
" );
// Do not generate section numbers if sectionnameonly
if ( !( course_of_action.do_sectionnameonly ) )
{
for ( i = 1; i <= depth; ++i )
{
fprintf( dest_doc, "%d.", sectiontoc_counters[i] );
}
fprintf( dest_doc, " " );
}
// Generate Link to first reference name
RB_HTML_Generate_Link( dest_doc, dest_name, parent->file_name,
parent->unique_name,
// only generate function name if sectionnameonly
( course_of_action.do_sectionnameonly ) ?
parent->function_name : parent->name, 0 );
// Generate links to further reference names
for ( n = 1; n < parent->no_names; n++ )
{
RB_HTML_Generate_String( dest_doc, ", " );
RB_HTML_Generate_Link( dest_doc, dest_name, parent->file_name,
parent->unique_name, parent->names[n], 0 );
}
// List item end
fprintf( dest_doc, "
\n" );
for ( i = 0; i < count; ++i )
{
header = headers[i];
if ( header->parent == parent )
{
// Generate better TOC level hiearchy (Thuffir)
// We only generate
once for a level
if ( !once )
{
once = 1;
fprintf( dest_doc, "
\n" );
}
RB_HTML_Generate_TOC_Section( dest_doc, dest_name, header,
headers, count, depth + 1 );
}
else
{
/* Empty */
}
}
// If we have generated an
before, generate the closing one too.
if ( once )
fprintf( dest_doc, "
\n" );
}
/*******/
void RB_HTML_Generate_TOC_2(
FILE *dest_doc,
struct RB_header **headers,
int count,
struct RB_Part *owner,
char *dest_name )
{
struct RB_header *header;
int i, j;
int depth = 1;
for ( i = 0; i < MAX_SECTION_DEPTH; ++i )
{
sectiontoc_counters[i] = 0;
}
fprintf( dest_doc, "
TABLE OF CONTENTS
\n" );
if ( course_of_action.do_sections )
{
/* --sections was specified, create a TOC based on the
* hierarchy of the headers.
*/
fprintf( dest_doc, "
\n" );
for ( i = 0; i < count; ++i )
{
header = headers[i];
if ( owner == NULL )
{
if ( header->parent )
{
/* Will be done in the subfunction */
}
else
{
RB_HTML_Generate_TOC_Section( dest_doc, dest_name, header,
headers, count, depth );
}
}
else
{
/* This is the TOC for a specific RB_Part (MultiDoc
* documentation). We only include the headers that
* are part of the subtree. That is, headers that are
* parth the RB_Part, or that are childern of the
* headers in the RB_Part.
*/
if ( header->owner == owner )
{
/* BUG 721690 */
/* Any of the parents of this header should not
* have the same owner as this header, otherwise
* this header will be part of the TOC multiple times.
*/
int no_bad_parent = TRUE;
struct RB_header *parent = header->parent;
for ( ; parent; parent = parent->parent )
{
if ( parent->owner == owner )
{
no_bad_parent = FALSE;
break;
}
}
if ( no_bad_parent )
{
RB_HTML_Generate_TOC_Section( dest_doc, dest_name,
header, headers, count,
depth );
}
}
}
}
fprintf( dest_doc, "
\n" );
}
else
{
/* No --section option, generate a plain, one-level
* TOC
*/
fprintf( dest_doc, "
\n" );
}
}
/****if* HTML_Generator/RB_HTML_Generate_Index_Shortcuts
* NAME
* RB_HTML_Generate_Index_Shortcuts
* FUNCTION
* Generates alphabetic shortcuts to index entries.
* SYNOPSIS
*/
static void RB_HTML_Generate_Index_Shortcuts(
FILE *dest )
/*
* INPUTS
* o dest -- the file to write to
* TODO
* - Only list used letters.
* - List all letters (accented, signs, etc), not just the common ones.
* - Should be better to implement it as a
\n" );
}
/********/
/****if* HTML_Generator/RB_HTML_Generate_Index_Table
* NAME
* RB_HTML_Generate_Index_Table --
* FUNCTION
* Create a HTML TABLE containing links to headers of a particular
* type. This creates two tables, a table for normal headers as
* well as one for internal headers.
* SYNOPSIS
*/
void RB_HTML_Generate_Index_Table(
FILE *dest,
char *dest_name,
struct RB_HeaderType *type,
char *title )
/*
* INPUTS
* o dest -- the file in which to write the table
* o dest_name -- the name of this file
* o type -- the type of header for which to generate
* the table
* o title -- the title of the table.
* SOURCE
*/
{
/* Compute the number of columns we need for
* this type of header.
*/
// Generate Index Title
fprintf( dest, "
" );
RB_HTML_Generate_String( dest, title );
fprintf( dest, "
\n" );
// Generate Shortcuts at the begining
RB_HTML_Generate_Index_Shortcuts( dest );
if ( RB_Number_Of_Links( type, NULL, FALSE ) )
{
if ( RB_Number_Of_Links( type, NULL, TRUE ) )
{
/* only print a title if there are two tables. */
fprintf( dest, "
Normal
" );
}
RB_HTML_Generate_Table_Body( dest, dest_name, type, FALSE );
}
if ( RB_Number_Of_Links( type, NULL, TRUE ) )
{
/* Always print the Internal title, since
* these headers are special and the user should know
* he is looking at something special.
*/
fprintf( dest, "
Internal
" );
RB_HTML_Generate_Table_Body( dest, dest_name, type, TRUE );
}
// Generate Shortcuts at the end
RB_HTML_Generate_Index_Shortcuts( dest );
}
/********/
/* TODO */
/*x**if* HTML_Generator/RB_HTML_Generate_Empty_Item
* NAME
* RB_HTML_Generate_Empty_Item --
******
*/
void RB_HTML_Generate_Empty_Item(
FILE *dest_doc )
{
fprintf( dest_doc, " \n" );
}
/****f* HTML_Generator/RB_HTML_Generate_Link
* NAME
* RB_HTML_Generate_Link --
* SYNOPSIS
*/
void RB_HTML_Generate_Link(
FILE *cur_doc,
char *cur_name,
char *filename,
char *labelname,
char *linkname,
char *classname )
/*
* INPUTS
* cur_doc -- the file to which the text is written
* cur_name -- the name of the destination file
* (the file from which we link)
* filename -- the name of the file that contains the link
* (the file we link to)
* labelname-- the name of the unique label of the link.
* linkname -- the name of the link as shown to the user.
* SOURCE
*/
{
if ( classname )
{
fprintf( cur_doc, "", r, labelname );
RB_HTML_Generate_String( cur_doc, linkname );
fprintf( cur_doc, "" );
}
else
{
fprintf( cur_doc, "href=\"#%s\">", labelname );
RB_HTML_Generate_String( cur_doc, linkname );
fprintf( cur_doc, "" );
}
}
/******/
/****f* HTML_Generator/RB_HTML_RelativeAddress
* FUNCTION
* Link to 'that' from 'this' computing the relative path. Here
* 'this' and 'that' are both paths. This function is used to
* create links from one document to another document that might be
* in a completely different directory.
* SYNOPSIS
*/
char *RB_HTML_RelativeAddress(
char *thisname,
char *thatname )
/*
* EXAMPLE
* The following two
* this /sub1/sub2/sub3/f.html
* that /sub1/sub2/g.html
* result in
* ../g.html
*
* this /sub1/f.html
* that /sub1/sub2/g.html
* ==
* ./sub2/g.html
*
* this /sub1/f.html
* that /sub1/g.html
* ==
* ./g.html
*
* this /sub1/doc3/doc1/tt.html
* that /sub1/doc5/doc2/qq.html
* ==
* ../../doc5/doc2/qq.html
*
* NOTES
* Notice the execelent docmentation.
* SOURCE
*/
#define MAX_RELATIVE_SIZE 1024
{
static char relative[MAX_RELATIVE_SIZE + 1];
char *i_this;
char *i_that;
char *i_this_slash = NULL;
char *i_that_slash = NULL;
relative[0] = '\0';
assert( thisname );
assert( thatname );
for ( i_this = thisname, i_that = thatname;
( *i_this && *i_that ) && ( *i_this == *i_that );
++i_this, ++i_that )
{
if ( *i_this == '/' )
{
i_this_slash = i_this;
}
if ( *i_that == '/' )
{
i_that_slash = i_that;
}
}
if ( i_this_slash && i_that_slash )
{
int this_slashes_left = 0;
int that_slashes_left = 0;
char *i_c;
for ( i_c = i_this_slash + 1; *i_c; ++i_c )
{
if ( *i_c == '/' )
{
++this_slashes_left;
}
}
for ( i_c = i_that_slash + 1; *i_c; ++i_c )
{
if ( *i_c == '/' )
{
++that_slashes_left;
}
}
if ( this_slashes_left )
{
int i;
for ( i = 0; i < this_slashes_left; ++i )
{
strcat( relative, "../" );
}
strcat( relative, i_that_slash + 1 );
}
else if ( that_slashes_left )
{
/* !this_slashes_left && that_slashes_left */
strcat( relative, "./" );
strcat( relative, i_that_slash + 1 );
}
else
{
/* !this_slashes_left && !that_slashes_left */
strcat( relative, "./" );
strcat( relative, i_that_slash + 1 );
}
}
return relative;
}
/******/
/****f* HTML_Generator/RB_HTML_Generate_Char
* NAME
* RB_HTML_Generate_Char -- generate a single character for an item.
* SYNOPSIS
*/
void RB_HTML_Generate_Char(
FILE *dest_doc,
int c )
/*
* FUNCTION
* This function is called for every character that goes
* into an item's body. This escapes all the reserved
* HTML characters such as '&', '<', '>', '"'.
* SOURCE
*/
{
switch ( c )
{
case '\n':
assert( 0 );
break;
case '\t':
assert( 0 );
break;
case '<':
fprintf( dest_doc, "<" );
break;
case '>':
fprintf( dest_doc, ">" );
break;
case '&':
fprintf( dest_doc, "&" );
break;
default:
// All others are printed literally
fputc( c, dest_doc );
}
}
/*******/
void HTML_Generate_Begin_Content(
FILE *dest_doc )
{
HTML_Generate_Div( dest_doc, "content" );
}
void HTML_Generate_End_Content(
FILE *dest_doc )
{
HTML_Generate_Div_End( dest_doc, "content" );
}
void HTML_Generate_Begin_Navigation(
FILE *dest_doc )
{
HTML_Generate_Div( dest_doc, "navigation" );
}
void HTML_Generate_End_Navigation(
FILE *dest_doc )
{
HTML_Generate_Div_End( dest_doc, "navigation" );
}
void HTML_Generate_Begin_Extra(
FILE *dest_doc )
{
HTML_Generate_Div( dest_doc, "extra" );
}
void HTML_Generate_End_Extra(
FILE *dest_doc )
{
HTML_Generate_Div_End( dest_doc, "extra" );
}
/****f* HTML_Generator/RB_Create_CSS
* FUNCTION
* Create the .css file. Unless the user specified it's own css
* file robodoc creates a default one.
*
* For multidoc mode the name of the .css file is
* robodoc.css
* For singledoc mode the name of the .css file is equal
* to the name of the documentation file.
* SYNOPSIS
*/
void RB_Create_CSS(
struct RB_Document *document )
/*
* INPUTS
* o document -- the document for which to create the file.
* SOURCE
*/
{
size_t l = 0;
FILE *css_file;
/* compute the complete path to the css file */
if ( ( document->actions.do_singledoc ) ||
( document->actions.do_singlefile ) )
{
char *extension = ".css";
l += strlen( document->singledoc_name );
l += strlen( extension );
++l;
css_name = malloc( l );
strcpy( css_name, document->singledoc_name );
strcat( css_name, extension );
}
else
{
struct RB_Path *docroot = document->docroot;
char *docrootname = docroot->name;
char *filename = "robodoc.css";
l = strlen( filename );
l += strlen( docrootname );
++l;
css_name = malloc( l );
strcpy( css_name, docrootname );
strcat( css_name, filename );
}
RB_Say( "Creating CSS file %s\n", SAY_DEBUG, css_name );
if ( document->css )
{
/* The user specified its own css file,
* so we use the content of that.
*/
RB_CopyFile( document->css, css_name );
}
else
{
css_file = fopen( css_name, "w" );
if ( css_file )
{
/** BEGIN BEGIN BEGIN Don't remove */
fprintf( css_file,
"/****h* ROBODoc/ROBODoc Cascading Style Sheet\n"
" * FUNCTION\n"
" * This is the default cascading style sheet for documentation\n"
" * generated with ROBODoc.\n"
" * You can edit this file to your own liking and then use\n"
" * it with the option\n"
" * --css \n"
" *\n"
" * This style-sheet defines the following layout\n"
" * +----------------------------------------+\n"
" * | logo |\n"
" * +----------------------------------------+\n"
" * | extra |\n"
" * +----------------------------------------+\n"
" * | | navi- |\n"
" * | | gation |\n"
" * | content | |\n"
" * | | |\n"
" * +----------------------------------------+\n"
" * | footer |\n"
" * +----------------------------------------+\n"
" *\n"
" * This style-sheet is based on a style-sheet that was automatically\n"
" * generated with the Strange Banana stylesheet generator.\n"
" * See http://www.strangebanana.com/generator.aspx\n"
" *\n"
" ******\n"
" * $Id: html_generator.c,v 1.90 2007/06/14 15:13:02 thuffir Exp $\n"
" */\n"
"\n"
"body\n"
"{\n"
" background-color: rgb(255,255,255);\n"
" color: rgb(98,84,55);\n"
" font-family: Arial, serif;\n"
" border-color: rgb(226,199,143);\n"
"}\n"
"\n"
"pre\n"
"{\n"
" font-family: monospace;\n"
" margin: 15px;\n"
" padding: 5px;\n"
" white-space: pre;\n"
" color: #000;\n"
"}\n"
"\n"
"pre.source\n"
"{\n"
" background-color: #ffe;\n"
" border: dashed #aa9 1px;\n"
"}\n"
"\n"
"p\n"
"{\n"
" margin:15px;\n"
"}\n"
"\n"
"p.item_name \n"
"{\n"
" font-weight: bolder;\n"
" margin:5px;\n"
" font-size: 120%%;\n"
"}\n"
"\n"
"#content\n" "{\n" " font-size: 100%%;\n" );
fprintf( css_file,
" color: rgb(0,0,0);\n"
" background-color: rgb(255,255,255);\n"
" border-left-width: 0px; \n"
" border-right-width: 0px; \n"
" border-top-width: 0px; \n"
" border-bottom-width: 0px;\n"
" border-left-style: none; \n"
" border-right-style: none; \n"
" border-top-style: none; \n"
" border-bottom-style: none;\n"
" padding: 40px 31px 14px 17px;\n"
" border-color: rgb(0,0,0);\n"
" text-align: justify;\n"
"}\n"
"\n"
"#navigation\n"
"{\n"
" background-color: rgb(98,84,55);\n"
" color: rgb(230,221,202);\n"
" font-family: \"Times New Roman\", serif;\n"
" font-style: normal;\n"
" border-color: rgb(0,0,0);\n"
"}\n"
"\n"
"a.menuitem\n"
"{\n"
" font-size: 120%%;\n"
" background-color: rgb(0,0,0);\n"
" color: rgb(195,165,100);\n"
" font-variant: normal;\n"
" text-transform: none;\n"
" font-weight: normal;\n"
" padding: 1px 8px 3px 1px;\n"
" margin-left: 5px; \n"
" margin-right: 5px; \n"
" margin-top: 5px; \n"
" margin-bottom: 5px;\n"
" border-color: rgb(159,126,57);\n"
" text-align: right;\n"
"}\n"
"\n"
"#logo, #logo a\n"
"{\n"
" font-size: 130%%;\n"
" background-color: rgb(198,178,135);\n"
" color: rgb(98,84,55);\n"
" font-family: Georgia, serif;\n"
" font-style: normal;\n"
" font-variant: normal;\n"
" text-transform: none;\n"
" font-weight: bold;\n"
" padding: 20px 18px 20px 18px;\n"
" border-color: rgb(255,255,255);\n"
" text-align: right;\n"
"}\n"
"\n"
"#extra, #extra a\n"
"{\n"
" font-size: 128%%;\n"
" background-color: rgb(0,0,0);\n"
" color: rgb(230,221,202);\n"
" font-style: normal;\n"
" font-variant: normal;\n"
" text-transform: none;\n"
" font-weight: normal;\n" );
fprintf( css_file,
" border-left-width: 0px; \n"
" border-right-width: 0px; \n"
" border-top-width: 0px; \n"
" border-bottom-width: 0px;\n"
" border-left-style: none; \n"
" border-right-style: none; \n"
" border-top-style: none; \n"
" border-bottom-style: none;\n"
" padding: 12px 12px 12px 12px;\n"
" border-color: rgb(195,165,100);\n"
" text-align: center;\n"
"}\n"
"\n"
"#content a\n"
"{\n"
" color: rgb(159,126,57);\n"
" text-decoration: none;\n"
"}\n"
"\n"
"#content a:hover, #content a:active\n"
"{\n"
" color: rgb(255,255,255);\n"
" background-color: rgb(159,126,57);\n"
"}\n"
"\n"
"a.indexitem\n"
"{\n"
" display: block;\n"
"}\n"
"\n"
"h1, h2, h3, h4, h5, h6\n"
"{\n"
" background-color: rgb(221,221,221);\n"
" font-family: Arial, serif;\n"
" font-style: normal;\n"
" font-variant: normal;\n"
" text-transform: none;\n"
" font-weight: normal;\n"
"}\n"
"\n"
"h1\n"
"{\n"
" font-size: 151%%;\n"
"}\n"
"\n"
"h2\n"
"{\n"
" font-size: 142%%;\n"
"}\n"
"\n"
"h3\n"
"{\n"
" font-size: 133%%;\n"
"}\n"
"\n"
"h4\n"
"{\n"
" font-size: 124%%;\n"
"}\n"
"\n"
"h5\n"
"{\n"
" font-size: 115%%;\n"
"}\n"
"\n"
"h6\n"
"{\n"
" font-size: 106%%;\n"
"}\n"
"\n"
"#navigation a\n"
"{\n"
" text-decoration: none;\n"
"}\n"
"\n"
".menuitem:hover\n"
"{\n"
" background-color: rgb(195,165,100);\n"
" color: rgb(0,0,0);\n"
"}\n"
"\n"
"#extra a\n"
"{\n"
" text-decoration: none;\n"
"}\n"
"\n"
"#logo a\n"
"{\n"
" text-decoration: none;\n"
"}\n"
"\n"
"#extra a:hover\n"
"{\n"
"}\n"
"\n"
"/* layout */\n"
"#navigation\n"
"{\n"
" width: 22%%; \n"
" position: relative; \n"
" top: 0; \n"
" right: 0; \n"
" float: right; \n"
" text-align: center;\n"
" margin-left: 10px;\n"
"}\n"
"\n"
".menuitem {width: auto;}\n"
"#content {width: auto;}\n"
".menuitem {display: block;}\n" "\n" "\n" );
fprintf( css_file,
"div#footer\n"
"{\n"
" background-color: rgb(198,178,135);\n"
" color: rgb(98,84,55);\n"
" clear: left;\n"
" width: 100%%;\n"
" font-size: 71%%;\n"
"}\n"
"\n"
"div#footer a\n"
"{\n"
" background-color: rgb(198,178,135);\n"
" color: rgb(98,84,55);\n"
"}\n"
"\n"
"div#footer p\n"
"{\n"
" margin:0;\n"
" padding:5px 10px\n"
"}\n"
"\n"
"span.keyword\n"
"{\n"
" color: #00F;\n"
"}\n"
"\n"
"span.comment\n"
"{\n"
" color: #080;\n"
"}\n"
"\n"
"span.quote\n"
"{\n"
" color: #F00;\n"
"}\n"
"\n"
"span.squote\n"
"{\n"
" color: #F0F;\n"
"}\n"
"\n"
"span.sign\n"
"{\n"
" color: #008B8B;\n"
"}\n"
"\n"
"\n"
"@media print\n"
"{\n"
" #navigation {display: none;}\n"
" #content {padding: 0px;}\n"
" #content a {text-decoration: underline;}\n"
"}\n" );
/** END END END Don't remove */
fclose( css_file );
}
else
{
RB_Panic( "Can't open %s for writing\n", css_name );
}
}
}
/*******/
void RB_InsertCSS(
FILE *dest_doc,
char *filename )
{
if ( css_name )
{
char *r = RB_HTML_RelativeAddress( filename, css_name );
assert( r );
assert( strlen( r ) );
fprintf( dest_doc,
"\n",
r );
}
}
void HTML_Generate_Begin_Paragraph(
FILE *dest_doc )
{
fprintf( dest_doc, "
\n" );
}
void HTML_Generate_Begin_Preformatted(
FILE *dest_doc,
int source )
{
// Check if we are preformatting a SOURCE item
if ( source )
{
// SOURCE items have their own class in the CSS
fprintf( dest_doc, "