initial import START
authorivan <ivan>
Mon, 11 Aug 2008 07:38:09 +0000 (07:38 +0000)
committerivan <ivan>
Mon, 11 Aug 2008 07:38:09 +0000 (07:38 +0000)
42 files changed:
.MANIFEST.swp [new file with mode: 0644]
.README.swp [new file with mode: 0644]
.TODO.swp [new file with mode: 0644]
.cvsignore [new file with mode: 0644]
Changes [new file with mode: 0644]
DiaryofaKillerCat.html [new file with mode: 0644]
MANIFEST [new file with mode: 0644]
Makefile.PL [new file with mode: 0644]
README [new file with mode: 0644]
TODO [new file with mode: 0644]
bin/DocumentConverter.py [new file with mode: 0755]
lib/HTML/.AutoConvert.pm.swp [new file with mode: 0644]
lib/HTML/AutoConvert.pm [new file with mode: 0644]
lib/HTML/AutoConvert/.OpenOffice.pm.swp [new file with mode: 0644]
lib/HTML/AutoConvert/.Run.pm.swp [new file with mode: 0644]
lib/HTML/AutoConvert/.antiword.pm.swp [new file with mode: 0644]
lib/HTML/AutoConvert/.poppler.pm.swp [new file with mode: 0644]
lib/HTML/AutoConvert/.unrtf.pm.swp [new file with mode: 0644]
lib/HTML/AutoConvert/.wvWare.pm.swp [new file with mode: 0644]
lib/HTML/AutoConvert/OpenOffice.pm [new file with mode: 0644]
lib/HTML/AutoConvert/Run.pm [new file with mode: 0644]
lib/HTML/AutoConvert/antiword.pm [new file with mode: 0644]
lib/HTML/AutoConvert/poppler.pm [new file with mode: 0644]
lib/HTML/AutoConvert/unrtf.pm [new file with mode: 0644]
lib/HTML/AutoConvert/wvWare.pm [new file with mode: 0644]
t/.26-pdf-poppler.t.swp [new file with mode: 0644]
t/.TO.swp [new file with mode: 0644]
t/00-load.t [new file with mode: 0644]
t/01-doc.t [new file with mode: 0644]
t/02-doc-antiword.t [new file with mode: 0644]
t/03-doc-wvWare.t [new file with mode: 0644]
t/04-doc-OpenOffice.t [new file with mode: 0644]
t/14-rtf-OpenOffice.t [new file with mode: 0644]
t/15-rtf-unrtf.t [new file with mode: 0644]
t/26-pdf-poppler.t [new file with mode: 0644]
t/DiaryofaKillerCat.doc [new file with mode: 0644]
t/VEGAN_RECIPES.rtf [new file with mode: 0644]
t/attitude.pdf [new file with mode: 0644]
t/boilerplate.t [new file with mode: 0644]
t/pod-coverage.t [new file with mode: 0644]
t/pod.t [new file with mode: 0644]
uno [new file with mode: 0644]

