static void gml_hp_sf_common( const gmltag * entry, int level, e_tags t ) { char * p; entry = entry; init_nest_cb(); nest_cb->p_stack = copy_to_nest_stack(); if( level >= wgml_font_cnt ) { // invalid font use default level = 0; } nest_cb->font = level; g_curr_font = level; nest_cb->c_tag = t; scan_err = false; p = scan_start; if( *p == '.' ) p++; // over '.' if( *p ) { process_text( p, g_curr_font ); } if( !ProcFlags.concat && (input_cbs->fmflags & II_eol) ) { scr_process_break(); // ensure line is output } 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; }
static void gml_hp_sf_common( gml_tag gtag, int level ) { char * p; /* unused parameters */ (void)gtag; // keep any existing post_space, even if CT follows -- TBD if( (input_cbs->fmflags & II_sol) ) { ProcFlags.fsp = true; if( post_space == 0 ) { post_space = wgml_fonts[g_curr_font].spc_width; // TBD } } init_nest_cb( true ); if( level >= wgml_font_cnt ) { // invalid font use default level = 0; } nest_cb->font = level; g_curr_font = level; nest_cb->gtag = gtag; scan_err = false; p = scan_start; if( *p == '.' ) p++; // over '.' if( *p ) { process_text( p, g_curr_font ); } if( !ProcFlags.concat && (input_cbs->fmflags & II_eol) ) { scr_process_break(); // ensure line is output } scan_start = scan_stop; return; }
void start_doc_sect( void ) { bool first_section; bool header; bool page_r; doc_section ds; font_number font; spacing_line spacing_ln; page_ej page_e; su *p_sk; su *top_sk; uint32_t ind; xx_str *h_string; if( ProcFlags.start_section ) { return; // once is enough } if( !ProcFlags.fb_document_done ) { // the very first section/page do_layout_end_processing(); } first_section = (ProcFlags.doc_sect == doc_sect_none); header = false; // no header string (ABSTRACT, ... ) output page_r = false; // no page number reset page_e = ej_no; // no page eject ProcFlags.start_section = true; ProcFlags.keep_left_margin = false; ds = ProcFlags.doc_sect_nxt; // new section if( ds == doc_sect_none ) { ds = doc_sect_body; // if text without section start assume body } /***********************************************************************/ /* process special section attributes */ /***********************************************************************/ switch( ds ) { case doc_sect_body: page_r = layout_work.body.page_reset; page_e = layout_work.body.page_eject; if( layout_work.body.header ) { header = true; h_string = layout_work.body.string; top_sk = &layout_work.body.pre_top_skip; p_sk = &layout_work.body.post_skip; font = layout_work.body.font; spacing_ln = g_spacing_ln; // standard spacing } break; case doc_sect_titlep: // for preceding :BINCLUDE/:GRAPHIC page_e = ej_yes; init_nest_cb( true ); nest_cb->gtag = t_TITLEP; nest_cb->p_stack->lineno = titlep_lineno; // correct line number break; case doc_sect_abstract: page_r = layout_work.abstract.page_reset; page_e = layout_work.abstract.page_eject; if( layout_work.abstract.header ) { header = true; h_string = layout_work.abstract.string; top_sk = &layout_work.abstract.pre_top_skip; p_sk = &layout_work.abstract.post_skip; font = layout_work.abstract.font; spacing_ln = layout_work.abstract.spacing; } break; case doc_sect_preface: page_r = layout_work.preface.page_reset; page_e = layout_work.preface.page_eject; if( layout_work.preface.header ) { header = true; h_string = layout_work.preface.string; top_sk = &layout_work.preface.pre_top_skip; p_sk = &layout_work.preface.post_skip; font = layout_work.preface.font; spacing_ln = layout_work.preface.spacing; } break; case doc_sect_appendix: page_r = layout_work.appendix.page_reset; page_e = layout_work.appendix.page_eject; if( layout_work.appendix.header ) { header = true; h_string = layout_work.appendix.string; top_sk = &layout_work.appendix.pre_top_skip; p_sk = &layout_work.appendix.post_skip; font = layout_work.appendix.font; spacing_ln = layout_work.appendix.spacing; } break; case doc_sect_backm: page_r = layout_work.backm.page_reset; page_e = layout_work.backm.page_eject; if( layout_work.backm.header ) { header = true; h_string = layout_work.backm.string; top_sk = &layout_work.backm.pre_top_skip; p_sk = &layout_work.backm.post_skip; font = layout_work.backm.font; spacing_ln = g_spacing_ln; // standard spacing } break; case doc_sect_index: page_r = layout_work.index.page_reset; page_e = layout_work.index.page_eject; if( layout_work.index.header ) { header = true; h_string = layout_work.index.index_string; top_sk = &layout_work.index.pre_top_skip; p_sk = &layout_work.index.post_skip; font = layout_work.index.font; spacing_ln = layout_work.index.spacing; } break; default: new_section( ds ); break; } if( first_section ) { // nothing precedes the first section if( page_e == ej_even ) { do_page_out(); // apage of first page is odd page = 0; // restart page for first text page } new_section( ds ); reset_t_page(); document_new_position(); // first text page ready for content } else { full_page_out(); // ensure are on last page switch( page_e ) { // page eject requested case ej_yes : finish_page_section( ds, true );// emit last page in old section if( page_r ) { page = 0; } reset_t_page(); break; case ej_odd : if( !(apage & 1) ) { // first page would be even do_page_out(); // emit last page in old section reset_t_page(); } finish_page_section( ds, true );// emit last page in old section if( page_r ) { page = 0; } reset_t_page(); break; case ej_even : if( (apage & 1) ) { // first page will be odd do_page_out(); // emit last page in old section reset_t_page(); } finish_page_section( ds, true );// emit last page in old section if( page_r ) { page = 0; } reset_t_page(); break; default: // ej_no new_section( ds ); /****************************************************/ /* set page bottom banner/limit for new section */ /****************************************************/ ind = !(page & 1); t_page.bottom_banner = sect_ban_bot[ind]; if( sect_ban_bot[ind] != NULL ) { if( bin_driver->y_positive == 0 ) { g_page_bottom = g_page_bottom_org + sect_ban_bot[ind]->ban_depth; } else { g_page_bottom = g_page_bottom_org - sect_ban_bot[ind]->ban_depth; } } else { g_page_bottom = g_page_bottom_org; } break; } } g_cur_left = g_page_left_org; g_cur_h_start = g_page_left_org + g_indent; if( header ) { doc_header( p_sk, top_sk, h_string, font, spacing_ln, page_e == ej_no ); } ProcFlags.doc_sect = ds; }
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; }
void init_page_geometry( void ) { int k; uint32_t page_depth_org; uint32_t net_top_margin; uint32_t net_y_start; uint32_t rm_test; uint32_t top_margin; uint32_t y_start_correction; #if 0 // activate for multi column TBD uint32_t offset; #endif g_resh = bin_device->horizontal_base_units; // hor resolution &sysresh g_resv = bin_device->vertical_base_units; // vert resolution &sysresv spacing = layout_work.defaults.spacing; g_cur_threshold = layout_work.widow.threshold; g_max_char_width = 0; g_max_line_height = 0; for( k = 0; k < wgml_font_cnt; k++ ) { if( g_max_char_width < wgml_fonts[k].default_width ) g_max_char_width = wgml_fonts[k].default_width; if( g_max_line_height < wgml_fonts[k].line_height ) g_max_line_height = wgml_fonts[k].line_height; } g_curr_font = layout_work.defaults.font; lm = conv_hor_unit( &layout_work.page.left_margin ) - bin_device->x_offset; // left margin &syspagelm if( lm < 0 ) { // wgml 4.0 limits value lm = 0; } rm = conv_hor_unit( &layout_work.page.right_margin ) - bin_device->x_offset; // right margin &syspagerm rm_test = bin_device->horizontal_base_units / 4; if( (bin_device->horizontal_base_units % 4) > 0 ) { rm_test++; // round up if any remainder } if( rm < rm_test ) { // wgml 4.0 limits value xx_err( err_right_margin_2_small ); // candidate Severe Error g_suicide(); // no recovery possible } g_page_left_org = lm + bin_device->x_start; if( g_page_left_org < bin_device->x_start ) g_page_left_org = bin_device->x_start; g_page_left = g_page_left_org; g_cur_left = g_page_left; // set initial value g_page_right_org = rm + bin_device->x_start; if( g_page_right_org > bin_device->page_width ) g_page_right_org = bin_device->page_width; g_page_right = g_page_right_org; if( g_page_right > bin_device->page_width ) {// output must appear on page xx_err( err_margins_inverted ); // candidate Severe Error g_suicide(); // no recovery possible } if( g_page_left >= g_page_right ) { // margins cannot be inverted xx_err( err_margins_inverted ); // candidate Severe Error g_suicide(); // no recovery possible } g_net_page_width = rm - lm; g_ll = g_net_page_width * CPI / bin_device->horizontal_base_units; // &sysll top_margin = conv_vert_unit( &layout_work.page.top_margin, 1 ); page_depth_org = conv_vert_unit( &layout_work.page.depth, 1 ); if( bin_device->y_offset > page_depth_org ) { xx_err( err_page_depth_too_small ); // candidate Severe Error g_suicide(); // no recovery possible } else { g_page_depth = page_depth_org - bin_device->y_offset; // &syspaged } if( bin_device->y_offset < top_margin ) { net_top_margin = top_margin - bin_device->y_offset; } else { net_top_margin = 0; } if( bin_driver->y_positive == 0 ) { g_page_top = bin_device->y_start - net_top_margin; if( g_page_depth > bin_device->y_start ) { /* see Wiki for discussion, wgml 4.0 differs here */ xx_err( err_page_depth_too_big ); // candidate Severe Error g_suicide(); // no recovery possible } else { g_page_bottom = bin_device->y_start - g_page_depth;// end of text area } g_net_page_depth = g_page_top - g_page_bottom; lcmax = 1 + (g_net_page_depth + bin_device->y_offset) / wgml_fonts[g_curr_font].line_height; // usable no of lines } else { net_y_start = bin_device->y_start; if( net_y_start < net_top_margin ) net_y_start = net_top_margin; if( bin_device->y_start > net_top_margin ) { y_start_correction = bin_device->y_start - net_top_margin; if( y_start_correction > wgml_fonts[g_curr_font].line_height ) { y_start_correction = wgml_fonts[g_curr_font].line_height; } } else { y_start_correction = 0; } g_page_top = net_y_start - y_start_correction; g_page_bottom = g_page_top + g_page_depth; g_net_page_depth = g_page_bottom - g_page_top; lcmax = g_net_page_depth; } g_page_bottom_org = g_page_bottom;// save for possible bot banner calculation g_page_top_org = g_page_top;// save top for possible bot banner calculation g_cd = layout_work.defaults.columns;// no of columns &syscd g_gutter = conv_hor_unit( &layout_work.defaults.gutter ); // &sysgutter #if 0 // activate for multi column TBD if( g_cd > 1 ) { // multi column layout if( g_cd > 9 ) { // no more than 9 columns g_cd = 9; // this limit is found in script_tso.txt // for .cd control word } g_cl = (g_net_page_width - (g_cd - 1) * g_gutter ) / (g_cd - 1); // column length offset = g_page_left; for( k = 0; k < g_cd; ++k ) { g_offset[k] = offset; // start of each column offset += g_cl + g_gutter; } for( ; k < 9; ++k ) { g_offset[k] = 0; // dummy start of undefined columns } } else { g_cl = g_ll; } #else g_cl = g_ll; // column length &syscl // This is what wgml 4 does, even if in multi column mode TBD #endif // if( GlobalFlags.firstpass && GlobalFlags.research ) { // show values TBD if( GlobalFlags.firstpass ) { out_msg( "\ntm:%d lm:%d rm:%d top margin:%d depth:%d\n\n", tm, lm, rm, top_margin, g_page_depth ); out_msg( "dev:%s page_w:%d page_d:%d hor_u:%d ver_u:%d x_s:%d y_s:%d" " x_o:%d y_o:%d\n\n", bin_device->driver_name, bin_device->page_width, bin_device->page_depth, bin_device->horizontal_base_units, bin_device->vertical_base_units, bin_device->x_start, bin_device->y_start, bin_device->x_offset, bin_device->y_offset ); out_msg( "default font number:%d font_count:%d\n", g_curr_font, wgml_font_cnt ); for( k = 0; k < wgml_font_cnt; ++k ) { out_msg( "font:%d def_width:%d em:%d font_h:%d font_s:%d" " line_h:%d line_s:%d spc_w:%d\n", k, wgml_fonts[k].default_width, wgml_fonts[k].em_base, wgml_fonts[k].font_height, wgml_fonts[k].font_space, wgml_fonts[k].line_height, wgml_fonts[k].line_space, wgml_fonts[k].spc_width ); } out_msg( "\npage top:%d bottom:%d left:%d right:%d lines:%d\n", g_page_top, g_page_bottom, g_page_left, g_page_right, lcmax ); out_msg( "page net depth:%d width:%d line height:%d char width:%d\n\n", g_net_page_depth, g_net_page_width, g_max_line_height, g_max_char_width ); } g_indent = 0; g_indentr = 0; init_nest_cb(); }
void start_doc_sect( void ) { bool first_section; bool header; bool page_r; char * h_text; doc_section ds; hdsrc hds_lvl; int k; page_ej page_e; uint32_t page_c; uint32_t page_s; if( ProcFlags.start_section ) { return; // once is enough } if( !ProcFlags.fb_document_done ) { // the very first section/page do_layout_end_processing(); } scr_process_break(); // commit any prior text first_section = (ProcFlags.doc_sect == doc_sect_none); ProcFlags.start_section = true; ProcFlags.keep_left_margin = false; page_c = layout_work.defaults.columns; ds = ProcFlags.doc_sect_nxt; // new section if( ds == doc_sect_none ) { ds = doc_sect_body; // if text without section start assume body } /***********************************************************************/ /* process special section attributes */ /***********************************************************************/ switch( ds ) { case doc_sect_titlep : page_c = layout_work.titlep.columns; page_e = ej_yes; page_r = false; // no page number reset header = false; // no header string (ABSTRACT, ... ) output init_nest_cb(); nest_cb->p_stack = copy_to_nest_stack(); nest_cb->c_tag = t_TITLEP; nest_cb->p_stack->lineno = titlep_lineno; // correct line number break; case doc_sect_abstract : page_c = layout_work.abstract.columns; page_e = layout_work.abstract.page_eject; page_r = layout_work.abstract.page_reset; page_s = layout_work.hx.hx_sect[hds_abstract].spacing; header = layout_work.hx.hx_sect[hds_abstract].header; if( header ) { h_text = &layout_work.abstract.string; hds_lvl = hds_abstract; } break; case doc_sect_preface : page_c = layout_work.preface.columns; page_e = layout_work.preface.page_eject; page_r = layout_work.preface.page_reset; page_s = layout_work.hx.hx_sect[hds_preface].spacing; header = layout_work.hx.hx_sect[hds_preface].header; if( header ) { h_text = &layout_work.preface.string; hds_lvl = hds_preface; } break; case doc_sect_body : page_c = layout_work.body.columns; page_e = layout_work.body.page_eject; page_r = layout_work.body.page_reset; page_s = layout_work.hx.hx_sect[hds_body].spacing; header = layout_work.hx.hx_sect[hds_body].header; if( header ) { h_text = &layout_work.body.string; hds_lvl = hds_body; } break; case doc_sect_appendix : page_c = layout_work.appendix.columns; page_e = layout_work.appendix.section_eject; page_r = layout_work.appendix.page_reset; page_s = layout_work.hx.hx_sect[hds_appendix].spacing; header = false; // no section header string output, as such if( page_e != ej_no ) { page_e = ej_yes; // "even" and "odd" act like "yes" } for( k = 1; k < hds_appendix; k++ ) { // reset heading levels hd_nums[k].headn = 0; if( hd_nums[k].headnsub != NULL ) { *(hd_nums[k].headnsub->value) = '\0'; } } break; case doc_sect_backm : page_c = layout_work.backm.columns; page_e = layout_work.backm.page_eject; page_r = layout_work.backm.page_reset; page_s = layout_work.hx.hx_sect[hds_backm].spacing; header = layout_work.hx.hx_sect[hds_backm].header; if( header ) { h_text = &layout_work.backm.string; hds_lvl = hds_backm; } break; case doc_sect_index : page_c = layout_work.index.columns; page_e = layout_work.index.page_eject; page_r = layout_work.index.page_reset; page_s = layout_work.hx.hx_sect[hds_index].spacing; header = layout_work.hx.hx_sect[hds_index].header; if( header ) { h_text = &layout_work.index.index_string; hds_lvl = hds_index; } break; case doc_sect_gdoc : case doc_sect_etitlep : case doc_sect_frontm : page_c = layout_work.defaults.columns; page_e = ej_no; // no page eject page_r = false; // no page number reset page_s = layout_work.defaults.spacing; // default spacing header = false; // no section header break; case doc_sect_egdoc : page_c = layout_work.defaults.columns; page_e = ej_yes; page_r = false; // no page number reset page_s = layout_work.defaults.spacing; // default spacing header = false; // no section header break; default: internal_err( __FILE__, __LINE__ ); break; } if( first_section ) { // nothing precedes the first section if( page_e == ej_even ) { do_page_out(); // apage of first page is odd page = 0; // restart page for first text page ProcFlags.page_ejected = true; } set_section_banners( ds ); reset_t_page(); document_new_position(); // first text page ready for content } else if( page_e == ej_no ) { full_page_out(); // ensure are on last page ProcFlags.page_ejected = false; set_section_banners( ds ); reset_bot_ban(); } else { last_page_out(); // ensure last page output ProcFlags.page_ejected = true; // only first section has nothing to output if( page_e == ej_odd ) { if( (page & 1) ) { // first page will be odd do_page_out(); // emit blank page } } else if( page_e == ej_even ) { if( !(page & 1) ) { // first page will be even do_page_out(); // emit blank page } } else if( page_e != ej_yes ) { internal_err( __FILE__, __LINE__ ); } g_skip = 0; // ignore remaining skip value set_section_banners( ds ); reset_t_page(); } ProcFlags.doc_sect = ds; t_page.col_count = page_c; set_cols(); if( page_r ) { page = 0; } spacing = page_s; g_cur_left = g_page_left_org; if( header ) { line_position = pos_center; concat_save = ProcFlags.concat; ProcFlags.concat = true; justify_save = ProcFlags.justify; ProcFlags.justify = ju_off; gen_heading( h_text, NULL, 0, hds_lvl ); g_indent = 0; // reset for section body ProcFlags.concat = concat_save; ProcFlags.justify = justify_save; } g_curr_font = layout_work.defaults.font; g_cur_h_start = g_page_left_org + g_indent; ProcFlags.doc_sect = ds; }