1<?php 2 3namespace dokuwiki\Parsing\ParserMode; 4 5use dokuwiki\Parsing\Handler; 6use dokuwiki\Parsing\Helpers\Media as MediaHelper; 7 8/** 9 * GFM inline image  with optional title . 10 * 11 * Emits the same internalmedia/externalmedia handler calls as DokuWiki's 12 * {{...}} media mode so renderers, indexers, and reverse renderers need no 13 * changes. Width, height, cache, linking, and alignment directives are 14 * accepted via the same URL-parameter vocabulary as DW media 15 * (?100x200&nolink&recache, ?right, ?center, etc.) through shared parsing 16 * in Helpers\Media::parseParameters() — the last `?` in the URL delimits 17 * the DW parameter block, so query-bearing URLs like 18 * https://example.com/img?v=2?100x100&right still work. GFM has no native 19 * alignment syntax, so the `?left`/`?right`/`?center` keywords are the 20 * canonical way to align an inline GFM image. 21 * 22 * Deliberately not supported (see skip.php for the affected spec examples): 23 * 24 * - Reference-style images ![text][id] / ![text][] / ![foo] — the 25 * single-pass lexer cannot resolve forward references to [foo]: url 26 * definitions. 27 * - Pointy-bracket destinations  — rarely used. 28 * - Nested brackets in alt text (](y), ](y)) 29 * — leftmost-match cannot reorder; outer falls back to literal. 30 * - Title HTML attribute — DokuWiki media instructions have no separate 31 * title-attribute slot (alt is used as the caption). The title parses 32 * cleanly but is discarded. 33 * - Mixed syntax:  inside [[dw|link]] or {{dw|media}} inside 34 * [gfm](link) — cross-syntax nesting is out of scope. 35 */ 36class GfmMedia extends AbstractMode 37{ 38 /** @inheritdoc */ 39 public function getSort() 40 { 41 return 310; 42 } 43 44 /** @inheritdoc */ 45 public function connectTo($mode) 46 { 47 // Outer shape: ``. Alt class forbids brackets and 48 // newlines; URL slot is permissive (`[^)\n]+`) — handle() does 49 // URL / title splitting post-entry, mirroring how GfmLink and DW 50 // Internallink work. 51 $this->Lexer->addSpecialPattern('!\[[^\[\]\n]*\]\([^)\n]+\)', $mode, 'gfm_media'); 52 } 53 54 /** @inheritdoc */ 55 public function handle($match, $state, $pos, Handler $handler) 56 { 57 $sep = strpos($match, ']('); 58 $alt = substr($match, 2, $sep - 2); 59 $inside = trim(substr($match, $sep + 2, -1)); 60 $url = substr($inside, 0, strcspn($inside, " \t\n")); 61 62 $p = MediaHelper::parseParameters($url); 63 64 $call = (media_isexternal($p['src']) || link_isinterwiki($p['src'])) 65 ? 'externalmedia' 66 : 'internalmedia'; 67 68 $handler->addCall( 69 $call, 70 [$p['src'], $alt !== '' ? $alt : null, $p['align'], $p['width'], $p['height'], $p['cache'], $p['linking']], 71 $pos 72 ); 73 return true; 74 } 75} 76