Lexer->addSpecialPattern('\.*?\', $mode, 'plugin_minecraftrecipe'); } public function handle($match, $state, $pos, Doku_Handler $handler) { $type = 'crafting'; // default type if(preg_match('/type="([^"]*)"/', $match, $matches)) { $type = $matches[1]; } $content = preg_replace('/^\|\<\/recipe\>$/i', '', $match); $lines = explode("\n", trim($content)); switch($type) { case 'smelting': return $this->_handleSmelting($lines); case 'brewing': return $this->_handleBrewing($lines); case 'crafting': default: return $this->_handleCrafting($lines); } } protected function _handleCrafting($lines) { $recipe = array(); $result = array(); foreach($lines as $line) { $line = trim($line); if(empty($line)) continue; if(strpos($line, '->') !== false) { $resultItems = explode(',', trim(substr($line, 2))); $result = array_map('trim', $resultItems); } else { $slots = array_filter(explode(' ', $line)); $row = array(); foreach($slots as $slot) { $items = array_map('trim', explode(',', $slot)); $row[] = $items; } while(count($row) < 3) { $row[] = array('empty'); } if(!empty($row)) { $recipe[] = $row; } } } // pad to 3 rows with empty slots while(count($recipe) < 3) { $recipe[] = array(array('empty'), array('empty'), array('empty')); } return array( 'type' => 'crafting', 'recipe' => $recipe, 'result' => $result, 'shapeless' => false ); } protected function _handleSmelting($lines) { $input = array(); $fuel = array(); $result = array(); foreach($lines as $index => $line) { $line = trim($line); if(empty($line)) continue; if(strpos($line, '->') !== false) { $resultItems = explode(',', trim(substr($line, 2))); $result = array_map('trim', $resultItems); } else if($index === 1) { // Second line is fuel $fuelItems = explode(',', $line); $fuel = array_map('trim', $fuelItems); } else if($index === 0) { // First line is input $inputItems = explode(',', $line); $input = array_map('trim', $inputItems); } } if(empty($fuel)) { $fuel = array('empty'); } return array( 'type' => 'smelting', 'input' => $input, 'fuel' => $fuel, 'result' => $result ); } protected function _handleBrewing($lines) { $reagent = array(); $potions = array(); foreach($lines as $line) { $line = trim($line); if(empty($line)) continue; if(strpos($line, '->') !== false) { $potionItems = explode(' ', trim(substr($line, 2))); foreach($potionItems as $potion) { $potions[] = array_map('trim', explode(',', $potion)); } } else { // first line is reagent $reagentItems = explode(',', $line); $reagent = array_map('trim', $reagentItems); } } while(count($potions) < 3) { $potions[] = array('empty'); } return array( 'type' => 'brewing', 'reagent' => $reagent, 'potions' => $potions ); } protected function _renderBrewing($renderer, $data) { $renderer->doc .= '
'; $renderer->doc .= '
'; $renderer->doc .= '
'; $renderer->doc .= '
'; $renderer->doc .= '
'; // reagent slot $renderer->doc .= '
'; $renderer->doc .= $this->_renderItem($data['reagent']); $renderer->doc .= '
'; // potion slots foreach($data['potions'] as $index => $potion) { $renderer->doc .= '
'; $renderer->doc .= $this->_renderItem($potion); $renderer->doc .= '
'; } $renderer->doc .= '
'; return true; } public function render($mode, Doku_Renderer $renderer, $data) { if($mode != 'xhtml') return false; if(!is_array($data)) return false; switch($data['type']) { case 'smelting': return $this->_renderSmelting($renderer, $data); case 'brewing': return $this->_renderBrewing($renderer, $data); case 'crafting': default: return $this->_renderCrafting($renderer, $data); } } protected function _renderCrafting($renderer, $data) { $renderer->doc .= '
'; $renderer->doc .= '
'; $renderer->doc .= '
'; $renderer->doc .= '
'; if(isset($data['recipe'])) { foreach($data['recipe'] as $row) { foreach($row as $item) { $renderer->doc .= ''; $renderer->doc .= $this->_renderItem($item); $renderer->doc .= ''; } } } $renderer->doc .= '
'; $renderer->doc .= '
'; $renderer->doc .= '
'; $renderer->doc .= ''; if(isset($data['result'])) { $renderer->doc .= $this->_renderItem($data['result']); } $renderer->doc .= '
'; return true; } protected function _renderSmelting($renderer, $data) { $renderer->doc .= '
'; $renderer->doc .= '
'; // input $renderer->doc .= '
'; $renderer->doc .= $this->_renderItem($data['input']); $renderer->doc .= '
'; // fire icon $renderer->doc .= '
'; // fuel $renderer->doc .= '
'; $renderer->doc .= $this->_renderItem($data['fuel']); $renderer->doc .= '
'; // arrow $renderer->doc .= '
'; // result $renderer->doc .= '
'; $renderer->doc .= $this->_renderItem($data['result']); $renderer->doc .= '
'; $renderer->doc .= '
'; return true; } protected function _renderItem($items) { if(!is_array($items)) { $items = array($items); } $allEmpty = true; foreach($items as $item) { $item = strtolower(trim($item)); if($item !== 'empty' && $item !== 'x') { $allEmpty = false; break; } } if($allEmpty) return ''; $output = '
'; foreach($items as $index => $item) { $item = trim($item); if(strtolower($item) === 'x') continue; if(strtolower($item) === 'empty') continue; $localPath = DOKU_PLUGIN . 'minecraftrecipe/images/item/' . strtolower($item) . '.png'; if(file_exists($localPath)) { $src = DOKU_BASE . 'lib/plugins/minecraftrecipe/images/item/' . strtolower($item) . '.png'; } else { $wikiItem = str_replace(' ', '_', $item); $src = 'https://minecraft.wiki/images/Invicon_' . $wikiItem . '.png'; // fallback to minecraft.wiki } $visibility = ($index === 0) ? '' : ' style="display: none;"'; $output .= ''.hsc($item).''; } $output .= '
'; return $output; } }