1<?php 2 3/** 4 * Plugin RefNotes: Renderer 5 * 6 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 7 * @author Mykola Ostrovskyy <dwpforge@gmail.com> 8 */ 9 10//////////////////////////////////////////////////////////////////////////////////////////////////// 11class refnotes_renderer_mock { 12 13 /** 14 * 15 */ 16 public function renderReference($reference) { 17 return ''; 18 } 19} 20 21//////////////////////////////////////////////////////////////////////////////////////////////////// 22abstract class refnotes_renderer_base { 23 24 protected $namespace; 25 26 /** 27 * Constructor 28 */ 29 public function __construct($namespace) { 30 $this->namespace = $namespace; 31 } 32 33 /** 34 * 35 */ 36 protected function getStyle($name) { 37 return $this->namespace->getStyle($name); 38 } 39 40 /** 41 * Returns an array of keys for data that is shared between references and notes. 42 */ 43 abstract public function getReferenceSharedDataSet(); 44 45 /** 46 * Returns an array of keys for data that is specific to references. 47 */ 48 abstract public function getReferencePrivateDataSet(); 49 50 /** 51 * 52 */ 53 abstract public function renderReference($mode, $reference); 54 55 /** 56 * 57 */ 58 abstract public function renderNoteText($note); 59 60 /** 61 * 62 */ 63 abstract public function renderNote($mode, $note, $reference); 64} 65 66//////////////////////////////////////////////////////////////////////////////////////////////////// 67class refnotes_renderer extends refnotes_renderer_base { 68 69 private $referenceRenderer; 70 private $noteRenderer; 71 72 /** 73 * Constructor 74 */ 75 public function __construct($namespace) { 76 parent::__construct($namespace); 77 78 $this->referenceRenderer = $this->createRenderer($this->getStyle('reference-render')); 79 $this->noteRenderer = $this->createRenderer($this->getStyle('note-render')); 80 } 81 82 /** 83 * 84 */ 85 private function createRenderer($style) { 86 switch ($style) { 87 case 'harvard': 88 $renderer = new refnotes_harvard_renderer($this->namespace); 89 break; 90 91 default: 92 $renderer = new refnotes_basic_renderer($this->namespace); 93 break; 94 } 95 96 return $renderer; 97 } 98 99 /** 100 * 101 */ 102 public function getReferenceSharedDataSet() { 103 return $this->referenceRenderer->getReferenceSharedDataSet(); 104 } 105 106 /** 107 * 108 */ 109 public function getReferencePrivateDataSet() { 110 return $this->referenceRenderer->getReferencePrivateDataSet(); 111 } 112 113 /** 114 * 115 */ 116 public function renderReference($mode, $reference) { 117 return $this->referenceRenderer->renderReference($mode, $reference); 118 } 119 120 /** 121 * 122 */ 123 public function renderNotesSeparator() { 124 $html = ''; 125 $style = $this->getStyle('notes-separator'); 126 if ($style != 'none') { 127 if ($style != '') { 128 $style = ' style="width: '. $style . '"'; 129 } 130 $html = '<hr' . $style . '>' . DOKU_LF; 131 } 132 133 return $html; 134 } 135 136 /** 137 * 138 */ 139 public function renderNoteText($note) { 140 return $this->noteRenderer->renderNoteText($note); 141 } 142 143 /** 144 * 145 */ 146 public function renderNote($mode, $note, $reference) { 147 return $this->noteRenderer->renderNote($mode, $note, $reference); 148 } 149} 150 151//////////////////////////////////////////////////////////////////////////////////////////////////// 152class refnotes_renderer_data { 153 154 private $data; 155 156 /** 157 * Constructor 158 */ 159 public function __construct($data) { 160 $this->data = $data; 161 } 162 163 /** 164 * 165 */ 166 public function has($key) { 167 if (func_num_args() > 1) { 168 $result = false; 169 170 foreach (func_get_args() as $key) { 171 if (array_key_exists($key, $this->data)) { 172 $result = true; 173 break; 174 } 175 } 176 177 return $result; 178 } 179 else { 180 return array_key_exists($key, $this->data); 181 } 182 } 183 184 /** 185 * 186 */ 187 public function get($key) { 188 if (func_num_args() > 1) { 189 $result = ''; 190 191 foreach (func_get_args() as $key) { 192 if (array_key_exists($key, $this->data)) { 193 $result = $this->data[$key]; 194 break; 195 } 196 } 197 198 return $result; 199 } 200 else { 201 return array_key_exists($key, $this->data) ? $this->data[$key] : ''; 202 } 203 } 204 205 /** 206 * 207 */ 208 public function getLongest() { 209 $result = ''; 210 211 if (func_num_args() > 0) { 212 foreach (func_get_args() as $key) { 213 if (array_key_exists($key, $this->data) && (strlen($result) < strlen($this->data[$key]))) { 214 $result = $this->data[$key]; 215 } 216 } 217 } 218 else { 219 foreach ($this->data as $value) { 220 if (strlen($result) < strlen($value)) { 221 $result = $value; 222 } 223 } 224 } 225 226 return $result; 227 } 228 229 /** 230 * 231 */ 232 public function isPositive($key) 233 { 234 static $lookup = array('y', 'yes', 'on', 'true', '1'); 235 236 return in_array(strtolower($this->get($key)), $lookup); 237 } 238} 239 240//////////////////////////////////////////////////////////////////////////////////////////////////// 241class refnotes_basic_renderer extends refnotes_renderer_base { 242 243 protected $renderedNoteId = array(); 244 245 /** 246 * 247 */ 248 public function getReferenceSharedDataSet() { 249 return array(); 250 } 251 252 /** 253 * 254 */ 255 public function getReferencePrivateDataSet() { 256 return array(); 257 } 258 259 /** 260 * 261 */ 262 public function renderReference($mode, $reference) { 263 if ($reference->isInline()) { 264 $doc = $this->renderInlineReference($reference); 265 } 266 else { 267 $doc = $this->renderRegularReference($mode, $reference); 268 } 269 270 return $doc; 271 } 272 273 /** 274 * 275 */ 276 public function renderNoteText($note) { 277 $data = new refnotes_renderer_data($note->getData()); 278 279 $text = $data->get('note-text', 'title'); 280 281 if ($text == '') { 282 $text = $data->getLongest(); 283 } 284 285 if ($url = $data->get('url')) { 286 $text = '[[' . $url . '|' . $text . ']]'; 287 } 288 289 return $text; 290 } 291 292 /** 293 * 294 */ 295 public function renderNote($mode, $note, $reference) { 296 $doc = ''; 297 298 switch ($mode) { 299 case 'xhtml': 300 $doc = $this->renderNoteXhtml($note, $reference); 301 break; 302 303 case 'odt': 304 $doc = $this->renderNoteOdt($note, $reference); 305 break; 306 } 307 308 return $doc; 309 } 310 311 /** 312 * 313 */ 314 protected function renderNoteXhtml($note, $reference) { 315 $html = '<div class="' . $this->renderNoteClass() . '">' . DOKU_LF; 316 $html .= $this->renderBackReferences($note, $reference); 317 $html .= '<span id="' . $note->getAnchorName() . ':text">' . DOKU_LF; 318 $html .= $note->getText() . DOKU_LF; 319 $html .= '</span></div>' . DOKU_LF; 320 321 $this->rendered = true; 322 323 return $html; 324 } 325 326 /** 327 * 328 */ 329 protected function renderNoteOdt($note, $reference) { 330 $this->rendered = true; 331 332 return ''; 333 } 334 335 /** 336 * 337 */ 338 protected function getInlineReferenceStyle($reference, $name, $default) { 339 return ($reference->getAttribute('use-' . $name) === false) ? $default : $this->getStyle($name); 340 } 341 342 /** 343 * 344 */ 345 protected function renderInlineReference($reference) { 346 $baseStyle = $this->getInlineReferenceStyle($reference, 'reference-base', 'text'); 347 $fontWeightStyle = $this->getInlineReferenceStyle($reference, 'reference-font-weight', 'normal'); 348 $fontStyle = $this->getInlineReferenceStyle($reference, 'reference-font-style', 'normal'); 349 $formatStyle = $this->getInlineReferenceStyle($reference, 'reference-format', 'none'); 350 351 list($baseOpen, $baseClose) = $this->renderBase($baseStyle); 352 list($fontOpen, $fontClose) = $this->renderFont($fontWeightStyle, 'normal', $fontStyle); 353 list($formatOpen, $formatClose) = $this->renderFormat($formatStyle); 354 355 $html = $baseOpen . $fontOpen . $formatOpen; 356 $html .= $reference->getNote()->getText(); 357 $html .= $formatClose . $fontClose . $baseClose; 358 359 return $html; 360 } 361 362 /** 363 * 364 */ 365 protected function renderRegularReference($mode, $reference) { 366 $doc = ''; 367 368 switch ($mode) { 369 case 'xhtml': 370 $doc = $this->renderRegularReferenceXhtml($reference); 371 break; 372 373 case 'odt': 374 $doc = $this->renderRegularReferenceOdt($reference); 375 break; 376 } 377 378 return $doc; 379 } 380 381 /** 382 * 383 */ 384 protected function renderRegularReferenceXhtml($reference) { 385 $noteName = $reference->getNote()->getAnchorName(); 386 $referenceName = $reference->getAnchorName(); 387 $class = $this->renderReferenceClass(); 388 389 list($baseOpen, $baseClose) = $this->renderReferenceBase(); 390 list($fontOpen, $fontClose) = $this->renderReferenceFont(); 391 list($formatOpen, $formatClose) = $this->renderReferenceFormat($reference); 392 393 $html = $baseOpen . $fontOpen; 394 $html .= '<a href="#' . $noteName . '" name="' . $referenceName . '" class="' . $class . '">'; 395 $html .= $formatOpen . $this->renderReferenceId($reference) . $formatClose; 396 $html .= '</a>'; 397 $html .= $fontClose . $baseClose; 398 399 return $html; 400 } 401 402 /** 403 * 404 */ 405 protected function renderRegularReferenceOdt($reference) { 406 $xmlOdt = ''; 407 $note = $reference->getNote(); 408 $noteId = $note->getId(); 409 $refId = $reference->getId(); 410 411 // Check to see if this note has been seen before 412 413 if (array_search($noteId, $this->renderedNoteId) === false) { 414 // new note, add it to the $renderedNoteId array 415 $this->renderedNoteId[] = $noteId; 416 417 $xmlOdt .= '<text:note text:id="refnote' . $refId . '" text:note-class="footnote">'; 418 $xmlOdt .= '<text:note-citation text:label="' . $refId . '">' . $refId . '</text:note-citation>'; 419 $xmlOdt .= '<text:note-body>'; 420 $xmlOdt .= '<text:p>' . $note->getText(); 421 $xmlOdt .= '</text:p>'; 422 $xmlOdt .= '</text:note-body>'; 423 $xmlOdt .= '</text:note>'; 424 } 425 else { 426 // Seen this one before - just reference it FIXME: style isn't correct 427 $xmlOdt = '<text:note-ref text:note-class="footnote" text:ref-name="refnote' . $noteId . '">'; 428 $xmlOdt .= $refId; 429 $xmlOdt .= '</text:note-ref>'; 430 } 431 432 return $xmlOdt; 433 } 434 435 /** 436 * 437 */ 438 protected function renderBackReferences($note, $reference) { 439 $references = count($reference); 440 $singleReference = ($references == 1); 441 $nameAttribute = ' name="' . $note->getAnchorName() .'"'; 442 $backRefFormat = $this->getStyle('back-ref-format'); 443 $backRefCaret = ''; 444 $html = ''; 445 446 list($formatOpen, $formatClose) = $this->renderNoteIdFormat(); 447 448 if (($backRefFormat != 'note') && ($backRefFormat != '')) { 449 list($baseOpen, $baseClose) = $this->renderNoteIdBase(); 450 list($fontOpen, $fontClose) = $this->renderNoteIdFont(); 451 452 $html .= $baseOpen . $fontOpen; 453 $html .= '<a' . $nameAttribute .' class="nolink">'; 454 $html .= $formatOpen . $this->renderNoteId($note) . $formatClose; 455 $html .= '</a>'; 456 $html .= $fontClose . $baseClose . DOKU_LF; 457 458 $nameAttribute = ''; 459 $formatOpen = ''; 460 $formatClose = ''; 461 $backRefCaret = $this->renderBackRefCaret($singleReference); 462 } 463 464 if ($backRefFormat != 'none') { 465 $separator = $this->renderBackRefSeparator(); 466 467 list($baseOpen, $baseClose) = $this->renderBackRefBase(); 468 list($fontOpen, $fontClose) = $this->renderBackRefFont(); 469 470 $html .= $baseOpen . $backRefCaret; 471 472 for ($r = 0; $r < $references; $r++) { 473 $referenceName = $reference[$r]->getAnchorName(); 474 475 if ($r > 0) { 476 $html .= $separator . DOKU_LF; 477 } 478 479 $html .= $fontOpen; 480 $html .= '<a href="#' . $referenceName . '"' . $nameAttribute .' class="backref">'; 481 $html .= $formatOpen . $this->renderBackRefId($reference[$r], $r, $singleReference) . $formatClose; 482 $html .= '</a>'; 483 $html .= $fontClose; 484 485 $nameAttribute = ''; 486 } 487 488 $html .= $baseClose . DOKU_LF; 489 } 490 491 return $html; 492 } 493 494 /** 495 * 496 */ 497 protected function renderReferenceClass() { 498 switch ($this->getStyle('note-preview')) { 499 case 'tooltip': 500 $result = 'refnotes-ref note-tooltip'; 501 break; 502 503 case 'none': 504 $result = 'refnotes-ref'; 505 break; 506 507 default: 508 $result = 'refnotes-ref note-popup'; 509 break; 510 } 511 512 return $result; 513 } 514 515 /** 516 * 517 */ 518 protected function renderReferenceBase() { 519 return $this->renderBase($this->getStyle('reference-base')); 520 } 521 522 /** 523 * 524 */ 525 protected function renderReferenceFont() { 526 return $this->renderFont('reference-font-weight', 'normal', 'reference-font-style'); 527 } 528 529 /** 530 * 531 */ 532 protected function renderReferenceFormat($reference) { 533 $result = $this->renderFormat($this->getStyle('reference-format')); 534 535 if ($this->getReferenceGrouping($reference)) { 536 switch ($reference->getAttribute('group')) { 537 case 'open': 538 $result = array($result[0], $this->renderReferenceGroupSeparator()); 539 break; 540 541 case 'hold': 542 $result = array('', $this->renderReferenceGroupSeparator()); 543 break; 544 545 case 'close': 546 $result = array('', $result[1]); 547 break; 548 } 549 } 550 551 return $result; 552 } 553 554 /** 555 * 556 */ 557 protected function getReferenceGrouping($reference) { 558 $group = $reference->getAttribute('group'); 559 return !empty($group) && in_array($group, array('open', 'hold', 'close')) && 560 in_array($this->getStyle('reference-group'), array(',', 's')); 561 } 562 563 /** 564 * 565 */ 566 protected function renderReferenceGroupSeparator() { 567 $style = $this->getStyle('reference-group'); 568 switch ($style) { 569 case ',': 570 $result = ','; 571 break; 572 573 case 's': 574 $result = ';'; 575 break; 576 577 default: 578 $result = ''; 579 break; 580 } 581 582 return $result; 583 } 584 585 /** 586 * 587 */ 588 protected function renderReferenceId($reference) { 589 $idStyle = $this->getStyle('refnote-id'); 590 if ($idStyle == 'name') { 591 $html = $reference->getNote()->getName(); 592 } 593 else { 594 switch ($this->getStyle('multi-ref-id')) { 595 case 'note': 596 $id = $reference->getNote()->getId(); 597 break; 598 599 default: 600 $id = $reference->getId(); 601 break; 602 } 603 604 $html = $this->convertToStyle($id, $idStyle); 605 } 606 607 return $html; 608 } 609 610 /** 611 * 612 */ 613 protected function renderNoteClass() { 614 $result = 'note'; 615 616 switch ($this->getStyle('note-font-size')) { 617 case 'small': 618 $result .= ' small'; 619 break; 620 } 621 622 switch ($this->getStyle('note-text-align')) { 623 case 'left': 624 $result .= ' left'; 625 break; 626 627 default: 628 $result .= ' justify'; 629 break; 630 } 631 632 return $result; 633 } 634 635 /** 636 * 637 */ 638 protected function renderNoteIdBase() { 639 return $this->renderBase($this->getStyle('note-id-base')); 640 } 641 642 /** 643 * 644 */ 645 protected function renderNoteIdFont() { 646 return $this->renderFont('note-id-font-weight', 'normal', 'note-id-font-style'); 647 } 648 649 /** 650 * 651 */ 652 protected function renderNoteIdFormat() { 653 $style = $this->getStyle('note-id-format'); 654 switch ($style) { 655 case '.': 656 $result = array('', '.'); 657 break; 658 659 default: 660 $result = $this->renderFormat($style); 661 break; 662 } 663 664 return $result; 665 } 666 667 /** 668 * 669 */ 670 protected function renderNoteId($note) { 671 $idStyle = $this->getStyle('refnote-id'); 672 if ($idStyle == 'name') { 673 $html = $note->getName(); 674 } 675 else { 676 $html = $this->convertToStyle($note->getId(), $idStyle); 677 } 678 679 return $html; 680 } 681 682 /** 683 * 684 */ 685 protected function renderBackRefCaret($singleReference) { 686 switch ($this->getStyle('back-ref-caret')) { 687 case 'prefix': 688 $result = '^ '; 689 break; 690 691 case 'merge': 692 $result = $singleReference ? '' : '^ '; 693 break; 694 695 default: 696 $result = ''; 697 break; 698 } 699 700 return $result; 701 } 702 703 /** 704 * 705 */ 706 protected function renderBackRefBase() { 707 return $this->renderBase($this->getStyle('back-ref-base')); 708 } 709 710 /** 711 * 712 */ 713 protected function renderBackRefFont() { 714 return $this->renderFont('back-ref-font-weight', 'bold', 'back-ref-font-style'); 715 } 716 717 /** 718 * 719 */ 720 protected function renderBackRefSeparator() { 721 static $html = array('' => ',', 'none' => ''); 722 723 $style = $this->getStyle('back-ref-separator'); 724 if (!array_key_exists($style, $html)) { 725 $style = ''; 726 } 727 728 return $html[$style]; 729 } 730 731 /** 732 * 733 */ 734 protected function renderBackRefId($reference, $index, $singleReference) { 735 $style = $this->getStyle('back-ref-format'); 736 switch ($style) { 737 case 'a': 738 $result = $this->convertToLatin($index + 1, $style); 739 break; 740 741 case '1': 742 $result = $index + 1; 743 break; 744 745 case 'caret': 746 $result = '^'; 747 break; 748 749 case 'arrow': 750 $result = '↑'; 751 break; 752 753 default: 754 $result = $this->renderReferenceId($reference); 755 break; 756 } 757 758 if ($singleReference && ($this->getStyle('back-ref-caret') == 'merge')) { 759 $result = '^'; 760 } 761 762 return $result; 763 } 764 765 /** 766 * 767 */ 768 protected function renderBase($style) { 769 static $html = array( 770 '' => array('<sup>', '</sup>'), 771 'text' => array('', '') 772 ); 773 774 if (!array_key_exists($style, $html)) { 775 $style = ''; 776 } 777 778 return $html[$style]; 779 } 780 781 /** 782 * 783 */ 784 protected function renderFont($weight, $defaultWeight, $style) { 785 list($weightOpen, $weightClose) = $this->renderFontWeight($this->getStyle($weight), $defaultWeight); 786 list($styleOpen, $styleClose) = $this->renderFontStyle($this->getStyle($style)); 787 788 return array($weightOpen . $styleOpen, $styleClose . $weightClose); 789 } 790 791 /** 792 * 793 */ 794 protected function renderFontWeight($style, $default) { 795 static $html = array( 796 'normal' => array('', ''), 797 'bold' => array('<b>', '</b>') 798 ); 799 800 if (!array_key_exists($style, $html)) { 801 $style = $default; 802 } 803 804 return $html[$style]; 805 } 806 807 /** 808 * 809 */ 810 protected function renderFontStyle($style) { 811 static $html = array( 812 '' => array('', ''), 813 'italic' => array('<i>', '</i>') 814 ); 815 816 if (!array_key_exists($style, $html)) { 817 $style = ''; 818 } 819 820 return $html[$style]; 821 } 822 823 /** 824 * 825 */ 826 protected function renderFormat($style) { 827 static $html = array( 828 '' => array('', ')'), 829 '()' => array('(', ')'), 830 ']' => array('', ']'), 831 '[]' => array('[', ']'), 832 'none' => array('', '') 833 ); 834 835 if (!array_key_exists($style, $html)) { 836 $style = ''; 837 } 838 839 return $html[$style]; 840 } 841 842 /** 843 * 844 */ 845 protected function convertToStyle($id, $style) { 846 switch ($style) { 847 case 'a': 848 case 'A': 849 $result = $this->convertToLatin($id, $style); 850 break; 851 852 case 'i': 853 case 'I': 854 $result = $this->convertToRoman($id, $style); 855 break; 856 857 case '*': 858 $result = str_repeat('*', $id); 859 break; 860 861 default: 862 $result = $id; 863 break; 864 } 865 866 return $result; 867 } 868 869 /** 870 * 871 */ 872 protected function convertToLatin($number, $case) { 873 static $alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; 874 875 $result = ''; 876 877 while ($number > 0) { 878 --$number; 879 $digit = $number % 26; 880 $result = $alpha[$digit] . $result; 881 $number = intval($number / 26); 882 } 883 884 if ($case == 'a') { 885 $result = strtolower($result); 886 } 887 888 return $result; 889 } 890 891 /** 892 * 893 */ 894 protected function convertToRoman($number, $case) { 895 static $lookup = array( 896 'M' => 1000, 'CM' => 900, 'D' => 500, 'CD' => 400, 897 'C' => 100, 'XC' => 90, 'L' => 50, 'XL' => 40, 898 'X' => 10, 'IX' => 9, 'V' => 5, 'IV' => 4, 'I' => 1 899 ); 900 901 $result = ''; 902 903 foreach ($lookup as $roman => $value) { 904 $matches = intval($number / $value); 905 906 if ($matches > 0) { 907 $result .= str_repeat($roman, $matches); 908 $number = $number % $value; 909 } 910 } 911 912 if ($case == 'i') { 913 $result = strtolower($result); 914 } 915 916 return $result; 917 } 918} 919 920//////////////////////////////////////////////////////////////////////////////////////////////////// 921class refnotes_harvard_renderer extends refnotes_basic_renderer { 922 923 /** 924 * Constructor 925 */ 926 public function __construct($namespace) { 927 parent::__construct($namespace); 928 } 929 930 /** 931 * 932 */ 933 public function getReferenceSharedDataSet() { 934 static $key = array('ref-authors', 'ref-author', 'authors', 'author', 'published', 'month', 'year'); 935 936 return $key; 937 } 938 939 /** 940 * 941 */ 942 public function getReferencePrivateDataSet() { 943 static $key = array('direct', 'pages', 'page'); 944 945 return $key; 946 } 947 948 /** 949 * 950 */ 951 public function renderNoteText($note) { 952 $data = new refnotes_renderer_data($note->getData()); 953 954 if (!$data->has('title')) { 955 return parent::renderNoteText($note); 956 } 957 958 // authors, published. //[[url|title.]]// edition. publisher, pages, isbn. 959 // authors, published. chapter In //[[url|title.]]// edition. publisher, pages, isbn. 960 // authors, published. [[url|title.]] //journal//, volume, publisher, pages, issn. 961 // authors, published. [[url|title.]] //booktitle//, publisher, pages, issn. 962 963 $title = $this->renderTitle($data); 964 965 // authors, published. //$title// edition. publisher, pages, isbn. 966 // authors, published. chapter In //$title// edition. publisher, pages, isbn. 967 // authors, published. $title //journal//, volume, publisher, pages, issn. 968 // authors, published. $title //booktitle//, publisher, pages, issn. 969 970 $authors = $this->renderAuthors($data); 971 972 // $authors? //$title// edition. publisher, pages, isbn. 973 // $authors? chapter In //$title// edition. publisher, pages, isbn. 974 // $authors? $title //journal//, volume, publisher, pages, issn. 975 // $authors? $title //booktitle//, publisher, pages, issn. 976 977 $publication = $this->renderPublication($data, $authors != ''); 978 979 if ($data->has('journal')) { 980 // $authors? $title //journal//, volume, $publication? 981 982 $subtitle = $this->renderJournal($data); 983 } 984 elseif ($data->has('booktitle')) { 985 // $authors? $title //booktitle//, $publication? 986 987 $subtitle = $this->renderBookTitle($data); 988 } 989 990 if (!empty($subtitle)) { 991 // $authors? $title $subtitle?, $publication? 992 993 $text = $title . ' ' . $subtitle; 994 995 // $authors? $text, $publication? 996 997 $text .= ($publication != '') ? ',' : '.'; 998 } 999 else { 1000 // $authors? //$title// edition. $publication? 1001 // $authors? chapter In //$title// edition. $publication? 1002 1003 $text = $this->renderBook($data, $title); 1004 } 1005 1006 // $authors? $text $publication? 1007 1008 if ($authors != '') { 1009 $text = $authors . ' ' . $text; 1010 } 1011 1012 if ($publication != '') { 1013 $text .= ' ' . $publication; 1014 } 1015 1016 return $text; 1017 } 1018 1019 /** 1020 * 1021 */ 1022 protected function renderTitle($data) { 1023 $text = $data->get('title') . '.'; 1024 1025 if ($url = $data->get('url')) { 1026 $text = '[[' . $url . '|' . $text . ']]'; 1027 } 1028 1029 return $text; 1030 } 1031 1032 /** 1033 * 1034 */ 1035 protected function renderAuthors($data) { 1036 $text = $data->get('authors', 'author'); 1037 1038 if ($text != '') { 1039 if ($published = $this->renderPublished($data)) { 1040 $text .= ', ' . $published; 1041 } 1042 1043 $text .= '.'; 1044 } 1045 1046 return $text; 1047 } 1048 1049 /** 1050 * 1051 */ 1052 protected function renderPublished($data, $useMonth = true) { 1053 $text = $data->get('published'); 1054 1055 if ($text == '') { 1056 if ($text = $data->get('year')) { 1057 if ($useMonth && $month = $data->get('month')) { 1058 $text = $month . ' ' . $text; 1059 } 1060 } 1061 } 1062 1063 return $text; 1064 } 1065 1066 /** 1067 * 1068 */ 1069 protected function renderPublication($data, $authors) { 1070 $part = array(); 1071 1072 $address = $data->get('address'); 1073 $publisher = $data->get('publisher'); 1074 1075 if ($address && $publisher) { 1076 $part[] = $address . ': ' . $publisher; 1077 } 1078 else { 1079 if ($address || $publisher) { 1080 $part[] = $address . $publisher; 1081 } 1082 } 1083 1084 if (!$authors && ($published = $this->renderPublished($data))) { 1085 $part[] = $published; 1086 } 1087 1088 if ($pages = $this->renderPages($data, array('note-pages', 'note-page', 'pages', 'page'))) { 1089 $part[] = $pages; 1090 } 1091 1092 if ($isbn = $data->get('isbn')) { 1093 $part[] = 'ISBN ' . $isbn; 1094 } 1095 elseif ($issn = $data->get('issn')) { 1096 $part[] = 'ISSN ' . $issn; 1097 } 1098 1099 $text = implode(', ', $part); 1100 1101 if ($text != '') { 1102 $text = rtrim($text, '.') . '.'; 1103 } 1104 1105 return $text; 1106 } 1107 1108 /** 1109 * 1110 */ 1111 protected function renderPages($data, $key) { 1112 $text = ''; 1113 1114 foreach ($key as $k) { 1115 if ($text = $data->get($k)) { 1116 if (preg_match("/^[0-9]/", $text)) { 1117 $abbr_key = (substr($k, -1) == 's') ? 'txt_pages_abbr' : 'txt_page_abbr'; 1118 $text = refnotes_localization::getInstance()->getLang($abbr_key) . $text; 1119 } 1120 break; 1121 } 1122 } 1123 1124 return $text; 1125 } 1126 1127 /** 1128 * 1129 */ 1130 protected function renderJournal($data) { 1131 $text = '//' . $data->get('journal') . '//'; 1132 1133 if ($volume = $data->get('volume')) { 1134 $text .= ', ' . $volume; 1135 } 1136 1137 return $text; 1138 } 1139 1140 /** 1141 * 1142 */ 1143 protected function renderBook($data, $title) { 1144 $text = '//' . $title . '//'; 1145 1146 if ($chapter = $data->get('chapter')) { 1147 $text = $chapter . '. ' . refnotes_localization::getInstance()->getLang('txt_in_cap') . ' ' . $text; 1148 } 1149 1150 if ($edition = $data->get('edition')) { 1151 $text .= ' ' . $edition . '.'; 1152 } 1153 1154 return $text; 1155 } 1156 1157 /** 1158 * 1159 */ 1160 protected function renderBookTitle($data) { 1161 return '//' . $data->get('booktitle') . '//'; 1162 } 1163 1164 /** 1165 * 1166 */ 1167 protected function renderReferenceId($reference) { 1168 $data = new refnotes_renderer_data($reference->getData()); 1169 1170 if (!$this->checkReferenceData($data)) { 1171 return $this->renderBasicReferenceId($reference); 1172 } 1173 1174 $authors = $data->get('ref-authors', 'ref-author', 'authors', 'author'); 1175 $html = $this->renderReferenceExtra($data); 1176 1177 list($formatOpen, $formatClose) = $this->renderReferenceParentheses(); 1178 1179 if ($data->isPositive('direct')) { 1180 $html = $authors . ' ' . $formatOpen . $html . $formatClose; 1181 1182 if ($this->getReferenceGrouping($reference)) { 1183 switch ($reference->getAttribute('group')) { 1184 case 'open': 1185 case 'hold': 1186 $html .= $this->renderReferenceGroupSeparator(); 1187 break; 1188 } 1189 } 1190 } 1191 else { 1192 if ($this->getReferenceGrouping($reference)) { 1193 switch ($reference->getAttribute('group')) { 1194 case 'open': 1195 $formatClose = $this->renderReferenceGroupSeparator(); 1196 break; 1197 1198 case 'hold': 1199 $formatOpen = ''; 1200 $formatClose = $this->renderReferenceGroupSeparator(); 1201 break; 1202 1203 case 'close': 1204 $formatOpen = ''; 1205 break; 1206 } 1207 } 1208 1209 $html = $formatOpen . $authors . ', ' . $html . $formatClose; 1210 } 1211 1212 return htmlspecialchars($html); 1213 } 1214 1215 /** 1216 * 1217 */ 1218 protected function renderBasicReferenceId($reference) { 1219 list($formatOpen, $formatClose) = parent::renderReferenceFormat($reference); 1220 1221 return $formatOpen . parent::renderReferenceId($reference) . $formatClose; 1222 } 1223 1224 /** 1225 * 1226 */ 1227 protected function renderReferenceExtra($data) { 1228 $html = ''; 1229 1230 if ($published = $this->renderPublished($data, false)) { 1231 $html .= $published; 1232 } 1233 1234 if ($pages = $this->renderPages($data, array('page', 'pages'))) { 1235 if ($html != '') { 1236 $html .= ', '; 1237 } 1238 1239 $html .= $pages; 1240 } 1241 1242 return $html; 1243 } 1244 1245 /** 1246 * 1247 */ 1248 protected function renderReferenceParentheses() { 1249 $style = $this->getStyle('reference-format'); 1250 $style = (($style == '[]') || ($style == ']')) ? '[]' : '()'; 1251 1252 return $this->renderFormat($style); 1253 } 1254 1255 /** 1256 * 1257 */ 1258 protected function renderReferenceFormat($reference) { 1259 return array('', ''); 1260 } 1261 1262 /** 1263 * 1264 */ 1265 protected function checkReferenceData($data) { 1266 $authors = $data->has('ref-authors', 'ref-author', 'authors', 'author'); 1267 $year = $data->has('published', 'year'); 1268 $page = $data->has('page', 'pages'); 1269 1270 return $authors && ($year || $page); 1271 } 1272} 1273