.\" -*- mode: troff; coding: utf-8 -*-
.\" Automatically generated by Pod::Man v6.0.2 (Pod::Simple 3.48)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
.ie n \{\
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds C`
. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
. if \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{\
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\"
.\" Required to disable full justification in groff 1.23.0.
.if n .ds AD l
.\" ========================================================================
.\"
.IX Title "IO::HTML 3"
.TH IO::HTML 3 2026-10-26 "perl v5.44.0" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "CONFIGURATION AND ENVIRONMENT"
.IX Header "CONFIGURATION AND ENVIRONMENT"
There are two global variables that affect IO::HTML. If you need to
change them, you should do so using \f(CW\*(C`local\*(C'\fR if possible:
.PP
.Vb 5
\& my $file = do {
\& # This file may define the charset later in the header
\& local $IO::HTML::bytes_to_check = 4096;
\& html_file(...);
\& };
.Ve
.ie n .IP $bytes_to_check 4
.el .IP \f(CW$bytes_to_check\fR 4
.IX Item "$bytes_to_check"
This is the number of bytes that \f(CW\*(C`sniff_encoding\*(C'\fR will read from the
stream. It is also the number of bytes that \f(CW\*(C`find_charset_in\*(C'\fR will
search for a \f(CW\*(C`\*(C'\fR tag containing charset information.
It must be a positive integer.
.Sp
The HTML 5 specification recommends using the default value of 1024,
but some pages do not follow the specification.
.ie n .IP $default_encoding 4
.el .IP \f(CW$default_encoding\fR 4
.IX Item "$default_encoding"
This is the encoding that \f(CW\*(C`html_file\*(C'\fR and \f(CW\*(C`html_file_and_encoding\*(C'\fR
will use if no encoding can be detected by \f(CW\*(C`sniff_encoding\*(C'\fR.
The default value is \f(CW\*(C`cp1252\*(C'\fR (a.k.a. Windows\-1252).
.Sp
Setting it to \f(CW\*(C`undef\*(C'\fR will cause the file subroutines to croak if
\&\f(CW\*(C`sniff_encoding\*(C'\fR fails to determine the encoding. (\f(CW\*(C`sniff_encoding\*(C'\fR
itself does not use \f(CW$default_encoding\fR).
.SH DEPENDENCIES
.IX Header "DEPENDENCIES"
IO::HTML has no non\-core dependencies for Perl 5.8.7+. With earlier
versions of Perl 5.8, you need to upgrade Encode to at least
version {{ \f(CW$meta\fR{prereqs}{runtime}{requires}{Encode} // die }}, and
you may need to upgrade Exporter to at least version
{{ \f(CW$meta\fR{prereqs}{runtime}{requires}{Exporter} // die }}.
.PP
.Vb 1
\& $filehandle = html_file($filename, \e%options);
.Ve
.PP
This function (exported by default) is the primary entry point. It
opens the file specified by \f(CW$filename\fR for reading, uses
\&\f(CW\*(C`sniff_encoding\*(C'\fR to find a suitable encoding layer, and applies it.
It also applies the \f(CW\*(C`:crlf\*(C'\fR layer. If the file begins with a BOM,
the filehandle is positioned just after the BOM.
.PP
The optional second argument is a hashref containing options. The
possible keys are described under \f(CW\*(C`find_charset_in\*(C'\fR.
.PP
If \f(CW\*(C`sniff_encoding\*(C'\fR is unable to determine the encoding, it defaults
to \f(CW$IO::HTML::default_encoding\fR, which is set to \f(CW\*(C`cp1252\*(C'\fR
(a.k.a. Windows\-1252) by default. According to the standard, the
default should be locale dependent, but that is not currently
implemented.
.PP
It dies if the file cannot be opened, or if \f(CW\*(C`sniff_encoding\*(C'\fR cannot
determine the encoding and \f(CW$IO::HTML::default_encoding\fR has been set
to \f(CW\*(C`undef\*(C'\fR.
.PP
.Vb 2
\& ($filehandle, $encoding, $bom)
\& = html_file_and_encoding($filename, \e%options);
.Ve
.PP
This function (exported only by request) is just like \f(CW\*(C`html_file\*(C'\fR,
but returns more information. In addition to the filehandle, it
returns the name of the encoding used, and a flag indicating whether a
byte order mark was found (if \f(CW$bom\fR is true, the file began with a
BOM). This may be useful if you want to write the file out again
(especially in conjunction with the \f(CW\*(C`html_outfile\*(C'\fR function).
.PP
The optional second argument is a hashref containing options. The
possible keys are described under \f(CW\*(C`find_charset_in\*(C'\fR.
.PP
It dies if the file cannot be opened, or if \f(CW\*(C`sniff_encoding\*(C'\fR cannot
determine the encoding and \f(CW$IO::HTML::default_encoding\fR has been set
to \f(CW\*(C`undef\*(C'\fR.
.PP
The result of calling \f(CW\*(C`html_file_and_encoding\*(C'\fR in scalar context is undefined
(in the C sense of there is no guarantee what you\*(Aqll get).
.PP
The specified file could not be opened for reading for the reason
specified by \f(CW$!\fR.
.PP
The \f(CW\*(C`sniff_encoding\*(C'\fR algorithm didn\*(Aqt find an encoding to use, and
you set \f(CW$IO::HTML::default_encoding\fR to \f(CW\*(C`undef\*(C'\fR.
.PP
.Vb 1
\& $filehandle = html_outfile($filename, $encoding, $bom);
.Ve
.PP
This function (exported only by request) opens \f(CW$filename\fR for output
using \f(CW$encoding\fR, and writes a BOM to it if \f(CW$bom\fR is true.
If \f(CW$encoding\fR is \f(CW\*(C`undef\*(C'\fR, it defaults to \f(CW$IO::HTML::default_encoding\fR.
\&\f(CW$encoding\fR may be either an encoding name or an Encode::Encoding object.
.PP
It dies if the file cannot be opened, or if both \f(CW$encoding\fR and
\&\f(CW$IO::HTML::default_encoding\fR are \f(CW\*(C`undef\*(C'\fR.
.PP
.Vb 1
\& ($encoding, $bom) = sniff_encoding($filehandle, $filename, \e%options);
.Ve
.PP
This function (exported only by request) runs the HTML5 encoding
sniffing algorithm on \f(CW$filehandle\fR (which must be seekable, and
should have been opened in \f(CW\*(C`:raw\*(C'\fR mode). \f(CW$filename\fR is used only
for error messages (if there\*(Aqs a problem using the filehandle), and
defaults to "file" if omitted. The optional third argument is a
hashref containing options. The possible keys are described under
\&\f(CW\*(C`find_charset_in\*(C'\fR.
.PP
It returns Perl\*(Aqs canonical name for the encoding, which is not
necessarily the same as the MIME or IANA charset name. It returns
\&\f(CW\*(C`undef\*(C'\fR if the encoding cannot be determined. \f(CW$bom\fR is true if the
file began with a byte order mark. In scalar context, it returns only
\&\f(CW$encoding\fR.
.PP
The filehandle\*(Aqs position is restored to its original position
(normally the beginning of the file) unless \f(CW$bom\fR is true. In that
case, the position is immediately after the BOM.
.PP
Tip: If you want to run \f(CW\*(C`sniff_encoding\*(C'\fR on a file you\*(Aqve already
loaded into a string, open an in\-memory file on the string, and pass
that handle:
.PP
.Vb 3
\& ($encoding, $bom) = do {
\& open(my $fh, \*(Aq<\*(Aq, \e$string); sniff_encoding($fh)
\& };
.Ve
.PP
(This only makes sense if \f(CW$string\fR contains bytes, not characters.)
.PP
The specified file could not be read from for the reason specified by \f(CW$!\fR.
.PP
The specified file could not be rewound for the reason specified by \f(CW$!\fR.
.PP
.Vb 1
\& $encoding = find_charset_in($string_containing_HTML, \e%options);
.Ve
.PP
This function (exported only by request) looks for charset information
in a \f(CW\*(C`\*(C'\fR tag in a possibly\-incomplete HTML document using
the "two step" algorithm specified by HTML5. It does not look for a BOM.
The \f(CW\*(C`\*(C'\fR tag must begin within the first \f(CW$IO::HTML::bytes_to_check\fR
bytes of the string.
.PP
It returns Perl\*(Aqs canonical name for the encoding, which is not
necessarily the same as the MIME or IANA charset name. It returns
\&\f(CW\*(C`undef\*(C'\fR if no charset is specified or if the specified charset is not
recognized by the Encode module.
.PP
The optional second argument is a hashref containing options. The
following keys are recognized:
.ie n .IP """encoding""" 4
.el .IP \f(CWencoding\fR 4
.IX Item "encoding"
If true, return the Encode::Encoding object instead of its name.
Defaults to false.
.ie n .IP """need_pragma""" 4
.el .IP \f(CWneed_pragma\fR 4
.IX Item "need_pragma"
If true (the default), follow the HTML5 spec and examine the
\&\f(CW\*(C`content\*(C'\fR attribute only of \f(CW\*(C`new_from_file(
\& html_file(\*(Aqfoo.html\*(Aq)
\& );
\&
\& # Alternative interface:
\& open(my $in, \*(Aq<:raw\*(Aq, \*(Aqbar.html\*(Aq);
\& my $encoding = IO::HTML::sniff_encoding($in, \*(Aqbar.html\*(Aq);
.Ve
.SH DESCRIPTION
.IX Header "DESCRIPTION"
IO::HTML provides an easy way to open a file containing HTML while
automatically determining its encoding. It uses the HTML5 encoding
sniffing algorithm specified in section 8.2.2.2 of the draft standard.
.PP
The algorithm as implemented here is:
.IP 1. 4
If the file begins with a byte order mark indicating UTF\-16LE,
UTF\-16BE, or UTF\-8, then that is the encoding.
.IP 2. 4
If the first \f(CW$bytes_to_check\fR bytes of the file contain a \f(CW\*(C`\*(C'\fR tag that
indicates the charset, and Encode recognizes the specified charset
name, then that is the encoding. (This portion of the algorithm is
implemented by \f(CW\*(C`find_charset_in\*(C'\fR.)
.Sp
The \f(CW\*(C`\*(C'\fR tag can be in one of two formats:
.Sp
.Vb 2
\&
\&
.Ve
.Sp
The search is case\-insensitive, and the order of attributes within the
tag is irrelevant. Any additional attributes of the tag are ignored.
The first matching tag with a recognized encoding ends the search.
.IP 3. 4
If the first \f(CW$bytes_to_check\fR bytes of the file are valid UTF\-8 (with at least 1
non\-ASCII character), then the encoding is UTF\-8.
.IP 4. 4
If all else fails, use the default character encoding. The HTML5
standard suggests the default encoding should be locale dependent, but
currently it is always \f(CW\*(C`cp1252\*(C'\fR unless you set
\&\f(CW$IO::HTML::default_encoding\fR to a different value. Note:
\&\f(CW\*(C`sniff_encoding\*(C'\fR does not apply this step; only \f(CW\*(C`html_file\*(C'\fR does
that.
.SH "SEE ALSO"
.IX Header "SEE ALSO"
The HTML5 specification, section 8.2.2.2 Determining the character encoding:
.SH "POD ERRORS"
.IX Header "POD ERRORS"
Hey! \fBThe above document had some coding errors, which are explained below:\fR
.IP "Around line 90:" 4
.IX Item "Around line 90:"
Unknown directive: =sub
.IP "Around line 120:" 4
.IX Item "Around line 120:"
Unknown directive: =sub
.IP "Around line 157:" 4
.IX Item "Around line 157:"
Unknown directive: =diag
.IP "Around line 162:" 4
.IX Item "Around line 162:"
Unknown directive: =diag
.IP "Around line 184:" 4
.IX Item "Around line 184:"
Unknown directive: =sub
.IP "Around line 219:" 4
.IX Item "Around line 219:"
Unknown directive: =sub
.IP "Around line 268:" 4
.IX Item "Around line 268:"
Unknown directive: =diag
.IP "Around line 272:" 4
.IX Item "Around line 272:"
Unknown directive: =diag
.IP "Around line 365:" 4
.IX Item "Around line 365:"
Unknown directive: =sub