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 54293182bbSAnna 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']; 62*8fdbbd20SAnna Dabrowska $this->docArray['authors']['*'] = 0; 634ea373cdSAndreas Gohr 644ea373cdSAndreas Gohr // get author info 655929c83eSMichael Große $changelog = new PageChangelog($ID); 665929c83eSMichael Große $revs = $changelog->getRevisions(0, 10000); //FIXME find a good solution for 'get ALL revisions' 674ea373cdSAndreas Gohr array_push($revs, $meta['last_change']['date']); 687db0beafSAnna Dabrowska $this->docArray['changes'] = count($revs); 694ea373cdSAndreas Gohr foreach ($revs as $rev) { 70088a1fe7SMichael Grosse $info = $changelog->getRevisionInfo($rev); 714ea373cdSAndreas Gohr if ($info['user']) { 72*8fdbbd20SAnna Dabrowska $authorUserCnt = !empty($this->docArray['authors'][$info['user']]) 73*8fdbbd20SAnna Dabrowska ? $this->docArray['authors'][$info['user']] 74*8fdbbd20SAnna Dabrowska : 0; 75*8fdbbd20SAnna Dabrowska $this->docArray['authors'][$info['user']] = $authorUserCnt + 1; 764ea373cdSAndreas Gohr } else { 777db0beafSAnna Dabrowska $this->docArray['authors']['*'] += 1; 784ea373cdSAndreas Gohr } 794ea373cdSAndreas Gohr } 804ea373cdSAndreas Gohr 814ea373cdSAndreas Gohr // work on raw text 824ea373cdSAndreas Gohr $text = rawWiki($ID); 837db0beafSAnna Dabrowska $this->docArray['chars'] = utf8_strlen($text); 847db0beafSAnna Dabrowska $this->docArray['words'] = count(array_filter(preg_split('/[^\w\-_]/u', $text))); 854ea373cdSAndreas Gohr } 864ea373cdSAndreas Gohr 874ea373cdSAndreas Gohr 888fce80b1SAndreas Gohr /** 898fce80b1SAndreas Gohr * Here the score is calculated 908fce80b1SAndreas Gohr */ 91293182bbSAnna Dabrowska public function document_end() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 9276bbc49cSAnna Dabrowska { 93e348ef7cSAndreas Gohr global $ID; 94e348ef7cSAndreas Gohr 95e348ef7cSAndreas Gohr // 2 points for missing backlinks 96e348ef7cSAndreas Gohr if (!count(ft_backlinks($ID))) { 977db0beafSAnna Dabrowska $this->docArray['err']['nobacklink'] += 2; 98e348ef7cSAndreas Gohr } 998fce80b1SAndreas Gohr 1008fce80b1SAndreas Gohr // 1 point for each FIXME 1017db0beafSAnna Dabrowska $this->docArray['err']['fixme'] += $this->docArray['fixme']; 1028fce80b1SAndreas Gohr 1038fce80b1SAndreas Gohr // 5 points for missing H1 1047db0beafSAnna Dabrowska if ($this->docArray['header_count'][1] == 0) { 1057db0beafSAnna Dabrowska $this->docArray['err']['noh1'] += 5; 1068fce80b1SAndreas Gohr } 1078fce80b1SAndreas Gohr // 1 point for each H1 too much 1087db0beafSAnna Dabrowska if ($this->docArray['header_count'][1] > 1) { 1097db0beafSAnna Dabrowska $this->docArray['err']['manyh1'] += $this->docArray['header'][1]; 1108fce80b1SAndreas Gohr } 1118fce80b1SAndreas Gohr 1128fce80b1SAndreas Gohr // 1 point for each incorrectly nested headline 1137db0beafSAnna Dabrowska $cnt = count($this->docArray['header_struct']); 1148fce80b1SAndreas Gohr for ($i = 1; $i < $cnt; $i++) { 1157db0beafSAnna Dabrowska if ($this->docArray['header_struct'][$i] - $this->docArray['header_struct'][$i - 1] > 1) { 1167db0beafSAnna Dabrowska $this->docArray['err']['headernest'] += 1; 1178fce80b1SAndreas Gohr } 1188fce80b1SAndreas Gohr } 1198fce80b1SAndreas Gohr 1208fce80b1SAndreas Gohr // 1/2 points for deeply nested quotations 1217db0beafSAnna Dabrowska if ($this->docArray['quote_nest'] > 2) { 1227db0beafSAnna Dabrowska $this->docArray['err']['deepquote'] += $this->docArray['quote_nest'] / 2; 1238fce80b1SAndreas Gohr } 1248fce80b1SAndreas Gohr 1258fce80b1SAndreas Gohr // FIXME points for many quotes? 1268fce80b1SAndreas Gohr 1278fce80b1SAndreas Gohr // 1/2 points for too many hr 1287db0beafSAnna Dabrowska if ($this->docArray['hr'] > 2) { 1297db0beafSAnna Dabrowska $this->docArray['err']['manyhr'] = ($this->docArray['hr'] - 2) / 2; 1308fce80b1SAndreas Gohr } 1318fce80b1SAndreas Gohr 1328fce80b1SAndreas Gohr // 1 point for too many line breaks 1337db0beafSAnna Dabrowska if ($this->docArray['linebreak'] > 2) { 1347db0beafSAnna Dabrowska $this->docArray['err']['manybr'] = $this->docArray['linebreak'] - 2; 1358fce80b1SAndreas Gohr } 1368fce80b1SAndreas Gohr 1374ea373cdSAndreas Gohr // 1 point for single author only 1387db0beafSAnna Dabrowska if (!$this->getConf('single_author_only') && count($this->docArray['authors']) == 1) { 1397db0beafSAnna Dabrowska $this->docArray['err']['singleauthor'] = 1; 1404ea373cdSAndreas Gohr } 1414ea373cdSAndreas Gohr 142d723b313SAndreas Gohr // 1 point for too small document 1437db0beafSAnna Dabrowska if ($this->docArray['chars'] < 150) { 1447db0beafSAnna Dabrowska $this->docArray['err']['toosmall'] = 1; 145d723b313SAndreas Gohr } 146d723b313SAndreas Gohr 147d723b313SAndreas Gohr // 1 point for too large document 1487db0beafSAnna Dabrowska if ($this->docArray['chars'] > 100000) { 1497db0beafSAnna Dabrowska $this->docArray['err']['toolarge'] = 1; 150d723b313SAndreas Gohr } 151d723b313SAndreas Gohr 152d723b313SAndreas Gohr // header to text ratio 1537db0beafSAnna Dabrowska $hc = $this->docArray['header_count'][1] + 1547db0beafSAnna Dabrowska $this->docArray['header_count'][2] + 1557db0beafSAnna Dabrowska $this->docArray['header_count'][3] + 1567db0beafSAnna Dabrowska $this->docArray['header_count'][4] + 1577db0beafSAnna Dabrowska $this->docArray['header_count'][5]; 15813abf7ccSAndreas Gohr $hc--; //we expect at least 1 15913abf7ccSAndreas Gohr if ($hc > 0) { 1607db0beafSAnna Dabrowska $hr = $this->docArray['chars'] / $hc; 161d723b313SAndreas Gohr 162d723b313SAndreas Gohr // 1 point for too many headers 163d723b313SAndreas Gohr if ($hr < 200) { 1647db0beafSAnna Dabrowska $this->docArray['err']['manyheaders'] = 1; 165d723b313SAndreas Gohr } 166d723b313SAndreas Gohr 167d723b313SAndreas Gohr // 1 point for too few headers 1681b085f03SAndreas Gohr if ($hr > 2000) { 1697db0beafSAnna Dabrowska $this->docArray['err']['fewheaders'] = 1; 170d723b313SAndreas Gohr } 171d723b313SAndreas Gohr } 172d723b313SAndreas Gohr 173d723b313SAndreas Gohr // 1 point when no link at all 1747db0beafSAnna Dabrowska if (!$this->docArray['internal_links']) { 1757db0beafSAnna Dabrowska $this->docArray['err']['nolink'] = 1; 176d723b313SAndreas Gohr } 177d723b313SAndreas Gohr 178d723b313SAndreas Gohr // 0.5 for broken links when too many 1797db0beafSAnna Dabrowska if ($this->docArray['broken_links'] > 2) { 1807db0beafSAnna Dabrowska $this->docArray['err']['brokenlink'] = $this->docArray['broken_links'] * 0.5; 181d723b313SAndreas Gohr } 182d723b313SAndreas Gohr 183d723b313SAndreas Gohr // 2 points for lot's of formatting 1847db0beafSAnna Dabrowska if ($this->docArray['formatted'] && $this->docArray['chars'] / $this->docArray['formatted'] < 3) { 1857db0beafSAnna Dabrowska $this->docArray['err']['manyformat'] = 2; 186d723b313SAndreas Gohr } 187d723b313SAndreas Gohr 1889068e431SAndreas Gohr // add up all scores 1897db0beafSAnna Dabrowska foreach ($this->docArray['err'] as $err => $val) $this->docArray['score'] += $val; 1909068e431SAndreas Gohr 1914ea373cdSAndreas Gohr 1928fce80b1SAndreas Gohr //we're done here 1937db0beafSAnna Dabrowska $this->doc = serialize($this->docArray); 1948fce80b1SAndreas Gohr } 1958fce80b1SAndreas Gohr 1968fce80b1SAndreas Gohr /** 1978fce80b1SAndreas Gohr * the format we produce 1988fce80b1SAndreas Gohr */ 19976bbc49cSAnna Dabrowska public function getFormat() 20076bbc49cSAnna Dabrowska { 2018fce80b1SAndreas Gohr return 'qc'; 2028fce80b1SAndreas Gohr } 2038fce80b1SAndreas Gohr 20476bbc49cSAnna Dabrowska public function internallink($id, $name = null, $search = null, $returnonly = false, $linktype = 'content') 20576bbc49cSAnna Dabrowska { 206d723b313SAndreas Gohr global $ID; 207d723b313SAndreas Gohr resolve_pageid(getNS($ID), $id, $exists); 208d723b313SAndreas Gohr 2098d7cf088SAndreas Gohr // calculate link width 210d78155a4SAndreas Gohr $a = explode(':', getNS($ID)); 211d78155a4SAndreas Gohr $b = explode(':', getNS($id)); 212d78155a4SAndreas Gohr while (isset($a[0]) && $a[0] == $b[0]) { 2138d7cf088SAndreas Gohr array_shift($a); 2148d7cf088SAndreas Gohr array_shift($b); 2158d7cf088SAndreas Gohr } 216d78155a4SAndreas Gohr $length = count($a) + count($b); 2177db0beafSAnna Dabrowska $this->docArray['link_lengths'][] = $length; 2188d7cf088SAndreas Gohr 2197db0beafSAnna Dabrowska $this->docArray['internal_links']++; 2207db0beafSAnna Dabrowska if (!$exists) $this->docArray['broken_links']++; 2210476d180SAndreas Gohr } 2220476d180SAndreas Gohr 22376bbc49cSAnna Dabrowska public function externallink($url, $name = null) 22476bbc49cSAnna Dabrowska { 2257db0beafSAnna Dabrowska $this->docArray['external_links']++; 226d723b313SAndreas Gohr } 2278fce80b1SAndreas Gohr 22876bbc49cSAnna Dabrowska public function header($text, $level, $pos) 22976bbc49cSAnna Dabrowska { 2307db0beafSAnna Dabrowska $this->docArray['header_count'][$level]++; 2317db0beafSAnna Dabrowska $this->docArray['header_struct'][] = $level; 2328fce80b1SAndreas Gohr } 2338fce80b1SAndreas Gohr 23476bbc49cSAnna Dabrowska public function smiley($smiley) 23576bbc49cSAnna Dabrowska { 2367db0beafSAnna Dabrowska if ($smiley == 'FIXME') $this->docArray['fixme']++; 2378fce80b1SAndreas Gohr } 2388fce80b1SAndreas Gohr 23976bbc49cSAnna Dabrowska public function linebreak() 24076bbc49cSAnna Dabrowska { 2416afc1841Sthesunrise1983 if (!$this->tableopen) { 2427db0beafSAnna Dabrowska $this->docArray['linebreak']++; 2438fce80b1SAndreas Gohr } 2446afc1841Sthesunrise1983 } 2456afc1841Sthesunrise1983 246293182bbSAnna Dabrowska public function table_open($maxcols = null, $numrows = null, $pos = null) // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 24776bbc49cSAnna Dabrowska { 2486afc1841Sthesunrise1983 $this->tableopen = true; 2496afc1841Sthesunrise1983 } 2506afc1841Sthesunrise1983 251293182bbSAnna Dabrowska public function table_close($pos = null) // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 25276bbc49cSAnna Dabrowska { 2536afc1841Sthesunrise1983 $this->tableopen = false; 2546afc1841Sthesunrise1983 } 2558fce80b1SAndreas Gohr 25676bbc49cSAnna Dabrowska public function hr() 25776bbc49cSAnna Dabrowska { 2587db0beafSAnna Dabrowska $this->docArray['hr']++; 2598fce80b1SAndreas Gohr } 2608fce80b1SAndreas Gohr 261293182bbSAnna Dabrowska public function quote_open() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 26276bbc49cSAnna Dabrowska { 2637db0beafSAnna Dabrowska $this->docArray['quote_count']++; 2648fce80b1SAndreas Gohr $this->quotelevel++; 2657db0beafSAnna Dabrowska $this->docArray['quote_nest'] = max($this->quotelevel, $this->docArray['quote_nest']); 2668fce80b1SAndreas Gohr } 2678fce80b1SAndreas Gohr 268293182bbSAnna Dabrowska public function quote_close() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 26976bbc49cSAnna Dabrowska { 2708fce80b1SAndreas Gohr $this->quotelevel--; 2718fce80b1SAndreas Gohr } 2728fce80b1SAndreas Gohr 273293182bbSAnna Dabrowska public function strong_open() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 27476bbc49cSAnna Dabrowska { 275d723b313SAndreas Gohr $this->formatting++; 276d723b313SAndreas Gohr } 2778fce80b1SAndreas Gohr 278293182bbSAnna Dabrowska public function strong_close() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 27976bbc49cSAnna Dabrowska { 280d723b313SAndreas Gohr $this->formatting--; 281d723b313SAndreas Gohr } 282d723b313SAndreas Gohr 283293182bbSAnna Dabrowska public function emphasis_open() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 28476bbc49cSAnna Dabrowska { 285d723b313SAndreas Gohr $this->formatting++; 286d723b313SAndreas Gohr } 287d723b313SAndreas Gohr 288293182bbSAnna Dabrowska public function emphasis_close() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 28976bbc49cSAnna Dabrowska { 290d723b313SAndreas Gohr $this->formatting--; 291d723b313SAndreas Gohr } 292d723b313SAndreas Gohr 293293182bbSAnna Dabrowska public function underline_open() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 29476bbc49cSAnna Dabrowska { 295d723b313SAndreas Gohr $this->formatting++; 296d723b313SAndreas Gohr } 297d723b313SAndreas Gohr 298293182bbSAnna Dabrowska public function underline_close() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 29976bbc49cSAnna Dabrowska { 300d723b313SAndreas Gohr $this->formatting--; 301d723b313SAndreas Gohr } 302d723b313SAndreas Gohr 30376bbc49cSAnna Dabrowska public function cdata($text) 30476bbc49cSAnna Dabrowska { 305d723b313SAndreas Gohr if (!$this->formatting) return; 306d723b313SAndreas Gohr 307d723b313SAndreas Gohr $len = utf8_strlen($text); 308d723b313SAndreas Gohr 309d723b313SAndreas Gohr // 1 point for formattings longer than 500 chars 3107db0beafSAnna Dabrowska if ($len > 500) $this->docArray['err']['longformat']++; 311d723b313SAndreas Gohr 3124bda998cSAndreas Gohr // 1 point for each multiformatting 3137db0beafSAnna Dabrowska if ($this->formatting > 1) $this->docArray['err']['multiformat'] += 1 * ($this->formatting - 1); 3144bda998cSAndreas Gohr 3157db0beafSAnna Dabrowska $this->docArray['formatted'] += $len; 316d723b313SAndreas Gohr } 3178fce80b1SAndreas Gohr} 3188fce80b1SAndreas Gohr 3198fce80b1SAndreas Gohr//Setup VIM: ex: et ts=4 enc=utf-8 : 320