Rev Author Line No. Line
541 miho 1 <?php
2 // This PHP script generates clickable HTML documentation files for amforth
3 // project. Script should be run once (offline) when new versions of sorces are
543 miho 4 // available. It creates new subdirectory with HTML documentation tree.
541 miho 5 //
545 miho 6 // Default configuration is in file GenerateHTML.cfg
541 miho 7 //
545 miho 8 // Command Line paramaters are available via php GenerateHTML.php --help
9 //
541 miho 10 // (c)miho 2007 / http://www.mlab.cz
11  
12 // **********************************************************************
13 // History
14 // **********************************************************************
15 // 0.00 work wersion
545 miho 16 // 0.01 basic functionality
541 miho 17  
18  
19 // **********************************************************************
20 // Definitions/parameters
21 // **********************************************************************
22  
23  
24 define ('INCLUDE_PATTERN', "/^ *\.include +\"(\S+)\"/i");
25 define ('LABEL_PREFIX', "(VE_|XT_|PFA)");
26 define ('LABEL_PATTERN', "/^ *(".LABEL_PREFIX."\S+):/i");
27 define ('WORD_PATTERN', "/((?:\\n *;.*)*)\\n *VE_Q:[^\\n]*\\n? *.db +[^,]* *, *(\S[^\\n|;]+)/im"); // Q is used instead of Word
28 define ('ASMFILES', "CodeAsm/");
29  
30  
31 // **********************************************************************
32 // Generic Funcions
33 // **********************************************************************
34  
35  
545 miho 36 function Error($ErrorStr)
37 // If ErrorStr is not empty print it and die
38 {
39 if ($ErrorStr=="")
40 return;
41 print "\n";
42 print " ERROR: -->".$ErrorStr."\n";
43 die(1);
44 }
45  
46  
541 miho 47 function MyReadFile($FileName, &$FileContent)
48 // Reads file, returns file as a single string
49 {
545 miho 50 //
51 if ($FileName=="")
52 return "No File Name";
53  
541 miho 54 // Read file
55 $FileContent=@file($FileName);
56  
57 // Test if file contains any content
58 if ($FileContent==FALSE)
545 miho 59 return "No Data in File: $FileName";
541 miho 60  
61 // Remove CR or LF or CR/LF
62 foreach($FileContent as $Key => $Line)
63 {
64 $FileContent[$Key]=rtrim($Line);
65 }
66  
67 // No error
68 return "";
69 }
70  
71  
72 function MyReadFileString($FileName, &$FileContent)
73 // Reads file and returns its content as a single string
74 {
75 // No Error
76 $Error="";
77  
78 // Read file
79 $Error=MyReadFile($FileName, &$FileContent);
80  
81 // Convert to a single string
82 if ($Error=="") $FileContent=implode("\n",$FileContent);
83  
84 // Finished
85 return $Error;
86 }
87  
88  
89 function MyWriteFile($FileName, $FileContent)
90 // Creates and writes file
91 {
92 // Create Output File
93 $File=@fopen($FileName,"w");
94 if ($File==FALSE)
95 {
96 return "Unable Write File ".$FileName;
97 }
98  
99 // Write content
100 fwrite($File,$FileContent);
101 fclose($File);
102  
103 // No Error
104 return "";
105 }
106  
107  
108 function FileName2HTML($FileName)
109 // Converts FileName to FileName of HTML file
110 {
111 // Remove path
112 $FileName=basename($FileName);
113 // Change suffix
114 $FileName=preg_replace("/\.asm$/i",".html",$FileName);
115 // Finished
116 #print $FileName;
117 return $FileName;
118 }
119  
120  
121 function Label2Link($Link, $href, $title, &$LabelList)
122 // Converts Label to Link
123 // If label not found returns original text
124 // IN $Link - label to find
125 // IN $Word - word to show (on mouse)
126 // IN $LabelList - list of all labels (Label, FileName, LineNumber)
127 {
128 // Find label in $LabelList
129 foreach($LabelList as $Value)
130 {
131 if ($Link===$Value["Label"])
132 {
133 #$LabelListItem=$Value /////////////////////////////
134 print "Found ".$Value["Label"]."\n";
135 }
136 }
137  
138 $FileName=$Value["FileName"]."#".$Link;
139  
140 // Create link
141 $Link="<a href=\"".$FileName."\" title=\" ".$Word."\">".$Link.'</a>';
142  
143 return $Link;
144 }
145  
146  
147 // **********************************************************************
148 // Function for processing
149 // **********************************************************************
150  
151  
545 miho 152 function Help()
153 // Display help
154 {
155 print "\n";
156 print "This script takes default parameters from GenerateHTML.cfg.\n";
157 print "\n";
158 print "Parameters can be entered directly on command line as well:\n";
159 print " php GenerateHTML.php par1=val1 par2=val2\n";
160 print "\n";
161 print "Sometimes (in Windows) it is necessary to use quotation marks this way:\n";
162 print " php GenerateHTML.php \"par1=val1\" \"par2=val2\"\n";
163 print "\n";
164 print "Parameters are: \n";
165 print " EnableApache={0|1} - Enable to run in Apache\n";
166 print " SourceDir=path - path to asm source directory\n";
167 print " SourceAsm=file - name of top level asm source file\n";
546 miho 168 print " SvnInfoFileName - name of Svn Info File\n";
545 miho 169 print " TemplateDir=path - path to HTML template\n";
170 print " DestinationDir=path - path to destination HTML\n";
171 Error("\n");
172 }
173  
174  
175 function Parameters(&$CFG)
176 // Function process Command Line parameters
177 {
178 // Dummy values
179 $CFG["EnableApache"] = 0; // Do not allow run in Apache
180 $CFG["SourceDir"] = "";
181 $CFG["SourceAsm"] = "";
546 miho 182 $CFG["SvnInfoFileName"] = "";
545 miho 183 $CFG["TemplateDir"] = "";
184 $CFG["DestinationDir"] = "";
185 // Default values (in cfg file)
186 @include_once("GenerateHTML.cfg");
187 // Command Line parameters
188 if ($_SERVER["argc"]>1)
189 {
190 // Help
191 if ($_SERVER["argv"][1]=="--help")
192 Help();
193 // Drop
194 unset($_SERVER["argv"][0]);
195 // Go through arguments
196 foreach($_SERVER["argv"] as $Key => $Value)
197 {
198 $Left=substr($Value,0,strpos($Value,"="));
199 $Right=substr($Value,strpos($Value,"=")+1);
200 if (isset($CFG[$Left]) && $Right!="" )
201 {
202 $CFG[$Left]=$Right;
203 }
204 else
205 {
206 return "Invalid Parameter: $Value";
207 }
208 }
209 }
210  
546 miho 211 // Check if alowed to run in Apache
212 if ($_SERVER["argc"]==0 & ! $CFG["EnableApache"])
213 return "<b>This Script is configured so that it will not run in Apache.</b>";
214  
215 // Info
216 print "Parameters\n";
217  
545 miho 218 // Correct paths and existence
219 foreach($CFG as $Key => $Value)
220 {
221 if (stripos($Key,"Dir"))
222 {
223 // Correct / at the end of path
224 if (substr($Value,strlen($Value)-1)!="/")
225 {
226 $CFG[$Key]=$Value."/";
227 }
228 // Check existence
229 #print "DIR".$CFG[$Key]."\n";
230 if ( ! is_dir($CFG[$Key]))
231 {
232 return "Directory does not exist: ".$Key."=".$CFG[$Key];
233 }
234 }
235 }
236  
237 // Print info
238 if (count(CFG))
239 foreach($CFG as $Key => $Value)
240 print " $Key=$Value\n";
241 print "\n";
242  
243 // No Error
244 return "";
245 }
246  
247  
541 miho 248 function SourceAsm($SourceDir, $FileName, &$SourceAsmFiles, &$LabelList )
249 // Process ASM source file, recurse all includes
545 miho 250 // Returns Error String
541 miho 251 // Stores file names and labels into two arrays
252 // IN $SourceDir - base directory (not printed)
253 // IN $FileName - file to process
254 // OUT $SourceAsmFiles - list of all processed files (Filename)
255 // OUT $LabelList - list of all labels (Label, FileName, LineNumber)
256 {
257  
258 // Start
259 print "Read Asm: $FileName\n";
260  
261 // Read file
262 $Error=MyReadFile($SourceDir.$FileName, $FileContent);
263 if ($Error!="")
545 miho 264 return $Error;
265  
541 miho 266 // Remember filename
267 $SourceAsmFiles[]=$FileName;
268  
269 // Filter source file line by line - find labels
270 foreach($FileContent as $Key => $Value)
271 {
272 // Find label definitions
273 if (preg_match(LABEL_PATTERN,$Value,$Matches))
274 {
275 print " label @line ".($Key+1)." ".$Matches[1]."\n";
276 $LabelList[]=array("Label"=>$Matches[1],"FileName"=>$FileName,"LineNumber"=>($Key+1));
277 }
278 }
279  
280 // Filter source file line by line - find includes
281 foreach($FileContent as $Key => $Value)
282 {
283 // Find .include "filename" lines
284 if (preg_match(INCLUDE_PATTERN,$Value,$Matches))
285 {
286 print " include @line ".($Key+1)." --> ".$Matches[1]."\n";
287 // Remember links
288 $Includes[]=$Matches[1];
289 }
290 }
291  
292 // Print delimiter
293 print "\n";
294  
295 // Recurse includes
296 if ($Includes)
297 {
298 foreach($Includes as $Value)
299 {
300 $Dir=dirname($FileName)."/";
301 if ($Dir=="./")
302 {
303 $Dir="";
304 }
545 miho 305 $Error=SourceAsm($SourceDir, $Dir.$Value, $SourceAsmFiles, $LabelList);
306 if ($Error!="")
307 return $Error;
541 miho 308 }
309 unset($Includes);
310 }
311  
312 // End
545 miho 313 return "";
541 miho 314 }
315  
316  
317 function PrintSourceAsm(&$SourceAsmFiles)
318 // Prints all procesed ASM files
319 {
320 print "Asm Source File List\n";
545 miho 321 if (count($SourceAsmFiles))
541 miho 322 foreach($SourceAsmFiles as $Key => $Value)
323 {
324 print " ".$Value."\n";
325 }
326 print "\n";
327 }
328  
329  
330 function PrintLabels(&$LabelList)
331 // Prints all found labels
332 {
333 print "Label List\n";
545 miho 334 if (count($LabelList))
541 miho 335 foreach($LabelList as $Key => $Value)
336 {
337 print " ".$Value["Label"]." ".$Value["FileName"]." ".$Value["LineNumber"]."\n";
338 }
339 print "\n";
340 }
341  
342  
343 function CreateWordList($SourceDir, &$LabelList, &$WordList)
344 // Goes through LabelList and looks for word definitions
545 miho 345 // Returns Error String
541 miho 346 // IN $LabelList - Found labels
347 // OUT $WordList - Word List (ShortLabel, Word, Comment, Label, FileName)
348 {
349  
350 print "Word List\n";
351  
545 miho 352 if (count($LabelList))
541 miho 353 foreach ($LabelList as $Value)
354 {
355 // Take all VE definitions
356 if (stristr(substr($Value["Label"],0,3),"VE_"))
357 {
358 // Prepare Label without VE_
359 $ShortLabel=substr($Value["Label"],3);
360  
361 // Prepare search pattern
362 $Pattern=str_replace("Q",$ShortLabel,WORD_PATTERN);
363 #print "Pattern: ".$Pattern." ".$Value["FileName"]."\n";
364  
365 // Read source file
366 $FileName=$SourceDir.$Value["FileName"];
543 miho 367 $Error=MyReadFileString($FileName, $FileContent);
541 miho 368 if ($Error!="")
545 miho 369 return $Error;
541 miho 370 $FileContent="\n".$FileContent;
371  
372 // Find label
373 if (preg_match($Pattern,$FileContent,$Matches))
374 {
375 // Coments - remove semiculomn
376 $Comment = rtrim(preg_replace("/\\n; ?(.*)/","$1\n",$Matches[1]));
377  
378 // Convert .db parameters into string
379 $Word="";
380 #$Word=$Matches[2]." : ";
381  
382 foreach(explode(",",$Matches[2]) as $Val)
383 {
384 // String element
385 preg_match("/^ *\"([^\"]*)(\" *)/",$Val,$Tmp);
386 #print "S:".$Tmp[1]."\n";
387 if ($Tmp[1]!="")
388 {
389 $Word.=$Tmp[1];
390 }
391  
392 // Hexa number
393 preg_match("/\\$([0-9A-F]+)/i",$Val,$Tmp);
394 #print "H:".$Tmp[1]."\n";
395 if ($Tmp[1]!="")
396 {
397 $Number=hexdec($Tmp[1]);
398 if ($Number!=0)
399 $Word.=chr($Number);
400 }
401  
402 // Decimal number
403 preg_match("/^([0-9]+)/i",$Val,$Tmp);
404 #print "D:".$Tmp[1]."\n";
405 if ($Tmp[1]!="")
406 {
407 $Number=$Tmp[1];
408 if ($Number!=0)
409 $Word.=chr($Number);
410 }
411  
412 }
413  
414 // Store label into array
415 $WordList[]=array("Word"=>$Word, "ShortLabel"=>$ShortLabel, "Comment"=>$Comment,
416 "Label"=>$Value["Label"] , "FileName"=>$Value["FileName"]
417 );
418 print " ".$Word." = ".$ShortLabel."\n";
419 if($Comment) print " ".preg_replace("/\\n/","\n ",$Comment)."\n";
420 }
421  
422 // Sort Words
423 array_multisort($WordList);
424  
425 // Clean Up
426 unset($FileContent);
427 }
428 }
429 print "\n";
545 miho 430 return "";
541 miho 431 }
432  
433  
546 miho 434 function GenerateWordList($TemplateDir, $SvnInfoFileName, $DestinationDir, &$LabelList, &$WordList)
541 miho 435 // Creates HTML pages with Word List
545 miho 436 // Returns Error String
541 miho 437 // IN $TemplateDir - template directory (file WordList.*.html)
438 // IN $LabelList - list of labels (Label, FileName, LineNumber)
439 // IN $WordList - list of words (ShortLabel, Word, Comment, Label, FileName)
440 // OUT WordList.*.html - create HTML pages (file WordList.*.html)
441 {
442 // Find all templates
443 print "Word List in HTML\n";
545 miho 444 if (count(glob($TemplateDir."WordList.*.html")))
541 miho 445 foreach (glob($TemplateDir."WordList.*.html") as $FileName)
446 {
447 // Process template file
448 print " Temlate $FileName\n";
449  
450 // Read template file
451 $Error=MyReadFileString($FileName, $FileContent);
452 if ($Error!="")
545 miho 453 return $Error;
541 miho 454  
546 miho 455 // Find <<SvnInfo>>
456 if (!preg_match("/( *)(<<SvnInfo>>)/i",$FileContent,$Matches))
457 {
458 unset($FileContent);
459 return "Missing <<SvnInfo>> in template file";
460 }
461 $Indent=$Matches[1];
462  
463 // Read Svn Info file
464 $Error=MyReadFileString($SvnInfoFileName, $SvnInfoFile);
465 if ($Error!="")
466 {
467 // We do not have Svn Info File
468 $SvnInfoFile="";
469 }
470 else
471 {
472 // We have Svn Info File
473 $SvnInfoFile=preg_replace("/^((?:URL|Repository|Last)[^:]*):(.*$)|^.*$/im","<tr><td>$1</td><td>$2</td></tr>",$SvnInfoFile);
474 $SvnInfoFile=preg_replace("~<tr><td></td><td></td></tr>\n~i","",$SvnInfoFile);
475 $SvnInfoFile="<tr><th colspan=\"2\">Subversion Info</th></tr>".$SvnInfoFile;
476 }
477  
478 // Put Svn Info into HTML template
479 $FileContent=str_ireplace("<<SvnInfo>>", $SvnInfoFile, $FileContent);
480 #print $FileContent;
481  
482  
541 miho 483 // Find <<WordList>>
484 if (!preg_match("/( *)(<<WordList>>)/i",$FileContent,$Matches))
485 {
486 unset($FileContent);
545 miho 487 return "Missing <<WordList>> in template file";
541 miho 488 }
489 $Indent=$Matches[1];
490  
491 // Create HTML code - table header
492 $WordListHTML[]="<table>";
493 $WordListHTML[]=" <tr>";
494 $WordListHTML[]=" <th>Word</th>";
495 $WordListHTML[]=" <th>Label</th>";
496 $WordListHTML[]=" <th>Definition</th>";
543 miho 497 $WordListHTML[]=" </tr>";
541 miho 498  
499 // Create HTML code - table lines
545 miho 500 if (count($WordList))
541 miho 501 foreach($WordList as $Key => $Value)
502 {
503 // Prepare (just for readibility)
504 $Word=$Value["Word"];
505 $Link="<a href=\"".ASMFILES.FileName2HTML($Value["FileName"])."#".$Value["ShortLabel"].
506 "\" title=\"".$Value["Label"]."\">".$Value["ShortLabel"]."</a>";
507 $Comment=$Value["Comment"];
508 // Generate HTML
509 $WordListHTML[]=" <tr>";
510 $WordListHTML[]=" <td>".htmlspecialchars($Word)."</td>";
511 $WordListHTML[]=" <td>".$Link."</td>";
512 $WordListHTML[]=" <td>".htmlspecialchars($Comment)."</td>";
513 $WordListHTML[]=" </tr>";
514 }
515 // Create HTML code - table end
516 $WordListHTML[]="</table>";
517  
518 // Indent and Concatenate lines
519 foreach($WordListHTML as $Key => $Value)
520 {
546 miho 521 if ($Key>0)
522 $WordListHTML[$Key]=$Indent.preg_replace("/\n/","<br>",$Value);
541 miho 523 }
524 $WordListHTML=implode("\n",$WordListHTML);
525  
526 // Put it into HTML template
527 $FileContent=str_ireplace("<<WordList>>", $WordListHTML, $FileContent);
528 #print $FileContent;
529  
530 // Create Output File
531 $Error=MyWriteFile($DestinationDir.basename($FileName), $FileContent);
532 if ($Error!="")
545 miho 533 return $Error;
541 miho 534  
535 // Clear memory
536 unset($FileContent);
537 unset($WordListHTML);
538 }
539  
540 // Delimiter
541 print "\n";
545 miho 542 return "";
541 miho 543 }
544  
545  
546 function GenerateAsmFiles($TemplateDir, $SourceDir, &$SourceAsmFiles, $DestinationDir)
547 // Cretaes HTML files from all processed ASM files
545 miho 548 // Returns Error String
549 // IN $TemplateDir - directory with template files
550 // IN $SourceDir - directory with asm source files
551 // OUT $SourceAsmFiles -
552 // IN $DestinationDir - directory for generated HTML files
541 miho 553 {
554 // Info
555 print "Copy ASM Files\n";
556  
557 // Destination directory exists
558 $DestinationDir.=ASMFILES;
559 if (!is_dir($DestinationDir))
560 if (!@mkdir($DestinationDir))
545 miho 561 return "Unable Create Dir ".$DestinationDir;
562  
541 miho 563 // Read template
564 $Error=MyReadFileString($TemplateDir."FileAsm.en.html", $Template);
565 if ($Error!="")
545 miho 566 return $Error;
541 miho 567  
568 // Copy all source files
569 foreach($SourceAsmFiles as $Key => $FileName)
570 {
571 print " ".$FileName."\n";
572  
573 // Read ASM file
574 $Error=MyReadFileString($SourceDir.$FileName, $FileContent);
575 if ($Error!="")
545 miho 576 return $Error;
541 miho 577  
578 // Prepare HTML
579 $FileContent=htmlspecialchars($FileContent);
580 $FileContent="<pre>\n".$FileContent."\n</pre>";
581  
582 // Use Template
583 $TemplateWork=$Template;
584 $TemplateWork=str_ireplace("<<FileName>>", $FileName, $TemplateWork);
585 $TemplateWork=str_ireplace("<<FileContent>>", $FileContent, $TemplateWork);
586  
587 // Write ASM file in HTML
588 $Error=MyWriteFile($DestinationDir.FileName2HTML($FileName), $TemplateWork);
589 if ($Error!="")
545 miho 590 return $Error;
541 miho 591 }
592  
593 // Delimiter
594 print "\n";
545 miho 595 return "";
541 miho 596 }
597  
598  
599 // **********************************************************************
600 // Main Block
601 // **********************************************************************
602  
545 miho 603 // Global Like Variables (arrays)
604 // $CFG - Config parameters
605 // $SourceAsmFiles - All processed ASM files (filenames)
606 // $LabelList - All label definitions (Label, FileName, LineNumber)
607 // $WordList - Word List (ShortLabel, Word, Comment, Label, FileName)
541 miho 608  
545 miho 609 // Process Command Line Parameters
610 Error(Parameters($CFG));
541 miho 611  
612 // Process all ASM files from the root level
545 miho 613 Error(SourceAsm($CFG["SourceDir"], $CFG["SourceAsm"], $SourceAsmFiles, $LabelList));
541 miho 614 PrintSourceAsm($SourceAsmFiles);
615 PrintLabels($LabelList);
616  
617 // Destilate Labels and Words
545 miho 618 Error(CreateWordList($CFG["SourceDir"], $LabelList, $WordList));
541 miho 619  
620 // Create HTML WordList
546 miho 621 Error(GenerateWordList(
622 $CFG["TemplateDir"],
623 $CFG["SourceDir"].$CFG["SvnInfoFileName"],
624 $CFG["DestinationDir"],
625 $LabelList, $WordList));
541 miho 626  
627 // Copy ASM files and convert them into HTML
545 miho 628 Error(GenerateAsmFiles($CFG["TemplateDir"], $CFG["SourceDir"], $SourceAsmFiles, $CFG["DestinationDir"]));
541 miho 629  
545 miho 630 // Finish
631 print "O.K.\n";
632 return
541 miho 633  
546 miho 634 // Zpracování readme autora
635 // Vyplatilo by se udělat samostatny formatovaci a nahrazovaci mechanizmus
541 miho 636 // Zpracování templejtů do samostatného podprogramu (vyřešit indent...)
637 // tím se vyřeší i en/cs verze Asm souboru
638 // Generovat log do souboru místo printu (zvážit) oddělit chyby a varování
639 // Vyčistit cílový adresář
640 // Process all FORTH files
641 // Problém s rekurzí (potenciální nekonečno)
543 miho 642 // Chtělo by to do stránek vkládat info o verzi a (c)
541 miho 643 ?>