###################################################
# Fern Definition file.
# Copyright 1998 N.A. Krawetz, All rights reserved.
#
# The definition file tells Fern how to process the
# HTML code.  It consists of "actions" followed by
# parameters for the actions.  The first parameter
# is called "%1", the second is %2, and the third
# is the "Message" (only the message can contain spaces).
#
# Available actions:
#  Definitions:
#	define %1  Message	(Make all occurances of %1 be the message)
#	define %1		("undefine" the definition of %1)
#    Definitions are used with "${%1}".
#    For example,
#		define ns Netscape
#    The value of ${ns} is "Netscape".
#    Definitions can contain other definitions, for example:
#	define browser Your browser is ${ns}.
#    The value of ${browser} is not determined until it is needed.
#    NOTE: The "%1" in "define" is case-sensitive.
#
#  Conditionals:
#	The condition is a "defined" message.  If it is not defined,
#	then the value is "false".  Otherwise, it is true.
#	Note #1: every "if" needs an "endif"
#	Note #2: all conditions are case-senditive.
#
#	if c1		(check if "c1" is defined)
#	if c1 | c2	(check if either "c1" or "c2" are defined)
#	if c1 & c2	(check if either "c1" and "c2" are defined)
#	if ! c1 	(check if "c1" is "not" defined)
#	if (c1 | (c2 & ! c3))	(a complex condition)
#	else if c	(else, if the condition is false, try a different if)
#	else		(else, if the condition is false)
#	endif		(end of the "if" if condition)
#
#	The ordering should be:
#		if c1
#		else if c2
#		else
#		endif
#	"if" statements can be nested:
#		if c1
#		  if cc1
#		  else
#		  endif
#		else if c2
#		  if cc2
#		  else
#		  endif
#		else
#		  if cc3
#		  else
#		  endif
#		endif
#
#  Rules:
#  Rules contain messages.  There are 2 types of messages: "MT" are displayed
#  if the rule is applied (message-true); "MF" are displayed if the rule
#  is not applied (message-false).
#  Messages (both MT and MF) contain text strings and defined variables
#  (${...}).  They may also contain special definitions:
#	$1	the value of "%1"
#	$2	the value of "%2"
#	$0	the value of the tag that triggered the rule.
#	$l	the line number in the HTML document (not always available)
#	$b	number of "begin tags" for <$0>
#	$e	number of "end tags" for </$0>
#	$n	difference between $b and $e (the "nesting" of $0)
#	$U	special (URL) see "PROCESS" below.
#    The "\" character means "the next character is special".
#	\n	a new-line character (^M)
#	\r	a carrage return (^J)
#	\t	a tab
#	\a	a bell (alarm)
#	\\	a backslash
#	\$	a dollar sign
#    A "\" followed by any other character just prints the character.
#
#  Rules that define tag ordering.
#	BEFORE %1 %2 MF	(Display message if %2 is not before %1)
#		e.g.:  before html body
#		     The tag <html> must come before <body>.
#	NESTED %1 %2 MT (Allow <%1>....<%2> can be nested.)
#	NESTED * * MF   (Special: All other tags should not be nested.)
#	RESET %1 %2 MT  (Tag <%1> resets begin/end tag counters for <%2>)
#	WITHIN %1 %2 MF (The tag <%2> must be within <%1>...</%1>.)
#
#  Rules that define individual tags.
#  (Note: even though many rules do not use %2, it must be defined.)
#	FIELD %1 %2 MF		(Expect the tag to contain "<%1 %2=...>")
#	FIELD_NOT %1 %2 MF	(Expect the tag to not contain "<%1 %2=...>")
#	FOUND %1 %2 MT		(Display message if <%1> is found)
#	IGNORE_WITHIN %1 %2 MT	(ignore all data between <%1> and <%2>)
#	IGNORE_WITHIN * * MF	(Special: display if the %2 was not found.)
#	MATCH %1 %2 MF		(Each tag <%1> must match a </%1>.)
#	MATCH * * MF		(Each tag <$0> must match a </$0>.)
#	MUST  %1 %2 MF		(The tag <%1> must be in the HTML code.>
#	NEVER %1 %2 MF		(The tag <%1> should never be seen.)
#	ONCE %1 %2 MF		(The tag <%1> should be seen at most ONCE.)
#	OPTIONAL_NOT %1 * MT	(The not-tag </%1> is optional.)
#	SURROUND_TAG %1 %2 MF	(The tag begins with "<%1" and ends with "%2")
#	TAG_ERROR %1 %2	MT	(display message on the tag-error)
#		valid values for %1 in TAG_ERROR are:
#			bad_<	(found "<" that isn't in a tag)
#			bad_>	(found ">" that isn't in a tag)
#			bad_/	(found </tag> before a matching <tag>)
#			bad_tag	(found a bad tag; e.g. "</" or "</>")
#			missing_>	(tag is missing a ">")
#			too_long	(tag is more than 4096 characters)
#
#  Rules that determine how Fern processes the input.
#	PRINT_BEFORE	%1 * MT
#		Display the message before processing the file.
#		"%1" is only used to determine printing order.
#		All "PRINT_BEFORE" messages are sorted and then displayed
#		in order from "lowest" to "highest".
#		Although any characters can be used, we recommend using
#		numbers between 0 and 1, for example "0.1" and "0.2".
#		This way, other lines can be inserted easily ("0.15").
#	PRINT_AFTER	%1 * MT
#		Similar to PRINT_BEFORE, except the messages are
#		displayed after the file has been processed.
#	PROCESS %1 %2
#		Determines how to process the input.
#		Values for %1 are:
#		  HTTP	== the HTML file includes HTTP meta-header
#		  URL	== first line contains the URL (and defines $U)
#		Values for %2 are:
#		  any-text == TRUE
#		  no-text == FALSE
#	FROM_HTTP %1 %2
#		If the input contains the HTTP meta header, then store
#		the meta-header option "%1" into "define" for "%2".
#		E.g.:	from_http content-type Content
#		This stores the HTTP meta-value "content-type" into the
#		defined variable "Content".
#		For the "content-type: text/html", this would be
#		the same as saying:
#			define Content text/html
###################################################

