/** * Convert a string to UTF-8 if needed * @param string String to be converted * @return string UTF-8 encoded string * * @author Florian Aders <*****@*****.**> */ function convertUtf8($string) { if (!isUtf8($string)) { $string = utf8_encode($string); } return addslashes($string); }
/** * Converts a string to UTF-8 encoding. * * @param string $string * @return string */ function convertToUtf8($string) { if (!is_string($string)) { return ''; } if (!isUtf8($string)) { if (function_exists('mb_convert_encoding')) { $string = mb_convert_encoding($string, 'UTF-8', 'GBK'); } else { $string = iconv('GBK', 'UTF-8//IGNORE', $string); } } return $string; }
function encodeChar($char) { // get template global $substr; // write prefix for char code $result = '"\\\\"'; // if character is utf-8 if (isUtf8($char)) { // get utf-8 code without quotes and slash $code = substr(json_encode($char), 2, -1); } else { // convert decimal to octal $code = base_convert(ord($char), 10, 8); // fix code if digist < 3 $code = str_pad($code, 3, 0, STR_PAD_LEFT) . ''; } // convert string to array $digits = str_split($code); for ($i = 0; $i < count($digits); $i++) { // encode code $result .= '+$.' . array_search($digits[$i], $substr); } return $result; }
/** * Generates HTML manual as PHPDocFill.html file in the same folder */ static function AJAX_Manual() { // OK, what do we do? // 1. scan files $list = RecursiveScanDir(__DIR__); usort($list, "strnatcasecmp"); // 2. for each file, we'll gather the insides $allblocks = array(); $files = array(); $bid = 0; foreach ($list as $file) { $source = @file_get_contents($file); if (!$source) { continue; } $fileblocks = DocBlock::ParseCode($source); if ($fileblocks === null) { continue; } foreach ($fileblocks as $block) { $bid++; $block->filename = $file; $block->id = $bid; $blockkey = $block->GetName() . " [{$block->filename}] {$block->line}"; // a unique identifier to sort the classes $allblocks[$block->GetClass()][$blockkey] = $block; $files[$file][] = $block; } } // 3. generate list of files output if ($_POST['Dpage']) { $fileout = "<div id='files'>"; foreach ($files as $filename => $blocks) { // Find page docblock $pagecomment = ""; foreach ($blocks as $block) { if ($block->type == BLOCK_PAGE) { $pagecomment = nl2br(str_replace("\n\n", "\n", trim($block->shortDescription . "\n" . $block->longDescription . "\n<i>" . $block->tags . "</i>"))); } } $pagecomment = !isUtf8($pagecomment) ? utf8_encode($pagecomment) : $pagecomment; $elements = array(); // Prepare list of contained elements foreach ($blocks as $block) { $class = $block->GetClass(); $name = $block->GetName(); $bid = $block->id; $documented = $block->valid ? "" : "Undocumented"; if ($name) { $elements[$class][] = "<a href='#{$class}{$bid}' title='{$documented}' class='{$documented}'><span class='objname'>{$name}</span></a>"; } } // Prepare for output $elementsout = ""; foreach ($elements as $class => $blocks) { $elementsout .= "<span class='{$class} bold'>{$class}</span>" . implode(", ", $blocks) . "<br />"; } $pagecomment = $pagecomment ? "<div class='pagecomment'>{$pagecomment}</div>" : ""; $id = dechex(crc32($filename)); $fileout .= "\n\t\t\t\t\t<div class='file'>\n\t\t\t\t\t\t<a name='file{$id}'><div class='filename'>{$filename}</div>\n\t\t\t\t\t\t{$pagecomment}\n\t\t\t\t\t\t<div class='contains'>{$elementsout}</div>\n\t\t\t\t\t</div>\n\t\t\t\t"; } $fileout .= "</div>"; $countfiles = count($files); $tabfile = "<li><a href='#files'>Files ({$countfiles})</a></li>"; } // 4. Generate list of classes if ($_POST['Dclas']) { $classout = "<div id='classes'>"; if (!is_array($allblocks['class'])) { $allblocks['class'] = array(); } uksort($allblocks['class'], "strnatcasecmp"); foreach ($allblocks['class'] as $block) { // Prepare docs $pagecomment = $block->OutputComment(); // Prepare information $bid = $block->id; $name = $block->GetName(); $classname = $block->GetClass(); $fid = dechex(crc32($block->filename)); $filename = $block->filename; $line = $block->line; // Prepare for output $classout .= "\n\t\t\t\t\t<div class='file'>\n\t\t\t\t\t\t<a name='{$classname}{$bid}'></a><div class='classname'>{$name}</div>\n\t\t\t\t\t\tFrom: <a href='#file{$fid}'>{$filename}</a> (line {$line})<br />\n\t\t\t\t\t\t<pre>{$pagecomment}</pre>\n\t\t\t\t\t</div>\n\t\t\t\t"; } $classout .= "</div>"; $countclasses = count($allblocks['class']); $tabclasses = "<li><a href='#classes'>Classes ({$countclasses})</a></li>"; } // 5. Generate list of functions if ($_POST['Dfunc']) { $fnout = "<div id='functions'>"; if (!is_array($allblocks['function'])) { $allblocks['function'] = array(); } uksort($allblocks['function'], "strnatcasecmp"); foreach ($allblocks['function'] as $block) { // Prepare docs $pagecomment = $block->OutputComment(); // Prepare information $bid = $block->id; $name = $block->GetName(); $classname = $block->GetClass(); $fid = dechex(crc32($block->filename)); $filename = $block->filename; $code = $block->associatedHlCode; $line = $block->line; // Prepare for output $fnout .= "\n\t\t\t\t\t<div class='file'>\n\t\t\t\t\t\t<a name='{$classname}{$bid}'></a><div class='fnname'>{$name}</div>\n\t\t\t\t\t\tFrom: <a href='#file{$fid}'>{$filename}</a> (line {$line})<br />\n\t\t\t\t\t\tContext: {$code}<br />\n\t\t\t\t\t\t<pre>{$pagecomment}</pre>\n\t\t\t\t\t</div>\n\t\t\t\t"; } $fnout .= "</div>"; $countfunctions = count($allblocks['function']); $tabfunctions = "<li><a href='#functions'>Functions ({$countfunctions})</a></li>"; } // 6. Generate list of interfaces if ($_POST['Dinte']) { $intout = "<div id='interfaces'>"; if (!is_array($allblocks['interface'])) { $allblocks['interface'] = array(); } uksort($allblocks['interface'], "strnatcasecmp"); foreach ($allblocks['interface'] as $block) { // Prepare docs $pagecomment = $block->OutputComment(); // Prepare information $bid = $block->id; $name = $block->GetName(); $classname = $block->GetClass(); $fid = dechex(crc32($block->filename)); $filename = $block->filename; $line = $block->line; // Prepare for output $intout .= "\n\t\t\t\t\t<div class='file'>\n\t\t\t\t\t\t<a name='{$classname}{$bid}'></a><div class='intname'>{$name}</div>\n\t\t\t\t\t\tFrom: <a href='#file{$fid}'>{$filename}</a> (line {$line})<br />\n\t\t\t\t\t\t<pre>{$pagecomment}</pre>\n\t\t\t\t\t</div>\n\t\t\t\t"; } $intout .= "</div>"; $countint = count($allblocks['interface']); $tabint = "<li><a href='#interfaces'>Interfaces ({$countint})</a></li>"; } // 7. Generate list of constants if ($_POST['Dcons']) { $defout = "<div id='define'>"; if (!is_array($allblocks['define'])) { $allblocks['define'] = array(); } uksort($allblocks['define'], "strnatcasecmp"); foreach ($allblocks['define'] as $block) { // Prepare docs $pagecomment = $block->OutputComment(); // Prepare information $bid = $block->id; $name = $block->GetName(); $classname = $block->GetClass(); $fid = dechex(crc32($block->filename)); $filename = $block->filename; $line = $block->line; $code = $block->associatedHlCode; // Prepare for output $defout .= "\n\t\t\t\t\t<div class='file'>\n\t\t\t\t\t\t<a name='{$classname}{$bid}'></a><div class='defname'>{$name}</div>\n\t\t\t\t\t\tFrom: <a href='#{$classname}{$fid}'>{$filename}</a> (line {$line})<br />\n\t\t\t\t\t\tContext: {$code}<br />\n\t\t\t\t\t\t<pre>{$pagecomment}</pre>\n\t\t\t\t\t</div>\n\t\t\t\t"; } $defout .= "</div>"; $countdef = count($allblocks['define']); $tabdef = "<li><a href='#define'>Constants ({$countdef})</a></li>"; } // 8. Generate list of constants if ($_POST['Dincl']) { $incout = "<div id='include'>"; if (!is_array($allblocks['include'])) { $allblocks['include'] = array(); } uksort($allblocks['include'], "strnatcasecmp"); foreach ($allblocks['include'] as $block) { // Prepare docs $pagecomment = $block->OutputComment(); // Prepare information $bid = $block->id; $name = $block->GetName(); $classname = $block->GetClass(); $fid = dechex(crc32($block->filename)); $filename = $block->filename; $line = $block->line; $code = $block->associatedHlCode; // Prepare for output $incout .= "\n\t\t\t\t\t<div class='file'>\n\t\t\t\t\t\t<a name='{$classname}{$bid}'></a><div class='incname'>{$name}</div>\n\t\t\t\t\t\tFrom: <a href='#{$classname}{$fid}'>{$filename}</a> (line {$line})<br />\n\t\t\t\t\t\tContext: {$code}<br />\n\t\t\t\t\t\t<pre>{$pagecomment}</pre>\n\t\t\t\t\t</div>\n\t\t\t\t"; } $incout .= "</div>"; $countinc = count($allblocks['include']); $tabinc = "<li><a href='#include'>Includes ({$countinc})</a></li>"; } // FINAL STEP: Prepare presentation $date = date("F j, Y, H:i"); $out = "<html>\n\t<head>\n\t\t<title>Documentation manual generated by PHPDocFill</title>\n\t\t<!-- Include jQuery & jQuery UI 鏩 -->\n\t\t<meta charset='utf-8' />\n\t\t<link rel='stylesheet' href='http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css' />\n\t\t<link rel='stylesheet' href='http://fonts.googleapis.com/css?family=Oxygen:400,700|PT+Sans+Narrow:700' />\n\t\t<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js'></script>\n\t\t<script type='text/javascript' src='http://code.jquery.com/ui/1.10.3/jquery-ui.js'></script>\n\t\t<style>\n\t\t\tbody{ margin:20px;padding:0;font-size: 12px;font-family: Oxygen, Verdana, Tahoma, Arial;color: black;background: white;}\n\t\t\t.file{ font-family: Oxygen, Verdana; margin: 15px; }\n\t\t\t.filename { font: bold 150% 'PT Sans Narrow', sans-serif; color: #666; letter-spacing: 1.4px; border-bottom: 1px solid #1365ad; }\n\t\t\t.classname { font: bold 150% 'PT Sans Narrow', sans-serif; color: #666; letter-spacing: 1.4px; border-bottom: 1px solid #ad1365; }\n\t\t\t.fnname { font: bold 150% 'PT Sans Narrow', sans-serif; color: #666; letter-spacing: 1.4px; border-bottom: 1px solid #13ad65; }\n\t\t\t.intname { font: bold 150% 'PT Sans Narrow', sans-serif; color: #666; letter-spacing: 1.4px; border-bottom: 1px solid #f4ba3e; }\n\t\t\t.defname { font: bold 150% 'PT Sans Narrow', sans-serif; color: #666; letter-spacing: 1.4px; border-bottom: 1px solid #d375e3; }\n\t\t\t.incname { font: bold 150% 'PT Sans Narrow', sans-serif; color: #666; letter-spacing: 1.4px; border-bottom: 1px solid #7c90aa; }\n\t\t\t.generated { font-size: 10px; margin: 10px; text-align: center; } \n\t\t\t.bold { font-weight: bold; }\n\t\t\t.class { display: inline-block; width: 65px; color: #1365ad; !important; }\n\t\t\t.function { display: inline-block; width: 65px; color: #1365ad !important; }\n\t\t\t.interface { display: inline-block; width: 65px; color: #1365ad !important; }\n\t\t\t.include { display: inline-block; width: 65px; color: #1365ad !important; }\n\t\t\t.define { display: inline-block; width: 65px; color: #1365ad !important; }\n\t\t\t.objname { font-weight: normal !important; }\n\t\t\th1 { font: bold 300% 'PT Sans Narrow', sans-serif; color: #666; letter-spacing: 1.4px; border-bottom: solid 2px #1365ad; height: 45px; text-transform: uppercase; margin-top: -10px; margin-bottom: 15px; }\n\t\t\ta { font-family: Oxygen, Verdana; text-decoration: none; }\n\t\t\tpre { margin: 0; }\n\t\t\t.pagecomment { margin: 2px; color:#922e2e; font-family: Courier New; }\n\t\t\t.asterisk { color: red; }\n\t\t\t.Undocumented { font-style: italic; color: #777 !important; }\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<h1>My Project</h1>\n\t\t<div id='tabs'>\n\t\t\t<ul>\n\t\t\t\t{$tabfile}\n\t\t\t\t{$tabfunctions}\n\t\t\t\t{$tabclasses}\n\t\t\t\t{$tabint}\n\t\t\t\t{$tabdef}\n\t\t\t\t{$tabinc}\n\t\t\t</ul>\n\t\t\t\n\t\t\t{$fileout}\n\t\t\t{$fnout}\n\t\t\t{$classout}\n\t\t\t{$intout}\n\t\t\t{$defout}\n\t\t\t{$incout}\n\t\t</div>\n\t\t\n\t\t<div class='generated'>\n\t\t\tGenerated by <a href='http://cnedelcu.net/phpdocfill/' style='color:black;'>PHPDocFill</a> - {$date}\n\t\t</div>\n\t\t\n\t\t<script>\n\t\tjQuery.fn.extend({\n\t\t scrollToMe: function () {\n\t\t\tif (jQuery(this).length < 1) return;\n\t\t var y = jQuery(this).offset().top;\n\t\t jQuery('html,body').animate({scrollTop: y}, 100);\n\t\t}});\n\t\t\n\t\tvar elementToScroll = '';\n\t\tfunction DoScrollTo() {\n\t\t\t\$(elementToScroll).scrollToMe();\n\t\t}\n\t\t\n\t\t\$(function() {\n\t\t\t\$('#tabs').tabs();\n\t\t\t\$('a').click(function(e) {\n\t\t\t\tvar link = \$(this).attr('href');\n\t\t\t\tvar index = 0;\n\t\t\t\tif (link.indexOf('#function') > -1) \n\t\t\t\t\tindex = \$('#functions').index();\n\t\t\t\telse if (link.indexOf('#class') > -1) \n\t\t\t\t\tindex = \$('#classes').index();\n\t\t\t\telse if (link.indexOf('#interface') > -1) \n\t\t\t\t\tindex = \$('#interfaces').index();\n\t\t\t\telse if (link.indexOf('#include') > -1) \n\t\t\t\t\tindex = \$('#include').index();\n\t\t\t\telse if (link.indexOf('#define') > -1) \n\t\t\t\t\tindex = \$('#define').index();\n\t\t\t\telse if (link.indexOf('#file') > -1) {\n\t\t\t\t\t// File links: a bit different\n\t\t\t\t\tindex = \$('#files').index();\n\t\t\t\t\t\$('#tabs').tabs('option', 'active', index-1);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse \n\t\t\t\t\treturn true;\n\n\t\t\t\t\$('#tabs').tabs('option', 'active', index-1);\n\t\t\t\telementToScroll = '[name='+link.replace('#','')+']';\n\t\t\t\tsetTimeout('DoScrollTo()',100);\n\t\t\t});\n\t\t});\n\t\t</script>\n\t</body>\n</html>\n\t\t"; // Save file if (!file_put_contents("PHPDocFill.html", $out)) { die("The file could not be saved. You might not have the proper writing permissions in the " . getcwd() . " folder."); } die("The manual has been generated and saved as PHPDocFill.html.<br /><a href='PHPDocFill.html' target=_blank>Click here to view this file in your browser</a>"); }