#! c:/perl5/bin/perl
#
# $Id: bibframe,v 1.10 1996/07/19 15:40:46 elm Exp leavens-pc $
#
# Modified by Mark Borges <mdb@cdc.noaa.gov>
# $Log: bibframe,v $
# Revision 1.10  1996/07/19 15:40:46  elm
# Fixed bug in parseRC that disallowed the use of ":" in parameters.
#
# Revision 1.9  1996/07/11  21:23:13  elm
# A few minor cleanup things.
#
# Revision 1.8  1996/07/11  20:21:55  elm
# Fixed this version up (finally!) so it works with Frame 4 again.  I
# think it still works with Frame 5 as well.  Also cleaned up some
# stuff related to bibliography files and directories.
#
# -- see ChangeLog for more details.
#
# Modified by Ethan Miller (elm@cs.umbc.edu) to do the following:
#   1) Merged bibframe & bibframem into a single perl script.  This
#      required a few changes, but now both inline and "compiled"
#      bibliographies can use a single script.  The resulting script is
#      now called bibframe.
#   2) Convert strike-through to small caps for bib styles that require
#      small caps.
#   3) Integrated bf_fixchar into the perl script.  This cuts down on
#      the number of "helper" programs that must be kept around.
# Modified by Ethan Miller (elm@cs.umbc.edu) to do the following:
#   1) Fixed a bug in the Reference paragraph recognition section.
#   2) Added a cleanup subroutine to delete files in case of an abort.
# Modified by Roy Fielding (fielding@ics.uci.edu) to do the following:
#   1) Minor syntax change on Usage message.
#   2) Removed unused assignment to @fileList.
#   3) Added an end-around backup of the document which is getting the
#      new reference list so that, if something goes wrong, the user can
#      recover the original file.
#   4) Changed the process of collecting the reffiles from each document
#      so that the reffiles remain in order (necessary for macro files).
#      Treated the BIBFRAMEREF files in the same manner.
#   5) Added an error handler so that the program safely exits if none
#      of the input files contain the required "Reference" paragraph.
#   6) Specified the full pathname (via $bibframebin) for the call
#      to the program frameRemovePara.
#   7) Added UCI-specific configuration.
#
# Modified to work with multiple files by Ethan Miller.
#
# New features include:
#   Multiple files now work correctly.
#   References are inserted at the first occurence of a paragraph
#	whose tag is `Reference'.
#   References no longer override the `Reference' style defined in the
#   document.
#   Each file may specify its own list of bibliography files.  All bib files
#	specified at least once will be searched.
#   All conversions are now automatic (no need to convert files to MIF
#	by hand).
#
# Based on bibframe by Tommy Persson.
#
#----------------------------------------------------------------------
require 5.000;

use Env qw(HOME BFHOME FMHOME);
use File::Basename 'basename';

# Define some basic variables before going any further.
$user = $ENV{'USER'} || $ENV{'LOGNAME'} || (getpwuid($<))[0] ||
    die " You are nameless! \n";

$myName = basename($0);

#----------------------------------------------------------------------
# START OF USER CONFIGURATION SECTION.
#
# These variables are user-configurable, and may vary by site.

# These defaults are just the first layer, and get over-ridden by
# values in the .bibframerc file, which in turn get over-ridden by those
# specified in the document.

$BFHOME = "d:/src/bibframe" unless $BFHOME;

%Dflt = ( 
# Default style file to use.
	 'bibstyle'         => "mmlunsrt",
# Temporary directory for bibframe files.
	 'tmpdir'           => "d:/tmp/$user",
# bibtex(1) location. Can be null if it's in $PATH.
	 'bibTeXbin'        => "d:/bin",
# Location of the bibframe .bst files.
	 'bstPath'          => "$BFHOME/tex",
# Location for frameRemovePara.
	 'bibframeBin'      => "$BFHOME/bin",
# FrameMaker home directory.
	 'fmHome'           => "$FMHOME",
# Default list of reference files.
	 'refFiles'         => "",
# Default directories in which to search for reference files.
	 'refDirs'          => "",
	 'logFile'          => "-"
	 );