diff --git a/.MANIFEST.swp b/.MANIFEST.swp
new file mode 100644 (file)
index 0000000..7f1fb81
Binary files /dev/null and b/.MANIFEST.swp differ
diff --git a/.README.swp b/.README.swp
new file mode 100644 (file)
index 0000000..86d9fe2
Binary files /dev/null and b/.README.swp differ
diff --git a/.TODO.swp b/.TODO.swp
new file mode 100644 (file)
index 0000000..0125f89
Binary files /dev/null and b/.TODO.swp differ
diff --git a/.cvsignore b/.cvsignore
new file mode 100644 (file)
index 0000000..722450d
--- /dev/null
@@ -0,0 +1,10 @@
+blib*
+Makefile
+Makefile.old
+Build
+_build*
+pm_to_blib*
+*.tar.gz
+.lwpcookies
+HTML-AutoConvert-*
+cover_db
diff --git a/Changes b/Changes
new file mode 100644 (file)
index 0000000..18eaa9e
--- /dev/null
+++ b/Changes
@@ -0,0 +1,5 @@
+Revision history for HTML-AutoConvert
+
+0.01    unreleased
+        First version, released on an unsuspecting world.
+
diff --git a/DiaryofaKillerCat.html b/DiaryofaKillerCat.html
new file mode 100644 (file)
index 0000000..eb0507e
--- /dev/null
@@ -0,0 +1,236 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+       <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=iso-8859-1">
+       <TITLE>THE DIARY OF A KILLER CAT</TITLE>
+       <META NAME="GENERATOR" CONTENT="OpenOffice.org 2.4  (Linux)">
+       <META NAME="AUTHOR" CONTENT="Administrator">
+       <META NAME="CREATED" CONTENT="20071126;6470000">
+       <META NAME="CHANGEDBY" CONTENT="Angela Germany">
+       <META NAME="CHANGED" CONTENT="20080718;14160000">
+       <STYLE TYPE="text/css">
+       <!--
+               @page { size: 8.5in 11in; margin-right: 1in; margin-top: 1in; margin-bottom: 0.5in }
+               P { margin-bottom: 0.08in; direction: ltr; color: #000000; line-height: 115%; widows: 2; orphans: 2 }
+               P.western { font-family: "Calibri", sans-serif; font-size: 11pt; so-language: en-US }
+               P.cjk { font-family: "Times New Roman", serif; font-size: 11pt }
+               P.ctl { font-family: "Calibri", sans-serif; font-size: 11pt; so-language: ar-SA }
+               A:link { color: #0000ff }
+               A:visited { color: #800080 }
+       -->
+       </STYLE>
+</HEAD>
+<BODY LANG="en-US" TEXT="#000000" LINK="#0000ff" VLINK="#800080" DIR="LTR">
+<P CLASS="western" ALIGN=CENTER STYLE="text-indent: 0.5in; margin-bottom: 0in; line-height: 100%">
+<FONT FACE="Times New Roman, serif"><FONT SIZE=3><I><B>THE DIARY OF A
+KILLER CAT</B></I></FONT></FONT></P>
+<P CLASS="western" ALIGN=CENTER STYLE="margin-bottom: 0in; line-height: 100%">
+<FONT FACE="Times New Roman, serif"><FONT SIZE=3><B>ANNE FINE</B></FONT></FONT></P>
+<P CLASS="western" ALIGN=CENTER STYLE="margin-bottom: 0in; line-height: 100%">
+<BR>
+</P>
+<P CLASS="western" ALIGN=CENTER STYLE="margin-bottom: 0in; line-height: 100%">
+<FONT FACE="Times New Roman, serif"><FONT SIZE=3><B>LOUISIANA YOUNG
+READERS&rsquo; CHOICE NOMINEE 2009</B></FONT></FONT></P>
+<P CLASS="western" ALIGN=CENTER STYLE="margin-bottom: 0in; line-height: 100%">
+<FONT FACE="Times New Roman, serif"><FONT SIZE=3><B>GRADES 3-5</B></FONT></FONT></P>
+<P CLASS="western" ALIGN=CENTER STYLE="margin-bottom: 0.14in"><BR><BR>
+</P>
+<P CLASS="western" ALIGN=CENTER STYLE="margin-bottom: 0.14in"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Submitted
+by Samantha Klein, Graduate Student, Louisiana State University,
+Baton Rouge, LA</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0.14in"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>The
+Diary of a Killer Cat</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>
+by Anne Fine. Illustrated by Steve Cox. New York: Farrar, Straus and
+Giroux, 1994.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0.14in"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><B>ANNOTATION</B></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>:
+This humorous chapter book is told from the point of view of a cat
+named Tuffy. His human family gets upset after he brings a dead bird
+and a dead mouse in the house, but they </FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>really</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>
+go &ldquo;mental&rdquo; when he next brings in the neighbor&rsquo;s
+beloved rabbit Thumper&hellip;dead, of course.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0.14in"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><B>CLASSROOM
+CONNECTIONS</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><U><B>Explore
+Points of View</B></U></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><B>:
+</B></FONT></FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Tuffy
+is the narrator of this book; we see the events that occur in the
+story from his point of view. What makes it so funny is that Tuffy is
+a cat, so he looks at things in a different way than people do. He
+thinks his people are being ridiculous for being so upset with him
+for killing a bird when that is normal behavior for a cat. Students
+can do a creative writing exercise that will help them understand
+what first-person narration is. Ask children to write a story&mdash;it
+can be in diary form as in </FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>The
+Diary of a Killer Cat</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>&mdash;from
+the point of view of an animal. The animal can be their own pet, an
+insect, a zoo animal, farm animal, or wild animal. The following site
+provides a lesson for further exploration of point of view:
+</FONT></FONT><FONT COLOR="#0000ff"><U><A HREF="http://teachers.net/lessons/posts/414.html"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>http://teachers.net/lessons/posts/414.html</FONT></FONT></A></U></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>.
+It helps children learn to distinguish between first and third person
+points of view. The stories presented are </FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>The
+Three Little Pigs</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>
+(traditionally told), </FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>The
+True Story of the Three Little Pigs</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>
+by Jon Scieszka, and </FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>The
+Giver</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>
+by Lois Lowry. </FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>The
+Giver</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>
+is probably too advanced for our age group, but other titles can be
+substituted: e.g. </FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>Bunnicula:
+A Rabbit Tale of Mystery</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>
+by Deborah Howe and James Howe (or </FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>The
+Vampire Bunny</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>,
+the easy reader version of</FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>
+Bunnicula</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>),
+</FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>Sheep
+</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>by
+Valerie Hobbs, and </FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>A
+Room with a Zoo</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>
+by Jules Feiffer.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><U><B>Write
+a Book Review</B></U></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><B>:</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Have
+the students write a short book review of </FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>The
+Diary of a Killer Cat</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>.
+They could share the following: an explanation of what the story is
+about; whether they liked it or not and why; a character description
+of Tuffy. They could rate the book with stars, a five star review
+being the best. That is what children did for the Web site of the Old
+Hutton C of E Primary School, located in the town of Kendal, Cumbria,
+in the U.K. Click the following link to see student reviews of Fine&rsquo;s
+books, including a few of </FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>The
+Diary of a Killer Cat</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>:
+</FONT></FONT><FONT COLOR="#0000ff"><U><A HREF="http://www.oldhutton.cumbria.sch.uk/learning/literacy/bookreviews/f.html"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>http://www.oldhutton.cumbria.sch.uk/learning/literacy/bookreviews/f.html</FONT></FONT></A></U></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><U>&ldquo;<FONT FACE="Times New Roman, serif"><FONT SIZE=3><B>Is
+That How Cats Really Are?&rdquo;</B></U></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>This
+lesson about cats comes from the ASPCA Web site:
+</FONT></FONT><FONT COLOR="#0000ff"><U><A HREF="http://www.aspca.org/site/DocServer/Is_That_How_Cats_Really_Are.pdf?docID=4250"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>http://www.aspca.org/site/DocServer/Is_That_How_Cats_Really_Are.pdf?docID=4250</FONT></FONT></A></U></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>.
+It asks children to brainstorm and research characteristics of real
+cats. They then can compare these characteristics to portrayals of
+fictional cats. A handout is provided to help them remember famous
+fictional cats, like Tigger from Winnie the Pooh (yes, both domestic
+and wild cats can be represented). A series of discussion questions
+round out the lesson; they try to get children to think of &ldquo;basic
+cat care needs.&rdquo; Tuffy can be brought into the discussion. In
+what ways does Tuffy exhibit characteristics of real cats? How is he
+not like a real cat? Does Tuffy show affection toward Ellie? How do
+real cats show affection ?</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><U><B>Natural
+History Museum of Los Angelos County: &ldquo;Cats! Wild to Mild&rdquo;</B></U></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><FONT COLOR="#0000ff"><U><A HREF="http://www.nhm.org/cats/home.html"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>http://www.nhm.org/cats/home.html</FONT></FONT></A></U></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>.
+&ldquo;Cats! Wild to Mild&rdquo; is a traveling exhibit, but the Web
+site also provides in-depth information about cats of all types,
+organized in a clear fashion. On the left side of the page, click on
+&ldquo;Teacher Curriculum&rdquo; to see a 31-page &ldquo;Curriculum
+Guide&rdquo; that can be printed out. It includes many activities to
+engage students in the lesson.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><U><B>Draw
+a Cartoon Animal</B></U></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>One
+of the funny things about this book is Steve Cox&rsquo;s cartoon
+illustrations. Discuss how his illustrations of Tuffy correspond with
+Tuffy&rsquo;s voice in telling the tale. What kind of expression does
+Tuffy&rsquo;s face show? Have children create their own cartoon
+animal character. Show children &ldquo;Chunky Monkey&rsquo;s Cartoon
+Lessons&rdquo; on Pauline Camanor&rsquo;s Chunky Money Web site:
+</FONT></FONT><FONT COLOR="#0000ff"><U><A HREF="http://www.chunkymonkey.com/howto/drawinglessons.htm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>http://www.chunkymonkey.com/howto/drawinglessons.htm</FONT></FONT></A></U></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>.
+She gives step-by-step directions for drawing monkeys, cats, fish,
+koalas, poodles, plus more! Books from the </FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>1-2-3
+Draw</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>
+series will be especially of interest to kids interested in cartoon
+drawing. Titles include: </FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>1-2-3
+Draw Cartoon Animals</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>,
+</FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>1-2-3
+Draw Cartoon Wildlife</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>,
+and </FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>1-2-3
+Draw Pets and Farm Animals</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>.
+The Web site for these books, produced by Peel Productions, provides
+a sampling of drawing instructions online:
+</FONT></FONT><FONT COLOR="#0000ff"><U><A HREF="http://drawbooks.com/123_draw_series/index.html"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>http://drawbooks.com/123_draw_series/index.html</FONT></FONT></A></U></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>.
+Click on the individual titles. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><B>WEB
+SITES</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><B>Anne
+Fine: Official Web Site</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><FONT COLOR="#0000ff"><U><A HREF="http://www.annefine.co.uk/index.html"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>http://www.annefine.co.uk/index.html</FONT></FONT></A></U></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>.
+The attractive Web site of the British author of </FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>The
+Diary of a Killer Cat </I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>would
+be nice to show to children. Her books are listed according to
+reading level; short summaries and cover images are presented along
+with each title. Good news to kids who loved reading </FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>The
+Diary of a Killer Cat</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>:
+there&rsquo;s two more books featuring Tuffy, entitled </FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>The
+Return of the Killer Cat</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>
+and </FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>The
+Killer Cat Strikes Back</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>!
+Her brief biography is written in first person point of view, and
+Fine shares with us a little about her childhood and her writing
+process. The Web site lists the many awards Fine won over the years,
+including the 1995 </FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><SPAN LANG="en-GB">Nottinghamshire
+Libraries Award for </SPAN></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>The
+Diary of a Killer Cat</I></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>.
+There is also a section about Fine having been the United Kingdom&rsquo;s
+Children&rsquo;s Laureate for the years 2001-2003. A link is provided
+for the Children&rsquo;s Laureate homepage:
+</FONT></FONT><FONT COLOR="#0000ff"><U><A HREF="http://www.booktrusted.co.uk/childrenslaureate/"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>http://www.booktrusted.co.uk/childrenslaureate/</FONT></FONT></A></U></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>.
+The current Children&rsquo;s Laureate is Michael Rosen. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><B>Healthypet.com:
+Cat FAQs</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><FONT COLOR="#0000ff"><U><A HREF="http://www.healthypet.com/faq_list.aspx?id=2"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>http://www.healthypet.com/faq_list.aspx?id=2</FONT></FONT></A></U></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>.
+Healthypet.com is produced by the American Animal Hospital Associate.
+The Cat FAQs provides answers to common questions about cats. Topics
+are organized under category headings, &ldquo;Behavior&rdquo;,
+&ldquo;General Health&rdquo;, &ldquo;Diseases&rdquo;, etc. The
+behavior questions may be of especial interest as a thematic
+connection to Fine&rsquo;s book. The Dog FAQs can be linked from this
+page, too.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%">&ldquo;<FONT FACE="Times New Roman, serif"><FONT SIZE=3><B>Cats:
+Plans for Perfection&rdquo; from National Geographic</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><FONT COLOR="#0000ff"><U><A HREF="http://www.nationalgeographic.com/features/97/cats/index.html"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>http://www.nationalgeographic.com/features/97/cats/index.html</FONT></FONT></A></U></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3>.
+&ldquo;The story of cats is ultimately a story about design&rdquo;:
+this statement opens this intriguing online exhibit on cats. Children
+will love the  intricate drawings. The drawing of the &ldquo;retractable
+claw&rdquo; moves to show how it works. Another drawing depicts a
+Sabertooth marking its territory on a tree branch; the text beside it
+notes that domestic cats do the same thing. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; line-height: 100%"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0.14in"><BR><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0.14in"><BR><BR>
+</P>
+<DIV TYPE=FOOTER>
+       <P ALIGN=CENTER STYLE="margin-top: 0.46in; margin-bottom: 0in; line-height: 100%">
+       <SDFIELD TYPE=PAGE SUBTYPE=RANDOM FORMAT=PAGE>3</SDFIELD></P>
+       <P STYLE="margin-bottom: 0in; line-height: 100%"><BR>
+       </P>
+</DIV>
+</BODY>
+</HTML>
\ No newline at end of file
diff --git a/MANIFEST b/MANIFEST
new file mode 100644 (file)
index 0000000..173ec7a
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,25 @@
+Changes
+MANIFEST
+Makefile.PL
+README
+lib/HTML/AutoConvert.pm
+lib/HTML/AutoConvert/Run.pm
+lib/HTML/AutoConvert/antiword.pm
+lib/HTML/AutoConvert/OpenOffice.pm
+lib/HTML/AutoConvert/poppler.pm
+lib/HTML/AutoConvert/unrtf.pm
+lib/HTML/AutoConvert/wvWare.pm
+bin/DocumentConverter.py
+t/00-load.t
+t/pod-coverage.t
+t/pod.t
+t/01-doc.t
+t/02-doc-antiword.t
+t/03-doc-wvWare.t
+t/04-doc-OpenOffice.t
+t/14-rtf-OpenOffice.t
+t/15-rtf-unrtf.t
+t/26-pdf-poppler.t
+t/DiaryofaKillerCat.doc
+t/VEGAN_RECIPES.rtf
+t/attitude.pdf
diff --git a/Makefile.PL b/Makefile.PL
new file mode 100644 (file)
index 0000000..cd7c009
--- /dev/null
@@ -0,0 +1,21 @@
+use strict;
+use warnings;
+use ExtUtils::MakeMaker;
+
+WriteMakefile(
+    NAME                => 'HTML::AutoConvert',
+    AUTHOR              => 'Ivan Kohler <ivan-html-autoconvert@420.am>',
+    VERSION_FROM        => 'lib/HTML/AutoConvert.pm',
+    ABSTRACT_FROM       => 'lib/HTML/AutoConvert.pm',
+    PL_FILES            => {},
+    'EXE_FILES'         => [ glob 'bin/*' ],
+    'INSTALLSCRIPT'     => '/usr/local/bin',
+    'INSTALLSITEBIN'    => '/usr/local/bin',
+    PREREQ_PM => {
+        'Test::More'  => 0,
+        'IPC::Run'    => 0,
+        'File::Slurp' => 0,
+    },
+    dist                => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
+    clean               => { FILES => 'HTML-AutoConvert-*' },
+);
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..5249658
--- /dev/null
+++ b/README
@@ -0,0 +1,69 @@
+HTML-AutoConvert
+
+This module is intended for best-effort auto-conversion of arbitrary files
+into HTML.
+
+The main focus is on conversion of Microsoft Word .DOC and .RTF file as well
+as Adobe PDF.  The OpenOffice plugin also converts .SXW and .ODT formats.
+
+The actual conversion is mostly done by shelling out to existing programs.
+Useful programs to have installed:
+
+For DOC/RTF/SXW/ODT:
+OpenOffice v2.3 or later
+Python and Python-UNO
+
+For DOC:
+wvWare http://wvware.sourceforge.net/
+antiword http://www.winfield.demon.nl/index.html
+
+For RTF:
+unrtf ftp://ftp.gnu.org/pub/gnu/unrtf/
+
+For PDF:
+poppler http://poppler.freedesktop.org/
+
+INSTALLATION
+
+To install this module, run the following commands:
+
+       perl Makefile.PL
+       make
+       make test
+       make install
+
+SUPPORT AND DOCUMENTATION
+
+After installing, you can find documentation for this module with the
+perldoc command.
+
+    perldoc HTML::AutoConvert
+
+You can also look for information at:
+
+    RT, CPAN's request tracker
+        http://rt.cpan.org/NoAuth/Bugs.html?Dist=HTML-AutoConvert
+
+    AnnoCPAN, Annotated CPAN documentation
+        http://annocpan.org/dist/HTML-AutoConvert
+
+    CPAN Ratings
+        http://cpanratings.perl.org/d/HTML-AutoConvert
+
+    Search CPAN
+        http://search.cpan.org/dist/HTML-AutoConvert
+
+
+COPYRIGHT AND LICENCE
+
+Copyright (C) 2008 Freeside Internet Services, Inc.
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+HTML::AutoConvert::OpenOffice.pm derived from "PyODConverter"
+<http://www.artofsolving.com/opensource/pyodconverter>
+Copyright (C) 2008 Mirko Nasato <mirko@artofsolving.com>
+Licensed under the GNU LGPL v2.1 - http://www.gnu.org/licenses/lgpl-2.1.html
+- or any later version.
+
diff --git a/TODO b/TODO
new file mode 100644 (file)
index 0000000..0058ab2
--- /dev/null
+++ b/TODO
@@ -0,0 +1,6 @@
+- DOC: images
+- PDF: images
+- RTF: images
+
+- OpenOffice.pm: poll via UNO to determine readiness rather than sleep
+- OpenOffice.pm: convert DocumentConverter.py to Perl using OpenOffice::UNO
diff --git a/bin/DocumentConverter.py b/bin/DocumentConverter.py
new file mode 100755 (executable)
index 0000000..2b4d2b3
--- /dev/null
@@ -0,0 +1,151 @@
+#!/usr/bin/python
+#
+# PyODConverter (Python OpenDocument Converter) v1.0.0 - 2008-05-05
+#
+# This script converts a document from one office format to another by
+# connecting to an OpenOffice.org instance via Python-UNO bridge.
+#
+# Copyright (C) 2008 Mirko Nasato <mirko@artofsolving.com>
+# Licensed under the GNU LGPL v2.1 - http://www.gnu.org/licenses/lgpl-2.1.html
+# - or any later version.
+#
+DEFAULT_OPENOFFICE_PORT = 8100
+
+import uno
+from os.path import abspath, isfile, splitext
+from com.sun.star.beans import PropertyValue
+from com.sun.star.task import ErrorCodeIOException
+from com.sun.star.connection import NoConnectException
+
+FAMILY_TEXT = "Text"
+FAMILY_SPREADSHEET = "Spreadsheet"
+FAMILY_PRESENTATION = "Presentation"
+FAMILY_DRAWING = "Drawing"
+
+FILTER_MAP = {
+    "pdf": {
+        FAMILY_TEXT: "writer_pdf_Export",
+        FAMILY_SPREADSHEET: "calc_pdf_Export",
+        FAMILY_PRESENTATION: "impress_pdf_Export",
+        FAMILY_DRAWING: "draw_pdf_Export"
+    },
+    "html": {
+        FAMILY_TEXT: "HTML (StarWriter)",
+        FAMILY_SPREADSHEET: "HTML (StarCalc)",
+        FAMILY_PRESENTATION: "impress_html_Export"
+    },
+    "odt": { FAMILY_TEXT: "writer8" },
+    "doc": { FAMILY_TEXT: "MS Word 97" },
+    "rtf": { FAMILY_TEXT: "Rich Text Format" },
+    "txt": { FAMILY_TEXT: "Text" },
+    "ods": { FAMILY_SPREADSHEET: "calc8" },
+    "xls": { FAMILY_SPREADSHEET: "MS Excel 97" },
+    "odp": { FAMILY_PRESENTATION: "impress8" },
+    "ppt": { FAMILY_PRESENTATION: "MS PowerPoint 97" },
+    "swf": { FAMILY_PRESENTATION: "impress_flash_Export" }
+}
+# see http://wiki.services.openoffice.org/wiki/Framework/Article/Filter
+# for more available filters
+
+
+class DocumentConversionException(Exception):
+
+    def __init__(self, message):
+        self.message = message
+
+    def __str__(self):
+        return self.message
+
+
+class DocumentConverter:
+    
+    def __init__(self, port=DEFAULT_OPENOFFICE_PORT):
+        localContext = uno.getComponentContext()
+        resolver = localContext.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext)
+        try:
+            context = resolver.resolve("uno:socket,host=localhost,port=%s;urp;StarOffice.ComponentContext" % port)
+        except NoConnectException:
+            raise DocumentConversionException, "failed to connect to OpenOffice.org on port %s" % port
+        self.desktop = context.ServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop", context)
+
+    def convert(self, inputFile, outputFile):
+
+        inputUrl = self._toFileUrl(inputFile)
+        outputUrl = self._toFileUrl(outputFile)
+        
+        document = self.desktop.loadComponentFromURL(inputUrl, "_blank", 0, self._toProperties(Hidden=True))
+        try:
+          document.refresh()
+        except AttributeError:
+          pass
+        
+        outputExt = self._getFileExt(outputFile)
+        filterName = self._filterName(document, outputExt)
+
+        try:
+            document.storeToURL(outputUrl, self._toProperties(FilterName=filterName))
+        finally:
+            document.close(True)
+
+    def _filterName(self, document, outputExt):
+        family = self._detectFamily(document)
+        try:
+            filterByFamily = FILTER_MAP[outputExt]
+        except KeyError:
+            raise DocumentConversionException, "unknown output format: '%s'" % outputExt
+        try:
+            return filterByFamily[family]
+        except KeyError:
+            raise DocumentConversionException, "unsupported conversion: from '%s' to '%s'" % (family, outputExt)
+    
+    def _detectFamily(self, document):
+        if document.supportsService("com.sun.star.text.GenericTextDocument"):
+            # NOTE: a GenericTextDocument is either a TextDocument, a WebDocument, or a GlobalDocument
+            # but this further distinction doesn't seem to matter for conversions
+            return FAMILY_TEXT
+        if document.supportsService("com.sun.star.sheet.SpreadsheetDocument"):
+            return FAMILY_SPREADSHEET
+        if document.supportsService("com.sun.star.presentation.PresentationDocument"):
+            return FAMILY_PRESENTATION
+        if document.supportsService("com.sun.star.drawing.DrawingDocument"):
+            return FAMILY_DRAWING
+        raise DocumentConversionException, "unknown document family: %s" % document
+
+    def _getFileExt(self, path):
+        ext = splitext(path)[1]
+        if ext is not None:
+            return ext[1:].lower()
+
+    def _toFileUrl(self, path):
+        return uno.systemPathToFileUrl(abspath(path))
+
+    def _toProperties(self, **args):
+        props = []
+        for key in args:
+           prop = PropertyValue()
+           prop.Name = key
+           prop.Value = args[key]
+           props.append(prop)
+        return tuple(props)
+
+
+if __name__ == "__main__":
+    from sys import argv, exit
+    
+    if len(argv) < 3:
+        print "USAGE: python %s <input-file> <output-file>" % argv[0]
+        exit(255)
+    if not isfile(argv[1]):
+        print "no such input file: %s" % argv[1]
+        exit(1)
+
+    try:
+        converter = DocumentConverter()    
+        converter.convert(argv[1], argv[2])
+    except DocumentConversionException, exception:
+        print "ERROR!" + str(exception)
+        exit(1)
+    except ErrorCodeIOException, exception:
+        print "ERROR! ErrorCodeIOException %d" % exception.ErrCode
+        exit(1)
+
diff --git a/lib/HTML/.AutoConvert.pm.swp b/lib/HTML/.AutoConvert.pm.swp
new file mode 100644 (file)
index 0000000..f6927d2
Binary files /dev/null and b/lib/HTML/.AutoConvert.pm.swp differ
diff --git a/lib/HTML/AutoConvert.pm b/lib/HTML/AutoConvert.pm
new file mode 100644 (file)
index 0000000..7df3b82
--- /dev/null
@@ -0,0 +1,249 @@
+package HTML::AutoConvert;
+
+use warnings;
+use strict;
+
+=head1 NAME
+
+HTML::AutoConvert - Best-effort HTML conversion of arbitrary files to HTML.
+
+=head1 VERSION
+
+Version 0.01
+
+=cut
+
+our $VERSION = '0.01';
+
+=head1 SYNOPSIS
+
+    use HTML::AutoConvert;
+
+    my $converter = HTML::AutoConvert->new();
+    #or to turn on debugging
+    my $converter = HTML::AutoConvert->new('debug'=>1);
+
+    my( $html, @images ) = $converter->html_convert( $file );
+
+    #turn on or off debugging later
+    $converter->debug(1);
+
+=head1 DESCRIPTION
+
+Convert arbitrary file types to HTML.
+
+#=head1 EXPORT
+#
+#doc on also using html_convert functional interface
+
+=head1 FUNCTIONS
+
+=head2 new
+
+=cut
+
+sub new {
+  my $proto = shift;
+  my $class = ref($proto) || $proto;
+
+  my $opts = ref($_[0]) ? shift : { @_ };
+  my $self = $opts; #{};
+  bless ($self, $class);
+
+  $self->find_handlers;
+
+  $self;
+
+}
+
+=head2 html_convert FILENAME
+
+Convert the given filename to HTML.  The HTML output is returned as a scalar.
+
+=cut
+
+sub html_convert {
+  my( $self, $file ) = ( shift, shift );
+  my $opt = ref($_[0]) ? shift : { @_ };
+
+  $self->{'file'} = $file;
+
+  my @handlers = $self->handlers
+    or die "no registered handlers for filetype ". $self->filetype( $file );
+
+  my( $converted, $html, $errors ) = ( 0, '', '' );
+  foreach my $handler ( @handlers ) {
+
+    my $module = 'HTML::AutoConvert::'. $handler->{'module'};
+    my $tmp_html = eval { $module->html_convert( $self->{'file'} ) };
+    if ( $@ ) {
+       my $tmp_err = "conversion with $module failed: $@\n";
+       warn $tmp_err if $self->{'debug'};
+       $errors .= $tmp_err;
+       next;
+    }
+
+    $converted = 1;
+    $html = $tmp_html;
+    last;
+  }
+
+  die "couldn't convert $file:\n$errors" unless $converted;
+
+  $html;
+
+}
+
+=head2 debug
+
+Get or set the debugging level
+
+=cut
+
+sub debug {
+  my $self = shift;
+  $self->{'debug'} = shift if @_;
+  $self->{'debug'};
+}
+
+=head1 INTERNAL FUNCTIONS
+
+=head2 find_handlers
+
+Search for installed HTML::AutoConvert::* plugins.
+
+=cut
+
+sub find_handlers {
+  my $self = shift;
+
+  my %types;
+  foreach my $INC ( @INC ) {
+    warn "globbing $INC/HTML/AutoConvert/*.pm\n" if $self->{'debug'};
+    foreach my $file ( glob("$INC/HTML/AutoConvert/*.pm") ) {
+      warn "attempting to load handler info from $file\n" if $self->{'debug'};
+      $file =~ /\/(\w+)\.pm$/ or do {
+        warn "unrecognized file in $INC/HTML/AutoConvert/: $file\n";
+        next;
+      };
+      my $mod = $1;
+      my $info = eval "use HTML::AutoConvert::$mod; ".
+                      "\\%HTML::AutoConvert::$mod\::info;";
+      if ( $@ ) {
+        die "error using HTML::AutoConvert::$mod (skipping): $@\n" if $@;
+        next;
+      }
+      unless ( keys %$info ) {
+        warn "no %info hash in HTML::AutoConvert::$mod, skipping\n" if $self->{'debug'};
+        next;
+      }
+      warn "got handler info from HTML::AutoConvert::$mod: $info\n" if $self->{'debug'};
+      if ( exists($info->{'disabled'}) && $info->{'disabled'} ) {
+        warn "skipping disabled handler HTML::AutoConvert::$mod" if $self->{'debug'};
+        next;
+      }
+
+      my $types = $info->{'types'};
+      $types = [ $types ] unless ref($types);
+
+      foreach my $type ( @$types ) {
+        $types{lc($type)}->{$mod} = { 'module' => $mod, %$info };
+      }
+
+    }
+  }
+
+  $self->{'handlers'} = \%types;
+
+}
+
+=head2 handlers
+
+Return the available handlers for the current file.
+
+=cut
+
+sub handlers {
+  my( $self ) = @_;
+
+  my $types = $self->{'handlers'};
+
+  my $type = $self->filetype;
+
+  sort { $a->{'weight'} <=> $b->{'weight'} }
+       values %{ $types->{lc($type)} };
+}
+
+=head2
+
+
+=head2 filetype
+
+Determine the type of the current file.
+
+=cut
+
+#just use the file extension...  could also use File::MMagic or something
+sub filetype {
+  my $self = shift;
+
+  my $file = $self->{'file'};
+  $file =~ /\.(\w{3,4})$/ or die "can't parse $file for extension";
+  lc($1);
+}
+
+=head1 AUTHOR
+
+Ivan Kohler, C<< <ivan-html-autoconvert at 420.am> >>
+
+=head1 BUGS
+
+Please report any bugs or feature requests to C<bug-html-autoconvert at rt.cpan.org>, or through
+the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=HTML-AutoConvert>.  I will be notified, and then you'll
+automatically be notified of progress on your bug as I make changes.
+
+=head1 SUPPORT
+
+You can find documentation for this module with the perldoc command.
+
+    perldoc HTML::AutoConvert
+
+You can also look for information at:
+
+=over 4
+
+=item * RT: CPAN's request tracker
+
+L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=HTML-AutoConvert>
+
+=item * AnnoCPAN: Annotated CPAN documentation
+
+L<http://annocpan.org/dist/HTML-AutoConvert>
+
+=item * CPAN Ratings
+
+L<http://cpanratings.perl.org/d/HTML-AutoConvert>
+
+=item * Search CPAN
+
+L<http://search.cpan.org/dist/HTML-AutoConvert>
+
+=back
+
+
+=head1 ACKNOWLEDGEMENTS
+
+
+
+=head1 COPYRIGHT & LICENSE
+
+Copyright 2008 Freeside Internet Services, Inc.
+All rights reserved.
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=cut
+
+1; # End of HTML::AutoConvert
+
diff --git a/lib/HTML/AutoConvert/.OpenOffice.pm.swp b/lib/HTML/AutoConvert/.OpenOffice.pm.swp
new file mode 100644 (file)
index 0000000..750ad68
Binary files /dev/null and b/lib/HTML/AutoConvert/.OpenOffice.pm.swp differ
diff --git a/lib/HTML/AutoConvert/.Run.pm.swp b/lib/HTML/AutoConvert/.Run.pm.swp
new file mode 100644 (file)
index 0000000..8a90a9a
Binary files /dev/null and b/lib/HTML/AutoConvert/.Run.pm.swp differ
diff --git a/lib/HTML/AutoConvert/.antiword.pm.swp b/lib/HTML/AutoConvert/.antiword.pm.swp
new file mode 100644 (file)
index 0000000..79e92ef
Binary files /dev/null and b/lib/HTML/AutoConvert/.antiword.pm.swp differ
diff --git a/lib/HTML/AutoConvert/.poppler.pm.swp b/lib/HTML/AutoConvert/.poppler.pm.swp
new file mode 100644 (file)
index 0000000..2c011bf
Binary files /dev/null and b/lib/HTML/AutoConvert/.poppler.pm.swp differ
diff --git a/lib/HTML/AutoConvert/.unrtf.pm.swp b/lib/HTML/AutoConvert/.unrtf.pm.swp
new file mode 100644 (file)
index 0000000..9bc779c
Binary files /dev/null and b/lib/HTML/AutoConvert/.unrtf.pm.swp differ
diff --git a/lib/HTML/AutoConvert/.wvWare.pm.swp b/lib/HTML/AutoConvert/.wvWare.pm.swp
new file mode 100644 (file)
index 0000000..39e4317
Binary files /dev/null and b/lib/HTML/AutoConvert/.wvWare.pm.swp differ
diff --git a/lib/HTML/AutoConvert/OpenOffice.pm b/lib/HTML/AutoConvert/OpenOffice.pm
new file mode 100644 (file)
index 0000000..e09a9e4
--- /dev/null
@@ -0,0 +1,96 @@
+package HTML::AutoConvert::OpenOffice;
+
+=head1 NAME
+
+HTML::AutoConvert::antiword - antiword plugin for HTML::AutoConvert
+
+=head1 PREREQUISITES
+
+OpenOffice v2.3 or later
+
+(currently)
+Python
+Python-UNO
+
+(future)
+Perl OpenOffice::UNO
+
+=head1 SECURITY NOTE
+
+This module starts and leaves an OpenOffice instance running.
+
+The OpenOffice instance binds to and listens to a port on localhost for
+commands.  Anything which can talk to this port can instruct OpenOffice to
+read or write any file the current user has access to.
+
+By default, port 8100 is used.  You can choose a different port by passing an
+option to the new() constructor:
+
+  my $converter = HTML::AutoConvert->new('openoffice_port'=>5555);
+
+=cut
+
+use strict;
+use vars qw( %info ); #$slept );
+use IPC::Run qw( run timeout io );
+use File::Slurp qw( slurp );
+
+%info = (
+  'types'   => [qw( doc rtf odt sxw )],
+  'weight'  => 80,
+  'url'     => 'http://wvware.sourceforge.net/',
+);
+
+#$slept = 0;
+
+#sub program { ( 'openoffice', '-headless' ); }
+
+#half-ass using DocumentConverter.py for now
+#need to recode with OpenOffice::UNO
+
+sub html_convert {
+  my( $self, $file ) = ( shift, shift );
+  my $opt = ref($_[0]) ? shift : { @_ };
+
+  $self->start_openoffice($opt);
+
+  my $program = 'DocumentConverter.py';
+
+  my $timeout = 60; #?
+
+  use File::Temp qw/ tempfile /;
+  my($fh, $outfile) = tempfile(SUFFIX => '.html');
+  #hmm, it gets overwritten so $fh is bunk
+
+  my($out, $err) = ( '', '' );
+  local($SIG{CHLD}) = sub {};
+  run( [ $program, $file, $outfile ], \undef, \$out, \$err, timeout($timeout) )
+    or die "$program failed with exit status ". ( $? >> 8 ). ": $out\n";
+
+  my $html = slurp($outfile);
+
+  $html;
+
+}
+
+sub start_openoffice {
+  my( $self ) = ( shift, shift );
+  my $opt = ref($_[0]) ? shift : { @_ };
+  my $port = $opt->{'openoffice_port'} || 8100;
+
+  my $cmd = [ 'openoffice', '-headless',
+                            "-accept=socket,port=$port;urp",
+                            #'-splash-pipe=5',
+            ];
+
+  local($SIG{CHLD}) = sub {};
+  run $cmd, \undef, '>/dev/null', '2>/dev/null'
+    or die "can't launch openoffice: $@\n";
+
+  #it isn't ready to run commands right away :(
+  #it would be better if we could ping against UNO API somehow until ready...
+  #sleep 5 unless $slept++;
+
+}
+
+1;
diff --git a/lib/HTML/AutoConvert/Run.pm b/lib/HTML/AutoConvert/Run.pm
new file mode 100644 (file)
index 0000000..2eada89
--- /dev/null
@@ -0,0 +1,30 @@
+package HTML::AutoConvert::Run;
+
+=head1 NAME
+
+HTML::AutoConvert::Run - Base class for HTML::AutoConvert plugs that run an external program
+
+=cut
+
+use strict;
+use IPC::Run qw( run timeout );
+
+sub html_convert {
+  my( $self, $file ) = ( shift, shift );
+  my $opt = ref($_[0]) ? shift : { @_ };
+
+  my @program = $self->program;
+  my $program = $program[0];
+
+  my $timeout = 60; #?
+
+  my( $html, $err ) = ( '', '');
+  local($SIG{CHLD}) = sub {};
+  run( [ @program, $file ], \undef, \$html, \$err, timeout($timeout) )
+    or die "$program failed with exit status ". ( $? >> 8 ). ": $err\n";
+
+  $html;
+
+}
+
+1;
diff --git a/lib/HTML/AutoConvert/antiword.pm b/lib/HTML/AutoConvert/antiword.pm
new file mode 100644 (file)
index 0000000..4622a79
--- /dev/null
@@ -0,0 +1,31 @@
+package HTML::AutoConvert::antiword;
+
+=head1 NAME
+
+HTML::AutoConvert::antiword - antiword plugin for HTML::AutoConvert
+
+=head1 URL
+
+Antiword can be downloaded from http://www.winfield.demon.nl/index.html
+
+=cut
+
+use strict;
+use vars qw( %info );
+use base 'HTML::AutoConvert::Run';
+
+%info = (
+  'types'   => 'doc',
+  'weight'  => 90,
+  'url'     => 'http://www.winfield.demon.nl/index.html',
+);
+
+sub program { ( 'antiword' ) }
+
+sub html_convert {
+  my $self = shift;
+  my $html = $self->SUPER::html_convert(@_);
+  "<HTML><HEAD></HEAD><BODY><PRE>\n$html\n</PRE></BODY></HTML>";
+}
+
+1;
diff --git a/lib/HTML/AutoConvert/poppler.pm b/lib/HTML/AutoConvert/poppler.pm
new file mode 100644 (file)
index 0000000..cca5b0d
--- /dev/null
@@ -0,0 +1,48 @@
+package HTML::AutoConvert::poppler;
+
+=head1 NAME
+
+HTML::AutoConvert::poppler - poppler (pdftohtml) plugin for HTML::AutoConvert
+
+=head1 URL
+
+poppler can be downloaded from http://poppler.freedesktop.org/ 
+
+=cut
+
+use strict;
+use vars qw( %info );
+use base 'HTML::AutoConvert::Run';
+
+%info = (
+  'types'   => 'pdf',
+  'weight'  => 10,
+  'url'     => 'http://poppler.freedesktop.org/',
+);
+
+sub program { ( 'pdftohtml', '-stdout' ) }
+
+#false laziness w/OpenOffice.pm
+#sub html_convert {
+#  my( $self, $file ) = ( shift, shift );
+#  my $opt = ref($_[0]) ? shift : { @_ };
+#
+#  my $program = 'pdftohtml';
+#
+#  my $timeout = 60; #?
+#
+#  my($out, $err) = ( '', '' );
+#  local($SIG{CHLD}) = sub {};
+#  run( [ $program, $file ], \undef, \$out, \$err, timeout($timeout) )
+#    or die "$program failed with exit status ". ( $? >> 8 ). ": $out\n";
+#
+#  ( my $outfile = $file ) =~ s/\.pdf$/.html/i
+#    or die "poppler.pm called with non-PDF file?!";
+#
+#  my $html = slurp($outfile);
+#
+#  $html;
+#
+#}
+
+1;
diff --git a/lib/HTML/AutoConvert/unrtf.pm b/lib/HTML/AutoConvert/unrtf.pm
new file mode 100644 (file)
index 0000000..034440e
--- /dev/null
@@ -0,0 +1,25 @@
+package HTML::AutoConvert::unrtf;
+
+=head1 NAME
+
+HTML::AutoConvert::unrtf - unrtf plugin for HTML::AutoConvert
+
+=head1 URL
+
+unrtf can be downloaded from ftp://ftp.gnu.org/pub/gnu/unrtf/
+
+=cut
+
+use strict;
+use vars qw( %info );
+use base 'HTML::AutoConvert::Run';
+
+%info = (
+  'types'   => 'rtf',
+  'weight'  => 90,
+  'url'     => 'ftp://ftp.gnu.org/pub/gnu/unrtf/',
+);
+
+sub program { ( 'unrtf' ) }
+
+1;
diff --git a/lib/HTML/AutoConvert/wvWare.pm b/lib/HTML/AutoConvert/wvWare.pm
new file mode 100644 (file)
index 0000000..26a57cd
--- /dev/null
@@ -0,0 +1,25 @@
+package HTML::AutoConvert::wvWare;
+
+=head1 NAME
+
+HTML::AutoConvert::wvWare - wvWare plugin for HTML::AutoConvert
+
+=head1 URL
+
+wvWare can be downloaded from http://wvware.sourceforge.net/
+
+=cut
+
+use strict;
+use vars qw( %info );
+use base 'HTML::AutoConvert::Run';
+
+%info = (
+  'types'   => 'doc',
+  'weight'  => 80,
+  'url'     => 'http://wvware.sourceforge.net/',
+);
+
+sub program { ( 'wvWare' ) }
+
+1;
diff --git a/t/.26-pdf-poppler.t.swp b/t/.26-pdf-poppler.t.swp
new file mode 100644 (file)
index 0000000..1e7c8f3
Binary files /dev/null and b/t/.26-pdf-poppler.t.swp differ
diff --git a/t/.TO.swp b/t/.TO.swp
new file mode 100644 (file)
index 0000000..4048d23
Binary files /dev/null and b/t/.TO.swp differ
diff --git a/t/00-load.t b/t/00-load.t
new file mode 100644 (file)
index 0000000..501cd13
--- /dev/null
@@ -0,0 +1,9 @@
+#!perl -T
+
+use Test::More tests => 1;
+
+BEGIN {
+       use_ok( 'HTML::AutoConvert' );
+}
+
+diag( "Testing HTML::AutoConvert $HTML::AutoConvert::VERSION, Perl $], $^X" );
diff --git a/t/01-doc.t b/t/01-doc.t
new file mode 100644 (file)
index 0000000..cbb8286
--- /dev/null
@@ -0,0 +1,14 @@
+#!perl
+
+use Test::More tests => 2;
+
+use HTML::AutoConvert;
+
+my $c = new HTML::AutoConvert;
+
+my $html = $c->html_convert('t/DiaryofaKillerCat.doc');
+
+#match $html against something;
+like( $html, qr/Chunky/, 'text is Chunky' );
+like( $html, qr/Monkey/, 'text has Monkey' );
+
diff --git a/t/02-doc-antiword.t b/t/02-doc-antiword.t
new file mode 100644 (file)
index 0000000..d3ab6b7
--- /dev/null
@@ -0,0 +1,19 @@
+#!perl
+
+use Test::More tests => 2;
+
+use HTML::AutoConvert;
+
+my $c = new HTML::AutoConvert;
+
+my $force = 'antiword';
+#$c->{'handlers'}{'doc'}{$force}{'weight'} = -1;
+my @del = grep { $_ ne $force } keys %{ $c->{'handlers'}{'doc'} };
+delete($c->{'handlers'}{'doc'}{$_}) foreach @del;
+
+my $html = $c->html_convert('t/DiaryofaKillerCat.doc');
+
+#match $html against something;
+like( $html, qr/Chunky/, 'text is Chunky' );
+like( $html, qr/Monkey/, 'text has Monkey' );
+
diff --git a/t/03-doc-wvWare.t b/t/03-doc-wvWare.t
new file mode 100644 (file)
index 0000000..2f11898
--- /dev/null
@@ -0,0 +1,19 @@
+#!perl
+
+use Test::More tests => 2;
+
+use HTML::AutoConvert;
+
+my $c = new HTML::AutoConvert;
+
+my $force = 'wvWare';
+#$c->{'handlers'}{'doc'}{$force}{'weight'} = -1;
+my @del = grep { $_ ne $force } keys %{ $c->{'handlers'}{'doc'} };
+delete($c->{'handlers'}{'doc'}{$_}) foreach @del;
+
+my $html = $c->html_convert('t/DiaryofaKillerCat.doc');
+
+#match $html against something;
+like( $html, qr/Chunky/, 'text is Chunky' );
+like( $html, qr/Monkey/, 'text has Monkey' );
+
diff --git a/t/04-doc-OpenOffice.t b/t/04-doc-OpenOffice.t
new file mode 100644 (file)
index 0000000..489bff7
--- /dev/null
@@ -0,0 +1,21 @@
+#!perl
+
+BEGIN { chomp($pwd=`pwd`); $ENV{PATH} .= ":$pwd/bin"; };
+
+use Test::More tests => 2;
+
+use HTML::AutoConvert;
+
+my $c = new HTML::AutoConvert;
+
+my $force = 'OpenOffice';
+#$c->{'handlers'}{'doc'}{$force}{'weight'} = -1;
+my @del = grep { $_ ne $force } keys %{ $c->{'handlers'}{'doc'} };
+delete($c->{'handlers'}{'doc'}{$_}) foreach @del;
+
+my $html = $c->html_convert('t/DiaryofaKillerCat.doc');
+
+#match $html against something;
+like( $html, qr/Chunky/, 'text is Chunky' );
+like( $html, qr/Monkey/, 'text has Monkey' );
+
diff --git a/t/14-rtf-OpenOffice.t b/t/14-rtf-OpenOffice.t
new file mode 100644 (file)
index 0000000..319eff7
--- /dev/null
@@ -0,0 +1,21 @@
+#!perl
+
+BEGIN { chomp($pwd=`pwd`); $ENV{PATH} .= ":$pwd/bin"; };
+
+use Test::More tests => 2;
+
+use HTML::AutoConvert;
+
+my $c = new HTML::AutoConvert;
+
+my $force = 'OpenOffice';
+#$c->{'handlers'}{'doc'}{$force}{'weight'} = -1;
+my @del = grep { $_ ne $force } keys %{ $c->{'handlers'}{'rtf'} };
+delete($c->{'handlers'}{'rtf'}{$_}) foreach @del;
+
+my $html = $c->html_convert('t/VEGAN_RECIPES.rtf');
+
+#match $html against something;
+like( $html, qr/Gumbo/, 'text has Gumbo' );
+like( $html, qr/Cheesecake/, 'text has Cheesecake' );
+
diff --git a/t/15-rtf-unrtf.t b/t/15-rtf-unrtf.t
new file mode 100644 (file)
index 0000000..e5194f5
--- /dev/null
@@ -0,0 +1,19 @@
+#!perl
+
+use Test::More tests => 2;
+
+use HTML::AutoConvert;
+
+my $c = new HTML::AutoConvert;
+
+my $force = 'unrtf';
+#$c->{'handlers'}{'doc'}{$force}{'weight'} = -1;
+my @del = grep { $_ ne $force } keys %{ $c->{'handlers'}{'rtf'} };
+delete($c->{'handlers'}{'rtf'}{$_}) foreach @del;
+
+my $html = $c->html_convert('t/VEGAN_RECIPES.rtf');
+
+#match $html against something;
+like( $html, qr/Gumbo/, 'text has Gumbo' );
+like( $html, qr/Cheesecake/, 'text has Cheesecake' );
+
diff --git a/t/26-pdf-poppler.t b/t/26-pdf-poppler.t
new file mode 100644 (file)
index 0000000..af3aa8c
--- /dev/null
@@ -0,0 +1,19 @@
+#!perl
+
+use Test::More tests => 2;
+
+use HTML::AutoConvert;
+
+my $c = new HTML::AutoConvert;
+
+my $force = 'poppler';
+#$c->{'handlers'}{'doc'}{$force}{'weight'} = -1;
+my @del = grep { $_ ne $force } keys %{ $c->{'handlers'}{'pdf'} };
+delete($c->{'handlers'}{'pdf'}{$_}) foreach @del;
+
+my $html = $c->html_convert('t/attitude.pdf');
+
+#match $html against something;
+like( $html, qr/sampling/, 'text has sampling' );
+like( $html, qr/respondents/, 'text has respondents' );
+
diff --git a/t/DiaryofaKillerCat.doc b/t/DiaryofaKillerCat.doc
new file mode 100644 (file)
index 0000000..d8dd0fc
Binary files /dev/null and b/t/DiaryofaKillerCat.doc differ
diff --git a/t/VEGAN_RECIPES.rtf b/t/VEGAN_RECIPES.rtf
new file mode 100644 (file)
index 0000000..52cb4ea
--- /dev/null
@@ -0,0 +1,257 @@
+{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fswiss\fcharset0 Arial;}}\r
+{\*\generator Msftedit 5.41.21.2507;}\viewkind4\uc1\pard\b\f0\fs16 The Pigs are Safe in the Blanket\b0\par\r
+Ingredients :\par\r
+4 vegan "not dogs" (I use Smart Dogs)\par\r
+1/2 cup unbleached flour\par\r
+1 tablespoon corn meal\par\r
+1 tablespoon oil (any)\par\r
+1/2-1 teaspoon sugar (unrefined)\par\r
+1 teaspoon baking powder\par\r
+water (until dough formed)\par\r
+Directions:\par\r
+Mix together all ingredients except for the "not dogs" (well duh) until it is in a dough ball.\par\r
+Next cut the "not dogs" in half.\par\r
+Roll the dough out as thin as you would a tortilla and wrap the dough around your dogs.\par\r
+Bake at 375 from 12-15 minutes until golden.\par\r
+Serve with your favorite condiments.(I\rquote m attempting Thai peanut sauce). Smiley\par\r
+Serves: 2\par\r
+Preparation time: quick\par\r
+\par\r
+\b\par\r
+Veggie Sausage Gumbo\b0\par\r
+Makes 4 servings\par\r
+\par\r
+* 1 cup frozen okra\par\r
+* 16 ounces veggie sausage links, cut into 1-inch pieces (Tofurky Italian Sausage, Lightlife Smart Links Country Breakfast Style or another brand of vegan sausage)\par\r
+* 2 tablespoons all-purpose flour\par\r
+* 2 tablespoons vegetable oil\par\r
+* 1 large onion, chopped\par\r
+* 1 large green pepper, chopped\par\r
+* 2 cloves fresh garlic, chopped\par\r
+* 1/2 teaspoon dried thyme\par\r
+* 1/4 teaspoon ground red pepper\par\r
+* 1 16-ounce can diced tomatoes\par\r
+* 1 cup celery, chopped\par\r
+* 5 cups vegetable stock\par\r
+* salt to taste (if desired)\par\r
+* Tabasco sauce to taste (if desired)\par\r
+* 2 cups cooked rice\par\r
+Fry the okra until lightly browned and set aside. Lightly fry the sausage pieces and set aside.\par\r
+Combine flour and oil in a large pot, stirring constantly. Saut\'e9 over medium-high heat for 1 minute. Add okra, onion, pepper, garlic, thyme, and ground red pepper. Cook for 1 minute on medium heat, stirring frequently.\par\r
+Stir in veggie sausage, tomatoes, celery, vegetable stock, and cook 15 minutes or until thoroughly heated. Add salt and Tabasco sauce if desired. Serve over rice.\par\r
+\par\r
+\b\par\r
+Holiday Lentil Loaf\b0\par\r
+Ingredients :\par\r
+1 small onion\par\r
+1 clove garlic\par\r
+2 stalks celery\par\r
+2 teaspoon sage\par\r
+3 cups cooked lentils\par\r
+3 cups cooked wild rice (you can use a wild rice/brown rice mix here too)\par\r
+1/2 cup chopped walnuts\par\r
+1/4 cup whole wheat breadcrumbs\par\r
+2 tablespoon vinegar\par\r
+2 egg equivalents\par\r
+2 tablespoon whole wheat flour\par\r
+fresh ground black pepper and sea salt\par\r
+\par\r
+Directions:\par\r
+Preheat oven to 350 F.\par\r
+Chop onion and celery finely, and crush the garlic clove. Spray a fraying pan with non-stick spray, and saute the onion, garlic and celery until onion is translucent. Add the sage. Combine all ingredients in a large bowl and mix well. Spray a loaf pan with non-stick spray and fill the loaf pan with the mixture. Press down. Bake 30 minutes covered, 10 minutes uncovered. Let stand for 5-10 minutes before cutting and serving.\par\r
+\par\r
+\b\par\r
+\par\r
+\par\r
+\par\r
+\par\r
+\par\r
+Mock Meatloaf\b0\par\r
+Serves 4\par\r
+* 1 pound vegetarian ground beef (try Boca Burger's Original Meatless Ground Burger or Gardenburger's Meatless Crumbles)\par\r
+* 3 tablespoons ketchup\par\r
+* 2/3 tablespoon prepared mustard\par\r
+* 1/2 tablespoon horseradish\par\r
+* 1 small onion, finely chopped\par\r
+* 1 teaspoon salt\par\r
+* 1/2 cup soft bread crumbs\par\r
+* 1/4 cup soymilk\par\r
+* 1/2 tablespoon soy sauce\par\r
+\par\r
+Preheat oven to 350\'b0F degrees. Combine all ingredients in a large bowl. Press lightly into a bread loaf pan. Wrap loosely with foil. Bake for about 1 hour and 20 minutes.\par\r
+\par\r
+\b\par\r
+Vegan Gravy\par\r
+\b0 1/2 cup vegetable oil\par\r
+3-6 garlic cloves, minced well\par\r
+2-3 slices yellow onions, chopped\par\r
+1/2 cup all-purpose flour\par\r
+4 teaspoons nutritional yeast\par\r
+4 tablespoons reduced sodium soy sauce\par\r
+2 cups water\par\r
+1/2 teaspoon sage\par\r
+1/4 teaspoon black pepper\par\r
+1/2 teaspoon salt (optional)\par\r
+5-6 white mushrooms, sliced (optional)\par\r
+\par\r
+1. Cook the onion and garlic in the oil until tender.\par\r
+2. Add the flour, yeast, and soy sauce to make a paste.\par\r
+3. Add the water gradually, stirring constantly.\par\r
+4. Bring the gravy to a boil on medium heat, stirring constantly (the gravy has to boil to thicken).\par\r
+5. Add pepper.\par\r
+6. Add salt and sliced mushrooms, if using.\par\r
+7. If the gravy is too thin, whisk in 1-2 tablespoons of flour or small amounts of cornstarch to thicken it.\par\r
+8. The gravy refrigerates well, but freezing is not recommended.\par\r
+9. The cooled gravy re-heats well in the microwave or on the stove.\par\r
+\par\r
+\b\par\r
+VEGAN POT PIE\par\r
+\b0 Ingredients:\par\r
+1 frozen pie shell, or fresh dough if you have time\par\r
+2-3 cups veggie broth\par\r
+1-2 potatoes\par\r
+3 medium carrots\par\r
+a variety of veggies such as green beans, zuchinni, mushrooms, or just about anything.\par\r
+1 package frozen spinach\par\r
+vegan grated or sliced cheddar to cover pan in two layers\par\r
+lots of good spices: garlic,\par\r
+cumin, tarragon makes it savory, whatever you like.\par\r
+\par\r
+DIRECTIONS\par\r
+Thaw pie she'll and try real hard to take one 1/2 out of the tin w/o it breaking into a million pieces. If you manage, you are a god(dess). Meanwhile, cook chopped veggies (NOT spinach, just keep it till later). Cook in micro or oven till about 3/4 cooked. To make sauce, heat broth in large kettle, add spices, and lower heat. Add slowly either cornstarch or flour (I use flour), till slightly thickened. You can add dairy free milk and use veggie buillon cubes. Add to this cooked veggies and coat them w/sauce.\par\r
+Meanwhile, layer 1/2 cheese on bottom of lower crust. Spoon in veggies and sauce, then add spinach on top. add rest of cheese on top of that, and close it up as best as you can w/ the torn top shell. at least mine always tears. bake at 400 for about 45 min, till crust is brown and delicious cheese and juice oozes out.\par\r
+\par\r
+\b\par\r
+\par\r
+\par\r
+\par\r
+\par\r
+\par\r
+TUNA MUSHROOM CASSEROLE\par\r
+\par\r
+\b0 Serves: 3-4 hungry adults\par\r
+Ultimate Comfort Food!\par\r
+Photo Sharing and Video Hosting at Photobucket\par\r
+Ingredients:\par\r
+1 medium onion, chopped\par\r
+2 stalks celery, chopped\par\r
+10 oz. baby portabella mushrooms, sliced\par\r
+4 tablespoon vegan margarine\par\r
+1 teaspoon soy sauce\par\r
+1/4 cup flour\par\r
+2 cups veggie broth\par\r
+1-1/2 cups unsweetened soy milk\par\r
+2 teaspoon lemon juice\par\r
+1 cup canned chickpeas, drained and mashed\par\r
+1/2 cup crushed potato chips plain\par\r
+1/2 cup French fried onions\par\r
+8 oz. fusilli pasta\par\r
+\par\r
+Directions:\par\r
+Preheat oven to 350 Degrees F and prepare an 8x8" glass baking dish with a quick spray of cooking oil.\par\r
+\par\r
+\b Pumpkin Cheesecake\par\r
+\b0 * 12 oz. firm silken tofu, pureed\par\r
+* 8 oz. nondairy cream cheese (try Tofutti brand at Tofutti.com)\par\r
+* 1 cup canned pumpkin\par\r
+* 1 cup granulated sugar\par\r
+* 3 Tbsp. flour\par\r
+* 1/2 tsp. ground ginger\par\r
+* 1/2 tsp. nutmeg\par\r
+* 1 1/2 tsp. cinnamon\par\r
+* 1/8 tsp. salt\par\r
+* 1/4 tsp. baking soda\par\r
+* 1 prepared graham cracker crust\par\r
+Preheat the oven to 350\'b0F. Pur\'e9e all the ingredients except the pie crust in a food processor and pour into the graham cracker crust. Bake at 350\'b0F for 50 minutes. Allow to cool for 30 minutes, cover with plastic wrap or the top of the pie container\par\r
+Heat 1 tablespoon vegan margarine in a pan. Add onion, celery and mushrooms and saute for a few minutes. When mushrooms give off liquid, add soy sauce. Keep cooking until all vegetables are tender, turn off heat.\par\r
+In a medium soup pot, melt the remaining 3 tablespoon vegan margarine over low heat. Stir in the flour and whisk for a few minutes. It will get thick. Start adding the broth bit by bit, whisking all the while and bring to a boil. Add the soymilk little by little and continue to stir and simmer. Add the mushroom/celery/onion mixture and lemon juice. Season with salt, pepper and some paprika. Add the mashed chickpeas a spoonful at a time to break it up evenly throughout the sauce.\par\r
+Cook pasta until al dente, approx. 9 minutes. Drain and return it to the pot. Add the mushroom sauce to the pasta and stir gently to combine. Transfer the mixture to the baking dish. Cover tightly with foil and bake for 15 minutes. Uncover the dish and sprinkle crushed chips and french fried onions on top and bake for another 5-6 minutes or so or until the top is browned and crispy.\par\r
+Serves: 8\par\r
+\par\r
+\b Yummy Sugar Cookies\par\r
+\b0 Ingredients:\par\r
+2 cups flour\par\r
+3/4 cups sugar\par\r
+1 teaspoon baking powder\par\r
+1/4 cup applesauce\par\r
+1/2 cup oil\par\r
+1 tablespoon vanilla extract\par\r
+dash of cinnamon (optional)\par\r
+extra sugar or sprinkles for the top!(optional)\par\r
+\par\r
+Directions:\par\r
+In a medium sized bowl mix together flour, sugar, baking powder, and cinnamon set aside.\par\r
+In another bowl, mix together wet ingredients.\par\r
+Add the wet ingredients to the dry ingredients.\par\r
+Start preheating oven to 350 Fahrenheit.\par\r
+Roll dough out and cut out shapes with cookie cutters.\par\r
+Bake in oven on a lightly oiled cookie sheet for about 10-12 minutes.\par\r
+Serves: about 2 dozen\par\r
+Preparation time: not long !\par\r
+\par\r
+\b HUMMUS\par\r
+\b0 Hummus is a middle-eastern food composed of chickpeas, or garbanzo beans, and tahini, a paste similar in texture to peanut butter that is made from sesame seeds. Hummus is typically eaten with pita or other flat bread.\par\r
+Because both chickpeas and sesame seeds are wonderfully healthful, hummus is a nutritionist's delight. Chickpeas are a good source of protein, potassium and fiber. Sesame seeds are also a source of protein, along with vitamin E and a powerful antioxidant. So when you blend them together into hummus, you're really cooking!\par\r
+Mash them together, spread them on the flat bread and sprinkle with lemon....\par\r
+\par\r
+\b EGGPLANT HUMMUS\par\r
+BABAGANOUSH\b0\par\r
+\par\r
+Difficulty: easy\par\r
+Cooking Time: 60 minutes\par\r
+Servings: 4 people\par\r
+Ingredients:\par\r
+\u9829? 2 big eggplants\par\r
+\u9829? 1 garlic clove, mashed\par\r
+\u9829? 1/2 lemon juice\par\r
+\u9829? 3 tablespoon tahini\par\r
+\u9829? 2 tablespoon olive oil\par\r
+\u9829? oregano\par\r
+\u9829? salt\par\r
+\u9829? 1 tablespoon soy yoghourt with no sugar (optional)\par\r
+Preheat oven 10 minutes to 200\'baC. Prick the eggplant several times with a knife. Roast 35-45 minutes until soft and the skin is blackened (if you do not have oven, roast the eggplants over a barbecue turning frequently).\par\r
+Scoop out all the flesh of the eggplants and discard the skins.\par\r
+Mix the eggplant with the garlic, lemon juice, tahini, olive oil, oregano, salt and soy yoghourt, with a blender, until soft. Serve cold or hot with bread.\par\r
+Presentation Suggestion: serve with chopped tomato and parsley, and some tahini\par\r
+*If you never had hummus, try it. its awesomeculty: medium\par\r
+Cooking Time: 35 minutes\par\r
+\b\par\r
+\par\r
+EGGPLANT SANDWICH\par\r
+\b0 Ingredients:\par\r
+\u9829? 2 eggplants\par\r
+\u9829? 150 g (6oz) vegan salami or seitan\par\r
+\u9829? 2 tomatoes\par\r
+\u9829? 8 white asparagus\par\r
+\u9829? 100 g vegan (3.50z)soy cheese\par\r
+\u9829? 100 g (1 cup) tempura flour or chickpea flour with 1/2 teaspoon baking powder\par\r
+\u9829? sunflower oil (for frying)\par\r
+\u9829? salt\par\r
+Chop eggplants into 12 slices (long side), sprinkle with salt and let release bitter juice.\par\r
+Chop tomatoes into 8 slices, vegan salami/seitan into fine slices, vegan cheese into pieces and cut asparagus in half.\par\r
+Mix tempura flour or chickpea flour with water until thick.\par\r
+Heat abundant oil. Coat eggplant in temputa/flour and fry both sides until lightly brown. Leave in kitchen paper.\par\r
+For each sandwich, put an eggplant slice, two tomato slices, some salami/seitan slices, another eggplant, 4 half asparagus, more salami/seitan, another eggplant and vegan cheese on top.\par\r
+Cook at the oven at 180\'baC (350F) 8-10 minutes and serve hot.\par\r
+\par\r
+\b Apple Crunch Muffins\par\r
+\b0 Ingredients :\par\r
+1 1/2 cups unbleached flour, sifted\par\r
+2 teaspoon baking powder\par\r
+1 teaspoon ground cinnamon\par\r
+Replacement for 1 egg (Ener-G egg replacer)\par\r
+1 cup shredded apples\par\r
+1/2 cup sugar\par\r
+1/2 teaspoon salt\par\r
+1/4 cup shortening\par\r
+1/2 cup soy milk\par\r
+1/4 brown sugar\par\r
+1/4 cup pecans\par\r
+Directions:\par\r
+Sift together flour, vegan sugar, baking powder, salt and 1/2 tsp. cinnamon into mixing bowl.\par\r
+Cut in shortening with pastry blender until fine crumbs form. Combine Ener-G Egg Replacer and soymilk. Add to dry ingredients all at once, stirring just enough to moisten. Stir in apples. Spoon batter into paper-lined 2 1/2-inch muffin-pan cups, filling 2/3rds full. Mix brown vegan sugar, pecans, and 1/2 tsp cinnamon in a bowl. Sprinkle over muffins.\par\r
+Bake in 375 degree oven 25 minutes or until golden brown. Preparation time: 1 hour\fs20\par\r
+\par\r
+\b\par\r
+}\r
+\0
\ No newline at end of file
diff --git a/t/attitude.pdf b/t/attitude.pdf
new file mode 100644 (file)
index 0000000..4a2ee71
Binary files /dev/null and b/t/attitude.pdf differ
diff --git a/t/boilerplate.t b/t/boilerplate.t
new file mode 100644 (file)
index 0000000..121273f
--- /dev/null
@@ -0,0 +1,49 @@
+#!perl -T
+
+use strict;
+use warnings;
+use Test::More tests => 3;
+
+sub not_in_file_ok {
+    my ($filename, %regex) = @_;
+    open( my $fh, '<', $filename )
+        or die "couldn't open $filename for reading: $!";
+
+    my %violated;
+
+    while (my $line = <$fh>) {
+        while (my ($desc, $regex) = each %regex) {
+            if ($line =~ $regex) {
+                push @{$violated{$desc}||=[]}, $.;
+            }
+        }
+    }
+
+    if (%violated) {
+        fail("$filename contains boilerplate text");
+        diag "$_ appears on lines @{$violated{$_}}" for keys %violated;
+    } else {
+        pass("$filename contains no boilerplate text");
+    }
+}
+
+sub module_boilerplate_ok {
+    my ($module) = @_;
+    not_in_file_ok($module =>
+        'the great new $MODULENAME'   => qr/ - The great new /,
+        'boilerplate description'     => qr/Quick summary of what the module/,
+        'stub function definition'    => qr/function[12]/,
+    );
+}
+
+not_in_file_ok(README =>
+  "The README is used..."       => qr/The README is used/,
+  "'version information here'"  => qr/to provide version information/,
+);
+
+not_in_file_ok(Changes =>
+  "placeholder date/time"       => qr(Date/time)
+);
+
+module_boilerplate_ok('lib/HTML/AutoConvert.pm');
+
diff --git a/t/pod-coverage.t b/t/pod-coverage.t
new file mode 100644 (file)
index 0000000..0126dfc
--- /dev/null
@@ -0,0 +1,20 @@
+use strict;
+use warnings;
+use Test::More;
+
+# Ensure a recent version of Test::Pod::Coverage
+my $min_tpc = 1.08;
+eval "use Test::Pod::Coverage $min_tpc";
+plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage"
+    if $@;
+
+# Test::Pod::Coverage doesn't require a minimum Pod::Coverage version,
+# but older versions don't recognize some common documentation styles
+my $min_pc = 0.18;
+eval "use Pod::Coverage $min_pc";
+plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage"
+    if $@;
+
+plan skip_all => 'POD coverage check disabled for now';
+
+all_pod_coverage_ok();
diff --git a/t/pod.t b/t/pod.t
new file mode 100644 (file)
index 0000000..ee8b18a
--- /dev/null
+++ b/t/pod.t
@@ -0,0 +1,12 @@
+#!perl -T
+
+use strict;
+use warnings;
+use Test::More;
+
+# Ensure a recent version of Test::Pod
+my $min_tp = 1.22;
+eval "use Test::Pod $min_tp";
+plan skip_all => "Test::Pod $min_tp required for testing POD" if $@;
+
+all_pod_files_ok();
diff --git a/uno b/uno
new file mode 100644 (file)
index 0000000..f778b44
--- /dev/null
+++ b/uno
@@ -0,0 +1,316 @@
+%!PS-Adobe-3.0
+%%Creator: (ImageMagick)
+%%Title: (uno)
+%%CreationDate: (Sun Aug 10 19:46:10 2008)
+%%BoundingBox: 595 209 611 236
+%%HiResBoundingBox: 595 209 611 236
+%%DocumentData: Clean7Bit
+%%LanguageLevel: 1
+%%Orientation: Portrait
+%%PageOrder: Ascend
+%%Pages: 1
+%%EndComments
+
+%%BeginDefaults
+%%EndDefaults
+
+%%BeginProlog
+%
+% Display a color image.  The image is displayed in color on
+% Postscript viewers or printers that support color, otherwise
+% it is displayed as grayscale.
+%
+/DirectClassPacket
+{
+  %
+  % Get a DirectClass packet.
+  %
+  % Parameters:
+  %   red.
+  %   green.
+  %   blue.
+  %   length: number of pixels minus one of this color (optional).
+  %
+  currentfile color_packet readhexstring pop pop
+  compression 0 eq
+  {
+    /number_pixels 3 def
+  }
+  {
+    currentfile byte readhexstring pop 0 get
+    /number_pixels exch 1 add 3 mul def
+  } ifelse
+  0 3 number_pixels 1 sub
+  {
+    pixels exch color_packet putinterval
+  } for
+  pixels 0 number_pixels getinterval
+} bind def
+
+/DirectClassImage
+{
+  %
+  % Display a DirectClass image.
+  %
+  systemdict /colorimage known
+  {
+    columns rows 8
+    [
+      columns 0 0
+      rows neg 0 rows
+    ]
+    { DirectClassPacket } false 3 colorimage
+  }
+  {
+    %
+    % No colorimage operator;  convert to grayscale.
+    %
+    columns rows 8
+    [
+      columns 0 0
+      rows neg 0 rows
+    ]
+    { GrayDirectClassPacket } image
+  } ifelse
+} bind def
+
+/GrayDirectClassPacket
+{
+  %
+  % Get a DirectClass packet;  convert to grayscale.
+  %
+  % Parameters:
+  %   red
+  %   green
+  %   blue
+  %   length: number of pixels minus one of this color (optional).
+  %
+  currentfile color_packet readhexstring pop pop
+  color_packet 0 get 0.299 mul
+  color_packet 1 get 0.587 mul add
+  color_packet 2 get 0.114 mul add
+  cvi
+  /gray_packet exch def
+  compression 0 eq
+  {
+    /number_pixels 1 def
+  }
+  {
+    currentfile byte readhexstring pop 0 get
+    /number_pixels exch 1 add def
+  } ifelse
+  0 1 number_pixels 1 sub
+  {
+    pixels exch gray_packet put
+  } for
+  pixels 0 number_pixels getinterval
+} bind def
+
+/GrayPseudoClassPacket
+{
+  %
+  % Get a PseudoClass packet;  convert to grayscale.
+  %
+  % Parameters:
+  %   index: index into the colormap.
+  %   length: number of pixels minus one of this color (optional).
+  %
+  currentfile byte readhexstring pop 0 get
+  /offset exch 3 mul def
+  /color_packet colormap offset 3 getinterval def
+  color_packet 0 get 0.299 mul
+  color_packet 1 get 0.587 mul add
+  color_packet 2 get 0.114 mul add
+  cvi
+  /gray_packet exch def
+  compression 0 eq
+  {
+    /number_pixels 1 def
+  }
+  {
+    currentfile byte readhexstring pop 0 get
+    /number_pixels exch 1 add def
+  } ifelse
+  0 1 number_pixels 1 sub
+  {
+    pixels exch gray_packet put
+  } for
+  pixels 0 number_pixels getinterval
+} bind def
+
+/PseudoClassPacket
+{
+  %
+  % Get a PseudoClass packet.
+  %
+  % Parameters:
+  %   index: index into the colormap.
+  %   length: number of pixels minus one of this color (optional).
+  %
+  currentfile byte readhexstring pop 0 get
+  /offset exch 3 mul def
+  /color_packet colormap offset 3 getinterval def
+  compression 0 eq
+  {
+    /number_pixels 3 def
+  }
+  {
+    currentfile byte readhexstring pop 0 get
+    /number_pixels exch 1 add 3 mul def
+  } ifelse
+  0 3 number_pixels 1 sub
+  {
+    pixels exch color_packet putinterval
+  } for
+  pixels 0 number_pixels getinterval
+} bind def
+
+/PseudoClassImage
+{
+  %
+  % Display a PseudoClass image.
+  %
+  % Parameters:
+  %   class: 0-PseudoClass or 1-Grayscale.
+  %
+  currentfile buffer readline pop
+  token pop /class exch def pop
+  class 0 gt
+  {
+    currentfile buffer readline pop
+    token pop /depth exch def pop
+    /grays columns 8 add depth sub depth mul 8 idiv string def
+    columns rows depth
+    [
+      columns 0 0
+      rows neg 0 rows
+    ]
+    { currentfile grays readhexstring pop } image
+  }
+  {
+    %
+    % Parameters:
+    %   colors: number of colors in the colormap.
+    %   colormap: red, green, blue color packets.
+    %
+    currentfile buffer readline pop
+    token pop /colors exch def pop
+    /colors colors 3 mul def
+    /colormap colors string def
+    currentfile colormap readhexstring pop pop
+    systemdict /colorimage known
+    {
+      columns rows 8
+      [
+        columns 0 0
+        rows neg 0 rows
+      ]
+      { PseudoClassPacket } false 3 colorimage
+    }
+    {
+      %
+      % No colorimage operator;  convert to grayscale.
+      %
+      columns rows 8
+      [
+        columns 0 0
+        rows neg 0 rows
+      ]
+      { GrayPseudoClassPacket } image
+    } ifelse
+  } ifelse
+} bind def
+
+/DisplayImage
+{
+  %
+  % Display a DirectClass or PseudoClass image.
+  %
+  % Parameters:
+  %   x & y translation.
+  %   x & y scale.
+  %   label pointsize.
+  %   image label.
+  %   image columns & rows.
+  %   class: 0-DirectClass or 1-PseudoClass.
+  %   compression: 0-none or 1-RunlengthEncoded.
+  %   hex color packets.
+  %
+  gsave
+  /buffer 512 string def
+  /byte 1 string def
+  /color_packet 3 string def
+  /pixels 768 string def
+
+  currentfile buffer readline pop
+  token pop /x exch def
+  token pop /y exch def pop
+  x y translate
+  currentfile buffer readline pop
+  token pop /x exch def
+  token pop /y exch def pop
+  currentfile buffer readline pop
+  token pop /pointsize exch def pop
+  /Times-Roman findfont pointsize scalefont setfont
+  x y scale
+  currentfile buffer readline pop
+  token pop /columns exch def
+  token pop /rows exch def pop
+  currentfile buffer readline pop
+  token pop /class exch def pop
+  currentfile buffer readline pop
+  token pop /compression exch def pop
+  class 0 gt { PseudoClassImage } { DirectClassImage } ifelse
+  grestore
+  showpage
+} bind def
+%%EndProlog
+%%Page:  1 1
+%%PageBoundingBox: 595 209 611 236
+DisplayImage
+595 209
+16 27
+12.000000
+16 27
+0
+0
+1E20391E20391E20391E20391E20391E20391E20391E20391E20391E20391E20391F213A
+1F213A1F213A1F213A1F213A1E20391E20391E20391E20391E20391E20391E20391E2039
+1E20391E20391E20391F213A1F213A1F213A1F213A1F213A1E20391E20391E20391E2039
+1E20391E20391E20391E20391E20391E20391E20391F213A1F213A1F213A1F213A1F213A
+1E20391E20391E20391E20391E20391E20391E20391E20391E20391E20391E20391F213A
+1F213A1F213A1F213A1F213A1E20391E20391E20391E20391E20391E20391E20391E2039
+1E20391E20391E20391F213A1F213A1F213A1F213A1F213A1E20391E20391E20391E2039
+1E20391E20391E20391E20391E20391E20391E20391F213A1F213A1F213A1F213A1F213A
+1E20391E20391E20391E20391E20391E20391E20391E20391E20391E20391E20391F213A
+1F213A1F213A1F213A1F213A1E20391E20391E20391E20391E20391D1F381E20391E2039
+1E20391E20391E20391E20391E20391E20391E20391E20391E20391E20391E20391E2039
+1E20391E20391E20391E20391E20391E20391E20391E20391E20391E20391F213A1F213A
+1E1F3B1E1F3B1E1F3B1E1F3B1E1F3B1E1F3B1E1F3B1E1F3B1E1F3B1E1F3B1E1F3B1E1F3B
+1F203C1F203C1F203C1F203C1E1F3B1E1F3B1E1F3B1E1F3B1E1F3B1E1F3B1E1F3B1E1F3B
+1E1F3B1E1F3B1E1F3B1F203C1F203C1F203C1F203C1F203C1F203C1F203C1F203C1F203C
+1F203C1E1F3B1E1F3B1E1F3B1E1F3B1E1F3B1E1F3B1F203C1F203C1F203C1F203C1F203C
+1F203D1F203D1F203D1F203D1F203D1E1F3C1E1F3C1E1F3C1E1F3C1F203D1F203D1F203D
+1F203D1F203D1F203D1F203D1F203E1F203E1F203E1F203E1F203E1E1F3D1E1F3D1E1F3D
+1E1F3D1F203E1F203E1F203E1F203E1F203E1F203E1F203E1F203E1F203E1F203E1F203E
+1F203E1E1F3D1E1F3D1E1F3D1F203E1F203E1F203E1F203E1F203E1F203E1F203E1F203E
+1F203E1F203E1F203E1F203E1F203E1F203E1F203E1F203E1F203E1F203E1F203E1F203E
+1F203E1F203E1F203E20213F1F203E1F203E1F203E1F203E1F203E2425432122401D1E3C
+1E1F3D20213F2122401F203E1F203E1E1F3D21224021224020213F20213F20213F20213F
+20213F1A1B391B1C3A1B1C3A20213F22234123244220213F21224021224022234120213F
+1F21401F21401F21401F21401F214022234223244223244223244322234120213F1B1C3B
+1E1F3E2021402324422122401E21401E21401E21401E21401E2140202140202140202140
+2122412021401F203F1C1D3C1E1F3E2021402324432021401D203F1D203F1D203F1D203F
+1D203F1E1F3E1D1E3D1B1C3B1D1E3D1F203F2122412122412223422223422223421F203F
+1E21411E21411E21411E21411E21412E2F4E2728482021411D1D3D202040222242232443
+2223422122412122412122412023442023442023442023442023444646683A3A5C2E2E50
+2020422020421F1F411D1D3F1C1C3E1B1B3D1F1F41222244212143212143212143212143
+2121432727492222441D1D3F1B1B3D1E1E402121432020421F1F411D1D3F1E1E401E1E40
+1F1F411F1F411F1F411F1F411F1F412222442020421E1E402020422121432222441F1F41
+1F1F411F1F412222442121432020422020422020422020422020422020442020441F1F43
+202044212144212144202043202043202043212144212144212143202042202042202042
+202042212145212145212145212145212145212145212145212145212145212145212145
+
+%%PageTrailer
+%%Trailer
+%%EOF