##---------------------------------------------------------------------------##
##  File:
##	@(#) mhrcfile.pl 2.18 01/10/06 20:02:06
##  Author:
##      Earl Hood       mhonarc@mhonarc.org
##  Description:
##      Routines for parsing resource files
##---------------------------------------------------------------------------##
##    MHonArc -- Internet mail-to-HTML converter
##    Copyright (C) 1996-2001	Earl Hood, mhonarc@mhonarc.org
##
##    This program is free software; you can redistribute it and/or modify
##    it under the terms of the GNU General Public License as published by
##    the Free Software Foundation; either version 2 of the License, or
##    (at your option) any later version.
##
##    This program is distributed in the hope that it will be useful,
##    but WITHOUT ANY WARRANTY; without even the implied warranty of
##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##    GNU General Public License for more details.
##
##    You should have received a copy of the GNU General Public License
##    along with this program; if not, write to the Free Software
##    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
##    02111-1307, USA
##---------------------------------------------------------------------------##

package mhonarc;

##---------------------------------------------------------------------------
##	read_resource_file() parses the resource file.
##	(The code for this routine could probably be simplified).
##
sub read_resource_file {
    my($file) = shift;
    my($line, $tag, $label, $acro, $hr, $type, $routine, $plfile,
       $url, $arg, $tmp, @a);
    my($elem, $attr, $override, $handle, $pathhead, $chop);
    $override = 0;

    $handle = &file_open($file);

    if ($file =~ m%(.*[$DIRSEPREX])%o) {
	$pathhead = $1;
	$MainRcDir = $pathhead  unless defined $MainRcDir;
    } else {
	$pathhead = '';
    }

    print STDOUT "Reading resource file: $file ...\n"  unless $QUIET;
    while (defined($line = <$handle>)) {
	next unless $line =~ /^\s*<([^>]+)>/;
	$attr = '';
	($elem, $attr) = split(' ', $1, 2);
	$attr = ''  unless defined($attr);
	$elem =~ tr/A-Z/a-z/;
	$override = ($attr =~ /override/i);
	$chop = ($attr =~ /chop/i);

      FMTSW: {
	if ($elem eq 'addressmodifycode') {	# Code to strip subjects
	    $AddressModify = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'authorbegin') {		# Begin for author group
	    $AUTHBEG = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'authorend') {		# End for author group
	    $AUTHEND = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'authsort') {		# Sort msgs by author
	    $AUTHSORT = 1;
	    $NOSORT = 0;  $SUBSORT = 0;
	    last FMTSW;
	}
	if ($elem eq 'botlinks') {		# Bottom links in message
	    $BOTLINKS = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'charsetconverters') {	# Charset filters
	    if ($override) {
		%readmail::MIMECharSetConverters = ();
		%readmail::MIMECharSetConvertersSrc = ();
	    }
	    while (defined($line = <$handle>)) {
		last  if $line =~ /^\s*<\/charsetconverters\s*>/i;
		next  if $line =~ /^\s*$/;
		$line =~ s/\s//g;
		if ($line =~ /;/) {	# using Perl 5 qualification
		    ($type,$routine,$plfile) = split(/;/,$line,3);
		} else {
		    ($type,$routine,$plfile) = split(/:/,$line,3);
		}
		$type =~ tr/A-Z/a-z/;
		$readmail::MIMECharSetConverters{$type}    = $routine;
		$readmail::MIMECharSetConvertersSrc{$type} = $plfile
		    if defined($plfile) and $plfile =~ /\S/;
	    }
	    last FMTSW;
	}
	if ($elem eq 'checknoarchive') {
	    $CheckNoArchive = 1; last FMTSW;
	}
	if ($elem eq 'conlen') {
	    $CONLEN = 1; last FMTSW;
	}
	if ($elem eq 'datefields') {
	    @a = &get_list_content($handle, $elem);
	    if (@a) { @DateFields = @a; }
	    last FMTSW;
	}
	if ($elem eq 'daybegin') {		# Begin for day group
	    $DAYBEG = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'dayend') {		# End for day group
	    $DAYEND = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'decodeheads') {
	    $DecodeHeads = 1; last FMTSW;
	}
	if ($elem eq 'definederived') {		# Custom derived file
	    %UDerivedFile = ()  if $override;
	    $line = <$handle>;
	    last FMTSW if $line =~ /^\s*<\/definederived\s*>/i;
	    $line =~ s/\s//g;
	    $UDerivedFile{$line} = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'definevar') {		# Custom resource variable
	    @CustomRcVars = ()  if $override;
	    $line = <$handle>;
	    last FMTSW if $line =~ /^\s*<\/definevar\s*>/i;
	    $line =~ s/\s//g;
	    $CustomRcVars{$line} = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'doc') {			# Link to documentation
	    $NODOC = 0; last FMTSW;
	}
	if ($elem eq 'docurl') {		# Doc URL
	    if ($line = &get_elem_last_line($handle, $elem)) {
		$DOCURL = $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'dbfile') {		# Database file
	    if ($line = &get_elem_last_line($handle, $elem)) {
		$line =~ s/\s//g;
		$DBFILE = $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'excs') {			# Exclude header fields
	    %HFieldsExc = ()  if $override;
	    while (defined($line = <$handle>)) {
		last  if $line =~ /^\s*<\/excs\s*>/i;
		$line =~ s/\s//g;  $line =~ tr/A-Z/a-z/;
		$HFieldsExc{$line} = 1  if $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'expireage') {		# Time in seconds until expire
	    if (($tmp = &get_elem_int($handle, $elem, 1)) ne '') {
		$ExpireTime = $tmp;
	    }
	    last FMTSW;
	}
	if ($elem eq 'expiredate') {		# Expiration date
	    if ($line = &get_elem_last_line($handle, $elem)) {
		$ExpireDate = $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'fieldstyles') {		# Field text style
	    while (defined($line = <$handle>)) {
		last  if $line =~ /^\s*<\/fieldstyles\s*>/i;
		next  if $line =~ /^\s*$/;
		$line =~ s/\s//g;  $line =~ tr/A-Z/a-z/;
		($label, $tag) = split(/:/,$line);
		$HeadFields{$label} = $tag;
	    }
	    last FMTSW;
	}
	if ($elem eq 'fieldorder') {		# Field order
	    @FieldOrder = ();  %FieldODefs = ();
	    while (defined($line = <$handle>)) {
		last  if $line =~ /^\s*<\/fieldorder\s*>/i;
		next  if $line =~ /^\s*$/;
		$line =~ s/\s//g;  $line =~ tr/A-Z/a-z/;
		push(@FieldOrder, $line);
		$FieldODefs{$line} = 1;
	    }
	    # push(@FieldOrder,'-extra-')  if (!$FieldODefs{'-extra-'});
	    last FMTSW;
	}
	if ($elem eq 'fieldsbeg') {		# Begin markup of mail head
	    $FIELDSBEG = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'fieldsend') {		# End markup of mail head
	    $FIELDSEND = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'firstpglink') {		# First page link in index
	    $FIRSTPGLINK = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'fldbeg') {		# Begin markup of field text
	    $FLDBEG = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'fldend') {		# End markup of field text
	    $FLDEND = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'folrefs') {		# Print explicit fol/refs
	    $DoFolRefs = 1; last FMTSW;
	}
	if ($elem eq 'folupbegin') {		# Begin markup for follow-ups
	    $FOLUPBEGIN = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'folupend') {		# End markup for follow-ups
	    $FOLUPEND = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'foluplitxt') {		# Follow-up link markup
	    $FOLUPLITXT = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'fromfields') {		# Fields to get author
	    @a = &get_list_content($handle, $elem);
	    if (@a) { @FromFields = @a; }
	    last FMTSW;
	}
	if ($elem eq 'gmtdatefmt') {		# GMT date format
	    if ($line = &get_elem_last_line($handle, $elem)) {
		$GMTDateFmt = $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'gzipexe') {		# Gzip executable
	    if ($line = &get_elem_last_line($handle, $elem)) {
		$line =~ s/\s+$//g;
		$GzipExe = $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'gzipfiles') {
	    $GzipFiles = 1;  last FMTSW;
	}
	if ($elem eq 'gziplinks') {
	    $GzipLinks = 1;  last FMTSW;
	}
	if ($elem eq 'headbodysep') {
	    $HEADBODYSEP = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'htmlext') {		# Extension for HTML files
	    if ($line = &get_elem_last_line($handle, $elem)) {
		$line =~ s/\s//g;
		$HtmlExt = $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'icons') {			# Icons
	    %Icons = ()  if $override;
	    while (defined($line = <$handle>)) {
		last  if $line =~ /^\s*<\/icons\s*>/i;
		next  if $line =~ /^\s*$/;
		$line =~ s/\s//g;
		($type, $url) = split(/[;:]/,$line,2);
		$type =~ tr/A-Z/a-z/;
		$Icons{$type} = $url;
	    }
	    last FMTSW;
	}
	if ($elem eq 'idxfname') {		# Index filename
	    if ($line = &get_elem_last_line($handle, $elem)) {
		$line =~ s/\s//g;
		$IDXNAME = $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'idxlabel') {		# Index label
	    $IDXLABEL = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'idxpgbegin') {		# Opening markup of index
	    $IDXPGBEG = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'idxpgend') {		# Closing markup of index
	    $IDXPGEND = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'idxprefix') {		# Prefix for main idx pages
	    if ($line = &get_elem_last_line($handle, $elem)) {
		$line =~ s/\s//g;
		$IDXPREFIX = $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'idxsize') {		# Size of index
	    if (($tmp = &get_elem_int($handle, $elem, 1)) ne '') {
		$IDXSIZE = $tmp;
	    }
	    last FMTSW;
	}
	if ($elem eq 'include') {		# Include other rc files
	    while (defined($line = <$handle>)) {
		last  if $line =~ /^\s*<\/include\s*>/i;
		next  if $line =~ /^\s*$/;
		$line =~ s/\s+$//;
		$line = $pathhead . $line  if ($line !~ /$DIRSEPREX/o);
		&read_resource_file($line);
	    }
	    last FMTSW;
	}
	if ($elem eq 'keeponrmm') {		# Keep files on rmm
	    $KeepOnRmm = 1;
	    last FMTSW;
	}
	if ($elem eq 'labelbeg') {		# Begin markup of label
	    $LABELBEG = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'labelend') {		# End markup of label
	    $LABELEND = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'labelstyles') {		# Field label style
	    while (defined($line = <$handle>)) {
		last  if $line =~ /^\s*<\/labelstyles\s*>/i;
		next  if $line =~ /^\s*$/;
		$line =~ s/\s//g;  $line =~ tr/A-Z/a-z/;
		($label, $tag) = split(/:/,$line);
		$HeadHeads{$label} = $tag;
	    }
	    last FMTSW;
	}
	if ($elem eq 'lastpglink') {		# Last page link in index
	    $LASTPGLINK = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'listbegin') {		# List begin
	    $LIBEG = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'listend') {		# List end
	    $LIEND = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'litemplate') {		# List item template
	    $LITMPL = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'localdatefmt') {		# Local date format
	    if ($line = &get_elem_last_line($handle, $elem)) {
		$LocalDateFmt = $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'lockmethod') {		# Locking method
	    if ($line = &get_elem_last_line($handle, $elem)) {
		$LockMethod = &set_lock_mode($line);
	    }
	    last FMTSW;
	}
	if ($elem eq 'mailto') {		# Convert e-mail addrs
	    $NOMAILTO = 0; last FMTSW;
	}
	if ($elem eq 'mailtourl') {		# mailto URL
	    while (defined($line = <$handle>)) {
		last  if $line =~ /^\s*<\/mailtourl\s*>/i;
		next  if $line =~ /^\s*$/;
		$line =~ s/\s//g;
		$MAILTOURL = $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'main') {			# Print main index
	    $MAIN = 1; last FMTSW;
	}
	if ($elem eq 'maxsize') {		# Size of archive
	    if (($tmp = &get_elem_int($handle, $elem, 1)) ne '') {
		$MAXSIZE = $tmp;
	    }
	    last FMTSW;
	}
	if ($elem eq 'msgbodyend') {		# Markup after message body
	    $MSGBODYEND = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'msgexcfilter') {		# Code selectively exclude msgs
	    $MsgExcFilter = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'msgpgs') {		# Output message pages
	    $NoMsgPgs = 0; last FMTSW;
	}
	if ($elem eq 'msgprefix') {		# Prefix for message files
	    if ($line = &get_elem_last_line($handle, $elem)) {
		$line =~ s/\s//g;
		$MsgPrefix = $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'mhpattern') {		# File pattern MH-like dirs
	    if ($line = &get_elem_last_line($handle, $elem)) {
		$MHPATTERN = $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'mimedecoders') {		# Mime decoders
	    if ($override) {
		%readmail::MIMEDecoders = ();
		%readmail::MIMEDecodersSrc = ();
	    }
	    while (defined($line = <$handle>)) {
		last  if     $line =~ /^\s*<\/mimedecoders\s*>/i;
		next  unless $line =~ /\S/;
		$line =~ s/\s//g;
		if ($line =~ /;/) {	# using Perl 5 qualification
		    ($type,$routine,$plfile) = split(/;/,$line,3);
		} else {
		    ($type,$routine,$plfile) = split(/:/,$line,3);
		}
		$type =~ tr/A-Z/a-z/;
		$readmail::MIMEDecoders{$type}    = $routine;
		$readmail::MIMEDecodersSrc{$type} = $plfile  if $plfile =~ /\S/;
	    }
	    last FMTSW;
	}
	if ($elem eq 'mimefilters') {		# Mime filters
	    if ($override) {
		%readmail::MIMEFilters = ();
		%readmail::MIMEFiltersSrc = ();
	    }
	    while (defined($line = <$handle>)) {
		last  if $line =~ /^\s*<\/mimefilters\s*>/i;
		next  if $line =~ /^\s*$/;
		$line =~ s/\s//g;
		if ($line =~ /;/) {	# using Perl 5 qualification
		    ($type,$routine,$plfile) = split(/;/,$line,3);
		} else {
		    ($type,$routine,$plfile) = split(/:/,$line,3);
		}
		$type =~ tr/A-Z/a-z/;
		$readmail::MIMEFilters{$type}    = $routine;
		$readmail::MIMEFiltersSrc{$type} = $plfile  if $plfile =~ /\S/;
	    }
	    last FMTSW;
	}
	if ($elem eq 'mimeargs') {		# Mime arguments
	    %readmail::MIMEFiltersArgs = ()  if $override;
	    while (defined($line = <$handle>)) {
		last  if     $line =~ /^\s*<\/mimeargs\s*>/i;
		next  unless $line =~ /\S/;
		$line =~ s/^\s+//;
		if ($line =~ /;/) {	# using Perl 5 qualification
		    ($type, $arg) = split(/;/,$line,2);
		} else {
		    ($type, $arg) = split(/:/,$line,2);
		}
		$type =~ tr/A-Z/a-z/  if $type =~ m%/%;
		$readmail::MIMEFiltersArgs{$type} = $arg;
	    }
	    last FMTSW;
	}
	if ($elem eq 'mimeexcs') {		# Mime exclusions
	    %readmail::MIMEExcs = ()  if $override;
	    while (defined($line = <$handle>)) {
		last  if $line =~ /^\s*<\/mimeexcs\s*>/i;
		$line =~ s/\s//g;  $line =~ tr/A-Z/a-z/;
		$readmail::MIMEExcs{$line} = 1  if $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'months') {		# Full month names
	    @a = &get_list_content($handle, $elem);
	    if (scalar(@a)) {
		@Months = @a;
	    }
	    last FMTSW;
	}
	if ($elem eq 'monthsabr') {		# Abbreviated month names
	    @a = &get_list_content($handle, $elem);
	    if (scalar(@a)) {
		@months = @a;
	    }
	    last FMTSW;
	}
	if ($elem eq 'modtime') {		# Mod time same as msg date
	    $MODTIME = 1; last FMTSW;
	}
	if ($elem eq 'msgfoot') {		# Message footer text
	    $MSGFOOT = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'msggmtdatefmt') {		# Message GMT date format
	    if ($line = &get_elem_last_line($handle, $elem)) {
		$MsgGMTDateFmt = $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'msghead') {		# Message header text
	    $MSGHEAD = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'msgidlink') {
	    $MSGIDLINK = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'msglocaldatefmt') {	# Message local date format
	    if ($line = &get_elem_last_line($handle, $elem)) {
		$MsgLocalDateFmt = $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'msgpgbegin') {		# Opening markup of message
	    $MSGPGBEG = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'msgpgend') {		# Closing markup of message
	    $MSGPGEND = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'msgsep') {		# Message separator
	    if ($line = &get_elem_last_line($handle, $elem)) {
		$FROM = $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'multipg') {		# Print multi-page indexes
	    $MULTIIDX = 1; last FMTSW;
	}
	if ($elem eq 'nextbutton') {		# Next button link in message
	    $NEXTBUTTON = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'nextbuttonia') {
	    $NEXTBUTTONIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'nextlink') {		# Next link in message
	    $NEXTLINK = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'nextlinkia') {
	    $NEXTLINKIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'nextpglink') {		# Next page link in index
	    $NEXTPGLINK = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'nextpglinkia') {
	    $NEXTPGLINKIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'news') {			# News for linking
	    $NONEWS = 0; last FMTSW;
	}
	if ($elem eq 'noauthsort') {		# Do not sort msgs by author
	    $AUTHSORT = 0;
	    last FMTSW;
	}
	if ($elem eq 'nochecknoarchive') {
	    $CheckNoArchive = 0; last FMTSW;
	}
	if ($elem eq 'noconlen') {		# Ignore content-length
	    $CONLEN = 0; last FMTSW;
	}
	if ($elem eq 'nodecodeheads') {		# Don't decode charsets
	    $DecodeHeads = 0; last FMTSW;
	}
	if ($elem eq 'nodoc') {			# Do not link to docs
	    $NODOC = 1; last FMTSW;
	}
	if ($elem eq 'nofolrefs') {		# Don't print explicit fol/refs
	    $DoFolRefs = 0; last FMTSW;
	}
	if ($elem eq 'nogzipfiles') {		# Don't gzip files
	    $GzipFiles = 0;  last FMTSW;
	}
	if ($elem eq 'nogziplinks') {		# Don't add ".gz" to links
	    $GzipLinks = 0;  last FMTSW;
	}
	if ($elem eq 'nokeeponrmm') {		# Remove files on rmm
	    $KeepOnRmm = 0;
	    last FMTSW;
	}
	if ($elem eq 'nomailto') {		# Do not convert e-mail addrs
	    $NOMAILTO = 1; last FMTSW;
	}
	if ($elem eq 'nomain') {		# No main index
	    $MAIN = 0; last FMTSW;
	}
	if ($elem eq 'nomodtime') {		# Do not change mod times
	    $MODTIME = 0; last FMTSW;
	}
	if ($elem eq 'nomsgpgs') {		# Do not print message pages
	    $NoMsgPgs = 1; last FMTSW;
	}
	if ($elem eq 'nomultipg') {		# Single page index
	    $MULTIIDX = 0; last FMTSW;
	}
	if ($elem eq 'nonews') {		# Ignore news for linking
	    $NONEWS = 1; last FMTSW;
	}
	if ($elem eq 'noposixstrftime') {	# Do not use POSIX::strftime()
	    $POSIXstrftime = 0;
	    last FMTSW;
	}
	if ($elem eq 'noreverse') {		# Sort in normal order
	    $REVSORT = 0; last FMTSW;
	}
	if ($elem eq 'nosaveresources') {	# Do not save resources
	    $SaveRsrcs = 0;
	    last FMTSW;
	}
	if ($elem eq 'nosort') {		# Do not sort messages
	    $NOSORT = 1;
	    last FMTSW;
	}
	if ($elem eq 'nospammode') {		# Do not do anti-spam stuff
	    $SpamMode = 0; last FMTSW;
	}
	if ($elem eq 'nosubjectthreads') {	# No check subjects for threads
	    $NoSubjectThreads = 1;
	    last FMTSW;
	}
	if ($elem eq 'nosubsort') {		# Do not sort msgs by subject
	    $SUBSORT = 0;
	    last FMTSW;
	}
	if ($elem eq 'note') {			# Annotation markup
	    $NOTE = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'notedir') {		# Notes directory
	    if ($line = &get_elem_last_line($handle, $elem)) {
		$NoteDir = $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'noteia') {		# No Annotation markup
	    $NOTEIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'noteicon') {		# Note icon
	    $NOTEICON = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'noteiconia') {		# Note icon when no annotation
	    $NOTEICONIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'nothread') {		# No thread index
	    $THREAD = 0; last FMTSW;
	}
	if ($elem eq 'notreverse') {		# Thread sort in normal order
	    $TREVERSE = 0; last FMTSW;
	}
	if ($elem eq 'notsubsort' ||
	    $elem eq 'tnosubsort') {		# No subject order for threads
	    $TSUBSORT = 0;
	    last FMTSW;
	}
	if ($elem eq 'notsort' ||
	    $elem eq 'tnosort') {		# Raw order for threads
	    $TNOSORT = 1; $TSUBSORT = 0;
	    last FMTSW;
	}
	if ($elem eq 'nourl') {			# Ignore URLs
	    $NOURL = 1; last FMTSW;
	}
	if ($elem eq 'nouselocaltime') {	# Not using localtime
	    $UseLocalTime = 0; last FMTSW;
	}
	if ($elem eq 'nousinglastpg') {		# Not using $LASTPG$
	    $UsingLASTPG = 0; last FMTSW;
	}
	if ($elem eq 'otherindexes') {		# Other indexes
	    @OtherIdxs = ()  if $override;
	    unshift(@OtherIdxs, &get_pathname_content($handle, $elem));
	    last FMTSW;
	}
	if ($elem eq 'perlinc') {		# Define perl search paths
	    @PerlINC = ()  if $override;
	    unshift(@PerlINC, &get_pathname_content($handle, $elem));
	    last FMTSW;
	}
	if ($elem eq 'posixstrftime') {		# Use POSIX::strftime()
	    $POSIXstrftime = 1;
	    last FMTSW;
	}
	if ($elem eq 'prevbutton') {		# Prev button link in message
	    $PREVBUTTON = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'prevbuttonia') {		# Prev i/a button link
	    $PREVBUTTONIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'prevlink') {		# Prev link in message
	    $PREVLINK = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'prevlinkia') {		# Prev i/a link
	    $PREVLINKIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'prevpglink') {		# Prev page link for index
	    $PREVPGLINK = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'prevpglinkia') {
	    $PREVPGLINKIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'refsbegin') {		# Explicit ref links begin
	    $REFSBEGIN = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'refsend') {		# Explicit ref links end
	    $REFSEND = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'refslitxt') {		# Explicit ref link
	    $REFSLITXT = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'reverse') {		# Reverse sort
	    $REVSORT = 1;
	    last FMTSW;
	}
	if ($elem eq 'saveresources') {		# Save resources in db
	    $SaveRsrcs = 1;
	    last FMTSW;
	}
	if ($elem eq 'sort') {			# Sort messages by date
	    $NOSORT = 0;
	    $AUTHSORT = 0;  $SUBSORT = 0;
	    last FMTSW;
	}
	if ($elem eq 'spammode') {		# Obfsucate/hide addresses
	    $SpamMode = 1; last FMTSW;
	}
	if ($elem eq 'ssmarkup') {		# Initial page markup
	    $SSMARKUP = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'subjectarticlerxp') {	# Regex for language articles
	    if ($line = &get_elem_last_line($handle, $elem)) {
		$SubArtRxp = $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'subjectreplyrxp') {	# Regex for reply text
	    if ($line = &get_elem_last_line($handle, $elem)) {
		$SubReplyRxp = $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'subjectstripcode') {	# Code to strip subjects
	    $SubStripCode = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'subjectthreads') {	# Check subjects for threads
	    $NoSubjectThreads = 0;
	    last FMTSW;
	}
	if ($elem eq 'subsort') {		# Sort messages by subject
	    $SUBSORT = 1;
	    $AUTHSORT = 0;  $NOSORT = 0;
	    last FMTSW;
	}
	if ($elem eq 'subjectbegin') {		# Begin for subject group
	    $SUBJECTBEG = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'subjectend') {		# End for subject group
	    $SUBJECTEND = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'subjectheader') {
	    $SUBJECTHEADER = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tcontbegin') {		# Thread cont. start
	    $TCONTBEG = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tcontend') {		# Thread cont. end
	    $TCONTEND = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tfirstpglink') {		# First thread page link
	    $TFIRSTPGLINK = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tfoot') {			# Thread idx foot
	    $TFOOT = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'thead') {			# Thread idx head
	    $THEAD = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tidxfname') {		# Threaded idx filename
	    if ($line = &get_elem_last_line($handle, $elem)) {
		$line =~ s/\s//g;
		$TIDXNAME = $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'tidxlabel') {		# Thread index label
	    $TIDXLABEL = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tidxpgbegin') {		# Opening markup of thread idx
	    $TIDXPGBEG = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tidxpgend') {		# Closing markup of thread idx
	    $TIDXPGEND = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tidxprefix') {		# Prefix for thread idx pages
	    if ($line = &get_elem_last_line($handle, $elem)) {
		$line =~ s/\s//g;
		$TIDXPREFIX = $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'timezones') {		# Time zones
	    if ($override) { %ZoneUD = (); }
	    while (defined($line = <$handle>)) {
		last  if $line =~ /^\s*<\/timezones\s*>/i;
		$line =~ s/\s//g;  $line =~ tr/a-z/A-Z/;
		($acro,$hr) = split(/:/,$line);
		$acro =~ tr/a-z/A-Z/;
		$ZoneUD{$acro} = $hr;
	    }
	    last FMTSW;
	}
	if ($elem eq 'tindentbegin') {		# Thread indent start
	    $TINDENTBEG = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tindentend') {		# Thread indent end
	    $TINDENTEND = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'title') {			# Title of index page
	    $TITLE = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tlastpglink') {		# Last thread page link
	    $TLASTPGLINK = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tlevels') {		# Level of threading
	    if (($tmp = &get_elem_int($handle, $elem, 1)) ne '') {
		$TLEVELS = $tmp;
	    }
	    last FMTSW;
	}
	if ($elem eq 'tlinone') {		# Markup for missing message
	    $TLINONE = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tlinoneend') {		# End markup for missing msg
	    $TLINONEEND = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tlitxt') {		# Thread idx list item
	    $TLITXT = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tliend') {		# Thread idx list item end
	    $TLIEND = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'toplinks') {		# Top links in message
	    $TOPLINKS = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tslice') {
	    ($TSliceNBefore, $TSliceNAfter, $TSliceInclusive) =
		&get_list_content($handle, $elem);
	    last FMTSW;
	}
	if ($elem eq 'tslicebeg') {		# Start of thread slice
	    $TSLICEBEG = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tsliceend') {		# End of thread slice
	    $TSLICEEND = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tslicelevels') {		# Level of slice threading
	    if (($tmp = &get_elem_int($handle, $elem, 1)) ne '') {
		$TSLICELEVELS = $tmp;
	    }
	    last FMTSW;
	}
        if ($elem eq 'tslicesingletxt') {
          $TSLICESINGLETXT = &get_elem_content($handle, $elem, $chop);
          last FMTSW;
        }
        if ($elem eq 'tslicetopbegin') {
          $TSLICETOPBEG = &get_elem_content($handle, $elem, $chop);
          last FMTSW;
        }
        if ($elem eq 'tslicetopend') {
          $TSLICETOPEND = &get_elem_content($handle, $elem, $chop);
          last FMTSW;
        }
        if ($elem eq 'tslicesublistbeg') {
          $TSLICESUBLISTBEG = &get_elem_content($handle, $elem, $chop);
          last FMTSW;
        }
        if ($elem eq 'tslicesublistend') {
          $TSLICESUBLISTEND = &get_elem_content($handle, $elem, $chop);
          last FMTSW;
        }
        if ($elem eq 'tslicelitxt') {
          $TSLICELITXT = &get_elem_content($handle, $elem, $chop);
          last FMTSW;
        }
        if ($elem eq 'tsliceliend') {
          $TSLICELIEND = &get_elem_content($handle, $elem, $chop);
          last FMTSW;
        }
        if ($elem eq 'tslicelinone') {
          $TSLICELINONE = &get_elem_content($handle, $elem, $chop);
          last FMTSW;
        }
        if ($elem eq 'tslicelinoneend') {
          $TSLICELINONEEND = &get_elem_content($handle, $elem, $chop);
          last FMTSW;
        }
        if ($elem eq 'tslicesubjectbeg') {
          $TSLICESUBJECTBEG = &get_elem_content($handle, $elem, $chop);
          last FMTSW;
        }
        if ($elem eq 'tslicesubjectend') {
          $TSLICESUBJECTEND = &get_elem_content($handle, $elem, $chop);
          last FMTSW;
        }
        if ($elem eq 'tsliceindentbegin') {
          $TSLICEINDENTBEG = &get_elem_content($handle, $elem, $chop);
          last FMTSW;
        }
        if ($elem eq 'tsliceindentend') {
          $TSLICEINDENTEND = &get_elem_content($handle, $elem, $chop);
          last FMTSW;
        }
        if ($elem eq 'tslicecontbegin') {
          $TSLICECONTBEG = &get_elem_content($handle, $elem, $chop);
          last FMTSW;
        }
        if ($elem eq 'tslicecontend') {
          $TSLICECONTEND = &get_elem_content($handle, $elem, $chop);
          last FMTSW;
        }
        if ($elem eq 'tslicesingletxtcur') {
          $TSLICESINGLETXTCUR = &get_elem_content($handle, $elem, $chop);
          last FMTSW;
        }
        if ($elem eq 'tslicetopbegincur') {
          $TSLICETOPBEGCUR = &get_elem_content($handle, $elem, $chop);
          last FMTSW;
        }
        if ($elem eq 'tslicetopendcur') {
          $TSLICETOPENDCUR = &get_elem_content($handle, $elem, $chop);
          last FMTSW;
        }
        if ($elem eq 'tslicelitxtcur') {
          $TSLICELITXTCUR = &get_elem_content($handle, $elem, $chop);
          last FMTSW;
        }
        if ($elem eq 'tsliceliendcur') {
          $TSLICELIENDCUR = &get_elem_content($handle, $elem, $chop);
          last FMTSW;
        }
	if ($elem eq 'tsort') {			# Date order for threads
	    $TNOSORT = 0; $TSUBSORT = 0;
	    last FMTSW;
	}
	if ($elem eq 'tsubsort') {		# Subject order for threads
	    $TNOSORT = 0; $TSUBSORT = 1;
	    last FMTSW;
	}
	if ($elem eq 'tsublistbeg') {		# List begin in sub-thread
	    $TSUBLISTBEG = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tsublistend') {		# List end in sub-thread
	    $TSUBLISTEND = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tsubjectbeg') {		# Begin markup for sub thread
	    $TSUBJECTBEG = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tsubjectend') {		# End markup for sub thread
	    $TSUBJECTEND = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tsingletxt') {		# Markup for single msg
	    $TSINGLETXT = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'ttopbegin') {		# Begin for top of a thread
	    $TTOPBEG = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'ttopend') {		# End for a thread
	    $TTOPEND = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'ttitle') {		# Title of threaded idx
	    $TTITLE = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'thread') {		# Create thread index
	    $THREAD = 1; last FMTSW;
	}
	if ($elem eq 'tnextbutton') {		# Thread Next button link
	    $TNEXTBUTTON = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tnextbuttonia') {
	    $TNEXTBUTTONIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tnextinbutton') {	# Within Thread Next button link
	    $TNEXTINBUTTON = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tnextinbuttonia') {
	    $TNEXTINBUTTONIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tnextinlink') {	# Within Thread Next link
	    $TNEXTINLINK = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tnextinlinkia') {
	    $TNEXTINLINKIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tnextlink') {	# Thread Next link
	    $TNEXTLINK = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tnextlinkia') {
	    $TNEXTLINKIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tnextpglink') {		# Thread next page link
	    $TNEXTPGLINK = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tnextpglinkia') {
	    $TNEXTPGLINKIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tprevbutton') {		# Thread Prev button link
	    $TPREVBUTTON = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tprevbuttonia') {
	    $TPREVBUTTONIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tprevinbutton') {	# Within thread previous button
	    $TPREVINBUTTON = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tprevinbuttonia') {
	    $TPREVINBUTTONIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tprevinlink') {	# Within thread previous link
	    $TPREVINLINK = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tprevinlinkia') {
	    $TPREVINLINKIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tprevlink') {		# Thread previous link
	    $TPREVLINK = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tprevlinkia') {
	    $TPREVLINKIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tprevpglink') {		# Thread previous page link
	    $TPREVPGLINK = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tprevpglinkia') {
	    $TPREVPGLINKIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'treverse') {		# Reverse order of threads
	    $TREVERSE = 1; last FMTSW;
	}
	if ($elem eq 'tnexttopbutton') {	# Next thread button
	    $TNEXTTOPBUTTON = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tnexttopbuttonia') {
	    $TNEXTTOPBUTTONIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tnexttoplink') {		# Next thread link
	    $TNEXTTOPLINK = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tnexttoplinkia') {
	    $TNEXTTOPLINKIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tprevtopbutton') {	# Previous thread button
	    $TPREVTOPBUTTON = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tprevtopbuttonia') {
	    $TPREVTOPBUTTONIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tprevtoplink') {		# Previous thread link
	    $TPREVTOPLINK = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'tprevtoplinkia') {
	    $TPREVTOPLINKIA = &get_elem_content($handle, $elem, $chop);
	    last FMTSW;
	}
	if ($elem eq 'umask') {		# Umask of process
	    if ($line = &get_elem_last_line($handle, $elem)) {
		$line =~ s/\s//g;
		$UMASK = $line;
	    }
	    last FMTSW;
	}
	if ($elem eq 'uselocaltime') {		# Use localtime for day groups
	    $UseLocalTime = 1; last FMTSW;
	}
	if ($elem eq 'usinglastpg') {
	    $UsingLASTPG = 1; last FMTSW;
	}
	if ($elem eq 'varregex') {		# Regex matching rc vars
	    $tmp = &get_elem_last_line($handle, $elem);
	    # only take value if not blank
	    $VarExp = $tmp  if $tmp =~ /\S/;
	    last FMTSW;
	}
	if ($elem eq 'weekdays') {		# Full weekday name
	    @a = &get_list_content($handle, $elem);
	    if (scalar(@a)) {
		@Weekdays = @a;
	    }
	    last FMTSW;
	}
	if ($elem eq 'weekdaysabr') {		# Abbreviated weekday name
	    @a = &get_list_content($handle, $elem);
	    if (scalar(@a)) {
		@weekdays = @a;
	    }
	    last FMTSW;
	}

      } ## End FMTSW
    }
    close($handle);
    1;
}

##----------------------------------------------------------------------
sub get_elem_content {
    my($filehandle, $gi, $chop) = @_;
    my($ret) = '';

    while (<$filehandle>) {
	last  if /^\s*<\/$gi\s*>/i;
	$ret .= $_;
    }
    $ret =~ s/\r?\n?$//  if $chop;
    $ret;
}

##----------------------------------------------------------------------
sub get_elem_int {
    my($filehandle, $gi, $abs) = @_;
    my($ret) = '';

    while (<$filehandle>) {
	last  if /^\s*<\/$gi\s*>/i;
	next  unless /^\s*[-+]?\d+\s*$/;
	s/[+\s]//g;
	s/-//  if $abs;
	$ret = $_;
    }
    $ret;
}

##----------------------------------------------------------------------
sub get_elem_last_line {
    my($filehandle, $gi) = @_;
    my($ret) = '';

    while (<$filehandle>) {
	last  if /^\s*<\/$gi\s*>/i;
	next  unless /\S/;
	$ret = $_;
    }
    $ret =~ s/\r?\n?$//;
    $ret;
}

##----------------------------------------------------------------------
sub get_list_content {
    my($filehandle, $gi) = @_;
    my(@items) = ();

    while (<$filehandle>) {
	last  if /^\s*<\/$gi\s*>/i;
	next  unless /\S/;
	s/\r?\n?$//;
	push(@items, split(/[:;]/, $_));
    }
    @items;
}

##----------------------------------------------------------------------
sub get_pathname_content {
    my($filehandle, $gi) = @_;
    my(@items) = ();

    while (<$filehandle>) {
	last  if /^\s*<\/$gi\s*>/i;
	next  unless /\S/;
	s/\r?\n?$//;
	push(@items, split(/$PATHSEP/o, $_));
    }
    @items;
}

##---------------------------------------------------------------------------##
1;
