Exemple #1
0
/* This function will do proper escaping or character substitution for
 * characters special to InfoBench and add them to the section text.
 */
static int trans_add_char_ib( int ch, section_def *section, int *alloc_size )
/***************************************************************************/
{
    int                 len=0;
    int                 esc;

    esc = map_char_ib( ch );
    if( esc == MAP_REMOVE ) {
        return( 0 );
    } else if( esc != MAP_NONE ) {
        len += trans_add_char( esc, section, alloc_size );
    }

    len += trans_add_char( ch, section, alloc_size );

    return( len );
}
Exemple #2
0
static void draw_line( section_def *section, allocsize *alloc_size )
/******************************************************************/
{
    int         i;

    trans_add_str( ":cgraphic.\n", section, alloc_size );
    for( i = BOX_LINE_SIZE; i > 0; --i ) {
        trans_add_char( CH_BOX_HBAR, section, alloc_size );
    }
    trans_add_str( "\n:ecgraphic.\n", section, alloc_size );
}
Exemple #3
0
static void draw_line(
/********************/

    section_def         *section,
    int                 *alloc_size
) {
    int                 i;

    trans_add_str( ":cgraphic.\n", section, alloc_size );
    for( i = BOX_LINE_SIZE; i > 0; --i ) {
        trans_add_char( 196, section, alloc_size );
    }
    trans_add_str( "\n:ecgraphic.\n", section, alloc_size );
}
Exemple #4
0
int ib_trans_line(
/*****************/

    section_def         *section,
    int                 alloc_size
) {
    char                *ptr;
    char                *end;
    int                 ch;
    char                *ctx_name;
    char                *ctx_text;
    char                buf[ 100 ];
    int                 indent = 0;
    int                 ctr;
    char                *file_name;

    // check for special pre-processing stuff first
    ptr = Line_buf;
    ch = *(unsigned char *)ptr;

    // We start at a new line...
    Wrap_Safe = section->section_size;
    Cursor_X = 0;
    R_Chars = 0;

    if( Blank_line && ( ch != CH_LIST_ITEM ||
                        Curr_list->compact != LIST_SPACE_COMPACT ) ) {
        Blank_line = FALSE;
    }
    switch( ch ) {
    // Tabbed-example
    case CH_TABXMP:
        if( *skip_blank( ptr + 1 ) == '\0' ) {
            Tab_xmp = FALSE;
        } else {
            read_tabs( ptr + 1 );
            Tab_xmp = TRUE;
        }
        return( alloc_size );

    // Box-mode start
    case CH_BOX_ON:
        ctr = 0;
        // indent properly
        while( ctr < Curr_indent ) {
            ctr++;
            trans_add_char( ' ', section, &alloc_size);
        }
        // draw the top line of the box
        trans_add_char( BOX_CORNER_TOP_LEFT, section, &alloc_size );
        for( ctr = 1; ctr <= Right_Margin - Curr_indent - 2; ctr++ ) {
            trans_add_char( BOX_HBAR, section, &alloc_size );
        }
        trans_add_char( BOX_CORNER_TOP_RIGHT, section, &alloc_size );

        trans_add_char_wrap( '\n', section, &alloc_size);

        Box_Mode = TRUE;
        return( alloc_size );

    case CH_BOX_OFF:
        ctr = 0;
        while( ctr < Curr_indent ) {
            ctr++;
            trans_add_char( ' ', section, &alloc_size);
        }

        trans_add_char( BOX_CORNER_BOTOM_LEFT, section, &alloc_size );
        for( ctr = 1; ctr <= Right_Margin - Curr_indent - 2; ctr++ ) {
            trans_add_char( BOX_HBAR, section, &alloc_size );
        }
        trans_add_char( BOX_CORNER_BOTOM_RIGHT, section, &alloc_size );
        Box_Mode = FALSE;

        trans_add_char_wrap( '\n', section, &alloc_size );

        return( alloc_size );

    case CH_OLIST_START:
        new_list( LIST_TYPE_ORDERED );
        set_compact( ptr );
        Curr_indent += Text_Indent;
        return( alloc_size );

    case CH_LIST_START:
    case CH_DLIST_START:
        new_list( ( ch == CH_LIST_START ) ? LIST_TYPE_UNORDERED :
                                                        LIST_TYPE_DEFN );
        set_compact( ptr );
        Curr_indent += Text_Indent;

        if( ch == CH_DLIST_START ) {
            ptr = skip_blank( ptr + 1 );
            if( *ptr != '\0' ) {
                /* due to a weakness in GML, the definition term must be
                   allowed on the same line as the definition tag. So
                   if its there, continue */
                break;
            }
        }
        return( alloc_size );

    case CH_DLIST_TERM:
        Curr_indent -= Text_Indent;
        break;

    case CH_SLIST_START:
        indent = 0;
        if( Curr_list->type == LIST_TYPE_SIMPLE ) {
            /* nested simple lists, with no pre-indent. Force an
               indent */
            indent = Text_Indent;
        }

        new_list( LIST_TYPE_SIMPLE );
        set_compact( ptr );
        Curr_indent += indent;
        return( alloc_size );

    case CH_SLIST_END:
    case CH_OLIST_END:
    case CH_LIST_END:
    case CH_DLIST_END:
        pop_list();
        return( alloc_size );

    case CH_DLIST_DESC:
        Curr_indent += Text_Indent;
        if( *skip_blank( ptr + 1 ) == '\0' ) {
            /* no description on this line. Ignore it so that no
               blank line gets generated */
            return( alloc_size );
        }
        break;

    case CH_CTX_KW:
        ptr = whole_keyword_line( ptr );
        if( ptr == NULL ) {
            return( alloc_size );
        }
        break;
    }

    // skip preceding blank lines
    if( *skip_blank( ptr ) == '\0' && Curr_ctx->empty ) {
        return( alloc_size );
    }

    // remove '\n' on the end
    if( Blank_line ) {
        --section->section_size;
    }

    // indent properly if the first char is not white-space
    if( ch != '\0' && ch != ' ' && ch != '\t') {
        ctr = ( ch == CH_LIST_ITEM && !Box_Mode &&
                        Curr_list->type != LIST_TYPE_SIMPLE )
                ? Text_Indent
                : 0;
        while( ctr < Curr_indent ) {
            ctr++;
            trans_add_char_wrap( ' ', section, &alloc_size);
        }

        if( Box_Mode ) {
            trans_add_char_wrap( BOX_VBAR, section, &alloc_size);
            trans_add_char_wrap( ' ', section, &alloc_size);
        }
    }

    Blank_line = TRUE;
    for( ;; ) {
        ch = *(unsigned char *)ptr;
        if( ch != '\0' && ( ch != ' ' || ch != '\t' ) ) {
            Blank_line = FALSE;
        }
        if( ch == '\0' ) {
            // this just shuts off bolding after a def. list term
            if( Line_postfix == LPOSTFIX_TERM ) {
                Line_postfix = LPOSTFIX_NONE;
                trans_add_str( STR_BOLD_OFF, section, &alloc_size );
            }
            trans_add_char_wrap( '\n', section, &alloc_size );
            break;
        } else if( ch == CH_HLINK || ch == CH_DFN || ch == CH_FLINK ) {
            Curr_ctx->empty = FALSE;
            if( ch == CH_FLINK ) {
                file_name = strchr( ptr + 1, ch );
                if( file_name == NULL ) {
                    error( ERR_BAD_LINK_DFN, TRUE );
                }
                *file_name = '\0';
            } else {
                file_name = ptr;
            }
            ctx_name = strchr( file_name + 1, ch );
            if( ctx_name == NULL ) {
                error( ERR_BAD_LINK_DFN, TRUE );
            }
            *ctx_name = '\0';

            ctx_text = strchr( ctx_name + 1, ch );
            if( ctx_text == NULL ) {
                error( ERR_BAD_LINK_DFN, TRUE );
            }
            *ctx_text = '\0';

            ctx_text = ctx_name + 1;
            ctx_name = file_name + 1;
            file_name = ptr + 1;
            if( ch != CH_FLINK ) {
                add_link( ctx_name );
            }

            ptr = ctx_text + strlen( ctx_text ) + 1;

            // Definition pop-up's are converted to hyper-links in InfoBench
            trans_add_char( CHR_TEMP_HLINK , section, &alloc_size );

            // Add line number to hyperlink so we can give meaningful errors
            trans_add_str( itoa( Line_num, buf, 10 ), section, &alloc_size );
            trans_add_char( CHR_TEMP_HLINK, section, &alloc_size );

            // We don't want links to break as IB doesn't like this...
            to_nobreak( ctx_text );

            indent = Curr_indent;
            if( indent < 0 )
                indent = 0;
            // find out the maximum allowed length for hyper-link text:
            ctr = Right_Margin - indent - ( ( Hyper_Brace_L == '<' ) ? 2 : 0 );

            // if the link name is too long then we warn & truncate it
            if( strlen( ctx_text ) > ctr ) {
                warning( "Hyperlink name too long", Line_num );
                ctx_text[ ctr ] = '\0';
            }

            /* If hyper-link bracing is on we have to do a kludge to fix
             * the spacing. The "XX" will make the wrap routine happy.
             * They're stripped off when it comes time to write the file.
             */
            if( Hyper_Brace_L == '<' ) {
                trans_add_str_wrap( "XX", section, &alloc_size );
            }
            trans_add_str_wrap( ctx_text, section, &alloc_size );
            trans_add_char( CHR_HLINK_BREAK , section, &alloc_size );
            trans_add_str( ctx_name, section, &alloc_size );
            if( ch == CH_FLINK ) {
                trans_add_char( CHR_HLINK_BREAK, section, &alloc_size );
                trans_add_str( file_name, section, &alloc_size );
            }
            trans_add_char( CHR_TEMP_HLINK , section, &alloc_size );
        } else if( ch == CH_LIST_ITEM ) {
            if( Curr_list->type != LIST_TYPE_SIMPLE ) {
                if( Curr_list->type == LIST_TYPE_UNORDERED ) {
                    // generate a bullet, correctly spaced for tab size
                    buf[0] = '\0';
                    for( ctr = 1; ctr <= Text_Indent; ctr++)
                    {
                        strcat( buf, " " );
                    }
                    buf[ Text_Indent / 2 - 1 ] = CHR_BULLET;
                } else if( Curr_list->type == LIST_TYPE_ORDERED ) {
                    /* ordered list type */
                    sprintf( buf, "%*d. ", Text_Indent - 2,
                                                        Curr_list->number );
                    ++Curr_list->number;
                }
                trans_add_str_wrap( buf, section, &alloc_size );
            }
            Eat_blanks = TRUE;
            ptr = skip_blank( ptr + 1 );
        } else if( ch == CH_DLIST_DESC ) {
            ptr = skip_blank( ptr + 1 );
        } else if( ch == CH_DLIST_TERM ) {
            /* definition list term */
            trans_add_str( STR_BOLD_ON, section, &alloc_size );
            Line_postfix = LPOSTFIX_TERM;
            ptr = skip_blank( ptr + 1 );
            Eat_blanks = TRUE;
        } else if( ch == CH_CTX_KW ) {
            end = strchr( ptr + 1, CH_CTX_KW );
            memcpy( buf, ptr + 1, end - ptr - 1 );
            buf[end - ptr - 1] = '\0';
            add_ctx_keyword( Curr_ctx, buf );
            ptr = end + 1;
            if( *ptr == ' ' ) {
                /* kludge fix cuz of GML: GML thinks that keywords are
                   are real words, so it puts a space after them.
                   This should fix that */
                ++ptr;
            }
        } else if( ch == CH_PAR_RESET ) {
            // we ignore paragraph resets
            ++ptr;
        } else if( ch == CH_BMP ) {
            // we ignore bitmaps
            ptr = strchr( ptr + 3, CH_BMP ) + 1;
        } else if( ch == CH_FONTSTYLE_START ) {
            ++ptr;
            end = strchr( ptr, CH_FONTSTYLE_START );
            for( ; ptr != end; ++ptr ) {
                switch( *ptr ) {

                // bold and italic map to bold
                case 'b':
                case 'i':
                    trans_add_str( STR_BOLD_ON, section, &alloc_size );
                    break;

                // underline and underscore map to underline
                case 'u':
                case 's':
                    trans_add_str( STR_UNDERLINE_ON, section, &alloc_size );
                    break;
                }
            }
            ++ptr;
        } else if( ch == CH_FONTSTYLE_END ) {
            // reset style (bold off, underline off)
            trans_add_str( Reset_Style, section, &alloc_size );
            ++ptr;
        } else if( ch == CH_FONTTYPE ) {
            // we basically ignore font type changes
            ptr = strchr( strchr( ptr + 1 , CH_FONTTYPE ) + 1,
                            CH_FONTTYPE ) + 1;
        } else {
            ++ptr;
            if( !Eat_blanks || ch != ' ' ) {
                Curr_ctx->empty = FALSE;

                if( Tab_xmp && ch == Tab_xmp_char ) {
                    tab_align( section, &alloc_size );
                    ptr = skip_blank( ptr );
                } else {
                    trans_add_char_wrap( ch, section, &alloc_size );
                }

                Eat_blanks = FALSE;
            }
        }
    }

    return( alloc_size );
}
Exemple #5
0
// The following two functions handle word-wrapping
int trans_add_char_wrap( int ch, section_def *section, int *alloc_size )
/**********************************************************************/
{
    int                 ctr;            // misc. counter
    int                 wrap_amount;    // amount of wrapped text
    int                 shift;          // amount we need to shift text
    int                 delta;          // amount of whitespace we ignore
    int                 indent;         // actual indent
    int                 len = 0;        // number of chars we just added

    // the "1" is because a character is allowed to appear on the right margin
    // the minus part is so that we leave enough room for the box chars
    #define MY_MARGIN ( Right_Margin + 1 - ( Box_Mode ? 2 : 0 ) )

    // find out the real indentation
    indent = Curr_indent;
    if( indent < 0 )
        indent = 0;

    // add character
    if( ch == '\n' ) {
        NL_Group++;
        if( Box_Mode ) {
            // Add left side if necessary:
            while( Cursor_X < indent ) {
                trans_add_char( ' ', section, alloc_size );
                Cursor_X++;
            }
            if( Cursor_X == indent ) {
                trans_add_char( BOX_VBAR, section, alloc_size );
                Cursor_X++;
            }

            // Now add right side:
            // the "- 1" is for the BOX_VBAR
            while( Cursor_X < Right_Margin - 1 ) {
                trans_add_char( ' ', section, alloc_size );
                Cursor_X++;
            }
            // Now add vertical bar if room (there should be...)
            if( Cursor_X == Right_Margin - 1 ) {
                trans_add_char( BOX_VBAR, section, alloc_size );
            }
        }
        R_Chars = 0;
        Cursor_X = 0;
        Wrap_Safe = section->section_size;
    } else {
        // We assume all other characters will advance one char by default
        R_Chars++;
        Cursor_X++;
    }

    // now we actually add the character to our buffer
    len = trans_add_char_ib( ch, section, alloc_size );

    // adjust the nearest safe break point if the char we got was a space and
    // is not preceded by a space
    if( ch == ' ' && section->section_size > 2 &&
                section->section_text[ section->section_size - 2 ] != ' ' ) {
        Wrap_Safe = section->section_size;
        R_Chars = 0;
    }

    // If a bunch of spaces are pushing us over the edge then we'll rip all
    // of them off except one. Only happens in extreme cases. (ie: wdbg.whp)
    if( Cursor_X >= MY_MARGIN && ch==' ' ) {
        while( section->section_size > 2 &&
                section->section_text[ section->section_size - 2 ] == ' ' ) {
            section->section_size--;
            Cursor_X--;
        }
    }

    // if this assertion fails then the wrapping code will break. Hopefully
    // this cannot happen...
    assert( Cursor_X <= MY_MARGIN );

    // if we need to wrap...
    if( Cursor_X == MY_MARGIN ) {

        // find out how many characters we need to move to next line
        if( R_Chars == MY_MARGIN - indent ) {
            // if the current word won't even fit on the next line then we
            // break it at the margin, so just wrap the current char
            R_Chars = 1;
            wrap_amount = len;
            Wrap_Safe = section->section_size - wrap_amount;
        } else {
            wrap_amount = section->section_size - Wrap_Safe;
        }

        // By this point we know exactly how many chars we need to move to
        // the next line. Now to figure out how to move them:
        // calculate shift
        shift = indent          // for the indent spaces
                + 1;            // for the newline char

        // if we're in box mode we need some extra space for the
        // spaces and box drawing chars
        if ( Box_Mode ) {
            shift += R_Chars                 // trailing spaces to add
                     + 3;                    // 2 vertical bars and 1 space
        } else {
            // remove existing trailing spaces when not in box mode
            delta = 0;
            while( 1 + delta < Wrap_Safe && section->section_text[ Wrap_Safe - 1 - delta ] == ' ' ) {
                delta++;
            }
            shift -= delta;
        }

        // figure out which way the text has to move, and tweak the section
        if( shift > 0 ) {
            // add some padding so we can shift the chars over
            for( ctr = 1; ctr <= shift; ctr++ ) {
                trans_add_char( 'X', section, alloc_size );
            }
        } else {
            // we have to decrease the section size accordingly
            section->section_size += shift;
        }

        // shift the chars over
        memmove( section->section_text + Wrap_Safe + shift, section->section_text + Wrap_Safe, wrap_amount );

        // fill "vacated" region with spaces (if there was one)
        if( shift > 0 ) {
            memset( section->section_text + Wrap_Safe, ' ', shift );
            // if shift is negative then the region we'll be working with
            // should already be filled with spaces.
        }

        // add newline before text we just shifted to break the line
        ctr = Wrap_Safe + shift - indent - 1;
        if( Box_Mode ) {
            // when in box mode we've added two chars for the vertical bar
            // and a leading space. Need to make sure the newline goes
            // before them...
            ctr -= 2;
        }
        *(unsigned char *)(section->section_text + ctr) = '\n';

        // if we're in Box_Mode then we also add the vertical bars
        if( Box_Mode ) {
            *(unsigned char *)(section->section_text + ctr - 1) = BOX_VBAR;
            *(unsigned char *)(section->section_text + Wrap_Safe + shift - 2) = BOX_VBAR;
        }

        // reset cursor x position
        Cursor_X = indent + R_Chars + ( Box_Mode ? 2 : 0 );

        // Set next safe wrappable point to beginning of text on this line
        Wrap_Safe += indent + 1;

        if( wrap_amount==len ) {
            R_Chars = 1;
        }
    }
    return( len );
}
Exemple #6
0
int ipf_trans_line(
/*****************/

    section_def         *section,
    int                 alloc_size
) {
    char                *ptr;
    char                *end;
    int                 ch;
    char                *ctx_name;
    char                *ctx_text;
    char                buf[500];
    int                 font_idx;
    int                 line_len;
    bool                term_fix;
    int                 ch_len;
    int                 len;
    char                *file_name;

    /* check for special column 0 stuff first */
    ptr = Line_buf;
    ch = *(unsigned char *)ptr;
    ch_len = 0;
    line_len = 0;

    switch( ch ) {
    case CH_TABXMP:
        if( *skip_blank( ptr + 1 ) == '\0' ) {
            Tab_xmp = FALSE;
            trans_add_str( ":exmp.\n", section, &alloc_size );
            Blank_line_sfx = FALSE;     // remove following blanks
        } else {
            read_tabs( ptr + 1 );
            trans_add_str( ":xmp.\n", section, &alloc_size );
            Tab_xmp = TRUE;
            Blank_line_pfx = FALSE;     // remove preceding blanks
        }
        return( alloc_size );

    case CH_BOX_ON:
        /* Table support is the closest thing to boxing in IPF, but it
           doesn't work well with changing fonts on items in the tables
           (the edges don't line up). So we draw long lines at the
           top and bottom instead */
        draw_line( section, &alloc_size );
        Blank_line_pfx = FALSE;
        return( alloc_size );

    case CH_BOX_OFF:
        draw_line( section, &alloc_size );
        Blank_line_sfx = FALSE;
        return( alloc_size );

    case CH_OLIST_START:
        trans_add_list( ":ol", section, &alloc_size, ptr );
        Blank_line_pfx = FALSE;
        return( alloc_size );

    case CH_LIST_START:
        trans_add_list( ":ul", section, &alloc_size, ptr );
        Blank_line_pfx = FALSE;
        return( alloc_size );

    case CH_DLIST_START:
        trans_add_str( ":dl break=all tsize=5.\n", section, &alloc_size );
        Blank_line_pfx = FALSE;
        return( alloc_size );

    case CH_SLIST_START:
        trans_add_list( ":sl", section, &alloc_size, ptr );
        Blank_line_pfx = FALSE;
        return( alloc_size );

    case CH_SLIST_END:
        trans_add_str( ":esl.\n", section, &alloc_size );
        Blank_line_sfx = FALSE;
        return( alloc_size );

    case CH_OLIST_END:
        trans_add_str( ":eol.\n", section, &alloc_size );
        Blank_line_sfx = FALSE;
        return( alloc_size );

    case CH_LIST_END:
        trans_add_str( ":eul.\n", section, &alloc_size );
        Blank_line_sfx = FALSE;
        return( alloc_size );

    case CH_DLIST_END:
        trans_add_str( ":edl.\n", section, &alloc_size );
        Blank_line_sfx = FALSE;
        return( alloc_size );

    case CH_LIST_ITEM:
    case CH_DLIST_TERM:
        /* eat blank lines before list items and terms */
        Blank_line_pfx = FALSE;
        break;

    case CH_CTX_KW:
        ptr = whole_keyword_line( ptr );
        if( ptr == NULL ) {
            return( alloc_size );
        }
        break;
    }

    if( *skip_blank( ptr ) == '\0' ) {
        /* ignore blanks lines before the topic starts */
        if( !Curr_ctx->empty ) {
            /* the line is completely blank. This tells us to output
               a blank line. BUT, all lists and things automatically
               generate blank lines before they display, so we
               must pend the line */
            Blank_line_pfx = TRUE;
        }
        return( alloc_size );
    }

    /* An explanation of 'Blank_line_pfx': when we hit a blank line,
       we set Blank_line_pfx to TRUE. On the non-tag next line, the
       blank line is generated.
       Some tags automatically generate a blank line, so they
       turn this flag off. This causes the next non-tag line to NOT
       put out the blank line */

    if( Blank_line_pfx ) {
        if( Blank_line_sfx ) {
            line_len += trans_add_str( ".br\n", section, &alloc_size );
        }
        Blank_line_pfx = FALSE;
    }

    /* An explanation of 'Blank_line_sfx': some ending tags automatically
       generate a blank line, so no blank line after them should get
       generated. Normally, this flag is set to TRUE, but ending
       tags and Defn list term tags set this FALSE, so no extra '.br'
       is generated.
       But, this rule only applies if a blank line immediately
       follows the tag, so its reset here regardless */

    Blank_line_sfx = TRUE;

    ch = *(unsigned char *)ptr;
    if( ch != CH_LIST_ITEM && ch != CH_DLIST_TERM && ch != CH_DLIST_DESC && !Tab_xmp ) {
        /* a .br in front of li and dt would generate extra spaces */
        line_len += trans_add_str( ".br\n", section, &alloc_size );
    }

    term_fix = FALSE;
    for( ;; ) {
        ch = *(unsigned char *)ptr;
        if( ch == '\0' ) {
            if( term_fix ) {
                trans_add_str( ":ehp2.", section, &alloc_size );
                term_fix = FALSE;
            }
            trans_add_char( '\n', section, &alloc_size );
            break;
        } else if( ch == CH_HLINK || ch == CH_DFN ) {
            Curr_ctx->empty = FALSE;
            /* there are no popups in IPF, so treat them as links */
            ctx_name = ptr + 1;
            ptr = strchr( ptr + 1, ch );
            if( ptr == NULL ) {
                error( ERR_BAD_LINK_DFN, TRUE );
            }
            *ptr = '\0';
            ctx_text = ptr + 1;
            ptr = strchr( ctx_text + 1, ch );
            if( ptr == NULL ) {
                error( ERR_BAD_LINK_DFN, TRUE );
            }
            *ptr = '\0';
            add_link( ctx_name );
            sprintf( buf, ":link reftype=hd refid=%s.", ctx_name );
            line_len += trans_add_str( buf, section, &alloc_size );
            line_len += trans_add_str_ipf( ctx_text, section, &alloc_size );
            ch_len += strlen( ctx_text );
            line_len += trans_add_str( ":elink.", section, &alloc_size );
            ++ptr;
        } else if( ch == CH_FLINK ) {
            Curr_ctx->empty = FALSE;
            file_name = strchr( ptr + 1, ch );
            if( file_name == NULL ) {
                error( ERR_BAD_LINK_DFN, TRUE );
            }
            ctx_name = strchr( file_name + 1, ch );
            if( ctx_name == NULL ) {
                error( ERR_BAD_LINK_DFN, TRUE );
            }
            ctx_text = strchr( ctx_name + 1, ch );
            if( ctx_text == NULL ) {
                error( ERR_BAD_LINK_DFN, TRUE );
            }
            *ctx_text = '\0';
            ctx_text = ctx_name + 1;
            *ctx_name = '\0';
            ctx_name = file_name + 1;
            *file_name = '\0';
            file_name = ptr + 1;
            sprintf( buf, ":link reftype=launch object='view.exe' "
                          "data='%s %s'.", file_name, ctx_name );
            line_len += trans_add_str( buf, section, &alloc_size );
            line_len += trans_add_str_ipf( ctx_text, section, &alloc_size );
            ch_len += strlen( ctx_text );
            line_len += trans_add_str( ":elink.", section, &alloc_size );
            ptr = ctx_text + strlen( ctx_text ) + 1;
        } else if( ch == CH_LIST_ITEM ) {
            /* list item */
            line_len += trans_add_str( ":li.", section, &alloc_size );
            ptr = skip_blank( ptr + 1 );
        } else if( ch == CH_DLIST_DESC ) {
            trans_add_str( ":dd.", section, &alloc_size );
            ptr = skip_blank( ptr + 1 );
        } else if( ch == CH_DLIST_TERM ) {
            /* definition list term */
            ptr = skip_blank( ptr + 1 );
            if( *(unsigned char *)ptr == CH_FONTSTYLE_START ) {  /* avoid nesting */
                line_len += trans_add_str( ":dt.", section, &alloc_size );
                Blank_line_sfx = FALSE;
            } else {
                line_len += trans_add_str( ":dt.:hp2.", section, &alloc_size );
                term_fix = TRUE;
                Blank_line_sfx = FALSE;
            }
        } else if( ch == CH_CTX_KW ) {
            end = strchr( ptr + 1, CH_CTX_KW );
            memcpy( buf, ptr + 1, end - ptr - 1 );
            buf[end - ptr - 1] = '\0';
            add_ctx_keyword( Curr_ctx, buf );
            ptr = end + 1;
            if( *ptr == ' ' ) {
                /* kludge fix cuz of GML: GML thinks that keywords are
                   are real words, so it puts a space after them.
                   This should fix that */
                ++ptr;
            }
        } else if( ch == CH_PAR_RESET ) {
            /* this can be ignored for IPF */
            ++ptr;
        } else if( ch == CH_BMP ) {
            Curr_ctx->empty = FALSE;
            ++ptr;
            ch = *(unsigned char *)ptr;
            ptr += 2;
            end = strchr( ptr, CH_BMP );
            *end = '\0';
            switch( ch ) {
            case 'i':
                sprintf( buf, ":artwork runin name='%s'.", ptr );
                break;

            case 'l':
                sprintf( buf, ":artwork align=left name='%s'.", ptr );
                break;

            case 'r':
                sprintf( buf, ":artwork align=right name='%s'.", ptr );
                break;

            case 'c':
                sprintf( buf, ":artwork align=center name='%s'.", ptr );
                break;
            }
            line_len += trans_add_str( buf, section, &alloc_size );
            ptr = end + 1;
        } else if( ch == CH_FONTSTYLE_START ) {
            ++ptr;
            end = strchr( ptr, CH_FONTSTYLE_START );
            font_idx = 0;
            for( ; ptr != end; ++ptr ) {
                switch( *ptr ) {

                case 'b':
                    font_idx |= FONT_STYLE_BOLD;
                    break;

                case 'i':
                    font_idx |= FONT_STYLE_ITALIC;
                    break;

                case 'u':
                case 's':
                    font_idx |= FONT_STYLE_UNDERLINE;
                    break;
                }
            }
            line_len += trans_add_str( Font_match[font_idx],
                                                section, &alloc_size );
            Font_list[Font_list_curr] = font_idx;
            ++Font_list_curr;
            ++ptr;
        } else if( ch == CH_FONTSTYLE_END ) {
            --Font_list_curr;
            line_len += trans_add_str( Font_end[Font_list[Font_list_curr]],
                                                section, &alloc_size );
            ++ptr;
        } else if( ch == CH_FONTTYPE ) {
            ++ptr;
            end = strchr( ptr, CH_FONTTYPE );
            *end = '\0';
            strcpy( buf, ":font facename=" );

            if( Real_ipf_font ) {
                /* This code supports fonts in the expected
                   manor, but not in the usual IPF way. In IPF, font switching
                   (including sizing) is NEVER done, except to Courier for
                   examples. So, this code is inappropriate */

                if( stricmp( ptr, Fonttype_roman ) == 0 ) {
                    strcat( buf, "'Tms Rmn'" );
                } else if( stricmp( ptr, Fonttype_helv ) == 0 ) {
                    strcat( buf, "Helv" );
                } else {
                    /* Symbol doesn't work,so use courier instead */
                    strcat( buf, "Courier" );
                }
                line_len += trans_add_str( buf, section, &alloc_size );
                ptr = end + 1;
                end = strchr( ptr, CH_FONTTYPE );
                *end = '\0';
                sprintf( buf, " size=%dx10.", atoi( ptr ) );
            } else {
                /* this code turns all font changes to the default system
                   font, except for Courier. This is the normal IPF way */

                strcat( buf, "Courier" );
                if( stricmp( ptr, Fonttype_courier ) == 0 ) {
                    strcat( buf, " size=12x10." );
                } else {
                    /* default system font */
                    strcat( buf, " size=0x0." );
                }
                ptr = end + 1;
                end = strchr( ptr, CH_FONTTYPE );
            }

            line_len += trans_add_str( buf, section, &alloc_size );
            ptr = end + 1;
        } else {
            ++ptr;
            Curr_ctx->empty = FALSE;
            if( Tab_xmp && ch == Tab_xmp_char ) {
                len = tab_align( ch_len, section, &alloc_size );
                ch_len += len;
                line_len += len;
                ptr = skip_blank( ptr );
            } else {
                line_len += trans_add_char_ipf( ch, section, &alloc_size );
                ++ch_len;
            }
            if( line_len > 120 && ch == ' ' && !Tab_xmp ) {
                /* break onto the next line */
                line_len = 0;
                trans_add_char( '\n', section, &alloc_size );
            }
        }
    }

    return( alloc_size );
}
Exemple #7
0
int html_trans_line( section_def *section, int alloc_size )
/*********************************************************/
{
    char                *ptr;
    char                *end;
    int                 ch;
    char                *ctx_name;
    char                *ctx_text;
    char                buf[ 500 ];
    int                 font_idx;
    int                 line_len;
    bool                term_fix;
    int                 ch_len;
    int                 len;
    char                *file_name;

    /* check for special column 0 stuff first */
    ptr = Line_buf;
    ch = *(unsigned char *)ptr;
    ch_len = 0;
    line_len = 0;

    switch( ch ) {
    case CH_TABXMP:
        if( *skip_blank( ptr + 1 ) == '\0' ) {
            Tab_xmp = FALSE;
            trans_add_str( "</xmp>\n", section, &alloc_size );
            Blank_line_sfx = FALSE;     // remove following blanks
        } else {
            read_tabs( ptr + 1 );
            trans_add_str( "<xmp>\n", section, &alloc_size );
            Tab_xmp = TRUE;
            Blank_line_pfx = FALSE;     // remove preceding blanks
        }
        return( alloc_size );

    case CH_BOX_ON:
        /* Table support is the closest thing to boxing in IPF, but it
           doesn't work well with changing fonts on items in the tables
           (the edges don't line up). So we draw long lines at the
           top and bottom instead */
        draw_line( section, &alloc_size );
        Blank_line_pfx = FALSE;
        return( alloc_size );

    case CH_BOX_OFF:
        draw_line( section, &alloc_size );
        Blank_line_sfx = FALSE;
        return( alloc_size );

    case CH_OLIST_START:
        trans_add_list( "<OL>\n", section, &alloc_size, ptr );
        Blank_line_pfx = FALSE;
        return( alloc_size );

    case CH_LIST_START:
        trans_add_list( "<UL>\n", section, &alloc_size, ptr );
        Blank_line_pfx = FALSE;
        return( alloc_size );

    case CH_DLIST_START:
        trans_add_str( "<DL>\n", section, &alloc_size );
        Blank_line_pfx = FALSE;
        return( alloc_size );

    case CH_SLIST_START:
        trans_add_list( "<UL>\n", section, &alloc_size, ptr );
        Blank_line_pfx = FALSE;
        return( alloc_size );

    case CH_SLIST_END:
        trans_add_str( "</UL>\n", section, &alloc_size );
        Blank_line_sfx = FALSE;
        return( alloc_size );

    case CH_OLIST_END:
        trans_add_str( "</OL>\n", section, &alloc_size );
        Blank_line_sfx = FALSE;
        return( alloc_size );

    case CH_LIST_END:
        trans_add_str( "</UL>\n", section, &alloc_size );
        Blank_line_sfx = FALSE;
        return( alloc_size );

    case CH_DLIST_END:
        trans_add_str( "</DL>\n", section, &alloc_size );
        Blank_line_sfx = FALSE;
        return( alloc_size );

    case CH_LIST_ITEM:
    case CH_DLIST_TERM:
        /* eat blank lines before list items and terms */
        Blank_line_pfx = FALSE;
        break;

    case CH_CTX_KW:
        ptr = whole_keyword_line( ptr );
        if( ptr == NULL ) {
            return( alloc_size );
        }
        break;
    }

    if( *skip_blank( ptr ) == '\0' ) {
        /* ignore blanks lines before the topic starts */
        if( !Curr_ctx->empty ) {
            /* the line is completely blank. This tells us to output
               a blank line. BUT, all lists and things automatically
               generate blank lines before they display, so we
               must pend the line */
            Blank_line_pfx = TRUE;
        }
        return( alloc_size );
    }

    /* An explanation of 'Blank_line_pfx': when we hit a blank line,
       we set Blank_line_pfx to TRUE. On the non-tag next line, the
       blank line is generated.
       Some tags automatically generate a blank line, so they
       turn this flag off. This causes the next non-tag line to NOT
       put out the blank line */

    if( Blank_line_pfx ) {
        if( Blank_line_sfx ) {
            line_len += trans_add_str( "<BR>", section, &alloc_size );
        }
        Blank_line_pfx = FALSE;
    }

    /* An explanation of 'Blank_line_sfx': some ending tags automatically
       generate a blank line, so no blank line after them should get
       generated. Normally, this flag is set to TRUE, but ending
       tags and Defn list term tags set this FALSE, so no extra '<BR>'
       is generated.
       But, this rule only applies if a blank line immediately
       follows the tag, so its reset here regardless */

    Blank_line_sfx = TRUE;

    ch = *(unsigned char *)ptr;
    if( ch != CH_LIST_ITEM && ch != CH_DLIST_TERM && ch != CH_DLIST_DESC && !Tab_xmp ) {
        /* a .br in front of li and dt would generate extra spaces */
        line_len += trans_add_str( "<BR>", section, &alloc_size );
    }

    term_fix = FALSE;
    for( ;; ) {
        ch = *(unsigned char *)ptr;
        if( ch == '\0' ) {
            if( term_fix ) {
//              trans_add_str( "</hp2>", section, &alloc_size );
                term_fix = FALSE;
            }
            trans_add_char( '\n', section, &alloc_size );
            break;
        } else if( ch == CH_HLINK || ch == CH_DFN ) {
            Curr_ctx->empty = FALSE;
            /* there are no popups in IPF, so treat them as links */
            ctx_name = ptr + 1;
            ptr = strchr( ptr + 1, ch );
            if( ptr == NULL ) {
                error( ERR_BAD_LINK_DFN, TRUE );
            }
            *ptr = '\0';
            ctx_text = ptr + 1;
            ptr = strchr( ctx_text + 1, ch );
            if( ptr == NULL ) {
              error( ERR_BAD_LINK_DFN, TRUE );
            }
            *ptr = '\0';
            add_link( ctx_name );
            sprintf( buf, "<A HREF=\"#%s\">", ctx_name );
            line_len += trans_add_str( buf, section, &alloc_size );
            line_len += trans_add_str_html( ctx_text, section, &alloc_size );
            ch_len += strlen( ctx_text );
            line_len += trans_add_str( "</A>", section, &alloc_size );
            ++ptr;
        } else if( ch == CH_FLINK ) {
            Curr_ctx->empty = FALSE;
            file_name = strchr( ptr + 1, ch );
            if( file_name == NULL ) {
                error( ERR_BAD_LINK_DFN, TRUE );
            }
            ctx_name = strchr( file_name + 1, ch );
            if( ctx_name == NULL ) {
                error( ERR_BAD_LINK_DFN, TRUE );
            }
            ctx_text = strchr( ctx_name + 1, ch );
            if( ctx_text == NULL ) {
                error( ERR_BAD_LINK_DFN, TRUE );
            }
            *ctx_text = '\0';
            ctx_text = ctx_name + 1;
            *ctx_name = '\0';
            ctx_name = file_name + 1;
            *file_name = '\0';
            file_name = ptr + 1;
            sprintf( buf, "<A HREF=\"#%s\">", ctx_name );
            line_len += trans_add_str( buf, section, &alloc_size );
            line_len += trans_add_str_html( ctx_text, section, &alloc_size );
            ch_len += strlen( ctx_text );
            line_len += trans_add_str( "</A>", section, &alloc_size );
            ptr = ctx_text + strlen( ctx_text ) + 1;
        } else if( ch == CH_LIST_ITEM ) {
            /* list item */
            line_len += trans_add_str( "<LI>", section, &alloc_size );
            ptr = skip_blank( ptr + 1 );
        } else if( ch == CH_DLIST_DESC ) {
            trans_add_str( "<DD>", section, &alloc_size );
            ptr = skip_blank( ptr + 1 );
        } else if( ch == CH_DLIST_TERM ) {
            /* definition list term */
            line_len += trans_add_str( "<DT>", section, &alloc_size );
            term_fix = TRUE;
            ptr = skip_blank( ptr + 1 );
            Blank_line_sfx = FALSE;
        } else if( ch == CH_CTX_KW ) {
            end = strchr( ptr + 1, CH_CTX_KW );
            memcpy( buf, ptr + 1, end - ptr - 1 );
            buf[ end - ptr - 1 ] = '\0';
            add_ctx_keyword( Curr_ctx, buf );
            ptr = end + 1;
            if( *ptr == ' ' ) {
                /* kludge fix cuz of GML: GML thinks that keywords are
                   are real words, so it puts a space after them.
                   This should fix that */
                ++ptr;
            }
        } else if( ch == CH_PAR_RESET ) {
            /* this can be ignored for IPF */
            ++ptr;
        } else if( ch == CH_BMP ) {
            Curr_ctx->empty = FALSE;
            ++ptr;
            ch = *(unsigned char *)ptr;
            ptr += 2;
            end = strchr( ptr, CH_BMP );
            *end = '\0';
           // convert filenames to lower case
           strlwr( ptr );
           switch( ch ) {
            case 'i':
                sprintf( buf, "<IMG SRC=\"%s\">", ptr );
                break;

            case 'l':
                sprintf( buf, "<IMG SRC=\"%s\" ALIGN=TOP>", ptr );
                break;

            case 'r':
                sprintf( buf, "<IMG SRC=\"%s\" ALIGN=BOTTOM>", ptr );
                break;

            case 'c':
                sprintf( buf, "<IMG SRC=\"%s\" ALIGN=MIDDLE>", ptr );
                break;
            }
            line_len += trans_add_str( buf, section, &alloc_size );
            ptr = end + 1;
        } else if( ch == CH_FONTSTYLE_START ) {
            ++ptr;
            end = strchr( ptr, CH_FONTSTYLE_START );
            font_idx = 0;
            for( ; ptr != end; ++ptr ) {
                switch( *ptr ) {
                case 'b':
                    font_idx |= FONT_STYLE_BOLD;
                    break;

                case 'i':
                    font_idx |= FONT_STYLE_ITALIC;
                    break;

                case 'u':
                case 's':
                    font_idx |= FONT_STYLE_UNDERLINE;
                    break;
                }
            }
            line_len += trans_add_str( Font_match[ font_idx ], section, &alloc_size );
            Font_list[ Font_list_curr ] = font_idx;
            ++Font_list_curr;
            ++ptr;
        } else if( ch == CH_FONTSTYLE_END ) {
            --Font_list_curr;
            line_len += trans_add_str( Font_end[ Font_list[ Font_list_curr ] ], section, &alloc_size );
            ++ptr;
        } else if( ch == CH_FONTTYPE ) {
            ++ptr;
            end = strchr( ptr, CH_FONTTYPE );
            *end = '\0';

            if( stricmp( ptr, Fonttype_courier ) == 0 ) {
               strcpy( buf, "<TT>" );
            } else {
               /* default system font */
               strcpy( buf, "</TT>" );
            }
            ptr = end + 1;
            end = strchr( ptr, CH_FONTTYPE );
            line_len += trans_add_str( buf, section, &alloc_size );
            ptr = end + 1;
        } else {
            ++ptr;
            Curr_ctx->empty = FALSE;
            if( Tab_xmp && ch == Tab_xmp_char ) {
                len = tab_align( ch_len, section, &alloc_size );
                ch_len += len;
                line_len += len * sizeof( HTML_SPACE );
                ptr = skip_blank( ptr );
            }
            if( line_len > 120 && ch == ' ' && !Tab_xmp ) {
                /* break onto the next line */
                line_len = 0;
                trans_add_char( '\n', section, &alloc_size );
                if( *ptr == ' ' ) {
                    line_len += trans_add_str( HTML_SPACE, section, &alloc_size );
                    ++ch_len;
                    ptr++;
                }
            } else {
                line_len += trans_add_char_html( ch, *(unsigned char *)ptr, section, &alloc_size );
                ++ch_len;
            }
        }
    }

    return( alloc_size );
}