xref: /plugin/skillforge/syntax.php (revision 1729dd472fd5524951126802d13bd2e76b84b680)
1*1729dd47SHenrik Yllemo<?php
2*1729dd47SHenrik Yllemoif (!defined('DOKU_INC')) die();
3*1729dd47SHenrik Yllemo
4*1729dd47SHenrik Yllemo/**
5*1729dd47SHenrik Yllemo * Optional syntax component: renders <frontmatter> and <skillmeta> blocks as
6*1729dd47SHenrik Yllemo * readable page metadata with an optional ZIP download action.
7*1729dd47SHenrik Yllemo */
8*1729dd47SHenrik Yllemoclass syntax_plugin_skillforge extends DokuWiki_Syntax_Plugin {
9*1729dd47SHenrik Yllemo    public function getType() { return 'substition'; }
10*1729dd47SHenrik Yllemo    public function getSort() { return 32; }
11*1729dd47SHenrik Yllemo    public function connectTo($mode) {
12*1729dd47SHenrik Yllemo        $this->Lexer->addSpecialPattern('<frontmatter>.*?</frontmatter>', $mode, 'plugin_skillforge');
13*1729dd47SHenrik Yllemo        $this->Lexer->addSpecialPattern('<skillmeta>.*?</skillmeta>', $mode, 'plugin_skillforge');
14*1729dd47SHenrik Yllemo    }
15*1729dd47SHenrik Yllemo
16*1729dd47SHenrik Yllemo    public function handle($match, $state, $pos, Doku_Handler $handler) {
17*1729dd47SHenrik Yllemo        if (preg_match('/^<(frontmatter|skillmeta)>(.*?)<\/\1>$/is', $match, $m)) {
18*1729dd47SHenrik Yllemo            return array('metadata' => trim($m[2]));
19*1729dd47SHenrik Yllemo        }
20*1729dd47SHenrik Yllemo        return array('metadata' => '');
21*1729dd47SHenrik Yllemo    }
22*1729dd47SHenrik Yllemo
23*1729dd47SHenrik Yllemo    public function render($mode, Doku_Renderer $renderer, $data) {
24*1729dd47SHenrik Yllemo        if ($mode !== 'xhtml') return true;
25*1729dd47SHenrik Yllemo
26*1729dd47SHenrik Yllemo        $showMetadata = (bool)$this->getConf('show_rendered_metadata');
27*1729dd47SHenrik Yllemo        $showDownload = (bool)$this->getConf('show_page_download_button');
28*1729dd47SHenrik Yllemo        if (!$showMetadata && !$showDownload) return true;
29*1729dd47SHenrik Yllemo
30*1729dd47SHenrik Yllemo        $content = '';
31*1729dd47SHenrik Yllemo        if ($showMetadata) {
32*1729dd47SHenrik Yllemo            $content .= $this->renderMetadata($data['metadata']);
33*1729dd47SHenrik Yllemo        }
34*1729dd47SHenrik Yllemo        if ($showDownload && auth_isadmin()) {
35*1729dd47SHenrik Yllemo            $content .= $this->renderDownloadButton($data['metadata']);
36*1729dd47SHenrik Yllemo        }
37*1729dd47SHenrik Yllemo        if ($content === '') return true;
38*1729dd47SHenrik Yllemo
39*1729dd47SHenrik Yllemo        $renderer->doc .= '<div class="skillforge-page-tools">' . $content . '</div>';
40*1729dd47SHenrik Yllemo        return true;
41*1729dd47SHenrik Yllemo    }
42*1729dd47SHenrik Yllemo
43*1729dd47SHenrik Yllemo    private function renderMetadata($metadata) {
44*1729dd47SHenrik Yllemo        $fields = $this->parseMetadata($metadata);
45*1729dd47SHenrik Yllemo        if (!$fields) return '';
46*1729dd47SHenrik Yllemo
47*1729dd47SHenrik Yllemo        $html = '<section class="skillforge-metadata"><h2>Skill metadata</h2><dl>';
48*1729dd47SHenrik Yllemo        foreach ($fields as $name => $value) {
49*1729dd47SHenrik Yllemo            $html .= '<dt>' . hsc($name) . '</dt><dd>';
50*1729dd47SHenrik Yllemo            if (is_array($value)) {
51*1729dd47SHenrik Yllemo                $html .= '<ul>';
52*1729dd47SHenrik Yllemo                foreach ($value as $item) {
53*1729dd47SHenrik Yllemo                    $html .= '<li>' . hsc($item) . '</li>';
54*1729dd47SHenrik Yllemo                }
55*1729dd47SHenrik Yllemo                $html .= '</ul>';
56*1729dd47SHenrik Yllemo            } else {
57*1729dd47SHenrik Yllemo                $html .= hsc($value);
58*1729dd47SHenrik Yllemo            }
59*1729dd47SHenrik Yllemo            $html .= '</dd>';
60*1729dd47SHenrik Yllemo        }
61*1729dd47SHenrik Yllemo        return $html . '</dl></section>';
62*1729dd47SHenrik Yllemo    }
63*1729dd47SHenrik Yllemo
64*1729dd47SHenrik Yllemo    private function renderDownloadButton($metadata) {
65*1729dd47SHenrik Yllemo        global $ID;
66*1729dd47SHenrik Yllemo        $url = wl($ID, array(
67*1729dd47SHenrik Yllemo            'do' => 'skillforge_download_current',
68*1729dd47SHenrik Yllemo            'sf_page' => $ID,
69*1729dd47SHenrik Yllemo            'sectok' => getSecurityToken()
70*1729dd47SHenrik Yllemo        ), false, '&');
71*1729dd47SHenrik Yllemo        $label = $this->downloadButtonLabel($metadata);
72*1729dd47SHenrik Yllemo
73*1729dd47SHenrik Yllemo        return '<p class="skillforge-download"><a class="button" href="' . hsc($url) . '">' . hsc($label) . '</a></p>';
74*1729dd47SHenrik Yllemo    }
75*1729dd47SHenrik Yllemo
76*1729dd47SHenrik Yllemo    private function downloadButtonLabel($metadata) {
77*1729dd47SHenrik Yllemo        $label = trim((string)$this->getConf('download_button_label'));
78*1729dd47SHenrik Yllemo        if ($label === '') $label = 'Download SKILL.md (.zip)';
79*1729dd47SHenrik Yllemo
80*1729dd47SHenrik Yllemo        $fields = $this->parseMetadata($metadata);
81*1729dd47SHenrik Yllemo        $replacements = array(
82*1729dd47SHenrik Yllemo            '{name}' => isset($fields['name']) && !is_array($fields['name']) ? $fields['name'] : '',
83*1729dd47SHenrik Yllemo            '{title}' => isset($fields['title']) && !is_array($fields['title']) ? $fields['title'] : '',
84*1729dd47SHenrik Yllemo            '{description}' => isset($fields['description']) && !is_array($fields['description']) ? $fields['description'] : '',
85*1729dd47SHenrik Yllemo            '{output}' => $this->getConf('output_skill_filename') ?: 'SKILL.md',
86*1729dd47SHenrik Yllemo        );
87*1729dd47SHenrik Yllemo
88*1729dd47SHenrik Yllemo        $label = str_replace(array_keys($replacements), array_values($replacements), $label);
89*1729dd47SHenrik Yllemo        $label = preg_replace('/\s+/', ' ', trim($label));
90*1729dd47SHenrik Yllemo        return $label !== '' ? $label : 'Download SKILL.md (.zip)';
91*1729dd47SHenrik Yllemo    }
92*1729dd47SHenrik Yllemo
93*1729dd47SHenrik Yllemo    private function parseMetadata($metadata) {
94*1729dd47SHenrik Yllemo        $fields = array();
95*1729dd47SHenrik Yllemo        $current = null;
96*1729dd47SHenrik Yllemo        foreach (preg_split('/\R/', (string)$metadata) as $line) {
97*1729dd47SHenrik Yllemo            $line = rtrim($line);
98*1729dd47SHenrik Yllemo            if ($line === '' || preg_match('/^\s*#/', $line)) continue;
99*1729dd47SHenrik Yllemo
100*1729dd47SHenrik Yllemo            if ($current !== null && preg_match('/^\s*-\s*(.+)$/', $line, $m)) {
101*1729dd47SHenrik Yllemo                if (!isset($fields[$current]) || !is_array($fields[$current])) $fields[$current] = array();
102*1729dd47SHenrik Yllemo                $fields[$current][] = trim($m[1], " \t\"'");
103*1729dd47SHenrik Yllemo                continue;
104*1729dd47SHenrik Yllemo            }
105*1729dd47SHenrik Yllemo
106*1729dd47SHenrik Yllemo            if (preg_match('/^([A-Za-z0-9_.-]+):\s*(.*)$/', $line, $m)) {
107*1729dd47SHenrik Yllemo                $current = $m[1];
108*1729dd47SHenrik Yllemo                $value = trim($m[2], " \t\"'");
109*1729dd47SHenrik Yllemo                $fields[$current] = ($value === '') ? array() : $value;
110*1729dd47SHenrik Yllemo            }
111*1729dd47SHenrik Yllemo        }
112*1729dd47SHenrik Yllemo        return $fields;
113*1729dd47SHenrik Yllemo    }
114*1729dd47SHenrik Yllemo}
115