public static function getBitfields(TagCollection $tags, Ruleset $rootRules)
	{
		$rules = ['*root*' => iterator_to_array($rootRules)];
		foreach ($tags as $tagName => $tag)
		{
			$rules[$tagName] = iterator_to_array($tag->rules);
		}

		// Create a matrix that contains all of the tags and whether every other tag is allowed as
		// a child and as a descendant
		$matrix = self::unrollRules($rules);

		// Remove unusable tags from the matrix
		self::pruneMatrix($matrix);

		// Group together tags are allowed in the exact same contexts
		$groupedTags = [];
		foreach (array_keys($matrix) as $tagName)
		{
			if ($tagName === '*root*')
			{
				continue;
			}

			$k = '';
			foreach ($matrix as $tagMatrix)
			{
				$k .= $tagMatrix['allowedChildren'][$tagName];
				$k .= $tagMatrix['allowedDescendants'][$tagName];
			}

			$groupedTags[$k][] = $tagName;
		}

		// Record the bit number of each tag, and the name of a tag for each bit
		$bitTag     = [];
		$bitNumber  = 0;
		$tagsConfig = [];
		foreach ($groupedTags as $tagNames)
		{
			foreach ($tagNames as $tagName)
			{
				$tagsConfig[$tagName]['bitNumber'] = $bitNumber;
				$bitTag[$bitNumber] = $tagName;
			}

			++$bitNumber;
		}

		// Build the bitfields of each tag, including the *root* pseudo-tag
		foreach ($matrix as $tagName => $tagMatrix)
		{
			$allowedChildren    = '';
			$allowedDescendants = '';
			foreach ($bitTag as $targetName)
			{
				$allowedChildren    .= $tagMatrix['allowedChildren'][$targetName];
				$allowedDescendants .= $tagMatrix['allowedDescendants'][$targetName];
			}

			$tagsConfig[$tagName]['allowed'] = self::pack($allowedChildren, $allowedDescendants);
		}

		// Prepare the return value
		$return = [
			'root' => $tagsConfig['*root*'],
			'tags' => $tagsConfig
		];
		unset($return['tags']['*root*']);

		return $return;
	}
public static function getBitfields(TagCollection $tags, Ruleset $rootRules)
	{
		$rules = ['*root*' => iterator_to_array($rootRules)];
		foreach ($tags as $tagName => $tag)
		{
			$rules[$tagName] = iterator_to_array($tag->rules);
		}

		// Create a matrix that contains all of the tags and whether every other tag is allowed as
		// a child and as a descendant
		$matrix = self::unrollRules($rules);

		// Remove unusable tags from the matrix
		self::pruneMatrix($matrix);

		// Group together tags are allowed in the exact same contexts
		$groupedTags = [];
		foreach (array_keys($matrix) as $tagName)
		{
			if ($tagName === '*root*')
			{
				continue;
			}

			$k = '';
			foreach ($matrix as $tagMatrix)
			{
				$k .= $tagMatrix['allowedChildren'][$tagName];
				$k .= $tagMatrix['allowedDescendants'][$tagName];
			}

			$groupedTags[$k][] = $tagName;
		}

		// Record the bit number of each tag, and the name of a tag for each bit
		$bitTag     = [];
		$bitNumber  = 0;
		$tagsConfig = [];
		foreach ($groupedTags as $tagNames)
		{
			foreach ($tagNames as $tagName)
			{
				$tagsConfig[$tagName]['bitNumber'] = $bitNumber;
				$bitTag[$bitNumber] = $tagName;
			}

			++$bitNumber;
		}

		// Build the bitfields of each tag, including the *root* pseudo-tag
		foreach ($matrix as $tagName => $tagMatrix)
		{
			$allowedChildren    = '';
			$allowedDescendants = '';
			foreach ($bitTag as $targetName)
			{
				$allowedChildren    .= $tagMatrix['allowedChildren'][$targetName];
				$allowedDescendants .= $tagMatrix['allowedDescendants'][$targetName];
			}

			$tagsConfig[$tagName]['allowed'] = self::pack($allowedChildren, $allowedDescendants);
		}

		// Prepare the return value
		$return = [
			'root' => $tagsConfig['*root*'],
			'tags' => $tagsConfig
		];
		unset($return['tags']['*root*']);

		return $return;
	}
public static function getBitfields ( TagCollection $ tags , Ruleset $ rootRules ) { $ rules = [ '*root*' => iterator_to_array ( $ rootRules ) ] ; foreach ( $ tags as $ tagName => $ tag ) { $ rules [ $ tagName ] = iterator_to_array ( $ tag -> rules ) ; } // Create a matrix that contains all of the tags and whether every other tag is allowed as // a child and as a descendant $ matrix = self :: unrollRules ( $ rules ) ; // Remove unusable tags from the matrix self :: pruneMatrix ( $ matrix ) ; // Group together tags are allowed in the exact same contexts $ groupedTags = [ ] ; foreach ( array_keys ( $ matrix ) as $ tagName ) { if ( $ tagName === '*root*' ) { continue ; } $ k = '' ; foreach ( $ matrix as $ tagMatrix ) { $ k .= $ tagMatrix [ 'allowedChildren' ] [ $ tagName ] ; $ k .= $ tagMatrix [ 'allowedDescendants' ] [ $ tagName ] ; } $ groupedTags [ $ k ] [ ] = $ tagName ; } // Record the bit number of each tag, and the name of a tag for each bit $ bitTag = [ ] ; $ bitNumber = 0 ; $ tagsConfig = [ ] ; foreach ( $ groupedTags as $ tagNames ) { foreach ( $ tagNames as $ tagName ) { $ tagsConfig [ $ tagName ] [ 'bitNumber' ] = $ bitNumber ; $ bitTag [ $ bitNumber ] = $ tagName ; } ++ $ bitNumber ; } // Build the bitfields of each tag, including the *root* pseudo-tag foreach ( $ matrix as $ tagName => $ tagMatrix ) { $ allowedChildren = '' ; $ allowedDescendants = '' ; foreach ( $ bitTag as $ targetName ) { $ allowedChildren .= $ tagMatrix [ 'allowedChildren' ] [ $ targetName ] ; $ allowedDescendants .= $ tagMatrix [ 'allowedDescendants' ] [ $ targetName ] ; } $ tagsConfig [ $ tagName ] [ 'allowed' ] = self :: pack ( $ allowedChildren , $ allowedDescendants ) ; } // Prepare the return value $ return = [ 'root' => $ tagsConfig [ '*root*' ] , 'tags' => $ tagsConfig ] ; unset ( $ return [ 'tags' ] [ '*root*' ] ) ; return $ return ; }
Generate the allowedChildren and allowedDescendants bitfields for every tag and for the root context

@param  TagCollection $tags
@param  Ruleset       $rootRules
@return array
Generate the allowedChildren and allowedDescendants bitfields for every tag and for the root context