Location: PHPKode > scripts > Jargon File Processor > jargon-file-processor/jarg.php
<?

/*
 *  Program to search/display word(s) from the Jargon File (v 1.2.0)
 *  still doesn't make coffee...
 *
 *  Copyleft (c+) 2001 tobozo <hide@address.com>
 *
 *  You may copy and use this program freely as long as this
 *  notice is left intact. This program is provided "AS IS"
 *  without warranty of any kind. The copyright owner may not
 *  be held liable for any damages, direct or consequential,
 *  which may result from the the use of this program.
 */



class jargon {


  var $VER       = "1.2.0";       // version of this script
  var $JARG_FILE = "jarg430.txt"; // jargon file (you know where to get it eh?)
  var $JARG_IDX  = "jarg430.idx"; // the index file (must be chmod 777 when building)
  var $lock      = "no";          // set this to "yes" when index is rebuilt
  var $showrand  = true;          // show random word in search Form
  var $showindex = true;          // show list if letters in search Form
  var $showlinks = true;          // show internal hyperlinks for {definitions}

  var $self      = "";
  var $rebuild   = false;
  var $index     = false;
  var $jargon    = false;
  var $footer    = "";
  var $output    = "";
  var $result    = array();
  var $op        = "";
  var $l         = "";
  var $strict    = "exact";
  var $definition= "";
  var $word      = array("Keyword"=>"", // the keyword itself
                         "Def"    =>"", // the full text definition
                         "Html"   =>"", // the full html definition
                         "Links"  =>array("") // the embedded {keywords}
                         );

  /*
      $word["$keyword"] = array (
                            ["keyword"] = the keyword itself
                            ["def"]     = full definition (including :keyword: )
                            ["html"]    = full definition + html links ( including :keyword: )
                            ["links"]   = array(
                                          {keyword1},
                                          {keyword2},
                                          {keyword3} )

   */



  function jargon() {
    /* main function */

    // Logical assignments
    global $PHP_SELF, $l, $op, $strict;

    // name of this document
    if($this->self=="") {
      $this->self=end(explode("/", $PHP_SELF));
      }

    // clean keyword
    if($op) {
      $op=ltrim(chop(stripslashes($op)));
      $this->op=$op;
      }

    // clean letter
    if($l) {
      $l=substr(ltrim(chop(strtolower($l))), 0, 1);
      $this->l=$l;
      }

    // search method
    if(!$strict || $strict=="no") {
      $this->strict="no";
      }

    // file checking for Jargon file
    if(!file_exists($this->JARG_FILE)) {
      $this->output.="  File $this->JARG_FILE does not exist...\n\n".
                     "  Try to edit the file '$this->self' (this file) and\n".
                     "  modify the  value of '\$this->JARG_FILE' to match\n".
                     "  the filename of your Jargon File.\n\n".
                     "  Aborting ...\n\n<br>";
      echo $this->output;
      exit;
      }

    // file checking for Index file
    if(!file_exists($this->JARG_IDX) && ($this->op!="RebuildIndex")) {
      $this->output.="  Index File $this->JARG_IDX does not exist...\n\n".
                     "  Try to create a file to store the index and\n".
                     "  modify the  value of '\$this->JARG_IDX' to match\n".
                     "  the name of the created file.\n\n".
                     "  Also you may try to edit this script and set the \n".
                     "  value of \$lock to 'true', then <a href='$this->self?op=RebuildIndex'>Rebuild the index</a> \n\n".
                     "  Aborting ...\n\n<br>";
      echo $this->output;
      exit;
      }

    // footer and link to search page
    if($this->showlinks) { // insert html links
      $this->footer = "\n\n<a href='$this->self' title=\"Retour a la page de recherche\">Search</a>";
      }

    // $this->callMethod($op, $mode, $letter);

    // if $op has only one letter, display index list for that letter
    if (strlen($this->op)==1 && !$this->IsInTheIndex($this->op)) {
      $this->l=strtolower($this->op);
      $this->op="List";
      return;
      }

    // $op = "List" are we listing keywords for a specific letter ?
    if(($this->op=="List") && ($this->l!="")) {
      return;
      }

    // $op = rebuild index ?
    if(($this->op=="RebuildIndex") && ($this->lock=="no")) {
      $this->rebuild=true;
      }
    else {
      $this->index=$this->getIndex();
      }
    return;
    }




