1<?php 2 3/** 4 * DokuWiki Plugin Numbered Headings: add tiered numbers for hierarchical headings 5 * 6 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 7 * @author Lars J. Metz <dokuwiki@meistermetz.de> 8 * @author Satoshi Sahara <sahara.satoshi@gmail.com> 9 * 10 * Config settings 11 * tier1 : heading level corresponding to the 1st tier 12 * format : numbering format (used in vsprintf) of each tier, JSON array string 13 */ 14class helper_plugin_numberedheadings extends DokuWiki_Plugin 15{ 16 protected $Tier1Level; // (int) heading level corresponding to the 1st tier 17 protected $TierFormat; // (array) numbering format of each tier 18 protected $HeadingCount; // (array) heading counter 19 20 protected function initHeadingCounter() 21 { 22 $this->HeadingCount = [ 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0 ]; 23 } 24 25 /** 26 * Set the first tier level 27 */ 28 public function setTier1($level=null) 29 { 30 $this->Tier1Level = $level; 31 return; 32 } 33 34 /** 35 * Get the first tier level 36 */ 37 public function getTier1() 38 { 39 return $this->Tier1Level; 40 } 41 42 /** 43 * Set or initialise the numbering format of each tier 44 * 45 * usage: setTierFormat('["Chapter %d."]', 1); 46 */ 47 public function setTierFormat($format=null, $tier=null) 48 { 49 if (empty($format)) { 50 $format = $this->getConf('format'); // JSON array string 51 } 52 $TierFormat = json_decode($format, true); 53 if ($TierFormat === null) $TierFormat = []; 54 if ($tier === null) { 55 // initialise numbering format (tier 1 to 5) using config parameter 56 // re-index array from 1, instead of 0 57 array_unshift($TierFormat, ''); 58 unset($TierFormat[0]); 59 $this->TierFormat = $TierFormat; 60 } else { 61 // set numbering format of the specified tier and sub-tires 62 foreach ($TierFormat as $k => $value) { 63 $this->TierFormat[$tier + $k] = $value; 64 } 65 } 66 return; 67 } 68 69 /** 70 * Set or initialise the internal heading counter 71 */ 72 public function setHeadingCounter($level=null, $number=null) 73 { 74 if (isset($level)) { 75 // prepare the internal heading counter 76 if (!$this->HeadingCount) { 77 $this->initHeadingCounter(); 78 } 79 if ($number === '') $number = null; 80 $this->HeadingCount[$level] = isset($number) 81 ? $number 82 : ++$this->HeadingCount[$level]; 83 // reset the number of the subheadings 84 for ($i = $level +1; $i <= 5; $i++) { 85 $this->HeadingCount[$i] = 0; 86 } 87 } else { 88 $this->initHeadingCounter(); 89 } 90 return; 91 } 92 93 /** 94 * Build tiered numbers 95 */ 96 public function getTieredNumbers($level, $offset=null) 97 { 98 if (!$this->TierFormat) { 99 $this->setTierFormat($this->getConf('format')); 100 } 101 102 if (!isset($offset)) { 103 $offset = max(0, $this->Tier1Level -1); 104 } 105 if (isset($level) && $offset < $level) { 106 $tier = $level - $offset; 107 $numbers = array_slice($this->HeadingCount, $offset, $tier); 108 if (isset($this->TierFormat[$tier])) { 109 $tieredNumbers = vsprintf($this->TierFormat[$tier], $numbers); 110 } else { 111 $tieredNumbers = implode('.', $numbers); 112 } 113 } else { 114 $tieredNumbers = ''; 115 } 116 return $tieredNumbers; 117 } 118 119} 120