rtf.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 779 行 · 第 1/2 页
C
779 行
/****************************************************************************
*
* 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 RTF specific functions.
*
****************************************************************************/
#include "whpcvt.h"
#define MAX_LISTS 20
enum {
LPREFIX_NONE = 0x0,
LPREFIX_S_LIST = 0x1,
LPREFIX_FIX_FI = 0x2,
LPREFIX_E_LIST = 0x4,
LPREFIX_PAR_RESET = 0x8,
LPREFIX_LEFTALIGN = 0x10,
LPREFIX_BOX_ON = 0x20,
};
static unsigned long Line_prefix=LPREFIX_NONE;
enum {
LPOSTFIX_NONE,
LPOSTFIX_TERM,
};
static int Line_postfix=LPOSTFIX_NONE;
static char Reset_font_str[]="\\plain\\f2\\fs20";
static char Rtf_ctl_prefix[]="{\\footnote \\pard\\plain \\sl240 \\fs20 ";
enum {
LIST_SPACE_COMPACT,
LIST_SPACE_STANDARD,
};
enum {
LIST_TYPE_NONE,
LIST_TYPE_UNORDERED,
LIST_TYPE_ORDERED,
LIST_TYPE_SIMPLE,
LIST_TYPE_DEFN
};
typedef struct {
int type;
int number;
int prev_indent;
int compact;
} list_def;
static list_def Lists[MAX_LISTS]={
{ LIST_TYPE_NONE, 0, 0 }, // list base
};
static int List_level=0;
static list_def *Curr_list=&Lists[0];
static bool Blank_line=FALSE;
static int Curr_indent=0;
static bool Eat_blanks=FALSE;
#define RTF_CHAR_SIZE 180
#define RTF_TRANS_LEN 50
static char *Trans_str=NULL;
static int Trans_len=0;
static void trans_add_tabs(
/*************************/
section_def *section,
int *alloc_size
) {
int tab;
char buf[30];
trans_add_str( "\\pard ", section, alloc_size );
for( tab = 1; tab <= NUM_TAB_STOPS; ++tab ) {
sprintf( buf, "\\tx%d ", INDENT_INC * tab );
trans_add_str( buf, section, alloc_size );
}
sprintf( buf, "\\li%d ", Curr_indent );
trans_add_str( buf, section, alloc_size );
}
static void set_compact(
/**********************/
char *line
) {
++line;
if( *line == 'c' ) {
/* compact list */
Curr_list->compact = LIST_SPACE_COMPACT;
} else {
Curr_list->compact = LIST_SPACE_STANDARD;
}
}
static int translate_char_rtf(
/****************************/
char ch,
char *buf,
int do_quotes
) {
switch( ch ) {
case '}':
strcpy( buf, "\\}" );
break;
case '{':
strcpy( buf, "\\{" );
break;
case '\\':
strcpy( buf, "\\\\" );
break;
case '"':
if( do_quotes ) {
strcpy( buf, "\\\"" );
break;
}
/* fall into default case */
default:
buf[0] = ch;
buf[1] = '\0';
break;
}
return( strlen( buf ) );
}
static char *translate_str_rtf(
/*****************************/
char *str,
int do_quotes
) {
char *t_str;
int len;
char buf[RTF_TRANS_LEN];
char *ptr;
len = 1;
for( t_str = str; *t_str != '\0'; ++t_str ) {
len += translate_char_rtf( *t_str, buf, do_quotes );
}
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_rtf( *t_str, buf, do_quotes );
strcpy( ptr, buf );
ptr += len;
}
*ptr = '\0';
return( Trans_str );
}
static int trans_add_char_rtf(
/****************************/
char ch,
section_def *section,
int *alloc_size
) {
char buf[RTF_TRANS_LEN];
translate_char_rtf( ch, buf, FALSE );
return( trans_add_str( buf, section, alloc_size ) );
}
static void new_list(
/*******************/
int type
) {
++List_level;
if( List_level == MAX_LISTS ) {
error( ERR_MAX_LISTS, TRUE );
}
Curr_list = &Lists[List_level];
Curr_list->type = type;
Curr_list->number = 1;
Curr_list->prev_indent = Curr_indent;
Curr_list->compact = LIST_SPACE_STANDARD;
}
static void pop_list( void )
/**************************/
{
Curr_indent = Curr_list->prev_indent;
--List_level;
Curr_list = &Lists[List_level];
}
static void add_tabxmp(
/*********************/
char *tab_line,
section_def *section,
int *alloc_size
) {
char *ptr;
char buf[50];
int tabcol;
trans_add_str( "\\pard ", section, alloc_size );
Tab_xmp_char = *tab_line;
ptr = strtok( tab_line + 1, " " );
for( tabcol = 0 ; ptr != NULL; ptr = strtok( NULL, " " ) ) {
if( *ptr == '+' ) {
tabcol += atoi( ptr + 1 );
} else {
tabcol = atoi( ptr );
}
sprintf( buf, "\\tx%d ", RTF_CHAR_SIZE * tabcol );
trans_add_str( buf, section, alloc_size );
}
trans_add_char( '\n', section, alloc_size );
}
void rtf_topic_init( void )
/*************************/
{
Line_prefix = LPREFIX_NONE;
}
int rtf_trans_line(
/*****************/
section_def *section,
int alloc_size
) {
char *ptr;
char *end;
char ch;
char *ctx_name;
char *ctx_text;
char buf[100];
int indent;
char *file_name;
/* check for special pre-processing stuff first */
ptr = Line_buf;
ch = *ptr;
if( Blank_line && ( ch != CH_LIST_ITEM ||
Curr_list->compact != LIST_SPACE_COMPACT ) ) {
Blank_line = FALSE;
}
switch( ch ) {
case CH_TABXMP:
if( *skip_blank( ptr + 1 ) == '\0' ) {
Line_prefix |= LPREFIX_PAR_RESET;
Tab_xmp = FALSE;
} else {
add_tabxmp( ptr + 1, section, &alloc_size );
Tab_xmp = TRUE;
}
return( alloc_size );
case CH_BOX_ON:
Line_prefix |= LPREFIX_BOX_ON;
return( alloc_size );
case CH_BOX_OFF:
Line_prefix |= LPREFIX_PAR_RESET;
return( alloc_size );
case CH_OLIST_START:
new_list( LIST_TYPE_ORDERED );
set_compact( ptr );
Line_prefix |= LPREFIX_S_LIST;
Curr_indent += INDENT_INC + Start_inc_ol;
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 );
Line_prefix |= LPREFIX_S_LIST;
Curr_indent += INDENT_INC +
((ch == CH_LIST_START) ? Start_inc_ul : Start_inc_dl);
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_SLIST_START:
indent = Start_inc_sl;
if( indent == 0 && Curr_list->type == LIST_TYPE_SIMPLE ) {
/* nested simple lists, with no pre-indent. Force an
indent */
indent = INDENT_INC;
}
new_list( LIST_TYPE_SIMPLE );
set_compact( ptr );
Curr_indent += indent;
if( indent != 0 ) {
Line_prefix |= LPREFIX_S_LIST;
}
return( alloc_size );
case CH_SLIST_END:
if( Curr_list->prev_indent != Curr_indent ) {
Line_prefix |= LPREFIX_E_LIST;
}
pop_list();
return( alloc_size );
case CH_OLIST_END:
pop_list();
Line_prefix |= LPREFIX_E_LIST;
return( alloc_size );
case CH_LIST_END:
pop_list();
Line_prefix |= LPREFIX_E_LIST;
return( alloc_size );
case CH_DLIST_END:
pop_list();
Line_prefix |= LPREFIX_E_LIST;
return( alloc_size );
case CH_DLIST_DESC:
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;
}
if( *skip_blank( ptr ) == '\0' && Curr_ctx->empty ) {
/* skip preceding blank lines */
return( alloc_size );
}
if( Blank_line ) {
/* remove '\n' on the end */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?