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;