2 //==============================================================================
3 // Name: JPGENHTMLDOC.PHP
4 // Description: Implements a HTML plugin for the reference framework as
5 // specified in jpclassref.php
7 // Author: johanp@aditus.nu
8 // Version: $Id: jpgenhtmldoc.php,v 1.18 2003/01/30 14:55:57 aditus Exp $
11 // Copyright (C) 2002 Johan Persson
13 //==============================================================================
15 include "jpclassref.php" ;
17 DEFINE('GLOBALFUNCS_FILENAME','global_funcs.html');
23 function Open($aFileName) {
24 if( ($this->iFP = @fopen($aFileName,'w')) == false )
25 die("<b>File open error:</b> Can't open file '$aFileName'. Check that file and directory exists.");
26 $this->iFileName = $aFileName;
35 if( fwrite($this->iFP,$aStr) == -1 )
36 die("Can't write to file : ".$this->iFileName);
43 // Basic HTML Class formatter
44 class ClassHTMLFormatter extends ClassFormatter {
45 var $iNumClasses,$iColumnClassCnt,$iGlobalClassCnt,$iNumMethods,$iColumnMethCnt,$iClassMethodCnt;
50 '<style type="text/css">
52 A:link {font-family: helvetica, arial, geneva, sans-serif; font-size: x-small; text-decoration: none; color: #0000ff}
53 A:visited {font-family: helvetica, arial, geneva, sans-serif; font-size: x-small; text-decoration: none; color: #0000ff}
54 A:hover {font-family: helvetica, arial, geneva, sans-serif; font-size: x-small; text-decoration: underline; color: #FF0000}
55 th {font-family: helvetica, arial; color : blue; font-size:85%; background : lightgrey; border-right:black solid 1pt; border-bottom:black solid 1pt;}
59 var $iIndexFramePage =
60 '<!doctype html public "-//W3C//DTD HTML 4.0 Frameset//EN">
62 <LINK REL=STYLESHEET TYPE="text/css" HREF="de_normal.css">
63 <title>Project documentation</title>
65 <frameset cols="270,*">
66 <frame src=class_toc.html name=toc>;
67 <frame src=projinfo.html name=classdetail>
72 '<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
74 <LINK REL=STYLESHEET TYPE="text/css" HREF="de_normal.css">
75 <title>Project documentation</title>
78 function ClassHTMLFormatter($aDBCache,$aFlags="") {
79 parent::ClassFormatter($aDBCache,$aFlags="");
80 $this->iWriter = new FileWriter();
85 $t = '<table width=100% border=1 style="background-color:lightblue;"><tr><td align=center><span style="font-size:20pt;font-family:arial;font-weight:bold;">'.$this->iProjName."</span></td></tr></table>\n";
86 $t .= '<div align=center><h3 style="color:darkred;font-family:arial;">Documentation status: '.round($this->iStatAverage*100).'%</h3>';
87 $t .= '<span style="font-family:arial;">Total number of Classes: '.$this->iStatNumClasses.', Methods: '.$this->iStatNumMethods."</span><p>\n";
88 if( $this->iShowPrivate )
89 $t .= '<i>This version <b>includes</b> private methods & classes</i><p>';
91 $t .= '<i>This version does <b>not</b> include private methods & classes</i><p>';
92 $t .= '<p><i>Generated at '.strftime('%d %b %Y at %H:%M')."</i><br>\n";
94 $t .= "<p>".$this->iProjDesc; //$proj['fld_desc'];
96 if( $this->iDocType == 0 ) {
97 $dt = 'HTML: Multiple files.';
98 $this->iWriter->Open($this->iDirectory.'projinfo.html');
99 $this->iWriter->W( $t );
100 $this->iWriter->Close();
102 $this->iWriter->Open($this->iDirectory.'index.html');
103 $this->iWriter->W( $this->iIndexFramePage );
104 $this->iWriter->Close();
107 $dt = 'HTML: Single file.';
108 $this->iWriter->Open($this->iDirectory.'index.html');
109 $this->iWriter->W( $this->iIndexPage );
110 $this->iWriter->W( $this->iCSS );
111 $this->iWriter->W( $t );
114 HTMLGenerator::CloseWinButton('left');
116 echo "<font face=arial><b>Generating reference for project : <font color=blue>$this->iProjName</font></b></font><br>";
117 echo "Output directory: <b><font color=blue>".$this->iDirectory.'</font></b><br>';
118 echo "Output format: <b><font color=blue>$dt</font></b> <br>\n";
119 echo "Including private methods and classes: <b><font color=blue>".($this->iShowPrivate ? 'Yes' : 'No')."</font></b><br>";
120 echo "Including global functions: <b><font color=blue>".($this->iShowGlobFuncs ? 'Yes' : 'No')."</font></b><br>";
125 echo "<h3>Successfully generated all documentation.</h3>";
127 HTMLGenerator::CloseWinButton('left');
130 function ClassEntry($aClassName) {
132 echo "$this->iListCnt. Writing class <b><font color=blue>$aClassName</font></b>...";flush();
133 if( $this->iDocType == 0 ) { // Split output
134 $this->iWriter->Open($this->iDirectory.$aClassName.'.html');
135 $this->iWriter->W( $this->iCSS );
139 function ClassExit() {
140 echo " done.<br>\n";flush();
141 $this->iWriter->W( '<p> <hr> <p>' );
142 if( $this->iDocType == 0 ) { // Split output
143 $this->iWriter->Close();
147 function GlobalFuncEntry($aNumFuncs) {
148 echo "<p>Writing <b><font color=blue> $aNumFuncs global functions</font></b>...\n";flush();
149 if( $this->iDocType == 0 ) { // Split output
150 $this->iWriter->Open($this->iDirectory.GLOBALFUNCS_FILENAME);
151 $this->iWriter->W( $this->iCSS );
153 $this->iWriter->W('<div style="background-color:yellow;font-family:arial;font-weight:bold;font-size:150%;">Global functions</div>');
156 function GlobalFuncExit() {
157 echo "<br> done.<br>\n";
158 $this->iWriter->W( '<p> <hr> <p>' );
159 if( $this->iDocType == 0 ) { // Split output
160 $this->iWriter->Close();
164 function FmtClassHierarchySetup($aHier,$aNbr) {
165 $this->iWriter->W( "<table border=1>" );
168 function FmtClassHierarchyExit($aHier,$aNbr) {
169 $this->iWriter->W( "</tr></table>" );
172 function FmtClassHierarchyHeaders($aHier,$aNbr) {
173 $this->iWriter->W( "<tr>" );
174 for( $i=0; $i<$aNbr; ++$i ) {
175 $this->iWriter->W( '<td> <a href="'.$aHier[$i].'.html" style="font-family:arial;font-weight:bold;color:darkblue;">'.$aHier[$i]."</a> </td>" );
177 $this->iWriter->W( "</tr><tr>" );
180 function FmtClassHierarchyColumnSetup($aClassName,$aColNbr) {
181 $this->iWriter->W( "<td valign=top>" );
184 function FmtClassHierarchyColumnExit($aClassName,$aColNbr) {
185 $this->iWriter->W( "</td>" );
188 function FmtClassHierarchyRow($aClassName,$aMethodName,$aOverridden,$aPublic) {
189 if( $aMethodName == "" )
190 $this->iWriter->W( " " );
192 // Markup private methods with a '*'
193 if( !$this->iShowPrivate && !$aPublic )
201 $this->iWriter->W( "<a href=\"$aClassName.html#".
202 strtoupper("_".$aClassName."_".$aMethodName).
203 "\" style=\"color:darkgrey;\">$mark".$aMethodName."() </a><br>\n" );
206 $this->iWriter->W( " ".
207 "<a href=\"$aClassName.html#".strtoupper("_".$aClassName."_".$aMethodName)."\">$mark".
208 $aMethodName."()</a> <br>\n" );
213 function FmtClassSetup($aClassInfo) {
215 $res = "<hr><a name=\"".strtoupper("_C_".$aClassInfo["fld_name"])."\"><div style=\"background-color:yellow;font-family:courier new;\"></a>";
216 $res .= "CLASS <b>".$aClassInfo["fld_name"]."</b>";
217 if( $aClassInfo["fld_parentname"] != "" )
218 $res .= " EXTENDS <a href=\"".$aClassInfo["fld_parentname"].".html#".strtoupper("_C_".$aClassInfo["fld_parentname"])."\" style=\"font-face:arial;font-weight:bold;\">".$aClassInfo["fld_parentname"]."</a>";
220 $res .= "<i>(Defined in: ".$aClassInfo['fld_file']." : $aClassInfo[fld_linenbr])</i>";
221 $this->iWriter->W( $res );
224 function FmtClassOverview($aClassInfo) {
225 $res = " <p><div style=\"font-weight:bold;font-family:arial;font-size:100%;\">Class usage and Overview</div>".$aClassInfo["fld_desc"]." <p> \n";
226 $this->iWriter->W( $res );
229 function FmtClassOverviewExit($aClassInfo) {
230 $this->iWriter->W( '<hr><span style="font-family:arial;font-size:120%;font-weight:bold;">Class Methods</span><hr>' );
233 function FmtClassRefs($aClassInfo) {
236 for( $i=1; $i <= $MAXREFS; ++$i ) {
237 $cname = @$aClassInfo['fld_ref'.$i];
238 if( !empty($cname) && trim($cname) != '' ) {
245 $this->iWriter->W("<div style=\"font-weight:bold;font-family:arial;font-size:85%;\">See also related classes:</div>" ) ;
246 for( $i=0; $i < $n; ++$i ) {
247 $this->iWriter->W( '<a href="'.$refs[$i].'.html">'.$refs[$i].'</a>' );
249 $this->iWriter->W( ", " );
251 $this->iWriter->W( " and " );
253 $this->iWriter->W( ' <p> ' );
256 function FmtClassVars($aVars) {
257 $res = "<table border=0>\n";
258 for($i=0; $i<count($aVars); ++$i) {
259 $res .= "<tr><td valign=top>";
260 // highlight_string is buggy so we add ';' to be able to parse a
262 $t = $aVars[$i]["fld_name"];
263 $t = Utils::HighlightCodeSnippet($t);
264 $res .= "<span style=\"font-family:times;font-size:85%;font-weight:bold;\">$t</span>\n";
265 $res .= "</td></tr>\n";
267 $res .= "</table>\n";
268 $this->iWriter->W( $res );
271 function FmtFuncPrototype($aClassName,$aFunc,$aShowFile=false) {
274 $file = "<i>($aFunc[fld_file]:$aFunc[fld_linenbr])</i><br>\n";
276 $t = "function ".$aFunc["fld_name"]."(";
277 for($i=0; $i<$aFunc["fld_numargs"]; ++$i) {
278 if( $i != 0 ) $t .= ",";
279 $t .= $aFunc["fld_arg".($i+1)];
282 $t = Utils::HighlightCodeSnippet($t);
283 $t = "<p> <p> <span style='font-size:110%;'><a name=\"".strtoupper("_".$aClassName."_".$aFunc["fld_name"])."\">".$t."</a></span>\n";
284 $t .= "$file\n<span style='font-family:arial;font-size:90%;'><i>".$aFunc["fld_shortdesc"]."</i></span><p>\n";
285 $this->iWriter->W( "<p>\n".$t );
288 function FmtFuncReturn($aFunc) {
289 $r = $aFunc["fld_return"];
290 if( trim($r) != '' ) {
291 $res = "<br>\n<div style=\"font-weight:bold;font-family:arial;font-size:85%;\">Returns</div>$r<br>\n";
292 $this->iWriter->W( $res );
296 function FmtFuncArgs($aFunc) {
297 if( $aFunc["fld_numargs"] == 0 ) {
298 $this->iWriter->W( "<br>\n" );
302 $res = "\n<table cellspacing=0 style='border:black solid 1pt;' width=100%>\n";
303 $res .= '<tr><th width=25%>Argument</th><th width=15%>Default</th><th width=60%>Description</th></tr>';
304 for($i=0; $i<$aFunc["fld_numargs"]; ++$i) {
305 $res .= "\n<tr><td style='border-right:black solid 1pt;font-family:courier;font-size:90%;font-weight:bold;'>";
306 // highlight_string is buggy so we add ';' to be able to parse a
308 $t = $aFunc["fld_arg".($i+1)];
309 $t = Utils::HighlightCodeSnippet($t,false,false);
311 $res .= "</td><td style='border-right:black solid 1pt;font-family:courier;font-size:90%;font-weight:bold;'>";
312 $val = $aFunc["fld_argval".($i+1)];
313 if( !isset($val) || strlen(trim($val)) == 0 )
316 $val = Utils::HighlightCodeSnippet($val,false,false);
317 $res .= $val.'</td><td>';
318 $des = $aFunc["fld_argdes".($i+1)];
319 if( empty($des) || strlen(trim($des)) == 0 )
320 $des = "No description available";
324 $res .= "</table>\n";
325 $this->iWriter->W( $res );
328 function FmtFuncDesc($aFunc) {
329 $res = "\n<div style=\"font-weight:bold;font-family:arial;font-size:85%;\">Description</div>";
331 if( strlen(trim($aFunc['fld_desc'])) == 0 )
332 $res .= "No description available.";
334 $res .= $aFunc['fld_desc']." <br>\n";
336 $this->iWriter->W( $res );
339 function FmtFuncRef($aRef) {
340 $this->iWriter->W(" <div style=\"font-weight:bold;font-family:arial;font-size:85%;\">See also</div>" ) ;
342 for( $i=0; $i < $m; ++$i ) {
343 list($cname,$mname) = $aRef[$i];
344 $this->iWriter->W( "<a href=\"$cname.html#".strtoupper("_".$cname."_".$mname)."\">".$cname."::".$mname."</a>" );
346 $this->iWriter->W( ", " );
348 $this->iWriter->W( " and " );
352 function FmtFuncExample($aFunc) {
353 if( $aFunc["fld_example"] != "" ) {
354 $this->iWriter->W( "\n<div style=\"font-weight:bold;font-family:arial;font-size:85%;\"><p>Example</div>" );
355 $this->iWriter->W( Utils::HighlightCodeSnippet($aFunc["fld_example"],false)."<br>\n" );
359 function FmtIndexSetup($aNumClasses,$aNumMethods, $aNumColumns=3) {
361 // Note: In this formatter we ignore the outside specification of
362 // columns because we always use 1 column for frames formatting
363 // and 3 columns for a single file formatting.
365 if( $this->iDocType == 0 ) {
367 $class_toc_name = 'class_toc.html';
368 $this->iWriter->Open( $this->iDirectory.$class_toc_name );
371 $class_toc_name = 'index.html';
375 $this->iNumIndexColumns = $aNumColumns;
376 //echo "<h4>Creating index (".$this->iDirectory.$class_toc_name.") with $aNumColumns columns...</h4>";
377 $this->iWriter->W( $this->iCSS );
378 $this->iWriter->W( "<a href=projinfo.html target=classdetail style='font-size:120%;'>$this->iProjName</a><p>\n" );
380 if( $this->iShowGlobFuncs ) {
381 $this->iWriter->W( "<a href=".GLOBALFUNCS_FILENAME." target=classdetail style='font-size:100%;'>Global functions</a><p>\n" );
384 $this->iNumClasses = $aNumClasses;
385 $this->iNumMethods = $aNumMethods;
387 $this->iColumnClassCnt = 0;
388 $this->iGlobalClassCnt = 0;
389 $this->iColumnMethCnt = 0;
390 $this->iWriter->W( "<table width=100%><tr><td valign=top width=".round(100/$aNumColumns,0)."%>" );
393 function FmtIndexExit() {
394 $this->iWriter->W( "</td></tr></table><p>" );
395 if( $this->iDocType == 0 ) {
396 $this->iWriter->Close();
400 function FmtIndexClass($aClassName) {
401 ++$this->iColumnClassCnt;
402 ++$this->iGlobalClassCnt;
403 $this->iClassMethodCnt=0;
404 if( ($this->iColumnClassCnt > floor($this->iNumClasses/$this->iNumIndexColumns)) ) {
405 if( $this->iCol < $this->iNumIndexColumns ) {
406 $this->iWriter->W( "</td><td valign=top width=".round(100/$this->iNumIndexColumns,0)."%>" );
407 $this->iColumnClassCnt = 0;
408 $this->iColumnMethCnt = 0;
411 $target = ' target=classdetail';
412 $this->iWriter->W( "<b><font face='arial'>$this->iGlobalClassCnt.</font> <a href=\"$aClassName.html#".strtoupper("_C_$aClassName")."\" $target>$aClassName</a></b><br>\n" );
415 function FmtIndexMethod($aClassName,$aMethodName) {
416 ++$this->iColumnMethCnt;
417 ++$this->iClassMethodCnt;
418 $target = ' target=classdetail';
419 $this->iWriter->W( " <span style='font-family:arial;font-size:x-small;'> $this->iGlobalClassCnt.$this->iClassMethodCnt</span> <a href=\"$aClassName.html#".strtoupper("_".$aClassName."_".$aMethodName)."\" $target>$aMethodName</a><br>\n" );
424 class HTMLDriver extends ClassRefDriver {
426 function NewClassFormatter($aDBCache,$aFlags) {
427 return new ClassHTMLFormatter($aDBCache,$aFlags);
432 //==========================================================================
433 // Script entry point
434 // Read URL argument and create Driver
435 //==========================================================================
436 if( !isset($HTTP_GET_VARS['class']) )
439 $class = urldecode($HTTP_GET_VARS['class']);
441 $driver = new HTMLDriver();
442 $driver->Run($class,FMT_CLASSVARS);