PageRenderTime 62ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/refnotes/syntax/references.php

http://dwp-forge.googlecode.com/
PHP | 334 lines | 196 code | 65 blank | 73 comment | 22 complexity | 6241f93a316974b170eed14fd9dec9e7 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /**
  3. * Plugin RefNotes: Reference collector/renderer
  4. *
  5. * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
  6. * @author Mykola Ostrovskyy <spambox03@mail.ru>
  7. */
  8. /* Must be run within Dokuwiki */
  9. if (!defined('DOKU_INC') || !defined('DOKU_PLUGIN')) die();
  10. require_once(DOKU_PLUGIN . 'syntax.php');
  11. require_once(DOKU_PLUGIN . 'refnotes/core.php');
  12. require_once(DOKU_PLUGIN . 'refnotes/bibtex.php');
  13. ////////////////////////////////////////////////////////////////////////////////////////////////////
  14. class syntax_plugin_refnotes_references extends DokuWiki_Syntax_Plugin {
  15. private $mode;
  16. private $entryPattern;
  17. private $exitPattern;
  18. private $handlePattern;
  19. private $noteCapture;
  20. /**
  21. * Constructor
  22. */
  23. public function __construct() {
  24. refnotes_localization::initialize($this);
  25. $this->mode = substr(get_class($this), 7);
  26. $this->noteCapture = new refnotes_note_capture();
  27. $this->initializePatterns();
  28. }
  29. /**
  30. *
  31. */
  32. private function initializePatterns() {
  33. if (refnotes_configuration::getSetting('replace-footnotes')) {
  34. $entry = '(?:\(\(|\[\()';
  35. $exit = '(?:\)\)|\)\])';
  36. $id = '@@FNT\d+|#\d+';
  37. }
  38. else {
  39. $entry = '\[\(';
  40. $exit = '\)\]';
  41. $id = '#\d+';
  42. }
  43. $strictName = refnotes_note::getNamePattern('strict');
  44. $extendedName = refnotes_note::getNamePattern('extended');
  45. $namespace = refnotes_namespace::getNamePattern('optional');
  46. $text = '.*?';
  47. $strictName = '(?:' . $id . '|' . $strictName . ')';
  48. $fullName = '\s*(?:' . $namespace . $strictName . '|:' . $namespace . $extendedName . ')\s*';
  49. $lookaheadExit = '(?=' . $exit . ')';
  50. $nameEntry = $fullName . $lookaheadExit;
  51. $extendedName = '(?:' . $id . '|' . $extendedName . ')';
  52. $optionalFullName = $namespace . $extendedName . '?';
  53. $structuredEntry = '\s*' . $optionalFullName . '\s*>>' . $text . $lookaheadExit;
  54. $define = '\s*' . $optionalFullName . '\s*>\s*';
  55. $optionalDefine = '(?:' . $define . ')?';
  56. $lookaheadExit = '(?=' . $text . $exit . ')';
  57. $defineEntry = $optionalDefine . $lookaheadExit;
  58. $this->entryPattern = $entry . '(?:' . $nameEntry . '|' . $structuredEntry . '|' . $defineEntry . ')';
  59. $this->exitPattern = $exit;
  60. $this->handlePattern = '/' . $entry . '\s*(' . $optionalFullName . ')\s*(?:>>(.*))?(.*)/s';
  61. }
  62. /**
  63. * What kind of syntax are we?
  64. */
  65. public function getType() {
  66. return 'formatting';
  67. }
  68. /**
  69. * What modes are allowed within our mode?
  70. */
  71. public function getAllowedTypes() {
  72. return array (
  73. 'formatting',
  74. 'substition',
  75. 'protected',
  76. 'disabled'
  77. );
  78. }
  79. /**
  80. * Where to sort in?
  81. */
  82. public function getSort() {
  83. return 145;
  84. }
  85. public function connectTo($mode) {
  86. refnotes_parser_core::getInstance()->registerLexer($this->Lexer);
  87. $this->Lexer->addEntryPattern($this->entryPattern, $mode, $this->mode);
  88. }
  89. public function postConnect() {
  90. $this->Lexer->addExitPattern($this->exitPattern, $this->mode);
  91. }
  92. /**
  93. * Handle the match
  94. */
  95. public function handle($match, $state, $pos, $handler) {
  96. $result = refnotes_parser_core::getInstance()->canHandle($state);
  97. if ($result) {
  98. switch ($state) {
  99. case DOKU_LEXER_ENTER:
  100. $result = $this->handleEnter($match);
  101. break;
  102. case DOKU_LEXER_EXIT:
  103. $result = $this->handleExit();
  104. break;
  105. }
  106. }
  107. if ($result === false) {
  108. $handler->_addCall('cdata', array($match), $pos);
  109. }
  110. return $result;
  111. }
  112. /**
  113. * Create output
  114. */
  115. public function render($mode, $renderer, $data) {
  116. $result = false;
  117. try {
  118. switch ($mode) {
  119. case 'xhtml':
  120. $result = $this->renderXhtml($renderer, $data);
  121. break;
  122. case 'metadata':
  123. $result = $this->renderMetadata($renderer, $data);
  124. break;
  125. }
  126. }
  127. catch (Exception $error) {
  128. msg($error->getMessage(), -1);
  129. }
  130. return $result;
  131. }
  132. /**
  133. *
  134. */
  135. private function handleEnter($syntax) {
  136. if (preg_match($this->handlePattern, $syntax, $match) == 0) {
  137. return false;
  138. }
  139. refnotes_parser_core::getInstance()->enterReference($match[1], $match[2]);
  140. return array('start');
  141. }
  142. /**
  143. *
  144. */
  145. private function handleExit() {
  146. $reference = refnotes_parser_core::getInstance()->exitReference();
  147. if ($reference->hasData()) {
  148. return array('render', $reference->getAttributes(), $reference->getData());
  149. }
  150. else {
  151. return array('render', $reference->getAttributes());
  152. }
  153. }
  154. /**
  155. *
  156. */
  157. public function renderXhtml($renderer, $data) {
  158. switch ($data[0]) {
  159. case 'start':
  160. $this->noteCapture->start($renderer);
  161. break;
  162. case 'render':
  163. $this->renderReference($renderer, $data[1], (count($data) > 2) ? $data[2] : array());
  164. break;
  165. }
  166. return true;
  167. }
  168. /**
  169. * Stops renderer output capture and renders the reference link
  170. */
  171. private function renderReference($renderer, $attributes, $data) {
  172. $reference = refnotes_renderer_core::getInstance()->addReference($attributes, $data);
  173. $text = $this->noteCapture->stop();
  174. if ($text != '') {
  175. $reference->getNote()->setText($text);
  176. }
  177. $renderer->doc .= $reference->render();
  178. }
  179. /**
  180. *
  181. */
  182. public function renderMetadata($renderer, $data) {
  183. if ($data[0] == 'render') {
  184. $source = '';
  185. if (array_key_exists('source', $data[1])) {
  186. $source = $data[1]['source'];
  187. }
  188. if (($source != '') && ($source != '{configuration}')) {
  189. $renderer->meta['plugin']['refnotes']['dbref'][wikiFN($source)] = true;
  190. }
  191. }
  192. return true;
  193. }
  194. }
  195. ////////////////////////////////////////////////////////////////////////////////////////////////////
  196. class refnotes_note_capture {
  197. private $renderer;
  198. private $note;
  199. private $doc;
  200. /**
  201. * Constructor
  202. */
  203. public function __construct() {
  204. $this->initialize();
  205. }
  206. /**
  207. *
  208. */
  209. private function initialize() {
  210. $this->renderer = NULL;
  211. $this->doc = '';
  212. }
  213. /**
  214. *
  215. */
  216. private function resetCapture() {
  217. $this->renderer->doc = '';
  218. }
  219. /**
  220. *
  221. */
  222. public function start($renderer) {
  223. $this->renderer = $renderer;
  224. $this->doc = $renderer->doc;
  225. $this->resetCapture();
  226. }
  227. /**
  228. *
  229. */
  230. public function restart() {
  231. $text = trim($this->renderer->doc);
  232. $this->resetCapture();
  233. return $text;
  234. }
  235. /**
  236. *
  237. */
  238. public function stop() {
  239. $text = trim($this->renderer->doc);
  240. $this->renderer->doc = $this->doc;
  241. $this->initialize();
  242. return $text;
  243. }
  244. }
  245. ////////////////////////////////////////////////////////////////////////////////////////////////////
  246. class refnotes_nested_call_writer extends Doku_Handler_Nest {
  247. private $handler;
  248. private $callWriterBackup;
  249. /**
  250. * Constructor
  251. */
  252. public function __construct($handler) {
  253. $this->handler = $handler;
  254. parent::__construct($this->handler->CallWriter);
  255. }
  256. /**
  257. *
  258. */
  259. public function connect() {
  260. $this->callWriterBackup = $this->handler->CallWriter;
  261. $this->handler->CallWriter = $this;
  262. }
  263. /**
  264. *
  265. */
  266. public function disconnect() {
  267. $this->handler->CallWriter = $this->callWriterBackup;
  268. }
  269. }