# comment out what you don't want...

### check for usability issues
#define	Accessibility	TRUE
#define	Compatability	TRUE
#define	SlowModem	TRUE

####################################################
# You shouldn't need to edit below this point unless
# you want to change how Fern processes.
####################################################
### check for specific browsers
define	Netscape4	Netscape v.4
define	MSIE4		Microsoft Internet Explorer v.4
define	Lynx		Lynx
#define	HTML4		HTML 4.0

### for input (what to process)
if HTTP_IN
  # currently defined:
  #	HTTP:  input has the HTTP meta-header.
  #	URL:  first line of input has the URL.
  process	HTTP	TRUE
  process	URL	TRUE
endif

### for output
if HTML_OUT
  define li	\    <li>
  define >	&gt;
  define <	&lt;
  define red	<font color=RED>
  define /red	</font>
  define h1	<h1>
  define /h1	</h1>
  define ul	<ul>\n
  define /ul	</ul>\n
  define amp	&amp;
else
  define >	>
  define <	<
  define amp	&
endif

### if we're processing the HTTP meta-header...
# if "process HTTP TRUE", then define ${Content} to the value of content-type
from_http	content-type	Content
from_http	Server	Server
# the ones with a "$" are special and refer to the HTTP initial status line
from_http	$http-code	RC
from_http	$http-message	Message
from_http	$http-protocol	Protocol

