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