1<?php 2 3use dokuwiki\plugin\doi\Resolver\AbstractResolver; 4use \dokuwiki\plugin\doi\Resolver\DoiResolver; 5 6 7/** 8 * DokuWiki Plugin doi (Syntax Component) 9 * 10 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 11 * @author Andreas Gohr <gohr@cosmocode.de> 12 */ 13class syntax_plugin_doi_doi extends \dokuwiki\Extension\SyntaxPlugin 14{ 15 /** @inheritDoc */ 16 public function getType() 17 { 18 return 'substition'; 19 } 20 21 /** @inheritDoc */ 22 public function getPType() 23 { 24 return 'normal'; 25 } 26 27 /** @inheritDoc */ 28 public function getSort() 29 { 30 return 155; 31 } 32 33 /** @inheritDoc */ 34 public function connectTo($mode) 35 { 36 $this->Lexer->addSpecialPattern('\[\[doi>[^\]]+\]\]', $mode, 'plugin_doi_doi'); 37 } 38 39 /** @inheritDoc */ 40 public function handle($match, $state, $pos, Doku_Handler $handler) 41 { 42 $match = substr($match, 2, -2); 43 list(, $id) = sexplode('>', $match, 2); 44 list($id, $title) = sexplode('|', $id, 2); 45 return [ 46 'id' => $id, 47 'title' => $title, 48 ]; 49 } 50 51 /** @inheritDoc */ 52 public function render($mode, Doku_Renderer $renderer, $data) 53 { 54 $resolver = $this->getResolver(); 55 $data['id'] = $resolver->cleanID($data['id']); 56 57 try { 58 $publication = $resolver->getData($data['id']); 59 } catch (Exception $e) { 60 msg(hsc($e->getMessage()), -1); 61 $url = $resolver->getFallbackURL($data['id']); 62 $title = empty($data['title']) ? $data['id'] : $data['title']; 63 64 $renderer->externallink($url, $title); 65 return true; 66 } 67 68 // overwritten title? 69 if (!empty($data['title'])) $publication['title'] = $data['title']; 70 71 // overwritten url (eg. by amazonlight plugin)? 72 if (!empty($data['url'])) $publication['url'] = $data['url']; 73 74 if ($mode === 'xhtml') { 75 /** @var Doku_Renderer_xhtml $renderer */ 76 $this->renderXHTML($publication, $renderer); 77 } else { 78 $this->renderAny($publication, $renderer); 79 } 80 81 return true; 82 } 83 84 /** 85 * @return AbstractResolver 86 */ 87 protected function getResolver() 88 { 89 return new DoiResolver(); 90 } 91 92 /** 93 * Render the given data on the XHTML renderer 94 * 95 * Adds various classes to the output for CSS styling 96 * 97 * @param array $data 98 * @param Doku_Renderer_xhtml $renderer 99 * @return void 100 */ 101 protected function renderXHTML($data, $renderer) 102 { 103 $renderer->doc .= '<div class="plugin_doi ' . hsc($data['type']) . '">'; 104 105 if( $this->getConf('cover') && $data['image'] ) { 106 $renderer->externallink( 107 $data['url'], 108 [ 109 'src' => $data['image'], 110 'title' => $data['title'], 111 'align' => 'left', 112 'width' => 64, 113 'height' => 90, 114 'cache' => true, 115 'type' => 'externalmedia' 116 ] 117 ); 118 } 119 120 $renderer->externallink($data['url'], $data['title']); 121 122 if ($data['published']) { 123 $renderer->doc .= ' <span>(' . hsc($data['published']) . ')</span>'; 124 } 125 126 $renderer->doc .= '<div class="meta">'; 127 if ($data['authors']) { 128 $authors = array_map(function ($author) { 129 return '<strong>' . hsc($author) . '</strong>'; 130 }, $data['authors']); 131 $renderer->doc .= '<span class="authors">' . join(', ', $authors) . '</span>'; 132 } 133 if ($data['journal']) { 134 $journal = $data['journal']; 135 $journal .= ' ' . join('/', array_filter([$data['volume'] ?? null, $data['issue'] ?? null])); 136 $journal = '<span>' . hsc($journal) . '</span>'; 137 if ($data['page']) { 138 $journal .= ' <i>p' . hsc($data['page']) . '</i>'; 139 } 140 $renderer->doc .= ' <span class="journal">' . $journal . '</span>'; 141 } 142 $renderer->doc .= '</div>'; 143 144 $renderer->doc .= '<div class="meta">'; 145 if ($data['publisher']) { 146 $renderer->doc .= '<span class="publisher">' . hsc($data['publisher']) . '</span>'; 147 } 148 $renderer->doc .= ' <code class="id">' . $data['idtype'] . ':' . hsc($data['id']) . '</code>'; 149 $renderer->doc .= '</div>'; 150 151 $renderer->doc .= '</div>'; 152 } 153 154 /** 155 * Render the given data on any renderer 156 * 157 * Uses renderer methods only 158 * 159 * @param array $data 160 * @param Doku_Renderer $renderer 161 * @return void 162 */ 163 protected function renderAny($data, $renderer) 164 { 165 $renderer->p_open(); 166 $renderer->externallink($data['url'], $data['title']); 167 168 if ($data['published']) { 169 $renderer->cdata(' (' . hsc($data['published']) . ')'); 170 } 171 $renderer->linebreak(); 172 173 if ($data['authors']) { 174 $len = count($data['authors']); 175 for ($i = 0; $i < $len; $i++) { 176 $renderer->strong_open(); 177 $renderer->cdata($data['authors'][$i]); 178 $renderer->strong_close(); 179 if ($i < $len - 1) { 180 $renderer->cdata(', '); 181 } 182 } 183 184 if ($data['journal']) { 185 $journal = $data['journal']; 186 $journal .= ' ' . join('/', array_filter([$data['volume'] ?? null, $data['issue'] ?? null])); 187 $renderer->cdata(' ' . $journal); 188 } 189 190 if ($data['page']) { 191 $renderer->cdata(' '); 192 $renderer->emphasis_open(); 193 $renderer->cdata('p' . $data['page']); 194 $renderer->emphasis_close(); 195 } 196 } 197 $renderer->linebreak(); 198 199 if ($data['publisher']) { 200 $renderer->cdata($data['publisher']); 201 $renderer->cdata(' '); 202 } 203 $renderer->monospace_open(); 204 $renderer->cdata($data['idtype'] . ':' . hsc($data['id'])); 205 $renderer->monospace_close(); 206 207 $renderer->p_close(); 208 } 209} 210 211