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";
168 print " TemplateDir=path - path to HTML template\n";
169 print " DestinationDir=path - path to destination HTML\n";
170 Error("\n");
171 }
172  
173  
174 function Parameters(&$CFG)
175 // Function process Command Line parameters
176 {
177 // Info
178 print "Parameters\n";
179 // Dummy values
180 $CFG["EnableApache"] = 0; // Do not allow run in Apache
181 $CFG["SourceDir"] = "";
182 $CFG["SourceAsm"] = "";
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  
211 // Correct paths and existence
212 foreach($CFG as $Key => $Value)
213 {
214 if (stripos($Key,"Dir"))
215 {
216 // Correct / at the end of path
217 if (substr($Value,strlen($Value)-1)!="/")
218 {
219 $CFG[$Key]=$Value."/";
220 }
221 // Check existence
222 #print "DIR".$CFG[$Key]."\n";
223 if ( ! is_dir($CFG[$Key]))
224 {
225 return "Directory does not exist: ".$Key."=".$CFG[$Key];
226 }
227 }
228 }
229  
230 // Print info
231 if (count(CFG))
232 foreach($CFG as $Key => $Value)
233 print " $Key=$Value\n";
234 print "\n";
235  
236 // Check if alowed to run in Apache
237 if ($_SERVER["argc"]==0 & ! $CFG["Apache"])
238 return "This Script is configured so that it will not run in Apache.";
239  
240 // No Error
241 return "";
242 }
243  
244  
541 miho 245 function SourceAsm($SourceDir, $FileName, &$SourceAsmFiles, &$LabelList )
246 // Process ASM source file, recurse all includes
545 miho 247 // Returns Error String
541 miho 248 // Stores file names and labels into two arrays
249 // IN $SourceDir - base directory (not printed)
250 // IN $FileName - file to process
251 // OUT $SourceAsmFiles - list of all processed files (Filename)
252 // OUT $LabelList - list of all labels (Label, FileName, LineNumber)
253 {
254  
255 // Start
256 print "Read Asm: $FileName\n";
257  
258 // Read file
259 $Error=MyReadFile($SourceDir.$FileName, $FileContent);
260 if ($Error!="")
545 miho 261 return $Error;
262  
541 miho 263 // Remember filename
264 $SourceAsmFiles[]=$FileName;
265  
266 // Filter source file line by line - find labels
267 foreach($FileContent as $Key => $Value)
268 {
269 // Find label definitions
270 if (preg_match(LABEL_PATTERN,$Value,$Matches))
271 {
272 print " label @line ".($Key+1)." ".$Matches[1]."\n";
273 $LabelList[]=array("Label"=>$Matches[1],"FileName"=>$FileName,"LineNumber"=>($Key+1));
274 }
275 }
276  
277 // Filter source file line by line - find includes
278 foreach($FileContent as $Key => $Value)
279 {
280 // Find .include "filename" lines
281 if (preg_match(INCLUDE_PATTERN,$Value,$Matches))
282 {
283 print " include @line ".($Key+1)." --> ".$Matches[1]."\n";
284 // Remember links
285 $Includes[]=$Matches[1];
286 }
287 }
288  
289 // Print delimiter
290 print "\n";
291  
292 // Recurse includes
293 if ($Includes)
294 {
295 foreach($Includes as $Value)
296 {
297 $Dir=dirname($FileName)."/";
298 if ($Dir=="./")
299 {
300 $Dir="";
301 }
545 miho 302 $Error=SourceAsm($SourceDir, $Dir.$Value, $SourceAsmFiles, $LabelList);
303 if ($Error!="")
304 return $Error;
541 miho 305 }
306 unset($Includes);
307 }
308  
309 // End
545 miho 310 return "";
541 miho 311 }
312  
313  
314 function PrintSourceAsm(&$SourceAsmFiles)
315 // Prints all procesed ASM files
316 {
317 print "Asm Source File List\n";
545 miho 318 if (count($SourceAsmFiles))
541 miho 319 foreach($SourceAsmFiles as $Key => $Value)
320 {
321 print " ".$Value."\n";
322 }
323 print "\n";
324 }
325  
326  
327 function PrintLabels(&$LabelList)
328 // Prints all found labels
329 {
330 print "Label List\n";
545 miho 331 if (count($LabelList))
541 miho 332 foreach($LabelList as $Key => $Value)
333 {
334 print " ".$Value["Label"]." ".$Value["FileName"]." ".$Value["LineNumber"]."\n";
335 }
336 print "\n";
337 }
338  
339  
340 function CreateWordList($SourceDir, &$LabelList, &$WordList)
341 // Goes through LabelList and looks for word definitions
545 miho 342 // Returns Error String
541 miho 343 // IN $LabelList - Found labels
344 // OUT $WordList - Word List (ShortLabel, Word, Comment, Label, FileName)
345 {
346  
347 print "Word List\n";
348  
545 miho 349 if (count($LabelList))
541 miho 350 foreach ($LabelList as $Value)
351 {
352 // Take all VE definitions
353 if (stristr(substr($Value["Label"],0,3),"VE_"))
354 {
355 // Prepare Label without VE_
356 $ShortLabel=substr($Value["Label"],3);
357  
358 // Prepare search pattern
359 $Pattern=str_replace("Q",$ShortLabel,WORD_PATTERN);
360 #print "Pattern: ".$Pattern." ".$Value["FileName"]."\n";
361  
362 // Read source file
363 $FileName=$SourceDir.$Value["FileName"];
543 miho 364 $Error=MyReadFileString($FileName, $FileContent);
541 miho 365 if ($Error!="")
545 miho 366 return $Error;
541 miho 367 $FileContent="\n".$FileContent;
368  
369 // Find label
370 if (preg_match($Pattern,$FileContent,$Matches))
371 {
372 // Coments - remove semiculomn
373 $Comment = rtrim(preg_replace("/\\n; ?(.*)/","$1\n",$Matches[1]));
374  
375 // Convert .db parameters into string
376 $Word="";
377 #$Word=$Matches[2]." : ";
378  
379 foreach(explode(",",$Matches[2]) as $Val)
380 {
381 // String element
382 preg_match("/^ *\"([^\"]*)(\" *)/",$Val,$Tmp);
383 #print "S:".$Tmp[1]."\n";
384 if ($Tmp[1]!="")
385 {
386 $Word.=$Tmp[1];
387 }
388  
389 // Hexa number
390 preg_match("/\\$([0-9A-F]+)/i",$Val,$Tmp);
391 #print "H:".$Tmp[1]."\n";
392 if ($Tmp[1]!="")
393 {
394 $Number=hexdec($Tmp[1]);
395 if ($Number!=0)
396 $Word.=chr($Number);
397 }
398  
399 // Decimal number
400 preg_match("/^([0-9]+)/i",$Val,$Tmp);
401 #print "D:".$Tmp[1]."\n";
402 if ($Tmp[1]!="")
403 {
404 $Number=$Tmp[1];
405 if ($Number!=0)
406 $Word.=chr($Number);
407 }
408  
409 }
410  
411 // Store label into array
412 $WordList[]=array("Word"=>$Word, "ShortLabel"=>$ShortLabel, "Comment"=>$Comment,
413 "Label"=>$Value["Label"] , "FileName"=>$Value["FileName"]
414 );
415 print " ".$Word." = ".$ShortLabel."\n";
416 if($Comment) print " ".preg_replace("/\\n/","\n ",$Comment)."\n";
417 }
418  
419 // Sort Words
420 array_multisort($WordList);
421  
422 // Clean Up
423 unset($FileContent);
424 }
425 }
426 print "\n";
545 miho 427 return "";
541 miho 428 }
429  
430  
431 function GenerateWordList($TemplateDir, $DestinationDir, &$LabelList, &$WordList)
432 // Creates HTML pages with Word List
545 miho 433 // Returns Error String
541 miho 434 // IN $TemplateDir - template directory (file WordList.*.html)
435 // IN $LabelList - list of labels (Label, FileName, LineNumber)
436 // IN $WordList - list of words (ShortLabel, Word, Comment, Label, FileName)
437 // OUT WordList.*.html - create HTML pages (file WordList.*.html)
438 {
439 // Find all templates
440 print "Word List in HTML\n";
545 miho 441 if (count(glob($TemplateDir."WordList.*.html")))
541 miho 442 foreach (glob($TemplateDir."WordList.*.html") as $FileName)
443 {
444 // Process template file
445 print " Temlate $FileName\n";
446  
447 // Read template file
448 $Error=MyReadFileString($FileName, $FileContent);
449 if ($Error!="")
545 miho 450 return $Error;
541 miho 451  
452 // Find <<WordList>>
453 if (!preg_match("/( *)(<<WordList>>)/i",$FileContent,$Matches))
454 {
455 unset($FileContent);
545 miho 456 return "Missing <<WordList>> in template file";
541 miho 457 }
458 $Indent=$Matches[1];
459  
460 // Create HTML code - table header
461 $WordListHTML[]="<table>";
462 $WordListHTML[]=" <tr>";
463 $WordListHTML[]=" <th>Word</th>";
464 $WordListHTML[]=" <th>Label</th>";
465 $WordListHTML[]=" <th>Definition</th>";
543 miho 466 $WordListHTML[]=" </tr>";
541 miho 467  
468 // Create HTML code - table lines
545 miho 469 if (count($WordList))
541 miho 470 foreach($WordList as $Key => $Value)
471 {
472 // Prepare (just for readibility)
473 $Word=$Value["Word"];
474 $Link="<a href=\"".ASMFILES.FileName2HTML($Value["FileName"])."#".$Value["ShortLabel"].
475 "\" title=\"".$Value["Label"]."\">".$Value["ShortLabel"]."</a>";
476 $Comment=$Value["Comment"];
477 // Generate HTML
478 $WordListHTML[]=" <tr>";
479 $WordListHTML[]=" <td>".htmlspecialchars($Word)."</td>";
480 $WordListHTML[]=" <td>".$Link."</td>";
481 $WordListHTML[]=" <td>".htmlspecialchars($Comment)."</td>";
482 $WordListHTML[]=" </tr>";
483 }
484 // Create HTML code - table end
485 $WordListHTML[]="</table>";
486  
487 // Indent and Concatenate lines
488 foreach($WordListHTML as $Key => $Value)
489 {
490 $WordListHTML[$Key]=$Indent.preg_replace("/\n/","<br>",$Value);
491 }
492 $WordListHTML=implode("\n",$WordListHTML);
493  
494 // Put it into HTML template
495 $FileContent=str_ireplace("<<WordList>>", $WordListHTML, $FileContent);
496 #print $FileContent;
497  
498 // Create Output File
499 $Error=MyWriteFile($DestinationDir.basename($FileName), $FileContent);
500 if ($Error!="")
545 miho 501 return $Error;
541 miho 502  
503 // Clear memory
504 unset($FileContent);
505 unset($WordListHTML);
506 }
507  
508 // Delimiter
509 print "\n";
545 miho 510 return "";
541 miho 511 }
512  
513  
514 function GenerateAsmFiles($TemplateDir, $SourceDir, &$SourceAsmFiles, $DestinationDir)
515 // Cretaes HTML files from all processed ASM files
545 miho 516 // Returns Error String
517 // IN $TemplateDir - directory with template files
518 // IN $SourceDir - directory with asm source files
519 // OUT $SourceAsmFiles -
520 // IN $DestinationDir - directory for generated HTML files
541 miho 521 {
522 // Info
523 print "Copy ASM Files\n";
524  
525 // Destination directory exists
526 $DestinationDir.=ASMFILES;
527 if (!is_dir($DestinationDir))
528 if (!@mkdir($DestinationDir))
545 miho 529 return "Unable Create Dir ".$DestinationDir;
530  
541 miho 531 // Read template
532 $Error=MyReadFileString($TemplateDir."FileAsm.en.html", $Template);
533 if ($Error!="")
545 miho 534 return $Error;
541 miho 535  
536 // Copy all source files
537 foreach($SourceAsmFiles as $Key => $FileName)
538 {
539 print " ".$FileName."\n";
540  
541 // Read ASM file
542 $Error=MyReadFileString($SourceDir.$FileName, $FileContent);
543 if ($Error!="")
545 miho 544 return $Error;
541 miho 545  
546 // Prepare HTML
547 $FileContent=htmlspecialchars($FileContent);
548 $FileContent="<pre>\n".$FileContent."\n</pre>";
549  
550 // Use Template
551 $TemplateWork=$Template;
552 $TemplateWork=str_ireplace("<<FileName>>", $FileName, $TemplateWork);
553 $TemplateWork=str_ireplace("<<FileContent>>", $FileContent, $TemplateWork);
554  
555 // Write ASM file in HTML
556 $Error=MyWriteFile($DestinationDir.FileName2HTML($FileName), $TemplateWork);
557 if ($Error!="")
545 miho 558 return $Error;
541 miho 559 }
560  
561 // Delimiter
562 print "\n";
545 miho 563 return "";
541 miho 564 }
565  
566  
567 // **********************************************************************
568 // Main Block
569 // **********************************************************************
570  
545 miho 571 // Global Like Variables (arrays)
572 // $CFG - Config parameters
573 // $SourceAsmFiles - All processed ASM files (filenames)
574 // $LabelList - All label definitions (Label, FileName, LineNumber)
575 // $WordList - Word List (ShortLabel, Word, Comment, Label, FileName)
541 miho 576  
545 miho 577 // Process Command Line Parameters
578 Error(Parameters($CFG));
541 miho 579  
580 // Process all ASM files from the root level
545 miho 581 Error(SourceAsm($CFG["SourceDir"], $CFG["SourceAsm"], $SourceAsmFiles, $LabelList));
541 miho 582 PrintSourceAsm($SourceAsmFiles);
583 PrintLabels($LabelList);
584  
585 // Destilate Labels and Words
545 miho 586 Error(CreateWordList($CFG["SourceDir"], $LabelList, $WordList));
541 miho 587  
588 // Create HTML WordList
545 miho 589 Error(GenerateWordList($CFG["TemplateDir"], $CFG["DestinationDir"], $LabelList, $WordList));
541 miho 590  
591 // Copy ASM files and convert them into HTML
545 miho 592 Error(GenerateAsmFiles($CFG["TemplateDir"], $CFG["SourceDir"], $SourceAsmFiles, $CFG["DestinationDir"]));
541 miho 593  
545 miho 594 // Finish
595 print "O.K.\n";
596 return
541 miho 597  
598 // Zpracování readme autora + verze
599 // Zpracování templejtů do samostatného podprogramu (vyřešit indent...)
600 // tím se vyřeší i en/cs verze Asm souboru
601 // Generovat log do souboru místo printu (zvážit) oddělit chyby a varování
602 // Vyčistit cílový adresář
603 // Process all FORTH files
604 // Problém s rekurzí (potenciální nekonečno)
543 miho 605 // Chtělo by to do stránek vkládat info o verzi a (c)
541 miho 606 ?>