From ee46374edfb377f57169f2b1de9afd19bf052da2 Mon Sep 17 00:00:00 2001
From: fukachan
Date: Thu, 18 Oct 2001 08:32:16 +0000
Subject: Initial revision
---
cpan/dist/HTML-FromText/FromText.pm | 736 ++++++++++++++++++++++++++++++++++
cpan/dist/HTML-FromText/MANIFEST | 6 +
cpan/dist/HTML-FromText/Makefile.PL | 5 +
cpan/dist/HTML-FromText/README | 58 +++
cpan/dist/HTML-FromText/TODO | 33 ++
cpan/dist/HTML-FromText/t/text2html.t | 698 ++++++++++++++++++++++++++++++++
6 files changed, 1536 insertions(+)
create mode 100644 cpan/dist/HTML-FromText/FromText.pm
create mode 100644 cpan/dist/HTML-FromText/MANIFEST
create mode 100644 cpan/dist/HTML-FromText/Makefile.PL
create mode 100644 cpan/dist/HTML-FromText/README
create mode 100644 cpan/dist/HTML-FromText/TODO
create mode 100644 cpan/dist/HTML-FromText/t/text2html.t
(limited to 'cpan/dist/HTML-FromText')
diff --git a/cpan/dist/HTML-FromText/FromText.pm b/cpan/dist/HTML-FromText/FromText.pm
new file mode 100644
index 00000000..2b7f1753
--- /dev/null
+++ b/cpan/dist/HTML-FromText/FromText.pm
@@ -0,0 +1,736 @@
+require 5.004;
+use strict;
+
+package HTML::FromText;
+use Carp;
+use Exporter;
+use Text::Tabs 'expand';
+use vars qw($RCSID $VERSION $QUIET @EXPORT @ISA);
+
+@ISA = qw(Exporter);
+@EXPORT = qw(text2html);
+$RCSID = q$Id: FromText.pm,v 1.14 1999/10/06 10:53:37 garethr Exp $;
+$VERSION = '1.005';
+$QUIET = 0;
+
+# This list of protocols is taken from RFC 1630: "Universal Resource
+# Identifiers in WWW". The protocol "file" is omitted because
+# experience suggests that it results in many false positives; "https"
+# postdates RFC 1630. The protocol "mailto" is handled separately, by
+# the email address matching code.
+
+my $protocol = join '|',
+ qw(afs cid ftp gopher http https mid news nntp prospero telnet wais);
+
+# The regular expressions matching email addresses use the following
+# syntax elements from RFC 822. I can't use the full details of
+# structured field bodies, because that would give too many false
+# positives. (See Tom Christiansen's ckaddr.gz for a full
+# implementation of the RFC 822.)
+#
+# addr-spec = local-part "@" domain
+# local-part = word *("." word)
+# word = atom
+# domain = sub-domain *("." sub-domain)
+# sub-domain = domain-ref
+# domain-ref = atom
+# atom = 1*
+# specials = "(" / ")" / "<" / ">" / "@" / "," / ";" / ":" / "\"
+# / <"> / "." / "[" / "]"
+#
+# I have ignored quoting, domain literals and comments.
+#
+# Note that '&' can legally appear in email addresses (for example,
+# 'fred&barney@stonehenge.com'). If the 'metachars' option is passed to
+# text2html then I must use '&' to recognize '&'. Thus the regular
+# expression $atom[0] recognizes an atom in the case where the option
+# 'metachars' is false; $atom[1] recognizes an atom in the case where
+# 'metachars' is true. Similarly for the regular expressions $email[0]
+# and $email[1], which recognize email addresses.
+
+my @atom =
+ ( '[!#$%&\'*+\\-/0123456789=?ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~]+',
+ '(?:&|[!#$%\'*+\\-/0123456789=?ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~])+' );
+
+my @email = ( "$atom[0](\\.$atom[0])*\@$atom[0](\\.$atom[0])*",
+ "$atom[1](\\.$atom[1])*\@$atom[1](\\.$atom[1])*" );
+
+my @alignments = ( '', '', ' ALIGN="RIGHT"', ' ALIGN="CENTER"' );
+
+sub string2html ($$) {
+ my $options = $_[1];
+ for ($_[0]) { # Modify in-place.
+
+ # METACHARS: mark up HTML metacharacters as corresponding entities.
+ if ($options->{metachars}) {
+ s/&/&/g;
+ s/</g;
+ s/>/>/g;
+ s/\"/"/g;
+ }
+
+ # EMAIL, URLS: spot electronic mail addresses and turn them into
+ # links. Note (1) if `urls' is set but not `email', then only
+ # addresses prefixed by `mailto:' will be marked up; (2) that we leave
+ # the `mailto:' prefix in the anchor text.
+ if ($options->{email} or $options->{urls}) {
+ s|((?:mailto:)?)($email[$options->{metachars}?1:0])|
+ ($options->{email} or $1)
+ ? "$1$2" : $2|gex;
+ }
+
+ # URLS: mark up URLs as links (note that `mailto' links are handled
+ # above).
+ if ($options->{urls}) {
+ s|\b((?:$protocol):\S+[\w/])|$1|g;
+ }
+
+ # BOLD: mark up words in *asterisks* as bold.
+ if ($options->{bold}) {
+ s#(^|\s)\*([^*]+)\*(?=\s|$)#$1$2#g;
+ }
+
+ # UNDERLINE: mark up words in _underscores_ as underlined.
+ if ($options->{underline}) {
+ s#(^|\s)_([^_]+?)_(?=\s|$)#$1$2#g;
+ }
+ }
+
+ return $_[0];
+}
+
+sub text2html {
+ local $_ = shift; # Take a copy; don't modify in-place.
+ return $_ unless $_;
+
+ my %options = ( metachars => 1, @_ );
+
+ # Check options for sanity.
+ unless ($QUIET) {
+ carp "text2html: `spaces' will be ignored since `lines' is not specified"
+ if $options{spaces} and not $options{lines};
+ if ($options{paras}) {
+ if ($options{blockparas}) {
+ foreach my $o (qw(blockquotes blockcode)) {
+ carp "text2html: `$o' will be ignored since `blockparas' is specified" if $options{$o};
+ }
+ } elsif ($options{blockcode} and $options{blockquotes}) {
+ carp "text2html: `blockquotes' will be ignored since `blockcode' is specified";
+ }
+ } else {
+ foreach my $o (qw(bullets numbers blockquotes blockparas blockcode
+ title headings tables)) {
+ carp "text2html: `$o' will be ignored since `paras' is not specified"
+ if $options{$o};
+ }
+ }
+ }
+
+ # Expand tabs.
+ $_ = join "\n", expand(split /\r?\n/);
+
+ # PRE: put text in element.
+ if ($options{pre}) {
+ string2html($_, \%options);
+ s|^||;
+ s|$|
|;
+ }
+
+ # LINES: preserve line breaks from original text.
+ elsif ($options{lines}) {
+ string2html($_, \%options);
+ s/\n/
\n/gm;
+
+ # SPACES: preserve spaces from original text.
+ s/ / /g if $options{spaces};
+ }
+
+ # PARAS: treat text as sequence of paragraphs.
+ elsif ($options{paras}) {
+ my @paras;
+
+ # Remove initial and final blank lines.
+ s/^(?:\s*?\n)+//;
+ s/(?:\n\s*?)+$//;
+
+ # Split on a different regexp depending on what kinds of paragraphs
+ # will be recognised later. The idea is that bulleted lists like
+ # this:
+ #
+ # * item 1
+ # * item 2
+ #
+ # will be recognised as multiple paragraphs if the 'bullets' option
+ # is supplied, but as a single paragraph otherwise. (Similarly for
+ # numbered lists).
+ if ($options{bullets} and $options{numbers}) {
+ @paras = split
+ /(?:\s*\n)+ # (0 or more blank lines, followed by LF)
+ (?:\s*\n # Either 1 or more blank lines, or
+ |(?=\s*[*-]\s+ # bulleted item follows, or
+ |\s*(?:\d+)[.\)\]]?\s+)) # numbered item follows
+ /x;
+ } elsif ($options{bullets}) {
+ @paras = split
+ /(?:\s*\n)+ # (0 or more blank lines, followed by LF)
+ (?:\s*\n # Either 1 or more blank lines, or
+ |(?=\s*[*-]\s+)) # bulleted item follows.
+ /x;
+ } elsif ($options{numbers}) {
+ @paras = split
+ /(?:\s*\n)+ # (0 or more blank lines, followed by LF)
+ (?:\s*\n # Either 1 or more blank lines, or
+ |(?=\s*(?:\d+)[.\)\]]?\s+)) # numbered item follows.
+ /x;
+ } else {
+ @paras = split
+ /\s*\n(?:\s*\n)+ # 1 or more blank lines.
+ /x;
+ }
+
+ my $last = ''; # List type (OL/UL) of last paragraph
+ my $this; # List type (OL/UL) of this paragraph
+ my $first = 1; # True if this is first paragraph
+
+ foreach (@paras) {
+ my (@rows,@starts,@ends);
+ $this = '';
+
+ # TITLE: mark up first paragraph as level-1 heading.
+ if ($options{title} and $first) {
+ string2html($_,\%options);
+ s|^||;
+ s|$|
|;
+ }
+
+ # HEADINGS: mark up paragraphs with numbers at the start of the
+ # first line as headings.
+ elsif ($options{headings} and /^(\d+(\.\d+)*)\.?\s/) {
+ my $number = $1;
+ my $level = 1 + ($number =~ tr/././);
+ $level = 6 if $level > 6;
+ string2html($_,\%options);
+ s|^||;
+ s|$||;
+ }
+
+ # BULLETS: mark up paragraphs starting with bullets as items in an
+ # unnumbered list.
+ elsif ($options{bullets} and /^\s*[*-]\s+/) {
+ string2html($_,\%options);
+ s/^\s*[*-]\s+//;
+ s|$|
|;
+ $this = 'UL';
+ }
+
+ # NUMBERS: mark up paragraphs starting with numbers as items in a
+ # numbered list.
+ elsif ($options{numbers} and /^\s*(\d+)[.\)\]]?\s+/) {
+ string2html($_,\%options);
+ s/^\s*(\d+)[.\)\]]?\s+//;
+ s|$|
|;
+ $this = 'OL';
+ }
+
+ # TABLES: spot and mark up tables. We combine the lines of the
+ # paragraph using the string bitwise or (|) operator, the result
+ # being in $spaces. A character in $spaces is a space only if
+ # there was a space at that position in every line of the
+ # paragraph. $space can be used to search for contiguous spaces
+ # that occur on all lines of the paragraph. If this results in at
+ # least two columns, the paragraph is identified as a table.
+ #
+ # Note that this option appears before the various 'blockquotes'
+ # options because a table may well have whitespace to the left, in
+ # which case it must not be incorrectly recognised as a
+ # blockquote.
+ elsif ($options{tables} and do {
+ @rows = split /\n/, $_;
+ my $spaces;
+ my $max = 0;
+ my $min = length;
+ foreach my $row (@rows) {
+ ($spaces |= $row) =~ tr/ /\xff/c;
+ $min = length $row if length $row < $min;
+ $max = length $row if $max < length $row;
+ }
+ $spaces = substr $spaces, 0, $min;
+ push(@starts, 0) unless $spaces =~ /^ /;
+ while ($spaces =~ /((?:^| ) +)(?=[^ ])/g) {
+ push @ends, pos($spaces) - length $1;
+ push @starts, pos($spaces);
+ }
+ shift(@ends) if $spaces =~ /^ /;
+ push(@ends, $max);
+
+ # Two or more rows and two or more columns indicate a table.
+ 2 <= @rows and 2 <= @starts
+ }) {
+ # For each column, guess whether it should be left, centre or
+ # right aligned by examining all cells in that column for space
+ # to the left or the right. A simple majority among those cells
+ # that actually have space to one side or another decides (if no
+ # alignment gets a majority, left alignment wins by default).
+
+ my @align;
+ foreach my $col (0 .. $#starts) {
+ my @count = (0, 0, 0, 0);
+ foreach my $row (@rows) {
+ my $width = $ends[$col] - $starts[$col];
+ my $cell = substr $row, $starts[$col], $width;
+ ++ $count[($cell =~ /^ / ? 2 : 0)
+ + ($cell =~ / $/ || length($cell) < $width ? 1 : 0)];
+ }
+ $align[$col] = 0;
+ my $population = $count[1] + $count[2] + $count[3];
+ foreach (1 .. 3) {
+ if ($count[$_] * 2 > $population) {
+ $align[$col] = $_;
+ last;
+ }
+ }
+ }
+
+ foreach my $row (@rows) {
+ $row = join '', '', (map {
+ my $cell = substr $row, $starts[$_], $ends[$_] - $starts[$_];
+ $cell =~ s/^ +//;
+ $cell =~ s/ +$//;
+ string2html($cell,\%options);
+ ('| ', $cell, ' | ')
+ } 0 .. $#starts), '
';
+ }
+ my $tag = $starts[0] == 0 ? 'P' : 'BLOCKQUOTE';
+ $_ = join "\n", "<$tag>$tag>";
+ }
+
+ # BLOCKPARAS, BLOCKCODE, BLOCKQUOTES: mark up indented paragraphs
+ # as block quotes of various kinds.
+ elsif (($options{blockparas} or $options{blockquotes}
+ or $options{blockcode}) and /^(\s+).*(?:\n\1.*)*$/) {
+ string2html($_,\%options);
+
+ # Every line in the paragraph starts with at white space, the common
+ # whitespace being in $1. Remove the common initial whitespace,
+ s/^$1//gm;
+
+ # BLOCKPARAS: treat as a paragraph.
+ if ($options{blockparas}) {
+ s|^||;
+ s|$|
|;
+ }
+
+ # BLOCKCODE, BLOCKQUOTES: preserve line breaks.
+ else {
+ s/\n/
\n/gm;
+
+ # BLOCKCODE: preserve spaces, use fixed-width font.
+ if ($options{blockcode}) {
+ s| | |g;
+ s|^||;
+ s|$||;
+ }
+ }
+ s|^||;
+ s|$|
|;
+ }
+
+ # Didn't match any of the above, so just an ordinary paragraph.
+ else {
+ string2html($_,\%options);
+ s|^||;
+ s|$|
|;
+ }
+
+ # Insert , or
if this paragraph belongs to a
+ # different list type than the previous one.
+ if ($this ne $last) {
+ s|^|<$this>| if ($this ne '');
+ s|^|$last>| if ($last ne '');
+ }
+ $last = $this;
+ $first = 0;
+ }
+ if ($this ne '') {
+ push @paras, "$this>";
+ }
+ $_ = join "\n", @paras;
+ }
+
+ # None of PRE, LINES, PARAS specified: apply basic transformations.
+ else {
+ string2html($_,\%options);
+ }
+ return $_;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+HTML::FromText - mark up text as HTML
+
+=head1 SYNOPSIS
+
+ use HTML::FromText;
+ print text2html($text, urls => 1, paras => 1, headings => 1);
+
+=head1 DESCRIPTION
+
+The C function marks up plain text as HTML. By default it
+expands tabs and converts HTML metacharacters into the corresponding
+entities. More complicated transformations, such as splitting the text
+into paragraphs or marking up bulleted lists, can be carried out by
+setting the appropriate options.
+
+=head1 SUMMARY OF OPTIONS
+
+These options always apply:
+
+ metachars Convert HTML metacharacters to entity references
+ urls Convert URLs to links
+ email Convert email addresses to links
+ bold Mark up words with *asterisks* in bold
+ underline Mark up words with _underscores_ as underlined
+
+You can then choose to treat the text according to one of these options:
+
+ pre Treat text as preformatted
+ lines Treat text as line-oriented
+ paras Treat text as paragraph-oriented
+
+(If more than one of these is specified, C takes precedence over
+C which takes precedence over C.) The following option
+applies when the C option is specified:
+
+ spaces Preserve spaces from the original text
+
+The following options apply when the C option is specified:
+
+ blockparas Mark up indented paragraphs as block quote
+ blockquotes Ditto, also preserve lines from original
+ blockcode Ditto, also preserve spaces from original
+ bullets Mark up bulleted paragraphs as unordered list
+ headings Mark up headings
+ numbers Mark up numbered paragraphs as ordered list
+ tables Mark up tables
+ title Mark up first paragraph as level 1 heading
+
+C will issue a warning if it is passed nonsensical options,
+for example C but not C. These warnings can be
+supressed by setting $HTML::FromText::QUIET to true.
+
+=head1 OPTIONS
+
+=over 4
+
+=item blockparas
+
+=item blockquotes
+
+=item blockcode
+
+These options cause to C to spot paragraphs where every line
+begins with whitespace, and mark them up as block quotes. If more than
+one of these options is specified, C takes precedence over
+C, which takes precedence over C. All three
+options are ignored unless the C option is also set.
+
+The C option marks up the paragraph as a block quote with no
+other changes. For example,
+
+ Turing wrote,
+
+ I propose to consider the question,
+ "Can machines think?"
+
+becomes
+
+ Turing wrote,
+ I propose to consider the question,
+ "Can machines think?"
+
+The C option preserves line breaks in the original text.
+For example,
+
+ From "The Waste Land":
+
+ Phlebas the Phoenecian, a fortnight dead,
+ Forgot the cry of gulls, and the deep sea swell
+
+becomes
+
+ From "The Waste Land":
+ Phlebas the Phoenecian, a fortnight dead,
+ Forgot the cry of gulls, and the deep sea swell
+
+The C option preserves line breaks and spaces in the original
+text and renders the paragraph in a fixed-width font. For example:
+
+ Here's how to output numbers with commas:
+
+ sub commify {
+ local $_ = shift;
+ 1 while s/^(-?\d+)(\d{3})/$1,$2/;
+ $_;
+ }
+
+becomes
+
+ Here's how to output numbers with commas:
+ sub commify {
+ local $_ = shift;
+ 1 while s/^(-?\d+)(\d{3})/$1,$2/;
+ $_;
+ }
+
+=item bold
+
+Words surrounded with asterisks are marked up in bold, so C<*abc*>
+becomes CBEabcE/BE>.
+
+=item bullets
+
+Spots bulleted paragraphs (beginning with optional whitespace, an
+asterisk or hyphen, and whitespace) and marks them up as an unordered
+list. Bulleted paragraphs don't have to be separated by blank lines.
+For example,
+
+ Shopping list:
+
+ * apples
+ * pears
+
+becomes
+
+ Shopping list:
+
+
+This option is ignored unless the C option is set.
+
+=item email
+
+Spots email addresses in the text and converts them to links. For example
+
+ Mail me at web@perl.com.
+
+becomes
+
+ Mail me at web@perl.com.
+
+=item headings
+
+Spots headings (paragraphs starting with numbers) and marks them up as
+headings of the appropriate level. For example,
+
+ 1. Introduction
+
+ 1.1 Background
+
+ 1.1.1 Previous work
+
+ 2. Conclusion
+
+becomes
+
+ 1. Introduction
+ 1.1 Background
+ 1.1.1 Previous work
+ 2. Conclusion
+
+This option is ignored unless the C option is set.
+
+=item lines
+
+Formats the text so as to preserve line breaks. For example,
+
+ Line 1
+ Line 2
+
+becomes
+
+ Line 1
+ Line 2
+
+If two or more of the options C, C and C are set,
+then C takes precedence over C, which takes precedence over
+C.
+
+=item metachars
+
+Converts HTML metacharacters into their corresponding entity references.
+Ampersand (C>) becomes Camp;>, less than (C>)
+becomes Clt;>, greater than (C>) becomes Cgt;>, and
+quote (") becomes Cquot;>. This option is 1 by default.
+
+=item numbers
+
+Spots numbered paragraphs (beginning with whitespace, digits, an
+optional period/parenthesis/bracket, and whitespace) and marks them up
+as an ordered list. Numbered paragraphs don't have to be separated by
+blank lines. For example,
+
+ To do:
+
+ 1. Write thesis
+ 2. Submit it
+ 3. Celebrate
+
+becomes
+
+ To do:
+ Write thesis
+ Submit it
+ Celebrate
+
+
+This option is ignored unless the C option is set.
+
+=item paras
+
+Format the text into paragraphs. Paragraphs are separated by one or
+more blank lines. For example,
+
+ Paragraph 1
+
+ Paragraph 2
+
+becomes
+
+ Paragraph 1
+ Paragraph 2
+
+If two or more of the options C, C and C are set,
+then C takes precedence over C, which takes precedence over
+C.
+
+=item pre
+
+Wrap the whole input in a CPREE> element. For example,
+
+ preformatted
+ text
+
+becomes
+
+ preformatted
+ text
+
+If two or more of the options C, C and C are set,
+then C takes precedence over C, which takes precedence over
+C.
+
+=item spaces
+
+Preserves spaces throughout the text. For example,
+
+ Line 1
+ Line 2
+ Line 3
+
+becomes
+
+ Line 1
+ Line 2
+ Line 3
+
+This option is ignored unless the C option is set.
+
+=item tables
+
+Spots tables and marks them up appropriately. Columns must be separated
+by two or more spaces (this prevents accidental incorrect recognition of
+a paragraph where interword spaces happen to line up). If there are two
+or more rows in a paragraph and all rows share the same set of (two or
+more) columns, the paragraph is assumed to be a table. For example
+
+ -e File exists.
+ -z File has zero size.
+ -s File has nonzero size (returns size).
+
+becomes
+
+
+ | -e | File exists. |
+ | -z | File has zero size. |
+ | -s | File has nonzero size (returns size). |
+
+
+C guesses for each column whether it is intended to be left,
+centre or right aligned.
+
+This option is ignored unless the C option is set.
+
+=item title
+
+Formats the first paragraph of the text as a first-level heading.
+For example,
+
+ Paragraph 1
+
+ Paragraph 2
+
+becomes
+
+ Paragraph 1
+ Paragraph 2
+
+This option is ignored unless the C option is set.
+
+=item underline
+
+Words surrounded with underscores are marked up with underline, so C<_abc_>
+becomes CUEabcE/UE>.
+
+=item urls
+
+Spots Uniform Resource Locators (URLs) in the text and converts them
+to links. For example
+
+ See https://perl.com/.
+
+becomes
+
+ See https://perl.com/.
+
+=back
+
+=head1 SEE ALSO
+
+The C module (part of the LWP package) provides
+functions for encoding and decoding HTML entities.
+
+Tom Christiansen has a complete implementation of RFC 822 structured
+field bodies. See
+C.
+
+Seth Golub's C utility does everything that C
+does, and a few things that it would like to do. See
+C.
+
+RFC 822: "Standard for the Format of ARPA Internet Text Messages"
+describes the syntax of email addresses (the more esoteric features of
+structured field bodies, in particular quoted-strings, domain literals
+and comments, are not recognized by C). See
+C.
+
+RFC 1630: "Universal Resource Identifiers in WWW" lists the protocols
+that may appear in URLs. C also recognizes "https:",
+but ignores "file:" because experience suggests that it results in too
+many false positives. See C.
+
+=head1 AUTHOR
+
+Gareth Rees Cgarethr@cre.canon.co.ukE>.
+
+=head1 COPYRIGHT
+
+Copyright (c) 1999 Canon Research Centre Europe. All rights reserved.
+This module is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=cut
diff --git a/cpan/dist/HTML-FromText/MANIFEST b/cpan/dist/HTML-FromText/MANIFEST
new file mode 100644
index 00000000..1d625b62
--- /dev/null
+++ b/cpan/dist/HTML-FromText/MANIFEST
@@ -0,0 +1,6 @@
+FromText.pm
+MANIFEST
+Makefile.PL
+README
+TODO
+t/text2html.t
diff --git a/cpan/dist/HTML-FromText/Makefile.PL b/cpan/dist/HTML-FromText/Makefile.PL
new file mode 100644
index 00000000..e73edc44
--- /dev/null
+++ b/cpan/dist/HTML-FromText/Makefile.PL
@@ -0,0 +1,5 @@
+use ExtUtils::MakeMaker;
+WriteMakefile( NAME => 'HTML::FromText',
+ VERSION_FROM => 'FromText.pm',
+ dist => { COMPRESS => 'gzip', SUFFIX => 'gz' },
+ );
diff --git a/cpan/dist/HTML-FromText/README b/cpan/dist/HTML-FromText/README
new file mode 100644
index 00000000..cf740136
--- /dev/null
+++ b/cpan/dist/HTML-FromText/README
@@ -0,0 +1,58 @@
+NAME
+ HTML::FromText - mark up text as HTML
+
+SYNOPSIS
+ use HTML::FromText;
+ print text2html($text, urls => 1, paras => 1, headings => 1);
+
+DESCRIPTION
+ The text2html function marks up plain text as HTML. By
+ default it converts HTML metacharacters into the
+ corresponding entities. More sophisticated transformations,
+ such as splitting the text into paragraphs or marking up
+ bulleted lists, can be carried out by setting the
+ appropriate options.
+
+INSTALLATION
+ perl Makefile.PL && make && make test && make install
+
+HISTORY
+ 1.005 Options 'bold' and 'underline' are more aggressive in
+ recognising markup.
+
+ 1.004 New options 'blockparas' (mark up block quotes as ordinary
+ paragraphs) and 'blockcode' (mark up block quotes in
+ fixed-width font while preserving line breaks and spaces).
+
+ Tabs are expanded throughout the text (it was a bug not to
+ do so in earlier versions because alignment could be lost,
+ block quotes not recognised, etc).
+
+ New option 'tables'.
+
+ 1.003 Recognize '&' in email addresses, as specified by RFC822.
+
+ 1.002 Much improved recognition of e-mail addresses with special
+ characters, as specified by RFC822.
+
+ When 'urls' is supplied, the prefix mailto: on email
+ addresses is preserved.
+
+ New option 'pre' wraps text in ...
.
+
+ When anchor text is in fixed-width font, the element is
+ inside the element, as required by the HTML DTD.
+
+ 1.001 Original CPAN release.
+
+BUGS
+ There are transformations it doesn't do.
+
+AUTHOR
+ Gareth Rees .
+
+COPYRIGHT
+ Copyright (c) 1999 Canon Research Centre Europe. All rights
+ reserved. This module is free software; you can
+ redistribute it and/or modify it under the same terms as
+ Perl itself.
diff --git a/cpan/dist/HTML-FromText/TODO b/cpan/dist/HTML-FromText/TODO
new file mode 100644
index 00000000..6ebf6838
--- /dev/null
+++ b/cpan/dist/HTML-FromText/TODO
@@ -0,0 +1,33 @@
+---------------------------------IDEAS----------------------------------
+
+1. Have a more general means of representing paragraph transformations
+ and applying them so that text2html can be extended. Each
+ transformation would have (a) an option name, (b) a sub for testing
+ whether the transformation is applicable to the paragraph and (c) a
+ sub for applying the option. (There must be a means of passing
+ information from step (b) to step (c) as for the table
+ transformation.)
+
+ (But are there that many other transformations that can be applied on
+ a paragraph basis? Other kinds of transformations would be harder to
+ generalise like this. Think about the need to have a different idea
+ about where paragraph boundaries are depending on the options.)
+
+2. The current approach is to test the transformations for applicability
+ one by one and apply the first one that matches. It might be better
+ to test all the transformations and score them, then apply the
+ best scoring. This would allow heuristics to be applied.
+
+3. The current approach goes through the paragraphs one by one with no
+ lookahead. Multiple passes through the paragraphs could allow
+ heuristics to be applied, e.g., to distinguish nested lists from
+ adjacent lists.
+
+4. These transformations could be implemented:
+
+ * lettered paragraphs a) b) c) etc
+
+ * underlined headings
+
+ * quoted text in e-mail message (impossible to accurately given the
+ enormous diversity of quoting styles -- would 60% be good enough?)
diff --git a/cpan/dist/HTML-FromText/t/text2html.t b/cpan/dist/HTML-FromText/t/text2html.t
new file mode 100644
index 00000000..0e78a21c
--- /dev/null
+++ b/cpan/dist/HTML-FromText/t/text2html.t
@@ -0,0 +1,698 @@
+# HTML::FromText test suite (-*- cperl -*-)
+
+use strict;
+use HTML::FromText;
+$^W = 1;
+
+# Each test is represented by three data chunks, separated by a line
+# containing only a form-feed character (0x0c). The first chunk is
+# the options to pass to text2html(), the second is the input, and the
+# third the expected output.
+
+$/ = "\n\f\n";
+my @tests = ();
+while () {
+ chomp;
+ push @tests, $_;
+}
+my $n = @tests / 3;
+print "1..$n\n";
+foreach my $i (1..$n) {
+ my $j = 3 * ($i - 1);
+ my $input = $tests[$j + 1];
+ my $expected = $tests[$j + 2];
+ my @options = eval $tests[$j];
+ my $output = text2html($input, @options);
+ unless ($output eq $expected) {
+ print STDERR
+ "\n",'--expected','-'x60,
+ "\n",$expected,
+ "\n",'--but-found','-'x59,
+ "\n",$output,
+ "\n",'-'x70,
+ "\n";
+ print "not ";
+ }
+ print "ok $i\n";
+}
+
+__DATA__
+
+()
+
+<&>
+
+<B><&></B>
+
+
+(metachars => 0)
+
+<&>
+
+<&>
+
+
+(email => 1)
+
+real@email.address, real2@email.addresss.
+fake@:email.address, another@[fake].address
+mailto:me@foo.bar.com
+
+#$%=strange!?@characters.=+=in=+=_.address
+
+real@email.address, real2@email.addresss.
+fake@:email.address, another@[fake].address
+mailto:me@foo.bar.com
+<tricky@subdomain.domain>
+#$%=strange!?@characters.=+=in=+=_.address
+
+
+(metachars => 1, email => 1)
+
+An email address with an & in it: fred&barney@stonehenge.com.
+
+An email address with an & in it: fred&barney@stonehenge.com.
+
+
+(metachars => 0, email => 1)
+
+An email address with an & in it: fred&barney@stonehenge.com. Generates
+non-legal HTML, but that was what was asked for!
+
+An email address with an & in it: fred&barney@stonehenge.com. Generates
+non-legal HTML, but that was what was asked for!
+
+
+(urls => 1)
+
+See http://foo.bar.com.
+What about http://foo.com/bar/baz?
+http://foo.com/bar/baz?quux.
+ftp://spong.gov/a/b/c/d.e/f.g/h/ should have trailing /
+...gopher://x.y.z/foo...
+mailto:mail@address.com is translated
+but mail@address.com on its own is not
+
+See http://foo.bar.com.
+What about http://foo.com/bar/baz?
+http://foo.com/bar/baz?quux.
+ftp://spong.gov/a/b/c/d.e/f.g/h/ should have trailing /
+...gopher://x.y.z/foo...
+mailto:mail@address.com is translated
+but mail@address.com on its own is not
+
+
+(bold => 1, underline => 1)
+
+*Words* in *bold* _underline_ and *bold* again, but 5*4, 3_1 unaffected;
+_underline_ *more* *bold*
+_more_ _underline_
+Now *several words in bold* and _several in underline_ but
+equations like 5*x + 5*y or zeta_i + phi_i are not marked up.
+Here's a *phrase in bold
+crossing a newline* and an _underlined phrase
+crossing a newline_
+Single letter words: *a* _b_ *c* _d_
+
+Words in bold underline and bold again, but 5*4, 3_1 unaffected;
+underline more bold
+more underline
+Now several words in bold and several in underline but
+equations like 5*x + 5*y or zeta_i + phi_i are not marked up.
+Here's a phrase in bold
+crossing a newline and an underlined phrase
+crossing a newline
+Single letter words: a b c d
+
+
+(paras => 1, bold => 1, underline => 1)
+
+*Bold* works OK in a paragraph context
+and so does _underline_
+
+_Underline works OK_ in a paragraph context
+and *so does bold*
+
+Bold works OK in a paragraph context
+and so does underline
+Underline works OK in a paragraph context
+and so does bold
+
+
+(lines => 1)
+
+line 1
+line 2
+line 3
+line 4
+
+line 1
+line 2
+line 3
+line 4
+
+
+(lines => 1, spaces => 1)
+
+line 1
+ line 2
+ line 3
+ line 4
+ tab 1
+ tab 2
+
+line 1
+ line 2
+ line 3
+ line 4
+ tab 1
+ tab 2
+
+
+(paras => 1)
+
+paragraph
+one
+
+paragraph
+two
+
+a
+long
+paragraph
+three
+
+paragraph
+one
+paragraph
+two
+a
+long
+paragraph
+three
+
+
+(paras => 1, title => 1)
+
+this
+is the
+title
+
+and this
+the text
+
+this
+is the
+title
+and this
+the text
+
+
+(paras => 1, headings => 1)
+
+1. Chapter one
+
+2. Chapter two
+
+2.1 Section two point one
+
+2.1.1 Subsection two point one point one
+
+2.1.1.3 Subsubsection two point one point one point three
+
+2.1.1.3.7 Heading level 5
+
+2.1.1.3.7.1 Heading level 6 (a long heading across
+two lines)
+
+paragraph text
+
+2.1.1.3.7.1.2 There are no more than 6 heading levels.
+
+paragraph text
+
+3. Chapter three
+
+1. Chapter one
+2. Chapter two
+2.1 Section two point one
+2.1.1 Subsection two point one point one
+2.1.1.3 Subsubsection two point one point one point three
+2.1.1.3.7 Heading level 5
+2.1.1.3.7.1 Heading level 6 (a long heading across
+two lines)
+paragraph text
+2.1.1.3.7.1.2 There are no more than 6 heading levels.
+paragraph text
+3. Chapter three
+
+
+(paras => 1, bullets => 1)
+
+Ordinary text
+
+ * bulleted paragraph
+
+ * another bulleted paragarph
+ with two lines
+
+ordinary text
+
+* bullet flush left
+
+ * bullet with tabs
+
+ - bullet with hyphen
+
+Ordinary text
+ordinary text
+bullet flush left
+bullet with tabs
+bullet with hyphen
+
+
+
+(paras => 1, headings => 1, numbers => 1)
+
+1. This is a heading, not a numbered paragraph
+
+ 1. number one
+
+ 2. number two
+
+ 31. number thirty-one
+
+ordinary text
+
+ 1. another number one
+
+ * bulleted paragraph not recognised
+
+ 3. number three
+
+1. This is a heading, not a numbered paragraph
+number one
+number two
+number thirty-one
+
ordinary text
+another number one
+
* bulleted paragraph not recognised
+number three
+
+
+
+(paras => 1, numbers => 1, bullets => 1)
+
+ 1. a numbered item
+
+ 2. and another
+
+ * switching to bullets starts a new list
+
+ 3. as does switching back
+
+a numbered item
+and another
+
as does switching back
+
+
+
+(paras => 1, numbers => 1, bullets => 1)
+
+* a bulleted list
+* with all the bullets next to each other
+* blah
+* blah
+
+
+
+
+(paras => 1, numbers => 1, bullets => 1)
+
+1. a numbered list
+2. with all the numbers next to each other
+3. blah
+4. blah
+
+a numbered list
+with all the numbers next to each other
+blah
+blah
+
+
+
+(paras => 1, numbers => 1, bullets => 1)
+
+* switching between
+111 numbers
+* and
+222 bullets
+
+numbers
+
bullets
+
+
+
+(paras => 1, numbers => 1, bullets => 1)
+
+Ordinary paragraphs
+* mixed up with
+numbers
+789 and
+bullets
+
+Ordinary paragraphs
+and
+bullets
+
+
+
+(paras => 1, numbers => 1, bullets => 1)
+
+000 different
+002. kinds
+003) of
+004] numbered
+001 list
+
+different
+kinds
+of
+numbered
+list
+
+
+
+(paras => 1, blockquotes => 1)
+
+Here's a block quote:
+
+ line 1
+ line 2
+ line 3
+ line 4
+
+end of block quote
+
+Here's a block quote:
+line 1
+line 2
+line 3
+line 4
+end of block quote
+
+
+(paras => 1, blockquotes => 1)
+
+A block quote with variable spacing:
+
+ line 1
+ line 2
+ line 3
+
+end of block quote
+
+A block quote with variable spacing:
+line 1
+ line 2
+ line 3
+end of block quote
+
+
+(paras => 1, blockquotes => 1)
+
+Ditto, spacing goes the other way:
+
+ line 1
+ line 2
+ line 3
+
+end of block quote
+
+Ditto, spacing goes the other way:
+ line 1
+ line 2
+line 3
+end of block quote
+
+
+(paras => 1, blockquotes => 1)
+
+This shouldn't be recognized as blockquote:
+
+ despite the spaces on this line,
+ and this one,
+this is just an ordinary paragraph?
+
+This shouldn't be recognized as blockquote:
+ despite the spaces on this line,
+ and this one,
+this is just an ordinary paragraph?
+
+
+(paras => 1, bullets => 1, numbers => 1, blockquotes => 1)
+
+
+This is not a blockquote, despite initial and final blank lines.
+
+
+This is not a blockquote, despite initial and final blank lines.
+
+
+(pre => 1)
+
+preformatted
+text
+
+preformatted
+text
+
+
+(paras => 1, blockparas => 1)
+
+Turing wrote,
+
+ I propose to consider the question, "Can machines think?"
+ This should begin with definitions of the meaning of the
+ terms "machine" and "think".
+
+Turing wrote,
+I propose to consider the question, "Can machines think?"
+This should begin with definitions of the meaning of the
+terms "machine" and "think".
+
+
+(paras => 1, blockquotes => 1)
+
+From "The Waste Land":
+
+ Phlebas the Phoenecian, a fortnight dead,
+ Forgot the cry of gulls, and the deep sea swell
+
+From "The Waste Land":
+Phlebas the Phoenecian, a fortnight dead,
+Forgot the cry of gulls, and the deep sea swell
+
+
+(paras => 1, blockcode => 1)
+
+Here's how to output numbers with commas (from perlfaq4):
+
+ sub commify {
+ local $_ = shift;
+ 1 while s/^(-?\d+)(\d{3})/$1,$2/;
+ $_;
+ }
+
+Here's how to output numbers with commas (from perlfaq4):
+sub commify {
+ local $_ = shift;
+ 1 while s/^(-?\d+)(\d{3})/$1,$2/;
+ $_;
+}
+
+
+()
+
+Line mixing tabs and metachars:
+ &&& <>
+
+Line mixing tabs and metachars:
+ &&& <>
+
+
+(paras => 1, tables => 1)
+
+ 1, 1 1, 2 1, 3
+ 2, 1 2, 2 2, 3
+ 3, 1 3, 2 3, 3
+
+
+| 1, 1 | 1, 2 | 1, 3 |
+| 2, 1 | 2, 2 | 2, 3 |
+| 3, 1 | 3, 2 | 3, 3 |
+
+
+
+(paras => 1, tables => 1)
+
+Tables can be left-aligned:
+
+1, 1 1, 2 1, 3
+2, 1 2, 2 2, 3
+3, 1 3, 2 3, 3
+
+Tables can be left-aligned:
+
+| 1, 1 | 1, 2 | 1, 3 |
+| 2, 1 | 2, 2 | 2, 3 |
+| 3, 1 | 3, 2 | 3, 3 |
+
+
+
+(paras => 1, tables => 1)
+
+ despite its appearance
+ this table has
+ only two columns
+
+
+| despite its | appearance |
+| this table | has |
+| only two | columns |
+
+
+
+(paras => 1, tables => 1)
+
+ tables
+ must
+ have
+ two
+ columns
+
+ tables
+ must
+ have
+ two
+ columns
+
+
+(paras => 1, tables => 1)
+
+ tables can
+ have only
+ one space
+ at the left
+
+
+| tables | can |
+| have | only |
+| one | space |
+| at the | left |
+
+
+
+(paras => 1, tables => 1)
+
+ tables must have two rows
+
+ tables must have two rows
+
+
+(paras => 1, tables => 1)
+
+ this table has varying lengths of column
+ at the right
+
+
+| this | table | has varying lengths of column |
+| at | the | right |
+
+
+
+(paras => 1, tables => 1)
+
+This table contains right-aligned cells:
+
+ p p^2 p^3 p^4
+ 2 4 8 16
+ 3 9 27 81
+ 5 25 125 625
+ 7 49 343 2401
+
+This table contains right-aligned cells:
+
+| p | p^2 | p^3 | p^4 |
+| 2 | 4 | 8 | 16 |
+| 3 | 9 | 27 | 81 |
+| 5 | 25 | 125 | 625 |
+| 7 | 49 | 343 | 2401 |
+
+
+
+(paras => 1, tables => 1)
+
+This table contains metacharacters:
+
+ & &
+ < <
+ > >
+
+This table contains metacharacters:
+
+
+
+(paras => 1, tables => 1)
+
+Here's a table with centre-aligned columns:
+
+1 1
+2 1 1
+3 1 2 1
+4 1 3 3 1
+5 1 4 6 4 1
+
+Here's a table with centre-aligned columns:
+
+| 1 | 1 |
+| 2 | 1 1 |
+| 3 | 1 2 1 |
+| 4 | 1 3 3 1 |
+| 5 | 1 4 6 4 1 |
+
+
+
+(paras => 1, blockparas => 1, tables => 1)
+
+ This should get recognised
+ as a blockquote despite
+ the unorthodox spacing.
+
+ But this is a table
+ XXX XXXX XX X XXXXX
+
+This should get recognised
+as a blockquote despite
+the unorthodox spacing.
+
+| But | this | is | a | table |
+| XXX | XXXX | XX | X | XXXXX |
+
+
--
cgit v1.2.1