<?php
/**
 * Internal formatting to create HTML from a shorthand-style scheme.
 * Idea taken from Juerd's MetaMarkup. See http://juerd.nl.
 * @author Matt Sparks
 * @version 20050602-0400
 */
class Format {
    var 
$blockLevel;
    var 
$usePTags;
    
    function 
Format() {
        
// Define the block-level elements
        // http://www.htmlhelp.com/reference/html40/block.html
        
$this->blockLevel=array("h1","h2","h3","h4","h5","h6",
                          
"p","pre","blockquote","address",
                          
"ul","ol","dir","menu","li","dl","dt","dd",
                          
"div","center","form","hr","table");
    }
    
    function 
makeAcronym($acronym,$text) {
        return 
"<acronym title=\"$text\">$acronym</acronym>";
    }
    
    function 
makeLink($url) {
        if (
ereg("^[a-z]{3,4}:\/\/",$url) || ereg("^mailto:",$url)) return $this->makeELink($url);
        else return 
$this->makeILink($url);
    }
    
    function 
makeELink($url,$target="_blank") {
        
$url=preg_replace("/&^([0-9a-z#]+?;)/i","&amp;",$url);
        list(
$url,$name)=split("\|",$url);
        if (!
$name$name=$url;
        
//$b64=base64_encode($url);
        //return "<a href=\"/core/out/url=$b64\" title=\"External link: $url\" target=\"_blank\">$name</a>";
        
return "<a href=\"$url\" title=\"External link: $url\" target=\"$target\">$name</a>";
    }
    
    function 
makeILink($url) {
        
$url=preg_replace("/&^([0-9a-z#]+?;)/i","&amp;",$url);
        list(
$url,$name)=split("\|",$url);
        if (!
$name$name=$url;
        if (!
ereg("^[/#]",$url)) $url="/core/$url";
        return 
"<a href=\"$url\" title=\"Internal link: $url\">$name</a>";
    }
    
    function 
tagPhrase($phrase) {
        while (
preg_match("/\{([a-z0-9 \"=]+):(.+)\}/ism",$phrase,$matches)) {
            list(
$match,$tag,$text)=$matches;
            
// find embedded tags
            
$text=$this->tagPhrase($text);
            
// check for other tags caught in the greediness
            
if ($braceloc=strpos($text,"}")) {
                
$text=substr($text,0,$braceloc);
                
$match='{'.$tag.":".$text.'}';
            }
            
//echo "<!-- replacing '$match' with '<$tag>$text</$tag>'  in '$phrase' -->\n";
            
$split=split(" ",$tag); $firstword=$split[0];
            if (
in_array($firstword,$this->blockLevel)) $this->usePTags false;
            
$phrase=str_replace($match,"<$tag>$text</$firstword>",$phrase);
        }
        return 
$phrase;
    }    
    
    function 
formatParagraph($paragraph) {
        
$this->usePTags=true;
        
$paragraph=trim($paragraph);
        
        
// #
        // if paragraph begins with "#", ignore it, much like a comment
        // this paragraph will not be output at all
        
if (ereg("^#",$paragraph)) {
            return;
        }
        
        
// %
        // don't format if paragraph begins with %
        
if (ereg("^%",$paragraph)) {
            return 
substr($paragraph,1)."\n\n";
        }
        
        
// !
        // if paragraph begins with !, turn off the automatic <p> tagging
        // as of 20050601, this shouldn't be needed for block level elements;
        // block level elements occurring anywhere in a paragraph will
        // automatically turn the <p> tagging off for that paragraph.
        
if (ereg("^!",$paragraph)) {
            
$this->usePTags=false;
            
$paragraph=substr($paragraph,1);
        }

        
// temporarily replace { } [ ] so the parsers won't get confused
        
$paragraph=str_replace("\[","%LEFT_BRACKET%",$paragraph);
        
$paragraph=str_replace("\]","%RIGHT_BRACKET%",$paragraph);
        
$paragraph=str_replace("\{","%LEFT_BRACE%",$paragraph);
        
$paragraph=str_replace("\}","%RIGHT_BRACE%",$paragraph);
        
        
// tagged phrases
        // ex: {b:this text will be made bold}
        
$paragraph=$this->tagPhrase($paragraph);
        
        
// external links
        // ex: [http://google.com]
        
while (preg_match("/\[([a-z]{3,4}:\/\/.+?)\]/ism",$paragraph,$matches)) {
            list(
$match,$url)=$matches;
            
$paragraph=str_replace($match,$this->makeELink($url),$paragraph);
        }
        
        
// internal links
        
while (preg_match("/\[(.+?)\]/ism",$paragraph,$matches)) {
            list(
$match,$url)=$matches;
            if (
ereg("^mailto:",$url))
                
$paragraph=str_replace($match,$this->makeELink($url,"_top"),$paragraph);
            else
                
$paragraph=str_replace($match,$this->makeILink($url),$paragraph);
        }
        
        
// return braces and brackets to normal
        
$paragraph=str_replace("%LEFT_BRACKET%","[",$paragraph);
        
$paragraph=str_replace("%RIGHT_BRACKET%","]",$paragraph);
        
$paragraph=str_replace("%LEFT_BRACE%","{",$paragraph);
        
$paragraph=str_replace("%RIGHT_BRACE%","}",$paragraph);
        
        return (
$this->usePTags) ? "<p>\n$paragraph\n</p>\n\n" "$paragraph\n\n";
    }
    
    function 
parse($content) {
        
$output="";
        
$parts=split("\n\n",trim($content));
        foreach(
$parts as $paragraph) {
            
$output.=$this->formatParagraph($paragraph);
        }
        return 
$output;
    }
}
?>