(\w+?)!$bookmark$1!gio;
s!<.*?>!!g; # strip all other HTML tags
##
# Clean up whitespace
##
s! +! !gm; # collapse spaces
s!^ +!!gm; # strip leading spaces
s! ! !g; # tab-space -> tab
s!^[ ]+$!!gm; # strip lines of whitespace
s!^\n{2,}!\n!gm; # collapse newlines
s!\s*%PRE%(.*?)%/PRE%\s*!decode($1)!egs; # "thaw" blocks
s! +$!!gm; # strip trailing spaces
# Convert numeric entity references
s!(\d+);!pack( 'c', $1 )!eg;
s!([\dA-F]+);!pack( 'c', hex($1) )!eg;
# Convert character entity references
%char_entity = (
'quot', '"',
'amp', '&',
'lt', '<',
'gt', '>',
'emsp', "\x80", # em space (HTML 2.0)
'sbquo', "\x82", # single low-9 (bottom) quotation mark
'fnof', "\x83", # Florin or Guilder (currency)
'bdquo', "\x84", # double low-9 (bottom) quotation mark
'hellip', "\x85", # horizontal ellipsis
'dagger', "\x86", # dagger
'Dagger', "\x87", # double dagger
'circ', "\x88", # modifier letter circumflex accent
'permil', "\x89", # per mill sign
'Scaron', "\x8A", # latin capital letter S with caron
'lsaquo', "\x8B", # left single angle quotation mark
'OElig', "\x8C", # latin capital ligature OE
'diams', "\x8D", # diamond suit
'clubs', "\x8E", # club suit
'hearts', "\x8F", # heart suit
'spades', "\x90", # spade suit
'lsquo', "\x91", # left single quotation mark
'rsquo', "\x92", # right single quotation mark
'ldquo', "\x93", # left double quotation mark
'rdquo', "\x94", # right double quotation mark
'endash', "\x96", # dash the width of ensp (Lynx)
'ndash', "\x96", # dash the width of ensp (HTML 2.0)
'emdash', "\x97", # dash the width of emsp (Lynx)
'mdash', "\x97", # dash the width of emsp (HTML 2.0)
'tilde', "\x98", # small tilde
'trade', "\x99", # trademark sign (HTML 2.0)
'scaron', "\x9A", # latin small letter s with caron
'rsaquo', "\x8B", # right single angle quotation mark
'oelig', "\x9C", # latin small ligature oe
'Yuml', "\x9F", # latin capital letter Y with diaeresis
'ensp', "\xA0", # en space (HTML 2.0)
'thinsp', "\xA0", # thin space (Lynx)
'nbsp', "\xA0", # non breaking space
'iexcl', "\xA1", # inverted exclamation mark
'cent', "\xA2", # cent (currency)
'pound', "\xA3", # pound sterling (currency)
'curren', "\xA4", # general currency sign (currency)
'yen', "\xA5", # yen (currency)
'brkbar', "\xA6", # broken vertical bar (Lynx)
'brvbar', "\xA6", # broken vertical bar
'sect', "\xA7", # section sign
'die', "\xA8", # spacing dieresis (Lynx)
'uml', "\xA8", # spacing dieresis
'copy', "\xA9", # copyright sign
'ordf', "\xAA", # feminine ordinal indicator
'laquo', "\xAB", # angle quotation mark, left
'not', "\xAC", # negation sign
'shy', "\xAD", # soft hyphen
'reg', "\xAE", # circled R registered sign
'hibar', "\xAF", # spacing macron (Lynx)
'macr', "\xAF", # spacing macron
'deg', "\xB0", # degree sign
'plusmn', "\xB1", # plus-or-minus sign
'sup2', "\xB2", # superscript 2
'sup3', "\xB3", # superscript 3
'acute', "\xB4", # spacing acute
'micro', "\xB5", # micro sign
'para', "\xB6", # paragraph sign
'middot', "\xB7", # middle dot
'cedil', "\xB8", # spacing cedilla
'sup1', "\xB9", # superscript 1
'ordm', "\xBA", # masculine ordinal indicator
'raquo', "\xBB", # angle quotation mark, right
'frac12', "\xBC", # fraction 1/2
'frac14', "\xBD", # fraction 1/4
'frac34', "\xBE", # fraction 3/4
'iquest', "\xBF", # inverted question mark
'Agrave', "\xC0", # capital A, grave accent
'Aacute', "\xC1", # capital A, acute accent
'Acirc', "\xC2", # capital A, circumflex accent
'Atilde', "\xC3", # capital A, tilde
'Auml', "\xC4", # capital A, dieresis or umlaut mark
'Aring', "\xC5", # capital A, ring
'AElig', "\xC6", # capital AE diphthong (ligature)
'Ccedil', "\xC7", # capital C, cedilla
'Egrave', "\xC8", # capital E, grave accent
'Eacute', "\xC9", # capital E, acute accent
'Ecirc', "\xCA", # capital E, circumflex accent
'Euml', "\xCB", # capital E, dieresis or umlaut mark
'Igrave', "\xCC", # capital I, grave accent
'Iacute', "\xCD", # capital I, acute accent
'Icirc', "\xCE", # capital I, circumflex accent
'Iuml', "\xCF", # capital I, dieresis or umlaut mark
'Dstrok', "\xD0", # capital Eth, Icelandic (Lynx)
'ETH', "\xD0", # capital Eth, Icelandic
'Ntilde', "\xD1", # capital N, tilde
'Ograve', "\xD2", # capital O, grave accent
'Oacute', "\xD3", # capital O, acute accent
'Ocirc', "\xD4", # capital O, circumflex accent
'Otilde', "\xD5", # capital O, tilde
'Ouml', "\xD6", # capital O, dieresis or umlaut mark
'times', "\xD7", # multiplication sign
'Oslash', "\xD8", # capital O, slash
'Ugrave', "\xD9", # capital U, grave accent
'Uacute', "\xDA", # capital U, acute accent
'Ucirc', "\xDB", # capital U, circumflex accent
'Uuml', "\xDC", # capital U, dieresis or umlaut mark
'Yacute', "\xDD", # capital Y, acute accent
'THORN', "\xDE", # capital THORN, Icelandic
'szlig', "\xDF", # small sharp s, German (sz ligature)
'agrave', "\xE0", # small a, grave accent
'aacute', "\xE1", # small a, acute accent
'acirc', "\xE2", # small a, circumflex accent
'atilde', "\xE3", # small a, tilde
'auml', "\xE4", # small a, dieresis or umlaut mark
'aring', "\xE5", # small a, ring
'aelig', "\xE6", # small ae diphthong (ligature)
'ccedil', "\xE7", # small c, cedilla
'egrave', "\xE8", # small e, grave accent
'eacute', "\xE9", # small e, acute accent
'ecirc', "\xEA", # small e, circumflex accent
'euml', "\xEB", # small e, dieresis or umlaut mark
'igrave', "\xEC", # small i, grave accent
'iacute', "\xED", # small i, acute accent
'icirc', "\xEE", # small i, circumflex accent
'iuml', "\xEF", # small i, dieresis or umlaut mark
'dstrok', "\xF0", # small eth, Icelandic (Lynx)
'eth', "\xF0", # small eth, Icelandic
'ntilde', "\xF1", # small n, tilde
'ograve', "\xF2", # small o, grave accent
'oacute', "\xF3", # small o, acute accent
'ocirc', "\xF4", # small o, circumflex accent
'otilde', "\xF5", # small o, tilde
'ouml', "\xF6", # small o, dieresis or umlaut mark
'divide', "\xF7", # division sign
'oslash', "\xF8", # small o, slash
'ugrave', "\xF9", # small u, grave accent
'uacute', "\xFA", # small u, acute accent
'ucirc', "\xFB", # small u, circumflex accent
'uuml', "\xFC", # small u, dieresis or umlaut mark
'yacute', "\xFD", # small y, acute accent
'thorn', "\xFE", # small thorn, Icelandic
'yuml', "\xFF", # small y, dieresis or umlaut mark
);
s/&(\w+);/exists $char_entity{ $1 } ? $char_entity{ $1 } : ' '/eg;
# Converted UTF codes for non-matching ISO-8859-1
# Strip it down to basic ASCII
%utf_entity = (
"\x{2019}", "'",
"\x{201c}", '"',
"\x{201d}", '"',
"\x{2026}", "...",
"\x{fffd}", "",
);
s/(\X)/ exists $utf_entity{$1} ? $utf_entity{$1} : $1 /eg;
##
# Output Doc text
##
print "\xF8$title\n" if $title;
print "$opt_u\n" if $opt_u;
print "$HR\n" if $title || $opt_u;
print "$_\n";
print "<$bookmark>\n" if $bookmarks;