*/ class syntax_plugin_number extends SyntaxPlugin { /** @inheritDoc */ public function getType() { return 'substition'; } /** @inheritDoc */ public function getPType() { return 'normal'; } /** @inheritDoc */ public function getSort() { return 100; } /** @inheritDoc */ public function connectTo($mode) { $this->Lexer->addSpecialPattern('{{n>.*?}}', $mode, 'plugin_number'); } /** @inheritDoc */ public function handle($match, $state, $pos, Doku_Handler $handler) { $raw = substr($match, 4, -2); $raw = strtolower($raw); $raw = preg_replace('/[^0-9a-z_]/', '', $raw); $data = []; $data['raw'] = $raw; if (preg_match('/^\d+(e\d+)?$/', $raw)) { $data['type'] = 'dec'; $data['value'] = intval($raw); } else if (preg_match('/^0b[01]+$/', $raw)) { $data['type'] = 'bin'; $data['value'] = intval(substr($raw, 2), 2); } else if (preg_match('/^0x[0-9a-f]+$/i', $raw)) { $data['type'] = 'hex'; $data['value'] = intval(substr($raw, 2), 16); } else if (preg_match('/^[0-9a-z]+_[0-9]+$/i', $raw)) { $data['type'] = 'padic'; list($number, $base) = explode('_', $raw); $data['value'] = intval($number, $base); $data['number'] = $number; $data['base'] = intval($base); if ($data['base'] < 2 || $data['base'] > 36 || base_convert($data['value'], 10, $data['base']) != $number) $data['value'] = NAN; } else { $data['value'] = NAN; } return $data; } static private function renderDec($value) { return ''.$value.''; } static private function renderHex($value) { return '0x' . (is_string($value) ? substr($value, 2) : dechex($value)) . ''; } static private function renderBin($value) { return '0b' . (is_string($value) ? substr($value, 2) : decbin($value)) . ''; } const NUMBERSYSTEM = ';;Binary;Ternary;Quaternary;Quinary;Senary;Septenary;Octal;Nonary;Decimal;Undecimal;Duodecimal;Tridecimal;Tetradecimal;Pentadecimal;Hexadecimal;Heptadecimal;Octodecimal;Enneadecimal;Vigesimal;Unvigesimal;Duovigesimal;Trivigesimal;Tetravigesimal;Pentavigesimal;Hexavigesimal;Heptavigesimal;Octovigesimal;Enneavigesimal;Trigesimal;Untrigesimal;Duotrigesimal;Tritrigesimal;Tetratrigesimal;Pentatrigesimal; Hexatrigesimal'; /** @inheritDoc */ public function render($mode, Doku_Renderer $renderer, $data) { if ($mode !== 'xhtml') { return false; } $value = $data['value']; if (is_nan($value)) { $renderer->doc .= '⚠️ warning: ' . $data['raw'] . ' is not a valid input'; return true; } if (!is_int($value) || $value >= PHP_INT_MAX) { $renderer->doc .= '⚠️ warning: ' . $data['raw'] . ' is not a safe for conversion '.$value; return true; } $type = $data['type']; if ($type == 'dec') { $number = self::renderDec($data['raw']); $tooltip = 'Decimal number (base 10)
= ' . self::renderBin($value) . ' (binary)'; if ("~$value" != '~' . $data['raw']) { // $tooltip .= '
= ' . self::renderDec($value) . ' (decimal)'; } $tooltip .= '
= ' . self::renderHex($value) . ' (hexadecimal)'; } else if ($type == 'bin') { $number = self::renderBin($data['raw']); $tooltip = 'Binary number (base 2)
= ' . self::renderDec($value) . ' (decimal)
= ' . self::renderHex($value) . ' (hexadecimal)'; } else if ($type == 'hex') { $number = self::renderHex($data['raw']); $tooltip = 'Hexadecimal number (base 16)
= ' . self::renderBin($value) . ' (binary)
= ' . self::renderDec($value) . ' (decimal)'; } else if ($type == 'padic') { $number = '[' . $data['number'] . ']' . $data['base'] . ''; $tooltip = '' . explode(';', self::NUMBERSYSTEM)[$data['base']] . ' number (base ' . $data['base'] . ')
= ' . self::renderBin($value) . ' (binary)
= ' . self::renderDec($value) . ' (decimal)
= ' . self::renderHex($value) . ' (hexadecimal)'; } // $renderer->doc .= "$tooltip$number"; return true; } }