Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

Tag.php

Zuletzt modifiziert: 02.04.2025, 15:03 - Dateigröße: 8.23 KiB


001  <?php
002   
003  /**
004  * @package   s9e\TextFormatter
005  * @copyright Copyright (c) 2010-2022 The s9e authors
006  * @license   http://www.opensource.org/licenses/mit-license.php The MIT License
007  */
008  namespace s9e\TextFormatter\Parser;
009   
010  class Tag
011  {
012      /**
013      * Tag type: start tag
014      */
015      const START_TAG = 1;
016   
017      /**
018      * Tag type: end tag
019      */
020      const END_TAG = 2;
021   
022      /**
023      * Tag type: self-closing tag
024      */
025      const SELF_CLOSING_TAG = self::START_TAG | self::END_TAG;
026   
027      /**
028      * @var array Dictionary of attributes
029      */
030      protected $attributes = [];
031   
032      /**
033      * @var array List of tags that are invalidated when this tag is invalidated
034      */
035      protected $cascade = [];
036   
037      /**
038      * @var Tag End tag that unconditionally ends this start tag
039      */
040      protected $endTag = null;
041   
042      /**
043      * @var integer Bitfield of boolean rules that apply to this tag
044      */
045      protected $flags = 0;
046   
047      /**
048      * @var bool Whether this tag is be invalid
049      */
050      protected $invalid = false;
051   
052      /**
053      * @var integer Length of text consumed by this tag
054      */
055      protected $len;
056   
057      /**
058      * @var string Name of this tag
059      */
060      protected $name;
061   
062      /**
063      * @var integer Position of this tag in the text
064      */
065      protected $pos;
066   
067      /**
068      * @var integer Tiebreaker used when sorting identical tags
069      */
070      protected $sortPriority;
071   
072      /**
073      * @var Tag Start tag that is unconditionally closed this end tag
074      */
075      protected $startTag = null;
076   
077      /**
078      * @var integer Tag type
079      */
080      protected $type;
081   
082      /**
083      * Constructor
084      *
085      * @param  integer $type     Tag's type
086      * @param  string  $name     Name of the tag
087      * @param  integer $pos      Position of the tag in the text
088      * @param  integer $len      Length of text consumed by the tag
089      * @param  integer $priority This tag's sorting tiebreaker
090      */
091      public function __construct($type, $name, $pos, $len, $priority = 0)
092      {
093          $this->type = (int) $type;
094          $this->name = $name;
095          $this->pos  = (int) $pos;
096          $this->len  = (int) $len;
097          $this->sortPriority = (int) $priority;
098      }
099   
100      //==========================================================================
101      // Actions
102      //==========================================================================
103   
104      /**
105      * Add a set of flags to this tag's
106      *
107      * @param  integer $flags
108      * @return void
109      */
110      public function addFlags($flags)
111      {
112          $this->flags |= $flags;
113      }
114   
115      /**
116      * Set given tag to be invalidated if this tag is invalidated
117      *
118      * @param  Tag  $tag
119      * @return void
120      */
121      public function cascadeInvalidationTo(Tag $tag)
122      {
123          $this->cascade[] = $tag;
124   
125          // If this tag is already invalid, cascade it now
126          if ($this->invalid)
127          {
128              $tag->invalidate();
129          }
130      }
131   
132      /**
133      * Invalidate this tag, as well as tags bound to this tag
134      *
135      * @return void
136      */
137      public function invalidate()
138      {
139          // Only invalidate if this tag is valid to prevent infinite loops
140          if (!$this->invalid)
141          {
142              $this->invalid = true;
143              foreach ($this->cascade as $tag)
144              {
145                  $tag->invalidate();
146              }
147          }
148      }
149   
150      /**
151      * Pair this tag with given tag
152      *
153      * @param  Tag  $tag
154      * @return void
155      */
156      public function pairWith(Tag $tag)
157      {
158          if ($this->canBePaired($this, $tag))
159          {
160              $this->endTag  = $tag;
161              $tag->startTag = $this;
162   
163              $this->cascadeInvalidationTo($tag);
164          }
165          elseif ($this->canBePaired($tag, $this))
166          {
167              $this->startTag = $tag;
168              $tag->endTag    = $this;
169          }
170      }
171   
172      /**
173      * Test whether two tags can be paired
174      */
175      protected function canBePaired(Tag $startTag, Tag $endTag): bool
176      {
177          return $startTag->name === $endTag->name && $startTag->type === self::START_TAG && $endTag->type === self::END_TAG && $startTag->pos <= $endTag->pos;
178      }
179   
180      /**
181      * Remove a set of flags from this tag's
182      *
183      * @param  integer $flags
184      * @return void
185      */
186      public function removeFlags($flags)
187      {
188          $this->flags &= ~$flags;
189      }
190   
191      /**
192      * Set the bitfield of boolean rules that apply to this tag
193      *
194      * @param  integer $flags Bitfield of boolean rules that apply to this tag
195      * @return void
196      */
197      public function setFlags($flags)
198      {
199          $this->flags = $flags;
200      }
201   
202      //==========================================================================
203      // Getters
204      //==========================================================================
205   
206      /**
207      * Return this tag's attributes
208      *
209      * @return array
210      */
211      public function getAttributes()
212      {
213          return $this->attributes;
214      }
215   
216      /**
217      * Return this tag's end tag
218      *
219      * @return Tag|null This tag's end tag, or NULL if none is set
220      */
221      public function getEndTag()
222      {
223          return $this->endTag;
224      }
225   
226      /**
227      * Return the bitfield of boolean rules that apply to this tag
228      *
229      * @return integer
230      */
231      public function getFlags()
232      {
233          return $this->flags;
234      }
235   
236      /**
237      * Return the length of text consumed by this tag
238      *
239      * @return integer
240      */
241      public function getLen()
242      {
243          return $this->len;
244      }
245   
246      /**
247      * Return this tag's name
248      *
249      * @return string
250      */
251      public function getName()
252      {
253          return $this->name;
254      }
255   
256      /**
257      * Return this tag's position
258      *
259      * @return integer
260      */
261      public function getPos()
262      {
263          return $this->pos;
264      }
265   
266      /**
267      * Return this tag's tiebreaker
268      *
269      * @return integer
270      */
271      public function getSortPriority()
272      {
273          return $this->sortPriority;
274      }
275   
276      /**
277      * Return this tag's start tag
278      *
279      * @return Tag|null This tag's start tag, or NULL if none is set
280      */
281      public function getStartTag()
282      {
283          return $this->startTag;
284      }
285   
286      /**
287      * Return this tag's type
288      *
289      * @return integer
290      */
291      public function getType()
292      {
293          return $this->type;
294      }
295   
296      //==========================================================================
297      // Tag's status
298      //==========================================================================
299   
300      /**
301      * Test whether this tag can close given start tag
302      *
303      * @param  Tag  $startTag A start tag
304      * @return bool
305      */
306      public function canClose(Tag $startTag)
307      {
308          if ($this->invalid
309           || !$this->canBePaired($startTag, $this)
310           || ($this->startTag && $this->startTag !== $startTag)
311           || ($startTag->endTag && $startTag->endTag !== $this))
312          {
313              return false;
314          }
315   
316          return true;
317      }
318   
319      /**
320      * Test whether this tag is a br tag
321      *
322      * @return bool
323      */
324      public function isBrTag()
325      {
326          return ($this->name === 'br');
327      }
328   
329      /**
330      * Test whether this tag is an end tag (self-closing tags inclusive)
331      *
332      * @return bool
333      */
334      public function isEndTag()
335      {
336          return (bool) ($this->type & self::END_TAG);
337      }
338   
339      /**
340      * Test whether this tag is an ignore tag
341      *
342      * @return bool
343      */
344      public function isIgnoreTag()
345      {
346          return ($this->name === 'i');
347      }
348   
349      /**
350      * Test whether this tag is invalid
351      *
352      * @return bool
353      */
354      public function isInvalid()
355      {
356          return $this->invalid;
357      }
358   
359      /**
360      * Test whether this tag represents a paragraph break
361      *
362      * @return bool
363      */
364      public function isParagraphBreak()
365      {
366          return ($this->name === 'pb');
367      }
368   
369      /**
370      * Test whether this tag is a self-closing tag
371      *
372      * @return bool
373      */
374      public function isSelfClosingTag()
375      {
376          return ($this->type === self::SELF_CLOSING_TAG);
377      }
378   
379      /**
380      * Test whether this tag is a special tag: "br", "i", "pb" or "v"
381      *
382      * @return bool
383      */
384      public function isSystemTag()
385      {
386          return (strpos('br i pb v', $this->name) !== false);
387      }
388   
389      /**
390      * Test whether this tag is a start tag (self-closing tags inclusive)
391      *
392      * @return bool
393      */
394      public function isStartTag()
395      {
396          return (bool) ($this->type & self::START_TAG);
397      }
398   
399      /**
400      * Test whether this tag represents verbatim text
401      *
402      * @return bool
403      */
404      public function isVerbatim()
405      {
406          return ($this->name === 'v');
407      }
408   
409      //==========================================================================
410      // Attributes handling
411      //==========================================================================
412   
413      /**
414      * Return the value of given attribute
415      *
416      * @param  string $attrName
417      * @return mixed
418      */
419      public function getAttribute($attrName)
420      {
421          return $this->attributes[$attrName];
422      }
423   
424      /**
425      * Return whether given attribute is set
426      *
427      * @param  string $attrName
428      * @return bool
429      */
430      public function hasAttribute($attrName)
431      {
432          return isset($this->attributes[$attrName]);
433      }
434   
435      /**
436      * Remove given attribute
437      *
438      * @param  string $attrName
439      * @return void
440      */
441      public function removeAttribute($attrName)
442      {
443          unset($this->attributes[$attrName]);
444      }
445   
446      /**
447      * Set the value of an attribute
448      *
449      * @param  string $attrName  Attribute's name
450      * @param  string $attrValue Attribute's value
451      * @return void
452      */
453      public function setAttribute($attrName, $attrValue)
454      {
455          $this->attributes[$attrName] = $attrValue;
456      }
457   
458      /**
459      * Set all of this tag's attributes at once
460      *
461      * @param  array $attributes
462      * @return void
463      */
464      public function setAttributes(array $attributes)
465      {
466          $this->attributes = $attributes;
467      }
468  }