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