1: #!/usr/local/bin/perl5.00403 -w 2: BEGIN { # try to get to legacy perl support files 3: my @tmp = @INC; 4: use lib qw( /usr/local/lib/perl5 /usr/local/lib/perl5/site_perl 5: /data1/opt2/perl/vendor/lib/vendor_perl/5.6.0/. ); 6: use lib @INC; # these should replace trailing paths 8: } 10: my $version_marker = ' $Id: htmltrans,v 1.45 2001/09/20 11:35:07 rbraddoc Exp xethair $ '; 12: use lib ("/usr/app/home/rbraddoc/SGML/Transform"); 13: use lib ("."); 14: use SGMLHandler; 15: use Carp; 16: use Data::Locations::Shell; 17: use strict; 18: require "sgmlhelp.pl"; 20: my $doctype_html = '<!doctype html PUBLIC "-//W3C//DTD HTML 4.0//EN">'; 21: my $handbookdir = "/usr/app/home/rbraddoc/Handbook"; 22: my $htmldir = $handbookdir . "/conversion/html"; 24: require "$handbookdir/conversion/general.pl"; 25: require "$handbookdir/general/common.pl"; 26: require "$htmldir/grutils.pl"; 28: my $debug = 0; # does very little 31: #constants 32: my $dirpath = "."; 33: my $topleveldir = $handbookdir . "/conversion/html"; 34: my $topleveldirtype = 'volume'; 36: #flags 37: my $do_purge_before = 0; #delete all files before article processing 38: my $do_section_split = 1; #whether to produce multi page documents 39: my $do_manuscript = 0; #whether to produce manuscript review format 40: my $do_comments = 0; #whether to include debugging info in comments 41: my $do_stylesheet = 1; #include code to call stylesheet 42: my $do_full_toc = 0; #include runin sects in toc 43: my $do_subfile_toc = 0; #include toc in section files 44: my $do_accurate_table_borders = 0; 45: my %do_external_images = ('color'=>0,'halftone'=>0,'lineart'=>0); #include links to full size separate images 46: my $with_graphics_at = 'absolute'; #use relative links to graphics hierarchy 47: my $show_borders = 0; #show borders on formatting tables 49: #globals 50: my $exitcode = 0; 51: my $sgml = new SGMLHandler(); 52: my $out = '[no location created here!]'; 53: my $null = '[no location created here!]'; 54: my ($volnum,$divnum,$artnum,$footnote_count,$end_notes,$targetfile, 55: $stylesheetloc,$stylesheet); 56: my (@simplecontentelements,@calloutsections,@runinsections); 57: my (%Label,%Label_Sub,%Label_Prime,%simple_element_map, #%map_section_heading, 58: %entity_map,%entity_map_tex,%entity_map_html,%ID_File,%ID_Content); 60: $stylesheet = $htmldir . "/section.css"; 61: 62: my @filelist = ReadArgs(@ARGV); 64: %simple_element_map = ('ITALIC' => 'em', 65: 'BOLD' => 'strong', 66: 'PARA' => 'p', 67: #'SUB' => 'sub', 68: #'SUP' => 'sup', 69: #'BREAK' => 'br', 70: ); 72: my %map_element_default_title = 73: ( 74: 'SELECT.SECT' => "Selected References", 75: 'INTRO' => "Introduction", 76: 'APPENDIX' => "Appendix", 77: 'TOPIC.OVERVIEW' => "Overview" 78: ); 80: @simplecontentelements = ('INTRO','RUNIN.SECT', 81: 'FIG.SECT'); 82: @calloutsections = ('CALLOUT.SECT','FIG.SECT','SELECT.SECT','REF.SECT', 83: 'ACKNOWLEDGE','INTRO','APPENDIX','TOPIC.OVERVIEW'); 84: @runinsections = ('RUNIN.SECT','EXAMPLE'); 86: my %section_type = ((map { ($_,'callout') } @calloutsections), 87: (map { ($_,'runin') } @runinsections)); 88: 91: %entity_map = %entity_map_tex = %entity_map_html = (); 92: ReadEntityMapping("$handbookdir/conversion/html/entity.map",\%entity_map_html); 93: ReadEntityMapping("$handbookdir/conversion/tex/entity.map",\%entity_map_tex); 95: # zero-th is repeated for out of range notes 96: my @footnote_marker = (0,'*','**',Entity('dagger'),Entity('Dagger')); 97: $a = 0; 98: my %footnote_map = 99: map { ($_, ++$a) } @footnote_marker[1..$#footnote_marker]; 101: my $layout_table_attr = ''; #valign="top" cellpadding=0 102: if ($show_borders) { 103: $layout_table_attr .= ' border=0'; 104: } else { 105: $layout_table_attr .= ' border=0'; 106: } 108: ############################################################################# 109: ## Handler Functions 110: $sgml->handler_mode('DEFAULT'); 111: # Default handlers 112: $sgml->element('',sub { 113: my ($sgml,$element) = @_; 114: warn "WARN:Unhandled Element:".$sgml->get_context."\n"; 115: print $out "<!--IGNORE:[".$element->name."]-->" if $do_comments; 116: print $out &check_for_id($sgml,$element); 117: my $save = $out; 118: $out = new Data::Locations::Shell("/dev/null"); 119: $sgml->process_content; 120: $out = $save; 121: #print $out "<!--INGORE:CLOSE[".$element->name."]-->" if $do_comments; 122: }); 123: $sgml->cdata('',sub { 124: my ($sgml,$data) = @_; 125: if (ref($out)) { 126: print $out $data; 127: } else { 128: warn "WARNING:CDATA:Output Location is invalid:".$sgml->get_context."\n"; 129: } 130: }); 131: $sgml->sdata('',sub { 132: my ($sgml,$data) = @_; 133: #$data->data =~ /^\\s*(\w+)\s*$/ || warn "Bad SData: '$data'\n"; 134: my $adata = $data->name; 135: my $cont = Entity($adata); 136: print $out $cont; 137: }); 138: $sgml->pi('',sub { 139: my ($sgml,$data) = @_; 140: print $out "<!--IGNORE:PI:".$$data."-->" if $do_comments; 141: }); 142: $sgml->comment('',sub { 143: my ($sgml,$comment) = @_; 144: my @temp = $comment->comments(); 145: print $out "<!--COMMENT:[".join('--',@temp)."]-->" if $do_comments; 146: }); 147: $sgml->re('',sub { 148: my ($sgml,$data) = @_; 149: print $out "\n"; 150: }); 152: $sgml->element('ARTICLE',sub { 153: my ($sgml,$element) = @_; 154: my ($savedout,$dir,$curdir,$toc,$tocloc,$cref,$artloc,%counts, 155: @sectionlist,@sectargs,@divlist,%texcache,$tmp,$sectpathloc, 156: $titleloc,$headingloc,@cleanup_tasks,$year); 158: my $id = $element->attr('ID'); 159: $id = uc $id->value if defined $id; 160: ($volnum,$divnum,$artnum,$year) = 161: Handbook::General::ReadAccessNumber($element->attr('ACCESS.NO')->value); 162: if (!defined $volnum) { 163: warn "WARNING: article '$id' omitted (access number error)\n"; 164: $sgml->suppress_content; 165: return; 166: } else { 167: my @ctrldata = 168: (Handbook::General::Get_Article_Info($id))[2,3,4,5]; 169: $year = $ctrldata[3] unless $year; 170: my @sgmldata = ($volnum,$divnum,$artnum,$year); 171: for (my $i=0; $i<4; $i+=1) { 172: my $c = $ctrldata[$i]; 173: my $s = $sgmldata[$i]; 174: next unless defined($c) || defined($s); 175: my $err = 1; 176: TEST: { 177: last TEST if (!defined($c) || !defined($s)); 178: if ($c =~ /\D/) { 179: last TEST unless ($c eq $s); 180: } else { 181: last TEST unless ($c == $s); 182: } 183: $err = 0; 184: } 186: if ($err) { 187: warn "WARNING: SGML access number does not match Control Data". 188: ": " . ('volume','division','article','year')[$i] . 189: " S:'".$s."' C:'".$c."'\n"; 190: if (defined $c) { 191: if ($i == 0) { 192: $volnum = $c; 193: } elsif ($i == 1) { 194: $divnum = $c; 195: } elsif ($i == 2) { 196: $artnum = $c; 197: } 198: } 199: #last; 200: } 201: } 203: $volnum = '0'.(0+$volnum) unless $volnum =~ /\D/ || $volnum > 9; 204: $divnum = '0'.(0+$divnum) unless $divnum =~ /\D/ || $divnum > 9; 205: $artnum = '0'.(0+$artnum) unless $artnum =~ /\D/ || $artnum > 9; 206: $year = 0 unless $year; 207: } 208: $dirpath = $topleveldir; 209: if ($topleveldirtype eq 'volume') { 210: if ($volnum =~ /\D/) { 211: $tmp = "/".$volnum; 212: } else { 213: $tmp = "/V".$volnum; 214: } 215: foreach $dir ($tmp, "Y".$year, "/D".$divnum, "/A".$artnum) { 216: $dirpath .= $dir; 217: if (! -d $dirpath) { 218: mkdir $dirpath,0755 || die "Failed to make destination directory"; 219: } 220: } 221: } elsif ($topleveldirtype eq 'article') { 222: foreach $dir ("/A".$artnum) { 223: $dirpath .= $dir; 224: if (! -d $dirpath) { 225: mkdir $dirpath,0755 || die "Failed to make destination directory"; 226: } 227: } 228: } elsif ($topleveldirtype eq 'id') { 229: foreach $dir ("/".$id) { 230: $dirpath .= $dir; 231: if (! -d $dirpath) { 232: mkdir $dirpath,0755 || die "Failed to make destination directory"; 233: } 234: } 235: } elsif ($topleveldirtype eq 'content') { 236: if (! -d $dirpath) { 237: mkdir $dirpath,0755 || die "Failed to make destination directory"; 238: } 239: } elsif ($topleveldirtype eq 'division') { 240: foreach $dir ("/D".$divnum,"/A".$artnum) { 241: $dirpath .= $dir; 242: if (! -d $dirpath) { 243: mkdir $dirpath,0755 || die "Failed to make destination directory"; 244: } 245: } 246: } 248: if ($do_purge_before) { 249: system 'rm','-rf',$dirpath; 250: mkdir($dirpath,0755) || die "Failed to make destination directory"; 251: } 253: if ($with_graphics_at eq 'local') { 254: mkdir($dirpath.'/detail',0755) || 255: die "Failed to make detail images directory"; 256: } elsif ($with_graphics_at eq 'division') { 257: foreach $dir ('','/inline','/entities','/detail') { 258: if (! -d $dirpath.'/../graphics'.$dir) { 259: mkdir($dirpath.'/../graphics'.$dir,0755) || 260: die "Failed to make ".$dir." images directory\n"; 261: } 262: } 263: } 265: $sgml->global('footnote count',0); 266: %ID_Content = (); 267: %ID_File = (); 268: foreach my $name ('table','inline.table','fig','ref.item','equation', 269: 'example') { 270: $Label_Prime{$name} = 0; 271: } 272: 273: $titleloc = new Data::Locations::Shell("/dev/null"); 274: $headingloc = new Data::Locations::Shell("/dev/null"); 275: $tocloc = new Data::Locations::Shell("/dev/null"); 276: $sectpathloc = new Data::Locations::Shell("/dev/null"); 277: %texcache = @sectionlist = @divlist = (); 278: #note some of these are initialization for open_section_file 279: $sgml->stack_new('math numbering' => 1,'destination path' => $dirpath, 280: 'TeX rendered hash' => \%texcache, 281: 'Article ID' => $id, 282: 'Article Heading' => $headingloc, 283: 'Section Path' => $sectpathloc, 284: 'Article Title' => $titleloc, 285: 'Article Section Location List' => \@sectionlist, 286: 'div list reference' => \@divlist, 287: 'Section Type' => 'article', 288: 'Volume' => $volnum, 289: 'end of article cleanup' => \@cleanup_tasks); 291: chomp ($curdir = `pwd`); 292: chdir($dirpath) || die "Failed to change directory to $dirpath: $!\n"; 293: warn "INFO:Writing to ".$dirpath."/\n"; 294: unlink "index.html"; # TODO remove these lines after symlinks gone 295: unlink "$id.html"; 296: #symlink "$id.html","index.html"; 297: $savedout = $out; 298: #dont do start_section($sgml,$element,'article'); 299: ($out,$toc) = open_section_file($sgml,$element,'article'); 301: $sgml->handler_mode_push('ARTICLE','DEFAULT'); 302: print $out "<div class=\"article-sect\">"; 303: $sgml->process_content_filt('Article Top-level Location'=>$out); 304: print $out "<div>"; 305: $sgml->handler_mode_pop('ARTICLE','DEFAULT'); 306: 307: #if ($sgml->global('footnote count') > 0) { 308: # print $out "<div class=\"FOOTNOTES\">"; 309: # print $out "<!--Footnotes-->" if $do_comments; 310: # print $out "<h3 class='sect-title'>Notes</h3>\n<ol>\n"; 311: # print $out $sgml->global('article notes'); 312: # print $out "</ol>\n</div>\n"; 313: #} 315: $titleloc->reset; 316: if (!defined $titleloc->read) { 317: print $titleloc $element->attr('ACCESS.NO')->value; 318: } 320: close_section_file($sgml,$element); 321: #finish_section($sgml,$element); 323: foreach my $task (@cleanup_tasks) { 324: if (ref($task) eq 'ARRAY') { 325: my $proc = shift @$task; 326: &$proc(@$task); 327: } elsif (ref($task) eq 'CODEREF') { 328: &$task(); 329: } else { 330: warn "WARNING:cleanup:unexpected task type ".ref($task)."\n"; 331: } 332: } 334: #all included locations should be filled by now 335: foreach $tmp (@sectionlist) { 336: $tmp->dump; 337: #$tmp->delete; #not recursive - maybe try traverse & delete? 338: } 339: 340: chdir $curdir; 341: $out = $savedout; 342: }); 344: $sgml->element(['HDBKEDIT','DIV'],'process'); 346: $sgml->element('DIV.INFO','suppress'); 348: ################################################################# 349: ## Article content handlers 350: $sgml->handler_mode('ARTICLE'); 352: foreach my $el (keys %simple_element_map) { 353: $sgml->element($el,'',\&simple_mapped_element); 354: } 356: $sgml->element(['ARTICLE.REAR','ARTICLE.BODY'],'process'); 358: $sgml->element('BREAK',sub { 359: my ($sgml,$element) = @_; 360: print $out "<br>"; 361: $sgml->process_content; 362: }); 364: $sgml->element('TRADENAME','process'); 366: #override the simple_mapped_elements 367: $sgml->element('PARA',sub { 368: my ($sgml,$element) = @_; 369: Count_Increment($sgml,'paragraph'); 370: $sgml->stack('seen content',1); 371: if ($sgml->global("Suppress Next Open Para")) { 372: $sgml->global("Suppress Next Open Para",0); 373: } else { 374: print $out "<" . $simple_element_map{'PARA'} . ">"; 375: } 376: $sgml->process_content; 377: print $out "</" . $simple_element_map{'PARA'} . ">\n"; 378: }); 379: #override the para default case 380: $sgml->element('PARA','.*/((FOOTNOTE)|(ENTRY)|(ITEM)|(REF\.ITEM))/[^/]+', 381: 'process'); 383: $sgml->element(\@simplecontentelements,\&SimpleContentElement); 385: $sgml->element('CALLOUT.SECT',\&Element_CalloutSection); 387: $sgml->element('BYLINE.DISPLAY','.*/(CALLOUT)|(PROPERTY).SECT/[^/]*', sub { 388: my ($sgml,$element) = @_; 389: my $savedout = $out; 390: $out = $sgml->stack('section byline'); 391: $sgml->process_content; 392: $out = $savedout; 393: }); 395: $sgml->element('COPYRIGHT','suppress'); 397: $sgml->element('PAGE.NO','suppress'); 398: $sgml->element('SOURCE.INFO','suppress'); 400: #these are assumed duplicated by footnotes 401: $sgml->element('PERMISSION','suppress'); 403: $sgml->element('ARTICLE.INFO','.*/ARTICLE/[^/]+', sub { 404: my ($sgml,$element) = @_; 405: my ($head,$title,$titlestr,$tmploc,$series,$volnum, 406: $divtitle,$voltitle,$byline,$vol,$permission); 407: #print $out &check_for_id($sgml,$element); 408: 409: $tmploc = new Data::Locations::Shell('/dev/null'); 410: foreach (\$title,\$series,\$volnum,\$divnum,\$divtitle,\$voltitle, 411: \$byline,\$permission) { 412: $$_ = $tmploc->new; 413: } 414: $sgml->stack_new('series'=>$series,'vol.no'=>$volnum,'title'=>$title, 415: 'div.title'=>$divtitle,'div.chair.display'=>$tmploc, 416: 'byline.display'=>$byline,'permission'=>$permission); 418: $sgml->process_content; 420: #print $head "<table width=100% border=0>\n<tr><td>\n<table width=100% border=0>\n<tr><td>"; 421: #$sgml->stack('series',$head->new); 422: #print $head ", Volume "; 423: #$sgml->stack('vol.no',$head->new); 424: #print $head "</td></tr>\n<tr><td>"; 425: #$sgml->stack('div.title',$head->new); 426: #print $head "</td></tr>\n<tr><td><br>\n"; 427: #$sgml->stack('div.chair.display',$head->new); 428: #print $head "</td></tr></table>\n</td><td>\n<h1 align=center>"; 429: #$titleloc = $head->new; 430: #$sgml->stack('title',$titleloc); 431: #print $head "</h1>\n<h4 align=right>"; 432: #$sgml->stack('byline.display',$head->new); 433: #print $head "</h4>\n</td></tr></table>\n"; 435: #make stripped title 436: $head = $sgml->stack('Article Title'); 437: $title->reset; 438: $titlestr = join '',($title->read); 439: $titlestr =~ s/<\/?[^>]+>//g; 440: print $head $titlestr; 442: #get vol title 443: $vol = $sgml->stack('Volume'); 444: #$voltitle = join '',($volnum->read); 445: #$voltitle =~ s/<\/?[^>]+>//g; 446: $voltitle = Handbook::General::Get_Volume_Info($vol); 447: $voltitle = '[VOLUME]' unless defined $voltitle; 449: #set up section path 450: $head = $sgml->stack('Section Path'); 451: if ($vol =~ /\D/) { 452: #desk edition 453: print $head ("<a href='../../../index.html'>ASM Desk Editions", 454: "</a> --> <a href='../../index.html'>",$voltitle, 455: "</a> --> <a href='../index.html'>Division: ", 456: $divtitle,"</a> --> <a href='index.html'>Article: ",$title,"</a>"); 457: } else { 458: #handbook 459: print $head ("<a href='../../../index.html'>",$series, 460: "</a> --> <a href='../../index.html'>Volume ",(0+$vol),", ", 461: $voltitle,"</a> --> <a href='../index.html'>Division: ", 462: $divtitle,"</a> --> <a href='index.html'>Article: ",$title,"</a>"); 463: } 464: #set up article heading 465: $head = $sgml->stack('Article Heading'); 466: print $head " 467: <h1 class='article-title'>",$title,"</h1> 468: <p class='byline'>",$byline,"</p> 469: "; 470: if (defined $permission->read) { 471: print $head "<p class='permission'>",$permission,"</p>\n"; 472: } 473: print $head " 474: <hr> 475: "; 476: #<table border=0 width='100%'> 477: #<tr><td>From:</td><td><it>",$series,"</it>, Volume ",$volnum,", ",$voltitle,"</td></tr> 478: #<tr><td>Division:</td><td><it>",$divtitle,"</it></td></tr> 479: #</table> 480: #<hr> 481: #"; 483: }); 484: 485: $sgml->element('TITLE',sub { 486: my ($sgml,$element) = @_; 487: my (@prefix,@suffix,$savedout,$sect,$parent,$secttype); 489: print $out &check_for_id($sgml,$element); 490: #fig.section causes this to choke without the defined test 491: #if (defined($$element[5]->attr('EXTRALEVEL')) && ! $$element[5]->attr('EXTRALEVEL')->is_implied && $$element[5]->attr('EXTRALEVEL')->value != 0 ) { #NOTE INTERNAL INTERFACE 492: $secttype = $sgml->stack('Section Type'); 493: if (Parent($element,@calloutsections,@runinsections)) { 494: $sect = 1; 495: @prefix = (); 496: @suffix = (); 497: if ($secttype eq 'runin') { 498: $sgml->global("Suppress Next Open Para",1); 499: } 500: } else { 501: $sect = 0; 502: @prefix = ($sgml->stack('title style start')); 503: @suffix = ($sgml->stack('title style end')); 504: } 505: 506: print $out @prefix; 507: 508: if ($sect) { 509: $savedout = $out; 510: $out = $sgml->stack('toc title'); 511: #print $savedout $out; 512: $sgml->stack('section title')->print($out); 513: } 515: $sgml->process_content; 517: if ($sect) { 518: $out = $savedout; 519: } 521: print $out @suffix; 522: }); 523: 524: $sgml->element(['TITLE.TOC','TITLE.HEAD','TITLE.SEARCH','TABCT','BYLINE', 525: 'COMMITTEE.BYLINE','FIGCT','CREATE.DATE','REVISE.DATE', 526: 'WORK.HISTORY','INDX.ALL','TEXTPAGES.CT','DIV.CHAIR', 527: 'PROCESS.NOTES'], sub { 528: my ($sgml,$element) = @_; 529: print $out "<!--SKIP:OPEN[".$element->name."]-->" if $do_comments; 530: $sgml->suppress_content; 531: }); 533: $sgml->element('TOPIC.OVERVIEW',sub { 534: my ($sgml,$element) = @_; 535: 536: start_section($sgml,$element,'toplevel'=>1,'notoc'=>1); 537: print $out "<hr>\n"; 538: $sgml->process_content; 539: print $out "<hr>\n"; 540: finish_section($sgml,$element); 541: }); 543: $sgml->element('APPENDIX',sub { 544: my ($sgml,$element) = @_; 546: start_section($sgml,$element); 547: $sgml->process_content; 548: finish_section($sgml,$element); 549: }); 551: $sgml->element('ARTICLE.INFO','.*/APPENDIX/[^/]+',sub { 552: my ($sgml,$element) = @_ ; 553: my ($byline,$title,$permission,$dummy); 554: print $out "<h3 class='sect-title'>"; 555: $title = $out->new; 556: print $out "</h3>\n<p class='byline'>"; 557: $byline = $out->new; 558: print $out "</p>\n"; 559: $permission = $out->new; 560: $dummy = new Data::Locations::Shell('/dev/null'); 561: $sgml->process_content_filt('byline.display'=>$byline,'title'=>$title, 562: 'series'=>$dummy,'vol.no'=>$dummy, 563: 'div.title'=>$dummy,'permission'=>$permission, 564: 'div.chair.display'=>$dummy); 565: $dummy->delete; 566: if (defined $permission->read) { 567: print $byline "<p class='permission'>"; 568: print $permission "</p>\n"; 569: } 570: }); 573: $sgml->element(['DEF.LIST','GLOSS.LIST'],sub { 574: my ($sgml,$element) = @_; 575: my ($title); 576: print $out &check_for_id($sgml,$element); 577: $sgml->stack('seen content',1); 578: print $out "<ul class='term-list'>\n"; 579: $title = $out->new; 580: $sgml->process_content_filt('title location',$title); 581: print $out "</ul>\n"; 582: }); 584: $sgml->element(['DEF.BLOCK','GLOSS.BLOCK'],sub { 585: my ($sgml,$element) = @_; 586: my ($title); 587: print $out "<ul class='term-list'>\n"; 588: print $out &check_for_id($sgml,$element); 589: $title = $out->new; 590: $sgml->process_content_filt('title location',$title); 591: print $out "</ul>\n"; 592: }); 594: $sgml->element('TITLE','.*/(DEF|GLOSS)\.(BLOCK|LIST)/[^/]+',sub { 595: my ($sgml,$element) = @_; 596: my $savedout = $out; 597: $out = $sgml->stack('title location'); 598: print $out "<li class=\"title\">"; 599: $sgml->process_content; 600: print $out "</li>\n"; 601: $out = $savedout; 602: }); 603: 604: $sgml->element(['DEF.ENTRY','GLOSS.ENTRY'],sub { 605: my ($sgml,$element) = @_; 606: my ($def,$term); 607: print $out "<li class='term'>"; 608: print $out &check_for_id($sgml,$element); 609: $term = $out->new; 610: print $out "</li><li class='def'>"; 611: $def = $out->new; 612: print $out "</li>\n"; 614: $sgml->process_content_filt('deflist term location',$term, 615: 'deflist definition location',$def); 616: }); 618: $sgml->element('TERM',sub { 619: my ($sgml,$element) = @_; 620: my $savedout = $out; 621: $out = $sgml->stack('deflist term location'); 622: print $out &check_for_id($sgml,$element); 623: $sgml->process_content; 624: $out = $savedout; 625: }); 627: $sgml->element('DEF',sub { 628: my ($sgml,$element) = @_; 629: my $savedout = $out; 630: $out = $sgml->stack('deflist definition location'); 631: print $out &check_for_id($sgml,$element); 632: $sgml->process_content; 633: $out = $savedout; 634: }); 637: $sgml->element('LIST',sub { 638: my ($sgml,$element) = @_; 639: my ($style,$head,$tail,$title,$pretitle,$outertype); 640: Count_Increment($sgml,'list'); 641: $sgml->stack('seen content',1); 642: if ($sgml->stack_exists('list style')) { 643: $outertype = $sgml->stack('list style'); 644: } else { 645: $outertype = ''; 646: } 647: $sgml->stack_new('list style' => ''); 648: $style = lc $element->attr('LIST.STYLE')->value; 649: if ($style eq 'bulleted') { 650: #$sgml->stack('list style',''); 651: $head = "<ul class='$style'>"; 652: $tail = "</ul>\n"; 653: } elsif ($style eq 'numbered') { 654: if ($outertype eq 'number-1') { 655: $sgml->stack('list style','number-a'); 656: #$head = "<ol type='a' class='$style'>"; 657: $head = "<ol class='$style'>"; 658: $tail = "</ol>\n"; 659: } else { #default or ($outertype eq 'number-a') 660: $sgml->stack('list style','number-1'); 661: #$head = "<ol type='1' class='$style'>"; 662: $head = "<ol class='$style'>"; 663: $tail = "</ol>\n"; 664: } 665: } elsif ($style eq 'simple') { 666: #$sgml->stack('list style',''); 667: $head = "<ul class='$style'>"; 668: $tail = "</ul>\n"; 669: } else { 670: if ($do_comments) { 671: $head = "<!--ERROR:LIST:OPEN:UNKNOWN STYLE [$style]-->"; 672: $tail = "<!--ERROR:LIST:CLOSE:UNKNOWN STYLE [$style]-->"; 673: } else { 674: $head = $tail = ''; 675: } 676: } 678: print $out "<table $layout_table_attr width='100%' class='list'><tr><td>"; 679: print $out &check_for_id($sgml,$element); 680: $pretitle = $out->new; 681: $title = $out->new; 682: print $out $head; 684: $sgml->process_content_filt('title location' => $title, 685: 'list block start' => $head, 686: 'list block end' => $tail); 687: print $out $tail; 688: print $out "</td></tr></table>"; 690: if (defined $title->read) { 691: print $pretitle "<span class=\"title\">"; 692: print $title "</span>"; 693: } 694: }); 696: $sgml->element('BLOCK',".*/LIST/[^/]+",sub { 697: my ($sgml,$element) = @_; 698: my ($title,$pretitle); 699: print $out $sgml->stack('list block end'); 700: print $out "</td></tr><tr><td>"; 701: $pretitle = $out->new; 702: $title = $out->new; 703: print $out $sgml->stack('list block start'); 704: print $out &check_for_id($sgml,$element); 706: $sgml->process_content_filt('title location',$title); 708: if (defined $title->read) { 709: print $pretitle "<span class=\"title\">"; 710: print $title "</span>"; 711: } 712: }); 714: $sgml->element('TITLE','.*/LIST(/BLOCK)?/[^/]+',\&Title_Loc); 716: $sgml->element('ITEM',".*/LIST(/BLOCK)?/[^/]+",sub { 717: my ($sgml,$element) = @_; 719: print $out "<li>"; 720: print $out &check_for_id($sgml,$element); 721: $sgml->process_content; 722: print $out "</li>\n"; 723: }); 724: 726: $sgml->element('TABLE',\&Table); 727: $sgml->element('INLINE.TABLE',\&Table); 729: $sgml->element('EXT.XREF',sub { 730: my ($sgml,$element) = @_; 731: my ($pointer,$targetvol,$targetdiv,$targetart,$tmp,$numvol); 732: Count_Increment($sgml,'crossref'); 733: $pointer = $element->attr('POINTER')->value; 735: my @info = Handbook::General::Get_Article_Info($pointer); 736: if (@info < 1 || !defined $info[4]) { 737: warn "WARNING:ext.ref:no data found for article $pointer\n"; 738: print $out "<A HREF=\"\">"; 739: print $out "<!--ERROR:FAILED TO LOOKUP $pointer-->" if $do_comments; 740: } else { 741: my ($title,$id,$v,$d,$a,$p) = @info; 742: $targetdiv = $d; 743: $targetdiv = '0' . (0+$targetdiv) if $targetdiv < 10; 744: $targetart = $a; 745: $targetart = '0' . (0+$targetart) if $targetart < 10; 746: $targetvol = $v; 747: if ($targetvol !~ /\D/) { 748: $targetvol = '0' . (0+$targetvol) if $targetvol < 10; 749: $numvol = 0; 750: } else { 751: $numvol = 1; 752: } 754: print $out "<A HREF=\""; 755: if (($numvol && $volnum !~ /\D/ && $targetvol == $volnum) || 756: ($targetvol eq $volnum)) { 757: if ($targetdiv == $divnum) { 758: print $out "../A$targetart/"; 759: } else { 760: print $out "../../D$targetdiv/A$targetart/"; 761: } 762: } else { 763: $tmp = ''; 764: $tmp = 'V' unless $numvol; 765: print $out "../../../$tmp$targetvol/D$targetdiv/A$targetart/"; 766: } 767: print $out "index.html\">"; 768: } 770: $sgml->process_content; 772: print $out "</A>"; 773: }); 775: $sgml->element(['XREF','REFERENCE','FNREF'],\&Reference); 777: $sgml->element('FOOTNOTE',sub { 778: my ($sgml,$element) = @_; 779: my ($tabnotes,$notebody,$referencetext,$saved,$notecount,$label,$marker); 781: #warn "checking footnote type\n"; 782: if (Ancestor($element,'TABLE','INLINE.TABLE')) { 783: #warn "processing table footnote\n"; 784: $tabnotes = $sgml->globalrefs('table footnote count'); 785: if ($$tabnotes == 0) { 786: $notebody = new Data::Locations::Shell(); 787: $sgml->global('table notes',$notebody); 788: } else { 789: $notebody = $sgml->global('table notes'); 790: } 791: $$tabnotes += 1; 792: $label = '('.lc(NumToTableNoteLetter($$tabnotes)).')'; 793: set_gen_numbering($element->attr('ID')->value,$label); 794: print $notebody '<tr><td valign="top" class="label">'.$label.'</td><td valign="top" class="body">'; 795: print $notebody &check_for_id($sgml,$element); 796: $saved = $out; 797: $out = $notebody; 798: $sgml->process_content; 799: $out = $saved; 800: print $notebody "</td></tr>\n"; 801: } else { 802: #warn "processing footnote\n"; 803: $notecount = $sgml->globalrefs('footnote count'); 804: if ($$notecount == 0) { 805: $notebody = new Data::Locations::Shell(); 806: $sgml->global('article notes',$notebody); 807: } else { 808: $notebody = $sgml->global('article notes'); 809: } 810: $notebody = $notebody->new; 811: set_ID_content($element->attr('ID')->value,$notebody); 812: $$notecount += 1; 814: #assert($$notecount > 0); 815: if ($$notecount > $#footnote_marker) { 816: warn "WARN:Footnote count exceeds number of available symbols\n"; 817: if ($footnote_marker[0] eq '0') { 818: $marker = $$notecount; 819: } else { 820: $marker = $footnote_marker[0] x $$notecount; 821: } 822: } else { 823: $marker = $footnote_marker[$$notecount]; 824: } 825: set_gen_numbering($element->attr('ID')->value,$marker); 826: #$ref = $sgml->stack('Section References List'); 827: #$$ref{lc $idref} = 1; 828: print $notebody "<tr><td valign='top' class='label'>".$marker. 829: "</td><td valign='top' class='body'>"; 830: print $notebody &check_for_id($sgml,$element); 831: $saved = $out; 832: $out = $notebody; 833: $sgml->process_content; 834: $out = $saved; 835: print $notebody "</td></tr>\n"; 836: } 837: }); 839: $sgml->element(['TITLE','DIV.CHAIR.DISPLAY','BYLINE.DISPLAY','DIV.TITLE', 840: 'SERIES','VOL.NO'], 841: '.*/ARTICLE\.INFO(/.*)?',\&proc_artinfosub); 843: $sgml->element('REF.SECT',sub { 844: my ($sgml,$element) = @_; 845: my ($title); 846: 847: start_section($sgml,$element); 848: $sgml->stack('_Section Refs Location', #no need for separate refs list 849: new Data::Locations::Shell('/dev/null')); 851: $title = $sgml->stack('toc title'); 852: print $title 'Reference'; 853: print $title 's' if $element->attr('PLURAL')->value == 1; 854: 855: print $out '<h3 class="sect-title">'; 856: print $out $title; 857: print $out '</h3>'; 859: $sgml->process_content; 861: finish_section($sgml,$element); 862: }); 864: $sgml->element('SELECT.SECT',sub { 865: my ($sgml,$element) = @_; 866: my ($title); 868: start_section($sgml,$element); 870: $title = $sgml->stack('toc title'); 871: print $title 'Selected References'; 873: print $out '<h3 class="sect-title">'; 874: print $out $title; 875: print $out '</h3>'; 877: $sgml->process_content; 879: finish_section($sgml,$element); 880: }); 882: $sgml->element('REF.LIST', sub { #can have title and ref.block content 883: my ($sgml,$element) = @_; 884: $sgml->stack('seen content',1); 885: my $type = 'numbered'; 886: $type = 'selected' if (Ancestor($element,'SELECT.SECT')); 888: print $out "<table $layout_table_attr class='$type-refs-list'>"; 889: $sgml->stack_new('title location',$out->new); 890: $sgml->process_content; 891: print $out "</table>\n"; 892: }); 894: $sgml->element('REF.BLOCK', sub { #can have title 895: my ($sgml,$element) = @_; 896: my $type = 'numbered'; 897: $type = 'selected' if (Ancestor($element,'SELECT.SECT')); 899: print $out "<tr><td></td><td><table $layout_table_attr class='$type-refs-block'>"; 900: $sgml->stack_new('title location',$out->new); 902: $sgml->process_content; 903: print $out "</table></td></tr>\n"; 904: }); 906: $sgml->element('TITLE','.*/REF\.(LIST|BLOCK)/[^/]+',sub { 907: my ($sgml,$element) = @_; 908: my $savedout = $out; 909: $out = $sgml->stack('title location'); 910: print $out "<tr><td colspan=2><h3 class=\"sect-title\">"; #list-title? 911: $sgml->process_content; 912: print $out "</h3></td></tr>\n"; 913: $out = $savedout; 914: }); 916: $sgml->element('REF.ITEM', sub { 917: my ($sgml,$element) = @_; 918: my ($savedout); 919: $savedout = $out; 920: $out = $out->new; #location for just this reference 921: my $type = 'numbered'; 922: $type = 'selected' if (Ancestor($element,'SELECT.SECT')); 924: #these explicit valign attrs were necessary 20001023 925: print $out "<tr><td class='label' valign='top'>"; 926: print $out &check_for_id($sgml,$element); 927: if (!Ancestor($element,'SELECT.SECT')) { 928: gen_numbering_simple($element); 929: Count_Increment($sgml,'numbered reference'); 930: set_ID_content($element->attr('ID')->value,$out); 931: print $out &read_gen_numbering($element->attr('ID')->value),'.'; 932: } else { 933: Count_Increment($sgml,'unnumbered reference'); 934: set_ID_content($element->attr('ID')->value,$out); 935: # can't print saved numbering here, because it might be in the note 936: # body already (data not marked up for this) 937: print $out &Entity('bull'); 938: } 939: print $out "</td><td valign='top' class='body'>"; 940: $sgml->process_content; 941: print $out "</td></tr>\n"; 942: $out = $savedout; 943: }); 945: $sgml->element('CAUTION',sub { 946: my ($sgml,$element) = @_; 947: print $out "<span class='caution'>Caution: "; 948: $sgml->process_content; 949: print $out "</span>" 950: }); 952: $sgml->element('BLOCK.QUOTE',sub { 953: my ($sgml,$element) = @_; 954: $sgml->stack('seen content',1); 955: print $out "<table width='100%' $layout_table_attr><tr><td width='10%'></td><td>"; 956: $sgml->process_content; 957: print $out "</td><td width='10%'></td></tr></table>" 958: }); 960: $sgml->element('SIG.BLOCK',sub { 961: my ($sgml,$element) = @_; 962: $sgml->stack('seen content',1); 963: print $out "<table width='100%' $layout_table_attr><td width='20%'></td><tr><td class='sig-block'>"; 964: $sgml->process_content; 965: print $out "</td></tr></table>" 966: }); 968: $sgml->element('ACKNOWLEDGE',sub { 969: my ($sgml,$element) = @_; 970: my ($title); 972: start_section($sgml,$element,'nosplit'=>1,'notoc'=>1); 974: $title = $sgml->stack('toc title'); 975: print $title 'Acknowledgement'; 976: print $title 's' if $element->attr('PLURAL')->value == 1; 977: print $out '<h3 class="sect-title">'; 978: print $out $title; 979: print $out '</h3>'; 981: $sgml->process_content; 982: finish_section($sgml,$element); 983: }); 985: $sgml->element('TITLE','.*/EXAMPLE/[^/]+',\&Title_Loc); 987: $sgml->element('EXAMPLE',sub { 988: my ($sgml,$element) = @_; 989: my ($id,$toc,$titleloc,$titlesub,$titleprefix); 990: Count_Increment($sgml,'example'); 991: gen_numbering_dual($element); 993: start_section($sgml,$element); 995: $id = $element->attr('ID'); 996: $id = $id->value if defined $id; 998: print $out '<h3 class="sect-title">'; 999: $titleloc = $out->new; 1000: if ($element->attr('NUMBERED')->value != 0) { 1001: print $titleloc "Example ",&read_gen_numbering($id); 1002: } else { 1003: print $titleloc "Example"; 1004: } 1005: $titleprefix = $titleloc->new; 1006: $titlesub = $titleloc->new; 1007: print $out "</h3>\n"; 1009: $toc = $sgml->stack('toc title'); 1010: print $toc $titleloc; 1012: $sgml->process_content_filt('title location',$titlesub); 1014: if ($element->attr('NUMBERED')->value != 0 || defined $titlesub->read) { 1015: print $titleprefix ": "; 1016: } 1017: finish_section($sgml,$element); 1018: }); 1020: $sgml->element('EQUATION', sub { 1021: my ($sgml,$element) = @_; 1022: Count_Increment($sgml,'equation'); 1023: $sgml->stack('seen content',1); 1024: gen_numbering_dual($element); 1025: $sgml->stack_new('title style start' => "<h5 class=\"title\">", 1026: 'title style end' => "</h5>", 1027: 'image caption position',"right"); 1028: 1029: print $out &check_for_id($sgml,$element); 1030: print $out '<table border=0 width="100%"><tr><td align=center>'; 1031: print $out '<!--'.$element->name.'-->' if $do_comments; 1032: print $out '<table border=0><tr><td align=left>'; 1033: $sgml->process_content; 1034: print $out '</td></tr></table>'; 1035: print $out '</td>'; 1036: if ($element->attr('NUMBERED')->value != 0) { 1037: print $out "<td align=right><strong>(Eq "; 1038: print $out &read_gen_numbering($element->attr('ID')->value); 1039: print $out ")</strong></td>"; 1040: } 1041: print $out "</tr>\n"; 1042: print $out "<!--".$element->name."-->" if $do_comments; 1043: print $out "</table>\n"; 1044: }); 1046: $sgml->element('FIG.GRP',sub { 1047: my ($sgml,$element) = @_; 1048: my ($pretitle,$title,$body,$precaption,$caption,$savedout); 1049: print $out &check_for_id($sgml,$element); 1050: #gen_numbering_dual($element); #numbering is based on name but this isnt FIG 1052: print $out "<table border=1 width='100%' class='figure-group'><tr><td><table $layout_table_attr width='100%'>"; 1053: print $out "<!--".$element->name."-->" if $do_comments; 1054: $pretitle = $out->new; 1055: $title = $out->new; 1056: print $out "<tr><td>"; 1057: $body = $out->new; 1058: print $out "</td></tr>"; 1059: $precaption = $out->new; 1060: $caption = $out->new; 1061: print $out "</table></td></tr></table>\n"; 1063: ($savedout,$out) = ($out,$body); 1064: $sgml->process_content_filt('figure caption' => $caption, 1065: 'title location' => $title); 1066: $out = $savedout; 1068: if (defined $title->read()) { 1069: print $pretitle "<tr><td><h3 class='title'>"; 1070: print $title "</h3></td></tr>\n"; 1071: } 1072: if (defined $caption->read()) { 1073: print $precaption "<tr><td>"; 1074: print $caption "</td></tr>\n"; 1075: } 1076: }); 1078: $sgml->element('TITLE','.*/FIG\.GRP/[^/]+',\&Title_Loc); 1080: $sgml->element('CAPTION','.*/FIG(.GRP)?/[^/]+',sub { 1081: my ($sgml,$element) = @_; 1082: my $savedout = $out; 1083: $out = $sgml->stack('figure caption'); 1084: $sgml->process_content; 1085: $out = $savedout; 1086: }); 1088: $sgml->element('FIG',sub { 1089: my ($sgml,$element) = @_; 1090: my ($precaption,$caption,$pos,$savedout); 1092: gen_numbering_dual($element); 1093: Count_Increment($sgml,'figure'); 1094: $sgml->stack('seen content',1); 1096: #print $out "<tr><td>" if (Parent($element,'FIG.GRP')); 1097: print $out "<table $layout_table_attr class=\"figure\">"; 1098: print $out "<!--".$element->name."-->" if $do_comments; 1099: print $out "<tr><td>"; 1100: print $out &check_for_id($sgml,$element); 1101: $savedout = $out->new; 1102: print $out "</td>"; 1103: $precaption = $out->new; 1104: print $out "<td valign=top class=\"caption\">"; 1105: if ($element->attr('NUMBERED')->value != 0) { 1106: print $out "<strong>Fig. "; 1107: print $out &read_gen_numbering($element->attr('ID')->value); 1108: print $out "</strong> "; 1109: } 1110: $caption = $out->new; 1111: print $out "</td>"; 1112: print $out "</tr>"; 1113: print $out "<!--".$element->name."-->" if $do_comments; 1114: print $out "</table>\n"; 1115: #print $out "</td></tr>" if (Parent($element,'FIG.GRP')); 1117: ($out,$savedout) = ($savedout,$out); 1118: ($caption,$pos) = $sgml->process_content_filt('figure caption'=> $caption,'image caption position','right','title style start' => "<tr><td colspan=2><h3 class=\"title\">",'title style end'=> "</h3></td></tr>"); 1119: ($out,$savedout) = ($savedout,$out); 1121: #if (Parent($element,'FIG.GRP') || $pos ne 'right') { 1122: print $precaption "</tr>\n<tr>"; 1123: #} 1124: }); 1126: $sgml->element('IMAGE',sub { 1127: use integer; 1128: my ($sgml,$element) = @_; 1129: my ($class,$id,$width,$height,$type,$urltofull,$urltoinline); 1130: $id = $element->attr('ID')->value; 1131: $type = lc $element->attr('IMAGE.TYPE')->value; 1132: $class = lc $element->attr('IMAGE.CLASS')->value; 1134: Count_Increment($sgml,$class) if ($class eq 'lineart' || $class eq 'halftone' || $class eq 'color'); 1136: if (defined($id) && $id =~ /^([LIQ])((\d)(\d)(\d)(\d)(\d)(\d)(\d))$/) { 1137: #$class = $1; 1138: #$id = $class.$2; 1139: 1140: ($urltofull,$urltoinline,$width,$height) = 1141: LookupGraphic($id,$class,$type); 1142: #if ($width > 480 || (3*$width) > (4*$height)) { 1143: # $sgml->stack('image caption position','bottom'); 1144: #} 1145: 1146: print $out "<A href=\"$urltofull\">" if ($do_external_images{$class}); 1147: print $out "ID:$id<br>" if ($do_manuscript); 1148: print $out "<IMG src=\"$urltoinline\" alt=\"$class:$id\" width=$width height=$height border=0>"; 1149: print $out "</A>" if ($do_external_images{$class}); 1150: print $out "\n"; 1151: } else { 1152: warn "WARN: Image id is invalid: '$id'\n"; 1153: print $out "<!--FLAG:IMAGE:invalid id [$id]-->" if $do_comments; 1154: } 1155: 1156: $sgml->suppress_content; 1157: }); 1159: $sgml->element('IMAGE','.*/(FIG|EQUATION|TABLE|INLINE\.TABLE)/[^/]+',sub { 1160: use integer; 1161: my ($sgml,$element) = @_; 1162: my ($class,$id,$width,$height,$type,$urltofull,$urltoinline); 1163: $id = $element->attr('ID')->value; 1164: $type = lc $element->attr('IMAGE.TYPE')->value; 1165: $class = lc $element->attr('IMAGE.CLASS')->value; 1167: Count_Increment($sgml,$class) if ($class eq 'lineart' || $class eq 'halftone' || $class eq 'color'); 1169: if (defined($id) && $id =~ /^([LIQ])((\d)(\d)(\d)(\d)(\d)(\d)(\d))$/) { 1170: #$class = $1; 1171: #$id = $class.$2; 1172: 1173: ($urltofull,$urltoinline,$width,$height) = 1174: LookupGraphic($id,$class,$type); 1175: if ($width > 480 || (3*$width) > (4*$height)) { 1176: $sgml->stack('image caption position','bottom'); 1177: } 1178: 1179: print $out "<A href=\"$urltofull\">" if ($do_external_images{$class}); 1180: print $out "ID:$id<br>" if ($do_manuscript); 1181: print $out "<IMG src=\"$urltoinline\" alt=\"$class:$id\" width=$width height=$height border=0>"; 1182: print $out "</A>" if ($do_external_images{$class}); 1183: print $out "\n"; 1184: } else { 1185: warn "WARN: Image id is invalid: '$id'\n"; 1186: print $out "<!--FLAG:IMAGE:invalid id [$id]-->" if $do_comments; 1187: } 1188: 1189: $sgml->suppress_content; 1190: }); 1192: $sgml->element('TITLE','.*/(INLINE\.)?TABLE/[^/]*',\&Title_Loc); 1194: $sgml->element('TGROUP', sub { 1195: my ($sgml,$element) = @_; 1196: my ($thead,$tfoot,%args,$rowsep,$colsep,$frame,$tagstart); 1198: $sgml->stack_new('table span specification' => { }, 1199: 'table column specification' => { }, 1200: 'tgroup has colsep' => 0, 1201: 'tgroup has rowsep' => 0, 1202: 'table header location' => $thead=new Data::Locations::Shell(), 1203: 'table footer location' => $tfoot=new Data::Locations::Shell()); 1205: #location for table start tag, deferred to wait for col/row sep uses 1206: $tagstart = $out->new; 1208: print $out '<!--'.$element->name.'-->' if $do_comments; 1209: print $out $thead; 1210: %args = (); 1211: if (!$element->attr('TGROUPSTYLE')->is_implied) { 1212: $args{'table style name'} = $element->attr('TGROUPSTYLE')->value; 1213: } 1214: if (!$element->attr('COLSEP')->is_implied) { 1215: $args{'table column separator'} = $element->attr('COLSEP')->value; 1216: } 1217: if (!$element->attr('ROWSEP')->is_implied) { 1218: $args{'table row separator'} = $element->attr('ROWSEP')->value; 1219: } 1220: if (!$element->attr('ALIGN')->is_implied) { 1221: $args{'table horizontal alignment'} = $element->attr('ALIGN')->value; 1222: } 1223: if (!$element->attr('CHAROFF')->is_implied) { 1224: $args{'table character offset'} = $element->attr('CHAROFF')->value; 1225: } 1226: if (!$element->attr('CHAR')->is_implied) { #NOTE:UNUSED 1227: $args{'table alignment character'} = join("",$element->attr('CHAR')->value); 1228: } 1229: $sgml->process_content_filt(%args); 1230: print $out $tfoot; 1231: print $out "\n"; 1232: print $out "<!--".$element->name."-->" if $do_comments; 1233: print $out "</table>\n"; 1235: $frame = $sgml->stack('table frame'); 1236: $frame = lc $frame; 1237: ($rowsep,$colsep) = $sgml->stackvals('tgroup has rowsep', 1238: 'tgroup has colsep'); 1239: if ($rowsep || $colsep || $frame ne 'none') { 1240: print $tagstart "<table border=1 class='body' "; 1241: if ($do_accurate_table_borders) { 1242: if ($rowsep && $colsep) { 1243: print $tagstart "rules=all "; 1244: } elsif ($rowsep) { 1245: print $tagstart "rules=rows "; 1246: } elsif ($colsep) { 1247: print $tagstart "rules=cols "; 1248: } else { 1249: print $tagstart "rules=none "; 1250: } 1251: if ($frame eq "all") { 1252: print $tagstart "frame=box"; 1253: } elsif ($frame eq "sides") { 1254: print $tagstart "frame=vsides"; 1255: } elsif ($frame eq "topbot") { 1256: print $tagstart "frame=hsides"; 1257: } elsif ($frame eq "top") { 1258: print $tagstart "frame=above"; 1259: } elsif ($frame eq "bottom") { 1260: print $tagstart "frame=below"; 1261: } else { 1262: print $tagstart "frame=void"; 1263: } 1264: } 1265: print $tagstart ">"; 1266: } else { 1267: print $tagstart "<table border=0 class='body'>"; 1268: } 1269: }); 1271: $sgml->element('THEAD', sub { 1272: my ($sgml,$element) = @_; 1273: my ($saved,$valign); 1274: $saved = $out; 1275: $out = $sgml->stack('table header location'); 1276: print $out "<!--".$element->name."-open-->" if $do_comments; 1277: if ($element->attr('VALIGN')->is_implied) { 1278: $valign = 'BOTTOM'; 1279: } else { 1280: $valign = $element->attr('VALIGN')->value; 1281: } 1282: $sgml->process_content_filt('table vertical alignment',$valign, 1283: 'table section','HEAD'); 1284: print $out "<!--".$element->name."-close-->\n" if $do_comments; 1285: $out = $saved; 1286: }); 1288: $sgml->element('TFOOT', sub { 1289: my ($sgml,$element) = @_; 1290: my ($saved,$valign); 1291: $saved = $out; 1292: $out = $sgml->stack('table footer location'); 1293: print $out "<!--".$element->name."-open-->" if $do_comments; 1294: if ($element->attr('VALIGN')->is_implied) { 1295: $valign = 'TOP'; 1296: } else { 1297: $valign = $element->attr('VALIGN')->value; 1298: } 1299: $sgml->process_content_filt('table vertical alignment',$valign, 1300: 'table section','FOOT'); 1301: print $out "<!--".$element->name."-close-->\n" if $do_comments; 1302: $out = $saved; 1303: }); 1305: $sgml->element('TBODY', sub { 1306: my ($sgml,$element) = @_; 1307: my ($valign); 1308: print $out "<!--".$element->name."-open-->" if $do_comments; 1309: if ($element->attr('VALIGN')->is_implied) { 1310: $valign = 'TOP'; 1311: } else { 1312: $valign = $element->attr('VALIGN')->value; 1313: } 1314: $sgml->process_content_filt('table vertical alignment',$valign, 1315: 'table section','BODY'); 1316: print $out "<!--".$element->name."-close-->\n" if $do_comments; 1317: }); 1319: $sgml->element('TDESC', sub { 1320: my ($sgml,$element) = @_; 1321: my $savedout = $out; 1322: $out = $sgml->stack('table description'); 1323: print $out "<!--".$element->name."-open-->" if $do_comments; 1324: $sgml->process_content; 1325: print $out "<!--".$element->name."-close-->\n" if $do_comments; 1326: $out = $savedout 1327: }); 1329: $sgml->element('ROW', sub { 1330: my ($sgml,$element) = @_; 1331: my ($valign,$rowsep,%args); 1332: Count_Increment($sgml,'row'); 1333: print $out "<tr>"; 1334: %args = (); 1335: if (!$element->attr('VALIGN')->is_implied) { 1336: $args{'table vertical alignment'} = $element->attr('VALIGN')->value; 1337: } 1338: if (!$element->attr('ROWSEP')->is_implied) { 1339: $args{'table row separator'} = $element->attr('ROWSEP')->value; 1340: } 1341: $sgml->process_content_filt(%args); 1342: print $out "</tr>\n"; 1343: }); 1345: $sgml->element('SPANSPEC','.*/TGROUP/[^/]*', sub { 1346: my ($sgml,$element) = @_; 1347: my ($hash,$name,$start,$end,$align,$charoff,$char,$colsep,$rowsep); 1348: $hash = $sgml->stack('table span specification'); 1349: $name = lc $element->attr('SPANNAME')->value; 1350: $start = $element->attr('NAMEST')->value; 1351: $end = $element->attr('NAMEEND')->value; 1352: $align = $element->attr('ALIGN'); 1353: if ($align->is_implied) { 1354: $align = undef; 1355: } else { 1356: $align = $align->value; 1357: } 1358: $charoff = $element->attr('CHAROFF'); 1359: if ($charoff->is_implied) { 1360: $charoff = undef; 1361: } else { 1362: $charoff = $charoff->value; 1363: } 1364: $char = $element->attr('CHAR'); 1365: if ($char->is_implied) { 1366: $char = undef; 1367: } else { 1368: $char = join("",$char->value); #NOTE:UNUSED 1369: } 1370: $colsep = $element->attr('COLSEP'); 1371: if ($colsep->is_implied) { 1372: $colsep = undef; 1373: } else { 1374: $colsep = $colsep->value; 1375: } 1376: $rowsep = $element->attr('ROWSEP'); 1377: if ($rowsep->is_implied) { 1378: $rowsep = undef; 1379: } else { 1380: $rowsep = $rowsep->value; 1381: } 1383: $$hash{$name} = [ $start, $end, $align, $char, $charoff, $colsep, $rowsep ]; 1384: $sgml->process_content; 1385: }); 1387: $sgml->element('COLSPEC','.*/TGROUP/[^/]*', sub { 1388: my ($sgml,$element) = @_; 1389: my ($hash,$name,$num,$width,$align,$charoff,$char,$colsep,$rowsep); 1390: $hash = $sgml->stack('table column specification'); 1391: $num = join("",$element->attr('COLNUM')->value); 1392: $name = $element->attr('COLNAME'); 1393: if ($name->is_implied) { 1394: $name = "c" . (0+$num); 1395: } else { 1396: $name = lc($name->value); 1397: } 1398: $width = $element->attr('COLWIDTH'); 1399: if ($width->is_implied) { 1400: $width = undef; 1401: } else { 1402: $width = $width->value; 1403: } 1404: $align = $element->attr('ALIGN'); 1405: if ($align->is_implied) { 1406: $align = undef; 1407: } else { 1408: $align = $align->value; 1409: } 1410: $charoff = $element->attr('CHAROFF'); 1411: if ($charoff->is_implied) { 1412: $charoff = undef; 1413: } else { 1414: $charoff = $charoff->value; 1415: } 1416: $char = $element->attr('CHAR'); 1417: if ($char->is_implied) { 1418: $char = undef; 1419: } else { 1420: $char = join("",$char->value); #NOTE:UNUSED 1421: } 1422: $colsep = $element->attr('COLSEP'); 1423: if ($colsep->is_implied) { 1424: $colsep = undef; 1425: } else { 1426: $colsep = $colsep->value; 1427: } 1428: $rowsep = $element->attr('ROWSEP'); 1429: if ($rowsep->is_implied) { 1430: $rowsep = undef; 1431: } else { 1432: $rowsep = $rowsep->value; 1433: } 1435: $$hash{$name} = [ $num, $width, $align, $char, $charoff, $colsep, $rowsep ]; 1436: $sgml->process_content; 1437: }); 1439: #NOTE: This makes the asumption that ALL ENTRIES ARE SPECIFIED AND IN ORDER 1440: # Proper handling would generate a table showing where each entry 1441: # goes and print in order at the end 1442: # (actually, this was done in the TeX conversion--need to re do this based 1443: # on that now) 1444: $sgml->element('ENTRY', sub { 1445: my ($sgml,$element) = @_; 1446: my ($col,$span,$spec,$colnum,$colwidth,$colstart,$colend,$halign,$char, 1447: $charoff,$colsep,$rowsep,$att,$rotate,$valign,$colspan,$rowspan, 1448: $in_thead,$savedout); 1449: Count_Increment($sgml,'entry'); 1451: $in_thead = 'HEAD' eq $sgml->stack('table section'); 1453: $colsep = $sgml->stack('table column separator'); 1454: $rowsep = $sgml->stack('table row separator'); 1455: $valign = $sgml->stack('table vertical alignment'); 1456: $halign = $sgml->stack('table horizontal alignment'); 1457: $charoff = $sgml->stack('table character offset'); 1458: $char = $sgml->stack('table alignment character'); 1460: #check for a span name and fill in span info 1461: $span = $element->attr('SPANNAME'); 1462: if (!$span->is_implied) { 1463: $span = lc $span->value; 1464: $spec = $sgml->stack('table span specification'); 1465: $spec = $$spec{$span}; 1466: #($colstart,$colend,$halign,$char,$charoff,$colsep,$rowsep) = @$spec; 1467: $colstart = $$spec[0]; #required 1468: $colend = $$spec[1]; #required 1469: $halign = $$spec[2] if defined $$spec[2]; 1470: $char = $$spec[3] if defined $$spec[3]; 1471: $charoff = $$spec[4] if defined $$spec[4]; 1472: $colsep = $$spec[5] if defined $$spec[5]; 1473: $colsep = $$spec[6] if defined $$spec[6]; 1474: } 1475: #check for a column name and fill in column details 1476: if (!$element->attr('COLNAME')->is_implied) { 1477: $col = lc $element->attr('COLNAME')->value; 1478: } elsif (!$element->attr('NAMEST')->is_implied) { 1479: $col = lc $element->attr('NAMEST')->value; 1480: } elsif (!$span->is_implied) { 1481: $col = lc $colstart; 1482: } else { 1483: warn "WARN:Table entry has no column specification: ".Ancestor($element,'TABLE','INLINE.TABLE')->attr('ID')->value."\n"; 1484: $col = undef; 1485: } 1486: if (defined $col) { 1487: $spec = $sgml->stack('table column specification'); 1488: $spec = $$spec{$col}; 1489: $colnum = $$spec[0] if defined $$spec[0]; 1490: $colwidth = $$spec[1] if defined $$spec[1]; 1491: $halign = $$spec[2] if defined $$spec[2]; 1492: $char = $$spec[3] if defined $$spec[3]; 1493: $charoff = $$spec[4] if defined $$spec[4]; 1494: $colsep = $$spec[5] if defined $$spec[5]; 1495: $rowsep = $$spec[6] if defined $$spec[6]; 1496: $colstart = $col unless defined $colstart; 1497: } 1498: #fill in any specified values 1499: $att = $element->attr('NAMEST'); 1500: $colstart = $att->value unless ($att->is_implied); 1501: $att = $element->attr('NAMEEND'); 1502: $colend = $att->value unless ($att->is_implied); 1503: $att = $element->attr('COLSEP'); 1504: $colsep = $att->value unless ($att->is_implied); 1505: $att = $element->attr('ROWSEP'); 1506: $rowsep = $att->value unless ($att->is_implied); 1507: $att = $element->attr('ROTATE'); 1508: $rotate = $att->value unless ($att->is_implied); 1509: $att = $element->attr('VALIGN'); 1510: $valign = $att->value unless ($att->is_implied); 1511: $att = $element->attr('ALIGN'); 1512: $halign = $att->value unless ($att->is_implied); 1513: $att = $element->attr('CHAROFF'); 1514: $charoff = $att->value unless ($att->is_implied); 1515: $att = $element->attr('CHAR'); 1516: $char = join("",$att->value) unless ($att->is_implied); #NOTE:UNUSED 1518: if (defined $colstart && $colstart ne '') { 1519: warn "WARN:Column start name is invalid [$colstart]\n" unless $colstart =~ /[Cc](\d+)/; 1520: $colstart = $1; 1521: if (defined $colend && $colend ne '') { 1522: warn "WARN:Column end name is invalid [$colend]\n" unless $colend =~ /[Cc](\d+)/; 1523: $colend = $1; 1524: } else { 1525: $colend = $colstart; 1526: } 1527: } else { 1528: warn "WARN:Column start name is unspecified\n"; 1529: print $out "<!--ERROR:Unspecified Columt start-->" if $do_comments; 1530: $colstart = $colend = 0; 1531: } 1532: 1533: $colspan = $colend - $colstart + 1; 1534: $rowspan = $element->attr('MOREROWS')->value + 1; 1535: $halign = lc $halign; 1536: $valign = lc $valign; 1537: if ($halign eq 'char') { 1538: $halign = 'center'; 1539: } elsif ($halign eq 'justify') { 1540: $halign = 'left'; 1541: } 1542: if (!defined $halign || $halign eq '') { 1543: warn "WARN:Horizontal alignment undefined: ".Ancestor($element,'TABLE','INLINE.TABLE')->attr('ID')->value."\n"; 1544: $halign = 'left'; 1545: } 1546: if (!defined $valign || $valign eq '') { 1547: warn "WARN:Vertical alignment undefined: ".Ancestor($element,'TABLE','INLINE.TABLE')->attr('ID')->value."\n"; 1548: $valign = 'baseline'; 1549: } 1550: 1551: $sgml->stack('tgroup has colsep',1) if ($colsep); 1552: $sgml->stack('tgroup has rowsep',1) if ($rowsep); 1553: 1555: print $out "<td"; 1556: print $out " rowspan=$rowspan" unless $rowspan == 1; 1557: print $out " colspan=$colspan" unless $colspan == 1; 1558: print $out " align=$halign" unless $halign eq 'left'; 1559: print $out " valign=$valign" unless $valign eq 'baseline'; 1560: print $out ">"; 1561: print $out "<strong>" if $in_thead; 1562: print $out &check_for_id($sgml,$element); 1564: $savedout = $out; 1565: $out = $out->new; 1566: $sgml->process_content; 1567: $out->reset; 1568: if (join('',$out->read) =~ /\A\s*\Z/s) { 1569: print $savedout &Entity('nbsp'); # makes empty cell non-"empty" 1570: } 1571: $out = $savedout; 1573: print $out "</strong>" if $in_thead; 1574: print $out " </td>"; # add space for borders on empty cells 1575: }); 1577: $sgml->element('PROPERTY.SECT',sub { 1578: my ($sgml,$element) = @_; 1579: start_section($sgml,$element,'type'=>'callout'); 1580: $sgml->process_content; 1581: finish_section($sgml,$element); 1582: }); 1584: $sgml->element('PROPERTY.SECT','.*/PROPERTY.SECT/(.*/)?PROPERTY.SECT/[^/]+',sub { 1585: my ($sgml,$element) = @_; 1586: start_section($sgml,$element,'type'=>'runin'); 1587: $sgml->process_content; 1588: finish_section($sgml,$element); 1589: }); 1591: $sgml->element('PROPERTY.HEAD','.*/PROPERTY.SECT/[^/]+',\&Section_Title); 1593: #################################### 1594: ## Math Handlers 1595: $sgml->element(['OVERDOT','OVERBAR','OVERLINE','UNDRLINE','SUBFORM','FRACTION', 1596: 'SUP','SUB','INF','DDOT','HAT','EQUALS','DEG','TILDE', 1597: 'OVERRIGHTARROW','UNDERRIGHTARROW'],sub { 1598: my ($sgml,$element) = @_; 1599: $sgml->stack_new('math-pseudo',1); 1600: print $out "<!--MATH:IMPLICIT:OPEN-->" if $do_comments; 1601: $sgml->reprocess_pseudo_element('MATH'); 1602: print $out "<!--MATH:IMPLICIT:CLOSE-->" if $do_comments; 1603: }); 1605: $sgml->element(['MATH','MATH.ISO'],sub { 1606: my ($sgml,$element) = @_; 1607: my ($tex,$simple,$content,$savedout,$complete,$real_math); 1608: print $out "<!--MATH:INLINE:OPEN-->" if $do_comments; 1610: $real_math = $sgml->stack_exists('math-pseudo'); 1611: if ($real_math && $sgml->stack('math-pseudo')) { 1612: $real_math = 0; 1613: } else { 1614: $real_math = 1; 1615: } 1616: my %constructs = (); 1617: my @styles = (); 1618: if (Parent($element,"ITALIC")) { 1619: push @styles, 'italic'; 1620: } else { 1621: push @styles, 'roman'; # if (@styles == 0); 1622: } 1623: push @styles, 'bold' if (Parent($element,"BOLD")); 1625: $tex = new Data::Locations::Shell; 1626: $simple = $out->new; 1627: $savedout = $out; 1628: $out = $tex; 1629: print $tex "\$"; 1630: $sgml->handler_mode_push('MATH','DEFAULT'); #keep default for PI 1631: ($content,$complete) = 1632: $sgml->process_content_filt('math content','empty', 1633: 'complete math handling','complete', 1634: 'math element open',$real_math, 1635: 'math constructs',\%constructs, 1636: 'normal output',$savedout, 1637: 'simple output',$simple, 1638: 'math formatting','inline', 1639: 'math text style',\@styles, 1640: 'math pre-script open',0); 1641: $sgml->handler_mode_pop('MATH','DEFAULT'); 1642: print $tex "\$"; 1643: $out = $savedout; 1645: if ($complete ne 'complete') { 1646: print $out "<!--FLAG:TEX:incomplete:",$tex,"-->" if $do_comments; 1647: print $out "<strong><code>MATH OMITTED</code></strong>"; 1648: warn "WARNING:Math composition failed (search for 'MATH OMITTED')\n"; 1649: } else { 1650: #constructs(symbol,fraction,compactscript,spanner,multilevelscript) { 1651: #was the simple version good enough? 1652: if ($content eq 'complex') { 1653: #nope, render with TeX 1654: $simple->delete; 1655: print $out "<!--TEX:",$tex,"-->" if $do_comments; 1657: my ($path,$w,$h,$b,$number,$texhash,$textmp); 1658: #get the data from the location 1659: $textmp = $tex; 1660: $textmp->reset; 1661: $tex = join '',$textmp->read; 1662: #see if this TeX string was rendered already 1663: $texhash = $sgml->stack('TeX rendered hash'); 1664: if (defined ($path = $$texhash{$tex})) { 1665: ($path,$w,$h,$b) = @$path; 1666: print $out "<img src=\"$path\" border=0 height=$h width=$w"; 1667: if (defined($b) && $b) { 1668: print $out " style='vertical-align: $b".'%'."'"; 1669: } 1670: print $out ">"; 1671: } else { 1672: $path = $sgml->stack('destination path'); 1673: $number = $sgml->stack('math numbering'); 1674: $sgml->stack('math numbering',$number + 1); 1675: ($w,$h,$b) = TeXtoImage("$path/math$number.png",$tex); 1676: if (defined $w) { 1677: $$texhash{$tex} = [ "math$number.png",$w,$h,$b ]; 1678: print $out "<img src=\"math$number.png\" border=0". 1679: " width=$w height=$h"; 1680: if (defined($b) && $b) { 1681: print $out " style='vertical-align: $b".'%'."'"; 1682: } 1683: print $out ">"; 1684: } else { 1685: #TeXtoImage should have printed a message for us 1686: print $out "<!--FLAG:TEX:rendering failed-->" 1687: if $do_comments; 1688: print $out "<strong><code>MATH OMITTED</code></strong>"; 1689: } 1690: } 1691: } 1692: } 1693: print $out "<!--MATH:INLINE:CLOSE-->" if $do_comments; 1694: }); 1696: $sgml->handler_mode('MATH'); 1698: #This is here to cancel any non math specific handlers 1699: $sgml->element('',sub { 1700: my ($sgml,$element) = @_; 1701: my $save = $out; 1702: $sgml->stack('complete math handling','failed'); 1703: $sgml->stack('math constructs')->{'unknown'} = 1; 1704: $out = $sgml->stack('normal output'); 1705: warn "WARN:Unhandled Element in MATH:".$sgml->get_context."\n"; 1706: print $out "<!--MATH:IGNORE:[".$element->name."]-->" if $do_comments; 1707: print $out &check_for_id($sgml,$element); 1708: $sgml->suppress_content; 1709: $out = $save; 1710: #print $out "<!--MATH:INGORE:CLOSE[".$element->name."]-->" if $do_comments; 1711: }); 1713: #for math inside implicit math elements 1714: $sgml->element('MATH', sub { 1715: my ($sgml,$element) = @_; 1716: $sgml->process_content_filt('math element open',1); 1717: }); 1720: $sgml->element('ITALIC',sub { 1721: my ($sgml,$element) = @_; 1722: #$sgml->stack('complete math handling','failed'); 1723: $sgml->stack('math constructs')->{'style'} = 1; 1724: my $simple = $sgml->stack('simple output'); 1725: my $styles = $sgml->stack('math text style'); 1726: print $simple '<em>'; 1727: push @$styles,'italic'; 1728: $sgml->process_content; 1729: print $out "\\/"; #end italic spacer 1730: pop @$styles; 1731: print $simple '</em>'; 1732: }); 1733: $sgml->element('BOLD',sub { 1734: my ($sgml,$element) = @_; 1735: my $save = $out; 1736: #$sgml->stack('complete math handling','failed'); 1737: $sgml->stack('math constructs')->{'style'} = 1; 1738: #print $out "<!--MATH:IGNORE:[".$element->name."]-->" if $do_comments; 1739: my $simple = $sgml->stack('simple output'); 1740: my $styles = $sgml->stack('math text style'); 1741: print $simple '<strong>'; 1742: push @$styles,'bold'; 1743: $sgml->process_content; 1744: pop @$styles; 1745: print $simple '</strong>'; 1746: }); 1748: sub texStyle { 1749: my $listref = shift; 1750: my %styles = ('roman'=>0,'italic'=>0,'bold'=>0, 1751: map { ($_ => 1) } @$listref); 1752: my $pre = ''; 1753: my $post = ''; 1754: #no explicit italic, or tex will complain about subscripts 1755: if (! $styles{'italic'} && $styles{'roman'}) { 1756: $pre .= "{\\rm "; 1757: $post .= '}'; 1758: } 1759: if ($styles{'bold'}) { 1760: $pre .= "{\\bf "; 1761: $post .= '}'; 1762: } 1764: #foreach my $s (@$listref) { 1765: # if ($s eq 'italic') { 1766: # $pre .= "{\\it "; 1767: # } elsif ($s eq 'bold') { 1768: # $pre .= "{\\bf "; 1769: # } elsif ($s eq 'roman') { 1770: # $pre .= "{\\rm "; 1771: # } else { 1772: # warn "WARN:MATH:Ignoring text style [$s]\n"; 1773: # $pre .= '{'; 1774: # } 1775: #} 1776: return ($pre,$post); #''.('}' x $post)); 1777: } 1779: $sgml->sdata('',sub { 1780: my ($sgml,$data) = @_; 1781: my ($name,$tex,$cont); 1782: $name = $data->name; 1784: $cont = ''; 1785: #look for html definition 1786: if (defined $entity_map_html{$name}) { 1787: $cont = '<!--ENTITY:HTML:'.$name.'-->' if ($do_comments); 1788: $cont .= $entity_map_html{$name}; 1789: #if ($cont =~ m/\<img src=/) { 1790: # $cont = ''; 1791: #} 1792: } 1793: if ($cont ne '') { 1794: my $simple = $sgml->stack('simple output'); 1795: print $simple $cont; 1796: } else { 1797: #will have to use TeX version 1798: $sgml->stack('math content',"complex"); 1799: $sgml->stack('math constructs')->{'symbol'} = 1; 1800: } 1801: my ($pre,$suf) = texStyle($sgml->stack('math text style')); 1802: if (defined ($tex = $entity_map_tex{$name})) { 1803: if ($tex =~ /^\$(.*)\$$/) { 1804: $tex = $1; 1805: } else { 1806: $tex = '\hbox{'.$tex.'}'; 1807: } 1808: print $out $pre.$tex.$suf; 1809: } else { 1810: warn "WARN:Entity $name has no TeX conversion\n"; 1811: $sgml->stack('complete math handling','failed'); 1812: } 1813: }); 1815: $sgml->cdata('',sub { 1816: my ($sgml,$data) = @_; 1817: my $simple = $sgml->stack('simple output'); 1818: print $simple $data; 1819: #escape for TeX 1820: $data =~ s/\s+/ /sg; 1821: $data =~ s/\\/\\backslash/g; 1822: $data =~ s/([\{\}\$\#\_\%])/\\$1/g; #'; 1823: $data =~ s/\^/\\hat{\\hbox{\\ }}/g; 1824: $data =~ s/~/\\tilde{\\hbox{\\ }}/g; 1825: $data =~ s'"'``'g; #'; 1826: #$data =~ s'([%&\{}_~|<>#$"^])'\\$1'g; #'; # translate TeX special chars 1827: if ($data =~ /\S/) { 1828: my ($pre,$suf) = texStyle($sgml->stack('math text style')); 1829: print $out $pre.$data.$suf; #note: need concat here for unknown reason 1830: #warn $pre.$data.$suf."\n"; #maybe Locations using "unlikely" char string? 1831: } else { 1832: print $out $data; 1833: } 1834: }); 1836: $sgml->element('FRACTION',sub { 1837: my ($sgml,$element) = @_; 1838: my ($num,$den,$format,$tmpout,$type); 1839: #attributes: 1840: # shape (built|case) <implied> 1841: # align (left|center|right) 1842: # style lots of types, do 'single' and 'none' first, insert comments 1843: $sgml->stack('math constructs')->{'fraction'} = 1; 1844: $sgml->stack('math content',"complex"); 1846: print $out "{{"; 1847: $num = $out->new; 1848: print $out "}\\over{"; 1849: $den = $out->new; 1850: print $out "}}"; 1852: ($type) = $sgml->process_content_filt('fraction type','simple', 1853: 'numerator location',$num, 1854: 'denominator location',$den); 1856: #$format = $sgml->stack('math formatting'); 1857: #if ($sgml->stack('math content') eq 'empty' && 1858: # $format eq 'inline' && $type eq 'simple') { 1859: # $sgml->stack('math content',"simple fraction"); 1860: # $tmpout = $sgml->stack('simple output'); 1861: # print $tmpout "<sup>",$num,"</sup>/<sub>",$den,"</sub>"; 1862: #} else { 1863: # $sgml->stack('math content',"complex"); 1864: #} 1865: }); 1867: $sgml->element('NUM',sub { 1868: my ($sgml,$element) = @_; 1869: my ($savedout,$content); 1870: $savedout = $out; 1871: $out = $sgml->stack('numerator location'); 1872: $sgml->process_content; 1873: if (defined ($content = $out->read) && !defined $out->read) { 1874: if ($content !~ /^\d+$/) { 1875: $sgml->stack('fraction type',"complex"); 1876: } 1877: } else { 1878: $sgml->stack('fraction type',"complex"); 1879: } 1880: $out = $savedout; 1881: }); 1883: $sgml->element('DEN',sub { 1884: my ($sgml,$element) = @_; 1885: my ($savedout,$content); 1886: $savedout = $out; 1887: $out = $sgml->stack('denominator location'); 1888: $sgml->process_content; 1889: if (defined ($content = $out->read) && !defined $out->read) { 1890: if ($content !~ /^\d+$/) { 1891: $sgml->stack('fraction type',"complex"); 1892: } 1893: } else { 1894: $sgml->stack('fraction type',"complex"); 1895: } 1896: $out = $savedout; 1897: }); 1899: sub scriptPlacement { 1900: my ($element,$in_math) = @_; 1901: my $precedes = 0; 1902: my $stagger = 1; #non-math default: stagger 1904: if ($in_math) { 1905: #math default: compact 1906: $stagger = $element->attr('ARRANGE'); 1907: $stagger = $stagger->value if defined $stagger; 1908: if (defined $stagger) { 1909: $stagger = (lc($stagger) ne 'compact'); 1910: } else { 1911: $stagger = 0; 1912: } 1913: my $loc = $element->attr('LOCATION'); 1914: $loc = $loc->value if defined $loc; 1915: if (defined $loc && lc($loc) eq 'pre') { 1916: $precedes = 1; 1917: #$sgml->stack('complete math handling','failed'); 1918: #warn "WARN:MATH contains SUP/INF with 'PRE' placement\n"; 1919: } 1920: } 1921: return ($stagger,$precedes); 1922: } 1924: sub mathScript { 1925: my ($sgml,$element,$type) = @_; 1926: my ($stagger,$precedes,$simple,$savedout); 1927: if (Ancestor($element,'SUP','INF','SUB')) { 1928: $sgml->stack('math content',"complex"); 1929: } 1931: ($stagger,$precedes) = scriptPlacement($element, 1932: $sgml->stack('math element open')); 1934: if ($stagger) { 1935: $sgml->stack('math constructs')->{'script'} = 1; 1936: print $out '{}'; 1937: $simple = $sgml->stack('simple output'); 1938: print $simple "<$type>"; 1939: } else { 1940: $sgml->stack('math constructs')->{'compactscript'} = 1; 1941: $sgml->stack('math content',"complex"); 1942: if ($precedes) { 1943: if (! $sgml->stack('math pre-script open')) { 1944: $sgml->stack('math pre-script open',1); 1945: print $out ' {}'; 1946: } 1947: } 1948: } 1949: $sgml->stack('math pre-script open',0) unless $precedes; 1951: if ($type eq 'sup') { 1952: print $out '^{'; 1953: } else { 1954: print $out '_{'; 1955: } 1956: $sgml->process_content; 1957: print $out '}'; 1958: if ($stagger) { 1959: print $simple "</$type>"; 1960: } 1961: } 1963: #these have attributes: location(pre|post) and arrange(compact|stagger) 1964: $sgml->element('SUP', sub { mathScript($_[0],$_[1],'sup'); }); 1965: $sgml->element(['INF','SUB'], sub { mathScript($_[0],$_[1],'sub'); }); 1967: $sgml->element('SUBFORM',sub { 1968: my ($sgml,$element) = @_; 1969: #$sgml->stack('math content',"complex"); 1970: $sgml->stack('math pre-script open',0); 1971: $sgml->stack('math constructs')->{'subform'} = 1; 1972: print $out '{'; 1973: $sgml->process_content; 1974: print $out '}'; 1975: }); 1977: $sgml->element('OVERBAR',sub { 1978: my ($sgml,$element) = @_; 1979: $sgml->stack('math content',"complex"); 1980: $sgml->stack('math constructs')->{'spanner'} = 1; 1981: print $out '\overline{'; #used to use \bar here 1982: $sgml->process_content; 1983: print $out '}'; 1984: }); 1986: $sgml->element('OVERLINE',sub { 1987: my ($sgml,$element) = @_; 1988: $sgml->stack('math content',"complex"); 1989: $sgml->stack('math constructs')->{'spanner'} = 1; 1990: print $out '\overline{'; 1991: $sgml->process_content; 1992: print $out '}'; 1993: }); 1995: $sgml->element('UNDRLINE',sub { 1996: my ($sgml,$element) = @_; 1997: $sgml->stack('math content',"complex"); 1998: $sgml->stack('math constructs')->{'spanner'} = 1; 1999: print $out '{\underline'; 2000: $sgml->process_content; 2001: print $out '}'; 2002: }); 2004: $sgml->element('OVERDOT',sub { 2005: my ($sgml,$element) = @_; 2006: $sgml->stack('math content',"complex"); 2007: $sgml->stack('math constructs')->{'spanner'} = 1; 2008: print $out '\dot{'; 2009: $sgml->process_content; 2010: print $out '}'; 2011: }); 2013: $sgml->element('DDOT',sub { 2014: my ($sgml,$element) = @_; 2015: $sgml->stack('math content',"complex"); 2016: $sgml->stack('math constructs')->{'spanner'} = 1; 2017: print $out '\ddot{'; 2018: $sgml->process_content; 2019: print $out '}'; 2020: }); 2022: $sgml->element('TILDE',sub { 2023: my ($sgml,$element) = @_; 2024: $sgml->stack('math content',"complex"); 2025: $sgml->stack('math constructs')->{'spanner'} = 1; 2026: print $out '\tilde{'; 2027: $sgml->process_content; 2028: print $out '}'; 2029: }); 2031: $sgml->element('HAT',sub { 2032: my ($sgml,$element) = @_; 2033: $sgml->stack('math content',"complex"); 2034: $sgml->stack('math constructs')->{'spanner'} = 1; 2035: print $out '\hat{'; 2036: $sgml->process_content; 2037: print $out '}'; 2038: }); 2040: $sgml->element('DEG',sub { 2041: my ($sgml,$element) = @_; 2042: $sgml->stack('math content',"complex"); 2043: $sgml->stack('math constructs')->{'spanner'} = 1; 2044: print $out '\hbox{\setbox0=\hbox{h}\dimen0=\ht0 \advance\dimen0 by -1ex\rlap{\raise.67\dimen0\hbox{\char'."'".'27}}\hbox{'; 2045: $sgml->process_content; 2046: print $out '}}'; 2047: }); 2049: $sgml->element('EQUALS',sub { 2050: my ($sgml,$element) = @_; 2051: $sgml->stack('math content',"complex"); 2052: $sgml->stack('math constructs')->{'spanner'} = 1; 2053: print $out '\overline{\overline{'; 2054: $sgml->process_content; 2055: print $out '}}'; 2056: }); 2058: $sgml->element('OVERRIGHTARROW',sub { 2059: my ($sgml,$element) = @_; 2060: $sgml->stack('math content',"complex"); 2061: $sgml->stack('math constructs')->{'spanner'} = 1; 2062: print $out '\hbox{\vbox{\ialign{#\crcr\rightarrowfill\crcr\noalign{\kern-1pt\nointerlineskip\vskip1.5pt}\hfil {'; 2063: $sgml->process_content; 2064: print $out '}\hfil\crcr}}}'; 2065: }); 2067: $sgml->element('UNDERRIGHTARROW',sub { 2068: my ($sgml,$element) = @_; 2069: $sgml->stack('math content',"complex"); 2070: $sgml->stack('math constructs')->{'spanner'} = 1; 2071: print $out '\hbox{\vbox{\ialign{#\crcr\hfil {'; 2072: $sgml->process_content; 2073: print $out '}\hfil\crcr\noalign{\kern-1pt\nointerlineskip\vskip3pt}\rightarrowfill\crcr}}}'; 2074: }); 2076: $sgml->element('RADICAL',sub { 2077: my ($sgml,$element) = @_; 2078: $sgml->stack('math content',"complex"); 2079: $sgml->stack('math constructs')->{'spanner'} = 1; 2080: my ($radicand,$radix) = 2081: $sgml->process_content_filt('radicand',new Data::Locations::Shell, 2082: 'radix',new Data::Locations::Shell); 2083: if (defined $radix->read) { 2084: print $out '{\root {',$radix,'} \of {',$radicand,'}}'; 2085: } else { 2086: print $out '\sqrt{',$radicand,'}'; 2087: } 2088: }); 2090: $sgml->element('RADICAND',sub { 2091: my ($sgml,$element) = @_; 2092: my $savedout = $out; 2093: $out = $sgml->stack('radicand'); 2094: $sgml->process_content; 2095: $out = $savedout; 2096: }); 2098: $sgml->element('RADIX',sub { 2099: my ($sgml,$element) = @_; 2100: my $savedout = $out; 2101: $out = $sgml->stack('radix'); 2102: $sgml->process_content; 2103: $out = $savedout; 2104: }); 2106: ## End of Handler Definitions 2107: ######################################################### 2109: #last minute sanity checks 2110: if ($with_graphics_at eq 'division') { 2111: die "cannot use division level graphics links with article level destination\n" 2112: if ($topleveldirtype eq 'article' || $topleveldirtype eq 'id' || 2113: $topleveldirtype eq 'content'); 2114: } elsif ($with_graphics_at ne 'local' && $with_graphics_at ne 'division' && 2115: $with_graphics_at ne 'absolute') { 2116: die "graphics links must be 'local' 'division' or 'absolute'\n"; 2117: } 2119: delete $ENV{'DISPLAY'}; #imagemagick inexplicably opens windows on occasion 2121: foreach $targetfile (@filelist) { 2122: my ($res,$tocloc); 2123: #initialize globals 2124: $sgml->global("Suppress Next Open Para",0); 2125: $tocloc = $out = new Data::Locations::Shell("/dev/null"); 2126: $sgml->stack_new('Link to Up Loc' => '', 2127: 'Link to Next Loc' => '', 2128: 'Link to Previous Loc' => '', 2129: 'seen content' => 0, 2130: 'Table of Contents' => $tocloc, 2131: 'Section Type' => 'File'); 2132: $stylesheetloc = new Data::Locations::Shell("/dev/null"); 2133: if ($do_stylesheet) { 2134: #print $stylesheetloc "<STYLE>\n<!--\n"; 2135: #open STYLEF,"<$stylesheet"; 2136: #while (<STYLEF>) { print $stylesheetloc $_; } 2137: #close STYLEF; 2138: #print $stylesheetloc "\n-->\n</STYLE>\n"; 2139: print $stylesheetloc '<META http-equiv="Content-Style-Type" content="text/css"><LINK href="'.$stylesheet.'" rel=stylesheet type="text/css">' 2140: } 2141: 2142: #process the input 2143: $sgml->handler_mode('DEFAULT'); 2144: $res = $sgml->process_sgml_sysid($targetfile); 2145: if (!defined $res) { 2146: warn "WARNING: SGML Errors processing file $targetfile\n"; 2147: $exitcode = 1; 2148: } 2149: #clean up Locations 2150: #$out->dump(); #this should only dump to /dev/null 2151: Data::Locations->delete; 2152: } 2154: exit $exitcode; 2156: ############################################################################# 2157: ## Handler Functions for multiple elements 2160: sub Entity { 2161: my ($name,$data) = @_; 2162: return $entity_map{$name} if defined $entity_map{$name}; 2164: my ($cont,$h,$w,$b,$file); 2165: $data = '['.$name.']' unless defined $data; 2166: $cont = ''; 2168: if (defined $entity_map_html{$name}) { 2169: $cont = '<!--ENTITY:HTML:'.$name.'-->' if ($do_comments); 2170: $cont .= $entity_map_html{$name}; 2171: #if ($do_relative_graphics && $cont =~ m/\<img src=/) { 2172: # $cont =~ s|(src=['""'])(/graphics/)|$1../../..$2|g; 2173: #} 2174: } elsif (defined $entity_map_tex{$name}) { 2175: $file = $name.'.png'; 2176: $file = 'u-'.lc($file) if $file =~ /[A-Z]/; 2177: ($w,$h,$b) = TeXtoImage("/data1/httpd/root/graphics/entities/$file", 2178: $entity_map_tex{$name}); 2179: if (defined $w) { 2180: $cont = "<!--ENTITY:TEX:".$name."-->" if $do_comments; 2181: if ($with_graphics_at eq 'local') { 2182: $cont .= "<img src='$file'"; 2183: symlink("/data1/httpd/root/graphics/entities/".$file, 2184: $file); 2185: } elsif ($with_graphics_at eq 'division') { 2186: $cont .= "<img src='../graphics/entities/$file'"; 2187: symlink("/data1/httpd/root/graphics/entities/".$file, 2188: "../graphics/entities/".$file); 2189: } else { 2190: $cont .= "<img src=\"/graphics/entities/$file\""; 2191: } 2192: $cont .= " border='0' width='$w' height='$h' alt='$name'"; 2193: $cont .= " style='vertical-align: ".$b.'%'."'" if defined($b) && $b != 0; 2194: $cont .= ">"; 2195: } else { 2196: $cont = "<!--ENTITY:FAILED:TEX:".$name."-->" if $do_comments; 2197: $cont .= $data; 2198: warn "WARN:Failed to generate image for entity $name\n"; 2199: } 2200: } else { 2201: $cont = "<!--ENTITY:FAILED:".$name."-->" if $do_comments; 2202: $cont .= $data; 2203: warn "WARN:Failed to find replacement for entity $name\n"; 2204: } 2206: $entity_map{$name} = $cont; #cache this result 2207: return $cont; 2208: } 2210: sub Title_Loc { 2211: my ($sgml,$element) = @_; 2212: my $savedout = $out; 2213: $out = $sgml->stack('title location'); 2214: $sgml->process_content; 2215: $out = $savedout; 2216: } 2218: sub Section_Title { 2219: my ($sgml,$element) = @_; 2220: my $savedout = $out; 2221: my $secttype = $sgml->stack('Section Type'); 2223: $out = $sgml->stack('toc title'); 2224: $sgml->stack('section title')->print($out); 2226: $sgml->process_content; 2228: $out = $savedout; 2229: if ($secttype eq 'runin') { 2230: $sgml->global("Suppress Next Open Para",1); 2231: } 2232: } 2234: sub Element_CalloutSection { 2235: my ($sgml,$element) = @_; 2237: start_section($sgml,$element); 2238: $sgml->process_content; 2239: finish_section($sgml,$element); 2240: } 2242: sub SimpleContentElement { 2243: my ($sgml,$element) = @_; 2244: my ($id,$toc,$toctitle,$cref,$tocdata,$secttype,$temp,$tocbyline); 2245: if ($do_comments) { 2246: $sgml->stack_new('title style start' => "<!--ERROR:Unexpected Title--><h3 class=\"sect-title\">", 2247: 'title style end' => "</h3>"); 2248: } else { 2249: $sgml->stack_new('title style start' => "<h3 class=\"sect-title\">", 2250: 'title style end' => "</h3>"); 2251: } 2253: if ($element->name eq 'INTRO') { 2254: start_section($sgml,$element,'notoc'=>1,'toplevel'=>1); 2255: } else { 2256: start_section($sgml,$element); 2257: } 2259: $id = $element->attr('ID'); 2260: if (defined $id) { 2261: $id = $id->value; 2262: } else { 2263: if ($element->name ne 'ARTICLE.BODY' && 2264: $element->name ne 'ARTICLE.REAR') { 2265: print $out "<!--WARNING:NO ID ATTRIBUTE-->" if $do_comments; 2266: } 2267: } 2268: 2269: $sgml->process_content; 2271: finish_section($sgml,$element); 2272: } 2274: sub Reference { 2275: my ($sgml,$element) = @_; 2276: my ($idref,$elname,$saved,$ref); 2277: $idref = lc $element->attr('IDREF')->value; 2278: $elname = $element->name; 2280: if ($elname eq 'FNREF') { 2281: Count_Increment($sgml,'footnote'); 2282: print $out "<a href=\"#$idref\">"; 2283: if (Ancestor($element,'TABLE','INLINE.TABLE')) { 2284: print $out "<sup>"; 2285: print $out &read_gen_numbering($idref); 2286: print $out "</sup>"; 2287: #} elsif (Ancestor($element,'TITLE')) { 2288: # print $out "<strong>*</strong>"; 2289: # $ref = $sgml->stack('Section Notes List'); 2290: # $$ref{$idref} = 1; 2291: } else { 2292: print $out "<sup><strong>"; 2293: print $out &read_gen_numbering($idref); 2294: print $out "</strong></sup>"; 2295: $ref = $sgml->stack('Section Notes List'); 2296: $$ref{$idref} = 1; 2297: } 2298: print $out "</a>"; 2299: #discard content 2300: $saved = $out; 2301: $out = new Data::Locations::Shell('/dev/null'); 2302: $sgml->process_content; 2303: $out->delete(); 2304: $out = $saved; 2305: } else { 2306: if ($elname eq 'REFERENCE') { 2307: #local file reference 2308: print $out "<A HREF=\"#$idref\">"; 2309: $ref = $sgml->stack('Section References List'); 2310: $$ref{lc $idref} = 1; 2311: } elsif ($elname eq 'XREF') { 2312: print $out "<A HREF=\"",read_ID_file($idref),"#$idref\">"; 2313: } 2314: Count_Increment($sgml,'crossref'); 2315: $sgml->process_content; #prints the label for the ref--could gen this 2316: if ($elname eq 'REFERENCE' || 2317: $element->attr('XREF.TYPE')->value ne 'other') { 2318: print $out " "; 2319: print $out &read_gen_numbering($idref); 2320: } else { 2321: warn "WARN:Cross reference with type 'other' handled minimally\n"; 2322: } 2323: print $out "</A>"; 2324: } 2325: } 2327: sub Table { 2328: my ($sgml,$element) = @_; 2329: my ($notecount,$subtable,$label,$realtable,$numbered,$tdesc, 2330: $titleloc,%args,$cref); 2332: $notecount = $sgml->globalrefs('table footnote count'); 2333: $subtable = Ancestor($element,'TABLE','INLINE.TABLE'); 2334: $realtable = $element->name eq 'TABLE'; 2335: if (! $subtable) { 2336: $$notecount = 0; 2337: } 2339: $sgml->stack('seen content',1); 2340: if ($realtable) { 2341: $label = gen_numbering_dual($element); 2342: Count_Increment($sgml,'table'); 2343: } 2345: #print $out '<div class="table">'; 2346: print $out &check_for_id($sgml,$element); 2347: print $out "<table $layout_table_attr class='table'>"; 2348: print $out '<!--'.$element->name.'-->' if $do_comments; 2349: $titleloc = $out->new; 2350: print $titleloc "<tr><td><span class='title'><strong>"; 2352: $sgml->stack_new('table description' => $tdesc=new Data::Locations::Shell, 2353: 'image caption position' => "bottom", 2354: 'title location',$titleloc, 2355: 'table section','UNKNOWN'); 2356: %args = (); 2357: if ($realtable) { 2358: print $titleloc "Table ",$label," " if $label ne ''; 2359: if (!$element->attr('TABSTYLE')->is_implied) { 2360: $args{'table style name'} = $element->attr('TABSTYLE')->value; 2361: } 2362: if ($element->attr('COLSEP')->is_implied) { 2363: $args{'table column separator'} = "1"; 2364: } else { 2365: $args{'table column separator'} = $element->attr('COLSEP')->value; 2366: } 2367: if ($element->attr('ROWSEP')->is_implied) { 2368: $args{'table row separator'} = "1"; 2369: } else { 2370: $args{'table row separator'} = $element->attr('ROWSEP')->value; 2371: } 2372: if (!$element->attr('FOLD')->is_implied) { 2373: $args{'table folding'} = $element->attr('FOLD')->value; 2374: } 2375: if (!$element->attr('ORIENT')->is_implied) { 2376: $args{'table orientation'} = $element->attr('ORIENT')->value; 2377: } 2378: if (!$element->attr('FRAME')->is_implied) { 2379: $args{'table frame'} = $element->attr('FRAME')->value; 2380: } 2381: } else { 2382: #these are all implied in real tables, anyway 2383: $args{'table row separator'} = "1"; 2384: $args{'table column separator'} = "1"; 2385: $args{'table frame'} = "all"; 2386: } 2388: $sgml->process_content_filt(%args); 2390: print $titleloc "</strong>"; 2391: print $titleloc "TableID:".($element->attr('ID')->value) if ($do_manuscript && defined($element->attr('ID'))); 2392: print $titleloc "</span></td></tr>\n<tr><td>"; 2393: $tdesc->reset; 2394: if (defined $tdesc->read()) { 2395: print $titleloc $tdesc,"</td></tr>\n<tr><td>"; 2396: } 2398: print $out "</td></tr>\n"; 2399: 2400: if (! $subtable && $$notecount > 0) { 2401: print $out "<tr><td>"; 2402: print $out "<!--Footnotes-->" if $do_comments; 2403: print $out "<table $layout_table_attr class='note-list'>\n"; 2404: print $out $sgml->global('table notes'); 2405: print $out "</table></td></tr>\n"; 2406: } 2407: #if ($sgml->stack('table has title') { 2408: print $out "<!--".$element->name."-->" if $do_comments; 2409: print $out "</table>\n"; 2410: #}; 2411: #print $out "</div>\n"; 2412: } 2413: sub proc_artinfosub { 2414: my ($sgml,$element) = @_; 2415: my $prev = $out; 2416: $out = $sgml->stack(lc $element->name); 2417: $sgml->process_content; 2418: $out = $prev; 2419: } 2421: sub simple_mapped_element { 2422: my ($sgml,$element) = @_; 2423: print $out "<" . $simple_element_map{$element->name} . ">"; 2424: $sgml->process_content; 2425: print $out "</" . $simple_element_map{$element->name} . ">"; 2426: #print $out " " if $element->name eq 'ITALIC' 2427: } 2429: ############################################################################# 2430: ## Handler subroutines 2432: sub start_section { 2433: my ($sgml,$element,%flags) = @_; 2434: my ($split,$outersecttype,$secttype,$name,$temp,$savedout,$toc); 2435: Count_Increment($sgml,'section'); 2437: $outersecttype = $sgml->stack('Section Type'); 2438: $secttype = $flags{'type'}; 2439: if (!defined $secttype || $secttype eq '') { 2440: #check for section type (callout,runin,extralevel) 2441: $name = $element->name; 2442: $secttype = $section_type{$name}; 2443: if ($secttype eq 'callout') { 2444: my $el = $element->attr('EXTRALEVEL'); 2445: if (defined $el && ! $el->is_implied && $el->value != 0) { 2446: $secttype = 'extralevel' ; 2447: } 2448: } 2450: if (!defined($secttype) || $secttype eq '') { 2451: warn "WARN:Section element [$name] not recognized as callout or runin\n"; 2452: $secttype = 'callout'; 2453: } 2454: } 2456: #setup Section Path 2457: $temp = new Data::Locations::Shell('/dev/null'); 2458: print $temp $sgml->stack('Section Path'); 2459: $sgml->stack_new('Section Path'=>$temp); 2461: #open file 2462: $savedout = $out; 2463: if ($flags{'toplevel'}) { 2464: $out = $sgml->stack('Article Top-level Location'); 2465: $split = 0; 2466: } elsif ($do_section_split && 2467: (!defined $flags{'nosplit'} || !$flags{'nosplit'}) && 2468: ($secttype eq 'extralevel' || 2469: ($secttype eq 'callout' && $outersecttype ne 'callout' && 2470: $sgml->stack('seen content')))) { 2471: $split = 1; 2472: ($out) = open_section_file($sgml,$element,$secttype); 2473: print $out &check_for_id($sgml,$element); #so links go to top of file 2474: #$secttype = 'extralevel' if $secttype eq 'article'; 2475: } else { 2476: $split=0; 2477: } 2479: if ($flags{'notoc'}) { 2480: #set up toc for non-listed sects 2481: toc_add_entry($sgml,$element,'hidden'); 2482: } else { 2483: #set up toc for callout sects 2484: toc_add_entry($sgml,$element,$secttype); 2485: } 2487: print $out '<div class="'.$secttype.'-sect">'; 2488: print $out &check_for_id($sgml,$element) unless $split; 2489: my $pretitle = $out->new; 2490: my $title = $out->new; 2491: my $byline = $out->new; 2492: my $permission = $out->new; 2493: 2494: $sgml->stack_new('Section Type',$secttype, 'section byline'=>$byline, 2495: 'section permission'=>$permission, 2496: 'section title'=>$title->new, 2497: 'section top'=>$pretitle, 2498: '_section title'=>$title, 2499: '_savedout',$savedout, 2500: '_splitatthislevel',$split); 2501: return $secttype; 2502: } 2504: sub finish_section { 2505: my ($sgml,$element) = @_; 2506: my ($split,$savedout,$titlepost,$secttype,$sectpath, 2507: $pretitle,$title,$byline,$permission) = 2508: $sgml->stackvals('_splitatthislevel','_savedout','_section title', 2509: 'Section Type', 2510: 'Section Path','section top','section title', 2511: 'section byline','section permission'); 2512: my ($id); 2514: #cleanup toc 2515: toc_finish_entry($sgml,$element); 2517: #cleanup file 2518: print $out "<!--".$element->name."-->" if $do_comments; 2519: print $out "</div>\n"; 2521: #finish section heading 2522: my ($fmt_title_s,$fmt_title_e,$fmt_byline_s,$fmt_byline_e, 2523: $fmt_perm_s,$fmt_perm_e) = ('','',"<p class='byline'>","</p>\n", 2524: "<p class='permission'>","</p>\n"); 2525: if ($secttype eq 'extralevel') { 2526: $fmt_title_s = "<h2 class=\"sect-title\">"; 2527: $fmt_title_e = "</h2>\n"; 2528: } elsif ($secttype eq 'callout') { 2529: $fmt_title_s = "<h3 class=\"sect-title\">"; 2530: $fmt_title_e = "</h3>\n"; 2531: } elsif ($secttype eq 'runin') { 2532: #title handler blocks open para 2533: $fmt_title_s = "<" . $simple_element_map{"PARA"} . ">" . 2534: '<span class="sect-title">'; 2535: $fmt_title_e = "</span> "; 2536: $fmt_byline_s = ""; 2537: $fmt_byline_e = ""; 2538: $fmt_perm_s = ""; 2539: $fmt_perm_e = ""; 2540: } 2542: #print $pretitle "<hr>" if $secttype eq 'extralevel'; 2543: if (defined $title->read) { 2544: print $pretitle $fmt_title_s; 2545: print $titlepost $fmt_title_e; 2546: } 2547: if (defined $byline->read) { 2548: print $titlepost $fmt_byline_s; 2549: print $byline $fmt_byline_e; 2550: } 2551: if (defined $permission->read) { 2552: print $byline $fmt_perm_s; 2553: print $permission $fmt_perm_e; 2554: } 2555: print $permission "<hr>" if $secttype eq 'extralevel'; 2557: #update section path 2558: print $sectpath " --> "; 2559: $id = $element->attr('ID'); 2560: $id = $id->value if (defined $id); 2561: if (defined $id) { 2562: print $sectpath "<a href=\"",read_ID_file($id),"#".lc($id)."\">"; 2563: } 2564: print $sectpath "Section: ",$title; 2565: print $sectpath "</a>" if defined $id; 2567: if ($split) { 2568: close_section_file($sgml,$element); 2569: } 2570: $sgml->global("Suppress Next Open Para" => 0); #failsafe 2571: $out = $savedout; 2572: } 2574: sub toc_add_entry { 2575: my ($sgml,$element,$secttype) = @_; 2576: my ($toc,$id,$toctitle,$tocdata,$tocbyline,$toccontent,$outersecttype); 2577: $outersecttype = $sgml->stack('Section Type'); 2578: if ($secttype ne 'hidden' && 2579: ($do_full_toc || 2580: ( ($secttype eq 'callout' || $secttype eq 'extralevel') && 2581: ($outersecttype eq 'article' || 2582: $outersecttype eq 'extralevel')))) { 2583: $toc = $sgml->stack('Table of Contents'); 2584: } else { 2585: $toc = new Data::Locations::Shell('/dev/null'); 2586: } 2587: print $toc "<li>"; 2588: $id = $element->attr('ID'); 2589: $id = $id->value if (defined $id); 2590: if (defined $id) { 2591: print $toc "<a href=\"",read_ID_file($id),"#".lc($id)."\">"; 2592: } 2593: print $toc "<big><strong>" if ($secttype eq 'extralevel'); 2594: print $toc "<strong>" if ($secttype eq 'callout'); 2595: print $toc "<small>" if ($secttype eq 'runin'); 2596: $toctitle = $toc->new; 2597: print $toc "</strong></big>" if ($secttype eq 'extralevel'); 2598: print $toc "</strong>" if ($secttype eq 'callout'); 2599: print $toc "</small>" if ($secttype eq 'runin'); 2600: print $toc (defined $id?"</a>":""); 2601: $tocdata = $toc->new; 2602: $tocbyline = $toc->new; 2603: print $toc "<ul compact>"; 2604: $toccontent = $toc->new; 2605: print $toc "</ul>\n</li>\n"; 2606: $sgml->stack_new('toc title',$toctitle,'toc byline',$tocbyline, 2607: 'toc title byline divider',$tocdata, 2608: 'Table of Contents',$toccontent); 2609: } 2611: sub toc_finish_entry { 2612: my ($sgml,$element) = @_; 2613: my ($tb,$tt,$ttbd) = $sgml->stackvals('toc byline','toc title', 2614: 'toc title byline divider'); 2615: if (defined $tb->read) { 2616: print $ttbd "<br>\n"; 2617: } 2618: if (! defined $tt->read) { 2619: if (defined $map_element_default_title{$element->name}) { 2620: print $tt $map_element_default_title{$element->name}; 2621: } else { 2622: print $tt "[".$element->name."]"; 2623: } 2624: } 2625: } 2627: #starts a new section file 2628: #pre: on stack: 'Article Section Location List','Article Heading','Table of Contents','div list reference','Link to Previous Loc','Link to Next Loc','Link to Up Loc' 2629: # working directory is right place for content objects 2630: # in: sgml, element, section-type (for saved div elements) 2631: #out: content location, toc location, %hash of special stack args 2632: #Proper call sequence 2633: #if ($do_section_split) { 2634: # $savedout = $out; 2635: # ($out,$toc,@stackargs) = open_section_file($sgml,$element,$secttype); 2636: #} 2637: #$sgml->process_content_filt(@stackargs,[other stack args]); 2638: #if ($do_section_split) { 2639: # $out = $savedout; 2640: # close_section_file($sgml,$element,@stackargs); 2641: #} 2642: sub open_section_file { 2643: my ($sgml,$element,$secttype) = @_; 2644: my ($fname,$fileout,$id,$tmp,$toc,$divlistref,$content,$refs,$notes, 2645: @sectionargs,%reflist,%notelist,$savedout,$navbarloc,$pathloc, 2646: $currenturl,$prevlink,$nextlink,$uplink,$pretoc); 2647: 2648: $id = $element->attr('ID'); 2649: $id = uc $id->value if defined $id; 2650: if (!defined $id) { 2651: warn "WARN:open_section_file called for ". $element->name . 2652: " with no ID, using SDUMMYID\n"; 2653: $id = 'SDUMMYID'; 2654: } 2655: #make a new section file 2656: #$fname = $dirpath."/".$id.".html"; 2657: if ($secttype eq 'article') { 2658: $fname = "index.html"; 2659: } else { 2660: $fname = $id.".html"; 2661: } 2662: $fileout = new Data::Locations::Shell($fname); 2663: $tmp = $sgml->stack('Article Section Location List'); 2664: push @$tmp,$fileout; 2665: $currenturl = $fname; 2666: 2667: print $fileout $doctype_html,"<html>\n<head>\n"; 2668: print $fileout "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n"; 2669: print $fileout "<meta name=\"robots\" content=\"noindex,nofollow\">\n"; 2670: print $fileout "<!--TIME:".scalar(localtime(time))."-->\n"; # if $do_comments; 2671: print $fileout "<!--VERSION:".$version_marker."-->\n"; # if $do_comments; 2672: print $fileout "<title>",$sgml->stack('Article Title'),"</title>\n"; 2673: print $fileout $stylesheetloc if $do_stylesheet; 2674: print $fileout "</head>\n<body bgcolor=\"white\" text=\"black\">\n"; 2675: print $fileout "<A NAME=\"".lc($id)."\"></A>"; #cheat to get section links to go to top of file 2676: $pathloc = $fileout->new; 2677: print $pathloc "<p class='file-path'>",$sgml->stack('Section Path'),"</p>"; 2679: print $fileout $sgml->stack('Article Heading'); 2680: $pretoc = $fileout->new; 2682: if ($secttype ne 'article') { 2683: #fill in next link from previous section before making new navbar 2684: $nextlink = $sgml->stack('Link to Next Loc'); 2685: $nextlink->print("<a href='$currenturl'>[Next section in this article]</a>") if ref($nextlink); 2686: } 2688: #set up top navigation bar 2690: if ($secttype ne 'article') { 2691: $uplink = $sgml->stack('Link to Up Loc'); 2692: $prevlink = $sgml->stack('Link to Previous Loc'); 2693: } else { 2694: $uplink = "<a href='../index.html'>[Listing of articles in this division]</a>"; 2695: $prevlink = ''; 2696: } 2697: $navbarloc = $fileout->new; 2698: print $navbarloc "<table $layout_table_attr width='100%'>"; 2699: print $navbarloc "<tr><td width='30%' align=left>"; 2700: print $navbarloc $prevlink; 2701: print $navbarloc "</td><td width='40%' align=center>"; 2702: print $navbarloc $uplink; 2703: print $navbarloc "</td><td width='30%' align=right>"; 2704: $nextlink = $navbarloc->new; 2705: print $navbarloc "</td></tr></table>\n"; 2707: if ($secttype eq 'article') { 2708: $uplink = "<a href='$currenturl'>[Listing of sections in this article]</a>"; 2709: $sgml->stack_new('Link to Up Loc' => $uplink, 2710: 'Link to Next Loc' => '', 2711: 'Link to Previous Loc' => ''); 2712: # #dont reset nextlink, so top points to first section 2713: #$prevlink = ''; 2714: } else { 2715: #set up new link values 2716: #this is for next section # at this level 2717: #$sgml->stack('Link to Previous Loc',$prevlink); 2718: #$sgml->stack('Link to Next Loc',$nextlink); 2719: #this is for child sections (if used with stack_new) 2720: #$prevlink = ''; 2721: #$nextlink = ''; 2722: } 2723: $prevlink = 2724: "<a href='$currenturl'>[Previous section in this article]</a>"; 2725: $sgml->stack('Link to Next Loc' => $nextlink); 2726: $sgml->stack('Link to Previous Loc' => $prevlink); 2730: #set up table of contents 2731: if ($do_subfile_toc || $secttype eq 'article' || 2732: $secttype eq 'extralevel') { 2733: print $fileout "<ul compact>\n"; 2734: $tmp = $fileout->new; 2735: print $fileout "</ul>\n"; 2736: print $fileout "<hr>\n"; 2737: $toc = $sgml->stack('Table of Contents'); 2738: print $toc $tmp; #insert into enclosing toc 2739: $toc = $tmp; 2740: $sgml->stack_new('Table of Contents' => $toc); 2741: } else { 2742: $toc = $sgml->stack('Table of Contents'); 2743: #print $fileout "<hr>\n"; #article heading 2744: } 2746: #set up included content sections 2747: $divlistref = $sgml->stack('div list reference'); 2748: print $fileout @$divlistref; 2749: $content = $fileout->new; 2750: print $fileout "</div>" x scalar(@$divlistref); 2751: push @$divlistref,'<div class="'.$secttype.'-sect">'; 2752: 2753: #set up section reference section 2754: $refs = $fileout->new; 2756: #set up section notes section 2757: $notes = $fileout->new; 2758: 2759: #print bottom of page navigation links 2760: #if ($secttype ne 'article') { 2761: print $fileout "<hr>\n"; 2762: print $fileout $navbarloc; 2763: print $fileout $pathloc; 2764: #if ($secttype eq 'article') { 2765: # $nextlink = new Data::Locations::Shell('/dev/null'); 2766: #} 2767: print $fileout "</body>\n</html>\n"; 2768: 2769: #need to special case this because it has to be available at current 2770: #level for check_for_id to read the current file correctly 2771: $sgml->stack('seen content' => 1); #prevents "sliding" before sections 2772: $sgml->stack_new('Section File' => $fname, 2773: 'Section References List' => { }, 2774: 'Section Notes List' => { }, 2775: 'seen content' => 0, 2776: #'Link to Next Loc' => $nextlink, 2777: #'Link to Previous Loc' => $prevlink, 2778: '_Section End Location' => $fileout, 2779: '_Section Notes Location' => $notes, 2780: '_Section Refs Location' => $refs); 2781: return ($content,$toc); 2782: } 2784: #clean up after a file section 2785: # in: sgml,$element 2786: #out: n/a 2787: sub close_section_file { 2788: my ($sgml,$element) = @_; 2789: my ($eof_todo,$extra,@items); 2791: my ($divlistref,$refs,$notes,$notelist,$reflist,$secttype) = 2792: $sgml->stackvals('div list reference','_Section Refs Location', 2793: '_Section Notes Location','Section Notes List', 2794: 'Section References List','Section Type'); 2795: pop @$divlistref; 2797: if ($secttype eq 'article') { 2798: $extra = ''; 2799: } else { 2800: $extra = " cited in this section"; 2801: } 2803: $eof_todo = $sgml->stack('end of article cleanup'); 2805: @items = keys %$reflist; 2806: if (@items > 0) { 2807: push @$eof_todo, [ \&make_end_list, 'Reference', $extra, $refs, 2808: @items ]; 2809: } 2811: @items = keys %$notelist; 2812: if (@items > 0) { 2813: push @$eof_todo, [ \&make_end_list, 'Note', $extra, $notes, @items ]; 2814: } 2816: } 2818: sub make_end_list { 2819: my ($title,$post_title,$loc,@items) = @_; 2820: # prepare a sorted (by gen num, if possible) list of IDs 2822: my %hash = (); #%$data; 2823: $hash{''} = 0; 2824: 2825: INNER: foreach my $id (@items) { 2826: my $num = read_gen_numbering($id); 2827: if (ref $num) { 2828: $num->reset; 2829: if (defined $num->read) { 2830: $num->reset; 2831: $num = join '',$num->read; 2832: } else { 2833: $num = ''; 2834: } 2835: } 2836: if (defined($num) && $num ne '') { 2837: if ($num =~ /^\d+$/) { 2838: $hash{$id} = 0 + $num; 2839: } elsif (exists $footnote_map{$num}) { 2840: $hash{$id} = 0 + $footnote_map{$num}; 2841: } else { 2842: warn "WARN:close_section_file:$title $id has unexpected ". 2843: "marker:[$num]\n"; 2844: } 2845: } else { 2846: warn "WARN:close_section_file:$title $id without ". 2847: "marker at end of section\n"; 2848: $hash{$id} = 99999; 2849: } 2850: } 2851: 2852: @items = sort { 2853: ($hash{$a} <=> $hash{$b}) || 2854: ($a cmp $b); 2855: } @items; 2856: 2857: # print title 2858: my $plural = (@items == 1) ? '' : 's'; 2859: print $loc "<hr>\n<h3 class='sect-title'>" . 2860: $title . $plural . $post_title . "</h3>\n"; 2861: # print tag 2862: print $loc "<table $layout_table_attr class='"; 2863: if ($title eq 'Reference') { 2864: print $loc "numbered-ref-list"; 2865: } elsif ($title eq 'Note') { 2866: print $loc "note-list"; 2867: } 2868: print $loc "'>\n"; 2869: # print list entries 2870: foreach my $id (@items) { 2871: print $loc &read_ID_content($id); 2872: } 2873: #close tag 2874: print $loc "</table>\n"; 2875: } 2877: sub check_for_id { 2878: my ($sgml,$element) = @_; 2879: my ($attr,$val,$file,$content,@content); 2880: #croak "screwed up" if (! ref $element); 2881: $attr = $element->attr('ID'); 2882: $val = ''; 2883: if (defined $attr) { 2884: @content = $attr->value; 2885: foreach $content (@content) { 2886: if (ref $content) { 2887: if (ref $content eq 'SGML::SData') { 2888: $val .= "<!--SDATA:-->" if $do_comments; 2889: } else { 2890: warn "WARN:Unexpected type for attribute content: ".(ref $content); 2891: } 2892: } else { 2893: $val .= lc $content; 2894: } 2895: } 2896: if ($val ne '') { 2897: $file = $sgml->stack('Section File'); 2898: set_ID_file($val,$file); 2899: return '<A NAME="' . $val . '"></A>'; 2900: } else { 2901: return ''; 2902: } 2903: } else { 2904: #warn "Check for ID on element with no ID attribute [".$element->name."]"; 2905: return ""; 2906: } 2907: } 2909: sub read_ID_content { 2910: my ($id) = @_; 2911: $id =~ tr/A-Z/a-z/; 2912: if (!defined $ID_Content{$id}) { 2913: $ID_Content{$id} = Data::Locations::Shell->new("/dev/null"); 2914: } 2916: return $ID_Content{$id}; 2917: } 2919: sub set_ID_content { 2920: my ($id,$file) = @_; 2921: $id =~ tr/A-Z/a-z/; 2922: if (defined $ID_Content{$id}) { 2923: #$ID_Content{$id}->delete; 2924: $ID_Content{$id}->print($file); 2925: } else { 2926: $ID_Content{$id} = Data::Locations::Shell->new("/dev/null"); 2927: $ID_Content{$id}->print($file); 2928: } 2930: return $ID_Content{$id}; 2931: } 2933: sub read_ID_file { 2934: my ($id) = @_; 2935: $id =~ tr/A-Z/a-z/; 2936: if (!defined $ID_File{$id}) { 2937: $ID_File{$id} = Data::Locations::Shell->new("/dev/null"); 2938: } 2940: return $ID_File{$id}; 2941: } 2943: sub set_ID_file { 2944: my ($id,$file) = @_; 2945: $id =~ tr/A-Z/a-z/; 2946: if (defined $ID_File{$id}) { 2947: #$ID_File{$id}->delete; 2948: $ID_File{$id}->print($file); 2949: } else { 2950: $ID_File{$id} = Data::Locations::Shell->new("/dev/null"); 2951: $ID_File{$id}->print($file); 2952: } 2954: return $ID_File{$id}; 2955: } 2957: sub read_gen_numbering { 2958: my ($id) = @_; 2959: $id =~ tr/A-Z/a-z/; 2960: if (!defined $Label{$id}) { 2961: $Label{$id} = Data::Locations::Shell->new("/dev/null"); 2962: } 2964: return $Label{$id}; 2965: } 2967: sub set_gen_numbering { 2968: my ($id,$label) = @_; 2969: $id =~ tr/A-Z/a-z/; 2970: if (defined $Label{$id}) { 2971: #$Label{$id}->delete; 2972: $Label{$id}->print($label); 2973: } else { 2974: $Label{$id} = Data::Locations::Shell->new("/dev/null"); 2975: $Label{$id}->print($label); 2976: } 2978: return $Label{$id}; 2979: } 2981: sub gen_numbering_dual { 2982: my ($element) = @_; 2983: my $numbered = $element->attr('NUMBERED'); 2984: if (defined $numbered && ref $numbered) { 2985: $numbered = $numbered->value; 2986: } else { 2987: warn "WARN:Attempted to gen_numbering_dual for element without NUMBERED attribute: '".$element->name."'\n"; 2988: } 2989: if ($numbered != 1) { 2990: return ""; 2991: } 2992: #if ($element->name eq 'EQUATION') { 2993: # my ($k,$atref); 2994: # $atref = $element->[2]; 2995: # warn "Equation Attributes:\n"; 2996: # foreach $k (keys %$atref) { 2997: # warn "EQ:$k:".$$atref{$k}->value."\n"; 2998: # } 2999: # return "HORK"; 3000: #} 3001: if ((ref($element) ne 'SGML::Element') || 3002: (ref($element->attr('ID')) ne 'SGML::Attribute') || 3003: (ref($element->attr('INCREASE.FIRST')) ne 'SGML::Attribute') || 3004: (ref($element->attr('SECOND.LEVEL')) ne 'SGML::Attribute')) { 3005: my ($atth,$att); 3006: warn "WARNING:Invalid object structure in gen_numbering_dual. debugging ".$element->name.":\n"; 3007: $atth = $element->attributes; 3008: foreach $att (keys %$atth) { 3009: #my $self = $$atth{$att}; 3010: my $attribute = $$atth{$att}; 3011: warn "A:". ($element->attr($att)->name) . "\n"; 3012: #$element->attr($att)->accept($self,$depth + 2, @_); 3013: #warn ("Attribute: ".($$self{'name'})."\n"); 3014: warn ("defaulted\n") if $attribute->is_defaulted; 3015: warn ("current\n") if $attribute->is_current; 3016: warn ("specified\n") if $attribute->is_specified; 3017: warn ("invalid\n") if $attribute->is_invalid; 3018: warn ("implied\n") if $attribute->is_implied; 3019: warn ("data\n") if $attribute->is_data; 3020: warn ("tokenized\n") if $attribute->is_tokenized; 3021: my $contents = $attribute->value(); 3022: #$"=']['; 3023: warn "V:[$contents]\n"; 3024: } 3025: 3026: 3027: return "[[DEBUGTHIS]]"; 3028: } 3029: my ($name,$id) = ($element->name,$element->attr('ID')->value); 3030: my ($label); 3031: $name =~ tr/A-Z/a-z/; 3032: $id =~ tr/A-Z/a-z/; 3034: if ($element->attr('INCREASE.FIRST')->value eq "1") { 3035: $Label_Prime{$name} += 1; 3036: } 3037: if ($element->attr('SECOND.LEVEL')->value =~ /^increase/i) { 3038: $Label_Sub{$name}++; # magic auto-increment 3039: } elsif ($element->attr('SECOND.LEVEL')->value =~ /^reset/i) { 3040: $Label_Sub{$name} = "a"; 3041: } 3042: if ($element->attr('SECOND.LEVEL')->value =~ /^no/i) { 3043: $label = "" . $Label_Prime{$name}; 3044: } else { 3045: if ($name eq "table" || $name eq 'fig') { 3046: $label = "" . $Label_Prime{$name} . "(" . $Label_Sub{$name} . ")"; 3047: } else { 3048: $label = "" . $Label_Prime{$name} . $Label_Sub{$name}; 3049: } 3050: } 3051: if (defined $Label{$id}) { 3052: #warn "Redefined label for $id\n"; 3053: #$Label{$id}->delete; 3054: $Label{$id}->print($label); 3055: } else { 3056: $Label{$id} = Data::Locations::Shell->new("/dev/null"); 3057: $Label{$id}->print($label); 3058: } 3060: return $Label{$id}; 3061: } 3063: sub gen_numbering_simple { 3064: my ($element) = @_; 3065: my ($name,$id) = ($element->name,$element->attr('ID')->value); 3066: my $label; 3067: $name =~ tr/A-Z/a-z/; 3068: $id =~ tr/A-Z/a-z/; 3069: $Label_Prime{$name} = 0 unless exists $Label_Prime{$name}; 3070: $Label_Prime{$name} += 1; 3071: $label = "" . $Label_Prime{$name}; 3073: if (defined $Label{$id}) { 3074: #warn "Redefined label for $id\n"; 3075: #$Label{$id}->delete; 3076: $Label{$id}->print($label); 3077: } else { 3078: $Label{$id} = Data::Locations::Shell->new("/dev/null"); 3079: $Label{$id}->print($label); 3080: } 3081: 3082: return $Label{$id}; 3083: } 3085: 3086: sub NumToTableNoteLetter { 3087: use integer; 3088: my ($num) = @_; 3089: my @let = ('a' .. 'z'); 3090: $num -= 1; # shift to 0 based 3091: my $count = $num / @let; 3092: my $l = $num - $count * @let; 3093: my $str = $let[$l] x ($count + 1); 3094: return $str; 3095: } 3097: # not used 3098: sub NumToLetter { 3099: my ($num) = @_; 3100: my $str = ''; 3101: my @let = ('a' .. 'z'); 3102: while ($num > 0) { 3103: use integer; 3104: $num -= 1; # shift to 0 based 3105: my $onum = $num; 3106: $num = $num / @let; 3107: my $l = $onum - $num * @let; 3108: $str .= $let[$l]; 3109: } 3110: return scalar reverse $str; #chr(ord('a')-1+$num); 3111: } 3113: # returns paths to full size and inline versions, and width and height 3114: sub LookupGraphic { 3115: my ($id,$class,$type) = @_; 3116: my ($pathfrag,$idtype,$idnum,$fheight,$fwidth,$iwidth,$iheight,$format, 3117: $iformat,%data,$urltofull,$urltoinline); 3119: $class = lc $class; 3120: $type = lc $type; 3121: $id = lc $id; 3123: #read database file 3124: %data = GetGraphicDBEntry($id); 3125: if (defined $data{'id'}) { 3126: $iheight = $data{'inline height'}; 3127: $iwidth = $data{'inline width'}; 3128: $iformat = $format = $data{'format'}; 3129: $iformat = 'png' unless $iformat eq 'jpg'; 3130: $urltofull = Graphic_ID_Expand_Path("/data1/httpd/root/graphics/detail", 3131: $id,$class,$iformat); 3132: $urltoinline = Graphic_ID_Expand_Path("/data1/httpd/root/graphics/inline", 3133: $id,$class,$iformat); 3134: } else { 3135: warn "WARN:Failed to find entry for $id in graphics database file\n"; 3136: $urltoinline = $urltofull = undef; 3137: $iheight = $iwidth = undef; 3138: } 3139: $urltofull = "/data1/httpd/root/graphics/ASMLogo.png" 3140: unless defined $urltofull; 3141: $urltoinline = "/data1/httpd/root/graphics/ASMLogo.png" 3142: unless defined $urltoinline; 3143: if (!defined $iwidth || !defined $iheight) { 3144: $iwidth = $iheight = 10; 3145: $urltoinline = "/data1/httpd/root/graphics/ASMLogo.png"; 3146: } 3147: 3148: my $pathtofull = $urltofull; 3149: my $pathtoinline = $urltoinline; 3150: $urltofull =~ s|^/data1/httpd/root||; 3151: $urltoinline =~ s|^/data1/httpd/root||; 3152: my $basefull = $pathtofull; 3153: my $baseinline = $pathtoinline; 3154: $basefull =~ s/(.*\/)//; 3155: $baseinline =~ s/(.*\/)//; 3157: if ($with_graphics_at eq 'local') { 3158: $urltofull = 'detail/' . $basefull; 3159: $urltoinline = $baseinline; 3160: symlink $pathtofull,$urltofull if $do_external_images{$class}; 3161: symlink $pathtoinline,$urltoinline; 3162: } elsif ($with_graphics_at eq 'division') { 3163: $urltofull = '../graphics/detail/' . $basefull; 3164: $urltoinline = '../graphics/inline/' . $baseinline; 3165: symlink $pathtofull,$urltofull if $do_external_images{$class}; 3166: symlink $pathtoinline,$urltoinline; 3167: } 3169: return ($urltofull,$urltoinline,$iwidth,$iheight); 3170: } 3173: sub TeXtoImage { 3174: use integer; 3175: my ($flags,@tex) = @_; 3176: my ($texexpr,$imagef,$tempf,$width,$height,$base_adj,$comment,$data, 3177: $line,%flag,$scale); 3178: #read flags 3179: $line = 0; 3180: foreach $data (split /\s+/,$flags) { 3181: if ($line == 0) { 3182: $line = 1; 3183: $imagef = $data; 3184: next; 3185: } 3186: if ($data =~ /^([^=]+)=(.*)$/) { 3187: $flag{lc $1} = lc $2; 3188: } else { 3189: $flag{lc $data} = 1; 3190: } 3191: } 3192: #construct the TeX expression 3193: $texexpr = ''; 3194: foreach $data (@tex) { 3195: if (ref $data) { 3196: #prob a location 3197: $data->reset; 3198: while (defined ($line = $data->read)) { 3199: $texexpr .= $line; 3200: } 3201: } else { 3202: $texexpr .= $data; 3203: } 3204: } 3205: #$texexpr =~ s/\s+/ /g; # drop newlines? 3206: $texexpr =~ s/\A\s+//s; 3207: $texexpr =~ s/\s+\Z//s; 3209: #check for existing image 3210: #warn "INFO:TeX:$imagef:".$texexpr."\n" ; 3211: if (-f $imagef) { 3212: if (! $flag{'force'}) { 3213: #scan image file 3214: warn "INFO:TeX:reusing:".$texexpr."\n" if $debug; 3215: ($comment,$width,$height) = 3216: Graphic_File_Data($imagef,'comments','width','height'); 3217: if (defined $comment) { 3218: if ($comment =~ /\A\s*v(\d+)\s+(-?\d+)\s+(.*?)\s*\Z/s && 3219: $1 == 1) { # comment data version 3220: my ($adj,$tex) = ($2,$3); 3221: if (! (0 > index $tex, '%')) { # undo my escape seqs 3222: $tex = join "\\", split '%/', $tex; 3223: $tex = join "\n", split '%n', $tex; 3224: $tex = join '%', split '%%', $tex; 3225: } 3226: if ($tex eq $texexpr) { 3227: #warn "DBG:TEX:reusing $comment\n"; 3228: return ($width,$height,$adj); 3229: } else { 3230: warn "DBG:TEX: [$texexpr] CANNOT reuse [$comment]\n"; 3231: } 3232: } else { 3233: warn "DBG:TEX: not reusing old [$comment]\n"; 3234: #chomp $comment; 3235: #return ($width,$height) if $comment eq $texexpr; 3236: } 3237: } 3238: } 3239: unlink $imagef; 3240: } 3241: #create new image 3242: $tempf = "$$"; 3243: open(TMP,">$tempf.tex") || return undef; 3244: print TMP "\\batchmode\\input amssym \\nopagenumbers"; 3245: print TMP "\\vbox{"; 3246: #print TMP "\\hrule width3pt"; # min width spacer 3247: print TMP "\\hrule\\hbox{"; 3248: #print TMP "\\hbox{\\vbox{\\hrule width2pt height0.2pt depth0.0pt}}"; 3249: #print TMP "\\vrule height1ex depth0"; #baseline marker 3250: print TMP "\\vrule width1pt depth0pt"; #baseline marker 3251: print TMP "\\setbox0=\\hbox{H}\\dimen0=\\ht0\\vbox to \\dimen0{}"; # min height spacer 3252: #print TMP "\\hbox{\\setbox0=\\hbox{H}\\vbox to \\ht0{\\hrule width0.1pt height0.1pt depth 0.0pt}}"; # min height spacer 3253: print TMP "\\vrule"; 3254: print TMP "\\kern0.2pt{\\vtop{\\vbox{\\kern0.2pt\\hbox{"; 3255: print TMP $texexpr; 3256: print TMP "}}\\kern0.2pt}}\\kern0.2pt"; 3257: print TMP "\\vrule"; 3258: print TMP "}\\hrule}"; 3259: print TMP "\\bye\n"; 3260: close TMP; 3261: unlink $tempf.".log" if -f $tempf.".log"; 3262: unlink $tempf.".dvi" if -f $tempf.".dvi"; 3263: warn "INFO:TeX:generating:".$texexpr."\n" if $debug; 3264: system 'tex',"$tempf.tex"; 3265: if (-f $tempf.".log" && `grep -c '^[!lL ]' $tempf.log` =~ /^[^0]/) { 3266: open TMP,"<$tempf.log"; 3267: warn "" . join("",<TMP>); 3268: close TMP; 3269: } 3270: if (-f "$tempf.dvi") { 3271: unlink "$tempf.tex"; 3272: unlink "$tempf.log"; 3273: } else { 3274: warn "WARN:TeX:Failed to generate DVI from TeX: $texexpr\n"; 3275: return undef; 3276: } 3277: unlink $tempf.".eps" if -f $tempf.".eps"; 3278: system 'dvips','-q',"-E","-D","600",'-x','4750',"-o","$tempf.eps","$tempf.dvi"; 3279: if (-f "$tempf.eps") { 3280: unlink "$tempf.dvi"; 3281: } else { 3282: warn "WARN:TeX:Failed to generate PS image from DVI: $texexpr\n"; 3283: return undef; 3284: } 3285: unlink $tempf.".bmp" if -f $tempf.".bmp"; 3286: system("convert", 3287: "-density","600", #set PS resolution 3288: "-monochrome", 3289: "-bordercolor","white","-border","5x5", #insure outer white border 3290: "-pen","black","-draw","color 1,1 floodfill", #fill around box 3291: "-crop","0x0", #crop box 3292: "$tempf.eps","$tempf.bmp"); 3293: system("convert", 3294: "-density","600", #set PS resolution 3295: "-monochrome", 3296: "-bordercolor","white","-border","5x5", #insure outer white border 3297: #"-pen","black","-draw","color 1,1 floodfill", #fill around box 3298: "-crop","0x0", #crop white box 3299: "-crop","0x0", #crop black box 3300: "$tempf.eps","$tempf-size.bmp"); 3301: #if ($imagef =~ /emsp/) { 3302: # warn "DBG:TEX:emsp:$tempf\n"; 3303: # system('cp', "$tempf-size.bmp","emsp-size.bmp"); 3304: # system('cp', "$tempf.bmp", "emsp-img.bmp"); 3305: #} 3307: if (-f "$tempf.bmp") { 3308: unlink "$tempf.eps"; 3309: } else { 3310: warn "WARN:TeX:Failed to generate BMP from PS image for TeX: $texexpr\n"; 3311: return undef; 3312: } 3313: unlink $tempf."-slice.bmp", $tempf."-space.bmp"; 3314: $width = Graphic_File_Data($tempf."-size.bmp",'width'); 3315: system("convert", 3316: "-crop","-".($width-1)."+0", #slice off all but left edge 3317: $tempf."-size.bmp",$tempf."-slice.bmp"); 3318: system("convert", 3319: "-bordercolor","black","-border","5x5", #insure outer white border 3320: #"-pen","black","-draw","color 1,1 floodfill", #fill around box 3321: "-crop","0x0", #crop box 3322: $tempf."-slice.bmp",$tempf."-space.bmp"); 3323: my $h_all = Graphic_File_Data($tempf."-slice.bmp",'height'); 3324: my $h_depth = Graphic_File_Data($tempf."-space.bmp",'height'); 3325: if (! defined $h_depth || $h_depth == 0) { 3326: $base_adj = 0; 3327: } else { 3328: $base_adj = 0 - (100 * $h_depth)/$h_all; 3329: } 3330: unlink $tempf."-slice.bmp", $tempf."-size.bmp", $tempf."-space.bmp"; 3331: 3332: #system("mogrify", 3333: # "-monochrome", 3334: # "-crop","0x0", #crop outside white space 3335: # "$tempf.bmp"); 3336: #system 'cp',$tempf.".bmp",$imagef."-crop.bmp"; 3337: $flag{'size'} = 'normal' unless defined $flag{'size'}; 3338: if ($flag{'size'} eq 'large') { 3339: $scale = '10%x10%'; 3340: } else { 3341: $scale = '5%x5%'; 3342: } 3343: unlink $tempf."-s.bmp" if -f $tempf."-s.bmp"; 3344: system "convert","-geometry",$scale,"$tempf.bmp",$tempf."-s.bmp"; 3345: #system 'cp',$tempf.".bmp",$imagef."-scale.bmp"; 3346: if (-f $tempf."-s.bmp") { 3347: unlink $tempf . ".bmp"; 3348: } else { 3349: warn "WARN:TeX:Failed to reduce BMP for TeX: $texexpr\n"; 3350: return undef; 3351: } 3352: unlink $imagef if -f $imagef; 3353: system("convert","-density","25",$tempf."-s.bmp","$imagef"); 3354: if (-f $imagef) { 3355: unlink $tempf . "-s.bmp"; 3356: } else { 3357: warn "WARN:TeX:Failed to reduce BMP to $imagef for TeX: $texexpr\n"; 3358: return undef; 3359: } 3361: # have to escape \n because imagemagick changes it to newline, but no \\ 3362: # use %, a TeX special char (comment starter, I think) 3363: $texexpr = join('%%', split '%', $texexpr); 3364: $texexpr = join('%n', split /\n/s, $texexpr); 3365: $texexpr = join('%/', split /\\/, $texexpr); 3367: system("mogrify","-comment","v1 ".$base_adj." ".$texexpr,$imagef); 3368: ($width,$height) = Graphic_File_Data($imagef,'width','height'); 3369: if (defined $width && defined $height) { 3370: return ($width,$height,$base_adj); 3371: } 3372: return undef; 3373: } 3375: #adds to current count set 3376: sub Count_Increment { 3377: my ($sgml,$count) = @_; 3378: my ($ref); 3379: if ($sgml->stack_exists("$count count")) { 3380: $ref = $sgml->stackrefs("$count count"); 3381: $$ref += 1 if defined $$ref; 3382: } 3383: } 3385: sub ReadArgs { 3386: my (@args) = @_; 3387: my ($arg,$val,$oarg,@nonargs,$noscan); 3389: $noscan = 0; 3390: @nonargs = (); 3391: foreach $oarg (@args) { 3392: if ($noscan) { 3393: push @nonargs,$oarg; 3394: } elsif ($oarg eq '--') { 3395: $noscan = 1; 3396: } elsif ($oarg =~ /^-([^-].*)$/) { 3397: ReadArgs('--verbose') if ($oarg =~ /v/); 3398: ReadArgs('--debug') if ($oarg =~ /d/); 3399: ReadArgs('--debug=99') if ($oarg =~ /D/); 3400: ReadArgs('--help') if ($oarg =~ /h/); 3401: } elsif ($oarg =~ /^--([^=]+)(=(.*))?$/) { 3402: $arg = $1; 3403: $val = $3; 3404: if ($arg eq 'manuscript') { 3405: $do_manuscript = 1; 3406: } elsif ($arg eq 'one-big-page') { 3407: $do_section_split = 0; 3408: } elsif ($arg eq 'hide-comments') { 3409: $do_comments = 0; 3410: } elsif ($arg eq 'show-comments') { 3411: $do_comments = 1; 3412: } elsif ($arg eq 'show-table-lines') { 3413: $show_borders = 1; 3414: } elsif ($arg eq 'hide-table-lines') { 3415: $show_borders = 0; 3416: } elsif ($arg eq 'subfile-toc') { 3417: $do_subfile_toc = 1; 3418: } elsif ($arg eq 'full-toc') { 3419: $do_full_toc = 1; 3420: } elsif ($arg eq 'id-path') { 3421: $topleveldir = $val; 3422: $topleveldirtype = 'id'; 3423: } elsif ($arg eq 'content-path') { 3424: $topleveldir = $val; 3425: $topleveldirtype = 'content'; 3426: } elsif ($arg eq 'article-path') { 3427: $topleveldir = $val; 3428: $topleveldirtype = 'article'; 3429: } elsif ($arg eq 'division-path') { 3430: $topleveldir = $val; 3431: $topleveldirtype = 'division'; 3432: } elsif ($arg eq 'volume-path') { 3433: $topleveldir = $val; 3434: $topleveldirtype = 'volume'; 3435: } elsif ($arg eq 'stylesheet') { 3436: $do_stylesheet = 1; 3437: $stylesheet = $val; 3438: } elsif ($arg eq 'purge-before') { 3439: $do_purge_before = 1; 3440: } elsif ($arg eq 'graphics') { 3441: $with_graphics_at = $val 3442: } elsif ($arg eq 'debug') { 3443: if (defined $val && $val ne '') { 3444: $debug = $val; 3445: } else { 3446: $debug = 1; 3447: } 3448: $do_comments = 1 if $debug; 3449: } elsif ($arg eq 'help') { 3450: print STDOUT " 3451: $0 [arguments] sgmlfile1 sgmlfile2 ... 3453: Command line arguments: 3454: --help Print helpful summary 3455: --debug[=VAL] Turn on debugging (set debug level to VAL) 3456: --manuscript Prepare manuscript review version 3457: --stylesheet=FILE Use stylesheet formatting (include stylesheet FILE) 3458: --hide-comments Hide processing comments from output 3459: --show-comments Opposite of above 3460: --one-big-page Output as a single html page, no splitting 3461: --show-table-lines Show all table borders (includes formatting tables) 3462: --purge-before Delete article directory before processing 3463: --graphics=TOKEN Use local, division level, or absolute link paths 3464: --subfile-toc Include table of contents in section files 3465: --full-toc List runin sections in table of contents 3466: Only one of the following should be specified (last one will override): 3467: --content-path=PATH Directory to write article contents in 3468: --article-path=PATH Directory to create article (NUM) directories in 3469: --division-path=PATH Directory to create division directories in 3470: --volume-path=PATH Directory to create volume directories in 3471: --id-path=PATH Directory to create article (ID) directories in 3473: Note that all arguments are read and take effect before any processing. 3474: "; 3475: exit; 3476: } else { 3477: die "$0: Unrecognized argument: $arg\n"; 3478: } 3479: } else { 3480: push @nonargs,$oarg; 3481: } 3482: } 3483: 3484: return wantarray ? @nonargs : 0 == @nonargs; 3485: } 3488: 1;