  function extractWord() {
    /* this function extracts one or several words from the array $this->jargon  */
    // load the jargon file

    $op=$this->op;
    $strict=$this->strict;

    if($op=="") {
      return false;
      }

    $ary = $this->getJargon();

    while ( ($bfr=next($ary)) && !ereg("The Jargon Lexicon",$bfr) ); // passer l'intro

    while ( ($bfr=next($ary)) /*&& !ereg("(Lexicon Entries End Here)",$bfr)*/ ) {

      if(substr($bfr,0, 1)==":") { // debut de la definition d'un mot

        $match = no;
        $i=1;
        $keyword="";
        $links=0;

        while(substr($bfr, $i, 1)!=":" && $i<=strlen($bfr)) { // recuperation du mot
          $keyword.= substr($bfr, $i, 1);
          $i++;
          } // fin de la definition d'un mot ou fin de la ligne (peu probable)

        // build words array
        $this->word[strtolower($keyword)][Keyword] = $keyword;

        if($this->rebuild && ($keyword!="(Lexicon Entries End Here)")) {
          // only terms are stored in the index when rebuilt
          $this->index.=addslashes($keyword)."\n";
          }
        elseif( ( $strict=="exact"
                  && strtolower($op)==strtolower($keyword)
                ) // exact search match - lowercase (case insensitive) for both
                  || ( $strict!="exact"
                       && ( ereg(strtolower($op),strtolower($keyword))
                            || ereg($op, $keyword)
                          ) // no strict search, use ereg match - lowercase for both
                     )
              ) { // definition matches searched keyword, activate index bolean
          $this->result[$rs++]=strtolower($keyword);
          $match = "yes"; // inside the definition itself AND match keyword
          }
        /*
        else {
          // we're inside non-matching data (keyword line)
          // located after the header of the keyword.. eg :
          // :keyword: \n.\ non matching data
          }*/
        }
      /*
      else {
        // we're inside non matching data (definition lines)
        // located after the first line of the keyword
        }*/

      // build words array
      $this->word[strtolower($keyword)][Def] .=$bfr;


      if($match=="yes") { // buffer is on the searched data, start processing definition data

        if($this->showlinks) { // insert html links
          $bfr=str_replace(":$keyword:",
                           ":<A href='$this->self?op=$keyword&strict=no' title='Termes similaires'>$keyword</a>:",
                           $bfr);
          }
        // get buffer length (variable)
        $txtlen = strlen($bfr);

        $mylogicalpointer=0;
        $def = "";

        // process all data in the buffer (80 chars max)
        while( ($mylogicalpointer<=strlen($bfr))) {
          // found a link to another keyword ?
          if((substr($bfr, $mylogicalpointer, 1)=="{") || $inword=="yes") {
            // we're inside a linked keyword...
            // it might be wrapped in the text... let's check if we're
            // not already inside one that started on the previous line
            if($inword!="yes") { // start of a new keyword, set the start pointers
              $subword = "";
              if($this->showlinks) { // insert html links
                // build words array
                $this->word[strtolower($keyword)][Html] .= "{<a href=\"$this->self?op=";
                $def.="{<a href=\"$this->self?op=";
                $sim.=" <a href=\"$this->self?op=";
                }
              else { // restore the bracket at the beginning of the keyword
                $def.="{"; // (this can be improved)
                }
              $inword="yes"; // set pointer (we're inside a {linked keyword} )
              $mylogicalpointer++;
              }

            // get the content of the {keyword} (this can be improved)
            while( ($mylogicalpointer<=strlen($bfr)) && (substr($bfr, $mylogicalpointer, 1)!="}") ) {
              $subword.= substr($bfr, $mylogicalpointer, 1);
              $mylogicalpointer++;
              }

            if($mylogicalpointer<strlen($bfr)) {
              $subword=str_replace("{", "", $subword); // this can be improved
              $sublink=$subword;

              // build the links

              if($this->showlinks) { // insert html links

                // remove double spaces
                while(ereg("  ", $sublink)) {
                  $sublink=str_replace("  ", " ", $sublink);
                  }

                // remove <CR> and <LF>
                $sublink=str_replace("\r\n", "", $sublink);

                $def.=urlencode($sublink); // insert keyword inside url
                $this->word[strtolower($keyword)][Html] .= urlencode($sublink);
                $sim.=urlencode($sublink); // insert keyword inside url

                // complete html link for "more like this"
                $sim.="&strict=no";
                $sim.="\" title=\"Recherche sur un terme similaire\">";
                $sim.="<font size=-1><u><sup>[?]</sup></u></a></font>";

                // complete html link for "exact word"
                $def.="&strict=exact";
                $def.="\" title=\"Recherche sur le terme Exact\">";
                $def.=$subword;
                $def.="</a>$sim";
                // build words array
                $this->word[strtolower($keyword)][Html] .= "&strict=exact".
                                               "\" title=\"Recherche sur le terme Exact\">".
                                               $subword.
                                               "</a>$sim";
                }
              else {
                // just print the word
                $def.=$sublink;
                }

              // build words array
              $this->word[strtolower($keyword)][Links][$links++] =$sublink;
              $sim="";

              $inword="no"; // end of the word, ready to process definition data
              }
            }

          $def.= substr($bfr, $mylogicalpointer, 1);
          // build words array
          $this->word[strtolower($keyword)][Html] .= substr($bfr, $mylogicalpointer, 1);
          $mylogicalpointer++;
          }

        $this->definition.=$def;
        }
      }

    if($this->rebuild) {
      return $this->rebuildIndex();;
      }
    else {
      return $this->definition;
      }
    }




