1<?php 2 3/** 4 * DokuWiki Plugin doi (Syntax Component) 5 * 6 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 7 * @author Andreas Gohr <gohr@cosmocode.de> 8 */ 9class syntax_plugin_doi_doi extends \dokuwiki\Extension\SyntaxPlugin 10{ 11 /** @inheritDoc */ 12 public function getType() 13 { 14 return 'substition'; 15 } 16 17 /** @inheritDoc */ 18 public function getPType() 19 { 20 return 'normal'; 21 } 22 23 /** @inheritDoc */ 24 public function getSort() 25 { 26 return 155; 27 } 28 29 /** @inheritDoc */ 30 public function connectTo($mode) 31 { 32 $this->Lexer->addSpecialPattern('\[\[doi>[^\]]+\]\]', $mode, 'plugin_doi_doi'); 33 } 34 35 /** @inheritDoc */ 36 public function handle($match, $state, $pos, Doku_Handler $handler) 37 { 38 $doi = substr($match, 6, -2); 39 40 return ['doi' => $doi]; 41 } 42 43 /** @inheritDoc */ 44 public function render($mode, Doku_Renderer $renderer, $data) 45 { 46 $publication = $this->fetchInfo($data['doi']); 47 $title = $publication['message']['title'][0] ?? $data['doi']; 48 $url = $publication['message']['URL'] ?? 'https://doi.org/' . $data['doi']; 49 50 if ($mode !== 'xhtml' || !$publication) { 51 $renderer->externallink($url, $title); 52 return true; 53 } 54 55 /** @var Doku_Renderer_xhtml $renderer */ 56 $this->formatPub($publication['message'], $renderer); 57 58 return true; 59 } 60 61 /** 62 * Render the given message 63 * 64 * @param array $message 65 * @param Doku_Renderer_xhtml $renderer 66 * @return void 67 */ 68 protected function formatPub($message, $renderer) 69 { 70 $doi = $message['DOI']; 71 $title = $message['title'][0] ?? $doi; 72 $url = $message['URL'] ?? 'https://doi.org/' . $doi; 73 74 $class = hsc($message['type']); 75 76 $authorList = []; 77 foreach ($message['author'] ?? [] as $author) { 78 $authorList[] = '<strong>' . hsc($author['given'].' '.$author['family']) . '</strong>'; 79 } 80 81 if (isset($message['container-title'][0])) { 82 $journal = $message['container-title'][0]; 83 $journal .= ' ' . join('/', [$message['volume'] ?? null, $message['issue'] ?? null]); 84 $journal = '<span>' . hsc($journal) . '</span>'; 85 if (isset($message['page'])) { 86 $journal .= ' <i>p' . hsc($message['page']) . '</i>'; 87 } 88 $journal = ' <span class="journal">' . $journal . '</span>'; 89 } else { 90 $journal = ''; 91 } 92 93 $published = $message['issued']['date-parts'][0][0] ?? ''; 94 if ($published) $published = ' <span>(' . hsc($published) . ')</span>'; 95 96 $publisher = hsc($message['publisher'] ?? ''); 97 98 //output 99 $renderer->doc .= '<div class="plugin_doi ' . $class . '">'; 100 $renderer->externallink($url, $title); 101 $renderer->doc .= $published; 102 103 $renderer->doc .= '<div class="meta">'; 104 if ($authorList) { 105 $renderer->doc .= '<span class="authors">' . join(', ', $authorList) . '</span>'; 106 } 107 if ($journal) { 108 $renderer->doc .= $journal; 109 } 110 $renderer->doc .= '</div>'; 111 112 $renderer->doc .= '<div class="meta">'; 113 if ($publisher) { 114 $renderer->doc .= '<span class="publisher">' . $publisher . '</span>'; 115 } 116 $renderer->doc .= ' <code class="doi">DOI:' . $doi . '</code>'; 117 $renderer->doc .= '</div>'; 118 119 $renderer->doc .= '</div>'; 120 } 121 122 /** 123 * Fetch the info for the given DOI 124 * 125 * @param string $doi 126 * @return false|array 127 */ 128 protected function fetchInfo($doi) 129 { 130 $http = new \dokuwiki\HTTP\DokuHTTPClient(); 131 132 $json = $http->get('https://api.crossref.org/works/' . $doi); 133 if (!$json) return false; 134 135 return json_decode($json, true); 136 } 137} 138 139