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 $doi = substr($match, 6, -2); 43 44 return ['id' => $doi]; 45 } 46 47 /** @inheritDoc */ 48 public function render($mode, Doku_Renderer $renderer, $data) 49 { 50 $resolver = $this->getResolver(); 51 $data['id'] = $resolver->cleanID($data['id']); 52 53 try { 54 $publication = $resolver->getData($data['id']); 55 } catch (Exception $e) { 56 msg(hsc($e->getMessage()), -1); 57 $url = $resolver->getFallbackURL($data['id']); 58 $title = $data['id']; 59 60 $renderer->externallink($url, $title); 61 return true; 62 } 63 64 if ($mode === 'xhtml') { 65 /** @var Doku_Renderer_xhtml $renderer */ 66 $this->renderXHTML($publication, $renderer); 67 } else { 68 $this->renderAny($publication, $renderer); 69 } 70 71 return true; 72 } 73 74 /** 75 * @return AbstractResolver 76 */ 77 protected function getResolver() 78 { 79 return new DoiResolver(); 80 } 81 82 /** 83 * Render the given data on the XHTML renderer 84 * 85 * Adds various classes to the output for CSS styling 86 * 87 * @param array $data 88 * @param Doku_Renderer_xhtml $renderer 89 * @return void 90 */ 91 protected function renderXHTML($data, $renderer) 92 { 93 $renderer->doc .= '<div class="plugin_doi ' . hsc($data['type']) . '">'; 94 $renderer->externallink($data['url'], $data['title']); 95 96 if ($data['published']) { 97 $renderer->doc .= ' <span>(' . hsc($data['published']) . ')</span>'; 98 } 99 100 $renderer->doc .= '<div class="meta">'; 101 if ($data['authors']) { 102 $authors = array_map(function ($author) { 103 return '<strong>' . hsc($author) . '</strong>'; 104 }, $data['authors']); 105 $renderer->doc .= '<span class="authors">' . join(', ', $authors) . '</span>'; 106 } 107 if ($data['journal']) { 108 $journal = $data['journal']; 109 $journal .= ' ' . join('/', array_filter([$data['volume'] ?? null, $data['issue'] ?? null])); 110 $journal = '<span>' . hsc($journal) . '</span>'; 111 if ($data['page']) { 112 $journal .= ' <i>p' . hsc($data['page']) . '</i>'; 113 } 114 $renderer->doc .= ' <span class="journal">' . $journal . '</span>'; 115 } 116 $renderer->doc .= '</div>'; 117 118 $renderer->doc .= '<div class="meta">'; 119 if ($data['publisher']) { 120 $renderer->doc .= '<span class="publisher">' . hsc($data['publisher']) . '</span>'; 121 } 122 $renderer->doc .= ' <code class="id">' . $data['idtype'] . ':' . hsc($data['id']) . '</code>'; 123 $renderer->doc .= '</div>'; 124 125 $renderer->doc .= '</div>'; 126 } 127 128 /** 129 * Render the given data on any renderer 130 * 131 * Uses renderer methods only 132 * 133 * @param array $data 134 * @param Doku_Renderer $renderer 135 * @return void 136 */ 137 protected function renderAny($data, $renderer) 138 { 139 $renderer->p_open(); 140 $renderer->externallink($data['url'], $data['title']); 141 142 if ($data['published']) { 143 $renderer->cdata(' (' . hsc($data['published']) . ')'); 144 } 145 $renderer->linebreak(); 146 147 if ($data['authors']) { 148 $len = count($data['authors']); 149 for ($i = 0; $i < $len; $i++) { 150 $renderer->strong_open(); 151 $renderer->cdata($data['authors'][$i]); 152 $renderer->strong_close(); 153 if ($i < $len - 1) { 154 $renderer->cdata(', '); 155 } 156 } 157 158 if ($data['journal']) { 159 $journal = $data['journal']; 160 $journal .= ' ' . join('/', array_filter([$data['volume'] ?? null, $data['issue'] ?? null])); 161 $renderer->cdata(' ' . $journal); 162 } 163 164 if ($data['page']) { 165 $renderer->cdata(' '); 166 $renderer->emphasis_open(); 167 $renderer->cdata('p' . $data['page']); 168 $renderer->emphasis_close(); 169 } 170 } 171 $renderer->linebreak(); 172 173 if ($data['publisher']) { 174 $renderer->cdata($data['publisher']); 175 $renderer->cdata(' '); 176 } 177 $renderer->monospace_open(); 178 $renderer->cdata($data['idtype'] . ':' . hsc($data['id'])); 179 $renderer->monospace_close(); 180 181 $renderer->p_close(); 182 } 183} 184 185