1<?php 2/******************************************************************************************************************************** 3* 4* LabVIEW Hacker Packet Plugin 5* 6* Written By Sammy_K 7* www.labviewhacker.com 8* 9/*******************************************************************************************************************************/ 10 11 12// must be run within DokuWiki 13if(!defined('DOKU_INC')) die(); 14 15if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 16require_once DOKU_PLUGIN.'syntax.php'; 17 18//Include LVH Plugin Common Code 19if(!defined('LVH_COMMON')) 20{ 21 define('LVH_COMMON', 'lib/plugins/lvhplugincommon.php'); 22 include 'lib/plugins/lvhplugincommon.php'; 23} 24 25/******************************************************************************************************************************** 26* All DokuWiki plugins to extend the parser/rendering mechanism 27* need to inherit from this class 28********************************************************************************************************************************/ 29class syntax_plugin_lvhpacket extends DokuWiki_Syntax_Plugin 30{ 31 32 //Return Plugin Info 33 function getInfo() 34 { 35 return array('author' => 'Sammy_K', 36 'email' => 'sammyk.labviewhacker@gmail.com', 37 'date' => '2013-07-28', 38 'name' => 'LabVIEW Hacker Packet', 39 'desc' => 'Template for describing a packet', 40 'url' => 'www.labviewhacker.com'); 41 } 42 43 44 //Set This To True To Enable Debug Strings 45 protected $lvhDebug = false; 46 47 /*************************************************************************************************************************** 48 * Plugin Variables 49 ***************************************************************************************************************************/ 50 protected $name = ''; 51 protected $description = ''; 52 protected $size = ''; 53 protected $format = ''; 54 protected $subPackets = array(); 55 protected $allPackets = array(); 56 57 protected $subPacketNum = 0; 58 protected $subPacketIdNum = 0; 59 protected $subPacketValueNum = 0; 60 protected $subPacketSizeNum = 0; 61 protected $subPacketDetailsNum = 0; 62 63 64 /******************************************************************************************************************************************** 65 ** Plugin Configuration 66 ********************************************************************************************************************************************/ 67 68 function getType() { return 'protected'; } 69 function getSort() { return 32; } 70 71 function connectTo($mode) { 72 $this->Lexer->addEntryPattern('{{lvh_packet.*?(?=.*?}})',$mode,'plugin_lvhpacket'); 73 74 //Add Internal Pattern Match For Product Page Elements 75 $this->Lexer->addPattern('\|.*?(?=.*?)\n','plugin_lvhpacket'); 76 } 77 78 function postConnect() { 79 $this->Lexer->addExitPattern('}}','plugin_lvhpacket'); 80 } 81 82 /******************************************************************************************************************************************** 83 ** Handle 84 ********************************************************************************************************************************************/ 85 86 function handle($match, $state, $pos, &$handler) 87 { 88 switch ($state) 89 { 90 case DOKU_LEXER_ENTER : 91 break; 92 case DOKU_LEXER_MATCHED : 93 //Find The Token And Value (Before '=' remove white space, convert to lower case). 94 $tokenDiv = strpos($match, '='); //Find Token Value Divider ('=') 95 $token = strtolower(trim(substr($match, 1, ($tokenDiv - 1)))); //Everything Before '=', Remove White Space, Convert To Lower Case 96 $value = substr($match, ($tokenDiv + 1)); //Everything after '=' 97 switch($token) 98 { 99 case 'name': 100 $this->name = $value; 101 break; 102 case 'description': 103 $this->description = $value; 104 break; 105 case 'size': 106 $this->size = $value; 107 break; 108 case 'format': 109 $this->format = $value; 110 break; 111 case 'subpacketid' : 112 if($this->subPacketIdNum != $this->subPacketNum) 113 { 114 //New Subpacket 115 $this->subPacketNum++; 116 $this->subPacketIdNum = $this->subPacketNum; 117 $this->subPacketValueNum = $this->subPacketNum; 118 $this->subPacketSizeNum = $this->subPacketNum; 119 $this->subPacketDetailsNum = $this->subPacketNum; 120 } 121 //Add New Subpacket ID 122 $this->subPackets[$this->subPacketNum][0] = $value; 123 $this->subPacketIdNum++; 124 break; 125 case 'subpacketsize' : 126 if($this->subPacketSizeNum != $this->subPacketNum) 127 { 128 //New Subpacket 129 $this->subPacketNum++; 130 $this->subPacketIdNum = $this->subPacketNum; 131 $this->subPacketValueNum = $this->subPacketNum; 132 $this->subPacketSizeNum = $this->subPacketNum; 133 $this->subPacketDetailsNum = $this->subPacketNum; 134 } 135 //-------Add New Subpacket Size-------// 136 //Create New Subpacket Entry If Necissary 137 if(count($this->subPackets[$this->subPacketNum]) == 0) 138 { 139 $this->subPackets[$subPacketNum][0] = ''; 140 } 141 $this->subPackets[$this->subPacketNum][1] = $value; 142 $this->subPacketSizeNum++; 143 break; 144 case 'subpacketdetails': 145 if($this->subPacketDetailsNum != $this->subPacketNum) 146 { 147 //New Subpacket 148 $this->subPacketNum++; 149 $this->subPacketIdNum = $this->subPacketNum; 150 $this->subPacketValueNum = $this->subPacketNum; 151 $this->subPacketSizeNum = $this->subPacketNum; 152 $this->subPacketDetailsNum = $this->subPacketNum; 153 } 154 //Add New Subpacket Size 155 //Create New Subpacket Entry If Necissary 156 if(count($this->subPackets[$this->subPacketNum]) == 0) 157 { 158 $this->subPackets[$this->subPacketNum][0] = ''; 159 } 160 $this->subPackets[$this->subPacketNum][2] = $value; 161 $this->subPacketDetailsNum++; 162 break; 163 case 'subpacketvalue' : 164 if($this->subPacketValueNum != $this->subPacketNum) 165 { 166 //New Subpacket 167 $this->subPacketNum++; 168 $this->subPacketIdNum = $this->subPacketNum; 169 $this->subPacketValueNum = $this->subPacketNum; 170 $this->subPacketSizeNum = $this->subPacketNum; 171 $this->subPacketDetailsNum = $this->subPacketNum; 172 } 173 //Add New Subpacket Size 174 //Create New Subpacket Entry If Necissary 175 if(count($this->subPackets[$this->subPacketNum]) == 0) 176 { 177 $this->subPackets[$this->subPacketNum][0] = ''; 178 } 179 $this->subPackets[$this->subPacketNum][3] = $value; 180 $this->subPacketValueNum++; 181 break; 182 183 default: 184 break; 185 } 186 return array($state, $value); 187 break; 188 case DOKU_LEXER_UNMATCHED : 189 break; 190 case DOKU_LEXER_EXIT : 191 192 /******************************************************************************************************************************************** 193 ** Build Subpacket Details 194 ********************************************************************************************************************************************/ 195 $details = ''; 196 $packetSize = 0; 197 198 //Count Packet Size 199 foreach($this->subPackets as $subPacketVal) 200 { 201 $packetSize += $subPacketVal[1]; 202 } 203 204 //Calculate Num Cols 205 $numCols = ($packetSize)*8; 206 207 //Build Packet Breakdown HTML 208 foreach($this->subPackets as $subPacketVal) 209 { 210 $details .= " 211 <tr> 212 <td class='subPacketHeaderCell'> 213 " . $subPacketVal[0] . " 214 </td> 215 <td class='subPacketDetailsCell' colspan='32'> 216 " . $subPacketVal[2] . " 217 </td> 218 </tr>"; 219 } 220 /************************************************************ 221 * Helper Functions For HTML Generation 222 *************************************************************/ 223 224 //Convert Packet Size From Bits To Bytes 225 $partialByte = 0; 226 if( ($packetSize % 8) > 0) 227 { 228 $partialByte = 1; 229 } 230 $packetNumBytes = (floor($packetSize / 8) + $partialByte); //Number of full bytes needed to hold the entire packet. 231 232 /******************************************************** 233 * Name Row 234 *********************************************************/ 235 $nameRow = "<tr> 236 <td class='packetNameCell' colspan='33'> 237 <center>" . $this->name . "</center> 238 </td> 239 </tr>"; 240 241 /******************************************************** 242 * Description Row 243 *********************************************************/ 244 $descriptionRow = "<tr> 245 <td class='subPacketHeaderCell'> 246 Description 247 </td> 248 <td class='packetDescriptionCell' colspan='32'> 249 " . $this->description . " 250 </td> 251 </tr>"; 252 /******************************************************** 253 * Size Row 254 *********************************************************/ 255 $sizeRow = " <tr> 256 <td class='subPacketHeaderCell'> 257 Size 258 </td> 259 <td class='packetSizeCell' colspan='32'> 260 " . $this->size . " 261 </td> 262 </tr>"; 263 264 /******************************************************** 265 * Format Rows 266 *********************************************************/ 267 $numFormatRows = 0; 268 //Calculate Number Of Rows Needed For Format 269 if( ($packetNumBytes % 4) > 0) 270 { 271 $numFormatRows = (floor($packetNumBytes / 4)) + 1; 272 } 273 else 274 { 275 $numFormatRows = floor($packetNumBytes / 4); 276 } 277 278 //Build Each Packet Format Row 279 280 //TODO - Get Rid of This Reverse And Build The Table Top To Bottom. This Was Implemented This Way Because The Bytes Used To Be Right Justified In The Table But Are Now Top / Left Justified 281 $this->subPackets = array_reverse($this->subPackets); 282 283 $formatRows = ""; 284 $partialBitsUsed = 0; 285 $idNum = 0; 286 for($i=0; $i<$numFormatRows; $i++) 287 { 288 //Build It Backwards 289 290 //Build ID Row 291 $idBitsRemaining = 32; 292 $loopCountSafty = 0; 293 294 //Close ID Row 295 $formatRows = "</tr>" . $formatRows; 296 297 //TODO - Add Bits and Bytes and padding at the end (right now we probably read off the end of the array when looking for sub packet sizes ans ids 298 299 //Add Format ID Row 300 while($idBitsRemaining > 0) 301 { 302 //If There Are More IDs To Add Do So 303 if($this->subPackets[$idNum][1] != '') 304 { 305 //Check If There Is Room For The Entire ID On This Format Row 306 $idBitsNeeded = ($this->subPackets[$idNum][1]-$partialBitsUsed); //Number Of Bit Cols Needed For Next ID Or Partial ID 307 308 if( $idBitsNeeded <= $idBitsRemaining ) 309 { 310 311 //Add Entire ID To Current Row 312 $subPacketIDCell = "<td class='packetIdCell' colspan='" . $idBitsNeeded . "'><center>" . $this->subPackets[$idNum][0]; 313 //Add Value If Specified 314 if($this->subPackets[$idNum][3] != '') 315 { 316 $subPacketIDCell .= ": " . $this->subPackets[$idNum][3]; 317 } 318 319 //Close Sub Packet Cell 320 $subPacketIDCell .= "</center></td>"; 321 322 //Add To formatRows 323 $formatRows = $subPacketIDCell . $formatRows; 324 325 $idNum++; 326 $partialBitsUsed = 0; 327 $idBitsRemaining = $idBitsRemaining - $idBitsNeeded; 328 } 329 330 else 331 { 332 //Add Partial ID To Current Row 333 $subPacketIDCell = "<td class='packetIdCell' colspan='" . $idBitsRemaining . "'><center>" . $this->subPackets[$idNum][0]; 334 //Add Value If Specified 335 if($this->subPackets[$idNum][3] != '') 336 { 337 $subPacketIDCell .= ": " . $this->subPackets[$idNum][3]; 338 } 339 340 //Close Sub Packet Cell 341 $subPacketIDCell .= "</center></td>"; 342 343 //Add To formatRows 344 $formatRows = $subPacketIDCell . $formatRows; 345 $partialBitsUsed = $idBitsRemaining; 346 $idBitsRemaining = 0; 347 } 348 } 349 else 350 { 351 //All IDs Have Been Added. Pad The Rest Of The Row 352 $formatRows = "<td class='packetIdCell' colspan='" . $idBitsRemaining . "'><center>" . "N/A" . "</center></td>" . $formatRows; 353 $idBitsRemaining = 0; 354 } 355 356 //Prevent This Loop From Grinding Forever 357 $loopCountSafty++; 358 if($loopCountSafty > 100) 359 { 360 break; 361 } 362 } 363 //Close Bit Row, Open ID Row 364 $formatRows = "</tr><tr>" . $formatRows; 365 366 //Add Format Bit Row 367 for($j=8; $j<40; $j++) 368 { 369 $formatRows = "<td class='packetBitCell'><center>" . ($j % 8) . "</center></td>" . $formatRows; 370 } 371 372 //Close Byte Row And Open Bits Row 373 $formatRows = "</tr><tr>" . $formatRows; 374 375 //Add Format Byte Row 376 for($j=0; $j<4; $j++) 377 { 378 $byteNum = $packetNumBytes - ( ($i*4) + $j +1 ); 379 if($byteNum >= 0) 380 { 381 $formatRows = "<td class='packetByteCell' colspan='8'><center>" . $byteNum . "</center></td>" . $formatRows; 382 } 383 else 384 { 385 $formatRows = "<td class='packetByteCell' colspan='8'><center>-</center></td>" . $formatRows; 386 } 387 } 388 } 389 390 //Prepend Format Row Header 391 $formatRows = "<tr class='packetFormatRow'><td class='subPacketHeaderCell' rowspan='" . ($numFormatRows * 3) . "'>Format</td>" . $formatRows; 392 393 //Build TOC 394 395 //Build Array To Send To Renderer 396 $retVal = array($state, $this->name, $nameRow, $descriptionRow, $sizeRow, $formatRows, $details, $numCols); 397 398 //Clear Variables That Will Be Resused Here If Neccissary 399 $this->name = ''; 400 $this->description = ''; 401 $this->size = ''; 402 $this->format = ''; 403 $this->subPackets = ''; 404 $this->allPackets = ''; 405 406 $this->subPacketNum = 0; 407 $this->subPacketIdNum = 0; 408 $this->subPacketValueNum = 0; 409 $this->subPacketSizeNum = 0; 410 $this->subPacketDetailsNum = 0; 411 412 return $retVal; 413 break; 414 case DOKU_LEXER_SPECIAL : 415 break; 416 } 417 return array($state, $match); 418 } 419 420 /******************************************************************************************************************************************** 421 ** Render 422 ********************************************************************************************************************************************/ 423 424 function render($mode, &$renderer, $data) 425 { 426 // $data is what the function handle return'ed. 427 if($mode == 'xhtml') 428 { 429 switch ($data[0]) 430 { 431 case DOKU_LEXER_ENTER : 432 //Initialize Table 433 if($this->lvhDebug) $renderer->doc .= 'ENTER'; //Debug 434 435 //$renderer->doc.= '<HTML><body><table border="0">'; 436 break; 437 case DOKU_LEXER_MATCHED : 438 //Add Table Elements Based On Type 439 if($this->lvhDebug) $renderer->doc .= 'MATCHED'; //Debug 440 break; 441 case DOKU_LEXER_UNMATCHED : 442 //Ignore 443 if($this->lvhDebug) $renderer->doc .= 'UNMATCHED'; //Debug 444 break; 445 case DOKU_LEXER_EXIT : 446 //Close Elements 447 if($this->lvhDebug) $renderer->doc .= 'EXIT'; //Debug 448 //$renderer->doc.= '</table></body></HTML>'; 449 450 //Separate Data 451 $instPacketName = $data[1]; 452 $instNameRow = $data[2]; 453 $instDescriptionRow = $data[3]; 454 $instSizeRow = $data[4]; 455 $instFormatRow = $data[5]; 456 $instDetails = $data[6]; 457 $instNumCols = $data[7]; 458 459 460 /************************************************************ 461 * Variables For HTML Generation 462 *************************************************************/ 463 464 465 //Add Packet Table 466 $renderer->doc .= " 467 <head> 468 <style type='text/css'> 469 470 table.packetTOC 471 { 472 width:100%; 473 background-color: #FFFFFF; 474 border-style:none; 475 border-spacing:0; 476 } 477 478 td.packetTOCCell 479 { 480 border-style:none; 481 } 482 483 table.packetTable 484 { 485 width:100%; 486 border-style:solid; 487 border-width:2px; 488 border-color:#1C1C1C; 489 border-collapse:collapse; 490 font-size:.9em; 491 background-color: #EEEEEE; 492 } 493 494 tr.packetFormatRow 495 { 496 497 } 498 499 td.packetNameCell 500 { 501 text-align: center; 502 font-size:1.2em; 503 font-weight:bold; 504 background-color: #A4A4A4; 505 border-bottom-style=solid; 506 border-bottom-width:1px; 507 border-bottom-color:#1C1C1C; 508 border-right-style=solid; 509 border-right-width:2px; 510 border-right-color:#1C1C1C; 511 512 } 513 td.packetDescriptionCell 514 { 515 516 } 517 518 td.packetSizeCell 519 { 520 border-bottom-style=solid; 521 border-bottom-width:1px; 522 border-bottom-color:#1C1C1C; 523 } 524 525 td.packetByteCell 526 { 527 text-align: center; 528 background-color: #A4A4A4; 529 font-weight:bold; 530 border-width:1px; 531 border-color:#1C1C1C; 532 } 533 534 td.packetBitCell 535 { 536 text-align: center; 537 background-color: #BBBBBB; 538 font-weight:bold; 539 border-width:1px; 540 border-color:#1C1C1C; 541 } 542 td.packetIdCell 543 { 544 text-align: center; 545 font-weight:bold; 546 background-color: #E6E6E6; 547 border-width:1px; 548 border-color:#1C1C1C; 549 } 550 551 td.subPacketHeaderCell 552 { 553 width:7%; 554 background-color: #A4A4A4; 555 text-align:right; 556 font-weight:bold; 557 border-right-style:solid; 558 border-right-width:1px; 559 border-right-color:#1C1C1C; 560 } 561 td.subPacketDetailsCell 562 { 563 564 } 565 </style> 566 </head> 567 568 569 <body> 570 <table class = packetTOC> 571 <ul> 572 <!--TOC--> 573 </ul> 574 </table> 575 </table> 576 577 <a id='".trim(str_replace(' ', '', $instPacketName))."'></a> 578 <table class='packetTable'> 579 " . $instNameRow 580 . $instDescriptionRow 581 . $instSizeRow 582 . $instFormatRow 583 . $instDetails . " 584 </table> 585 </body>"; 586 587 //Add To Packet TOC 588 $renderer->doc = preg_replace("/<!--TOC-->/", "<tr><td class=packetTOCCell><li><a href='#".trim(str_replace(' ', '', $instPacketName))."'>" . $instPacketName ." </a></li></tr></td><!--TOC-->", $renderer->doc, 1); 589 590 break; 591 case DOKU_LEXER_SPECIAL : 592 //Ignore 593 if($this->lvhDebug) $renderer->doc .= 'SPECIAL'; //Debug 594 break; 595 } 596 return true; 597 } 598 return false; 599 } 600} 601