18fce80b1SAndreas Gohr<?php 28fce80b1SAndreas Gohr// must be run within Dokuwiki 38fce80b1SAndreas Gohrif(!defined('DOKU_INC')) die(); 48fce80b1SAndreas Gohr 58fce80b1SAndreas Gohr// we inherit from the XHTML renderer instead directly of the base renderer 68fce80b1SAndreas Gohrrequire_once DOKU_INC.'inc/parser/renderer.php'; 78fce80b1SAndreas Gohr 88fce80b1SAndreas Gohr/** 98fce80b1SAndreas Gohr * The Renderer 108fce80b1SAndreas Gohr */ 118fce80b1SAndreas Gohrclass renderer_plugin_qc extends Doku_Renderer { 128fce80b1SAndreas Gohr /** 138fce80b1SAndreas Gohr * We store all our data in an array 148fce80b1SAndreas Gohr */ 158fce80b1SAndreas Gohr var $doc = array( 168fce80b1SAndreas Gohr // raw statistics 178fce80b1SAndreas Gohr 'header_count' => array(0,0,0,0,0,0), 188fce80b1SAndreas Gohr 'header_struct' => array(), 198fce80b1SAndreas Gohr 'linebreak' => 0, 208fce80b1SAndreas Gohr 'quote_nest' => 0, 218fce80b1SAndreas Gohr 'quote_count' => 0, 228fce80b1SAndreas Gohr 'fixme' => 0, 238fce80b1SAndreas Gohr 'hr' => 0, 24*d723b313SAndreas Gohr 'formatted' => 0, 258fce80b1SAndreas Gohr 264ea373cdSAndreas Gohr 'created' => 0, 274ea373cdSAndreas Gohr 'modified' => 0, 284ea373cdSAndreas Gohr 'changes' => 0, 294ea373cdSAndreas Gohr 'authors' => array(), 304ea373cdSAndreas Gohr 31*d723b313SAndreas Gohr 'internal_links'=> 0, 32*d723b313SAndreas Gohr 'broken_links' => 0, 33*d723b313SAndreas Gohr 'external_links'=> 0, 34*d723b313SAndreas 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, 48*d723b313SAndreas Gohr 'longformat' => 0, 498fce80b1SAndreas Gohr ), 508fce80b1SAndreas Gohr ); 518fce80b1SAndreas Gohr 528fce80b1SAndreas Gohr var $quotelevel = 0; 53*d723b313SAndreas Gohr var $formatting = 0; 548fce80b1SAndreas Gohr 554ea373cdSAndreas Gohr function document_start() { 564ea373cdSAndreas Gohr global $ID; 574ea373cdSAndreas Gohr $meta = p_get_metadata($ID); 584ea373cdSAndreas Gohr 594ea373cdSAndreas Gohr // get some dates from meta data 604ea373cdSAndreas Gohr $this->doc['created'] = $meta['date']['created']; 614ea373cdSAndreas Gohr $this->doc['modified'] = $meta['date']['modified']; 624ea373cdSAndreas Gohr 634ea373cdSAndreas Gohr // get author info 644ea373cdSAndreas Gohr $revs = getRevisions($ID,0,0); 654ea373cdSAndreas Gohr array_push($revs,$meta['last_change']['date']); 664ea373cdSAndreas Gohr $this->doc['changes'] = count($revs); 674ea373cdSAndreas Gohr foreach($revs as $rev){ 684ea373cdSAndreas Gohr $info = getRevisionInfo($ID, $rev); 694ea373cdSAndreas Gohr if($info['user']){ 704ea373cdSAndreas Gohr $this->doc['authors'][$info['user']] += 1; 714ea373cdSAndreas Gohr }else{ 724ea373cdSAndreas Gohr $this->doc['authors']['*'] += 1; 734ea373cdSAndreas Gohr } 744ea373cdSAndreas Gohr } 754ea373cdSAndreas Gohr 764ea373cdSAndreas Gohr // work on raw text 774ea373cdSAndreas Gohr $text = rawWiki($ID); 784ea373cdSAndreas Gohr $this->doc['chars'] = utf8_strlen($text); 794ea373cdSAndreas Gohr $this->doc['words'] = count(preg_split('/[^\w\-_]/u',$text)); 804ea373cdSAndreas Gohr } 814ea373cdSAndreas Gohr 824ea373cdSAndreas Gohr 838fce80b1SAndreas Gohr /** 848fce80b1SAndreas Gohr * Here the score is calculated 858fce80b1SAndreas Gohr */ 868fce80b1SAndreas Gohr function document_end() { 878fce80b1SAndreas Gohr 888fce80b1SAndreas Gohr // 1 point for each FIXME 898fce80b1SAndreas Gohr $this->doc['err']['fixme'] += $this->doc['fixme']; 908fce80b1SAndreas Gohr 918fce80b1SAndreas Gohr // 5 points for missing H1 928fce80b1SAndreas Gohr if($this->doc['header_count'][1] == 0){ 938fce80b1SAndreas Gohr $this->doc['err']['noh1'] += 5; 948fce80b1SAndreas Gohr } 958fce80b1SAndreas Gohr // 1 point for each H1 too much 968fce80b1SAndreas Gohr if($this->doc['header_count'][1] > 1){ 978fce80b1SAndreas Gohr $this->doc['err']['manyh1'] += $this->doc['header'][1]; 988fce80b1SAndreas Gohr } 998fce80b1SAndreas Gohr 1008fce80b1SAndreas Gohr // 1 point for each incorrectly nested headline 1018fce80b1SAndreas Gohr $cnt = count($this->doc['header_struct']); 1028fce80b1SAndreas Gohr for($i = 1; $i < $cnt; $i++){ 1038fce80b1SAndreas Gohr if($this->doc['header_struct'][$i] - $this->doc['header_struct'][$i-1] > 1){ 1048fce80b1SAndreas Gohr $this->doc['err']['headernest'] += 1; 1058fce80b1SAndreas Gohr } 1068fce80b1SAndreas Gohr } 1078fce80b1SAndreas Gohr 1088fce80b1SAndreas Gohr // 1/2 points for deeply nested quotations 1098fce80b1SAndreas Gohr if($this->doc['quote_nest'] > 2){ 1108fce80b1SAndreas Gohr $this->doc['err']['deepquote'] += $this->doc['quote_nest']/2; 1118fce80b1SAndreas Gohr } 1128fce80b1SAndreas Gohr 1138fce80b1SAndreas Gohr // FIXME points for many quotes? 1148fce80b1SAndreas Gohr 1158fce80b1SAndreas Gohr // 1/2 points for too many hr 1168fce80b1SAndreas Gohr if($this->doc['hr'] > 2){ 1178fce80b1SAndreas Gohr $this->doc['err']['manyhr'] = ($this->doc['hr'] - 2)/2; 1188fce80b1SAndreas Gohr } 1198fce80b1SAndreas Gohr 1208fce80b1SAndreas Gohr // 1 point for too many line breaks 1218fce80b1SAndreas Gohr if($this->doc['linebreak'] > 2){ 1228fce80b1SAndreas Gohr $this->doc['err']['manybr'] = $this->doc['linebreak'] - 2; 1238fce80b1SAndreas Gohr } 1248fce80b1SAndreas Gohr 1254ea373cdSAndreas Gohr // 1 point for single author only 1264ea373cdSAndreas Gohr if(count($this->doc['authors']) == 1){ 1274ea373cdSAndreas Gohr $this->doc['err']['singleauthor'] = 1; 1284ea373cdSAndreas Gohr } 1294ea373cdSAndreas Gohr 130*d723b313SAndreas Gohr // 1 point for too small document 131*d723b313SAndreas Gohr if($this->doc['chars'] < 150){ 132*d723b313SAndreas Gohr $this->doc['err']['toosmall'] = 1; 133*d723b313SAndreas Gohr } 134*d723b313SAndreas Gohr 135*d723b313SAndreas Gohr // 1 point for too large document 136*d723b313SAndreas Gohr if($this->doc['chars'] > 100000){ 137*d723b313SAndreas Gohr $this->doc['err']['toolarge'] = 1; 138*d723b313SAndreas Gohr } 139*d723b313SAndreas Gohr 140*d723b313SAndreas Gohr // header to text ratio 141*d723b313SAndreas Gohr $hc = $this->doc['header_count'][1] + 142*d723b313SAndreas Gohr $this->doc['header_count'][2] + 143*d723b313SAndreas Gohr $this->doc['header_count'][3] + 144*d723b313SAndreas Gohr $this->doc['header_count'][4] + 145*d723b313SAndreas Gohr $this->doc['header_count'][5]; 146*d723b313SAndreas Gohr if($hc){ 147*d723b313SAndreas Gohr $hr = $this->doc['chars']/$hc; 148*d723b313SAndreas Gohr 149*d723b313SAndreas Gohr // 1 point for too many headers 150*d723b313SAndreas Gohr if($hr < 200){ 151*d723b313SAndreas Gohr $this->doc['err']['manyheaders'] = 1; 152*d723b313SAndreas Gohr } 153*d723b313SAndreas Gohr 154*d723b313SAndreas Gohr // 1 point for too few headers 155*d723b313SAndreas Gohr if($hr < 2000){ 156*d723b313SAndreas Gohr $this->doc['err']['fewheaders'] = 1; 157*d723b313SAndreas Gohr } 158*d723b313SAndreas Gohr } 159*d723b313SAndreas Gohr 160*d723b313SAndreas Gohr // 1 point when no link at all 161*d723b313SAndreas Gohr if(!$this->doc['internal_links']){ 162*d723b313SAndreas Gohr $this->doc['err']['nolink'] = 1; 163*d723b313SAndreas Gohr } 164*d723b313SAndreas Gohr 165*d723b313SAndreas Gohr // 0.5 for broken links when too many 166*d723b313SAndreas Gohr if($this->doc['broken_links'] > 2){ 167*d723b313SAndreas Gohr $this->doc['err']['brokenlink'] = $this->doc['broken_links']*0.5; 168*d723b313SAndreas Gohr } 169*d723b313SAndreas Gohr 170*d723b313SAndreas Gohr // 2 points for lot's of formatting 171*d723b313SAndreas Gohr if($this->doc['formatted'] && $this->doc['chars']/$this->doc['formatted'] < 3){ 172*d723b313SAndreas Gohr $this->doc['err']['manyformat'] = 2; 173*d723b313SAndreas Gohr } 174*d723b313SAndreas Gohr 1759068e431SAndreas Gohr // add up all scores 1769068e431SAndreas Gohr foreach($this->doc['err'] as $err => $val) $this->doc['score'] += $val; 1779068e431SAndreas Gohr 1784ea373cdSAndreas Gohr 1798fce80b1SAndreas Gohr //we're done here 1808fce80b1SAndreas Gohr $this->doc = serialize($this->doc); 1818fce80b1SAndreas Gohr } 1828fce80b1SAndreas Gohr 1838fce80b1SAndreas Gohr /** 1848fce80b1SAndreas Gohr * return some info 1858fce80b1SAndreas Gohr */ 1868fce80b1SAndreas Gohr function getInfo(){ 1878fce80b1SAndreas Gohr return confToHash(dirname(__FILE__).'/info.txt'); 1888fce80b1SAndreas Gohr } 1898fce80b1SAndreas Gohr 1908fce80b1SAndreas Gohr /** 1918fce80b1SAndreas Gohr * the format we produce 1928fce80b1SAndreas Gohr */ 1938fce80b1SAndreas Gohr function getFormat(){ 1948fce80b1SAndreas Gohr return 'qc'; 1958fce80b1SAndreas Gohr } 1968fce80b1SAndreas Gohr 197*d723b313SAndreas Gohr function internallink($id, $name = NULL, $search=NULL,$returnonly=false,$linktype='content') { 198*d723b313SAndreas Gohr global $ID; 199*d723b313SAndreas Gohr resolve_pageid(getNS($ID),$id,$exists); 200*d723b313SAndreas Gohr 201*d723b313SAndreas Gohr $this->doc['internal_link']++; 202*d723b313SAndreas Gohr if(!$exists) $this->doc['broken_link']++; 203*d723b313SAndreas Gohr } 2048fce80b1SAndreas Gohr 2058fce80b1SAndreas Gohr function header($text, $level, $pos){ 2068fce80b1SAndreas Gohr $this->doc['header_count'][$level]++; 2078fce80b1SAndreas Gohr $this->doc['header_struct'][] = $level; 2088fce80b1SAndreas Gohr } 2098fce80b1SAndreas Gohr 2108fce80b1SAndreas Gohr function smiley($smiley) { 2118fce80b1SAndreas Gohr if($smiley == 'FIXME') $this->doc['fixme']++; 2128fce80b1SAndreas Gohr } 2138fce80b1SAndreas Gohr 2148fce80b1SAndreas Gohr function linebreak() { 2158fce80b1SAndreas Gohr $this->doc['linebreak']++; 2168fce80b1SAndreas Gohr } 2178fce80b1SAndreas Gohr 2188fce80b1SAndreas Gohr function hr() { 2198fce80b1SAndreas Gohr $this->doc['hr']++; 2208fce80b1SAndreas Gohr } 2218fce80b1SAndreas Gohr 2228fce80b1SAndreas Gohr function quote_open() { 2238fce80b1SAndreas Gohr $this->doc['quote_count']++; 2248fce80b1SAndreas Gohr $this->quotelevel++; 2258fce80b1SAndreas Gohr $this->doc['quote_nest'] = max($this->quotelevel,$this->doc['quote_nest']); 2268fce80b1SAndreas Gohr } 2278fce80b1SAndreas Gohr 2288fce80b1SAndreas Gohr function quote_close() { 2298fce80b1SAndreas Gohr $this->quotelevel--; 2308fce80b1SAndreas Gohr } 2318fce80b1SAndreas Gohr 232*d723b313SAndreas Gohr function strong_open() { 233*d723b313SAndreas Gohr $this->formatting++; 234*d723b313SAndreas Gohr } 2358fce80b1SAndreas Gohr 236*d723b313SAndreas Gohr function strong_close() { 237*d723b313SAndreas Gohr $this->formatting--; 238*d723b313SAndreas Gohr } 239*d723b313SAndreas Gohr 240*d723b313SAndreas Gohr function emphasis_open() { 241*d723b313SAndreas Gohr $this->formatting++; 242*d723b313SAndreas Gohr } 243*d723b313SAndreas Gohr 244*d723b313SAndreas Gohr function emphasis_close() { 245*d723b313SAndreas Gohr $this->formatting--; 246*d723b313SAndreas Gohr } 247*d723b313SAndreas Gohr 248*d723b313SAndreas Gohr function underline_open() { 249*d723b313SAndreas Gohr $this->formatting++; 250*d723b313SAndreas Gohr } 251*d723b313SAndreas Gohr 252*d723b313SAndreas Gohr function underline_close() { 253*d723b313SAndreas Gohr $this->formatting--; 254*d723b313SAndreas Gohr } 255*d723b313SAndreas Gohr 256*d723b313SAndreas Gohr function cdata($text) { 257*d723b313SAndreas Gohr if(!$this->formatting) return; 258*d723b313SAndreas Gohr 259*d723b313SAndreas Gohr $len = utf8_strlen($text); 260*d723b313SAndreas Gohr 261*d723b313SAndreas Gohr // 1 point for formattings longer than 500 chars 262*d723b313SAndreas Gohr if($len>500) $this->doc['err']['longformat']++; 263*d723b313SAndreas Gohr 264*d723b313SAndreas Gohr $this->doc['formatted'] += $len; 265*d723b313SAndreas Gohr } 2668fce80b1SAndreas Gohr} 2678fce80b1SAndreas Gohr 2688fce80b1SAndreas Gohr//Setup VIM: ex: et ts=4 enc=utf-8 : 269