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