1<?php 2if(!defined('DOKU_INC')) die(); 3 4class syntax_plugin_pgpblock extends DokuWiki_Syntax_Plugin { 5 public function getType() { return 'protected'; } 6 public function getPType() { return 'normal'; } 7 public function getSort() { return 150; } 8 9 public function connectTo($mode) { 10 /** 11 * We use (?s:...) which is the PCRE 'DOTALL' modifier. 12 * This allows the dot (.) to match newlines, which is 13 * mandatory for multi-line PGP blocks. 14 */ 15 $this->Lexer->addSpecialPattern('(?s:<pgp\b.*?>.*?</pgp>)', $mode, 'plugin_pgpblock'); 16 $this->Lexer->addSpecialPattern('(?s:<gpg\b.*?>.*?</gpg>)', $mode, 'plugin_pgpblock'); 17 $this->Lexer->addSpecialPattern('(?s:<pgpfile\b.*?>.*?</pgpfile>)', $mode, 'plugin_pgpblock'); 18 } 19 20 public function handle($match, $state, $pos, Doku_Handler $handler) { 21 // 1. Identify the tag and capture attributes 22 if (preg_match('/^<(pgp|gpg|pgpfile)(.*?)>(.*)<\/\1>$/is', $match, $matches)) { 23 $tag = strtolower($matches[1]); 24 $attr_str = $matches[2]; 25 $text = trim($matches[3]); 26 } else { 27 return false; 28 } 29 30 // 2. Extract filename attribute safely 31 $filename = ''; 32 if (preg_match('/filename=["\']([^"\']+)["\']/i', $attr_str, $fn_match)) { 33 $filename = $fn_match[1]; 34 } 35 36 return array($text, $tag, $filename); 37 } 38 39 public function render($format, Doku_Renderer $renderer, $data) { 40 if($format != 'xhtml' || $data === false) return false; 41 42 list($text, $tag, $filename) = $data; 43 $is_encrypted = (strpos($text, '-----BEGIN PGP MESSAGE-----') !== false); 44 $encoded_text = hsc($text); 45 46 if ($is_encrypted) { 47 $is_file = ($tag === 'pgpfile'); 48 $type_class = $is_file ? 'pgp-type-file' : 'pgp-type-text'; 49 $title = $is_file ? ' Encrypted File' : ' Encrypted Text'; 50 if ($is_file && $filename) $title .= ': ' . hsc($filename); 51 52 $renderer->doc .= '<div class="pgpblock-container ' . $type_class . '">'; 53 $renderer->doc .= '<div class="pgp-header">' . $title . '</div>'; 54 $renderer->doc .= '<pre class="pgpblock">' . $encoded_text . '</pre>'; 55 $renderer->doc .= '</div>'; 56 } else { 57 // Render unencrypted text in the white box 58 $renderer->doc .= '<pre class="pgpblock-plaintext">' . $encoded_text . '</pre>'; 59 } 60 61 return true; 62 } 63} 64