Converters/Text2HTML.php

[email protected] ("Paul Meagher") Wed, 14 Mar 2001 16:35:06 -0400
Newsgroups php.pear
Message-ID <00d201c0acc6$43f1dc40$6c35de18@datavore>
I just started building a ASCII Text to HTML converter.  Below is the work
in progress.  No PEAR Error incorporated yet.

I am developing this class because I want a tool that will allow me to
construct documents using ASCII text format and run a program over it to
convert it to HTML.   Some people call this idea "smart ascii".

The names of methods are after the text patterns that I want to replace.

For example, the method convertNoSpacesAllCaps() was chosen because
document titles (<H1>) and top level headings <H2> in smart ascii format
will appear at the beginning of a line with all caps.  The diff between H1
and H2 titles is whether they appear on the first line or not.

So the objective is to develop a method of writing ascii that is very
natural so that the person is not even aware that they are writing a doc
that could be converted into a web doc (this is unrealistic but that is the
general goal).  This allows them to concertrate on writing instead of
disrupting their flow by having to think about tags and such.  It should be
like writing email.

Once these conventions are defined, then what I call "converters" are
created that look for patterns obeying those conventions and applies a
conversion to them.  The definitions of the conversions should probably be
more flexible but are hardcoded in the proof-of-concept code below.

There is a perl module that does such a text 2 html conversion.  The code
is pretty ugly so I didn't even look at very much for motivation.

http://www.aigeek.com/txt2html/

The next link provides a bit of discussion on the motivation behind using
"smart ascii".  I couldn't download the module that he discusses so I
didn't derive motivation from here either.  Just cooked it up myself.

http://gnosis.cx/publish/programming/charming_python_3.txt


Let me know if you think a class like this, suitibly PEARized, would be
useful addition to PEAR.  I will be away for the next 4 days so if anyone
feels like hacking this source, adding methods, suggesting better
conventions, etc... feel free.  It is just meant as a proof of concept of a
line oriented parser for doing the job.  It is not robust or complete at
this point.

BTW, when I look for stuff like this on the net you will sometimes find
them along with a bunch of other Converters - I wonder if we need a
directory for converters?  Text2HTML.php, Mail2HTML.php, Text2PDF.php,
etc...

<?php

define(LINE_FEED, chr(13));
define(LINE_BREAK, chr(10));

class Text2HTML
{

 var $line_number = 0;
 var $line = "";
 var $previous_line = "";
 var $ul_list_open = 0;
 var $ol_list_open = 0;
 var $text;
 var $html;


 function isLineBreak()
 {
  if ($this->line == LINE_BREAK ) {
    return true;
  } else {
    return false;
  }
 }

 function convertNoSpacesAllCaps()
 {
  if (! ($this->isLineBreak()) ) {
   if ( substr($this->line, 0, 2) !== "  " ) {
    $all_upper = strtoupper($this->line);
    if ($all_upper == $this->line) {
     $this->line = ucwords(strtolower($this->line));
     if ($this->line_number == 0) {
      $this->line = "<H1>".chop($this->line)."</H1>";
     } else {
      $this->line = "<H2>".chop($this->line)."</H2>";
     }
    }
   }
  }
  return $this->line;
 }

 function convertTwoSpacesAllCaps()
 {
  if (! ($this->isLineBreak()) ) {
   if ( substr($this->line, 0, 2) == "  " ) {
    $all_upper = strtoupper($this->line);
    if ($all_upper == $this->line) {
     $this->line = ucwords(strtolower($this->line));
     $this->line = "<H3>".chop($this->line)."</H3>";
    }
   }
  }
  return $this->line;
 }


 function convertNumberedLine()
 {
  if ($this->ol_list_open == 1) {
   $chars = substr($this->line, 0, 2);
   if (! (preg_match("/^[1-9]\.$/", $chars)) ) {
    fputs($this->html, "</OL>");
    $this->ol_list_open = 0;
    return $this->line;
   }
  }
  if ( ! ( (substr($this->line, 0, 1)) == " ")) {
   $chars = substr($this->line, 0, 2);
   if (preg_match("/^[1-9]\.$/", $chars)) {
    $this->line = substr($this->line, 2);
    if ( (preg_match("/<LI>/", $this->previous_line)) AND
($this->ul_list_open != 1) ) {
     $this->line = "<LI>".$this->line."</LI>";
    } else {
     $this->line = "<OL><LI>".$this->line."</LI>";
    }
   $this->ol_list_open = 1;
   }
  }
  return $this->line;
 }

 function convertDashedLine()
 {
  if ($this->ul_list_open == 1) {
   $chars = substr($this->line, 0, 2);
   if (! (preg_match("/^- $/", $chars)) ) {
    fputs($this->html, "</UL>");
    $this->ul_list_open = 0;
    return $this->line;
   }
  }
  if ( ! ( (substr($this->line, 0, 1)) == " ")) {
   $chars = substr($this->line, 0, 2);
   if (preg_match("/^- $/", $chars)) {
    $this->line = substr($this->line, 2);
    if ((preg_match("/<LI>/", $this->previous_line))  AND
($this->ol_list_open != 1) ) {
     $this->line = "<LI>".$this->line."</LI>";
    } else {
     $this->line = "<UL><LI>".$this->line."</LI>";
    }
   $this->ul_list_open = 1;
   }
  }
  return $this->line;
 }


 function convertLineFeed()
 {
  $this->line = str_replace(LINE_FEED,"",$this->line);
  return $this->line;
 }

 function convertLineBreak()
 {
  $this->line = str_replace(LINE_BREAK, "<BR>", $this->line);
  return $this->line;
 }


 function convertAll()
 {
  $this->convertNumberedLine();
  $this->convertDashedLine();
  $this->convertNoSpacesAllCaps();
  $this->convertTwoSpacesAllCaps();
  $this->convertLineFeed();
  $this->convertLineBreak();
  return $this->line;
 }

 function transform($text_file, $html_file)
 {
  $this->text = @fopen($text_file, "r") or die("Error: Unable to open
$file_name for reading");
  $this->html = @fopen($html_file, 'w') or die('Error: Could not open
temp_file for writing');
  while (!feof ($this->text)) {
   $this->line = fgets($this->text, 4096);
   $this->convertAll();
   $this->previous_line = $this->line;
   fputs($this->html, $this->line);
   $this->line_number++;
  }
  fclose($this->text);
  fclose($this->html);
  return true;
 }

 function printFile($file_name)
 {
  $this->text = fopen($file_name, "r") or die("Error: Unable to open
$file_name for reading");
  while (!feof ($this->text)) {
   $this->line = fgets($this->text, 4096);
   print $this->line;
  }
  fclose($this->text);
 }

} // end Class

$text_file = "text.txt";
$html_file = "text.html";

$text = new Text2HTML;
$text->transform($text_file, $html_file);
$text->printFile($html_file);
?>


This is the test file called text.txt - Make sure to put no linebreaks
before LEVEL 1 HEADER

LEVEL 1 HEADER

This is level 1 text with a line break coverted to an HTML break.

These are the points I want to make.

1. This is the first element in an ordered list.
2. This is the second element in an ordered list

- This is the first element in an unordered list.
- This is the second element in an unordered list.

LEVEL 2 HEADER

This is level 2 text.

  LEVEL 3 HEADER