#
# END OF USER CONFIGURATION SECTION
#----------------------------------------------------------------------
parseRC("$HOME/.bibframerc",\%Dflt);

open(LOG,">$Dflt{'logFile'}") || die "Can't open logFile: $Dflt{'logFile'} $!\n";

open(STDERR,">&LOG");

while (($key,$value) = each %Dflt) {
    print LOG "$key: $value\n"
    }
#----------------------------------------------------------------------

die "Usage: $myName doc1.fm [ doc2.fm doc3.fm ... ]\n" unless @ARGV;
	
$tmpBase = "$Dflt{'tmpdir'}/${myName}$$";

$bibTeX[0] = "$Dflt{'bibTeXbin'}/" if $Dflt{'bibTeXbin'};
$bibTeX[0] .= "bibtex";
push(@bibTeX,"$tmpBase");

%tmpFiles = ( 
	 'aux'         => "$tmpBase.aux",
	 'bbl'         => "$tmpBase.bbl",
	 'mml'         => "$tmpBase.mml",
	 'blg'         => "$tmpBase.blg",
	 'tmpblg'      => "$tmpBase.blgnew",
	 'newMIF'      => "$tmpBase.new.mif",
	 'varMIF'      => "$tmpBase.var.mif",
	 'varDOC'      => "$tmpBase.var.doc",
	 'fmBatch'     => "$tmpBase.fmbatch",
	 'backup'      => "$tmpBase.backup"
	 );

@toClean = values %tmpFiles;

# This is probably too late to do any good...
mkdir($Dflt{'tmpdir'}, 0775) unless -d $Dflt{'tmpdir'};

#
# If this script is called by the name `bibframe' (no trailing `m'),
# then the input file is taken to be a MIF file generated by the
# single-file bibframe macros.
#

$fileNum = 0;

if ( $ARGV[0] eq "-inplace" ) {
    shift @ARGV;
    @mifFiles = ($ARGV[0]);
    push(@toClean,@mifFiles);
    $inplace = 1;
} else {
    $inplace = 0;
    $fmbatch = "$Dflt{'fmHome'}/bin/fmbatch";
    open (FMBATCHFILE, ">$tmpFiles{'fmBatch'}")
	|| die "Can't open FM batch file $tmpFiles{'fmBatch'}: $!\n";
#
# Convert all of the files from DOC to MIF format.
#
    @fileList = @ARGV;
    while ($curFile = shift) {
	$fileNum ++;
	$curMifFile = "$tmpBase.$fileNum.mif";
	$tmpFiles .= " $curMifFile";
	print FMBATCHFILE "echo \"Converting $curFile to MIF.\"\n";
	print FMBATCHFILE "Open $curFile\n";
	print FMBATCHFILE "SaveAs m $curFile $curMifFile\n";
	print FMBATCHFILE "Quit $curFile\n";
	push(@mifFiles, "$curMifFile");
	$docFromMif{$curMifFile} = $curFile;
    }
    print FMBATCHFILE "echo \"Done with conversions to MIF.\"\n";

    close (FMBATCHFILE);
    print LOG "Using fmbatch to generate MIF files\n";
    system "$fmbatch $tmpFiles{'fmBatch'}";
}

#
# Run through all of the MIF files and build the aux file for bibtex.
#
open(AUXFILE, ">$tmpFiles{'aux'}") || die "Can't open $tmpFiles{'aux'}: $!\n";
undef $refMifFile;
undef @refArray;

