#
# name: chtml.pl
# authors: Robert Polansky, Darren Dupre
# $Id: chtml.pl,v 1.2 1996/12/06 17:21:29 gjc Exp $
#
# COPYRIGHT (c) 1995-1996 BY NEWS INTERNET SERVICES
# ALL RIGHTS RESERVED.
#
# Permission to use, copy, modify, distribute and sell this software
# and its documentation for any purpose and without fee is hereby
# granted, provided that the above copyright notice appear in all
# copies and that both the copyright notice and this permission notice
# appear in supporting documentation and that the name of News
# Internet Services not be used in advertising or publicity pertaining
# to distribution of the software without specific, written prior
# permission.
#
# THIS SOFTWARE IS MADE AVAILABLE WITHOUT CHARGE, AS-IS. NEWS
# INTERNET SERVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
# FITNESS, IN NO EVENT SHALL NEWS INTERNET BE LIABLE FOR ANY SPECIAL,
# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# ChtmlFilterFile: This subroutine will open the specified file,
# filter it through the filter item list, and send the result to
# STDOUT. It will be used primarily to allow segments of HTML to be
# created by perl scripts without embedding lots of HTML into the perl
# script. It will also allow people to edit the HTML files with
# confidence that the file is still complete and coherent. The tags
# that it uses to mark data to be filtered are the key elements of the
# inputted associative array. The key will be limited to one line, and
# the replacement text can be arbitrarily long. Be aware the
# replacement text for one key may contain other keys that will in
# turn be themselves replaced.
# Example:
# &ChtmlFilterFile("/home/template.html",%assoc_array); filters
# template.html, replacing keys(assoc_array) with the corresponding
# data.
# Following comments added 4/19/95 by Darren:
# If the associative array in the example (%assoc_array) has a key
# whose value is made up of multiple values 'joined' using the rubout
# character (defined globally as $chtml_rub), then occurrences of the
# key value in the HTML file will be replaced by the first substring
# up to the $rub. Then the substring will be stripped off and the
# remaining string will be used for the next substitution. If there
# is only one more substring left, then it remains the replacement
# text for the rest of the FilterFile process. This allows multiple
# occurences of the same value to be replaced by different text each
# time the key is found in the HTML file. Repeated objects are now
# supported, but, each repeated object must be defined on one line in
# the HTML file. Multiple lines will be supported in the future.
# End of comments added 4/19/95 by Darren
$chtml_rub = pack("c", hex("7f"));
$chtml_repeatobjstr = '';
$chtml_begin_map = 'CHTML-INTERFACE';
$chtml_processed_comment =
'';
sub ChtmlFilterFile {
local($filename, %filterlist) = @_;
local(*FILTER);
local(*newlist);
local($begin_comment);
local($old_map);
local($version);
local($key);
$begin_comment = '';
# go through file until it finds $end_comment
while () {
if (/^(.*)::(.*)::.*/) { # has trailing comment
$old = $1;
$new = $2;
$old =~ /^\s*(\S+)\s*$/; # pull out whitespace
$old = $1;
$new =~ /^\s*(\S+)\s*$/;
$new = $1;
}
elsif (/^(.*)::(.*)$/) { # no trailing comment
$old = $1;
$new = $2;
$old =~ /^\s*(\S+)\s*$/;
$old = $1;
$new =~ /^\s*(\S+)\s*$/;
$new = $1;
}
elsif (/^$end_comment/) {
print "$chtml_processed_comment\n";
last;
}
# add new element; use *newlist if version >= 1.0
if ($version >= 1.0) {
$newlist{$new} = $filterlist{$old};
}
else {
$filterlist{$new} = $filterlist{$old};
# remove old element
delete $filterlist{$old};
}
}
# print "new list 1:
\n";
# foreach $key (keys(%newlist)) {
# print "$key --> $newlist{$key}
\n";
# }
}
# ChtmlFilterLine: This subroutine Filters a single line based on the
# keys in the associate array of arrays passed in. It supports
# successive substitution values for a single key. It returns the
# filtered line. It does not modify the input line, but it may modify
# the input array.
sub ChtmlFilterLine {
local($outline, *filterlist) = @_;
local($key);
local(@values);
local($newline);
$newline = $outline;
# loop through all keys
foreach $key (keys(%filterlist)) {
if ($newline =~ /$key/) { # found key matching substring of line
# create list of values for that key
@values = split(/$chtml_rub/, $filterlist{$key});
if ($#values) { # more than one value
# substitute for each occurrence of key, pulling off first in list
# leaving it intact if it is last one in list
$newline =~ s/$key/$#values?shift(@values):$values[0]/eg;
# reassemble array of values into string
$#values?($filterlist{$key} = join($chtml_rub, @values)):($filterlist{$key} = $values[0]);
}
else { # only one value
$newline =~ s/$key/$filterlist{$key}/g; # standard sub of value for key
}
}
}
return $newline;
}
# ChtmlRepeatObjec: This subroutine performs the processing required
# for a repeating object that needs to be filtered. It takes a
# filehandle, the line that starts the repeated object, and an
# associative array of arrays as arguments. It determines the number
# of times the object needs to be repeated, builds up the string that
# represents all the lines of the object, and passes the string to the
# FilterString subroutine once for each time the object is to be
# repeated. If the EOF is encountered while building up the object,
# the object is assumed to be finished and processing continues from
# there. Some calling function must detect the EOF later and close the
# file.
sub ChtmlRepeatObject {
local(*FILEHANDLE, $first_line, *filterlist) = @_;
local($filtered); # filtered version of string
local($times2repeat); # number of times to repeat object
local($chunk); # lines to be repeated as single string
local($i);
# filter first line
$filtered = &ChtmlFilterLine($first_line, *filterlist);
# get number out of filtered line
if ($filtered =~ /$chtml_repeatobjstr(\d+)/) {
$times2repeat = $1;
}
# go through file until it finds $chtml_endrepeatobjstr
while () {
if (/^(.*)$chtml_endrepeatobjstr/) {
$chunk = $chunk . $1;
last;
}
$chunk = $chunk . $_;
}
# filter the lines x number of times and print
for ($i = 0; $i < $times2repeat; $i++) {
$filtered = &ChtmlFilterLine($chunk, *filterlist);
print $filtered;
}
}
# html_encode: Substitutes the corresponding escape sequences for
# certain characters that have special meaning in HTML. Good for
# striping out potential HTML tags embedded in inputted text fields
# from HTML forms. The converted text is a return value.
# Fred Russell 04/10/95
#
sub html_encode {
local($str) = @_;
$str =~ s/\&/\&/g;
$str =~ s/\"/\"/g;
$str =~ s/\</g;
$str =~ s/>/\>/g;
return $str;
}
#1; # return true. MUST BE THE LAST LINE IN THIS LIBRARY FILE.