1<?php
2
3/**
4 * Plugin RefNotes: Reference
5 *
6 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
7 * @author     Mykola Ostrovskyy <dwpforge@gmail.com>
8 */
9
10////////////////////////////////////////////////////////////////////////////////////////////////////
11class refnotes_parser_reference extends refnotes_refnote {
12
13    /**
14     * Constructor
15     */
16    public function __construct($name, $data) {
17        list($namespace, $name) = refnotes_namespace::parseName($name);
18
19        if (preg_match('/(?:@@FNT|#)(\d+)/', $name, $match) == 1) {
20            $name = intval($match[1]);
21        }
22
23        parent::__construct(array('ns' => $namespace, 'name' => $name));
24
25        if ($data != '') {
26            $this->parseStructuredData($data);
27        }
28    }
29
30    /**
31     *
32     */
33    private function parseStructuredData($data) {
34        if (preg_match('/^\s*\|/', $data) == 1) {
35            preg_match_all('/\|\s*([-\w]+)\s*=\s*([^|]+)/', $data, $match, PREG_SET_ORDER);
36
37            foreach ($match as $m) {
38                $this->data[$m[1]] = preg_replace('/\s+/', ' ', trim($m[2]));
39            }
40        }
41        else {
42            preg_match_all('/([-\w]+)\s*:\s*(.+?)\s*?(?:(?<!\\\\);|\n|$)/', $data, $match, PREG_SET_ORDER);
43
44            foreach ($match as $m) {
45                $this->data[$m[1]] = str_replace('\\;', ';', $m[2]);
46            }
47        }
48    }
49}
50
51////////////////////////////////////////////////////////////////////////////////////////////////////
52class refnotes_reference extends refnotes_refnote {
53
54    protected $inline;
55    protected $hidden;
56    protected $note;
57    protected $id;
58
59    /**
60     * Constructor
61     */
62    public function __construct($note, $attributes, $data) {
63        parent::__construct($attributes, $data);
64
65        $this->inline = $this->getAttribute('inline', false);
66        $this->hidden = $this->getAttribute('hidden', false);
67        $this->note = $note;
68        $this->id = -1;
69
70        if ($this->isBackReferenced()) {
71            $this->id = $this->note->getScope()->getReferenceId();
72        }
73    }
74
75    /**
76     *
77     */
78    public function getId() {
79        return $this->id;
80    }
81
82    /**
83     *
84     */
85    public function getNote() {
86        return $this->note;
87    }
88
89    /**
90     *
91     */
92    public function isInline() {
93        return $this->inline;
94    }
95
96    /**
97     *
98     */
99    public function isBackReferenced() {
100        return !$this->inline && !$this->hidden;
101    }
102}
103
104////////////////////////////////////////////////////////////////////////////////////////////////////
105class refnotes_renderer_reference extends refnotes_reference {
106
107    /**
108     *
109     */
110    public function getAnchorName() {
111        $result = 'refnotes';
112        $result .= $this->note->getScope()->getName();
113        $result .= ':ref' . $this->id;
114
115        return $result;
116    }
117
118    /**
119     *
120     */
121    public function render($mode) {
122        $doc = '';
123
124        if (!$this->hidden) {
125            $doc = $this->note->getScope()->getRenderer()->renderReference($mode, $this);
126        }
127
128        return $doc;
129    }
130}
131
132////////////////////////////////////////////////////////////////////////////////////////////////////
133class refnotes_action_reference extends refnotes_reference {
134
135    private $call;
136
137    /**
138     * Constructor
139     */
140    public function __construct($note, $attributes, $data, $call) {
141        parent::__construct($note, $attributes, $data);
142
143        $this->call = $call;
144    }
145
146    /**
147     *
148     */
149    private function updateAttributes($attributes) {
150        static $key = array('inline', 'use-reference-base', 'use-reference-font-weight', 'use-reference-font-style', 'use-reference-format', 'source');
151
152        foreach ($key as $k) {
153            if (array_key_exists($k, $attributes)) {
154                $this->attributes[$k] = $attributes[$k];
155            }
156        }
157    }
158
159    /**
160     *
161     */
162    private function updateData($data) {
163        $include = $this->note->getScope()->getRenderer()->getReferenceSharedDataSet();
164        $data = array_intersect_key($data, array_flip($include));
165        $this->data = array_merge($data, $this->data);
166    }
167
168    /**
169     *
170     */
171    public function rewrite($attributes, $data) {
172        $this->updateAttributes($attributes);
173        $this->updateData($data);
174
175        $this->call->setPluginData(1, $this->attributes);
176
177        if ($this->hasData()) {
178            $this->call->setPluginData(2, $this->data);
179        }
180    }
181
182    /**
183     *
184     */
185    public function setNoteText($text) {
186        if ($text != '') {
187            $calls = refnotes_parser_core::getInstance()->getInstructions($text);
188
189            $this->call->insertBefore(new refnotes_nest_instruction($calls));
190        }
191    }
192}
193