  function getForm() {
    /* just builds the form and the index links */
    $this->output .= "<form action='$this->self' method='get'>".
            "<table border='0' cellspacing='0' cellpadding='0' align='center'><tr>".
            "<Td align='center'><pre>".
            "/----------------------------------------------------------------------------\ \n<br />".
            "| Jargon File outil de recherche $this->VER par hide@address.com      |\n<br />".
            "|              copyleft (c+) 12-oct-2001   <a href='$this->self?op=show_source'>View source</a>                       |\n<br />".
            "\----------------------------------------------------------------------------/ \n\n<br />".
            "</pre></td></tr></table>".
            "<table border='1' cellspacing='1' cellpadding='5' align='center'><tr>".
            "<Td align='center'> Rechercher : <input type='text' name='op' size=5>".
            "<input type='submit' value='go!'> \n<br /> Terme exact :     ".
            "<input type='checkbox' name='strict' CHECKED value='exact'>".
            "</td></tr><tr><Td align=center>";

    /* display list of existing letters in index*/
    if($this->showindex) {
      $this->showLettersFromIndex($this->index);
      }
    $this->output.= "</font></td></tr></table>".
          "</form>";

    /* display random term */
    if($this->showrand) {
      $ary=$this->getIndex();
      $max=count($ary);
      srand((double)microtime()*1000000);
      $r = rand(0,$max);
      $this->output.="<table border='0' cellspacing='0' cellpadding='0' align='center'>".
               "<tr><td><pre><BR>\nIl y a $max Termes dans le jargon\n\nTerme au hasard : \n\n";
      $this->op = $ary[$r];
      $this->strict="exact";
      $this->output.=$this->extractWord();
      $this->output.= "</pre></td></tr></table>";
      }
    return $this->output;
    }



  function getWordsFrom($l) {
    /* list words for a specific letter
       returns false if bad entry or if
       nothing is found
     */
    $l=substr(ltrim(chop($l)), 0, 1);
    if($l=="") {
      return false;
      }
    $ary=$this->getIndex();
    $w=0;
    while($w<=count($ary)) {
      if(strtolower($l)==strtolower(substr($ary[$w],0,1))) {
        $this->output.="<a href=\"$this->self?op=".
                  urlencode($ary[$w]).
                 "&strict=exact\">".
                  htmlentities($ary[$w]).
                  "</a>\n";
        $let++;
        }
      $w++;
      }
    if($let==0) {
      $this->output.="Sorry, None of the words in the file $this->JARG_IDX starts with the character '$l'";
      return false;
      }
    else {
      return $this->output;
      }
    }


  function showLettersFromIndex() {
    /* returns all first letters from words in the index file */
    $ary=$this->getIndex();
    $w=0;
    while($w<=count($ary)) {
      $tmp=strtolower(substr($ary[$w],0,1));
      $link[$tmp]="<a class=letter href=?op=List&l=".urlencode($tmp).">$tmp</a>";
      $w++;
      }
    sort($link);
    while(list($v, $n)=each($link)) {
      $output.=$n;
      }
    $this->output.=$output;
    return $this->output;
    }




  function loadJargon() {
    /* Returns the link to the jargon index file */
    $fp=@fopen($this->JARG_IDX, "r")  or die(
         "Unable to open $this->JARG_IDX file\n".
         "You may try edit this script and \n".
         "set the value of \$lock to 'true', \n".
         "then <a href='$this->self?op=RebuildIndex'>Rebuild the index</a>");
    return $fp;
    }




  function IsInTheIndex($op) {
    // checks in index file for matching string $op
    // returns the string or false if nothing found
    $op=ltrim(chop(strtolower($op)));
    if(!is_array($this->index)) {
      $ary=$this->getIndex();
      }
    else {
      $ary=$this->index;
      }
    while($bfr=next($ary)) {
      $tmp=ltrim(chop($bfr));
      if($op==strtolower($tmp)) {
        return $tmp;
        }
      }
    return false;
    }



  function MatchesSimilarTerms($op) {
    $op=ltrim(chop(strtolower($op)));
    if(!is_array($this->index)) {
      $ary=$this->getIndex();
      }
    else {
      $ary=$this->index;
      }
    while($bfr=next($ary)) {
      $tmp=ltrim(chop($bfr));
      if(ereg($op, strtolower($tmp))) {
        $result[$i++]=$tmp;
        }
      }
    if(!empty($result)) {
      return true;
      }
    return false;
    }


