18fce80b1SAndreas Gohr<?php 2*76bbc49cSAnna Dabrowska 38fce80b1SAndreas Gohr// must be run within Dokuwiki 48fce80b1SAndreas Gohrif (!defined('DOKU_INC')) die(); 58fce80b1SAndreas Gohr 68fce80b1SAndreas Gohr/** 78fce80b1SAndreas Gohr * The Renderer 88fce80b1SAndreas Gohr */ 9*76bbc49cSAnna Dabrowskaclass renderer_plugin_qc extends Doku_Renderer 10*76bbc49cSAnna Dabrowska{ 118fce80b1SAndreas Gohr /** 128fce80b1SAndreas Gohr * We store all our data in an array 138fce80b1SAndreas Gohr */ 147db0beafSAnna Dabrowska public $docArray = array( 158fce80b1SAndreas Gohr // raw statistics 168fce80b1SAndreas Gohr 'header_count' => array(0,0,0,0,0,0), 178fce80b1SAndreas Gohr 'header_struct' => array(), 188fce80b1SAndreas Gohr 'linebreak' => 0, 198fce80b1SAndreas Gohr 'quote_nest' => 0, 208fce80b1SAndreas Gohr 'quote_count' => 0, 218fce80b1SAndreas Gohr 'fixme' => 0, 228fce80b1SAndreas Gohr 'hr' => 0, 23d723b313SAndreas Gohr 'formatted' => 0, 248fce80b1SAndreas Gohr 254ea373cdSAndreas Gohr 'created' => 0, 264ea373cdSAndreas Gohr 'modified' => 0, 274ea373cdSAndreas Gohr 'changes' => 0, 284ea373cdSAndreas Gohr 'authors' => array(), 294ea373cdSAndreas Gohr 30d723b313SAndreas Gohr 'internal_links' => 0, 31d723b313SAndreas Gohr 'broken_links' => 0, 32d723b313SAndreas Gohr 'external_links' => 0, 338d7cf088SAndreas Gohr 'link_lengths' => array(), 34d723b313SAndreas Gohr 354ea373cdSAndreas Gohr 'chars' => 0, 364ea373cdSAndreas Gohr 'words' => 0, 374ea373cdSAndreas Gohr 389068e431SAndreas Gohr 'score' => 0, 399068e431SAndreas Gohr 408fce80b1SAndreas Gohr // calculated error scores 418fce80b1SAndreas Gohr 'err' => array( 428fce80b1SAndreas Gohr 'fixme' => 0, 438fce80b1SAndreas Gohr 'noh1' => 0, 448fce80b1SAndreas Gohr 'manyh1' => 0, 458fce80b1SAndreas Gohr 'headernest' => 0, 468fce80b1SAndreas Gohr 'manyhr' => 0, 478fce80b1SAndreas Gohr 'manybr' => 0, 48d723b313SAndreas Gohr 'longformat' => 0, 494bda998cSAndreas Gohr 'multiformat' => 0, 508fce80b1SAndreas Gohr ), 518fce80b1SAndreas Gohr ); 528fce80b1SAndreas Gohr 537db0beafSAnna Dabrowska protected $quotelevel = 0; 547db0beafSAnna Dabrowska protected $formatting = 0; 557db0beafSAnna Dabrowska protected $tableopen = false; 568fce80b1SAndreas Gohr 57*76bbc49cSAnna Dabrowska public function document_start() 58*76bbc49cSAnna Dabrowska { 594ea373cdSAndreas Gohr global $ID; 604ea373cdSAndreas Gohr $meta = p_get_metadata($ID); 614ea373cdSAndreas Gohr 624ea373cdSAndreas Gohr // get some dates from meta data 637db0beafSAnna Dabrowska $this->docArray['created'] = $meta['date']['created']; 647db0beafSAnna Dabrowska $this->docArray['modified'] = $meta['date']['modified']; 654ea373cdSAndreas Gohr 664ea373cdSAndreas Gohr // get author info 675929c83eSMichael Große $changelog = new PageChangelog($ID); 685929c83eSMichael Große $revs = $changelog->getRevisions(0, 10000); //FIXME find a good solution for 'get ALL revisions' 694ea373cdSAndreas Gohr array_push($revs, $meta['last_change']['date']); 707db0beafSAnna Dabrowska $this->docArray['changes'] = count($revs); 714ea373cdSAndreas Gohr foreach ($revs as $rev) { 72088a1fe7SMichael Grosse $info = $changelog->getRevisionInfo($rev); 734ea373cdSAndreas Gohr if ($info['user']) { 747db0beafSAnna Dabrowska $this->docArray['authors'][$info['user']] += 1; 754ea373cdSAndreas Gohr } else { 767db0beafSAnna Dabrowska $this->docArray['authors']['*'] += 1; 774ea373cdSAndreas Gohr } 784ea373cdSAndreas Gohr } 794ea373cdSAndreas Gohr 804ea373cdSAndreas Gohr // work on raw text 814ea373cdSAndreas Gohr $text = rawWiki($ID); 827db0beafSAnna Dabrowska $this->docArray['chars'] = utf8_strlen($text); 837db0beafSAnna Dabrowska $this->docArray['words'] = count(array_filter(preg_split('/[^\w\-_]/u', $text))); 844ea373cdSAndreas Gohr } 854ea373cdSAndreas Gohr 864ea373cdSAndreas Gohr 878fce80b1SAndreas Gohr /** 888fce80b1SAndreas Gohr * Here the score is calculated 898fce80b1SAndreas Gohr */ 90*76bbc49cSAnna Dabrowska public function document_end() 91*76bbc49cSAnna Dabrowska { 92e348ef7cSAndreas Gohr global $ID; 93e348ef7cSAndreas Gohr 94e348ef7cSAndreas Gohr // 2 points for missing backlinks 95e348ef7cSAndreas Gohr if (!count(ft_backlinks($ID))) { 967db0beafSAnna Dabrowska $this->docArray['err']['nobacklink'] += 2; 97e348ef7cSAndreas Gohr } 988fce80b1SAndreas Gohr 998fce80b1SAndreas Gohr // 1 point for each FIXME 1007db0beafSAnna Dabrowska $this->docArray['err']['fixme'] += $this->docArray['fixme']; 1018fce80b1SAndreas Gohr 1028fce80b1SAndreas Gohr // 5 points for missing H1 1037db0beafSAnna Dabrowska if ($this->docArray['header_count'][1] == 0) { 1047db0beafSAnna Dabrowska $this->docArray['err']['noh1'] += 5; 1058fce80b1SAndreas Gohr } 1068fce80b1SAndreas Gohr // 1 point for each H1 too much 1077db0beafSAnna Dabrowska if ($this->docArray['header_count'][1] > 1) { 1087db0beafSAnna Dabrowska $this->docArray['err']['manyh1'] += $this->docArray['header'][1]; 1098fce80b1SAndreas Gohr } 1108fce80b1SAndreas Gohr 1118fce80b1SAndreas Gohr // 1 point for each incorrectly nested headline 1127db0beafSAnna Dabrowska $cnt = count($this->docArray['header_struct']); 1138fce80b1SAndreas Gohr for ($i = 1; $i < $cnt; $i++) { 1147db0beafSAnna Dabrowska if ($this->docArray['header_struct'][$i] - $this->docArray['header_struct'][$i - 1] > 1) { 1157db0beafSAnna Dabrowska $this->docArray['err']['headernest'] += 1; 1168fce80b1SAndreas Gohr } 1178fce80b1SAndreas Gohr } 1188fce80b1SAndreas Gohr 1198fce80b1SAndreas Gohr // 1/2 points for deeply nested quotations 1207db0beafSAnna Dabrowska if ($this->docArray['quote_nest'] > 2) { 1217db0beafSAnna Dabrowska $this->docArray['err']['deepquote'] += $this->docArray['quote_nest'] / 2; 1228fce80b1SAndreas Gohr } 1238fce80b1SAndreas Gohr 1248fce80b1SAndreas Gohr // FIXME points for many quotes? 1258fce80b1SAndreas Gohr 1268fce80b1SAndreas Gohr // 1/2 points for too many hr 1277db0beafSAnna Dabrowska if ($this->docArray['hr'] > 2) { 1287db0beafSAnna Dabrowska $this->docArray['err']['manyhr'] = ($this->docArray['hr'] - 2) / 2; 1298fce80b1SAndreas Gohr } 1308fce80b1SAndreas Gohr 1318fce80b1SAndreas Gohr // 1 point for too many line breaks 1327db0beafSAnna Dabrowska if ($this->docArray['linebreak'] > 2) { 1337db0beafSAnna Dabrowska $this->docArray['err']['manybr'] = $this->docArray['linebreak'] - 2; 1348fce80b1SAndreas Gohr } 1358fce80b1SAndreas Gohr 1364ea373cdSAndreas Gohr // 1 point for single author only 1377db0beafSAnna Dabrowska if (!$this->getConf('single_author_only') && count($this->docArray['authors']) == 1) { 1387db0beafSAnna Dabrowska $this->docArray['err']['singleauthor'] = 1; 1394ea373cdSAndreas Gohr } 1404ea373cdSAndreas Gohr 141d723b313SAndreas Gohr // 1 point for too small document 1427db0beafSAnna Dabrowska if ($this->docArray['chars'] < 150) { 1437db0beafSAnna Dabrowska $this->docArray['err']['toosmall'] = 1; 144d723b313SAndreas Gohr } 145d723b313SAndreas Gohr 146d723b313SAndreas Gohr // 1 point for too large document 1477db0beafSAnna Dabrowska if ($this->docArray['chars'] > 100000) { 1487db0beafSAnna Dabrowska $this->docArray['err']['toolarge'] = 1; 149d723b313SAndreas Gohr } 150d723b313SAndreas Gohr 151d723b313SAndreas Gohr // header to text ratio 1527db0beafSAnna Dabrowska $hc = $this->docArray['header_count'][1] + 1537db0beafSAnna Dabrowska $this->docArray['header_count'][2] + 1547db0beafSAnna Dabrowska $this->docArray['header_count'][3] + 1557db0beafSAnna Dabrowska $this->docArray['header_count'][4] + 1567db0beafSAnna Dabrowska $this->docArray['header_count'][5]; 15713abf7ccSAndreas Gohr $hc--; //we expect at least 1 15813abf7ccSAndreas Gohr if ($hc > 0) { 1597db0beafSAnna Dabrowska $hr = $this->docArray['chars'] / $hc; 160d723b313SAndreas Gohr 161d723b313SAndreas Gohr // 1 point for too many headers 162d723b313SAndreas Gohr if ($hr < 200) { 1637db0beafSAnna Dabrowska $this->docArray['err']['manyheaders'] = 1; 164d723b313SAndreas Gohr } 165d723b313SAndreas Gohr 166d723b313SAndreas Gohr // 1 point for too few headers 1671b085f03SAndreas Gohr if ($hr > 2000) { 1687db0beafSAnna Dabrowska $this->docArray['err']['fewheaders'] = 1; 169d723b313SAndreas Gohr } 170d723b313SAndreas Gohr } 171d723b313SAndreas Gohr 172d723b313SAndreas Gohr // 1 point when no link at all 1737db0beafSAnna Dabrowska if (!$this->docArray['internal_links']) { 1747db0beafSAnna Dabrowska $this->docArray['err']['nolink'] = 1; 175d723b313SAndreas Gohr } 176d723b313SAndreas Gohr 177d723b313SAndreas Gohr // 0.5 for broken links when too many 1787db0beafSAnna Dabrowska if ($this->docArray['broken_links'] > 2) { 1797db0beafSAnna Dabrowska $this->docArray['err']['brokenlink'] = $this->docArray['broken_links'] * 0.5; 180d723b313SAndreas Gohr } 181d723b313SAndreas Gohr 182d723b313SAndreas Gohr // 2 points for lot's of formatting 1837db0beafSAnna Dabrowska if ($this->docArray['formatted'] && $this->docArray['chars'] / $this->docArray['formatted'] < 3) { 1847db0beafSAnna Dabrowska $this->docArray['err']['manyformat'] = 2; 185d723b313SAndreas Gohr } 186d723b313SAndreas Gohr 1879068e431SAndreas Gohr // add up all scores 1887db0beafSAnna Dabrowska foreach ($this->docArray['err'] as $err => $val) $this->docArray['score'] += $val; 1899068e431SAndreas Gohr 1904ea373cdSAndreas Gohr 1918fce80b1SAndreas Gohr //we're done here 1927db0beafSAnna Dabrowska $this->doc = serialize($this->docArray); 1938fce80b1SAndreas Gohr } 1948fce80b1SAndreas Gohr 1958fce80b1SAndreas Gohr /** 1968fce80b1SAndreas Gohr * the format we produce 1978fce80b1SAndreas Gohr */ 198*76bbc49cSAnna Dabrowska public function getFormat() 199*76bbc49cSAnna Dabrowska { 2008fce80b1SAndreas Gohr return 'qc'; 2018fce80b1SAndreas Gohr } 2028fce80b1SAndreas Gohr 203*76bbc49cSAnna Dabrowska public function internallink($id, $name = null, $search = null, $returnonly = false, $linktype = 'content') 204*76bbc49cSAnna Dabrowska { 205d723b313SAndreas Gohr global $ID; 206d723b313SAndreas Gohr resolve_pageid(getNS($ID), $id, $exists); 207d723b313SAndreas Gohr 2088d7cf088SAndreas Gohr // calculate link width 209d78155a4SAndreas Gohr $a = explode(':', getNS($ID)); 210d78155a4SAndreas Gohr $b = explode(':', getNS($id)); 211d78155a4SAndreas Gohr while (isset($a[0]) && $a[0] == $b[0]) { 2128d7cf088SAndreas Gohr array_shift($a); 2138d7cf088SAndreas Gohr array_shift($b); 2148d7cf088SAndreas Gohr } 215d78155a4SAndreas Gohr $length = count($a) + count($b); 2167db0beafSAnna Dabrowska $this->docArray['link_lengths'][] = $length; 2178d7cf088SAndreas Gohr 2187db0beafSAnna Dabrowska $this->docArray['internal_links']++; 2197db0beafSAnna Dabrowska if (!$exists) $this->docArray['broken_links']++; 2200476d180SAndreas Gohr } 2210476d180SAndreas Gohr 222*76bbc49cSAnna Dabrowska public function externallink($url, $name = null) 223*76bbc49cSAnna Dabrowska { 2247db0beafSAnna Dabrowska $this->docArray['external_links']++; 225d723b313SAndreas Gohr } 2268fce80b1SAndreas Gohr 227*76bbc49cSAnna Dabrowska public function header($text, $level, $pos) 228*76bbc49cSAnna Dabrowska { 2297db0beafSAnna Dabrowska $this->docArray['header_count'][$level]++; 2307db0beafSAnna Dabrowska $this->docArray['header_struct'][] = $level; 2318fce80b1SAndreas Gohr } 2328fce80b1SAndreas Gohr 233*76bbc49cSAnna Dabrowska public function smiley($smiley) 234*76bbc49cSAnna Dabrowska { 2357db0beafSAnna Dabrowska if ($smiley == 'FIXME') $this->docArray['fixme']++; 2368fce80b1SAndreas Gohr } 2378fce80b1SAndreas Gohr 238*76bbc49cSAnna Dabrowska public function linebreak() 239*76bbc49cSAnna Dabrowska { 2406afc1841Sthesunrise1983 if (!$this->tableopen) { 2417db0beafSAnna Dabrowska $this->docArray['linebreak']++; 2428fce80b1SAndreas Gohr } 2436afc1841Sthesunrise1983 } 2446afc1841Sthesunrise1983 245*76bbc49cSAnna Dabrowska public function table_open($maxcols = null, $numrows = null, $pos = null) 246*76bbc49cSAnna Dabrowska { 2476afc1841Sthesunrise1983 $this->tableopen = true; 2486afc1841Sthesunrise1983 } 2496afc1841Sthesunrise1983 250*76bbc49cSAnna Dabrowska public function table_close($pos = null) 251*76bbc49cSAnna Dabrowska { 2526afc1841Sthesunrise1983 $this->tableopen = false; 2536afc1841Sthesunrise1983 } 2548fce80b1SAndreas Gohr 255*76bbc49cSAnna Dabrowska public function hr() 256*76bbc49cSAnna Dabrowska { 2577db0beafSAnna Dabrowska $this->docArray['hr']++; 2588fce80b1SAndreas Gohr } 2598fce80b1SAndreas Gohr 260*76bbc49cSAnna Dabrowska public function quote_open() 261*76bbc49cSAnna Dabrowska { 2627db0beafSAnna Dabrowska $this->docArray['quote_count']++; 2638fce80b1SAndreas Gohr $this->quotelevel++; 2647db0beafSAnna Dabrowska $this->docArray['quote_nest'] = max($this->quotelevel, $this->docArray['quote_nest']); 2658fce80b1SAndreas Gohr } 2668fce80b1SAndreas Gohr 267*76bbc49cSAnna Dabrowska public function quote_close() 268*76bbc49cSAnna Dabrowska { 2698fce80b1SAndreas Gohr $this->quotelevel--; 2708fce80b1SAndreas Gohr } 2718fce80b1SAndreas Gohr 272*76bbc49cSAnna Dabrowska public function strong_open() 273*76bbc49cSAnna Dabrowska { 274d723b313SAndreas Gohr $this->formatting++; 275d723b313SAndreas Gohr } 2768fce80b1SAndreas Gohr 277*76bbc49cSAnna Dabrowska public function strong_close() 278*76bbc49cSAnna Dabrowska { 279d723b313SAndreas Gohr $this->formatting--; 280d723b313SAndreas Gohr } 281d723b313SAndreas Gohr 282*76bbc49cSAnna Dabrowska public function emphasis_open() 283*76bbc49cSAnna Dabrowska { 284d723b313SAndreas Gohr $this->formatting++; 285d723b313SAndreas Gohr } 286d723b313SAndreas Gohr 287*76bbc49cSAnna Dabrowska public function emphasis_close() 288*76bbc49cSAnna Dabrowska { 289d723b313SAndreas Gohr $this->formatting--; 290d723b313SAndreas Gohr } 291d723b313SAndreas Gohr 292*76bbc49cSAnna Dabrowska public function underline_open() 293*76bbc49cSAnna Dabrowska { 294d723b313SAndreas Gohr $this->formatting++; 295d723b313SAndreas Gohr } 296d723b313SAndreas Gohr 297*76bbc49cSAnna Dabrowska public function underline_close() 298*76bbc49cSAnna Dabrowska { 299d723b313SAndreas Gohr $this->formatting--; 300d723b313SAndreas Gohr } 301d723b313SAndreas Gohr 302*76bbc49cSAnna Dabrowska public function cdata($text) 303*76bbc49cSAnna Dabrowska { 304d723b313SAndreas Gohr if (!$this->formatting) return; 305d723b313SAndreas Gohr 306d723b313SAndreas Gohr $len = utf8_strlen($text); 307d723b313SAndreas Gohr 308d723b313SAndreas Gohr // 1 point for formattings longer than 500 chars 3097db0beafSAnna Dabrowska if ($len > 500) $this->docArray['err']['longformat']++; 310d723b313SAndreas Gohr 3114bda998cSAndreas Gohr // 1 point for each multiformatting 3127db0beafSAnna Dabrowska if ($this->formatting > 1) $this->docArray['err']['multiformat'] += 1 * ($this->formatting - 1); 3134bda998cSAndreas Gohr 3147db0beafSAnna Dabrowska $this->docArray['formatted'] += $len; 315d723b313SAndreas Gohr } 3168fce80b1SAndreas Gohr} 3178fce80b1SAndreas Gohr 3188fce80b1SAndreas Gohr//Setup VIM: ex: et ts=4 enc=utf-8 : 319