
2 changed files with 721 additions and 3 deletions
@ -0,0 +1,718 @@ |
|||||
|
<?php /* |
||||
|
Provides ways to manipulate and print API documentation of PHP programs |
||||
|
|
||||
|
author: Martin Monperrus |
||||
|
|
||||
|
*/ |
||||
|
|
||||
|
|
||||
|
global $diffs; |
||||
|
$diffs = array(); |
||||
|
|
||||
|
function get_functions_in($phpfile) { |
||||
|
return load($phpfile)['functions']; |
||||
|
} |
||||
|
|
||||
|
function load($phpfile) { |
||||
|
global $diffs; |
||||
|
|
||||
|
if (!isset($diffs[$phpfile])) { |
||||
|
$beforef=get_defined_functions()['user']; |
||||
|
$beforec=get_declared_classes(); |
||||
|
} else { |
||||
|
return $diffs[$phpfile]; |
||||
|
} |
||||
|
|
||||
|
// prevent problems if they is one exit in the included script
|
||||
|
// register_shutdown_function('printNewFunctions',$beforef);
|
||||
|
|
||||
|
// we don't want the output
|
||||
|
ob_start(); |
||||
|
require($phpfile); |
||||
|
// this does not work because the include is not executed
|
||||
|
//eval('return true; include("'.$_GET['file'].'");');
|
||||
|
ob_end_clean(); |
||||
|
|
||||
|
$afterf=get_defined_functions()['user']; |
||||
|
$afterc=get_declared_classes(); |
||||
|
|
||||
|
$new_functions = array(); |
||||
|
foreach($afterf as $k) { |
||||
|
if (!in_array($k,$beforef)) { |
||||
|
$new_functions[] = $k; |
||||
|
} |
||||
|
} |
||||
|
$diffs[$phpfile]['functions'] = $new_functions; |
||||
|
|
||||
|
$new_classes = array(); |
||||
|
foreach($afterc as $k) { |
||||
|
if (!in_array($k,$beforec)) { |
||||
|
$new_classes[] = $k; |
||||
|
} |
||||
|
} |
||||
|
$diffs[$phpfile]['classes'] = $new_classes; |
||||
|
|
||||
|
return $diffs[$phpfile]; |
||||
|
} |
||||
|
|
||||
|
/** returns a list of new classes */ |
||||
|
function get_classes_in($phpfile) { |
||||
|
return load($phpfile)['classes']; |
||||
|
} |
||||
|
|
||||
|
/** print only documented classes and methods */ |
||||
|
function printDocumentedClasses($file) { |
||||
|
$res = ''; |
||||
|
foreach (get_classes_in($file) as $klass) { |
||||
|
$res .= printAPIDocClass($klass, true); |
||||
|
} |
||||
|
return $res; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
?><?php /* pp4php: including ./gakowiki-syntax.php (in reflectivedoc.php:73) */ ?><?php /**
|
||||
|
|
||||
|
A wiki parser implemented in a neat way. |
||||
|
|
||||
|
Author: Martin Monperrus |
||||
|
Public domain |
||||
|
|
||||
|
Usage: echo gk_wiki2html("foo **bar*") |
||||
|
|
||||
|
*/ |
||||
|
|
||||
|
/** returns an HTML version of the wiki text of $text, according to the syntax of [[http://www.monperrus.net/martin/gakowiki-syntax]] */ |
||||
|
function gk_wiki2html($text) { |
||||
|
global $parser; |
||||
|
if ($parser==null) $parser = create_wiki_parser(); |
||||
|
return $parser->parse($text); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
?><?php /* pp4php: including ./gakoparser.php (in ./gakowiki-syntax.php:20) */ ?><?php /* Gakoparser
|
||||
|
|
||||
|
Gakoparser parses a family of markup language |
||||
|
|
||||
|
Sunday, October 30 2011 |
||||
|
impossible to handle both ===== sdf ===== and ==== sdfsdf ==== |
||||
|
handling of space different |
||||
|
|
||||
|
handling of >\n different |
||||
|
|
||||
|
*/ |
||||
|
|
||||
|
if (defined('gakoparser.php')) return; |
||||
|
define('gakoparser.php',true); |
||||
|
|
||||
|
class Delimiter{} |
||||
|
|
||||
|
class GakoParserException extends Exception {} |
||||
|
|
||||
|
/** provides a parametrizable parser. The main method is "parse" */ |
||||
|
class GakoParser { |
||||
|
|
||||
|
/** is the PHP5 constructor. */ |
||||
|
function __construct() { |
||||
|
// an array of Delimiter objects
|
||||
|
$this->start_delimiters = array(); |
||||
|
$this->end_delimiters = array(); |
||||
|
$this->nonesting = array(); |
||||
|
$this->delegate = array(); |
||||
|
} |
||||
|
|
||||
|
/** specifies that $tag can not contain nested tags */ |
||||
|
function noNesting($tag) { |
||||
|
$this->nonesting[] = $tag; |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
function setDelegate($obj) { |
||||
|
$this->delegate = $obj; |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
function addDelim($name, $delim) { |
||||
|
return $this->addDelimX($name, $delim, $delim); |
||||
|
} |
||||
|
|
||||
|
/** adds a trigger $tag -> execution of function $name */ |
||||
|
function addTag($name, $tag) { |
||||
|
$start = substr($tag,0,strlen($tag)-1); |
||||
|
$end = substr($tag,strlen($tag)-1); |
||||
|
return $this->addDelimX($name, $start, $end); |
||||
|
} |
||||
|
|
||||
|
/** setDelegate must be called before this method */ |
||||
|
function addDelimX($name, $start, $end) { |
||||
|
if (!method_exists($this->delegate,$name)) {throw new GakoParserException('no method '.$method.' in delegate!');} |
||||
|
|
||||
|
$x = new Delimiter(); |
||||
|
$x->value = $start; |
||||
|
// $x->type = 'start';
|
||||
|
$x->action = $name; |
||||
|
|
||||
|
$y = new Delimiter(); |
||||
|
$y->value = $end; |
||||
|
// $y->type = 'end';
|
||||
|
$y->action = $name; |
||||
|
|
||||
|
// crossing links
|
||||
|
$y->startDelim = $x; |
||||
|
$x->endDelim = $y; |
||||
|
|
||||
|
if (in_array($start, $this->get_start_delimiters())) { |
||||
|
throw new GakoParserException("delimiter ".$start." already exists"); |
||||
|
} |
||||
|
|
||||
|
$this->start_delimiters[$start] = $x; |
||||
|
$this->end_delimiters[$end] = $y; |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
function get_start_delimiters() { |
||||
|
return array_keys($this->start_delimiters); |
||||
|
} |
||||
|
|
||||
|
function get_end_delimiters() { |
||||
|
return array_keys($this->end_delimiters); |
||||
|
} |
||||
|
|
||||
|
function array_preg_quote($x) { |
||||
|
$result = array(); |
||||
|
foreach($x as $k) { $result[] = preg_quote($k, '/'); } |
||||
|
return $result; |
||||
|
} |
||||
|
|
||||
|
function addDelimXML($name, $delim) { |
||||
|
return $this->addDelimX($name, '<'.$delim.'>', '</'.$delim.'>'); |
||||
|
} |
||||
|
|
||||
|
function getCandidateDelimiters_man($str) { |
||||
|
$result = array(); |
||||
|
|
||||
|
for ( $i=0; $i < strlen( $str ); $i++) { |
||||
|
foreach(array_merge($this->get_start_delimiters(),$this->get_end_delimiters()) as $v) { |
||||
|
$new_fragment = substr($str, $i, strlen($v)); |
||||
|
if ($new_fragment === $v) { |
||||
|
$x = array(); |
||||
|
$x[0] = array(); |
||||
|
$x[0][0] = $v; |
||||
|
$x[0][1] = $i; |
||||
|
$result[] = $x; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
//print_r($result);
|
||||
|
return $result; |
||||
|
} |
||||
|
|
||||
|
function getCandidateDelimiters($str) { |
||||
|
//return $this->getCandidateDelimiters_man($str);
|
||||
|
return $this->getCandidateDelimiters_preg($str); |
||||
|
} |
||||
|
|
||||
|
function getCandidateDelimiters_preg($str) { |
||||
|
// getting the start delimiters
|
||||
|
preg_match_all('/'.implode('|',array_merge($this->array_preg_quote($this->get_start_delimiters()),$this->array_preg_quote($this->get_end_delimiters()))).'/', $str, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE ); |
||||
|
return $matches; |
||||
|
} |
||||
|
|
||||
|
function parse($str) { |
||||
|
// echo "---------parse $str\n";
|
||||
|
$method = '__pre'; |
||||
|
if (method_exists($this->delegate,$method)) { |
||||
|
$str = $this->delegate->$method($str); |
||||
|
} |
||||
|
|
||||
|
$matches = $this->getCandidateDelimiters($str); |
||||
|
|
||||
|
// print_r($matches);
|
||||
|
|
||||
|
//echo 'parse '.$str.'<br>';
|
||||
|
// the stack contains the current markup environment
|
||||
|
$init = new Delimiter(); $init->action = '__init__'; $init->value = '__init__'; $init->endDelim = $init; |
||||
|
$stack = array($init); |
||||
|
$strings = array(1=>''); |
||||
|
$last = 0; |
||||
|
|
||||
|
// if (count($matches) == 0) return $str;
|
||||
|
|
||||
|
// print_r($matches);
|
||||
|
|
||||
|
// $strings[1] = substr($str, 0, $matches[0][0][1]);
|
||||
|
|
||||
|
// for each tags found
|
||||
|
foreach ( $matches as $_ ) { |
||||
|
|
||||
|
list($v, $pos) = $_[0]; |
||||
|
|
||||
|
// echo "studying ".$v." at ".$pos." (last=".$last.")\n";
|
||||
|
|
||||
|
// if $_ is a start delimiter,
|
||||
|
// we'll get '' in $k
|
||||
|
//echo $stack[0];
|
||||
|
if (isset($this->end_delimiters[$v]) |
||||
|
// && $stack[0] != '__init__'
|
||||
|
&& $stack[0]->endDelim->value == $v |
||||
|
&& $pos>=$last |
||||
|
) { |
||||
|
$k = $stack[0]->endDelim->action; |
||||
|
|
||||
|
$strings[count($stack)] .= substr($str,$last, $pos-$last); |
||||
|
|
||||
|
// echo "popping ".$k." at ".$pos." with ".$v." (last=".$last.", stack=".count($stack).")\n";
|
||||
|
|
||||
|
$closedtag = array_shift($stack); |
||||
|
|
||||
|
$method = $k; |
||||
|
// echo $method." ".$value. "\n";
|
||||
|
$value = $strings[count($stack)+1]; |
||||
|
$transformed = $this->delegate->$method($value); |
||||
|
// echo $transformed ."---".$value." \n";
|
||||
|
$strings[count($stack)] .= $transformed; |
||||
|
|
||||
|
$strings[count($stack)+1] = ''; |
||||
|
$last = $pos+strlen($v); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// certain tags do not support nesting
|
||||
|
else if (!in_array($stack[0]->action, $this->nonesting) |
||||
|
&& in_array($v, $this->get_start_delimiters()) && $pos >= $last) |
||||
|
{ |
||||
|
$delim = $this->start_delimiters[$v]; |
||||
|
$k = $delim->action; |
||||
|
|
||||
|
// echo "putting ".$k." at ".$pos." with ".$last."<br/>\n";
|
||||
|
|
||||
|
if ($pos>$last) { |
||||
|
$strings[count($stack)] .= substr($str, $last, $pos-$last); |
||||
|
} |
||||
|
array_unshift($stack, $delim); |
||||
|
// init the new stack
|
||||
|
$strings[count($stack)] = ''; |
||||
|
$last = $pos+strlen($v); |
||||
|
// print_r($strings);
|
||||
|
|
||||
|
} else { |
||||
|
//die('oops');
|
||||
|
} |
||||
|
|
||||
|
} // end foreach
|
||||
|
|
||||
|
|
||||
|
if ($stack[0]->action!="__init__") { |
||||
|
//print_r($strings);
|
||||
|
throw new GakoParserException("parsing error: ending with ".$stack[0]->action. " ('".$strings[1]."')"); |
||||
|
} |
||||
|
|
||||
|
$result = $strings[count($stack)]; |
||||
|
|
||||
|
// adding the rest
|
||||
|
if ($last<strlen($str)) $result .= substr($str,$last,strlen($str)-$last); |
||||
|
|
||||
|
$method = '__post'; |
||||
|
if (method_exists($this->delegate,$method)) { |
||||
|
$result = $this->delegate->$method($result); |
||||
|
} |
||||
|
//echo "$$$$$ ".$result."\n";
|
||||
|
|
||||
|
return $result; |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
?><?php
|
||||
|
|
||||
|
/** Defines a set of functions for interpreting a markup language in HTML. |
||||
|
Maintains a state to build the table of contents. |
||||
|
Delegate class for Gakoparser. |
||||
|
<pre> |
||||
|
|
||||
|
// high level
|
||||
|
$parser = create_wiki_parser(); |
||||
|
$html_text = $parser->parse($wiki_text); |
||||
|
|
||||
|
// low level
|
||||
|
$parser = new Gakoparser(); |
||||
|
$parser->setDelegate(new MarkupInterpreter()); |
||||
|
$parser->addDelim('bold','**'); |
||||
|
echo $parser->parse('hello **world**'); |
||||
|
|
||||
|
</pre> |
||||
|
*/ |
||||
|
|
||||
|
|
||||
|
class GakowikiMarkupToHTMLTranslator { |
||||
|
|
||||
|
var $toc = array(); |
||||
|
|
||||
|
var $references = array(); |
||||
|
|
||||
|
/** replaces all line breaks by "__newline__" that are meant to replaced back by a call to __post() */ |
||||
|
function __pre($str) { |
||||
|
$result = $str; |
||||
|
|
||||
|
// we often use nelines to have pretty HTML code
|
||||
|
// such as in tables
|
||||
|
// however, they are no "real" newlines to be transformed in <br/>
|
||||
|
$result = preg_replace("/>\s*(\n|\r\n)/",'>__newline__',$result); |
||||
|
return $result; |
||||
|
} |
||||
|
|
||||
|
function bib($str) { |
||||
|
$this->references[] = $str; |
||||
|
return '<a name="ref'.count($this->references).'">['.count($this->references).']</a> '.$str; |
||||
|
} |
||||
|
|
||||
|
function cite($str) { |
||||
|
return "@@@".$str."@@@"; |
||||
|
} |
||||
|
|
||||
|
function escape_newline($str) { |
||||
|
return preg_replace("/(\n|\r\n)/","__newline__",$str); |
||||
|
} |
||||
|
|
||||
|
function toc($str) { |
||||
|
return '+++TOC+++'; |
||||
|
} |
||||
|
|
||||
|
function __post($str) { |
||||
|
$result = $str; |
||||
|
$result = preg_replace("/(\n|\r\n)/","<br/>\n",$result); |
||||
|
|
||||
|
// workaround to support the semantics change in pre mode
|
||||
|
// and the semantics of embedded HTML
|
||||
|
$result = preg_replace("/__newline__/","\n",$result);// must be at the end
|
||||
|
|
||||
|
// cleaning the additional <br>
|
||||
|
// this is really nice
|
||||
|
$result = preg_replace("/(<\/h.>)<br\/>/i","\\1 ",$result); |
||||
|
|
||||
|
// adding the table of contents
|
||||
|
$result = str_replace($this->toc(''),implode('<br/>',$this->toc),$result); |
||||
|
|
||||
|
// adding the references
|
||||
|
$citeregexp = '/@@@(.*?)@@@/'; |
||||
|
if (preg_match_all($citeregexp,$result,$matches)) { |
||||
|
foreach($matches[1] as $m) { |
||||
|
$theref = ''; |
||||
|
foreach ($this->references as $k => $ref) { |
||||
|
if (preg_match('/'.preg_quote($m).'/i', $ref)) { |
||||
|
//echo $m.' '.$ref;
|
||||
|
// if we have already a match it is not deterministic
|
||||
|
if ($theref!='') $result = "undeterministic citation: ".$m; |
||||
|
$theref = $ref; |
||||
|
$result = preg_replace('/@@@'.preg_quote($m).'@@@/i', '<a href="#ref'.($k+1).'">['.($k+1).']</a>', $result); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return $result; |
||||
|
} |
||||
|
|
||||
|
/** adds <pre> tags and prevents newline to be replaced by <br/> by __post */ |
||||
|
function pre($str) { |
||||
|
return '<pre>'.$this->escape_newline($str).'</pre>'; |
||||
|
} |
||||
|
|
||||
|
/** prevents newline to be replaced by <br/> by __post */ |
||||
|
function unwrap($str) { |
||||
|
return $this->escape_newline($str); |
||||
|
} |
||||
|
|
||||
|
/** adds <b> tags */ |
||||
|
function bold($str) { |
||||
|
return '<b>'.$str.'</b>'; |
||||
|
} |
||||
|
|
||||
|
/** adds <i> tags */ |
||||
|
function italic($str) { |
||||
|
return '<i>'.$str.'</i>'; |
||||
|
} |
||||
|
|
||||
|
function table($str) { |
||||
|
$result = ''; |
||||
|
foreach(preg_split('/\n/',$str) as $line) { |
||||
|
if (strlen(trim($line))>0) { |
||||
|
$result .= '<tr>'; |
||||
|
foreach(preg_split('/&&/',$line) as $field) { |
||||
|
$result .= '<td>'.$field.'</td>'; |
||||
|
|
||||
|
} |
||||
|
$result .= '</tr>'; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return '<table border="1">'.$result.'</table>'; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
function __create_anchor($m) { |
||||
|
return preg_replace("/[^a-zA-Z]/","",$m); |
||||
|
} |
||||
|
function h2($str) { |
||||
|
$tag = $this->__create_anchor($str); |
||||
|
$this->toc[] = "<a href=\"#".$tag."\">".$str."</a>"; |
||||
|
return '<a name="'.$tag.'"></a>'.'<h2>'.$str."</h2>"; |
||||
|
} |
||||
|
|
||||
|
function h3($str) { |
||||
|
$tag = $this->__create_anchor($str); |
||||
|
$this->toc[] = " <a href=\"#".$tag."\">".$str."</a>"; |
||||
|
return '<a name="'.$tag.'"></a>'.'<h3>'.$str."</h3>"; |
||||
|
} |
||||
|
|
||||
|
function monotype($str) { |
||||
|
return '<code>'.str_replace('<','<',$str).'</code>'; |
||||
|
} |
||||
|
|
||||
|
function link($str) { |
||||
|
|
||||
|
if (preg_match('/(.*)\|(.*)/',$str, $matches)) { |
||||
|
$rawurl = $matches[1]; |
||||
|
$text = $matches[2]; |
||||
|
} else {$rawurl=$str;$text=$str;} |
||||
|
|
||||
|
$url=$rawurl; |
||||
|
|
||||
|
if (!preg_match("/(#|^http|^mailto)/",$rawurl)) { |
||||
|
if (function_exists('logical2url')) { |
||||
|
$url=logical2url($rawurl); |
||||
|
} else { |
||||
|
$url=$rawurl; |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return '<a href="'.trim($url).'">'.trim($text).'</a>'; |
||||
|
} |
||||
|
|
||||
|
function phpcode($str) { |
||||
|
ob_start(); |
||||
|
eval($str); |
||||
|
return $this->escape_newline(ob_get_clean()); |
||||
|
} |
||||
|
|
||||
|
function phpcode2($str) { |
||||
|
return gk_wiki2html($this->phpcode($str)); |
||||
|
} |
||||
|
|
||||
|
function a($str) { |
||||
|
return '<a'.$str.'</a>'; |
||||
|
} |
||||
|
|
||||
|
function script($str) { |
||||
|
return '<script'.$this->escape_newline($str).'</script>'; |
||||
|
} |
||||
|
|
||||
|
function img($str) { |
||||
|
return '<img src="'.$this->escape_newline($str).'"/>'; |
||||
|
} |
||||
|
|
||||
|
function img2($str) { |
||||
|
return '<img'.$str.'/>'; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
function html($str) { |
||||
|
return '<'.$str.'>'; |
||||
|
} |
||||
|
|
||||
|
function iframe($str) { |
||||
|
return '<iframe'.$str.'</iframe>'; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
function comment($str) { |
||||
|
return ''; // comments are discarded
|
||||
|
} |
||||
|
|
||||
|
function silent($str) { |
||||
|
return ''; |
||||
|
} |
||||
|
|
||||
|
} // end class
|
||||
|
|
||||
|
|
||||
|
/** returns a parser object to parse wiki syntax. |
||||
|
|
||||
|
The returned object may be used with the parse method: |
||||
|
<pre> |
||||
|
$parser = create_wiki_parser(); |
||||
|
$html_text = $parser->parse($wiki_text); |
||||
|
</pre> |
||||
|
*/ |
||||
|
function create_wiki_parser() { |
||||
|
$x = new Gakoparser(); |
||||
|
return $x->setDelegate(new GakowikiMarkupToHTMLTranslator()) |
||||
|
->addDelimX('comment','<!--','-->')->noNesting('comment') |
||||
|
|
||||
|
->addDelim('bold','**') |
||||
|
->addDelim('italic','//')//->noNesting('italic')
|
||||
|
->addDelim('bold',"'''") |
||||
|
->addDelim('monotype',"''")->noNesting('monotype') |
||||
|
->addDelim('h2',"=====") // the longest comes before, it has the highest priority
|
||||
|
->addDelim('h3',"====") |
||||
|
->addDelim('table',"|||") |
||||
|
->addDelimXML('pre','pre')->noNesting('pre') // this is essential otherwise you have infinite loops
|
||||
|
->addDelimX('pre','{{{','}}}')->noNesting('pre2') // à la Google Code wiki syntax
|
||||
|
->addDelimX('link','[[',']]')->noNesting('link') |
||||
|
->addDelimX('phpcode2','<?php2wiki','?>')->noNesting('phpcode2') |
||||
|
->addDelimX('phpcode','<?php','?>') ->noNesting('phpcode') |
||||
|
->addDelimX('img2','<img','/>')->noNesting('img2') |
||||
|
->addDelim('img','%%')->noNesting('img')// huge bug when I did this for 1000 index :(
|
||||
|
->addDelimX('script','<script','</script>') ->noNesting('script') |
||||
|
->addDelimX('unwrap','^^','^^') |
||||
|
->addTag('toc','+++TOC+++') |
||||
|
|
||||
|
->addDelimX('a','<a','</a>')->noNesting('a') // important to support cross tags
|
||||
|
|
||||
|
->addDelimX('iframe','<iframe','</iframe>')->noNesting('iframe') |
||||
|
|
||||
|
// Dec 30 2012
|
||||
|
->addDelimX('bib','\bib{','}') |
||||
|
->addDelimX('cite','\cite{','}') |
||||
|
|
||||
|
// this one is really not good
|
||||
|
//->addDelimX('html','<','>')->noNesting('html') // a link often contains // (e.g. http:// which clash with italics
|
||||
|
; |
||||
|
} // end create_wiki_parser
|
||||
|
|
||||
|
function gakowiki__doc() { |
||||
|
?>
|
||||
|
<a href="http://www.monperrus.net/martin/gakowiki-syntax">Syntax specification</a>:<br/> |
||||
|
**<b>this is bold</b>**<br/> |
||||
|
//<i>this is italic</i>//<br/>
|
||||
|
''<code>this is code</code>''<br/> |
||||
|
[[link to a page on this wiki]],[[http://www.google.fr|link to google]]<br/> |
||||
|
<h2>=====Section=====</h2> |
||||
|
<h3>====Subsection====</h3> |
||||
|
<?php |
||||
|
} // end function gakowiki__doc()
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
// end file
|
||||
|
?><?php
|
||||
|
|
||||
|
function printGk($comment) { |
||||
|
try { |
||||
|
$result = htmlentities($comment); |
||||
|
$result = str_replace('<pre>', '<pre>', $result); |
||||
|
$result = str_replace('</pre>', '</pre>', $result); |
||||
|
// removes lines prefixed "*" often used to have nice API comments
|
||||
|
$result = preg_replace('/^.*?\*/m', '', $result); |
||||
|
return '<pre>'.$result.'</pre>'; |
||||
|
//return gk_wiki2html($comment);
|
||||
|
} catch (GakoParserException $e) {return '<pre>'.$comment.'</pre>';} |
||||
|
} |
||||
|
|
||||
|
/** outputs the API doc of the function called $fname */ |
||||
|
function printDocFuncName($fname, $prefix='') { |
||||
|
$funcdeclared = new ReflectionFunction($fname); |
||||
|
return printDocFuncObj($funcdeclared, $prefix); |
||||
|
} |
||||
|
|
||||
|
function getComment($funcdeclared) { |
||||
|
$comment = trim(substr($funcdeclared->getDocComment(),3,-2)); |
||||
|
return $comment; |
||||
|
} |
||||
|
function printDocFuncObj($funcdeclared, $prefix='', $documented = true) { |
||||
|
$comment = trim(substr($funcdeclared->getDocComment(),3,-2)); |
||||
|
if ($documented && strlen($comment)<1) { return ''; } |
||||
|
$res = ""; |
||||
|
$res .= '<div>'; |
||||
|
$res .= '<b>'.$prefix.$funcdeclared->getName().'</b>'; |
||||
|
$res .= '<i>('.implode(', ',array_map('f',$funcdeclared->getParameters())).')</i> '; |
||||
|
$res .= printGk($comment); |
||||
|
$res .= '</div>'; |
||||
|
return $res; |
||||
|
} |
||||
|
|
||||
|
// Anonymous functions are available only since PHP 5.3.0
|
||||
|
function f($x){return '$'.$x->getName();} |
||||
|
|
||||
|
|
||||
|
/** this is printNewFunctions |
||||
|
the main limitation is that this does not fully work if there is an exit/die in the included script |
||||
|
*/ |
||||
|
function printNewFunctions($beforef) { |
||||
|
$afterf=get_defined_functions(); |
||||
|
|
||||
|
|
||||
|
foreach($afterf['user'] as $fname ) { |
||||
|
$funcdeclared = new ReflectionFunction($fname); |
||||
|
if (!in_array($fname,$beforef['user']) && $funcdeclared->getFileName()==realpath($_GET['file'])) { |
||||
|
printDocFunc($funcdeclared); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** outputs an HTML representation of the API doc of the class called $cname */ |
||||
|
function printAPIDocClass($cname, $documented = true) { |
||||
|
$res = ''; |
||||
|
$cdeclared = new ReflectionClass($cname); |
||||
|
//if ($cdeclared->getFileName()!=realpath($_GET['file'])) {continue;}
|
||||
|
$res .= '<b>'.$cdeclared->getName().'</b> '; |
||||
|
$comment = trim(substr($cdeclared->getDocComment(),3,-2)); |
||||
|
if ($documented && strlen($comment)<1) { return '';} |
||||
|
$res .= printGk($comment); |
||||
|
foreach($cdeclared->getMethods() as $method) { |
||||
|
$f = printDocFuncObj($method, " "/*,$cname.'.'*/, true); |
||||
|
if (strlen($f)>0) { |
||||
|
$res .= $f; |
||||
|
} |
||||
|
} |
||||
|
return "<div>".$res."</div><hr/>"; |
||||
|
} |
||||
|
|
||||
|
function getCodeSnippetsInClass($cname) { |
||||
|
$res = array(); |
||||
|
$cdeclared = new ReflectionClass($cname); |
||||
|
$res[] = _getCodeSnippet($cdeclared); |
||||
|
foreach($cdeclared->getMethods() as $method) { |
||||
|
$res[] = _getCodeSnippet($method); |
||||
|
} |
||||
|
return $res; |
||||
|
} |
||||
|
|
||||
|
/** returns the snippet of a function */ |
||||
|
function getCodeSnippet($function_name) { |
||||
|
$funcdeclared = new ReflectionFunction($function_name); |
||||
|
return _getCodeSnippet($funcdeclared); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
function _getCodeSnippet($obj) { |
||||
|
$comment = getComment($obj); |
||||
|
if (preg_match('/<pre>(.*)<\/pre>/is', $comment, $matches)) { |
||||
|
return $matches[1]; |
||||
|
} |
||||
|
return ""; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
function getAllSnippetsInFile($file) { |
||||
|
$res = array(); |
||||
|
foreach (get_functions_in($file) as $f) { |
||||
|
$x=getCodeSnippet($f); |
||||
|
if (strlen($x)>0) $res[] = $x; |
||||
|
} |
||||
|
|
||||
|
foreach (get_classes_in($file) as $klass) { |
||||
|
foreach (getCodeSnippetsInClass($klass) as $x) { |
||||
|
if (strlen($x)>0) $res[] = $x; |
||||
|
} |
||||
|
} |
||||
|
return $res; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
?>
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue