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