  function getIndex() {
    // reads the index file from filesystem
    // or from $this->index (if exists) and
    // return content into an array
    if(!is_array($this->index)) {
      $fp=$this->loadJargon();
      while(!@feof($fp) && $bfr=@fgets($fp, 255)) {
        $ary[$i]=stripslashes(ltrim(chop($bfr)));
        if($ary[$i]!="") {
          $i++;
          }
        }
      $this->index=$ary;
      }
    return $this->index;
    }



  function rebuildIndex() {
    /* Just rebuilds the index file */
    $q=@fopen($this->JARG_IDX, "w") or die(
         "Unable to create $this->JARG_IDX file\n".
         "You may try to chmod the file as r/w and ".
         "<a href='$this->self?op=RebuildIndex'>try again</a>");
    @fputs($q, $this->index);
    @fclose($q);
    return "Index file rebuilt on file $this->JARG_IDX";
    }


  function getJargon() {
    /* get the content of the jargon and store it into an array of 80 chars width */
    if($this->jargon==false) {
      $fp=@fopen($this->JARG_FILE, "r") or die ("Impossible d'ouvrir le fichier $this->JARG_FILE");
      while(!@feof($fp)) {
        $index[$i++]=@fgets($fp, 80);
        }
      $this->jargon=$index;
      }
    return $this->jargon;
    }



  function out($mode) {
    /* Returns the results or writes to stdout */
    global $PHP_SELF;

    switch ($this->op) {

      case "List":
        if ($this->l!="") {
          $this->getWordsFrom($this->l);
          }
        break;

      case "RebuildIndex":
        $this->output.=$this->extractWord().$this->footer;
        break;

      case "show_source":
        show_source(end(explode("/", $PHP_SELF)));
        exit;
        break;

      default :
        if($this->op!="") {

          // $op = "some term"
          // process this only if not rebuilding the index
          $this->output.="\n  ... Recherche du terme '$this->op' dans le fichier $this->JARG_FILE...\n\n";
          $op=$this->op;

          if(!$this->IsInTheIndex($this->op)) { // empty results?
            $this->output.="\n  ... Désolé aucun terme n'a été trouvé pour la recherche sur '$op'.\n\n";
            if($this->MatchesSimilarTerms($this->op)) {
              if($this->strict=="exact") {
                $this->output.="\n  ... <a href='$this->self?op=$op&strict=no'>Rechercher dans les ".
                               "termes similaires</a>.\n\n";
                $this->op=false;
                }
              else {
                $this->output.="\n ... Recherche automatique dans les termes similaires ..\n\n";
                $this->strict="no";
                }
              }
            }

          $this->extractWord();

          $ar = $this->result;

          if(count($ar)>1) { // multiple results
            // $this->output .="\n\n Found multiple results... displaying \n\n";
            while($a++<count($ar)) {
              $ary= $this->word[$ar[$a]];
              // echo $ary[Keyword];
              if($this->showlinks) $out.=$ary[Html];
              else $out.=$ary[Def];
              if($this->relatedlinks) {
                if(is_array($ary[Links])) {
                  while(list($n, $v) = each ($ary[Links])) $out.= $v."\n<Br>";
                  }
                }
              }
            $this->output.= $out.$this->footer;
            }
          else { // single result
            // $this->output .="\n Found single result... displaying \n\n";
            $ary= $this->word[strtolower($this->op)];
            ?><?
            // echo $ary[Keyword];
            if($this->showlinks) $out.=$ary[Html];
            else $out.=$ary[Def];
            if($this->relatedlinks) {
              if(is_array($ary[Links])) {
                while(list($n, $v) = each ($ary[Links])) $out.= $v."\n<Br>";
                }
              }
            $this->output.=$out.$this->footer;
            }
          }
        else { // $op = "" -> display form
          $this->getForm();
          }
        }

    if($mode=="out") {
      echo $this->output;
      }
    else {
      return $this->output;
      }
    }


  }; // end class



?><html>
<head>
<title>Jargon File Processor ... Copyleft(c+) 2001 hide@address.com</title>
</head>
<style>
A { text-decoration:none; }
A:link { text-decoration:none; }
A:visited { text-decoration:none; }
A:active { text-decoration:none; }
A:hover { font-weight:bold; }

A.letter { text-decoration:none; font-size:12px; }
A.letter:link { text-decoration:none; }
A.letter:visited { text-decoration:none; }
A.letter:active { text-decoration:none; }
A.letter:hover { text-decoration:underline; font-weight:normal; background:black; color:white; }
</style>
<body>
<pre>
<?
$j = new jargon($strict);
$j ->out("out");

?>

</pre>
</body>
</html>
Return current item: Jargon File Processor