Thursday, December 5, 2013

A Basic PHP LispReader

<?php
 require_once(dirname(__FILE__).DIRECTORY_SEPARATOR."lispreader.php");
 $content = file_get_contents(dirname(__FILE__).DIRECTORY_SEPARATOR."tiles.strf");
 $content = preg_replace("#;.*?\n#si", "", $content);
 $lisp = new lispReader($content);
 echo $lisp->toXML();
<?php
class lispReader
{
 var $_content;
 var $content="";
 var $children = array();
 /**
 ** Author: Jariah Holsapple
 **  return void
 **  input string content
 **  parse string into data structure
 **/
 function __construct($content)
 { 
  $this->_content = $content;
  $isQuote = false;
     for($i=0; $i<strlen($this->_content); $i++)
     {
      $curchar = $this->_content[0];
   $this->_content = substr($this->_content, 1);

            if($curchar == '(' && !$isQuote):
    $child = new lispReader($this->_content);
                $this->children[] = $child;
    $this->_content = $child->_content;
   elseif($curchar ==  ')' && !$isQuote):
                return $this;
   else:
    if($curchar ==  "\""):
     $isQuote=$isQuote?false:true;
    endif;
                $this->content.=$curchar;
   endif;
     }
 }
 /**
 ** Author: Jariah Holsapple
 **  return string xml
 **  input lispReader node, int level
 **/
 function toXML($node=null, $level=0)
 {
  //check to see if the node is null, if it is then this is the base call
  if($node==null)
  {
   $node=$this;
  }
  $result="";
  //first lets get nodes with content <name>value</name>
  if(isset($node->content) && !(isset($node->children) && count($node->children)>1)):
   $parts = preg_split("/[\s\r\n]+/", trim($node->content),2);
   $parts[0] = isset($parts[0])? trim($parts[0]): "root";
   $result.= $this->addTabs($level)."<".$parts[0].">";
   if(isset($parts[1]))
    $result.= str_replace("\"","", trim($parts[1]));
   $result.= "</".$parts[0].">\n";
  //first print the open <node>
  elseif(isset($node->content)):
   $content = trim($node->content);
   $content = $content!=""? $content: "root";
   $result.= $this->addTabs($level)."<".trim($content).">\n";
  endif;
  //lets get the contents from the children, It will be passed back from a recursive call
  if(isset($node->children)):
   foreach($node->children as $child)
   {
    $result.=$this->toXML($child, $level+1);
   }
  endif;
   // then print the close </node>
  if(isset($node->content) && (isset($node->children) && count($node->children)>1)):
   $content = trim($node->content);
   $content = $content!=""? $content: "root";
   $result.= $this->addTabs($level)."</".trim($content).">\n";
  endif;
  return $result;
 }
 /**
 ** Author: Jariah Holsapple
 **  return string number of tabs
 **  input number of tabs
 **/
 function addTabs($level)
 {
  $result="";
  for($i=0; $i<$level; $i++)
   $result.="\t";
  return $result;
 }
}