1<?php 2 3namespace dokuwiki\Parsing\ParserMode; 4 5use dokuwiki\Parsing\Handler; 6use dokuwiki\Parsing\Helpers\Media as MediaHelper; 7 8class Media extends AbstractMode 9{ 10 /** @inheritdoc */ 11 public function getSort() 12 { 13 return 320; 14 } 15 16 /** @inheritdoc */ 17 public function connectTo($mode) 18 { 19 // Word boundaries? 20 $this->Lexer->addSpecialPattern("\{\{(?:[^\}]|(?:\}[^\}]))+\}\}", $mode, 'media'); 21 } 22 23 /** @inheritdoc */ 24 public function handle($match, $state, $pos, Handler $handler) 25 { 26 $p = self::parseMedia($match); 27 28 $handler->addCall( 29 $p['type'], 30 [$p['src'], $p['title'], $p['align'], $p['width'], $p['height'], $p['cache'], $p['linking']], 31 $pos 32 ); 33 return true; 34 } 35 36 /** 37 * Parse media syntax into its components 38 * 39 * @param string $match The full media syntax (e.g. {{image.png?200|title}}) 40 * @return array Parsed media parameters (type, src, title, align, width, height, cache, linking) 41 */ 42 public static function parseMedia($match) 43 { 44 // Strip the opening and closing markup 45 $link = preg_replace(['/^\{\{/', '/\}\}$/u'], '', $match); 46 47 // Split title from URL 48 $link = sexplode('|', $link, 2); 49 50 // Check alignment 51 $ralign = (bool)preg_match('/^ /', $link[0]); 52 $lalign = (bool)preg_match('/ $/', $link[0]); 53 54 // Logic = what's that ;)... 55 if ($lalign & $ralign) { 56 $align = 'center'; 57 } elseif ($ralign) { 58 $align = 'right'; 59 } elseif ($lalign) { 60 $align = 'left'; 61 } else { 62 $align = null; 63 } 64 65 // The title... 66 if (!isset($link[1])) { 67 $link[1] = null; 68 } 69 70 //remove aligning spaces 71 $link[0] = trim($link[0]); 72 73 $p = MediaHelper::parseParameters($link[0]); 74 75 // Explicit param-derived alignment (?left/?right/?center) beats 76 // the whitespace-derived one — it's unambiguous and visible, and 77 // is the only form GfmMedia can express. 78 if ($p['align'] !== null) { 79 $align = $p['align']; 80 } 81 82 if (media_isexternal($p['src']) || link_isinterwiki($p['src'])) { 83 $call = 'externalmedia'; 84 } else { 85 $call = 'internalmedia'; 86 } 87 88 return [ 89 'type' => $call, 90 'src' => $p['src'], 91 'title' => $link[1], 92 'align' => $align, 93 'width' => $p['width'], 94 'height' => $p['height'], 95 'cache' => $p['cache'], 96 'linking' => $p['linking'] 97 ]; 98 } 99} 100