HTML_Generator

[ Top ] [ ROBODoc ] [ Modules ]

FUNCTION

The generator for HTML output.

The generator supports sections upto 7 levels deep. It supports a Table of Contents based on all headers. A masterindex for all headertypes and seperate masterindexes for each headertype.

MODIFICATION HISTORY

2003-02-03 Frans Slothouber Refactoring ????-??-?? Frans Slothouber V1.0


RB_Create_CSS

[ Top ] [ HTML_Generator ] [ Functions ]

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

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 <filename>\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.94 2008/06/17 11:49:27 gumpu 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"
                     "span.line_number\n"
                     "{\n"
                     "    color: #808080;\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 );
        }
    }
}

RB_HTML_Color_String

[ Top ] [ HTML_Generator ] [ Functions ]

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, "</span>" );
        break;

        /*  opening, string */
    case 1:
        fprintf( dest_doc, "<span class=\"%s\">", class );
        RB_HTML_Generate_String( dest_doc, string );
        break;

        /*  opening, string, closing */
    case 2:
        fprintf( dest_doc, "<span class=\"%s\">", class );
        RB_HTML_Generate_String( dest_doc, string );
        fprintf( dest_doc, "</span>" );
        break;

        /*  opening, char, closing */
    case 3:
        fprintf( dest_doc, "<span class=\"%s\">", class );
        RB_HTML_Generate_Char( dest_doc, *string );
        fprintf( dest_doc, "</span>" );
        break;

        /*  Bug */
    default:
        assert( 0 );
    }
}

RB_HTML_Generate_Char

[ Top ] [ HTML_Generator ] [ Functions ]

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, "&lt;" );
        break;
    case '>':
        fprintf( dest_doc, "&gt;" );
        break;
    case '&':
        fprintf( dest_doc, "&amp;" );
        break;
    default:
        /*  All others are printed literally */
        fputc( c, dest_doc );
    }
}

RB_HTML_Generate_Doc_Start

[ Top ] [ HTML_Generator ] [ Functions ]

NAME

RB_HTML_Generate_Doc_Start --

FUNCTION

Generate the first part of a HTML document. As far as ROBODoc is concerned a HTML document consists of three parts:

SYNOPSIS

void RB_HTML_Generate_Doc_Start(
    FILE *dest_doc,
    char *src_name,
    char *name,
    char *dest_name,
    char *charset )

INPUTS

SOURCE

{

    if ( course_of_action.do_headless )
    {
        /* The user wants a headless document, so we skip everything
         * upto and until <BODY>
         */
    }
    else
    {
        /* Append document type and title */
        fprintf( dest_doc, "<?xml version=\"1.0\" encoding=\"%s\"?>\n",
                 charset ? charset : DEFAULT_CHARSET );
        fprintf( dest_doc,
                 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n" );
        fprintf( dest_doc,
                 "                      \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" );

        fprintf( dest_doc,
                 "<html  xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" );
        fprintf( dest_doc, "<head>\n" );
        fprintf( dest_doc,
                 "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\" />\n" );
        /* TODO is charset still needed?? */
        fprintf( dest_doc,
                 "<meta http-equiv=\"Content-type\" content=\"text/html; charset=%s\" />\n",
                 charset ? charset : DEFAULT_CHARSET );
        RB_InsertCSS( dest_doc, dest_name );
        fprintf( dest_doc, "<title>%s</title>\n", name );

        /* append SGML-comment with document- and copyright-info. This code
         * ensures that every line has an own comment to avoid problems with
         * buggy browsers */
        fprintf( dest_doc, "<!-- Source: %s -->\n", src_name );
        if ( course_of_action.do_nogenwith )
        {

        }
        else
        {
            static const char   copyright_text[]
                = COMMENT_ROBODOC /* COMMENT_COPYRIGHT */ ;
            size_t              i = 0;
            char                previous_char = '\n';
            char                current_char = copyright_text[i];

            while ( current_char )
            {
                if ( previous_char == '\n' )
                {
                    fprintf( dest_doc, "<!-- " );
                }
                if ( current_char == '\n' )
                {
                    fprintf( dest_doc, " -->" );
                }
                else if ( ( current_char == '-' )
                          && ( previous_char == '-' ) )
                {
                    /* avoid "--" inside SGML-comment, and use "-_" instead; this
                     * looks a bit strange, but one should still be able to figure
                     * out what is meant when reading the output */
                    current_char = '_';
                }
                fputc( current_char, dest_doc );
                i += 1;
                previous_char = current_char;
                current_char = copyright_text[i];
            }
        }

        /* append heading and start list of links to functions */
        fprintf( dest_doc, "</head>\n" );
        fprintf( dest_doc, "<body>\n" );
    }

/*     HTML_Generate_Div( dest_doc, "container" ); */

    /* Generate document title if available (Thuffir) */
    HTML_Generate_Div( dest_doc, "logo" );
    fprintf( dest_doc, "<a name=\"robo_top_of_doc\">" );
    if ( document_title )
        RB_HTML_Generate_String( dest_doc, document_title );
    fprintf( dest_doc, "</a>\n" );
    HTML_Generate_Div_End( dest_doc, "logo" );



}

RB_HTML_Generate_Extra

[ Top ] [ HTML_Generator ] [ Functions ]

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

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, "<a href=\"%s\">%s</a>.", link, link );
            }
            else
            {
                fprintf( dest_doc, "<a href=\"%s\">%s</a>", link, link );
            }
        }
        else if ( strncmp( "href:", cur_char, 5 ) == 0 )
        {
            /*
             * handy in relative hyperlink paths, e.g.
             * ../../modulex/
             */
            sscanf( ( cur_char + 5 ), "%s", link );
            RB_Say( "found link %s\n", SAY_DEBUG, link );
            res = ( strlen( link ) + 4 );
            fprintf( dest_doc, "<a href=\"%s\">%s</a>", 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, "<a href=\"%s\">%s</a>", 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, "<a href=\"mailto:%s\">%s</a>", 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, "<img src=\"%s\">", link );
        }

    }
    return res;
}

