texi2html
来自「FFTW, a collection of fast C routines to」· 代码 · 共 2,095 行 · 第 1/4 页
TXT
2,095 行
# $tag = ''; $end_tag = ''; if (/^\@end\s+(\w+)\b/) { $end_tag = $1; } elsif (/^\@(\w+)\b/) { $tag = $1; } # # handle @ifhtml / @end ifhtml # if ($in_html) { if ($end_tag eq 'ifhtml') { $in_html = 0; } else { $tag2pro{$in_html} .= $_; } next; } elsif ($tag eq 'ifhtml') { $in_html = $PROTECTTAG . ++$html_num; push(@lines, $in_html); next; } # # try to skip the line # if ($end_tag) { next if $to_skip{"end $end_tag"}; } elsif ($tag) { next if $to_skip{$tag}; last if $tag eq 'bye'; } if ($in_top) { # parsing the top node if ($tag eq 'node' || $tag eq 'include' || $sec2level{$tag}) { # no more in top $in_top = 0; } else { # skip it next; } } # # try to remove inlined comments # syntax from tex-mode.el comment-start-skip # s/((^|[^\@])(\@\@)*)\@c(omment)? .*/$1/; # non-@ substitutions cf. texinfmt.el unless ($in_pre) { s/``/\"/g; s/''/\"/g; s/([\w ])---([\w ])/$1--$2/g; } # # analyze the tag # if ($tag) { # skip lines &skip_until($tag), next if $tag eq 'ignore'; if ($expandinfo) { &skip_until($tag), next if $tag eq 'iftex'; } else { &skip_until($tag), next if $tag eq 'ifinfo'; } &skip_until($tag), next if $tag eq 'tex'; # handle special tables if ($tag =~ /^(|f|v|multi)table$/) { $table_type = $1; $tag = 'table'; } # special cases if ($tag eq 'top' || ($tag eq 'node' && /^\@node\s+top\s*,/i)) { $in_top = 1; @lines = (); # ignore all lines before top (title page garbage) next; } elsif ($tag eq 'node') { $in_top = 0; warn "$ERROR Bad node line: $_" unless $_ =~ /^\@node\s$NODESRE$/o; $_ = &protect_html($_); # if node contains '&' for instance s/^\@node\s+//; ($node) = split(/,/); &normalise_node($node); if ($split_node) { &next_doc; push(@lines, $SPLITTAG) if $split_num++; push(@sections, $node); } next; } elsif ($tag eq 'include') { if (/^\@include\s+($FILERE)\s*$/o) { $file = $1; unless (-e $file) { foreach $dir (@include_dirs) { $file = "$dir/$1"; last if -e $file; } } if (-e $file) { &open($file); print "# including $file\n" if $verbose; } else { warn "$ERROR Can't find $file, skipping"; } } else { warn "$ERROR Bad include line: $_"; } next; } elsif ($tag eq 'ifclear') { if (/^\@ifclear\s+($VARRE)\s*$/o) { next unless defined($value{$1}); &skip_until($tag); } else { warn "$ERROR Bad ifclear line: $_"; } next; } elsif ($tag eq 'ifset') { if (/^\@ifset\s+($VARRE)\s*$/o) { next if defined($value{$1}); &skip_until($tag); } else { warn "$ERROR Bad ifset line: $_"; } next; } elsif ($tag eq 'menu') { unless ($show_menu) { &skip_until($tag); next; } &html_push_if($tag); push(@lines, &html_debug("\n", __LINE__)); } elsif ($format_map{$tag}) { $in_pre = 1 if $format_map{$tag} eq 'PRE'; &html_push_if($format_map{$tag}); push(@lines, &html_debug("\n", __LINE__)); $in_list++ if $format_map{$tag} eq 'UL' || $format_map{$tag} eq 'OL' ; push(@lines, &debug("<$format_map{$tag}>\n", __LINE__)); next; } elsif ($tag eq 'table') { if (/^\@(|f|v|multi)table\s+\@(\w+)/) { $in_table = $2; unshift(@tables, join($;, $table_type, $in_table)); if ($table_type eq "multi") { push(@lines, &debug("<TABLE BORDER>\n", __LINE__)); &html_push_if('TABLE'); } else { push(@lines, &debug("<DL COMPACT>\n", __LINE__)); &html_push_if('DL'); } push(@lines, &html_debug("\n", __LINE__)); } else { warn "$ERROR Bad table line: $_"; } next; } elsif ($tag eq 'synindex' || $tag eq 'syncodeindex') { if (/^\@$tag\s+(\w\w?)\s+(\w\w?)\s*$/) { eval("*${1}index = *${2}index"); } else { warn "$ERROR Bad syn*index line: $_"; } next; } elsif ($tag eq 'sp') { push(@lines, &debug("<P>\n", __LINE__)); next; } elsif ($tag eq 'setref') { &protect_html; # if setref contains '&' for instance if (/^\@$tag\s*{($NODERE)}\s*$/) { $setref = $1; $setref =~ s/\s+/ /g; # normalize $setref =~ s/ $//; $node2sec{$setref} = $name; $node2href{$setref} = "$docu_doc#$docid"; } else { warn "$ERROR Bad setref line: $_"; } next; } elsif ($tag eq 'defindex' || $tag eq 'defcodeindex') { if (/^\@$tag\s+(\w\w)\s*$/) { $valid_index{$1} = 1; } else { warn "$ERROR Bad defindex line: $_"; } next; } elsif (defined($def_map{$tag})) { if ($def_map{$tag}) { s/^\@$tag\s+//; $tag = $def_map{$tag}; $_ = "\@$tag $_"; $tag =~ s/\s.*//; } } elsif (defined($user_sub{$tag})) { s/^\@$tag\s+//; $sub = $user_sub{$tag}; print "# user $tag = $sub, arg: $_" if $debug & $DEBUG_USER; if (defined(&$sub)) { chop($_); &$sub($_); } else { warn "$ERROR Bad user sub for $tag: $sub\n"; } next; } if (defined($def_map{$tag})) { s/^\@$tag\s+//; if ($tag =~ /x$/) { # extra definition line $tag = $`; $is_extra = 1; } else { $is_extra = 0; } while (/\{([^\{\}]*)\}/) { # this is a {} construct ($before, $contents, $after) = ($`, $1, $'); # protect spaces $contents =~ s/\s+/$;9/g; # restore $_ protecting {} $_ = "$before$;7$contents$;8$after"; } @args = split(/\s+/, &protect_html($_)); foreach (@args) { s/$;9/ /g; # unprotect spaces s/$;7/\{/g; # ... { s/$;8/\}/g; # ... } } $type = shift(@args); $type =~ s/^\{(.*)\}$/$1/; print "# def ($tag): {$type} ", join(', ', @args), "\n" if $debug & $DEBUG_DEF; $type .= ':'; # it's nicer like this $name = shift(@args); $name =~ s/^\{(.*)\}$/$1/; if ($is_extra) { $_ = &debug("<DT>", __LINE__); } else { $_ = &debug("<DL>\n<DT>", __LINE__); } if ($tag eq 'deffn' || $tag eq 'defvr' || $tag eq 'deftp') { $_ .= "<U>$type</U> <B>$name</B>"; $_ .= " <I>@args</I>" if @args; } elsif ($tag eq 'deftypefn' || $tag eq 'deftypevr' || $tag eq 'defcv' || $tag eq 'defop') { $ftype = $name; $name = shift(@args); $name =~ s/^\{(.*)\}$/$1/; $_ .= "<U>$type</U> $ftype <B>$name</B>"; $_ .= " <I>@args</I>" if @args; } else { warn "$ERROR Unknown definition type: $tag\n"; $_ .= "<U>$type</U> <B>$name</B>"; $_ .= " <I>@args</I>" if @args; } $_ .= &debug("\n<DD>", __LINE__); $name = &unprotect_html($name); if ($tag eq 'deffn' || $tag eq 'deftypefn') { unshift(@input_spool, "\@findex $name\n"); } elsif ($tag eq 'defop') { unshift(@input_spool, "\@findex $name on $ftype\n"); } elsif ($tag eq 'defvr' || $tag eq 'deftypevr' || $tag eq 'defcv') { unshift(@input_spool, "\@vindex $name\n"); } else { unshift(@input_spool, "\@tindex $name\n"); } $dont_html = 1; } } elsif ($end_tag) { if ($format_map{$end_tag}) { $in_pre = 0 if $format_map{$end_tag} eq 'PRE'; $in_list-- if $format_map{$end_tag} eq 'UL' || $format_map{$end_tag} eq 'OL' ; &html_pop_if('LI', 'P'); &html_pop_if(); push(@lines, &debug("</$format_map{$end_tag}>\n", __LINE__)); push(@lines, &html_debug("\n", __LINE__)); } elsif ($end_tag =~ /^(|f|v|multi)table$/) { unless (@tables) { warn "$ERROR \@end $end_tag without \@*table\n"; next; } ($table_type, $in_table) = split($;, shift(@tables)); unless ($1 eq $table_type) { warn "$ERROR \@end $end_tag without matching \@$end_tag\n"; next; } if ($table_type eq "multi") { push(@lines, "</TR></TABLE>\n"); &html_pop_if('TR'); } else { push(@lines, "</DL>\n"); &html_pop_if('DD'); } &html_pop_if(); if (@tables) { ($table_type, $in_table) = split($;, $tables[0]); } else { $in_table = 0; } } elsif (defined($def_map{$end_tag})) { push(@lines, &debug("</DL>\n", __LINE__)); } elsif ($end_tag eq 'menu') { &html_pop_if(); push(@lines, $_); # must keep it for pass 2 } next; } # # misc things # # protect texi and HTML things &protect_texi; $_ = &protect_html($_) unless $dont_html; $dont_html = 0; # substitution (unsupported things) s/^\@center\s+//g; s/^\@exdent\s+//g; s/\@noindent\s+//g; s/\@refill\s+//g; # other substitutions &simple_substitutions; s/\@value{($VARRE)}/$value{$1}/eg; s/\@footnote\{/\@footnote$docu_doc\{/g; # mark footnotes, cf. pass 4 # # analyze the tag again # if ($tag) { if (defined($sec2level{$tag}) && $sec2level{$tag} > 0) { if (/^\@$tag\s+(.+)$/) { $name = $1; $name =~ s/\s+$//; $level = $sec2level{$tag}; $name = &update_sec_num($tag, $level) . " $name" if $number_sections && $tag !~ /^unnumbered/; if ($tag =~ /heading$/) { push(@lines, &html_debug("\n", __LINE__)); if ($html_element ne 'body') { # We are in a nice pickle here. We are trying to get a H? heading # even though we are not in the body level. So, we convert it to a # nice, bold, line by itself. $_ = &debug("\n\n<P><STRONG>$name</STRONG>\n\n", __LINE__); } else { $_ = &debug("<H$level>$name</H$level>\n", __LINE__); &html_push_if('body'); } print "# heading, section $name, level $level\n" if $debug & $DEBUG_TOC; } else { if ($split_chapter) { unless ($toplevel) { # first time we see a "section" unless ($level == 1) { warn "$ERROR The first section found is not of level 1: $_"; warn "$ERROR I'll split on sections of level $level...\n"; } $toplevel = $level; } if ($level == $toplevel) { &next_doc; push(@lines, $SPLITTAG) if $split_num++; push(@sections, $name); } } $sec_num++; $docid = "SEC$sec_num"; $tocid = "TOC$sec_num"; # check biblio and glossary $in_bibliography = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*bibliography$/i); $in_glossary = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*glossary$/i); # check node if ($node) { if ($node2sec{$node}) { warn "$ERROR Duplicate node found: $node\n"; } else { $node2sec{$node} = $name; $node2href{$node} = "$docu_doc#$docid"; print "# node $node, section $name, level $level\n" if $debug & $DEBUG_TOC; } $node = ''; } else { print "# no node, section $name, level $level\n" if $debug & $DEBUG_TOC; } # update TOC while ($level > $curlevel) { $curlevel++; push(@toc_lines, "<UL>\n"); } while ($level < $curlevel) { $curlevel--; push(@toc_lines, "</UL>\n"); } $_ = "<LI>" . &anchor($tocid, "$docu_doc#$docid", $name, 1); push(@toc_lines, &substitute_style($_)); # update DOC push(@lines, &html_debug("\n", __LINE__)); &html_reset; if ($no_toc_href) { $_ = "<H$level>" . &anchor($docid, "", $name) . "</H$level>\n"; } else { $_ = "<H$level>" . &anchor($docid, "$docu_toc#$tocid", $name) . "</H$level>\n"; } $_ = &debug($_, __LINE__); push(@lines, &html_debug("\n", __LINE__)); } # update DOC foreach $line (split(/\n+/, $_)) { push(@lines, "$line\n"); } next; } else { warn "$ERROR Bad section line: $_"; } } else { # track variables $value{$1} = $2, next if /^\@set\s+($VARRE)\s+(.*)$/o; delete $value{$1}, next if /^\@clear\s+($VARRE)\s*$/o; # store things $value{'_setfilename'} = $1, next if /^\@setfilename\s+(.*)$/; $value{'_settitle'} = $1, next if /^\@settitle\s+(.*)$/; $value{'_author'} .= "$1\n", next if /^\@author\s+(.*)$/; $value{'_subtitle'} .= "$1\n", next if /^\@subtitle\s+(.*)$/; $value{'_title'} .= "$1\n", next if /^\@title\s+(.*)$/; # index if (/^\@(..?)index\s+/) { unless ($valid_index{$1}) { warn "$ERROR Undefined index command: $_"; next; } $id = 'IDX' . ++$idx_num; $index = $1 . 'index'; $what = &substitute_style($'); $what =~ s/\s+$//; print "# found $index for '$what' id $id\n" if $debug & $DEBUG_INDEX; eval(<<EOC); if (defined(\$$index\{\$what\})) { \$$index\{\$what\} .= "$;$docu_doc#$id"; } else { \$$index\{\$what\} = "$docu_doc#$id"; }EOC # # dirty hack to see if I can put an invisible anchor... # if ($html_element eq 'P' || $html_element eq 'LI' || $html_element eq 'DT' || $html_element eq 'DD' || $html_element eq 'ADDRESS' || $html_element eq 'B' || $html_element eq 'BLOCKQUOTE' || $html_element eq 'PRE' || $html_element eq 'SAMP') { push(@lines, &anchor($id, '', $invisible_mark, !$in_pre)); } elsif ($html_element eq 'body') { push(@lines, &debug("<P>\n", __LINE__)); push(@lines, &anchor($id, '', $invisible_mark, !$in_pre)); &html_push('P'); } elsif ($html_element eq 'DL' || $html_element eq 'UL' || $html_element eq 'OL' ) { $deferred_ref .= &anchor($id, '', $invisible_mark, !$in_pre) . " "; } next; } # list item if (/^\@itemx?\s+/) { $what = $'; $what =~ s/\s+$//; if ($in_bibliography && $use_bibliography) { if ($what =~ /^$BIBRE$/o) { $id = 'BIB' . ++$bib_num; $bib2href{$what} = "$docu_doc#$id"; print "# found bibliography for '$what' id $id\n" if $debug & $DEBUG_BIB; $what = &anchor($id, '', $what); } } elsif ($in_glossary && $use_glossary) { $id = 'GLOSS' . ++$gloss_num; $entry = $what; $entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/; $gloss2href{$entry} = "$docu_doc#$id"; print "# found glossary for '$entry' id $id\n" if $debug & $DEBUG_GLOSS; $what = &anchor($id, '', $what); } &html_pop_if('P'); if ($html_element eq 'DL' || $html_element eq 'DD') { if ($things_map{$in_table} && !$what) { # special case to allow @table @bullet for instance push(@lines, &debug("<DT>$things_map{$in_table}\n", __LINE__)); } else { push(@lines, &debug("<DT>\@$in_table\{$what\}\n", __LINE__)); } push(@lines, "<DD>"); &html_push('DD') unless $html_element eq 'DD'; if ($table_type) { # add also an index unshift(@input_spool, "\@${table_type}index $what\n"); } } elsif ($html_element eq 'TABLE') { push(@lines, &debug("<TR><TD>$what</TD>\n", __LINE__)); &html_push('TR'); } elsif ($html_element eq 'TR') { push(@lines, &debug("</TR>\n", __LINE__)); push(@lines, &debug("<TR><TD>$what</TD>\n", __LINE__)); } else { push(@lines, &debug("<LI>$what\n", __LINE__)); &html_push('LI') unless $html_element eq 'LI'; } push(@lines, &html_debug("\n", __LINE__)); if ($deferred_ref) { push(@lines, &debug("$deferred_ref\n", __LINE__)); $deferred_ref = ''; } next; } elsif (/^\@tab\s+(.*)$/) { push(@lines, "<TD>$1</TD>\n"); next; } } } # paragraph separator if ($_ eq "\n") { next if $#lines >= 0 && $lines[$#lines] eq "\n"; if ($html_element eq 'P') {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?