### for Templeton
if Tton | Templeton | tton | templeton
  ## should be started with something like:
  ##	Command_pattern * fern.exe fern.def %F Date=%N >> fern.out
  process	HTTP	TRUE
  process	URL	TRUE
  if HTML_OUT
   print_before	0.1	*	${h1}From <a href="$U">$U</a>${/h1}\n
  else
   print_before	0.1	*	${h1}From $U:${/h1}\n
  endif
  print_before  0.14	*	${li}${Date}\n
  print_before	0.15	*	${li}Server ${Server}: ${Content} ${Message} (${RC})\n
  print_before	0.2	*	${ul}
  print_after	0.2	*	${/ul}
  print_after	0.9	*	\n
endif

##############################################
# general messages...
# Special flags:
#  $$ = print a $
#  $1 = print the first parameter
#  $2 = print the second parameter
#  $l = print the line number (not always allowed)
# The following may be reset by some of the actions below
#  $b = print number of Begin-tags seen
#  $e = print number of End-tags seen
#  $n = print difference between number of Begin and End tags ($n="nesting")
#
#  FAQ: How can I get a line to start with a space?  Answer:  Use "\ ".
#  NOTE: Messages can only be nested 8 deep.
define w	${li}Line $l: Warning:
define e	${li}${red}Line $l: Error:${/red}
define n	${li}Line $l: Notice:
define msie	Microsoft Internet Explorer
define netscape	Netscape

# tags that "must" be seen  (no line numbers)
define	must	Warning: Missing ${<}$1${>}...${<}$2${>} tags.\n
must	html	/html	${must}
must	head	/head	${must}
must	body	/body	${must}

# tags that should only be seen once
define	once	${e} The ${<}$1${>}...${<}$2${>} tag should only be seen once.\n
once	html	/html	${once}
once	head	/head	${once}
once	title	/title	${once}
once	body	/body	${once}
once	base	/base	${once}
once	basefont	/basefont	${once}

# tags that do not require end-tags (no line numbers)
# These "not-tags" are optional (they don't need to be present)
# "optional_not" changes the $n counters.
optional_not dd /dd
optional_not dt /dt
optional_not li /li
optional_not p  /p
optional_not td /td
optional_not th /th
optional_not tr /tr
optional_not noframes /noframes
optional_not legend /legend
optional_not option /option
optional_not optgroup /optgroup

# tags that should never be seen
# "Never" tags can be either "begin" tags or "end" tags.
# "never" changes the $n counters.
define	never	${e} Invalid tag: ${<}$0 ...${>}.\n
## from the <head>...</head> area
never	/!DOCTYPE	*	${never}
never	/base	*	${never}
never	/basefont	*	${never}
never	/isindex	*	${never}
never	/link	*	${never}
never	/meta	*	${never}
never	/nextid	*	${never}
## from the <body>...</body> area
never	/!--	*	${never}
never	/area	*	${never}
never	/bgsound	*	${never}
never	/br	*	${never}
never	/col	*	${never}
never	/embed	*	${never}
never	/frame	*	${never}
never	/hr	*	${never}
never	/img	*	${never}
never	/input	*	${never}
never	/keygen	*	${never}
never	/object	*	${never}
never	/param	*	${never}
never	/plaintext	*	${never}
never	/spacer	*	${never}
never	/wbr	*	${never}

# tags that require specific ordering
define	before ${e} ${<}$1${>} should come before ${<}$2${>}.\n
before	head	body	${before}
before	/head	body	${before}

# tags that should be "within" other tags
define within	${w} ${<}$1${>} should be within ${<}$2${>}...${<}/$2${>} tags.\n
## basic skeleton
within	head	html	${within}
within	body	html	${within}
within	frameset	html	${within}
## within <head>...</head>
within	base	head	${within}
within	basefont	head	${within}
within	isindex	head	${within}
within	link	head	${within}
within	meta	head	${within}
within	nextid	head	${within}
within	style	head	${within}
within	title	head	${within}
## within <table>...</table>
within	caption	table	${within}
within	col	table	${within}
within	colgroup	table	${within}
within	thead	table	${within}
within	tbody	table	${within}
within	tfoot	table	${within}
within	td	table	${within}
within	th	table	${within}
within	tr	table	${within}
## within <select>...</select>
within	option	select	${within}
within	optgroup	select	${within}
## other "within" tags
within	area	map	${within}
within	dt	dl	${within}
within	dd	dl	${within}
within	legent	fieldset	${within}
within	frame	frameset	${within}
within	noframes	frameset	${within}
within	server	head	${within}

