<?
/*
* 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>