1<?php 2// must be run within Dokuwiki 3if(!defined('DOKU_INC')) die(); 4 5require_once DOKU_INC.'inc/parser/renderer.php'; 6require_once DOKU_INC.'inc/fulltext.php'; 7 8/** 9 * The Renderer 10 */ 11class renderer_plugin_qc extends Doku_Renderer { 12 /** 13 * We store all our data in an array 14 */ 15 var $doc = array( 16 // raw statistics 17 'header_count' => array(0,0,0,0,0,0), 18 'header_struct' => array(), 19 'linebreak' => 0, 20 'quote_nest' => 0, 21 'quote_count' => 0, 22 'fixme' => 0, 23 'hr' => 0, 24 'formatted' => 0, 25 26 'created' => 0, 27 'modified' => 0, 28 'changes' => 0, 29 'authors' => array(), 30 31 'internal_links'=> 0, 32 'broken_links' => 0, 33 'external_links'=> 0, 34 35 'chars' => 0, 36 'words' => 0, 37 38 'score' => 0, 39 40 // calculated error scores 41 'err' => array( 42 'fixme' => 0, 43 'noh1' => 0, 44 'manyh1' => 0, 45 'headernest' => 0, 46 'manyhr' => 0, 47 'manybr' => 0, 48 'longformat' => 0, 49 ), 50 ); 51 52 var $quotelevel = 0; 53 var $formatting = 0; 54 55 function document_start() { 56 global $ID; 57 $meta = p_get_metadata($ID); 58 59 // get some dates from meta data 60 $this->doc['created'] = $meta['date']['created']; 61 $this->doc['modified'] = $meta['date']['modified']; 62 63 // get author info 64 $revs = getRevisions($ID,0,0); 65 array_push($revs,$meta['last_change']['date']); 66 $this->doc['changes'] = count($revs); 67 foreach($revs as $rev){ 68 $info = getRevisionInfo($ID, $rev); 69 if($info['user']){ 70 $this->doc['authors'][$info['user']] += 1; 71 }else{ 72 $this->doc['authors']['*'] += 1; 73 } 74 } 75 76 // work on raw text 77 $text = rawWiki($ID); 78 $this->doc['chars'] = utf8_strlen($text); 79 $this->doc['words'] = count(preg_split('/[^\w\-_]/u',$text)); 80 } 81 82 83 /** 84 * Here the score is calculated 85 */ 86 function document_end() { 87 global $ID; 88 89 // 2 points for missing backlinks 90 if(!count(ft_backlinks($ID))){ 91 $this->doc['err']['nobacklink'] += 2; 92 } 93 94 // 1 point for each FIXME 95 $this->doc['err']['fixme'] += $this->doc['fixme']; 96 97 // 5 points for missing H1 98 if($this->doc['header_count'][1] == 0){ 99 $this->doc['err']['noh1'] += 5; 100 } 101 // 1 point for each H1 too much 102 if($this->doc['header_count'][1] > 1){ 103 $this->doc['err']['manyh1'] += $this->doc['header'][1]; 104 } 105 106 // 1 point for each incorrectly nested headline 107 $cnt = count($this->doc['header_struct']); 108 for($i = 1; $i < $cnt; $i++){ 109 if($this->doc['header_struct'][$i] - $this->doc['header_struct'][$i-1] > 1){ 110 $this->doc['err']['headernest'] += 1; 111 } 112 } 113 114 // 1/2 points for deeply nested quotations 115 if($this->doc['quote_nest'] > 2){ 116 $this->doc['err']['deepquote'] += $this->doc['quote_nest']/2; 117 } 118 119 // FIXME points for many quotes? 120 121 // 1/2 points for too many hr 122 if($this->doc['hr'] > 2){ 123 $this->doc['err']['manyhr'] = ($this->doc['hr'] - 2)/2; 124 } 125 126 // 1 point for too many line breaks 127 if($this->doc['linebreak'] > 2){ 128 $this->doc['err']['manybr'] = $this->doc['linebreak'] - 2; 129 } 130 131 // 1 point for single author only 132 if(count($this->doc['authors']) == 1){ 133 $this->doc['err']['singleauthor'] = 1; 134 } 135 136 // 1 point for too small document 137 if($this->doc['chars'] < 150){ 138 $this->doc['err']['toosmall'] = 1; 139 } 140 141 // 1 point for too large document 142 if($this->doc['chars'] > 100000){ 143 $this->doc['err']['toolarge'] = 1; 144 } 145 146 // header to text ratio 147 $hc = $this->doc['header_count'][1] + 148 $this->doc['header_count'][2] + 149 $this->doc['header_count'][3] + 150 $this->doc['header_count'][4] + 151 $this->doc['header_count'][5]; 152 if($hc){ 153 $hr = $this->doc['chars']/$hc; 154 155 // 1 point for too many headers 156 if($hr < 200){ 157 $this->doc['err']['manyheaders'] = 1; 158 } 159 160 // 1 point for too few headers 161 if($hr > 2000){ 162 $this->doc['err']['fewheaders'] = 1; 163 } 164 } 165 166 // 1 point when no link at all 167 if(!$this->doc['internal_links']){ 168 $this->doc['err']['nolink'] = 1; 169 } 170 171 // 0.5 for broken links when too many 172 if($this->doc['broken_links'] > 2){ 173 $this->doc['err']['brokenlink'] = $this->doc['broken_links']*0.5; 174 } 175 176 // 2 points for lot's of formatting 177 if($this->doc['formatted'] && $this->doc['chars']/$this->doc['formatted'] < 3){ 178 $this->doc['err']['manyformat'] = 2; 179 } 180 181 // add up all scores 182 foreach($this->doc['err'] as $err => $val) $this->doc['score'] += $val; 183 184 185 //we're done here 186 $this->doc = serialize($this->doc); 187 } 188 189 /** 190 * the format we produce 191 */ 192 function getFormat(){ 193 return 'qc'; 194 } 195 196 function internallink($id, $name = NULL, $search=NULL,$returnonly=false,$linktype='content') { 197 global $ID; 198 resolve_pageid(getNS($ID),$id,$exists); 199 200 $this->doc['internal_links']++; 201 if(!$exists) $this->doc['broken_links']++; 202 } 203 204 function externallink($url, $name = NULL) { 205 $this->doc['external_links']++; 206 } 207 208 function header($text, $level, $pos){ 209 $this->doc['header_count'][$level]++; 210 $this->doc['header_struct'][] = $level; 211 } 212 213 function smiley($smiley) { 214 if($smiley == 'FIXME') $this->doc['fixme']++; 215 } 216 217 function linebreak() { 218 $this->doc['linebreak']++; 219 } 220 221 function hr() { 222 $this->doc['hr']++; 223 } 224 225 function quote_open() { 226 $this->doc['quote_count']++; 227 $this->quotelevel++; 228 $this->doc['quote_nest'] = max($this->quotelevel,$this->doc['quote_nest']); 229 } 230 231 function quote_close() { 232 $this->quotelevel--; 233 } 234 235 function strong_open() { 236 $this->formatting++; 237 } 238 239 function strong_close() { 240 $this->formatting--; 241 } 242 243 function emphasis_open() { 244 $this->formatting++; 245 } 246 247 function emphasis_close() { 248 $this->formatting--; 249 } 250 251 function underline_open() { 252 $this->formatting++; 253 } 254 255 function underline_close() { 256 $this->formatting--; 257 } 258 259 function cdata($text) { 260 if(!$this->formatting) return; 261 262 $len = utf8_strlen($text); 263 264 // 1 point for formattings longer than 500 chars 265 if($len>500) $this->doc['err']['longformat']++; 266 267 $this->doc['formatted'] += $len; 268 } 269} 270 271//Setup VIM: ex: et ts=4 enc=utf-8 : 272