ipf.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 757 行 · 第 1/2 页
C
757 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: This file defines the IPF specific functions.
*
****************************************************************************/
#include "whpcvt.h"
static int Curr_head_level = 0;
static int Curr_head_skip = 0;
#define BOX_LINE_SIZE 200
#define FONT_STYLE_BOLD 1
#define FONT_STYLE_ITALIC 2
#define FONT_STYLE_UNDERLINE 4
static char *Font_match[]={
":hp1.:ehp1", // 0: PLAIN
":hp2.", // 1: BOLD
":hp1.", // 2: ITALIC
":hp3.", // 3: BOLD + ITALIC
":hp5.", // 4: UNDERLINE
":hp7.", // 5: BOLD + UNDERLINE
":hp6.", // 6: ITALIC + UNDERLINE
":hp7.", // 7: BOLD + ITALIC + UNDERLINE (can't do it)
};
static char *Font_end[]={
"", // 0: PLAIN
":ehp2.", // 1: BOLD
":ehp1.", // 2: ITALIC
":ehp3.", // 3: BOLD + ITALIC
":ehp5.", // 4: UNDERLINE
":ehp7.", // 5: BOLD + UNDERLINE
":ehp6.", // 6: ITALIC + UNDERLINE
":ehp7.", // 7: BOLD + ITALIC + UNDERLINE (can't do it)
};
static int Font_list[100]; // up to 100 nested fonts
static int Font_list_curr= 0;
static bool Blank_line_pfx=FALSE;
static bool Blank_line_sfx=TRUE;
#define IPF_TRANS_LEN 50
static char *Trans_str=NULL;
static int Trans_len=0;
#define MAX_TABS 100 // up to 100 tab stops
static int Tab_list[MAX_TABS];
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 );
}
static int translate_char_ipf(
/****************************/
char ch,
char *buf
) {
switch( ch ) {
case ':':
strcpy( buf, "&colon." );
break;
case '=':
strcpy( buf, "&eq." );
break;
case '&':
strcpy( buf, "&." );
break;
case '.':
strcpy( buf, "&per." );
break;
default:
buf[0] = ch;
buf[1] = '\0';
break;
}
return( strlen( buf ) );
}
static char *translate_str_ipf(
/*****************************/
char *str
) {
char *t_str;
int len;
char buf[IPF_TRANS_LEN];
char *ptr;
len = 1;
for( t_str = str; *t_str != '\0'; ++t_str ) {
len += translate_char_ipf( *t_str, buf );
}
if( len > Trans_len ) {
if( Trans_str != NULL ) {
_free( Trans_str );
}
_new( Trans_str, len );
Trans_len = len;
}
ptr = Trans_str;
for( t_str = str; *t_str != '\0'; ++t_str ) {
len = translate_char_ipf( *t_str, buf );
strcpy( ptr, buf );
ptr += len;
}
*ptr = '\0';
return( Trans_str );
}
static int trans_add_char_ipf(
/****************************/
char ch,
section_def *section,
int *alloc_size
) {
char buf[IPF_TRANS_LEN];
translate_char_ipf( ch, buf );
return( trans_add_str( buf, section, alloc_size ) );
}
static int trans_add_str_ipf(
/***************************/
char *str,
section_def *section,
int *alloc_size
) {
int len;
len = 0;
for( ; *str != '\0'; ++str ) {
len += trans_add_char_ipf( *str, section, alloc_size );
}
return( len );
}
static int trans_add_list(
/************************/
char *list,
section_def *section,
int *alloc_size,
char *ptr
) {
int len;
len = trans_add_str( list, section, alloc_size );
++ptr;
if( *ptr == 'c' ) {
len += trans_add_str( " compact", section, alloc_size );
}
len += trans_add_str( ".\n", section, alloc_size );
return( len );
}
static void read_tabs(
/********************/
char *tab_line
) {
char *ptr;
int i;
int tabcol;
Tab_xmp_char = *tab_line;
ptr = strtok( tab_line + 1, " " );
for( tabcol = 0, i = 0 ; ptr != NULL; ptr = strtok( NULL, " " ), ++i ) {
if( *ptr == '+' ) {
tabcol += atoi( ptr + 1 );
} else {
tabcol = atoi( ptr );
}
Tab_list[i] = tabcol;
}
Tab_list[i] = -1;
}
static int tab_align(
/*******************/
int ch_len,
section_def *section,
int *alloc_size
) {
int i;
int len;
// find the tab we should use
i = 0;
while( ch_len >= Tab_list[i]) {
if( Tab_list[i] == -1 ) break;
++i;
}
len = 1;
if( Tab_list[i] != -1 ) {
len = Tab_list[i] - ch_len;
}
for( i = len; i > 0; --i ) {
trans_add_char_ipf( ' ', section, alloc_size );
}
return( len );
}
void ipf_topic_init(
/******************/
void
) {
}
int ipf_trans_line(
/*****************/
section_def *section,
int alloc_size
) {
char *ptr;
char *end;
char 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 = *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
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?