foreach $mifFile (@mifFiles) {
    undef $/;
    open(CURMIF, $mifFile);
    $mif = <CURMIF>;
    $/ = "\n";
    seek(CURMIF,0,0);
    if ((! $referenceTagDefined) && ($mif =~ /\<PgfTag \`Reference\'>/)) {
	$referenceTagDefined = 1;
    }
    $newrefdirs = getvalue("bf-refdir");
    if ($newrefdirs ne "") {
	$curdirs = join (":", @refdirs);
	foreach $d (split (/:/,$newrefdirs)) {
	    push @refdirs, $d if ($curdirs !~ /$d/);
	}
    }
    if (! $filedir) {
	$filedir = getfiledir();
    }
    if (! $bibstyle) {
	$bibstyle = getvalue("bf-bibstyle");
    }
#
# Note that the reffiles must be processed in the order given AND
# each reffile can only be processed once.  Therefore, we must check
# for duplicates before adding them to the refArray.
#
    if ( $rfiles = getvalue("bf-reffiles") ) {
	if (! @refArray) {
	    @refArray = split(',', $rfiles);
	} else {
	    foreach $rfnew (split(',', $rfiles)) {
		$rfAdd = 1;
		foreach $rfold (@refArray) {
		    if ($rfnew eq $rfold) { $rfAdd = 0; }
		}
		push(@refArray, $rfnew) if $rfAdd;
	    }
	}
    }
    $* = 1;
    if (($refMifFile eq "") && $mif =~
	/\s*\<Para\s*(\<Unique\s*[0-9]*\>)?\s*\<PgfTag[ \t]*\`Reference\'/) {
	$refMifFile = $mifFile;
    }
    $* = 0;
    $after=0;
    while ($_ = <CURMIF>) {
#
# Initiate %shortcites
	if (/^.*<VariableName .scite-(.*).>/) { $shortcites{$1}=1 };
#
# Add AUXFILE entry
	/^.*<VariableName .*cite-(.*).>/ && print AUXFILE "\\citation{$1}\n" if
	    (/end of VariableFormats/ ? $after=1 : $after);
    }

    close CURMIF;
}

if ($fileNum > 0) {
    # bail if nothing in $refMifFile
    unless ($refMifFile) {
	print STDERR "$myName: no files contain paragraphs with tag Reference.\n";
	print STDERR "$myName: exiting...\n";
	cleanup(@toClean);
	exit 1;
    }
    print LOG "Reference list will be inserted into $docFromMif{$refMifFile}\n";
}
#
# Add the default directories to the end of the search list.  If the
# list is *still* empty, use the current directory.
#

if ($Dflt{'refDirs'} ne "") {
    $currefdirs = join (":", @refdirs);
    foreach $d (split (/:/,$Dflt{'refDirs'})) {
	push @refdirs, $d if ($currefdirs !~ /$d/);
    }
}
if ($#refdirs == 0) {
    $refdirlist = $filedir;
} else {
    $refdirlist = join (":", @refdirs);
}

#
# Use the default bibliography style if none is given
#
$bibstyle = $Dflt{'bibstyle'} unless $bibstyle;

#
# Add the default bibliography files to the end of the list...
#
if (! @refArray) {
    @refArray = split(',', $Dflt{'refFiles'});
} else {
    $curreffiles = join (',', @refArray);
    foreach $rfnew (split(',', $Dflt{'refFiles'})) {
	if ($curreffiles !~ /$rfnew/) {
	    push (@refArray, $rfnew);
	    $curreffiles .= "," . $rfnew;
	}
    }
}

$reffiles = join(',', @refArray) if @refArray;
unless ($reffiles) {
    close AUXFILE;
    die "No reference files were specified, stopped\n";
}

print LOG "SHORTCITES: ";
foreach $key (%shortcites) {
    print LOG "$key ";
}
print LOG "\nREFERENCE FILES: $reffiles\n";
print LOG "DOCUMENT DIRECTORY: $filedir\n";
print LOG "REF-FILE DIRECTORIES: $refdirlist\n";
print LOG "BIB-STYLE: $bibstyle\n";

print AUXFILE "\\bibdata{$reffiles}\n";
print AUXFILE "\\bibstyle{$bibstyle}\n";
close AUXFILE;

#
# Fix TEXINPUTS and BIBINPUTS
#

if ($ENV{'TEXINPUTS'}) {
    $slask = ":" . $ENV{'TEXINPUTS'};
    $ENV{'TEXINPUTS'} = $Dflt{'bstPath'} . ":" . $ENV{'TEXINPUTS'};
} else {
    $ENV{'TEXINPUTS'} = $Dflt{'bstPath'};
}
$ENV{'BSTINPUTS'} = $ENV{'TEXINPUTS'};

print LOG "BIB-STYLE DIRECTORIES: $ENV{'TEXINPUTS'}\n";

if ($ENV{'BIBINPUTS'}) {
    $ENV{'BIBINPUTS'} = $refdirlist . ":" . $ENV{'BIBINPUTS'};
} else {
    $ENV{'BIBINPUTS'} = $refdirlist . $slask;
}
print LOG "BIB-FILE DIRECTORIES: $ENV{'BIBINPUTS'}\n";

#
# Run bibtex and fix the result
#

print LOG "BIBTEX COMMAND: " . join (" ", @bibTeX) . "\n";

system @bibTeX;
fixtextomml($tmpFiles{'bbl'}, $tmpFiles{'mml'});
fixtextomml($tmpFiles{'blg'}, $tmpFiles{'blg'});

#
# Initiate the keys list
#

open(BLGFILE, "$tmpFiles{'blg'}") || die "Can't open $tmpFiles{'blg'}: $!\n";
$/ = "\n";
while ($_ = <BLGFILE>) {
    /^(\S*) = (.*)$/ && ($keys{$1} = $2);
}
close BLGFILE;

#
# Fix the mml-file generatad by bibtex and convert it to mif.
#
# Fix crossref in entries.  The bst-file replaces the \cite{key} with
# tpe-cite-key. 
#
# Fix the fonts in the mif-file
#

open(MMLFILE, "$tmpFiles{'mml'}") ||
    die "Can't open $tmpFiles{'mml'}: $!\n";
undef $/;
$* = 1;
$_ = <MMLFILE>;

foreach $key (%keys) {
    s/tpe-cite-$key/explicit-cite-$key-endcite/g;
}

open(MMLFILE, ">$tmpFiles{'mml'}") || die "Can't open $tmpFiles{'mml'}: $!\n";
print MMLFILE;
close MMLFILE;

$_ = `mmltomif $tmpFiles{'mml'}`;

s/<FStrike Yes>/<FCase FSmallCaps>/g;
s/<FStrike No>/<FCase FAsTyped>/g;
foreach $word (split(' ',$_)) {
    if ($word =~ /explicit-(scite|cite)-(.*)-endcite/) {
	$cite = $1;
	$key = $2;
#	($cite eq "scite") && ($shortcites{$key} = 1);
        (! $keys{$key}) && ($keys{$key} = $key);
#	print "EXPLICIT OR CROSSREF CITE: $cite  $key\n";
#        /<String `(.*)explicit-$cite-$key-endcite(.*)'>/ && (print "MATCH1. $1  M2:  $2\n");
        s/<String \`(.*)explicit-$cite-$key-endcite(.*)'\>/\<String `$1\[\'\> \<Variable \<VariableName `$cite-$key'\> \> \<String `]$2'>/g;
    }
}

s/\\x4 /\\x11 /g;

#
# Prepare the variable format statments for the keys.
#

open(VAMIF, "> $tmpFiles{'varMIF'}") || die "Can't open $tmpFiles{'varMIF'}: $!\n";
print VAMIF "<MIFFile 4.00>\n";
print VAMIF "<VariableFormats \n";

foreach $key (keys %keys) {
    $keyvalue = $keys{$key};
    fixmmltomif($keyvalue);
    fixmmltomif($key);
    $keyvalue =~ s/<Hardspace>/\\x11 /gi;
    print VAMIF " <VariableFormat\n  <VariableName `cite-$key'>\n";
    print VAMIF "  <VariableDef `$keyvalue'>\n";
    print VAMIF " > # end of VariableFormat\n";
    if ($shortcites{$key}) {
#	($keyvalue =~ /.*<HarDspace>(.*)/) && ($keyvalue = $1);
	($keyvalue = $keys{$key}) =~ s/<HarDspace>(\d+)/<Hardspace>\($1\)/;
	$keyvalue =~ s/<Hardspace>/\\x11 /gi;
	($bibstyle eq "mmldraft") && ($keyvalue = $key);
	print VAMIF " <VariableFormat\n";
	print VAMIF "  <VariableName `scite-$key'>\n";
	print VAMIF "  <VariableDef `$keyvalue'>\n";
	print VAMIF " > # end of VariableFormat\n";
	}
}

print VAMIF "> # end of VariableFormats\n";
close VAMIF;

#
# Using the results of the previous massaging, strip out the paragraphs
# containing the references.
#
print LOG "Extracting reference paragraphs...\n";
if ($referenceTagDefined) {
    $* = 1;
    while (/[ \t]*\<Para[ \t]*(\#|\n)/) {
	$_ = $& . $';
	/\>[ \t]*\#[ \t]*end([ \t]*of)* Para[ \t]*\n/i;
	$curPara = $` . $&;
	$rest = $';
	$_ = $curPara;
	/\<PgfTag[ \t]*\`([^\']*)\'/i && ($refType = $1);
	if ($refType eq "Reference") {
	    $refParagraphs .= $curPara;
	}
	$_ = $rest;
    }
} else {
    $refParagraphs = $_;
}
print LOG "Reference paragraphs extracted.\n";

if ($inplace == 1) {
# If we are doing an in-place import, we must make a single MIF file to
# import.  This should include the variables and the Reference paragraphs.
    open(VAMIF, ">> $tmpFiles{'varMIF'}") || die "Can't open $tmpFiles{'varMIF'}: $!\n";
    print VAMIF $refParagraphs;
    close VAMIF;
    print LOG "Copying $tmpFiles{'varMIF'} => $ARGV[1]\n";
    system "/bin/cp $tmpFiles{'varMIF'} $ARGV[1]";
} else {
#
# Rip all of the reference paragraphs out of the original bib file.  Then,
# insert all of the new references at the location of the first reference
# paragraph.
#
    print LOG "Replacing old references with new references...please wait.\n";
    open (NEWMIFFILE, ">$tmpFiles{'newMIF'}");

    $_ = `$Dflt{'bibframeBin'}/frameRemovePara Reference PUT_REFERENCES_HERE 1 \< $refMifFile`;

    s/PUT_REFERENCES_HERE/"$refParagraphs"/e;

    print NEWMIFFILE;
    close NEWMIFFILE;

    open (FMBATCHFILE, ">$tmpFiles{'fmBatch'}");
    print FMBATCHFILE "Open $tmpFiles{'newMIF'}\n";
    print FMBATCHFILE "SaveAs d $tmpFiles{'newMIF'} $docFromMif{$refMifFile}\n";
    print FMBATCHFILE "Quit $tmpFiles{'newMIF'}\n";
    print FMBATCHFILE "Open $tmpFiles{'varMIF'}\n";
    foreach $docFile (@fileList) {
	print FMBATCHFILE "Open $docFile\n";
	print FMBATCHFILE "UseFormatsFrom v $docFile $tmpFiles{'varMIF'}\n";
	print FMBATCHFILE "Save $docFile\n";
	print FMBATCHFILE "Quit $docFile\n";
    }
    close FMBATCHFILE;

    print LOG "Rebuilding $docFromMif{$refMifFile} to include bibliography\n";
    print LOG "Updating citations in all files.\n";

    system "cp -p $docFromMif{$refMifFile} $tmpFiles{'backup'}";

    system "$fmbatch $tmpFiles{'fmBatch'}";

    system "cp -p $tmpFiles{'backup'} $docFromMif{$refMifFile}\.backup";
}

close(LOG);
cleanup(@toClean);

#
# End main program
#
############################################################

sub cleanup { 
    system ("/bin/rm","-f",@_);
}

sub fixmmltomif {
    local($_) = @_;
    s/<superscript>/<Superscript\\>/g;
    s/<normal>/<Default \\xa6  Font\\>/g;
    s/<Hardspace>/\\x11 /g;
    s/<HardSpace>/\\x11 /g;
    s/<FStrike Yes>/<FCase FSmallCaps>/g;
    s/<FStrike No>/<FCase FAsTyped>/g;
    $_[0] = $_;
}

sub getvalue {
    local($vname) = @_;
    local($_) = $mif;
    local($*, $vvalue);
    $* = 1;
    /(<VariableName[ \t]*`$vname'>[ \t]*\n[ \t]*<VariableDef[ \t]*`[^']*'>)/
	&& ($_ = $1) && /<VariableDef..(.*).>/ && ($vvalue = $1);
    return $vvalue;
}

sub getfiledir {
    local($*, $filedir);
    $* = 1;
    local($_) = $mif;
    /(^<BookComponent[^\000]*end of BookComponent)/ && ($_ = $1);
    /<FileName.*U\\>(.*)\/.*\'>/ && ($filedir = $1);
    return $filedir;
}

sub getreffontsize {
    local($*, $returnvalue);
    $* = 1;
    local($_) = $mif;
    /^<PgfCatalog[^\000]*end of PgfCatalog/ && ($_ = $&);
    ?\<PgfTag \`Reference\'[^\000]*end of PgfFont? && ($_ = $&);
    /<FSize (.*)>/ && ($returnvalue = $1);
    return $returnvalue;
}

#
# fixtextomml converts TeX-style specifications for foreign characters
# and different character formats to the corresponding MML-style stuff.
#
sub fixtextomml {
    open (FROMFILE, "<$_[0]");
    local ($slash) = $/;
    undef $/;
    local ($_) = <FROMFILE>;
    close FROMFILE;
    $/ = $slash;
    local ($*) = 0;
    s/\\shortcite{([^}]*)}/explicit-scite-$1-endcite/g;
    s/\\cite{([^}]*)}/explicit-cite-$1-endcite/g;
    s/{\\"A}/\\x80 /g;
    s/\\"{A}/\\x80 /g;
    s/([A-Z][a-z])\\"A/$1\\x80 /g;
    s/{\\AA}/\\x81 /g;
    s/\\AA /\\x81 /g;
    s/\\AA/\\x81 /g;
    s/\\c{C}/\\x82 /g;
    s/{\\c{C}}/\\x82 /g;
    s/\\'{E}/\\x83 /g;
    s/{\\'E}/\\x83 /g;
    s/{\\~N}/\\x84 /g;
    s/\\~{N}/\\x84 /g;
    s/{\\"O}/\\x85 /g;
    s/\\"{O}/\\x85 /g;
    s/([A-Z][a-z])\\"O/$1\\x85 /g;
    s/{\\"U}/\\x86 /g;
    s/\\"{U}/\\x86 /g;
    s/([A-Z][a-z])\\"U/$1\\x86 /g;
    s/{\\'a}/\\x87 /g;
    s/\\'{a}/\\x87 /g;
    s/{\\`a}/\\x88 /g;
    s/\\`{a}/\\x88 /g;
    s/{\\\^a}/\\x89 /g;
    s/\\\^{a}/\\x89 /g;
    s/{\\"a}/\\x8a /g;
    s/\\"{a}/\\x8a /g;
    s/([A-Z][a-z])\\"a/$1\\x8a /g;
    s/{\\~a}/\\x8b /g;
    s/\\~{a}/\\x8b /g;
    s/{\\aa}/\\x8c /g;
    s/\\aa /\\x8c /g;
    s/\\aa/\\x8c /g;
    s/{\\c{c}}/\\x8d /g;
    s/\\c{c}/\\x8d /g;
    s/{\\'e}/\\x8e /g;
    s/\\'{e}/\\x8e /g;
    s/{\\`e}/\\x8f /g;
    s/\\`{e}/\\x8f /g;
    s/{\\\^e}/\\x90 /g;
    s/\\\^{e}/\\x90 /g;
    s/{\\"e}/\\x91 /g;
    s/\\"{e}/\\x91 /g;
    s/{\\'i}/\\x92 /g;
    s/\\'{i}/\\x92 /g;
    s/{\\`i}/\\x93 /g;
    s/\\`{i}/\\x93 /g;
    s/{\\\^i}/\\x94 /g;
    s/\\\^{i}/\\x94 /g;
    s/{\\"i}/\\x95 /g;
    s/\\"{i}/\\x95 /g;
    s/{\\~n}/\\x96 /g;
    s/\\~{n}/\\x96 /g;
    s/{\\'o}/\\x97 /g;
    s/\\'{o}/\\x97 /g;
    s/{\\`o}/\\x98 /g;
    s/\\`{o}/\\x98 /g;
    s/{\\\^o}/\\x99 /g;
    s/\\\^{o}/\\x99 /g;
    s/{\\"o}/\\x9a /g;
    s/\\"{o}/\\x9a /g;
    s/([A-Z][a-z])\\"o/$1\\x9a /g;
    s/{\\~o}/\\x9b /g;
    s/\\~{o}/\\x9b /g;
    s/{\\'u}/\\x9c /g;
    s/\\'{u}/\\x9c /g;
    s/{\\`u}/\\x9d /g;
    s/\\`{u}/\\x9d /g;
    s/{\\\^u}/\\x9e /g;
    s/\\\^{u}/\\x9e /g;
    s/{\\"u}/\\x9f /g;
    s/\\"{u}/\\x9f /g;
    s/([A-Z][a-z])\\"u/$1\\x9f /g;
    s/{\\ss}/\\xa7 /g;
    s/{\\AE}/\\xae /g;
    s/{\\O}/\\xaf /g;
    s/\\b{a}/\\xbb /g;
    s/\\b{o}/\\xbc /g;
    s/{\\ae}/\\xbe /g;
    s/{\\o}/\\xbf /g;
    s/{\\`A}/\\xcb /g;
    s/\\`{A}/\\xcb /g;
    s/{\\~A}/\\xcc /g;
    s/\\~{A}/\\xcc /g;
    s/{\\~O}/\\xcd /g;
    s/\\~{O}/\\xcd /g;
    s/{\\o}/\\xcd /g;
    s/{\\oe}/\\xcd /g;
    s/{\\"y}/\\xd8 /g;
    s/\\"{y}/\\xd8 /g;
    s/{\\"Y}/\\xd9 /g;
    s/\\"{Y}/\\xd9 /g;
    s/---/\\xd1 /g;
    s/--/\\xd0 /g;
    s/``/\\xd2 /g;
    s/''/\\xd3 /g;
    s/~/<HardSpace>/g;
    s/{\\\^e}/\\x90 /g;
    s/{\\em *([^}]*)}/<italic>$1<noitalic>/g;
    s/{\\bf *([^}]*)}/<bold>$1<nobold>/g;
    s/\$([0-9]*)\^{\\rm ([a-z]*)}\$/$1<superscript>$2<normal>/g;
    s/\$([0-9]*)\^{([a-z]*)}\$/$1<superscript>$2<normal>/g;
    s/([0-9]*)\$\^{([a-z]*)}\$/$1<superscript>$2<normal>/g;
    s/\$\^([^\$]*)\$/<superscript>$1<normal>/g;
    s/\$\_([^\$]*)\$/<subscript>$1<normal>/g;
    s/\$([^^]*)\^([^\$]*)\$/$1<superscript>$2<normal>/g;
    s/\$([^_]*)\_([^\$]*)\$/$1<subscript>$2<normal>/g;
    s/([^\\])[{}]/$1/g;
    open (TOFILE, ">$_[1]");
    print TOFILE;
    close TOFILE;
}

sub parseRC{

    my($validKey)="(bibstyle|logFile|tmpdir|bibTeXbin|bstPath|bibframeBin|fmHome|refFiles|refDirs)";
    my($RCfile,$RCref)= @_;
    my($line,$word);
    my($REyep)= "^([Yy](es)?|1|[Tt](rue)?)";
    open(RC,"$RCfile") || die "Can't open control file $RCfile\n";
    chop(my(@RC) = <RC>);
    close(RC);

    while (@RC) {
	$_ = shift(@RC);

# Skip comments or blank lines.
	next if /^\#/ or not $_;

# Split and trim trailing whitespace.
	($line = (split('#',$_))[0]) =~ s/\s+$//;
	($keyword, $param) = (split(':',$line, 2));
	die "Invalid keyword=$keyword\n" unless $keyword =~ /$validKey/;

# Trim leading whitespace.
	$param =~ s/^\s+//;

	if ($param =~ '\$') {
	    # Support substitution of common environment variables in a crude way.
	    $param =~ s/\$USER/$ENV{'USER'}/g;
	    $param =~ s/\$LOGNAME/$ENV{'LOGNAME'}/g;
	    $param =~ s/\$TMPDIR/$ENV{'TMPDIR'}/g;
	    $param =~ s/\$HOME/$ENV{'HOME'}/g;
	    $param =~ s/\$BFHOME/$ENV{'BFHOME'}/g;
	};
	$$RCref{"$keyword"} = "$param";
    }
}
