void proc_p_pc( p_lay_tag * p_pc ) { char * p; scan_err = false; p = scan_start; ProcFlags.keep_left_margin = true; // special Note indent start_doc_sect(); // if not already done scr_process_break(); if( nest_cb->c_tag == t_NONE ) { g_cur_left = g_page_left + g_indent;// left start TBD } else { g_cur_left = g_cur_left; } // possibly indent first line g_cur_h_start = g_cur_left + conv_hor_unit( &(p_pc->line_indent) ); g_cur_threshold = layout_work.widow.threshold; // standard threshold if( *p == '.' ) p++; // over '.' set_skip_vars( &(p_pc->pre_skip), NULL, &(p_pc->post_skip), spacing, g_curr_font ); post_space = 0; process_text( p, g_curr_font ); scan_start = scan_stop + 1; return; }
static void gml_xl_lp_common( e_tags t ) { char * p; end_lp(); // terminate :LP if active init_nest_cb(); nest_cb->p_stack = copy_to_nest_stack(); nest_cb->c_tag = t; scan_err = false; p = scan_start; if( *p == '.' ) p++; // possible tag end if( t != t_LP ) { // text only allowed for :LP if( t != t_DL && t != t_GL ) { // DL/GL don't require LI/LP ProcFlags.need_li_lp = true; // :LI or :LP next } start_doc_sect(); // if not already done if( g_line_indent == 0 ) { ProcFlags.para_starting = false; // clear for this tag's first break } scr_process_break(); if( *p ) { process_text( p, g_curr_font ); } } return; }
extern void gml_abstract( const gmltag * entry ) { if( ProcFlags.doc_sect_nxt == doc_sect_egdoc ) { xx_line_err( err_eof_expected, tok_start ); return; } if( !ProcFlags.frontm_seen ) { xx_line_err( err_doc_sec_expected_1, tok_start ); return; } if( blank_lines > 0 ) { set_skip_vars( NULL, NULL, NULL, 0, 0 ); // set g_blank_lines } scr_process_break(); gml_doc_xxx( doc_sect_abstract ); g_cur_left = g_page_left; g_cur_h_start = g_page_left; if( layout_work.hx.hx_sect[hds_abstract].header ) { start_doc_sect(); // a header is enough } g_indent = 0; g_indentr = 0; set_h_start(); }
extern void gml_pb( const gmltag * entry ) { scan_err = false; start_doc_sect(); // if not already done scr_process_break(); scan_start = scan_stop + 1; return; }
void gml_egdoc( gml_tag gtag ) { gtag = gtag; if( g_blank_lines_ln > 0 ) { set_skip_vars( NULL, NULL, NULL, 0, 0 ); // set g_blank_lines } scr_process_break(); // outputs last element in file if( !ProcFlags.start_section ) { start_doc_sect(); // if not already done } gml_doc_xxx( doc_sect_egdoc ); }
extern void gml_pb( gml_tag gtag ) { gtag = gtag; scan_err = false; start_doc_sect(); // if not already done scr_process_break(); scan_start = scan_stop; return; }
extern void gml_pb( gml_tag gtag ) { /* unused parameters */ (void)gtag; scan_err = false; start_doc_sect(); // if not already done scr_process_break(); scan_start = scan_stop; return; }
extern void gml_backm( const gmltag * entry ) { if( !ProcFlags.fb_document_done ) { // the very first section/page do_layout_end_processing(); } if( blank_lines > 0 ) { set_skip_vars( NULL, NULL, NULL, 0, 0 ); // set g_blank_lines } scr_process_break(); gml_doc_xxx( doc_sect_backm ); ProcFlags.frontm_seen = false; // no longer in FRONTM section g_cur_left = g_page_left; g_cur_h_start = g_page_left; if( layout_work.hx.hx_sect[hds_backm].header ) { start_doc_sect(); // a header is enough } g_indent = 0; g_indentr = 0; }
void proc_p_pc( p_lay_tag * p_pc ) { char * p; scan_err = false; p = scan_start; ProcFlags.keep_left_margin = true; // special Note indent start_doc_sect(); // if not already done if( g_line_indent == 0 ) { ProcFlags.para_starting = false; // clear for this tag's break } scr_process_break(); g_line_indent = conv_hor_unit( &(p_pc->line_indent), g_curr_font ); g_cur_left = g_page_left + g_indent + nest_cb->left_indent + nest_cb->align;// left start TBD // possibly indent first line g_cur_h_start = g_cur_left + g_line_indent; g_cur_threshold = layout_work.widow.threshold; // standard threshold if( *p == '.' ) p++; // over '.' set_skip_vars( &(p_pc->pre_skip), NULL, &(p_pc->post_skip), spacing, g_curr_font ); ProcFlags.para_starting = true; // for next break, not this tag's break post_space = 0; if( *p ) { process_text( p, g_curr_font ); } scan_start = scan_stop + 1; return; }
extern void gml_body( const gmltag * entry ) { if( blank_lines > 0 ) { set_skip_vars( NULL, NULL, NULL, 0, 0 ); // set g_blank_lines } scr_process_break(); gml_doc_xxx( doc_sect_body ); ProcFlags.just_override = true; // justify for first line ?? TBD g_cur_left = g_page_left; g_cur_h_start = g_page_left + conv_hor_unit( &layout_work.p.line_indent, g_curr_font ); ProcFlags.frontm_seen = false; // no longer in FRONTM section if( !ProcFlags.fb_document_done ) { // the very first section/page do_layout_end_processing(); } if( layout_work.hx.hx_sect[hds_body].header ) { start_doc_sect(); // a header is enough } g_indent = 0; g_indentr = 0; set_h_start(); }
static void gml_hx_common( gml_tag gtag, int hx_lvl ) { char * p; char * headp; bool idseen; bool stitleseen; int rc; int k; size_t headlen; size_t txtlen; char hnumstr[64]; ref_entry * re; ref_entry * rwk; static char hxstr[4] = ":HX"; static char htextx[8] = "$htextX"; static char headx[7] = "$headX"; gtag = gtag; *(hxstr + 2) = '0' + hx_lvl; htextx[6] = '0' + hx_lvl; hnumx[5] = '0' + hx_lvl; headx[5] = '0' + hx_lvl; switch( hx_lvl ) { case 0: if( !((ProcFlags.doc_sect == doc_sect_body) || (ProcFlags.doc_sect_nxt == doc_sect_body)) ) { g_err( err_tag_wrong_sect, hxstr, ":BODY section" ); err_count++; file_mac_info(); } break; case 1: if( !((ProcFlags.doc_sect >= doc_sect_body) || (ProcFlags.doc_sect_nxt >= doc_sect_body)) ) { g_err( err_tag_wrong_sect, hxstr, ":BODY :APPENDIX :BACKM sections" ); err_count++; file_mac_info(); } break; default: if( !((ProcFlags.doc_sect >= doc_sect_abstract) || (ProcFlags.doc_sect_nxt >= doc_sect_abstract)) ) { g_err( err_tag_wrong_sect, hxstr, ":ABSTRACT section or later" ); err_count++; file_mac_info(); } break; } if( layout_work.hx[hx_lvl].number_form != num_none ) { layout_work.hx[hx_lvl].headn++; } idseen = false; stitleseen = false; p = scan_start; re = NULL; /***********************************************************************/ /* Scan attributes for :Hx */ /* id= */ /* stitle= */ /***********************************************************************/ for( ;; ) { while( *p == ' ' ) { p++; } if( *p == '\0' || *p == '.' ) { break; // tag end found } if( !strnicmp( "stitle=", p, 7 ) ) { p += 6; stitleseen = true; /***************************************************************/ /* Although unsupported scan stitle='xxx' */ /***************************************************************/ g_warn( wng_unsupp_att, "stitle" ); wng_count++; file_mac_info(); p = get_att_value( p ); scan_start = p; if( !ProcFlags.tag_end_found ) { continue; } break; } /*******************************************************************/ /* ID='xxxxxxxx' */ /*******************************************************************/ if( !strnicmp( "id=", p, 3 ) ) { p += 2; p = get_refid_value( p ); if( val_len > 0 ) { idseen = true; // valid id attribute found *(val_start + val_len) = '\0'; if( re == NULL ) { // prepare reference entry re = mem_alloc( sizeof( ref_entry ) ); init_ref_entry( re, val_start, val_len ); } else { fill_id( re, val_start, val_len ); } } scan_start = p; if( !ProcFlags.tag_end_found ) { continue; } break; } /*******************************************************************/ /* no more valid attributes, process remaining input as header text*/ /*******************************************************************/ break; } if( *p == '.' ) { // tag end ? p++; } /************************************************************************/ /* set the global vars $headx, $headnumx, $htextx */ /* perhaps text translated to upper or lower case */ /************************************************************************/ while( *p == ' ' ) { // ignore leading blanks p++; } if( *p ) { // text exists if( layout_work.hx[hx_lvl].cases == case_lower ) { strlwr( p ); } else if( layout_work.hx[hx_lvl].cases == case_upper ) { strupr( p ); } } rc = add_symvar( &global_dict, htextx, p, no_subscript, 0 ); update_headnumx( hx_lvl, hnumstr, sizeof( hnumstr ) ); txtlen = strlen( p ); headlen = strlen( hnumstr) + txtlen + 2; headp = mem_alloc( headlen ); if( layout_work.hx[hx_lvl].number_form != num_none ) { strcpy( headp, hnumstr); // numbered header strcat( headp, " " ); } else { *headp = '\0'; } strcat( headp, p ); rc = add_symvar( &global_dict, headx, headp, no_subscript, 0 ); out_msg( " %s\n", headp ); // always verbose output ? TBD mem_free( headp ); /***********************************************************************/ /* if id specified add it to reference dict */ /***********************************************************************/ if( idseen ) { rwk = find_refid( ref_dict, re->id ); if( !rwk ) { // new entry if( txtlen > 0 ) { // text line not empty re->u.info.text_cap = mem_alloc( txtlen + 1 ); strcpy( re->u.info.text_cap, p ); } add_ref_entry( &ref_dict, re ); re = NULL; // free will be done via dictionary } else { /***************************************************************/ /* test for duplicate id */ /* it is done with comparing line no only, in the hope that */ /* two identical ids are not specified in different files on */ /* the same line no. */ /***************************************************************/ if( re->lineno != rwk->lineno ) { g_err( wng_id_xxx, re->id ); g_info( inf_id_duplicate ); file_mac_info(); err_count++; } if( re->u.info.text_cap != NULL ) { mem_free( re->u.info.text_cap ); } mem_free( re ); } } if( layout_work.hx[hx_lvl].number_reset ) { for( k = hx_lvl + 1; k < 7; k++ ) { layout_work.hx[k].headn = 0;// reset following levels if( layout_work.hx[k].headnsub != NULL ) { *(layout_work.hx[k].headnsub->value) = '\0'; } } } /***********************************************************************/ /* creation of actual heading */ /***********************************************************************/ /***********************************************************************/ /* eject page(s) if specified */ /***********************************************************************/ if( layout_work.hx[hx_lvl].page_eject != ej_no ) { if( ProcFlags.page_started ) { do_page_out(); reset_t_page(); } if( !ProcFlags.start_section ) { start_doc_sect(); } set_headx_banners( hx_lvl ); // set possible banners reset_t_page(); // and adjust page margins if( (layout_work.hx[hx_lvl].page_eject == ej_odd) && (page & 1) ) { do_page_out(); // next page would be even reset_t_page(); } else if( (layout_work.hx[hx_lvl].page_eject == ej_even) && !(page & 1) ) { do_page_out(); // next page would be odd reset_t_page(); } } if( layout_work.hx[hx_lvl].display_heading ) { hx_header( hx_lvl, hnumstr, p ); } scan_start = scan_stop; return; }
void gml_binclude( gml_tag gtag ) { bool depth_found = false; bool file_found = false; bool has_rec_type = false; bool reposition; bool reposition_found = false; char file[FILENAME_MAX]; char rt_buff[MAX_FILE_ATTR]; char * p; doc_element * cur_el; su depth_su; uint32_t depth; size_t len; if( (ProcFlags.doc_sect < doc_sect_gdoc) ) { if( (ProcFlags.doc_sect_nxt < doc_sect_gdoc) ) { xx_tag_err( err_tag_before_gdoc, gml_tagname( gtag ) ); scan_start = scan_stop; return; } } len = 0; file[0] = '\0'; rt_buff[0] = '\0'; p = scan_start; for( ;; ) { while( *p == ' ' ) { // over WS to attribute p++; } if( *p == '\0' ) { // end of line: get new line if( !(input_cbs->fmflags & II_eof) ) { if( get_line( true ) ) { // next line for missing attribute process_line(); if( (*scan_start == SCR_char) || // cw found: end-of-tag (*scan_start == GML_char) ) { // tag found: end-of-tag ProcFlags.tag_end_found = true; break; } else { p = scan_start; // new line is part of current tag continue; } } } } if( !strnicmp( "file", p, 4 ) ) { p += 4; p = get_att_value( p ); if( val_start == NULL ) { break; } file_found = true; len = val_len; if( len >= FILENAME_MAX ) len = FILENAME_MAX - 1; memcpy( file, val_start, len ); file[len] = '\0'; split_attr_file( file, rt_buff, MAX_FILE_ATTR ); if( (rt_buff[0] != '\0') ) { has_rec_type = true; if( rt_buff[0] != 't' ) { xx_warn( wng_rec_type_binclude ); } } if( ProcFlags.tag_end_found ) { break; } } else if( !strnicmp( "depth", p, 5 ) ) { p += 5; p = get_att_value( p ); if( val_start == NULL ) { break; } depth_found = true; if( att_val_to_su( &depth_su, true ) ) { return; } depth = conv_vert_unit( &depth_su, g_spacing_ln ); if( ProcFlags.tag_end_found ) { break; } } else if( !strnicmp( "reposition", p, 10 ) ) { p += 10; p = get_att_value( p ); if( val_start == NULL ) { break; } reposition_found = true; if( !strnicmp( "start", val_start, 5 ) ) { reposition = true; // moving following text down by depth } else if( !strnicmp( "end", val_start, 3 ) ) { reposition = false; // device at proper position after insertion } else { xx_line_err( err_inv_att_val, val_start ); scan_start = scan_stop; return; } if( ProcFlags.tag_end_found ) { break; } } else { // no match = end-of-tag in wgml 4.0 ProcFlags.tag_end_found = true; break; } } // detect missing required attributes if( !depth_found || !file_found || !reposition_found ) { xx_err( err_att_missing ); scan_start = scan_stop; return; } scr_process_break(); // flush existing text start_doc_sect(); // if not already done cur_el = alloc_doc_el( el_binc ); if( reposition && depth ) { cur_el->depth = depth; // otherwise, it will be "0" } if( depth > 0 ) { set_skip_vars( NULL, NULL, NULL, 1, g_curr_font ); cur_el->blank_lines = g_blank_lines; g_blank_lines = 0; cur_el->subs_skip = g_subs_skip; cur_el->top_skip = g_top_skip; } cur_el->element.binc.depth = depth; cur_el->element.binc.cur_left = g_cur_h_start; cur_el->element.binc.has_rec_type = has_rec_type; ProcFlags.skips_valid = false; memcpy( cur_el->element.binc.file, file, len + 1 ); insert_col_main( cur_el ); scan_start = scan_stop; // skip following text }
void gml_docnum( const gmltag * entry ) { char * p; doc_element * cur_el; text_line * p_line; int8_t d_spacing; font_number font_save; int32_t rc; symsub * docnumval; if( !((ProcFlags.doc_sect == doc_sect_titlep) || (ProcFlags.doc_sect_nxt == doc_sect_titlep)) ) { g_err( err_tag_wrong_sect, entry->tagname, ":TITLEP section" ); err_count++; show_include_stack(); } if( ProcFlags.docnum_tag_seen ) { // only one DOCNUM tag allowed xx_line_err( err_2nd_docnum, buff2 ); } ProcFlags.docnum_tag_seen = true; p = scan_start; if( *p && *p == '.' ) p++; // over . to docnum while( *p == ' ' ) { // over WS to attribute p++; } rc = find_symvar( &sys_dict, "$docnum", no_subscript, &docnumval ); if( *p ) { // docnum specified strcpy_s( docnumval->value, 60, p ); } else { *(docnumval->value) = 0; } start_doc_sect(); // if not already done p_line = alloc_text_line(); p_line->line_height = wgml_fonts[layout_work.docnum.font].line_height; prep_docnum_line( p_line, docnumval->value ); d_spacing = layout_work.titlep.spacing; font_save = g_curr_font; g_curr_font = layout_work.docnum.font; /************************************************************/ /* pre_skip is treated as pre_top_skip because it is */ /* always used at the top of the page, despite the docs */ /************************************************************/ set_skip_vars( NULL, &layout_work.docnum.pre_skip, NULL, d_spacing, g_curr_font ); cur_el = alloc_doc_el( el_text ); cur_el->blank_lines = g_blank_lines; g_blank_lines = 0; cur_el->depth = p_line->line_height + g_spacing; cur_el->subs_skip = g_subs_skip; cur_el->top_skip = g_top_skip; cur_el->element.text.overprint = ProcFlags.overprint; ProcFlags.overprint = false; cur_el->element.text.spacing = g_spacing; cur_el->element.text.first = p_line; ProcFlags.skips_valid = false; p_line = NULL; insert_col_main( cur_el ); g_curr_font = font_save; scan_start = scan_stop + 1; }
extern void gml_xmp( const gmltag * entry ) { char * p; entry = entry; start_doc_sect(); scr_process_break(); scan_err = false; p = scan_start; if( *p == '.' ) { /* already at tag end */ } else { p++; while( *p == ' ' ) { p++; } if( !strnicmp( "depth=", p, 6 ) ) { p += 6; /***************************************************************/ /* Although unsupported, scan depth='xxx' */ /***************************************************************/ g_warn( wng_unsupp_att, "depth" ); wng_count++; file_mac_info(); while( *p && *p != '.' ) { // ignore all up to tag end p++; } } } if( ProcFlags.xmp_active ) { // nested :XMP tag not supported g_err_tag_nest( "eXMP" ); scan_start = scan_stop + 1; return; } /******************************************************************/ /* test for XMP within :ADDRESS, :FIG , :FN */ /******************************************************************/ if( ProcFlags.address_active ) { g_err_tag_x_in_y( "XMP", "ADDRESS" ); scan_start = scan_stop + 1; return; } else { if( ProcFlags.fig_active ) { g_err_tag_x_in_y( "XMP", "FIG" ); scan_start = scan_stop + 1; return; } else { if( ProcFlags.fn_active ) { g_err_tag_x_in_y( "XMP", "FN" ); scan_start = scan_stop + 1; return; } } } ProcFlags.xmp_active = true; first_xline = true; font_save = g_curr_font; g_curr_font = layout_work.xmp.font; if( nest_cb->c_tag == t_NONE ) { g_cur_left = g_page_left + conv_hor_unit( &layout_work.xmp.left_indent ); } else { g_cur_left += conv_hor_unit( &layout_work.xmp.left_indent ); } g_cur_h_start = g_cur_left; ProcFlags.keep_left_margin = true; // keep special indent init_nest_cb(); nest_cb->p_stack = copy_to_nest_stack(); nest_cb->c_tag = t_XMP; spacing = layout_work.xmp.spacing; set_skip_vars( NULL, &layout_work.xmp.pre_skip, NULL, spacing, g_curr_font ); ProcFlags.group_elements = true; justify_save = ProcFlags.justify; ProcFlags.justify = ju_off; // TBD if( *p == '.' ) p++; // possible tag end if( *p ) { process_text( p, g_curr_font ); // if text follows } scan_start = scan_stop + 1; return; }
static void scan_gml( void ) { inputcb * cb; char * p; int toklen; int k; char csave; bool processed; gtentry * ge; // GML user tag entry mac_entry * me; // script macro for processing GML tag char linestr[MAX_L_AS_STR]; char tok_upper[TAG_NAME_LENGTH]; cb = input_cbs; p = scan_start + 1; tok_start = scan_start; while( is_id_char( *p ) && p <= scan_stop ) { // search end of TAG p++; } scan_start = p; // store argument start address toklen = p - tok_start - 1; csave = *p; *p = '\0'; if( toklen >= TAG_NAME_LENGTH ) { err_count++; // SC--009 The tagname is too long if( cb->fmflags & II_macro ) { ultoa( cb->s.m->lineno, linestr, 10 ); g_err( err_tag_name, tok_start + 1, linestr, "macro", cb->s.m->mac->name ); } else { ultoa( cb->s.f->lineno, linestr, 10 ); g_err( err_tag_name, tok_start + 1, linestr, "file", cb->s.f->filename ); } if( inc_level > 0 ) { show_include_stack(); } *p = csave; scan_start = tok_start; // process as text return; } if( GlobalFlags.firstpass && cb->fmflags & II_research ) { if( stricmp( tok_start + 1, "cmt" ) ) { // quiet for :cmt. if( cb->fmflags & II_macro ) { printf_research( "L%d %c%s tag found in macro %s(%d)\n\n", inc_level, GML_char, tok_start + 1, cb->s.m->mac->name, cb->s.m->lineno ); } else { printf_research( "L%d %c%s tag found in file %s(%d)\n\n", inc_level, GML_char, tok_start + 1, cb->s.f->filename, cb->s.f->lineno ); } } add_GML_tag_research( tok_start + 1 ); } if( ProcFlags.layout ) { ge = NULL; // no user tags within :LAYOUT } else { ge = find_tag( &tag_dict, tok_start + 1 ); } processed = false; me = NULL; if( ge != NULL ) { // GML user defined Tag found *p = csave; if( ge->tagflags & tag_off ) { // inactive, treat as text scan_start = tok_start; return; } me = find_macro( macro_dict, ge->macname ); if( me == NULL ) { err_count++; // SC--037: The macro 'xxxxxx' for the gml tag 'yyyyy' // is not defined if( cb->fmflags & II_macro ) { ultoa( cb->s.m->lineno, linestr, 10 ); g_err( err_tag_macro, ge->macname, ge->name, linestr, "macro", cb->s.m->mac->name ); } else { ultoa( cb->s.f->lineno, linestr, 10 ); g_err( err_tag_macro, ge->macname, ge->name, linestr, "file", cb->s.f->filename ); } if( inc_level > 0 ) { show_include_stack(); } *p = csave; scan_start = tok_start; // process as text return; } else { /*******************************************************************/ /* The following is to prevent an endless loop */ /* Example from ow documentation: */ /* .gt ZH1 add zh1 */ /* .gt H1 add zh1 */ /* .dm zh1 begin */ /* ... */ /* :H1 <---- overridden gml tag */ /* ... */ /* .dm zh1 end */ /* */ /* we call the predefined :H1 instead */ /*******************************************************************/ if( (cb->fmflags & II_tag) && (cb->s.m->mac == me) ) { me = NULL; } } } if( me != NULL ) { // usertag and coresponding macro ok processed = process_tag( ge, me ); } else { *p ='\0'; for( k = 0; k <= toklen; k++ ) { tok_upper[k] = toupper( *(tok_start + 1 + k) ); } tok_upper[k] = '\0'; if( ProcFlags.layout ) { // different tags within :LAYOUT for( k = 0; k < LAY_TAGMAX; ++k ) { if( toklen == lay_tags[k].taglen ) { if( !strcmp( lay_tags[k].tagname, tok_upper ) ) { *p = csave; lay_ind = -1; // process tag not attribute lay_tags[k].gmlproc( &lay_tags[k] ); processed = true; lay_ind = k; // now process attributes if any if( *scan_start == '.' ) { scan_start++; } break; } } } if( !processed ) { // check for gml only tag in :LAYOUT for( k = 0; k < GML_TAGMAX; ++k ) { if( toklen == gml_tags[k].taglen ) { if( !strcmp( gml_tags[k].tagname, tok_upper ) ) { g_err( err_gml_in_lay, gml_tags[k].tagname ); err_count++; file_mac_info(); processed = true; scan_start = scan_stop + 1; break; } } } } } else { // not within :LAYOUT for( k = 0; k < GML_TAGMAX; ++k ) { if( toklen == gml_tags[k].taglen ) { if( !strcmp( gml_tags[k].tagname, tok_upper ) ) { if( GlobalFlags.firstpass && !strcmp(tok_upper, "LAYOUT" ) && ProcFlags.fb_document_done ) { g_err( err_lay_too_late ); err_count++; file_mac_info(); processed = true; scan_start = scan_stop + 1; break; } *p = csave; if( (rs_loc == 0) && !ProcFlags.need_li_lp ) { // no restrictions: do them all gml_tags[k].gmlproc( &gml_tags[k] ); } else if( ProcFlags.need_li_lp && ((gml_tags[k].taglocs & li_lp_tag) != 0) ) { // tag is LP or LI gml_tags[k].gmlproc( &gml_tags[k] ); } else if( (gml_tags[k].taglocs & rs_loc) != 0 ) { // tag allowed in this restricted location gml_tags[k].gmlproc( &gml_tags[k] ); } else if( (gml_tags[k].tagflags & tag_is_general) != 0 ) { // tag allowed everywhere gml_tags[k].gmlproc( &gml_tags[k] ); } else { start_doc_sect(); // if not already done if( ProcFlags.need_li_lp ) { xx_nest_err( err_no_li_lp ); } else { // rs_loc > 0 g_err_tag_rsloc( rs_loc, tok_start ); } } processed = true; if( *scan_start == '.' ) { scan_start++; } break; } } } if( !processed ) { // check for layout tag in normal text for( k = 0; k < LAY_TAGMAX; ++k ) { if( toklen == lay_tags[k].taglen ) { if( !strcmp( lay_tags[k].tagname, tok_upper ) ) { g_err( err_lay_in_gml, lay_tags[k].tagname ); err_count++; file_mac_info(); processed = true; scan_start = scan_stop + 1; break; } } } } } } if( *p == '\0' ) { *p = csave; } if( !processed ) { // treat as text scan_start = tok_start; } }
void gml_graphic( gml_tag gtag ) { bool depth_found = false; bool file_found = false; char file[FILENAME_MAX]; char rt_buff[MAX_FILE_ATTR]; char * p; char * pa; doc_element * cur_el; su cur_su; uint32_t depth; uint32_t scale = 100; // the initial value of width is only correct for one-column pages. uint32_t width = g_net_page_width; int32_t xoff = 0; int32_t yoff = 0; size_t len; if( (ProcFlags.doc_sect < doc_sect_gdoc) ) { if( (ProcFlags.doc_sect_nxt < doc_sect_gdoc) ) { xx_tag_err( err_tag_before_gdoc, gml_tagname( gtag ) ); scan_start = scan_stop; return; } } len = 0; file[0] = '\0'; rt_buff[0] = '\0'; p = scan_start; for( ;; ) { while( *p == ' ' ) { // over WS to attribute p++; } if( *p == '\0' ) { // end of line: get new line if( !(input_cbs->fmflags & II_eof) ) { if( get_line( true ) ) { // next line for missing attribute process_line(); if( (*scan_start == SCR_char) || // cw found: end-of-tag (*scan_start == GML_char) ) { // tag found: end-of-tag ProcFlags.tag_end_found = true; break; } else { p = scan_start; // new line is part of current tag continue; } } } } if( !strnicmp( "file", p, 4 ) ) { p += 4; p = get_att_value( p ); if( val_start == NULL ) { break; } file_found = true; len = val_len; if( len >= FILENAME_MAX ) len = FILENAME_MAX - 1; memcpy( file, val_start, len ); file[len] = '\0'; split_attr_file( file, rt_buff, sizeof( rt_buff ) ); if( (rt_buff[0] != '\0') ) { xx_warn( wng_rec_type_graphic ); } if( ProcFlags.tag_end_found ) { break; } } else if( !strnicmp( "depth", p, 5 ) ) { p += 5; p = get_att_value( p ); if( val_start == NULL ) { break; } depth_found = true; pa = val_start; if( att_val_to_su( &cur_su, true ) ) { return; } depth = conv_vert_unit( &cur_su, g_spacing_ln ); if( depth == 0 ) { xx_line_err( err_inv_depth_graphic, pa ); scan_start = scan_stop; return; } if( ProcFlags.tag_end_found ) { break; } } else if( !strnicmp( "width", p, 5 ) ) { p += 5; p = get_att_value( p ); if( val_start == NULL ) { break; } if( !strnicmp( "page", val_start, 4 ) ) { // default value is the correct value to use } else if( !strnicmp( "column", val_start, 6 ) ) { // default value is the correct value to use } else { // value actually specifies the width pa = val_start; if( att_val_to_su( &cur_su, true ) ) { return; } width = conv_hor_unit( &cur_su ); if( width == 0 ) { xx_line_err( err_inv_width_graphic, pa ); scan_start = scan_stop; return; } /* there should be a check somewhere for width > page width */ } if( ProcFlags.tag_end_found ) { break; } } else if( !strnicmp( "scale", p, 5 ) ) { p += 5; p = get_att_value( p ); if( val_start == NULL ) { break; } pa = val_start; if( (*pa == '+') || (*pa == '-') ) { // signs not allowed xx_line_err( err_num_too_large, pa ); scan_start = scan_stop; return; } scale = 0; while( (*pa >= '0') && (*pa <= '9') ) { // convert to number scale = (10 * scale) + (*pa - '0'); pa++; if( (pa - val_start) > val_len ) { // value end reached break; } } if( scale > 0x7fffffff ) { // wgml 4.0 limit xx_line_err( err_num_too_large, val_start ); scan_start = scan_stop; return; } if( (pa - val_start) < val_len ) { // value continues on xx_line_err( err_num_too_large, val_start ); scan_start = scan_stop; return; } if( ProcFlags.tag_end_found ) { break; } } else if( !strnicmp( "xoff", p, 4 ) ) { p += 4; p = get_att_value( p ); if( val_start == NULL ) { break; } if( att_val_to_su( &cur_su, false ) ) { return; } xoff = conv_hor_unit( &cur_su ); if( ProcFlags.tag_end_found ) { break; } } else if( !strnicmp( "yoff", p, 4 ) ) { p += 4; p = get_att_value( p ); if( val_start == NULL ) { break; } if( att_val_to_su( &cur_su, false ) ) { return; } yoff = conv_vert_unit( &cur_su, g_spacing_ln ); if( ProcFlags.tag_end_found ) { break; } } else { // no match = end-of-tag in wgml 4.0 ProcFlags.tag_end_found = true; break; } } if( !depth_found || !file_found ) { // detect missing required attributes xx_err( err_att_missing ); scan_start = scan_stop; return; } scr_process_break(); // flush existing text start_doc_sect(); // if not already done cur_el = alloc_doc_el( el_graph ); cur_el->depth = depth; // always used with GRAPHIC if( !ProcFlags.ps_device ) { // character devices ignore SK & post_skip g_skip = 0; g_post_skip = 0; } set_skip_vars( NULL, NULL, NULL, 1, g_curr_font ); cur_el->blank_lines = g_blank_lines; g_blank_lines = 0; cur_el->subs_skip = g_subs_skip; g_subs_skip = 0; cur_el->top_skip = g_top_skip; g_top_skip = 0; cur_el->element.graph.cur_left = g_cur_h_start; cur_el->element.graph.depth = depth; cur_el->element.graph.scale = scale; cur_el->element.graph.width = width; cur_el->element.graph.xoff = xoff; cur_el->element.graph.yoff = yoff; ProcFlags.skips_valid = false; memcpy( cur_el->element.graph.file, file, len + 1 ); insert_col_main( cur_el ); if( *p == '.' ) { p++; } scan_start = p; // process following text }
extern void gml_note( const gmltag * entry ) { char * p; font_number font_save; text_chars * marker; uint32_t spc_cnt; scan_err = false; p = scan_start; start_doc_sect(); // if not already done scr_process_break(); font_save = g_curr_font; g_curr_font = layout_work.note.font; set_skip_vars( &layout_work.note.pre_skip, NULL, &layout_work.note.post_skip, spacing, g_curr_font ); post_space = 0; if( nest_cb->c_tag == t_NONE ) { g_cur_left = g_page_left + conv_hor_unit( &layout_work.note.left_indent, g_curr_font ); } else { g_cur_left += conv_hor_unit( &layout_work.note.left_indent, g_curr_font ); } g_cur_h_start = g_cur_left; ProcFlags.keep_left_margin = true; // keep special Note indent start_line_with_string( layout_work.note.string, layout_work.note.font, false ); /* the value of post_space after start_line_with_string() is wrong for */ /* two reasons: 1) it uses the wrong font; 2) it is at most "1" even if */ /* more than one space appears at the end of the note_string. */ spc_cnt = post_space / wgml_fonts[g_curr_font].spc_width; post_space = spc_cnt * wgml_fonts[font_save].spc_width; if( (t_line != NULL) && (t_line->last != NULL) ) { g_cur_left += t_line->last->width + post_space; } g_cur_h_start = g_cur_left; ju_x_start = g_cur_h_start; spacing = layout_work.note.spacing; g_curr_font = layout_work.defaults.font; set_skip_vars( NULL, NULL, NULL, spacing, g_curr_font ); if( *p == '.' ) p++; // over '.' while( *p == ' ' ) p++; // skip initial space if( *p ) { // if text follows post_space = 0; process_text( p, g_curr_font ); } else if( !ProcFlags.concat && ProcFlags.has_aa_block && (t_line != NULL) && (post_space > 0) ) { /* only create marker if line not empty, */ /* :NOTE note_string is not nullstring and ends in at least 1 space */ marker = alloc_text_chars( NULL, 0, font_save ); marker->x_address = g_cur_h_start; if( t_line->first == NULL ) { t_line->first = marker; t_line->last = t_line->first; } else { marker->prev = t_line->last; t_line->last->next = marker; t_line->last = t_line->last->next; } post_space = 0; } g_curr_font = font_save; scan_start = scan_stop + 1; return; }
void gml_date( gml_tag gtag ) { char * p; doc_element * cur_el; text_line * p_line; spacing_line spacing_ln; font_number font_save; if( !((ProcFlags.doc_sect == doc_sect_titlep) || (ProcFlags.doc_sect_nxt == doc_sect_titlep)) ) { g_err( err_tag_wrong_sect, gml_tagname( gtag ), ":TITLEP section" ); err_count++; show_include_stack(); } if( ProcFlags.date_tag_seen ) { // only one DATE tag allowed xx_line_err( err_2nd_date, buff2 ); } ProcFlags.date_tag_seen = true; p = scan_start; if( *p && *p == '.' ) p++; // over . to docnum while( *p == ' ' ) { // over WS to attribute p++; } if( *p ) { // date specified add_symvar( &global_dict, "date", p, no_subscript, 0 ); } start_doc_sect(); // if not already done p_line = alloc_text_line(); p_line->line_height = wgml_fonts[layout_work.docnum.font].line_height; prep_date_line( p_line, p ); spacing_ln = layout_work.titlep.spacing; font_save = g_curr_font; g_curr_font = layout_work.date.font; /************************************************************/ /* pre_skip is treated as pre_top_skip because it is */ /* always used at the top of the page, despite the docs */ /************************************************************/ set_skip_vars( NULL, &layout_work.date.pre_skip, NULL, spacing_ln, g_curr_font ); cur_el = alloc_doc_el( el_text ); cur_el->depth = p_line->line_height + g_spacing; cur_el->subs_skip = g_subs_skip; cur_el->top_skip = g_top_skip; cur_el->element.text.overprint = ProcFlags.overprint; ProcFlags.overprint = false; cur_el->element.text.spacing = g_spacing; cur_el->element.text.first = p_line; ProcFlags.skips_valid = false; p_line = NULL; insert_col_main( cur_el ); g_curr_font = font_save; scan_start = scan_stop; }
static void scan_script( void ) { inputcb * cb; mac_entry * me; char * p; char * pt; int toklen; int k; bool cwfound; cb = input_cbs; p = scan_start + 1; scan_restart = scan_start; if( (*p == '*') || !strnicmp( p, "cm ", 3 ) ) { scan_start = scan_stop + 1; // .cm +++ ignore comment up to EOL return; // .* +++ ignore comment up to EOL } if( *p == SCR_char && *(p+1) == SCR_char ) { pt = token_buf; *pt++ = SCR_char; // special for ...label *pt++ = SCR_char; *pt = '\0'; me = NULL; scan_start = p + 2; toklen = 2; } else { if( *p == '\'' ) { // .' p++; ProcFlags.CW_sep_ignore = 1; } else { if( CW_sep_char == '\0') { ProcFlags.CW_sep_ignore = 1;// No separator char no split } else{ ProcFlags.CW_sep_ignore = 0; } if( *p == SCR_char ) { // .. p++; ProcFlags.macro_ignore = 1; me = NULL; } else { ProcFlags.macro_ignore = 0; } } if( ProcFlags.literal ) { // no macro or split line if literal ProcFlags.CW_sep_ignore = 1; ProcFlags.macro_ignore = 1; } if( !ProcFlags.CW_sep_ignore ) { // scan line for CW_sep_char char * pchar; pchar = search_separator( buff2, CW_sep_char ); if( pchar != NULL ) { if( *(pchar + 1) != '\0' ) { // only split if more follows split_input( buff2, pchar + 1, false );// ignore CW_sep_char } *pchar= '\0'; // delete CW_sep_char buff2_lg = strlen( buff2 ); // new length of first part } } scan_start = p; pt = token_buf; while( *p && is_macro_char( *p ) ) { // end of controlword *pt++ = tolower( *p++ ); // copy lowercase to TokenBuf } *pt = '\0'; toklen = pt - token_buf; if( *p && (*p != ' ') || toklen == 0 ) {// no valid script controlword / macro // if( !ProcFlags.literal ) { // TBD // cw_err(); // } scan_start = scan_restart; // treat as text return; } if( toklen >= MAC_NAME_LENGTH ) { *(token_buf + MAC_NAME_LENGTH) = '\0'; } if( !ProcFlags.macro_ignore ) { me = find_macro( macro_dict, token_buf ); } else { me = NULL; } } if( me != NULL ) { // macro found if( GlobalFlags.firstpass && cb->fmflags & II_research ) { if( cb->fmflags & II_macro ) { printf_research( "L%d %c%s macro found in macro %s(%d)\n\n", inc_level, SCR_char, token_buf, cb->s.m->mac->name, cb->s.m->lineno ); } else { printf_research( "L%d %c%s macro found in file %s(%d)\n\n", inc_level, SCR_char, token_buf, cb->s.f->filename, cb->s.f->lineno ); } add_SCR_tag_research( token_buf ); } add_macro_cb_entry( me, NULL ); inc_inc_level(); add_macro_parms( p ); scan_restart = scan_stop + 1; } else { // try script controlword cwfound = false; if( cb->fmflags & II_research && GlobalFlags.firstpass ) { if( cb->fmflags & II_macro ) { printf_research( "L%d %c%s CW found in macro %s(%d)\n\n", inc_level, SCR_char, token_buf, cb->s.m->mac->name, cb->s.m->lineno ); } else { printf_research( "L%d %c%s CW found in file %s(%d)\n\n", inc_level, SCR_char, token_buf, cb->s.f->filename, cb->s.f->lineno ); } add_SCR_tag_research( token_buf ); } if( toklen == SCR_KW_LENGTH ) { for( k = 0; k < SCR_TAGMAX; ++k ) { if( !strcmp( scr_tags[k].tagname, token_buf ) ) { #if 0 if( !ProcFlags.fb_document_done && scr_tags[k].cwflags & cw_o_t ) { /***************************************************/ /* if this is the first cw which produces output */ /* set page geometry and margins from layout */ /***************************************************/ do_layout_end_processing(); } #endif if( !ProcFlags.layout && (scr_tags[k].cwflags & cw_o_t) ) { /********************************************************/ /* this is the first control word which produces output */ /* start the document, the layout is done */ /* start_doc_sect() calls do_layout_end_processing() */ /********************************************************/ start_doc_sect(); } if( ProcFlags.literal ) { // .li active if( !strcmp( token_buf, "li" ) ) { // .li scan_start = p; // found, process scr_tags[k].tagproc(); } } else { scan_start = p; // script controlword found, process if( scr_tags[k].cwflags & cw_break ) { scr_process_break();// output incomplete line, if any } scr_tags[k].tagproc(); } cwfound = true; break; } } } if( !cwfound ) { cw_err(); // unrecognized control word } } scan_start = scan_restart; }
void scan_line( void ) { condcode cc; ifcb * cb; cb = input_cbs->if_cb; scan_start = buff2; scan_stop = buff2 + buff2_lg; if( !ProcFlags.literal ) { set_if_then_do( cb ); cc = test_process( cb ); } else { if( !ProcFlags.ct ) { // special for .ct .li construct if( (t_line != NULL) && (t_line->first != NULL) ) { scr_process_break(); } } cc = pos; } if( cc == pos ) { // process record if( ProcFlags.scr_cw ) { scan_script(); // script control line } else if( ProcFlags.gml_tag ) { scan_gml(); // GML tags } /*******************************************************************/ /* here we arrive if no script keyword / GML tag recognized */ /* or for unprocessed text in the input record */ /* or for attributes of LAYOUT tags */ /*******************************************************************/ if( (*scan_start != '\0') && (scan_start <= scan_stop) ) { if( input_cbs->fmflags & II_research && GlobalFlags.firstpass ) { g_info_lm( inf_text_line, scan_start ); } if( ProcFlags.layout ) { // LAYOUT active: process attributes lay_tags[lay_ind].gmlproc( &lay_tags[lay_ind] ); } else { // processs (remaining) text if( rs_loc > 0 ) { start_doc_sect(); // if not already done g_err_tag_rsloc( rs_loc, scan_start ); } else { process_text( scan_start, g_curr_font ); } } } /*******************************************************************/ /* For .co off or :xmp and the last part of the line just processed*/ /* ensure the line is output */ /*******************************************************************/ if( !ProcFlags.layout && (input_cbs->fmflags & II_eol) ) { if( !ProcFlags.concat || ProcFlags.xmp_active ) { scr_process_break(); } } } else if( input_cbs->fmflags & II_research && GlobalFlags.firstpass ) { g_info_lm( inf_skip_line ); // show skipped line } if( ProcFlags.literal ) { if( li_cnt < LONG_MAX ) { // we decrement, do not wait for .li OFF if( li_cnt-- <= 0 ) { ProcFlags.literal = false; } } if( input_cbs->fmflags & II_eol ) { scr_process_break(); // ensure the line is output } } }
void gml_title( const gmltag * entry ) { char * p; doc_element * cur_el; text_line * p_line = NULL; int8_t t_spacing; font_number font_save; if( !((ProcFlags.doc_sect == doc_sect_titlep) || (ProcFlags.doc_sect_nxt == doc_sect_titlep)) ) { g_err( err_tag_wrong_sect, entry->tagname, ":TITLEP section" ); err_count++; show_include_stack(); } p = scan_start; if( *p && *p != '.' ) p++; while( *p == ' ' ) { // over WS to attribute p++; } if( *p && ! (strnicmp( "stitle ", p, 7 ) && // look for stitle strnicmp( "stitle=", p, 7 )) ) { char quote; char * valstart; p += 6; while( *p == ' ' ) { p++; } if( *p == '=' ) { p++; while( *p == ' ' ) { p++; } } if( *p == '"' || *p == '\'' ) { quote = *p; ++p; } else { quote = ' '; } valstart = p; while( *p && *p != quote ) { ++p; } *p = '\0'; if( !ProcFlags.stitle_seen ) { // first stitle goes into dictionary add_symvar( &global_dict, "$stitle", valstart, no_subscript, 0 ); ProcFlags.stitle_seen = true; } p++; } if( *p == '.' ) p++; // over '.' if( !ProcFlags.title_text_seen ) { if( *p ) { // first title goes into dictionary add_symvar( &global_dict, "$title", p, no_subscript, 0 ); } } start_doc_sect(); // if not already done font_save = g_curr_font; g_curr_font = layout_work.title.font; t_spacing = layout_work.titlep.spacing; if( !ProcFlags.title_tag_top ) { set_skip_vars( NULL, &layout_work.title.pre_top_skip, NULL, t_spacing, g_curr_font ); ProcFlags.title_tag_top = true; } else { set_skip_vars( &layout_work.title.skip, NULL, NULL, t_spacing, g_curr_font ); } p_line = alloc_text_line(); p_line->line_height = wgml_fonts[g_curr_font].line_height; if( *p ) { prep_title_line( p_line, p ); } cur_el = init_doc_el( el_text, p_line->line_height ); cur_el->element.text.first = p_line; p_line = NULL; insert_col_main( cur_el ); g_curr_font = font_save; scan_start = scan_stop + 1; }
static void gen_index( void ) { char buffer[11]; char letter[2]; ix_h_blk * ixh1; ix_h_blk * ixh2; ix_h_blk * ixh3; symsub * ixrefval; // &sysixref value if( index_dict == NULL ) return; // no index_dict, no INDEX scr_process_break(); // flush any pending text start_doc_sect(); letter[0] = 0; letter[1] = 0; ixh1 = index_dict; find_symvar( &sys_dict, "$ixref", no_subscript, &ixrefval); while( ixh1 != NULL ) { // level 1 if( letter[0] != toupper( *(ixh1->ix_term) ) ) { letter[0] = toupper( *(ixh1->ix_term) ); process_text( letter, g_curr_font ); scr_process_break(); // flush letter heading } if( ixh1->prt_term == NULL ) { process_text( ixh1->ix_term, g_curr_font ); } else { process_text( ixh1->prt_term, g_curr_font ); } if( ixh1->entry->entry_typ >= pgstring ) { // 'pageno' is text process_text( ixh1->entry->page_text, g_curr_font ); } else { // 'pageno' is numeric ultoa( ixh1->entry->page_no, &buffer, 10 ); process_text( buffer, g_curr_font ); } ixh2 = ixh1->lower; while( ixh2 != NULL ) { // level 2 if( ixh2->prt_term == NULL ) { process_text( ixh2->ix_term, g_curr_font ); } else { process_text( ixh2->prt_term, g_curr_font ); } if( ixh2->entry->entry_typ >= pgstring ) { // 'pageno' is text process_text( ixh2->entry->page_text, g_curr_font ); } else { // 'pageno' is numeric ultoa( ixh2->entry->page_no, &buffer, 10 ); process_text( buffer, g_curr_font ); } ixh3 = ixh2->lower; while( ixh3 != NULL ) { // level 3 if( ixh3->prt_term == NULL ) { process_text( ixh3->ix_term, g_curr_font ); } else { process_text( ixh3->prt_term, g_curr_font ); } if( ixh3->entry->entry_typ >= pgstring ) { // 'pageno' is text process_text( ixh3->entry->page_text, g_curr_font ); } else { // 'pageno' is numeric ultoa( ixh3->entry->page_no, &buffer, 10 ); process_text( buffer, g_curr_font ); } if( ixh3->lower != NULL ) {// this is error TBD ix_h_blk * ixhp = ixh3->lower; process_text( "lower 3 nn\n", g_curr_font ); while( ixhp != NULL ) { // level 4 if( ixhp->prt_term == NULL ) { process_text( ixhp->ix_term, g_curr_font ); } else { process_text( ixhp->prt_term, g_curr_font ); } if( ixhp->entry->entry_typ >= pgstring ) { // 'pageno' is text process_text( ixhp->entry->page_text, g_curr_font ); } else { // 'pageno' is numeric ultoa( ixhp->entry->page_no, &buffer, 10 ); process_text( buffer, g_curr_font ); } ixhp = ixhp->next; } } ixh3 = ixh3->next; } ixh2 = ixh2->next; } ixh1 = ixh1->next; } }