Resolves all @see and @link tags in the description of the given descriptor to their markdown representation.

@uses self::resolveTag()
350704
private function resolveSeeAndLinkTags(DescriptorAbstract $descriptor): void
    {
        // store descriptor to use it in the resolveTag method
        $this->descriptor = $descriptor;

        $descriptor->setDescription(
            preg_replace_callback(
                self::REGEX_INLINE_LINK_OR_SEE_TAG,
                [$this, 'resolveTag'],
                $descriptor->getDescription()
            )
        );
    }
861902
public function taggedWith($tag)
    {
        $results = [];

        if (isset($this->tags[$tag]))
        {
            foreach ($this->tags[$tag] as $view)
            {
                $results[] = $view;
            }

        }

        return $results;
    }
503873
private function resolveElement(DescriptorAbstract $element, $link, ?string $description = null): string
    {
        $rule = $this->router->match($element);

        if ($rule) {
            $url = '..' . $rule->generate($element);
            $link = $this->generateMarkdownLink($url, $description ?: (string) $link);
        }

        return $link;
    }
418818
public function tags()
    {
        $result = $this->execute('list', array('--xml' => true, $this->getUrl() . '/' . $this->basePaths['tags']));

        $tags = array();
        foreach ($result as $fileinfo) {
            $tags[] = new Reference($fileinfo->getFilename(), Reference::TAG, $fileinfo->getCommit()->getRevision());
        }

        return $tags;
    }
709305
public function getTags ($tag)
	{
		
		$tags	= array ();
		
		foreach ($this->lines as $line)
		{
			if (strpos ($line, '@' . $tag) === 0)
			{
				$tags[]	= trim (substr ($line, strlen ('@' . $tag)));
			}
		}
		
		return $tags;
		
	}
70866
public function pairWith(Tag $tag)
	{
		if ($this->name === $tag->name)
		{
			if ($this->type === self::START_TAG
			 && $tag->type  === self::END_TAG
			 && $tag->pos   >=  $this->pos)
			{
				$this->endTag  = $tag;
				$tag->startTag = $this;

				$this->cascadeInvalidationTo($tag);
			}
			elseif ($this->type === self::END_TAG
			     && $tag->type  === self::START_TAG
			     && $tag->pos   <=  $this->pos)
			{
				$this->startTag = $tag;
				$tag->endTag    = $this;
			}
		}
	}
435285
public function setResolvedDescription($resolvedDescription) {
		if (is_array($resolvedDescription) && empty($resolvedDescription)) {
			$this->resolvedDescription = new \stdClass;
		} else {
			$this->resolvedDescription = $resolvedDescription;
		}

		return $this;
	}
973475
@PostConstruct
    public void loadTagDefinitions()
    {
        Map<Addon, List<URL>> addonToResourcesMap = scanner.scanForAddonMap(new FileExtensionFilter("tags.xml"));
        for (Map.Entry<Addon, List<URL>> entry : addonToResourcesMap.entrySet())
        {
            for (URL resource : entry.getValue())
            {
                log.info("Reading tags definitions from: " + resource.toString() + " from addon " + entry.getKey().getId());
                try(InputStream is = resource.openStream())
                {
                    tagService.readTags(is);
                }
                catch( Exception ex )
                {
                    throw new WindupException("Failed reading tags definition: " + resource.toString() + " from addon " + entry.getKey().getId() + ":\n" + ex.getMessage(), ex);
                }
            }
        }
    }
1292389
protected function parseReferenceLinks()
	{
		$labels = $this->getLabels();
		foreach ($labels as $startPos => $id)
		{
			$labelPos = $startPos + 2 + strlen($id);
			$endPos   = $labelPos - 1;
			$endLen   = 1;

			if ($this->text->charAt($labelPos) === ' ')
			{
				++$labelPos;
			}
			if (isset($labels[$labelPos], $this->text->linkReferences[$labels[$labelPos]]))
			{
				$id     = $labels[$labelPos];
				$endLen = $labelPos + 2 + strlen($id) - $endPos;
			}
			if (isset($this->text->linkReferences[$id]))
			{
				$this->addLinkTag($startPos, $endPos, $endLen, $this->text->linkReferences[$id]);
			}
		}
	}
971743
protected function findDefinitionsByTag(ContainerBuilder $builder, $showHidden)
    {
        $definitions = [];
        $tags = $builder->findTags();
        asort($tags);

        foreach ($tags as $tag) {
            foreach ($builder->findTaggedServiceIds($tag) as $serviceId => $attributes) {
                $definition = $this->resolveServiceDefinition($builder, $serviceId);

                if ($showHidden xor '.' === ($serviceId[0] ?? null)) {
                    continue;
                }

                if (!isset($definitions[$tag])) {
                    $definitions[$tag] = [];
                }

                $definitions[$tag][$serviceId] = $definition;
            }
        }

        return $definitions;
    }
633000
public function resolveTagNames($tagNames)
    {
        $resolvedTags = [];

        foreach ($tagNames as $tagName) {
            $tag = $this->findByName($tagName);
            if (null !== $tag) {
                $resolvedTags[] = $tag->getId();
            }
        }

        return $resolvedTags;
    }
1184141
public function resolve(string $definition, array $args = [])
    {
        $def = $this->getDefinition($definition);
        if ($def === null) {
            throw new ClassDefinitionNotFoundException($definition);
        }

        return $this->binding_resolver->resolve($def, $this, $args);
    }