# tags that can be nested
#define	nested	Line $l: Nested ${<}$1${>}...${<}$2${>} is $n deep (Total $b starts and $e ends).\n
nested dir	/dir	${nested}
nested dl	/dl	${nested}
nested menu	/menu	${nested}
nested ol	/ol	${nested}
nested ul	/ul	${nested}
nested frameset	/frameset	${nested}
nested font	/font	${nested}
nested table	/table	${nested}
# general messsage for tags that cannot be nested */
nested * * ${e} The ${<}$0${>} tag cannot be nested; you need a ${<}/$0${>} tag.\n

# we want some tags to always match (no line numbers)
match	a	/a	Error: Mismatched ${<}a${>} ($b) and ${<}/a${>} ($e) tags.\n
match	*	*	Error: Missed end tags: ${<}$0${>} ($b occurances) and ${<}/$0${>} ($e occurances) tags.\n

## field_url currently not implemented
# some tag fields with URL's to check
#define	url	${w} ${<}$1 $2=URL ...${>} contains "$u" in the URL.\n
#field_url	a	href	${url}
#field_url	body	background	${url}
#field_url	img	src	${url}
#field_url	img	lowsrc	${url}

# some tags act as closing tags for other's
define	reset	${w} ${<}$1${>} closes ${<}$2${>} tag.\n
reset	table	a	${reset}
reset	/table	td
reset	/table	th
reset	/table	tr

# what do tags normally begin with?  Form: "${<}$1 $2"
# Note: Everything that is surrounded is ignored
define surroundtag	${e} Beginning of tag "${<}$0" missing "$2".\n
### comments
surround_tag	!--	-->	${surroundtag}
### asp pages
surround_tag	%	%>	${surroundtag}
surround_tag	%@	%>	${surroundtag}

### scripts
define ignorewithin	${e} Missed end to block ${<}$0${>}...${<}/$0${>}.\n
ignore_within	script	/script	${n} Skipping ${<}$1${>}...${<}$2${>}\n
### pre-formatted
ignore_within	xmp	/xmp	${n} Skipping ${<}$1${>}...${<}$2${>}\n
ignore_within	*	*	${ignorewithin}

### general tag markings (these definitions are special)
tag_error	bad_<	*	${e} Only use "${<}" for tags -- use "${amp}lt;" for text.\n
tag_error	bad_>	*	${e} Only use "${>}" for tags -- use "${amp}gt;" for text.\n
tag_error	bad_/	*	${e} Tag ${<}/$0${>} is missing start tag ${<}$0${>}.\n
tag_error	bad_tag	*	${e} Tag ${<}$0${>} is poorly formed.\n
tag_error	missing_>	*	${e} Tag "${<}$0" is missing "${>}".\n
tag_error	too_long	*	${e} The tag is too long.\n

############# HTML specific issues #########################
if Compatability
  # Compatability issues are directed toward maintaining standard HTML
  # that can be properly viewed by all (most) web browsers.
  # Because different browsers support different HTML versions, compatability
  # issues may arise.
  field_not font face	${w} ${<}$1 $2=...${>} is not supported by the HTML standards.\n
  field_not font size	${w} Text size set by ${<}$1 $2=...${>} may be unreadable.\n
  field_not hr length	${w} ${<}$1 $2=...${>} is not supported by older browsers.\n
  nested table	/table	${w} Nested tables are not supported by some older browsers.\n
  nested font	/font	${w} Nested fonts are not supported by some older browsers.\n
  # permit error messages for specific browsers
  define MSIE4	true
  define Netscape	true
  define Lynx	true
  define HTML4	true
