18fce80b1SAndreas Gohr<?php 276bbc49cSAnna Dabrowska 38fce80b1SAndreas Gohr/** 48fce80b1SAndreas Gohr * The Renderer 58fce80b1SAndreas Gohr */ 676bbc49cSAnna Dabrowskaclass renderer_plugin_qc extends Doku_Renderer 776bbc49cSAnna Dabrowska{ 88fce80b1SAndreas Gohr /** 98fce80b1SAndreas Gohr * We store all our data in an array 108fce80b1SAndreas Gohr */ 117db0beafSAnna Dabrowska public $docArray = array( 128fce80b1SAndreas Gohr // raw statistics 138fce80b1SAndreas Gohr 'header_count' => array(0,0,0,0,0,0), 148fce80b1SAndreas Gohr 'header_struct' => array(), 158fce80b1SAndreas Gohr 'linebreak' => 0, 168fce80b1SAndreas Gohr 'quote_nest' => 0, 178fce80b1SAndreas Gohr 'quote_count' => 0, 188fce80b1SAndreas Gohr 'fixme' => 0, 198fce80b1SAndreas Gohr 'hr' => 0, 20d723b313SAndreas Gohr 'formatted' => 0, 218fce80b1SAndreas Gohr 224ea373cdSAndreas Gohr 'created' => 0, 234ea373cdSAndreas Gohr 'modified' => 0, 244ea373cdSAndreas Gohr 'changes' => 0, 254ea373cdSAndreas Gohr 'authors' => array(), 264ea373cdSAndreas Gohr 27d723b313SAndreas Gohr 'internal_links' => 0, 28d723b313SAndreas Gohr 'broken_links' => 0, 29d723b313SAndreas Gohr 'external_links' => 0, 308d7cf088SAndreas Gohr 'link_lengths' => array(), 31d723b313SAndreas Gohr 324ea373cdSAndreas Gohr 'chars' => 0, 334ea373cdSAndreas Gohr 'words' => 0, 344ea373cdSAndreas Gohr 359068e431SAndreas Gohr 'score' => 0, 369068e431SAndreas Gohr 378fce80b1SAndreas Gohr // calculated error scores 388fce80b1SAndreas Gohr 'err' => array( 398fce80b1SAndreas Gohr 'fixme' => 0, 408fce80b1SAndreas Gohr 'noh1' => 0, 418fce80b1SAndreas Gohr 'manyh1' => 0, 428fce80b1SAndreas Gohr 'headernest' => 0, 438fce80b1SAndreas Gohr 'manyhr' => 0, 448fce80b1SAndreas Gohr 'manybr' => 0, 45d723b313SAndreas Gohr 'longformat' => 0, 464bda998cSAndreas Gohr 'multiformat' => 0, 478fce80b1SAndreas Gohr ), 488fce80b1SAndreas Gohr ); 498fce80b1SAndreas Gohr 507db0beafSAnna Dabrowska protected $quotelevel = 0; 517db0beafSAnna Dabrowska protected $formatting = 0; 527db0beafSAnna Dabrowska protected $tableopen = false; 538fce80b1SAndreas Gohr 54*293182bbSAnna Dabrowska public function document_start() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 5576bbc49cSAnna Dabrowska { 564ea373cdSAndreas Gohr global $ID; 574ea373cdSAndreas Gohr $meta = p_get_metadata($ID); 584ea373cdSAndreas Gohr 594ea373cdSAndreas Gohr // get some dates from meta data 607db0beafSAnna Dabrowska $this->docArray['created'] = $meta['date']['created']; 617db0beafSAnna Dabrowska $this->docArray['modified'] = $meta['date']['modified']; 624ea373cdSAndreas Gohr 634ea373cdSAndreas Gohr // get author info 645929c83eSMichael Große $changelog = new PageChangelog($ID); 655929c83eSMichael Große $revs = $changelog->getRevisions(0, 10000); //FIXME find a good solution for 'get ALL revisions' 664ea373cdSAndreas Gohr array_push($revs, $meta['last_change']['date']); 677db0beafSAnna Dabrowska $this->docArray['changes'] = count($revs); 684ea373cdSAndreas Gohr foreach ($revs as $rev) { 69088a1fe7SMichael Grosse $info = $changelog->getRevisionInfo($rev); 704ea373cdSAndreas Gohr if ($info['user']) { 717db0beafSAnna Dabrowska $this->docArray['authors'][$info['user']] += 1; 724ea373cdSAndreas Gohr } else { 737db0beafSAnna Dabrowska $this->docArray['authors']['*'] += 1; 744ea373cdSAndreas Gohr } 754ea373cdSAndreas Gohr } 764ea373cdSAndreas Gohr 774ea373cdSAndreas Gohr // work on raw text 784ea373cdSAndreas Gohr $text = rawWiki($ID); 797db0beafSAnna Dabrowska $this->docArray['chars'] = utf8_strlen($text); 807db0beafSAnna Dabrowska $this->docArray['words'] = count(array_filter(preg_split('/[^\w\-_]/u', $text))); 814ea373cdSAndreas Gohr } 824ea373cdSAndreas Gohr 834ea373cdSAndreas Gohr 848fce80b1SAndreas Gohr /** 858fce80b1SAndreas Gohr * Here the score is calculated 868fce80b1SAndreas Gohr */ 87*293182bbSAnna Dabrowska public function document_end() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 8876bbc49cSAnna Dabrowska { 89e348ef7cSAndreas Gohr global $ID; 90e348ef7cSAndreas Gohr 91e348ef7cSAndreas Gohr // 2 points for missing backlinks 92e348ef7cSAndreas Gohr if (!count(ft_backlinks($ID))) { 937db0beafSAnna Dabrowska $this->docArray['err']['nobacklink'] += 2; 94e348ef7cSAndreas Gohr } 958fce80b1SAndreas Gohr 968fce80b1SAndreas Gohr // 1 point for each FIXME 977db0beafSAnna Dabrowska $this->docArray['err']['fixme'] += $this->docArray['fixme']; 988fce80b1SAndreas Gohr 998fce80b1SAndreas Gohr // 5 points for missing H1 1007db0beafSAnna Dabrowska if ($this->docArray['header_count'][1] == 0) { 1017db0beafSAnna Dabrowska $this->docArray['err']['noh1'] += 5; 1028fce80b1SAndreas Gohr } 1038fce80b1SAndreas Gohr // 1 point for each H1 too much 1047db0beafSAnna Dabrowska if ($this->docArray['header_count'][1] > 1) { 1057db0beafSAnna Dabrowska $this->docArray['err']['manyh1'] += $this->docArray['header'][1]; 1068fce80b1SAndreas Gohr } 1078fce80b1SAndreas Gohr 1088fce80b1SAndreas Gohr // 1 point for each incorrectly nested headline 1097db0beafSAnna Dabrowska $cnt = count($this->docArray['header_struct']); 1108fce80b1SAndreas Gohr for ($i = 1; $i < $cnt; $i++) { 1117db0beafSAnna Dabrowska if ($this->docArray['header_struct'][$i] - $this->docArray['header_struct'][$i - 1] > 1) { 1127db0beafSAnna Dabrowska $this->docArray['err']['headernest'] += 1; 1138fce80b1SAndreas Gohr } 1148fce80b1SAndreas Gohr } 1158fce80b1SAndreas Gohr 1168fce80b1SAndreas Gohr // 1/2 points for deeply nested quotations 1177db0beafSAnna Dabrowska if ($this->docArray['quote_nest'] > 2) { 1187db0beafSAnna Dabrowska $this->docArray['err']['deepquote'] += $this->docArray['quote_nest'] / 2; 1198fce80b1SAndreas Gohr } 1208fce80b1SAndreas Gohr 1218fce80b1SAndreas Gohr // FIXME points for many quotes? 1228fce80b1SAndreas Gohr 1238fce80b1SAndreas Gohr // 1/2 points for too many hr 1247db0beafSAnna Dabrowska if ($this->docArray['hr'] > 2) { 1257db0beafSAnna Dabrowska $this->docArray['err']['manyhr'] = ($this->docArray['hr'] - 2) / 2; 1268fce80b1SAndreas Gohr } 1278fce80b1SAndreas Gohr 1288fce80b1SAndreas Gohr // 1 point for too many line breaks 1297db0beafSAnna Dabrowska if ($this->docArray['linebreak'] > 2) { 1307db0beafSAnna Dabrowska $this->docArray['err']['manybr'] = $this->docArray['linebreak'] - 2; 1318fce80b1SAndreas Gohr } 1328fce80b1SAndreas Gohr 1334ea373cdSAndreas Gohr // 1 point for single author only 1347db0beafSAnna Dabrowska if (!$this->getConf('single_author_only') && count($this->docArray['authors']) == 1) { 1357db0beafSAnna Dabrowska $this->docArray['err']['singleauthor'] = 1; 1364ea373cdSAndreas Gohr } 1374ea373cdSAndreas Gohr 138d723b313SAndreas Gohr // 1 point for too small document 1397db0beafSAnna Dabrowska if ($this->docArray['chars'] < 150) { 1407db0beafSAnna Dabrowska $this->docArray['err']['toosmall'] = 1; 141d723b313SAndreas Gohr } 142d723b313SAndreas Gohr 143d723b313SAndreas Gohr // 1 point for too large document 1447db0beafSAnna Dabrowska if ($this->docArray['chars'] > 100000) { 1457db0beafSAnna Dabrowska $this->docArray['err']['toolarge'] = 1; 146d723b313SAndreas Gohr } 147d723b313SAndreas Gohr 148d723b313SAndreas Gohr // header to text ratio 1497db0beafSAnna Dabrowska $hc = $this->docArray['header_count'][1] + 1507db0beafSAnna Dabrowska $this->docArray['header_count'][2] + 1517db0beafSAnna Dabrowska $this->docArray['header_count'][3] + 1527db0beafSAnna Dabrowska $this->docArray['header_count'][4] + 1537db0beafSAnna Dabrowska $this->docArray['header_count'][5]; 15413abf7ccSAndreas Gohr $hc--; //we expect at least 1 15513abf7ccSAndreas Gohr if ($hc > 0) { 1567db0beafSAnna Dabrowska $hr = $this->docArray['chars'] / $hc; 157d723b313SAndreas Gohr 158d723b313SAndreas Gohr // 1 point for too many headers 159d723b313SAndreas Gohr if ($hr < 200) { 1607db0beafSAnna Dabrowska $this->docArray['err']['manyheaders'] = 1; 161d723b313SAndreas Gohr } 162d723b313SAndreas Gohr 163d723b313SAndreas Gohr // 1 point for too few headers 1641b085f03SAndreas Gohr if ($hr > 2000) { 1657db0beafSAnna Dabrowska $this->docArray['err']['fewheaders'] = 1; 166d723b313SAndreas Gohr } 167d723b313SAndreas Gohr } 168d723b313SAndreas Gohr 169d723b313SAndreas Gohr // 1 point when no link at all 1707db0beafSAnna Dabrowska if (!$this->docArray['internal_links']) { 1717db0beafSAnna Dabrowska $this->docArray['err']['nolink'] = 1; 172d723b313SAndreas Gohr } 173d723b313SAndreas Gohr 174d723b313SAndreas Gohr // 0.5 for broken links when too many 1757db0beafSAnna Dabrowska if ($this->docArray['broken_links'] > 2) { 1767db0beafSAnna Dabrowska $this->docArray['err']['brokenlink'] = $this->docArray['broken_links'] * 0.5; 177d723b313SAndreas Gohr } 178d723b313SAndreas Gohr 179d723b313SAndreas Gohr // 2 points for lot's of formatting 1807db0beafSAnna Dabrowska if ($this->docArray['formatted'] && $this->docArray['chars'] / $this->docArray['formatted'] < 3) { 1817db0beafSAnna Dabrowska $this->docArray['err']['manyformat'] = 2; 182d723b313SAndreas Gohr } 183d723b313SAndreas Gohr 1849068e431SAndreas Gohr // add up all scores 1857db0beafSAnna Dabrowska foreach ($this->docArray['err'] as $err => $val) $this->docArray['score'] += $val; 1869068e431SAndreas Gohr 1874ea373cdSAndreas Gohr 1888fce80b1SAndreas Gohr //we're done here 1897db0beafSAnna Dabrowska $this->doc = serialize($this->docArray); 1908fce80b1SAndreas Gohr } 1918fce80b1SAndreas Gohr 1928fce80b1SAndreas Gohr /** 1938fce80b1SAndreas Gohr * the format we produce 1948fce80b1SAndreas Gohr */ 19576bbc49cSAnna Dabrowska public function getFormat() 19676bbc49cSAnna Dabrowska { 1978fce80b1SAndreas Gohr return 'qc'; 1988fce80b1SAndreas Gohr } 1998fce80b1SAndreas Gohr 20076bbc49cSAnna Dabrowska public function internallink($id, $name = null, $search = null, $returnonly = false, $linktype = 'content') 20176bbc49cSAnna Dabrowska { 202d723b313SAndreas Gohr global $ID; 203d723b313SAndreas Gohr resolve_pageid(getNS($ID), $id, $exists); 204d723b313SAndreas Gohr 2058d7cf088SAndreas Gohr // calculate link width 206d78155a4SAndreas Gohr $a = explode(':', getNS($ID)); 207d78155a4SAndreas Gohr $b = explode(':', getNS($id)); 208d78155a4SAndreas Gohr while (isset($a[0]) && $a[0] == $b[0]) { 2098d7cf088SAndreas Gohr array_shift($a); 2108d7cf088SAndreas Gohr array_shift($b); 2118d7cf088SAndreas Gohr } 212d78155a4SAndreas Gohr $length = count($a) + count($b); 2137db0beafSAnna Dabrowska $this->docArray['link_lengths'][] = $length; 2148d7cf088SAndreas Gohr 2157db0beafSAnna Dabrowska $this->docArray['internal_links']++; 2167db0beafSAnna Dabrowska if (!$exists) $this->docArray['broken_links']++; 2170476d180SAndreas Gohr } 2180476d180SAndreas Gohr 21976bbc49cSAnna Dabrowska public function externallink($url, $name = null) 22076bbc49cSAnna Dabrowska { 2217db0beafSAnna Dabrowska $this->docArray['external_links']++; 222d723b313SAndreas Gohr } 2238fce80b1SAndreas Gohr 22476bbc49cSAnna Dabrowska public function header($text, $level, $pos) 22576bbc49cSAnna Dabrowska { 2267db0beafSAnna Dabrowska $this->docArray['header_count'][$level]++; 2277db0beafSAnna Dabrowska $this->docArray['header_struct'][] = $level; 2288fce80b1SAndreas Gohr } 2298fce80b1SAndreas Gohr 23076bbc49cSAnna Dabrowska public function smiley($smiley) 23176bbc49cSAnna Dabrowska { 2327db0beafSAnna Dabrowska if ($smiley == 'FIXME') $this->docArray['fixme']++; 2338fce80b1SAndreas Gohr } 2348fce80b1SAndreas Gohr 23576bbc49cSAnna Dabrowska public function linebreak() 23676bbc49cSAnna Dabrowska { 2376afc1841Sthesunrise1983 if (!$this->tableopen) { 2387db0beafSAnna Dabrowska $this->docArray['linebreak']++; 2398fce80b1SAndreas Gohr } 2406afc1841Sthesunrise1983 } 2416afc1841Sthesunrise1983 242*293182bbSAnna Dabrowska public function table_open($maxcols = null, $numrows = null, $pos = null) // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 24376bbc49cSAnna Dabrowska { 2446afc1841Sthesunrise1983 $this->tableopen = true; 2456afc1841Sthesunrise1983 } 2466afc1841Sthesunrise1983 247*293182bbSAnna Dabrowska public function table_close($pos = null) // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 24876bbc49cSAnna Dabrowska { 2496afc1841Sthesunrise1983 $this->tableopen = false; 2506afc1841Sthesunrise1983 } 2518fce80b1SAndreas Gohr 25276bbc49cSAnna Dabrowska public function hr() 25376bbc49cSAnna Dabrowska { 2547db0beafSAnna Dabrowska $this->docArray['hr']++; 2558fce80b1SAndreas Gohr } 2568fce80b1SAndreas Gohr 257*293182bbSAnna Dabrowska public function quote_open() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 25876bbc49cSAnna Dabrowska { 2597db0beafSAnna Dabrowska $this->docArray['quote_count']++; 2608fce80b1SAndreas Gohr $this->quotelevel++; 2617db0beafSAnna Dabrowska $this->docArray['quote_nest'] = max($this->quotelevel, $this->docArray['quote_nest']); 2628fce80b1SAndreas Gohr } 2638fce80b1SAndreas Gohr 264*293182bbSAnna Dabrowska public function quote_close() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 26576bbc49cSAnna Dabrowska { 2668fce80b1SAndreas Gohr $this->quotelevel--; 2678fce80b1SAndreas Gohr } 2688fce80b1SAndreas Gohr 269*293182bbSAnna Dabrowska public function strong_open() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 27076bbc49cSAnna Dabrowska { 271d723b313SAndreas Gohr $this->formatting++; 272d723b313SAndreas Gohr } 2738fce80b1SAndreas Gohr 274*293182bbSAnna Dabrowska public function strong_close() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 27576bbc49cSAnna Dabrowska { 276d723b313SAndreas Gohr $this->formatting--; 277d723b313SAndreas Gohr } 278d723b313SAndreas Gohr 279*293182bbSAnna Dabrowska public function emphasis_open() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 28076bbc49cSAnna Dabrowska { 281d723b313SAndreas Gohr $this->formatting++; 282d723b313SAndreas Gohr } 283d723b313SAndreas Gohr 284*293182bbSAnna Dabrowska public function emphasis_close() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 28576bbc49cSAnna Dabrowska { 286d723b313SAndreas Gohr $this->formatting--; 287d723b313SAndreas Gohr } 288d723b313SAndreas Gohr 289*293182bbSAnna Dabrowska public function underline_open() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 29076bbc49cSAnna Dabrowska { 291d723b313SAndreas Gohr $this->formatting++; 292d723b313SAndreas Gohr } 293d723b313SAndreas Gohr 294*293182bbSAnna Dabrowska public function underline_close() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 29576bbc49cSAnna Dabrowska { 296d723b313SAndreas Gohr $this->formatting--; 297d723b313SAndreas Gohr } 298d723b313SAndreas Gohr 29976bbc49cSAnna Dabrowska public function cdata($text) 30076bbc49cSAnna Dabrowska { 301d723b313SAndreas Gohr if (!$this->formatting) return; 302d723b313SAndreas Gohr 303d723b313SAndreas Gohr $len = utf8_strlen($text); 304d723b313SAndreas Gohr 305d723b313SAndreas Gohr // 1 point for formattings longer than 500 chars 3067db0beafSAnna Dabrowska if ($len > 500) $this->docArray['err']['longformat']++; 307d723b313SAndreas Gohr 3084bda998cSAndreas Gohr // 1 point for each multiformatting 3097db0beafSAnna Dabrowska if ($this->formatting > 1) $this->docArray['err']['multiformat'] += 1 * ($this->formatting - 1); 3104bda998cSAndreas Gohr 3117db0beafSAnna Dabrowska $this->docArray['formatted'] += $len; 312d723b313SAndreas Gohr } 3138fce80b1SAndreas Gohr} 3148fce80b1SAndreas Gohr 3158fce80b1SAndreas Gohr//Setup VIM: ex: et ts=4 enc=utf-8 : 316