#! /usr/bin/env perl # Convert fdsymbol.sty to a faked version that does not require # the definition of any additional math alphabets # # By Scott Pakin use POSIX; use warnings; use strict; # Define a subroutine to construct text and display delimiters. sub output_delimiter ($$$$$$$) { my ($name, $smclass, $small, $top, $mid, $bot, $rep) = @_; if ($smclass eq "fake") { printf '\DeclareRobustCommand{\FDSYMt%s}{{\usefont{U}{FdSymbolF}{m}{n}\raisebox{0pt}{\CLSLfaketdelim{%d}{%d}{%d}}}}%s', $name, $top, $mid, $bot, "\n"; } else { printf '\DeclareRobustCommand{\FDSYMt%s}{{\usefont{U}{FdSymbol%s}{m}{n}\char%d}}%s', $name, $smclass, $small, "\n"; } printf '\DeclareRobustCommand{\FDSYMd%s}{{\usefont{U}{FdSymbolF}{m}{n}\raisebox{20pt}{\CLSLfakeddelim{%d}{%d}{%d}{%d}}}}%s', $name, $top, $mid, $bot, $rep, "\n"; } # Define a subroutine to construct an extensible accent. sub output_accent ($$$$$) { my ($name, $smraise, $smchar, $lgraise, $lgchar) = @_; printf '\DeclareRobustCommand{\FDSYM%s}[1]{\CLSLfakewidetopaccent{#1}{%dpt}{%d}{%dpt}{%d}{{U}{FdSymbolE}{m}{n}}}%s', $name, $smraise, $smchar, $lgraise, $lgchar, "\n"; } # Output some header boilerplate. print "\%" x 43, "\n"; print "\% This is a generated file. DO NOT EDIT. \%\n"; print "\%" x 43, "\n"; print "\n"; # Read and process fdsymbol.sty. my $seen_symfont = 0; # 1=we've seen a \DeclareSymbolFont; 1=we haven't my $slot = 0; # Current character slot my $lastsym; # Name of last symbol declared my $ignored_conditional = 0; # 1=on false branch of conditional; 0=true branch or not in conditional while (my $oneline = <>) { chomp $oneline; # Output some package header information. if ($oneline =~ /NeedsTeXFormat/o) { print $oneline, "\n"; next; } if ($oneline =~ /ProvidesPackage/o) { $oneline =~ s/fdsymbol/fakefdsymbol/; $oneline =~ s/FdSymbol/faked FdSymbol/; print $oneline, "\n\n"; next; } # Handle conditionals. if ($oneline =~ /^\\fi\s*$/) { $ignored_conditional = 0; next; } if ($oneline =~ /^\\else\s*$/) { $ignored_conditional = 1 - $ignored_conditional; next; } if ($oneline =~ /^\\iffdsy\@sfop/o) { $ignored_conditional = 1; # Ignore sans-serif operators. next; } if ($oneline =~ /^\\iffdsy\@largedelims/o) { $ignored_conditional = 1; # Don't use large delimiters. next; } next if $ignored_conditional; # Declare fonts. if ($oneline =~ /DeclareFontFamily\{U\}\{(FdSymbol\w+)\}\{\}/o) { print $oneline, "\n"; print "\\DeclareFontShape{U}{$1}{m}{n}{<-> $1-Book}{}\n"; print "\\DeclareFontShape{U}{$1}{b}{n}{<-> $1-Medium}{}\n"; next; } if ($oneline =~ /DeclareSymbolFont\{(.*?)s\}\{U\}(\{FdSymbol\w+\}\{m\}\{n\})/o) { if (!$seen_symfont) { print "\n"; $seen_symfont = 1; } print "\\newcommand*{\\FDSYM$1char}[1]{{\\usefont{U}$2\\char#1}}\n"; next; } # Define all basic symbol characters. if ($oneline =~ /\\fdsy\@setslot\{(\d+)\}/o) { $slot = $1; print "\n"; next; } if ($oneline =~ /\\fdsy\@DeclareSymbol\{\\([A-Za-z\@]+)\}\{(\w+)s\}/o) { $lastsym = $1; print "\\DeclareRobustCommand{\\FDSYM$lastsym}{\\FDSYM$2char{$slot}}\n"; $slot++; next; } if ($oneline =~ /\\fdsy\@DeclareAlias\{\\([A-Za-z\@]+)\}\{\w+s\}/o) { print "\\let\\FDSYM$1=\\FDSYM$lastsym\n"; next; } if ($oneline =~ /\\let\\([A-Za-z\@]+)=?\\([A-Za-z\@]+)/o && $2 ne "undefined") { print "\\let\\FDSYM$1=\\FDSYM$2\n"; next; } # Define most delimiters. if ($oneline =~ /\\fdsy\@Declare(?:Open|Close|Delimiter)\{\\([A-Za-z\@]+)\}.*\{delimiters\}\{\"(.*?)\}/o) { my $sym = $1; my $smallchar = hex($2); my $bigchar = $smallchar + 5; # Include a special case for vertical-line delimiters. if ($sym =~ /^[rl]?(V?v?)ert$/) { my $segchar = $1 eq "Vv" ? $smallchar + 2 : $smallchar - 1; output_delimiter $sym, "F", $smallchar, $segchar, $segchar, $segchar, $segchar; next; } # Include a special case for left and right groups. if ($sym =~ /^[rl]group$/) { output_delimiter $sym, "fake", -1, $smallchar, 132, $smallchar+2, 132; next; } # Ignore moustaches for now (handled below). next if $sym =~ /^[lr]moustache$/; # Handle all of the normal delimiters. print "\\DeclareRobustCommand{\\FDSYMt$sym}{{\\usefont{U}{FdSymbolF}{m}{n}\\char$smallchar}}\n"; print "\\DeclareRobustCommand{\\FDSYMd$sym}{{\\usefont{U}{FdSymbolF}{m}{n}\\char$bigchar}}\n"; next; } # Define various math symbols. if ($oneline =~ /\\DeclareMathSymbol\{\\([A-Za-z\@]+)\}.*\{(\w+)s\}\{\"(\w+)\}/o) { my $sym = $1; my $cat = $2; my $char = hex $3; print "\\DeclareRobustCommand{\\FDSYM$sym}{\\FDSYM${cat}char{$char}}\n"; } # Define all of our accents. if ($oneline =~ /\\DeclareMathAccent\{\\([A-Za-z\@]+)\}.*\{\"(\w+)\}/o) { my $sym = $1; my $smallacc = hex($2); my $bigacc = $smallacc; $bigacc += 2 if substr($sym, 0, 4) eq "wide"; output_accent $sym, 0, $smallacc, 2, $bigacc; } } # Output a few special-case delimiters. output_delimiter "uparrow", "C", 1, 198, 200, 200, 200; output_delimiter "downarrow", "C", 3, 200, 200, 199, 200; output_delimiter "Uparrow", "C", 9, 201, 203, 203, 203; output_delimiter "Downarrow", "C", 11, 203, 203, 202, 203; output_delimiter "updownarrow", "C", 17, 198, 200, 199, 200; output_delimiter "Updownarrow", "C", 21, 201, 203, 202, 203; output_delimiter "lmoustache", "fake", -1, 126, 132, 129, 132; output_delimiter "rmoustache", "fake", -1, 127, 132, 128, 132; # Output various other symbol definitions. print <<'FDSYM_COMPOSITIONS' \DeclareRobustCommand{\FDSYMdotcong}{\mathrel{\dot{\text{\FDSYMcong}}}} \DeclareRobustCommand{\FDSYMthicksim}{{\usefont{U}{FdSymbolB}{b}{n}\char2}} \DeclareRobustCommand{\FDSYMthickapprox}{{\usefont{U}{FdSymbolB}{b}{n}\char4}} \DeclareRobustCommand{\FDSYMhbar}{\CLSLfakewidetopaccent{h}{1.8pt}{133}{2pt}{133}{{U}{FdSymbolE}{m}{n}}} \DeclareRobustCommand{\FDSYMhslash}{\CLSLfakewidetopaccent{h}{1.8pt}{134}{2pt}{134}{{U}{FdSymbolE}{m}{n}}} \DeclareRobustCommand{\FDSYMcenterdot}{\mathbin{\rule{0.15em}{0.15em}}} \let\FDSYMvdots=\FDSYM@vdots \DeclareRobustCommand{\FDSYMrelbar}{\mathrel{\smash{\text{\FDSYMminus}}}} \DeclareRobustCommand{\FDSYMRelbar}{\mathrel{\smash{\text{\FDSYMequal}}}} \makeatletter \def\FDSYMlinesegmentfill@{\arrowfill@{\text{\FDSYMleftfootline}}\FDSYMrelbar{\text{\FDSYMrightfootline}}} \def\FDSYMleftharpoonfill@{\arrowfill@{\text{\FDSYMleftharpoondown}}\FDSYMrelbar\FDSYMrelbar} \def\FDSYMrightharpoonfill@{\arrowfill@\FDSYMrelbar\FDSYMrelbar{\text{\FDSYMrightharpoonup}}} \DeclareRobustCommand{\FDSYMoverlinesegment}{\mathpalette{\overarrow@\FDSYMlinesegmentfill@}} \DeclareRobustCommand{\FDSYMoverleftharpoon}{\mathpalette{\overarrow@\FDSYMleftharpoonfill@}} \DeclareRobustCommand{\FDSYMoverrightharpoon}{\mathpalette{\overarrow@\FDSYMrightharpoonfill@}} \DeclareRobustCommand{\FDSYMunderlinesegment}{\mathpalette{\underarrow@\FDSYMlinesegmentfill@}} \DeclareRobustCommand{\FDSYMovergroup}{\mathpalette{\overarrow@\FDSYMdowngroupfill@}} \DeclareRobustCommand{\FDSYMundergroup}{\mathpalette{\underarrow@\FDSYMupgroupfill@}} \def\FDSYMbracefill@#1#2#3#4#5{% $\m@th#5\hbox{#1}\leaders\hbox{#4}\hfill\hbox{#2}\leaders\hbox{#4}\hfill\hbox{#3}$% } \def\FDSYMdownbracefill@{\FDSYMbracefill@\FDSYMbraceld\FDSYMbracemd\FDSYMbracerd\FDSYMbracemid} \def\FDSYMupbracefill@{\FDSYMbracefill@\FDSYMbracelu\FDSYMbracemu\FDSYMbraceru\FDSYMbracemid} \def\FDSYMdowngroupfill@{\FDSYMbracefill@\FDSYMbraceld{}\FDSYMbracerd\FDSYMbracemid} \def\FDSYMupgroupfill@{\FDSYMbracefill@\FDSYMbracelu{}\FDSYMbraceru\FDSYMbracemid} \DeclareRobustCommand{\FDSYMoverbrace}[1]{% \mathop{\mathpalette{\overarrow@\FDSYMdownbracefill@}{#1}}\limits } \DeclareRobustCommand{\FDSYMunderbrace}[1]{% \mathop{\mathpalette{\underarrow@\FDSYMupbracefill@}{#1}}\limits% } \makeatother FDSYM_COMPOSITIONS ; # Write some trailer boilerplate. print "\n"; print "\\endinput\n";