RB_HTML_Generate_Index_Page

[ Top ] [ HTML_Generator ] [ Functions ]

FUNCTION

Generate a single file with a index table for headers of one specific type of headers

SYNOPSIS

void RB_HTML_Generate_Index_Page(
    struct RB_Document *document,
    struct RB_HeaderType *header_type )

INPUTS


RB_HTML_Generate_IndexMenu

[ Top ] [ HTML_Generator ] [ Functions ]

FUNCTION

Generates a menu to jump to the various master index files for the various header types. The menu is generated for each of the master index files. The current header type is highlighted.

SYNOPSIS

void RB_HTML_Generate_IndexMenu(
    FILE *dest_doc,
    char *filename,
    struct RB_Document *document,
    struct RB_HeaderType *cur_type )
    /* TODO  Use cur_type */

INPUTS


RB_HTML_Generate_Item_Line_Number

[ Top ] [ HTML_Generator ] [ Functions ]

FUNCTION

Generate line numbers for SOURCE like items

SYNOPSIS

void RB_HTML_Generate_Item_Line_Number(
    FILE *dest_doc,
    char *line_number_string )

INPUTS

SOURCE

{
    RB_HTML_Color_String( dest_doc, 2, LINE_NUMBER_CLASS,
                          line_number_string );
}

RB_HTML_Generate_Label

[ Top ] [ HTML_Generator ] [ Functions ]

FUNCTION

Generate a label (name) that can be refered too. A label should consist of only alphanumeric characters so all 'odd' characters are replaced with their ASCII code in hex format.

SYNOPSIS

void RB_HTML_Generate_Label(
    FILE *dest_doc,
    char *name )

INPUTS

SOURCE

{
    int                 i;
    int                 l = strlen( name );
    unsigned char       c;

    fprintf( dest_doc, "<a name=\"" );
    for ( i = 0; i < l; ++i )
    {
        c = name[i];
        if ( utf8_isalnum( c ) )
        {
            RB_HTML_Generate_Char( dest_doc, c );
        }
        else
        {
            char                buf[4];

            sprintf( buf, "%02x", c );
            RB_HTML_Generate_Char( dest_doc, buf[0] );
            RB_HTML_Generate_Char( dest_doc, buf[1] );
        }
    }
    fprintf( dest_doc, "\"></a>\n" );
}

RB_HTML_Generate_Line_Comment_End

[ Top ] [ HTML_Generator ] [ Functions ]

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, "" );
    }
}

RB_HTML_Generate_Link

[ Top ] [ HTML_Generator ] [ Functions ]

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, "<a class=\"%s\" ", classname );
    }
    else
    {
        fprintf( cur_doc, "<a " );
    }
    if ( filename && strcmp( filename, cur_name ) )
    {
        char               *r = RB_HTML_RelativeAddress( cur_name, filename );

        fprintf( cur_doc, "href=\"%s#%s\">", r, labelname );
        RB_HTML_Generate_String( cur_doc, linkname );
        fprintf( cur_doc, "</a>" );

    }
    else
    {
        fprintf( cur_doc, "href=\"#%s\">", labelname );
        RB_HTML_Generate_String( cur_doc, linkname );
        fprintf( cur_doc, "</a>" );
    }
}

RB_HTML_Generate_TOC_Section

[ Top ] [ HTML_Generator ] [ Functions ]

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

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, "<li>" );

    /*  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, "</li>\n" );

    for ( i = 0; i < count; ++i )
    {
        header = headers[i];
        if ( header->parent == parent )
        {
            /*  Generate better TOC level hiearchy (Thuffir) */
            /*  We only generate <ul> once for a level */
            if ( !once )
            {
                once = 1;
                fprintf( dest_doc, "<ul>\n" );
            }
            RB_HTML_Generate_TOC_Section( dest_doc, dest_name, header,
                                          headers, count, depth + 1 );
        }
        else
        {
            /* Empty */
        }
    }
    /*  If we have generated an <ul> before, generate the closing one too. */
    if ( once )
        fprintf( dest_doc, "</ul>\n" );
}

RB_HTML_RelativeAddress

[ Top ] [ HTML_Generator ] [ Functions ]

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;
}