endif

## "Depricated" means the tag has been replaced by another tag
##    and will probably become obsolete in the furture.
## "Obsolete" means the tag is no longer supported by the standards.
## "Unsupported" means it's a browser-specific extension to the HTML standard.
define dep_found	${w} The ${<}$1${>} tag is depricated
define obs_found	${w} The ${<}$1${>} tag is obsolete
define uns_found	${w} The ${<}$1${>} tag is unsupported
define dep_field	${w} The ${<}$1$ $2=...{>} tag is depricated
define obs_field	${w} The ${<}$1$ $2=...{>} tag is obsolete
define uns_field	${w} The ${<}$1$ $2=...{>} tag is unsupported
if HTML4
  define html4_dep_found  ${dep_found} in ${HTML4}.\n
  define html4_obs_found  ${obs_found} in ${HTML4}.\n
  define html4_uns_found  ${uns_found} in ${HTML4}.\n
  define html4_dep_field  ${dep_field} in ${HTML4}.\n
  define html4_obs_field  ${obs_field} in ${HTML4}.\n
  define html4_uns_field  ${uns_field} in ${HTML4}.\n
  ## depricated HTML
  found applet /applet	${html4_dep_found}
  found basefont /basefont	${html4_dep_found}
  found center	/center	${html4_dep_found}
  found font	/font	${html4_dep_found}
  found isindex	/isindex	${html4_dep_found}
  found strike	/strike	${html4_dep_found}
  found s	/s	${html4_dep_found}
  found u	/u	${html4_dep_found}
  field br	clear	${html4_dep_field}
  field hr	align	${html4_dep_field}
  field hr	noshade	${html4_dep_field}
  field hr	size	${html4_dep_field}
  field hr	width	${html4_dep_field}
  ## obsolete HTML
  found listing	/listing	${html4_obs_found}
  found nextid	*	${html4_obs_found}
  found plaintext	*	${html4_obs_found}
  found xmp	/xmp	${html4_obs_found}
endif

############# Browser specific and other issues ############
# Many "popular" browsers have their own extensions to the HTML standard
# or interpret the HTML in a non-standard fashion.
# The extensions are only usable with the specific browser.
# The interpretation issues may cause "standard" HTML to be interpreted
# differently or incorrectly.  In addition, extensions for one browser may
# be misinterpreted by a different browser.

### for MSIE-only tags
if !MSIE4 | (Netscape | Lynx)
  define msie_only_field	${w} ${<}$1 $2=...${>} is only available under ${msie}\n
  define msie_only_found	${w} ${<}$1${>}...${<}$2${>} is only available under ${msie}\n
  found  bgsound	*	${msie_only_found}
  found  marque	/marque	${msie_only_found}
  found  comment	/comment	${msie_only_found}
  field_not area	notab	${msie_only_field}
  field_not area	taborder	${msie_only_field}
  field_not basefont name	${msie_only_field}
  field_not body bgproperties	${msie_only_field}
  field_not body leftmargin	${msie_only_field}
  field_not body topmargin	${msie_only_field}
  field_not caption valign	${msie_only_field}
  field_not div nowrap	${msie_only_field}
  field_not frameset framespacing	${msie_only_field}
  field_not hr	color	${msie_only_field}
  field_not input	notab	${msie_only_field}
  field_not input	taborder	${msie_only_field}
  field_not img	controls	${msie_only_field}
  field_not img	dynsrc	${msie_only_field}
  field_not img	loop	${msie_only_field}
  field_not img	start	${msie_only_field}
  field_not isindex	action	${msie_only_field}
  field_not meta	charset	${msie_only_field}
  field_not object	notab	${msie_only_field}
  field_not object	shapes	${msie_only_field}
  field_not table	background	${msie_only_field}
  field_not table	bordercolordark	${msie_only_field}
  field_not table	bordercolorlight	${msie_only_field}
  field_not table	nowrap	${msie_only_field}
  field_not table	valign	${msie_only_field}
  field_not tr	bordercolor	${msie_only_field}
  field_not tr	bordercolorlight	${msie_only_field}
  field_not tr	bordercolordark	${msie_only_field}
  field_not th	background	${msie_only_field}
  field_not th	bordercolor	${msie_only_field}
  field_not th	bordercolorlight	${msie_only_field}
  field_not th	bordercolordark	${msie_only_field}
  field_not td	background	${msie_only_field}
  field_not td	bordercolor	${msie_only_field}
  field_not td	bordercolorlight	${msie_only_field}
  field_not td	bordercolordark	${msie_only_field}
