/** * Execute one or multiple migrations. */ public function perform() { if (!$this->migrator()->isConfigured()) { if ($this->option('quiet')) { $this->writeln("<comment>Migrator does not configured, skipping.</comment>"); } else { $this->writeln("<fg=red>Migrator does not configured, unable to proceed.</fg=red`>"); } return; } if (!$this->verifyEnvironment()) { //Making sure we can safely migrate in this environment return; } $found = false; $count = $this->option('one') ? 1 : PHP_INT_MAX; while ($count > 0 && ($migration = $this->migrator()->run())) { $found = true; $count--; $this->writeln(interpolate("<info>Migration <comment>{name}</comment> was successfully executed.</info>", ['name' => $migration->getStatus()->getName()])); } if (!$found) { $this->writeln("<fg=yellow>No outstanding migrations were found.</fg=yellow>"); } }
static function makeGradient($start, $end, $steps) { $theColorBegin = hexdec($start); $theColorEnd = hexdec($end); $theR0 = ($theColorBegin & 0xff0000) >> 16; $theG0 = ($theColorBegin & 0xff00) >> 8; $theB0 = ($theColorBegin & 0xff) >> 0; $theR1 = ($theColorEnd & 0xff0000) >> 16; $theG1 = ($theColorEnd & 0xff00) >> 8; $theB1 = ($theColorEnd & 0xff) >> 0; function interpolate($pBegin, $pEnd, $pStep, $pMax) { if ($pBegin < $pEnd) { return ($pEnd - $pBegin) * ($pStep / $pMax) + $pBegin; } else { return ($pBegin - $pEnd) * (1 - $pStep / $pMax) + $pEnd; } } $grad = array(); for ($i = 0; $i <= $steps; $i++) { $theR = interpolate($theR0, $theR1, $i, $steps); $theG = interpolate($theG0, $theG1, $i, $steps); $theB = interpolate($theB0, $theB1, $i, $steps); $theVal = ($theR << 8 | $theG) << 8 | $theB; $grad[] = sprintf("#%06X", $theVal); } return $grad; }
function save_log($action, $array = []) { $CI =& get_instance(); $CI->load->model('my_log'); $log = ['action' => interpolate($action, $array), 'ip' => $CI->input->ip_address()]; $CI->my_log->save($log); }
function gradient(&$colorindex, $pos, $theColorBegin, $theColorEnd, $theNumSteps) { //just check function so that the values are not less $theColorBegin = $theColorBegin >= 0x0 && $theColorBegin <= 0xffffff ? $theColorBegin : 0x0; $theColorEnd = $theColorEnd >= 0x0 && $theColorEnd <= 0xffffff ? $theColorEnd : 0xffffff; $theNumSteps = $theNumSteps > 0 && $theNumSteps < 256 ? $theNumSteps : 256; $theR0 = ($theColorBegin & 0xff0000) >> 16; $theG0 = ($theColorBegin & 0xff00) >> 8; $theB0 = ($theColorBegin & 0xff) >> 0; $theR1 = ($theColorEnd & 0xff0000) >> 16; $theG1 = ($theColorEnd & 0xff00) >> 8; $theB1 = ($theColorEnd & 0xff) >> 0; // generate gradient swathe now //echo "<table width='100%' cellpadding='8' style='border-collapse:collapse'>\n"; for ($i = 0; $i <= $theNumSteps; $i++) { $theR = interpolate($theR0, $theR1, $i, $theNumSteps); $theG = interpolate($theG0, $theG1, $i, $theNumSteps); $theB = interpolate($theB0, $theB1, $i, $theNumSteps); $theVal = ($theR << 8 | $theG) << 8 | $theB; $theTDTag = sprintf("<td bgcolor='#%06X'>", $theVal); $theTDARTag = sprintf("<td bgcolor='#%06X' align='right'>", $theVal); $temp = dechex($theVal); while (strlen($temp) < 6) { $temp = '0' . $temp; } $colorindex[$i + $pos] = $temp; $theFC0Tag = "<font color='#000000'>"; $theFC1Tag = "<font color='#ffffff'>"; //printf("<tr>$theTDTag$theFC0Tag%d</font></td>$theTDTag$theFC0Tag%d%%</font></td>$theTDARTag$theFC0Tag%d</font></td>$theTDARTag$theFC0Tag%06X</font></td>", $i, ($i/$theNumSteps) * 100, $theVal, $theVal); //printf("$theTDTag$theFC1Tag%06X</font></td>$theTDTag$theFC1Tag%d</font></td>$theTDARTag$theFC1Tag%d%%</font></td>$theTDARTag$theFC1Tag%d</font></td></tr>\n", $theVal, $theVal, ($i/$theNumSteps) * 100, $i); } //echo "</table>\n"; }
public function getLinearPosition($p, $i, $points) { $angleBetweenPoints = 2 * M_PI / count($points); $fraction = $i / $this->segments; $startAngle = $p * $angleBetweenPoints; $endAngle = ($p + 1) * $angleBetweenPoints; $startPositionX = sin($startAngle) * $points[$p]; $startPositionY = -cos($startAngle) * $points[$p]; $endPositionX = sin($endAngle) * $points[$p + 1]; $endPositionY = -cos($endAngle) * $points[($p + 1) % count($points)]; return [interpolate($fraction, $startPositionX, $endPositionX), interpolate($fraction, $startPositionY, $endPositionY)]; }
/** * @param InspectionsConfig $config * @param ODM $odm * @param ORM $orm */ public function perform(InspectionsConfig $config, ODM $odm, ORM $orm) { $inspector = $this->createInspector($config, $odm, $orm); if ($this->isVerbosity()) { $table = $this->tableHelper(['Entity', 'Rank', 'Fields', 'Fillable', 'Validated']); foreach ($inspector->getInspections() as $inspection) { $table->addRow([$inspection->getName(), $this->describeRank($inspection->getRank()), $inspection->countFields(), $inspection->countFillable(), $inspection->countValidated()]); } $table->render(); $this->writeln(""); } $this->writeln(interpolate("Inspected entities <fg=yellow>{count}</fg=yellow>, average rank {level} ({rank}).", ['count' => number_format($inspector->countInspections()), 'level' => $this->describeRank($inspector->getRank()), 'rank' => number_format($inspector->getRank(), 2)])); }
/** * Execute one or multiple migrations. */ public function perform() { if (!$this->verifyConfigured() || !$this->verifyEnvironment()) { return; } $found = false; $count = $this->option('one') ? 1 : PHP_INT_MAX; while ($count > 0 && ($migration = $this->migrator->run())) { $found = true; $count--; $this->writeln(interpolate("<info>Migration <comment>{name}</comment> was successfully executed.</info>", ['name' => $migration->getMeta()->getName()])); } if (!$found) { $this->writeln("<fg=red>No outstanding migrations were found.</fg=red>"); } }
/** * Perform command. */ public function perform() { if (!$this->verifyEnvironment()) { //Making sure we can safely migrate in this environment return; } $found = false; $count = !$this->option('all') ? 1 : PHP_INT_MAX; while ($count > 0 && ($migration = $this->migrator()->rollback())) { $found = true; $count--; $this->writeln(interpolate("<info>Migration <comment>{name}</comment> was successfully rolled back.</info>", ['name' => $migration->getStatus()->getName()])); } if (!$found) { $this->writeln("<fg=red>No executed migrations were found.</fg=red>"); } }
/** * Check if current environment is safe to run migration. * * @return bool */ protected function verifyEnvironment() { if ($this->option('safe')) { //Safe to run return true; } if (in_array($this->core->environment(), $this->migrator()->config()['environments'])) { //Safe to run return true; } $this->writeln(interpolate("<fg=red>Application environment '{environment}' does not allowed to run migrations.</fg=red>", ['environment' => $this->core->environment()])); if (!$this->ask()->confirm("Do you wish to continue?")) { $this->writeln("<comment>Cancelling operation.</comment>"); return false; } return true; }
/** * @param number $factor * @return string */ public function color($factor) { $factor = max(0.0, min(1.0, $factor)); $color1 = $color2 = $this->gradient['0.0']; $f1 = 0; foreach ($this->gradient as $f => $color) { if ($factor <= $f) { $color2 = $color; if ($f1 != $f) { $factor = ($factor - $f1) / ($f - $f1); } else { $factor = $f; } break; } $color1 = $color; $f1 = $f; } return hex2str(interpolate($color1, $color2, $factor)); }
function color_pie_chart($ret) { $theColorBegin = hexdec('BC2800'); $theColorEnd = hexdec('D8D0D0'); $theR0 = ($theColorBegin & 0xff0000) >> 16; $theG0 = ($theColorBegin & 0xff00) >> 8; $theB0 = ($theColorBegin & 0xff) >> 0; $theR1 = ($theColorEnd & 0xff0000) >> 16; $theG1 = ($theColorEnd & 0xff00) >> 8; $theB1 = ($theColorEnd & 0xff) >> 0; $ix = 0; $theNumSteps = count($ret); foreach ($ret as $ret_k => $ret_v) { $theR = interpolate($theR0, $theR1, $ix, $theNumSteps); $theG = interpolate($theG0, $theG1, $ix, $theNumSteps); $theB = interpolate($theB0, $theB1, $ix, $theNumSteps); $theVal = ($theR << 8 | $theG) << 8 | $theB; $theVal = sprintf("#%06X", $theVal); $ret[$ret_k]['color'] = $theVal; $ix++; } return $ret; }
foreach (array_reverse($stacktrace) as $index => $trace) { if (empty($trace['file']) && isset($stacktrace[$index - 1]['file'])) { $trace['file'] = $stacktrace[$index - 1]['file']; $trace['line'] = $stacktrace[$index - 1]['line']; } if (!isset($stacktrace[$index + 1])) { $trace['file'] = $exception->getFile(); $trace['line'] = $exception->getLine(); } if (!isset($trace['function']) || !isset($trace['file'])) { continue; } $function = '<strong>' . $trace['function'] . '</strong>'; if (isset($trace['type']) && isset($trace['class'])) { $reflection = new ReflectionClass($trace['class']); $function = interpolate("<span title=\"{title}\">{class}</span>{type}{function}", ['title' => $reflection->getName(), 'class' => $reflection->getShortName(), 'type' => $trace['type'], 'function' => $function]); } $arguments = []; if (isset($trace['args'])) { $arguments = $argumenter($trace['args']); } ?> <div class="call"> <div class="function"> <?php echo $function; ?> (<span class="arguments"><?php echo join(', ', $arguments); ?> </span>)
/** * @param \Throwable $exception * @return string */ public static function createMessage($exception) { return interpolate('{exception}: {message} in {file} at line {line}', ['exception' => get_class($exception), 'message' => $exception->getMessage(), 'file' => $exception->getFile(), 'line' => $exception->getLine()]); }
foreach ($polygons as $index => $item) { $item['start'] = $item['colors'][0]; $item['index'] = $index; $item['animate'] = ''; if (count($item['colors']) > 1) { $item['colors'][] = $item['colors'][0]; $item['colors'] = implode('; ', $item['colors']); $item['begin'] = rand(0, 2); $item['dur'] = rand(3, 6); $item['animate'] = interpolate($animateTemplate, $item); } $templateData['polygons'][] = interpolate($polyTemplate, $item); } $templateData['polygons'] = implode("\n", $templateData['polygons']); $svg = file_get_contents('template.svg'); $svg = interpolate($svg, $templateData); file_put_contents('test.svg', $svg); /** * Interpolates context values into the message placeholders. */ function interpolate($message, array $context = array()) { // build a replacement array with braces around the context keys $replace = array(); foreach ($context as $key => $val) { $replace['{' . $key . '}'] = $val; } // interpolate replacement values into the message and return return strtr($message, $replace); } function hexPoints($start)
function getSeverity($value, $steps, $startHex, $endHex) { $x = round($value); $start = hexdec($startHex); $end = hexdec($endHex); if ($x >= $steps) { $x = $steps; } $theR0 = ($start & 0xff0000) >> 16; $theG0 = ($start & 0xff00) >> 8; $theB0 = ($start & 0xff) >> 0; $theR1 = ($end & 0xff0000) >> 16; $theG1 = ($end & 0xff00) >> 8; $theB1 = ($end & 0xff) >> 0; $theR = interpolate($theR0, $theR1, $x, $steps); $theG = interpolate($theG0, $theG1, $x, $steps); $theB = interpolate($theB0, $theB1, $x, $steps); $theVal = ($theR << 8 | $theG) << 8 | $theB; $result = sprintf("#%06X", $theVal); return $result; }
function draw($j) { global $config; $quantum = 75; $spacing = 10; $half_spacing = $spacing / 2; $aspect_ratio = 0.8; $cell_w = $quantum * $aspect_ratio + $spacing; $cell_h = $quantum + $spacing; echo '<div style="top:' . $half_spacing . 'px;left:' . $half_spacing . 'px;position:absolute;">'; // Use a colour gradient to colour cells $theColorBegin = 0xdddddd; $theColorEnd = 0x0; $theR0 = ($theColorBegin & 0xff0000) >> 16; $theG0 = ($theColorBegin & 0xff00) >> 8; $theB0 = ($theColorBegin & 0xff) >> 0; $theR1 = ($theColorEnd & 0xff0000) >> 16; $theG1 = ($theColorEnd & 0xff00) >> 8; $theB1 = ($theColorEnd & 0xff) >> 0; $n = count($j->sizes); for ($i = 0; $i < $n; $i++) { $num_rows = ceil($j->sizes[$i] / $j->rects[$i]->w); // Background colour $theR = interpolate($theR0, $theR1, $i, $n); $theG = interpolate($theG0, $theG1, $i, $n); $theB = interpolate($theB0, $theB1, $i, $n); $theVal = ($theR << 8 | $theG) << 8 | $theB; $colour = sprintf("background-color: #%06X; ", $theVal); // Cell holding quanta echo '<div style="position:absolute;' . 'left:' . $j->rects[$i]->x * $cell_w . 'px;' . 'top:' . $j->rects[$i]->y * $cell_h . 'px;' . 'width:' . $j->rects[$i]->w * $cell_w . 'px;' . 'height:' . $j->rects[$i]->h * $cell_h . 'px;' . 'background: -webkit-gradient(linear, left top, right bottom, from(#CCDEFD), to(#FFFFFF));' . 'background: -moz-linear-gradient(-45deg, #aaa, #fff);' . 'filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr=\'#aaaaaa\', EndColorStr=\'#ffffff\');' . '">'; // Draw individual quanta $k = 0; $row = 0; $col = 0; while ($k < $j->sizes[$i]) { echo '<div style="position:absolute;' . 'left:' . ($col * $cell_w + $half_spacing) . 'px;' . 'top:' . ($row * $cell_h + $half_spacing) . 'px;' . 'width:' . $quantum * $aspect_ratio . 'px;' . 'height:' . $quantum . 'px;' . 'overflow:hidden;' . 'line-height:' . $quantum . 'px;' . 'text-align:center;' . 'font-family:Arial,Verdana,sans-serif;font-size:10px;' . '"' . '>'; if (isset($j->rects[$i]->ids)) { echo '<a href="id/' . $j->rects[$i]->ids[$k] . '">'; echo '<img style="vertical-align:middle;" src="' . $config['web_server'] . $config['web_root'] . 'thumbnail.php?id=' . $j->rects[$i]->ids[$k] . '" height="' . $cell_h . '" border="0" />'; echo '</a>'; } echo '</div>'; $col++; if ($col == $j->rects[$i]->w) { $row++; $col = 0; } $k++; } // see http://stackoverflow.com/questions/3793204/click-through-div-with-an-alpha-channel // pointer-events:none; echo '<div style="pointer-events:none;position:absolute;z-index:10;font-size:16px;font-weight:bold;font-family:Arial;overflow:hidden;text-overflow: ellipsis;opacity:0.6;' . 'width:' . $j->rects[$i]->w * $cell_w . 'px;' . '">' . $j->rects[$i]->label . '</div>'; echo '</div>'; } echo '</div>'; }
function test_interpolate() { $a = array('x' => 'test', 'y' => "foo'bar", 'z' => 'jan";fu'); $this->assertTrue(interpolate('', $a) == ''); $this->assertTrue(interpolate('x', $a) == 'x'); $this->assertTrue(interpolate('$x', $a) == $a['x']); $this->assertTrue(interpolate('$y', $a) == $a['y']); $this->assertTrue(interpolate('$z', $a) == $a['z']); $this->assertTrue(interpolate('"$z', $a) == '"' . $a['z']); }
<?php ## Обработка плейсхолдеров function interpolate($message, array $context = []) { // Построение массива подстановки с фигурными скобками // вокруг значений ключей массива context. $replace = []; foreach ($context as $key => $val) { $replace['{' . $key . '}'] = $val; } // Подстановка значений в сообщение и возврат результата. return strtr($message, $replace); } // Сообщение с плейсхолдером, имя которого обрамлено // фигурными скобками. $message = "User {username} created"; // Массив context с данными для замены плейсхолдера на // итоговое значение. $context = ['username' => 'bolivar']; // Результат: "User bolivar created" echo interpolate($message, $context);
$theNumSteps = $theNumSteps > 0 && $theNumSteps < 256 ? $theNumSteps : 16; printf("<p>values are: (color begin: 0x%06X), (color end: 0x%06X), (number of steps: %d)</p>\n", $theColorBegin, $theColorEnd, $theNumSteps); $theR0 = ($theColorBegin & 0xff0000) >> 16; $theG0 = ($theColorBegin & 0xff00) >> 8; $theB0 = ($theColorBegin & 0xff) >> 0; $theR1 = ($theColorEnd & 0xff0000) >> 16; $theG1 = ($theColorEnd & 0xff00) >> 8; $theB1 = ($theColorEnd & 0xff) >> 0; // return the interpolated value between pBegin and pEnd function interpolate($pBegin, $pEnd, $pStep, $pMax) { if ($pBegin < $pEnd) { return ($pEnd - $pBegin) * ($pStep / $pMax) + $pBegin; } else { return ($pBegin - $pEnd) * (1 - $pStep / $pMax) + $pEnd; } } // generate gradient swathe now echo "<table width='100%' cellpadding='8' style='border-collapse:collapse'>\n"; for ($i = 0; $i <= $theNumSteps; $i++) { $theR = interpolate($theR0, $theR1, $i, $theNumSteps); $theG = interpolate($theG0, $theG1, $i, $theNumSteps); $theB = interpolate($theB0, $theB1, $i, $theNumSteps); $theVal = ($theR << 8 | $theG) << 8 | $theB; $theTDTag = sprintf("<td bgcolor='#%06X'>", $theVal); $theTDARTag = sprintf("<td bgcolor='#%06X' align='right'>", $theVal); $theFC0Tag = "<font color='#000000'>"; $theFC1Tag = "<font color='#ffffff'>"; printf("\"%06X\",<br/>", $theVal); } echo "</table>\n";
// the treemap appear below the treemap (rather than being obscured). echo '<div style="color:white;font-family:Arial;position:relative;font-size:10px;height:' . $tm_height . 'px;margin-left:20px">'; $theNumSteps = count($items); $count = 0; foreach ($items as $i) { // Note that each treemap cell has position:absolute echo '<div id="div' . $i->id . '" class="cell" style="opacity:0.6;filter:alpha(opacity=60);position: absolute; overflow:hidden;text-align:center;'; echo ' left:' . $i->bounds->x . 'px;'; echo ' top:' . $i->bounds->y . 'px;'; echo ' width:' . $i->bounds->w . 'px;'; echo ' height:' . $i->bounds->h . 'px;'; echo ' border:1px solid white;'; // Background colour $theR = interpolate($theR0, $theR1, $count, $theNumSteps); $theG = interpolate($theG0, $theG1, $count, $theNumSteps); $theB = interpolate($theB0, $theB1, $count, $theNumSteps); $theVal = ($theR << 8 | $theG) << 8 | $theB; printf("background-color: #%06X; ", $theVal); echo '" '; // Mouse activity echo ' onMouseOver="mouse_over(\'div' . $i->id . '\');" '; echo ' onMouseOut="mouse_out(\'div' . $i->id . '\');" '; // Link to drill down if (!$i->isLeaf) { echo ' onClick="document.location=\'?node=' . $i->id; if (!$show_text) { echo '&showtext=false'; } echo '\';" '; } echo ' >';
<animate attributeName="fill" values="{colors};" repeatCount="indefinite" begin="{delay}s" dur="{duration}s" /></polygon> '; foreach ($points as $item) { $c = array_merge([], $colors); shuffle($c); $c[] = $c[0]; $values = ['start' => $c[0], 'colors' => implode('; ', $c), 'middle' => rand(4, 6), 'delay' => rand(0, 2), 'duration' => rand(3, 6)]; $values['points'] = $item; while ($values['start'] == $values['end']) { $values['end'] = $colors[array_rand($colors)]; } echo interpolate($template, $values); } /** * Interpolates context values into the message placeholders. */ function interpolate($message, array $context = array()) { // build a replacement array with braces around the context keys $replace = array(); foreach ($context as $key => $val) { $replace['{' . $key . '}'] = $val; } // interpolate replacement values into the message and return return strtr($message, $replace); }
/** * Render configuration file content with it's header and data (can be automatically merged with * original configuration). Config content will be merged based on merge rule. * * @param mixed $original * @return string * @throw ConfigWriterException * @throws SerializeException */ protected function renderConfig($original = null) { $config = $this->config; if (!empty($original)) { //Merging configs $config = $this->mergeConfigs($config, $original); } return interpolate("{header}return {config};", ['header' => $this->header, 'config' => $this->serializer->serialize($config)]); }
/** * Prepares some rainbow colors for the nodes of the graph * and stores them in an array which may be accessed with * <code>getColor</code>. */ function createColors() { $predefcolors = array(array('red' => 255, 'green' => 0, 'blue' => 0), array('red' => 255, 'green' => 255, 'blue' => 0), array('red' => 0, 'green' => 255, 'blue' => 0), array('red' => 0, 'green' => 255, 'blue' => 255), array('red' => 0, 'green' => 0, 'blue' => 255), array('red' => 100, 'green' => 100, 'blue' => 100)); $steps = 2; $numberofcolors = count($predefcolors) * $steps; $promille = -1; foreach ($predefcolors as $color) { if ($promille < 0) { $oldcolor = $color; $promille = 0; continue; } for ($i = 0; $i < $steps; $i++) { $this->ColorTab[++$promille / $numberofcolors * 1000] = array(floor(interpolate($oldcolor['red'], $color['red'], $i / $steps)), floor(interpolate($oldcolor['green'], $color['green'], $i / $steps)), floor(interpolate($oldcolor['blue'], $color['blue'], $i / $steps))); } $oldcolor = $color; } //echo"<pre>"; var_dump($this->ColorTab); echo "</pre>"; }
/** * Text translation (I18n) * * @param string $message * @param array $context * @return string * * <code> * echo __('Hello'); * echo __('There are {number} persons logged', array('number' => 7)); * </code> */ function __($message, array $context = array()) { $translator = \App\Container\AppContainer::getInstance()->translator; $message = $translator->trans($message); if (!empty($context)) { $message = interpolate($message, $context); } return $message; }
/** * Parses the jsdoc comments into a markdown file. * @param {String} $filepath The relative path to the .js file. * @returns {String} The generated markdown. */ function parse($filepath) { $api = array(); $openTag = "<!-- div -->"; $closeTag = "<!-- /div -->"; $result = array("# Benchmark.js API documentation", ""); // load file and extract comment blocks $source = str_replace(PHP_EOL, "\n", file_get_contents($filepath)); preg_match_all("#/\\*(?![-!])[\\s\\S]*?\\*/\\s*[^=\n;]+#", $source, $entries); $entries = array_pop($entries); foreach ($entries as $entry) { // parse flags $isCtor = strripos($entry, "@constructor") !== false; $isPrivate = strripos($entry, "@private") !== false; $isStatic = strripos($entry, "@static") !== false; // parse @member(s) preg_match("/@member ([^\n]+)/", $entry, $members); if ($members = array_pop($members)) { $members = preg_split("/,\\s*/", $members); } if ($isCtor) { preg_match("#\\*/\\s*function ([^(]+)#", $entry, $name); $name = array_pop($name); if ($members) { $members = array($members[0] . '.' . $name); } else { $members = array($name); } } // skip private if ($isPrivate || !$members) { continue; } foreach ($members as $member) { // find line number preg_match_all("/\n/", substr($source, 0, strrpos($source, $entry) + strlen($entry)), $lines); $lines = array_pop($lines); $ln = count($lines) + 1; // parse #{call} preg_match("@\\*/\\s*(?:function ([^(]*)|(?:" . $member . "\\.)?([^:=,]*))@", $entry, $call); if ($call = array_pop($call)) { $call = trim(trim($call), "'"); } // parse #{name} preg_match("/@name ([^\n]+)/", $entry, $name); if (!($name = array_pop($name))) { $name = $call; } // set isStatic in cases where it isn't explicitly stated $oldStatic = $isStatic; if (!$isStatic && !$isCtor && preg_match("/[#.]/", $member)) { $parentMember = preg_replace("/[#.][^#.]+\$/", "", $member); $parentAPI = $api[$parentMember]["plugin"]; $ownMember = substr($member, strlen($parentMember) + 1); // if ownMember exits on its parent then its not a constructor and has static properties foreach ($parentAPI as $parentEntry) { if ($parentEntry["name"] == $ownMember) { $isStatic = true; break; } } } // parse #{type} preg_match("/@type ([^\n]+)/", $entry, $type); $type = array_pop($type); $type = $type ? $type : "Function"; // parse #{desc} preg_match("#/\\*\\*([^@]+)#", $entry, $desc); if ($desc = array_pop($desc)) { $desc = preg_replace("/\n\\s*\\*\\s*/", "\n", $desc); $desc = ($type == "Function" ? "" : "(" . $type . "): ") . trim($desc); } // parse @example preg_match("#@example([\\s\\S]*)?(?=\\*\\s\\@[a-z]|\\*/)#", $entry, $example); if ($example = array_pop($example)) { $example = " " . trim(preg_replace("/\n\\s*\\* ?/", "\n ", $example)); } // parse @param preg_match_all("/@param \\{([^}]+)\\} (\\[[^]]+\\]|\\w+) ([^\n]+)/", $entry, $args); array_shift($args); $args = array_filter($args); if (count($args)) { // compile "call" $call = array($call); // compile "args" foreach ($args as $arr) { foreach ($arr as $index => $value) { if (!is_array($args[0][$index])) { $args[0][$index] = array(); } if (count($args[0][$index]) == 1) { $call[] = $value; } $args[0][$index][] = $value; } } // format "call" $call = array_shift($call) . "(" . implode($call, ", ") . ")"; $call = str_replace(", [", " [, ", str_replace("], [", ", ", $call)); // flatten "args" array_splice($args, 1); $args = array_pop($args); } // parse @returns preg_match("/@returns \\{([^}]+)\\} ([^*]+)/", $entry, $returns); array_shift($returns); if (count($returns)) { $returns = array_map("trim", $returns); } // define #{separator} if ($isCtor) { $separator = ""; } else { $separator = !$isStatic && strpos($member, "#") === false ? "#" : "."; } // define #{hash} $hash = str_replace("#", ":", $member) . ($isCtor ? "" : ($isStatic ? "." : ":") . $name); // define #{link} $link = "https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L" . $ln; // create entry $item = array("args" => $args, "call" => $call, "desc" => $desc, "example" => $example, "hash" => $hash, "link" => $link, "ln" => $ln, "name" => $name, "member" => $member, "separator" => $separator, "returns" => $returns, "type" => $type); // create api category arrays if (!isset($api[$member]["ctor"])) { $api[$member]["ctor"] = array(); } if (!isset($api[$member]["static"])) { $api[$member]["static"] = array(); } if (!isset($api[$member]["plugin"])) { $api[$member]["plugin"] = array(); } // append entry to api category if ($isCtor) { $api[$member]["ctor"] = array($item); } else { if ($isStatic) { $api[$member]["static"][] = $item; } else { $api[$member]["plugin"][] = $item; } } // reset isStatic $isStatic = $oldStatic; } } /*------------------------------------------------------------------------*/ // sort classes ksort($api); foreach ($api as &$object) { // make "plugin" the last type key ksort($object); $object["temp"] = $object["plugin"]; unset($object["plugin"]); $object["plugin"] = $object["temp"]; unset($object["temp"]); // sort entries foreach ($object as &$entries) { $sortByA = array(); $sortByB = array(); $sortByC = array(); foreach ($entries as $entry) { // functions w/o ALL-CAPs names are last $sortByA[] = $entry["type"] == "Function" && !preg_match("/^[A-Z_]+\$/", $entry["name"]) ? 1 : 0; // ALL-CAPs properties first $sortByB[] = preg_match("/^[A-Z_]+\$/", $entry["name"]); // alphanumerically $sortByC[] = $entry["name"]; } array_multisort($sortByA, SORT_ASC, $sortByB, SORT_DESC, $sortByC, SORT_ASC, $entries); unset($entries); } unset($object); } /*------------------------------------------------------------------------*/ // move object entries into the top of their own api category foreach ($api as $member => &$object) { if (preg_match("/[#.]/", $member)) { $parentMember = preg_replace("/[#.][^#.]+\$/", "", $member); $parentType = substr(substr($member, strlen($parentMember)), 0, 1) == "#" ? "plugin" : "static"; $parentAPI =& $api[$parentMember]; $ownMember = substr($member, strlen($parentMember) + 1); foreach ($parentAPI[$parentType] as $index => $parentEntry) { if ($parentEntry["name"] == $ownMember) { array_unshift($object["static"], $parentEntry); unset($parentAPI[$parentType][$index]); } } } unset($object, $parentAPI); } /*------------------------------------------------------------------------*/ // compile TOC $started = false; $result[] = $openTag; foreach ($api as $member => $object) { foreach ($object as $type => $entries) { if (count($entries)) { if ($type == "ctor") { if ($started) { $result[] = $closeTag; } $started = true; array_push($result, $openTag, "## `" . $member . "`", interpolate("* [`#{member}`](##{hash})", $entries[0])); } else { if ($type == "plugin") { if ($started) { $result[] = $closeTag; } $started = true; array_push($result, $openTag, "## `" . $member . ".prototype`"); } foreach ($entries as $entry) { $result[] = interpolate("* [`#{member}#{separator}#{name}`](##{hash})", $entry); } } } } } array_push($result, $closeTag, $closeTag, "", ""); /*------------------------------------------------------------------------*/ // compile content $started = false; $result[] = $openTag; foreach ($api as $member => $object) { foreach ($object as $type => $entries) { // title if (count($entries)) { if ($type == "ctor") { if ($started) { array_pop($result); array_push($result, $closeTag, "", ""); } $started = true; array_push($result, $openTag, "## `" . $member . "`"); } else { if ($type == "plugin") { if ($started) { array_pop($result); array_push($result, $closeTag, "", ""); } $started = true; array_push($result, $openTag, "## `" . $member . ".prototype`"); } } } // body foreach ($entries as $entry) { array_push($result, $openTag); // description if ($entry["name"]) { if ($type == "ctor") { // clip "call" $entry["call"] = substr($entry["call"], strpos($entry["call"], "(")); $result[] = interpolate("### <a id=\"#{hash}\" href=\"#{link}\" title=\"View in source\">`" . "#{member}#{call}`</a>\n#{desc}\n[▲][1]", $entry); } else { $result[] = interpolate("### <a id=\"#{hash}\" href=\"#{link}\" title=\"View in source\">`" . "#{member}#{separator}#{call}`</a>\n#{desc}\n[▲][1]", $entry); } } // @param if (count($entry["args"])) { array_push($result, "", "#### Arguments"); foreach ($entry["args"] as $index => $arr) { $result[] = interpolate("#{num}. `#{name}` (#{type}): #{desc}", array("desc" => $arr[2], "name" => $arr[1], "num" => $index + 1, "type" => $arr[0])); } } // @returns if (count($entry["returns"])) { array_push($result, "", "#### Returns", interpolate("(#{type}): #{desc}", array("desc" => $entry["returns"][1], "type" => $entry["returns"][0]))); } // @example if ($entry["example"]) { array_push($result, "", "#### Example", $entry["example"]); } array_push($result, $closeTag, ""); } } } // close tags add TOC link reference array_pop($result); array_push($result, $closeTag, $closeTag, "", " [1]: #readme \"Jump back to the TOC.\""); // cleanup whitespace return trim(preg_replace("/ +\n/", "\n", join($result, "\n"))); }