ipf.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 757 行 · 第 1/2 页
C
757 行
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;
if( *ptr != CH_LIST_ITEM && *ptr != CH_DLIST_TERM &&
*ptr != 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 = *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 */
line_len += trans_add_str( ":dt.:hp2.", 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 = *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 );
}
static void output_hdr(
/*********************/
void
) {
whp_fprintf( Out_file, ":userdoc.\n" );
if( Ipf_title != NULL && Ipf_title[0] != '\0' ) {
whp_fprintf( Out_file, ":title.%s\n", Ipf_title );
}
whp_fprintf( Out_file, ":docprof toc=123456.\n" );
}
static void output_ctx_hdr(
/*************************/
ctx_def *ctx
) {
int head_level;
char *ptr;
keyword_def *key;
keylist_def *keylist;
int p_skip;
head_level = ctx->head_level;
if( head_level == 0 ) {
/* OS/2 can't handle heading level 0 */
head_level = 1;
}
head_level -= Curr_head_skip;
if( head_level > Curr_head_level + 1 ) {
/* you can't skip heading levels upwards in IPF. To handle this,
you go up to the next level, and keep track of the
skip for future heading levels. */
p_skip = head_level - Curr_head_level - 1 ;
head_level -= p_skip;
Curr_head_skip += p_skip;
} else if( head_level < Curr_head_level ) {
head_level += Curr_head_skip;
if( head_level > Curr_head_level ) {
/* we moved down levels, but we're still too high! */
Curr_head_skip = head_level - Curr_head_level;
head_level -= Curr_head_skip;
} else {
Curr_head_skip = 0;
}
}
Curr_head_level = head_level;
whp_fprintf( Out_file, "\n:h%d res=%d id=%s.%s\n",
head_level, ctx->ctx_id, ctx->ctx_name,
translate_str_ipf( ctx->title ) );
if( ctx->keylist != NULL ) {
for( keylist = ctx->keylist; keylist != NULL;
keylist = keylist->next ) {
key = keylist->key;
ptr = key->keyword;
if( !key->duplicate ) {
fputs( ":i1.", Out_file );
} else {
if( key->defined_ctx == ctx ) {
/* this is the first instance. :i1 and :i2 */
fprintf( Out_file, ":i1 id=%d.%s\n",
key->id, translate_str_ipf( ptr ) );
}
if( stricmp( ptr, ctx->title ) == 0 ) {
/* we are about to out an index subentry whose
name is the same as the main index entry!
Skip it! */
continue;
}
fprintf( Out_file, ":i2 refid=%d.", key->id );
ptr = ctx->title;
}
fputs( translate_str_ipf( ptr ), Out_file );
fputc( '\n', Out_file );
}
}
if( Real_ipf_font ) {
/* The default font is system, which wouldn't be right */
whp_fprintf( Out_file, ":font facename=Helv size=10x10.\n" );
}
/* browse lists are not used in IPF */
/* nor does 'Up' topicing have any relevance */
}
static void output_end(
/*********************/
void
) {
whp_fprintf( Out_file, "\n:euserdoc.\n" );
}
static void output_ctx_sections(
/******************************/
ctx_def *ctx
) {
section_def *section;
for( section = ctx->section_list; section != NULL; ) {
if( section->section_size > 0 ) {
whp_fwrite( section->section_text, 1,
section->section_size, Out_file );
}
section = section->next;
}
}
void ipf_output_file(
/*******************/
void
) {
ctx_def *ctx;
output_hdr();
for( ctx = Ctx_list; ctx != NULL; ctx = ctx->next ) {
if( !Remove_empty || !ctx->empty || ctx->req_by_link ) {
if( !Exclude_special || !is_special_topic( ctx, FALSE ) ) {
output_ctx_hdr( ctx );
output_ctx_sections( ctx );
}
}
}
output_end();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?