endif

### for Netscape-only tags
if !Netscape | (MSIE4 | Lynx)
  define netscape_only_field	${w} ${<}$1 $2=...${>} is only available under ${netscape}\n
  define netscape_only_found	${w} ${<}$1${>}...${<}$2${>} is only available under ${netscape}\n
  found  blink	/blink	${netscape_only_found}
  found  layer	/layer	${netscape_only_found}
  found  multicol	/multicol	${netscape_only_found}
  found  spacer	*	${netscape_only_found}
  found  server	/server	${w} ${<}$1${>}...${<}$2${>} is only available from a Netscape web server.\n
  field_not applet	mayscript	${netscape_only_field}
  field_not embed	align	${netscape_only_field}
  field_not embed	border	${netscape_only_field}
  field_not embed	hspace	${netscape_only_field}
  field_not embed	pluginspace	${netscape_only_field}
  field_not embed	type	${netscape_only_field}
  field_not embed	vspace	${netscape_only_field}
  field_not frameset	border	${netscape_only_field}
  field_not frameset	bordercolor	${netscape_only_field}
  field_not frame	bordercolor	${netscape_only_field}
  field_not form	name	${netscape_only_field}
  field_not img	lowsrc	${netscape_only_field}
  field_not img	name	${netscape_only_field}
  field_not input	border	${netscape_only_field}
  field_not textarea	wrap	${netscape_only_field}
  field_not table	hspace	${netscape_only_field}
  field_not table	vspace	${netscape_only_field}
endif

### for current browsers
if HTML4 | MSIE4 | Netscape | Lynx
  define most_only_found ${w} ${<}$1${>}...${<}$2${>} is not supported by HTML 4.0.\n
  define most_only_field ${w} ${<}$1$ $2=...${>} is not supported by HTML 4.0.\n
  found	ins	/ins	${most_only_found}
  found	del	/del	${most_only_found}
  found	bdo	/bdo	${most_only_found}
  found	embed	/embed	${most_only_found}
  found nobr	/nobr	${most_only_found}
  found wbr	*	${most_only_found}
  field_not body	onblur	${most_only_field}
  field_not body	onfocus	${most_only_field}
  field_not dir		type	${most_only_field}
  field_not menu	type	${most_only_field}
  field_not frameset	frameborder	${most_only_field}
  field_not table	cols	${most_only_field}
  field_not tr		bgcolor	${most_only_field}
endif

### for people with slow network connections (most people using ISP's)
if SlowModem
  field img lowsrc	${n} Consider using ${<}$1 src=url1 $2=url2${>} for large images.\n
endif

if Accessibility
  # Accessibility issues are directed toward non-graphical web "browsers".
  # these include search engines, text-only browsers (e.g. Lynx), and
  # HTML-to-speech browsers for the blind.
  must	title	/title	${must}
  found	table	/table	${w} Tables may be difficult to follow for non-graphical browsers.\n
  field img alt  ${n} Use ${<}$1 src=url $2="text"${>} for non-graphical browsers.\n
  field_not body bgcolor	${n} Color appears differently on various platforms.\n
  field_not font color	${n} Color appears differently on various platforms.\n
endif