842950
function getTags()
    {
        if( $this->getRenderedMetaContent() instanceof TagsAwareInterface  )
        {
            return array_unique(
                        array_merge(
                            parent::getTags(),
                            $this->getRenderedMetaContent()->getTags()
                   ));
        }
        return parent::getTags();
    }
954461
function processTag(tag, targets) {
  if (tag.description) {
    tag.description = replaceLink(tag.description, targets);
  }
  if (tag.params) {
    tag.params.forEach(function (param) {
      if (param.description) {
        param.description = replaceLink(param.description, targets);
      }
    });
  }
  if (tag.members) {
    tag.members.forEach(function (member) {
      processTag(member, targets);
    });
  }
  if (tag.methods) {
    tag.methods.forEach(function (method) {
      processTag(method, targets);
    });
  }
}
1256906
public function MetaTags(&$tags)
    {
        $MetaMarkup = array();
        $owner = $this->owner;
        $tagTypes = array(
            'TagTitle',
            'MetaTagCharset',
            'MetaTagGenerator',
            'MetaTagDescription',
            'MetaTagRobots',
            'MetaTagResponsive',
            'MetaTagTwitter',
            'SchemaTagWebsite',
            'SchemaTagBreadcrumbs',
            'SchemaTagContactPoints',
            'SchemaTagLocalBusiness'
        );

        foreach ($tagTypes as $tagType) {
            if ($owner->{$tagType}) {
                $MetaMarkup[] = $owner->{$tagType};
            }
        }

        if(Permission::check('CMS_ACCESS_CMSMain')
        && in_array('CMSPreviewable', class_implements($owner))
        && !$owner instanceof ErrorPage
        && $owner->ID > 0
        ) {
            $MetaMarkup[] = MetaHelper::MetaTag('x-page-id', $owner->ID);
            $MetaMarkup[] = MetaHelper::MetaTag('x-cms-edit-link', $owner->CMSEditLink());
            Requirements::customScript(file_get_contents(BASE_PATH.'/'.BETTERMETA_DIR.'/js/cmseditshortcut.js'));
        }

        $tags = implode("\n", $MetaMarkup);
    }
214282
private function _parseTags($tags)
        {
            if(count($tags) > 0)
            {   
//              loop through the tags
                foreach($tags as $key=>$tag)
                {   
//                  if a tag is delayed, it is rendered after everything else and it's has to be re parsed.
                    if(isset($tag['attributes']) === true && isset($tag['attributes']->delayed) === true && $tag['attributes']->delayed === 'true')
                    {
                        continue;
                    }
//                  check for buried preserved tags, so they can be replaced.
//                  NOTE: this only works with no collected tags. Collected tags are a massive pain in the rectum.
                    if(($has_buried = preg_match_all('!------@@%([0-9\-]+)%@@------!', $tag['content'], $info)) > 0)
                    {   
                        $containers = $info[0];
                        $indexs = $info[1];
                        $replacements = array();
                        foreach ($indexs as $key2=>$index)
                        {
                            $index_parts = explode('-', $index);
                            $tag_index = array_pop($index_parts);
                            if(isset($tags[$tag_index]['parsed']) === true)
                            {
                                $replacements[$key2] = $tags[$tag_index]['parsed'];
                            }
                            else
                            {   
                                if(isset($tags[$tag_index]['block']) === true)
                                {
                                    $block = preg_replace('/ delayed="true"/', '', $tags[$tag_index]['block'], 1);
                                    if(isset($tag['block']) === true)
                                    {
                                        $tag['block'] = str_replace($containers[$key2], $block, $tag['block']); 
                                    }
                                    $tag['content'] = str_replace($containers[$key2], $block, $tag['content']); 
                                }
                            }
                        }
                        $tags[$key]['buried_source_markers'] = $tag['buried_source_markers'] = $containers;
                    }

//                  if the tag is a nocahe tag then the block must be replaced as is for later processing
                    if($tag['name'] === 'nocache')
                    {
                        array_push(self::$nocache_tags, $tag);
                        $tags[$key]['parsed'] = $tag['source_marker'];
//                      $tags[$key]['parsed'] = $tag['block'];
                    }
//                  if the tag is just plain text then just shove the content back into the parsed as it doesn't require processing
                    else if($tag['name'] === '___text')
                    {
                        $tags[$key]['parsed'] = $tag['content'];
                    }
//                  otherwise we have a tag and must post process
                    else
                    {   
                        $tags[$key]['parsed'] = $this->_parseTag($tag);
                    }
//                  update any buried tags within the parsed content
                    $tags[$key]['parsed'] = $has_buried > 0 ? str_replace($containers, $replacements, $tags[$key]['parsed']) : $tags[$key]['parsed'];
                }
// //              if there are items within the nocache elements, parse the contents to pull them out
//                 $tagname = $this->_options['tag_name'];
//                 if(substr_count($tags[$key]['parsed'], self::$tag_open.$tagname.':') > substr_count($tags[$key]['parsed'], self::$tag_open.$tagname.':nocache'))
//                 {
//                     $tags[$key]['parsed'] = $this->parse($tags[$key]['parsed'], true, true);
// //                  $tags[$key]['parsed'] = $this->_processTags($tags[$key]['parsed'], true);
//                 }
                
//                 Debug::info($tags[$key]);
                
                return $tags[$key]['parsed'];
            }
            return false;
        }
585203
private function convertToTagDoc(TagDoc $tag)
    {
        $tagDoc = [
            'name' => $tag->getName(),
        ];
        if (null !== $tag->getDescription()) {
            $tagDoc['description'] = $tag->getDescription();
        }

        return $tagDoc;
    }